canvu-react 0.4.7 → 0.4.9
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/realtime.cjs +97 -10
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +97 -10
- package/dist/realtime.js.map +1 -1
- package/package.json +1 -1
package/dist/realtime.cjs
CHANGED
|
@@ -2021,6 +2021,7 @@ function createYjsBoardDoc() {
|
|
|
2021
2021
|
doc,
|
|
2022
2022
|
yItems,
|
|
2023
2023
|
lastServerConfirmedIds: /* @__PURE__ */ new Set(),
|
|
2024
|
+
lastServerConfirmedItemSerializations: /* @__PURE__ */ new Map(),
|
|
2024
2025
|
serverItemSeenAt: /* @__PURE__ */ new Map()
|
|
2025
2026
|
};
|
|
2026
2027
|
}
|
|
@@ -2077,6 +2078,10 @@ function valuesEqual(left, right) {
|
|
|
2077
2078
|
return false;
|
|
2078
2079
|
}
|
|
2079
2080
|
}
|
|
2081
|
+
function serializeItem(value) {
|
|
2082
|
+
const item = value instanceof Y__namespace.Map ? yMapToVectorItem(value) : value;
|
|
2083
|
+
return JSON.stringify(item);
|
|
2084
|
+
}
|
|
2080
2085
|
function updateYMapInPlace(yMap, next) {
|
|
2081
2086
|
const nextKeys = /* @__PURE__ */ new Set();
|
|
2082
2087
|
for (const [key, value] of Object.entries(next)) {
|
|
@@ -2146,6 +2151,14 @@ function applyServerSnapshotToYDoc(board, options) {
|
|
|
2146
2151
|
if (!id) continue;
|
|
2147
2152
|
const existing = indexYItemsById(board.yItems).get(id);
|
|
2148
2153
|
if (existing) {
|
|
2154
|
+
const currentSerialized = serializeItem(existing.yMap);
|
|
2155
|
+
const incomingSerialized = serializeItem(item);
|
|
2156
|
+
const confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);
|
|
2157
|
+
const hasPendingLocalChange = confirmedSerialized === void 0 ? currentSerialized !== incomingSerialized : currentSerialized !== confirmedSerialized && currentSerialized !== incomingSerialized;
|
|
2158
|
+
if (hasPendingLocalChange) {
|
|
2159
|
+
board.serverItemSeenAt.set(id, now);
|
|
2160
|
+
continue;
|
|
2161
|
+
}
|
|
2149
2162
|
updateYMapInPlace(existing.yMap, item);
|
|
2150
2163
|
board.serverItemSeenAt.set(id, now);
|
|
2151
2164
|
continue;
|
|
@@ -2156,9 +2169,13 @@ function applyServerSnapshotToYDoc(board, options) {
|
|
|
2156
2169
|
}
|
|
2157
2170
|
}, origin);
|
|
2158
2171
|
board.lastServerConfirmedIds = /* @__PURE__ */ new Set();
|
|
2172
|
+
board.lastServerConfirmedItemSerializations = /* @__PURE__ */ new Map();
|
|
2159
2173
|
for (const item of snapshotItems) {
|
|
2160
2174
|
const id = getItemId(item);
|
|
2161
|
-
if (id)
|
|
2175
|
+
if (id) {
|
|
2176
|
+
board.lastServerConfirmedIds.add(id);
|
|
2177
|
+
board.lastServerConfirmedItemSerializations.set(id, serializeItem(item));
|
|
2178
|
+
}
|
|
2162
2179
|
}
|
|
2163
2180
|
}
|
|
2164
2181
|
function replaceYDocWithSnapshot(board, options) {
|
|
@@ -2173,11 +2190,13 @@ function replaceYDocWithSnapshot(board, options) {
|
|
|
2173
2190
|
}
|
|
2174
2191
|
}, origin);
|
|
2175
2192
|
board.lastServerConfirmedIds = /* @__PURE__ */ new Set();
|
|
2193
|
+
board.lastServerConfirmedItemSerializations = /* @__PURE__ */ new Map();
|
|
2176
2194
|
board.serverItemSeenAt = /* @__PURE__ */ new Map();
|
|
2177
2195
|
for (const item of snapshotItems) {
|
|
2178
2196
|
const id = getItemId(item);
|
|
2179
2197
|
if (id) {
|
|
2180
2198
|
board.lastServerConfirmedIds.add(id);
|
|
2199
|
+
board.lastServerConfirmedItemSerializations.set(id, serializeItem(item));
|
|
2181
2200
|
board.serverItemSeenAt.set(id, now);
|
|
2182
2201
|
}
|
|
2183
2202
|
}
|
|
@@ -2189,7 +2208,8 @@ function getLocallyPendingItemIds(board) {
|
|
|
2189
2208
|
if (!yMap) continue;
|
|
2190
2209
|
const id = getItemId(yMap);
|
|
2191
2210
|
if (!id) continue;
|
|
2192
|
-
|
|
2211
|
+
const confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);
|
|
2212
|
+
if (!confirmedSerialized || serializeItem(yMap) !== confirmedSerialized) {
|
|
2193
2213
|
pending.add(id);
|
|
2194
2214
|
}
|
|
2195
2215
|
}
|
|
@@ -2378,6 +2398,30 @@ function prepareRealtimeItems(items) {
|
|
|
2378
2398
|
return null;
|
|
2379
2399
|
}
|
|
2380
2400
|
}
|
|
2401
|
+
function getRealtimeItemId(item) {
|
|
2402
|
+
const id = item.id;
|
|
2403
|
+
return typeof id === "string" ? id : null;
|
|
2404
|
+
}
|
|
2405
|
+
function serializeRealtimeItem(item) {
|
|
2406
|
+
try {
|
|
2407
|
+
return JSON.stringify(sanitizeRealtimeItem(item));
|
|
2408
|
+
} catch {
|
|
2409
|
+
return null;
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
function resolvePendingDraftItemIds(board, items) {
|
|
2413
|
+
const pendingIds = /* @__PURE__ */ new Set();
|
|
2414
|
+
for (const item of items) {
|
|
2415
|
+
const id = getRealtimeItemId(item);
|
|
2416
|
+
if (!id) continue;
|
|
2417
|
+
const confirmedSerialized = board.lastServerConfirmedItemSerializations.get(id);
|
|
2418
|
+
const serialized = serializeRealtimeItem(item);
|
|
2419
|
+
if (!confirmedSerialized || !serialized || serialized !== confirmedSerialized) {
|
|
2420
|
+
pendingIds.add(id);
|
|
2421
|
+
}
|
|
2422
|
+
}
|
|
2423
|
+
return pendingIds.size > 0 ? Array.from(pendingIds) : void 0;
|
|
2424
|
+
}
|
|
2381
2425
|
function useRealtimeSession(options) {
|
|
2382
2426
|
const {
|
|
2383
2427
|
url,
|
|
@@ -2568,7 +2612,8 @@ function useRealtimeSession(options) {
|
|
|
2568
2612
|
}
|
|
2569
2613
|
const board = boardRef.current;
|
|
2570
2614
|
const draft = localDraftRef.current;
|
|
2571
|
-
const
|
|
2615
|
+
const canEncodeYDocState = board && draft.yDocState == null && sameSerializedItems(readVectorItems(board.yItems), draft.items);
|
|
2616
|
+
const draftToWrite = canEncodeYDocState ? { ...draft, yDocState: encodeYDocState(board) } : draft;
|
|
2572
2617
|
writeRealtimeOfflineDraft(draftToWrite);
|
|
2573
2618
|
}, [clearDraftPersistSchedule, roomId]);
|
|
2574
2619
|
const scheduleDraftPersistence = react.useCallback(() => {
|
|
@@ -2708,13 +2753,26 @@ function useRealtimeSession(options) {
|
|
|
2708
2753
|
}, DOCUMENT_FLUSH_DEBOUNCE_MS);
|
|
2709
2754
|
}, DOCUMENT_FLUSH_DEBOUNCE_MS);
|
|
2710
2755
|
}, [clearDocumentFlushSchedule, flushQueuedDocument]);
|
|
2711
|
-
const queueDocumentSend = react.useCallback(
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2756
|
+
const queueDocumentSend = react.useCallback(
|
|
2757
|
+
(items) => {
|
|
2758
|
+
pendingLocalItemsRef.current = items;
|
|
2759
|
+
queuedDirtyRef.current = true;
|
|
2760
|
+
setHasPendingDocumentSync(true);
|
|
2761
|
+
setHasLocalOfflineDraft(true);
|
|
2762
|
+
const board = boardRef.current;
|
|
2763
|
+
const draftItems = sanitizeRealtimeItems(items);
|
|
2764
|
+
setLocalDraftRef.current({
|
|
2765
|
+
roomId,
|
|
2766
|
+
baseRevision: currentRevisionRef.current,
|
|
2767
|
+
items: draftItems,
|
|
2768
|
+
updatedAt: nowMs(),
|
|
2769
|
+
pendingIds: board ? resolvePendingDraftItemIds(board, draftItems) : void 0
|
|
2770
|
+
});
|
|
2771
|
+
scheduleDraftPersistenceRef.current?.();
|
|
2772
|
+
scheduleDocumentFlushRef.current();
|
|
2773
|
+
},
|
|
2774
|
+
[roomId]
|
|
2775
|
+
);
|
|
2718
2776
|
const applyDraftSnapshot = react.useCallback(
|
|
2719
2777
|
(draft, options2) => {
|
|
2720
2778
|
const board = boardRef.current;
|
|
@@ -2729,6 +2787,7 @@ function useRealtimeSession(options) {
|
|
|
2729
2787
|
restoredFromBinary = decodeYDocState(board, draft.yDocState);
|
|
2730
2788
|
if (restoredFromBinary) {
|
|
2731
2789
|
const allIds = /* @__PURE__ */ new Set();
|
|
2790
|
+
const allItems = readVectorItems(board.yItems);
|
|
2732
2791
|
for (let i = 0; i < board.yItems.length; i++) {
|
|
2733
2792
|
const yMap = board.yItems.get(i);
|
|
2734
2793
|
if (!yMap) continue;
|
|
@@ -2737,9 +2796,17 @@ function useRealtimeSession(options) {
|
|
|
2737
2796
|
}
|
|
2738
2797
|
const pendingIds = new Set(draft.pendingIds ?? []);
|
|
2739
2798
|
board.lastServerConfirmedIds = /* @__PURE__ */ new Set();
|
|
2799
|
+
board.lastServerConfirmedItemSerializations = /* @__PURE__ */ new Map();
|
|
2740
2800
|
for (const id of allIds) {
|
|
2741
2801
|
if (!pendingIds.has(id)) {
|
|
2742
2802
|
board.lastServerConfirmedIds.add(id);
|
|
2803
|
+
const item = allItems.find((candidate) => candidate.id === id);
|
|
2804
|
+
if (item) {
|
|
2805
|
+
board.lastServerConfirmedItemSerializations.set(
|
|
2806
|
+
id,
|
|
2807
|
+
JSON.stringify(item)
|
|
2808
|
+
);
|
|
2809
|
+
}
|
|
2743
2810
|
}
|
|
2744
2811
|
}
|
|
2745
2812
|
}
|
|
@@ -2750,6 +2817,7 @@ function useRealtimeSession(options) {
|
|
|
2750
2817
|
origin: ORIGIN_BOOTSTRAP
|
|
2751
2818
|
});
|
|
2752
2819
|
board.lastServerConfirmedIds = /* @__PURE__ */ new Set();
|
|
2820
|
+
board.lastServerConfirmedItemSerializations = /* @__PURE__ */ new Map();
|
|
2753
2821
|
}
|
|
2754
2822
|
}
|
|
2755
2823
|
const items = board ? readVectorItems(board.yItems) : draft.items;
|
|
@@ -2868,6 +2936,25 @@ function useRealtimeSession(options) {
|
|
|
2868
2936
|
setLocalDraftRef.current = setLocalDraft;
|
|
2869
2937
|
const scheduleDraftPersistenceRef = react.useRef(scheduleDraftPersistence);
|
|
2870
2938
|
scheduleDraftPersistenceRef.current = scheduleDraftPersistence;
|
|
2939
|
+
const persistLocalDraftRef = react.useRef(persistLocalDraft);
|
|
2940
|
+
persistLocalDraftRef.current = persistLocalDraft;
|
|
2941
|
+
react.useEffect(() => {
|
|
2942
|
+
const persistDraft = () => {
|
|
2943
|
+
persistLocalDraftRef.current();
|
|
2944
|
+
};
|
|
2945
|
+
const handleVisibilityChange = () => {
|
|
2946
|
+
if (window.document.visibilityState === "hidden") persistDraft();
|
|
2947
|
+
};
|
|
2948
|
+
window.addEventListener("pagehide", persistDraft);
|
|
2949
|
+
window.document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
2950
|
+
return () => {
|
|
2951
|
+
window.removeEventListener("pagehide", persistDraft);
|
|
2952
|
+
window.document.removeEventListener(
|
|
2953
|
+
"visibilitychange",
|
|
2954
|
+
handleVisibilityChange
|
|
2955
|
+
);
|
|
2956
|
+
};
|
|
2957
|
+
}, []);
|
|
2871
2958
|
react.useEffect(() => {
|
|
2872
2959
|
if (boardRef.current) {
|
|
2873
2960
|
boardRef.current.doc.destroy();
|