@liveblocks/core 1.9.8-pre1 → 1.10.0-beta2

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
@@ -5,6 +5,19 @@
5
5
  declare function detectDupes(pkgName: string, pkgVersion: string | false, // false if not built yet
6
6
  pkgFormat: string | false): void;
7
7
 
8
+ declare type CustomAuthenticationResult = {
9
+ token: string;
10
+ error?: never;
11
+ } | {
12
+ token?: never;
13
+ error: "forbidden";
14
+ reason: string;
15
+ } | {
16
+ token?: never;
17
+ error: string;
18
+ reason: string;
19
+ };
20
+
8
21
  /**
9
22
  * Represents an indefinitely deep arbitrary JSON data structure. There are
10
23
  * four types that make up the Json family:
@@ -25,6 +38,211 @@ declare function isJsonScalar(data: Json): data is JsonScalar;
25
38
  declare function isJsonArray(data: Json): data is JsonArray;
26
39
  declare function isJsonObject(data: Json): data is JsonObject;
27
40
 
41
+ /**
42
+ * Represents some constraints for user info. Basically read this as: "any JSON
43
+ * object is fine, but _if_ it has a name field, it _must_ be a string."
44
+ * (Ditto for avatar.)
45
+ */
46
+ declare type IUserInfo = {
47
+ [key: string]: Json | undefined;
48
+ name?: string;
49
+ avatar?: string;
50
+ };
51
+ /**
52
+ * This type is used by clients to define the metadata for a user.
53
+ */
54
+ declare type BaseUserMeta = {
55
+ /**
56
+ * The id of the user that has been set in the authentication endpoint.
57
+ * Useful to get additional information about the connected user.
58
+ */
59
+ id?: string;
60
+ /**
61
+ * Additional user information that has been set in the authentication endpoint.
62
+ */
63
+ info?: IUserInfo;
64
+ };
65
+
66
+ declare type Callback<T> = (event: T) => void;
67
+ declare type UnsubscribeCallback = () => void;
68
+ declare type Observable<T> = {
69
+ /**
70
+ * Register a callback function to be called whenever the event source emits
71
+ * an event.
72
+ */
73
+ subscribe(callback: Callback<T>): UnsubscribeCallback;
74
+ /**
75
+ * Register a one-time callback function to be called whenever the event
76
+ * source emits an event. After the event fires, the callback is
77
+ * auto-unsubscribed.
78
+ */
79
+ subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
80
+ /**
81
+ * Returns a promise that will resolve when an event is emitted by this
82
+ * event source. Optionally, specify a predicate that has to match. The first
83
+ * event matching that predicate will then resolve the promise.
84
+ */
85
+ waitUntil(predicate?: (event: T) => boolean): Promise<T>;
86
+ };
87
+ declare type EventSource<T> = Observable<T> & {
88
+ /**
89
+ * Notify all subscribers about the event.
90
+ */
91
+ notify(event: T): void;
92
+ /**
93
+ * Clear all registered event listeners. None of the registered functions
94
+ * will ever get called again. Be careful when using this API, because the
95
+ * subscribers may not have any idea they won't be notified anymore.
96
+ */
97
+ clear(): void;
98
+ /**
99
+ * Returns the number of active subscribers.
100
+ */
101
+ count(): number;
102
+ /**
103
+ * Pauses event delivery until unpaused. Any .notify() calls made while
104
+ * paused will get buffered into memory and emitted later.
105
+ */
106
+ pause(): void;
107
+ /**
108
+ * Emits all in-memory buffered events, and unpauses. Any .notify() calls
109
+ * made after this will be synchronously delivered again.
110
+ */
111
+ unpause(): void;
112
+ /**
113
+ * Observable instance, which can be used to subscribe to this event source
114
+ * in a readonly fashion. Safe to publicly expose.
115
+ */
116
+ observable: Observable<T>;
117
+ };
118
+ /**
119
+ * makeEventSource allows you to generate a subscribe/notify pair of functions
120
+ * to make subscribing easy and to get notified about events.
121
+ *
122
+ * The events are anonymous, so you can use it to define events, like so:
123
+ *
124
+ * const event1 = makeEventSource();
125
+ * const event2 = makeEventSource();
126
+ *
127
+ * event1.subscribe(foo);
128
+ * event1.subscribe(bar);
129
+ * event2.subscribe(qux);
130
+ *
131
+ * // Unsubscription is pretty standard
132
+ * const unsub = event2.subscribe(foo);
133
+ * unsub();
134
+ *
135
+ * event1.notify(); // Now foo and bar will get called
136
+ * event2.notify(); // Now qux will get called (but foo will not, since it's unsubscribed)
137
+ *
138
+ */
139
+ declare function makeEventSource<T>(): EventSource<T>;
140
+
141
+ interface IWebSocketEvent {
142
+ type: string;
143
+ }
144
+ interface IWebSocketCloseEvent extends IWebSocketEvent {
145
+ readonly code: WebsocketCloseCodes;
146
+ readonly wasClean: boolean;
147
+ readonly reason: string;
148
+ }
149
+ interface IWebSocketMessageEvent extends IWebSocketEvent {
150
+ readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
151
+ }
152
+ interface IWebSocketInstance {
153
+ readonly CONNECTING: number;
154
+ readonly OPEN: number;
155
+ readonly CLOSING: number;
156
+ readonly CLOSED: number;
157
+ readonly readyState: number;
158
+ addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
159
+ addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
160
+ addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
161
+ removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
162
+ removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
163
+ removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
164
+ close(): void;
165
+ send(data: string): void;
166
+ }
167
+ /**
168
+ * Either the browser-based WebSocket API or Node.js' WebSocket API (from the
169
+ * 'ws' package).
170
+ *
171
+ * This type defines the minimal WebSocket API that Liveblocks needs from
172
+ * a WebSocket implementation, and is a minimal subset of the browser-based
173
+ * WebSocket APIs and Node.js' WebSocket API so that both implementations are
174
+ * assignable to this type.
175
+ */
176
+ interface IWebSocket {
177
+ new (address: string): IWebSocketInstance;
178
+ }
179
+ /**
180
+ * The following ranges will be respected by the client:
181
+ *
182
+ * 40xx: client will disconnect
183
+ * 41xx: client will reauthorize
184
+ * 42xx: client will retry without reauthorizing (currently not used)
185
+ *
186
+ */
187
+ declare enum WebsocketCloseCodes {
188
+ /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
189
+ CLOSE_ABNORMAL = 1006,
190
+ /** Unexpected error happened. In spirit akin to HTTP 500 */
191
+ UNEXPECTED_CONDITION = 1011,
192
+ /** Please back off for now, but try again in a few moments */
193
+ TRY_AGAIN_LATER = 1013,
194
+ /** Message wasn't understood, disconnect */
195
+ INVALID_MESSAGE_FORMAT = 4000,
196
+ /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
197
+ NOT_ALLOWED = 4001,
198
+ /** Unused */
199
+ MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
200
+ /** Unused */
201
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
202
+ /** Unused */
203
+ MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
204
+ /** Room is full, disconnect */
205
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
206
+ /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
207
+ TOKEN_EXPIRED = 4109,
208
+ /** Disconnect immediately */
209
+ CLOSE_WITHOUT_RETRY = 4999
210
+ }
211
+
212
+ /**
213
+ * Old connection statuses, here for backward-compatibility reasons only.
214
+ */
215
+ declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
216
+ /**
217
+ * Returns a human-readable status indicating the current connection status of
218
+ * a Room, as returned by `room.getStatus()`. Can be used to implement
219
+ * a connection status badge.
220
+ */
221
+ declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
222
+ /**
223
+ * Used to report about app-level reconnection issues.
224
+ *
225
+ * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
226
+ * the application will only get an event if the reconnection attempts by the
227
+ * client are taking (much) longer than usual. Definitely a situation you want
228
+ * to inform your users about, for example, by throwing a toast message on
229
+ * screen, or show a "trying to reconnect" banner.
230
+ */
231
+ declare type LostConnectionEvent = "lost" | "restored" | "failed";
232
+ /**
233
+ * Arbitrary record that will be used as the authentication "authValue". It's the
234
+ * value that is returned by calling the authentication delegate, and will get
235
+ * passed to the connection factory delegate. This value will be remembered by
236
+ * the connection manager, but its value will not be interpreted, so it can be
237
+ * any value (except null).
238
+ */
239
+ declare type BaseAuthResult = NonNullable<Json>;
240
+ declare type Delegates<T extends BaseAuthResult> = {
241
+ authenticate: () => Promise<T>;
242
+ createSocket: (authValue: T) => IWebSocketInstance;
243
+ canZombie: () => boolean;
244
+ };
245
+
28
246
  declare enum OpCode {
29
247
  INIT = 0,
30
248
  SET_PARENT_KEY = 1,
@@ -203,77 +421,27 @@ declare type PlainLsonList = {
203
421
  };
204
422
  declare type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | Json;
205
423
 
206
- declare type LiveObjectUpdateDelta<O extends {
207
- [key: string]: unknown;
208
- }> = {
209
- [K in keyof O]?: UpdateDelta | undefined;
210
- };
211
424
  /**
212
- * A LiveObject notification that is sent in-client to any subscribers whenever
213
- * one or more of the entries inside the LiveObject instance have changed.
425
+ * Helper type to convert any valid Lson type to the equivalent Json type.
426
+ *
427
+ * Examples:
428
+ *
429
+ * ToImmutable<42> // 42
430
+ * ToImmutable<'hi'> // 'hi'
431
+ * ToImmutable<number> // number
432
+ * ToImmutable<string> // string
433
+ * ToImmutable<string | LiveList<number>> // string | readonly number[]
434
+ * ToImmutable<LiveMap<string, LiveList<number>>>
435
+ * // ReadonlyMap<string, readonly number[]>
436
+ * ToImmutable<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
437
+ * // { readonly a: null, readonly b: readonly string[], readonly c?: number }
438
+ *
214
439
  */
215
- declare type LiveObjectUpdates<TData extends LsonObject> = {
216
- type: "LiveObject";
217
- node: LiveObject<TData>;
218
- updates: LiveObjectUpdateDelta<TData>;
219
- };
440
+ declare type ToImmutable<L extends Lson | LsonObject> = L extends LiveList<infer I> ? readonly ToImmutable<I>[] : L extends LiveObject<infer O> ? ToImmutable<O> : L extends LiveMap<infer K, infer V> ? ReadonlyMap<K, ToImmutable<V>> : L extends LsonObject ? {
441
+ readonly [K in keyof L]: ToImmutable<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
442
+ } : L extends Json ? L : never;
220
443
  /**
221
- * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
222
- * Keys should be a string, and values should be serializable to JSON.
223
- * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
224
- */
225
- declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
226
- constructor(obj?: O);
227
- /**
228
- * Transform the LiveObject into a javascript object
229
- */
230
- toObject(): O;
231
- /**
232
- * Adds or updates a property with a specified key and a value.
233
- * @param key The key of the property to add
234
- * @param value The value of the property to add
235
- */
236
- set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
237
- /**
238
- * Returns a specified property from the LiveObject.
239
- * @param key The key of the property to get
240
- */
241
- get<TKey extends keyof O>(key: TKey): O[TKey];
242
- /**
243
- * Deletes a key from the LiveObject
244
- * @param key The key of the property to delete
245
- */
246
- delete(key: keyof O): void;
247
- /**
248
- * Adds or updates multiple properties at once with an object.
249
- * @param patch The object used to overrides properties
250
- */
251
- update(patch: Partial<O>): void;
252
- toImmutable(): ToImmutable<O>;
253
- clone(): LiveObject<O>;
254
- }
255
-
256
- /**
257
- * Helper type to convert any valid Lson type to the equivalent Json type.
258
- *
259
- * Examples:
260
- *
261
- * ToImmutable<42> // 42
262
- * ToImmutable<'hi'> // 'hi'
263
- * ToImmutable<number> // number
264
- * ToImmutable<string> // string
265
- * ToImmutable<string | LiveList<number>> // string | readonly number[]
266
- * ToImmutable<LiveMap<string, LiveList<number>>>
267
- * // ReadonlyMap<string, readonly number[]>
268
- * ToImmutable<LiveObject<{ a: number, b: LiveList<string>, c?: number }>>
269
- * // { readonly a: null, readonly b: readonly string[], readonly c?: number }
270
- *
271
- */
272
- declare type ToImmutable<L extends Lson | LsonObject> = L extends LiveList<infer I> ? readonly ToImmutable<I>[] : L extends LiveObject<infer O> ? ToImmutable<O> : L extends LiveMap<infer K, infer V> ? ReadonlyMap<K, ToImmutable<V>> : L extends LsonObject ? {
273
- readonly [K in keyof L]: ToImmutable<Exclude<L[K], undefined>> | (undefined extends L[K] ? undefined : never);
274
- } : L extends Json ? L : never;
275
- /**
276
- * Returns PlainLson for a given Json or LiveStructure, suitable for calling the storage init api
444
+ * Returns PlainLson for a given Json or LiveStructure, suitable for calling the storage init api
277
445
  */
