@liveblocks/react 0.15.5 → 0.15.6-beta.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/lib/esm/index.js +216 -0
- package/lib/esm/index.mjs +216 -0
- package/lib/index.d.ts +208 -206
- package/lib/index.js +355 -424
- package/package.json +18 -5
- package/lib/index.js.map +0 -1
- package/lib/index.test.d.ts +0 -1
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { LiveMap, LiveList, LiveObject } from '@liveblocks/client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
const ClientContext = React.createContext(null);
|
|
5
|
+
const RoomContext = React.createContext(null);
|
|
6
|
+
function LiveblocksProvider(props) {
|
|
7
|
+
return /* @__PURE__ */ React.createElement(ClientContext.Provider, {
|
|
8
|
+
value: props.client
|
|
9
|
+
}, props.children);
|
|
10
|
+
}
|
|
11
|
+
function useClient() {
|
|
12
|
+
const client = React.useContext(ClientContext);
|
|
13
|
+
if (client == null) {
|
|
14
|
+
throw new Error("LiveblocksProvider is missing from the react tree");
|
|
15
|
+
}
|
|
16
|
+
return client;
|
|
17
|
+
}
|
|
18
|
+
function RoomProvider({
|
|
19
|
+
id,
|
|
20
|
+
children,
|
|
21
|
+
defaultPresence,
|
|
22
|
+
defaultStorageRoot
|
|
23
|
+
}) {
|
|
24
|
+
if (process.env.NODE_ENV !== "production") {
|
|
25
|
+
if (id == null) {
|
|
26
|
+
throw new Error("RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required");
|
|
27
|
+
}
|
|
28
|
+
if (typeof id !== "string") {
|
|
29
|
+
throw new Error("RoomProvider id property should be a string.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const client = useClient();
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
return () => {
|
|
35
|
+
client.leave(id);
|
|
36
|
+
};
|
|
37
|
+
}, [client, id]);
|
|
38
|
+
const room = client.getRoom(id) || client.enter(id, {
|
|
39
|
+
defaultPresence: defaultPresence ? defaultPresence() : void 0,
|
|
40
|
+
defaultStorageRoot,
|
|
41
|
+
DO_NOT_USE_withoutConnecting: typeof window === "undefined"
|
|
42
|
+
});
|
|
43
|
+
return /* @__PURE__ */ React.createElement(RoomContext.Provider, {
|
|
44
|
+
value: room
|
|
45
|
+
}, children);
|
|
46
|
+
}
|
|
47
|
+
function useRoom() {
|
|
48
|
+
const room = React.useContext(RoomContext);
|
|
49
|
+
if (room == null) {
|
|
50
|
+
throw new Error("RoomProvider is missing from the react tree");
|
|
51
|
+
}
|
|
52
|
+
return room;
|
|
53
|
+
}
|
|
54
|
+
function useMyPresence() {
|
|
55
|
+
const room = useRoom();
|
|
56
|
+
const presence = room.getPresence();
|
|
57
|
+
const [, update] = React.useState(0);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
function onMyPresenceChange() {
|
|
60
|
+
update((x) => x + 1);
|
|
61
|
+
}
|
|
62
|
+
const unsubscribe = room.subscribe("my-presence", onMyPresenceChange);
|
|
63
|
+
return () => {
|
|
64
|
+
unsubscribe();
|
|
65
|
+
};
|
|
66
|
+
}, [room]);
|
|
67
|
+
const setPresence = React.useCallback((overrides, options) => room.updatePresence(overrides, options), [room]);
|
|
68
|
+
return [presence, setPresence];
|
|
69
|
+
}
|
|
70
|
+
function useUpdateMyPresence() {
|
|
71
|
+
const room = useRoom();
|
|
72
|
+
return React.useCallback((overrides, options) => {
|
|
73
|
+
room.updatePresence(overrides, options);
|
|
74
|
+
}, [room]);
|
|
75
|
+
}
|
|
76
|
+
function useOthers() {
|
|
77
|
+
const room = useRoom();
|
|
78
|
+
const [, update] = React.useState(0);
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
function onOthersChange() {
|
|
81
|
+
update((x) => x + 1);
|
|
82
|
+
}
|
|
83
|
+
const unsubscribe = room.subscribe("others", onOthersChange);
|
|
84
|
+
return () => {
|
|
85
|
+
unsubscribe();
|
|
86
|
+
};
|
|
87
|
+
}, [room]);
|
|
88
|
+
return room.getOthers();
|
|
89
|
+
}
|
|
90
|
+
function useBroadcastEvent() {
|
|
91
|
+
const room = useRoom();
|
|
92
|
+
return React.useCallback((event, options = { shouldQueueEventIfNotReady: false }) => {
|
|
93
|
+
room.broadcastEvent(event, options);
|
|
94
|
+
}, [room]);
|
|
95
|
+
}
|
|
96
|
+
function useErrorListener(callback) {
|
|
97
|
+
const room = useRoom();
|
|
98
|
+
const savedCallback = React.useRef(callback);
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
savedCallback.current = callback;
|
|
101
|
+
});
|
|
102
|
+
React.useEffect(() => {
|
|
103
|
+
const listener = (e) => savedCallback.current(e);
|
|
104
|
+
const unsubscribe = room.subscribe("error", listener);
|
|
105
|
+
return () => {
|
|
106
|
+
unsubscribe();
|
|
107
|
+
};
|
|
108
|
+
}, [room]);
|
|
109
|
+
}
|
|
110
|
+
function useEventListener(callback) {
|
|
111
|
+
const room = useRoom();
|
|
112
|
+
const savedCallback = React.useRef(callback);
|
|
113
|
+
React.useEffect(() => {
|
|
114
|
+
savedCallback.current = callback;
|
|
115
|
+
});
|
|
116
|
+
React.useEffect(() => {
|
|
117
|
+
const listener = (e) => savedCallback.current(e);
|
|
118
|
+
const unsubscribe = room.subscribe("event", listener);
|
|
119
|
+
return () => {
|
|
120
|
+
unsubscribe();
|
|
121
|
+
};
|
|
122
|
+
}, [room]);
|
|
123
|
+
}
|
|
124
|
+
function useSelf() {
|
|
125
|
+
const room = useRoom();
|
|
126
|
+
const [, update] = React.useState(0);
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
function onChange() {
|
|
129
|
+
update((x) => x + 1);
|
|
130
|
+
}
|
|
131
|
+
const unsubscribePresence = room.subscribe("my-presence", onChange);
|
|
132
|
+
const unsubscribeConnection = room.subscribe("connection", onChange);
|
|
133
|
+
return () => {
|
|
134
|
+
unsubscribePresence();
|
|
135
|
+
unsubscribeConnection();
|
|
136
|
+
};
|
|
137
|
+
}, [room]);
|
|
138
|
+
return room.getSelf();
|
|
139
|
+
}
|
|
140
|
+
function useStorage() {
|
|
141
|
+
const room = useRoom();
|
|
142
|
+
const [root, setState] = React.useState(null);
|
|
143
|
+
React.useEffect(() => {
|
|
144
|
+
let didCancel = false;
|
|
145
|
+
async function fetchStorage() {
|
|
146
|
+
const storage = await room.getStorage();
|
|
147
|
+
if (!didCancel) {
|
|
148
|
+
setState(storage.root);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
fetchStorage();
|
|
152
|
+
return () => {
|
|
153
|
+
didCancel = true;
|
|
154
|
+
};
|
|
155
|
+
}, [room]);
|
|
156
|
+
return [root];
|
|
157
|
+
}
|
|
158
|
+
function useMap(key, entries) {
|
|
159
|
+
return useCrdt(key, new LiveMap(entries));
|
|
160
|
+
}
|
|
161
|
+
function useList(key, items) {
|
|
162
|
+
return useCrdt(key, new LiveList(items));
|
|
163
|
+
}
|
|
164
|
+
function useObject(key, initialData) {
|
|
165
|
+
return useCrdt(key, new LiveObject(initialData));
|
|
166
|
+
}
|
|
167
|
+
function useUndo() {
|
|
168
|
+
return useRoom().history.undo;
|
|
169
|
+
}
|
|
170
|
+
function useRedo() {
|
|
171
|
+
return useRoom().history.redo;
|
|
172
|
+
}
|
|
173
|
+
function useBatch() {
|
|
174
|
+
return useRoom().batch;
|
|
175
|
+
}
|
|
176
|
+
function useHistory() {
|
|
177
|
+
return useRoom().history;
|
|
178
|
+
}
|
|
179
|
+
function useCrdt(key, initialCrdt) {
|
|
180
|
+
var _a;
|
|
181
|
+
const room = useRoom();
|
|
182
|
+
const [root] = useStorage();
|
|
183
|
+
const [, setCount] = React.useState(0);
|
|
184
|
+
React.useEffect(() => {
|
|
185
|
+
if (root == null) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
let crdt = root.get(key);
|
|
189
|
+
if (crdt == null) {
|
|
190
|
+
crdt = initialCrdt;
|
|
191
|
+
root.set(key, crdt);
|
|
192
|
+
}
|
|
193
|
+
function onChange() {
|
|
194
|
+
setCount((x) => x + 1);
|
|
195
|
+
}
|
|
196
|
+
function onRootChange() {
|
|
197
|
+
const newCrdt = root.get(key);
|
|
198
|
+
if (newCrdt !== crdt) {
|
|
199
|
+
unsubscribeCrdt();
|
|
200
|
+
crdt = newCrdt;
|
|
201
|
+
unsubscribeCrdt = room.subscribe(crdt, onChange);
|
|
202
|
+
setCount((x) => x + 1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
let unsubscribeCrdt = room.subscribe(crdt, onChange);
|
|
206
|
+
const unsubscribeRoot = room.subscribe(root, onRootChange);
|
|
207
|
+
setCount((x) => x + 1);
|
|
208
|
+
return () => {
|
|
209
|
+
unsubscribeRoot();
|
|
210
|
+
unsubscribeCrdt();
|
|
211
|
+
};
|
|
212
|
+
}, [root, room]);
|
|
213
|
+
return (_a = root == null ? void 0 : root.get(key)) != null ? _a : null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { LiveblocksProvider, RoomProvider, useBatch, useBroadcastEvent, useErrorListener, useEventListener, useHistory, useList, useMap, useMyPresence, useObject, useOthers, useRedo, useRoom, useSelf, useStorage, useUndo, useUpdateMyPresence };
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { LiveMap, LiveList, LiveObject } from '@liveblocks/client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
|
|
4
|
+
const ClientContext = React.createContext(null);
|
|
5
|
+
const RoomContext = React.createContext(null);
|
|
6
|
+
function LiveblocksProvider(props) {
|
|
7
|
+
return /* @__PURE__ */ React.createElement(ClientContext.Provider, {
|
|
8
|
+
value: props.client
|
|
9
|
+
}, props.children);
|
|
10
|
+
}
|
|
11
|
+
function useClient() {
|
|
12
|
+
const client = React.useContext(ClientContext);
|
|
13
|
+
if (client == null) {
|
|
14
|
+
throw new Error("LiveblocksProvider is missing from the react tree");
|
|
15
|
+
}
|
|
16
|
+
return client;
|
|
17
|
+
}
|
|
18
|
+
function RoomProvider({
|
|
19
|
+
id,
|
|
20
|
+
children,
|
|
21
|
+
defaultPresence,
|
|
22
|
+
defaultStorageRoot
|
|
23
|
+
}) {
|
|
24
|
+
if (process.env.NODE_ENV !== "production") {
|
|
25
|
+
if (id == null) {
|
|
26
|
+
throw new Error("RoomProvider id property is required. For more information: https://liveblocks.io/docs/errors/liveblocks-react/RoomProvider-id-property-is-required");
|
|
27
|
+
}
|
|
28
|
+
if (typeof id !== "string") {
|
|
29
|
+
throw new Error("RoomProvider id property should be a string.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const client = useClient();
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
return () => {
|
|
35
|
+
client.leave(id);
|
|
36
|
+
};
|
|
37
|
+
}, [client, id]);
|
|
38
|
+
const room = client.getRoom(id) || client.enter(id, {
|
|
39
|
+
defaultPresence: defaultPresence ? defaultPresence() : void 0,
|
|
40
|
+
defaultStorageRoot,
|
|
41
|
+
DO_NOT_USE_withoutConnecting: typeof window === "undefined"
|
|
42
|
+
});
|
|
43
|
+
return /* @__PURE__ */ React.createElement(RoomContext.Provider, {
|
|
44
|
+
value: room
|
|
45
|
+
}, children);
|
|
46
|
+
}
|
|
47
|
+
function useRoom() {
|
|
48
|
+
const room = React.useContext(RoomContext);
|
|
49
|
+
if (room == null) {
|
|
50
|
+
throw new Error("RoomProvider is missing from the react tree");
|
|
51
|
+
}
|
|
52
|
+
return room;
|
|
53
|
+
}
|
|
54
|
+
function useMyPresence() {
|
|
55
|
+
const room = useRoom();
|
|
56
|
+
const presence = room.getPresence();
|
|
57
|
+
const [, update] = React.useState(0);
|
|
58
|
+
React.useEffect(() => {
|
|
59
|
+
function onMyPresenceChange() {
|
|
60
|
+
update((x) => x + 1);
|
|
61
|
+
}
|
|
62
|
+
const unsubscribe = room.subscribe("my-presence", onMyPresenceChange);
|
|
63
|
+
return () => {
|
|
64
|
+
unsubscribe();
|
|
65
|
+
};
|
|
66
|
+
}, [room]);
|
|
67
|
+
const setPresence = React.useCallback((overrides, options) => room.updatePresence(overrides, options), [room]);
|
|
68
|
+
return [presence, setPresence];
|
|
69
|
+
}
|
|
70
|
+
function useUpdateMyPresence() {
|
|
71
|
+
const room = useRoom();
|
|
72
|
+
return React.useCallback((overrides, options) => {
|
|
73
|
+
room.updatePresence(overrides, options);
|
|
74
|
+
}, [room]);
|
|
75
|
+
}
|
|
76
|
+
function useOthers() {
|
|
77
|
+
const room = useRoom();
|
|
78
|
+
const [, update] = React.useState(0);
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
function onOthersChange() {
|
|
81
|
+
update((x) => x + 1);
|
|
82
|
+
}
|
|
83
|
+
const unsubscribe = room.subscribe("others", onOthersChange);
|
|
84
|
+
return () => {
|
|
85
|
+
unsubscribe();
|
|
86
|
+
};
|
|
87
|
+
}, [room]);
|
|
88
|
+
return room.getOthers();
|
|
89
|
+
}
|
|
90
|
+
function useBroadcastEvent() {
|
|
91
|
+
const room = useRoom();
|
|
92
|
+
return React.useCallback((event, options = { shouldQueueEventIfNotReady: false }) => {
|
|
93
|
+
room.broadcastEvent(event, options);
|
|
94
|
+
}, [room]);
|
|
95
|
+
}
|
|
96
|
+
function useErrorListener(callback) {
|
|
97
|
+
const room = useRoom();
|
|
98
|
+
const savedCallback = React.useRef(callback);
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
savedCallback.current = callback;
|
|
101
|
+
});
|
|
102
|
+
React.useEffect(() => {
|
|
103
|
+
const listener = (e) => savedCallback.current(e);
|
|
104
|
+
const unsubscribe = room.subscribe("error", listener);
|
|
105
|
+
return () => {
|
|
106
|
+
unsubscribe();
|
|
107
|
+
};
|
|
108
|
+
}, [room]);
|
|
109
|
+
}
|
|
110
|
+
function useEventListener(callback) {
|
|
111
|
+
const room = useRoom();
|
|
112
|
+
const savedCallback = React.useRef(callback);
|
|
113
|
+
React.useEffect(() => {
|
|
114
|
+
savedCallback.current = callback;
|
|
115
|
+
});
|
|
116
|
+
React.useEffect(() => {
|
|
117
|
+
const listener = (e) => savedCallback.current(e);
|
|
118
|
+
const unsubscribe = room.subscribe("event", listener);
|
|
119
|
+
return () => {
|
|
120
|
+
unsubscribe();
|
|
121
|
+
};
|
|
122
|
+
}, [room]);
|
|
123
|
+
}
|
|
124
|
+
function useSelf() {
|
|
125
|
+
const room = useRoom();
|
|
126
|
+
const [, update] = React.useState(0);
|
|
127
|
+
React.useEffect(() => {
|
|
128
|
+
function onChange() {
|
|
129
|
+
update((x) => x + 1);
|
|
130
|
+
}
|
|
131
|
+
const unsubscribePresence = room.subscribe("my-presence", onChange);
|
|
132
|
+
const unsubscribeConnection = room.subscribe("connection", onChange);
|
|
133
|
+
return () => {
|
|
134
|
+
unsubscribePresence();
|
|
135
|
+
unsubscribeConnection();
|
|
136
|
+
};
|
|
137
|
+
}, [room]);
|
|
138
|
+
return room.getSelf();
|
|
139
|
+
}
|
|
140
|
+
function useStorage() {
|
|
141
|
+
const room = useRoom();
|
|
142
|
+
const [root, setState] = React.useState(null);
|
|
143
|
+
React.useEffect(() => {
|
|
144
|
+
let didCancel = false;
|
|
145
|
+
async function fetchStorage() {
|
|
146
|
+
const storage = await room.getStorage();
|
|
147
|
+
if (!didCancel) {
|
|
148
|
+
setState(storage.root);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
fetchStorage();
|
|
152
|
+
return () => {
|
|
153
|
+
didCancel = true;
|
|
154
|
+
};
|
|
155
|
+
}, [room]);
|
|
156
|
+
return [root];
|
|
157
|
+
}
|
|
158
|
+
function useMap(key, entries) {
|
|
159
|
+
return useCrdt(key, new LiveMap(entries));
|
|
160
|
+
}
|
|
161
|
+
function useList(key, items) {
|
|
162
|
+
return useCrdt(key, new LiveList(items));
|
|
163
|
+
}
|
|
164
|
+
function useObject(key, initialData) {
|
|
165
|
+
return useCrdt(key, new LiveObject(initialData));
|
|
166
|
+
}
|
|
167
|
+
function useUndo() {
|
|
168
|
+
return useRoom().history.undo;
|
|
169
|
+
}
|
|
170
|
+
function useRedo() {
|
|
171
|
+
return useRoom().history.redo;
|
|
172
|
+
}
|
|
173
|
+
function useBatch() {
|
|
174
|
+
return useRoom().batch;
|
|
175
|
+
}
|
|
176
|
+
function useHistory() {
|
|
177
|
+
return useRoom().history;
|
|
178
|
+
}
|
|
179
|
+
function useCrdt(key, initialCrdt) {
|
|
180
|
+
var _a;
|
|
181
|
+
const room = useRoom();
|
|
182
|
+
const [root] = useStorage();
|
|
183
|
+
const [, setCount] = React.useState(0);
|
|
184
|
+
React.useEffect(() => {
|
|
185
|
+
if (root == null) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
let crdt = root.get(key);
|
|
189
|
+
if (crdt == null) {
|
|
190
|
+
crdt = initialCrdt;
|
|
191
|
+
root.set(key, crdt);
|
|
192
|
+
}
|
|
193
|
+
function onChange() {
|
|
194
|
+
setCount((x) => x + 1);
|
|
195
|
+
}
|
|
196
|
+
function onRootChange() {
|
|
197
|
+
const newCrdt = root.get(key);
|
|
198
|
+
if (newCrdt !== crdt) {
|
|
199
|
+
unsubscribeCrdt();
|
|
200
|
+
crdt = newCrdt;
|
|
201
|
+
unsubscribeCrdt = room.subscribe(crdt, onChange);
|
|
202
|
+
setCount((x) => x + 1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
let unsubscribeCrdt = room.subscribe(crdt, onChange);
|
|
206
|
+
const unsubscribeRoot = room.subscribe(root, onRootChange);
|
|
207
|
+
setCount((x) => x + 1);
|
|
208
|
+
return () => {
|
|
209
|
+
unsubscribeRoot();
|
|
210
|
+
unsubscribeCrdt();
|
|
211
|
+
};
|
|
212
|
+
}, [root, room]);
|
|
213
|
+
return (_a = root == null ? void 0 : root.get(key)) != null ? _a : null;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export { LiveblocksProvider, RoomProvider, useBatch, useBroadcastEvent, useErrorListener, useEventListener, useHistory, useList, useMap, useMyPresence, useObject, useOthers, useRedo, useRoom, useSelf, useStorage, useUndo, useUpdateMyPresence };
|