@liveblocks/server 1.5.0-rc2 → 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.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, Awaitable, CompactNode, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
1
+ import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, CompactNode, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
2
2
  export { BroadcastEventClientMsg, ClientMsg, ClientWireOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, DeleteCrdtOp, DeleteObjectKeyOp, FetchStorageClientMsg, FetchYDocClientMsg, HasOpId, IgnoredOp, Op, RoomStateServerMsg, ServerMsg, ServerWireOp, SetParentKeyOp, UpdateObjectOp, UpdatePresenceClientMsg, UpdateStorageClientMsg, UpdateYDocClientMsg } from '@liveblocks/core';
3
3
  import * as decoders from 'decoders';
4
4
  import { Decoder } from 'decoders';
@@ -521,96 +521,6 @@ interface IServerWebSocket {
521
521
  getLastPongTimestamp?(): Date | null;
522
522
  }
523
523
 
524
- /**
525
- * Copyright (c) Liveblocks Inc.
526
- *
527
- * This program is free software: you can redistribute it and/or modify
528
- * it under the terms of the GNU Affero General Public License as published
529
- * by the Free Software Foundation, either version 3 of the License, or
530
- * (at your option) any later version.
531
- *
532
- * This program is distributed in the hope that it will be useful,
533
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
534
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
535
- * GNU Affero General Public License for more details.
536
- *
537
- * You should have received a copy of the GNU Affero General Public License
538
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
539
- */
540
-
541
- declare enum LogLevel {
542
- DEBUG = 0,
543
- INFO = 1,
544
- WARNING = 2,
545
- ERROR = 3
546
- }
547
- /**
548
- * Inherit from this abstract log target to implement your own custom
549
- * LogTarget.
550
- */
551
- declare abstract class LogTarget {
552
- #private;
553
- readonly level: LogLevel;
554
- constructor(level?: LogLevel | keyof typeof LogLevelNames);
555
- /** Helper for formatting a log level */
556
- protected formatLevel(level: LogLevel): string;
557
- /** Helper for formatting an Arg */
558
- protected formatArg(arg: string | Error): string;
559
- /**
560
- * Helper for formatting a Context. Override this in a subclass to change the
561
- * formatting.
562
- */
563
- protected formatContextImpl(context: JsonObject): string;
564
- /**
565
- * Helper for formatting a Context. Will only compute the string once for
566
- * every Context instance, and keep its computed string value cached for
567
- * performance.
568
- */
569
- protected formatContext(context: JsonObject): string;
570
- /**
571
- * Implement this in a concrete subclass. The goal is to do whatever to log
572
- * the given log level, context, and log arg. You'll typically want to
573
- * utilize the pre-defined helper methods .formatContext() and .formatArg()
574
- * to implement this.
575
- */
576
- abstract log(level: LogLevel, context: JsonObject, arg: string | Error): void;
577
- }
578
- declare class ConsoleTarget extends LogTarget {
579
- log(level: LogLevel, context: JsonObject, arg: string | Error): void;
580
- }
581
- declare const LogLevelNames: {
582
- readonly debug: LogLevel.DEBUG;
583
- readonly info: LogLevel.INFO;
584
- readonly warning: LogLevel.WARNING;
585
- readonly error: LogLevel.ERROR;
586
- };
587
- type LogFn = (arg: string | Error) => void;
588
- /**
589
- * Structured logger with configurable log targets.
590
- */
591
- declare class Logger {
592
- readonly debug: LogFn;
593
- readonly info: LogFn;
594
- readonly warn: LogFn;
595
- readonly error: LogFn;
596
- readonly o: {
597
- readonly debug?: LogFn;
598
- readonly info?: LogFn;
599
- readonly warn?: LogFn;
600
- readonly error?: LogFn;
601
- };
602
- private readonly _context;
603
- private readonly _targets;
604
- constructor(target?: LogTarget | readonly LogTarget[], context?: JsonObject);
605
- /**
606
- * Creates a new Logger instance with the given extra context applied. All
607
- * log calls made from that new Logger will carry all current _and_ the extra
608
- * context, with the extra context taking precedence. Assign an explicit
609
- * `undefined` value to a key to "remove" it from the context.
610
- */
611
- withContext(extra: JsonObject): Logger;
612
- }
613
-
614
524
  /**
615
525
  * Copyright (c) Liveblocks Inc.
616
526
  *
@@ -697,14 +607,20 @@ interface IReadableSnapshot {
697
607
  destroy(): void;
698
608
  }
699
609
  /**
700
- * CRDT node storage with synchronous reads and async persistence.
610
+ * Persistent storage backend for Liveblocks room data: CRDT nodes, metadata,
611
+ * actor IDs, and Yjs updates.
612
+ *
613
+ * The node methods will initialize lazily (but synchronously): on first node
614
+ * access, the driver loads/repairs its node state internally, at most once per
615
+ * instance. DANGEROUSLY_reset_nodes() invalidates that state, after which the
616
+ * next access transparently re-runs the load/repair sanitization.
701
617
  *
702
618
  * INVARIANTS:
703
619
  * - A virtual root node `{type: OBJECT, data: {}}` always exists.
704
620
  * - All non-root nodes have parentId and parentKey forming a tree.
705
- * - Reads reflect writes immediately, before the returned Promise resolves.
621
+ * - Reads reflect writes immediately.
706
622
  */
