@liveblocks/react 0.16.4 → 0.16.7
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 +39 -190
- package/index.js +240 -379
- package/index.mjs +214 -491
- package/package.json +10 -9
package/index.mjs
CHANGED
|
@@ -1,507 +1,230 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import { useReducer } from "react";
|
|
4
|
+
|
|
5
|
+
import { LiveMap, LiveList, LiveObject } from "@liveblocks/client";
|
|
6
|
+
|
|
7
|
+
import { deprecateIf } from "@liveblocks/client/internal";
|
|
5
8
|
|
|
6
9
|
const ClientContext = React.createContext(null);
|
|
7
|
-
|
|
8
|
-
* Makes the Liveblocks client available in the component hierarchy below.
|
|
9
|
-
*/
|
|
10
|
+
|
|
10
11
|
function LiveblocksProvider(props) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* Returns the Client of the nearest LiveblocksProvider above in the React
|
|
15
|
-
* component tree.
|
|
16
|
-
*/
|
|
17
|
-
function useClient() {
|
|
18
|
-
const client = React.useContext(ClientContext);
|
|
19
|
-
if (client == null) {
|
|
20
|
-
throw new Error("LiveblocksProvider is missing from the react tree");
|
|
21
|
-
}
|
|
22
|
-
return client;
|
|
12
|
+
return React.createElement(ClientContext.Provider, {
|
|
13
|
+
value: props.client
|
|
14
|
+
}, props.children);
|
|
23
15
|
}
|
|
24
16
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
17
|
+
function useClient() {
|
|
18
|
+
const client = React.useContext(ClientContext);
|
|
19
|
+
if (null == client) throw new Error("LiveblocksProvider is missing from the react tree");
|
|
20
|
+
return client;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
24
|
+
return new (P || (P = Promise))((function(resolve, reject) {
|
|
25
|
+
function fulfilled(value) {
|
|
26
|
+
try {
|
|
27
|
+
step(generator.next(value));
|
|
28
|
+
} catch (e) {
|
|
29
|
+
reject(e);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function rejected(value) {
|
|
33
|
+
try {
|
|
34
|
+
step(generator.throw(value));
|
|
35
|
+
} catch (e) {
|
|
36
|
+
reject(e);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function step(result) {
|
|
40
|
+
var value;
|
|
41
|
+
result.done ? resolve(result.value) : (value = result.value, value instanceof P ? value : new P((function(resolve) {
|
|
42
|
+
resolve(value);
|
|
43
|
+
}))).then(fulfilled, rejected);
|
|
44
|
+
}
|
|
45
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
46
|
+
}));
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
/**
|
|
51
|
-
* Trigger a re-render programmatically, without changing the component's
|
|
52
|
-
* state.
|
|
53
|
-
*
|
|
54
|
-
* Usage:
|
|
55
|
-
*
|
|
56
|
-
* const rerender = useRerender();
|
|
57
|
-
* return (
|
|
58
|
-
* <button onClick={rerender}>
|
|
59
|
-
* {Math.random()}
|
|
60
|
-
* </button>
|
|
61
|
-
* )
|
|
62
|
-
*
|
|
63
|
-
*/
|
|
64
49
|
function useRerender() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
throw new Error("RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required");
|
|
85
|
-
}
|
|
86
|
-
if (typeof roomId !== "string") {
|
|
87
|
-
throw new Error("RoomProvider id property should be a string.");
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
deprecateIf(defaultPresence, "RoomProvider's `defaultPresence` prop will be removed in @liveblocks/react 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence");
|
|
91
|
-
deprecateIf(defaultStorageRoot, "RoomProvider's `defaultStorageRoot` prop will be removed in @liveblocks/react 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot");
|
|
92
|
-
const client = useClient();
|
|
93
|
-
const [room, setRoom] = React.useState(() => client.enter(roomId, {
|
|
94
|
-
initialPresence,
|
|
95
|
-
initialStorage,
|
|
96
|
-
defaultPresence,
|
|
97
|
-
defaultStorageRoot,
|
|
98
|
-
DO_NOT_USE_withoutConnecting: typeof window === "undefined",
|
|
50
|
+
const [, update] = useReducer((x => x + 1), 0);
|
|
51
|
+
return update;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const {RoomProvider: RoomProvider, useRoom: useRoom, useMyPresence: useMyPresence, useUpdateMyPresence: useUpdateMyPresence, useOthers: useOthers, useBroadcastEvent: useBroadcastEvent, useErrorListener: useErrorListener, useEventListener: useEventListener, useSelf: useSelf, useStorage: useStorage, useMap: useMap, useList: useList, useObject: useObject, useUndo: useUndo, useRedo: useRedo, useBatch: useBatch, useHistory: useHistory} = function() {
|
|
55
|
+
const RoomContext = React.createContext(null);
|
|
56
|
+
function useRoom() {
|
|
57
|
+
const room = React.useContext(RoomContext);
|
|
58
|
+
if (null == room) throw new Error("RoomProvider is missing from the react tree");
|
|
59
|
+
return room;
|
|
60
|
+
}
|
|
61
|
+
function useStorage() {
|
|
62
|
+
const room = useRoom(), [root, setState] = React.useState(null);
|
|
63
|
+
return React.useEffect((() => {
|
|
64
|
+
let didCancel = !1;
|
|
65
|
+
return function() {
|
|
66
|
+
__awaiter(this, void 0, void 0, (function*() {
|
|
67
|
+
const storage = yield room.getStorage();
|
|
68
|
+
didCancel || setState(storage.root);
|
|
99
69
|
}));
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
* return null;
|
|
184
|
-
* }
|
|
185
|
-
* return <Cursor key={connectionId} cursor={presence.cursor} />
|
|
186
|
-
* })
|
|
187
|
-
* }
|
|
188
|
-
*/
|
|
189
|
-
function useOthers() {
|
|
190
|
-
const room = useRoom();
|
|
191
|
-
const rerender = useRerender();
|
|
192
|
-
React.useEffect(() => {
|
|
193
|
-
const unsubscribe = room.subscribe("others", rerender);
|
|
194
|
-
return () => {
|
|
195
|
-
unsubscribe();
|
|
196
|
-
};
|
|
197
|
-
}, [room]);
|
|
198
|
-
return room.getOthers();
|
|
199
|
-
}
|
|
200
|
-
/**
|
|
201
|
-
* Returns a callback that lets you broadcast custom events to other users in the room
|
|
202
|
-
*
|
|
203
|
-
* @example
|
|
204
|
-
* import { useBroadcastEvent } from "@liveblocks/react";
|
|
205
|
-
*
|
|
206
|
-
* const broadcast = useBroadcastEvent();
|
|
207
|
-
*
|
|
208
|
-
* broadcast({ type: "CUSTOM_EVENT", data: { x: 0, y: 0 } });
|
|
209
|
-
*/
|
|
210
|
-
function useBroadcastEvent() {
|
|
211
|
-
const room = useRoom();
|
|
212
|
-
return React.useCallback((event, options = { shouldQueueEventIfNotReady: false }) => {
|
|
213
|
-
room.broadcastEvent(event, options);
|
|
214
|
-
}, [room]);
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* useErrorListener is a react hook that lets you react to potential room connection errors.
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* import { useErrorListener } from "@liveblocks/react";
|
|
221
|
-
*
|
|
222
|
-
* useErrorListener(er => {
|
|
223
|
-
* console.error(er);
|
|
224
|
-
* })
|
|
225
|
-
*/
|
|
226
|
-
function useErrorListener(callback) {
|
|
227
|
-
const room = useRoom();
|
|
228
|
-
const savedCallback = React.useRef(callback);
|
|
229
|
-
React.useEffect(() => {
|
|
230
|
-
savedCallback.current = callback;
|
|
231
|
-
});
|
|
232
|
-
React.useEffect(() => {
|
|
233
|
-
const listener = (e) => savedCallback.current(e);
|
|
234
|
-
const unsubscribe = room.subscribe("error", listener);
|
|
235
|
-
return () => {
|
|
236
|
-
unsubscribe();
|
|
237
|
-
};
|
|
238
|
-
}, [room]);
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* useEventListener is a react hook that lets you react to event broadcasted by other users in the room.
|
|
242
|
-
*
|
|
243
|
-
* @example
|
|
244
|
-
* import { useEventListener } from "@liveblocks/react";
|
|
245
|
-
*
|
|
246
|
-
* useEventListener(({ connectionId, event }) => {
|
|
247
|
-
* if (event.type === "CUSTOM_EVENT") {
|
|
248
|
-
* // Do something
|
|
249
|
-
* }
|
|
250
|
-
* });
|
|
251
|
-
*/
|
|
252
|
-
function useEventListener(callback) {
|
|
253
|
-
const room = useRoom();
|
|
254
|
-
const savedCallback = React.useRef(callback);
|
|
255
|
-
React.useEffect(() => {
|
|
256
|
-
savedCallback.current = callback;
|
|
257
|
-
});
|
|
258
|
-
React.useEffect(() => {
|
|
259
|
-
const listener = (e) => savedCallback.current(e);
|
|
260
|
-
const unsubscribe = room.subscribe("event", listener);
|
|
261
|
-
return () => {
|
|
262
|
-
unsubscribe();
|
|
263
|
-
};
|
|
264
|
-
}, [room]);
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Gets the current user once it is connected to the room.
|
|
268
|
-
*
|
|
269
|
-
* @example
|
|
270
|
-
* import { useSelf } from "@liveblocks/react";
|
|
271
|
-
*
|
|
272
|
-
* const user = useSelf();
|
|
273
|
-
*/
|
|
274
|
-
function useSelf() {
|
|
275
|
-
const room = useRoom();
|
|
276
|
-
const rerender = useRerender();
|
|
277
|
-
React.useEffect(() => {
|
|
278
|
-
const unsubscribePresence = room.subscribe("my-presence", rerender);
|
|
279
|
-
const unsubscribeConnection = room.subscribe("connection", rerender);
|
|
280
|
-
return () => {
|
|
281
|
-
unsubscribePresence();
|
|
282
|
-
unsubscribeConnection();
|
|
283
|
-
};
|
|
284
|
-
}, [room]);
|
|
285
|
-
return room.getSelf();
|
|
286
|
-
}
|
|
287
|
-
function useStorage() {
|
|
288
|
-
const room = useRoom();
|
|
289
|
-
const [root, setState] = React.useState(null);
|
|
290
|
-
React.useEffect(() => {
|
|
291
|
-
let didCancel = false;
|
|
292
|
-
function fetchStorage() {
|
|
293
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
294
|
-
const storage = yield room.getStorage();
|
|
295
|
-
if (!didCancel) {
|
|
296
|
-
setState(storage.root);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
fetchStorage();
|
|
301
|
-
return () => {
|
|
302
|
-
didCancel = true;
|
|
303
|
-
};
|
|
304
|
-
}, [room]);
|
|
305
|
-
return [root];
|
|
306
|
-
}
|
|
307
|
-
function useMap(key, entries) {
|
|
308
|
-
deprecateIf(entries, `Support for initializing entries in useMap() directly will be removed in @liveblocks/react 0.18.
|
|
309
|
-
|
|
310
|
-
Instead, please initialize this data where you set up your RoomProvider:
|
|
311
|
-
|
|
312
|
-
const initialStorage = () => {
|
|
313
|
-
${JSON.stringify(key)}: new LiveMap(...),
|
|
314
|
-
...
|
|
70
|
+
}(), () => {
|
|
71
|
+
didCancel = !0;
|
|
72
|
+
};
|
|
73
|
+
}), [ room ]), [ root ];
|
|
74
|
+
}
|
|
75
|
+
function useHistory() {
|
|
76
|
+
return useRoom().history;
|
|
77
|
+
}
|
|
78
|
+
function useStorageValue(key, initialValue) {
|
|
79
|
+
const room = useRoom(), [root] = useStorage(), rerender = useRerender();
|
|
80
|
+
if (React.useEffect((() => {
|
|
81
|
+
if (null == root) return;
|
|
82
|
+
let liveValue = root.get(key);
|
|
83
|
+
null == liveValue && (liveValue = initialValue, root.set(key, liveValue));
|
|
84
|
+
let unsubscribeCrdt = room.subscribe(liveValue, rerender);
|
|
85
|
+
const unsubscribeRoot = room.subscribe(root, (function() {
|
|
86
|
+
const newCrdt = root.get(key);
|
|
87
|
+
newCrdt !== liveValue && (unsubscribeCrdt(), liveValue = newCrdt, unsubscribeCrdt = room.subscribe(liveValue, rerender),
|
|
88
|
+
rerender());
|
|
89
|
+
}));
|
|
90
|
+
return rerender(), () => {
|
|
91
|
+
unsubscribeRoot(), unsubscribeCrdt();
|
|
92
|
+
};
|
|
93
|
+
}), [ root, room ]), null == root) return {
|
|
94
|
+
status: "loading"
|
|
95
|
+
};
|
|
96
|
+
{
|
|
97
|
+
const value = root.get(key);
|
|
98
|
+
return null == value ? {
|
|
99
|
+
status: "notfound"
|
|
100
|
+
} : {
|
|
101
|
+
status: "ok",
|
|
102
|
+
value: value
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
RoomProvider: function(props) {
|
|
108
|
+
const {id: roomId, initialPresence: initialPresence, initialStorage: initialStorage, defaultPresence: defaultPresence, defaultStorageRoot: defaultStorageRoot} = props;
|
|
109
|
+
if ("production" !== process.env.NODE_ENV) {
|
|
110
|
+
if (null == roomId) throw new Error("RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required");
|
|
111
|
+
if ("string" != typeof roomId) throw new Error("RoomProvider id property should be a string.");
|
|
112
|
+
}
|
|
113
|
+
deprecateIf(defaultPresence, "RoomProvider's `defaultPresence` prop will be removed in @liveblocks/react 0.18. Please use `initialPresence` instead. For more info, see https://bit.ly/3Niy5aP", "defaultPresence"),
|
|
114
|
+
deprecateIf(defaultStorageRoot, "RoomProvider's `defaultStorageRoot` prop will be removed in @liveblocks/react 0.18. Please use `initialStorage` instead. For more info, see https://bit.ly/3Niy5aP", "defaultStorageRoot");
|
|
115
|
+
const client = useClient(), [room, setRoom] = React.useState((() => client.enter(roomId, {
|
|
116
|
+
initialPresence: initialPresence,
|
|
117
|
+
initialStorage: initialStorage,
|
|
118
|
+
defaultPresence: defaultPresence,
|
|
119
|
+
defaultStorageRoot: defaultStorageRoot,
|
|
120
|
+
DO_NOT_USE_withoutConnecting: "undefined" == typeof window
|
|
121
|
+
})));
|
|
122
|
+
return React.useEffect((() => (setRoom(client.enter(roomId, {
|
|
123
|
+
initialPresence: initialPresence,
|
|
124
|
+
initialStorage: initialStorage,
|
|
125
|
+
defaultPresence: defaultPresence,
|
|
126
|
+
defaultStorageRoot: defaultStorageRoot,
|
|
127
|
+
DO_NOT_USE_withoutConnecting: "undefined" == typeof window
|
|
128
|
+
})), () => {
|
|
129
|
+
client.leave(roomId);
|
|
130
|
+
})), [ client, roomId ]), React.createElement(RoomContext.Provider, {
|
|
131
|
+
value: room
|
|
132
|
+
}, props.children);
|
|
133
|
+
},
|
|
134
|
+
useBatch: function() {
|
|
135
|
+
return useRoom().batch;
|
|
136
|
+
},
|
|
137
|
+
useBroadcastEvent: function() {
|
|
138
|
+
const room = useRoom();
|
|
139
|
+
return React.useCallback(((event, options = {
|
|
140
|
+
shouldQueueEventIfNotReady: !1
|
|
141
|
+
}) => {
|
|
142
|
+
room.broadcastEvent(event, options);
|
|
143
|
+
}), [ room ]);
|
|
144
|
+
},
|
|
145
|
+
useErrorListener: function(callback) {
|
|
146
|
+
const room = useRoom(), savedCallback = React.useRef(callback);
|
|
147
|
+
React.useEffect((() => {
|
|
148
|
+
savedCallback.current = callback;
|
|
149
|
+
})), React.useEffect((() => {
|
|
150
|
+
const unsubscribe = room.subscribe("error", (e => savedCallback.current(e)));
|
|
151
|
+
return () => {
|
|
152
|
+
unsubscribe();
|
|
315
153
|
};
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return value.value;
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
deprecateIf(value.status === "notfound", `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useMap() will no longer automatically create this key.
|
|
330
|
-
|
|
331
|
-
Instead, please initialize your storage where you set up your RoomProvider:
|
|
332
|
-
|
|
333
|
-
import { LiveMap } from "@liveblocks/client";
|
|
334
|
-
|
|
335
|
-
const initialStorage = () => {
|
|
336
|
-
${JSON.stringify(key)}: new LiveMap(...),
|
|
337
|
-
...
|
|
154
|
+
}), [ room ]);
|
|
155
|
+
},
|
|
156
|
+
useEventListener: function(callback) {
|
|
157
|
+
const room = useRoom(), savedCallback = React.useRef(callback);
|
|
158
|
+
React.useEffect((() => {
|
|
159
|
+
savedCallback.current = callback;
|
|
160
|
+
})), React.useEffect((() => {
|
|
161
|
+
const unsubscribe = room.subscribe("event", (e => savedCallback.current(e)));
|
|
162
|
+
return () => {
|
|
163
|
+
unsubscribe();
|
|
338
164
|
};
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
function
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
<RoomProvider initialStorage={initialStorage}>
|
|
361
|
-
...
|
|
362
|
-
</RoomProvider>
|
|
363
|
-
|
|
364
|
-
Please see https://bit.ly/3Niy5aP for details.`);
|
|
365
|
-
const value = useCrdt(key, new LiveList(items));
|
|
366
|
-
// ^^^^^^^^^^^^^^^^^^^
|
|
367
|
-
// NOTE: This param is scheduled for removal in 0.18
|
|
368
|
-
if (value.status === "ok") {
|
|
369
|
-
return value.value;
|
|
370
|
-
}
|
|
371
|
-
else {
|
|
372
|
-
deprecateIf(value.status === "notfound", `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useList() will no longer automatically create this key.
|
|
373
|
-
|
|
374
|
-
Instead, please initialize your storage where you set up your RoomProvider:
|
|
375
|
-
|
|
376
|
-
import { LiveList } from "@liveblocks/client";
|
|
377
|
-
|
|
378
|
-
const initialStorage = () => {
|
|
379
|
-
${JSON.stringify(key)}: new LiveList(...),
|
|
380
|
-
...
|
|
165
|
+
}), [ room ]);
|
|
166
|
+
},
|
|
167
|
+
useHistory: useHistory,
|
|
168
|
+
useList: function(key, items) {
|
|
169
|
+
deprecateIf(items, `Support for initializing items in useList() directly will be removed in @liveblocks/react 0.18.\n\nInstead, please initialize this data where you set up your RoomProvider:\n\n import { LiveList } from "@liveblocks/client";\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveList(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`);
|
|
170
|
+
const value = useStorageValue(key, new LiveList(items));
|
|
171
|
+
return "ok" === value.status ? value.value : (deprecateIf("notfound" === value.status, `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useList() will no longer automatically create this key.\n\nInstead, please initialize your storage where you set up your RoomProvider:\n\n import { LiveList } from "@liveblocks/client";\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveList(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`),
|
|
172
|
+
null);
|
|
173
|
+
},
|
|
174
|
+
useMap: function(key, entries) {
|
|
175
|
+
deprecateIf(entries, `Support for initializing entries in useMap() directly will be removed in @liveblocks/react 0.18.\n\nInstead, please initialize this data where you set up your RoomProvider:\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveMap(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`);
|
|
176
|
+
const value = useStorageValue(key, new LiveMap(null != entries ? entries : void 0));
|
|
177
|
+
return "ok" === value.status ? value.value : (deprecateIf("notfound" === value.status, `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useMap() will no longer automatically create this key.\n\nInstead, please initialize your storage where you set up your RoomProvider:\n\n import { LiveMap } from "@liveblocks/client";\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveMap(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`),
|
|
178
|
+
null);
|
|
179
|
+
},
|
|
180
|
+
useMyPresence: function() {
|
|
181
|
+
const room = useRoom(), presence = room.getPresence(), rerender = useRerender();
|
|
182
|
+
return React.useEffect((() => {
|
|
183
|
+
const unsubscribe = room.subscribe("my-presence", rerender);
|
|
184
|
+
return () => {
|
|
185
|
+
unsubscribe();
|
|
381
186
|
};
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
</RoomProvider
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
import { LiveObject } from "@liveblocks/client";
|
|
397
|
-
|
|
398
|
-
const initialStorage = () => {
|
|
399
|
-
${JSON.stringify(key)}: new LiveObject(...),
|
|
400
|
-
...
|
|
187
|
+
}), [ room ]), [ presence, React.useCallback(((overrides, options) => room.updatePresence(overrides, options)), [ room ]) ];
|
|
188
|
+
},
|
|
189
|
+
useObject: function(key, initialData) {
|
|
190
|
+
deprecateIf(initialData, `Support for initializing data in useObject() directly will be removed in @liveblocks/react 0.18.\n\nInstead, please initialize this data where you set up your RoomProvider:\n\n import { LiveObject } from "@liveblocks/client";\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveObject(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`);
|
|
191
|
+
const value = useStorageValue(key, new LiveObject(initialData));
|
|
192
|
+
return "ok" === value.status ? value.value : (deprecateIf("notfound" === value.status, `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useObject() will no longer automatically create this key.\n\nInstead, please initialize your storage where you set up your RoomProvider:\n\n import { LiveObject } from "@liveblocks/client";\n\n const initialStorage = () => ({\n ${JSON.stringify(key)}: new LiveObject(...),\n ...\n });\n\n <RoomProvider initialStorage={initialStorage}>\n ...\n </RoomProvider>\n\nPlease see https://bit.ly/3Niy5aP for details.`),
|
|
193
|
+
null);
|
|
194
|
+
},
|
|
195
|
+
useOthers: function() {
|
|
196
|
+
const room = useRoom(), rerender = useRerender();
|
|
197
|
+
return React.useEffect((() => {
|
|
198
|
+
const unsubscribe = room.subscribe("others", rerender);
|
|
199
|
+
return () => {
|
|
200
|
+
unsubscribe();
|
|
401
201
|
};
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
else {
|
|
415
|
-
deprecateIf(value.status === "notfound", `Key ${JSON.stringify(key)} was not found in Storage. Starting with 0.18, useObject() will no longer automatically create this key.
|
|
416
|
-
|
|
417
|
-
Instead, please initialize your storage where you set up your RoomProvider:
|
|
418
|
-
|
|
419
|
-
import { LiveObject } from "@liveblocks/client";
|
|
420
|
-
|
|
421
|
-
const initialStorage = () => {
|
|
422
|
-
${JSON.stringify(key)}: new LiveObject(...),
|
|
423
|
-
...
|
|
202
|
+
}), [ room ]), room.getOthers();
|
|
203
|
+
},
|
|
204
|
+
useRedo: function() {
|
|
205
|
+
return useHistory().redo;
|
|
206
|
+
},
|
|
207
|
+
useRoom: useRoom,
|
|
208
|
+
useSelf: function() {
|
|
209
|
+
const room = useRoom(), rerender = useRerender();
|
|
210
|
+
return React.useEffect((() => {
|
|
211
|
+
const unsubscribePresence = room.subscribe("my-presence", rerender), unsubscribeConnection = room.subscribe("connection", rerender);
|
|
212
|
+
return () => {
|
|
213
|
+
unsubscribePresence(), unsubscribeConnection();
|
|
424
214
|
};
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
return useRoom().history.undo;
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
|
-
* Returns a function that redoes the last operation executed by the current client.
|
|
443
|
-
* It does not impact operations made by other clients.
|
|
444
|
-
*/
|
|
445
|
-
function useRedo() {
|
|
446
|
-
return useRoom().history.redo;
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Returns a function that batches modifications made during the given function.
|
|
450
|
-
* All the modifications are sent to other clients in a single message.
|
|
451
|
-
* All the modifications are merged in a single history item (undo/redo).
|
|
452
|
-
* All the subscribers are called only after the batch is over.
|
|
453
|
-
*/
|
|
454
|
-
function useBatch() {
|
|
455
|
-
return useRoom().batch;
|
|
456
|
-
}
|
|
457
|
-
/**
|
|
458
|
-
* Returns the room.history
|
|
459
|
-
*/
|
|
460
|
-
function useHistory() {
|
|
461
|
-
return useRoom().history;
|
|
462
|
-
}
|
|
463
|
-
function useCrdt(key, initialCrdt) {
|
|
464
|
-
const room = useRoom();
|
|
465
|
-
const [root] = useStorage();
|
|
466
|
-
const rerender = useRerender();
|
|
467
|
-
React.useEffect(() => {
|
|
468
|
-
if (root == null) {
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
let crdt = root.get(key);
|
|
472
|
-
if (crdt == null) {
|
|
473
|
-
crdt = initialCrdt;
|
|
474
|
-
root.set(key, crdt);
|
|
475
|
-
}
|
|
476
|
-
function onRootChange() {
|
|
477
|
-
const newCrdt = root.get(key);
|
|
478
|
-
if (newCrdt !== crdt) {
|
|
479
|
-
unsubscribeCrdt();
|
|
480
|
-
crdt = newCrdt;
|
|
481
|
-
unsubscribeCrdt = room.subscribe(crdt /* AbstractCrdt */, rerender);
|
|
482
|
-
rerender();
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
let unsubscribeCrdt = room.subscribe(crdt /* AbstractCrdt */, rerender);
|
|
486
|
-
const unsubscribeRoot = room.subscribe(root /* AbstractCrdt */, onRootChange);
|
|
487
|
-
rerender();
|
|
488
|
-
return () => {
|
|
489
|
-
unsubscribeRoot();
|
|
490
|
-
unsubscribeCrdt();
|
|
491
|
-
};
|
|
492
|
-
}, [root, room]);
|
|
493
|
-
if (root == null) {
|
|
494
|
-
return { status: "loading" };
|
|
495
|
-
}
|
|
496
|
-
else {
|
|
497
|
-
const value = root.get(key);
|
|
498
|
-
if (value == null) {
|
|
499
|
-
return { status: "notfound" };
|
|
500
|
-
}
|
|
501
|
-
else {
|
|
502
|
-
return { status: "ok", value };
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
215
|
+
}), [ room ]), room.getSelf();
|
|
216
|
+
},
|
|
217
|
+
useStorage: useStorage,
|
|
218
|
+
useUndo: function() {
|
|
219
|
+
return useHistory().undo;
|
|
220
|
+
},
|
|
221
|
+
useUpdateMyPresence: function() {
|
|
222
|
+
const room = useRoom();
|
|
223
|
+
return React.useCallback(((overrides, options) => {
|
|
224
|
+
room.updatePresence(overrides, options);
|
|
225
|
+
}), [ room ]);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}();
|
|
506
229
|
|
|
507
230
|
export { LiveblocksProvider, RoomProvider, useBatch, useBroadcastEvent, useClient, useErrorListener, useEventListener, useHistory, useList, useMap, useMyPresence, useObject, useOthers, useRedo, useRoom, useSelf, useStorage, useUndo, useUpdateMyPresence };
|