@liveblocks/react 0.18.0-beta3 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.built-by-link-script +1 -1
- package/index.d.ts +27 -46
- package/index.js +22 -20
- package/package.json +2 -2
package/.built-by-link-script
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
ab4dc80c03188cfbc87c124cad9c824347a785b0
|
package/index.d.ts
CHANGED
|
@@ -39,7 +39,7 @@ declare type RoomProviderProps<TPresence extends JsonObject, TStorage extends Ls
|
|
|
39
39
|
*/
|
|
40
40
|
declare type OmitFirstArg<F> = F extends (first: any, ...rest: infer A) => infer R ? (...args: A) => R : never;
|
|
41
41
|
declare type MutationContext<TPresence extends JsonObject, TStorage extends LsonObject, TUserMeta extends BaseUserMeta> = {
|
|
42
|
-
|
|
42
|
+
storage: LiveObject<TStorage>;
|
|
43
43
|
self: User<TPresence, TUserMeta>;
|
|
44
44
|
others: Others<TPresence, TUserMeta>;
|
|
45
45
|
setMyPresence: (patch: Partial<TPresence>, options?: {
|
|
@@ -166,13 +166,6 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
166
166
|
* const [root] = useStorageRoot();
|
|
167
167
|
*/
|
|
168
168
|
useStorageRoot(): [root: LiveObject<TStorage> | null];
|
|
169
|
-
/**
|
|
170
|
-
* Returns your entire Liveblocks Storage as an immutable data structure.
|
|
171
|
-
*
|
|
172
|
-
* @example
|
|
173
|
-
* const root = useStorage();
|
|
174
|
-
*/
|
|
175
|
-
useStorage(): ToImmutable<TStorage> | null;
|
|
176
169
|
/**
|
|
177
170
|
* Extract arbitrary data from the Liveblocks Storage state, using an
|
|
178
171
|
* arbitrary selector function.
|
|
@@ -192,7 +185,7 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
192
185
|
* return the result of a .map() or .filter() call from the selector. In
|
|
193
186
|
* those cases, you'll probably want to use a `shallow` comparison check.
|
|
194
187
|
*/
|
|
195
|
-
useStorage<T>(selector: (root: ToImmutable<TStorage>) => T, isEqual?: (prev: T, curr: T) => boolean): T | null;
|
|
188
|
+
useStorage<T>(selector: (root: ToImmutable<TStorage>) => T, isEqual?: (prev: T | null, curr: T | null) => boolean): T | null;
|
|
196
189
|
/**
|
|
197
190
|
* Gets the current user once it is connected to the room.
|
|
198
191
|
*
|
|
@@ -296,10 +289,10 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
296
289
|
* for each user in the room, e.g. cursors.
|
|
297
290
|
*
|
|
298
291
|
* @example
|
|
299
|
-
* const ids =
|
|
292
|
+
* const ids = useOthersConnectionIds();
|
|
300
293
|
* // [2, 4, 7]
|
|
301
294
|
*/
|
|
302
|
-
|
|
295
|
+
useOthersConnectionIds(): readonly number[];
|
|
303
296
|
/**
|
|
304
297
|
* Related to useOthers(), but optimized for selecting only "subsets" of
|
|
305
298
|
* others. This is useful for performance reasons in particular, because
|
|
@@ -307,11 +300,11 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
307
300
|
* re-renders that will be triggered.
|
|
308
301
|
*
|
|
309
302
|
* @example
|
|
310
|
-
* const avatars =
|
|
303
|
+
* const avatars = useOthersMapped(user => user.info.avatar);
|
|
311
304
|
* // ^^^^^^^
|
|
312
305
|
* // { connectionId: number; data: string }[]
|
|
313
306
|
*
|
|
314
|
-
* The selector function you pass to
|
|
307
|
+
* The selector function you pass to useOthersMapped() is called an "item
|
|
315
308
|
* selector", and operates on a single user at a time. If you provide an
|
|
316
309
|
* (optional) "item comparison" function, it will be used to compare each
|
|
317
310
|
* item pairwise.
|
|
@@ -319,17 +312,14 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
319
312
|
* For example, to select multiple properties:
|
|
320
313
|
*
|
|
321
314
|
* @example
|
|
322
|
-
* const avatarsAndCursors =
|
|
315
|
+
* const avatarsAndCursors = useOthersMapped(
|
|
323
316
|
* user => [u.info.avatar, u.presence.cursor],
|
|
324
317
|
* shallow, // 👈
|
|
325
318
|
* );
|
|
326
319
|
*/
|
|
327
|
-
|
|
328
|
-
readonly connectionId: number;
|
|
329
|
-
readonly data: T;
|
|
330
|
-
}[];
|
|
320
|
+
useOthersMapped<T>(itemSelector: (other: User<TPresence, TUserMeta>) => T, itemIsEqual?: (prev: T, curr: T) => boolean): ReadonlyArray<readonly [connectionId: number, data: T]>;
|
|
331
321
|
/**
|
|
332
|
-
* Given a connection ID (as obtained by using `
|
|
322
|
+
* Given a connection ID (as obtained by using `useOthersConnectionIds`), you can
|
|
333
323
|
* call this selector deep down in your component stack to only have the
|
|
334
324
|
* component re-render if properties for this particular user change.
|
|
335
325
|
*
|
|
@@ -339,8 +329,8 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
339
329
|
*/
|
|
340
330
|
useOther(connectionId: number): User<TPresence, TUserMeta>;
|
|
341
331
|
/**
|
|
342
|
-
* Given a connection ID (as obtained by using `
|
|
343
|
-
* call this selector deep down in your component stack to only have the
|
|
332
|
+
* Given a connection ID (as obtained by using `useOthersConnectionIds`), you
|
|
333
|
+
* can call this selector deep down in your component stack to only have the
|
|
344
334
|
* component re-render if properties for this particular user change.
|
|
345
335
|
*
|
|
346
336
|
* @example
|
|
@@ -363,7 +353,7 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
363
353
|
addToHistory: boolean;
|
|
364
354
|
}) => void;
|
|
365
355
|
/**
|
|
366
|
-
* Create a callback function that
|
|
356
|
+
* Create a callback function that lets you mutate Liveblocks state.
|
|
367
357
|
*
|
|
368
358
|
* The first argument that gets passed into your callback will be a "mutation
|
|
369
359
|
* context", which exposes the following:
|
|
@@ -493,13 +483,6 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
493
483
|
* const [root] = useStorageRoot();
|
|
494
484
|
*/
|
|
495
485
|
useStorageRoot(): [root: LiveObject<TStorage> | null];
|
|
496
|
-
/**
|
|
497
|
-
* Returns your entire Liveblocks Storage as an immutable data structure.
|
|
498
|
-
*
|
|
499
|
-
* @example
|
|
500
|
-
* const root = useStorage();
|
|
501
|
-
*/
|
|
502
|
-
useStorage(): ToImmutable<TStorage>;
|
|
503
486
|
/**
|
|
504
487
|
* Extract arbitrary data from the Liveblocks Storage state, using an
|
|
505
488
|
* arbitrary selector function.
|
|
@@ -623,10 +606,10 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
623
606
|
* for each user in the room, e.g. cursors.
|
|
624
607
|
*
|
|
625
608
|
* @example
|
|
626
|
-
* const ids =
|
|
609
|
+
* const ids = useOthersConnectionIds();
|
|
627
610
|
* // [2, 4, 7]
|
|
628
611
|
*/
|
|
629
|
-
|
|
612
|
+
useOthersConnectionIds(): readonly number[];
|
|
630
613
|
/**
|
|
631
614
|
* Related to useOthers(), but optimized for selecting only "subsets" of
|
|
632
615
|
* others. This is useful for performance reasons in particular, because
|
|
@@ -634,11 +617,11 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
634
617
|
* re-renders that will be triggered.
|
|
635
618
|
*
|
|
636
619
|
* @example
|
|
637
|
-
* const avatars =
|
|
620
|
+
* const avatars = useOthersMapped(user => user.info.avatar);
|
|
638
621
|
* // ^^^^^^^
|
|
639
622
|
* // { connectionId: number; data: string }[]
|
|
640
623
|
*
|
|
641
|
-
* The selector function you pass to
|
|
624
|
+
* The selector function you pass to useOthersMapped() is called an "item
|
|
642
625
|
* selector", and operates on a single user at a time. If you provide an
|
|
643
626
|
* (optional) "item comparison" function, it will be used to compare each
|
|
644
627
|
* item pairwise.
|
|
@@ -646,19 +629,17 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
646
629
|
* For example, to select multiple properties:
|
|
647
630
|
*
|
|
648
631
|
* @example
|
|
649
|
-
* const avatarsAndCursors =
|
|
632
|
+
* const avatarsAndCursors = useOthersMapped(
|
|
650
633
|
* user => [u.info.avatar, u.presence.cursor],
|
|
651
634
|
* shallow, // 👈
|
|
652
635
|
* );
|
|
653
636
|
*/
|
|
654
|
-
|
|
655
|
-
readonly connectionId: number;
|
|
656
|
-
readonly data: T;
|
|
657
|
-
}[];
|
|
637
|
+
useOthersMapped<T>(itemSelector: (other: User<TPresence, TUserMeta>) => T, itemIsEqual?: (prev: T, curr: T) => boolean): ReadonlyArray<readonly [connectionId: number, data: T]>;
|
|
658
638
|
/**
|
|
659
|
-
* Given a connection ID (as obtained by using `
|
|
660
|
-
* can call this selector deep down in your component stack to only
|
|
661
|
-
* the component re-render if properties for this particular user
|
|
639
|
+
* Given a connection ID (as obtained by using `useOthersConnectionIds`),
|
|
640
|
+
* you can call this selector deep down in your component stack to only
|
|
641
|
+
* have the component re-render if properties for this particular user
|
|
642
|
+
* change.
|
|
662
643
|
*
|
|
663
644
|
* @example
|
|
664
645
|
* // Returns full user and re-renders whenever anything on the user changes
|
|
@@ -666,9 +647,10 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
666
647
|
*/
|
|
667
648
|
useOther(connectionId: number): User<TPresence, TUserMeta>;
|
|
668
649
|
/**
|
|
669
|
-
* Given a connection ID (as obtained by using `
|
|
670
|
-
* can call this selector deep down in your component stack to only
|
|
671
|
-
* the component re-render if properties for this particular user
|
|
650
|
+
* Given a connection ID (as obtained by using `useOthersConnectionIds`),
|
|
651
|
+
* you can call this selector deep down in your component stack to only
|
|
652
|
+
* have the component re-render if properties for this particular user
|
|
653
|
+
* change.
|
|
672
654
|
*
|
|
673
655
|
* @example
|
|
674
656
|
* // Returns only the selected values re-renders whenever that selection changes)
|
|
@@ -690,8 +672,7 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
690
672
|
addToHistory: boolean;
|
|
691
673
|
}) => void;
|
|
692
674
|
/**
|
|
693
|
-
* Create a callback function that
|
|
694
|
-
* state.
|
|
675
|
+
* Create a callback function that lets you mutate Liveblocks state.
|
|
695
676
|
*
|
|
696
677
|
* The first argument that gets passed into your callback will be
|
|
697
678
|
* a "mutation context", which exposes the following:
|
package/index.js
CHANGED
|
@@ -43,12 +43,12 @@ function getEmptyOthers() {
|
|
|
43
43
|
function makeMutationContext(room) {
|
|
44
44
|
const errmsg = "This mutation cannot be used until connected to the Liveblocks room";
|
|
45
45
|
return {
|
|
46
|
-
get
|
|
47
|
-
const
|
|
48
|
-
if (
|
|
46
|
+
get storage() {
|
|
47
|
+
const mutableRoot = room.getStorageSnapshot();
|
|
48
|
+
if (mutableRoot === null) {
|
|
49
49
|
throw new Error(errmsg);
|
|
50
50
|
}
|
|
51
|
-
return
|
|
51
|
+
return mutableRoot;
|
|
52
52
|
},
|
|
53
53
|
get self() {
|
|
54
54
|
const self = room.getSelf();
|
|
@@ -142,15 +142,14 @@ function createRoomContext(client) {
|
|
|
142
142
|
isEqual
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
|
-
function
|
|
145
|
+
function useOthersConnectionIds() {
|
|
146
146
|
return useOthers(connectionIdSelector, _client.shallow);
|
|
147
147
|
}
|
|
148
|
-
function
|
|
148
|
+
function useOthersMapped(itemSelector, itemIsEqual) {
|
|
149
149
|
const wrappedSelector = React2.useCallback(
|
|
150
|
-
(others) => others.map(
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
})),
|
|
150
|
+
(others) => others.map(
|
|
151
|
+
(other) => [other.connectionId, itemSelector(other)]
|
|
152
|
+
),
|
|
154
153
|
[itemSelector]
|
|
155
154
|
);
|
|
156
155
|
const wrappedIsEqual = React2.useCallback(
|
|
@@ -158,7 +157,7 @@ function createRoomContext(client) {
|
|
|
158
157
|
const eq = itemIsEqual != null ? itemIsEqual : Object.is;
|
|
159
158
|
return a.length === b.length && a.every((atuple, index) => {
|
|
160
159
|
const btuple = b[index];
|
|
161
|
-
return atuple
|
|
160
|
+
return atuple[0] === btuple[0] && eq(atuple[1], btuple[1]);
|
|
162
161
|
});
|
|
163
162
|
},
|
|
164
163
|
[itemIsEqual]
|
|
@@ -346,10 +345,9 @@ function createRoomContext(client) {
|
|
|
346
345
|
return root.get(key);
|
|
347
346
|
}
|
|
348
347
|
}
|
|
349
|
-
function useStorage(
|
|
348
|
+
function useStorage(selector, isEqual) {
|
|
350
349
|
const room = useRoom();
|
|
351
350
|
const rootOrNull = useMutableStorageRoot();
|
|
352
|
-
const selector = maybeSelector != null ? maybeSelector : identity;
|
|
353
351
|
const wrappedSelector = React2.useCallback(
|
|
354
352
|
(rootOrNull2) => rootOrNull2 !== null ? selector(rootOrNull2) : null,
|
|
355
353
|
[selector]
|
|
@@ -379,7 +377,7 @@ function createRoomContext(client) {
|
|
|
379
377
|
function ensureNotServerSide() {
|
|
380
378
|
if (typeof window === "undefined") {
|
|
381
379
|
throw new Error(
|
|
382
|
-
"You cannot
|
|
380
|
+
"You cannot use the Suspense version of this hook on the server side. Make sure to only call them on the client side.\nFor tips, see https://liveblocks.io/docs/api-reference/liveblocks-react#suspense-avoid-ssr"
|
|
383
381
|
);
|
|
384
382
|
}
|
|
385
383
|
}
|
|
@@ -435,9 +433,13 @@ function createRoomContext(client) {
|
|
|
435
433
|
isEqual
|
|
436
434
|
);
|
|
437
435
|
}
|
|
438
|
-
function
|
|
436
|
+
function useOthersConnectionIdsSuspense() {
|
|
437
|
+
useSuspendUntilPresenceLoaded();
|
|
438
|
+
return useOthersConnectionIds();
|
|
439
|
+
}
|
|
440
|
+
function useOthersMappedSuspense(itemSelector, itemIsEqual) {
|
|
439
441
|
useSuspendUntilPresenceLoaded();
|
|
440
|
-
return
|
|
442
|
+
return useOthersMapped(itemSelector, itemIsEqual);
|
|
441
443
|
}
|
|
442
444
|
function useOtherSuspense(connectionId, selector, isEqual) {
|
|
443
445
|
useSuspendUntilPresenceLoaded();
|
|
@@ -473,8 +475,8 @@ function createRoomContext(client) {
|
|
|
473
475
|
useMyPresence,
|
|
474
476
|
useUpdateMyPresence,
|
|
475
477
|
useOthers,
|
|
476
|
-
|
|
477
|
-
|
|
478
|
+
useOthersMapped,
|
|
479
|
+
useOthersConnectionIds,
|
|
478
480
|
useOther,
|
|
479
481
|
useMutation,
|
|
480
482
|
suspense: {
|
|
@@ -499,8 +501,8 @@ function createRoomContext(client) {
|
|
|
499
501
|
useMyPresence,
|
|
500
502
|
useUpdateMyPresence,
|
|
501
503
|
useOthers: useOthersSuspense,
|
|
502
|
-
|
|
503
|
-
|
|
504
|
+
useOthersMapped: useOthersMappedSuspense,
|
|
505
|
+
useOthersConnectionIds: useOthersConnectionIdsSuspense,
|
|
504
506
|
useOther: useOtherSuspense,
|
|
505
507
|
useMutation
|
|
506
508
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react",
|
|
3
|
-
"version": "0.18.0
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "A set of React hooks and providers to use Liveblocks declaratively.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"use-sync-external-store": "^1.2.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@liveblocks/client": "0.18.0
|
|
30
|
+
"@liveblocks/client": "0.18.0",
|
|
31
31
|
"react": "^16.14.0 || ^17 || ^18"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|