707
- interface IStorageDriverNodeAPI {
623
+ interface IStorageDriver {
708
624
  /**
709
625
  * Return the node with the given id, or undefined if no such node exists.
710
626
  * Must always return a valid root node for id="root", even if empty.
@@ -769,18 +685,18 @@ interface IStorageDriverNodeAPI {
769
685
  * If allowOverwrite=true: replace any existing node at this id, deleting its
770
686
  * entire subtree if it has children.
771
687
  */
772
- set_child(id: string, node: SerializedChild, allowOverwrite?: boolean): Awaitable<void>;
688
+ set_child(id: string, node: SerializedChild, allowOverwrite?: boolean): void;
773
689
  /**
774
690
  * Change a node's parentKey, effectively repositioning the node within its
775
691
  * parent. The new position must be free.
776
692
  * Throw if another node already occupies (parentId, newPos).
777
693
  */
778
- move_sibling(id: string, newPos: Pos): Awaitable<void>;
694
+ move_sibling(id: string, newPos: Pos): void;
779
695
  /**
780
696
  * Delete a node and its entire subtree recursively.
781
697
  * Ignore if id="root" (root is immortal).
782
698
  */
783
- delete_node(id: string): Awaitable<void>;
699
+ delete_node(id: string): void;
784
700
  /**
785
701
  * Delete a key from node `id`. Handle two cases:
786
702
  *
@@ -790,7 +706,7 @@ interface IStorageDriverNodeAPI {
790
706
  *
791
707
  * No-op if neither applies or if the node doesn't exist.
792
708
  */
793
- delete_child_key(id: string, key: string): Awaitable<void>;
709
+ delete_child_key(id: string, key: string): void;
794
710
  /**
795
711
  * Replace the data object of an OBJECT node.
796
712
  *
@@ -799,7 +715,7 @@ interface IStorageDriverNodeAPI {
799
715
  * If allowOverwrite=true: first delete any conflicting children (and their
800
716
  * entire subtrees), then set the data.
801
717
  */
802
- set_object_data(id: string, data: JsonObject, allowOverwrite?: boolean): Awaitable<void>;
718
+ set_object_data(id: string, data: JsonObject, allowOverwrite?: boolean): void;
803
719
  /**
804
720
  * Return a readable snapshot of the storage tree.
805
721
  *
@@ -808,45 +724,39 @@ interface IStorageDriverNodeAPI {
808
724
  * access.
809
725
  */
810
726
  get_snapshot(lowMemory?: boolean): IReadableSnapshot;
811
- }
812
- /**
813
- * Persistent storage backend for Liveblocks room data: CRDT nodes, metadata,
814
- * actor IDs, and Yjs updates. All methods may be async.
815
- */
816
- interface IStorageDriver {
817
727
  /**
818
- * Load all nodes from storage, validate/repair corruptions (orphans, cycles,
819
- * conflicting siblings), and return an IStorageDriverNodeAPI for operations.
820
- *
821
- * After DANGEROUSLY_reset_nodes(), any previously-loaded instance is
822
- * invalid—must call this again to get a fresh one.
728
+ * Release any lazily-initialized in-memory node state (caches/indexes
729
+ * built on first node access), freeing it up for garbage collection.
730
+ * Persisted data is NOT touched — the next node access transparently
731
+ * re-initializes. (Contrast with DANGEROUSLY_reset_nodes(), which deletes
732
+ * the actual data.)
823
733
  */
824
- load_nodes_api(logger: Logger): Awaitable<IStorageDriverNodeAPI>;
734
+ reinitialize(): void;
825
735
  /**
826
736
  * Delete all CRDT nodes and replace them with the given document.
827
737
  * Does NOT affect metadata, actor IDs, or Yjs updates.
828
- * Invalidates any previously-loaded IStorageDriverNodeAPI.
738
+ * Invalidates the driver's internally loaded node state.
829
739
  *
830
740
  * Pass `{ liveblocksType: "LiveObject", data: {} }` to reset to an empty root.
831
741
  */
832
- DANGEROUSLY_reset_nodes(doc: PlainLsonObject): Awaitable<void>;
742
+ DANGEROUSLY_reset_nodes(doc: PlainLsonObject): void;
833
743
  /**
834
744
  * Return the value for `key`, or undefined if not set.
835
745
  */
836
- get_meta(key: string): Awaitable<Json | undefined>;
746
+ get_meta(key: string): Json | undefined;
837
747
  /**
838
748
  * Store `value` under `key`. Overwrite any existing value.
839
749
  */
840
- put_meta(key: string, value: Json): Awaitable<void>;
750
+ put_meta(key: string, value: Json): void;
841
751
  /**
842
752
  * Delete the value under `key`. No-op if not set.
843
753
  */
844
- delete_meta(key: string): Awaitable<void>;
754
+ delete_meta(key: string): void;
845
755
  /**
846
756
  * Return a unique actor ID. Each call must return a distinct integer ≥ 0.
847
757
  * Concurrent calls must never return duplicates.
848
758
  */
849
- next_actor(): Awaitable<number>;
759
+ next_actor(): number;
850
760
  /**
851
761
  * If defined, called once before each storage mutation batch. Can be used by
852
762
  * the driver to more efficiently implement snapshot isolation.
@@ -855,42 +765,42 @@ interface IStorageDriver {
855
765
  /**
856
766
  * Return all Yjs updates for docId as [key, data] pairs. Return empty if none.
857
767
  */
858
- iter_y_updates(docId: YDocId): Awaitable<Iterable<[string, Uint8Array]>>;
768
+ iter_y_updates(docId: YDocId): Iterable<[string, Uint8Array]>;
859
769
  /**
860
770
  * Store a Yjs update under (docId, key). Overwrite if key exists.
861
771
  */
862
- write_y_updates(docId: YDocId, key: string, data: Uint8Array): Awaitable<void>;
772
+ write_y_updates(docId: YDocId, key: string, data: Uint8Array): void;
863
773
  /**
864
774
  * Delete the specified keys for docId.
865
775
  */
866
- delete_y_updates(docId: YDocId, keys: string[]): Awaitable<void>;
776
+ delete_y_updates(docId: YDocId, keys: string[]): void;
867
777
  /**
868
778
  * Delete ALL Yjs updates across ALL documents.
869
779
  * @private Test-only: never use in production.
870
780
  */
871
- DANGEROUSLY_wipe_all_y_updates(): Awaitable<void>;
781
+ DANGEROUSLY_wipe_all_y_updates(): void;
872
782
  /**
873
783
  * List all leased sessions.
874
784
  * Note: Does NOT filter by expiration - returns all stored sessions.
875
785
  * Expiration logic is handled at the Room.ts level.
876
786
  */
877
- list_leased_sessions(): Awaitable<Iterable<[sessionId: string, session: LeasedSession]>>;
787
+ list_leased_sessions(): Iterable<[sessionId: string, session: LeasedSession]>;
878
788
  /**
879
789
  * Get a specific leased session by session ID.
880
790
  * Note: Does NOT check expiration - returns the stored session if it exists.
881
791
  * Expiration logic is handled at the Room.ts level.
882
792
  */
883
- get_leased_session(sessionId: string): Awaitable<LeasedSession | undefined>;
793
+ get_leased_session(sessionId: string): LeasedSession | undefined;
884
794
  /**
885
795
  * Create or update a leased session.
886
796
  * Note: This is a full replace operation - the caller is responsible for
887
797
  * merging/patching presence if needed.
888
798
  */
889
- put_leased_session(session: LeasedSession): Awaitable<void>;
799
+ put_leased_session(session: LeasedSession): void;
890
800
  /**
891
801
  * Delete a leased session by session ID.
892
802
  */
893
- delete_leased_session(sessionId: string): Awaitable<void>;
803
+ delete_leased_session(sessionId: string): void;
894
804
  /**
895
805
  * Return the number of storage rows written since last call to this method,
896
806
  * and reset the counter.
@@ -900,41 +810,41 @@ interface IStorageDriver {
900
810
  * List feeds with pagination, filtering, and metadata querying.
901
811
  * Feeds are sorted by createdAt descending (newest first).
902
812
  */
903
- list_feeds(options?: ListFeedsOptions): Awaitable<ListFeedsResult>;
813
+ list_feeds(options?: ListFeedsOptions): ListFeedsResult;
904
814
  /**
905
815
  * Get a specific feed by feed ID.
906
816
  * Returns feed metadata only (without messages).
907
817
  * Use list_feed_messages to retrieve messages for this feed.
908
818
  * Returns undefined if the feed doesn't exist.
909
819
  */
910
- get_feed(feedId: string): Awaitable<Feed | undefined>;
820
+ get_feed(feedId: string): Feed | undefined;
911
821
  /**
912
822
  * Create a new feed.
913
823
  * If feedId already exists, throws an error.
914
824
  */
915
- create_feed(feed: Feed): Awaitable<void>;
825
+ create_feed(feed: Feed): void;
916
826
  /**
917
827
  * Update a feed's metadata.
918
828
  * The feed must exist, otherwise throws an error.
919
829
  */
920
- update_feed_metadata(feedId: string, metadata: Json): Awaitable<void>;
830
+ update_feed_metadata(feedId: string, metadata: Json): void;
921
831
  /**
922
832
  * Delete a feed by feed ID.
923
833
  * Also deletes all messages associated with the feed (via CASCADE).
924
834
  * No-op if feed doesn't exist.
925
835
  */
926
- delete_feed(feedId: string): Awaitable<void>;
836
+ delete_feed(feedId: string): void;
927
837
  /**
928
838
  * List feed messages for a feed with pagination.
929
839
  * Messages are sorted by createdAt descending (newest first).
930
840
  */
931
- list_feed_messages(feedId: string, options?: ListFeedMessagesOptions): Awaitable<ListFeedMessagesResult>;
841
+ list_feed_messages(feedId: string, options?: ListFeedMessagesOptions): ListFeedMessagesResult;
932
842
  /**
933
843
  * Add a message to a feed.
934
844
  * The message must have id, createdAt, and updatedAt already set (handled by Room layer).
935
845
  * The feed must exist, otherwise throws an error.
936
846
  */
937
- add_feed_message(feedId: string, message: FeedMessage): Awaitable<void>;
847
+ add_feed_message(feedId: string, message: FeedMessage): void;
938
848
  /**
939
849
  * Update a feed message's data.
940
850
  * Returns the updated message.
@@ -942,12 +852,12 @@ interface IStorageDriver {
942
852
  * If timestamp is not provided, current server time is used.
943
853
  * Messages are only updated if the provided timestamp is greater than or equal to the stored updatedAt.
944
854
  */
945
- update_feed_message(feedId: string, messageId: string, data: Json, timestamp?: number): Awaitable<FeedMessage>;
855
+ update_feed_message(feedId: string, messageId: string, data: Json, timestamp?: number): FeedMessage;
946
856
  /**
947
857
  * Delete a feed message.
948
858
  * The feed and message must exist, otherwise throws an error.
949
859
  */
950
- delete_feed_message(feedId: string, messageId: string): Awaitable<void>;
860
+ delete_feed_message(feedId: string, messageId: string): void;
951
861
  }
952
862
 
953
863
  /**
@@ -1093,10 +1003,10 @@ declare function makeInMemorySnapshot(values: NodeMap$1 | NodeStream$1): IReadab
1093
1003
  */
1094
1004
 
1095
1005
  interface MetadataDB {
1096
- get(key: string): Promise<Json | undefined>;
1097
- get<T>(decoder: Decoder<T>, key: string): Promise<T | undefined>;
1098
- put(key: string, value: Json): Awaitable<void>;
1099
- delete(key: string): Awaitable<void>;
1006
+ get(key: string): Json | undefined;
1007
+ get<T>(decoder: Decoder<T>, key: string): T | undefined;
1008
+ put(key: string, value: Json): void;
1009
+ delete(key: string): void;
1100
1010
  }
1101
1011
  /**
1102
1012
  * Returns a thin wrapper around an IStorageDriver to provide MetadataDB
@@ -1104,6 +1014,96 @@ interface MetadataDB {
1104
1014
  */
1105
1015
  declare function makeMetadataDB(driver: IStorageDriver): MetadataDB;
1106
1016
 
1017
+ /**
1018
+ * Copyright (c) Liveblocks Inc.
1019
+ *
1020
+ * This program is free software: you can redistribute it and/or modify
1021
+ * it under the terms of the GNU Affero General Public License as published
1022
+ * by the Free Software Foundation, either version 3 of the License, or
1023
+ * (at your option) any later version.
1024
+ *
1025
+ * This program is distributed in the hope that it will be useful,
1026
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1027
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1028
+ * GNU Affero General Public License for more details.
1029
+ *
1030
+ * You should have received a copy of the GNU Affero General Public License
1031
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
1032
+ */
1033
+
1034
+ declare enum LogLevel {
1035
+ DEBUG = 0,
1036
+ INFO = 1,
1037
+ WARNING = 2,
1038
+ ERROR = 3
1039
+ }
1040
+ /**
1041
+ * Inherit from this abstract log target to implement your own custom
1042
+ * LogTarget.
1043
+ */
1044
+ declare abstract class LogTarget {
1045
+ #private;
1046
+ readonly level: LogLevel;
1047
+ constructor(level?: LogLevel | keyof typeof LogLevelNames);
1048
+ /** Helper for formatting a log level */
1049
+ protected formatLevel(level: LogLevel): string;
1050
+ /** Helper for formatting an Arg */
1051
+ protected formatArg(arg: string | Error): string;
1052
+ /**
1053
+ * Helper for formatting a Context. Override this in a subclass to change the
1054
+ * formatting.
1055
+ */
1056
+ protected formatContextImpl(context: JsonObject): string;
1057
+ /**
1058
+ * Helper for formatting a Context. Will only compute the string once for
1059
+ * every Context instance, and keep its computed string value cached for
1060
+ * performance.
1061
+ */
1062
+ protected formatContext(context: JsonObject): string;
1063
+ /**
1064
+ * Implement this in a concrete subclass. The goal is to do whatever to log
1065
+ * the given log level, context, and log arg. You'll typically want to
1066
+ * utilize the pre-defined helper methods .formatContext() and .formatArg()
1067
+ * to implement this.
1068
+ */
1069
+ abstract log(level: LogLevel, context: JsonObject, arg: string | Error): void;
1070
+ }
1071
+ declare class ConsoleTarget extends LogTarget {
1072
+ log(level: LogLevel, context: JsonObject, arg: string | Error): void;
1073
+ }
1074
+ declare const LogLevelNames: {
1075
+ readonly debug: LogLevel.DEBUG;
1076
+ readonly info: LogLevel.INFO;
1077
+ readonly warning: LogLevel.WARNING;
1078
+ readonly error: LogLevel.ERROR;
1079
+ };
1080
+ type LogFn = (arg: string | Error) => void;
1081
+ /**
1082
+ * Structured logger with configurable log targets.
1083
+ */
1084
+ declare class Logger {
1085
+ readonly debug: LogFn;
1086
+ readonly info: LogFn;
1087
+ readonly warn: LogFn;
1088
+ readonly error: LogFn;
1089
+ readonly o: {
1090
+ readonly debug?: LogFn;
1091
+ readonly info?: LogFn;
1092
+ readonly warn?: LogFn;
1093
+ readonly error?: LogFn;
1094
+ };
1095
+ private readonly _context;
1096
+ private readonly _targets;
1097
+ constructor(target?: LogTarget | readonly LogTarget[], context?: JsonObject);
1098
+ /**
1099
+ * Creates a new Logger instance with the given extra context applied. All
1100
+ * log calls made from that new Logger will carry all current _and_ the extra
1101
+ * context, with the extra context taking precedence. Assign an explicit
1102
+ * `undefined` value to a key to "remove" it from the context.
1103
+ */
1104
+ withContext(extra: JsonObject): Logger;
1105
+ }
1106
+
1107
1107
  /**
1108
1108
  * Copyright (c) Liveblocks Inc.
1109
1109
  *
@@ -1132,23 +1132,13 @@ type OpIgnored = {
1132
1132
  ignoredOpId?: string;
1133
1133
  };
1134
1134
  declare class Storage {
1135
- private readonly coreDriver;
1136
- private _loadedDriver;
1137
- constructor(coreDriver: IStorageDriver);
1138
- get loadedDriver(): IStorageDriverNodeAPI;
1139
- raw_iter_nodes(): Awaitable<Iterable<[string, SerializedCrdt]>>;
1140
- /**
1141
- * Load the room data from object storage into memory. Persisted room
1142
- * data consists of the main node map, which represents the Liveblocks
1143
- * Storage tree, and special keys where we store usage metrics, or room
1144
- * metadata.
1145
- */
1146
- load(logger: Logger): Promise<void>;
1147
- unload(): void;
1135
+ readonly driver: IStorageDriver;
1136
+ constructor(driver: IStorageDriver);
1137
+ raw_iter_nodes(): Iterable<[string, SerializedCrdt]>;
1148
1138
  /**
1149
1139
  * Applies a batch of Ops.
1150
1140
  */
1151
- applyOps(ops: ClientWireOp[]): Promise<ApplyOpResult[]>;
1141
+ applyOps(ops: ClientWireOp[]): ApplyOpResult[];
1152
1142
  /**
1153
1143
  * Applies a single Op.
1154
1144
  */
@@ -1228,41 +1218,46 @@ declare class Storage {
1228
1218
  declare class YjsStorage {
1229
1219
  private readonly driver;
1230
1220
  private readonly updateCountThreshold;
1231
- private readonly doc;
1221
+ /**
1222
+ * The root Y.Doc instance, which may not have been hydrated from storage
1223
+ * yet. Use getRootDoc() instead, which lazily hydrates it on first access —
1224
+ * only touch this field directly when the unhydrated instance is fine
1225
+ * (e.g. identity checks, subdoc traversal).
1226
+ */
1227
+ private readonly rawRootDoc;
1232
1228
  private readonly lastSnapshotById;
1233
- private readonly initPromisesById;
1229
+ private readonly docsById;
1234
1230
  private readonly storedKeysById;
1235
1231
  constructor(driver: IStorageDriver, updateCountThreshold?: number);
1236
- getYDoc(logger: Logger, docId: YDocId): Promise<Y.Doc>;
1232
+ getYDoc(logger: Logger, docId: YDocId): Y.Doc;
1233
+ /**
1234
+ * Returns the root Y.Doc, lazily loading it from storage first if it
1235
+ * hasn't been loaded yet during this instance's lifetime.
1236
+ */
1237
+ private getRootDoc;
1237
1238
  /**
1238
1239
  * If passed a state vector, an update with diff will be returned, if not the entire doc is returned.
1239
1240
  *
1240
1241
  * @param stateVector a base64 encoded target state vector created by running Y.encodeStateVector(Doc) on the client
1241
1242
  * @returns a base64 encoded array of YJS updates
1242
1243
  */
1243
- getYDocUpdate(logger: Logger, stateVector?: string, guid?: Guid, isV2?: boolean): Promise<string | null>;
1244
- getYDocUpdateBinary(logger: Logger, stateVector?: string, guid?: Guid, isV2?: boolean): Promise<Uint8Array<ArrayBuffer> | null>;
1245
- getYStateVector(logger: Logger, guid?: Guid): Promise<string | null>;
1244
+ getYDocUpdate(logger: Logger, stateVector?: string, guid?: Guid, isV2?: boolean): string | null;
1245
+ getYDocUpdateBinary(logger: Logger, stateVector?: string, guid?: Guid, isV2?: boolean): Uint8Array<ArrayBuffer> | null;
1246
+ getYStateVector(logger: Logger, guid?: Guid): string | null;
1246
1247
  getSnapshotHash(logger: Logger, options: {
1247
1248
  guid?: Guid;
1248
1249
  isV2?: boolean;
1249
- }): Promise<string | null>;
1250
+ }): string | null;
1250
1251
  /**
1251
1252
  * @param update base64 encoded uint8array
1252
1253
  * @returns { isUpdated: boolean; snapshotHash: string }
1253
1254
  * isUpdated: true if the update had an effect on the YDoc
1254
1255
  * snapshotHash: the hash of the new snapshot
1255
1256
  */
1256
- addYDocUpdate(logger: Logger, update: string | Uint8Array, guid?: Guid, isV2?: boolean): Promise<{
1257
+ addYDocUpdate(logger: Logger, update: string | Uint8Array, guid?: Guid, isV2?: boolean): {
1257
1258
  isUpdated: boolean;
1258
1259
  snapshotHash: string;
1259
- }>;
1260
- loadDocByIdIfNotAlreadyLoaded(logger: Logger, docId: YDocId): Promise<Y.Doc>;
1261
- load(logger: Logger): Promise<void>;
1262
- /**
1263
- * Unloads the Yjs documents from memory.
1264
- */
1265
- unload(): void;
1260
+ };
1266
1261
  private _getOrPutLastSnapshot;
1267
1262
  private _putLastSnapshot;
1268
1263
  private _compactYJSUpdates;
@@ -1292,7 +1287,6 @@ declare class YjsStorage {
1292
1287
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
1293
1288
  */
1294
1289
 
1295
- type LoadingState = "initial" | "loading" | "loaded";
1296
1290
  type ActorID = Brand<number, "ActorID">;
1297
1291
  /** Number of milliseconds since Unix epoch. */
1298
1292
  type Millis = Brand<number, "Millis">;
@@ -1401,14 +1395,8 @@ type RoomOptions<SM, CM extends JsonObject, C> = {
1401
1395
  };
1402
1396
  /** Called whenever the server acknowledged a ping with a pong */
1403
1397
  onDidPong?: (ctx?: C) => void | Promise<void>;
1404
- /** Called before the room is attempted to be loaded */
1405
- onRoomWillLoad?: (ctx?: C) => void | Promise<void>;
1406
- /** Called right after the room's contents are loaded, but before any session has been started */
1407
- onRoomDidLoad?: (ctx?: C) => void | Promise<void>;
1408
1398
  /** Called right before the room is attempted to be unloaded. Synchronous. May throw to abort the unloading. */
1409
1399
  onRoomWillUnload?: (ctx?: C) => void;
1410
- /** Called right after the room has been unloaded from memory. Synchronous. */
1411
- onRoomDidUnload?: (ctx?: C) => void;
1412
1400
  /** Called when a new user entered the room. */
1413
1401
  onSessionDidStart?: (session: BrowserSession<SM, CM>, ctx?: C) => void | Promise<void>;
1414
1402
  /** Called when a user left the room. */
@@ -1444,7 +1432,6 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1444
1432
  #private;
1445
1433
  meta: RM;
1446
1434
  readonly driver: IStorageDriver;
1447
- logger: Logger;
1448
1435
  /**
1449
1436
  * While a room is in "maintenance mode", all WebSocket connections to the
1450
1437
  * room should be rejected until it's pulled out of maintenance mode again.
@@ -1454,18 +1441,18 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1454
1441
  * init-storage, storage-reset, etc.) cannot interfere with one another.
1455
1442
  */
1456
1443
  private readonly _maintenanceMode;
1457
- private _loadData$;
1458
- private _data;
1444
+ private _storage;
1445
+ private _yjsStorage;
1446
+ readonly mutex: Mutex;
1447
+ get storage(): Storage;
1448
+ get yjsStorage(): YjsStorage;
1459
1449
  private _qsize;
1460
1450
  private readonly sessions;
1461
1451
  private readonly hooks;
1462
1452
  constructor(meta: RM, options?: RoomOptions<SM, CM, C>);
1463
- get loadingState(): LoadingState;
1453
+ get logger(): Logger;
1454
+ addLoggerContext(attrs: JsonObject): void;
1464
1455
  get numSessions(): number;
1465
- get storage(): Storage;
1466
- get yjsStorage(): YjsStorage;
1467
- get mutex(): Mutex;
1468
- private get data();
1469
1456
  /**
1470
1457
  * Returns true if the room is currently in maintenance mode.
1471
1458
  * When in maintenance mode, callers should refuse new WebSocket connections.
@@ -1476,17 +1463,11 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1476
1463
  * If the room is already in maintenance mode, throws E_ALREADY_LOCKED
1477
1464
  * immediately instead of queuing the request.
1478
1465
  */
1479
- runInMaintenanceMode<T>(callback: () => Promise<T>): Promise<T>;
1480
- /**
1481
- * Initializes the Room, so it's ready to start accepting connections. Safe
1482
- * to call multiple times. After awaiting `room.load()` the Room is ready to
1483
- * be used.
1484
- */
1485
- load(ctx?: C): Promise<void>;
1466
+ runInMaintenanceMode<T>(callback: () => T | Promise<T>): Promise<T>;
1486
1467
  /**
1487
- * Releases the currently-loaded storage tree from worker memory, freeing it
1488
- * up to be garbage collected. The next time a user will join the room, the
1489
- * room will be reloaded from storage.
1468
+ * Releases the currently-loaded storage tree and Yjs documents from worker
1469
+ * memory, freeing them up to be garbage collected. The next time the room
1470
+ * is used, fresh instances will lazily be created.
1490
1471
  */
1491
1472
  unload(ctx?: C): void;
1492
1473
  /**
@@ -1500,11 +1481,11 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1500
1481
  * connection is established. If the socket is never established, this
1501
1482
  * unused Ticket will simply get garbage collected.
1502
1483
  */
1503
- createTicket(options?: CreateTicketOptions<SM, CM>): Promise<Ticket<SM, CM>>;
1504
- createBackendSession_experimental(): Promise<[
1484
+ createTicket(options?: CreateTicketOptions<SM, CM>): Ticket<SM, CM>;
1485
+ createBackendSession_experimental(): [
1505
1486
  session: BackendSession,
1506
1487
  outgoingMessages: jstring<ServerMsg>[]
1507
- ]>;
1488
+ ];
1508
1489
  /**
1509
1490
  * Restores the given sessions as the Room server's session list. Can only be
1510
1491
  * called as long as there are no existing sessions.
@@ -1531,7 +1512,7 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1531
1512
  * - Sends a ROOM_STATE message to the socket.
1532
1513
  * - Broadcasts a USER_JOINED message to all other sessions in the room.
1533
1514
  */
1534
- startBrowserSession(ticket: Ticket<SM, CM>, socket: IServerWebSocket, ctx?: C, defer?: (promise: Promise<void>) => void): Promise<void>;
1515
+ startBrowserSession(ticket: Ticket<SM, CM>, socket: IServerWebSocket, ctx?: C, defer?: (promise: Promise<void>) => void): void;
1535
1516
  /**
1536
1517
  * Unregisters the BrowserSession for the given actor. Call this when the socket has
1537
1518
  * been closed from the client's end.
@@ -1587,46 +1568,46 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1587
1568
  * Upsert a leased session. Creates a new session if it doesn't exist (or is expired),
1588
1569
  * or updates an existing session with merged presence.
1589
1570
  */
1590
- upsertLeasedSession(sessionId: string, presence: JsonObject, ttl: number, info: IUserInfo, ctx?: C, defer?: (promise: Promise<void>) => void): Promise<void>;
1571
+ upsertLeasedSession(sessionId: string, presence: JsonObject, ttl: number, info: IUserInfo, ctx?: C, defer?: (promise: Promise<void>) => void): void;
1591
1572
  /**
1592
1573
  * List all server sessions. As a side effect, it will delete expired sessions.
1593
1574
  */
1594
- listLeasedSessions(ctx?: C, defer?: (promise: Promise<void>) => void): Promise<LeasedSession[]>;
1575
+ listLeasedSessions(ctx?: C, defer?: (promise: Promise<void>) => void): LeasedSession[];
1595
1576
  /**
1596
1577
  * Delete a server session and broadcast USER_LEFT to all sessions.
1597
1578
  */
1598
- deleteLeasedSession(session: LeasedSession, ctx?: C, defer?: (promise: Promise<void>) => void): Promise<void>;
1579
+ deleteLeasedSession(session: LeasedSession, ctx?: C, defer?: (promise: Promise<void>) => void): void;
1599
1580
  /**
1600
1581
  * Delete all server sessions and broadcast USER_LEFT to all sessions.
1601
1582
  */
1602
- deleteAllLeasedSessions(ctx?: C, defer?: (promise: Promise<void>) => void): Promise<void>;
1583
+ deleteAllLeasedSessions(ctx?: C, defer?: (promise: Promise<void>) => void): void;
1603
1584
  /**
1604
1585
  * List feeds with pagination and filtering.
1605
1586
  */
1606
- listFeeds(options?: ListFeedsOptions): Promise<ListFeedsResult>;
1587
+ listFeeds(options?: ListFeedsOptions): ListFeedsResult;
1607
1588
  /**
1608
1589
  * Get a specific feed by feed ID.
1609
1590
  */
1610
- getFeed(feedId: string): Promise<Feed | undefined>;
1591
+ getFeed(feedId: string): Feed | undefined;
1611
1592
  /**
1612
1593
  * Create a new feed.
1613
1594
  * If timestamp is not provided, current server time is used.
1614
1595
  */
1615
1596
  createFeed(feed: Omit<Feed, "createdAt" | "updatedAt"> & {
1616
1597
  timestamp?: number;
1617
- }): Promise<Feed>;
1598
+ }): Feed;
1618
1599
  /**
1619
1600
  * Update a feed's metadata.
1620
1601
  */
