@liveblocks/core 1.2.0-internal4 → 1.2.0-internal6
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/dist/index.d.mts +1904 -0
- package/dist/index.d.ts +217 -216
- package/dist/index.js +222 -280
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +5903 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +15 -2
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1904 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents an indefinitely deep arbitrary JSON data structure. There are
|
|
3
|
+
* four types that make up the Json family:
|
|
4
|
+
*
|
|
5
|
+
* - Json any legal JSON value
|
|
6
|
+
* - JsonScalar any legal JSON leaf value (no lists or objects)
|
|
7
|
+
* - JsonArray a JSON value whose outer type is an array
|
|
8
|
+
* - JsonObject a JSON value whose outer type is an object
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
11
|
+
declare type Json = JsonScalar | JsonArray | JsonObject;
|
|
12
|
+
declare type JsonScalar = string | number | boolean | null;
|
|
13
|
+
declare type JsonArray = Json[];
|
|
14
|
+
declare type JsonObject = {
|
|
15
|
+
[key: string]: Json | undefined;
|
|
16
|
+
};
|
|
17
|
+
declare function isJsonScalar(data: Json): data is JsonScalar;
|
|
18
|
+
declare function isJsonArray(data: Json): data is JsonArray;
|
|
19
|
+
declare function isJsonObject(data: Json): data is JsonObject;
|
|
20
|
+
|
|
21
|
+
declare enum OpCode {
|
|
22
|
+
INIT = 0,
|
|
23
|
+
SET_PARENT_KEY = 1,
|
|
24
|
+
CREATE_LIST = 2,
|
|
25
|
+
UPDATE_OBJECT = 3,
|
|
26
|
+
CREATE_OBJECT = 4,
|
|
27
|
+
DELETE_CRDT = 5,
|
|
28
|
+
DELETE_OBJECT_KEY = 6,
|
|
29
|
+
CREATE_MAP = 7,
|
|
30
|
+
CREATE_REGISTER = 8
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* These operations are the payload for {@link UpdateStorageServerMsg} messages
|
|
34
|
+
* only.
|
|
35
|
+
*/
|
|
36
|
+
declare type Op = AckOp | CreateOp | UpdateObjectOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
|
|
37
|
+
declare type CreateOp = CreateRootObjectOp | CreateChildOp;
|
|
38
|
+
declare type CreateChildOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
|
|
39
|
+
declare type UpdateObjectOp = {
|
|
40
|
+
readonly opId?: string;
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly type: OpCode.UPDATE_OBJECT;
|
|
43
|
+
readonly data: Partial<JsonObject>;
|
|
44
|
+
};
|
|
45
|
+
declare type CreateObjectOp = {
|
|
46
|
+
readonly opId?: string;
|
|
47
|
+
readonly id: string;
|
|
48
|
+
readonly intent?: "set";
|
|
49
|
+
readonly deletedId?: string;
|
|
50
|
+
readonly type: OpCode.CREATE_OBJECT;
|
|
51
|
+
readonly parentId: string;
|
|
52
|
+
readonly parentKey: string;
|
|
53
|
+
readonly data: JsonObject;
|
|
54
|
+
};
|
|
55
|
+
declare type CreateRootObjectOp = {
|
|
56
|
+
readonly opId?: string;
|
|
57
|
+
readonly id: string;
|
|
58
|
+
readonly type: OpCode.CREATE_OBJECT;
|
|
59
|
+
readonly data: JsonObject;
|
|
60
|
+
readonly parentId?: never;
|
|
61
|
+
readonly parentKey?: never;
|
|
62
|
+
};
|
|
63
|
+
declare type CreateListOp = {
|
|
64
|
+
readonly opId?: string;
|
|
65
|
+
readonly id: string;
|
|
66
|
+
readonly intent?: "set";
|
|
67
|
+
readonly deletedId?: string;
|
|
68
|
+
readonly type: OpCode.CREATE_LIST;
|
|
69
|
+
readonly parentId: string;
|
|
70
|
+
readonly parentKey: string;
|
|
71
|
+
};
|
|
72
|
+
declare type CreateMapOp = {
|
|
73
|
+
readonly opId?: string;
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly intent?: "set";
|
|
76
|
+
readonly deletedId?: string;
|
|
77
|
+
readonly type: OpCode.CREATE_MAP;
|
|
78
|
+
readonly parentId: string;
|
|
79
|
+
readonly parentKey: string;
|
|
80
|
+
};
|
|
81
|
+
declare type CreateRegisterOp = {
|
|
82
|
+
readonly opId?: string;
|
|
83
|
+
readonly id: string;
|
|
84
|
+
readonly intent?: "set";
|
|
85
|
+
readonly deletedId?: string;
|
|
86
|
+
readonly type: OpCode.CREATE_REGISTER;
|
|
87
|
+
readonly parentId: string;
|
|
88
|
+
readonly parentKey: string;
|
|
89
|
+
readonly data: Json;
|
|
90
|
+
};
|
|
91
|
+
declare type DeleteCrdtOp = {
|
|
92
|
+
readonly opId?: string;
|
|
93
|
+
readonly id: string;
|
|
94
|
+
readonly type: OpCode.DELETE_CRDT;
|
|
95
|
+
};
|
|
96
|
+
declare type AckOp = {
|
|
97
|
+
readonly type: OpCode.DELETE_CRDT;
|
|
98
|
+
readonly id: "ACK";
|
|
99
|
+
readonly opId: string;
|
|
100
|
+
};
|
|
101
|
+
declare type SetParentKeyOp = {
|
|
102
|
+
readonly opId?: string;
|
|
103
|
+
readonly id: string;
|
|
104
|
+
readonly type: OpCode.SET_PARENT_KEY;
|
|
105
|
+
readonly parentKey: string;
|
|
106
|
+
};
|
|
107
|
+
declare type DeleteObjectKeyOp = {
|
|
108
|
+
readonly opId?: string;
|
|
109
|
+
readonly id: string;
|
|
110
|
+
readonly type: OpCode.DELETE_OBJECT_KEY;
|
|
111
|
+
readonly key: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Represents an indefinitely deep arbitrary immutable data
|
|
116
|
+
* structure, as returned by the .toImmutable().
|
|
117
|
+
*/
|
|
118
|
+
declare type Immutable = Scalar | ImmutableList | ImmutableObject | ImmutableMap;
|
|
119
|
+
declare type Scalar = string | number | boolean | null;
|
|
120
|
+
declare type ImmutableList = readonly Immutable[];
|
|
121
|
+
declare type ImmutableObject = {
|
|
122
|
+
readonly [key: string]: Immutable | undefined;
|
|
123
|
+
};
|
|
124
|
+
declare type ImmutableMap = ReadonlyMap<string, Immutable>;
|
|
125
|
+
|
|
126
|
+
declare type UpdateDelta = {
|
|
127
|
+
type: "update";
|
|
128
|
+
} | {
|
|
129
|
+
type: "delete";
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* "Plain LSON" is a JSON-based format that's used when serializing Live structures
|
|
134
|
+
* to send them over HTTP (e.g. in the API endpoint to let users upload their initial
|
|
135
|
+
* Room storage, in the API endpoint to fetch a Room's storage, ...).
|
|
136
|
+
*
|
|
137
|
+
* In the client, you would typically create LSON values using:
|
|
138
|
+
*
|
|
139
|
+
* new LiveObject({ x: 0, y: 0 })
|
|
140
|
+
*
|
|
141
|
+
* But over HTTP, this has to be serialized somehow. The "Plain LSON" format
|
|
142
|
+
* is what's used in the POST /init-storage-new endpoint, to allow users to
|
|
143
|
+
* control which parts of their data structure should be considered "Live"
|
|
144
|
+
* objects, and which parts are "normal" objects.
|
|
145
|
+
*
|
|
146
|
+
* So if they have a structure like:
|
|
147
|
+
*
|
|
148
|
+
* { x: 0, y: 0 }
|
|
149
|
+
*
|
|
150
|
+
* And want to make it a Live object, they can serialize it by wrapping it in
|
|
151
|
+
* a special "annotation":
|
|
152
|
+
*
|
|
153
|
+
* {
|
|
154
|
+
* "liveblocksType": "LiveObject",
|
|
155
|
+
* "data": { x: 0, y: 0 },
|
|
156
|
+
* }
|
|
157
|
+
*
|
|
158
|
+
* This "Plain LSON" data format defines exactly those wrappings.
|
|
159
|
+
*
|
|
160
|
+
* To summarize:
|
|
161
|
+
*
|
|
162
|
+
* LSON value | Plain LSON equivalent
|
|
163
|
+
* ----------------------+----------------------------------------------
|
|
164
|
+
* 42 | 42
|
|
165
|
+
* [1, 2, 3] | [1, 2, 3]
|
|
166
|
+
* { x: 0, y: 0 } | { x: 0, y: 0 }
|
|
167
|
+
* ----------------------+----------------------------------------------
|
|
168
|
+
* new LiveList(...) | { liveblocksType: "LiveList", data: ... }
|
|
169
|
+
* new LiveMap(...) | { liveblocksType: "LiveMap", data: ... }
|
|
170
|
+
* new LiveObject(...) | { liveblocksType: "LiveObject", data: ... }
|
|
171
|
+
*
|
|
172
|
+
*/
|
|
173
|
+
|
|
174
|
+
declare type PlainLsonFields = Record<string, PlainLson>;
|
|
175
|
+
declare type PlainLsonObject = {
|
|
176
|
+
liveblocksType: "LiveObject";
|
|
177
|
+
data: PlainLsonFields;
|
|
178
|
+
};
|
|
179
|
+
declare type PlainLsonMap = {
|
|
180
|
+
liveblocksType: "LiveMap";
|
|
181
|
+
data: PlainLsonFields;
|
|
182
|
+
};
|
|
183
|
+
declare type PlainLsonList = {
|
|
184
|
+
liveblocksType: "LiveList";
|
|
185
|
+
data: PlainLson[];
|
|
186
|
+
};
|
|
187
|
+
declare type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | Json;
|
|
188
|
+
|
|
189
|
+
declare type LiveObjectUpdateDelta<O extends {
|
|
190
|
+
[key: string]: unknown;
|
|
191
|
+
}> = {
|
|
192
|
+
[K in keyof O]?: UpdateDelta | undefined;
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* A LiveObject notification that is sent in-client to any subscribers whenever
|
|
196
|
+
* one or more of the entries inside the LiveObject instance have changed.
|
|
197
|
+
*/
|
|
198
|
+
declare type LiveObjectUpdates<TData extends LsonObject> = {
|
|
199
|
+
type: "LiveObject";
|
|
200
|
+
node: LiveObject<TData>;
|
|
201
|
+
updates: LiveObjectUpdateDelta<TData>;
|
|
202
|
+
};
|
|
203
|
+
/**
|
|
204
|
+
* The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
|
|
205
|
+
* Keys should be a string, and values should be serializable to JSON.
|
|
206
|
+
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
|
|
207
|
+
*/
|
|
208
|
+
declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
|
|
209
|
+
constructor(obj?: O);
|
|
210
|
+
/**
|
|
211
|
+
* Transform the LiveObject into a javascript object
|
|
212
|
+
*/
|
|
213
|
+
toObject(): O;
|
|
214
|
+
/**
|
|
215
|
+
* Adds or updates a property with a specified key and a value.
|
|
216
|
+
* @param key The key of the property to add
|
|
217
|
+
* @param value The value of the property to add
|
|
218
|
+
*/
|
|
219
|
+
set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
|
|
220
|
+
/**
|
|
221
|
+
* Returns a specified property from the LiveObject.
|
|
222
|
+
* @param key The key of the property to get
|
|
223
|
+
*/
|
|
224
|
+
get<TKey extends keyof O>(key: TKey): O[TKey];
|
|
225
|
+
/**
|
|
226
|
+
* Deletes a key from the LiveObject
|
|
227
|
+
* @param key The key of the property to delete
|
|
228
|
+
*/
|
|
229
|
+
delete(key: keyof O): void;
|
|
230
|
+
/**
|
|
231
|
+
* Adds or updates multiple properties at once with an object.
|
|
232
|
+
* @param patch The object used to overrides properties
|
|
233
|
+
*/
|
|
234
|
+
update(patch: Partial<O>): void;
|
|
235
|
+
toImmutable(): ToImmutable<O>;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Helper type to convert any valid Lson type to the equivalent Json type.
|
|
240
|
+
*
|
|
241
|
+
* Examples:
|
|
242
|
+
*
|
|
243
|
+
* ToImmutable<42> // 42
|
|
244
|
+
* ToImmutable<'hi'> // 'hi'
|
|
245
|
+
* ToImmutable<number> // number
|
|
246
|
+
* ToImmutable<string> // string
|
|
247
|
+
* ToImmutable<string | LiveList<number>> // string | readonly number[]
|
|
248
|
+
* ToImmutable<LiveMap<string, LiveList<number>>>
|
|
249
|
+
* // ReadonlyMap<string, readonly number[]>
|
|
250
|
+
* ToImmutable<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
|
|
251
|
+
* // { readonly a: null, readonly b: readonly string[], readonly c?: number }
|
|
252
|
+
*
|
|
253
|
+
*/
|
|
254
|
+
declare type ToImmutable<L extends Lson | LsonObject> = L extends LiveList<infer I> ? readonly ToImmutable<I>[] : L extends LiveObject<infer O> ? ToImmutable<O> : L extends LiveMap<infer K, infer V> ? ReadonlyMap<K, ToImmutable<V>> : L extends LsonObject ? {
|
|
255
|
+
readonly [K in keyof L]: ToImmutable<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
|
|
256
|
+
} : L extends Json ? L : never;
|
|
257
|
+
/**
|
|
258
|
+
* Returns PlainLson for a given Json or LiveStructure, suitable for calling the storage init api
|
|
259
|
+
*/
|
|
260
|
+
declare function toPlainLson(lson: Lson): PlainLson;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* A LiveMap notification that is sent in-client to any subscribers whenever
|
|
264
|
+
* one or more of the values inside the LiveMap instance have changed.
|
|
265
|
+
*/
|
|
266
|
+
declare type LiveMapUpdates<TKey extends string, TValue extends Lson> = {
|
|
267
|
+
type: "LiveMap";
|
|
268
|
+
node: LiveMap<TKey, TValue>;
|
|
269
|
+
updates: {
|
|
270
|
+
[key: string]: UpdateDelta;
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
/**
|
|
274
|
+
* The LiveMap class is similar to a JavaScript Map that is synchronized on all clients.
|
|
275
|
+
* Keys should be a string, and values should be serializable to JSON.
|
|
276
|
+
* If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
|
|
277
|
+
*/
|
|
278
|
+
declare class LiveMap<TKey extends string, TValue extends Lson> extends AbstractCrdt {
|
|
279
|
+
constructor(entries?: readonly (readonly [TKey, TValue])[] | undefined);
|
|
280
|
+
/**
|
|
281
|
+
* Returns a specified element from the LiveMap.
|
|
282
|
+
* @param key The key of the element to return.
|
|
283
|
+
* @returns The element associated with the specified key, or undefined if the key can't be found in the LiveMap.
|
|
284
|
+
*/
|
|
285
|
+
get(key: TKey): TValue | undefined;
|
|
286
|
+
/**
|
|
287
|
+
* Adds or updates an element with a specified key and a value.
|
|
288
|
+
* @param key The key of the element to add. Should be a string.
|
|
289
|
+
* @param value The value of the element to add. Should be serializable to JSON.
|
|
290
|
+
*/
|
|
291
|
+
set(key: TKey, value: TValue): void;
|
|
292
|
+
/**
|
|
293
|
+
* Returns the number of elements in the LiveMap.
|
|
294
|
+
*/
|
|
295
|
+
get size(): number;
|
|
296
|
+
/**
|
|
297
|
+
* Returns a boolean indicating whether an element with the specified key exists or not.
|
|
298
|
+
* @param key The key of the element to test for presence.
|
|
299
|
+
*/
|
|
300
|
+
has(key: TKey): boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Removes the specified element by key.
|
|
303
|
+
* @param key The key of the element to remove.
|
|
304
|
+
* @returns true if an element existed and has been removed, or false if the element does not exist.
|
|
305
|
+
*/
|
|
306
|
+
delete(key: TKey): boolean;
|
|
307
|
+
/**
|
|
308
|
+
* Returns a new Iterator object that contains the [key, value] pairs for each element.
|
|
309
|
+
*/
|
|
310
|
+
entries(): IterableIterator<[TKey, TValue]>;
|
|
311
|
+
/**
|
|
312
|
+
* Same function object as the initial value of the entries method.
|
|
313
|
+
*/
|
|
314
|
+
[Symbol.iterator](): IterableIterator<[TKey, TValue]>;
|
|
315
|
+
/**
|
|
316
|
+
* Returns a new Iterator object that contains the keys for each element.
|
|
317
|
+
*/
|
|
318
|
+
keys(): IterableIterator<TKey>;
|
|
319
|
+
/**
|
|
320
|
+
* Returns a new Iterator object that contains the values for each element.
|
|
321
|
+
*/
|
|
322
|
+
values(): IterableIterator<TValue>;
|
|
323
|
+
/**
|
|
324
|
+
* Executes a provided function once per each key/value pair in the Map object, in insertion order.
|
|
325
|
+
* @param callback Function to execute for each entry in the map.
|
|
326
|
+
*/
|
|
327
|
+
forEach(callback: (value: TValue, key: TKey, map: LiveMap<TKey, TValue>) => void): void;
|
|
328
|
+
toImmutable(): ReadonlyMap<TKey, ToImmutable<TValue>>;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
declare type StorageCallback = (updates: StorageUpdate[]) => void;
|
|
332
|
+
declare type LiveMapUpdate = LiveMapUpdates<string, Lson>;
|
|
333
|
+
declare type LiveObjectUpdate = LiveObjectUpdates<LsonObject>;
|
|
334
|
+
declare type LiveListUpdate = LiveListUpdates<Lson>;
|
|
335
|
+
/**
|
|
336
|
+
* The payload of notifications sent (in-client) when LiveStructures change.
|
|
337
|
+
* Messages of this kind are not originating from the network, but are 100%
|
|
338
|
+
* in-client.
|
|
339
|
+
*/
|
|
340
|
+
declare type StorageUpdate = LiveMapUpdate | LiveObjectUpdate | LiveListUpdate;
|
|
341
|
+
|
|
342
|
+
declare abstract class AbstractCrdt {
|
|
343
|
+
get roomId(): string | null;
|
|
344
|
+
/**
|
|
345
|
+
* Return an immutable snapshot of this Live node and its children.
|
|
346
|
+
*/
|
|
347
|
+
toImmutable(): Immutable;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
declare type LiveListUpdateDelta = {
|
|
351
|
+
index: number;
|
|
352
|
+
item: Lson;
|
|
353
|
+
type: "insert";
|
|
354
|
+
} | {
|
|
355
|
+
index: number;
|
|
356
|
+
type: "delete";
|
|
357
|
+
} | {
|
|
358
|
+
index: number;
|
|
359
|
+
previousIndex: number;
|
|
360
|
+
item: Lson;
|
|
361
|
+
type: "move";
|
|
362
|
+
} | {
|
|
363
|
+
index: number;
|
|
364
|
+
item: Lson;
|
|
365
|
+
type: "set";
|
|
366
|
+
};
|
|
367
|
+
/**
|
|
368
|
+
* A LiveList notification that is sent in-client to any subscribers whenever
|
|
369
|
+
* one or more of the items inside the LiveList instance have changed.
|
|
370
|
+
*/
|
|
371
|
+
declare type LiveListUpdates<TItem extends Lson> = {
|
|
372
|
+
type: "LiveList";
|
|
373
|
+
node: LiveList<TItem>;
|
|
374
|
+
updates: LiveListUpdateDelta[];
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* The LiveList class represents an ordered collection of items that is synchronized across clients.
|
|
378
|
+
*/
|
|
379
|
+
declare class LiveList<TItem extends Lson> extends AbstractCrdt {
|
|
380
|
+
constructor(items?: TItem[]);
|
|
381
|
+
/**
|
|
382
|
+
* Returns the number of elements.
|
|
383
|
+
*/
|
|
384
|
+
get length(): number;
|
|
385
|
+
/**
|
|
386
|
+
* Adds one element to the end of the LiveList.
|
|
387
|
+
* @param element The element to add to the end of the LiveList.
|
|
388
|
+
*/
|
|
389
|
+
push(element: TItem): void;
|
|
390
|
+
/**
|
|
391
|
+
* Inserts one element at a specified index.
|
|
392
|
+
* @param element The element to insert.
|
|
393
|
+
* @param index The index at which you want to insert the element.
|
|
394
|
+
*/
|
|
395
|
+
insert(element: TItem, index: number): void;
|
|
396
|
+
/**
|
|
397
|
+
* Move one element from one index to another.
|
|
398
|
+
* @param index The index of the element to move
|
|
399
|
+
* @param targetIndex The index where the element should be after moving.
|
|
400
|
+
*/
|
|
401
|
+
move(index: number, targetIndex: number): void;
|
|
402
|
+
/**
|
|
403
|
+
* Deletes an element at the specified index
|
|
404
|
+
* @param index The index of the element to delete
|
|
405
|
+
*/
|
|
406
|
+
delete(index: number): void;
|
|
407
|
+
clear(): void;
|
|
408
|
+
set(index: number, item: TItem): void;
|
|
409
|
+
/**
|
|
410
|
+
* Returns an Array of all the elements in the LiveList.
|
|
411
|
+
*/
|
|
412
|
+
toArray(): TItem[];
|
|
413
|
+
/**
|
|
414
|
+
* Tests whether all elements pass the test implemented by the provided function.
|
|
415
|
+
* @param predicate Function to test for each element, taking two arguments (the element and its index).
|
|
416
|
+
* @returns true if the predicate function returns a truthy value for every element. Otherwise, false.
|
|
417
|
+
*/
|
|
418
|
+
every(predicate: (value: TItem, index: number) => unknown): boolean;
|
|
419
|
+
/**
|
|
420
|
+
* Creates an array with all elements that pass the test implemented by the provided function.
|
|
421
|
+
* @param predicate Function to test each element of the LiveList. Return a value that coerces to true to keep the element, or to false otherwise.
|
|
422
|
+
* @returns An array with the elements that pass the test.
|
|
423
|
+
*/
|
|
424
|
+
filter(predicate: (value: TItem, index: number) => unknown): TItem[];
|
|
425
|
+
/**
|
|
426
|
+
* Returns the first element that satisfies the provided testing function.
|
|
427
|
+
* @param predicate Function to execute on each value.
|
|
428
|
+
* @returns The value of the first element in the LiveList that satisfies the provided testing function. Otherwise, undefined is returned.
|
|
429
|
+
*/
|
|
430
|
+
find(predicate: (value: TItem, index: number) => unknown): TItem | undefined;
|
|
431
|
+
/**
|
|
432
|
+
* Returns the index of the first element in the LiveList that satisfies the provided testing function.
|
|
433
|
+
* @param predicate Function to execute on each value until the function returns true, indicating that the satisfying element was found.
|
|
434
|
+
* @returns The index of the first element in the LiveList that passes the test. Otherwise, -1.
|
|
435
|
+
*/
|
|
436
|
+
findIndex(predicate: (value: TItem, index: number) => unknown): number;
|
|
437
|
+
/**
|
|
438
|
+
* Executes a provided function once for each element.
|
|
439
|
+
* @param callbackfn Function to execute on each element.
|
|
440
|
+
*/
|
|
441
|
+
forEach(callbackfn: (value: TItem, index: number) => void): void;
|
|
442
|
+
/**
|
|
443
|
+
* Get the element at the specified index.
|
|
444
|
+
* @param index The index on the element to get.
|
|
445
|
+
* @returns The element at the specified index or undefined.
|
|
446
|
+
*/
|
|
447
|
+
get(index: number): TItem | undefined;
|
|
448
|
+
/**
|
|
449
|
+
* Returns the first index at which a given element can be found in the LiveList, or -1 if it is not present.
|
|
450
|
+
* @param searchElement Element to locate.
|
|
451
|
+
* @param fromIndex The index to start the search at.
|
|
452
|
+
* @returns The first index of the element in the LiveList; -1 if not found.
|
|
453
|
+
*/
|
|
454
|
+
indexOf(searchElement: TItem, fromIndex?: number): number;
|
|
455
|
+
/**
|
|
456
|
+
* Returns the last index at which a given element can be found in the LiveList, or -1 if it is not present. The LiveLsit is searched backwards, starting at fromIndex.
|
|
457
|
+
* @param searchElement Element to locate.
|
|
458
|
+
* @param fromIndex The index at which to start searching backwards.
|
|
459
|
+
* @returns
|
|
460
|
+
*/
|
|
461
|
+
lastIndexOf(searchElement: TItem, fromIndex?: number): number;
|
|
462
|
+
/**
|
|
463
|
+
* Creates an array populated with the results of calling a provided function on every element.
|
|
464
|
+
* @param callback Function that is called for every element.
|
|
465
|
+
* @returns An array with each element being the result of the callback function.
|
|
466
|
+
*/
|
|
467
|
+
map<U>(callback: (value: TItem, index: number) => U): U[];
|
|
468
|
+
/**
|
|
469
|
+
* Tests whether at least one element in the LiveList passes the test implemented by the provided function.
|
|
470
|
+
* @param predicate Function to test for each element.
|
|
471
|
+
* @returns true if the callback function returns a truthy value for at least one element. Otherwise, false.
|
|
472
|
+
*/
|
|
473
|
+
some(predicate: (value: TItem, index: number) => unknown): boolean;
|
|
474
|
+
[Symbol.iterator](): IterableIterator<TItem>;
|
|
475
|
+
toImmutable(): readonly ToImmutable<TItem>[];
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* INTERNAL
|
|
480
|
+
*/
|
|
481
|
+
declare class LiveRegister<TValue extends Json> extends AbstractCrdt {
|
|
482
|
+
constructor(data: TValue);
|
|
483
|
+
get data(): TValue;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
declare type LiveStructure = LiveObject<LsonObject> | LiveList<Lson> | LiveMap<string, Lson>;
|
|
487
|
+
/**
|
|
488
|
+
* Think of Lson as a sibling of the Json data tree, except that the nested
|
|
489
|
+
* data structure can contain a mix of Json values and LiveStructure instances.
|
|
490
|
+
*/
|
|
491
|
+
declare type Lson = Json | LiveStructure;
|
|
492
|
+
/**
|
|
493
|
+
* LiveNode is the internal tree for managing Live data structures. The key
|
|
494
|
+
* difference with Lson is that all the Json values get represented in
|
|
495
|
+
* a LiveRegister node.
|
|
496
|
+
*/
|
|
497
|
+
declare type LiveNode = LiveStructure | LiveRegister<Json>;
|
|
498
|
+
/**
|
|
499
|
+
* A mapping of keys to Lson values. A Lson value is any valid JSON
|
|
500
|
+
* value or a Live storage data structure (LiveMap, LiveList, etc.)
|
|
501
|
+
*/
|
|
502
|
+
declare type LsonObject = {
|
|
503
|
+
[key: string]: Lson | undefined;
|
|
504
|
+
};
|
|
505
|
+
/**
|
|
506
|
+
* Helper type to convert any valid Lson type to the equivalent Json type.
|
|
507
|
+
*
|
|
508
|
+
* Examples:
|
|
509
|
+
*
|
|
510
|
+
* ToJson<42> // 42
|
|
511
|
+
* ToJson<'hi'> // 'hi'
|
|
512
|
+
* ToJson<number> // number
|
|
513
|
+
* ToJson<string> // string
|
|
514
|
+
* ToJson<string | LiveList<number>> // string | number[]
|
|
515
|
+
* ToJson<LiveMap<string, LiveList<number>>>
|
|
516
|
+
* // { [key: string]: number[] }
|
|
517
|
+
* ToJson<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
|
|
518
|
+
* // { a: null, b: string[], c?: number }
|
|
519
|
+
*
|
|
520
|
+
*/
|
|
521
|
+
declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extends LsonObject ? {
|
|
522
|
+
[K in keyof T]: ToJson<Exclude<T[K], undefined>> | (undefined extends T[K] ? undefined : never);
|
|
523
|
+
} : T extends LiveList<infer I> ? ToJson<I>[] : T extends LiveObject<infer O> ? ToJson<O> : T extends LiveMap<infer KS, infer V> ? {
|
|
524
|
+
[K in KS]: ToJson<V>;
|
|
525
|
+
} : never;
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* This helper type is effectively a no-op, but will force TypeScript to
|
|
529
|
+
* "evaluate" any named helper types in its definition. This can sometimes make
|
|
530
|
+
* API signatures clearer in IDEs.
|
|
531
|
+
*
|
|
532
|
+
* For example, in:
|
|
533
|
+
*
|
|
534
|
+
* type Payload<T> = { data: T };
|
|
535
|
+
*
|
|
536
|
+
* let r1: Payload<string>;
|
|
537
|
+
* let r2: Resolve<Payload<string>>;
|
|
538
|
+
*
|
|
539
|
+
* The inferred type of `r1` is going to be `Payload<string>` which shows up in
|
|
540
|
+
* editor hints, and it may be unclear what's inside if you don't know the
|
|
541
|
+
* definition of `Payload`.
|
|
542
|
+
*
|
|
543
|
+
* The inferred type of `r2` is going to be `{ data: string }`, which may be
|
|
544
|
+
* more helpful.
|
|
545
|
+
*
|
|
546
|
+
* This trick comes from:
|
|
547
|
+
* https://effectivetypescript.com/2022/02/25/gentips-4-display/
|
|
548
|
+
*/
|
|
549
|
+
declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
|
|
550
|
+
[K in keyof T]: T[K];
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* This type is used by clients to define the metadata for a user.
|
|
555
|
+
*/
|
|
556
|
+
declare type BaseUserMeta = {
|
|
557
|
+
/**
|
|
558
|
+
* The id of the user that has been set in the authentication endpoint.
|
|
559
|
+
* Useful to get additional information about the connected user.
|
|
560
|
+
*/
|
|
561
|
+
id?: string;
|
|
562
|
+
/**
|
|
563
|
+
* Additional user information that has been set in the authentication endpoint.
|
|
564
|
+
*/
|
|
565
|
+
info?: Json;
|
|
566
|
+
};
|
|
567
|
+
|
|
568
|
+
declare type Callback<T> = (event: T) => void;
|
|
569
|
+
declare type UnsubscribeCallback = () => void;
|
|
570
|
+
declare type Observable<T> = {
|
|
571
|
+
/**
|
|
572
|
+
* Register a callback function to be called whenever the event source emits
|
|
573
|
+
* an event.
|
|
574
|
+
*/
|
|
575
|
+
subscribe(callback: Callback<T>): UnsubscribeCallback;
|
|
576
|
+
/**
|
|
577
|
+
* Register a one-time callback function to be called whenever the event
|
|
578
|
+
* source emits an event. After the event fires, the callback is
|
|
579
|
+
* auto-unsubscribed.
|
|
580
|
+
*/
|
|
581
|
+
subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
|
|
582
|
+
/**
|
|
583
|
+
* Returns a promise that will resolve when an event is emitted by this
|
|
584
|
+
* event source. Optionally, specify a predicate that has to match. The first
|
|
585
|
+
* event matching that predicate will then resolve the promise.
|
|
586
|
+
*/
|
|
587
|
+
waitUntil(predicate?: (event: T) => boolean): Promise<T>;
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
interface IWebSocketEvent {
|
|
591
|
+
type: string;
|
|
592
|
+
}
|
|
593
|
+
interface IWebSocketCloseEvent extends IWebSocketEvent {
|
|
594
|
+
readonly code: number;
|
|
595
|
+
readonly wasClean: boolean;
|
|
596
|
+
readonly reason: string;
|
|
597
|
+
}
|
|
598
|
+
interface IWebSocketMessageEvent extends IWebSocketEvent {
|
|
599
|
+
readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
|
|
600
|
+
}
|
|
601
|
+
interface IWebSocketInstance {
|
|
602
|
+
readonly CONNECTING: number;
|
|
603
|
+
readonly OPEN: number;
|
|
604
|
+
readonly CLOSING: number;
|
|
605
|
+
readonly CLOSED: number;
|
|
606
|
+
readonly readyState: number;
|
|
607
|
+
addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
|
|
608
|
+
addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
|
|
609
|
+
addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
|
|
610
|
+
removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
|
|
611
|
+
removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
|
|
612
|
+
removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
|
|
613
|
+
close(): void;
|
|
614
|
+
send(data: string): void;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Either the browser-based WebSocket API or Node.js' WebSocket API (from the
|
|
618
|
+
* 'ws' package).
|
|
619
|
+
*
|
|
620
|
+
* This type defines the minimal WebSocket API that Liveblocks needs from
|
|
621
|
+
* a WebSocket implementation, and is a minimal subset of the browser-based
|
|
622
|
+
* WebSocket APIs and Node.js' WebSocket API so that both implementations are
|
|
623
|
+
* assignable to this type.
|
|
624
|
+
*/
|
|
625
|
+
interface IWebSocket {
|
|
626
|
+
new (address: string): IWebSocketInstance;
|
|
627
|
+
}
|
|
628
|
+
declare enum WebsocketCloseCodes {
|
|
629
|
+
CLOSE_ABNORMAL = 1006,
|
|
630
|
+
INVALID_MESSAGE_FORMAT = 4000,
|
|
631
|
+
NOT_ALLOWED = 4001,
|
|
632
|
+
MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
|
|
633
|
+
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
|
|
634
|
+
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
|
|
635
|
+
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
|
|
636
|
+
CLOSE_WITHOUT_RETRY = 4999
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* Old connection statuses, here for backward-compatibility reasons only.
|
|
641
|
+
*/
|
|
642
|
+
declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
|
|
643
|
+
/**
|
|
644
|
+
* Returns a human-readable status indicating the current connection status of
|
|
645
|
+
* a Room, as returned by `room.getStatus()`. Can be used to implement
|
|
646
|
+
* a connection status badge.
|
|
647
|
+
*/
|
|
648
|
+
declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
|
|
649
|
+
/**
|
|
650
|
+
* Used to report about app-level reconnection issues.
|
|
651
|
+
*
|
|
652
|
+
* Normal (quick) reconnects won't be reported as a "lost connection". Instead,
|
|
653
|
+
* the application will only get an event if the reconnection attempts by the
|
|
654
|
+
* client are taking (much) longer than usual. Definitely a situation you want
|
|
655
|
+
* to inform your users about, for example, by throwing a toast message on
|
|
656
|
+
* screen, or show a "trying to reconnect" banner.
|
|
657
|
+
*/
|
|
658
|
+
declare type LostConnectionEvent = "lost" | "restored" | "failed";
|
|
659
|
+
/**
|
|
660
|
+
* Arbitrary record that will be used as the authentication "token". It's the
|
|
661
|
+
* value that is returned by calling the authentication delegate, and will get
|
|
662
|
+
* passed to the connection factory delegate. This value will be remembered by
|
|
663
|
+
* the connection manager, but its value will not be interpreted, so it can be
|
|
664
|
+
* any value (except null).
|
|
665
|
+
*/
|
|
666
|
+
declare type BaseAuthResult = NonNullable<Json>;
|
|
667
|
+
declare type Delegates<T extends BaseAuthResult> = {
|
|
668
|
+
authenticate: () => Promise<T>;
|
|
669
|
+
createSocket: (token: T) => IWebSocketInstance;
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
declare type IdTuple<T> = [id: string, value: T];
|
|
673
|
+
declare enum CrdtType {
|
|
674
|
+
OBJECT = 0,
|
|
675
|
+
LIST = 1,
|
|
676
|
+
MAP = 2,
|
|
677
|
+
REGISTER = 3
|
|
678
|
+
}
|
|
679
|
+
declare type SerializedCrdt = SerializedRootObject | SerializedChild;
|
|
680
|
+
declare type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister;
|
|
681
|
+
declare type SerializedRootObject = {
|
|
682
|
+
readonly type: CrdtType.OBJECT;
|
|
683
|
+
readonly data: JsonObject;
|
|
684
|
+
readonly parentId?: never;
|
|
685
|
+
readonly parentKey?: never;
|
|
686
|
+
};
|
|
687
|
+
declare type SerializedObject = {
|
|
688
|
+
readonly type: CrdtType.OBJECT;
|
|
689
|
+
readonly parentId: string;
|
|
690
|
+
readonly parentKey: string;
|
|
691
|
+
readonly data: JsonObject;
|
|
692
|
+
};
|
|
693
|
+
declare type SerializedList = {
|
|
694
|
+
readonly type: CrdtType.LIST;
|
|
695
|
+
readonly parentId: string;
|
|
696
|
+
readonly parentKey: string;
|
|
697
|
+
};
|
|
698
|
+
declare type SerializedMap = {
|
|
699
|
+
readonly type: CrdtType.MAP;
|
|
700
|
+
readonly parentId: string;
|
|
701
|
+
readonly parentKey: string;
|
|
702
|
+
};
|
|
703
|
+
declare type SerializedRegister = {
|
|
704
|
+
readonly type: CrdtType.REGISTER;
|
|
705
|
+
readonly parentId: string;
|
|
706
|
+
readonly parentKey: string;
|
|
707
|
+
readonly data: Json;
|
|
708
|
+
};
|
|
709
|
+
declare function isRootCrdt(crdt: SerializedCrdt): crdt is SerializedRootObject;
|
|
710
|
+
declare function isChildCrdt(crdt: SerializedCrdt): crdt is SerializedChild;
|
|
711
|
+
|
|
712
|
+
declare enum ServerMsgCode {
|
|
713
|
+
UPDATE_PRESENCE = 100,
|
|
714
|
+
USER_JOINED = 101,
|
|
715
|
+
USER_LEFT = 102,
|
|
716
|
+
BROADCASTED_EVENT = 103,
|
|
717
|
+
ROOM_STATE = 104,
|
|
718
|
+
INITIAL_STORAGE_STATE = 200,
|
|
719
|
+
UPDATE_STORAGE = 201,
|
|
720
|
+
REJECT_STORAGE_OP = 299,
|
|
721
|
+
UPDATE_YDOC = 300
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Messages that can be sent from the server to the client.
|
|
725
|
+
*/
|
|
726
|
+
declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg | RejectedStorageOpServerMsg | YDocUpdate;
|
|
727
|
+
/**
|
|
728
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
729
|
+
* a User updated their presence. For example, when a user moves their cursor.
|
|
730
|
+
*
|
|
731
|
+
* In most cases, the data payload will only include the fields from the
|
|
732
|
+
* Presence that have been changed since the last announcement. However, after
|
|
733
|
+
* a new user joins a room, a "full presence" will be announced so the newly
|
|
734
|
+
* connected user will get each other's user full presence at least once. In
|
|
735
|
+
* those cases, the `targetActor` field indicates the newly connected client,
|
|
736
|
+
* so all other existing clients can ignore this broadcasted message.
|
|
737
|
+
*/
|
|
738
|
+
declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
|
|
739
|
+
readonly type: ServerMsgCode.UPDATE_PRESENCE;
|
|
740
|
+
/**
|
|
741
|
+
* The User whose Presence has changed.
|
|
742
|
+
*/
|
|
743
|
+
readonly actor: number;
|
|
744
|
+
/**
|
|
745
|
+
* When set, signifies that this is a Full Presence™ update, not a patch.
|
|
746
|
+
*
|
|
747
|
+
* The numeric value itself no longer has specific meaning. Historically,
|
|
748
|
+
* this field was intended so that clients could ignore these broadcasted
|
|
749
|
+
* full presence messages, but it turned out that getting a full presence
|
|
750
|
+
* "keyframe" from time to time was useful.
|
|
751
|
+
*
|
|
752
|
+
* So nowadays, the presence (pun intended) of this `targetActor` field
|
|
753
|
+
* is a backward-compatible way of expressing that the `data` contains
|
|
754
|
+
* all presence fields, and isn't a partial "patch".
|
|
755
|
+
*/
|
|
756
|
+
readonly targetActor: number;
|
|
757
|
+
/**
|
|
758
|
+
* The partial or full Presence of a User. If the `targetActor` field is set,
|
|
759
|
+
* this will be the full Presence, otherwise it only contain the fields that
|
|
760
|
+
* have changed since the last broadcast.
|
|
761
|
+
*/
|
|
762
|
+
readonly data: TPresence;
|
|
763
|
+
} | {
|
|
764
|
+
readonly type: ServerMsgCode.UPDATE_PRESENCE;
|
|
765
|
+
/**
|
|
766
|
+
* The User whose Presence has changed.
|
|
767
|
+
*/
|
|
768
|
+
readonly actor: number;
|
|
769
|
+
/**
|
|
770
|
+
* Not set for partial presence updates.
|
|
771
|
+
*/
|
|
772
|
+
readonly targetActor?: undefined;
|
|
773
|
+
/**
|
|
774
|
+
* A partial Presence patch to apply to the User. It will only contain the
|
|
775
|
+
* fields that have changed since the last broadcast.
|
|
776
|
+
*/
|
|
777
|
+
readonly data: Partial<TPresence>;
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
781
|
+
* a new User has joined the Room.
|
|
782
|
+
*/
|
|
783
|
+
declare type UserJoinServerMsg<TUserMeta extends BaseUserMeta> = {
|
|
784
|
+
readonly type: ServerMsgCode.USER_JOINED;
|
|
785
|
+
readonly actor: number;
|
|
786
|
+
/**
|
|
787
|
+
* The id of the User that has been set in the authentication endpoint.
|
|
788
|
+
* Useful to get additional information about the connected user.
|
|
789
|
+
*/
|
|
790
|
+
readonly id: TUserMeta["id"];
|
|
791
|
+
/**
|
|
792
|
+
* Additional user information that has been set in the authentication
|
|
793
|
+
* endpoint.
|
|
794
|
+
*/
|
|
795
|
+
readonly info: TUserMeta["info"];
|
|
796
|
+
/**
|
|
797
|
+
* Permissions that the user has in the Room.
|
|
798
|
+
*/
|
|
799
|
+
readonly scopes: string[];
|
|
800
|
+
};
|
|
801
|
+
/**
|
|
802
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
803
|
+
* a new User has left the Room.
|
|
804
|
+
*/
|
|
805
|
+
declare type UserLeftServerMsg = {
|
|
806
|
+
readonly type: ServerMsgCode.USER_LEFT;
|
|
807
|
+
readonly actor: number;
|
|
808
|
+
};
|
|
809
|
+
/**
|
|
810
|
+
* Sent by the WebSocket server when the ydoc is updated or when requested based on stateVector passed.
|
|
811
|
+
* Contains a base64 encoded update
|
|
812
|
+
*/
|
|
813
|
+
declare type YDocUpdate = {
|
|
814
|
+
readonly type: ServerMsgCode.UPDATE_YDOC;
|
|
815
|
+
readonly update: string;
|
|
816
|
+
readonly isSync: boolean;
|
|
817
|
+
};
|
|
818
|
+
/**
|
|
819
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
820
|
+
* a User broadcasted an Event to everyone in the Room.
|
|
821
|
+
*/
|
|
822
|
+
declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
|
|
823
|
+
readonly type: ServerMsgCode.BROADCASTED_EVENT;
|
|
824
|
+
/**
|
|
825
|
+
* The User who broadcasted the Event.
|
|
826
|
+
*/
|
|
827
|
+
readonly actor: number;
|
|
828
|
+
/**
|
|
829
|
+
* The arbitrary payload of the Event. This can be any JSON value. Clients
|
|
830
|
+
* will have to manually verify/decode this event.
|
|
831
|
+
*/
|
|
832
|
+
readonly event: TRoomEvent;
|
|
833
|
+
};
|
|
834
|
+
/**
|
|
835
|
+
* Sent by the WebSocket server to a single client in response to the client
|
|
836
|
+
* joining the Room, to provide the initial state of the Room. The payload
|
|
837
|
+
* includes a list of all other Users that already are in the Room.
|
|
838
|
+
*/
|
|
839
|
+
declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
|
|
840
|
+
readonly type: ServerMsgCode.ROOM_STATE;
|
|
841
|
+
/**
|
|
842
|
+
* Informs the client what their actor ID is going to be.
|
|
843
|
+
* @since v1.2 (WS API v7)
|
|
844
|
+
*/
|
|
845
|
+
readonly actor: number;
|
|
846
|
+
/**
|
|
847
|
+
* Informs the client what permissions the current User (self) has.
|
|
848
|
+
* @since v1.2 (WS API v7)
|
|
849
|
+
*/
|
|
850
|
+
readonly scopes: string[];
|
|
851
|
+
readonly users: {
|
|
852
|
+
readonly [actor: number]: TUserMeta & {
|
|
853
|
+
scopes: string[];
|
|
854
|
+
};
|
|
855
|
+
};
|
|
856
|
+
};
|
|
857
|
+
/**
|
|
858
|
+
* Sent by the WebSocket server to a single client in response to the client
|
|
859
|
+
* joining the Room, to provide the initial Storage state of the Room. The
|
|
860
|
+
* payload includes the entire Storage document.
|
|
861
|
+
*/
|
|
862
|
+
declare type InitialDocumentStateServerMsg = {
|
|
863
|
+
readonly type: ServerMsgCode.INITIAL_STORAGE_STATE;
|
|
864
|
+
readonly items: IdTuple<SerializedCrdt>[];
|
|
865
|
+
};
|
|
866
|
+
/**
|
|
867
|
+
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
868
|
+
* a change occurred in the Storage document.
|
|
869
|
+
*
|
|
870
|
+
* The payload of this message contains a list of Ops (aka incremental
|
|
871
|
+
* mutations to make to the initially loaded document).
|
|
872
|
+
*/
|
|
873
|
+
declare type UpdateStorageServerMsg = {
|
|
874
|
+
readonly type: ServerMsgCode.UPDATE_STORAGE;
|
|
875
|
+
readonly ops: Op[];
|
|
876
|
+
};
|
|
877
|
+
/**
|
|
878
|
+
* Sent by the WebSocket server to the client to indicate that certain opIds
|
|
879
|
+
* have been received but were rejected because they caused mutations that are
|
|
880
|
+
* incompatible with the Room's schema.
|
|
881
|
+
*/
|
|
882
|
+
declare type RejectedStorageOpServerMsg = {
|
|
883
|
+
readonly type: ServerMsgCode.REJECT_STORAGE_OP;
|
|
884
|
+
readonly opIds: string[];
|
|
885
|
+
readonly reason: string;
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
declare type ReadonlyArrayWithLegacyMethods<T> = readonly T[] & {
|
|
889
|
+
/**
|
|
890
|
+
* @deprecated Prefer the normal .length property on arrays.
|
|
891
|
+
*/
|
|
892
|
+
readonly count: number;
|
|
893
|
+
/**
|
|
894
|
+
* @deprecated Calling .toArray() is no longer needed
|
|
895
|
+
*/
|
|
896
|
+
readonly toArray: () => readonly T[];
|
|
897
|
+
};
|
|
898
|
+
declare function asArrayWithLegacyMethods<T>(arr: readonly T[]): ReadonlyArrayWithLegacyMethods<T>;
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Represents a user connected in a room. Treated as immutable.
|
|
902
|
+
*/
|
|
903
|
+
declare type User<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
|
|
904
|
+
/**
|
|
905
|
+
* The connection ID of the User. It is unique and increment at every new connection.
|
|
906
|
+
*/
|
|
907
|
+
readonly connectionId: number;
|
|
908
|
+
/**
|
|
909
|
+
* The ID of the User that has been set in the authentication endpoint.
|
|
910
|
+
* Useful to get additional information about the connected user.
|
|
911
|
+
*/
|
|
912
|
+
readonly id: TUserMeta["id"];
|
|
913
|
+
/**
|
|
914
|
+
* Additional user information that has been set in the authentication endpoint.
|
|
915
|
+
*/
|
|
916
|
+
readonly info: TUserMeta["info"];
|
|
917
|
+
/**
|
|
918
|
+
* The user’s presence data.
|
|
919
|
+
*/
|
|
920
|
+
readonly presence: TPresence;
|
|
921
|
+
/**
|
|
922
|
+
* False if the user can modify the room storage, true otherwise.
|
|
923
|
+
*/
|
|
924
|
+
readonly isReadOnly: boolean;
|
|
925
|
+
};
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Represents all the other users connected in the room. Treated as immutable.
|
|
929
|
+
*/
|
|
930
|
+
declare type Others<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = ReadonlyArrayWithLegacyMethods<User<TPresence, TUserMeta>>;
|
|
931
|
+
declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
|
|
932
|
+
type: "leave";
|
|
933
|
+
user: User<TPresence, TUserMeta>;
|
|
934
|
+
} | {
|
|
935
|
+
type: "enter";
|
|
936
|
+
user: User<TPresence, TUserMeta>;
|
|
937
|
+
} | {
|
|
938
|
+
type: "update";
|
|
939
|
+
user: User<TPresence, TUserMeta>;
|
|
940
|
+
updates: Partial<TPresence>;
|
|
941
|
+
} | {
|
|
942
|
+
type: "reset";
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
declare type CustomEvent<TRoomEvent extends Json> = {
|
|
946
|
+
connectionId: number;
|
|
947
|
+
event: TRoomEvent;
|
|
948
|
+
};
|
|
949
|
+
declare type StorageStatus = "not-loaded" | "loading" | "synchronizing" | "synchronized";
|
|
950
|
+
interface History {
|
|
951
|
+
/**
|
|
952
|
+
* Undoes the last operation executed by the current client.
|
|
953
|
+
* It does not impact operations made by other clients.
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* room.updatePresence({ selectedId: "xx" }, { addToHistory: true });
|
|
957
|
+
* room.updatePresence({ selectedId: "yy" }, { addToHistory: true });
|
|
958
|
+
* room.history.undo();
|
|
959
|
+
* // room.getPresence() equals { selectedId: "xx" }
|
|
960
|
+
*/
|
|
961
|
+
undo: () => void;
|
|
962
|
+
/**
|
|
963
|
+
* Redoes the last operation executed by the current client.
|
|
964
|
+
* It does not impact operations made by other clients.
|
|
965
|
+
*
|
|
966
|
+
* @example
|
|
967
|
+
* room.updatePresence({ selectedId: "xx" }, { addToHistory: true });
|
|
968
|
+
* room.updatePresence({ selectedId: "yy" }, { addToHistory: true });
|
|
969
|
+
* room.history.undo();
|
|
970
|
+
* // room.getPresence() equals { selectedId: "xx" }
|
|
971
|
+
* room.history.redo();
|
|
972
|
+
* // room.getPresence() equals { selectedId: "yy" }
|
|
973
|
+
*/
|
|
974
|
+
redo: () => void;
|
|
975
|
+
/**
|
|
976
|
+
* Returns whether there are any operations to undo.
|
|
977
|
+
*
|
|
978
|
+
* @example
|
|
979
|
+
* room.updatePresence({ selectedId: "xx" }, { addToHistory: true });
|
|
980
|
+
* // room.history.canUndo() is true
|
|
981
|
+
* room.history.undo();
|
|
982
|
+
* // room.history.canUndo() is false
|
|
983
|
+
*/
|
|
984
|
+
canUndo: () => boolean;
|
|
985
|
+
/**
|
|
986
|
+
* Returns whether there are any operations to redo.
|
|
987
|
+
*
|
|
988
|
+
* @example
|
|
989
|
+
* room.updatePresence({ selectedId: "xx" }, { addToHistory: true });
|
|
990
|
+
* room.history.undo();
|
|
991
|
+
* // room.history.canRedo() is true
|
|
992
|
+
* room.history.redo();
|
|
993
|
+
* // room.history.canRedo() is false
|
|
994
|
+
*/
|
|
995
|
+
canRedo: () => boolean;
|
|
996
|
+
/**
|
|
997
|
+
* All future modifications made on the Room will be merged together to create a single history item until resume is called.
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
|
|
1001
|
+
* room.history.pause();
|
|
1002
|
+
* room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
|
|
1003
|
+
* room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
|
|
1004
|
+
* room.history.resume();
|
|
1005
|
+
* room.history.undo();
|
|
1006
|
+
* // room.getPresence() equals { cursor: { x: 0, y: 0 } }
|
|
1007
|
+
*/
|
|
1008
|
+
pause: () => void;
|
|
1009
|
+
/**
|
|
1010
|
+
* Resumes history. Modifications made on the Room are not merged into a single history item anymore.
|
|
1011
|
+
*
|
|
1012
|
+
* @example
|
|
1013
|
+
* room.updatePresence({ cursor: { x: 0, y: 0 } }, { addToHistory: true });
|
|
1014
|
+
* room.history.pause();
|
|
1015
|
+
* room.updatePresence({ cursor: { x: 1, y: 1 } }, { addToHistory: true });
|
|
1016
|
+
* room.updatePresence({ cursor: { x: 2, y: 2 } }, { addToHistory: true });
|
|
1017
|
+
* room.history.resume();
|
|
1018
|
+
* room.history.undo();
|
|
1019
|
+
* // room.getPresence() equals { cursor: { x: 0, y: 0 } }
|
|
1020
|
+
*/
|
|
1021
|
+
resume: () => void;
|
|
1022
|
+
}
|
|
1023
|
+
declare type HistoryEvent = {
|
|
1024
|
+
canUndo: boolean;
|
|
1025
|
+
canRedo: boolean;
|
|
1026
|
+
};
|
|
1027
|
+
declare type BroadcastOptions = {
|
|
1028
|
+
/**
|
|
1029
|
+
* Whether or not event is queued if the connection is currently closed.
|
|
1030
|
+
*
|
|
1031
|
+
* ❗ We are not sure if we want to support this option in the future so it might be deprecated to be replaced by something else
|
|
1032
|
+
*/
|
|
1033
|
+
shouldQueueEventIfNotReady: boolean;
|
|
1034
|
+
};
|
|
1035
|
+
declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = {
|
|
1036
|
+
/**
|
|
1037
|
+
* Subscribe to the current user presence updates.
|
|
1038
|
+
*
|
|
1039
|
+
* @param listener the callback that is called every time the current user presence is updated with {@link Room.updatePresence}.
|
|
1040
|
+
*
|
|
1041
|
+
* @returns Unsubscribe function.
|
|
1042
|
+
*
|
|
1043
|
+
* @example
|
|
1044
|
+
* room.subscribe("my-presence", (presence) => {
|
|
1045
|
+
* // Do something
|
|
1046
|
+
* });
|
|
1047
|
+
*/
|
|
1048
|
+
(type: "my-presence", listener: Callback<TPresence>): () => void;
|
|
1049
|
+
/**
|
|
1050
|
+
* Subscribe to the other users updates.
|
|
1051
|
+
*
|
|
1052
|
+
* @param listener the callback that is called when a user enters or leaves the room or when a user update its presence.
|
|
1053
|
+
*
|
|
1054
|
+
* @returns Unsubscribe function.
|
|
1055
|
+
*
|
|
1056
|
+
* @example
|
|
1057
|
+
* room.subscribe("others", (others) => {
|
|
1058
|
+
* // Do something
|
|
1059
|
+
* });
|
|
1060
|
+
*
|
|
1061
|
+
*/
|
|
1062
|
+
(type: "others", listener: (others: Others<TPresence, TUserMeta>, event: OthersEvent<TPresence, TUserMeta>) => void): () => void;
|
|
1063
|
+
/**
|
|
1064
|
+
* Subscribe to events broadcasted by {@link Room.broadcastEvent}
|
|
1065
|
+
*
|
|
1066
|
+
* @param listener the callback that is called when a user calls {@link Room.broadcastEvent}
|
|
1067
|
+
*
|
|
1068
|
+
* @returns Unsubscribe function.
|
|
1069
|
+
*
|
|
1070
|
+
* @example
|
|
1071
|
+
* room.subscribe("event", ({ event, connectionId }) => {
|
|
1072
|
+
* // Do something
|
|
1073
|
+
* });
|
|
1074
|
+
*
|
|
1075
|
+
*/
|
|
1076
|
+
(type: "event", listener: Callback<CustomEvent<TRoomEvent>>): () => void;
|
|
1077
|
+
/**
|
|
1078
|
+
* Subscribe to errors thrown in the room.
|
|
1079
|
+
*
|
|
1080
|
+
* @returns Unsubscribe function.
|
|
1081
|
+
*
|
|
1082
|
+
*/
|
|
1083
|
+
(type: "error", listener: ErrorCallback): () => void;
|
|
1084
|
+
/**
|
|
1085
|
+
* @deprecated This API will be removed in a future version of Liveblocks.
|
|
1086
|
+
* Prefer using the newer `.subscribe('status')` API.
|
|
1087
|
+
*
|
|
1088
|
+
* We recommend making the following changes if you use these APIs:
|
|
1089
|
+
*
|
|
1090
|
+
* OLD APIs NEW APIs
|
|
1091
|
+
* .getConnectionState() --> .getStatus()
|
|
1092
|
+
* .subscribe('connection') --> .subscribe('status')
|
|
1093
|
+
*
|
|
1094
|
+
* OLD STATUSES NEW STATUSES
|
|
1095
|
+
* closed --> initial
|
|
1096
|
+
* authenticating --> connecting
|
|
1097
|
+
* connecting --> connecting
|
|
1098
|
+
* open --> connected
|
|
1099
|
+
* unavailable --> reconnecting
|
|
1100
|
+
* failed --> disconnected
|
|
1101
|
+
*
|
|
1102
|
+
* Subscribe to legacy connection status updates.
|
|
1103
|
+
*
|
|
1104
|
+
* @returns Unsubscribe function.
|
|
1105
|
+
*
|
|
1106
|
+
*/
|
|
1107
|
+
(type: "connection", listener: Callback<LegacyConnectionStatus>): () => void;
|
|
1108
|
+
/**
|
|
1109
|
+
* Subscribe to connection status updates. The callback will be called any
|
|
1110
|
+
* time the status changes.
|
|
1111
|
+
*
|
|
1112
|
+
* @returns Unsubscribe function.
|
|
1113
|
+
*
|
|
1114
|
+
*/
|
|
1115
|
+
(type: "status", listener: Callback<Status>): () => void;
|
|
1116
|
+
/**
|
|
1117
|
+
* Subscribe to the exceptional event where reconnecting to the Liveblocks
|
|
1118
|
+
* servers is taking longer than usual. This typically is a sign of a client
|
|
1119
|
+
* that has lost internet connectivity.
|
|
1120
|
+
*
|
|
1121
|
+
* This isn't problematic (because the Liveblocks client is still trying to
|
|
1122
|
+
* reconnect), but it's typically a good idea to inform users about it if
|
|
1123
|
+
* the connection takes too long to recover.
|
|
1124
|
+
*/
|
|
1125
|
+
(type: "lost-connection", listener: Callback<LostConnectionEvent>): () => void;
|
|
1126
|
+
/**
|
|
1127
|
+
* Subscribes to changes made on a Live structure. Returns an unsubscribe function.
|
|
1128
|
+
* In a future version, we will also expose what exactly changed in the Live structure.
|
|
1129
|
+
*
|
|
1130
|
+
* @param callback The callback this called when the Live structure changes.
|
|
1131
|
+
*
|
|
1132
|
+
* @returns Unsubscribe function.
|
|
1133
|
+
*
|
|
1134
|
+
* @example
|
|
1135
|
+
* const liveMap = new LiveMap(); // Could also be LiveList or LiveObject
|
|
1136
|
+
* const unsubscribe = room.subscribe(liveMap, (liveMap) => { });
|
|
1137
|
+
* unsubscribe();
|
|
1138
|
+
*/
|
|
1139
|
+
<L extends LiveStructure>(liveStructure: L, callback: (node: L) => void): () => void;
|
|
1140
|
+
/**
|
|
1141
|
+
* Subscribes to changes made on a Live structure and all the nested data
|
|
1142
|
+
* structures. Returns an unsubscribe function. In a future version, we
|
|
1143
|
+
* will also expose what exactly changed in the Live structure.
|
|
1144
|
+
*
|
|
1145
|
+
* @param callback The callback this called when the Live structure, or any
|
|
1146
|
+
* of its nested values, changes.
|
|
1147
|
+
*
|
|
1148
|
+
* @returns Unsubscribe function.
|
|
1149
|
+
*
|
|
1150
|
+
* @example
|
|
1151
|
+
* const liveMap = new LiveMap(); // Could also be LiveList or LiveObject
|
|
1152
|
+
* const unsubscribe = room.subscribe(liveMap, (updates) => { }, { isDeep: true });
|
|
1153
|
+
* unsubscribe();
|
|
1154
|
+
*/
|
|
1155
|
+
<L extends LiveStructure>(liveStructure: L, callback: StorageCallback, options: {
|
|
1156
|
+
isDeep: true;
|
|
1157
|
+
}): () => void;
|
|
1158
|
+
/**
|
|
1159
|
+
* Subscribe to the current user's history changes.
|
|
1160
|
+
*
|
|
1161
|
+
* @returns Unsubscribe function.
|
|
1162
|
+
*
|
|
1163
|
+
* @example
|
|
1164
|
+
* room.subscribe("history", ({ canUndo, canRedo }) => {
|
|
1165
|
+
* // Do something
|
|
1166
|
+
* });
|
|
1167
|
+
*/
|
|
1168
|
+
(type: "history", listener: Callback<HistoryEvent>): () => void;
|
|
1169
|
+
/**
|
|
1170
|
+
* Subscribe to storage status changes.
|
|
1171
|
+
*
|
|
1172
|
+
* @returns Unsubscribe function.
|
|
1173
|
+
*
|
|
1174
|
+
* @example
|
|
1175
|
+
* room.subscribe("storage-status", (status) => {
|
|
1176
|
+
* switch(status) {
|
|
1177
|
+
* case "not-loaded":
|
|
1178
|
+
* break;
|
|
1179
|
+
* case "loading":
|
|
1180
|
+
* break;
|
|
1181
|
+
* case "synchronizing":
|
|
1182
|
+
* break;
|
|
1183
|
+
* case "synchronized":
|
|
1184
|
+
* break;
|
|
1185
|
+
* default:
|
|
1186
|
+
* break;
|
|
1187
|
+
* }
|
|
1188
|
+
* });
|
|
1189
|
+
*/
|
|
1190
|
+
(type: "storage-status", listener: Callback<StorageStatus>): () => void;
|
|
1191
|
+
};
|
|
1192
|
+
declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = {
|
|
1193
|
+
/**
|
|
1194
|
+
* The id of the room.
|
|
1195
|
+
*/
|
|
1196
|
+
readonly id: string;
|
|
1197
|
+
/**
|
|
1198
|
+
* A client is considered "self aware" if it knows its own
|
|
1199
|
+
* metadata and connection ID (from the auth server).
|
|
1200
|
+
*/
|
|
1201
|
+
isSelfAware(): boolean;
|
|
1202
|
+
/**
|
|
1203
|
+
* @deprecated This API will be removed in a future version of Liveblocks.
|
|
1204
|
+
* Prefer using `.getStatus()` instead.
|
|
1205
|
+
*
|
|
1206
|
+
* We recommend making the following changes if you use these APIs:
|
|
1207
|
+
*
|
|
1208
|
+
* OLD APIs NEW APIs
|
|
1209
|
+
* .getConnectionState() --> .getStatus()
|
|
1210
|
+
* .subscribe('connection') --> .subscribe('status')
|
|
1211
|
+
*
|
|
1212
|
+
* OLD STATUSES NEW STATUSES
|
|
1213
|
+
* closed --> initial
|
|
1214
|
+
* authenticating --> connecting
|
|
1215
|
+
* connecting --> connecting
|
|
1216
|
+
* open --> connected
|
|
1217
|
+
* unavailable --> reconnecting
|
|
1218
|
+
* failed --> disconnected
|
|
1219
|
+
*/
|
|
1220
|
+
getConnectionState(): LegacyConnectionStatus;
|
|
1221
|
+
/**
|
|
1222
|
+
* Return the current connection status for this room. Can be used to display
|
|
1223
|
+
* a status badge for your Liveblocks connection.
|
|
1224
|
+
*/
|
|
1225
|
+
getStatus(): Status;
|
|
1226
|
+
readonly subscribe: SubscribeFn<TPresence, TStorage, TUserMeta, TRoomEvent>;
|
|
1227
|
+
/**
|
|
1228
|
+
* Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
|
|
1229
|
+
*/
|
|
1230
|
+
readonly history: History;
|
|
1231
|
+
/**
|
|
1232
|
+
* Gets the current user.
|
|
1233
|
+
* Returns null if not it is not yet connected to the room.
|
|
1234
|
+
*
|
|
1235
|
+
* @example
|
|
1236
|
+
* const user = room.getSelf();
|
|
1237
|
+
*/
|
|
1238
|
+
getSelf(): User<TPresence, TUserMeta> | null;
|
|
1239
|
+
/**
|
|
1240
|
+
* Gets the presence of the current user.
|
|
1241
|
+
*
|
|
1242
|
+
* @example
|
|
1243
|
+
* const presence = room.getPresence();
|
|
1244
|
+
*/
|
|
1245
|
+
getPresence(): TPresence;
|
|
1246
|
+
/**
|
|
1247
|
+
* Gets all the other users in the room.
|
|
1248
|
+
*
|
|
1249
|
+
* @example
|
|
1250
|
+
* const others = room.getOthers();
|
|
1251
|
+
*/
|
|
1252
|
+
getOthers(): Others<TPresence, TUserMeta>;
|
|
1253
|
+
/**
|
|
1254
|
+
* Updates the presence of the current user. Only pass the properties you want to update. No need to send the full presence.
|
|
1255
|
+
* @param patch A partial object that contains the properties you want to update.
|
|
1256
|
+
* @param options Optional object to configure the behavior of updatePresence.
|
|
1257
|
+
*
|
|
1258
|
+
* @example
|
|
1259
|
+
* room.updatePresence({ x: 0 });
|
|
1260
|
+
* room.updatePresence({ y: 0 });
|
|
1261
|
+
*
|
|
1262
|
+
* const presence = room.getPresence();
|
|
1263
|
+
* // presence is equivalent to { x: 0, y: 0 }
|
|
1264
|
+
*/
|
|
1265
|
+
updatePresence(patch: Partial<TPresence>, options?: {
|
|
1266
|
+
/**
|
|
1267
|
+
* Whether or not the presence should have an impact on the undo/redo history.
|
|
1268
|
+
*/
|
|
1269
|
+
addToHistory: boolean;
|
|
1270
|
+
}): void;
|
|
1271
|
+
/**
|
|
1272
|
+
*
|
|
1273
|
+
* Sends Yjs document updates to liveblocks server
|
|
1274
|
+
*
|
|
1275
|
+
* @param {string} data the doc update to send to the server, base64 encoded uint8array
|
|
1276
|
+
*/
|
|
1277
|
+
updateYDoc(data: string): void;
|
|
1278
|
+
/**
|
|
1279
|
+
* Sends a request for the current document from liveblocks server
|
|
1280
|
+
*/
|
|
1281
|
+
fetchYDoc(stateVector: string): void;
|
|
1282
|
+
/**
|
|
1283
|
+
* Broadcasts an event to other users in the room. Event broadcasted to the room can be listened with {@link Room.subscribe}("event").
|
|
1284
|
+
* @param {any} event the event to broadcast. Should be serializable to JSON
|
|
1285
|
+
*
|
|
1286
|
+
* @example
|
|
1287
|
+
* // On client A
|
|
1288
|
+
* room.broadcastEvent({ type: "EMOJI", emoji: "🔥" });
|
|
1289
|
+
*
|
|
1290
|
+
* // On client B
|
|
1291
|
+
* room.subscribe("event", ({ event }) => {
|
|
1292
|
+
* if(event.type === "EMOJI") {
|
|
1293
|
+
* // Do something
|
|
1294
|
+
* }
|
|
1295
|
+
* });
|
|
1296
|
+
*/
|
|
1297
|
+
broadcastEvent(event: TRoomEvent, options?: BroadcastOptions): void;
|
|
1298
|
+
/**
|
|
1299
|
+
* Get the room's storage asynchronously.
|
|
1300
|
+
* The storage's root is a {@link LiveObject}.
|
|
1301
|
+
*
|
|
1302
|
+
* @example
|
|
1303
|
+
* const { root } = await room.getStorage();
|
|
1304
|
+
*/
|
|
1305
|
+
getStorage(): Promise<{
|
|
1306
|
+
root: LiveObject<TStorage>;
|
|
1307
|
+
}>;
|
|
1308
|
+
/**
|
|
1309
|
+
* Get the room's storage synchronously.
|
|
1310
|
+
* The storage's root is a {@link LiveObject}.
|
|
1311
|
+
*
|
|
1312
|
+
* @example
|
|
1313
|
+
* const root = room.getStorageSnapshot();
|
|
1314
|
+
*/
|
|
1315
|
+
getStorageSnapshot(): LiveObject<TStorage> | null;
|
|
1316
|
+
readonly events: {
|
|
1317
|
+
readonly connection: Observable<LegacyConnectionStatus>;
|
|
1318
|
+
readonly status: Observable<Status>;
|
|
1319
|
+
readonly lostConnection: Observable<LostConnectionEvent>;
|
|
1320
|
+
readonly customEvent: Observable<{
|
|
1321
|
+
connectionId: number;
|
|
1322
|
+
event: TRoomEvent;
|
|
1323
|
+
}>;
|
|
1324
|
+
readonly me: Observable<TPresence>;
|
|
1325
|
+
readonly others: Observable<{
|
|
1326
|
+
others: Others<TPresence, TUserMeta>;
|
|
1327
|
+
event: OthersEvent<TPresence, TUserMeta>;
|
|
1328
|
+
}>;
|
|
1329
|
+
readonly error: Observable<Error>;
|
|
1330
|
+
readonly storage: Observable<StorageUpdate[]>;
|
|
1331
|
+
readonly history: Observable<HistoryEvent>;
|
|
1332
|
+
/**
|
|
1333
|
+
* Subscribe to the storage loaded event. Will fire any time a full Storage
|
|
1334
|
+
* copy is downloaded. (This happens after the initial connect, and on
|
|
1335
|
+
* every reconnect.)
|
|
1336
|
+
*/
|
|
1337
|
+
readonly storageDidLoad: Observable<void>;
|
|
1338
|
+
readonly storageStatus: Observable<StorageStatus>;
|
|
1339
|
+
readonly ydoc: Observable<YDocUpdate>;
|
|
1340
|
+
};
|
|
1341
|
+
/**
|
|
1342
|
+
* Batches modifications made during the given function.
|
|
1343
|
+
* All the modifications are sent to other clients in a single message.
|
|
1344
|
+
* All the subscribers are called only after the batch is over.
|
|
1345
|
+
* All the modifications are merged in a single history item (undo/redo).
|
|
1346
|
+
*
|
|
1347
|
+
* @example
|
|
1348
|
+
* const { root } = await room.getStorage();
|
|
1349
|
+
* room.batch(() => {
|
|
1350
|
+
* root.set("x", 0);
|
|
1351
|
+
* room.updatePresence({ cursor: { x: 100, y: 100 }});
|
|
1352
|
+
* });
|
|
1353
|
+
*/
|
|
1354
|
+
batch<T>(fn: () => T): T;
|
|
1355
|
+
/**
|
|
1356
|
+
* Get the storage status.
|
|
1357
|
+
*
|
|
1358
|
+
* - `not-loaded`: Initial state when entering the room.
|
|
1359
|
+
* - `loading`: Once the storage has been requested via room.getStorage().
|
|
1360
|
+
* - `synchronizing`: When some local updates have not been acknowledged by Liveblocks servers.
|
|
1361
|
+
* - `synchronized`: Storage is in sync with Liveblocks servers.
|
|
1362
|
+
*/
|
|
1363
|
+
getStorageStatus(): StorageStatus;
|
|
1364
|
+
/**
|
|
1365
|
+
* Reconnect the room to the Liveblocks server by re-establishing a fresh
|
|
1366
|
+
* connection. If the room is not connected yet, initiate it.
|
|
1367
|
+
*/
|
|
1368
|
+
reconnect(): void;
|
|
1369
|
+
};
|
|
1370
|
+
declare type Polyfills = {
|
|
1371
|
+
atob?: (data: string) => string;
|
|
1372
|
+
fetch?: typeof fetch;
|
|
1373
|
+
WebSocket?: IWebSocket;
|
|
1374
|
+
};
|
|
1375
|
+
declare type RoomInitializers<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<{
|
|
1376
|
+
/**
|
|
1377
|
+
* The initial Presence to use and announce when you enter the Room. The
|
|
1378
|
+
* Presence is available on all users in the Room (me & others).
|
|
1379
|
+
*/
|
|
1380
|
+
initialPresence: TPresence | ((roomId: string) => TPresence);
|
|
1381
|
+
/**
|
|
1382
|
+
* The initial Storage to use when entering a new Room.
|
|
1383
|
+
*/
|
|
1384
|
+
initialStorage?: TStorage | ((roomId: string) => TStorage);
|
|
1385
|
+
/**
|
|
1386
|
+
* Whether or not the room connects to Liveblock servers. Default is true.
|
|
1387
|
+
*
|
|
1388
|
+
* Usually set to false when the client is used from the server to not call
|
|
1389
|
+
* the authentication endpoint or connect via WebSocket.
|
|
1390
|
+
*/
|
|
1391
|
+
shouldInitiallyConnect?: boolean;
|
|
1392
|
+
}>;
|
|
1393
|
+
|
|
1394
|
+
declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<RoomInitializers<TPresence, TStorage> & {
|
|
1395
|
+
/**
|
|
1396
|
+
* Only necessary when you’re using Liveblocks with React v17 or lower.
|
|
1397
|
+
*
|
|
1398
|
+
* If so, pass in a reference to `ReactDOM.unstable_batchedUpdates` here.
|
|
1399
|
+
* This will allow Liveblocks to circumvent the so-called "zombie child
|
|
1400
|
+
* problem". To learn more, see
|
|
1401
|
+
* https://liveblocks.io/docs/guides/troubleshooting#stale-props-zombie-child
|
|
1402
|
+
*/
|
|
1403
|
+
unstable_batchedUpdates?: (cb: () => void) => void;
|
|
1404
|
+
}>;
|
|
1405
|
+
declare type Client = {
|
|
1406
|
+
/**
|
|
1407
|
+
* Gets a room. Returns null if {@link Client.enter} has not been called previously.
|
|
1408
|
+
*
|
|
1409
|
+
* @param roomId The id of the room
|
|
1410
|
+
*/
|
|
1411
|
+
getRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
|
|
1412
|
+
/**
|
|
1413
|
+
* Enters a room and returns it.
|
|
1414
|
+
* @param roomId The id of the room
|
|
1415
|
+
* @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
|
|
1416
|
+
*/
|
|
1417
|
+
enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
|
|
1418
|
+
/**
|
|
1419
|
+
* Leaves a room.
|
|
1420
|
+
* @param roomId The id of the room
|
|
1421
|
+
*/
|
|
1422
|
+
leave(roomId: string): void;
|
|
1423
|
+
};
|
|
1424
|
+
declare type AuthEndpoint = string | ((room: string) => Promise<{
|
|
1425
|
+
token: string;
|
|
1426
|
+
}>);
|
|
1427
|
+
/**
|
|
1428
|
+
* The authentication endpoint that is called to ensure that the current user has access to a room.
|
|
1429
|
+
* Can be an url or a callback if you need to add additional headers.
|
|
1430
|
+
*/
|
|
1431
|
+
declare type ClientOptions = {
|
|
1432
|
+
throttle?: number;
|
|
1433
|
+
lostConnectionTimeout?: number;
|
|
1434
|
+
polyfills?: Polyfills;
|
|
1435
|
+
unstable_fallbackToHTTP?: boolean;
|
|
1436
|
+
/**
|
|
1437
|
+
* @deprecated Use `polyfills: { fetch: ... }` instead.
|
|
1438
|
+
* This option will be removed in a future release.
|
|
1439
|
+
*/
|
|
1440
|
+
fetchPolyfill?: Polyfills["fetch"];
|
|
1441
|
+
/**
|
|
1442
|
+
* @deprecated Use `polyfills: { WebSocket: ... }` instead.
|
|
1443
|
+
* This option will be removed in a future release.
|
|
1444
|
+
*/
|
|
1445
|
+
WebSocketPolyfill?: Polyfills["WebSocket"];
|
|
1446
|
+
} & ({
|
|
1447
|
+
publicApiKey: string;
|
|
1448
|
+
authEndpoint?: never;
|
|
1449
|
+
} | {
|
|
1450
|
+
publicApiKey?: never;
|
|
1451
|
+
authEndpoint: AuthEndpoint;
|
|
1452
|
+
});
|
|
1453
|
+
/**
|
|
1454
|
+
* Create a client that will be responsible to communicate with liveblocks servers.
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* const client = createClient({
|
|
1458
|
+
* authEndpoint: "/api/auth"
|
|
1459
|
+
* });
|
|
1460
|
+
*
|
|
1461
|
+
* // It's also possible to use a function to call your authentication endpoint.
|
|
1462
|
+
* // Useful to add additional headers or use an API wrapper (like Firebase functions)
|
|
1463
|
+
* const client = createClient({
|
|
1464
|
+
* authEndpoint: async (room) => {
|
|
1465
|
+
* const response = await fetch("/api/auth", {
|
|
1466
|
+
* method: "POST",
|
|
1467
|
+
* headers: {
|
|
1468
|
+
* Authentication: "token",
|
|
1469
|
+
* "Content-Type": "application/json"
|
|
1470
|
+
* },
|
|
1471
|
+
* body: JSON.stringify({ room })
|
|
1472
|
+
* });
|
|
1473
|
+
*
|
|
1474
|
+
* return await response.json(); // should be: { token: "..." }
|
|
1475
|
+
* }
|
|
1476
|
+
* });
|
|
1477
|
+
*/
|
|
1478
|
+
declare function createClient(options: ClientOptions): Client;
|
|
1479
|
+
|
|
1480
|
+
declare function lsonToJson(value: Lson): Json;
|
|
1481
|
+
declare function patchLiveObjectKey<O extends LsonObject, K extends keyof O, V extends Json>(liveObject: LiveObject<O>, key: K, prev?: V, next?: V): void;
|
|
1482
|
+
declare function legacy_patchImmutableObject<S extends JsonObject>(state: S, updates: StorageUpdate[]): S;
|
|
1483
|
+
|
|
1484
|
+
/**
|
|
1485
|
+
* Helper function that can be used to implement exhaustive switch statements
|
|
1486
|
+
* with TypeScript. Example usage:
|
|
1487
|
+
*
|
|
1488
|
+
* type Fruit = "🍎" | "🍌";
|
|
1489
|
+
*
|
|
1490
|
+
* switch (fruit) {
|
|
1491
|
+
* case "🍎":
|
|
1492
|
+
* case "🍌":
|
|
1493
|
+
* return doSomething();
|
|
1494
|
+
*
|
|
1495
|
+
* default:
|
|
1496
|
+
* return assertNever(fruit, "Unknown fruit");
|
|
1497
|
+
* }
|
|
1498
|
+
*
|
|
1499
|
+
* If now the Fruit union is extended (i.e. add "🍒"), TypeScript will catch
|
|
1500
|
+
* this *statically*, rather than at runtime, and force you to handle the
|
|
1501
|
+
* 🍒 case.
|
|
1502
|
+
*/
|
|
1503
|
+
declare function assertNever(_value: never, errmsg: string): never;
|
|
1504
|
+
/**
|
|
1505
|
+
* Asserts that a certain condition holds. If it does not hold, will throw
|
|
1506
|
+
* a runtime error in dev mode.
|
|
1507
|
+
*
|
|
1508
|
+
* In production, nothing is asserted and this acts as a no-op.
|
|
1509
|
+
*/
|
|
1510
|
+
declare function assert(condition: boolean, errmsg: string): asserts condition;
|
|
1511
|
+
/**
|
|
1512
|
+
* Asserts that a given value is non-nullable. This is similar to TypeScript's
|
|
1513
|
+
* `!` operator, but will throw an error at runtime (dev-mode only) indicating
|
|
1514
|
+
* an incorrect assumption.
|
|
1515
|
+
*
|
|
1516
|
+
* Instead of:
|
|
1517
|
+
*
|
|
1518
|
+
* foo!.bar
|
|
1519
|
+
*
|
|
1520
|
+
* Use:
|
|
1521
|
+
*
|
|
1522
|
+
* nn(foo).bar
|
|
1523
|
+
*
|
|
1524
|
+
*/
|
|
1525
|
+
declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
|
|
1526
|
+
|
|
1527
|
+
/**
|
|
1528
|
+
* Displays a deprecation warning in the dev console. Only in dev mode, and
|
|
1529
|
+
* only once per message/key. In production, this is a no-op.
|
|
1530
|
+
*/
|
|
1531
|
+
declare function deprecate(message: string, key?: string): void;
|
|
1532
|
+
/**
|
|
1533
|
+
* Conditionally displays a deprecation warning in the dev
|
|
1534
|
+
* console if the first argument is truthy. Only in dev mode, and
|
|
1535
|
+
* only once per message/key. In production, this is a no-op.
|
|
1536
|
+
*/
|
|
1537
|
+
declare function deprecateIf(condition: unknown, message: string, key?: string): void;
|
|
1538
|
+
/**
|
|
1539
|
+
* Throws a deprecation error in the dev console.
|
|
1540
|
+
*
|
|
1541
|
+
* Only triggers in dev mode. In production, this is a no-op.
|
|
1542
|
+
*/
|
|
1543
|
+
declare function throwUsageError(message: string): void;
|
|
1544
|
+
/**
|
|
1545
|
+
* Conditionally throws a usage error in the dev console if the first argument
|
|
1546
|
+
* is truthy. Use this to "escalate" usage patterns that in previous versions
|
|
1547
|
+
* we already warned about with deprecation warnings.
|
|
1548
|
+
*
|
|
1549
|
+
* Only has effect in dev mode. In production, this is a no-op.
|
|
1550
|
+
*/
|
|
1551
|
+
declare function errorIf(condition: unknown, message: string): void;
|
|
1552
|
+
|
|
1553
|
+
/**
|
|
1554
|
+
* Freezes the given argument, but only in development builds. In production
|
|
1555
|
+
* builds, this is a no-op for performance reasons.
|
|
1556
|
+
*/
|
|
1557
|
+
declare const freeze: typeof Object.freeze;
|
|
1558
|
+
|
|
1559
|
+
declare const brand: unique symbol;
|
|
1560
|
+
declare type Brand<T, TBrand extends string> = T & {
|
|
1561
|
+
[brand]: TBrand;
|
|
1562
|
+
};
|
|
1563
|
+
declare function isPlainObject(blob: unknown): blob is {
|
|
1564
|
+
[key: string]: unknown;
|
|
1565
|
+
};
|
|
1566
|
+
/**
|
|
1567
|
+
* Alternative to JSON.parse() that will not throw in production. If the passed
|
|
1568
|
+
* string cannot be parsed, this will return `undefined`.
|
|
1569
|
+
*/
|
|
1570
|
+
declare function tryParseJson(rawMessage: string): Json | undefined;
|
|
1571
|
+
/**
|
|
1572
|
+
* Decode base64 string.
|
|
1573
|
+
*/
|
|
1574
|
+
declare function b64decode(b64value: string): string;
|
|
1575
|
+
/**
|
|
1576
|
+
* Returns whatever the given promise returns, but will be rejected with
|
|
1577
|
+
* a "Timed out" error if the given promise does not return or reject within
|
|
1578
|
+
* the given timeout period (in milliseconds).
|
|
1579
|
+
*/
|
|
1580
|
+
declare function withTimeout<T>(promise: Promise<T>, millis: number, errmsg?: string): Promise<T>;
|
|
1581
|
+
|
|
1582
|
+
/**
|
|
1583
|
+
* Positions, aka the Pos type, are efficient encodings of "positions" in
|
|
1584
|
+
* a list, using the following printable subset of the ASCII alphabet:
|
|
1585
|
+
*
|
|
1586
|
+
* !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
|
1587
|
+
* ^ ^
|
|
1588
|
+
* Lowest digit Highest digit
|
|
1589
|
+
*
|
|
1590
|
+
* Each Pos is a sequence of characters from the above alphabet, conceptually
|
|
1591
|
+
* codifying a floating point number 0 < n < 1. For example, the string "31007"
|
|
1592
|
+
* would be used to represent the number 0.31007, except that this
|
|
1593
|
+
* representation uses base 96.
|
|
1594
|
+
*
|
|
1595
|
+
* 0 ≃ ' ' (lowest digit)
|
|
1596
|
+
* 1 ≃ '!'
|
|
1597
|
+
* 2 ≃ '"'
|
|
1598
|
+
* ...
|
|
1599
|
+
* 9 ≃ '~' (highest digit)
|
|
1600
|
+
*
|
|
1601
|
+
* So think:
|
|
1602
|
+
* '!' ≃ 0.1
|
|
1603
|
+
* '"' ≃ 0.2
|
|
1604
|
+
* '!"~' ≃ 0.129
|
|
1605
|
+
*
|
|
1606
|
+
* Three rules:
|
|
1607
|
+
* - All "characters" in the string should be valid digits (from the above
|
|
1608
|
+
* alphabet)
|
|
1609
|
+
* - The value 0.0 is not a valid Pos value
|
|
1610
|
+
* - A Pos cannot have trailing "zeroes"
|
|
1611
|
+
*
|
|
1612
|
+
* This representation has the following benefits:
|
|
1613
|
+
*
|
|
1614
|
+
* 1. It's always possible to get a number that lies before, after, or between
|
|
1615
|
+
* two arbitrary Pos values.
|
|
1616
|
+
* 2. Pos values can be compared using normal string comparison.
|
|
1617
|
+
*
|
|
1618
|
+
* Some examples:
|
|
1619
|
+
* - '!' < '"' (like how .1 < .2)
|
|
1620
|
+
* - '!' < '~' (like how .1 < .9)
|
|
1621
|
+
* - '!!' < '!~' (like how .11 < .19)
|
|
1622
|
+
* - '~!' < '~~' (like how .91 < .99)
|
|
1623
|
+
* - '~' < '~!' (like how .9 < .91)
|
|
1624
|
+
* - '!!' < '!O' (like how .1 < .5)
|
|
1625
|
+
* - '!O' < '!~' (like how .5 < .9)
|
|
1626
|
+
*
|
|
1627
|
+
*/
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* A valid/verified "position" string. These values are used as "parentKey"s by
|
|
1631
|
+
* LiveList children, and define their relative ordering.
|
|
1632
|
+
*/
|
|
1633
|
+
declare type Pos = Brand<string, "Pos">;
|
|
1634
|
+
/**
|
|
1635
|
+
* Given two positions, returns the position value that lies in the middle.
|
|
1636
|
+
* When given only a high bound, computes the canonical position "before" it.
|
|
1637
|
+
* When given only a low bound, computes the canonical position "after" it.
|
|
1638
|
+
* When given no bounds at all, returns the "first" canonical position.
|
|
1639
|
+
*/
|
|
1640
|
+
declare function makePosition(x?: Pos, y?: Pos): Pos;
|
|
1641
|
+
/**
|
|
1642
|
+
* Checks that a str is a valid Pos, and converts it to the nearest valid one
|
|
1643
|
+
* if not.
|
|
1644
|
+
*/
|
|
1645
|
+
declare function asPos(str: string): Pos;
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* Shallowly compares two given values.
|
|
1649
|
+
*
|
|
1650
|
+
* - Two simple values are considered equal if they're strictly equal
|
|
1651
|
+
* - Two arrays are considered equal if their members are strictly equal
|
|
1652
|
+
* - Two objects are considered equal if their values are strictly equal
|
|
1653
|
+
*
|
|
1654
|
+
* Testing goes one level deep.
|
|
1655
|
+
*/
|
|
1656
|
+
declare function shallow(a: unknown, b: unknown): boolean;
|
|
1657
|
+
|
|
1658
|
+
declare enum ClientMsgCode {
|
|
1659
|
+
UPDATE_PRESENCE = 100,
|
|
1660
|
+
BROADCAST_EVENT = 103,
|
|
1661
|
+
FETCH_STORAGE = 200,
|
|
1662
|
+
UPDATE_STORAGE = 201,
|
|
1663
|
+
FETCH_YDOC = 300,
|
|
1664
|
+
UPDATE_YDOC = 301
|
|
1665
|
+
}
|
|
1666
|
+
/**
|
|
1667
|
+
* Messages that can be sent from the client to the server.
|
|
1668
|
+
*/
|
|
1669
|
+
declare type ClientMsg<TPresence extends JsonObject, TRoomEvent extends Json> = BroadcastEventClientMsg<TRoomEvent> | UpdatePresenceClientMsg<TPresence> | UpdateStorageClientMsg | FetchStorageClientMsg | FetchYDocClientMsg | UpdateYDocClientMsg;
|
|
1670
|
+
declare type BroadcastEventClientMsg<TRoomEvent extends Json> = {
|
|
1671
|
+
type: ClientMsgCode.BROADCAST_EVENT;
|
|
1672
|
+
event: TRoomEvent;
|
|
1673
|
+
};
|
|
1674
|
+
declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
|
|
1675
|
+
readonly type: ClientMsgCode.UPDATE_PRESENCE;
|
|
1676
|
+
/**
|
|
1677
|
+
* Set this to any number to signify that this is a Full Presence™
|
|
1678
|
+
* update, not a patch.
|
|
1679
|
+
*
|
|
1680
|
+
* The numeric value itself no longer has specific meaning. Historically,
|
|
1681
|
+
* this field was intended so that clients could ignore these broadcasted
|
|
1682
|
+
* full presence messages, but it turned out that getting a full presence
|
|
1683
|
+
* "keyframe" from time to time was useful.
|
|
1684
|
+
*
|
|
1685
|
+
* So nowadays, the presence (pun intended) of this `targetActor` field
|
|
1686
|
+
* is a backward-compatible way of expressing that the `data` contains
|
|
1687
|
+
* all presence fields, and isn't a partial "patch".
|
|
1688
|
+
*/
|
|
1689
|
+
readonly targetActor: number;
|
|
1690
|
+
readonly data: TPresence;
|
|
1691
|
+
} | {
|
|
1692
|
+
readonly type: ClientMsgCode.UPDATE_PRESENCE;
|
|
1693
|
+
/**
|
|
1694
|
+
* Absence of the `targetActor` field signifies that this is a Partial
|
|
1695
|
+
* Presence™ "patch".
|
|
1696
|
+
*/
|
|
1697
|
+
readonly targetActor?: undefined;
|
|
1698
|
+
readonly data: Partial<TPresence>;
|
|
1699
|
+
};
|
|
1700
|
+
declare type UpdateStorageClientMsg = {
|
|
1701
|
+
readonly type: ClientMsgCode.UPDATE_STORAGE;
|
|
1702
|
+
readonly ops: Op[];
|
|
1703
|
+
};
|
|
1704
|
+
declare type FetchStorageClientMsg = {
|
|
1705
|
+
readonly type: ClientMsgCode.FETCH_STORAGE;
|
|
1706
|
+
};
|
|
1707
|
+
declare type FetchYDocClientMsg = {
|
|
1708
|
+
readonly type: ClientMsgCode.FETCH_YDOC;
|
|
1709
|
+
readonly vector: string;
|
|
1710
|
+
};
|
|
1711
|
+
declare type UpdateYDocClientMsg = {
|
|
1712
|
+
readonly type: ClientMsgCode.UPDATE_YDOC;
|
|
1713
|
+
readonly update: string;
|
|
1714
|
+
};
|
|
1715
|
+
|
|
1716
|
+
/**
|
|
1717
|
+
* Lookup table for nodes (= SerializedCrdt values) by their IDs.
|
|
1718
|
+
*/
|
|
1719
|
+
declare type NodeMap = Map<string, // Node ID
|
|
1720
|
+
SerializedCrdt>;
|
|
1721
|
+
/**
|
|
1722
|
+
* Reverse lookup table for all child nodes (= list of SerializedCrdt values)
|
|
1723
|
+
* by their parent node's IDs.
|
|
1724
|
+
*/
|
|
1725
|
+
declare type ParentToChildNodeMap = Map<string, // Parent's node ID
|
|
1726
|
+
IdTuple<SerializedChild>[]>;
|
|
1727
|
+
|
|
1728
|
+
declare type JsonTreeNode = {
|
|
1729
|
+
readonly type: "Json";
|
|
1730
|
+
readonly id: string;
|
|
1731
|
+
readonly key: string;
|
|
1732
|
+
readonly payload: Json;
|
|
1733
|
+
};
|
|
1734
|
+
declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
|
|
1735
|
+
readonly type: TName;
|
|
1736
|
+
readonly id: string;
|
|
1737
|
+
readonly key: string;
|
|
1738
|
+
readonly payload: LsonTreeNode[];
|
|
1739
|
+
};
|
|
1740
|
+
declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
|
|
1741
|
+
declare type UserTreeNode = {
|
|
1742
|
+
readonly type: "User";
|
|
1743
|
+
readonly id: string;
|
|
1744
|
+
readonly key: string;
|
|
1745
|
+
readonly payload: {
|
|
1746
|
+
readonly connectionId: number;
|
|
1747
|
+
readonly id?: string;
|
|
1748
|
+
readonly info?: Json;
|
|
1749
|
+
readonly presence: JsonObject;
|
|
1750
|
+
readonly isReadOnly: boolean;
|
|
1751
|
+
};
|
|
1752
|
+
};
|
|
1753
|
+
declare type TreeNode = LsonTreeNode | UserTreeNode;
|
|
1754
|
+
|
|
1755
|
+
type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
|
|
1756
|
+
type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
|
|
1757
|
+
type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
|
|
1758
|
+
type DevToolsTreeNode_UserTreeNode = UserTreeNode;
|
|
1759
|
+
type DevToolsTreeNode_TreeNode = TreeNode;
|
|
1760
|
+
declare namespace DevToolsTreeNode {
|
|
1761
|
+
export {
|
|
1762
|
+
DevToolsTreeNode_JsonTreeNode as JsonTreeNode,
|
|
1763
|
+
DevToolsTreeNode_LiveTreeNode as LiveTreeNode,
|
|
1764
|
+
DevToolsTreeNode_LsonTreeNode as LsonTreeNode,
|
|
1765
|
+
DevToolsTreeNode_UserTreeNode as UserTreeNode,
|
|
1766
|
+
DevToolsTreeNode_TreeNode as TreeNode,
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
/**
|
|
1771
|
+
* Definition of all messages the Panel can send to the Client.
|
|
1772
|
+
*/
|
|
1773
|
+
declare type PanelToClientMessage =
|
|
1774
|
+
/**
|
|
1775
|
+
* Initial message from the panel to the client, used for two purposes.
|
|
1776
|
+
* 1. First, it’s eavesdropped by the background script, which uses this
|
|
1777
|
+
* message to register a "port", which sets up a channel for two-way
|
|
1778
|
+
* communication between panel and client for the remainder of the time.
|
|
1779
|
+
* 2. It signifies to the client that the devpanel is listening.
|
|
1780
|
+
*/
|
|
1781
|
+
{
|
|
1782
|
+
msg: "connect";
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Expresses to the client that the devtool is interested in
|
|
1786
|
+
* receiving the "sync stream" for the room. The sync stream
|
|
1787
|
+
* that follows is an initial "full sync", followed by many
|
|
1788
|
+
* "partial" syncs, happening for every update.
|
|
1789
|
+
*/
|
|
1790
|
+
| {
|
|
1791
|
+
msg: "room::subscribe";
|
|
1792
|
+
roomId: string;
|
|
1793
|
+
}
|
|
1794
|
+
/**
|
|
1795
|
+
* Expresses to the client that the devtool no longer is
|
|
1796
|
+
* interested in the "sync stream" for a room, for example,
|
|
1797
|
+
* because the devtools panel is closed, or if it switched to
|
|
1798
|
+
* a different room.
|
|
1799
|
+
*/
|
|
1800
|
+
| {
|
|
1801
|
+
msg: "room::unsubscribe";
|
|
1802
|
+
roomId: string;
|
|
1803
|
+
};
|
|
1804
|
+
/**
|
|
1805
|
+
* Definition of all messages the Client can send to the Panel.
|
|
1806
|
+
*/
|
|
1807
|
+
declare type ClientToPanelMessage =
|
|
1808
|
+
/**
|
|
1809
|
+
* Initial message sent by the client to test if a dev panel is listening.
|
|
1810
|
+
* This is necessary in cases where the dev panel is already opened and
|
|
1811
|
+
* listened, before the client is loaded. If the panel receives this message,
|
|
1812
|
+
* it will replay its initial "connect" message, which triggers the loading
|
|
1813
|
+
* of the two-way connection.
|
|
1814
|
+
*/
|
|
1815
|
+
{
|
|
1816
|
+
msg: "wake-up-devtools";
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Sent when a new room is available for the dev panel to track and watch.
|
|
1820
|
+
* Sent by the client as soon as the room is attempted to be entered. This
|
|
1821
|
+
* happens _before_ the actual connection to the room server is established,
|
|
1822
|
+
* meaning the room is visible to the devtools even while it is connecting.
|
|
1823
|
+
*/
|
|
1824
|
+
| {
|
|
1825
|
+
msg: "room::available";
|
|
1826
|
+
roomId: string;
|
|
1827
|
+
clientVersion: string;
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Sent when a room is left and the client loses track of the room instance.
|
|
1831
|
+
*/
|
|
1832
|
+
| {
|
|
1833
|
+
msg: "room::unavailable";
|
|
1834
|
+
roomId: string;
|
|
1835
|
+
}
|
|
1836
|
+
/**
|
|
1837
|
+
* Sent initially, to synchronize the entire current state of the room.
|
|
1838
|
+
*/
|
|
1839
|
+
| {
|
|
1840
|
+
msg: "room::sync::full";
|
|
1841
|
+
roomId: string;
|
|
1842
|
+
status: Status;
|
|
1843
|
+
storage: readonly LsonTreeNode[] | null;
|
|
1844
|
+
me: UserTreeNode | null;
|
|
1845
|
+
others: readonly UserTreeNode[];
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Sent whenever something about the internals of a room changes.
|
|
1849
|
+
*/
|
|
1850
|
+
| {
|
|
1851
|
+
msg: "room::sync::partial";
|
|
1852
|
+
roomId: string;
|
|
1853
|
+
status?: Status;
|
|
1854
|
+
storage?: readonly LsonTreeNode[];
|
|
1855
|
+
me?: UserTreeNode;
|
|
1856
|
+
others?: readonly UserTreeNode[];
|
|
1857
|
+
};
|
|
1858
|
+
declare type FullPanelToClientMessage = PanelToClientMessage & {
|
|
1859
|
+
source: "liveblocks-devtools-panel";
|
|
1860
|
+
tabId: number;
|
|
1861
|
+
};
|
|
1862
|
+
declare type FullClientToPanelMessage = ClientToPanelMessage & {
|
|
1863
|
+
source: "liveblocks-devtools-client";
|
|
1864
|
+
};
|
|
1865
|
+
|
|
1866
|
+
type protocol_PanelToClientMessage = PanelToClientMessage;
|
|
1867
|
+
type protocol_ClientToPanelMessage = ClientToPanelMessage;
|
|
1868
|
+
type protocol_FullPanelToClientMessage = FullPanelToClientMessage;
|
|
1869
|
+
type protocol_FullClientToPanelMessage = FullClientToPanelMessage;
|
|
1870
|
+
declare namespace protocol {
|
|
1871
|
+
export {
|
|
1872
|
+
protocol_PanelToClientMessage as PanelToClientMessage,
|
|
1873
|
+
protocol_ClientToPanelMessage as ClientToPanelMessage,
|
|
1874
|
+
protocol_FullPanelToClientMessage as FullPanelToClientMessage,
|
|
1875
|
+
protocol_FullClientToPanelMessage as FullClientToPanelMessage,
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
/**
|
|
1880
|
+
* PRIVATE / INTERNAL APIS
|
|
1881
|
+
* -----------------------
|
|
1882
|
+
*
|
|
1883
|
+
* This module is intended for internal use only, PLEASE DO NOT RELY ON ANY OF
|
|
1884
|
+
* THE EXPORTS IN HERE. These are implementation details that can change at any
|
|
1885
|
+
* time and without announcement. This module purely exists to share code
|
|
1886
|
+
* between the several Liveblocks packages.
|
|
1887
|
+
*
|
|
1888
|
+
* But since you're so deep inside Liveblocks code... we're hiring!
|
|
1889
|
+
* https://join.team/liveblocks ;)
|
|
1890
|
+
*/
|
|
1891
|
+
|
|
1892
|
+
/**
|
|
1893
|
+
* Helper type to help users adopt to Lson types from interface definitions.
|
|
1894
|
+
* You should only use this to wrap interfaces you don't control. For more
|
|
1895
|
+
* information, see
|
|
1896
|
+
* https://liveblocks.io/docs/guides/limits#lson-constraint-and-interfaces
|
|
1897
|
+
*/
|
|
1898
|
+
declare type EnsureJson<T> = [
|
|
1899
|
+
unknown
|
|
1900
|
+
] extends [T] ? T : T extends (...args: unknown[]) => unknown ? T : {
|
|
1901
|
+
[K in keyof T]: EnsureJson<T[K]>;
|
|
1902
|
+
};
|
|
1903
|
+
|
|
1904
|
+
export { AckOp, BaseAuthResult, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ToImmutable, ToJson, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, asPos, assert, assertNever, b64decode, createClient, deprecate, deprecateIf, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, toPlainLson, tryParseJson, withTimeout };
|