@liveblocks/core 1.1.0-beta1 → 1.1.0-beta3

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 (2) hide show
  1. package/dist/index.js +96 -68
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -157,7 +157,7 @@ var onMessageFromPanel = eventSource.observable;
157
157
  // src/devtools/index.ts
158
158
  var VERSION = true ? (
159
159
  /* istanbul ignore next */
160
- "1.1.0-beta1"
160
+ "1.1.0-beta3"
161
161
  ) : "dev";
162
162
  var _devtoolsSetupHasRun = false;
163
163
  function setupDevTools(getAllRooms) {
@@ -901,10 +901,39 @@ function log(level, message) {
901
901
  logger(message);
902
902
  };
903
903
  }
904
+ function logPrematureErrorOrCloseEvent(e) {
905
+ const conn = "Connection to Liveblocks websocket server";
906
+ return (ctx) => {
907
+ if (e instanceof Error) {
908
+ warn(`${conn} could not be established. ${String(e)}`);
909
+ } else {
910
+ warn(
911
+ isCloseEvent(e) ? `${conn} closed prematurely (code: ${e.code}). Retrying in ${ctx.backoffDelay}ms.` : `${conn} could not be established.`
912
+ );
913
+ }
914
+ };
915
+ }
916
+ function logCloseEvent(event) {
917
+ return (ctx) => {
918
+ warn(
919
+ `Connection to Liveblocks websocket server closed (code: ${event.code}). Retrying in ${ctx.backoffDelay}ms.`
920
+ );
921
+ };
922
+ }
923
+ var logPermanentClose = log(
924
+ 1 /* WARN */,
925
+ "Connection to WebSocket closed permanently. Won't retry."
926
+ );
904
927
  function sendHeartbeat(ctx) {
905
928
  var _a;
906
929
  (_a = ctx.socket) == null ? void 0 : _a.send("ping");
907
930
  }
931
+ function isCloseEvent(error2) {
932
+ return !(error2 instanceof Error) && error2.type === "close";
933
+ }
934
+ function isCustomCloseEvent(error2) {
935
+ return isCloseEvent(error2) && error2.code >= 4e3 && error2.code < 4100;
936
+ }
908
937
  function enableTracing(machine) {
909
938
  const start = (/* @__PURE__ */ new Date()).getTime();
910
939
  function log2(...args) {
@@ -1118,23 +1147,24 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
1118
1147
  effect: log(2 /* ERROR */, err.message)
1119
1148
  };
1120
1149
  }
1150
+ if (isCloseEvent(err) && err.code === 4999) {
1151
+ return {
1152
+ target: "@idle.failed",
1153
+ effect: log(2 /* ERROR */, err.reason)
1154
+ };
1155
+ }
1156
+ if (isCustomCloseEvent(err) && err.code !== 4001) {
1157
+ return {
1158
+ target: "@connecting.backoff",
1159
+ effect: [
1160
+ increaseBackoffDelayAggressively,
1161
+ logPrematureErrorOrCloseEvent(err)
1162
+ ]
1163
+ };
1164
+ }
1121
1165
  return {
1122
1166
  target: "@auth.backoff",
1123
- effect: [
1124
- // Increase the backoff delay conditionally
1125
- // TODO: This is ugly. DRY this up with the other code 40xx checks elsewhere.
1126
- !(err instanceof Error) && err.type === "close" && err.code >= 4e3 && err.code <= 4100 ? increaseBackoffDelayAggressively : increaseBackoffDelay,
1127
- // Produce a useful log message
1128
- (ctx) => {
1129
- if (err instanceof Error) {
1130
- warn(String(err));
1131
- } else {
1132
- warn(
1133
- err.type === "close" ? `Connection to Liveblocks websocket server closed prematurely (code: ${err.code}). Retrying in ${ctx.backoffDelay}ms.` : "Connection to Liveblocks websocket server could not be established."
1134
- );
1135
- }
1136
- }
1137
- ]
1167
+ effect: [increaseBackoffDelay, logPrematureErrorOrCloseEvent(err)]
1138
1168
  };
1139
1169
  }
1140
1170
  );
