@liveblocks/core 1.1.7 → 1.2.0-comments

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -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,239 @@ 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
+ declare enum Permission {
42
+ Read = "room:read",
43
+ Write = "room:write",
44
+ PresenceWrite = "room:presence:write",
45
+ CommentsWrite = "comments:write",
46
+ CommentsRead = "comments:read"
47
+ }
48
+ declare type LiveblocksPermissions = Record<string, Permission[]>;
49
+ declare enum TokenKind {
50
+ SECRET_LEGACY = "sec-legacy",
51
+ ACCESS_TOKEN = "acc",
52
+ ID_TOKEN = "id"
53
+ }
54
+ declare type JwtMeta = {
55
+ iat: number;
56
+ exp: number;
57
+ };
58
+ /**
59
+ * Legacy Secret Token.
60
+ */
61
+ declare type LegacySecretToken = {
62
+ k: TokenKind.SECRET_LEGACY;
63
+ roomId: string;
64
+ scopes: string[];
65
+ id?: string;
66
+ info?: Json;
67
+ [other: string]: Json | undefined;
68
+ } & JwtMeta;
69
+ /**
70
+ * New authorization Access Token.
71
+ */
72
+ declare type AccessToken = {
73
+ k: TokenKind.ACCESS_TOKEN;
74
+ pid: string;
75
+ uid: string;
76
+ perms: LiveblocksPermissions;
77
+ ui?: Json;
78
+ } & JwtMeta;
79
+ /**
80
+ * New authorization ID Token.
81
+ */
82
+ declare type IDToken = {
83
+ k: TokenKind.ID_TOKEN;
84
+ pid: string;
85
+ uid: string;
86
+ gids?: string[];
87
+ ui?: Json;
88
+ } & JwtMeta;
89
+ declare type AuthToken = AccessToken | IDToken | LegacySecretToken;
90
+ declare type ParsedAuthToken = {
91
+ readonly raw: string;
92
+ readonly parsed: AuthToken;
93
+ };
94
+
95
+ declare type Callback<T> = (event: T) => void;
96
+ declare type UnsubscribeCallback = () => void;
97
+ declare type Observable<T> = {
98
+ /**
99
+ * Register a callback function to be called whenever the event source emits
100
+ * an event.
101
+ */
102
+ subscribe(callback: Callback<T>): UnsubscribeCallback;
103
+ /**
104
+ * Register a one-time callback function to be called whenever the event
105
+ * source emits an event. After the event fires, the callback is
106
+ * auto-unsubscribed.
107
+ */
108
+ subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
109
+ /**
110
+ * Returns a promise that will resolve when an event is emitted by this
111
+ * event source. Optionally, specify a predicate that has to match. The first
112
+ * event matching that predicate will then resolve the promise.
113
+ */
114
+ waitUntil(predicate?: (event: T) => boolean): Promise<T>;
115
+ };
116
+ declare type EventSource<T> = Observable<T> & {
117
+ /**
118
+ * Notify all subscribers about the event.
119
+ */
120
+ notify(event: T): void;
121
+ /**
122
+ * Clear all registered event listeners. None of the registered functions
123
+ * will ever get called again. Be careful when using this API, because the
124
+ * subscribers may not have any idea they won't be notified anymore.
125
+ */
126
+ clear(): void;
127
+ /**
128
+ * Returns the number of active subscribers.
129
+ */
130
+ count(): number;
131
+ /**
132
+ * Pauses event delivery until unpaused. Any .notify() calls made while
133
+ * paused will get buffered into memory and emitted later.
134
+ */
135
+ pause(): void;
136
+ /**
137
+ * Emits all in-memory buffered events, and unpauses. Any .notify() calls
138
+ * made after this will be synchronously delivered again.
139
+ */
140
+ unpause(): void;
141
+ /**
142
+ * Observable instance, which can be used to subscribe to this event source
143
+ * in a readonly fashion. Safe to publicly expose.
144
+ */
145
+ observable: Observable<T>;
146
+ };
147
+ /**
148
+ * makeEventSource allows you to generate a subscribe/notify pair of functions
149
+ * to make subscribing easy and to get notified about events.
150
+ *
151
+ * The events are anonymous, so you can use it to define events, like so:
152
+ *
153
+ * const event1 = makeEventSource();
154
+ * const event2 = makeEventSource();
155
+ *
156
+ * event1.subscribe(foo);
157
+ * event1.subscribe(bar);
158
+ * event2.subscribe(qux);
159
+ *
160
+ * // Unsubscription is pretty standard
161
+ * const unsub = event2.subscribe(foo);
162
+ * unsub();
163
+ *
164
+ * event1.notify(); // Now foo and bar will get called
165
+ * event2.notify(); // Now qux will get called (but foo will not, since it's unsubscribed)
166
+ *
167
+ */
168
+ declare function makeEventSource<T>(): EventSource<T>;
169
+
170
+ interface IWebSocketEvent {
171
+ type: string;
172
+ }
173
+ interface IWebSocketCloseEvent extends IWebSocketEvent {
174
+ readonly code: number;
175
+ readonly wasClean: boolean;
176
+ readonly reason: string;
177
+ }
178
+ interface IWebSocketMessageEvent extends IWebSocketEvent {
179
+ readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
180
+ }
181
+ interface IWebSocketInstance {
182
+ readonly CONNECTING: number;
183
+ readonly OPEN: number;
184
+ readonly CLOSING: number;
185
+ readonly CLOSED: number;
186
+ readonly readyState: number;
187
+ addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
188
+ addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
189
+ addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
190
+ removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
191
+ removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
192
+ removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
193
+ close(): void;
194
+ send(data: string): void;
195
+ }
196
+ /**
197
+ * Either the browser-based WebSocket API or Node.js' WebSocket API (from the
198
+ * 'ws' package).
199
+ *
200
+ * This type defines the minimal WebSocket API that Liveblocks needs from
201
+ * a WebSocket implementation, and is a minimal subset of the browser-based
202
+ * WebSocket APIs and Node.js' WebSocket API so that both implementations are
203
+ * assignable to this type.
204
+ */
205
+ interface IWebSocket {
206
+ new (address: string): IWebSocketInstance;
207
+ }
208
+ /**
209
+ * The following ranges will be respected by the client:
210
+ *
211
+ * 40xx: client will disconnect
212
+ * 41xx: client will reauthorize
213
+ * 42xx: client will retry without reauthorizing (currently not used)
214
+ *
215
+ */
216
+ declare enum WebsocketCloseCodes {
217
+ /** Unexpected error happened with the network/infra level. In spirit akin to HTTP 503 */
218
+ CLOSE_ABNORMAL = 1006,
219
+ /** Unexpected error happened. In spirit akin to HTTP 500 */
220
+ UNEXPECTED_CONDITION = 1011,
221
+ /** Please back off for now, but try again in a few moments */
222
+ TRY_AGAIN_LATER = 1013,
223
+ /** Message wasn't understood, disconnect */
224
+ INVALID_MESSAGE_FORMAT = 4000,
225
+ /** Server refused to allow connection. Re-authorizing won't help. Disconnect. In spirit akin to HTTP 403 */
226
+ NOT_ALLOWED = 4001,
227
+ /** Unused */
228
+ MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
229
+ /** Unused */
230
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
231
+ /** Unused */
232
+ MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
233
+ /** Room is full, disconnect */
234
+ MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
235
+ /** The auth token is expired, reauthorize to get a fresh one. In spirit akin to HTTP 401 */
236
+ TOKEN_EXPIRED = 4109,
237
+ /** Disconnect immediately */
238
+ CLOSE_WITHOUT_RETRY = 4999
239
+ }
240
+
241
+ /**
242
+ * Old connection statuses, here for backward-compatibility reasons only.
243
+ */
244
+ declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
245
+ /**
246
+ * Returns a human-readable status indicating the current connection status of
247
+ * a Room, as returned by `room.getStatus()`. Can be used to implement
248
+ * a connection status badge.
249
+ */
250
+ declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
251
+ /**
252
+ * Used to report about app-level reconnection issues.
253
+ *
254
+ * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
255
+ * the application will only get an event if the reconnection attempts by the
256
+ * client are taking (much) longer than usual. Definitely a situation you want
257
+ * to inform your users about, for example, by throwing a toast message on
258
+ * screen, or show a "trying to reconnect" banner.
259
+ */
260
+ declare type LostConnectionEvent = "lost" | "restored" | "failed";
261
+ /**
262
+ * Arbitrary record that will be used as the authentication "authValue". It's the
263
+ * value that is returned by calling the authentication delegate, and will get
264
+ * passed to the connection factory delegate. This value will be remembered by
265
+ * the connection manager, but its value will not be interpreted, so it can be
266
+ * any value (except null).
267
+ */
268
+ declare type BaseAuthResult = NonNullable<Json>;
269
+ declare type Delegates<T extends BaseAuthResult> = {
270
+ authenticate: () => Promise<T>;
271
+ createSocket: (authValue: T) => IWebSocketInstance;
272
+ };
273
+
28
274
  declare enum OpCode {
29
275
  INIT = 0,
30
276
  SET_PARENT_KEY = 1,
@@ -193,55 +439,6 @@ declare type PlainLsonList = {
193
439
  };
194
440
  declare type PlainLson = PlainLsonObject | PlainLsonMap | PlainLsonList | Json;
195
441
 
196
- declare type LiveObjectUpdateDelta<O extends {
197
- [key: string]: unknown;
198
- }> = {
199
- [K in keyof O]?: UpdateDelta | undefined;
200
- };
201
- /**
202
- * A LiveObject notification that is sent in-client to any subscribers whenever
203
- * one or more of the entries inside the LiveObject instance have changed.
204
- */
205
- declare type LiveObjectUpdates<TData extends LsonObject> = {
206
- type: "LiveObject";
207
- node: LiveObject<TData>;
208
- updates: LiveObjectUpdateDelta<TData>;
209
- };
210
- /**
211
- * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
212
- * Keys should be a string, and values should be serializable to JSON.
213
- * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
214
- */
215
- declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
216
- constructor(obj?: O);
217
- /**
218
- * Transform the LiveObject into a javascript object
219
- */
220
- toObject(): O;
221
- /**
222
- * Adds or updates a property with a specified key and a value.
223
- * @param key The key of the property to add
224
- * @param value The value of the property to add
225
- */
226
- set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
227
- /**
228
- * Returns a specified property from the LiveObject.
229
- * @param key The key of the property to get
230
- */
231
- get<TKey extends keyof O>(key: TKey): O[TKey];
232
- /**
233
- * Deletes a key from the LiveObject
234
- * @param key The key of the property to delete
235
- */
236
- delete(key: keyof O): void;
237
- /**
238
- * Adds or updates multiple properties at once with an object.
239
- * @param patch The object used to overrides properties
240
- */
241
- update(patch: Partial<O>): void;
242
- toImmutable(): ToImmutable<O>;
243
- }
244
-
245
442
  /**
246
443
  * Helper type to convert any valid Lson type to the equivalent Json type.
247
444
  *
@@ -531,6 +728,55 @@ declare type ToJson<T extends Lson | LsonObject> = T extends Json ? T : T extend
531
728
  [K in KS]: ToJson<V>;
532
729
  } : never;
533
730
 
731
+ declare type LiveObjectUpdateDelta<O extends {
732
+ [key: string]: unknown;
733
+ }> = {
734
+ [K in keyof O]?: UpdateDelta | undefined;
735
+ };
736
+ /**
737
+ * A LiveObject notification that is sent in-client to any subscribers whenever
738
+ * one or more of the entries inside the LiveObject instance have changed.
739
+ */
740
+ declare type LiveObjectUpdates<TData extends LsonObject> = {
741
+ type: "LiveObject";
742
+ node: LiveObject<TData>;
743
+ updates: LiveObjectUpdateDelta<TData>;
744
+ };
745
+ /**
746
+ * The LiveObject class is similar to a JavaScript object that is synchronized on all clients.
747
+ * Keys should be a string, and values should be serializable to JSON.
748
+ * If multiple clients update the same property simultaneously, the last modification received by the Liveblocks servers is the winner.
749
+ */
750
+ declare class LiveObject<O extends LsonObject> extends AbstractCrdt {
751
+ constructor(obj?: O);
752
+ /**
753
+ * Transform the LiveObject into a javascript object
754
+ */
755
+ toObject(): O;
756
+ /**
757
+ * Adds or updates a property with a specified key and a value.
758
+ * @param key The key of the property to add
759
+ * @param value The value of the property to add
760
+ */
761
+ set<TKey extends keyof O>(key: TKey, value: O[TKey]): void;
762
+ /**
763
+ * Returns a specified property from the LiveObject.
764
+ * @param key The key of the property to get
765
+ */
766
+ get<TKey extends keyof O>(key: TKey): O[TKey];
767
+ /**
768
+ * Deletes a key from the LiveObject
769
+ * @param key The key of the property to delete
770
+ */
771
+ delete(key: keyof O): void;
772
+ /**
773
+ * Adds or updates multiple properties at once with an object.
774
+ * @param patch The object used to overrides properties
775
+ */
776
+ update(patch: Partial<O>): void;
777
+ toImmutable(): ToImmutable<O>;
778
+ }
779
+
534
780
  /**
535
781
  * This helper type is effectively a no-op, but will force TypeScript to
536
782
  * "evaluate" any named helper types in its definition. This can sometimes make
@@ -572,110 +818,6 @@ declare type BaseUserMeta = {
572
818
  info?: Json;
573
819
  };
574
820
 
575
- declare type Callback<T> = (event: T) => void;
576
- declare type UnsubscribeCallback = () => void;
577
- declare type Observable<T> = {
578
- /**
579
- * Register a callback function to be called whenever the event source emits
580
- * an event.
581
- */
582
- subscribe(callback: Callback<T>): UnsubscribeCallback;
583
- /**
584
- * Register a one-time callback function to be called whenever the event
585
- * source emits an event. After the event fires, the callback is
586
- * auto-unsubscribed.
587
- */
588
- subscribeOnce(callback: Callback<T>): UnsubscribeCallback;
589
- /**
590
- * Returns a promise that will resolve when an event is emitted by this
591
- * event source. Optionally, specify a predicate that has to match. The first
592
- * event matching that predicate will then resolve the promise.
593
- */
594
- waitUntil(predicate?: (event: T) => boolean): Promise<T>;
595
- };
596
-
597
- interface IWebSocketEvent {
598
- type: string;
599
- }
600
- interface IWebSocketCloseEvent extends IWebSocketEvent {
601
- readonly code: number;
602
- readonly wasClean: boolean;
603
- readonly reason: string;
604
- }
605
- interface IWebSocketMessageEvent extends IWebSocketEvent {
606
- readonly data: string | Buffer | ArrayBuffer | readonly Buffer[];
607
- }
608
- interface IWebSocketInstance {
609
- readonly CONNECTING: number;
610
- readonly OPEN: number;
611
- readonly CLOSING: number;
612
- readonly CLOSED: number;
613
- readonly readyState: number;
614
- addEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
615
- addEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
616
- addEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
617
- removeEventListener(type: "close", listener: (this: IWebSocketInstance, ev: IWebSocketCloseEvent) => unknown): void;
618
- removeEventListener(type: "message", listener: (this: IWebSocketInstance, ev: IWebSocketMessageEvent) => unknown): void;
619
- removeEventListener(type: "open" | "error", listener: (this: IWebSocketInstance, ev: IWebSocketEvent) => unknown): void;
620
- close(): void;
621
- send(data: string): void;
622
- }
623
- /**
624
- * Either the browser-based WebSocket API or Node.js' WebSocket API (from the
625
- * 'ws' package).
626
- *
627
- * This type defines the minimal WebSocket API that Liveblocks needs from
628
- * a WebSocket implementation, and is a minimal subset of the browser-based
629
- * WebSocket APIs and Node.js' WebSocket API so that both implementations are
630
- * assignable to this type.
631
- */
632
- interface IWebSocket {
633
- new (address: string): IWebSocketInstance;
634
- }
635
- declare enum WebsocketCloseCodes {
636
- CLOSE_ABNORMAL = 1006,
637
- INVALID_MESSAGE_FORMAT = 4000,
638
- NOT_ALLOWED = 4001,
639
- MAX_NUMBER_OF_MESSAGES_PER_SECONDS = 4002,
640
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS = 4003,
641
- MAX_NUMBER_OF_MESSAGES_PER_DAY_PER_APP = 4004,
642
- MAX_NUMBER_OF_CONCURRENT_CONNECTIONS_PER_ROOM = 4005,
643
- CLOSE_WITHOUT_RETRY = 4999
644
- }
645
-
646
- /**
647
- * Old connection statuses, here for backward-compatibility reasons only.
648
- */
649
- declare type LegacyConnectionStatus = "closed" | "authenticating" | "connecting" | "open" | "unavailable" | "failed";
650
- /**
651
- * Returns a human-readable status indicating the current connection status of
652
- * a Room, as returned by `room.getStatus()`. Can be used to implement
653
- * a connection status badge.
654
- */
655
- declare type Status = "initial" | "connecting" | "connected" | "reconnecting" | "disconnected";
656
- /**
657
- * Used to report about app-level reconnection issues.
658
- *
659
- * Normal (quick) reconnects won't be reported as a "lost connection". Instead,
660
- * the application will only get an event if the reconnection attempts by the
661
- * client are taking (much) longer than usual. Definitely a situation you want
662
- * to inform your users about, for example, by throwing a toast message on
663
- * screen, or show a "trying to reconnect" banner.
664
- */
665
- declare type LostConnectionEvent = "lost" | "restored" | "failed";
666
- /**
667
- * Arbitrary record that will be used as the authentication "token". It's the
668
- * value that is returned by calling the authentication delegate, and will get
669
- * passed to the connection factory delegate. This value will be remembered by
670
- * the connection manager, but its value will not be interpreted, so it can be
671
- * any value (except null).
672
- */
673
- declare type BaseAuthResult = NonNullable<Json>;
674
- declare type Delegates<T extends BaseAuthResult> = {
675
- authenticate: () => Promise<T>;
676
- createSocket: (token: T) => IWebSocketInstance;
677
- };
678
-
679
821
  declare type IdTuple<T> = [id: string, value: T];
