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