@pluv/react 0.18.0 → 0.20.0

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/index.js CHANGED
@@ -38,25 +38,39 @@ module.exports = __toCommonJS(src_exports);
38
38
  var import_client2 = require("@pluv/client");
39
39
 
40
40
  // src/createBundle.tsx
41
- var import_react3 = require("react");
41
+ var import_react5 = require("react");
42
42
 
43
43
  // src/createRoomBundle.tsx
44
44
  var import_client = require("@pluv/client");
45
45
  var import_crdt = require("@pluv/crdt");
46
46
  var import_fast_deep_equal = __toESM(require("fast-deep-equal"));
47
- var import_react2 = require("react");
47
+ var import_react4 = require("react");
48
48
 
49
- // src/internal/hooks/useRerender.ts
49
+ // src/internal/hooks/useNoSsr.ts
50
50
  var import_react = require("react");
51
+ var useNoSsr = () => {
52
+ const [didMount, setDidMount] = (0, import_react.useState)(false);
53
+ (0, import_react.useEffect)(() => setDidMount(typeof window !== "undefined"), []);
54
+ const noSsr = (0, import_react.useCallback)(
55
+ (value, fallback = null) => {
56
+ return didMount ? typeof value !== "function" ? value : value() : fallback;
57
+ },
58
+ [didMount]
59
+ );
60
+ return noSsr;
61
+ };
62
+
63
+ // src/internal/hooks/useRerender.ts
64
+ var import_react2 = require("react");
51
65
  var useRerender = () => {
52
- const [, setCount] = (0, import_react.useState)(0);
53
- return (0, import_react.useCallback)(() => {
66
+ const [, setCount] = (0, import_react2.useState)(0);
67
+ return (0, import_react2.useCallback)(() => {
54
68
  setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
55
69
  }, []);
56
70
  };
57
71
 
58
72
  // src/internal/hooks/useSyncExternalStoreWithSelector.ts
59
- var import_with_selector = require("use-sync-external-store/with-selector.js");
73
+ var import_react3 = require("react");
60
74
 
61
75
  // src/internal/utils/identity.ts
62
76
  var identity = (x) => x;
@@ -66,16 +80,45 @@ var shallowArrayEqual = (a, b) => {
66
80
  return a.length === b.length && a.every((item, i) => item === b[i]);
67
81
  };
68
82
 
83
+ // src/internal/utils/shallowEqual.ts
84
+ var shallowEqual = (a, b) => a === b;
85
+
86
+ // src/internal/hooks/useSyncExternalStoreWithSelector.ts
87
+ var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
88
+ const noSsr = useNoSsr();
89
+ const cacheRef = (0, import_react3.useRef)(null);
90
+ const _getServerSnapshot = getServerSnapshot ? () => {
91
+ const data = getServerSnapshot();
92
+ const snapshot = selector(data);
93
+ const compare = isEqual != null ? isEqual : shallowEqual;
94
+ const cached = cacheRef.current;
95
+ const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
96
+ cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
97
+ return cacheRef.current;
98
+ } : void 0;
99
+ const _getClientSnapshot = () => {
100
+ const data = getClientSnapshot();
101
+ const snapshot = selector(data);
102
+ const compare = isEqual != null ? isEqual : shallowEqual;
103
+ const cached = cacheRef.current;
104
+ const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
105
+ cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
106
+ return cacheRef.current;
107
+ };
108
+ const result = (0, import_react3.useSyncExternalStore)(subscribe, _getClientSnapshot, _getServerSnapshot);
109
+ return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot == null ? void 0 : _getServerSnapshot()) : result;
110
+ };
111
+
69
112
  // src/createRoomBundle.tsx
70
113
  var import_jsx_runtime = require("react/jsx-runtime");
