@liveblocks/core 1.4.7 → 1.5.0-test1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1755,6 +1755,24 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1755
1755
  * - `synchronized`: Storage is in sync with Liveblocks servers.
1756
1756
  */
1757
1757
  getStorageStatus(): StorageStatus;
1758
+ /**
1759
+ * Start an attempt to connect the room (aka "enter" it). Calling
1760
+ * `.connect()` only has an effect if the room is still in its idle initial
1761
+ * state, or the room was explicitly disconnected, or reconnection attempts
1762
+ * were stopped (for example, because the user isn't authorized to enter the
1763
+ * room). Will be a no-op otherwise.
1764
+ */
1765
+ connect(): void;
1766
+ /**
1767
+ * Disconnect the room's connection to the Liveblocks server, if any. Puts
1768
+ * the room back into an idle state. It will not do anything until either
1769
+ * `.connect()` or `.reconnect()` is called.
1770
+ *
1771
+ * Only use this API if you wish to connect the room again at a later time.
1772
+ * If you want to disconnect the room because you no longer need it, call
1773
+ * `.destroy()` instead.
1774
+ */
1775
+ disconnect(): void;
1758
1776
  /**
1759
1777
  * Reconnect the room to the Liveblocks server by re-establishing a fresh
1760
1778
  * connection. If the room is not connected yet, initiate it.
@@ -1777,11 +1795,14 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1777
1795
  */
1778
1796
  initialStorage?: TStorage | ((roomId: string) => TStorage);
1779
1797
  /**
1780
- * Whether or not the room connects to Liveblock servers. Default is true.
1798
+ * Whether or not the room automatically connects to Liveblock servers.
1799
+ * Default is true.
1781
1800
  *
1782
1801
  * Usually set to false when the client is used from the server to not call
1783
1802
  * the authentication endpoint or connect via WebSocket.
1784
1803
  */
1804
+ autoConnect?: boolean;
1805
+ /** @deprecated Renamed to `autoConnect` */
1785
1806
  shouldInitiallyConnect?: boolean;
1786
1807
  }>;
1787
1808
 
@@ -1804,13 +1825,33 @@ declare type Client = {
1804
1825
  */
1805
1826
  getRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
1806
1827
  /**
1828
+ * Enter a room.
1829
+ * @param roomId The id of the room
1830
+ * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1831
+ * @returns The room and a leave function. Call the returned leave() function when you no longer need the room.
1832
+ */
1833
+ enterRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): {
1834
+ room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
1835
+ leave: () => void;
1836
+ };
1837
+ /**
1838
+ * @deprecated - Prefer using {@link Client.enterRoom} instead.
1839
+ *
1807
1840
  * Enters a room and returns it.
1808
1841
  * @param roomId The id of the room
1809
1842
  * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1810
1843
  */
1811
1844
  enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
1812
1845
  /**
1813
- * Leaves a room.
1846
+ * @deprecated - Prefer using {@link Client.enterRoom} and calling the returned leave function instead, which is safer.
1847
+ *
1848
+ * Forcefully leaves a room.
1849
+ *
1850
+ * Only call this if you know for sure there are no other "instances" of this
1851
+ * room used elsewhere in your application. Force-leaving can trigger
1852
+ * unexpected conditions in other parts of your application that may not
1853
+ * expect this.
1854
+ *
1814
1855
  * @param roomId The id of the room
1815
1856
  */
1816
1857
  leave(roomId: string): void;
@@ -2366,4 +2407,4 @@ declare type EnsureJson<T> = [
2366
2407
  [K in keyof T]: EnsureJson<T[K]>;
2367
2408
  };
2368
2409
 
2369
- export { AckOp, AsyncCache, AsyncState, AsyncStateError, AsyncStateInitial, AsyncStateLoading, AsyncStateResolved, AsyncStateSuccess, BaseAuthResult, BaseMetadata, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CommentBody, CommentBodyElement, CommentBodyLink, CommentBodyMention, CommentBodyParagraph, CommentBodyText, CommentData, CommentReaction, CommentsApi, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, EventSource, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomEventMessage, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ThreadData, ToImmutable, ToJson, UnsubscribeCallback, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, YDocUpdateServerMsg, asPos, assert, assertNever, b64decode, fancyConsole as console, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, shallow, stringify, throwUsageError, toPlainLson, tryParseJson, withTimeout };
2410
+ export { AckOp, AsyncCache, AsyncState, AsyncStateError, AsyncStateInitial, AsyncStateLoading, AsyncStateResolved, AsyncStateSuccess, BaseAuthResult, BaseMetadata, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CommentBody, CommentBodyElement, CommentBodyLink, CommentBodyMention, CommentBodyParagraph, CommentBodyText, CommentData, CommentReaction, CommentsApi, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, EnterOptions, EventSource, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomEventMessage, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ThreadData, ToImmutable, ToJson, UnsubscribeCallback, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, YDocUpdateServerMsg, asPos, assert, assertNever, b64decode, fancyConsole as console, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, shallow, stringify, throwUsageError, toPlainLson, tryParseJson, withTimeout };
package/dist/index.d.ts CHANGED
@@ -1755,6 +1755,24 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1755
1755
  * - `synchronized`: Storage is in sync with Liveblocks servers.
