@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/.turbo/turbo-build.log +16 -16
- package/CHANGELOG.md +28 -0
- package/dist/index.d.mts +48 -49
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +408 -554
- package/dist/index.mjs.map +1 -0
- package/package.json +20 -16
- package/src/createBundle.tsx +9 -8
- package/src/internal/hooks/useNoSsr.ts +1 -0
- package/src/internal/hooks/useSyncExternalStoreWithSelector.ts +1 -0
- package/tsdown.config.ts +15 -0
- package/dist/index.d.ts +0 -72
- package/dist/index.js +0 -596
package/dist/index.mjs
CHANGED
|
@@ -1,571 +1,425 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __defProps = Object.defineProperties;
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __async = (__this, __arguments, generator) => {
|
|
21
|
-
return new Promise((resolve, reject) => {
|
|
22
|
-
var fulfilled = (value) => {
|
|
23
|
-
try {
|
|
24
|
-
step(generator.next(value));
|
|
25
|
-
} catch (e) {
|
|
26
|
-
reject(e);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var rejected = (value) => {
|
|
30
|
-
try {
|
|
31
|
-
step(generator.throw(value));
|
|
32
|
-
} catch (e) {
|
|
33
|
-
reject(e);
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
37
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
38
|
-
});
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
// src/createBundle.tsx
|
|
42
1
|
import { MockedRoom } from "@pluv/client";
|
|
43
|
-
import
|
|
44
|
-
import {
|
|
45
|
-
|
|
46
|
-
memo,
|
|
47
|
-
useCallback as useCallback4,
|
|
48
|
-
useContext,
|
|
49
|
-
useEffect as useEffect3,
|
|
50
|
-
useMemo as useMemo2,
|
|
51
|
-
useState as useState4,
|
|
52
|
-
useSyncExternalStore as useSyncExternalStore2
|
|
53
|
-
} from "react";
|
|
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";
|
|
54
5
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
6
|
+
//#region src/internal/hooks/useAsyncQueue.ts
|
|
7
|
+
/**
|
|
8
|
+
* @description This is to handle race conditions, so that our async operations that can
|
|
9
|
+
* happen between re-renders will happen sequentially.
|
|
10
|
+
* @date April 13, 2025
|
|
11
|
+
*/
|
|
12
|
+
const useAsyncQueue = () => {
|
|
13
|
+
const queueRef = useRef(Promise.resolve(void 0));
|
|
14
|
+
const push = useCallback(async (promise) => {
|
|
15
|
+
queueRef.current = queueRef.current.then(async () => await promise);
|
|
16
|
+
return await queueRef.current;
|
|
17
|
+
}, []);
|
|
18
|
+
return useMemo(() => ({ push }), [push]);
|
|
66
19
|
};
|
|
67
20
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* !HACK
|
|
127
|
-
* @description We're only going to use the `isEqual` function to determine if this hook
|
|
128
|
-
* should re-run. This is basically our hook's version of a dependency array
|
|
129
|
-
* @date April 13, 2025
|
|
130
|
-
*/
|
|
131
|
-
// factory,
|
|
132
|
-
isEqual
|
|
133
|
-
]);
|
|
134
|
-
return state;
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/internal/hooks/useDeepAsyncMemo.ts
|
|
23
|
+
const useDeepAsyncMemo = (factory, isEqual = fastDeepEqual) => {
|
|
24
|
+
const [state, setState] = useState({
|
|
25
|
+
isInitialized: false,
|
|
26
|
+
isLoading: true,
|
|
27
|
+
value: void 0,
|
|
28
|
+
error: null
|
|
29
|
+
});
|
|
30
|
+
const lastValueRef = useRef(void 0);
|
|
31
|
+
const hasValueRef = useRef(false);
|
|
32
|
+
const inflightRef = useRef(null);
|
|
33
|
+
const isMountedRef = useRef(true);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
isMountedRef.current = true;
|
|
36
|
+
const promise = factory();
|
|
37
|
+
inflightRef.current = promise;
|
|
38
|
+
setState((prev) => {
|
|
39
|
+
return {
|
|
40
|
+
...prev,
|
|
41
|
+
isLoading: true,
|
|
42
|
+
error: null
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
promise.then((result) => {
|
|
46
|
+
if (!isMountedRef.current || inflightRef.current !== promise) return;
|
|
47
|
+
if (hasValueRef.current && isEqual(lastValueRef.current, result)) {
|
|
48
|
+
setState((prev) => {
|
|
49
|
+
return {
|
|
50
|
+
...prev,
|
|
51
|
+
isInitialized: true,
|
|
52
|
+
isLoading: false
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
lastValueRef.current = result;
|
|
58
|
+
hasValueRef.current = true;
|
|
59
|
+
setState({
|
|
60
|
+
isInitialized: true,
|
|
61
|
+
isLoading: false,
|
|
62
|
+
value: result,
|
|
63
|
+
error: null
|
|
64
|
+
});
|
|
65
|
+
}).catch((err) => {
|
|
66
|
+
if (!isMountedRef.current || inflightRef.current !== promise) return;
|
|
67
|
+
setState({
|
|
68
|
+
isInitialized: hasValueRef.current,
|
|
69
|
+
isLoading: false,
|
|
70
|
+
value: void 0,
|
|
71
|
+
error: err instanceof Error ? err : /* @__PURE__ */ new Error("Unknown error")
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
return () => {
|
|
75
|
+
isMountedRef.current = false;
|
|
76
|
+
};
|
|
77
|
+
}, [isEqual]);
|
|
78
|
+
return state;
|
|
135
79
|
};
|
|
136
80
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
},
|
|
146
|
-
[didMount]
|
|
147
|
-
);
|
|
148
|
-
return noSsr;
|
|
81
|
+
//#endregion
|
|
82
|
+
//#region src/internal/hooks/useNoSsr.ts
|
|
83
|
+
const useNoSsr = () => {
|
|
84
|
+
const [didMount, setDidMount] = useState(false);
|
|
85
|
+
useEffect(() => setDidMount(typeof window !== "undefined"), []);
|
|
86
|
+
return useCallback((value, fallback = null) => {
|
|
87
|
+
return didMount ? typeof value !== "function" ? value : value() : fallback;
|
|
88
|
+
}, [didMount]);
|
|
149
89
|
};
|
|
150
90
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
91
|
+
//#endregion
|
|
92
|
+
//#region src/internal/hooks/useRerender.ts
|
|
93
|
+
const useRerender = () => {
|
|
94
|
+
const [, setCount] = useState(0);
|
|
95
|
+
return useCallback(() => {
|
|
96
|
+
setCount((oldCount) => (oldCount + 1) % Number.MAX_SAFE_INTEGER);
|
|
97
|
+
}, []);
|
|
158
98
|
};
|
|
159
99
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
// src/internal/utils/identity.ts
|
|
164
|
-
var identity = (x) => x;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/internal/utils/identity.ts
|
|
102
|
+
const identity = (x) => x;
|
|
165
103
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
104
|
+
//#endregion
|
|
105
|
+
//#region src/internal/utils/shallowArrayEqual.ts
|
|
106
|
+
const shallowArrayEqual = (a, b) => {
|
|
107
|
+
return a.length === b.length && a.every((item, i) => item === b[i]);
|
|
169
108
|
};
|
|
170
109
|
|
|
171
|
-
|
|
172
|
-
|
|
110
|
+
//#endregion
|
|
111
|
+
//#region src/internal/utils/shallowEqual.ts
|
|
112
|
+
const shallowEqual = (a, b) => a === b;
|
|
173
113
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
114
|
+
//#endregion
|
|
115
|
+
//#region src/internal/hooks/useSyncExternalStoreWithSelector.ts
|
|
116
|
+
const useSyncExternalStoreWithSelector = (subscribe, getClientSnapshot, getServerSnapshot, selector, isEqual) => {
|
|
117
|
+
const noSsr = useNoSsr();
|
|
118
|
+
const cacheRef = useRef(null);
|
|
119
|
+
const _getServerSnapshot = getServerSnapshot ? () => {
|
|
120
|
+
const snapshot = selector(getServerSnapshot());
|
|
121
|
+
const compare = isEqual ?? shallowEqual;
|
|
122
|
+
const cached = cacheRef.current;
|
|
123
|
+
/**
|
|
124
|
+
* !HACK
|
|
125
|
+
* @description Memoize only the last snapshot so that we can only rerender on changes
|
|
126
|
+
* @date June 22, 2024
|
|
127
|
+
*/
|
|
128
|
+
cacheRef.current = (cached === null ? snapshot === null : compare(cached, snapshot)) ? cached ?? snapshot : snapshot;
|
|
129
|
+
return cacheRef.current;
|
|
130
|
+
} : void 0;
|
|
131
|
+
const _getClientSnapshot = () => {
|
|
132
|
+
const snapshot = selector(getClientSnapshot());
|
|
133
|
+
const compare = isEqual ?? shallowEqual;
|
|
134
|
+
const cached = cacheRef.current;
|
|
135
|
+
/**
|
|
136
|
+
* !HACK
|
|
137
|
+
* @description Memoize only the last snapshot so that we can only rerender on changes
|
|
138
|
+
* @date June 22, 2024
|
|
139
|
+
*/
|
|
140
|
+
cacheRef.current = (cached === null ? snapshot === null : compare(cached, snapshot)) ? cached ?? snapshot : snapshot;
|
|
141
|
+
return cacheRef.current;
|
|
142
|
+
};
|
|
143
|
+
const result = useSyncExternalStore(subscribe, _getClientSnapshot, _getServerSnapshot);
|
|
144
|
+
return typeof window !== "undefined" ? noSsr(result, _getServerSnapshot?.()) : result;
|
|
198
145
|
};
|
|
199
146
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
};
|
|
475
|
-
const useOthers = (selector = identity, options2) => {
|
|
476
|
-
var _a;
|
|
477
|
-
const room = useRoom();
|
|
478
|
-
const subscribe = useCallback4(
|
|
479
|
-
(onStoreChange) => room.subscribe.others(onStoreChange),
|
|
480
|
-
[room]
|
|
481
|
-
);
|
|
482
|
-
const getSnapshot = room.getOthers;
|
|
483
|
-
return useSyncExternalStoreWithSelector(
|
|
484
|
-
subscribe,
|
|
485
|
-
getSnapshot,
|
|
486
|
-
getSnapshot,
|
|
487
|
-
selector,
|
|
488
|
-
(_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : (a, b) => {
|
|
489
|
-
if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
|
|
490
|
-
return shallowArrayEqual(a, b);
|
|
491
|
-
}
|
|
492
|
-
return fastDeepEqual2(a, b);
|
|
493
|
-
}
|
|
494
|
-
);
|
|
495
|
-
};
|
|
496
|
-
const useRedo = () => {
|
|
497
|
-
const room = useRoom();
|
|
498
|
-
return room.redo;
|
|
499
|
-
};
|
|
500
|
-
const useStorage = (key, selector = identity, options2) => {
|
|
501
|
-
var _a, _b;
|
|
502
|
-
const room = useRoom();
|
|
503
|
-
const rerender = useRerender();
|
|
504
|
-
useEffect3(() => {
|
|
505
|
-
const unsubscribe = room.subscribe.storageLoaded(() => {
|
|
506
|
-
rerender();
|
|
507
|
-
});
|
|
508
|
-
return () => {
|
|
509
|
-
unsubscribe();
|
|
510
|
-
};
|
|
511
|
-
}, [rerender, room]);
|
|
512
|
-
const subscribe = useCallback4(
|
|
513
|
-
(onStoreChange) => room.subscribe.storage(key, onStoreChange),
|
|
514
|
-
[key, room]
|
|
515
|
-
);
|
|
516
|
-
const getSnapshot = useCallback4(() => {
|
|
517
|
-
return room.getStorageJson(key);
|
|
518
|
-
}, [key, room]);
|
|
519
|
-
const _selector = useCallback4(
|
|
520
|
-
(snapshot) => {
|
|
521
|
-
return snapshot === null ? null : selector(snapshot);
|
|
522
|
-
},
|
|
523
|
-
[selector]
|
|
524
|
-
);
|
|
525
|
-
const data = useSyncExternalStoreWithSelector(
|
|
526
|
-
subscribe,
|
|
527
|
-
getSnapshot,
|
|
528
|
-
getSnapshot,
|
|
529
|
-
_selector,
|
|
530
|
-
(_a = options2 == null ? void 0 : options2.isEqual) != null ? _a : fastDeepEqual2
|
|
531
|
-
);
|
|
532
|
-
const sharedType = (_b = room.getStorage(key)) != null ? _b : null;
|
|
533
|
-
return [data, sharedType];
|
|
534
|
-
};
|
|
535
|
-
const useTransact = () => {
|
|
536
|
-
const room = useRoom();
|
|
537
|
-
return room.transact;
|
|
538
|
-
};
|
|
539
|
-
const useUndo = () => {
|
|
540
|
-
const room = useRoom();
|
|
541
|
-
return room.undo;
|
|
542
|
-
};
|
|
543
|
-
return {
|
|
544
|
-
// components
|
|
545
|
-
MockedRoomProvider,
|
|
546
|
-
PluvProvider,
|
|
547
|
-
PluvRoomProvider,
|
|
548
|
-
// proxies
|
|
549
|
-
event,
|
|
550
|
-
// hooks
|
|
551
|
-
useBroadcast,
|
|
552
|
-
useCanRedo,
|
|
553
|
-
useCanUndo,
|
|
554
|
-
useClient,
|
|
555
|
-
useConnection,
|
|
556
|
-
useDoc,
|
|
557
|
-
useEvent,
|
|
558
|
-
useMyPresence,
|
|
559
|
-
useMyself,
|
|
560
|
-
useOther,
|
|
561
|
-
useOthers,
|
|
562
|
-
useRedo,
|
|
563
|
-
useRoom,
|
|
564
|
-
useStorage,
|
|
565
|
-
useTransact,
|
|
566
|
-
useUndo
|
|
567
|
-
};
|
|
568
|
-
};
|
|
569
|
-
export {
|
|
570
|
-
createBundle
|
|
147
|
+
//#endregion
|
|
148
|
+
//#region src/createBundle.tsx
|
|
149
|
+
const createBundle = (client, options = {}) => {
|
|
150
|
+
/**
|
|
151
|
+
* !HACK
|
|
152
|
+
* @description We'll let the context error out if client is not provided,
|
|
153
|
+
* and let the users deal with it.
|
|
154
|
+
* @date October 27, 2022
|
|
155
|
+
*/
|
|
156
|
+
const PluvContext = createContext(null);
|
|
157
|
+
/**
|
|
158
|
+
* !HACK
|
|
159
|
+
* @description We'll let the context error out if the room is not provided,
|
|
160
|
+
* and let the users deal with it.
|
|
161
|
+
* @date November 11, 2022
|
|
162
|
+
*/
|
|
163
|
+
const PluvRoomContext = createContext(null);
|
|
164
|
+
const MockedRoomContext = createContext(null);
|
|
165
|
+
const MockedRoomProvider = memo((props) => {
|
|
166
|
+
const { children, events, initialPresence, initialStorage, room: _room } = props;
|
|
167
|
+
const [room] = useState(() => {
|
|
168
|
+
return new MockedRoom(_room, {
|
|
169
|
+
events,
|
|
170
|
+
initialPresence,
|
|
171
|
+
initialStorage: typeof initialStorage === "function" ? client._defs.initialStorage?.getFactory(initialStorage) : void 0
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
return /* @__PURE__ */ jsx(MockedRoomContext.Provider, {
|
|
175
|
+
value: room,
|
|
176
|
+
children: /* @__PURE__ */ jsx(PluvRoomContext.Provider, {
|
|
177
|
+
value: room,
|
|
178
|
+
children
|
|
179
|
+
})
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
MockedRoomProvider.displayName = "MockedRoomProvider";
|
|
183
|
+
const PluvRoomProvider = memo((props) => {
|
|
184
|
+
const { children, connect = true, debug, initialPresence, initialStorage, metadata, onAuthorizationFail, room: _room } = props;
|
|
185
|
+
const queue = useAsyncQueue();
|
|
186
|
+
const rerender = useRerender();
|
|
187
|
+
const mockedRoom = useContext(MockedRoomContext);
|
|
188
|
+
const createRoom = useCallback(() => {
|
|
189
|
+
return client.createRoom(_room, {
|
|
190
|
+
addons: options.addons,
|
|
191
|
+
debug,
|
|
192
|
+
initialPresence,
|
|
193
|
+
initialStorage: typeof initialStorage === "function" ? client._defs.initialStorage?.getFactory(initialStorage) : void 0,
|
|
194
|
+
metadata,
|
|
195
|
+
onAuthorizationFail,
|
|
196
|
+
router: options.router
|
|
197
|
+
});
|
|
198
|
+
}, [
|
|
199
|
+
_room,
|
|
200
|
+
debug,
|
|
201
|
+
initialPresence,
|
|
202
|
+
initialStorage,
|
|
203
|
+
metadata,
|
|
204
|
+
onAuthorizationFail
|
|
205
|
+
]);
|
|
206
|
+
const [room, setRoom] = useState(() => createRoom());
|
|
207
|
+
useEffect(() => {
|
|
208
|
+
if (room.id === _room) return;
|
|
209
|
+
setRoom(createRoom());
|
|
210
|
+
}, [
|
|
211
|
+
_room,
|
|
212
|
+
createRoom,
|
|
213
|
+
room
|
|
214
|
+
]);
|
|
215
|
+
const resolvedMeta = useDeepAsyncMemo(async () => {
|
|
216
|
+
const resolved = await Promise.resolve(typeof metadata === "function" ? metadata() : metadata);
|
|
217
|
+
return !!room.metadata ? room.metadata.parse(resolved) : resolved;
|
|
218
|
+
});
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
const unsubscribe = room.subscribe.connection(() => {
|
|
221
|
+
rerender();
|
|
222
|
+
});
|
|
223
|
+
return () => {
|
|
224
|
+
unsubscribe();
|
|
225
|
+
};
|
|
226
|
+
}, [rerender, room]);
|
|
227
|
+
useEffect(() => {
|
|
228
|
+
const leaveRoom = async () => {
|
|
229
|
+
await queue.push(client.leave(room).catch((error) => {
|
|
230
|
+
console.error(error);
|
|
231
|
+
}));
|
|
232
|
+
};
|
|
233
|
+
if (!connect) {
|
|
234
|
+
leaveRoom();
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
if (!resolvedMeta.isInitialized) {
|
|
238
|
+
leaveRoom();
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const resolved = resolvedMeta.value;
|
|
242
|
+
queue.push(client.enter(room, ...[{ metadata: resolved }]).catch(async (error) => {
|
|
243
|
+
console.error(error);
|
|
244
|
+
await leaveRoom();
|
|
245
|
+
}));
|
|
246
|
+
return () => {
|
|
247
|
+
leaveRoom();
|
|
248
|
+
};
|
|
249
|
+
}, [
|
|
250
|
+
connect,
|
|
251
|
+
queue,
|
|
252
|
+
resolvedMeta.isInitialized,
|
|
253
|
+
resolvedMeta.value,
|
|
254
|
+
room
|
|
255
|
+
]);
|
|
256
|
+
return /* @__PURE__ */ jsx(PluvRoomContext.Provider, {
|
|
257
|
+
value: mockedRoom ?? room,
|
|
258
|
+
children
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
PluvRoomProvider.displayName = "PluvRoomProvider";
|
|
262
|
+
const PluvProvider = memo((props) => {
|
|
263
|
+
const { children } = props;
|
|
264
|
+
return /* @__PURE__ */ jsx(PluvContext.Provider, {
|
|
265
|
+
value: client,
|
|
266
|
+
children
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
PluvProvider.displayName = "PluvProvider";
|
|
270
|
+
const useClient = () => useContext(PluvContext);
|
|
271
|
+
const useRoom = () => {
|
|
272
|
+
const room = useContext(PluvRoomContext);
|
|
273
|
+
if (!room) throw new Error("Room could not be found. Component must be wrapped with PluvRoomProvider");
|
|
274
|
+
return room;
|
|
275
|
+
};
|
|
276
|
+
const useBroadcast = () => {
|
|
277
|
+
const room = useRoom();
|
|
278
|
+
const broadcast = useCallback((event$1, data) => {
|
|
279
|
+
room.broadcast(event$1, data);
|
|
280
|
+
}, [room]);
|
|
281
|
+
return useMemo(() => {
|
|
282
|
+
return new Proxy(broadcast, { get(fn, prop) {
|
|
283
|
+
return (data) => {
|
|
284
|
+
return fn(prop, data);
|
|
285
|
+
};
|
|
286
|
+
} });
|
|
287
|
+
}, [broadcast]);
|
|
288
|
+
};
|
|
289
|
+
const useCanRedo = () => {
|
|
290
|
+
const room = useRoom();
|
|
291
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.storage(onStoreChange), [room]);
|
|
292
|
+
const getSnapshot = useCallback(() => room.canRedo(), [room]);
|
|
293
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
|
|
294
|
+
};
|
|
295
|
+
const useCanUndo = () => {
|
|
296
|
+
const room = useRoom();
|
|
297
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.storage(onStoreChange), [room]);
|
|
298
|
+
const getSnapshot = useCallback(() => room.canUndo(), [room]);
|
|
299
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, identity);
|
|
300
|
+
};
|
|
301
|
+
const useConnection = (selector = identity, options$1) => {
|
|
302
|
+
const room = useRoom();
|
|
303
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.connection(onStoreChange), [room]);
|
|
304
|
+
const getSnapshot = room.getConnection;
|
|
305
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => selector(snapshot), [selector]), options$1?.isEqual ?? fastDeepEqual);
|
|
306
|
+
};
|
|
307
|
+
const useDoc = () => {
|
|
308
|
+
const room = useRoom();
|
|
309
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.storageLoaded(onStoreChange), [room]);
|
|
310
|
+
const getSnapshot = room.getDoc;
|
|
311
|
+
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
312
|
+
};
|
|
313
|
+
const useEvent = (type, callback) => {
|
|
314
|
+
const room = useRoom();
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
const unsubscribe = room.subscribe.event(type, callback);
|
|
317
|
+
return () => {
|
|
318
|
+
unsubscribe();
|
|
319
|
+
};
|
|
320
|
+
}, [
|
|
321
|
+
callback,
|
|
322
|
+
room,
|
|
323
|
+
type
|
|
324
|
+
]);
|
|
325
|
+
};
|
|
326
|
+
const event = new Proxy({}, { get(_, prop) {
|
|
327
|
+
const useProxyEvent = (callback) => {
|
|
328
|
+
return useEvent(prop, callback);
|
|
329
|
+
};
|
|
330
|
+
return { useEvent: useProxyEvent };
|
|
331
|
+
} });
|
|
332
|
+
const useMyPresence = (selector = identity, options$1) => {
|
|
333
|
+
const room = useRoom();
|
|
334
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.myPresence(onStoreChange), [room]);
|
|
335
|
+
const getSnapshot = room.getMyPresence;
|
|
336
|
+
return [useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => selector(snapshot), [selector]), options$1?.isEqual ?? fastDeepEqual), room.updateMyPresence];
|
|
337
|
+
};
|
|
338
|
+
const useMyself = (selector = identity, options$1) => {
|
|
339
|
+
const room = useRoom();
|
|
340
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.myself(onStoreChange), [room]);
|
|
341
|
+
const getSnapshot = room.getMyself;
|
|
342
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
|
|
343
|
+
return !snapshot ? null : selector(snapshot);
|
|
344
|
+
}, [selector]), options$1?.isEqual ?? fastDeepEqual);
|
|
345
|
+
};
|
|
346
|
+
const useOther = (connectionId, selector = identity, options$1) => {
|
|
347
|
+
const room = useRoom();
|
|
348
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.other(connectionId, onStoreChange), [room, connectionId]);
|
|
349
|
+
const getSnapshot = useCallback(() => room.getOther(connectionId), [room, connectionId]);
|
|
350
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
|
|
351
|
+
return !snapshot ? null : selector(snapshot);
|
|
352
|
+
}, [selector]), options$1?.isEqual ?? fastDeepEqual);
|
|
353
|
+
};
|
|
354
|
+
const useOthers = (selector = identity, options$1) => {
|
|
355
|
+
const room = useRoom();
|
|
356
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.others(onStoreChange), [room]);
|
|
357
|
+
const getSnapshot = room.getOthers;
|
|
358
|
+
return useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, selector, options$1?.isEqual ?? ((a, b) => {
|
|
359
|
+
/**
|
|
360
|
+
* !HACK
|
|
361
|
+
* @description Assume the return type will always be an array when this occurs
|
|
362
|
+
* and do a shallow comparison instead like how standard React dependency
|
|
363
|
+
* arrays work. This is for performance's sake and may lead to bugs if the
|
|
364
|
+
* selector doesn't always return an array
|
|
365
|
+
* @date June 22, 2024
|
|
366
|
+
*/
|
|
367
|
+
if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) return shallowArrayEqual(a, b);
|
|
368
|
+
return fastDeepEqual(a, b);
|
|
369
|
+
}));
|
|
370
|
+
};
|
|
371
|
+
const useRedo = () => {
|
|
372
|
+
return useRoom().redo;
|
|
373
|
+
};
|
|
374
|
+
const useStorage = (key, selector = identity, options$1) => {
|
|
375
|
+
const room = useRoom();
|
|
376
|
+
const rerender = useRerender();
|
|
377
|
+
useEffect(() => {
|
|
378
|
+
const unsubscribe = room.subscribe.storageLoaded(() => {
|
|
379
|
+
rerender();
|
|
380
|
+
});
|
|
381
|
+
return () => {
|
|
382
|
+
unsubscribe();
|
|
383
|
+
};
|
|
384
|
+
}, [rerender, room]);
|
|
385
|
+
const subscribe = useCallback((onStoreChange) => room.subscribe.storage(key, onStoreChange), [key, room]);
|
|
386
|
+
const getSnapshot = useCallback(() => {
|
|
387
|
+
return room.getStorageJson(key);
|
|
388
|
+
}, [key, room]);
|
|
389
|
+
return [useSyncExternalStoreWithSelector(subscribe, getSnapshot, getSnapshot, useCallback((snapshot) => {
|
|
390
|
+
return snapshot === null ? null : selector(snapshot);
|
|
391
|
+
}, [selector]), options$1?.isEqual ?? fastDeepEqual), room.getStorage(key) ?? null];
|
|
392
|
+
};
|
|
393
|
+
const useTransact = () => {
|
|
394
|
+
return useRoom().transact;
|
|
395
|
+
};
|
|
396
|
+
const useUndo = () => {
|
|
397
|
+
return useRoom().undo;
|
|
398
|
+
};
|
|
399
|
+
return {
|
|
400
|
+
MockedRoomProvider,
|
|
401
|
+
PluvProvider,
|
|
402
|
+
PluvRoomProvider,
|
|
403
|
+
event,
|
|
404
|
+
useBroadcast,
|
|
405
|
+
useCanRedo,
|
|
406
|
+
useCanUndo,
|
|
407
|
+
useClient,
|
|
408
|
+
useConnection,
|
|
409
|
+
useDoc,
|
|
410
|
+
useEvent,
|
|
411
|
+
useMyPresence,
|
|
412
|
+
useMyself,
|
|
413
|
+
useOther,
|
|
414
|
+
useOthers,
|
|
415
|
+
useRedo,
|
|
416
|
+
useRoom,
|
|
417
|
+
useStorage,
|
|
418
|
+
useTransact,
|
|
419
|
+
useUndo
|
|
420
|
+
};
|
|
571
421
|
};
|
|
422
|
+
|
|
423
|
+
//#endregion
|
|
424
|
+
export { createBundle };
|
|
425
|
+
//# sourceMappingURL=index.mjs.map
|