graphwise 1.6.0 → 1.7.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.
@@ -5,22 +5,326 @@ import { n as miniBatchKMeans, r as normaliseFeatures, t as _computeMean } from
5
5
  import { approximateClusteringCoefficient, batchClusteringCoefficients, computeJaccard, countEdgesOfType, countNodesOfType, entropyFromCounts, localClusteringCoefficient, localTypeEntropy, neighbourIntersection, neighbourOverlap, neighbourSet, normalisedEntropy, shannonEntropy } from "../utils/index.js";
6
6
  import { grasp, stratified } from "../seeds/index.js";
7
7
  import { GPUContext, GPUNotAvailableError, assertWebGPUAvailable, createGPUContext, createResultBuffer, csrToGPUBuffers, detectWebGPU, getGPUContext, graphToCSR, isWebGPUAvailable, readBufferToCPU } from "../gpu/index.js";
8
- //#region src/expansion/base.ts
8
+ //#region src/async/utils.ts
9
+ /**
10
+ * Async utility functions.
11
+ *
12
+ * @module async/utils
13
+ */
14
+ /** Collect an AsyncIterable into a readonly array. */
15
+ async function collectAsyncIterable(iter) {
16
+ const result = [];
17
+ for await (const item of iter) result.push(item);
18
+ return result;
19
+ }
20
+ /** Default yield strategy: setTimeout(0) to yield to the event loop. */
21
+ function defaultYieldStrategy() {
22
+ return new Promise((r) => {
23
+ setTimeout(r, 0);
24
+ });
25
+ }
26
+ //#endregion
27
+ //#region src/async/runners.ts
28
+ /**
29
+ * Resolve a single GraphOp against a synchronous ReadableGraph.
30
+ *
31
+ * Returns a tagged GraphOpResponse so the receiving generator can narrow
32
+ * the result type without type assertions.
33
+ *
34
+ * @param graph - The synchronous graph to query
35
+ * @param op - The operation to resolve
36
+ * @returns The tagged response
37
+ */
38
+ function resolveSyncOp(graph, op) {
39
+ switch (op.tag) {
40
+ case "neighbours": return {
41
+ tag: "neighbours",
42
+ value: Array.from(graph.neighbours(op.id, op.direction))
43
+ };
44
+ case "degree": return {
45
+ tag: "degree",
46
+ value: graph.degree(op.id, op.direction)
47
+ };
48
+ case "getNode": return {
49
+ tag: "getNode",
50
+ value: graph.getNode(op.id)
51
+ };
52
+ case "getEdge": return {
53
+ tag: "getEdge",
54
+ value: graph.getEdge(op.source, op.target)
55
+ };
56
+ case "hasNode": return {
57
+ tag: "hasNode",
58
+ value: graph.hasNode(op.id)
59
+ };
60
+ case "yield": return { tag: "yield" };
61
+ case "progress": return { tag: "progress" };
62
+ }
63
+ }
9
64
  /**
10
- * Default priority function - degree-ordered (DOME).
65
+ * Drive a generator to completion using a synchronous graph.
66
+ *
67
+ * The generator yields GraphOp requests; each is resolved immediately
68
+ * against the graph and the tagged response is fed back via gen.next().
69
+ *
70
+ * @param gen - The generator to drive
71
+ * @param graph - The graph to resolve ops against
72
+ * @returns The generator's return value
73
+ */
74
+ function runSync(gen, graph) {
75
+ let step = gen.next();
76
+ while (step.done !== true) {
77
+ const response = resolveSyncOp(graph, step.value);
78
+ step = gen.next(response);
79
+ }
80
+ return step.value;
81
+ }
82
+ /**
83
+ * Resolve a single GraphOp against an async ReadableGraph.
84
+ *
85
+ * AsyncIterables (neighbours) are collected into readonly arrays so the
86
+ * generator receives the same value type as in sync mode. Returns a tagged
87
+ * GraphOpResponse for type-safe narrowing without assertions.
88
+ *
89
+ * @param graph - The async graph to query
90
+ * @param op - The operation to resolve
91
+ * @returns A promise resolving to the tagged response
92
+ */
93
+ async function resolveAsyncOp(graph, op) {
94
+ switch (op.tag) {
95
+ case "neighbours": return {
96
+ tag: "neighbours",
97
+ value: await collectAsyncIterable(graph.neighbours(op.id, op.direction))
98
+ };
99
+ case "degree": return {
100
+ tag: "degree",
101
+ value: await graph.degree(op.id, op.direction)
102
+ };
103
+ case "getNode": return {
104
+ tag: "getNode",
105
+ value: await graph.getNode(op.id)
106
+ };
107
+ case "getEdge": return {
108
+ tag: "getEdge",
109
+ value: await graph.getEdge(op.source, op.target)
110
+ };
111
+ case "hasNode": return {
112
+ tag: "hasNode",
113
+ value: await graph.hasNode(op.id)
114
+ };
115
+ case "yield": return { tag: "yield" };
116
+ case "progress": return { tag: "progress" };
117
+ }
118
+ }
119
+ /**
120
+ * Drive a generator to completion using an async graph.
121
+ *
122
+ * Extends sync semantics with:
123
+ * - Cancellation via AbortSignal (throws DOMException "AbortError")
124
+ * - Cooperative yielding at `yield` ops (calls yieldStrategy)
125
+ * - Progress callbacks at `progress` ops (may be async for backpressure)
126
+ * - Error propagation: graph errors are forwarded via gen.throw(); if the
127
+ * generator does not handle them, they propagate to the caller
128
+ *
129
+ * @param gen - The generator to drive
130
+ * @param graph - The async graph to resolve ops against
131
+ * @param options - Runner configuration
132
+ * @returns A promise resolving to the generator's return value
133
+ */
134
+ async function runAsync(gen, graph, options) {
135
+ const signal = options?.signal;
136
+ const onProgress = options?.onProgress;
137
+ const yieldStrategy = options?.yieldStrategy ?? defaultYieldStrategy;
138
+ let step = gen.next();
139
+ while (step.done !== true) {
140
+ if (signal?.aborted === true) {
141
+ const abortError = new DOMException("Aborted", "AbortError");
142
+ try {
143
+ gen.throw(abortError);
144
+ } catch {
145
+ throw abortError;
146
+ }
147
+ throw abortError;
148
+ }
149
+ const op = step.value;
150
+ if (op.tag === "yield") {
151
+ await yieldStrategy();
152
+ step = gen.next({ tag: "yield" });
153
+ continue;
154
+ }
155
+ if (op.tag === "progress") {
156
+ if (onProgress !== void 0) {
157
+ const maybePromise = onProgress(op.stats);
158
+ if (maybePromise instanceof Promise) await maybePromise;
159
+ }
160
+ step = gen.next({ tag: "progress" });
161
+ continue;
162
+ }
163
+ let response;
164
+ try {
165
+ response = await resolveAsyncOp(graph, op);
166
+ } catch (error) {
167
+ step = gen.throw(error);
168
+ continue;
169
+ }
170
+ step = gen.next(response);
171
+ }
172
+ return step.value;
173
+ }
174
+ //#endregion
175
+ //#region src/async/ops.ts
176
+ function* opNeighbours(id, direction) {
177
+ const response = yield direction !== void 0 ? {
178
+ tag: "neighbours",
179
+ id,
180
+ direction
181
+ } : {
182
+ tag: "neighbours",
183
+ id
184
+ };
185
+ if (response.tag !== "neighbours") throw new TypeError(`Expected neighbours response, got ${response.tag}`);
186
+ return response.value;
187
+ }
188
+ function* opDegree(id, direction) {
189
+ const response = yield direction !== void 0 ? {
190
+ tag: "degree",
191
+ id,
192
+ direction
193
+ } : {
194
+ tag: "degree",
195
+ id
196
+ };
197
+ if (response.tag !== "degree") throw new TypeError(`Expected degree response, got ${response.tag}`);
198
+ return response.value;
199
+ }
200
+ //#endregion
201
+ //#region src/expansion/base-helpers.ts
202
+ /**
203
+ * Check whether expansion should continue given current progress.
204
+ *
205
+ * Returns shouldContinue=false as soon as any configured limit is reached,
206
+ * along with the appropriate termination reason.
207
+ *
208
+ * @param iterations - Number of iterations completed so far
209
+ * @param nodesVisited - Number of distinct nodes visited so far
210
+ * @param pathsFound - Number of paths discovered so far
211
+ * @param limits - Configured expansion limits (0 = unlimited)
212
+ * @returns Whether to continue and the termination reason if stopping
213
+ */
214
+ function continueExpansion(iterations, nodesVisited, pathsFound, limits) {
215
+ if (limits.maxIterations > 0 && iterations >= limits.maxIterations) return {
216
+ shouldContinue: false,
217
+ termination: "limit"
218
+ };
219
+ if (limits.maxNodes > 0 && nodesVisited >= limits.maxNodes) return {
220
+ shouldContinue: false,
221
+ termination: "limit"
222
+ };
223
+ if (limits.maxPaths > 0 && pathsFound >= limits.maxPaths) return {
224
+ shouldContinue: false,
225
+ termination: "limit"
226
+ };
227
+ return {
228
+ shouldContinue: true,
229
+ termination: "exhausted"
230
+ };
231
+ }
232
+ /**
233
+ * Reconstruct path from collision point.
234
+ *
235
+ * Traces backwards through the predecessor maps of both frontiers from the
236
+ * collision node, then concatenates the two halves to form the full path.
237
+ *
238
+ * @param collisionNode - The node where the two frontiers met
239
+ * @param frontierA - Index of the first frontier
240
+ * @param frontierB - Index of the second frontier
241
+ * @param predecessors - Predecessor maps, one per frontier
242
+ * @param seeds - Seed nodes, one per frontier
243
+ * @returns The reconstructed path, or null if seeds are missing
244
+ */
245
+ function reconstructPath$1(collisionNode, frontierA, frontierB, predecessors, seeds) {
246
+ const pathA = [collisionNode];
247
+ const predA = predecessors[frontierA];
248
+ if (predA !== void 0) {
249
+ let node = collisionNode;
250
+ let next = predA.get(node);
251
+ while (next !== null && next !== void 0) {
252
+ node = next;
253
+ pathA.unshift(node);
254
+ next = predA.get(node);
255
+ }
256
+ }
257
+ const pathB = [];
258
+ const predB = predecessors[frontierB];
259
+ if (predB !== void 0) {
260
+ let node = collisionNode;
261
+ let next = predB.get(node);
262
+ while (next !== null && next !== void 0) {
263
+ node = next;
264
+ pathB.push(node);
265
+ next = predB.get(node);
266
+ }
267
+ }
268
+ const fullPath = [...pathA, ...pathB];
269
+ const seedA = seeds[frontierA];
270
+ const seedB = seeds[frontierB];
271
+ if (seedA === void 0 || seedB === void 0) return null;
272
+ return {
273
+ fromSeed: seedA,
274
+ toSeed: seedB,
275
+ nodes: fullPath
276
+ };
277
+ }
278
+ /**
279
+ * Create an empty expansion result for early termination (e.g. no seeds given).
280
+ *
281
+ * @param algorithm - Name of the algorithm producing this result
282
+ * @param startTime - performance.now() timestamp taken before the algorithm began
283
+ * @returns An ExpansionResult with zero paths and zero stats
284
+ */
285
+ function emptyResult$2(algorithm, startTime) {
286
+ return {
287
+ paths: [],
288
+ sampledNodes: /* @__PURE__ */ new Set(),
289
+ sampledEdges: /* @__PURE__ */ new Set(),
290
+ visitedPerFrontier: [],
291
+ stats: {
292
+ iterations: 0,
293
+ nodesVisited: 0,
294
+ edgesTraversed: 0,
295
+ pathsFound: 0,
296
+ durationMs: performance.now() - startTime,
297
+ algorithm,
298
+ termination: "exhausted"
299
+ }
300
+ };
301
+ }
302
+ //#endregion
303
+ //#region src/expansion/base-core.ts
304
+ /**
305
+ * Default priority function — degree-ordered (DOME).
306
+ *
307
+ * Lower degree = higher priority, so sparse nodes are explored before hubs.
11
308
  */
