@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.cjs
CHANGED
|
@@ -129,7 +129,9 @@ var feedMetadataRecordForCreate = _decoders.record.call(void 0,
|
|
|
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 = _decoders.optional.call(void 0,
|
|
132
|
+
var optionalFeedMetadataDecoder = _decoders.optional.call(void 0,
|
|
133
|
+
feedMetadataRecordForCreate
|
|
134
|
+
);
|
|
133
135
|
var feedMetadataUpdateDecoder = _decoders.record.call(void 0,
|
|
134
136
|
feedMetadataIdDecoder,
|
|
135
137
|
feedMetadataNullableValueDecoder
|
|
@@ -826,7 +828,6 @@ function makeMetadataDB(driver) {
|
|
|
826
828
|
|
|
827
829
|
|
|
828
830
|
|
|
829
|
-
|
|
830
831
|
var _asyncmutex = require('async-mutex');
|
|
831
832
|
|
|
832
833
|
var _itertools = require('itertools');
|
|
@@ -967,6 +968,12 @@ var Logger = class _Logger {
|
|
|
967
968
|
|
|
968
969
|
|
|
969
970
|
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
|
|
974
|
+
|
|
975
|
+
|
|
976
|
+
|
|
970
977
|
// src/lib/text.ts
|
|
971
978
|
function quote(value) {
|
|
972
979
|
return value !== void 0 ? `'${value}'` : "???";
|
|
@@ -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 _core.nodeStreamToCompactNodes.call(void 0, 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 = _decoders.array.call(void 0, clientMsgDecoder);
|
|
2039
2058
|
var ServerMsgCode2 = { ..._core.ServerMsgCode, ...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 _itertools.chunkedByCost.call(void 0, 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,29 +2227,27 @@ 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 = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _61 => _61.storage]), () => ( makeNewInMemoryDriver()));
|
|
2208
2231
|
this.meta = meta;
|
|
2209
2232
|
this.driver = driver;
|
|
2210
2233
|
this.logger = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _62 => _62.logger]), () => ( BLACK_HOLE));
|
|
2211
|
-
__privateSet(this, __allowStreaming, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.allowStreaming]), () => ( true)));
|
|
2212
2234
|
this.hooks = {
|
|
2213
|
-
isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2235
|
+
isClientMsgAllowed: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _63 => _63.hooks, 'optionalAccess', _64 => _64.isClientMsgAllowed]), () => ( (() => {
|
|
2214
2236
|
return {
|
|
2215
2237
|
allowed: true
|
|
2216
2238
|
};
|
|
2217
2239
|
}))),
|
|
2218
2240
|
// YYY .load() isn't called on the RoomServer yet! As soon as it does, these hooks will get called
|
|
2219
|
-
onRoomWillLoad: _optionalChain([options, 'optionalAccess',
|
|
2220
|
-
onRoomDidLoad: _optionalChain([options, 'optionalAccess',
|
|
2221
|
-
onRoomWillUnload: _optionalChain([options, 'optionalAccess',
|
|
2222
|
-
onRoomDidUnload: _optionalChain([options, 'optionalAccess',
|
|
2223
|
-
onSessionDidStart: _optionalChain([options, 'optionalAccess',
|
|
2224
|
-
onSessionDidEnd: _optionalChain([options, 'optionalAccess',
|
|
2225
|
-
postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess',
|
|
2226
|
-
postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess',
|
|
2241
|
+
onRoomWillLoad: _optionalChain([options, 'optionalAccess', _65 => _65.hooks, 'optionalAccess', _66 => _66.onRoomWillLoad]),
|
|
2242
|
+
onRoomDidLoad: _optionalChain([options, 'optionalAccess', _67 => _67.hooks, 'optionalAccess', _68 => _68.onRoomDidLoad]),
|
|
2243
|
+
onRoomWillUnload: _optionalChain([options, 'optionalAccess', _69 => _69.hooks, 'optionalAccess', _70 => _70.onRoomWillUnload]),
|
|
2244
|
+
onRoomDidUnload: _optionalChain([options, 'optionalAccess', _71 => _71.hooks, 'optionalAccess', _72 => _72.onRoomDidUnload]),
|
|
2245
|
+
onSessionDidStart: _optionalChain([options, 'optionalAccess', _73 => _73.hooks, 'optionalAccess', _74 => _74.onSessionDidStart]),
|
|
2246
|
+
onSessionDidEnd: _optionalChain([options, 'optionalAccess', _75 => _75.hooks, 'optionalAccess', _76 => _76.onSessionDidEnd]),
|
|
2247
|
+
postClientMsgStorageDidUpdate: _optionalChain([options, 'optionalAccess', _77 => _77.hooks, 'optionalAccess', _78 => _78.postClientMsgStorageDidUpdate]),
|
|
2248
|
+
postClientMsgYdocDidUpdate: _optionalChain([options, 'optionalAccess', _79 => _79.hooks, 'optionalAccess', _80 => _80.postClientMsgYdocDidUpdate])
|
|
2227
2249
|
};
|
|
2228
|
-
__privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2250
|
+
__privateSet(this, __debug2, _nullishCoalesce(_optionalChain([options, 'optionalAccess', _81 => _81.enableDebugLogging]), () => ( false)));
|
|
2229
2251
|
}
|
|
2230
2252
|
get loadingState() {
|
|
2231
2253
|
if (this._loadData$ === null) {
|
|
@@ -2299,13 +2321,13 @@ var Room = class {
|
|
|
2299
2321
|
* room will be reloaded from storage.
|
|
2300
2322
|
*/
|
|
2301
2323
|
unload(ctx) {
|
|
2302
|
-
_optionalChain([this, 'access',
|
|
2324
|
+
_optionalChain([this, 'access', _82 => _82.hooks, 'access', _83 => _83.onRoomWillUnload, 'optionalCall', _84 => _84(ctx)]);
|
|
2303
2325
|
if (this._data) {
|
|
2304
2326
|
this.storage.unload();
|
|
2305
2327
|
this.yjsStorage.unload();
|
|
2306
2328
|
}
|
|
2307
2329
|
this._loadData$ = null;
|
|
2308
|
-
_optionalChain([this, 'access',
|
|
2330
|
+
_optionalChain([this, 'access', _85 => _85.hooks, 'access', _86 => _86.onRoomDidUnload, 'optionalCall', _87 => _87(ctx)]);
|
|
2309
2331
|
}
|
|
2310
2332
|
/**
|
|
2311
2333
|
* Issues a Ticket with a new/unique actor ID
|
|
@@ -2319,17 +2341,17 @@ var Room = class {
|
|
|
2319
2341
|
* unused Ticket will simply get garbage collected.
|
|
2320
2342
|
*/
|
|
2321
2343
|
async createTicket(options) {
|
|
2322
|
-
const actor$ = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2344
|
+
const actor$ = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _88 => _88.actor]), () => ( this.getNextActor()));
|
|
2323
2345
|
const sessionKey = _nanoid.nanoid.call(void 0, );
|
|
2324
|
-
const info = _optionalChain([options, 'optionalAccess',
|
|
2346
|
+
const info = _optionalChain([options, 'optionalAccess', _89 => _89.info]);
|
|
2325
2347
|
const ticket = {
|
|
2326
|
-
version: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2348
|
+
version: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _90 => _90.version]), () => ( HIGHEST_PROTOCOL_VERSION)),
|
|
2327
2349
|
actor: await actor$,
|
|
2328
2350
|
sessionKey,
|
|
2329
|
-
meta: _optionalChain([options, 'optionalAccess',
|
|
2330
|
-
publicMeta: _optionalChain([options, 'optionalAccess',
|
|
2331
|
-
user: _optionalChain([options, 'optionalAccess',
|
|
2332
|
-
scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2351
|
+
meta: _optionalChain([options, 'optionalAccess', _91 => _91.meta]),
|
|
2352
|
+
publicMeta: _optionalChain([options, 'optionalAccess', _92 => _92.publicMeta]),
|
|
2353
|
+
user: _optionalChain([options, 'optionalAccess', _93 => _93.id]) ? { id: options.id, info } : { anonymousId: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _94 => _94.anonymousId]), () => ( _nanoid.nanoid.call(void 0, ))), info },
|
|
2354
|
+
scopes: _nullishCoalesce(_optionalChain([options, 'optionalAccess', _95 => _95.scopes]), () => ( ["room:write"]))
|
|
2333
2355
|
};
|
|
2334
2356
|
if (__privateGet(this, __debug2)) {
|
|
2335
2357
|
console.log(`new ticket created: ${JSON.stringify(ticket)}`);
|
|
@@ -2463,7 +2485,7 @@ var Room = class {
|
|
|
2463
2485
|
ctx,
|
|
2464
2486
|
defer
|
|
2465
2487
|
);
|
|
2466
|
-
const p$ = _optionalChain([this, 'access',
|
|
2488
|
+
const p$ = _optionalChain([this, 'access', _96 => _96.hooks, 'access', _97 => _97.onSessionDidStart, 'optionalCall', _98 => _98(newSession, ctx)]);
|
|
2467
2489
|
if (p$) defer(p$);
|
|
2468
2490
|
}
|
|
2469
2491
|
/**
|
|
@@ -2487,7 +2509,7 @@ var Room = class {
|
|
|
2487
2509
|
for (const other of this.otherSessions(key)) {
|
|
2488
2510
|
other.send({ type: ServerMsgCode2.USER_LEFT, actor: session.actor });
|
|
2489
2511
|
}
|
|
2490
|
-
const p$ = _optionalChain([this, 'access',
|
|
2512
|
+
const p$ = _optionalChain([this, 'access', _99 => _99.hooks, 'access', _100 => _100.onSessionDidEnd, 'optionalCall', _101 => _101(session, ctx)]);
|
|
2491
2513
|
if (p$) defer(p$);
|
|
2492
2514
|
}
|
|
2493
2515
|
}
|
|
@@ -2518,7 +2540,7 @@ var Room = class {
|
|
|
2518
2540
|
);
|
|
2519
2541
|
}) {
|
|
2520
2542
|
const text = typeof data === "string" ? data : _core.raise.call(void 0, "Unsupported message format");
|
|
2521
|
-
_optionalChain([this, 'access',
|
|
2543
|
+
_optionalChain([this, 'access', _102 => _102.sessions, 'access', _103 => _103.get, 'call', _104 => _104(key), 'optionalAccess', _105 => _105.markActive, 'call', _106 => _106()]);
|
|
2522
2544
|
if (text === "ping") {
|
|
2523
2545
|
await this.handlePing(key, ctx);
|
|
2524
2546
|
} else {
|
|
@@ -2873,7 +2895,7 @@ var Room = class {
|
|
|
2873
2895
|
}
|
|
2874
2896
|
// Don't ever manually call this!
|
|
2875
2897
|
async _load(ctx) {
|
|
2876
|
-
await _optionalChain([this, 'access',
|
|
2898
|
+
await _optionalChain([this, 'access', _107 => _107.hooks, 'access', _108 => _108.onRoomWillLoad, 'optionalCall', _109 => _109(ctx)]);
|
|
2877
2899
|
const storage = await this._loadStorage();
|
|
2878
2900
|
const yjsStorage = await this._loadYjsStorage();
|
|
2879
2901
|
this._data = {
|
|
@@ -2881,7 +2903,7 @@ var Room = class {
|
|
|
2881
2903
|
storage,
|
|
2882
2904
|
yjsStorage
|
|
2883
2905
|
};
|
|
2884
|
-
await _optionalChain([this, 'access',
|
|
2906
|
+
await _optionalChain([this, 'access', _110 => _110.hooks, 'access', _111 => _111.onRoomDidLoad, 'optionalCall', _112 => _112(ctx)]);
|
|
2885
2907
|
}
|
|
2886
2908
|
/**
|
|
2887
2909
|
* Returns a new, unique, actor ID.
|
|
@@ -2921,7 +2943,7 @@ var Room = class {
|
|
|
2921
2943
|
}
|
|
2922
2944
|
const sent = session.sendPong();
|
|
2923
2945
|
if (sent !== 0) {
|
|
2924
|
-
await _optionalChain([this, 'access',
|
|
2946
|
+
await _optionalChain([this, 'access', _113 => _113.hooks, 'access', _114 => _114.onDidPong, 'optionalCall', _115 => _115(ctx)]);
|
|
2925
2947
|
}
|
|
2926
2948
|
}
|
|
2927
2949
|
async _processClientMsg_withExclusiveAccess(sessionKey, messages, ctx, defer) {
|
|
@@ -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 _core.ClientMsgCode.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
|
-
_core.nodeStreamToCompactNodes.call(void 0, 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 {
|
|
@@ -3060,7 +3074,7 @@ var Room = class {
|
|
|
3060
3074
|
break;
|
|
3061
3075
|
}
|
|
3062
3076
|
case _core.ClientMsgCode.UPDATE_STORAGE: {
|
|
3063
|
-
_optionalChain([this, 'access',
|
|
3077
|
+
_optionalChain([this, 'access', _116 => _116.driver, 'access', _117 => _117.bump_storage_version, 'optionalCall', _118 => _118()]);
|
|
3064
3078
|
const result = await this.storage.applyOps(msg.ops);
|
|
3065
3079
|
const opsToForward = result.flatMap(
|
|
3066
3080
|
(r) => r.action === "accepted" ? [r.op] : []
|
|
@@ -3093,7 +3107,7 @@ var Room = class {
|
|
|
3093
3107
|
});
|
|
3094
3108
|
}
|
|
3095
3109
|
if (opsToForward.length > 0) {
|
|
3096
|
-
const p$ = _optionalChain([this, 'access',
|
|
3110
|
+
const p$ = _optionalChain([this, 'access', _119 => _119.hooks, 'access', _120 => _120.postClientMsgStorageDidUpdate, 'optionalCall', _121 => _121(ctx)]);
|
|
3097
3111
|
if (p$) defer(p$);
|
|
3098
3112
|
}
|
|
3099
3113
|
break;
|
|
@@ -3144,7 +3158,7 @@ var Room = class {
|
|
|
3144
3158
|
defer
|
|
3145
3159
|
);
|
|
3146
3160
|
if (result.isUpdated) {
|
|
3147
|
-
const p$ = _optionalChain([this, 'access',
|
|
3161
|
+
const p$ = _optionalChain([this, 'access', _122 => _122.hooks, 'access', _123 => _123.postClientMsgYdocDidUpdate, 'optionalCall', _124 => _124(ctx, session)]);
|
|
3148
3162
|
if (p$) defer(p$);
|
|
3149
3163
|
}
|
|
3150
3164
|
break;
|
|
@@ -3327,7 +3341,6 @@ var Room = class {
|
|
|
3327
3341
|
}
|
|
3328
3342
|
};
|
|
3329
3343
|
__debug2 = new WeakMap();
|
|
3330
|
-
__allowStreaming = new WeakMap();
|
|
3331
3344
|
|
|
3332
3345
|
|
|
3333
3346
|
|