@liveblocks/client 0.16.13 → 0.16.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -1
- package/index.js +43 -30
- package/index.mjs +46 -34
- package/internal.d.ts +227 -77
- package/internal.js +57 -17
- package/internal.mjs +57 -15
- package/package.json +9 -13
- package/shared.d.ts +184 -342
- package/shared.js +351 -599
- package/shared.mjs +314 -632
package/internal.d.ts
CHANGED
|
@@ -1,33 +1,22 @@
|
|
|
1
|
-
import { d as JsonObject, J as Json,
|
|
2
|
-
export {
|
|
1
|
+
import { d as JsonObject, J as Json, g as Resolve, e as Lson, A as AbstractCrdt, f as LsonObject, L as LiveObject, S as StorageUpdate } from './shared';
|
|
2
|
+
export { g as Resolve, h as RoomInitializers, i as isJsonArray, j as isJsonObject, k as isJsonScalar } from './shared';
|
|
3
3
|
|
|
4
|
-
declare
|
|
5
|
-
UPDATE_PRESENCE = 100,
|
|
6
|
-
BROADCAST_EVENT = 103,
|
|
7
|
-
FETCH_STORAGE = 200,
|
|
8
|
-
UPDATE_STORAGE = 201
|
|
9
|
-
}
|
|
4
|
+
declare type IdTuple<T> = [id: string, value: T];
|
|
10
5
|
/**
|
|
11
|
-
*
|
|
6
|
+
* Lookup table for nodes (= SerializedCrdt values) by their IDs.
|
|
12
7
|
*/
|
|
13
|
-
declare type
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
ops: Op[];
|
|
26
|
-
};
|
|
27
|
-
declare type FetchStorageClientMsg = {
|
|
28
|
-
type: ClientMsgCode.FETCH_STORAGE;
|
|
29
|
-
};
|
|
30
|
-
|
|
8
|
+
declare type NodeMap = Map<string, // Node ID
|
|
9
|
+
SerializedCrdt>;
|
|
10
|
+
/**
|
|
11
|
+
* Reverse lookup table for all child nodes (= list of SerializedCrdt values)
|
|
12
|
+
* by their parent node's IDs.
|
|
13
|
+
*/
|
|
14
|
+
declare type ParentToChildNodeMap = Map<string, // Parent's node ID
|
|
15
|
+
IdTuple<SerializedChild>[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Messages that can be sent from the server to the client.
|
|
18
|
+
*/
|
|
19
|
+
declare type ServerMsg<TPresence extends JsonObject> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg | UserLeftServerMsg | BroadcastedEventServerMsg | RoomStateServerMsg | InitialDocumentStateServerMsg | UpdateStorageServerMsg;
|
|
31
20
|
declare enum ServerMsgCode {
|
|
32
21
|
UPDATE_PRESENCE = 100,
|
|
33
22
|
USER_JOINED = 101,
|
|
@@ -38,9 +27,19 @@ declare enum ServerMsgCode {
|
|
|
38
27
|
UPDATE_STORAGE = 201
|
|
39
28
|
}
|
|
40
29
|
/**
|
|
41
|
-
*
|
|
30
|
+
* Sent by the WebSocket server to a single client in response to the client
|
|
31
|
+
* joining the Room, to provide the initial state of the Room. The payload
|
|
32
|
+
* includes a list of all other Users that already are in the Room.
|
|
42
33
|
*/
|
|
43
|
-
declare type
|
|
34
|
+
declare type RoomStateServerMsg = {
|
|
35
|
+
type: ServerMsgCode.ROOM_STATE;
|
|
36
|
+
users: {
|
|
37
|
+
[actor: number]: {
|
|
38
|
+
id?: string;
|
|
39
|
+
info?: Json;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
44
43
|
/**
|
|
45
44
|
* Sent by the WebSocket server and broadcasted to all clients to announce that
|
|
46
45
|
* a User updated their presence. For example, when a user moves their cursor.
|
|
@@ -113,20 +112,6 @@ declare type BroadcastedEventServerMsg = {
|
|
|
113
112
|
*/
|
|
114
113
|
event: Json;
|
|
115
114
|
};
|
|
116
|
-
/**
|
|
117
|
-
* Sent by the WebSocket server to a single client in response to the client
|
|
118
|
-
* joining the Room, to provide the initial state of the Room. The payload
|
|
119
|
-
* includes a list of all other Users that already are in the Room.
|
|
120
|
-
*/
|
|
121
|
-
declare type RoomStateServerMsg = {
|
|
122
|
-
type: ServerMsgCode.ROOM_STATE;
|
|
123
|
-
users: {
|
|
124
|
-
[actor: number]: {
|
|
125
|
-
id?: string;
|
|
126
|
-
info?: Json;
|
|
127
|
-
};
|
|
128
|
-
};
|
|
129
|
-
};
|
|
130
115
|
/**
|
|
131
116
|
* Sent by the WebSocket server to a single client in response to the client
|
|
132
117
|
* joining the Room, to provide the initial Storage state of the Room. The
|
|
@@ -147,42 +132,159 @@ declare type UpdateStorageServerMsg = {
|
|
|
147
132
|
type: ServerMsgCode.UPDATE_STORAGE;
|
|
148
133
|
ops: Op[];
|
|
149
134
|
};
|
|
150
|
-
|
|
151
135
|
/**
|
|
152
|
-
*
|
|
153
|
-
* with TypeScript. Example usage:
|
|
154
|
-
*
|
|
155
|
-
* type Fruit = "🍎" | "🍌";
|
|
156
|
-
*
|
|
157
|
-
* switch (fruit) {
|
|
158
|
-
* case "🍎":
|
|
159
|
-
* case "🍌":
|
|
160
|
-
* return doSomething();
|
|
161
|
-
*
|
|
162
|
-
* default:
|
|
163
|
-
* return assertNever(fruit, "Unknown fruit");
|
|
164
|
-
* }
|
|
165
|
-
*
|
|
166
|
-
* If now the Fruit union is extended (i.e. add "🍒"), TypeScript will catch
|
|
167
|
-
* this *statically*, rather than at runtime, and force you to handle the
|
|
168
|
-
* 🍒 case.
|
|
136
|
+
* Messages that can be sent from the client to the server.
|
|
169
137
|
*/
|
|
170
|
-
declare
|
|
138
|
+
declare type ClientMsg<TPresence extends JsonObject> = BroadcastEventClientMsg | UpdatePresenceClientMsg<TPresence> | UpdateStorageClientMsg | FetchStorageClientMsg;
|
|
139
|
+
declare enum ClientMsgCode {
|
|
140
|
+
UPDATE_PRESENCE = 100,
|
|
141
|
+
BROADCAST_EVENT = 103,
|
|
142
|
+
FETCH_STORAGE = 200,
|
|
143
|
+
UPDATE_STORAGE = 201
|
|
144
|
+
}
|
|
145
|
+
declare type BroadcastEventClientMsg = {
|
|
146
|
+
type: ClientMsgCode.BROADCAST_EVENT;
|
|
147
|
+
event: Json;
|
|
148
|
+
};
|
|
149
|
+
declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
|
|
150
|
+
type: ClientMsgCode.UPDATE_PRESENCE;
|
|
151
|
+
data: TPresence;
|
|
152
|
+
targetActor?: number;
|
|
153
|
+
};
|
|
154
|
+
declare type UpdateStorageClientMsg = {
|
|
155
|
+
type: ClientMsgCode.UPDATE_STORAGE;
|
|
156
|
+
ops: Op[];
|
|
157
|
+
};
|
|
158
|
+
declare type FetchStorageClientMsg = {
|
|
159
|
+
type: ClientMsgCode.FETCH_STORAGE;
|
|
160
|
+
};
|
|
161
|
+
declare enum CrdtType {
|
|
162
|
+
OBJECT = 0,
|
|
163
|
+
LIST = 1,
|
|
164
|
+
MAP = 2,
|
|
165
|
+
REGISTER = 3
|
|
166
|
+
}
|
|
167
|
+
declare type SerializedRootObject = {
|
|
168
|
+
type: CrdtType.OBJECT;
|
|
169
|
+
data: JsonObject;
|
|
170
|
+
parentId?: never;
|
|
171
|
+
parentKey?: never;
|
|
172
|
+
};
|
|
173
|
+
declare type SerializedObject = {
|
|
174
|
+
type: CrdtType.OBJECT;
|
|
175
|
+
parentId: string;
|
|
176
|
+
parentKey: string;
|
|
177
|
+
data: JsonObject;
|
|
178
|
+
};
|
|
179
|
+
declare type SerializedList = {
|
|
180
|
+
type: CrdtType.LIST;
|
|
181
|
+
parentId: string;
|
|
182
|
+
parentKey: string;
|
|
183
|
+
};
|
|
184
|
+
declare type SerializedMap = {
|
|
185
|
+
type: CrdtType.MAP;
|
|
186
|
+
parentId: string;
|
|
187
|
+
parentKey: string;
|
|
188
|
+
};
|
|
189
|
+
declare type SerializedRegister = {
|
|
190
|
+
type: CrdtType.REGISTER;
|
|
191
|
+
parentId: string;
|
|
192
|
+
parentKey: string;
|
|
193
|
+
data: Json;
|
|
194
|
+
};
|
|
195
|
+
declare type SerializedCrdt = SerializedRootObject | SerializedChild;
|
|
196
|
+
declare type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister;
|
|
197
|
+
declare function isRootCrdt(crdt: SerializedCrdt): crdt is SerializedRootObject;
|
|
198
|
+
declare function isChildCrdt(crdt: SerializedCrdt): crdt is SerializedChild;
|
|
199
|
+
declare enum OpCode {
|
|
200
|
+
INIT = 0,
|
|
201
|
+
SET_PARENT_KEY = 1,
|
|
202
|
+
CREATE_LIST = 2,
|
|
203
|
+
UPDATE_OBJECT = 3,
|
|
204
|
+
CREATE_OBJECT = 4,
|
|
205
|
+
DELETE_CRDT = 5,
|
|
206
|
+
DELETE_OBJECT_KEY = 6,
|
|
207
|
+
CREATE_MAP = 7,
|
|
208
|
+
CREATE_REGISTER = 8
|
|
209
|
+
}
|
|
171
210
|
/**
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* an incorrect assumption.
|
|
175
|
-
*
|
|
176
|
-
* Instead of:
|
|
177
|
-
*
|
|
178
|
-
* foo!.bar
|
|
179
|
-
*
|
|
180
|
-
* Use:
|
|
181
|
-
*
|
|
182
|
-
* nn(foo).bar
|
|
183
|
-
*
|
|
211
|
+
* These operations are the payload for {@link UpdateStorageServerMsg} messages
|
|
212
|
+
* only.
|
|
184
213
|
*/
|
|
185
|
-
declare
|
|
214
|
+
declare type Op = CreateOp | UpdateObjectOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
|
|
215
|
+
declare type CreateOp = CreateRootObjectOp | CreateChildOp;
|
|
216
|
+
declare type CreateChildOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
|
|
217
|
+
declare type UpdateObjectOp = {
|
|
218
|
+
opId?: string;
|
|
219
|
+
id: string;
|
|
220
|
+
type: OpCode.UPDATE_OBJECT;
|
|
221
|
+
data: Partial<JsonObject>;
|
|
222
|
+
};
|
|
223
|
+
declare type CreateObjectOp = {
|
|
224
|
+
opId?: string;
|
|
225
|
+
id: string;
|
|
226
|
+
intent?: "set";
|
|
227
|
+
type: OpCode.CREATE_OBJECT;
|
|
228
|
+
parentId: string;
|
|
229
|
+
parentKey: string;
|
|
230
|
+
data: JsonObject;
|
|
231
|
+
};
|
|
232
|
+
declare type CreateRootObjectOp = Resolve<Omit<CreateObjectOp, "parentId" | "parentKey"> & {
|
|
233
|
+
parentId?: never;
|
|
234
|
+
parentKey?: never;
|
|
235
|
+
}>;
|
|
236
|
+
declare type CreateListOp = {
|
|
237
|
+
opId?: string;
|
|
238
|
+
id: string;
|
|
239
|
+
intent?: "set";
|
|
240
|
+
type: OpCode.CREATE_LIST;
|
|
241
|
+
parentId: string;
|
|
242
|
+
parentKey: string;
|
|
243
|
+
};
|
|
244
|
+
declare type CreateMapOp = {
|
|
245
|
+
opId?: string;
|
|
246
|
+
id: string;
|
|
247
|
+
intent?: "set";
|
|
248
|
+
type: OpCode.CREATE_MAP;
|
|
249
|
+
parentId: string;
|
|
250
|
+
parentKey: string;
|
|
251
|
+
};
|
|
252
|
+
declare type CreateRegisterOp = {
|
|
253
|
+
opId?: string;
|
|
254
|
+
id: string;
|
|
255
|
+
intent?: "set";
|
|
256
|
+
type: OpCode.CREATE_REGISTER;
|
|
257
|
+
parentId: string;
|
|
258
|
+
parentKey: string;
|
|
259
|
+
data: Json;
|
|
260
|
+
};
|
|
261
|
+
declare type DeleteCrdtOp = {
|
|
262
|
+
opId?: string;
|
|
263
|
+
id: string;
|
|
264
|
+
type: OpCode.DELETE_CRDT;
|
|
265
|
+
};
|
|
266
|
+
declare type SetParentKeyOp = {
|
|
267
|
+
opId?: string;
|
|
268
|
+
id: string;
|
|
269
|
+
type: OpCode.SET_PARENT_KEY;
|
|
270
|
+
parentKey: string;
|
|
271
|
+
};
|
|
272
|
+
declare type DeleteObjectKeyOp = {
|
|
273
|
+
opId?: string;
|
|
274
|
+
id: string;
|
|
275
|
+
type: OpCode.DELETE_OBJECT_KEY;
|
|
276
|
+
key: string;
|
|
277
|
+
};
|
|
278
|
+
declare enum WebsocketCloseCodes {
|
|
279
|
+
CLOSE_ABNORMAL = 1006,
|
|
280
|
+
INVALID_MESSAGE_FORMAT = 4000,
|
|
281
|
+
NOT_ALLOWED = 4001,
|
|
282
|
+
MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
|
|
283
|
+
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
|
|
284
|
+
MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
|
|
285
|
+
MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
|
|
286
|
+
CLOSE_WITHOUT_RETRY = 4999
|
|
287
|
+
}
|
|
186
288
|
|
|
187
289
|
/**
|
|
188
290
|
* Tools to help with the controlled deprecation of public APIs.
|
|
@@ -215,13 +317,61 @@ declare function throwUsageError(message: string): void;
|
|
|
215
317
|
*/
|
|
216
318
|
declare function errorIf(condition: unknown, message: string): void;
|
|
217
319
|
|
|
218
|
-
declare
|
|
320
|
+
declare const SCOPES: readonly ["websocket:presence", "websocket:storage", "room:read", "room:write", "rooms:read", "rooms:write"];
|
|
321
|
+
declare type Scope = typeof SCOPES[number];
|
|
322
|
+
declare type AppOnlyAuthToken = {
|
|
323
|
+
appId: string;
|
|
324
|
+
roomId?: never;
|
|
325
|
+
scopes: string[];
|
|
326
|
+
};
|
|
327
|
+
declare type RoomAuthToken = {
|
|
328
|
+
appId: string;
|
|
329
|
+
roomId: string;
|
|
330
|
+
scopes: string[];
|
|
331
|
+
actor: number;
|
|
332
|
+
maxConnections: number;
|
|
333
|
+
maxConnectionsPerRoom?: number;
|
|
334
|
+
id?: string;
|
|
335
|
+
info?: Json;
|
|
336
|
+
};
|
|
337
|
+
declare type AuthToken = AppOnlyAuthToken | RoomAuthToken;
|
|
338
|
+
interface JwtMetadata extends JsonObject {
|
|
339
|
+
iat: number;
|
|
340
|
+
exp: number;
|
|
341
|
+
}
|
|
342
|
+
declare function isScope(value: unknown): value is Scope;
|
|
343
|
+
declare function isAppOnlyAuthToken(data: JsonObject): data is AppOnlyAuthToken;
|
|
344
|
+
declare function isRoomAuthToken(data: JsonObject): data is RoomAuthToken;
|
|
345
|
+
declare function isAuthToken(data: JsonObject): data is AuthToken;
|
|
346
|
+
declare function parseAuthToken(token: string): AuthToken & JwtMetadata;
|
|
347
|
+
|
|
348
|
+
declare function lsonToJson(value: Lson | AbstractCrdt): Json;
|
|
219
349
|
declare function patchLiveObjectKey<O extends LsonObject>(liveObject: LiveObject<O>, key: keyof O, prev: unknown, next: unknown): void;
|
|
220
350
|
declare function patchImmutableObject<T>(state: T, updates: StorageUpdate[]): T;
|
|
221
351
|
|
|
222
352
|
declare function makePosition(before?: string, after?: string): string;
|
|
223
353
|
declare function comparePosition(posA: string, posB: string): number;
|
|
224
354
|
|
|
355
|
+
/**
|
|
356
|
+
* Helper function that can be used to implement exhaustive switch statements
|
|
357
|
+
* with TypeScript. Example usage:
|
|
358
|
+
*
|
|
359
|
+
* type Fruit = "🍎" | "🍌";
|
|
360
|
+
*
|
|
361
|
+
* switch (fruit) {
|
|
362
|
+
* case "🍎":
|
|
363
|
+
* case "🍌":
|
|
364
|
+
* return doSomething();
|
|
365
|
+
*
|
|
366
|
+
* default:
|
|
367
|
+
* return assertNever(fruit, "Unknown fruit");
|
|
368
|
+
* }
|
|
369
|
+
*
|
|
370
|
+
* If now the Fruit union is extended (i.e. add "🍒"), TypeScript will catch
|
|
371
|
+
* this *statically*, rather than at runtime, and force you to handle the
|
|
372
|
+
* 🍒 case.
|
|
373
|
+
*/
|
|
374
|
+
declare function assertNever(_value: never, errmsg: string): never;
|
|
225
375
|
/**
|
|
226
376
|
* Alternative to JSON.parse() that will not throw in production. If the passed
|
|
227
377
|
* string cannot be parsed, this will return `undefined`.
|
|
@@ -232,4 +382,4 @@ declare function tryParseJson(rawMessage: string): Json | undefined;
|
|
|
232
382
|
*/
|
|
233
383
|
declare function b64decode(b64value: string): string;
|
|
234
384
|
|
|
235
|
-
export {
|
|
385
|
+
export { AppOnlyAuthToken, AuthToken, BroadcastEventClientMsg, ClientMsg, ClientMsgCode, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateRegisterOp, CreateRootObjectOp, DeleteCrdtOp, DeleteObjectKeyOp, FetchStorageClientMsg, IdTuple, InitialDocumentStateServerMsg, NodeMap, Op, OpCode, ParentToChildNodeMap, RoomAuthToken, RoomStateServerMsg, Scope, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, UpdateObjectOp, UpdatePresenceClientMsg, UpdateStorageClientMsg, UserJoinServerMsg, WebsocketCloseCodes, assertNever, b64decode, comparePosition, deprecate, deprecateIf, errorIf, isAppOnlyAuthToken, isAuthToken, isChildCrdt, isRoomAuthToken, isRootCrdt, isScope, lsonToJson, makePosition, parseAuthToken, patchImmutableObject, patchLiveObjectKey, throwUsageError, tryParseJson };
|
package/internal.js
CHANGED
|
@@ -4,7 +4,37 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: !0
|
|
5
5
|
});
|
|
6
6
|
|
|
7
|
-
var LiveObject = require("./shared.js");
|
|
7
|
+
var LiveObject = require("./shared.js"), SCOPES = [ "websocket:presence", "websocket:storage", "room:read", "room:write", "rooms:read", "rooms:write" ];
|
|
8
|
+
|
|
9
|
+
function isStringList(value) {
|
|
10
|
+
return Array.isArray(value) && value.every((function(i) {
|
|
11
|
+
return "string" == typeof i;
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isAppOnlyAuthToken(data) {
|
|
16
|
+
return "string" == typeof data.appId && void 0 === data.roomId && isStringList(data.scopes);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isRoomAuthToken(data) {
|
|
20
|
+
return "string" == typeof data.appId && "string" == typeof data.roomId && "number" == typeof data.actor && (void 0 === data.id || "string" == typeof data.id) && isStringList(data.scopes) && "number" == typeof data.maxConnections && (void 0 === data.maxConnectionsPerRoom || "number" == typeof data.maxConnectionsPerRoom);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isAuthToken(data) {
|
|
24
|
+
return isAppOnlyAuthToken(data) || isRoomAuthToken(data);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function parseJwtToken(token) {
|
|
28
|
+
var tokenParts = token.split(".");
|
|
29
|
+
if (3 !== tokenParts.length) throw new Error("Authentication error: invalid JWT token");
|
|
30
|
+
var data = LiveObject.tryParseJson(LiveObject.b64decode(tokenParts[1]));
|
|
31
|
+
if (data && function(data) {
|
|
32
|
+
if (!LiveObject.isPlainObject(data)) return !1;
|
|
33
|
+
var iat = data.iat, exp = data.exp;
|
|
34
|
+
return "number" == typeof iat && "number" == typeof exp;
|
|
35
|
+
}(data)) return data;
|
|
36
|
+
throw new Error("Authentication error: missing JWT metadata");
|
|
37
|
+
}
|
|
8
38
|
|
|
9
39
|
function lsonObjectToJson(obj) {
|
|
10
40
|
var result = {};
|
|
@@ -20,15 +50,20 @@ function lsonListToJson(value) {
|
|
|
20
50
|
}
|
|
21
51
|
|
|
22
52
|
function lsonToJson(value) {
|
|
23
|
-
|
|
53
|
+
if (value instanceof LiveObject.LiveObject) return lsonObjectToJson(value.toObject());
|
|
54
|
+
if (value instanceof LiveObject.LiveList) return function(value) {
|
|
24
55
|
return lsonListToJson(value.toArray());
|
|
25
|
-
}(value)
|
|
56
|
+
}(value);
|
|
57
|
+
if (value instanceof LiveObject.LiveMap) return function(map) {
|
|
26
58
|
for (var _step, result = {}, _iterator = LiveObject._createForOfIteratorHelperLoose(map.entries()); !(_step = _iterator()).done; ) {
|
|
27
59
|
var _step$value = _step.value, _key2 = _step$value[0], value = _step$value[1];
|
|
28
60
|
result[_key2] = lsonToJson(value);
|
|
29
61
|
}
|
|
30
62
|
return result;
|
|
31
|
-
}(value)
|
|
63
|
+
}(value);
|
|
64
|
+
if (value instanceof LiveObject.LiveRegister) return value.data;
|
|
65
|
+
if (value instanceof LiveObject.AbstractCrdt) throw new Error("Unhandled subclass of AbstractCrdt encountered");
|
|
66
|
+
return Array.isArray(value) ? lsonListToJson(value) : isPlainObject(value) ? lsonObjectToJson(value) : value;
|
|
32
67
|
}
|
|
33
68
|
|
|
34
69
|
function isPlainObject(obj) {
|
|
@@ -54,7 +89,7 @@ function patchLiveObjectKey(liveObject, key, prev, next) {
|
|
|
54
89
|
var value = liveObject.get(key);
|
|
55
90
|
if (void 0 === next) liveObject.delete(key); else if (void 0 === value) liveObject.set(key, anyToCrdt(next)); else {
|
|
56
91
|
if (prev === next) return;
|
|
57
|
-
LiveObject.
|
|
92
|
+
value instanceof LiveObject.LiveList && Array.isArray(prev) && Array.isArray(next) ? function(liveList, prev, next) {
|
|
58
93
|
var i = 0, prevEnd = prev.length - 1, nextEnd = next.length - 1, prevNode = prev[0], nextNode = next[0];
|
|
59
94
|
outer: {
|
|
60
95
|
for (;prevNode === nextNode; ) {
|
|
@@ -74,13 +109,13 @@ function patchLiveObjectKey(liveObject, key, prev, next) {
|
|
|
74
109
|
for (;i <= prevEnd && i <= nextEnd; ) {
|
|
75
110
|
prevNode = prev[i], nextNode = next[i];
|
|
76
111
|
var liveListNode = liveList.get(i);
|
|
77
|
-
LiveObject.
|
|
112
|
+
liveListNode instanceof LiveObject.LiveObject && isPlainObject(prevNode) && isPlainObject(nextNode) ? patchLiveObject(liveListNode, prevNode, nextNode) : liveList.set(i, anyToCrdt(nextNode)),
|
|
78
113
|
i++;
|
|
79
114
|
}
|
|
80
115
|
for (;i <= nextEnd; ) liveList.insert(anyToCrdt(next[i]), i), i++;
|
|
81
116
|
for (var _localI = i; _localI <= prevEnd; ) liveList.delete(i), _localI++;
|
|
82
117
|
}
|
|
83
|
-
}(value, prev, next) : LiveObject.
|
|
118
|
+
}(value, prev, next) : value instanceof LiveObject.LiveObject && isPlainObject(prev) && isPlainObject(next) ? patchLiveObject(value, prev, next) : liveObject.set(key, anyToCrdt(next));
|
|
84
119
|
}
|
|
85
120
|
}
|
|
86
121
|
|
|
@@ -123,10 +158,7 @@ function patchImmutableNode(state, path, update) {
|
|
|
123
158
|
var _newState2 = Object.assign({}, state);
|
|
124
159
|
for (var _key7 in update.updates) {
|
|
125
160
|
var _update$updates$_key3, _update$updates$_key4;
|
|
126
|
-
|
|
127
|
-
var value = update.node.get(_key7);
|
|
128
|
-
void 0 !== value && (_newState2[_key7] = lsonToJson(value));
|
|
129
|
-
} else "delete" === (null == (_update$updates$_key4 = update.updates[_key7]) ? void 0 : _update$updates$_key4.type) && delete _newState2[_key7];
|
|
161
|
+
"update" === (null == (_update$updates$_key3 = update.updates[_key7]) ? void 0 : _update$updates$_key3.type) ? _newState2[_key7] = lsonToJson(update.node.get(_key7)) : "delete" === (null == (_update$updates$_key4 = update.updates[_key7]) ? void 0 : _update$updates$_key4.type) && delete _newState2[_key7];
|
|
130
162
|
}
|
|
131
163
|
return _newState2;
|
|
132
164
|
}
|
|
@@ -166,15 +198,23 @@ Object.defineProperty(exports, "ClientMsgCode", {
|
|
|
166
198
|
}), exports.assertNever = LiveObject.assertNever, exports.b64decode = LiveObject.b64decode,
|
|
167
199
|
exports.comparePosition = LiveObject.comparePosition, exports.deprecate = LiveObject.deprecate,
|
|
168
200
|
exports.deprecateIf = LiveObject.deprecateIf, exports.errorIf = LiveObject.errorIf,
|
|
169
|
-
exports.isChildCrdt = LiveObject.isChildCrdt, exports.
|
|
170
|
-
exports.
|
|
171
|
-
exports.
|
|
172
|
-
exports.
|
|
201
|
+
exports.isChildCrdt = LiveObject.isChildCrdt, exports.isJsonArray = LiveObject.isJsonArray,
|
|
202
|
+
exports.isJsonObject = LiveObject.isJsonObject, exports.isJsonScalar = LiveObject.isJsonScalar,
|
|
203
|
+
exports.isRootCrdt = LiveObject.isRootCrdt, exports.makePosition = LiveObject.makePosition,
|
|
204
|
+
exports.throwUsageError = LiveObject.throwUsageError, exports.tryParseJson = LiveObject.tryParseJson,
|
|
205
|
+
exports.isAppOnlyAuthToken = isAppOnlyAuthToken, exports.isAuthToken = isAuthToken,
|
|
206
|
+
exports.isRoomAuthToken = isRoomAuthToken, exports.isScope = function(value) {
|
|
207
|
+
return SCOPES.includes(value);
|
|
208
|
+
}, exports.lsonToJson = lsonToJson, exports.parseAuthToken = function(token) {
|
|
209
|
+
var data = parseJwtToken(token);
|
|
210
|
+
if (data && isAuthToken(data)) return data;
|
|
211
|
+
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
212
|
+
}, exports.patchImmutableObject = function(state, updates) {
|
|
173
213
|
return updates.reduce((function(state, update) {
|
|
174
214
|
return function(state, update) {
|
|
175
215
|
var path = function(node) {
|
|
176
|
-
for (var path = [];
|
|
177
|
-
node = node.
|
|
216
|
+
for (var path = []; null != node._parentKey && null != node._parent; ) node._parent instanceof LiveObject.LiveList ? path.push(node._parent._indexOfPosition(node._parentKey)) : path.push(node._parentKey),
|
|
217
|
+
node = node._parent;
|
|
178
218
|
return path;
|
|
179
219
|
}(update.node);
|
|
180
220
|
return patchImmutableNode(state, path, update);
|
package/internal.mjs
CHANGED
|
@@ -1,6 +1,46 @@
|
|
|
1
|
-
import { L as LiveObject,
|
|
1
|
+
import { t as tryParseJson, e as b64decode, l as isPlainObject$1, L as LiveObject, b as LiveList, k as LiveMap, n as LiveRegister, A as AbstractCrdt, o as findNonSerializableValue } from "./shared.mjs";
|
|
2
2
|
|
|
3
|
-
export { C as ClientMsgCode,
|
|
3
|
+
export { C as ClientMsgCode, u as CrdtType, O as OpCode, S as ServerMsgCode, W as WebsocketCloseCodes, y as assertNever, e as b64decode, v as comparePosition, p as deprecate, j as deprecateIf, q as errorIf, x as isChildCrdt, c as isJsonArray, f as isJsonObject, z as isJsonScalar, h as isRootCrdt, w as makePosition, s as throwUsageError, t as tryParseJson } from "./shared.mjs";
|
|
4
|
+
|
|
5
|
+
const SCOPES = [ "websocket:presence", "websocket:storage", "room:read", "room:write", "rooms:read", "rooms:write" ];
|
|
6
|
+
|
|
7
|
+
function isScope(value) {
|
|
8
|
+
return SCOPES.includes(value);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function isStringList(value) {
|
|
12
|
+
return Array.isArray(value) && value.every((i => "string" == typeof i));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function isAppOnlyAuthToken(data) {
|
|
16
|
+
return "string" == typeof data.appId && void 0 === data.roomId && isStringList(data.scopes);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isRoomAuthToken(data) {
|
|
20
|
+
return "string" == typeof data.appId && "string" == typeof data.roomId && "number" == typeof data.actor && (void 0 === data.id || "string" == typeof data.id) && isStringList(data.scopes) && "number" == typeof data.maxConnections && (void 0 === data.maxConnectionsPerRoom || "number" == typeof data.maxConnectionsPerRoom);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function isAuthToken(data) {
|
|
24
|
+
return isAppOnlyAuthToken(data) || isRoomAuthToken(data);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function parseJwtToken(token) {
|
|
28
|
+
const tokenParts = token.split(".");
|
|
29
|
+
if (3 !== tokenParts.length) throw new Error("Authentication error: invalid JWT token");
|
|
30
|
+
const data = tryParseJson(b64decode(tokenParts[1]));
|
|
31
|
+
if (data && function(data) {
|
|
32
|
+
if (!isPlainObject$1(data)) return !1;
|
|
33
|
+
const {iat: iat, exp: exp} = data;
|
|
34
|
+
return "number" == typeof iat && "number" == typeof exp;
|
|
35
|
+
}(data)) return data;
|
|
36
|
+
throw new Error("Authentication error: missing JWT metadata");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function parseAuthToken(token) {
|
|
40
|
+
const data = parseJwtToken(token);
|
|
41
|
+
if (data && isAuthToken(data)) return data;
|
|
42
|
+
throw new Error("Authentication error. Liveblocks could not parse the response of your authentication endpoint");
|
|
43
|
+
}
|
|
4
44
|
|
|
5
45
|
function lsonObjectToJson(obj) {
|
|
6
46
|
const result = {};
|
|
@@ -16,13 +56,18 @@ function lsonListToJson(value) {
|
|
|
16
56
|
}
|
|
17
57
|
|
|
18
58
|
function lsonToJson(value) {
|
|
19
|
-
|
|
59
|
+
if (value instanceof LiveObject) return lsonObjectToJson(value.toObject());
|
|
60
|
+
if (value instanceof LiveList) return function(value) {
|
|
20
61
|
return lsonListToJson(value.toArray());
|
|
21
|
-
}(value)
|
|
62
|
+
}(value);
|
|
63
|
+
if (value instanceof LiveMap) return function(map) {
|
|
22
64
|
const result = {};
|
|
23
65
|
for (const [key, value] of map.entries()) result[key] = lsonToJson(value);
|
|
24
66
|
return result;
|
|
25
|
-
}(value)
|
|
67
|
+
}(value);
|
|
68
|
+
if (value instanceof LiveRegister) return value.data;
|
|
69
|
+
if (value instanceof AbstractCrdt) throw new Error("Unhandled subclass of AbstractCrdt encountered");
|
|
70
|
+
return Array.isArray(value) ? lsonListToJson(value) : isPlainObject(value) ? lsonObjectToJson(value) : value;
|
|
26
71
|
}
|
|
27
72
|
|
|
28
73
|
function isPlainObject(obj) {
|
|
@@ -48,7 +93,7 @@ function patchLiveObjectKey(liveObject, key, prev, next) {
|
|
|
48
93
|
const value = liveObject.get(key);
|
|
49
94
|
if (void 0 === next) liveObject.delete(key); else if (void 0 === value) liveObject.set(key, anyToCrdt(next)); else {
|
|
50
95
|
if (prev === next) return;
|
|
51
|
-
|
|
96
|
+
value instanceof LiveList && Array.isArray(prev) && Array.isArray(next) ? function(liveList, prev, next) {
|
|
52
97
|
let i = 0, prevEnd = prev.length - 1, nextEnd = next.length - 1, prevNode = prev[0], nextNode = next[0];
|
|
53
98
|
outer: {
|
|
54
99
|
for (;prevNode === nextNode; ) {
|
|
@@ -70,14 +115,14 @@ function patchLiveObjectKey(liveObject, key, prev, next) {
|
|
|
70
115
|
for (;i <= prevEnd && i <= nextEnd; ) {
|
|
71
116
|
prevNode = prev[i], nextNode = next[i];
|
|
72
117
|
const liveListNode = liveList.get(i);
|
|
73
|
-
|
|
118
|
+
liveListNode instanceof LiveObject && isPlainObject(prevNode) && isPlainObject(nextNode) ? patchLiveObject(liveListNode, prevNode, nextNode) : liveList.set(i, anyToCrdt(nextNode)),
|
|
74
119
|
i++;
|
|
75
120
|
}
|
|
76
121
|
for (;i <= nextEnd; ) liveList.insert(anyToCrdt(next[i]), i), i++;
|
|
77
122
|
let localI = i;
|
|
78
123
|
for (;localI <= prevEnd; ) liveList.delete(i), localI++;
|
|
79
124
|
}
|
|
80
|
-
}(value, prev, next) :
|
|
125
|
+
}(value, prev, next) : value instanceof LiveObject && isPlainObject(prev) && isPlainObject(next) ? patchLiveObject(value, prev, next) : liveObject.set(key, anyToCrdt(next));
|
|
81
126
|
}
|
|
82
127
|
}
|
|
83
128
|
|
|
@@ -92,8 +137,8 @@ function patchImmutableObject(state, updates) {
|
|
|
92
137
|
return updates.reduce(((state, update) => function(state, update) {
|
|
93
138
|
const path = function(node) {
|
|
94
139
|
const path = [];
|
|
95
|
-
for (;
|
|
96
|
-
node = node.
|
|
140
|
+
for (;null != node._parentKey && null != node._parent; ) node._parent instanceof LiveList ? path.push(node._parent._indexOfPosition(node._parentKey)) : path.push(node._parentKey),
|
|
141
|
+
node = node._parent;
|
|
97
142
|
return path;
|
|
98
143
|
}(update.node);
|
|
99
144
|
return patchImmutableNode(state, path, update);
|
|
@@ -127,10 +172,7 @@ function patchImmutableNode(state, path, update) {
|
|
|
127
172
|
{
|
|
128
173
|
if ("object" != typeof state) throw new Error("Internal: received update on LiveMap but state was not an object");
|
|
129
174
|
const newState = Object.assign({}, state);
|
|
130
|
-
for (const key in update.updates)
|
|
131
|
-
const value = update.node.get(key);
|
|
132
|
-
void 0 !== value && (newState[key] = lsonToJson(value));
|
|
133
|
-
} else "delete" === (null === (_d = update.updates[key]) || void 0 === _d ? void 0 : _d.type) && delete newState[key];
|
|
175
|
+
for (const key in update.updates) "update" === (null === (_c = update.updates[key]) || void 0 === _c ? void 0 : _c.type) ? newState[key] = lsonToJson(update.node.get(key)) : "delete" === (null === (_d = update.updates[key]) || void 0 === _d ? void 0 : _d.type) && delete newState[key];
|
|
134
176
|
return newState;
|
|
135
177
|
}
|
|
136
178
|
}
|
|
@@ -143,4 +185,4 @@ function patchImmutableNode(state, path, update) {
|
|
|
143
185
|
});
|
|
144
186
|
}
|
|
145
187
|
|
|
146
|
-
export { lsonToJson, patchImmutableObject, patchLiveObjectKey };
|
|
188
|
+
export { isAppOnlyAuthToken, isAuthToken, isRoomAuthToken, isScope, lsonToJson, parseAuthToken, patchImmutableObject, patchLiveObjectKey };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liveblocks/client",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.16",
|
|
4
4
|
"description": "A client that lets you interact with Liveblocks servers.",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"module": "./index.mjs",
|
|
@@ -33,9 +33,8 @@
|
|
|
33
33
|
"build": "rollup -c && cp ./package.json ./README.md ./lib",
|
|
34
34
|
"format": "eslint --fix src/ test/ && prettier --write src/ test/",
|
|
35
35
|
"lint": "eslint src/ test/",
|
|
36
|
-
"test": "jest --watch
|
|
37
|
-
"test-ci": "jest
|
|
38
|
-
"test-e2e": "jest --silent --verbose --config=./jest.config.e2e.js"
|
|
36
|
+
"test": "jest --watch",
|
|
37
|
+
"test-ci": "jest"
|
|
39
38
|
},
|
|
40
39
|
"license": "Apache-2.0",
|
|
41
40
|
"devDependencies": {
|
|
@@ -46,26 +45,23 @@
|
|
|
46
45
|
"@rollup/plugin-node-resolve": "^13.1.3",
|
|
47
46
|
"@rollup/plugin-replace": "^4.0.0",
|
|
48
47
|
"@rollup/plugin-typescript": "^8.3.1",
|
|
49
|
-
"@types/jest": "^26.0.
|
|
48
|
+
"@types/jest": "^26.0.21",
|
|
50
49
|
"@types/node-fetch": "^2.6.1",
|
|
51
|
-
"@types/ws": "^8.
|
|
52
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
53
|
-
"@typescript-eslint/parser": "^5.
|
|
54
|
-
"dotenv": "^16.0.0",
|
|
50
|
+
"@types/ws": "^8.2.2",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^5.17.0",
|
|
52
|
+
"@typescript-eslint/parser": "^5.17.0",
|
|
55
53
|
"eslint": "^8.12.0",
|
|
56
54
|
"eslint-plugin-import": "^2.26.0",
|
|
57
55
|
"eslint-plugin-simple-import-sort": "^7.0.0",
|
|
58
|
-
"jest": "^
|
|
56
|
+
"jest": "^26.6.3",
|
|
59
57
|
"jest-each": "^27.5.1",
|
|
60
|
-
"jest-environment-jsdom": "^28.1.0",
|
|
61
58
|
"msw": "^0.39.1",
|
|
62
59
|
"node-fetch": "2.6.7",
|
|
63
|
-
"regenerator-runtime": "^0.13.9",
|
|
64
60
|
"rollup": "^2.68.0",
|
|
65
61
|
"rollup-plugin-command": "^1.1.3",
|
|
66
62
|
"rollup-plugin-dts": "^4.1.0",
|
|
67
63
|
"rollup-plugin-terser": "^7.0.2",
|
|
68
|
-
"typescript": "^4.
|
|
64
|
+
"typescript": "^4.4.0",
|
|
69
65
|
"whatwg-fetch": "^3.6.2",
|
|
70
66
|
"ws": "^8.5.0"
|
|
71
67
|
},
|