@graphty/graphty-element 2.5.2 → 2.6.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 (135) hide show
  1. package/dist/ai.js +3 -3
  2. package/dist/catalog.d.ts +16 -0
  3. package/dist/catalog.js +34 -32
  4. package/dist/chunks/{AiManager-CrbvKdEK.js → AiManager-4iQpsJW1.js} +4 -4
  5. package/dist/chunks/{DataSource-qU-nLhXN.js → DataSource-BL2UzPff.js} +2 -2
  6. package/dist/chunks/GraphSession-BhuHSXIo.js +12819 -0
  7. package/dist/chunks/{GraphtyLogger-DOTwCiMR.js → GraphtyLogger-B_O67a6c.js} +1 -1
  8. package/dist/chunks/{VoiceInputAdapter-D4NrRL_1.js → VoiceInputAdapter-Cc6mHXTI.js} +1 -1
  9. package/dist/chunks/{XRPivotCameraController-Uqa47vmo.js → XRPivotCameraController-BLa89LXn.js} +2 -2
  10. package/dist/chunks/{algorithms-D-ab-Auu.js → algorithms-BJ6DQMOe.js} +931 -781
  11. package/dist/chunks/{capability-check-Vw3IcqiE.js → capability-check-Am2zliFj.js} +1 -1
  12. package/dist/chunks/{detect-B4Qrw976.js → detect-fyuVnlCT.js} +1 -1
  13. package/dist/chunks/{format-detection-r2IfNFXO.js → format-detection-BHwrAVzW.js} +1 -1
  14. package/dist/chunks/{index-J9MgLio9.js → index-BkBLbvui.js} +2691 -2434
  15. package/dist/chunks/optionsFromZod-CKMYSwTz.js +3636 -0
  16. package/dist/chunks/{paletteRegistry-Kt-6CeoN.js → paletteRegistry-BCFSwJGK.js} +224 -189
  17. package/dist/chunks/parse-BMTqt4SS.js +3658 -0
  18. package/dist/chunks/{types-C_c53VgR.js → types-DFchv4Ny.js} +4 -1
  19. package/dist/custom-elements.json +1 -1
  20. package/dist/extend.d.ts +10 -8
  21. package/dist/extend.js +6 -6
  22. package/dist/graphty-catalog.json +75 -38
  23. package/dist/graphty.bundle.js +55368 -48970
  24. package/dist/graphty.js +19 -19
  25. package/dist/index.d.ts +1 -1
  26. package/dist/logging.js +2 -2
  27. package/dist/schema.d.ts +15 -1
  28. package/dist/schema.js +1 -1
  29. package/dist/session.d.ts +30 -7
  30. package/dist/session.js +40 -37
  31. package/dist/src/Graph.d.ts +35 -7
  32. package/dist/src/acceleration/types.d.ts +79 -43
  33. package/dist/src/algorithms/Algorithm.d.ts +52 -4
  34. package/dist/src/algorithms/BFSAlgorithm.d.ts +3 -0
  35. package/dist/src/algorithms/BellmanFordAlgorithm.d.ts +3 -0
  36. package/dist/src/algorithms/BetweennessCentralityAlgorithm.d.ts +3 -0
  37. package/dist/src/algorithms/BipartiteMatchingAlgorithm.d.ts +3 -0
  38. package/dist/src/algorithms/ClosenessCentralityAlgorithm.d.ts +3 -0
  39. package/dist/src/algorithms/ConnectedComponentsAlgorithm.d.ts +4 -1
  40. package/dist/src/algorithms/DFSAlgorithm.d.ts +3 -0
  41. package/dist/src/algorithms/DegreeAlgorithm.d.ts +3 -0
  42. package/dist/src/algorithms/DijkstraAlgorithm.d.ts +6 -0
  43. package/dist/src/algorithms/EigenvectorCentralityAlgorithm.d.ts +2 -0
  44. package/dist/src/algorithms/FloydWarshallAlgorithm.d.ts +3 -0
  45. package/dist/src/algorithms/GirvanNewmanAlgorithm.d.ts +3 -0
  46. package/dist/src/algorithms/HITSAlgorithm.d.ts +3 -0
  47. package/dist/src/algorithms/KCoreAlgorithm.d.ts +3 -0
  48. package/dist/src/algorithms/KatzCentralityAlgorithm.d.ts +3 -0
  49. package/dist/src/algorithms/KruskalAlgorithm.d.ts +4 -1
  50. package/dist/src/algorithms/LabelPropagationAlgorithm.d.ts +3 -0
  51. package/dist/src/algorithms/LeidenAlgorithm.d.ts +3 -0
  52. package/dist/src/algorithms/LinkPredictionAlgorithm.d.ts +4 -1
  53. package/dist/src/algorithms/LouvainAlgorithm.d.ts +3 -0
  54. package/dist/src/algorithms/MaxFlowAlgorithm.d.ts +3 -0
  55. package/dist/src/algorithms/MinCutAlgorithm.d.ts +3 -0
  56. package/dist/src/algorithms/PageRankAlgorithm.d.ts +3 -0
  57. package/dist/src/algorithms/PrimAlgorithm.d.ts +3 -0
  58. package/dist/src/algorithms/StronglyConnectedComponentsAlgorithm.d.ts +3 -0
  59. package/dist/src/algorithms/input/ScopedInput.d.ts +185 -0
  60. package/dist/src/algorithms/input/derivedInputs.d.ts +199 -0
  61. package/dist/src/algorithms/input/maskBack.d.ts +37 -0
  62. package/dist/src/algorithms/metrics/MetricAlgorithm.d.ts +3 -3
  63. package/dist/src/algorithms/results/DeclaredAlgorithm.d.ts +4 -3
  64. package/dist/src/algorithms/results/types.d.ts +28 -6
  65. package/dist/src/algorithms/utils/communityUtils.d.ts +0 -48
  66. package/dist/src/algorithms/utils/graphUtils.d.ts +2 -68
  67. package/dist/src/algorithms/utils/snapshotGraph.d.ts +3 -1
  68. package/dist/src/catalog/algorithms.d.ts +3 -0
  69. package/dist/src/catalog/layouts.d.ts +2 -0
  70. package/dist/src/catalog/sets/canonical.d.ts +68 -0
  71. package/dist/src/catalog/sets/hash.d.ts +126 -0
  72. package/dist/src/catalog/sets/parse.d.ts +115 -0
  73. package/dist/src/catalog/types.d.ts +329 -8
  74. package/dist/src/data/GraphStore.d.ts +73 -1
  75. package/dist/src/data/edgeIdentity.d.ts +202 -1
  76. package/dist/src/data/ingest.d.ts +3 -1
  77. package/dist/src/data/report.d.ts +20 -0
  78. package/dist/src/graphty-element.d.ts +42 -6
  79. package/dist/src/layout/D3GraphLayoutEngine.d.ts +11 -0
  80. package/dist/src/layout/LayoutEngine.d.ts +56 -0
  81. package/dist/src/layout/NGraphLayoutEngine.d.ts +10 -0
  82. package/dist/src/layout/SimulationLayoutEngine.d.ts +11 -0
  83. package/dist/src/managers/AlgorithmManager.d.ts +8 -0
  84. package/dist/src/managers/DataManager.d.ts +11 -0
  85. package/dist/src/managers/LayoutManager.d.ts +126 -2
  86. package/dist/src/managers/StatsManager.d.ts +1 -0
  87. package/dist/src/session/GraphSession.d.ts +48 -0
  88. package/dist/src/session/attributes.d.ts +121 -1
  89. package/dist/src/session/cost/estimate.d.ts +20 -0
  90. package/dist/src/session/cost/index.d.ts +1 -1
  91. package/dist/src/session/planning.d.ts +32 -2
  92. package/dist/src/session/query.d.ts +7 -0
  93. package/dist/src/session/results/ResultsApi.d.ts +14 -1
  94. package/dist/src/session/runs/Run.d.ts +65 -4
  95. package/dist/src/session/runs/RunsApi.d.ts +58 -2
  96. package/dist/src/session/runs/runId.d.ts +55 -6
  97. package/dist/src/session/runs/types.d.ts +36 -8
  98. package/dist/src/session/scope/ElementMask.d.ts +14 -1
  99. package/dist/src/session/scope/ScopeApi.d.ts +160 -31
  100. package/dist/src/session/scope/index.d.ts +1 -1
  101. package/dist/src/session/selection/SelectionApi.d.ts +15 -10
  102. package/dist/src/session/selection/index.d.ts +1 -1
  103. package/dist/src/session/selection/targets.d.ts +6 -7
  104. package/dist/src/session/sets/SetsApi.d.ts +110 -0
  105. package/dist/src/session/sets/algebra.d.ts +124 -0
  106. package/dist/src/session/sets/cache.d.ts +197 -0
  107. package/dist/src/session/sets/captures.d.ts +83 -0
  108. package/dist/src/session/sets/dependencies.d.ts +167 -0
  109. package/dist/src/session/sets/layers.d.ts +101 -0
  110. package/dist/src/session/sets/notify.d.ts +122 -0
  111. package/dist/src/session/sets/offers.d.ts +103 -0
  112. package/dist/src/session/sets/path.d.ts +37 -0
  113. package/dist/src/session/sets/prepare.d.ts +209 -0
  114. package/dist/src/session/sets/resolve.d.ts +311 -0
  115. package/dist/src/session/sets/signature.d.ts +77 -0
  116. package/dist/src/session/sets/status.d.ts +98 -0
  117. package/dist/src/session/sets/store.d.ts +196 -0
  118. package/dist/src/session/sets/types.d.ts +386 -0
  119. package/dist/src/session/styles/Layer.d.ts +9 -2
  120. package/dist/src/session/styles/StylesApi.d.ts +5 -2
  121. package/dist/src/session/styles/explain.d.ts +5 -2
  122. package/dist/src/session/styles/predicate.d.ts +41 -2
  123. package/dist/src/session/styles/repaint.d.ts +19 -0
  124. package/dist/src/session/styles/selector.d.ts +16 -5
  125. package/dist/src/session/types.d.ts +18 -0
  126. package/dist/src/session/visibility/VisibilityApi.d.ts +47 -3
  127. package/dist/src/session/visibility/filter.d.ts +86 -51
  128. package/dist/src/session/visibility/index.d.ts +1 -1
  129. package/dist/src/testing/fakeAccelerator.d.ts +5 -0
  130. package/dist/src/utils/queue-migration.d.ts +17 -0
  131. package/package.json +15 -9
  132. package/dist/chunks/GraphSession-DuAhRgCd.js +0 -8622
  133. package/dist/chunks/optionsFromZod-B9RncoTX.js +0 -2578
  134. package/dist/chunks/scales-CJCRwi2J.js +0 -3220
  135. package/dist/src/algorithms/utils/index.d.ts +0 -6
