@graphrefly/graphrefly 0.24.0 → 0.26.0
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/README.md +8 -0
- package/dist/{chunk-QOWVNWOC.js → chunk-3ZWCKRHX.js} +27 -25
- package/dist/{chunk-QOWVNWOC.js.map → chunk-3ZWCKRHX.js.map} +1 -1
- package/dist/chunk-6LDQFTYS.js +102 -0
- package/dist/chunk-6LDQFTYS.js.map +1 -0
- package/dist/{chunk-5WGT55R4.js → chunk-AMCG74RZ.js} +195 -24
- package/dist/chunk-AMCG74RZ.js.map +1 -0
- package/dist/{chunk-AOCBDH4T.js → chunk-BVZYTZ5H.js} +76 -103
- package/dist/chunk-BVZYTZ5H.js.map +1 -0
- package/dist/chunk-FQMKGR6L.js +330 -0
- package/dist/chunk-FQMKGR6L.js.map +1 -0
- package/dist/chunk-HXZEYDUR.js +94 -0
- package/dist/chunk-HXZEYDUR.js.map +1 -0
- package/dist/{chunk-IPLKX3L2.js → chunk-IZYUSJC7.js} +16 -14
- package/dist/{chunk-IPLKX3L2.js.map → chunk-IZYUSJC7.js.map} +1 -1
- package/dist/chunk-J22W6HV3.js +107 -0
- package/dist/chunk-J22W6HV3.js.map +1 -0
- package/dist/{chunk-HWPIFSW2.js → chunk-JSCT3CR4.js} +6 -4
- package/dist/{chunk-HWPIFSW2.js.map → chunk-JSCT3CR4.js.map} +1 -1
- package/dist/chunk-JYXEWPH4.js +62 -0
- package/dist/chunk-JYXEWPH4.js.map +1 -0
- package/dist/chunk-LCE3GF5P.js +866 -0
- package/dist/chunk-LCE3GF5P.js.map +1 -0
- package/dist/chunk-MJ2NKQQL.js +119 -0
- package/dist/chunk-MJ2NKQQL.js.map +1 -0
- package/dist/chunk-N6UR7YVY.js +198 -0
- package/dist/chunk-N6UR7YVY.js.map +1 -0
- package/dist/chunk-OHISZPOJ.js +97 -0
- package/dist/chunk-OHISZPOJ.js.map +1 -0
- package/dist/{chunk-5DJTTKX3.js → chunk-PHOUUNK7.js} +74 -111
- package/dist/chunk-PHOUUNK7.js.map +1 -0
- package/dist/{chunk-PY4XCDLR.js → chunk-RB6QPHJ7.js} +8 -6
- package/dist/{chunk-PY4XCDLR.js.map → chunk-RB6QPHJ7.js.map} +1 -1
- package/dist/chunk-SN4YWWYO.js +171 -0
- package/dist/chunk-SN4YWWYO.js.map +1 -0
- package/dist/chunk-SX52TAR4.js +110 -0
- package/dist/chunk-SX52TAR4.js.map +1 -0
- package/dist/{chunk-XOFWRC73.js → chunk-THTWHNU4.js} +319 -24
- package/dist/chunk-THTWHNU4.js.map +1 -0
- package/dist/{chunk-H4RVA4VE.js → chunk-VYPWMZ6H.js} +2 -2
- package/dist/chunk-XGPU467M.js +136 -0
- package/dist/chunk-XGPU467M.js.map +1 -0
- package/dist/{chunk-TDEXAMGO.js → chunk-ZQMEI34O.js} +206 -574
- package/dist/chunk-ZQMEI34O.js.map +1 -0
- package/dist/compat/index.cjs +7656 -0
- package/dist/compat/index.cjs.map +1 -0
- package/dist/compat/index.d.cts +18 -0
- package/dist/compat/index.d.ts +18 -0
- package/dist/compat/index.js +49 -0
- package/dist/compat/index.js.map +1 -0
- package/dist/compat/jotai/index.cjs +2048 -0
- package/dist/compat/jotai/index.cjs.map +1 -0
- package/dist/compat/jotai/index.d.cts +2 -0
- package/dist/compat/jotai/index.d.ts +2 -0
- package/dist/compat/jotai/index.js +9 -0
- package/dist/compat/jotai/index.js.map +1 -0
- package/dist/compat/nanostores/index.cjs +2175 -0
- package/dist/compat/nanostores/index.cjs.map +1 -0
- package/dist/compat/nanostores/index.d.cts +2 -0
- package/dist/compat/nanostores/index.d.ts +2 -0
- package/dist/compat/nanostores/index.js +23 -0
- package/dist/compat/nanostores/index.js.map +1 -0
- package/dist/compat/nestjs/index.cjs +350 -16
- package/dist/compat/nestjs/index.cjs.map +1 -1
- package/dist/compat/nestjs/index.d.cts +6 -6
- package/dist/compat/nestjs/index.d.ts +6 -6
- package/dist/compat/nestjs/index.js +10 -9
- package/dist/compat/react/index.cjs +141 -0
- package/dist/compat/react/index.cjs.map +1 -0
- package/dist/compat/react/index.d.cts +2 -0
- package/dist/compat/react/index.d.ts +2 -0
- package/dist/compat/react/index.js +12 -0
- package/dist/compat/react/index.js.map +1 -0
- package/dist/compat/solid/index.cjs +128 -0
- package/dist/compat/solid/index.cjs.map +1 -0
- package/dist/compat/solid/index.d.cts +2 -0
- package/dist/compat/solid/index.d.ts +2 -0
- package/dist/compat/solid/index.js +12 -0
- package/dist/compat/solid/index.js.map +1 -0
- package/dist/compat/svelte/index.cjs +131 -0
- package/dist/compat/svelte/index.cjs.map +1 -0
- package/dist/compat/svelte/index.d.cts +2 -0
- package/dist/compat/svelte/index.d.ts +2 -0
- package/dist/compat/svelte/index.js +12 -0
- package/dist/compat/svelte/index.js.map +1 -0
- package/dist/compat/vue/index.cjs +146 -0
- package/dist/compat/vue/index.cjs.map +1 -0
- package/dist/compat/vue/index.d.cts +3 -0
- package/dist/compat/vue/index.d.ts +3 -0
- package/dist/compat/vue/index.js +12 -0
- package/dist/compat/vue/index.js.map +1 -0
- package/dist/compat/zustand/index.cjs +4931 -0
- package/dist/compat/zustand/index.cjs.map +1 -0
- package/dist/compat/zustand/index.d.cts +5 -0
- package/dist/compat/zustand/index.d.ts +5 -0
- package/dist/compat/zustand/index.js +12 -0
- package/dist/compat/zustand/index.js.map +1 -0
- package/dist/core/index.cjs +53 -4
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +3 -3
- package/dist/core/index.d.ts +3 -3
- package/dist/core/index.js +26 -24
- package/dist/demo-shell-26p5fVxn.d.cts +102 -0
- package/dist/demo-shell-DEp-nMTl.d.ts +102 -0
- package/dist/extra/index.cjs +290 -110
- package/dist/extra/index.cjs.map +1 -1
- package/dist/extra/index.d.cts +5 -4
- package/dist/extra/index.d.ts +5 -4
- package/dist/extra/index.js +8 -5
- package/dist/extra/sources.cjs +2486 -0
- package/dist/extra/sources.cjs.map +1 -0
- package/dist/extra/sources.d.cts +465 -0
- package/dist/extra/sources.d.ts +465 -0
- package/dist/extra/sources.js +57 -0
- package/dist/extra/sources.js.map +1 -0
- package/dist/graph/index.cjs +408 -14
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +5 -5
- package/dist/graph/index.d.ts +5 -5
- package/dist/graph/index.js +13 -5
- package/dist/{graph-D-3JIQme.d.cts → graph-6tZ5jEzr.d.cts} +195 -4
- package/dist/{graph-B6NFqv3z.d.ts → graph-DQ69XU0g.d.ts} +195 -4
- package/dist/index-B4MP_8V_.d.cts +37 -0
- package/dist/index-BEfE8H_G.d.cts +121 -0
- package/dist/{index-D7XgsUt7.d.ts → index-BW1z3BN9.d.ts} +169 -127
- package/dist/index-BYOHF0zP.d.ts +34 -0
- package/dist/index-B_IP40nB.d.cts +36 -0
- package/dist/index-Bd_fwmLf.d.cts +45 -0
- package/dist/{index-BysCTzJz.d.ts → index-BeIdBfcb.d.cts} +121 -547
- package/dist/index-BjI6ty9z.d.ts +121 -0
- package/dist/index-Bxb5ZYc9.d.cts +34 -0
- package/dist/{index-BJB7t9gg.d.cts → index-C0ZXMaXO.d.cts} +2 -2
- package/dist/{index-b5BYtczN.d.cts → index-C8mdwMXc.d.cts} +169 -127
- package/dist/index-CDAjUFIv.d.ts +36 -0
- package/dist/index-CPgZ5wRl.d.ts +44 -0
- package/dist/{index-AMWewNDe.d.cts → index-CUwyr1Kk.d.cts} +33 -4
- package/dist/index-CUyrtuOf.d.cts +127 -0
- package/dist/{index-C-TXEa7C.d.ts → index-CY2TljO4.d.ts} +2 -2
- package/dist/index-CmnuOibw.d.ts +37 -0
- package/dist/{index-DiobMNwE.d.ts → index-CuYwdKO-.d.ts} +3 -3
- package/dist/index-DFhjO4Gg.d.cts +44 -0
- package/dist/{index-1z8vRTCt.d.cts → index-DdD5MVDL.d.ts} +121 -547
- package/dist/index-DrISNAOm.d.ts +45 -0
- package/dist/index-QBpffFW-.d.cts +86 -0
- package/dist/{index-J7Kc0oIQ.d.cts → index-_oMEWlDq.d.cts} +3 -3
- package/dist/{index-CYkjxu3s.d.ts → index-eJ6T_qGM.d.ts} +33 -4
- package/dist/index-qldRdbQw.d.ts +86 -0
- package/dist/index-xdGjv0nO.d.ts +127 -0
- package/dist/index.cjs +2334 -195
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1007 -648
- package/dist/index.d.ts +1007 -648
- package/dist/index.js +1204 -1172
- package/dist/index.js.map +1 -1
- package/dist/{meta-CnkLA_43.d.ts → meta-BGqSZ7mt.d.ts} +1 -1
- package/dist/{meta-DWbkoq1s.d.cts → meta-C0-8XW6Q.d.cts} +1 -1
- package/dist/{node-B-f-Lu-k.d.cts → node-C_IBuvX2.d.cts} +26 -1
- package/dist/{node-B-f-Lu-k.d.ts → node-C_IBuvX2.d.ts} +26 -1
- package/dist/{observable-DBnrwcar.d.cts → observable-Crr1jgzx.d.cts} +1 -1
- package/dist/{observable-uP-wy_uK.d.ts → observable-DCk45RH5.d.ts} +1 -1
- package/dist/patterns/demo-shell.cjs +5604 -0
- package/dist/patterns/demo-shell.cjs.map +1 -0
- package/dist/patterns/demo-shell.d.cts +6 -0
- package/dist/patterns/demo-shell.d.ts +6 -0
- package/dist/patterns/demo-shell.js +15 -0
- package/dist/patterns/demo-shell.js.map +1 -0
- package/dist/patterns/reactive-layout/index.cjs +843 -29
- package/dist/patterns/reactive-layout/index.cjs.map +1 -1
- package/dist/patterns/reactive-layout/index.d.cts +6 -5
- package/dist/patterns/reactive-layout/index.d.ts +6 -5
- package/dist/patterns/reactive-layout/index.js +25 -10
- package/dist/reactive-layout-BaOQefHu.d.cts +183 -0
- package/dist/reactive-layout-D9gejYXE.d.ts +183 -0
- package/dist/{storage-BuTdpCI1.d.cts → storage-BMycWEh2.d.ts} +9 -1
- package/dist/{storage-F2X1U1x0.d.ts → storage-DiqWHzVI.d.cts} +9 -1
- package/package.json +32 -2
- package/dist/chunk-5DJTTKX3.js.map +0 -1
- package/dist/chunk-5WGT55R4.js.map +0 -1
- package/dist/chunk-AOCBDH4T.js.map +0 -1
- package/dist/chunk-MW4VAKAO.js +0 -47
- package/dist/chunk-MW4VAKAO.js.map +0 -1
- package/dist/chunk-TDEXAMGO.js.map +0 -1
- package/dist/chunk-XOFWRC73.js.map +0 -1
- /package/dist/{chunk-H4RVA4VE.js.map → chunk-VYPWMZ6H.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/patterns/demo-shell.ts"],"sourcesContent":["/**\n * Three-pane demo shell (roadmap §7.2).\n *\n * A `Graph(\"demo-shell\")` that dogfoods reactive coordination for the\n * main/side split layout with synchronized cross-highlighting.\n *\n * **Zero framework dependency** — framework bindings wrap pane components only.\n * The shell graph is headless and fully testable.\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { describeNode, resolveDescribeFields } from \"../core/meta.js\";\nimport { derived, effect, state } from \"../core/sugar.js\";\nimport { Graph } from \"../graph/graph.js\";\nimport type { MeasurementAdapter } from \"./reactive-layout/reactive-layout.js\";\nimport { analyzeAndMeasure, computeLineBreaks } from \"./reactive-layout/reactive-layout.js\";\n\n// ——————————————————————————————————————————————————————————\n// Types\n// ——————————————————————————————————————————————————————————\n\n/** Identifies which pane is the source of a hover event. */\nexport type HoverPaneType = \"visual\" | \"graph\" | \"code\";\n\n/** Cross-highlighting hover target. `null` means nothing hovered. */\nexport type HoverTarget = { pane: HoverPaneType; id: string } | null;\n\n/** Which pane is full-screened (null = normal layout). */\nexport type FullscreenPane = \"main\" | \"graph\" | \"code\" | null;\n\n/**\n * Cross-referencing registry: maps node paths to code line numbers and\n * visual element selectors. Provided by each demo's `store.ts`.\n */\nexport type NodeRegistry = Map<string, { codeLine: number; visualSelector: string }>;\n\n/** Callbacks for cross-highlighting effect nodes. */\nexport type HighlightCallbacks = {\n\t/** Called when code-scroll highlight target changes. */\n\tcodeScroll?: (line: number | null) => void;\n\t/** Called when visual highlight target changes. */\n\tvisual?: (selector: string | null) => void;\n\t/** Called when graph highlight target changes. */\n\tgraph?: (nodeId: string | null) => void;\n};\n\n/** Label dimensions for graph node sizing. */\nexport type GraphLabelSize = { width: number; height: number };\n\n/** Options for {@link demoShell}. */\nexport type DemoShellOptions = {\n\t/** Initial main/side split ratio (0–1). Default: `0.65`. */\n\tmainRatio?: number;\n\t/** Initial graph/code vertical split in the side pane (0–1). Default: `0.5`. */\n\tsideSplit?: number;\n\t/** Initial viewport width in pixels. Default: `1280`. */\n\tviewportWidth?: number;\n\t/** Cross-referencing registry for hover→code/visual/graph mapping. */\n\tnodeRegistry?: NodeRegistry;\n\t/** Measurement adapter for layout engine integration. When provided, enables layout/* derived nodes. */\n\tadapter?: MeasurementAdapter;\n\t/** Font string for layout measurement. Default: `\"14px monospace\"`. */\n\tlayoutFont?: string;\n\t/** Callbacks for cross-highlighting effect nodes. When provided, creates effect nodes visible in describe(). */\n\tonHighlight?: HighlightCallbacks;\n};\n\n/** Return type of {@link demoShell}. */\nexport type DemoShellHandle = {\n\t/** The demo-shell graph. */\n\tgraph: Graph;\n\n\t// ── Convenience setters (shorthand for graph.set) ──────────\n\tsetMainRatio(ratio: number): void;\n\tsetSideSplit(ratio: number): void;\n\tsetFullscreen(pane: FullscreenPane): void;\n\tsetViewportWidth(width: number): void;\n\tsetHoverTarget(target: HoverTarget): void;\n\tsetDemoGraph(g: Graph | null): void;\n\tbumpGraphTick(): void;\n\tselectNode(path: string | null): void;\n\tsetMetaDebug(on: boolean): void;\n\t/** Set code text for layout/code-lines measurement (requires adapter). */\n\tsetCodeText(text: string): void;\n\t/** Atomic multi-set — wraps core `batch()` for glitch-free updates. */\n\tbatch(fn: () => void): void;\n\tdestroy(): void;\n};\n\n// ——————————————————————————————————————————————————————————\n// Helpers\n// ——————————————————————————————————————————————————————————\n\nfunction clamp01(v: number): number {\n\treturn Math.max(0, Math.min(1, v));\n}\n\n// ——————————————————————————————————————————————————————————\n// Factory\n// ——————————————————————————————————————————————————————————\n\n/**\n * Creates the three-pane demo shell graph (roadmap §7.2).\n *\n * All coordination is reactive — no polling, no imperative triggers.\n * Framework bindings subscribe to named nodes and drive `state` inputs.\n */\nexport function demoShell(opts?: DemoShellOptions): DemoShellHandle {\n\tconst mainRatioInit = clamp01(opts?.mainRatio ?? 0.65);\n\tconst sideSplitInit = clamp01(opts?.sideSplit ?? 0.5);\n\tconst viewportInit = Math.max(0, opts?.viewportWidth ?? 1280);\n\tconst registry = opts?.nodeRegistry ?? new Map();\n\tconst adapter = opts?.adapter ?? null;\n\tconst layoutFont = opts?.layoutFont ?? \"14px monospace\";\n\tconst onHighlight = opts?.onHighlight;\n\n\tconst g = new Graph(\"demo-shell\");\n\n\t// ── Layout state ─────────────────────────────────────\n\tconst paneMainRatio = state(mainRatioInit, { name: \"pane/main-ratio\" });\n\tconst paneSideSplit = state(sideSplitInit, { name: \"pane/side-split\" });\n\tconst paneFullscreen = state<FullscreenPane>(null, {\n\t\tname: \"pane/fullscreen\",\n\t});\n\tconst viewportWidth = state(viewportInit, { name: \"viewport/width\" });\n\n\tg.add(\"pane/main-ratio\", paneMainRatio);\n\tg.add(\"pane/side-split\", paneSideSplit);\n\tg.add(\"pane/fullscreen\", paneFullscreen);\n\tg.add(\"viewport/width\", viewportWidth);\n\n\t// ── Derived pane dimensions ──────────────────────────\n\tconst paneMainWidth = derived(\n\t\t[paneMainRatio, viewportWidth, paneFullscreen],\n\t\t([ratio, vw, fs]) => {\n\t\t\tconst r = ratio as number;\n\t\t\tconst w = vw as number;\n\t\t\tconst fullscreen = fs as FullscreenPane;\n\t\t\tif (fullscreen === \"main\") return w;\n\t\t\tif (fullscreen === \"graph\" || fullscreen === \"code\") return 0;\n\t\t\treturn Math.round(w * r);\n\t\t},\n\t\t{ name: \"pane/main-width\" },\n\t);\n\n\tconst paneSideWidth = derived(\n\t\t[paneMainWidth, viewportWidth, paneFullscreen],\n\t\t([main, vw, fs]) => {\n\t\t\tconst fullscreen = fs as FullscreenPane;\n\t\t\tconst w = vw as number;\n\t\t\tif (fullscreen === \"main\") return 0;\n\t\t\tif (fullscreen === \"graph\" || fullscreen === \"code\") return w;\n\t\t\treturn (w as number) - (main as number);\n\t\t},\n\t\t{ name: \"pane/side-width\" },\n\t);\n\n\tconst paneGraphHeight = derived(\n\t\t[paneSideSplit, paneFullscreen],\n\t\t([split, fs]) => {\n\t\t\tconst fullscreen = fs as FullscreenPane;\n\t\t\tif (fullscreen === \"graph\") return 1;\n\t\t\tif (fullscreen === \"code\") return 0;\n\t\t\tif (fullscreen === \"main\") return 0;\n\t\t\treturn clamp01(split as number);\n\t\t},\n\t\t{ name: \"pane/graph-height-ratio\" },\n\t);\n\n\tconst paneCodeHeight = derived(\n\t\t[paneGraphHeight, paneFullscreen],\n\t\t([graphH, fs]) => {\n\t\t\tconst fullscreen = fs as FullscreenPane;\n\t\t\tif (fullscreen === \"code\") return 1;\n\t\t\tif (fullscreen === \"graph\" || fullscreen === \"main\") return 0;\n\t\t\treturn 1 - (graphH as number);\n\t\t},\n\t\t{ name: \"pane/code-height-ratio\" },\n\t);\n\n\tg.add(\"pane/main-width\", paneMainWidth);\n\tg.add(\"pane/side-width\", paneSideWidth);\n\tg.add(\"pane/graph-height-ratio\", paneGraphHeight);\n\tg.add(\"pane/code-height-ratio\", paneCodeHeight);\n\n\t// ── External graph observation ───────────────────────\n\tconst demoGraphRef = state<Graph | null>(null, {\n\t\tname: \"demo/graph-ref\",\n\t});\n\tconst demoGraphTick = state(0, { name: \"demo/graph-tick\" });\n\n\tg.add(\"demo/graph-ref\", demoGraphRef);\n\tg.add(\"demo/graph-tick\", demoGraphTick);\n\n\tconst graphMermaid = derived(\n\t\t[demoGraphRef, demoGraphTick],\n\t\t([ref, _tick]) => {\n\t\t\tconst demo = ref as Graph | null;\n\t\t\tif (!demo) return \"\";\n\t\t\treturn demo.describe({ format: \"mermaid\" });\n\t\t},\n\t\t{ name: \"graph/mermaid\" },\n\t);\n\n\tconst graphDescribe = derived(\n\t\t[demoGraphRef, demoGraphTick],\n\t\t([ref, _tick]) => {\n\t\t\tconst demo = ref as Graph | null;\n\t\t\tif (!demo) return null;\n\t\t\tconst { expand: _, ...snapshot } = demo.describe({ detail: \"standard\" });\n\t\t\treturn snapshot;\n\t\t},\n\t\t{ name: \"graph/describe\" },\n\t);\n\n\tg.add(\"graph/mermaid\", graphMermaid);\n\tg.add(\"graph/describe\", graphDescribe);\n\n\t// ── Cross-highlighting ───────────────────────────────\n\tconst hoverTarget = state<HoverTarget>(null, { name: \"hover/target\" });\n\tg.add(\"hover/target\", hoverTarget);\n\n\tconst highlightCodeScroll = derived(\n\t\t[hoverTarget],\n\t\t([target]) => {\n\t\t\tconst t = target as HoverTarget;\n\t\t\tif (!t) return null;\n\t\t\tconst entry = registry.get(t.id);\n\t\t\treturn entry ? entry.codeLine : null;\n\t\t},\n\t\t{ name: \"highlight/code-scroll\" },\n\t);\n\n\tconst highlightVisual = derived(\n\t\t[hoverTarget],\n\t\t([target]) => {\n\t\t\tconst t = target as HoverTarget;\n\t\t\tif (!t) return null;\n\t\t\tconst entry = registry.get(t.id);\n\t\t\treturn entry ? entry.visualSelector : null;\n\t\t},\n\t\t{ name: \"highlight/visual\" },\n\t);\n\n\tconst highlightGraph = derived(\n\t\t[hoverTarget],\n\t\t([target]) => {\n\t\t\tconst t = target as HoverTarget;\n\t\t\tif (!t) return null;\n\t\t\treturn t.id;\n\t\t},\n\t\t{ name: \"highlight/graph\" },\n\t);\n\n\tg.add(\"highlight/code-scroll\", highlightCodeScroll);\n\tg.add(\"highlight/visual\", highlightVisual);\n\tg.add(\"highlight/graph\", highlightGraph);\n\n\t// ── Cross-highlighting effect nodes (optional) ─────\n\t// Created when onHighlight callbacks are provided, making the full\n\t// source→derived→effect chain visible in describe()/toMermaid().\n\n\tif (onHighlight?.codeScroll) {\n\t\tconst cb = onHighlight.codeScroll;\n\t\tconst applyCodeScroll = effect([highlightCodeScroll], ([line]) => {\n\t\t\tcb(line as number | null);\n\t\t});\n\t\tg.add(\"highlight/apply-code-scroll\", applyCodeScroll);\n\t}\n\n\tif (onHighlight?.visual) {\n\t\tconst cb = onHighlight.visual;\n\t\tconst applyVisual = effect([highlightVisual], ([selector]) => {\n\t\t\tcb(selector as string | null);\n\t\t});\n\t\tg.add(\"highlight/apply-visual\", applyVisual);\n\t}\n\n\tif (onHighlight?.graph) {\n\t\tconst cb = onHighlight.graph;\n\t\tconst applyGraph = effect([highlightGraph], ([nodeId]) => {\n\t\t\tcb(nodeId as string | null);\n\t\t});\n\t\tg.add(\"highlight/apply-graph\", applyGraph);\n\t}\n\n\t// ── Inspect panel ────────────────────────────────────\n\tconst inspectSelected = state<string | null>(null, {\n\t\tname: \"inspect/selected-node\",\n\t});\n\tg.add(\"inspect/selected-node\", inspectSelected);\n\n\tconst standardFields = resolveDescribeFields(\"standard\");\n\n\tconst inspectNodeDetail = derived(\n\t\t[inspectSelected, demoGraphRef, demoGraphTick],\n\t\t([path, ref, _tick]) => {\n\t\t\tconst demo = ref as Graph | null;\n\t\t\tconst p = path as string | null;\n\t\t\tif (!demo || !p) return null;\n\t\t\ttry {\n\t\t\t\tconst nd = demo.resolve(p);\n\t\t\t\tconst nodeDesc = describeNode(nd, standardFields);\n\t\t\t\treturn { path: p, ...nodeDesc, value: nd.cache };\n\t\t\t} catch {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t},\n\t\t{ name: \"inspect/node-detail\" },\n\t);\n\n\tconst inspectTraceLog = derived(\n\t\t[demoGraphRef, demoGraphTick],\n\t\t([ref, _tick]) => {\n\t\t\tconst demo = ref as Graph | null;\n\t\t\tif (!demo) return [];\n\t\t\treturn demo.trace();\n\t\t},\n\t\t{ name: \"inspect/trace-log\" },\n\t);\n\n\tg.add(\"inspect/node-detail\", inspectNodeDetail);\n\tg.add(\"inspect/trace-log\", inspectTraceLog);\n\n\t// ── Meta debug toggle ────────────────────────────────\n\tconst metaDebug = state(false, { name: \"meta/debug\" });\n\tg.add(\"meta/debug\", metaDebug);\n\n\tconst metaShellMermaid = derived(\n\t\t[metaDebug, demoGraphTick],\n\t\t([debug, _tick]) => {\n\t\t\tif (!(debug as boolean)) return \"\";\n\t\t\treturn g.describe({ format: \"mermaid\" });\n\t\t},\n\t\t{ name: \"meta/shell-mermaid\" },\n\t);\n\tg.add(\"meta/shell-mermaid\", metaShellMermaid);\n\n\t// ── Layout engine integration (optional, requires adapter) ──\n\tconst codeTextNode = state(\"\", { name: \"layout/code-text\" });\n\tg.add(\"layout/code-text\", codeTextNode);\n\n\tif (adapter) {\n\t\tconst measureCache = new Map<string, Map<string, number>>();\n\n\t\tconst graphLabels = derived(\n\t\t\t[graphDescribe],\n\t\t\t([desc]) => {\n\t\t\t\tconst d = desc as { nodes: Record<string, { type: string }> } | null;\n\t\t\t\tif (!d) return new Map<string, GraphLabelSize>();\n\t\t\t\tconst result = new Map<string, GraphLabelSize>();\n\t\t\t\tfor (const [name] of Object.entries(d.nodes)) {\n\t\t\t\t\tconst segments = analyzeAndMeasure(name, layoutFont, adapter, measureCache);\n\t\t\t\t\tconst lb = computeLineBreaks(segments, Infinity, adapter, layoutFont, measureCache);\n\t\t\t\t\tconst width = lb.lines.reduce((max, l) => Math.max(max, l.width), 0);\n\t\t\t\t\tconst height = lb.lineCount * 20; // line-height approximation\n\t\t\t\t\tresult.set(name, { width, height });\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: \"layout/graph-labels\",\n\t\t\t\tequals: (a, b) => {\n\t\t\t\t\tif (a === b) return true;\n\t\t\t\t\tconst ma = a as Map<string, GraphLabelSize>;\n\t\t\t\t\tconst mb = b as Map<string, GraphLabelSize>;\n\t\t\t\t\tif (ma.size !== mb.size) return false;\n\t\t\t\t\tfor (const [k, v] of ma) {\n\t\t\t\t\t\tconst bv = mb.get(k);\n\t\t\t\t\t\tif (!bv || bv.width !== v.width || bv.height !== v.height) return false;\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tconst codeLines = derived(\n\t\t\t[codeTextNode, paneSideWidth],\n\t\t\t([text, sideW]) => {\n\t\t\t\tconst t = text as string;\n\t\t\t\tif (!t) return { lineCount: 0, lines: [] };\n\t\t\t\tconst segments = analyzeAndMeasure(t, layoutFont, adapter, measureCache);\n\t\t\t\tconst maxW = (sideW as number) - 40; // side pane minus padding\n\t\t\t\treturn computeLineBreaks(segments, Math.max(100, maxW), adapter, layoutFont, measureCache);\n\t\t\t},\n\t\t\t{ name: \"layout/code-lines\" },\n\t\t);\n\n\t\tconst sideWidthHint = derived(\n\t\t\t[graphLabels],\n\t\t\t([labels]) => {\n\t\t\t\tconst m = labels as Map<string, GraphLabelSize>;\n\t\t\t\tif (m.size === 0) return 200; // minimum default\n\t\t\t\tlet maxW = 0;\n\t\t\t\tfor (const { width } of m.values()) {\n\t\t\t\t\tif (width > maxW) maxW = width;\n\t\t\t\t}\n\t\t\t\t// widest label + padding (node box chrome + margin)\n\t\t\t\treturn Math.max(200, Math.round(maxW + 80));\n\t\t\t},\n\t\t\t{ name: \"layout/side-width-hint\" },\n\t\t);\n\n\t\tg.add(\"layout/graph-labels\", graphLabels);\n\t\tg.add(\"layout/code-lines\", codeLines);\n\t\tg.add(\"layout/side-width-hint\", sideWidthHint);\n\t}\n\n\t// ── Edges (explicit wiring for describe/toMermaid) ───\n\n\t// ── Handle ───────────────────────────────────────────\n\tlet tickCounter = 0;\n\treturn {\n\t\tgraph: g,\n\t\tsetMainRatio(ratio: number) {\n\t\t\tg.set(\"pane/main-ratio\", clamp01(ratio));\n\t\t},\n\t\tsetSideSplit(ratio: number) {\n\t\t\tg.set(\"pane/side-split\", clamp01(ratio));\n\t\t},\n\t\tsetFullscreen(pane: FullscreenPane) {\n\t\t\tg.set(\"pane/fullscreen\", pane);\n\t\t},\n\t\tsetViewportWidth(width: number) {\n\t\t\tg.set(\"viewport/width\", Math.max(0, width));\n\t\t},\n\t\tsetHoverTarget(target: HoverTarget) {\n\t\t\tg.set(\"hover/target\", target);\n\t\t},\n\t\tsetDemoGraph(demo: Graph | null) {\n\t\t\tg.set(\"demo/graph-ref\", demo);\n\t\t},\n\t\tbumpGraphTick() {\n\t\t\tg.set(\"demo/graph-tick\", ++tickCounter);\n\t\t},\n\t\tselectNode(path: string | null) {\n\t\t\tg.set(\"inspect/selected-node\", path);\n\t\t},\n\t\tsetMetaDebug(on: boolean) {\n\t\t\tg.set(\"meta/debug\", on);\n\t\t},\n\t\tsetCodeText(text: string) {\n\t\t\tg.set(\"layout/code-text\", text);\n\t\t},\n\t\tbatch(fn: () => void) {\n\t\t\tbatch(fn);\n\t\t},\n\t\tdestroy() {\n\t\t\tg.destroy();\n\t\t},\n\t};\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DATA,
|
|
3
|
+
DIRTY,
|
|
4
|
+
RESOLVED,
|
|
5
|
+
__export
|
|
6
|
+
} from "./chunk-SX52TAR4.js";
|
|
7
|
+
|
|
8
|
+
// src/compat/solid/index.ts
|
|
9
|
+
var solid_exports = {};
|
|
10
|
+
__export(solid_exports, {
|
|
11
|
+
useStore: () => useStore,
|
|
12
|
+
useSubscribe: () => useSubscribe,
|
|
13
|
+
useSubscribeRecord: () => useSubscribeRecord
|
|
14
|
+
});
|
|
15
|
+
import { createSignal, getOwner, onCleanup } from "solid-js";
|
|
16
|
+
function useSubscribe(node) {
|
|
17
|
+
const [value, setValue] = createSignal(node.cache, { equals: false });
|
|
18
|
+
const unsub = node.subscribe(() => {
|
|
19
|
+
setValue(() => node.cache);
|
|
20
|
+
});
|
|
21
|
+
if (getOwner()) {
|
|
22
|
+
onCleanup(() => unsub());
|
|
23
|
+
} else if (typeof console !== "undefined") {
|
|
24
|
+
console.warn(
|
|
25
|
+
"[graphrefly-ts] useSubscribe called outside a Solid reactive owner \u2014 subscription will not be auto-disposed."
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function useStore(node) {
|
|
31
|
+
const value = useSubscribe(node);
|
|
32
|
+
const setter = (v) => {
|
|
33
|
+
node.down([[DIRTY], [DATA, v]]);
|
|
34
|
+
};
|
|
35
|
+
return [value, setter];
|
|
36
|
+
}
|
|
37
|
+
function useSubscribeRecord(keysNode, factory) {
|
|
38
|
+
const [value, setValue] = createSignal({}, { equals: false });
|
|
39
|
+
let entrySubs = [];
|
|
40
|
+
const cleanupEntries = () => {
|
|
41
|
+
for (const unsub of entrySubs) unsub();
|
|
42
|
+
entrySubs = [];
|
|
43
|
+
};
|
|
44
|
+
const buildSnapshot = () => {
|
|
45
|
+
const snap = {};
|
|
46
|
+
for (const key of keysNode.cache ?? []) {
|
|
47
|
+
const nodes = factory(key);
|
|
48
|
+
const values = {};
|
|
49
|
+
for (const field of Object.keys(nodes)) {
|
|
50
|
+
values[field] = nodes[field].cache;
|
|
51
|
+
}
|
|
52
|
+
snap[key] = values;
|
|
53
|
+
}
|
|
54
|
+
return snap;
|
|
55
|
+
};
|
|
56
|
+
const sync = (nextKeys) => {
|
|
57
|
+
cleanupEntries();
|
|
58
|
+
for (const key of nextKeys) {
|
|
59
|
+
const nodes = factory(key);
|
|
60
|
+
for (const field of Object.keys(nodes)) {
|
|
61
|
+
const unsub = nodes[field].subscribe(() => {
|
|
62
|
+
setValue(() => buildSnapshot());
|
|
63
|
+
});
|
|
64
|
+
entrySubs.push(unsub);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
setValue(() => buildSnapshot());
|
|
68
|
+
};
|
|
69
|
+
const keysUnsub = keysNode.subscribe((msgs) => {
|
|
70
|
+
if (msgs.some((m) => m[0] === DATA || m[0] === RESOLVED)) {
|
|
71
|
+
sync(keysNode.cache ?? []);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
sync(keysNode.cache ?? []);
|
|
75
|
+
if (getOwner()) {
|
|
76
|
+
onCleanup(() => {
|
|
77
|
+
keysUnsub();
|
|
78
|
+
cleanupEntries();
|
|
79
|
+
});
|
|
80
|
+
} else if (typeof console !== "undefined") {
|
|
81
|
+
console.warn(
|
|
82
|
+
"[graphrefly-ts] useSubscribeRecord called outside a Solid reactive owner \u2014 subscription will not be auto-disposed."
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
useSubscribe,
|
|
90
|
+
useStore,
|
|
91
|
+
useSubscribeRecord,
|
|
92
|
+
solid_exports
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=chunk-HXZEYDUR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compat/solid/index.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Solid bindings — useSubscribe / useStore\n// ---------------------------------------------------------------------------\n// Bridges GraphReFly nodes into Solid reactivity via createSignal.\n// Works with any Node<T>, including companion nodes (node.meta.status).\n//\n// Usage:\n// import { useSubscribe, useStore } from '@graphrefly/graphrefly-ts/compat/solid';\n// // Optional peer install (only for this adapter): pnpm add solid-js\n// const status = useSubscribe(wsStatusNode); // Accessor<string | undefined>\n// const [count, setCount] = useStore(countNode); // [Accessor<number | undefined>, Setter]\n// ---------------------------------------------------------------------------\n\nimport { createSignal, getOwner, onCleanup } from \"solid-js\";\nimport { DATA, DIRTY, type Messages, RESOLVED } from \"../../core/messages.js\";\nimport type { Node } from \"../../core/node.js\";\n\n/** Solid accessor function — returns current value when called. */\nexport type Accessor<T> = () => T;\n\n/**\n * Subscribe to a `Node<T>` as a Solid signal. Auto-cleans up with the owning scope.\n * Subscription lifecycle is tied to Solid scope cleanup (not node terminal messages).\n */\nexport function useSubscribe<T>(node: Node<T>): Accessor<T | undefined | null> {\n\tconst [value, setValue] = createSignal(node.cache, { equals: false });\n\n\tconst unsub = node.subscribe(() => {\n\t\tsetValue(() => node.cache);\n\t});\n\n\tif (getOwner()) {\n\t\tonCleanup(() => unsub());\n\t} else if (typeof console !== \"undefined\") {\n\t\tconsole.warn(\n\t\t\t\"[graphrefly-ts] useSubscribe called outside a Solid reactive owner — subscription will not be auto-disposed.\",\n\t\t);\n\t}\n\n\treturn value;\n}\n\n/**\n * Bind a writable `Node<T>` as a Solid resource tuple `[accessor, setter]`.\n * Setter always forwards `[[DIRTY], [DATA, value]]`, including `value === undefined`.\n * Subscription lifecycle is tied to Solid scope cleanup (not node terminal messages).\n */\nexport function useStore<T>(node: Node<T>): [Accessor<T | undefined | null>, (v: T) => void] {\n\tconst value = useSubscribe(node);\n\tconst setter = (v: T) => {\n\t\tnode.down([[DIRTY], [DATA, v]]);\n\t};\n\treturn [value, setter];\n}\n\n/** Maps a key to an object of nodes. Used by `useSubscribeRecord`. */\nexport type NodeFactory<K, R extends Record<string, any>> = (key: K) => {\n\t[P in keyof R]: Node<R[P]>;\n};\n\n/**\n * Subscribe to a dynamic set of keyed node records as a Solid accessor.\n * Re-subscribes all per-key fields whenever `keys` changes.\n * Key re-sync is gated to settled batches (`messageTier >= 3`) to avoid DIRTY-phase churn.\n */\nexport function useSubscribeRecord<K extends string, R extends Record<string, any>>(\n\tkeysNode: Node<K[]>,\n\tfactory: NodeFactory<K, R>,\n): Accessor<Record<K, R>> {\n\tconst [value, setValue] = createSignal({} as Record<K, R>, { equals: false });\n\tlet entrySubs: Array<() => void> = [];\n\n\tconst cleanupEntries = () => {\n\t\tfor (const unsub of entrySubs) unsub();\n\t\tentrySubs = [];\n\t};\n\n\tconst buildSnapshot = (): Record<K, R> => {\n\t\tconst snap = {} as Record<K, R>;\n\t\tfor (const key of keysNode.cache ?? []) {\n\t\t\tconst nodes = factory(key);\n\t\t\tconst values = {} as R;\n\t\t\tfor (const field of Object.keys(nodes) as (keyof R)[]) {\n\t\t\t\tvalues[field] = nodes[field].cache as R[keyof R];\n\t\t\t}\n\t\t\tsnap[key] = values;\n\t\t}\n\t\treturn snap;\n\t};\n\n\tconst sync = (nextKeys: K[]) => {\n\t\tcleanupEntries();\n\t\tfor (const key of nextKeys) {\n\t\t\tconst nodes = factory(key);\n\t\t\tfor (const field of Object.keys(nodes) as (keyof R)[]) {\n\t\t\t\tconst unsub = nodes[field].subscribe(() => {\n\t\t\t\t\tsetValue(() => buildSnapshot());\n\t\t\t\t});\n\t\t\t\tentrySubs.push(unsub);\n\t\t\t}\n\t\t}\n\t\tsetValue(() => buildSnapshot());\n\t};\n\n\tconst keysUnsub = keysNode.subscribe((msgs: Messages) => {\n\t\tif (msgs.some((m) => m[0] === DATA || m[0] === RESOLVED)) {\n\t\t\tsync(keysNode.cache ?? []);\n\t\t}\n\t});\n\tsync(keysNode.cache ?? []);\n\n\tif (getOwner()) {\n\t\tonCleanup(() => {\n\t\t\tkeysUnsub();\n\t\t\tcleanupEntries();\n\t\t});\n\t} else if (typeof console !== \"undefined\") {\n\t\tconsole.warn(\n\t\t\t\"[graphrefly-ts] useSubscribeRecord called outside a Solid reactive owner — subscription will not be auto-disposed.\",\n\t\t);\n\t}\n\n\treturn value;\n}\n"],"mappings":";;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,SAAS,cAAc,UAAU,iBAAiB;AAW3C,SAAS,aAAgB,MAA+C;AAC9E,QAAM,CAAC,OAAO,QAAQ,IAAI,aAAa,KAAK,OAAO,EAAE,QAAQ,MAAM,CAAC;AAEpE,QAAM,QAAQ,KAAK,UAAU,MAAM;AAClC,aAAS,MAAM,KAAK,KAAK;AAAA,EAC1B,CAAC;AAED,MAAI,SAAS,GAAG;AACf,cAAU,MAAM,MAAM,CAAC;AAAA,EACxB,WAAW,OAAO,YAAY,aAAa;AAC1C,YAAQ;AAAA,MACP;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AAOO,SAAS,SAAY,MAAiE;AAC5F,QAAM,QAAQ,aAAa,IAAI;AAC/B,QAAM,SAAS,CAAC,MAAS;AACxB,SAAK,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;AAAA,EAC/B;AACA,SAAO,CAAC,OAAO,MAAM;AACtB;AAYO,SAAS,mBACf,UACA,SACyB;AACzB,QAAM,CAAC,OAAO,QAAQ,IAAI,aAAa,CAAC,GAAmB,EAAE,QAAQ,MAAM,CAAC;AAC5E,MAAI,YAA+B,CAAC;AAEpC,QAAM,iBAAiB,MAAM;AAC5B,eAAW,SAAS,UAAW,OAAM;AACrC,gBAAY,CAAC;AAAA,EACd;AAEA,QAAM,gBAAgB,MAAoB;AACzC,UAAM,OAAO,CAAC;AACd,eAAW,OAAO,SAAS,SAAS,CAAC,GAAG;AACvC,YAAM,QAAQ,QAAQ,GAAG;AACzB,YAAM,SAAS,CAAC;AAChB,iBAAW,SAAS,OAAO,KAAK,KAAK,GAAkB;AACtD,eAAO,KAAK,IAAI,MAAM,KAAK,EAAE;AAAA,MAC9B;AACA,WAAK,GAAG,IAAI;AAAA,IACb;AACA,WAAO;AAAA,EACR;AAEA,QAAM,OAAO,CAAC,aAAkB;AAC/B,mBAAe;AACf,eAAW,OAAO,UAAU;AAC3B,YAAM,QAAQ,QAAQ,GAAG;AACzB,iBAAW,SAAS,OAAO,KAAK,KAAK,GAAkB;AACtD,cAAM,QAAQ,MAAM,KAAK,EAAE,UAAU,MAAM;AAC1C,mBAAS,MAAM,cAAc,CAAC;AAAA,QAC/B,CAAC;AACD,kBAAU,KAAK,KAAK;AAAA,MACrB;AAAA,IACD;AACA,aAAS,MAAM,cAAc,CAAC;AAAA,EAC/B;AAEA,QAAM,YAAY,SAAS,UAAU,CAAC,SAAmB;AACxD,QAAI,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,QAAQ,EAAE,CAAC,MAAM,QAAQ,GAAG;AACzD,WAAK,SAAS,SAAS,CAAC,CAAC;AAAA,IAC1B;AAAA,EACD,CAAC;AACD,OAAK,SAAS,SAAS,CAAC,CAAC;AAEzB,MAAI,SAAS,GAAG;AACf,cAAU,MAAM;AACf,gBAAU;AACV,qBAAe;AAAA,IAChB,CAAC;AAAA,EACF,WAAW,OAAO,YAAY,aAAa;AAC1C,YAAQ;AAAA,MACP;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;","names":[]}
|
|
@@ -2,28 +2,20 @@ import {
|
|
|
2
2
|
createWatermarkController,
|
|
3
3
|
reactiveLog,
|
|
4
4
|
toObservable
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-RB6QPHJ7.js";
|
|
6
6
|
import {
|
|
7
7
|
domainMeta
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JSCT3CR4.js";
|
|
9
9
|
import {
|
|
10
10
|
fromCron,
|
|
11
11
|
fromTimer,
|
|
12
12
|
keepalive
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BVZYTZ5H.js";
|
|
14
14
|
import {
|
|
15
15
|
Graph
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-THTWHNU4.js";
|
|
17
17
|
import {
|
|
18
|
-
COMPLETE,
|
|
19
|
-
DATA,
|
|
20
18
|
DEFAULT_ACTOR,
|
|
21
|
-
ERROR,
|
|
22
|
-
TEARDOWN,
|
|
23
|
-
__decorateElement,
|
|
24
|
-
__decoratorStart,
|
|
25
|
-
__export,
|
|
26
|
-
__runInitializers,
|
|
27
19
|
batch,
|
|
28
20
|
derived,
|
|
29
21
|
node,
|
|
@@ -31,7 +23,17 @@ import {
|
|
|
31
23
|
policy,
|
|
32
24
|
state,
|
|
33
25
|
wallClockNs
|
|
34
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-PHOUUNK7.js";
|
|
27
|
+
import {
|
|
28
|
+
COMPLETE,
|
|
29
|
+
DATA,
|
|
30
|
+
ERROR,
|
|
31
|
+
TEARDOWN,
|
|
32
|
+
__decorateElement,
|
|
33
|
+
__decoratorStart,
|
|
34
|
+
__export,
|
|
35
|
+
__runInitializers
|
|
36
|
+
} from "./chunk-SX52TAR4.js";
|
|
35
37
|
|
|
36
38
|
// src/compat/nestjs/index.ts
|
|
37
39
|
var nestjs_exports = {};
|
|
@@ -1364,4 +1366,4 @@ export {
|
|
|
1364
1366
|
GraphReflyModule,
|
|
1365
1367
|
nestjs_exports
|
|
1366
1368
|
};
|
|
1367
|
-
//# sourceMappingURL=chunk-
|
|
1369
|
+
//# sourceMappingURL=chunk-IZYUSJC7.js.map
|