1756
1756
  */
1757
1757
  getStorageStatus(): StorageStatus;
1758
+ /**
1759
+ * Start an attempt to connect the room (aka "enter" it). Calling
1760
+ * `.connect()` only has an effect if the room is still in its idle initial
1761
+ * state, or the room was explicitly disconnected, or reconnection attempts
1762
+ * were stopped (for example, because the user isn't authorized to enter the
1763
+ * room). Will be a no-op otherwise.
1764
+ */
1765
+ connect(): void;
1766
+ /**
1767
+ * Disconnect the room's connection to the Liveblocks server, if any. Puts
1768
+ * the room back into an idle state. It will not do anything until either
1769
+ * `.connect()` or `.reconnect()` is called.
1770
+ *
1771
+ * Only use this API if you wish to connect the room again at a later time.
1772
+ * If you want to disconnect the room because you no longer need it, call
1773
+ * `.destroy()` instead.
1774
+ */
1775
+ disconnect(): void;
1758
1776
  /**
1759
1777
  * Reconnect the room to the Liveblocks server by re-establishing a fresh
1760
1778
  * connection. If the room is not connected yet, initiate it.
@@ -1777,11 +1795,14 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1777
1795
  */
1778
1796
  initialStorage?: TStorage | ((roomId: string) => TStorage);
1779
1797
  /**
1780
- * Whether or not the room connects to Liveblock servers. Default is true.
1798
+ * Whether or not the room automatically connects to Liveblock servers.
1799
+ * Default is true.
1781
1800
  *
1782
1801
  * Usually set to false when the client is used from the server to not call
1783
1802
  * the authentication endpoint or connect via WebSocket.
1784
1803
  */
1804
+ autoConnect?: boolean;
1805
+ /** @deprecated Renamed to `autoConnect` */
1785
1806
  shouldInitiallyConnect?: boolean;
1786
1807
  }>;
1787
1808
 
@@ -1804,13 +1825,33 @@ declare type Client = {
1804
1825
  */
1805
1826
  getRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
1806
1827
  /**
1828
+ * Enter a room.
1829
+ * @param roomId The id of the room
1830
+ * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1831
+ * @returns The room and a leave function. Call the returned leave() function when you no longer need the room.
1832
+ */
1833
+ enterRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): {
1834
+ room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
1835
+ leave: () => void;
1836
+ };
1837
+ /**
1838
+ * @deprecated - Prefer using {@link Client.enterRoom} instead.
1839
+ *
1807
1840
  * Enters a room and returns it.
1808
1841
  * @param roomId The id of the room
1809
1842
  * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1810
1843
  */
1811
1844
  enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
1812
1845
  /**
1813
- * Leaves a room.
1846
+ * @deprecated - Prefer using {@link Client.enterRoom} and calling the returned leave function instead, which is safer.
1847
+ *
1848
+ * Forcefully leaves a room.
1849
+ *
1850
+ * Only call this if you know for sure there are no other "instances" of this
1851
+ * room used elsewhere in your application. Force-leaving can trigger
1852
+ * unexpected conditions in other parts of your application that may not
1853
+ * expect this.
1854
+ *
1814
1855
  * @param roomId The id of the room
1815
1856
  */
1816
1857
  leave(roomId: string): void;
@@ -2366,4 +2407,4 @@ declare type EnsureJson<T> = [
2366
2407
  [K in keyof T]: EnsureJson<T[K]>;
2367
2408
  };
2368
2409
 