@@ -1,9 +1,10 @@
1
1
  import type { SimulationType } from "@graphty/layout";
2
+ import type { Scope, ScopeInput } from "../catalog/types";
2
3
  import type { GraphLayoutBehavior } from "../config/GraphBehavior";
3
4
  import type { Edge } from "../Edge";
4
5
  import { LayoutEngine } from "../layout/LayoutEngine";
5
6
  import { type SimulationEngineOptions } from "../layout/SimulationLayoutEngine";
6
- import type { Node } from "../Node";
7
+ import type { Node, NodeIdType } from "../Node";
7
8
  import type { Styles } from "../Styles";
8
9
  import type { DataManager } from "./DataManager";
9
10
  import type { EventManager } from "./EventManager";
@@ -32,6 +33,31 @@ import type { Manager } from "./interfaces";
32
33
  * @throws A `ZodError` when an option is outside the range its published schema declares.
33
34
  */
34
35
  export declare function resolveSimulationOptions(type: SimulationType, options: Record<string, unknown>, behavior: GraphLayoutBehavior): SimulationEngineOptions;
36
+ /**
37
+ * What a layout manager reads of the session to scope a layout. `Graph` hands its session's in.
38
+ */
39
+ interface LayoutScopeSource {
40
+ /**
41
+ * A write position's scope in canonical form.
42
+ * @param input - The scope as a consumer gave it.
43
+ * @returns The canonical scope.
44
+ * @throws A `GraphtyError` with `E_BAD_COMMAND` when it is not a scope.
45
+ */
46
+ canonical(input: ScopeInput): Scope;
47
+ /**
48
+ * The ids of the nodes a scope covers now.
49
+ * @param scope - The scope.
50
+ * @returns The ids.
51
+ * @throws A `GraphtyError` when the scope cannot be resolved, such as a removed set.
52
+ */
53
+ members(scope: Scope): readonly NodeIdType[];
54
+ /**
55
+ * Whether something the scope names was removed, so it can no longer mean what it meant.
56
+ * @param scope - The scope.
57
+ * @returns True when it is detached.
58
+ */
59
+ detached(scope: Scope): boolean;
60
+ }
35
61
  /**
36
62
  * Manages layout engines and their lifecycle
37
63
  * Coordinates layout updates and transitions
@@ -61,6 +87,20 @@ export declare class LayoutManager implements Manager {
61
87
  */
