@xenosystem/blocks 0.15.2 → 0.15.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -449,6 +449,8 @@ declare class ConsoleController {
449
449
  /** Collapse adjacent duplicates. */
450
450
  setCollapse(collapse: boolean): void;
451
451
  /** Drop every record. Emits nothing — clearing a view is not an event a host acts on. */
452
+ /** Ask the host to recompute the records (a lint, an audit) — nothing changes here until it pushes. */
453
+ requestRefresh(): void;
452
454
  clear(): void;
453
455
  /**
454
456
  * A record was opened.
@@ -486,6 +488,7 @@ interface ConsoleRenderContext {
486
488
  rowHeight: number;
487
489
  showTimestamps: boolean;
488
490
  emptyHint?: string;
491
+ showRefresh?: boolean;
489
492
  };
490
493
  }
491
494
  /** Options for {@link createConsolePanel}. */
@@ -563,6 +566,7 @@ interface ConsoleViewModel {
563
566
  errors?: string;
564
567
  warns?: string;
565
568
  multiSource: boolean;
569
+ showRefresh: boolean;
566
570
  sources: ConsoleViewSource[];
567
571
  empty: boolean;
568
572
  emptyTitle: string;
@@ -585,6 +589,8 @@ type ConsoleUiIntent = {
585
589
  kind: 'copyVisible';
586
590
  } | {
587
591
  kind: 'clear';
592
+ } | {
593
+ kind: 'refresh';
588
594
  } | {
589
595
  kind: 'source';
590
596
  id: string;
@@ -602,6 +608,7 @@ interface ConsoleViewOptions {
602
608
  rowHeight?: number;
603
609
  showTimestamps?: boolean;
604
610
  emptyHint?: string;
611
+ showRefresh?: boolean;
605
612
  }
606
613
  /** Derive the view from the live controller — the runtime calls this on every draw. */
607
614
  declare function consoleViewState(c: ConsoleController, options?: ConsoleViewOptions): ConsoleViewModel;
package/dist/ops/index.js CHANGED
@@ -422,6 +422,10 @@ var ConsoleController = class {
422
422
  this.notify();
423
423
  }
424
424
  /** Drop every record. Emits nothing — clearing a view is not an event a host acts on. */
425
+ /** Ask the host to recompute the records (a lint, an audit) — nothing changes here until it pushes. */
426
+ requestRefresh() {
427
+ this.host.emit("refreshRequest", {});
428
+ }
425
429
  clear() {
426
430
  this.records = [];
427
431
  this.dropped = 0;
@@ -522,6 +526,12 @@ var consoleManifest = {
522
526
  name: "Context Menu Request",
523
527
  type: "object",
524
528
  description: "The host opens its own menu."
529
+ },
530
+ {
531
+ id: "refreshRequest",
532
+ name: "Refresh Requested",
533
+ type: "object",
534
+ description: "{} \u2014 the person pressed Refresh (config `showRefresh`), so a host whose records are a COMPUTATION (a lint, an audit, a query) re-runs it and pushes a `replace`. A live stream never shows the button."
525
535
  }
526
536
  ],
527
537
  commands: [
@@ -558,6 +568,13 @@ var consoleManifest = {
558
568
  }
559
569
  ],
560
570
  config: [
571
+ {
572
+ key: "showRefresh",
573
+ label: "Refresh button",
574
+ type: "boolean",
575
+ defaultValue: false,
576
+ description: "For records that are computed on demand rather than streamed: a Refresh button that emits `refreshRequest`."
577
+ },
561
578
  {
562
579
  key: "maxRecords",
563
580
  label: "Buffer size",
@@ -667,6 +684,7 @@ function consoleViewState(c, options = {}) {
667
684
  errors: s.counts.error > 0 ? String(s.counts.error) : void 0,
668
685
  warns: s.counts.warn > 0 ? String(s.counts.warn) : void 0,
669
686
  multiSource: s.sources.length > 1,
687
+ showRefresh: options.showRefresh === true,
670
688
  sources: s.sources.map((src) => ({ id: src.id, label: src.label ?? src.id, on: src.enabled, title: `${src.count} records` })),
671
689
  empty: s.rows.length === 0,
672
690
  emptyTitle: s.total > 0 ? "No matches" : "No output",
@@ -705,6 +723,9 @@ function applyConsoleUi(c, intent) {
705
723
  case "clear":
706
724
  c.clear();
707
725
  break;
726
+ case "refresh":
727
+ c.requestRefresh();
728
+ break;
708
729
  case "source":
709
730
  c.toggleSource(intent.id, intent.on);
710
731
  break;
@@ -725,7 +746,7 @@ var consoleViewManifest = {
725
746
  outputs: [{ id: "ui", name: "UI intent", type: "object", description: "{ kind, \u2026 } \u2014 applied by the runtime to the controller." }],
726
747
  commands: []
727
748
  };
728
- var EMPTY = { search: "", levels: [], level: "trace", multiSource: false, sources: [], empty: true, emptyTitle: "No output", emptyHint: "Run something to see its output here.", listed: false, rowHeight: 20, totalHeight: 0, offsetTop: 0, rows: [], countLabel: "0 of 0" };
749
+ var EMPTY = { search: "", levels: [], level: "trace", multiSource: false, showRefresh: false, sources: [], empty: true, emptyTitle: "No output", emptyHint: "Run something to see its output here.", listed: false, rowHeight: 20, totalHeight: 0, offsetTop: 0, rows: [], countLabel: "0 of 0" };
729
750
  var BEHAVIOURS = {
730
751
  "ops/consolePanelView": (inputs) => inputs.view ?? EMPTY
731
752
  };
@@ -758,6 +779,7 @@ var CONSOLE_DECLARATION = {
758
779
  children: [
759
780
  { component: "chrome/Badge", when: { input: "view.errors" }, props: { tone: { value: "error" } }, children: [text({ input: "view.errors" })] },
760
781
  { component: "chrome/Badge", when: { input: "view.warns" }, props: { tone: { value: "warning" } }, children: [text({ input: "view.warns" })] },
782
+ { component: "chrome/IconButton", when: { input: "view.showRefresh" }, props: { icon: { node: { component: "icons/Refresh" } }, label: { value: "Refresh" } }, on: { onClick: ui("refresh") } },
761
783
  { component: "chrome/IconButton", props: { icon: { node: { component: "icons/Copy" } }, label: { value: "Copy visible" } }, on: { onClick: ui("copyVisible") } },
762
784
  { component: "chrome/IconButton", props: { icon: { node: { component: "icons/Clear" } }, label: { value: "Clear" } }, on: { onClick: ui("clear") } }
763
785
  ]
@@ -828,6 +850,7 @@ var CONSOLE_DECLARATION = {
828
850
  // src/ops/console/react/ConsolePanelView.tsx
829
851
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
830
852
  var CopyGlyph = ICONS["icons/Copy"];
853
+ var RefreshGlyph = ICONS["icons/Refresh"];
831
854
  var ClearGlyph = ICONS["icons/Clear"];
832
855
  function ConsoleScroller({ controller, rowHeight = 20, children }) {
833
856
  const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
@@ -882,6 +905,7 @@ function ConsolePanelView({ controller, ...options }) {
882
905
  right: /* @__PURE__ */ jsxs(ToolbarGroup, { end: true, children: [
883
906
  view.errors ? /* @__PURE__ */ jsx(Badge, { tone: "error", children: view.errors }) : null,
884
907
  view.warns ? /* @__PURE__ */ jsx(Badge, { tone: "warning", children: view.warns }) : null,
908
+ view.showRefresh ? /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(RefreshGlyph, {}), label: "Refresh", onClick: () => ui5({ kind: "refresh" }) }) : null,
885
909
  /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CopyGlyph, {}), label: "Copy visible", onClick: () => ui5({ kind: "copyVisible" }) }),
886
910
  /* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(ClearGlyph, {}), label: "Clear", onClick: () => ui5({ kind: "clear" }) })
887
911
  ] })
@@ -935,7 +959,8 @@ function createConsolePanel(options = {}) {
935
959
  const resolve = (config2) => ({
936
960
  rowHeight: numberConfig(config2.rowHeight, 20),
937
961
  showTimestamps: config2.showTimestamps !== false,
938
- emptyHint: typeof config2.emptyHint === "string" ? config2.emptyHint : void 0
962
+ emptyHint: typeof config2.emptyHint === "string" ? config2.emptyHint : void 0,
963
+ showRefresh: config2.showRefresh === true
939
964
  });
940
965
  let renderConfig = resolve(host.config ?? {});
941
966
  let unrender = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenosystem/blocks",
3
- "version": "0.15.2",
3
+ "version": "0.15.3",
4
4
  "description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",