@graphty/graphty-element 2.2.5 → 2.3.1

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 (50) hide show
  1. package/dist/ai.js +115 -222
  2. package/dist/catalog.js +56 -55
  3. package/dist/chunks/{AiManager-Bd_r1Hei.js → AiManager-BBmGJbH4.js} +793 -654
  4. package/dist/chunks/{DataSource-Dag8H5US.js → DataSource-OeN3NeyD.js} +1 -1
  5. package/dist/chunks/{GraphSession-mfo75G0q.js → GraphSession-Bef1AYw9.js} +2136 -2104
  6. package/dist/chunks/{GraphStyle-D0PXnZKu.js → GraphStyle-Cwr55SAE.js} +5 -2
  7. package/dist/chunks/{VoiceInputAdapter-DszYl6Ha.js → VoiceInputAdapter-Dr9Gcmds.js} +1 -1
  8. package/dist/chunks/{XRPivotCameraController-BdoMFcON.js → XRPivotCameraController-BbfgZWpS.js} +1 -1
  9. package/dist/chunks/algorithms-CpX56sUB.js +3482 -0
  10. package/dist/chunks/{capability-check-CdoqmrF0.js → capability-check-Blhb2aBB.js} +1 -1
  11. package/dist/chunks/{detect-LAOOaxY_.js → detect-Cqwshr9a.js} +1 -1
  12. package/dist/chunks/{format-detection-a0bD5PIB.js → format-detection-BXGO1lSn.js} +1 -1
  13. package/dist/chunks/{index-BY1gnMiZ.js → index-C0mIoumR.js} +2258 -2129
  14. package/dist/chunks/optionsFromZod-17lkrAJs.js +2565 -0
  15. package/dist/chunks/paletteRegistry-x7WOEKZY.js +1153 -0
  16. package/dist/chunks/scales-BRwl51k8.js +3047 -0
  17. package/dist/custom-elements.json +1 -1
  18. package/dist/extend.js +42 -42
  19. package/dist/graphty-catalog.json +1 -1
  20. package/dist/graphty.bundle.js +25816 -25456
  21. package/dist/graphty.js +29 -29
  22. package/dist/schema.js +1 -1
  23. package/dist/session.d.ts +1 -1
  24. package/dist/session.js +28 -29
  25. package/dist/src/Graph.d.ts +33 -3
  26. package/dist/src/algorithms/metrics/context.d.ts +7 -5
  27. package/dist/src/algorithms/results/types.d.ts +17 -1
  28. package/dist/src/camera/builtins.d.ts +14 -1
  29. package/dist/src/camera/types.d.ts +7 -0
  30. package/dist/src/cameras/CameraManager.d.ts +13 -0
  31. package/dist/src/cameras/OrbitCameraController.d.ts +9 -0
  32. package/dist/src/catalog/types.d.ts +10 -0
  33. package/dist/src/config/GraphStyle.d.ts +5 -1
  34. package/dist/src/config/StyleTemplate.d.ts +2 -2
  35. package/dist/src/graphty-element.d.ts +11 -6
  36. package/dist/src/managers/StylePainter.d.ts +9 -0
  37. package/dist/src/managers/UpdateManager.d.ts +5 -0
  38. package/dist/src/session/results/index.d.ts +1 -1
  39. package/dist/src/session/results/statistics.d.ts +8 -1
  40. package/dist/src/session/results/types.d.ts +33 -0
  41. package/dist/src/session/selection/targets.d.ts +4 -1
  42. package/dist/src/session/styles/predicate.d.ts +26 -1
  43. package/dist/src/session/styles/repaint.d.ts +11 -0
  44. package/dist/src/session/styles/selector.d.ts +13 -1
  45. package/dist/src/session/styles/sources.d.ts +9 -0
  46. package/package.json +1 -1
  47. package/dist/chunks/Algorithm-RQ629NLb.js +0 -494
  48. package/dist/chunks/cameras-ii4vngYY.js +0 -435
  49. package/dist/chunks/paletteRegistry-YSpPryiT.js +0 -3164
  50. package/dist/chunks/scales-DOpwlWuz.js +0 -6086