278
446
  declare function toPlainLson(lson: Lson): PlainLson;
279
447
 
@@ -550,464 +718,99 @@ declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extend
550
718
  [K in KS]: ToJson<V>;
551
719
  } : never;
552
720
 
553
- /**
554
- * This helper type is effectively a no-op, but will force TypeScript to
555
- * "evaluate" any named helper types in its definition. This can sometimes make
556
- * API signatures clearer in IDEs.
557
- *
558
- * For example, in:
559
- *
560
- * type Payload<T> = { data: T };
561
- *
562
- * let r1: Payload<string>;
563
- * let r2: Resolve<Payload<string>>;
564
- *
565
- * The inferred type of `r1` is going to be `Payload<string>` which shows up in
566
- * editor hints, and it may be unclear what's inside if you don't know the
567
- * definition of `Payload`.
568
- *
569
- * The inferred type of `r2` is going to be `{ data: string }`, which may be
570
- * more helpful.
571
- *
572
- * This trick comes from:
573
- * https://effectivetypescript.com/2022/02/25/gentips-4-display/
574
- */
575
- declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
576
- [K in keyof T]: T[K];
577
- };
578
-
579
- declare type CustomAuthenticationResult = {
580
- token: string;
581
- error?: never;
582
- } | {
583
- token?: never;
584
- error: "forbidden";
585
- reason: string;
586
- } | {
587
- token?: never;
588
- error: string;
589
- reason: string;
590
- };
591
-
592
- /**
593
- * Represents some constraints for user info. Basically read this as: "any JSON
594
- * object is fine, but _if_ it has a name field, it _must_ be a string."
595
- * (Ditto for avatar.)
596
- */
597
- declare type IUserInfo = {
598
- [key: string]: Json | undefined;
599
- name?: string;
600
- avatar?: string;
601
- };
602
- /**
603
- * This type is used by clients to define the metadata for a user.
604
- */
605
- declare type BaseUserMeta = {
606
- /**
607
- * The id of the user that has been set in the authentication endpoint.
608
- * Useful to get additional information about the connected user.
609
- */
610
- id?: string;
611
- /**
612
- * Additional user information that has been set in the authentication endpoint.
613
- */
614
- info?: IUserInfo;
615
- };
616
-
617
- declare enum Permission {
618
- Read = "room:read",
619
- Write = "room:write",
620
- PresenceWrite = "room:presence:write",
621
- CommentsWrite = "comments:write",
622
- CommentsRead = "comments:read"
623
- }
624
- declare type LiveblocksPermissions = Record<string, Permission[]>;
625
- declare enum TokenKind {
626
- SECRET_LEGACY = "sec-legacy",
627
- ACCESS_TOKEN = "acc",
628
- ID_TOKEN = "id"
629
- }
630
- declare type JwtMeta = {
631
- iat: number;
632
- exp: number;
633
- };
634
- /**
635
- * Legacy Secret Token.
636
- */
637
- declare type LegacySecretToken = {
638
- k: TokenKind.SECRET_LEGACY;
639
- roomId: string;
640
- scopes: string[];
641
- id?: string;
642
- info?: IUserInfo;
643
- [other: string]: Json | undefined;
644
- } & JwtMeta;
645
- /**
646
- * New authorization Access Token.
647
- */
648
- declare type AccessToken = {
649
- k: TokenKind.ACCESS_TOKEN;
650
- pid: string;
651
- uid: string;
652
- perms: LiveblocksPermissions;
653
- ui?: IUserInfo;
654
- } & JwtMeta;
655
- /**
656
- * New authorization ID Token.
657
- */
658
- declare type IDToken = {
659
- k: TokenKind.ID_TOKEN;
660
- pid: string;
661
- uid: string;
662
- gids?: string[];
663
- ui?: IUserInfo;
664
- } & JwtMeta;
665
- declare type AuthToken = AccessToken | IDToken | LegacySecretToken;
666
- declare type ParsedAuthToken = {
667
- readonly raw: string;
668
- readonly parsed: AuthToken;
669
- };
670
-
671
- declare type AuthValue = {
672
- type: "secret";
673
- token: ParsedAuthToken;
674
- } | {
675
- type: "public";
676
- publicApiKey: string;
677
- };
678
-
679
- declare type BaseMetadata = Record<string, string | boolean | number>;
680
-
681
- declare type CommentBodyBlockElement = CommentBodyParagraph;
682
- declare type CommentBodyInlineElement = CommentBodyText | CommentBodyMention | CommentBodyLink;
683
- declare type CommentBodyElement = CommentBodyBlockElement | CommentBodyInlineElement;
684
- declare type CommentBodyParagraph = {
685
- type: "paragraph";
686
- children: CommentBodyInlineElement[];
687
- };
688
- declare type CommentBodyMention = {
689
- type: "mention";
690
- id: string;
691
- };
692
- declare type CommentBodyLink = {
693
- type: "link";
694
- url: string;
695
- };
696
- declare type CommentBodyText = {
697
- bold?: boolean;
698
- italic?: boolean;
699
- strikethrough?: boolean;
700
- code?: boolean;
701
- text: string;
702
- };
703
- declare type CommentBody = {
704
- version: 1;
705
- content: CommentBodyBlockElement[];
706
- };
707
-
708
- declare type DateToString<T> = {
709
- [P in keyof T]: T[P] extends Date ? string : T[P];
710
- };
711
-
712
- declare type CommentReaction = {
713
- emoji: string;
714
- createdAt: Date;
715
- users: {
716
- id: string;
717
- }[];
721
+ declare type LiveObjectUpdateDelta<O extends {
722
+ [key: string]: unknown;
723
+ }> = {
724
+ [K in keyof O]?: UpdateDelta | undefined;
718
725
  };
719
726
  /**
720
- * Represents a comment.
727
+ * A LiveObject notification that is sent in-client to any subscribers whenever
728
+ * one or more of the entries inside the LiveObject instance have changed.
721
729
  */
722
- declare type CommentData = {
723
- type: "comment";
724
- id: string;
725
- threadId: string;
726
- roomId: string;
727
- userId: string;
728
- createdAt: Date;
729
- editedAt?: Date;
730
- reactions: CommentReaction[];
731
- } & ({
732
- body: CommentBody;
733
- deletedAt?: never;
734
- } | {
735
- body?: never;
736
- deletedAt: Date;
737
- });
738
- declare type CommentDataPlain = Omit<DateToString<CommentData>, "reaction" | "body"> & {
739
- reactions: DateToString<CommentReaction[]>;
740
- } & ({
741
- body: CommentBody;
742
- deletedAt?: never;
743
- } | {
744
- body?: never;
745
- deletedAt: string;
746
- });
747
-
748
- declare type CommentUserReaction = {
749
- emoji: string;
750
- createdAt: Date;
751
- userId: string;
730
+ declare type LiveObjectUpdates<TData extends LsonObject> = {
731
+ type: "LiveObject";
732
+ node: LiveObject<TData>;
733
+ updates: LiveObjectUpdateDelta<TData>;
752
734
  };
753
- declare type CommentUserReactionPlain = DateToString<CommentUserReaction>;
754
-
755
735
  /**
756
- * Represents a thread of comments.
736
+ * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
737
+ * Keys should be a string, and values should be serializable to JSON.
738
+ * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
757
739
  */
758
- declare type ThreadData<TThreadMetadata extends BaseMetadata = never> = {
759
- type: "thread";
760
- id: string;
761
- roomId: string;
762
- createdAt: Date;
763
- updatedAt?: Date;
764
- comments: CommentData[];
765
- metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
766
- };
767
- declare type ThreadDataPlain<TThreadMetadata extends BaseMetadata = never> = Omit<DateToString<ThreadData<TThreadMetadata>>, "comments" | "metadata"> & {
768
- comments: CommentDataPlain[];
769
- metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
770
- };
771
-
772
- declare type Options = {
773
- baseUrl: string;
774
- };
775
- declare type PartialNullable<T> = {
776
- [P in keyof T]?: T[P] | null | undefined;
777
- };
778
- declare type GetThreadsOptions<TThreadMetadata extends BaseMetadata> = {
779
- query?: {
780
- metadata?: Partial<TThreadMetadata>;
781
- };
782
- };
783
- declare type CommentsApi<TThreadMetadata extends BaseMetadata> = {
784
- getThreads(options?: GetThreadsOptions<TThreadMetadata>): Promise<ThreadData<TThreadMetadata>[]>;
785
- createThread(options: {
786
- threadId: string;
787
- commentId: string;
788
- metadata: TThreadMetadata | undefined;
789
- body: CommentBody;
790
- }): Promise<ThreadData<TThreadMetadata>>;
791
- editThreadMetadata(options: {
792
- metadata: PartialNullable<TThreadMetadata>;
793
- threadId: string;
794
- }): Promise<TThreadMetadata>;
795
- createComment(options: {
796
- threadId: string;
797
- commentId: string;
798
- body: CommentBody;
799
- }): Promise<CommentData>;
800
- editComment(options: {
801
- threadId: string;
802
- commentId: string;
803
- body: CommentBody;
804
- }): Promise<CommentData>;
805
- deleteComment(options: {
806
- threadId: string;
807
- commentId: string;
808
- }): Promise<void>;
809
- addReaction(options: {
810
- threadId: string;
811
- commentId: string;
812
- emoji: string;
813
- }): Promise<CommentUserReaction>;
814
- removeReaction(options: {
815
- threadId: string;
816
- commentId: string;
817
- emoji: string;
818
- }): Promise<void>;
819
- };
820
- declare class CommentsApiError extends Error {
821
- message: string;
822
- status: number;
823
- details?: JsonObject | undefined;
824
- constructor(message: string, status: number, details?: JsonObject | undefined);
825
- }
826
- declare function createCommentsApi<TThreadMetadata extends BaseMetadata>(roomId: string, getAuthValue: () => Promise<AuthValue>, config: Options): CommentsApi<TThreadMetadata>;
827
-
828
- declare type Callback<T> = (event: T) => void;
829
- declare type UnsubscribeCallback = () => void;
830
- declare type Observable<T> = {
831
- /**
832
- * Register a callback function to be called whenever the event source emits
833
- * an event.
834
- */
835
- subscribe(callback: Callback<T>): UnsubscribeCallback;
836
- /**
837
- * Register a one-time callback function to be called whenever the event
838
- * source emits an event. After the event fires, the callback is
839
- * auto-unsubscribed.
840
- */
841
- subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
842
- /**
843
- * Returns a promise that will resolve when an event is emitted by this
844
- * event source. Optionally, specify a predicate that has to match. The first
845
- * event matching that predicate will then resolve the promise.
846
- */
847
- waitUntil(predicate?: (event: T) => boolean): Promise<T>;
848
- };
849
- declare type EventSource<T> = Observable<T> & {
850
- /**
851
- * Notify all subscribers about the event.
852
- */
853
- notify(event: T): void;
740
+ declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
741
+ constructor(obj?: O);
854
742
  /**
855
- * Clear all registered event listeners. None of the registered functions
856
- * will ever get called again. Be careful when using this API, because the
857
- * subscribers may not have any idea they won't be notified anymore.
743
+ * Transform the LiveObject into a javascript object
858
744
  */
859
- clear(): void;
745
+ toObject(): O;
860
746
  /**
861
- * Returns the number of active subscribers.
747
+ * Adds or updates a property with a specified key and a value.
748
+ * @param key The key of the property to add
749
+ * @param value The value of the property to add
862
750
  */
863
- count(): number;
751
+ set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
864
752
  /**
865
- * Pauses event delivery until unpaused. Any .notify() calls made while
866
- * paused will get buffered into memory and emitted later.
753
+ * Returns a specified property from the LiveObject.
754
+ * @param key The key of the property to get
867
755
  */
868
- pause(): void;
756
+ get<TKey extends keyof O>(key: TKey): O[TKey];
869
757
  /**
870
- * Emits all in-memory buffered events, and unpauses. Any .notify() calls
871
- * made after this will be synchronously delivered again.
758
+ * Deletes a key from the LiveObject
759
+ * @param key The key of the property to delete
872
760
  */
873
- unpause(): void;
761
+ delete(key: keyof O): void;
874
762
  /**
875
- * Observable instance, which can be used to subscribe to this event source
876
- * in a readonly fashion. Safe to publicly expose.
763
+ * Adds or updates multiple properties at once with an object.
764
+ * @param patch The object used to overrides properties
877
765
  */
878
- observable: Observable<T>;
879
- };
880
- /**
881
- * makeEventSource allows you to generate a subscribe/notify pair of functions
882
- * to make subscribing easy and to get notified about events.
883
- *
884
- * The events are anonymous, so you can use it to define events, like so:
885
- *
886
- * const event1 = makeEventSource();
887
- * const event2 = makeEventSource();
888
- *
889
- * event1.subscribe(foo);
890
- * event1.subscribe(bar);
891
- * event2.subscribe(qux);
892
- *
893
- * // Unsubscription is pretty standard
894
- * const unsub = event2.subscribe(foo);
895
- * unsub();
896
- *
897
- * event1.notify(); // Now foo and bar will get called
898
- * event2.notify(); // Now qux will get called (but foo will not, since it's unsubscribed)
899
- *
900
- */
901
- declare function makeEventSource<T>(): EventSource<T>;
902
-
903
- interface IWebSocketEvent {
904
- type: string;
905
- }
906
- interface IWebSocketCloseEvent extends IWebSocketEvent {
907
- readonly code: WebsocketCloseCodes;
908
- readonly wasClean: boolean;
909
- readonly reason: string;
910
- }
911
- interface IWebSocketMessageEvent extends IWebSocketEvent {
912
- readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
913
- }
914
- interface IWebSocketInstance {
915
- readonly CONNECTING: number;
916
- readonly OPEN: number;
917
- readonly CLOSING: number;
918
- readonly CLOSED: number;
919
- readonly readyState: number;
920
- addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
921
- addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
922
- addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
923
- removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
924
- removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
925
- removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
926
- close(): void;
927
- send(data: string): void;
928
- }
929
- /**
930
- * Either the browser-based WebSocket API or Node.js' WebSocket API (from the
931
- * 'ws' package).
932
- *
933
- * This type defines the minimal WebSocket API that Liveblocks needs from
934
- * a WebSocket implementation, and is a minimal subset of the browser-based
935
- * WebSocket APIs and Node.js' WebSocket API so that both implementations are
936
- * assignable to this type.
937
- */
938
- interface IWebSocket {
939
- new (address: string): IWebSocketInstance;
940
- }
941
- /**
942
- * The following ranges will be respected by the client:
943
- *
944
- * 10xx: client will reauthorize (just like 41xx)
945
- * 40xx: client will disconnect
946
- * 41xx: client will reauthorize
947
- * 42xx: client will retry without reauthorizing (currently not used)
948
- *
949
- */
950
- declare enum WebsocketCloseCodes {
951
- /** Normal close of connection, the connection fulfilled its purpose. */
952
- CLOSE_NORMAL = 1000,
953
- /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
954
- CLOSE_ABNORMAL = 1006,
955
- /** Unexpected error happened. In spirit akin to HTTP 500 */
956
- UNEXPECTED_CONDITION = 1011,
957
- /** Please back off for now, but try again in a few moments */
958
- TRY_AGAIN_LATER = 1013,
959
- /** Message wasn't understood, disconnect */
960
- INVALID_MESSAGE_FORMAT = 4000,
961
- /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
962
- NOT_ALLOWED = 4001,
963
- /** Unused */
964
- MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
965
- /** Unused */
966
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
967
- /** Unused */
968
- MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
969
- /** Room is full, disconnect */
970
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
971
- /** The server kicked the connection from the room. */
972
- KICKED = 4100,
973
- /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
974
- TOKEN_EXPIRED = 4109,
975
- /** Disconnect immediately */
976
- CLOSE_WITHOUT_RETRY = 4999
766
+ update(patch: Partial<O>): void;
767
+ toImmutable(): ToImmutable<O>;
768
+ clone(): LiveObject<O>;
977
769
  }
978
770
 
979
771
  /**
980
- * Old connection statuses, here for backward-compatibility reasons only.
981
- */
982
- declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
983
- /**
984
- * Returns a human-readable status indicating the current connection status of
985
- * a Room, as returned by `room.getStatus()`. Can be used to implement
986
- * a connection status badge.
987
- */
988
- declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
989
- /**
990
- * Used to report about app-level reconnection issues.
772
+ * Use this symbol to brand an object property as internal.
991
773
  *
992
- * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
993
- * the application will only get an event if the reconnection attempts by the
994
- * client are taking (much) longer than usual. Definitely a situation you want
995
- * to inform your users about, for example, by throwing a toast message on
996
- * screen, or show a "trying to reconnect" banner.
774
+ * @example
775
+ * Object.defineProperty(
776
+ * {
777
+ * public,
778
+ * [kInternal]: {
779
+ * private
780
+ * },
781
+ * },
782
+ * kInternal,
783
+ * {
784
+ * enumerable: false,
785
+ * }
786
+ * );
997
787
  */
998
- declare type LostConnectionEvent = "lost" | "restored" | "failed";
788
+ declare const kInternal: unique symbol;
789
+
999
790
  /**
1000
- * Arbitrary record that will be used as the authentication "authValue". It's the
1001
- * value that is returned by calling the authentication delegate, and will get
1002
- * passed to the connection factory delegate. This value will be remembered by
1003
- * the connection manager, but its value will not be interpreted, so it can be
1004
- * any value (except null).
791
+ * This helper type is effectively a no-op, but will force TypeScript to
792
+ * "evaluate" any named helper types in its definition. This can sometimes make
793
+ * API signatures clearer in IDEs.
794
+ *
795
+ * For example, in:
796
+ *
797
+ * type Payload<T> = { data: T };
798
+ *
799
+ * let r1: Payload<string>;
800
+ * let r2: Resolve<Payload<string>>;
801
+ *
802
+ * The inferred type of `r1` is going to be `Payload<string>` which shows up in
803
+ * editor hints, and it may be unclear what's inside if you don't know the
804
+ * definition of `Payload`.
805
+ *
806
+ * The inferred type of `r2` is going to be `{ data: string }`, which may be
807
+ * more helpful.
808
+ *
809
+ * This trick comes from:
810
+ * https://effectivetypescript.com/2022/02/25/gentips-4-display/
1005
811
  */
1006
- declare type BaseAuthResult = NonNullable<Json>;
1007
- declare type Delegates<T extends BaseAuthResult> = {
1008
- authenticate: () => Promise<T>;
1009
- createSocket: (authValue: T) => IWebSocketInstance;
1010
- canZombie: () => boolean;
812
+ declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
813
+ [K in keyof T]: T[K];
1011
814
  };
1012
815
 
1013
816
  declare enum ClientMsgCode {
@@ -1337,6 +1140,137 @@ declare type RejectedStorageOpServerMsg = {
1337
1140
  readonly reason: string;
1338
1141
  };
1339
1142
 
1143
+ declare type BaseMetadata = Record<string, string | boolean | number>;
1144
+
1145
+ declare type CommentBodyBlockElement = CommentBodyParagraph;
1146
+ declare type CommentBodyInlineElement = CommentBodyText | CommentBodyMention | CommentBodyLink;
1147
+ declare type CommentBodyElement = CommentBodyBlockElement | CommentBodyInlineElement;
1148
+ declare type CommentBodyParagraph = {
1149
+ type: "paragraph";
1150
+ children: CommentBodyInlineElement[];
1151
+ };
1152
+ declare type CommentBodyMention = {
1153
+ type: "mention";
1154
+ id: string;
1155
+ };
1156
+ declare type CommentBodyLink = {
1157
+ type: "link";
1158
+ url: string;
1159
+ };
1160
+ declare type CommentBodyText = {
1161
+ bold?: boolean;
1162
+ italic?: boolean;
1163
+ strikethrough?: boolean;
1164
+ code?: boolean;
1165
+ text: string;
1166
+ };
1167
+ declare type CommentBody = {
1168
+ version: 1;
1169
+ content: CommentBodyBlockElement[];
1170
+ };
1171
+
1172
+ declare type DateToString<T> = {
1173
+ [P in keyof T]: T[P] extends Date ? string : T[P] extends Date | null ? string | null : T[P] extends Date | undefined ? string | undefined : T[P];
1174
+ };
1175
+
1176
+ declare type CommentReaction = {
1177
+ emoji: string;
1178
+ createdAt: Date;
1179
+ users: {
1180
+ id: string;
1181
+ }[];
1182
+ };
1183
+ /**
1184
+ * Represents a comment.
1185
+ */
1186
+ declare type CommentData = {
1187
+ type: "comment";
1188
+ id: string;
1189
+ threadId: string;
1190
+ roomId: string;
1191
+ userId: string;
1192
+ createdAt: Date;
1193
+ editedAt?: Date;
1194
+ reactions: CommentReaction[];
1195
+ } & ({
1196
+ body: CommentBody;
1197
+ deletedAt?: never;
1198
+ } | {
1199
+ body?: never;
1200
+ deletedAt: Date;
1201
+ });
1202
+ declare type CommentDataPlain = Omit<DateToString<CommentData>, "reactions" | "body"> & {
1203
+ reactions: DateToString<CommentReaction[]>;
1204
+ } & ({
1205
+ body: CommentBody;
1206
+ deletedAt?: never;
1207
+ } | {
1208
+ body?: never;
1209
+ deletedAt: string;
1210
+ });
1211
+
1212
+ declare type CommentUserReaction = {
1213
+ emoji: string;
1214
+ createdAt: Date;
1215
+ userId: string;
1216
+ };
1217
+ declare type CommentUserReactionPlain = DateToString<CommentUserReaction>;
1218
+
1219
+ declare type JsonTreeNode = {
1220
+ readonly type: "Json";
1221
+ readonly id: string;
1222
+ readonly key: string;
1223
+ readonly payload: Json;
1224
+ };
1225
+ declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
1226
+ readonly type: TName;
1227
+ readonly id: string;
1228
+ readonly key: string;
1229
+ readonly payload: LsonTreeNode[];
1230
+ };
1231
+ declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
1232
+ declare type UserTreeNode = {
1233
+ readonly type: "User";
1234
+ readonly id: string;
1235
+ readonly key: string;
1236
+ readonly payload: {
1237
+ readonly connectionId: number;
1238
+ readonly id?: string;
1239
+ readonly info?: Json;
1240
+ readonly presence: JsonObject;
1241
+ readonly isReadOnly: boolean;
1242
+ };
1243
+ };
1244
+ declare type CustomEventTreeNode = {
1245
+ readonly type: "CustomEvent";
1246
+ readonly id: string;
1247
+ readonly key: string;
1248
+ readonly connectionId: number;
1249
+ readonly payload: Json;
1250
+ };
1251
+ declare type TreeNode = LsonTreeNode | UserTreeNode | CustomEventTreeNode;
1252
+
1253
+ type DevToolsTreeNode_CustomEventTreeNode = CustomEventTreeNode;
1254
+ type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
1255
+ type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
1256
+ type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
1257
+ type DevToolsTreeNode_TreeNode = TreeNode;
1258
+ type DevToolsTreeNode_UserTreeNode = UserTreeNode;
1259
+ declare namespace DevToolsTreeNode {
1260
+ export type { DevToolsTreeNode_CustomEventTreeNode as CustomEventTreeNode, DevToolsTreeNode_JsonTreeNode as JsonTreeNode, DevToolsTreeNode_LiveTreeNode as LiveTreeNode, DevToolsTreeNode_LsonTreeNode as LsonTreeNode, DevToolsTreeNode_TreeNode as TreeNode, DevToolsTreeNode_UserTreeNode as UserTreeNode };
1261
+ }
1262
+
1263
+ declare type InboxNotificationThreadData = {
1264
+ kind: "thread";
1265
+ id: string;
1266
+ roomId: string;
1267
+ threadId: string;
1268
+ notifiedAt: Date;
1269
+ readAt: Date | null;
1270
+ };
1271
+ declare type InboxNotificationData = InboxNotificationThreadData;
1272
+ declare type InboxNotificationDataPlain = DateToString<InboxNotificationData>;
1273
+
1340
1274
  /**
1341
1275
  * Represents a user connected in a room. Treated as immutable.
1342
1276
  */
@@ -1396,6 +1330,32 @@ declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUse
1396
1330
  others: readonly User<TPresence, TUserMeta>[];
1397
1331
  }>;
1398
1332
 
1333
+ declare type PartialNullable<T> = {
1334
+ [P in keyof T]?: T[P] | null | undefined;
1335
+ };
1336
+
1337
+ declare type RoomThreadsNotificationSettings = "all" | "replies_and_mentions" | "none";
1338
+ declare type RoomNotificationSettings = {
1339
+ threads: RoomThreadsNotificationSettings;
1340
+ };
1341
+
1342
+ /**
1343
+ * Represents a thread of comments.
1344
+ */
1345
+ declare type ThreadData<TThreadMetadata extends BaseMetadata = never> = {
1346
+ type: "thread";
1347
+ id: string;
1348
+ roomId: string;
1349
+ createdAt: Date;
1350
+ updatedAt?: Date;
1351
+ comments: CommentData[];
1352
+ metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
1353
+ };
1354
+ declare type ThreadDataPlain<TThreadMetadata extends BaseMetadata = never> = Omit<DateToString<ThreadData<TThreadMetadata>>, "comments" | "metadata"> & {
1355
+ comments: CommentDataPlain[];
1356
+ metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
1357
+ };
1358
+
1399
1359
  declare type LegacyOthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
1400
1360
  type: "leave";
1401
1361
  user: User<TPresence, TUserMeta>;
@@ -1670,9 +1630,95 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
1670
1630
  * }