71
114
  var createRoomBundle = (client, options) => {
72
115
  var _a;
73
116
  const _initialStorage = (_a = options.initialStorage) != null ? _a : import_crdt.noop.doc();
74
- const PluvRoomContext = (0, import_react2.createContext)(null);
75
- const MockedRoomContext = (0, import_react2.createContext)({ room: null });
76
- const MockedRoomProvider = (0, import_react2.memo)((props) => {
117
+ const PluvRoomContext = (0, import_react4.createContext)(null);
118
+ const MockedRoomContext = (0, import_react4.createContext)({ room: null });
119
+ const MockedRoomProvider = (0, import_react4.memo)((props) => {
77
120
  const { children, events, initialPresence, initialStorage, room: _room } = props;
78
- const [room] = (0, import_react2.useState)(() => {
121
+ const [room] = (0, import_react4.useState)(() => {
79
122
  return new import_client.MockedRoom(_room, {
80
123
  events,
81
124
  initialPresence,
@@ -86,11 +129,11 @@ var createRoomBundle = (client, options) => {
86
129
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MockedRoomContext.Provider, { value: { room }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: room, children }) });
87
130
  });
88
131
  MockedRoomProvider.displayName = "MockedRoomProvider";
89
- const PluvRoomProvider = (0, import_react2.memo)((props) => {
132
+ const PluvRoomProvider = (0, import_react4.memo)((props) => {
90
133
  const { children, debug, initialPresence, initialStorage, onAuthorizationFail, room: _room } = props;
91
134
  const rerender = useRerender();
92
- const { room: mockedRoom } = (0, import_react2.useContext)(MockedRoomContext);
93
- const [room] = (0, import_react2.useState)(() => {
135
+ const { room: mockedRoom } = (0, import_react4.useContext)(MockedRoomContext);
136
+ const [room] = (0, import_react4.useState)(() => {
94
137
  return client.createRoom(_room, {
95
138
  addons: options.addons,
96
139
  debug,
@@ -100,7 +143,7 @@ var createRoomBundle = (client, options) => {
100
143
  onAuthorizationFail
101
144
  });
102
145
  });
103
- (0, import_react2.useEffect)(() => {
146
+ (0, import_react4.useEffect)(() => {
104
147
  const unsubscribe = room.subscribe("connection", () => {
105
148
  rerender();
106
149
  });
@@ -108,7 +151,7 @@ var createRoomBundle = (client, options) => {
108
151
  unsubscribe();
109
152
  };
110
153
  }, [rerender, room]);
111
- (0, import_react2.useEffect)(() => {
154
+ (0, import_react4.useEffect)(() => {
112
155
  client.enter(room);
113
156
  return () => {
114
157
  client.leave(room);
@@ -117,16 +160,16 @@ var createRoomBundle = (client, options) => {
117
160
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: mockedRoom != null ? mockedRoom : room, children });
118
161
  });
119
162
  PluvRoomProvider.displayName = "PluvRoomProvider";
120
- const useRoom = () => (0, import_react2.useContext)(PluvRoomContext);
163
+ const useRoom = () => (0, import_react4.useContext)(PluvRoomContext);
121
164
  const useBroadcast = () => {
122
165
  const room = useRoom();
123
- const broadcast = (0, import_react2.useCallback)(
166
+ const broadcast = (0, import_react4.useCallback)(
124
167
  (event2, data) => {
125
168
  room.broadcast(event2, data);
126
169
  },
127
170
  [room]
128
171
  );
129
- return (0, import_react2.useMemo)(() => {
172
+ return (0, import_react4.useMemo)(() => {
130
173
  return new Proxy(broadcast, {
131
174
  get(fn, prop) {
132
175
  return (data) => {
@@ -138,30 +181,30 @@ var createRoomBundle = (client, options) => {
138
181
  };
139
182
  const useCanRedo = () => {
140
183
  const room = useRoom();
141
- const subscribe = (0, import_react2.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
142
- const getSnapshot = (0, import_react2.useCallback)(() => room.canRedo(), [room]);
143
- const canRedo = (0, import_with_selector.useSyncExternalStoreWithSelector)(subscribe, getSnapshot, getSnapshot, identity);
184
+ const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
185
+ const getSnapshot = (0, import_react4.useCallback)(() => room.canRedo(), [room]);
186
+ const canRedo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
144
187
  return canRedo;
145
188
  };
146
189
  const useCanUndo = () => {
147
190
  const room = useRoom();
148
- const subscribe = (0, import_react2.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
149
- const getSnapshot = (0, import_react2.useCallback)(() => room.canUndo(), [room]);
150
- const canRedo = (0, import_with_selector.useSyncExternalStoreWithSelector)(subscribe, getSnapshot, getSnapshot, identity);
151
- return canRedo;
191
+ const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
192
+ const getSnapshot = (0, import_react4.useCallback)(() => room.canUndo(), [room]);
193
+ const canUndo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
194
+ return canUndo;
152
195
  };
153
196
  const useConnection = (selector = identity, options2) => {
154
197
  var _a2;
155
198
  const room = useRoom();
156
- const subscribe = (0, import_react2.useCallback)(
199
+ const subscribe = (0, import_react4.useCallback)(
157
200
  (onStoreChange) => {
158
201
  return room.subscribe("connection", onStoreChange);
159
202
  },
160
203
  [room]
161
204
  );
162
205
  const getSnapshot = room.getConnection;
163
- const _selector = (0, import_react2.useCallback)((snapshot) => selector(snapshot), [selector]);
164
- return (0, import_with_selector.useSyncExternalStoreWithSelector)(
206
+ const _selector = (0, import_react4.useCallback)((snapshot) => selector(snapshot), [selector]);
207
+ return useSyncExternalStoreWithSelector(
165
208
  subscribe,
166
209
  getSnapshot,
167
210
  getSnapshot,
@@ -175,7 +218,7 @@ var createRoomBundle = (client, options) => {
175
218
  };
176
219
  const useEvent = (type, callback) => {
177
220
  const room = useRoom();
178
- (0, import_react2.useEffect)(() => {
221
+ (0, import_react4.useEffect)(() => {
179
222
  const unsubscribe = room.event(type, callback);
180
223
  return () => {
181
224
  unsubscribe();
@@ -196,47 +239,40 @@ var createRoomBundle = (client, options) => {
196
239
  const useMyPresence = (selector = identity, options2) => {
197
240
  var _a2;
198
241
  const room = useRoom();
199
- const subscribe = (0, import_react2.useCallback)(
242
+ const subscribe = (0, import_react4.useCallback)(
200
243
  (onStoreChange) => {
201
244
  return room.subscribe("my-presence", onStoreChange);
202
245
  },
203
246
  [room]
204
247
  );
205
248
  const getSnapshot = room.getMyPresence;
206
- const _selector = (0, import_react2.useCallback)((snapshot) => selector(snapshot), [selector]);
207
- const myPresence = (0, import_with_selector.useSyncExternalStoreWithSelector)(
249
+ const _selector = (0, import_react4.useCallback)((snapshot) => selector(snapshot), [selector]);
250
+ const myPresence = useSyncExternalStoreWithSelector(
208
251
  subscribe,
209
252
  getSnapshot,
210
253
  getSnapshot,
211
254
  _selector,
212
255
  (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : import_fast_deep_equal.default
213
256
  );
214
- const updateMyPresence = (0, import_react2.useCallback)(
215
- (value) => {
216
- const presence = typeof value === "function" ? value(room.getMyPresence()) : value;
217
- room.updateMyPresence(presence);
218
- },
219
- [room]
220
- );
221
- return [myPresence, updateMyPresence];
257
+ return [myPresence, room.updateMyPresence];
222
258
  };
223
259
  const useMyself = (selector = identity, options2) => {
224
260
  var _a2;
225
261
  const room = useRoom();
226
- const subscribe = (0, import_react2.useCallback)(
262
+ const subscribe = (0, import_react4.useCallback)(
227
263
  (onStoreChange) => {
228
264
  return room.subscribe("myself", onStoreChange);
229
265
  },
230
266
  [room]
231
267
  );
232
268
  const getSnapshot = room.getMyself;
233
- const _selector = (0, import_react2.useCallback)(
269
+ const _selector = (0, import_react4.useCallback)(
234
270
  (snapshot) => {
235
271
  return !snapshot ? null : selector(snapshot);
236
272
  },
237
273
  [selector]
238
274
  );
239
- return (0, import_with_selector.useSyncExternalStoreWithSelector)(
275
+ return useSyncExternalStoreWithSelector(
240
276
  subscribe,
241
277
  getSnapshot,
242
278
  getSnapshot,
@@ -247,20 +283,20 @@ var createRoomBundle = (client, options) => {
247
283
  const useOther = (connectionId, selector = identity, options2) => {
248
284
  var _a2;
249
285
  const room = useRoom();
250
- const subscribe = (0, import_react2.useCallback)(
286
+ const subscribe = (0, import_react4.useCallback)(
251
287
  (onStoreChange) => {
252
288
  return room.other(connectionId, onStoreChange);
253
289
  },
254
290
  [room, connectionId]
255
291
  );
256
- const getSnapshot = (0, import_react2.useCallback)(() => room.getOther(connectionId), [room, connectionId]);
257
- const _selector = (0, import_react2.useCallback)(
292
+ const getSnapshot = (0, import_react4.useCallback)(() => room.getOther(connectionId), [room, connectionId]);
293
+ const _selector = (0, import_react4.useCallback)(
258
294
  (snapshot) => {
259
295
  return !snapshot ? null : selector(snapshot);
260
296
  },
261
297
  [selector]
262
298
  );
263
- return (0, import_with_selector.useSyncExternalStoreWithSelector)(
299
+ return useSyncExternalStoreWithSelector(
264
300
  subscribe,
265
301
  getSnapshot,
266
302
  getSnapshot,
@@ -271,19 +307,24 @@ var createRoomBundle = (client, options) => {
271
307
  const useOthers = (selector = identity, options2) => {
272
308
  var _a2;
273
309
  const room = useRoom();
274
- const subscribe = (0, import_react2.useCallback)(
310
+ const subscribe = (0, import_react4.useCallback)(
275
311
  (onStoreChange) => {
276
312
  return room.subscribe("others", onStoreChange);
277
313
  },
278
314
  [room]
279
315
  );
280
316
  const getSnapshot = room.getOthers;
281
- return (0, import_with_selector.useSyncExternalStoreWithSelector)(
317
+ return useSyncExternalStoreWithSelector(
282
318
  subscribe,
283
319
  getSnapshot,
284
320
  getSnapshot,
285
321
  selector,
286
- (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : shallowArrayEqual
322
+ (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : (a, b) => {
323
+ if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
324
+ return shallowArrayEqual(a, b);
325
+ }
326
+ return (0, import_fast_deep_equal.default)(a, b);
327
+ }
287
328
  );
288
329
  };
289
330
  const useRedo = () => {
@@ -297,18 +338,17 @@ var createRoomBundle = (client, options) => {
297
338
  room.subscribe("storage-loaded", () => {
298
339
  rerender();
299
340
  });
300
- const subscribe = (0, import_react2.useCallback)((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
301
- const getSnapshot = (0, import_react2.useCallback)(() => {
302
- var _a3;
303
- return (_a3 = room.getStorage(key)) == null ? void 0 : _a3.toJson();
341
+ const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
342
+ const getSnapshot = (0, import_react4.useCallback)(() => {
343
+ return room.getStorageJson(key);
304
344
  }, [key, room]);
305
- const _selector = (0, import_react2.useCallback)(
345
+ const _selector = (0, import_react4.useCallback)(
306
346
  (snapshot) => {
307
347
  return snapshot === null ? null : selector(snapshot);
308
348
  },
309
349
  [selector]
310
350
  );
311
- const data = (0, import_with_selector.useSyncExternalStoreWithSelector)(
351
+ const data = useSyncExternalStoreWithSelector(
312
352
  subscribe,
313
353
  getSnapshot,
314
354
  getSnapshot,
@@ -354,13 +394,13 @@ var createRoomBundle = (client, options) => {
354
394
  // src/createBundle.tsx
355
395
  var import_jsx_runtime2 = require("react/jsx-runtime");
356
396
  var createBundle = (client) => {
357
- const PluvContext = (0, import_react3.createContext)(null);
358
- const PluvProvider = (0, import_react3.memo)((props) => {
397
+ const PluvContext = (0, import_react5.createContext)(null);
398
+ const PluvProvider = (0, import_react5.memo)((props) => {
359
399
  const { children } = props;
360
400
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PluvContext.Provider, { value: client, children });
361
401
  });
362
402
  PluvProvider.displayName = "PluvProvider";
363
- const useClient = () => (0, import_react3.useContext)(PluvContext);
403
+ const useClient = () => (0, import_react5.useContext)(PluvContext);
364
404
  const createRoomBundle2 = (options) => createRoomBundle(client, options);
365
405
  return {
366
406
  createRoomBundle: createRoomBundle2,
package/dist/index.mjs CHANGED
@@ -8,19 +8,33 @@ import { createContext as createContext2, memo as memo2, useContext as useContex
8
8
  import { MockedRoom } from "@pluv/client";
9
9
  import { noop } from "@pluv/crdt";
10
10
  import fastDeepEqual from "fast-deep-equal";
11
- import { createContext, memo, useCallback as useCallback2, useContext, useEffect, useMemo, useState as useState2 } from "react";
11
+ import { createContext, memo, useCallback as useCallback3, useContext, useEffect as useEffect2, useMemo, useState as useState3 } from "react";
12
+
13
+ // src/internal/hooks/useNoSsr.ts
14
+ import { useCallback, useEffect, useState } from "react";
15
+ var useNoSsr = () => {
16
+ const [didMount, setDidMount] = useState(false);
17
+ useEffect(() => setDidMount(typeof window !== "undefined"), []);
18
+ const noSsr = useCallback(
19
+ (value, fallback = null) => {
20
+ return didMount ? typeof value !== "function" ? value : value() : fallback;
21
+ },
22
+ [didMount]
23
+ );
24
+ return noSsr;
25
+ };
12
26
 
13
27
  // src/internal/hooks/useRerender.ts
14
- import { useCallback, useState } from "react";
28
+ import { useCallback as useCallback2, useState as useState2 } from "react";
15
29
  var useRerender = () => {
16
- const [, setCount] = useState(0);
17
- return useCallback(() => {
30
+ const [, setCount] = useState2(0);
31
+ return useCallback2(() => {
18
32
  setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
19
33
  }, []);
20
34
  };
21
35
 
22
36
  // src/internal/hooks/useSyncExternalStoreWithSelector.ts
23
- import { useSyncExternalStoreWithSelector } from "use-sync-external-store/with-selector.js";
37
+ import { useRef, useSyncExternalStore } from "react";
24
38
 
25
39
  // src/internal/utils/identity.ts
26
40
  var identity = (x) => x;
@@ -30,6 +44,35 @@ var shallowArrayEqual = (a, b) => {
30
44
  return a.length === b.length && a.every((item, i) => item === b[i]);
31
45
  };
32
46
 
47
+ // src/internal/utils/shallowEqual.ts
48
+ var shallowEqual = (a, b) => a === b;
49
+
50
+ // src/internal/hooks/useSyncExternalStoreWithSelector.ts
51
+ var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
52
+ const noSsr = useNoSsr();
53
+ const cacheRef = useRef(null);
54
+ const _getServerSnapshot = getServerSnapshot ? () => {
55
+ const data = getServerSnapshot();
56
+ const snapshot = selector(data);
57
+ const compare = isEqual != null ? isEqual : shallowEqual;
58
+ const cached = cacheRef.current;
59
+ const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
60
+ cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
61
+ return cacheRef.current;
62
+ } : void 0;
63
+ const _getClientSnapshot = () => {
64
+ const data = getClientSnapshot();
65
+ const snapshot = selector(data);
66
+ const compare = isEqual != null ? isEqual : shallowEqual;
67
+ const cached = cacheRef.current;
68
+ const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
69
+ cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
70
+ return cacheRef.current;
71
+ };
72
+ const result = useSyncExternalStore(subscribe, _getClientSnapshot, _getServerSnapshot);
73
+ return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot == null ? void 0 : _getServerSnapshot()) : result;
74
+ };
75
+
33
76
  // src/createRoomBundle.tsx
34
77
  import { jsx } from "react/jsx-runtime";
35
78
  var createRoomBundle = (client, options) => {
@@ -39,7 +82,7 @@ var createRoomBundle = (client, options) => {
39
82
  const MockedRoomContext = createContext({ room: null });
40
83
  const MockedRoomProvider = memo((props) => {
41
84
  const { children, events, initialPresence, initialStorage, room: _room } = props;
42
- const [room] = useState2(() => {
85
+ const [room] = useState3(() => {
43
86
  return new MockedRoom(_room, {
44
87
  events,
45
88
  initialPresence,
@@ -54,7 +97,7 @@ var createRoomBundle = (client, options) => {
54
97
  const { children, debug, initialPresence, initialStorage, onAuthorizationFail, room: _room } = props;
55
98
  const rerender = useRerender();
56
99
  const { room: mockedRoom } = useContext(MockedRoomContext);
57
- const [room] = useState2(() => {
100
+ const [room] = useState3(() => {
58
101
  return client.createRoom(_room, {
59
102
  addons: options.addons,
60
103
  debug,
@@ -64,7 +107,7 @@ var createRoomBundle = (client, options) => {
64
107
  onAuthorizationFail
65
108
  });
66
109
  });
67
- useEffect(() => {
110
+ useEffect2(() => {
68
111
  const unsubscribe = room.subscribe("connection", () => {
69
112
  rerender();
70
113
  });
@@ -72,7 +115,7 @@ var createRoomBundle = (client, options) => {
72
115
  unsubscribe();
73
116
  };
74
117
  }, [rerender, room]);
75
- useEffect(() => {
118
+ useEffect2(() => {
76
119
  client.enter(room);
77
120
  return () => {
78
121
  client.leave(room);
@@ -84,7 +127,7 @@ var createRoomBundle = (client, options) => {
84
127
  const useRoom = () => useContext(PluvRoomContext);
85
128
  const useBroadcast = () => {
86
129
  const room = useRoom();
87
- const broadcast = useCallback2(
130
+ const broadcast = useCallback3(
88
131
  (event2, data) => {
89
132
  room.broadcast(event2, data);
90
133
  },
@@ -102,29 +145,29 @@ var createRoomBundle = (client, options) => {
102
145
  };
103
146
  const useCanRedo = () => {
104
147
  const room = useRoom();
105
- const subscribe = useCallback2((onStoreChange) => room.storageRoot(onStoreChange), [room]);
106
- const getSnapshot = useCallback2(() => room.canRedo(), [room]);
148
+ const subscribe = useCallback3((onStoreChange) => room.storageRoot(onStoreChange), [room]);
149
+ const getSnapshot = useCallback3(() => room.canRedo(), [room]);
107
150
  const canRedo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
108
151
  return canRedo;
109
152
  };
110
153
  const useCanUndo = () => {
111
154
  const room = useRoom();
112
- const subscribe = useCallback2((onStoreChange) => room.storageRoot(onStoreChange), [room]);
113
- const getSnapshot = useCallback2(() => room.canUndo(), [room]);
114
- const canRedo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
115
- return canRedo;
155
+ const subscribe = useCallback3((onStoreChange) => room.storageRoot(onStoreChange), [room]);
156
+ const getSnapshot = useCallback3(() => room.canUndo(), [room]);
157
+ const canUndo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
158
+ return canUndo;
116
159
  };
117
160
  const useConnection = (selector = identity, options2) => {
118
161
  var _a2;
119
162
  const room = useRoom();
120
- const subscribe = useCallback2(
163
+ const subscribe = useCallback3(
121
164
  (onStoreChange) => {
122
165
  return room.subscribe("connection", onStoreChange);
123
166
  },
124
167
  [room]
125
168
  );
126
169
  const getSnapshot = room.getConnection;
127
- const _selector = useCallback2((snapshot) => selector(snapshot), [selector]);
170
+ const _selector = useCallback3((snapshot) => selector(snapshot), [selector]);
128
171
  return useSyncExternalStoreWithSelector(
129
172
  subscribe,
130
173
  getSnapshot,
@@ -139,7 +182,7 @@ var createRoomBundle = (client, options) => {
139
182
  };
140
183
  const useEvent = (type, callback) => {
141
184
  const room = useRoom();
142
- useEffect(() => {
185
+ useEffect2(() => {
143
186
  const unsubscribe = room.event(type, callback);
144
187
  return () => {
145
188
  unsubscribe();
@@ -160,14 +203,14 @@ var createRoomBundle = (client, options) => {
160
203
  const useMyPresence = (selector = identity, options2) => {
161
204
  var _a2;
162
205
  const room = useRoom();
163
- const subscribe = useCallback2(
206
+ const subscribe = useCallback3(
164
207
  (onStoreChange) => {
165
208
  return room.subscribe("my-presence", onStoreChange);
166
209
  },
167
210
  [room]
168
211
  );
169
212
  const getSnapshot = room.getMyPresence;
170
- const _selector = useCallback2((snapshot) => selector(snapshot), [selector]);
213
+ const _selector = useCallback3((snapshot) => selector(snapshot), [selector]);
171
214
  const myPresence = useSyncExternalStoreWithSelector(
172
215
  subscribe,
173
216
  getSnapshot,
@@ -175,26 +218,19 @@ var createRoomBundle = (client, options) => {
175
218
  _selector,
176
219
  (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : fastDeepEqual
177
220
  );
178
- const updateMyPresence = useCallback2(
179
- (value) => {
180
- const presence = typeof value === "function" ? value(room.getMyPresence()) : value;
181
- room.updateMyPresence(presence);
182
- },
183
- [room]
184
- );
185
- return [myPresence, updateMyPresence];
221
+ return [myPresence, room.updateMyPresence];
186
222
  };
187
223
  const useMyself = (selector = identity, options2) => {
188
224
  var _a2;
189
225
  const room = useRoom();
190
- const subscribe = useCallback2(
226
+ const subscribe = useCallback3(
191
227
  (onStoreChange) => {
192
228
  return room.subscribe("myself", onStoreChange);
193
229
  },
194
230
  [room]
195
231
  );
196
232
  const getSnapshot = room.getMyself;
197
- const _selector = useCallback2(
233
+ const _selector = useCallback3(
198
234
  (snapshot) => {
199
235
  return !snapshot ? null : selector(snapshot);
200
236
  },
@@ -211,14 +247,14 @@ var createRoomBundle = (client, options) => {
211
247
  const useOther = (connectionId, selector = identity, options2) => {
212
248
  var _a2;
213
249
  const room = useRoom();
214
- const subscribe = useCallback2(
250
+ const subscribe = useCallback3(
215
251
  (onStoreChange) => {
216
252
  return room.other(connectionId, onStoreChange);
217
253
  },
218
254
  [room, connectionId]
219
255
  );
220
- const getSnapshot = useCallback2(() => room.getOther(connectionId), [room, connectionId]);
221
- const _selector = useCallback2(
256
+ const getSnapshot = useCallback3(() => room.getOther(connectionId), [room, connectionId]);
257
+ const _selector = useCallback3(
222
258
  (snapshot) => {
223
259
  return !snapshot ? null : selector(snapshot);
224
260
  },
@@ -235,7 +271,7 @@ var createRoomBundle = (client, options) => {
235
271
  const useOthers = (selector = identity, options2) => {
236
272
  var _a2;
237
273
  const room = useRoom();
238
- const subscribe = useCallback2(
274
+ const subscribe = useCallback3(
239
275
  (onStoreChange) => {
240
276
  return room.subscribe("others", onStoreChange);
241
277
  },
@@ -247,7 +283,12 @@ var createRoomBundle = (client, options) => {
247
283
  getSnapshot,
248
284
  getSnapshot,
249
285
  selector,
250
- (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : shallowArrayEqual
286
+ (_a2 = options2 == null ? void 0 : options2.isEqual) != null ? _a2 : (a, b) => {
287
+ if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
288
+ return shallowArrayEqual(a, b);
289
+ }
290
+ return fastDeepEqual(a, b);
291
+ }
251
292
  );
252
293
  };
253
294
  const useRedo = () => {
@@ -261,12 +302,11 @@ var createRoomBundle = (client, options) => {
261
302
  room.subscribe("storage-loaded", () => {
262
303
  rerender();
263
304
  });
264
- const subscribe = useCallback2((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
265
- const getSnapshot = useCallback2(() => {
266
- var _a3;
267
- return (_a3 = room.getStorage(key)) == null ? void 0 : _a3.toJson();
305
+ const subscribe = useCallback3((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
306
+ const getSnapshot = useCallback3(() => {
307
+ return room.getStorageJson(key);
268
308
  }, [key, room]);
269
- const _selector = useCallback2(
309
+ const _selector = useCallback3(
270
310
  (snapshot) => {
271
311
  return snapshot === null ? null : selector(snapshot);
272
312
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/react",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "@pluv/client React.js bindings",
5
5
  "author": "leedavidcs",
6
6
  "license": "MIT",
@@ -17,24 +17,23 @@
17
17
  "access": "public"
18
18
  },
19
19
  "dependencies": {
20
- "@types/react": "^18.3.3",
21
- "@types/use-sync-external-store": "^0.0.6",
22
20
  "fast-deep-equal": "^3.1.3",
23
- "use-sync-external-store": "^1.2.2",
24
- "@pluv/client": "^0.18.0",
25
- "@pluv/crdt": "^0.18.0",
26
- "@pluv/types": "^0.18.0"
21
+ "@pluv/client": "^0.20.0",
22
+ "@pluv/crdt": "^0.20.0",
23
+ "@pluv/types": "^0.20.0"
27
24
  },
28
25
  "peerDependencies": {
29
- "react": "^17.0.0 || ^18.0.0"
26
+ "@types/react": "^18.0.0",
27
+ "react": "^18.0.0"
30
28
  },
31
29
  "devDependencies": {
30
+ "@types/react": "^18.3.3",
32
31
  "eslint": "^8.57.0",
33
32
  "react": "^18.3.1",
34
- "tsup": "^8.0.2",
33
+ "tsup": "^8.1.0",
35
34
  "typescript": "^5.4.5",
36
- "@pluv/tsconfig": "^0.18.0",
37
- "eslint-config-pluv": "^0.18.0"
35
+ "@pluv/tsconfig": "^0.20.0",
36
+ "eslint-config-pluv": "^0.20.0"
38
37
  },
39
38
  "scripts": {
40
39
  "build": "tsup src/index.ts --format esm,cjs --dts --external react",