@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.
Files changed (72) hide show
  1. package/dist/algorithm-options.d.ts +5 -0
  2. package/dist/algorithm-options.d.ts.map +1 -0
  3. package/dist/algorithm-options.js +285 -0
  4. package/dist/algorithm-options.js.map +1 -0
  5. package/dist/algorithms.d.ts +489 -0
  6. package/dist/algorithms.d.ts.map +1 -0
  7. package/dist/algorithms.js +1184 -0
  8. package/dist/algorithms.js.map +1 -0
  9. package/dist/cdn/chunks/elements-DkrLtNP8.js +1 -0
  10. package/dist/cdn/chunks/gpu-platform-browser-VBah74fl.js +2825 -0
  11. package/dist/cdn/chunks/index-C4RZkds_.js +10 -0
  12. package/dist/cdn/chunks/index-CAhmhhmb.js +1 -0
  13. package/dist/cdn/chunks/io-Da5POp5D.js +268 -0
  14. package/dist/cdn/chunks/preload-helper-DEpZAvig.js +1 -0
  15. package/dist/cdn/chunks/samples-BkLzaDJ3.js +1 -0
  16. package/dist/cdn/chunks/sigv4-EokFic1V-CWJiFeEe.js +3 -0
  17. package/dist/cdn/chunks/sources-cypher-BGGD4kJ9.js +5 -0
  18. package/dist/cdn/chunks/sources-ndex-CxnPOYff.js +1 -0
  19. package/dist/cdn/chunks/sources-rest-BPNV8mX-.js +1 -0
  20. package/dist/cdn/chunks/sources-sparql-BiqRQuHD.js +5 -0
  21. package/dist/cdn/cytoscape-extensions.js +1 -0
  22. package/dist/cdn/io.js +1 -0
  23. package/dist/cytoscape-extensions.bundle.js +2825 -0
  24. package/dist/elements.d.ts +69 -0
  25. package/dist/elements.d.ts.map +1 -0
  26. package/dist/elements.js +343 -0
  27. package/dist/elements.js.map +1 -0
  28. package/dist/gpu-platform-browser.d.ts +11 -0
  29. package/dist/gpu-platform-browser.d.ts.map +1 -0
  30. package/dist/gpu-platform-browser.js +22 -0
  31. package/dist/gpu-platform-browser.js.map +1 -0
  32. package/dist/gpu-platform-node.d.ts +15 -0
  33. package/dist/gpu-platform-node.d.ts.map +1 -0
  34. package/dist/gpu-platform-node.js +27 -0
  35. package/dist/gpu-platform-node.js.map +1 -0
  36. package/dist/gpu.d.ts +149 -0
  37. package/dist/gpu.d.ts.map +1 -0
  38. package/dist/gpu.js +312 -0
  39. package/dist/gpu.js.map +1 -0
  40. package/dist/graph-data.d.ts +101 -0
  41. package/dist/graph-data.d.ts.map +1 -0
  42. package/dist/graph-data.js +147 -0
  43. package/dist/graph-data.js.map +1 -0
  44. package/dist/index.d.ts +36 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +48 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/io.d.ts +111 -0
  49. package/dist/io.d.ts.map +1 -0
  50. package/dist/io.js +258 -0
  51. package/dist/io.js.map +1 -0
  52. package/dist/layouts.d.ts +207 -0
  53. package/dist/layouts.d.ts.map +1 -0
  54. package/dist/layouts.js +615 -0
  55. package/dist/layouts.js.map +1 -0
  56. package/dist/lazy.d.ts +21 -0
  57. package/dist/lazy.d.ts.map +1 -0
  58. package/dist/lazy.js +32 -0
  59. package/dist/lazy.js.map +1 -0
  60. package/dist/samples.d.ts +115 -0
  61. package/dist/samples.d.ts.map +1 -0
  62. package/dist/samples.js +237 -0
  63. package/dist/samples.js.map +1 -0
  64. package/dist/snapshot.d.ts +81 -0
  65. package/dist/snapshot.d.ts.map +1 -0
  66. package/dist/snapshot.js +225 -0
  67. package/dist/snapshot.js.map +1 -0
  68. package/dist/webgpu-provider.d.ts +25 -0
  69. package/dist/webgpu-provider.d.ts.map +1 -0
  70. package/dist/webgpu-provider.js +53 -0
  71. package/dist/webgpu-provider.js.map +1 -0
  72. package/package.json +13 -9
@@ -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.28",
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.48",
75
- "@graphty/webgpu-graph-algorithms": "^0.6.61",
76
- "@graphty/graph-samples": "^0.1.39"
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.0.11",
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.0.5",
107
+ "vite": "^7.3.7",
105
108
  "vitest": "4.1.11",
106
- "@graphty/graph-format": "^1.4.7",
107
- "@graphty/algorithms": "^3.4.14",
108
- "@graphty/layout": "^2.5.10"
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",