@liveblocks/core 3.22.0 → 3.23.0-exp1

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.ts CHANGED
@@ -334,6 +334,26 @@ type ContextualPromptContext = {
334
334
  afterSelection: string;
335
335
  };
336
336
 
337
+ /**
338
+ * Use this symbol to brand an object property as internal.
339
+ *
340
+ * @example
341
+ * Object.defineProperty(
342
+ * {
343
+ * public,
344
+ * [kInternal]: {
345
+ * private
346
+ * },
347
+ * },
348
+ * kInternal,
349
+ * {
350
+ * enumerable: false,
351
+ * }
352
+ * );
353
+ */
354
+ declare const kInternal: unique symbol;
355
+ declare const kStorageUpdateSource: unique symbol;
356
+
337
357
  declare const brand: unique symbol;
338
358
  type Brand<T, TBrand extends string> = T & {
339
359
  [brand]: TBrand;
@@ -419,6 +439,8 @@ declare const OpCode: Readonly<{
419
439
  DELETE_OBJECT_KEY: 6;
420
440
  CREATE_MAP: 7;
421
441
  CREATE_REGISTER: 8;
442
+ CREATE_TEXT: 9;
443
+ UPDATE_TEXT: 10;
422
444
  }>;
423
445
  declare namespace OpCode {
424
446
  type INIT = typeof OpCode.INIT;
@@ -430,13 +452,48 @@ declare namespace OpCode {
430
452
  type DELETE_OBJECT_KEY = typeof OpCode.DELETE_OBJECT_KEY;
431
453
  type CREATE_MAP = typeof OpCode.CREATE_MAP;
432
454
  type CREATE_REGISTER = typeof OpCode.CREATE_REGISTER;
455
+ type CREATE_TEXT = typeof OpCode.CREATE_TEXT;
456
+ type UPDATE_TEXT = typeof OpCode.UPDATE_TEXT;
433
457
  }
458
+ type TextAttributes = JsonObject;
459
+ /**
460
+ * A single segment in a {@link LiveTextData} document.
461
+ *
462
+ * @example
463
+ * ["Hello world"]
464
+ * ["Hello ", { bold: true }]
465
+ */
466
+ type LiveTextSegment = [text: string] | [text: string, attributes: TextAttributes];
467
+ /**
468
+ * Serialized form of a {@link LiveText} document: an ordered list of text
469
+ * segments with optional inline attributes.
470
+ *
471
+ * @example
472
+ * [["Hello world"]]
473
+ * [["Hello ", { bold: true }], ["world"]]
474
+ */
475
+ type LiveTextData = LiveTextSegment[];
476
+ type TextOperation = {
477
+ type: "insert";
478
+ index: number;
479
+ text: string;
480
+ attributes?: TextAttributes;
481
+ } | {
482
+ type: "delete";
483
+ index: number;
484
+ length: number;
485
+ } | {
486
+ type: "format";
487
+ index: number;
488
+ length: number;
489
+ attributes: JsonObject;
490
+ };
434
491
  /**
435
492
  * These operations are the payload for {@link UpdateStorageServerMsg} messages
436
493
  * only.
437
494
  */
438
- type Op = CreateOp | UpdateObjectOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
439
- type CreateOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp;
495
+ type Op = CreateOp | UpdateObjectOp | UpdateTextOp | DeleteCrdtOp | SetParentKeyOp | DeleteObjectKeyOp;
496
+ type CreateOp = CreateObjectOp | CreateRegisterOp | CreateMapOp | CreateListOp | CreateTextOp;
440
497
  type UpdateObjectOp = {
441
498
  readonly opId?: string;
442
499
  readonly id: string;
@@ -481,6 +538,26 @@ type CreateRegisterOp = {
481
538
  readonly intent?: "set" | "push";
482
539
  readonly deletedId?: string;
483
540
  };
541
+ type CreateTextOp = {
542
+ readonly opId?: string;
543
+ readonly id: string;
544
+ readonly type: OpCode.CREATE_TEXT;
545
+ readonly parentId: string;
546
+ readonly parentKey: string;
547
+ readonly data: LiveTextData;
548
+ readonly version: number;
549
+ readonly intent?: "set" | "push";
550
+ readonly deletedId?: string;
551
+ };
552
+ type UpdateTextOp = {
553
+ readonly opId?: string;
554
+ readonly id: string;
555
+ readonly type: OpCode.UPDATE_TEXT;
556
+ readonly baseVersion: number;
557
+ readonly version?: number;
558
+ readonly ops: TextOperation[];
559
+ readonly metadata?: JsonObject;
560
+ };
484
561
  type DeleteCrdtOp = {
485
562
  readonly opId?: string;
486
563
  readonly id: string;
@@ -609,15 +686,17 @@ declare const CrdtType: Readonly<{
609
686
  LIST: 1;
610
687
  MAP: 2;
611
688
  REGISTER: 3;
689
+ TEXT: 4;
612
690
  }>;
613
691
  declare namespace CrdtType {
614
692
  type OBJECT = typeof CrdtType.OBJECT;
615
693
  type LIST = typeof CrdtType.LIST;
616
694
  type MAP = typeof CrdtType.MAP;
617
695
  type REGISTER = typeof CrdtType.REGISTER;
696
+ type TEXT = typeof CrdtType.TEXT;
618
697
  }
619
698
  type SerializedCrdt = SerializedRootObject | SerializedChild;
620
- type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister;
699
+ type SerializedChild = SerializedObject | SerializedList | SerializedMap | SerializedRegister | SerializedText;
621
700
  type SerializedRootObject = {
622
701
  readonly type: CrdtType.OBJECT;
623
702
  readonly data: JsonObject;
@@ -646,13 +725,21 @@ type SerializedRegister = {
646
725
  readonly parentKey: string;
647
726
  readonly data: Json;
648
727
  };
728
+ type SerializedText = {
729
+ readonly type: CrdtType.TEXT;
730
+ readonly parentId: string;
731
+ readonly parentKey: string;
732
+ readonly data: LiveTextData;
733
+ readonly version: number;
734
+ };
649
735
  type StorageNode = RootStorageNode | ChildStorageNode;
650
- type ChildStorageNode = ObjectStorageNode | ListStorageNode | MapStorageNode | RegisterStorageNode;
736
+ type ChildStorageNode = ObjectStorageNode | ListStorageNode | MapStorageNode | RegisterStorageNode | TextStorageNode;
651
737
  type RootStorageNode = [id: "root", value: SerializedRootObject];
652
738
  type ObjectStorageNode = [id: string, value: SerializedObject];
653
739
  type ListStorageNode = [id: string, value: SerializedList];
654
740
  type MapStorageNode = [id: string, value: SerializedMap];
655
741
  type RegisterStorageNode = [id: string, value: SerializedRegister];
742
+ type TextStorageNode = [id: string, value: SerializedText];
656
743
  type NodeMap = Map<string, SerializedCrdt>;
657
744
  type NodeStream = Iterable<StorageNode>;
658
745
  declare function isRootStorageNode(node: StorageNode): node is RootStorageNode;
@@ -660,8 +747,9 @@ declare function isObjectStorageNode(node: StorageNode): node is RootStorageNode
660
747
  declare function isListStorageNode(node: StorageNode): node is ListStorageNode;
661
748
  declare function isMapStorageNode(node: StorageNode): node is MapStorageNode;
662
749
  declare function isRegisterStorageNode(node: StorageNode): node is RegisterStorageNode;
750
+ declare function isTextStorageNode(node: StorageNode): node is TextStorageNode;
663
751
  type CompactNode = CompactRootNode | CompactChildNode;
664
- type CompactChildNode = CompactObjectNode | CompactListNode | CompactMapNode | CompactRegisterNode;
752
+ type CompactChildNode = CompactObjectNode | CompactListNode | CompactMapNode | CompactRegisterNode | CompactTextNode;
665
753
  type CompactRootNode = readonly [id: "root", data: JsonObject];
666
754
  type CompactObjectNode = readonly [
667
755
  id: string,
@@ -689,6 +777,14 @@ type CompactRegisterNode = readonly [
689
777
  parentKey: string,
690
778
  data: Json
691
779
  ];
780
+ type CompactTextNode = readonly [
781
+ id: string,
782
+ type: CrdtType.TEXT,
783
+ parentId: string,
784
+ parentKey: string,
785
+ data: LiveTextData,
786
+ version: number
787
+ ];
692
788
  declare function compactNodesToNodeStream(compactNodes: CompactNode[]): NodeStream;
693
789
  declare function nodeStreamToCompactNodes(nodes: NodeStream): Iterable<CompactNode>;
694
790
 
@@ -854,16 +950,224 @@ declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
854
950
  clone(): LiveObject<O>;
855
951
  }
856
952
 
953
+ /**
954
+ * The position of the ops being transformed relative to the ops they are
955
+ * transformed over, in the final (server-serialized) timeline:
956
+ *
957
+ * - "after": the transformed ops will be ordered after the `over` ops. Used
958
+ * when rebasing a not-yet-accepted op over already-accepted ops. On
959
+ * same-index insert ties, the transformed op shifts right (the earlier op
960
+ * stays left), and conflicting format attributes are kept (they will
961
+ * overwrite, since the op applies later).
962
+ * - "before": the transformed ops were ordered before the `over` ops. Used
963
+ * when applying an accepted remote op on top of locally-pending ops. On
964
+ * same-index insert ties, the transformed op stays left, and conflicting
965
+ * format attributes are dropped on overlapping ranges (the later `over` op
966
+ * wins).
967
+ */
968
+ type TransformOrder = "before" | "after";
969
+ /**
970
+ * Transform `ops` over `over` (see {@link transformTextOperationsX}),
971
+ * returning only the transformed `ops`.
972
+ */
973
+ declare function transformTextOperations(ops: readonly TextOperation[], over: readonly TextOperation[], order: TransformOrder): TextOperation[];
974
+ declare function applyLiveTextOperations(data: LiveTextData, ops: readonly TextOperation[]): LiveTextData;
975
+
976
+ type LiveTextAttributes = TextAttributes;
977
+ type LiveTextAttributesPatch = JsonObject;
978
+
979
+ type LiveTextChange = {
980
+ /** Text was inserted at {@link LiveTextChange.index}. */
981
+ readonly type: "insert";
982
+ readonly index: number;
983
+ readonly text: string;
984
+ readonly attributes?: TextAttributes;
985
+ } | {
986
+ /** Text was deleted starting at {@link LiveTextChange.index}. */
987
+ readonly type: "delete";
988
+ readonly index: number;
989
+ readonly length: number;
990
+ readonly deletedText: string;
991
+ } | {
992
+ /** Inline attributes were updated on a range of text. */
993
+ readonly type: "format";
994
+ readonly index: number;
995
+ readonly length: number;
996
+ readonly attributes: LiveTextAttributesPatch;
997
+ };
998
+ /** Notification payload when a {@link LiveText} node changes. */
999
+ type LiveTextUpdates = {
1000
+ type: "LiveText";
1001
+ node: LiveText;
1002
+ version: number;
1003
+ updates: LiveTextChange[];
1004
+ };
1005
+ /**
1006
+ * @private
1007
+ *
1008
+ * Private methods on a LiveText node. As a user of Liveblocks, NEVER USE ANY
1009
+ * OF THESE DIRECTLY, because bad things will probably happen if you do.
1010
+ */
1011
+ type PrivateLiveTextApi = PrivateLiveNodeApi & {
1012
+ /**
1013
+ * Encode a local-document index into server-confirmed coordinates suitable
1014
+ * for broadcasting to peers via presence or any other side channel. Pair
1015
+ * the result with {@link LiveText.version} at the same instant when
1016
+ * sending.
1017
+ */
1018
+ encodeIndex(localIndex: number): number;
1019
+ /**
1020
+ * Decode an `(index, fromVersion)` pair from a peer into an offset in this
1021
+ * LiveText's current local document.
1022
+ */
1023
+ decodeIndex(index: number, fromVersion: number): number | null;
1024
+ };
1025
+
1026
+ /**
1027
+ * LiveText is a collaborative rich-text primitive built on server-ordered
1028
+ * operational transformation.
1029
+ *
1030
+ * Use it to store plain text with optional inline formatting attributes in
1031
+ * Liveblocks Storage. Each document is a flat sequence of text segments; it
1032
+ * cannot contain child Storage structures.
1033
+ *
1034
+ * Outbound model (one-in-flight): at most one UpdateTextOp per node is
1035
+ * awaiting server acknowledgement at any time. Local edits made while an op
1036
+ * is in flight are queued and sent (composed into a single op) once the ack
1037
+ * arrives. This guarantees every wire op is expressed against server-state
1038
+ * coordinates, so the server can transform it over exactly the (foreign)
1039
+ * ops the client hadn't seen — never over the client's own pending ops.
1040
+ *
1041
+ * Inbound model: accepted remote ops are transformed over the local pending
1042
+ * ops before being applied ("before" order: the accepted op wins ties), and
1043
+ * the pending ops are re-expressed over the remote op in turn ("after"
1044
+ * order), keeping them in server coordinates at all times.
1045
+ *
1046
+ * @example
1047
+ * const text = new LiveText("Hello");
1048
+ * text.insert(5, " world");
1049
+ * text.format(0, 5, { bold: true });
1050
+ *
1051
+ * // [["Hello", { bold: true }], [" world"]]
1052
+ * text.toJSON();
1053
+ *
1054
+ * @example
1055
+ * // Use in Storage
1056
+ * declare global {
1057
+ * interface Liveblocks {
1058
+ * Storage: { document: LiveText };
1059
+ * }
1060
+ * }
1061
+ *
1062
+ * const { root } = await room.getStorage();
1063
+ * root.get("document").replace(0, root.get("document").length, "Updated");
1064
+ */
1065
+ declare class LiveText extends AbstractCrdt {
1066
+ #private;
1067
+ /**
1068
+ * @private
1069
+ *
1070
+ * Private methods and variables used in the core internals, but as a user
1071
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
1072
+ * will probably happen if you do.
1073
+ */
1074
+ readonly [kInternal]: PrivateLiveTextApi;
1075
+ /**
1076
+ * Creates a new LiveText document.
1077
+ *
1078
+ * @param textOrData Initial plain text, or an array of `[text]` /
1079
+ * `[text, attributes]` segments. Defaults to an empty document.
1080
+ *
1081
+ * @example
1082
+ * new LiveText();
1083
+ * new LiveText("Hello world");
1084
+ * new LiveText([["Hello ", { bold: true }], ["world"]]);
1085
+ */
1086
+ constructor(textOrData?: string | LiveTextData, version?: number);
1087
+ get version(): number;
1088
+ get length(): number;
1089
+ /**
1090
+ * Inserts text at the given index.
1091
+ *
1092
+ * @param index Character index at which to insert. Values outside the
1093
+ * document range are clipped.
1094
+ * @param text Text to insert.
1095
+ * @param attributes Optional inline attributes for the inserted text.
1096
+ *
1097
+ * @example
1098
+ * const text = new LiveText("Hello");
1099
+ * text.insert(5, " world");
1100
+ * text.insert(0, "Say: ", { italic: true });
1101
+ */
1102
+ insert(index: number, text: string, attributes?: TextAttributes): void;
1103
+ /**
1104
+ * Deletes `length` characters starting at `index`.
1105
+ *
1106
+ * @example
1107
+ * const text = new LiveText("Hello world");
1108
+ * text.delete(5, 6); // "Hello"
1109
+ */
1110
+ delete(index: number, length: number): void;
1111
+ /**
1112
+ * Replaces a range of text with new text.
1113
+ *
1114
+ * @example
1115
+ * const text = new LiveText("Hello world");
1116
+ * text.replace(0, 5, "Hi"); // "Hi world"
1117
+ */
1118
+ replace(index: number, length: number, text: string, attributes?: TextAttributes): void;
1119
+ /**
1120
+ * Applies or removes inline attributes on a range of text.
1121
+ *
1122
+ * Set an attribute to `null` to remove it from the range.
1123
+ *
1124
+ * @example
1125
+ * const text = new LiveText("Hello world");
1126
+ * text.format(0, 5, { bold: true });
1127
+ * text.format(0, 5, { bold: null });
1128
+ */
1129
+ format(index: number, length: number, attributes: LiveTextAttributesPatch): void;
1130
+ /** Returns the plain text content without attributes. Equivalent to joining the text from each segment in {@link LiveText.toJSON}. */
1131
+ toString(): string;
1132
+ /**
1133
+ * Returns a JSON-compatible snapshot of the document as a {@link LiveTextData}
1134
+ * array.
1135
+ *
1136
+ * @example
1137
+ * new LiveText([["Hello ", { bold: true }], ["world"]]).toJSON();
1138
+ * // [["Hello ", { bold: true }], ["world"]]
1139
+ */
1140
+ toJSON(): LiveTextData;
1141
+ clone(): LiveText;
1142
+ }
1143
+
857
1144
  type StorageCallback = (updates: StorageUpdate[]) => void;
858
1145
  type LiveMapUpdate = LiveMapUpdates<string, Lson>;
859
1146
  type LiveObjectUpdate = LiveObjectUpdates<LsonObject>;
860
1147
  type LiveListUpdate = LiveListUpdates<Lson>;
1148
+ type LiveTextUpdate = LiveTextUpdates;
1149
+ type StorageUpdateSource = {
1150
+ origin: "remote";
1151
+ } | {
1152
+ origin: "local";
1153
+ via: "mutation";
1154
+ } | {
1155
+ origin: "local";
1156
+ via: "history";
1157
+ action: "undo" | "redo";
1158
+ };
861
1159
  /**
862
1160
  * The payload of notifications sent (in-client) when LiveStructures change.
863
1161
  * Messages of this kind are not originating from the network, but are 100%
864
1162
  * in-client.
1163
+ *
1164
+ * Updates delivered through `room.subscribe` may carry
1165
+ * `[kStorageUpdateSource]` to distinguish where a mutation came from.
1166
+ * Undo/redo replays use `via: "history"` with `action: "undo" | "redo"`.
865
1167
  */
866
- type StorageUpdate = LiveMapUpdate | LiveObjectUpdate | LiveListUpdate;
1168
+ type StorageUpdate = (LiveMapUpdate | LiveObjectUpdate | LiveListUpdate | LiveTextUpdate) & {
1169
+ [kStorageUpdateSource]?: StorageUpdateSource;
1170
+ };
867
1171
 
868
1172
  /**
869
1173
  * Read-only query surface over {@link UnacknowledgedOps}, handed to CRDTs so
@@ -889,6 +1193,27 @@ interface ReadonlyUnacknowledgedOps {
889
1193
  isPossiblyStored(opId: string): boolean;
890
1194
  }
891
1195
 
1196
+ type DispatchOptions = {
1197
+ /**
1198
+ * Whether this dispatch should clear the redo stack. Defaults to true when
1199
+ * any forward ops are included (a fresh local mutation), false otherwise.
1200
+ * LiveText uses this to dispatch queued ops after an acknowledgement
1201
+ * (which should not clear redo), and to register fresh local edits that
1202
+ * don't carry wire ops yet (which should).
1203
+ */
1204
+ clearRedoStack?: boolean;
1205
+ };
1206
+ /**
1207
+ * Private methods on any Liveblocks CRDT node. As a user of Liveblocks, NEVER
1208
+ * USE ANY OF THESE DIRECTLY, because bad things will probably happen if you do.
1209
+ */
1210
+ type PrivateLiveNodeApi = {
1211
+ /**
1212
+ * Returns the CRDT node id once attached to the room pool. Detached nodes
1213
+ * that have not entered storage yet return `undefined`.
1214
+ */
1215
+ getId(): string | undefined;
1216
+ };
892
1217
  /**
893
1218
  * The managed pool is a namespace registry (i.e. a context) that "owns" all
894
1219
  * the individual live nodes, ensuring each one has a unique ID, and holding on
@@ -907,7 +1232,7 @@ interface ManagedPool {
907
1232
  * - Add reverse operations to the undo/redo stack
908
1233
  * - Notify room subscribers with updates (in-client, no networking)
909
1234
  */
910
- dispatch: (ops: ClientWireOp[], reverseOps: Op[], storageUpdates: Map<string, StorageUpdate>) => void;
1235
+ dispatch: (ops: ClientWireOp[], reverseOps: Op[], storageUpdates: Map<string, StorageUpdate>, options?: DispatchOptions) => void;
911
1236
  /**
912
1237
  * Ensures storage can be written to else throws an error.
913
1238
  * This is used to prevent writing to storage when the user does not have
@@ -932,7 +1257,7 @@ type CreateManagedPoolOptions = {
932
1257
  /**
933
1258
  * Will get invoked when any Live structure calls .dispatch() on the pool.
934
1259
  */
935
- onDispatch?: (ops: ClientWireOp[], reverse: Op[], storageUpdates: Map<string, StorageUpdate>) => void;
1260
+ onDispatch?: (ops: ClientWireOp[], reverse: Op[], storageUpdates: Map<string, StorageUpdate>, options?: DispatchOptions) => void;
936
1261
  /**
937
1262
  * Will get invoked when any Live structure calls .assertStorageIsWritable()
938
1263
  * on the pool. Defaults to true when not provided. Return false if you want
@@ -954,6 +1279,8 @@ type CreateManagedPoolOptions = {
954
1279
  declare function createManagedPool(options: CreateManagedPoolOptions): ManagedPool;
955
1280
  declare abstract class AbstractCrdt {
956
1281
  #private;
1282
+ readonly [kInternal]: PrivateLiveNodeApi;
1283
+ constructor();
957
1284
  /**
958
1285
  * @private
959
1286
  * Returns true if the cached JSON snapshot exists and is reference-equal
@@ -1111,7 +1438,7 @@ declare class LiveRegister<TValue extends Json> extends AbstractCrdt {
1111
1438
  clone(): TValue;
1112
1439
  }
1113
1440
 
1114
- type LiveStructure = LiveObject<LsonObject> | LiveList<Lson> | LiveMap<string, Lson>;
1441
+ type LiveStructure = LiveObject<LsonObject> | LiveList<Lson> | LiveMap<string, Lson> | LiveText;
1115
1442
  /**
1116
1443
  * Think of Lson as a sibling of the Json data tree, except that the nested
1117
1444
  * data structure can contain a mix of Json values and LiveStructure instances.
@@ -1147,7 +1474,7 @@ type ToJson<L extends Lson | LsonObject> = L extends LiveList<infer I extends Ls
1147
1474
  readonly [K in keyof O]: ToJson<Exclude<O[K], undefined>> | (undefined extends O[K] ? undefined : never);
1148
1475
  } : L extends LiveMap<infer KS extends string, infer V extends Lson> ? Lson extends V ? ReadonlyJsonObject : {
1149
1476
  readonly [K in KS]: ToJson<V>;
1150
- } : L extends LsonObject ? string extends keyof L ? ReadonlyJsonObject : {
1477
+ } : L extends LiveText ? LiveTextData : L extends LsonObject ? string extends keyof L ? ReadonlyJsonObject : {
1151
1478
  readonly [K in keyof L]: ToJson<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
1152
1479
  } : L extends Json ? L : never;
1153
1480
 
@@ -1994,25 +2321,6 @@ interface LiveblocksHttpApi<TM extends BaseMetadata, CM extends BaseMetadata> ex
1994
2321
  getGroup(groupId: string): Promise<GroupData | undefined>;
1995
2322
  }
1996
2323
 
1997
- /**
1998
- * Use this symbol to brand an object property as internal.
1999
- *
2000
- * @example
2001
- * Object.defineProperty(
2002
- * {
2003
- * public,
2004
- * [kInternal]: {
2005
- * private
2006
- * },
2007
- * },
2008
- * kInternal,
2009
- * {
2010
- * enumerable: false,
2011
- * }
2012
- * );
2013
- */
2014
- declare const kInternal: unique symbol;
2015
-
2016
2324
  /**
2017
2325
  * Back-port of TypeScript 5.4's built-in NoInfer utility type.
2018
2326
  * See https://stackoverflow.com/a/56688073/148872
@@ -4136,7 +4444,14 @@ interface SyncSource {
4136
4444
  */
4137
4445
  type PrivateRoomApi = {
4138
4446
  presenceBuffer: Json | undefined;
4139
- undoStack: readonly (readonly Readonly<Stackframe<JsonObject>>[])[];
4447
+ undoStack: readonly {
4448
+ readonly id: number;
4449
+ readonly frames: readonly Readonly<Stackframe<JsonObject>>[];
4450
+ }[];
4451
+ redoStack: readonly {
4452
+ readonly id: number;
4453
+ readonly frames: readonly Readonly<Stackframe<JsonObject>>[];
4454
+ }[];
4140
4455
  nodeCount: number;
4141
4456
  getYjsProvider(): IYjsProvider | undefined;
4142
4457
  setYjsProvider(provider: IYjsProvider | undefined): void;
@@ -4176,6 +4491,21 @@ type PrivateRoomApi = {
4176
4491
  incomingMessage(data: string): void;
4177
4492
  };
4178
4493
  attachmentUrlsStore: BatchStore<string, string>;
4494
+ readonly history: Observable<{
4495
+ action: "push";
4496
+ id: number;
4497
+ } | {
4498
+ action: "undo";
4499
+ id: number;
4500
+ } | {
4501
+ action: "redo";
4502
+ id: number;
4503
+ } | {
4504
+ action: "clear";
4505
+ } | {
4506
+ action: "discard";
4507
+ ids: number[];
4508
+ }>;
4179
4509
  };
4180
4510
  type Stackframe<P extends JsonObject> = Op | PresenceStackframe<P>;
4181
4511
  type PresenceStackframe<P extends JsonObject> = {
@@ -5075,7 +5405,12 @@ type PlainLsonList = {
5075
5405
  liveblocksType: "LiveList";
5076
5406
  data: PlainLson[];
5077
5407
  };
5078
- type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | Json;
5408
+ type PlainLsonText = {
5409
+ liveblocksType: "LiveText";
5410
+ data: LiveTextData;
5411
+ version?: number;
5412
+ };
5413
+ type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | PlainLsonText | Json;
5079
5414
 
5080
5415
  /**
5081
5416
  * Returns PlainLson for a given Json or LiveStructure, suitable for calling the storage init api
@@ -5790,4 +6125,4 @@ type EnsureJson<T> = T extends Json ? T : T extends Array<infer I> ? (EnsureJson
5790
6125
  [K in keyof T as EnsureJson<T[K]> extends never ? never : K]: EnsureJson<T[K]>;
5791
6126
  };
5792
6127
 
5793
- export { type AccessLevel, type ActivityData, type AiAssistantContentPart, type AiAssistantMessage, type AiChat, type AiChatMessage, type AiChatsQuery, type AiKnowledgeRetrievalPart, type AiKnowledgeSource, type AiOpaqueToolDefinition, type AiOpaqueToolInvocationProps, type AiReasoningPart, type AiRetrievalPart, type AiSourcesPart, type AiTextPart, type AiToolDefinition, type AiToolExecuteCallback, type AiToolExecuteContext, type AiToolInvocationPart, type AiToolInvocationProps, type AiToolTypePack, type AiUrlSource, type AiUserMessage, type AiWebRetrievalPart, type AsyncError, type AsyncLoading, type AsyncResult, type AsyncSuccess, type Awaitable, type BaseActivitiesData, type BaseAuthResult, type BaseGroupInfo, type BaseMetadata, type BaseRoomInfo, type BaseUserMeta, type Brand, type BroadcastEventClientMsg, type BroadcastOptions, type BroadcastedEventServerMsg, type ChildStorageNode, type Client, type ClientMsg, ClientMsgCode, type ClientOptions, type ClientWireOp, type CommentAttachment, type CommentBody, type CommentBodyBlockElement, type CommentBodyElement, type CommentBodyInlineElement, type CommentBodyLink, type CommentBodyLinkElementArgs, type CommentBodyMention, type CommentBodyMentionElementArgs, type CommentBodyParagraph, type CommentBodyParagraphElementArgs, type CommentBodyText, type CommentBodyTextElementArgs, type CommentData, type CommentDataPlain, type CommentLocalAttachment, type CommentMixedAttachment, type CommentReaction, type CommentUserReaction, type CommentUserReactionPlain, type CommentsEventServerMsg, type CompactChildNode, type CompactListNode, type CompactMapNode, type CompactNode, type CompactObjectNode, type CompactRegisterNode, type CompactRootNode, type ContextualPromptContext, type ContextualPromptResponse, type CopilotId, CrdtType, type CreateListOp, type CreateManagedPoolOptions, type CreateMapOp, type CreateObjectOp, type CreateOp, type CreateRegisterOp, type Cursor, type CustomAuthenticationResult, type DAD, type DCM, type DE, type DFM, type DFMD, type DGI, type DP, type DRI, type DS, type DTM, type DU, DefaultMap, type Delegates, type DeleteCrdtOp, type DeleteObjectKeyOp, Deque, DerivedSignal, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, type DistributiveOmit, type EnsureJson, type EnterOptions, type EventSource, type Feed, type FeedCreateMetadata, type FeedDeletedServerMsg, type FeedFetchMetadataFilter, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesUpdatedServerMsg, type FeedRequestError, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedUpdateMetadata, type FeedsAddedServerMsg, type FeedsEventServerMsg, type FeedsListServerMsg, type FeedsUpdatedServerMsg, type FetchStorageClientMsg, type FetchYDocClientMsg, type GetThreadsOptions, type GroupData, type GroupDataPlain, type GroupMemberData, type GroupMentionData, type GroupScopes, type HasOpId, type History, type HistoryVersion, HttpError, type ISODateString, type ISignal, type IUserInfo, type IWebSocket, type IWebSocketCloseEvent, type IWebSocketEvent, type IWebSocketInstance, type IWebSocketMessageEvent, type IYjsProvider, type IgnoredOp, type Immutable, type InboxNotificationCustomData, type InboxNotificationCustomDataPlain, type InboxNotificationData, type InboxNotificationDataPlain, type InboxNotificationDeleteInfo, type InboxNotificationTextMentionData, type InboxNotificationTextMentionDataPlain, type InboxNotificationThreadData, type InboxNotificationThreadDataPlain, type InferFromSchema, type Json, type JsonArray, type JsonObject, type JsonScalar, type KDAD, type LayerKey, type ListStorageNode, LiveList, type LiveListUpdate, LiveMap, type LiveMapUpdate, type LiveNode, LiveObject, type LiveObjectUpdate, type LiveStructure, LiveblocksError, type LiveblocksErrorContext, type LostConnectionEvent, type Lson, type LsonObject, MENTION_CHARACTER, type ManagedPool, type MapStorageNode, type MentionData, type MessageId, MutableSignal, type NoInfr, type NodeMap, type NodeStream, type NotificationChannel, type NotificationChannelSettings, type NotificationKind, type NotificationSettings, type NotificationSettingsPlain, type ObjectStorageNode, type Observable, type Op, OpCode, type OpaqueClient, type OpaqueRoom, type OptionalTupleUnless, type OthersEvent, type ParentToChildNodeMap, type PartialNotificationSettings, type PartialUnless, type Patchable, Permission, type PermissionMatrix, type PermissionResources, type PlainLson, type PlainLsonFields, type PlainLsonList, type PlainLsonMap, type PlainLsonObject, type Poller, type PrivateClientApi, type PrivateRoomApi, Promise_withResolvers, type QueryMetadata, type QueryParams, type ReadonlyJson, type ReadonlyJsonObject, type RegisterStorageNode, type RejectedStorageOpServerMsg, type Relax, type RenderableToolResultResponse, type RequiredAccessLevel, type Resolve, type ResolveGroupsInfoArgs, type ResolveMentionSuggestionsArgs, type ResolveRoomsInfoArgs, type ResolveUsersArgs, type Room, type RoomAccesses, type RoomEventMessage, type RoomPermissions, type RoomStateServerMsg, type RoomSubscriptionSettings, type RootStorageNode, type SearchCommentsResult, type SerializedChild, type SerializedCrdt, type SerializedList, type SerializedMap, type SerializedObject, type SerializedRegister, type SerializedRootObject, type ServerMsg, ServerMsgCode, type ServerWireOp, type SetParentKeyOp, Signal, type SignalType, SortedList, type Status, type StorageChunkServerMsg, type StorageNode, type StorageStatus, type StorageUpdate, type StringifyCommentBodyElements, type StringifyCommentBodyOptions, type SubscriptionData, type SubscriptionDataPlain, type SubscriptionDeleteInfo, type SubscriptionDeleteInfoPlain, type SubscriptionKey, type SyncConfig, type SyncMode, type SyncSource, type SyncStatus, TextEditorType, type ThreadData, type ThreadDataPlain, type ThreadDataWithDeleteInfo, type ThreadDeleteInfo, type ThreadVisibility, type ToJson, type ToolResultResponse, type URLSafeString, type UnsubscribeCallback, type UpdateObjectOp, type UpdatePresenceClientMsg, type UpdatePresenceServerMsg, type UpdateRoomAccesses, type UpdateStorageClientMsg, type UpdateStorageServerMsg, type UpdateYDocClientMsg, type UploadAttachmentOptions, type UrlMetadata, type User, type UserJoinServerMsg, type UserLeftServerMsg, type UserMentionData, type UserRoomSubscriptionSettings, type UserSubscriptionData, type UserSubscriptionDataPlain, WebsocketCloseCodes, type WithNavigation, type WithOptional, type WithRequired, type YDocUpdateServerMsg, type YjsSyncStatus, asPos, assert, assertNever, autoRetry, b64decode, batch, checkBounds, chunk, cloneLson, compactNodesToNodeStream, compactObject, fancyConsole as console, convertToCommentData, convertToCommentUserReaction, convertToGroupData, convertToInboxNotificationData, convertToSubscriptionData, convertToThreadData, convertToUserSubscriptionData, createClient, createCommentAttachmentId, createCommentId, createInboxNotificationId, createManagedPool, createNotificationSettings, createThreadId, deepLiveify, defineAiTool, deprecate, deprecateIf, detectDupes, entries, errorIf, findLastIndex, freeze, generateUrl, getMentionsFromCommentBody, getSubscriptionKey, hasPermissionAccess, html, htmlSafe, isCommentBodyLink, isCommentBodyMention, isCommentBodyText, isJsonArray, isJsonObject, isJsonScalar, isListStorageNode, isLiveNode, isMapStorageNode, isNotificationChannelEnabled, isNumberOperator, isObjectStorageNode, isPlainObject, isRegisterStorageNode, isRootStorageNode, isStartsWithOperator, isUrl, kInternal, keys, makeAbortController, makeEventSource, makePoller, makePosition, mapValues, memoizeOnSuccess, mergeRoomPermissionScopes, nanoid, nn, nodeStreamToCompactNodes, normalizeRoomAccesses, normalizeRoomPermissions, normalizeUpdateRoomAccesses, objectToQuery, patchNotificationSettings, permissionMatrixFromScopes, raise, resolveMentionsInCommentBody, sanitizeUrl, shallow, shallow2, stableStringify, stringifyCommentBody, throwUsageError, toPlainLson, tryParseJson, url, urljoin, validatePermissionsSet, wait, warnOnce, warnOnceIf, withTimeout };
6128
+ export { type AccessLevel, type ActivityData, type AiAssistantContentPart, type AiAssistantMessage, type AiChat, type AiChatMessage, type AiChatsQuery, type AiKnowledgeRetrievalPart, type AiKnowledgeSource, type AiOpaqueToolDefinition, type AiOpaqueToolInvocationProps, type AiReasoningPart, type AiRetrievalPart, type AiSourcesPart, type AiTextPart, type AiToolDefinition, type AiToolExecuteCallback, type AiToolExecuteContext, type AiToolInvocationPart, type AiToolInvocationProps, type AiToolTypePack, type AiUrlSource, type AiUserMessage, type AiWebRetrievalPart, type AsyncError, type AsyncLoading, type AsyncResult, type AsyncSuccess, type Awaitable, type BaseActivitiesData, type BaseAuthResult, type BaseGroupInfo, type BaseMetadata, type BaseRoomInfo, type BaseUserMeta, type Brand, type BroadcastEventClientMsg, type BroadcastOptions, type BroadcastedEventServerMsg, type ChildStorageNode, type Client, type ClientMsg, ClientMsgCode, type ClientOptions, type ClientWireOp, type CommentAttachment, type CommentBody, type CommentBodyBlockElement, type CommentBodyElement, type CommentBodyInlineElement, type CommentBodyLink, type CommentBodyLinkElementArgs, type CommentBodyMention, type CommentBodyMentionElementArgs, type CommentBodyParagraph, type CommentBodyParagraphElementArgs, type CommentBodyText, type CommentBodyTextElementArgs, type CommentData, type CommentDataPlain, type CommentLocalAttachment, type CommentMixedAttachment, type CommentReaction, type CommentUserReaction, type CommentUserReactionPlain, type CommentsEventServerMsg, type CompactChildNode, type CompactListNode, type CompactMapNode, type CompactNode, type CompactObjectNode, type CompactRegisterNode, type CompactRootNode, type CompactTextNode, type ContextualPromptContext, type ContextualPromptResponse, type CopilotId, CrdtType, type CreateListOp, type CreateManagedPoolOptions, type CreateMapOp, type CreateObjectOp, type CreateOp, type CreateRegisterOp, type CreateTextOp, type Cursor, type CustomAuthenticationResult, type DAD, type DCM, type DE, type DFM, type DFMD, type DGI, type DP, type DRI, type DS, type DTM, type DU, DefaultMap, type Delegates, type DeleteCrdtOp, type DeleteObjectKeyOp, Deque, DerivedSignal, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, type DistributiveOmit, type EnsureJson, type EnterOptions, type EventSource, type Feed, type FeedCreateMetadata, type FeedDeletedServerMsg, type FeedFetchMetadataFilter, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesUpdatedServerMsg, type FeedRequestError, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedUpdateMetadata, type FeedsAddedServerMsg, type FeedsEventServerMsg, type FeedsListServerMsg, type FeedsUpdatedServerMsg, type FetchStorageClientMsg, type FetchYDocClientMsg, type GetThreadsOptions, type GroupData, type GroupDataPlain, type GroupMemberData, type GroupMentionData, type GroupScopes, type HasOpId, type History, type HistoryVersion, HttpError, type ISODateString, type ISignal, type IUserInfo, type IWebSocket, type IWebSocketCloseEvent, type IWebSocketEvent, type IWebSocketInstance, type IWebSocketMessageEvent, type IYjsProvider, type IgnoredOp, type Immutable, type InboxNotificationCustomData, type InboxNotificationCustomDataPlain, type InboxNotificationData, type InboxNotificationDataPlain, type InboxNotificationDeleteInfo, type InboxNotificationTextMentionData, type InboxNotificationTextMentionDataPlain, type InboxNotificationThreadData, type InboxNotificationThreadDataPlain, type InferFromSchema, type Json, type JsonArray, type JsonObject, type JsonScalar, type KDAD, type LayerKey, type ListStorageNode, LiveList, type LiveListUpdate, LiveMap, type LiveMapUpdate, type LiveNode, LiveObject, type LiveObjectUpdate, type LiveStructure, LiveText, type LiveTextAttributes, type LiveTextAttributesPatch, type LiveTextChange, type LiveTextData, type TextOperation as LiveTextOperation, type LiveTextSegment, type LiveTextUpdate, type LiveTextUpdates, LiveblocksError, type LiveblocksErrorContext, type LostConnectionEvent, type Lson, type LsonObject, MENTION_CHARACTER, type ManagedPool, type MapStorageNode, type MentionData, type MessageId, MutableSignal, type NoInfr, type NodeMap, type NodeStream, type NotificationChannel, type NotificationChannelSettings, type NotificationKind, type NotificationSettings, type NotificationSettingsPlain, type ObjectStorageNode, type Observable, type Op, OpCode, type OpaqueClient, type OpaqueRoom, type OptionalTupleUnless, type OthersEvent, type ParentToChildNodeMap, type PartialNotificationSettings, type PartialUnless, type Patchable, Permission, type PermissionMatrix, type PermissionResources, type PlainLson, type PlainLsonFields, type PlainLsonList, type PlainLsonMap, type PlainLsonObject, type PlainLsonText, type Poller, type PrivateClientApi, type PrivateLiveNodeApi, type PrivateLiveTextApi, type PrivateRoomApi, Promise_withResolvers, type QueryMetadata, type QueryParams, type ReadonlyJson, type ReadonlyJsonObject, type RegisterStorageNode, type RejectedStorageOpServerMsg, type Relax, type RenderableToolResultResponse, type RequiredAccessLevel, type Resolve, type ResolveGroupsInfoArgs, type ResolveMentionSuggestionsArgs, type ResolveRoomsInfoArgs, type ResolveUsersArgs, type Room, type RoomAccesses, type RoomEventMessage, type RoomPermissions, type RoomStateServerMsg, type RoomSubscriptionSettings, type RootStorageNode, type SearchCommentsResult, type SerializedChild, type SerializedCrdt, type SerializedList, type SerializedMap, type SerializedObject, type SerializedRegister, type SerializedRootObject, type SerializedText, type ServerMsg, ServerMsgCode, type ServerWireOp, type SetParentKeyOp, Signal, type SignalType, SortedList, type Status, type StorageChunkServerMsg, type StorageNode, type StorageStatus, type StorageUpdate, type StorageUpdateSource, type StringifyCommentBodyElements, type StringifyCommentBodyOptions, type SubscriptionData, type SubscriptionDataPlain, type SubscriptionDeleteInfo, type SubscriptionDeleteInfoPlain, type SubscriptionKey, type SyncConfig, type SyncMode, type SyncSource, type SyncStatus, type TextAttributes, TextEditorType, type TextOperation, type TextStorageNode, type ThreadData, type ThreadDataPlain, type ThreadDataWithDeleteInfo, type ThreadDeleteInfo, type ThreadVisibility, type ToJson, type ToolResultResponse, type URLSafeString, type UnsubscribeCallback, type UpdateObjectOp, type UpdatePresenceClientMsg, type UpdatePresenceServerMsg, type UpdateRoomAccesses, type UpdateStorageClientMsg, type UpdateStorageServerMsg, type UpdateTextOp, type UpdateYDocClientMsg, type UploadAttachmentOptions, type UrlMetadata, type User, type UserJoinServerMsg, type UserLeftServerMsg, type UserMentionData, type UserRoomSubscriptionSettings, type UserSubscriptionData, type UserSubscriptionDataPlain, WebsocketCloseCodes, type WithNavigation, type WithOptional, type WithRequired, type YDocUpdateServerMsg, type YjsSyncStatus, applyLiveTextOperations, asPos, assert, assertNever, autoRetry, b64decode, batch, checkBounds, chunk, cloneLson, compactNodesToNodeStream, compactObject, fancyConsole as console, convertToCommentData, convertToCommentUserReaction, convertToGroupData, convertToInboxNotificationData, convertToSubscriptionData, convertToThreadData, convertToUserSubscriptionData, createClient, createCommentAttachmentId, createCommentId, createInboxNotificationId, createManagedPool, createNotificationSettings, createThreadId, deepLiveify, defineAiTool, deprecate, deprecateIf, detectDupes, entries, errorIf, findLastIndex, freeze, generateUrl, getMentionsFromCommentBody, getSubscriptionKey, hasPermissionAccess, html, htmlSafe, isCommentBodyLink, isCommentBodyMention, isCommentBodyText, isJsonArray, isJsonObject, isJsonScalar, isListStorageNode, isLiveNode, isMapStorageNode, isNotificationChannelEnabled, isNumberOperator, isObjectStorageNode, isPlainObject, isRegisterStorageNode, isRootStorageNode, isStartsWithOperator, isTextStorageNode, isUrl, kInternal, kStorageUpdateSource, keys, makeAbortController, makeEventSource, makePoller, makePosition, mapValues, memoizeOnSuccess, mergeRoomPermissionScopes, nanoid, nn, nodeStreamToCompactNodes, normalizeRoomAccesses, normalizeRoomPermissions, normalizeUpdateRoomAccesses, objectToQuery, patchNotificationSettings, permissionMatrixFromScopes, raise, resolveMentionsInCommentBody, sanitizeUrl, shallow, shallow2, stableStringify, stringifyCommentBody, throwUsageError, toPlainLson, transformTextOperations, tryParseJson, url, urljoin, validatePermissionsSet, wait, warnOnce, warnOnceIf, withTimeout };