@pluv/react 3.2.2 → 4.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/dist/index.js DELETED
@@ -1,596 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
- var __getProtoOf = Object.getPrototypeOf;
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));
25
- var __export = (target, all) => {
26
- for (var name in all)
27
- __defProp(target, name, { get: all[name], enumerable: true });
28
- };
29
- var __copyProps = (to, from, except, desc) => {
30
- if (from && typeof from === "object" || typeof from === "function") {
31
- for (let key of __getOwnPropNames(from))
32
- if (!__hasOwnProp.call(to, key) && key !== except)
33
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
- }
35
- return to;
36
- };
37
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
- // If the importer is in node compatibility mode or this is not an ESM
39
- // file that has been converted to a CommonJS file using a Babel-
40
- // compatible transform (i.e. "__esModule" has not been set), then set
41
- // "default" to the CommonJS "module.exports" for node compatibility.
42
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
- mod
44
- ));
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
- };
66
-
67
- // src/index.ts
68
- var index_exports = {};
69
- __export(index_exports, {
70
- createBundle: () => createBundle
71
- });
72
- module.exports = __toCommonJS(index_exports);
73
-
74
- // src/createBundle.tsx
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(null, null, function* () {
84
- queueRef.current = queueRef.current.then(() => __async(null, 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");
94
- var import_fast_deep_equal = __toESM(require("fast-deep-equal"));
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
- };
160
-
161
- // src/internal/hooks/useNoSsr.ts
162
- var import_react3 = require("react");
163
- var useNoSsr = () => {
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)(
167
- (value, fallback = null) => {
168
- return didMount ? typeof value !== "function" ? value : value() : fallback;
169
- },
170
- [didMount]
171
- );
172
- return noSsr;
173
- };
174
-
175
- // src/internal/hooks/useRerender.ts
176
- var import_react4 = require("react");
177
- var useRerender = () => {
178
- const [, setCount] = (0, import_react4.useState)(0);
179
- return (0, import_react4.useCallback)(() => {
180
- setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
181
- }, []);
182
- };
183
-
184
- // src/internal/hooks/useSyncExternalStoreWithSelector.ts
185
- var import_react5 = require("react");
186
-
187
- // src/internal/utils/identity.ts
188
- var identity = (x) => x;
189
-
190
- // src/internal/utils/shallowArrayEqual.ts
191
- var shallowArrayEqual = (a, b) => {
192
- return a.length === b.length && a.every((item, i) => item === b[i]);
193
- };
194
-
195
- // src/internal/utils/shallowEqual.ts
196
- var shallowEqual = (a, b) => a === b;
197
-
198
- // src/internal/hooks/useSyncExternalStoreWithSelector.ts
199
- var useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
200
- const noSsr = useNoSsr();
201
- const cacheRef = (0, import_react5.useRef)(null);
202
- const _getServerSnapshot = getServerSnapshot ? () => {
203
- const data = getServerSnapshot();
204
- const snapshot = selector(data);
205
- const compare = isEqual != null ? isEqual : shallowEqual;
206
- const cached = cacheRef.current;
207
- const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
208
- cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
209
- return cacheRef.current;
210
- } : void 0;
211
- const _getClientSnapshot = () => {
212
- const data = getClientSnapshot();
213
- const snapshot = selector(data);
214
- const compare = isEqual != null ? isEqual : shallowEqual;
215
- const cached = cacheRef.current;
216
- const isUnchanged = cached === null ? snapshot === null : compare(cached, snapshot);
217
- cacheRef.current = isUnchanged ? cached != null ? cached : snapshot : snapshot;
218
- return cacheRef.current;
219
- };
220
- const result = (0, import_react5.useSyncExternalStore)(subscribe, _getClientSnapshot, _getServerSnapshot);
221
- return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot == null ? void 0 : _getServerSnapshot()) : result;
222
- };
223
-
224
- // src/createBundle.tsx
225
- var import_jsx_runtime = require("react/jsx-runtime");
226
- var createBundle = (client, options = {}) => {
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) => {
231
- const { children, events, initialPresence, initialStorage, room: _room } = props;
232
- const [room] = (0, import_react6.useState)(() => {
233
- var _a;
234
- return new import_client.MockedRoom(_room, {
235
- events,
236
- initialPresence,
237
- initialStorage: typeof initialStorage === "function" ? (_a = client._defs.initialStorage) == null ? void 0 : _a.getFactory(initialStorage) : void 0
238
- });
239
- });
240
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MockedRoomContext.Provider, { value: room, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: room, children }) });
241
- });
242
- MockedRoomProvider.displayName = "MockedRoomProvider";
243
- const PluvRoomProvider = (0, import_react6.memo)(
244
- (props) => {
245
- const {
246
- children,
247
- connect = true,
248
- debug,
249
- initialPresence,
250
- initialStorage,
251
- metadata,
252
- onAuthorizationFail,
253
- room: _room
254
- } = props;
255
- const queue = useAsyncQueue();
256
- const rerender = useRerender();
257
- const mockedRoom = (0, import_react6.useContext)(MockedRoomContext);
258
- const resolvedMeta = useDeepAsyncMemo(() => __async(null, null, function* () {
259
- const resolved = yield Promise.resolve(
260
- typeof metadata === "function" ? metadata() : metadata
261
- );
262
- return !!room.metadata ? room.metadata.parse(resolved) : resolved;
263
- }));
264
- const createRoom = (0, import_react6.useCallback)(() => {
265
- var _a;
266
- return client.createRoom(_room, {
267
- addons: options.addons,
268
- debug,
269
- initialPresence,
270
- initialStorage: typeof initialStorage === "function" ? (_a = client._defs.initialStorage) == null ? void 0 : _a.getFactory(initialStorage) : void 0,
271
- metadata,
272
- onAuthorizationFail,
273
- router: options.router
274
- });
275
- }, [_room, debug, initialPresence, initialStorage, metadata, onAuthorizationFail]);
276
- const [room, setRoom] = (0, import_react6.useState)(() => createRoom());
277
- (0, import_react6.useEffect)(() => {
278
- if (room.id === _room) return;
279
- setRoom(createRoom());
280
- }, [_room, createRoom, room]);
281
- (0, import_react6.useEffect)(() => {
282
- const unsubscribe = room.subscribe.connection(() => {
283
- rerender();
284
- });
285
- return () => {
286
- unsubscribe();
287
- };
288
- }, [rerender, room]);
289
- (0, import_react6.useEffect)(() => {
290
- const leaveRoom = () => __async(null, null, function* () {
291
- yield queue.push(
292
- client.leave(room).catch((error) => {
293
- console.error(error);
294
- })
295
- );
296
- });
297
- if (!connect) {
298
- leaveRoom();
299
- return;
300
- }
301
- if (!resolvedMeta.isInitialized) {
302
- leaveRoom();
303
- return;
304
- }
305
- const resolved = resolvedMeta.value;
306
- queue.push(
307
- client.enter(room, ...[{ metadata: resolved }]).catch((error) => __async(null, null, function* () {
308
- console.error(error);
309
- yield leaveRoom();
310
- }))
311
- );
312
- return () => {
313
- leaveRoom();
314
- };
315
- }, [connect, queue, resolvedMeta.isInitialized, resolvedMeta.value, room]);
316
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvRoomContext.Provider, { value: mockedRoom != null ? mockedRoom : room, children });
317
- }
318
- );
319
- PluvRoomProvider.displayName = "PluvRoomProvider";
320
- const PluvProvider = (0, import_react6.memo)((props) => {
321
- const { children } = props;
322
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PluvContext.Provider, { value: client, children });
323
- });
324
- PluvProvider.displayName = "PluvProvider";
325
- const useClient = () => (0, import_react6.useContext)(PluvContext);
326
- const useRoom = () => {
327
- const room = (0, import_react6.useContext)(PluvRoomContext);
328
- if (!room)
329
- throw new Error(
330
- "Room could not be found. Component must be wrapped with PluvRoomProvider"
331
- );
332
- return room;
333
- };
334
- const useBroadcast = () => {
335
- const room = useRoom();
336
- const broadcast = (0, import_react6.useCallback)(
337
- (event2, data) => {
338
- room.broadcast(event2, data);
339
- },
340
- [room]
341
- );
342
- return (0, import_react6.useMemo)(() => {
343
- return new Proxy(broadcast, {
344
- get(fn, prop) {
345
- return (data) => {
346
- return fn(prop, data);
347
- };
348
- }
349
- });
350
- }, [broadcast]);
351
- };
352
- const useCanRedo = () => {
353
- const room = useRoom();
354
- const subscribe = (0, import_react6.useCallback)(
355
- (onStoreChange) => room.subscribe.storage(onStoreChange),
356
- [room]
357
- );
358
- const getSnapshot = (0, import_react6.useCallback)(() => room.canRedo(), [room]);
359
- const canRedo = useSyncExternalStoreWithSelector(
360
- subscribe,
361
- getSnapshot,
362
- getSnapshot,
363
- identity
364
- );
365
- return canRedo;
366
- };
367
- const useCanUndo = () => {
368
- const room = useRoom();
369
- const subscribe = (0, import_react6.useCallback)(
370
- (onStoreChange) => room.subscribe.storage(onStoreChange),
371
- [room]
372
- );
373
- const getSnapshot = (0, import_react6.useCallback)(() => room.canUndo(), [room]);
374
- const canUndo = useSyncExternalStoreWithSelector(
375
- subscribe,
376
- getSnapshot,
377
- getSnapshot,
378
- identity
379
- );
380
- return canUndo;
381
- };
382
- const useConnection = (selector = identity, options2) => {
383
- var _a;
384
- const room = useRoom();
385
- const subscribe = (0, import_react6.useCallback)(
386
- (onStoreChange) => room.subscribe.connection(onStoreChange),
387
- [room]
388
- );
389
- const getSnapshot = room.getConnection;
390
- const _selector = (0, import_react6.useCallback)(
391
- (snapshot) => selector(snapshot),
392
- [selector]
393
- );
394
- return useSyncExternalStoreWithSelector(
395
- subscribe,
396
- getSnapshot,
397
- getSnapshot,
398
- _selector,
399
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
400
- );
401
- };
402
- const useDoc = () => {
403
- const room = useRoom();
404
- const subscribe = (0, import_react6.useCallback)(
405
- (onStoreChange) => room.subscribe.storageLoaded(onStoreChange),
406
- [room]
407
- );
408
- const getSnapshot = room.getDoc;
409
- return (0, import_react6.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
410
- };
411
- const useEvent = (type, callback) => {
412
- const room = useRoom();
413
- (0, import_react6.useEffect)(() => {
414
- const unsubscribe = room.subscribe.event(type, callback);
415
- return () => {
416
- unsubscribe();
417
- };
418
- }, [callback, room, type]);
419
- };
420
- const event = new Proxy(
421
- {},
422
- {
423
- get(_, prop) {
424
- const useProxyEvent = (callback) => {
425
- return useEvent(
426
- prop,
427
- callback
428
- );
429
- };
430
- return { useEvent: useProxyEvent };
431
- }
432
- }
433
- );
434
- const useMyPresence = (selector = identity, options2) => {
435
- var _a;
436
- const room = useRoom();
437
- const subscribe = (0, import_react6.useCallback)(
438
- (onStoreChange) => room.subscribe.myPresence(onStoreChange),
439
- [room]
440
- );
441
- const getSnapshot = room.getMyPresence;
442
- const _selector = (0, import_react6.useCallback)(
443
- (snapshot) => selector(snapshot),
444
- [selector]
445
- );
446
- const myPresence = useSyncExternalStoreWithSelector(
447
- subscribe,
448
- getSnapshot,
449
- getSnapshot,
450
- _selector,
451
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
452
- );
453
- return [myPresence, room.updateMyPresence];
454
- };
455
- const useMyself = (selector = identity, options2) => {
456
- var _a;
457
- const room = useRoom();
458
- const subscribe = (0, import_react6.useCallback)(
459
- (onStoreChange) => room.subscribe.myself(onStoreChange),
460
- [room]
461
- );
462
- const getSnapshot = room.getMyself;
463
- const _selector = (0, import_react6.useCallback)(
464
- (snapshot) => {
465
- return !snapshot ? null : selector(snapshot);
466
- },
467
- [selector]
468
- );
469
- return useSyncExternalStoreWithSelector(
470
- subscribe,
471
- getSnapshot,
472
- getSnapshot,
473
- _selector,
474
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
475
- );
476
- };
477
- const useOther = (connectionId, selector = identity, options2) => {
478
- var _a;
479
- const room = useRoom();
480
- const subscribe = (0, import_react6.useCallback)(
481
- (onStoreChange) => room.subscribe.other(connectionId, onStoreChange),
482
- [room, connectionId]
483
- );
484
- const getSnapshot = (0, import_react6.useCallback)(() => room.getOther(connectionId), [room, connectionId]);
485
- const _selector = (0, import_react6.useCallback)(
486
- (snapshot) => {
487
- return !snapshot ? null : selector(snapshot);
488
- },
489
- [selector]
490
- );
491
- return useSyncExternalStoreWithSelector(
492
- subscribe,
493
- getSnapshot,
494
- getSnapshot,
495
- _selector,
496
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
497
- );
498
- };
499
- const useOthers = (selector = identity, options2) => {
500
- var _a;
501
- const room = useRoom();
502
- const subscribe = (0, import_react6.useCallback)(
503
- (onStoreChange) => room.subscribe.others(onStoreChange),
504
- [room]
505
- );
506
- const getSnapshot = room.getOthers;
507
- return useSyncExternalStoreWithSelector(
508
- subscribe,
509
- getSnapshot,
510
- getSnapshot,
511
- selector,
512
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : (a, b) => {
513
- if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
514
- return shallowArrayEqual(a, b);
515
- }
516
- return (0, import_fast_deep_equal2.default)(a, b);
517
- }
518
- );
519
- };
520
- const useRedo = () => {
521
- const room = useRoom();
522
- return room.redo;
523
- };
524
- const useStorage = (key, selector = identity, options2) => {
525
- var _a, _b;
526
- const room = useRoom();
527
- const rerender = useRerender();
528
- (0, import_react6.useEffect)(() => {
529
- const unsubscribe = room.subscribe.storageLoaded(() => {
530
- rerender();
531
- });
532
- return () => {
533
- unsubscribe();
534
- };
535
- }, [rerender, room]);
536
- const subscribe = (0, import_react6.useCallback)(
537
- (onStoreChange) => room.subscribe.storage(key, onStoreChange),
538
- [key, room]
539
- );
540
- const getSnapshot = (0, import_react6.useCallback)(() => {
541
- return room.getStorageJson(key);
542
- }, [key, room]);
543
- const _selector = (0, import_react6.useCallback)(
544
- (snapshot) => {
545
- return snapshot === null ? null : selector(snapshot);
546
- },
547
- [selector]
548
- );
549
- const data = useSyncExternalStoreWithSelector(
550
- subscribe,
551
- getSnapshot,
552
- getSnapshot,
553
- _selector,
554
- (_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : import_fast_deep_equal2.default
555
- );
556
- const sharedType = (_b = room.getStorage(key)) != null ? _b : null;
557
- return [data, sharedType];
558
- };
559
- const useTransact = () => {
560
- const room = useRoom();
561
- return room.transact;
562
- };
563
- const useUndo = () => {
564
- const room = useRoom();
565
- return room.undo;
566
- };
567
- return {
568
- // components
569
- MockedRoomProvider,
570
- PluvProvider,
571
- PluvRoomProvider,
572
- // proxies
573
- event,
574
- // hooks
575
- useBroadcast,
576
- useCanRedo,
577
- useCanUndo,
578
- useClient,
579
- useConnection,
580
- useDoc,
581
- useEvent,
582
- useMyPresence,
583
- useMyself,
584
- useOther,
585
- useOthers,
586
- useRedo,
587
- useRoom,
588
- useStorage,
589
- useTransact,
590
- useUndo
591
- };
592
- };
593
- // Annotate the CommonJS export names for ESM import in node:
594
- 0 && (module.exports = {
595
- createBundle
596
- });