62
88
  private engineDimension?;
63
89
  private logger;
90
+ /** Where a scope is canonicalised and resolved, once `Graph` has a session to hand in. */
91
+ private scopeSource;
92
+ /**
93
+ * The scope layouts run over, CARRIED from one `setLayout` to the next: an explicit scope sets
94
+ * it, `"graph"` clears it, and a call that names none keeps it, so changing one force
95
+ * parameter never un-scopes the layout. Undefined is the whole graph.
96
+ */
97
+ private carriedScope;
98
+ /**
99
+ * The members the running layout captured when it started, or null when it holds nothing:
100
+ * no scope, an engine that is not scoped, or a scope that could not be resolved. Every node
101
+ * outside it is held, including one that arrives later.
102
+ */
103
+ private members;
64
104
  /**
65
105
  * Gets the running state of the layout
66
106
  * @returns True if layout is running, false otherwise
@@ -161,6 +201,8 @@ export declare class LayoutManager implements Manager {
161
201
  * Used by operations that are already queued to prevent nested queueing
162
202
  * @param layout - A registered engine name, or a catalogue layout id
163
203
  * @param opts - Layout-specific options
204
+ * @param explicitScope - Whether the carried scope was named in this call, which is the only
205
+ * case in which a scope the engine cannot use, or cannot resolve, is refused
164
206
  */
165
207
  private _setLayoutInternal;
