@graphty/cytoscape-extensions 0.0.28 → 0.0.29
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/algorithm-options.d.ts +5 -0
- package/dist/algorithm-options.d.ts.map +1 -0
- package/dist/algorithm-options.js +285 -0
- package/dist/algorithm-options.js.map +1 -0
- package/dist/algorithms.d.ts +489 -0
- package/dist/algorithms.d.ts.map +1 -0
- package/dist/algorithms.js +1184 -0
- package/dist/algorithms.js.map +1 -0
- package/dist/cdn/chunks/elements-DkrLtNP8.js +1 -0
- package/dist/cdn/chunks/gpu-platform-browser-VBah74fl.js +2825 -0
- package/dist/cdn/chunks/index-C4RZkds_.js +10 -0
- package/dist/cdn/chunks/index-CAhmhhmb.js +1 -0
- package/dist/cdn/chunks/io-Da5POp5D.js +268 -0
- package/dist/cdn/chunks/preload-helper-DEpZAvig.js +1 -0
- package/dist/cdn/chunks/samples-BkLzaDJ3.js +1 -0
- package/dist/cdn/chunks/sigv4-EokFic1V-CWJiFeEe.js +3 -0
- package/dist/cdn/chunks/sources-cypher-BGGD4kJ9.js +5 -0
- package/dist/cdn/chunks/sources-ndex-CxnPOYff.js +1 -0
- package/dist/cdn/chunks/sources-rest-BPNV8mX-.js +1 -0
- package/dist/cdn/chunks/sources-sparql-BiqRQuHD.js +5 -0
- package/dist/cdn/cytoscape-extensions.js +1 -0
- package/dist/cdn/io.js +1 -0
- package/dist/cytoscape-extensions.bundle.js +2825 -0
- package/dist/elements.d.ts +69 -0
- package/dist/elements.d.ts.map +1 -0
- package/dist/elements.js +343 -0
- package/dist/elements.js.map +1 -0
- package/dist/gpu-platform-browser.d.ts +11 -0
- package/dist/gpu-platform-browser.d.ts.map +1 -0
- package/dist/gpu-platform-browser.js +22 -0
- package/dist/gpu-platform-browser.js.map +1 -0
- package/dist/gpu-platform-node.d.ts +15 -0
- package/dist/gpu-platform-node.d.ts.map +1 -0
- package/dist/gpu-platform-node.js +27 -0
- package/dist/gpu-platform-node.js.map +1 -0
- package/dist/gpu.d.ts +149 -0
- package/dist/gpu.d.ts.map +1 -0
- package/dist/gpu.js +312 -0
- package/dist/gpu.js.map +1 -0
- package/dist/graph-data.d.ts +101 -0
- package/dist/graph-data.d.ts.map +1 -0
- package/dist/graph-data.js +147 -0
- package/dist/graph-data.js.map +1 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/io.d.ts +111 -0
- package/dist/io.d.ts.map +1 -0
- package/dist/io.js +258 -0
- package/dist/io.js.map +1 -0
- package/dist/layouts.d.ts +207 -0
- package/dist/layouts.d.ts.map +1 -0
- package/dist/layouts.js +615 -0
- package/dist/layouts.js.map +1 -0
- package/dist/lazy.d.ts +21 -0
- package/dist/lazy.d.ts.map +1 -0
- package/dist/lazy.js +32 -0
- package/dist/lazy.js.map +1 -0
- package/dist/samples.d.ts +115 -0
- package/dist/samples.d.ts.map +1 -0
- package/dist/samples.js +237 -0
- package/dist/samples.js.map +1 -0
- package/dist/snapshot.d.ts +81 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +225 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/webgpu-provider.d.ts +25 -0
- package/dist/webgpu-provider.d.ts.map +1 -0
- package/dist/webgpu-provider.js +53 -0
- package/dist/webgpu-provider.js.map +1 -0
- package/package.json +13 -9
package/dist/snapshot.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conversion between Cytoscape elements and the graph-format snapshot every graphty layout and algorithm takes.
|
|
3
|
+
*
|
|
4
|
+
* A snapshot addresses nodes and edges by dense index. Here node index i is `nodes[i]` and edge index e is
|
|
5
|
+
* `edges[e]`, in the collection order Cytoscape gave, so a result array maps back to elements by position.
|
|
6
|
+
*/
|
|
7
|
+
import { fromEdgeArrays } from "@graphty/graph-format";
|
|
8
|
+
const state = new WeakMap();
|
|
9
|
+
/** Runs still using each snapshot; a snapshot the cache drops while it has holds is released when the last ends. */
|
|
10
|
+
const holds = new Map();
|
|
11
|
+
/** Snapshots the cache dropped while held, and the core state whose listeners release them. */
|
|
12
|
+
const deferred = new Map();
|
|
13
|
+
/**
|
|
14
|
+
* The core of a collection. Every collection has `cy()` at run time; Cytoscape's typings declare it only on single
|
|
15
|
+
* elements.
|
|
16
|
+
* @param eles - the collection
|
|
17
|
+
* @returns its core
|
|
18
|
+
*/
|
|
19
|
+
export function coreOf(eles) {
|
|
20
|
+
return eles.cy();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The per-core cache state; the first call subscribes to the events that change the graph.
|
|
24
|
+
* @param cy - the core
|
|
25
|
+
* @returns its cache state
|
|
26
|
+
*/
|
|
27
|
+
function coreState(cy) {
|
|
28
|
+
let s = state.get(cy);
|
|
29
|
+
if (s === undefined) {
|
|
30
|
+
const created = { version: 0, entries: [], dropListeners: new Set() };
|
|
31
|
+
// ponytail: "data" fires for any field, so writing a result into data also invalidates; a per-field
|
|
32
|
+
// check would need Cytoscape to say which field changed, and it does not.
|
|
33
|
+
cy.on("add remove data move", () => {
|
|
34
|
+
created.version++;
|
|
35
|
+
drop(created, created.entries);
|
|
36
|
+
created.entries = [];
|
|
37
|
+
});
|
|
38
|
+
state.set(cy, created);
|
|
39
|
+
s = created;
|
|
40
|
+
}
|
|
41
|
+
return s;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Tells the drop listeners about entries leaving the cache.
|
|
45
|
+
* @param cs - the core's cache state
|
|
46
|
+
* @param gone - the entries
|
|
47
|
+
*/
|
|
48
|
+
function drop(cs, gone) {
|
|
49
|
+
const now = [];
|
|
50
|
+
for (const { value } of gone) {
|
|
51
|
+
if (holds.has(value.snapshot)) {
|
|
52
|
+
deferred.set(value.snapshot, cs);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
now.push(value.snapshot);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
notify(cs, now);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Tells a core's drop listeners about snapshots to release.
|
|
62
|
+
* @param cs - the core's cache state
|
|
63
|
+
* @param snapshots - the snapshots
|
|
64
|
+
*/
|
|
65
|
+
function notify(cs, snapshots) {
|
|
66
|
+
if (snapshots.length > 0) {
|
|
67
|
+
for (const listener of cs.dropListeners) {
|
|
68
|
+
listener(snapshots);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Keeps a snapshot from being released while a run uses it: when the cache drops it (a data change, say) during
|
|
74
|
+
* the run, its release waits until every hold on it is let go.
|
|
75
|
+
* @param s - the snapshot
|
|
76
|
+
* @returns lets go of the hold; calling it again does nothing
|
|
77
|
+
*/
|
|
78
|
+
export function hold(s) {
|
|
79
|
+
holds.set(s, (holds.get(s) ?? 0) + 1);
|
|
80
|
+
let held = true;
|
|
81
|
+
return () => {
|
|
82
|
+
if (!held) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
held = false;
|
|
86
|
+
const left = (holds.get(s) ?? 1) - 1;
|
|
87
|
+
if (left > 0) {
|
|
88
|
+
holds.set(s, left);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
holds.delete(s);
|
|
92
|
+
const cs = deferred.get(s);
|
|
93
|
+
if (cs !== undefined) {
|
|
94
|
+
deferred.delete(s);
|
|
95
|
+
notify(cs, [s]);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Subscribes to the snapshots a core's cache lets go of.
|
|
101
|
+
* @param cy - the core
|
|
102
|
+
* @param listener - called with the dropped snapshots
|
|
103
|
+
* @returns the unsubscriber
|
|
104
|
+
*/
|
|
105
|
+
export function onSnapshotsDropped(cy, listener) {
|
|
106
|
+
const cs = coreState(cy);
|
|
107
|
+
cs.dropListeners.add(listener);
|
|
108
|
+
return () => {
|
|
109
|
+
cs.dropListeners.delete(listener);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Builds (or returns the cached) snapshot of a collection. The cache holds one snapshot per option set per core and
|
|
114
|
+
* is dropped when an element is added, removed, moved to other endpoints, or has its data changed.
|
|
115
|
+
* @param eles - the collection to read: its nodes, and its edges whose endpoints are both in it
|
|
116
|
+
* @param options - directed flag and weight field
|
|
117
|
+
* @returns the snapshot and the element arrays its indices refer to
|
|
118
|
+
*/
|
|
119
|
+
export function toSnapshot(eles, options = {}) {
|
|
120
|
+
const directed = options.directed ?? false;
|
|
121
|
+
const all = eles;
|
|
122
|
+
if (typeof options.weight === "function") {
|
|
123
|
+
return build(all, directed, options.weight);
|
|
124
|
+
}
|
|
125
|
+
const key = `${String(directed)}|${options.weight ?? ""}`;
|
|
126
|
+
const cs = coreState(coreOf(eles));
|
|
127
|
+
// the same elements in the same order: indices follow the collection's order, so a reordered one is another snapshot
|
|
128
|
+
const hit = cs.entries.find((e) => e.key === key && e.version === cs.version && sameOrder(e.eles, all));
|
|
129
|
+
if (hit !== undefined) {
|
|
130
|
+
return hit.value;
|
|
131
|
+
}
|
|
132
|
+
const value = build(all, directed, options.weight);
|
|
133
|
+
drop(cs, cs.entries.filter((e) => e.key === key));
|
|
134
|
+
cs.entries = [...cs.entries.filter((e) => e.key !== key), { key, eles: all, version: cs.version, value }];
|
|
135
|
+
return value;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Whether two collections hold the same elements in the same order.
|
|
139
|
+
* @param a - one collection
|
|
140
|
+
* @param b - the other
|
|
141
|
+
* @returns true when they match element by element
|
|
142
|
+
*/
|
|
143
|
+
function sameOrder(a, b) {
|
|
144
|
+
if (a.length !== b.length) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
for (let i = 0; i < a.length; i++) {
|
|
148
|
+
if (a[i] !== b[i]) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Builds a snapshot without the cache.
|
|
156
|
+
* @param eles - the collection
|
|
157
|
+
* @param directed - whether the snapshot is directed
|
|
158
|
+
* @param weight - edge data field or function of the weight, or undefined for none
|
|
159
|
+
* @returns the snapshot and element arrays
|
|
160
|
+
*/
|
|
161
|
+
function build(eles, directed, weight) {
|
|
162
|
+
const nodes = eles.nodes();
|
|
163
|
+
const ids = [];
|
|
164
|
+
const index = new Map();
|
|
165
|
+
nodes.forEach((n, i) => {
|
|
166
|
+
ids.push(n.id());
|
|
167
|
+
index.set(n.id(), i);
|
|
168
|
+
});
|
|
169
|
+
const edges = eles.edges().filter((e) => index.has(e.source().id()) && index.has(e.target().id()));
|
|
170
|
+
const src = new Uint32Array(edges.length);
|
|
171
|
+
const dst = new Uint32Array(edges.length);
|
|
172
|
+
const weights = weight === undefined ? undefined : new Float64Array(edges.length);
|
|
173
|
+
edges.forEach((e, k) => {
|
|
174
|
+
src[k] = index.get(e.source().id()) ?? 0;
|
|
175
|
+
dst[k] = index.get(e.target().id()) ?? 0;
|
|
176
|
+
if (weights !== undefined && weight !== undefined) {
|
|
177
|
+
const w = typeof weight === "function" ? weight(e) : e.data(weight);
|
|
178
|
+
weights[k] = typeof w === "number" && Number.isFinite(w) ? w : 1;
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
const snapshot = fromEdgeArrays({ directed, ids, src, dst, weights });
|
|
182
|
+
return { snapshot, nodes, edges };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Writes one value per element into its data, in one batch (one style pass).
|
|
186
|
+
* @param elements - `nodes` or `edges` of a CytoscapeSnapshot, in index order
|
|
187
|
+
* @param values - one value per element
|
|
188
|
+
* @param field - the data field to write
|
|
189
|
+
*/
|
|
190
|
+
export function writeData(elements, values, field) {
|
|
191
|
+
coreOf(elements).batch(() => {
|
|
192
|
+
elements.forEach((ele, i) => {
|
|
193
|
+
ele.data(field, values[i]);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Indices of the snapshot's nodes in a selection.
|
|
199
|
+
* @param cs - the snapshot
|
|
200
|
+
* @param sel - a selector or a collection
|
|
201
|
+
* @returns the node indices, in collection order
|
|
202
|
+
*/
|
|
203
|
+
export function indicesOf(cs, sel) {
|
|
204
|
+
const picked = typeof sel === "string" ? cs.nodes.filter(sel) : cs.nodes.intersection(sel);
|
|
205
|
+
return picked.map((n) => cs.snapshot.ids.requireIndex(n.id()));
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* The index of the first node of a selection.
|
|
209
|
+
* @param cs - the snapshot
|
|
210
|
+
* @param sel - a selector or a collection, or undefined
|
|
211
|
+
* @param what - the option name, for the error
|
|
212
|
+
* @returns the index, or undefined when no selection was given
|
|
213
|
+
* @throws Error when the selection matches no node of the snapshot
|
|
214
|
+
*/
|
|
215
|
+
export function indexOf(cs, sel, what) {
|
|
216
|
+
if (sel === undefined) {
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
const [i] = indicesOf(cs, sel);
|
|
220
|
+
if (i === undefined) {
|
|
221
|
+
throw new Error(`${what} matches no node of the collection`);
|
|
222
|
+
}
|
|
223
|
+
return i;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../src/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The device provider both platform builds (browser and Node) return: probe, request a context, check that the
|
|
3
|
+
* device computes correctly, build the accelerator. Everything here happens before any graph work, so a refusal is
|
|
4
|
+
* detection (the CPU runs and the result says why), never a fallback.
|
|
5
|
+
*
|
|
6
|
+
* Only the lazily loaded "#gpu-platform" chunk imports this module, so @graphty/webgpu-graph-algorithms stays out of
|
|
7
|
+
* the main chunk.
|
|
8
|
+
*/
|
|
9
|
+
import { type GpuContext, type ProbeResult } from "@graphty/webgpu-graph-algorithms";
|
|
10
|
+
import { type GpuProvider, type WebGpuOptions } from "./gpu.js";
|
|
11
|
+
/** How one platform probes for a device and opens a context on it. */
|
|
12
|
+
export interface Platform {
|
|
13
|
+
probe(rejectSoftware: boolean): Promise<ProbeResult>;
|
|
14
|
+
open(probe: ProbeResult, rejectSoftware: boolean, residentSnapshots: number): Promise<GpuContext>;
|
|
15
|
+
/** What the user can do about a refusal code on this platform; codes it does not name have no fix. */
|
|
16
|
+
readonly fixes: Readonly<Record<string, string>>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A provider for a platform.
|
|
20
|
+
* @param platform - the platform's probe, context factory and fixes
|
|
21
|
+
* @param options - the options
|
|
22
|
+
* @returns the provider
|
|
23
|
+
*/
|
|
24
|
+
export declare function providerFor(platform: Platform, options: WebGpuOptions): GpuProvider;
|
|
25
|
+
//# sourceMappingURL=webgpu-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgpu-provider.d.ts","sourceRoot":"","sources":["../src/webgpu-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAqB,KAAK,UAAU,EAAE,KAAK,WAAW,EAAgB,MAAM,kCAAkC,CAAC;AAEtH,OAAO,EAAE,KAAK,WAAW,EAAuB,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAMrF,sEAAsE;AACtE,MAAM,WAAW,QAAQ;IACrB,KAAK,CAAC,cAAc,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,IAAI,CAAC,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAClG,sGAAsG;IACtG,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACpD;AAKD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,GAAG,WAAW,CAgCnF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The device provider both platform builds (browser and Node) return: probe, request a context, check that the
|
|
3
|
+
* device computes correctly, build the accelerator. Everything here happens before any graph work, so a refusal is
|
|
4
|
+
* detection (the CPU runs and the result says why), never a fallback.
|
|
5
|
+
*
|
|
6
|
+
* Only the lazily loaded "#gpu-platform" chunk imports this module, so @graphty/webgpu-graph-algorithms stays out of
|
|
7
|
+
* the main chunk.
|
|
8
|
+
*/
|
|
9
|
+
import { createAccelerator, verifyDevice } from "@graphty/webgpu-graph-algorithms";
|
|
10
|
+
import { GpuUnavailableError } from "./gpu.js";
|
|
11
|
+
// The GPU package warns once when more than 2 snapshots are resident (its default); the adapter caches one snapshot
|
|
12
|
+
// per directed/weight combination per core and releases each when the cache drops it, so a few are normal.
|
|
13
|
+
const RESIDENT_SNAPSHOTS = 8;
|
|
14
|
+
/** The fix of a refused software adapter, on every platform. */
|
|
15
|
+
const SOFTWARE_FIX = "call configureWebGpu({ acceptSoftware: true }) to accept the software adapter";
|
|
16
|
+
/**
|
|
17
|
+
* A provider for a platform.
|
|
18
|
+
* @param platform - the platform's probe, context factory and fixes
|
|
19
|
+
* @param options - the options
|
|
20
|
+
* @returns the provider
|
|
21
|
+
*/
|
|
22
|
+
export function providerFor(platform, options) {
|
|
23
|
+
return {
|
|
24
|
+
acquire: async () => {
|
|
25
|
+
const rejectSoftware = options.acceptSoftware !== true;
|
|
26
|
+
const probe = await platform.probe(rejectSoftware);
|
|
27
|
+
if (!probe.ok) {
|
|
28
|
+
const fix = probe.code === "E_SOFTWARE_ONLY" ? SOFTWARE_FIX : (platform.fixes[probe.code] ?? null);
|
|
29
|
+
throw new GpuUnavailableError(probe.code, probe.reason ?? probe.code, fix);
|
|
30
|
+
}
|
|
31
|
+
const ctx = await platform.open(probe, rejectSoftware, RESIDENT_SNAPSHOTS);
|
|
32
|
+
try {
|
|
33
|
+
// The GPU package's compute entry points refuse a device that fails this check, mid-run. Checking
|
|
34
|
+
// here decides up front, so such a device means the CPU, not an error from the first call.
|
|
35
|
+
const check = await verifyDevice(ctx);
|
|
36
|
+
if (check.mismatch !== null) {
|
|
37
|
+
throw new GpuUnavailableError("E_DEVICE_INCORRECT", `the ${check.vendor} device computes a known prefix sum incorrectly (${check.mismatch.where})`);
|
|
38
|
+
}
|
|
39
|
+
const { caps } = ctx;
|
|
40
|
+
return {
|
|
41
|
+
accelerator: createAccelerator(ctx),
|
|
42
|
+
device: `${caps.vendor} ${caps.device === "" ? caps.description : caps.device}`,
|
|
43
|
+
lost: ctx.lost.then((info) => (info.message === "" ? info.reason : info.message)),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
ctx.dispose();
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=webgpu-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webgpu-provider.js","sourceRoot":"","sources":["../src/webgpu-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,iBAAiB,EAAqC,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEtH,OAAO,EAAoB,mBAAmB,EAAsB,MAAM,UAAU,CAAC;AAErF,oHAAoH;AACpH,2GAA2G;AAC3G,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAU7B,gEAAgE;AAChE,MAAM,YAAY,GAAG,+EAA+E,CAAC;AAErG;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAAkB,EAAE,OAAsB;IAClE,OAAO;QACH,OAAO,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,KAAK,IAAI,CAAC;YACvD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACnD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC;gBACnG,MAAM,IAAI,mBAAmB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YAC/E,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC;YAC3E,IAAI,CAAC;gBACD,kGAAkG;gBAClG,2FAA2F;gBAC3F,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;gBACtC,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;oBAC1B,MAAM,IAAI,mBAAmB,CACzB,oBAAoB,EACpB,OAAO,KAAK,CAAC,MAAM,oDAAoD,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,CACjG,CAAC;gBACN,CAAC;gBACD,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;gBACrB,OAAO;oBACH,WAAW,EAAE,iBAAiB,CAAC,GAAG,CAAC;oBACnC,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE;oBAC/E,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;iBACpF,CAAC;YACN,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,MAAM,KAAK,CAAC;YAChB,CAAC;QACL,CAAC;KACJ,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphty/cytoscape-extensions",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "Graphty layouts, algorithms, graph generators, sample datasets and file import/export as Cytoscape.js extensions",
|
|
5
5
|
"author": "Adam Powers <apowers@ato.ms>",
|
|
6
6
|
"type": "module",
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
},
|
|
72
72
|
"homepage": "https://graphty.app/docs/cytoscape-extensions/",
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@graphty/graph-io": "^0.3.
|
|
75
|
-
"@graphty/webgpu-graph-algorithms": "^0.6.
|
|
76
|
-
"@graphty/graph-samples": "^0.1.
|
|
74
|
+
"@graphty/graph-io": "^0.3.49",
|
|
75
|
+
"@graphty/webgpu-graph-algorithms": "^0.6.62",
|
|
76
|
+
"@graphty/graph-samples": "^0.1.40"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|
|
79
79
|
"@graphty/algorithms": "^3.0.0",
|
|
@@ -89,23 +89,26 @@
|
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@storybook/addon-docs": "^9.0.11",
|
|
92
|
+
"@storybook/addon-vitest": "^9.0.11",
|
|
92
93
|
"@storybook/html-vite": "^9.0.11",
|
|
94
|
+
"@vitest/browser-playwright": "4.1.11",
|
|
93
95
|
"@vitest/coverage-v8": "4.1.11",
|
|
94
96
|
"@vitest/ui": "4.1.11",
|
|
95
97
|
"cytoscape": "^3.34.3",
|
|
96
98
|
"eslint": "^9.29.0",
|
|
99
|
+
"playwright": "^1.53.0",
|
|
97
100
|
"prettier": "^3.4.2",
|
|
98
|
-
"storybook": "^9.
|
|
101
|
+
"storybook": "^9.1.21",
|
|
99
102
|
"tsx": "^4.20.3",
|
|
100
103
|
"typedoc": "^0.28.15",
|
|
101
104
|
"typedoc-plugin-markdown": "^4.9.0",
|
|
102
105
|
"typedoc-vitepress-theme": "^1.1.2",
|
|
103
106
|
"typescript": "^5.9.3",
|
|
104
|
-
"vite": "^7.
|
|
107
|
+
"vite": "^7.3.7",
|
|
105
108
|
"vitest": "4.1.11",
|
|
106
|
-
"@graphty/graph-format": "^1.4.
|
|
107
|
-
"@graphty/algorithms": "^3.4.
|
|
108
|
-
"@graphty/layout": "^2.5.
|
|
109
|
+
"@graphty/graph-format": "^1.4.8",
|
|
110
|
+
"@graphty/algorithms": "^3.4.15",
|
|
111
|
+
"@graphty/layout": "^2.5.11"
|
|
109
112
|
},
|
|
110
113
|
"scripts": {
|
|
111
114
|
"build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && vite build --config vite.bundle.config.ts --mode cdn --logLevel warn && vite build --config vite.bundle.config.ts --logLevel warn",
|
|
@@ -115,6 +118,7 @@
|
|
|
115
118
|
"test": "vitest",
|
|
116
119
|
"test:ui": "vitest --ui",
|
|
117
120
|
"test:run": "vitest run",
|
|
121
|
+
"test:storybook": "vitest run --config vitest.storybook.config.ts",
|
|
118
122
|
"coverage": "vitest run --coverage",
|
|
119
123
|
"coverage:preview": "npx serve coverage -p ${PORT:?start it through servherd, which sets PORT}",
|
|
120
124
|
"storybook": "storybook dev -p ${PORT:?start it through servherd, which sets PORT} --host ${HOST:-localhost} ${HTTPS_CERT_PATH:+--https --ssl-cert $HTTPS_CERT_PATH --ssl-key $HTTPS_KEY_PATH} --no-open",
|