@liveblocks/core 3.13.0-vincent3 → 3.13.1-hackathon
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 +502 -322
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +331 -212
- package/dist/index.d.ts +331 -212
- package/dist/index.js +434 -254
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "3.13.
|
|
9
|
+
var PKG_VERSION = "3.13.1-hackathon";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -251,6 +251,19 @@ function findLastIndex(arr, predicate) {
|
|
|
251
251
|
}
|
|
252
252
|
return -1;
|
|
253
253
|
}
|
|
254
|
+
function partition(iterable, predicate) {
|
|
255
|
+
const good = [];
|
|
256
|
+
const bad = [];
|
|
257
|
+
let index = 0;
|
|
258
|
+
for (const item of iterable) {
|
|
259
|
+
if (predicate(item, index++)) {
|
|
260
|
+
good.push(item);
|
|
261
|
+
} else {
|
|
262
|
+
bad.push(item);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return [good, bad];
|
|
266
|
+
}
|
|
254
267
|
|
|
255
268
|
// src/lib/signals.ts
|
|
256
269
|
var kSinks = Symbol("kSinks");
|
|
@@ -1606,6 +1619,7 @@ function createApiClient({
|
|
|
1606
1619
|
comment: {
|
|
1607
1620
|
id: commentId,
|
|
1608
1621
|
body: options.body,
|
|
1622
|
+
metadata: options.commentMetadata,
|
|
1609
1623
|
attachmentIds: options.attachmentIds
|
|
1610
1624
|
},
|
|
1611
1625
|
metadata: options.metadata
|
|
@@ -1659,6 +1673,16 @@ function createApiClient({
|
|
|
1659
1673
|
options.metadata
|
|
1660
1674
|
);
|
|
1661
1675
|
}
|
|
1676
|
+
async function editCommentMetadata(options) {
|
|
1677
|
+
return await httpClient.post(
|
|
1678
|
+
url`/v2/c/rooms/${options.roomId}/threads/${options.threadId}/comments/${options.commentId}/metadata`,
|
|
1679
|
+
await authManager.getAuthValue({
|
|
1680
|
+
requestedScope: "comments:read",
|
|
1681
|
+
roomId: options.roomId
|
|
1682
|
+
}),
|
|
1683
|
+
options.metadata
|
|
1684
|
+
);
|
|
1685
|
+
}
|
|
1662
1686
|
async function createComment(options) {
|
|
1663
1687
|
const commentId = options.commentId ?? createCommentId();
|
|
1664
1688
|
const comment = await httpClient.post(
|
|
@@ -1670,6 +1694,7 @@ function createApiClient({
|
|
|
1670
1694
|
{
|
|
1671
1695
|
id: commentId,
|
|
1672
1696
|
body: options.body,
|
|
1697
|
+
metadata: options.metadata,
|
|
1673
1698
|
attachmentIds: options.attachmentIds
|
|
1674
1699
|
}
|
|
1675
1700
|
);
|
|
@@ -1684,7 +1709,8 @@ function createApiClient({
|
|
|
1684
1709
|
}),
|
|
1685
1710
|
{
|
|
1686
1711
|
body: options.body,
|
|
1687
|
-
attachmentIds: options.attachmentIds
|
|
1712
|
+
attachmentIds: options.attachmentIds,
|
|
1713
|
+
metadata: options.metadata
|
|
1688
1714
|
}
|
|
1689
1715
|
);
|
|
1690
1716
|
return convertToCommentData(comment);
|
|
@@ -2426,6 +2452,7 @@ function createApiClient({
|
|
|
2426
2452
|
editThreadMetadata,
|
|
2427
2453
|
createComment,
|
|
2428
2454
|
editComment,
|
|
2455
|
+
editCommentMetadata,
|
|
2429
2456
|
deleteComment,
|
|
2430
2457
|
addReaction,
|
|
2431
2458
|
removeReaction,
|
|
@@ -3090,12 +3117,7 @@ var ServerMsgCode = Object.freeze({
|
|
|
3090
3117
|
BROADCASTED_EVENT: 103,
|
|
3091
3118
|
ROOM_STATE: 104,
|
|
3092
3119
|
// For Storage
|
|
3093
|
-
|
|
3094
|
-
// Only sent in V7
|
|
3095
|
-
STORAGE_CHUNK: 210,
|
|
3096
|
-
// Used in V8+
|
|
3097
|
-
STORAGE_STREAM_END: 211,
|
|
3098
|
-
// Used in V8+
|
|
3120
|
+
STORAGE_STATE: 200,
|
|
3099
3121
|
UPDATE_STORAGE: 201,
|
|
3100
3122
|
// For Yjs Docs
|
|
3101
3123
|
UPDATE_YDOC: 300,
|
|
@@ -3109,6 +3131,10 @@ var ServerMsgCode = Object.freeze({
|
|
|
3109
3131
|
COMMENT_DELETED: 404,
|
|
3110
3132
|
COMMENT_REACTION_ADDED: 405,
|
|
3111
3133
|
COMMENT_REACTION_REMOVED: 406,
|
|
3134
|
+
COMMENT_METADATA_UPDATED: 409,
|
|
3135
|
+
// For Agent Sessions
|
|
3136
|
+
AGENT_SESSIONS: 501,
|
|
3137
|
+
AGENT_MESSAGES: 503,
|
|
3112
3138
|
// Error codes
|
|
3113
3139
|
REJECT_STORAGE_OP: 299
|
|
3114
3140
|
// Sent if a mutation was not allowed on the server (i.e. due to permissions, limit exceeded, etc)
|
|
@@ -6094,6 +6120,19 @@ var AbstractCrdt = class {
|
|
|
6094
6120
|
}
|
|
6095
6121
|
this.#pool = void 0;
|
|
6096
6122
|
}
|
|
6123
|
+
/**
|
|
6124
|
+
* Serializes this CRDT and all its children into a list of creation ops
|
|
6125
|
+
* with opIds. Used for forward operations that will be sent over the wire
|
|
6126
|
+
* immediately. Each op gets a unique opId for server acknowledgement.
|
|
6127
|
+
*
|
|
6128
|
+
* @internal
|
|
6129
|
+
*/
|
|
6130
|
+
_toOpsWithOpId(parentId, parentKey, pool) {
|
|
6131
|
+
return this._toOps(parentId, parentKey).map((op) => ({
|
|
6132
|
+
opId: pool.generateOpId(),
|
|
6133
|
+
...op
|
|
6134
|
+
}));
|
|
6135
|
+
}
|
|
6097
6136
|
/** This caches the result of the last .toImmutable() call for this Live node. */
|
|
6098
6137
|
#cachedImmutable;
|
|
6099
6138
|
#cachedTreeNodeKey;
|
|
@@ -6145,57 +6184,6 @@ var CrdtType = Object.freeze({
|
|
|
6145
6184
|
MAP: 2,
|
|
6146
6185
|
REGISTER: 3
|
|
6147
6186
|
});
|
|
6148
|
-
function isRootNode(node) {
|
|
6149
|
-
return node[0] === "root";
|
|
6150
|
-
}
|
|
6151
|
-
function isRootCrdt(id, _) {
|
|
6152
|
-
return id === "root";
|
|
6153
|
-
}
|
|
6154
|
-
function* compactNodesToNodeStream(nodes) {
|
|
6155
|
-
for (const node of nodes) {
|
|
6156
|
-
const id = node[0];
|
|
6157
|
-
if (isRootNode(node)) {
|
|
6158
|
-
yield [id, { type: CrdtType.OBJECT, data: node[1] }];
|
|
6159
|
-
continue;
|
|
6160
|
-
}
|
|
6161
|
-
switch (node[1]) {
|
|
6162
|
-
case CrdtType.OBJECT:
|
|
6163
|
-
yield [id, { type: CrdtType.OBJECT, parentId: node[2], parentKey: node[3], data: node[4] }];
|
|
6164
|
-
break;
|
|
6165
|
-
case CrdtType.LIST:
|
|
6166
|
-
yield [id, { type: CrdtType.LIST, parentId: node[2], parentKey: node[3] }];
|
|
6167
|
-
break;
|
|
6168
|
-
case CrdtType.MAP:
|
|
6169
|
-
yield [id, { type: CrdtType.MAP, parentId: node[2], parentKey: node[3] }];
|
|
6170
|
-
break;
|
|
6171
|
-
case CrdtType.REGISTER:
|
|
6172
|
-
yield [id, { type: CrdtType.REGISTER, parentId: node[2], parentKey: node[3], data: node[4] }];
|
|
6173
|
-
break;
|
|
6174
|
-
}
|
|
6175
|
-
}
|
|
6176
|
-
}
|
|
6177
|
-
function* nodeStreamToCompactNodes(nodes) {
|
|
6178
|
-
for (const [id, node] of nodes) {
|
|
6179
|
-
switch (node.type) {
|
|
6180
|
-
case CrdtType.OBJECT:
|
|
6181
|
-
if (isRootCrdt(id, node)) {
|
|
6182
|
-
yield [id, node.data];
|
|
6183
|
-
} else {
|
|
6184
|
-
yield [id, CrdtType.OBJECT, node.parentId, node.parentKey, node.data];
|
|
6185
|
-
}
|
|
6186
|
-
break;
|
|
6187
|
-
case CrdtType.LIST:
|
|
6188
|
-
yield [id, CrdtType.LIST, node.parentId, node.parentKey];
|
|
6189
|
-
break;
|
|
6190
|
-
case CrdtType.MAP:
|
|
6191
|
-
yield [id, CrdtType.MAP, node.parentId, node.parentKey];
|
|
6192
|
-
break;
|
|
6193
|
-
case CrdtType.REGISTER:
|
|
6194
|
-
yield [id, CrdtType.REGISTER, node.parentId, node.parentKey, node.data];
|
|
6195
|
-
break;
|
|
6196
|
-
}
|
|
6197
|
-
}
|
|
6198
|
-
}
|
|
6199
6187
|
|
|
6200
6188
|
// src/crdts/LiveRegister.ts
|
|
6201
6189
|
var LiveRegister = class _LiveRegister extends AbstractCrdt {
|
|
@@ -6214,7 +6202,7 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
|
|
|
6214
6202
|
return register;
|
|
6215
6203
|
}
|
|
6216
6204
|
/** @internal */
|
|
6217
|
-
_toOps(parentId, parentKey
|
|
6205
|
+
_toOps(parentId, parentKey) {
|
|
6218
6206
|
if (this._id === void 0) {
|
|
6219
6207
|
throw new Error(
|
|
6220
6208
|
"Cannot serialize register if parentId or parentKey is undefined"
|
|
@@ -6223,7 +6211,6 @@ var LiveRegister = class _LiveRegister extends AbstractCrdt {
|
|
|
6223
6211
|
return [
|
|
6224
6212
|
{
|
|
6225
6213
|
type: OpCode.CREATE_REGISTER,
|
|
6226
|
-
opId: pool?.generateOpId(),
|
|
6227
6214
|
id: this._id,
|
|
6228
6215
|
parentId,
|
|
6229
6216
|
parentKey,
|
|
@@ -6322,14 +6309,13 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6322
6309
|
* This is quite unintuitive and should disappear as soon as
|
|
6323
6310
|
* we introduce an explicit LiveList.Set operation
|
|
6324
6311
|
*/
|
|
6325
|
-
_toOps(parentId, parentKey
|
|
6312
|
+
_toOps(parentId, parentKey) {
|
|
6326
6313
|
if (this._id === void 0) {
|
|
6327
6314
|
throw new Error("Cannot serialize item is not attached");
|
|
6328
6315
|
}
|
|
6329
6316
|
const ops = [];
|
|
6330
6317
|
const op = {
|
|
6331
6318
|
id: this._id,
|
|
6332
|
-
opId: pool?.generateOpId(),
|
|
6333
6319
|
type: OpCode.CREATE_LIST,
|
|
6334
6320
|
parentId,
|
|
6335
6321
|
parentKey
|
|
@@ -6338,13 +6324,9 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6338
6324
|
for (const item of this.#items) {
|
|
6339
6325
|
const parentKey2 = item._getParentKeyOrThrow();
|
|
6340
6326
|
const childOps = HACK_addIntentAndDeletedIdToOperation(
|
|
6341
|
-
item._toOps(this._id, parentKey2
|
|
6327
|
+
item._toOps(this._id, parentKey2),
|
|
6342
6328
|
void 0
|
|
6343
6329
|
);
|
|
6344
|
-
const childOpId = childOps[0].opId;
|
|
6345
|
-
if (childOpId !== void 0) {
|
|
6346
|
-
this.#unacknowledgedSets.set(parentKey2, childOpId);
|
|
6347
|
-
}
|
|
6348
6330
|
ops.push(...childOps);
|
|
6349
6331
|
}
|
|
6350
6332
|
return ops;
|
|
@@ -6636,7 +6618,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6636
6618
|
existingItem._detach();
|
|
6637
6619
|
this.#items[indexOfItemWithSameKey] = child;
|
|
6638
6620
|
const reverse = HACK_addIntentAndDeletedIdToOperation(
|
|
6639
|
-
existingItem._toOps(nn(this._id), key
|
|
6621
|
+
existingItem._toOps(nn(this._id), key),
|
|
6640
6622
|
op.id
|
|
6641
6623
|
);
|
|
6642
6624
|
const delta = [setDelta(indexOfItemWithSameKey, child)];
|
|
@@ -6692,7 +6674,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6692
6674
|
_detachChild(child) {
|
|
6693
6675
|
if (child) {
|
|
6694
6676
|
const parentKey = nn(child._parentKey);
|
|
6695
|
-
const reverse = child._toOps(nn(this._id), parentKey
|
|
6677
|
+
const reverse = child._toOps(nn(this._id), parentKey);
|
|
6696
6678
|
const indexToDelete = this.#items.indexOf(child);
|
|
6697
6679
|
if (indexToDelete === -1) {
|
|
6698
6680
|
return {
|
|
@@ -6899,7 +6881,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6899
6881
|
const id = this._pool.generateId();
|
|
6900
6882
|
value._attach(id, this._pool);
|
|
6901
6883
|
this._pool.dispatch(
|
|
6902
|
-
value.
|
|
6884
|
+
value._toOpsWithOpId(this._id, position, this._pool),
|
|
6903
6885
|
[{ type: OpCode.DELETE_CRDT, id }],
|
|
6904
6886
|
/* @__PURE__ */ new Map([
|
|
6905
6887
|
[this._id, makeUpdate(this, [insertDelta(index, value)])]
|
|
@@ -7058,12 +7040,12 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7058
7040
|
const storageUpdates = /* @__PURE__ */ new Map();
|
|
7059
7041
|
storageUpdates.set(this._id, makeUpdate(this, [setDelta(index, value)]));
|
|
7060
7042
|
const ops = HACK_addIntentAndDeletedIdToOperation(
|
|
7061
|
-
value.
|
|
7043
|
+
value._toOpsWithOpId(this._id, position, this._pool),
|
|
7062
7044
|
existingId
|
|
7063
7045
|
);
|
|
7064
7046
|
this.#unacknowledgedSets.set(position, nn(ops[0].opId));
|
|
7065
7047
|
const reverseOps = HACK_addIntentAndDeletedIdToOperation(
|
|
7066
|
-
existingItem._toOps(this._id, position
|
|
7048
|
+
existingItem._toOps(this._id, position),
|
|
7067
7049
|
id
|
|
7068
7050
|
);
|
|
7069
7051
|
this._pool.dispatch(ops, reverseOps, storageUpdates);
|
|
@@ -7302,21 +7284,20 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7302
7284
|
}
|
|
7303
7285
|
}
|
|
7304
7286
|
/** @internal */
|
|
7305
|
-
_toOps(parentId, parentKey
|
|
7287
|
+
_toOps(parentId, parentKey) {
|
|
7306
7288
|
if (this._id === void 0) {
|
|
7307
7289
|
throw new Error("Cannot serialize item is not attached");
|
|
7308
7290
|
}
|
|
7309
7291
|
const ops = [];
|
|
7310
7292
|
const op = {
|
|
7311
7293
|
id: this._id,
|
|
7312
|
-
opId: pool?.generateOpId(),
|
|
7313
7294
|
type: OpCode.CREATE_MAP,
|
|
7314
7295
|
parentId,
|
|
7315
7296
|
parentKey
|
|
7316
7297
|
};
|
|
7317
7298
|
ops.push(op);
|
|
7318
7299
|
for (const [key, value] of this.#map) {
|
|
7319
|
-
ops.push(...value._toOps(this._id, key
|
|
7300
|
+
ops.push(...value._toOps(this._id, key));
|
|
7320
7301
|
}
|
|
7321
7302
|
return ops;
|
|
7322
7303
|
}
|
|
@@ -7400,7 +7381,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7400
7381
|
_detachChild(child) {
|
|
7401
7382
|
const id = nn(this._id);
|
|
7402
7383
|
const parentKey = nn(child._parentKey);
|
|
7403
|
-
const reverse = child._toOps(id, parentKey
|
|
7384
|
+
const reverse = child._toOps(id, parentKey);
|
|
7404
7385
|
for (const [key, value] of this.#map) {
|
|
7405
7386
|
if (value === child) {
|
|
7406
7387
|
this.#map.delete(key);
|
|
@@ -7467,10 +7448,10 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7467
7448
|
type: "LiveMap",
|
|
7468
7449
|
updates: { [key]: { type: "update" } }
|
|
7469
7450
|
});
|
|
7470
|
-
const ops = item.
|
|
7451
|
+
const ops = item._toOpsWithOpId(this._id, key, this._pool);
|
|
7471
7452
|
this.#unacknowledgedSet.set(key, nn(ops[0].opId));
|
|
7472
7453
|
this._pool.dispatch(
|
|
7473
|
-
|
|
7454
|
+
ops,
|
|
7474
7455
|
oldValue ? oldValue._toOps(this._id, key) : [{ type: OpCode.DELETE_CRDT, id }],
|
|
7475
7456
|
storageUpdates
|
|
7476
7457
|
);
|
|
@@ -7630,12 +7611,25 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7630
7611
|
|
|
7631
7612
|
// src/crdts/LiveObject.ts
|
|
7632
7613
|
var MAX_LIVE_OBJECT_SIZE = 128 * 1024;
|
|
7633
|
-
function
|
|
7614
|
+
function isRootCrdt(id, _) {
|
|
7634
7615
|
return id === "root";
|
|
7635
7616
|
}
|
|
7636
7617
|
var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
7637
7618
|
#map;
|
|
7638
|
-
|
|
7619
|
+
/**
|
|
7620
|
+
* Tracks unacknowledged local changes per property to preserve optimistic
|
|
7621
|
+
* updates. Maps property keys to their pending operation IDs.
|
|
7622
|
+
*
|
|
7623
|
+
* INVARIANT: Only locally-generated opIds are ever stored here. Remote opIds
|
|
7624
|
+
* are only compared against (to detect ACKs), never stored.
|
|
7625
|
+
*
|
|
7626
|
+
* When a local change is made, the opId is stored here. When a remote op
|
|
7627
|
+
* arrives for the same key:
|
|
7628
|
+
* - If no entry exists → apply remote op
|
|
7629
|
+
* - If opId matches → it's an ACK, clear the entry
|
|
7630
|
+
* - If opId differs → ignore remote op to preserve optimistic update
|
|
7631
|
+
*/
|
|
7632
|
+
#unackedOpsByKey;
|
|
7639
7633
|
/**
|
|
7640
7634
|
* Enable or disable detection of too large LiveObjects.
|
|
7641
7635
|
* When enabled, throws an error if LiveObject static data exceeds 128KB, which
|
|
@@ -7650,7 +7644,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7650
7644
|
const parentToChildren = /* @__PURE__ */ new Map();
|
|
7651
7645
|
let root = null;
|
|
7652
7646
|
for (const [id, crdt] of items) {
|
|
7653
|
-
if (
|
|
7647
|
+
if (isRootCrdt(id, crdt)) {
|
|
7654
7648
|
root = crdt;
|
|
7655
7649
|
} else {
|
|
7656
7650
|
const tuple = [id, crdt];
|
|
@@ -7668,8 +7662,8 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7668
7662
|
return [root, parentToChildren];
|
|
7669
7663
|
}
|
|
7670
7664
|
/** @private Do not use this API directly */
|
|
7671
|
-
static _fromItems(
|
|
7672
|
-
const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(
|
|
7665
|
+
static _fromItems(items, pool) {
|
|
7666
|
+
const [root, parentToChildren] = _LiveObject.#buildRootAndParentToChildren(items);
|
|
7673
7667
|
return _LiveObject._deserialize(
|
|
7674
7668
|
["root", root],
|
|
7675
7669
|
parentToChildren,
|
|
@@ -7678,7 +7672,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7678
7672
|
}
|
|
7679
7673
|
constructor(obj = {}) {
|
|
7680
7674
|
super();
|
|
7681
|
-
this.#
|
|
7675
|
+
this.#unackedOpsByKey = /* @__PURE__ */ new Map();
|
|
7682
7676
|
const o = compactObject(obj);
|
|
7683
7677
|
for (const key of Object.keys(o)) {
|
|
7684
7678
|
const value = o[key];
|
|
@@ -7689,16 +7683,14 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7689
7683
|
this.#map = new Map(Object.entries(o));
|
|
7690
7684
|
}
|
|
7691
7685
|
/** @internal */
|
|
7692
|
-
_toOps(parentId, parentKey
|
|
7686
|
+
_toOps(parentId, parentKey) {
|
|
7693
7687
|
if (this._id === void 0) {
|
|
7694
7688
|
throw new Error("Cannot serialize item is not attached");
|
|
7695
7689
|
}
|
|
7696
|
-
const opId = pool?.generateOpId();
|
|
7697
7690
|
const ops = [];
|
|
7698
7691
|
const op = {
|
|
7699
7692
|
type: OpCode.CREATE_OBJECT,
|
|
7700
7693
|
id: this._id,
|
|
7701
|
-
opId,
|
|
7702
7694
|
parentId,
|
|
7703
7695
|
parentKey,
|
|
7704
7696
|
data: {}
|
|
@@ -7706,7 +7698,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7706
7698
|
ops.push(op);
|
|
7707
7699
|
for (const [key, value] of this.#map) {
|
|
7708
7700
|
if (isLiveNode(value)) {
|
|
7709
|
-
ops.push(...value._toOps(this._id, key
|
|
7701
|
+
ops.push(...value._toOps(this._id, key));
|
|
7710
7702
|
} else {
|
|
7711
7703
|
op.data[key] = value;
|
|
7712
7704
|
}
|
|
@@ -7752,16 +7744,16 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7752
7744
|
const { id, opId, parentKey: key } = op;
|
|
7753
7745
|
const child = creationOpToLson(op);
|
|
7754
7746
|
if (this._pool.getNode(id) !== void 0) {
|
|
7755
|
-
if (this.#
|
|
7756
|
-
this.#
|
|
7747
|
+
if (this.#unackedOpsByKey.get(key) === opId) {
|
|
7748
|
+
this.#unackedOpsByKey.delete(key);
|
|
7757
7749
|
}
|
|
7758
7750
|
return { modified: false };
|
|
7759
7751
|
}
|
|
7760
7752
|
if (source === 0 /* LOCAL */) {
|
|
7761
|
-
this.#
|
|
7762
|
-
} else if (this.#
|
|
7763
|
-
} else if (this.#
|
|
7764
|
-
this.#
|
|
7753
|
+
this.#unackedOpsByKey.set(key, nn(opId));
|
|
7754
|
+
} else if (this.#unackedOpsByKey.get(key) === void 0) {
|
|
7755
|
+
} else if (this.#unackedOpsByKey.get(key) === opId) {
|
|
7756
|
+
this.#unackedOpsByKey.delete(key);
|
|
7765
7757
|
return { modified: false };
|
|
7766
7758
|
} else {
|
|
7767
7759
|
return { modified: false };
|
|
@@ -7803,7 +7795,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7803
7795
|
if (child) {
|
|
7804
7796
|
const id = nn(this._id);
|
|
7805
7797
|
const parentKey = nn(child._parentKey);
|
|
7806
|
-
const reverse = child._toOps(id, parentKey
|
|
7798
|
+
const reverse = child._toOps(id, parentKey);
|
|
7807
7799
|
for (const [key, value] of this.#map) {
|
|
7808
7800
|
if (value === child) {
|
|
7809
7801
|
this.#map.delete(key);
|
|
@@ -7889,11 +7881,11 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7889
7881
|
continue;
|
|
7890
7882
|
}
|
|
7891
7883
|
if (isLocal) {
|
|
7892
|
-
this.#
|
|
7893
|
-
} else if (this.#
|
|
7884
|
+
this.#unackedOpsByKey.set(key, nn(op.opId));
|
|
7885
|
+
} else if (this.#unackedOpsByKey.get(key) === void 0) {
|
|
7894
7886
|
isModified = true;
|
|
7895
|
-
} else if (this.#
|
|
7896
|
-
this.#
|
|
7887
|
+
} else if (this.#unackedOpsByKey.get(key) === op.opId) {
|
|
7888
|
+
this.#unackedOpsByKey.delete(key);
|
|
7897
7889
|
continue;
|
|
7898
7890
|
} else {
|
|
7899
7891
|
continue;
|
|
@@ -7925,7 +7917,7 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
7925
7917
|
if (oldValue === void 0) {
|
|
7926
7918
|
return { modified: false };
|
|
7927
7919
|
}
|
|
7928
|
-
if (!isLocal && this.#
|
|
7920
|
+
if (!isLocal && this.#unackedOpsByKey.get(key) !== void 0) {
|
|
7929
7921
|
return { modified: false };
|
|
7930
7922
|
}
|
|
7931
7923
|
const id = nn(this._id);
|
|
@@ -8108,17 +8100,21 @@ var LiveObject = class _LiveObject extends AbstractCrdt {
|
|
|
8108
8100
|
if (isLiveNode(newValue)) {
|
|
8109
8101
|
newValue._setParentLink(this, key);
|
|
8110
8102
|
newValue._attach(this._pool.generateId(), this._pool);
|
|
8111
|
-
const newAttachChildOps = newValue.
|
|
8103
|
+
const newAttachChildOps = newValue._toOpsWithOpId(
|
|
8104
|
+
this._id,
|
|
8105
|
+
key,
|
|
8106
|
+
this._pool
|
|
8107
|
+
);
|
|
8112
8108
|
const createCrdtOp = newAttachChildOps.find(
|
|
8113
8109
|
(op) => op.parentId === this._id
|
|
8114
8110
|
);
|
|
8115
8111
|
if (createCrdtOp) {
|
|
8116
|
-
this.#
|
|
8112
|
+
this.#unackedOpsByKey.set(key, nn(createCrdtOp.opId));
|
|
8117
8113
|
}
|
|
8118
8114
|
ops.push(...newAttachChildOps);
|
|
8119
8115
|
} else {
|
|
8120
8116
|
updatedProps[key] = newValue;
|
|
8121
|
-
this.#
|
|
8117
|
+
this.#unackedOpsByKey.set(key, opId);
|
|
8122
8118
|
}
|
|
8123
8119
|
this.#map.set(key, newValue);
|
|
8124
8120
|
this.invalidate();
|
|
@@ -8288,7 +8284,10 @@ function getTreesDiffOperations(currentItems, newItems) {
|
|
|
8288
8284
|
const ops = [];
|
|
8289
8285
|
currentItems.forEach((_, id) => {
|
|
8290
8286
|
if (!newItems.get(id)) {
|
|
8291
|
-
ops.push({
|
|
8287
|
+
ops.push({
|
|
8288
|
+
type: OpCode.DELETE_CRDT,
|
|
8289
|
+
id
|
|
8290
|
+
});
|
|
8292
8291
|
}
|
|
8293
8292
|
});
|
|
8294
8293
|
newItems.forEach((crdt, id) => {
|
|
@@ -8511,7 +8510,10 @@ var ClientMsgCode = Object.freeze({
|
|
|
8511
8510
|
UPDATE_STORAGE: 201,
|
|
8512
8511
|
// For Yjs support
|
|
8513
8512
|
FETCH_YDOC: 300,
|
|
8514
|
-
UPDATE_YDOC: 301
|
|
8513
|
+
UPDATE_YDOC: 301,
|
|
8514
|
+
// For Agent Sessions
|
|
8515
|
+
FETCH_AGENT_SESSIONS: 500,
|
|
8516
|
+
FETCH_AGENT_MESSAGES: 502
|
|
8515
8517
|
});
|
|
8516
8518
|
|
|
8517
8519
|
// src/refs/ManagedOthers.ts
|
|
@@ -8713,6 +8715,8 @@ function defaultMessageFromContext(context) {
|
|
|
8713
8715
|
return "Could not delete thread";
|
|
8714
8716
|
case "EDIT_THREAD_METADATA_ERROR":
|
|
8715
8717
|
return "Could not edit thread metadata";
|
|
8718
|
+
case "EDIT_COMMENT_METADATA_ERROR":
|
|
8719
|
+
return "Could not edit comment metadata";
|
|
8716
8720
|
case "MARK_THREAD_AS_RESOLVED_ERROR":
|
|
8717
8721
|
return "Could not mark thread as resolved";
|
|
8718
8722
|
case "MARK_THREAD_AS_UNRESOLVED_ERROR":
|
|
@@ -8786,21 +8790,6 @@ function installBackgroundTabSpy() {
|
|
|
8786
8790
|
};
|
|
8787
8791
|
return [inBackgroundSince, unsub];
|
|
8788
8792
|
}
|
|
8789
|
-
function makePartialNodeMap() {
|
|
8790
|
-
let map = /* @__PURE__ */ new Map();
|
|
8791
|
-
return {
|
|
8792
|
-
append(chunk2) {
|
|
8793
|
-
for (const [id, node] of chunk2) {
|
|
8794
|
-
map.set(id, node);
|
|
8795
|
-
}
|
|
8796
|
-
},
|
|
8797
|
-
clear() {
|
|
8798
|
-
const result = map;
|
|
8799
|
-
map = /* @__PURE__ */ new Map();
|
|
8800
|
-
return result;
|
|
8801
|
-
}
|
|
8802
|
-
};
|
|
8803
|
-
}
|
|
8804
8793
|
function createRoom(options, config) {
|
|
8805
8794
|
const roomId = config.roomId;
|
|
8806
8795
|
const initialPresence = options.initialPresence;
|
|
@@ -8861,7 +8850,6 @@ function createRoom(options, config) {
|
|
|
8861
8850
|
activeBatch: null,
|
|
8862
8851
|
unacknowledgedOps: /* @__PURE__ */ new Map()
|
|
8863
8852
|
};
|
|
8864
|
-
const partialNodes = makePartialNodeMap();
|
|
8865
8853
|
let lastTokenKey;
|
|
8866
8854
|
function onStatusDidChange(newStatus) {
|
|
8867
8855
|
const authValue = managedSocket.authValue;
|
|
@@ -8983,6 +8971,7 @@ function createRoom(options, config) {
|
|
|
8983
8971
|
storageStatus: makeEventSource(),
|
|
8984
8972
|
ydoc: makeEventSource(),
|
|
8985
8973
|
comments: makeEventSource(),
|
|
8974
|
+
agentSessions: makeEventSource(),
|
|
8986
8975
|
roomWillDestroy: makeEventSource()
|
|
8987
8976
|
};
|
|
8988
8977
|
async function createTextMention(mentionId, mention) {
|
|
@@ -9143,11 +9132,14 @@ function createRoom(options, config) {
|
|
|
9143
9132
|
self,
|
|
9144
9133
|
(me) => me !== null ? userToTreeNode("Me", me) : null
|
|
9145
9134
|
);
|
|
9146
|
-
function createOrUpdateRootFromMessage(
|
|
9135
|
+
function createOrUpdateRootFromMessage(message) {
|
|
9136
|
+
if (message.items.length === 0) {
|
|
9137
|
+
throw new Error("Internal error: cannot load storage without items");
|
|
9138
|
+
}
|
|
9147
9139
|
if (context.root !== void 0) {
|
|
9148
|
-
updateRoot(
|
|
9140
|
+
updateRoot(message.items);
|
|
9149
9141
|
} else {
|
|
9150
|
-
context.root = LiveObject._fromItems(
|
|
9142
|
+
context.root = LiveObject._fromItems(message.items, context.pool);
|
|
9151
9143
|
}
|
|
9152
9144
|
const canWrite = self.get()?.canWrite ?? true;
|
|
9153
9145
|
const stackSizeBefore = context.undoStack.length;
|
|
@@ -9164,10 +9156,7 @@ function createRoom(options, config) {
|
|
|
9164
9156
|
}
|
|
9165
9157
|
context.undoStack.length = stackSizeBefore;
|
|
9166
9158
|
}
|
|
9167
|
-
function updateRoot(
|
|
9168
|
-
if (nodes.size === 0) {
|
|
9169
|
-
throw new Error("Internal error: cannot load storage without items");
|
|
9170
|
-
}
|
|
9159
|
+
function updateRoot(items) {
|
|
9171
9160
|
if (context.root === void 0) {
|
|
9172
9161
|
return;
|
|
9173
9162
|
}
|
|
@@ -9175,26 +9164,22 @@ function createRoom(options, config) {
|
|
|
9175
9164
|
for (const [id, node] of context.pool.nodes) {
|
|
9176
9165
|
currentItems.set(id, node._serialize());
|
|
9177
9166
|
}
|
|
9178
|
-
const ops = getTreesDiffOperations(currentItems,
|
|
9179
|
-
const result =
|
|
9180
|
-
ops,
|
|
9181
|
-
/* isLocal */
|
|
9182
|
-
false
|
|
9183
|
-
);
|
|
9167
|
+
const ops = getTreesDiffOperations(currentItems, new Map(items));
|
|
9168
|
+
const result = applyRemoteOps(ops);
|
|
9184
9169
|
notify(result.updates);
|
|
9185
9170
|
}
|
|
9186
|
-
function _addToRealUndoStack(
|
|
9171
|
+
function _addToRealUndoStack(frames) {
|
|
9187
9172
|
if (context.undoStack.length >= 50) {
|
|
9188
9173
|
context.undoStack.shift();
|
|
9189
9174
|
}
|
|
9190
|
-
context.undoStack.push(
|
|
9175
|
+
context.undoStack.push(frames);
|
|
9191
9176
|
onHistoryChange();
|
|
9192
9177
|
}
|
|
9193
|
-
function addToUndoStack(
|
|
9178
|
+
function addToUndoStack(frames) {
|
|
9194
9179
|
if (context.pausedHistory !== null) {
|
|
9195
|
-
context.pausedHistory.pushLeft(
|
|
9180
|
+
context.pausedHistory.pushLeft(frames);
|
|
9196
9181
|
} else {
|
|
9197
|
-
_addToRealUndoStack(
|
|
9182
|
+
_addToRealUndoStack(frames);
|
|
9198
9183
|
}
|
|
9199
9184
|
}
|
|
9200
9185
|
function notify(updates) {
|
|
@@ -9225,69 +9210,85 @@ function createRoom(options, config) {
|
|
|
9225
9210
|
"Internal. Tried to get connection id but connection was never open"
|
|
9226
9211
|
);
|
|
9227
9212
|
}
|
|
9228
|
-
function
|
|
9213
|
+
function applyLocalOps(frames) {
|
|
9214
|
+
const [pframes, ops] = partition(
|
|
9215
|
+
frames,
|
|
9216
|
+
(f) => f.type === "presence"
|
|
9217
|
+
);
|
|
9218
|
+
const opsWithOpIds = ops.map(
|
|
9219
|
+
(op) => op.opId === void 0 ? { ...op, opId: context.pool.generateOpId() } : op
|
|
9220
|
+
);
|
|
9221
|
+
const { reverse, updates } = applyOps(
|
|
9222
|
+
pframes,
|
|
9223
|
+
opsWithOpIds,
|
|
9224
|
+
/* isLocal */
|
|
9225
|
+
true
|
|
9226
|
+
);
|
|
9227
|
+
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
9228
|
+
}
|
|
9229
|
+
function applyRemoteOps(ops) {
|
|
9230
|
+
return applyOps(
|
|
9231
|
+
[],
|
|
9232
|
+
ops,
|
|
9233
|
+
/* isLocal */
|
|
9234
|
+
false
|
|
9235
|
+
);
|
|
9236
|
+
}
|
|
9237
|
+
function applyOps(pframes, ops, isLocal) {
|
|
9229
9238
|
const output = {
|
|
9230
9239
|
reverse: new Deque(),
|
|
9231
9240
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
9232
9241
|
presence: false
|
|
9233
9242
|
};
|
|
9234
|
-
const
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9243
|
+
for (const pf of pframes) {
|
|
9244
|
+
const reverse = {
|
|
9245
|
+
type: "presence",
|
|
9246
|
+
data: {}
|
|
9247
|
+
};
|
|
9248
|
+
for (const key in pf.data) {
|
|
9249
|
+
reverse.data[key] = context.myPresence.get()[key];
|
|
9250
|
+
}
|
|
9251
|
+
context.myPresence.patch(pf.data);
|
|
9252
|
+
if (context.buffer.presenceUpdates === null) {
|
|
9253
|
+
context.buffer.presenceUpdates = { type: "partial", data: pf.data };
|
|
9238
9254
|
} else {
|
|
9239
|
-
|
|
9255
|
+
for (const key in pf.data) {
|
|
9256
|
+
context.buffer.presenceUpdates.data[key] = pf.data[key];
|
|
9257
|
+
}
|
|
9240
9258
|
}
|
|
9241
|
-
|
|
9259
|
+
output.reverse.pushLeft(reverse);
|
|
9260
|
+
output.presence = true;
|
|
9261
|
+
}
|
|
9262
|
+
const createdNodeIds = /* @__PURE__ */ new Set();
|
|
9242
9263
|
for (const op of ops) {
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
reverse.data[key] = context.myPresence.get()[key];
|
|
9250
|
-
}
|
|
9251
|
-
context.myPresence.patch(op.data);
|
|
9252
|
-
if (context.buffer.presenceUpdates === null) {
|
|
9253
|
-
context.buffer.presenceUpdates = { type: "partial", data: op.data };
|
|
9254
|
-
} else {
|
|
9255
|
-
for (const key in op.data) {
|
|
9256
|
-
context.buffer.presenceUpdates.data[key] = op.data[key];
|
|
9257
|
-
}
|
|
9258
|
-
}
|
|
9259
|
-
output.reverse.pushLeft(reverse);
|
|
9260
|
-
output.presence = true;
|
|
9264
|
+
let source;
|
|
9265
|
+
if (isLocal) {
|
|
9266
|
+
source = 0 /* LOCAL */;
|
|
9267
|
+
} else if (op.opId !== void 0) {
|
|
9268
|
+
context.unacknowledgedOps.delete(op.opId);
|
|
9269
|
+
source = 2 /* OURS */;
|
|
9261
9270
|
} else {
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
|
|
9265
|
-
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9271
|
+
source = 1 /* THEIRS */;
|
|
9272
|
+
}
|
|
9273
|
+
const applyOpResult = applyOp(op, source);
|
|
9274
|
+
if (applyOpResult.modified) {
|
|
9275
|
+
const nodeId = applyOpResult.modified.node._id;
|
|
9276
|
+
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
9277
|
+
output.storageUpdates.set(
|
|
9278
|
+
nn(applyOpResult.modified.node._id),
|
|
9279
|
+
mergeStorageUpdates(
|
|
9280
|
+
output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
|
|
9281
|
+
applyOpResult.modified
|
|
9282
|
+
)
|
|
9283
|
+
);
|
|
9284
|
+
output.reverse.pushLeft(applyOpResult.reverse);
|
|
9269
9285
|
}
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
const nodeId = applyOpResult.modified.node._id;
|
|
9273
|
-
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
9274
|
-
output.storageUpdates.set(
|
|
9275
|
-
nn(applyOpResult.modified.node._id),
|
|
9276
|
-
mergeStorageUpdates(
|
|
9277
|
-
output.storageUpdates.get(nn(applyOpResult.modified.node._id)),
|
|
9278
|
-
applyOpResult.modified
|
|
9279
|
-
)
|
|
9280
|
-
);
|
|
9281
|
-
output.reverse.pushLeft(applyOpResult.reverse);
|
|
9282
|
-
}
|
|
9283
|
-
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
|
|
9284
|
-
createdNodeIds.add(nn(op.id));
|
|
9285
|
-
}
|
|
9286
|
+
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
|
|
9287
|
+
createdNodeIds.add(op.id);
|
|
9286
9288
|
}
|
|
9287
9289
|
}
|
|
9288
9290
|
}
|
|
9289
9291
|
return {
|
|
9290
|
-
ops,
|
|
9291
9292
|
reverse: Array.from(output.reverse),
|
|
9292
9293
|
updates: {
|
|
9293
9294
|
storageUpdates: output.storageUpdates,
|
|
@@ -9472,20 +9473,16 @@ function createRoom(options, config) {
|
|
|
9472
9473
|
return compact([parseServerMessage(data)]);
|
|
9473
9474
|
}
|
|
9474
9475
|
}
|
|
9475
|
-
function
|
|
9476
|
-
if (
|
|
9476
|
+
function applyAndSendOfflineOps(unackedOps) {
|
|
9477
|
+
if (unackedOps.size === 0) {
|
|
9477
9478
|
return;
|
|
9478
9479
|
}
|
|
9479
9480
|
const messages = [];
|
|
9480
|
-
const inOps = Array.from(
|
|
9481
|
-
const result =
|
|
9482
|
-
inOps,
|
|
9483
|
-
/* isLocal */
|
|
9484
|
-
true
|
|
9485
|
-
);
|
|
9481
|
+
const inOps = Array.from(unackedOps.values());
|
|
9482
|
+
const result = applyLocalOps(inOps);
|
|
9486
9483
|
messages.push({
|
|
9487
9484
|
type: ClientMsgCode.UPDATE_STORAGE,
|
|
9488
|
-
ops: result.
|
|
9485
|
+
ops: result.opsToEmit
|
|
9489
9486
|
});
|
|
9490
9487
|
notify(result.updates);
|
|
9491
9488
|
sendMessages(messages);
|
|
@@ -9542,18 +9539,12 @@ function createRoom(options, config) {
|
|
|
9542
9539
|
updates.others.push(onRoomStateMessage(message));
|
|
9543
9540
|
break;
|
|
9544
9541
|
}
|
|
9545
|
-
case ServerMsgCode.
|
|
9546
|
-
|
|
9547
|
-
break;
|
|
9548
|
-
case ServerMsgCode.STORAGE_STREAM_END:
|
|
9549
|
-
processInitialStorage(partialNodes.clear());
|
|
9542
|
+
case ServerMsgCode.STORAGE_STATE: {
|
|
9543
|
+
processInitialStorage(message);
|
|
9550
9544
|
break;
|
|
9545
|
+
}
|
|
9551
9546
|
case ServerMsgCode.UPDATE_STORAGE: {
|
|
9552
|
-
const applyResult =
|
|
9553
|
-
message.ops,
|
|
9554
|
-
/* isLocal */
|
|
9555
|
-
false
|
|
9556
|
-
);
|
|
9547
|
+
const applyResult = applyRemoteOps(message.ops);
|
|
9557
9548
|
for (const [key, value] of applyResult.updates.storageUpdates) {
|
|
9558
9549
|
updates.storageUpdates.set(
|
|
9559
9550
|
key,
|
|
@@ -9586,12 +9577,50 @@ function createRoom(options, config) {
|
|
|
9586
9577
|
case ServerMsgCode.COMMENT_REACTION_REMOVED:
|
|
9587
9578
|
case ServerMsgCode.COMMENT_CREATED:
|
|
9588
9579
|
case ServerMsgCode.COMMENT_EDITED:
|
|
9589
|
-
case ServerMsgCode.COMMENT_DELETED:
|
|
9580
|
+
case ServerMsgCode.COMMENT_DELETED:
|
|
9581
|
+
case ServerMsgCode.COMMENT_METADATA_UPDATED: {
|
|
9590
9582
|
eventHub.comments.notify(message);
|
|
9591
9583
|
break;
|
|
9592
9584
|
}
|
|
9593
|
-
case ServerMsgCode.
|
|
9594
|
-
|
|
9585
|
+
case ServerMsgCode.AGENT_SESSIONS: {
|
|
9586
|
+
const agentSessionsMsg = message;
|
|
9587
|
+
if (agentSessionsMsg.operation === "list") {
|
|
9588
|
+
for (const [
|
|
9589
|
+
requestId,
|
|
9590
|
+
{ resolve }
|
|
9591
|
+
] of pendingAgentSessionsRequests) {
|
|
9592
|
+
resolve({
|
|
9593
|
+
sessions: agentSessionsMsg.sessions,
|
|
9594
|
+
nextCursor: agentSessionsMsg.nextCursor
|
|
9595
|
+
});
|
|
9596
|
+
pendingAgentSessionsRequests.delete(requestId);
|
|
9597
|
+
break;
|
|
9598
|
+
}
|
|
9599
|
+
}
|
|
9600
|
+
eventHub.agentSessions.notify(agentSessionsMsg);
|
|
9601
|
+
break;
|
|
9602
|
+
}
|
|
9603
|
+
case ServerMsgCode.AGENT_MESSAGES: {
|
|
9604
|
+
const agentMessagesMsg = message;
|
|
9605
|
+
if (agentMessagesMsg.operation === "list") {
|
|
9606
|
+
for (const [
|
|
9607
|
+
requestId,
|
|
9608
|
+
{ resolve }
|
|
9609
|
+
] of pendingAgentMessagesRequests) {
|
|
9610
|
+
const parsedRequestId = JSON.parse(requestId);
|
|
9611
|
+
if (parsedRequestId.sessionId === agentMessagesMsg.sessionId) {
|
|
9612
|
+
resolve({
|
|
9613
|
+
messages: agentMessagesMsg.messages,
|
|
9614
|
+
nextCursor: agentMessagesMsg.nextCursor
|
|
9615
|
+
});
|
|
9616
|
+
pendingAgentMessagesRequests.delete(requestId);
|
|
9617
|
+
break;
|
|
9618
|
+
}
|
|
9619
|
+
}
|
|
9620
|
+
}
|
|
9621
|
+
eventHub.agentSessions.notify(agentMessagesMsg);
|
|
9622
|
+
break;
|
|
9623
|
+
}
|
|
9595
9624
|
default:
|
|
9596
9625
|
break;
|
|
9597
9626
|
}
|
|
@@ -9602,7 +9631,7 @@ function createRoom(options, config) {
|
|
|
9602
9631
|
const storageOps = context.buffer.storageOperations;
|
|
9603
9632
|
if (storageOps.length > 0) {
|
|
9604
9633
|
for (const op of storageOps) {
|
|
9605
|
-
context.unacknowledgedOps.set(
|
|
9634
|
+
context.unacknowledgedOps.set(op.opId, op);
|
|
9606
9635
|
}
|
|
9607
9636
|
notifyStorageStatus();
|
|
9608
9637
|
}
|
|
@@ -9693,18 +9722,20 @@ function createRoom(options, config) {
|
|
|
9693
9722
|
}
|
|
9694
9723
|
let _getStorage$ = null;
|
|
9695
9724
|
let _resolveStoragePromise = null;
|
|
9696
|
-
|
|
9725
|
+
const pendingAgentSessionsRequests = /* @__PURE__ */ new Map();
|
|
9726
|
+
const pendingAgentMessagesRequests = /* @__PURE__ */ new Map();
|
|
9727
|
+
function processInitialStorage(message) {
|
|
9697
9728
|
const unacknowledgedOps = new Map(context.unacknowledgedOps);
|
|
9698
|
-
createOrUpdateRootFromMessage(
|
|
9699
|
-
|
|
9729
|
+
createOrUpdateRootFromMessage(message);
|
|
9730
|
+
applyAndSendOfflineOps(unacknowledgedOps);
|
|
9700
9731
|
_resolveStoragePromise?.();
|
|
9701
9732
|
notifyStorageStatus();
|
|
9702
9733
|
eventHub.storageDidLoad.notify();
|
|
9703
9734
|
}
|
|
9704
9735
|
async function streamStorage() {
|
|
9705
9736
|
if (!managedSocket.authValue) return;
|
|
9706
|
-
const
|
|
9707
|
-
processInitialStorage(
|
|
9737
|
+
const items = await httpClient.streamStorage({ roomId });
|
|
9738
|
+
processInitialStorage({ type: ServerMsgCode.STORAGE_STATE, items });
|
|
9708
9739
|
}
|
|
9709
9740
|
function refreshStorage(options2) {
|
|
9710
9741
|
const messages = context.buffer.messages;
|
|
@@ -9712,7 +9743,6 @@ function createRoom(options, config) {
|
|
|
9712
9743
|
void streamStorage();
|
|
9713
9744
|
} else if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
9714
9745
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
9715
|
-
partialNodes.clear();
|
|
9716
9746
|
}
|
|
9717
9747
|
if (options2.flush) {
|
|
9718
9748
|
flushNowOrSoon();
|
|
@@ -9761,27 +9791,80 @@ function createRoom(options, config) {
|
|
|
9761
9791
|
}
|
|
9762
9792
|
flushNowOrSoon();
|
|
9763
9793
|
}
|
|
9794
|
+
async function fetchAgentSessions(options2) {
|
|
9795
|
+
const requestId = JSON.stringify({
|
|
9796
|
+
cursor: options2?.cursor,
|
|
9797
|
+
since: options2?.since,
|
|
9798
|
+
limit: options2?.limit,
|
|
9799
|
+
metadata: options2?.metadata
|
|
9800
|
+
});
|
|
9801
|
+
const { promise, resolve, reject } = Promise_withResolvers();
|
|
9802
|
+
pendingAgentSessionsRequests.set(requestId, { resolve, reject });
|
|
9803
|
+
const message = {
|
|
9804
|
+
type: ClientMsgCode.FETCH_AGENT_SESSIONS,
|
|
9805
|
+
cursor: options2?.cursor,
|
|
9806
|
+
since: options2?.since,
|
|
9807
|
+
limit: options2?.limit,
|
|
9808
|
+
metadata: options2?.metadata
|
|
9809
|
+
};
|
|
9810
|
+
context.buffer.messages.push(message);
|
|
9811
|
+
flushNowOrSoon();
|
|
9812
|
+
setTimeout(() => {
|
|
9813
|
+
if (pendingAgentSessionsRequests.has(requestId)) {
|
|
9814
|
+
pendingAgentSessionsRequests.delete(requestId);
|
|
9815
|
+
reject(new Error("Agent sessions fetch timeout"));
|
|
9816
|
+
}
|
|
9817
|
+
}, 3e4);
|
|
9818
|
+
return promise;
|
|
9819
|
+
}
|
|
9820
|
+
async function fetchAgentMessages(sessionId, options2) {
|
|
9821
|
+
const requestId = JSON.stringify({
|
|
9822
|
+
sessionId,
|
|
9823
|
+
cursor: options2?.cursor,
|
|
9824
|
+
since: options2?.since,
|
|
9825
|
+
limit: options2?.limit
|
|
9826
|
+
});
|
|
9827
|
+
const existingRequest = pendingAgentMessagesRequests.get(requestId);
|
|
9828
|
+
if (existingRequest) {
|
|
9829
|
+
return new Promise((resolve2, reject2) => {
|
|
9830
|
+
existingRequest.resolve = resolve2;
|
|
9831
|
+
existingRequest.reject = reject2;
|
|
9832
|
+
});
|
|
9833
|
+
}
|
|
9834
|
+
const { promise, resolve, reject } = Promise_withResolvers();
|
|
9835
|
+
pendingAgentMessagesRequests.set(requestId, { resolve, reject });
|
|
9836
|
+
const message = {
|
|
9837
|
+
type: ClientMsgCode.FETCH_AGENT_MESSAGES,
|
|
9838
|
+
sessionId,
|
|
9839
|
+
cursor: options2?.cursor,
|
|
9840
|
+
since: options2?.since,
|
|
9841
|
+
limit: options2?.limit
|
|
9842
|
+
};
|
|
9843
|
+
context.buffer.messages.push(message);
|
|
9844
|
+
flushNowOrSoon();
|
|
9845
|
+
setTimeout(() => {
|
|
9846
|
+
if (pendingAgentMessagesRequests.has(requestId)) {
|
|
9847
|
+
pendingAgentMessagesRequests.delete(requestId);
|
|
9848
|
+
reject(new Error("Agent messages fetch timeout"));
|
|
9849
|
+
}
|
|
9850
|
+
}, 3e4);
|
|
9851
|
+
return promise;
|
|
9852
|
+
}
|
|
9764
9853
|
function undo() {
|
|
9765
9854
|
if (context.activeBatch) {
|
|
9766
9855
|
throw new Error("undo is not allowed during a batch");
|
|
9767
9856
|
}
|
|
9768
|
-
const
|
|
9769
|
-
if (
|
|
9857
|
+
const frames = context.undoStack.pop();
|
|
9858
|
+
if (frames === void 0) {
|
|
9770
9859
|
return;
|
|
9771
9860
|
}
|
|
9772
9861
|
context.pausedHistory = null;
|
|
9773
|
-
const result =
|
|
9774
|
-
historyOps,
|
|
9775
|
-
/* isLocal */
|
|
9776
|
-
true
|
|
9777
|
-
);
|
|
9862
|
+
const result = applyLocalOps(frames);
|
|
9778
9863
|
notify(result.updates);
|
|
9779
9864
|
context.redoStack.push(result.reverse);
|
|
9780
9865
|
onHistoryChange();
|
|
9781
|
-
for (const op of result.
|
|
9782
|
-
|
|
9783
|
-
context.buffer.storageOperations.push(op);
|
|
9784
|
-
}
|
|
9866
|
+
for (const op of result.opsToEmit) {
|
|
9867
|
+
context.buffer.storageOperations.push(op);
|
|
9785
9868
|
}
|
|
9786
9869
|
flushNowOrSoon();
|
|
9787
9870
|
}
|
|
@@ -9789,23 +9872,17 @@ function createRoom(options, config) {
|
|
|
9789
9872
|
if (context.activeBatch) {
|
|
9790
9873
|
throw new Error("redo is not allowed during a batch");
|
|
9791
9874
|
}
|
|
9792
|
-
const
|
|
9793
|
-
if (
|
|
9875
|
+
const frames = context.redoStack.pop();
|
|
9876
|
+
if (frames === void 0) {
|
|
9794
9877
|
return;
|
|
9795
9878
|
}
|
|
9796
9879
|
context.pausedHistory = null;
|
|
9797
|
-
const result =
|
|
9798
|
-
historyOps,
|
|
9799
|
-
/* isLocal */
|
|
9800
|
-
true
|
|
9801
|
-
);
|
|
9880
|
+
const result = applyLocalOps(frames);
|
|
9802
9881
|
notify(result.updates);
|
|
9803
9882
|
context.undoStack.push(result.reverse);
|
|
9804
9883
|
onHistoryChange();
|
|
9805
|
-
for (const op of result.
|
|
9806
|
-
|
|
9807
|
-
context.buffer.storageOperations.push(op);
|
|
9808
|
-
}
|
|
9884
|
+
for (const op of result.opsToEmit) {
|
|
9885
|
+
context.buffer.storageOperations.push(op);
|
|
9809
9886
|
}
|
|
9810
9887
|
flushNowOrSoon();
|
|
9811
9888
|
}
|
|
@@ -9852,10 +9929,10 @@ function createRoom(options, config) {
|
|
|
9852
9929
|
}
|
|
9853
9930
|
}
|
|
9854
9931
|
function resumeHistory() {
|
|
9855
|
-
const
|
|
9932
|
+
const frames = context.pausedHistory;
|
|
9856
9933
|
context.pausedHistory = null;
|
|
9857
|
-
if (
|
|
9858
|
-
_addToRealUndoStack(Array.from(
|
|
9934
|
+
if (frames !== null && frames.length > 0) {
|
|
9935
|
+
_addToRealUndoStack(Array.from(frames));
|
|
9859
9936
|
}
|
|
9860
9937
|
}
|
|
9861
9938
|
const syncSourceForStorage = config.createSyncSource();
|
|
@@ -9915,6 +9992,7 @@ function createRoom(options, config) {
|
|
|
9915
9992
|
storageStatus: eventHub.storageStatus.observable,
|
|
9916
9993
|
ydoc: eventHub.ydoc.observable,
|
|
9917
9994
|
comments: eventHub.comments.observable,
|
|
9995
|
+
agentSessions: eventHub.agentSessions.observable,
|
|
9918
9996
|
roomWillDestroy: eventHub.roomWillDestroy.observable
|
|
9919
9997
|
};
|
|
9920
9998
|
async function getThreadsSince(options2) {
|
|
@@ -9941,6 +10019,7 @@ function createRoom(options, config) {
|
|
|
9941
10019
|
commentId: options2.commentId,
|
|
9942
10020
|
metadata: options2.metadata,
|
|
9943
10021
|
body: options2.body,
|
|
10022
|
+
commentMetadata: options2.commentMetadata,
|
|
9944
10023
|
attachmentIds: options2.attachmentIds
|
|
9945
10024
|
});
|
|
9946
10025
|
}
|
|
@@ -9953,6 +10032,18 @@ function createRoom(options, config) {
|
|
|
9953
10032
|
}) {
|
|
9954
10033
|
return httpClient.editThreadMetadata({ roomId, threadId, metadata });
|
|
9955
10034
|
}
|
|
10035
|
+
async function editCommentMetadata({
|
|
10036
|
+
threadId,
|
|
10037
|
+
commentId,
|
|
10038
|
+
metadata
|
|
10039
|
+
}) {
|
|
10040
|
+
return httpClient.editCommentMetadata({
|
|
10041
|
+
roomId,
|
|
10042
|
+
threadId,
|
|
10043
|
+
commentId,
|
|
10044
|
+
metadata
|
|
10045
|
+
});
|
|
10046
|
+
}
|
|
9956
10047
|
async function markThreadAsResolved(threadId) {
|
|
9957
10048
|
return httpClient.markThreadAsResolved({ roomId, threadId });
|
|
9958
10049
|
}
|
|
@@ -9974,6 +10065,7 @@ function createRoom(options, config) {
|
|
|
9974
10065
|
threadId: options2.threadId,
|
|
9975
10066
|
commentId: options2.commentId,
|
|
9976
10067
|
body: options2.body,
|
|
10068
|
+
metadata: options2.metadata,
|
|
9977
10069
|
attachmentIds: options2.attachmentIds
|
|
9978
10070
|
});
|
|
9979
10071
|
}
|
|
@@ -9983,6 +10075,7 @@ function createRoom(options, config) {
|
|
|
9983
10075
|
threadId: options2.threadId,
|
|
9984
10076
|
commentId: options2.commentId,
|
|
9985
10077
|
body: options2.body,
|
|
10078
|
+
metadata: options2.metadata,
|
|
9986
10079
|
attachmentIds: options2.attachmentIds
|
|
9987
10080
|
});
|
|
9988
10081
|
}
|
|
@@ -10108,7 +10201,7 @@ function createRoom(options, config) {
|
|
|
10108
10201
|
id: roomId,
|
|
10109
10202
|
subscribe: makeClassicSubscribeFn(
|
|
10110
10203
|
roomId,
|
|
10111
|
-
|
|
10204
|
+
eventHub,
|
|
10112
10205
|
config.errorEventSource
|
|
10113
10206
|
),
|
|
10114
10207
|
connect: () => managedSocket.connect(),
|
|
@@ -10143,6 +10236,8 @@ function createRoom(options, config) {
|
|
|
10143
10236
|
resume: resumeHistory
|
|
10144
10237
|
},
|
|
10145
10238
|
fetchYDoc,
|
|
10239
|
+
fetchAgentSessions,
|
|
10240
|
+
fetchAgentMessages,
|
|
10146
10241
|
getStorage,
|
|
10147
10242
|
getStorageSnapshot,
|
|
10148
10243
|
getStorageStatus,
|
|
@@ -10170,6 +10265,7 @@ function createRoom(options, config) {
|
|
|
10170
10265
|
unsubscribeFromThread,
|
|
10171
10266
|
createComment,
|
|
10172
10267
|
editComment,
|
|
10268
|
+
editCommentMetadata,
|
|
10173
10269
|
deleteComment,
|
|
10174
10270
|
addReaction,
|
|
10175
10271
|
removeReaction,
|
|
@@ -10302,7 +10398,7 @@ function makeCreateSocketDelegateForRoom(roomId, baseUrl, WebSocketPolyfill, eng
|
|
|
10302
10398
|
}
|
|
10303
10399
|
const url2 = new URL(baseUrl);
|
|
10304
10400
|
url2.protocol = url2.protocol === "http:" ? "ws" : "wss";
|
|
10305
|
-
url2.pathname = "/
|
|
10401
|
+
url2.pathname = "/v7";
|
|
10306
10402
|
url2.searchParams.set("roomId", roomId);
|
|
10307
10403
|
if (authValue.type === "secret") {
|
|
10308
10404
|
url2.searchParams.set("tok", authValue.token.raw);
|
|
@@ -11094,9 +11190,9 @@ function lsonToJson(value) {
|
|
|
11094
11190
|
}
|
|
11095
11191
|
return value;
|
|
11096
11192
|
}
|
|
11097
|
-
function
|
|
11193
|
+
function _deepLiveify(value) {
|
|
11098
11194
|
if (Array.isArray(value)) {
|
|
11099
|
-
return new LiveList(value.map(
|
|
11195
|
+
return new LiveList(value.map(_deepLiveify));
|
|
11100
11196
|
} else if (isPlainObject(value)) {
|
|
11101
11197
|
const init = {};
|
|
11102
11198
|
for (const key in value) {
|
|
@@ -11104,7 +11200,7 @@ function deepLiveify(value) {
|
|
|
11104
11200
|
if (val === void 0) {
|
|
11105
11201
|
continue;
|
|
11106
11202
|
}
|
|
11107
|
-
init[key] =
|
|
11203
|
+
init[key] = _deepLiveify(val);
|
|
11108
11204
|
}
|
|
11109
11205
|
return new LiveObject(init);
|
|
11110
11206
|
} else {
|
|
@@ -11141,7 +11237,7 @@ function patchLiveList(liveList, prev, next) {
|
|
|
11141
11237
|
if (i > prevEnd) {
|
|
11142
11238
|
if (i <= nextEnd) {
|
|
11143
11239
|
while (i <= nextEnd) {
|
|
11144
|
-
liveList.insert(
|
|
11240
|
+
liveList.insert(_deepLiveify(next[i]), i);
|
|
11145
11241
|
i++;
|
|
11146
11242
|
}
|
|
11147
11243
|
}
|
|
@@ -11159,12 +11255,12 @@ function patchLiveList(liveList, prev, next) {
|
|
|
11159
11255
|
if (isLiveObject(liveListNode) && isPlainObject(prevNode) && isPlainObject(nextNode)) {
|
|
11160
11256
|
patchLiveObject(liveListNode, prevNode, nextNode);
|
|
11161
11257
|
} else {
|
|
11162
|
-
liveList.set(i,
|
|
11258
|
+
liveList.set(i, _deepLiveify(nextNode));
|
|
11163
11259
|
}
|
|
11164
11260
|
i++;
|
|
11165
11261
|
}
|
|
11166
11262
|
while (i <= nextEnd) {
|
|
11167
|
-
liveList.insert(
|
|
11263
|
+
liveList.insert(_deepLiveify(next[i]), i);
|
|
11168
11264
|
i++;
|
|
11169
11265
|
}
|
|
11170
11266
|
let localI = i;
|
|
@@ -11191,7 +11287,7 @@ Only serializable value can be synced with Liveblocks.`
|
|
|
11191
11287
|
if (next === void 0) {
|
|
11192
11288
|
liveObject.delete(key);
|
|
11193
11289
|
} else if (value === void 0) {
|
|
11194
|
-
liveObject.set(key,
|
|
11290
|
+
liveObject.set(key, _deepLiveify(next));
|
|
11195
11291
|
} else if (prev === next) {
|
|
11196
11292
|
return;
|
|
11197
11293
|
} else if (isLiveList(value) && Array.isArray(prev) && Array.isArray(next)) {
|
|
@@ -11199,7 +11295,7 @@ Only serializable value can be synced with Liveblocks.`
|
|
|
11199
11295
|
} else if (isLiveObject(value) && isPlainObject(prev) && isPlainObject(next)) {
|
|
11200
11296
|
patchLiveObject(value, prev, next);
|
|
11201
11297
|
} else {
|
|
11202
|
-
liveObject.set(key,
|
|
11298
|
+
liveObject.set(key, _deepLiveify(next));
|
|
11203
11299
|
}
|
|
11204
11300
|
}
|
|
11205
11301
|
function patchLiveObject(root, prev, next) {
|
|
@@ -11500,6 +11596,90 @@ function makePoller(callback, intervalMs, options) {
|
|
|
11500
11596
|
};
|
|
11501
11597
|
}
|
|
11502
11598
|
|
|
11599
|
+
// src/mutations.ts
|
|
11600
|
+
function generateOpsFromJson(nodes, mutation, actorId = 1) {
|
|
11601
|
+
const capturedOps = [];
|
|
11602
|
+
const pool = createManagedPool("mutation-temp", {
|
|
11603
|
+
getCurrentConnectionId: () => actorId,
|
|
11604
|
+
onDispatch: (ops) => {
|
|
11605
|
+
capturedOps.push(...ops);
|
|
11606
|
+
}
|
|
11607
|
+
});
|
|
11608
|
+
const root = LiveObject._fromItems(nodes, pool);
|
|
11609
|
+
if (isPlainObject(mutation)) {
|
|
11610
|
+
applyMutationToLiveObject(root, mutation);
|
|
11611
|
+
} else {
|
|
11612
|
+
throw new Error(
|
|
11613
|
+
"Root mutation must be an object. Use a nested key to update specific values."
|
|
11614
|
+
);
|
|
11615
|
+
}
|
|
11616
|
+
return capturedOps;
|
|
11617
|
+
}
|
|
11618
|
+
function applyMutationToLiveObject(target, mutation) {
|
|
11619
|
+
for (const key in mutation) {
|
|
11620
|
+
const mutationValue = mutation[key];
|
|
11621
|
+
if (mutationValue === void 0) {
|
|
11622
|
+
continue;
|
|
11623
|
+
}
|
|
11624
|
+
const existingValue = target.get(key);
|
|
11625
|
+
if (isLiveNode(mutationValue)) {
|
|
11626
|
+
target.set(key, mutationValue);
|
|
11627
|
+
continue;
|
|
11628
|
+
}
|
|
11629
|
+
if (isLiveObject(existingValue) && isPlainObject(mutationValue)) {
|
|
11630
|
+
applyMutationToLiveObject(
|
|
11631
|
+
existingValue,
|
|
11632
|
+
mutationValue
|
|
11633
|
+
);
|
|
11634
|
+
} else if (isLiveMap(existingValue) && isPlainObject(mutationValue)) {
|
|
11635
|
+
applyMutationToLiveMap(existingValue, mutationValue);
|
|
11636
|
+
} else if (isLiveList(existingValue) && Array.isArray(mutationValue)) {
|
|
11637
|
+
applyMutationToLiveList(existingValue, mutationValue);
|
|
11638
|
+
} else if (existingValue === void 0 && isPlainObject(mutationValue)) {
|
|
11639
|
+
const convertedValue = _deepLiveify(mutationValue);
|
|
11640
|
+
target.set(key, convertedValue);
|
|
11641
|
+
} else {
|
|
11642
|
+
target.set(key, mutationValue);
|
|
11643
|
+
}
|
|
11644
|
+
}
|
|
11645
|
+
}
|
|
11646
|
+
function applyMutationToLiveMap(target, mutation) {
|
|
11647
|
+
for (const key in mutation) {
|
|
11648
|
+
const mutationValue = mutation[key];
|
|
11649
|
+
if (mutationValue === void 0) {
|
|
11650
|
+
continue;
|
|
11651
|
+
}
|
|
11652
|
+
const existingValue = target.get(key);
|
|
11653
|
+
if (isLiveNode(mutationValue)) {
|
|
11654
|
+
target.set(key, mutationValue);
|
|
11655
|
+
continue;
|
|
11656
|
+
}
|
|
11657
|
+
if (isLiveObject(existingValue) && isPlainObject(mutationValue)) {
|
|
11658
|
+
applyMutationToLiveObject(
|
|
11659
|
+
existingValue,
|
|
11660
|
+
mutationValue
|
|
11661
|
+
);
|
|
11662
|
+
} else if (isLiveMap(existingValue) && isPlainObject(mutationValue)) {
|
|
11663
|
+
applyMutationToLiveMap(existingValue, mutationValue);
|
|
11664
|
+
} else if (isLiveList(existingValue) && Array.isArray(mutationValue)) {
|
|
11665
|
+
applyMutationToLiveList(existingValue, mutationValue);
|
|
11666
|
+
} else if (existingValue === void 0 && isPlainObject(mutationValue)) {
|
|
11667
|
+
const convertedValue = _deepLiveify(mutationValue);
|
|
11668
|
+
target.set(key, convertedValue);
|
|
11669
|
+
} else {
|
|
11670
|
+
const newValue = isLiveNode(mutationValue) ? mutationValue : mutationValue;
|
|
11671
|
+
target.set(key, newValue);
|
|
11672
|
+
}
|
|
11673
|
+
}
|
|
11674
|
+
}
|
|
11675
|
+
function applyMutationToLiveList(target, mutation) {
|
|
11676
|
+
target.clear();
|
|
11677
|
+
for (const item of mutation) {
|
|
11678
|
+
const liveItem = isLiveNode(item) ? item : item;
|
|
11679
|
+
target.push(liveItem);
|
|
11680
|
+
}
|
|
11681
|
+
}
|
|
11682
|
+
|
|
11503
11683
|
// src/protocol/Subscriptions.ts
|
|
11504
11684
|
function getSubscriptionKey(subscription, subjectId) {
|
|
11505
11685
|
if (typeof subscription === "string") {
|
|
@@ -11572,6 +11752,7 @@ export {
|
|
|
11572
11752
|
errorIf,
|
|
11573
11753
|
findLastIndex,
|
|
11574
11754
|
freeze,
|
|
11755
|
+
generateOpsFromJson,
|
|
11575
11756
|
generateUrl,
|
|
11576
11757
|
getMentionsFromCommentBody,
|
|
11577
11758
|
getSubscriptionKey,
|
|
@@ -11601,7 +11782,6 @@ export {
|
|
|
11601
11782
|
memoizeOnSuccess,
|
|
11602
11783
|
nanoid,
|
|
11603
11784
|
nn,
|
|
11604
|
-
nodeStreamToCompactNodes,
|
|
11605
11785
|
objectToQuery,
|
|
11606
11786
|
patchLiveObjectKey,
|
|
11607
11787
|
patchNotificationSettings,
|