@liveblocks/react-flow 3.17.0-rc1 → 3.18.0-rc1
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/flow.cjs +27 -35
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.js +26 -34
- package/dist/flow.js.map +1 -1
- package/dist/helpers.cjs +57 -15
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.js +52 -14
- package/dist/helpers.js.map +1 -1
- package/dist/index.cjs +0 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -20
- package/dist/index.d.ts +1 -20
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +151 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +78 -0
- package/dist/node.d.ts +78 -0
- package/dist/node.js +149 -0
- package/dist/node.js.map +1 -0
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +25 -5
- package/dist/constants.cjs +0 -35
- package/dist/constants.cjs.map +0 -1
- package/dist/constants.js +0 -31
- package/dist/constants.js.map +0 -1
package/dist/helpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../src/helpers.ts"],"sourcesContent":["import type { JsonObject, SyncConfig } from \"@liveblocks/core\";\nimport { LiveObject } from \"@liveblocks/core\";\nimport type { Edge, Node } from \"@xyflow/react\";\n\nimport {
|
|
1
|
+
{"version":3,"file":"helpers.js","sources":["../src/helpers.ts"],"sourcesContent":["import type { JsonObject, SyncConfig, SyncMode } from \"@liveblocks/core\";\nimport { LiveObject } from \"@liveblocks/core\";\nimport type { Edge, Node } from \"@xyflow/react\";\n\nimport type { InternalLiveblocksEdge, InternalLiveblocksNode } from \"./types\";\n\nexport const DEFAULT_STORAGE_KEY = \"flow\";\n\n// React Flow specific versions of `SyncConfig` that only allow keys that are actually exposed by React Flow.\ntype NodeSyncConfig = { [K in keyof Node]?: SyncMode };\ntype EdgeSyncConfig = { [K in keyof Edge]?: SyncMode };\n\nexport const NODE_BASE_CONFIG = {\n // Local-only (not synced)\n selected: false,\n dragging: false,\n measured: false,\n resizing: false,\n\n // Atomic (synced as plain Json)\n position: \"atomic\",\n sourcePosition: \"atomic\",\n targetPosition: \"atomic\",\n extent: \"atomic\",\n origin: \"atomic\",\n handles: \"atomic\",\n\n // Note: the `data` key is intentionally left out of this base config, as it\n // is expected to be provided by the end user\n} as const satisfies NodeSyncConfig;\n\nexport const EDGE_BASE_CONFIG = {\n // Local-only (not synced)\n selected: false,\n\n // Atomic (synced as plain Json)\n markerStart: \"atomic\",\n markerEnd: \"atomic\",\n label: \"atomic\",\n labelBgPadding: \"atomic\",\n\n // Note: the `data` key is intentionally left out of this base config, as it\n // is expected to be provided by the end user\n} as const satisfies EdgeSyncConfig;\n\n/**\n * Merges a base config with per-type user data configs, returning a lookup\n * function that resolves the full SyncConfig for a given type string.\n */\nexport function buildFlowDataConfigCache(\n base: SyncConfig,\n data?: Record<string, SyncConfig | undefined>\n): (type: string | undefined) => SyncConfig {\n if (!data) return () => base;\n\n const dataFallback = data[\"*\"];\n const fallback = dataFallback ? { ...base, data: dataFallback } : base;\n\n // Pre-compute full sync configs for all explicitly declared types\n const cache = new Map<string | undefined, SyncConfig>();\n for (const type in data) {\n if (type === \"*\") continue;\n const specific = data[type];\n if (!specific) continue;\n const dataConfig: SyncConfig = { ...dataFallback, ...specific };\n cache.set(type, { ...base, data: dataConfig });\n }\n\n return (type) => cache.get(type) || fallback;\n}\n\nexport function buildNodeConfigCache(\n nodeDataConfig?: Record<string, SyncConfig | undefined>\n): (type: string | undefined) => SyncConfig {\n return buildFlowDataConfigCache(NODE_BASE_CONFIG, nodeDataConfig);\n}\n\nexport function buildEdgeConfigCache(\n edgeDataConfig?: Record<string, SyncConfig | undefined>\n): (type: string | undefined) => SyncConfig {\n return buildFlowDataConfigCache(EDGE_BASE_CONFIG, edgeDataConfig);\n}\n\nexport function toLiveblocksInternalNode<N extends Node>(\n node: N,\n config: SyncConfig\n): InternalLiveblocksNode {\n return LiveObject.from(\n node as unknown as JsonObject,\n config\n ) as InternalLiveblocksNode;\n}\n\nexport function toLiveblocksInternalEdge<E extends Edge>(\n edge: E,\n config: SyncConfig\n): InternalLiveblocksEdge {\n return LiveObject.from(\n edge as unknown as JsonObject,\n config\n ) as InternalLiveblocksEdge;\n}\n"],"names":[],"mappings":";;AAMO,MAAM,mBAAsB,GAAA,OAAA;AAM5B,MAAM,gBAAmB,GAAA;AAAA;AAAA,EAE9B,QAAU,EAAA,KAAA;AAAA,EACV,QAAU,EAAA,KAAA;AAAA,EACV,QAAU,EAAA,KAAA;AAAA,EACV,QAAU,EAAA,KAAA;AAAA;AAAA,EAGV,QAAU,EAAA,QAAA;AAAA,EACV,cAAgB,EAAA,QAAA;AAAA,EAChB,cAAgB,EAAA,QAAA;AAAA,EAChB,MAAQ,EAAA,QAAA;AAAA,EACR,MAAQ,EAAA,QAAA;AAAA,EACR,OAAS,EAAA,QAAA;AAAA;AAAA;AAIX,EAAA;AAEO,MAAM,gBAAmB,GAAA;AAAA;AAAA,EAE9B,QAAU,EAAA,KAAA;AAAA;AAAA,EAGV,WAAa,EAAA,QAAA;AAAA,EACb,SAAW,EAAA,QAAA;AAAA,EACX,KAAO,EAAA,QAAA;AAAA,EACP,cAAgB,EAAA,QAAA;AAAA;AAAA;AAIlB,EAAA;AAMgB,SAAA,wBAAA,CACd,MACA,IAC0C,EAAA;AAC1C,EAAA,IAAI,CAAC,IAAA;AAAM,IAAA,OAAO,MAAM,IAAA,CAAA;AAExB,EAAM,MAAA,YAAA,GAAe,KAAK,GAAG,CAAA,CAAA;AAC7B,EAAA,MAAM,WAAW,YAAe,GAAA,EAAE,GAAG,IAAM,EAAA,IAAA,EAAM,cAAiB,GAAA,IAAA,CAAA;AAGlE,EAAM,MAAA,KAAA,uBAAY,GAAoC,EAAA,CAAA;AACtD,EAAA,KAAA,MAAW,QAAQ,IAAM,EAAA;AACvB,IAAA,IAAI,IAAS,KAAA,GAAA;AAAK,MAAA,SAAA;AAClB,IAAM,MAAA,QAAA,GAAW,KAAK,IAAI,CAAA,CAAA;AAC1B,IAAA,IAAI,CAAC,QAAA;AAAU,MAAA,SAAA;AACf,IAAA,MAAM,UAAyB,GAAA,EAAE,GAAG,YAAA,EAAc,GAAG,QAAS,EAAA,CAAA;AAC9D,IAAA,KAAA,CAAM,IAAI,IAAM,EAAA,EAAE,GAAG,IAAM,EAAA,IAAA,EAAM,YAAY,CAAA,CAAA;AAAA,GAC/C;AAEA,EAAA,OAAO,CAAC,IAAA,KAAS,KAAM,CAAA,GAAA,CAAI,IAAI,CAAK,IAAA,QAAA,CAAA;AACtC,CAAA;AAEO,SAAS,qBACd,cAC0C,EAAA;AAC1C,EAAO,OAAA,wBAAA,CAAyB,kBAAkB,cAAc,CAAA,CAAA;AAClE,CAAA;AAEO,SAAS,qBACd,cAC0C,EAAA;AAC1C,EAAO,OAAA,wBAAA,CAAyB,kBAAkB,cAAc,CAAA,CAAA;AAClE,CAAA;AAEgB,SAAA,wBAAA,CACd,MACA,MACwB,EAAA;AACxB,EAAA,OAAO,UAAW,CAAA,IAAA;AAAA,IAChB,IAAA;AAAA,IACA,MAAA;AAAA,GACF,CAAA;AACF,CAAA;AAEgB,SAAA,wBAAA,CACd,MACA,MACwB,EAAA;AACxB,EAAA,OAAO,UAAW,CAAA,IAAA;AAAA,IAChB,IAAA;AAAA,IACA,MAAA;AAAA,GACF,CAAA;AACF;;;;"}
|
package/dist/index.cjs
CHANGED
|
@@ -4,12 +4,9 @@ var core = require('@liveblocks/core');
|
|
|
4
4
|
var version = require('./version.cjs');
|
|
5
5
|
var cursors = require('./cursors.cjs');
|
|
6
6
|
var flow = require('./flow.cjs');
|
|
7
|
-
var helpers = require('./helpers.cjs');
|
|
8
7
|
|
|
9
8
|
core.detectDupes(version.PKG_NAME, version.PKG_VERSION, version.PKG_FORMAT);
|
|
10
9
|
|
|
11
10
|
exports.Cursors = cursors.Cursors;
|
|
12
11
|
exports.useLiveblocksFlow = flow.useLiveblocksFlow;
|
|
13
|
-
exports.toLiveblocksEdge = helpers.toLiveblocksEdge;
|
|
14
|
-
exports.toLiveblocksNode = helpers.toLiveblocksNode;
|
|
15
12
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { CursorsCursorProps, CursorsProps } from \"./cursors\";\nexport { Cursors } from \"./cursors\";\nexport { useLiveblocksFlow } from \"./flow\";\nexport
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { CursorsCursorProps, CursorsProps } from \"./cursors\";\nexport { Cursors } from \"./cursors\";\nexport { useLiveblocksFlow } from \"./flow\";\nexport type {\n EdgeSyncConfig,\n LiveblocksEdge,\n LiveblocksFlow,\n LiveblocksNode,\n NodeSyncConfig,\n SyncConfig,\n SyncMode,\n} from \"./types\";\n"],"names":["detectDupes","PKG_NAME","PKG_VERSION","PKG_FORMAT"],"mappings":";;;;;;;AAIAA,gBAAY,CAAAC,gBAAA,EAAUC,qBAAaC,kBAAU,CAAA;;;;;"}
|
package/dist/index.d.cts
CHANGED
|
@@ -244,23 +244,4 @@ declare function useLiveblocksFlow<N extends Node = BuiltInNode, E extends Edge
|
|
|
244
244
|
suspense: true;
|
|
245
245
|
}): Resolve<LiveblocksFlowSuspenseResult<N, E>>;
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
* @experimental
|
|
249
|
-
*
|
|
250
|
-
* Converts a React Flow `Node` into a Liveblocks Storage version.
|
|
251
|
-
* Keys marked `false` in config are set as local-only (not synced).
|
|
252
|
-
* Keys marked `"atomic"` are stored as plain Json (no deep wrapping).
|
|
253
|
-
* All other keys are deep-liveified (objects→LiveObject, arrays→LiveList).
|
|
254
|
-
*/
|
|
255
|
-
declare function toLiveblocksNode<N extends Node>(node: N, config?: SyncConfig): LiveblocksNode<N>;
|
|
256
|
-
/**
|
|
257
|
-
* @experimental
|
|
258
|
-
*
|
|
259
|
-
* Converts a React Flow `Edge` into a Liveblocks Storage version.
|
|
260
|
-
* Keys marked `false` in config are set as local-only (not synced).
|
|
261
|
-
* Keys marked `"atomic"` are stored as plain Json (no deep wrapping).
|
|
262
|
-
* All other keys are deep-liveified (objects→LiveObject, arrays→LiveList).
|
|
263
|
-
*/
|
|
264
|
-
declare function toLiveblocksEdge<E extends Edge>(edge: E, config?: SyncConfig): LiveblocksEdge<E>;
|
|
265
|
-
|
|
266
|
-
export { Cursors, CursorsCursorProps, CursorsProps, EdgeSyncConfig, LiveblocksEdge, LiveblocksFlow, LiveblocksNode, NodeSyncConfig, toLiveblocksEdge, toLiveblocksNode, useLiveblocksFlow };
|
|
247
|
+
export { Cursors, CursorsCursorProps, CursorsProps, EdgeSyncConfig, LiveblocksEdge, LiveblocksFlow, LiveblocksNode, NodeSyncConfig, useLiveblocksFlow };
|
package/dist/index.d.ts
CHANGED
|
@@ -244,23 +244,4 @@ declare function useLiveblocksFlow<N extends Node = BuiltInNode, E extends Edge
|
|
|
244
244
|
suspense: true;
|
|
245
245
|
}): Resolve<LiveblocksFlowSuspenseResult<N, E>>;
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
* @experimental
|
|
249
|
-
*
|
|
250
|
-
* Converts a React Flow `Node` into a Liveblocks Storage version.
|
|
251
|
-
* Keys marked `false` in config are set as local-only (not synced).
|
|
252
|
-
* Keys marked `"atomic"` are stored as plain Json (no deep wrapping).
|
|
253
|
-
* All other keys are deep-liveified (objects→LiveObject, arrays→LiveList).
|
|
254
|
-
*/
|
|
255
|
-
declare function toLiveblocksNode<N extends Node>(node: N, config?: SyncConfig): LiveblocksNode<N>;
|
|
256
|
-
/**
|
|
257
|
-
* @experimental
|
|
258
|
-
*
|
|
259
|
-
* Converts a React Flow `Edge` into a Liveblocks Storage version.
|
|
260
|
-
* Keys marked `false` in config are set as local-only (not synced).
|
|
261
|
-
* Keys marked `"atomic"` are stored as plain Json (no deep wrapping).
|
|
262
|
-
* All other keys are deep-liveified (objects→LiveObject, arrays→LiveList).
|
|
263
|
-
*/
|
|
264
|
-
declare function toLiveblocksEdge<E extends Edge>(edge: E, config?: SyncConfig): LiveblocksEdge<E>;
|
|
265
|
-
|
|
266
|
-
export { Cursors, CursorsCursorProps, CursorsProps, EdgeSyncConfig, LiveblocksEdge, LiveblocksFlow, LiveblocksNode, NodeSyncConfig, toLiveblocksEdge, toLiveblocksNode, useLiveblocksFlow };
|
|
247
|
+
export { Cursors, CursorsCursorProps, CursorsProps, EdgeSyncConfig, LiveblocksEdge, LiveblocksFlow, LiveblocksNode, NodeSyncConfig, useLiveblocksFlow };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import { detectDupes } from '@liveblocks/core';
|
|
|
2
2
|
import { PKG_NAME, PKG_VERSION, PKG_FORMAT } from './version.js';
|
|
3
3
|
export { Cursors } from './cursors.js';
|
|
4
4
|
export { useLiveblocksFlow } from './flow.js';
|
|
5
|
-
export { toLiveblocksEdge, toLiveblocksNode } from './helpers.js';
|
|
6
5
|
|
|
7
6
|
detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
8
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { CursorsCursorProps, CursorsProps } from \"./cursors\";\nexport { Cursors } from \"./cursors\";\nexport { useLiveblocksFlow } from \"./flow\";\nexport
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { detectDupes } from \"@liveblocks/core\";\n\nimport { PKG_FORMAT, PKG_NAME, PKG_VERSION } from \"./version\";\n\ndetectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);\n\nexport type { CursorsCursorProps, CursorsProps } from \"./cursors\";\nexport { Cursors } from \"./cursors\";\nexport { useLiveblocksFlow } from \"./flow\";\nexport type {\n EdgeSyncConfig,\n LiveblocksEdge,\n LiveblocksFlow,\n LiveblocksNode,\n NodeSyncConfig,\n SyncConfig,\n SyncMode,\n} from \"./types\";\n"],"names":[],"mappings":";;;;;AAIA,WAAY,CAAA,QAAA,EAAU,aAAa,UAAU,CAAA"}
|
package/dist/node.cjs
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@liveblocks/core');
|
|
4
|
+
var helpers = require('./helpers.cjs');
|
|
5
|
+
|
|
6
|
+
async function mutateFlow(options, callback) {
|
|
7
|
+
const { client, roomId } = options;
|
|
8
|
+
const storageKey = options.storageKey ?? helpers.DEFAULT_STORAGE_KEY;
|
|
9
|
+
const getNodeSyncConfig = helpers.buildNodeConfigCache(options.nodes?.sync);
|
|
10
|
+
const getEdgeSyncConfig = helpers.buildEdgeConfigCache(options.edges?.sync);
|
|
11
|
+
const nodeListCache = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
const edgeListCache = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
await client.mutateStorage(roomId, async ({ root }) => {
|
|
14
|
+
let flow = root.get(storageKey);
|
|
15
|
+
if (!flow) {
|
|
16
|
+
const newFlow = new core.LiveObject({
|
|
17
|
+
nodes: new core.LiveMap(),
|
|
18
|
+
edges: new core.LiveMap()
|
|
19
|
+
});
|
|
20
|
+
root.set(storageKey, newFlow);
|
|
21
|
+
flow = newFlow;
|
|
22
|
+
}
|
|
23
|
+
const nodesLiveMap = flow.get("nodes");
|
|
24
|
+
const edgesLiveMap = flow.get("edges");
|
|
25
|
+
function getNodes() {
|
|
26
|
+
const nodeMap = nodesLiveMap.toJSON();
|
|
27
|
+
if (!nodeListCache.has(nodeMap)) {
|
|
28
|
+
nodeListCache.set(nodeMap, Object.values(nodeMap));
|
|
29
|
+
}
|
|
30
|
+
return nodeListCache.get(nodeMap);
|
|
31
|
+
}
|
|
32
|
+
function getEdges() {
|
|
33
|
+
const edgeMap = edgesLiveMap.toJSON();
|
|
34
|
+
if (!edgeListCache.has(edgeMap)) {
|
|
35
|
+
edgeListCache.set(edgeMap, Object.values(edgeMap));
|
|
36
|
+
}
|
|
37
|
+
return edgeListCache.get(edgeMap);
|
|
38
|
+
}
|
|
39
|
+
function getNode(id) {
|
|
40
|
+
return nodesLiveMap.get(id)?.toJSON();
|
|
41
|
+
}
|
|
42
|
+
function getEdge(id) {
|
|
43
|
+
return edgesLiveMap.get(id)?.toJSON();
|
|
44
|
+
}
|
|
45
|
+
function upsertNode(id, newNode) {
|
|
46
|
+
const existing = nodesLiveMap.get(id);
|
|
47
|
+
const syncConfig = getNodeSyncConfig(newNode.type);
|
|
48
|
+
if (!existing) {
|
|
49
|
+
nodesLiveMap.set(id, helpers.toLiveblocksInternalNode(newNode, syncConfig));
|
|
50
|
+
} else {
|
|
51
|
+
existing.reconcile(newNode, syncConfig);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function upsertEdge(id, newEdge) {
|
|
55
|
+
const existing = edgesLiveMap.get(id);
|
|
56
|
+
const syncConfig = getEdgeSyncConfig(newEdge.type);
|
|
57
|
+
if (!existing) {
|
|
58
|
+
edgesLiveMap.set(id, helpers.toLiveblocksInternalEdge(newEdge, syncConfig));
|
|
59
|
+
} else {
|
|
60
|
+
existing.reconcile(newEdge, syncConfig);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const mutableFlow = {
|
|
64
|
+
get nodes() {
|
|
65
|
+
return getNodes();
|
|
66
|
+
},
|
|
67
|
+
get edges() {
|
|
68
|
+
return getEdges();
|
|
69
|
+
},
|
|
70
|
+
toJSON() {
|
|
71
|
+
return { nodes: getNodes(), edges: getEdges() };
|
|
72
|
+
},
|
|
73
|
+
getNode,
|
|
74
|
+
getEdge,
|
|
75
|
+
addNode(node) {
|
|
76
|
+
upsertNode(node.id, node);
|
|
77
|
+
},
|
|
78
|
+
addNodes(nodes) {
|
|
79
|
+
for (const node of nodes) {
|
|
80
|
+
mutableFlow.addNode(node);
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
updateNode(id, partialOrUpdater) {
|
|
84
|
+
const oldNode = getNode(id);
|
|
85
|
+
if (!oldNode)
|
|
86
|
+
return;
|
|
87
|
+
let newNode;
|
|
88
|
+
if (typeof partialOrUpdater === "function") {
|
|
89
|
+
newNode = partialOrUpdater(oldNode);
|
|
90
|
+
} else {
|
|
91
|
+
newNode = { ...oldNode, ...partialOrUpdater };
|
|
92
|
+
}
|
|
93
|
+
return upsertNode(id, newNode);
|
|
94
|
+
},
|
|
95
|
+
updateNodeData(id, partialOrUpdater) {
|
|
96
|
+
return mutableFlow.updateNode(id, (node) => {
|
|
97
|
+
const currData = node.data ?? {};
|
|
98
|
+
const newData = typeof partialOrUpdater === "function" ? partialOrUpdater(currData) : { ...currData, ...partialOrUpdater };
|
|
99
|
+
return { ...node, data: newData };
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
removeNode(id) {
|
|
103
|
+
nodesLiveMap.delete(id);
|
|
104
|
+
},
|
|
105
|
+
removeNodes(ids) {
|
|
106
|
+
for (const id of ids) {
|
|
107
|
+
nodesLiveMap.delete(id);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
addEdge(edge) {
|
|
111
|
+
upsertEdge(edge.id, edge);
|
|
112
|
+
},
|
|
113
|
+
addEdges(edges) {
|
|
114
|
+
for (const edge of edges) {
|
|
115
|
+
mutableFlow.addEdge(edge);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
updateEdge(id, partialOrUpdater) {
|
|
119
|
+
const oldEdge = getEdge(id);
|
|
120
|
+
if (!oldEdge)
|
|
121
|
+
return;
|
|
122
|
+
let newEdge;
|
|
123
|
+
if (typeof partialOrUpdater === "function") {
|
|
124
|
+
newEdge = partialOrUpdater(oldEdge);
|
|
125
|
+
} else {
|
|
126
|
+
newEdge = { ...oldEdge, ...partialOrUpdater };
|
|
127
|
+
}
|
|
128
|
+
return upsertEdge(id, newEdge);
|
|
129
|
+
},
|
|
130
|
+
updateEdgeData(id, partialOrUpdater) {
|
|
131
|
+
return mutableFlow.updateEdge(id, (edge) => {
|
|
132
|
+
const currData = edge.data;
|
|
133
|
+
const newData = typeof partialOrUpdater === "function" ? partialOrUpdater(currData) : { ...currData, ...partialOrUpdater };
|
|
134
|
+
return { ...edge, data: newData };
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
removeEdge(id) {
|
|
138
|
+
edgesLiveMap.delete(id);
|
|
139
|
+
},
|
|
140
|
+
removeEdges(ids) {
|
|
141
|
+
for (const id of ids) {
|
|
142
|
+
edgesLiveMap.delete(id);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
await callback(mutableFlow);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
exports.mutateFlow = mutateFlow;
|
|
151
|
+
//# sourceMappingURL=node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.cjs","sources":["../src/node.ts"],"sourcesContent":["import type { JsonObject, LsonObject } from \"@liveblocks/core\";\nimport { LiveMap, LiveObject } from \"@liveblocks/core\";\nimport type { BuiltInEdge, BuiltInNode, Edge, Node } from \"@xyflow/react\";\n\nimport {\n buildEdgeConfigCache,\n buildNodeConfigCache,\n DEFAULT_STORAGE_KEY,\n toLiveblocksInternalEdge,\n toLiveblocksInternalNode,\n} from \"./helpers\";\nimport type {\n EdgeSyncConfig,\n InternalLiveblocksFlow,\n NodeSyncConfig,\n} from \"./types\";\n\n/**\n * A minimal interface for the Liveblocks Node client — just the\n * `mutateStorage` method we actually need. This avoids importing\n * `@liveblocks/node` as a dependency.\n */\ninterface ILiveblocksClient {\n mutateStorage(\n roomId: string,\n callback: (context: {\n root: LiveObject<LsonObject>;\n }) => void | Promise<void>\n ): Promise<void>;\n}\n\n/** Options for `mutateFlow()`. */\nexport interface MutateFlowOptions<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n> {\n client: ILiveblocksClient;\n roomId: string;\n storageKey?: string;\n nodes?: { sync?: NodeSyncConfig<N> };\n edges?: { sync?: EdgeSyncConfig<E> };\n}\n\nexport interface MutableFlow<N extends Node, E extends Edge> {\n readonly nodes: readonly N[];\n readonly edges: readonly E[];\n toJSON(): {\n nodes: readonly N[];\n edges: readonly E[];\n };\n\n getNode(id: string): N | undefined;\n getEdge(id: string): E | undefined;\n\n addNode(node: N): void;\n addNodes(nodes: N[]): void;\n updateNode(id: string, partial: Partial<N>): void;\n updateNode(id: string, updater: (node: N) => N): void;\n updateNodeData(id: string, partial: Partial<N[\"data\"]>): void;\n updateNodeData<D extends N[\"data\"]>(\n id: string,\n updater: (data: D) => D\n ): void;\n removeNode(id: string): void;\n removeNodes(ids: string[]): void;\n\n addEdge(edge: E): void;\n addEdges(edges: E[]): void;\n updateEdge(id: string, partial: Partial<E>): void;\n updateEdge(id: string, updater: (edge: E) => E): void;\n updateEdgeData(id: string, partial: Partial<NonNullable<E[\"data\"]>>): void;\n updateEdgeData<D extends E[\"data\"]>(\n id: string,\n updater: (data: D) => D\n ): void;\n removeEdge(id: string): void;\n removeEdges(ids: string[]): void;\n}\n\n/**\n * Opens a \"Flow document\" (a collection of nodes and edges) for reading and\n * mutating, then automatically flushes all changes when the callback\n * completes.\n *\n * @example\n * ```ts\n * await mutateFlow({ client, roomId: \"my-room\" }, (flow) => {\n * flow.addNode({ id: \"1\", position: { x: 0, y: 0 }, data: {} });\n * flow.updateNodeData(\"1\", { label: \"Hello\" });\n * });\n * ```\n */\nexport async function mutateFlow<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n>(\n options: MutateFlowOptions<N, E>,\n callback: (flow: MutableFlow<N, E>) => void | Promise<void>\n): Promise<void> {\n const { client, roomId } = options;\n const storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;\n\n const getNodeSyncConfig = buildNodeConfigCache(options.nodes?.sync);\n const getEdgeSyncConfig = buildEdgeConfigCache(options.edges?.sync);\n\n const nodeListCache = new WeakMap<Record<string, N>, N[]>();\n const edgeListCache = new WeakMap<Record<string, E>, E[]>();\n\n await client.mutateStorage(roomId, async ({ root }) => {\n let flow = root.get(storageKey) as InternalLiveblocksFlow | undefined;\n if (!flow) {\n const newFlow = new LiveObject({\n nodes: new LiveMap(),\n edges: new LiveMap(),\n }) satisfies InternalLiveblocksFlow;\n root.set(storageKey, newFlow);\n flow = newFlow;\n }\n\n const nodesLiveMap = flow.get(\"nodes\");\n const edgesLiveMap = flow.get(\"edges\");\n\n function getNodes(): readonly N[] {\n const nodeMap = nodesLiveMap.toJSON() as unknown as Record<string, N>;\n if (!nodeListCache.has(nodeMap)) {\n // TODO (LB-3665): To support sub-nodes, this function will need to emit nodes\n // in topological order (parents before children), deferring any node with a\n // parentId until its parent has been emitted.\n nodeListCache.set(nodeMap, Object.values(nodeMap));\n }\n return nodeListCache.get(nodeMap)!;\n }\n\n function getEdges(): readonly E[] {\n const edgeMap = edgesLiveMap.toJSON() as unknown as Record<string, E>;\n if (!edgeListCache.has(edgeMap)) {\n edgeListCache.set(edgeMap, Object.values(edgeMap));\n }\n return edgeListCache.get(edgeMap)!;\n }\n\n function getNode(id: string) {\n return nodesLiveMap.get(id)?.toJSON() as N | undefined;\n }\n function getEdge(id: string) {\n return edgesLiveMap.get(id)?.toJSON() as E | undefined;\n }\n\n function upsertNode(id: string, newNode: N) {\n const existing = nodesLiveMap.get(id);\n const syncConfig = getNodeSyncConfig(newNode.type);\n if (!existing) {\n nodesLiveMap.set(id, toLiveblocksInternalNode(newNode, syncConfig));\n } else {\n existing.reconcile(newNode as unknown as JsonObject, syncConfig);\n }\n }\n\n function upsertEdge(id: string, newEdge: E) {\n const existing = edgesLiveMap.get(id);\n const syncConfig = getEdgeSyncConfig(newEdge.type);\n if (!existing) {\n edgesLiveMap.set(id, toLiveblocksInternalEdge(newEdge, syncConfig));\n } else {\n existing.reconcile(newEdge as unknown as JsonObject, syncConfig);\n }\n }\n\n const mutableFlow: MutableFlow<N, E> = {\n get nodes() {\n return getNodes();\n },\n get edges() {\n return getEdges();\n },\n toJSON() {\n return { nodes: getNodes(), edges: getEdges() };\n },\n getNode,\n getEdge,\n\n addNode(node: N) {\n upsertNode(node.id, node);\n },\n addNodes(nodes: N[]) {\n for (const node of nodes) {\n mutableFlow.addNode(node);\n }\n },\n updateNode(id: string, partialOrUpdater: Partial<N> | ((node: N) => N)) {\n const oldNode = getNode(id);\n if (!oldNode) return;\n\n let newNode: N;\n if (typeof partialOrUpdater === \"function\") {\n newNode = partialOrUpdater(oldNode);\n } else {\n newNode = { ...oldNode, ...partialOrUpdater };\n }\n return upsertNode(id, newNode);\n },\n updateNodeData(\n id: string,\n partialOrUpdater:\n | Partial<N[\"data\"]>\n | (<D extends N[\"data\"]>(data: D) => D)\n ) {\n return mutableFlow.updateNode(id, (node) => {\n const currData = node.data ?? ({} as N[\"data\"]);\n const newData =\n typeof partialOrUpdater === \"function\"\n ? partialOrUpdater(currData)\n : { ...currData, ...partialOrUpdater };\n return { ...node, data: newData };\n });\n },\n removeNode(id: string) {\n nodesLiveMap.delete(id);\n },\n removeNodes(ids: string[]) {\n for (const id of ids) {\n nodesLiveMap.delete(id);\n }\n },\n\n addEdge(edge: E) {\n upsertEdge(edge.id, edge);\n },\n addEdges(edges: E[]) {\n for (const edge of edges) {\n mutableFlow.addEdge(edge);\n }\n },\n updateEdge(id: string, partialOrUpdater: Partial<E> | ((edge: E) => E)) {\n const oldEdge = getEdge(id);\n if (!oldEdge) return;\n\n let newEdge: E;\n if (typeof partialOrUpdater === \"function\") {\n newEdge = partialOrUpdater(oldEdge);\n } else {\n newEdge = { ...oldEdge, ...partialOrUpdater };\n }\n return upsertEdge(id, newEdge);\n },\n updateEdgeData(\n id: string,\n partialOrUpdater:\n | Partial<NonNullable<E[\"data\"]>>\n | (<D extends E[\"data\"]>(data: D) => D)\n ) {\n return mutableFlow.updateEdge(id, (edge) => {\n const currData = edge.data;\n const newData =\n typeof partialOrUpdater === \"function\"\n ? partialOrUpdater(currData)\n : { ...currData, ...partialOrUpdater };\n return { ...edge, data: newData };\n });\n },\n removeEdge(id: string) {\n edgesLiveMap.delete(id);\n },\n removeEdges(ids: string[]) {\n for (const id of ids) {\n edgesLiveMap.delete(id);\n }\n },\n };\n\n await callback(mutableFlow);\n });\n}\n"],"names":["DEFAULT_STORAGE_KEY","buildNodeConfigCache","buildEdgeConfigCache","LiveObject","LiveMap","toLiveblocksInternalNode","toLiveblocksInternalEdge"],"mappings":"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"}
|
package/dist/node.d.cts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { SyncConfig, LiveObject, LsonObject } from '@liveblocks/core';
|
|
2
|
+
import { Node, Edge, BuiltInNode, BuiltInEdge } from '@xyflow/react';
|
|
3
|
+
|
|
4
|
+
type InferNodeTypeLiterals<N> = N extends Node<any, infer T extends string> ? string extends T ? never : T : never;
|
|
5
|
+
type NodeTypeLiterals<N> = (string & {}) | "*" | InferNodeTypeLiterals<N>;
|
|
6
|
+
type InferEdgeTypeLiterals<E> = E extends Edge<any, infer T extends string> ? string extends T ? never : T : never;
|
|
7
|
+
type EdgeTypeLiterals<E> = (string & {}) | "*" | InferEdgeTypeLiterals<E>;
|
|
8
|
+
type NodeSyncConfig<N extends Node> = {
|
|
9
|
+
[key in NodeTypeLiterals<N>]?: SyncConfig;
|
|
10
|
+
};
|
|
11
|
+
type EdgeSyncConfig<E extends Edge> = {
|
|
12
|
+
[key in EdgeTypeLiterals<E>]?: SyncConfig;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A minimal interface for the Liveblocks Node client — just the
|
|
17
|
+
* `mutateStorage` method we actually need. This avoids importing
|
|
18
|
+
* `@liveblocks/node` as a dependency.
|
|
19
|
+
*/
|
|
20
|
+
interface ILiveblocksClient {
|
|
21
|
+
mutateStorage(roomId: string, callback: (context: {
|
|
22
|
+
root: LiveObject<LsonObject>;
|
|
23
|
+
}) => void | Promise<void>): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/** Options for `mutateFlow()`. */
|
|
26
|
+
interface MutateFlowOptions<N extends Node = BuiltInNode, E extends Edge = BuiltInEdge> {
|
|
27
|
+
client: ILiveblocksClient;
|
|
28
|
+
roomId: string;
|
|
29
|
+
storageKey?: string;
|
|
30
|
+
nodes?: {
|
|
31
|
+
sync?: NodeSyncConfig<N>;
|
|
32
|
+
};
|
|
33
|
+
edges?: {
|
|
34
|
+
sync?: EdgeSyncConfig<E>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface MutableFlow<N extends Node, E extends Edge> {
|
|
38
|
+
readonly nodes: readonly N[];
|
|
39
|
+
readonly edges: readonly E[];
|
|
40
|
+
toJSON(): {
|
|
41
|
+
nodes: readonly N[];
|
|
42
|
+
edges: readonly E[];
|
|
43
|
+
};
|
|
44
|
+
getNode(id: string): N | undefined;
|
|
45
|
+
getEdge(id: string): E | undefined;
|
|
46
|
+
addNode(node: N): void;
|
|
47
|
+
addNodes(nodes: N[]): void;
|
|
48
|
+
updateNode(id: string, partial: Partial<N>): void;
|
|
49
|
+
updateNode(id: string, updater: (node: N) => N): void;
|
|
50
|
+
updateNodeData(id: string, partial: Partial<N["data"]>): void;
|
|
51
|
+
updateNodeData<D extends N["data"]>(id: string, updater: (data: D) => D): void;
|
|
52
|
+
removeNode(id: string): void;
|
|
53
|
+
removeNodes(ids: string[]): void;
|
|
54
|
+
addEdge(edge: E): void;
|
|
55
|
+
addEdges(edges: E[]): void;
|
|
56
|
+
updateEdge(id: string, partial: Partial<E>): void;
|
|
57
|
+
updateEdge(id: string, updater: (edge: E) => E): void;
|
|
58
|
+
updateEdgeData(id: string, partial: Partial<NonNullable<E["data"]>>): void;
|
|
59
|
+
updateEdgeData<D extends E["data"]>(id: string, updater: (data: D) => D): void;
|
|
60
|
+
removeEdge(id: string): void;
|
|
61
|
+
removeEdges(ids: string[]): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Opens a "Flow document" (a collection of nodes and edges) for reading and
|
|
65
|
+
* mutating, then automatically flushes all changes when the callback
|
|
66
|
+
* completes.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* await mutateFlow({ client, roomId: "my-room" }, (flow) => {
|
|
71
|
+
* flow.addNode({ id: "1", position: { x: 0, y: 0 }, data: {} });
|
|
72
|
+
* flow.updateNodeData("1", { label: "Hello" });
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
declare function mutateFlow<N extends Node = BuiltInNode, E extends Edge = BuiltInEdge>(options: MutateFlowOptions<N, E>, callback: (flow: MutableFlow<N, E>) => void | Promise<void>): Promise<void>;
|
|
77
|
+
|
|
78
|
+
export { MutableFlow, MutateFlowOptions, mutateFlow };
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { SyncConfig, LiveObject, LsonObject } from '@liveblocks/core';
|
|
2
|
+
import { Node, Edge, BuiltInNode, BuiltInEdge } from '@xyflow/react';
|
|
3
|
+
|
|
4
|
+
type InferNodeTypeLiterals<N> = N extends Node<any, infer T extends string> ? string extends T ? never : T : never;
|
|
5
|
+
type NodeTypeLiterals<N> = (string & {}) | "*" | InferNodeTypeLiterals<N>;
|
|
6
|
+
type InferEdgeTypeLiterals<E> = E extends Edge<any, infer T extends string> ? string extends T ? never : T : never;
|
|
7
|
+
type EdgeTypeLiterals<E> = (string & {}) | "*" | InferEdgeTypeLiterals<E>;
|
|
8
|
+
type NodeSyncConfig<N extends Node> = {
|
|
9
|
+
[key in NodeTypeLiterals<N>]?: SyncConfig;
|
|
10
|
+
};
|
|
11
|
+
type EdgeSyncConfig<E extends Edge> = {
|
|
12
|
+
[key in EdgeTypeLiterals<E>]?: SyncConfig;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A minimal interface for the Liveblocks Node client — just the
|
|
17
|
+
* `mutateStorage` method we actually need. This avoids importing
|
|
18
|
+
* `@liveblocks/node` as a dependency.
|
|
19
|
+
*/
|
|
20
|
+
interface ILiveblocksClient {
|
|
21
|
+
mutateStorage(roomId: string, callback: (context: {
|
|
22
|
+
root: LiveObject<LsonObject>;
|
|
23
|
+
}) => void | Promise<void>): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
/** Options for `mutateFlow()`. */
|
|
26
|
+
interface MutateFlowOptions<N extends Node = BuiltInNode, E extends Edge = BuiltInEdge> {
|
|
27
|
+
client: ILiveblocksClient;
|
|
28
|
+
roomId: string;
|
|
29
|
+
storageKey?: string;
|
|
30
|
+
nodes?: {
|
|
31
|
+
sync?: NodeSyncConfig<N>;
|
|
32
|
+
};
|
|
33
|
+
edges?: {
|
|
34
|
+
sync?: EdgeSyncConfig<E>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
interface MutableFlow<N extends Node, E extends Edge> {
|
|
38
|
+
readonly nodes: readonly N[];
|
|
39
|
+
readonly edges: readonly E[];
|
|
40
|
+
toJSON(): {
|
|
41
|
+
nodes: readonly N[];
|
|
42
|
+
edges: readonly E[];
|
|
43
|
+
};
|
|
44
|
+
getNode(id: string): N | undefined;
|
|
45
|
+
getEdge(id: string): E | undefined;
|
|
46
|
+
addNode(node: N): void;
|
|
47
|
+
addNodes(nodes: N[]): void;
|
|
48
|
+
updateNode(id: string, partial: Partial<N>): void;
|
|
49
|
+
updateNode(id: string, updater: (node: N) => N): void;
|
|
50
|
+
updateNodeData(id: string, partial: Partial<N["data"]>): void;
|
|
51
|
+
updateNodeData<D extends N["data"]>(id: string, updater: (data: D) => D): void;
|
|
52
|
+
removeNode(id: string): void;
|
|
53
|
+
removeNodes(ids: string[]): void;
|
|
54
|
+
addEdge(edge: E): void;
|
|
55
|
+
addEdges(edges: E[]): void;
|
|
56
|
+
updateEdge(id: string, partial: Partial<E>): void;
|
|
57
|
+
updateEdge(id: string, updater: (edge: E) => E): void;
|
|
58
|
+
updateEdgeData(id: string, partial: Partial<NonNullable<E["data"]>>): void;
|
|
59
|
+
updateEdgeData<D extends E["data"]>(id: string, updater: (data: D) => D): void;
|
|
60
|
+
removeEdge(id: string): void;
|
|
61
|
+
removeEdges(ids: string[]): void;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Opens a "Flow document" (a collection of nodes and edges) for reading and
|
|
65
|
+
* mutating, then automatically flushes all changes when the callback
|
|
66
|
+
* completes.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* await mutateFlow({ client, roomId: "my-room" }, (flow) => {
|
|
71
|
+
* flow.addNode({ id: "1", position: { x: 0, y: 0 }, data: {} });
|
|
72
|
+
* flow.updateNodeData("1", { label: "Hello" });
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
declare function mutateFlow<N extends Node = BuiltInNode, E extends Edge = BuiltInEdge>(options: MutateFlowOptions<N, E>, callback: (flow: MutableFlow<N, E>) => void | Promise<void>): Promise<void>;
|
|
77
|
+
|
|
78
|
+
export { MutableFlow, MutateFlowOptions, mutateFlow };
|
package/dist/node.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { LiveObject, LiveMap } from '@liveblocks/core';
|
|
2
|
+
import { DEFAULT_STORAGE_KEY, buildNodeConfigCache, buildEdgeConfigCache, toLiveblocksInternalNode, toLiveblocksInternalEdge } from './helpers.js';
|
|
3
|
+
|
|
4
|
+
async function mutateFlow(options, callback) {
|
|
5
|
+
const { client, roomId } = options;
|
|
6
|
+
const storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
7
|
+
const getNodeSyncConfig = buildNodeConfigCache(options.nodes?.sync);
|
|
8
|
+
const getEdgeSyncConfig = buildEdgeConfigCache(options.edges?.sync);
|
|
9
|
+
const nodeListCache = /* @__PURE__ */ new WeakMap();
|
|
10
|
+
const edgeListCache = /* @__PURE__ */ new WeakMap();
|
|
11
|
+
await client.mutateStorage(roomId, async ({ root }) => {
|
|
12
|
+
let flow = root.get(storageKey);
|
|
13
|
+
if (!flow) {
|
|
14
|
+
const newFlow = new LiveObject({
|
|
15
|
+
nodes: new LiveMap(),
|
|
16
|
+
edges: new LiveMap()
|
|
17
|
+
});
|
|
18
|
+
root.set(storageKey, newFlow);
|
|
19
|
+
flow = newFlow;
|
|
20
|
+
}
|
|
21
|
+
const nodesLiveMap = flow.get("nodes");
|
|
22
|
+
const edgesLiveMap = flow.get("edges");
|
|
23
|
+
function getNodes() {
|
|
24
|
+
const nodeMap = nodesLiveMap.toJSON();
|
|
25
|
+
if (!nodeListCache.has(nodeMap)) {
|
|
26
|
+
nodeListCache.set(nodeMap, Object.values(nodeMap));
|
|
27
|
+
}
|
|
28
|
+
return nodeListCache.get(nodeMap);
|
|
29
|
+
}
|
|
30
|
+
function getEdges() {
|
|
31
|
+
const edgeMap = edgesLiveMap.toJSON();
|
|
32
|
+
if (!edgeListCache.has(edgeMap)) {
|
|
33
|
+
edgeListCache.set(edgeMap, Object.values(edgeMap));
|
|
34
|
+
}
|
|
35
|
+
return edgeListCache.get(edgeMap);
|
|
36
|
+
}
|
|
37
|
+
function getNode(id) {
|
|
38
|
+
return nodesLiveMap.get(id)?.toJSON();
|
|
39
|
+
}
|
|
40
|
+
function getEdge(id) {
|
|
41
|
+
return edgesLiveMap.get(id)?.toJSON();
|
|
42
|
+
}
|
|
43
|
+
function upsertNode(id, newNode) {
|
|
44
|
+
const existing = nodesLiveMap.get(id);
|
|
45
|
+
const syncConfig = getNodeSyncConfig(newNode.type);
|
|
46
|
+
if (!existing) {
|
|
47
|
+
nodesLiveMap.set(id, toLiveblocksInternalNode(newNode, syncConfig));
|
|
48
|
+
} else {
|
|
49
|
+
existing.reconcile(newNode, syncConfig);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function upsertEdge(id, newEdge) {
|
|
53
|
+
const existing = edgesLiveMap.get(id);
|
|
54
|
+
const syncConfig = getEdgeSyncConfig(newEdge.type);
|
|
55
|
+
if (!existing) {
|
|
56
|
+
edgesLiveMap.set(id, toLiveblocksInternalEdge(newEdge, syncConfig));
|
|
57
|
+
} else {
|
|
58
|
+
existing.reconcile(newEdge, syncConfig);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const mutableFlow = {
|
|
62
|
+
get nodes() {
|
|
63
|
+
return getNodes();
|
|
64
|
+
},
|
|
65
|
+
get edges() {
|
|
66
|
+
return getEdges();
|
|
67
|
+
},
|
|
68
|
+
toJSON() {
|
|
69
|
+
return { nodes: getNodes(), edges: getEdges() };
|
|
70
|
+
},
|
|
71
|
+
getNode,
|
|
72
|
+
getEdge,
|
|
73
|
+
addNode(node) {
|
|
74
|
+
upsertNode(node.id, node);
|
|
75
|
+
},
|
|
76
|
+
addNodes(nodes) {
|
|
77
|
+
for (const node of nodes) {
|
|
78
|
+
mutableFlow.addNode(node);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
updateNode(id, partialOrUpdater) {
|
|
82
|
+
const oldNode = getNode(id);
|
|
83
|
+
if (!oldNode)
|
|
84
|
+
return;
|
|
85
|
+
let newNode;
|
|
86
|
+
if (typeof partialOrUpdater === "function") {
|
|
87
|
+
newNode = partialOrUpdater(oldNode);
|
|
88
|
+
} else {
|
|
89
|
+
newNode = { ...oldNode, ...partialOrUpdater };
|
|
90
|
+
}
|
|
91
|
+
return upsertNode(id, newNode);
|
|
92
|
+
},
|
|
93
|
+
updateNodeData(id, partialOrUpdater) {
|
|
94
|
+
return mutableFlow.updateNode(id, (node) => {
|
|
95
|
+
const currData = node.data ?? {};
|
|
96
|
+
const newData = typeof partialOrUpdater === "function" ? partialOrUpdater(currData) : { ...currData, ...partialOrUpdater };
|
|
97
|
+
return { ...node, data: newData };
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
removeNode(id) {
|
|
101
|
+
nodesLiveMap.delete(id);
|
|
102
|
+
},
|
|
103
|
+
removeNodes(ids) {
|
|
104
|
+
for (const id of ids) {
|
|
105
|
+
nodesLiveMap.delete(id);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
addEdge(edge) {
|
|
109
|
+
upsertEdge(edge.id, edge);
|
|
110
|
+
},
|
|
111
|
+
addEdges(edges) {
|
|
112
|
+
for (const edge of edges) {
|
|
113
|
+
mutableFlow.addEdge(edge);
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
updateEdge(id, partialOrUpdater) {
|
|
117
|
+
const oldEdge = getEdge(id);
|
|
118
|
+
if (!oldEdge)
|
|
119
|
+
return;
|
|
120
|
+
let newEdge;
|
|
121
|
+
if (typeof partialOrUpdater === "function") {
|
|
122
|
+
newEdge = partialOrUpdater(oldEdge);
|
|
123
|
+
} else {
|
|
124
|
+
newEdge = { ...oldEdge, ...partialOrUpdater };
|
|
125
|
+
}
|
|
126
|
+
return upsertEdge(id, newEdge);
|
|
127
|
+
},
|
|
128
|
+
updateEdgeData(id, partialOrUpdater) {
|
|
129
|
+
return mutableFlow.updateEdge(id, (edge) => {
|
|
130
|
+
const currData = edge.data;
|
|
131
|
+
const newData = typeof partialOrUpdater === "function" ? partialOrUpdater(currData) : { ...currData, ...partialOrUpdater };
|
|
132
|
+
return { ...edge, data: newData };
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
removeEdge(id) {
|
|
136
|
+
edgesLiveMap.delete(id);
|
|
137
|
+
},
|
|
138
|
+
removeEdges(ids) {
|
|
139
|
+
for (const id of ids) {
|
|
140
|
+
edgesLiveMap.delete(id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
await callback(mutableFlow);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export { mutateFlow };
|
|
149
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sources":["../src/node.ts"],"sourcesContent":["import type { JsonObject, LsonObject } from \"@liveblocks/core\";\nimport { LiveMap, LiveObject } from \"@liveblocks/core\";\nimport type { BuiltInEdge, BuiltInNode, Edge, Node } from \"@xyflow/react\";\n\nimport {\n buildEdgeConfigCache,\n buildNodeConfigCache,\n DEFAULT_STORAGE_KEY,\n toLiveblocksInternalEdge,\n toLiveblocksInternalNode,\n} from \"./helpers\";\nimport type {\n EdgeSyncConfig,\n InternalLiveblocksFlow,\n NodeSyncConfig,\n} from \"./types\";\n\n/**\n * A minimal interface for the Liveblocks Node client — just the\n * `mutateStorage` method we actually need. This avoids importing\n * `@liveblocks/node` as a dependency.\n */\ninterface ILiveblocksClient {\n mutateStorage(\n roomId: string,\n callback: (context: {\n root: LiveObject<LsonObject>;\n }) => void | Promise<void>\n ): Promise<void>;\n}\n\n/** Options for `mutateFlow()`. */\nexport interface MutateFlowOptions<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n> {\n client: ILiveblocksClient;\n roomId: string;\n storageKey?: string;\n nodes?: { sync?: NodeSyncConfig<N> };\n edges?: { sync?: EdgeSyncConfig<E> };\n}\n\nexport interface MutableFlow<N extends Node, E extends Edge> {\n readonly nodes: readonly N[];\n readonly edges: readonly E[];\n toJSON(): {\n nodes: readonly N[];\n edges: readonly E[];\n };\n\n getNode(id: string): N | undefined;\n getEdge(id: string): E | undefined;\n\n addNode(node: N): void;\n addNodes(nodes: N[]): void;\n updateNode(id: string, partial: Partial<N>): void;\n updateNode(id: string, updater: (node: N) => N): void;\n updateNodeData(id: string, partial: Partial<N[\"data\"]>): void;\n updateNodeData<D extends N[\"data\"]>(\n id: string,\n updater: (data: D) => D\n ): void;\n removeNode(id: string): void;\n removeNodes(ids: string[]): void;\n\n addEdge(edge: E): void;\n addEdges(edges: E[]): void;\n updateEdge(id: string, partial: Partial<E>): void;\n updateEdge(id: string, updater: (edge: E) => E): void;\n updateEdgeData(id: string, partial: Partial<NonNullable<E[\"data\"]>>): void;\n updateEdgeData<D extends E[\"data\"]>(\n id: string,\n updater: (data: D) => D\n ): void;\n removeEdge(id: string): void;\n removeEdges(ids: string[]): void;\n}\n\n/**\n * Opens a \"Flow document\" (a collection of nodes and edges) for reading and\n * mutating, then automatically flushes all changes when the callback\n * completes.\n *\n * @example\n * ```ts\n * await mutateFlow({ client, roomId: \"my-room\" }, (flow) => {\n * flow.addNode({ id: \"1\", position: { x: 0, y: 0 }, data: {} });\n * flow.updateNodeData(\"1\", { label: \"Hello\" });\n * });\n * ```\n */\nexport async function mutateFlow<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n>(\n options: MutateFlowOptions<N, E>,\n callback: (flow: MutableFlow<N, E>) => void | Promise<void>\n): Promise<void> {\n const { client, roomId } = options;\n const storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;\n\n const getNodeSyncConfig = buildNodeConfigCache(options.nodes?.sync);\n const getEdgeSyncConfig = buildEdgeConfigCache(options.edges?.sync);\n\n const nodeListCache = new WeakMap<Record<string, N>, N[]>();\n const edgeListCache = new WeakMap<Record<string, E>, E[]>();\n\n await client.mutateStorage(roomId, async ({ root }) => {\n let flow = root.get(storageKey) as InternalLiveblocksFlow | undefined;\n if (!flow) {\n const newFlow = new LiveObject({\n nodes: new LiveMap(),\n edges: new LiveMap(),\n }) satisfies InternalLiveblocksFlow;\n root.set(storageKey, newFlow);\n flow = newFlow;\n }\n\n const nodesLiveMap = flow.get(\"nodes\");\n const edgesLiveMap = flow.get(\"edges\");\n\n function getNodes(): readonly N[] {\n const nodeMap = nodesLiveMap.toJSON() as unknown as Record<string, N>;\n if (!nodeListCache.has(nodeMap)) {\n // TODO (LB-3665): To support sub-nodes, this function will need to emit nodes\n // in topological order (parents before children), deferring any node with a\n // parentId until its parent has been emitted.\n nodeListCache.set(nodeMap, Object.values(nodeMap));\n }\n return nodeListCache.get(nodeMap)!;\n }\n\n function getEdges(): readonly E[] {\n const edgeMap = edgesLiveMap.toJSON() as unknown as Record<string, E>;\n if (!edgeListCache.has(edgeMap)) {\n edgeListCache.set(edgeMap, Object.values(edgeMap));\n }\n return edgeListCache.get(edgeMap)!;\n }\n\n function getNode(id: string) {\n return nodesLiveMap.get(id)?.toJSON() as N | undefined;\n }\n function getEdge(id: string) {\n return edgesLiveMap.get(id)?.toJSON() as E | undefined;\n }\n\n function upsertNode(id: string, newNode: N) {\n const existing = nodesLiveMap.get(id);\n const syncConfig = getNodeSyncConfig(newNode.type);\n if (!existing) {\n nodesLiveMap.set(id, toLiveblocksInternalNode(newNode, syncConfig));\n } else {\n existing.reconcile(newNode as unknown as JsonObject, syncConfig);\n }\n }\n\n function upsertEdge(id: string, newEdge: E) {\n const existing = edgesLiveMap.get(id);\n const syncConfig = getEdgeSyncConfig(newEdge.type);\n if (!existing) {\n edgesLiveMap.set(id, toLiveblocksInternalEdge(newEdge, syncConfig));\n } else {\n existing.reconcile(newEdge as unknown as JsonObject, syncConfig);\n }\n }\n\n const mutableFlow: MutableFlow<N, E> = {\n get nodes() {\n return getNodes();\n },\n get edges() {\n return getEdges();\n },\n toJSON() {\n return { nodes: getNodes(), edges: getEdges() };\n },\n getNode,\n getEdge,\n\n addNode(node: N) {\n upsertNode(node.id, node);\n },\n addNodes(nodes: N[]) {\n for (const node of nodes) {\n mutableFlow.addNode(node);\n }\n },\n updateNode(id: string, partialOrUpdater: Partial<N> | ((node: N) => N)) {\n const oldNode = getNode(id);\n if (!oldNode) return;\n\n let newNode: N;\n if (typeof partialOrUpdater === \"function\") {\n newNode = partialOrUpdater(oldNode);\n } else {\n newNode = { ...oldNode, ...partialOrUpdater };\n }\n return upsertNode(id, newNode);\n },\n updateNodeData(\n id: string,\n partialOrUpdater:\n | Partial<N[\"data\"]>\n | (<D extends N[\"data\"]>(data: D) => D)\n ) {\n return mutableFlow.updateNode(id, (node) => {\n const currData = node.data ?? ({} as N[\"data\"]);\n const newData =\n typeof partialOrUpdater === \"function\"\n ? partialOrUpdater(currData)\n : { ...currData, ...partialOrUpdater };\n return { ...node, data: newData };\n });\n },\n removeNode(id: string) {\n nodesLiveMap.delete(id);\n },\n removeNodes(ids: string[]) {\n for (const id of ids) {\n nodesLiveMap.delete(id);\n }\n },\n\n addEdge(edge: E) {\n upsertEdge(edge.id, edge);\n },\n addEdges(edges: E[]) {\n for (const edge of edges) {\n mutableFlow.addEdge(edge);\n }\n },\n updateEdge(id: string, partialOrUpdater: Partial<E> | ((edge: E) => E)) {\n const oldEdge = getEdge(id);\n if (!oldEdge) return;\n\n let newEdge: E;\n if (typeof partialOrUpdater === \"function\") {\n newEdge = partialOrUpdater(oldEdge);\n } else {\n newEdge = { ...oldEdge, ...partialOrUpdater };\n }\n return upsertEdge(id, newEdge);\n },\n updateEdgeData(\n id: string,\n partialOrUpdater:\n | Partial<NonNullable<E[\"data\"]>>\n | (<D extends E[\"data\"]>(data: D) => D)\n ) {\n return mutableFlow.updateEdge(id, (edge) => {\n const currData = edge.data;\n const newData =\n typeof partialOrUpdater === \"function\"\n ? partialOrUpdater(currData)\n : { ...currData, ...partialOrUpdater };\n return { ...edge, data: newData };\n });\n },\n removeEdge(id: string) {\n edgesLiveMap.delete(id);\n },\n removeEdges(ids: string[]) {\n for (const id of ids) {\n edgesLiveMap.delete(id);\n }\n },\n };\n\n await callback(mutableFlow);\n });\n}\n"],"names":[],"mappings":"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"}
|
package/dist/version.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const PKG_NAME = "@liveblocks/react-flow";
|
|
4
|
-
const PKG_VERSION = typeof "3.
|
|
4
|
+
const PKG_VERSION = typeof "3.18.0-rc1" === "string" && "3.18.0-rc1";
|
|
5
5
|
const PKG_FORMAT = typeof TSUP_FORMAT === "string" && TSUP_FORMAT;
|
|
6
6
|
|
|
7
7
|
exports.PKG_FORMAT = PKG_FORMAT;
|