1671
1631
  * });
1672
1632
  */
1673
- (type: "storage-status", listener: Callback<StorageStatus>): () => void;
1633
+ (type: "storage-status", listener: Callback<StorageStatus>): () => void;
1634
+ };
1635
+ declare type GetThreadsOptions<TThreadMetadata extends BaseMetadata> = {
1636
+ query?: {
1637
+ metadata?: Partial<TThreadMetadata>;
1638
+ };
1639
+ };
1640
+ declare type CommentsApi<TThreadMetadata extends BaseMetadata = never> = {
1641
+ /**
1642
+ * @private
1643
+ */
1644
+ getThreads(options?: GetThreadsOptions<TThreadMetadata>): Promise<{
1645
+ threads: ThreadData<TThreadMetadata>[];
1646
+ inboxNotifications: InboxNotificationData[];
1647
+ }>;
1648
+ /**
1649
+ * @private
1650
+ */
1651
+ getThread(options: {
1652
+ threadId: string;
1653
+ }): Promise<{
1654
+ thread: ThreadData<TThreadMetadata>;
1655
+ inboxNotification?: InboxNotificationData;
1656
+ } | undefined>;
1657
+ /**
1658
+ * @private
1659
+ */
1660
+ createThread(options: {
1661
+ threadId: string;
1662
+ commentId: string;
1663
+ metadata: TThreadMetadata | undefined;
1664
+ body: CommentBody;
1665
+ }): Promise<ThreadData<TThreadMetadata>>;
1666
+ /**
1667
+ * @private
1668
+ */
1669
+ editThreadMetadata(options: {
1670
+ metadata: PartialNullable<TThreadMetadata>;
1671
+ threadId: string;
1672
+ }): Promise<TThreadMetadata>;
1673
+ /**
1674
+ * @private
1675
+ */
1676
+ createComment(options: {
1677
+ threadId: string;
1678
+ commentId: string;
1679
+ body: CommentBody;
1680
+ }): Promise<CommentData>;
1681
+ /**
1682
+ * @private
1683
+ */
1684
+ editComment(options: {
1685
+ threadId: string;
1686
+ commentId: string;
1687
+ body: CommentBody;
1688
+ }): Promise<CommentData>;
1689
+ /**
1690
+ * @private
1691
+ */
1692
+ deleteComment(options: {
1693
+ threadId: string;
1694
+ commentId: string;
1695
+ }): Promise<void>;
1696
+ /**
1697
+ * @private
1698
+ */
1699
+ addReaction(options: {
1700
+ threadId: string;
1701
+ commentId: string;
1702
+ emoji: string;
1703
+ }): Promise<CommentUserReaction>;
1704
+ /**
1705
+ * @private
1706
+ */
1707
+ removeReaction(options: {
1708
+ threadId: string;
1709
+ commentId: string;
1710
+ emoji: string;
1711
+ }): Promise<void>;
1674
1712
  };
