@liveblocks/core 1.19.0-test1 → 2.0.0-alpha1

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,217 @@ 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
+ * 10xx: client will reauthorize (just like 41xx)
183
+ * 40xx: client will disconnect
184
+ * 41xx: client will reauthorize
185
+ * 42xx: client will retry without reauthorizing (currently not used)
186
+ *
187
+ */
188
+ declare enum WebsocketCloseCodes {
189
+ /** Normal close of connection, the connection fulfilled its purpose. */
190
+ CLOSE_NORMAL = 1000,
191
+ /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
192
+ CLOSE_ABNORMAL = 1006,
193
+ /** Unexpected error happened. In spirit akin to HTTP 500 */
194
+ UNEXPECTED_CONDITION = 1011,
195
+ /** Please back off for now, but try again in a few moments */
196
+ TRY_AGAIN_LATER = 1013,
197
+ /** Message wasn't understood, disconnect */
198
+ INVALID_MESSAGE_FORMAT = 4000,
199
+ /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
200
+ NOT_ALLOWED = 4001,
201
+ /** Unused */
202
+ MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
203
+ /** Unused */
204
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
205
+ /** Unused */
206
+ MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
207
+ /** Room is full, disconnect */
208
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
209
+ /** The room's ID was updated, disconnect */
210
+ ROOM_ID_UPDATED = 4006,
211
+ /** The server kicked the connection from the room. */
212
+ KICKED = 4100,
213
+ /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
214
+ TOKEN_EXPIRED = 4109,
215
+ /** Disconnect immediately */
216
+ CLOSE_WITHOUT_RETRY = 4999
217
+ }
218
+
219
+ /**
220
+ * Returns a human-readable status indicating the current connection status of
221
+ * a Room, as returned by `room.getStatus()`. Can be used to implement
222
+ * a connection status badge.
223
+ */
224
+ declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
225
+ /**
226
+ * Used to report about app-level reconnection issues.
227
+ *
228
+ * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
229
+ * the application will only get an event if the reconnection attempts by the
230
+ * client are taking (much) longer than usual. Definitely a situation you want
231
+ * to inform your users about, for example, by throwing a toast message on
232
+ * screen, or show a "trying to reconnect" banner.
233
+ */
234
+ declare type LostConnectionEvent = "lost" | "restored" | "failed";
235
+ /**
236
+ * Arbitrary record that will be used as the authentication "authValue". It's the
237
+ * value that is returned by calling the authentication delegate, and will get
238
+ * passed to the connection factory delegate. This value will be remembered by
239
+ * the connection manager, but its value will not be interpreted, so it can be
240
+ * any value (except null).
241
+ */
242
+ declare type BaseAuthResult = NonNullable<Json>;
243
+ declare class LiveblocksError extends Error {
244
+ code: number;
245
+ }
246
+ declare type Delegates<T extends BaseAuthResult> = {
247
+ authenticate: () => Promise<T>;
248
+ createSocket: (authValue: T) => IWebSocketInstance;
249
+ canZombie: () => boolean;
250
+ };
251
+
28
252
  declare enum OpCode {
29
253
  INIT = 0,
30
254
  SET_PARENT_KEY = 1,
@@ -96,6 +320,25 @@ declare type AckOp = {
96
320
  readonly id: "ACK";
97
321
  readonly opId: string;
98
322
  };
323
+ /**
324
+ * Create an Op that can be used as an acknowledgement for the given opId, to
325
+ * send back to the originating client in cases where the server decided to
326
+ * ignore the Op and not forward it.
327
+ *
328
+ * Why?
329
+ * It's important for the client to receive an acknowledgement for this, so
330
+ * that it can correctly update its own unacknowledged Ops administration.
331
+ * Otherwise it could get in "synchronizing" state indefinitely.
332
+ *
333
+ * CLEVER HACK
334
+ * Introducing a new Op type for this would not be backward-compatible as
335
+ * receiving such Op would crash old clients :(
336
+ * So the clever backward-compatible hack pulled here is that we codify the
337
+ * acknowledgement as a "deletion Op" for the non-existing node id "ACK". In
338
+ * old clients such Op is accepted, but will effectively be a no-op as that
339
+ * node does not exist, but as a side-effect the Op will get acknowledged.
340
+ */
341
+ declare function ackOp(opId: string): AckOp;
99
342
  declare type SetParentKeyOp = {
100
343
  readonly opId?: string;
101
344
  readonly id: string;
@@ -184,56 +427,6 @@ declare type PlainLsonList = {
184
427
  };
185
428
  declare type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | Json;
186
429
 
187
- declare type LiveObjectUpdateDelta<O extends {
188
- [key: string]: unknown;
189
- }> = {
190
- [K in keyof O]?: UpdateDelta | undefined;
191
- };
192
- /**
193
- * A LiveObject notification that is sent in-client to any subscribers whenever
194
- * one or more of the entries inside the LiveObject instance have changed.
195
- */
196
- declare type LiveObjectUpdates<TData extends LsonObject> = {
197
- type: "LiveObject";
198
- node: LiveObject<TData>;
199
- updates: LiveObjectUpdateDelta<TData>;
200
- };
201
- /**
202
- * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
203
- * Keys should be a string, and values should be serializable to JSON.
204
- * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
205
- */
206
- declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
207
- constructor(obj?: O);
208
- /**
209
- * Transform the LiveObject into a javascript object
210
- */
211
- toObject(): O;
212
- /**
213
- * Adds or updates a property with a specified key and a value.
214
- * @param key The key of the property to add
215
- * @param value The value of the property to add
216
- */
217
- set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
218
- /**
219
- * Returns a specified property from the LiveObject.
220
- * @param key The key of the property to get
221
- */
222
- get<TKey extends keyof O>(key: TKey): O[TKey];
223
- /**
224
- * Deletes a key from the LiveObject
225
- * @param key The key of the property to delete
226
- */
227
- delete(key: keyof O): void;
228
- /**
229
- * Adds or updates multiple properties at once with an object.
230
- * @param patch The object used to overrides properties
231
- */
232
- update(patch: Partial<O>): void;
233
- toImmutable(): ToImmutable<O>;
234
- clone(): LiveObject<O>;
235
- }
236
-
237
430
  /**
238
431
  * Helper type to convert any valid Lson type to the equivalent Json type.
239
432
  *
@@ -531,165 +724,73 @@ declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extend
531
724
  [K in KS]: ToJson<V>;
532
725
  } : never;
533
726
 
534
- /**
535
- * This helper type is effectively a no-op, but will force TypeScript to
536
- * "evaluate" any named helper types in its definition. This can sometimes make
537
- * API signatures clearer in IDEs.
538
- *
539
- * For example, in:
540
- *
541
- * type Payload<T> = { data: T };
542
- *
543
- * let r1: Payload<string>;
544
- * let r2: Resolve<Payload<string>>;
545
- *
546
- * The inferred type of `r1` is going to be `Payload<string>` which shows up in
547
- * editor hints, and it may be unclear what's inside if you don't know the
548
- * definition of `Payload`.
549
- *
550
- * The inferred type of `r2` is going to be `{ data: string }`, which may be
551
- * more helpful.
552
- *
553
- * This trick comes from:
554
- * https://effectivetypescript.com/2022/02/25/gentips-4-display/
555
- */
556
- declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
557
- [K in keyof T]: T[K];
558
- };
559
-
560
- declare type CustomAuthenticationResult = {
561
- token: string;
562
- error?: never;
563
- } | {
564
- token?: never;
565
- error: "forbidden";
566
- reason: string;
567
- } | {
568
- token?: never;
569
- error: string;
570
- reason: string;
727
+ declare type LiveObjectUpdateDelta<O extends {
728
+ [key: string]: unknown;
729
+ }> = {
730
+ [K in keyof O]?: UpdateDelta | undefined;
571
731
  };
572
-
573
732
  /**
574
- * Represents some constraints for user info. Basically read this as: "any JSON
575
- * object is fine, but _if_ it has a name field, it _must_ be a string."
576
- * (Ditto for avatar.)
733
+ * A LiveObject notification that is sent in-client to any subscribers whenever
734
+ * one or more of the entries inside the LiveObject instance have changed.
577
735
  */
578
- declare type IUserInfo = {
579
- [key: string]: Json | undefined;
580
- name?: string;
581
- avatar?: string;
736
+ declare type LiveObjectUpdates<TData extends LsonObject> = {
737
+ type: "LiveObject";
738
+ node: LiveObject<TData>;
739
+ updates: LiveObjectUpdateDelta<TData>;
582
740
  };
583
741
  /**
584
- * This type is used by clients to define the metadata for a user.
742
+ * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
743
+ * Keys should be a string, and values should be serializable to JSON.
744
+ * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
585
745
  */
586
- declare type BaseUserMeta = {
746
+ declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
747
+ constructor(obj?: O);
587
748
  /**
588
- * The id of the user that has been set in the authentication endpoint.
589
- * Useful to get additional information about the connected user.
749
+ * Transform the LiveObject into a javascript object
590
750
  */
591
- id?: string;
751
+ toObject(): O;
592
752
  /**
593
- * Additional user information that has been set in the authentication endpoint.
753
+ * Adds or updates a property with a specified key and a value.
754
+ * @param key The key of the property to add
755
+ * @param value The value of the property to add
594
756
  */
595
- info?: IUserInfo;
596
- };
597
-
598
- declare enum Permission {
599
- Read = "room:read",
600
- Write = "room:write",
601
- PresenceWrite = "room:presence:write",
602
- CommentsWrite = "comments:write",
603
- CommentsRead = "comments:read"
604
- }
605
- declare type LiveblocksPermissions = Record<string, Permission[]>;
606
- declare enum TokenKind {
607
- SECRET_LEGACY = "sec-legacy",
608
- ACCESS_TOKEN = "acc",
609
- ID_TOKEN = "id"
757
+ set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
758
+ /**
759
+ * Returns a specified property from the LiveObject.
760
+ * @param key The key of the property to get
761
+ */
762
+ get<TKey extends keyof O>(key: TKey): O[TKey];
763
+ /**
764
+ * Deletes a key from the LiveObject
765
+ * @param key The key of the property to delete
766
+ */
767
+ delete(key: keyof O): void;
768
+ /**
769
+ * Adds or updates multiple properties at once with an object.
770
+ * @param patch The object used to overrides properties
771
+ */
772
+ update(patch: Partial<O>): void;
773
+ toImmutable(): ToImmutable<O>;
774
+ clone(): LiveObject<O>;
610
775
  }
611
- declare type JwtMeta = {
612
- iat: number;
613
- exp: number;
614
- };
615
- /**
616
- * Legacy Secret Token.
617
- */
618
- declare type LegacySecretToken = {
619
- k: TokenKind.SECRET_LEGACY;
620
- roomId: string;
621
- scopes: string[];
622
- id?: string;
623
- info?: IUserInfo;
624
- [other: string]: Json | undefined;
625
- } & JwtMeta;
626
- /**
627
- * New authorization Access Token.
628
- */
629
- declare type AccessToken = {
630
- k: TokenKind.ACCESS_TOKEN;
631
- pid: string;
632
- uid: string;
633
- perms: LiveblocksPermissions;
634
- ui?: IUserInfo;
635
- } & JwtMeta;
636
- /**
637
- * New authorization ID Token.
638
- */
639
- declare type IDToken = {
640
- k: TokenKind.ID_TOKEN;
641
- pid: string;
642
- uid: string;
643
- gids?: string[];
644
- ui?: IUserInfo;
645
- } & JwtMeta;
646
- declare type AuthToken = AccessToken | IDToken | LegacySecretToken;
647
- declare type ParsedAuthToken = {
648
- readonly raw: string;
649
- readonly parsed: AuthToken;
650
- };
651
-
652
- declare type AuthValue = {
653
- type: "secret";
654
- token: ParsedAuthToken;
655
- } | {
656
- type: "public";
657
- publicApiKey: string;
658
- };
659
776
 
660
- declare type BaseMetadata = Record<string, string | boolean | number>;
661
-
662
- declare type CommentBodyBlockElement = CommentBodyParagraph;
663
- declare type CommentBodyInlineElement = CommentBodyText | CommentBodyMention | CommentBodyLink;
664
- declare type CommentBodyElement = CommentBodyBlockElement | CommentBodyInlineElement;
665
- declare type CommentBodyParagraph = {
666
- type: "paragraph";
667
- children: CommentBodyInlineElement[];
668
- };
669
- declare type CommentBodyMention = {
670
- type: "mention";
671
- id: string;
672
- };
673
- declare type CommentBodyLink = {
674
- type: "link";
675
- url: string;
676
- };
677
- declare type CommentBodyText = {
678
- bold?: boolean;
679
- italic?: boolean;
680
- strikethrough?: boolean;
681
- code?: boolean;
682
- text: string;
683
- };
684
- declare type CommentBody = {
685
- version: 1;
686
- content: CommentBodyBlockElement[];
777
+ declare type BaseRoomInfo = {
778
+ [key: string]: Json | undefined;
779
+ /**
780
+ * The name of the room.
781
+ */
782
+ name?: string;
783
+ /**
784
+ * The URL of the room.
785
+ */
786
+ url?: string;
687
787
  };
688
788
 
689
789
  declare type DateToString<T> = {
690
- [P in keyof T]: T[P] extends Date ? string : T[P];
790
+ [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];
691
791
  };
692
792
 
793
+ declare type BaseMetadata = Record<string, string | boolean | number | undefined>;
693
794
  declare type CommentReaction = {
694
795
  emoji: string;
695
796
  createdAt: Date;
@@ -716,8 +817,8 @@ declare type CommentData = {
716
817
  body?: never;
717
818
  deletedAt: Date;
718
819
  });
719
- declare type CommentDataPlain = Omit<DateToString<CommentData>, "reaction" | "body"> & {
720
- reactions: DateToString<CommentReaction[]>;
820
+ declare type CommentDataPlain = Omit<DateToString<CommentData>, "reactions" | "body"> & {
821
+ reactions: DateToString<CommentReaction>[];
721
822
  } & ({
722
823
  body: CommentBody;
723
824
  deletedAt?: never;
@@ -725,265 +826,138 @@ declare type CommentDataPlain = Omit<DateToString<CommentData>, "reaction" | "bo
725
826
  body?: never;
726
827
  deletedAt: string;
727
828
  });
728
-
729
- declare type CommentUserReaction = {
730
- emoji: string;
731
- createdAt: Date;
732
- userId: string;
829
+ declare type CommentBodyBlockElement = CommentBodyParagraph;
830
+ declare type CommentBodyInlineElement = CommentBodyText | CommentBodyMention | CommentBodyLink;
831
+ declare type CommentBodyElement = CommentBodyBlockElement | CommentBodyInlineElement;
832
+ declare type CommentBodyParagraph = {
833
+ type: "paragraph";
834
+ children: CommentBodyInlineElement[];
733
835
  };
734
- declare type CommentUserReactionPlain = DateToString<CommentUserReaction>;
735
-
736
- /**
737
- * Represents a thread of comments.
738
- */
739
- declare type ThreadData<TThreadMetadata extends BaseMetadata = never> = {
740
- type: "thread";
836
+ declare type CommentBodyMention = {
837
+ type: "mention";
741
838
  id: string;
742
- roomId: string;
743
- createdAt: Date;
744
- updatedAt?: Date;
745
- comments: CommentData[];
746
- metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
747
- };
748
- declare type ThreadDataPlain<TThreadMetadata extends BaseMetadata = never> = Omit<DateToString<ThreadData<TThreadMetadata>>, "comments" | "metadata"> & {
749
- comments: CommentDataPlain[];
750
- metadata: [TThreadMetadata] extends [never] ? Record<string, never> : TThreadMetadata;
751
- };
752
-
753
- declare type Options = {
754
- baseUrl: string;
755
- };
756
- declare type PartialNullable<T> = {
757
- [P in keyof T]?: T[P] | null | undefined;
758
- };
759
- declare type ThreadsFilterOptions<TThreadMetadata extends BaseMetadata> = {
760
- query?: {
761
- metadata?: Partial<TThreadMetadata>;
762
- };
763
- };
764
- declare type CommentsApi<TThreadMetadata extends BaseMetadata> = {
765
- getThreads(options?: ThreadsFilterOptions<TThreadMetadata>): Promise<ThreadData<TThreadMetadata>[]>;
766
- createThread(options: {
767
- threadId: string;
768
- commentId: string;
769
- metadata: TThreadMetadata | undefined;
770
- body: CommentBody;
771
- }): Promise<ThreadData<TThreadMetadata>>;
772
- editThreadMetadata(options: {
773
- metadata: PartialNullable<TThreadMetadata>;
774
- threadId: string;
775
- }): Promise<TThreadMetadata>;
776
- createComment(options: {
777
- threadId: string;
778
- commentId: string;
779
- body: CommentBody;
780
- }): Promise<CommentData>;
781
- editComment(options: {
782
- threadId: string;
783
- commentId: string;
784
- body: CommentBody;
785
- }): Promise<CommentData>;
786
- deleteComment(options: {
787
- threadId: string;
788
- commentId: string;
789
- }): Promise<void>;
790
- addReaction(options: {
791
- threadId: string;
792
- commentId: string;
793
- emoji: string;
794
- }): Promise<CommentUserReaction>;
795
- removeReaction(options: {
796
- threadId: string;
797
- commentId: string;
798
- emoji: string;
799
- }): Promise<void>;
800
- };
801
- declare class CommentsApiError extends Error {
802
- message: string;
803
- status: number;
804
- details?: JsonObject | undefined;
805
- constructor(message: string, status: number, details?: JsonObject | undefined);
806
- }
807
- declare function createCommentsApi<TThreadMetadata extends BaseMetadata>(roomId: string, getAuthValue: () => Promise<AuthValue>, config: Options): CommentsApi<TThreadMetadata>;
808
-
809
- declare type Callback<T> = (event: T) => void;
810
- declare type UnsubscribeCallback = () => void;
811
- declare type Observable<T> = {
812
- /**
813
- * Register a callback function to be called whenever the event source emits
814
- * an event.
815
- */
816
- subscribe(callback: Callback<T>): UnsubscribeCallback;
817
- /**
818
- * Register a one-time callback function to be called whenever the event
819
- * source emits an event. After the event fires, the callback is
820
- * auto-unsubscribed.
821
- */
822
- subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
823
- /**
824
- * Returns a promise that will resolve when an event is emitted by this
825
- * event source. Optionally, specify a predicate that has to match. The first
826
- * event matching that predicate will then resolve the promise.
827
- */
828
- waitUntil(predicate?: (event: T) => boolean): Promise<T>;
829
839
  };
830
- declare type EventSource<T> = Observable<T> & {
831
- /**
832
- * Notify all subscribers about the event.
833
- */
834
- notify(event: T): void;
835
- /**
836
- * Clear all registered event listeners. None of the registered functions
837
- * will ever get called again. Be careful when using this API, because the
838
- * subscribers may not have any idea they won't be notified anymore.
839
- */
840
- clear(): void;
841
- /**
842
- * Returns the number of active subscribers.
843
- */
844
- count(): number;
845
- /**
846
- * Pauses event delivery until unpaused. Any .notify() calls made while
847
- * paused will get buffered into memory and emitted later.
848
- */
849
- pause(): void;
850
- /**
851
- * Emits all in-memory buffered events, and unpauses. Any .notify() calls
852
- * made after this will be synchronously delivered again.
853
- */
854
- unpause(): void;
855
- /**
856
- * Observable instance, which can be used to subscribe to this event source
857
- * in a readonly fashion. Safe to publicly expose.
858
- */
859
- observable: Observable<T>;
840
+ declare type CommentBodyLink = {
841
+ type: "link";
842
+ url: string;
843
+ };
844
+ declare type CommentBodyText = {
845
+ bold?: boolean;
846
+ italic?: boolean;
847
+ strikethrough?: boolean;
848
+ code?: boolean;
849
+ text: string;
850
+ };
851
+ declare type CommentBody = {
852
+ version: 1;
853
+ content: CommentBodyBlockElement[];
854
+ };
855
+ declare type CommentUserReaction = {
856
+ emoji: string;
857
+ createdAt: Date;
858
+ userId: string;
860
859
  };
860
+ declare type CommentUserReactionPlain = DateToString<CommentUserReaction>;
861
861
  /**
862
- * makeEventSource allows you to generate a subscribe/notify pair of functions
863
- * to make subscribing easy and to get notified about events.
864
- *
865
- * The events are anonymous, so you can use it to define events, like so:
866
- *
867
- * const event1 = makeEventSource();
868
- * const event2 = makeEventSource();
869
- *
870
- * event1.subscribe(foo);
871
- * event1.subscribe(bar);
872
- * event2.subscribe(qux);
873
- *
874
- * // Unsubscription is pretty standard
875
- * const unsub = event2.subscribe(foo);
876
- * unsub();
877
- *
878
- * event1.notify(); // Now foo and bar will get called
879
- * event2.notify(); // Now qux will get called (but foo will not, since it's unsubscribed)
880
- *
862
+ * Represents a thread of comments.
881
863
  */
882
- declare function makeEventSource<T>(): EventSource<T>;
883
-
884
- interface IWebSocketEvent {
885
- type: string;
886
- }
887
- interface IWebSocketCloseEvent extends IWebSocketEvent {
888
- readonly code: WebsocketCloseCodes;
889
- readonly wasClean: boolean;
890
- readonly reason: string;
891
- }
892
- interface IWebSocketMessageEvent extends IWebSocketEvent {
893
- readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
894
- }
895
- interface IWebSocketInstance {
896
- readonly CONNECTING: number;
897
- readonly OPEN: number;
898
- readonly CLOSING: number;
899
- readonly CLOSED: number;
900
- readonly readyState: number;
901
- addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
902
- addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
903
- addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
904
- removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
905
- removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
906
- removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
907
- close(): void;
908
- send(data: string): void;
864
+ declare type ThreadData<M extends BaseMetadata = DM> = {
865
+ type: "thread";
866
+ id: string;
867
+ roomId: string;
868
+ createdAt: Date;
869
+ updatedAt?: Date;
870
+ comments: CommentData[];
871
+ metadata: M;
872
+ };
873
+ interface ThreadDataWithDeleteInfo<M extends BaseMetadata = DM> extends ThreadData<M> {
874
+ deletedAt?: Date;
909
875
  }
876
+ declare type ThreadDataPlain<M extends BaseMetadata> = Omit<DateToString<ThreadData<M>>, "comments" | "metadata"> & {
877
+ comments: CommentDataPlain[];
878
+ metadata: M;
879
+ };
880
+ declare type ThreadDeleteInfo = {
881
+ type: "deletedThread";
882
+ id: string;
883
+ roomId: string;
884
+ deletedAt: Date;
885
+ };
886
+ declare type QueryMetadataStringValue<T extends string> = T | {
887
+ startsWith: string;
888
+ };
910
889
  /**
911
- * Either the browser-based WebSocket API or Node.js' WebSocket API (from the
912
- * 'ws' package).
890
+ * This type can be used to build a metadata query string (compatible
891
+ * with `@liveblocks/query-parser`) through a type-safe API.
913
892
  *
914
- * This type defines the minimal WebSocket API that Liveblocks needs from
915
- * a WebSocket implementation, and is a minimal subset of the browser-based
916
- * WebSocket APIs and Node.js' WebSocket API so that both implementations are
917
- * assignable to this type.
893
+ * In addition to exact values (`:` in query string), it adds:
894
+ * - to strings:
895
+ * - `startsWith` (`^` in query string)
918
896
  */
919
- interface IWebSocket {
920
- new (address: string): IWebSocketInstance;
897
+ declare type QueryMetadata<M extends BaseMetadata> = {
898
+ [K in keyof M]: M[K] extends string ? QueryMetadataStringValue<M[K]> : M[K];
899
+ };
900
+
901
+ declare global {
902
+ /**
903
+ * Namespace for user-defined Liveblocks types.
904
+ */
905
+ export interface Liveblocks {
906
+ [key: string]: unknown;
907
+ }
921
908
  }
909
+ declare type ExtendableTypes = "Presence" | "Storage" | "UserMeta" | "RoomEvent" | "ThreadMetadata" | "RoomInfo";
910
+ declare type ExtendedType<K extends ExtendableTypes, B> = unknown extends Liveblocks[K] ? B : Liveblocks[K] extends B ? Liveblocks[K] : `The type you provided for '${K}' does not match its requirements. To learn how to fix this, see https://liveblocks.io/errors/${K}`;
911
+ declare type DP = ExtendedType<"Presence", JsonObject>;
912
+ declare type DS = ExtendedType<"Storage", LsonObject>;
913
+ declare type DU = ExtendedType<"UserMeta", BaseUserMeta>;
914
+ declare type DE = ExtendedType<"RoomEvent", Json>;
915
+ declare type DM = ExtendedType<"ThreadMetadata", BaseMetadata>;
916
+ declare type DRI = ExtendedType<"RoomInfo", BaseRoomInfo>;
917
+
922
918
  /**
923
- * The following ranges will be respected by the client:
924
- *
925
- * 40xx: client will disconnect
926
- * 41xx: client will reauthorize
927
- * 42xx: client will retry without reauthorizing (currently not used)
919
+ * Use this symbol to brand an object property as internal.
928
920
  *
921
+ * @example
922
+ * Object.defineProperty(
923
+ * {
924
+ * public,
925
+ * [kInternal]: {
926
+ * private
927
+ * },
928
+ * },
929
+ * kInternal,
930
+ * {
931
+ * enumerable: false,
932
+ * }
933
+ * );
929
934
  */
930
- declare enum WebsocketCloseCodes {
931
- /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
932
- CLOSE_ABNORMAL = 1006,
933
- /** Unexpected error happened. In spirit akin to HTTP 500 */
934
- UNEXPECTED_CONDITION = 1011,
935
- /** Please back off for now, but try again in a few moments */
936
- TRY_AGAIN_LATER = 1013,
937
- /** Message wasn't understood, disconnect */
938
- INVALID_MESSAGE_FORMAT = 4000,
939
- /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
940
- NOT_ALLOWED = 4001,
941
- /** Unused */
942
- MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
943
- /** Unused */
944
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
945
- /** Unused */
946
- MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
947
- /** Room is full, disconnect */
948
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
949
- /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
950
- TOKEN_EXPIRED = 4109,
951
- /** Disconnect immediately */
952
- CLOSE_WITHOUT_RETRY = 4999
953
- }
935
+ declare const kInternal: unique symbol;
954
936
 
955
937
  /**
956
- * Old connection statuses, here for backward-compatibility reasons only.
957
- */
958
- declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
959
- /**
960
- * Returns a human-readable status indicating the current connection status of
961
- * a Room, as returned by `room.getStatus()`. Can be used to implement
962
- * a connection status badge.
963
- */
964
- declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
965
- /**
966
- * Used to report about app-level reconnection issues.
938
+ * This helper type is effectively a no-op, but will force TypeScript to
939
+ * "evaluate" any named helper types in its definition. This can sometimes make
940
+ * API signatures clearer in IDEs.
967
941
  *
968
- * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
969
- * the application will only get an event if the reconnection attempts by the
970
- * client are taking (much) longer than usual. Definitely a situation you want
971
- * to inform your users about, for example, by throwing a toast message on
972
- * screen, or show a "trying to reconnect" banner.
973
- */
974
- declare type LostConnectionEvent = "lost" | "restored" | "failed";
975
- /**
976
- * Arbitrary record that will be used as the authentication "authValue". It's the
977
- * value that is returned by calling the authentication delegate, and will get
978
- * passed to the connection factory delegate. This value will be remembered by
979
- * the connection manager, but its value will not be interpreted, so it can be
980
- * any value (except null).
942
+ * For example, in:
943
+ *
944
+ * type Payload<T> = { data: T };
945
+ *
946
+ * let r1: Payload<string>;
947
+ * let r2: Resolve<Payload<string>>;
948
+ *
949
+ * The inferred type of `r1` is going to be `Payload<string>` which shows up in
950
+ * editor hints, and it may be unclear what's inside if you don't know the
951
+ * definition of `Payload`.
952
+ *
953
+ * The inferred type of `r2` is going to be `{ data: string }`, which may be
954
+ * more helpful.
955
+ *
956
+ * This trick comes from:
957
+ * https://effectivetypescript.com/2022/02/25/gentips-4-display/
981
958
  */
982
- declare type BaseAuthResult = NonNullable<Json>;
983
- declare type Delegates<T extends BaseAuthResult> = {
984
- authenticate: () => Promise<T>;
985
- createSocket: (authValue: T) => IWebSocketInstance;
986
- canZombie: () => boolean;
959
+ declare type Resolve<T> = T extends (...args: unknown[]) => unknown ? T : {
960
+ [K in keyof T]: T[K];
987
961
  };
988
962
 
989
963
  declare enum ClientMsgCode {
@@ -997,12 +971,12 @@ declare enum ClientMsgCode {
997
971
  /**
998
972
  * Messages that can be sent from the client to the server.
999
973
  */
1000
- declare type ClientMsg<TPresence extends JsonObject, TRoomEvent extends Json> = BroadcastEventClientMsg<TRoomEvent> | UpdatePresenceClientMsg<TPresence> | UpdateStorageClientMsg | FetchStorageClientMsg | FetchYDocClientMsg | UpdateYDocClientMsg;
1001
- declare type BroadcastEventClientMsg<TRoomEvent extends Json> = {
974
+ declare type ClientMsg<P extends JsonObject, E extends Json> = BroadcastEventClientMsg<E> | UpdatePresenceClientMsg<P> | UpdateStorageClientMsg | FetchStorageClientMsg | FetchYDocClientMsg | UpdateYDocClientMsg;
975
+ declare type BroadcastEventClientMsg<E extends Json> = {
1002
976
  type: ClientMsgCode.BROADCAST_EVENT;
1003
- event: TRoomEvent;
977
+ event: E;
1004
978
  };
1005
- declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
979
+ declare type UpdatePresenceClientMsg<P extends JsonObject> = {
1006
980
  readonly type: ClientMsgCode.UPDATE_PRESENCE;
1007
981
  /**
1008
982
  * Set this to any number to signify that this is a Full Presence™
@@ -1018,7 +992,7 @@ declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
1018
992
  * all presence fields, and isn't a partial "patch".
1019
993
  */
1020
994
  readonly targetActor: number;
1021
- readonly data: TPresence;
995
+ readonly data: P;
1022
996
  } | {
1023
997
  readonly type: ClientMsgCode.UPDATE_PRESENCE;
1024
998
  /**
@@ -1026,7 +1000,7 @@ declare type UpdatePresenceClientMsg<TPresence extends JsonObject> = {
1026
1000
  * Presence™ "patch".
1027
1001
  */
1028
1002
  readonly targetActor?: undefined;
1029
- readonly data: Partial<TPresence>;
1003
+ readonly data: Partial<P>;
1030
1004
  };
1031
1005
  declare type UpdateStorageClientMsg = {
1032
1006
  readonly type: ClientMsgCode.UPDATE_STORAGE;
@@ -1046,6 +1020,42 @@ declare type UpdateYDocClientMsg = {
1046
1020
  readonly guid?: string;
1047
1021
  };
1048
1022
 
1023
+ declare type InboxNotificationThreadData = {
1024
+ kind: "thread";
1025
+ id: string;
1026
+ roomId: string;
1027
+ threadId: string;
1028
+ notifiedAt: Date;
1029
+ readAt: Date | null;
1030
+ };
1031
+ declare type ActivityData = Record<string, string | boolean | number | undefined>;
1032
+ declare type InboxNotificationActivity = {
1033
+ id: string;
1034
+ createdAt: Date;
1035
+ data: ActivityData;
1036
+ };
1037
+ declare type InboxNotificationCustomData = {
1038
+ kind: `$${string}`;
1039
+ id: string;
1040
+ roomId?: string;
1041
+ subjectId: string;
1042
+ notifiedAt: Date;
1043
+ readAt: Date | null;
1044
+ activities: InboxNotificationActivity[];
1045
+ };
1046
+ declare type InboxNotificationData = InboxNotificationThreadData | InboxNotificationCustomData;
1047
+ declare type InboxNotificationThreadDataPlain = DateToString<InboxNotificationThreadData>;
1048
+ declare type InboxNotificationCustomDataPlain = Omit<DateToString<InboxNotificationCustomData>, "activities"> & {
1049
+ activities: DateToString<InboxNotificationActivity>[];
1050
+ };
1051
+ declare type InboxNotificationDataPlain = InboxNotificationThreadDataPlain | InboxNotificationCustomDataPlain;
1052
+ declare type InboxNotificationDeleteInfo = {
1053
+ type: "deletedInboxNotification";
1054
+ id: string;
1055
+ roomId: string;
1056
+ deletedAt: Date;
1057
+ };
1058
+
1049
1059
  declare type IdTuple<T> = [id: string, value: T];
1050
1060
  declare enum CrdtType {
1051
1061
  OBJECT = 0,
@@ -1107,7 +1117,7 @@ declare enum ServerMsgCode {
1107
1117
  /**
1108
1118
  * Messages that can be sent from the server to the client.
1109
1119
  */
1110
- declare type ServerMsg<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = UpdatePresenceServerMsg<TPresence> | UserJoinServerMsg<TUserMeta> | UserLeftServerMsg | BroadcastedEventServerMsg<TRoomEvent> | RoomStateServerMsg<TUserMeta> | InitialDocumentStateServerMsg | UpdateStorageServerMsg | RejectedStorageOpServerMsg | YDocUpdateServerMsg | CommentsEventServerMsg;
1120
+ declare type ServerMsg<P extends JsonObject, U extends BaseUserMeta, E extends Json> = UpdatePresenceServerMsg<P> | UserJoinServerMsg<U> | UserLeftServerMsg | BroadcastedEventServerMsg<E> | RoomStateServerMsg<U> | InitialDocumentStateServerMsg | UpdateStorageServerMsg | RejectedStorageOpServerMsg | YDocUpdateServerMsg | CommentsEventServerMsg;
1111
1121
  declare type CommentsEventServerMsg = ThreadCreatedEvent | ThreadMetadataUpdatedEvent | CommentCreatedEvent | CommentEditedEvent | CommentDeletedEvent | CommentReactionAdded | CommentReactionRemoved;
1112
1122
  declare type ThreadCreatedEvent = {
1113
1123
  type: ServerMsgCode.THREAD_CREATED;
@@ -1155,7 +1165,7 @@ declare type CommentReactionRemoved = {
1155
1165
  * those cases, the `targetActor` field indicates the newly connected client,
1156
1166
  * so all other existing clients can ignore this broadcasted message.
1157
1167
  */
1158
- declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
1168
+ declare type UpdatePresenceServerMsg<P extends JsonObject> = {
1159
1169
  readonly type: ServerMsgCode.UPDATE_PRESENCE;
1160
1170
  /**
1161
1171
  * The User whose Presence has changed.
@@ -1179,7 +1189,7 @@ declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
1179
1189
  * this will be the full Presence, otherwise it only contain the fields that
1180
1190
  * have changed since the last broadcast.
1181
1191
  */
1182
- readonly data: TPresence;
1192
+ readonly data: P;
1183
1193
  } | {
1184
1194
  readonly type: ServerMsgCode.UPDATE_PRESENCE;
1185
1195
  /**
@@ -1194,25 +1204,25 @@ declare type UpdatePresenceServerMsg<TPresence extends JsonObject> = {
1194
1204
  * A partial Presence patch to apply to the User. It will only contain the
1195
1205
  * fields that have changed since the last broadcast.
1196
1206
  */
1197
- readonly data: Partial<TPresence>;
1207
+ readonly data: Partial<P>;
1198
1208
  };
1199
1209
  /**
1200
1210
  * Sent by the WebSocket server and broadcasted to all clients to announce that
1201
1211
  * a new User has joined the Room.
1202
1212
  */
1203
- declare type UserJoinServerMsg<TUserMeta extends BaseUserMeta> = {
1213
+ declare type UserJoinServerMsg<U extends BaseUserMeta> = {
1204
1214
  readonly type: ServerMsgCode.USER_JOINED;
1205
1215
  readonly actor: number;
1206
1216
  /**
1207
1217
  * The id of the User that has been set in the authentication endpoint.
1208
1218
  * Useful to get additional information about the connected user.
1209
1219
  */
1210
- readonly id: TUserMeta["id"];
1220
+ readonly id: U["id"];
1211
1221
  /**
1212
1222
  * Additional user information that has been set in the authentication
1213
1223
  * endpoint.
1214
1224
  */
1215
- readonly info: TUserMeta["info"];
1225
+ readonly info: U["info"];
1216
1226
  /**
1217
1227
  * Informs the client what (public) permissions this (other) User has.
1218
1228
  */
@@ -1241,7 +1251,7 @@ declare type YDocUpdateServerMsg = {
1241
1251
  * Sent by the WebSocket server and broadcasted to all clients to announce that
1242
1252
  * a User broadcasted an Event to everyone in the Room.
1243
1253
  */
1244
- declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
1254
+ declare type BroadcastedEventServerMsg<E extends Json> = {
1245
1255
  readonly type: ServerMsgCode.BROADCASTED_EVENT;
1246
1256
  /**
1247
1257
  * The User who broadcast the Event. Absent when this event is broadcast from
@@ -1252,14 +1262,14 @@ declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
1252
1262
  * The arbitrary payload of the Event. This can be any JSON value. Clients
1253
1263
  * will have to manually verify/decode this event.
1254
1264
  */
1255
- readonly event: TRoomEvent;
1265
+ readonly event: E;
1256
1266
  };
1257
1267
  /**
1258
1268
  * Sent by the WebSocket server to a single client in response to the client
1259
1269
  * joining the Room, to provide the initial state of the Room. The payload
1260
1270
  * includes a list of all other Users that already are in the Room.
1261
1271
  */
1262
- declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
1272
+ declare type RoomStateServerMsg<U extends BaseUserMeta> = {
1263
1273
  readonly type: ServerMsgCode.ROOM_STATE;
1264
1274
  /**
1265
1275
  * Informs the client what their actor ID is going to be.
@@ -1277,7 +1287,7 @@ declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
1277
1287
  */
1278
1288
  readonly scopes: string[];
1279
1289
  readonly users: {
1280
- readonly [otherActor: number]: TUserMeta & {
1290
+ readonly [otherActor: number]: U & {
1281
1291
  scopes: string[];
1282
1292
  };
1283
1293
  };
@@ -1313,10 +1323,54 @@ declare type RejectedStorageOpServerMsg = {
1313
1323
  readonly reason: string;
1314
1324
  };
1315
1325
 
1326
+ declare type JsonTreeNode = {
1327
+ readonly type: "Json";
1328
+ readonly id: string;
1329
+ readonly key: string;
1330
+ readonly payload: Json;
1331
+ };
1332
+ declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
1333
+ readonly type: TName;
1334
+ readonly id: string;
1335
+ readonly key: string;
1336
+ readonly payload: LsonTreeNode[];
1337
+ };
1338
+ declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
1339
+ declare type UserTreeNode = {
1340
+ readonly type: "User";
1341
+ readonly id: string;
1342
+ readonly key: string;
1343
+ readonly payload: {
1344
+ readonly connectionId: number;
1345
+ readonly id?: string;
1346
+ readonly info?: Json;
1347
+ readonly presence: JsonObject;
1348
+ readonly isReadOnly: boolean;
1349
+ };
1350
+ };
1351
+ declare type CustomEventTreeNode = {
1352
+ readonly type: "CustomEvent";
1353
+ readonly id: string;
1354
+ readonly key: string;
1355
+ readonly connectionId: number;
1356
+ readonly payload: Json;
1357
+ };
1358
+ declare type TreeNode = LsonTreeNode | UserTreeNode | CustomEventTreeNode;
1359
+
1360
+ type DevToolsTreeNode_CustomEventTreeNode = CustomEventTreeNode;
1361
+ type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
1362
+ type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
1363
+ type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
1364
+ type DevToolsTreeNode_TreeNode = TreeNode;
1365
+ type DevToolsTreeNode_UserTreeNode = UserTreeNode;
1366
+ declare namespace DevToolsTreeNode {
1367
+ 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 };
1368
+ }
1369
+
1316
1370
  /**
1317
1371
  * Represents a user connected in a room. Treated as immutable.
1318
1372
  */
1319
- declare type User<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
1373
+ declare type User<P extends JsonObject = DP, U extends BaseUserMeta = DU> = {
1320
1374
  /**
1321
1375
  * The connection ID of the User. It is unique and increment at every new connection.
1322
1376
  */
@@ -1325,21 +1379,15 @@ declare type User<TPresence extends JsonObject, TUserMeta extends BaseUserMeta>
1325
1379
  * The ID of the User that has been set in the authentication endpoint.
1326
1380
  * Useful to get additional information about the connected user.
1327
1381
  */
1328
- readonly id: TUserMeta["id"];
1382
+ readonly id: U["id"];
1329
1383
  /**
1330
1384
  * Additional user information that has been set in the authentication endpoint.
1331
1385
  */
1332
- readonly info: TUserMeta["info"];
1386
+ readonly info: U["info"];
1333
1387
  /**
1334
1388
  * The user’s presence data.
1335
1389
  */
1336
- readonly presence: TPresence;
1337
- /**
1338
- * @deprecated Use `!user.canWrite` instead.
1339
- * False if the user can mutate the Room’s Storage and/or YDoc, true if they
1340
- * can only read but not mutate it.
1341
- */
1342
- readonly isReadOnly: boolean;
1390
+ readonly presence: P;
1343
1391
  /**
1344
1392
  * True if the user can mutate the Room’s Storage and/or YDoc, false if they
1345
1393
  * can only read but not mutate it.
@@ -1351,42 +1399,48 @@ declare type User<TPresence extends JsonObject, TUserMeta extends BaseUserMeta>
1351
1399
  readonly canComment: boolean;
1352
1400
  };
1353
1401
 
1354
- /**
1355
- * @deprecated Use `readonly User<TPresence, TUserMeta>[]` instead of `Others<TPresence, TUserMeta>`.
1356
- */
1357
- declare type Others<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = readonly User<TPresence, TUserMeta>[];
1358
- declare type InternalOthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
1402
+ declare type InternalOthersEvent<P extends JsonObject, U extends BaseUserMeta> = {
1359
1403
  type: "leave";
1360
- user: User<TPresence, TUserMeta>;
1404
+ user: User<P, U>;
1361
1405
  } | {
1362
1406
  type: "enter";
1363
- user: User<TPresence, TUserMeta>;
1407
+ user: User<P, U>;
1364
1408
  } | {
1365
1409
  type: "update";
1366
- user: User<TPresence, TUserMeta>;
1367
- updates: Partial<TPresence>;
1410
+ user: User<P, U>;
1411
+ updates: Partial<P>;
1368
1412
  } | {
1369
1413
  type: "reset";
1414
+ user?: never;
1370
1415
  };
1371
- declare type OthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = Resolve<InternalOthersEvent<TPresence, TUserMeta> & {
1372
- others: readonly User<TPresence, TUserMeta>[];
1416
+ declare type OthersEvent<P extends JsonObject = DP, U extends BaseUserMeta = DU> = Resolve<InternalOthersEvent<P, U> & {
1417
+ others: readonly User<P, U>[];
1373
1418
  }>;
1374
1419
 
1375
- declare type LegacyOthersEvent<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = {
1420
+ declare type PartialNullable<T> = {
1421
+ [P in keyof T]?: T[P] | null;
1422
+ };
1423
+
1424
+ declare type RoomThreadsNotificationSettings = "all" | "replies_and_mentions" | "none";
1425
+ declare type RoomNotificationSettings = {
1426
+ threads: RoomThreadsNotificationSettings;
1427
+ };
1428
+
1429
+ declare type LegacyOthersEvent<P extends JsonObject, U extends BaseUserMeta> = {
1376
1430
  type: "leave";
1377
- user: User<TPresence, TUserMeta>;
1431
+ user: User<P, U>;
1378
1432
  } | {
1379
1433
  type: "enter";
1380
- user: User<TPresence, TUserMeta>;
1434
+ user: User<P, U>;
1381
1435
  } | {
1382
1436
  type: "update";
1383
- user: User<TPresence, TUserMeta>;
1384
- updates: Partial<TPresence>;
1437
+ user: User<P, U>;
1438
+ updates: Partial<P>;
1385
1439
  } | {
1386
1440
  type: "reset";
1387
1441
  };
1388
- declare type LegacyOthersEventCallback<TPresence extends JsonObject, TUserMeta extends BaseUserMeta> = (others: readonly User<TPresence, TUserMeta>[], event: LegacyOthersEvent<TPresence, TUserMeta>) => void;
1389
- declare type RoomEventMessage<TPresence extends JsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = {
1442
+ declare type LegacyOthersEventCallback<P extends JsonObject, U extends BaseUserMeta> = (others: readonly User<P, U>[], event: LegacyOthersEvent<P, U>) => void;
1443
+ declare type RoomEventMessage<P extends JsonObject, U extends BaseUserMeta, E extends Json> = {
1390
1444
  /**
1391
1445
  * The connection ID of the client that sent the event.
1392
1446
  * If this message was broadcast from the server (via the REST API), then
@@ -1398,8 +1452,8 @@ declare type RoomEventMessage<TPresence extends JsonObject, TUserMeta extends Ba
1398
1452
  * If this message was broadcast from the server (via the REST API), then
1399
1453
  * this value will be null.
1400
1454
  */
1401
- user: User<TPresence, TUserMeta> | null;
1402
- event: TRoomEvent;
1455
+ user: User<P, U> | null;
1456
+ event: E;
1403
1457
  };
1404
1458
  declare type StorageStatus = "not-loaded" | "loading" | "synchronizing" | "synchronized";
1405
1459
  interface History {
@@ -1491,7 +1545,7 @@ declare type BroadcastOptions = {
1491
1545
  */
1492
1546
  shouldQueueEventIfNotReady: boolean;
1493
1547
  };
1494
- declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = {
1548
+ declare type SubscribeFn<P extends JsonObject, _TStorage extends LsonObject, U extends BaseUserMeta, E extends Json> = {
1495
1549
  /**
1496
1550
  * Subscribe to the current user presence updates.
1497
1551
  *
@@ -1504,7 +1558,7 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
1504
1558
  * // Do something
1505
1559
  * });
1506
1560
  */
1507
- (type: "my-presence", listener: Callback<TPresence>): () => void;
1561
+ (type: "my-presence", listener: Callback<P>): () => void;
1508
1562
  /**
1509
1563
  * Subscribe to the other users updates.
1510
1564
  *
@@ -1518,52 +1572,28 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
1518
1572
  * });
1519
1573
  *
1520
1574
  */
1521
- (type: "others", listener: LegacyOthersEventCallback<TPresence, TUserMeta>): () => void;
1575
+ (type: "others", listener: LegacyOthersEventCallback<P, U>): () => void;
1522
1576
  /**
1523
1577
  * Subscribe to events broadcasted by {@link Room.broadcastEvent}
1524
1578
  *
1525
1579
  * @param listener the callback that is called when a user calls {@link Room.broadcastEvent}
1526
1580
  *
1527
- * @returns Unsubscribe function.
1528
- *
1529
- * @example
1530
- * room.subscribe("event", ({ event, connectionId }) => {
1531
- * // Do something
1532
- * });
1533
- *
1534
- */
1535
- (type: "event", listener: Callback<RoomEventMessage<TPresence, TUserMeta, TRoomEvent>>): () => void;
1536
- /**
1537
- * Subscribe to errors thrown in the room.
1538
- *
1539
- * @returns Unsubscribe function.
1540
- *
1541
- */
1542
- (type: "error", listener: ErrorCallback): () => void;
1543
- /**
1544
- * @deprecated This API will be removed in a future version of Liveblocks.
1545
- * Prefer using the newer `.subscribe('status')` API.
1546
- *
1547
- * We recommend making the following changes if you use these APIs:
1548
- *
1549
- * OLD APIs NEW APIs
1550
- * .getConnectionState() --> .getStatus()
1551
- * .subscribe('connection') --> .subscribe('status')
1581
+ * @returns Unsubscribe function.
1552
1582
  *
1553
- * OLD STATUSES NEW STATUSES
1554
- * closed --> initial
1555
- * authenticating --> connecting
1556
- * connecting --> connecting
1557
- * open --> connected
1558
- * unavailable --> reconnecting
1559
- * failed --> disconnected
1583
+ * @example
1584
+ * room.subscribe("event", ({ event, connectionId }) => {
1585
+ * // Do something
1586
+ * });
1560
1587
  *
1561
- * Subscribe to legacy connection status updates.
1588
+ */
1589
+ (type: "event", listener: Callback<RoomEventMessage<P, U, E>>): () => void;
1590
+ /**
1591
+ * Subscribe to errors thrown in the room.
1562
1592
  *
1563
1593
  * @returns Unsubscribe function.
1564
1594
  *
1565
1595
  */
1566
- (type: "connection", listener: Callback<LegacyConnectionStatus>): () => void;
1596
+ (type: "error", listener: Callback<LiveblocksError>): () => void;
1567
1597
  /**
1568
1598
  * Subscribe to connection status updates. The callback will be called any
1569
1599
  * time the status changes.
@@ -1648,36 +1678,88 @@ declare type SubscribeFn<TPresence extends JsonObject, _TStorage extends LsonObj
1648
1678
  */
1649
1679
  (type: "storage-status", listener: Callback<StorageStatus>): () => void;
1650
1680
  };
1651
- declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUserMeta extends BaseUserMeta, TRoomEvent extends Json> = CommentsApi<any> & {
1681
+ declare type GetThreadsOptions<M extends BaseMetadata> = {
1682
+ query?: {
1683
+ metadata?: Partial<QueryMetadata<M>>;
1684
+ };
1685
+ since?: Date;
1686
+ };
1687
+ declare type CommentsApi<M extends BaseMetadata> = {
1688
+ getThreads(options?: GetThreadsOptions<M>): Promise<{
1689
+ threads: ThreadData<M>[];
1690
+ inboxNotifications: InboxNotificationData[];
1691
+ deletedThreads: ThreadDeleteInfo[];
1692
+ deletedInboxNotifications: InboxNotificationDeleteInfo[];
1693
+ meta: {
1694
+ requestedAt: Date;
1695
+ };
1696
+ }>;
1697
+ getThread(options: {
1698
+ threadId: string;
1699
+ }): Promise<{
1700
+ thread: ThreadData<M>;
1701
+ inboxNotification?: InboxNotificationData;
1702
+ } | undefined>;
1703
+ createThread(options: {
1704
+ threadId: string;
1705
+ commentId: string;
1706
+ metadata: M | undefined;
1707
+ body: CommentBody;
1708
+ }): Promise<ThreadData<M>>;
1709
+ editThreadMetadata(options: {
1710
+ metadata: PartialNullable<M>;
1711
+ threadId: string;
1712
+ }): Promise<M>;
1713
+ createComment(options: {
1714
+ threadId: string;
1715
+ commentId: string;
1716
+ body: CommentBody;
1717
+ }): Promise<CommentData>;
1718
+ editComment(options: {
1719
+ threadId: string;
1720
+ commentId: string;
1721
+ body: CommentBody;
1722
+ }): Promise<CommentData>;
1723
+ deleteComment(options: {
1724
+ threadId: string;
1725
+ commentId: string;
1726
+ }): Promise<void>;
1727
+ addReaction(options: {
1728
+ threadId: string;
1729
+ commentId: string;
1730
+ emoji: string;
1731
+ }): Promise<CommentUserReaction>;
1732
+ removeReaction(options: {
1733
+ threadId: string;
1734
+ commentId: string;
1735
+ emoji: string;
1736
+ }): Promise<void>;
1737
+ };
1738
+ /**
1739
+ * @private Widest-possible Room type, matching _any_ Room instance. Note that
1740
+ * this type is different from `Room`-without-type-arguments. That represents
1741
+ * a Room instance using globally augmented types only, which is narrower.
1742
+ */
1743
+ declare type OpaqueRoom = Room<JsonObject, LsonObject, BaseUserMeta, Json, BaseMetadata>;
1744
+ declare type Room<P extends JsonObject = DP, S extends LsonObject = DS, U extends BaseUserMeta = DU, E extends Json = DE, M extends BaseMetadata = DM> = {
1652
1745
  /**
1653
- * The id of the room.
1746
+ * @private
1747
+ *
1748
+ * Private methods and variables used in the core internals, but as a user
1749
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
1750
+ * will probably happen if you do.
1654
1751
  */
1655
- readonly id: string;
1752
+ readonly [kInternal]: PrivateRoomApi<M>;
1656
1753
  /**
1657
- * @deprecated This API will be removed in a future version of Liveblocks.
1658
- * Prefer using `.getStatus()` instead.
1659
- *
1660
- * We recommend making the following changes if you use these APIs:
1661
- *
1662
- * OLD APIs NEW APIs
1663
- * .getConnectionState() --> .getStatus()
1664
- * .subscribe('connection') --> .subscribe('status')
1665
- *
1666
- * OLD STATUSES NEW STATUSES
1667
- * closed --> initial
1668
- * authenticating --> connecting
1669
- * connecting --> connecting
1670
- * open --> connected
1671
- * unavailable --> reconnecting
1672
- * failed --> disconnected
1754
+ * The id of the room.
1673
1755
  */
1674
- getConnectionState(): LegacyConnectionStatus;
1756
+ readonly id: string;
1675
1757
  /**
1676
1758
  * Return the current connection status for this room. Can be used to display
1677
1759
  * a status badge for your Liveblocks connection.
1678
1760
  */
1679
1761
  getStatus(): Status;
1680
- readonly subscribe: SubscribeFn<TPresence, TStorage, TUserMeta, TRoomEvent>;
1762
+ readonly subscribe: SubscribeFn<P, S, U, E>;
1681
1763
  /**
1682
1764
  * Room's history contains functions that let you undo and redo operation made on by the current client on the presence and storage.
1683
1765
  */
@@ -1689,21 +1771,21 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1689
1771
  * @example
1690
1772
  * const user = room.getSelf();
1691
1773
  */
1692
- getSelf(): User<TPresence, TUserMeta> | null;
1774
+ getSelf(): User<P, U> | null;
1693
1775
  /**
1694
1776
  * Gets the presence of the current user.
1695
1777
  *
1696
1778
  * @example
1697
1779
  * const presence = room.getPresence();
1698
1780
  */
1699
- getPresence(): TPresence;
1781
+ getPresence(): P;
1700
1782
  /**
1701
1783
  * Gets all the other users in the room.
1702
1784
  *
1703
1785
  * @example
1704
1786
  * const others = room.getOthers();
1705
1787
  */
1706
- getOthers(): readonly User<TPresence, TUserMeta>[];
1788
+ getOthers(): readonly User<P, U>[];
1707
1789
  /**
1708
1790
  * Updates the presence of the current user. Only pass the properties you want to update. No need to send the full presence.
1709
1791
  * @param patch A partial object that contains the properties you want to update.
@@ -1716,15 +1798,14 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1716
1798
  * const presence = room.getPresence();
1717
1799
  * // presence is equivalent to { x: 0, y: 0 }
1718
1800
  */
1719
- updatePresence(patch: Partial<TPresence>, options?: {
1801
+ updatePresence(patch: Partial<P>, options?: {
1720
1802
  /**
1721
1803
  * Whether or not the presence should have an impact on the undo/redo history.
1722
1804
  */
1723
1805
  addToHistory: boolean;
1724
1806
  }): void;
1725
1807
  /**
1726
- *
1727
- * Sends Yjs document updates to liveblocks server
1808
+ * Sends Yjs document updates to Liveblocks server.
1728
1809
  *
1729
1810
  * @param {string} data the doc update to send to the server, base64 encoded uint8array
1730
1811
  */
@@ -1748,7 +1829,7 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1748
1829
  * }
1749
1830
  * });
1750
1831
  */
1751
- broadcastEvent(event: TRoomEvent, options?: BroadcastOptions): void;
1832
+ broadcastEvent(event: E, options?: BroadcastOptions): void;
1752
1833
  /**
1753
1834
  * Get the room's storage asynchronously.
1754
1835
  * The storage's root is a {@link LiveObject}.
@@ -1757,7 +1838,7 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1757
1838
  * const { root } = await room.getStorage();
1758
1839
  */
1759
1840
  getStorage(): Promise<{
1760
- root: LiveObject<TStorage>;
1841
+ root: LiveObject<S>;
1761
1842
  }>;
1762
1843
  /**
1763
1844
  * Get the room's storage synchronously.
@@ -1766,15 +1847,15 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1766
1847
  * @example
1767
1848
  * const root = room.getStorageSnapshot();
1768
1849
  */
1769
- getStorageSnapshot(): LiveObject<TStorage> | null;
1850
+ getStorageSnapshot(): LiveObject<S> | null;
1770
1851
  readonly events: {
1771
1852
  readonly status: Observable<Status>;
1772
1853
  readonly lostConnection: Observable<LostConnectionEvent>;
1773
- readonly customEvent: Observable<RoomEventMessage<TPresence, TUserMeta, TRoomEvent>>;
1774
- readonly self: Observable<User<TPresence, TUserMeta>>;
1775
- readonly myPresence: Observable<TPresence>;
1776
- readonly others: Observable<OthersEvent<TPresence, TUserMeta>>;
1777
- readonly error: Observable<Error>;
1854
+ readonly customEvent: Observable<RoomEventMessage<P, U, E>>;
1855
+ readonly self: Observable<User<P, U>>;
1856
+ readonly myPresence: Observable<P>;
1857
+ readonly others: Observable<OthersEvent<P, U>>;
1858
+ readonly error: Observable<LiveblocksError>;
1778
1859
  readonly storage: Observable<StorageUpdate[]>;
1779
1860
  readonly history: Observable<HistoryEvent>;
1780
1861
  /**
@@ -1834,21 +1915,50 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1834
1915
  */
1835
1916
  reconnect(): void;
1836
1917
  };
1918
+ /**
1919
+ * @private
1920
+ *
1921
+ * Private methods to directly control the underlying state machine for this
1922
+ * room. Used in the core internals and for unit testing, but as a user of
1923
+ * Liveblocks, NEVER USE ANY OF THESE METHODS DIRECTLY, because bad things
1924
+ * will probably happen if you do.
1925
+ */
1926
+ declare type PrivateRoomApi<M extends BaseMetadata> = {
1927
+ presenceBuffer: Json | undefined;
1928
+ undoStack: readonly (readonly Readonly<HistoryOp<JsonObject>>[])[];
1929
+ nodeCount: number;
1930
+ getSelf_forDevTools(): UserTreeNode | null;
1931
+ getOthers_forDevTools(): readonly UserTreeNode[];
1932
+ simulate: {
1933
+ explicitClose(event: IWebSocketCloseEvent): void;
1934
+ rawSend(data: string): void;
1935
+ };
1936
+ comments: CommentsApi<M>;
1937
+ notifications: {
1938
+ getRoomNotificationSettings(): Promise<RoomNotificationSettings>;
1939
+ updateRoomNotificationSettings(settings: Partial<RoomNotificationSettings>): Promise<RoomNotificationSettings>;
1940
+ markInboxNotificationAsRead(notificationId: string): Promise<void>;
1941
+ };
1942
+ };
1943
+ declare type HistoryOp<P extends JsonObject> = Op | {
1944
+ readonly type: "presence";
1945
+ readonly data: P;
1946
+ };
1837
1947
  declare type Polyfills = {
1838
1948
  atob?: (data: string) => string;
1839
1949
  fetch?: typeof fetch;
1840
1950
  WebSocket?: IWebSocket;
1841
1951
  };
1842
- declare type RoomInitializers<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<{
1952
+ declare type RoomInitializers<P extends JsonObject, S extends LsonObject> = Resolve<{
1843
1953
  /**
1844
1954
  * The initial Presence to use and announce when you enter the Room. The
1845
1955
  * Presence is available on all users in the Room (me & others).
1846
1956
  */
1847
- initialPresence: TPresence | ((roomId: string) => TPresence);
1957
+ initialPresence: P | ((roomId: string) => P);
1848
1958
  /**
1849
1959
  * The initial Storage to use when entering a new Room.
1850
1960
  */
1851
- initialStorage?: TStorage | ((roomId: string) => TStorage);
1961
+ initialStorage?: S | ((roomId: string) => S);
1852
1962
  /**
1853
1963
  * Whether or not the room automatically connects to Liveblock servers.
1854
1964
  * Default is true.
@@ -1857,11 +1967,178 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1857
1967
  * the authentication endpoint or connect via WebSocket.
1858
1968
  */
1859
1969
  autoConnect?: boolean;
1860
- /** @deprecated Renamed to `autoConnect` */
1861
- shouldInitiallyConnect?: boolean;
1862
1970
  }>;
1971
+ declare class CommentsApiError extends Error {
1972
+ message: string;
1973
+ status: number;
1974
+ details?: JsonObject | undefined;
1975
+ constructor(message: string, status: number, details?: JsonObject | undefined);
1976
+ }
1977
+
1978
+ declare type BatchStoreStateLoading = {
1979
+ isLoading: true;
1980
+ data?: never;
1981
+ error?: never;
1982
+ };
1983
+ declare type BatchStoreStateError = {
1984
+ isLoading: false;
1985
+ data?: never;
1986
+ error: Error;
1987
+ };
1988
+ declare type BatchStoreStateSuccess<T> = {
1989
+ isLoading: false;
1990
+ data: T;
1991
+ error?: never;
1992
+ };
1993
+ declare type BatchStoreState<T> = BatchStoreStateLoading | BatchStoreStateError | BatchStoreStateSuccess<T>;
1994
+ declare type BatchStore<T, A extends unknown[]> = EventSource<BatchStoreState<T> | undefined> & {
1995
+ get: (...args: A) => Promise<void>;
1996
+ getState: (...args: A) => BatchStoreState<T> | undefined;
1997
+ };
1998
+
1999
+ declare type Store<T> = {
2000
+ get: () => T;
2001
+ set: (callback: (currentState: T) => T) => void;
2002
+ subscribe: (callback: (state: T) => void) => () => void;
2003
+ };
2004
+
2005
+ declare type GetInboxNotificationsOptions = {
2006
+ limit?: number;
2007
+ since?: Date;
2008
+ };
2009
+
2010
+ declare type OptimisticUpdate<M extends BaseMetadata> = CreateThreadOptimisticUpdate<M> | EditThreadMetadataOptimisticUpdate<M> | CreateCommentOptimisticUpdate | EditCommentOptimisticUpdate | DeleteCommentOptimisticUpdate | AddReactionOptimisticUpdate | RemoveReactionOptimisticUpdate | MarkInboxNotificationAsReadOptimisticUpdate | MarkAllInboxNotificationsAsReadOptimisticUpdate | UpdateNotificationSettingsOptimisticUpdate;
2011
+ declare type CreateThreadOptimisticUpdate<M extends BaseMetadata> = {
2012
+ type: "create-thread";
2013
+ id: string;
2014
+ thread: ThreadData<M>;
2015
+ };
2016
+ declare type EditThreadMetadataOptimisticUpdate<M extends BaseMetadata> = {
2017
+ type: "edit-thread-metadata";
2018
+ id: string;
2019
+ threadId: string;
2020
+ metadata: Resolve<PartialNullable<M>>;
2021
+ updatedAt: Date;
2022
+ };
2023
+ declare type CreateCommentOptimisticUpdate = {
2024
+ type: "create-comment";
2025
+ id: string;
2026
+ comment: CommentData;
2027
+ };
2028
+ declare type EditCommentOptimisticUpdate = {
2029
+ type: "edit-comment";
2030
+ id: string;
2031
+ comment: CommentData;
2032
+ };
2033
+ declare type DeleteCommentOptimisticUpdate = {
2034
+ type: "delete-comment";
2035
+ id: string;
2036
+ threadId: string;
2037
+ deletedAt: Date;
2038
+ commentId: string;
2039
+ };
2040
+ declare type AddReactionOptimisticUpdate = {
2041
+ type: "add-reaction";
2042
+ id: string;
2043
+ threadId: string;
2044
+ commentId: string;
2045
+ reaction: CommentUserReaction;
2046
+ };
2047
+ declare type RemoveReactionOptimisticUpdate = {
2048
+ type: "remove-reaction";
2049
+ id: string;
2050
+ threadId: string;
2051
+ commentId: string;
2052
+ emoji: string;
2053
+ userId: string;
2054
+ removedAt: Date;
2055
+ };
2056
+ declare type MarkInboxNotificationAsReadOptimisticUpdate = {
2057
+ type: "mark-inbox-notification-as-read";
2058
+ id: string;
2059
+ inboxNotificationId: string;
2060
+ readAt: Date;
2061
+ };
2062
+ declare type MarkAllInboxNotificationsAsReadOptimisticUpdate = {
2063
+ type: "mark-inbox-notifications-as-read";
2064
+ id: string;
2065
+ readAt: Date;
2066
+ };
2067
+ declare type UpdateNotificationSettingsOptimisticUpdate = {
2068
+ type: "update-notification-settings";
2069
+ id: string;
2070
+ roomId: string;
2071
+ settings: Partial<RoomNotificationSettings>;
2072
+ };
2073
+ declare type QueryState = {
2074
+ isLoading: true;
2075
+ error?: never;
2076
+ } | {
2077
+ isLoading: false;
2078
+ error?: Error;
2079
+ };
2080
+ declare type CacheState<M extends BaseMetadata> = {
2081
+ /**
2082
+ * Threads by ID.
2083
+ */
2084
+ threads: Record<string, ThreadDataWithDeleteInfo<M>>;
2085
+ /**
2086
+ * Keep track of loading and error status of all the queries made by the client.
2087
+ */
2088
+ queries: Record<string, QueryState>;
2089
+ /**
2090
+ * Optimistic updates that have not been acknowledged by the server yet.
2091
+ * They are applied on top of the threads in selectors.
2092
+ */
2093
+ optimisticUpdates: OptimisticUpdate<M>[];
2094
+ /**
2095
+ * Inbox notifications by ID.
2096
+ */
2097
+ inboxNotifications: Record<string, InboxNotificationData>;
2098
+ /**
2099
+ * Notification settings per room id
2100
+ */
2101
+ notificationSettings: Record<string, RoomNotificationSettings>;
2102
+ };
2103
+ interface CacheStore<M extends BaseMetadata> extends Store<CacheState<M>> {
2104
+ deleteThread(threadId: string): void;
2105
+ updateThreadAndNotification(thread: ThreadData<M>, inboxNotification?: InboxNotificationData): void;
2106
+ updateThreadsAndNotifications(threads: ThreadData<M>[], inboxNotifications: InboxNotificationData[], deletedThreads: ThreadDeleteInfo[], deletedInboxNotifications: InboxNotificationDeleteInfo[], queryKey?: string): void;
2107
+ updateRoomInboxNotificationSettings(roomId: string, settings: RoomNotificationSettings, queryKey: string): void;
2108
+ pushOptimisticUpdate(optimisticUpdate: OptimisticUpdate<M>): void;
2109
+ setQueryState(queryKey: string, queryState: QueryState): void;
2110
+ }
2111
+ declare function applyOptimisticUpdates<M extends BaseMetadata>(state: CacheState<M>): Pick<CacheState<M>, "threads" | "inboxNotifications" | "notificationSettings">;
2112
+ declare function upsertComment<M extends BaseMetadata>(thread: ThreadDataWithDeleteInfo<M>, comment: CommentData): ThreadDataWithDeleteInfo<M>;
2113
+ declare function deleteComment<M extends BaseMetadata>(thread: ThreadDataWithDeleteInfo<M>, commentId: string, deletedAt: Date): ThreadDataWithDeleteInfo<M>;
2114
+ declare function addReaction<M extends BaseMetadata>(thread: ThreadDataWithDeleteInfo<M>, commentId: string, reaction: CommentUserReaction): ThreadDataWithDeleteInfo<M>;
2115
+ declare function removeReaction<M extends BaseMetadata>(thread: ThreadDataWithDeleteInfo<M>, commentId: string, emoji: string, userId: string, removedAt: Date): ThreadDataWithDeleteInfo<M>;
1863
2116
 
1864
- declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<RoomInitializers<TPresence, TStorage> & {
2117
+ declare type OptionalPromise<T> = T | Promise<T>;
2118
+
2119
+ declare type ResolveMentionSuggestionsArgs = {
2120
+ /**
2121
+ * The ID of the current room.
2122
+ */
2123
+ roomId: string;
2124
+ /**
2125
+ * The text to search for.
2126
+ */
2127
+ text: string;
2128
+ };
2129
+ declare type ResolveUsersArgs = {
2130
+ /**
2131
+ * The IDs of the users to resolve.
2132
+ */
2133
+ userIds: string[];
2134
+ };
2135
+ declare type ResolveRoomsInfoArgs = {
2136
+ /**
2137
+ * The IDs of the rooms to resolve.
2138
+ */
2139
+ roomIds: string[];
2140
+ };
2141
+ declare type EnterOptions<P extends JsonObject = DP, S extends LsonObject = DS> = Resolve<RoomInitializers<P, S> & {
1865
2142
  /**
1866
2143
  * Only necessary when you’re using Liveblocks with React v17 or lower.
1867
2144
  *
@@ -1872,44 +2149,60 @@ declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObj
1872
2149
  */
1873
2150
  unstable_batchedUpdates?: (cb: () => void) => void;
1874
2151
  }>;
1875
- declare type Client = {
2152
+ /**
2153
+ * @private
2154
+ *
2155
+ * Private methods and variables used in the core internals, but as a user
2156
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
2157
+ * will probably happen if you do.
2158
+ */
2159
+ declare type PrivateClientApi<U extends BaseUserMeta, M extends BaseMetadata> = {
2160
+ readonly notifications: NotificationsApi<M>;
2161
+ readonly currentUserIdStore: Store<string | null>;
2162
+ readonly resolveMentionSuggestions: ClientOptions<U>["resolveMentionSuggestions"];
2163
+ readonly cacheStore: CacheStore<BaseMetadata>;
2164
+ readonly usersStore: BatchStore<U["info"] | undefined, [string]>;
2165
+ readonly roomsInfoStore: BatchStore<DRI | undefined, [string]>;
2166
+ readonly getRoomIds: () => string[];
2167
+ };
2168
+ declare type NotificationsApi<M extends BaseMetadata> = {
2169
+ getInboxNotifications(options?: GetInboxNotificationsOptions): Promise<{
2170
+ inboxNotifications: InboxNotificationData[];
2171
+ threads: ThreadData<M>[];
2172
+ deletedThreads: ThreadDeleteInfo[];
2173
+ deletedInboxNotifications: InboxNotificationDeleteInfo[];
2174
+ meta: {
2175
+ requestedAt: Date;
2176
+ };
2177
+ }>;
2178
+ getUnreadInboxNotificationsCount(): Promise<number>;
2179
+ markAllInboxNotificationsAsRead(): Promise<void>;
2180
+ markInboxNotificationAsRead(inboxNotificationId: string): Promise<void>;
2181
+ };
2182
+ /**
2183
+ * @private Widest-possible Client type, matching _any_ Client instance. Note
2184
+ * that this type is different from `Client`-without-type-arguments. That
2185
+ * represents a Client instance using globally augmented types only, which is
2186
+ * narrower.
2187
+ */
2188
+ declare type OpaqueClient = Client<BaseUserMeta>;
2189
+ declare type Client<U extends BaseUserMeta = DU> = {
1876
2190
  /**
1877
2191
  * Gets a room. Returns null if {@link Client.enter} has not been called previously.
1878
2192
  *
1879
2193
  * @param roomId The id of the room
1880
2194
  */
1881
- getRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string): Room<TPresence, TStorage, TUserMeta, TRoomEvent> | null;
2195
+ getRoom<P extends JsonObject = DP, S extends LsonObject = DS, E extends Json = DE, M extends BaseMetadata = DM>(roomId: string): Room<P, S, U, E, M> | null;
1882
2196
  /**
1883
2197
  * Enter a room.
1884
2198
  * @param roomId The id of the room
1885
2199
  * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1886
2200
  * @returns The room and a leave function. Call the returned leave() function when you no longer need the room.
1887
2201
  */
1888
- enterRoom<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): {
1889
- room: Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
2202
+ enterRoom<P extends JsonObject = DP, S extends LsonObject = DS, E extends Json = DE, M extends BaseMetadata = DM>(roomId: string, options: EnterOptions<P, S>): {
2203
+ room: Room<P, S, U, E, M>;
1890
2204
  leave: () => void;
1891
2205
  };
1892
- /**
1893
- * @deprecated - Prefer using {@link Client.enterRoom} instead.
1894
- *
1895
- * Enters a room and returns it.
1896
- * @param roomId The id of the room
1897
- * @param options Optional. You can provide initializers for the Presence or Storage when entering the Room.
1898
- */
1899
- enter<TPresence extends JsonObject, TStorage extends LsonObject = LsonObject, TUserMeta extends BaseUserMeta = BaseUserMeta, TRoomEvent extends Json = never>(roomId: string, options: EnterOptions<TPresence, TStorage>): Room<TPresence, TStorage, TUserMeta, TRoomEvent>;
1900
- /**
1901
- * @deprecated - Prefer using {@link Client.enterRoom} and calling the returned leave function instead, which is safer.
1902
- *
1903
- * Forcefully leaves a room.
1904
- *
1905
- * Only call this if you know for sure there are no other "instances" of this
1906
- * room used elsewhere in your application. Force-leaving can trigger
1907
- * unexpected conditions in other parts of your application that may not
1908
- * expect this.
1909
- *
1910
- * @param roomId The id of the room
1911
- */
1912
- leave(roomId: string): void;
1913
2206
  /**
1914
2207
  * Purges all cached auth tokens and reconnects all rooms that are still
1915
2208
  * connected, if any.
@@ -1917,61 +2210,190 @@ declare type Client = {
1917
2210
  * Call this whenever you log out a user in your application.
1918
2211
  */
1919
2212
  logout(): void;
2213
+ /**
2214
+ * @private
2215
+ *
2216
+ * Private methods and variables used in the core internals, but as a user
2217
+ * of Liveblocks, NEVER USE ANY OF THESE DIRECTLY, because bad things
2218
+ * will probably happen if you do.
2219
+ */
2220
+ readonly [kInternal]: PrivateClientApi<U, BaseMetadata>;
1920
2221
  };
1921
- declare type AuthEndpoint = string | ((room: string) => Promise<CustomAuthenticationResult>);
2222
+ declare type AuthEndpoint = string | ((room?: string) => Promise<CustomAuthenticationResult>);
1922
2223
  /**
1923
2224
  * The authentication endpoint that is called to ensure that the current user has access to a room.
1924
2225
  * Can be an url or a callback if you need to add additional headers.
1925
2226
  */
1926
- declare type ClientOptions = {
2227
+ declare type ClientOptions<U extends BaseUserMeta = DU> = {
1927
2228
  throttle?: number;
1928
2229
  lostConnectionTimeout?: number;
1929
2230
  backgroundKeepAliveTimeout?: number;
1930
2231
  polyfills?: Polyfills;
1931
2232
  unstable_fallbackToHTTP?: boolean;
2233
+ unstable_streamData?: boolean;
2234
+ /**
2235
+ * A function that returns a list of user IDs matching a string.
2236
+ */
2237
+ resolveMentionSuggestions?: (args: ResolveMentionSuggestionsArgs) => OptionalPromise<string[]>;
2238
+ /**
2239
+ * A function that returns user info from user IDs.
2240
+ */
2241
+ resolveUsers?: (args: ResolveUsersArgs) => OptionalPromise<(U["info"] | undefined)[] | undefined>;
2242
+ /**
2243
+ * A function that returns room info from room IDs.
2244
+ */
2245
+ resolveRoomsInfo?: (args: ResolveRoomsInfoArgs) => OptionalPromise<(DRI | undefined)[] | undefined>;
2246
+ } & ({
2247
+ publicApiKey: string;
2248
+ authEndpoint?: never;
2249
+ } | {
2250
+ publicApiKey?: never;
2251
+ authEndpoint: AuthEndpoint;
2252
+ });
2253
+ /**
2254
+ * Create a client that will be responsible to communicate with liveblocks servers.
2255
+ *
2256
+ * @example
2257
+ * const client = createClient({
2258
+ * authEndpoint: "/api/auth"
2259
+ * });
2260
+ *
2261
+ * // It's also possible to use a function to call your authentication endpoint.
2262
+ * // Useful to add additional headers or use an API wrapper (like Firebase functions)
2263
+ * const client = createClient({
2264
+ * authEndpoint: async (room?) => {
2265
+ * const response = await fetch("/api/auth", {
2266
+ * method: "POST",
2267
+ * headers: {
2268
+ * Authentication: "token",
2269
+ * "Content-Type": "application/json"
2270
+ * },
2271
+ * body: JSON.stringify({ room })
2272
+ * });
2273
+ *
2274
+ * return await response.json(); // should be: { token: "..." }
2275
+ * }
2276
+ * });
2277
+ */
2278
+ declare function createClient<U extends BaseUserMeta = DU>(options: ClientOptions<U>): Client<U>;
2279
+ declare class NotificationsApiError extends Error {
2280
+ message: string;
2281
+ status: number;
2282
+ details?: JsonObject | undefined;
2283
+ constructor(message: string, status: number, details?: JsonObject | undefined);
2284
+ }
2285
+
2286
+ declare type CommentBodyParagraphElementArgs = {
2287
+ /**
2288
+ * The paragraph element.
2289
+ */
2290
+ element: CommentBodyParagraph;
2291
+ /**
2292
+ * The text content of the paragraph.
2293
+ */
2294
+ children: string;
2295
+ };
2296
+ declare type CommentBodyTextElementArgs = {
2297
+ /**
2298
+ * The text element.
2299
+ */
2300
+ element: CommentBodyText;
2301
+ };
2302
+ declare type CommentBodyLinkElementArgs = {
2303
+ /**
2304
+ * The link element.
2305
+ */
2306
+ element: CommentBodyLink;
2307
+ /**
2308
+ * The absolute URL of the link.
2309
+ */
2310
+ href: string;
2311
+ };
2312
+ declare type CommentBodyMentionElementArgs<U extends BaseUserMeta = DU> = {
2313
+ /**
2314
+ * The mention element.
2315
+ */
2316
+ element: CommentBodyMention;
2317
+ /**
2318
+ * The mention's user info, if the `resolvedUsers` option was provided.
2319
+ */
2320
+ user?: U["info"];
2321
+ };
2322
+ declare type StringifyCommentBodyElements<U extends BaseUserMeta = DU> = {
2323
+ /**
2324
+ * The element used to display paragraphs.
2325
+ */
2326
+ paragraph: (args: CommentBodyParagraphElementArgs, index: number) => string;
2327
+ /**
2328
+ * The element used to display text elements.
2329
+ */
2330
+ text: (args: CommentBodyTextElementArgs, index: number) => string;
2331
+ /**
2332
+ * The element used to display links.
2333
+ */
2334
+ link: (args: CommentBodyLinkElementArgs, index: number) => string;
2335
+ /**
2336
+ * The element used to display mentions.
2337
+ */
2338
+ mention: (args: CommentBodyMentionElementArgs<U>, index: number) => string;
2339
+ };
2340
+ declare type StringifyCommentBodyOptions<U extends BaseUserMeta = DU> = {
1932
2341
  /**
1933
- * @deprecated Use `polyfills: { fetch: ... }` instead.
1934
- * This option will be removed in a future release.
2342
+ * Which format to convert the comment to.
1935
2343
  */
1936
- fetchPolyfill?: Polyfills["fetch"];
2344
+ format?: "plain" | "html" | "markdown";
1937
2345
  /**
1938
- * @deprecated Use `polyfills: { WebSocket: ... }` instead.
1939
- * This option will be removed in a future release.
2346
+ * The elements used to customize the resulting string. Each element has
2347
+ * priority over the defaults inherited from the `format` option.
1940
2348
  */
1941
- WebSocketPolyfill?: Polyfills["WebSocket"];
1942
- } & ({
1943
- publicApiKey: string;
1944
- authEndpoint?: never;
1945
- } | {
1946
- publicApiKey?: never;
1947
- authEndpoint: AuthEndpoint;
1948
- });
2349
+ elements?: Partial<StringifyCommentBodyElements<U>>;
2350
+ /**
2351
+ * The separator used between paragraphs.
2352
+ */
2353
+ separator?: string;
2354
+ /**
2355
+ * A function that returns user info from user IDs.
2356
+ */
2357
+ resolveUsers?: (args: ResolveUsersArgs) => OptionalPromise<(U["info"] | undefined)[] | undefined>;
2358
+ };
1949
2359
  /**
1950
- * Create a client that will be responsible to communicate with liveblocks servers.
1951
- *
1952
- * @example
1953
- * const client = createClient({
1954
- * authEndpoint: "/api/auth"
1955
- * });
1956
- *
1957
- * // It's also possible to use a function to call your authentication endpoint.
1958
- * // Useful to add additional headers or use an API wrapper (like Firebase functions)
1959
- * const client = createClient({
1960
- * authEndpoint: async (room) => {
1961
- * const response = await fetch("/api/auth", {
1962
- * method: "POST",
1963
- * headers: {
1964
- * Authentication: "token",
1965
- * "Content-Type": "application/json"
1966
- * },
1967
- * body: JSON.stringify({ room })
1968
- * });
1969
- *
1970
- * return await response.json(); // should be: { token: "..." }
1971
- * }
1972
- * });
2360
+ * Get an array of each user's ID that has been mentioned in a `CommentBody`.
2361
+ */
2362
+ declare function getMentionedIdsFromCommentBody(body: CommentBody): string[];
2363
+ /**
2364
+ * Convert a `CommentBody` into either a plain string,
2365
+ * Markdown, HTML, or a custom format.
2366
+ */
2367
+ declare function stringifyCommentBody(body: CommentBody, options?: StringifyCommentBodyOptions<BaseUserMeta>): Promise<string>;
2368
+
2369
+ /**
2370
+ * Converts a plain comment data object (usually returned by the API) to a comment data object that can be used by the client.
2371
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2372
+ * @param data The plain comment data object (usually returned by the API)
2373
+ * @returns The rich comment data object that can be used by the client.
2374
+ */
2375
+ declare function convertToCommentData(data: CommentDataPlain): CommentData;
2376
+ /**
2377
+ * Converts a plain thread data object (usually returned by the API) to a thread data object that can be used by the client.
2378
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2379
+ * @param data The plain thread data object (usually returned by the API)
2380
+ * @returns The rich thread data object that can be used by the client.
2381
+ */
2382
+ declare function convertToThreadData<M extends BaseMetadata>(data: ThreadDataPlain<M>): ThreadData<M>;
2383
+ /**
2384
+ * Converts a plain comment reaction object (usually returned by the API) to a comment reaction object that can be used by the client.
2385
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2386
+ * @param data The plain comment reaction object (usually returned by the API)
2387
+ * @returns The rich comment reaction object that can be used by the client.
2388
+ */
2389
+ declare function convertToCommentUserReaction(data: CommentUserReactionPlain): CommentUserReaction;
2390
+ /**
2391
+ * Converts a plain inbox notification data object (usually returned by the API) to an inbox notification data object that can be used by the client.
2392
+ * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2393
+ * @param data The plain inbox notification data object (usually returned by the API)
2394
+ * @returns The rich inbox notification data object that can be used by the client.
1973
2395
  */
1974
- declare function createClient(options: ClientOptions): Client;
2396
+ declare function convertToInboxNotificationData(data: InboxNotificationDataPlain): InboxNotificationData;
1975
2397
 
1976
2398
  /**
1977
2399
  * Lookup table for nodes (= SerializedCrdt values) by their IDs.
@@ -1990,7 +2412,7 @@ declare function cloneLson<L extends Lson | undefined>(value: L): L;
1990
2412
 
1991
2413
  declare function lsonToJson(value: Lson): Json;
1992
2414
  declare function patchLiveObjectKey<O extends LsonObject, K extends keyof O, V extends Json>(liveObject: LiveObject<O>, key: K, prev?: V, next?: V): void;
1993
- declare function legacy_patchImmutableObject<S extends JsonObject>(state: S, updates: StorageUpdate[]): S;
2415
+ declare function legacy_patchImmutableObject<TState extends JsonObject>(state: TState, updates: StorageUpdate[]): TState;
1994
2416
 
1995
2417
  /**
1996
2418
  * Helper function that can be used to implement exhaustive switch statements
@@ -2035,93 +2457,6 @@ declare function assert(condition: boolean, errmsg: string): asserts condition;
2035
2457
  */
2036
2458
  declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
2037
2459
 
2038
- declare type PromiseOrNot$1<T> = T | Promise<T>;
2039
- declare type AsyncCacheFunction<T, A extends any[] = any[]> = (...args: A) => PromiseOrNot$1<T>;
2040
- declare type AsyncCacheOptions<T, E> = {
2041
- isStateEqual?: (a: AsyncState<T, E>, b: AsyncState<T, E>) => boolean;
2042
- };
2043
- declare type AsyncStateInitial = {
2044
- readonly isLoading: false;
2045
- readonly data?: never;
2046
- readonly error?: never;
2047
- };
2048
- declare type AsyncStateLoading<T> = {
2049
- readonly isLoading: true;
2050
- readonly data?: T;
2051
- readonly error?: never;
2052
- };
2053
- declare type AsyncStateSuccess<T> = {
2054
- readonly isLoading: false;
2055
- readonly data: T;
2056
- readonly error?: never;
2057
- };
2058
- declare type AsyncStateError<T, E> = {
2059
- readonly isLoading: false;
2060
- readonly data?: T;
2061
- readonly error: E;
2062
- };
2063
- declare type AsyncState<T, E> = AsyncStateInitial | AsyncStateLoading<T> | AsyncStateSuccess<T> | AsyncStateError<T, E>;
2064
- declare type AsyncStateResolved<T, E> = AsyncStateSuccess<T> | AsyncStateError<T, E>;
2065
- declare type AsyncCacheItem<T, E> = Observable<AsyncState<T, E>> & {
2066
- get(): Promise<AsyncStateResolved<T, E>>;
2067
- getState(): AsyncState<T, E>;
2068
- revalidate(): Promise<AsyncStateResolved<T, E>>;
2069
- };
2070
- declare type AsyncCache<T, E> = {
2071
- /**
2072
- * @private
2073
- *
2074
- * Creates a key in the cache.
2075
- *
2076
- * @param key The key to create.
2077
- * @param asyncFunction Override the cache's function for this key.
2078
- */
2079
- create(key: string, asyncFunction?: AsyncCacheFunction<T, [string]>): AsyncCacheItem<T, E>;
2080
- /**
2081
- * Returns a promise which resolves with the state of the key.
2082
- *
2083
- * @param key The key to get.
2084
- */
2085
- get(key: string): Promise<AsyncStateResolved<T, E>>;
2086
- /**
2087
- * Returns the current state of the key synchronously.
2088
- *
2089
- * @param key The key to get the state of.
2090
- */
2091
- getState(key: string): AsyncState<T, E> | undefined;
2092
- /**
2093
- * Revalidates the key.
2094
- *
2095
- * @param key The key to revalidate.
2096
- */
2097
- revalidate(key: string): Promise<AsyncStateResolved<T, E>>;
2098
- /**
2099
- * Subscribes to the key's changes.
2100
- *
2101
- * @param key The key to subscribe to.
2102
- * @param callback The function invoked on every change.
2103
- */
2104
- subscribe(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2105
- /**
2106
- * Subscribes to the key's changes once.
2107
- *
2108
- * @param key The key to subscribe to.
2109
- * @param callback The function invoked on every change.
2110
- */
2111
- subscribeOnce(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
2112
- /**
2113
- * Returns whether a key already exists in the cache.
2114
- *
2115
- * @param key The key to look for.
2116
- */
2117
- has(key: string): boolean;
2118
- /**
2119
- * Clears all keys.
2120
- */
2121
- clear(): void;
2122
- };
2123
- declare function createAsyncCache<T, E>(asyncFunction: AsyncCacheFunction<T, [string]>, options?: AsyncCacheOptions<T, E>): AsyncCache<T, E>;
2124
-
2125
2460
  /**
2126
2461
  * Displays a deprecation warning in the dev console. Only in dev mode, and
2127
2462
  * only once per message/key. In production, this is a no-op.
@@ -2167,6 +2502,39 @@ declare namespace fancyConsole {
2167
2502
  */
2168
2503
  declare const freeze: typeof Object.freeze;
2169
2504
 
2505
+ /**
2506
+ * Converts an object to a query string
2507
+ * Example:
2508
+ * ```ts
2509
+ * const query = objectToQuery({
2510
+ resolved: true,
2511
+ metadata: {
2512
+ status: "open",
2513
+ priority: 3,
2514
+ org: {
2515
+ startsWith: "liveblocks:",
2516
+ },
2517
+ },
2518
+ });
2519
+
2520
+ console.log(query);
2521
+ // resolved:true AND metadata["status"]:open AND metadata["priority"]:3 AND metadata["org"]^"liveblocks:"
2522
+
2523
+ * ```
2524
+ *
2525
+ *
2526
+ */
2527
+ declare type SimpleFilterValue = string | number | boolean;
2528
+ declare type OperatorFilterValue = {
2529
+ startsWith: string;
2530
+ };
2531
+ declare type FilterValue = SimpleFilterValue | OperatorFilterValue;
2532
+ declare function objectToQuery(obj: {
2533
+ [key: string]: FilterValue | {
2534
+ [key: string]: FilterValue | undefined;
2535
+ } | undefined;
2536
+ }): string;
2537
+
2170
2538
  declare type Poller = {
2171
2539
  start(interval: number): void;
2172
2540
  restart(interval: number): void;
@@ -2282,50 +2650,6 @@ declare function shallow(a: unknown, b: unknown): boolean;
2282
2650
  declare type OmitFirstTupleElement<T extends any[]> = T extends [any, ...infer R] ? R : never;
2283
2651
  declare function stringify(object: Parameters<typeof JSON.stringify>[0], ...args: OmitFirstTupleElement<Parameters<typeof JSON.stringify>>): string;
2284
2652
 
2285
- declare type JsonTreeNode = {
2286
- readonly type: "Json";
2287
- readonly id: string;
2288
- readonly key: string;
2289
- readonly payload: Json;
2290
- };
2291
- declare type LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = {
2292
- readonly type: TName;
2293
- readonly id: string;
2294
- readonly key: string;
2295
- readonly payload: LsonTreeNode[];
2296
- };
2297
- declare type LsonTreeNode = LiveTreeNode | JsonTreeNode;
2298
- declare type UserTreeNode = {
2299
- readonly type: "User";
2300
- readonly id: string;
2301
- readonly key: string;
2302
- readonly payload: {
2303
- readonly connectionId: number;
2304
- readonly id?: string;
2305
- readonly info?: Json;
2306
- readonly presence: JsonObject;
2307
- readonly isReadOnly: boolean;
2308
- };
2309
- };
2310
- declare type CustomEventTreeNode = {
2311
- readonly type: "CustomEvent";
2312
- readonly id: string;
2313
- readonly key: string;
2314
- readonly connectionId: number;
2315
- readonly payload: Json;
2316
- };
2317
- declare type TreeNode = LsonTreeNode | UserTreeNode | CustomEventTreeNode;
2318
-
2319
- type DevToolsTreeNode_CustomEventTreeNode = CustomEventTreeNode;
2320
- type DevToolsTreeNode_JsonTreeNode = JsonTreeNode;
2321
- type DevToolsTreeNode_LiveTreeNode<TName extends `Live${string}` = `Live${string}`> = LiveTreeNode<TName>;
2322
- type DevToolsTreeNode_LsonTreeNode = LsonTreeNode;
2323
- type DevToolsTreeNode_TreeNode = TreeNode;
2324
- type DevToolsTreeNode_UserTreeNode = UserTreeNode;
2325
- declare namespace DevToolsTreeNode {
2326
- 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 };
2327
- }
2328
-
2329
2653
  /**
2330
2654
  * Definition of all messages the Panel can send to the Client.
2331
2655
  */
@@ -2446,117 +2770,6 @@ declare namespace protocol {
2446
2770
  export type { protocol_ClientToPanelMessage as ClientToPanelMessage, protocol_FullClientToPanelMessage as FullClientToPanelMessage, protocol_FullPanelToClientMessage as FullPanelToClientMessage, protocol_PanelToClientMessage as PanelToClientMessage };
2447
2771
  }
2448
2772
 
2449
- declare type PromiseOrNot<T> = T | Promise<T>;
2450
- declare type CommentBodyResolveUsersArgs = {
2451
- /**
2452
- * The ID of the users to resolve.
2453
- */
2454
- userIds: string[];
2455
- };
2456
- declare type CommentBodyParagraphElementArgs = {
2457
- /**
2458
- * The paragraph element.
2459
- */
2460
- element: CommentBodyParagraph;
2461
- /**
2462
- * The text content of the paragraph.
2463
- */
2464
- children: string;
2465
- };
2466
- declare type CommentBodyTextElementArgs = {
2467
- /**
2468
- * The text element.
2469
- */
2470
- element: CommentBodyText;
2471
- };
2472
- declare type CommentBodyLinkElementArgs = {
2473
- /**
2474
- * The link element.
2475
- */
2476
- element: CommentBodyLink;
2477
- /**
2478
- * The absolute URL of the link.
2479
- */
2480
- href: string;
2481
- };
2482
- declare type CommentBodyMentionElementArgs<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2483
- /**
2484
- * The mention element.
2485
- */
2486
- element: CommentBodyMention;
2487
- /**
2488
- * The mention's user info, if the `resolvedUsers` option was provided.
2489
- */
2490
- user?: TUserMeta["info"];
2491
- };
2492
- declare type StringifyCommentBodyElements<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2493
- /**
2494
- * The element used to display paragraphs.
2495
- */
2496
- paragraph: (args: CommentBodyParagraphElementArgs, index: number) => string;
2497
- /**
2498
- * The element used to display text elements.
2499
- */
2500
- text: (args: CommentBodyTextElementArgs, index: number) => string;
2501
- /**
2502
- * The element used to display links.
2503
- */
2504
- link: (args: CommentBodyLinkElementArgs, index: number) => string;
2505
- /**
2506
- * The element used to display mentions.
2507
- */
2508
- mention: (args: CommentBodyMentionElementArgs<TUserMeta>, index: number) => string;
2509
- };
2510
- declare type StringifyCommentBodyOptions<TUserMeta extends BaseUserMeta = BaseUserMeta> = {
2511
- /**
2512
- * Which format to convert the comment to.
2513
- */
2514
- format?: "plain" | "html" | "markdown";
2515
- /**
2516
- * The elements used to customize the resulting string. Each element has
2517
- * priority over the defaults inherited from the `format` option.
2518
- */
2519
- elements?: Partial<StringifyCommentBodyElements<TUserMeta>>;
2520
- /**
2521
- * The separator used between paragraphs.
2522
- */
2523
- separator?: string;
2524
- /**
2525
- * A function that returns user info from user IDs.
2526
- */
2527
- resolveUsers?: (args: CommentBodyResolveUsersArgs) => PromiseOrNot<(TUserMeta["info"] | undefined)[] | undefined>;
2528
- };
2529
- /**
2530
- * Get an array of each user's ID that has been mentioned in a `CommentBody`.
2531
- */
2532
- declare function getMentionedIdsFromCommentBody(body: CommentBody): string[];
2533
- /**
2534
- * Convert a `CommentBody` into either a plain string,
2535
- * Markdown, HTML, or a custom format.
2536
- */
2537
- declare function stringifyCommentBody<TUserMeta extends BaseUserMeta = BaseUserMeta>(body: CommentBody, options?: StringifyCommentBodyOptions<TUserMeta>): Promise<string>;
2538
- /**
2539
- * Converts a plain comment data object (usually returned by the API) to a comment data object that can be used by the client.
2540
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2541
- * @param data The plain comment data object (usually returned by the API)
2542
- * @returns The rich comment data object that can be used by the client.
2543
- */
2544
- declare function convertToCommentData(data: CommentDataPlain): CommentData;
2545
- /**
2546
- * Converts a plain thread data object (usually returned by the API) to a thread data object that can be used by the client.
2547
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2548
- * @param data The plain thread data object (usually returned by the API)
2549
- * @returns The rich hread data object that can be used by the client.
2550
- */
2551
- declare function convertToThreadData<TThreadMetadata extends BaseMetadata = never>(data: ThreadDataPlain<TThreadMetadata>): ThreadData<TThreadMetadata>;
2552
- /**
2553
- * Converts a plain comment reaction object (usually returned by the API) to a comment reaction object that can be used by the client.
2554
- * This is necessary because the plain data object stores dates as ISO strings, but the client expects them as Date objects.
2555
- * @param data The plain comment reaction object (usually returned by the API)
2556
- * @returns The rich comment reaction object that can be used by the client.
2557
- */
2558
- declare function convertToCommentUserReaction(data: CommentUserReactionPlain): CommentUserReaction;
2559
-
2560
2773
  /**
2561
2774
  * Helper type to help users adopt to Lson types from interface definitions.
2562
2775
  * You should only use this to wrap interfaces you don't control. For more
@@ -2569,4 +2782,4 @@ declare type EnsureJson<T> = [
2569
2782
  [K in keyof T]: EnsureJson<T[K]>;
2570
2783
  };
2571
2784
 
2572
- 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 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 ThreadsFilterOptions, 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, 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 };
2785
+ export { type AckOp, type ActivityData, type BaseAuthResult, type BaseMetadata, type BaseRoomInfo, type BaseUserMeta, type Brand, type BroadcastEventClientMsg, type BroadcastOptions, type BroadcastedEventServerMsg, type CacheState, type CacheStore, type Client, type ClientMsg, ClientMsgCode, type ClientOptions, 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 DE, type DM, type DP, type DRI, type DS, type DU, 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 InboxNotificationCustomData, type InboxNotificationCustomDataPlain, type InboxNotificationData, type InboxNotificationDataPlain, type InboxNotificationDeleteInfo, type InboxNotificationThreadData, type InboxNotificationThreadDataPlain, type InitialDocumentStateServerMsg, type Json, type JsonArray, type JsonObject, type JsonScalar, LiveList, type LiveListUpdate, LiveMap, type LiveMapUpdate, type LiveNode, LiveObject, type LiveObjectUpdate, type LiveStructure, LiveblocksError, type LostConnectionEvent, type Lson, type LsonObject, type NodeMap, NotificationsApiError, type Op, OpCode, type OpaqueClient, type OpaqueRoom, type OptionalPromise, type OthersEvent, type ParentToChildNodeMap, type PartialNullable, type PlainLson, type PlainLsonFields, type PlainLsonList, type PlainLsonMap, type PlainLsonObject, type PrivateClientApi, type PrivateRoomApi, type QueryMetadata, type RejectedStorageOpServerMsg, type Resolve, type ResolveMentionSuggestionsArgs, type ResolveRoomsInfoArgs, type ResolveUsersArgs, type Room, type RoomEventMessage, 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 ThreadDeleteInfo, 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, addReaction, applyOptimisticUpdates, asPos, assert, assertNever, b64decode, cloneLson, fancyConsole as console, convertToCommentData, convertToCommentUserReaction, convertToInboxNotificationData, convertToThreadData, createClient, deleteComment, deprecate, deprecateIf, detectDupes, errorIf, freeze, getMentionedIdsFromCommentBody, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isLiveNode, isPlainObject, isRootCrdt, kInternal, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, objectToQuery, patchLiveObjectKey, raise, removeReaction, shallow, stringify, stringifyCommentBody, throwUsageError, toPlainLson, tryParseJson, upsertComment, withTimeout };