166
208
  /**
@@ -206,9 +248,90 @@ export declare class LayoutManager implements Manager {
206
248
  * This goes through the queue when called from Graph
207
249
  * @param type - Layout type identifier
208
250
  * @param opts - Layout-specific options
251
+ * @param scope - What the layout runs over. Absent keeps the carried scope, `"graph"` clears
252
+ * it, and anything else becomes the carried scope for this and later layouts. Internal: a
253
+ * consumer scopes a layout through `Graph.setLayout`'s `options.scope`.
209
254
  * @returns Promise that resolves when layout is set
255
+ * @throws A `GraphtyError` with `E_UNSUPPORTED` for a scope on an engine that is not scoped,
256
+ * or `E_BAD_COMMAND` for a scope that is malformed or names a removed set.
257
+ */
258
+ setLayout(type: string, opts?: object, scope?: ScopeInput): Promise<void>;
259
+ /**
260
+ * Hand the manager the session it resolves scopes through.
261
+ * @param source - The session's canonicaliser and resolver.
262
+ * @internal
263
+ */
264
+ setScopeSource(source: LayoutScopeSource): void;
265
+ /**
266
+ * The scope layouts run over, as the consumer last set it; undefined for the whole graph.
267
+ * @returns The canonical scope.
268
+ * @internal
269
+ */
270
+ get scope(): Scope | undefined;
271
+ /**
272
+ * Change the carried scope without starting a layout. The next layout, and
273
+ * {@link LayoutManager.rescope}, run over it. It never refuses a scope that cannot be resolved:
274
+ * a carried scope that means nothing is inactive.
275
+ * @param scope - The scope; undefined or `"graph"` for the whole graph.
276
+ * @throws A `GraphtyError` with `E_BAD_COMMAND` when it is not a scope.
277
+ * @internal
278
+ */
279
+ carryScope(scope: ScopeInput | undefined): void;
280
+ /**
281
+ * Restart the running layout, with its options, over the carried scope.
282
+ * @returns A promise that resolves once the layout has restarted; at once when none is set.
283
+ * @internal
284
+ */
285
+ rescope(): Promise<void>;
286
+ /**
287
+ * The layout as a user of the sets it names, for "Used by": present only while a layout
288
+ * is actually holding nodes for its scope.
289
+ * @returns The user and the scope, or undefined.
290
+ * @internal
291
+ */
292
+ scopeUser(): {
293
+ readonly user: {
294
+ readonly kind: "layout";
295
+ readonly id?: string;
296
+ readonly label: string;
297
+ };
298
+ readonly scope: Scope;
299
+ } | undefined;
300
+ /**
301
+ * Let go of every held node when the scope the running layout captured names something that was
302
+ * removed, so the layout runs over the whole graph instead. Nothing throws.
303
+ * @internal
304
+ */
305
+ releaseDetachedScope(): void;
306
+ /**
307
+ * The source, or the refusal a manager built without a graph gives for a scope.
308
+ * @returns The source.
309
+ */
310
+ private requireScopeSource;
311
+ /**
312
+ * Capture the members the next layout runs over, or null when it holds nothing.
313
+ * @param scoped - Whether the engine about to be built accepts a scope.
314
+ * @param explicit - Whether the scope came in this call, which is the only case that refuses.
315
+ * @returns The members.
316
+ * @throws The resolver's `GraphtyError` for an explicit scope that cannot be resolved.
317
+ */
318
+ private captureMembers;
319
+ /**
320
+ * The hold mask for the graph as it stands: every row whose node is not a member.
321
+ * @param members - The captured members.
322
+ * @returns The mask and the rows it covers.
323
+ */
324
+ private holdMaskOf;
325
+ /**
326
+ * Tell a freshly built scoped engine where every held node is, and then hold them.
327
+ *
328
+ * Placed first for the reason `replayPins` places before it pins: a live simulation's own idea
329
+ * of where a node is starts wherever its initialisation put it, and d3 fixes a node at that.
330
+ * @param engine - The engine about to become current.
331
+ * @param members - The members it lays out.
332
+ * @param nodes - Every node in the graph.
210
333
  */
211
- setLayout(type: string, opts?: object): Promise<void>;
334
+ private applyHold;
212
335
  /**
213
336
  * Run the configured number of simulation steps, stopping early if the layout arrives.
214
337
  *
@@ -348,3 +471,4 @@ export declare class LayoutManager implements Manager {
348
471
  */
349
472
  updatePositions(nodes: Node[]): Promise<void>;
350
473
  }