1675
1713
  declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = CommentsApi<any> & {
1714
+ /**
1715
+ * @private
1716
+ *
1717
+ * Private methods and variables used in the core internals, but as a user
1718
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
1719
+ * will probably happen if you do.
1720
+ */
1721
+ readonly [kInternal]: PrivateRoomApi;
1676
1722
  /**
1677
1723
  * The id of the room.
1678
1724
  */
@@ -1810,6 +1856,14 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1810
1856
  readonly ydoc: Observable<YDocUpdateServerMsg | UpdateYDocClientMsg>;
1811
1857
  readonly comments: Observable<CommentsEventServerMsg>;
1812
1858
  };
1859
+ /**
1860
+ * @private
1861
+ */
1862
+ getRoomNotificationSettings(): Promise<RoomNotificationSettings>;
1863
+ /**
1864
+ * @private
1865
+ */
1866
+ updateRoomNotificationSettings(settings: Partial<RoomNotificationSettings>): Promise<RoomNotificationSettings>;
1813
1867
  /**
1814
1868
  * Batches modifications made during the given function.
1815
1869
  * All the modifications are sent to other clients in a single message.
@@ -1857,6 +1911,29 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1857
1911
  */
1858
1912
  reconnect(): void;
1859
1913
  };
1914
+ /**
1915
+ * @private
1916
+ *
1917
+ * Private methods to directly control the underlying state machine for this
1918
+ * room. Used in the core internals and for unit testing, but as a user of
1919
+ * Liveblocks, NEVER USE ANY OF THESE METHODS DIRECTLY, because bad things
1920
+ * will probably happen if you do.
1921
+ */
1922
+ declare type PrivateRoomApi = {
1923
+ presenceBuffer: Json | undefined;
1924
+ undoStack: readonly (readonly Readonly<HistoryOp<JsonObject>>[])[];
1925
+ nodeCount: number;
1926
+ getSelf_forDevTools(): UserTreeNode | null;
1927
+ getOthers_forDevTools(): readonly UserTreeNode[];
1928
+ simulate: {
1929
+ explicitClose(event: IWebSocketCloseEvent): void;
1930
+ rawSend(data: string): void;
1931
+ };
1932
+ };
1933
+ declare type HistoryOp<TPresence extends JsonObject> = Op | {
1934
+ readonly type: "presence";
1935
+ readonly data: TPresence;
1936
+ };
1860
1937
  declare type Polyfills = {
1861
1938
  atob?: (data: string) => string;
1862
1939
  fetch?: typeof fetch;
@@ -1883,7 +1960,177 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1883
1960
  /** @deprecated Renamed to `autoConnect` */
1884
1961
  shouldInitiallyConnect?: boolean;
1885
1962
  }>;
