@liveblocks/core 1.9.7 → 1.10.0-beta1

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,459 +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
- * 40xx: client will disconnect
945
- * 41xx: client will reauthorize
946
- * 42xx: client will retry without reauthorizing (currently not used)
947
- *
948
- */
949
- declare enum WebsocketCloseCodes {
950
- /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
951
- CLOSE_ABNORMAL = 1006,
952
- /** Unexpected error happened. In spirit akin to HTTP 500 */
953
- UNEXPECTED_CONDITION = 1011,
954
- /** Please back off for now, but try again in a few moments */
955
- TRY_AGAIN_LATER = 1013,
956
- /** Message wasn't understood, disconnect */
957
- INVALID_MESSAGE_FORMAT = 4000,
958
- /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
959
- NOT_ALLOWED = 4001,
960
- /** Unused */
961
- MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
962
- /** Unused */
963
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
964
- /** Unused */
965
- MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
966
- /** Room is full, disconnect */
967
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
968
- /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
969
- TOKEN_EXPIRED = 4109,
970
- /** Disconnect immediately */
971
- CLOSE_WITHOUT_RETRY = 4999
766
+ update(patch: Partial<O>): void;
767
+ toImmutable(): ToImmutable<O>;
768
+ clone(): LiveObject<O>;
972
769
  }
973
770
 
974
771
  /**
975
- * Old connection statuses, here for backward-compatibility reasons only.
976
- */
977
- declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
978
- /**
979
- * Returns a human-readable status indicating the current connection status of
980
- * a Room, as returned by `room.getStatus()`. Can be used to implement
981
- * a connection status badge.
982
- */
983
- declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
984
- /**
985
- * Used to report about app-level reconnection issues.
772
+ * Use this symbol to brand an object property as internal.
986
773
  *
987
- * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
988
- * the application will only get an event if the reconnection attempts by the
989
- * client are taking (much) longer than usual. Definitely a situation you want
990
- * to inform your users about, for example, by throwing a toast message on
991
- * 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
+ * );
992
787
  */
993
- declare type LostConnectionEvent = "lost" | "restored" | "failed";
788
+ declare const kInternal: unique symbol;
789
+
994
790
  /**
995
- * Arbitrary record that will be used as the authentication "authValue". It's the
996
- * value that is returned by calling the authentication delegate, and will get
997
- * passed to the connection factory delegate. This value will be remembered by
998
- * the connection manager, but its value will not be interpreted, so it can be
999
- * 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/
1000
811
  */
1001
- declare type BaseAuthResult = NonNullable<Json>;
1002
- declare type Delegates<T extends BaseAuthResult> = {
1003
- authenticate: () => Promise<T>;
1004
- createSocket: (authValue: T) => IWebSocketInstance;
1005
- canZombie: () => boolean;
812
+ declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
813
+ [K in keyof T]: T[K];
1006
814
  };
1007
815
 
1008
816
  declare enum ClientMsgCode {
@@ -1332,6 +1140,137 @@ declare type RejectedStorageOpServerMsg = {
1332
1140
  readonly reason: string;
1333
1141
  };
1334
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
+
1335
1274
  /**
1336
1275
  * Represents a user connected in a room. Treated as immutable.
1337
1276
  */
@@ -1391,6 +1330,32 @@ declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUse
1391
1330
  others: readonly User<TPresence, TUserMeta>[];
1392
1331
  }>;
1393
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
+
1394
1359
  declare type LegacyOthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
1395
1360
  type: "leave";
1396
1361
  user: User<TPresence, TUserMeta>;
@@ -1665,9 +1630,95 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
1665
1630
  * }
1666
1631
  * });
1667
1632
  */
1668
- (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>;
1669
1712
  };
1670
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;
1671
1722
  /**
1672
1723
  * The id of the room.
1673
1724
  */
@@ -1805,6 +1856,14 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1805
1856
  readonly ydoc: Observable<YDocUpdateServerMsg | UpdateYDocClientMsg>;
