@liveblocks/server 1.4.1 → 1.4.2-pre1
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.cjs +66 -53
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -13
- package/dist/index.d.ts +57 -13
- package/dist/index.js +40 -27
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, Awaitable, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
|
|
1
|
+
import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, Awaitable, CompactNode, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
|
|
2
2
|
export { BroadcastEventClientMsg, ClientMsg, ClientWireOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, DeleteCrdtOp, DeleteObjectKeyOp, FetchStorageClientMsg, FetchYDocClientMsg, HasOpId, IgnoredOp, Op, RoomStateServerMsg, ServerMsg, ServerWireOp, SetParentKeyOp, UpdateObjectOp, UpdatePresenceClientMsg, UpdateStorageClientMsg, UpdateYDocClientMsg } from '@liveblocks/core';
|
|
3
3
|
import * as decoders from 'decoders';
|
|
4
4
|
import { Decoder } from 'decoders';
|
|
@@ -23,6 +23,37 @@ import * as Y from 'yjs';
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
type Pos = ReturnType<typeof asPos>;
|
|
26
|
+
declare const fromType: unique symbol;
|
|
27
|
+
/**
|
|
28
|
+
* A string known to be a valid JSON-encoded value. Use this whenever a
|
|
29
|
+
* `string` already carries JSON, to keep that fact visible in the type system
|
|
30
|
+
* (instead of letting it look like a freeform `string`).
|
|
31
|
+
*
|
|
32
|
+
* Optionally parameterised by the *parsed* shape: `jstring<CompactNode>`
|
|
33
|
+
* means "a string whose `JSON.parse` result is a `CompactNode`". Without
|
|
34
|
+
* a type argument, defaults to `jstring<Json>` (any JSON value).
|
|
35
|
+
*
|
|
36
|
+
* At storage boundaries (e.g. reading `jdata` from SQLite), `as jstring`
|
|
37
|
+
* is acceptable — we trust the bytes are valid JSON because we wrote them as
|
|
38
|
+
* JSON ourselves.
|
|
39
|
+
*
|
|
40
|
+
* For example, these are valid JSON strings:
|
|
41
|
+
* - '0', '1', '2', '3', '3.14', etc.
|
|
42
|
+
* - 'null', 'true', 'false'
|
|
43
|
+
* - '{"foo":1}', '{ "foo": 1 }' (spaces are fine)
|
|
44
|
+
* - '[]', '[1,2, 3]', '[[]]', etc.
|
|
45
|
+
* - '["hi",{}]'
|
|
46
|
+
* - '"foo"'
|
|
47
|
+
*
|
|
48
|
+
* But these are not:
|
|
49
|
+
* - 'foo'
|
|
50
|
+
* - '1,2,3'
|
|
51
|
+
* - '{'
|
|
52
|
+
* - '[1,2,3,]' or '{"foo":1},' (trailing commas are not valid)
|
|
53
|
+
*/
|
|
54
|
+
type jstring<J = Json> = string & {
|
|
55
|
+
readonly [fromType]: J;
|
|
56
|
+
};
|
|
26
57
|
type NodeTuple<T extends SerializedCrdt = SerializedCrdt> = [
|
|
27
58
|
id: string,
|
|
28
59
|
value: T
|
|
@@ -683,6 +714,27 @@ interface IStorageDriverNodeAPI {
|
|
|
683
714
|
* Yield all nodes as [id, node] pairs. Must always include the root node.
|
|
684
715
|
*/
|
|
685
716
|
iter_nodes(): Iterable<StorageNode>;
|
|
717
|
+
/**
|
|
718
|
+
* Yield each node as a pre-built `CompactNode` JSON tuple string, ready to
|
|
719
|
+
* be emitted directly into a STORAGE_CHUNK wire frame without JSON.parse()
|
|
720
|
+
* or JSON.stringify()'ing overhead. Implementations MUST produce text whose
|
|
721
|
+
* parsed shape exactly matches the `CompactNode` union type from
|
|
722
|
+
* @liveblocks/core. The emitted shapes are:
|
|
723
|
+
*
|
|
724
|
+
* - Root node: '["root",<data>]'
|
|
725
|
+
* - OBJECT / REGISTER: '["0:1",0,"root","a",<data>]'
|
|
726
|
+
* - LIST / MAP: '["0:2",1,"0:1","b"]'
|
|
727
|
+
*
|
|
728
|
+
* Invariant (implementations MUST uphold; asserted by `_generateFullTestSuite`):
|
|
729
|
+
*
|
|
730
|
+
* iter_nodes_optimized().map(JSON.parse)
|
|
731
|
+
* ≡ nodeStreamToCompactNodes(iter_nodes())
|
|
732
|
+
*
|
|
733
|
+
* i.e. parsing each yielded string yields the same sequence of CompactNodes
|
|
734
|
+
* that the canonical `iter_nodes()` + `nodeStreamToCompactNodes()` path
|
|
735
|
+
* would produce.
|
|
736
|
+
*/
|
|
737
|
+
iter_nodes_optimized(): Iterable<jstring<CompactNode>>;
|
|
686
738
|
/**
|
|
687
739
|
* Return true iff a node with the given id exists. Must return true for "root".
|
|
688
740
|
*/
|
|
@@ -1228,10 +1280,9 @@ type Millis = Brand<number, "Millis">;
|
|
|
1228
1280
|
* receives it as part of its ROOM_STATE message.
|
|
1229
1281
|
*/
|
|
1230
1282
|
type SessionKey = Brand<string, "SessionKey">;
|
|
1231
|
-
type PreSerializedServerMsg = Brand<string, "PreSerializedServerMsg">;
|
|
1232
1283
|
type ClientMsg = ClientMsg$1<JsonObject, Json> | FetchFeedsClientMsg | FetchFeedMessagesClientMsg | AddFeedClientMsg | UpdateFeedClientMsg | DeleteFeedClientMsg | AddFeedMessageClientMsg | UpdateFeedMessageClientMsg | DeleteFeedMessageClientMsg;
|
|
1233
1284
|
type ServerMsg = ServerMsg$1<JsonObject, BaseUserMeta, Json> | FeedMessagesServerMsg | FeedsServerMsg;
|
|
1234
|
-
declare function serialize(msgs: ServerMsg | readonly ServerMsg[]):
|
|
1285
|
+
declare function serialize(msgs: ServerMsg | readonly ServerMsg[]): jstring<ServerMsg>;
|
|
1235
1286
|
declare function ackIgnoredOp(opId: string): IgnoredOp;
|
|
1236
1287
|
/**
|
|
1237
1288
|
* A known or anonymous user.
|
|
@@ -1278,7 +1329,7 @@ declare class BrowserSession<SM, CM extends JsonObject> {
|
|
|
1278
1329
|
get hasNotifiedClientStorageUpdateError(): boolean;
|
|
1279
1330
|
setHasNotifiedClientStorageUpdateError(): void;
|
|
1280
1331
|
sendPong(): number;
|
|
1281
|
-
send(serverMsg: ServerMsg | ServerMsg[] |
|
|
1332
|
+
send(serverMsg: ServerMsg | ServerMsg[] | jstring<ServerMsg>): number;
|
|
1282
1333
|
}
|
|
1283
1334
|
declare class BackendSession extends BrowserSession<never, never> {
|
|
1284
1335
|
}
|
|
@@ -1317,13 +1368,6 @@ type RoomOptions<SM, CM extends JsonObject, C> = {
|
|
|
1317
1368
|
*/
|
|
1318
1369
|
storage?: IStorageDriver;
|
|
1319
1370
|
logger?: Logger;
|
|
1320
|
-
/**
|
|
1321
|
-
* Whether to allow streaming storage responses. Only safe with drivers
|
|
1322
|
-
* that can guarantee that no Ops from other clients can get interleaved
|
|
1323
|
-
* between the chunk generation until the last chunk has been sent.
|
|
1324
|
-
* Defaults to true, but is notably NOT safe to use from DOS-KV backends.
|
|
1325
|
-
*/
|
|
1326
|
-
allowStreaming?: boolean;
|
|
1327
1371
|
hooks?: {
|
|
1328
1372
|
/** Customize which incoming messages from a client are allowed or disallowed. */
|
|
1329
1373
|
isClientMsgAllowed?: (msg: ClientMsg, session: BrowserSession<SM, CM>) => {
|
|
@@ -1436,7 +1480,7 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
|
|
|
1436
1480
|
createTicket(options?: CreateTicketOptions<SM, CM>): Promise<Ticket<SM, CM>>;
|
|
1437
1481
|
createBackendSession_experimental(): Promise<[
|
|
1438
1482
|
session: BackendSession,
|
|
1439
|
-
outgoingMessages:
|
|
1483
|
+
outgoingMessages: jstring<ServerMsg>[]
|
|
1440
1484
|
]>;
|
|
1441
1485
|
/**
|
|
1442
1486
|
* Restores the given sessions as the Room server's session list. Can only be
|
|
@@ -1895,4 +1939,4 @@ declare class InMemoryDriver implements IStorageDriver {
|
|
|
1895
1939
|
load_nodes_api(): IStorageDriverNodeAPI;
|
|
1896
1940
|
}
|
|
1897
1941
|
|
|
1898
|
-
export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IStorageDriverNodeAPI, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, type LoadingState, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos,
|
|
1942
|
+
export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IStorageDriverNodeAPI, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, type LoadingState, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos, ProtocolVersion, ROOT_YDOC_ID, Room, type SessionKey, type Ticket, UniqueMap, type UpdateFeedClientMsg, type UpdateFeedMessageClientMsg, type YDocId, type YUpdate, type YVector, ackIgnoredOp, clientMsgDecoder, concatUint8Arrays, feedFailureServerMsg, feedMetadataIdDecoder, feedMetadataUpdateDecoder, feedRequestFailed, fetchFeedsMetadataFilterDecoder, guidDecoder, isLeasedSessionExpired, jsonObjectYolo, jsonYolo, type jstring, makeInMemorySnapshot, makeMetadataDB, mapFeedError, optionalFeedMetadataDecoder, plainLsonToNodeStream, protocolVersionDecoder, quote, serialize as serializeServerMsg, snapshotToLossyJson_eager, snapshotToLossyJson_lazy, snapshotToNodeStream, snapshotToPlainLson_eager, snapshotToPlainLson_lazy, Storage as test_only__Storage, YjsStorage as test_only__YjsStorage, transientClientMsgDecoder, tryCatch };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, Awaitable, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
|
|
1
|
+
import { Json, asPos, IUserInfo, SerializedCrdt, JsonObject, DistributiveOmit, SetParentKeyOp, DeleteCrdtOp, ClientMsg as ClientMsg$1, Brand, SerializedRootObject, SerializedChild, StorageNode, Awaitable, CompactNode, PlainLsonObject, NodeMap as NodeMap$1, NodeStream as NodeStream$1, ClientWireOp, ServerMsg as ServerMsg$1, BaseUserMeta, IgnoredOp } from '@liveblocks/core';
|
|
2
2
|
export { BroadcastEventClientMsg, ClientMsg, ClientWireOp, CreateListOp, CreateMapOp, CreateObjectOp, CreateOp, CreateRegisterOp, DeleteCrdtOp, DeleteObjectKeyOp, FetchStorageClientMsg, FetchYDocClientMsg, HasOpId, IgnoredOp, Op, RoomStateServerMsg, ServerMsg, ServerWireOp, SetParentKeyOp, UpdateObjectOp, UpdatePresenceClientMsg, UpdateStorageClientMsg, UpdateYDocClientMsg } from '@liveblocks/core';
|
|
3
3
|
import * as decoders from 'decoders';
|
|
4
4
|
import { Decoder } from 'decoders';
|
|
@@ -23,6 +23,37 @@ import * as Y from 'yjs';
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
type Pos = ReturnType<typeof asPos>;
|
|
26
|
+
declare const fromType: unique symbol;
|
|
27
|
+
/**
|
|
28
|
+
* A string known to be a valid JSON-encoded value. Use this whenever a
|
|
29
|
+
* `string` already carries JSON, to keep that fact visible in the type system
|
|
30
|
+
* (instead of letting it look like a freeform `string`).
|
|
31
|
+
*
|
|
32
|
+
* Optionally parameterised by the *parsed* shape: `jstring<CompactNode>`
|
|
33
|
+
* means "a string whose `JSON.parse` result is a `CompactNode`". Without
|
|
34
|
+
* a type argument, defaults to `jstring<Json>` (any JSON value).
|
|
35
|
+
*
|
|
36
|
+
* At storage boundaries (e.g. reading `jdata` from SQLite), `as jstring`
|
|
37
|
+
* is acceptable — we trust the bytes are valid JSON because we wrote them as
|
|
38
|
+
* JSON ourselves.
|
|
39
|
+
*
|
|
40
|
+
* For example, these are valid JSON strings:
|
|
41
|
+
* - '0', '1', '2', '3', '3.14', etc.
|
|
42
|
+
* - 'null', 'true', 'false'
|
|
43
|
+
* - '{"foo":1}', '{ "foo": 1 }' (spaces are fine)
|
|
44
|
+
* - '[]', '[1,2, 3]', '[[]]', etc.
|
|
45
|
+
* - '["hi",{}]'
|
|
46
|
+
* - '"foo"'
|
|
47
|
+
*
|
|
48
|
+
* But these are not:
|
|
49
|
+
* - 'foo'
|
|
50
|
+
* - '1,2,3'
|
|
51
|
+
* - '{'
|
|
52
|
+
* - '[1,2,3,]' or '{"foo":1},' (trailing commas are not valid)
|
|
53
|
+
*/
|
|
54
|
+
type jstring<J = Json> = string & {
|
|
55
|
+
readonly [fromType]: J;
|
|
56
|
+
};
|
|
26
57
|
type NodeTuple<T extends SerializedCrdt = SerializedCrdt> = [
|
|
27
58
|
id: string,
|
|
28
59
|
value: T
|
|
@@ -683,6 +714,27 @@ interface IStorageDriverNodeAPI {
|
|
|
683
714
|
* Yield all nodes as [id, node] pairs. Must always include the root node.
|
|
684
715
|
*/
|
|
685
716
|
iter_nodes(): Iterable<StorageNode>;
|
|
717
|
+
/**
|
|
718
|
+
* Yield each node as a pre-built `CompactNode` JSON tuple string, ready to
|
|
719
|
+
* be emitted directly into a STORAGE_CHUNK wire frame without JSON.parse()
|
|
720
|
+
* or JSON.stringify()'ing overhead. Implementations MUST produce text whose
|
|
721
|
+
* parsed shape exactly matches the `CompactNode` union type from
|
|
722
|
+
* @liveblocks/core. The emitted shapes are:
|
|
723
|
+
*
|
|
724
|
+
* - Root node: '["root",<data>]'
|
|
725
|
+
* - OBJECT / REGISTER: '["0:1",0,"root","a",<data>]'
|
|
726
|
+
* - LIST / MAP: '["0:2",1,"0:1","b"]'
|
|
727
|
+
*
|
|
728
|
+
* Invariant (implementations MUST uphold; asserted by `_generateFullTestSuite`):
|
|
729
|
+
*
|
|
730
|
+
* iter_nodes_optimized().map(JSON.parse)
|
|
731
|
+
* ≡ nodeStreamToCompactNodes(iter_nodes())
|
|
732
|
+
*
|
|
733
|
+
* i.e. parsing each yielded string yields the same sequence of CompactNodes
|
|
734
|
+
* that the canonical `iter_nodes()` + `nodeStreamToCompactNodes()` path
|
|
735
|
+
* would produce.
|
|
736
|
+
*/
|
|
737
|
+
iter_nodes_optimized(): Iterable<jstring<CompactNode>>;
|
|
686
738
|
/**
|
|
687
739
|
* Return true iff a node with the given id exists. Must return true for "root".
|
|
688
740
|
*/
|
|
@@ -1228,10 +1280,9 @@ type Millis = Brand<number, "Millis">;
|
|
|
1228
1280
|
* receives it as part of its ROOM_STATE message.
|
|
1229
1281
|
*/
|
|
1230
1282
|
type SessionKey = Brand<string, "SessionKey">;
|
|
1231
|
-
type PreSerializedServerMsg = Brand<string, "PreSerializedServerMsg">;
|
|
1232
1283
|
type ClientMsg = ClientMsg$1<JsonObject, Json> | FetchFeedsClientMsg | FetchFeedMessagesClientMsg | AddFeedClientMsg | UpdateFeedClientMsg | DeleteFeedClientMsg | AddFeedMessageClientMsg | UpdateFeedMessageClientMsg | DeleteFeedMessageClientMsg;
|
|
1233
1284
|
type ServerMsg = ServerMsg$1<JsonObject, BaseUserMeta, Json> | FeedMessagesServerMsg | FeedsServerMsg;
|
|
1234
|
-
declare function serialize(msgs: ServerMsg | readonly ServerMsg[]):
|
|
1285
|
+
declare function serialize(msgs: ServerMsg | readonly ServerMsg[]): jstring<ServerMsg>;
|
|
1235
1286
|
declare function ackIgnoredOp(opId: string): IgnoredOp;
|
|
1236
1287
|
/**
|
|
1237
1288
|
* A known or anonymous user.
|
|
@@ -1278,7 +1329,7 @@ declare class BrowserSession<SM, CM extends JsonObject> {
|
|
|
1278
1329
|
get hasNotifiedClientStorageUpdateError(): boolean;
|
|
1279
1330
|
setHasNotifiedClientStorageUpdateError(): void;
|
|
1280
1331
|
sendPong(): number;
|
|
1281
|
-
send(serverMsg: ServerMsg | ServerMsg[] |
|
|
1332
|
+
send(serverMsg: ServerMsg | ServerMsg[] | jstring<ServerMsg>): number;
|
|
1282
1333
|
}
|
|
1283
1334
|
declare class BackendSession extends BrowserSession<never, never> {
|
|
1284
1335
|
}
|
|
@@ -1317,13 +1368,6 @@ type RoomOptions<SM, CM extends JsonObject, C> = {
|
|
|
1317
1368
|
*/
|
|
1318
1369
|
storage?: IStorageDriver;
|
|
1319
1370
|
logger?: Logger;
|
|
1320
|
-
/**
|
|
1321
|
-
* Whether to allow streaming storage responses. Only safe with drivers
|
|
1322
|
-
* that can guarantee that no Ops from other clients can get interleaved
|
|
1323
|
-
* between the chunk generation until the last chunk has been sent.
|
|
1324
|
-
* Defaults to true, but is notably NOT safe to use from DOS-KV backends.
|
|
1325
|
-
*/
|
|
1326
|
-
allowStreaming?: boolean;
|
|
1327
1371
|
hooks?: {
|
|
1328
1372
|
/** Customize which incoming messages from a client are allowed or disallowed. */
|
|
1329
1373
|
isClientMsgAllowed?: (msg: ClientMsg, session: BrowserSession<SM, CM>) => {
|
|
@@ -1436,7 +1480,7 @@ declare class Room<RM, SM, CM extends JsonObject, C = undefined> {
|
|
|
1436
1480
|
createTicket(options?: CreateTicketOptions<SM, CM>): Promise<Ticket<SM, CM>>;
|
|
1437
1481
|
createBackendSession_experimental(): Promise<[
|
|
1438
1482
|
session: BackendSession,
|
|
1439
|
-
outgoingMessages:
|
|
1483
|
+
outgoingMessages: jstring<ServerMsg>[]
|
|
1440
1484
|
]>;
|
|
1441
1485
|
/**
|
|
1442
1486
|
* Restores the given sessions as the Room server's session list. Can only be
|
|
@@ -1895,4 +1939,4 @@ declare class InMemoryDriver implements IStorageDriver {
|
|
|
1895
1939
|
load_nodes_api(): IStorageDriverNodeAPI;
|
|
1896
1940
|
}
|
|
1897
1941
|
|
|
1898
|
-
export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IStorageDriverNodeAPI, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, type LoadingState, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos,
|
|
1942
|
+
export { type ActorID, type AddFeedClientMsg, type AddFeedMessageClientMsg, BackendSession, BrowserSession, ConsoleTarget, type CreateTicketOptions, DefaultMap, type DeleteFeedClientMsg, type DeleteFeedMessageClientMsg, type Feed, type FeedDeletedServerMsg, type FeedMessage, type FeedMessagesAddedServerMsg, type FeedMessagesDeletedServerMsg, type FeedMessagesListServerMsg, type FeedMessagesServerMsg, type FeedMessagesUpdatedServerMsg, FeedMsgCode, FeedRequestErrorCode, type FeedRequestFailedServerMsg, type FeedsAddedServerMsg, type FeedsListServerMsg, type FeedsServerMsg, type FeedsUpdatedServerMsg, type FetchFeedMessagesClientMsg, type FetchFeedsClientMsg, type FixOp, type Guid, type IReadableSnapshot, type IServerWebSocket, type IStorageDriver, type IStorageDriverNodeAPI, type IUserData, InMemoryDriver, type LeasedSession, type ListFeedMessagesOptions, type ListFeedMessagesResult, type ListFeedsOptions, type ListFeedsResult, type LoadingState, LogLevel, LogTarget, Logger, type MetadataDB, type Millis, NestedMap, type NodeMap, type NodeStream, type NodeTuple, type Pos, ProtocolVersion, ROOT_YDOC_ID, Room, type SessionKey, type Ticket, UniqueMap, type UpdateFeedClientMsg, type UpdateFeedMessageClientMsg, type YDocId, type YUpdate, type YVector, ackIgnoredOp, clientMsgDecoder, concatUint8Arrays, feedFailureServerMsg, feedMetadataIdDecoder, feedMetadataUpdateDecoder, feedRequestFailed, fetchFeedsMetadataFilterDecoder, guidDecoder, isLeasedSessionExpired, jsonObjectYolo, jsonYolo, type jstring, makeInMemorySnapshot, makeMetadataDB, mapFeedError, optionalFeedMetadataDecoder, plainLsonToNodeStream, protocolVersionDecoder, quote, serialize as serializeServerMsg, snapshotToLossyJson_eager, snapshotToLossyJson_lazy, snapshotToNodeStream, snapshotToPlainLson_eager, snapshotToPlainLson_lazy, Storage as test_only__Storage, YjsStorage as test_only__YjsStorage, transientClientMsgDecoder, tryCatch };
|
package/dist/index.js
CHANGED
|
@@ -129,7 +129,9 @@ var feedMetadataRecordForCreate = record(
|
|
|
129
129
|
(value) => Object.keys(value).length <= MAX_METADATA_COUNT,
|
|
130
130
|
`Must be at most ${MAX_METADATA_COUNT} items`
|
|
131
131
|
);
|
|
132
|
-
var optionalFeedMetadataDecoder = optional(
|
|
132
|
+
var optionalFeedMetadataDecoder = optional(
|
|
133
|
+
feedMetadataRecordForCreate
|
|
134
|
+
);
|
|
133
135
|
var feedMetadataUpdateDecoder = record(
|
|
134
136
|
feedMetadataIdDecoder,
|
|
135
137
|
feedMetadataNullableValueDecoder
|
|
@@ -820,7 +822,6 @@ function makeMetadataDB(driver) {
|
|
|
820
822
|
import {
|
|
821
823
|
assertNever as assertNever3,
|
|
822
824
|
ClientMsgCode as ClientMsgCode2,
|
|
823
|
-
nodeStreamToCompactNodes,
|
|
824
825
|
OpCode as OpCode3,
|
|
825
826
|
raise as raise3,
|
|
826
827
|
ServerMsgCode as CoreServerMsgCode,
|
|
@@ -829,7 +830,7 @@ import {
|
|
|
829
830
|
} from "@liveblocks/core";
|
|
830
831
|
import { Mutex, tryAcquire } from "async-mutex";
|
|
831
832
|
import { array as array3, formatInline } from "decoders";
|
|
832
|
-
import {
|
|
833
|
+
import { chunkedByCost } from "itertools";
|
|
833
834
|
import { nanoid as nanoid2 } from "nanoid";
|
|
834
835
|
|
|
835
836
|
// src/lib/Logger.ts
|
|
@@ -964,7 +965,13 @@ var Logger = class _Logger {
|
|
|
964
965
|
};
|
|
965
966
|
|
|
966
967
|
// src/plugins/InMemoryDriver.ts
|
|
967
|
-
import {
|
|
968
|
+
import {
|
|
969
|
+
asPos,
|
|
970
|
+
CrdtType as CrdtType4,
|
|
971
|
+
isRootStorageNode as isRootStorageNode2,
|
|
972
|
+
nn as nn2,
|
|
973
|
+
nodeStreamToCompactNodes
|
|
974
|
+
} from "@liveblocks/core";
|
|
968
975
|
import { ifilter, imap } from "itertools";
|
|
969
976
|
|
|
970
977
|
// src/lib/text.ts
|
|
@@ -1374,6 +1381,17 @@ var InMemoryDriver = class {
|
|
|
1374
1381
|
* Yield all nodes as [id, node] pairs. Must always include the root node.
|
|
1375
1382
|
*/
|
|
1376
1383
|
iter_nodes: () => nodes,
|
|
1384
|
+
/**
|
|
1385
|
+
* Yield each node as a pre-built CompactNode JSON tuple string.
|
|
1386
|
+
*
|
|
1387
|
+
* This implementation IS the canonical reference for the invariant:
|
|
1388
|
+
* iter_nodes_optimized` ≡ `nodeStreamToCompactNodes(iter_nodes())
|
|
1389
|
+
*/
|
|
1390
|
+
*iter_nodes_optimized() {
|
|
1391
|
+
for (const compact of nodeStreamToCompactNodes(nodes)) {
|
|
1392
|
+
yield JSON.stringify(compact);
|
|
1393
|
+
}
|
|
1394
|
+
},
|
|
1377
1395
|
/**
|
|
1378
1396
|
* Return true iff a node with the given id exists. Must return true for "root".
|
|
1379
1397
|
*/
|
|
@@ -2035,6 +2053,7 @@ function isLeasedSessionExpired(leasedSession) {
|
|
|
2035
2053
|
}
|
|
2036
2054
|
|
|
2037
2055
|
// src/Room.ts
|
|
2056
|
+
var MB = 1024 * 1024;
|
|
2038
2057
|
var messagesDecoder = array3(clientMsgDecoder);
|
|
2039
2058
|
var ServerMsgCode2 = { ...CoreServerMsgCode, ...FeedMsgCode };
|
|
2040
2059
|
var HIGHEST_PROTOCOL_VERSION = Math.max(
|
|
@@ -2048,6 +2067,11 @@ var SERVER_MSG_CODE_NAMES = Object.fromEntries(
|
|
|
2048
2067
|
var BLACK_HOLE = new Logger([
|
|
2049
2068
|
/* No targets, i.e. black hole logger */
|
|
2050
2069
|
]);
|
|
2070
|
+
function groupNodesForWebSocketMessages(input) {
|
|
2071
|
+
const MAX_SIZE = 16 * MB;
|
|
2072
|
+
const idealSize = (chunkIndex) => chunkIndex < 3 ? 1 * MB : Math.min(8, chunkIndex - 1) * MB;
|
|
2073
|
+
return chunkedByCost(input, (tup) => tup.length, MAX_SIZE, idealSize);
|
|
2074
|
+
}
|
|
2051
2075
|
function collectSideEffects() {
|
|
2052
2076
|
const deferred = [];
|
|
2053
2077
|
return {
|
|
@@ -2181,7 +2205,7 @@ var BackendSession = class extends BrowserSession {
|
|
|
2181
2205
|
super(ticket, socket, debug);
|
|
2182
2206
|
}
|
|
2183
2207
|
};
|
|
2184
|
-
var __debug2
|
|
2208
|
+
var __debug2;
|
|
2185
2209
|
var Room = class {
|
|
2186
2210
|
constructor(meta, options) {
|
|
2187
2211
|
// ^^^^^^^^^^ User-defined Room Metadata, Session Metadata, and Client Metadata
|
|
@@ -2203,12 +2227,10 @@ var Room = class {
|
|
|
2203
2227
|
__publicField(this, "sessions", new UniqueMap((s) => s.actor));
|
|
2204
2228
|
__publicField(this, "hooks");
|
|
2205
2229
|
__privateAdd(this, __debug2);
|
|
2206
|
-
__privateAdd(this, __allowStreaming);
|
|
2207
2230
|
const driver = options?.storage ?? makeNewInMemoryDriver();
|
|
2208
2231
|
this.meta = meta;
|
|
2209
2232
|
this.driver = driver;
|
|
2210
2233
|
this.logger = options?.logger ?? BLACK_HOLE;
|
|
2211
|
-
__privateSet(this, __allowStreaming, options?.allowStreaming ?? true);
|
|
2212
2234
|
this.hooks = {
|
|
2213
2235
|
isClientMsgAllowed: options?.hooks?.isClientMsgAllowed ?? (() => {
|
|
2214
2236
|
return {
|
|
@@ -2973,7 +2995,13 @@ var Room = class {
|
|
|
2973
2995
|
const toReplyImmediately = [];
|
|
2974
2996
|
const toReplyAfter = [];
|
|
2975
2997
|
const replyImmediately = (msg) => {
|
|
2976
|
-
if (
|
|
2998
|
+
if (typeof msg === "string") {
|
|
2999
|
+
if (toReplyImmediately.length > 0) {
|
|
3000
|
+
session.send(toReplyImmediately);
|
|
3001
|
+
toReplyImmediately.length = 0;
|
|
3002
|
+
}
|
|
3003
|
+
session.send(msg);
|
|
3004
|
+
} else if (Array.isArray(msg)) {
|
|
2977
3005
|
for (const m of msg) {
|
|
2978
3006
|
toReplyImmediately.push(m);
|
|
2979
3007
|
}
|
|
@@ -3031,24 +3059,10 @@ var Room = class {
|
|
|
3031
3059
|
}
|
|
3032
3060
|
case ClientMsgCode2.FETCH_STORAGE: {
|
|
3033
3061
|
if (session.version >= 8 /* V8 */) {
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
NODES_PER_CHUNK
|
|
3039
|
-
)) {
|
|
3040
|
-
replyImmediately({
|
|
3041
|
-
type: ServerMsgCode2.STORAGE_CHUNK,
|
|
3042
|
-
nodes: chunk
|
|
3043
|
-
});
|
|
3044
|
-
}
|
|
3045
|
-
} else {
|
|
3046
|
-
replyImmediately({
|
|
3047
|
-
type: ServerMsgCode2.STORAGE_CHUNK,
|
|
3048
|
-
nodes: Array.from(
|
|
3049
|
-
nodeStreamToCompactNodes(this.storage.loadedDriver.iter_nodes())
|
|
3050
|
-
)
|
|
3051
|
-
});
|
|
3062
|
+
const rawStream = this.storage.loadedDriver.iter_nodes_optimized();
|
|
3063
|
+
for (const chunk of groupNodesForWebSocketMessages(rawStream)) {
|
|
3064
|
+
const frame = `{"type":${ServerMsgCode2.STORAGE_CHUNK},"nodes":[${chunk.join(",")}]}`;
|
|
3065
|
+
replyImmediately(frame);
|
|
3052
3066
|
}
|
|
3053
3067
|
replyImmediately({ type: ServerMsgCode2.STORAGE_STREAM_END });
|
|
3054
3068
|
} else {
|
|
@@ -3327,7 +3341,6 @@ var Room = class {
|
|
|
3327
3341
|
}
|
|
3328
3342
|
};
|
|
3329
3343
|
__debug2 = new WeakMap();
|
|
3330
|
-
__allowStreaming = new WeakMap();
|
|
3331
3344
|
export {
|
|
3332
3345
|
BackendSession,
|
|
3333
3346
|
BrowserSession,
|