@liveblocks/server 1.3.0 → 1.4.1
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 +37 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +37 -31
- package/dist/index.js.map +1 -1
- package/package.json +9 -12
package/dist/index.cjs
CHANGED
|
@@ -476,6 +476,7 @@ function* iterJson(key, data, parent, state) {
|
|
|
476
476
|
case "LiveMap":
|
|
477
477
|
yield* iterMap(key, data.data, parent, state);
|
|
478
478
|
return;
|
|
479
|
+
// istanbul ignore next
|
|
479
480
|
default:
|
|
480
481
|
_core.assertNever.call(void 0, data, "Unknown `liveblocksType` field");
|
|
481
482
|
}
|
|
@@ -560,7 +561,7 @@ function buildNode2(snapshot2, id) {
|
|
|
560
561
|
} else if (node.type === _core.CrdtType.MAP) {
|
|
561
562
|
return buildMap2(snapshot2, id);
|
|
562
563
|
} else {
|
|
563
|
-
return node.data;
|
|
564
|
+
return _nullishCoalesce(node.data, () => ( null));
|
|
564
565
|
}
|
|
565
566
|
}
|
|
566
567
|
function buildObject2(snapshot2, id, staticData) {
|
|
@@ -604,7 +605,7 @@ function* emit2(snapshot2, id) {
|
|
|
604
605
|
} else if (node.type === _core.CrdtType.MAP) {
|
|
605
606
|
yield* emitMap2(snapshot2, id);
|
|
606
607
|
} else if (node.type === _core.CrdtType.REGISTER) {
|
|
607
|
-
yield JSON.stringify(node.data);
|
|
608
|
+
yield JSON.stringify(_nullishCoalesce(node.data, () => ( null)));
|
|
608
609
|
}
|
|
609
610
|
}
|
|
610
611
|
function* emitObject2(snapshot2, id, staticJson) {
|
|
@@ -940,12 +941,10 @@ var Logger = class _Logger {
|
|
|
940
941
|
}
|
|
941
942
|
});
|
|
942
943
|
this.o = {
|
|
943
|
-
/* eslint-disable @typescript-eslint/no-unsafe-enum-comparison */
|
|
944
944
|
debug: minLevel <= 0 /* DEBUG */ ? makeLogFn(0 /* DEBUG */) : void 0,
|
|
945
945
|
info: minLevel <= 1 /* INFO */ ? makeLogFn(1 /* INFO */) : void 0,
|
|
946
946
|
warn: minLevel <= 2 /* WARNING */ ? makeLogFn(2 /* WARNING */) : void 0,
|
|
947
947
|
error: minLevel <= 3 /* ERROR */ ? makeLogFn(3 /* ERROR */) : void 0
|
|
948
|
-
/* eslint-enable @typescript-eslint/no-unsafe-enum-comparison */
|
|
949
948
|
};
|
|
950
949
|
this.debug = _nullishCoalesce(this.o.debug, () => ( noop));
|
|
951
950
|
this.info = _nullishCoalesce(this.o.info, () => ( noop));
|
|
@@ -1494,6 +1493,7 @@ function nodeFromCreateChildOp(op2) {
|
|
|
1494
1493
|
parentKey: op2.parentKey,
|
|
1495
1494
|
data: op2.data
|
|
1496
1495
|
};
|
|
1496
|
+
// istanbul ignore next
|
|
1497
1497
|
default:
|
|
1498
1498
|
return _core.assertNever.call(void 0, op2, "Unknown op code");
|
|
1499
1499
|
}
|
|
@@ -1562,6 +1562,7 @@ var Storage = class {
|
|
|
1562
1562
|
return await this.applyDeleteObjectKeyOp(op2);
|
|
1563
1563
|
case _core.OpCode.DELETE_CRDT:
|
|
1564
1564
|
return await this.applyDeleteCrdtOp(op2);
|
|
1565
|
+
// istanbul ignore next
|
|
1565
1566
|
default:
|
|
1566
1567
|
if (process.env.NODE_ENV === "production") {
|
|
1567
1568
|
return ignore(op2);
|
|
@@ -1584,6 +1585,7 @@ var Storage = class {
|
|
|
1584
1585
|
if (op2.type === _core.OpCode.CREATE_REGISTER) {
|
|
1585
1586
|
return ignore(op2);
|
|
1586
1587
|
}
|
|
1588
|
+
// fall through
|
|
1587
1589
|
case _core.CrdtType.MAP:
|
|
1588
1590
|
await this.loadedDriver.set_child(op2.id, node, true);
|
|
1589
1591
|
return accept(op2);
|
|
@@ -1591,6 +1593,7 @@ var Storage = class {
|
|
|
1591
1593
|
return this.createChildAsListItem(op2, node);
|
|
1592
1594
|
case _core.CrdtType.REGISTER:
|
|
1593
1595
|
return ignore(op2);
|
|
1596
|
+
// istanbul ignore next
|
|
1594
1597
|
default:
|
|
1595
1598
|
return _core.assertNever.call(void 0, parent, "Unhandled CRDT type");
|
|
1596
1599
|
}
|
|
@@ -1731,6 +1734,7 @@ var _jsbase64 = require('js-base64');
|
|
|
1731
1734
|
|
|
1732
1735
|
var _yjs = require('yjs'); var Y = _interopRequireWildcard(_yjs);
|
|
1733
1736
|
var UPDATE_COUNT_THRESHOLD = 1e3;
|
|
1737
|
+
var MERGE_SHRINK_THRESHOLD = 0.8;
|
|
1734
1738
|
var YjsStorage = class {
|
|
1735
1739
|
constructor(driver, updateCountThreshold = UPDATE_COUNT_THRESHOLD) {
|
|
1736
1740
|
__publicField(this, "driver");
|
|
@@ -1748,15 +1752,16 @@ var YjsStorage = class {
|
|
|
1748
1752
|
await this.driver.delete_y_updates(docId, storedKeys);
|
|
1749
1753
|
this.storedKeysById.set(docId, [newKey]);
|
|
1750
1754
|
});
|
|
1751
|
-
__publicField(this, "_loadYDocFromDurableStorage", async (doc, docId) => {
|
|
1755
|
+
__publicField(this, "_loadYDocFromDurableStorage", async (_logger, doc, docId) => {
|
|
1752
1756
|
const docUpdates = Object.fromEntries(
|
|
1753
1757
|
await this.driver.iter_y_updates(docId)
|
|
1754
1758
|
);
|
|
1755
1759
|
const updates = Object.values(docUpdates);
|
|
1760
|
+
const beforeSize = updates.reduce((acc, update) => acc + update.length, 0);
|
|
1756
1761
|
const newupdate = Y.mergeUpdates(updates);
|
|
1757
1762
|
const storedKeys = Object.keys(docUpdates);
|
|
1758
1763
|
Y.applyUpdate(doc, newupdate);
|
|
1759
|
-
if (this.
|
|
1764
|
+
if (this.shouldCompactByKeyCount(storedKeys) || this.shouldCompactBySize(beforeSize, newupdate.length)) {
|
|
1760
1765
|
await this._compactYJSUpdates(doc, docId, storedKeys);
|
|
1761
1766
|
} else {
|
|
1762
1767
|
this.storedKeysById.set(docId, storedKeys);
|
|
@@ -1775,8 +1780,8 @@ var YjsStorage = class {
|
|
|
1775
1780
|
// ------------------------------------------------------------------------------------
|
|
1776
1781
|
// Public API
|
|
1777
1782
|
// ------------------------------------------------------------------------------------
|
|
1778
|
-
async getYDoc(docId) {
|
|
1779
|
-
const doc = await this.loadDocByIdIfNotAlreadyLoaded(docId);
|
|
1783
|
+
async getYDoc(logger, docId) {
|
|
1784
|
+
const doc = await this.loadDocByIdIfNotAlreadyLoaded(logger, docId);
|
|
1780
1785
|
return doc;
|
|
1781
1786
|
}
|
|
1782
1787
|
/**
|
|
@@ -1796,7 +1801,7 @@ var YjsStorage = class {
|
|
|
1796
1801
|
return _jsbase64.Base64.fromUint8Array(update);
|
|
1797
1802
|
}
|
|
1798
1803
|
async getYDocUpdateBinary(logger, stateVector = "", guid, isV2 = false) {
|
|
1799
|
-
const doc = guid !== void 0 ? await this.getYSubdoc(guid) : this.doc;
|
|
1804
|
+
const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
|
|
1800
1805
|
if (!doc) {
|
|
1801
1806
|
return null;
|
|
1802
1807
|
}
|
|
@@ -1813,15 +1818,15 @@ var YjsStorage = class {
|
|
|
1813
1818
|
}
|
|
1814
1819
|
return Y.encodeStateAsUpdate(doc, encodedTargetVector);
|
|
1815
1820
|
}
|
|
1816
|
-
async getYStateVector(guid) {
|
|
1817
|
-
const doc = guid !== void 0 ? await this.getYSubdoc(guid) : this.doc;
|
|
1821
|
+
async getYStateVector(logger, guid) {
|
|
1822
|
+
const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
|
|
1818
1823
|
if (!doc) {
|
|
1819
1824
|
return null;
|
|
1820
1825
|
}
|
|
1821
1826
|
return _jsbase64.Base64.fromUint8Array(Y.encodeStateVector(doc));
|
|
1822
1827
|
}
|
|
1823
|
-
async getSnapshotHash(options) {
|
|
1824
|
-
const doc = options.guid !== void 0 ? await this.getYSubdoc(options.guid) : this.doc;
|
|
1828
|
+
async getSnapshotHash(logger, options) {
|
|
1829
|
+
const doc = options.guid !== void 0 ? await this.getYSubdoc(logger, options.guid) : this.doc;
|
|
1825
1830
|
if (!doc) {
|
|
1826
1831
|
return null;
|
|
1827
1832
|
}
|
|
@@ -1835,7 +1840,7 @@ var YjsStorage = class {
|
|
|
1835
1840
|
* snapshotHash: the hash of the new snapshot
|
|
1836
1841
|
*/
|
|
1837
1842
|
async addYDocUpdate(logger, update, guid, isV2) {
|
|
1838
|
-
const doc = guid !== void 0 ? await this.getYSubdoc(guid) : this.doc;
|
|
1843
|
+
const doc = guid !== void 0 ? await this.getYSubdoc(logger, guid) : this.doc;
|
|
1839
1844
|
if (!doc) {
|
|
1840
1845
|
throw new Error(`YDoc with guid ${guid} not found`);
|
|
1841
1846
|
}
|
|
@@ -1860,20 +1865,20 @@ var YjsStorage = class {
|
|
|
1860
1865
|
);
|
|
1861
1866
|
}
|
|
1862
1867
|
}
|
|
1863
|
-
loadDocByIdIfNotAlreadyLoaded(docId) {
|
|
1868
|
+
loadDocByIdIfNotAlreadyLoaded(logger, docId) {
|
|
1864
1869
|
let loaded$ = this.initPromisesById.get(docId);
|
|
1865
1870
|
let doc = docId === ROOT_YDOC_ID ? this.doc : this.findYSubdocByGuid(docId);
|
|
1866
1871
|
if (!doc) {
|
|
1867
1872
|
doc = new Y.Doc();
|
|
1868
1873
|
}
|
|
1869
1874
|
if (loaded$ === void 0) {
|
|
1870
|
-
loaded$ = this._loadYDocFromDurableStorage(doc, docId);
|
|
1875
|
+
loaded$ = this._loadYDocFromDurableStorage(logger, doc, docId);
|
|
1871
1876
|
this.initPromisesById.set(docId, loaded$);
|
|
1872
1877
|
}
|
|
1873
1878
|
return loaded$;
|
|
1874
1879
|
}
|
|
1875
|
-
async load(
|
|
1876
|
-
await this.loadDocByIdIfNotAlreadyLoaded(ROOT_YDOC_ID);
|
|
1880
|
+
async load(logger) {
|
|
1881
|
+
await this.loadDocByIdIfNotAlreadyLoaded(logger, ROOT_YDOC_ID);
|
|
1877
1882
|
}
|
|
1878
1883
|
/**
|
|
1879
1884
|
* Unloads the Yjs documents from memory.
|
|
@@ -1916,12 +1921,12 @@ var YjsStorage = class {
|
|
|
1916
1921
|
);
|
|
1917
1922
|
}
|
|
1918
1923
|
// gets a subdoc, it will be loaded if not already loaded
|
|
1919
|
-
async getYSubdoc(guid) {
|
|
1924
|
+
async getYSubdoc(logger, guid) {
|
|
1920
1925
|
const subdoc = this.findYSubdocByGuid(guid);
|
|
1921
1926
|
if (!subdoc) {
|
|
1922
1927
|
return null;
|
|
1923
1928
|
}
|
|
1924
|
-
await this.loadDocByIdIfNotAlreadyLoaded(guid);
|
|
1929
|
+
await this.loadDocByIdIfNotAlreadyLoaded(logger, guid);
|
|
1925
1930
|
return subdoc;
|
|
1926
1931
|
}
|
|
1927
1932
|
// When the YJS doc changes, update it in durable storage
|
|
@@ -1929,7 +1934,7 @@ var YjsStorage = class {
|
|
|
1929
1934
|
const v1update = isV2 ? Y.convertUpdateFormatV2ToV1(update) : update;
|
|
1930
1935
|
const docId = doc.guid === this.doc.guid ? ROOT_YDOC_ID : doc.guid;
|
|
1931
1936
|
const storedKeys = this.storedKeysById.get(docId);
|
|
1932
|
-
if (this.
|
|
1937
|
+
if (this.shouldCompactByKeyCount(storedKeys)) {
|
|
1933
1938
|
await this._compactYJSUpdates(doc, docId, storedKeys || []);
|
|
1934
1939
|
return;
|
|
1935
1940
|
}
|
|
@@ -1941,7 +1946,10 @@ var YjsStorage = class {
|
|
|
1941
1946
|
storedKeys.push(newKey);
|
|
1942
1947
|
}
|
|
1943
1948
|
}
|
|
1944
|
-
|
|
1949
|
+
shouldCompactBySize(beforeSize, afterSize) {
|
|
1950
|
+
return beforeSize * MERGE_SHRINK_THRESHOLD > afterSize;
|
|
1951
|
+
}
|
|
1952
|
+
shouldCompactByKeyCount(storedKeys) {
|
|
1945
1953
|
if (!storedKeys) {
|
|
1946
1954
|
return false;
|
|
1947
1955
|
}
|
|
@@ -2905,7 +2913,6 @@ var Room = class {
|
|
|
2905
2913
|
* @internal
|
|
2906
2914
|
* Handles an incoming ping, by sending a pong back.
|
|
2907
2915
|
*/
|
|
2908
|
-
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2909
2916
|
async handlePing(sessionKey, ctx) {
|
|
2910
2917
|
const session = this.sessions.get(sessionKey);
|
|
2911
2918
|
if (session === void 0) {
|
|
@@ -3064,6 +3071,7 @@ var Room = class {
|
|
|
3064
3071
|
return r.ignoredOpId !== void 0 ? [ackIgnoredOp(r.ignoredOpId)] : [];
|
|
3065
3072
|
case "accepted":
|
|
3066
3073
|
return r.fix !== void 0 ? [r.fix] : [];
|
|
3074
|
+
// istanbul ignore next
|
|
3067
3075
|
default:
|
|
3068
3076
|
return _core.assertNever.call(void 0, r, "Unhandled case");
|
|
3069
3077
|
}
|
|
@@ -3096,8 +3104,8 @@ var Room = class {
|
|
|
3096
3104
|
const isV2 = msg.v2;
|
|
3097
3105
|
const [update, stateVector, snapshotHash] = await Promise.all([
|
|
3098
3106
|
this.yjsStorage.getYDocUpdate(this.logger, vector, guid, isV2),
|
|
3099
|
-
this.yjsStorage.getYStateVector(guid),
|
|
3100
|
-
this.yjsStorage.getSnapshotHash({ guid, isV2 })
|
|
3107
|
+
this.yjsStorage.getYStateVector(this.logger, guid),
|
|
3108
|
+
this.yjsStorage.getSnapshotHash(this.logger, { guid, isV2 })
|
|
3101
3109
|
]);
|
|
3102
3110
|
if (update !== null && snapshotHash !== null) {
|
|
3103
3111
|
replyImmediately({
|
|
@@ -3141,6 +3149,7 @@ var Room = class {
|
|
|
3141
3149
|
}
|
|
3142
3150
|
break;
|
|
3143
3151
|
}
|
|
3152
|
+
// Feed messages
|
|
3144
3153
|
case FeedMsgCode.FETCH_FEEDS: {
|
|
3145
3154
|
const fetchMsg = msg;
|
|
3146
3155
|
const [result, err] = await tryCatch(
|
|
@@ -3190,8 +3199,7 @@ var Room = class {
|
|
|
3190
3199
|
const [feed, err] = await tryCatch(
|
|
3191
3200
|
this.createFeed({
|
|
3192
3201
|
feedId: addMsg.feedId,
|
|
3193
|
-
metadata: _nullishCoalesce(addMsg.metadata, () => ( {}))
|
|
3194
|
-
timestamp: addMsg.timestamp
|
|
3202
|
+
metadata: _nullishCoalesce(addMsg.metadata, () => ( {}))
|
|
3195
3203
|
})
|
|
3196
3204
|
);
|
|
3197
3205
|
if (err) {
|
|
@@ -3253,8 +3261,7 @@ var Room = class {
|
|
|
3253
3261
|
const [message, err] = await tryCatch(
|
|
3254
3262
|
this.addFeedMessage(addMsg.feedId, {
|
|
3255
3263
|
data: addMsg.data,
|
|
3256
|
-
id: addMsg.id
|
|
3257
|
-
timestamp: addMsg.timestamp
|
|
3264
|
+
id: addMsg.id
|
|
3258
3265
|
})
|
|
3259
3266
|
);
|
|
3260
3267
|
if (err) {
|
|
@@ -3276,8 +3283,7 @@ var Room = class {
|
|
|
3276
3283
|
this.updateFeedMessage(
|
|
3277
3284
|
updateMsg.feedId,
|
|
3278
3285
|
updateMsg.messageId,
|
|
3279
|
-
updateMsg.data
|
|
3280
|
-
updateMsg.timestamp
|
|
3286
|
+
updateMsg.data
|
|
3281
3287
|
)
|
|
3282
3288
|
);
|
|
3283
3289
|
if (err) {
|