1963
+ declare class CommentsApiError extends Error {
1964
+ message: string;
1965
+ status: number;
1966
+ details?: JsonObject | undefined;
1967
+ constructor(message: string, status: number, details?: JsonObject | undefined);
1968
+ }
1969
+
1970
+ declare type BatchStoreStateLoading = {
1971
+ isLoading: true;
1972
+ data?: never;
1973
+ error?: never;
1974
+ };
1975
+ declare type BatchStoreStateError = {
1976
+ isLoading: false;
1977
+ data?: never;
1978
+ error: Error;
1979
+ };
1980
+ declare type BatchStoreStateSuccess<T> = {
1981
+ isLoading: false;
1982
+ data: T;
1983
+ error?: never;
1984
+ };
1985
+ declare type BatchStoreState<T> = BatchStoreStateLoading | BatchStoreStateError | BatchStoreStateSuccess<T>;
1986
+ declare type BatchStore<T, A extends unknown[]> = EventSource<BatchStoreState<T> | undefined> & {
1987
+ get: (...args: A) => Promise<void>;
1988
+ getState: (...args: A) => BatchStoreState<T> | undefined;
1989
+ };
1990
+
1991
+ declare type Store<T> = {
1992
+ get: () => T;
1993
+ set: (callback: (currentState: T) => T) => void;
1994
+ subscribe: (callback: (state: T) => void) => () => void;
1995
+ };
1996
+
1997
+ declare type OptimisticUpdate<TThreadMetadata extends BaseMetadata> = CreateThreadOptimisticUpdate<TThreadMetadata> | EditThreadMetadataOptimisticUpdate<TThreadMetadata> | CreateCommentOptimisticUpdate | EditCommentOptimisticUpdate | DeleteCommentOptimisticUpdate | AddReactionOptimisticUpdate | RemoveReactionOptimisticUpdate | MarkInboxNotificationAsReadOptimisticUpdate | MarkAllInboxNotificationsAsReadOptimisticUpdate | UpdateNotificationSettingsOptimisticUpdate;
1998
+ declare type CreateThreadOptimisticUpdate<TThreadMetadata extends BaseMetadata> = {
1999
+ type: "create-thread";
2000
+ id: string;
2001
+ thread: ThreadData<TThreadMetadata>;
2002
+ };
2003
+ declare type EditThreadMetadataOptimisticUpdate<TThreadMetadata extends BaseMetadata> = {
2004
+ type: "edit-thread-metadata";
2005
+ id: string;
2006
+ threadId: string;
2007
+ metadata: Resolve<PartialNullable<TThreadMetadata>>;
2008
+ };
2009
+ declare type CreateCommentOptimisticUpdate = {
2010
+ type: "create-comment";
2011
+ id: string;
2012
+ comment: CommentData;
2013
+ inboxNotificationId?: string;
2014
+ };
2015
+ declare type EditCommentOptimisticUpdate = {
2016
+ type: "edit-comment";
2017
+ id: string;
2018
+ threadId: string;
2019
+ editedAt: Date;
2020
+ commentId: string;
2021
+ body: CommentBody;
2022
+ };
2023
+ declare type DeleteCommentOptimisticUpdate = {
2024
+ type: "delete-comment";
2025
+ id: string;
2026
+ threadId: string;
2027
+ deletedAt: Date;
2028
+ commentId: string;
2029
+ };
2030
+ declare type AddReactionOptimisticUpdate = {
2031
+ type: "add-reaction";
2032
+ id: string;
2033
+ threadId: string;
2034
+ commentId: string;
2035
+ emoji: string;
2036
+ createdAt: Date;
2037
+ userId: string;
2038
+ };
2039
+ declare type RemoveReactionOptimisticUpdate = {
2040
+ type: "remove-reaction";
2041
+ id: string;
2042
+ threadId: string;
2043
+ commentId: string;
2044
+ emoji: string;
2045
+ userId: string;
2046
+ };
2047
+ declare type MarkInboxNotificationAsReadOptimisticUpdate = {
2048
+ type: "mark-inbox-notification-as-read";
2049
+ id: string;
2050
+ inboxNotificationId: string;
2051
+ readAt: Date;
2052
+ };
2053
+ declare type MarkAllInboxNotificationsAsReadOptimisticUpdate = {
2054
+ type: "mark-inbox-notifications-as-read";
2055
+ id: string;
2056
+ readAt: Date;
2057
+ };
2058
+ declare type UpdateNotificationSettingsOptimisticUpdate = {
2059
+ type: "update-notification-settings";
2060
+ id: string;
2061
+ roomId: string;
2062
+ settings: Partial<RoomNotificationSettings>;
2063
+ };
2064
+ declare type QueryState = {
2065
+ isLoading: true;
2066
+ error?: never;
2067
+ } | {
2068
+ isLoading: false;
2069
+ error?: Error;
2070
+ };
2071
+ declare type CacheState<TThreadMetadata extends BaseMetadata> = {
2072
+ /**
2073
+ * Threads by ID.
2074
+ */
2075
+ threads: Record<string, ThreadData<TThreadMetadata>>;
2076
+ /**
2077
+ * Keep track of loading and error status of all the queries made by the client.
2078
+ */
2079
+ queries: Record<string, QueryState>;
2080
+ /**
2081
+ * Optimistic updates that have not been acknowledged by the server yet.
2082
+ * They are applied on top of the threads in selectors.
2083
+ */
2084
+ optimisticUpdates: OptimisticUpdate<TThreadMetadata>[];
2085
+ /**
2086
+ * Inbox notifications by ID.
2087
+ */
2088
+ inboxNotifications: Record<string, InboxNotificationData>;
2089
+ /**
2090
+ * Notification settings per room id
2091
+ */
2092
+ notificationSettings: Record<string, RoomNotificationSettings>;
2093
+ };
2094
+ interface CacheStore<TThreadMetadata extends BaseMetadata> extends Store<CacheState<TThreadMetadata>> {
2095
+ deleteThread(threadId: string): void;
2096
+ updateThreadAndNotification(thread: ThreadData<TThreadMetadata>, inboxNotification?: InboxNotificationData): void;
2097
+ updateThreadsAndNotifications(threads: ThreadData<TThreadMetadata>[], inboxNotifications: InboxNotificationData[], queryKey?: string): void;
2098
+ pushOptimisticUpdate(optimisticUpdate: OptimisticUpdate<TThreadMetadata>): void;
2099
+ setQueryState(queryKey: string, queryState: QueryState): void;
2100
+ }
2101
+ declare function applyOptimisticUpdates<TThreadMetadata extends BaseMetadata>(state: CacheState<TThreadMetadata>): Pick<CacheState<TThreadMetadata>, "threads" | "inboxNotifications" | "notificationSettings">;
2102
+
2103
+ declare type OptionalPromise<T> = T | Promise<T>;
2104
+
2105
+ declare type RoomInfo = {
2106
+ /**
2107
+ * The name of the room.
2108
+ */
2109
+ name?: string;
2110
+ };
1886
2111
 
