@liveblocks/react 0.18.1 → 0.18.3
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/index.d.ts +15 -21
- package/index.js +65 -51
- package/package.json +2 -2
- package/.built-by-link-script +0 -1
package/index.d.ts
CHANGED
|
@@ -32,6 +32,21 @@ declare type RoomProviderProps<TPresence extends JsonObject, TStorage extends Ls
|
|
|
32
32
|
*/
|
|
33
33
|
id: string;
|
|
34
34
|
children: React.ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* If you're on React 17 or lower, pass in a reference to
|
|
37
|
+
* `ReactDOM.unstable_batchedUpdates` or
|
|
38
|
+
* `ReactNative.unstable_batchedUpdates` here.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* import { unstable_batchedUpdates } from "react-dom";
|
|
42
|
+
*
|
|
43
|
+
* <RoomProvider ... unstable_batchedUpdates={unstable_batchedUpdates} />
|
|
44
|
+
*
|
|
45
|
+
* This will prevent you from running into the so-called "stale props"
|
|
46
|
+
* and/or "zombie child" problem that React 17 and lower can suffer from.
|
|
47
|
+
* Not necessary when you're on React v18 or later.
|
|
48
|
+
*/
|
|
49
|
+
unstable_batchedUpdates?: (cb: () => void) => void;
|
|
35
50
|
} & RoomInitializers<TPresence, TStorage>>;
|
|
36
51
|
/**
|
|
37
52
|
* For any function type, returns a similar function type, but without the
|
|
@@ -318,16 +333,6 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
318
333
|
* );
|
|
319
334
|
*/
|
|
320
335
|
useOthersMapped<T>(itemSelector: (other: User<TPresence, TUserMeta>) => T, itemIsEqual?: (prev: T, curr: T) => boolean): ReadonlyArray<readonly [connectionId: number, data: T]>;
|
|
321
|
-
/**
|
|
322
|
-
* Given a connection ID (as obtained by using `useOthersConnectionIds`), you can
|
|
323
|
-
* call this selector deep down in your component stack to only have the
|
|
324
|
-
* component re-render if properties for this particular user change.
|
|
325
|
-
*
|
|
326
|
-
* @example
|
|
327
|
-
* // Returns full user and re-renders whenever anything on the user changes
|
|
328
|
-
* const secondUser = useOther(2);
|
|
329
|
-
*/
|
|
330
|
-
useOther(connectionId: number): User<TPresence, TUserMeta>;
|
|
331
336
|
/**
|
|
332
337
|
* Given a connection ID (as obtained by using `useOthersConnectionIds`), you
|
|
333
338
|
* can call this selector deep down in your component stack to only have the
|
|
@@ -635,17 +640,6 @@ declare type RoomContextBundle<TPresence extends JsonObject, TStorage extends Ls
|
|
|
635
640
|
* );
|
|
636
641
|
*/
|
|
637
642
|
useOthersMapped<T>(itemSelector: (other: User<TPresence, TUserMeta>) => T, itemIsEqual?: (prev: T, curr: T) => boolean): ReadonlyArray<readonly [connectionId: number, data: T]>;
|
|
638
|
-
/**
|
|
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.
|
|
643
|
-
*
|
|
644
|
-
* @example
|
|
645
|
-
* // Returns full user and re-renders whenever anything on the user changes
|
|
646
|
-
* const secondUser = useOther(2);
|
|
647
|
-
*/
|
|
648
|
-
useOther(connectionId: number): User<TPresence, TUserMeta>;
|
|
649
643
|
/**
|
|
650
644
|
* Given a connection ID (as obtained by using `useOthersConnectionIds`),
|
|
651
645
|
* you can call this selector deep down in your component stack to only
|
package/index.js
CHANGED
|
@@ -12,6 +12,10 @@ function ClientSideSuspense(props) {
|
|
|
12
12
|
|
|
13
13
|
// src/factory.tsx
|
|
14
14
|
var _client = require('@liveblocks/client');
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
15
19
|
var _internal = require('@liveblocks/client/internal');
|
|
16
20
|
|
|
17
21
|
var _withselector = require('use-sync-external-store/shim/with-selector');
|
|
@@ -33,8 +37,20 @@ function useInitial(value) {
|
|
|
33
37
|
var noop = () => {
|
|
34
38
|
};
|
|
35
39
|
var identity = (x) => x;
|
|
36
|
-
|
|
37
|
-
|
|
40
|
+
var missing_unstable_batchedUpdates = (reactVersion, roomId) => `We noticed you\u2019re using React ${reactVersion}. Please pass unstable_batchedUpdates at the RoomProvider level until you\u2019re ready to upgrade to React 18:
|
|
41
|
+
|
|
42
|
+
import { unstable_batchedUpdates } from "react-dom"; // or "react-native"
|
|
43
|
+
|
|
44
|
+
<RoomProvider id=${JSON.stringify(
|
|
45
|
+
roomId
|
|
46
|
+
)} ... unstable_batchedUpdates={unstable_batchedUpdates}>
|
|
47
|
+
...
|
|
48
|
+
</RoomProvider>
|
|
49
|
+
|
|
50
|
+
Why? Please see https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child for more information`;
|
|
51
|
+
var superfluous_unstable_batchedUpdates = "You don\u2019t need to pass unstable_batchedUpdates to RoomProvider anymore, since you\u2019re on React 18+ already.";
|
|
52
|
+
function useSyncExternalStore(s, gs, gss) {
|
|
53
|
+
return _withselector.useSyncExternalStoreWithSelector.call(void 0, s, gs, gss, identity);
|
|
38
54
|
}
|
|
39
55
|
var EMPTY_OTHERS = _internal.asArrayWithLegacyMethods.call(void 0, []);
|
|
40
56
|
function getEmptyOthers() {
|
|
@@ -70,7 +86,12 @@ function makeMutationContext(room) {
|
|
|
70
86
|
function createRoomContext(client) {
|
|
71
87
|
const RoomContext = React2.createContext(null);
|
|
72
88
|
function RoomProvider(props) {
|
|
73
|
-
const {
|
|
89
|
+
const {
|
|
90
|
+
id: roomId,
|
|
91
|
+
initialPresence,
|
|
92
|
+
initialStorage,
|
|
93
|
+
unstable_batchedUpdates
|
|
94
|
+
} = props;
|
|
74
95
|
if (process.env.NODE_ENV !== "production") {
|
|
75
96
|
if (!roomId) {
|
|
76
97
|
throw new Error(
|
|
@@ -80,15 +101,27 @@ function createRoomContext(client) {
|
|
|
80
101
|
if (typeof roomId !== "string") {
|
|
81
102
|
throw new Error("RoomProvider id property should be a string.");
|
|
82
103
|
}
|
|
104
|
+
const majorReactVersion = parseInt(React2.version) || 1;
|
|
105
|
+
const oldReactVersion = majorReactVersion < 18;
|
|
106
|
+
_internal.errorIf.call(void 0,
|
|
107
|
+
oldReactVersion && props.unstable_batchedUpdates === void 0,
|
|
108
|
+
missing_unstable_batchedUpdates(majorReactVersion, roomId)
|
|
109
|
+
);
|
|
110
|
+
_internal.deprecateIf.call(void 0,
|
|
111
|
+
!oldReactVersion && props.unstable_batchedUpdates !== void 0,
|
|
112
|
+
superfluous_unstable_batchedUpdates
|
|
113
|
+
);
|
|
83
114
|
}
|
|
84
115
|
const frozen = useInitial({
|
|
85
116
|
initialPresence,
|
|
86
|
-
initialStorage
|
|
117
|
+
initialStorage,
|
|
118
|
+
unstable_batchedUpdates
|
|
87
119
|
});
|
|
88
120
|
const [room, setRoom] = React2.useState(
|
|
89
121
|
() => client.enter(roomId, {
|
|
90
|
-
initialPresence,
|
|
91
|
-
initialStorage,
|
|
122
|
+
initialPresence: frozen.initialPresence,
|
|
123
|
+
initialStorage: frozen.initialStorage,
|
|
124
|
+
unstable_batchedUpdates: frozen.unstable_batchedUpdates,
|
|
92
125
|
DO_NOT_USE_withoutConnecting: typeof window === "undefined"
|
|
93
126
|
})
|
|
94
127
|
);
|
|
@@ -97,6 +130,7 @@ function createRoomContext(client) {
|
|
|
97
130
|
client.enter(roomId, {
|
|
98
131
|
initialPresence: frozen.initialPresence,
|
|
99
132
|
initialStorage: frozen.initialStorage,
|
|
133
|
+
unstable_batchedUpdates: frozen.unstable_batchedUpdates,
|
|
100
134
|
DO_NOT_USE_withoutConnecting: typeof window === "undefined"
|
|
101
135
|
})
|
|
102
136
|
);
|
|
@@ -164,50 +198,34 @@ function createRoomContext(client) {
|
|
|
164
198
|
);
|
|
165
199
|
return useOthers(wrappedSelector, wrappedIsEqual);
|
|
166
200
|
}
|
|
167
|
-
const
|
|
201
|
+
const NOT_FOUND = Symbol();
|
|
168
202
|
function useOther(connectionId, selector, isEqual) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
(others) => others.find((other2) => other2.connectionId === connectionId),
|
|
174
|
-
[connectionId]
|
|
175
|
-
);
|
|
176
|
-
const other = _useOthers(selector2, _client.shallow);
|
|
177
|
-
if (other === void 0) {
|
|
178
|
-
throw new Error(
|
|
179
|
-
`No such other user with connection id ${connectionId} exists`
|
|
203
|
+
const wrappedSelector = React2.useCallback(
|
|
204
|
+
(others) => {
|
|
205
|
+
const other2 = others.find(
|
|
206
|
+
(other3) => other3.connectionId === connectionId
|
|
180
207
|
);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return eq(prev, curr);
|
|
200
|
-
},
|
|
201
|
-
[isEqual]
|
|
208
|
+
return other2 !== void 0 ? selector(other2) : NOT_FOUND;
|
|
209
|
+
},
|
|
210
|
+
[connectionId, selector]
|
|
211
|
+
);
|
|
212
|
+
const wrappedIsEqual = React2.useCallback(
|
|
213
|
+
(prev, curr) => {
|
|
214
|
+
if (prev === NOT_FOUND || curr === NOT_FOUND) {
|
|
215
|
+
return prev === curr;
|
|
216
|
+
}
|
|
217
|
+
const eq = isEqual != null ? isEqual : Object.is;
|
|
218
|
+
return eq(prev, curr);
|
|
219
|
+
},
|
|
220
|
+
[isEqual]
|
|
221
|
+
);
|
|
222
|
+
const other = useOthers(wrappedSelector, wrappedIsEqual);
|
|
223
|
+
if (other === NOT_FOUND) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
`No such other user with connection id ${connectionId} exists`
|
|
202
226
|
);
|
|
203
|
-
const other = _useOthers(wrappedSelector, wrappedIsEqual);
|
|
204
|
-
if (other === sentinel) {
|
|
205
|
-
throw new Error(
|
|
206
|
-
`No such other user with connection id ${connectionId} exists`
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
return other;
|
|
210
227
|
}
|
|
228
|
+
return other;
|
|
211
229
|
}
|
|
212
230
|
function useBroadcastEvent() {
|
|
213
231
|
const room = useRoom();
|
|
@@ -443,11 +461,7 @@ function createRoomContext(client) {
|
|
|
443
461
|
}
|
|
444
462
|
function useOtherSuspense(connectionId, selector, isEqual) {
|
|
445
463
|
useSuspendUntilPresenceLoaded();
|
|
446
|
-
return useOther(
|
|
447
|
-
connectionId,
|
|
448
|
-
selector,
|
|
449
|
-
isEqual
|
|
450
|
-
);
|
|
464
|
+
return useOther(connectionId, selector, isEqual);
|
|
451
465
|
}
|
|
452
466
|
function useLegacyKeySuspense(key) {
|
|
453
467
|
useSuspendUntilStorageLoaded();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/react",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.3",
|
|
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.
|
|
30
|
+
"@liveblocks/client": "0.18.3",
|
|
31
31
|
"react": "^16.14.0 || ^17 || ^18"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
package/.built-by-link-script
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
ab4dc80c03188cfbc87c124cad9c824347a785b0
|