@stephen-netu/design-system 0.2.0 → 0.2.2
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/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte +10 -2
- package/dist/b0-app-shell/clarification-overlay/ClarificationOverlay.svelte.d.ts.map +1 -1
- package/dist/b0-app-shell/{command-bar/CommandBar.svelte → global-command-bar/GlobalCommandBar.svelte} +75 -75
- package/dist/b0-app-shell/{command-bar/CommandBar.svelte.d.ts → global-command-bar/GlobalCommandBar.svelte.d.ts} +6 -6
- package/dist/b0-app-shell/global-command-bar/GlobalCommandBar.svelte.d.ts.map +1 -0
- package/dist/b0-app-shell/index.d.ts +1 -1
- package/dist/b0-app-shell/index.d.ts.map +1 -1
- package/dist/b0-app-shell/index.js +1 -1
- package/dist/d0-data-viz/CheckpointPill.svelte +7 -2
- package/dist/d0-data-viz/CheckpointPill.svelte.d.ts.map +1 -1
- package/dist/d0-data-viz/theme-integration.d.ts +3 -3
- package/dist/d0-data-viz/theme-integration.js +3 -3
- package/dist/d0-data-viz/theme-integration.test.js +41 -0
- package/dist/demos/BspSizingInfographic.svelte +3 -32
- package/dist/editor/CodeEditor.test.js +38 -0
- package/dist/editor/FindReplaceDialog.svelte +32 -32
- package/dist/editor/MarkdownEditor.svelte +71 -58
- package/dist/editor/MarkdownEditor.svelte.d.ts.map +1 -1
- package/dist/editor/MarkdownEditor.test.js +38 -0
- package/dist/editor/components/CorrectionTooltip.svelte +0 -1
- package/dist/editor/extensions/expansion.d.ts.map +1 -1
- package/dist/editor/extensions/expansion.js +16 -10
- package/dist/entity-graph-view/WorldView.svelte +1 -1
- package/dist/fabric/ai/ChatPanel.svelte +31 -31
- package/dist/fabric/ai/ResearchPanel.svelte +6 -3
- package/dist/fabric/ai/ResearchPanel.svelte.d.ts.map +1 -1
- package/dist/fabric/index.d.ts +4 -5
- package/dist/fabric/index.d.ts.map +1 -1
- package/dist/fabric/index.js +3 -3
- package/dist/fabric/input/{CommandBar.svelte → AppHeaderBar.svelte} +13 -13
- package/dist/fabric/input/{CommandBar.svelte.d.ts → AppHeaderBar.svelte.d.ts} +5 -5
- package/dist/fabric/input/AppHeaderBar.svelte.d.ts.map +1 -0
- package/dist/fabric/input/{CommandBar.test.js → AppHeaderBar.test.js} +9 -9
- package/dist/fabric/input/index.d.ts +2 -2
- package/dist/fabric/input/index.d.ts.map +1 -1
- package/dist/fabric/input/index.js +1 -1
- package/dist/fabric/layout/KanbanBoard.svelte +25 -155
- package/dist/fabric/layout/KanbanBoard.svelte.d.ts +2 -26
- package/dist/fabric/layout/KanbanBoard.svelte.d.ts.map +1 -1
- package/dist/fabric/layout/KanbanBoard.test.js +125 -10
- package/dist/fabric/layout/KanbanCard.svelte +27 -223
- package/dist/fabric/layout/KanbanCard.svelte.d.ts +2 -19
- package/dist/fabric/layout/KanbanCard.svelte.d.ts.map +1 -1
- package/dist/fabric/layout/KanbanColumn.svelte +41 -275
- package/dist/fabric/layout/KanbanColumn.svelte.d.ts +2 -22
- package/dist/fabric/layout/KanbanColumn.svelte.d.ts.map +1 -1
- package/dist/fabric/layout/index.d.ts +2 -5
- package/dist/fabric/layout/index.d.ts.map +1 -1
- package/dist/fabric/layout/index.js +1 -1
- package/dist/g0-generative/renderer/OpenUIRenderer.svelte +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/l0-layout/SectionSplitter.svelte +5 -5
- package/dist/l0-layout/block-writer/BlockItem.svelte +6 -4
- package/dist/l0-layout/card/CompactCard.svelte +4 -3
- package/dist/l0-layout/grant/GrantCard.svelte +15 -5
- package/dist/l0-layout/grant/GrantCard.svelte.d.ts.map +1 -1
- package/dist/l0-layout/index.d.ts +2 -0
- package/dist/l0-layout/index.d.ts.map +1 -1
- package/dist/l0-layout/index.js +1 -0
- package/dist/l0-layout/kanban/KanbanBoard.svelte +246 -29
- package/dist/l0-layout/kanban/KanbanBoard.svelte.d.ts +28 -2
- package/dist/l0-layout/kanban/KanbanBoard.svelte.d.ts.map +1 -1
- package/dist/l0-layout/kanban/KanbanCard.svelte +175 -150
- package/dist/l0-layout/kanban/KanbanCard.svelte.d.ts +16 -18
- package/dist/l0-layout/kanban/KanbanCard.svelte.d.ts.map +1 -1
- package/dist/l0-layout/kanban/KanbanColumn.svelte +152 -78
- package/dist/l0-layout/kanban/KanbanColumn.svelte.d.ts +28 -7
- package/dist/l0-layout/kanban/KanbanColumn.svelte.d.ts.map +1 -1
- package/dist/l0-layout/kanban/index.d.ts +6 -0
- package/dist/l0-layout/kanban/index.d.ts.map +1 -0
- package/dist/l0-layout/kanban/index.js +3 -0
- package/dist/n0-node-graph/Node.svelte +2 -2
- package/dist/n0-node-graph/NodePalette.svelte +2 -2
- package/dist/n1-flow-canvas/graph-state.test.js +69 -0
- package/dist/n1-flow-canvas/utils.test.js +116 -0
- package/dist/n3-force-graph/GraphTooltip.svelte +2 -2
- package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte +12 -11
- package/dist/n4-adaptive-manifold/AdaptiveManifold.svelte.d.ts.map +1 -1
- package/dist/n4-adaptive-manifold/classifier.test.js +104 -0
- package/dist/n4-adaptive-manifold/n4-tokens.css +2 -2
- package/dist/p0-primitives/ThemeProvider.svelte +10 -11
- package/dist/p0-primitives/ThemeProvider.svelte.d.ts +1 -1
- package/dist/p0-primitives/ThemeProvider.svelte.d.ts.map +1 -1
- package/dist/p0-primitives/canvas-theme.d.ts +12 -0
- package/dist/p0-primitives/canvas-theme.d.ts.map +1 -1
- package/dist/p0-primitives/canvas-theme.js +10 -0
- package/dist/p0-primitives/index.d.ts +2 -1
- package/dist/p0-primitives/index.d.ts.map +1 -1
- package/dist/p0-primitives/index.js +1 -0
- package/dist/p0-primitives/theme-context.d.ts +9 -0
- package/dist/p0-primitives/theme-context.d.ts.map +1 -0
- package/dist/p0-primitives/theme-context.js +8 -0
- package/dist/p0-primitives/tokens/tokens.css +22 -11
- package/dist/p0-primitives/utils/index.d.ts +2 -2
- package/dist/p0-primitives/utils/index.d.ts.map +1 -1
- package/dist/s0-state/SyncStatus.svelte +1 -1
- package/dist/s0-state/ThemeStore.svelte.d.ts +3 -2
- package/dist/s0-state/ThemeStore.svelte.d.ts.map +1 -1
- package/dist/s0-state/ThemeStore.svelte.js +20 -1
- package/dist/s0-state/index.d.ts +0 -1
- package/dist/s0-state/index.d.ts.map +1 -1
- package/dist/s0-state/index.js +1 -0
- package/dist/s0-state/modal-stack-store.svelte.d.ts +25 -0
- package/dist/s0-state/modal-stack-store.svelte.d.ts.map +1 -1
- package/dist/s0-state/modal-stack-store.svelte.js +19 -0
- package/dist/showcase/Showcase.svelte +43 -34
- package/dist/showcase/Showcase.svelte.d.ts.map +1 -1
- package/dist/spatial/BspTilingCanvas.svelte +7 -5
- package/dist/spatial/BspTilingCanvas.svelte.d.ts +1 -0
- package/dist/spatial/BspTilingCanvas.svelte.d.ts.map +1 -1
- package/dist/spatial/BspTilingSimulation.test.js +88 -0
- package/dist/spatial/CameraController.test.js +120 -0
- package/dist/spatial/ForceCanvas.svelte +20 -13
- package/dist/spatial/ForceCanvas.svelte.d.ts +1 -0
- package/dist/spatial/ForceCanvas.svelte.d.ts.map +1 -1
- package/dist/spatial/ForceSimulation.svelte.d.ts.map +1 -1
- package/dist/spatial/ForceSimulation.svelte.js +32 -21
- package/dist/spatial/LodRenderer.svelte +16 -1
- package/dist/spatial/LodRenderer.svelte.d.ts +1 -0
- package/dist/spatial/LodRenderer.svelte.d.ts.map +1 -1
- package/dist/spatial/SnapZoomCamera.svelte +25 -13
- package/dist/spatial/SnapZoomCamera.svelte.d.ts +1 -0
- package/dist/spatial/SnapZoomCamera.svelte.d.ts.map +1 -1
- package/dist/spatial/ZoneTiler.svelte +5 -2
- package/dist/spatial/ZoneTiler.svelte.d.ts +1 -0
- package/dist/spatial/ZoneTiler.svelte.d.ts.map +1 -1
- package/dist/spatial/d3-types.d.ts +31 -0
- package/dist/spatial/d3-types.d.ts.map +1 -0
- package/dist/spatial/d3-types.js +19 -0
- package/dist/ssr-import-clean.test.js +37 -0
- package/dist/t0-transport/fs.d.ts +12 -0
- package/dist/t0-transport/fs.d.ts.map +1 -0
- package/dist/t0-transport/fs.js +55 -0
- package/dist/t0-transport/index.d.ts +1 -0
- package/dist/t0-transport/index.d.ts.map +1 -1
- package/dist/t0-transport/index.js +1 -0
- package/dist/t0-transport/invoke.d.ts.map +1 -1
- package/dist/t0-transport/invoke.js +5 -2
- package/dist/t0-transport/quality.d.ts +12 -3
- package/dist/t0-transport/quality.d.ts.map +1 -1
- package/dist/t0-transport/quality.js +17 -4
- package/dist/t0-transport/substrate.svelte.d.ts +27 -0
- package/dist/t0-transport/substrate.svelte.d.ts.map +1 -0
- package/dist/t0-transport/substrate.svelte.js +49 -0
- package/dist/u0-primitives/LockIndicator.svelte +1 -1
- package/dist/u0-primitives/VerticalToolbar.svelte +1 -1
- package/dist/u0-primitives/accordion/Accordion.svelte +10 -9
- package/dist/u0-primitives/accordion/Accordion.svelte.d.ts +0 -7
- package/dist/u0-primitives/accordion/Accordion.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/accordion/Accordion.test.js +5 -5
- package/dist/u0-primitives/badge/Badge.test.js +10 -10
- package/dist/u0-primitives/badge/ValidityBadge.test.js +9 -9
- package/dist/u0-primitives/button/Button.svelte +3 -1
- package/dist/u0-primitives/button/Button.svelte.d.ts +1 -0
- package/dist/u0-primitives/button/Button.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/button/Button.test.js +11 -11
- package/dist/u0-primitives/card/Card.svelte +26 -20
- package/dist/u0-primitives/card/Card.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/command-palette/CommandPalette.svelte +27 -0
- package/dist/u0-primitives/command-palette/CommandPalette.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/command-palette/commandStore.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/command-palette/commandStore.svelte.js +2 -1
- package/dist/u0-primitives/dropdown/Dropdown.test.js +1 -1
- package/dist/u0-primitives/index.d.ts +2 -0
- package/dist/u0-primitives/index.d.ts.map +1 -1
- package/dist/u0-primitives/index.js +1 -0
- package/dist/u0-primitives/input/Input.svelte +9 -0
- package/dist/u0-primitives/input/Input.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/input/Input.test.js +1 -1
- package/dist/u0-primitives/modal/Modal.svelte +46 -23
- package/dist/u0-primitives/modal/Modal.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/modal/Modal.test.js +63 -15
- package/dist/u0-primitives/rsvp/RsvpReader.svelte +8 -8
- package/dist/u0-primitives/rsvp/RsvpReader.svelte.d.ts.map +1 -1
- package/dist/u0-primitives/steps/Steps.svelte +2 -2
- package/dist/u0-primitives/surface-state/SurfaceState.svelte +190 -0
- package/dist/u0-primitives/surface-state/SurfaceState.svelte.d.ts +15 -0
- package/dist/u0-primitives/surface-state/SurfaceState.svelte.d.ts.map +1 -0
- package/dist/u0-primitives/toggle/Toggle.svelte +12 -2
- package/dist/u0-primitives/tooltip/Tooltip.test.js +12 -12
- package/dist/v0-diagrams/MarkmapDiagram.test.js +49 -0
- package/dist/v0-diagrams/MermaidDiagram.svelte +21 -9
- package/dist/v0-diagrams/MermaidDiagram.svelte.d.ts.map +1 -1
- package/dist/v0-diagrams/MermaidDiagram.test.js +40 -0
- package/package.json +51 -24
- package/src/n4-adaptive-manifold/n4-tokens.css +2 -2
- package/src/p0-primitives/tokens/tokens.css +22 -11
- package/src/p0-primitives/tokens/tokens.json +13 -2
- package/dist/b0-app-shell/command-bar/CommandBar.svelte.d.ts.map +0 -1
- package/dist/fabric/input/CommandBar.svelte.d.ts.map +0 -1
- package/dist/stores/vaultStore.svelte +0 -14
- package/dist/stores/vaultStore.svelte.d.ts +0 -24
- package/dist/stores/vaultStore.svelte.d.ts.map +0 -1
- package/dist/tauri/index.d.ts +0 -3
- package/dist/tauri/index.d.ts.map +0 -1
- package/dist/tauri/index.js +0 -11
- package/dist/types/tauri.d.ts +0 -18
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
//
|
|
5
5
|
// S-02: No Math.random — initial positions seeded by node index.
|
|
6
6
|
// S-05: alphaDecay bounds simulation convergence; RAF cancelled on destroy.
|
|
7
|
+
import { toD3Node, toD3Link } from './d3-types';
|
|
7
8
|
import { weightToRadius, cosineSimilarity, semanticSpringLength } from './force-canvas-types';
|
|
8
9
|
const MIN_ZONE_PAD = 40;
|
|
9
10
|
export class ForceSimulation {
|
|
@@ -51,9 +52,9 @@ export class ForceSimulation {
|
|
|
51
52
|
this.positions = [];
|
|
52
53
|
return;
|
|
53
54
|
}
|
|
54
|
-
const
|
|
55
|
+
const d3Mod = await import('d3-force');
|
|
55
56
|
if (gen !== this.generation)
|
|
56
|
-
return;
|
|
57
|
+
return;
|
|
57
58
|
const cfg = this.config;
|
|
58
59
|
const w = this.boundsWidth;
|
|
59
60
|
const h = this.boundsHeight;
|
|
@@ -66,33 +67,43 @@ export class ForceSimulation {
|
|
|
66
67
|
const velocityDecay = cfg?.velocityDecay ?? 0.4;
|
|
67
68
|
const cx = w / 2;
|
|
68
69
|
const cy = h / 2;
|
|
69
|
-
|
|
70
|
+
const nodes = this.cells.map((cell, i) => {
|
|
70
71
|
if (cell.x === undefined) {
|
|
71
|
-
|
|
72
|
-
cell.
|
|
73
|
-
cell.y = cy + (cell.index ?? 0) * 2;
|
|
72
|
+
cell.x = cx + (cell.index ?? i) * 3;
|
|
73
|
+
cell.y = cy + (cell.index ?? i) * 2;
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
return toD3Node(cell);
|
|
76
|
+
});
|
|
77
|
+
const links = this.buildLinks().map(toD3Link);
|
|
78
|
+
const sim = d3Mod.forceSimulation(nodes)
|
|
79
79
|
.alphaDecay(0.02)
|
|
80
80
|
.velocityDecay(velocityDecay)
|
|
81
|
-
.force('charge',
|
|
82
|
-
.force('collision',
|
|
83
|
-
|
|
84
|
-
.
|
|
81
|
+
.force('charge', d3Mod.forceManyBody().strength(chargeStrength))
|
|
82
|
+
.force('collision', d3Mod.forceCollide().radius((d) => {
|
|
83
|
+
const cell = this.cells.find((c) => c.id === d.id);
|
|
84
|
+
return cell ? weightToRadius(cell.weight) + collisionPadding : collisionPadding + 8;
|
|
85
|
+
}))
|
|
86
|
+
.force('link', d3Mod.forceLink(links).id((d) => d.id)
|
|
87
|
+
.distance((l) => semanticSpringLength(1 - (l.distance ?? 0.5), minSpring, maxSpring))
|
|
85
88
|
.strength(0.5))
|
|
86
|
-
.force('center',
|
|
89
|
+
.force('center', d3Mod.forceCenter(cx, cy).strength(0.03))
|
|
87
90
|
.force('wall', this.wallForce(w, h, wallMargin, wallStrength))
|
|
88
91
|
.on('tick', () => {
|
|
89
|
-
this.positions =
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
this.positions = nodes.map((n) => {
|
|
93
|
+
const cell = this.cells.find((c) => c.id === n.id);
|
|
94
|
+
return {
|
|
95
|
+
x: n.x ?? cx,
|
|
96
|
+
y: n.y ?? cy,
|
|
97
|
+
radius: weightToRadius(cell.weight),
|
|
98
|
+
cell,
|
|
99
|
+
};
|
|
100
|
+
});
|
|
95
101
|
});
|
|
102
|
+
if (gen !== this.generation) {
|
|
103
|
+
sim.stop();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.simulation = sim;
|
|
96
107
|
}
|
|
97
108
|
buildLinks() {
|
|
98
109
|
const links = [];
|
|
@@ -53,6 +53,8 @@
|
|
|
53
53
|
onCellClick?: (cellId: string, level: LodLevel) => void;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
export type LodRendererProps = Props;
|
|
57
|
+
|
|
56
58
|
let {
|
|
57
59
|
positions,
|
|
58
60
|
zoom,
|
|
@@ -207,12 +209,25 @@
|
|
|
207
209
|
{@const state = getLodState(pos.cell.id)}
|
|
208
210
|
{@const isTransitioning = state?.transitionProgress !== null && state?.transitionProgress !== undefined}
|
|
209
211
|
|
|
212
|
+
{@const cellAttrs = onCellClick ? {
|
|
213
|
+
role: 'button',
|
|
214
|
+
tabindex: 0,
|
|
215
|
+
'aria-label': 'Open cell at current level of detail',
|
|
216
|
+
onclick: () => onCellClick?.(pos.cell.id, currentLod),
|
|
217
|
+
onkeydown: (e: KeyboardEvent) => {
|
|
218
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
onCellClick?.(pos.cell.id, currentLod);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} : {}}
|
|
224
|
+
|
|
210
225
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
211
226
|
<div
|
|
212
227
|
class="lod-cell"
|
|
213
228
|
style:left="{pos.x - pos.radius}px"
|
|
214
229
|
style:top="{pos.y - pos.radius}px"
|
|
215
|
-
|
|
230
|
+
{...cellAttrs}
|
|
216
231
|
data-lod={currentLod}
|
|
217
232
|
data-cell-id={pos.cell.id}
|
|
218
233
|
>
|
|
@@ -28,6 +28,7 @@ interface Props {
|
|
|
28
28
|
/** Click handler — forwarded from individual cells */
|
|
29
29
|
onCellClick?: (cellId: string, level: LodLevel) => void;
|
|
30
30
|
}
|
|
31
|
+
export type LodRendererProps = Props;
|
|
31
32
|
declare const LodRenderer: import("svelte").Component<Props, {}, "">;
|
|
32
33
|
type LodRenderer = ReturnType<typeof LodRenderer>;
|
|
33
34
|
export default LodRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LodRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/LodRenderer.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;AAQ9E,UAAU,KAAK;IACb,sCAAsC;IACtC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAI3B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C;8DAC0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7C,sDAAsD;IACtD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACzD;
|
|
1
|
+
{"version":3,"file":"LodRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/LodRenderer.svelte.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAgB,MAAM,gBAAgB,CAAC;AAQ9E,UAAU,KAAK;IACb,sCAAsC;IACtC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAI3B,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C,wBAAwB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC7C;8DAC0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;IAE7C,sDAAsD;IACtD,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CACzD;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAmOvC,QAAA,MAAM,WAAW,2CAAwC,CAAC;AAC1D,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAClD,eAAe,WAAW,CAAC"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// Renders via CSS transforms on a wrapper div
|
|
5
5
|
|
|
6
6
|
import type { Snippet } from 'svelte';
|
|
7
|
-
import { onMount, onDestroy } from 'svelte';
|
|
7
|
+
import { onMount, onDestroy, untrack } from 'svelte';
|
|
8
8
|
import { CameraController } from './CameraController.svelte.js';
|
|
9
9
|
import type { CameraState, SnapZoomTarget, CameraConfig } from './camera-types.js';
|
|
10
10
|
import type { InteractionContext } from '../s0-lifecycle/InteractionContext.js';
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
onCameraChange?: (state: CameraState) => void;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
export type SnapZoomCameraProps = Props;
|
|
21
|
+
|
|
20
22
|
let {
|
|
21
23
|
width,
|
|
22
24
|
height,
|
|
@@ -25,8 +27,21 @@
|
|
|
25
27
|
onCameraChange,
|
|
26
28
|
}: Props = $props();
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
const cameraState: CameraState = $derived(controller
|
|
30
|
+
let controller = $state<CameraController | null>(null);
|
|
31
|
+
const cameraState: CameraState = $derived(controller?.getCameraState() ?? { zoom: 1, panX: 0, panY: 0 });
|
|
32
|
+
const panX = $derived(controller?.panX ?? 0);
|
|
33
|
+
const panY = $derived(controller?.panY ?? 0);
|
|
34
|
+
const zoom = $derived(controller?.zoom ?? 1);
|
|
35
|
+
|
|
36
|
+
$effect(() => {
|
|
37
|
+
void width;
|
|
38
|
+
void height;
|
|
39
|
+
void config;
|
|
40
|
+
untrack(() => {
|
|
41
|
+
controller = new CameraController(width, height, config);
|
|
42
|
+
runPhases();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
30
45
|
|
|
31
46
|
$effect(() => {
|
|
32
47
|
onCameraChange?.(cameraState);
|
|
@@ -35,6 +50,7 @@
|
|
|
35
50
|
// ── Contexts for lifecycle phases ─────────────────────────────────────────
|
|
36
51
|
|
|
37
52
|
function runPhases(): void {
|
|
53
|
+
if (!controller) return;
|
|
38
54
|
controller.constrain({
|
|
39
55
|
available: {
|
|
40
56
|
width: { min: width, preferred: width, max: width },
|
|
@@ -59,17 +75,13 @@
|
|
|
59
75
|
});
|
|
60
76
|
}
|
|
61
77
|
|
|
62
|
-
onMount(() => {
|
|
63
|
-
runPhases();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
78
|
// ── Interaction forwarding ────────────────────────────────────────────────
|
|
67
79
|
|
|
68
80
|
let wheelRafId: number | null = null;
|
|
69
81
|
let pendingWheelEvent: WheelEvent | null = null;
|
|
70
82
|
|
|
71
83
|
onDestroy(() => {
|
|
72
|
-
controller
|
|
84
|
+
controller?.stop();
|
|
73
85
|
if (wheelRafId !== null) cancelAnimationFrame(wheelRafId);
|
|
74
86
|
});
|
|
75
87
|
|
|
@@ -118,14 +130,14 @@
|
|
|
118
130
|
pendingWheelEvent = null;
|
|
119
131
|
if (evt) {
|
|
120
132
|
const ctx = makeInteractionContext(evt);
|
|
121
|
-
controller
|
|
133
|
+
controller?.interact(ctx);
|
|
122
134
|
}
|
|
123
135
|
});
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
function handlePointerDown(e: PointerEvent) {
|
|
127
139
|
const ctx = makeInteractionContext(e);
|
|
128
|
-
const outcome = controller
|
|
140
|
+
const outcome = controller?.interact(ctx);
|
|
129
141
|
if (outcome === 'consumed') {
|
|
130
142
|
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
|
131
143
|
}
|
|
@@ -133,12 +145,12 @@
|
|
|
133
145
|
|
|
134
146
|
function handlePointerMove(e: PointerEvent) {
|
|
135
147
|
const ctx = makeInteractionContext(e);
|
|
136
|
-
controller
|
|
148
|
+
controller?.interact(ctx);
|
|
137
149
|
}
|
|
138
150
|
|
|
139
151
|
function handlePointerUp(e: PointerEvent) {
|
|
140
152
|
const ctx = makeInteractionContext(e);
|
|
141
|
-
controller
|
|
153
|
+
controller?.interact(ctx);
|
|
142
154
|
}
|
|
143
155
|
</script>
|
|
144
156
|
|
|
@@ -155,7 +167,7 @@
|
|
|
155
167
|
>
|
|
156
168
|
<div
|
|
157
169
|
class="camera-viewport"
|
|
158
|
-
style:transform="translate({
|
|
170
|
+
style:transform="translate({panX}px, {panY}px) scale({zoom})"
|
|
159
171
|
style:transform-origin="0 0"
|
|
160
172
|
>
|
|
161
173
|
{@render children(cameraState)}
|
|
@@ -7,6 +7,7 @@ interface Props {
|
|
|
7
7
|
children: Snippet<[CameraState]>;
|
|
8
8
|
onCameraChange?: (state: CameraState) => void;
|
|
9
9
|
}
|
|
10
|
+
export type SnapZoomCameraProps = Props;
|
|
10
11
|
declare const SnapZoomCamera: import("svelte").Component<Props, {}, "">;
|
|
11
12
|
type SnapZoomCamera = ReturnType<typeof SnapZoomCamera>;
|
|
12
13
|
export default SnapZoomCamera;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SnapZoomCamera.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/SnapZoomCamera.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAkB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjF,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C;
|
|
1
|
+
{"version":3,"file":"SnapZoomCamera.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/SnapZoomCamera.svelte.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,OAAO,KAAK,EAAE,WAAW,EAAkB,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIjF,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAgK1C,QAAA,MAAM,cAAc,2CAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
|
|
@@ -43,6 +43,8 @@
|
|
|
43
43
|
onSplitRequest?: (zoneId: string, direction: SplitDirection) => void;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export type ZoneTilerProps = Props;
|
|
47
|
+
|
|
46
48
|
let {
|
|
47
49
|
tree,
|
|
48
50
|
width,
|
|
@@ -202,7 +204,7 @@
|
|
|
202
204
|
style:height="{height}px"
|
|
203
205
|
onkeydown={handleKeydown}
|
|
204
206
|
tabindex="0"
|
|
205
|
-
role="
|
|
207
|
+
role="grid"
|
|
206
208
|
aria-label="Zone tiler — use h/j/k/l to navigate zones"
|
|
207
209
|
>
|
|
208
210
|
<!-- Zone panes -->
|
|
@@ -217,7 +219,8 @@
|
|
|
217
219
|
style:width="{zone.width}px"
|
|
218
220
|
style:height="{zone.height}px"
|
|
219
221
|
tabindex="0"
|
|
220
|
-
role="
|
|
222
|
+
role="button"
|
|
223
|
+
aria-pressed={zone.id === focusedZoneId}
|
|
221
224
|
aria-label={zone.zone.label}
|
|
222
225
|
data-zone-id={zone.id}
|
|
223
226
|
onclick={() => handleZoneClick(zone.id)}
|
|
@@ -20,6 +20,7 @@ interface Props {
|
|
|
20
20
|
/** Fired when user requests a zone split (Ctrl+Shift+H/V) */
|
|
21
21
|
onSplitRequest?: (zoneId: string, direction: SplitDirection) => void;
|
|
22
22
|
}
|
|
23
|
+
export type ZoneTilerProps = Props;
|
|
23
24
|
declare const ZoneTiler: import("svelte").Component<Props, {}, "focusedZoneId">;
|
|
24
25
|
type ZoneTiler = ReturnType<typeof ZoneTiler>;
|
|
25
26
|
export default ZoneTiler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ZoneTiler.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ZoneTiler.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EACR,OAAO,EACP,QAAQ,EAER,eAAe,EAEf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAM/B,UAAU,KAAK;IACb,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,gCAAgC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACtE;
|
|
1
|
+
{"version":3,"file":"ZoneTiler.svelte.d.ts","sourceRoot":"","sources":["../../src/spatial/ZoneTiler.svelte.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,KAAK,EACR,OAAO,EACP,QAAQ,EAER,eAAe,EAEf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAM/B,UAAU,KAAK;IACb,wCAAwC;IACxC,IAAI,EAAE,OAAO,CAAC;IACd,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjC,8BAA8B;IAC9B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,gCAAgC;IAChC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,6DAA6D;IAC7D,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACtE;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,CAAC;AAsMrC,QAAA,MAAM,SAAS,wDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ForceCell, ForceLink } from './force-canvas-types';
|
|
2
|
+
export interface D3SimulationNode {
|
|
3
|
+
id: string;
|
|
4
|
+
index?: number;
|
|
5
|
+
x?: number;
|
|
6
|
+
y?: number;
|
|
7
|
+
vx?: number;
|
|
8
|
+
vy?: number;
|
|
9
|
+
fx?: number | null;
|
|
10
|
+
fy?: number | null;
|
|
11
|
+
}
|
|
12
|
+
export interface D3ForceLink<T extends D3SimulationNode = D3SimulationNode> {
|
|
13
|
+
source: T | string;
|
|
14
|
+
target: T | string;
|
|
15
|
+
distance?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface D3Simulation<T extends D3SimulationNode = D3SimulationNode> {
|
|
18
|
+
force(name: string): unknown;
|
|
19
|
+
force(name: string, force: unknown): this;
|
|
20
|
+
nodes(): T[];
|
|
21
|
+
nodes(nodes: T[]): this;
|
|
22
|
+
alphaDecay(): number;
|
|
23
|
+
alphaDecay(decay: number): this;
|
|
24
|
+
velocityDecay(): number;
|
|
25
|
+
velocityDecay(decay: number): this;
|
|
26
|
+
on(event: string, listener: (() => void) | null): this;
|
|
27
|
+
stop(): void;
|
|
28
|
+
}
|
|
29
|
+
export declare function toD3Node(cell: ForceCell): D3SimulationNode;
|
|
30
|
+
export declare function toD3Link(link: ForceLink): D3ForceLink;
|
|
31
|
+
//# sourceMappingURL=d3-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d3-types.d.ts","sourceRoot":"","sources":["../../src/spatial/d3-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IACxE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;IACnB,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,gBAAgB,GAAG,gBAAgB;IACzE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7B,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1C,KAAK,IAAI,CAAC,EAAE,CAAC;IACb,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IACxB,UAAU,IAAI,MAAM,CAAC;IACrB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,aAAa,IAAI,MAAM,CAAC;IACxB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IACvD,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,gBAAgB,CAW1D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,WAAW,CAMrD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function toD3Node(cell) {
|
|
2
|
+
return {
|
|
3
|
+
id: cell.id,
|
|
4
|
+
index: cell.index,
|
|
5
|
+
x: cell.x,
|
|
6
|
+
y: cell.y,
|
|
7
|
+
vx: cell.vx,
|
|
8
|
+
vy: cell.vy,
|
|
9
|
+
fx: cell.fx,
|
|
10
|
+
fy: cell.fy,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function toD3Link(link) {
|
|
14
|
+
return {
|
|
15
|
+
source: link.source,
|
|
16
|
+
target: link.target,
|
|
17
|
+
distance: link.distance,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* F-30a: Verify that key modules import cleanly without browser-API violations.
|
|
3
|
+
*
|
|
4
|
+
* vitest-setup.ts injects a localStorage mock and jsdom provides window/document,
|
|
5
|
+
* which can mask SSR violations. This test verifies that pure logic modules
|
|
6
|
+
* (no DOM, no browser-only APIs) import and execute without errors.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
describe('F-30a import-clean (pure modules)', () => {
|
|
10
|
+
it('quality module imports cleanly (module-scope singletons)', async () => {
|
|
11
|
+
const mod = await import('./t0-transport/quality');
|
|
12
|
+
expect(mod.startQualityMonitoring).toBeDefined();
|
|
13
|
+
expect(mod.subscribeQuality).toBeDefined();
|
|
14
|
+
expect(mod.getCurrentMetrics).toBeDefined();
|
|
15
|
+
});
|
|
16
|
+
it('n1-flow-canvas utils are pure and import cleanly', async () => {
|
|
17
|
+
const mod = await import('./n1-flow-canvas/utils');
|
|
18
|
+
expect(mod.nodeHitTest).toBeDefined();
|
|
19
|
+
expect(mod.domEventToCanvasCoords).toBeDefined();
|
|
20
|
+
expect(mod.parseMentionEdges).toBeDefined();
|
|
21
|
+
expect(mod.parseGroupedSequenceEdges).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
it('n4 classifier is pure and import cleanly', async () => {
|
|
24
|
+
const mod = await import('./n4-adaptive-manifold/classifier');
|
|
25
|
+
expect(mod.classifyTopology).toBeDefined();
|
|
26
|
+
expect(mod.computeMetrics).toBeDefined();
|
|
27
|
+
});
|
|
28
|
+
it('n4 transition is pure and import cleanly', async () => {
|
|
29
|
+
const mod = await import('./n4-adaptive-manifold/transition');
|
|
30
|
+
expect(mod.EASING_FUNCTIONS).toBeDefined();
|
|
31
|
+
expect(mod.TransitionAnimator).toBeDefined();
|
|
32
|
+
});
|
|
33
|
+
it('n4 graph-state is pure and import cleanly', async () => {
|
|
34
|
+
const mod = await import('./n1-flow-canvas/graph-state.svelte');
|
|
35
|
+
expect(mod.GraphState).toBeDefined();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { isTauri } from './invoke';
|
|
2
|
+
/** Thrown when no Tauri runtime (or no fs plugin) is available. */
|
|
3
|
+
export declare class FsUnavailableError extends Error {
|
|
4
|
+
constructor(operation: string, cause?: unknown);
|
|
5
|
+
}
|
|
6
|
+
/** Read a text file. Rejects with FsUnavailableError outside a Tauri host. */
|
|
7
|
+
export declare function readTextFile(path: string): Promise<string>;
|
|
8
|
+
/** Write a text file. Rejects with FsUnavailableError outside a Tauri host — never a silent no-op. */
|
|
9
|
+
export declare function writeTextFile(path: string, contents: string): Promise<void>;
|
|
10
|
+
/** Last-modified time in epoch ms, or null when the backend can't provide one. */
|
|
11
|
+
export declare function getMtimeMs(path: string): Promise<number | null>;
|
|
12
|
+
//# sourceMappingURL=fs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../../src/t0-transport/fs.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAEnC,mEAAmE;AACnE,qBAAa,kBAAmB,SAAQ,KAAK;gBAChC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAQ9C;AAsBD,8EAA8E;AAC9E,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGhE;AAED,sGAAsG;AACtG,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED,kFAAkF;AAClF,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIrE"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// T0 Transport — file persistence over the optional Tauri FS plugin.
|
|
2
|
+
//
|
|
3
|
+
// Follows the same optional-peer pattern as invoke.ts: a literal dynamic
|
|
4
|
+
// import of the Tauri module, guarded at runtime by isTauri(). In a non-Tauri
|
|
5
|
+
// environment every operation rejects with FsUnavailableError — callers must
|
|
6
|
+
// surface that state instead of pretending the operation succeeded.
|
|
7
|
+
//
|
|
8
|
+
// NOTE: deliberately NOT re-exported from the t0-transport barrel. The barrel
|
|
9
|
+
// is reachable from the root package export; keeping fs.ts subpath-only means
|
|
10
|
+
// consumers who never import the editor never make their bundler resolve
|
|
11
|
+
// '@tauri-apps/plugin-fs' (an optional peer). Import it directly:
|
|
12
|
+
// import { readTextFile, writeTextFile } from '<pkg>/t0-transport/fs' (internal: '../t0-transport/fs')
|
|
13
|
+
import { isTauri } from './invoke';
|
|
14
|
+
export { isTauri } from './invoke';
|
|
15
|
+
/** Thrown when no Tauri runtime (or no fs plugin) is available. */
|
|
16
|
+
export class FsUnavailableError extends Error {
|
|
17
|
+
constructor(operation, cause) {
|
|
18
|
+
super(`File ${operation} unavailable: no Tauri runtime detected. ` +
|
|
19
|
+
'Persistence requires a Tauri host with @tauri-apps/plugin-fs installed.');
|
|
20
|
+
this.name = 'FsUnavailableError';
|
|
21
|
+
if (cause !== undefined)
|
|
22
|
+
this.cause = cause;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function loadFs(operation) {
|
|
26
|
+
if (!isTauri())
|
|
27
|
+
throw new FsUnavailableError(operation);
|
|
28
|
+
try {
|
|
29
|
+
// @tauri-apps/plugin-fs is an optional peer. Using an indirect specifier
|
|
30
|
+
// so TypeScript and bundlers treat this as a fully dynamic import — no
|
|
31
|
+
// static module resolution, no build-time error on missing package.
|
|
32
|
+
const spec = '@tauri-apps/plugin-fs';
|
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
+
return await import(/* @vite-ignore */ spec);
|
|
35
|
+
}
|
|
36
|
+
catch (cause) {
|
|
37
|
+
throw new FsUnavailableError(operation, cause);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** Read a text file. Rejects with FsUnavailableError outside a Tauri host. */
|
|
41
|
+
export async function readTextFile(path) {
|
|
42
|
+
const fs = await loadFs('read');
|
|
43
|
+
return fs.readTextFile(path);
|
|
44
|
+
}
|
|
45
|
+
/** Write a text file. Rejects with FsUnavailableError outside a Tauri host — never a silent no-op. */
|
|
46
|
+
export async function writeTextFile(path, contents) {
|
|
47
|
+
const fs = await loadFs('write');
|
|
48
|
+
await fs.writeTextFile(path, contents);
|
|
49
|
+
}
|
|
50
|
+
/** Last-modified time in epoch ms, or null when the backend can't provide one. */
|
|
51
|
+
export async function getMtimeMs(path) {
|
|
52
|
+
const fs = await loadFs('stat');
|
|
53
|
+
const info = await fs.stat(path);
|
|
54
|
+
return info?.mtime ? new Date(info.mtime).getTime() : null;
|
|
55
|
+
}
|
|
@@ -2,5 +2,6 @@ export { invoke, isTauri, isTauriReady, awaitTauriReady } from './invoke';
|
|
|
2
2
|
export { createEventBus, type EventBus } from './events';
|
|
3
3
|
export { TransportError, TransportErrorCode } from './error';
|
|
4
4
|
export { createConnectionTracker, type ConnectionState } from './connection';
|
|
5
|
+
export { createSubstrateConnection, type CreateSubstrateConnectionOptions, type SubstrateConnection, type SubstrateState, } from './substrate.svelte';
|
|
5
6
|
export { startQualityMonitoring, stopQualityMonitoring, recordPingStart, recordPingEnd, subscribeQuality, getCurrentMetrics, createQualityMonitor, getQualityColor, getQualityLabel, type QualityMetrics, type QualitySample, type QualityLevel, type QualityMonitor, } from './quality';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/t0-transport/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/t0-transport/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EACL,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,mBAAmB,EACxB,KAAK,cAAc,GACpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC"}
|
|
@@ -3,5 +3,6 @@ export { invoke, isTauri, isTauriReady, awaitTauriReady } from './invoke';
|
|
|
3
3
|
export { createEventBus } from './events';
|
|
4
4
|
export { TransportError, TransportErrorCode } from './error';
|
|
5
5
|
export { createConnectionTracker } from './connection';
|
|
6
|
+
export { createSubstrateConnection, } from './substrate.svelte';
|
|
6
7
|
// New from NNJAS port - Connection quality monitoring
|
|
7
8
|
export { startQualityMonitoring, stopQualityMonitoring, recordPingStart, recordPingEnd, subscribeQuality, getCurrentMetrics, createQualityMonitor, getQualityColor, getQualityLabel, } from './quality';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/t0-transport/invoke.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/t0-transport/invoke.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ,QAAQ,CAAC,EAAE,CAAC,CAAC;CACd;AAYD;;GAEG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzF,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,GACV,OAAO,CAAC,CAAC,CAAC,CAOZ;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;GAGG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAGtC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAUxD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Type-safe invoke wrapper for Tauri commands
|
|
2
2
|
async function getTauriInvoke() {
|
|
3
|
-
const
|
|
3
|
+
const spec = '@tauri-apps/api/core';
|
|
4
|
+
const mod = await import(/* @vite-ignore */ spec);
|
|
4
5
|
return mod.invoke;
|
|
5
6
|
}
|
|
6
7
|
/**
|
|
@@ -26,7 +27,9 @@ export function isTauri() {
|
|
|
26
27
|
* Use for conditional rendering. Use awaitTauriReady() for init paths.
|
|
27
28
|
*/
|
|
28
29
|
export function isTauriReady() {
|
|
29
|
-
|
|
30
|
+
if (typeof window === 'undefined')
|
|
31
|
+
return false;
|
|
32
|
+
return window.__TAURI_INTERNALS__ != null;
|
|
30
33
|
}
|
|
31
34
|
/**
|
|
32
35
|
* Polls until window.__TAURI_INTERNALS__ is available (up to 5 seconds).
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Connection Quality Monitoring
|
|
2
|
+
* Connection Quality Monitoring (F-29 — module-scope singleton).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Holds module-scope mutable state (metrics, pingId, interval, subscribers).
|
|
5
|
+
* startQualityMonitoring() uses setInterval; consume via subscribeQuality()
|
|
6
|
+
* for reactive updates in components.
|
|
7
|
+
*
|
|
8
|
+
* @module t0-transport/quality
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { startQualityMonitoring, subscribeQuality } from '@kos/design-system/t0-transport';
|
|
12
|
+
* startQualityMonitoring();
|
|
13
|
+
* const unsub = subscribeQuality(m => console.log(m.quality));
|
|
14
|
+
* ```
|
|
6
15
|
*/
|
|
7
16
|
export type QualityLevel = 'excellent' | 'good' | 'fair' | 'poor' | 'disconnected';
|
|
8
17
|
export interface QualitySample {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/t0-transport/quality.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/t0-transport/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,YAAY,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,cAAc,CAAC;AAEnF,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,UAAU,IAAI,cAAc,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACpE;AA2DD,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAQ7D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAQ7D;AAED,wBAAgB,sBAAsB,IAAI,IAAI,CAsB7C;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAM5C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAGtC;AAEH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAmBlE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CASxF;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAElD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAoHrD"}
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Connection Quality Monitoring
|
|
2
|
+
* Connection Quality Monitoring (F-29 — module-scope singleton).
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Holds module-scope mutable state (metrics, pingId, interval, subscribers).
|
|
5
|
+
* startQualityMonitoring() uses setInterval; consume via subscribeQuality()
|
|
6
|
+
* for reactive updates in components.
|
|
7
|
+
*
|
|
8
|
+
* @module t0-transport/quality
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { startQualityMonitoring, subscribeQuality } from '@kos/design-system/t0-transport';
|
|
12
|
+
* startQualityMonitoring();
|
|
13
|
+
* const unsub = subscribeQuality(m => console.log(m.quality));
|
|
14
|
+
* ```
|
|
6
15
|
*/
|
|
7
16
|
const SAMPLE_WINDOW = 60; // 60 seconds of history
|
|
8
17
|
const PING_INTERVAL = 5000; // Ping every 5 seconds
|
|
9
|
-
const MAX_HISTORY = 12; //
|
|
18
|
+
const MAX_HISTORY = Math.max(12, Math.ceil(SAMPLE_WINDOW * 1000 / PING_INTERVAL)); // 60s window → 12 samples at 5s interval
|
|
10
19
|
let metrics = {
|
|
11
20
|
latency: null,
|
|
12
21
|
jitter: null,
|
|
@@ -88,6 +97,10 @@ export function startQualityMonitoring() {
|
|
|
88
97
|
lost: true
|
|
89
98
|
});
|
|
90
99
|
pingStartTime = null;
|
|
100
|
+
// Trim to bounded size — interval runs every 1s so history can grow fast
|
|
101
|
+
if (metrics.history.length > MAX_HISTORY) {
|
|
102
|
+
metrics.history = metrics.history.slice(-MAX_HISTORY);
|
|
103
|
+
}
|
|
91
104
|
updateMetrics();
|
|
92
105
|
}
|
|
93
106
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export type SubstrateState = {
|
|
2
|
+
status: 'starting';
|
|
3
|
+
} | {
|
|
4
|
+
status: 'connected';
|
|
5
|
+
seqno: number;
|
|
6
|
+
} | {
|
|
7
|
+
status: 'reconnecting';
|
|
8
|
+
attempt: number;
|
|
9
|
+
} | {
|
|
10
|
+
status: 'failed';
|
|
11
|
+
reason: string;
|
|
12
|
+
};
|
|
13
|
+
export interface SubstrateConnection {
|
|
14
|
+
state: SubstrateState;
|
|
15
|
+
init(): Promise<void>;
|
|
16
|
+
retry(): Promise<void>;
|
|
17
|
+
destroy(): void;
|
|
18
|
+
isDegraded: boolean;
|
|
19
|
+
retryLabel: string;
|
|
20
|
+
}
|
|
21
|
+
export interface CreateSubstrateConnectionOptions {
|
|
22
|
+
getStateCommand?: string;
|
|
23
|
+
stateEvent?: string;
|
|
24
|
+
retryCommand?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function createSubstrateConnection(options?: CreateSubstrateConnectionOptions): SubstrateConnection;
|
|
27
|
+
//# sourceMappingURL=substrate.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substrate.svelte.d.ts","sourceRoot":"","sources":["../../src/t0-transport/substrate.svelte.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,cAAc,GACtB;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GACtB;IAAE,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,MAAM,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,IAAI,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gCAAgC;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAkDD,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gCAAqC,GAC7C,mBAAmB,CAErB"}
|