canvu-react 0.3.12 → 0.3.13

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 CHANGED
@@ -2074,6 +2074,10 @@ function useRealtimeSession(options) {
2074
2074
  }, []);
2075
2075
  const applyDocument = react.useCallback(
2076
2076
  (snapshot, options2) => {
2077
+ const currentSnapshot = latestDocumentRef.current;
2078
+ if (currentSnapshot && currentSnapshot.revision === snapshot.revision && currentSnapshot.updatedByClientId === snapshot.updatedByClientId && sameSerializedItems(currentSnapshot.items, snapshot.items)) {
2079
+ return;
2080
+ }
2077
2081
  currentRevisionRef.current = snapshot.revision;
2078
2082
  latestDocumentRef.current = snapshot;
2079
2083
  setDocument(snapshot);
@@ -2997,7 +3001,12 @@ function useRealtimeCanvasDocument(options) {
2997
3001
  } = options;
2998
3002
  const [loading, setLoading] = react.useState(false);
2999
3003
  const lastAppliedRevisionRef = react.useRef(null);
3004
+ const inFlightRevisionRef = react.useRef(null);
3000
3005
  const realtimeEnabled = enabled && session != null;
3006
+ const documentRevision = session?.document?.revision ?? null;
3007
+ const documentItems = session?.document?.items;
3008
+ const documentUpdatedByClientId = session?.document?.updatedByClientId ?? null;
3009
+ const connectionClientId = session?.connection.clientId ?? null;
3001
3010
  const applyIncomingItems = react.useCallback(
3002
3011
  async (nextItems) => {
3003
3012
  const normalizedItems = normalizeItems ? normalizeItems(nextItems) : [...nextItems];
@@ -3020,22 +3029,38 @@ function useRealtimeCanvasDocument(options) {
3020
3029
  );
3021
3030
  react.useEffect(() => {
3022
3031
  if (!realtimeEnabled || !onItemsChange || !session?.document) return;
3023
- if (session.document.updatedByClientId === session.connection.clientId) return;
3024
- if (lastAppliedRevisionRef.current === session.document.revision) return;
3032
+ if (documentUpdatedByClientId === connectionClientId) return;
3033
+ if (documentRevision == null) return;
3034
+ if (lastAppliedRevisionRef.current === documentRevision) return;
3035
+ if (inFlightRevisionRef.current === documentRevision) return;
3036
+ inFlightRevisionRef.current = documentRevision;
3025
3037
  let cancelled = false;
3026
3038
  setLoading(true);
3027
- void applyIncomingItems(session.document.items).then((resolvedItems) => {
3039
+ void applyIncomingItems(documentItems ?? []).then((resolvedItems) => {
3028
3040
  if (cancelled) return;
3029
- lastAppliedRevisionRef.current = session.document?.revision ?? null;
3041
+ if (inFlightRevisionRef.current !== documentRevision) return;
3042
+ lastAppliedRevisionRef.current = documentRevision;
3030
3043
  onItemsChange(resolvedItems);
3031
3044
  }).finally(() => {
3045
+ if (inFlightRevisionRef.current === documentRevision) {
3046
+ inFlightRevisionRef.current = null;
3047
+ }
3032
3048
  if (cancelled) return;
3033
3049
  setLoading(false);
3034
3050
  });
3035
3051
  return () => {
3036
3052
  cancelled = true;
3037
3053
  };
3038
- }, [applyIncomingItems, realtimeEnabled, onItemsChange, session]);
3054
+ }, [
3055
+ applyIncomingItems,
3056
+ connectionClientId,
3057
+ documentItems,
3058
+ documentRevision,
3059
+ documentUpdatedByClientId,
3060
+ onItemsChange,
3061
+ realtimeEnabled,
3062
+ session?.document
3063
+ ]);
3039
3064
  return react.useMemo(
3040
3065
  () => ({
3041
3066
  items,