1621
- updateFeedMetadata(feedId: string, metadata: Json): Promise<void>;
1602
+ updateFeedMetadata(feedId: string, metadata: Json): void;
1622
1603
  /**
1623
1604
  * Delete a feed.
1624
1605
  */
1625
- deleteFeed(feedId: string): Promise<void>;
1606
+ deleteFeed(feedId: string): void;
1626
1607
  /**
1627
1608
  * List feed messages for a feed with pagination.
1628
1609
  */
1629
- listFeedMessages(feedId: string, options?: ListFeedMessagesOptions): Promise<ListFeedMessagesResult>;
1610
+ listFeedMessages(feedId: string, options?: ListFeedMessagesOptions): ListFeedMessagesResult;
1630
1611
  /**
1631
1612
  * Add a message to a feed.
1632
1613
  * If message id is not provided, a unique ID is automatically generated.
@@ -1634,16 +1615,16 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1634
1615
  */
1635
1616
  addFeedMessage(feedId: string, message: Omit<FeedMessage, "id" | "createdAt" | "updatedAt"> & Partial<Pick<FeedMessage, "id">> & {
1636
1617
  timestamp?: number;
1637
- }): Promise<FeedMessage>;
1618
+ }): FeedMessage;
1638
1619
  /**
1639
1620
  * Update a feed message's data.
1640
1621
  * Returns the updated message.
1641
1622
  */