1806
1857
  readonly comments: Observable<CommentsEventServerMsg>;
1807
1858
  };
1859
+ /**
1860
+ * @private
1861
+ */
1862
+ getRoomNotificationSettings(): Promise<RoomNotificationSettings>;
1863
+ /**
1864
+ * @private
1865
+ */
1866
+ updateRoomNotificationSettings(settings: Partial<RoomNotificationSettings>): Promise<RoomNotificationSettings>;
1808
1867
  /**
1809
1868
  * Batches modifications made during the given function.
1810
1869
  * All the modifications are sent to other clients in a single message.
@@ -1852,6 +1911,29 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1852
1911
  */
1853
1912
  reconnect(): void;
1854
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
+ };
1855
1937
  declare type Polyfills = {
1856
1938
  atob?: (data: string) => string;
1857
1939
  fetch?: typeof fetch;
@@ -1878,7 +1960,177 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1878
1960
  /** @deprecated Renamed to `autoConnect` */
1879
1961
  shouldInitiallyConnect?: boolean;
1880
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
+ };
1881
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
+ };
1882
2134
  declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<RoomInitializers<TPresence, TStorage> & {
1883
2135
  /**
1884
2136
  * Only necessary when you’re using Liveblocks with React v17 or lower.
@@ -1890,7 +2142,42 @@ declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObj
1890
2142
  */
1891
2143
  unstable_batchedUpdates?: (cb: () => void) => void;
1892
2144
  }>;
1893
- 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 & {
1894
2181
  /**
1895
2182
  * Gets a room. Returns null if {@link Client.enter} has not been called previously.
1896
2183
  *
@@ -1935,13 +2222,21 @@ declare type Client = {
1935
2222
  * Call this whenever you log out a user in your application.
1936
2223
  */
1937
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>;
1938
2233
  };
1939
- declare type AuthEndpoint = string | ((room: string) => Promise<CustomAuthenticationResult>);
2234
+ declare type AuthEndpoint = string | ((room?: string) => Promise<CustomAuthenticationResult>);
1940
2235
  /**
1941
2236
  * The authentication endpoint that is called to ensure that the current user has access to a room.
1942
2237
  * Can be an url or a callback if you need to add additional headers.
1943
2238
  */
1944
- declare type ClientOptions = {
2239
+ declare type ClientOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
1945
2240
  throttle?: number;
1946
2241
  lostConnectionTimeout?: number;
1947
2242
  backgroundKeepAliveTimeout?: number;
@@ -1949,48 +2244,177 @@ declare type ClientOptions = {
1949
2244
  unstable_fallbackToHTTP?: boolean;
1950
2245
  unstable_streamData?: boolean;
1951
2246
  /**
1952
- * @deprecated Use `polyfills: { fetch: ... }` instead.
1953
- * 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.
1954
2376
  */
1955
- fetchPolyfill?: Polyfills["fetch"];
2377
+ elements?: Partial<StringifyCommentBodyElements<TUserMeta>>;
1956
2378
  /**
1957
- * @deprecated Use `polyfills: { WebSocket: ... }` instead.
1958
- * This option will be removed in a future release.
2379
+ * The separator used between paragraphs.
1959
2380
  */
1960
- WebSocketPolyfill?: Polyfills["WebSocket"];
1961
- } & ({
1962
- publicApiKey: string;
1963
- authEndpoint?: never;
1964
- } | {
1965
- publicApiKey?: never;
1966
- authEndpoint: AuthEndpoint;
1967
- });
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
+ };
1968
2387
  /**
1969
- * Create a client that will be responsible to communicate with liveblocks servers.
1970
- *
1971
- * @example
1972
- * const client = createClient({
1973
- * authEndpoint: "/api/auth"
1974
- * });
1975
- *
1976
- * // It's also possible to use a function to call your authentication endpoint.
1977
- * // Useful to add additional headers or use an API wrapper (like Firebase functions)
1978
- * const client = createClient({
1979
- * authEndpoint: async (room) => {
1980
- * const response = await fetch("/api/auth", {
1981
- * method: "POST",
1982
- * headers: {
1983
- * Authentication: "token",
1984
- * "Content-Type": "application/json"
1985
- * },
1986
- * body: JSON.stringify({ room })
1987
- * });
1988
- *
1989
- * return await response.json(); // should be: { token: "..." }
1990
- * }
1991
- * });
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.
1992
2409
  */