474
+ export {};
@@ -24,6 +24,7 @@ interface PerfCounterSnapshot {
24
24
  * Draw calls counter data (includes count in addition to timing)
25
25
  */
26
26
  interface DrawCallsSnapshot extends PerfCounterSnapshot {
27
+ /** How many frames the counter has seen. The last frame's draw calls are `current`. */
27
28
  count: number;
28
29
  }
29
30
  /**
@@ -10,6 +10,11 @@
10
10
  * rather than aspirational: `test/packaging/node-safe-entries.test.ts` resolves the `./session`
11
11
  * entry point's import graph and fails if a renderer appears in it.
12
12
  */
13
+ import type { RuleTree, Scope } from "../catalog/types";
14
+ import { type InputCounters } from "./attributes";
15
+ import { type ScopeResolver } from "./scope";
16
+ import { SetsNotifier } from "./sets/notify";
17
+ import type { SetsApi, SetUser } from "./sets/types";
13
18
  import type { CreateGraphSessionOptions, ElementSession, GraphSession } from "./types";
14
19
  /**
15
20
  * Build a graph session.
@@ -45,3 +50,46 @@ export declare function createGraphSession(options?: CreateGraphSessionOptions):
45
50
  * @returns The session.
46
51
  */
47
52
  export declare function createElementSession(options?: CreateGraphSessionOptions): ElementSession;
53
+ /** What names a set from outside the session, for `usedBy`. */
54
+ type SetsUsersProvider = () => Iterable<{
55
+ readonly user: SetUser;
56
+ readonly scope: Scope | RuleTree;
57
+ }>;
58
+ /**
59
+ * Add users of sets that live outside the session -- the element's running layout -- to what
60
+ * `sets.usedBy` reports. Internal.
61
+ * @param session - a session this module built
62
+ * @param provider - reads the users now
63
+ * @throws An Error for a session this module did not build.
64
+ */
65
+ export declare function addSetsUsers(session: GraphSession, provider: SetsUsersProvider): void;
66
+ /**
67
+ * A session's change notifier and re-resolution scheduler (design/sets 11). Internal.
68
+ * @param session - a session this module built
69
+ * @returns its notifier
70
+ * @throws An Error for a session this module did not build.
71
+ */
72
+ export declare function setsNotifierOfSession(session: GraphSession): SetsNotifier;
73
+ /**
74
+ * A session's scope resolver, with the synchronous doors the published `session.scope` lacks.
75
+ * Internal.
76
+ * @param session - a session this module built
77
+ * @returns its resolver
78
+ * @throws An Error for a session this module did not build.
79
+ */
80
+ export declare function scopeResolverOfSession(session: GraphSession): ScopeResolver;
81
+ /**
82
+ * A session's kept sets. Internal: the tests' spelling of `session.sets`.
83
+ * @param session - a session
84
+ * @returns its sets
85
+ */
86
+ export declare function setsOfSession(session: GraphSession): SetsApi;
87
+ /**
88
+ * A session's input counters: its input tick and its attribute revisions (design/sets 6.2).
89
+ * Internal.
90
+ * @param session - a session this module built
91
+ * @returns its counters
92
+ * @throws An Error for a session this module did not build.
93
+ */
94
+ export declare function inputCountersOfSession(session: GraphSession): InputCounters;
95
+ export {};
@@ -1,14 +1,22 @@
1
1
  /**
2
- * @file What attributes the graph's records carry, described as data.
2
+ * @file What attributes the graph's records carry, described as data -- and the one function that
3
+ * writes them.
3
4
  *
4
5
  * An options form, a filter builder, a colour encoding and a column picker all need the same
5
6
  * four facts about every attribute: what it is called, what type its values are, how many
6
7
  * records actually carry it, and what a few of its values look like. Each of those is a walk
7
8
  * over the graph, so each of them is the element's to do once rather than every consumer's to do
8
9
  * separately.
10
+ *
11
+ * The second half is the writer. A cache over a rule that reads `data.weight` is keyed on the
12
+ * revision of `weight` (design/sets/sets-design.md 6.2), and a revision that some write path forgot
13
+ * to bump is a cache that answers from values nobody holds any more. So every write into a
14
+ * record's `data` goes through {@link writeAttributes} or {@link replaceAttributes}, and
15
+ * `test/session/single-attribute-writer.test.ts` fails on any other.
9
16
  */
10
17
  import type { GraphSnapshot } from "@graphty/graph-format";
11
18
  import type { AttributeDescriptor } from "../catalog/types";
19
+ import type { MovedInput } from "./sets/notify";
12
20
  import { type SessionRecordSource } from "./types";
13
21
  /**
14
22
  * Every attribute the graph's records carry.
@@ -22,3 +30,115 @@ import { type SessionRecordSource } from "./types";
22
30
  * @returns the descriptors, node attributes first
23
31
  */
24
32
  export declare function describeAttributes(snapshot: GraphSnapshot, records: SessionRecordSource | null): readonly AttributeDescriptor[];
33
+ /**
34
+ * One session-wide counter that moves whenever any input a set's resolution can read moves: an
35
+ * attribute revision, a visibility or selection mask version, an execution token or a freeze.
36
+ *
37
+ * A memo keyed on it can never outlive an input it summarises, which is its whole job: a reader
38
+ * that saw the same tick twice knows nothing it could have read has changed in between.
39
+ */
40
+ export declare class InputTick {
41
+ #private;
42
+ /**
43
+ * The current tick.
44
+ * @returns the tick, starting at 0 and only ever growing
45
+ */
46
+ get value(): number;
47
+ /** Move the tick on. Allocation-free, so a freeze can call it inside its commit. */
48
+ advance(): void;
49
+ /**
50
+ * Tell every session over this store that an input moved (design/sets 11). Separate from
51
+ * {@link InputTick.advance}, which moves on every bump: this is said once per write or freeze,
52
+ * after it has landed, by the store owner's side -- a freeze once delivered, an attribute
53
+ * write once per batch.
54
+ * @param input - what moved
55
+ */
56
+ announce(input: MovedInput): void;
57
+ /**
58
+ * Hear every announcement.
59
+ * @param listener - called with each
60
+ * @returns stops listening
61
+ */
62
+ listen(listener: (input: MovedInput) => void): () => void;
63
+ }
64
+ /**
65
+ * Per-field revisions of one element kind's attributes.
66
+ *
67
+ * Keyed by the TOP-LEVEL field, the first segment after `data.`, because that is the granularity a
68
+ * compiled rule's paths name and the granularity a write touches: editing `label` must not
69
+ * invalidate a rule over `weight`.
70
+ */
71
+ export declare class AttributeRevisions {
72
+ #private;
73
+ /**
74
+ * Start every field at revision 0.
75
+ * @param tick - the session tick every bump advances
76
+ */
77
+ constructor(tick: InputTick);
78
+ /**
79
+ * The revision of one field.
80
+ * @param field - the top-level attribute key
81
+ * @returns how many writes have touched it; 0 for a field nothing has written
82
+ */
83
+ of(field: string): number;
84
+ /**
85
+ * Record that one write touched these fields. A write that changed no value still counts:
86
+ * comparing old and new values would cost a deep equality per field for no correctness gain.
87
+ * @param fields - the top-level keys written
88
+ */
89
+ bump(fields: Iterable<string>): void;
90
+ }
91
+ /** The three counters a set's input signature reads, shared by a session and its store's owner. */
92
+ export interface InputCounters {
93
+ /** The session input tick. */
94
+ readonly tick: InputTick;
95
+ /** Node attribute revisions. */
96
+ readonly nodes: AttributeRevisions;
97
+ /** Edge attribute revisions. */
98
+ readonly edges: AttributeRevisions;
99
+ }
100
+ /**
101
+ * The counters of one store owner, created on first ask.
102
+ *
103
+ * Keyed by the object the session is handed as its store: `DataManager` for a rendered graph, which
104
+ * passes the same counters to every `GraphStore` it builds so a Clear never rewinds them, or the
105
+ * `GraphStore` itself for a headless session. A side table rather than a member, so the published
106
+ * `SessionGraphStore` interface gains nothing.
107
+ * @param owner - the store, or whoever builds stores
108
+ * @returns its counters
109
+ */
110
+ export declare function inputCountersOf(owner: object): InputCounters;
111
+ /**
112
+ * Write fields into a record's attributes and bump each field's revision. With `fields` naming
113
+ * only some keys of `update`, only those are written.
114
+ * @param revisions - the revisions of the record's kind
115
+ * @param data - the record's attribute object (`node.data`, `edge.data`)
116
+ * @param update - where the values come from
117
+ * @param fields - the keys to write; every own key of `update` when absent
118
+ */
119
+ export declare function writeAttributes(revisions: AttributeRevisions, data: Record<string, unknown>, update: Readonly<Record<string, unknown>>, fields?: readonly string[]): void;
120
+ /**
121
+ * Write a batch of updates, each into the attributes of the record its `id` names, through
122
+ * {@link writeAttributes}, then announce the fields written once on the input tick, so a live set
123
+ * re-resolves once per batch rather than once per record (design/sets 11). `id` is the address,
124
+ * not an attribute, and is not written; an id with no record is skipped.
125
+ * @param counters - the store owner's counters
126
+ * @param element - which kind of record
127
+ * @param updates - the updates
128
+ * @param dataOf - a record's attribute object by id
129
+ */
130
+ export declare function writeUpdates(counters: InputCounters, element: "node" | "edge", updates: readonly {
131
+ readonly id: string | number;
132
+ readonly [key: string]: unknown;
133
+ }[], dataOf: (id: string | number) => Record<string, unknown> | undefined): void;
134
+ /**
135
+ * Replace a record's attributes wholesale (the `last` repeated-edge policy) and bump every field
136
+ * the old or the new record carries, since a field that disappeared changed too.
137
+ * @param revisions - the revisions of the record's kind
138
+ * @param owner - the object holding `data`
139
+ * @param owner.data - its current attributes
140
+ * @param record - the new attributes, held by reference as the constructor holds the first
141
+ */
142
+ export declare function replaceAttributes<T extends object>(revisions: AttributeRevisions, owner: {
143
+ data: T;
144
+ }, record: T): void;
@@ -235,6 +235,11 @@ export interface CostInput {
235
235
  * same rule written once.
236
236
  */
237
237
  readonly sample?: number;
238
+ /**
239
+ * Seconds spent deriving a scoped run's compact input before the algorithm starts, added to
240
+ * the algorithm's own estimate. Absent for a run over the whole graph.
241
+ */
242
+ readonly derivationSeconds?: number;
238
243
  }
239
244
  /**
240
245
  * What a run would cost, and how much the answer is worth.
@@ -302,8 +307,23 @@ export type CostGateDecision = {
302
307
  /** The error to reject the run with, carrying the facts a consumer switches on. */
303
308
  readonly error: GraphtyError;
304
309
  };
