@graphty/graphty-element 2.6.1 → 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
@@ -19,21 +19,45 @@ export type NodeRenderState = "visible" | "hidden" | "context";
19
19
  interface NodeOpts {
20
20
  pinOnDrag?: boolean;
21
21
  }
22
+ /**
23
+ * Move a node to a row of the current snapshot. Only the data manager calls it, as a node reaches
24
+ * the builder, leaves it, or is renumbered by a freeze.
25
+ * @param node - The node.
26
+ * @param row - Its row, or INVALID_INDEX.
27
+ */
28
+ export declare function placeNodeRow(node: Node, row: number): void;
29
+ /**
30
+ * Hand an node the record the graph now holds for it. Only the data manager calls it, from the
31
+ * render half of the graph's derivation, when a command, an undo or a redo changed the record;
32
+ * no entry point exports it, so `node.data` is always the graph's record.
33
+ * @param node - The node.
34
+ * @param record - The record.
35
+ */
36
+ export declare function adoptNodeRecord(node: Node, record: AdHocData<string | number>): void;
22
37
  /**
23
38
  * Represents a node in the graph visualization with its mesh, label, and associated data.
24
39
  * Manages node rendering, styling, drag behavior, and interactions with the layout engine.
25
40
  */
26
41
  export declare class Node {
42
+ #private;
27
43
  parentGraph: Graph | GraphContext;
28
44
  opts: NodeOpts;
29
- id: NodeIdType;
45
+ readonly id: NodeIdType;
46
+ private row;
30
47
  /**
31
48
  * This node's index in the element's current GraphSnapshot, assigned at add time as
32
49
  * `builder.addNode(id)` and walked through `report.nodeRemap` on a renumbering freeze
33
50
  * (graph-format design 14.4 rule 5). INVALID_INDEX until the node reaches the builder.
51
+ * @returns The row.
34
52
  */
35
- index: number;
36
- data: AdHocData<string | number>;
53
+ get index(): number;
54
+ private set index(value);
55
+ /**
56
+ * The record this node carries, as the graph holds it: deep-frozen, so a write to it throws. A
57
+ * change goes through the graph (`updateNodes`, `session.data.updateNodes`, ...), which is what undo sees.
58
+ * @returns The record.
59
+ */
60
+ get data(): AdHocData<string | number>;
37
61
  mesh: AbstractMesh;
38
62
  label?: RichTextLabel;
39
63
  /**
@@ -407,6 +431,9 @@ export declare class Node {
407
431
  * of the element's bit and never a second source of truth. The order is load-bearing: the bit
408
432
  * is recorded FIRST, so an engine that calls back into {@link Node.isPinned} while being told
409
433
  * sees the pin.
434
+ *
435
+ * In a graph with a session the pin is an undoable step: it is recorded in the session's
436
+ * `pins`, which writes the byte and tells the engine.
410
437
  */
411
438
  pin(): void;
412
439
  /**
@@ -418,6 +445,12 @@ export declare class Node {
418
445
  * been told about.
419
446
  */
420
447
  unpin(): void;
448
+ /**
449
+ * Pin or release this node as a step of its graph's session, when it has one.
450
+ * @param pinned - Pin, or release.
451
+ * @returns False when there is no session to dispatch through.
452
+ */
453
+ private dispatchPin;
421
454
  /**
422
455
  * Tell the current layout engine about a pin the element has already recorded.
423
456
  *
@@ -11,6 +11,7 @@ export declare class NodeDragHandler {
11
11
  private node;
12
12
  private dragState;
13
13
  private clickState;
14
+ private gesture;
14
15
  private scene;
15
16
  private pointerObserver;
16
17
  private hoverObserver;
@@ -46,6 +47,28 @@ export declare class NodeDragHandler {
46
47
  * @param newPosition - New position to set for the node
47
48
  */
48
49
  setPositionDirect(newPosition: Vector3): void;
50
+ /**
51
+ * Open the drag's transaction. Its body waits for the drop; an undo while it is open aborts
52
+ * it, which ends the drag (design/undo/undo-design.md section 5.3).
53
+ * @returns The gesture, or null for a graph with no session.
54
+ */
55
+ private openGesture;
56
+ /**
57
+ * The drop: place the node where the pointer left it and, when it pins, pin it, both
58
+ * through the drag's transaction, then let the transaction record.
59
+ * @param gesture - The drag's gesture, or null for a graph with no session.
60
+ * @param pins - Whether the drop pins: `pinOnDrag` and the pointer placed the node.
61
+ */
62
+ private drop;
63
+ /**
64
+ * An undo aborted the drag: the dispatcher has rolled it back, restoring where everything
65
+ * was at drag start and stopping the layout. Release the node in the engine and give the
66
+ * camera its input back; the rest of the gesture is ignored until the pointer is released.
67
+ * @param gesture - The aborted gesture.
68
+ */
69
+ private abortGesture;
70
+ /** Give the camera its input back after a drag. */
71
+ private releaseCamera;
49
72
  /**
50
73
  * Get the node being dragged.
51
74
  * Used by XRInputHandler to access the node's mesh for position calculations.
@@ -57,6 +80,11 @@ export declare class NodeDragHandler {
57
80
  * Setup hover detection for emitting node-hover events.
58
81
  */
59
82
  private setupHoverEvents;
83
+ /**
84
+ * Whether the pointer placed the node, which is what `pinOnDrag` pins for.
85
+ * @returns True for a real drag; false for a click, however the hand shook during it.
86
+ */
87
+ private placedByPointer;
60
88
  /**
61
89
  * Check if the current pointer interaction qualifies as a click.
62
90
  * A click is defined as a short duration interaction with minimal movement.
@@ -17,12 +17,23 @@ import { StyleSchemaV1 } from "./config";
17
17
  * the element's own properties.
18
18
  */
19
19
  export declare class Styles {
20
- readonly config: StyleSchemaV1;
20
+ #private;
21
21
  /**
22
- * Creates a new Styles instance from a configuration document.
23
- * @param config - The parsed document.
22
+ * Creates a new Styles instance from a configuration document, or from a function that reads
23
+ * one.
24
+ * @param config - The parsed document, or the reader a graph builds its frozen view with.
24
25
  */
25
- constructor(config: StyleSchemaV1);
26
+ constructor(config: StyleSchemaV1 | (() => StyleSchemaV1));
27
+ /**
28
+ * The configuration document.
29
+ *
30
+ * On a graph it is a FROZEN VIEW: the project settings from the session's `config` slice,
31
+ * merged with the graph's view settings, rebuilt only when one of them changes. Two reads with
32
+ * no change between them return the same object, and writing into it throws. Change a setting
33
+ * through the element's properties, `Graph`'s setters or `session.config.set`.
34
+ * @returns The document.
35
+ */
36
+ get config(): StyleSchemaV1;
26
37
  /**
27
38
  * Creates a Styles instance from a JSON string.
28
39
  * @param json - JSON string containing the configuration
@@ -35,6 +35,14 @@ export interface AcceleratedWork {
35
35
  readonly capability: string;
36
36
  /** How many nodes this work is over. Compared against `acceleration.minNodes`. */
37
37
  readonly nodeCount: number;
38
+ /**
39
+ * False when this piece of work never goes to an accelerator, whatever the accelerator
40
+ * implements: the run asks for something no accelerator does, such as a walk that stops at a
41
+ * target. The decision is then the one for
42
+ * an accelerator without the capability -- the CPU path, or `E_NO_ACCELERATOR` under
43
+ * `"required"`. Absent means true.
44
+ */
45
+ readonly forwarded?: boolean;
38
46
  }
39
47
  /**
40
48
  * Where a piece of work will run, decided before any of it starts.
@@ -23,6 +23,12 @@
23
23
  import type { AlgorithmAccelerator } from "@graphty/algorithms";
24
24
  import type { LayoutAccelerator } from "@graphty/layout";
25
25
  import type { GraphAccelerator } from "./types";
26
+ /**
27
+ * Whether the element offers this capability to an accelerator at all.
28
+ * @param capability - A dispatcher member name, such as `"pageRank"`.
29
+ * @returns True when {@link narrowAlgorithms} copies a member of that name.
30
+ */
31
+ export declare function forwardsAlgorithm(capability: string): boolean;
26
32
  /**
27
33
  * Narrows the attached accelerator to the layout seam `createSimulation` feature-tests.
28
34
  *
@@ -45,6 +51,8 @@ export declare function narrowLayout(accelerator: GraphAccelerator): LayoutAccel
45
51
  * implements, each bound to it, so the dispatcher runs the accelerated implementation where one
46
52
  * exists and the CPU port everywhere else.
47
53
  * @param accelerator - The accelerator the controller has attached.
54
+ * @param onCall - Called whenever the dispatcher reaches one of the members, so a caller can tell
55
+ * an answer the device computed from one the dispatcher routed to the CPU port.
48
56
  * @returns The algorithm half of it, for `accelerated()`.
49
57
  * @example
50
58
  * ```ts
@@ -53,4 +61,4 @@ export declare function narrowLayout(accelerator: GraphAccelerator): LayoutAccel
53
61
  * );
54
62
  * ```
55
63
  */
56
- export declare function narrowAlgorithms(accelerator: GraphAccelerator): AlgorithmAccelerator;
64
+ export declare function narrowAlgorithms(accelerator: GraphAccelerator, onCall?: () => void): AlgorithmAccelerator;
@@ -461,6 +461,16 @@ export declare const ACCELERATION_MIN_NODES_MEASUREMENT = "RTX 4070 SUPER, headl
461
461
  * each. Carrying them is what makes the element's behaviour and that record agree; raising the
462
462
  * render ceiling (issue #419) is what would let any of the three be measured here and sharpened.
463
463
  *
464
+ * HITS, KATZ AND EIGENVECTOR CENTRALITY ARE FLOORED FROM THE SAME RECORD AND SIT BELOW THE CEILING.
465
+ * No sweep through the element has measured them yet. The record's section "Re-derived against the
466
+ * measured ports" times the kernels at 100 iterations against the index-based CPU ports in Chromium:
467
+ * HITS at 0.72x and 5.71x, Katz at 0.36x and 3.66x, at 10,000 and 100,000 nodes, so both LOSE at
468
+ * 10,000. The floors are where the speedup crosses 1x between those two measured sizes, taken on a
469
+ * straight line in log size against log speedup and rounded up: 15,000 nodes for HITS and 28,000
470
+ * for Katz. Eigenvector centrality shares Katz's floor: the record costs the two as one row, runs
471
+ * the same power iteration for both, and has no re-derivation of its own. All three are inside
472
+ * what the element can hold; a sweep through the element is what would sharpen them.
473
+ *
464
474
  * A floor is the smallest measured size at which the device's median was at or below the CPU
465
475
  * port's IN EVERY RUN, so a size that won under one load and lost under another is below it. A
466
476
  * capability that is not listed has no floor and follows {@link ACCELERATION_MIN_NODES_DEFAULT}.
@@ -86,16 +86,28 @@ export declare class AiController {
86
86
  * @returns Formatted schema section or empty string if no schema
87
87
  */
88
88
  private buildSchemaSection;
89
+ /**
90
+ * One message, inside its transaction: ask the model, then run the tools it calls.
91
+ * @param input - The user's natural language input
92
+ * @param tx - The message's transaction, which the tools write through
93
+ * @param signal - Fires when the message is cancelled or its transaction aborted
94
+ * @returns The execution result
95
+ */
96
+ private converse;
89
97
  /**
90
98
  * Execute a list of tool calls.
91
99
  * @param toolCalls - Tool calls to execute
100
+ * @param tx - The message's transaction
101
+ * @param signal - Fires when the message is cancelled
92
102
  * @param llmText - Text response from LLM (if any)
93
103
  * @returns Combined execution result
104
+ * @throws MessageRolledBack when a tool threw, so the message's transaction rolls back.
94
105
  */
95
106
  private executeToolCalls;
96
107
  /**
97
108
  * Execute a single tool call.
98
109
  * @param toolCall - The tool call to execute
110
+ * @param tx - The message's transaction, handed to the command as `ctx.tx`
99
111
  * @returns Command result
100
112
  */
101
113
  private executeToolCall;
@@ -80,6 +80,13 @@ export declare class AiManager {
80
80
  private registerBuiltinCommands;
81
81
  /**
82
82
  * Register a custom command.
83
+ *
84
+ * Each assistant message is one undoable step. A command joins it by writing through
85
+ * `ctx.tx` (`ctx.tx.styles.add`, `ctx.tx.layout.set`, `ctx.tx.run`): those changes are undone
86
+ * with the rest of the message, and rolled back if a command throws. A change made through
87
+ * `ctx.graph` is a step of its own and is not rolled back. A command stops when
88
+ * `ctx.abortSignal` fires, which happens when the message is cancelled or undone while it is
89
+ * still going.
83
90
  * @param command - The command to register
84
91
  */
85
92
  registerCommand(command: Parameters<CommandRegistry["register"]>[0]): void;
@@ -2,7 +2,7 @@
2
2
  * AlgorithmCommands - Commands for running and listing graph algorithms.
3
3
  * @module ai/commands/AlgorithmCommands
4
4
  */
5
- import type { GraphCommand } from "./types";
5
+ import { type GraphCommand } from "./types";
6
6
  /**
7
7
  * Run a graph algorithm.
8
8
  */
@@ -2,7 +2,7 @@
2
2
  * Layout Commands Module - Commands for changing graph layout and dimension.
3
3
  * @module ai/commands/LayoutCommands
4
4
  */
5
- import type { GraphCommand } from "./types";
5
+ import { type GraphCommand } from "./types";
6
6
  /**
7
7
  * Command to change the graph layout algorithm.
8
8
  */
@@ -14,7 +14,7 @@
14
14
  * reports and what a layer, a filter and a legend all use.
15
15
  * @module ai/commands/StyleCommands
16
16
  */
17
- import type { GraphCommand } from "./types";
17
+ import { type GraphCommand } from "./types";
18
18
  /**
19
19
  * Command to find and style nodes matching a selector.
20
20
  */
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { z } from "zod";
6
6
  import type { Graph } from "../../Graph";
7
+ import type { TransactionScope } from "../../session/types";
7
8
  import type { AiStatus } from "../AiStatus";
8
9
  /**
9
10
  * Result of executing a command.
@@ -26,13 +27,31 @@ export interface CommandResult {
26
27
  export interface CommandContext {
27
28
  /** The graph instance to operate on */
28
29
  graph: Graph;
29
- /** Signal to check for cancellation */
30
+ /**
31
+ * The message's transaction. Everything a command changes through `tx` -- `tx.styles.add`,
32
+ * `tx.layout.set`, `tx.run` -- joins the message's one undoable step, and is rolled back with
33
+ * the rest of the message when a command throws. A change made through `graph` instead is a
34
+ * step of its own and is not rolled back.
35
+ */
36
+ tx: TransactionScope;
37
+ /**
38
+ * Fires when the message is cancelled, or undone while it is still going. A command stops
39
+ * on it: once it has fired, every `tx` call rejects.
40
+ */
30
41
  abortSignal: AbortSignal;
31
42
  /** Function to emit events */
32
43
  emitEvent: (type: string, data: unknown) => void;
33
44
  /** Function to update AI status */
34
45
  updateStatus: (updates: Partial<AiStatus>) => void;
35
46
  }
47
+ /**
48
+ * Where a command writes: the message's transaction, so its changes join the message's step, or
49
+ * the graph's own session when the command is called outside a message.
50
+ * @param graph - The graph the command was handed.
51
+ * @param context - The command's context, when it has one.
52
+ * @returns The session to write through.
53
+ */
54
+ export declare function writerOf(graph: Graph, context?: CommandContext): TransactionScope;
36
55
  /**
37
56
  * Example of how a command can be invoked.
38
57
  */
@@ -1,6 +1,7 @@
1
1
  import { type AcceleratedAlgorithms, type Graph as AlgorithmGraph } from "@graphty/algorithms";
2
2
  import { type GraphSnapshot, type U32 } from "@graphty/graph-format";
3
3
  import { type AccelerationPrecision } from "../acceleration/types";
4
+ import { type RegisterOptions } from "../catalog/pluginRegistry";
4
5
  import type { AlgorithmDescriptor, EdgeId, FieldDescriptor, NodeId } from "../catalog/types";
5
6
  import { type OptionsSchema as ZodOptionsSchema } from "../config";
6
7
  import { Graph } from "../Graph";
@@ -65,8 +66,11 @@ export interface AlgorithmStatics {
65
66
  * `cubic`. The element divides them by the rate it measured for that class on this device,
66
67
  * so the estimate follows the machine and reports "calibrated" once the device is probed,
67
68
  * exactly as a built-in's does. Wins over {@link cost} when both are declared.
69
+ *
70
+ * `options` are the values the run would use -- the caller's, with the declared defaults
71
+ * filled in -- so an option that multiplies the work (a number of passes) is priced.
68
72
  */
69
- costUnits?: (n: number, m: number) => number;
73
+ costUnits?: (n: number, m: number, options: Readonly<Record<string, unknown>>) => number;
70
74
  /**
71
75
  * The plugin's own version, recorded on every run this algorithm produces.
72
76
  *
@@ -276,13 +280,22 @@ export declare abstract class Algorithm<TOptions extends Record<string, unknown>
276
280
  * THE DECISION IS TAKEN ONCE, HERE, BEFORE ANY WORK STARTS. The controller answers "the policy
277
281
  * is off", "no accelerator", "below `acceleration.minNodes`" or "this accelerator does not
278
282
  * implement that" up front, and under `acceleration="required"` it throws `E_NO_ACCELERATOR`
279
- * rather than answering quietly. After the work has started there is no second decision: a
283
+ * rather than answering quietly. Two answers stay on the CPU even under `"required"`, because
284
+ * the device is not the element's to offer for them: a capability the element does not
285
+ * forward (betweenness and closeness today) never asks the controller, and a call the
286
+ * dispatcher itself keeps on the CPU port (an option or a graph shape the device's kernel is
287
+ * not defined for) runs there. Both say `f64`. After the work has started there is no second decision: a
280
288
  * failure from the accelerator propagates with its code and fails the run, because a number
281
289
  * that silently came from somewhere else is worse than no number.
282
290
  * @param capability - The accelerator member this work would use, such as `"pageRank"`.
283
291
  * @param mode - The shape this algorithm needs; see {@link AlgorithmGraphMode}. `"undirected"`
284
292
  * takes the snapshot's undirected view, which is what collapses a reciprocal pair into one
285
293
  * edge.
294
+ * @param options - What the decision needs to know about this run.
295
+ * @param options.accelerable - False when the options of this run are ones no accelerator
296
+ * answers, such as a walk that stops at a target, so the decision is the CPU port's (and
297
+ * `E_NO_ACCELERATOR` under `acceleration="required"`). A capability the element does not
298
+ * forward to an accelerator is never accelerable, whatever this says.
286
299
  * @returns The snapshot, the edge map onto it, and the runner.
287
300
  * @example
288
301
  * ```ts
@@ -291,7 +304,9 @@ export declare abstract class Algorithm<TOptions extends Record<string, unknown>
291
304
  * const group = value.labels[snapshot.ids.indexOf(nodeId)];
292
305
  * ```
293
306
  */
294
- protected accelerated(capability: string, mode: AlgorithmGraphMode): AcceleratedAlgorithmRun;
307
+ protected accelerated(capability: string, mode: AlgorithmGraphMode, options?: {
308
+ accelerable?: boolean;
309
+ }): AcceleratedAlgorithmRun;
295
310
  /**
296
311
  * The dense row of a node the reader named in an option.
297
312
  *
@@ -347,9 +362,11 @@ export declare abstract class Algorithm<TOptions extends Record<string, unknown>
347
362
  /**
348
363
  * Registers an algorithm class in the global registry
349
364
  * @param cls - The algorithm class to register
365
+ * @param options - Whether a different class under a key already taken throws instead of
366
+ * replacing it.
350
367
  * @returns The registered algorithm class
351
368
  */
352
- static register<T extends AlgorithmClass>(cls: T): T;
369
+ static register<T extends AlgorithmClass>(cls: T, options?: RegisterOptions): T;
353
370
  /**
354
371
  * Gets an algorithm instance from the registry
355
372
  * @param g - The graph to run the algorithm on
@@ -53,14 +53,5 @@ export declare class BFSAlgorithm extends DeclaredAlgorithm<BFSOptions> {
53
53
  * @returns The layered result, or null when there is nothing to walk.
54
54
  */
55
55
  compute(context: AlgorithmRunContext): Promise<AlgorithmOutput | null>;
56
- /**
57
- * Walk with an early stop at a target, on the CPU reference implementation.
58
- * @param context - What the element gave the run.
59
- * @param nodeIds - The nodes to publish for.
60
- * @param source - Where the walk starts.
61
- * @param targetNode - Where it stops.
62
- * @returns The layered result, or null when the source is not in the graph.
63
- */
64
- private legacyWalk;
65
56
  }
66
57
  export {};
@@ -49,19 +49,5 @@ export declare class BellmanFordAlgorithm extends DeclaredAlgorithm<BellmanFordO
49
49
  * @returns The route, or null when there are no nodes to search.
50
50
  */
51
51
  compute(context: AlgorithmRunContext): Promise<AlgorithmOutput | null>;
52
- /**
53
- * Reconstruct the shortest path from predecessors
54
- * @param predecessors - Map of node to its predecessor in the shortest path
55
- * @param source - The source node
56
- * @param target - The target node
57
- * @returns Array of node IDs representing the shortest path
58
- */
59
- private reconstructPath;
60
- /**
61
- * Get set of edge keys that are part of the path
62
- * @param path - Array of node IDs representing the path
63
- * @returns Set of edge keys in "srcId:dstId" format
64
- */
65
- private getPathEdges;
66
52
  }
67
53
  export {};
@@ -10,7 +10,7 @@ interface DFSOptions extends Record<string, unknown> {
10
10
  source: number | string | null;
11
11
  /** Target node for early termination (optional) */
12
12
  targetNode: number | string | null;
13
- /** Use recursive implementation vs iterative */
13
+ /** Accepted and ignored; see the option's description. */
14
14
  recursive: boolean;
15
15
  /** Use pre-order traversal (visit before children) vs post-order */
16
16
  preOrder: boolean;
@@ -1,3 +1,4 @@
1
+ import type { SimplifyPolicy } from "./input/derivedInputs";
1
2
  import { type ScopeInputDeclaration } from "./input/ScopedInput";
2
3
  import { type AlgorithmOutput, type AlgorithmRunContext, DeclaredAlgorithm } from "./results";
3
4
  /**
@@ -8,6 +9,8 @@ export declare class FloydWarshallAlgorithm extends DeclaredAlgorithm {
8
9
  static type: string;
9
10
  /** Measures every pair of the run's scope: the node list and the graph both come from the input. */
10
11
  static scopeInput: ScopeInputDeclaration;
12
+ /** A distance: of a group of parallel edges, the cheapest is the one a shortest path takes. */
13
+ static parallelEdges: SimplifyPolicy;
11
14
  /**
12
15
  * Measure the distance between every pair of nodes, and give each node the distance to the
13
16
  * node furthest from it.
@@ -24,6 +27,8 @@ export declare class FloydWarshallAlgorithm extends DeclaredAlgorithm {
24
27
  * either, which is the case that has to be fixed here rather than worked around outside.
25
28
  * @param context - What the element gave the run.
26
29
  * @returns The all-pairs measurement, or null when there are no nodes to measure.
30
+ * @throws A `GraphtyError` with `E_TOO_LARGE` when the run is over more nodes than the
31
+ * all-pairs matrix is bounded to, before any of it is allocated.
27
32
  */
28
33
  compute(context: AlgorithmRunContext): Promise<AlgorithmOutput | null>;
29
34
  }
@@ -29,6 +29,11 @@ export declare class GirvanNewmanAlgorithm extends DeclaredAlgorithm<GirvanNewma
29
29
  * The method produces a dendrogram -- one partition per cut -- and the run publishes the cut
30
30
  * that scored the highest modularity, with that score. A graph with no edges falls apart at
31
31
  * the first step, and every node is then its own community.
32
+ *
33
+ * Modularity counts a self-loop twice in its node's degree, the standard (NetworkX) reading.
34
+ * The object-graph route this replaced counted it once, so on a graph with a self-loop the
35
+ * published modularity differs from that route's, and because the best-scoring cut is the one
36
+ * published, the partition can differ too. Without a self-loop both are unchanged.
32
37
  * @param context - What the element gave the run.
33
38
  * @returns The community result, or null when there are no nodes to group.
34
39
  */
@@ -31,6 +31,11 @@ export declare class LeidenAlgorithm extends DeclaredAlgorithm<LeidenOptions> {
31
31
  * Publishes the community shape's uniform fields: a group per node, and the modularity the
32
32
  * method reported. How many passes it took qualifies those numbers rather than being one of
33
33
  * them, so it travels in the caveats.
34
+ *
35
+ * The modularity counts a self-loop twice in its node's degree, the standard (NetworkX)
36
+ * reading; the object-graph route this replaced counted it once. The partition is a
37
+ * randomised heuristic's and not the replaced route's: on small graphs without self-loops its
38
+ * modularity lands within about 0.05 of that route's either way, and no lower on average.
34
39
  * @param context - What the element gave the run.
35
40
  * @returns The community result, or null when there are no nodes to group.
36
41
  */
@@ -1,4 +1,4 @@
1
- import { type NodeId as AlgorithmNodeId } from "@graphty/algorithms";
1
+ import type { NodeId as AlgorithmNodeId } from "@graphty/algorithms";
2
2
  import { z } from "zod/v4";
3
3
  import type { FieldDescriptor, NodeId } from "../catalog/types";
4
4
  import { type InferOptions } from "../config";
@@ -1,7 +1,7 @@
1
1
  import { type ScopeInputDeclaration } from "./input/ScopedInput";
2
2
  import { type AlgorithmOutput, type AlgorithmRunContext, DeclaredAlgorithm } from "./results";
3
3
  /**
4
- *
4
+ * Strongly connected components: the pieces a directed path can cross both ways.
5
5
  */
6
6
  export declare class StronglyConnectedComponentsAlgorithm extends DeclaredAlgorithm {
7
7
  static namespace: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @file The field list a node-metric result publishes.
2
+ * @file The field lists a metric or a community result publishes.
3
3
  *
4
4
  * The names are fixed by the result's SHAPE rather than by the algorithm -- `results.<run>.value`
5
5
  * means the same thing for every metric -- so they are built here once instead of being written
@@ -46,4 +46,26 @@ interface MetricValueName {
46
46
  * @returns The uniform field list for the node-metric shape.
47
47
  */
48
48
  export declare function nodeMetricFields(value: MetricValueName): readonly FieldDescriptor[];
49
+ /**
50
+ * Build the fields every edge-metric result publishes: {@link nodeMetricFields} for a value
51
+ * measured per edge.
52
+ * @param value - What this metric's primary value is called.
53
+ * @returns The uniform field list for the edge-metric shape.
54
+ */
55
+ export declare function edgeMetricFields(value: MetricValueName): readonly FieldDescriptor[];
56
+ /**
57
+ * Build the fields every community result publishes: the group, and the sizes and count the
58
+ * element derives from it; modularity only when asked for, because only a method that scores its
59
+ * own partition may publish one. A run fills what `communityFieldSpecs` lists.
60
+ * @param value - What one group is called, and whether the method publishes modularity.
61
+ * @param value.plainName - What one group is called in plain words, such as "Community".
62
+ * @param value.technicalName - What a paper calls the grouping.
63
+ * @param value.modularity - Whether the method scores its partition with modularity.
64
+ * @returns The uniform field list for the community shape.
65
+ */
66
+ export declare function communityFields(value: {
67
+ readonly plainName: string;
68
+ readonly technicalName: string;
69
+ readonly modularity?: boolean;
70
+ }): readonly FieldDescriptor[];
49
71
  export {};
@@ -1,7 +1,19 @@
1
1
  /**
2
2
  * @file Helpers the adapters share: matching an `@graphty/algorithms` answer back onto an edge,
3
- * and refusing a node option that names no node.
3
+ * refusing a node option that names no node, and the neighbour order a walk tries.
4
4
  */
5
+ import type { GraphSnapshot, U32 } from "@graphty/graph-format";
6
+ /**
7
+ * The order a walk tries each node's neighbours in: the order their edges were declared.
8
+ *
9
+ * An index-based walk tries a node's arcs in row order, which is neighbour index order. The
10
+ * element's walks have always tried them in the order the edges were declared, and a depth-first
11
+ * order, a strongly connected component's number and the nodes a breadth-first walk expands
12
+ * before it reaches its target all depend on it. Passed to a port as `arcOrder`, this keeps them.
13
+ * @param snapshot - The snapshot the walk runs over.
14
+ * @returns A permutation of the arc indices, each row's slice sorted by the edge each arc is of.
15
+ */
16
+ export declare function declarationArcOrder(snapshot: GraphSnapshot): U32;
5
17
  /**
6
18
  * The key an `@graphty/algorithms` result is matched back onto the element's edges by: the two
7
19
  * endpoint ids, in the orientation the record declared.
@@ -28,16 +28,16 @@
28
28
  * closing one.
29
29
  */
30
30
  import { type RegisterOptions } from "./pluginRegistry";
31
- import { type PaletteDescriptor, type PaletteId } from "./types";
31
+ import { type PaletteDescriptor, type PaletteId, type PaletteRegistration } from "./types";
32
32
  /**
33
33
  * Register a palette so that a style layer, a legend and a saved document can all name it.
34
- * @param descriptor - The palette: an id, a plain name, a kind, its colour anchors, its capacity
35
- * and whatever colour-blindness safety it claims.
34
+ * @param descriptor - The palette: an id, a plain name, a kind and its colour anchors, and
35
+ * optionally its capacity (derived when left off) and whatever colour-blindness safety it claims.
36
36
  * @param options - Whether a collision with an existing registration throws instead of replacing.
37
37
  * @throws A `GraphtyError` with `E_BAD_COMMAND` when the descriptor is malformed, naming the
38
38
  * field, or with `E_DUPLICATE_PLUGIN` when the id is one the element ships.
39
39
  */
40
- export declare function registerPalette(descriptor: PaletteDescriptor, options?: RegisterOptions): void;
40
+ export declare function registerPalette(descriptor: PaletteRegistration, options?: RegisterOptions): void;
41
41
  /**
42
42
  * What those palettes publish, in registration order.
43
43
  *
@@ -65,9 +65,10 @@ export interface RegisteredAlgorithm {
65
65
  * A cost model in work units of the descriptor's cost class, read from `static costUnits`.
66
66
  *
67
67
  * The estimator divides it by this device's rate for that class, so calibration scales it.
68
- * Wins over {@link cost} when both are present.
68
+ * Wins over {@link cost} when both are present. `options` are the run's option values, the
69
+ * declared defaults filled in.
69
70
  */
70
- readonly costUnits?: (n: number, m: number) => number;
71
+ readonly costUnits?: (n: number, m: number, options: Readonly<Record<string, unknown>>) => number;
71
72
  /**
72
73
  * The plugin's own version, read from `static version`.
73
74
  *
@@ -182,8 +182,16 @@ export interface OptionChoice {
182
182
  value: string;
183
183
  label: string;
184
184
  }
185
+ /**
186
+ * Which kind of element an "attribute" or "partition" option reads. Without it, neither a form nor
187
+ * the element can tell whether "confidence" names a node attribute or an edge attribute.
188
+ */
189
+ export interface OptionDescriptorDomain {
190
+ /** Nodes (the default) or edges. Meaningful only for type "attribute" or "partition". */
191
+ on?: "node" | "edge";
192
+ }
185
193
  /** One configurable option, as plain JSON a form can render with no knowledge of Zod. */
186
- export interface OptionDescriptor {
194
+ export interface OptionDescriptor extends OptionDescriptorDomain {
187
195
  name: string;
188
196
  plainName: string;
189
197
  technicalName?: string;
@@ -480,6 +488,15 @@ export interface PaletteDescriptor {
480
488
  capacity: number | null;
481
489
  colorblindSafe: readonly ("deuteranopia" | "protanopia" | "tritanopia")[];
482
490
  }
491
+ /**
492
+ * What `registerPalette` accepts: a {@link PaletteDescriptor} whose derived and optional members
493
+ * may be left off. `capacity` is derived from the kind and the colours, and a missing
494
+ * `colorblindSafe` is no claim.
495
+ */
496
+ export type PaletteRegistration = Omit<PaletteDescriptor, "capacity" | "colorblindSafe"> & {
497
+ capacity?: number | null;
498
+ colorblindSafe?: PaletteDescriptor["colorblindSafe"];
499
+ };
483
500
  /**
484
501
  * One camera view: a named way of deciding where the viewer stands and what they look at.
485
502
  *