aifastdb-devplan 1.5.0 → 1.6.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.
Files changed (121) hide show
  1. package/dist/autopilot.d.ts +58 -0
  2. package/dist/autopilot.d.ts.map +1 -0
  3. package/dist/autopilot.js +250 -0
  4. package/dist/autopilot.js.map +1 -0
  5. package/dist/dev-plan-document-store.d.ts +15 -1
  6. package/dist/dev-plan-document-store.d.ts.map +1 -1
  7. package/dist/dev-plan-document-store.js +122 -0
  8. package/dist/dev-plan-document-store.js.map +1 -1
  9. package/dist/dev-plan-factory.d.ts +69 -3
  10. package/dist/dev-plan-factory.d.ts.map +1 -1
  11. package/dist/dev-plan-factory.js +113 -19
  12. package/dist/dev-plan-factory.js.map +1 -1
  13. package/dist/dev-plan-graph-store.d.ts +79 -1
  14. package/dist/dev-plan-graph-store.d.ts.map +1 -1
  15. package/dist/dev-plan-graph-store.js +420 -3
  16. package/dist/dev-plan-graph-store.js.map +1 -1
  17. package/dist/dev-plan-interface.d.ts +24 -1
  18. package/dist/dev-plan-interface.d.ts.map +1 -1
  19. package/dist/dev-plan-migrate.d.ts +1 -0
  20. package/dist/dev-plan-migrate.d.ts.map +1 -1
  21. package/dist/dev-plan-migrate.js +28 -2
  22. package/dist/dev-plan-migrate.js.map +1 -1
  23. package/dist/index.d.ts +3 -2
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +14 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/mcp-server/index.d.ts +3 -0
  28. package/dist/mcp-server/index.d.ts.map +1 -1
  29. package/dist/mcp-server/index.js +397 -4
  30. package/dist/mcp-server/index.js.map +1 -1
  31. package/dist/types.d.ts +160 -1
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/types.js +9 -1
  34. package/dist/types.js.map +1 -1
  35. package/dist/visualize/graph-canvas/api-compat.d.ts +20 -0
  36. package/dist/visualize/graph-canvas/api-compat.d.ts.map +1 -0
  37. package/dist/visualize/graph-canvas/api-compat.js +344 -0
  38. package/dist/visualize/graph-canvas/api-compat.js.map +1 -0
  39. package/dist/visualize/graph-canvas/clusterer.d.ts +16 -0
  40. package/dist/visualize/graph-canvas/clusterer.d.ts.map +1 -0
  41. package/dist/visualize/graph-canvas/clusterer.js +460 -0
  42. package/dist/visualize/graph-canvas/clusterer.js.map +1 -0
  43. package/dist/visualize/graph-canvas/core.d.ts +11 -0
  44. package/dist/visualize/graph-canvas/core.d.ts.map +1 -0
  45. package/dist/visualize/graph-canvas/core.js +1136 -0
  46. package/dist/visualize/graph-canvas/core.js.map +1 -0
  47. package/dist/visualize/graph-canvas/index.d.ts +22 -0
  48. package/dist/visualize/graph-canvas/index.d.ts.map +1 -0
  49. package/dist/visualize/graph-canvas/index.js +69 -0
  50. package/dist/visualize/graph-canvas/index.js.map +1 -0
  51. package/dist/visualize/graph-canvas/interaction.d.ts +13 -0
  52. package/dist/visualize/graph-canvas/interaction.d.ts.map +1 -0
  53. package/dist/visualize/graph-canvas/interaction.js +457 -0
  54. package/dist/visualize/graph-canvas/interaction.js.map +1 -0
  55. package/dist/visualize/graph-canvas/layout-worker.d.ts +17 -0
  56. package/dist/visualize/graph-canvas/layout-worker.d.ts.map +1 -0
  57. package/dist/visualize/graph-canvas/layout-worker.js +577 -0
  58. package/dist/visualize/graph-canvas/layout-worker.js.map +1 -0
  59. package/dist/visualize/graph-canvas/lod.d.ts +10 -0
  60. package/dist/visualize/graph-canvas/lod.d.ts.map +1 -0
  61. package/dist/visualize/graph-canvas/lod.js +111 -0
  62. package/dist/visualize/graph-canvas/lod.js.map +1 -0
  63. package/dist/visualize/graph-canvas/renderer.d.ts +12 -0
  64. package/dist/visualize/graph-canvas/renderer.d.ts.map +1 -0
  65. package/dist/visualize/graph-canvas/renderer.js +813 -0
  66. package/dist/visualize/graph-canvas/renderer.js.map +1 -0
  67. package/dist/visualize/graph-canvas/spatial-index.d.ts +13 -0
  68. package/dist/visualize/graph-canvas/spatial-index.d.ts.map +1 -0
  69. package/dist/visualize/graph-canvas/spatial-index.js +482 -0
  70. package/dist/visualize/graph-canvas/spatial-index.js.map +1 -0
  71. package/dist/visualize/graph-canvas/styles.d.ts +11 -0
  72. package/dist/visualize/graph-canvas/styles.d.ts.map +1 -0
  73. package/dist/visualize/graph-canvas/styles.js +152 -0
  74. package/dist/visualize/graph-canvas/styles.js.map +1 -0
  75. package/dist/visualize/graph-canvas/viewport.d.ts +17 -0
  76. package/dist/visualize/graph-canvas/viewport.d.ts.map +1 -0
  77. package/dist/visualize/graph-canvas/viewport.js +385 -0
  78. package/dist/visualize/graph-canvas/viewport.js.map +1 -0
  79. package/dist/visualize/server.js +737 -7
  80. package/dist/visualize/server.js.map +1 -1
  81. package/dist/visualize/template-core.d.ts +9 -0
  82. package/dist/visualize/template-core.d.ts.map +1 -0
  83. package/dist/visualize/template-core.js +714 -0
  84. package/dist/visualize/template-core.js.map +1 -0
  85. package/dist/visualize/template-data-loading.d.ts +7 -0
  86. package/dist/visualize/template-data-loading.d.ts.map +1 -0
  87. package/dist/visualize/template-data-loading.js +677 -0
  88. package/dist/visualize/template-data-loading.js.map +1 -0
  89. package/dist/visualize/template-detail-panel.d.ts +14 -0
  90. package/dist/visualize/template-detail-panel.d.ts.map +1 -0
  91. package/dist/visualize/template-detail-panel.js +553 -0
  92. package/dist/visualize/template-detail-panel.js.map +1 -0
  93. package/dist/visualize/template-graph-3d.d.ts +7 -0
  94. package/dist/visualize/template-graph-3d.d.ts.map +1 -0
  95. package/dist/visualize/template-graph-3d.js +1112 -0
  96. package/dist/visualize/template-graph-3d.js.map +1 -0
  97. package/dist/visualize/template-graph-vis.d.ts +8 -0
  98. package/dist/visualize/template-graph-vis.d.ts.map +1 -0
  99. package/dist/visualize/template-graph-vis.js +1204 -0
  100. package/dist/visualize/template-graph-vis.js.map +1 -0
  101. package/dist/visualize/template-html.d.ts +9 -0
  102. package/dist/visualize/template-html.d.ts.map +1 -0
  103. package/dist/visualize/template-html.js +484 -0
  104. package/dist/visualize/template-html.js.map +1 -0
  105. package/dist/visualize/template-pages.d.ts +7 -0
  106. package/dist/visualize/template-pages.d.ts.map +1 -0
  107. package/dist/visualize/template-pages.js +806 -0
  108. package/dist/visualize/template-pages.js.map +1 -0
  109. package/dist/visualize/template-stats-modal.d.ts +7 -0
  110. package/dist/visualize/template-stats-modal.d.ts.map +1 -0
  111. package/dist/visualize/template-stats-modal.js +406 -0
  112. package/dist/visualize/template-stats-modal.js.map +1 -0
  113. package/dist/visualize/template-styles.d.ts +9 -0
  114. package/dist/visualize/template-styles.d.ts.map +1 -0
  115. package/dist/visualize/template-styles.js +487 -0
  116. package/dist/visualize/template-styles.js.map +1 -0
  117. package/dist/visualize/template.d.ts +14 -3
  118. package/dist/visualize/template.d.ts.map +1 -1
  119. package/dist/visualize/template.js +38 -2889
  120. package/dist/visualize/template.js.map +1 -1
  121. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/renderer.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAEH,8CA8xBC;AA9xBD,SAAgB,iBAAiB;IAC/B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4xBR,CAAC;AACF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SpatialIndex — 内联 R-tree 空间索引 (无外部依赖)