2369
- export { AckOp, AsyncCache, AsyncState, AsyncStateError, AsyncStateInitial, AsyncStateLoading, AsyncStateResolved, AsyncStateSuccess, BaseAuthResult, BaseMetadata, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CommentBody, CommentBodyElement, CommentBodyLink, CommentBodyMention, CommentBodyParagraph, CommentBodyText, CommentData, CommentReaction, CommentsApi, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, EventSource, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomEventMessage, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ThreadData, ToImmutable, ToJson, UnsubscribeCallback, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, YDocUpdateServerMsg, asPos, assert, assertNever, b64decode, fancyConsole as console, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, shallow, stringify, throwUsageError, toPlainLson, tryParseJson, withTimeout };
2410
+ export { AckOp, AsyncCache, AsyncState, AsyncStateError, AsyncStateInitial, AsyncStateLoading, AsyncStateResolved, AsyncStateSuccess, BaseAuthResult, BaseMetadata, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CommentBody, CommentBodyElement, CommentBodyLink, CommentBodyMention, CommentBodyParagraph, CommentBodyText, CommentData, CommentReaction, CommentsApi, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, EnterOptions, EventSource, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomEventMessage, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ThreadData, ToImmutable, ToJson, UnsubscribeCallback, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, YDocUpdateServerMsg, asPos, assert, assertNever, b64decode, fancyConsole as console, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, shallow, stringify, throwUsageError, toPlainLson, tryParseJson, withTimeout };
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ var __export = (target, all) => {
6
6
 
7
7
  // src/version.ts
8
8
  var PKG_NAME = "@liveblocks/core";
9
- var PKG_VERSION = "1.4.7";
9
+ var PKG_VERSION = "1.5.0-test1";
10
10
  var PKG_FORMAT = "cjs";
11
11
 
12
12
  // src/dupe-detection.ts
@@ -5911,15 +5911,35 @@ function createClient(options) {
5911
5911
  _nullishCoalesce(clientOptions.lostConnectionTimeout, () => ( DEFAULT_LOST_CONNECTION_TIMEOUT))
5912
5912
  );
5913
5913
  const authManager = createAuthManager(options);
5914
- const rooms = /* @__PURE__ */ new Map();
5915
- function getRoom(roomId) {
5916
- const room = rooms.get(roomId);
5917
- return room ? room : null;
5914
+ const roomsById = /* @__PURE__ */ new Map();
5915
+ function teardownRoom(room) {
5916
+ unlinkDevTools(room.id);
5917
+ roomsById.delete(room.id);
5918
+ room.destroy();
5919
+ }
5920
+ function leaseRoom(info) {
5921
+ const leave = () => {
5922
+ const self = leave;
5923
+ if (!info.unsubs.delete(self)) {
5924
+ warn(
5925
+ "This leave function was already called. Calling it more than once has no effect."
5926
+ );
5927
+ } else {
5928
+ if (info.unsubs.size === 0) {
5929
+ teardownRoom(info.room);
5930
+ }
5931
+ }
5932
+ };
5933
+ info.unsubs.add(leave);
5934
+ return {
5935
+ room: info.room,
5936
+ leave
5937
+ };
5918
5938
  }
5919
- function enter(roomId, options2) {
5920
- const existingRoom = rooms.get(roomId);
5921
- if (existingRoom !== void 0) {
5922
- return existingRoom;
5939
+ function enterRoom(roomId, options2) {
5940
+ const existing = roomsById.get(roomId);
5941
+ if (existing !== void 0) {
5942
+ return leaseRoom(existing);
5923
5943
  }
5924
5944
  deprecateIf(
5925
5945
  options2.initialPresence === null || options2.initialPresence === void 0,
@@ -5949,10 +5969,14 @@ function createClient(options) {
5949
5969
  unstable_fallbackToHTTP: !!clientOptions.unstable_fallbackToHTTP
5950
5970
  }
5951
5971
  );
5952
- rooms.set(roomId, newRoom);
5953
- setupDevTools(() => Array.from(rooms.keys()));
5972
+ const newRoomInfo = {
5973
+ room: newRoom,
5974
+ unsubs: /* @__PURE__ */ new Set()
5975
+ };
5976
+ roomsById.set(roomId, newRoomInfo);
5977
+ setupDevTools(() => Array.from(roomsById.keys()));
5954
5978
  linkDevTools(roomId, newRoom);
5955
- const shouldConnect = _nullishCoalesce(options2.shouldInitiallyConnect, () => ( true));
5979
+ const shouldConnect = _nullishCoalesce(_nullishCoalesce(options2.autoConnect, () => ( options2.shouldInitiallyConnect)), () => ( true));
5956
5980
  if (shouldConnect) {
5957
5981
  if (typeof atob === "undefined") {
5958
5982
  if (_optionalChain([clientOptions, 'access', _133 => _133.polyfills, 'optionalAccess', _134 => _134.atob]) === void 0) {
@@ -5964,20 +5988,29 @@ function createClient(options) {
5964
5988
  }
5965
5989
  newRoom.connect();
5966
5990
  }
5967
- return newRoom;
5991
+ return leaseRoom(newRoomInfo);
5968
5992
  }
5969
- function leave(roomId) {
5970
- unlinkDevTools(roomId);
5971
- const room = rooms.get(roomId);
5972
- if (room !== void 0) {
5973
- room.destroy();
5974
- rooms.delete(roomId);
5993
+ function enter(roomId, options2) {
5994
+ const { room, leave: _ } = enterRoom(roomId, options2);
5995
+ return room;
5996
+ }
5997
+ function getRoom(roomId) {
5998
+ const room = _optionalChain([roomsById, 'access', _135 => _135.get, 'call', _136 => _136(roomId), 'optionalAccess', _137 => _137.room]);
5999
+ return room ? room : null;
6000
+ }
6001
+ function forceLeave(roomId) {
6002
+ const unsubs = _nullishCoalesce(_optionalChain([roomsById, 'access', _138 => _138.get, 'call', _139 => _139(roomId), 'optionalAccess', _140 => _140.unsubs]), () => ( /* @__PURE__ */ new Set()));
6003
+ for (const unsub of unsubs) {
6004
+ unsub();
5975
6005
  }
5976
6006
  }
5977
6007
  return {
5978
- getRoom,
6008
+ // Old, deprecated APIs
5979
6009
  enter,
5980
- leave
6010
+ getRoom,
6011
+ leave: forceLeave,
6012
+ // New, preferred API
6013
+ enterRoom
5981
6014
  };
5982
6015
  }
5983
6016
  function checkBounds(option, value, min, max, recommendedMin) {
@@ -6230,12 +6263,12 @@ function legacy_patchImmutableNode(state, path, update) {
6230
6263
  }
6231
6264
  const newState = Object.assign({}, state);
6232
6265
  for (const key in update.updates) {
6233
- if (_optionalChain([update, 'access', _135 => _135.updates, 'access', _136 => _136[key], 'optionalAccess', _137 => _137.type]) === "update") {
6266
+ if (_optionalChain([update, 'access', _141 => _141.updates, 'access', _142 => _142[key], 'optionalAccess', _143 => _143.type]) === "update") {
6234
6267
  const val = update.node.get(key);
6235
6268
  if (val !== void 0) {
6236
6269
  newState[key] = lsonToJson(val);
6237
6270
  }
6238
- } else if (_optionalChain([update, 'access', _138 => _138.updates, 'access', _139 => _139[key], 'optionalAccess', _140 => _140.type]) === "delete") {
6271
+ } else if (_optionalChain([update, 'access', _144 => _144.updates, 'access', _145 => _145[key], 'optionalAccess', _146 => _146.type]) === "delete") {
6239
6272
  delete newState[key];
6240
6273
  }
6241
6274
  }
@@ -6296,12 +6329,12 @@ function legacy_patchImmutableNode(state, path, update) {
6296
6329
  }
6297
6330
  const newState = Object.assign({}, state);
6298
6331
  for (const key in update.updates) {
6299
- if (_optionalChain([update, 'access', _141 => _141.updates, 'access', _142 => _142[key], 'optionalAccess', _143 => _143.type]) === "update") {
6332
+ if (_optionalChain([update, 'access', _147 => _147.updates, 'access', _148 => _148[key], 'optionalAccess', _149 => _149.type]) === "update") {
6300
6333
  const value = update.node.get(key);
6301
6334
  if (value !== void 0) {
6302
6335
  newState[key] = lsonToJson(value);
6303
6336
  }
6304
- } else if (_optionalChain([update, 'access', _144 => _144.updates, 'access', _145 => _145[key], 'optionalAccess', _146 => _146.type]) === "delete") {
6337
+ } else if (_optionalChain([update, 'access', _150 => _150.updates, 'access', _151 => _151[key], 'optionalAccess', _152 => _152.type]) === "delete") {
6305
6338
  delete newState[key];
6306
6339
  }
6307
6340
  }
@@ -6391,7 +6424,7 @@ function createCacheItem(key, asyncFunction, options) {
6391
6424
  let previousState = { isLoading: false };
6392
6425
  const eventSource2 = makeEventSource();
6393
6426
  function notify() {
6394
- const isEqual = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _147 => _147.isStateEqual]), () => ( isShallowEqual));
6427
+ const isEqual = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _153 => _153.isStateEqual]), () => ( isShallowEqual));
6395
6428
  if (!isEqual(previousState, state)) {
6396
6429
  previousState = state;
6397
6430
  eventSource2.notify(state);
@@ -6459,7 +6492,7 @@ function createAsyncCache(asyncFunction, options) {
6459
6492
  return create(key).get();
6460
6493
  }
6461
6494
  function getState(key) {
6462
- return _optionalChain([cache, 'access', _148 => _148.get, 'call', _149 => _149(key), 'optionalAccess', _150 => _150.getState, 'call', _151 => _151()]);
6495
+ return _optionalChain([cache, 'access', _154 => _154.get, 'call', _155 => _155(key), 'optionalAccess', _156 => _156.getState, 'call', _157 => _157()]);
6463
6496
  }
6464
6497
  function revalidate(key) {
6465
6498
  return create(key).revalidate();