@@ -1185,37 +1215,31 @@ function createConnectionStateMachine(delegates, enableDebugLogging) {
1185
1215
  if (e.event.code === 4999) {
1186
1216
  return {
1187
1217
  target: "@idle.failed",
1188
- effect: log(
1189
- 1 /* WARN */,
1190
- "Connection to WebSocket closed permanently. Won't retry."
1191
- )
1218
+ effect: logPermanentClose
1192
1219
  };
1193
1220
  }
1194
- if (e.event.code >= 4e3 && e.event.code <= 4100) {
1221
+ if (e.event.code === 4001) {
1222
+ return {
1223
+ target: "@auth.backoff",
1224
+ effect: [increaseBackoffDelay, logCloseEvent(e.event)]
1225
+ };
1226
+ }
1227
+ if (isCustomCloseEvent(e.event)) {
1195
1228
  return {
1196
1229
  target: "@connecting.backoff",
1197
1230
  effect: [
1198
1231
  increaseBackoffDelayAggressively,
1199
- (ctx) => warn(
1200
- `Connection to Liveblocks websocket server closed (code: ${e.event.code}). Retrying in ${ctx.backoffDelay}ms.`
1201
- ),
1202
- (_, { event }) => {
1203
- if (event.code >= 4e3 && event.code <= 4100) {
1204
- const err = new LiveblocksError(event.reason, event.code);
1205
- onLiveblocksError.notify(err);
1206
- }
1232
+ logCloseEvent(e.event),
1233
+ () => {
1234
+ const err = new LiveblocksError(e.event.reason, e.event.code);
1235
+ onLiveblocksError.notify(err);
1207
1236
  }
1208
1237
  ]
1209
1238
  };
1210
1239
  }
1211
1240
  return {
1212
1241
  target: "@connecting.backoff",
1213
- effect: [
1214
- increaseBackoffDelay,
1215
- (ctx) => warn(
1216
- `Connection to Liveblocks websocket server closed (code: ${e.event.code}). Retrying in ${ctx.backoffDelay}ms.`
1217
- )
1218
- ]
1242
+ effect: [increaseBackoffDelay, logCloseEvent(e.event)]
1219
1243
  };
1220
1244
  }
1221
1245
  });
@@ -4316,10 +4340,10 @@ function createRoom(options, config) {
4316
4340
  )
4317
4341
  };
4318
4342
  context.idFactory = makeIdFactory(sessionInfo.id);
4319
- if (context.root) {
4320
- context.buffer.messages.push({ type: 200 /* FETCH_STORAGE */ });
4343
+ if (_getStorage$ !== null) {
4344
+ refreshStorage({ flush: false });
4321
4345
  }
4322
- tryFlushing();
4346
+ flushNowOrSoon();
4323
4347
  }