1642
- updateFeedMessage(feedId: string, messageId: string, data: Json, timestamp?: number): Promise<FeedMessage>;
1623
+ updateFeedMessage(feedId: string, messageId: string, data: Json, timestamp?: number): FeedMessage;
1643
1624
  /**
1644
1625
  * Delete a feed message.
1645
1626
  */
1646
- deleteFeedMessage(feedId: string, messageId: string): Promise<void>;
1627
+ deleteFeedMessage(feedId: string, messageId: string): void;
1647
1628
  /**
1648
1629
  * Will send the given ServerMsg through all Session, except the Session
1649
1630
  * where the message originates from.
@@ -1653,13 +1634,10 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
1653
1634
  * Will broadcast the given ServerMsg to all Sessions in the Room.
1654
1635
  */
1655
1636
  sendToAll(serverMsg: ServerMsg | readonly ServerMsg[], ctx?: C, defer?: (promise: Promise<void>) => void): void;
1656
- private _loadStorage;
1657
- private _loadYjsStorage;
1658
- private _load;
1659
1637
  /**
1660
1638
  * Returns a new, unique, actor ID.
1661
1639
  */
1662
- private getNextActor;
1640
+ getNextActor(): ActorID;
1663
1641
  /**
1664
1642
  * Iterates over all *other* Sessions and their session keys.
1665
1643
  */
