@liveblocks/client 0.13.2 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/lib/cjs/AbstractCrdt.d.ts +8 -4
  2. package/lib/cjs/AbstractCrdt.js +2 -2
  3. package/lib/cjs/LiveList.d.ts +9 -4
  4. package/lib/cjs/LiveList.js +58 -9
  5. package/lib/cjs/LiveMap.d.ts +7 -3
  6. package/lib/cjs/LiveMap.js +23 -5
  7. package/lib/cjs/LiveObject.d.ts +17 -7
  8. package/lib/cjs/LiveObject.js +45 -15
  9. package/lib/cjs/LiveRegister.d.ts +8 -4
  10. package/lib/cjs/LiveRegister.js +17 -4
  11. package/lib/cjs/client.js +50 -7
  12. package/lib/cjs/{immutable/index.d.ts → immutable.d.ts} +5 -3
  13. package/lib/cjs/{immutable/index.js → immutable.js} +98 -21
  14. package/lib/cjs/index.d.ts +1 -1
  15. package/lib/cjs/live.d.ts +7 -0
  16. package/lib/cjs/room.d.ts +17 -9
  17. package/lib/cjs/room.js +203 -81
  18. package/lib/cjs/types.d.ts +26 -1
  19. package/lib/cjs/utils.d.ts +2 -1
  20. package/lib/cjs/utils.js +76 -1
  21. package/lib/esm/AbstractCrdt.d.ts +8 -4
  22. package/lib/esm/AbstractCrdt.js +2 -2
  23. package/lib/esm/LiveList.d.ts +9 -4
  24. package/lib/esm/LiveList.js +59 -10
  25. package/lib/esm/LiveMap.d.ts +7 -3
  26. package/lib/esm/LiveMap.js +23 -5
  27. package/lib/esm/LiveObject.d.ts +17 -7
  28. package/lib/esm/LiveObject.js +45 -15
  29. package/lib/esm/LiveRegister.d.ts +8 -4
  30. package/lib/esm/LiveRegister.js +18 -5
  31. package/lib/esm/client.js +50 -7
  32. package/lib/esm/{immutable/index.d.ts → immutable.d.ts} +5 -3
  33. package/lib/esm/{immutable/index.js → immutable.js} +96 -21
  34. package/lib/esm/index.d.ts +1 -1
  35. package/lib/esm/live.d.ts +7 -0
  36. package/lib/esm/room.d.ts +17 -9
  37. package/lib/esm/room.js +203 -62
  38. package/lib/esm/types.d.ts +26 -1
  39. package/lib/esm/utils.d.ts +2 -1
  40. package/lib/esm/utils.js +75 -1
  41. package/package.json +6 -2
@@ -1,7 +1,9 @@
1
- import { LiveList } from "../LiveList";
2
- import { LiveObject } from "../LiveObject";
3
- import { StorageUpdate } from "../types";
1
+ import { LiveList } from "./LiveList";
2
+ import { LiveObject } from "./LiveObject";
3
+ import { StorageUpdate } from "./types";
4
4
  export declare function liveObjectToJson(liveObject: LiveObject<any>): any;
5
+ export declare function liveNodeToJson(value: any): any;
5
6
  export declare function patchLiveList<T>(liveList: LiveList<T>, prev: Array<T>, next: Array<T>): void;
7
+ export declare function patchLiveObjectKey<T>(liveObject: LiveObject<T>, key: keyof T, prev: any, next: any): void;
6
8
  export declare function patchLiveObject<T extends Record<string, any>>(root: LiveObject<T>, prev: T, next: T): void;
7
9
  export declare function patchImmutableObject<T>(state: T, updates: StorageUpdate[]): T;