2112
+ declare type ResolveMentionSuggestionsArgs = {
2113
+ /**
2114
+ * The ID of the current room.
2115
+ */
2116
+ roomId: string;
2117
+ /**
2118
+ * The text to search for.
2119
+ */
2120
+ text: string;
2121
+ };
2122
+ declare type ResolveUsersArgs = {
2123
+ /**
2124
+ * The IDs of the users to resolve.
2125
+ */
2126
+ userIds: string[];
2127
+ };
2128
+ declare type ResolveRoomsInfoArgs = {
2129
+ /**
2130
+ * The IDs of the rooms to resolve.
2131
+ */
2132
+ roomIds: string[];
2133
+ };
1887
2134
  declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<RoomInitializers<TPresence, TStorage> & {
1888
2135
  /**
1889
2136
  * Only necessary when you’re using Liveblocks with React v17 or lower.
@@ -1895,7 +2142,42 @@ declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObj
1895
2142
  */
1896
2143
  unstable_batchedUpdates?: (cb: () => void) => void;
1897
2144
  }>;
1898
- declare type Client = {
2145
+ /**
2146
+ * @private
2147
+ *
2148
+ * Private methods and variables used in the core internals, but as a user
2149
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
2150
+ * will probably happen if you do.
2151
+ */
2152
+ declare type PrivateClientApi<TUserMeta extends BaseUserMeta> = {
2153
+ currentUserIdStore: Store<string | null>;
2154
+ resolveMentionSuggestions: ClientOptions["resolveMentionSuggestions"];
2155
+ cacheStore: CacheStore<BaseMetadata>;
2156
+ usersStore: BatchStore<TUserMeta["info"] | undefined, [string]>;
2157
+ roomsInfoStore: BatchStore<RoomInfo | undefined, [string]>;
2158
+ };
2159
+ declare type InboxNotificationsApi<TThreadMetadata extends BaseMetadata = never> = {
2160
+ /**
2161
+ * @private
2162
+ */
2163
+ getInboxNotifications(): Promise<{
2164
+ inboxNotifications: InboxNotificationData[];
2165
+ threads: ThreadData<TThreadMetadata>[];
2166
+ }>;
2167
+ /**
2168
+ * @private
2169
+ */
2170
+ getUnreadInboxNotificationsCount(): Promise<number>;
2171
+ /**
2172
+ * @private
2173
+ */
2174
+ markAllInboxNotificationsAsRead(): Promise<void>;
2175
+ /**
2176
+ * @private
2177
+ */
2178
+ markInboxNotificationAsRead(inboxNotificationId: string): Promise<void>;
2179
+ };
2180
+ declare type Client<TUserMeta extends BaseUserMeta = BaseUserMeta> = InboxNotificationsApi & {
1899
2181
  /**
1900
2182
  * Gets a room. Returns null if {@link Client.enter} has not been called previously.
1901
2183
  *
@@ -1940,13 +2222,21 @@ declare type Client = {
1940
2222
  * Call this whenever you log out a user in your application.
1941
2223
  */
1942
2224
  logout(): void;
2225
+ /**
2226
+ * @private
2227
+ *
2228
+ * Private methods and variables used in the core internals, but as a user
2229
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
2230
+ * will probably happen if you do.
2231
+ */
2232
+ readonly [kInternal]: PrivateClientApi<TUserMeta>;
1943
2233
  };
1944
- declare type AuthEndpoint = string | ((room: string) => Promise<CustomAuthenticationResult>);
2234
+ declare type AuthEndpoint = string | ((room?: string) => Promise<CustomAuthenticationResult>);
1945
2235
  /**
1946
2236
  * The authentication endpoint that is called to ensure that the current user has access to a room.
1947
2237
  * Can be an url or a callback if you need to add additional headers.
1948
2238
  */
1949
- declare type ClientOptions = {
2239
+ declare type ClientOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
1950
2240
  throttle?: number;
1951
2241
  lostConnectionTimeout?: number;
1952
2242
  backgroundKeepAliveTimeout?: number;
@@ -1954,48 +2244,177 @@ declare type ClientOptions = {
1954
2244
  unstable_fallbackToHTTP?: boolean;
1955
2245
  unstable_streamData?: boolean;
1956
2246
  /**
1957
- * @deprecated Use `polyfills: { fetch: ... }` instead.
1958
- * This option will be removed in a future release.
2247
+ * @deprecated Use `polyfills: { fetch: ... }` instead.
2248
+ * This option will be removed in a future release.
2249
+ */
2250
+ fetchPolyfill?: Polyfills["fetch"];
2251
+ /**
2252
+ * @deprecated Use `polyfills: { WebSocket: ... }` instead.
2253
+ * This option will be removed in a future release.
2254
+ */
2255
+ WebSocketPolyfill?: Polyfills["WebSocket"];
2256
+ /**
2257
+ * @beta
2258
+ *
2259
+ * A function that returns a list of user IDs matching a string.
2260
+ */
2261
+ resolveMentionSuggestions?: (args: ResolveMentionSuggestionsArgs) => OptionalPromise<string[]>;
2262
+ /**
2263
+ * @beta
2264
+ *
2265
+ * A function that returns user info from user IDs.
2266
+ */
2267
+ resolveUsers?: (args: ResolveUsersArgs) => OptionalPromise<(TUserMeta["info"] | undefined)[] | undefined>;
2268
+ /**
2269
+ * @beta
2270
+ *
2271
+ * A function that returns room info from room IDs.
2272
+ */
2273
+ resolveRoomsInfo?: (args: ResolveRoomsInfoArgs) => OptionalPromise<(RoomInfo | undefined)[] | undefined>;
2274
+ } & ({
2275
+ publicApiKey: string;
2276
+ authEndpoint?: never;
2277
+ } | {
2278
+ publicApiKey?: never;
2279
+ authEndpoint: AuthEndpoint;
2280
+ });
2281
+ /**
2282
+ * Create a client that will be responsible to communicate with liveblocks servers.
2283
+ *
2284
+ * @example
2285
+ * const client = createClient({
2286
+ * authEndpoint: "/api/auth"
2287
+ * });
2288
+ *
2289
+ * // It's also possible to use a function to call your authentication endpoint.
2290
+ * // Useful to add additional headers or use an API wrapper (like Firebase functions)
2291
+ * const client = createClient({
2292
+ * authEndpoint: async (room?) => {
2293
+ * const response = await fetch("/api/auth", {
2294
+ * method: "POST",
2295
+ * headers: {
2296
+ * Authentication: "token",
2297
+ * "Content-Type": "application/json"
2298
+ * },
2299
+ * body: JSON.stringify({ room })
2300
+ * });
2301
+ *
2302
+ * return await response.json(); // should be: { token: "..." }
2303
+ * }
2304
+ * });
2305
+ */
2306
+ declare function createClient<TUserMeta extends BaseUserMeta = BaseUserMeta>(options: ClientOptions<TUserMeta>): Client<TUserMeta>;
2307
+ declare class NotificationsApiError extends Error {
2308
+ message: string;
2309
+ status: number;
2310
+ details?: JsonObject | undefined;
2311
+ constructor(message: string, status: number, details?: JsonObject | undefined);
2312
+ }
2313
+
2314
+ declare type CommentBodyParagraphElementArgs = {
2315
+ /**
2316
+ * The paragraph element.
2317
+ */
2318
+ element: CommentBodyParagraph;
2319
+ /**
2320
+ * The text content of the paragraph.
2321
+ */
2322
+ children: string;
2323
+ };
2324
+ declare type CommentBodyTextElementArgs = {
2325
+ /**
2326
+ * The text element.
2327
+ */
2328
+ element: CommentBodyText;
2329
+ };
2330
+ declare type CommentBodyLinkElementArgs = {
2331
+ /**
2332
+ * The link element.
2333
+ */
2334
+ element: CommentBodyLink;
2335
+ /**
2336
+ * The absolute URL of the link.
2337
+ */
2338
+ href: string;
2339
+ };
2340
+ declare type CommentBodyMentionElementArgs<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2341
+ /**
2342
+ * The mention element.
2343
+ */
2344
+ element: CommentBodyMention;
2345
+ /**
2346
+ * The mention's user info, if the `resolvedUsers` option was provided.
2347
+ */
2348
+ user?: TUserMeta["info"];
2349
+ };
2350
+ declare type StringifyCommentBodyElements<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2351
+ /**
2352
+ * The element used to display paragraphs.
2353
+ */
2354
+ paragraph: (args: CommentBodyParagraphElementArgs, index: number) => string;
2355
+ /**
2356
+ * The element used to display text elements.
2357
+ */
2358
+ text: (args: CommentBodyTextElementArgs, index: number) => string;
2359
+ /**
2360
+ * The element used to display links.
2361
+ */
2362
+ link: (args: CommentBodyLinkElementArgs, index: number) => string;
2363
+ /**
2364
+ * The element used to display mentions.
2365
+ */
2366
+ mention: (args: CommentBodyMentionElementArgs<TUserMeta>, index: number) => string;
2367
+ };
2368
+ declare type StringifyCommentBodyOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2369
+ /**
2370
+ * Which format to convert the comment to.
2371
+ */
2372
+ format?: "plain" | "html" | "markdown";
2373
+ /**
2374
+ * The elements used to customize the resulting string. Each element has
2375
+ * priority over the defaults inherited from the `format` option.
1959
2376
  */
1960
- fetchPolyfill?: Polyfills["fetch"];
2377
+ elements?: Partial<StringifyCommentBodyElements<TUserMeta>>;
1961
2378
  /**
1962
- * @deprecated Use `polyfills: { WebSocket: ... }` instead.
1963
- * This option will be removed in a future release.
2379
+ * The separator used between paragraphs.
1964
2380
  */
