@pluv/react 0.38.13 → 0.39.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @pluv/react@0.38.13 build /home/runner/work/pluv/pluv/packages/react
2
+ > @pluv/react@0.39.0 build /home/runner/work/pluv/pluv/packages/react
3
3
  > tsup src/index.ts --format esm,cjs --dts --external react
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,11 +8,11 @@
8
8
  CLI Target: es6
9
9
  ESM Build start
10
10
  CJS Build start
11
- ESM dist/index.mjs 11.51 KB
12
- ESM ⚡️ Build success in 117ms
13
- CJS dist/index.js 13.89 KB
14
- CJS ⚡️ Build success in 118ms
11
+ ESM dist/index.mjs 16.35 KB
12
+ ESM ⚡️ Build success in 140ms
13
+ CJS dist/index.js 18.73 KB
14
+ CJS ⚡️ Build success in 134ms
15
15
  DTS Build start
16
- DTS ⚡️ Build success in 5523ms
17
- DTS dist/index.d.mts 5.39 KB
18
- DTS dist/index.d.ts 5.39 KB
16
+ DTS ⚡️ Build success in 5767ms
17
+ DTS dist/index.d.mts 5.54 KB
18
+ DTS dist/index.d.ts 5.54 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # @pluv/react
2
2
 
3
+ ## 0.39.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ca160f5: **BREAKING** Update the context value of `MockedRoomContext` to mirror the same shape as `PluvRoomContext`. i.e. the value of `MockedRoomContext` is now the room itself, rather than an object containing the room. This should not be breaking in most cases. If you happen to be using `useContext(MockedRoomContext)`, those will need to be updated as shown below:
8
+
9
+ ```tsx
10
+ // Before
11
+ const { room } = useContext(MockedRoomContext);
12
+
13
+ // After
14
+ const room = useContext(MockedRoomContext);
15
+ ```
16
+
17
+ ### Patch Changes
18
+
19
+ - e6ddddc: Fixed potential race conditions between connecting and disconnecting between re-renders of `PluvRoomProvider`.
20
+ - e6ddddc: (Internal) Update how `PluvRoomProvider` handles the `metadata` prop internally to be updated to how `PluvClient` now handles this (i.e. moved to `PluvClient.enter`, from `PluvClient.createRoom`).
21
+ - e6ddddc: Add support for a passing either a function or object for the `metadata` prop on `PluvRoomProvider`. When a function is used, the `metadata` will be gotten at the moment of connection (internally this is a `useEffect`, so browser APIs can be used such as `document`, `window` and `localStorage`).
22
+
23
+ ```tsx
24
+ // Both of these work
25
+ <PluvRoomProvider metadata={{ hello: "world" }}>
26
+ {children}
27
+ </PluvRoomProvider>
28
+
29
+ <PluvRoomProvider
30
+ metadata={() => {
31
+ const value = localStorage.get(MY_LOCALSTORAGE_KEY);
32
+
33
+ return { hello: value };
34
+ }}
35
+ >
36
+ {children}
37
+ </PluvRoomProvider>
38
+ ```
39
+
40
+ - Updated dependencies [e6ddddc]
41
+ - Updated dependencies [e6ddddc]
42
+ - Updated dependencies [2cfb68d]
43
+ - Updated dependencies [e6ddddc]
44
+ - @pluv/client@0.39.0
45
+ - @pluv/crdt@0.39.0
46
+ - @pluv/types@0.39.0
47
+
48
+ ## 0.38.14
49
+
50
+ ### Patch Changes
51
+
52
+ - Updated dependencies [886a1f9]
53
+ - @pluv/client@0.38.14
54
+ - @pluv/crdt@0.38.14
55
+ - @pluv/types@0.38.14
56
+
3
57
  ## 0.38.13
4
58
 
5
59
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo, AbstractRoom } from '@pluv/client';
2
2
  import { CrdtType, AbstractCrdtDoc, InferCrdtJson } from '@pluv/crdt';