@@ -1,9 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.patchImmutableObject = exports.patchLiveObject = exports.patchLiveList = exports.liveObjectToJson = void 0;
4
- const LiveList_1 = require("../LiveList");
5
- const LiveMap_1 = require("../LiveMap");
6
- const LiveObject_1 = require("../LiveObject");
3
+ exports.patchImmutableObject = exports.patchLiveObject = exports.patchLiveObjectKey = exports.patchLiveList = exports.liveNodeToJson = exports.liveObjectToJson = void 0;
4
+ const LiveList_1 = require("./LiveList");
5
+ const LiveMap_1 = require("./LiveMap");
6
+ const LiveObject_1 = require("./LiveObject");
7
+ const LiveRegister_1 = require("./LiveRegister");
7
8
  function liveObjectToJson(liveObject) {
8
9
  const result = {};
9
10
  const obj = liveObject.toObject();
@@ -34,8 +35,12 @@ function liveNodeToJson(value) {
34
35
  else if (value instanceof LiveMap_1.LiveMap) {
35
36
  return liveMapToJson(value);
36
37
  }
38
+ else if (value instanceof LiveRegister_1.LiveRegister) {
39
+ return value.data;
40
+ }
37
41
  return value;
38
42
  }
43
+ exports.liveNodeToJson = liveNodeToJson;
39
44
  function isPlainObject(obj) {
40
45
  return Object.prototype.toString.call(obj) === "[object Object]";
41
46
  }
@@ -101,8 +106,10 @@ function patchLiveList(liveList, prev, next) {
101
106
  }
102
107
  }