@@ -1716,32 +1694,8 @@ declare function isLeasedSessionExpired(leasedSession: LeasedSession): boolean;
1716
1694
  * You should have received a copy of the GNU Affero General Public License
1717
1695
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
1718
1696
  */
1719
- /**
1720
- * Given a promise or promise factory, returns a 2-tuple of success or failure.
1721
- * This pattern avoids having to build deeply nested try / catch clauses, where
1722
- * success variables need to be defined as a `let` outside of the `try` block.
1723
- *
1724
- * Turns:
1725
- *
1726
- * let result;
1727
- * try {
1728
- * result = await doSomething();
1729
- * } catch (error) {
1730
- * // do something with error
1731
- * }
1732
- *
1733
- * doAnotherThing(result);
1734
- *
1735
- * Into:
1736
- *
1737
- * const [result, error] = await tryCatch(doSomething());
1738
- * if (error) {
1739
- * // do something with error
1740
- * }
1741
- * doAnotherThing(result);
1742
- *
1743
- */
1744
- declare function tryCatch<T, E = Error>(promise: Promise<T> | (() => Promise<T>) | (() => T)): Promise<[T, undefined] | [undefined, E]>;
1697
+ declare function tryCatch<T, E = Error>(promise: PromiseLike<T> | (() => PromiseLike<T>)): Promise<[T, undefined] | [undefined, E]>;
1698
+ declare function tryCatch<T, E = Error>(fn: () => T): [T, undefined] | [undefined, E];
1745
1699
 