1965
- WebSocketPolyfill?: Polyfills["WebSocket"];
1966
- } & ({
1967
- publicApiKey: string;
1968
- authEndpoint?: never;
1969
- } | {
1970
- publicApiKey?: never;
1971
- authEndpoint: AuthEndpoint;
1972
- });
2381
+ separator?: string;
2382
+ /**
2383
+ * A function that returns user info from user IDs.
2384
+ */
2385
+ resolveUsers?: (args: ResolveUsersArgs) => OptionalPromise<(TUserMeta["info"] | undefined)[] | undefined>;
2386
+ };
1973
2387
  /**
1974
- * Create a client that will be responsible to communicate with liveblocks servers.
1975
- *
1976
- * @example
1977
- * const client = createClient({
1978
- * authEndpoint: "/api/auth"
1979
- * });
1980
- *
1981
- * // It's also possible to use a function to call your authentication endpoint.
1982
- * // Useful to add additional headers or use an API wrapper (like Firebase functions)
1983
- * const client = createClient({
1984
- * authEndpoint: async (room) => {
1985
- * const response = await fetch("/api/auth", {
1986
- * method: "POST",
1987
- * headers: {
1988
- * Authentication: "token",
1989
- * "Content-Type": "application/json"
1990
- * },
1991
- * body: JSON.stringify({ room })
1992
- * });
1993
- *
1994
- * return await response.json(); // should be: { token: "..." }
1995
- * }
1996
- * });
2388
+ * Get an array of each user's ID that has been mentioned in a `CommentBody`.
2389
+ */
2390
+ declare function getMentionedIdsFromCommentBody(body: CommentBody): string[];
2391
+ /**
2392
+ * Convert a `CommentBody` into either a plain string,
2393
+ * Markdown, HTML, or a custom format.
2394
+ */
2395
+ declare function stringifyCommentBody<TUserMeta extends BaseUserMeta = BaseUserMeta>(body: CommentBody, options?: StringifyCommentBodyOptions<TUserMeta>): Promise<string>;
2396
+
2397
+ /**
2398
+ * Converts a plain comment data object (usually returned by the API) to a comment data object that can be used by the client.
2399
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2400
+ * @param data The plain comment data object (usually returned by the API)
2401
+ * @returns The rich comment data object that can be used by the client.
2402
+ */
2403
+ declare function convertToCommentData(data: CommentDataPlain): CommentData;
2404
+ /**
2405
+ * Converts a plain thread data object (usually returned by the API) to a thread data object that can be used by the client.
2406
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2407
+ * @param data The plain thread data object (usually returned by the API)
2408
+ * @returns The rich thread data object that can be used by the client.
1997
2409
  */
1998
- declare function createClient(options: ClientOptions): Client;
2410
+ declare function convertToThreadData<TThreadMetadata extends BaseMetadata = never>(data: ThreadDataPlain<TThreadMetadata>): ThreadData<TThreadMetadata>;
2411
+ /**
2412
+ * Converts a plain comment reaction object (usually returned by the API) to a comment reaction object that can be used by the client.
2413
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2414
+ * @param data The plain comment reaction object (usually returned by the API)
2415
+ * @returns The rich comment reaction object that can be used by the client.
2416
+ */
2417
+ declare function convertToCommentUserReaction(data: CommentUserReactionPlain): CommentUserReaction;
1999
2418
 
2000
2419
  /**
2001
2420
  * Lookup table for nodes (= SerializedCrdt values) by their IDs.
@@ -2059,93 +2478,6 @@ declare function assert(condition: boolean, errmsg: string): asserts condition;
2059
2478
  */
2060
2479
  declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
2061
2480
 
