@graphty/graphty-element 2.6.2 → 3.0.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.
Files changed (163) hide show
  1. package/dist/ai.js +3 -3
  2. package/dist/catalog.js +53 -54
  3. package/dist/chunks/{AiManager-4iQpsJW1.js → AiManager-Bhh0rR_p.js} +706 -655
  4. package/dist/chunks/GraphSession-DPoTaT3b.js +21175 -0
  5. package/dist/chunks/{GraphtyLogger-B_O67a6c.js → GraphtyLogger-BtcBJQPL.js} +1 -1
  6. package/dist/chunks/{VoiceInputAdapter-Cc6mHXTI.js → VoiceInputAdapter-CdLsJ_nG.js} +1 -1
  7. package/dist/chunks/{XRPivotCameraController-BLa89LXn.js → XRPivotCameraController-CiLJ9Gz6.js} +2 -2
  8. package/dist/chunks/algorithms-qij74zEN.js +6811 -0
  9. package/dist/chunks/{capability-check-Am2zliFj.js → capability-check-BbgTejS3.js} +1 -1
  10. package/dist/chunks/definePalette-BYt2Llxs.js +1333 -0
  11. package/dist/chunks/fields-5uVC1Pll.js +4999 -0
  12. package/dist/chunks/{format-detection-BHwrAVzW.js → format-detection-FKaDMshR.js} +1 -1
  13. package/dist/chunks/{index-BkBLbvui.js → index-Cc_6D9hV.js} +6034 -7127
  14. package/dist/chunks/interpolation-Dk206AhZ.js +105 -0
  15. package/dist/chunks/paletteRegistry-De3CGdst.js +357 -0
  16. package/dist/chunks/parse-SVp77JbE.js +669 -0
  17. package/dist/chunks/{pluginRegistry-Bs8bEkz9.js → pluginRegistry-Ddfl6Mv2.js} +27 -24
  18. package/dist/chunks/{registry-BdGvyZou.js → registry-CgMqldp4.js} +1 -1
  19. package/dist/chunks/{DataSource-BL2UzPff.js → sources-BbAJCDIH.js} +279 -108
  20. package/dist/commands.d.ts +128 -19
  21. package/dist/commands.js +49 -1
  22. package/dist/custom-elements.json +1 -1
  23. package/dist/extend.d.ts +10 -2
  24. package/dist/extend.js +64 -57
  25. package/dist/graphty-catalog.json +6 -3
  26. package/dist/graphty.bundle.js +267177 -240648
  27. package/dist/graphty.js +84 -78
  28. package/dist/index.d.ts +4 -0
  29. package/dist/logging.js +2 -2
  30. package/dist/schema.js +70 -71
  31. package/dist/session.d.ts +5 -6
  32. package/dist/session.js +40 -86
  33. package/dist/src/Edge.d.ts +31 -67
  34. package/dist/src/Graph.d.ts +335 -77
  35. package/dist/src/Node.d.ts +36 -3
  36. package/dist/src/NodeBehavior.d.ts +28 -0
  37. package/dist/src/Styles.d.ts +15 -4
  38. package/dist/src/acceleration/AccelerationController.d.ts +8 -0
  39. package/dist/src/acceleration/narrow.d.ts +9 -1
  40. package/dist/src/acceleration/types.d.ts +10 -0
  41. package/dist/src/ai/AiController.d.ts +12 -0
  42. package/dist/src/ai/AiManager.d.ts +7 -0
  43. package/dist/src/ai/commands/AlgorithmCommands.d.ts +1 -1
  44. package/dist/src/ai/commands/LayoutCommands.d.ts +1 -1
  45. package/dist/src/ai/commands/StyleCommands.d.ts +1 -1
  46. package/dist/src/ai/commands/types.d.ts +20 -1
  47. package/dist/src/algorithms/Algorithm.d.ts +21 -4
  48. package/dist/src/algorithms/BFSAlgorithm.d.ts +0 -9
  49. package/dist/src/algorithms/BellmanFordAlgorithm.d.ts +0 -14
  50. package/dist/src/algorithms/DFSAlgorithm.d.ts +1 -1
  51. package/dist/src/algorithms/FloydWarshallAlgorithm.d.ts +5 -0
  52. package/dist/src/algorithms/GirvanNewmanAlgorithm.d.ts +5 -0
  53. package/dist/src/algorithms/LeidenAlgorithm.d.ts +5 -0
  54. package/dist/src/algorithms/PageRankAlgorithm.d.ts +1 -1
  55. package/dist/src/algorithms/StronglyConnectedComponentsAlgorithm.d.ts +1 -1
  56. package/dist/src/algorithms/metrics/fields.d.ts +23 -1
  57. package/dist/src/algorithms/utils/graphUtils.d.ts +13 -1
  58. package/dist/src/catalog/paletteRegistry.d.ts +4 -4
  59. package/dist/src/catalog/registry.d.ts +3 -2
  60. package/dist/src/catalog/types.d.ts +18 -1
  61. package/dist/src/config/GraphStyle.d.ts +1 -1
  62. package/dist/src/config/StyleTemplate.d.ts +2 -2
  63. package/dist/src/config/xr-config-schema.d.ts +4 -4
  64. package/dist/src/data/CSVDataSource.d.ts +77 -22
  65. package/dist/src/data/ErrorAggregator.d.ts +5 -0
  66. package/dist/src/data/GEXFDataSource.d.ts +12 -61
  67. package/dist/src/data/GraphMLDataSource.d.ts +3 -44
  68. package/dist/src/data/GraphStore.d.ts +322 -15
  69. package/dist/src/data/JsonDataSource.d.ts +43 -1
  70. package/dist/src/data/graph-io-import.d.ts +89 -0
  71. package/dist/src/data/graph-io-records.d.ts +64 -0
  72. package/dist/src/data/lane.d.ts +23 -0
  73. package/dist/src/data/positions.d.ts +13 -0
  74. package/dist/src/data/seedPosition.d.ts +16 -0
  75. package/dist/src/errors/GraphtyError.d.ts +3 -1
  76. package/dist/src/errors/codes.d.ts +23 -0
  77. package/dist/src/events.d.ts +12 -0
  78. package/dist/src/graphty-element.d.ts +149 -54
  79. package/dist/src/input/types.d.ts +2 -0
  80. package/dist/src/layout/D3GraphLayoutEngine.d.ts +17 -3
  81. package/dist/src/layout/FixedLayoutEngine.d.ts +20 -4
  82. package/dist/src/layout/KamadaKawaiLayoutEngine.d.ts +6 -0
  83. package/dist/src/layout/LayoutEngine.d.ts +214 -116
  84. package/dist/src/layout/NGraphLayoutEngine.d.ts +10 -3
  85. package/dist/src/layout/SimulationLayoutEngine.d.ts +8 -3
  86. package/dist/src/managers/AlgorithmManager.d.ts +24 -5
  87. package/dist/src/managers/DataManager.d.ts +258 -181
  88. package/dist/src/managers/EventManager.d.ts +5 -2
  89. package/dist/src/managers/GraphContext.d.ts +7 -0
  90. package/dist/src/managers/InputManager.d.ts +11 -0
  91. package/dist/src/managers/LayoutManager.d.ts +129 -50
  92. package/dist/src/managers/RenderManager.d.ts +14 -1
  93. package/dist/src/managers/UpdateManager.d.ts +20 -0
  94. package/dist/src/screenshot/ScreenshotCapture.d.ts +1 -1
  95. package/dist/src/session/GraphSession.d.ts +83 -6
  96. package/dist/src/session/commands/algo.d.ts +169 -0
  97. package/dist/src/session/commands/config.d.ts +45 -0
  98. package/dist/src/session/commands/data.d.ts +178 -0
  99. package/dist/src/session/commands/doors.d.ts +93 -0
  100. package/dist/src/session/commands/index.d.ts +20 -0
  101. package/dist/src/session/commands/layout.d.ts +104 -0
  102. package/dist/src/session/commands/positions.d.ts +30 -0
  103. package/dist/src/session/commands/sets.d.ts +113 -0
  104. package/dist/src/session/commands/style.d.ts +92 -0
  105. package/dist/src/session/commands/view.d.ts +57 -0
  106. package/dist/src/session/commands/visibility.d.ts +41 -0
  107. package/dist/src/session/data.d.ts +131 -4
  108. package/dist/src/session/index.d.ts +1 -1
  109. package/dist/src/session/planning.d.ts +25 -8
  110. package/dist/src/session/project/Dispatcher.d.ts +905 -0
  111. package/dist/src/session/project/History.d.ts +382 -0
  112. package/dist/src/session/project/arrangement.d.ts +247 -0
  113. package/dist/src/session/project/derive.d.ts +132 -0
  114. package/dist/src/session/project/digest.d.ts +33 -0
  115. package/dist/src/session/project/draft.d.ts +194 -0
  116. package/dist/src/session/project/graphOps.d.ts +304 -0
  117. package/dist/src/session/project/ingest.d.ts +364 -0
  118. package/dist/src/session/project/state.d.ts +145 -0
  119. package/dist/src/session/project/strict.d.ts +68 -0
  120. package/dist/src/session/results/RunResult.d.ts +48 -0
  121. package/dist/src/session/results/statistics.d.ts +20 -0
  122. package/dist/src/session/runs/Run.d.ts +80 -4
  123. package/dist/src/session/runs/RunsApi.d.ts +23 -6
  124. package/dist/src/session/runs/types.d.ts +25 -6
  125. package/dist/src/session/scope/ElementMask.d.ts +14 -0
  126. package/dist/src/session/scope/ScopeApi.d.ts +3 -22
  127. package/dist/src/session/scope/spaces.d.ts +29 -0
  128. package/dist/src/session/sealed.d.ts +22 -0
  129. package/dist/src/session/selection/SelectionApi.d.ts +14 -4
  130. package/dist/src/session/sets/SetsApi.d.ts +13 -5
  131. package/dist/src/session/sets/store.d.ts +54 -53
  132. package/dist/src/session/sets/types.d.ts +5 -2
  133. package/dist/src/session/styles/Layer.d.ts +5 -0
  134. package/dist/src/session/styles/StylesApi.d.ts +68 -17
  135. package/dist/src/session/styles/autoApply.d.ts +64 -53
  136. package/dist/src/session/styles/index.d.ts +3 -3
  137. package/dist/src/session/styles/predicate.d.ts +7 -0
  138. package/dist/src/session/styles/repaint.d.ts +16 -1
  139. package/dist/src/session/styles/sources.d.ts +1 -1
  140. package/dist/src/session/types.d.ts +625 -54
  141. package/dist/src/session/visibility/VisibilityApi.d.ts +38 -18
  142. package/dist/src/session/visibility/filter.d.ts +10 -0
  143. package/dist/src/simple/defineAlgorithm.d.ts +28 -0
  144. package/dist/src/simple/defineLayout.d.ts +35 -0
  145. package/dist/src/simple/defineLogDestination.d.ts +31 -0
  146. package/dist/src/simple/definePalette.d.ts +26 -0
  147. package/dist/src/simple/definition.d.ts +106 -0
  148. package/dist/src/simple/options.d.ts +33 -0
  149. package/dist/src/simple/source.d.ts +49 -0
  150. package/dist/src/simple/types.d.ts +366 -0
  151. package/dist/src/simple/view.d.ts +107 -0
  152. package/dist/webgpu.js +2 -2
  153. package/package.json +10 -12
  154. package/dist/chunks/GraphSession-BhuHSXIo.js +0 -12819
  155. package/dist/chunks/GraphStyle-Cwr55SAE.js +0 -65
  156. package/dist/chunks/algorithms-BJ6DQMOe.js +0 -3777
  157. package/dist/chunks/detect-fyuVnlCT.js +0 -88
  158. package/dist/chunks/interpolation-DY-PNpqX.js +0 -43
  159. package/dist/chunks/optionsFromZod-CKMYSwTz.js +0 -3636
  160. package/dist/chunks/paletteRegistry-BCFSwJGK.js +0 -1196
  161. package/dist/chunks/parse-BMTqt4SS.js +0 -3658
  162. package/dist/src/data/csv-variant-detection.d.ts +0 -29
  163. package/dist/src/data/ingest.d.ts +0 -104
