@liveblocks/core 1.0.6 → 1.0.7-test1

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.ts CHANGED
@@ -1312,7 +1312,11 @@ declare type Pos = Brand<string, "Pos">;
1312
1312
  * When given no bounds at all, returns the "first" canonical position.
1313
1313
  */
1314
1314
  declare function makePosition(x?: Pos, y?: Pos): Pos;
1315
- declare function comparePosition(posA: Pos, posB: Pos): number;
1315
+ /**
1316
+ * Checks that a str is a valid Pos, and converts it to the nearest valid one
1317
+ * if not.
1318
+ */
1319
+ declare function asPos(str: string): Pos;
1316
1320
 
1317
1321
  /**
1318
1322
  * Shallowly compares two given values.
@@ -1735,4 +1739,4 @@ declare type EnsureJson<T> = [
1735
1739
  [K in keyof T]: EnsureJson<T[K]>;
1736
1740
  };
1737
1741
 
1738
- export { AckOp, AppOnlyAuthToken, AuthToken, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, ConnectionStatus, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, FetchStorageClientMsg, History, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LiveList, LiveMap, LiveNode, LiveObject, LiveStructure, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomAuthToken, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, StorageStatus, StorageUpdate, ToImmutable, ToJson, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, assert, assertNever, b64decode, comparePosition, createClient, deprecate, deprecateIf, errorIf, freeze, isAppOnlyAuthToken, isAuthToken, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRoomAuthToken, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, tryParseJson };
1742
+ export { AckOp, AppOnlyAuthToken, AuthToken, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, ConnectionStatus, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, FetchStorageClientMsg, History, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LiveList, LiveMap, LiveNode, LiveObject, LiveStructure, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomAuthToken, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, StorageStatus, StorageUpdate, ToImmutable, ToJson, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, asPos, assert, assertNever, b64decode, createClient, deprecate, deprecateIf, errorIf, freeze, isAppOnlyAuthToken, isAuthToken, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRoomAuthToken, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, tryParseJson };
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ var onMessageFromPanel = eventSource.observable;
117
117
  // src/devtools/index.ts
118
118
  var VERSION = true ? (
119
119
  /* istanbul ignore next */
120
- "1.0.6"
120
+ "1.0.7-test1"
121
121
  ) : "dev";
122
122
  var _devtoolsSetupHasRun = false;
