@pluv/react 4.1.0 → 5.0.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @pluv/react
2
2
 
3
+ ## 5.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - @pluv/client@5.0.1
8
+ - @pluv/crdt@5.0.1
9
+ - @pluv/types@5.0.1
10
+
11
+ ## 5.0.0
12
+
13
+ ### Patch Changes
14
+
15
+ - @pluv/client@5.0.0
16
+ - @pluv/crdt@5.0.0
17
+ - @pluv/types@5.0.0
18
+
3
19
  ## 4.1.0
4
20
 
5
21
  ### Patch Changes
@@ -260,9 +276,7 @@
260
276
  import type { InferBundleRoom } from "@pluv/react";
261
277
  import { createBundle } from "@pluv/react";
262
278
 
263
- const client = createclient({
264
- /* ... */
265
- });
279
+ const client = createclient({/* ... */});
266
280
 
267
281
  const bundle = createBundle(client);
268
282
 
@@ -1512,9 +1526,7 @@
1512
1526
  import { createClient } from "@pluv/react";
1513
1527
  import type { io } from "../backend/io";
1514
1528
 
1515
- const client = createClient<typeof io>({
1516
- /* ... */
1517
- });
1529
+ const client = createClient<typeof io>({/* ... */});
1518
1530
  ```
1519
1531
 
1520
1532
  ### Now:
@@ -1556,9 +1568,7 @@
1556
1568
  import type { ioServer } from "../backend/io";
1557
1569
 
1558
1570
  // This users the PluvServer type now
1559
- const client = createClient<typeof ioServer>({
1560
- /* ... */
1561
- });
1571
+ const client = createClient<typeof ioServer>({/* ... */});
1562
1572
  ```
1563
1573
 
1564
1574
  - `PluvRouter` instances can also be merged via the `mergeRouters` method, which effectively performs an `Object.assign` of the events object and returns a new `PluvRouter` with the correct types:
@@ -1761,9 +1771,7 @@
1761
1771
  // Before:
1762
1772
  import { createClient, y } from "@pluv/client";
1763
1773
 
1764
- const client = createClient({
1765
- /* ... */
1766
- });
1774
+ const client = createClient({/* ... */});
1767
1775
 