1746
1700
  /**
1747
1701
  * Copyright (c) Liveblocks Inc.
@@ -1924,6 +1878,7 @@ declare class UniqueMap<K, V, UK> extends Map<K, V> {
1924
1878
  declare class InMemoryDriver implements IStorageDriver {
1925
1879
  private _nextActor;
1926
1880
  private _nodes;
1881
+ private _nodesApi?;
1927
1882
  private _metadb;
1928
1883
  private _ydb;
1929
1884
  private _leasedSessions;
@@ -1934,32 +1889,53 @@ declare class InMemoryDriver implements IStorageDriver {
1934
1889
  initialNodes?: Iterable<[string, SerializedCrdt]>;
1935
1890
  });
1936
1891
  raw_iter_nodes(): MapIterator<[string, SerializedCrdt]>;
1892
+ reinitialize(): void;
1937
1893
  /** Deletes all nodes and replaces them with the given document. */
1938
1894
  DANGEROUSLY_reset_nodes(doc: PlainLsonObject): void;
1939
- get_meta(key: string): Promise<Json | undefined>;
1940
- put_meta(key: string, value: Json): Promise<void>;
1941
- delete_meta(key: string): Promise<void>;
1942
- list_leased_sessions(): Promise<MapIterator<[string, LeasedSession]>>;
1943
- get_leased_session(sessionId: string): Promise<LeasedSession | undefined>;
1944
- put_leased_session(session: LeasedSession): Promise<void>;
1945
- delete_leased_session(sessionId: string): Promise<void>;
1895
+ get_meta(key: string): Json | undefined;
1896
+ put_meta(key: string, value: Json): void;
1897
+ delete_meta(key: string): void;
1898
+ list_leased_sessions(): MapIterator<[string, LeasedSession]>;
1899
+ get_leased_session(sessionId: string): LeasedSession | undefined;
1900
+ put_leased_session(session: LeasedSession): void;
1901
+ delete_leased_session(sessionId: string): void;
1946
1902
  takeRowsWritten(): number;