123
123
  function setupDevTools(getAllRooms) {
@@ -2179,6 +2179,37 @@ var LiveObject = class extends AbstractCrdt {
2179
2179
  this._map = new Map(Object.entries(obj));
2180
2180
  }
2181
2181
  /** @internal */
2182
+ static _buildRootAndParentToChildren(items) {
2183
+ const parentToChildren = /* @__PURE__ */ new Map();
2184
+ let root = null;
2185
+ for (const [id, crdt] of items) {
2186
+ if (isRootCrdt(crdt)) {
2187
+ root = [id, crdt];
2188
+ } else {
2189
+ const tuple = [id, crdt];
2190
+ const children = parentToChildren.get(crdt.parentId);
2191
+ if (children !== void 0) {
2192
+ children.push(tuple);
2193
+ } else {
2194
+ parentToChildren.set(crdt.parentId, [tuple]);
2195
+ }
2196
+ }
2197
+ }
2198
+ if (root === null) {
2199
+ throw new Error("Root can't be null");
2200
+ }
2201
+ return [root, parentToChildren];
2202
+ }
2203
+ /** @internal */
2204
+ static _fromItems(items, pool) {
2205
+ const [root, parentToChildren] = LiveObject._buildRootAndParentToChildren(items);
2206
+ return LiveObject._deserialize(
2207
+ root,
2208
+ parentToChildren,
2209
+ pool
2210
+ );
2211
+ }
2212
+ /** @internal */
2182
2213
  _toOps(parentId, parentKey, pool) {
2183
2214
  if (this._id === void 0) {
2184
2215
  throw new Error("Cannot serialize item is not attached");
@@ -3249,14 +3280,15 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3249
3280
  token: null,
3250
3281
  lastConnectionId: null,
3251
3282
  socket: null,
3252
- numberOfRetry: 0,
3253
- lastFlushTime: 0,
3254
- timeoutHandles: {
3283
+ numRetries: 0,
3284
+ timers: {
3255
3285
  flush: void 0,
3256
3286
  reconnect: void 0,
3287
+ heartbeat: void 0,
3257
3288
  pongTimeout: void 0
3258
3289
  },
3259
3290
  buffer: {
3291
+ lastFlushedAt: 0,
3260
3292
  me: (
3261
3293
  // Queue up the initial presence message as a Full Presence™ update
3262
3294
  {
@@ -3267,9 +3299,6 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3267
3299
  messages: [],
3268
3300
  storageOperations: []
3269
3301
  },
3270
- intervalHandles: {
3271
- heartbeat: void 0
3272
- },
3273
3302
  connection: new ValueRef({ status: "closed" }),
3274
3303
  me: new MeRef(initialPresence),
3275
3304
  others: new OthersRef(),
@@ -3302,16 +3331,16 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3302
3331
  if (process.env.NODE_ENV !== "production") {
3303
3332
  const stackTrace = captureStackTrace("Storage mutation", this.dispatch);
3304
3333
  if (stackTrace) {
3305
- ops.forEach((op) => {
3334
+ for (const op of ops) {
3306
3335
  if (op.opId) {
3307
3336
  nn(context.opStackTraces).set(op.opId, stackTrace);
3308
3337
  }
3309
- });
3338
+ }
3310
3339
  }
3311
3340
  }
3312
3341
  if (activeBatch) {
3313
3342
  activeBatch.ops.push(...ops);
3314
- storageUpdates.forEach((value, key) => {
3343
+ for (const [key, value] of storageUpdates) {
3315
3344
  activeBatch.updates.storageUpdates.set(
3316
3345
  key,
3317
3346
  mergeStorageUpdates(
@@ -3319,7 +3348,7 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3319
3348
  value
3320
3349
  )
3321
3350
  );
3322
- });
3351
+ }
3323
3352
  activeBatch.reverseOps.unshift(...reverse);
3324
3353
  } else {
3325
3354
  batchUpdates(() => {
@@ -3378,18 +3407,10 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3378
3407
  }
3379
3408
  context.socket.send(JSON.stringify(messageOrMessages));
3380
3409
  },
3381
- delayFlush(delay) {
3382
- return setTimeout(tryFlushing, delay);
3383
- },
3384
- startHeartbeatInterval() {
3385
- return setInterval(heartbeat, HEARTBEAT_INTERVAL);
3386
- },
3387
- schedulePongTimeout() {
3388
- return setTimeout(pongTimeout, PONG_TIMEOUT);
3389
- },
3390
- scheduleReconnect(delay) {
3391
- return setTimeout(connect, delay);
3392
- }
3410
+ scheduleFlush: (delay) => setTimeout(tryFlushing, delay),
3411
+ scheduleReconnect: (delay) => setTimeout(connect, delay),
3412
+ startHeartbeatInterval: () => setInterval(heartbeat, HEARTBEAT_INTERVAL),
3413
+ schedulePongTimeout: () => setTimeout(pongTimeout, PONG_TIMEOUT)
3393
3414
  };
3394
3415
  const self = new DerivedRef(
3395
3416
  context.connection,
@@ -3413,7 +3434,7 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3413
3434
  if (context.root) {
3414
3435
  updateRoot(message.items, batchedUpdatesWrapper);
3415
3436
  } else {
3416
- context.root = load(message.items);
3437
+ context.root = LiveObject._fromItems(message.items, pool);
3417
3438
  }
3418
3439
  for (const key in context.initialStorage) {
3419
3440
  if (context.root.get(key) === void 0) {
@@ -3421,43 +3442,18 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3421
3442
  }
3422
3443
  }
3423
3444
  }
3424
- function buildRootAndParentToChildren(items) {
3425
- const parentToChildren = /* @__PURE__ */ new Map();
3426
- let root = null;
3427
- for (const [id, crdt] of items) {
3428
- if (isRootCrdt(crdt)) {
3429
- root = [id, crdt];
3430
- } else {
3431
- const tuple = [id, crdt];
3432
- const children = parentToChildren.get(crdt.parentId);
3433
- if (children !== void 0) {
3434
- children.push(tuple);
3435
- } else {
3436
- parentToChildren.set(crdt.parentId, [tuple]);
3437
- }
3438
- }
3439
- }
3440
- if (root === null) {
3441
- throw new Error("Root can't be null");
3442
- }
3443
- return [root, parentToChildren];
3444
- }
3445
3445
  function updateRoot(items, batchedUpdatesWrapper) {
3446
3446
  if (!context.root) {
3447
3447
  return;
3448
3448
  }
3449
3449
  const currentItems = /* @__PURE__ */ new Map();
3450
- context.nodes.forEach((node, id) => {
3450
+ for (const [id, node] of context.nodes) {
3451
3451
  currentItems.set(id, node._serialize());
3452
- });
3452
+ }
3453
3453
  const ops = getTreesDiffOperations(currentItems, new Map(items));
3454
3454
  const result = applyOps(ops, false);
3455
3455
  notify(result.updates, batchedUpdatesWrapper);
3456
3456
  }
3457
- function load(items) {
3458
- const [root, parentToChildren] = buildRootAndParentToChildren(items);
3459
- return LiveObject._deserialize(root, parentToChildren, pool);
3460
- }
3461
3457
  function _addToRealUndoStack(historyOps, batchedUpdatesWrapper) {
3462
3458
  if (context.undoStack.length >= 50) {
3463
3459
  context.undoStack.shift();
@@ -3702,10 +3698,9 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3702
3698
  }
3703
3699
  context.token = null;
3704
3700
  updateConnection({ status: "unavailable" }, batchUpdates);
3705
- context.numberOfRetry++;
3706
- context.timeoutHandles.reconnect = effects.scheduleReconnect(
3707
- getRetryDelay()
3708
- );
3701
+ context.numRetries++;
3702
+ clearTimeout(context.timers.reconnect);
3703
+ context.timers.reconnect = effects.scheduleReconnect(getRetryDelay());
3709
3704
  }
3710
3705
  function onVisibilityChange(visibilityState) {
3711
3706
  if (visibilityState === "visible" && context.connection.current.status === "open") {
@@ -3768,6 +3763,12 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3768
3763
  reconnect();
3769
3764
  }
3770
3765
  }
3766
+ function canUndo() {
3767
+ return context.undoStack.length > 0;
3768
+ }
3769
+ function canRedo() {
3770
+ return context.redoStack.length > 0;
3771
+ }
3771
3772
  function onHistoryChange(batchedUpdatesWrapper) {
3772
3773
  batchedUpdatesWrapper(() => {
3773
3774
  eventHub.history.notify({ canUndo: canUndo(), canRedo: canRedo() });
@@ -3805,9 +3806,23 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3805
3806
  return compact([parseServerMessage(data)]);
3806
3807
  }
3807
3808
  }
3809
+ function applyAndSendOps(offlineOps, batchedUpdatesWrapper) {
3810
+ if (offlineOps.size === 0) {
3811
+ return;
3812
+ }
3813
+ const messages = [];
3814
+ const ops = Array.from(offlineOps.values());
3815
+ const result = applyOps(ops, true);
3816
+ messages.push({
3817
+ type: 201 /* UPDATE_STORAGE */,
3818
+ ops: result.ops
3819
+ });
3820
+ notify(result.updates, batchedUpdatesWrapper);
3821
+ effects.send(messages);
3822
+ }
3808
3823
  function onMessage(event) {
3809
3824
  if (event.data === "pong") {
3810
- clearTimeout(context.timeoutHandles.pongTimeout);
3825
+ clearTimeout(context.timers.pongTimeout);
3811
3826
  return;
3812
3827
  }
3813
3828
  const messages = parseServerMessages(event.data);
@@ -3867,12 +3882,12 @@ function makeStateMachine(config, initialPresence, initialStorage) {
3867
3882
  }
3868
3883
  case 201 /* UPDATE_STORAGE */: {
3869
3884
  const applyResult = applyOps(message.ops, false);
3870
- applyResult.updates.storageUpdates.forEach((value, key) => {
3885
+ for (const [key, value] of applyResult.updates.storageUpdates) {
3871
3886
  updates.storageUpdates.set(
3872
3887
  key,
3873
3888
  mergeStorageUpdates(updates.storageUpdates.get(key), value)
3874
3889
  );
3875
- });
3890
+ }
3876
3891
  break;
3877
3892
  }
3878
3893
  case 299 /* REJECT_STORAGE_OP */: {
@@ -3909,12 +3924,10 @@ ${Array.from(traces).join("\n\n")}`
3909
3924
  }
3910
3925
  function onClose(event) {
3911
3926
  context.socket = null;
3912
- clearTimeout(context.timeoutHandles.pongTimeout);
3913
- clearInterval(context.intervalHandles.heartbeat);
3914
- if (context.timeoutHandles.flush) {
3915
- clearTimeout(context.timeoutHandles.flush);
3916
- }
3917
- clearTimeout(context.timeoutHandles.reconnect);
3927
+ clearTimeout(context.timers.flush);
3928
+ clearTimeout(context.timers.reconnect);
3929
+ clearInterval(context.timers.heartbeat);
3930
+ clearTimeout(context.timers.pongTimeout);
3918
3931
  context.others.clearOthers();
3919
3932
  batchUpdates(() => {
3920
3933
  notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
@@ -3923,26 +3936,28 @@ ${Array.from(traces).join("\n\n")}`
3923
3936
  const error2 = new LiveblocksError(event.reason, event.code);
3924
3937
  eventHub.error.notify(error2);
3925
3938
  const delay = getRetryDelay(true);
3926
- context.numberOfRetry++;
3939
+ context.numRetries++;
3927
3940
  if (process.env.NODE_ENV !== "production") {
3928
3941
  error(
3929
3942
  `Connection to websocket server closed. Reason: ${error2.message} (code: ${error2.code}). Retrying in ${delay}ms.`
3930
3943
  );
3931
3944
  }
3932
3945
  updateConnection({ status: "unavailable" }, doNotBatchUpdates);
3933
- context.timeoutHandles.reconnect = effects.scheduleReconnect(delay);
3946
+ clearTimeout(context.timers.reconnect);
3947
+ context.timers.reconnect = effects.scheduleReconnect(delay);
3934
3948
  } else if (event.code === 4999 /* CLOSE_WITHOUT_RETRY */) {
3935
3949
  updateConnection({ status: "closed" }, doNotBatchUpdates);
3936
3950
  } else {
3937
3951
  const delay = getRetryDelay();
3938
- context.numberOfRetry++;
3952
+ context.numRetries++;
3939
3953
  if (process.env.NODE_ENV !== "production") {
3940
3954
  warn(
3941
3955
  `Connection to Liveblocks websocket server closed (code: ${event.code}). Retrying in ${delay}ms.`
3942
3956
  );
3943
3957
  }
3944
3958
  updateConnection({ status: "unavailable" }, doNotBatchUpdates);
3945
- context.timeoutHandles.reconnect = effects.scheduleReconnect(delay);
3959
+ clearTimeout(context.timers.reconnect);
3960
+ context.timers.reconnect = effects.scheduleReconnect(delay);
3946
3961
  }
3947
3962
  });
3948
3963
  }
@@ -3954,21 +3969,21 @@ ${Array.from(traces).join("\n\n")}`
3954
3969
  }
3955
3970
  function getRetryDelay(slow = false) {
3956
3971
  if (slow) {
3957
- return BACKOFF_RETRY_DELAYS_SLOW[context.numberOfRetry < BACKOFF_RETRY_DELAYS_SLOW.length ? context.numberOfRetry : BACKOFF_RETRY_DELAYS_SLOW.length - 1];
3972
+ return BACKOFF_RETRY_DELAYS_SLOW[context.numRetries < BACKOFF_RETRY_DELAYS_SLOW.length ? context.numRetries : BACKOFF_RETRY_DELAYS_SLOW.length - 1];
3958
3973
  }
3959
- return BACKOFF_RETRY_DELAYS[context.numberOfRetry < BACKOFF_RETRY_DELAYS.length ? context.numberOfRetry : BACKOFF_RETRY_DELAYS.length - 1];
3974
+ return BACKOFF_RETRY_DELAYS[context.numRetries < BACKOFF_RETRY_DELAYS.length ? context.numRetries : BACKOFF_RETRY_DELAYS.length - 1];
3960
3975
  }
3961
3976
  function onError() {
3962
3977
  }
3963
3978
  function onOpen() {
3964
- clearInterval(context.intervalHandles.heartbeat);
3965
- context.intervalHandles.heartbeat = effects.startHeartbeatInterval();
3979
+ clearInterval(context.timers.heartbeat);
3980
+ context.timers.heartbeat = effects.startHeartbeatInterval();
3966
3981
  if (context.connection.current.status === "connecting") {
3967
3982
  updateConnection(
3968
3983
  __spreadProps(__spreadValues({}, context.connection.current), { status: "open" }),
3969
3984
  batchUpdates
3970
3985
  );
3971
- context.numberOfRetry = 0;
3986
+ context.numRetries = 0;
3972
3987
  if (context.lastConnectionId !== void 0) {
3973
3988
  context.buffer.me = {
3974
3989
  type: "full",
@@ -3993,8 +4008,8 @@ ${Array.from(traces).join("\n\n")}`
3993
4008
  if (context.socket === null) {
3994
4009
  return;
3995
4010
  }
3996
- clearTimeout(context.timeoutHandles.pongTimeout);
3997
- context.timeoutHandles.pongTimeout = effects.schedulePongTimeout();
4011
+ clearTimeout(context.timers.pongTimeout);
4012
+ context.timers.pongTimeout = effects.schedulePongTimeout();
3998
4013
  if (context.socket.readyState === context.socket.OPEN) {
3999
4014
  context.socket.send("ping");
4000
4015
  }
@@ -4003,7 +4018,7 @@ ${Array.from(traces).join("\n\n")}`
4003
4018
  log("Pong timeout. Trying to reconnect.");
4004
4019
  reconnect();
4005
4020
  }
4006
- function reconnect() {
4021
+ function disconnect() {
4007
4022
  if (context.socket) {
4008
4023
  context.socket.removeEventListener("open", onOpen);
4009
4024
  context.socket.removeEventListener("message", onMessage);
@@ -4012,35 +4027,41 @@ ${Array.from(traces).join("\n\n")}`
4012
4027
  context.socket.close();
4013
4028
  context.socket = null;
4014
4029
  }
4015
- updateConnection({ status: "unavailable" }, batchUpdates);
4016
- clearTimeout(context.timeoutHandles.pongTimeout);
4017
- if (context.timeoutHandles.flush) {
4018
- clearTimeout(context.timeoutHandles.flush);
4030
+ clearTimeout(context.timers.flush);
4031
+ clearTimeout(context.timers.reconnect);
4032
+ clearInterval(context.timers.heartbeat);
4033
+ clearTimeout(context.timers.pongTimeout);
4034
+ batchUpdates(() => {
4035
+ updateConnection({ status: "closed" }, doNotBatchUpdates);
4036
+ context.others.clearOthers();
4037
+ notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
4038
+ });
4039
+ for (const eventSource2 of Object.values(eventHub)) {
4040
+ eventSource2.clear();
4019
4041
  }
4020
- clearTimeout(context.timeoutHandles.reconnect);
4021
- clearInterval(context.intervalHandles.heartbeat);
4022
- connect();
4023
4042
  }
4024
- function applyAndSendOps(offlineOps, batchedUpdatesWrapper) {
4025
- if (offlineOps.size === 0) {
4026
- return;
4043
+ function reconnect() {
4044
+ if (context.socket) {
4045
+ context.socket.removeEventListener("open", onOpen);
4046
+ context.socket.removeEventListener("message", onMessage);
4047
+ context.socket.removeEventListener("close", onClose);
4048
+ context.socket.removeEventListener("error", onError);
4049
+ context.socket.close();
4050
+ context.socket = null;
4027
4051
  }
4028
- const messages = [];
4029
- const ops = Array.from(offlineOps.values());
4030
- const result = applyOps(ops, true);
4031
- messages.push({
4032
- type: 201 /* UPDATE_STORAGE */,
4033
- ops: result.ops
4034
- });
4035
- notify(result.updates, batchedUpdatesWrapper);
4036
- effects.send(messages);
4052
+ clearTimeout(context.timers.flush);
4053
+ clearTimeout(context.timers.reconnect);
4054
+ clearInterval(context.timers.heartbeat);
4055
+ clearTimeout(context.timers.pongTimeout);
4056
+ updateConnection({ status: "unavailable" }, batchUpdates);
4057
+ connect();
4037
4058
  }
4038
4059
  function tryFlushing() {
4039
4060
  const storageOps = context.buffer.storageOperations;
4040
4061
  if (storageOps.length > 0) {
4041
- storageOps.forEach((op) => {
4062
+ for (const op of storageOps) {
4042
4063
  context.unacknowledgedOps.set(nn(op.opId), op);
4043
- });
4064
+ }
4044
4065
  notifyStorageStatus();
4045
4066
  }
4046
4067
  if (context.socket === null || context.socket.readyState !== context.socket.OPEN) {
@@ -4048,78 +4069,54 @@ ${Array.from(traces).join("\n\n")}`
4048
4069
  return;
4049
4070
  }
4050
4071
  const now = Date.now();
4051
- const elapsedTime = now - context.lastFlushTime;
4052
- if (elapsedTime > config.throttleDelay) {
4053
- const messages = flushDataToMessages(context);
4054
- if (messages.length === 0) {
4072
+ const elapsedMillis = now - context.buffer.lastFlushedAt;
4073
+ if (elapsedMillis > config.throttleDelay) {
4074
+ const messagesToFlush = serializeBuffer();
4075
+ if (messagesToFlush.length === 0) {
4055
4076
  return;
4056
4077
  }
4057
- effects.send(messages);
4078
+ effects.send(messagesToFlush);
4058
4079
  context.buffer = {
4080
+ lastFlushedAt: now,
4059
4081
  messages: [],
4060
4082
  storageOperations: [],
4061
4083
  me: null
4062
4084
  };
4063
- context.lastFlushTime = now;
4064
4085
  } else {
4065
- if (context.timeoutHandles.flush !== null) {
4066
- clearTimeout(context.timeoutHandles.flush);
4067
- }
4068
- context.timeoutHandles.flush = effects.delayFlush(
4069
- config.throttleDelay - (now - context.lastFlushTime)
4086
+ clearTimeout(context.timers.flush);
4087
+ context.timers.flush = effects.scheduleFlush(
4088
+ config.throttleDelay - elapsedMillis
4070
4089
  );
4071
4090
  }
4072
4091
  }
4073
- function flushDataToMessages(state) {
4092
+ function serializeBuffer() {
4074
4093
  const messages = [];
4075
- if (state.buffer.me) {
4094
+ if (context.buffer.me) {
4076
4095
  messages.push(
4077
- state.buffer.me.type === "full" ? {
4096
+ context.buffer.me.type === "full" ? {
4078
4097
  type: 100 /* UPDATE_PRESENCE */,
4079
4098
  // Populating the `targetActor` field turns this message into
4080
4099
  // a Full Presence™ update message (not a patch), which will get
4081
4100
  // interpreted by other clients as such.
4082
4101
  targetActor: -1,
4083
- data: state.buffer.me.data
4102
+ data: context.buffer.me.data
4084
4103
  } : {
4085
4104
  type: 100 /* UPDATE_PRESENCE */,
4086
- data: state.buffer.me.data
4105
+ data: context.buffer.me.data
4087
4106
  }
4088
4107
  );
4089
4108
  }
4090
- for (const event of state.buffer.messages) {
4109
+ for (const event of context.buffer.messages) {
4091
4110
  messages.push(event);
4092
4111
  }
4093
- if (state.buffer.storageOperations.length > 0) {
4112
+ if (context.buffer.storageOperations.length > 0) {
4094
4113
  messages.push({
4095
4114
  type: 201 /* UPDATE_STORAGE */,
4096
- ops: state.buffer.storageOperations
4115
+ ops: context.buffer.storageOperations
4097
4116
  });
4098
4117
  }
4099
4118
  return messages;
4100
4119
  }
4101
- function disconnect() {
4102
- if (context.socket) {
4103
- context.socket.removeEventListener("open", onOpen);
4104
- context.socket.removeEventListener("message", onMessage);
4105
- context.socket.removeEventListener("close", onClose);
4106
- context.socket.removeEventListener("error", onError);
4107
- context.socket.close();
4108
- context.socket = null;
4109
- }
4110
- batchUpdates(() => {
4111
- updateConnection({ status: "closed" }, doNotBatchUpdates);
4112
- if (context.timeoutHandles.flush) {
4113
- clearTimeout(context.timeoutHandles.flush);
4114
- }
4115
- clearTimeout(context.timeoutHandles.reconnect);
4116
- clearTimeout(context.timeoutHandles.pongTimeout);
4117
- clearInterval(context.intervalHandles.heartbeat);
4118
- context.others.clearOthers();
4119
- notify({ others: [{ type: "reset" }] }, doNotBatchUpdates);
4120
- Object.values(eventHub).forEach((eventSource2) => eventSource2.clear());
4121
- });
4122
- }
4123
4120
  function broadcastEvent(event, options = {
4124
4121
  shouldQueueEventIfNotReady: false
4125
4122
  }) {
@@ -4193,9 +4190,6 @@ ${Array.from(traces).join("\n\n")}`
4193
4190
  }
4194
4191
  tryFlushing();
4195
4192
  }
4196
- function canUndo() {
4197
- return context.undoStack.length > 0;
4198
- }
4199
4193
  function redo() {
4200
4194
  if (context.activeBatch) {
4201
4195
  throw new Error("redo is not allowed during a batch");
@@ -4218,9 +4212,6 @@ ${Array.from(traces).join("\n\n")}`
4218
4212
  }
4219
4213
  tryFlushing();
4220
4214
  }
4221
- function canRedo() {
4222
- return context.redoStack.length > 0;
4223
- }
4224
4215
  function batch(callback) {
4225
4216
  if (context.activeBatch) {
4226
4217
  return callback();
@@ -4511,7 +4502,7 @@ function prepareCreateWebSocket(liveblocksServer, WebSocketPolyfill) {
4511
4502
  // @ts-ignore (__PACKAGE_VERSION__ will be injected by the build script)
4512
4503
  true ? (
4513
4504
  /* istanbul ignore next */
4514
- "1.0.6"
4505
+ "1.0.7-test1"
4515
4506
  ) : "dev"}`
4516
4507
  );
4517
4508
  };
@@ -5119,4 +5110,4 @@ function shallow(a, b) {
5119
5110
 
5120
5111
 
5121
5112
 
5122
- exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.OpCode = OpCode; exports.ServerMsgCode = ServerMsgCode; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asArrayWithLegacyMethods = asArrayWithLegacyMethods; exports.assert = assert; exports.assertNever = assertNever; exports.b64decode = b64decode; exports.comparePosition = comparePosition; exports.createClient = createClient; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.errorIf = errorIf; exports.freeze = freeze; exports.isAppOnlyAuthToken = isAppOnlyAuthToken; exports.isAuthToken = isAuthToken; exports.isChildCrdt = isChildCrdt; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isPlainObject = isPlainObject; exports.isRoomAuthToken = isRoomAuthToken; exports.isRootCrdt = isRootCrdt; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makePosition = makePosition; exports.nn = nn; exports.patchLiveObjectKey = patchLiveObjectKey; exports.shallow = shallow; exports.throwUsageError = throwUsageError; exports.tryParseJson = tryParseJson;
5113
+ exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.OpCode = OpCode; exports.ServerMsgCode = ServerMsgCode; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asArrayWithLegacyMethods = asArrayWithLegacyMethods; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.b64decode = b64decode; exports.createClient = createClient; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.errorIf = errorIf; exports.freeze = freeze; exports.isAppOnlyAuthToken = isAppOnlyAuthToken; exports.isAuthToken = isAuthToken; exports.isChildCrdt = isChildCrdt; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isPlainObject = isPlainObject; exports.isRoomAuthToken = isRoomAuthToken; exports.isRootCrdt = isRootCrdt; exports.legacy_patchImmutableObject = legacy_patchImmutableObject; exports.lsonToJson = lsonToJson; exports.makePosition = makePosition; exports.nn = nn; exports.patchLiveObjectKey = patchLiveObjectKey; exports.shallow = shallow; exports.throwUsageError = throwUsageError; exports.tryParseJson = tryParseJson;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/core",
3
- "version": "1.0.6",
3
+ "version": "1.0.7-test1",
4
4
  "description": "Shared code and foundational internals for Liveblocks",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",