@xenosystem/blocks 0.13.10 → 0.13.12
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.
- package/dist/chunk-5BVZMAD2.js +513 -0
- package/dist/data/index.d.ts +65 -11
- package/dist/data/index.js +217 -181
- package/dist/edit/index.js +5 -7
- package/dist/icons/index.js +2 -4
- package/dist/ops/index.d.ts +119 -9
- package/dist/ops/index.js +299 -183
- package/dist/time/index.js +1 -2
- package/package.json +3 -3
- package/dist/chunk-K7YLLV2W.js +0 -132
- package/dist/chunk-W4PTX2Y4.js +0 -414
package/dist/ops/index.js
CHANGED
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
} from "../chunk-WE6A2DTY.js";
|
|
9
9
|
import {
|
|
10
10
|
CancelGlyph,
|
|
11
|
-
|
|
12
|
-
CopyGlyph,
|
|
11
|
+
ICONS,
|
|
13
12
|
RetryGlyph
|
|
14
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-5BVZMAD2.js";
|
|
15
14
|
import "../chunk-2KG3PWR4.js";
|
|
16
15
|
|
|
17
16
|
// src/ops/console/panel.ts
|
|
@@ -63,10 +62,10 @@ function spliceRedactedAppend(existing, addition, redact, carry = REDACTION_CARR
|
|
|
63
62
|
const tail = existing.slice(cut);
|
|
64
63
|
return head + redact(tail + addition);
|
|
65
64
|
}
|
|
66
|
-
function truncateLogMessage(
|
|
67
|
-
if (max <= 0 ||
|
|
68
|
-
if (max <= MESSAGE_ELISION.length) return
|
|
69
|
-
return MESSAGE_ELISION +
|
|
65
|
+
function truncateLogMessage(text2, max) {
|
|
66
|
+
if (max <= 0 || text2.length <= max) return text2;
|
|
67
|
+
if (max <= MESSAGE_ELISION.length) return text2.slice(text2.length - max);
|
|
68
|
+
return MESSAGE_ELISION + text2.slice(text2.length - (max - MESSAGE_ELISION.length));
|
|
70
69
|
}
|
|
71
70
|
function formatRecord(record) {
|
|
72
71
|
const time = new Date(record.ts).toISOString();
|
|
@@ -243,7 +242,7 @@ var ConsoleController = class {
|
|
|
243
242
|
*/
|
|
244
243
|
merge(existing, patch) {
|
|
245
244
|
const secrets = [...this.host.getSecrets?.() ?? []];
|
|
246
|
-
const redact = (
|
|
245
|
+
const redact = (text2) => redactForLog(text2, secrets);
|
|
247
246
|
let message = existing.message;
|
|
248
247
|
if (typeof patch.message === "string") message = redact(patch.message);
|
|
249
248
|
if (typeof patch.appendMessage === "string" && patch.appendMessage.length > 0) {
|
|
@@ -388,6 +387,29 @@ var ConsoleController = class {
|
|
|
388
387
|
}
|
|
389
388
|
/* ── Interaction ───────────────────────────────────────────────────────── */
|
|
390
389
|
/** Follow the tail. Auto-disabled by the view when the user scrolls up. */
|
|
390
|
+
/* ── View state the declaration cannot hold ────────────────────────────── */
|
|
391
|
+
expandedId = null;
|
|
392
|
+
viewport = { height: 0, scrollTop: 0 };
|
|
393
|
+
/** Which record's data is expanded under its row, if any. */
|
|
394
|
+
getExpanded() {
|
|
395
|
+
return this.expandedId;
|
|
396
|
+
}
|
|
397
|
+
/** Toggle a record's expanded detail (only records carrying `data` expand). */
|
|
398
|
+
toggleExpanded(recordId) {
|
|
399
|
+
const record = this.records.find((r) => r.id === recordId);
|
|
400
|
+
if (!record || record.data === void 0) return;
|
|
401
|
+
this.expandedId = this.expandedId === recordId ? null : recordId;
|
|
402
|
+
this.notify();
|
|
403
|
+
}
|
|
404
|
+
/** The scroller reports its viewport; the view state windows the rows from it. */
|
|
405
|
+
setViewport(height, scrollTop) {
|
|
406
|
+
if (this.viewport.height === height && this.viewport.scrollTop === scrollTop) return;
|
|
407
|
+
this.viewport = { height, scrollTop };
|
|
408
|
+
this.notify();
|
|
409
|
+
}
|
|
410
|
+
getViewport() {
|
|
411
|
+
return this.viewport;
|
|
412
|
+
}
|
|
391
413
|
setFollow(follow) {
|
|
392
414
|
if (this.follow === follow) return;
|
|
393
415
|
this.follow = follow;
|
|
@@ -607,203 +629,289 @@ var consoleManifest = {
|
|
|
607
629
|
};
|
|
608
630
|
|
|
609
631
|
// src/ops/console/react/ConsolePanelView.tsx
|
|
610
|
-
import {
|
|
632
|
+
import { useEffect, useRef, useSyncExternalStore } from "react";
|
|
611
633
|
import {
|
|
612
634
|
Badge,
|
|
635
|
+
Code,
|
|
636
|
+
Column,
|
|
613
637
|
EmptyState,
|
|
638
|
+
FilterChip,
|
|
614
639
|
IconButton,
|
|
615
640
|
Row,
|
|
616
641
|
RowList,
|
|
617
642
|
ScrollArea,
|
|
618
643
|
SearchField,
|
|
619
644
|
SegmentedControl,
|
|
645
|
+
Stack,
|
|
620
646
|
StatusBar,
|
|
647
|
+
Text,
|
|
621
648
|
Toolbar,
|
|
622
|
-
ToolbarGroup
|
|
649
|
+
ToolbarGroup,
|
|
650
|
+
VirtualWindow
|
|
623
651
|
} from "@xenosystem/components/chrome";
|
|
652
|
+
|
|
653
|
+
// src/ops/console/declaration.ts
|
|
624
654
|
import { computeWindow } from "@xenosystem/tree-core";
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
655
|
+
var TONE = { trace: "neutral", debug: "neutral", info: "info", warn: "warning", error: "error" };
|
|
656
|
+
function consoleViewState(c, options = {}) {
|
|
657
|
+
const s = c.getState();
|
|
658
|
+
const rowHeight = options.rowHeight ?? 20;
|
|
659
|
+
const showTimestamps = options.showTimestamps ?? true;
|
|
660
|
+
const viewport = c.getViewport();
|
|
661
|
+
const window_ = computeWindow({ scrollTop: viewport.scrollTop, viewportHeight: viewport.height || rowHeight * 20, rowHeight, rowCount: s.rows.length });
|
|
662
|
+
const expanded = c.getExpanded();
|
|
663
|
+
return {
|
|
664
|
+
search: s.filter.search ?? "",
|
|
665
|
+
levels: LEVEL_ORDER.map((l) => ({ value: l, label: l.slice(0, 1).toUpperCase() })),
|
|
666
|
+
level: s.filter.minLevel ?? "trace",
|
|
667
|
+
errors: s.counts.error > 0 ? String(s.counts.error) : void 0,
|
|
668
|
+
warns: s.counts.warn > 0 ? String(s.counts.warn) : void 0,
|
|
669
|
+
multiSource: s.sources.length > 1,
|
|
670
|
+
sources: s.sources.map((src) => ({ id: src.id, label: src.label ?? src.id, on: src.enabled, title: `${src.count} records` })),
|
|
671
|
+
empty: s.rows.length === 0,
|
|
672
|
+
emptyTitle: s.total > 0 ? "No matches" : "No output",
|
|
673
|
+
emptyHint: s.total > 0 ? "Nothing matches the current filter." : options.emptyHint ?? "Run something to see its output here.",
|
|
674
|
+
listed: s.rows.length > 0,
|
|
675
|
+
rowHeight,
|
|
676
|
+
totalHeight: window_.totalHeight,
|
|
677
|
+
offsetTop: window_.offsetTop,
|
|
678
|
+
rows: s.rows.slice(window_.startIndex, window_.endIndex).map((record) => ({
|
|
679
|
+
id: record.id,
|
|
680
|
+
time: showTimestamps ? new Date(record.ts).toISOString().slice(11, 23) : void 0,
|
|
681
|
+
level: record.level,
|
|
682
|
+
tone: TONE[record.level],
|
|
683
|
+
source: record.source,
|
|
684
|
+
message: record.message,
|
|
685
|
+
repeat: (record.count ?? 1) > 1 ? `x${record.count}` : void 0,
|
|
686
|
+
expanded: expanded === record.id && record.data !== void 0,
|
|
687
|
+
// Already redacted — the buffer never held the raw value.
|
|
688
|
+
detail: expanded === record.id && record.data !== void 0 ? safeJson(record.data) : void 0
|
|
689
|
+
})),
|
|
690
|
+
countLabel: `${s.rows.length} of ${s.total}` + (s.dropped > 0 ? ` \xB7 ${s.dropped} dropped` : "") + (s.droppedPatches > 0 ? ` \xB7 ${s.droppedPatches} unmatched` : ""),
|
|
691
|
+
followLabel: s.follow ? "following" : void 0
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function applyConsoleUi(c, intent) {
|
|
695
|
+
switch (intent.kind) {
|
|
696
|
+
case "search":
|
|
697
|
+
c.setSearch(intent.value);
|
|
698
|
+
break;
|
|
699
|
+
case "level":
|
|
700
|
+
c.setLevel(intent.level === "trace" ? void 0 : intent.level);
|
|
701
|
+
break;
|
|
702
|
+
case "copyVisible":
|
|
703
|
+
void globalThis.navigator?.clipboard?.writeText(c.copyVisible());
|
|
704
|
+
break;
|
|
705
|
+
case "clear":
|
|
706
|
+
c.clear();
|
|
707
|
+
break;
|
|
708
|
+
case "source":
|
|
709
|
+
c.toggleSource(intent.id, intent.on);
|
|
710
|
+
break;
|
|
711
|
+
case "row":
|
|
712
|
+
c.toggleExpanded(intent.id);
|
|
713
|
+
c.activate(intent.id);
|
|
714
|
+
break;
|
|
715
|
+
case "contextMenu":
|
|
716
|
+
c.requestContextMenu(intent.id, intent.x, intent.y);
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
var consoleViewManifest = {
|
|
721
|
+
id: consoleManifest.id,
|
|
722
|
+
version: "1.0.0",
|
|
723
|
+
title: "Console",
|
|
724
|
+
category: "ops",
|
|
725
|
+
layout: { slot: "bottom" },
|
|
726
|
+
inputs: [{ id: "view", type: "object", label: "View state", description: "The ConsoleViewModel the runtime derives from the controller on every draw." }],
|
|
727
|
+
outputs: [{ id: "ui", type: "object", label: "UI intent", description: "{ kind, \u2026 } \u2014 applied by the runtime to the controller." }],
|
|
728
|
+
commands: []
|
|
632
729
|
};
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
730
|
+
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" };
|
|
731
|
+
var BEHAVIOURS = {
|
|
732
|
+
"ops/consolePanelView": (inputs) => inputs.view ?? EMPTY
|
|
733
|
+
};
|
|
734
|
+
var CONSOLE_RUNTIME_UNITS = ["console/Scroller"];
|
|
735
|
+
var text = (b) => ({ component: "text", props: { text: b } });
|
|
736
|
+
var ui = (kind, fields = {}) => ({ emit: "ui", value: { object: { kind: { value: kind }, ...fields } } });
|
|
737
|
+
var CONSOLE_DECLARATION = {
|
|
738
|
+
format: "xeno.block@1",
|
|
739
|
+
manifest: consoleViewManifest,
|
|
740
|
+
behaviour: "ops/consolePanelView",
|
|
741
|
+
composition: {
|
|
742
|
+
component: "chrome/Column",
|
|
743
|
+
children: [
|
|
744
|
+
{
|
|
745
|
+
component: "chrome/Toolbar",
|
|
746
|
+
props: {
|
|
747
|
+
left: {
|
|
748
|
+
node: {
|
|
749
|
+
component: "fragment",
|
|
750
|
+
children: [
|
|
751
|
+
{ component: "chrome/SearchField", props: { value: { input: "view.search" }, placeholder: { value: "Filter\u2026" } }, on: { onChange: ui("search", { value: { arg: "" } }) } },
|
|
752
|
+
{ component: "chrome/SegmentedControl", props: { size: { value: "sm" }, label: { value: "Minimum level" }, options: { input: "view.levels" }, value: { input: "view.level" } }, on: { onChange: ui("level", { level: { arg: "" } }) } }
|
|
753
|
+
]
|
|
754
|
+
}
|
|
755
|
+
},
|
|
756
|
+
right: {
|
|
757
|
+
node: {
|
|
758
|
+
component: "chrome/ToolbarGroup",
|
|
759
|
+
props: { end: { value: true } },
|
|
760
|
+
children: [
|
|
761
|
+
{ component: "chrome/Badge", when: { input: "view.errors" }, props: { tone: { value: "error" } }, children: [text({ input: "view.errors" })] },
|
|
762
|
+
{ component: "chrome/Badge", when: { input: "view.warns" }, props: { tone: { value: "warning" } }, children: [text({ input: "view.warns" })] },
|
|
763
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Copy" } }, label: { value: "Copy visible" } }, on: { onClick: ui("copyVisible") } },
|
|
764
|
+
{ component: "chrome/IconButton", props: { icon: { node: { component: "icons/Clear" } }, label: { value: "Clear" } }, on: { onClick: ui("clear") } }
|
|
765
|
+
]
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
component: "chrome/Stack",
|
|
772
|
+
when: { input: "view.multiSource" },
|
|
773
|
+
props: { direction: { value: "row" }, gap: { value: 4 }, pad: { value: "inset" } },
|
|
774
|
+
children: [
|
|
775
|
+
{ component: "chrome/FilterChip", each: { input: "view.sources", key: "id" }, props: { on: { item: "on" }, title: { item: "title" } }, on: { onChange: ui("source", { id: { item: "id" }, on: { arg: "" } }) }, children: [text({ item: "label" })] }
|
|
776
|
+
]
|
|
777
|
+
},
|
|
778
|
+
{ component: "chrome/EmptyState", when: { input: "view.empty" }, props: { title: { input: "view.emptyTitle" }, hint: { input: "view.emptyHint" } } },
|
|
779
|
+
{
|
|
780
|
+
component: "console/Scroller",
|
|
781
|
+
when: { input: "view.listed" },
|
|
782
|
+
children: [
|
|
783
|
+
{
|
|
784
|
+
component: "chrome/VirtualWindow",
|
|
785
|
+
props: { totalHeight: { input: "view.totalHeight" }, offsetTop: { input: "view.offsetTop" } },
|
|
786
|
+
children: [
|
|
787
|
+
{
|
|
788
|
+
component: "chrome/RowList",
|
|
789
|
+
props: { role: { value: "log" } },
|
|
790
|
+
children: [
|
|
791
|
+
{
|
|
792
|
+
component: "fragment",
|
|
793
|
+
each: { input: "view.rows", key: "id" },
|
|
794
|
+
children: [
|
|
795
|
+
{
|
|
796
|
+
component: "chrome/Row",
|
|
797
|
+
props: {
|
|
798
|
+
height: { input: "view.rowHeight" },
|
|
799
|
+
noIcon: { value: true },
|
|
800
|
+
label: {
|
|
801
|
+
node: {
|
|
802
|
+
component: "chrome/Stack",
|
|
803
|
+
props: { direction: { value: "row" }, pad: { value: "none" } },
|
|
804
|
+
children: [
|
|
805
|
+
{ component: "chrome/Text", when: { item: "time" }, props: { role: { value: "number" } }, children: [text({ item: "time" })] },
|
|
806
|
+
{ component: "chrome/Badge", props: { tone: { item: "tone" } }, children: [text({ item: "level" })] },
|
|
807
|
+
{ component: "chrome/Text", when: { item: "source" }, props: { role: { value: "meta" } }, children: [text({ item: "source" })] },
|
|
808
|
+
{ component: "chrome/Text", children: [text({ item: "message" })] }
|
|
809
|
+
]
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
trailing: { node: { component: "chrome/Badge", when: { item: "repeat" }, props: { title: { value: "Repeated consecutively" } }, children: [text({ item: "repeat" })] } }
|
|
813
|
+
},
|
|
814
|
+
on: { onClick: ui("row", { id: { item: "id" } }), onContextMenuAt: ui("contextMenu", { id: { item: "id" }, x: { arg: "", index: 0 }, y: { arg: "", index: 1 } }) }
|
|
815
|
+
},
|
|
816
|
+
{ component: "chrome/Code", when: { item: "expanded" }, children: [text({ item: "detail" })] }
|
|
817
|
+
]
|
|
818
|
+
}
|
|
819
|
+
]
|
|
820
|
+
}
|
|
821
|
+
]
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
},
|
|
825
|
+
{ component: "chrome/StatusBar", props: { left: { input: "view.countLabel" }, right: { input: "view.followLabel" } } }
|
|
826
|
+
]
|
|
827
|
+
}
|
|
828
|
+
};
|
|
829
|
+
|
|
830
|
+
// src/ops/console/react/ConsolePanelView.tsx
|
|
831
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
832
|
+
var CopyGlyph = ICONS["icons/Copy"];
|
|
833
|
+
var ClearGlyph = ICONS["icons/Clear"];
|
|
834
|
+
function ConsoleScroller({ controller, rowHeight = 20, children }) {
|
|
639
835
|
const state = useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
|
|
640
|
-
const
|
|
641
|
-
const [viewport, setViewport] = useState({ height: 0, scrollTop: 0 });
|
|
642
|
-
const [expanded, setExpanded] = useState(null);
|
|
836
|
+
const ref = useRef(null);
|
|
643
837
|
useEffect(() => {
|
|
644
|
-
const
|
|
645
|
-
if (!
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
838
|
+
const el = ref.current;
|
|
839
|
+
if (!el) return;
|
|
840
|
+
controller.setViewport(el.clientHeight, el.scrollTop);
|
|
841
|
+
const RO = globalThis.ResizeObserver;
|
|
842
|
+
if (!RO) return;
|
|
843
|
+
const ro = new RO(() => controller.setViewport(el.clientHeight, el.scrollTop));
|
|
844
|
+
ro.observe(el);
|
|
845
|
+
return () => ro.disconnect();
|
|
846
|
+
}, [controller]);
|
|
651
847
|
useEffect(() => {
|
|
652
|
-
const
|
|
653
|
-
if (!
|
|
654
|
-
|
|
848
|
+
const el = ref.current;
|
|
849
|
+
if (!el || !state.follow) return;
|
|
850
|
+
el.scrollTop = el.scrollHeight;
|
|
655
851
|
}, [state.rows.length, state.follow]);
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
852
|
+
return /* @__PURE__ */ jsx(
|
|
853
|
+
ScrollArea,
|
|
854
|
+
{
|
|
855
|
+
ref,
|
|
856
|
+
onScroll: (e) => {
|
|
857
|
+
const el = e.currentTarget;
|
|
858
|
+
controller.setViewport(el.clientHeight, el.scrollTop);
|
|
859
|
+
const atBottom = el.scrollHeight - el.scrollTop - el.clientHeight < rowHeight;
|
|
860
|
+
if (state.follow && !atBottom) controller.setFollow(false);
|
|
861
|
+
else if (!state.follow && atBottom) controller.setFollow(true);
|
|
862
|
+
},
|
|
863
|
+
children
|
|
864
|
+
}
|
|
665
865
|
);
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
rowHeight,
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
866
|
+
}
|
|
867
|
+
function consoleRuntimeComponents(controller, rowHeight) {
|
|
868
|
+
return {
|
|
869
|
+
"console/Scroller": ({ children }) => /* @__PURE__ */ jsx(ConsoleScroller, { controller, rowHeight, children })
|
|
870
|
+
};
|
|
871
|
+
}
|
|
872
|
+
function ConsolePanelView({ controller, ...options }) {
|
|
873
|
+
useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
|
|
874
|
+
const view = consoleViewState(controller, options);
|
|
875
|
+
const ui2 = (intent) => applyConsoleUi(controller, intent);
|
|
876
|
+
return /* @__PURE__ */ jsxs(Column, { children: [
|
|
674
877
|
/* @__PURE__ */ jsx(
|
|
675
878
|
Toolbar,
|
|
676
879
|
{
|
|
677
880
|
left: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
678
|
-
/* @__PURE__ */ jsx(
|
|
679
|
-
|
|
680
|
-
{
|
|
681
|
-
value: state.filter.search ?? "",
|
|
682
|
-
onChange: (term) => controller.setSearch(term),
|
|
683
|
-
placeholder: "Filter\u2026"
|
|
684
|
-
}
|
|
685
|
-
),
|
|
686
|
-
/* @__PURE__ */ jsx(
|
|
687
|
-
SegmentedControl,
|
|
688
|
-
{
|
|
689
|
-
size: "sm",
|
|
690
|
-
label: "Minimum level",
|
|
691
|
-
options: LEVEL_ORDER.map((l) => ({ value: l, label: l.slice(0, 1).toUpperCase() })),
|
|
692
|
-
value: state.filter.minLevel ?? "trace",
|
|
693
|
-
onChange: (level) => controller.setLevel(level === "trace" ? void 0 : level)
|
|
694
|
-
}
|
|
695
|
-
)
|
|
881
|
+
/* @__PURE__ */ jsx(SearchField, { value: view.search, placeholder: "Filter\u2026", onChange: (value) => ui2({ kind: "search", value }) }),
|
|
882
|
+
/* @__PURE__ */ jsx(SegmentedControl, { size: "sm", label: "Minimum level", options: view.levels, value: view.level, onChange: (level) => ui2({ kind: "level", level }) })
|
|
696
883
|
] }),
|
|
697
884
|
right: /* @__PURE__ */ jsxs(ToolbarGroup, { end: true, children: [
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
/* @__PURE__ */ jsx(
|
|
701
|
-
|
|
702
|
-
{
|
|
703
|
-
icon: /* @__PURE__ */ jsx(CopyGlyph, {}),
|
|
704
|
-
label: "Copy visible",
|
|
705
|
-
onClick: () => {
|
|
706
|
-
void navigator?.clipboard?.writeText(controller.copyVisible());
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
),
|
|
710
|
-
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(ClearGlyph, {}), label: "Clear", onClick: () => controller.clear() })
|
|
885
|
+
view.errors ? /* @__PURE__ */ jsx(Badge, { tone: "error", children: view.errors }) : null,
|
|
886
|
+
view.warns ? /* @__PURE__ */ jsx(Badge, { tone: "warning", children: view.warns }) : null,
|
|
887
|
+
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(CopyGlyph, {}), label: "Copy visible", onClick: () => ui2({ kind: "copyVisible" }) }),
|
|
888
|
+
/* @__PURE__ */ jsx(IconButton, { icon: /* @__PURE__ */ jsx(ClearGlyph, {}), label: "Clear", onClick: () => ui2({ kind: "clear" }) })
|
|
711
889
|
] })
|
|
712
890
|
}
|
|
713
891
|
),
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
{
|
|
732
|
-
record,
|
|
733
|
-
controller,
|
|
734
|
-
rowHeight,
|
|
735
|
-
showTimestamps,
|
|
736
|
-
expanded: expanded === record.id,
|
|
737
|
-
onToggle: () => setExpanded(expanded === record.id ? null : record.id)
|
|
738
|
-
},
|
|
739
|
-
record.id
|
|
740
|
-
)) }) }) }) }) }),
|
|
741
|
-
/* @__PURE__ */ jsx(
|
|
742
|
-
StatusBar,
|
|
743
|
-
{
|
|
744
|
-
left: `${state.rows.length} of ${state.total}` + (state.dropped > 0 ? ` \xB7 ${state.dropped} dropped` : "") + // A patch that addressed nothing is the one streaming failure with no visible symptom:
|
|
745
|
-
// the producer sees no line grow, and a mis-keyed wire looks exactly like a dead one.
|
|
746
|
-
(state.droppedPatches > 0 ? ` \xB7 ${state.droppedPatches} unmatched` : ""),
|
|
747
|
-
right: state.follow ? "following" : void 0
|
|
748
|
-
}
|
|
749
|
-
)
|
|
750
|
-
] });
|
|
751
|
-
}
|
|
752
|
-
function LogRow({
|
|
753
|
-
record,
|
|
754
|
-
controller,
|
|
755
|
-
rowHeight,
|
|
756
|
-
showTimestamps,
|
|
757
|
-
expanded,
|
|
758
|
-
onToggle
|
|
759
|
-
}) {
|
|
760
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
761
|
-
/* @__PURE__ */ jsx(
|
|
762
|
-
Row,
|
|
763
|
-
{
|
|
764
|
-
style: { height: rowHeight, alignItems: "flex-start" },
|
|
765
|
-
noIcon: true,
|
|
766
|
-
onClick: () => {
|
|
767
|
-
if (record.data !== void 0) onToggle();
|
|
768
|
-
controller.activate(record.id);
|
|
769
|
-
},
|
|
770
|
-
onContextMenu: (e) => {
|
|
771
|
-
e.preventDefault();
|
|
772
|
-
controller.requestContextMenu(record.id, e.clientX, e.clientY);
|
|
773
|
-
},
|
|
774
|
-
label: /* @__PURE__ */ jsxs("span", { style: { display: "flex", gap: 6, alignItems: "center", minWidth: 0 }, children: [
|
|
775
|
-
showTimestamps ? /* @__PURE__ */ jsx("span", { style: { opacity: 0.45, fontVariantNumeric: "tabular-nums", flex: "0 0 auto" }, children: new Date(record.ts).toISOString().slice(11, 23) }) : null,
|
|
776
|
-
/* @__PURE__ */ jsx(Badge, { tone: TONE[record.level], children: record.level }),
|
|
777
|
-
record.source ? /* @__PURE__ */ jsx("span", { style: { opacity: 0.55 }, children: record.source }) : null,
|
|
778
|
-
/* @__PURE__ */ jsx(
|
|
779
|
-
"span",
|
|
780
|
-
{
|
|
781
|
-
style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 },
|
|
782
|
-
children: record.message
|
|
783
|
-
}
|
|
784
|
-
)
|
|
785
|
-
] }),
|
|
786
|
-
trailing: (record.count ?? 1) > 1 ? (
|
|
787
|
-
// The best feature in any incumbent: a run of identical lines is one row with a count.
|
|
788
|
-
/* @__PURE__ */ jsx(Badge, { title: "Repeated consecutively", children: `x${record.count}` })
|
|
789
|
-
) : null
|
|
790
|
-
}
|
|
791
|
-
),
|
|
792
|
-
expanded && record.data !== void 0 ? /* @__PURE__ */ jsx(
|
|
793
|
-
"pre",
|
|
794
|
-
{
|
|
795
|
-
style: {
|
|
796
|
-
margin: 0,
|
|
797
|
-
padding: "2px 10px 6px 24px",
|
|
798
|
-
fontSize: 10,
|
|
799
|
-
lineHeight: 1.4,
|
|
800
|
-
whiteSpace: "pre-wrap",
|
|
801
|
-
wordBreak: "break-all",
|
|
802
|
-
opacity: 0.8
|
|
892
|
+
view.multiSource ? /* @__PURE__ */ jsx(Stack, { direction: "row", gap: 4, pad: "inset", children: view.sources.map((source) => /* @__PURE__ */ jsx(FilterChip, { on: source.on, title: source.title, onChange: (on) => ui2({ kind: "source", id: source.id, on }), children: source.label }, source.id)) }) : null,
|
|
893
|
+
view.empty ? /* @__PURE__ */ jsx(EmptyState, { title: view.emptyTitle, hint: view.emptyHint }) : null,
|
|
894
|
+
view.listed ? /* @__PURE__ */ jsx(ConsoleScroller, { controller, rowHeight: view.rowHeight, children: /* @__PURE__ */ jsx(VirtualWindow, { totalHeight: view.totalHeight, offsetTop: view.offsetTop, children: /* @__PURE__ */ jsx(RowList, { role: "log", children: view.rows.map((row) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
895
|
+
/* @__PURE__ */ jsx(
|
|
896
|
+
Row,
|
|
897
|
+
{
|
|
898
|
+
height: view.rowHeight,
|
|
899
|
+
noIcon: true,
|
|
900
|
+
label: /* @__PURE__ */ jsxs(Stack, { direction: "row", pad: "none", children: [
|
|
901
|
+
row.time ? /* @__PURE__ */ jsx(Text, { role: "number", children: row.time }) : null,
|
|
902
|
+
/* @__PURE__ */ jsx(Badge, { tone: row.tone, children: row.level }),
|
|
903
|
+
row.source ? /* @__PURE__ */ jsx(Text, { role: "meta", children: row.source }) : null,
|
|
904
|
+
/* @__PURE__ */ jsx(Text, { children: row.message })
|
|
905
|
+
] }),
|
|
906
|
+
trailing: row.repeat ? /* @__PURE__ */ jsx(Badge, { title: "Repeated consecutively", children: row.repeat }) : null,
|
|
907
|
+
onClick: () => ui2({ kind: "row", id: row.id }),
|
|
908
|
+
onContextMenuAt: (x, y) => ui2({ kind: "contextMenu", id: row.id, x, y })
|
|
803
909
|
},
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
910
|
+
row.id
|
|
911
|
+
),
|
|
912
|
+
row.expanded ? /* @__PURE__ */ jsx(Code, { children: row.detail }, `${row.id}:detail`) : null
|
|
913
|
+
] })) }) }) }) : null,
|
|
914
|
+
/* @__PURE__ */ jsx(StatusBar, { left: view.countLabel, right: view.followLabel })
|
|
807
915
|
] });
|
|
808
916
|
}
|
|
809
917
|
|
|
@@ -1815,12 +1923,12 @@ function TruncationBadge({ reason }) {
|
|
|
1815
1923
|
}
|
|
1816
1924
|
function RowLabel({
|
|
1817
1925
|
status,
|
|
1818
|
-
text,
|
|
1926
|
+
text: text2,
|
|
1819
1927
|
trailing
|
|
1820
1928
|
}) {
|
|
1821
1929
|
return /* @__PURE__ */ jsxs2("span", { style: { display: "flex", gap: 6, alignItems: "center", minWidth: 0 }, children: [
|
|
1822
1930
|
/* @__PURE__ */ jsx2(Badge2, { tone: toneOf(status), children: status }),
|
|
1823
|
-
/* @__PURE__ */ jsx2("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children:
|
|
1931
|
+
/* @__PURE__ */ jsx2("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: text2 }),
|
|
1824
1932
|
trailing
|
|
1825
1933
|
] });
|
|
1826
1934
|
}
|
|
@@ -2822,11 +2930,11 @@ function omissionLabel(omission) {
|
|
|
2822
2930
|
}
|
|
2823
2931
|
|
|
2824
2932
|
// src/ops/diff/controller.ts
|
|
2825
|
-
var
|
|
2933
|
+
var EMPTY2 = { files: [], status: "idle" };
|
|
2826
2934
|
var DiffController = class {
|
|
2827
2935
|
host;
|
|
2828
2936
|
reviewEnabled;
|
|
2829
|
-
model =
|
|
2937
|
+
model = EMPTY2;
|
|
2830
2938
|
rev = -1;
|
|
2831
2939
|
decisions = /* @__PURE__ */ new Map();
|
|
2832
2940
|
view;
|
|
@@ -3089,7 +3197,7 @@ var DiffController = class {
|
|
|
3089
3197
|
/** Tear down. */
|
|
3090
3198
|
dispose() {
|
|
3091
3199
|
this.listeners.clear();
|
|
3092
|
-
this.model =
|
|
3200
|
+
this.model = EMPTY2;
|
|
3093
3201
|
this.decisions.clear();
|
|
3094
3202
|
}
|
|
3095
3203
|
};
|
|
@@ -3245,8 +3353,8 @@ var MARK = {
|
|
|
3245
3353
|
context: {}
|
|
3246
3354
|
};
|
|
3247
3355
|
var SIGIL = { added: "+", removed: "-", context: " " };
|
|
3248
|
-
function visible(
|
|
3249
|
-
return show ?
|
|
3356
|
+
function visible(text2, show) {
|
|
3357
|
+
return show ? text2.replace(/\t/g, "\u2192 ").replace(/ /g, "\xB7") : text2;
|
|
3250
3358
|
}
|
|
3251
3359
|
function LineText({
|
|
3252
3360
|
line,
|
|
@@ -3629,9 +3737,13 @@ function createDiffPanel(options = {}) {
|
|
|
3629
3737
|
var diffPanel = createDiffPanel();
|
|
3630
3738
|
export {
|
|
3631
3739
|
ALL_STATUSES,
|
|
3740
|
+
BEHAVIOURS as CONSOLE_BEHAVIOURS,
|
|
3741
|
+
CONSOLE_DECLARATION,
|
|
3632
3742
|
CONSOLE_PANEL_ID,
|
|
3743
|
+
CONSOLE_RUNTIME_UNITS,
|
|
3633
3744
|
ConsoleController,
|
|
3634
3745
|
ConsolePanelView,
|
|
3746
|
+
ConsoleScroller,
|
|
3635
3747
|
DEFAULT_MAX_STEP_DEPTH,
|
|
3636
3748
|
DIFF_PANEL_ID,
|
|
3637
3749
|
DiffController,
|
|
@@ -3650,12 +3762,16 @@ export {
|
|
|
3650
3762
|
TerminalPanelView,
|
|
3651
3763
|
XENO_TERMINAL_THEME_KEYS,
|
|
3652
3764
|
appendStepsAtPath,
|
|
3765
|
+
applyConsoleUi,
|
|
3653
3766
|
canCancel,
|
|
3654
3767
|
canRetry,
|
|
3655
3768
|
collapseAdjacent,
|
|
3656
3769
|
computeStats,
|
|
3657
3770
|
consoleManifest,
|
|
3658
3771
|
consolePanel,
|
|
3772
|
+
consoleRuntimeComponents,
|
|
3773
|
+
consoleViewManifest,
|
|
3774
|
+
consoleViewState,
|
|
3659
3775
|
countChanges,
|
|
3660
3776
|
createConsolePanel,
|
|
3661
3777
|
createDiffPanel,
|
package/dist/time/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.12",
|
|
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",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
66
66
|
"@xenosystem/block-sdk": ">=0.3.4 <1",
|
|
67
|
-
"@xenosystem/components": ">=0.
|
|
67
|
+
"@xenosystem/components": ">=0.22.0 <1",
|
|
68
68
|
"@xenosystem/data-core": "^0.1.0",
|
|
69
69
|
"@xenosystem/elements": ">=0.0.1",
|
|
70
70
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react": "^19.0.0",
|
|
82
82
|
"@types/react-dom": "^19.0.0",
|
|
83
83
|
"@xenosystem/block-sdk": "^0.3.4",
|
|
84
|
-
"@xenosystem/components": "^0.
|
|
84
|
+
"@xenosystem/components": "^0.22.0",
|
|
85
85
|
"@xenosystem/data-core": "^0.1.0",
|
|
86
86
|
"@xenosystem/elements": "0.0.1",
|
|
87
87
|
"@xenosystem/elements-react": "0.0.1",
|