1947
- list_feeds(options?: ListFeedsOptions): Promise<ListFeedsResult>;
1948
- get_feed(feedId: string): Promise<Feed | undefined>;
1949
- create_feed(feed: Feed): Promise<void>;
1950
- update_feed_metadata(feedId: string, metadata: Json): Promise<void>;
1951
- delete_feed(feedId: string): Promise<void>;
1952
- list_feed_messages(feedId: string, options?: ListFeedMessagesOptions): Promise<ListFeedMessagesResult>;
1953
- add_feed_message(feedId: string, message: FeedMessage): Promise<void>;
1954
- update_feed_message(feedId: string, messageId: string, data: Json, timestamp?: number): Promise<FeedMessage>;
1955
- delete_feed_message(feedId: string, messageId: string): Promise<void>;
1903
+ list_feeds(options?: ListFeedsOptions): ListFeedsResult;
1904
+ get_feed(feedId: string): Feed | undefined;
1905
+ create_feed(feed: Feed): void;
1906
+ update_feed_metadata(feedId: string, metadata: Json): void;
1907
+ delete_feed(feedId: string): void;
1908
+ list_feed_messages(feedId: string, options?: ListFeedMessagesOptions): ListFeedMessagesResult;
1909
+ add_feed_message(feedId: string, message: FeedMessage): void;
1910
+ update_feed_message(feedId: string, messageId: string, data: Json, timestamp?: number): FeedMessage;
1911
+ delete_feed_message(feedId: string, messageId: string): void;
1956
1912
  next_actor(): number;
