trellis 3.1.35 → 3.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/CHANGELOG.md +23 -5
- package/README.md +63 -156
- package/bin/trellis.mjs +2 -75
- package/dist/{better-sqlite-backend-ahx5p0br.js → better-sqlite-backend-2P4F6AOJ.js} +91 -29
- package/dist/boot-middleware-MHLHFCUC.js +9 -0
- package/dist/browser/index.d.ts +18 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +95 -0
- package/dist/{index-53f3b8p8.js → chunk-2W3MHTMG.js} +552 -213
- package/dist/chunk-44FFQKQX.js +142 -0
- package/dist/chunk-4HYPLFJD.js +150 -0
- package/dist/chunk-4XIVMVHC.js +361 -0
- package/dist/{index-yp88he8n.js → chunk-6CTA6MCE.js} +88 -64
- package/dist/chunk-6GEZ6DN5.js +394 -0
- package/dist/chunk-7ZFRVCUE.js +211 -0
- package/dist/chunk-CAG4FULI.js +121 -0
- package/dist/chunk-FF36CQHZ.js +61 -0
- package/dist/{index-h32txmxe.js → chunk-FKQO5A3H.js} +6 -13
- package/dist/{index-nq520y6k.js → chunk-FWRS4CSC.js} +46 -32
- package/dist/chunk-GFZCJ4EH.js +108 -0
- package/dist/chunk-GLM4HGN4.js +55 -0
- package/dist/{index-4cdr7x2x.js → chunk-GU374KWZ.js} +182 -111
- package/dist/chunk-H6JB3PZ3.js +45 -0
- package/dist/chunk-IZX2PLIB.js +1240 -0
- package/dist/chunk-J2TXUFCZ.js +289 -0
- package/dist/chunk-J3WYZO3Q.js +211 -0
- package/dist/{index-xzym9w0m.js → chunk-JA7AIHRK.js} +12 -7
- package/dist/chunk-JHHEXEDM.js +162 -0
- package/dist/chunk-JUEMDWLU.js +233 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/chunk-KIJITUZB.js +419 -0
- package/dist/{index-4wxa8xz4.js → chunk-KQ4A2D2P.js} +162 -23
- package/dist/chunk-KSU2GW22.js +958 -0
- package/dist/{index-rv1p47gp.js → chunk-L5N5PR2S.js} +3015 -2480
- package/dist/{index-h9e2efx4.js → chunk-LNUIGRDZ.js} +71 -55
- package/dist/{index-skhn0agf.js → chunk-MLC5BUYO.js} +19 -20
- package/dist/chunk-MPXUVGT3.js +104 -0
- package/dist/chunk-N6MYZT4O.js +68 -0
- package/dist/chunk-O2AV5WMN.js +48 -0
- package/dist/chunk-PZ4XYZ4J.js +143 -0
- package/dist/chunk-QB5ISE47.js +419 -0
- package/dist/chunk-RSWUFTO2.js +857 -0
- package/dist/chunk-S3XLFZ27.js +1095 -0
- package/dist/{index-w5wccer3.js → chunk-S6GBJ2ZB.js} +28 -12
- package/dist/{index-7pjz3tsy.js → chunk-SGMDTWJJ.js} +57 -15
- package/dist/chunk-SPSPV5BC.js +390 -0
- package/dist/chunk-TCKXSOBP.js +123 -0
- package/dist/chunk-UBGUDMUV.js +59 -0
- package/dist/{index-wt8rz4gn.js → chunk-UQISRW6T.js} +97 -26
- package/dist/chunk-USEINYUL.js +12 -0
- package/dist/{index-bmyt7k8n.js → chunk-UZRUP7QW.js} +12 -4
- package/dist/{index-xhcp6xrn.js → chunk-VBYUTRXX.js} +695 -514
- package/dist/{index-vkpkfwhq.js → chunk-VDAKEOML.js} +234 -194
- package/dist/chunk-WXSWA3MV.js +0 -0
- package/dist/{index-n9f2qyh5.js → chunk-X5FLTRUB.js} +55 -33
- package/dist/{index-h7zxhhhh.js → chunk-XMQ7G77X.js} +46 -38
- package/dist/{index-w7ng765c.js → chunk-YCM7ZYEZ.js} +102 -49
- package/dist/cli/deploy-cli.d.ts +18 -0
- package/dist/cli/deploy-cli.d.ts.map +1 -0
- package/dist/cli/errors.d.ts +6 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/examples.d.ts +23 -0
- package/dist/cli/examples.d.ts.map +1 -0
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2426 -6225
- package/dist/client/index.browser.d.ts +29 -0
- package/dist/client/index.browser.d.ts.map +1 -0
- package/dist/client/index.browser.js +64 -0
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +41 -21
- package/dist/client/live.d.ts +67 -0
- package/dist/client/live.d.ts.map +1 -0
- package/dist/client/reactive.d.ts +31 -0
- package/dist/client/reactive.d.ts.map +1 -0
- package/dist/client/sdk.browser.d.ts +104 -0
- package/dist/client/sdk.browser.d.ts.map +1 -0
- package/dist/client/sdk.browser.js +9 -0
- package/dist/client/sdk.d.ts +26 -2
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +9 -0
- package/dist/client/vcs-client.d.ts +129 -0
- package/dist/client/vcs-client.d.ts.map +1 -0
- package/dist/cms/index.js +171 -163
- package/dist/{config-8hczw0rs.js → config-PFTP67TR.js} +8 -9
- package/dist/core/computation/index.d.ts +5 -0
- package/dist/core/computation/index.d.ts.map +1 -0
- package/dist/core/computation/rollup.d.ts +18 -0
- package/dist/core/computation/rollup.d.ts.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +171 -104
- package/dist/core/kernel/boot-middleware.d.ts +10 -0
- package/dist/core/kernel/boot-middleware.d.ts.map +1 -0
- package/dist/core/kernel/logic-middleware.d.ts +7 -1
- package/dist/core/kernel/logic-middleware.d.ts.map +1 -1
- package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
- package/dist/core/ontology/types.d.ts +5 -0
- package/dist/core/ontology/types.d.ts.map +1 -1
- package/dist/core/persist/better-sqlite-backend.d.ts +9 -2
- package/dist/core/persist/better-sqlite-backend.d.ts.map +1 -1
- package/dist/core/persist/factory.d.ts +6 -7
- package/dist/core/persist/factory.d.ts.map +1 -1
- package/dist/core/persist/factory.js +2 -3
- package/dist/core/persist/sqljs-backend.js +2 -3
- package/dist/db/index.d.ts +4 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +67 -54
- package/dist/db/inspector.js +11 -19
- package/dist/db/trellis.css +1 -1
- package/dist/decisions/index.js +9 -10
- package/dist/deploy-LQ7GUGJ5.js +9 -0
- package/dist/deploy-YNVG5E4E.js +9 -0
- package/dist/deploy-cli-24BCHAXY.js +67 -0
- package/dist/deploy-cli-C35HTITO.js +67 -0
- package/dist/embeddings/auto-embed.d.ts +2 -2
- package/dist/embeddings/auto-embed.d.ts.map +1 -1
- package/dist/embeddings/index.js +20 -22
- package/dist/embeddings/search.d.ts +2 -1
- package/dist/embeddings/search.d.ts.map +1 -1
- package/dist/embeddings/store.d.ts +25 -4
- package/dist/embeddings/store.d.ts.map +1 -1
- package/dist/engine.d.ts +59 -19
- package/dist/engine.d.ts.map +1 -1
- package/dist/import-UZEKXU3B.js +10 -0
- package/dist/index.js +102 -93
- package/dist/launch-explorer-HZ4ZJA4X.js +95 -0
- package/dist/links/index.js +24 -26
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/plugins/agent-memory/index.js +316 -0
- package/dist/plugins/idea-garden/index.js +165 -0
- package/dist/plugins/plan-approval/index.js +579 -0
- package/dist/plugins/proactive-watcher/index.js +194 -0
- package/dist/{index-2r4jxwnb.js → query-XYLTJYSA.js} +14 -15
- package/dist/react/index.js +39 -70
- package/dist/react/realtime.js +11 -0
- package/dist/react/schema-hooks.js +87 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +43 -0
- package/dist/realtime/broadcast-channel-transport.d.ts.map +1 -0
- package/dist/realtime/durable-object-relay-transport.d.ts +96 -0
- package/dist/realtime/durable-object-relay-transport.d.ts.map +1 -0
- package/dist/realtime/index.d.ts +44 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +40 -0
- package/dist/realtime/memory-hub.d.ts +32 -0
- package/dist/realtime/memory-hub.d.ts.map +1 -0
- package/dist/realtime/persistent-channel.d.ts +105 -0
- package/dist/realtime/persistent-channel.d.ts.map +1 -0
- package/dist/realtime/presence.d.ts +73 -0
- package/dist/realtime/presence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.d.ts +37 -0
- package/dist/realtime/relay-persistence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.js +107 -0
- package/dist/realtime/relay-server.d.ts +103 -0
- package/dist/realtime/relay-server.d.ts.map +1 -0
- package/dist/realtime/room.d.ts +98 -0
- package/dist/realtime/room.d.ts.map +1 -0
- package/dist/realtime/text.d.ts +73 -0
- package/dist/realtime/text.d.ts.map +1 -0
- package/dist/realtime/types.d.ts +89 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/websocket-relay-transport.d.ts +28 -0
- package/dist/realtime/websocket-relay-transport.d.ts.map +1 -0
- package/dist/realtime.bundle.js +1100 -0
- package/dist/{remote-manager-xvbg4230.js → remote-manager-ODE3T2KR.js} +25 -15
- package/dist/scaffold/seed.d.ts.map +1 -1
- package/dist/scaffold/write.d.ts +1 -1
- package/dist/scaffold/write.d.ts.map +1 -1
- package/dist/schema/define.d.ts +137 -0
- package/dist/schema/define.d.ts.map +1 -0
- package/dist/schema/entity-projection.d.ts +34 -0
- package/dist/schema/entity-projection.d.ts.map +1 -0
- package/dist/schema/eql.d.ts +46 -0
- package/dist/schema/eql.d.ts.map +1 -0
- package/dist/schema/index.d.ts +21 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +46 -0
- package/dist/schema/kernel-resolve.d.ts +21 -0
- package/dist/schema/kernel-resolve.d.ts.map +1 -0
- package/dist/schema/mutations.d.ts +20 -0
- package/dist/schema/mutations.d.ts.map +1 -0
- package/dist/schema/resolve.d.ts +21 -0
- package/dist/schema/resolve.d.ts.map +1 -0
- package/dist/server/deploy-meta.d.ts +25 -0
- package/dist/server/deploy-meta.d.ts.map +1 -0
- package/dist/server/deploy.d.ts +7 -2
- package/dist/server/deploy.d.ts.map +1 -1
- package/dist/server/index.d.ts +7 -2
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +100 -58
- package/dist/server/node-adapter.js +5 -104
- package/dist/server/realtime.d.ts +14 -3
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/server.d.ts +8 -16
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/sprites.d.ts +18 -1
- package/dist/server/sprites.d.ts.map +1 -1
- package/dist/server/tenancy.d.ts +4 -0
- package/dist/server/tenancy.d.ts.map +1 -1
- package/dist/server/usage-meter.d.ts +53 -0
- package/dist/server/usage-meter.d.ts.map +1 -0
- package/dist/server-MB3OPSPI.js +18 -0
- package/dist/server-ZVWGLLRF.js +18 -0
- package/dist/sprites-KQGTGM6W.js +27 -0
- package/dist/{sprites-vc4qbrp1.js → sprites-RU3E4XQN.js} +6 -7
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +51 -0
- package/dist/svelte/schema-hooks.d.ts +45 -0
- package/dist/svelte/schema-hooks.d.ts.map +1 -0
- package/dist/svelte/schema-hooks.js +71 -0
- package/dist/svelte/stores.d.ts +78 -0
- package/dist/svelte/stores.d.ts.map +1 -0
- package/dist/sync/http-transport.d.ts +3 -3
- package/dist/sync/http-transport.d.ts.map +1 -1
- package/dist/sync/index.d.ts +15 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +617 -0
- package/dist/sync/memory-room.d.ts +37 -0
- package/dist/sync/memory-room.d.ts.map +1 -0
- package/dist/sync/memory-transport.d.ts +3 -3
- package/dist/sync/memory-transport.d.ts.map +1 -1
- package/dist/sync/partykit-room.d.ts +40 -0
- package/dist/sync/partykit-room.d.ts.map +1 -0
- package/dist/sync/partykit-transport.d.ts +84 -0
- package/dist/sync/partykit-transport.d.ts.map +1 -0
- package/dist/sync/room-core.d.ts +53 -0
- package/dist/sync/room-core.d.ts.map +1 -0
- package/dist/sync/sync-engine.d.ts +40 -2
- package/dist/sync/sync-engine.d.ts.map +1 -1
- package/dist/sync/sync-room-server.d.ts +39 -0
- package/dist/sync/sync-room-server.d.ts.map +1 -0
- package/dist/sync/types.d.ts +70 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/vcs-sync-peer.d.ts +63 -0
- package/dist/sync/vcs-sync-peer.d.ts.map +1 -0
- package/dist/sync/ws-transport.d.ts +2 -2
- package/dist/sync/ws-transport.d.ts.map +1 -1
- package/dist/tenancy-NBLLGCNJ.js +14 -0
- package/dist/tenancy-POMWQP6M.js +16 -0
- package/dist/ui/client.html +355 -67
- package/dist/ui/launch-explorer.d.ts +22 -0
- package/dist/ui/launch-explorer.d.ts.map +1 -0
- package/dist/ui/server.d.ts +1 -1
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/vcs/blob-store.d.ts.map +1 -1
- package/dist/vcs/idb-op-log.d.ts +67 -0
- package/dist/vcs/idb-op-log.d.ts.map +1 -0
- package/dist/vcs/index.d.ts +1 -0
- package/dist/vcs/index.d.ts.map +1 -1
- package/dist/vcs/index.js +81 -72
- package/dist/vcs/issue.d.ts +22 -5
- package/dist/vcs/issue.d.ts.map +1 -1
- package/dist/vcs/lane-materialize.d.ts +5 -0
- package/dist/vcs/lane-materialize.d.ts.map +1 -1
- package/dist/vcs/op-log.d.ts +28 -2
- package/dist/vcs/op-log.d.ts.map +1 -1
- package/dist/vcs/ops.d.ts +10 -0
- package/dist/vcs/ops.d.ts.map +1 -1
- package/dist/vcs/types.d.ts +2 -0
- package/dist/vcs/types.d.ts.map +1 -1
- package/dist/{vm-config-6xhsj6b3.js → vm-config-JI4OXKDQ.js} +9 -10
- package/dist/vue/hooks.d.ts +64 -0
- package/dist/vue/hooks.d.ts.map +1 -0
- package/dist/vue/index.d.ts +19 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +59 -0
- package/dist/vue/schema-hooks.d.ts +41 -0
- package/dist/vue/schema-hooks.d.ts.map +1 -0
- package/dist/vue/schema-hooks.js +64 -0
- package/package.json +130 -17
- package/dist/deploy-999q207z.js +0 -10
- package/dist/engine-y0724kjq.js +0 -8
- package/dist/import-s2b8e0ft.js +0 -11
- package/dist/index-a76rekgs.js +0 -67
- package/dist/index-c9h37r6h.js +0 -1
- package/dist/index-hr9qvv77.js +0 -860
- package/dist/index-k5b0xskw.js +0 -1
- package/dist/index-nzb3am4f.js +0 -80
- package/dist/index-wncptktd.js +0 -292
- package/dist/index-y6a4kj0p.js +0 -43
- package/dist/index-yhwjgfvj.js +0 -342
- package/dist/sdk-bepky0xs.js +0 -16
- package/dist/server-szdjx0nt.js +0 -13
- package/dist/sqlite-backend-0vsmc6qj.js +0 -8
- package/dist/tenancy-pjm32b4v.js +0 -14
package/dist/ui/client.html
CHANGED
|
@@ -80,14 +80,44 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
80
80
|
.cmd-item .ci-type{font:500 9px var(--mono);color:var(--text3);text-transform:uppercase;width:48px;flex-shrink:0}
|
|
81
81
|
.cmd-item .ci-label{font:400 13px var(--font);color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
82
82
|
|
|
83
|
-
/* ─── Graph Panel ─── */
|
|
84
|
-
#graph-panel
|
|
85
|
-
.graph-
|
|
86
|
-
.graph-
|
|
87
|
-
.graph-
|
|
88
|
-
.graph-
|
|
89
|
-
.
|
|
90
|
-
.
|
|
83
|
+
/* ─── Graph Panel (Studio GraphView parity) ─── */
|
|
84
|
+
#graph-panel.panel.active{display:flex;flex-direction:column;padding:0;overflow:hidden}
|
|
85
|
+
.graph-layout{display:flex;flex:1;min-height:0;overflow:hidden}
|
|
86
|
+
.graph-sidebar{width:200px;flex-shrink:0;border-right:1px solid var(--border);background:var(--surface);display:flex;flex-direction:column;overflow:hidden}
|
|
87
|
+
.graph-sidebar-head{padding:10px 12px;border-bottom:1px solid var(--border);font:600 10px var(--font);letter-spacing:.08em;text-transform:uppercase;color:var(--text3)}
|
|
88
|
+
.graph-sidebar-meta{padding:8px 12px;font:400 11px var(--mono);color:var(--text3);border-bottom:1px solid var(--border)}
|
|
89
|
+
.graph-filter-list{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:4px}
|
|
90
|
+
.graph-type-pill{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;border:1px solid transparent;border-radius:8px;background:transparent;color:var(--text2);font:500 11px var(--font);cursor:pointer;text-align:left;transition:background .12s,border-color .12s,opacity .12s}
|
|
91
|
+
.graph-type-pill:hover{background:var(--surface2)}
|
|
92
|
+
.graph-type-pill.active{background:var(--accent-glow);border-color:rgba(109,91,250,.35);color:var(--text)}
|
|
93
|
+
.graph-type-pill.dimmed{opacity:.35}
|
|
94
|
+
.graph-type-pill .dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
|
95
|
+
.graph-type-pill .name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
96
|
+
.graph-type-pill .count{font:500 10px var(--mono);color:var(--text3)}
|
|
97
|
+
.graph-canvas-wrap{position:relative;flex:1;min-width:0;min-height:0;background:var(--bg2)}
|
|
98
|
+
.graph-canvas-wrap svg{width:100%;height:100%;display:block;touch-action:none}
|
|
99
|
+
.graph-tooltip{position:absolute;pointer-events:none;z-index:20;display:none;padding:8px 10px;border-radius:8px;font:400 11px/1.4 var(--font);background:color-mix(in srgb,var(--surface) 88%,transparent);backdrop-filter:blur(8px);border:1px solid var(--border2);color:var(--text);box-shadow:0 6px 20px rgba(0,0,0,.4);max-width:min(360px,90vw);opacity:0;transform:translateY(2px);transition:opacity 80ms ease-out,transform 80ms ease-out}
|
|
100
|
+
.graph-tooltip.visible{display:block;opacity:1;transform:translateY(0)}
|
|
101
|
+
.graph-tooltip .gt-type{font:600 9px var(--mono);text-transform:uppercase;letter-spacing:.06em;color:var(--text3);margin-bottom:2px}
|
|
102
|
+
.graph-tooltip .gt-label{font-weight:500}
|
|
103
|
+
.graph-minimap{position:absolute;left:12px;bottom:12px;z-index:15;border:1px solid var(--border);border-radius:6px;background:color-mix(in srgb,var(--surface) 90%,transparent);box-shadow:0 2px 10px rgba(0,0,0,.35);cursor:pointer;transition:opacity .18s}
|
|
104
|
+
.graph-chrome{position:absolute;left:12px;bottom:144px;z-index:16;width:180px;border:1px solid var(--border);border-radius:8px;background:color-mix(in srgb,var(--surface) 90%,transparent);backdrop-filter:blur(10px);box-shadow:0 4px 16px rgba(0,0,0,.35);overflow:hidden;transition:opacity .18s}
|
|
105
|
+
.graph-chrome.dimmed,.graph-minimap.dimmed{opacity:.12;pointer-events:none}
|
|
106
|
+
.graph-chrome-head{display:flex;align-items:center;justify-content:space-between;padding:6px 8px;border-bottom:1px solid var(--border);font:600 10px var(--font);letter-spacing:.06em;text-transform:uppercase;color:var(--text3)}
|
|
107
|
+
.graph-chrome-head button{background:none;border:none;color:var(--text3);font:500 10px var(--font);cursor:pointer;padding:2px 6px;border-radius:4px}
|
|
108
|
+
.graph-chrome-head button:hover{color:var(--text);background:var(--surface2)}
|
|
109
|
+
.graph-chrome-body{padding:6px 8px 8px;display:flex;flex-direction:column;gap:6px}
|
|
110
|
+
.graph-chrome-body button{width:100%;padding:6px 8px;border-radius:6px;border:1px solid var(--border);background:var(--bg);color:var(--text2);font:500 11px var(--font);cursor:pointer}
|
|
111
|
+
.graph-chrome-body button:hover{border-color:var(--accent);color:var(--accent2)}
|
|
112
|
+
.graph-beacon{position:absolute;z-index:25;display:none;align-items:center;justify-content:center;width:40px;height:40px;padding:0;border-radius:999px;border:1px solid var(--border2);background:color-mix(in srgb,var(--surface) 92%,transparent);color:var(--text);box-shadow:0 4px 16px rgba(0,0,0,.4);cursor:pointer;transform:translate(-50%,-50%);transition:opacity .12s}
|
|
113
|
+
.graph-beacon.visible{display:flex}
|
|
114
|
+
.graph-controls{position:absolute;bottom:12px;right:12px;z-index:14;display:flex;flex-direction:column;gap:4px}
|
|
115
|
+
.graph-controls button{width:32px;height:32px;background:color-mix(in srgb,var(--surface) 92%,transparent);backdrop-filter:blur(8px);border:1px solid var(--border);border-radius:6px;color:var(--text2);font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center}
|
|
116
|
+
.graph-controls button:hover{background:var(--surface2);color:var(--text);border-color:var(--border2)}
|
|
117
|
+
.graph-links line{stroke-linecap:round}
|
|
118
|
+
.graph-edge-labels text{font-family:var(--font);pointer-events:none}
|
|
119
|
+
@keyframes edgeFlow{to{stroke-dashoffset:-16}}
|
|
120
|
+
.graph-links line.edge-flow{animation:edgeFlow .5s linear infinite}
|
|
91
121
|
|
|
92
122
|
/* ─── Timeline Panel ─── */
|
|
93
123
|
#timeline-panel{padding:0}
|
|
@@ -194,8 +224,13 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
194
224
|
// ─── State ───
|
|
195
225
|
const S = { panel: 'graph', graph: null, timeline: null, store: null, system: null, cmdOpen: false, drawerOpen: false };
|
|
196
226
|
const $ = id => document.getElementById(id);
|
|
197
|
-
|
|
198
|
-
const
|
|
227
|
+
// Aligned with turtlecode/ide entity-theme (GraphView)
|
|
228
|
+
const ENTITY_COLORS = { file:'#14b8a6', milestone:'#3b82f6', issue:'#e879f9', branch:'#fde047', default:'#94a3b8' };
|
|
229
|
+
const GRAPH_LABEL_MIN_ZOOM = 0.65;
|
|
230
|
+
const GRAPH_MINIMAP_W = 180, GRAPH_MINIMAP_H = 120, GRAPH_MINIMAP_PAD = 6;
|
|
231
|
+
const EDGE_LABELS = { milestone_file:'includes', issue_branch:'branch', wikilink:'wikilink', causal:'causal' };
|
|
232
|
+
function nodeRadius(d){ if(d.type==='issue')return 12; if(d.type==='milestone')return 11; if(d.type==='branch')return 8; if(d.type==='file')return 7; return 6; }
|
|
233
|
+
function nodeColor(d){ return ENTITY_COLORS[d.type]||ENTITY_COLORS.default; }
|
|
199
234
|
|
|
200
235
|
// ─── Panel Switching ───
|
|
201
236
|
const tabs = document.querySelectorAll('.tab');
|
|
@@ -260,7 +295,7 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
260
295
|
try{
|
|
261
296
|
const res = await fetch('/api/node/'+encodeURIComponent(nodeId));
|
|
262
297
|
const d = await res.json();
|
|
263
|
-
let h = `<div class="d-section"><span class="d-badge" style="background:${
|
|
298
|
+
let h = `<div class="d-section"><span class="d-badge" style="background:${ENTITY_COLORS[d.type]||ENTITY_COLORS.default}22;color:${ENTITY_COLORS[d.type]||ENTITY_COLORS.default}">${d.type}</span></div>`;
|
|
264
299
|
if(d.type==='file'){
|
|
265
300
|
h += `<div class="d-section"><h4>Path</h4><div class="d-meta"><strong>${esc(d.path)}</strong></div></div>`;
|
|
266
301
|
if(d.contentHash) h += `<div class="d-section"><h4>Hash</h4><div style="font:11px var(--mono);color:var(--text3);word-break:break-all">${d.contentHash}</div></div>`;
|
|
@@ -298,9 +333,120 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
298
333
|
}
|
|
299
334
|
|
|
300
335
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
301
|
-
// GRAPH PANEL
|
|
336
|
+
// GRAPH PANEL (Studio GraphView-style)
|
|
302
337
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
303
|
-
let graphSim, graphZoom, graphSvg, graphG,
|
|
338
|
+
let graphSim, graphZoom, graphSvg, graphG, graphNodeGroups, graphLinks, graphLabels, graphEdgeLabels, graphNodeMap;
|
|
339
|
+
let graphCanvasWrap, graphZoomState = { k: 1, x: 0, y: 0 }, graphActiveFilters = null, graphMinimap, graphMinimapCtx, graphBeacon;
|
|
340
|
+
|
|
341
|
+
function buildGraphSidebar(nodes){
|
|
342
|
+
const counts = {};
|
|
343
|
+
nodes.forEach(n => { counts[n.type] = (counts[n.type]||0)+1; });
|
|
344
|
+
const types = Object.keys(counts).sort();
|
|
345
|
+
graphActiveFilters = new Set(types);
|
|
346
|
+
const sidebar = document.createElement('aside');
|
|
347
|
+
sidebar.className = 'graph-sidebar';
|
|
348
|
+
sidebar.innerHTML = `<div class="graph-sidebar-head">Entity types</div><div class="graph-sidebar-meta" id="graph-sidebar-meta"></div><div class="graph-filter-list" id="graph-filter-list"></div>`;
|
|
349
|
+
const list = sidebar.querySelector('#graph-filter-list');
|
|
350
|
+
const meta = sidebar.querySelector('#graph-sidebar-meta');
|
|
351
|
+
function refreshMeta(visible){
|
|
352
|
+
meta.textContent = visible + ' / ' + nodes.length + ' nodes';
|
|
353
|
+
}
|
|
354
|
+
function applyFilters(){
|
|
355
|
+
const on = graphActiveFilters;
|
|
356
|
+
let visible = 0;
|
|
357
|
+
graphNodeGroups?.attr('display', n => { const show = on.has(n.type); if(show) visible++; return show ? null : 'none'; });
|
|
358
|
+
graphLinks?.attr('stroke-opacity', l => {
|
|
359
|
+
const sid = typeof l.source==='object'?l.source.id:l.source;
|
|
360
|
+
const tid = typeof l.target==='object'?l.target.id:l.target;
|
|
361
|
+
const st = graphNodeMap?.get(sid)?.type;
|
|
362
|
+
const tt = graphNodeMap?.get(tid)?.type;
|
|
363
|
+
return (st && tt && on.has(st) && on.has(tt)) ? 0.18 : 0.02;
|
|
364
|
+
});
|
|
365
|
+
list.querySelectorAll('.graph-type-pill').forEach(p => p.classList.toggle('dimmed', !on.has(p.dataset.type)));
|
|
366
|
+
refreshMeta(visible);
|
|
367
|
+
}
|
|
368
|
+
types.forEach(t => {
|
|
369
|
+
const btn = document.createElement('button');
|
|
370
|
+
btn.type = 'button';
|
|
371
|
+
btn.className = 'graph-type-pill active';
|
|
372
|
+
btn.dataset.type = t;
|
|
373
|
+
btn.innerHTML = `<span class="dot" style="background:${ENTITY_COLORS[t]||ENTITY_COLORS.default}"></span><span class="name">${t}</span><span class="count">${counts[t]}</span>`;
|
|
374
|
+
btn.onclick = () => {
|
|
375
|
+
if(on.has(t) && on.size>1) on.delete(t); else on.add(t);
|
|
376
|
+
btn.classList.toggle('active', on.has(t));
|
|
377
|
+
applyFilters();
|
|
378
|
+
};
|
|
379
|
+
list.append(btn);
|
|
380
|
+
});
|
|
381
|
+
refreshMeta(nodes.length);
|
|
382
|
+
return { sidebar, applyFilters };
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function paintGraphMinimap(simNodes){
|
|
386
|
+
if(!graphMinimapCtx) return;
|
|
387
|
+
const MAP_W = GRAPH_MINIMAP_W, MAP_H = GRAPH_MINIMAP_H, PAD = GRAPH_MINIMAP_PAD;
|
|
388
|
+
const mctx = graphMinimapCtx;
|
|
389
|
+
const wrap = graphCanvasWrap;
|
|
390
|
+
const w = wrap.clientWidth, h = wrap.clientHeight;
|
|
391
|
+
const zoom = graphZoomState;
|
|
392
|
+
mctx.clearRect(0, 0, MAP_W, MAP_H);
|
|
393
|
+
let minX=Infinity,minY=Infinity,maxX=-Infinity,maxY=-Infinity;
|
|
394
|
+
simNodes.forEach(n => {
|
|
395
|
+
const x=n.x??0,y=n.y??0;
|
|
396
|
+
if(x<minX)minX=x; if(y<minY)minY=y; if(x>maxX)maxX=x; if(y>maxY)maxY=y;
|
|
397
|
+
});
|
|
398
|
+
const vx0=-zoom.x/zoom.k, vy0=-zoom.y/zoom.k, vx1=(w-zoom.x)/zoom.k, vy1=(h-zoom.y)/zoom.k;
|
|
399
|
+
minX=Math.min(minX,vx0); minY=Math.min(minY,vy0); maxX=Math.max(maxX,vx1); maxY=Math.max(maxY,vy1);
|
|
400
|
+
if(!Number.isFinite(minX)){ minX=0;minY=0;maxX=w;maxY=h; }
|
|
401
|
+
const dx=maxX-minX||1, dy=maxY-minY||1;
|
|
402
|
+
const scale=Math.min((MAP_W-PAD*2)/dx,(MAP_H-PAD*2)/dy);
|
|
403
|
+
const toMap=(x,y)=>[PAD+(x-minX)*scale,PAD+(y-minY)*scale];
|
|
404
|
+
mctx.globalAlpha=.75;
|
|
405
|
+
simNodes.forEach(n => {
|
|
406
|
+
if(graphActiveFilters && !graphActiveFilters.has(n.type)) return;
|
|
407
|
+
const [mx,my]=toMap(n.x??0,n.y??0);
|
|
408
|
+
mctx.fillStyle=nodeColor(n);
|
|
409
|
+
mctx.beginPath(); mctx.arc(mx,my,1.2,0,Math.PI*2); mctx.fill();
|
|
410
|
+
});
|
|
411
|
+
mctx.globalAlpha=1;
|
|
412
|
+
const [rx,ry]=toMap(vx0,vy0), rw=(vx1-vx0)*scale, rh=(vy1-vy0)*scale;
|
|
413
|
+
mctx.fillStyle='rgba(0,0,0,.45)';
|
|
414
|
+
const mask=new Path2D();
|
|
415
|
+
mask.rect(0,0,MAP_W,MAP_H); mask.rect(rx,ry,rw,rh);
|
|
416
|
+
mctx.fill(mask,'evenodd');
|
|
417
|
+
mctx.strokeStyle='rgba(255,255,255,.85)'; mctx.lineWidth=1;
|
|
418
|
+
mctx.strokeRect(rx+.5,ry+.5,rw-1,rh-1);
|
|
419
|
+
updateGraphBeacon(simNodes, w, h);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
function updateGraphBeacon(simNodes, w, h){
|
|
423
|
+
if(!graphBeacon) return;
|
|
424
|
+
const zoom=graphZoomState;
|
|
425
|
+
let minX=Infinity,minY=Infinity,maxX=-Infinity,maxY=-Infinity,cx=0,cy=0,n=0;
|
|
426
|
+
simNodes.forEach(nd => {
|
|
427
|
+
if(graphActiveFilters && !graphActiveFilters.has(nd.type)) return;
|
|
428
|
+
const x=nd.x??0,y=nd.y??0; cx+=x; cy+=y; n++;
|
|
429
|
+
if(x<minX)minX=x; if(y<minY)minY=y; if(x>maxX)maxX=x; if(y>maxY)maxY=y;
|
|
430
|
+
});
|
|
431
|
+
if(!n){ graphBeacon.classList.remove('visible'); return; }
|
|
432
|
+
cx/=n; cy/=n;
|
|
433
|
+
const vx0=-zoom.x/zoom.k, vy0=-zoom.y/zoom.k, vx1=(w-zoom.x)/zoom.k, vy1=(h-zoom.y)/zoom.k;
|
|
434
|
+
const offscreen = maxX<vx0||minX>vx1||maxY<vy0||minY>vy1;
|
|
435
|
+
if(!offscreen){ graphBeacon.classList.remove('visible'); return; }
|
|
436
|
+
const sx=cx*zoom.k+zoom.x, sy=cy*zoom.k+zoom.y;
|
|
437
|
+
const pad=56, hw=Math.max(24,w/2-pad), hh=Math.max(24,h/2-pad);
|
|
438
|
+
const dx=sx-w/2, dy=sy-h/2;
|
|
439
|
+
const sc=Math.min(Math.abs(hw/(dx||1e-6)),Math.abs(hh/(dy||1e-6)));
|
|
440
|
+
graphBeacon.style.left=(w/2+dx*sc)+'px';
|
|
441
|
+
graphBeacon.style.top=(h/2+dy*sc)+'px';
|
|
442
|
+
graphBeacon.classList.add('visible');
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
function updateLabelVisibility(){
|
|
446
|
+
const show = graphZoomState.k >= GRAPH_LABEL_MIN_ZOOM;
|
|
447
|
+
graphLabels?.attr('opacity', show ? 0.85 : 0);
|
|
448
|
+
graphEdgeLabels?.attr('opacity', show ? 0.35 : 0);
|
|
449
|
+
}
|
|
304
450
|
|
|
305
451
|
async function initGraph(){
|
|
306
452
|
try{ const r = await fetch('/api/graph'); S.graph = await r.json(); }
|
|
@@ -310,75 +456,217 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
310
456
|
buildCmdItems();
|
|
311
457
|
|
|
312
458
|
const container = $('graph-panel');
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
459
|
+
container.innerHTML = '';
|
|
460
|
+
const layout = document.createElement('div');
|
|
461
|
+
layout.className = 'graph-layout';
|
|
462
|
+
const { sidebar, applyFilters } = buildGraphSidebar(nodes);
|
|
463
|
+
graphCanvasWrap = document.createElement('div');
|
|
464
|
+
graphCanvasWrap.className = 'graph-canvas-wrap';
|
|
465
|
+
graphCanvasWrap.id = 'graph-canvas-wrap';
|
|
466
|
+
layout.append(sidebar, graphCanvasWrap);
|
|
467
|
+
container.append(layout);
|
|
468
|
+
|
|
469
|
+
const w = graphCanvasWrap.clientWidth || 800, h = graphCanvasWrap.clientHeight || 600;
|
|
470
|
+
const svg = d3.select(graphCanvasWrap).append('svg').attr('width', w).attr('height', h);
|
|
316
471
|
graphSvg = svg;
|
|
317
472
|
const g = svg.append('g');
|
|
318
473
|
graphG = g;
|
|
319
|
-
graphZoom = d3.zoom().scaleExtent([0.
|
|
474
|
+
graphZoom = d3.zoom().scaleExtent([0.05, 4]).on('zoom', e => {
|
|
475
|
+
g.attr('transform', e.transform);
|
|
476
|
+
graphZoomState = { k: e.transform.k, x: e.transform.x, y: e.transform.y };
|
|
477
|
+
updateLabelVisibility();
|
|
478
|
+
paintGraphMinimap(simNodes);
|
|
479
|
+
});
|
|
320
480
|
svg.call(graphZoom);
|
|
481
|
+
svg.on('click', () => { clearGraphHighlight(); drawer.classList.remove('open'); });
|
|
321
482
|
|
|
322
483
|
const simLinks = edges.map(e => ({...e}));
|
|
323
484
|
const simNodes = nodes.map(n => ({...n}));
|
|
324
485
|
graphNodeMap = new Map(); simNodes.forEach(n => graphNodeMap.set(n.id, n));
|
|
325
486
|
|
|
487
|
+
const size = simNodes.length;
|
|
488
|
+
const dist = size > 800 ? 45 : size > 300 ? 60 : 90;
|
|
489
|
+
const charge = size > 800 ? -90 : size > 300 ? -130 : -220;
|
|
490
|
+
|
|
326
491
|
graphSim = d3.forceSimulation(simNodes)
|
|
327
|
-
.force('link', d3.forceLink(simLinks).id(d=>d.id).distance(
|
|
328
|
-
.force('charge', d3.forceManyBody().strength(
|
|
492
|
+
.force('link', d3.forceLink(simLinks).id(d=>d.id).distance(dist).strength(0.35))
|
|
493
|
+
.force('charge', d3.forceManyBody().strength(charge).distanceMax(400))
|
|
329
494
|
.force('center', d3.forceCenter(w/2, h/2))
|
|
330
|
-
.force('collision', d3.forceCollide().radius(d=>(
|
|
331
|
-
.
|
|
332
|
-
|
|
495
|
+
.force('collision', d3.forceCollide().radius(d => nodeRadius(d) + 4))
|
|
496
|
+
.alphaDecay(0.04).alphaMin(0.02);
|
|
497
|
+
|
|
498
|
+
graphLinks = g.append('g').attr('class','graph-links').selectAll('line').data(simLinks).join('line')
|
|
499
|
+
.attr('stroke', 'var(--text3)')
|
|
500
|
+
.attr('stroke-width', 1)
|
|
501
|
+
.attr('stroke-opacity', 0.18)
|
|
502
|
+
.attr('stroke-dasharray', d => d.type==='wikilink' ? '3,3' : null);
|
|
503
|
+
|
|
504
|
+
graphEdgeLabels = g.append('g').attr('class','graph-edge-labels').selectAll('text').data(simLinks).join('text')
|
|
505
|
+
.text(d => EDGE_LABELS[d.type] || d.type)
|
|
506
|
+
.attr('font-size', 9).attr('font-weight', 500).attr('fill', 'var(--text2)')
|
|
507
|
+
.attr('stroke', 'var(--bg)').attr('stroke-width', 3).attr('paint-order', 'stroke')
|
|
508
|
+
.attr('text-anchor', 'middle').attr('dy', '0.35em').attr('opacity', 0);
|
|
509
|
+
|
|
510
|
+
graphNodeGroups = g.append('g').attr('class','graph-nodes').selectAll('g').data(simNodes).join('g')
|
|
511
|
+
.attr('cursor', 'pointer')
|
|
512
|
+
.call(d3.drag().on('start',(e,d)=>{if(!e.active)graphSim.alphaTarget(.25).restart();d.fx=d.x;d.fy=d.y})
|
|
513
|
+
.on('drag',(e,d)=>{d.fx=e.x;d.fy=e.y})
|
|
514
|
+
.on('end',(e,d)=>{if(!e.active)graphSim.alphaTarget(0);d.fx=null;d.fy=null}));
|
|
515
|
+
|
|
516
|
+
graphNodeGroups.append('circle')
|
|
517
|
+
.attr('r', d => nodeRadius(d))
|
|
518
|
+
.attr('fill', d => nodeColor(d))
|
|
519
|
+
.attr('stroke', 'transparent').attr('stroke-width', 2);
|
|
520
|
+
|
|
521
|
+
graphLabels = graphNodeGroups.append('text')
|
|
522
|
+
.text(d => d.label.length > 24 ? d.label.slice(0, 24) + '…' : d.label)
|
|
523
|
+
.attr('font-size', 10).attr('fill', 'var(--text2)')
|
|
524
|
+
.attr('x', d => nodeRadius(d) + 5).attr('dy', 4)
|
|
525
|
+
.attr('pointer-events', 'none').attr('opacity', 0)
|
|
526
|
+
.attr('font-family', 'Inter,sans-serif');
|
|
527
|
+
|
|
528
|
+
const graphTip = document.createElement('div');
|
|
529
|
+
graphTip.className = 'graph-tooltip';
|
|
530
|
+
graphCanvasWrap.appendChild(graphTip);
|
|
531
|
+
|
|
532
|
+
graphNodeGroups.on('mouseenter', (e, d) => {
|
|
533
|
+
graphTip.innerHTML = `<div class="gt-type">${d.type}</div><div class="gt-label">${esc(d.label)}</div>`;
|
|
534
|
+
graphTip.classList.add('visible');
|
|
535
|
+
graphTip.style.left = (e.offsetX + 14) + 'px';
|
|
536
|
+
graphTip.style.top = (e.offsetY + 10) + 'px';
|
|
537
|
+
$('tooltip').style.display = 'none';
|
|
538
|
+
}).on('mousemove', (e) => {
|
|
539
|
+
graphTip.style.left = (e.offsetX + 14) + 'px';
|
|
540
|
+
graphTip.style.top = (e.offsetY + 10) + 'px';
|
|
541
|
+
}).on('mouseleave', () => graphTip.classList.remove('visible'))
|
|
542
|
+
.on('click', (e, d) => { e.stopPropagation(); highlightGraphNode(d); loadNodeDetail(d.id); });
|
|
333
543
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
544
|
+
graphSim.on('tick', () => {
|
|
545
|
+
graphLinks
|
|
546
|
+
.attr('x1', d => d.source.x).attr('y1', d => d.source.y)
|
|
547
|
+
.attr('x2', d => d.target.x).attr('y2', d => d.target.y);
|
|
548
|
+
graphNodeGroups.attr('transform', d => `translate(${d.x},${d.y})`);
|
|
549
|
+
graphEdgeLabels
|
|
550
|
+
.attr('x', d => (d.source.x + d.target.x) / 2)
|
|
551
|
+
.attr('y', d => (d.source.y + d.target.y) / 2);
|
|
552
|
+
paintGraphMinimap(simNodes);
|
|
553
|
+
});
|
|
337
554
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
555
|
+
// Minimap
|
|
556
|
+
graphMinimap = document.createElement('canvas');
|
|
557
|
+
graphMinimap.className = 'graph-minimap';
|
|
558
|
+
graphMinimap.width = GRAPH_MINIMAP_W * (devicePixelRatio||1);
|
|
559
|
+
graphMinimap.height = GRAPH_MINIMAP_H * (devicePixelRatio||1);
|
|
560
|
+
graphMinimap.style.width = GRAPH_MINIMAP_W + 'px';
|
|
561
|
+
graphMinimap.style.height = GRAPH_MINIMAP_H + 'px';
|
|
562
|
+
graphMinimapCtx = graphMinimap.getContext('2d');
|
|
563
|
+
graphMinimapCtx.scale(devicePixelRatio||1, devicePixelRatio||1);
|
|
564
|
+
graphCanvasWrap.appendChild(graphMinimap);
|
|
565
|
+
|
|
566
|
+
function panToWorld(wx, wy){
|
|
567
|
+
const k = graphZoomState.k;
|
|
568
|
+
svg.transition().duration(280).call(graphZoom.transform, d3.zoomIdentity.translate(w/2 - wx*k, h/2 - wy*k).scale(k));
|
|
569
|
+
}
|
|
570
|
+
function minimapPoint(evt){
|
|
571
|
+
const rect = graphMinimap.getBoundingClientRect();
|
|
572
|
+
const mx = evt.clientX - rect.left, my = evt.clientY - rect.top;
|
|
573
|
+
let minX=Infinity,minY=Infinity,maxX=-Infinity,maxY=-Infinity;
|
|
574
|
+
simNodes.forEach(n => { const x=n.x??0,y=n.y??0; if(x<minX)minX=x; if(y<minY)minY=y; if(x>maxX)maxX=x; if(y>maxY)maxY=y; });
|
|
575
|
+
const dx=maxX-minX||1, dy=maxY-minY||1;
|
|
576
|
+
const scale=Math.min((GRAPH_MINIMAP_W-GRAPH_MINIMAP_PAD*2)/dx,(GRAPH_MINIMAP_H-GRAPH_MINIMAP_PAD*2)/dy);
|
|
577
|
+
return [(mx-GRAPH_MINIMAP_PAD)/scale+minX, (my-GRAPH_MINIMAP_PAD)/scale+minY];
|
|
578
|
+
}
|
|
579
|
+
graphMinimap.addEventListener('mousedown', e => { e.preventDefault(); panToWorld(...minimapPoint(e)); });
|
|
580
|
+
graphMinimap.addEventListener('mousemove', e => { if(e.buttons===1) panToWorld(...minimapPoint(e)); });
|
|
581
|
+
|
|
582
|
+
// Return-to-graph beacon
|
|
583
|
+
graphBeacon = document.createElement('button');
|
|
584
|
+
graphBeacon.type = 'button';
|
|
585
|
+
graphBeacon.className = 'graph-beacon';
|
|
586
|
+
graphBeacon.setAttribute('aria-label', 'Return to graph');
|
|
587
|
+
graphBeacon.innerHTML = '<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2"><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></svg>';
|
|
588
|
+
graphBeacon.onclick = e => { e.stopPropagation(); fitGraph(); };
|
|
589
|
+
graphCanvasWrap.appendChild(graphBeacon);
|
|
590
|
+
|
|
591
|
+
// Graph chrome (fit / reset)
|
|
592
|
+
const chrome = document.createElement('div');
|
|
593
|
+
chrome.className = 'graph-chrome';
|
|
594
|
+
chrome.innerHTML = '<div class="graph-chrome-head"><span>Graph</span><button type="button" id="graph-chrome-reset">Reset</button></div><div class="graph-chrome-body"><button type="button" id="graph-chrome-fit">Fit to view</button></div>';
|
|
595
|
+
graphCanvasWrap.appendChild(chrome);
|
|
596
|
+
chrome.querySelector('#graph-chrome-fit').onclick = () => fitGraph();
|
|
597
|
+
chrome.querySelector('#graph-chrome-reset').onclick = () => { simNodes.forEach(n => { n.fx=null; n.fy=null; }); graphSim.alpha(0.6).restart(); };
|
|
598
|
+
|
|
599
|
+
const ctrlDiv = document.createElement('div');
|
|
600
|
+
ctrlDiv.className = 'graph-controls';
|
|
601
|
+
ctrlDiv.innerHTML = '<button id="gz-in" title="Zoom in">+</button><button id="gz-out" title="Zoom out">−</button><button id="gz-fit" title="Fit">⊙</button>';
|
|
602
|
+
graphCanvasWrap.appendChild(ctrlDiv);
|
|
603
|
+
$('gz-in').onclick = () => svg.transition().duration(200).call(graphZoom.scaleBy, 1.4);
|
|
604
|
+
$('gz-out').onclick = () => svg.transition().duration(200).call(graphZoom.scaleBy, 0.72);
|
|
605
|
+
$('gz-fit').onclick = () => fitGraph();
|
|
606
|
+
|
|
607
|
+
applyFilters();
|
|
608
|
+
graphSim.on('end', () => { fitGraph(); updateLabelVisibility(); });
|
|
609
|
+
|
|
610
|
+
const onResize = () => {
|
|
611
|
+
const nw = graphCanvasWrap.clientWidth, nh = graphCanvasWrap.clientHeight;
|
|
612
|
+
svg.attr('width', nw).attr('height', nh);
|
|
613
|
+
graphSim.force('center', d3.forceCenter(nw/2, nh/2));
|
|
614
|
+
paintGraphMinimap(simNodes);
|
|
615
|
+
};
|
|
616
|
+
window.addEventListener('resize', onResize);
|
|
617
|
+
}
|
|
343
618
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
619
|
+
function fitGraph(){
|
|
620
|
+
if(!graphG?.node()) return;
|
|
621
|
+
const b = graphG.node().getBBox();
|
|
622
|
+
if(!b.width) return;
|
|
623
|
+
const w = graphCanvasWrap?.clientWidth || 800, h = graphCanvasWrap?.clientHeight || 600, p = 80;
|
|
624
|
+
const s = Math.min((w - p*2)/b.width, (h - p*2)/b.height, 2);
|
|
625
|
+
graphSvg.transition().duration(500).call(graphZoom.transform,
|
|
626
|
+
d3.zoomIdentity.translate(w/2, h/2).scale(s).translate(-b.x - b.width/2, -b.y - b.height/2));
|
|
627
|
+
}
|
|
347
628
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
629
|
+
function highlightGraphNode(d){
|
|
630
|
+
const c = new Set([d.id]);
|
|
631
|
+
graphLinks.each(function(l){
|
|
632
|
+
const s = typeof l.source==='object'?l.source.id:l.source;
|
|
633
|
+
const t = typeof l.target==='object'?l.target.id:l.target;
|
|
634
|
+
if(s===d.id) c.add(t); if(t===d.id) c.add(s);
|
|
635
|
+
});
|
|
636
|
+
graphNodeGroups.attr('opacity', n => c.has(n.id) ? 1 : 0.15);
|
|
637
|
+
graphNodeGroups.select('circle').attr('stroke', n => c.has(n.id) ? '#fff' : 'transparent').attr('stroke-width', n => c.has(n.id) ? 2.5 : 0);
|
|
638
|
+
graphLinks.each(function(l){
|
|
639
|
+
const s = typeof l.source==='object'?l.source.id:l.source;
|
|
640
|
+
const t = typeof l.target==='object'?l.target.id:l.target;
|
|
641
|
+
const on = (s===d.id||t===d.id);
|
|
642
|
+
d3.select(this).classed('edge-flow', on).attr('stroke-opacity', on ? 0.75 : 0.04);
|
|
643
|
+
});
|
|
644
|
+
graphLabels.attr('opacity', n => c.has(n.id) ? 1 : 0.1);
|
|
645
|
+
graphEdgeLabels.attr('opacity', l => {
|
|
646
|
+
const s = typeof l.source==='object'?l.source.id:l.source;
|
|
647
|
+
const t = typeof l.target==='object'?l.target.id:l.target;
|
|
648
|
+
return (s===d.id||t===d.id) && graphZoomState.k >= GRAPH_LABEL_MIN_ZOOM ? 0.9 : 0;
|
|
352
649
|
});
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function clearGraphHighlight(){
|
|
653
|
+
graphNodeGroups?.attr('opacity', 1);
|
|
654
|
+
graphNodeGroups?.select('circle').attr('stroke', 'transparent');
|
|
655
|
+
graphLinks?.attr('stroke-opacity', 0.18).classed('edge-flow', false);
|
|
656
|
+
graphLabels?.attr('opacity', graphZoomState.k >= GRAPH_LABEL_MIN_ZOOM ? 0.85 : 0);
|
|
657
|
+
graphEdgeLabels?.attr('opacity', graphZoomState.k >= GRAPH_LABEL_MIN_ZOOM ? 0.35 : 0);
|
|
658
|
+
}
|
|
353
659
|
|
|
354
|
-
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
// Legend
|
|
365
|
-
const legendHtml = Object.entries(TYPE_COLORS).filter(([k])=>k!=='default').map(([k,c])=>`<div class="legend-item"><div class="legend-dot" style="background:${c}"></div>${k}</div>`).join('');
|
|
366
|
-
const legendDiv = document.createElement('div'); legendDiv.className='graph-legend'; legendDiv.innerHTML=legendHtml; container.appendChild(legendDiv);
|
|
367
|
-
|
|
368
|
-
// Zoom controls
|
|
369
|
-
const ctrlDiv = document.createElement('div'); ctrlDiv.className='graph-controls';
|
|
370
|
-
ctrlDiv.innerHTML='<button id="gz-in">+</button><button id="gz-out">−</button><button id="gz-fit">⊙</button>';
|
|
371
|
-
container.appendChild(ctrlDiv);
|
|
372
|
-
$('gz-in').onclick=()=>svg.transition().duration(300).call(graphZoom.scaleBy,1.5);
|
|
373
|
-
$('gz-out').onclick=()=>svg.transition().duration(300).call(graphZoom.scaleBy,0.67);
|
|
374
|
-
$('gz-fit').onclick=()=>fitGraph();
|
|
375
|
-
|
|
376
|
-
graphSim.on('end', fitGraph);
|
|
660
|
+
function focusGraphNode(id){
|
|
661
|
+
const n = graphNodeMap?.get(id);
|
|
662
|
+
if(!n) return;
|
|
663
|
+
switchPanel('graph');
|
|
664
|
+
highlightGraphNode(n);
|
|
665
|
+
loadNodeDetail(id);
|
|
666
|
+
const w = graphCanvasWrap?.clientWidth || 800, h = graphCanvasWrap?.clientHeight || 600;
|
|
667
|
+
graphSvg.transition().duration(450).call(graphZoom.transform,
|
|
668
|
+
d3.zoomIdentity.translate(w/2, h/2).scale(Math.max(graphZoomState.k, 1)).translate(-n.x, -n.y));
|
|
377
669
|
}
|
|
378
|
-
function fitGraph(){ const b=graphG.node().getBBox();if(!b.width)return;const w=$('graph-panel').clientWidth,h=$('graph-panel').clientHeight,p=50;const s=Math.min((w-p*2)/b.width,(h-p*2)/b.height,2);graphSvg.transition().duration(600).call(graphZoom.transform,d3.zoomIdentity.translate(w/2,h/2).scale(s).translate(-b.x-b.width/2,-b.y-b.height/2)); }
|
|
379
|
-
function highlightGraphNode(d){ const c=new Set([d.id]);graphLinks.each(function(l){const s=typeof l.source==='object'?l.source.id:l.source;const t=typeof l.target==='object'?l.target.id:l.target;if(s===d.id)c.add(t);if(t===d.id)c.add(s)});graphNodes.attr('opacity',n=>c.has(n.id)?1:.12);graphLinks.attr('opacity',l=>{const s=typeof l.source==='object'?l.source.id:l.source;const t=typeof l.target==='object'?l.target.id:l.target;return(s===d.id||t===d.id)?1:.04});graphLabels.attr('opacity',n=>c.has(n.id)?1:.08); }
|
|
380
|
-
function clearGraphHighlight(){ graphNodes?.attr('opacity',1); graphLinks?.attr('opacity',1); graphLabels?.attr('opacity',.8); }
|
|
381
|
-
function focusGraphNode(id){ const n=graphNodeMap?.get(id);if(!n)return;highlightGraphNode(n);loadNodeDetail(id);graphSvg.transition().duration(500).call(graphZoom.translateTo,n.x,n.y); }
|
|
382
670
|
|
|
383
671
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
384
672
|
// TIMELINE PANEL
|
|
@@ -394,7 +682,7 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
394
682
|
if(!ops.length){ $('tl-body').innerHTML='<div class="tl-empty">No operations yet</div>'; return; }
|
|
395
683
|
const body = $('tl-body');
|
|
396
684
|
const W = Math.max(body.clientWidth, ops.length*14+120), H = body.clientHeight-20;
|
|
397
|
-
const KIND_COLORS = {'vcs:fileAdd':
|
|
685
|
+
const KIND_COLORS = {'vcs:fileAdd':ENTITY_COLORS.file,'vcs:fileModify':'#38bdf8','vcs:fileDelete':ENTITY_COLORS.issue,'vcs:fileRename':'#fb923c','vcs:branchCreate':ENTITY_COLORS.branch,'vcs:branchDelete':'#f472b6','vcs:milestoneCreate':ENTITY_COLORS.milestone,'vcs:checkpointCreate':'#6b7280'};
|
|
398
686
|
const svg = d3.select('#tl-body').append('svg').attr('width',W).attr('height',H);
|
|
399
687
|
const x = d3.scaleLinear().domain([0,ops.length-1||1]).range([40,W-40]);
|
|
400
688
|
const laneY = H/2;
|
|
@@ -412,9 +700,9 @@ body{font-family:var(--font);background:var(--bg);color:var(--text);overflow:hid
|
|
|
412
700
|
.on('click',(e,d)=>{e.stopPropagation();openDrawer('Op: '+d.kind,`<div class="d-section"><div class="d-kv"><span class="k">kind</span><span class="v">${d.kind}</span><span class="k">hash</span><span class="v">${d.hash}</span><span class="k">time</span><span class="v">${d.timestamp||''}</span><span class="k">agent</span><span class="v">${d.agentId||''}</span>${d.filePath?'<span class="k">file</span><span class="v">'+esc(d.filePath)+'</span>':''}${d.branchName?'<span class="k">branch</span><span class="v">'+esc(d.branchName)+'</span>':''}</div></div>`)});
|
|
413
701
|
|
|
414
702
|
// Milestone markers
|
|
415
|
-
milestones.forEach(m=>{const mx=x(m.atOpIndex);svg.append('polygon').attr('points',`${mx},${laneY-18} ${mx+6},${laneY-10} ${mx},${laneY-2} ${mx-6},${laneY-10}`).attr('fill',
|
|
703
|
+
milestones.forEach(m=>{const mx=x(m.atOpIndex);svg.append('polygon').attr('points',`${mx},${laneY-18} ${mx+6},${laneY-10} ${mx},${laneY-2} ${mx-6},${laneY-10}`).attr('fill',ENTITY_COLORS.milestone).attr('opacity',.85).attr('cursor','pointer')
|
|
416
704
|
.on('click',()=>openDrawer('Milestone',`<div class="d-section"><h4>Message</h4><div class="d-meta"><strong>${esc(m.message||'')}</strong></div></div><div class="d-section"><div class="d-kv"><span class="k">ID</span><span class="v">${m.id}</span><span class="k">at op</span><span class="v">#${m.atOpIndex}</span><span class="k">files</span><span class="v">${m.affectedFiles}</span></div></div>`));
|
|
417
|
-
svg.append('text').attr('x',mx).attr('y',laneY-22).attr('text-anchor','middle').attr('font-size',9).attr('fill',
|
|
705
|
+
svg.append('text').attr('x',mx).attr('y',laneY-22).attr('text-anchor','middle').attr('font-size',9).attr('fill',ENTITY_COLORS.milestone).attr('font-family','Inter').text(m.message?.slice(0,20)||m.id)});
|
|
418
706
|
|
|
419
707
|
// Checkpoint ticks
|
|
420
708
|
checkpoints.forEach(c=>{const cx=x(c.atOpIndex);svg.append('line').attr('x1',cx).attr('y1',laneY+8).attr('x2',cx).attr('y2',laneY+18).attr('stroke','#6b7280').attr('stroke-width',1).attr('opacity',.5)});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Launch the SvelteKit realtime explorer (demo/realtime-app).
|
|
3
|
+
* Replaces the legacy client.html System Visualizer for `trellis ui`.
|
|
4
|
+
*/
|
|
5
|
+
export type LaunchExplorerOptions = {
|
|
6
|
+
/** Repo root — ensures .trellis exists; explorer DB lives in demo/realtime-app */
|
|
7
|
+
rootPath: string;
|
|
8
|
+
/** SvelteKit dev port (default 4000) */
|
|
9
|
+
appPort?: number;
|
|
10
|
+
/** Trellis graph sidecar port (default 3920) */
|
|
11
|
+
trellisPort?: number;
|
|
12
|
+
};
|
|
13
|
+
export type LaunchExplorerHandle = {
|
|
14
|
+
appPort: number;
|
|
15
|
+
trellisPort: number;
|
|
16
|
+
appUrl: string;
|
|
17
|
+
trellisUrl: string;
|
|
18
|
+
stop: () => void;
|
|
19
|
+
};
|
|
20
|
+
export declare function resolveExplorerAppDir(): string;
|
|
21
|
+
export declare function launchRealtimeExplorer(opts: LaunchExplorerOptions): Promise<LaunchExplorerHandle>;
|
|
22
|
+
//# sourceMappingURL=launch-explorer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-explorer.d.ts","sourceRoot":"","sources":["../../src/ui/launch-explorer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,MAAM,qBAAqB,GAAG;IAClC,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAIF,wBAAgB,qBAAqB,IAAI,MAAM,CAY9C;AAMD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,oBAAoB,CAAC,CA0D/B"}
|
package/dist/ui/server.d.ts
CHANGED
package/dist/ui/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAmBH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,gBAAgB,GAAG,cAAc,GAAG,UAAU,GAAG,QAAQ,CAAC;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAqZD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC,CAsOD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blob-store.d.ts","sourceRoot":"","sources":["../../src/vcs/blob-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,UAAU,EAAE,MAAM;IAO9B;;;OAGG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IASxD;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM;IAS7C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQhC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM;
|
|
1
|
+
{"version":3,"file":"blob-store.d.ts","sourceRoot":"","sources":["../../src/vcs/blob-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;gBAEZ,UAAU,EAAE,MAAM;IAO9B;;;OAGG;IACG,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IASxD;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM;IAS7C;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQhC;;OAEG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM;IAK9C;;OAEG;IACH,KAAK,IAAI,MAAM;IASf;;OAEG;IACH,SAAS,IAAI,MAAM;IAgBnB,OAAO,CAAC,aAAa;CAKtB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IndexedDB-backed op log.
|
|
3
|
+
*
|
|
4
|
+
* Browser-side companion to {@link JsonOpLog}. Designed to satisfy the
|
|
5
|
+
* {@link OpLog} contract while accommodating IndexedDB's async nature:
|
|
6
|
+
*
|
|
7
|
+
* - `load()` opens the database and pulls every persisted op into an
|
|
8
|
+
* in-memory cache. All subsequent reads serve from cache, so the engine
|
|
9
|
+
* can continue using synchronous `readAll`/`getLastOp`/`count`.
|
|
10
|
+
* - `append()` is synchronous from the caller's perspective: it updates the
|
|
11
|
+
* in-memory cache immediately and enqueues a durable IDB write. The
|
|
12
|
+
* returned promise from `flush()` resolves once every queued write has
|
|
13
|
+
* committed.
|
|
14
|
+
* - Hash dedup happens against the cache before the write is enqueued, so
|
|
15
|
+
* replayed sync batches never insert the same op twice.
|
|
16
|
+
*
|
|
17
|
+
* Default store layout: one database per repo, one object store keyed by
|
|
18
|
+
* `hash`, with a monotonically-increasing `seq` index so we can replay in
|
|
19
|
+
* append order on load. Callers may override the IDB factory in tests by
|
|
20
|
+
* passing `indexedDB` in the constructor options.
|
|
21
|
+
*/
|
|
22
|
+
import type { VcsOp } from './types.js';
|
|
23
|
+
import type { OpLog } from './op-log.js';
|
|
24
|
+
/**
|
|
25
|
+
* Subset of the IndexedDB Factory we use. Matches both `globalThis.indexedDB`
|
|
26
|
+
* and `fake-indexeddb`'s `IDBFactory`. Allows test injection without pulling
|
|
27
|
+
* in the full DOM typings.
|
|
28
|
+
*/
|
|
29
|
+
export interface IdbFactoryLike {
|
|
30
|
+
open(name: string, version?: number): IDBOpenDBRequest;
|
|
31
|
+
}
|
|
32
|
+
export interface IdbOpLogOptions {
|
|
33
|
+
/** Database name. One Trellis repo per database. */
|
|
34
|
+
dbName: string;
|
|
35
|
+
/**
|
|
36
|
+
* Object store name. Defaults to `ops`. Override if multiple op logs share
|
|
37
|
+
* a database (e.g. integration journal vs. lane journals).
|
|
38
|
+
*/
|
|
39
|
+
storeName?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Injected IndexedDB factory. Defaults to `globalThis.indexedDB`. Tests
|
|
42
|
+
* pass `fake-indexeddb`'s factory directly.
|
|
43
|
+
*/
|
|
44
|
+
indexedDB?: IdbFactoryLike;
|
|
45
|
+
}
|
|
46
|
+
export declare class IdbOpLog implements OpLog {
|
|
47
|
+
private ops;
|
|
48
|
+
private hashes;
|
|
49
|
+
private db;
|
|
50
|
+
private nextSeq;
|
|
51
|
+
private pendingWrites;
|
|
52
|
+
private readonly dbName;
|
|
53
|
+
private readonly storeName;
|
|
54
|
+
private readonly factory;
|
|
55
|
+
constructor(opts: IdbOpLogOptions);
|
|
56
|
+
load(): Promise<void>;
|
|
57
|
+
append(op: VcsOp): void;
|
|
58
|
+
readAll(): VcsOp[];
|
|
59
|
+
getLastOp(): VcsOp | undefined;
|
|
60
|
+
count(): number;
|
|
61
|
+
flush(): Promise<void>;
|
|
62
|
+
close(): Promise<void>;
|
|
63
|
+
private openDb;
|
|
64
|
+
private readAllRecords;
|
|
65
|
+
private putRecord;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=idb-op-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idb-op-log.d.ts","sourceRoot":"","sources":["../../src/vcs/idb-op-log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;CACxD;AAED,MAAM,WAAW,eAAe;IAC9B,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAQD,qBAAa,QAAS,YAAW,KAAK;IACpC,OAAO,CAAC,GAAG,CAAe;IAC1B,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,EAAE,CAA4B;IACtC,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;gBAE7B,IAAI,EAAE,eAAe;IAc3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,MAAM,CAAC,EAAE,EAAE,KAAK,GAAG,IAAI;IAevB,OAAO,IAAI,KAAK,EAAE;IAIlB,SAAS,IAAI,KAAK,GAAG,SAAS;IAI9B,KAAK,IAAI,MAAM;IAIT,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,SAAS;CAclB"}
|