@@ -115,6 +115,19 @@ export interface SelectorSource {
115
115
  * @returns The indices, or undefined when the column cannot be enumerated.
116
116
  */
117
117
  readonly measured?: (path: Path, target: SelectorTarget) => ArrayLike<number> | undefined;
118
+ /**
119
+ * The lowest value in the top `n` of one run column, cut only between tie groups (see
120
+ * `RunResult.top`), or undefined when nothing is taken or the column is not a ranked run
121
+ * field for this kind of element. Absent, a `{match:"top"}` selector is refused.
122
+ *
123
+ * Asked once per element, so it must answer from something already computed: a session
124
+ * reads it off the run's result, which keeps the answer per field and `n`.
125
+ * @param path - The column path, `results.<run>.<field>`.
126
+ * @param target - Whether the asking layer paints nodes or edges.
127
+ * @param n - The most elements the top may hold.
128
+ * @returns The cut, or undefined.
129
+ */
130
+ readonly topCut?: (path: Path, target: SelectorTarget, n: number) => number | undefined;
118
131
  }
119
132
  /**
120
133
  * One target's half of a {@link SelectorSource}, resolved once so the predicate never chooses.
@@ -160,7 +173,7 @@ export type ElementPredicate = (index: number) => boolean;
160
173
  /** A selector, reduced to the test a repaint runs and the columns that test reads. */
