canvu-react 0.3.11 → 0.3.12
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 +58 -50
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +58 -50
- package/dist/realtime.js.map +1 -1
- package/package.json +1 -1
package/dist/realtime.js
CHANGED
|
@@ -2198,7 +2198,7 @@ function useRealtimeSession(options) {
|
|
|
2198
2198
|
items: preparedItems.items,
|
|
2199
2199
|
serialized: preparedItems.serialized
|
|
2200
2200
|
};
|
|
2201
|
-
const didSend =
|
|
2201
|
+
const didSend = sendRawRef.current({
|
|
2202
2202
|
type: "document:update",
|
|
2203
2203
|
roomId,
|
|
2204
2204
|
clientId: clientIdRef.current,
|
|
@@ -2210,7 +2210,7 @@ function useRealtimeSession(options) {
|
|
|
2210
2210
|
outboundInFlightRef.current = null;
|
|
2211
2211
|
setHasPendingDocumentSync(true);
|
|
2212
2212
|
}
|
|
2213
|
-
}, [clearDocumentFlushSchedule, roomId
|
|
2213
|
+
}, [clearDocumentFlushSchedule, roomId]);
|
|
2214
2214
|
const scheduleDocumentFlush = useCallback(() => {
|
|
2215
2215
|
clearDocumentFlushSchedule();
|
|
2216
2216
|
documentFlushTimerRef.current = window.setTimeout(() => {
|
|
@@ -2233,9 +2233,9 @@ function useRealtimeSession(options) {
|
|
|
2233
2233
|
queuedItemsRef.current = items;
|
|
2234
2234
|
setHasPendingDocumentSync(true);
|
|
2235
2235
|
if (conflictRef.current) return;
|
|
2236
|
-
|
|
2236
|
+
scheduleDocumentFlushRef.current();
|
|
2237
2237
|
},
|
|
2238
|
-
[roomId,
|
|
2238
|
+
[roomId, scheduleDraftPersistence, setLocalDraft]
|
|
2239
2239
|
);
|
|
2240
2240
|
const applyDraftSnapshot = useCallback(
|
|
2241
2241
|
(draft, options2) => {
|
|
@@ -2253,7 +2253,7 @@ function useRealtimeSession(options) {
|
|
|
2253
2253
|
return false;
|
|
2254
2254
|
}
|
|
2255
2255
|
if (sameSerializedItems(localDraft.items, serverDocument.items)) {
|
|
2256
|
-
|
|
2256
|
+
clearLocalDraftRef.current();
|
|
2257
2257
|
setHasPendingDocumentSync(false);
|
|
2258
2258
|
setConflictState(null);
|
|
2259
2259
|
applyDocument(serverDocument, options2);
|
|
@@ -2280,13 +2280,7 @@ function useRealtimeSession(options) {
|
|
|
2280
2280
|
});
|
|
2281
2281
|
return true;
|
|
2282
2282
|
},
|
|
2283
|
-
[
|
|
2284
|
-
applyDocument,
|
|
2285
|
-
applyDraftSnapshot,
|
|
2286
|
-
clearLocalDraft,
|
|
2287
|
-
scheduleDocumentFlush,
|
|
2288
|
-
setConflictState
|
|
2289
|
-
]
|
|
2283
|
+
[applyDocument, applyDraftSnapshot, scheduleDocumentFlush, setConflictState]
|
|
2290
2284
|
);
|
|
2291
2285
|
const sendPresenceUpdate = useCallback(() => {
|
|
2292
2286
|
sendRaw({
|
|
@@ -2373,6 +2367,26 @@ function useRealtimeSession(options) {
|
|
|
2373
2367
|
setLocalDraft
|
|
2374
2368
|
]
|
|
2375
2369
|
);
|
|
2370
|
+
const setConflictStateRef = useRef(setConflictState);
|
|
2371
|
+
setConflictStateRef.current = setConflictState;
|
|
2372
|
+
const updateConnectionRef = useRef(updateConnection);
|
|
2373
|
+
updateConnectionRef.current = updateConnection;
|
|
2374
|
+
const applyDocumentRef = useRef(applyDocument);
|
|
2375
|
+
applyDocumentRef.current = applyDocument;
|
|
2376
|
+
const clearLocalDraftRef = useRef(clearLocalDraft);
|
|
2377
|
+
clearLocalDraftRef.current = clearLocalDraft;
|
|
2378
|
+
const collapsePeersToSelfRef = useRef(collapsePeersToSelf);
|
|
2379
|
+
collapsePeersToSelfRef.current = collapsePeersToSelf;
|
|
2380
|
+
const applyPeersRef = useRef(applyPeers);
|
|
2381
|
+
applyPeersRef.current = applyPeers;
|
|
2382
|
+
const resolveAuthoritativeDocumentRef = useRef(resolveAuthoritativeDocument);
|
|
2383
|
+
resolveAuthoritativeDocumentRef.current = resolveAuthoritativeDocument;
|
|
2384
|
+
const scheduleDocumentFlushRef = useRef(scheduleDocumentFlush);
|
|
2385
|
+
scheduleDocumentFlushRef.current = scheduleDocumentFlush;
|
|
2386
|
+
const scheduleReconnectRef = useRef(scheduleReconnect);
|
|
2387
|
+
scheduleReconnectRef.current = scheduleReconnect;
|
|
2388
|
+
const sendRawRef = useRef(sendRaw);
|
|
2389
|
+
sendRawRef.current = sendRaw;
|
|
2376
2390
|
useEffect(() => {
|
|
2377
2391
|
if (!roomId) {
|
|
2378
2392
|
clearDocumentFlushSchedule();
|
|
@@ -2426,8 +2440,8 @@ function useRealtimeSession(options) {
|
|
|
2426
2440
|
queuedItemsRef.current = localDraftRef.current?.items ?? null;
|
|
2427
2441
|
outboundInFlightRef.current = null;
|
|
2428
2442
|
setHasPendingDocumentSync(localDraftRef.current != null);
|
|
2429
|
-
|
|
2430
|
-
|
|
2443
|
+
collapsePeersToSelfRef.current("offline");
|
|
2444
|
+
updateConnectionRef.current((prev) => ({
|
|
2431
2445
|
...prev,
|
|
2432
2446
|
state: "offline",
|
|
2433
2447
|
connected: false,
|
|
@@ -2439,8 +2453,8 @@ function useRealtimeSession(options) {
|
|
|
2439
2453
|
manualDisconnectRef.current = false;
|
|
2440
2454
|
const socketUrl = normalizeSocketUrl(url);
|
|
2441
2455
|
if (!socketUrl) {
|
|
2442
|
-
|
|
2443
|
-
|
|
2456
|
+
collapsePeersToSelfRef.current("offline");
|
|
2457
|
+
updateConnectionRef.current((prev) => ({
|
|
2444
2458
|
...prev,
|
|
2445
2459
|
state: "offline",
|
|
2446
2460
|
connected: false,
|
|
@@ -2450,7 +2464,7 @@ function useRealtimeSession(options) {
|
|
|
2450
2464
|
return;
|
|
2451
2465
|
}
|
|
2452
2466
|
if (!isValidSocketUrl(socketUrl)) {
|
|
2453
|
-
|
|
2467
|
+
updateConnectionRef.current((prev) => ({
|
|
2454
2468
|
...prev,
|
|
2455
2469
|
state: "error",
|
|
2456
2470
|
connected: false,
|
|
@@ -2461,7 +2475,7 @@ function useRealtimeSession(options) {
|
|
|
2461
2475
|
return;
|
|
2462
2476
|
}
|
|
2463
2477
|
let disposed = false;
|
|
2464
|
-
|
|
2478
|
+
updateConnectionRef.current((prev) => ({
|
|
2465
2479
|
...prev,
|
|
2466
2480
|
state: retryCountRef.current > 0 ? "reconnecting" : "connecting",
|
|
2467
2481
|
connected: false,
|
|
@@ -2479,7 +2493,7 @@ function useRealtimeSession(options) {
|
|
|
2479
2493
|
socket.addEventListener("open", () => {
|
|
2480
2494
|
if (disposed) return;
|
|
2481
2495
|
clearConnectTimeout();
|
|
2482
|
-
|
|
2496
|
+
sendRawRef.current({
|
|
2483
2497
|
type: "session:join",
|
|
2484
2498
|
roomId,
|
|
2485
2499
|
peer: {
|
|
@@ -2492,7 +2506,7 @@ function useRealtimeSession(options) {
|
|
|
2492
2506
|
});
|
|
2493
2507
|
clearHeartbeatTimer();
|
|
2494
2508
|
heartbeatTimerRef.current = window.setInterval(() => {
|
|
2495
|
-
|
|
2509
|
+
sendRawRef.current({
|
|
2496
2510
|
type: "session:ping",
|
|
2497
2511
|
roomId,
|
|
2498
2512
|
clientId: clientIdRef.current,
|
|
@@ -2512,13 +2526,13 @@ function useRealtimeSession(options) {
|
|
|
2512
2526
|
}
|
|
2513
2527
|
const parsed = parseRealtimeServerMessage(payload);
|
|
2514
2528
|
if (!parsed) return;
|
|
2515
|
-
|
|
2529
|
+
updateConnectionRef.current((prev) => ({
|
|
2516
2530
|
...prev,
|
|
2517
2531
|
lastMessageAt: nowMs()
|
|
2518
2532
|
}));
|
|
2519
2533
|
if (parsed.type === "session:welcome") {
|
|
2520
2534
|
retryCountRef.current = 0;
|
|
2521
|
-
|
|
2535
|
+
updateConnectionRef.current((prev) => ({
|
|
2522
2536
|
...prev,
|
|
2523
2537
|
state: "connected",
|
|
2524
2538
|
connected: true,
|
|
@@ -2527,8 +2541,8 @@ function useRealtimeSession(options) {
|
|
|
2527
2541
|
lastConnectedAt: nowMs(),
|
|
2528
2542
|
lastError: null
|
|
2529
2543
|
}));
|
|
2530
|
-
|
|
2531
|
-
const handledByDraft =
|
|
2544
|
+
applyPeersRef.current(parsed.peers);
|
|
2545
|
+
const handledByDraft = resolveAuthoritativeDocumentRef.current(
|
|
2532
2546
|
sanitizeRealtimeSnapshot(parsed.document),
|
|
2533
2547
|
{
|
|
2534
2548
|
suppressSubscriberNotify: localDraftRef.current != null && sameSerializedItems(
|
|
@@ -2542,11 +2556,11 @@ function useRealtimeSession(options) {
|
|
|
2542
2556
|
outboundInFlightRef.current = null;
|
|
2543
2557
|
setHasPendingDocumentSync(false);
|
|
2544
2558
|
}
|
|
2545
|
-
|
|
2559
|
+
scheduleDocumentFlushRef.current();
|
|
2546
2560
|
return;
|
|
2547
2561
|
}
|
|
2548
2562
|
if (parsed.type === "presence:sync") {
|
|
2549
|
-
|
|
2563
|
+
applyPeersRef.current(parsed.peers);
|
|
2550
2564
|
return;
|
|
2551
2565
|
}
|
|
2552
2566
|
if (parsed.type === "session:peer-joined") {
|
|
@@ -2568,14 +2582,14 @@ function useRealtimeSession(options) {
|
|
|
2568
2582
|
return;
|
|
2569
2583
|
}
|
|
2570
2584
|
if (parsed.type === "session:pong") {
|
|
2571
|
-
|
|
2585
|
+
updateConnectionRef.current((prev) => ({
|
|
2572
2586
|
...prev,
|
|
2573
2587
|
lastPongAt: parsed.serverTime
|
|
2574
2588
|
}));
|
|
2575
2589
|
return;
|
|
2576
2590
|
}
|
|
2577
2591
|
if (parsed.type === "session:error") {
|
|
2578
|
-
|
|
2592
|
+
updateConnectionRef.current((prev) => ({
|
|
2579
2593
|
...prev,
|
|
2580
2594
|
state: prev.connected ? prev.state : "error",
|
|
2581
2595
|
lastError: parsed.message
|
|
@@ -2591,42 +2605,46 @@ function useRealtimeSession(options) {
|
|
|
2591
2605
|
outboundInFlightRef.current = null;
|
|
2592
2606
|
queuedItemsRef.current = localDraftRef.current?.items ?? null;
|
|
2593
2607
|
setHasPendingDocumentSync(queuedItemsRef.current != null);
|
|
2594
|
-
|
|
2608
|
+
resolveAuthoritativeDocumentRef.current(
|
|
2609
|
+
sanitizeRealtimeSnapshot(parsed.document)
|
|
2610
|
+
);
|
|
2595
2611
|
return;
|
|
2596
2612
|
}
|
|
2597
2613
|
const shouldSuppress = inFlight != null && sameSerializedItems(inFlight.items, parsed.document.items);
|
|
2598
2614
|
outboundInFlightRef.current = null;
|
|
2599
|
-
|
|
2615
|
+
applyDocumentRef.current(sanitizeRealtimeSnapshot(parsed.document), {
|
|
2600
2616
|
suppressSubscriberNotify: shouldSuppress
|
|
2601
2617
|
});
|
|
2602
2618
|
if (queuedItemsRef.current) {
|
|
2603
2619
|
if (sameSerializedItems(queuedItemsRef.current, parsed.document.items)) {
|
|
2604
2620
|
queuedItemsRef.current = null;
|
|
2605
2621
|
} else {
|
|
2606
|
-
|
|
2622
|
+
scheduleDocumentFlushRef.current();
|
|
2607
2623
|
}
|
|
2608
2624
|
}
|
|
2609
2625
|
if (!queuedItemsRef.current) {
|
|
2610
|
-
|
|
2626
|
+
clearLocalDraftRef.current();
|
|
2611
2627
|
}
|
|
2612
2628
|
setHasPendingDocumentSync(queuedItemsRef.current != null);
|
|
2613
|
-
|
|
2629
|
+
setConflictStateRef.current(null);
|
|
2614
2630
|
return;
|
|
2615
2631
|
}
|
|
2616
2632
|
if (parsed.type === "document:resync-required") {
|
|
2617
2633
|
outboundInFlightRef.current = null;
|
|
2618
2634
|
queuedItemsRef.current = localDraftRef.current?.items ?? null;
|
|
2619
2635
|
setHasPendingDocumentSync(queuedItemsRef.current != null);
|
|
2620
|
-
|
|
2636
|
+
updateConnectionRef.current((prev) => ({
|
|
2621
2637
|
...prev,
|
|
2622
2638
|
lastError: parsed.reason
|
|
2623
2639
|
}));
|
|
2624
|
-
|
|
2640
|
+
resolveAuthoritativeDocumentRef.current(
|
|
2641
|
+
sanitizeRealtimeSnapshot(parsed.document)
|
|
2642
|
+
);
|
|
2625
2643
|
}
|
|
2626
2644
|
});
|
|
2627
2645
|
socket.addEventListener("error", () => {
|
|
2628
2646
|
if (disposed) return;
|
|
2629
|
-
|
|
2647
|
+
updateConnectionRef.current((prev) => ({
|
|
2630
2648
|
...prev,
|
|
2631
2649
|
state: prev.connected ? prev.state : "error",
|
|
2632
2650
|
lastError: "Falha de conex\xE3o websocket."
|
|
@@ -2637,17 +2655,17 @@ function useRealtimeSession(options) {
|
|
|
2637
2655
|
clearHeartbeatTimer();
|
|
2638
2656
|
clearConnectTimeout();
|
|
2639
2657
|
wsRef.current = null;
|
|
2640
|
-
|
|
2658
|
+
collapsePeersToSelfRef.current(
|
|
2641
2659
|
manualDisconnectRef.current || !enabled ? "offline" : "reconnecting"
|
|
2642
2660
|
);
|
|
2643
|
-
|
|
2661
|
+
updateConnectionRef.current((prev) => ({
|
|
2644
2662
|
...prev,
|
|
2645
2663
|
connected: false,
|
|
2646
2664
|
clientId: prev.clientId,
|
|
2647
2665
|
state: manualDisconnectRef.current || !enabled ? "offline" : prev.state
|
|
2648
2666
|
}));
|
|
2649
2667
|
if (!manualDisconnectRef.current && enabled) {
|
|
2650
|
-
|
|
2668
|
+
scheduleReconnectRef.current();
|
|
2651
2669
|
}
|
|
2652
2670
|
});
|
|
2653
2671
|
return () => {
|
|
@@ -2659,14 +2677,10 @@ function useRealtimeSession(options) {
|
|
|
2659
2677
|
socket.close();
|
|
2660
2678
|
};
|
|
2661
2679
|
}, [
|
|
2662
|
-
applyDocument,
|
|
2663
|
-
applyPeers,
|
|
2664
2680
|
clearConnectTimeout,
|
|
2681
|
+
clearDocumentFlushSchedule,
|
|
2665
2682
|
clearHeartbeatTimer,
|
|
2666
|
-
clearLocalDraft,
|
|
2667
2683
|
clearReconnectTimer,
|
|
2668
|
-
collapsePeersToSelf,
|
|
2669
|
-
clearDocumentFlushSchedule,
|
|
2670
2684
|
connectSequence,
|
|
2671
2685
|
connectTimeoutMs,
|
|
2672
2686
|
enabled,
|
|
@@ -2675,13 +2689,7 @@ function useRealtimeSession(options) {
|
|
|
2675
2689
|
peer.displayName,
|
|
2676
2690
|
peer.id,
|
|
2677
2691
|
peer.image,
|
|
2678
|
-
resolveAuthoritativeDocument,
|
|
2679
2692
|
roomId,
|
|
2680
|
-
scheduleDocumentFlush,
|
|
2681
|
-
scheduleReconnect,
|
|
2682
|
-
sendRaw,
|
|
2683
|
-
setConflictState,
|
|
2684
|
-
updateConnection,
|
|
2685
2693
|
url
|
|
2686
2694
|
]);
|
|
2687
2695
|
useEffect(() => {
|