graphwise 1.0.0 → 1.1.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/README.md +41 -0
- package/dist/expansion/base.d.ts +12 -0
- package/dist/expansion/base.d.ts.map +1 -0
- package/dist/expansion/base.unit.test.d.ts +2 -0
- package/dist/expansion/base.unit.test.d.ts.map +1 -0
- package/dist/expansion/dome.d.ts +16 -0
- package/dist/expansion/dome.d.ts.map +1 -0
- package/dist/expansion/dome.unit.test.d.ts +2 -0
- package/dist/expansion/dome.unit.test.d.ts.map +1 -0
- package/dist/expansion/edge.d.ts +15 -0
- package/dist/expansion/edge.d.ts.map +1 -0
- package/dist/expansion/edge.unit.test.d.ts +2 -0
- package/dist/expansion/edge.unit.test.d.ts.map +1 -0
- package/dist/expansion/hae.d.ts +22 -0
- package/dist/expansion/hae.d.ts.map +1 -0
- package/dist/expansion/hae.unit.test.d.ts +2 -0
- package/dist/expansion/hae.unit.test.d.ts.map +1 -0
- package/dist/expansion/index.d.ts +22 -0
- package/dist/expansion/index.d.ts.map +1 -0
- package/dist/expansion/maze.d.ts +25 -0
- package/dist/expansion/maze.d.ts.map +1 -0
- package/dist/expansion/maze.unit.test.d.ts +2 -0
- package/dist/expansion/maze.unit.test.d.ts.map +1 -0
- package/dist/expansion/pipe.d.ts +15 -0
- package/dist/expansion/pipe.d.ts.map +1 -0
- package/dist/expansion/pipe.unit.test.d.ts +2 -0
- package/dist/expansion/pipe.unit.test.d.ts.map +1 -0
- package/dist/expansion/reach.d.ts +26 -0
- package/dist/expansion/reach.d.ts.map +1 -0
- package/dist/expansion/reach.unit.test.d.ts +2 -0
- package/dist/expansion/reach.unit.test.d.ts.map +1 -0
- package/dist/expansion/sage.d.ts +24 -0
- package/dist/expansion/sage.d.ts.map +1 -0
- package/dist/expansion/sage.unit.test.d.ts +2 -0
- package/dist/expansion/sage.unit.test.d.ts.map +1 -0
- package/dist/expansion/types.d.ts +105 -0
- package/dist/expansion/types.d.ts.map +1 -0
- package/dist/extraction/ego-network.d.ts +32 -0
- package/dist/extraction/ego-network.d.ts.map +1 -0
- package/dist/extraction/ego-network.unit.test.d.ts +5 -0
- package/dist/extraction/ego-network.unit.test.d.ts.map +1 -0
- package/dist/extraction/index.d.ts +20 -0
- package/dist/extraction/index.d.ts.map +1 -0
- package/dist/extraction/induced-subgraph.d.ts +19 -0
- package/dist/extraction/induced-subgraph.d.ts.map +1 -0
- package/dist/extraction/induced-subgraph.unit.test.d.ts +5 -0
- package/dist/extraction/induced-subgraph.unit.test.d.ts.map +1 -0
- package/dist/extraction/k-core.d.ts +24 -0
- package/dist/extraction/k-core.d.ts.map +1 -0
- package/dist/extraction/k-core.unit.test.d.ts +5 -0
- package/dist/extraction/k-core.unit.test.d.ts.map +1 -0
- package/dist/extraction/motif.d.ts +50 -0
- package/dist/extraction/motif.d.ts.map +1 -0
- package/dist/extraction/motif.unit.test.d.ts +5 -0
- package/dist/extraction/motif.unit.test.d.ts.map +1 -0
- package/dist/extraction/node-filter.d.ts +35 -0
- package/dist/extraction/node-filter.d.ts.map +1 -0
- package/dist/extraction/node-filter.unit.test.d.ts +5 -0
- package/dist/extraction/node-filter.unit.test.d.ts.map +1 -0
- package/dist/extraction/truss.d.ts +41 -0
- package/dist/extraction/truss.d.ts.map +1 -0
- package/dist/extraction/truss.unit.test.d.ts +5 -0
- package/dist/extraction/truss.unit.test.d.ts.map +1 -0
- package/dist/gpu/context.d.ts +118 -0
- package/dist/gpu/context.d.ts.map +1 -0
- package/dist/gpu/context.unit.test.d.ts +2 -0
- package/dist/gpu/context.unit.test.d.ts.map +1 -0
- package/dist/gpu/csr.d.ts +97 -0
- package/dist/gpu/csr.d.ts.map +1 -0
- package/dist/gpu/csr.unit.test.d.ts +2 -0
- package/dist/gpu/csr.unit.test.d.ts.map +1 -0
- package/dist/gpu/detect.d.ts +25 -0
- package/dist/gpu/detect.d.ts.map +1 -0
- package/dist/gpu/detect.unit.test.d.ts +2 -0
- package/dist/gpu/detect.unit.test.d.ts.map +1 -0
- package/dist/gpu/index.cjs +6 -0
- package/dist/gpu/index.d.ts +11 -0
- package/dist/gpu/index.d.ts.map +1 -0
- package/dist/gpu/index.js +2 -0
- package/dist/gpu/types.d.ts +50 -0
- package/dist/gpu/types.d.ts.map +1 -0
- package/dist/gpu-BJRVYBjx.cjs +338 -0
- package/dist/gpu-BJRVYBjx.cjs.map +1 -0
- package/dist/gpu-BveuXugy.js +315 -0
- package/dist/gpu-BveuXugy.js.map +1 -0
- package/dist/graph/adjacency-map.d.ts +95 -0
- package/dist/graph/adjacency-map.d.ts.map +1 -0
- package/dist/graph/adjacency-map.unit.test.d.ts +2 -0
- package/dist/graph/adjacency-map.unit.test.d.ts.map +1 -0
- package/dist/graph/index.cjs +3 -0
- package/dist/graph/index.d.ts +9 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +2 -0
- package/dist/graph/interfaces.d.ts +125 -0
- package/dist/graph/interfaces.d.ts.map +1 -0
- package/dist/graph/types.d.ts +72 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph-DLWiziLB.js +222 -0
- package/dist/graph-DLWiziLB.js.map +1 -0
- package/dist/graph-az06J1YV.cjs +227 -0
- package/dist/graph-az06J1YV.cjs.map +1 -0
- package/dist/index/index.cjs +1404 -0
- package/dist/index/index.cjs.map +1 -0
- package/dist/index/index.js +1356 -0
- package/dist/index/index.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/kmeans-B0HEOU6k.cjs +234 -0
- package/dist/kmeans-B0HEOU6k.cjs.map +1 -0
- package/dist/kmeans-DgbsOznU.js +223 -0
- package/dist/kmeans-DgbsOznU.js.map +1 -0
- package/dist/ranking/baselines/shortest.d.ts +15 -0
- package/dist/ranking/baselines/shortest.d.ts.map +1 -0
- package/dist/ranking/baselines/shortest.unit.test.d.ts +2 -0
- package/dist/ranking/baselines/shortest.unit.test.d.ts.map +1 -0
- package/dist/ranking/baselines/types.d.ts +30 -0
- package/dist/ranking/baselines/types.d.ts.map +1 -0
- package/dist/ranking/index.d.ts +15 -0
- package/dist/ranking/index.d.ts.map +1 -0
- package/dist/ranking/mi/adamic-adar.d.ts +13 -0
- package/dist/ranking/mi/adamic-adar.d.ts.map +1 -0
- package/dist/ranking/mi/adaptive.d.ts +16 -0
- package/dist/ranking/mi/adaptive.d.ts.map +1 -0
- package/dist/ranking/mi/etch.d.ts +7 -0
- package/dist/ranking/mi/etch.d.ts.map +1 -0
- package/dist/ranking/mi/index.d.ts +18 -0
- package/dist/ranking/mi/index.d.ts.map +1 -0
- package/dist/ranking/mi/jaccard.d.ts +13 -0
- package/dist/ranking/mi/jaccard.d.ts.map +1 -0
- package/dist/ranking/mi/mi-variants.unit.test.d.ts +2 -0
- package/dist/ranking/mi/mi-variants.unit.test.d.ts.map +1 -0
- package/dist/ranking/mi/notch.d.ts +7 -0
- package/dist/ranking/mi/notch.d.ts.map +1 -0
- package/dist/ranking/mi/scale.d.ts +7 -0
- package/dist/ranking/mi/scale.d.ts.map +1 -0
- package/dist/ranking/mi/skew.d.ts +7 -0
- package/dist/ranking/mi/skew.d.ts.map +1 -0
- package/dist/ranking/mi/span.d.ts +7 -0
- package/dist/ranking/mi/span.d.ts.map +1 -0
- package/dist/ranking/mi/types.d.ts +35 -0
- package/dist/ranking/mi/types.d.ts.map +1 -0
- package/dist/ranking/parse.d.ts +56 -0
- package/dist/ranking/parse.d.ts.map +1 -0
- package/dist/ranking/parse.unit.test.d.ts +2 -0
- package/dist/ranking/parse.unit.test.d.ts.map +1 -0
- package/dist/schemas/define.d.ts +18 -0
- package/dist/schemas/define.d.ts.map +1 -0
- package/dist/schemas/define.unit.test.d.ts +2 -0
- package/dist/schemas/define.unit.test.d.ts.map +1 -0
- package/dist/schemas/graph.d.ts +85 -0
- package/dist/schemas/graph.d.ts.map +1 -0
- package/dist/schemas/graph.unit.test.d.ts +2 -0
- package/dist/schemas/graph.unit.test.d.ts.map +1 -0
- package/dist/schemas/index.cjs +3791 -0
- package/dist/schemas/index.cjs.map +1 -0
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +3782 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/seeds/grasp.d.ts +79 -0
- package/dist/seeds/grasp.d.ts.map +1 -0
- package/dist/seeds/grasp.unit.test.d.ts +2 -0
- package/dist/seeds/grasp.unit.test.d.ts.map +1 -0
- package/dist/seeds/index.cjs +4 -0
- package/dist/seeds/index.d.ts +10 -0
- package/dist/seeds/index.d.ts.map +1 -0
- package/dist/seeds/index.js +2 -0
- package/dist/seeds/stratified.d.ts +85 -0
- package/dist/seeds/stratified.d.ts.map +1 -0
- package/dist/seeds/stratified.unit.test.d.ts +2 -0
- package/dist/seeds/stratified.unit.test.d.ts.map +1 -0
- package/dist/seeds-B6J9oJfU.cjs +404 -0
- package/dist/seeds-B6J9oJfU.cjs.map +1 -0
- package/dist/seeds-UNZxqm_U.js +393 -0
- package/dist/seeds-UNZxqm_U.js.map +1 -0
- package/dist/structures/index.cjs +3 -0
- package/dist/structures/index.d.ts +3 -0
- package/dist/structures/index.d.ts.map +1 -0
- package/dist/structures/index.js +2 -0
- package/dist/structures/priority-queue.d.ts +59 -0
- package/dist/structures/priority-queue.d.ts.map +1 -0
- package/dist/structures/priority-queue.unit.test.d.ts +2 -0
- package/dist/structures/priority-queue.unit.test.d.ts.map +1 -0
- package/dist/structures-BPfhfqNP.js +133 -0
- package/dist/structures-BPfhfqNP.js.map +1 -0
- package/dist/structures-CJ_S_7fs.cjs +138 -0
- package/dist/structures-CJ_S_7fs.cjs.map +1 -0
- package/dist/traversal/bfs.d.ts +50 -0
- package/dist/traversal/bfs.d.ts.map +1 -0
- package/dist/traversal/bfs.unit.test.d.ts +2 -0
- package/dist/traversal/bfs.unit.test.d.ts.map +1 -0
- package/dist/traversal/dfs.d.ts +50 -0
- package/dist/traversal/dfs.d.ts.map +1 -0
- package/dist/traversal/dfs.unit.test.d.ts +2 -0
- package/dist/traversal/dfs.unit.test.d.ts.map +1 -0
- package/dist/traversal/index.cjs +6 -0
- package/dist/traversal/index.d.ts +11 -0
- package/dist/traversal/index.d.ts.map +1 -0
- package/dist/traversal/index.js +2 -0
- package/dist/traversal-CQCjUwUJ.js +149 -0
- package/dist/traversal-CQCjUwUJ.js.map +1 -0
- package/dist/traversal-QeHaNUWn.cjs +172 -0
- package/dist/traversal-QeHaNUWn.cjs.map +1 -0
- package/dist/utils/clustering-coefficient.d.ts +38 -0
- package/dist/utils/clustering-coefficient.d.ts.map +1 -0
- package/dist/utils/clustering-coefficient.unit.test.d.ts +2 -0
- package/dist/utils/clustering-coefficient.unit.test.d.ts.map +1 -0
- package/dist/utils/entropy.d.ts +58 -0
- package/dist/utils/entropy.d.ts.map +1 -0
- package/dist/utils/entropy.unit.test.d.ts +2 -0
- package/dist/utils/entropy.unit.test.d.ts.map +1 -0
- package/dist/utils/index.cjs +13 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/kmeans.d.ts +73 -0
- package/dist/utils/kmeans.d.ts.map +1 -0
- package/dist/utils/kmeans.unit.test.d.ts +2 -0
- package/dist/utils/kmeans.unit.test.d.ts.map +1 -0
- package/dist/utils-Q_akvlMn.js +164 -0
- package/dist/utils-Q_akvlMn.js.map +1 -0
- package/dist/utils-spZa1ZvS.cjs +205 -0
- package/dist/utils-spZa1ZvS.cjs.map +1 -0
- package/package.json +136 -8
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
//#region src/utils/kmeans.ts
|
|
2
|
+
/** Small epsilon to prevent division by zero */
|
|
3
|
+
var EPSILON = 1e-10;
|
|
4
|
+
/**
|
|
5
|
+
* Simple seeded pseudo-random number generator using mulberry32.
|
|
6
|
+
*/
|
|
7
|
+
function createRNG(seed) {
|
|
8
|
+
let state = seed >>> 0;
|
|
9
|
+
return () => {
|
|
10
|
+
state = state + 1831565813 >>> 0;
|
|
11
|
+
let t = Math.imul(state ^ state >>> 15, state | 1);
|
|
12
|
+
t = (t ^ t >>> 7) * (t | 1640531527);
|
|
13
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Compute Euclidean distance between two 3D feature vectors.
|
|
18
|
+
*/
|
|
19
|
+
function euclideanDistance(a, b) {
|
|
20
|
+
const d1 = a.f1 - b.f1;
|
|
21
|
+
const d2 = a.f2 - b.f2;
|
|
22
|
+
const d3 = a.f3 - b.f3;
|
|
23
|
+
return Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);
|
|
24
|
+
}
|
|
25
|
+
function normaliseFeatures(features) {
|
|
26
|
+
if (features.length === 0) return [];
|
|
27
|
+
let sum1 = 0;
|
|
28
|
+
let sum2 = 0;
|
|
29
|
+
let sum3 = 0;
|
|
30
|
+
for (const f of features) {
|
|
31
|
+
sum1 += f.f1;
|
|
32
|
+
sum2 += f.f2;
|
|
33
|
+
sum3 += f.f3;
|
|
34
|
+
}
|
|
35
|
+
const n = features.length;
|
|
36
|
+
const mean1 = sum1 / n;
|
|
37
|
+
const mean2 = sum2 / n;
|
|
38
|
+
const mean3 = sum3 / n;
|
|
39
|
+
let var1 = 0;
|
|
40
|
+
let var2 = 0;
|
|
41
|
+
let var3 = 0;
|
|
42
|
+
for (const f of features) {
|
|
43
|
+
var1 += (f.f1 - mean1) ** 2;
|
|
44
|
+
var2 += (f.f2 - mean2) ** 2;
|
|
45
|
+
var3 += (f.f3 - mean3) ** 2;
|
|
46
|
+
}
|
|
47
|
+
const std1 = Math.sqrt(var1 / n + EPSILON);
|
|
48
|
+
const std2 = Math.sqrt(var2 / n + EPSILON);
|
|
49
|
+
const std3 = Math.sqrt(var3 / n + EPSILON);
|
|
50
|
+
return features.map((f) => ({
|
|
51
|
+
nodeId: f.nodeId,
|
|
52
|
+
f1: (f.f1 - mean1) / std1,
|
|
53
|
+
f2: (f.f2 - mean2) / std2,
|
|
54
|
+
f3: (f.f3 - mean3) / std3
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Mini-batch K-means clustering for 3D feature vectors.
|
|
59
|
+
*
|
|
60
|
+
* Uses Mini-batch K-means for efficiency with large datasets.
|
|
61
|
+
* This is specifically designed for the GRASP seed selection algorithm.
|
|
62
|
+
*
|
|
63
|
+
* @param features - Array of labelled feature vectors
|
|
64
|
+
* @param options - Clustering options
|
|
65
|
+
* @returns Clustering result with centroids and assignments
|
|
66
|
+
*/
|
|
67
|
+
function miniBatchKMeans(features, options) {
|
|
68
|
+
const { k, maxIterations = 100, tolerance = 1e-6, seed = 42 } = options;
|
|
69
|
+
if (features.length === 0) return {
|
|
70
|
+
centroids: [],
|
|
71
|
+
assignments: /* @__PURE__ */ new Map(),
|
|
72
|
+
k
|
|
73
|
+
};
|
|
74
|
+
const rng = createRNG(seed);
|
|
75
|
+
const n = features.length;
|
|
76
|
+
const effectiveK = Math.min(k, n);
|
|
77
|
+
const centroids = initialiseCentroidsKMeansPP(features, effectiveK, rng);
|
|
78
|
+
const assignments = /* @__PURE__ */ new Map();
|
|
79
|
+
const batchSize = Math.max(10, Math.floor(n / 10));
|
|
80
|
+
for (let iter = 0; iter < maxIterations; iter++) {
|
|
81
|
+
const batchIndices = /* @__PURE__ */ new Set();
|
|
82
|
+
while (batchIndices.size < Math.min(batchSize, n)) batchIndices.add(Math.floor(rng() * n));
|
|
83
|
+
const batchPoints = [];
|
|
84
|
+
for (const idx of batchIndices) {
|
|
85
|
+
const feature = features[idx];
|
|
86
|
+
if (feature === void 0) continue;
|
|
87
|
+
let minDist = Infinity;
|
|
88
|
+
let bestCluster = 0;
|
|
89
|
+
for (let c = 0; c < centroids.length; c++) {
|
|
90
|
+
const centroid = centroids[c];
|
|
91
|
+
if (centroid === void 0) continue;
|
|
92
|
+
const dist = euclideanDistance(feature, centroid);
|
|
93
|
+
if (dist < minDist) {
|
|
94
|
+
minDist = dist;
|
|
95
|
+
bestCluster = c;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
batchPoints.push({
|
|
99
|
+
feature,
|
|
100
|
+
cluster: bestCluster
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
const oldCentroids = centroids.map((c) => ({ ...c }));
|
|
104
|
+
const clusterCounts = Array.from({ length: centroids.length }, () => 0);
|
|
105
|
+
const clusterSums = Array.from({ length: centroids.length }, () => [
|
|
106
|
+
0,
|
|
107
|
+
0,
|
|
108
|
+
0
|
|
109
|
+
]);
|
|
110
|
+
for (const { feature, cluster } of batchPoints) {
|
|
111
|
+
const currentCount = clusterCounts[cluster];
|
|
112
|
+
if (currentCount !== void 0) clusterCounts[cluster] = currentCount + 1;
|
|
113
|
+
const sum = clusterSums[cluster];
|
|
114
|
+
if (sum !== void 0) {
|
|
115
|
+
sum[0] += feature.f1;
|
|
116
|
+
sum[1] += feature.f2;
|
|
117
|
+
sum[2] += feature.f3;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for (let c = 0; c < centroids.length; c++) {
|
|
121
|
+
const count = clusterCounts[c] ?? 0;
|
|
122
|
+
if (count > 0) {
|
|
123
|
+
const sum = clusterSums[c];
|
|
124
|
+
if (sum !== void 0) centroids[c] = {
|
|
125
|
+
f1: sum[0] / count,
|
|
126
|
+
f2: sum[1] / count,
|
|
127
|
+
f3: sum[2] / count
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
let maxShift = 0;
|
|
132
|
+
for (let c = 0; c < centroids.length; c++) {
|
|
133
|
+
const newCentroid = centroids[c];
|
|
134
|
+
const oldCentroid = oldCentroids[c];
|
|
135
|
+
if (newCentroid !== void 0 && oldCentroid !== void 0) {
|
|
136
|
+
const shift = euclideanDistance(newCentroid, oldCentroid);
|
|
137
|
+
maxShift = Math.max(maxShift, shift);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (maxShift < tolerance) break;
|
|
141
|
+
}
|
|
142
|
+
for (const feature of features) {
|
|
143
|
+
let minDist = Infinity;
|
|
144
|
+
let bestCluster = 0;
|
|
145
|
+
for (let c = 0; c < centroids.length; c++) {
|
|
146
|
+
const centroid = centroids[c];
|
|
147
|
+
if (centroid === void 0) continue;
|
|
148
|
+
const dist = euclideanDistance(feature, centroid);
|
|
149
|
+
if (dist < minDist) {
|
|
150
|
+
minDist = dist;
|
|
151
|
+
bestCluster = c;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
assignments.set(feature.nodeId, bestCluster);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
centroids,
|
|
158
|
+
assignments,
|
|
159
|
+
k: effectiveK
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* K-means++ initialisation for better centroid seeding.
|
|
164
|
+
*/
|
|
165
|
+
function initialiseCentroidsKMeansPP(features, k, rng) {
|
|
166
|
+
const centroids = [];
|
|
167
|
+
const n = features.length;
|
|
168
|
+
const firstFeature = features[Math.floor(rng() * n)];
|
|
169
|
+
if (firstFeature === void 0) return [{
|
|
170
|
+
f1: 0,
|
|
171
|
+
f2: 0,
|
|
172
|
+
f3: 0
|
|
173
|
+
}];
|
|
174
|
+
centroids.push({
|
|
175
|
+
f1: firstFeature.f1,
|
|
176
|
+
f2: firstFeature.f2,
|
|
177
|
+
f3: firstFeature.f3
|
|
178
|
+
});
|
|
179
|
+
const distances = Array.from({ length: n }, () => Infinity);
|
|
180
|
+
for (let c = 1; c < k; c++) {
|
|
181
|
+
let totalDistSq = 0;
|
|
182
|
+
for (let i = 0; i < n; i++) {
|
|
183
|
+
const feature = features[i];
|
|
184
|
+
if (feature === void 0) continue;
|
|
185
|
+
const lastCentroid = centroids[c - 1];
|
|
186
|
+
if (lastCentroid === void 0) continue;
|
|
187
|
+
const dist = euclideanDistance(feature, lastCentroid);
|
|
188
|
+
const currentMin = distances[i];
|
|
189
|
+
if (currentMin !== void 0 && dist < currentMin) distances[i] = dist;
|
|
190
|
+
const d = distances[i];
|
|
191
|
+
if (d !== void 0) totalDistSq += d * d;
|
|
192
|
+
}
|
|
193
|
+
const threshold = rng() * totalDistSq;
|
|
194
|
+
let cumulative = 0;
|
|
195
|
+
let nextIdx = 0;
|
|
196
|
+
for (let i = 0; i < n; i++) {
|
|
197
|
+
const d = distances[i];
|
|
198
|
+
if (d !== void 0) {
|
|
199
|
+
cumulative += d * d;
|
|
200
|
+
if (cumulative >= threshold) {
|
|
201
|
+
nextIdx = i;
|
|
202
|
+
break;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
const nextFeature = features[nextIdx];
|
|
207
|
+
if (nextFeature !== void 0) centroids.push({
|
|
208
|
+
f1: nextFeature.f1,
|
|
209
|
+
f2: nextFeature.f2,
|
|
210
|
+
f3: nextFeature.f3
|
|
211
|
+
});
|
|
212
|
+
else centroids.push({
|
|
213
|
+
f1: 0,
|
|
214
|
+
f2: 0,
|
|
215
|
+
f3: 0
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return centroids;
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
export { normaliseFeatures as n, miniBatchKMeans as t };
|
|
222
|
+
|
|
223
|
+
//# sourceMappingURL=kmeans-DgbsOznU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kmeans-DgbsOznU.js","names":[],"sources":["../src/utils/kmeans.ts"],"sourcesContent":["/**\n * Minimal K-means clustering implementation for GRASP seed selection.\n *\n * This is a lightweight implementation specifically designed for 3D feature vectors\n * used in structural seed selection. For general-purpose clustering, consider\n * using a dedicated library.\n *\n * @packageDocumentation\n */\n\n/**\n * A 3D feature vector representing node structural properties.\n */\nexport interface FeatureVector3D {\n\t/** First dimension (e.g., log-degree) */\n\treadonly f1: number;\n\t/** Second dimension (e.g., clustering coefficient) */\n\treadonly f2: number;\n\t/** Third dimension (e.g., approximate PageRank) */\n\treadonly f3: number;\n}\n\n/**\n * A labelled feature vector with associated node ID.\n */\nexport interface LabelledFeature extends FeatureVector3D {\n\t/** Node identifier */\n\treadonly nodeId: string;\n}\n\n/**\n * Result of K-means clustering.\n */\nexport interface KMeansResult {\n\t/** Cluster centroids */\n\treadonly centroids: readonly FeatureVector3D[];\n\t/** Cluster assignments: nodeId -> cluster index */\n\treadonly assignments: ReadonlyMap<string, number>;\n\t/** Number of clusters */\n\treadonly k: number;\n}\n\n/**\n * Options for K-means clustering.\n */\nexport interface KMeansOptions {\n\t/** Number of clusters */\n\treadonly k: number;\n\t/** Maximum iterations (default: 100) */\n\treadonly maxIterations?: number;\n\t/** Convergence threshold (default: 1e-6) */\n\treadonly tolerance?: number;\n\t/** Random seed for reproducibility */\n\treadonly seed?: number;\n}\n\n/** Small epsilon to prevent division by zero */\nconst EPSILON = 1e-10;\n\n/**\n * Simple seeded pseudo-random number generator using mulberry32.\n */\nfunction createRNG(seed: number): () => number {\n\tlet state = seed >>> 0;\n\treturn (): number => {\n\t\tstate = (state + 0x6d2b79f5) >>> 0;\n\t\tlet t = Math.imul(state ^ (state >>> 15), state | 1);\n\t\tt = (t ^ (t >>> 7)) * (t | 0x61c88647);\n\t\treturn ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\n/**\n * Compute Euclidean distance between two 3D feature vectors.\n */\nfunction euclideanDistance(a: FeatureVector3D, b: FeatureVector3D): number {\n\tconst d1 = a.f1 - b.f1;\n\tconst d2 = a.f2 - b.f2;\n\tconst d3 = a.f3 - b.f3;\n\treturn Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3);\n}\n\n/**\n * Compute the mean of a set of feature vectors.\n * @internal - Used for testing\n */\nexport function _computeMean(\n\tvectors: readonly FeatureVector3D[],\n): FeatureVector3D {\n\tif (vectors.length === 0) {\n\t\treturn { f1: 0, f2: 0, f3: 0 };\n\t}\n\tlet sum1 = 0;\n\tlet sum2 = 0;\n\tlet sum3 = 0;\n\tfor (const v of vectors) {\n\t\tsum1 += v.f1;\n\t\tsum2 += v.f2;\n\t\tsum3 += v.f3;\n\t}\n\tconst n = vectors.length;\n\treturn { f1: sum1 / n, f2: sum2 / n, f3: sum3 / n };\n}\n\n/**\n * Z-score normalise features (zero mean, unit variance).\n */\nexport { normaliseFeatures as zScoreNormalise };\n\nexport function normaliseFeatures(\n\tfeatures: readonly LabelledFeature[],\n): LabelledFeature[] {\n\tif (features.length === 0) {\n\t\treturn [];\n\t}\n\n\t// Compute means\n\tlet sum1 = 0;\n\tlet sum2 = 0;\n\tlet sum3 = 0;\n\tfor (const f of features) {\n\t\tsum1 += f.f1;\n\t\tsum2 += f.f2;\n\t\tsum3 += f.f3;\n\t}\n\tconst n = features.length;\n\tconst mean1 = sum1 / n;\n\tconst mean2 = sum2 / n;\n\tconst mean3 = sum3 / n;\n\n\t// Compute standard deviations\n\tlet var1 = 0;\n\tlet var2 = 0;\n\tlet var3 = 0;\n\tfor (const f of features) {\n\t\tvar1 += (f.f1 - mean1) ** 2;\n\t\tvar2 += (f.f2 - mean2) ** 2;\n\t\tvar3 += (f.f3 - mean3) ** 2;\n\t}\n\tconst std1 = Math.sqrt(var1 / n + EPSILON);\n\tconst std2 = Math.sqrt(var2 / n + EPSILON);\n\tconst std3 = Math.sqrt(var3 / n + EPSILON);\n\n\t// Normalise\n\treturn features.map(\n\t\t(f): LabelledFeature => ({\n\t\t\tnodeId: f.nodeId,\n\t\t\tf1: (f.f1 - mean1) / std1,\n\t\t\tf2: (f.f2 - mean2) / std2,\n\t\t\tf3: (f.f3 - mean3) / std3,\n\t\t}),\n\t);\n}\n\n/**\n * Mini-batch K-means clustering for 3D feature vectors.\n *\n * Uses Mini-batch K-means for efficiency with large datasets.\n * This is specifically designed for the GRASP seed selection algorithm.\n *\n * @param features - Array of labelled feature vectors\n * @param options - Clustering options\n * @returns Clustering result with centroids and assignments\n */\nexport function miniBatchKMeans(\n\tfeatures: readonly LabelledFeature[],\n\toptions: KMeansOptions,\n): KMeansResult {\n\tconst { k, maxIterations = 100, tolerance = 1e-6, seed = 42 } = options;\n\n\tif (features.length === 0) {\n\t\treturn {\n\t\t\tcentroids: [],\n\t\t\tassignments: new Map(),\n\t\t\tk,\n\t\t};\n\t}\n\n\tconst rng = createRNG(seed);\n\tconst n = features.length;\n\tconst effectiveK = Math.min(k, n);\n\n\t// Initialise centroids using k-means++ seeding\n\tconst centroids: FeatureVector3D[] = initialiseCentroidsKMeansPP(\n\t\tfeatures,\n\t\teffectiveK,\n\t\trng,\n\t);\n\n\t// Assignments map\n\tconst assignments = new Map<string, number>();\n\n\t// Mini-batch size (10% of data or at least 10)\n\tconst batchSize = Math.max(10, Math.floor(n / 10));\n\n\tfor (let iter = 0; iter < maxIterations; iter++) {\n\t\t// Sample mini-batch\n\t\tconst batchIndices = new Set<number>();\n\t\twhile (batchIndices.size < Math.min(batchSize, n)) {\n\t\t\tbatchIndices.add(Math.floor(rng() * n));\n\t\t}\n\n\t\t// Assign batch points to nearest centroid\n\t\tconst batchPoints: { feature: LabelledFeature; cluster: number }[] = [];\n\t\tfor (const idx of batchIndices) {\n\t\t\tconst feature = features[idx];\n\t\t\tif (feature === undefined) continue;\n\t\t\tlet minDist = Infinity;\n\t\t\tlet bestCluster = 0;\n\t\t\tfor (let c = 0; c < centroids.length; c++) {\n\t\t\t\tconst centroid = centroids[c];\n\t\t\t\tif (centroid === undefined) continue;\n\t\t\t\tconst dist = euclideanDistance(feature, centroid);\n\t\t\t\tif (dist < minDist) {\n\t\t\t\t\tminDist = dist;\n\t\t\t\t\tbestCluster = c;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbatchPoints.push({ feature, cluster: bestCluster });\n\t\t}\n\n\t\t// Update centroids based on batch\n\t\tconst oldCentroids = centroids.map((c) => ({ ...c }));\n\n\t\t// Compute per-cluster counts and sums from batch\n\t\tconst clusterCounts = Array.from({ length: centroids.length }, () => 0);\n\t\tconst clusterSums: [number, number, number][] = Array.from(\n\t\t\t{ length: centroids.length },\n\t\t\t(): [number, number, number] => [0, 0, 0],\n\t\t);\n\n\t\tfor (const { feature, cluster } of batchPoints) {\n\t\t\tconst currentCount = clusterCounts[cluster];\n\t\t\tif (currentCount !== undefined) {\n\t\t\t\tclusterCounts[cluster] = currentCount + 1;\n\t\t\t}\n\t\t\tconst sum = clusterSums[cluster];\n\t\t\tif (sum !== undefined) {\n\t\t\t\tsum[0] += feature.f1;\n\t\t\t\tsum[1] += feature.f2;\n\t\t\t\tsum[2] += feature.f3;\n\t\t\t}\n\t\t}\n\n\t\t// Update centroids\n\t\tfor (let c = 0; c < centroids.length; c++) {\n\t\t\tconst count = clusterCounts[c] ?? 0;\n\t\t\tif (count > 0) {\n\t\t\t\tconst sum = clusterSums[c];\n\t\t\t\tif (sum !== undefined) {\n\t\t\t\t\tcentroids[c] = {\n\t\t\t\t\t\tf1: sum[0] / count,\n\t\t\t\t\t\tf2: sum[1] / count,\n\t\t\t\t\t\tf3: sum[2] / count,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Check convergence\n\t\tlet maxShift = 0;\n\t\tfor (let c = 0; c < centroids.length; c++) {\n\t\t\tconst newCentroid = centroids[c];\n\t\t\tconst oldCentroid = oldCentroids[c];\n\t\t\tif (newCentroid !== undefined && oldCentroid !== undefined) {\n\t\t\t\tconst shift = euclideanDistance(newCentroid, oldCentroid);\n\t\t\t\tmaxShift = Math.max(maxShift, shift);\n\t\t\t}\n\t\t}\n\n\t\tif (maxShift < tolerance) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Final assignment of all points\n\tfor (const feature of features) {\n\t\tlet minDist = Infinity;\n\t\tlet bestCluster = 0;\n\t\tfor (let c = 0; c < centroids.length; c++) {\n\t\t\tconst centroid = centroids[c];\n\t\t\tif (centroid === undefined) continue;\n\t\t\tconst dist = euclideanDistance(feature, centroid);\n\t\t\tif (dist < minDist) {\n\t\t\t\tminDist = dist;\n\t\t\t\tbestCluster = c;\n\t\t\t}\n\t\t}\n\t\tassignments.set(feature.nodeId, bestCluster);\n\t}\n\n\treturn {\n\t\tcentroids,\n\t\tassignments,\n\t\tk: effectiveK,\n\t};\n}\n\n/**\n * K-means++ initialisation for better centroid seeding.\n */\nfunction initialiseCentroidsKMeansPP(\n\tfeatures: readonly LabelledFeature[],\n\tk: number,\n\trng: () => number,\n): FeatureVector3D[] {\n\tconst centroids: FeatureVector3D[] = [];\n\tconst n = features.length;\n\n\t// Choose first centroid randomly\n\tconst firstIdx = Math.floor(rng() * n);\n\tconst firstFeature = features[firstIdx];\n\tif (firstFeature === undefined) {\n\t\treturn [{ f1: 0, f2: 0, f3: 0 }];\n\t}\n\tcentroids.push({\n\t\tf1: firstFeature.f1,\n\t\tf2: firstFeature.f2,\n\t\tf3: firstFeature.f3,\n\t});\n\n\t// Choose remaining centroids with probability proportional to squared distance\n\tconst distances = Array.from({ length: n }, () => Infinity);\n\n\tfor (let c = 1; c < k; c++) {\n\t\t// Update distances to nearest centroid\n\t\tlet totalDistSq = 0;\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst feature = features[i];\n\t\t\tif (feature === undefined) continue;\n\t\t\tconst lastCentroid = centroids[c - 1];\n\t\t\tif (lastCentroid === undefined) continue;\n\t\t\tconst dist = euclideanDistance(feature, lastCentroid);\n\t\t\tconst currentMin = distances[i];\n\t\t\tif (currentMin !== undefined && dist < currentMin) {\n\t\t\t\tdistances[i] = dist;\n\t\t\t}\n\t\t\tconst d = distances[i];\n\t\t\tif (d !== undefined) {\n\t\t\t\ttotalDistSq += d * d;\n\t\t\t}\n\t\t}\n\n\t\t// Choose next centroid with probability proportional to squared distance\n\t\tconst threshold = rng() * totalDistSq;\n\t\tlet cumulative = 0;\n\t\tlet nextIdx = 0;\n\t\tfor (let i = 0; i < n; i++) {\n\t\t\tconst d = distances[i];\n\t\t\tif (d !== undefined) {\n\t\t\t\tcumulative += d * d;\n\t\t\t\tif (cumulative >= threshold) {\n\t\t\t\t\tnextIdx = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst nextFeature = features[nextIdx];\n\t\tif (nextFeature !== undefined) {\n\t\t\tcentroids.push({\n\t\t\t\tf1: nextFeature.f1,\n\t\t\t\tf2: nextFeature.f2,\n\t\t\t\tf3: nextFeature.f3,\n\t\t\t});\n\t\t} else {\n\t\t\t// Fallback: use zero centroid\n\t\t\tcentroids.push({ f1: 0, f2: 0, f3: 0 });\n\t\t}\n\t}\n\n\treturn centroids;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { ExpansionPath } from '../../expansion/types';
|
|
3
|
+
import { BaselineConfig, BaselineResult } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Rank paths by length (shortest first).
|
|
6
|
+
*
|
|
7
|
+
* Score = 1 / path_length, normalised to [0, 1].
|
|
8
|
+
*
|
|
9
|
+
* @param _graph - Source graph (unused for length ranking)
|
|
10
|
+
* @param paths - Paths to rank
|
|
11
|
+
* @param config - Configuration options
|
|
12
|
+
* @returns Ranked paths (shortest first)
|
|
13
|
+
*/
|
|
14
|
+
export declare function shortest<N extends NodeData, E extends EdgeData>(_graph: ReadableGraph<N, E>, paths: readonly ExpansionPath[], config?: BaselineConfig): BaselineResult;
|
|
15
|
+
//# sourceMappingURL=shortest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortest.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/shortest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAc,MAAM,SAAS,CAAC;AAE1E;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,GACrB,cAAc,CAiChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shortest.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/shortest.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { ExpansionPath } from '../../expansion/types';
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for baseline ranking methods.
|
|
5
|
+
*/
|
|
6
|
+
export interface BaselineConfig {
|
|
7
|
+
/** Whether to include scores in result */
|
|
8
|
+
readonly includeScores?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A scored path from baseline ranking.
|
|
12
|
+
*/
|
|
13
|
+
export interface ScoredPath extends ExpansionPath {
|
|
14
|
+
/** Ranking score */
|
|
15
|
+
readonly score: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Result from baseline ranking.
|
|
19
|
+
*/
|
|
20
|
+
export interface BaselineResult {
|
|
21
|
+
/** Paths ranked by score */
|
|
22
|
+
readonly paths: readonly ScoredPath[];
|
|
23
|
+
/** Ranking method name */
|
|
24
|
+
readonly method: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Path ranking function type.
|
|
28
|
+
*/
|
|
29
|
+
export type PathRanker<N extends NodeData = NodeData, E extends EdgeData = EdgeData> = (graph: ReadableGraph<N, E>, paths: readonly ExpansionPath[], config?: BaselineConfig) => BaselineResult;
|
|
30
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ranking/baselines/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,aAAa;IAChD,oBAAoB;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,CACrB,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAC1B,CACH,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,cAAc,KACnB,cAAc,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path ranking module.
|
|
3
|
+
*
|
|
4
|
+
* Provides PARSE (Path-Aware Ranking via Salience Estimation) and
|
|
5
|
+
* baseline ranking methods for comparing discovered paths.
|
|
6
|
+
*
|
|
7
|
+
* @module ranking
|
|
8
|
+
*/
|
|
9
|
+
export { parse } from './parse';
|
|
10
|
+
export type { PARSEConfig, PARSEResult, RankedPath } from './parse';
|
|
11
|
+
export type { MIFunction, MIVariantName, MIConfig, AdaptiveMIConfig, } from './mi/types';
|
|
12
|
+
export { jaccard, adamicAdar, scale, skew, span, etch, notch, adaptive, } from './mi/index';
|
|
13
|
+
export { shortest } from './baselines/shortest';
|
|
14
|
+
export type { BaselineConfig, BaselineResult, ScoredPath, PathRanker, } from './baselines/types';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ranking/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAGpE,YAAY,EACX,UAAU,EACV,aAAa,EACb,QAAQ,EACR,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACN,OAAO,EACP,UAAU,EACV,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,QAAQ,GACR,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,YAAY,EACX,cAAc,EACd,cAAc,EACd,UAAU,EACV,UAAU,GACV,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute Adamic-Adar index between neighbourhoods of two nodes.
|
|
5
|
+
*
|
|
6
|
+
* @param graph - Source graph
|
|
7
|
+
* @param source - Source node ID
|
|
8
|
+
* @param target - Target node ID
|
|
9
|
+
* @param config - Optional configuration
|
|
10
|
+
* @returns Adamic-Adar index (normalised to [0, 1] if configured)
|
|
11
|
+
*/
|
|
12
|
+
export declare function adamicAdar<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
13
|
+
//# sourceMappingURL=adamic-adar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adamic-adar.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/adamic-adar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAChE,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAuCR"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { AdaptiveMIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute unified adaptive MI between two connected nodes.
|
|
5
|
+
*
|
|
6
|
+
* Combines structural, degree, and overlap signals with
|
|
7
|
+
* adaptive weighting based on graph density.
|
|
8
|
+
*
|
|
9
|
+
* @param graph - Source graph
|
|
10
|
+
* @param source - Source node ID
|
|
11
|
+
* @param target - Target node ID
|
|
12
|
+
* @param config - Optional configuration with component weights
|
|
13
|
+
* @returns Adaptive MI score in [0, 1]
|
|
14
|
+
*/
|
|
15
|
+
export declare function adaptive<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: AdaptiveMIConfig): number;
|
|
16
|
+
//# sourceMappingURL=adaptive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adaptive.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIhD;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC9D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,gBAAgB,GACvB,MAAM,CAmDR"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute ETCH MI between two nodes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function etch<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
7
|
+
//# sourceMappingURL=etch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"etch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/etch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CA6DR"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mutual Information (MI) variants module.
|
|
3
|
+
*
|
|
4
|
+
* MI measures quantify the strength of association between connected nodes.
|
|
5
|
+
* These are used in PARSE for computing path salience via geometric mean.
|
|
6
|
+
*
|
|
7
|
+
* @module ranking/mi
|
|
8
|
+
*/
|
|
9
|
+
export type { MIFunction, MIVariantName, MIConfig, AdaptiveMIConfig, } from './types';
|
|
10
|
+
export { jaccard } from './jaccard';
|
|
11
|
+
export { adamicAdar } from './adamic-adar';
|
|
12
|
+
export { scale } from './scale';
|
|
13
|
+
export { skew } from './skew';
|
|
14
|
+
export { span } from './span';
|
|
15
|
+
export { etch } from './etch';
|
|
16
|
+
export { notch } from './notch';
|
|
17
|
+
export { adaptive } from './adaptive';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EACX,UAAU,EACV,aAAa,EACb,QAAQ,EACR,gBAAgB,GAChB,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute Jaccard similarity between neighbourhoods of two nodes.
|
|
5
|
+
*
|
|
6
|
+
* @param graph - Source graph
|
|
7
|
+
* @param source - Source node ID
|
|
8
|
+
* @param target - Target node ID
|
|
9
|
+
* @param config - Optional configuration
|
|
10
|
+
* @returns Jaccard coefficient in [0, 1]
|
|
11
|
+
*/
|
|
12
|
+
export declare function jaccard<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
13
|
+
//# sourceMappingURL=jaccard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jaccard.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/jaccard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC7D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAgCR"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mi-variants.unit.test.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/mi-variants.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute NOTCH MI between two nodes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function notch<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
7
|
+
//# sourceMappingURL=notch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notch.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/notch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAkCR"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute SCALE MI between two nodes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function scale<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
7
|
+
//# sourceMappingURL=scale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scale.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/scale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAsCR"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute SKEW MI between two nodes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function skew<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
7
|
+
//# sourceMappingURL=skew.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skew.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/skew.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAuCR"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
import { MIConfig } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compute SPAN MI between two nodes.
|
|
5
|
+
*/
|
|
6
|
+
export declare function span<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, source: NodeId, target: NodeId, config?: MIConfig): number;
|
|
7
|
+
//# sourceMappingURL=span.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"span.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/span.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC1D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,QAAQ,GACf,MAAM,CAkCR"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { NodeId, NodeData, EdgeData, ReadableGraph } from '../../graph';
|
|
2
|
+
/**
|
|
3
|
+
* MI function computes association strength between connected nodes.
|
|
4
|
+
*
|
|
5
|
+
* @param graph - Source graph
|
|
6
|
+
* @param source - Source node ID
|
|
7
|
+
* @param target - Target node ID
|
|
8
|
+
* @returns MI score in [0, 1] range (0 = no association, 1 = perfect)
|
|
9
|
+
*/
|
|
10
|
+
export type MIFunction<N extends NodeData = NodeData, E extends EdgeData = EdgeData> = (graph: ReadableGraph<N, E>, source: NodeId, target: NodeId) => number;
|
|
11
|
+
/**
|
|
12
|
+
* Names of available MI variants.
|
|
13
|
+
*/
|
|
14
|
+
export type MIVariantName = "jaccard" | "adamic-adar" | "scale" | "skew" | "span" | "etch" | "notch" | "adaptive";
|
|
15
|
+
/**
|
|
16
|
+
* Configuration for MI computation.
|
|
17
|
+
*/
|
|
18
|
+
export interface MIConfig {
|
|
19
|
+
/** Epsilon for numerical stability */
|
|
20
|
+
readonly epsilon?: number;
|
|
21
|
+
/** Whether to normalise result to [0, 1] */
|
|
22
|
+
readonly normalise?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Configuration for Adaptive MI.
|
|
26
|
+
*/
|
|
27
|
+
export interface AdaptiveMIConfig extends MIConfig {
|
|
28
|
+
/** Weight for structural (Jaccard) MI component */
|
|
29
|
+
readonly structuralWeight?: number;
|
|
30
|
+
/** Weight for degree-weighted (Adamic-Adar) MI component */
|
|
31
|
+
readonly degreeWeight?: number;
|
|
32
|
+
/** Weight for overlap coefficient component */
|
|
33
|
+
readonly overlapWeight?: number;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/ranking/mi/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,MAAM,UAAU,CACrB,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAC1B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,aAAa,GACtB,SAAS,GACT,aAAa,GACb,OAAO,GACP,MAAM,GACN,MAAM,GACN,MAAM,GACN,OAAO,GACP,UAAU,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IACjD,mDAAmD;IACnD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CAChC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { NodeData, EdgeData, ReadableGraph } from '../graph';
|
|
2
|
+
import { ExpansionPath } from '../expansion/types';
|
|
3
|
+
import { MIFunction } from './mi/types';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for PARSE ranking.
|
|
6
|
+
*/
|
|
7
|
+
export interface PARSEConfig<N extends NodeData = NodeData, E extends EdgeData = EdgeData> {
|
|
8
|
+
/** MI function to use (default: jaccard) */
|
|
9
|
+
readonly mi?: MIFunction<N, E>;
|
|
10
|
+
/** Minimum epsilon for MI (default: 1e-10) */
|
|
11
|
+
readonly epsilon?: number;
|
|
12
|
+
/** Whether to include salience scores in result (default: true) */
|
|
13
|
+
readonly includeSalience?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A ranked path with salience score.
|
|
17
|
+
*/
|
|
18
|
+
export interface RankedPath extends ExpansionPath {
|
|
19
|
+
/** Salience score (geometric mean of edge MI) */
|
|
20
|
+
readonly salience: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Result of PARSE ranking.
|
|
24
|
+
*/
|
|
25
|
+
export interface PARSEResult {
|
|
26
|
+
/** Paths ranked by salience (highest first) */
|
|
27
|
+
readonly paths: readonly RankedPath[];
|
|
28
|
+
/** Ranking statistics */
|
|
29
|
+
readonly stats: {
|
|
30
|
+
/** Total paths ranked */
|
|
31
|
+
readonly pathsRanked: number;
|
|
32
|
+
/** Mean salience */
|
|
33
|
+
readonly meanSalience: number;
|
|
34
|
+
/** Median salience */
|
|
35
|
+
readonly medianSalience: number;
|
|
36
|
+
/** Maximum salience */
|
|
37
|
+
readonly maxSalience: number;
|
|
38
|
+
/** Minimum salience */
|
|
39
|
+
readonly minSalience: number;
|
|
40
|
+
/** Ranking duration in milliseconds */
|
|
41
|
+
readonly durationMs: number;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Rank paths using PARSE (Path-Aware Ranking via Salience Estimation).
|
|
46
|
+
*
|
|
47
|
+
* Computes geometric mean of edge MI scores for each path,
|
|
48
|
+
* then sorts by salience (highest first).
|
|
49
|
+
*
|
|
50
|
+
* @param graph - Source graph
|
|
51
|
+
* @param paths - Paths to rank
|
|
52
|
+
* @param config - Configuration options
|
|
53
|
+
* @returns Ranked paths with statistics
|
|
54
|
+
*/
|
|
55
|
+
export declare function parse<N extends NodeData, E extends EdgeData>(graph: ReadableGraph<N, E>, paths: readonly ExpansionPath[], config?: PARSEConfig<N, E>): PARSEResult;
|
|
56
|
+
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../src/ranking/parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C;;GAEG;AACH,MAAM,WAAW,WAAW,CAC3B,CAAC,SAAS,QAAQ,GAAG,QAAQ,EAC7B,CAAC,SAAS,QAAQ,GAAG,QAAQ;IAE7B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/B,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,mEAAmE;IACnE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,aAAa;IAChD,iDAAiD;IACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,yBAAyB;IACzB,QAAQ,CAAC,KAAK,EAAE;QACf,yBAAyB;QACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,oBAAoB;QACpB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,sBAAsB;QACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,uBAAuB;QACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,uBAAuB;QACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,uCAAuC;QACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC5B,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,QAAQ,EAC3D,KAAK,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC1B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,GACxB,WAAW,CAoDb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.unit.test.d.ts","sourceRoot":"","sources":["../../src/ranking/parse.unit.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Attach a type guard directly to a Zod schema.
|
|
4
|
+
*
|
|
5
|
+
* This keeps the runtime validator, the inferred TypeScript type,
|
|
6
|
+
* and the runtime type guard derived from the same source.
|
|
7
|
+
*/
|
|
8
|
+
export declare function defineSchema<T extends z.ZodType>(schema: T): T & {
|
|
9
|
+
is(value: unknown): value is z.infer<T>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Create a schema with a custom type guard name for better error messages.
|
|
13
|
+
*/
|
|
14
|
+
export declare function defineNamedSchema<T extends z.ZodType>(name: string, schema: T): T & {
|
|
15
|
+
is(value: unknown): value is z.infer<T>;
|
|
16
|
+
typeName: string;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=define.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/schemas/define.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAC/C,MAAM,EAAE,CAAC,GACP,CAAC,GAAG;IAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;CAAE,CAMjD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EACpD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,GACP,CAAC,GAAG;IAAE,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAOnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.unit.test.d.ts","sourceRoot":"","sources":["../../src/schemas/define.unit.test.ts"],"names":[],"mappings":""}
|