@liveblocks/server 1.5.0 → 1.6.0

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.cjs CHANGED
@@ -812,11 +812,11 @@ function makeInMemorySnapshot(values) {
812
812
 
813
813
  // src/MetadataDB.ts
814
814
  function makeMetadataDB(driver) {
815
- async function get(a1, a2) {
815
+ function get(a1, a2) {
816
816
  if (a2 === void 0) {
817
- return await driver.get_meta(a1);
817
+ return driver.get_meta(a1);
818
818
  } else {
819
- return a1.value(await driver.get_meta(a2));
819
+ return a1.value(driver.get_meta(a2));
820
820
  }
821
821
  }
822
822
  return {
@@ -1039,6 +1039,7 @@ var InMemoryDriver = class {
1039
1039
  constructor(options) {
1040
1040
  __publicField(this, "_nextActor");
1041
1041
  __publicField(this, "_nodes");
1042
+ __publicField(this, "_nodesApi");
1042
1043
  __publicField(this, "_metadb");
1043
1044
  __publicField(this, "_ydb");
1044
1045
  __publicField(this, "_leasedSessions");
@@ -1058,32 +1059,36 @@ var InMemoryDriver = class {
1058
1059
  raw_iter_nodes() {
1059
1060
  return this._nodes[Symbol.iterator]();
1060
1061
  }
1062
+ reinitialize() {
1063
+ this._nodesApi = void 0;
1064
+ }
1061
1065
  /** Deletes all nodes and replaces them with the given document. */
1062
1066
  DANGEROUSLY_reset_nodes(doc) {
1067
+ this.reinitialize();
1063
1068
  this._nodes.clear();
1064
1069
  for (const [id, node] of plainLsonToNodeStream(doc)) {
1065
1070
  this._nodes.set(id, node);
1066
1071
  }
1067
1072
  }
1068
- async get_meta(key) {
1073
+ get_meta(key) {
1069
1074
  return this._metadb.get(key);
1070
1075
  }
1071
- async put_meta(key, value) {
1076
+ put_meta(key, value) {
1072
1077
  this._metadb.set(key, value);
1073
1078
  }
1074
- async delete_meta(key) {
1079
+ delete_meta(key) {
1075
1080
  this._metadb.delete(key);
1076
1081
  }
1077
- async list_leased_sessions() {
1082
+ list_leased_sessions() {
1078
1083
  return this._leasedSessions.entries();
1079
1084
  }
1080
- async get_leased_session(sessionId) {
1085
+ get_leased_session(sessionId) {
1081
1086
  return this._leasedSessions.get(sessionId);
1082
1087
  }
1083
- async put_leased_session(session) {
1088
+ put_leased_session(session) {
1084
1089
  this._leasedSessions.set(session.sessionId, session);
1085
1090
  }
1086
- async delete_leased_session(sessionId) {
1091
+ delete_leased_session(sessionId) {
1087
1092
  this._leasedSessions.delete(sessionId);
1088
1093
  }
1089
1094
  takeRowsWritten() {
@@ -1092,7 +1097,7 @@ var InMemoryDriver = class {
1092
1097
  // ---------------------------------------------------------------------------
1093
1098
  // Feed APIs
1094
1099
  // ---------------------------------------------------------------------------
1095
- async list_feeds(options) {
1100
+ list_feeds(options) {
1096
1101
  const limit = Math.min(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _37 => _37.limit]), () => ( 20)), 100);
1097
1102
  const since = _optionalChain([options, 'optionalAccess', _38 => _38.since]);
1098
1103
  const cursor = _optionalChain([options, 'optionalAccess', _39 => _39.cursor]);
@@ -1148,14 +1153,14 @@ var InMemoryDriver = class {
1148
1153
  }
1149
1154
  return { feeds, nextCursor };
1150
1155
  }
1151
- async get_feed(feedId) {
1156
+ get_feed(feedId) {
1152
1157
  const feed = this._feeds.get(feedId);
1153
1158
  if (feed === void 0) {
1154
1159
  return void 0;
1155
1160
  }
1156
1161
  return feed;
1157
1162
  }
1158
- async create_feed(feed) {
1163
+ create_feed(feed) {
1159
1164
  if (this._feeds.has(feed.feedId)) {
1160
1165
  throw new Error(`Feed ${feed.feedId} already exists`);
1161
1166
  }
@@ -1166,7 +1171,7 @@ var InMemoryDriver = class {
1166
1171
  updatedAt: feed.updatedAt
1167
1172
  });
1168
1173
  }
1169
- async update_feed_metadata(feedId, metadata) {
1174
+ update_feed_metadata(feedId, metadata) {
1170
1175
  const existing = this._feeds.get(feedId);
1171
1176
  if (existing === void 0) {
1172
1177
  throw new Error(`Feed ${feedId} not found`);
@@ -1176,7 +1181,7 @@ var InMemoryDriver = class {
1176
1181
  metadata
1177
1182
  });
1178
1183
  }
1179
- async delete_feed(feedId) {
1184
+ delete_feed(feedId) {
1180
1185
  const messageKeys = [];
1181
1186
  for (const [key] of this._feedMessages.entries()) {
1182
1187
  if (key.startsWith(`${feedId}:`)) {
@@ -1188,7 +1193,7 @@ var InMemoryDriver = class {
1188
1193
  }
1189
1194
  this._feeds.delete(feedId);
1190
1195
  }
1191
- async list_feed_messages(feedId, options) {
1196
+ list_feed_messages(feedId, options) {
1192
1197
  const limit = Math.min(_nullishCoalesce(_optionalChain([options, 'optionalAccess', _41 => _41.limit]), () => ( 20)), 100);
1193
1198
  const since = _optionalChain([options, 'optionalAccess', _42 => _42.since]);
1194
1199
  const cursor = _optionalChain([options, 'optionalAccess', _43 => _43.cursor]);
@@ -1235,14 +1240,14 @@ var InMemoryDriver = class {
1235
1240
  }
1236
1241
  return { messages, nextCursor };
1237
1242
  }
1238
- async add_feed_message(feedId, message) {
1243
+ add_feed_message(feedId, message) {
1239
1244
  const feed = this._feeds.get(feedId);
1240
1245
  if (feed === void 0) {
1241
1246
  throw new Error(`Feed ${feedId} not found`);
1242
1247
  }
1243
1248
  this._feedMessages.set(`${feedId}:${message.id}`, message);
1244
1249
  }
1245
- async update_feed_message(feedId, messageId, data, timestamp) {
1250
+ update_feed_message(feedId, messageId, data, timestamp) {
1246
1251
  const key = `${feedId}:${messageId}`;
1247
1252
  const message = this._feedMessages.get(key);
1248
1253
  if (message === void 0) {
@@ -1260,33 +1265,85 @@ var InMemoryDriver = class {
1260
1265
  this._feedMessages.set(key, updatedMessage);
1261
1266
  return updatedMessage;
1262
1267
  }
1263
- async delete_feed_message(feedId, messageId) {
1268
+ delete_feed_message(feedId, messageId) {
1264
1269
  this._feedMessages.delete(`${feedId}:${messageId}`);
1265
1270
  }
1266
1271
  next_actor() {
1267
1272
  return ++this._nextActor;
1268
1273
  }
1269
- async iter_y_updates(docId) {
1274
+ iter_y_updates(docId) {
1270
1275
  const prefix = `${docId}@|@`;
1271
1276
  return _itertools.imap.call(void 0,
1272
1277
  _itertools.ifilter.call(void 0, this._ydb.entries(), ([k]) => k.startsWith(prefix)),
1273
1278
  ([k, v]) => [k.slice(prefix.length), v]
1274
1279
  );
1275
1280
  }
1276
- async write_y_updates(docId, key, data) {
1281
+ write_y_updates(docId, key, data) {
1277
1282
  this._ydb.set(`${docId}@|@${key}`, data);
1278
1283
  }
1279
- async delete_y_updates(docId, keys) {
1284
+ delete_y_updates(docId, keys) {
1280
1285
  for (const key of keys) {
1281
1286
  this._ydb.delete(`${docId}@|@${key}`);
1282
1287
  }
1283
1288
  }
1284
1289
  /** @private Only use this in unit tests, never in production. */
1285
- async DANGEROUSLY_wipe_all_y_updates() {
1290
+ DANGEROUSLY_wipe_all_y_updates() {
1286
1291
  this._ydb.clear();
1287
1292
  }
1288
- // Intercept load_nodes_api to add caching layer
1289
- load_nodes_api() {
1293
+ // ---------------------------------------------------------------------------
1294
+ // Node APIs
1295
+ // ---------------------------------------------------------------------------
1296
+ /**
1297
+ * The lazily-built node API. Building it ensures the root node exists and
1298
+ * constructs the reverse-lookup index. Invalidated by
1299
+ * DANGEROUSLY_reset_nodes(), after which the next access rebuilds it.
1300
+ */
1301
+ get loadedApi() {
1302
+ return _nullishCoalesce(this._nodesApi, () => ( (this._nodesApi = this._loadNodesApi())));
1303
+ }
1304
+ get_node(id) {
1305
+ return this.loadedApi.get_node(id);
1306
+ }
1307
+ iter_nodes() {
1308
+ return this.loadedApi.iter_nodes();
1309
+ }
1310
+ iter_nodes_optimized() {
1311
+ return this.loadedApi.iter_nodes_optimized();
1312
+ }
1313
+ has_node(id) {
1314
+ return this.loadedApi.has_node(id);
1315
+ }
1316
+ get_child_at(parentId, parentKey) {
1317
+ return this.loadedApi.get_child_at(parentId, parentKey);
1318
+ }
1319
+ has_child_at(parentId, parentKey) {
1320
+ return this.loadedApi.has_child_at(parentId, parentKey);
1321
+ }
1322
+ get_next_sibling(parentId, pos) {
1323
+ return this.loadedApi.get_next_sibling(parentId, pos);
1324
+ }
1325
+ get_last_sibling(parentId) {
1326
+ return this.loadedApi.get_last_sibling(parentId);
1327
+ }
1328
+ set_child(id, node, allowOverwrite) {
1329
+ this.loadedApi.set_child(id, node, allowOverwrite);
1330
+ }
1331
+ move_sibling(id, newPos) {
1332
+ this.loadedApi.move_sibling(id, newPos);
1333
+ }
1334
+ delete_node(id) {
1335
+ this.loadedApi.delete_node(id);
1336
+ }
1337
+ delete_child_key(id, key) {
1338
+ this.loadedApi.delete_child_key(id, key);
1339
+ }
1340
+ set_object_data(id, data, allowOverwrite) {
1341
+ this.loadedApi.set_object_data(id, data, allowOverwrite);
1342
+ }
1343
+ get_snapshot(lowMemory) {
1344
+ return this.loadedApi.get_snapshot(lowMemory);
1345
+ }
1346
+ _loadNodesApi() {
1290
1347
  const nodes = this._nodes;
1291
1348
  if (!nodes.has("root")) {
1292
1349
  nodes.set("root", { type: _core.CrdtType.OBJECT, data: {} });
@@ -1312,7 +1369,7 @@ var InMemoryDriver = class {
1312
1369
  }
1313
1370
  return lastPos;
1314
1371
  }
1315
- async function set_child(id, node, allowOverwrite = false) {
1372
+ function set_child(id, node, allowOverwrite = false) {
1316
1373
  const parentNode = nodes.get(node.parentId);
1317
1374
  if (parentNode === void 0) {
1318
1375
  throw new Error(`No such parent ${quote(node.parentId)}`);
@@ -1335,7 +1392,7 @@ var InMemoryDriver = class {
1335
1392
  }
1336
1393
  nodes.set(id, node);
1337
1394
  }
1338
- async function move_sibling(id, newPos) {
1395
+ function move_sibling(id, newPos) {
1339
1396
  const node = nodes.get(id);
1340
1397
  if (_optionalChain([node, 'optionalAccess', _44 => _44.parentId]) === void 0) {
1341
1398
  return;
@@ -1347,7 +1404,7 @@ var InMemoryDriver = class {
1347
1404
  nodes.set(id, newNode);
1348
1405
  revNodes.set(node.parentId, newPos, id);
1349
1406
  }
1350
- async function set_object_data(id, data, allowOverwrite = false) {
1407
+ function set_object_data(id, data, allowOverwrite = false) {
1351
1408
  const node = nodes.get(id);
1352
1409
  if (_optionalChain([node, 'optionalAccess', _45 => _45.type]) !== _core.CrdtType.OBJECT) {
1353
1410
  return;
@@ -1540,45 +1597,26 @@ function nodeFromCreateChildOp(op2) {
1540
1597
  }
1541
1598
  }
1542
1599
  var Storage = class {
1543
- constructor(coreDriver) {
1600
+ constructor(driver) {
1544
1601
  // The actual underlying storage API (could be backed by in-memory store,
1545
- // SQLite, Redis, Postgres, Cloudflare Durable Object Storage, etc.)
1546
- __publicField(this, "coreDriver");
1547
- __publicField(this, "_loadedDriver");
1548
- this.coreDriver = coreDriver;
1602
+ // SQLite, Postgres, etc.)
1603
+ __publicField(this, "driver");
1604
+ this.driver = driver;
1549
1605
  }
1550
1606
  // -------------------------------------------------------------------------
1551
1607
  // Public API (for Storage)
1552
1608
  // -------------------------------------------------------------------------
1553
- get loadedDriver() {
1554
- if (this._loadedDriver === void 0) {
1555
- throw new Error("Cannot access tree before it's been loaded");
1556
- }
1557
- return this._loadedDriver;
1558
- }
1559
1609
  // REFACTOR NOTE: Eventually raw_iter_nodes has to be removed here
1560
1610
  raw_iter_nodes() {
1561
- return this.coreDriver.raw_iter_nodes();
1562
- }
1563
- /**
1564
- * Load the room data from object storage into memory. Persisted room
1565
- * data consists of the main node map, which represents the Liveblocks
1566
- * Storage tree, and special keys where we store usage metrics, or room
1567
- * metadata.
1568
- */
1569
- async load(logger) {
1570
- this._loadedDriver = await this.coreDriver.load_nodes_api(logger);
1571
- }
1572
- unload() {
1573
- this._loadedDriver = void 0;
1611
+ return this.driver.raw_iter_nodes();
1574
1612
  }
1575
1613
  /**
1576
1614
  * Applies a batch of Ops.
1577
1615
  */
1578
- async applyOps(ops) {
1616
+ applyOps(ops) {
1579
1617
  const results = [];
1580
1618
  for (const op2 of ops) {
1581
- results.push(await this.applyOp(op2));
1619
+ results.push(this.applyOp(op2));
1582
1620
  }
1583
1621
  return results;
1584
1622
  }
@@ -1588,21 +1626,21 @@ var Storage = class {
1588
1626
  /**
1589
1627
  * Applies a single Op.
1590
1628
  */
1591
- async applyOp(op2) {
1629
+ applyOp(op2) {
1592
1630
  switch (op2.type) {
1593
1631
  case _core.OpCode.CREATE_LIST:
1594
1632
  case _core.OpCode.CREATE_MAP:
1595
1633
  case _core.OpCode.CREATE_REGISTER:
1596
1634
  case _core.OpCode.CREATE_OBJECT:
1597
- return await this.applyCreateOp(op2);
1635
+ return this.applyCreateOp(op2);
1598
1636
  case _core.OpCode.UPDATE_OBJECT:
1599
- return await this.applyUpdateObjectOp(op2);
1637
+ return this.applyUpdateObjectOp(op2);
1600
1638
  case _core.OpCode.SET_PARENT_KEY:
1601
- return await this.applySetParentKeyOp(op2);
1639
+ return this.applySetParentKeyOp(op2);
1602
1640
  case _core.OpCode.DELETE_OBJECT_KEY:
1603
- return await this.applyDeleteObjectKeyOp(op2);
1641
+ return this.applyDeleteObjectKeyOp(op2);
1604
1642
  case _core.OpCode.DELETE_CRDT:
1605
- return await this.applyDeleteCrdtOp(op2);
1643
+ return this.applyDeleteCrdtOp(op2);
1606
1644
  // istanbul ignore next
1607
1645
  default:
1608
1646
  if (process.env.NODE_ENV === "production") {
@@ -1612,12 +1650,12 @@ var Storage = class {
1612
1650
  }
1613
1651
  }
1614
1652
  }
1615
- async applyCreateOp(op2) {
1616
- if (this.loadedDriver.has_node(op2.id)) {
1653
+ applyCreateOp(op2) {
1654
+ if (this.driver.has_node(op2.id)) {
1617
1655
  return ignore(op2);
1618
1656
  }
1619
1657
  const node = nodeFromCreateChildOp(op2);
1620
- const parent = this.loadedDriver.get_node(node.parentId);
1658
+ const parent = this.driver.get_node(node.parentId);
1621
1659
  if (parent === void 0) {
1622
1660
  return ignore(op2);
1623
1661
  }
@@ -1628,7 +1666,7 @@ var Storage = class {
1628
1666
  }
1629
1667
  // fall through
1630
1668
  case _core.CrdtType.MAP:
1631
- await this.loadedDriver.set_child(op2.id, node, true);
1669
+ this.driver.set_child(op2.id, node, true);
1632
1670
  return accept(op2);
1633
1671
  case _core.CrdtType.LIST:
1634
1672
  return this.createChildAsListItem(op2, node);
@@ -1639,23 +1677,19 @@ var Storage = class {
1639
1677
  return _core.assertNever.call(void 0, parent, "Unhandled CRDT type");
1640
1678
  }
1641
1679
  }
1642
- async createChildAsListItem(op2, node) {
1680
+ createChildAsListItem(op2, node) {
1643
1681
  const intent2 = _nullishCoalesce(op2.intent, () => ( "insert"));
1644
1682
  if (intent2 === "insert") {
1645
- return this.acceptAndFix(
1646
- op2,
1647
- node,
1648
- await this.insertIntoList(op2.id, node)
1649
- );
1683
+ return this.acceptAndFix(op2, node, this.insertIntoList(op2.id, node));
1650
1684
  } else if (intent2 === "push") {
1651
- return this.acceptAndFix(op2, node, await this.appendToList(op2.id, node));
1685
+ return this.acceptAndFix(op2, node, this.appendToList(op2.id, node));
1652
1686
  } else if (intent2 === "set") {
1653
1687
  let fix;
1654
- const deletedId = op2.deletedId !== void 0 && op2.deletedId !== op2.id && _optionalChain([this, 'access', _47 => _47.loadedDriver, 'access', _48 => _48.get_node, 'call', _49 => _49(op2.deletedId), 'optionalAccess', _50 => _50.parentId]) === node.parentId ? op2.deletedId : void 0;
1688
+ const deletedId = op2.deletedId !== void 0 && op2.deletedId !== op2.id && _optionalChain([this, 'access', _47 => _47.driver, 'access', _48 => _48.get_node, 'call', _49 => _49(op2.deletedId), 'optionalAccess', _50 => _50.parentId]) === node.parentId ? op2.deletedId : void 0;
1655
1689
  if (deletedId !== void 0) {
1656
- await this.loadedDriver.delete_node(deletedId);
1690
+ this.driver.delete_node(deletedId);
1657
1691
  }
1658
- const prevItemId = this.loadedDriver.get_child_at(
1692
+ const prevItemId = this.driver.get_child_at(
1659
1693
  node.parentId,
1660
1694
  node.parentKey
1661
1695
  );
@@ -1665,7 +1699,7 @@ var Storage = class {
1665
1699
  id: prevItemId
1666
1700
  };
1667
1701
  }
1668
- await this.loadedDriver.set_child(op2.id, node, true);
1702
+ this.driver.set_child(op2.id, node, true);
1669
1703
  return accept(op2, fix);
1670
1704
  } else {
1671
1705
  return _core.assertNever.call(void 0, intent2, "Invalid intent");
@@ -1685,20 +1719,20 @@ var Storage = class {
1685
1719
  }
1686
1720
  return accept(op2);
1687
1721
  }
1688
- async applyDeleteObjectKeyOp(op2) {
1689
- await this.loadedDriver.delete_child_key(op2.id, op2.key);
1722
+ applyDeleteObjectKeyOp(op2) {
1723
+ this.driver.delete_child_key(op2.id, op2.key);
1690
1724
  return accept(op2);
1691
1725
  }
1692
- async applyUpdateObjectOp(op2) {
1693
- await this.loadedDriver.set_object_data(op2.id, op2.data, true);
1726
+ applyUpdateObjectOp(op2) {
1727
+ this.driver.set_object_data(op2.id, op2.data, true);
1694
1728
  return accept(op2);
1695
1729
  }
1696
- async applyDeleteCrdtOp(op2) {
1697
- await this.loadedDriver.delete_node(op2.id);
1730
+ applyDeleteCrdtOp(op2) {
1731
+ this.driver.delete_node(op2.id);
1698
1732
  return accept(op2);
1699
1733
  }
1700
- async applySetParentKeyOp(op2) {
1701
- const newPosition = await this.moveToPosInList(op2.id, op2.parentKey);
1734
+ applySetParentKeyOp(op2) {
1735
+ const newPosition = this.moveToPosInList(op2.id, op2.parentKey);
1702
1736
  if (newPosition === void 0) {
1703
1737
  return ignore(op2);
1704
1738
  }
@@ -1722,12 +1756,12 @@ var Storage = class {
1722
1756
  *
1723
1757
  * Returns the key that was used for the insertion.
1724
1758
  */
1725
- async insertIntoList(id, node) {
1759
+ insertIntoList(id, node) {
1726
1760
  const key = this.findFreeListPosition(node.parentId, _core.asPos.call(void 0, node.parentKey));
1727
1761
  if (key !== node.parentKey) {
1728
1762
  node = { ...node, parentKey: key };
1729
1763
  }
1730
- await this.loadedDriver.set_child(id, node);
1764
+ this.driver.set_child(id, node);
1731
1765
  return node.parentKey;
1732
1766
  }
1733
1767
  /**
@@ -1740,11 +1774,11 @@ var Storage = class {
1740
1774
  *
1741
1775
  * Returns the final key that was used for the insertion.
1742
1776
  */
1743
- async appendToList(id, node) {
1744
- const lastPos = this.loadedDriver.get_last_sibling(node.parentId);
1777
+ appendToList(id, node) {
1778
+ const lastPos = this.driver.get_last_sibling(node.parentId);
1745
1779
  const preferredPos = _core.asPos.call(void 0, node.parentKey);
1746
1780
  const finalKey = lastPos === void 0 || preferredPos > lastPos ? preferredPos : _core.makePosition.call(void 0, lastPos);
1747
- await this.loadedDriver.set_child(
1781
+ this.driver.set_child(
1748
1782
  id,
1749
1783
  finalKey !== node.parentKey ? { ...node, parentKey: finalKey } : node
1750
1784
  );
@@ -1762,12 +1796,12 @@ var Storage = class {
1762
1796
  * Will return `undefined` if this action could not be interpreted. Will be
1763
1797
  * a no-op for non-list items.
1764
1798
  */
1765
- async moveToPosInList(id, targetKey) {
1766
- const node = this.loadedDriver.get_node(id);
1799
+ moveToPosInList(id, targetKey) {
1800
+ const node = this.driver.get_node(id);
1767
1801
  if (_optionalChain([node, 'optionalAccess', _51 => _51.parentId]) === void 0) {
1768
1802
  return;
1769
1803
  }
1770
- if (_optionalChain([this, 'access', _52 => _52.loadedDriver, 'access', _53 => _53.get_node, 'call', _54 => _54(node.parentId), 'optionalAccess', _55 => _55.type]) !== _core.CrdtType.LIST) {
1804
+ if (_optionalChain([this, 'access', _52 => _52.driver, 'access', _53 => _53.get_node, 'call', _54 => _54(node.parentId), 'optionalAccess', _55 => _55.type]) !== _core.CrdtType.LIST) {
1771
1805
  return;
1772
1806
  }
1773
1807
  if (node.parentKey === targetKey) {
@@ -1775,7 +1809,7 @@ var Storage = class {
1775
1809
  }
1776
1810
  const key = this.findFreeListPosition(node.parentId, _core.asPos.call(void 0, targetKey));
1777
1811
  if (key !== node.parentKey) {
1778
- await this.loadedDriver.move_sibling(id, key);
1812
+ this.driver.move_sibling(id, key);
1779
1813
  }
1780
1814
  return key;
1781
1815
  }
@@ -1787,11 +1821,11 @@ var Storage = class {
1787
1821
  * to use as parentKey.
1788
1822
  */
1789
1823
  findFreeListPosition(parentId, parentPos) {
1790
- if (!this.loadedDriver.has_child_at(parentId, parentPos)) {
1824
+ if (!this.driver.has_child_at(parentId, parentPos)) {
1791
1825
  return parentPos;
1792
1826
  }
1793
1827
  const currPos = parentPos;
1794
- const nextPos = this.loadedDriver.get_next_sibling(parentId, currPos);
1828
+ const nextPos = this.driver.get_next_sibling(parentId, currPos);
1795
1829
  if (nextPos !== void 0) {
1796
1830
  return _core.makePosition.call(void 0, currPos, nextPos);
1797
1831
  } else {
@@ -1801,6 +1835,7 @@ var Storage = class {
1801
1835
  };
1802
1836
 
1803
1837
  // src/YjsStorage.ts
1838
+ var _crypto = require('crypto');
1804
1839
  var _jsbase64 = require('js-base64');
1805
1840
 
1806
1841
  var _yjs = require('yjs'); var Y = _interopRequireWildcard(_yjs);
@@ -1810,30 +1845,33 @@ var YjsStorage = class {
1810
1845
  constructor(driver, updateCountThreshold = UPDATE_COUNT_THRESHOLD) {
1811
1846
  __publicField(this, "driver");
1812
1847
  __publicField(this, "updateCountThreshold");
1813
- __publicField(this, "doc", new Y.Doc());
1814
- // the root document
1848
+ /**
1849
+ * The root Y.Doc instance, which may not have been hydrated from storage
1850
+ * yet. Use getRootDoc() instead, which lazily hydrates it on first access —
1851
+ * only touch this field directly when the unhydrated instance is fine
1852
+ * (e.g. identity checks, subdoc traversal).
1853
+ */
1854
+ __publicField(this, "rawRootDoc", new Y.Doc());
1815
1855
  __publicField(this, "lastSnapshotById", /* @__PURE__ */ new Map());
1816
- __publicField(this, "initPromisesById", /* @__PURE__ */ new Map());
1856
+ __publicField(this, "docsById", /* @__PURE__ */ new Map());
1817
1857
  __publicField(this, "storedKeysById", /* @__PURE__ */ new Map());
1818
1858
  // compact the updates into a single update and write it to the durable storage
1819
- __publicField(this, "_compactYJSUpdates", async (doc, docId, storedKeys) => {
1859
+ __publicField(this, "_compactYJSUpdates", (doc, docId, storedKeys) => {
1820
1860
  const compactedUpdate = Y.encodeStateAsUpdate(doc);
1821
1861
  const newKey = _nanoid.nanoid.call(void 0, );
1822
- await this.driver.write_y_updates(docId, newKey, compactedUpdate);
1823
- await this.driver.delete_y_updates(docId, storedKeys);
1862
+ this.driver.write_y_updates(docId, newKey, compactedUpdate);
1863
+ this.driver.delete_y_updates(docId, storedKeys);
1824
1864
  this.storedKeysById.set(docId, [newKey]);
1825
1865
  });
1826
- __publicField(this, "_loadYDocFromDurableStorage", async (_logger, doc, docId) => {
1827
- const docUpdates = Object.fromEntries(
1828
- await this.driver.iter_y_updates(docId)
1829
- );
1866
+ __publicField(this, "_loadYDocFromDurableStorage", (doc, docId) => {
1867
+ const docUpdates = Object.fromEntries(this.driver.iter_y_updates(docId));
1830
1868
  const updates = Object.values(docUpdates);
1831
1869
  const beforeSize = updates.reduce((acc, update) => acc + update.length, 0);
1832
1870
  const newupdate = Y.mergeUpdates(updates);
1833
1871
  const storedKeys = Object.keys(docUpdates);
1834
1872
  Y.applyUpdate(doc, newupdate);
1835
1873
  if (this.shouldCompactByKeyCount(storedKeys) || this.shouldCompactBySize(beforeSize, newupdate.length)) {
1836
- await this._compactYJSUpdates(doc, docId, storedKeys);
1874
+ this._compactYJSUpdates(doc, docId, storedKeys);
1837
1875
  } else {
1838
1876
  this.storedKeysById.set(docId, storedKeys);
1839
1877
  }
@@ -1842,7 +1880,7 @@ var YjsStorage = class {
1842
1880
  });
1843
1881
  this.driver = driver;
1844
1882
  this.updateCountThreshold = updateCountThreshold;
1845
- this.doc.on("subdocs", ({ removed }) => {
1883
+ this.rawRootDoc.on("subdocs", ({ removed }) => {
1846
1884
  removed.forEach((subdoc) => {
1847
1885
  subdoc.destroy();
1848
1886
  });
@@ -1851,9 +1889,27 @@ var YjsStorage = class {
1851
1889
  // ------------------------------------------------------------------------------------
1852
1890
  // Public API
1853
1891
  // ------------------------------------------------------------------------------------
1854
- async getYDoc(logger, docId) {
1855
- const doc = await this.loadDocByIdIfNotAlreadyLoaded(logger, docId);
1856
- return doc;
1892
+ getYDoc(logger, docId) {
1893
+ if (docId !== ROOT_YDOC_ID) {
1894
+ this.getRootDoc(logger);
1895
+ }
1896
+ let loaded = this.docsById.get(docId);
1897
+ let doc = docId === ROOT_YDOC_ID ? this.rawRootDoc : this.findYSubdocByGuid(docId);
1898
+ if (!doc) {
1899
+ doc = new Y.Doc();
1900
+ }
1901
+ if (loaded === void 0) {
1902
+ loaded = this._loadYDocFromDurableStorage(doc, docId);
1903
+ this.docsById.set(docId, loaded);
1904
+ }
1905
+ return loaded;
1906
+ }
1907
+ /**
1908
+ * Returns the root Y.Doc, lazily loading it from storage first if it
1909
+ * hasn't been loaded yet during this instance's lifetime.
1910
+ */
1911
+ getRootDoc(logger) {
1912
+ return this.getYDoc(logger, ROOT_YDOC_ID);
1857
1913
  }
1858
1914
  /**
1859
1915
  * If passed a state vector, an update with diff will be returned, if not the entire doc is returned.
@@ -1861,18 +1917,13 @@ var YjsStorage = class {
1861
1917
  * @param stateVector a base64 encoded target state vector created by running Y.encodeStateVector(Doc) on the client
1862
1918
  * @returns a base64 encoded array of YJS updates
1863
1919
  */
1864
- async getYDocUpdate(logger, stateVector = "", guid, isV2 = false) {
1865
- const update = await this.getYDocUpdateBinary(
1866
- logger,
1867
- stateVector,
1868
- guid,
1869
- isV2
1870
- );
1920
+ getYDocUpdate(logger, stateVector = "", guid, isV2 = false) {
1921
+ const update = this.getYDocUpdateBinary(logger, stateVector, guid, isV2);
1871
1922
  if (!update) return null;
1872
1923
  return _jsbase64.Base64.fromUint8Array(update);
1873
1924
  }
1874
- async getYDocUpdateBinary(logger, stateVector = "", guid, isV2 = false) {
1875
- const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
1925
+ getYDocUpdateBinary(logger, stateVector = "", guid, isV2 = false) {
1926
+ const doc = guid !== void 0 ? this.getYSubdoc(logger, guid) : this.getRootDoc(logger);
1876
1927
  if (!doc) {
1877
1928
  return null;
1878
1929
  }
@@ -1889,15 +1940,15 @@ var YjsStorage = class {
1889
1940
  }
1890
1941
  return Y.encodeStateAsUpdate(doc, encodedTargetVector);
1891
1942
  }
1892
- async getYStateVector(logger, guid) {
1893
- const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
1943
+ getYStateVector(logger, guid) {
1944
+ const doc = guid !== void 0 ? this.getYSubdoc(logger, guid) : this.getRootDoc(logger);
1894
1945
  if (!doc) {
1895
1946
  return null;
1896
1947
  }
1897
1948
  return _jsbase64.Base64.fromUint8Array(Y.encodeStateVector(doc));
1898
1949
  }
1899
- async getSnapshotHash(logger, options) {
1900
- const doc = options.guid !== void 0 ? await this.getYSubdoc(logger, options.guid) : this.doc;
1950
+ getSnapshotHash(logger, options) {
1951
+ const doc = options.guid !== void 0 ? this.getYSubdoc(logger, options.guid) : this.getRootDoc(logger);
1901
1952
  if (!doc) {
1902
1953
  return null;
1903
1954
  }
@@ -1910,8 +1961,8 @@ var YjsStorage = class {
1910
1961
  * isUpdated: true if the update had an effect on the YDoc
1911
1962
  * snapshotHash: the hash of the new snapshot
1912
1963
  */
1913
- async addYDocUpdate(logger, update, guid, isV2) {
1914
- const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
1964
+ addYDocUpdate(logger, update, guid, isV2) {
1965
+ const doc = guid !== void 0 ? this.getYSubdoc(logger, guid) : this.getRootDoc(logger);
1915
1966
  if (!doc) {
1916
1967
  throw new Error(`YDoc with guid ${guid} not found`);
1917
1968
  }
@@ -1923,11 +1974,11 @@ var YjsStorage = class {
1923
1974
  const afterSnapshot = this._putLastSnapshot(doc);
1924
1975
  const updated = !Y.equalSnapshots(beforeSnapshot, afterSnapshot);
1925
1976
  if (updated) {
1926
- await this.handleYDocUpdate(doc, updateAsU8, isV2);
1977
+ this.handleYDocUpdate(doc, updateAsU8, isV2);
1927
1978
  }
1928
1979
  return {
1929
1980
  isUpdated: updated,
1930
- snapshotHash: await this.calculateSnapshotHash(afterSnapshot, { isV2 })
1981
+ snapshotHash: this.calculateSnapshotHash(afterSnapshot, { isV2 })
1931
1982
  };
1932
1983
  } catch (e) {
1933
1984
  logger.warn(`Ignored bad YDoc update: ${String(e)}`);
@@ -1936,32 +1987,12 @@ var YjsStorage = class {
1936
1987
  );
1937
1988
  }
1938
1989
  }
1939
- loadDocByIdIfNotAlreadyLoaded(logger, docId) {
1940
- let loaded$ = this.initPromisesById.get(docId);
1941
- let doc = docId === ROOT_YDOC_ID ? this.doc : this.findYSubdocByGuid(docId);
1942
- if (!doc) {
1943
- doc = new Y.Doc();
1944
- }
1945
- if (loaded$ === void 0) {
1946
- loaded$ = this._loadYDocFromDurableStorage(logger, doc, docId);
1947
- this.initPromisesById.set(docId, loaded$);
1948
- }
1949
- return loaded$;
1950
- }
1951
- async load(logger) {
1952
- await this.loadDocByIdIfNotAlreadyLoaded(logger, ROOT_YDOC_ID);
1953
- }
1954
- /**
1955
- * Unloads the Yjs documents from memory.
1956
- */
1957
- unload() {
1958
- }
1959
1990
  // ------------------------------------------------------------------------------------
1960
1991
  // Private APIs
1961
1992
  // ------------------------------------------------------------------------------------
1962
1993
  // NOTE: We could instead store the hash of snapshot instead of the whole snapshot to optimize memory usage.
1963
1994
  _getOrPutLastSnapshot(doc) {
1964
- const docId = doc.guid === this.doc.guid ? ROOT_YDOC_ID : doc.guid;
1995
+ const docId = doc.guid === this.rawRootDoc.guid ? ROOT_YDOC_ID : doc.guid;
1965
1996
  const snapshot2 = this.lastSnapshotById.get(docId);
1966
1997
  if (snapshot2) {
1967
1998
  return snapshot2;
@@ -1970,47 +2001,44 @@ var YjsStorage = class {
1970
2001
  }
1971
2002
  // NOTE: We could instead store the hash of snapshot instead of the whole snapshot to optimize memory usage.
1972
2003
  _putLastSnapshot(doc) {
1973
- const docId = doc.guid === this.doc.guid ? ROOT_YDOC_ID : doc.guid;
2004
+ const docId = doc.guid === this.rawRootDoc.guid ? ROOT_YDOC_ID : doc.guid;
1974
2005
  const snapshot2 = Y.snapshot(doc);
1975
2006
  this.lastSnapshotById.set(docId, snapshot2);
1976
2007
  return snapshot2;
1977
2008
  }
1978
2009
  findYSubdocByGuid(guid) {
1979
- for (const subdoc of this.doc.getSubdocs()) {
2010
+ for (const subdoc of this.rawRootDoc.getSubdocs()) {
1980
2011
  if (subdoc.guid === guid) {
1981
2012
  return subdoc;
1982
2013
  }
1983
2014
  }
1984
2015
  return null;
1985
2016
  }
1986
- async calculateSnapshotHash(snapshot2, { isV2 }) {
2017
+ calculateSnapshotHash(snapshot2, { isV2 }) {
1987
2018
  const encodedSnapshot = isV2 ? Y.encodeSnapshotV2(snapshot2) : Y.encodeSnapshot(snapshot2);
1988
- return _jsbase64.Base64.fromUint8Array(
1989
- new Uint8Array(
1990
- await crypto.subtle.digest("SHA-256", new Uint8Array(encodedSnapshot))
1991
- )
1992
- );
2019
+ return _crypto.createHash.call(void 0, "sha256").update(encodedSnapshot).digest("base64");
1993
2020
  }
1994
2021
  // gets a subdoc, it will be loaded if not already loaded
1995
- async getYSubdoc(logger, guid) {
2022
+ getYSubdoc(logger, guid) {
2023
+ this.getRootDoc(logger);
1996
2024
  const subdoc = this.findYSubdocByGuid(guid);
1997
2025
  if (!subdoc) {
1998
2026
  return null;
1999
2027
  }
2000
- await this.loadDocByIdIfNotAlreadyLoaded(logger, guid);
2028
+ this.getYDoc(logger, guid);
2001
2029
  return subdoc;
2002
2030
  }
2003
2031
  // When the YJS doc changes, update it in durable storage
2004
- async handleYDocUpdate(doc, update, isV2) {
2032
+ handleYDocUpdate(doc, update, isV2) {
2005
2033
  const v1update = isV2 ? Y.convertUpdateFormatV2ToV1(update) : update;
2006
- const docId = doc.guid === this.doc.guid ? ROOT_YDOC_ID : doc.guid;
2034
+ const docId = doc.guid === this.rawRootDoc.guid ? ROOT_YDOC_ID : doc.guid;
2007
2035
  const storedKeys = this.storedKeysById.get(docId);
2008
2036
  if (this.shouldCompactByKeyCount(storedKeys)) {
2009
- await this._compactYJSUpdates(doc, docId, storedKeys || []);
2037
+ this._compactYJSUpdates(doc, docId, storedKeys || []);
2010
2038
  return;
2011
2039
  }
2012
2040
  const newKey = _nanoid.nanoid.call(void 0, );
2013
- await this.driver.write_y_updates(docId, newKey, v1update);
2041
+ this.driver.write_y_updates(docId, newKey, v1update);
2014
2042
  if (!storedKeys) {
2015
2043
  this.storedKeysById.set(docId, [newKey]);
2016
2044
  } else {
@@ -2029,10 +2057,19 @@ var YjsStorage = class {
2029
2057
  };
2030
2058
 
2031
2059
  // src/lib/tryCatch.ts
2032
- async function tryCatch(promise) {
2060
+ function isThenable(value) {
2061
+ return value !== null && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
2062
+ }
2063
+ function tryCatch(promise) {
2033
2064
  try {
2034
- const data = await (typeof promise === "function" ? promise() : promise);
2035
- return [data, void 0];
2065
+ const result = typeof promise === "function" ? promise() : promise;
2066
+ if (isThenable(result)) {
2067
+ return Promise.resolve(result).then(
2068
+ (data) => [data, void 0],
2069
+ (error) => [void 0, error]
2070
+ );
2071
+ }
2072
+ return [result, void 0];
2036
2073
  } catch (error) {
2037
2074
  return [void 0, error];
2038
2075
  }
@@ -2258,13 +2295,13 @@ var BackendSession = class extends BrowserSession {
2258
2295
  super(ticket, socket, debug);
2259
2296
  }
2260
2297
  };
2261
- var __debug2;
2298
+ var _logger, __debug2;
2262
2299
  var Room = class {
2263
2300
  constructor(meta, options) {
2264
2301
  // ^^^^^^^^^^ User-defined Room Metadata, Session Metadata, and Client Metadata
2265
2302
  __publicField(this, "meta");
2266
2303
  __publicField(this, "driver");
2267
- __publicField(this, "logger");
2304
+ __privateAdd(this, _logger);
2268
2305
  /**
2269
2306
  * While a room is in "maintenance mode", all WebSocket connections to the
2270
2307
  * room should be rejected until it's pulled out of maintenance mode again.
@@ -2274,8 +2311,10 @@ var Room = class {
2274
2311
  * init-storage, storage-reset, etc.) cannot interfere with one another.
2275
2312
  */
2276
2313
  __publicField(this, "_maintenanceMode", new (0, _asyncmutex.Mutex)());
2277
- __publicField(this, "_loadData$", null);
2278
- __publicField(this, "_data", null);
2314
+ __publicField(this, "_storage");
2315
+ __publicField(this, "_yjsStorage");
2316
+ __publicField(this, "mutex", new (0, _asyncmutex.Mutex)());
2317
+ // prettier-ignore
2279
2318
  __publicField(this, "_qsize", 0);
2280
2319
  __publicField(this, "sessions", new UniqueMap((s) => s.actor));
2281
2320
  __publicField(this, "hooks");
@@ -2283,52 +2322,38 @@ var Room = class {
2283
2322
  const driver = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _61 => _61.storage]), () => ( makeNewInMemoryDriver()));
2284
2323
  this.meta = meta;
2285
2324
  this.driver = driver;
2286
- this.logger = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.logger]), () => ( BLACK_HOLE));
2325
+ this._storage = new Storage(this.driver);
2326
+ this._yjsStorage = new YjsStorage(this.driver);
2327
+ __privateSet(this, _logger, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.logger]), () => ( BLACK_HOLE)));
2287
2328
  this.hooks = {
2288
2329
  isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.hooks, 'optionalAccess', _64 => _64.isClientMsgAllowed]), () => ( (() => {
2289
2330
  return {
2290
2331
  allowed: true
2291
2332
  };
2292
2333
  }))),
2293
- // YYY .load() isn't called on the RoomServer yet! As soon as it does, these hooks will get called
2294
- onRoomWillLoad: _optionalChain([options, 'optionalAccess', _65 => _65.hooks, 'optionalAccess', _66 => _66.onRoomWillLoad]),
2295
- onRoomDidLoad: _optionalChain([options, 'optionalAccess', _67 => _67.hooks, 'optionalAccess', _68 => _68.onRoomDidLoad]),
2296
- onRoomWillUnload: _optionalChain([options, 'optionalAccess', _69 => _69.hooks, 'optionalAccess', _70 => _70.onRoomWillUnload]),
2297
- onRoomDidUnload: _optionalChain([options, 'optionalAccess', _71 => _71.hooks, 'optionalAccess', _72 => _72.onRoomDidUnload]),
2298
- onSessionDidStart: _optionalChain([options, 'optionalAccess', _73 => _73.hooks, 'optionalAccess', _74 => _74.onSessionDidStart]),
2299
- onSessionDidEnd: _optionalChain([options, 'optionalAccess', _75 => _75.hooks, 'optionalAccess', _76 => _76.onSessionDidEnd]),
2300
- postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _77 => _77.hooks, 'optionalAccess', _78 => _78.postClientMsgStorageDidUpdate]),
2301
- postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _79 => _79.hooks, 'optionalAccess', _80 => _80.postClientMsgYdocDidUpdate])
2334
+ onRoomWillUnload: _optionalChain([options, 'optionalAccess', _65 => _65.hooks, 'optionalAccess', _66 => _66.onRoomWillUnload]),
2335
+ onSessionDidStart: _optionalChain([options, 'optionalAccess', _67 => _67.hooks, 'optionalAccess', _68 => _68.onSessionDidStart]),
2336
+ onSessionDidEnd: _optionalChain([options, 'optionalAccess', _69 => _69.hooks, 'optionalAccess', _70 => _70.onSessionDidEnd]),
2337
+ postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _71 => _71.hooks, 'optionalAccess', _72 => _72.postClientMsgStorageDidUpdate]),
2338
+ postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _73 => _73.hooks, 'optionalAccess', _74 => _74.postClientMsgYdocDidUpdate])
2302
2339
  };
2303
- __privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.enableDebugLogging]), () => ( false)));
2304
- }
2305
- get loadingState() {
2306
- if (this._loadData$ === null) {
2307
- return "initial";
2308
- } else if (this._data === null) {
2309
- return "loading";
2310
- } else {
2311
- return "loaded";
2312
- }
2340
+ __privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _75 => _75.enableDebugLogging]), () => ( false)));
2313
2341
  }
2314
- get numSessions() {
2315
- return this.sessions.size;
2316
- }
2317
- // prettier-ignore
2318
2342
  get storage() {
2319
- return this.data.storage;
2343
+ return this._storage;
2320
2344
  }
2321
2345
  // prettier-ignore
2322
2346
  get yjsStorage() {
2323
- return this.data.yjsStorage;
2347
+ return this._yjsStorage;
2324
2348
  }
2325
- // prettier-ignore
2326
- get mutex() {
2327
- return this.data.mutex;
2349
+ get logger() {
2350
+ return __privateGet(this, _logger);
2328
2351
  }
2329
- // prettier-ignore
2330
- get data() {
2331
- return _nullishCoalesce(this._data, () => ( _core.raise.call(void 0, "Cannot use room before it's loaded")));
2352
+ addLoggerContext(attrs) {
2353
+ __privateSet(this, _logger, __privateGet(this, _logger).withContext(attrs));
2354
+ }
2355
+ get numSessions() {
2356
+ return this.sessions.size;
2332
2357
  }
2333
2358
  // prettier-ignore
2334
2359
  // ------------------------------------------------------------------------------------
@@ -2353,34 +2378,15 @@ var Room = class {
2353
2378
  // Public API
2354
2379
  // ------------------------------------------------------------------------------------
2355
2380
  /**
2356
- * Initializes the Room, so it's ready to start accepting connections. Safe
2357
- * to call multiple times. After awaiting `room.load()` the Room is ready to
2358
- * be used.
2359
- */
2360
- async load(ctx) {
2361
- if (this._loadData$ === null) {
2362
- this._data = null;
2363
- this._loadData$ = this._load(ctx).catch((e) => {
2364
- this._data = null;
2365
- this._loadData$ = null;
2366
- throw e;
2367
- });
2368
- }
2369
- return this._loadData$;
2370
- }
2371
- /**
2372
- * Releases the currently-loaded storage tree from worker memory, freeing it
2373
- * up to be garbage collected. The next time a user will join the room, the
2374
- * room will be reloaded from storage.
2381
+ * Releases the currently-loaded storage tree and Yjs documents from worker
2382
+ * memory, freeing them up to be garbage collected. The next time the room
2383
+ * is used, fresh instances will lazily be created.
2375
2384
  */
2376
2385
  unload(ctx) {
2377
- _optionalChain([this, 'access', _82 => _82.hooks, 'access', _83 => _83.onRoomWillUnload, 'optionalCall', _84 => _84(ctx)]);
2378
- if (this._data) {
2379
- this.storage.unload();
2380
- this.yjsStorage.unload();
2381
- }
2382
- this._loadData$ = null;
2383
- _optionalChain([this, 'access', _85 => _85.hooks, 'access', _86 => _86.onRoomDidUnload, 'optionalCall', _87 => _87(ctx)]);
2386
+ _optionalChain([this, 'access', _76 => _76.hooks, 'access', _77 => _77.onRoomWillUnload, 'optionalCall', _78 => _78(ctx)]);
2387
+ this.driver.reinitialize();
2388
+ this._storage = new Storage(this.driver);
2389
+ this._yjsStorage = new YjsStorage(this.driver);
2384
2390
  }
2385
2391
  /**
2386
2392
  * Issues a Ticket with a new/unique actor ID
@@ -2393,26 +2399,26 @@ var Room = class {
2393
2399
  * connection is established. If the socket is never established, this
2394
2400
  * unused Ticket will simply get garbage collected.
2395
2401
  */
2396
- async createTicket(options) {
2397
- const actor$ = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.actor]), () => ( this.getNextActor()));
2402
+ createTicket(options) {
2403
+ const actor = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _79 => _79.actor]), () => ( this.getNextActor()));
2398
2404
  const sessionKey = _nanoid.nanoid.call(void 0, );
2399
- const info = _optionalChain([options, 'optionalAccess', _89 => _89.info]);
2405
+ const info = _optionalChain([options, 'optionalAccess', _80 => _80.info]);
2400
2406
  const ticket = {
2401
- version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _90 => _90.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
2402
- actor: await actor$,
2407
+ version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
2408
+ actor,
2403
2409
  sessionKey,
2404
- meta: _optionalChain([options, 'optionalAccess', _91 => _91.meta]),
2405
- publicMeta: _optionalChain([options, 'optionalAccess', _92 => _92.publicMeta]),
2406
- user: _optionalChain([options, 'optionalAccess', _93 => _93.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _94 => _94.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
2407
- scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _95 => _95.scopes]), () => ( ["room:write"]))
2410
+ meta: _optionalChain([options, 'optionalAccess', _82 => _82.meta]),
2411
+ publicMeta: _optionalChain([options, 'optionalAccess', _83 => _83.publicMeta]),
2412
+ user: _optionalChain([options, 'optionalAccess', _84 => _84.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _85 => _85.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
2413
+ scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _86 => _86.scopes]), () => ( ["room:write"]))
2408
2414
  };
2409
2415
  if (__privateGet(this, __debug2)) {
2410
2416
  console.log(`new ticket created: ${JSON.stringify(ticket)}`);
2411
2417
  }
2412
2418
  return ticket;
2413
2419
  }
2414
- async createBackendSession_experimental() {
2415
- const ticket = await this.createTicket();
2420
+ createBackendSession_experimental() {
2421
+ const ticket = this.createTicket();
2416
2422
  const capturedServerMsgs = [];
2417
2423
  const stub = {
2418
2424
  send: (data) => {
@@ -2453,7 +2459,7 @@ var Room = class {
2453
2459
  newSession.markActive(lastActivity);
2454
2460
  }
2455
2461
  }
2456
- async sendSessionStartMessages(newSession, ticket, ctx, defer = () => {
2462
+ sendSessionStartMessages(newSession, ticket, ctx, defer = () => {
2457
2463
  throw new Error(
2458
2464
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to sendSessionStartMessages() to collect async side effects."
2459
2465
  );
@@ -2466,10 +2472,7 @@ var Room = class {
2466
2472
  scopes: session.scopes
2467
2473
  };
2468
2474
  }
2469
- const leasedSessions = await this.listLeasedSessions(
2470
- ctx,
2471
- defer
2472
- );
2475
+ const leasedSessions = this.listLeasedSessions(ctx, defer);
2473
2476
  for (const leasedSession of leasedSessions) {
2474
2477
  users[leasedSession.actorId] = {
2475
2478
  id: leasedSession.sessionId,
@@ -2505,7 +2508,7 @@ var Room = class {
2505
2508
  * - Sends a ROOM_STATE message to the socket.
2506
2509
  * - Broadcasts a USER_JOINED message to all other sessions in the room.
2507
2510
  */
2508
- async startBrowserSession(ticket, socket, ctx, defer = () => {
2511
+ startBrowserSession(ticket, socket, ctx, defer = () => {
2509
2512
  throw new Error(
2510
2513
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to startBrowserSession() to collect async side effects."
2511
2514
  );
@@ -2519,13 +2522,13 @@ var Room = class {
2519
2522
  ctx,
2520
2523
  defer
2521
2524
  );
2522
- this.logger.warn(
2525
+ __privateGet(this, _logger).warn(
2523
2526
  `Previous session for actor ${ticket.actor} killed in favor of new session`
2524
2527
  );
2525
2528
  }
2526
2529
  const newSession = new BrowserSession(ticket, socket, __privateGet(this, __debug2));
2527
2530
  this.sessions.set(ticket.sessionKey, newSession);
2528
- await this.sendSessionStartMessages(newSession, ticket, ctx, defer);
2531
+ this.sendSessionStartMessages(newSession, ticket, ctx, defer);
2529
2532
  this.sendToOthers(
2530
2533
  ticket.sessionKey,
2531
2534
  {
@@ -2538,7 +2541,7 @@ var Room = class {
2538
2541
  ctx,
2539
2542
  defer
2540
2543
  );
2541
- const p$ = _optionalChain([this, 'access', _96 => _96.hooks, 'access', _97 => _97.onSessionDidStart, 'optionalCall', _98 => _98(newSession, ctx)]);
2544
+ const p$ = _optionalChain([this, 'access', _87 => _87.hooks, 'access', _88 => _88.onSessionDidStart, 'optionalCall', _89 => _89(newSession, ctx)]);
2542
2545
  if (p$) defer(p$);
2543
2546
  }
2544
2547
  /**
@@ -2562,7 +2565,7 @@ var Room = class {
2562
2565
  for (const other of this.otherSessions(key)) {
2563
2566
  other.send({ type: ServerMsgCode2.USER_LEFT, actor: session.actor });
2564
2567
  }
2565
- const p$ = _optionalChain([this, 'access', _99 => _99.hooks, 'access', _100 => _100.onSessionDidEnd, 'optionalCall', _101 => _101(session, ctx)]);
2568
+ const p$ = _optionalChain([this, 'access', _90 => _90.hooks, 'access', _91 => _91.onSessionDidEnd, 'optionalCall', _92 => _92(session, ctx)]);
2566
2569
  if (p$) defer(p$);
2567
2570
  }
2568
2571
  }
@@ -2593,7 +2596,7 @@ var Room = class {
2593
2596
  );
2594
2597
  }) {
2595
2598
  const text = typeof data === "string" ? data : _core.raise.call(void 0, "Unsupported message format");
2596
- _optionalChain([this, 'access', _102 => _102.sessions, 'access', _103 => _103.get, 'call', _104 => _104(key), 'optionalAccess', _105 => _105.markActive, 'call', _106 => _106()]);
2599
+ _optionalChain([this, 'access', _93 => _93.sessions, 'access', _94 => _94.get, 'call', _95 => _95(key), 'optionalAccess', _96 => _96.markActive, 'call', _97 => _97()]);
2597
2600
  if (text === "ping") {
2598
2601
  await this.handlePing(key, ctx);
2599
2602
  } else {
@@ -2633,7 +2636,6 @@ var Room = class {
2633
2636
  * 2. The ClientMsg payload has been validated to be correct.
2634
2637
  */
2635
2638
  async processClientMsg(key, messages, ctx) {
2636
- await this.load(ctx);
2637
2639
  const { defer, waitAll } = collectSideEffects();
2638
2640
  await this.mutex.runExclusive(
2639
2641
  () => this._processClientMsg_withExclusiveAccess(key, messages, ctx, defer)
@@ -2660,7 +2662,6 @@ var Room = class {
2660
2662
  * a session.
2661
2663
  */
2662
2664
  async processClientMsgFromBackendSession(session, messages, ctx) {
2663
- await this.load(ctx);
2664
2665
  const { defer, waitAll } = collectSideEffects();
2665
2666
  await this.mutex.runExclusive(
2666
2667
  () => this._processClientMsgFromBackendSession_withExclusiveAccess(
@@ -2682,18 +2683,18 @@ var Room = class {
2682
2683
  * Upsert a leased session. Creates a new session if it doesn't exist (or is expired),
2683
2684
  * or updates an existing session with merged presence.
2684
2685
  */
2685
- async upsertLeasedSession(sessionId, presence, ttl, info, ctx, defer = () => {
2686
+ upsertLeasedSession(sessionId, presence, ttl, info, ctx, defer = () => {
2686
2687
  throw new Error(
2687
2688
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to upsertLeasedSession() to collect async side effects."
2688
2689
  );
2689
2690
  }) {
2690
- const existingSession = await this.driver.get_leased_session(sessionId);
2691
+ const existingSession = this.driver.get_leased_session(sessionId);
2691
2692
  const isExpired = existingSession !== void 0 && isLeasedSessionExpired(existingSession);
2692
2693
  if (isExpired) {
2693
- await this.deleteLeasedSession(existingSession, ctx, defer);
2694
+ this.deleteLeasedSession(existingSession, ctx, defer);
2694
2695
  }
2695
2696
  if (existingSession === void 0 || isExpired) {
2696
- const actorId = await this.getNextActor();
2697
+ const actorId = this.getNextActor();
2697
2698
  const now = Date.now();
2698
2699
  const session = {
2699
2700
  sessionId,
@@ -2703,7 +2704,7 @@ var Room = class {
2703
2704
  ttl,
2704
2705
  actorId
2705
2706
  };
2706
- await this.driver.put_leased_session(session);
2707
+ this.driver.put_leased_session(session);
2707
2708
  this.sendToAll(
2708
2709
  {
2709
2710
  type: ServerMsgCode2.USER_JOINED,
@@ -2737,7 +2738,7 @@ var Room = class {
2737
2738
  updatedAt: Date.now(),
2738
2739
  ttl
2739
2740
  };
2740
- await this.driver.put_leased_session(updatedSession);
2741
+ this.driver.put_leased_session(updatedSession);
2741
2742
  this.sendToAll(
2742
2743
  {
2743
2744
  type: ServerMsgCode2.UPDATE_PRESENCE,
@@ -2754,13 +2755,12 @@ var Room = class {
2754
2755
  /**
2755
2756
  * List all server sessions. As a side effect, it will delete expired sessions.
2756
2757
  */
2757
- async listLeasedSessions(ctx, defer = () => {
2758
+ listLeasedSessions(ctx, defer = () => {
2758
2759
  throw new Error(
2759
2760
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to listLeasedSessions() to collect async side effects."
2760
2761
  );
2761
2762
  }) {
2762
- await this.load(ctx);
2763
- const sessions = await this.driver.list_leased_sessions();
2763
+ const sessions = this.driver.list_leased_sessions();
2764
2764
  const validSessions = [];
2765
2765
  const toDelete = [];
2766
2766
  for (const [_, session] of sessions) {
@@ -2771,14 +2771,14 @@ var Room = class {
2771
2771
  }
2772
2772
  }
2773
2773
  for (const session of toDelete) {
2774
- await this.deleteLeasedSession(session, ctx, defer);
2774
+ this.deleteLeasedSession(session, ctx, defer);
2775
2775
  }
2776
2776
  return validSessions;
2777
2777
  }
2778
2778
  /**
2779
2779
  * Delete a server session and broadcast USER_LEFT to all sessions.
2780
2780
  */
2781
- async deleteLeasedSession(session, ctx, defer = () => {
2781
+ deleteLeasedSession(session, ctx, defer = () => {
2782
2782
  throw new Error(
2783
2783
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to deleteLeasedSession() to collect async side effects."
2784
2784
  );
@@ -2791,20 +2791,19 @@ var Room = class {
2791
2791
  ctx,
2792
2792
  defer
2793
2793
  );
2794
- await this.driver.delete_leased_session(session.sessionId);
2794
+ this.driver.delete_leased_session(session.sessionId);
2795
2795
  }
2796
2796
  /**
2797
2797
  * Delete all server sessions and broadcast USER_LEFT to all sessions.
2798
2798
  */
2799
- async deleteAllLeasedSessions(ctx, defer = () => {
2799
+ deleteAllLeasedSessions(ctx, defer = () => {
2800
2800
  throw new Error(
2801
2801
  "One of your hook handlers returned a promise, but no side effect collector was provided. Pass a `defer` callback to deleteAllLeasedSessions() to collect async side effects."
2802
2802
  );
2803
2803
  }) {
2804
- await this.load(ctx);
2805
- const sessions = await this.driver.list_leased_sessions();
2804
+ const sessions = this.driver.list_leased_sessions();
2806
2805
  for (const [_, session] of sessions) {
2807
- await this.deleteLeasedSession(session, ctx, defer);
2806
+ this.deleteLeasedSession(session, ctx, defer);
2808
2807
  }
2809
2808
  }
2810
2809
  // ---------------------------------------------------------------------------
@@ -2813,53 +2812,53 @@ var Room = class {
2813
2812
  /**
2814
2813
  * List feeds with pagination and filtering.
2815
2814
  */
2816
- async listFeeds(options) {
2817
- return await this.driver.list_feeds(options);
2815
+ listFeeds(options) {
2816
+ return this.driver.list_feeds(options);
2818
2817
  }
2819
2818
  /**
2820
2819
  * Get a specific feed by feed ID.
2821
2820
  */
2822
- async getFeed(feedId) {
2823
- return await this.driver.get_feed(feedId);
2821
+ getFeed(feedId) {
2822
+ return this.driver.get_feed(feedId);
2824
2823
  }
2825
2824
  /**
2826
2825
  * Create a new feed.
2827
2826
  * If timestamp is not provided, current server time is used.
2828
2827
  */
2829
- async createFeed(feed) {
2828
+ createFeed(feed) {
2830
2829
  const now = _nullishCoalesce(feed.timestamp, () => ( Date.now()));
2831
2830
  const fullFeed = {
2832
2831
  ...feed,
2833
2832
  createdAt: now,
2834
2833
  updatedAt: now
2835
2834
  };
2836
- await this.driver.create_feed(fullFeed);
2835
+ this.driver.create_feed(fullFeed);
2837
2836
  return fullFeed;
2838
2837
  }
2839
2838
  /**
2840
2839
  * Update a feed's metadata.
2841
2840
  */
2842
- async updateFeedMetadata(feedId, metadata) {
2843
- await this.driver.update_feed_metadata(feedId, metadata);
2841
+ updateFeedMetadata(feedId, metadata) {
2842
+ this.driver.update_feed_metadata(feedId, metadata);
2844
2843
  }
2845
2844
  /**
2846
2845
  * Delete a feed.
2847
2846
  */
2848
- async deleteFeed(feedId) {
2849
- await this.driver.delete_feed(feedId);
2847
+ deleteFeed(feedId) {
2848
+ this.driver.delete_feed(feedId);
2850
2849
  }
2851
2850
  /**
2852
2851
  * List feed messages for a feed with pagination.
2853
2852
  */
2854
- async listFeedMessages(feedId, options) {
2855
- return await this.driver.list_feed_messages(feedId, options);
2853
+ listFeedMessages(feedId, options) {
2854
+ return this.driver.list_feed_messages(feedId, options);
2856
2855
  }
2857
2856
  /**
2858
2857
  * Add a message to a feed.
2859
2858
  * If message id is not provided, a unique ID is automatically generated.
2860
2859
  * If timestamp is not provided, current server time is used.
2861
2860
  */
2862
- async addFeedMessage(feedId, message) {
2861
+ addFeedMessage(feedId, message) {
2863
2862
  const now = _nullishCoalesce(message.timestamp, () => ( Date.now()));
2864
2863
  const fullMessage = {
2865
2864
  id: _nullishCoalesce(message.id, () => ( _nanoid.nanoid.call(void 0, ))),
@@ -2867,15 +2866,15 @@ var Room = class {
2867
2866
  updatedAt: now,
2868
2867
  data: message.data
2869
2868
  };
2870
- await this.driver.add_feed_message(feedId, fullMessage);
2869
+ this.driver.add_feed_message(feedId, fullMessage);
2871
2870
  return fullMessage;
2872
2871
  }
2873
2872
  /**
2874
2873
  * Update a feed message's data.
2875
2874
  * Returns the updated message.
2876
2875
  */
2877
- async updateFeedMessage(feedId, messageId, data, timestamp) {
2878
- return await this.driver.update_feed_message(
2876
+ updateFeedMessage(feedId, messageId, data, timestamp) {
2877
+ return this.driver.update_feed_message(
2879
2878
  feedId,
2880
2879
  messageId,
2881
2880
  data,
@@ -2885,8 +2884,8 @@ var Room = class {
2885
2884
  /**
2886
2885
  * Delete a feed message.
2887
2886
  */
2888
- async deleteFeedMessage(feedId, messageId) {
2889
- await this.driver.delete_feed_message(feedId, messageId);
2887
+ deleteFeedMessage(feedId, messageId) {
2888
+ this.driver.delete_feed_message(feedId, messageId);
2890
2889
  }
2891
2890
  /**
2892
2891
  * Will send the given ServerMsg through all Session, except the Session
@@ -2933,37 +2932,15 @@ var Room = class {
2933
2932
  }
2934
2933
  }
2935
2934
  }
2936
- // ------------------------------------------------------------------------------------
2937
- // Private APIs
2938
- // ------------------------------------------------------------------------------------
2939
- async _loadStorage() {
2940
- const storage = new Storage(this.driver);
2941
- await storage.load(this.logger);
2942
- return storage;
2943
- }
2944
- async _loadYjsStorage() {
2945
- const yjsStorage = new YjsStorage(this.driver);
2946
- await yjsStorage.load(this.logger);
2947
- return yjsStorage;
2948
- }
2949
- // Don't ever manually call this!
2950
- async _load(ctx) {
2951
- await _optionalChain([this, 'access', _107 => _107.hooks, 'access', _108 => _108.onRoomWillLoad, 'optionalCall', _109 => _109(ctx)]);
2952
- const storage = await this._loadStorage();
2953
- const yjsStorage = await this._loadYjsStorage();
2954
- this._data = {
2955
- mutex: new (0, _asyncmutex.Mutex)(),
2956
- storage,
2957
- yjsStorage
2958
- };
2959
- await _optionalChain([this, 'access', _110 => _110.hooks, 'access', _111 => _111.onRoomDidLoad, 'optionalCall', _112 => _112(ctx)]);
2960
- }
2961
2935
  /**
2962
2936
  * Returns a new, unique, actor ID.
2963
2937
  */
2964
- async getNextActor() {
2965
- return await this.driver.next_actor();
2938
+ getNextActor() {
2939
+ return this.driver.next_actor();
2966
2940
  }
2941
+ // ------------------------------------------------------------------------------------
2942
+ // Private APIs
2943
+ // ------------------------------------------------------------------------------------
2967
2944
  /**
2968
2945
  * Iterates over all *other* Sessions and their session keys.
2969
2946
  */
@@ -2991,18 +2968,18 @@ var Room = class {
2991
2968
  async handlePing(sessionKey, ctx) {
2992
2969
  const session = this.sessions.get(sessionKey);
2993
2970
  if (session === void 0) {
2994
- this.logger.withContext({ sessionKey }).warn("[probe] in handlePing, no such session exists");
2971
+ __privateGet(this, _logger).withContext({ sessionKey }).warn("[probe] in handlePing, no such session exists");
2995
2972
  return;
2996
2973
  }
2997
2974
  const sent = session.sendPong();
2998
2975
  if (sent !== 0) {
2999
- await _optionalChain([this, 'access', _113 => _113.hooks, 'access', _114 => _114.onDidPong, 'optionalCall', _115 => _115(ctx)]);
2976
+ await _optionalChain([this, 'access', _98 => _98.hooks, 'access', _99 => _99.onDidPong, 'optionalCall', _100 => _100(ctx)]);
3000
2977
  }
3001
2978
  }
3002
- async _processClientMsg_withExclusiveAccess(sessionKey, messages, ctx, defer) {
2979
+ _processClientMsg_withExclusiveAccess(sessionKey, messages, ctx, defer) {
3003
2980
  const session = this.sessions.get(sessionKey);
3004
2981
  if (!session) {
3005
- this.logger.withContext({ sessionKey }).warn("[probe] in handleClientMsgs, no such session exists");
2982
+ __privateGet(this, _logger).withContext({ sessionKey }).warn("[probe] in handleClientMsgs, no such session exists");
3006
2983
  return;
3007
2984
  }
3008
2985
  const toFanOut = [];
@@ -3013,7 +2990,7 @@ var Room = class {
3013
2990
  for (const msg of messages) {
3014
2991
  const isMsgAllowed = this.hooks.isClientMsgAllowed(msg, session);
3015
2992
  if (isMsgAllowed.allowed) {
3016
- await this.handleOne(
2993
+ this.handleOne(
3017
2994
  session,
3018
2995
  msg,
3019
2996
  replyImmediately,
@@ -3043,7 +3020,7 @@ var Room = class {
3043
3020
  // TODO It's a bit bothering how much duplication there is between this method
3044
3021
  // and the _processClientMsg_withExclusiveAccess version. A better
3045
3022
  // abstraction is needed.
3046
- async _processClientMsgFromBackendSession_withExclusiveAccess(session, messages, ctx, defer) {
3023
+ _processClientMsgFromBackendSession_withExclusiveAccess(session, messages, ctx, defer) {
3047
3024
  const toFanOut = [];
3048
3025
  const toReplyImmediately = [];
3049
3026
  const toReplyAfter = [];
@@ -3065,7 +3042,7 @@ var Room = class {
3065
3042
  const scheduleFanOut = (msg) => void toFanOut.push(msg);
3066
3043
  const scheduleReply = (msg) => void toReplyAfter.push(msg);
3067
3044
  for (const msg of messages) {
3068
- await this.handleOne(
3045
+ this.handleOne(
3069
3046
  session,
3070
3047
  msg,
3071
3048
  replyImmediately,
@@ -3088,7 +3065,7 @@ var Room = class {
3088
3065
  toReplyAfter.length = 0;
3089
3066
  }
3090
3067
  }
3091
- async handleOne(session, msg, replyImmediately, scheduleFanOut, scheduleReply, ctx, defer) {
3068
+ handleOne(session, msg, replyImmediately, scheduleFanOut, scheduleReply, ctx, defer) {
3092
3069
  if (!this.mutex.isLocked()) {
3093
3070
  throw new Error("Handling messages requires exclusive access");
3094
3071
  }
@@ -3112,7 +3089,7 @@ var Room = class {
3112
3089
  }
3113
3090
  case _core.ClientMsgCode.FETCH_STORAGE: {
3114
3091
  if (session.version >= 8 /* V8 */) {
3115
- const rawStream = this.storage.loadedDriver.iter_nodes_optimized();
3092
+ const rawStream = this.storage.driver.iter_nodes_optimized();
3116
3093
  for (const chunk of groupNodesForWebSocketMessages(rawStream)) {
3117
3094
  const frame = `{"type":${ServerMsgCode2.STORAGE_CHUNK},"nodes":[${chunk.join(",")}]}`;
3118
3095
  replyImmediately(frame);
@@ -3121,14 +3098,14 @@ var Room = class {
3121
3098
  } else {
3122
3099
  replyImmediately({
3123
3100
  type: ServerMsgCode2.STORAGE_STATE_V7,
3124
- items: Array.from(this.storage.loadedDriver.iter_nodes())
3101
+ items: Array.from(this.storage.driver.iter_nodes())
3125
3102
  });
3126
3103
  }
3127
3104
  break;
3128
3105
  }
3129
3106
  case _core.ClientMsgCode.UPDATE_STORAGE: {
3130
- _optionalChain([this, 'access', _116 => _116.driver, 'access', _117 => _117.bump_storage_version, 'optionalCall', _118 => _118()]);
3131
- const result = await this.storage.applyOps(msg.ops);
3107
+ _optionalChain([this, 'access', _101 => _101.driver, 'access', _102 => _102.bump_storage_version, 'optionalCall', _103 => _103()]);
3108
+ const result = this.storage.applyOps(msg.ops);
3132
3109
  const opsToForward = result.flatMap(
3133
3110
  (r) => r.action === "accepted" ? [r.op] : []
3134
3111
  );
@@ -3160,7 +3137,7 @@ var Room = class {
3160
3137
  });
3161
3138
  }
3162
3139
  if (opsToForward.length > 0) {
3163
- const p$ = _optionalChain([this, 'access', _119 => _119.hooks, 'access', _120 => _120.postClientMsgStorageDidUpdate, 'optionalCall', _121 => _121(ctx)]);
3140
+ const p$ = _optionalChain([this, 'access', _104 => _104.hooks, 'access', _105 => _105.postClientMsgStorageDidUpdate, 'optionalCall', _106 => _106(ctx)]);
3164
3141
  if (p$) defer(p$);
3165
3142
  }
3166
3143
  break;
@@ -3169,11 +3146,17 @@ var Room = class {
3169
3146
  const vector = msg.vector;
3170
3147
  const guid = msg.guid;
3171
3148
  const isV2 = msg.v2;
3172
- const [update, stateVector, snapshotHash] = await Promise.all([
3173
- this.yjsStorage.getYDocUpdate(this.logger, vector, guid, isV2),
3174
- this.yjsStorage.getYStateVector(this.logger, guid),
3175
- this.yjsStorage.getSnapshotHash(this.logger, { guid, isV2 })
3176
- ]);
3149
+ const update = this.yjsStorage.getYDocUpdate(
3150
+ __privateGet(this, _logger),
3151
+ vector,
3152
+ guid,
3153
+ isV2
3154
+ );
3155
+ const stateVector = this.yjsStorage.getYStateVector(__privateGet(this, _logger), guid);
3156
+ const snapshotHash = this.yjsStorage.getSnapshotHash(__privateGet(this, _logger), {
3157
+ guid,
3158
+ isV2
3159
+ });
3177
3160
  if (update !== null && snapshotHash !== null) {
3178
3161
  replyImmediately({
3179
3162
  type: ServerMsgCode2.UPDATE_YDOC,
@@ -3192,8 +3175,8 @@ var Room = class {
3192
3175
  const update = msg.update;
3193
3176
  const guid = msg.guid;
3194
3177
  const isV2 = msg.v2;
3195
- const [result, error] = await tryCatch(
3196
- this.yjsStorage.addYDocUpdate(this.logger, update, guid, isV2)
3178
+ const [result, error] = tryCatch(
3179
+ () => this.yjsStorage.addYDocUpdate(__privateGet(this, _logger), update, guid, isV2)
3197
3180
  );
3198
3181
  if (error)
3199
3182
  break;
@@ -3211,7 +3194,7 @@ var Room = class {
3211
3194
  defer
3212
3195
  );
3213
3196
  if (result.isUpdated) {
3214
- const p$ = _optionalChain([this, 'access', _122 => _122.hooks, 'access', _123 => _123.postClientMsgYdocDidUpdate, 'optionalCall', _124 => _124(ctx, session)]);
3197
+ const p$ = _optionalChain([this, 'access', _107 => _107.hooks, 'access', _108 => _108.postClientMsgYdocDidUpdate, 'optionalCall', _109 => _109(ctx, session)]);
3215
3198
  if (p$) defer(p$);
3216
3199
  }
3217
3200
  break;
@@ -3219,8 +3202,8 @@ var Room = class {
3219
3202
  // Feed messages
3220
3203
  case FeedMsgCode.FETCH_FEEDS: {
3221
3204
  const fetchMsg = msg;
3222
- const [result, err] = await tryCatch(
3223
- this.listFeeds({
3205
+ const [result, err] = tryCatch(
3206
+ () => this.listFeeds({
3224
3207
  cursor: fetchMsg.cursor,
3225
3208
  since: fetchMsg.since,
3226
3209
  limit: fetchMsg.limit,
@@ -3241,8 +3224,8 @@ var Room = class {
3241
3224
  }
3242
3225
  case FeedMsgCode.FETCH_FEED_MESSAGES: {
3243
3226
  const fetchMsg = msg;
3244
- const [result, err] = await tryCatch(
3245
- this.listFeedMessages(fetchMsg.feedId, {
3227
+ const [result, err] = tryCatch(
3228
+ () => this.listFeedMessages(fetchMsg.feedId, {
3246
3229
  cursor: fetchMsg.cursor,
3247
3230
  since: fetchMsg.since,
3248
3231
  limit: fetchMsg.limit
@@ -3263,8 +3246,8 @@ var Room = class {
3263
3246
  }
3264
3247
  case FeedMsgCode.ADD_FEED: {
3265
3248
  const addMsg = msg;
3266
- const [feed, err] = await tryCatch(
3267
- this.createFeed({
3249
+ const [feed, err] = tryCatch(
3250
+ () => this.createFeed({
3268
3251
  feedId: addMsg.feedId,
3269
3252
  metadata: _nullishCoalesce(addMsg.metadata, () => ( {}))
3270
3253
  })
@@ -3283,14 +3266,14 @@ var Room = class {
3283
3266
  }
3284
3267
  case FeedMsgCode.UPDATE_FEED: {
3285
3268
  const updateMsg = msg;
3286
- const [, metaErr] = await tryCatch(
3287
- this.updateFeedMetadata(updateMsg.feedId, updateMsg.metadata)
3269
+ const [, metaErr] = tryCatch(
3270
+ () => this.updateFeedMetadata(updateMsg.feedId, updateMsg.metadata)
3288
3271
  );
3289
3272
  if (metaErr) {
3290
3273
  replyImmediately(feedFailureServerMsg(updateMsg.requestId, metaErr));
3291
3274
  break;
3292
3275
  }
3293
- const feed = await this.getFeed(updateMsg.feedId);
3276
+ const feed = this.getFeed(updateMsg.feedId);
3294
3277
  if (!feed) {
3295
3278
  replyImmediately(
3296
3279
  feedRequestFailed(
@@ -3310,7 +3293,7 @@ var Room = class {
3310
3293
  }
3311
3294
  case FeedMsgCode.DELETE_FEED: {
3312
3295
  const deleteMsg = msg;
3313
- const [, err] = await tryCatch(this.deleteFeed(deleteMsg.feedId));
3296
+ const [, err] = tryCatch(() => this.deleteFeed(deleteMsg.feedId));
3314
3297
  if (err) {
3315
3298
  replyImmediately(feedFailureServerMsg(deleteMsg.requestId, err));
3316
3299
  break;
@@ -3325,8 +3308,8 @@ var Room = class {
3325
3308
  }
3326
3309
  case FeedMsgCode.ADD_FEED_MESSAGE: {
3327
3310
  const addMsg = msg;
3328
- const [message, err] = await tryCatch(
3329
- this.addFeedMessage(addMsg.feedId, {
3311
+ const [message, err] = tryCatch(
3312
+ () => this.addFeedMessage(addMsg.feedId, {
3330
3313
  data: addMsg.data,
3331
3314
  id: addMsg.id
3332
3315
  })
@@ -3346,8 +3329,8 @@ var Room = class {
3346
3329
  }
3347
3330
  case FeedMsgCode.UPDATE_FEED_MESSAGE: {
3348
3331
  const updateMsg = msg;
3349
- const [message, err] = await tryCatch(
3350
- this.updateFeedMessage(
3332
+ const [message, err] = tryCatch(
3333
+ () => this.updateFeedMessage(
3351
3334
  updateMsg.feedId,
3352
3335
  updateMsg.messageId,
3353
3336
  updateMsg.data
@@ -3368,8 +3351,8 @@ var Room = class {
3368
3351
  }
3369
3352
  case FeedMsgCode.DELETE_FEED_MESSAGE: {
3370
3353
  const deleteMsg = msg;
3371
- const [, err] = await tryCatch(
3372
- this.deleteFeedMessage(deleteMsg.feedId, deleteMsg.messageId)
3354
+ const [, err] = tryCatch(
3355
+ () => this.deleteFeedMessage(deleteMsg.feedId, deleteMsg.messageId)
3373
3356
  );
3374
3357
  if (err) {
3375
3358
  replyImmediately(feedFailureServerMsg(deleteMsg.requestId, err));
@@ -3393,6 +3376,7 @@ var Room = class {
3393
3376
  }
3394
3377
  }
3395
3378
  };
3379
+ _logger = new WeakMap();
3396
3380
  __debug2 = new WeakMap();
3397
3381
 
3398
3382