graphwise 1.8.0 → 1.9.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.
- package/dist/adjacency-map-BtKzcuJq.js +229 -0
- package/dist/adjacency-map-BtKzcuJq.js.map +1 -0
- package/dist/adjacency-map-JqBnMNkF.cjs +234 -0
- package/dist/adjacency-map-JqBnMNkF.cjs.map +1 -0
- package/dist/async/index.cjs +15 -242
- package/dist/async/index.js +2 -229
- package/dist/expansion/index.cjs +43 -0
- package/dist/expansion/index.js +2 -0
- package/dist/expansion-ClDhlMK8.js +1704 -0
- package/dist/expansion-ClDhlMK8.js.map +1 -0
- package/dist/expansion-DaTroIyv.cjs +1949 -0
- package/dist/expansion-DaTroIyv.cjs.map +1 -0
- package/dist/extraction/index.cjs +630 -0
- package/dist/extraction/index.cjs.map +1 -0
- package/dist/extraction/index.js +621 -0
- package/dist/extraction/index.js.map +1 -0
- package/dist/gpu/csr.d.ts +29 -30
- package/dist/gpu/csr.d.ts.map +1 -1
- package/dist/gpu/dispatch.d.ts +31 -0
- package/dist/gpu/dispatch.d.ts.map +1 -0
- package/dist/gpu/dispatch.unit.test.d.ts +5 -0
- package/dist/gpu/dispatch.unit.test.d.ts.map +1 -0
- package/dist/gpu/index.cjs +15 -410
- package/dist/gpu/index.d.ts +3 -1
- package/dist/gpu/index.d.ts.map +1 -1
- package/dist/gpu/index.js +2 -400
- package/dist/gpu/kernels/bfs/kernel.d.ts +59 -0
- package/dist/gpu/kernels/bfs/kernel.d.ts.map +1 -0
- package/dist/gpu/kernels/bfs/logic.d.ts +47 -0
- package/dist/gpu/kernels/bfs/logic.d.ts.map +1 -0
- package/dist/gpu/kernels/bfs/logic.unit.test.d.ts +2 -0
- package/dist/gpu/kernels/bfs/logic.unit.test.d.ts.map +1 -0
- package/dist/gpu/kernels/degree-histogram/kernel.d.ts +32 -0
- package/dist/gpu/kernels/degree-histogram/kernel.d.ts.map +1 -0
- package/dist/gpu/kernels/degree-histogram/logic.d.ts +45 -0
- package/dist/gpu/kernels/degree-histogram/logic.d.ts.map +1 -0
- package/dist/gpu/kernels/degree-histogram/logic.unit.test.d.ts +2 -0
- package/dist/gpu/kernels/degree-histogram/logic.unit.test.d.ts.map +1 -0
- package/dist/gpu/kernels/jaccard/kernel.d.ts +40 -0
- package/dist/gpu/kernels/jaccard/kernel.d.ts.map +1 -0
- package/dist/gpu/kernels/jaccard/logic.d.ts +43 -0
- package/dist/gpu/kernels/jaccard/logic.d.ts.map +1 -0
- package/dist/gpu/kernels/jaccard/logic.unit.test.d.ts +2 -0
- package/dist/gpu/kernels/jaccard/logic.unit.test.d.ts.map +1 -0
- package/dist/gpu/kernels/pagerank/kernel.d.ts +44 -0
- package/dist/gpu/kernels/pagerank/kernel.d.ts.map +1 -0
- package/dist/gpu/kernels/pagerank/logic.d.ts +50 -0
- package/dist/gpu/kernels/pagerank/logic.d.ts.map +1 -0
- package/dist/gpu/kernels/pagerank/logic.unit.test.d.ts +2 -0
- package/dist/gpu/kernels/pagerank/logic.unit.test.d.ts.map +1 -0
- package/dist/gpu/kernels/spmv/kernel.d.ts +43 -0
- package/dist/gpu/kernels/spmv/kernel.d.ts.map +1 -0
- package/dist/gpu/kernels/spmv/logic.d.ts +31 -0
- package/dist/gpu/kernels/spmv/logic.d.ts.map +1 -0
- package/dist/gpu/kernels/spmv/logic.unit.test.d.ts +2 -0
- package/dist/gpu/kernels/spmv/logic.unit.test.d.ts.map +1 -0
- package/dist/gpu/operations.d.ts +76 -0
- package/dist/gpu/operations.d.ts.map +1 -0
- package/dist/gpu/operations.unit.test.d.ts +5 -0
- package/dist/gpu/operations.unit.test.d.ts.map +1 -0
- package/dist/gpu/root.d.ts +53 -0
- package/dist/gpu/root.d.ts.map +1 -0
- package/dist/gpu/root.unit.test.d.ts +2 -0
- package/dist/gpu/root.unit.test.d.ts.map +1 -0
- package/dist/gpu/types.d.ts +3 -8
- package/dist/gpu/types.d.ts.map +1 -1
- package/dist/gpu-CHiCN0wa.js +16945 -0
- package/dist/gpu-CHiCN0wa.js.map +1 -0
- package/dist/gpu-Y6owRVMi.cjs +17028 -0
- package/dist/gpu-Y6owRVMi.cjs.map +1 -0
- package/dist/graph/index.cjs +2 -229
- package/dist/graph/index.js +1 -228
- package/dist/index/index.cjs +141 -4040
- package/dist/index/index.js +15 -3917
- package/dist/jaccard-3rCdilwm.js +39 -0
- package/dist/jaccard-3rCdilwm.js.map +1 -0
- package/dist/jaccard-Bys9_dGW.cjs +50 -0
- package/dist/jaccard-Bys9_dGW.cjs.map +1 -0
- package/dist/{kmeans-BIgSyGKu.cjs → kmeans-B8x9D1kt.cjs} +1 -1
- package/dist/{kmeans-BIgSyGKu.cjs.map → kmeans-B8x9D1kt.cjs.map} +1 -1
- package/dist/{kmeans-87ExSUNZ.js → kmeans-DKkL9rAN.js} +1 -1
- package/dist/{kmeans-87ExSUNZ.js.map → kmeans-DKkL9rAN.js.map} +1 -1
- package/dist/ops-djAsQQSh.cjs +277 -0
- package/dist/ops-djAsQQSh.cjs.map +1 -0
- package/dist/ops-upIi6JIi.js +212 -0
- package/dist/ops-upIi6JIi.js.map +1 -0
- package/dist/priority-queue-BIiD1L0k.cjs +148 -0
- package/dist/priority-queue-BIiD1L0k.cjs.map +1 -0
- package/dist/priority-queue-CFDd5cBg.js +143 -0
- package/dist/priority-queue-CFDd5cBg.js.map +1 -0
- package/dist/ranking/index.cjs +43 -0
- package/dist/ranking/index.js +4 -0
- package/dist/ranking/mi/index.cjs +581 -0
- package/dist/ranking/mi/index.cjs.map +1 -0
- package/dist/ranking/mi/index.js +555 -0
- package/dist/ranking/mi/index.js.map +1 -0
- package/dist/ranking-3ez5m67U.js +1016 -0
- package/dist/ranking-3ez5m67U.js.map +1 -0
- package/dist/ranking-DVvajgUZ.cjs +1093 -0
- package/dist/ranking-DVvajgUZ.cjs.map +1 -0
- package/dist/seeds/index.cjs +1 -1
- package/dist/seeds/index.js +1 -1
- package/dist/structures/index.cjs +2 -143
- package/dist/structures/index.js +1 -142
- package/dist/utils/index.cjs +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils-BodeE2Mo.js +22 -0
- package/dist/utils-BodeE2Mo.js.map +1 -0
- package/dist/utils-CDtCcsyF.cjs +33 -0
- package/dist/utils-CDtCcsyF.cjs.map +1 -0
- package/package.json +3 -1
- package/dist/async/index.cjs.map +0 -1
- package/dist/async/index.js.map +0 -1
- package/dist/gpu/context.d.ts +0 -118
- package/dist/gpu/context.d.ts.map +0 -1
- package/dist/gpu/context.unit.test.d.ts +0 -2
- package/dist/gpu/context.unit.test.d.ts.map +0 -1
- package/dist/gpu/index.cjs.map +0 -1
- package/dist/gpu/index.js.map +0 -1
- package/dist/graph/index.cjs.map +0 -1
- package/dist/graph/index.js.map +0 -1
- package/dist/index/index.cjs.map +0 -1
- package/dist/index/index.js.map +0 -1
- package/dist/structures/index.cjs.map +0 -1
- package/dist/structures/index.js.map +0 -1
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { n as defaultYieldStrategy, t as collectAsyncIterable } from "./utils-BodeE2Mo.js";
|
|
2
|
+
//#region src/async/runners.ts
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a single GraphOp against a synchronous ReadableGraph.
|
|
5
|
+
*
|
|
6
|
+
* Returns a tagged GraphOpResponse so the receiving generator can narrow
|
|
7
|
+
* the result type without type assertions.
|
|
8
|
+
*
|
|
9
|
+
* @param graph - The synchronous graph to query
|
|
10
|
+
* @param op - The operation to resolve
|
|
11
|
+
* @returns The tagged response
|
|
12
|
+
*/
|
|
13
|
+
function resolveSyncOp(graph, op) {
|
|
14
|
+
switch (op.tag) {
|
|
15
|
+
case "neighbours": return {
|
|
16
|
+
tag: "neighbours",
|
|
17
|
+
value: Array.from(graph.neighbours(op.id, op.direction))
|
|
18
|
+
};
|
|
19
|
+
case "degree": return {
|
|
20
|
+
tag: "degree",
|
|
21
|
+
value: graph.degree(op.id, op.direction)
|
|
22
|
+
};
|
|
23
|
+
case "getNode": return {
|
|
24
|
+
tag: "getNode",
|
|
25
|
+
value: graph.getNode(op.id)
|
|
26
|
+
};
|
|
27
|
+
case "getEdge": return {
|
|
28
|
+
tag: "getEdge",
|
|
29
|
+
value: graph.getEdge(op.source, op.target)
|
|
30
|
+
};
|
|
31
|
+
case "hasNode": return {
|
|
32
|
+
tag: "hasNode",
|
|
33
|
+
value: graph.hasNode(op.id)
|
|
34
|
+
};
|
|
35
|
+
case "yield": return { tag: "yield" };
|
|
36
|
+
case "progress": return { tag: "progress" };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Drive a generator to completion using a synchronous graph.
|
|
41
|
+
*
|
|
42
|
+
* The generator yields GraphOp requests; each is resolved immediately
|
|
43
|
+
* against the graph and the tagged response is fed back via gen.next().
|
|
44
|
+
*
|
|
45
|
+
* @param gen - The generator to drive
|
|
46
|
+
* @param graph - The graph to resolve ops against
|
|
47
|
+
* @returns The generator's return value
|
|
48
|
+
*/
|
|
49
|
+
function runSync(gen, graph) {
|
|
50
|
+
let step = gen.next();
|
|
51
|
+
while (step.done !== true) {
|
|
52
|
+
const response = resolveSyncOp(graph, step.value);
|
|
53
|
+
step = gen.next(response);
|
|
54
|
+
}
|
|
55
|
+
return step.value;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve a single GraphOp against an async ReadableGraph.
|
|
59
|
+
*
|
|
60
|
+
* AsyncIterables (neighbours) are collected into readonly arrays so the
|
|
61
|
+
* generator receives the same value type as in sync mode. Returns a tagged
|
|
62
|
+
* GraphOpResponse for type-safe narrowing without assertions.
|
|
63
|
+
*
|
|
64
|
+
* @param graph - The async graph to query
|
|
65
|
+
* @param op - The operation to resolve
|
|
66
|
+
* @returns A promise resolving to the tagged response
|
|
67
|
+
*/
|
|
68
|
+
async function resolveAsyncOp(graph, op) {
|
|
69
|
+
switch (op.tag) {
|
|
70
|
+
case "neighbours": return {
|
|
71
|
+
tag: "neighbours",
|
|
72
|
+
value: await collectAsyncIterable(graph.neighbours(op.id, op.direction))
|
|
73
|
+
};
|
|
74
|
+
case "degree": return {
|
|
75
|
+
tag: "degree",
|
|
76
|
+
value: await graph.degree(op.id, op.direction)
|
|
77
|
+
};
|
|
78
|
+
case "getNode": return {
|
|
79
|
+
tag: "getNode",
|
|
80
|
+
value: await graph.getNode(op.id)
|
|
81
|
+
};
|
|
82
|
+
case "getEdge": return {
|
|
83
|
+
tag: "getEdge",
|
|
84
|
+
value: await graph.getEdge(op.source, op.target)
|
|
85
|
+
};
|
|
86
|
+
case "hasNode": return {
|
|
87
|
+
tag: "hasNode",
|
|
88
|
+
value: await graph.hasNode(op.id)
|
|
89
|
+
};
|
|
90
|
+
case "yield": return { tag: "yield" };
|
|
91
|
+
case "progress": return { tag: "progress" };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Drive a generator to completion using an async graph.
|
|
96
|
+
*
|
|
97
|
+
* Extends sync semantics with:
|
|
98
|
+
* - Cancellation via AbortSignal (throws DOMException "AbortError")
|
|
99
|
+
* - Cooperative yielding at `yield` ops (calls yieldStrategy)
|
|
100
|
+
* - Progress callbacks at `progress` ops (may be async for backpressure)
|
|
101
|
+
* - Error propagation: graph errors are forwarded via gen.throw(); if the
|
|
102
|
+
* generator does not handle them, they propagate to the caller
|
|
103
|
+
*
|
|
104
|
+
* @param gen - The generator to drive
|
|
105
|
+
* @param graph - The async graph to resolve ops against
|
|
106
|
+
* @param options - Runner configuration
|
|
107
|
+
* @returns A promise resolving to the generator's return value
|
|
108
|
+
*/
|
|
109
|
+
async function runAsync(gen, graph, options) {
|
|
110
|
+
const signal = options?.signal;
|
|
111
|
+
const onProgress = options?.onProgress;
|
|
112
|
+
const yieldStrategy = options?.yieldStrategy ?? defaultYieldStrategy;
|
|
113
|
+
let step = gen.next();
|
|
114
|
+
while (step.done !== true) {
|
|
115
|
+
if (signal?.aborted === true) {
|
|
116
|
+
const abortError = new DOMException("Aborted", "AbortError");
|
|
117
|
+
try {
|
|
118
|
+
gen.throw(abortError);
|
|
119
|
+
} catch {
|
|
120
|
+
throw abortError;
|
|
121
|
+
}
|
|
122
|
+
throw abortError;
|
|
123
|
+
}
|
|
124
|
+
const op = step.value;
|
|
125
|
+
if (op.tag === "yield") {
|
|
126
|
+
await yieldStrategy();
|
|
127
|
+
step = gen.next({ tag: "yield" });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (op.tag === "progress") {
|
|
131
|
+
if (onProgress !== void 0) {
|
|
132
|
+
const maybePromise = onProgress(op.stats);
|
|
133
|
+
if (maybePromise instanceof Promise) await maybePromise;
|
|
134
|
+
}
|
|
135
|
+
step = gen.next({ tag: "progress" });
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
let response;
|
|
139
|
+
try {
|
|
140
|
+
response = await resolveAsyncOp(graph, op);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
step = gen.throw(error);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
step = gen.next(response);
|
|
146
|
+
}
|
|
147
|
+
return step.value;
|
|
148
|
+
}
|
|
149
|
+
//#endregion
|
|
150
|
+
//#region src/async/ops.ts
|
|
151
|
+
function* opNeighbours(id, direction) {
|
|
152
|
+
const response = yield direction !== void 0 ? {
|
|
153
|
+
tag: "neighbours",
|
|
154
|
+
id,
|
|
155
|
+
direction
|
|
156
|
+
} : {
|
|
157
|
+
tag: "neighbours",
|
|
158
|
+
id
|
|
159
|
+
};
|
|
160
|
+
if (response.tag !== "neighbours") throw new TypeError(`Expected neighbours response, got ${response.tag}`);
|
|
161
|
+
return response.value;
|
|
162
|
+
}
|
|
163
|
+
function* opDegree(id, direction) {
|
|
164
|
+
const response = yield direction !== void 0 ? {
|
|
165
|
+
tag: "degree",
|
|
166
|
+
id,
|
|
167
|
+
direction
|
|
168
|
+
} : {
|
|
169
|
+
tag: "degree",
|
|
170
|
+
id
|
|
171
|
+
};
|
|
172
|
+
if (response.tag !== "degree") throw new TypeError(`Expected degree response, got ${response.tag}`);
|
|
173
|
+
return response.value;
|
|
174
|
+
}
|
|
175
|
+
function* opGetNode(id) {
|
|
176
|
+
const response = yield {
|
|
177
|
+
tag: "getNode",
|
|
178
|
+
id
|
|
179
|
+
};
|
|
180
|
+
if (response.tag !== "getNode") throw new TypeError(`Expected getNode response, got ${response.tag}`);
|
|
181
|
+
return response.value;
|
|
182
|
+
}
|
|
183
|
+
function* opGetEdge(source, target) {
|
|
184
|
+
const response = yield {
|
|
185
|
+
tag: "getEdge",
|
|
186
|
+
source,
|
|
187
|
+
target
|
|
188
|
+
};
|
|
189
|
+
if (response.tag !== "getEdge") throw new TypeError(`Expected getEdge response, got ${response.tag}`);
|
|
190
|
+
return response.value;
|
|
191
|
+
}
|
|
192
|
+
function* opHasNode(id) {
|
|
193
|
+
const response = yield {
|
|
194
|
+
tag: "hasNode",
|
|
195
|
+
id
|
|
196
|
+
};
|
|
197
|
+
if (response.tag !== "hasNode") throw new TypeError(`Expected hasNode response, got ${response.tag}`);
|
|
198
|
+
return response.value;
|
|
199
|
+
}
|
|
200
|
+
function* opYield() {
|
|
201
|
+
yield { tag: "yield" };
|
|
202
|
+
}
|
|
203
|
+
function* opProgress(stats) {
|
|
204
|
+
yield {
|
|
205
|
+
tag: "progress",
|
|
206
|
+
stats
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
export { opNeighbours as a, resolveAsyncOp as c, runSync as d, opHasNode as i, resolveSyncOp as l, opGetEdge as n, opProgress as o, opGetNode as r, opYield as s, opDegree as t, runAsync as u };
|
|
211
|
+
|
|
212
|
+
//# sourceMappingURL=ops-upIi6JIi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ops-upIi6JIi.js","names":[],"sources":["../src/async/runners.ts","../src/async/ops.ts"],"sourcesContent":["/**\n * Sync and async runners for generator-based graph algorithms.\n *\n * The runner drives a generator that yields GraphOp objects, resolves each op\n * against the graph, and feeds the result back via gen.next(response). This\n * allows algorithm logic to be written once as a generator and executed\n * synchronously or asynchronously depending on the graph backing.\n *\n * @module async/runners\n */\n\nimport type { NodeData, EdgeData, ReadableGraph } from \"../graph\";\nimport type { AsyncReadableGraph } from \"../graph/async-interfaces\";\nimport type { GraphOp, GraphOpResponse } from \"./protocol\";\nimport type { AsyncRunnerOptions } from \"./types\";\nimport { collectAsyncIterable, defaultYieldStrategy } from \"./utils\";\n\n// ---------------------------------------------------------------------------\n// Sync runner\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a single GraphOp against a synchronous ReadableGraph.\n *\n * Returns a tagged GraphOpResponse so the receiving generator can narrow\n * the result type without type assertions.\n *\n * @param graph - The synchronous graph to query\n * @param op - The operation to resolve\n * @returns The tagged response\n */\nexport function resolveSyncOp<N extends NodeData, E extends EdgeData>(\n\tgraph: ReadableGraph<N, E>,\n\top: GraphOp,\n): GraphOpResponse<N, E> {\n\tswitch (op.tag) {\n\t\tcase \"neighbours\":\n\t\t\treturn {\n\t\t\t\ttag: \"neighbours\",\n\t\t\t\tvalue: Array.from(graph.neighbours(op.id, op.direction)),\n\t\t\t};\n\t\tcase \"degree\":\n\t\t\treturn { tag: \"degree\", value: graph.degree(op.id, op.direction) };\n\t\tcase \"getNode\":\n\t\t\treturn { tag: \"getNode\", value: graph.getNode(op.id) };\n\t\tcase \"getEdge\":\n\t\t\treturn { tag: \"getEdge\", value: graph.getEdge(op.source, op.target) };\n\t\tcase \"hasNode\":\n\t\t\treturn { tag: \"hasNode\", value: graph.hasNode(op.id) };\n\t\tcase \"yield\":\n\t\t\treturn { tag: \"yield\" };\n\t\tcase \"progress\":\n\t\t\treturn { tag: \"progress\" };\n\t}\n}\n\n/**\n * Drive a generator to completion using a synchronous graph.\n *\n * The generator yields GraphOp requests; each is resolved immediately\n * against the graph and the tagged response is fed back via gen.next().\n *\n * @param gen - The generator to drive\n * @param graph - The graph to resolve ops against\n * @returns The generator's return value\n */\nexport function runSync<N extends NodeData, E extends EdgeData, R>(\n\tgen: Generator<GraphOp, R, GraphOpResponse<N, E>>,\n\tgraph: ReadableGraph<N, E>,\n): R {\n\tlet step = gen.next();\n\twhile (step.done !== true) {\n\t\tconst response = resolveSyncOp(graph, step.value);\n\t\tstep = gen.next(response);\n\t}\n\treturn step.value;\n}\n\n// ---------------------------------------------------------------------------\n// Async runner\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a single GraphOp against an async ReadableGraph.\n *\n * AsyncIterables (neighbours) are collected into readonly arrays so the\n * generator receives the same value type as in sync mode. Returns a tagged\n * GraphOpResponse for type-safe narrowing without assertions.\n *\n * @param graph - The async graph to query\n * @param op - The operation to resolve\n * @returns A promise resolving to the tagged response\n */\nexport async function resolveAsyncOp<N extends NodeData, E extends EdgeData>(\n\tgraph: AsyncReadableGraph<N, E>,\n\top: GraphOp,\n): Promise<GraphOpResponse<N, E>> {\n\tswitch (op.tag) {\n\t\tcase \"neighbours\":\n\t\t\treturn {\n\t\t\t\ttag: \"neighbours\",\n\t\t\t\tvalue: await collectAsyncIterable(\n\t\t\t\t\tgraph.neighbours(op.id, op.direction),\n\t\t\t\t),\n\t\t\t};\n\t\tcase \"degree\":\n\t\t\treturn { tag: \"degree\", value: await graph.degree(op.id, op.direction) };\n\t\tcase \"getNode\":\n\t\t\treturn { tag: \"getNode\", value: await graph.getNode(op.id) };\n\t\tcase \"getEdge\":\n\t\t\treturn {\n\t\t\t\ttag: \"getEdge\",\n\t\t\t\tvalue: await graph.getEdge(op.source, op.target),\n\t\t\t};\n\t\tcase \"hasNode\":\n\t\t\treturn { tag: \"hasNode\", value: await graph.hasNode(op.id) };\n\t\tcase \"yield\":\n\t\t\treturn { tag: \"yield\" };\n\t\tcase \"progress\":\n\t\t\treturn { tag: \"progress\" };\n\t}\n}\n\n/**\n * Drive a generator to completion using an async graph.\n *\n * Extends sync semantics with:\n * - Cancellation via AbortSignal (throws DOMException \"AbortError\")\n * - Cooperative yielding at `yield` ops (calls yieldStrategy)\n * - Progress callbacks at `progress` ops (may be async for backpressure)\n * - Error propagation: graph errors are forwarded via gen.throw(); if the\n * generator does not handle them, they propagate to the caller\n *\n * @param gen - The generator to drive\n * @param graph - The async graph to resolve ops against\n * @param options - Runner configuration\n * @returns A promise resolving to the generator's return value\n */\nexport async function runAsync<N extends NodeData, E extends EdgeData, R>(\n\tgen: Generator<GraphOp, R, GraphOpResponse<N, E>>,\n\tgraph: AsyncReadableGraph<N, E>,\n\toptions?: AsyncRunnerOptions,\n): Promise<R> {\n\tconst signal = options?.signal;\n\tconst onProgress = options?.onProgress;\n\tconst yieldStrategy = options?.yieldStrategy ?? defaultYieldStrategy;\n\n\tlet step = gen.next();\n\n\twhile (step.done !== true) {\n\t\t// Check for cancellation before processing each op. Throw the error\n\t\t// into the generator so that any finally blocks in the algorithm run\n\t\t// before the error propagates to the caller.\n\t\tif (signal?.aborted === true) {\n\t\t\tconst abortError = new DOMException(\"Aborted\", \"AbortError\");\n\t\t\ttry {\n\t\t\t\tgen.throw(abortError);\n\t\t\t} catch {\n\t\t\t\t// Generator did not handle the error — propagate it\n\t\t\t\tthrow abortError;\n\t\t\t}\n\t\t\t// Generator handled the error but we still honour cancellation\n\t\t\tthrow abortError;\n\t\t}\n\n\t\tconst op = step.value;\n\n\t\t// Handle cooperative yield ops without hitting the graph\n\t\tif (op.tag === \"yield\") {\n\t\t\tawait yieldStrategy();\n\t\t\tstep = gen.next({ tag: \"yield\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Handle progress ops: call the callback (awaiting if async)\n\t\tif (op.tag === \"progress\") {\n\t\t\tif (onProgress !== undefined) {\n\t\t\t\tconst maybePromise = onProgress(op.stats);\n\t\t\t\tif (maybePromise instanceof Promise) {\n\t\t\t\t\tawait maybePromise;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstep = gen.next({ tag: \"progress\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Resolve graph ops, forwarding any errors into the generator\n\t\tlet response: GraphOpResponse<N, E>;\n\t\ttry {\n\t\t\tresponse = await resolveAsyncOp(graph, op);\n\t\t} catch (error) {\n\t\t\t// Forward the error into the generator; if unhandled, it propagates\n\t\t\tstep = gen.throw(error);\n\t\t\tcontinue;\n\t\t}\n\n\t\tstep = gen.next(response);\n\t}\n\n\treturn step.value;\n}\n","/**\n * Type-safe yield helpers for graph operations.\n *\n * Each function is a sub-generator that yields one GraphOp and returns\n * the correctly-typed result. Narrowing is done via the tagged discriminated\n * union in GraphOpResponse — no type assertions needed.\n *\n * Use with `yield*` inside algorithm generators.\n *\n * @module async/ops\n */\n\nimport type { NodeId, NodeData, EdgeData, Direction } from \"../graph\";\nimport type { GraphOp, GraphOpResponse, ProgressStats } from \"./protocol\";\n\nexport function* opNeighbours<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(\n\tid: NodeId,\n\tdirection?: Direction,\n): Generator<GraphOp, readonly NodeId[], GraphOpResponse<N, E>> {\n\tconst op: GraphOp =\n\t\tdirection !== undefined\n\t\t\t? { tag: \"neighbours\", id, direction }\n\t\t\t: { tag: \"neighbours\", id };\n\tconst response: GraphOpResponse<N, E> = yield op;\n\tif (response.tag !== \"neighbours\") {\n\t\tthrow new TypeError(`Expected neighbours response, got ${response.tag}`);\n\t}\n\treturn response.value;\n}\n\nexport function* opDegree<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(\n\tid: NodeId,\n\tdirection?: Direction,\n): Generator<GraphOp, number, GraphOpResponse<N, E>> {\n\tconst op: GraphOp =\n\t\tdirection !== undefined\n\t\t\t? { tag: \"degree\", id, direction }\n\t\t\t: { tag: \"degree\", id };\n\tconst response: GraphOpResponse<N, E> = yield op;\n\tif (response.tag !== \"degree\") {\n\t\tthrow new TypeError(`Expected degree response, got ${response.tag}`);\n\t}\n\treturn response.value;\n}\n\nexport function* opGetNode<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(id: NodeId): Generator<GraphOp, N | undefined, GraphOpResponse<N, E>> {\n\tconst response: GraphOpResponse<N, E> = yield { tag: \"getNode\", id };\n\tif (response.tag !== \"getNode\") {\n\t\tthrow new TypeError(`Expected getNode response, got ${response.tag}`);\n\t}\n\treturn response.value;\n}\n\nexport function* opGetEdge<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(\n\tsource: NodeId,\n\ttarget: NodeId,\n): Generator<GraphOp, E | undefined, GraphOpResponse<N, E>> {\n\tconst response: GraphOpResponse<N, E> = yield {\n\t\ttag: \"getEdge\",\n\t\tsource,\n\t\ttarget,\n\t};\n\tif (response.tag !== \"getEdge\") {\n\t\tthrow new TypeError(`Expected getEdge response, got ${response.tag}`);\n\t}\n\treturn response.value;\n}\n\nexport function* opHasNode<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(id: NodeId): Generator<GraphOp, boolean, GraphOpResponse<N, E>> {\n\tconst response: GraphOpResponse<N, E> = yield { tag: \"hasNode\", id };\n\tif (response.tag !== \"hasNode\") {\n\t\tthrow new TypeError(`Expected hasNode response, got ${response.tag}`);\n\t}\n\treturn response.value;\n}\n\nexport function* opYield<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(): Generator<GraphOp, void, GraphOpResponse<N, E>> {\n\tyield { tag: \"yield\" };\n}\n\nexport function* opProgress<\n\tN extends NodeData = NodeData,\n\tE extends EdgeData = EdgeData,\n>(stats: ProgressStats): Generator<GraphOp, void, GraphOpResponse<N, E>> {\n\tyield { tag: \"progress\", stats };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
//#region src/structures/priority-queue.ts
|
|
2
|
+
/**
|
|
3
|
+
* Min-heap priority queue implementation using an array-based binary heap.
|
|
4
|
+
* Lower priority values have higher precedence (extracted first).
|
|
5
|
+
*/
|
|
6
|
+
var PriorityQueue = class {
|
|
7
|
+
heap = [];
|
|
8
|
+
indexMap = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Returns the number of items in the queue.
|
|
11
|
+
*/
|
|
12
|
+
size() {
|
|
13
|
+
return this.heap.length;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns true if the queue is empty.
|
|
17
|
+
*/
|
|
18
|
+
isEmpty() {
|
|
19
|
+
return this.heap.length === 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Adds an item with the given priority to the queue.
|
|
23
|
+
*/
|
|
24
|
+
push(item, priority) {
|
|
25
|
+
const entry = {
|
|
26
|
+
item,
|
|
27
|
+
priority
|
|
28
|
+
};
|
|
29
|
+
this.heap.push(entry);
|
|
30
|
+
this.indexMap.set(item, this.heap.length - 1);
|
|
31
|
+
this.heapifyUp(this.heap.length - 1);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Removes and returns the highest precedence item (lowest priority value).
|
|
35
|
+
* Returns undefined if the queue is empty.
|
|
36
|
+
*/
|
|
37
|
+
pop() {
|
|
38
|
+
if (this.heap.length === 0) return;
|
|
39
|
+
const root = this.heap[0];
|
|
40
|
+
if (root === void 0) return;
|
|
41
|
+
this.indexMap.delete(root.item);
|
|
42
|
+
const last = this.heap.pop();
|
|
43
|
+
if (last === void 0) return root;
|
|
44
|
+
if (this.heap.length > 0) {
|
|
45
|
+
this.heap[0] = last;
|
|
46
|
+
this.indexMap.set(last.item, 0);
|
|
47
|
+
this.heapifyDown(0);
|
|
48
|
+
}
|
|
49
|
+
return root;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the highest precedence item without removing it.
|
|
53
|
+
* Returns undefined if the queue is empty.
|
|
54
|
+
*/
|
|
55
|
+
peek() {
|
|
56
|
+
return this.heap[0];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Rebuilds the heap from the current array state.
|
|
60
|
+
* Useful when priorities have been modified externally (e.g., phase transitions).
|
|
61
|
+
*/
|
|
62
|
+
rebuild() {
|
|
63
|
+
const start = Math.floor(this.heap.length / 2) - 1;
|
|
64
|
+
for (let i = start; i >= 0; i--) this.heapifyDown(i);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Decreases the priority of an existing item in the queue.
|
|
68
|
+
* Returns true if the item was found and updated, false otherwise.
|
|
69
|
+
*
|
|
70
|
+
* @param item - The item to find
|
|
71
|
+
* @param newPriority - The new (lower) priority value
|
|
72
|
+
* @param equals - Function to compare items for equality. If provided, uses linear search;
|
|
73
|
+
* otherwise uses O(1) reference-based lookup.
|
|
74
|
+
*/
|
|
75
|
+
decreaseKey(item, newPriority, equals) {
|
|
76
|
+
let foundIndex = -1;
|
|
77
|
+
if (equals !== void 0) for (let i = 0; i < this.heap.length; i++) {
|
|
78
|
+
const entry = this.heap[i];
|
|
79
|
+
if (entry !== void 0 && equals(entry.item, item)) {
|
|
80
|
+
foundIndex = i;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else foundIndex = this.indexMap.get(item) ?? -1;
|
|
85
|
+
if (foundIndex === -1) return false;
|
|
86
|
+
const entry = this.heap[foundIndex];
|
|
87
|
+
if (entry === void 0) return false;
|
|
88
|
+
if (newPriority >= entry.priority) return false;
|
|
89
|
+
entry.priority = newPriority;
|
|
90
|
+
this.heapifyUp(foundIndex);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Restores heap property by moving element up from given index.
|
|
95
|
+
*/
|
|
96
|
+
heapifyUp(index) {
|
|
97
|
+
let current = index;
|
|
98
|
+
while (current > 0) {
|
|
99
|
+
const parent = Math.floor((current - 1) / 2);
|
|
100
|
+
const currentEntry = this.heap[current];
|
|
101
|
+
const parentEntry = this.heap[parent];
|
|
102
|
+
if (currentEntry === void 0 || parentEntry === void 0) return;
|
|
103
|
+
if (currentEntry.priority >= parentEntry.priority) return;
|
|
104
|
+
this.heap[current] = parentEntry;
|
|
105
|
+
this.heap[parent] = currentEntry;
|
|
106
|
+
this.indexMap.set(parentEntry.item, current);
|
|
107
|
+
this.indexMap.set(currentEntry.item, parent);
|
|
108
|
+
current = parent;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Restores heap property by moving element down from given index.
|
|
113
|
+
*/
|
|
114
|
+
heapifyDown(index) {
|
|
115
|
+
let current = index;
|
|
116
|
+
const length = this.heap.length;
|
|
117
|
+
while (current < length) {
|
|
118
|
+
const left = 2 * current + 1;
|
|
119
|
+
const right = 2 * current + 2;
|
|
120
|
+
let smallest = current;
|
|
121
|
+
const currentEntry = this.heap[current];
|
|
122
|
+
if (currentEntry === void 0) return;
|
|
123
|
+
const leftEntry = this.heap[left];
|
|
124
|
+
if (left < length && leftEntry !== void 0 && leftEntry.priority < currentEntry.priority) smallest = left;
|
|
125
|
+
const rightEntry = this.heap[right];
|
|
126
|
+
const currentSmallestEntry = this.heap[smallest];
|
|
127
|
+
if (right < length && rightEntry !== void 0 && currentSmallestEntry !== void 0 && rightEntry.priority < currentSmallestEntry.priority) smallest = right;
|
|
128
|
+
if (smallest === current) return;
|
|
129
|
+
const finalSmallestEntry = this.heap[smallest];
|
|
130
|
+
if (finalSmallestEntry !== void 0) {
|
|
131
|
+
this.heap[current] = finalSmallestEntry;
|
|
132
|
+
this.heap[smallest] = currentEntry;
|
|
133
|
+
this.indexMap.set(finalSmallestEntry.item, current);
|
|
134
|
+
this.indexMap.set(currentEntry.item, smallest);
|
|
135
|
+
current = smallest;
|
|
136
|
+
} else return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
Object.defineProperty(exports, "PriorityQueue", {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function() {
|
|
144
|
+
return PriorityQueue;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
//# sourceMappingURL=priority-queue-BIiD1L0k.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority-queue-BIiD1L0k.cjs","names":[],"sources":["../src/structures/priority-queue.ts"],"sourcesContent":["/**\n * Priority queue entry containing an item and its priority.\n */\nexport interface PriorityEntry<T> {\n\titem: T;\n\tpriority: number;\n}\n\n/**\n * Min-heap priority queue implementation using an array-based binary heap.\n * Lower priority values have higher precedence (extracted first).\n */\nexport class PriorityQueue<T> {\n\tprivate heap: PriorityEntry<T>[] = [];\n\tprivate indexMap = new Map<T, number>();\n\n\t/**\n\t * Returns the number of items in the queue.\n\t */\n\tpublic size(): number {\n\t\treturn this.heap.length;\n\t}\n\n\t/**\n\t * Returns true if the queue is empty.\n\t */\n\tpublic isEmpty(): boolean {\n\t\treturn this.heap.length === 0;\n\t}\n\n\t/**\n\t * Adds an item with the given priority to the queue.\n\t */\n\tpublic push(item: T, priority: number): void {\n\t\tconst entry: PriorityEntry<T> = { item, priority };\n\t\tthis.heap.push(entry);\n\t\tthis.indexMap.set(item, this.heap.length - 1);\n\t\tthis.heapifyUp(this.heap.length - 1);\n\t}\n\n\t/**\n\t * Removes and returns the highest precedence item (lowest priority value).\n\t * Returns undefined if the queue is empty.\n\t */\n\tpublic pop(): PriorityEntry<T> | undefined {\n\t\tif (this.heap.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst root = this.heap[0];\n\t\tif (root === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthis.indexMap.delete(root.item);\n\n\t\tconst last = this.heap.pop();\n\t\tif (last === undefined) {\n\t\t\treturn root;\n\t\t}\n\n\t\tif (this.heap.length > 0) {\n\t\t\tthis.heap[0] = last;\n\t\t\tthis.indexMap.set(last.item, 0);\n\t\t\tthis.heapifyDown(0);\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Returns the highest precedence item without removing it.\n\t * Returns undefined if the queue is empty.\n\t */\n\tpublic peek(): PriorityEntry<T> | undefined {\n\t\treturn this.heap[0];\n\t}\n\n\t/**\n\t * Rebuilds the heap from the current array state.\n\t * Useful when priorities have been modified externally (e.g., phase transitions).\n\t */\n\tpublic rebuild(): void {\n\t\t// Floyd's algorithm: heapify down from last non-leaf to root\n\t\tconst start = Math.floor(this.heap.length / 2) - 1;\n\t\tfor (let i = start; i >= 0; i--) {\n\t\t\tthis.heapifyDown(i);\n\t\t}\n\t}\n\n\t/**\n\t * Decreases the priority of an existing item in the queue.\n\t * Returns true if the item was found and updated, false otherwise.\n\t *\n\t * @param item - The item to find\n\t * @param newPriority - The new (lower) priority value\n\t * @param equals - Function to compare items for equality. If provided, uses linear search;\n\t * otherwise uses O(1) reference-based lookup.\n\t */\n\tpublic decreaseKey(\n\t\titem: T,\n\t\tnewPriority: number,\n\t\tequals?: (a: T, b: T) => boolean,\n\t): boolean {\n\t\tlet foundIndex = -1;\n\n\t\t// If equals function provided, use linear search for custom equality\n\t\tif (equals !== undefined) {\n\t\t\tfor (let i = 0; i < this.heap.length; i++) {\n\t\t\t\tconst entry = this.heap[i];\n\t\t\t\tif (entry !== undefined && equals(entry.item, item)) {\n\t\t\t\t\tfoundIndex = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Use O(1) reference-based lookup via indexMap\n\t\t\tfoundIndex = this.indexMap.get(item) ?? -1;\n\t\t}\n\n\t\tif (foundIndex === -1) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst entry = this.heap[foundIndex];\n\t\tif (entry === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Only update if new priority is lower (higher precedence)\n\t\tif (newPriority >= entry.priority) {\n\t\t\treturn false;\n\t\t}\n\n\t\tentry.priority = newPriority;\n\t\tthis.heapifyUp(foundIndex);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Restores heap property by moving element up from given index.\n\t */\n\tprivate heapifyUp(index: number): void {\n\t\tlet current = index;\n\n\t\twhile (current > 0) {\n\t\t\tconst parent = Math.floor((current - 1) / 2);\n\t\t\tconst currentEntry = this.heap[current];\n\t\t\tconst parentEntry = this.heap[parent];\n\n\t\t\tif (currentEntry === undefined || parentEntry === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (currentEntry.priority >= parentEntry.priority) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Swap current and parent\n\t\t\tthis.heap[current] = parentEntry;\n\t\t\tthis.heap[parent] = currentEntry;\n\t\t\t// Update indexMap after swap\n\t\t\tthis.indexMap.set(parentEntry.item, current);\n\t\t\tthis.indexMap.set(currentEntry.item, parent);\n\t\t\tcurrent = parent;\n\t\t}\n\t}\n\n\t/**\n\t * Restores heap property by moving element down from given index.\n\t */\n\tprivate heapifyDown(index: number): void {\n\t\tlet current = index;\n\t\tconst length = this.heap.length;\n\n\t\twhile (current < length) {\n\t\t\tconst left = 2 * current + 1;\n\t\t\tconst right = 2 * current + 2;\n\t\t\tlet smallest = current;\n\n\t\t\tconst currentEntry = this.heap[current];\n\t\t\tif (currentEntry === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Compare with left child\n\t\t\tconst leftEntry = this.heap[left];\n\t\t\tif (\n\t\t\t\tleft < length &&\n\t\t\t\tleftEntry !== undefined &&\n\t\t\t\tleftEntry.priority < currentEntry.priority\n\t\t\t) {\n\t\t\t\tsmallest = left;\n\t\t\t}\n\n\t\t\t// Compare with right child (need to re-fetch smallest after potential update)\n\t\t\tconst rightEntry = this.heap[right];\n\t\t\tconst currentSmallestEntry = this.heap[smallest];\n\t\t\tif (\n\t\t\t\tright < length &&\n\t\t\t\trightEntry !== undefined &&\n\t\t\t\tcurrentSmallestEntry !== undefined &&\n\t\t\t\trightEntry.priority < currentSmallestEntry.priority\n\t\t\t) {\n\t\t\t\tsmallest = right;\n\t\t\t}\n\n\t\t\tif (smallest === current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get the final smallest entry (after determining final smallest index)\n\t\t\tconst finalSmallestEntry = this.heap[smallest];\n\t\t\tif (finalSmallestEntry !== undefined) {\n\t\t\t\tthis.heap[current] = finalSmallestEntry;\n\t\t\t\tthis.heap[smallest] = currentEntry;\n\t\t\t\t// Update indexMap after swap\n\t\t\t\tthis.indexMap.set(finalSmallestEntry.item, current);\n\t\t\t\tthis.indexMap.set(currentEntry.item, smallest);\n\t\t\t\tcurrent = smallest;\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":";;;;;AAYA,IAAa,gBAAb,MAA8B;CAC7B,OAAmC,EAAE;CACrC,2BAAmB,IAAI,KAAgB;;;;CAKvC,OAAsB;AACrB,SAAO,KAAK,KAAK;;;;;CAMlB,UAA0B;AACzB,SAAO,KAAK,KAAK,WAAW;;;;;CAM7B,KAAY,MAAS,UAAwB;EAC5C,MAAM,QAA0B;GAAE;GAAM;GAAU;AAClD,OAAK,KAAK,KAAK,MAAM;AACrB,OAAK,SAAS,IAAI,MAAM,KAAK,KAAK,SAAS,EAAE;AAC7C,OAAK,UAAU,KAAK,KAAK,SAAS,EAAE;;;;;;CAOrC,MAA2C;AAC1C,MAAI,KAAK,KAAK,WAAW,EACxB;EAGD,MAAM,OAAO,KAAK,KAAK;AACvB,MAAI,SAAS,KAAA,EACZ;AAGD,OAAK,SAAS,OAAO,KAAK,KAAK;EAE/B,MAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,MAAI,SAAS,KAAA,EACZ,QAAO;AAGR,MAAI,KAAK,KAAK,SAAS,GAAG;AACzB,QAAK,KAAK,KAAK;AACf,QAAK,SAAS,IAAI,KAAK,MAAM,EAAE;AAC/B,QAAK,YAAY,EAAE;;AAGpB,SAAO;;;;;;CAOR,OAA4C;AAC3C,SAAO,KAAK,KAAK;;;;;;CAOlB,UAAuB;EAEtB,MAAM,QAAQ,KAAK,MAAM,KAAK,KAAK,SAAS,EAAE,GAAG;AACjD,OAAK,IAAI,IAAI,OAAO,KAAK,GAAG,IAC3B,MAAK,YAAY,EAAE;;;;;;;;;;;CAarB,YACC,MACA,aACA,QACU;EACV,IAAI,aAAa;AAGjB,MAAI,WAAW,KAAA,EACd,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;GAC1C,MAAM,QAAQ,KAAK,KAAK;AACxB,OAAI,UAAU,KAAA,KAAa,OAAO,MAAM,MAAM,KAAK,EAAE;AACpD,iBAAa;AACb;;;MAKF,cAAa,KAAK,SAAS,IAAI,KAAK,IAAI;AAGzC,MAAI,eAAe,GAClB,QAAO;EAGR,MAAM,QAAQ,KAAK,KAAK;AACxB,MAAI,UAAU,KAAA,EACb,QAAO;AAIR,MAAI,eAAe,MAAM,SACxB,QAAO;AAGR,QAAM,WAAW;AACjB,OAAK,UAAU,WAAW;AAC1B,SAAO;;;;;CAMR,UAAkB,OAAqB;EACtC,IAAI,UAAU;AAEd,SAAO,UAAU,GAAG;GACnB,MAAM,SAAS,KAAK,OAAO,UAAU,KAAK,EAAE;GAC5C,MAAM,eAAe,KAAK,KAAK;GAC/B,MAAM,cAAc,KAAK,KAAK;AAE9B,OAAI,iBAAiB,KAAA,KAAa,gBAAgB,KAAA,EACjD;AAGD,OAAI,aAAa,YAAY,YAAY,SACxC;AAID,QAAK,KAAK,WAAW;AACrB,QAAK,KAAK,UAAU;AAEpB,QAAK,SAAS,IAAI,YAAY,MAAM,QAAQ;AAC5C,QAAK,SAAS,IAAI,aAAa,MAAM,OAAO;AAC5C,aAAU;;;;;;CAOZ,YAAoB,OAAqB;EACxC,IAAI,UAAU;EACd,MAAM,SAAS,KAAK,KAAK;AAEzB,SAAO,UAAU,QAAQ;GACxB,MAAM,OAAO,IAAI,UAAU;GAC3B,MAAM,QAAQ,IAAI,UAAU;GAC5B,IAAI,WAAW;GAEf,MAAM,eAAe,KAAK,KAAK;AAC/B,OAAI,iBAAiB,KAAA,EACpB;GAID,MAAM,YAAY,KAAK,KAAK;AAC5B,OACC,OAAO,UACP,cAAc,KAAA,KACd,UAAU,WAAW,aAAa,SAElC,YAAW;GAIZ,MAAM,aAAa,KAAK,KAAK;GAC7B,MAAM,uBAAuB,KAAK,KAAK;AACvC,OACC,QAAQ,UACR,eAAe,KAAA,KACf,yBAAyB,KAAA,KACzB,WAAW,WAAW,qBAAqB,SAE3C,YAAW;AAGZ,OAAI,aAAa,QAChB;GAID,MAAM,qBAAqB,KAAK,KAAK;AACrC,OAAI,uBAAuB,KAAA,GAAW;AACrC,SAAK,KAAK,WAAW;AACrB,SAAK,KAAK,YAAY;AAEtB,SAAK,SAAS,IAAI,mBAAmB,MAAM,QAAQ;AACnD,SAAK,SAAS,IAAI,aAAa,MAAM,SAAS;AAC9C,cAAU;SAEV"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
//#region src/structures/priority-queue.ts
|
|
2
|
+
/**
|
|
3
|
+
* Min-heap priority queue implementation using an array-based binary heap.
|
|
4
|
+
* Lower priority values have higher precedence (extracted first).
|
|
5
|
+
*/
|
|
6
|
+
var PriorityQueue = class {
|
|
7
|
+
heap = [];
|
|
8
|
+
indexMap = /* @__PURE__ */ new Map();
|
|
9
|
+
/**
|
|
10
|
+
* Returns the number of items in the queue.
|
|
11
|
+
*/
|
|
12
|
+
size() {
|
|
13
|
+
return this.heap.length;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Returns true if the queue is empty.
|
|
17
|
+
*/
|
|
18
|
+
isEmpty() {
|
|
19
|
+
return this.heap.length === 0;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Adds an item with the given priority to the queue.
|
|
23
|
+
*/
|
|
24
|
+
push(item, priority) {
|
|
25
|
+
const entry = {
|
|
26
|
+
item,
|
|
27
|
+
priority
|
|
28
|
+
};
|
|
29
|
+
this.heap.push(entry);
|
|
30
|
+
this.indexMap.set(item, this.heap.length - 1);
|
|
31
|
+
this.heapifyUp(this.heap.length - 1);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Removes and returns the highest precedence item (lowest priority value).
|
|
35
|
+
* Returns undefined if the queue is empty.
|
|
36
|
+
*/
|
|
37
|
+
pop() {
|
|
38
|
+
if (this.heap.length === 0) return;
|
|
39
|
+
const root = this.heap[0];
|
|
40
|
+
if (root === void 0) return;
|
|
41
|
+
this.indexMap.delete(root.item);
|
|
42
|
+
const last = this.heap.pop();
|
|
43
|
+
if (last === void 0) return root;
|
|
44
|
+
if (this.heap.length > 0) {
|
|
45
|
+
this.heap[0] = last;
|
|
46
|
+
this.indexMap.set(last.item, 0);
|
|
47
|
+
this.heapifyDown(0);
|
|
48
|
+
}
|
|
49
|
+
return root;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns the highest precedence item without removing it.
|
|
53
|
+
* Returns undefined if the queue is empty.
|
|
54
|
+
*/
|
|
55
|
+
peek() {
|
|
56
|
+
return this.heap[0];
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Rebuilds the heap from the current array state.
|
|
60
|
+
* Useful when priorities have been modified externally (e.g., phase transitions).
|
|
61
|
+
*/
|
|
62
|
+
rebuild() {
|
|
63
|
+
const start = Math.floor(this.heap.length / 2) - 1;
|
|
64
|
+
for (let i = start; i >= 0; i--) this.heapifyDown(i);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Decreases the priority of an existing item in the queue.
|
|
68
|
+
* Returns true if the item was found and updated, false otherwise.
|
|
69
|
+
*
|
|
70
|
+
* @param item - The item to find
|
|
71
|
+
* @param newPriority - The new (lower) priority value
|
|
72
|
+
* @param equals - Function to compare items for equality. If provided, uses linear search;
|
|
73
|
+
* otherwise uses O(1) reference-based lookup.
|
|
74
|
+
*/
|
|
75
|
+
decreaseKey(item, newPriority, equals) {
|
|
76
|
+
let foundIndex = -1;
|
|
77
|
+
if (equals !== void 0) for (let i = 0; i < this.heap.length; i++) {
|
|
78
|
+
const entry = this.heap[i];
|
|
79
|
+
if (entry !== void 0 && equals(entry.item, item)) {
|
|
80
|
+
foundIndex = i;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else foundIndex = this.indexMap.get(item) ?? -1;
|
|
85
|
+
if (foundIndex === -1) return false;
|
|
86
|
+
const entry = this.heap[foundIndex];
|
|
87
|
+
if (entry === void 0) return false;
|
|
88
|
+
if (newPriority >= entry.priority) return false;
|
|
89
|
+
entry.priority = newPriority;
|
|
90
|
+
this.heapifyUp(foundIndex);
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Restores heap property by moving element up from given index.
|
|
95
|
+
*/
|
|
96
|
+
heapifyUp(index) {
|
|
97
|
+
let current = index;
|
|
98
|
+
while (current > 0) {
|
|
99
|
+
const parent = Math.floor((current - 1) / 2);
|
|
100
|
+
const currentEntry = this.heap[current];
|
|
101
|
+
const parentEntry = this.heap[parent];
|
|
102
|
+
if (currentEntry === void 0 || parentEntry === void 0) return;
|
|
103
|
+
if (currentEntry.priority >= parentEntry.priority) return;
|
|
104
|
+
this.heap[current] = parentEntry;
|
|
105
|
+
this.heap[parent] = currentEntry;
|
|
106
|
+
this.indexMap.set(parentEntry.item, current);
|
|
107
|
+
this.indexMap.set(currentEntry.item, parent);
|
|
108
|
+
current = parent;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Restores heap property by moving element down from given index.
|
|
113
|
+
*/
|
|
114
|
+
heapifyDown(index) {
|
|
115
|
+
let current = index;
|
|
116
|
+
const length = this.heap.length;
|
|
117
|
+
while (current < length) {
|
|
118
|
+
const left = 2 * current + 1;
|
|
119
|
+
const right = 2 * current + 2;
|
|
120
|
+
let smallest = current;
|
|
121
|
+
const currentEntry = this.heap[current];
|
|
122
|
+
if (currentEntry === void 0) return;
|
|
123
|
+
const leftEntry = this.heap[left];
|
|
124
|
+
if (left < length && leftEntry !== void 0 && leftEntry.priority < currentEntry.priority) smallest = left;
|
|
125
|
+
const rightEntry = this.heap[right];
|
|
126
|
+
const currentSmallestEntry = this.heap[smallest];
|
|
127
|
+
if (right < length && rightEntry !== void 0 && currentSmallestEntry !== void 0 && rightEntry.priority < currentSmallestEntry.priority) smallest = right;
|
|
128
|
+
if (smallest === current) return;
|
|
129
|
+
const finalSmallestEntry = this.heap[smallest];
|
|
130
|
+
if (finalSmallestEntry !== void 0) {
|
|
131
|
+
this.heap[current] = finalSmallestEntry;
|
|
132
|
+
this.heap[smallest] = currentEntry;
|
|
133
|
+
this.indexMap.set(finalSmallestEntry.item, current);
|
|
134
|
+
this.indexMap.set(currentEntry.item, smallest);
|
|
135
|
+
current = smallest;
|
|
136
|
+
} else return;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
//#endregion
|
|
141
|
+
export { PriorityQueue as t };
|
|
142
|
+
|
|
143
|
+
//# sourceMappingURL=priority-queue-CFDd5cBg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"priority-queue-CFDd5cBg.js","names":[],"sources":["../src/structures/priority-queue.ts"],"sourcesContent":["/**\n * Priority queue entry containing an item and its priority.\n */\nexport interface PriorityEntry<T> {\n\titem: T;\n\tpriority: number;\n}\n\n/**\n * Min-heap priority queue implementation using an array-based binary heap.\n * Lower priority values have higher precedence (extracted first).\n */\nexport class PriorityQueue<T> {\n\tprivate heap: PriorityEntry<T>[] = [];\n\tprivate indexMap = new Map<T, number>();\n\n\t/**\n\t * Returns the number of items in the queue.\n\t */\n\tpublic size(): number {\n\t\treturn this.heap.length;\n\t}\n\n\t/**\n\t * Returns true if the queue is empty.\n\t */\n\tpublic isEmpty(): boolean {\n\t\treturn this.heap.length === 0;\n\t}\n\n\t/**\n\t * Adds an item with the given priority to the queue.\n\t */\n\tpublic push(item: T, priority: number): void {\n\t\tconst entry: PriorityEntry<T> = { item, priority };\n\t\tthis.heap.push(entry);\n\t\tthis.indexMap.set(item, this.heap.length - 1);\n\t\tthis.heapifyUp(this.heap.length - 1);\n\t}\n\n\t/**\n\t * Removes and returns the highest precedence item (lowest priority value).\n\t * Returns undefined if the queue is empty.\n\t */\n\tpublic pop(): PriorityEntry<T> | undefined {\n\t\tif (this.heap.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst root = this.heap[0];\n\t\tif (root === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthis.indexMap.delete(root.item);\n\n\t\tconst last = this.heap.pop();\n\t\tif (last === undefined) {\n\t\t\treturn root;\n\t\t}\n\n\t\tif (this.heap.length > 0) {\n\t\t\tthis.heap[0] = last;\n\t\t\tthis.indexMap.set(last.item, 0);\n\t\t\tthis.heapifyDown(0);\n\t\t}\n\n\t\treturn root;\n\t}\n\n\t/**\n\t * Returns the highest precedence item without removing it.\n\t * Returns undefined if the queue is empty.\n\t */\n\tpublic peek(): PriorityEntry<T> | undefined {\n\t\treturn this.heap[0];\n\t}\n\n\t/**\n\t * Rebuilds the heap from the current array state.\n\t * Useful when priorities have been modified externally (e.g., phase transitions).\n\t */\n\tpublic rebuild(): void {\n\t\t// Floyd's algorithm: heapify down from last non-leaf to root\n\t\tconst start = Math.floor(this.heap.length / 2) - 1;\n\t\tfor (let i = start; i >= 0; i--) {\n\t\t\tthis.heapifyDown(i);\n\t\t}\n\t}\n\n\t/**\n\t * Decreases the priority of an existing item in the queue.\n\t * Returns true if the item was found and updated, false otherwise.\n\t *\n\t * @param item - The item to find\n\t * @param newPriority - The new (lower) priority value\n\t * @param equals - Function to compare items for equality. If provided, uses linear search;\n\t * otherwise uses O(1) reference-based lookup.\n\t */\n\tpublic decreaseKey(\n\t\titem: T,\n\t\tnewPriority: number,\n\t\tequals?: (a: T, b: T) => boolean,\n\t): boolean {\n\t\tlet foundIndex = -1;\n\n\t\t// If equals function provided, use linear search for custom equality\n\t\tif (equals !== undefined) {\n\t\t\tfor (let i = 0; i < this.heap.length; i++) {\n\t\t\t\tconst entry = this.heap[i];\n\t\t\t\tif (entry !== undefined && equals(entry.item, item)) {\n\t\t\t\t\tfoundIndex = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Use O(1) reference-based lookup via indexMap\n\t\t\tfoundIndex = this.indexMap.get(item) ?? -1;\n\t\t}\n\n\t\tif (foundIndex === -1) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst entry = this.heap[foundIndex];\n\t\tif (entry === undefined) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// Only update if new priority is lower (higher precedence)\n\t\tif (newPriority >= entry.priority) {\n\t\t\treturn false;\n\t\t}\n\n\t\tentry.priority = newPriority;\n\t\tthis.heapifyUp(foundIndex);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Restores heap property by moving element up from given index.\n\t */\n\tprivate heapifyUp(index: number): void {\n\t\tlet current = index;\n\n\t\twhile (current > 0) {\n\t\t\tconst parent = Math.floor((current - 1) / 2);\n\t\t\tconst currentEntry = this.heap[current];\n\t\t\tconst parentEntry = this.heap[parent];\n\n\t\t\tif (currentEntry === undefined || parentEntry === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (currentEntry.priority >= parentEntry.priority) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Swap current and parent\n\t\t\tthis.heap[current] = parentEntry;\n\t\t\tthis.heap[parent] = currentEntry;\n\t\t\t// Update indexMap after swap\n\t\t\tthis.indexMap.set(parentEntry.item, current);\n\t\t\tthis.indexMap.set(currentEntry.item, parent);\n\t\t\tcurrent = parent;\n\t\t}\n\t}\n\n\t/**\n\t * Restores heap property by moving element down from given index.\n\t */\n\tprivate heapifyDown(index: number): void {\n\t\tlet current = index;\n\t\tconst length = this.heap.length;\n\n\t\twhile (current < length) {\n\t\t\tconst left = 2 * current + 1;\n\t\t\tconst right = 2 * current + 2;\n\t\t\tlet smallest = current;\n\n\t\t\tconst currentEntry = this.heap[current];\n\t\t\tif (currentEntry === undefined) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Compare with left child\n\t\t\tconst leftEntry = this.heap[left];\n\t\t\tif (\n\t\t\t\tleft < length &&\n\t\t\t\tleftEntry !== undefined &&\n\t\t\t\tleftEntry.priority < currentEntry.priority\n\t\t\t) {\n\t\t\t\tsmallest = left;\n\t\t\t}\n\n\t\t\t// Compare with right child (need to re-fetch smallest after potential update)\n\t\t\tconst rightEntry = this.heap[right];\n\t\t\tconst currentSmallestEntry = this.heap[smallest];\n\t\t\tif (\n\t\t\t\tright < length &&\n\t\t\t\trightEntry !== undefined &&\n\t\t\t\tcurrentSmallestEntry !== undefined &&\n\t\t\t\trightEntry.priority < currentSmallestEntry.priority\n\t\t\t) {\n\t\t\t\tsmallest = right;\n\t\t\t}\n\n\t\t\tif (smallest === current) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Get the final smallest entry (after determining final smallest index)\n\t\t\tconst finalSmallestEntry = this.heap[smallest];\n\t\t\tif (finalSmallestEntry !== undefined) {\n\t\t\t\tthis.heap[current] = finalSmallestEntry;\n\t\t\t\tthis.heap[smallest] = currentEntry;\n\t\t\t\t// Update indexMap after swap\n\t\t\t\tthis.indexMap.set(finalSmallestEntry.item, current);\n\t\t\t\tthis.indexMap.set(currentEntry.item, smallest);\n\t\t\t\tcurrent = smallest;\n\t\t\t} else {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_jaccard = require("../jaccard-Bys9_dGW.cjs");
|
|
3
|
+
const require_ranking = require("../ranking-DVvajgUZ.cjs");
|
|
4
|
+
const require_ranking_mi = require("./mi/index.cjs");
|
|
5
|
+
exports.adamicAdar = require_ranking_mi.adamicAdar;
|
|
6
|
+
exports.adamicAdarAsync = require_ranking_mi.adamicAdarAsync;
|
|
7
|
+
exports.adaptive = require_ranking_mi.adaptive;
|
|
8
|
+
exports.adaptiveAsync = require_ranking_mi.adaptiveAsync;
|
|
9
|
+
exports.betweenness = require_ranking.betweenness;
|
|
10
|
+
exports.communicability = require_ranking.communicability;
|
|
11
|
+
exports.cosine = require_ranking_mi.cosine;
|
|
12
|
+
exports.cosineAsync = require_ranking_mi.cosineAsync;
|
|
13
|
+
exports.degreeSum = require_ranking.degreeSum;
|
|
14
|
+
exports.etch = require_ranking_mi.etch;
|
|
15
|
+
exports.etchAsync = require_ranking_mi.etchAsync;
|
|
16
|
+
exports.hittingTime = require_ranking.hittingTime;
|
|
17
|
+
exports.hubPromoted = require_ranking_mi.hubPromoted;
|
|
18
|
+
exports.hubPromotedAsync = require_ranking_mi.hubPromotedAsync;
|
|
19
|
+
exports.jaccard = require_jaccard.jaccard;
|
|
20
|
+
exports.jaccardArithmetic = require_ranking.jaccardArithmetic;
|
|
21
|
+
exports.jaccardAsync = require_jaccard.jaccardAsync;
|
|
22
|
+
exports.katz = require_ranking.katz;
|
|
23
|
+
exports.notch = require_ranking_mi.notch;
|
|
24
|
+
exports.notchAsync = require_ranking_mi.notchAsync;
|
|
25
|
+
exports.overlapCoefficient = require_ranking_mi.overlapCoefficient;
|
|
26
|
+
exports.overlapCoefficientAsync = require_ranking_mi.overlapCoefficientAsync;
|
|
27
|
+
exports.pagerank = require_ranking.pagerank;
|
|
28
|
+
exports.parse = require_ranking.parse;
|
|
29
|
+
exports.parseAsync = require_ranking.parseAsync;
|
|
30
|
+
exports.randomRanking = require_ranking.randomRanking;
|
|
31
|
+
exports.resistanceDistance = require_ranking.resistanceDistance;
|
|
32
|
+
exports.resourceAllocation = require_ranking_mi.resourceAllocation;
|
|
33
|
+
exports.resourceAllocationAsync = require_ranking_mi.resourceAllocationAsync;
|
|
34
|
+
exports.scale = require_ranking_mi.scale;
|
|
35
|
+
exports.scaleAsync = require_ranking_mi.scaleAsync;
|
|
36
|
+
exports.shortest = require_ranking.shortest;
|
|
37
|
+
exports.skew = require_ranking_mi.skew;
|
|
38
|
+
exports.skewAsync = require_ranking_mi.skewAsync;
|
|
39
|
+
exports.sorensen = require_ranking_mi.sorensen;
|
|
40
|
+
exports.sorensenAsync = require_ranking_mi.sorensenAsync;
|
|
41
|
+
exports.span = require_ranking_mi.span;
|
|
42
|
+
exports.spanAsync = require_ranking_mi.spanAsync;
|
|
43
|
+
exports.widestPath = require_ranking.widestPath;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { n as jaccardAsync, t as jaccard } from "../jaccard-3rCdilwm.js";
|
|
2
|
+
import { a as katz, c as jaccardArithmetic, d as shortest, f as parse, i as communicability, l as widestPath, n as randomRanking, o as betweenness, p as parseAsync, r as resistanceDistance, s as pagerank, t as hittingTime, u as degreeSum } from "../ranking-3ez5m67U.js";
|
|
3
|
+
import { adamicAdar, adamicAdarAsync, adaptive, adaptiveAsync, cosine, cosineAsync, etch, etchAsync, hubPromoted, hubPromotedAsync, notch, notchAsync, overlapCoefficient, overlapCoefficientAsync, resourceAllocation, resourceAllocationAsync, scale, scaleAsync, skew, skewAsync, sorensen, sorensenAsync, span, spanAsync } from "./mi/index.js";
|
|
4
|
+
export { adamicAdar, adamicAdarAsync, adaptive, adaptiveAsync, betweenness, communicability, cosine, cosineAsync, degreeSum, etch, etchAsync, hittingTime, hubPromoted, hubPromotedAsync, jaccard, jaccardArithmetic, jaccardAsync, katz, notch, notchAsync, overlapCoefficient, overlapCoefficientAsync, pagerank, parse, parseAsync, randomRanking, resistanceDistance, resourceAllocation, resourceAllocationAsync, scale, scaleAsync, shortest, skew, skewAsync, sorensen, sorensenAsync, span, spanAsync, widestPath };
|