103
108
  else if (i > nextEnd) {
104
- while (i <= prevEnd) {
105
- liveList.delete(i++);
109
+ let localI = i;
110
+ while (localI <= prevEnd) {
111
+ liveList.delete(i);
112
+ localI++;
106
113
  }
107
114
  }
108
115
  else {
@@ -132,21 +139,36 @@ function patchLiveList(liveList, prev, next) {
132
139
  }
133
140
  }
134
141
  exports.patchLiveList = patchLiveList;
142
+ function patchLiveObjectKey(liveObject, key, prev, next) {
143
+ const value = liveObject.get(key);
144
+ if (next === undefined) {
145
+ liveObject.delete(key);
146
+ }
147
+ else if (value === undefined) {
148
+ liveObject.set(key, anyToCrdt(next));
149
+ }
150
+ else if (prev === next) {
151
+ return;
152
+ }
153
+ else if (value instanceof LiveList_1.LiveList &&
154
+ Array.isArray(prev) &&
155
+ Array.isArray(next)) {
156
+ patchLiveList(value, prev, next);
157
+ }
158
+ else if (value instanceof LiveObject_1.LiveObject &&
159
+ isPlainObject(prev) &&
160
+ isPlainObject(next)) {
161
+ patchLiveObject(value, prev, next);
162
+ }
163
+ else {
164
+ liveObject.set(key, anyToCrdt(next));
165
+ }
166
+ }
167
+ exports.patchLiveObjectKey = patchLiveObjectKey;
135
168
  function patchLiveObject(root, prev, next) {
136
169
  const updates = {};
137
170
  for (const key in next) {
138
- if (prev[key] === next[key]) {
139
- continue;
140
- }
141
- else if (Array.isArray(prev[key]) && Array.isArray(next[key])) {
142
- patchLiveList(root.get(key), prev[key], next[key]);
143
- }
144
- else if (isPlainObject(prev[key]) && isPlainObject(next[key])) {
145
- patchLiveObject(root.get(key), prev[key], next[key]);
146
- }
147
- else {
148
- updates[key] = anyToCrdt(next[key]);
149
- }
171
+ patchLiveObjectKey(root, key, prev[key], next[key]);
150
172
  }
151
173
  for (const key in prev) {
152
174
  if (next[key] === undefined) {
@@ -180,6 +202,7 @@ function patchImmutableObjectWithUpdate(state, update) {
180
202
  return patchImmutableNode(state, path, update);
181
203
  }
182
204
  function patchImmutableNode(state, path, update) {
205
+ var _a, _b, _c, _d;
183
206
  const pathItem = path.pop();
184
207
  if (pathItem === undefined) {
185
208
  switch (update.type) {
@@ -187,19 +210,73 @@ function patchImmutableNode(state, path, update) {
187
210
  if (typeof state !== "object") {
188
211
  throw new Error("Internal: received update on LiveObject but state was not an object");
189
212
  }
190
- return liveObjectToJson(update.node);
213
+ let newState = Object.assign({}, state);
214
+ for (const key in update.updates) {
215
+ if (((_a = update.updates[key]) === null || _a === void 0 ? void 0 : _a.type) === "update") {
216
+ newState[key] = liveNodeToJson(update.node.get(key));
217
+ }
218
+ else if (((_b = update.updates[key]) === null || _b === void 0 ? void 0 : _b.type) === "delete") {
219
+ delete newState[key];
220
+ }
221
+ }
222
+ return newState;
191
223
  }
192
224
  case "LiveList": {
193
225
  if (Array.isArray(state) === false) {
194
226
  throw new Error("Internal: received update on LiveList but state was not an array");
195
227
  }
196
- return liveListToJson(update.node);
228
+ let newState = state.map((x) => x);
229
+ for (const listUpdate of update.updates) {
230
+ if (listUpdate.type === "insert") {
231
+ if (listUpdate.index === newState.length) {
232
+ newState.push(liveNodeToJson(listUpdate.item));
233
+ }
234
+ else {
235
+ newState = [
236
+ ...newState.slice(0, listUpdate.index),
237
+ liveNodeToJson(listUpdate.item),
238
+ ...newState.slice(listUpdate.index),
239
+ ];
240
+ }
241
+ }
242
+ else if (listUpdate.type === "delete") {
243
+ newState.splice(listUpdate.index, 1);
244
+ }
245
+ else if (listUpdate.type === "move") {
246
+ if (listUpdate.previousIndex > listUpdate.index) {
247
+ newState = [
248
+ ...newState.slice(0, listUpdate.index),
249
+ liveNodeToJson(listUpdate.item),
250
+ ...newState.slice(listUpdate.index, listUpdate.previousIndex),
251
+ ...newState.slice(listUpdate.previousIndex + 1),
252
+ ];
253
+ }
254
+ else {
255
+ newState = [
256
+ ...newState.slice(0, listUpdate.previousIndex),
257
+ ...newState.slice(listUpdate.previousIndex + 1, listUpdate.index + 1),
258
+ liveNodeToJson(listUpdate.item),
259
+ ...newState.slice(listUpdate.index + 1),
260
+ ];
261
+ }
262
+ }
263
+ }
264
+ return newState;
197
265
  }
198
266
  case "LiveMap": {
199
267
  if (typeof state !== "object") {
200
268
  throw new Error("Internal: received update on LiveMap but state was not an object");
201
269
  }
202
- return liveMapToJson(update.node);
270
+ let newState = Object.assign({}, state);
271
+ for (const key in update.updates) {
272
+ if (((_c = update.updates[key]) === null || _c === void 0 ? void 0 : _c.type) === "update") {
273
+ newState[key] = liveNodeToJson(update.node.get(key));
274
+ }
275
+ else if (((_d = update.updates[key]) === null || _d === void 0 ? void 0 : _d.type) === "delete") {
276
+ delete newState[key];
277
+ }
278
+ }
279
+ return newState;
203
280
  }
204
281
  }
205
282
  }
@@ -1,5 +1,5 @@
1
1
  export { LiveObject } from "./LiveObject";
2
2
  export { LiveMap } from "./LiveMap";
3
3
  export { LiveList } from "./LiveList";
4
- export type { Others, Presence, Room, Client, User } from "./types";
4
+ export type { Others, Presence, Room, Client, User, BroadcastOptions, } from "./types";
5
5
  export { createClient } from "./client";
package/lib/cjs/live.d.ts CHANGED
@@ -122,6 +122,7 @@ export declare type UpdateObjectOp = {
122
122
  };
123
123
  };
124
124
  export declare type CreateObjectOp = {
125
+ opId?: string;
125
126
  id: string;
126
127
  type: OpType.CreateObject;
127
128
  parentId?: string;
@@ -131,18 +132,21 @@ export declare type CreateObjectOp = {
131
132
  };
132
133
  };
133
134
  export declare type CreateListOp = {
135
+ opId?: string;
134
136
  id: string;
135
137
  type: OpType.CreateList;
136
138
  parentId: string;
137
139
  parentKey: string;
138
140
  };
139
141
  export declare type CreateMapOp = {
142
+ opId?: string;
140
143
  id: string;
141
144
  type: OpType.CreateMap;
142
145
  parentId: string;
143
146
  parentKey: string;
144
147
  };
145
148
  export declare type CreateRegisterOp = {
149
+ opId?: string;
146
150
  id: string;
147
151
  type: OpType.CreateRegister;
148
152
  parentId: string;
@@ -150,15 +154,18 @@ export declare type CreateRegisterOp = {
150
154
  data: any;
151
155
  };
152
156
  export declare type DeleteCrdtOp = {
157
+ opId?: string;
153
158
  id: string;
154
159
  type: OpType.DeleteCrdt;
155
160
  };
156
161
  export declare type SetParentKeyOp = {
162
+ opId?: string;
157
163
  id: string;
158
164
  type: OpType.SetParentKey;
159
165
  parentKey: string;
160
166
  };
161
167
  export declare type DeleteObjectKeyOp = {
168
+ opId?: string;
162
169
  id: string;
163
170
  type: OpType.DeleteObjectKey;
164
171
  key: string;
package/lib/cjs/room.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Others, Presence, ClientOptions, Room, MyPresenceCallback, OthersEventCallback, AuthEndpoint, EventCallback, User, Connection, ErrorCallback, AuthenticationToken, ConnectionCallback, StorageCallback, StorageUpdate } from "./types";
1
+ import { Others, Presence, Room, MyPresenceCallback, OthersEventCallback, EventCallback, User, Connection, ErrorCallback, AuthenticationToken, ConnectionCallback, StorageCallback, StorageUpdate, BroadcastOptions, AuthorizeResponse, Authentication } from "./types";
2
2
  import { ClientMessage, Op } from "./live";
3
3
  import { LiveMap } from "./LiveMap";
4
4
  import { LiveObject } from "./LiveObject";
@@ -11,6 +11,7 @@ declare type HistoryItem = Array<Op | {
11
11
  declare type IdFactory = () => string;
12
12
  export declare type State = {
13
13
  connection: Connection;
14
+ lastConnectionId: number | null;
14
15
  socket: WebSocket | null;
15
16
  lastFlushTime: number;
16
17
  buffer: {
@@ -62,9 +63,10 @@ export declare type State = {
62
63
  nodes: Set<AbstractCrdt>;
63
64
  };
64
65
  };
66
+ offlineOperations: Map<string, Op>;
65
67
  };
66
68
  export declare type Effects = {
67
- authenticate(): void;
69
+ authenticate(auth: (room: string) => Promise<AuthorizeResponse>, createWebSocket: (token: string) => WebSocket): void;
68
70
  send(messages: ClientMessage[]): void;
69
71
  delayFlush(delay: number): number;
70
72
  startHeartbeatInterval(): number;
@@ -73,13 +75,13 @@ export declare type Effects = {
73
75
  };
74
76
  declare type Context = {
75
77
  room: string;
76
- authEndpoint: AuthEndpoint;
77
- liveblocksServer: string;
78
78
  throttleDelay: number;
79
- publicApiKey?: string;
79
+ fetchPolyfill?: typeof fetch;
80
+ WebSocketPolyfill?: typeof WebSocket;
81
+ authentication: Authentication;
82
+ liveblocksServer: string;
80
83
  };
81
84
  export declare function makeStateMachine(state: State, context: Context, mockedEffects?: Effects): {
82
- onOpen: () => void;
83
85
  onClose: (event: {
84
86
  code: number;
85
87
  wasClean: boolean;
@@ -89,6 +91,12 @@ export declare function makeStateMachine(state: State, context: Context, mockedE
89
91
  authenticationSuccess: (token: AuthenticationToken, socket: WebSocket) => void;
90
92
  heartbeat: () => void;
91
93
  onNavigatorOnline: () => void;
94
+ simulateSocketClose: () => void;
95
+ simulateSendCloseEvent: (event: {
96
+ code: number;
97
+ wasClean: boolean;
98
+ reason: any;
99
+ }) => void;
92
100
  onVisibilityChange: (visibilityState: VisibilityState) => void;
93
101
  getUndoStack: () => HistoryItem[];
94
102
  getItemsCount: () => number;
@@ -118,7 +126,7 @@ export declare function makeStateMachine(state: State, context: Context, mockedE
118
126
  updatePresence: <T_4 extends Presence>(overrides: Partial<T_4>, options?: {
119
127
  addToHistory: boolean;
120
128
  } | undefined) => void;
121
- broadcastEvent: (event: any) => void;
129
+ broadcastEvent: (event: any, options?: BroadcastOptions) => void;
122
130
  batch: (callback: () => void) => void;
123
131
  undo: () => void;
124
132
  redo: () => void;
@@ -144,8 +152,8 @@ export declare type InternalRoom = {
144
152
  onNavigatorOnline: () => void;
145
153
  onVisibilityChange: (visibilityState: VisibilityState) => void;
146
154
  };
147
- export declare function createRoom(name: string, options: ClientOptions & {
155
+ export declare function createRoom(options: {
148
156
  defaultPresence?: Presence;
149
157
  defaultStorageRoot?: Record<string, any>;
150
- }): InternalRoom;
158
+ }, context: Context): InternalRoom;
151
159
  export {};