@liveblocks/react-flow 3.16.0-flow1 → 3.16.0-flow3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/dist/constants.cjs +34 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.js +30 -0
- package/dist/constants.js.map +1 -0
- package/dist/cursors.cjs +27 -18
- package/dist/cursors.cjs.map +1 -1
- package/dist/cursors.js +29 -20
- package/dist/cursors.js.map +1 -1
- package/dist/flow.cjs +166 -237
- package/dist/flow.cjs.map +1 -1
- package/dist/flow.js +171 -240
- package/dist/flow.js.map +1 -1
- package/dist/helpers.cjs +35 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.js +30 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +197 -93
- package/dist/index.d.ts +197 -93
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -18
- package/dist/suspense.cjs +0 -13
- package/dist/suspense.cjs.map +0 -1
- package/dist/suspense.d.cts +0 -149
- package/dist/suspense.d.ts +0 -149
- package/dist/suspense.js +0 -7
- package/dist/suspense.js.map +0 -1
- package/suspense/README.md +0 -5
- package/suspense/package.json +0 -4
package/dist/flow.js
CHANGED
|
@@ -1,140 +1,74 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useStorage, useMutation } from '@liveblocks/react';
|
|
3
|
-
import { useInitial,
|
|
1
|
+
import { LiveObject, LiveMap, kInternal } from '@liveblocks/core';
|
|
2
|
+
import { useHistory, useStorage, useMutation } from '@liveblocks/react';
|
|
3
|
+
import { useInitial, useSuspendUntilStorageReady } from '@liveblocks/react/_private';
|
|
4
4
|
import { addEdge } from '@xyflow/react';
|
|
5
|
-
import {
|
|
5
|
+
import { useMemo, useEffect } from 'react';
|
|
6
|
+
import { NODE_BASE_CONFIG, EDGE_BASE_CONFIG, DEFAULT_STORAGE_KEY } from './constants.js';
|
|
7
|
+
import { toLiveblocksInternalNode, toLiveblocksInternalEdge } from './helpers.js';
|
|
6
8
|
|
|
7
|
-
const DEFAULT_STORAGE_KEY = "flow";
|
|
8
|
-
const NODE_LOCAL_KEYS = [
|
|
9
|
-
"selected",
|
|
10
|
-
"dragging",
|
|
11
|
-
"measured",
|
|
12
|
-
"resizing"
|
|
13
|
-
];
|
|
14
|
-
const EDGE_LOCAL_KEYS = ["selected"];
|
|
15
9
|
const EMPTY_ARRAY = [];
|
|
16
|
-
function
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
10
|
+
function mergeAndBuildDataConfigCache(base, data) {
|
|
11
|
+
if (!data)
|
|
12
|
+
return () => base;
|
|
13
|
+
const dataFallback = data["*"];
|
|
14
|
+
const fallback = dataFallback ? { ...base, data: dataFallback } : base;
|
|
15
|
+
const cache = /* @__PURE__ */ new Map();
|
|
16
|
+
for (const type in data) {
|
|
17
|
+
if (type === "*")
|
|
18
|
+
continue;
|
|
19
|
+
const specific = data[type];
|
|
20
|
+
if (!specific)
|
|
21
|
+
continue;
|
|
22
|
+
const dataConfig = { ...dataFallback, ...specific };
|
|
23
|
+
cache.set(type, { ...base, data: dataConfig });
|
|
23
24
|
}
|
|
24
|
-
return
|
|
25
|
+
return (type) => cache.get(type) || fallback;
|
|
25
26
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
for (const key of keys) {
|
|
29
|
-
delete result[key];
|
|
30
|
-
}
|
|
31
|
-
return result;
|
|
27
|
+
function buildNodeConfigCache(nodeDataConfig) {
|
|
28
|
+
return mergeAndBuildDataConfigCache(NODE_BASE_CONFIG, nodeDataConfig);
|
|
32
29
|
}
|
|
33
|
-
function
|
|
34
|
-
|
|
35
|
-
if (previous && shallow(previous, next)) {
|
|
36
|
-
return previous;
|
|
37
|
-
}
|
|
38
|
-
cache.set(next.id, next);
|
|
39
|
-
return next;
|
|
40
|
-
}
|
|
41
|
-
function merge(cache, remote, local) {
|
|
42
|
-
for (const id of cache.keys()) {
|
|
43
|
-
if (!remote.has(id)) {
|
|
44
|
-
cache.delete(id);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
for (const id of local.keys()) {
|
|
48
|
-
if (!remote.has(id)) {
|
|
49
|
-
local.delete(id);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return Array.from(remote.values(), (item) => {
|
|
53
|
-
const localItem = local.get(item.id);
|
|
54
|
-
return reconcile(
|
|
55
|
-
cache,
|
|
56
|
-
localItem ? Object.assign({}, item, localItem) : item
|
|
57
|
-
);
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
function updateLocalState(map, key, changes) {
|
|
61
|
-
const next = {};
|
|
62
|
-
for (const change in changes) {
|
|
63
|
-
const value = changes[change];
|
|
64
|
-
if (value !== void 0 && value !== false) {
|
|
65
|
-
next[change] = value;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (Object.keys(next).length > 0) {
|
|
69
|
-
map.set(key, next);
|
|
70
|
-
return true;
|
|
71
|
-
} else {
|
|
72
|
-
const hasItem = map.has(key);
|
|
73
|
-
map.delete(key);
|
|
74
|
-
return hasItem;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
function nodeToStorage(node) {
|
|
78
|
-
const { data, ...rest } = omit(node, NODE_LOCAL_KEYS);
|
|
79
|
-
return new LiveObject({
|
|
80
|
-
...rest,
|
|
81
|
-
data: new LiveObject(data)
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
function edgeToStorage(edge) {
|
|
85
|
-
const { data, ...rest } = omit(edge, EDGE_LOCAL_KEYS);
|
|
86
|
-
return new LiveObject({
|
|
87
|
-
...rest,
|
|
88
|
-
// `data` is optional on edges.
|
|
89
|
-
data: data === void 0 ? void 0 : new LiveObject(data)
|
|
90
|
-
});
|
|
30
|
+
function buildEdgeConfigCache(edgeDataConfig) {
|
|
31
|
+
return mergeAndBuildDataConfigCache(EDGE_BASE_CONFIG, edgeDataConfig);
|
|
91
32
|
}
|
|
92
|
-
function applyNodeChanges(
|
|
93
|
-
const { changes, nodes, nextLocal, nodeCache } = args;
|
|
94
|
-
let hasLocalChanged = false;
|
|
33
|
+
function applyNodeChanges(changes, nodes, history, getNodeSyncConfig) {
|
|
95
34
|
for (const change of changes) {
|
|
96
35
|
switch (change.type) {
|
|
97
36
|
case "add":
|
|
98
|
-
case "replace":
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
change.item
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
37
|
+
case "replace": {
|
|
38
|
+
const config = getNodeSyncConfig(change.item.type);
|
|
39
|
+
const existing = nodes.get(change.item.id);
|
|
40
|
+
if (existing) {
|
|
41
|
+
existing.reconcile(change.item, config);
|
|
42
|
+
} else {
|
|
43
|
+
nodes.set(
|
|
44
|
+
change.item.id,
|
|
45
|
+
toLiveblocksInternalNode(change.item, config)
|
|
46
|
+
);
|
|
106
47
|
}
|
|
107
48
|
break;
|
|
108
|
-
|
|
109
|
-
nodes.delete(change.id);
|
|
110
|
-
nodeCache.delete(change.id);
|
|
111
|
-
nextLocal.delete(change.id);
|
|
112
|
-
hasLocalChanged = true;
|
|
113
|
-
break;
|
|
49
|
+
}
|
|
114
50
|
case "position": {
|
|
115
51
|
const node = nodes.get(change.id);
|
|
116
|
-
if (!node || !change.position)
|
|
52
|
+
if (!node || !change.position)
|
|
117
53
|
break;
|
|
118
|
-
|
|
119
|
-
const previous = node.get("position");
|
|
120
|
-
if (previous?.x !== change.position.x || previous?.y !== change.position.y) {
|
|
54
|
+
if (change.position !== void 0) {
|
|
121
55
|
node.set("position", change.position);
|
|
122
56
|
}
|
|
123
57
|
if (change.dragging !== void 0) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
58
|
+
if (change.dragging) {
|
|
59
|
+
history.pause();
|
|
60
|
+
} else {
|
|
61
|
+
history.resume();
|
|
62
|
+
}
|
|
63
|
+
node.setLocal("dragging", change.dragging);
|
|
129
64
|
}
|
|
130
65
|
break;
|
|
131
66
|
}
|
|
132
67
|
case "dimensions": {
|
|
133
68
|
const node = nodes.get(change.id);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (node && change.dimensions !== void 0 && change.setAttributes !== void 0) {
|
|
69
|
+
if (!node)
|
|
70
|
+
break;
|
|
71
|
+
if (change.dimensions !== void 0 && change.setAttributes !== void 0) {
|
|
138
72
|
if (change.setAttributes === true || change.setAttributes === "width") {
|
|
139
73
|
node.set("width", change.dimensions.width);
|
|
140
74
|
}
|
|
@@ -143,115 +77,92 @@ function applyNodeChanges(args) {
|
|
|
143
77
|
}
|
|
144
78
|
}
|
|
145
79
|
if (change.dimensions !== void 0) {
|
|
146
|
-
|
|
80
|
+
node.setLocal("measured", change.dimensions);
|
|
147
81
|
}
|
|
148
82
|
if (change.resizing !== void 0) {
|
|
149
|
-
|
|
83
|
+
if (change.resizing) {
|
|
84
|
+
history.pause();
|
|
85
|
+
} else {
|
|
86
|
+
history.resume();
|
|
87
|
+
}
|
|
88
|
+
node.setLocal("resizing", change.resizing);
|
|
150
89
|
}
|
|
151
|
-
updateLocalState(nextLocal, change.id, patch);
|
|
152
|
-
hasLocalChanged = true;
|
|
153
90
|
break;
|
|
154
91
|
}
|
|
155
|
-
case "select":
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
92
|
+
case "select": {
|
|
93
|
+
const node = nodes.get(change.id);
|
|
94
|
+
if (!node)
|
|
95
|
+
break;
|
|
96
|
+
node.setLocal("selected", change.selected);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case "remove":
|
|
161
100
|
break;
|
|
162
101
|
}
|
|
163
102
|
}
|
|
164
|
-
return hasLocalChanged;
|
|
165
103
|
}
|
|
166
|
-
function applyEdgeChanges(
|
|
167
|
-
const { changes, edges, nextLocal, edgeCache } = args;
|
|
168
|
-
let hasLocalChanged = false;
|
|
104
|
+
function applyEdgeChanges(changes, edges, getEdgeSyncConfig) {
|
|
169
105
|
for (const change of changes) {
|
|
170
106
|
switch (change.type) {
|
|
171
107
|
case "add":
|
|
172
|
-
case "replace":
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
change.item
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
108
|
+
case "replace": {
|
|
109
|
+
const config = getEdgeSyncConfig(change.item.type);
|
|
110
|
+
const existing = edges.get(change.item.id);
|
|
111
|
+
if (existing) {
|
|
112
|
+
existing.reconcile(change.item, config);
|
|
113
|
+
} else {
|
|
114
|
+
edges.set(
|
|
115
|
+
change.item.id,
|
|
116
|
+
toLiveblocksInternalEdge(change.item, config)
|
|
117
|
+
);
|
|
180
118
|
}
|
|
181
119
|
break;
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
120
|
+
}
|
|
121
|
+
case "select": {
|
|
122
|
+
const edge = edges.get(change.id);
|
|
123
|
+
if (!edge)
|
|
124
|
+
break;
|
|
125
|
+
edge.setLocal("selected", change.selected);
|
|
187
126
|
break;
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
...nextLocal.get(change.id),
|
|
191
|
-
selected: change.selected
|
|
192
|
-
});
|
|
193
|
-
hasLocalChanged = true;
|
|
127
|
+
}
|
|
128
|
+
case "remove":
|
|
194
129
|
break;
|
|
195
130
|
}
|
|
196
131
|
}
|
|
197
|
-
return hasLocalChanged;
|
|
198
|
-
}
|
|
199
|
-
function createLiveblocksFlow(nodes = [], edges = []) {
|
|
200
|
-
return new LiveObject({
|
|
201
|
-
nodes: new LiveMap(nodes.map((node) => [node.id, nodeToStorage(node)])),
|
|
202
|
-
edges: new LiveMap(edges.map((edge) => [edge.id, edgeToStorage(edge)]))
|
|
203
|
-
});
|
|
204
132
|
}
|
|
205
133
|
function useLiveblocksFlow(options = {}) {
|
|
134
|
+
const history = useHistory();
|
|
206
135
|
const isStorageLoaded = useStorage(() => true) ?? false;
|
|
207
136
|
const frozenOptions = useInitial({
|
|
208
|
-
|
|
209
|
-
|
|
137
|
+
nodes: options.nodes,
|
|
138
|
+
edges: options.edges,
|
|
139
|
+
storageKey: options.storageKey ?? DEFAULT_STORAGE_KEY,
|
|
140
|
+
suspense: options.suspense ?? false
|
|
210
141
|
});
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
() => new Signal(/* @__PURE__ */ new Map())
|
|
142
|
+
const [getNodeSyncConfig, getEdgeSyncConfig] = useMemo(
|
|
143
|
+
() => [
|
|
144
|
+
buildNodeConfigCache(frozenOptions.nodes?.sync),
|
|
145
|
+
buildEdgeConfigCache(frozenOptions.edges?.sync)
|
|
146
|
+
],
|
|
147
|
+
[frozenOptions]
|
|
218
148
|
);
|
|
219
|
-
const
|
|
220
|
-
const localEdges = useSignal(localEdges\u03A3);
|
|
221
|
-
const remoteNodesMap = useStorage((storage) => {
|
|
149
|
+
const nodes = useStorage((storage) => {
|
|
222
150
|
const flow = storage[frozenOptions.storageKey];
|
|
223
|
-
return flow?.nodes
|
|
151
|
+
return flow?.nodes ? [...flow.nodes.values()] : null;
|
|
224
152
|
});
|
|
225
|
-
const
|
|
153
|
+
const edges = useStorage((storage) => {
|
|
226
154
|
const flow = storage[frozenOptions.storageKey];
|
|
227
|
-
return flow?.edges
|
|
155
|
+
return flow?.edges ? [...flow.edges.values()] : null;
|
|
228
156
|
});
|
|
229
|
-
const nodes = useMemo(
|
|
230
|
-
() => remoteNodesMap ? merge(nodeCache.current, remoteNodesMap, localNodes) : null,
|
|
231
|
-
[remoteNodesMap, localNodes]
|
|
232
|
-
);
|
|
233
|
-
const edges = useMemo(
|
|
234
|
-
() => remoteEdgesMap ? merge(edgeCache.current, remoteEdgesMap, localEdges) : null,
|
|
235
|
-
[remoteEdgesMap, localEdges]
|
|
236
|
-
);
|
|
237
157
|
const onNodesChange = useMutation(
|
|
238
158
|
({ storage }, changes) => {
|
|
239
159
|
const flow = storage.get(frozenOptions.storageKey);
|
|
240
160
|
if (!flow) {
|
|
241
161
|
return;
|
|
242
162
|
}
|
|
243
|
-
|
|
244
|
-
const hasLocalChanged = applyNodeChanges({
|
|
245
|
-
changes,
|
|
246
|
-
nodes: flow.get("nodes"),
|
|
247
|
-
nextLocal,
|
|
248
|
-
nodeCache: nodeCache.current
|
|
249
|
-
});
|
|
250
|
-
if (hasLocalChanged) {
|
|
251
|
-
localNodes\u03A3.set(nextLocal);
|
|
252
|
-
}
|
|
163
|
+
applyNodeChanges(changes, flow.get("nodes"), history, getNodeSyncConfig);
|
|
253
164
|
},
|
|
254
|
-
[]
|
|
165
|
+
[history, frozenOptions, getNodeSyncConfig]
|
|
255
166
|
);
|
|
256
167
|
const onEdgesChange = useMutation(
|
|
257
168
|
({ storage }, changes) => {
|
|
@@ -259,70 +170,90 @@ function useLiveblocksFlow(options = {}) {
|
|
|
259
170
|
if (!flow) {
|
|
260
171
|
return;
|
|
261
172
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
if (
|
|
270
|
-
|
|
173
|
+
applyEdgeChanges(changes, flow.get("edges"), getEdgeSyncConfig);
|
|
174
|
+
},
|
|
175
|
+
[frozenOptions, getEdgeSyncConfig]
|
|
176
|
+
);
|
|
177
|
+
const onConnect = useMutation(
|
|
178
|
+
({ storage }, connection) => {
|
|
179
|
+
const flow = storage.get(frozenOptions.storageKey);
|
|
180
|
+
if (!flow) {
|
|
181
|
+
return;
|
|
271
182
|
}
|
|
183
|
+
const [newEdge] = addEdge(connection, []);
|
|
184
|
+
if (!newEdge) {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const edges2 = flow.get("edges");
|
|
188
|
+
const config = getEdgeSyncConfig(newEdge.type);
|
|
189
|
+
edges2.set(newEdge.id, toLiveblocksInternalEdge(newEdge, config));
|
|
272
190
|
},
|
|
273
|
-
[]
|
|
191
|
+
[frozenOptions.storageKey, getEdgeSyncConfig]
|
|
274
192
|
);
|
|
275
|
-
const
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
const edges2 = flow.get("edges");
|
|
281
|
-
for (const edge of edges2.values()) {
|
|
282
|
-
if (edge.get("source") === connection.source && edge.get("target") === connection.target && (edge.get("sourceHandle") ?? null) === (connection.sourceHandle ?? null) && (edge.get("targetHandle") ?? null) === (connection.targetHandle ?? null)) {
|
|
193
|
+
const onDelete = useMutation(
|
|
194
|
+
({ storage }, params) => {
|
|
195
|
+
const flow = storage.get(frozenOptions.storageKey);
|
|
196
|
+
if (!flow) {
|
|
283
197
|
return;
|
|
284
198
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
storage
|
|
298
|
-
frozenOptions.storageKey
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
199
|
+
const nodesMap = flow.get("nodes");
|
|
200
|
+
const edgesMap = flow.get("edges");
|
|
201
|
+
for (const edge of params.edges) {
|
|
202
|
+
edgesMap.delete(edge.id);
|
|
203
|
+
}
|
|
204
|
+
for (const node of params.nodes) {
|
|
205
|
+
nodesMap.delete(node.id);
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
[frozenOptions.storageKey]
|
|
209
|
+
);
|
|
210
|
+
const setInitialStorage = useMutation(
|
|
211
|
+
({ storage }) => {
|
|
212
|
+
if (storage.get(frozenOptions.storageKey) !== void 0) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const initialNodes = frozenOptions.nodes?.initial ?? [];
|
|
216
|
+
const initialEdges = frozenOptions.edges?.initial ?? [];
|
|
217
|
+
storage.set(
|
|
218
|
+
frozenOptions.storageKey,
|
|
219
|
+
new LiveObject({
|
|
220
|
+
nodes: new LiveMap(
|
|
221
|
+
initialNodes.map((node) => [
|
|
222
|
+
node.id,
|
|
223
|
+
toLiveblocksInternalNode(node, getNodeSyncConfig(node.type))
|
|
224
|
+
])
|
|
225
|
+
),
|
|
226
|
+
edges: new LiveMap(
|
|
227
|
+
initialEdges.map((edge) => [
|
|
228
|
+
edge.id,
|
|
229
|
+
toLiveblocksInternalEdge(edge, getEdgeSyncConfig(edge.type))
|
|
230
|
+
])
|
|
231
|
+
)
|
|
232
|
+
})
|
|
233
|
+
);
|
|
234
|
+
},
|
|
235
|
+
[frozenOptions, getNodeSyncConfig, getEdgeSyncConfig]
|
|
236
|
+
);
|
|
302
237
|
useEffect(() => {
|
|
303
238
|
if (isStorageLoaded) {
|
|
304
|
-
|
|
239
|
+
history[kInternal].withoutHistory(() => {
|
|
240
|
+
setInitialStorage();
|
|
241
|
+
});
|
|
305
242
|
}
|
|
306
|
-
}, [isStorageLoaded, setInitialStorage]);
|
|
243
|
+
}, [isStorageLoaded, setInitialStorage, history]);
|
|
244
|
+
if (frozenOptions.suspense) {
|
|
245
|
+
useSuspendUntilStorageReady();
|
|
246
|
+
}
|
|
307
247
|
return {
|
|
308
|
-
nodes,
|
|
309
|
-
edges,
|
|
310
|
-
isLoading: !isStorageLoaded,
|
|
248
|
+
nodes: frozenOptions.suspense ? nodes ?? EMPTY_ARRAY : nodes,
|
|
249
|
+
edges: frozenOptions.suspense ? edges ?? EMPTY_ARRAY : edges,
|
|
250
|
+
isLoading: frozenOptions.suspense ? false : !isStorageLoaded,
|
|
311
251
|
onNodesChange,
|
|
312
252
|
onEdgesChange,
|
|
313
|
-
onConnect
|
|
314
|
-
|
|
315
|
-
}
|
|
316
|
-
function useLiveblocksFlowSuspense(options = {}) {
|
|
317
|
-
const result = useLiveblocksFlow(options);
|
|
318
|
-
useSuspendUntilStorageReady();
|
|
319
|
-
return {
|
|
320
|
-
...result,
|
|
321
|
-
nodes: result.nodes ?? EMPTY_ARRAY,
|
|
322
|
-
edges: result.edges ?? EMPTY_ARRAY,
|
|
323
|
-
isLoading: false
|
|
253
|
+
onConnect,
|
|
254
|
+
onDelete
|
|
324
255
|
};
|
|
325
256
|
}
|
|
326
257
|
|
|
327
|
-
export {
|
|
258
|
+
export { useLiveblocksFlow };
|
|
328
259
|
//# sourceMappingURL=flow.js.map
|
package/dist/flow.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow.js","sources":["../src/flow.ts"],"sourcesContent":["import {\n type DistributiveOmit,\n type JsonObject,\n LiveMap,\n LiveObject,\n type LsonObject,\n type Resolve,\n shallow,\n Signal,\n type ToImmutable,\n} from \"@liveblocks/core\";\nimport { useMutation, useStorage } from \"@liveblocks/react\";\nimport {\n useInitial,\n useSignal,\n useSuspendUntilStorageReady,\n} from \"@liveblocks/react/_private\";\nimport {\n addEdge as defaultAddEdge,\n type Connection,\n type Edge,\n type EdgeChange,\n type Node,\n type NodeChange,\n type OnConnect,\n type OnEdgesChange,\n type OnNodesChange,\n} from \"@xyflow/react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\n\nconst DEFAULT_STORAGE_KEY = \"flow\";\n\n// React Flow `Node` properties that are purely ephemeral and local to each client\n// instead of being written to Liveblocks Storage.\nconst NODE_LOCAL_KEYS = [\n \"selected\",\n \"dragging\",\n \"measured\",\n \"resizing\",\n] as const satisfies (keyof Node)[number][];\n\n// React Flow `Edge` properties that are purely ephemeral and local to each client\n// instead of being written to Liveblocks Storage.\nconst EDGE_LOCAL_KEYS = [\"selected\"] as const satisfies (keyof Edge)[number][];\n\nconst EMPTY_ARRAY = [] as unknown[];\n\nexport type SerializableNode = Node<JsonObject>;\nexport type SerializableEdge = Edge<JsonObject>;\n\n/**\n * The Liveblocks Storage representation of a React Flow `Node`.\n *\n * It doesn't include local-only properties.\n * The entire node and its `data` property are both stored as `LiveObject`s.\n */\nexport type LiveblocksNode<TNode extends SerializableNode = SerializableNode> =\n LiveObject<\n DistributiveOmit<TNode, (typeof NODE_LOCAL_KEYS)[number] | \"data\"> & {\n data: LiveObject<TNode[\"data\"]>;\n } & LsonObject\n >;\n\n/**\n * The Liveblocks Storage representation of a React Flow `Edge`.\n *\n * It doesn't include local-only properties.\n * The entire edge and its `data` property are both stored as `LiveObject`s.\n */\nexport type LiveblocksEdge<TEdge extends SerializableEdge = SerializableEdge> =\n LiveObject<\n DistributiveOmit<TEdge, (typeof EDGE_LOCAL_KEYS)[number] | \"data\"> & {\n data?: LiveObject<NonNullable<TEdge[\"data\"]>>;\n } & LsonObject\n >;\n\n/**\n * The Liveblocks Storage representation of a React Flow diagram made of nodes and edges.\n *\n * Nodes and edges are stored as `LiveMap`s keyed by their IDs, enabling\n * fine-grained conflict-free updates from multiple clients simultaneously.\n */\nexport type LiveblocksFlow<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n> = LiveObject<{\n nodes: LiveMap<string, LiveblocksNode<TNode>>;\n edges: LiveMap<string, LiveblocksEdge<TEdge>>;\n}>;\n\ntype LocalNodes = Partial<Record<(typeof NODE_LOCAL_KEYS)[number], unknown>>;\ntype LocalEdges = Partial<Record<(typeof EDGE_LOCAL_KEYS)[number], unknown>>;\n\ntype UseLiveblocksFlowResult<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n> = Resolve<\n (\n | {\n nodes: null;\n edges: null;\n isLoading: true;\n }\n | {\n nodes: TNode[];\n edges: TEdge[];\n isLoading: false;\n }\n ) & {\n onNodesChange: OnNodesChange<TNode>;\n onEdgesChange: OnEdgesChange<TEdge>;\n onConnect: OnConnect;\n }\n>;\n\ntype LiveblocksFlowSuspenseResult<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n> = Extract<UseLiveblocksFlowResult<TNode, TEdge>, { isLoading: false }>;\n\ntype UseLiveblocksFlowOptions<\n TNode extends SerializableNode,\n TEdge extends SerializableEdge,\n> = {\n /**\n * The initial React Flow nodes and edges.\n *\n * @example\n * ```tsx\n * const { ... } = useLiveblocksFlow({\n * initial: {\n * nodes: [\n * { id: \"1\", position: { x: 0, y: 0 }, data: { label: \"Node 1\" } },\n * { id: \"2\", position: { x: 0, y: 100 }, data: { label: \"Node 2\" } },\n * ],\n * edges: [\n * { id: \"1-2\", source: \"1\", target: \"2\" },\n * ],\n * },\n * });\n * ```\n *\n * This is equivalent to setting `initialStorage` on `RoomProvider`.\n *\n * @example\n * ```tsx\n * <RoomProvider\n * initialStorage={{\n * flow: createLiveblocksFlow([\n * { id: \"1\", position: { x: 0, y: 0 }, data: { label: \"Node 1\" } },\n * { id: \"2\", position: { x: 0, y: 100 }, data: { label: \"Node 2\" } },\n * ], [\n * { id: \"1-2\", source: \"1\", target: \"2\" },\n * ]),\n * }}\n * />\n * ```\n */\n initial?: {\n nodes?: TNode[];\n edges?: TEdge[];\n };\n\n /**\n * The key used to store the React Flow diagram in Liveblocks Storage.\n *\n * Defaults to `\"flow\"`.\n *\n * @example\n * ```tsx\n * const { ... } = useLiveblocksFlow({\n * storageKey: \"myDiagram\",\n * });\n * ```\n */\n storageKey?: string;\n};\n\nfunction pick<T extends object, K extends PropertyKey>(\n from: T,\n keys: readonly K[]\n): Partial<Record<K, unknown>> {\n const result: Partial<Record<K, unknown>> = {};\n\n for (const key of keys) {\n const value = (from as Record<PropertyKey, unknown>)[key];\n\n if (value !== undefined && value !== null) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction omit<T extends object, K extends PropertyKey>(\n from: T,\n keys: readonly K[]\n): Omit<T, Extract<K, keyof T>> {\n const result = { ...from } as Partial<T>;\n\n for (const key of keys) {\n delete (result as Record<PropertyKey, unknown>)[key];\n }\n\n return result as Omit<T, Extract<K, keyof T>>;\n}\n\nfunction reconcile<T extends { id: string }>(cache: Map<string, T>, next: T) {\n const previous = cache.get(next.id);\n\n if (previous && shallow(previous, next)) {\n return previous;\n }\n\n cache.set(next.id, next);\n\n return next;\n}\n\nfunction merge<T extends { id: string }, L extends object>(\n cache: Map<string, T>,\n remote: ReadonlyMap<string, T>,\n local: Map<string, L>\n): T[] {\n // Prune cached items that were deleted remotely.\n for (const id of cache.keys()) {\n if (!remote.has(id)) {\n cache.delete(id);\n }\n }\n\n // Prune local items that were deleted remotely.\n for (const id of local.keys()) {\n if (!remote.has(id)) {\n local.delete(id);\n }\n }\n\n // Reconcile remote and local items.\n return Array.from(remote.values(), (item) => {\n const localItem = local.get(item.id);\n\n return reconcile(\n cache,\n localItem ? (Object.assign({}, item, localItem) as T) : item\n );\n });\n}\n\nfunction updateLocalState<T extends object>(\n map: Map<string, T>,\n key: string,\n changes: T\n): boolean {\n const next: Record<string, unknown> = {};\n\n for (const change in changes) {\n const value = (changes as Record<string, unknown>)[change];\n\n // `false` values aren't stored.\n if (value !== undefined && value !== false) {\n next[change] = value;\n }\n }\n\n if (Object.keys(next).length > 0) {\n map.set(key, next as T);\n\n return true;\n } else {\n const hasItem = map.has(key);\n map.delete(key);\n\n return hasItem;\n }\n}\n\n// Converts a React Flow `Node` into a Liveblocks Storage version, omitting\n// the fields that must stay local to each client.\nfunction nodeToStorage<TNode extends SerializableNode>(\n node: TNode\n): LiveblocksNode<TNode> {\n const { data, ...rest } = omit(node, NODE_LOCAL_KEYS) as TNode;\n\n return new LiveObject({\n ...(rest as LsonObject),\n data: new LiveObject(data as LsonObject),\n }) as LiveblocksNode<TNode>;\n}\n\n// Converts a React Flow `Edge` into a Liveblocks Storage version, omitting\n// the fields that must stay local to each client.\nfunction edgeToStorage<TEdge extends SerializableEdge>(\n edge: TEdge\n): LiveblocksEdge<TEdge> {\n const { data, ...rest } = omit(edge, EDGE_LOCAL_KEYS) as TEdge;\n\n return new LiveObject({\n ...(rest as LsonObject),\n\n // `data` is optional on edges.\n data: data === undefined ? undefined : new LiveObject(data as LsonObject),\n }) as LiveblocksEdge<TEdge>;\n}\n\n// Similar to React Flow's `applyNodeChanges()`, but with a split between local\n// and remote changes.\n// https://reactflow.dev/api-reference/utils/apply-node-changes\nfunction applyNodeChanges<TNode extends SerializableNode>(args: {\n changes: NodeChange<TNode>[];\n nodes: LiveMap<string, LiveblocksNode<TNode>>;\n nextLocal: Map<string, Partial<LocalNodes>>;\n nodeCache: Map<string, TNode>;\n}): boolean {\n const { changes, nodes, nextLocal, nodeCache } = args;\n\n let hasLocalChanged = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n case \"replace\":\n nodes.set(change.item.id, nodeToStorage(change.item));\n if (\n updateLocalState(\n nextLocal,\n change.item.id,\n pick(change.item, NODE_LOCAL_KEYS)\n )\n ) {\n hasLocalChanged = true;\n }\n break;\n\n case \"remove\":\n nodes.delete(change.id);\n nodeCache.delete(change.id);\n nextLocal.delete(change.id);\n hasLocalChanged = true;\n break;\n\n case \"position\": {\n const node = nodes.get(change.id);\n\n if (!node || !change.position) {\n break;\n }\n\n const previous = node.get(\"position\") as TNode[\"position\"] | undefined;\n\n if (\n previous?.x !== change.position.x ||\n previous?.y !== change.position.y\n ) {\n node.set(\"position\", change.position);\n }\n\n if (change.dragging !== undefined) {\n updateLocalState(nextLocal, change.id, {\n ...nextLocal.get(change.id),\n dragging: change.dragging,\n });\n hasLocalChanged = true;\n }\n\n break;\n }\n\n case \"dimensions\": {\n const node = nodes.get(change.id);\n const patch: Partial<LocalNodes> = {\n ...nextLocal.get(change.id),\n };\n\n if (\n node &&\n change.dimensions !== undefined &&\n change.setAttributes !== undefined\n ) {\n if (\n change.setAttributes === true ||\n change.setAttributes === \"width\"\n ) {\n node.set(\"width\", change.dimensions.width);\n }\n\n if (\n change.setAttributes === true ||\n change.setAttributes === \"height\"\n ) {\n node.set(\"height\", change.dimensions.height);\n }\n }\n\n if (change.dimensions !== undefined) {\n patch.measured = change.dimensions;\n }\n\n if (change.resizing !== undefined) {\n patch.resizing = change.resizing;\n }\n\n updateLocalState(nextLocal, change.id, patch);\n hasLocalChanged = true;\n break;\n }\n\n case \"select\":\n updateLocalState(nextLocal, change.id, {\n ...nextLocal.get(change.id),\n selected: change.selected,\n });\n hasLocalChanged = true;\n break;\n }\n }\n\n return hasLocalChanged;\n}\n\n// Similar to React Flow's `applyEdgeChanges()`, but with a split between local\n// and remote changes.\n// https://reactflow.dev/api-reference/utils/apply-edge-changes\nfunction applyEdgeChanges<TEdge extends SerializableEdge>(args: {\n changes: EdgeChange<TEdge>[];\n edges: LiveMap<string, LiveblocksEdge<TEdge>>;\n nextLocal: Map<string, Partial<LocalEdges>>;\n edgeCache: Map<string, TEdge>;\n}): boolean {\n const { changes, edges, nextLocal, edgeCache } = args;\n\n let hasLocalChanged = false;\n\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n case \"replace\":\n edges.set(change.item.id, edgeToStorage(change.item));\n if (\n updateLocalState(\n nextLocal,\n change.item.id,\n pick(change.item, EDGE_LOCAL_KEYS)\n )\n ) {\n hasLocalChanged = true;\n }\n break;\n\n case \"remove\":\n edges.delete(change.id);\n edgeCache.delete(change.id);\n nextLocal.delete(change.id);\n hasLocalChanged = true;\n break;\n\n case \"select\":\n updateLocalState(nextLocal, change.id, {\n ...nextLocal.get(change.id),\n selected: change.selected,\n });\n hasLocalChanged = true;\n break;\n }\n }\n\n return hasLocalChanged;\n}\n\n/**\n * Creates a Liveblocks Storage representation of a React Flow diagram from nodes and edges.\n *\n * @example\n * ```tsx\n * <RoomProvider\n * initialStorage={{\n * flow: createLiveblocksFlow(initialNodes, initialEdges),\n * }}\n * />\n * ```\n */\nexport function createLiveblocksFlow<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n>(nodes: TNode[] = [], edges: TEdge[] = []): LiveblocksFlow<TNode, TEdge> {\n return new LiveObject({\n nodes: new LiveMap(nodes.map((node) => [node.id, nodeToStorage(node)])),\n edges: new LiveMap(edges.map((edge) => [edge.id, edgeToStorage(edge)])),\n }) as LiveblocksFlow<TNode, TEdge>;\n}\n\n/**\n * Returns a controlled React Flow state backed by Liveblocks Storage.\n *\n * @example\n * ```tsx\n * const { nodes, edges, onNodesChange, onEdgesChange, onConnect, isLoading } = useLiveblocksFlow();\n *\n * if (isLoading) {\n * return <div>Loading…</div>\n * }\n *\n * return <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} />;\n * ```\n */\nexport function useLiveblocksFlow<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n>(\n options: UseLiveblocksFlowOptions<TNode, TEdge> = {}\n): Resolve<UseLiveblocksFlowResult<TNode, TEdge>> {\n type TFlow = LiveblocksFlow<TNode, TEdge>;\n type TImmutableFlow = ToImmutable<LiveblocksFlow<TNode, TEdge>>;\n\n const isStorageLoaded = useStorage(() => true) ?? false;\n\n // These options are not reactive, only their initial values are used.\n const frozenOptions = useInitial({\n initial: options.initial,\n storageKey: options.storageKey ?? DEFAULT_STORAGE_KEY,\n });\n\n // Used to reconcile state changes with stable object references when the changes\n // are shallowly equal, preventing React Flow from re-rendering unchanged nodes and edges.\n const nodeCache = useRef<Map<string, TNode>>(new Map());\n const edgeCache = useRef<Map<string, TEdge>>(new Map());\n\n // Local-only state lives in signals.\n const [localNodesΣ] = useState(\n () => new Signal(new Map<string, Partial<LocalNodes>>())\n );\n const [localEdgesΣ] = useState(\n () => new Signal(new Map<string, Partial<LocalEdges>>())\n );\n const localNodes = useSignal(localNodesΣ);\n const localEdges = useSignal(localEdgesΣ);\n\n // Remote state lives in Liveblocks Storage.\n const remoteNodesMap = useStorage((storage) => {\n const flow = storage[frozenOptions.storageKey] as\n | TImmutableFlow\n | undefined;\n\n return (flow?.nodes ?? null) as ReadonlyMap<string, TNode> | null;\n });\n const remoteEdgesMap = useStorage((storage) => {\n const flow = storage[frozenOptions.storageKey] as\n | TImmutableFlow\n | undefined;\n\n return (flow?.edges ?? null) as ReadonlyMap<string, TEdge> | null;\n });\n\n // Merge remote and local layers to get the final state.\n const nodes = useMemo(\n () =>\n remoteNodesMap\n ? merge(nodeCache.current, remoteNodesMap, localNodes)\n : null,\n [remoteNodesMap, localNodes]\n );\n const edges = useMemo(\n () =>\n remoteEdgesMap\n ? merge(edgeCache.current, remoteEdgesMap, localEdges)\n : null,\n [remoteEdgesMap, localEdges]\n );\n\n const onNodesChange = useMutation(\n ({ storage }, changes: NodeChange<TNode>[]) => {\n const flow = storage.get(frozenOptions.storageKey) as TFlow | undefined;\n\n if (!flow) {\n return;\n }\n\n const nextLocal = new Map(localNodesΣ.get());\n const hasLocalChanged = applyNodeChanges({\n changes,\n nodes: flow.get(\"nodes\"),\n nextLocal,\n nodeCache: nodeCache.current,\n });\n\n if (hasLocalChanged) {\n localNodesΣ.set(nextLocal);\n }\n },\n []\n );\n\n const onEdgesChange = useMutation(\n ({ storage }, changes: EdgeChange<TEdge>[]) => {\n const flow = storage.get(frozenOptions.storageKey) as TFlow | undefined;\n\n if (!flow) {\n return;\n }\n\n const nextLocal = new Map(localEdgesΣ.get());\n const hasLocalChanged = applyEdgeChanges({\n changes,\n edges: flow.get(\"edges\"),\n nextLocal,\n edgeCache: edgeCache.current,\n });\n\n if (hasLocalChanged) {\n localEdgesΣ.set(nextLocal);\n }\n },\n []\n );\n\n const onConnect = useMutation(({ storage }, connection: Connection) => {\n const flow = storage.get(frozenOptions.storageKey) as TFlow | undefined;\n\n if (!flow) {\n return;\n }\n\n const edges = flow.get(\"edges\");\n\n // Check for duplicate connections.\n for (const edge of edges.values()) {\n if (\n edge.get(\"source\") === connection.source &&\n edge.get(\"target\") === connection.target &&\n (edge.get(\"sourceHandle\") ?? null) ===\n (connection.sourceHandle ?? null) &&\n (edge.get(\"targetHandle\") ?? null) === (connection.targetHandle ?? null)\n ) {\n return;\n }\n }\n\n // Delegate to React Flow's own `addEdge` helper for consistent default\n // edge ID generation, passing an empty array since de-duplication is\n // already handled above.\n const [newEdge] = defaultAddEdge(connection, [] as TEdge[]);\n\n if (!newEdge) {\n return;\n }\n\n edges.set(newEdge.id, edgeToStorage(newEdge));\n }, []);\n\n const setInitialStorage = useMutation(({ storage }) => {\n // Similarly to `initialStorage` on `Client.enterRoom` and `RoomProvider`, we only\n // initialize Storage if it doesn't already exist.\n if (storage.get(frozenOptions.storageKey) !== undefined) {\n return;\n }\n\n const { nodes: initialNodes = [], edges: initialEdges = [] } =\n frozenOptions.initial ?? {};\n\n storage.set(\n frozenOptions.storageKey,\n createLiveblocksFlow(initialNodes, initialEdges)\n );\n }, []);\n\n useEffect(() => {\n if (isStorageLoaded) {\n setInitialStorage();\n }\n }, [isStorageLoaded, setInitialStorage]);\n\n return {\n nodes,\n edges,\n isLoading: !isStorageLoaded,\n onNodesChange,\n onEdgesChange,\n onConnect,\n } as UseLiveblocksFlowResult<TNode, TEdge>;\n}\n\n/**\n * Returns a controlled React Flow state backed by Liveblocks Storage.\n *\n * @example\n * ```tsx\n * const { nodes, edges, onNodesChange, onEdgesChange, onConnect } = useLiveblocksFlow();\n *\n * return <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} />;\n * ```\n */\nexport function useLiveblocksFlowSuspense<\n TNode extends SerializableNode = SerializableNode,\n TEdge extends SerializableEdge = SerializableEdge,\n>(\n options: UseLiveblocksFlowOptions<TNode, TEdge> = {}\n): Resolve<LiveblocksFlowSuspenseResult<TNode, TEdge>> {\n const result = useLiveblocksFlow<TNode, TEdge>(options);\n\n useSuspendUntilStorageReady();\n\n return {\n ...result,\n nodes: result.nodes ?? (EMPTY_ARRAY as TNode[]),\n edges: result.edges ?? (EMPTY_ARRAY as TEdge[]),\n isLoading: false,\n };\n}\n"],"names":["edges","defaultAddEdge"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flow.js","sources":["../src/flow.ts"],"sourcesContent":["import type {\n History,\n JsonObject,\n Resolve,\n ToImmutable,\n} from \"@liveblocks/core\";\nimport { kInternal, LiveMap, LiveObject } from \"@liveblocks/core\";\nimport { useHistory, useMutation, useStorage } from \"@liveblocks/react\";\nimport {\n useInitial,\n useSuspendUntilStorageReady,\n} from \"@liveblocks/react/_private\";\nimport type {\n BuiltInEdge,\n BuiltInNode,\n Connection,\n Edge,\n EdgeChange,\n Node,\n NodeChange,\n OnConnect,\n OnDelete,\n OnEdgesChange,\n OnNodesChange,\n} from \"@xyflow/react\";\nimport { addEdge as defaultAddEdge } from \"@xyflow/react\";\nimport { useEffect, useMemo } from \"react\";\n\nimport {\n DEFAULT_STORAGE_KEY,\n EDGE_BASE_CONFIG,\n NODE_BASE_CONFIG,\n} from \"./constants\";\nimport { toLiveblocksInternalEdge, toLiveblocksInternalNode } from \"./helpers\";\nimport type {\n EdgeSyncConfig,\n InternalLiveblocksEdge,\n InternalLiveblocksFlow,\n InternalLiveblocksNode,\n NodeSyncConfig,\n SyncConfig,\n} from \"./types\";\n\nconst EMPTY_ARRAY = [] as unknown[];\n\ntype UseLiveblocksFlowResult<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n> = Resolve<\n (\n | {\n nodes: null;\n edges: null;\n isLoading: true;\n }\n | {\n nodes: N[];\n edges: E[];\n isLoading: false;\n }\n ) & {\n onNodesChange: OnNodesChange<N>;\n onEdgesChange: OnEdgesChange<E>;\n onConnect: OnConnect;\n onDelete: OnDelete<N, E>;\n }\n>;\n\ntype LiveblocksFlowSuspenseResult<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n> = Extract<UseLiveblocksFlowResult<N, E>, { isLoading: false }>;\n\nfunction mergeAndBuildDataConfigCache(\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 node/edge 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\nfunction buildNodeConfigCache<N extends Node>(\n /** The user-provided node data sync configuration, if any. */\n nodeDataConfig?: NodeSyncConfig<N>\n): (type: string | undefined) => SyncConfig {\n return mergeAndBuildDataConfigCache(NODE_BASE_CONFIG, nodeDataConfig);\n}\n\nfunction buildEdgeConfigCache<E extends Edge>(\n /** The user-provided edge data sync configuration, if any. */\n edgeDataConfig?: EdgeSyncConfig<E>\n): (type: string | undefined) => SyncConfig {\n return mergeAndBuildDataConfigCache(EDGE_BASE_CONFIG, edgeDataConfig);\n}\n\ntype UseLiveblocksFlowOptions<N extends Node, E extends Edge> = {\n nodes?: {\n /**\n * The initial React Flow nodes.\n *\n * @example\n * ```tsx\n * const { ... } = useLiveblocksFlow({\n * nodes: {\n * initial: [\n * { id: \"1\", position: { x: 0, y: 0 }, data: { label: \"Node 1\" } },\n * { id: \"2\", position: { x: 0, y: 100 }, data: { label: \"Node 2\" } },\n * ],\n * },\n * });\n * ```\n */\n initial?: N[];\n /**\n * Per-type sync configuration for node data keys.\n *\n * Use `\"*\"` as a fallback for all node types. Type-specific entries are\n * deep-merged on top of `\"*\"`, with explicitly named keys taking\n * precedence.\n *\n * @example\n * ```tsx\n * const { ... } = useLiveblocksFlow({\n * nodes: {\n * sync: {\n * // Fallback for all node types\n * \"*\": {\n * label: false, // Don't sync node.data.label\n * },\n *\n * // Override for node.type === 'myCustomNode'\n * // This will also not sync `myCustomNode.data.label` (because of the fallback above)\n * myCustomNode: {\n * showPreview: false, // Don't sync myCustomNode.data.showPreview\n * },\n * },\n * },\n * });\n * ```\n */\n sync?: NodeSyncConfig<N>;\n };\n\n edges?: {\n initial?: E[];\n /**\n * Per-type sync configuration for edge data keys.\n *\n * Use `\"*\"` as a fallback for all edge types. Type-specific entries are\n * deep-merged on top of `\"*\"`, with explicitly named keys taking\n * precedence.\n *\n * @example\n * ```tsx\n * const { ... } = useLiveblocksFlow({\n * edges: {\n * sync: {\n * // Fallback for all edge types\n * \"*\": {\n * hovered: false, // Don't sync edge.data.hovered\n * },\n *\n * // Override for edge.type === 'myCustomEdge'\n * // This will also not sync `myCustomEdge.data.hovered` (because of the fallback above)\n * myCustomEdge: {\n * isHighlighted: false, // Don't sync myCustomEdge.data.isHighlighted\n * },\n * },\n * },\n * });\n * ```\n */\n sync?: EdgeSyncConfig<E>;\n };\n\n /**\n * The key used to store the React Flow diagram in Liveblocks Storage.\n * Defaults to `\"flow\"`.\n */\n storageKey?: string;\n\n /**\n * When true, suspends until Storage is ready (use a React `Suspense`\n * boundary). Then `nodes` and `edges` are always arrays and `isLoading` is\n * always false.\n */\n suspense?: boolean;\n};\n\n// Similar to React Flow's `applyNodeChanges()`, but writes local-only\n// properties via `setLocal()` / `delete()` on the LiveObject directly.\n// https://reactflow.dev/api-reference/utils/apply-node-changes\nfunction applyNodeChanges<N extends Node>(\n changes: NodeChange<N>[],\n nodes: LiveMap<string, InternalLiveblocksNode>,\n history: History,\n getNodeSyncConfig: (nodeType: string | undefined) => SyncConfig\n): void {\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n case \"replace\": {\n const config = getNodeSyncConfig(change.item.type);\n const existing = nodes.get(change.item.id);\n if (existing) {\n existing.reconcile(change.item as unknown as JsonObject, config);\n } else {\n nodes.set(\n change.item.id,\n toLiveblocksInternalNode(change.item, config)\n );\n }\n break;\n }\n\n case \"position\": {\n const node = nodes.get(change.id);\n if (!node || !change.position) break;\n\n if (change.position !== undefined) {\n node.set(\"position\", change.position);\n }\n\n if (change.dragging !== undefined) {\n if (change.dragging) {\n history.pause();\n } else {\n history.resume();\n }\n // Must match NODE_BASE_CONFIG's `dragging: false`\n node.setLocal(\"dragging\", change.dragging);\n }\n break;\n }\n\n case \"dimensions\": {\n const node = nodes.get(change.id);\n if (!node) break;\n\n if (\n change.dimensions !== undefined &&\n change.setAttributes !== undefined\n ) {\n if (\n change.setAttributes === true ||\n change.setAttributes === \"width\"\n ) {\n node.set(\"width\", change.dimensions.width);\n }\n\n if (\n change.setAttributes === true ||\n change.setAttributes === \"height\"\n ) {\n node.set(\"height\", change.dimensions.height);\n }\n }\n\n if (change.dimensions !== undefined) {\n // Must match NODE_BASE_CONFIG's `measured: false`\n node.setLocal(\"measured\", change.dimensions);\n }\n\n if (change.resizing !== undefined) {\n if (change.resizing) {\n history.pause();\n } else {\n history.resume();\n }\n // Must match NODE_BASE_CONFIG's `resizing: false`\n node.setLocal(\"resizing\", change.resizing);\n }\n\n break;\n }\n\n case \"select\": {\n const node = nodes.get(change.id);\n if (!node) break;\n\n // Must match NODE_BASE_CONFIG's `selected: false`\n node.setLocal(\"selected\", change.selected);\n break;\n }\n\n case \"remove\":\n // Removals are handled by onDelete for atomic undo\n break;\n }\n }\n}\n\n// Similar to React Flow's `applyEdgeChanges()`, but writes local-only\n// properties via `setLocal()` / `delete()` on the LiveObject directly.\n// https://reactflow.dev/api-reference/utils/apply-edge-changes\nfunction applyEdgeChanges<E extends Edge>(\n changes: EdgeChange<E>[],\n edges: LiveMap<string, InternalLiveblocksEdge>,\n getEdgeSyncConfig: (type: string | undefined) => SyncConfig\n): void {\n for (const change of changes) {\n switch (change.type) {\n case \"add\":\n case \"replace\": {\n const config = getEdgeSyncConfig(change.item.type);\n const existing = edges.get(change.item.id);\n if (existing) {\n existing.reconcile(change.item as unknown as JsonObject, config);\n } else {\n edges.set(\n change.item.id,\n toLiveblocksInternalEdge(change.item, config)\n );\n }\n break;\n }\n\n case \"select\": {\n const edge = edges.get(change.id);\n if (!edge) break;\n // Must match EDGE_BASE_CONFIG's `selected: false`\n edge.setLocal(\"selected\", change.selected);\n break;\n }\n\n case \"remove\":\n // Removals are handled by onDelete for atomic undo\n break;\n }\n }\n}\n\n/**\n * Returns a controlled React Flow state backed by Liveblocks Storage.\n *\n * @example\n * ```tsx\n * const { nodes, edges, onNodesChange, onEdgesChange, onConnect, onDelete, isLoading } = useLiveblocksFlow();\n *\n * if (isLoading) {\n * return <div>Loading…</div>\n * }\n *\n * return <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} onDelete={onDelete} />;\n * ```\n * Pass `{ suspense: true }` to suspend until Storage is ready, `nodes` and `edges` will never be `null`.\n *\n * @example\n * ```tsx\n * const { nodes, edges, onNodesChange, onEdgesChange, onConnect, onDelete } =\n * useLiveblocksFlow({ suspense: true });\n *\n * return <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} onDelete={onDelete} />;\n * ```\n */\nexport function useLiveblocksFlow<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n>(\n options?: UseLiveblocksFlowOptions<N, E> & { suspense?: false }\n): Resolve<UseLiveblocksFlowResult<N, E>>;\nexport function useLiveblocksFlow<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n>(\n options: UseLiveblocksFlowOptions<N, E> & { suspense: true }\n): Resolve<LiveblocksFlowSuspenseResult<N, E>>;\nexport function useLiveblocksFlow<\n N extends Node = BuiltInNode,\n E extends Edge = BuiltInEdge,\n>(\n options: UseLiveblocksFlowOptions<N, E> = {}\n): Resolve<UseLiveblocksFlowResult<N, E> | LiveblocksFlowSuspenseResult<N, E>> {\n const history = useHistory();\n const isStorageLoaded = useStorage(() => true) ?? false;\n\n // These options are not reactive, only their initial values are used.\n const frozenOptions = useInitial({\n nodes: options.nodes,\n edges: options.edges,\n storageKey: options.storageKey ?? DEFAULT_STORAGE_KEY,\n suspense: options.suspense ?? false,\n });\n\n // Pre-compute sync config caches once (not on every render)\n const [getNodeSyncConfig, getEdgeSyncConfig] = useMemo(\n () =>\n [\n buildNodeConfigCache(frozenOptions.nodes?.sync),\n buildEdgeConfigCache(frozenOptions.edges?.sync),\n ] as const,\n [frozenOptions]\n );\n\n // Storage already includes local overlays via toImmutable(), so no\n // separate local layer is needed. Individual node/edge immutable references\n // are already stable (only change when the underlying LiveObject changes).\n const nodes = useStorage((storage) => {\n const flow = storage[frozenOptions.storageKey] as\n | ToImmutable<InternalLiveblocksFlow>\n | undefined;\n return flow?.nodes ? ([...flow.nodes.values()] as unknown as N[]) : null;\n });\n const edges = useStorage((storage) => {\n const flow = storage[frozenOptions.storageKey] as\n | ToImmutable<InternalLiveblocksFlow>\n | undefined;\n return flow?.edges ? ([...flow.edges.values()] as unknown as E[]) : null;\n });\n\n const onNodesChange = useMutation(\n ({ storage }, changes: NodeChange<N>[]) => {\n const flow = storage.get(frozenOptions.storageKey) as\n | InternalLiveblocksFlow\n | undefined;\n if (!flow) {\n return;\n }\n\n applyNodeChanges(changes, flow.get(\"nodes\"), history, getNodeSyncConfig);\n },\n [history, frozenOptions, getNodeSyncConfig]\n );\n\n const onEdgesChange = useMutation(\n ({ storage }, changes: EdgeChange<E>[]) => {\n const flow = storage.get(frozenOptions.storageKey) as\n | InternalLiveblocksFlow\n | undefined;\n if (!flow) {\n return;\n }\n\n applyEdgeChanges(changes, flow.get(\"edges\"), getEdgeSyncConfig);\n },\n [frozenOptions, getEdgeSyncConfig]\n );\n\n const onConnect = useMutation(\n ({ storage }, connection: Connection) => {\n const flow = storage.get(frozenOptions.storageKey) as\n | InternalLiveblocksFlow\n | undefined;\n if (!flow) {\n return;\n }\n\n // Delegate to React Flow's own `addEdge` helper for consistent default\n // edge ID generation, passing an empty array since de-duplication is\n // already handled above.\n const [newEdge] = defaultAddEdge(connection, [] as E[]);\n if (!newEdge) {\n return;\n }\n\n const edges = flow.get(\"edges\");\n const config = getEdgeSyncConfig(newEdge.type);\n edges.set(newEdge.id, toLiveblocksInternalEdge(newEdge, config));\n },\n [frozenOptions.storageKey, getEdgeSyncConfig]\n );\n\n const onDelete = useMutation(\n ({ storage }, params: { nodes: N[]; edges: E[] }) => {\n const flow = storage.get(frozenOptions.storageKey) as\n | InternalLiveblocksFlow\n | undefined;\n if (!flow) {\n return;\n }\n\n const nodesMap = flow.get(\"nodes\");\n const edgesMap = flow.get(\"edges\");\n\n for (const edge of params.edges) {\n edgesMap.delete(edge.id);\n }\n\n for (const node of params.nodes) {\n nodesMap.delete(node.id);\n }\n },\n [frozenOptions.storageKey]\n );\n\n const setInitialStorage = useMutation(\n ({ storage }) => {\n // Similarly to `initialStorage` on `Client.enterRoom` and `RoomProvider`, we only\n // initialize Storage if it doesn't already exist.\n if (storage.get(frozenOptions.storageKey) !== undefined) {\n return;\n }\n\n const initialNodes = frozenOptions.nodes?.initial ?? [];\n const initialEdges = frozenOptions.edges?.initial ?? [];\n\n storage.set(\n frozenOptions.storageKey,\n new LiveObject({\n nodes: new LiveMap(\n initialNodes.map((node) => [\n node.id,\n toLiveblocksInternalNode(node, getNodeSyncConfig(node.type)),\n ])\n ),\n edges: new LiveMap(\n initialEdges.map((edge) => [\n edge.id,\n toLiveblocksInternalEdge(edge, getEdgeSyncConfig(edge.type)),\n ])\n ),\n })\n );\n },\n [frozenOptions, getNodeSyncConfig, getEdgeSyncConfig]\n );\n\n useEffect(() => {\n if (isStorageLoaded) {\n history[kInternal].withoutHistory(() => {\n setInitialStorage();\n });\n }\n }, [isStorageLoaded, setInitialStorage, history]);\n\n if (frozenOptions.suspense) {\n // eslint-disable-next-line react-hooks/rules-of-hooks -- `suspense` is frozen so this branch is stable\n useSuspendUntilStorageReady();\n }\n\n return {\n nodes: frozenOptions.suspense ? (nodes ?? (EMPTY_ARRAY as N[])) : nodes,\n edges: frozenOptions.suspense ? (edges ?? (EMPTY_ARRAY as E[])) : edges,\n isLoading: frozenOptions.suspense ? false : !isStorageLoaded,\n onNodesChange,\n onEdgesChange,\n onConnect,\n onDelete,\n } as UseLiveblocksFlowResult<N, E> | LiveblocksFlowSuspenseResult<N, E>;\n}\n"],"names":["defaultAddEdge","edges"],"mappings":"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"}
|