@liveblocks/core 1.1.6-test2 → 1.1.7

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.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/version.ts
2
2
  var PKG_NAME = "@liveblocks/core";
3
- var PKG_VERSION = "1.1.6-test2";
3
+ var PKG_VERSION = "1.1.7";
4
4
  var PKG_FORMAT = "esm";
5
5
 
6
6
  // src/dupe-detection.ts
@@ -20,6 +20,7 @@ function detectDupes(pkgName, pkgVersion, pkgFormat) {
20
20
  const pkgBuildInfo = pkgFormat ? `${pkgVersion || "dev"} (${pkgFormat})` : pkgVersion || "dev";
21
21
  if (!g[pkgId]) {
22
22
  g[pkgId] = pkgBuildInfo;
23
+ } else if (g[pkgId] === pkgBuildInfo) {
23
24
  } else {
24
25
  const msg = [
25
26
  `Multiple copies of Liveblocks are being loaded in your project. This will cause issues! See ${dupesDocs + SPACE}`,
@@ -194,7 +195,7 @@ function startSyncStream(room) {
194
195
  // Any time storage updates, send the new storage root
195
196
  room.events.storage.subscribe(() => partialSyncStorage(room)),
196
197
  // Any time "me" or "others" updates, send the new values accordingly
197
- room.events.me.subscribe(() => partialSyncMe(room)),
198
+ room.events.self.subscribe(() => partialSyncMe(room)),
198
199
  room.events.others.subscribe(() => partialSyncOthers(room))
199
200
  ]);
200
201
  }
@@ -1779,7 +1780,6 @@ var LiveList = class _LiveList extends AbstractCrdt {
1779
1780
  this._items = [];
1780
1781
  this._implicitlyDeletedItems = /* @__PURE__ */ new WeakSet();
1781
1782
  this._unacknowledgedSets = /* @__PURE__ */ new Map();
1782
- this._unacknowledgedDeletedIds = /* @__PURE__ */ new Set();
1783
1783
  let position = void 0;
1784
1784
  for (const item of items) {
1785
1785
  const newPosition = makePosition(position);
@@ -1917,7 +1917,6 @@ var LiveList = class _LiveList extends AbstractCrdt {
1917
1917
  if (this._pool === void 0) {
1918
1918
  throw new Error("Can't attach child if managed pool is not present");
1919
1919
  }
1920
- this._unacknowledgedDeletedIds.delete(nn(op.deletedId));
1921
1920
  const delta = [];
1922
1921
  const deletedDelta = this._detachItemAssociatedToSetOperation(op.deletedId);
1923
1922
  if (deletedDelta) {
@@ -2028,11 +2027,6 @@ var LiveList = class _LiveList extends AbstractCrdt {
2028
2027
  }
2029
2028
  /** @internal */
2030
2029
  _applyInsertAck(op) {
2031
- if (this._unacknowledgedDeletedIds.has(op.id)) {
2032
- return {
2033
- modified: false
2034
- };
2035
- }
2036
2030
  const existingItem = this._items.find((item) => item._id === op.id);
2037
2031
  const key = asPos(op.parentKey);
2038
2032
  const itemIndexAtPosition = this._indexOfPosition(key);
@@ -2375,7 +2369,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
2375
2369
  this._pool?.assertStorageIsWritable();
2376
2370
  if (index < 0 || index > this._items.length) {
2377
2371
  throw new Error(
2378
- `Cannot insert list item at index "${index}". index should be between 0 and ${this._items.length}`
2372
+ `Cannot insert list item at index "${index}". index should be between 0 and ${this._items.length}`
2379
2373
  );
2380
2374
  }
2381
2375
  const before2 = this._items[index - 1] ? this._items[index - 1]._parentPos : void 0;
@@ -2463,7 +2457,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
2463
2457
  this._pool?.assertStorageIsWritable();
2464
2458
  if (index < 0 || index >= this._items.length) {
2465
2459
  throw new Error(
2466
- `Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
2460
+ `Cannot delete list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
2467
2461
  );
2468
2462
  }
2469
2463
  const item = this._items[index];
@@ -2471,8 +2465,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
2471
2465
  this._items.splice(index, 1);
2472
2466
  this.invalidate();
2473
2467
  if (this._pool) {
2474
- const childId = item._id;
2475
- if (childId) {
2468
+ const childRecordId = item._id;
2469
+ if (childRecordId) {
2476
2470
  const storageUpdates = /* @__PURE__ */ new Map();
2477
2471
  storageUpdates.set(
2478
2472
  nn(this._id),
@@ -2481,7 +2475,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
2481
2475
  this._pool.dispatch(
2482
2476
  [
2483
2477
  {
2484
- id: childId,
2478
+ id: childRecordId,
2485
2479
  opId: this._pool.generateOpId(),
2486
2480
  type: 5 /* DELETE_CRDT */
2487
2481
  }
@@ -2530,16 +2524,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
2530
2524
  this._pool?.assertStorageIsWritable();
2531
2525
  if (index < 0 || index >= this._items.length) {
2532
2526
  throw new Error(
2533
- `Cannot set list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
2527
+ `Cannot set list item at index "${index}". index should be between 0 and ${this._items.length - 1}`
2534
2528
  );
2535
2529
  }
2536
2530
  const existingItem = this._items[index];
2537
2531
  const position = existingItem._getParentKeyOrThrow();
2538
2532
  const existingId = existingItem._id;
2539
2533
  existingItem._detach();
2540
- if (existingId !== void 0) {
2541
- this._unacknowledgedDeletedIds.add(existingId);
2542
- }
2543
2534
  const value = lsonToLiveNode(item);
2544
2535
  value._setParentLink(this, position);
2545
2536
  this._items[index] = value;
@@ -3902,16 +3893,11 @@ function isJsonObject(data) {
3902
3893
  }
3903
3894
 
3904
3895
  // src/protocol/AuthToken.ts
3905
- function isTokenExpired(token) {
3906
- const now = Date.now() / 1e3;
3907
- const valid = now <= token.exp - 300 && now >= token.iat - 300;
3908
- return !valid;
3909
- }
3910
3896
  function isStringList(value) {
3911
3897
  return Array.isArray(value) && value.every((i) => typeof i === "string");
3912
3898
  }
3913
3899
  function isMinimalTokenPayload(data) {
3914
- return isPlainObject(data) && typeof data.iat === "number" && typeof data.exp === "number" && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string") && isStringList(data.scopes);
3900
+ return isPlainObject(data) && typeof data.actor === "number" && (data.id === void 0 || typeof data.id === "string") && isStringList(data.scopes);
3915
3901
  }
3916
3902
  function parseAuthToken(rawTokenString) {
3917
3903
  const tokenParts = rawTokenString.split(".");
@@ -4252,6 +4238,7 @@ function createRoom(options, config) {
4252
4238
  batchUpdates(() => {
4253
4239
  eventHub.status.notify(newStatus);
4254
4240
  eventHub.connection.notify(newToLegacyStatus(newStatus));
4241
+ notifySelfChanged(doNotBatchUpdates);
4255
4242
  });
4256
4243
  }
4257
4244
  let _connectionLossTimerId;
@@ -4375,7 +4362,8 @@ function createRoom(options, config) {
4375
4362
  // New/recommended API
4376
4363
  lostConnection: makeEventSource(),
4377
4364
  customEvent: makeEventSource(),
4378
- me: makeEventSource(),
4365
+ self: makeEventSource(),
4366
+ myPresence: makeEventSource(),
4379
4367
  others: makeEventSource(),
4380
4368
  error: makeEventSource(),
4381
4369
  storage: makeEventSource(),
@@ -4389,15 +4377,16 @@ function createRoom(options, config) {
4389
4377
  if (config.unstable_fallbackToHTTP) {
4390
4378
  const size = new TextEncoder().encode(message).length;
4391
4379
  if (size > MAX_MESSAGE_SIZE && managedSocket.token?.raw && config.httpSendEndpoint) {
4392
- if (isTokenExpired(managedSocket.token.parsed)) {
4393
- return managedSocket.reconnect();
4394
- }
4395
4380
  void httpSend(
4396
4381
  message,
4397
4382
  managedSocket.token.raw,
4398
4383
  config.httpSendEndpoint,
4399
4384
  config.polyfills?.fetch
4400
- );
4385
+ ).then((resp) => {
4386
+ if (!resp.ok && resp.status === 403) {
4387
+ managedSocket.reconnect();
4388
+ }
4389
+ });
4401
4390
  warn(
4402
4391
  "Message was too large for websockets and sent over HTTP instead"
4403
4392
  );
@@ -4419,6 +4408,16 @@ function createRoom(options, config) {
4419
4408
  } : null;
4420
4409
  }
4421
4410
  );
4411
+ let _lastSelf;
4412
+ function notifySelfChanged(batchedUpdatesWrapper) {
4413
+ const currSelf = self.current;
4414
+ if (currSelf !== null && currSelf !== _lastSelf) {
4415
+ batchedUpdatesWrapper(() => {
4416
+ eventHub.self.notify(currSelf);
4417
+ });
4418
+ _lastSelf = currSelf;
4419
+ }
4420
+ }
4422
4421
  const selfAsTreeNode = new DerivedRef(
4423
4422
  self,
4424
4423
  (me) => me !== null ? userToTreeNode("Me", me) : null
@@ -4477,12 +4476,14 @@ function createRoom(options, config) {
4477
4476
  }
4478
4477
  }
4479
4478
  if (presence) {
4480
- eventHub.me.notify(context.me.current);
4479
+ notifySelfChanged(doNotBatchUpdates);
4480
+ eventHub.myPresence.notify(context.me.current);
4481
4481
  }
4482
4482
  if (storageUpdates.size > 0) {
4483
4483
  const updates = Array.from(storageUpdates.values());
4484
4484
  eventHub.storage.notify(updates);
4485
4485
  }
4486
+ notifyStorageStatus();
4486
4487
  });
4487
4488
  }
4488
4489
  function getConnectionId() {
@@ -4558,7 +4559,6 @@ function createRoom(options, config) {
4558
4559
  }
4559
4560
  }
4560
4561
  }
4561
- notifyStorageStatus();
4562
4562
  return {
4563
4563
  ops,
4564
4564
  reverse: output.reverse,
@@ -4802,7 +4802,7 @@ function createRoom(options, config) {
4802
4802
  break;
4803
4803
  }
4804
4804
  case 300 /* UPDATE_YDOC */: {
4805
- eventHub.ydoc.notify(message.update);
4805
+ eventHub.ydoc.notify(message);
4806
4806
  break;
4807
4807
  }
4808
4808
  case 104 /* ROOM_STATE */: {
@@ -5110,7 +5110,8 @@ ${Array.from(traces).join("\n\n")}`
5110
5110
  lostConnection: eventHub.lostConnection.observable,
5111
5111
  customEvent: eventHub.customEvent.observable,
5112
5112
  others: eventHub.others.observable,
5113
- me: eventHub.me.observable,
5113
+ self: eventHub.self.observable,
5114
+ myPresence: eventHub.myPresence.observable,
5114
5115
  error: eventHub.error.observable,
5115
5116
  storage: eventHub.storage.observable,
5116
5117
  history: eventHub.history.observable,
@@ -5216,7 +5217,7 @@ function makeClassicSubscribeFn(events) {
5216
5217
  callback
5217
5218
  );
5218
5219
  case "my-presence":
5219
- return events.me.subscribe(callback);
5220
+ return events.myPresence.subscribe(callback);
5220
5221
  case "others": {
5221
5222
  const cb = callback;
5222
5223
  return events.others.subscribe(
@@ -5324,12 +5325,25 @@ function makeAuthDelegateForRoom(roomId, authentication, fetchPolyfill) {
5324
5325
  } else if (authentication.type === "custom") {
5325
5326
  return async () => {
5326
5327
  const response = await authentication.callback(roomId);
5327
- if (!response || !response.token) {
5328
+ if (!response || typeof response !== "object") {
5329
+ throw new Error(
5330
+ 'We expect the authentication callback to return a token, but it does not. Hint: the return value should look like: { token: "..." }'
5331
+ );
5332
+ }
5333
+ if (typeof response.token === "string") {
5334
+ return parseAuthToken(response.token);
5335
+ } else if (typeof response.error === "string") {
5336
+ const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
5337
+ if (response.error === "forbidden") {
5338
+ throw new StopRetrying(reason);
5339
+ } else {
5340
+ throw new Error(reason);
5341
+ }
5342
+ } else {
5328
5343
  throw new Error(
5329
5344
  'We expect the authentication callback to return a token, but it does not. Hint: the return value should look like: { token: "..." }'
5330
5345
  );
5331
5346
  }
5332
- return parseAuthToken(response.token);
5333
5347
  };
5334
5348
  } else {
5335
5349
  throw new Error("Internal error. Unexpected authentication type");