1993
- 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;
1994
2418
 
1995
2419
  /**
1996
2420
  * Lookup table for nodes (= SerializedCrdt values) by their IDs.
@@ -2054,93 +2478,6 @@ declare function assert(condition: boolean, errmsg: string): asserts condition;
2054
2478
  */
2055
2479
  declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
2056
2480
 
2057
- declare type PromiseOrNot$1<T> = T | Promise<T>;
2058
- declare type AsyncCacheFunction<T, A extends any[] = any[]> = (...args: A) => PromiseOrNot$1<T>;
2059
- declare type AsyncCacheOptions<T, E> = {
2060
- isStateEqual?: (a: AsyncState<T, E>, b: AsyncState<T, E>) => boolean;
2061
- };
2062
- declare type AsyncStateInitial = {
2063
- readonly isLoading: false;
2064
- readonly data?: never;
2065
- readonly error?: never;
2066
- };
2067
- declare type AsyncStateLoading<T> = {
2068
- readonly isLoading: true;
2069
- readonly data?: T;
2070
- readonly error?: never;
2071
- };
2072
- declare type AsyncStateSuccess<T> = {
2073
- readonly isLoading: false;
2074
- readonly data: T;
2075
- readonly error?: never;
2076
- };
2077
- declare type AsyncStateError<T, E> = {
2078
- readonly isLoading: false;
2079
- readonly data?: T;
2080
- readonly error: E;
2081
- };
2082
- declare type AsyncState<T, E> = AsyncStateInitial | AsyncStateLoading<T> | AsyncStateSuccess<T> | AsyncStateError<T, E>;
2083
- declare type AsyncStateResolved<T, E> = AsyncStateSuccess<T> | AsyncStateError<T, E>;
2084
- declare type AsyncCacheItem<T, E> = Observable<AsyncState<T, E>> & {
2085
- get(): Promise<AsyncStateResolved<T, E>>;
2086
- getState(): AsyncState<T, E>;
2087
- revalidate(): Promise<AsyncStateResolved<T, E>>;
2088
- };
2089
- declare type AsyncCache<T, E> = {
2090
- /**
2091
- * @private
2092
- *
2093
- * Creates a key in the cache.
2094
- *
2095
- * @param key The key to create.
2096
- * @param asyncFunction Override the cache's function for this key.
2097
- */
2098
- create(key: string, asyncFunction?: AsyncCacheFunction<T, [string]>): AsyncCacheItem<T, E>;
2099
- /**
2100
- * Returns a promise which resolves with the state of the key.
2101
- *
2102
- * @param key The key to get.
2103
- */
2104
- get(key: string): Promise<AsyncStateResolved<T, E>>;
2105
- /**
2106
- * Returns the current state of the key synchronously.
2107
- *
2108
- * @param key The key to get the state of.
2109
- */
2110
- getState(key: string): AsyncState<T, E> | undefined;
2111
- /**
2112
- * Revalidates the key.
2113
- *
2114
- * @param key The key to revalidate.
2115
- */
2116
- revalidate(key: string): Promise<AsyncStateResolved<T, E>>;
2117
- /**
2118
- * Subscribes to the key's changes.
2119
- *
2120
- * @param key The key to subscribe to.
2121
- * @param callback The function invoked on every change.
2122
- */
2123
- subscribe(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2124
- /**
2125
- * Subscribes to the key's changes once.
2126
- *
2127
- * @param key The key to subscribe to.
2128
- * @param callback The function invoked on every change.
2129
- */
2130
- subscribeOnce(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2131
- /**
2132
- * Returns whether a key already exists in the cache.
2133
- *
2134
- * @param key The key to look for.
2135
- */
2136
- has(key: string): boolean;
2137
- /**
2138
- * Clears all keys.
2139
- */
2140
- clear(): void;
2141
- };
2142
- declare function createAsyncCache<T, E>(asyncFunction: AsyncCacheFunction<T, [string]>, options?: AsyncCacheOptions<T, E>): AsyncCache<T, E>;
2143
-
2144
2481
  /**
2145
2482
  * Displays a deprecation warning in the dev console. Only in dev mode, and
2146
2483
  * only once per message/key. In production, this is a no-op.
@@ -2301,50 +2638,6 @@ declare function shallow(a: unknown, b: unknown): boolean;
2301
2638
  declare type OmitFirstTupleElement<T extends any[]> = T extends [any, ...infer R] ? R : never;
2302
2639
  declare function stringify(object: Parameters<typeof JSON.stringify>[0], ...args: OmitFirstTupleElement<Parameters<typeof JSON.stringify>>): string;
2303
2640
 
2304
- declare type JsonTreeNode = {
2305
- readonly type: "Json";
2306
- readonly id: string;
2307
- readonly key: string;
2308
- readonly payload: Json;
2309
- };
2310
- declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
2311
- readonly type: TName;
2312
- readonly id: string;
2313
- readonly key: string;
2314
- readonly payload: LsonTreeNode[];
2315
- };
2316
- declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
2317
- declare type UserTreeNode = {
2318
- readonly type: "User";
2319
- readonly id: string;
2320
- readonly key: string;
2321
- readonly payload: {
2322
- readonly connectionId: number;
2323
- readonly id?: string;
2324
- readonly info?: Json;
2325
- readonly presence: JsonObject;
2326
- readonly isReadOnly: boolean;
2327
- };
2328
- };
2329
- declare type CustomEventTreeNode = {
2330
- readonly type: "CustomEvent";
2331
- readonly id: string;
2332
- readonly key: string;
2333
- readonly connectionId: number;
2334
- readonly payload: Json;
2335
- };
2336
- declare type TreeNode = LsonTreeNode | UserTreeNode | CustomEventTreeNode;
2337
-
2338
- type DevToolsTreeNode_CustomEventTreeNode = CustomEventTreeNode;
2339
- type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
2340
- type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
2341
- type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
2342
- type DevToolsTreeNode_TreeNode = TreeNode;
2343
- type DevToolsTreeNode_UserTreeNode = UserTreeNode;
2344
- declare namespace DevToolsTreeNode {
2345
- 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 };
2346
- }
2347
-
2348
2641
  /**
2349
2642
  * Definition of all messages the Panel can send to the Client.
2350
2643
  */
@@ -2465,117 +2758,6 @@ declare namespace protocol {
2465
2758
  export type { protocol_ClientToPanelMessage as ClientToPanelMessage, protocol_FullClientToPanelMessage as FullClientToPanelMessage, protocol_FullPanelToClientMessage as FullPanelToClientMessage, protocol_PanelToClientMessage as PanelToClientMessage };
2466
2759
  }
2467
2760
 
2468
- declare type PromiseOrNot<T> = T | Promise<T>;
2469
- declare type CommentBodyResolveUsersArgs = {
2470
- /**
2471
- * The ID of the users to resolve.
2472
- */
2473
- userIds: string[];
2474
- };
2475
- declare type CommentBodyParagraphElementArgs = {
2476
- /**
2477
- * The paragraph element.
2478
- */
2479
- element: CommentBodyParagraph;
2480
- /**
2481
- * The text content of the paragraph.
2482
- */
2483
- children: string;
2484
- };
2485
- declare type CommentBodyTextElementArgs = {
2486
- /**
2487
- * The text element.
2488
- */
2489
- element: CommentBodyText;
2490
- };
2491
- declare type CommentBodyLinkElementArgs = {
2492
- /**
2493
- * The link element.
2494
- */
2495
- element: CommentBodyLink;
2496
- /**
2497
- * The absolute URL of the link.
2498
- */
2499
- href: string;
2500
- };
2501
- declare type CommentBodyMentionElementArgs<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2502
- /**
2503
- * The mention element.
2504
- */
2505
- element: CommentBodyMention;
2506
- /**
2507
- * The mention's user info, if the `resolvedUsers` option was provided.
2508
- */
2509
- user?: TUserMeta["info"];
2510
- };
2511
- declare type StringifyCommentBodyElements<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2512
- /**
2513
- * The element used to display paragraphs.
2514
- */
2515
- paragraph: (args: CommentBodyParagraphElementArgs, index: number) => string;
2516
- /**
2517
- * The element used to display text elements.
2518
- */
2519
- text: (args: CommentBodyTextElementArgs, index: number) => string;
2520
- /**
2521
- * The element used to display links.
2522
- */
2523
- link: (args: CommentBodyLinkElementArgs, index: number) => string;
2524
- /**
2525
- * The element used to display mentions.
2526
- */
2527
- mention: (args: CommentBodyMentionElementArgs<TUserMeta>, index: number) => string;
2528
- };
2529
- declare type StringifyCommentBodyOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2530
- /**
2531
- * Which format to convert the comment to.
2532
- */
2533
- format?: "plain" | "html" | "markdown";
2534
- /**
2535
- * The elements used to customize the resulting string. Each element has
2536
- * priority over the defaults inherited from the `format` option.
2537
- */
2538
- elements?: Partial<StringifyCommentBodyElements<TUserMeta>>;
2539
- /**
2540
- * The separator used between paragraphs.
2541
- */
2542
- separator?: string;
2543
- /**
2544
- * A function that returns user info from user IDs.
2545
- */
2546
- resolveUsers?: (args: CommentBodyResolveUsersArgs) => PromiseOrNot<(TUserMeta["info"] | undefined)[] | undefined>;
2547
- };
2548
- /**
2549
- * Get an array of each user's ID that has been mentioned in a `CommentBody`.
2550
- */
2551
- declare function getMentionedIdsFromCommentBody(body: CommentBody): string[];
2552
- /**
2553
- * Convert a `CommentBody` into either a plain string,
2554
- * Markdown, HTML, or a custom format.
2555
- */
2556
- declare function stringifyCommentBody<TUserMeta extends BaseUserMeta = BaseUserMeta>(body: CommentBody, options?: StringifyCommentBodyOptions<TUserMeta>): Promise<string>;
2557
- /**
2558
- * Converts a plain comment data object (usually returned by the API) to a comment data object that can be used by the client.
2559
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2560
- * @param data The plain comment data object (usually returned by the API)
2561
- * @returns The rich comment data object that can be used by the client.
2562
- */
2563
- declare function convertToCommentData(data: CommentDataPlain): CommentData;
2564
- /**
2565
- * Converts a plain thread data object (usually returned by the API) to a thread data object that can be used by the client.
2566
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2567
- * @param data The plain thread data object (usually returned by the API)
2568
- * @returns The rich hread data object that can be used by the client.
2569
- */
2570
- declare function convertToThreadData<TThreadMetadata extends BaseMetadata = never>(data: ThreadDataPlain<TThreadMetadata>): ThreadData<TThreadMetadata>;
2571
- /**
2572
- * Converts a plain comment reaction object (usually returned by the API) to a comment reaction object that can be used by the client.
2573
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2574
- * @param data The plain comment reaction object (usually returned by the API)
2575
- * @returns The rich comment reaction object that can be used by the client.
2576
- */
2577
- declare function convertToCommentUserReaction(data: CommentUserReactionPlain): CommentUserReaction;
2578
-
2579
2761
  /**
2580
2762
  * Helper type to help users adopt to Lson types from interface definitions.
2581
2763
  * You should only use this to wrap interfaces you don't control. For more
@@ -2588,4 +2770,4 @@ declare type EnsureJson<T> = [
2588
2770
  [K in keyof T]: EnsureJson<T[K]>;
2589
2771
  };
2590
2772
 
2591
- 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 };