4324
4348
  function onDidDisconnect() {
4325
4349
  clearTimeout(context.buffer.flushTimerID);
@@ -4447,7 +4471,7 @@ function createRoom(options, config) {
4447
4471
  if (message.items.length === 0) {
4448
4472
  throw new Error("Internal error: cannot load storage without items");
4449
4473
  }
4450
- if (context.root) {
4474
+ if (context.root !== void 0) {
4451
4475
  updateRoot(message.items, batchedUpdatesWrapper);
4452
4476
  } else {
4453
4477
  context.root = LiveObject._fromItems(message.items, pool);
@@ -4459,7 +4483,7 @@ function createRoom(options, config) {
4459
4483
  }
4460
4484
  }
4461
4485
  function updateRoot(items, batchedUpdatesWrapper) {
4462
- if (!context.root) {
4486
+ if (context.root === void 0) {
4463
4487
  return;
4464
4488
  }
4465
4489
  const currentItems = /* @__PURE__ */ new Map();
@@ -4657,7 +4681,7 @@ function createRoom(options, config) {
4657
4681
  }
4658
4682
  context.activeBatch.updates.presence = true;
4659
4683
  } else {
4660
- tryFlushing();
4684
+ flushNowOrSoon();
4661
4685
  batchUpdates(() => {
4662
4686
  if (options2 == null ? void 0 : options2.addToHistory) {
4663
4687
  addToUndoStack(
@@ -4744,7 +4768,7 @@ function createRoom(options, config) {
4744
4768
  data: context.me.current,
4745
4769
  targetActor: message.actor
4746
4770
  });
4747
- tryFlushing();
4771
+ flushNowOrSoon();
4748
4772
  const user = context.others.getUser(message.actor);
4749
4773
  return user ? { type: "enter", user } : void 0;
4750
4774
  }
@@ -4830,9 +4854,7 @@ function createRoom(options, config) {
4830
4854
  const unacknowledgedOps = new Map(context.unacknowledgedOps);
4831
4855
  createOrUpdateRootFromMessage(message, doNotBatchUpdates);
4832
4856
  applyAndSendOps(unacknowledgedOps, doNotBatchUpdates);
4833
- if (_resolveInitialStatePromise !== null) {
4834
- _resolveInitialStatePromise();
4835
- }
4857
+ _resolveStoragePromise == null ? void 0 : _resolveStoragePromise();
4836
4858
  notifyStorageStatus();
4837
4859
  eventHub.storageDidLoad.notify();
4838
4860
  break;
@@ -4879,7 +4901,7 @@ ${Array.from(traces).join("\n\n")}`
4879
4901
  notify(updates, doNotBatchUpdates);
4880
4902
  });
4881
4903
  }
4882
- function tryFlushing() {
4904
+ function flushNowOrSoon() {
4883
4905
  const storageOps = context.buffer.storageOperations;
4884
4906
  if (storageOps.length > 0) {
4885
4907
  for (const op of storageOps) {
@@ -4909,7 +4931,7 @@ ${Array.from(traces).join("\n\n")}`
4909
4931
  } else {
4910
4932
  clearTimeout(context.buffer.flushTimerID);
4911
4933
  context.buffer.flushTimerID = setTimeout(
4912
- tryFlushing,
4934
+ flushNowOrSoon,
4913
4935
  config.throttleDelay - elapsedMillis
4914
4936
  );
4915
4937
  }
@@ -4952,24 +4974,32 @@ ${Array.from(traces).join("\n\n")}`
4952
4974
  type: 103 /* BROADCAST_EVENT */,
4953
4975
  event
4954
4976
  });
4955
- tryFlushing();
4977
+ flushNowOrSoon();
4956
4978
  }
4957
4979
  function dispatchOps(ops) {
4958
4980
  context.buffer.storageOperations.push(...ops);
4959
- tryFlushing();
4981
+ flushNowOrSoon();
4982
+ }
4983
+ let _getStorage$ = null;
4984
+ let _resolveStoragePromise = null;
4985
+ function refreshStorage(options2) {
4986
+ const messages = context.buffer.messages;
4987
+ if (!messages.some((msg) => msg.type === 200 /* FETCH_STORAGE */)) {
4988
+ messages.push({ type: 200 /* FETCH_STORAGE */ });
4989
+ }
4990
+ if (options2.flush) {
4991
+ flushNowOrSoon();
4992
+ }
4960
4993
  }
4961
- let _getInitialStatePromise = null;
4962
- let _resolveInitialStatePromise = null;
4963
4994
  function startLoadingStorage() {
4964
- if (_getInitialStatePromise === null) {
4965
- context.buffer.messages.push({ type: 200 /* FETCH_STORAGE */ });
4966
- tryFlushing();
4967
- _getInitialStatePromise = new Promise(
4968
- (resolve) => _resolveInitialStatePromise = resolve
4969
- );
4995
+ if (_getStorage$ === null) {
4996
+ refreshStorage({ flush: true });
4997
+ _getStorage$ = new Promise((resolve) => {
4998
+ _resolveStoragePromise = resolve;
4999
+ });
4970
5000
  notifyStorageStatus();
4971
5001
  }
4972
- return _getInitialStatePromise;
5002
+ return _getStorage$;
4973
5003
  }
4974
5004
  function getStorageSnapshot() {
4975
5005
  const root = context.root;
@@ -4982,7 +5012,7 @@ ${Array.from(traces).join("\n\n")}`
4982
5012
  }
4983
5013
  function getStorage() {
4984
5014
  return __async(this, null, function* () {
4985
- if (context.root) {
5015
+ if (context.root !== void 0) {
4986
5016
  return Promise.resolve({
4987
5017
  root: context.root
4988
5018
  });
@@ -5013,7 +5043,7 @@ ${Array.from(traces).join("\n\n")}`
5013
5043
  context.buffer.storageOperations.push(op);
5014
5044
  }
5015
5045
  }
5016
- tryFlushing();
5046
+ flushNowOrSoon();
5017
5047
  }
5018
5048
  function redo() {
5019
5049
  if (context.activeBatch) {
@@ -5035,7 +5065,7 @@ ${Array.from(traces).join("\n\n")}`
5035
5065
  context.buffer.storageOperations.push(op);
5036
5066
  }
5037
5067
  }
5038
- tryFlushing();
5068
+ flushNowOrSoon();
5039
5069
  }
5040
5070
  function batch(callback) {
5041
5071
  if (context.activeBatch) {
@@ -5067,7 +5097,7 @@ ${Array.from(traces).join("\n\n")}`
5067
5097
  dispatchOps(currentBatch.ops);
5068
5098
  }
5069
5099
  notify(currentBatch.updates, doNotBatchUpdates);
5070
- tryFlushing();
5100
+ flushNowOrSoon();
5071
5101
  }
5072
5102
  });
5073
5103
  return returnValue;
@@ -5083,13 +5113,11 @@ ${Array.from(traces).join("\n\n")}`
5083
5113
  }
5084
5114
  }
5085
5115
  function getStorageStatus() {
5086
- if (_getInitialStatePromise === null) {
5087
- return "not-loaded";
5088
- }
5089
5116
  if (context.root === void 0) {
5090
- return "loading";
5117
+ return _getStorage$ === null ? "not-loaded" : "loading";
5118
+ } else {
5119
+ return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
5091
5120
  }
5092
- return context.unacknowledgedOps.size === 0 ? "synchronized" : "synchronizing";
5093
5121
  }
5094
5122
  let _lastStorageStatus = getStorageStatus();
5095
5123
  function notifyStorageStatus() {
@@ -5277,7 +5305,7 @@ function makeCreateSocketDelegateForRoom(liveblocksServer, WebSocketPolyfill) {
5277
5305
  // @ts-ignore (__PACKAGE_VERSION__ will be injected by the build script)
5278
5306
  true ? (
5279
5307
  /* istanbul ignore next */
5280
- "1.1.0-beta1"
5308
+ "1.1.0-beta3"
5281
5309
  ) : "dev"}`
5282
5310
  );
5283
5311
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liveblocks/core",
3
- "version": "1.1.0-beta1",
3
+ "version": "1.1.0-beta3",
4
4
  "description": "Shared code and foundational internals for Liveblocks",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",