161
174
  export interface CompiledSelector {
162
175
  /** Which selector kind this was compiled from. */
163
- readonly match: "everything" | "expression" | "has" | "ids";
176
+ readonly match: "everything" | "expression" | "has" | "ids" | "top";
164
177
  /** Which kind of element it speaks about. */
165
178
  readonly target: SelectorTarget;
166
179
  /**
@@ -231,6 +244,18 @@ export declare function hasPredicate(columns: ElementColumns, path: Path): Eleme
231
244
  * @returns The test.
232
245
  */
233
246
  export declare function idsPredicate(columns: ElementColumns, ids: ReadonlySet<EdgeId | NodeId>): ElementPredicate;
247
+ /**
248
+ * The predicate for `{match:"top"}`: the element's value is at or above the top's cut.
249
+ *
250
+ * The cut is asked for per element rather than settled here, because a run that finishes or
251
+ * re-runs after the layer was added publishes a new ranking, and a cut captured now would go on
252
+ * painting the old top.
253
+ * @param columns - Where to read values.
254
+ * @param path - The column path.
255
+ * @param cutOf - The lowest value in the top, or undefined when nothing is in it.
256
+ * @returns The test.
257
+ */
258
+ export declare function topPredicate(columns: ElementColumns, path: Path, cutOf: () => number | undefined): ElementPredicate;
234
259
  /**
235
260
  * Parse and compile `{match:"expression"}`.
236
261
  *
@@ -211,6 +211,17 @@ export interface ElementPaint {
211
211
  * @returns A function that stops the notifications.
212
212
  */
213
213
  onPainted(listener: () => void): () => void;
214
+ /**
215
+ * Whether a pass has been asked for and has not finished yet.
216
+ *
217
+ * A pass YIELDS TO THE EVENT LOOP and waits behind the pass in front of it, so between the
218
+ * edit that asks for it and the announcement that ends it there are frames -- as many as the
219
+ * machine is slow. Nothing is in {@link ElementPaint.lastPainted} for those frames, and a
220
+ * renderer that asked only whether paint was waiting to be drawn would call the picture
221
+ * finished, and frame the camera on it, while a node's new size was still on its way.
222
+ * @returns True from the moment a pass is requested until it has announced what it painted.
223
+ */
224
+ painting(): boolean;
214
225
  /**
215
226
  * The layers the last pass could not paint, and why.
216
227
  * @returns The problems, emptied at the start of every pass.
@@ -68,6 +68,17 @@ export type Selector =
68
68
  readonly match: "ids";
69
69
  readonly nodes?: readonly NodeId[];
70
70
  readonly edges?: readonly EdgeId[];
71
+ }
72
+ /**
73
+ * The top `n` elements by one run field, `results.<run>.<field>`, cut only between tie
74
+ * groups: a group of equal values is painted whole, and only when all of it fits inside `n`.
75
+ * So a layer never paints more than `n` elements, and paints none on a graph whose highest
76
+ * value is shared by more than `n`. `RunResult.top` is the same cut with its reason.
77
+ */
78
+ | {
79
+ readonly match: "top";
80
+ readonly path: Path;
81
+ readonly n: number;
71
82
  };
72
83
  /**
73
84
  * Turn a selector into the predicate a repaint runs.
@@ -81,6 +92,7 @@ export type Selector =
81
92
  * @returns The compiled selector: its test, and the columns that test reads.
82
93
  * @throws A `GraphtyError` with code `E_BAD_SELECTOR` when the selector's shape or its
83
94
  * expression is wrong, `E_SELECTOR_EMPTY` when a selector is empty, and `E_UNSUPPORTED`
84
- * when an `ids` selector is offered to a session that cannot say which id sits at which row.
95
+ * when an `ids` selector is offered to a session that cannot say which id sits at which row,
96
+ * or a `top` selector to one that cannot rank a run's column.
85
97
  */
86
98
  export declare function compileSelector(selector: Selector, target: SelectorTarget, source: SelectorSource): CompiledSelector;
@@ -131,6 +131,15 @@ export interface SessionSelectorSource extends SelectorSource {
131
131
  * @returns The indices, ascending, or undefined when the column cannot be enumerated.
132
132
  */
133
133
  readonly measured: (path: Path, target: SelectorTarget) => ArrayLike<number> | undefined;
134
+ /**
135
+ * The lowest value in the top `n` of a run's column, from `RunResult.top`, which keeps it.
136
+ * @param path - The column path, `results.<run>.<field>`.
137
+ * @param target - Whether the asking layer paints nodes or edges.
138
+ * @param n - The most elements the top may hold.
139
+ * @returns The cut, or undefined when nothing is taken or the path names no numeric field of
140
+ * this kind of element.
141
+ */
142
+ readonly topCut: (path: Path, target: SelectorTarget, n: number) => number | undefined;
134
143
  }
135
144
  /**
136
145
  * The id of the node at one end of an edge, for the attribute keys that name an endpoint.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphty/graphty-element",
3
- "version": "2.2.5",
3
+ "version": "2.3.1",
4
4
  "description": "A Web Component library for 3D/2D graph visualization built with Lit and Babylon.js",
5
5
  "type": "module",
6
6
  "customElements": "./dist/custom-elements.json",
@@ -1,494 +0,0 @@
1
- import { q as C } from "./GraphtyLogger-5KEttFUo.js";
2
- import { K as $, f as N } from "./types-B7bX5c0K.js";
3
- import { G as d } from "./GraphtyError-BwcnblTH.js";
4
- import { Graph as _, accelerated as y } from "@graphty/algorithms";
5
- import { INVALID_INDEX as w } from "@graphty/graph-format";
6
- const p = C({
7
- kind: "camera",
8
- idOf: (e) => e.descriptor.id,
9
- descriptorOf: (e) => e.descriptor,
10
- implementationOf: (e) => e.compute,
11
- builtInIds: () => $
12
- });
13
- function K(e, t) {
14
- const s = e.descriptor;
15
- if (s === void 0 || typeof s != "object")
16
- throw new d({
17
- code: "E_BAD_COMMAND",
18
- message: "registerCameraView takes a camera view with a descriptor",
19
- source: "registry",
20
- details: { kind: "camera", field: "descriptor" }
21
- });
22
- if (!Array.isArray(s.modes) || s.modes.length === 0)
23
- throw new d({
24
- code: "E_BAD_COMMAND",
25
- message: `the camera view "${String(s.id)}" declares no drawing modes, so nothing could ever offer it: a view says where it works with \`modes\`, and the element refuses the rest`,
26
- source: "registry",
27
- details: { kind: "camera", name: String(s.id), field: "modes" }
28
- });
29
- if (!Array.isArray(s.options))
30
- throw new d({
31
- code: "E_BAD_COMMAND",
32
- message: `the camera view "${String(s.id)}" declares no options list. A view that takes no configuration declares an empty one, so a form has something to render and the element has something to check a caller's values against`,
33
- source: "registry",
34
- details: { kind: "camera", name: String(s.id), field: "options" }
35
- });
36
- if (typeof e.compute != "function")
37
- throw new d({
38
- code: "E_BAD_COMMAND",
39
- message: `the camera view "${String(s.id)}" was registered without a compute function`,
40
- source: "registry",
41
- details: { kind: "camera", name: String(s.id), field: "compute" }
42
- });
43
- p.register(e, t);
44
- }
45
- function z() {
46
- return p.descriptors();
47
- }
48
- function W(e) {
49
- return p.byId(e);
50
- }
51
- function Y() {
52
- p.clearForTesting();
53
- }
54
- const I = ["forceAtlas2", "fruchtermanReingold", "springElectrical", "release"], k = [
55
- "pageRank",
56
- "sssp",
57
- "breadthFirstSearch",
58
- "connectedComponents",
59
- "weaklyConnectedComponents",
60
- "minimumSpanningTree"
61
- ];
62
- function H(e) {
63
- const t = {
64
- kind: e.backend
65
- };
66
- for (const s of I) {
67
- const r = e[s];
68
- typeof r == "function" && (t[s] = r.bind(e));
69
- }
70
- return t;
71
- }
72
- function R(e) {
73
- const t = {
74
- kind: e.backend
75
- };
76
- for (const s of k) {
77
- const r = e[s];
78
- typeof r == "function" && (t[s] = r.bind(e));
79
- }
80
- return t;
81
- }
82
- const D = ["auto", "off", "required"], Z = "auto";
83
- function X(e) {
84
- return typeof e == "string" && D.includes(e);
85
- }
86
- const M = "f64", J = "f32", Q = "acceleration.minNodes", ee = 0, g = C({
87
- kind: "algorithm",
88
- idOf: (e) => e.descriptor.key,
89
- descriptorOf: (e) => e.descriptor,
90
- implementationOf: (e) => e.descriptor,
91
- builtInIds: () => N
92
- });
93
- function T(e, t) {
94
- if (e.descriptor.key !== e.type)
95
- throw new d({
96
- code: "E_BAD_COMMAND",
97
- message: `the algorithm registered as "${e.namespace}:${e.type}" publishes the catalogue key "${e.descriptor.key}". An algorithm has one name: make "descriptor.key" equal "static type".`,
98
- source: "registry",
99
- details: {
100
- kind: "algorithm",
101
- field: "descriptor.key",
102
- key: e.descriptor.key,
103
- type: e.type,
104
- namespace: e.namespace
105
- }
106
- });
107
- g.register(e, t);
108
- }
109
- function te() {
110
- return g.descriptors();
111
- }
112
- function se(e) {
113
- return g.byId(e);
114
- }
115
- function re() {
116
- g.clearForTesting();
117
- }
118
- class a extends Error {
119
- /**
120
- * Creates an option validation error
121
- * @param optionKey - The key of the option that failed validation
122
- * @param message - The validation error message
123
- */
124
- constructor(t, s) {
125
- super(`Option '${t}': ${s}`), this.optionKey = t, this.name = "OptionValidationError";
126
- }
127
- }
128
- function v(e, t, s) {
129
- if (t == null) {
130
- if (s.required)
131
- throw new a(e, "is required but was not provided");
132
- return;
133
- }
134
- switch (s.type) {
135
- case "number":
136
- A(e, t, s, !1);
137
- break;
138
- case "integer":
139
- A(e, t, s, !0);
140
- break;
141
- case "boolean":
142
- if (typeof t != "boolean")
143
- throw new a(e, `must be a boolean, got ${typeof t}`);
144
- break;
145
- case "string":
146
- if (typeof t != "string")
147
- throw new a(e, `must be a string, got ${typeof t}`);
148
- break;
149
- case "select":
150
- L(e, t, s);
151
- break;
152
- case "nodeId":
153
- if (typeof t != "string" && typeof t != "number")
154
- throw new a(e, `must be a string or number (node ID), got ${typeof t}`);
155
- break;
156
- default:
157
- throw new a(e, `has unknown type '${s.type}'`);
158
- }
159
- }
160
- function A(e, t, s, r) {
161
- if (typeof t != "number")
162
- throw new a(e, `must be a number, got ${typeof t}`);
163
- if (Number.isNaN(t))
164
- throw new a(e, "must not be NaN");
165
- if (!Number.isFinite(t))
166
- throw new a(e, "must be finite");
167
- if (r && !Number.isInteger(t))
168
- throw new a(e, `must be an integer, got ${t}`);
169
- if (s.min !== void 0 && t < s.min)
170
- throw new a(e, `must be >= ${s.min}, got ${t}`);
171
- if (s.max !== void 0 && t > s.max)
172
- throw new a(e, `must be <= ${s.max}, got ${t}`);
173
- }
174
- function L(e, t, s) {
175
- if (!s.options || s.options.length === 0)
176
- throw new a(e, "is a select type but has no options defined");
177
- if (!s.options.map((n) => n.value).includes(t)) {
178
- const n = s.options.map((i) => `'${String(i.value)}'`).join(", ");
179
- throw new a(e, `must be one of [${n}], got '${String(t)}'`);
180
- }
181
- }
182
- function P(e, t) {
183
- const s = {};
184
- for (const [r, n] of Object.entries(e)) {
185
- const c = t?.[r] ?? n.default;
186
- v(r, c, n), s[r] = c;
187
- }
188
- return s;
189
- }
190
- function ne(e) {
191
- return e;
192
- }
193
- function x(e, t) {
194
- const s = e.getSnapshot(), r = t === "directed" ? s : e.undirected(s).snapshot, n = r.flags.multigraph ? r.simplified({ weights: "sum" }).snapshot : r;
195
- return B(n, t);
196
- }
197
- function oe(e) {
198
- const t = e.getSnapshot();
199
- return t.flags.multigraph ? t.edgeCount - t.simplified({ weights: "sum" }).snapshot.edgeCount : 0;
200
- }
201
- function B(e, t) {
202
- const s = new _({
203
- directed: t !== "undirected"
204
- }), { ids: r } = e;
205
- for (let o = 0; o < e.nodeCount; o++)
206
- s.addNode(r.idOf(o));
207
- const { src: n, dst: i, weights: c } = e.edgeList();
208
- for (let o = 0; o < e.edgeCount; o++) {
209
- const u = r.idOf(n[o]), h = r.idOf(i[o]), l = c === null ? 1 : c[o];
210
- s.addEdge(u, h, l);
211
- }
212
- return s;
213
- }
214
- const m = /* @__PURE__ */ new Map();
215
- function F(e, t) {
216
- if (t === null)
217
- return e;
218
- if (e === null)
219
- return t;
220
- const s = new Uint32Array(e.length);
221
- for (let r = 0; r < e.length; r++) {
222
- const n = e[r];
223
- s[r] = n === w ? w : t[n];
224
- }
225
- return s;
226
- }
227
- const O = class O {
228
- /**
229
- * Getter for schema options
230
- *
231
- * Algorithms that use the new schema-based options should access
232
- * options via this getter.
233
- * @returns The resolved schema options
234
- */
235
- get schemaOptions() {
236
- return this._schemaOptions;
237
- }
238
- /**
239
- * Creates a new algorithm instance
240
- * @param g - The graph to run the algorithm on
241
- * @param options - Optional configuration options (uses schema defaults if not provided)
242
- */
243
- constructor(t, s) {
244
- this.graph = t, this._schemaOptions = this.resolveOptions(s);
245
- }
246
- /**
247
- * The `@graphty/algorithms` Graph this run reads, built from the element's graph snapshot.
248
- *
249
- * This is the ONLY way an algorithm should obtain its input. The `Node` and `Edge` objects the
250
- * data manager also holds are render objects -- each `Node` builds a Babylon mesh in its
251
- * constructor -- and reading the graph out of them ties every algorithm to a renderer and to
252
- * whatever part of a data load the scene has caught up with.
253
- * @param mode - the shape this algorithm needs; see {@link AlgorithmGraphMode}
254
- * @returns a freshly built Graph for the algorithm package
255
- */
256
- algorithmGraph(t) {
257
- return x(this.graph.getDataManager(), t);
258
- }
259
- /**
260
- * The route an algorithm with an accelerated implementation takes.
261
- *
262
- * It is the counterpart of {@link algorithmGraph} for the algorithms `@graphty/algorithms`
263
- * can dispatch: instead of copying the snapshot into an object graph, the work runs over the
264
- * snapshot itself, on the attached accelerator or on the index-based CPU port, and the adapter
265
- * writes one loop over an index-aligned result either way.
266
- *
267
- * THE DECISION IS TAKEN ONCE, HERE, BEFORE ANY WORK STARTS. The controller answers "the policy
268
- * is off", "no accelerator", "below `acceleration.minNodes`" or "this accelerator does not
269
- * implement that" up front, and under `acceleration="required"` it throws `E_NO_ACCELERATOR`
270
- * rather than answering quietly. After the work has started there is no second decision: a
271
- * failure from the accelerator propagates with its code and fails the run, because a number
272
- * that silently came from somewhere else is worse than no number.
273
- * @param capability - The accelerator member this work would use, such as `"pageRank"`.
274
- * @param mode - The shape this algorithm needs; see {@link AlgorithmGraphMode}. `"undirected"`
275
- * takes the snapshot's undirected view, which is what collapses a reciprocal pair into one
276
- * edge.
277
- * @returns The snapshot, the edge map onto it, and the runner.
278
- * @example
279
- * ```ts
280
- * const { snapshot, run } = this.accelerated("connectedComponents", "undirected");
281
- * const { value, precision } = await run((dispatch, s) => dispatch.connectedComponents(s));
282
- * const group = value.labels[snapshot.ids.indexOf(nodeId)];
283
- * ```
284
- */
285
- accelerated(t, s) {
286
- const r = this.graph.getDataManager(), n = r.getSnapshot(), i = s === "undirected" ? r.undirected(n) : null, c = i === null ? n : i.snapshot, o = c.flags.multigraph ? c.simplified({ weights: "sum" }) : null, u = o === null ? c : o.snapshot, h = this.graph.acceleration, l = { capability: t, nodeCount: u.nodeCount };
287
- return {
288
- snapshot: u,
289
- edgeRemap: F(i?.edgeRemap ?? null, o?.edgeRemap ?? null),
290
- run: async (b) => {
291
- const f = await h.run(
292
- l,
293
- (S) => b(y(R(S)), u)
294
- );
295
- return f.accelerated ? { value: f.value, precision: f.precision } : { value: await b(y(null), u), precision: M };
296
- }
297
- };
298
- }
299
- /**
300
- * The dense row of a node the reader named in an option.
301
- *
302
- * A search takes its source as an id and the snapshot answers in indices, so this is where the
303
- * two meet -- and where an id that names no node in the graph is reported as what it is: an
304
- * option whose value is outside the permitted range, carrying the option's name and what was
305
- * passed, rather than a silent empty result or a search from row zero.
306
- * @param snapshot - The graph the work runs over.
307
- * @param option - The option the id came from, named in the error.
308
- * @param id - The node id the reader gave.
309
- * @returns The node's dense row.
310
- * @throws A `GraphtyError` with `E_OPTION_RANGE` when the graph has no such node.
311
- */
312
- nodeIndex(t, s, r) {
313
- const n = t.ids.indexOf(r);
314
- if (n === w)
315
- throw new d({
316
- code: "E_OPTION_RANGE",
317
- message: `the graph has no node "${String(r)}", so "${s}" names nothing to run from`,
318
- source: "run",
319
- details: { option: s, value: r }
320
- });
321
- return n;
322
- }
323
- /**
324
- * Resolves and validates options against the schema
325
- * @param options - User-provided options (partial)
326
- * @returns Fully resolved options with defaults applied
327
- */
328
- resolveOptions(t) {
329
- const s = this.constructor.optionsSchema;
330
- return Object.keys(s).length === 0 ? {} : P(s, t);
331
- }
332
- /**
333
- * Gets the algorithm type
334
- * @returns The algorithm type identifier
335
- */
336
- get type() {
337
- return this.constructor.type;
338
- }
339
- /**
340
- * Gets the algorithm namespace
341
- * @returns The algorithm namespace identifier
342
- */
343
- get namespace() {
344
- return this.constructor.namespace;
345
- }
346
- /**
347
- * Compute this algorithm and publish what it produced as a result object.
348
- *
349
- * This is the entry point the run machinery calls, and it is the one that makes an algorithm
350
- * startable as a `Run`: it takes a signal it must throw from, a progress channel, a yield, and
351
- * the run id the result is published under -- and it RETURNS the result rather than writing it
352
- * somewhere a caller has to go looking for. `run()` is the 1.10 entry point beside it, which
353
- * returns nothing and can be neither watched nor stopped.
354
- *
355
- * The default refuses, because an algorithm that has not been migrated genuinely cannot answer
356
- * a run: it publishes through side effects under its own names and has no result object to
357
- * hand back. Both shipped families -- a metric and a declared algorithm -- override it.
358
- * @param _context - A signal, a progress channel and a yield.
359
- * @param runId - The id the result is published under.
360
- * @param _fields - The catalogue's descriptors for this algorithm's fields, when the caller
361
- * holds them.
362
- * @returns The result, or undefined when there was nothing to compute.
363
- * @throws A `GraphtyError` with code `E_UNSUPPORTED` when this algorithm has no result to
364
- * publish.
365
- */
366
- publishResult(t, s, r) {
367
- return Promise.reject(
368
- new d({
369
- code: "E_UNSUPPORTED",
370
- message: `The "${this.namespace}:${this.type}" algorithm writes its result through side effects and cannot be started as a run.`,
371
- source: "run",
372
- target: { kind: "run", id: s },
373
- details: { algorithm: `${this.namespace}:${this.type}` }
374
- })
375
- );
376
- }
377
- /**
378
- * Registers an algorithm class in the global registry
379
- * @param cls - The algorithm class to register
380
- * @returns The registered algorithm class
381
- */
382
- static register(t) {
383
- const s = t, r = String(s.type), n = String(s.namespace), { descriptor: i, cost: c, version: o } = s;
384
- return i !== void 0 && T({
385
- descriptor: i,
386
- namespace: n,
387
- type: r,
388
- ...c === void 0 ? {} : { cost: c },
389
- ...o === void 0 ? {} : { version: o }
390
- }), m.set(`${n}:${r}`, t), t;
391
- }
392
- /**
393
- * Gets an algorithm instance from the registry
394
- * @param g - The graph to run the algorithm on
395
- * @param namespace - The algorithm namespace
396
- * @param type - The algorithm type
397
- * @param options - Optional algorithm-specific options to pass to constructor
398
- * @returns A new instance of the algorithm, or null if not found
399
- */
400
- static get(t, s, r, n) {
401
- const i = m.get(`${s}:${r}`);
402
- return i ? new i(t, n) : null;
403
- }
404
- /**
405
- * Gets an algorithm class from the registry
406
- * @param namespace - The algorithm namespace
407
- * @param type - The algorithm type
408
- * @returns The algorithm class, or null if not found
409
- */
410
- static getClass(t, s) {
411
- return m.get(`${t}:${s}`) ?? null;
412
- }
413
- /**
414
- * Get the options schema for this algorithm
415
- * @returns The options schema, or an empty object if no options defined
416
- * @deprecated Use getZodOptionsSchema() instead
417
- */
418
- static getOptionsSchema() {
419
- return this.optionsSchema;
420
- }
421
- /**
422
- * Check if this algorithm has configurable options
423
- * @returns true if the algorithm has at least one option defined
424
- * @deprecated Use hasZodOptions() instead
425
- */
426
- static hasOptions() {
427
- return Object.keys(this.optionsSchema).length > 0;
428
- }
429
- /**
430
- * Get the Zod-based options schema for this algorithm.
431
- * @returns The Zod options schema, or an empty object if no schema defined
432
- */
433
- static getZodOptionsSchema() {
434
- return this.zodOptionsSchema ?? {};
435
- }
436
- /**
437
- * Check if this algorithm has a Zod-based options schema.
438
- * @returns true if the algorithm has a Zod options schema defined
439
- */
440
- static hasZodOptions() {
441
- return this.zodOptionsSchema !== void 0 && Object.keys(this.zodOptionsSchema).length > 0;
442
- }
443
- /**
444
- * Get all registered algorithm names.
445
- * @param namespace - Optional namespace to filter by
446
- * @returns Array of algorithm names in "namespace:type" format
447
- */
448
- static getRegisteredAlgorithms(t) {
449
- const s = [];
450
- for (const r of m.keys())
451
- (!t || r.startsWith(`${t}:`)) && s.push(r);
452
- return s.sort();
453
- }
454
- /**
455
- * Get all registered algorithm types.
456
- * This method is provided for API consistency with DataSource.
457
- * @returns Array of algorithm keys in "namespace:type" format
458
- * @since 1.5.0
459
- * @example
460
- * ```typescript
461
- * const types = Algorithm.getRegisteredTypes();
462
- * console.log('Available algorithms:', types);
463
- * // ['graphty:betweenness', 'graphty:closeness', 'graphty:degree', ...]
464
- * ```
465
- */
466
- static getRegisteredTypes() {
467
- return this.getRegisteredAlgorithms();
468
- }
469
- };
470
- O.optionsSchema = {};
471
- let E = O;
472
- export {
473
- E as A,
474
- M as C,
475
- J as D,
476
- a as O,
477
- Y as a,
478
- te as b,
479
- re as c,
480
- ne as d,
481
- z as e,
482
- P as f,
483
- D as g,
484
- Z as h,
485
- X as i,
486
- W as j,
487
- ee as k,
488
- Q as l,
489
- se as m,
490
- H as n,
491
- oe as o,
492
- K as r,
493
- v
494
- };