310
+ /** A scope a refused run could be pointed at, sized by whoever holds it: a kept set, today. */
311
+ export interface ScopeCandidate {
312
+ /** The scope specification. */
313
+ readonly scope: Scope;
314
+ /** What to call it on a button: the set's name. */
315
+ readonly label: string;
316
+ /** How many nodes it covers. */
317
+ readonly nodes: number;
318
+ /** How many edges it covers. */
319
+ readonly edges: number;
320
+ /** Seconds to derive its compact input. */
321
+ readonly derivationSeconds: number;
322
+ }
305
323
  /** What the gate is told beyond the estimate's own inputs. */
306
324
  interface CostGateOptions {
325
+ /** The kept sets to suggest when they fit, read only on a refusal. */
326
+ readonly keptSets?: () => readonly ScopeCandidate[];
307
327
  /** The cap and the memory budget. Defaults to {@link DEFAULT_COST_GATE_LIMITS}. */
308
328
  readonly limits?: Readonly<CostGateLimits>;
309
329
  /** Refuse to approximate: above the cap this fails rather than sampling. */
@@ -13,5 +13,5 @@
13
13
  * the frame for 10.4.
14
14
  */
15
15
  export { calibrateCost, calibrateOnce, CostMeasurementLog, currentCalibration, machineFingerprint, resetCalibration, } from "./calibrate";
16
- export type { CostConfidence, CostEstimate, CostGateDecision, CostGateLimits, CostInput, CostMeasurement, MachineCalibration, } from "./estimate";
16
+ export type { CostConfidence, CostEstimate, CostGateDecision, CostGateLimits, CostInput, CostMeasurement, MachineCalibration, ScopeCandidate, } from "./estimate";
17
17
  export { ASSUMED_ITERATION_BOUND, DEFAULT_COST_GATE_LIMITS, DEFAULT_COST_RATES, DEFAULT_EXACT_COMPUTATION_CAP_SECONDS, estimateCost, gateRun, ITERATION_OPTION_NAME, MAX_COLUMN_LENGTH, MEASUREMENT_EXTRAPOLATION_LIMIT, resultBytes, } from "./estimate";
@@ -15,9 +15,9 @@
15
15
  *
16
16
  * Nothing here reaches Babylon.js, Lit or the DOM.
17
17
  */
18
- import type { AlgorithmDescriptor, AlgorithmKey, FieldDescriptor, RunId, Scope } from "../catalog/types";
18
+ import type { AlgorithmDescriptor, AlgorithmKey, FieldDescriptor, RunId, Scope, SetId } from "../catalog/types";
19
19
  import type { GraphtyErrorCode } from "../errors";
20
- import { type CostEstimate, type CostGateLimits, type CostMeasurement, type MachineCalibration } from "./cost";
20
+ import { type CostEstimate, type CostGateLimits, type CostMeasurement, type MachineCalibration, type ScopeCandidate } from "./cost";
21
21
  import type { Caveats, ResolvedScope } from "./runs";
22
22
  import type { GraphStatistics } from "./types";
23
23
  /**
@@ -175,7 +175,37 @@ export interface PlanningContext {
175
175
  readonly calibration?: () => MachineCalibration | undefined;
176
176
  /** Reads the most recent timing of each algorithm on this machine. */
177
177
  readonly measurements?: () => ReadonlyMap<AlgorithmKey, CostMeasurement> | undefined;
178
+ /**
179
+ * The kept sets, in listing order, for the scopes a refused run is pointed at.
180
+ * @returns Each set's id and name.
181
+ */
182
+ readonly keptSets?: () => readonly {
183
+ readonly id: SetId;
184
+ readonly name: string;
185
+ }[];
178
186
  }