3
- import { IOLike, JsonObject, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
3
+ import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
4
4
  import { FC, ReactNode, Dispatch } from 'react';
5
5
 
6
6
  interface PluvProviderProps {
@@ -18,13 +18,15 @@ type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record
18
18
  type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = BaseRoomProviderProps<TPresence, TStorage> & {
19
19
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
20
20
  };
21
+ type MetadataGetter<TMetadata extends JsonObject> = TMetadata | (() => MaybePromise<TMetadata>);
21
22
  type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
23
+ connect?: boolean;
22
24
  debug?: boolean | PluvRoomDebug<TIO>;
23
25
  onAuthorizationFail?: (error: Error) => void;
24
26
  } & (keyof TMetadata extends never ? {
25
27
  metadata?: undefined;
26
28
  } : {
27
- metadata: TMetadata;
29
+ metadata: MetadataGetter<TMetadata>;
28
30
  });
29
31
  interface SubscriptionHookOptions<T extends unknown> {
30
32
  isEqual?: (a: T, b: T) => boolean;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PluvRouterEventConfig, PluvClient, PluvRoomAddon, PluvRouter, MockedRoomEvents, MergeEvents, PluvRoomDebug, WebSocketConnection, UserInfo, AbstractRoom } from '@pluv/client';
2
2
  import { CrdtType, AbstractCrdtDoc, InferCrdtJson } from '@pluv/crdt';
3
- import { IOLike, JsonObject, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
3
+ import { IOLike, JsonObject, MaybePromise, InferIOOutput, Id, IOEventMessage, InferIOInput } from '@pluv/types';
4
4
  import { FC, ReactNode, Dispatch } from 'react';
5
5
 
6
6
  interface PluvProviderProps {
@@ -18,13 +18,15 @@ type BaseRoomProviderProps<TPresence extends JsonObject, TStorage extends Record
18
18
  type MockedRoomProviderProps<TIO extends IOLike, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>, TEvents extends PluvRouterEventConfig<TIO, TPresence, TStorage> = {}> = BaseRoomProviderProps<TPresence, TStorage> & {
19
19
  events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
20
20
  };
21
+ type MetadataGetter<TMetadata extends JsonObject> = TMetadata | (() => MaybePromise<TMetadata>);
21
22
  type PluvRoomProviderProps<TIO extends IOLike<any, any>, TMetadata extends JsonObject, TPresence extends JsonObject, TStorage extends Record<string, CrdtType<any, any>>> = BaseRoomProviderProps<TPresence, TStorage> & {
23
+ connect?: boolean;
22
24
  debug?: boolean | PluvRoomDebug<TIO>;
23
25
  onAuthorizationFail?: (error: Error) => void;
24
26
  } & (keyof TMetadata extends never ? {
25
27
  metadata?: undefined;
26
28
  } : {
27
- metadata: TMetadata;
29
+ metadata: MetadataGetter<TMetadata>;
28
30
  });
29
31
  interface SubscriptionHookOptions<T extends unknown> {
30
32
  isEqual?: (a: T, b: T) => boolean;
package/dist/index.js CHANGED
@@ -1,10 +1,27 @@
1
1
  "use strict";
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
9
  var __getProtoOf = Object.getPrototypeOf;
7
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
8
25
  var __export = (target, all) => {
9
26
  for (var name in all)
10
27
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -26,6 +43,26 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
43
  mod
27
44
  ));
28
45
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
46
+ var __async = (__this, __arguments, generator) => {
47
+ return new Promise((resolve, reject) => {
48
+ var fulfilled = (value) => {
49
+ try {
50
+ step(generator.next(value));
51
+ } catch (e) {
52
+ reject(e);
53
+ }
54
+ };
55
+ var rejected = (value) => {
56
+ try {
57
+ step(generator.throw(value));
58
+ } catch (e) {
59
+ reject(e);
60
+ }
61
+ };
62
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
63
+ step((generator = generator.apply(__this, __arguments)).next());
64
+ });
65
+ };
29
66
 
30
67
  // src/index.ts
31
68
  var index_exports = {};
@@ -36,15 +73,97 @@ module.exports = __toCommonJS(index_exports);
36
73
 
37
74
  // src/createBundle.tsx
38
75
  var import_client = require("@pluv/client");
76
+ var import_fast_deep_equal2 = __toESM(require("fast-deep-equal"));
77
+ var import_react6 = require("react");
78
+
79
+ // src/internal/hooks/useAsyncQueue.ts
80
+ var import_react = require("react");
81
+ var useAsyncQueue = () => {
82
+ const queueRef = (0, import_react.useRef)(Promise.resolve(void 0));
83
+ const push = (0, import_react.useCallback)((promise) => __async(void 0, null, function* () {
84
+ queueRef.current = queueRef.current.then(() => __async(void 0, null, function* () {
85
+ return yield promise;
86
+ }));
87
+ return yield queueRef.current;
88
+ }), []);
89
+ return (0, import_react.useMemo)(() => ({ push }), [push]);
90
+ };
91
+
92
+ // src/internal/hooks/useDeepAsyncMemo.ts
93
+ var import_react2 = require("react");
39
94
  var import_fast_deep_equal = __toESM(require("fast-deep-equal"));
40
- var import_react4 = require("react");
95
+ var useDeepAsyncMemo = (factory, isEqual = import_fast_deep_equal.default) => {
96
+ const [state, setState] = (0, import_react2.useState)({
97
+ isInitialized: false,
98
+ isLoading: true,
99
+ value: void 0,
100
+ error: null
101
+ });
102
+ const lastValueRef = (0, import_react2.useRef)(void 0);
103
+ const hasValueRef = (0, import_react2.useRef)(false);
104
+ const inflightRef = (0, import_react2.useRef)(null);
105
+ const isMountedRef = (0, import_react2.useRef)(true);
106
+ (0, import_react2.useEffect)(() => {
107
+ isMountedRef.current = true;
108
+ const promise = factory();
109
+ inflightRef.current = promise;
110
+ setState((prev) => {
111
+ return __spreadProps(__spreadValues({}, prev), {
112
+ isLoading: true,
113
+ error: null
114
+ });
115
+ });
116
+ promise.then((result) => {
117
+ if (!isMountedRef.current || inflightRef.current !== promise) return;
118
+ const isSame = hasValueRef.current && isEqual(lastValueRef.current, result);
119
+ if (isSame) {
120
+ setState((prev) => {
121
+ return __spreadProps(__spreadValues({}, prev), {
122
+ isInitialized: true,
123
+ isLoading: false
124
+ });
125
+ });
126
+ return;
127
+ }
128
+ lastValueRef.current = result;
129
+ hasValueRef.current = true;
130
+ setState({
131
+ isInitialized: true,
132
+ isLoading: false,
133
+ value: result,
134
+ error: null
135
+ });
136
+ }).catch((err) => {
137
+ if (!isMountedRef.current || inflightRef.current !== promise) return;
138
+ setState({
139
+ isInitialized: hasValueRef.current,
140
+ isLoading: false,
141
+ value: void 0,
142
+ error: err instanceof Error ? err : new Error("Unknown error")
143
+ });
144
+ });
145
+ return () => {
146
+ isMountedRef.current = false;
147
+ };
148
+ }, [
149
+ /**
150
+ * !HACK
151
+ * @description We're only going to use the `isEqual` function to determine if this hook
152
+ * should re-run. This is basically our hook's version of a dependency array
153
+ * @date April 13, 2025
154
+ */
155
+ // factory,
156
+ isEqual
157
+ ]);
158
+ return state;
159
+ };
41
160
 
42
161
  // src/internal/hooks/useNoSsr.ts
43
- var import_react = require("react");
162
+ var import_react3 = require("react");
44
163
  var useNoSsr = () => {
45
- const [didMount, setDidMount] = (0, import_react.useState)(false);
46
- (0, import_react.useEffect)(() => setDidMount(typeof window !== "undefined"), []);
47
- const noSsr = (0, import_react.useCallback)(
164
+ const [didMount, setDidMount] = (0, import_react3.useState)(false);
165
+ (0, import_react3.useEffect)(() => setDidMount(typeof window !== "undefined"), []);
166
+ const noSsr = (0, import_react3.useCallback)(
48
167
  (value, fallback = null) => {
49
168
  return didMount ? typeof value !== "function" ? value : value() : fallback;
50
169
  },
@@ -54,16 +173,16 @@ var useNoSsr = () => {
54
173
  };
55
174
 
56
175
  // src/internal/hooks/useRerender.ts
57
- var import_react2 = require("react");
176
+ var import_react4 = require("react");
58
177
  var useRerender = () => {
59
- const [, setCount] = (0, import_react2.useState)(0);
60
- return (0, import_react2.useCallback)(() => {
178
+ const [, setCount] = (0, import_react4.useState)(0);
179
+ return (0, import_react4.useCallback)(() => {
61
180
  setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
62
181
  }, []);
63
182
  };
64
183
 
65
184
  // src/internal/hooks/useSyncExternalStoreWithSelector.ts
66
- var import_react3 = require("react");
185
+ var import_react5 = require("react");
67
186
 
68
187
  // src/internal/utils/identity.ts
69
188
  var identity = (x) => x;
@@ -79,7 +198,7 @@ var shallowEqual = (a, b) => a === b;
79
198
  // src/internal/hooks/useSyncExternalStoreWithSelector.ts
80
199
  var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
81
200
  const noSsr = useNoSsr();
82
- const cacheRef = (0, import_react3.useRef)(null);
201
+ const cacheRef = (0, import_react5.useRef)(null);
83
202
  const _getServerSnapshot = getServerSnapshot ? () => {
84
203
  const data = getServerSnapshot();
85
204
  const snapshot = selector(data);
@@ -98,19 +217,19 @@ var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerS
98
217
  cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
99
218
  return cacheRef.current;
100
219
  };
101
- const result = (0, import_react3.useSyncExternalStore)(subscribe, _getClientSnapshot, _getServerSnapshot);
220
+ const result = (0, import_react5.useSyncExternalStore)(subscribe, _getClientSnapshot, _getServerSnapshot);
102
221
  return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot == null ? void 0 : _getServerSnapshot()) : result;
103
222
  };
104
223
 
105
224
  // src/createBundle.tsx
106
225
  var import_jsx_runtime = require("react/jsx-runtime");
107
226
  var createBundle = (client, options = {}) => {
108
- const PluvContext = (0, import_react4.createContext)(null);
109
- const PluvRoomContext = (0, import_react4.createContext)(null);
110
- const MockedRoomContext = (0, import_react4.createContext)({ room: null });
111
- const MockedRoomProvider = (0, import_react4.memo)((props) => {
227
+ const PluvContext = (0, import_react6.createContext)(null);
228
+ const PluvRoomContext = (0, import_react6.createContext)(null);
229
+ const MockedRoomContext = (0, import_react6.createContext)(null);
230
+ const MockedRoomProvider = (0, import_react6.memo)((props) => {
112
231
  const { children, events, initialPresence, initialStorage, room: _room } = props;
113
- const [room] = (0, import_react4.useState)(() => {
232
+ const [room] = (0, import_react6.useState)(() => {
114
233
  var _a;
115
234
  return new import_client.MockedRoom(_room, {
116
235
  events,
@@ -118,14 +237,28 @@ var createBundle = (client, options = {}) => {
118
237
  initialStorage: typeof initialStorage === "function" ? (_a = client._defs.initialStorage) == null ? void 0 : _a.getFactory(initialStorage) : client._defs.initialStorage
119
238
  });
120
239
  });
121
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MockedRoomContext.Provider, { value: { room }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: room, children }) });
240
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MockedRoomContext.Provider, { value: room, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: room, children }) });
122
241
  });
123
242
  MockedRoomProvider.displayName = "MockedRoomProvider";
124
- const PluvRoomProvider = (0, import_react4.memo)((props) => {
125
- const { children, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
243
+ const PluvRoomProvider = (0, import_react6.memo)((props) => {
244
+ const {
245
+ children,
246
+ connect = true,
247
+ debug,
248
+ initialPresence,
249
+ initialStorage,
250
+ metadata,
251
+ onAuthorizationFail,
252
+ room: _room
253
+ } = props;
254
+ const queue = useAsyncQueue();
126
255
  const rerender = useRerender();
127
- const { room: mockedRoom } = (0, import_react4.useContext)(MockedRoomContext);
128
- const [room] = (0, import_react4.useState)(() => {
256
+ const mockedRoom = (0, import_react6.useContext)(MockedRoomContext);
257
+ const resolvedMeta = useDeepAsyncMemo(() => __async(void 0, null, function* () {
258
+ const resolved = yield Promise.resolve(typeof metadata === "function" ? metadata() : metadata);
259
+ return !!room.metadata ? room.metadata.parse(metadata) : resolved;
260
+ }));
261
+ const [room] = (0, import_react6.useState)(() => {
129
262
  var _a;
130
263
  return client.createRoom(_room, {
131
264
  addons: options.addons,
@@ -137,7 +270,7 @@ var createBundle = (client, options = {}) => {
137
270
  router: options.router
138
271
  });
139
272
  });
140
- (0, import_react4.useEffect)(() => {
273
+ (0, import_react6.useEffect)(() => {
141
274
  const unsubscribe = room.subscribe("connection", () => {
142
275
  rerender();
143
276
  });
@@ -145,35 +278,56 @@ var createBundle = (client, options = {}) => {
145
278
  unsubscribe();
146
279
  };
147
280
  }, [rerender, room]);
148
- (0, import_react4.useEffect)(() => {
149
- client.enter(room);
281
+ (0, import_react6.useEffect)(() => {
282
+ const leaveRoom = () => __async(void 0, null, function* () {
283
+ yield queue.push(
284
+ client.leave(room).catch((error) => {
285
+ console.error(error);
286
+ })
287
+ );
288
+ });
289
+ if (!connect) {
290
+ leaveRoom();
291
+ return;
292
+ }
293
+ if (!resolvedMeta.isInitialized) {
294
+ leaveRoom();
295
+ return;
296
+ }
297
+ const resolved = resolvedMeta.value;
298
+ queue.push(
299
+ client.enter(room, ...[{ metadata: resolved }]).catch((error) => __async(void 0, null, function* () {
300
+ console.error(error);
301
+ yield leaveRoom();
302
+ }))
303
+ );
150
304
  return () => {
151
- client.leave(room);
305
+ leaveRoom();
152
306
  };
153
- }, [room]);
307
+ }, [connect, queue, resolvedMeta.isInitialized, resolvedMeta.value, room]);
154
308
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: mockedRoom != null ? mockedRoom : room, children });
155
309
  });
156
310
  PluvRoomProvider.displayName = "PluvRoomProvider";
157
- const PluvProvider = (0, import_react4.memo)((props) => {
311
+ const PluvProvider = (0, import_react6.memo)((props) => {
158
312
  const { children } = props;
159
313
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvContext.Provider, { value: client, children });
160
314
  });
161
315
  PluvProvider.displayName = "PluvProvider";
162
- const useClient = () => (0, import_react4.useContext)(PluvContext);
316
+ const useClient = () => (0, import_react6.useContext)(PluvContext);
163
317
  const useRoom = () => {
164
- const room = (0, import_react4.useContext)(PluvRoomContext);
318
+ const room = (0, import_react6.useContext)(PluvRoomContext);
165
319
  if (!room) throw new Error("Room could not be found. Component must be wrapped with PluvRoomProvider");
166
320
  return room;
167
321
  };
168
322
  const useBroadcast = () => {
169
323
  const room = useRoom();
170
- const broadcast = (0, import_react4.useCallback)(
324
+ const broadcast = (0, import_react6.useCallback)(
171
325
  (event2, data) => {
172
326
  room.broadcast(event2, data);
173
327
  },
174
328
  [room]
175
329
  );
176
- return (0, import_react4.useMemo)(() => {
330
+ return (0, import_react6.useMemo)(() => {
177
331
  return new Proxy(broadcast, {
178
332
  get(fn, prop) {
179
333
  return (data) => {
@@ -185,35 +339,35 @@ var createBundle = (client, options = {}) => {
185
339
  };
186
340
  const useCanRedo = () => {
187
341
  const room = useRoom();
188
- const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
189
- const getSnapshot = (0, import_react4.useCallback)(() => room.canRedo(), [room]);
342
+ const subscribe = (0, import_react6.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
343
+ const getSnapshot = (0, import_react6.useCallback)(() => room.canRedo(), [room]);
190
344
  const canRedo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
191
345
  return canRedo;
192
346
  };
193
347
  const useCanUndo = () => {
194
348
  const room = useRoom();
195
- const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
196
- const getSnapshot = (0, import_react4.useCallback)(() => room.canUndo(), [room]);
349
+ const subscribe = (0, import_react6.useCallback)((onStoreChange) => room.storageRoot(onStoreChange), [room]);
350
+ const getSnapshot = (0, import_react6.useCallback)(() => room.canUndo(), [room]);
197
351
  const canUndo = useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
198
352
  return canUndo;
199
353
  };
200
354
  const useConnection = (selector = identity, options2) => {
201
355
  var _a;
202
356
  const room = useRoom();
203
- const subscribe = (0, import_react4.useCallback)(
357
+ const subscribe = (0, import_react6.useCallback)(
204
358
  (onStoreChange) => {
205
359
  return room.subscribe("connection", onStoreChange);
206
360
  },
207
361
  [room]
208
362
  );
209
363
  const getSnapshot = room.getConnection;
210
- const _selector = (0, import_react4.useCallback)((snapshot) => selector(snapshot), [selector]);
364
+ const _selector = (0, import_react6.useCallback)((snapshot) => selector(snapshot), [selector]);
211
365
  return useSyncExternalStoreWithSelector(
212
366
  subscribe,
213
367
  getSnapshot,
214
368
  getSnapshot,
215
369
  _selector,
216
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal.default
370
+ (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
217
371
  );
218
372
  };
219
373
  const useDoc = () => {
@@ -222,7 +376,7 @@ var createBundle = (client, options = {}) => {
222
376
  };
223
377
  const useEvent = (type, callback) => {
224
378
  const room = useRoom();
225
- (0, import_react4.useEffect)(() => {
379
+ (0, import_react6.useEffect)(() => {
226
380
  const unsubscribe = room.event(type, callback);
227
381
  return () => {
228
382
  unsubscribe();
@@ -243,34 +397,34 @@ var createBundle = (client, options = {}) => {
243
397
  const useMyPresence = (selector = identity, options2) => {
244
398
  var _a;
245
399
  const room = useRoom();
246
- const subscribe = (0, import_react4.useCallback)(
400
+ const subscribe = (0, import_react6.useCallback)(
247
401
  (onStoreChange) => {
248
402
  return room.subscribe("my-presence", onStoreChange);
249
403
  },
250
404
  [room]
251
405
  );
252
406
  const getSnapshot = room.getMyPresence;
253
- const _selector = (0, import_react4.useCallback)((snapshot) => selector(snapshot), [selector]);
407
+ const _selector = (0, import_react6.useCallback)((snapshot) => selector(snapshot), [selector]);
254
408
  const myPresence = useSyncExternalStoreWithSelector(
255
409
  subscribe,
256
410
  getSnapshot,
257
411
  getSnapshot,
258
412
  _selector,
259
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal.default
413
+ (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
260
414
  );
261
415
  return [myPresence, room.updateMyPresence];
262
416
  };
263
417
  const useMyself = (selector = identity, options2) => {
264
418
  var _a;
265
419
  const room = useRoom();
266
- const subscribe = (0, import_react4.useCallback)(
420
+ const subscribe = (0, import_react6.useCallback)(
267
421
  (onStoreChange) => {
268
422
  return room.subscribe("myself", onStoreChange);
269
423
  },
270
424
  [room]
271
425
  );
272
426
  const getSnapshot = room.getMyself;
273
- const _selector = (0, import_react4.useCallback)(
427
+ const _selector = (0, import_react6.useCallback)(
274
428
  (snapshot) => {
275
429
  return !snapshot ? null : selector(snapshot);
276
430
  },
@@ -281,20 +435,20 @@ var createBundle = (client, options = {}) => {
281
435
  getSnapshot,
282
436
  getSnapshot,
283
437
  _selector,
284
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal.default
438
+ (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
285
439
  );
286
440
  };
287
441
  const useOther = (connectionId, selector = identity, options2) => {
288
442
  var _a;
289
443
  const room = useRoom();
290
- const subscribe = (0, import_react4.useCallback)(
444
+ const subscribe = (0, import_react6.useCallback)(
291
445
  (onStoreChange) => {
292
446
  return room.other(connectionId, onStoreChange);
293
447
  },
294
448
  [room, connectionId]
295
449
  );
296
- const getSnapshot = (0, import_react4.useCallback)(() => room.getOther(connectionId), [room, connectionId]);
297
- const _selector = (0, import_react4.useCallback)(
450
+ const getSnapshot = (0, import_react6.useCallback)(() => room.getOther(connectionId), [room, connectionId]);
451
+ const _selector = (0, import_react6.useCallback)(
298
452
  (snapshot) => {
299
453
  return !snapshot ? null : selector(snapshot);
300
454
  },
@@ -305,13 +459,13 @@ var createBundle = (client, options = {}) => {
305
459
  getSnapshot,
306
460
  getSnapshot,
307
461
  _selector,
308
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal.default
462
+ (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
309
463
  );
310
464
  };
311
465
  const useOthers = (selector = identity, options2) => {
312
466
  var _a;
313
467
  const room = useRoom();
314
- const subscribe = (0, import_react4.useCallback)(
468
+ const subscribe = (0, import_react6.useCallback)(
315
469
  (onStoreChange) => {
316
470
  return room.subscribe("others", onStoreChange);
317
471
  },
@@ -327,7 +481,7 @@ var createBundle = (client, options = {}) => {
327
481
  if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
328
482
  return shallowArrayEqual(a, b);
329
483
  }
330
- return (0, import_fast_deep_equal.default)(a, b);
484
+ return (0, import_fast_deep_equal2.default)(a, b);
331
485
  }
332
486
  );
333
487
  };
@@ -342,11 +496,11 @@ var createBundle = (client, options = {}) => {
342
496
  room.subscribe("storage-loaded", () => {
343
497
  rerender();
344
498
  });
345
- const subscribe = (0, import_react4.useCallback)((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
346
- const getSnapshot = (0, import_react4.useCallback)(() => {
499
+ const subscribe = (0, import_react6.useCallback)((onStoreChange) => room.storage(key, onStoreChange), [key, room]);
500
+ const getSnapshot = (0, import_react6.useCallback)(() => {
347
501
  return room.getStorageJson(key);
348
502
  }, [key, room]);
349
- const _selector = (0, import_react4.useCallback)(
503
+ const _selector = (0, import_react6.useCallback)(
350
504
  (snapshot) => {
351
505
  return snapshot === null ? null : selector(snapshot);
352
506
  },
@@ -357,7 +511,7 @@ var createBundle = (client, options = {}) => {
357
511
  getSnapshot,
358
512
  getSnapshot,
359
513
  _selector,
360
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal.default
514
+ (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
361
515
  );
362
516
  const sharedType = (_b = room.getStorage(key)) != null ? _b : null;
363
517
  return [data, sharedType];