@@ -1,8 +1,14 @@
1
- import { type ColumnHandle, type DerivedGraph, type FreezeReport, GraphBuilder, type GraphSnapshot, type U32 } from "@graphty/graph-format";
1
+ import { type ColumnHandle, type DerivedGraph, type FreezeReport, GraphBuilder, type GraphSnapshot, type NodeId, type U32 } from "@graphty/graph-format";
2
2
  import { type InputCounters } from "../session/attributes";
3
3
  import type { DirectionProvenance } from "../session/types";
4
4
  import { type EdgeCounter } from "./edgeIdentity";
5
5
  import { ElementPositions } from "./positions";
6
+ /** An edge's stable-identity cells: its hash lanes, its ordinal and its pair's count. */
7
+ export interface EdgeIdentityCells {
8
+ readonly hash: readonly [number, number];
9
+ readonly ordinal: number;
10
+ readonly among: number;
11
+ }
6
12
  /** The payload of `snapshot-replaced` (graph-format design 14.4 rule 11). */
7
13
  export interface SnapshotReplacement {
8
14
  /** The snapshot this one supersedes; null on the first freeze. */
@@ -13,8 +19,12 @@ export interface SnapshotReplacement {
13
19
  readonly report: FreezeReport;
14
20
  }
15
21
  export interface GraphStoreOptions {
16
- /** config.data.directed. "auto" leaves the builder unlocked (14.4 rule 1). */
17
- readonly directed: boolean | "auto";
22
+ /**
23
+ * config.data.directed. "auto" leaves the builder unlocked (14.4 rule 1). Given as a thunk it
24
+ * is read again whenever the graph is emptied, so a cleared graph takes the setting in force
25
+ * then, as a freshly built store would.
26
+ */
27
+ readonly directed: boolean | "auto" | (() => boolean | "auto");
18
28
  /**
19
29
  * config.data.knownFields.positionScale: record units -> scene units, read THROUGH A THUNK on
20
30
  * every seeding pass rather than captured once.
@@ -44,6 +54,44 @@ export interface GraphStoreOptions {
44
54
  */
45
55
  readonly inputs?: InputCounters;
46
56
  }
57
+ /** Every registered builder column's value in one row, by column name; unset cells are absent. */
58
+ type RowValues = ReadonlyMap<string, unknown>;
59
+ /** A node row a removal took out, with what putting it back needs. */
60
+ interface RemovedNode {
61
+ /** Its id. */
62
+ readonly id: NodeId;
63
+ /** Its row in the graph it was removed from. */
64
+ readonly index: number;
65
+ /** Its value in every registered column: the seed coordinate, and any column added later. */
66
+ readonly values: RowValues;
67
+ }
68
+ /** An edge row a removal took out: resolved endpoints and weight, never re-read through ingest. */
69
+ interface RemovedEdge {
70
+ /** The element-assigned id. */
71
+ readonly edgeId: number;
72
+ /** Its row in the graph it was removed from. */
73
+ readonly index: number;
74
+ /** The source id. */
75
+ readonly source: NodeId;
76
+ /** The target id. */
77
+ readonly target: NodeId;
78
+ /** The weight. */
79
+ readonly weight: number;
80
+ /** Its value in every registered column except the edge id. */
81
+ readonly values: RowValues;
82
+ }
83
+ /** The rows one removal took out, each list in ascending row order. */
84
+ export interface RemovedRows {
85
+ readonly nodes: readonly RemovedNode[];
86
+ readonly edges: readonly RemovedEdge[];
87
+ }
88
+ /** A whole graph a replace set aside, for its undo. */
89
+ export interface KeptGraph {
90
+ /** The graph, frozen fresh so it still carries every builder column and no positions lane. */
91
+ readonly snapshot: GraphSnapshot;
92
+ /** How its direction had been settled. */
93
+ readonly direction: DirectionProvenance;
94
+ }
47
95
  /**
48
96
  * The element's ONE graph-format builder and the snapshot it freezes to (graph-format design 14.4).
49
97
  *
@@ -66,20 +114,28 @@ export interface GraphStoreOptions {
66
114
  * render loop reads every frame, and the symptom is a blank canvas with nothing in the console.
67
115
  */
68
116
  export declare class GraphStore {
69
- /** The one builder, alive for the whole life of the Graph. */
70
- readonly builder: GraphBuilder;
71
117
  /** The element-owned node coordinates, lent to every snapshot. */
72
118
  readonly positions: ElementPositions;
73
- /** Handle of the importer seed column; `setNodeValue(seedColumn, i, [x, y, z])` seeds a node. */
74
- readonly seedColumn: ColumnHandle;
75
- /** Handle of the element-assigned edge counter column. */
76
- readonly edgeIdColumn: ColumnHandle;
77
119
  private readonly options;
120
+ /** The builder now. Replaced only by a rebuild; see {@link GraphStore.builder}. */
121
+ private current;
122
+ private seedHandle;
123
+ private edgeIdHandle;
124
+ /** Structural changes waiting to be applied, already folded to their net effect. */
125
+ private structural;
126
+ /** Every column of the last freeze, taken before the positions lane replaced the seed column. */
127
+ private frozenColumns;
128
+ private rebuilds;
129
+ /**
130
+ * Strict: the resident snapshot last sealed. Each dispatch checks its arrays; a snapshot no
131
+ * longer resident is checked by the sweep after each test.
132
+ */
133
+ sealedResident: GraphSnapshot | null;
78
134
  private readonly counter;
79
- private readonly nodeHashColumn;
80
- private readonly edgeHashColumn;
81
- private readonly edgeOrdinalColumn;
82
- private readonly edgeAmongColumn;
135
+ private nodeHashColumn;
136
+ private edgeHashColumn;
137
+ private edgeOrdinalColumn;
138
+ private edgeAmongColumn;
83
139
  /** Node rows below this have their hash; rows from here to `nodeBound` are new. */
84
140
  private nodeMark;
85
141
  /** Edges ingested outside a load and not yet completed: row, counter, file id. */
@@ -93,21 +149,81 @@ export declare class GraphStore {
93
149
  private loadDepth;
94
150
  /** Whether edge pairs are ordered, latched when the first edge is completed. */
95
151
  private pairsOrdered;
96
- /** The counters whose tick every freeze advances. */
97
- private readonly inputs;
152
+ /** The counters whose tick every freeze advances; the graph primitives bump its fields. */
153
+ readonly inputs: InputCounters;
98
154
  private readonly undirectedCache;
99
155
  private cache;
100
156
  private cachedRevision;
101
157
  private revision;
158
+ /** The edge-id column, mirrored by builder row: what {@link GraphStore.edgeIdAt} reads. */
159
+ private edgeIdByIndex;
160
+ /** Builder row by edge id: what {@link GraphStore.edgeIndexOf} reads. */
161
+ private readonly indexByEdgeId;
102
162
  private pending;
103
163
  private pendingPositions;
164
+ /**
165
+ * Where the rows each removal and each kept graph took out were in the lane, read again at
166
+ * every redo: the lane half of a removed row, so undoing the removal puts the node back where
167
+ * it was rather than where its file seeded it.
168
+ */
169
+ private readonly heldLane;
170
+ /** Rows put back since the last freeze, by what put them back; written once they have rows. */
171
+ private readonly laneToRestore;
104
172
  private publishing;
105
173
  private disposed;
174
+ /** The builder and its `mutationCount` after the last write the store accounted for. */
175
+ private accounted;
176
+ /** Builder mutations found unaccounted for before a write of the store's own. */
177
+ private drift;
106
178
  /**
107
179
  * Build the empty store: one builder, one position array, the two element columns.
108
180
  * @param options - the store's configuration and its three freeze callbacks
109
181
  */
110
182
  constructor(options: GraphStoreOptions);
183
+ /**
184
+ * The one builder. Reading it first applies any structural change still waiting, so a reader
185
+ * never sees rows in an order the graph does not hold. A rebuild replaces the object: hold the
186
+ * store, not the builder.
187
+ * @returns the builder
188
+ */
189
+ get builder(): GraphBuilder;
190
+ /**
191
+ * Handle of the importer seed column; `setNodeValue(seedColumn, i, [x, y, z])` seeds a node.
192
+ * @returns the handle of the current builder
193
+ */
194
+ get seedColumn(): ColumnHandle;
195
+ /**
196
+ * Handle of the element-assigned edge counter column.
197
+ * @returns the handle of the current builder
198
+ */
199
+ get edgeIdColumn(): ColumnHandle;
200
+ /**
201
+ * How many times a structural change rebuilt the builder rather than appending to it.
202
+ * @returns the count
203
+ */
204
+ get rebuildCount(): number;
205
+ /**
206
+ * The direction setting now.
207
+ * @returns config.data.directed
208
+ */
209
+ private directedSetting;
210
+ /**
211
+ * The direction an empty graph starts with: the configured one, or directed until a file says.
212
+ * @returns Whether it is directed.
213
+ */
214
+ private emptyDirected;
215
+ /**
216
+ * How an empty graph's direction is settled: by a consumer who named one, and no file can
217
+ * overrule them, or not yet.
218
+ * @returns The provenance.
219
+ */
220
+ private emptyDirection;
221
+ /**
222
+ * A builder with the element's two columns declared.
223
+ * @param directed - Its direction; locked when the configuration named one.
224
+ * @returns the builder
225
+ */
226
+ private createBuilder;
111
227
  /**
112
228
  * Whether a reader would get anything other than a settled, fully published snapshot.
113
229
  *
@@ -137,6 +253,21 @@ export declare class GraphStore {
137
253
  * @throws Error when the store has been disposed
138
254
  */
139
255
  touch(): void;
256
+ /**
257
+ * How many times the builder was mutated with nobody accounting for it: a write that reached
258
+ * `builder` directly, without the graph primitives. Every legitimate write ends in
259
+ * {@link GraphStore.touch}, which accounts for it, and begins with {@link GraphStore.audit},
260
+ * which keeps what it finds. Strict state fails the next dispatch when this is not zero.
261
+ * @returns The count.
262
+ */
263
+ get mutationDrift(): number;
264
+ /**
265
+ * Keep the unaccounted mutations found now, before a write of the graph primitives or of the
266
+ * store itself would account for them.
267
+ */
268
+ audit(): void;
269
+ /** Account for every mutation of the builder so far. */
270
+ private account;
140
271
  /**
141
272
  * Take the next element-assigned edge id, written into the graphty.edgeId column at addEdge time.
142
273
  * @returns the id, one higher than the last
@@ -162,6 +293,45 @@ export declare class GraphStore {
162
293
  * store ignores this, so a load's cleanup may run after a Clear replaced its store.
163
294
  */
164
295
  closeLoad(): void;
296
+ /**
297
+ * Stamp an element-assigned edge id into a builder row's `graphty.edgeId` column, and index it
298
+ * both ways so the graph primitives can find a row by its id without freezing.
299
+ *
300
+ * The counter is never wound back: a redone edge gets the id it had, stamped here again.
301
+ * @param edgeIndex - the builder row
302
+ * @param edgeId - the counter
303
+ */
304
+ stampEdgeId(edgeIndex: number, edgeId: number): void;
305
+ /**
306
+ * The stable-identity cells an edge was given, read from the last freeze without settling:
307
+ * what an undone add keeps so its redo gives the edge back the identity it had.
308
+ * @param edgeId - the element-assigned counter
309
+ * @returns the hash, ordinal and among, or undefined when the last freeze holds no such edge
310
+ */
311
+ frozenEdgeIdentity(edgeId: number): EdgeIdentityCells | undefined;
312
+ /**
313
+ * Give a re-added edge the identity cells it had, instead of completing it as a new edge.
314
+ * @param row - the builder row
315
+ * @param cells - what {@link GraphStore.frozenEdgeIdentity} returned for it
316
+ */
317
+ restoreEdgeIdentity(row: number, cells: EdgeIdentityCells): void;
318
+ /**
319
+ * The builder row a live edge occupies.
320
+ * @param edgeId - the element-assigned counter
321
+ * @returns the row, or INVALID_INDEX when no live edge has that id
322
+ */
323
+ edgeIndexOf(edgeId: number): number;
324
+ /**
325
+ * The element-assigned id of the edge in one builder row.
326
+ * @param edgeIndex - the row
327
+ * @returns the counter, or INVALID_INDEX when the row is not a live edge
328
+ */
329
+ edgeIdAt(edgeIndex: number): number;
330
+ /**
331
+ * Put back how the direction was settled, when the write that settled it is undone.
332
+ * @param provenance - what it was before
333
+ */
334
+ restoreDirection(provenance: DirectionProvenance): void;
165
335
  /**
166
336
  * The current snapshot, freezing first when the graph has changed since the last one.
167
337
  *
@@ -186,6 +356,130 @@ export declare class GraphStore {
186
356
  * @throws Error when the store has been disposed
187
357
  */
188
358
  getSnapshot(): GraphSnapshot;
359
+ /**
360
+ * Take rows out of the graph, recording everything that putting them back needs: their rows,
361
+ * every registered column's value, and an edge's resolved endpoints and weight. Pins are the
362
+ * session's `pins` slice, which the removal's own draft records.
363
+ * Removing a node removes every edge attached to it.
364
+ * @param nodeIds - The nodes to remove; one the graph does not hold is skipped.
365
+ * @param edgeIds - The element-assigned ids of edges to remove; likewise.
366
+ * @returns What was removed.
367
+ */
368
+ removeRows(nodeIds: readonly NodeId[], edgeIds: readonly number[]): RemovedRows;
369
+ /**
370
+ * Whether the graph holds no node rows, answered without freezing: a clear still waiting to be
371
+ * applied empties it, and any other structural change still waiting is taken to leave rows.
372
+ * @returns True when it holds none.
373
+ */
374
+ get holdsNoRows(): boolean;
375
+ /**
376
+ * Whether structural changes are waiting for the next read. While they are, a write that
377
+ * would read the builder rebuilds it first; {@link GraphStore.dropAdded} waits with them.
378
+ * @returns True when some are.
379
+ */
380
+ get deferring(): boolean;
381
+ /**
382
+ * Take rows an add appended out again -- the undo of an add -- at the next read, with the
383
+ * structural changes waiting before it, so that undoing adds and removals in one run rebuilds
384
+ * the graph once rather than once per add.
385
+ * @param nodes - The nodes the add created.
386
+ * @param edges - The element-assigned ids of the edges it added.
387
+ */
388
+ dropAdded(nodes: readonly NodeId[], edges: readonly number[]): void;
389
+ /**
390
+ * Put removed rows back where they were: the undo of {@link GraphStore.removeRows}. Applied at
391
+ * the next read, folded with whatever else is waiting.
392
+ * @param rows - What the removal recorded.
393
+ */
394
+ insertRows(rows: RemovedRows): void;
395
+ /**
396
+ * Take recorded rows out again: the redo of {@link GraphStore.removeRows}. Applied at the next read.
397
+ * @param rows - What the removal recorded.
398
+ */
399
+ dropRows(rows: RemovedRows): void;
400
+ /**
401
+ * Forget the cached snapshot without freezing a replacement, once its holders have been told
402
+ * the dataset is gone: the next freeze then reports no previous snapshot, so nothing releases
403
+ * the forgotten one a second time.
404
+ */
405
+ forgetSnapshot(): void;
406
+ /**
407
+ * Set the whole graph aside for a replace: every row, every column and the direction.
408
+ * @returns What was set aside.
409
+ */
410
+ keep(): KeptGraph;
411
+ /**
412
+ * Swap the whole graph for an empty one (`restore` false), or back to a kept one (`restore`
413
+ * true). Applied at the next read; the last replace waiting wins over everything before it.
414
+ * @param kept - The graph {@link GraphStore.keep} set aside.
415
+ * @param restore - Whether to go back to it.
416
+ */
417
+ replace(kept: KeptGraph, restore: boolean): void;
418
+ /**
419
+ * Read again where rows about to be taken out are in the lane, for those it holds now.
420
+ * @param taken - The removal or the kept graph.
421
+ * @param ids - Its node ids.
422
+ */
423
+ private holdLane;
424
+ /**
425
+ * Queue the coordinates rows being put back had in the lane, for the next freeze.
426
+ * @param taken - The removal or the kept graph.
427
+ */
428
+ private putBack;
429
+ /**
430
+ * Give rows put back the coordinates they had when they were taken out, before anything seeds
431
+ * them. Not a move of the arrangement, so it writes the array directly.
432
+ * @param snapshot - The snapshot just frozen, its lane already remapped.
433
+ */
434
+ private restoreLane;
435
+ /**
436
+ * Queue a structural change, cancelling it against the one before when they undo each other.
437
+ * @param change - The change.
438
+ */
439
+ private defer;
440
+ /** Apply the structural changes waiting, if any, by freezing. */
441
+ private settle;
442
+ /**
443
+ * Apply the waiting structural changes to the builder. Appends and removals go straight into
444
+ * it; anything that must land mid-row rebuilds it once, however many changes are waiting.
445
+ * @returns The walk from the old builder's rows to the new one's when it rebuilt, else null.
446
+ */
447
+ private materialize;
448
+ /**
449
+ * Apply one change straight to the builder when that keeps row order: a removal always, an
450
+ * insert only when every row it puts back belongs at the end.
451
+ * @param change - The change.
452
+ * @returns False when it needs a rebuild.
453
+ */
454
+ private applyDirect;
455
+ /**
456
+ * Build a new builder in one pass, in the style of `GraphBuilder.from`: the rows of the graph
457
+ * it starts from, with the waiting changes merged in at their recorded rows.
458
+ * @param replace - The replace it starts from, or null to start from the builder now.
459
+ * @param changes - The inserts and removals after it, in order.
460
+ * @returns The walk from the old builder's rows to the new one's.
461
+ */
462
+ private rebuild;
463
+ /**
464
+ * Write a recorded node row's column values back.
465
+ * @param index - The row.
466
+ * @param values - The values.
467
+ */
468
+ private writeNode;
469
+ /**
470
+ * Write a recorded edge row's id and column values back.
471
+ * @param index - The row.
472
+ * @param edgeId - Its element-assigned id.
473
+ * @param values - The values.
474
+ */
475
+ private writeEdge;
476
+ /**
477
+ * Every set cell of one row of the last freeze.
478
+ * @param columns - The columns of that freeze.
479
+ * @param row - The row.
480
+ * @returns The values by column name, the edge id and weight excepted.
481
+ */
482
+ private rowValues;
189
483
  /**
190
484
  * The undirected view of a snapshot, cached per snapshot (14.4 rule 8).
191
485
  *
@@ -256,6 +550,12 @@ export declare class GraphStore {
256
550
  * torn down -- and then re-clear a `pending` that `dispose()` had already cleared.
257
551
  */
258
552
  private publish;
553
+ /**
554
+ * Follow a compacting freeze with the edge-id index: the builder's rows are the snapshot's
555
+ * from here on.
556
+ * @param remap - the freeze report's edgeRemap, or null when nothing was renumbered
557
+ */
558
+ private remapEdgeIds;
259
559
  /**
260
560
  * The completion pass (design 12.2, 12.3): hash new nodes, complete session edges, and, when
261
561
  * no load is open, complete the load's edges -- ordinal and among per pair over the load's
@@ -269,6 +569,12 @@ export declare class GraphStore {
269
569
  * @returns the latched value
270
570
  */
271
571
  private latchPairsOrdered;
572
+ /**
573
+ * Move the edges waiting for the completion pass into a rebuilt builder's rows, before the
574
+ * pass reads them: a rebuild renumbers rows the way a compacting freeze does.
575
+ * @param edgeRemap - old builder row to new builder row, INVALID_INDEX for a row dropped
576
+ */
577
+ private followRebuild;
272
578
  /**
273
579
  * Move the pass's marks and the open load's rows into the index space of a freeze just
274
580
  * committed. Allocation-free.
@@ -326,3 +632,4 @@ export declare class GraphStore {
326
632
  private direction;
327
633
  private seedUnplaced;
328
634
  }
635
+ export {};
@@ -42,10 +42,52 @@ export declare class JsonDataSource extends DataSource {
42
42
  protected getConfig(): BaseDataSourceConfig;
43
43
  /**
44
44
  * Fetches and parses JSON data into graph chunks.
45
- * Uses JMESPath to extract nodes and edges from the JSON structure.
45
+ *
46
+ * The node and edge arrays are found with the configured JMESPath expressions and read by
47
+ * graph-io's node-link importer, which checks every node's id and every edge's endpoints. The
48
+ * records the element receives are the ones the file wrote, unchanged, less the ones graph-io
49
+ * refused and every repeat of a node id after its first record.
50
+ *
51
+ * Two things graph-io cannot read are handed to the element as the file wrote them: nodes
52
+ * whose id is a JMESPath expression rather than a key, and edges whose endpoints no key names
53
+ * -- the element resolves the first and refuses the second, naming the keys the records carry.
46
54
  * @yields DataSourceChunk objects containing parsed nodes and edges
47
55
  */
48
56
  sourceFetchData(): AsyncGenerator<DataSourceChunk, void, unknown>;
57
+ /**
58
+ * Find one of the two arrays with its JMESPath expression.
59
+ * @param data - the parsed document
60
+ * @param path - the configured expression
61
+ * @param what - "nodes" or "edges", for the messages
62
+ * @returns the array, or an empty one when the expression finds nothing usable
63
+ */
64
+ private locate;
65
+ /**
66
+ * The key that holds a node's id, when graph-io can read it.
67
+ *
68
+ * The configured `nodeIdPath` when it is a key, else the first of `id`, `name`, `key` and
69
+ * `label` that some record carries -- the identifier keys this reader has always accepted.
70
+ * Null when the configured path is a JMESPath expression rather than a key.
71
+ * @param nodes - the node records
72
+ * @returns the key, or null
73
+ */
74
+ private nodeIdKey;
75
+ /**
76
+ * The keys that name an edge's endpoints, when graph-io can read them.
77
+ *
78
+ * The spelling is the one the element itself would resolve (`src/data/endpoints.ts`): the
79
+ * configured keys, else the first of `source`/`target`, `src`/`dst` and `from`/`to` that some
80
+ * record carries. Null when no key names them, or when a configured one is a JMESPath
81
+ * expression rather than a key: the records then reach the element as the file wrote them.
82
+ * @param edges - the edge records
83
+ * @returns the two keys, or null
84
+ */
85
+ private endpointKeys;
86
+ /**
87
+ * Record an error, and stop the load at the error limit as every reader does.
88
+ * @param error - the error
89
+ */
90
+ private addError;
49
91
  /**
50
92
  * Validates a node object and logs errors if invalid.
51
93
  * Returns true if the node is valid and should be included.
@@ -0,0 +1,89 @@
1
+ import { type Column, type GraphSnapshot, type NodeId } from "@graphty/graph-format";
2
+ import { type CommonImportOptions, type GraphImporter, type ImportReport } from "@graphty/graph-io";
3
+ import type { AdHocData } from "../config/common.js";
4
+ import type { ErrorAggregator } from "./ErrorAggregator.js";
5
+ /** What one import produced: the frozen scratch graph, the importer's report and the declared nodes. */
6
+ export interface ImportedGraph {
7
+ readonly snapshot: GraphSnapshot;
8
+ readonly report: ImportReport;
9
+ /** The ids of the nodes the file declared, as opposed to those an edge created. */
10
+ readonly declared: ReadonlySet<NodeId>;
11
+ }
12
+ /**
13
+ * Run a graph-io importer over a document into a scratch builder and freeze it.
14
+ *
15
+ * The scratch builder, not the element's own, is the importer's sink: the element's builder holds
16
+ * no attribute columns, so a data source reads the file here and rebuilds its records from the
17
+ * columns afterwards (see {@link toRecords}).
18
+ *
19
+ * A document that is recognisably this format but breaks off (a tag left open, a stray end tag)
20
+ * keeps what was read before the break: the importer's fatal error becomes one more error in the
21
+ * report rather than a thrown one. A document the importer does not recognise at all, or one whose
22
+ * report holds one of the `fatal` codes, still throws: a `GraphtyError` with `E_PARSE_FAILED`
23
+ * naming the format and the line, whose `cause` is the importer's `ImportError`.
24
+ * @param importer - the graph-io importer for the format
25
+ * @param text - the whole document
26
+ * @param options - importer options; `ids` defaults to "string", so ids stay the text the file wrote
27
+ * @param fatal - issue codes that make even a recognisable document unreadable
28
+ * @returns the snapshot, the report and the declared node ids
29
+ */
30
+ export declare function importDocument<Opts>(importer: GraphImporter<Opts>, text: string, options: Opts & CommonImportOptions, fatal?: readonly string[]): Promise<ImportedGraph>;
31
+ /**
32
+ * Copy the errors of an import report into the source's aggregator.
33
+ *
34
+ * Warnings stay in the report: the aggregator has always counted only what went wrong, and a
35
+ * warning is something the importer read and kept.
36
+ * @param report - the importer's report
37
+ * @param errors - the data source's aggregator
38
+ */
39
+ export declare function aggregateErrors(report: ImportReport, errors: ErrorAggregator): void;
40
+ /**
41
+ * A cell as the element's records carry it.
42
+ *
43
+ * An f32 cell is widened to the shortest decimal that reads back to the same f32, so a `float`
44
+ * attribute written as 0.1 arrives as 0.1 rather than as 0.10000000149011612.
45
+ * @param column - the column
46
+ * @param row - the row
47
+ * @returns the value
48
+ */
49
+ export declare function cell(column: Column, row: number): unknown;
50
+ /**
51
+ * The components of a multi-component f32 or f64 cell, each widened as {@link cell} does.
52
+ * @param column - a column with `components > 1`
53
+ * @param row - the row
54
+ * @returns the components
55
+ */
56
+ export declare function components(column: Column, row: number): number[];
57
+ /**
58
+ * The title a declared attribute was written with.
59
+ *
60
+ * graph-io names an attribute's column after its title (a GEXF `title`, a GraphML `attr.name`),
61
+ * but renames it `<title>#<id>` when that name is taken -- in GEXF by one of its own fields
62
+ * (`label`, `color`, `size`, ...). The element has always keyed the value by its title.
63
+ * @param name - the column name
64
+ * @param id - the attribute's id in the file
65
+ * @returns the title
66
+ */
67
+ export declare function attributeTitle(name: string, id: string): string;
68
+ /** How one format turns a row of the scratch graph into the keys of its record. */
69
+ export interface RecordMapping {
70
+ /** Write a node's keys onto its record, which already holds `id`. */
71
+ node(row: number, record: Record<string, unknown>): void;
72
+ /** Write an edge's keys onto its record, which already holds `source`, `target` and any `weight`. */
73
+ edge(row: number, record: Record<string, unknown>): void;
74
+ }
75
+ /**
76
+ * Rebuild the element's node and edge records from an imported graph.
77
+ *
78
+ * Only declared nodes become records, in declaration order. Each logical edge of the file becomes one record: when the
79
+ * importer expanded an edge into two halves to hold a mixed-direction file, the mirror half (the
80
+ * one whose `pair` points at a lower row) is skipped. An edge carries `weight` only when the file
81
+ * gave it one, at the precision the importer read it with.
82
+ * @param imported - the import
83
+ * @param mapping - the format's mapping from rows to record keys
84
+ * @returns the records, in file order
85
+ */
86
+ export declare function toRecords(imported: ImportedGraph, mapping: RecordMapping): {
87
+ nodes: AdHocData[];
88
+ edges: AdHocData[];
89
+ };
@@ -0,0 +1,64 @@
1
+ import { type NodeId } from "@graphty/graph-format";
2
+ import { type CommonImportOptions, type GraphImporter, type ImportInput, type ImportReport } from "@graphty/graph-io";
3
+ import type { ErrorAggregator } from "./ErrorAggregator";
4
+ /** One node or edge record, in the shape the element's data bags hold. */
5
+ export type ImportedRecord = Record<string, unknown>;
6
+ /**
7
+ * One imported node: its id, and every attribute the file set on it.
8
+ *
9
+ * The id is kept apart from the attributes because a file may carry an attribute under the very
10
+ * key the element reads the id from (a JSON node whose id is `name` and which also has an `id`
11
+ * value); each data source decides which key the id goes under.
12
+ */
13
+ export interface ImportedNode {
14
+ /** The node id. */
15
+ readonly id: NodeId;
16
+ /** Every attribute the file set. */
17
+ readonly data: ImportedRecord;
18
+ }
19
+ /** One imported edge: its endpoints, and every attribute the file set on it. See {@link ImportedNode}. */
20
+ export interface ImportedEdge {
21
+ /** The source node id. */
22
+ readonly source: NodeId;
23
+ /** The target node id. */
24
+ readonly target: NodeId;
25
+ /** Every attribute the file set, plus `weight` when the importer read a weight for it. */
26
+ readonly data: ImportedRecord;
27
+ }
28
+ /** What a graph-io import yields once it is turned back into element records. */
29
+ export interface ImportedRecords {
30
+ /** One entry per node, in node index order. */
31
+ readonly nodes: ImportedNode[];
32
+ /** One entry per logical edge, in insertion order. */
33
+ readonly edges: ImportedEdge[];
34
+ /** The importer's report, also when it aborted. */
35
+ readonly report: ImportReport;
36
+ /** Whether the importer aborted (a fatal issue, or its error limit): the records are then empty. */
37
+ readonly aborted: boolean;
38
+ }
39
+ /**
40
+ * Run a graph-io importer into a scratch builder and hand back the records the element consumes.
41
+ *
42
+ * The scratch builder is directed, keeps parallel edges and self-loops and adds the endpoints an
43
+ * edge names, so every record the file holds comes back once, in file order, with the endpoints
44
+ * the file wrote. Direction is not read from it: each data source declares what its format
45
+ * states. An importer that aborts -- an empty input, an unclosed quote, a header that names no
46
+ * column it can read -- does not throw here; its report is returned with `aborted` set, so the
47
+ * caller can record the issues and yield nothing, as every reader in the element has always done.
48
+ * @param importer - the graph-io importer
49
+ * @param input - the text to read
50
+ * @param options - the importer's options
51
+ * @returns the records and the report
52
+ */
53
+ export declare function importRecords<O>(importer: GraphImporter<O>, input: ImportInput, options: O & CommonImportOptions): Promise<ImportedRecords>;
54
+ /**
55
+ * Record an import report's errors in a data source's error aggregator.
56
+ *
57
+ * Only errors are recorded. Warnings did not reach the aggregator before either -- a header with
58
+ * no rows, a column renamed because its name was taken -- and the aggregator's count is what
59
+ * decides whether a load is reported as having failed rows.
60
+ * @param report - the importer's report
61
+ * @param aggregator - the data source's aggregator
62
+ * @throws Error when the aggregator's error limit is reached, as every reader does
63
+ */
64
+ export declare function recordIssues(report: ImportReport, aggregator: ErrorAggregator): void;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @file The coordinate lane as the renderer's public objects hand it out: read-only. The writable
3
+ * lane is reached only through {@link writableLane}, which no entry point exports.
4
+ */
5
+ import type { ReadonlyElementPositions } from "../session/types";
6
+ import { ElementPositions } from "./positions";
7
+ /** The key a data manager keeps its writable lane under; see {@link writableLane}. */
8
+ export declare const WRITABLE_LANE: unique symbol;
9
+ /**
10
+ * The writable coordinate lane of a data manager, for the element's own layout engines and
11
+ * nodes. A consumer reads `getDataManager().positions`, which has no writer, and places nodes
12
+ * through `session.positions.set`.
13
+ * @param manager - A data manager, or a stand-in for one that hands its lane out directly.
14
+ * @returns The lane, or undefined when the manager keeps none.
15
+ */
16
+ export declare function writableLane(manager: object | undefined): ElementPositions | undefined;
17
+ /**
18
+ * The read half of a coordinate lane, as a plain object: a caller holding it can read every row
19
+ * and reach no writer, not even through a cast.
20
+ * @param lane - Reads the lane now; a store may replace its lane object.
21
+ * @returns The read-only coordinates.
22
+ */
23
+ export declare function readonlyPositions(lane: () => ReadonlyElementPositions): ReadonlyElementPositions;