680
822
  declare enum CrdtType {
681
823
  OBJECT = 0,
@@ -801,7 +943,7 @@ declare type UserJoinServerMsg<TUserMeta extends BaseUserMeta> = {
801
943
  */
802
944
  readonly info: TUserMeta["info"];
803
945
  /**
804
- * Permissions that the user has in the Room.
946
+ * Informs the client what (public) permissions this (other) User has.
805
947
  */
806
948
  readonly scopes: string[];
807
949
  };
@@ -845,8 +987,18 @@ declare type BroadcastedEventServerMsg<TRoomEvent extends Json> = {
845
987
  */
846
988
  declare type RoomStateServerMsg<TUserMeta extends BaseUserMeta> = {
847
989
  readonly type: ServerMsgCode.ROOM_STATE;
990
+ /**
991
+ * Informs the client what their actor ID is going to be.
992
+ * @since v1.2 (WS API v7)
993
+ */
994
+ readonly actor: number;
995
+ /**
996
+ * Informs the client what permissions the current User (self) has.
997
+ * @since v1.2 (WS API v7)
998
+ */
999
+ readonly scopes: string[];
848
1000
  readonly users: {
849
- readonly [actor: number]: TUserMeta & {
1001
+ readonly [otherActor: number]: TUserMeta & {
850
1002
  scopes: string[];
851
1003
  };
852
1004
  };
@@ -916,9 +1068,16 @@ declare type User<TPresence extends JsonObject, TUserMeta extends BaseUserMeta>
916
1068
  */
917
1069
  readonly presence: TPresence;
918
1070
  /**
919
- * False if the user can modify the room storage, true otherwise.
1071
+ * @deprecated Use `!user.canWrite` instead.
1072
+ * False if the user can mutate the Room’s Storage and/or YDoc, true if they
1073
+ * can only read but not mutate it.
920
1074
  */
921
1075
  readonly isReadOnly: boolean;
1076
+ /**
1077
+ * True if the user can mutate the Room’s Storage and/or YDoc, false if they
1078
+ * can only read but not mutate it.
1079
+ */
1080
+ readonly canWrite: boolean;
922
1081
  };
923
1082
 
924
1083
  /**
@@ -1191,11 +1350,6 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1191
1350
  * The id of the room.
1192
1351
  */
1193
1352
  readonly id: string;
1194
- /**
1195
- * A client is considered "self aware" if it knows its own
1196
- * metadata and connection ID (from the auth server).
1197
- */
1198
- isSelfAware(): boolean;
1199
1353
  /**
1200
1354
  * @deprecated This API will be removed in a future version of Liveblocks.
1201
1355
  * Prefer using `.getStatus()` instead.
@@ -1311,6 +1465,7 @@ declare type Room<TPresence extends JsonObject, TStorage extends LsonObject, TUs
1311
1465
  */
1312
1466
  getStorageSnapshot(): LiveObject<TStorage> | null;
1313
1467
  readonly events: {
1468
+ /** @deprecated Prefer `status` instead. */
1314
1469
  readonly connection: Observable<LegacyConnectionStatus>;
1315
1470
  readonly status: Observable<Status>;
1316
1471
  readonly lostConnection: Observable<LostConnectionEvent>;
@@ -1389,6 +1544,51 @@ declare type RoomInitializers<TPresence extends JsonObject, TStorage extends Lso
1389
1544
  shouldInitiallyConnect?: boolean;
1390
1545
  }>;
1391
1546
 
1547
+ declare type AuthValue = {
1548
+ type: "secret";
1549
+ token: ParsedAuthToken;
1550
+ } | {
1551
+ type: "public";
1552
+ publicApiKey: string;
1553
+ };
1554
+ declare type RequestedScope = "room:read" | "comments:read";
1555
+ declare type AuthManager = {
1556
+ getAuthValue(requestedScope: RequestedScope, roomId: string): Promise<AuthValue>;
1557
+ };
1558
+
1559
+ declare type BaseThreadRealtimeEvent = {
1560
+ roomId: string;
1561
+ threadId: string;
1562
+ };
1563
+ declare type BaseCommentRealtimeEvent = BaseThreadRealtimeEvent & {
1564
+ commentId: string;
1565
+ };
1566
+ declare type ThreadCreatedRealtimeEvent = BaseThreadRealtimeEvent & {
1567
+ type: "threadCreated";
1568
+ };
1569
+ declare type ThreadUpdatedRealtimeEvent = BaseThreadRealtimeEvent & {
1570
+ type: "threadUpdated";
1571
+ };
1572
+ declare type ThreadDeletedRealtimeEvent = BaseThreadRealtimeEvent & {
1573
+ type: "threadDeleted";
1574
+ };
1575
+ declare type CommentCreatedRealtimeEvent = BaseCommentRealtimeEvent & {
1576
+ type: "commentCreated";
1577
+ };
1578
+ declare type CommentUpdatedRealtimeEvent = BaseCommentRealtimeEvent & {
1579
+ type: "commentEdited";
1580
+ };
1581
+ declare type CommentDeletedRealtimeEvent = BaseCommentRealtimeEvent & {
1582
+ type: "commentDeleted";
1583
+ };
1584
+ declare type RealtimeEvent = ThreadCreatedRealtimeEvent | ThreadUpdatedRealtimeEvent | ThreadDeletedRealtimeEvent | CommentCreatedRealtimeEvent | CommentUpdatedRealtimeEvent | CommentDeletedRealtimeEvent;
1585
+
1586
+ declare type RealtimeClient = {
1587
+ subscribeToEvents: (roomId: string, callback: Callback<RealtimeEvent>) => UnsubscribeCallback;
1588
+ error: Observable<Error>;
1589
+ connection: Observable<Status>;
1590
+ };
1591
+
1392
1592
  declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObject> = Resolve<RoomInitializers<TPresence, TStorage> & {
1393
1593
  /**
1394
1594
  * Only necessary when you’re using Liveblocks with React v17 or lower.
@@ -1401,6 +1601,10 @@ declare type EnterOptions<TPresence extends JsonObject, TStorage extends LsonObj
1401
1601
  unstable_batchedUpdates?: (cb: () => void) => void;
1402
1602
  }>;
1403
1603
  declare type Client = {
1604
+ __internal: {
1605
+ getAuthValue: AuthManager["getAuthValue"];
1606
+ realtimeClient: RealtimeClient;
1607
+ };
1404
1608
  /**
1405
1609
  * Gets a room. Returns null if {@link Client.enter} has not been called previously.
1406
1610
  *
@@ -1419,9 +1623,7 @@ declare type Client = {
1419
1623
  */
1420
1624
  leave(roomId: string): void;
1421
1625
  };
1422
- declare type AuthEndpoint = string | ((room: string) => Promise<{
1423
- token: string;
1424
- }>);
1626
+ declare type AuthEndpoint = string | ((room: string) => Promise<CustomAuthenticationResult>);
1425
1627
  /**
1426
1628
  * The authentication endpoint that is called to ensure that the current user has access to a room.
1427
1629
  * Can be an url or a callback if you need to add additional headers.
@@ -1522,6 +1724,93 @@ declare function assert(condition: boolean, errmsg: string): asserts condition;
1522
1724
  */
1523
1725
  declare function nn<T>(value: T, errmsg?: string): NonNullable<T>;
1524
1726
 
1727
+ declare type AsyncFunction<T, A extends any[] = any[]> = (...args: A) => Promise<T>;
1728
+ declare type AsyncCacheOptions<T, E> = {
1729
+ isStateEqual?: (a: AsyncState<T, E>, b: AsyncState<T, E>) => boolean;
1730
+ };
1731
+ declare type AsyncStateInitial = {
1732
+ readonly isLoading: false;
1733
+ readonly data?: never;
1734
+ readonly error?: never;
1735
+ };
1736
+ declare type AsyncStateLoading<T> = {
1737
+ readonly isLoading: true;
1738
+ readonly data?: T;
1739
+ readonly error?: never;
1740
+ };
1741
+ declare type AsyncStateSuccess<T> = {
1742
+ readonly isLoading: false;
1743
+ readonly data: T;
1744
+ readonly error?: never;
1745
+ };
1746
+ declare type AsyncStateError<T, E> = {
1747
+ readonly isLoading: false;
1748
+ readonly data?: T;
1749
+ readonly error: E;
1750
+ };
1751
+ declare type AsyncState<T, E> = AsyncStateInitial | AsyncStateLoading<T> | AsyncStateSuccess<T> | AsyncStateError<T, E>;
1752
+ declare type AsyncStateResolved<T, E> = AsyncStateSuccess<T> | AsyncStateError<T, E>;
1753
+ declare type AsyncCacheItem<T, E> = Observable<AsyncState<T, E>> & {
1754
+ setAsyncFunction(asyncFunction: AsyncFunction<T, [string]>): void;
1755
+ get(): Promise<AsyncStateResolved<T, E>>;
1756
+ getState(): AsyncState<T, E>;
1757
+ revalidate(): Promise<AsyncStateResolved<T, E>>;
1758
+ };
1759
+ declare type AsyncCache<T, E> = {
1760
+ /**
1761
+ * @private
1762
+ *
1763
+ * Creates a key in the cache.
1764
+ *
1765
+ * @param key The key to create.
1766
+ * @param asyncFunction Override the cache's function for this key.
1767
+ */
1768
+ create(key: string, asyncFunction?: AsyncFunction<T, [string]>): AsyncCacheItem<T, E>;
1769
+ /**
1770
+ * Returns a promise which resolves with the state of the key.
1771
+ *
1772
+ * @param key The key to get.
1773
+ */
1774
+ get(key: string): Promise<AsyncStateResolved<T, E>>;
1775
+ /**
1776
+ * Returns the current state of the key synchronously.
1777
+ *
1778
+ * @param key The key to get the state of.
1779
+ */
1780
+ getState(key: string): AsyncState<T, E> | undefined;
1781
+ /**
1782
+ * Revalidates the key.
1783
+ *
1784
+ * @param key The key to revalidate.
1785
+ */
1786
+ revalidate(key: string): Promise<AsyncStateResolved<T, E>>;
1787
+ /**
1788
+ * Subscribes to the key's changes.
1789
+ *
1790
+ * @param key The key to subscribe to.
1791
+ * @param callback The function invoked on every change.
1792
+ */
1793
+ subscribe(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
1794
+ /**
1795
+ * Subscribes to the key's changes once.
1796
+ *
1797
+ * @param key The key to subscribe to.
1798
+ * @param callback The function invoked on every change.
1799
+ */
1800
+ subscribeOnce(key: string, callback: Callback<AsyncState<T, E>>): UnsubscribeCallback;
1801
+ /**
1802
+ * Returns whether a key already exists in the cache.
1803
+ *
1804
+ * @param key The key to look for.
1805
+ */
1806
+ has(key: string): boolean;
1807
+ /**
1808
+ * Clears all keys.
1809
+ */
1810
+ clear(): void;
1811
+ };
1812
+ declare function createAsyncCache<T, E>(asyncFunction: AsyncFunction<T, [string]>, options?: AsyncCacheOptions<T, E>): AsyncCache<T, E>;
1813
+
1525
1814
  /**
1526
1815
  * Displays a deprecation warning in the dev console. Only in dev mode, and
1527
1816
  * only once per message/key. In production, this is a no-op.
@@ -1548,12 +1837,39 @@ declare function throwUsageError(message: string): void;
1548
1837
  */
1549
1838
  declare function errorIf(condition: unknown, message: string): void;
1550
1839
 
1840
+ declare const warn: (message: string, ...args: readonly unknown[]) => void;
1841
+ declare const error: (message: string, ...args: readonly unknown[]) => void;
1842
+ declare const warnWithTitle: (title: string, message: string, ...args: readonly unknown[]) => void;
1843
+ declare const errorWithTitle: (title: string, message: string, ...args: readonly unknown[]) => void;
1844
+
1845
+ declare const fancyConsole_warn: typeof warn;
1846
+ declare const fancyConsole_error: typeof error;
1847
+ declare const fancyConsole_warnWithTitle: typeof warnWithTitle;
1848
+ declare const fancyConsole_errorWithTitle: typeof errorWithTitle;
1849
+ declare namespace fancyConsole {
1850
+ export {
1851
+ fancyConsole_warn as warn,
1852
+ fancyConsole_error as error,
1853
+ fancyConsole_warnWithTitle as warnWithTitle,
1854
+ fancyConsole_errorWithTitle as errorWithTitle,
1855
+ };
1856
+ }
1857
+
1551
1858
  /**
1552
1859
  * Freezes the given argument, but only in development builds. In production
1553
1860
  * builds, this is a no-op for performance reasons.
1554
1861
  */
1555
1862
  declare const freeze: typeof Object.freeze;
1556
1863
 
1864
+ declare type Poller = {
1865
+ start(interval: number): void;
1866
+ restart(interval: number): void;
1867
+ pause(): void;
1868
+ resume(): void;
1869
+ stop(): void;
1870
+ };
1871
+ declare function makePoller(callback: () => void): Poller;
1872
+
1557
1873
  declare const brand: unique symbol;
1558
1874
  declare type Brand<T, TBrand extends string> = T & {
1559
1875
  [brand]: TBrand;
@@ -1653,19 +1969,6 @@ declare function asPos(str: string): Pos;
1653
1969
  */
1654
1970
  declare function shallow(a: unknown, b: unknown): boolean;
1655
1971
 
1656
- declare type CustomAuthenticationResult = {
1657
- token: string;
1658
- error?: never;
1659
- } | {
1660
- token?: never;
1661
- error: "forbidden";
1662
- reason: string;
1663
- } | {
1664
- token?: never;
1665
- error: string;
1666
- reason: string;
1667
- };
1668
-
1669
1972
  declare enum ClientMsgCode {
1670
1973
  UPDATE_PRESENCE = 100,
1671
1974
  BROADCAST_EVENT = 103,
@@ -1887,6 +2190,103 @@ declare namespace protocol {
1887
2190
  };
1888
2191
  }
1889
2192
 
2193
+ declare type BaseMetadata = Record<string, string | boolean | number>;
2194
+
2195
+ declare type CommentBodyBlockElement = CommentBodyParagraph;
2196
+ declare type CommentBodyInlineElement = CommentBodyText | CommentBodyMention;
2197
+ declare type CommentBodyElement = CommentBodyBlockElement | CommentBodyInlineElement;
2198
+ declare type CommentBodyParagraph = {
2199
+ type: "paragraph";
2200
+ children: CommentBodyInlineElement[];
2201
+ };
2202
+ declare type CommentBodyMention = {
2203
+ type: "mention";
2204
+ userId: string;
2205
+ };
2206
+ declare type CommentBodyText = {
2207
+ bold?: boolean;
2208
+ italic?: boolean;
2209
+ strikethrough?: boolean;
2210
+ code?: boolean;
2211
+ text: string;
2212
+ };
2213
+ declare type CommentBody = {
2214
+ version: 1;
2215
+ content: CommentBodyBlockElement[];
2216
+ };
2217
+
2218
+ declare type CommentData = {
2219
+ type: "comment";
2220
+ id: string;
2221
+ threadId: string;
2222
+ roomId: string;
2223
+ userId: string;
2224
+ createdAt: string;
2225
+ editedAt?: string;
2226
+ } & ({
2227
+ body: CommentBody;
2228
+ deletedAt?: never;
2229
+ } | {
2230
+ body?: never;
2231
+ deletedAt: string;
2232
+ });
2233
+
2234
+ declare type ThreadData<ThreadMetadata extends BaseMetadata = never> = {
2235
+ type: "thread";
2236
+ id: string;
2237
+ roomId: string;
2238
+ createdAt: string;
2239
+ updatedAt?: string;
2240
+ comments: CommentData[];
2241
+ metadata: [ThreadMetadata] extends [never] ? Record<string, never> : ThreadMetadata;
2242
+ };
2243
+
2244
+ declare type Options = {
2245
+ serverEndpoint: string;
2246
+ };
2247
+ declare type CommentsApi<ThreadMetadata extends BaseMetadata> = {
2248
+ getThreads(options: {
2249
+ roomId: string;
2250
+ }): Promise<ThreadData<ThreadMetadata>[]>;
2251
+ createThread(options: {
2252
+ roomId: string;
2253
+ threadId: string;
2254
+ commentId: string;
2255
+ metadata: ThreadMetadata | undefined;
2256
+ body: CommentBody;
2257
+ }): Promise<ThreadData<ThreadMetadata>>;
2258
+ editThreadMetadata(options: {
2259
+ roomId: string;
2260
+ metadata: Partial<ThreadMetadata>;
2261
+ threadId: string;
2262
+ }): Promise<ThreadData<ThreadMetadata>>;
2263
+ createComment(options: {
2264
+ roomId: string;
2265
+ threadId: string;
2266
+ commentId: string;
2267
+ body: CommentBody;
2268
+ }): Promise<CommentData>;
2269
+ editComment(options: {
2270
+ roomId: string;
2271
+ threadId: string;
2272
+ commentId: string;
2273
+ body: CommentBody;
2274
+ }): Promise<CommentData>;
2275
+ deleteComment(options: {
2276
+ roomId: string;
2277
+ threadId: string;
2278
+ commentId: string;
2279
+ }): Promise<void>;
2280
+ };
2281
+ declare function createCommentsApi<ThreadMetadata extends BaseMetadata>(client: Client, { serverEndpoint }: Options): CommentsApi<ThreadMetadata>;
2282
+
2283
+ declare type BaseUserInfo = {
2284
+ name?: string;
2285
+ avatar?: string;
2286
+ };
2287
+
2288
+ declare function isCommentBodyMention(element: CommentBodyElement): element is CommentBodyMention;
2289
+
1890
2290
  /**
1891
2291
  * Helper type to help users adopt to Lson types from interface definitions.
1892
2292
  * You should only use this to wrap interfaces you don't control. For more
@@ -1899,4 +2299,4 @@ declare type EnsureJson<T> = [
1899
2299
  [K in keyof T]: EnsureJson<T[K]>;
1900
2300
  };
1901
2301
 
1902
- export { AckOp, BaseAuthResult, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RejectedStorageOpServerMsg, Resolve, Room, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ToImmutable, ToJson, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, asPos, assert, assertNever, b64decode, createClient, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, toPlainLson, tryParseJson, withTimeout };
2302
+ export { AckOp, AsyncCache, AsyncState, AsyncStateError, AsyncStateInitial, AsyncStateLoading, AsyncStateResolved, AsyncStateSuccess, BaseAuthResult, BaseMetadata, BaseUserInfo, BaseUserMeta, BroadcastEventClientMsg, BroadcastOptions, BroadcastedEventServerMsg, Client, ClientMsg, ClientMsgCode, CommentBody, CommentBodyElement, CommentBodyMention, CommentBodyParagraph, CommentData, CommentsApi, CrdtType, CreateChildOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, CreateRootObjectOp, CustomAuthenticationResult, Delegates, DeleteCrdtOp, DeleteObjectKeyOp, DevToolsTreeNode as DevTools, protocol as DevToolsMsg, EnsureJson, EventSource, FetchStorageClientMsg, FetchYDocClientMsg, History, IWebSocket, IWebSocketCloseEvent, IWebSocketEvent, IWebSocketInstance, IWebSocketMessageEvent, IdTuple, Immutable, InitialDocumentStateServerMsg, Json, JsonArray, JsonObject, JsonScalar, LegacyConnectionStatus, LiveList, LiveListUpdate, LiveMap, LiveMapUpdate, LiveNode, LiveObject, LiveObjectUpdate, LiveStructure, LostConnectionEvent, Lson, LsonObject, NodeMap, Op, OpCode, Others, ParentToChildNodeMap, PlainLson, PlainLsonFields, PlainLsonList, PlainLsonMap, PlainLsonObject, RealtimeClient, RejectedStorageOpServerMsg, Resolve, Room, RoomInitializers, RoomStateServerMsg, SerializedChild, SerializedCrdt, SerializedList, SerializedMap, SerializedObject, SerializedRegister, SerializedRootObject, ServerMsg, ServerMsgCode, SetParentKeyOp, Status, StorageStatus, StorageUpdate, ThreadData, ToImmutable, ToJson, UnsubscribeCallback, UpdateObjectOp, UpdatePresenceClientMsg, UpdatePresenceServerMsg, UpdateStorageClientMsg, UpdateStorageServerMsg, UpdateYDocClientMsg, User, UserJoinServerMsg, UserLeftServerMsg, WebsocketCloseCodes, asArrayWithLegacyMethods, asPos, assert, assertNever, b64decode, fancyConsole as console, createAsyncCache, createClient, createCommentsApi, deprecate, deprecateIf, detectDupes, errorIf, freeze, isChildCrdt, isCommentBodyMention, isJsonArray, isJsonObject, isJsonScalar, isPlainObject, isRootCrdt, legacy_patchImmutableObject, lsonToJson, makeEventSource, makePoller, makePosition, nn, patchLiveObjectKey, shallow, throwUsageError, toPlainLson, tryParseJson, withTimeout };