canvu-react 0.4.56 → 0.4.58
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/native.cjs +74 -31
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +75 -32
- package/dist/native.js.map +1 -1
- package/dist/realtimeNative.cjs +46 -2
- package/dist/realtimeNative.cjs.map +1 -1
- package/dist/realtimeNative.js +46 -2
- package/dist/realtimeNative.js.map +1 -1
- package/package.json +1 -1
package/dist/realtimeNative.js
CHANGED
|
@@ -823,6 +823,7 @@ var DRAFT_STORAGE_PREFIX = "canvu-realtime-draft:";
|
|
|
823
823
|
var DOCUMENT_FLUSH_DEBOUNCE_MS = 120;
|
|
824
824
|
var DRAFT_PERSIST_DEBOUNCE_MS = 420;
|
|
825
825
|
var CONNECTION_MESSAGE_STATE_UPDATE_INTERVAL_MS = 1e3;
|
|
826
|
+
var PRESENCE_UPDATE_THROTTLE_MS = 80;
|
|
826
827
|
function requestRuntimeIdleCallback(callback, timeout) {
|
|
827
828
|
const runtime = globalThis;
|
|
828
829
|
if (typeof runtime.requestIdleCallback === "function") {
|
|
@@ -958,6 +959,10 @@ function nowMs() {
|
|
|
958
959
|
function shouldUpdateRealtimeConnectionMessageState(input) {
|
|
959
960
|
return input.lastStateUpdateAt == null || input.receivedAt - input.lastStateUpdateAt >= CONNECTION_MESSAGE_STATE_UPDATE_INTERVAL_MS;
|
|
960
961
|
}
|
|
962
|
+
function shouldSendRealtimePresenceUpdate(input) {
|
|
963
|
+
const minIntervalMs = input.minIntervalMs ?? PRESENCE_UPDATE_THROTTLE_MS;
|
|
964
|
+
return input.lastPresenceSentAt == null || input.requestedAt - input.lastPresenceSentAt >= minIntervalMs;
|
|
965
|
+
}
|
|
961
966
|
function hasDurableDocumentPersistence(snapshot) {
|
|
962
967
|
return snapshot.persistedRevision == null || snapshot.persistedRevision >= snapshot.revision;
|
|
963
968
|
}
|
|
@@ -1098,6 +1103,7 @@ function useRealtimeSession(options) {
|
|
|
1098
1103
|
const documentFlushIdleRef = useRef(null);
|
|
1099
1104
|
const draftPersistTimerRef = useRef(null);
|
|
1100
1105
|
const draftPersistIdleRef = useRef(null);
|
|
1106
|
+
const presenceUpdateTimerRef = useRef(null);
|
|
1101
1107
|
const draftStorageRef = useRef(draftStorage);
|
|
1102
1108
|
draftStorageRef.current = draftStorage;
|
|
1103
1109
|
const manualDisconnectRef = useRef(false);
|
|
@@ -1122,6 +1128,7 @@ function useRealtimeSession(options) {
|
|
|
1122
1128
|
enabled ? "connecting" : "offline"
|
|
1123
1129
|
);
|
|
1124
1130
|
const lastConnectionMessageStateUpdateAtRef = useRef(null);
|
|
1131
|
+
const lastPresenceSentAtRef = useRef(null);
|
|
1125
1132
|
const localDraftRef = useRef(null);
|
|
1126
1133
|
const conflictRef = useRef(null);
|
|
1127
1134
|
const onErrorRef = useRef(onError);
|
|
@@ -1186,6 +1193,12 @@ function useRealtimeSession(options) {
|
|
|
1186
1193
|
cancelRuntimeIdleCallback(draftPersistIdleRef.current);
|
|
1187
1194
|
draftPersistIdleRef.current = null;
|
|
1188
1195
|
}, []);
|
|
1196
|
+
const clearPresenceUpdateSchedule = useCallback(() => {
|
|
1197
|
+
if (presenceUpdateTimerRef.current != null) {
|
|
1198
|
+
globalThis.clearTimeout(presenceUpdateTimerRef.current);
|
|
1199
|
+
presenceUpdateTimerRef.current = null;
|
|
1200
|
+
}
|
|
1201
|
+
}, []);
|
|
1189
1202
|
const updateConnection = useCallback(
|
|
1190
1203
|
(patch) => {
|
|
1191
1204
|
setConnection((prev) => {
|
|
@@ -1544,7 +1557,8 @@ function useRealtimeSession(options) {
|
|
|
1544
1557
|
},
|
|
1545
1558
|
[applyDocument, roomId, scheduleDocumentFlush, setLocalDraft]
|
|
1546
1559
|
);
|
|
1547
|
-
const
|
|
1560
|
+
const sendPresenceUpdateNow = useCallback(() => {
|
|
1561
|
+
lastPresenceSentAtRef.current = nowMs();
|
|
1548
1562
|
sendRaw({
|
|
1549
1563
|
type: "presence:update",
|
|
1550
1564
|
roomId,
|
|
@@ -1557,6 +1571,24 @@ function useRealtimeSession(options) {
|
|
|
1557
1571
|
}
|
|
1558
1572
|
});
|
|
1559
1573
|
}, [roomId, sendRaw]);
|
|
1574
|
+
const sendPresenceUpdate = useCallback(() => {
|
|
1575
|
+
const requestedAt = nowMs();
|
|
1576
|
+
if (shouldSendRealtimePresenceUpdate({
|
|
1577
|
+
lastPresenceSentAt: lastPresenceSentAtRef.current,
|
|
1578
|
+
requestedAt
|
|
1579
|
+
})) {
|
|
1580
|
+
clearPresenceUpdateSchedule();
|
|
1581
|
+
sendPresenceUpdateNow();
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
if (presenceUpdateTimerRef.current != null) return;
|
|
1585
|
+
const elapsedMs = requestedAt - (lastPresenceSentAtRef.current ?? requestedAt);
|
|
1586
|
+
const delayMs = Math.max(0, PRESENCE_UPDATE_THROTTLE_MS - elapsedMs);
|
|
1587
|
+
presenceUpdateTimerRef.current = globalThis.setTimeout(() => {
|
|
1588
|
+
presenceUpdateTimerRef.current = null;
|
|
1589
|
+
sendPresenceUpdateNow();
|
|
1590
|
+
}, delayMs);
|
|
1591
|
+
}, [clearPresenceUpdateSchedule, sendPresenceUpdateNow]);
|
|
1560
1592
|
const scheduleReconnect = useCallback(() => {
|
|
1561
1593
|
if (!reconnect || manualDisconnectRef.current) return;
|
|
1562
1594
|
clearReconnectTimer();
|
|
@@ -1638,6 +1670,7 @@ function useRealtimeSession(options) {
|
|
|
1638
1670
|
if (!roomId) {
|
|
1639
1671
|
clearDocumentFlushSchedule();
|
|
1640
1672
|
clearDraftPersistSchedule();
|
|
1673
|
+
clearPresenceUpdateSchedule();
|
|
1641
1674
|
localDraftRef.current = null;
|
|
1642
1675
|
setHasLocalOfflineDraft(false);
|
|
1643
1676
|
setHasPendingDocumentSync(false);
|
|
@@ -1680,6 +1713,7 @@ function useRealtimeSession(options) {
|
|
|
1680
1713
|
applyDraftSnapshot,
|
|
1681
1714
|
clearDocumentFlushSchedule,
|
|
1682
1715
|
clearDraftPersistSchedule,
|
|
1716
|
+
clearPresenceUpdateSchedule,
|
|
1683
1717
|
roomId,
|
|
1684
1718
|
setConflictState,
|
|
1685
1719
|
setLocalDraft
|
|
@@ -1692,6 +1726,7 @@ function useRealtimeSession(options) {
|
|
|
1692
1726
|
clearHeartbeatTimer();
|
|
1693
1727
|
clearConnectTimeout();
|
|
1694
1728
|
clearDocumentFlushSchedule();
|
|
1729
|
+
clearPresenceUpdateSchedule();
|
|
1695
1730
|
wsRef.current?.close();
|
|
1696
1731
|
wsRef.current = null;
|
|
1697
1732
|
queuedDirtyRef.current = localDraftRef.current != null;
|
|
@@ -1975,12 +2010,14 @@ function useRealtimeSession(options) {
|
|
|
1975
2010
|
clearHeartbeatTimer();
|
|
1976
2011
|
clearConnectTimeout();
|
|
1977
2012
|
clearDocumentFlushSchedule();
|
|
2013
|
+
clearPresenceUpdateSchedule();
|
|
1978
2014
|
socket.close();
|
|
1979
2015
|
};
|
|
1980
2016
|
}, [
|
|
1981
2017
|
clearConnectTimeout,
|
|
1982
2018
|
clearDocumentFlushSchedule,
|
|
1983
2019
|
clearHeartbeatTimer,
|
|
2020
|
+
clearPresenceUpdateSchedule,
|
|
1984
2021
|
clearReconnectTimer,
|
|
1985
2022
|
connectSequence,
|
|
1986
2023
|
connectTimeoutMs,
|
|
@@ -2008,12 +2045,17 @@ function useRealtimeSession(options) {
|
|
|
2008
2045
|
() => () => {
|
|
2009
2046
|
clearDocumentFlushSchedule();
|
|
2010
2047
|
clearDraftPersistSchedule();
|
|
2048
|
+
clearPresenceUpdateSchedule();
|
|
2011
2049
|
if (boardRef.current) {
|
|
2012
2050
|
boardRef.current.doc.destroy();
|
|
2013
2051
|
boardRef.current = null;
|
|
2014
2052
|
}
|
|
2015
2053
|
},
|
|
2016
|
-
[
|
|
2054
|
+
[
|
|
2055
|
+
clearDocumentFlushSchedule,
|
|
2056
|
+
clearDraftPersistSchedule,
|
|
2057
|
+
clearPresenceUpdateSchedule
|
|
2058
|
+
]
|
|
2017
2059
|
);
|
|
2018
2060
|
const flushDocumentSync = useCallback(async () => {
|
|
2019
2061
|
const board = boardRef.current;
|
|
@@ -2065,6 +2107,7 @@ function useRealtimeSession(options) {
|
|
|
2065
2107
|
clearReconnectTimer();
|
|
2066
2108
|
clearHeartbeatTimer();
|
|
2067
2109
|
clearConnectTimeout();
|
|
2110
|
+
clearPresenceUpdateSchedule();
|
|
2068
2111
|
sendRaw({
|
|
2069
2112
|
type: "session:leave",
|
|
2070
2113
|
roomId,
|
|
@@ -2081,6 +2124,7 @@ function useRealtimeSession(options) {
|
|
|
2081
2124
|
}, [
|
|
2082
2125
|
clearConnectTimeout,
|
|
2083
2126
|
clearHeartbeatTimer,
|
|
2127
|
+
clearPresenceUpdateSchedule,
|
|
2084
2128
|
clearReconnectTimer,
|
|
2085
2129
|
collapsePeersToSelf,
|
|
2086
2130
|
roomId,
|