187
+ /**
188
+ * The cost of deriving a scope's compact input, in seconds: a + b(N + E) + c(kept edges).
189
+ *
190
+ * Not proportional to the scope: `inducedSubgraph` allocates full-length remaps and scans every
191
+ * edge of the whole graph, then builds the kept edges. Fitted to the design's measured rows
192
+ * (design/sets 6.5, Barabasi-Albert m = 5): 64 ms at 1M / 5M keeping 10% of the nodes and 273 ms
193
+ * keeping 50%, which gives about 9 ns per element of the whole graph and 170 ns per kept edge.
194
+ * ponytail: fixed coefficients from one machine; the timing runners re-fit them, and a calibrated
195
+ * rate replaces them when a derivation is ever timed on the device.
196
+ * @param nodes - Nodes in the whole graph.
197
+ * @param edges - Edges in the whole graph.
198
+ * @param keptEdges - Edges in the scope.
199
+ * @returns The seconds.
200
+ */
201
+ export declare function derivationSeconds(nodes: number, edges: number, keptEdges: number): number;
202
+ /**
203
+ * The kept sets a refused run could be pointed at, sized over the graph as it stands. A set that
204
+ * cannot be resolved now (a detached one) or holds no node is left out.
205
+ * @param context - What planning reads.
206
+ * @returns The candidates, in listing order.
207
+ */
208
+ export declare function keptSetScopes(context: PlanningContext): ScopeCandidate[];
179
209
  /**
180
210
  * What one command would cost, answered synchronously so that a button can be drawn from it.
181
211
  * @param context - What planning reads.
@@ -66,6 +66,13 @@ export interface QueryEngine {
66
66
  * @returns The unresolved paths.
67
67
  */
68
68
  unresolvedPathsOf(where: Query): readonly Path[];
69
+ /**
70
+ * Every path an expression reads, as its node compile sees them: what a cached answer over it
71
+ * is keyed on.
72
+ * @param where - The expression.
73
+ * @returns The paths.
74
+ */
75
+ pathsOf(where: Query): readonly Path[];
69
76
  /**
70
77
  * The nodes a text search finds.
71
78
  * @param text - What was typed.
@@ -16,7 +16,7 @@
16
16
  * published from the Node-safe `./session` entry point.
17
17
  */
18
18
  import type { Path, ResultShape, RunId } from "../../catalog/types";
19
- import { type ResultRoot, type ResultsApi, type RunResult } from "./types";
19
+ import { type ResultRoot, type ResultsApi, type RunRef, type RunResult } from "./types";
20
20
  /**
21
21
  * The few candidates closest to a name somebody got wrong.
22
22
  *
@@ -50,6 +50,12 @@ export interface ResultsRunEntry {
50
50
  readonly shape: ResultShape;
51
51
  /** The result, once the run has published one. */
52
52
  readonly result?: RunResult;
53
+ /**
54
+ * The token of the execution that produced `result`, written with it so whatever restores the
55
+ * result restores its token (design/sets 5.2). Internal: surfaced later only as the opaque
56
+ * `ResultItem.run`.
57
+ */
58
+ readonly execution?: string;
53
59
  }
54
60
  /**
55
61
  * Where the results API looks runs up.
@@ -70,6 +76,13 @@ export interface ResultsRegistry {
70
76
  */
71
77
  entries(): readonly ResultsRunEntry[];
72
78
  }
79
+ /**
80
+ * The execution token of a run's current result, read from its result entry.
81
+ * @param results - A results API this module built.
82
+ * @param run - The run, its result, or its id.
83
+ * @returns The token, or undefined when there is no result or none was minted.
84
+ */
85
+ export declare function resultExecutionOf(results: ResultsApi, run: RunRef): string | undefined;
73
86
  /**
74
87
  * Build the results API over a registry of runs.
75
88
  * @param registry - Where runs are looked up.
@@ -26,8 +26,9 @@
26
26
  import type { AlgorithmKey, FieldDescriptor, ResultShape, RunId } from "../../catalog/types";
27
27
  import { GraphtyError } from "../../errors";
28
28
  import type { ResultSummary, RunResult } from "../results/types";
29
+ import type { HeldCaptures } from "../sets/captures";
29
30
  import { type StyleSuggestion } from "../styles/derive";
30
- import { type Caveats, type EngineVersions, type JournalId, type Progress, type ResolvedScope, type Run, type RunPhase, type RunRecord, type RunStatus, type RunStyle, type StaleNote } from "./types";
31
+ import { type Caveats, type EngineVersions, type JournalId, type Progress, type ResolvedScope, type Run, type RunPhase, type RunRecord, type RunScopeFacts, type RunStatus, type RunStyle, type StaleNote } from "./types";
31
32
  /**
32
33
  * Where a run writes its progress so the element's existing operation events carry it.
33
34
  *
@@ -205,6 +206,12 @@ export interface RunSurroundings {
205
206
  * @returns The resolved scope.
206
207
  */