1957
- iter_y_updates(docId: YDocId): Promise<IterableIterator<[string, Uint8Array<ArrayBufferLike>]>>;
1958
- write_y_updates(docId: YDocId, key: string, data: Uint8Array): Promise<void>;
1959
- delete_y_updates(docId: YDocId, keys: string[]): Promise<void>;
1913
+ iter_y_updates(docId: YDocId): IterableIterator<[string, Uint8Array<ArrayBufferLike>]>;
1914
+ write_y_updates(docId: YDocId, key: string, data: Uint8Array): void;
1915
+ delete_y_updates(docId: YDocId, keys: string[]): void;
1960
1916
  /** @private Only use this in unit tests, never in production. */
1961
- DANGEROUSLY_wipe_all_y_updates(): Promise<void>;
1962
- load_nodes_api(): IStorageDriverNodeAPI;
1917
+ DANGEROUSLY_wipe_all_y_updates(): void;
1918
+ /**
1919
+ * The lazily-built node API. Building it ensures the root node exists and
1920
+ * constructs the reverse-lookup index. Invalidated by
1921
+ * DANGEROUSLY_reset_nodes(), after which the next access rebuilds it.
1922
+ */
1923
+ private get loadedApi();
1924
+ get_node(id: string): SerializedCrdt | undefined;
1925
+ iter_nodes(): NodeStream$1;
1926
+ iter_nodes_optimized(): Iterable<jstring<CompactNode>>;
1927
+ has_node(id: string): boolean;
1928
+ get_child_at(parentId: string, parentKey: string): string | undefined;
1929
+ has_child_at(parentId: string, parentKey: string): boolean;
1930
+ get_next_sibling(parentId: string, pos: Pos): Pos | undefined;
1931
+ get_last_sibling(parentId: string): Pos | undefined;
1932
+ set_child(id: string, node: SerializedChild, allowOverwrite?: boolean): void;
1933
+ move_sibling(id: string, newPos: Pos): void;
1934
+ delete_node(id: string): void;
1935
+ delete_child_key(id: string, key: string): void;
1936
+ set_object_data(id: string, data: JsonObject, allowOverwrite?: boolean): void;
1937
+ get_snapshot(lowMemory?: boolean): IReadableSnapshot;
1938
+ private _loadNodesApi;
1963
1939
  }
1964
1940
 
1965
- export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IStorageDriverNodeAPI, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, type LoadingState, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos, ProtocolVersion, ROOT_YDOC_ID, Room, type SessionKey, type Ticket, UniqueMap, type UpdateFeedClientMsg, type UpdateFeedMessageClientMsg, type YDocId, type YUpdate, type YVector, ackIgnoredOp, clientMsgDecoder, concatUint8Arrays, feedFailureServerMsg, feedMetadataIdDecoder, feedMetadataUpdateDecoder, feedRequestFailed, fetchFeedsMetadataFilterDecoder, guidDecoder, isLeasedSessionExpired, jsonObjectYolo, jsonYolo, type jstring, makeInMemorySnapshot, makeMetadataDB, mapFeedError, optionalFeedMetadataDecoder, plainLsonToNodeStream, protocolVersionDecoder, quote, serialize as serializeServerMsg, snapshotToLossyJson_eager, snapshotToLossyJson_lazy, snapshotToNodeStream, snapshotToPlainLson_eager, snapshotToPlainLson_lazy, Storage as test_only__Storage, YjsStorage as test_only__YjsStorage, transientClientMsgDecoder, tryCatch };
1941
+ export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos, ProtocolVersion, ROOT_YDOC_ID, Room, type SessionKey, type Ticket, UniqueMap, type UpdateFeedClientMsg, type UpdateFeedMessageClientMsg, type YDocId, type YUpdate, type YVector, ackIgnoredOp, clientMsgDecoder, concatUint8Arrays, feedFailureServerMsg, feedMetadataIdDecoder, feedMetadataUpdateDecoder, feedRequestFailed, fetchFeedsMetadataFilterDecoder, guidDecoder, isLeasedSessionExpired, jsonObjectYolo, jsonYolo, type jstring, makeInMemorySnapshot, makeMetadataDB, mapFeedError, optionalFeedMetadataDecoder, plainLsonToNodeStream, protocolVersionDecoder, quote, serialize as serializeServerMsg, snapshotToLossyJson_eager, snapshotToLossyJson_lazy, snapshotToNodeStream, snapshotToPlainLson_eager, snapshotToPlainLson_lazy, Storage as test_only__Storage, YjsStorage as test_only__YjsStorage, transientClientMsgDecoder, tryCatch };