1768
1776
  client.createRoom({
1769
1777
  // ...
@@ -1777,9 +1785,7 @@
1777
1785
  // This is now imported separately
1778
1786
  import { yjs } from "@pluv/crdt-yjs";
1779
1787
 
1780
- const client = createClient({
1781
- /* ... */
1782
- });
1788
+ const client = createClient({/* ... */});
1783
1789
 
1784
1790
  client.createRoom({
1785
1791
  // ...
@@ -1815,9 +1821,7 @@
1815
1821
  // Before:
1816
1822
  import { Doc as YDoc } from "yjs";
1817
1823
 
1818
- const room: PluvRoom = client.createRoom({
1819
- /* ... */
1820
- });
1824
+ const room: PluvRoom = client.createRoom({/* ... */});
1821
1825
 
1822
1826
  const doc: YDoc = room.getDoc();
1823
1827
 
@@ -1825,9 +1829,7 @@
1825
1829
  import { CrdtYjsDoc } from "@pluv/crdt-yjs";
1826
1830
  import { Doc as YDoc } from "yjs";
1827
1831
 
1828
- const room: PluvRoom = client.createRoom({
1829
- /* ... */
1830
- });
1832
+ const room: PluvRoom = client.createRoom({/* ... */});
1831
1833
 
1832
1834
  const doc: CrdtYjsDoc<any> = room.getDoc();
1833
1835
  const ydoc: YDoc = doc.value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pluv/react",
3
- "version": "4.1.0",
3
+ "version": "5.0.1",
4
4
  "description": "@pluv/client React.js bindings",
5
5
  "author": {
6
6
  "email": "david@pluv.io",
@@ -20,23 +20,23 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
- "fast-deep-equal": "^3.1.3",
24
- "@pluv/client": "^4.1.0",
25
- "@pluv/crdt": "^4.1.0",
26
- "@pluv/types": "^4.1.0"
23
+ "@pluv/client": "^5.0.1",
24
+ "@pluv/crdt": "^5.0.1",
25
+ "@pluv/types": "^5.0.1",
26
+ "fast-deep-equal": "^3.1.3"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "@types/react": "^18.0.0 || ^19.0.0",
30
30
  "react": "^18.0.0 || ^19.0.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@types/react": "^19.2.17",
34
- "eslint": "^10.5.0",
35
- "react": "^19.2.7",
36
- "tsdown": "0.22.2",
37
- "typescript": "^5.9.3",
38
- "@pluv/tsconfig": "^4.1.0",
39
- "eslint-config-pluv": "^4.1.0"
33
+ "@pluv/tsconfig": "^5.0.1",
34
+ "@types/react": "^19.2.18",
35
+ "eslint": "^10.9.0",
36
+ "eslint-config-pluv": "^5.0.1",
37
+ "react": "^19.2.8",
38
+ "tsdown": "0.22.14",
39
+ "typescript": "^5.9.3"
40
40
  },
41
41
  "exports": {
42
42
  ".": "./dist/index.mjs",
package/src/types.ts CHANGED
@@ -65,8 +65,7 @@ export type EventProxy<TIO extends IOLike> = {
65
65
  };
66
66
 
67
67
  export type MetadataGetter<TMetadata extends JsonObject> =
68
- | TMetadata
69
- | (() => MaybePromise<TMetadata>);
68
+ TMetadata | (() => MaybePromise<TMetadata>);
70
69
 
71
70
  export type PluvRoomProviderProps<
72
71
  TIO extends IOLike<any, any, any>,
@@ -1,18 +0,0 @@
1
- $ tsdown
2
- ℹ tsdown v0.22.2 powered by rolldown v1.1.1
3
- ℹ config file: /home/runner/work/pluv/pluv/packages/react/tsdown.config.ts
4
- ℹ entry: src/index.ts
5
- ℹ target: esnext
6
- ℹ tsconfig: tsconfig.json
7
-
8
-  WARN  `external` is deprecated. Use `deps.neverBundle` instead.
9
-
10
- ℹ Build start
11
- ℹ dist/index.mjs 13.68 kB │ gzip: 3.19 kB
12
- ℹ dist/index.mjs.map 36.29 kB │ gzip: 7.88 kB
13
- ℹ dist/index.d.mts.map  3.93 kB │ gzip: 1.06 kB
14
- ℹ dist/index.d.mts  6.17 kB │ gzip: 1.56 kB
15
- ℹ 4 files, total: 60.08 kB
16
- [PLUGIN_TIMINGS] Your build spent significant time in plugin `rolldown-plugin-dts:generate`. See https://rolldown.rs/options/checks#plugintimings for more details.
17
-
18
- ✔ Build complete in 4111ms
package/dist/index.d.mts DELETED
@@ -1,71 +0,0 @@
1
- import { MergeEvents, MockedRoomEvents, PluvClient, PluvRoomAddon, PluvRoomDebug, PluvRouter, PluvRouterEventConfig, UserInfo, WebSocketConnection } from "@pluv/client";
2
- import { Dispatch, FC, ReactNode } from "react";
3
- import { AbstractCrdtDocFactory, InferCrdtJson, InferDoc, InferInitialStorageFn, InferStorage } from "@pluv/crdt";
4
- import { CrdtDocLike, IOEventMessage, IOLike, Id, InferIOCrdtKind, InferIOInput, InferIOOutput, JsonObject, MaybePromise, RoomLike, UpdateMyPresenceAction } from "@pluv/types";
5
-
6
- //#region src/types.d.ts
7
- interface PluvProviderProps {
8
- children?: ReactNode;
9
- }
10
- type BaseRoomProviderProps<TPresence extends Record<string, any>, TCrdt extends AbstractCrdtDocFactory<any, any>> = {
11
- children?: ReactNode;
12
- initialStorage?: keyof InferStorage<TCrdt> extends never ? never : InferInitialStorageFn<TCrdt>;
13
- room: string;
14
- } & (keyof TPresence extends never ? {
15
- initialPresence?: never;
16
- } : {
17
- initialPresence: TPresence;
18
- });
19
- type MockedRoomProviderProps<TIO extends IOLike, TPresence extends Record<string, any>, TCrdt extends AbstractCrdtDocFactory<any, any>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = BaseRoomProviderProps<TPresence, TCrdt> & {
20
- events?: MockedRoomEvents<MergeEvents<TEvents, TIO>>;
21
- };
22
- type BroadcastProxy<TIO extends IOLike> = (<TEvent extends keyof InferIOInput<TIO>>(event: TEvent, data: Id<InferIOInput<TIO>[TEvent]>) => void) & { [event in keyof InferIOInput<TIO>]: (input: Id<InferIOInput<TIO>[event]>) => void };
23
- type EventProxy<TIO extends IOLike> = { [event in keyof InferIOOutput<TIO>]: {
24
- useEvent: (callback: (data: Id<IOEventMessage<TIO, event>>) => void) => void;
25
- } };
26
- type MetadataGetter<TMetadata extends JsonObject> = TMetadata | (() => MaybePromise<TMetadata>);
27
- type PluvRoomProviderProps<TIO extends IOLike<any, any, any>, TMetadata extends JsonObject, TPresence extends Record<string, any>, TCrdt extends AbstractCrdtDocFactory<any, any>> = BaseRoomProviderProps<TPresence, TCrdt> & {
28
- connect?: boolean;
29
- debug?: boolean | PluvRoomDebug<TIO>;
30
- onAuthorizationFail?: (error: Error) => void;
31
- } & (keyof TMetadata extends never ? {
32
- metadata?: undefined;
33
- } : {
34
- metadata: MetadataGetter<TMetadata>;
35
- });
36
- interface SubscriptionHookOptions<T extends unknown> {
37
- isEqual?: (a: T, b: T) => boolean;
38
- }
39
- interface CreateBundle<TIO extends IOLike<any, any, any>, TMetadata extends JsonObject, TPresence extends Record<string, any> = {}, TCrdt extends InferIOCrdtKind<TIO> = InferIOCrdtKind<TIO>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> {
40
- MockedRoomProvider: FC<MockedRoomProviderProps<TIO, TPresence, TCrdt>>;
41
- PluvProvider: FC<PluvProviderProps>;
42
- PluvRoomProvider: FC<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>;
43
- event: EventProxy<MergeEvents<TEvents, TIO>>;
44
- useBroadcast: () => BroadcastProxy<MergeEvents<TEvents, TIO>>;
45
- useCanRedo: () => boolean;
46
- useCanUndo: () => boolean;
47
- useClient: () => PluvClient<TIO, TPresence, TCrdt, TMetadata>;
48
- useConnection: <T extends unknown = WebSocketConnection>(selector?: (connection: WebSocketConnection) => T, options?: SubscriptionHookOptions<Id<T>>) => Id<T>;
49
- useDoc: () => CrdtDocLike<InferDoc<TCrdt>, InferStorage<TCrdt>>;
50
- useEvent: <TType extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(type: TType, callback: (data: Id<IOEventMessage<MergeEvents<TEvents, TIO>, TType>>) => void) => void;
51
- useMyPresence: <T extends unknown = TPresence>(selector?: (myPresence: TPresence) => T, options?: SubscriptionHookOptions<Id<T> | null>) => [myPresence: Id<T>, updateMyPresence: Dispatch<UpdateMyPresenceAction<TPresence>>];
52
- useMyself: <T extends unknown = UserInfo<TIO, TPresence>>(selector?: (myself: Id<UserInfo<TIO, TPresence>>) => T, options?: SubscriptionHookOptions<Id<T> | null>) => Id<T> | null;
53
- useOther: <T extends unknown = UserInfo<TIO, TPresence>>(connectionId: string, selector?: (other: UserInfo<TIO, TPresence>) => T, options?: SubscriptionHookOptions<T | null>) => T | null;
54
- useOthers: <T extends unknown = readonly UserInfo<TIO, TPresence>[]>(selector?: (other: readonly Id<UserInfo<TIO, TPresence>>[]) => T, options?: SubscriptionHookOptions<T>) => T;
55
- useRedo: () => () => void;
56
- useRoom: () => RoomLike<TIO, InferDoc<TCrdt>, TPresence, InferStorage<TCrdt>, TEvents>;
57
- useStorage: <TKey extends keyof InferStorage<TCrdt>, TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>>(key: TKey, selector?: (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData, options?: SubscriptionHookOptions<TData | null>) => [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null];
58
- useTransact: () => (fn: (storage: InferStorage<TCrdt>) => void, origin?: string) => void;
59
- useUndo: () => () => void;
60
- }
61
- type InferBundleRoom<TBundle extends CreateBundle<any, any, any, any, any>> = TBundle extends CreateBundle<infer IIO, any, infer IPresence, infer ICrdt, infer IEvents> ? RoomLike<IIO, InferDoc<ICrdt>, IPresence, InferStorage<ICrdt>, IEvents> : never;
62
- //#endregion
63
- //#region src/createBundle.d.ts
64
- type CreateBundleOptions<TIO extends IOLike<any, any, any>, TMetadata extends JsonObject = {}, TPresence extends Record<string, any> = {}, TCrdt extends InferIOCrdtKind<TIO> = InferIOCrdtKind<TIO>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}> = {
65
- addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];
66
- router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;
67
- };
68
- declare const createBundle: <TIO extends IOLike<any, any, any>, TMetadata extends JsonObject = {}, TPresence extends Record<string, any> = {}, TCrdt extends InferIOCrdtKind<TIO> = InferIOCrdtKind<TIO>, TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {}>(client: PluvClient<TIO, TPresence, TCrdt, TMetadata>, options?: CreateBundleOptions<TIO, TMetadata, TPresence, TCrdt, TEvents>) => CreateBundle<TIO, TMetadata, TPresence, TCrdt, TEvents>;
69
- //#endregion
70
- export { type CreateBundle, type EventProxy, type InferBundleRoom, type PluvProviderProps, type PluvRoomProviderProps, type SubscriptionHookOptions, createBundle };
71
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/createBundle.tsx"],"mappings":"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"}
package/dist/index.mjs DELETED
@@ -1,416 +0,0 @@
1
- import { MockedRoom } from "@pluv/client";
2
- import fastDeepEqual from "fast-deep-equal";
3
- import { createContext, memo, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
- import { jsx } from "react/jsx-runtime";
5
- //#region src/internal/hooks/useAsyncQueue.ts
6
- /**
7
- * @description This is to handle race conditions, so that our async operations that can
8
- * happen between re-renders will happen sequentially.
9
- * @date April 13, 2025
10
- */
11
- const useAsyncQueue = () => {
12
- const queueRef = useRef(Promise.resolve(void 0));
13
- const push = useCallback(async (promise) => {
14
- queueRef.current = queueRef.current.then(async () => await promise);
15
- return await queueRef.current;
16
- }, []);
17
- return useMemo(() => ({ push }), [push]);
18
- };
19
- //#endregion
20
- //#region src/internal/hooks/useDeepAsyncMemo.ts
21
- const useDeepAsyncMemo = (factory, isEqual = fastDeepEqual) => {
22
- const [state, setState] = useState({
23
- isInitialized: false,
24
- isLoading: true,
25
- value: void 0,
26
- error: null
27
- });
28
- const lastValueRef = useRef(void 0);
29
- const hasValueRef = useRef(false);
30
- const inflightRef = useRef(null);
31
- const isMountedRef = useRef(true);
32
- useEffect(() => {
33
- isMountedRef.current = true;
34
- const promise = factory();
35
- inflightRef.current = promise;
36
- setState((prev) => {
37
- return {
38
- ...prev,
39
- isLoading: true,
40
- error: null
41
- };
42
- });
43
- promise.then((result) => {
44
- if (!isMountedRef.current || inflightRef.current !== promise) return;
45
- if (hasValueRef.current && isEqual(lastValueRef.current, result)) {
46
- setState((prev) => {
47
- return {
48
- ...prev,
49
- isInitialized: true,
50
- isLoading: false
51
- };
52
- });
53
- return;
54
- }
55
- lastValueRef.current = result;
56
- hasValueRef.current = true;
57
- setState({
58
- isInitialized: true,
59
- isLoading: false,
60
- value: result,
61
- error: null
62
- });
63
- }).catch((err) => {
64
- if (!isMountedRef.current || inflightRef.current !== promise) return;
65
- setState({
66
- isInitialized: hasValueRef.current,
67
- isLoading: false,
68
- value: void 0,
69
- error: err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error")
70
- });
71
- });
72
- return () => {
73
- isMountedRef.current = false;
74
- };
75
- }, [isEqual]);
76
- return state;
77
- };
78
- //#endregion
79
- //#region src/internal/hooks/useNoSsr.ts
80
- const useNoSsr = () => {
81
- const [didMount, setDidMount] = useState(false);
82
- useEffect(() => setDidMount(typeof window !== "undefined"), []);
83
- return useCallback((value, fallback = null) => {
84
- return didMount ? typeof value !== "function" ? value : value() : fallback;
85
- }, [didMount]);
86
- };
87
- //#endregion
88
- //#region src/internal/hooks/useRerender.ts
89
- const useRerender = () => {
90
- const [, setCount] = useState(0);
91
- return useCallback(() => {
92
- setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
93
- }, []);
94
- };
95
- //#endregion
96
- //#region src/internal/utils/identity.ts
97
- const identity = (x) => x;
98
- //#endregion
99
- //#region src/internal/utils/shallowArrayEqual.ts
100
- const shallowArrayEqual = (a, b) => {
101
- return a.length === b.length && a.every((item, i) => item === b[i]);
102
- };
103
- //#endregion
104
- //#region src/internal/utils/shallowEqual.ts
105
- const shallowEqual = (a, b) => a === b;
106
- //#endregion
107
- //#region src/internal/hooks/useSyncExternalStoreWithSelector.ts
108
- const useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
109
- const noSsr = useNoSsr();
110
- const cacheRef = useRef(null);
111
- const _getServerSnapshot = getServerSnapshot ? () => {
112
- const snapshot = selector(getServerSnapshot());
113
- const compare = isEqual ?? shallowEqual;
114
- const cached = cacheRef.current;
115
- /**
116
- * !HACK
117
- * @description Memoize only the last snapshot so that we can only rerender on changes
118
- * @date June 22, 2024
119
- */
120
- cacheRef.current = (cached === null ? snapshot === null : compare(cached, snapshot)) ? cached ?? snapshot : snapshot;
121
- return cacheRef.current;
122
- } : void 0;
123
- const _getClientSnapshot = () => {
124
- const snapshot = selector(getClientSnapshot());
125
- const compare = isEqual ?? shallowEqual;
126
- const cached = cacheRef.current;
127
- /**
128
- * !HACK
129
- * @description Memoize only the last snapshot so that we can only rerender on changes
130
- * @date June 22, 2024
131
- */
132
- cacheRef.current = (cached === null ? snapshot === null : compare(cached, snapshot)) ? cached ?? snapshot : snapshot;
133
- return cacheRef.current;
134
- };
135
- const result = useSyncExternalStore(subscribe, _getClientSnapshot, _getServerSnapshot);
136
- return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot?.()) : result;
137
- };
138
- //#endregion
139
- //#region src/createBundle.tsx
140
- const createBundle = (client, options = {}) => {
141
- /**
142
- * !HACK
143
- * @description We'll let the context error out if client is not provided,
144
- * and let the users deal with it.
145
- * @date October 27, 2022
146
- */
147
- const PluvContext = createContext(null);
148
- /**
149
- * !HACK
150
- * @description We'll let the context error out if the room is not provided,
151
- * and let the users deal with it.
152
- * @date November 11, 2022
153
- */
154
- const PluvRoomContext = createContext(null);
155
- const MockedRoomContext = createContext(null);
156
- const MockedRoomProvider = memo((props) => {
157
- const { children, events, initialPresence, initialStorage, room: _room } = props;
158
- const [room] = useState(() => {
159
- return new MockedRoom(_room, {
160
- events,
161
- initialPresence,
162
- initialStorage: typeof initialStorage === "function" ? client._defs.initialStorage?.getFactory(initialStorage) : void 0
163
- });
164
- });
165
- return /* @__PURE__ */ jsx(MockedRoomContext.Provider, {
166
- value: room,
167
- children: /* @__PURE__ */ jsx(PluvRoomContext.Provider, {
168
- value: room,
169
- children
170
- })
171
- });
172
- });
173
- MockedRoomProvider.displayName = "MockedRoomProvider";
174
- const PluvRoomProvider = memo((props) => {
175
- const { children, connect = true, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
176
- const queue = useAsyncQueue();
177
- const rerender = useRerender();
178
- const mockedRoom = useContext(MockedRoomContext);
179
- const createRoom = useCallback(() => {
180
- return client.createRoom(_room, {
181
- addons: options.addons,
182
- debug,
183
- initialPresence,
184
- initialStorage: typeof initialStorage === "function" ? client._defs.initialStorage?.getFactory(initialStorage) : void 0,
185
- metadata,
186
- onAuthorizationFail,
187
- router: options.router
188
- });
189
- }, [
190
- _room,
191
- debug,
192
- initialPresence,
193
- initialStorage,
194
- metadata,
195
- onAuthorizationFail
196
- ]);
197
- const [room, setRoom] = useState(() => createRoom());
198
- useEffect(() => {
199
- if (room.id === _room) return;
200
- setRoom(createRoom());
201
- }, [
202
- _room,
203
- createRoom,
204
- room
205
- ]);
206
- const resolvedMeta = useDeepAsyncMemo(async () => {
207
- const resolved = await Promise.resolve(typeof metadata === "function" ? metadata() : metadata);
208
- return !!room.metadata ? room.metadata.parse(resolved) : resolved;
209
- });
210
- useEffect(() => {
211
- const unsubscribe = room.subscribe.connection(() => {
212
- rerender();
213
- });
214
- return () => {
215
- unsubscribe();
216
- };
217
- }, [rerender, room]);
218
- useEffect(() => {
219
- const leaveRoom = async () => {
220
- await queue.push(client.leave(room).catch((error) => {
221
- console.error(error);
222
- }));
223
- };
224
- if (!connect) {
225
- leaveRoom();
226
- return;
227
- }
228
- if (!resolvedMeta.isInitialized) {
229
- leaveRoom();
230
- return;
231
- }
232
- const resolved = resolvedMeta.value;
233
- queue.push(client.enter(room, ...[{ metadata: resolved }]).catch(async (error) => {
234
- console.error(error);
235
- await leaveRoom();
236
- }));
237
- return () => {
238
- leaveRoom();
239
- };
240
- }, [
241
- connect,
242
- queue,
243
- resolvedMeta.isInitialized,
244
- resolvedMeta.value,
245
- room
246
- ]);
247
- return /* @__PURE__ */ jsx(PluvRoomContext.Provider, {
248
- value: mockedRoom ?? room,
249
- children
250
- });
251
- });
252
- PluvRoomProvider.displayName = "PluvRoomProvider";
253
- const PluvProvider = memo((props) => {
254
- const { children } = props;
255
- return /* @__PURE__ */ jsx(PluvContext.Provider, {
256
- value: client,
257
- children
258
- });
259
- });
260
- PluvProvider.displayName = "PluvProvider";
261
- const useClient = () => useContext(PluvContext);
262
- const useRoom = () => {
263
- const room = useContext(PluvRoomContext);
264
- if (!room) throw new Error("Room could not be found. Component must be wrapped with PluvRoomProvider");
265
- return room;
266
- };
267
- const useBroadcast = () => {
268
- const room = useRoom();
269
- const broadcast = useCallback((event, data) => {
270
- room.broadcast(event, data);
271
- }, [room]);
272
- return useMemo(() => {
273
- return new Proxy(broadcast, { get(fn, prop) {
274
- return (data) => {
275
- return fn(prop, data);
276
- };
277
- } });
278
- }, [broadcast]);
279
- };
280
- const useCanRedo = () => {
281
- const room = useRoom();
282
- const subscribe = useCallback((onStoreChange) => room.subscribe.storage(onStoreChange), [room]);
283
- const getSnapshot = useCallback(() => room.canRedo(), [room]);
284
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
285
- };
286
- const useCanUndo = () => {
287
- const room = useRoom();
288
- const subscribe = useCallback((onStoreChange) => room.subscribe.storage(onStoreChange), [room]);
289
- const getSnapshot = useCallback(() => room.canUndo(), [room]);
290
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
291
- };
292
- const useConnection = (selector = identity, options) => {
293
- const room = useRoom();
294
- const subscribe = useCallback((onStoreChange) => room.subscribe.connection(onStoreChange), [room]);
295
- const getSnapshot = room.getConnection;
296
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => selector(snapshot), [selector]), options?.isEqual ?? fastDeepEqual);
297
- };
298
- const useDoc = () => {
299
- const room = useRoom();
300
- const subscribe = useCallback((onStoreChange) => room.subscribe.storageLoaded(onStoreChange), [room]);
301
- const getSnapshot = room.getDoc;
302
- return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
303
- };
304
- const useEvent = (type, callback) => {
305
- const room = useRoom();
306
- useEffect(() => {
307
- const unsubscribe = room.subscribe.event(type, callback);
308
- return () => {
309
- unsubscribe();
310
- };
311
- }, [
312
- callback,
313
- room,
314
- type
315
- ]);
316
- };
317
- const event = new Proxy({}, { get(_, prop) {
318
- const useProxyEvent = (callback) => {
319
- return useEvent(prop, callback);
320
- };
321
- return { useEvent: useProxyEvent };
322
- } });
323
- const useMyPresence = (selector = identity, options) => {
324
- const room = useRoom();
325
- const subscribe = useCallback((onStoreChange) => room.subscribe.myPresence(onStoreChange), [room]);
326
- const getSnapshot = room.getMyPresence;
327
- return [useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => selector(snapshot), [selector]), options?.isEqual ?? fastDeepEqual), room.updateMyPresence];
328
- };
329
- const useMyself = (selector = identity, options) => {
330
- const room = useRoom();
331
- const subscribe = useCallback((onStoreChange) => room.subscribe.myself(onStoreChange), [room]);
332
- const getSnapshot = room.getMyself;
333
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
334
- return !snapshot ? null : selector(snapshot);
335
- }, [selector]), options?.isEqual ?? fastDeepEqual);
336
- };
337
- const useOther = (connectionId, selector = identity, options) => {
338
- const room = useRoom();
339
- const subscribe = useCallback((onStoreChange) => room.subscribe.other(connectionId, onStoreChange), [room, connectionId]);
340
- const getSnapshot = useCallback(() => room.getOther(connectionId), [room, connectionId]);
341
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
342
- return !snapshot ? null : selector(snapshot);
343
- }, [selector]), options?.isEqual ?? fastDeepEqual);
344
- };
345
- const useOthers = (selector = identity, options) => {
346
- const room = useRoom();
347
- const subscribe = useCallback((onStoreChange) => room.subscribe.others(onStoreChange), [room]);
348
- const getSnapshot = room.getOthers;
349
- return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, selector, options?.isEqual ?? ((a, b) => {
350
- /**
351
- * !HACK
352
- * @description Assume the return type will always be an array when this occurs
353
- * and do a shallow comparison instead like how standard React dependency
354
- * arrays work. This is for performance's sake and may lead to bugs if the
355
- * selector doesn't always return an array
356
- * @date June 22, 2024
357
- */
358
- if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) return shallowArrayEqual(a, b);
359
- return fastDeepEqual(a, b);
360
- }));
361
- };
362
- const useRedo = () => {
363
- return useRoom().redo;
364
- };
365
- const useStorage = (key, selector = identity, options) => {
366
- const room = useRoom();
367
- const rerender = useRerender();
368
- useEffect(() => {
369
- const unsubscribe = room.subscribe.storageLoaded(() => {
370
- rerender();
371
- });
372
- return () => {
373
- unsubscribe();
374
- };
375
- }, [rerender, room]);
376
- const subscribe = useCallback((onStoreChange) => room.subscribe.storage(key, onStoreChange), [key, room]);
377
- const getSnapshot = useCallback(() => {
378
- return room.getStorageJson(key);
379
- }, [key, room]);
380
- return [useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
381
- return snapshot === null ? null : selector(snapshot);
382
- }, [selector]), options?.isEqual ?? fastDeepEqual), room.getStorage(key) ?? null];
383
- };
384
- const useTransact = () => {
385
- return useRoom().transact;
386
- };
387
- const useUndo = () => {
388
- return useRoom().undo;
389
- };
390
- return {
391
- MockedRoomProvider,
392
- PluvProvider,
393
- PluvRoomProvider,
394
- event,
395
- useBroadcast,
396
- useCanRedo,
397
- useCanUndo,
398
- useClient,
399
- useConnection,
400
- useDoc,
401
- useEvent,
402
- useMyPresence,
403
- useMyself,
404
- useOther,
405
- useOthers,
406
- useRedo,
407
- useRoom,
408
- useStorage,
409
- useTransact,
410
- useUndo
411
- };
412
- };
413
- //#endregion
414
- export { createBundle };
415
-
416
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/internal/hooks/useAsyncQueue.ts","../src/internal/hooks/useDeepAsyncMemo.ts","../src/internal/hooks/useNoSsr.ts","../src/internal/hooks/useRerender.ts","../src/internal/utils/identity.ts","../src/internal/utils/shallowArrayEqual.ts","../src/internal/utils/shallowEqual.ts","../src/internal/hooks/useSyncExternalStoreWithSelector.ts","../src/createBundle.tsx"],"sourcesContent":["import { useCallback, useMemo, useRef } from \"react\";\n\n/**\n * @description This is to handle race conditions, so that our async operations that can\n * happen between re-renders will happen sequentially.\n * @date April 13, 2025\n */\nexport const useAsyncQueue = () => {\n const queueRef = useRef<Promise<void>>(Promise.resolve(undefined));\n\n const push = useCallback(async (promise: Promise<any>) => {\n queueRef.current = queueRef.current.then(async () => await promise);\n\n return await queueRef.current;\n }, []);\n\n return useMemo(() => ({ push }), [push]);\n};\n","import { useEffect, useRef, useState } from \"react\";\nimport fastDeepEqual from \"fast-deep-equal\";\n\nexport type UseDeepAsyncMemoResult<T extends unknown> =\n | {\n error: null;\n isInitialized: true;\n isLoading: false;\n value: T;\n }\n | {\n error: null;\n isInitialized: boolean;\n value: undefined;\n isLoading: true;\n }\n | {\n error: Error;\n isInitialized: boolean;\n value: undefined;\n isLoading: false;\n };\n\nexport const useDeepAsyncMemo = <T>(\n factory: () => Promise<T>,\n isEqual: (a: T, b: T) => boolean = fastDeepEqual,\n): UseDeepAsyncMemoResult<T> => {\n // Store the current async state (loading, value, error, etc.)\n const [state, setState] = useState<UseDeepAsyncMemoResult<T>>({\n isInitialized: false,\n isLoading: true,\n value: undefined,\n error: null,\n });\n\n // Keep track of the last resolved value to compare with new ones\n const lastValueRef = useRef<T | undefined>(undefined);\n const hasValueRef = useRef(false); // Tracks whether we've ever resolved a value\n\n // Tracks the current in-flight promise to guard against race conditions\n const inflightRef = useRef<Promise<T> | null>(null);\n\n // Used to prevent state updates after the component unmounts\n const isMountedRef = useRef(true);\n\n useEffect(() => {\n isMountedRef.current = true;\n\n // Trigger the async factory\n const promise = factory();\n inflightRef.current = promise;\n\n // Set loading state\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setState((prev) => {\n return {\n ...prev,\n isLoading: true,\n error: null,\n } as UseDeepAsyncMemoResult<T>;\n });\n\n promise\n .then((result) => {\n // Ignore if component unmounted or if this promise is stale\n if (!isMountedRef.current || inflightRef.current !== promise) return;\n\n // Skip update if value hasn't changed\n const isSame = hasValueRef.current && isEqual(lastValueRef.current as T, result);\n if (isSame) {\n setState((prev) => {\n return {\n ...prev,\n isInitialized: true,\n isLoading: false,\n } as UseDeepAsyncMemoResult<T>;\n });\n return;\n }\n\n // Save the new value\n lastValueRef.current = result;\n hasValueRef.current = true;\n\n setState({\n isInitialized: true,\n isLoading: false,\n value: result,\n error: null,\n });\n })\n .catch((err) => {\n // Ignore if component unmounted or if this promise is stale\n if (!isMountedRef.current || inflightRef.current !== promise) return;\n\n setState({\n isInitialized: hasValueRef.current,\n isLoading: false,\n value: undefined,\n error: err instanceof Error ? err : new Error(\"Unknown error\"),\n });\n });\n\n // Cleanup: prevent state updates after unmount\n return () => {\n isMountedRef.current = false;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n /**\n * !HACK\n * @description We're only going to use the `isEqual` function to determine if this hook\n * should re-run. This is basically our hook's version of a dependency array\n * @date April 13, 2025\n */\n // factory,\n isEqual,\n ]);\n\n return state;\n};\n","import { useCallback, useEffect, useState } from \"react\";\n\nexport type NoSsrFunction = <T = null>(value: T | (() => T), fallback?: T) => T;\n\nexport const useNoSsr = (): NoSsrFunction => {\n const [didMount, setDidMount] = useState<boolean>(false);\n\n // eslint-disable-next-line react-hooks/set-state-in-effect\n useEffect(() => setDidMount(typeof window !== \"undefined\"), []);\n\n const noSsr = useCallback(\n <T = null>(value: T | (() => T), fallback: T = null as T): T => {\n return didMount\n ? typeof value !== \"function\"\n ? value\n : (value as () => T)()\n : fallback;\n },\n [didMount],\n );\n\n return noSsr;\n};\n","import { useCallback, useState } from \"react\";\n\nexport const useRerender = (): (() => void) => {\n const [, setCount] = useState(0);\n\n return useCallback(() => {\n setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);\n }, []);\n};\n","export const identity = <T extends unknown>(x: T): T => x;\n","export const shallowArrayEqual = <T extends unknown>(\n a: readonly T[] | T[],\n b: readonly T[] | T[],\n): boolean => {\n return a.length === b.length && a.every((item, i) => item === b[i]);\n};\n","export const shallowEqual = (a: any, b: any): boolean => a === b;\n","import { useRef, useSyncExternalStore } from \"react\";\nimport { shallowEqual } from \"../utils\";\nimport { useNoSsr } from \"./useNoSsr\";\n\nexport const useSyncExternalStoreWithSelector = <TSnapshot, TSelection>(\n subscribe: (onStoreChange: () => void) => () => void,\n getClientSnapshot: () => TSnapshot,\n getServerSnapshot: undefined | null | (() => TSnapshot),\n selector: (snapshot: TSnapshot) => TSelection,\n isEqual?: (a: TSelection, b: TSelection) => boolean,\n): TSelection => {\n const noSsr = useNoSsr();\n const cacheRef = useRef<TSelection | null>(null);\n\n const _getServerSnapshot = getServerSnapshot\n ? () => {\n const data = getServerSnapshot();\n const snapshot = selector(data);\n const compare = isEqual ?? shallowEqual;\n const cached = cacheRef.current;\n\n const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);\n\n /**\n * !HACK\n * @description Memoize only the last snapshot so that we can only rerender on changes\n * @date June 22, 2024\n */\n cacheRef.current = isUnchanged ? (cached ?? snapshot) : snapshot;\n\n return cacheRef.current;\n }\n : undefined;\n\n const _getClientSnapshot = () => {\n const data = getClientSnapshot();\n const snapshot = selector(data);\n const compare = isEqual ?? shallowEqual;\n const cached = cacheRef.current;\n\n const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);\n\n /**\n * !HACK\n * @description Memoize only the last snapshot so that we can only rerender on changes\n * @date June 22, 2024\n */\n cacheRef.current = isUnchanged ? (cached ?? snapshot) : snapshot;\n\n return cacheRef.current;\n };\n\n const result = useSyncExternalStore(subscribe, _getClientSnapshot, _getServerSnapshot);\n\n // eslint-disable-next-line react-hooks/refs\n return typeof window !== \"undefined\" ? noSsr(result, _getServerSnapshot?.()) : result;\n};\n","import type {\n CreateRoomOptions,\n EnterRoomParams,\n MergeEvents,\n PluvClient,\n PluvRoom,\n PluvRoomAddon,\n PluvRouter,\n PluvRouterEventConfig,\n UserInfo,\n WebSocketConnection,\n} from \"@pluv/client\";\nimport { MockedRoom } from \"@pluv/client\";\nimport type { InferCrdtJson, InferDoc, InferStorage } from \"@pluv/crdt\";\nimport type {\n Id,\n InferIOCrdtKind,\n InferIOInput,\n InferIOOutput,\n IOEventMessage,\n IOLike,\n JsonObject,\n RoomLike,\n UpdateMyPresenceAction,\n} from \"@pluv/types\";\nimport fastDeepEqual from \"fast-deep-equal\";\nimport type { Dispatch } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport {\n identity,\n shallowArrayEqual,\n useAsyncQueue,\n useDeepAsyncMemo,\n useRerender,\n useSyncExternalStoreWithSelector,\n} from \"./internal\";\nimport type {\n BroadcastProxy,\n CreateBundle,\n EventProxy,\n MockedRoomProviderProps,\n PluvProviderProps,\n PluvRoomProviderProps,\n SubscriptionHookOptions,\n} from \"./types\";\n\nexport type CreateBundleOptions<\n TIO extends IOLike<any, any, any>,\n TMetadata extends JsonObject = {},\n TPresence extends Record<string, any> = {},\n TCrdt extends InferIOCrdtKind<TIO> = InferIOCrdtKind<TIO>,\n TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},\n> = {\n addons?: readonly PluvRoomAddon<TIO, TMetadata, TPresence, TCrdt>[];\n router?: PluvRouter<TIO, TPresence, InferStorage<TCrdt>, TEvents>;\n};\n\nexport const createBundle = <\n TIO extends IOLike<any, any, any>,\n TMetadata extends JsonObject = {},\n TPresence extends Record<string, any> = {},\n TCrdt extends InferIOCrdtKind<TIO> = InferIOCrdtKind<TIO>,\n TEvents extends PluvRouterEventConfig<TIO, TPresence, InferStorage<TCrdt>> = {},\n>(\n client: PluvClient<TIO, TPresence, TCrdt, TMetadata>,\n options: CreateBundleOptions<TIO, TMetadata, TPresence, TCrdt, TEvents> = {},\n): CreateBundle<TIO, TMetadata, TPresence, TCrdt, TEvents> => {\n /**\n * !HACK\n * @description We'll let the context error out if client is not provided,\n * and let the users deal with it.\n * @date October 27, 2022\n */\n const PluvContext = createContext<PluvClient<TIO, TPresence, TCrdt, TMetadata>>(null as any);\n\n /**\n * !HACK\n * @description We'll let the context error out if the room is not provided,\n * and let the users deal with it.\n * @date November 11, 2022\n */\n const PluvRoomContext = createContext<\n RoomLike<TIO, InferDoc<TCrdt>, TPresence, InferStorage<TCrdt>, TEvents>\n >(null as any);\n\n const MockedRoomContext = createContext<RoomLike<\n TIO,\n InferDoc<TCrdt>,\n TPresence,\n InferStorage<TCrdt>,\n TEvents\n > | null>(null);\n\n const MockedRoomProvider = memo<MockedRoomProviderProps<TIO, TPresence, TCrdt>>((props) => {\n const { children, events, initialPresence, initialStorage, room: _room } = props;\n\n const [room] = useState<MockedRoom<TIO, TPresence, TCrdt, TEvents>>(() => {\n return new MockedRoom<TIO, TPresence, TCrdt, TEvents>(_room, {\n events,\n initialPresence,\n initialStorage:\n typeof initialStorage === \"function\"\n ? (client._defs.initialStorage?.getFactory(initialStorage) as TCrdt)\n : undefined,\n });\n });\n\n return (\n <MockedRoomContext.Provider value={room}>\n <PluvRoomContext.Provider value={room}>{children}</PluvRoomContext.Provider>\n </MockedRoomContext.Provider>\n );\n });\n\n MockedRoomProvider.displayName = \"MockedRoomProvider\";\n\n const PluvRoomProvider = memo<PluvRoomProviderProps<TIO, TMetadata, TPresence, TCrdt>>(\n (props) => {\n const {\n children,\n connect = true,\n debug,\n initialPresence,\n initialStorage,\n metadata,\n onAuthorizationFail,\n room: _room,\n } = props;\n\n const queue = useAsyncQueue();\n const rerender = useRerender();\n const mockedRoom = useContext(MockedRoomContext);\n\n const createRoom = useCallback((): PluvRoom<\n TIO,\n TMetadata,\n TPresence,\n TCrdt,\n TEvents\n > => {\n return client.createRoom(_room, {\n addons: options.addons,\n debug,\n initialPresence,\n initialStorage:\n typeof initialStorage === \"function\"\n ? client._defs.initialStorage?.getFactory(initialStorage)\n : undefined,\n metadata,\n onAuthorizationFail,\n router: options.router,\n } as CreateRoomOptions<TIO, TPresence, TCrdt, TMetadata, TEvents>);\n }, [_room, debug, initialPresence, initialStorage, metadata, onAuthorizationFail]);\n\n const [room, setRoom] = useState(() => createRoom());\n\n useEffect(() => {\n if (room.id === _room) return;\n\n setRoom(createRoom());\n }, [_room, createRoom, room]);\n\n const resolvedMeta = useDeepAsyncMemo(async () => {\n const resolved = await Promise.resolve(\n typeof metadata === \"function\" ? metadata() : metadata,\n );\n\n return !!room.metadata ? room.metadata.parse(resolved) : resolved;\n });\n\n useEffect(() => {\n const unsubscribe = room.subscribe.connection(() => {\n rerender();\n });\n\n return () => {\n unsubscribe();\n };\n }, [rerender, room]);\n\n useEffect(() => {\n const leaveRoom = async (): Promise<void> => {\n await queue.push(\n client.leave(room).catch((error) => {\n console.error(error);\n }),\n );\n };\n\n if (!connect) {\n leaveRoom();\n return;\n }\n\n if (!resolvedMeta.isInitialized) {\n leaveRoom();\n return;\n }\n\n const resolved = resolvedMeta.value as TMetadata;\n\n queue.push(\n client\n .enter(room, ...([{ metadata: resolved }] as EnterRoomParams<TMetadata>))\n .catch(async (error) => {\n console.error(error);\n await leaveRoom();\n }),\n );\n\n return () => {\n leaveRoom();\n };\n }, [connect, queue, resolvedMeta.isInitialized, resolvedMeta.value, room]);\n\n return (\n <PluvRoomContext.Provider value={mockedRoom ?? room}>\n {children}\n </PluvRoomContext.Provider>\n );\n },\n );\n\n PluvRoomProvider.displayName = \"PluvRoomProvider\";\n\n const PluvProvider = memo<PluvProviderProps>((props) => {\n const { children } = props;\n\n return <PluvContext.Provider value={client}>{children}</PluvContext.Provider>;\n });\n\n PluvProvider.displayName = \"PluvProvider\";\n\n const useClient = (): PluvClient<TIO, TPresence, TCrdt, TMetadata> => useContext(PluvContext);\n\n const useRoom = () => {\n const room = useContext(PluvRoomContext);\n\n if (!room)\n throw new Error(\n \"Room could not be found. Component must be wrapped with PluvRoomProvider\",\n );\n\n return room;\n };\n\n const useBroadcast = (): BroadcastProxy<MergeEvents<TEvents, TIO>> => {\n const room = useRoom();\n\n const broadcast = useCallback(\n <TEvent extends keyof InferIOInput<MergeEvents<TEvents, TIO>>>(\n event: TEvent,\n data: Id<InferIOInput<MergeEvents<TEvents, TIO>>[TEvent]>,\n ) => {\n room.broadcast(event, data);\n },\n [room],\n );\n\n return useMemo((): BroadcastProxy<MergeEvents<TEvents, TIO>> => {\n return new Proxy(broadcast, {\n get(fn, prop) {\n return (\n data: Id<\n InferIOInput<MergeEvents<TEvents, TIO>>[keyof InferIOInput<\n MergeEvents<TEvents, TIO>\n >]\n >,\n ): void => {\n return fn(prop as keyof InferIOInput<MergeEvents<TEvents, TIO>>, data);\n };\n },\n }) as BroadcastProxy<MergeEvents<TEvents, TIO>>;\n }, [broadcast]);\n };\n\n const useCanRedo = (): boolean => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.storage(onStoreChange),\n [room],\n );\n\n const getSnapshot = useCallback((): boolean => room.canRedo(), [room]);\n\n const canRedo = useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n identity,\n );\n\n return canRedo;\n };\n\n const useCanUndo = (): boolean => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.storage(onStoreChange),\n [room],\n );\n\n const getSnapshot = useCallback((): boolean => room.canUndo(), [room]);\n\n const canUndo = useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n identity,\n );\n\n return canUndo;\n };\n\n const useConnection = <T extends unknown = WebSocketConnection>(\n selector = identity as (connection: WebSocketConnection) => T,\n options?: SubscriptionHookOptions<Id<T>>,\n ): Id<T> => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.connection(onStoreChange),\n [room],\n );\n\n const getSnapshot = room.getConnection;\n\n const _selector = useCallback(\n (snapshot: WebSocketConnection) => selector(snapshot) as Id<T>,\n [selector],\n );\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n _selector,\n options?.isEqual ?? fastDeepEqual,\n );\n };\n\n const useDoc = () => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.storageLoaded(onStoreChange),\n [room],\n );\n\n const getSnapshot = room.getDoc;\n\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\n };\n\n const useEvent = <TType extends keyof InferIOOutput<MergeEvents<TEvents, TIO>>>(\n type: TType,\n callback: (data: Id<IOEventMessage<MergeEvents<TEvents, TIO>, TType>>) => void,\n ): void => {\n const room = useRoom();\n\n useEffect(() => {\n const unsubscribe = room.subscribe.event(type, callback);\n\n return () => {\n unsubscribe();\n };\n }, [callback, room, type]);\n };\n\n const event = new Proxy(\n {},\n {\n get(_, prop) {\n const useProxyEvent = (\n callback: (\n data: Id<\n IOEventMessage<\n MergeEvents<TEvents, TIO>,\n keyof InferIOOutput<MergeEvents<TEvents, TIO>>\n >\n >,\n ) => void,\n ): void => {\n return useEvent(\n prop as keyof InferIOOutput<MergeEvents<TEvents, TIO>>,\n callback,\n );\n };\n\n return { useEvent: useProxyEvent };\n },\n },\n ) as EventProxy<MergeEvents<TEvents, TIO>>;\n\n const useMyPresence = <T extends unknown = TPresence>(\n selector = identity as (myPresence: TPresence) => T,\n options?: SubscriptionHookOptions<Id<T> | null>,\n ): [Id<T>, Dispatch<UpdateMyPresenceAction<TPresence>>] => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.myPresence(onStoreChange),\n [room],\n );\n\n const getSnapshot = room.getMyPresence;\n\n const _selector = useCallback(\n (snapshot: TPresence) => selector(snapshot) as Id<T>,\n [selector],\n );\n\n const myPresence = useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n _selector,\n options?.isEqual ?? fastDeepEqual,\n );\n\n return [myPresence, room.updateMyPresence];\n };\n\n const useMyself = <T extends unknown = UserInfo<TIO, TPresence>>(\n selector = identity as (myself: Id<UserInfo<TIO, TPresence>>) => T,\n options?: SubscriptionHookOptions<Id<T> | null>,\n ): Id<T> | null => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.myself(onStoreChange),\n [room],\n );\n\n const getSnapshot = room.getMyself;\n\n const _selector = useCallback(\n (snapshot: Id<UserInfo<TIO, TPresence>> | null) => {\n return !snapshot ? null : (selector(snapshot) as Id<T>);\n },\n [selector],\n );\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n _selector,\n options?.isEqual ?? fastDeepEqual,\n );\n };\n\n const useOther = <T extends unknown = UserInfo<TIO, TPresence>>(\n connectionId: string,\n selector = identity as (other: UserInfo<TIO, TPresence>) => T,\n options?: SubscriptionHookOptions<T | null>,\n ): T | null => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.other(connectionId, onStoreChange),\n [room, connectionId],\n );\n\n const getSnapshot = useCallback(() => room.getOther(connectionId), [room, connectionId]);\n\n const _selector = useCallback(\n (snapshot: Id<UserInfo<TIO, TPresence>> | null) => {\n return !snapshot ? null : (selector(snapshot) as T);\n },\n [selector],\n );\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n _selector,\n options?.isEqual ?? fastDeepEqual,\n );\n };\n\n const useOthers = <T extends unknown = readonly UserInfo<TIO, TPresence>[]>(\n selector = identity as (other: readonly Id<UserInfo<TIO, TPresence>>[]) => T,\n options?: SubscriptionHookOptions<T>,\n ): T => {\n const room = useRoom();\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.others(onStoreChange),\n [room],\n );\n\n const getSnapshot = room.getOthers;\n\n return useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n selector as (other: readonly Id<UserInfo<TIO, TPresence>>[]) => T,\n options?.isEqual ??\n ((a, b) => {\n /**\n * !HACK\n * @description Assume the return type will always be an array when this occurs\n * and do a shallow comparison instead like how standard React dependency\n * arrays work. This is for performance's sake and may lead to bugs if the\n * selector doesn't always return an array\n * @date June 22, 2024\n */\n if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {\n return shallowArrayEqual(a, b);\n }\n\n return fastDeepEqual(a, b);\n }),\n );\n };\n\n const useRedo = () => {\n const room = useRoom();\n\n return room.redo;\n };\n\n const useStorage = <\n TKey extends keyof InferStorage<TCrdt>,\n TData extends unknown = InferCrdtJson<InferStorage<TCrdt>[TKey]>,\n >(\n key: TKey,\n selector = identity as (data: InferCrdtJson<InferStorage<TCrdt>[TKey]>) => TData,\n options?: SubscriptionHookOptions<TData | null>,\n ): [data: TData | null, sharedType: InferStorage<TCrdt>[TKey] | null] => {\n const room = useRoom();\n const rerender = useRerender();\n\n useEffect(() => {\n const unsubscribe = room.subscribe.storageLoaded(() => {\n rerender();\n });\n\n return () => {\n unsubscribe();\n };\n }, [rerender, room]);\n\n const subscribe = useCallback(\n (onStoreChange: () => void) => room.subscribe.storage(key, onStoreChange),\n [key, room],\n );\n\n const getSnapshot = useCallback((): InferCrdtJson<InferStorage<TCrdt>[TKey]> | null => {\n return room.getStorageJson(key);\n }, [key, room]);\n\n const _selector = useCallback(\n (snapshot: InferCrdtJson<InferStorage<TCrdt>[TKey]> | null) => {\n return snapshot === null ? null : selector(snapshot);\n },\n [selector],\n );\n\n const data = useSyncExternalStoreWithSelector(\n subscribe,\n getSnapshot,\n getSnapshot,\n _selector,\n options?.isEqual ?? fastDeepEqual,\n );\n\n const sharedType = room.getStorage(key) ?? null;\n\n return [data, sharedType];\n };\n\n const useTransact = () => {\n const room = useRoom();\n\n return room.transact;\n };\n\n const useUndo = () => {\n const room = useRoom();\n\n return room.undo;\n };\n\n return {\n // components\n MockedRoomProvider,\n PluvProvider,\n PluvRoomProvider,\n\n // proxies\n event,\n\n // hooks\n useBroadcast,\n useCanRedo,\n useCanUndo,\n useClient,\n useConnection,\n useDoc,\n useEvent,\n useMyPresence,\n useMyself,\n useOther,\n useOthers,\n useRedo,\n useRoom,\n useStorage,\n useTransact,\n useUndo,\n };\n};\n"],"mappings":"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"}