207
208
  resolveScope(): ResolvedScope;
209
+ /**
210
+ * What the run records about the set its scope names, read when the scope is resolved.
211
+ * Optional: a run with nobody to ask records neither.
212
+ * @returns The facts.
213
+ */
214
+ scopeFacts?(): RunScopeFacts;
208
215
  /**
209
216
  * Hand the run's work to the queue.
210
217
  * @param body - The work.
@@ -220,6 +227,21 @@ export interface RunSurroundings {
220
227
  * @param phase - Which moment.
221
228
  */
222
229
  notify?(phase: RunPhase): void;
230
+ /**
231
+ * Mint the token that identifies one execution of this run (design/sets 5.2): a session nonce
232
+ * plus a session-wide counter. Called once when the work starts. Optional for the same reason
233
+ * as `notify`: a run driven directly by a test has no session to mint from.
234
+ * @returns The token.
235
+ */
236
+ mintExecution?(): string;
237
+ /**
238
+ * Capture what live references hold of the result about to be replaced (design/sets 5.2).
239
+ * Called when a finished run re-executes in place, before its result goes. Optional for the
240
+ * same reason as `notify`.
241
+ * @param prior - The captures the run keeps now.
242
+ * @returns The captures the run keeps from now on.
243
+ */
244
+ captureHeld?(prior: HeldCaptures): HeldCaptures;
223
245
  }
224
246
  /**
225
247
  * A started computation.
@@ -231,8 +253,6 @@ export interface RunSurroundings {
231
253
  export declare class ManagedRun<T = RunResult> implements Run<T> {
232
254
  readonly id: RunId;
233
255
  readonly algorithm: AlgorithmKey;
234
- readonly params: Readonly<Record<string, unknown>>;
235
- readonly seed: number | null;
236
256
  readonly shape: ResultShape;
237
257
  readonly engine: EngineVersions;
238
258
  /**
@@ -243,14 +263,22 @@ export declare class ManagedRun<T = RunResult> implements Run<T> {
243
263
  readonly style: RunStyle;
244
264
  /** The journal has not landed, so every run reports that it wrote no entry. */
245
265
  readonly journalId: JournalId | null;
246
- private readonly definition;
266
+ /** What the run is. Replaced only by {@link ManagedRun.retune}, which changes the parameters and seed. */
267
+ private definition;
247
268
  private readonly surroundings;
248
269
  private scopeValue;
270
+ private scopeFactsValue;
249
271
  private statusValue;
250
272
  private progressValue;
251
273
  private caveatsValue;
252
274
  private fieldsValue;
253
275
  private resultValue;
276
+ /** The token of the execution now running, minted when its work started. */
277
+ private executionValue;
278
+ /** The token of the execution that produced {@link resultValue}, written with it. */
279
+ private resultExecutionValue;
280
+ /** What held references keep of earlier executions: run state, written only by a re-run. */
281
+ private heldValue;
254
282
  private summaryValue;
255
283
  private errorValue;
256
284
  private startedAtValue;
@@ -272,6 +300,16 @@ export declare class ManagedRun<T = RunResult> implements Run<T> {
272
300
  * @param surroundings - What the run asks of the session holding it.
273
301
  */
274
302
  constructor(definition: RunDefinition<T>, surroundings: RunSurroundings);
303
+ /**
304
+ * The parameters the current execution uses, canonicalised.
305
+ * @returns The parameters.
306
+ */
307
+ get params(): Readonly<Record<string, unknown>>;
308
+ /**
309
+ * The seed the current execution uses, or null.
310
+ * @returns The seed.
311
+ */
312
+ get seed(): number | null;
275
313
  /**
276
314
  * What to call this run, computed by the element rather than by the consumer.
277
315
  * @returns The label.
@@ -345,6 +383,18 @@ export declare class ManagedRun<T = RunResult> implements Run<T> {
345
383
  * @returns The result, or undefined until the run succeeds.
346
384
  */
347
385
  get result(): T | undefined;
386
+ /**
387
+ * The execution token of the current result: undefined until a result exists, and for a run
388
+ * whose surroundings mint none. Internal: not on the published `Run` interface.
389
+ * @returns The token.
390
+ */
391
+ get resultExecution(): string | undefined;
392
+ /**
393
+ * The members of earlier executions' items that live references hold, by execution and item
394
+ * key. Internal: not on the published `Run` interface.
395
+ * @returns The captures.
396
+ */
397
+ get held(): HeldCaptures;
348
398
  /**
349
399
  * Why the run failed.
350
400
  * @returns The error, or undefined when it did not.
@@ -386,6 +436,17 @@ export declare class ManagedRun<T = RunResult> implements Run<T> {
386
436
  * @returns This run, restarted.
387
437
  */
388
438
  rerun(): Run<T>;
439
+ /**
440
+ * Run the same result again with other parameters or another seed, keeping its id, so every
441
+ * style layer and reference bound to the result repaints from the new values. Work still
442
+ * queued or running is cancelled first: only the latest parameters' answer matters.
443
+ * @param params - The new parameters, canonicalised.
444
+ * @param seed - The new seed, or null.
445
+ * @param caveats - The caveats the new execution starts from.
446
+ * @returns This run, restarted.
447
+ * @internal
448
+ */
449
+ retune(params: Readonly<Record<string, unknown>>, seed: number | null, caveats: Caveats): Run<T>;
389
450
  /**
390
451
  * What this run suggests be drawn from it.
391
452
  *