2062
- declare type PromiseOrNot$1<T> = T | Promise<T>;
2063
- declare type AsyncCacheFunction<T, A extends any[] = any[]> = (...args: A) => PromiseOrNot$1<T>;
2064
- declare type AsyncCacheOptions<T, E> = {
2065
- isStateEqual?: (a: AsyncState<T, E>, b: AsyncState<T, E>) => boolean;
2066
- };
2067
- declare type AsyncStateInitial = {
2068
- readonly isLoading: false;
2069
- readonly data?: never;
2070
- readonly error?: never;
2071
- };
2072
- declare type AsyncStateLoading<T> = {
2073
- readonly isLoading: true;
2074
- readonly data?: T;
2075
- readonly error?: never;
2076
- };
2077
- declare type AsyncStateSuccess<T> = {
2078
- readonly isLoading: false;
2079
- readonly data: T;
2080
- readonly error?: never;
2081
- };
2082
- declare type AsyncStateError<T, E> = {
2083
- readonly isLoading: false;
2084
- readonly data?: T;
2085
- readonly error: E;
2086
- };
2087
- declare type AsyncState<T, E> = AsyncStateInitial | AsyncStateLoading<T> | AsyncStateSuccess<T> | AsyncStateError<T, E>;
2088
- declare type AsyncStateResolved<T, E> = AsyncStateSuccess<T> | AsyncStateError<T, E>;
2089
- declare type AsyncCacheItem<T, E> = Observable<AsyncState<T, E>> & {
2090
- get(): Promise<AsyncStateResolved<T, E>>;
2091
- getState(): AsyncState<T, E>;
2092
- revalidate(): Promise<AsyncStateResolved<T, E>>;
2093
- };
2094
- declare type AsyncCache<T, E> = {
2095
- /**
2096
- * @private
2097
- *
2098
- * Creates a key in the cache.
2099
- *
2100
- * @param key The key to create.
2101
- * @param asyncFunction Override the cache's function for this key.
2102
- */
2103
- create(key: string, asyncFunction?: AsyncCacheFunction<T, [string]>): AsyncCacheItem<T, E>;
2104
- /**
2105
- * Returns a promise which resolves with the state of the key.
2106
- *
2107
- * @param key The key to get.
2108
- */
2109
- get(key: string): Promise<AsyncStateResolved<T, E>>;
2110
- /**
2111
- * Returns the current state of the key synchronously.
2112
- *
2113
- * @param key The key to get the state of.
2114
- */
2115
- getState(key: string): AsyncState<T, E> | undefined;
2116
- /**
2117
- * Revalidates the key.
2118
- *
2119
- * @param key The key to revalidate.
2120
- */
2121
- revalidate(key: string): Promise<AsyncStateResolved<T, E>>;
2122
- /**
2123
- * Subscribes to the key's changes.
2124
- *
2125
- * @param key The key to subscribe to.
2126
- * @param callback The function invoked on every change.
2127
- */
2128
- subscribe(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2129
- /**
2130
- * Subscribes to the key's changes once.
2131
- *
2132
- * @param key The key to subscribe to.
2133
- * @param callback The function invoked on every change.
2134
- */
2135
- subscribeOnce(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2136
- /**
2137
- * Returns whether a key already exists in the cache.
2138
- *
2139
- * @param key The key to look for.
2140
- */
2141
- has(key: string): boolean;
2142
- /**
2143
- * Clears all keys.
2144
- */
2145
- clear(): void;
2146
- };
2147
- declare function createAsyncCache<T, E>(asyncFunction: AsyncCacheFunction<T, [string]>, options?: AsyncCacheOptions<T, E>): AsyncCache<T, E>;
2148
-
2149
2481
  /**
2150
2482
  * Displays a deprecation warning in the dev console. Only in dev mode, and
2151
2483
  * only once per message/key. In production, this is a no-op.
@@ -2306,50 +2638,6 @@ declare function shallow(a: unknown, b: unknown): boolean;
2306
2638
  declare type OmitFirstTupleElement<T extends any[]> = T extends [any, ...infer R] ? R : never;
2307
2639
  declare function stringify(object: Parameters<typeof JSON.stringify>[0], ...args: OmitFirstTupleElement<Parameters<typeof JSON.stringify>>): string;
2308
2640
 
2309
- declare type JsonTreeNode = {
2310
- readonly type: "Json";
2311
- readonly id: string;
2312
- readonly key: string;
2313
- readonly payload: Json;
2314
- };
2315
- declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
2316
- readonly type: TName;
2317
- readonly id: string;
2318
- readonly key: string;
2319
- readonly payload: LsonTreeNode[];
2320
- };
2321
- declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
2322
- declare type UserTreeNode = {
2323
- readonly type: "User";
2324
- readonly id: string;
2325
- readonly key: string;
2326
- readonly payload: {
2327
- readonly connectionId: number;
2328
- readonly id?: string;
2329
- readonly info?: Json;
2330
- readonly presence: JsonObject;
2331
- readonly isReadOnly: boolean;
2332
- };
2333
- };
2334
- declare type CustomEventTreeNode = {
2335
- readonly type: "CustomEvent";
2336
- readonly id: string;
2337
- readonly key: string;
2338
- readonly connectionId: number;
2339
- readonly payload: Json;
2340
- };
2341
- declare type TreeNode = LsonTreeNode | UserTreeNode | CustomEventTreeNode;
2342
-
2343
- type DevToolsTreeNode_CustomEventTreeNode = CustomEventTreeNode;
2344
- type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
2345
- type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
2346
- type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
2347
- type DevToolsTreeNode_TreeNode = TreeNode;
2348
- type DevToolsTreeNode_UserTreeNode = UserTreeNode;
2349
- declare namespace DevToolsTreeNode {
2350
- export type { DevToolsTreeNode_CustomEventTreeNode as CustomEventTreeNode, DevToolsTreeNode_JsonTreeNode as JsonTreeNode, DevToolsTreeNode_LiveTreeNode as LiveTreeNode, DevToolsTreeNode_LsonTreeNode as LsonTreeNode, DevToolsTreeNode_TreeNode as TreeNode, DevToolsTreeNode_UserTreeNode as UserTreeNode };
2351
- }
2352
-
2353
2641
  /**
2354
2642
  * Definition of all messages the Panel can send to the Client.
2355
2643
  */
@@ -2470,117 +2758,6 @@ declare namespace protocol {
2470
2758
  export type { protocol_ClientToPanelMessage as ClientToPanelMessage, protocol_FullClientToPanelMessage as FullClientToPanelMessage, protocol_FullPanelToClientMessage as FullPanelToClientMessage, protocol_PanelToClientMessage as PanelToClientMessage };
2471
2759
  }
2472
2760
 
2473
- declare type PromiseOrNot<T> = T | Promise<T>;
2474
- declare type CommentBodyResolveUsersArgs = {
2475
- /**
2476
- * The ID of the users to resolve.
2477
- */
2478
- userIds: string[];
2479
- };
2480
- declare type CommentBodyParagraphElementArgs = {
2481
- /**
2482
- * The paragraph element.
2483
- */
2484
- element: CommentBodyParagraph;
2485
- /**
2486
- * The text content of the paragraph.
2487
- */
2488
- children: string;
2489
- };
2490
- declare type CommentBodyTextElementArgs = {
2491
- /**
2492
- * The text element.
2493
- */
2494
- element: CommentBodyText;
2495
- };
2496
- declare type CommentBodyLinkElementArgs = {
2497
- /**
2498
- * The link element.
2499
- */
2500
- element: CommentBodyLink;
2501
- /**
2502
- * The absolute URL of the link.
2503
- */
2504
- href: string;
2505
- };
2506
- declare type CommentBodyMentionElementArgs<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2507
- /**
2508
- * The mention element.
2509
- */
2510
- element: CommentBodyMention;
2511
- /**
2512
- * The mention's user info, if the `resolvedUsers` option was provided.
2513
- */
2514
- user?: TUserMeta["info"];
2515
- };
2516
- declare type StringifyCommentBodyElements<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2517
- /**
2518
- * The element used to display paragraphs.
2519
- */
2520
- paragraph: (args: CommentBodyParagraphElementArgs, index: number) => string;
2521
- /**
2522
- * The element used to display text elements.
2523
- */
2524
- text: (args: CommentBodyTextElementArgs, index: number) => string;
2525
- /**
2526
- * The element used to display links.
2527
- */
2528
- link: (args: CommentBodyLinkElementArgs, index: number) => string;
2529
- /**
2530
- * The element used to display mentions.
2531
- */
2532
- mention: (args: CommentBodyMentionElementArgs<TUserMeta>, index: number) => string;
2533
- };
2534
- declare type StringifyCommentBodyOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2535
- /**
2536
- * Which format to convert the comment to.
2537
- */
2538
- format?: "plain" | "html" | "markdown";
2539
- /**
2540
- * The elements used to customize the resulting string. Each element has
2541
- * priority over the defaults inherited from the `format` option.
2542
- */
2543
- elements?: Partial<StringifyCommentBodyElements<TUserMeta>>;
2544
- /**
2545
- * The separator used between paragraphs.
2546
- */
2547
- separator?: string;
2548
- /**
2549
- * A function that returns user info from user IDs.
2550
- */
2551
- resolveUsers?: (args: CommentBodyResolveUsersArgs) => PromiseOrNot<(TUserMeta["info"] | undefined)[] | undefined>;
2552
- };
2553
- /**
2554
- * Get an array of each user's ID that has been mentioned in a `CommentBody`.
2555
- */
2556
- declare function getMentionedIdsFromCommentBody(body: CommentBody): string[];
2557
- /**
2558
- * Convert a `CommentBody` into either a plain string,
2559
- * Markdown, HTML, or a custom format.
2560
- */
2561
- declare function stringifyCommentBody<TUserMeta extends BaseUserMeta = BaseUserMeta>(body: CommentBody, options?: StringifyCommentBodyOptions<TUserMeta>): Promise<string>;
2562
- /**
2563
- * Converts a plain comment data object (usually returned by the API) to a comment data object that can be used by the client.
2564
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2565
- * @param data The plain comment data object (usually returned by the API)
2566
- * @returns The rich comment data object that can be used by the client.
2567
- */
2568
- declare function convertToCommentData(data: CommentDataPlain): CommentData;
2569
- /**
2570
- * Converts a plain thread data object (usually returned by the API) to a thread data object that can be used by the client.
2571
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2572
- * @param data The plain thread data object (usually returned by the API)
2573
- * @returns The rich hread data object that can be used by the client.
2574
- */
2575
- declare function convertToThreadData<TThreadMetadata extends BaseMetadata = never>(data: ThreadDataPlain<TThreadMetadata>): ThreadData<TThreadMetadata>;
2576
- /**
2577
- * Converts a plain comment reaction object (usually returned by the API) to a comment reaction object that can be used by the client.
2578
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2579
- * @param data The plain comment reaction object (usually returned by the API)
2580
- * @returns The rich comment reaction object that can be used by the client.
2581
- */
2582
- declare function convertToCommentUserReaction(data: CommentUserReactionPlain): CommentUserReaction;
2583
-
2584
2761
  /**
2585
2762
  * Helper type to help users adopt to Lson types from interface definitions.
2586
2763
  * You should only use this to wrap interfaces you don't control. For more
@@ -2593,4 +2770,4 @@ declare type EnsureJson<T> = [
2593
2770
  [K in keyof T]: EnsureJson<T[K]>;
2594
2771
  };
2595
2772
 
2596
- export { type AckOp, type AsyncCache, type AsyncState, type AsyncStateError, type AsyncStateInitial, type AsyncStateLoading, type AsyncStateResolved, type AsyncStateSuccess, type BaseAuthResult, type BaseMetadata, type BaseUserMeta, type Brand, type BroadcastEventClientMsg, type BroadcastOptions, type BroadcastedEventServerMsg, type Client, type ClientMsg, ClientMsgCode, type CommentBody, type CommentBodyBlockElement, type CommentBodyElement, type CommentBodyInlineElement, type CommentBodyLink, type CommentBodyLinkElementArgs, type CommentBodyMention, type CommentBodyMentionElementArgs, type CommentBodyParagraph, type CommentBodyParagraphElementArgs, type CommentBodyResolveUsersArgs, type CommentBodyText, type CommentBodyTextElementArgs, type CommentData, type CommentDataPlain, type CommentReaction, type CommentUserReaction, type CommentUserReactionPlain, type CommentsApi, CommentsApiError, CrdtType, type CreateListOp, type CreateMapOp, type CreateObjectOp, type CreateOp, type CreateRegisterOp, type CustomAuthenticationResult, type Delegates, type DeleteCrdtOp, type DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, type EnsureJson, type EnterOptions, type EventSource, type FetchStorageClientMsg, type FetchYDocClientMsg, type GetThreadsOptions, type History, type IUserInfo, type IWebSocket, type IWebSocketCloseEvent, type IWebSocketEvent, type IWebSocketInstance, type IWebSocketMessageEvent, type IdTuple, type Immutable, type InitialDocumentStateServerMsg, type Json, type JsonArray, type JsonObject, type JsonScalar, type LegacyConnectionStatus, LiveList, type LiveListUpdate, LiveMap, type LiveMapUpdate, type LiveNode, LiveObject, type LiveObjectUpdate, type LiveStructure, type LostConnectionEvent, type Lson, type LsonObject, type NodeMap, type Op, OpCode, type Others, type OthersEvent, type ParentToChildNodeMap, type PlainLson, type PlainLsonFields, type PlainLsonList, type PlainLsonMap, type PlainLsonObject, type RejectedStorageOpServerMsg, type Resolve, type Room, type RoomEventMessage, type RoomInitializers, type RoomStateServerMsg, type SerializedChild, type SerializedCrdt, type SerializedList, type SerializedMap, type SerializedObject, type SerializedRegister, type SerializedRootObject, type ServerMsg, ServerMsgCode, type SetParentKeyOp, type Status, type StorageStatus, type StorageUpdate, type StringifyCommentBodyElements, type StringifyCommentBodyOptions, type ThreadData, type ThreadDataPlain, type ToImmutable, type ToJson, type UnsubscribeCallback, type UpdateObjectOp, type UpdatePresenceClientMsg, type UpdatePresenceServerMsg, type UpdateStorageClientMsg, type UpdateStorageServerMsg, type UpdateYDocClientMsg, type User, type UserJoinServerMsg, type UserLeftServerMsg, WebsocketCloseCodes, type YDocUpdateServerMsg, ackOp, asPos, assert, assertNever, b64decode, cloneLson, fancyConsole as console, convertToCommentData, convertToCommentUserReaction, convertToThreadData, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, getMentionedIdsFromCommentBody, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, raise, shallow, stringify, stringifyCommentBody, throwUsageError, toPlainLson, tryParseJson, withTimeout };
2773
+ export { type AckOp, type BaseAuthResult, type BaseMetadata, type BaseUserMeta, type Brand, type BroadcastEventClientMsg, type BroadcastOptions, type BroadcastedEventServerMsg, type CacheState, type CacheStore, type Client, type ClientMsg, ClientMsgCode, 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 CommentReaction, type CommentUserReaction, type CommentUserReactionPlain, CommentsApiError, type CommentsEventServerMsg, CrdtType, type CreateListOp, type CreateMapOp, type CreateObjectOp, type CreateOp, type CreateRegisterOp, type CustomAuthenticationResult, type Delegates, type DeleteCrdtOp, type DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, type EnsureJson, type EnterOptions, type EventSource, type FetchStorageClientMsg, type FetchYDocClientMsg, type GetThreadsOptions, type History, type IUserInfo, type IWebSocket, type IWebSocketCloseEvent, type IWebSocketEvent, type IWebSocketInstance, type IWebSocketMessageEvent, type IdTuple, type Immutable, type InboxNotificationData, type InboxNotificationDataPlain, type InboxNotificationThreadData, type InitialDocumentStateServerMsg, type Json, type JsonArray, type JsonObject, type JsonScalar, type LegacyConnectionStatus, LiveList, type LiveListUpdate, LiveMap, type LiveMapUpdate, type LiveNode, LiveObject, type LiveObjectUpdate, type LiveStructure, type LostConnectionEvent, type Lson, type LsonObject, type NodeMap, NotificationsApiError, type Op, OpCode, type OptionalPromise, type Others, type OthersEvent, type ParentToChildNodeMap, type PartialNullable, type PlainLson, type PlainLsonFields, type PlainLsonList, type PlainLsonMap, type PlainLsonObject, type RejectedStorageOpServerMsg, type Resolve, type ResolveMentionSuggestionsArgs, type ResolveRoomsInfoArgs, type ResolveUsersArgs, type Room, type RoomEventMessage, type RoomInfo, type RoomInitializers, type RoomNotificationSettings, type RoomStateServerMsg, type SerializedChild, type SerializedCrdt, type SerializedList, type SerializedMap, type SerializedObject, type SerializedRegister, type SerializedRootObject, type ServerMsg, ServerMsgCode, type SetParentKeyOp, type Status, type StorageStatus, type StorageUpdate, type Store, type StringifyCommentBodyElements, type StringifyCommentBodyOptions, type ThreadData, type ThreadDataPlain, type ToImmutable, type ToJson, type UnsubscribeCallback, type UpdateObjectOp, type UpdatePresenceClientMsg, type UpdatePresenceServerMsg, type UpdateStorageClientMsg, type UpdateStorageServerMsg, type UpdateYDocClientMsg, type User, type UserJoinServerMsg, type UserLeftServerMsg, WebsocketCloseCodes, type YDocUpdateServerMsg, ackOp, applyOptimisticUpdates, asPos, assert, assertNever, b64decode, cloneLson, fancyConsole as console, convertToCommentData, convertToCommentUserReaction, convertToThreadData, createClient, deprecate, deprecateIf, detectDupes, errorIf, freeze, getMentionedIdsFromCommentBody, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, kInternal, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, raise, shallow, stringify, stringifyCommentBody, throwUsageError, toPlainLson, tryParseJson, withTimeout };