3
+ *
4
+ * 轻量级 R-tree 实现,支持:
5
+ * - bulk insert (STR 批量构建)
6
+ * - viewport search (矩形范围查询)
7
+ * - point query (hit-test)
8
+ * - 动态 insert/remove/update
9
+ *
10
+ * 基于简化版 rbush 算法,优化为图谱节点场景。
11
+ */
12
+ export declare function getSpatialIndexScript(): string;
13
+ //# sourceMappingURL=spatial-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial-index.d.ts","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/spatial-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,wBAAgB,qBAAqB,IAAI,MAAM,CAkd9C"}
@@ -0,0 +1,482 @@
1
+ "use strict";
2
+ /**
3
+ * SpatialIndex — 内联 R-tree 空间索引 (无外部依赖)
4
+ *
5
+ * 轻量级 R-tree 实现,支持:
6
+ * - bulk insert (STR 批量构建)
7
+ * - viewport search (矩形范围查询)
8
+ * - point query (hit-test)
9
+ * - 动态 insert/remove/update
10
+ *
11
+ * 基于简化版 rbush 算法,优化为图谱节点场景。
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.getSpatialIndexScript = getSpatialIndexScript;
15
+ function getSpatialIndexScript() {
16
+ return `
17
+ // ============================================================================
18
+ // SpatialIndex — Lightweight R-tree for viewport culling & hit-test
19
+ // ============================================================================
20
+
21
+ /**
22
+ * Minimal R-tree implementation optimized for graph nodes.
23
+ * Supports bulk load, search, point query, insert, remove.
24
+ */
25
+ function SpatialIndex() {
26
+ this._maxEntries = 16; // max children per node
27
+ this._minEntries = 4; // min children per node (for split)
28
+ this._root = this._createNode([]);
29
+ this._nodeIdToItem = {}; // nodeId → leaf item (for O(1) remove/update)
30
+
31
+ // Edge spatial index — separate R-tree for edges
32
+ this._edgeRoot = this._createNode([]);
33
+ this._edgeIdToItem = {}; // edgeId → leaf item
34
+ }
35
+
36
+ // ── Node structure ────────────────────────────────────────────────────────
37
+ SpatialIndex.prototype._createNode = function(children) {
38
+ return {
39
+ children: children,
40
+ height: 1, // 1 = leaf
41
+ leaf: true,
42
+ minX: Infinity,
43
+ minY: Infinity,
44
+ maxX: -Infinity,
45
+ maxY: -Infinity,
46
+ };
47
+ };
48
+
49
+ // ── Build from nodes (bulk load) ──────────────────────────────────────────
50
+
51
+ /**
52
+ * Build the R-tree from all graph nodes.
53
+ * Uses Sort-Tile-Recursive (STR) bulk loading for optimal tree structure.
54
+ * @param {Array} nodes — [{id, x, y, _radius, ...}, ...]
55
+ */
56
+ SpatialIndex.prototype.buildFromNodes = function(nodes) {
57
+ this._nodeIdToItem = {};
58
+ if (!nodes || nodes.length === 0) {
59
+ this._root = this._createNode([]);
60
+ return;
61
+ }
62
+
63
+ // Create leaf items with AABB
64
+ var items = [];
65
+ for (var i = 0; i < nodes.length; i++) {
66
+ var n = nodes[i];
67
+ var r = n._radius || 10;
68
+ var item = {
69
+ minX: n.x - r,
70
+ minY: n.y - r,
71
+ maxX: n.x + r,
72
+ maxY: n.y + r,
73
+ _nodeId: n.id,
74
+ _node: n,
75
+ };
76
+ n._aabb = item; // back-reference
77
+ items.push(item);
78
+ this._nodeIdToItem[n.id] = item;
79
+ }
80
+
81
+ // Build tree using STR bulk loading
82
+ this._root = this._buildSTR(items, 0, items.length - 1, 0);
83
+ };
84
+
85
+ SpatialIndex.prototype._buildSTR = function(items, left, right, level) {
86
+ var N = right - left + 1;
87
+ var M = this._maxEntries;
88
+
89
+ if (N <= M) {
90
+ // Fits in one leaf node
91
+ var node = this._createNode(items.slice(left, right + 1));
92
+ this._calcBBox(node);
93
+ return node;
94
+ }
95
+
96
+ // Sort by X, then divide into vertical slices
97
+ if (level % 2 === 0) {
98
+ items.sort(function(a, b) { return a.minX - b.minX; });
99
+ } else {
100
+ items.sort(function(a, b) { return a.minY - b.minY; });
101
+ }
102
+
103
+ var S = Math.ceil(N / M);
104
+ var children = [];
105
+
106
+ for (var i = left; i <= right; i += S) {
107
+ var end = Math.min(i + S - 1, right);
108
+ if (end - i + 1 <= M) {
109
+ var child = this._createNode(items.slice(i, end + 1));
110
+ this._calcBBox(child);
111
+ children.push(child);
112
+ } else {
113
+ children.push(this._buildSTR(items, i, end, level + 1));
114
+ }
115
+ }
116
+
117
+ var node = this._createNode(children);
118
+ node.leaf = false;
119
+ node.height = children[0].height + 1;
120
+ this._calcBBox(node);
121
+ return node;
122
+ };
123
+
124
+ SpatialIndex.prototype._calcBBox = function(node) {
125
+ var children = node.children;
126
+ node.minX = Infinity;
127
+ node.minY = Infinity;
128
+ node.maxX = -Infinity;
129
+ node.maxY = -Infinity;
130
+ for (var i = 0; i < children.length; i++) {
131
+ var c = children[i];
132
+ if (c.minX < node.minX) node.minX = c.minX;
133
+ if (c.minY < node.minY) node.minY = c.minY;
134
+ if (c.maxX > node.maxX) node.maxX = c.maxX;
135
+ if (c.maxY > node.maxY) node.maxY = c.maxY;
136
+ }
137
+ };
138
+
139
+ // ── Search (viewport query) ──────────────────────────────────────────────
140
+
141
+ /**
142
+ * Find all items intersecting the given AABB.
143
+ * @param {{minX, minY, maxX, maxY}} bbox
144
+ * @returns {Array} array of items with _nodeId and _node references
145
+ */
146
+ SpatialIndex.prototype.search = function(bbox) {
147
+ var result = [];
148
+ this._searchNode(this._root, bbox, result);
149
+ return result;
150
+ };
151
+
152
+ SpatialIndex.prototype._searchNode = function(node, bbox, result) {
153
+ if (!this._intersects(node, bbox)) return;
154
+
155
+ var children = node.children;
156
+ if (node.leaf) {
157
+ for (var i = 0; i < children.length; i++) {
158
+ if (this._intersects(children[i], bbox)) {
159
+ result.push(children[i]);
160
+ }
161
+ }
162
+ } else {
163
+ for (var i = 0; i < children.length; i++) {
164
+ this._searchNode(children[i], bbox, result);
165
+ }
166
+ }
167
+ };
168
+
169
+ SpatialIndex.prototype._intersects = function(a, b) {
170
+ return a.minX <= b.maxX && a.maxX >= b.minX &&
171
+ a.minY <= b.maxY && a.maxY >= b.minY;
172
+ };
173
+
174
+ // ── Point Query (hit-test) ───────────────────────────────────────────────
175
+
176
+ /**
177
+ * Find all items containing the given point.
178
+ * @param {number} x - World X
179
+ * @param {number} y - World Y
180
+ * @returns {Array} items at this point
181
+ */
182
+ SpatialIndex.prototype.pointQuery = function(x, y) {
183
+ var point = { minX: x, minY: y, maxX: x, maxY: y };
184
+ return this.search(point);
185
+ };
186
+
187
+ // ── Dynamic updates ──────────────────────────────────────────────────────
188
+
189
+ /**
190
+ * Update a node's position in the spatial index.
191
+ * @param {Object} node — graph node with .id, .x, .y, ._radius
192
+ */
193
+ SpatialIndex.prototype.updateNode = function(node) {
194
+ var item = this._nodeIdToItem[node.id];
195
+ if (!item) return;
196
+ var r = node._radius || 10;
197
+ item.minX = node.x - r;
198
+ item.minY = node.y - r;
199
+ item.maxX = node.x + r;
200
+ item.maxY = node.y + r;
201
+ node._aabb = item;
202
+ // Note: for optimal performance with frequent updates (e.g., during layout),
203
+ // we defer tree rebalancing. The tree stays valid but suboptimal.
204
+ // Call rebuildFromNodes() when layout stabilizes.
205
+ this._markAncestorsDirty();
206
+ };
207
+
208
+ SpatialIndex.prototype._markAncestorsDirty = function() {
209
+ // Simple approach: recalculate root bbox (propagation optimization deferred)
210
+ this._calcBBoxRecursive(this._root);
211
+ };
212
+
213
+ SpatialIndex.prototype._calcBBoxRecursive = function(node) {
214
+ if (node.leaf) {
215
+ this._calcBBox(node);
216
+ return;
217
+ }
218
+ for (var i = 0; i < node.children.length; i++) {
219
+ this._calcBBoxRecursive(node.children[i]);
220
+ }
221
+ this._calcBBox(node);
222
+ };
223
+
224
+ /**
225
+ * Remove a node from the spatial index.
226
+ */
227
+ SpatialIndex.prototype.removeNode = function(nodeId) {
228
+ var item = this._nodeIdToItem[nodeId];
229
+ if (!item) return;
230
+ this._removeItem(this._root, item);
231
+ delete this._nodeIdToItem[nodeId];
232
+ };
233
+
234
+ SpatialIndex.prototype._removeItem = function(node, item) {
235
+ if (node.leaf) {
236
+ var idx = node.children.indexOf(item);
237
+ if (idx >= 0) {
238
+ node.children.splice(idx, 1);
239
+ this._calcBBox(node);
240
+ return true;
241
+ }
242
+ return false;
243
+ }
244
+ for (var i = 0; i < node.children.length; i++) {
245
+ if (this._intersects(node.children[i], item)) {
246
+ if (this._removeItem(node.children[i], item)) {
247
+ if (node.children[i].children.length === 0) {
248
+ node.children.splice(i, 1);
249
+ }
250
+ this._calcBBox(node);
251
+ return true;
252
+ }
253
+ }
254
+ }
255
+ return false;
256
+ };
257
+
258
+ /**
259
+ * Rebuild the tree (call after many updates/removes for optimal performance).
260
+ */
261
+ SpatialIndex.prototype.rebuild = function(nodes) {
262
+ this.buildFromNodes(nodes);
263
+ };
264
+
265
+ /**
266
+ * Get the total number of items in the index.
267
+ */
268
+ SpatialIndex.prototype.size = function() {
269
+ return Object.keys(this._nodeIdToItem).length;
270
+ };
271
+
272
+ // ============================================================================
273
+ // Edge Spatial Index — R-tree for edges (AABB = bounding box of from→to)
274
+ // ============================================================================
275
+
276
+ /**
277
+ * Build the edge R-tree from all edges.
278
+ * Edge AABB = bounding box of (fromNode, toNode) positions.
279
+ * @param {Array} edges — [{id, from, to, ...}, ...]
280
+ * @param {Object} nodeMap — { nodeId → node }
281
+ */
282
+ SpatialIndex.prototype.buildEdgeIndex = function(edges, nodeMap) {
283
+ this._edgeIdToItem = {};
284
+ if (!edges || edges.length === 0) {
285
+ this._edgeRoot = this._createNode([]);
286
+ return;
287
+ }
288
+
289
+ var items = [];
290
+ for (var i = 0; i < edges.length; i++) {
291
+ var e = edges[i];
292
+ var fromNode = nodeMap[e.from];
293
+ var toNode = nodeMap[e.to];
294
+ if (!fromNode || !toNode) continue;
295
+
296
+ var item = this._calcEdgeAABB(e, fromNode, toNode);
297
+ items.push(item);
298
+ this._edgeIdToItem[e.id] = item;
299
+ }
300
+
301
+ if (items.length === 0) {
302
+ this._edgeRoot = this._createNode([]);
303
+ return;
304
+ }
305
+
306
+ this._edgeRoot = this._buildSTR(items, 0, items.length - 1, 0);
307
+ };
308
+
309
+ /**
310
+ * Calculate AABB for an edge based on its endpoint node positions.
311
+ */
312
+ SpatialIndex.prototype._calcEdgeAABB = function(edge, fromNode, toNode) {
313
+ var pad = 2; // small padding for line width
314
+ var minX = Math.min(fromNode.x, toNode.x) - pad;
315
+ var minY = Math.min(fromNode.y, toNode.y) - pad;
316
+ var maxX = Math.max(fromNode.x, toNode.x) + pad;
317
+ var maxY = Math.max(fromNode.y, toNode.y) + pad;
318
+ return {
319
+ minX: minX,
320
+ minY: minY,
321
+ maxX: maxX,
322
+ maxY: maxY,
323
+ _edgeId: edge.id,
324
+ _edge: edge,
325
+ };
326
+ };
327
+
328
+ /**
329
+ * Search for edges whose AABB intersects the given bounding box.
330
+ * @param {{minX, minY, maxX, maxY}} bbox
331
+ * @returns {Array} items with _edgeId and _edge references
332
+ */
333
+ SpatialIndex.prototype.searchEdges = function(bbox) {
334
+ var result = [];
335
+ this._searchNode(this._edgeRoot, bbox, result);
336
+ return result;
337
+ };
338
+
339
+ /**
340
+ * Update edge AABBs when a node moves.
341
+ * @param {string} nodeId — the node that moved
342
+ * @param {Object} nodeEdges — { nodeId → [edge, ...] } adjacency list
343
+ * @param {Object} nodeMap — { nodeId → node }
344
+ */
345
+ SpatialIndex.prototype.updateEdgesForNode = function(nodeId, nodeEdges, nodeMap) {
346
+ var edges = nodeEdges[nodeId] || [];
347
+ for (var i = 0; i < edges.length; i++) {
348
+ var e = edges[i];
349
+ var item = this._edgeIdToItem[e.id];
350
+ if (!item) continue;
351
+ var fromNode = nodeMap[e.from];
352
+ var toNode = nodeMap[e.to];
353
+ if (!fromNode || !toNode) continue;
354
+ var pad = 2;
355
+ item.minX = Math.min(fromNode.x, toNode.x) - pad;
356
+ item.minY = Math.min(fromNode.y, toNode.y) - pad;
357
+ item.maxX = Math.max(fromNode.x, toNode.x) + pad;
358
+ item.maxY = Math.max(fromNode.y, toNode.y) + pad;
359
+ }
360
+ // Propagate changes up (simple approach)
361
+ this._calcBBoxRecursive(this._edgeRoot);
362
+ };
363
+
364
+ /**
365
+ * Get the number of edges in the edge index.
366
+ */
367
+ SpatialIndex.prototype.edgeSize = function() {
368
+ return Object.keys(this._edgeIdToItem).length;
369
+ };
370
+
371
+ // ============================================================================
372
+ // Incremental Insert (Phase-8C) — add single items without full rebuild
373
+ // ============================================================================
374
+
375
+ /**
376
+ * Insert a single node into the R-tree incrementally.
377
+ * Uses simple insertion into the best-fit leaf.
378
+ * @param {Object} node — graph node with .id, .x, .y, ._radius
379
+ */
380
+ SpatialIndex.prototype.insertNode = function(node) {
381
+ var r = node._radius || 10;
382
+ var item = {
383
+ minX: node.x - r,
384
+ minY: node.y - r,
385
+ maxX: node.x + r,
386
+ maxY: node.y + r,
387
+ _nodeId: node.id,
388
+ _node: node,
389
+ };
390
+ node._aabb = item;
391
+ this._nodeIdToItem[node.id] = item;
392
+ this._insertItem(this._root, item);
393
+ };
394
+
395
+ /**
396
+ * Insert a single edge into the edge R-tree incrementally.
397
+ * @param {Object} edge — graph edge
398
+ * @param {Object} fromNode — source node
399
+ * @param {Object} toNode — target node
400
+ */
401
+ SpatialIndex.prototype.insertEdge = function(edge, fromNode, toNode) {
402
+ var item = this._calcEdgeAABB(edge, fromNode, toNode);
403
+ this._edgeIdToItem[edge.id] = item;
404
+ this._insertItem(this._edgeRoot, item);
405
+ };
406
+
407
+ /**
408
+ * Insert an item into an R-tree node (simple greedy insert).
409
+ * Finds the leaf with minimum area enlargement and adds the item.
410
+ */
411
+ SpatialIndex.prototype._insertItem = function(root, item) {
412
+ var node = root;
413
+
414
+ // Traverse to find best leaf
415
+ while (!node.leaf) {
416
+ var bestChild = null;
417
+ var bestEnlargement = Infinity;
418
+ var bestArea = Infinity;
419
+
420
+ for (var i = 0; i < node.children.length; i++) {
421
+ var child = node.children[i];
422
+ var area = this._area(child);
423
+ var enlargement = this._enlargedArea(child, item) - area;
424
+
425
+ if (enlargement < bestEnlargement || (enlargement === bestEnlargement && area < bestArea)) {
426
+ bestEnlargement = enlargement;
427
+ bestArea = area;
428
+ bestChild = child;
429
+ }
430
+ }
431
+ node = bestChild;
432
+ }
433
+
434
+ // Add to leaf
435
+ node.children.push(item);
436
+
437
+ // Split if needed
438
+ if (node.children.length > this._maxEntries) {
439
+ this._splitNode(node);
440
+ }
441
+
442
+ // Update bounding boxes up the tree
443
+ this._calcBBoxRecursive(root);
444
+ };
445
+
446
+ SpatialIndex.prototype._area = function(node) {
447
+ return (node.maxX - node.minX) * (node.maxY - node.minY);
448
+ };
449
+
450
+ SpatialIndex.prototype._enlargedArea = function(node, item) {
451
+ var minX = Math.min(node.minX, item.minX);
452
+ var minY = Math.min(node.minY, item.minY);
453
+ var maxX = Math.max(node.maxX, item.maxX);
454
+ var maxY = Math.max(node.maxY, item.maxY);
455
+ return (maxX - minX) * (maxY - minY);
456
+ };
457
+
458
+ /**
459
+ * Split an overfull leaf into two halves (simple median split).
460
+ */
461
+ SpatialIndex.prototype._splitNode = function(node) {
462
+ var items = node.children;
463
+ // Sort by center X
464
+ items.sort(function(a, b) {
465
+ return (a.minX + a.maxX) - (b.minX + b.maxX);
466
+ });
467
+ var mid = Math.ceil(items.length / 2);
468
+ node.children = items.slice(0, mid);
469
+ this._calcBBox(node);
470
+ // The remaining items need to go into a sibling —
471
+ // for simplicity, just keep them in the same node but in a new child
472
+ // This is a simplified split; full R-tree split would restructure parent
473
+ // For incremental adds, this is sufficient; periodic rebuild() restores optimal structure
474
+ var overflow = items.slice(mid);
475
+ for (var i = 0; i < overflow.length; i++) {
476
+ node.children.push(overflow[i]);
477
+ }
478
+ this._calcBBox(node);
479
+ };
480
+ `;
481
+ }
482
+ //# sourceMappingURL=spatial-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spatial-index.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/spatial-index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAEH,sDAkdC;AAldD,SAAgB,qBAAqB;IACnC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgdR,CAAC;AACF,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * StyleManager — DevPlan 节点/边样式系统
3
+ *
4
+ * 迁移自 vis-network 的样式规则:
5
+ * - 5 种节点类型样式 (project/module/main-task/sub-task/document)
6
+ * - 4 种状态颜色 (completed/in_progress/pending/cancelled)
7
+ * - 动态大小规则 (基于度数 sqrt 曲线)
8
+ * - 6 种边类型样式
9
+ */
10
+ export declare function getStylesScript(): string;
11
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,eAAe,IAAI,MAAM,CA0IxC"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * StyleManager — DevPlan 节点/边样式系统
4
+ *
5
+ * 迁移自 vis-network 的样式规则:
6
+ * - 5 种节点类型样式 (project/module/main-task/sub-task/document)
7
+ * - 4 种状态颜色 (completed/in_progress/pending/cancelled)
8
+ * - 动态大小规则 (基于度数 sqrt 曲线)
9
+ * - 6 种边类型样式
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getStylesScript = getStylesScript;
13
+ function getStylesScript() {
14
+ return `
15
+ // ============================================================================
16
+ // StyleManager — Node & Edge Styles
17
+ // ============================================================================
18
+
19
+ function StyleManager() {
20
+ // 从统一配置加载颜色 (如果 getUnifiedNodeStyle 可用)
21
+ var _uni = (typeof getUnifiedNodeStyle === 'function') ? getUnifiedNodeStyle() : null;
22
+
23
+ // Status colors
24
+ this.STATUS_COLORS = _uni ? _uni.statusGeneric : {
25
+ completed: { bg: '#059669', border: '#047857', font: '#d1fae5' },
26
+ in_progress: { bg: '#7c3aed', border: '#6d28d9', font: '#ddd6fe' },
27
+ pending: { bg: '#4b5563', border: '#374151', font: '#d1d5db' },
28
+ cancelled: { bg: '#92400e', border: '#78350f', font: '#fde68a' },
29
+ };
30
+
31
+ // 统一样式缓存 (供 getNodeStyle 使用)
32
+ this._uniStyle = _uni;
33
+
34
+ // Node sizing rules by type
35
+ this.NODE_SIZE_RULES = {
36
+ 'project': { min: 35, max: 65, baseFont: 16, maxFont: 22, scale: 3.5 },
37
+ 'module': { min: 20, max: 45, baseFont: 12, maxFont: 16, scale: 2.8 },
38
+ 'main-task': { min: 14, max: 38, baseFont: 11, maxFont: 15, scale: 2.2 },
39
+ 'sub-task': { min: 7, max: 18, baseFont: 8, maxFont: 11, scale: 1.5 },
40
+ 'document': { min: 12, max: 30, baseFont: 9, maxFont: 13, scale: 1.8 },
41
+ };
42
+
43
+ // Node type shapes
44
+ this.NODE_SHAPES = {
45
+ 'project': 'star',
46
+ 'module': 'diamond',
47
+ 'main-task': 'circle',
48
+ 'sub-task': 'circle',
49
+ 'document': 'box',
50
+ };
51
+
52
+ // Node type colors (for non-status-based types) — 从统一配置读取
53
+ this.NODE_COLORS = _uni ? {
54
+ 'project': _uni.project,
55
+ 'module': _uni.module,
56
+ 'document': _uni.document,
57
+ } : {
58
+ 'project': { bg: '#f59e0b', border: '#d97706', font: '#fff' },
59
+ 'module': { bg: '#ff6600', border: '#cc5200', font: '#fff3e0' },
60
+ 'document': { bg: '#2563eb', border: '#1d4ed8', font: '#dbeafe' },
61
+ };
62
+
63
+ // Edge styles by label
64
+ this.EDGE_STYLES = {
65
+ 'has_main_task': { width: 2, color: '#4b5563', highlightColor: '#93c5fd', dashes: null, arrows: true },
66
+ 'has_sub_task': { width: 1, color: '#4b5563', highlightColor: '#818cf8', dashes: null, arrows: true },
67
+ 'has_document': { width: 1, color: '#4b5563', highlightColor: '#60a5fa', dashes: [5, 5], arrows: true },
68
+ 'module_has_task':{ width: 1.5, color: '#4b5563', highlightColor: '#ff8533', dashes: [2, 4], arrows: true },
69
+ 'task_has_doc': { width: 1.5, color: '#4b5563', highlightColor: '#f59e0b', dashes: [4, 3], arrows: true },
70
+ 'doc_has_child': { width: 1.5, color: '#4b5563', highlightColor: '#c084fc', dashes: [6, 3], arrows: true },
71
+ };
72
+
73
+ this.EDGE_DEFAULT = { width: 1, color: '#4b5563', highlightColor: '#9ca3af', dashes: null, arrows: false };
74
+ }
75
+
76
+ /**
77
+ * Compute node size and font size based on type and degree.
78
+ */
79
+ StyleManager.prototype._calcNodeSize = function(type, degree) {
80
+ var rule = this.NODE_SIZE_RULES[type] || { min: 10, max: 22, baseFont: 10, maxFont: 13, scale: 1.0 };
81
+ var size = rule.min + rule.scale * Math.sqrt(degree || 0);
82
+ size = Math.max(rule.min, Math.min(size, rule.max));
83
+ var sizeRatio = (size - rule.min) / (rule.max - rule.min || 1);
84
+ var fontSize = Math.round(rule.baseFont + sizeRatio * (rule.maxFont - rule.baseFont));
85
+ return { size: Math.round(size), fontSize: fontSize };
86
+ };
87
+
88
+ /**
89
+ * Get style for a node.
90
+ * @param {Object} node
91
+ * @returns {Object} { shape, radius, bgColor, borderColor, borderWidth, fontColor, fontSize }
92
+ */
93
+ StyleManager.prototype.getNodeStyle = function(node) {
94
+ var type = node.type || 'default';
95
+ var props = node.properties || {};
96
+ var status = props.status || 'pending';
97
+ var degree = node.degree || 0;
98
+
99
+ var ns = this._calcNodeSize(type, degree);
100
+ var shape = this.NODE_SHAPES[type] || 'circle';
101
+
102
+ // Determine colors — 从统一配置读取
103
+ var colors;
104
+ if (type === 'project' || type === 'module' || type === 'document') {
105
+ colors = this.NODE_COLORS[type] || this.STATUS_COLORS.pending;
106
+ } else if (type === 'main-task') {
107
+ // 主任务: 从统一配置读取状态颜色
108
+ var _mt = this._uniStyle ? this._uniStyle.mainTask : null;
109
+ colors = (_mt && _mt[status]) || (_mt && _mt.pending) || this.STATUS_COLORS[status] || this.STATUS_COLORS.pending;
110
+ } else {
111
+ // 子任务: 从统一配置读取状态颜色 (completed=亮绿色)
112
+ var _st = this._uniStyle ? this._uniStyle.subTask : null;
113
+ colors = (_st && _st[status]) || (_st && _st.pending) || this.STATUS_COLORS[status] || this.STATUS_COLORS.pending;
114
+ }
115
+
116
+ return {
117
+ shape: shape,
118
+ radius: ns.size,
119
+ bgColor: colors.bg,
120
+ borderColor: colors.border,
121
+ borderWidth: type === 'project' ? 3 : (type === 'sub-task' ? 1 : 2),
122
+ fontColor: colors.font,
123
+ fontSize: ns.fontSize,
124
+ };
125
+ };
126
+
127
+ /**
128
+ * Get style for an edge.
129
+ * @param {Object} edge
130
+ * @returns {Object} { width, color, highlightColor, dashes, arrows }
131
+ */
132
+ StyleManager.prototype.getEdgeStyle = function(edge) {
133
+ var label = edge.label || edge._label || '';
134
+ return this.EDGE_STYLES[label] || this.EDGE_DEFAULT;
135
+ };
136
+
137
+ /**
138
+ * Apply styles to all nodes and edges (batch).
139
+ */
140
+ StyleManager.prototype.applyAllStyles = function(nodes, edges) {
141
+ for (var i = 0; i < nodes.length; i++) {
142
+ var style = this.getNodeStyle(nodes[i]);
143
+ nodes[i]._style = style;
144
+ nodes[i]._radius = style.radius;
145
+ }
146
+ for (var i = 0; i < edges.length; i++) {
147
+ edges[i]._style = this.getEdgeStyle(edges[i]);
148
+ }
149
+ };
150
+ `;
151
+ }
152
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/visualize/graph-canvas/styles.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAEH,0CA0IC;AA1ID,SAAgB,eAAe;IAC7B,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIR,CAAC;AACF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ViewportManager — 平移/缩放/手势 + 世界↔屏幕坐标变换
3
+ *
4
+ * 管理 2D 视口变换矩阵:
5
+ * screenX = worldX * scale + offsetX
6
+ * screenY = worldY * scale + offsetY
7
+ *
8
+ * 支持:
9
+ * - 鼠标拖拽平移
10
+ * - 滚轮缩放 (以鼠标位置为中心)
11
+ * - 触摸双指缩放
12
+ * - fit() 自适应视口
13
+ * - zoomTo() 定位到特定坐标
14
+ * - 惯性平移 (inertia)
15
+ */
16
+ export declare function getViewportScript(): string;
17
+ //# sourceMappingURL=viewport.d.ts.map