12
309
  function degreePriority(_nodeId, context) {
13
310
  return context.degree;
14
311
  }
15
312
  /**
16
- * Run BASE expansion algorithm.
313
+ * Generator core of the BASE expansion algorithm.
17
314
  *
18
- * @param graph - Source graph
315
+ * Yields GraphOp objects to request graph data, allowing the caller to
316
+ * provide a sync or async runner. The optional `graphRef` parameter is
317
+ * required when the priority function accesses `context.graph` — it is
318
+ * populated in sync mode by `base()`. In async mode (Phase 4+), a proxy
319
+ * graph may be supplied instead.
320
+ *
321
+ * @param graphMeta - Immutable graph metadata (directed, nodeCount, edgeCount)
19
322
  * @param seeds - Seed nodes for expansion
20
- * @param config - Expansion configuration
21
- * @returns Expansion result with discovered paths
323
+ * @param config - Expansion configuration (priority, limits, debug)
324
+ * @param graphRef - Optional real graph reference for context.graph in priority functions
325
+ * @returns An ExpansionResult with all discovered paths and statistics
22
326
  */
23
- function base(graph, seeds, config) {
327
+ function* baseCore(graphMeta, seeds, config, graphRef) {
24
328
  const startTime = performance.now();
25
329
  const { maxNodes = 0, maxIterations = 0, maxPaths = 0, priority = degreePriority, debug = false } = config ?? {};
26
330
  if (seeds.length === 0) return emptyResult$2("base", startTime);
@@ -40,7 +344,8 @@ function base(graph, seeds, config) {
40
344
  predecessors[i]?.set(seedNode, null);
41
345
  combinedVisited.set(seedNode, i);
42
346
  allVisited.add(seedNode);
43
- const seedPriority = priority(seedNode, createPriorityContext(graph, seedNode, i, combinedVisited, allVisited, [], 0));
347
+ const seedDegree = yield* opDegree(seedNode);
348
+ const seedPriority = priority(seedNode, buildPriorityContext(seedNode, i, combinedVisited, allVisited, [], 0, seedDegree, graphRef));
44
349
  queues[i]?.push({
45
350
  nodeId: seedNode,
46
351
  frontierIndex: i,
@@ -52,22 +357,17 @@ function base(graph, seeds, config) {
52
357
  let iterations = 0;
53
358
  let edgesTraversed = 0;
54
359
  let termination = "exhausted";
55
- const continueExpansion = () => {
56
- if (maxIterations > 0 && iterations >= maxIterations) {
57
- termination = "limit";
58
- return false;
59
- }
60
- if (maxNodes > 0 && allVisited.size >= maxNodes) {
61
- termination = "limit";
62
- return false;
63
- }
64
- if (maxPaths > 0 && discoveredPaths.length >= maxPaths) {
65
- termination = "limit";
66
- return false;
67
- }
68
- return true;
360
+ const limits = {
361
+ maxIterations,
362
+ maxNodes,
363
+ maxPaths
69
364
  };
70
- while (continueExpansion()) {
365
+ for (;;) {
366
+ const check = continueExpansion(iterations, allVisited.size, discoveredPaths.length, limits);
367
+ if (!check.shouldContinue) {
368
+ termination = check.termination;
369
+ break;
370
+ }
71
371
  let lowestPriority = Number.POSITIVE_INFINITY;
72
372
  let activeFrontier = -1;
73
373
  for (let i = 0; i < numFrontiers; i++) {
@@ -111,7 +411,7 @@ function base(graph, seeds, config) {
111
411
  }
112
412
  }
113
413
  }
114
- const neighbours = graph.neighbours(nodeId);
414
+ const neighbours = yield* opNeighbours(nodeId);
115
415
  for (const neighbour of neighbours) {
116
416
  edgesTraversed++;
117
417
  const [s, t] = nodeId < neighbour ? [nodeId, neighbour] : [neighbour, nodeId];
@@ -121,9 +421,10 @@ function base(graph, seeds, config) {
121
421
  sampledEdgeMap.set(s, targets);
122
422
  }
123
423
  targets.add(t);
124
- const frontierVisited = visitedByFrontier[activeFrontier];
125
- if (frontierVisited === void 0 || frontierVisited.has(neighbour)) continue;
126
- const neighbourPriority = priority(neighbour, createPriorityContext(graph, neighbour, activeFrontier, combinedVisited, allVisited, discoveredPaths, iterations + 1));
424
+ const fv = visitedByFrontier[activeFrontier];
425
+ if (fv === void 0 || fv.has(neighbour)) continue;
426
+ const neighbourDegree = yield* opDegree(neighbour);
427
+ const neighbourPriority = priority(neighbour, buildPriorityContext(neighbour, activeFrontier, combinedVisited, allVisited, discoveredPaths, iterations + 1, neighbourDegree, graphRef));
127
428
  queue.push({
128
429
  nodeId: neighbour,
129
430
  frontierIndex: activeFrontier,
@@ -153,12 +454,50 @@ function base(graph, seeds, config) {
153
454
  };
154
455
  }
155
456
  /**
156
- * Create priority context for a node.
457
+ * Create a sentinel ReadableGraph that throws if any member is accessed.
458
+ *
459
+ * Used in async mode when no graphRef is provided. Gives a clear error
460
+ * message rather than silently returning incorrect results if a priority
461
+ * function attempts to access `context.graph` before Phase 4b introduces
462
+ * a real async proxy.
157
463
  */
158
- function createPriorityContext(graph, nodeId, frontierIndex, combinedVisited, allVisited, discoveredPaths, iteration) {
464
+ function makeNoGraphSentinel() {
465
+ const msg = "Priority function accessed context.graph in async mode without a graph proxy. Pass a graphRef or use a priority function that does not access context.graph.";
466
+ const fail = () => {
467
+ throw new Error(msg);
468
+ };
159
469
  return {
160
- graph,
161
- degree: graph.degree(nodeId),
470
+ get directed() {
471
+ return fail();
472
+ },
473
+ get nodeCount() {
474
+ return fail();
475
+ },
476
+ get edgeCount() {
477
+ return fail();
478
+ },
479
+ hasNode: fail,
480
+ getNode: fail,
481
+ nodeIds: fail,
482
+ neighbours: fail,
483
+ degree: fail,
484
+ getEdge: fail,
485
+ edges: fail
486
+ };
487
+ }
488
+ /**
489
+ * Build a PriorityContext for a node using a pre-fetched degree.
490
+ *
491
+ * When `graphRef` is provided (sync mode), it is used as `context.graph` so
492
+ * priority functions can access the graph directly. When it is absent (async
493
+ * mode), a Proxy is used in its place that throws a clear error if any
494
+ * property is accessed — this prevents silent failures until Phase 4b
495
+ * introduces a real async proxy graph.
496
+ */
497
+ function buildPriorityContext(_nodeId, frontierIndex, combinedVisited, allVisited, discoveredPaths, iteration, degree, graphRef) {
498
+ return {
499
+ graph: graphRef ?? makeNoGraphSentinel(),
500
+ degree,
162
501
  frontierIndex,
163
502
  visitedByFrontier: combinedVisited,
164
503
  allVisited,
@@ -166,61 +505,55 @@ function createPriorityContext(graph, nodeId, frontierIndex, combinedVisited, al
166
505
  iteration
167
506
  };
168
507
  }
508
+ //#endregion
509
+ //#region src/expansion/base.ts
169
510
  /**
170
- * Reconstruct path from collision point.
511
+ * Run BASE expansion synchronously.
512
+ *
513
+ * Delegates to baseCore + runSync. Behaviour is identical to the previous
514
+ * direct implementation — all existing callers are unaffected.
515
+ *
516
+ * @param graph - Source graph
517
+ * @param seeds - Seed nodes for expansion
518
+ * @param config - Expansion configuration
519
+ * @returns Expansion result with discovered paths
171
520
  */
172
- function reconstructPath$1(collisionNode, frontierA, frontierB, predecessors, seeds) {
173
- const pathA = [collisionNode];
174
- const predA = predecessors[frontierA];
175
- if (predA !== void 0) {
176
- let node = collisionNode;
177
- let next = predA.get(node);
178
- while (next !== null && next !== void 0) {
179
- node = next;
180
- pathA.unshift(node);
181
- next = predA.get(node);
182
- }
183
- }
184
- const pathB = [];
185
- const predB = predecessors[frontierB];
186
- if (predB !== void 0) {
187
- let node = collisionNode;
188
- let next = predB.get(node);
189
- while (next !== null && next !== void 0) {
190
- node = next;
191
- pathB.push(node);
192
- next = predB.get(node);
193
- }
194
- }
195
- const fullPath = [...pathA, ...pathB];
196
- const seedA = seeds[frontierA];
197
- const seedB = seeds[frontierB];
198
- if (seedA === void 0 || seedB === void 0) return null;
199
- return {
200
- fromSeed: seedA,
201
- toSeed: seedB,
202
- nodes: fullPath
203
- };
521
+ function base(graph, seeds, config) {
522
+ return runSync(baseCore({
523
+ directed: graph.directed,
524
+ nodeCount: graph.nodeCount,
525
+ edgeCount: graph.edgeCount
526
+ }, seeds, config, graph), graph);
204
527
  }
205
528
  /**
206
- * Create an empty result for early termination.
207
- */
208
- function emptyResult$2(algorithm, startTime) {
209
- return {
210
- paths: [],
211
- sampledNodes: /* @__PURE__ */ new Set(),
212
- sampledEdges: /* @__PURE__ */ new Set(),
213
- visitedPerFrontier: [],
214
- stats: {
215
- iterations: 0,
216
- nodesVisited: 0,
217
- edgesTraversed: 0,
218
- pathsFound: 0,
219
- durationMs: performance.now() - startTime,
220
- algorithm,
221
- termination: "exhausted"
222
- }
223
- };
529
+ * Run BASE expansion asynchronously.
530
+ *
531
+ * Delegates to baseCore + runAsync. Supports:
532
+ * - Cancellation via AbortSignal (config.signal)
533
+ * - Progress callbacks (config.onProgress)
534
+ * - Custom cooperative yield strategies (config.yieldStrategy)
535
+ *
536
+ * Note: priority functions that access `context.graph` are not supported in
537
+ * async mode without a graph proxy (Phase 4b). The default degree-based
538
+ * priority (DOME) does not access context.graph and works correctly.
539
+ *
540
+ * @param graph - Async source graph
541
+ * @param seeds - Seed nodes for expansion
542
+ * @param config - Expansion and async runner configuration
543
+ * @returns Promise resolving to the expansion result
544
+ */
545
+ async function baseAsync(graph, seeds, config) {
546
+ const [nodeCount, edgeCount] = await Promise.all([graph.nodeCount, graph.edgeCount]);
547
+ const gen = baseCore({
548
+ directed: graph.directed,
549
+ nodeCount,
550
+ edgeCount
551
+ }, seeds, config);
552
+ const runnerOptions = {};
553
+ if (config?.signal !== void 0) runnerOptions.signal = config.signal;
554
+ if (config?.onProgress !== void 0) runnerOptions.onProgress = config.onProgress;
555
+ if (config?.yieldStrategy !== void 0) runnerOptions.yieldStrategy = config.yieldStrategy;
556
+ return runAsync(gen, graph, runnerOptions);
224
557
  }
225
558
  //#endregion
226
559
  //#region src/expansion/dome.ts
@@ -3000,6 +3333,6 @@ function filterSubgraph(graph, options) {
3000
3333
  return result;
3001
3334
  }
3002
3335
  //#endregion
3003
- export { AdjacencyMapGraph, GPUContext, GPUNotAvailableError, PriorityQueue, _computeMean, adamicAdar, adaptive, approximateClusteringCoefficient, assertWebGPUAvailable, base, batchClusteringCoefficients, betweenness, bfs, bfsWithPath, communicability, computeJaccard, computeTrussNumbers, cosine, countEdgesOfType, countNodesOfType, createGPUContext, createResultBuffer, csrToGPUBuffers, degreeSum, detectWebGPU, dfs, dfsPriority, dfsPriorityFn, dfsWithPath, dome, domeHighDegree, edge, entropyFromCounts, enumerateMotifs, enumerateMotifsWithInstances, etch, extractEgoNetwork, extractInducedSubgraph, extractKCore, extractKTruss, filterSubgraph, flux, frontierBalanced, fuse, getGPUContext, getMotifName, graphToCSR, grasp, hae, hittingTime, hubPromoted, isWebGPUAvailable, jaccard, jaccardArithmetic, kHop, katz, lace, localClusteringCoefficient, localTypeEntropy, maze, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, notch, overlapCoefficient, pagerank, parse, pipe, randomPriority, randomRanking, randomWalk, reach, readBufferToCPU, resistanceDistance, resourceAllocation, sage, scale, shannonEntropy, shortest, sift, skew, sorensen, span, standardBfs, stratified, tide, warp, widestPath };
3336
+ export { AdjacencyMapGraph, GPUContext, GPUNotAvailableError, PriorityQueue, _computeMean, adamicAdar, adaptive, approximateClusteringCoefficient, assertWebGPUAvailable, base, baseAsync, batchClusteringCoefficients, betweenness, bfs, bfsWithPath, communicability, computeJaccard, computeTrussNumbers, cosine, countEdgesOfType, countNodesOfType, createGPUContext, createResultBuffer, csrToGPUBuffers, degreeSum, detectWebGPU, dfs, dfsPriority, dfsPriorityFn, dfsWithPath, dome, domeHighDegree, edge, entropyFromCounts, enumerateMotifs, enumerateMotifsWithInstances, etch, extractEgoNetwork, extractInducedSubgraph, extractKCore, extractKTruss, filterSubgraph, flux, frontierBalanced, fuse, getGPUContext, getMotifName, graphToCSR, grasp, hae, hittingTime, hubPromoted, isWebGPUAvailable, jaccard, jaccardArithmetic, kHop, katz, lace, localClusteringCoefficient, localTypeEntropy, maze, miniBatchKMeans, neighbourIntersection, neighbourOverlap, neighbourSet, normaliseFeatures, normaliseFeatures as zScoreNormalise, normalisedEntropy, notch, overlapCoefficient, pagerank, parse, pipe, randomPriority, randomRanking, randomWalk, reach, readBufferToCPU, resistanceDistance, resourceAllocation, sage, scale, shannonEntropy, shortest, sift, skew, sorensen, span, standardBfs, stratified, tide, warp, widestPath };
3004
3337
 
3005
3338
  //# sourceMappingURL=index.js.map