@liveblocks/core 3.21.0-exp1 → 3.21.0-private1
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 +508 -1645
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -367
- package/dist/index.d.ts +65 -367
- package/dist/index.js +346 -1483
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
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.21.0-
|
|
9
|
+
var PKG_VERSION = "3.21.0-private1";
|
|
10
10
|
var PKG_FORMAT = "cjs";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -1567,6 +1567,15 @@ function isUrl(string) {
|
|
|
1567
1567
|
}
|
|
1568
1568
|
|
|
1569
1569
|
// src/api-client.ts
|
|
1570
|
+
function commentsResourceForVisibility(visibility) {
|
|
1571
|
+
if (visibility === "private") {
|
|
1572
|
+
return "comments:private";
|
|
1573
|
+
}
|
|
1574
|
+
if (visibility === "public") {
|
|
1575
|
+
return "comments:public";
|
|
1576
|
+
}
|
|
1577
|
+
return "comments";
|
|
1578
|
+
}
|
|
1570
1579
|
function createApiClient({
|
|
1571
1580
|
baseUrl,
|
|
1572
1581
|
authManager,
|
|
@@ -1618,7 +1627,7 @@ function createApiClient({
|
|
|
1618
1627
|
url`/v2/c/rooms/${options.roomId}/threads`,
|
|
1619
1628
|
await authManager.getAuthValue({
|
|
1620
1629
|
roomId: options.roomId,
|
|
1621
|
-
resource:
|
|
1630
|
+
resource: commentsResourceForVisibility(_optionalChain([options, 'access', _15 => _15.query, 'optionalAccess', _16 => _16.visibility])),
|
|
1622
1631
|
access: "read"
|
|
1623
1632
|
}),
|
|
1624
1633
|
{
|
|
@@ -1676,7 +1685,7 @@ function createApiClient({
|
|
|
1676
1685
|
hasMentions: options.query.hasMentions
|
|
1677
1686
|
})
|
|
1678
1687
|
},
|
|
1679
|
-
{ signal: _optionalChain([requestOptions, 'optionalAccess',
|
|
1688
|
+
{ signal: _optionalChain([requestOptions, 'optionalAccess', _17 => _17.signal]) }
|
|
1680
1689
|
);
|
|
1681
1690
|
return result;
|
|
1682
1691
|
}
|
|
@@ -1687,11 +1696,12 @@ function createApiClient({
|
|
|
1687
1696
|
url`/v2/c/rooms/${options.roomId}/threads`,
|
|
1688
1697
|
await authManager.getAuthValue({
|
|
1689
1698
|
roomId: options.roomId,
|
|
1690
|
-
resource: "
|
|
1699
|
+
resource: commentsResourceForVisibility(_nullishCoalesce(options.visibility, () => ( "public"))),
|
|
1691
1700
|
access: "write"
|
|
1692
1701
|
}),
|
|
1693
1702
|
{
|
|
1694
1703
|
id: threadId,
|
|
1704
|
+
visibility: options.visibility,
|
|
1695
1705
|
comment: {
|
|
1696
1706
|
id: commentId,
|
|
1697
1707
|
body: options.body,
|
|
@@ -1878,11 +1888,11 @@ function createApiClient({
|
|
|
1878
1888
|
`Upload of attachment ${options.attachment.id} was aborted.`,
|
|
1879
1889
|
"AbortError"
|
|
1880
1890
|
) : void 0;
|
|
1881
|
-
if (_optionalChain([abortSignal, 'optionalAccess',
|
|
1891
|
+
if (_optionalChain([abortSignal, 'optionalAccess', _18 => _18.aborted])) {
|
|
1882
1892
|
throw abortError;
|
|
1883
1893
|
}
|
|
1884
1894
|
const handleRetryError = (err) => {
|
|
1885
|
-
if (_optionalChain([abortSignal, 'optionalAccess',
|
|
1895
|
+
if (_optionalChain([abortSignal, 'optionalAccess', _19 => _19.aborted])) {
|
|
1886
1896
|
throw abortError;
|
|
1887
1897
|
}
|
|
1888
1898
|
if (err instanceof HttpError && err.status === 413) {
|
|
@@ -1956,7 +1966,7 @@ function createApiClient({
|
|
|
1956
1966
|
try {
|
|
1957
1967
|
uploadId = createMultiPartUpload.uploadId;
|
|
1958
1968
|
const parts = splitFileIntoParts(attachment.file);
|
|
1959
|
-
if (_optionalChain([abortSignal, 'optionalAccess',
|
|
1969
|
+
if (_optionalChain([abortSignal, 'optionalAccess', _20 => _20.aborted])) {
|
|
1960
1970
|
throw abortError;
|
|
1961
1971
|
}
|
|
1962
1972
|
const batches = chunk(parts, 5);
|
|
@@ -1984,7 +1994,7 @@ function createApiClient({
|
|
|
1984
1994
|
}
|
|
1985
1995
|
uploadedParts.push(...await Promise.all(uploadedPartsPromises));
|
|
1986
1996
|
}
|
|
1987
|
-
if (_optionalChain([abortSignal, 'optionalAccess',
|
|
1997
|
+
if (_optionalChain([abortSignal, 'optionalAccess', _21 => _21.aborted])) {
|
|
1988
1998
|
throw abortError;
|
|
1989
1999
|
}
|
|
1990
2000
|
const sortedUploadedParts = uploadedParts.sort(
|
|
@@ -2001,7 +2011,7 @@ function createApiClient({
|
|
|
2001
2011
|
{ signal: abortSignal }
|
|
2002
2012
|
);
|
|
2003
2013
|
} catch (error3) {
|
|
2004
|
-
if (uploadId && _optionalChain([error3, 'optionalAccess',
|
|
2014
|
+
if (uploadId && _optionalChain([error3, 'optionalAccess', _22 => _22.name]) && (error3.name === "AbortError" || error3.name === "TimeoutError")) {
|
|
2005
2015
|
try {
|
|
2006
2016
|
await httpClient.rawDelete(
|
|
2007
2017
|
url`/v2/c/rooms/${roomId}/attachments/${attachment.id}/multipart/${uploadId}`,
|
|
@@ -2234,14 +2244,14 @@ function createApiClient({
|
|
|
2234
2244
|
async function getInboxNotifications(options) {
|
|
2235
2245
|
const PAGE_SIZE = 50;
|
|
2236
2246
|
let query;
|
|
2237
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
2247
|
+
if (_optionalChain([options, 'optionalAccess', _23 => _23.query])) {
|
|
2238
2248
|
query = objectToQuery(options.query);
|
|
2239
2249
|
}
|
|
2240
2250
|
const json = await httpClient.get(
|
|
2241
2251
|
url`/v2/c/inbox-notifications`,
|
|
2242
2252
|
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2243
2253
|
{
|
|
2244
|
-
cursor: _optionalChain([options, 'optionalAccess',
|
|
2254
|
+
cursor: _optionalChain([options, 'optionalAccess', _24 => _24.cursor]),
|
|
2245
2255
|
limit: PAGE_SIZE,
|
|
2246
2256
|
query
|
|
2247
2257
|
}
|
|
@@ -2260,7 +2270,7 @@ function createApiClient({
|
|
|
2260
2270
|
}
|
|
2261
2271
|
async function getInboxNotificationsSince(options) {
|
|
2262
2272
|
let query;
|
|
2263
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
2273
|
+
if (_optionalChain([options, 'optionalAccess', _25 => _25.query])) {
|
|
2264
2274
|
query = objectToQuery(options.query);
|
|
2265
2275
|
}
|
|
2266
2276
|
const json = await httpClient.get(
|
|
@@ -2289,14 +2299,14 @@ function createApiClient({
|
|
|
2289
2299
|
}
|
|
2290
2300
|
async function getUnreadInboxNotificationsCount(options) {
|
|
2291
2301
|
let query;
|
|
2292
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
2302
|
+
if (_optionalChain([options, 'optionalAccess', _26 => _26.query])) {
|
|
2293
2303
|
query = objectToQuery(options.query);
|
|
2294
2304
|
}
|
|
2295
2305
|
const { count } = await httpClient.get(
|
|
2296
2306
|
url`/v2/c/inbox-notifications/count`,
|
|
2297
2307
|
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2298
2308
|
{ query },
|
|
2299
|
-
{ signal: _optionalChain([options, 'optionalAccess',
|
|
2309
|
+
{ signal: _optionalChain([options, 'optionalAccess', _27 => _27.signal]) }
|
|
2300
2310
|
);
|
|
2301
2311
|
return count;
|
|
2302
2312
|
}
|
|
@@ -2346,7 +2356,7 @@ function createApiClient({
|
|
|
2346
2356
|
url`/v2/c/notification-settings`,
|
|
2347
2357
|
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2348
2358
|
void 0,
|
|
2349
|
-
{ signal: _optionalChain([options, 'optionalAccess',
|
|
2359
|
+
{ signal: _optionalChain([options, 'optionalAccess', _28 => _28.signal]) }
|
|
2350
2360
|
);
|
|
2351
2361
|
}
|
|
2352
2362
|
async function updateNotificationSettings(settings) {
|
|
@@ -2358,7 +2368,7 @@ function createApiClient({
|
|
|
2358
2368
|
}
|
|
2359
2369
|
async function getUserThreads_experimental(options) {
|
|
2360
2370
|
let query;
|
|
2361
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
2371
|
+
if (_optionalChain([options, 'optionalAccess', _29 => _29.query])) {
|
|
2362
2372
|
query = objectToQuery(options.query);
|
|
2363
2373
|
}
|
|
2364
2374
|
const PAGE_SIZE = 50;
|
|
@@ -2366,7 +2376,7 @@ function createApiClient({
|
|
|
2366
2376
|
url`/v2/c/threads`,
|
|
2367
2377
|
await authManager.getAuthValue({ resource: "personal", access: "write" }),
|
|
2368
2378
|
{
|
|
2369
|
-
cursor: _optionalChain([options, 'optionalAccess',
|
|
2379
|
+
cursor: _optionalChain([options, 'optionalAccess', _30 => _30.cursor]),
|
|
2370
2380
|
query,
|
|
2371
2381
|
limit: PAGE_SIZE
|
|
2372
2382
|
}
|
|
@@ -2539,7 +2549,7 @@ var HttpClient = class {
|
|
|
2539
2549
|
// These headers are default, but can be overriden by custom headers
|
|
2540
2550
|
"Content-Type": "application/json; charset=utf-8",
|
|
2541
2551
|
// Possible header overrides
|
|
2542
|
-
..._optionalChain([options, 'optionalAccess',
|
|
2552
|
+
..._optionalChain([options, 'optionalAccess', _31 => _31.headers]),
|
|
2543
2553
|
// Cannot be overriden by custom headers
|
|
2544
2554
|
Authorization: `Bearer ${getBearerTokenFromAuthValue(authValue)}`,
|
|
2545
2555
|
"X-LB-Client": PKG_VERSION || "dev"
|
|
@@ -2547,7 +2557,7 @@ var HttpClient = class {
|
|
|
2547
2557
|
});
|
|
2548
2558
|
const xwarn = response.headers.get("X-LB-Warn");
|
|
2549
2559
|
if (xwarn) {
|
|
2550
|
-
const method = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
2560
|
+
const method = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _32 => _32.method, 'optionalAccess', _33 => _33.toUpperCase, 'call', _34 => _34()]), () => ( "GET"));
|
|
2551
2561
|
const msg = `${xwarn} (${method} ${endpoint})`;
|
|
2552
2562
|
if (response.ok) {
|
|
2553
2563
|
warn(msg);
|
|
@@ -3029,7 +3039,7 @@ var FSM = class {
|
|
|
3029
3039
|
});
|
|
3030
3040
|
}
|
|
3031
3041
|
#getTargetFn(eventName) {
|
|
3032
|
-
return _optionalChain([this, 'access',
|
|
3042
|
+
return _optionalChain([this, 'access', _35 => _35.#allowedTransitions, 'access', _36 => _36.get, 'call', _37 => _37(this.currentState), 'optionalAccess', _38 => _38.get, 'call', _39 => _39(eventName)]);
|
|
3033
3043
|
}
|
|
3034
3044
|
/**
|
|
3035
3045
|
* Exits the current state, and executes any necessary cleanup functions.
|
|
@@ -3048,7 +3058,7 @@ var FSM = class {
|
|
|
3048
3058
|
this.#currentContext.allowPatching((patchableContext) => {
|
|
3049
3059
|
levels = _nullishCoalesce(levels, () => ( this.#cleanupStack.length));
|
|
3050
3060
|
for (let i = 0; i < levels; i++) {
|
|
3051
|
-
_optionalChain([this, 'access',
|
|
3061
|
+
_optionalChain([this, 'access', _40 => _40.#cleanupStack, 'access', _41 => _41.pop, 'call', _42 => _42(), 'optionalCall', _43 => _43(patchableContext)]);
|
|
3052
3062
|
const entryTime = this.#entryTimesStack.pop();
|
|
3053
3063
|
if (entryTime !== void 0 && // ...but avoid computing state names if nobody is listening
|
|
3054
3064
|
this.#eventHub.didExitState.count() > 0) {
|
|
@@ -3076,7 +3086,7 @@ var FSM = class {
|
|
|
3076
3086
|
this.#currentContext.allowPatching((patchableContext) => {
|
|
3077
3087
|
for (const pattern of enterPatterns) {
|
|
3078
3088
|
const enterFn = this.#enterFns.get(pattern);
|
|
3079
|
-
const cleanupFn = _optionalChain([enterFn, 'optionalCall',
|
|
3089
|
+
const cleanupFn = _optionalChain([enterFn, 'optionalCall', _44 => _44(patchableContext)]);
|
|
3080
3090
|
if (typeof cleanupFn === "function") {
|
|
3081
3091
|
this.#cleanupStack.push(cleanupFn);
|
|
3082
3092
|
} else {
|
|
@@ -3503,7 +3513,7 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3503
3513
|
}
|
|
3504
3514
|
function waitForActorId(event) {
|
|
3505
3515
|
const serverMsg = tryParseJson(event.data);
|
|
3506
|
-
if (_optionalChain([serverMsg, 'optionalAccess',
|
|
3516
|
+
if (_optionalChain([serverMsg, 'optionalAccess', _45 => _45.type]) === ServerMsgCode.ROOM_STATE) {
|
|
3507
3517
|
if (options.enableDebugLogging && socketOpenAt !== null) {
|
|
3508
3518
|
const elapsed = performance.now() - socketOpenAt;
|
|
3509
3519
|
warn(
|
|
@@ -3631,12 +3641,12 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3631
3641
|
const sendHeartbeat = {
|
|
3632
3642
|
target: "@ok.awaiting-pong",
|
|
3633
3643
|
effect: (ctx) => {
|
|
3634
|
-
_optionalChain([ctx, 'access',
|
|
3644
|
+
_optionalChain([ctx, 'access', _46 => _46.socket, 'optionalAccess', _47 => _47.send, 'call', _48 => _48("ping")]);
|
|
3635
3645
|
}
|
|
3636
3646
|
};
|
|
3637
3647
|
const maybeHeartbeat = () => {
|
|
3638
3648
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
3639
|
-
const canZombie = _optionalChain([doc, 'optionalAccess',
|
|
3649
|
+
const canZombie = _optionalChain([doc, 'optionalAccess', _49 => _49.visibilityState]) === "hidden" && delegates.canZombie();
|
|
3640
3650
|
return canZombie ? "@idle.zombie" : sendHeartbeat;
|
|
3641
3651
|
};
|
|
3642
3652
|
machine.addTimedTransition("@ok.connected", HEARTBEAT_INTERVAL, maybeHeartbeat).addTransitions("@ok.connected", {
|
|
@@ -3676,7 +3686,7 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3676
3686
|
// socket, or not. So always check to see if the socket is still OPEN or
|
|
3677
3687
|
// not. When still OPEN, don't transition.
|
|
3678
3688
|
EXPLICIT_SOCKET_ERROR: (_, context) => {
|
|
3679
|
-
if (_optionalChain([context, 'access',
|
|
3689
|
+
if (_optionalChain([context, 'access', _50 => _50.socket, 'optionalAccess', _51 => _51.readyState]) === 1) {
|
|
3680
3690
|
return IGNORE;
|
|
3681
3691
|
}
|
|
3682
3692
|
return {
|
|
@@ -3728,17 +3738,17 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3728
3738
|
machine.send({ type: "NAVIGATOR_ONLINE" });
|
|
3729
3739
|
}
|
|
3730
3740
|
function onVisibilityChange() {
|
|
3731
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
3741
|
+
if (_optionalChain([doc, 'optionalAccess', _52 => _52.visibilityState]) === "visible") {
|
|
3732
3742
|
machine.send({ type: "WINDOW_GOT_FOCUS" });
|
|
3733
3743
|
}
|
|
3734
3744
|
}
|
|
3735
|
-
_optionalChain([win, 'optionalAccess',
|
|
3736
|
-
_optionalChain([win, 'optionalAccess',
|
|
3737
|
-
_optionalChain([root, 'optionalAccess',
|
|
3745
|
+
_optionalChain([win, 'optionalAccess', _53 => _53.addEventListener, 'call', _54 => _54("online", onNetworkBackOnline)]);
|
|
3746
|
+
_optionalChain([win, 'optionalAccess', _55 => _55.addEventListener, 'call', _56 => _56("offline", onNetworkOffline)]);
|
|
3747
|
+
_optionalChain([root, 'optionalAccess', _57 => _57.addEventListener, 'call', _58 => _58("visibilitychange", onVisibilityChange)]);
|
|
3738
3748
|
return () => {
|
|
3739
|
-
_optionalChain([root, 'optionalAccess',
|
|
3740
|
-
_optionalChain([win, 'optionalAccess',
|
|
3741
|
-
_optionalChain([win, 'optionalAccess',
|
|
3749
|
+
_optionalChain([root, 'optionalAccess', _59 => _59.removeEventListener, 'call', _60 => _60("visibilitychange", onVisibilityChange)]);
|
|
3750
|
+
_optionalChain([win, 'optionalAccess', _61 => _61.removeEventListener, 'call', _62 => _62("online", onNetworkBackOnline)]);
|
|
3751
|
+
_optionalChain([win, 'optionalAccess', _63 => _63.removeEventListener, 'call', _64 => _64("offline", onNetworkOffline)]);
|
|
3742
3752
|
teardownSocket(ctx.socket);
|
|
3743
3753
|
};
|
|
3744
3754
|
});
|
|
@@ -3827,7 +3837,7 @@ var ManagedSocket = class {
|
|
|
3827
3837
|
* message if this is somehow impossible.
|
|
3828
3838
|
*/
|
|
3829
3839
|
send(data) {
|
|
3830
|
-
const socket = _optionalChain([this, 'access',
|
|
3840
|
+
const socket = _optionalChain([this, 'access', _65 => _65.#machine, 'access', _66 => _66.context, 'optionalAccess', _67 => _67.socket]);
|
|
3831
3841
|
if (socket === null) {
|
|
3832
3842
|
warn("Cannot send: not connected yet", data);
|
|
3833
3843
|
} else if (socket.readyState !== 1) {
|
|
@@ -3847,7 +3857,6 @@ var ManagedSocket = class {
|
|
|
3847
3857
|
|
|
3848
3858
|
// src/internal.ts
|
|
3849
3859
|
var kInternal = /* @__PURE__ */ Symbol();
|
|
3850
|
-
var kStorageUpdateSource = /* @__PURE__ */ Symbol();
|
|
3851
3860
|
|
|
3852
3861
|
// src/lib/IncrementalJsonParser.ts
|
|
3853
3862
|
var EMPTY_OBJECT = Object.freeze({});
|
|
@@ -4290,7 +4299,7 @@ function createStore_forKnowledge() {
|
|
|
4290
4299
|
}
|
|
4291
4300
|
function getKnowledgeForChat(chatId) {
|
|
4292
4301
|
const globalKnowledge = knowledgeByChatId.getOrCreate(kWILDCARD).get();
|
|
4293
|
-
const scopedKnowledge = _nullishCoalesce(_optionalChain([knowledgeByChatId, 'access',
|
|
4302
|
+
const scopedKnowledge = _nullishCoalesce(_optionalChain([knowledgeByChatId, 'access', _68 => _68.get, 'call', _69 => _69(chatId), 'optionalAccess', _70 => _70.get, 'call', _71 => _71()]), () => ( []));
|
|
4294
4303
|
return [...globalKnowledge, ...scopedKnowledge];
|
|
4295
4304
|
}
|
|
4296
4305
|
return {
|
|
@@ -4315,7 +4324,7 @@ function createStore_forTools() {
|
|
|
4315
4324
|
return DerivedSignal.from(() => {
|
|
4316
4325
|
return (
|
|
4317
4326
|
// A tool that's registered and scoped to a specific chat ID...
|
|
4318
|
-
_nullishCoalesce(_optionalChain([(chatId !== void 0 ? toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(name) : void 0), 'optionalAccess',
|
|
4327
|
+
_nullishCoalesce(_optionalChain([(chatId !== void 0 ? toolsByChatId\u03A3.getOrCreate(chatId).getOrCreate(name) : void 0), 'optionalAccess', _72 => _72.get, 'call', _73 => _73()]), () => ( // ...or a globally registered tool
|
|
4319
4328
|
toolsByChatId\u03A3.getOrCreate(kWILDCARD).getOrCreate(name).get()))
|
|
4320
4329
|
);
|
|
4321
4330
|
});
|
|
@@ -4345,8 +4354,8 @@ function createStore_forTools() {
|
|
|
4345
4354
|
const globalTools\u03A3 = toolsByChatId\u03A3.get(kWILDCARD);
|
|
4346
4355
|
const scopedTools\u03A3 = toolsByChatId\u03A3.get(chatId);
|
|
4347
4356
|
return Array.from([
|
|
4348
|
-
..._nullishCoalesce(_optionalChain([globalTools\u03A3, 'optionalAccess',
|
|
4349
|
-
..._nullishCoalesce(_optionalChain([scopedTools\u03A3, 'optionalAccess',
|
|
4357
|
+
..._nullishCoalesce(_optionalChain([globalTools\u03A3, 'optionalAccess', _74 => _74.entries, 'call', _75 => _75()]), () => ( [])),
|
|
4358
|
+
..._nullishCoalesce(_optionalChain([scopedTools\u03A3, 'optionalAccess', _76 => _76.entries, 'call', _77 => _77()]), () => ( []))
|
|
4350
4359
|
]).flatMap(([name, tool\u03A3]) => {
|
|
4351
4360
|
const tool = tool\u03A3.get();
|
|
4352
4361
|
return tool && (_nullishCoalesce(tool.enabled, () => ( true))) ? [{ name, description: tool.description, parameters: tool.parameters }] : [];
|
|
@@ -4449,7 +4458,7 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
|
|
|
4449
4458
|
} else {
|
|
4450
4459
|
continue;
|
|
4451
4460
|
}
|
|
4452
|
-
const executeFn = _optionalChain([toolsStore, 'access',
|
|
4461
|
+
const executeFn = _optionalChain([toolsStore, 'access', _78 => _78.getTool\u03A3, 'call', _79 => _79(toolInvocation.name, message.chatId), 'access', _80 => _80.get, 'call', _81 => _81(), 'optionalAccess', _82 => _82.execute]);
|
|
4453
4462
|
if (executeFn) {
|
|
4454
4463
|
(async () => {
|
|
4455
4464
|
const result = await executeFn(toolInvocation.args, {
|
|
@@ -4548,8 +4557,8 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
|
|
|
4548
4557
|
const spine = [];
|
|
4549
4558
|
let lastVisitedMessage = null;
|
|
4550
4559
|
for (const message2 of pool.walkUp(leaf.id)) {
|
|
4551
|
-
const prev = _nullishCoalesce(_optionalChain([first, 'call',
|
|
4552
|
-
const next = _nullishCoalesce(_optionalChain([first, 'call',
|
|
4560
|
+
const prev = _nullishCoalesce(_optionalChain([first, 'call', _83 => _83(pool.walkLeft(message2.id, isAlive)), 'optionalAccess', _84 => _84.id]), () => ( null));
|
|
4561
|
+
const next = _nullishCoalesce(_optionalChain([first, 'call', _85 => _85(pool.walkRight(message2.id, isAlive)), 'optionalAccess', _86 => _86.id]), () => ( null));
|
|
4553
4562
|
if (!message2.deletedAt || prev || next) {
|
|
4554
4563
|
const node = {
|
|
4555
4564
|
...message2,
|
|
@@ -4615,7 +4624,7 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
|
|
|
4615
4624
|
const latest = pool.sorted.findRight(
|
|
4616
4625
|
(m) => m.role === "assistant" && !m.deletedAt
|
|
4617
4626
|
);
|
|
4618
|
-
return _optionalChain([latest, 'optionalAccess',
|
|
4627
|
+
return _optionalChain([latest, 'optionalAccess', _87 => _87.copilotId]);
|
|
4619
4628
|
}
|
|
4620
4629
|
return {
|
|
4621
4630
|
// Readers
|
|
@@ -4646,11 +4655,11 @@ function createStore_forChatMessages(toolsStore, setToolResultFn) {
|
|
|
4646
4655
|
*getAutoExecutingMessageIds() {
|
|
4647
4656
|
for (const messageId of myMessages) {
|
|
4648
4657
|
const message = getMessageById(messageId);
|
|
4649
|
-
if (_optionalChain([message, 'optionalAccess',
|
|
4658
|
+
if (_optionalChain([message, 'optionalAccess', _88 => _88.role]) === "assistant" && message.status === "awaiting-tool") {
|
|
4650
4659
|
const isAutoExecuting = message.contentSoFar.some((part) => {
|
|
4651
4660
|
if (part.type === "tool-invocation" && part.stage === "executing") {
|
|
4652
4661
|
const tool = toolsStore.getTool\u03A3(part.name, message.chatId).get();
|
|
4653
|
-
return typeof _optionalChain([tool, 'optionalAccess',
|
|
4662
|
+
return typeof _optionalChain([tool, 'optionalAccess', _89 => _89.execute]) === "function";
|
|
4654
4663
|
}
|
|
4655
4664
|
return false;
|
|
4656
4665
|
});
|
|
@@ -4798,7 +4807,7 @@ function createAi(config) {
|
|
|
4798
4807
|
flushPendingDeltas();
|
|
4799
4808
|
switch (msg.event) {
|
|
4800
4809
|
case "cmd-failed":
|
|
4801
|
-
_optionalChain([pendingCmd, 'optionalAccess',
|
|
4810
|
+
_optionalChain([pendingCmd, 'optionalAccess', _90 => _90.reject, 'call', _91 => _91(new Error(msg.error))]);
|
|
4802
4811
|
break;
|
|
4803
4812
|
case "settle": {
|
|
4804
4813
|
context.messagesStore.upsert(msg.message);
|
|
@@ -4875,7 +4884,7 @@ function createAi(config) {
|
|
|
4875
4884
|
return assertNever(msg, "Unhandled case");
|
|
4876
4885
|
}
|
|
4877
4886
|
}
|
|
4878
|
-
_optionalChain([pendingCmd, 'optionalAccess',
|
|
4887
|
+
_optionalChain([pendingCmd, 'optionalAccess', _92 => _92.resolve, 'call', _93 => _93(msg)]);
|
|
4879
4888
|
}
|
|
4880
4889
|
managedSocket.events.onMessage.subscribe(handleServerMessage);
|
|
4881
4890
|
managedSocket.events.statusDidChange.subscribe(onStatusDidChange);
|
|
@@ -4951,9 +4960,9 @@ function createAi(config) {
|
|
|
4951
4960
|
invocationId,
|
|
4952
4961
|
result,
|
|
4953
4962
|
generationOptions: {
|
|
4954
|
-
copilotId: _optionalChain([options, 'optionalAccess',
|
|
4955
|
-
stream: _optionalChain([options, 'optionalAccess',
|
|
4956
|
-
timeout: _optionalChain([options, 'optionalAccess',
|
|
4963
|
+
copilotId: _optionalChain([options, 'optionalAccess', _94 => _94.copilotId]),
|
|
4964
|
+
stream: _optionalChain([options, 'optionalAccess', _95 => _95.stream]),
|
|
4965
|
+
timeout: _optionalChain([options, 'optionalAccess', _96 => _96.timeout]),
|
|
4957
4966
|
// Knowledge and tools aren't coming from the options, but retrieved
|
|
4958
4967
|
// from the global context
|
|
4959
4968
|
knowledge: knowledge.length > 0 ? knowledge : void 0,
|
|
@@ -4971,7 +4980,7 @@ function createAi(config) {
|
|
|
4971
4980
|
}
|
|
4972
4981
|
}
|
|
4973
4982
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
4974
|
-
_optionalChain([win, 'optionalAccess',
|
|
4983
|
+
_optionalChain([win, 'optionalAccess', _97 => _97.addEventListener, 'call', _98 => _98("beforeunload", handleBeforeUnload, { once: true })]);
|
|
4975
4984
|
return Object.defineProperty(
|
|
4976
4985
|
{
|
|
4977
4986
|
[kInternal]: {
|
|
@@ -4990,7 +4999,7 @@ function createAi(config) {
|
|
|
4990
4999
|
clearChat: (chatId) => sendClientMsgWithResponse({ cmd: "clear-chat", chatId }),
|
|
4991
5000
|
askUserMessageInChat: async (chatId, userMessage, targetMessageId, options) => {
|
|
4992
5001
|
const knowledge = context.knowledgeStore.getKnowledgeForChat(chatId);
|
|
4993
|
-
const requestKnowledge = _optionalChain([options, 'optionalAccess',
|
|
5002
|
+
const requestKnowledge = _optionalChain([options, 'optionalAccess', _99 => _99.knowledge]) || [];
|
|
4994
5003
|
const combinedKnowledge = [...knowledge, ...requestKnowledge];
|
|
4995
5004
|
const tools = context.toolsStore.getToolDescriptions(chatId);
|
|
4996
5005
|
messagesStore.markMine(targetMessageId);
|
|
@@ -5000,9 +5009,9 @@ function createAi(config) {
|
|
|
5000
5009
|
sourceMessage: userMessage,
|
|
5001
5010
|
targetMessageId,
|
|
5002
5011
|
generationOptions: {
|
|
5003
|
-
copilotId: _optionalChain([options, 'optionalAccess',
|
|
5004
|
-
stream: _optionalChain([options, 'optionalAccess',
|
|
5005
|
-
timeout: _optionalChain([options, 'optionalAccess',
|
|
5012
|
+
copilotId: _optionalChain([options, 'optionalAccess', _100 => _100.copilotId]),
|
|
5013
|
+
stream: _optionalChain([options, 'optionalAccess', _101 => _101.stream]),
|
|
5014
|
+
timeout: _optionalChain([options, 'optionalAccess', _102 => _102.timeout]),
|
|
5006
5015
|
// Combine global knowledge with request-specific knowledge
|
|
5007
5016
|
knowledge: combinedKnowledge.length > 0 ? combinedKnowledge : void 0,
|
|
5008
5017
|
tools: tools.length > 0 ? tools : void 0
|
|
@@ -5074,7 +5083,7 @@ function replaceOrAppend(content, newItem, keyFn, now2) {
|
|
|
5074
5083
|
}
|
|
5075
5084
|
}
|
|
5076
5085
|
function closePart(prevPart, endedAt) {
|
|
5077
|
-
if (_optionalChain([prevPart, 'optionalAccess',
|
|
5086
|
+
if (_optionalChain([prevPart, 'optionalAccess', _103 => _103.type]) === "reasoning") {
|
|
5078
5087
|
prevPart.endedAt ??= endedAt;
|
|
5079
5088
|
}
|
|
5080
5089
|
}
|
|
@@ -5089,7 +5098,7 @@ function patchContentWithDelta(content, delta) {
|
|
|
5089
5098
|
const lastPart = parts[parts.length - 1];
|
|
5090
5099
|
switch (delta.type) {
|
|
5091
5100
|
case "text-delta":
|
|
5092
|
-
if (_optionalChain([lastPart, 'optionalAccess',
|
|
5101
|
+
if (_optionalChain([lastPart, 'optionalAccess', _104 => _104.type]) === "text") {
|
|
5093
5102
|
lastPart.text += delta.textDelta;
|
|
5094
5103
|
} else {
|
|
5095
5104
|
closePart(lastPart, now2);
|
|
@@ -5097,7 +5106,7 @@ function patchContentWithDelta(content, delta) {
|
|
|
5097
5106
|
}
|
|
5098
5107
|
break;
|
|
5099
5108
|
case "reasoning-delta":
|
|
5100
|
-
if (_optionalChain([lastPart, 'optionalAccess',
|
|
5109
|
+
if (_optionalChain([lastPart, 'optionalAccess', _105 => _105.type]) === "reasoning") {
|
|
5101
5110
|
lastPart.text += delta.textDelta;
|
|
5102
5111
|
} else {
|
|
5103
5112
|
closePart(lastPart, now2);
|
|
@@ -5117,8 +5126,8 @@ function patchContentWithDelta(content, delta) {
|
|
|
5117
5126
|
break;
|
|
5118
5127
|
}
|
|
5119
5128
|
case "tool-delta": {
|
|
5120
|
-
if (_optionalChain([lastPart, 'optionalAccess',
|
|
5121
|
-
_optionalChain([lastPart, 'access',
|
|
5129
|
+
if (_optionalChain([lastPart, 'optionalAccess', _106 => _106.type]) === "tool-invocation" && lastPart.stage === "receiving") {
|
|
5130
|
+
_optionalChain([lastPart, 'access', _107 => _107.__appendDelta, 'optionalCall', _108 => _108(delta.delta)]);
|
|
5122
5131
|
}
|
|
5123
5132
|
break;
|
|
5124
5133
|
}
|
|
@@ -5192,6 +5201,15 @@ var Permission = {
|
|
|
5192
5201
|
CommentsWrite: "comments:write",
|
|
5193
5202
|
CommentsRead: "comments:read",
|
|
5194
5203
|
CommentsNone: "comments:none",
|
|
5204
|
+
CommentsPublicWrite: "comments:public:write",
|
|
5205
|
+
CommentsPublicRead: "comments:public:read",
|
|
5206
|
+
CommentsPublicNone: "comments:public:none",
|
|
5207
|
+
CommentsPrivateWrite: "comments:private:write",
|
|
5208
|
+
CommentsPrivateRead: "comments:private:read",
|
|
5209
|
+
CommentsPrivateNone: "comments:private:none",
|
|
5210
|
+
CommentsPersonalWrite: "comments:personal:write",
|
|
5211
|
+
CommentsPersonalRead: "comments:personal:read",
|
|
5212
|
+
CommentsPersonalNone: "comments:personal:none",
|
|
5195
5213
|
/**
|
|
5196
5214
|
* Feeds
|
|
5197
5215
|
*/
|
|
@@ -5204,152 +5222,125 @@ var Permission = {
|
|
|
5204
5222
|
LegacyRoomPresenceWrite: "room:presence:write"
|
|
5205
5223
|
};
|
|
5206
5224
|
var ACCESS_LEVELS = ["none", "read", "write"];
|
|
5207
|
-
var basePermissionScopes = /* @__PURE__ */ new Set([
|
|
5208
|
-
Permission.Read,
|
|
5209
|
-
Permission.Write,
|
|
5210
|
-
Permission.RoomRead,
|
|
5211
|
-
Permission.RoomWrite
|
|
5212
|
-
]);
|
|
5213
5225
|
var ACCESS_LEVEL_RANKS = {
|
|
5214
5226
|
none: 0,
|
|
5215
5227
|
read: 1,
|
|
5216
5228
|
write: 2
|
|
5217
5229
|
};
|
|
5218
|
-
var
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
write: [Permission.Write, Permission.RoomWrite]
|
|
5222
|
-
},
|
|
5223
|
-
personal: {
|
|
5224
|
-
write: []
|
|
5225
|
-
},
|
|
5226
|
-
storage: {
|
|
5227
|
-
write: [Permission.StorageWrite],
|
|
5228
|
-
read: [Permission.StorageRead],
|
|
5229
|
-
none: [Permission.StorageNone]
|
|
5230
|
-
},
|
|
5231
|
-
comments: {
|
|
5232
|
-
write: [Permission.CommentsWrite],
|
|
5233
|
-
read: [Permission.CommentsRead],
|
|
5234
|
-
none: [Permission.CommentsNone]
|
|
5235
|
-
},
|
|
5236
|
-
feeds: {
|
|
5237
|
-
write: [Permission.FeedsWrite],
|
|
5238
|
-
read: [Permission.FeedsRead],
|
|
5239
|
-
none: [Permission.FeedsNone]
|
|
5240
|
-
}
|
|
5230
|
+
var BASE_PERMISSIONS_BY_ACCESS = {
|
|
5231
|
+
read: [Permission.Read, Permission.RoomRead],
|
|
5232
|
+
write: [Permission.Write, Permission.RoomWrite]
|
|
5241
5233
|
};
|
|
5242
5234
|
var NO_PERMISSION_MATRIX = {
|
|
5243
5235
|
room: "none",
|
|
5244
5236
|
storage: "none",
|
|
5245
5237
|
comments: "none",
|
|
5238
|
+
"comments:public": "none",
|
|
5239
|
+
"comments:private": "none",
|
|
5240
|
+
"comments:personal": "none",
|
|
5246
5241
|
feeds: "none",
|
|
5247
5242
|
personal: "none"
|
|
5248
5243
|
};
|
|
5249
5244
|
var BASE_PERMISSION_RESOURCE = "room";
|
|
5250
|
-
var
|
|
5245
|
+
var basePermissionScopes = /* @__PURE__ */ new Set([
|
|
5246
|
+
Permission.Read,
|
|
5247
|
+
Permission.Write,
|
|
5248
|
+
Permission.RoomRead,
|
|
5249
|
+
Permission.RoomWrite
|
|
5250
|
+
]);
|
|
5251
|
+
var ROOM_PERMISSION_RESOURCES = Object.freeze([
|
|
5251
5252
|
"storage",
|
|
5252
5253
|
"comments",
|
|
5254
|
+
"comments:public",
|
|
5255
|
+
"comments:private",
|
|
5256
|
+
"comments:personal",
|
|
5253
5257
|
"feeds"
|
|
5254
|
-
];
|
|
5255
|
-
var
|
|
5256
|
-
|
|
5257
|
-
return VALID_PERMISSIONS.has(permission);
|
|
5258
|
-
}
|
|
5259
|
-
function resolveResourceAccess(scopes, resource) {
|
|
5260
|
-
const permissions = PERMISSIONS_BY_RESOURCE[resource];
|
|
5261
|
-
let resourceAccess;
|
|
5262
|
-
for (const access of ACCESS_LEVELS) {
|
|
5263
|
-
const scopedPermissions = permissions[access];
|
|
5264
|
-
if (scopedPermissions !== void 0 && scopedPermissions.some((permission) => scopes.includes(permission))) {
|
|
5265
|
-
resourceAccess = access;
|
|
5266
|
-
}
|
|
5267
|
-
}
|
|
5268
|
-
return resourceAccess;
|
|
5269
|
-
}
|
|
5270
|
-
function permissionMatrixFromResolvedScopes(resolved) {
|
|
5271
|
-
if (!resolved.hasDefaultPermission) {
|
|
5272
|
-
return { ...NO_PERMISSION_MATRIX };
|
|
5273
|
-
}
|
|
5274
|
-
const matrix = {
|
|
5275
|
-
...NO_PERMISSION_MATRIX,
|
|
5276
|
-
[BASE_PERMISSION_RESOURCE]: resolved.baseAccess,
|
|
5277
|
-
personal: "write"
|
|
5278
|
-
};
|
|
5258
|
+
]);
|
|
5259
|
+
var CHILD_ROOM_PERMISSION_RESOURCES = (() => {
|
|
5260
|
+
const result = /* @__PURE__ */ new Map();
|
|
5279
5261
|
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5280
|
-
|
|
5262
|
+
const childResourcePrefix = `${resource}:`;
|
|
5263
|
+
result.set(
|
|
5264
|
+
resource,
|
|
5265
|
+
Object.freeze(
|
|
5266
|
+
ROOM_PERMISSION_RESOURCES.filter((candidate) => {
|
|
5267
|
+
if (!candidate.startsWith(childResourcePrefix)) {
|
|
5268
|
+
return false;
|
|
5269
|
+
}
|
|
5270
|
+
return !candidate.slice(childResourcePrefix.length).includes(":");
|
|
5271
|
+
})
|
|
5272
|
+
)
|
|
5273
|
+
);
|
|
5281
5274
|
}
|
|
5282
|
-
return
|
|
5283
|
-
}
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
}
|
|
5287
|
-
function resolvePermissionScopes(scopes) {
|
|
5288
|
-
const hasDefaultPermission = scopes.includes(Permission.Write) || scopes.includes(Permission.Read) || scopes.includes(Permission.RoomWrite) || scopes.includes(Permission.RoomRead);
|
|
5289
|
-
const baseAccess = scopes.includes(Permission.Write) || scopes.includes(Permission.RoomWrite) ? "write" : scopes.includes(Permission.Read) || scopes.includes(Permission.RoomRead) ? "read" : "none";
|
|
5290
|
-
const matrix = {};
|
|
5275
|
+
return result;
|
|
5276
|
+
})();
|
|
5277
|
+
var LEAF_ROOM_PERMISSION_RESOURCES_BY_PARENT = (() => {
|
|
5278
|
+
const result = /* @__PURE__ */ new Map();
|
|
5291
5279
|
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5292
|
-
|
|
5293
|
-
if (access !== void 0) {
|
|
5294
|
-
matrix[resource] = access;
|
|
5295
|
-
}
|
|
5296
|
-
}
|
|
5297
|
-
return { hasDefaultPermission, baseAccess, matrix };
|
|
5298
|
-
}
|
|
5299
|
-
function hasPermissionAccess(matrix, resource, requiredAccess) {
|
|
5300
|
-
const access = _nullishCoalesce(matrix[resource], () => ( "none"));
|
|
5301
|
-
return ACCESS_LEVEL_RANKS[access] >= ACCESS_LEVEL_RANKS[requiredAccess];
|
|
5302
|
-
}
|
|
5303
|
-
function resolveRoomPermissionMatrix(permissions, roomId) {
|
|
5304
|
-
const matchedPermissions = permissions.filter(
|
|
5305
|
-
(entry) => roomPatternMatches(entry.pattern, roomId)
|
|
5306
|
-
);
|
|
5307
|
-
if (matchedPermissions.length === 0) {
|
|
5308
|
-
return void 0;
|
|
5280
|
+
result.set(resource, Object.freeze(getLeafResources(resource)));
|
|
5309
5281
|
}
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
const
|
|
5314
|
-
for (const
|
|
5315
|
-
const
|
|
5316
|
-
|
|
5317
|
-
if (resolved.hasDefaultPermission) {
|
|
5318
|
-
hasDefaultPermission = true;
|
|
5319
|
-
baseAccess = strongestAccess(baseAccess, resolved.baseAccess);
|
|
5320
|
-
}
|
|
5321
|
-
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5322
|
-
const access = resolved.matrix[resource];
|
|
5323
|
-
if (access !== void 0) {
|
|
5324
|
-
const currentSpecificity = _nullishCoalesce(explicitSpecificity[resource], () => ( -1));
|
|
5325
|
-
if (specificity > currentSpecificity) {
|
|
5326
|
-
explicitMatrix[resource] = access;
|
|
5327
|
-
explicitSpecificity[resource] = specificity;
|
|
5328
|
-
} else if (specificity === currentSpecificity) {
|
|
5329
|
-
explicitMatrix[resource] = strongestAccess(
|
|
5330
|
-
_nullishCoalesce(explicitMatrix[resource], () => ( "none")),
|
|
5331
|
-
access
|
|
5332
|
-
);
|
|
5333
|
-
}
|
|
5334
|
-
}
|
|
5282
|
+
return result;
|
|
5283
|
+
})();
|
|
5284
|
+
var PARENT_ROOM_PERMISSION_RESOURCES = (() => {
|
|
5285
|
+
const result = /* @__PURE__ */ new Map();
|
|
5286
|
+
for (const parentResource of ROOM_PERMISSION_RESOURCES) {
|
|
5287
|
+
for (const childResource of childResourcesOf(parentResource)) {
|
|
5288
|
+
result.set(childResource, parentResource);
|
|
5335
5289
|
}
|
|
5336
5290
|
}
|
|
5337
|
-
return
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
5291
|
+
return result;
|
|
5292
|
+
})();
|
|
5293
|
+
var LEAF_ROOM_PERMISSION_RESOURCES = Object.freeze(
|
|
5294
|
+
ROOM_PERMISSION_RESOURCES.filter(
|
|
5295
|
+
(resource) => childResourcesOf(resource).length === 0
|
|
5296
|
+
)
|
|
5297
|
+
);
|
|
5298
|
+
var PERMISSIONS_BY_ROOM_RESOURCE = {
|
|
5299
|
+
storage: {
|
|
5300
|
+
write: [Permission.StorageWrite],
|
|
5301
|
+
read: [Permission.StorageRead],
|
|
5302
|
+
none: [Permission.StorageNone]
|
|
5303
|
+
},
|
|
5304
|
+
comments: {
|
|
5305
|
+
write: [Permission.CommentsWrite],
|
|
5306
|
+
read: [Permission.CommentsRead],
|
|
5307
|
+
none: [Permission.CommentsNone]
|
|
5308
|
+
},
|
|
5309
|
+
"comments:public": {
|
|
5310
|
+
write: [Permission.CommentsPublicWrite],
|
|
5311
|
+
read: [Permission.CommentsPublicRead],
|
|
5312
|
+
none: [Permission.CommentsPublicNone]
|
|
5313
|
+
},
|
|
5314
|
+
"comments:private": {
|
|
5315
|
+
write: [Permission.CommentsPrivateWrite],
|
|
5316
|
+
read: [Permission.CommentsPrivateRead],
|
|
5317
|
+
none: [Permission.CommentsPrivateNone]
|
|
5318
|
+
},
|
|
5319
|
+
"comments:personal": {
|
|
5320
|
+
write: [Permission.CommentsPersonalWrite],
|
|
5321
|
+
read: [Permission.CommentsPersonalRead],
|
|
5322
|
+
none: [Permission.CommentsPersonalNone]
|
|
5323
|
+
},
|
|
5324
|
+
feeds: {
|
|
5325
|
+
write: [Permission.FeedsWrite],
|
|
5326
|
+
read: [Permission.FeedsRead],
|
|
5327
|
+
none: [Permission.FeedsNone]
|
|
5328
|
+
}
|
|
5329
|
+
};
|
|
5330
|
+
var VALID_PERMISSIONS = new Set(Object.values(Permission));
|
|
5343
5331
|
function normalizeRoomPermissions(permissions) {
|
|
5344
5332
|
if (!Array.isArray(permissions)) {
|
|
5345
5333
|
throw new Error("Permission list must be an array");
|
|
5346
5334
|
}
|
|
5347
5335
|
const result = [];
|
|
5348
5336
|
for (const permission of permissions) {
|
|
5349
|
-
|
|
5337
|
+
const knownPermission = Object.values(Permission).find(
|
|
5338
|
+
(value) => value === permission
|
|
5339
|
+
);
|
|
5340
|
+
if (knownPermission === void 0) {
|
|
5350
5341
|
throw new Error(`Not a valid permission: ${permission}`);
|
|
5351
5342
|
}
|
|
5352
|
-
result.push(
|
|
5343
|
+
result.push(knownPermission);
|
|
5353
5344
|
}
|
|
5354
5345
|
return result;
|
|
5355
5346
|
}
|
|
@@ -5375,6 +5366,31 @@ function normalizeUpdateRoomAccesses(accesses) {
|
|
|
5375
5366
|
])
|
|
5376
5367
|
);
|
|
5377
5368
|
}
|
|
5369
|
+
function validatePermissionsSet(scopes) {
|
|
5370
|
+
const unknownScopes = scopes.filter((scope) => !VALID_PERMISSIONS.has(scope));
|
|
5371
|
+
if (unknownScopes.length > 0) {
|
|
5372
|
+
return `Unknown permission scope(s): ${unknownScopes.join(", ")}`;
|
|
5373
|
+
}
|
|
5374
|
+
const baseScopes = scopes.filter((scope) => basePermissionScopes.has(scope));
|
|
5375
|
+
if (baseScopes.length !== 1) {
|
|
5376
|
+
return `Permissions must include exactly one of ${Permission.Read}, ${Permission.Write} (or the legacy aliases ${Permission.RoomRead}, ${Permission.RoomWrite}), got ${baseScopes.length === 0 ? "none" : baseScopes.join(", ")}`;
|
|
5377
|
+
}
|
|
5378
|
+
const seenFeatures = /* @__PURE__ */ new Set();
|
|
5379
|
+
for (const scope of scopes) {
|
|
5380
|
+
if (basePermissionScopes.has(scope) || scope === Permission.LegacyRoomPresenceWrite) {
|
|
5381
|
+
continue;
|
|
5382
|
+
}
|
|
5383
|
+
const feature = scope.split(":").slice(0, -1).join(":");
|
|
5384
|
+
if (seenFeatures.has(feature)) {
|
|
5385
|
+
return `Permissions can include at most one scope per feature, got multiple "${feature}" scopes`;
|
|
5386
|
+
}
|
|
5387
|
+
seenFeatures.add(feature);
|
|
5388
|
+
}
|
|
5389
|
+
return true;
|
|
5390
|
+
}
|
|
5391
|
+
function permissionMatrixFromScopes(scopes) {
|
|
5392
|
+
return permissionMatrixFromResolvedScopes(resolvePermissionScopes(scopes));
|
|
5393
|
+
}
|
|
5378
5394
|
function permissionMatrixToScopes(matrix) {
|
|
5379
5395
|
const scopes = [];
|
|
5380
5396
|
const baseAccess = matrix.room;
|
|
@@ -5382,13 +5398,59 @@ function permissionMatrixToScopes(matrix) {
|
|
|
5382
5398
|
scopes.push(permissionForAccessLevel(BASE_PERMISSION_RESOURCE, baseAccess));
|
|
5383
5399
|
}
|
|
5384
5400
|
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
scopes.push(permissionForAccessLevel(resource, access));
|
|
5401
|
+
if (parentResourceOf(resource) === void 0) {
|
|
5402
|
+
pushResourcePermissions(scopes, matrix, resource, baseAccess);
|
|
5388
5403
|
}
|
|
5389
5404
|
}
|
|
5390
5405
|
return scopes;
|
|
5391
5406
|
}
|
|
5407
|
+
function hasPermissionAccess(matrix, resource, requiredAccess) {
|
|
5408
|
+
const access = _nullishCoalesce(matrix[resource], () => ( "none"));
|
|
5409
|
+
return ACCESS_LEVEL_RANKS[access] >= ACCESS_LEVEL_RANKS[requiredAccess];
|
|
5410
|
+
}
|
|
5411
|
+
function resolveRoomPermissionMatrix(permissions, roomId) {
|
|
5412
|
+
const matchedPermissions = permissions.filter((entry) => {
|
|
5413
|
+
if (entry.pattern.includes("*")) {
|
|
5414
|
+
return roomId.startsWith(entry.pattern.replace("*", ""));
|
|
5415
|
+
}
|
|
5416
|
+
return entry.pattern === roomId;
|
|
5417
|
+
});
|
|
5418
|
+
if (matchedPermissions.length === 0) {
|
|
5419
|
+
return void 0;
|
|
5420
|
+
}
|
|
5421
|
+
let hasDefaultPermission = false;
|
|
5422
|
+
let baseAccess = "none";
|
|
5423
|
+
const leafAccesses = {};
|
|
5424
|
+
const leafSpecificity = {};
|
|
5425
|
+
for (const entry of matchedPermissions) {
|
|
5426
|
+
const resolved = resolvePermissionScopes(entry.scopes);
|
|
5427
|
+
const specificity = entry.pattern.replace("*", "").length;
|
|
5428
|
+
if (resolved.baseAccess !== void 0) {
|
|
5429
|
+
hasDefaultPermission = true;
|
|
5430
|
+
baseAccess = strongestAccess(baseAccess, resolved.baseAccess);
|
|
5431
|
+
}
|
|
5432
|
+
for (const resource of LEAF_ROOM_PERMISSION_RESOURCES) {
|
|
5433
|
+
if (resolved.leafAccesses[resource] === void 0) {
|
|
5434
|
+
continue;
|
|
5435
|
+
}
|
|
5436
|
+
const access = resolveLeafAccessFromSource(resolved, resource);
|
|
5437
|
+
const currentSpecificity = _nullishCoalesce(leafSpecificity[resource], () => ( -1));
|
|
5438
|
+
if (specificity > currentSpecificity) {
|
|
5439
|
+
leafAccesses[resource] = access;
|
|
5440
|
+
leafSpecificity[resource] = specificity;
|
|
5441
|
+
} else if (specificity === currentSpecificity) {
|
|
5442
|
+
leafAccesses[resource] = strongestAccess(
|
|
5443
|
+
_nullishCoalesce(leafAccesses[resource], () => ( "none")),
|
|
5444
|
+
access
|
|
5445
|
+
);
|
|
5446
|
+
}
|
|
5447
|
+
}
|
|
5448
|
+
}
|
|
5449
|
+
return permissionMatrixFromResolvedScopes({
|
|
5450
|
+
baseAccess: hasDefaultPermission ? baseAccess : void 0,
|
|
5451
|
+
leafAccesses
|
|
5452
|
+
});
|
|
5453
|
+
}
|
|
5392
5454
|
function mergeRoomPermissionScopes({
|
|
5393
5455
|
defaultAccesses,
|
|
5394
5456
|
groupsAccesses,
|
|
@@ -5402,90 +5464,158 @@ function mergeRoomPermissionScopes({
|
|
|
5402
5464
|
resolvePermissionScopes(userAccesses)
|
|
5403
5465
|
];
|
|
5404
5466
|
const merged = {
|
|
5405
|
-
|
|
5406
|
-
baseAccess: "none",
|
|
5407
|
-
matrix: {}
|
|
5467
|
+
leafAccesses: {}
|
|
5408
5468
|
};
|
|
5409
5469
|
for (const source of sources) {
|
|
5410
|
-
if (source.
|
|
5411
|
-
merged.hasDefaultPermission = true;
|
|
5470
|
+
if (source.baseAccess !== void 0) {
|
|
5412
5471
|
merged.baseAccess = source.baseAccess;
|
|
5413
5472
|
}
|
|
5414
|
-
for (const resource of
|
|
5415
|
-
const
|
|
5416
|
-
if (
|
|
5417
|
-
|
|
5473
|
+
for (const resource of LEAF_ROOM_PERMISSION_RESOURCES) {
|
|
5474
|
+
const sourceAccess = source.leafAccesses[resource];
|
|
5475
|
+
if (sourceAccess === void 0) {
|
|
5476
|
+
continue;
|
|
5418
5477
|
}
|
|
5478
|
+
merged.leafAccesses[resource] = sourceAccess;
|
|
5419
5479
|
}
|
|
5420
5480
|
}
|
|
5421
5481
|
return permissionMatrixToScopes(permissionMatrixFromResolvedScopes(merged));
|
|
5422
5482
|
}
|
|
5483
|
+
function resolvePermissionScopes(scopes) {
|
|
5484
|
+
const baseAccess = resolveAccess(scopes, BASE_PERMISSIONS_BY_ACCESS);
|
|
5485
|
+
const leafAccesses = {};
|
|
5486
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5487
|
+
const access = resolveResourceAccess(scopes, resource);
|
|
5488
|
+
if (access !== void 0) {
|
|
5489
|
+
for (const leafResource of leafResourcesOf(resource)) {
|
|
5490
|
+
leafAccesses[leafResource] = access;
|
|
5491
|
+
}
|
|
5492
|
+
}
|
|
5493
|
+
}
|
|
5494
|
+
return { baseAccess, leafAccesses };
|
|
5495
|
+
}
|
|
5496
|
+
function resolveResourceAccess(scopes, resource) {
|
|
5497
|
+
return resolveAccess(scopes, PERMISSIONS_BY_ROOM_RESOURCE[resource]);
|
|
5498
|
+
}
|
|
5499
|
+
function resolveAccess(scopes, permissions) {
|
|
5500
|
+
let resourceAccess;
|
|
5501
|
+
for (const access of ACCESS_LEVELS) {
|
|
5502
|
+
const scopedPermissions = permissions[access];
|
|
5503
|
+
if (scopedPermissions !== void 0 && scopedPermissions.some((permission) => scopes.includes(permission))) {
|
|
5504
|
+
resourceAccess = access;
|
|
5505
|
+
}
|
|
5506
|
+
}
|
|
5507
|
+
return resourceAccess;
|
|
5508
|
+
}
|
|
5509
|
+
function permissionMatrixFromResolvedScopes(resolved) {
|
|
5510
|
+
if (resolved.baseAccess === void 0) {
|
|
5511
|
+
return { ...NO_PERMISSION_MATRIX };
|
|
5512
|
+
}
|
|
5513
|
+
const matrix = {
|
|
5514
|
+
...NO_PERMISSION_MATRIX,
|
|
5515
|
+
[BASE_PERMISSION_RESOURCE]: resolved.baseAccess,
|
|
5516
|
+
personal: "write"
|
|
5517
|
+
};
|
|
5518
|
+
for (const resource of LEAF_ROOM_PERMISSION_RESOURCES) {
|
|
5519
|
+
matrix[resource] = resolveLeafAccessFromSource(resolved, resource);
|
|
5520
|
+
}
|
|
5521
|
+
for (const resource of ROOM_PERMISSION_RESOURCES) {
|
|
5522
|
+
if (childResourcesOf(resource).length > 0) {
|
|
5523
|
+
let strongest = "none";
|
|
5524
|
+
for (const leafResource of leafResourcesOf(resource)) {
|
|
5525
|
+
strongest = strongestAccess(strongest, matrix[leafResource]);
|
|
5526
|
+
}
|
|
5527
|
+
matrix[resource] = strongest;
|
|
5528
|
+
}
|
|
5529
|
+
}
|
|
5530
|
+
return matrix;
|
|
5531
|
+
}
|
|
5532
|
+
function resolveLeafAccessFromSource(source, resource) {
|
|
5533
|
+
const access = source.leafAccesses[resource];
|
|
5534
|
+
if (access !== void 0) {
|
|
5535
|
+
return access;
|
|
5536
|
+
}
|
|
5537
|
+
return _nullishCoalesce(source.baseAccess, () => ( "none"));
|
|
5538
|
+
}
|
|
5539
|
+
function pushResourcePermissions(scopes, matrix, resource, baseAccess) {
|
|
5540
|
+
const childResources = childResourcesOf(resource);
|
|
5541
|
+
if (childResources.length === 0) {
|
|
5542
|
+
const access = matrix[resource];
|
|
5543
|
+
if (access !== baseAccess) {
|
|
5544
|
+
scopes.push(permissionForAccessLevel(resource, access));
|
|
5545
|
+
}
|
|
5546
|
+
return;
|
|
5547
|
+
}
|
|
5548
|
+
const leafResources = leafResourcesOf(resource);
|
|
5549
|
+
let sharedAccess;
|
|
5550
|
+
let allLeavesShareAccess = true;
|
|
5551
|
+
for (const leafResource of leafResources) {
|
|
5552
|
+
const access = matrix[leafResource];
|
|
5553
|
+
sharedAccess ??= access;
|
|
5554
|
+
if (access !== sharedAccess) {
|
|
5555
|
+
allLeavesShareAccess = false;
|
|
5556
|
+
break;
|
|
5557
|
+
}
|
|
5558
|
+
}
|
|
5559
|
+
if (sharedAccess !== void 0 && sharedAccess !== baseAccess && allLeavesShareAccess) {
|
|
5560
|
+
scopes.push(permissionForAccessLevel(resource, sharedAccess));
|
|
5561
|
+
return;
|
|
5562
|
+
}
|
|
5563
|
+
for (const childResource of childResources) {
|
|
5564
|
+
pushResourcePermissions(scopes, matrix, childResource, baseAccess);
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5423
5567
|
function mergeResolvedScopesByHighestAccess(sources) {
|
|
5424
5568
|
const merged = {
|
|
5425
|
-
|
|
5426
|
-
baseAccess: "none",
|
|
5427
|
-
matrix: {}
|
|
5569
|
+
leafAccesses: {}
|
|
5428
5570
|
};
|
|
5429
5571
|
for (const source of sources) {
|
|
5430
|
-
if (source.
|
|
5431
|
-
merged.
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
);
|
|
5572
|
+
if (source.baseAccess !== void 0) {
|
|
5573
|
+
merged.baseAccess = strongestAccess(
|
|
5574
|
+
_nullishCoalesce(merged.baseAccess, () => ( "none")),
|
|
5575
|
+
source.baseAccess
|
|
5576
|
+
);
|
|
5577
|
+
}
|
|
5578
|
+
for (const resource of LEAF_ROOM_PERMISSION_RESOURCES) {
|
|
5579
|
+
const sourceAccess = source.leafAccesses[resource];
|
|
5580
|
+
if (sourceAccess === void 0) {
|
|
5581
|
+
continue;
|
|
5441
5582
|
}
|
|
5583
|
+
merged.leafAccesses[resource] = strongestAccess(
|
|
5584
|
+
_nullishCoalesce(merged.leafAccesses[resource], () => ( "none")),
|
|
5585
|
+
sourceAccess
|
|
5586
|
+
);
|
|
5442
5587
|
}
|
|
5443
5588
|
}
|
|
5444
5589
|
return merged;
|
|
5445
5590
|
}
|
|
5446
5591
|
function permissionForAccessLevel(resource, access, field = resource) {
|
|
5447
|
-
const
|
|
5448
|
-
const
|
|
5449
|
-
if (
|
|
5450
|
-
|
|
5451
|
-
`Invalid permission level for ${field}: ${_nullishCoalesce(JSON.stringify(access), () => ( String(access)))}`
|
|
5452
|
-
);
|
|
5592
|
+
const permissions = resource === "room" ? BASE_PERMISSIONS_BY_ACCESS[access] : resource === "personal" ? void 0 : PERMISSIONS_BY_ROOM_RESOURCE[resource][access];
|
|
5593
|
+
const permission = _optionalChain([permissions, 'optionalAccess', _109 => _109[0]]);
|
|
5594
|
+
if (permission !== void 0) {
|
|
5595
|
+
return permission;
|
|
5453
5596
|
}
|
|
5454
|
-
|
|
5597
|
+
throw new Error(
|
|
5598
|
+
`Invalid permission level for ${field}: ${_nullishCoalesce(JSON.stringify(access), () => ( String(access)))}`
|
|
5599
|
+
);
|
|
5455
5600
|
}
|
|
5456
5601
|
function strongestAccess(left, right) {
|
|
5457
5602
|
return ACCESS_LEVEL_RANKS[right] > ACCESS_LEVEL_RANKS[left] ? right : left;
|
|
5458
5603
|
}
|
|
5459
|
-
function
|
|
5460
|
-
|
|
5461
|
-
return roomId.startsWith(pattern.replace("*", ""));
|
|
5462
|
-
}
|
|
5463
|
-
return pattern === roomId;
|
|
5604
|
+
function leafResourcesOf(resource) {
|
|
5605
|
+
return _nullishCoalesce(LEAF_ROOM_PERMISSION_RESOURCES_BY_PARENT.get(resource), () => ( []));
|
|
5464
5606
|
}
|
|
5465
|
-
function
|
|
5466
|
-
return
|
|
5607
|
+
function childResourcesOf(resource) {
|
|
5608
|
+
return _nullishCoalesce(CHILD_ROOM_PERMISSION_RESOURCES.get(resource), () => ( []));
|
|
5467
5609
|
}
|
|
5468
|
-
function
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
return `Permissions must include exactly one of ${Permission.Read}, ${Permission.Write} (or the legacy aliases ${Permission.RoomRead}, ${Permission.RoomWrite}), got ${baseScopes.length === 0 ? "none" : baseScopes.join(", ")}`;
|
|
5476
|
-
}
|
|
5477
|
-
const seenFeatures = /* @__PURE__ */ new Set();
|
|
5478
|
-
for (const scope of scopes) {
|
|
5479
|
-
if (basePermissionScopes.has(scope) || scope === Permission.LegacyRoomPresenceWrite) {
|
|
5480
|
-
continue;
|
|
5481
|
-
}
|
|
5482
|
-
const feature = scope.slice(0, scope.indexOf(":"));
|
|
5483
|
-
if (seenFeatures.has(feature)) {
|
|
5484
|
-
return `Permissions can include at most one scope per feature, got multiple "${feature}" scopes`;
|
|
5485
|
-
}
|
|
5486
|
-
seenFeatures.add(feature);
|
|
5610
|
+
function parentResourceOf(resource) {
|
|
5611
|
+
return PARENT_ROOM_PERMISSION_RESOURCES.get(resource);
|
|
5612
|
+
}
|
|
5613
|
+
function getLeafResources(resource) {
|
|
5614
|
+
const childResources = childResourcesOf(resource);
|
|
5615
|
+
if (childResources.length === 0) {
|
|
5616
|
+
return [resource];
|
|
5487
5617
|
}
|
|
5488
|
-
return
|
|
5618
|
+
return childResources.flatMap(getLeafResources);
|
|
5489
5619
|
}
|
|
5490
5620
|
|
|
5491
5621
|
// src/protocol/AuthToken.ts
|
|
@@ -5548,7 +5678,7 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5548
5678
|
return void 0;
|
|
5549
5679
|
}
|
|
5550
5680
|
async function makeAuthRequest(options) {
|
|
5551
|
-
const fetcher = _nullishCoalesce(_optionalChain([authOptions, 'access',
|
|
5681
|
+
const fetcher = _nullishCoalesce(_optionalChain([authOptions, 'access', _110 => _110.polyfills, 'optionalAccess', _111 => _111.fetch]), () => ( (typeof window === "undefined" ? void 0 : window.fetch)));
|
|
5552
5682
|
if (authentication.type === "private") {
|
|
5553
5683
|
if (fetcher === void 0) {
|
|
5554
5684
|
throw new StopRetrying(
|
|
@@ -5561,14 +5691,14 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5561
5691
|
const parsed = parseAuthToken(response.token);
|
|
5562
5692
|
if (seenTokens.has(parsed.raw)) {
|
|
5563
5693
|
const cachedToken = getCachedToken(options);
|
|
5564
|
-
if (_optionalChain([cachedToken, 'optionalAccess',
|
|
5694
|
+
if (_optionalChain([cachedToken, 'optionalAccess', _112 => _112.raw]) === parsed.raw) {
|
|
5565
5695
|
return cachedToken;
|
|
5566
5696
|
}
|
|
5567
5697
|
throw new StopRetrying(
|
|
5568
5698
|
"The same Liveblocks auth token was issued from the backend before. Caching Liveblocks tokens is not supported."
|
|
5569
5699
|
);
|
|
5570
5700
|
}
|
|
5571
|
-
_optionalChain([onAuthenticate, 'optionalCall',
|
|
5701
|
+
_optionalChain([onAuthenticate, 'optionalCall', _113 => _113(parsed.parsed)]);
|
|
5572
5702
|
return parsed;
|
|
5573
5703
|
}
|
|
5574
5704
|
if (authentication.type === "custom") {
|
|
@@ -5576,7 +5706,7 @@ function createAuthManager(authOptions, onAuthenticate) {
|
|
|
5576
5706
|
if (response && typeof response === "object") {
|
|
5577
5707
|
if (typeof response.token === "string") {
|
|
5578
5708
|
const parsed = parseAuthToken(response.token);
|
|
5579
|
-
_optionalChain([onAuthenticate, 'optionalCall',
|
|
5709
|
+
_optionalChain([onAuthenticate, 'optionalCall', _114 => _114(parsed.parsed)]);
|
|
5580
5710
|
return parsed;
|
|
5581
5711
|
} else if (typeof response.error === "string") {
|
|
5582
5712
|
const reason = `Authentication failed: ${"reason" in response && typeof response.reason === "string" ? response.reason : "Forbidden"}`;
|
|
@@ -5768,15 +5898,13 @@ var OpCode = Object.freeze({
|
|
|
5768
5898
|
DELETE_CRDT: 5,
|
|
5769
5899
|
DELETE_OBJECT_KEY: 6,
|
|
5770
5900
|
CREATE_MAP: 7,
|
|
5771
|
-
CREATE_REGISTER: 8
|
|
5772
|
-
CREATE_TEXT: 9,
|
|
5773
|
-
UPDATE_TEXT: 10
|
|
5901
|
+
CREATE_REGISTER: 8
|
|
5774
5902
|
});
|
|
5775
5903
|
function isIgnoredOp(op) {
|
|
5776
5904
|
return op.type === OpCode.DELETE_CRDT && op.id === "ACK";
|
|
5777
5905
|
}
|
|
5778
5906
|
function isCreateOp(op) {
|
|
5779
|
-
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST
|
|
5907
|
+
return op.type === OpCode.CREATE_OBJECT || op.type === OpCode.CREATE_REGISTER || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_LIST;
|
|
5780
5908
|
}
|
|
5781
5909
|
|
|
5782
5910
|
// src/protocol/StorageNode.ts
|
|
@@ -5784,8 +5912,7 @@ var CrdtType = Object.freeze({
|
|
|
5784
5912
|
OBJECT: 0,
|
|
5785
5913
|
LIST: 1,
|
|
5786
5914
|
MAP: 2,
|
|
5787
|
-
REGISTER: 3
|
|
5788
|
-
TEXT: 4
|
|
5915
|
+
REGISTER: 3
|
|
5789
5916
|
});
|
|
5790
5917
|
function isRootStorageNode(node) {
|
|
5791
5918
|
return node[0] === "root";
|
|
@@ -5802,9 +5929,6 @@ function isMapStorageNode(node) {
|
|
|
5802
5929
|
function isRegisterStorageNode(node) {
|
|
5803
5930
|
return node[1].type === CrdtType.REGISTER;
|
|
5804
5931
|
}
|
|
5805
|
-
function isTextStorageNode(node) {
|
|
5806
|
-
return node[1].type === CrdtType.TEXT;
|
|
5807
|
-
}
|
|
5808
5932
|
function isCompactRootNode(node) {
|
|
5809
5933
|
return node[0] === "root";
|
|
5810
5934
|
}
|
|
@@ -5827,9 +5951,6 @@ function* compactNodesToNodeStream(compactNodes) {
|
|
|
5827
5951
|
case CrdtType.REGISTER:
|
|
5828
5952
|
yield [cnode[0], { type: CrdtType.REGISTER, parentId: cnode[2], parentKey: cnode[3], data: cnode[4] }];
|
|
5829
5953
|
break;
|
|
5830
|
-
case CrdtType.TEXT:
|
|
5831
|
-
yield [cnode[0], { type: CrdtType.TEXT, parentId: cnode[2], parentKey: cnode[3], data: cnode[4], version: cnode[5] }];
|
|
5832
|
-
break;
|
|
5833
5954
|
default:
|
|
5834
5955
|
}
|
|
5835
5956
|
}
|
|
@@ -5858,17 +5979,6 @@ function* nodeStreamToCompactNodes(nodes) {
|
|
|
5858
5979
|
const id = node[0];
|
|
5859
5980
|
const crdt = node[1];
|
|
5860
5981
|
yield [id, CrdtType.REGISTER, crdt.parentId, crdt.parentKey, crdt.data];
|
|
5861
|
-
} else if (isTextStorageNode(node)) {
|
|
5862
|
-
const id = node[0];
|
|
5863
|
-
const crdt = node[1];
|
|
5864
|
-
yield [
|
|
5865
|
-
id,
|
|
5866
|
-
CrdtType.TEXT,
|
|
5867
|
-
crdt.parentId,
|
|
5868
|
-
crdt.parentKey,
|
|
5869
|
-
crdt.data,
|
|
5870
|
-
crdt.version
|
|
5871
|
-
];
|
|
5872
5982
|
} else {
|
|
5873
5983
|
}
|
|
5874
5984
|
}
|
|
@@ -6071,10 +6181,6 @@ ${parentKey}`;
|
|
|
6071
6181
|
get size() {
|
|
6072
6182
|
return this.#byOpId.size;
|
|
6073
6183
|
}
|
|
6074
|
-
/** The still-unacknowledged op with the given opId, if any. */
|
|
6075
|
-
get(opId) {
|
|
6076
|
-
return this.#byOpId.get(opId);
|
|
6077
|
-
}
|
|
6078
6184
|
/**
|
|
6079
6185
|
* Mark the given Op as still unacknowledged.
|
|
6080
6186
|
*/
|
|
@@ -6111,12 +6217,12 @@ ${parentKey}`;
|
|
|
6111
6217
|
if (isCreateOp(op)) {
|
|
6112
6218
|
const posKey = this.#posKey(op.parentId, op.parentKey);
|
|
6113
6219
|
const atPosition = this.#createOpsByPosition.get(posKey);
|
|
6114
|
-
_optionalChain([atPosition, 'optionalAccess',
|
|
6220
|
+
_optionalChain([atPosition, 'optionalAccess', _115 => _115.delete, 'call', _116 => _116(opId)]);
|
|
6115
6221
|
if (atPosition !== void 0 && atPosition.size === 0) {
|
|
6116
6222
|
this.#createOpsByPosition.delete(posKey);
|
|
6117
6223
|
}
|
|
6118
6224
|
const inParent = this.#createOpsByParent.get(op.parentId);
|
|
6119
|
-
_optionalChain([inParent, 'optionalAccess',
|
|
6225
|
+
_optionalChain([inParent, 'optionalAccess', _117 => _117.delete, 'call', _118 => _118(opId)]);
|
|
6120
6226
|
if (inParent !== void 0 && inParent.size === 0) {
|
|
6121
6227
|
this.#createOpsByParent.delete(op.parentId);
|
|
6122
6228
|
}
|
|
@@ -6128,14 +6234,14 @@ ${parentKey}`;
|
|
|
6128
6234
|
* Empty if none.
|
|
6129
6235
|
*/
|
|
6130
6236
|
getByParentIdAndKey(parentId, parentKey) {
|
|
6131
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
6237
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _119 => _119.#createOpsByPosition, 'access', _120 => _120.get, 'call', _121 => _121(this.#posKey(parentId, parentKey)), 'optionalAccess', _122 => _122.values, 'call', _123 => _123()]), () => ( []));
|
|
6132
6238
|
}
|
|
6133
6239
|
/**
|
|
6134
6240
|
* The still-unacknowledged Create ops with the given `parentId` (across all
|
|
6135
6241
|
* positions), in dispatch order. O(1) lookup. Empty if none.
|
|
6136
6242
|
*/
|
|
6137
6243
|
getByParentId(parentId) {
|
|
6138
|
-
return _nullishCoalesce(_optionalChain([this, 'access',
|
|
6244
|
+
return _nullishCoalesce(_optionalChain([this, 'access', _124 => _124.#createOpsByParent, 'access', _125 => _125.get, 'call', _126 => _126(parentId), 'optionalAccess', _127 => _127.values, 'call', _128 => _128()]), () => ( []));
|
|
6139
6245
|
}
|
|
6140
6246
|
/** All still-unacknowledged ops, in dispatch order. */
|
|
6141
6247
|
values() {
|
|
@@ -6175,8 +6281,8 @@ function createManagedPool(roomId, options) {
|
|
|
6175
6281
|
deleteNode: (id) => void nodes.delete(id),
|
|
6176
6282
|
generateId: () => `${getCurrentConnectionId()}:${clock++}`,
|
|
6177
6283
|
generateOpId: () => `${getCurrentConnectionId()}:${opClock++}`,
|
|
6178
|
-
dispatch(ops, reverse, storageUpdates
|
|
6179
|
-
_optionalChain([onDispatch, 'optionalCall',
|
|
6284
|
+
dispatch(ops, reverse, storageUpdates) {
|
|
6285
|
+
_optionalChain([onDispatch, 'optionalCall', _129 => _129(ops, reverse, storageUpdates)]);
|
|
6180
6286
|
},
|
|
6181
6287
|
assertStorageIsWritable: () => {
|
|
6182
6288
|
if (!isStorageWritable()) {
|
|
@@ -6900,7 +7006,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6900
7006
|
#applyInsertUndoRedo(op) {
|
|
6901
7007
|
const { id, parentKey: key } = op;
|
|
6902
7008
|
const child = creationOpToLiveNode(op);
|
|
6903
|
-
if (_optionalChain([this, 'access',
|
|
7009
|
+
if (_optionalChain([this, 'access', _130 => _130._pool, 'optionalAccess', _131 => _131.getNode, 'call', _132 => _132(id)]) !== void 0) {
|
|
6904
7010
|
return { modified: false };
|
|
6905
7011
|
}
|
|
6906
7012
|
child._attach(id, nn(this._pool));
|
|
@@ -6908,8 +7014,8 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6908
7014
|
const existingItemIndex = this._indexOfPosition(key);
|
|
6909
7015
|
let newKey = key;
|
|
6910
7016
|
if (existingItemIndex !== -1) {
|
|
6911
|
-
const before2 = _optionalChain([this, 'access',
|
|
6912
|
-
const after2 = _optionalChain([this, 'access',
|
|
7017
|
+
const before2 = _optionalChain([this, 'access', _133 => _133.#items, 'access', _134 => _134.at, 'call', _135 => _135(existingItemIndex), 'optionalAccess', _136 => _136._parentPos]);
|
|
7018
|
+
const after2 = _optionalChain([this, 'access', _137 => _137.#items, 'access', _138 => _138.at, 'call', _139 => _139(existingItemIndex + 1), 'optionalAccess', _140 => _140._parentPos]);
|
|
6913
7019
|
newKey = makePosition(before2, after2);
|
|
6914
7020
|
child._setParentLink(this, newKey);
|
|
6915
7021
|
}
|
|
@@ -6923,7 +7029,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
6923
7029
|
#applySetUndoRedo(op) {
|
|
6924
7030
|
const { id, parentKey: key } = op;
|
|
6925
7031
|
const child = creationOpToLiveNode(op);
|
|
6926
|
-
if (_optionalChain([this, 'access',
|
|
7032
|
+
if (_optionalChain([this, 'access', _141 => _141._pool, 'optionalAccess', _142 => _142.getNode, 'call', _143 => _143(id)]) !== void 0) {
|
|
6927
7033
|
return { modified: false };
|
|
6928
7034
|
}
|
|
6929
7035
|
const indexOfItemWithSameKey = this._indexOfPosition(key);
|
|
@@ -7044,7 +7150,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7044
7150
|
} else {
|
|
7045
7151
|
this.#updateItemPositionAt(
|
|
7046
7152
|
existingItemIndex,
|
|
7047
|
-
makePosition(newKey, _optionalChain([this, 'access',
|
|
7153
|
+
makePosition(newKey, _optionalChain([this, 'access', _144 => _144.#items, 'access', _145 => _145.at, 'call', _146 => _146(existingItemIndex + 1), 'optionalAccess', _147 => _147._parentPos]))
|
|
7048
7154
|
);
|
|
7049
7155
|
const previousIndex = this.#items.findIndex((item) => item === child);
|
|
7050
7156
|
this.#updateItemPosition(child, newKey);
|
|
@@ -7071,7 +7177,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7071
7177
|
this,
|
|
7072
7178
|
makePosition(
|
|
7073
7179
|
newKey,
|
|
7074
|
-
_optionalChain([this, 'access',
|
|
7180
|
+
_optionalChain([this, 'access', _148 => _148.#items, 'access', _149 => _149.at, 'call', _150 => _150(existingItemIndex + 1), 'optionalAccess', _151 => _151._parentPos])
|
|
7075
7181
|
)
|
|
7076
7182
|
);
|
|
7077
7183
|
this.#items.reposition(existingItem);
|
|
@@ -7095,7 +7201,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7095
7201
|
existingItemIndex,
|
|
7096
7202
|
makePosition(
|
|
7097
7203
|
newKey,
|
|
7098
|
-
_optionalChain([this, 'access',
|
|
7204
|
+
_optionalChain([this, 'access', _152 => _152.#items, 'access', _153 => _153.at, 'call', _154 => _154(existingItemIndex + 1), 'optionalAccess', _155 => _155._parentPos])
|
|
7099
7205
|
)
|
|
7100
7206
|
);
|
|
7101
7207
|
}
|
|
@@ -7123,7 +7229,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7123
7229
|
if (existingItemIndex !== -1) {
|
|
7124
7230
|
actualNewKey = makePosition(
|
|
7125
7231
|
newKey,
|
|
7126
|
-
_optionalChain([this, 'access',
|
|
7232
|
+
_optionalChain([this, 'access', _156 => _156.#items, 'access', _157 => _157.at, 'call', _158 => _158(existingItemIndex + 1), 'optionalAccess', _159 => _159._parentPos])
|
|
7127
7233
|
);
|
|
7128
7234
|
}
|
|
7129
7235
|
this.#updateItemPosition(child, actualNewKey);
|
|
@@ -7197,14 +7303,14 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7197
7303
|
* instead of resolving its position against the client's stale view.
|
|
7198
7304
|
*/
|
|
7199
7305
|
#injectAt(element, index, intent) {
|
|
7200
|
-
_optionalChain([this, 'access',
|
|
7306
|
+
_optionalChain([this, 'access', _160 => _160._pool, 'optionalAccess', _161 => _161.assertStorageIsWritable, 'call', _162 => _162()]);
|
|
7201
7307
|
if (index < 0 || index > this.#items.length) {
|
|
7202
7308
|
throw new Error(
|
|
7203
7309
|
`Cannot insert list item at index "${index}". index should be between 0 and ${this.#items.length}`
|
|
7204
7310
|
);
|
|
7205
7311
|
}
|
|
7206
|
-
const before2 = _optionalChain([this, 'access',
|
|
7207
|
-
const after2 = _optionalChain([this, 'access',
|
|
7312
|
+
const before2 = _optionalChain([this, 'access', _163 => _163.#items, 'access', _164 => _164.at, 'call', _165 => _165(index - 1), 'optionalAccess', _166 => _166._parentPos]);
|
|
7313
|
+
const after2 = _optionalChain([this, 'access', _167 => _167.#items, 'access', _168 => _168.at, 'call', _169 => _169(index), 'optionalAccess', _170 => _170._parentPos]);
|
|
7208
7314
|
const position = makePosition(before2, after2);
|
|
7209
7315
|
const value = lsonToLiveNode(element);
|
|
7210
7316
|
value._setParentLink(this, position);
|
|
@@ -7228,7 +7334,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7228
7334
|
* @param targetIndex The index where the element should be after moving.
|
|
7229
7335
|
*/
|
|
7230
7336
|
move(index, targetIndex) {
|
|
7231
|
-
_optionalChain([this, 'access',
|
|
7337
|
+
_optionalChain([this, 'access', _171 => _171._pool, 'optionalAccess', _172 => _172.assertStorageIsWritable, 'call', _173 => _173()]);
|
|
7232
7338
|
if (targetIndex < 0) {
|
|
7233
7339
|
throw new Error("targetIndex cannot be less than 0");
|
|
7234
7340
|
}
|
|
@@ -7246,11 +7352,11 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7246
7352
|
let beforePosition = null;
|
|
7247
7353
|
let afterPosition = null;
|
|
7248
7354
|
if (index < targetIndex) {
|
|
7249
|
-
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access',
|
|
7355
|
+
afterPosition = targetIndex === this.#items.length - 1 ? void 0 : _optionalChain([this, 'access', _174 => _174.#items, 'access', _175 => _175.at, 'call', _176 => _176(targetIndex + 1), 'optionalAccess', _177 => _177._parentPos]);
|
|
7250
7356
|
beforePosition = this.#items.at(targetIndex)._parentPos;
|
|
7251
7357
|
} else {
|
|
7252
7358
|
afterPosition = this.#items.at(targetIndex)._parentPos;
|
|
7253
|
-
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access',
|
|
7359
|
+
beforePosition = targetIndex === 0 ? void 0 : _optionalChain([this, 'access', _178 => _178.#items, 'access', _179 => _179.at, 'call', _180 => _180(targetIndex - 1), 'optionalAccess', _181 => _181._parentPos]);
|
|
7254
7360
|
}
|
|
7255
7361
|
const position = makePosition(beforePosition, afterPosition);
|
|
7256
7362
|
const item = this.#items.at(index);
|
|
@@ -7285,7 +7391,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7285
7391
|
* @param index The index of the element to delete
|
|
7286
7392
|
*/
|
|
7287
7393
|
delete(index) {
|
|
7288
|
-
_optionalChain([this, 'access',
|
|
7394
|
+
_optionalChain([this, 'access', _182 => _182._pool, 'optionalAccess', _183 => _183.assertStorageIsWritable, 'call', _184 => _184()]);
|
|
7289
7395
|
if (index < 0 || index >= this.#items.length) {
|
|
7290
7396
|
throw new Error(
|
|
7291
7397
|
`Cannot delete list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -7318,7 +7424,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7318
7424
|
}
|
|
7319
7425
|
}
|
|
7320
7426
|
clear() {
|
|
7321
|
-
_optionalChain([this, 'access',
|
|
7427
|
+
_optionalChain([this, 'access', _185 => _185._pool, 'optionalAccess', _186 => _186.assertStorageIsWritable, 'call', _187 => _187()]);
|
|
7322
7428
|
if (this._pool) {
|
|
7323
7429
|
const ops = [];
|
|
7324
7430
|
const reverseOps = [];
|
|
@@ -7352,7 +7458,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7352
7458
|
}
|
|
7353
7459
|
}
|
|
7354
7460
|
set(index, item) {
|
|
7355
|
-
_optionalChain([this, 'access',
|
|
7461
|
+
_optionalChain([this, 'access', _188 => _188._pool, 'optionalAccess', _189 => _189.assertStorageIsWritable, 'call', _190 => _190()]);
|
|
7356
7462
|
if (index < 0 || index >= this.#items.length) {
|
|
7357
7463
|
throw new Error(
|
|
7358
7464
|
`Cannot set list item at index "${index}". index should be between 0 and ${this.#items.length - 1}`
|
|
@@ -7511,7 +7617,7 @@ var LiveList = class _LiveList extends AbstractCrdt {
|
|
|
7511
7617
|
#shiftItemPosition(index, key) {
|
|
7512
7618
|
const shiftedPosition = makePosition(
|
|
7513
7619
|
key,
|
|
7514
|
-
this.#items.length > index + 1 ? _optionalChain([this, 'access',
|
|
7620
|
+
this.#items.length > index + 1 ? _optionalChain([this, 'access', _191 => _191.#items, 'access', _192 => _192.at, 'call', _193 => _193(index + 1), 'optionalAccess', _194 => _194._parentPos]) : void 0
|
|
7515
7621
|
);
|
|
7516
7622
|
this.#updateItemPositionAt(index, shiftedPosition);
|
|
7517
7623
|
}
|
|
@@ -7760,7 +7866,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7760
7866
|
* @param value The value of the element to add. Should be serializable to JSON.
|
|
7761
7867
|
*/
|
|
7762
7868
|
set(key, value) {
|
|
7763
|
-
_optionalChain([this, 'access',
|
|
7869
|
+
_optionalChain([this, 'access', _195 => _195._pool, 'optionalAccess', _196 => _196.assertStorageIsWritable, 'call', _197 => _197()]);
|
|
7764
7870
|
const oldValue = this.#map.get(key);
|
|
7765
7871
|
if (oldValue) {
|
|
7766
7872
|
oldValue._detach();
|
|
@@ -7806,7 +7912,7 @@ var LiveMap = class _LiveMap extends AbstractCrdt {
|
|
|
7806
7912
|
* @returns true if an element existed and has been removed, or false if the element does not exist.
|
|
7807
7913
|
*/
|
|
7808
7914
|
delete(key) {
|
|
7809
|
-
_optionalChain([this, 'access',
|
|
7915
|
+
_optionalChain([this, 'access', _198 => _198._pool, 'optionalAccess', _199 => _199.assertStorageIsWritable, 'call', _200 => _200()]);
|
|
7810
7916
|
const item = this.#map.get(key);
|
|
7811
7917
|
if (item === void 0) {
|
|
7812
7918
|
return false;
|
|
@@ -8418,20 +8524,20 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8418
8524
|
* Caveat: this method will not add changes to the undo/redo stack.
|
|
8419
8525
|
*/
|
|
8420
8526
|
setLocal(key, value) {
|
|
8421
|
-
_optionalChain([this, 'access',
|
|
8527
|
+
_optionalChain([this, 'access', _201 => _201._pool, 'optionalAccess', _202 => _202.assertStorageIsWritable, 'call', _203 => _203()]);
|
|
8422
8528
|
const deleteResult = this.#prepareDelete(key);
|
|
8423
8529
|
this.#local.set(key, value);
|
|
8424
8530
|
this.invalidate();
|
|
8425
8531
|
if (this._pool !== void 0 && this._id !== void 0) {
|
|
8426
|
-
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8427
|
-
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8428
|
-
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess',
|
|
8532
|
+
const ops = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _204 => _204[0]]), () => ( []));
|
|
8533
|
+
const reverse = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _205 => _205[1]]), () => ( []));
|
|
8534
|
+
const storageUpdates = _nullishCoalesce(_optionalChain([deleteResult, 'optionalAccess', _206 => _206[2]]), () => ( /* @__PURE__ */ new Map()));
|
|
8429
8535
|
const existing = storageUpdates.get(this._id);
|
|
8430
8536
|
storageUpdates.set(this._id, {
|
|
8431
8537
|
node: this,
|
|
8432
8538
|
type: "LiveObject",
|
|
8433
8539
|
updates: {
|
|
8434
|
-
..._optionalChain([existing, 'optionalAccess',
|
|
8540
|
+
..._optionalChain([existing, 'optionalAccess', _207 => _207.updates]),
|
|
8435
8541
|
[key]: { type: "update" }
|
|
8436
8542
|
}
|
|
8437
8543
|
});
|
|
@@ -8451,7 +8557,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8451
8557
|
* #synced or pool/id are unavailable. Does NOT dispatch.
|
|
8452
8558
|
*/
|
|
8453
8559
|
#prepareDelete(key) {
|
|
8454
|
-
_optionalChain([this, 'access',
|
|
8560
|
+
_optionalChain([this, 'access', _208 => _208._pool, 'optionalAccess', _209 => _209.assertStorageIsWritable, 'call', _210 => _210()]);
|
|
8455
8561
|
const k = key;
|
|
8456
8562
|
if (this.#local.has(k) && !this.#synced.has(k)) {
|
|
8457
8563
|
const oldValue2 = this.#local.get(k);
|
|
@@ -8527,7 +8633,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8527
8633
|
const result = this.#prepareDelete(key);
|
|
8528
8634
|
if (result) {
|
|
8529
8635
|
const [ops, reverse, storageUpdates] = result;
|
|
8530
|
-
_optionalChain([this, 'access',
|
|
8636
|
+
_optionalChain([this, 'access', _211 => _211._pool, 'optionalAccess', _212 => _212.dispatch, 'call', _213 => _213(ops, reverse, storageUpdates)]);
|
|
8531
8637
|
}
|
|
8532
8638
|
}
|
|
8533
8639
|
/**
|
|
@@ -8535,7 +8641,7 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8535
8641
|
* @param patch The object used to overrides properties
|
|
8536
8642
|
*/
|
|
8537
8643
|
update(patch) {
|
|
8538
|
-
_optionalChain([this, 'access',
|
|
8644
|
+
_optionalChain([this, 'access', _214 => _214._pool, 'optionalAccess', _215 => _215.assertStorageIsWritable, 'call', _216 => _216()]);
|
|
8539
8645
|
if (_LiveObject.detectLargeObjects) {
|
|
8540
8646
|
const data = {};
|
|
8541
8647
|
for (const [key, value] of this.#synced) {
|
|
@@ -8735,1105 +8841,6 @@ var LiveObject = (_class2 = class _LiveObject extends AbstractCrdt {
|
|
|
8735
8841
|
}
|
|
8736
8842
|
}, _class2.__initStatic(), _class2);
|
|
8737
8843
|
|
|
8738
|
-
// src/crdts/liveTextOps.ts
|
|
8739
|
-
function attributesEqual(left, right) {
|
|
8740
|
-
if (left === right) {
|
|
8741
|
-
return true;
|
|
8742
|
-
}
|
|
8743
|
-
if (left === void 0 || right === void 0) {
|
|
8744
|
-
return false;
|
|
8745
|
-
}
|
|
8746
|
-
const leftKeys = Object.keys(left);
|
|
8747
|
-
const rightKeys = Object.keys(right);
|
|
8748
|
-
if (leftKeys.length !== rightKeys.length) {
|
|
8749
|
-
return false;
|
|
8750
|
-
}
|
|
8751
|
-
for (const key of leftKeys) {
|
|
8752
|
-
if (left[key] !== right[key]) {
|
|
8753
|
-
return false;
|
|
8754
|
-
}
|
|
8755
|
-
}
|
|
8756
|
-
return true;
|
|
8757
|
-
}
|
|
8758
|
-
function cloneAttributes(attributes) {
|
|
8759
|
-
return attributes === void 0 ? void 0 : freeze({ ...attributes });
|
|
8760
|
-
}
|
|
8761
|
-
function normalizeSegments(segments) {
|
|
8762
|
-
const normalized = [];
|
|
8763
|
-
for (const segment of segments) {
|
|
8764
|
-
if (segment.text.length === 0) {
|
|
8765
|
-
continue;
|
|
8766
|
-
}
|
|
8767
|
-
const last = normalized.at(-1);
|
|
8768
|
-
const attributes = cloneAttributes(segment.attributes);
|
|
8769
|
-
if (last !== void 0 && attributesEqual(last.attributes, attributes)) {
|
|
8770
|
-
last.text += segment.text;
|
|
8771
|
-
} else {
|
|
8772
|
-
normalized.push({ text: segment.text, attributes });
|
|
8773
|
-
}
|
|
8774
|
-
}
|
|
8775
|
-
return normalized;
|
|
8776
|
-
}
|
|
8777
|
-
function dataToSegments(data) {
|
|
8778
|
-
return normalizeSegments(
|
|
8779
|
-
data.map(([text, attributes]) => ({
|
|
8780
|
-
text,
|
|
8781
|
-
attributes
|
|
8782
|
-
}))
|
|
8783
|
-
);
|
|
8784
|
-
}
|
|
8785
|
-
function segmentsToData(segments) {
|
|
8786
|
-
return segments.map(
|
|
8787
|
-
(segment) => segment.attributes === void 0 ? [segment.text] : [segment.text, { ...segment.attributes }]
|
|
8788
|
-
);
|
|
8789
|
-
}
|
|
8790
|
-
function textLength(segments) {
|
|
8791
|
-
return segments.reduce((sum, segment) => sum + segment.text.length, 0);
|
|
8792
|
-
}
|
|
8793
|
-
function splitSegmentsAt(segments, index) {
|
|
8794
|
-
const result = [];
|
|
8795
|
-
let offset = 0;
|
|
8796
|
-
for (const segment of segments) {
|
|
8797
|
-
const end = offset + segment.text.length;
|
|
8798
|
-
if (index > offset && index < end) {
|
|
8799
|
-
const before2 = segment.text.slice(0, index - offset);
|
|
8800
|
-
const after2 = segment.text.slice(index - offset);
|
|
8801
|
-
result.push({ text: before2, attributes: segment.attributes });
|
|
8802
|
-
result.push({ text: after2, attributes: segment.attributes });
|
|
8803
|
-
} else {
|
|
8804
|
-
result.push({ text: segment.text, attributes: segment.attributes });
|
|
8805
|
-
}
|
|
8806
|
-
offset = end;
|
|
8807
|
-
}
|
|
8808
|
-
return result;
|
|
8809
|
-
}
|
|
8810
|
-
function clipRange(index, length, contentLength) {
|
|
8811
|
-
const clippedIndex = Math.max(0, Math.min(index, contentLength));
|
|
8812
|
-
const clippedEnd = Math.max(
|
|
8813
|
-
clippedIndex,
|
|
8814
|
-
Math.min(index + length, contentLength)
|
|
8815
|
-
);
|
|
8816
|
-
return { index: clippedIndex, length: clippedEnd - clippedIndex };
|
|
8817
|
-
}
|
|
8818
|
-
function applyInsert(segments, index, text, attributes) {
|
|
8819
|
-
if (text.length === 0) {
|
|
8820
|
-
return normalizeSegments(segments);
|
|
8821
|
-
}
|
|
8822
|
-
const split = splitSegmentsAt(segments, index);
|
|
8823
|
-
const result = [];
|
|
8824
|
-
let offset = 0;
|
|
8825
|
-
let inserted = false;
|
|
8826
|
-
for (const segment of split) {
|
|
8827
|
-
if (!inserted && offset === index) {
|
|
8828
|
-
result.push({ text, attributes });
|
|
8829
|
-
inserted = true;
|
|
8830
|
-
}
|
|
8831
|
-
result.push(segment);
|
|
8832
|
-
offset += segment.text.length;
|
|
8833
|
-
}
|
|
8834
|
-
if (!inserted) {
|
|
8835
|
-
result.push({ text, attributes });
|
|
8836
|
-
}
|
|
8837
|
-
return normalizeSegments(result);
|
|
8838
|
-
}
|
|
8839
|
-
function extractDeletedSegments(segments, index, length) {
|
|
8840
|
-
const split = splitSegmentsAt(
|
|
8841
|
-
splitSegmentsAt(segments, index),
|
|
8842
|
-
index + length
|
|
8843
|
-
);
|
|
8844
|
-
const deleted = [];
|
|
8845
|
-
let offset = 0;
|
|
8846
|
-
for (const segment of split) {
|
|
8847
|
-
const end = offset + segment.text.length;
|
|
8848
|
-
if (offset >= index && end <= index + length) {
|
|
8849
|
-
deleted.push({
|
|
8850
|
-
text: segment.text,
|
|
8851
|
-
attributes: segment.attributes
|
|
8852
|
-
});
|
|
8853
|
-
}
|
|
8854
|
-
offset = end;
|
|
8855
|
-
}
|
|
8856
|
-
return normalizeSegments(deleted);
|
|
8857
|
-
}
|
|
8858
|
-
function applyDelete(segments, index, length) {
|
|
8859
|
-
const deletedSegments = extractDeletedSegments(segments, index, length);
|
|
8860
|
-
const split = splitSegmentsAt(
|
|
8861
|
-
splitSegmentsAt(segments, index),
|
|
8862
|
-
index + length
|
|
8863
|
-
);
|
|
8864
|
-
const result = [];
|
|
8865
|
-
let offset = 0;
|
|
8866
|
-
let deletedText = "";
|
|
8867
|
-
for (const segment of split) {
|
|
8868
|
-
const end = offset + segment.text.length;
|
|
8869
|
-
if (offset >= index && end <= index + length) {
|
|
8870
|
-
deletedText += segment.text;
|
|
8871
|
-
} else {
|
|
8872
|
-
result.push(segment);
|
|
8873
|
-
}
|
|
8874
|
-
offset = end;
|
|
8875
|
-
}
|
|
8876
|
-
return {
|
|
8877
|
-
segments: normalizeSegments(result),
|
|
8878
|
-
deletedText,
|
|
8879
|
-
deletedSegments
|
|
8880
|
-
};
|
|
8881
|
-
}
|
|
8882
|
-
function applyFormat(segments, index, length, attributes) {
|
|
8883
|
-
const split = splitSegmentsAt(
|
|
8884
|
-
splitSegmentsAt(segments, index),
|
|
8885
|
-
index + length
|
|
8886
|
-
);
|
|
8887
|
-
const result = [];
|
|
8888
|
-
let offset = 0;
|
|
8889
|
-
for (const segment of split) {
|
|
8890
|
-
const end = offset + segment.text.length;
|
|
8891
|
-
if (offset >= index && end <= index + length) {
|
|
8892
|
-
const nextAttributes = {
|
|
8893
|
-
..._nullishCoalesce(segment.attributes, () => ( {}))
|
|
8894
|
-
};
|
|
8895
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
8896
|
-
if (value === null) {
|
|
8897
|
-
delete nextAttributes[key];
|
|
8898
|
-
} else {
|
|
8899
|
-
nextAttributes[key] = value;
|
|
8900
|
-
}
|
|
8901
|
-
}
|
|
8902
|
-
result.push({
|
|
8903
|
-
text: segment.text,
|
|
8904
|
-
attributes: Object.keys(nextAttributes).length === 0 ? void 0 : freeze(nextAttributes)
|
|
8905
|
-
});
|
|
8906
|
-
} else {
|
|
8907
|
-
result.push(segment);
|
|
8908
|
-
}
|
|
8909
|
-
offset = end;
|
|
8910
|
-
}
|
|
8911
|
-
return normalizeSegments(result);
|
|
8912
|
-
}
|
|
8913
|
-
function formatReverseOperations(segments, index, length, patch) {
|
|
8914
|
-
const split = splitSegmentsAt(
|
|
8915
|
-
splitSegmentsAt(segments, index),
|
|
8916
|
-
index + length
|
|
8917
|
-
);
|
|
8918
|
-
const result = [];
|
|
8919
|
-
let offset = 0;
|
|
8920
|
-
for (const segment of split) {
|
|
8921
|
-
const end = offset + segment.text.length;
|
|
8922
|
-
if (offset >= index && end <= index + length) {
|
|
8923
|
-
const attributes = {};
|
|
8924
|
-
for (const key of Object.keys(patch)) {
|
|
8925
|
-
attributes[key] = _nullishCoalesce(_optionalChain([segment, 'access', _214 => _214.attributes, 'optionalAccess', _215 => _215[key]]), () => ( null));
|
|
8926
|
-
}
|
|
8927
|
-
result.push({
|
|
8928
|
-
type: "format",
|
|
8929
|
-
index: offset,
|
|
8930
|
-
length: segment.text.length,
|
|
8931
|
-
attributes
|
|
8932
|
-
});
|
|
8933
|
-
}
|
|
8934
|
-
offset = end;
|
|
8935
|
-
}
|
|
8936
|
-
return result;
|
|
8937
|
-
}
|
|
8938
|
-
function mapIndexThroughOperation(index, op) {
|
|
8939
|
-
if (op.type === "insert") {
|
|
8940
|
-
return op.index <= index ? index + op.text.length : index;
|
|
8941
|
-
} else if (op.type === "delete") {
|
|
8942
|
-
if (op.index >= index) {
|
|
8943
|
-
return index;
|
|
8944
|
-
}
|
|
8945
|
-
return Math.max(op.index, index - op.length);
|
|
8946
|
-
} else {
|
|
8947
|
-
return index;
|
|
8948
|
-
}
|
|
8949
|
-
}
|
|
8950
|
-
function mapTextIndexThroughOperations(index, ops) {
|
|
8951
|
-
let mapped = index;
|
|
8952
|
-
for (const op of ops) {
|
|
8953
|
-
mapped = mapIndexThroughOperation(mapped, op);
|
|
8954
|
-
}
|
|
8955
|
-
return mapped;
|
|
8956
|
-
}
|
|
8957
|
-
function inverseMapIndexThroughOperation(index, op) {
|
|
8958
|
-
if (op.type === "insert") {
|
|
8959
|
-
if (index <= op.index) {
|
|
8960
|
-
return index;
|
|
8961
|
-
}
|
|
8962
|
-
return Math.max(op.index, index - op.text.length);
|
|
8963
|
-
} else if (op.type === "delete") {
|
|
8964
|
-
return op.index <= index ? index + op.length : index;
|
|
8965
|
-
} else {
|
|
8966
|
-
return index;
|
|
8967
|
-
}
|
|
8968
|
-
}
|
|
8969
|
-
function inverseMapTextIndexThroughOperations(index, ops) {
|
|
8970
|
-
let mapped = index;
|
|
8971
|
-
for (let i = ops.length - 1; i >= 0; i--) {
|
|
8972
|
-
mapped = inverseMapIndexThroughOperation(mapped, ops[i]);
|
|
8973
|
-
}
|
|
8974
|
-
return mapped;
|
|
8975
|
-
}
|
|
8976
|
-
function oppositeOrder(order) {
|
|
8977
|
-
return order === "before" ? "after" : "before";
|
|
8978
|
-
}
|
|
8979
|
-
function mapIndexOverDelete(index, deleteIndex, deleteLength) {
|
|
8980
|
-
if (deleteIndex >= index) {
|
|
8981
|
-
return index;
|
|
8982
|
-
}
|
|
8983
|
-
return Math.max(deleteIndex, index - deleteLength);
|
|
8984
|
-
}
|
|
8985
|
-
function transformInsert(op, over, order) {
|
|
8986
|
-
if (over.type === "insert") {
|
|
8987
|
-
const shifts = over.index < op.index || over.index === op.index && order === "after";
|
|
8988
|
-
return [shifts ? { ...op, index: op.index + over.text.length } : { ...op }];
|
|
8989
|
-
} else if (over.type === "delete") {
|
|
8990
|
-
return [
|
|
8991
|
-
{ ...op, index: mapIndexOverDelete(op.index, over.index, over.length) }
|
|
8992
|
-
];
|
|
8993
|
-
} else {
|
|
8994
|
-
return [{ ...op }];
|
|
8995
|
-
}
|
|
8996
|
-
}
|
|
8997
|
-
function transformDelete(op, over) {
|
|
8998
|
-
const start = op.index;
|
|
8999
|
-
const end = op.index + op.length;
|
|
9000
|
-
if (over.type === "insert") {
|
|
9001
|
-
const at = over.index;
|
|
9002
|
-
const len = over.text.length;
|
|
9003
|
-
if (at <= start) {
|
|
9004
|
-
return [{ ...op, index: start + len }];
|
|
9005
|
-
}
|
|
9006
|
-
if (at >= end) {
|
|
9007
|
-
return [{ ...op }];
|
|
9008
|
-
}
|
|
9009
|
-
return [
|
|
9010
|
-
{ type: "delete", index: start, length: at - start },
|
|
9011
|
-
{ type: "delete", index: start + len, length: end - at }
|
|
9012
|
-
];
|
|
9013
|
-
} else if (over.type === "delete") {
|
|
9014
|
-
const newStart = mapIndexOverDelete(start, over.index, over.length);
|
|
9015
|
-
const newEnd = mapIndexOverDelete(end, over.index, over.length);
|
|
9016
|
-
return newEnd - newStart > 0 ? [{ type: "delete", index: newStart, length: newEnd - newStart }] : [];
|
|
9017
|
-
} else {
|
|
9018
|
-
return [{ ...op }];
|
|
9019
|
-
}
|
|
9020
|
-
}
|
|
9021
|
-
function transformFormat(op, over, order) {
|
|
9022
|
-
const start = op.index;
|
|
9023
|
-
const end = op.index + op.length;
|
|
9024
|
-
if (over.type === "insert") {
|
|
9025
|
-
const at = over.index;
|
|
9026
|
-
const len = over.text.length;
|
|
9027
|
-
if (at <= start) {
|
|
9028
|
-
return [{ ...op, index: start + len }];
|
|
9029
|
-
}
|
|
9030
|
-
if (at >= end) {
|
|
9031
|
-
return [{ ...op }];
|
|
9032
|
-
}
|
|
9033
|
-
return [
|
|
9034
|
-
{
|
|
9035
|
-
type: "format",
|
|
9036
|
-
index: start,
|
|
9037
|
-
length: at - start,
|
|
9038
|
-
attributes: op.attributes
|
|
9039
|
-
},
|
|
9040
|
-
{
|
|
9041
|
-
type: "format",
|
|
9042
|
-
index: at + len,
|
|
9043
|
-
length: end - at,
|
|
9044
|
-
attributes: op.attributes
|
|
9045
|
-
}
|
|
9046
|
-
];
|
|
9047
|
-
} else if (over.type === "delete") {
|
|
9048
|
-
const newStart = mapIndexOverDelete(start, over.index, over.length);
|
|
9049
|
-
const newEnd = mapIndexOverDelete(end, over.index, over.length);
|
|
9050
|
-
return newEnd - newStart > 0 ? [
|
|
9051
|
-
{
|
|
9052
|
-
type: "format",
|
|
9053
|
-
index: newStart,
|
|
9054
|
-
length: newEnd - newStart,
|
|
9055
|
-
attributes: op.attributes
|
|
9056
|
-
}
|
|
9057
|
-
] : [];
|
|
9058
|
-
} else {
|
|
9059
|
-
if (order === "after") {
|
|
9060
|
-
return [{ ...op }];
|
|
9061
|
-
}
|
|
9062
|
-
const overlapStart = Math.max(start, over.index);
|
|
9063
|
-
const overlapEnd = Math.min(end, over.index + over.length);
|
|
9064
|
-
if (overlapStart >= overlapEnd) {
|
|
9065
|
-
return [{ ...op }];
|
|
9066
|
-
}
|
|
9067
|
-
const hasConflict = Object.keys(op.attributes).some(
|
|
9068
|
-
(key) => key in over.attributes
|
|
9069
|
-
);
|
|
9070
|
-
if (!hasConflict) {
|
|
9071
|
-
return [{ ...op }];
|
|
9072
|
-
}
|
|
9073
|
-
const reduced = {};
|
|
9074
|
-
for (const [key, value] of Object.entries(op.attributes)) {
|
|
9075
|
-
if (!(key in over.attributes)) {
|
|
9076
|
-
reduced[key] = value;
|
|
9077
|
-
}
|
|
9078
|
-
}
|
|
9079
|
-
const pieces = [];
|
|
9080
|
-
if (start < overlapStart) {
|
|
9081
|
-
pieces.push({
|
|
9082
|
-
type: "format",
|
|
9083
|
-
index: start,
|
|
9084
|
-
length: overlapStart - start,
|
|
9085
|
-
attributes: op.attributes
|
|
9086
|
-
});
|
|
9087
|
-
}
|
|
9088
|
-
if (Object.keys(reduced).length > 0) {
|
|
9089
|
-
pieces.push({
|
|
9090
|
-
type: "format",
|
|
9091
|
-
index: overlapStart,
|
|
9092
|
-
length: overlapEnd - overlapStart,
|
|
9093
|
-
attributes: reduced
|
|
9094
|
-
});
|
|
9095
|
-
}
|
|
9096
|
-
if (overlapEnd < end) {
|
|
9097
|
-
pieces.push({
|
|
9098
|
-
type: "format",
|
|
9099
|
-
index: overlapEnd,
|
|
9100
|
-
length: end - overlapEnd,
|
|
9101
|
-
attributes: op.attributes
|
|
9102
|
-
});
|
|
9103
|
-
}
|
|
9104
|
-
return pieces;
|
|
9105
|
-
}
|
|
9106
|
-
}
|
|
9107
|
-
function transformSingle(op, over, order) {
|
|
9108
|
-
switch (op.type) {
|
|
9109
|
-
case "insert":
|
|
9110
|
-
return transformInsert(op, over, order);
|
|
9111
|
-
case "delete":
|
|
9112
|
-
return transformDelete(op, over);
|
|
9113
|
-
case "format":
|
|
9114
|
-
return transformFormat(op, over, order);
|
|
9115
|
-
}
|
|
9116
|
-
}
|
|
9117
|
-
function transformTextOperationsX(a, b, order) {
|
|
9118
|
-
if (a.length === 0 || b.length === 0) {
|
|
9119
|
-
return [[...a], [...b]];
|
|
9120
|
-
}
|
|
9121
|
-
if (a.length === 1 && b.length === 1) {
|
|
9122
|
-
return [
|
|
9123
|
-
transformSingle(a[0], b[0], order),
|
|
9124
|
-
transformSingle(b[0], a[0], oppositeOrder(order))
|
|
9125
|
-
];
|
|
9126
|
-
}
|
|
9127
|
-
if (a.length > 1) {
|
|
9128
|
-
const [headA1, b1] = transformTextOperationsX([a[0]], b, order);
|
|
9129
|
-
const [restA1, b2] = transformTextOperationsX(a.slice(1), b1, order);
|
|
9130
|
-
return [[...headA1, ...restA1], b2];
|
|
9131
|
-
}
|
|
9132
|
-
const [a1, headB1] = transformTextOperationsX(a, [b[0]], order);
|
|
9133
|
-
const [a2, restB1] = transformTextOperationsX(a1, b.slice(1), order);
|
|
9134
|
-
return [a2, [...headB1, ...restB1]];
|
|
9135
|
-
}
|
|
9136
|
-
function transformTextOperations(ops, over, order) {
|
|
9137
|
-
return transformTextOperationsX(ops, over, order)[0];
|
|
9138
|
-
}
|
|
9139
|
-
function textOperationsEqual(a, b) {
|
|
9140
|
-
return a === b || stableStringify(a) === stableStringify(b);
|
|
9141
|
-
}
|
|
9142
|
-
function applyTextOperationsToSegments(segments, ops) {
|
|
9143
|
-
let next = [...segments];
|
|
9144
|
-
for (const op of ops) {
|
|
9145
|
-
if (op.type === "insert") {
|
|
9146
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9147
|
-
next = applyInsert(next, index, op.text, op.attributes);
|
|
9148
|
-
} else if (op.type === "delete") {
|
|
9149
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9150
|
-
const clipped = clipRange(index, op.length, textLength(next));
|
|
9151
|
-
next = applyDelete(next, clipped.index, clipped.length).segments;
|
|
9152
|
-
} else {
|
|
9153
|
-
const index = Math.max(0, Math.min(op.index, textLength(next)));
|
|
9154
|
-
const clipped = clipRange(index, op.length, textLength(next));
|
|
9155
|
-
next = applyFormat(next, clipped.index, clipped.length, op.attributes);
|
|
9156
|
-
}
|
|
9157
|
-
}
|
|
9158
|
-
return next;
|
|
9159
|
-
}
|
|
9160
|
-
function applyLiveTextOperations(data, ops) {
|
|
9161
|
-
return segmentsToData(
|
|
9162
|
-
applyTextOperationsToSegments(dataToSegments(data), ops)
|
|
9163
|
-
);
|
|
9164
|
-
}
|
|
9165
|
-
function invertTextOperations(segments, ops) {
|
|
9166
|
-
let shadow = [...segments];
|
|
9167
|
-
const reverse = [];
|
|
9168
|
-
for (const op of ops) {
|
|
9169
|
-
if (op.type === "insert") {
|
|
9170
|
-
shadow = applyInsert(shadow, op.index, op.text, op.attributes);
|
|
9171
|
-
reverse.unshift({
|
|
9172
|
-
type: "delete",
|
|
9173
|
-
index: op.index,
|
|
9174
|
-
length: op.text.length
|
|
9175
|
-
});
|
|
9176
|
-
} else if (op.type === "delete") {
|
|
9177
|
-
const deletedSegments = extractDeletedSegments(
|
|
9178
|
-
shadow,
|
|
9179
|
-
op.index,
|
|
9180
|
-
op.length
|
|
9181
|
-
);
|
|
9182
|
-
shadow = applyDelete(shadow, op.index, op.length).segments;
|
|
9183
|
-
const inserts = [];
|
|
9184
|
-
let insertIndex = op.index;
|
|
9185
|
-
for (const segment of deletedSegments) {
|
|
9186
|
-
inserts.push({
|
|
9187
|
-
type: "insert",
|
|
9188
|
-
index: insertIndex,
|
|
9189
|
-
text: segment.text,
|
|
9190
|
-
attributes: segment.attributes
|
|
9191
|
-
});
|
|
9192
|
-
insertIndex += segment.text.length;
|
|
9193
|
-
}
|
|
9194
|
-
for (let index = inserts.length - 1; index >= 0; index--) {
|
|
9195
|
-
reverse.unshift(inserts[index]);
|
|
9196
|
-
}
|
|
9197
|
-
} else {
|
|
9198
|
-
const inverse = formatReverseOperations(
|
|
9199
|
-
shadow,
|
|
9200
|
-
op.index,
|
|
9201
|
-
op.length,
|
|
9202
|
-
op.attributes
|
|
9203
|
-
);
|
|
9204
|
-
shadow = applyFormat(shadow, op.index, op.length, op.attributes);
|
|
9205
|
-
reverse.unshift(...inverse.reverse());
|
|
9206
|
-
}
|
|
9207
|
-
}
|
|
9208
|
-
return reverse;
|
|
9209
|
-
}
|
|
9210
|
-
|
|
9211
|
-
// src/crdts/LiveText.ts
|
|
9212
|
-
var ACCEPTED_OPS_HISTORY_LIMIT = 1e3;
|
|
9213
|
-
var LiveText = class _LiveText extends AbstractCrdt {
|
|
9214
|
-
/** The local document: #confirmed ⊕ #inFlightOps ⊕ #queuedOps. */
|
|
9215
|
-
#segments;
|
|
9216
|
-
/** The server-confirmed document (only authoritative ops applied). */
|
|
9217
|
-
#confirmed;
|
|
9218
|
-
#version;
|
|
9219
|
-
/** The op currently awaiting server acknowledgement (at most one). */
|
|
9220
|
-
#inFlightOpId;
|
|
9221
|
-
/** Its ops, continuously re-expressed against current server state. */
|
|
9222
|
-
#inFlightOps = [];
|
|
9223
|
-
/** Local edits made while an op is in flight; sent after the ack. */
|
|
9224
|
-
#queuedOps = [];
|
|
9225
|
-
#acceptedOps = [];
|
|
9226
|
-
/**
|
|
9227
|
-
* Creates a new LiveText document.
|
|
9228
|
-
*
|
|
9229
|
-
* @param textOrData Initial plain text, or an array of `[text]` /
|
|
9230
|
-
* `[text, attributes]` segments. Defaults to an empty document.
|
|
9231
|
-
*
|
|
9232
|
-
* @example
|
|
9233
|
-
* new LiveText();
|
|
9234
|
-
* new LiveText("Hello world");
|
|
9235
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]);
|
|
9236
|
-
*/
|
|
9237
|
-
constructor(textOrData = "", version = 0) {
|
|
9238
|
-
super();
|
|
9239
|
-
this.#segments = typeof textOrData === "string" ? textOrData.length === 0 ? [] : [{ text: textOrData }] : dataToSegments(textOrData);
|
|
9240
|
-
this.#confirmed = [...this.#segments];
|
|
9241
|
-
this.#version = version;
|
|
9242
|
-
Object.defineProperty(this, kInternal, {
|
|
9243
|
-
value: {
|
|
9244
|
-
encodeIndex: (localIndex) => this.#encodeIndex(localIndex),
|
|
9245
|
-
decodeIndex: (index, fromVersion) => this.#decodeIndex(index, fromVersion)
|
|
9246
|
-
},
|
|
9247
|
-
enumerable: false
|
|
9248
|
-
});
|
|
9249
|
-
}
|
|
9250
|
-
get version() {
|
|
9251
|
-
return this.#version;
|
|
9252
|
-
}
|
|
9253
|
-
get length() {
|
|
9254
|
-
return textLength(this.#segments);
|
|
9255
|
-
}
|
|
9256
|
-
/** @internal */
|
|
9257
|
-
static _deserialize([id, item], _parentToChildren, pool) {
|
|
9258
|
-
const text = new _LiveText(item.data, item.version);
|
|
9259
|
-
text._attach(id, pool);
|
|
9260
|
-
return text;
|
|
9261
|
-
}
|
|
9262
|
-
/** @internal */
|
|
9263
|
-
_toOps(parentId, parentKey) {
|
|
9264
|
-
if (this._id === void 0) {
|
|
9265
|
-
throw new Error("Cannot serialize LiveText if it is not attached");
|
|
9266
|
-
}
|
|
9267
|
-
return [
|
|
9268
|
-
{
|
|
9269
|
-
type: OpCode.CREATE_TEXT,
|
|
9270
|
-
id: this._id,
|
|
9271
|
-
parentId,
|
|
9272
|
-
parentKey,
|
|
9273
|
-
data: this.toJSON(),
|
|
9274
|
-
version: this.#version
|
|
9275
|
-
}
|
|
9276
|
-
];
|
|
9277
|
-
}
|
|
9278
|
-
/** @internal */
|
|
9279
|
-
_serialize() {
|
|
9280
|
-
if (this.parent.type !== "HasParent") {
|
|
9281
|
-
throw new Error("Cannot serialize LiveText if parent is missing");
|
|
9282
|
-
}
|
|
9283
|
-
return {
|
|
9284
|
-
type: CrdtType.TEXT,
|
|
9285
|
-
parentId: nn(this.parent.node._id, "Parent node expected to have ID"),
|
|
9286
|
-
parentKey: this.parent.key,
|
|
9287
|
-
data: this.toJSON(),
|
|
9288
|
-
version: this.#version
|
|
9289
|
-
};
|
|
9290
|
-
}
|
|
9291
|
-
/** @internal */
|
|
9292
|
-
_attachChild(_op) {
|
|
9293
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9294
|
-
}
|
|
9295
|
-
/** @internal */
|
|
9296
|
-
_detachChild(_crdt) {
|
|
9297
|
-
throw new Error("LiveText cannot contain child nodes");
|
|
9298
|
-
}
|
|
9299
|
-
/** @internal */
|
|
9300
|
-
_apply(op, isLocal) {
|
|
9301
|
-
if (op.type !== OpCode.UPDATE_TEXT) {
|
|
9302
|
-
return super._apply(op, isLocal);
|
|
9303
|
-
}
|
|
9304
|
-
if (isLocal) {
|
|
9305
|
-
return this.#applyLocal(op);
|
|
9306
|
-
}
|
|
9307
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
9308
|
-
return this.#applyAck(op);
|
|
9309
|
-
}
|
|
9310
|
-
if (op.opId !== void 0 && this.#acceptedOps.some((entry) => entry.opId === op.opId)) {
|
|
9311
|
-
this.#version = Math.max(this.#version, _nullishCoalesce(op.version, () => ( op.baseVersion + 1)));
|
|
9312
|
-
return { modified: false };
|
|
9313
|
-
}
|
|
9314
|
-
return this.#applyRemote(op);
|
|
9315
|
-
}
|
|
9316
|
-
/**
|
|
9317
|
-
* Inserts text at the given index.
|
|
9318
|
-
*
|
|
9319
|
-
* @param index Character index at which to insert. Values outside the
|
|
9320
|
-
* document range are clipped.
|
|
9321
|
-
* @param text Text to insert.
|
|
9322
|
-
* @param attributes Optional inline attributes for the inserted text.
|
|
9323
|
-
*
|
|
9324
|
-
* @example
|
|
9325
|
-
* const text = new LiveText("Hello");
|
|
9326
|
-
* text.insert(5, " world");
|
|
9327
|
-
* text.insert(0, "Say: ", { italic: true });
|
|
9328
|
-
*/
|
|
9329
|
-
insert(index, text, attributes) {
|
|
9330
|
-
const clippedIndex = Math.max(0, Math.min(index, this.length));
|
|
9331
|
-
this.#dispatch([{ type: "insert", index: clippedIndex, text, attributes }]);
|
|
9332
|
-
}
|
|
9333
|
-
/**
|
|
9334
|
-
* Deletes `length` characters starting at `index`.
|
|
9335
|
-
*
|
|
9336
|
-
* @example
|
|
9337
|
-
* const text = new LiveText("Hello world");
|
|
9338
|
-
* text.delete(5, 6); // "Hello"
|
|
9339
|
-
*/
|
|
9340
|
-
delete(index, length) {
|
|
9341
|
-
const clipped = clipRange(index, length, this.length);
|
|
9342
|
-
if (clipped.length === 0) {
|
|
9343
|
-
return;
|
|
9344
|
-
}
|
|
9345
|
-
this.#dispatch([
|
|
9346
|
-
{ type: "delete", index: clipped.index, length: clipped.length }
|
|
9347
|
-
]);
|
|
9348
|
-
}
|
|
9349
|
-
/**
|
|
9350
|
-
* Replaces a range of text with new text.
|
|
9351
|
-
*
|
|
9352
|
-
* @example
|
|
9353
|
-
* const text = new LiveText("Hello world");
|
|
9354
|
-
* text.replace(0, 5, "Hi"); // "Hi world"
|
|
9355
|
-
*/
|
|
9356
|
-
replace(index, length, text, attributes) {
|
|
9357
|
-
const clipped = clipRange(index, length, this.length);
|
|
9358
|
-
const ops = [];
|
|
9359
|
-
if (clipped.length > 0) {
|
|
9360
|
-
ops.push({
|
|
9361
|
-
type: "delete",
|
|
9362
|
-
index: clipped.index,
|
|
9363
|
-
length: clipped.length
|
|
9364
|
-
});
|
|
9365
|
-
}
|
|
9366
|
-
if (text.length > 0) {
|
|
9367
|
-
ops.push({ type: "insert", index: clipped.index, text, attributes });
|
|
9368
|
-
}
|
|
9369
|
-
this.#dispatch(ops);
|
|
9370
|
-
}
|
|
9371
|
-
/**
|
|
9372
|
-
* Encode a local-document index (an offset into this LiveText's current
|
|
9373
|
-
* #segments, which CodeMirror or any consumer mirrors as its document)
|
|
9374
|
-
* into server-confirmed coordinates suitable for broadcasting to peers via
|
|
9375
|
-
* presence or any other side channel.
|
|
9376
|
-
*
|
|
9377
|
-
* The returned index is in this LiveText's current #confirmed coordinates
|
|
9378
|
-
* — that is, with this client's local pending ops inverse-mapped out.
|
|
9379
|
-
* Pair it with the current {@link LiveText.version} when sending so the
|
|
9380
|
-
* receiver can call {@link PrivateLiveTextApi.decodeIndex} to land the
|
|
9381
|
-
* position in their own local document coordinates regardless of their
|
|
9382
|
-
* private pending ops.
|
|
9383
|
-
*
|
|
9384
|
-
* Index ambiguity at boundaries is resolved by an inverse-of-forward
|
|
9385
|
-
* convention: a position at or before a local insertion is reported as
|
|
9386
|
-
* the position right before the insertion in #confirmed; a position past
|
|
9387
|
-
* the insertion shifts left by the insertion's length. Positions inside
|
|
9388
|
-
* an own-pending insertion collapse to the insertion point.
|
|
9389
|
-
*/
|
|
9390
|
-
#encodeIndex(localIndex) {
|
|
9391
|
-
let mapped = Math.max(0, Math.min(localIndex, this.length));
|
|
9392
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
9393
|
-
mapped = inverseMapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
9394
|
-
return mapped;
|
|
9395
|
-
}
|
|
9396
|
-
/**
|
|
9397
|
-
* Decode an `(index, fromVersion)` pair produced by
|
|
9398
|
-
* {@link PrivateLiveTextApi.encodeIndex} — typically on a peer — into an
|
|
9399
|
-
* offset in this LiveText's current local document (an index suitable for
|
|
9400
|
-
* placing a CodeMirror marker, an annotation anchor, or anything else that
|
|
9401
|
-
* lives over #segments).
|
|
9402
|
-
*
|
|
9403
|
-
* Composes the accepted ops applied since `fromVersion` (drawn from
|
|
9404
|
-
* #acceptedOps in locally-applied form) with this client's own local
|
|
9405
|
-
* pending ops, in that order. The result is in current #segments
|
|
9406
|
-
* coordinates.
|
|
9407
|
-
*
|
|
9408
|
-
* Returns `null` when the position cannot be decoded against the current
|
|
9409
|
-
* state:
|
|
9410
|
-
* - `fromVersion` is greater than this LiveText's current version: the
|
|
9411
|
-
* peer is ahead of us. The caller should park the message and retry
|
|
9412
|
-
* after more accepted ops arrive.
|
|
9413
|
-
* - `fromVersion` falls outside the retained accepted-ops history. This
|
|
9414
|
-
* only happens after very long-lived disconnections; the caller can
|
|
9415
|
-
* fall back to using the raw index and letting subsequent local
|
|
9416
|
-
* transactions map it (with bounded drift).
|
|
9417
|
-
*/
|
|
9418
|
-
#decodeIndex(index, fromVersion) {
|
|
9419
|
-
if (fromVersion > this.#version) {
|
|
9420
|
-
return null;
|
|
9421
|
-
}
|
|
9422
|
-
if (fromVersion < this.#version) {
|
|
9423
|
-
const oldest = _optionalChain([this, 'access', _216 => _216.#acceptedOps, 'access', _217 => _217[0], 'optionalAccess', _218 => _218.version]);
|
|
9424
|
-
if (oldest === void 0 || oldest > fromVersion + 1) {
|
|
9425
|
-
return null;
|
|
9426
|
-
}
|
|
9427
|
-
}
|
|
9428
|
-
let mapped = index;
|
|
9429
|
-
for (const entry of this.#acceptedOps) {
|
|
9430
|
-
if (entry.version <= fromVersion) continue;
|
|
9431
|
-
if (entry.version > this.#version) break;
|
|
9432
|
-
if (entry.ops.length === 0) continue;
|
|
9433
|
-
mapped = mapTextIndexThroughOperations(mapped, entry.ops);
|
|
9434
|
-
}
|
|
9435
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#inFlightOps);
|
|
9436
|
-
mapped = mapTextIndexThroughOperations(mapped, this.#queuedOps);
|
|
9437
|
-
return Math.max(0, Math.min(mapped, this.length));
|
|
9438
|
-
}
|
|
9439
|
-
/**
|
|
9440
|
-
* Applies or removes inline attributes on a range of text.
|
|
9441
|
-
*
|
|
9442
|
-
* Set an attribute to `null` to remove it from the range.
|
|
9443
|
-
*
|
|
9444
|
-
* @example
|
|
9445
|
-
* const text = new LiveText("Hello world");
|
|
9446
|
-
* text.format(0, 5, { bold: true });
|
|
9447
|
-
* text.format(0, 5, { bold: null });
|
|
9448
|
-
*/
|
|
9449
|
-
format(index, length, attributes) {
|
|
9450
|
-
const clipped = clipRange(index, length, this.length);
|
|
9451
|
-
if (clipped.length === 0) {
|
|
9452
|
-
return;
|
|
9453
|
-
}
|
|
9454
|
-
this.#dispatch([
|
|
9455
|
-
{
|
|
9456
|
-
type: "format",
|
|
9457
|
-
index: clipped.index,
|
|
9458
|
-
length: clipped.length,
|
|
9459
|
-
attributes
|
|
9460
|
-
}
|
|
9461
|
-
]);
|
|
9462
|
-
}
|
|
9463
|
-
/** Local edits made through the public API. */
|
|
9464
|
-
#dispatch(ops) {
|
|
9465
|
-
if (ops.length === 0) {
|
|
9466
|
-
return;
|
|
9467
|
-
}
|
|
9468
|
-
_optionalChain([this, 'access', _219 => _219._pool, 'optionalAccess', _220 => _220.assertStorageIsWritable, 'call', _221 => _221()]);
|
|
9469
|
-
const attached = this._pool !== void 0 && this._id !== void 0;
|
|
9470
|
-
const reverse = attached ? this.#invertOperations(ops) : [];
|
|
9471
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
9472
|
-
if (!attached) {
|
|
9473
|
-
return;
|
|
9474
|
-
}
|
|
9475
|
-
const pool = nn(this._pool);
|
|
9476
|
-
const id = nn(this._id);
|
|
9477
|
-
const updates = /* @__PURE__ */ new Map([
|
|
9478
|
-
[
|
|
9479
|
-
id,
|
|
9480
|
-
{
|
|
9481
|
-
type: "LiveText",
|
|
9482
|
-
node: this,
|
|
9483
|
-
version: this.#version,
|
|
9484
|
-
updates: changes
|
|
9485
|
-
}
|
|
9486
|
-
]
|
|
9487
|
-
]);
|
|
9488
|
-
if (this.#inFlightOpId === void 0) {
|
|
9489
|
-
const opId = pool.generateOpId();
|
|
9490
|
-
this.#inFlightOpId = opId;
|
|
9491
|
-
this.#inFlightOps = [...ops];
|
|
9492
|
-
pool.dispatch(
|
|
9493
|
-
[
|
|
9494
|
-
{
|
|
9495
|
-
type: OpCode.UPDATE_TEXT,
|
|
9496
|
-
id,
|
|
9497
|
-
opId,
|
|
9498
|
-
baseVersion: this.#version,
|
|
9499
|
-
ops: [...ops]
|
|
9500
|
-
}
|
|
9501
|
-
],
|
|
9502
|
-
reverse,
|
|
9503
|
-
updates
|
|
9504
|
-
);
|
|
9505
|
-
} else {
|
|
9506
|
-
this.#queuedOps.push(...ops);
|
|
9507
|
-
pool.dispatch([], reverse, updates, { clearRedoStack: true });
|
|
9508
|
-
}
|
|
9509
|
-
}
|
|
9510
|
-
/**
|
|
9511
|
-
* A local replay of an existing wire op: an undo/redo frame, or an
|
|
9512
|
-
* unacknowledged op re-sent after a reconnect.
|
|
9513
|
-
*/
|
|
9514
|
-
#applyLocal(op) {
|
|
9515
|
-
const mutableOp = op;
|
|
9516
|
-
if (op.opId !== void 0 && op.opId === this.#inFlightOpId) {
|
|
9517
|
-
this.#inFlightOps = [...this.#inFlightOps, ...this.#queuedOps];
|
|
9518
|
-
this.#queuedOps = [];
|
|
9519
|
-
mutableOp.baseVersion = this.#version;
|
|
9520
|
-
mutableOp.ops = [...this.#inFlightOps];
|
|
9521
|
-
return { modified: false };
|
|
9522
|
-
}
|
|
9523
|
-
let ops = op.ops;
|
|
9524
|
-
for (const entry of this.#acceptedOps) {
|
|
9525
|
-
if (entry.version > op.baseVersion && entry.ops.length > 0) {
|
|
9526
|
-
ops = transformTextOperations(ops, entry.ops, "after");
|
|
9527
|
-
}
|
|
9528
|
-
}
|
|
9529
|
-
const reverse = this.#invertOperations(ops);
|
|
9530
|
-
const changes = this.#applyOperationsLocally(ops);
|
|
9531
|
-
if (this.#inFlightOpId === void 0 && ops.length > 0) {
|
|
9532
|
-
this.#inFlightOpId = nn(op.opId, "Local ops must have an opId");
|
|
9533
|
-
this.#inFlightOps = [...ops];
|
|
9534
|
-
mutableOp.baseVersion = this.#version;
|
|
9535
|
-
mutableOp.ops = [...ops];
|
|
9536
|
-
} else {
|
|
9537
|
-
this.#queuedOps.push(...ops);
|
|
9538
|
-
mutableOp.baseVersion = this.#version;
|
|
9539
|
-
mutableOp.ops = [];
|
|
9540
|
-
}
|
|
9541
|
-
if (changes.length === 0) {
|
|
9542
|
-
return { modified: false };
|
|
9543
|
-
}
|
|
9544
|
-
return {
|
|
9545
|
-
reverse,
|
|
9546
|
-
modified: {
|
|
9547
|
-
type: "LiveText",
|
|
9548
|
-
node: this,
|
|
9549
|
-
version: this.#version,
|
|
9550
|
-
updates: changes
|
|
9551
|
-
}
|
|
9552
|
-
};
|
|
9553
|
-
}
|
|
9554
|
-
/** Server acknowledgement of our in-flight op. */
|
|
9555
|
-
#applyAck(op) {
|
|
9556
|
-
const ackedVersion = _nullishCoalesce(op.version, () => ( Math.max(this.#version, op.baseVersion + 1)));
|
|
9557
|
-
const predicted = this.#inFlightOps;
|
|
9558
|
-
const opId = this.#inFlightOpId;
|
|
9559
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
9560
|
-
this.#inFlightOpId = void 0;
|
|
9561
|
-
this.#inFlightOps = [];
|
|
9562
|
-
let appliedOps = [];
|
|
9563
|
-
let result = { modified: false };
|
|
9564
|
-
if (!textOperationsEqual(op.ops, predicted)) {
|
|
9565
|
-
error2(
|
|
9566
|
-
"LiveText: acknowledgement did not match the local prediction; resynchronizing"
|
|
9567
|
-
);
|
|
9568
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
9569
|
-
appliedOps = rebuilt.appliedOps;
|
|
9570
|
-
if (rebuilt.changes.length > 0) {
|
|
9571
|
-
result = {
|
|
9572
|
-
reverse: [],
|
|
9573
|
-
modified: {
|
|
9574
|
-
type: "LiveText",
|
|
9575
|
-
node: this,
|
|
9576
|
-
version: ackedVersion,
|
|
9577
|
-
updates: rebuilt.changes
|
|
9578
|
-
}
|
|
9579
|
-
};
|
|
9580
|
-
}
|
|
9581
|
-
}
|
|
9582
|
-
this.#version = Math.max(this.#version, ackedVersion);
|
|
9583
|
-
this.#recordAccepted(ackedVersion, appliedOps, opId);
|
|
9584
|
-
this.#flushQueued();
|
|
9585
|
-
return result;
|
|
9586
|
-
}
|
|
9587
|
-
/** An accepted op from another client (or a server-fabricated fix op). */
|
|
9588
|
-
#applyRemote(op) {
|
|
9589
|
-
const version = _nullishCoalesce(op.version, () => ( this.#version + 1));
|
|
9590
|
-
this.#confirmed = applyTextOperationsToSegments(this.#confirmed, op.ops);
|
|
9591
|
-
const [overInFlight, inFlight] = transformTextOperationsX(
|
|
9592
|
-
op.ops,
|
|
9593
|
-
this.#inFlightOps,
|
|
9594
|
-
"before"
|
|
9595
|
-
);
|
|
9596
|
-
const [applied, queued] = transformTextOperationsX(
|
|
9597
|
-
overInFlight,
|
|
9598
|
-
this.#queuedOps,
|
|
9599
|
-
"before"
|
|
9600
|
-
);
|
|
9601
|
-
this.#inFlightOps = inFlight;
|
|
9602
|
-
this.#queuedOps = queued;
|
|
9603
|
-
this.#recordAccepted(version, applied, op.opId);
|
|
9604
|
-
if (applied.length === 0) {
|
|
9605
|
-
this.#version = Math.max(this.#version, version);
|
|
9606
|
-
return { modified: false };
|
|
9607
|
-
}
|
|
9608
|
-
const reverse = this.#invertOperations(applied);
|
|
9609
|
-
const changes = this.#applyOperationsLocally(applied);
|
|
9610
|
-
this.#version = Math.max(this.#version, version);
|
|
9611
|
-
return {
|
|
9612
|
-
reverse,
|
|
9613
|
-
modified: {
|
|
9614
|
-
type: "LiveText",
|
|
9615
|
-
node: this,
|
|
9616
|
-
version: this.#version,
|
|
9617
|
-
updates: changes
|
|
9618
|
-
}
|
|
9619
|
-
};
|
|
9620
|
-
}
|
|
9621
|
-
/** Send the queued ops as the next in-flight op (after an ack). */
|
|
9622
|
-
#flushQueued() {
|
|
9623
|
-
if (this.#queuedOps.length === 0 || this._pool === void 0 || this._id === void 0) {
|
|
9624
|
-
return;
|
|
9625
|
-
}
|
|
9626
|
-
const opId = this._pool.generateOpId();
|
|
9627
|
-
this.#inFlightOpId = opId;
|
|
9628
|
-
this.#inFlightOps = this.#queuedOps;
|
|
9629
|
-
this.#queuedOps = [];
|
|
9630
|
-
this._pool.dispatch(
|
|
9631
|
-
[
|
|
9632
|
-
{
|
|
9633
|
-
type: OpCode.UPDATE_TEXT,
|
|
9634
|
-
id: this._id,
|
|
9635
|
-
opId,
|
|
9636
|
-
baseVersion: this.#version,
|
|
9637
|
-
ops: [...this.#inFlightOps]
|
|
9638
|
-
}
|
|
9639
|
-
],
|
|
9640
|
-
[],
|
|
9641
|
-
/* @__PURE__ */ new Map(),
|
|
9642
|
-
// The local content was already applied (and made undoable) when the
|
|
9643
|
-
// edits happened; this is purely an outbound flush.
|
|
9644
|
-
{ clearRedoStack: false }
|
|
9645
|
-
);
|
|
9646
|
-
}
|
|
9647
|
-
/**
|
|
9648
|
-
* Rebuild the local document as confirmed ⊕ queued ops, returning the
|
|
9649
|
-
* coarse delta that was applied. Only used by defensive recovery paths.
|
|
9650
|
-
*/
|
|
9651
|
-
#rebuildLocalFromConfirmed() {
|
|
9652
|
-
const before2 = this.#segments;
|
|
9653
|
-
const after2 = applyTextOperationsToSegments(this.#confirmed, [
|
|
9654
|
-
...this.#inFlightOps,
|
|
9655
|
-
...this.#queuedOps
|
|
9656
|
-
]);
|
|
9657
|
-
if (stableStringify(segmentsToData(before2)) === stableStringify(segmentsToData(after2))) {
|
|
9658
|
-
this.#segments = after2;
|
|
9659
|
-
return { appliedOps: [], changes: [] };
|
|
9660
|
-
}
|
|
9661
|
-
const beforeText = before2.map((segment) => segment.text).join("");
|
|
9662
|
-
this.#segments = after2;
|
|
9663
|
-
this.invalidate();
|
|
9664
|
-
const appliedOps = [];
|
|
9665
|
-
const changes = [];
|
|
9666
|
-
if (beforeText.length > 0) {
|
|
9667
|
-
appliedOps.push({ type: "delete", index: 0, length: beforeText.length });
|
|
9668
|
-
changes.push({
|
|
9669
|
-
type: "delete",
|
|
9670
|
-
index: 0,
|
|
9671
|
-
length: beforeText.length,
|
|
9672
|
-
deletedText: beforeText
|
|
9673
|
-
});
|
|
9674
|
-
}
|
|
9675
|
-
let index = 0;
|
|
9676
|
-
for (const segment of after2) {
|
|
9677
|
-
appliedOps.push({
|
|
9678
|
-
type: "insert",
|
|
9679
|
-
index,
|
|
9680
|
-
text: segment.text,
|
|
9681
|
-
attributes: segment.attributes
|
|
9682
|
-
});
|
|
9683
|
-
changes.push({
|
|
9684
|
-
type: "insert",
|
|
9685
|
-
index,
|
|
9686
|
-
text: segment.text,
|
|
9687
|
-
attributes: segment.attributes
|
|
9688
|
-
});
|
|
9689
|
-
index += segment.text.length;
|
|
9690
|
-
}
|
|
9691
|
-
return { appliedOps, changes };
|
|
9692
|
-
}
|
|
9693
|
-
/**
|
|
9694
|
-
* Reconcile this node against an authoritative storage snapshot (e.g.
|
|
9695
|
-
* after a reconnect). The confirmed state and version are replaced by the
|
|
9696
|
-
* snapshot's; pending (in-flight + queued) ops are preserved on top and
|
|
9697
|
-
* will be re-sent by the offline-ops replay.
|
|
9698
|
-
*
|
|
9699
|
-
* @internal
|
|
9700
|
-
*/
|
|
9701
|
-
_resyncText(data, version) {
|
|
9702
|
-
this.#confirmed = dataToSegments(data);
|
|
9703
|
-
this.#version = version;
|
|
9704
|
-
this.#acceptedOps = [];
|
|
9705
|
-
const rebuilt = this.#rebuildLocalFromConfirmed();
|
|
9706
|
-
if (rebuilt.changes.length === 0) {
|
|
9707
|
-
return void 0;
|
|
9708
|
-
}
|
|
9709
|
-
return {
|
|
9710
|
-
type: "LiveText",
|
|
9711
|
-
node: this,
|
|
9712
|
-
version: this.#version,
|
|
9713
|
-
updates: rebuilt.changes
|
|
9714
|
-
};
|
|
9715
|
-
}
|
|
9716
|
-
/**
|
|
9717
|
-
* Called when the server rejected one of our ops. Drops all pending state
|
|
9718
|
-
* for this node (edits queued behind a rejected op cannot be trusted
|
|
9719
|
-
* either); the room follows up with a storage resync.
|
|
9720
|
-
*
|
|
9721
|
-
* @internal
|
|
9722
|
-
*/
|
|
9723
|
-
_rejectPendingOp(opId) {
|
|
9724
|
-
if (opId !== this.#inFlightOpId) {
|
|
9725
|
-
return;
|
|
9726
|
-
}
|
|
9727
|
-
this.#inFlightOpId = void 0;
|
|
9728
|
-
this.#inFlightOps = [];
|
|
9729
|
-
this.#queuedOps = [];
|
|
9730
|
-
}
|
|
9731
|
-
#recordAccepted(version, ops, opId) {
|
|
9732
|
-
if (this.#acceptedOps.some((entry) => entry.version === version)) {
|
|
9733
|
-
return;
|
|
9734
|
-
}
|
|
9735
|
-
this.#acceptedOps.push({ version, opId, ops: [...ops] });
|
|
9736
|
-
this.#acceptedOps.sort((left, right) => left.version - right.version);
|
|
9737
|
-
if (this.#acceptedOps.length > ACCEPTED_OPS_HISTORY_LIMIT) {
|
|
9738
|
-
this.#acceptedOps.splice(
|
|
9739
|
-
0,
|
|
9740
|
-
this.#acceptedOps.length - ACCEPTED_OPS_HISTORY_LIMIT
|
|
9741
|
-
);
|
|
9742
|
-
}
|
|
9743
|
-
}
|
|
9744
|
-
#applyOperationsLocally(ops) {
|
|
9745
|
-
const changes = [];
|
|
9746
|
-
for (const op of ops) {
|
|
9747
|
-
if (op.type === "insert") {
|
|
9748
|
-
this.#segments = applyInsert(
|
|
9749
|
-
this.#segments,
|
|
9750
|
-
op.index,
|
|
9751
|
-
op.text,
|
|
9752
|
-
op.attributes
|
|
9753
|
-
);
|
|
9754
|
-
changes.push({
|
|
9755
|
-
type: "insert",
|
|
9756
|
-
index: op.index,
|
|
9757
|
-
text: op.text,
|
|
9758
|
-
attributes: op.attributes
|
|
9759
|
-
});
|
|
9760
|
-
} else if (op.type === "delete") {
|
|
9761
|
-
const result = applyDelete(this.#segments, op.index, op.length);
|
|
9762
|
-
this.#segments = result.segments;
|
|
9763
|
-
changes.push({
|
|
9764
|
-
type: "delete",
|
|
9765
|
-
index: op.index,
|
|
9766
|
-
length: op.length,
|
|
9767
|
-
deletedText: result.deletedText
|
|
9768
|
-
});
|
|
9769
|
-
} else {
|
|
9770
|
-
this.#segments = applyFormat(
|
|
9771
|
-
this.#segments,
|
|
9772
|
-
op.index,
|
|
9773
|
-
op.length,
|
|
9774
|
-
op.attributes
|
|
9775
|
-
);
|
|
9776
|
-
changes.push({
|
|
9777
|
-
type: "format",
|
|
9778
|
-
index: op.index,
|
|
9779
|
-
length: op.length,
|
|
9780
|
-
attributes: op.attributes
|
|
9781
|
-
});
|
|
9782
|
-
}
|
|
9783
|
-
}
|
|
9784
|
-
this.invalidate();
|
|
9785
|
-
return changes;
|
|
9786
|
-
}
|
|
9787
|
-
#invertOperations(ops) {
|
|
9788
|
-
return [
|
|
9789
|
-
{
|
|
9790
|
-
type: OpCode.UPDATE_TEXT,
|
|
9791
|
-
id: nn(this._id),
|
|
9792
|
-
baseVersion: this.#version,
|
|
9793
|
-
ops: invertTextOperations(this.#segments, ops)
|
|
9794
|
-
}
|
|
9795
|
-
];
|
|
9796
|
-
}
|
|
9797
|
-
/** Returns the plain text content without attributes. Equivalent to joining the text from each segment in {@link LiveText.toJSON}. */
|
|
9798
|
-
toString() {
|
|
9799
|
-
return this.#segments.map((segment) => segment.text).join("");
|
|
9800
|
-
}
|
|
9801
|
-
/**
|
|
9802
|
-
* Returns a JSON-compatible snapshot of the document as a {@link LiveTextData}
|
|
9803
|
-
* array.
|
|
9804
|
-
*
|
|
9805
|
-
* @example
|
|
9806
|
-
* new LiveText([["Hello ", { bold: true }], ["world"]]).toJSON();
|
|
9807
|
-
* // [["Hello ", { bold: true }], ["world"]]
|
|
9808
|
-
*/
|
|
9809
|
-
toJSON() {
|
|
9810
|
-
return super.toJSON();
|
|
9811
|
-
}
|
|
9812
|
-
/** @internal */
|
|
9813
|
-
_toJSON() {
|
|
9814
|
-
return segmentsToData(this.#segments);
|
|
9815
|
-
}
|
|
9816
|
-
/** @internal */
|
|
9817
|
-
_toTreeNode(key) {
|
|
9818
|
-
return {
|
|
9819
|
-
type: "LiveText",
|
|
9820
|
-
id: _nullishCoalesce(this._id, () => ( nanoid())),
|
|
9821
|
-
key,
|
|
9822
|
-
payload: [
|
|
9823
|
-
{
|
|
9824
|
-
type: "Json",
|
|
9825
|
-
id: `${_nullishCoalesce(this._id, () => ( nanoid()))}:text`,
|
|
9826
|
-
key: "text",
|
|
9827
|
-
payload: this.toString()
|
|
9828
|
-
}
|
|
9829
|
-
]
|
|
9830
|
-
};
|
|
9831
|
-
}
|
|
9832
|
-
clone() {
|
|
9833
|
-
return new _LiveText(this.toJSON(), this.#version);
|
|
9834
|
-
}
|
|
9835
|
-
};
|
|
9836
|
-
|
|
9837
8844
|
// src/crdts/liveblocks-helpers.ts
|
|
9838
8845
|
function creationOpToLiveNode(op) {
|
|
9839
8846
|
return lsonToLiveNode(creationOpToLson(op));
|
|
@@ -9848,8 +8855,6 @@ function creationOpToLson(op) {
|
|
|
9848
8855
|
return new LiveMap();
|
|
9849
8856
|
case OpCode.CREATE_LIST:
|
|
9850
8857
|
return new LiveList([]);
|
|
9851
|
-
case OpCode.CREATE_TEXT:
|
|
9852
|
-
return new LiveText(op.data, op.version);
|
|
9853
8858
|
default:
|
|
9854
8859
|
return assertNever(op, "Unknown creation Op");
|
|
9855
8860
|
}
|
|
@@ -9872,8 +8877,6 @@ function deserialize(node, parentToChildren, pool) {
|
|
|
9872
8877
|
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
9873
8878
|
} else if (isRegisterStorageNode(node)) {
|
|
9874
8879
|
return LiveRegister._deserialize(node, parentToChildren, pool);
|
|
9875
|
-
} else if (isTextStorageNode(node)) {
|
|
9876
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
9877
8880
|
} else {
|
|
9878
8881
|
throw new Error("Unexpected CRDT type");
|
|
9879
8882
|
}
|
|
@@ -9887,14 +8890,12 @@ function deserializeToLson(node, parentToChildren, pool) {
|
|
|
9887
8890
|
return LiveMap._deserialize(node, parentToChildren, pool);
|
|
9888
8891
|
} else if (isRegisterStorageNode(node)) {
|
|
9889
8892
|
return node[1].data;
|
|
9890
|
-
} else if (isTextStorageNode(node)) {
|
|
9891
|
-
return LiveText._deserialize(node, parentToChildren, pool);
|
|
9892
8893
|
} else {
|
|
9893
8894
|
throw new Error("Unexpected CRDT type");
|
|
9894
8895
|
}
|
|
9895
8896
|
}
|
|
9896
8897
|
function isLiveStructure(value) {
|
|
9897
|
-
return isLiveList(value) || isLiveMap(value) || isLiveObject(value)
|
|
8898
|
+
return isLiveList(value) || isLiveMap(value) || isLiveObject(value);
|
|
9898
8899
|
}
|
|
9899
8900
|
function isLiveNode(value) {
|
|
9900
8901
|
return isLiveStructure(value) || isLiveRegister(value);
|
|
@@ -9908,9 +8909,6 @@ function isLiveMap(value) {
|
|
|
9908
8909
|
function isLiveObject(value) {
|
|
9909
8910
|
return value instanceof LiveObject;
|
|
9910
8911
|
}
|
|
9911
|
-
function isLiveText(value) {
|
|
9912
|
-
return value instanceof LiveText;
|
|
9913
|
-
}
|
|
9914
8912
|
function isLiveRegister(value) {
|
|
9915
8913
|
return value instanceof LiveRegister;
|
|
9916
8914
|
}
|
|
@@ -9920,14 +8918,14 @@ function cloneLson(value) {
|
|
|
9920
8918
|
function liveNodeToLson(obj) {
|
|
9921
8919
|
if (obj instanceof LiveRegister) {
|
|
9922
8920
|
return obj.data;
|
|
9923
|
-
} else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject
|
|
8921
|
+
} else if (obj instanceof LiveList || obj instanceof LiveMap || obj instanceof LiveObject) {
|
|
9924
8922
|
return obj;
|
|
9925
8923
|
} else {
|
|
9926
8924
|
return assertNever(obj, "Unknown AbstractCrdt");
|
|
9927
8925
|
}
|
|
9928
8926
|
}
|
|
9929
8927
|
function lsonToLiveNode(value) {
|
|
9930
|
-
if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList
|
|
8928
|
+
if (value instanceof LiveObject || value instanceof LiveMap || value instanceof LiveList) {
|
|
9931
8929
|
return value;
|
|
9932
8930
|
} else {
|
|
9933
8931
|
return new LiveRegister(value);
|
|
@@ -10070,16 +9068,6 @@ function diffNodeMap(prev, next) {
|
|
|
10070
9068
|
parentKey: crdt.parentKey
|
|
10071
9069
|
});
|
|
10072
9070
|
break;
|
|
10073
|
-
case CrdtType.TEXT:
|
|
10074
|
-
ops.push({
|
|
10075
|
-
type: OpCode.CREATE_TEXT,
|
|
10076
|
-
id,
|
|
10077
|
-
parentId: crdt.parentId,
|
|
10078
|
-
parentKey: crdt.parentKey,
|
|
10079
|
-
data: crdt.data,
|
|
10080
|
-
version: crdt.version
|
|
10081
|
-
});
|
|
10082
|
-
break;
|
|
10083
9071
|
}
|
|
10084
9072
|
}
|
|
10085
9073
|
});
|
|
@@ -10112,43 +9100,19 @@ function mergeListStorageUpdates(first, second) {
|
|
|
10112
9100
|
updates: updates.concat(second.updates)
|
|
10113
9101
|
};
|
|
10114
9102
|
}
|
|
10115
|
-
function mergeTextStorageUpdates(first, second) {
|
|
10116
|
-
return {
|
|
10117
|
-
...second,
|
|
10118
|
-
updates: first.updates.concat(second.updates)
|
|
10119
|
-
};
|
|
10120
|
-
}
|
|
10121
9103
|
function mergeStorageUpdates(first, second) {
|
|
10122
9104
|
if (first === void 0) {
|
|
10123
9105
|
return second;
|
|
10124
9106
|
}
|
|
10125
|
-
let merged;
|
|
10126
9107
|
if (first.type === "LiveObject" && second.type === "LiveObject") {
|
|
10127
|
-
|
|
9108
|
+
return mergeObjectStorageUpdates(first, second);
|
|
10128
9109
|
} else if (first.type === "LiveMap" && second.type === "LiveMap") {
|
|
10129
|
-
|
|
9110
|
+
return mergeMapStorageUpdates(first, second);
|
|
10130
9111
|
} else if (first.type === "LiveList" && second.type === "LiveList") {
|
|
10131
|
-
|
|
10132
|
-
} else if (first.type === "LiveText" && second.type === "LiveText") {
|
|
10133
|
-
merged = mergeTextStorageUpdates(first, second);
|
|
9112
|
+
return mergeListStorageUpdates(first, second);
|
|
10134
9113
|
} else {
|
|
10135
|
-
merged = second;
|
|
10136
|
-
}
|
|
10137
|
-
const sa = first[kStorageUpdateSource];
|
|
10138
|
-
const sb = second[kStorageUpdateSource];
|
|
10139
|
-
if (sa !== void 0 || sb !== void 0) {
|
|
10140
|
-
if (_optionalChain([sa, 'optionalAccess', _222 => _222.origin]) === "remote" || _optionalChain([sb, 'optionalAccess', _223 => _223.origin]) === "remote") {
|
|
10141
|
-
merged[kStorageUpdateSource] = { origin: "remote" };
|
|
10142
|
-
} else if (_optionalChain([sa, 'optionalAccess', _224 => _224.via]) === "history" || _optionalChain([sb, 'optionalAccess', _225 => _225.via]) === "history") {
|
|
10143
|
-
const historySource = _optionalChain([sb, 'optionalAccess', _226 => _226.via]) === "history" ? sb : _optionalChain([sa, 'optionalAccess', _227 => _227.via]) === "history" ? sa : void 0;
|
|
10144
|
-
if (_optionalChain([historySource, 'optionalAccess', _228 => _228.via]) === "history") {
|
|
10145
|
-
merged[kStorageUpdateSource] = historySource;
|
|
10146
|
-
}
|
|
10147
|
-
} else {
|
|
10148
|
-
merged[kStorageUpdateSource] = { origin: "local", via: "mutation" };
|
|
10149
|
-
}
|
|
10150
9114
|
}
|
|
10151
|
-
return
|
|
9115
|
+
return second;
|
|
10152
9116
|
}
|
|
10153
9117
|
|
|
10154
9118
|
// src/devtools/bridge.ts
|
|
@@ -10164,7 +9128,7 @@ function sendToPanel(message, options) {
|
|
|
10164
9128
|
...message,
|
|
10165
9129
|
source: "liveblocks-devtools-client"
|
|
10166
9130
|
};
|
|
10167
|
-
if (!(_optionalChain([options, 'optionalAccess',
|
|
9131
|
+
if (!(_optionalChain([options, 'optionalAccess', _217 => _217.force]) || _bridgeActive)) {
|
|
10168
9132
|
return;
|
|
10169
9133
|
}
|
|
10170
9134
|
window.postMessage(fullMsg, "*");
|
|
@@ -10172,7 +9136,7 @@ function sendToPanel(message, options) {
|
|
|
10172
9136
|
var eventSource = makeEventSource();
|
|
10173
9137
|
if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
|
|
10174
9138
|
window.addEventListener("message", (event) => {
|
|
10175
|
-
if (event.source === window && _optionalChain([event, 'access',
|
|
9139
|
+
if (event.source === window && _optionalChain([event, 'access', _218 => _218.data, 'optionalAccess', _219 => _219.source]) === "liveblocks-devtools-panel") {
|
|
10176
9140
|
eventSource.notify(event.data);
|
|
10177
9141
|
} else {
|
|
10178
9142
|
}
|
|
@@ -10314,7 +9278,7 @@ function fullSync(room) {
|
|
|
10314
9278
|
msg: "room::sync::full",
|
|
10315
9279
|
roomId: room.id,
|
|
10316
9280
|
status: room.getStatus(),
|
|
10317
|
-
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess',
|
|
9281
|
+
storage: _nullishCoalesce(_optionalChain([root, 'optionalAccess', _220 => _220.toTreeNode, 'call', _221 => _221("root"), 'access', _222 => _222.payload]), () => ( null)),
|
|
10318
9282
|
me,
|
|
10319
9283
|
others
|
|
10320
9284
|
});
|
|
@@ -11001,15 +9965,15 @@ function installBackgroundTabSpy() {
|
|
|
11001
9965
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
11002
9966
|
const inBackgroundSince = { current: null };
|
|
11003
9967
|
function onVisibilityChange() {
|
|
11004
|
-
if (_optionalChain([doc, 'optionalAccess',
|
|
9968
|
+
if (_optionalChain([doc, 'optionalAccess', _223 => _223.visibilityState]) === "hidden") {
|
|
11005
9969
|
inBackgroundSince.current = _nullishCoalesce(inBackgroundSince.current, () => ( Date.now()));
|
|
11006
9970
|
} else {
|
|
11007
9971
|
inBackgroundSince.current = null;
|
|
11008
9972
|
}
|
|
11009
9973
|
}
|
|
11010
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9974
|
+
_optionalChain([doc, 'optionalAccess', _224 => _224.addEventListener, 'call', _225 => _225("visibilitychange", onVisibilityChange)]);
|
|
11011
9975
|
const unsub = () => {
|
|
11012
|
-
_optionalChain([doc, 'optionalAccess',
|
|
9976
|
+
_optionalChain([doc, 'optionalAccess', _226 => _226.removeEventListener, 'call', _227 => _227("visibilitychange", onVisibilityChange)]);
|
|
11013
9977
|
};
|
|
11014
9978
|
return [inBackgroundSince, unsub];
|
|
11015
9979
|
}
|
|
@@ -11092,8 +10056,6 @@ function createRoom(options, config) {
|
|
|
11092
10056
|
activeBatch: null,
|
|
11093
10057
|
unacknowledgedOps
|
|
11094
10058
|
};
|
|
11095
|
-
let nextHistoryItemId = 0;
|
|
11096
|
-
let historyDisabled = 0;
|
|
11097
10059
|
const nodeMapBuffer = makeNodeMapBuffer();
|
|
11098
10060
|
const stopwatch = config.enableDebugLogging ? makeStopWatch() : void 0;
|
|
11099
10061
|
let lastTokenKey;
|
|
@@ -11178,10 +10140,7 @@ function createRoom(options, config) {
|
|
|
11178
10140
|
}
|
|
11179
10141
|
}
|
|
11180
10142
|
});
|
|
11181
|
-
function onDispatch(ops, reverse, storageUpdates
|
|
11182
|
-
for (const value of storageUpdates.values()) {
|
|
11183
|
-
value[kStorageUpdateSource] = { origin: "local", via: "mutation" };
|
|
11184
|
-
}
|
|
10143
|
+
function onDispatch(ops, reverse, storageUpdates) {
|
|
11185
10144
|
if (context.activeBatch) {
|
|
11186
10145
|
for (const op of ops) {
|
|
11187
10146
|
context.activeBatch.ops.push(op);
|
|
@@ -11200,17 +10159,15 @@ function createRoom(options, config) {
|
|
|
11200
10159
|
if (reverse.length > 0) {
|
|
11201
10160
|
addToUndoStack(reverse);
|
|
11202
10161
|
}
|
|
11203
|
-
if (_nullishCoalesce(_optionalChain([options2, 'optionalAccess', _240 => _240.clearRedoStack]), () => ( ops.length > 0))) {
|
|
11204
|
-
clearRedoStack();
|
|
11205
|
-
}
|
|
11206
10162
|
if (ops.length > 0) {
|
|
10163
|
+
context.redoStack.length = 0;
|
|
11207
10164
|
dispatchOps(ops);
|
|
11208
10165
|
}
|
|
11209
10166
|
notify({ storageUpdates });
|
|
11210
10167
|
}
|
|
11211
10168
|
}
|
|
11212
10169
|
function isStorageWritable() {
|
|
11213
|
-
const permissionMatrix = _optionalChain([context, 'access',
|
|
10170
|
+
const permissionMatrix = _optionalChain([context, 'access', _228 => _228.dynamicSessionInfoSig, 'access', _229 => _229.get, 'call', _230 => _230(), 'optionalAccess', _231 => _231.permissionMatrix]);
|
|
11214
10171
|
return permissionMatrix !== void 0 ? hasPermissionAccess(permissionMatrix, "storage", "write") : true;
|
|
11215
10172
|
}
|
|
11216
10173
|
const eventHub = {
|
|
@@ -11223,7 +10180,6 @@ function createRoom(options, config) {
|
|
|
11223
10180
|
others: makeEventSource(),
|
|
11224
10181
|
storageBatch: makeEventSource(),
|
|
11225
10182
|
history: makeEventSource(),
|
|
11226
|
-
privateHistory: makeEventSource(),
|
|
11227
10183
|
storageDidLoad: makeEventSource(),
|
|
11228
10184
|
storageStatus: makeEventSource(),
|
|
11229
10185
|
ydoc: makeEventSource(),
|
|
@@ -11316,23 +10272,6 @@ function createRoom(options, config) {
|
|
|
11316
10272
|
}
|
|
11317
10273
|
const ops = diffNodeMap(currentItems, nodes);
|
|
11318
10274
|
const result = applyRemoteOps(ops);
|
|
11319
|
-
for (const [id, crdt] of nodes) {
|
|
11320
|
-
if (crdt.type === CrdtType.TEXT) {
|
|
11321
|
-
const node = context.pool.nodes.get(id);
|
|
11322
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
11323
|
-
const update = node._resyncText(crdt.data, crdt.version);
|
|
11324
|
-
if (update !== void 0) {
|
|
11325
|
-
result.updates.storageUpdates.set(
|
|
11326
|
-
id,
|
|
11327
|
-
mergeStorageUpdates(
|
|
11328
|
-
result.updates.storageUpdates.get(id),
|
|
11329
|
-
update
|
|
11330
|
-
)
|
|
11331
|
-
);
|
|
11332
|
-
}
|
|
11333
|
-
}
|
|
11334
|
-
}
|
|
11335
|
-
}
|
|
11336
10275
|
notify(result.updates);
|
|
11337
10276
|
} else {
|
|
11338
10277
|
context.root = LiveObject._fromItems(
|
|
@@ -11340,7 +10279,7 @@ function createRoom(options, config) {
|
|
|
11340
10279
|
context.pool
|
|
11341
10280
|
);
|
|
11342
10281
|
}
|
|
11343
|
-
const canWrite = _nullishCoalesce(_optionalChain([self, 'access',
|
|
10282
|
+
const canWrite = _nullishCoalesce(_optionalChain([self, 'access', _232 => _232.get, 'call', _233 => _233(), 'optionalAccess', _234 => _234.canWrite]), () => ( true));
|
|
11344
10283
|
const root = context.root;
|
|
11345
10284
|
disableHistory(() => {
|
|
11346
10285
|
for (const key in context.initialStorage) {
|
|
@@ -11356,26 +10295,11 @@ function createRoom(options, config) {
|
|
|
11356
10295
|
}
|
|
11357
10296
|
});
|
|
11358
10297
|
}
|
|
11359
|
-
function notifyPrivateHistory(event) {
|
|
11360
|
-
if (historyDisabled > 0) return;
|
|
11361
|
-
eventHub.privateHistory.notify(event);
|
|
11362
|
-
}
|
|
11363
|
-
function clearRedoStack() {
|
|
11364
|
-
if (context.redoStack.length === 0) return;
|
|
11365
|
-
const ids = context.redoStack.map((item) => item.id);
|
|
11366
|
-
context.redoStack.length = 0;
|
|
11367
|
-
notifyPrivateHistory({ action: "discard", ids });
|
|
11368
|
-
}
|
|
11369
10298
|
function _addToRealUndoStack(frames) {
|
|
11370
10299
|
if (context.undoStack.length >= 50) {
|
|
11371
|
-
|
|
11372
|
-
if (evicted !== void 0) {
|
|
11373
|
-
notifyPrivateHistory({ action: "discard", ids: [evicted.id] });
|
|
11374
|
-
}
|
|
10300
|
+
context.undoStack.shift();
|
|
11375
10301
|
}
|
|
11376
|
-
|
|
11377
|
-
context.undoStack.push({ id, frames });
|
|
11378
|
-
notifyPrivateHistory({ action: "push", id });
|
|
10302
|
+
context.undoStack.push(frames);
|
|
11379
10303
|
onHistoryChange();
|
|
11380
10304
|
}
|
|
11381
10305
|
function addToUndoStack(frames) {
|
|
@@ -11413,7 +10337,7 @@ function createRoom(options, config) {
|
|
|
11413
10337
|
"Internal. Tried to get connection id but connection was never open"
|
|
11414
10338
|
);
|
|
11415
10339
|
}
|
|
11416
|
-
function applyLocalOps(frames
|
|
10340
|
+
function applyLocalOps(frames) {
|
|
11417
10341
|
const [pframes, ops] = partition(
|
|
11418
10342
|
frames,
|
|
11419
10343
|
(f) => f.type === "presence"
|
|
@@ -11425,8 +10349,7 @@ function createRoom(options, config) {
|
|
|
11425
10349
|
pframes,
|
|
11426
10350
|
opsWithOpIds,
|
|
11427
10351
|
/* isLocal */
|
|
11428
|
-
true
|
|
11429
|
-
localStorageUpdateSource
|
|
10352
|
+
true
|
|
11430
10353
|
);
|
|
11431
10354
|
return { opsToEmit: opsWithOpIds, reverse, updates };
|
|
11432
10355
|
}
|
|
@@ -11438,7 +10361,7 @@ function createRoom(options, config) {
|
|
|
11438
10361
|
false
|
|
11439
10362
|
);
|
|
11440
10363
|
}
|
|
11441
|
-
function applyOps(pframes, ops, isLocal
|
|
10364
|
+
function applyOps(pframes, ops, isLocal) {
|
|
11442
10365
|
const output = {
|
|
11443
10366
|
reverse: new Deque(),
|
|
11444
10367
|
storageUpdates: /* @__PURE__ */ new Map(),
|
|
@@ -11476,7 +10399,6 @@ function createRoom(options, config) {
|
|
|
11476
10399
|
}
|
|
11477
10400
|
const applyOpResult = applyOp(op, source);
|
|
11478
10401
|
if (applyOpResult.modified) {
|
|
11479
|
-
applyOpResult.modified[kStorageUpdateSource] = source === 1 /* THEIRS */ ? { origin: "remote" } : localStorageUpdateSource;
|
|
11480
10402
|
const nodeId = applyOpResult.modified.node._id;
|
|
11481
10403
|
if (!(nodeId && createdNodeIds.has(nodeId))) {
|
|
11482
10404
|
output.storageUpdates.set(
|
|
@@ -11488,7 +10410,7 @@ function createRoom(options, config) {
|
|
|
11488
10410
|
);
|
|
11489
10411
|
output.reverse.pushLeft(applyOpResult.reverse);
|
|
11490
10412
|
}
|
|
11491
|
-
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT
|
|
10413
|
+
if (op.type === OpCode.CREATE_LIST || op.type === OpCode.CREATE_MAP || op.type === OpCode.CREATE_OBJECT) {
|
|
11492
10414
|
createdNodeIds.add(op.id);
|
|
11493
10415
|
}
|
|
11494
10416
|
}
|
|
@@ -11508,7 +10430,6 @@ function createRoom(options, config) {
|
|
|
11508
10430
|
switch (op.type) {
|
|
11509
10431
|
case OpCode.DELETE_OBJECT_KEY:
|
|
11510
10432
|
case OpCode.UPDATE_OBJECT:
|
|
11511
|
-
case OpCode.UPDATE_TEXT:
|
|
11512
10433
|
case OpCode.DELETE_CRDT: {
|
|
11513
10434
|
const node = context.pool.nodes.get(op.id);
|
|
11514
10435
|
if (node === void 0) {
|
|
@@ -11533,7 +10454,6 @@ function createRoom(options, config) {
|
|
|
11533
10454
|
case OpCode.CREATE_OBJECT:
|
|
11534
10455
|
case OpCode.CREATE_LIST:
|
|
11535
10456
|
case OpCode.CREATE_MAP:
|
|
11536
|
-
case OpCode.CREATE_TEXT:
|
|
11537
10457
|
case OpCode.CREATE_REGISTER: {
|
|
11538
10458
|
if (op.parentId === void 0) {
|
|
11539
10459
|
return { modified: false };
|
|
@@ -11564,7 +10484,7 @@ function createRoom(options, config) {
|
|
|
11564
10484
|
}
|
|
11565
10485
|
context.myPresence.patch(patch);
|
|
11566
10486
|
if (context.activeBatch) {
|
|
11567
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10487
|
+
if (_optionalChain([options2, 'optionalAccess', _235 => _235.addToHistory])) {
|
|
11568
10488
|
context.activeBatch.reverseOps.pushLeft({
|
|
11569
10489
|
type: "presence",
|
|
11570
10490
|
data: oldValues
|
|
@@ -11573,7 +10493,7 @@ function createRoom(options, config) {
|
|
|
11573
10493
|
context.activeBatch.updates.presence = true;
|
|
11574
10494
|
} else {
|
|
11575
10495
|
flushNowOrSoon();
|
|
11576
|
-
if (_optionalChain([options2, 'optionalAccess',
|
|
10496
|
+
if (_optionalChain([options2, 'optionalAccess', _236 => _236.addToHistory])) {
|
|
11577
10497
|
addToUndoStack([{ type: "presence", data: oldValues }]);
|
|
11578
10498
|
}
|
|
11579
10499
|
notify({ presence: true });
|
|
@@ -11752,11 +10672,11 @@ function createRoom(options, config) {
|
|
|
11752
10672
|
break;
|
|
11753
10673
|
}
|
|
11754
10674
|
case ServerMsgCode.STORAGE_CHUNK:
|
|
11755
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
10675
|
+
_optionalChain([stopwatch, 'optionalAccess', _237 => _237.lap, 'call', _238 => _238()]);
|
|
11756
10676
|
nodeMapBuffer.append(compactNodesToNodeStream(message.nodes));
|
|
11757
10677
|
break;
|
|
11758
10678
|
case ServerMsgCode.STORAGE_STREAM_END: {
|
|
11759
|
-
const timing = _optionalChain([stopwatch, 'optionalAccess',
|
|
10679
|
+
const timing = _optionalChain([stopwatch, 'optionalAccess', _239 => _239.stop, 'call', _240 => _240()]);
|
|
11760
10680
|
if (timing) {
|
|
11761
10681
|
const ms = (v) => `${v.toFixed(1)}ms`;
|
|
11762
10682
|
const rest = timing.laps.slice(1);
|
|
@@ -11783,37 +10703,16 @@ function createRoom(options, config) {
|
|
|
11783
10703
|
}
|
|
11784
10704
|
break;
|
|
11785
10705
|
}
|
|
11786
|
-
// Receiving a RejectedOps message means the server
|
|
11787
|
-
//
|
|
11788
|
-
//
|
|
11789
|
-
//
|
|
11790
|
-
// server's retained history window — and we can recover: drop the
|
|
11791
|
-
// rejected pending state and re-fetch the authoritative storage
|
|
11792
|
-
// snapshot. For other ops (e.g. permission rejections), rolling back
|
|
11793
|
-
// particular Ops is hard/impossible, so we keep the old behavior of
|
|
11794
|
-
// accepting the out-of-sync reality and surfacing an error.
|
|
10706
|
+
// Receiving a RejectedOps message in the client means that the server is no
|
|
10707
|
+
// longer in sync with the client. Trying to synchronize the client again by
|
|
10708
|
+
// rolling back particular Ops may be hard/impossible. It's fine to not try and
|
|
10709
|
+
// accept the out-of-sync reality and throw an error.
|
|
11795
10710
|
case ServerMsgCode.REJECT_STORAGE_OP: {
|
|
11796
10711
|
errorWithTitle(
|
|
11797
10712
|
"Storage mutation rejection error",
|
|
11798
10713
|
message.reason
|
|
11799
10714
|
);
|
|
11800
|
-
|
|
11801
|
-
for (const opId of message.opIds) {
|
|
11802
|
-
const rejectedOp = context.unacknowledgedOps.get(opId);
|
|
11803
|
-
context.unacknowledgedOps.delete(opId);
|
|
11804
|
-
context.buffer.storageOperations = context.buffer.storageOperations.filter((op) => op.opId !== opId);
|
|
11805
|
-
if (rejectedOp !== void 0 && rejectedOp.type === OpCode.UPDATE_TEXT) {
|
|
11806
|
-
const node = context.pool.nodes.get(rejectedOp.id);
|
|
11807
|
-
if (node !== void 0 && isLiveText(node)) {
|
|
11808
|
-
node._rejectPendingOp(opId);
|
|
11809
|
-
needsStorageResync = true;
|
|
11810
|
-
}
|
|
11811
|
-
}
|
|
11812
|
-
}
|
|
11813
|
-
if (needsStorageResync) {
|
|
11814
|
-
refreshStorage();
|
|
11815
|
-
flushNowOrSoon();
|
|
11816
|
-
} else if (process.env.NODE_ENV !== "production") {
|
|
10715
|
+
if (process.env.NODE_ENV !== "production") {
|
|
11817
10716
|
throw new Error(
|
|
11818
10717
|
`Storage mutations rejected by server: ${message.reason}`
|
|
11819
10718
|
);
|
|
@@ -11912,11 +10811,11 @@ function createRoom(options, config) {
|
|
|
11912
10811
|
} else if (pendingFeedsRequests.has(requestId)) {
|
|
11913
10812
|
const pending = pendingFeedsRequests.get(requestId);
|
|
11914
10813
|
pendingFeedsRequests.delete(requestId);
|
|
11915
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10814
|
+
_optionalChain([pending, 'optionalAccess', _241 => _241.reject, 'call', _242 => _242(err)]);
|
|
11916
10815
|
} else if (pendingFeedMessagesRequests.has(requestId)) {
|
|
11917
10816
|
const pending = pendingFeedMessagesRequests.get(requestId);
|
|
11918
10817
|
pendingFeedMessagesRequests.delete(requestId);
|
|
11919
|
-
_optionalChain([pending, 'optionalAccess',
|
|
10818
|
+
_optionalChain([pending, 'optionalAccess', _243 => _243.reject, 'call', _244 => _244(err)]);
|
|
11920
10819
|
}
|
|
11921
10820
|
eventHub.feeds.notify(message);
|
|
11922
10821
|
break;
|
|
@@ -12070,10 +10969,10 @@ function createRoom(options, config) {
|
|
|
12070
10969
|
timeoutId,
|
|
12071
10970
|
kind,
|
|
12072
10971
|
feedId,
|
|
12073
|
-
messageId: _optionalChain([options2, 'optionalAccess',
|
|
12074
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
10972
|
+
messageId: _optionalChain([options2, 'optionalAccess', _245 => _245.messageId]),
|
|
10973
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _246 => _246.expectedClientMessageId])
|
|
12075
10974
|
});
|
|
12076
|
-
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess',
|
|
10975
|
+
if (kind === "add-message" && _optionalChain([options2, 'optionalAccess', _247 => _247.expectedClientMessageId]) === void 0) {
|
|
12077
10976
|
const q = _nullishCoalesce(pendingAddMessageFifoByFeed.get(feedId), () => ( []));
|
|
12078
10977
|
q.push(requestId);
|
|
12079
10978
|
pendingAddMessageFifoByFeed.set(feedId, q);
|
|
@@ -12124,10 +11023,10 @@ function createRoom(options, config) {
|
|
|
12124
11023
|
}
|
|
12125
11024
|
if (!matched) {
|
|
12126
11025
|
const q = pendingAddMessageFifoByFeed.get(message.feedId);
|
|
12127
|
-
const headId = _optionalChain([q, 'optionalAccess',
|
|
11026
|
+
const headId = _optionalChain([q, 'optionalAccess', _248 => _248[0]]);
|
|
12128
11027
|
if (headId !== void 0) {
|
|
12129
11028
|
const pending = pendingFeedMutations.get(headId);
|
|
12130
|
-
if (_optionalChain([pending, 'optionalAccess',
|
|
11029
|
+
if (_optionalChain([pending, 'optionalAccess', _249 => _249.kind]) === "add-message" && pending.expectedClientMessageId === void 0) {
|
|
12131
11030
|
settleFeedMutation(headId, "ok");
|
|
12132
11031
|
}
|
|
12133
11032
|
}
|
|
@@ -12163,7 +11062,7 @@ function createRoom(options, config) {
|
|
|
12163
11062
|
const unacknowledgedOps2 = [...context.unacknowledgedOps.values()];
|
|
12164
11063
|
createOrUpdateRootFromMessage(nodes);
|
|
12165
11064
|
applyAndSendOfflineOps(unacknowledgedOps2);
|
|
12166
|
-
_optionalChain([_resolveStoragePromise, 'optionalCall',
|
|
11065
|
+
_optionalChain([_resolveStoragePromise, 'optionalCall', _250 => _250()]);
|
|
12167
11066
|
notifyStorageStatus();
|
|
12168
11067
|
eventHub.storageDidLoad.notify();
|
|
12169
11068
|
}
|
|
@@ -12172,7 +11071,7 @@ function createRoom(options, config) {
|
|
|
12172
11071
|
if (!messages.some((msg) => msg.type === ClientMsgCode.FETCH_STORAGE)) {
|
|
12173
11072
|
messages.push({ type: ClientMsgCode.FETCH_STORAGE });
|
|
12174
11073
|
nodeMapBuffer.take();
|
|
12175
|
-
_optionalChain([stopwatch, 'optionalAccess',
|
|
11074
|
+
_optionalChain([stopwatch, 'optionalAccess', _251 => _251.start, 'call', _252 => _252()]);
|
|
12176
11075
|
}
|
|
12177
11076
|
}
|
|
12178
11077
|
function startLoadingStorage() {
|
|
@@ -12226,10 +11125,10 @@ function createRoom(options, config) {
|
|
|
12226
11125
|
const message = {
|
|
12227
11126
|
type: ClientMsgCode.FETCH_FEEDS,
|
|
12228
11127
|
requestId,
|
|
12229
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
12230
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
12231
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
12232
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
11128
|
+
cursor: _optionalChain([options2, 'optionalAccess', _253 => _253.cursor]),
|
|
11129
|
+
since: _optionalChain([options2, 'optionalAccess', _254 => _254.since]),
|
|
11130
|
+
limit: _optionalChain([options2, 'optionalAccess', _255 => _255.limit]),
|
|
11131
|
+
metadata: _optionalChain([options2, 'optionalAccess', _256 => _256.metadata])
|
|
12233
11132
|
};
|
|
12234
11133
|
context.buffer.messages.push(message);
|
|
12235
11134
|
flushNowOrSoon();
|
|
@@ -12249,9 +11148,9 @@ function createRoom(options, config) {
|
|
|
12249
11148
|
type: ClientMsgCode.FETCH_FEED_MESSAGES,
|
|
12250
11149
|
requestId,
|
|
12251
11150
|
feedId,
|
|
12252
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
12253
|
-
since: _optionalChain([options2, 'optionalAccess',
|
|
12254
|
-
limit: _optionalChain([options2, 'optionalAccess',
|
|
11151
|
+
cursor: _optionalChain([options2, 'optionalAccess', _257 => _257.cursor]),
|
|
11152
|
+
since: _optionalChain([options2, 'optionalAccess', _258 => _258.since]),
|
|
11153
|
+
limit: _optionalChain([options2, 'optionalAccess', _259 => _259.limit])
|
|
12255
11154
|
};
|
|
12256
11155
|
context.buffer.messages.push(message);
|
|
12257
11156
|
flushNowOrSoon();
|
|
@@ -12270,8 +11169,8 @@ function createRoom(options, config) {
|
|
|
12270
11169
|
type: ClientMsgCode.ADD_FEED,
|
|
12271
11170
|
requestId,
|
|
12272
11171
|
feedId,
|
|
12273
|
-
metadata: _optionalChain([options2, 'optionalAccess',
|
|
12274
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11172
|
+
metadata: _optionalChain([options2, 'optionalAccess', _260 => _260.metadata]),
|
|
11173
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _261 => _261.createdAt])
|
|
12275
11174
|
};
|
|
12276
11175
|
context.buffer.messages.push(message);
|
|
12277
11176
|
flushNowOrSoon();
|
|
@@ -12305,15 +11204,15 @@ function createRoom(options, config) {
|
|
|
12305
11204
|
function addFeedMessage(feedId, data, options2) {
|
|
12306
11205
|
const requestId = nanoid();
|
|
12307
11206
|
const promise = registerFeedMutation(requestId, "add-message", feedId, {
|
|
12308
|
-
expectedClientMessageId: _optionalChain([options2, 'optionalAccess',
|
|
11207
|
+
expectedClientMessageId: _optionalChain([options2, 'optionalAccess', _262 => _262.id])
|
|
12309
11208
|
});
|
|
12310
11209
|
const message = {
|
|
12311
11210
|
type: ClientMsgCode.ADD_FEED_MESSAGE,
|
|
12312
11211
|
requestId,
|
|
12313
11212
|
feedId,
|
|
12314
11213
|
data,
|
|
12315
|
-
id: _optionalChain([options2, 'optionalAccess',
|
|
12316
|
-
createdAt: _optionalChain([options2, 'optionalAccess',
|
|
11214
|
+
id: _optionalChain([options2, 'optionalAccess', _263 => _263.id]),
|
|
11215
|
+
createdAt: _optionalChain([options2, 'optionalAccess', _264 => _264.createdAt])
|
|
12317
11216
|
};
|
|
12318
11217
|
context.buffer.messages.push(message);
|
|
12319
11218
|
flushNowOrSoon();
|
|
@@ -12330,7 +11229,7 @@ function createRoom(options, config) {
|
|
|
12330
11229
|
feedId,
|
|
12331
11230
|
messageId,
|
|
12332
11231
|
data,
|
|
12333
|
-
updatedAt: _optionalChain([options2, 'optionalAccess',
|
|
11232
|
+
updatedAt: _optionalChain([options2, 'optionalAccess', _265 => _265.updatedAt])
|
|
12334
11233
|
};
|
|
12335
11234
|
context.buffer.messages.push(message);
|
|
12336
11235
|
flushNowOrSoon();
|
|
@@ -12355,19 +11254,14 @@ function createRoom(options, config) {
|
|
|
12355
11254
|
if (context.activeBatch) {
|
|
12356
11255
|
throw new Error("undo is not allowed during a batch");
|
|
12357
11256
|
}
|
|
12358
|
-
const
|
|
12359
|
-
if (
|
|
11257
|
+
const frames = context.undoStack.pop();
|
|
11258
|
+
if (frames === void 0) {
|
|
12360
11259
|
return;
|
|
12361
11260
|
}
|
|
12362
11261
|
context.pausedHistory = null;
|
|
12363
|
-
const result = applyLocalOps(
|
|
12364
|
-
origin: "local",
|
|
12365
|
-
via: "history",
|
|
12366
|
-
action: "undo"
|
|
12367
|
-
});
|
|
12368
|
-
context.redoStack.push({ id: item.id, frames: result.reverse });
|
|
12369
|
-
notifyPrivateHistory({ action: "undo", id: item.id });
|
|
11262
|
+
const result = applyLocalOps(frames);
|
|
12370
11263
|
notify(result.updates);
|
|
11264
|
+
context.redoStack.push(result.reverse);
|
|
12371
11265
|
onHistoryChange();
|
|
12372
11266
|
for (const op of result.opsToEmit) {
|
|
12373
11267
|
context.buffer.storageOperations.push(op);
|
|
@@ -12378,19 +11272,14 @@ function createRoom(options, config) {
|
|
|
12378
11272
|
if (context.activeBatch) {
|
|
12379
11273
|
throw new Error("redo is not allowed during a batch");
|
|
12380
11274
|
}
|
|
12381
|
-
const
|
|
12382
|
-
if (
|
|
11275
|
+
const frames = context.redoStack.pop();
|
|
11276
|
+
if (frames === void 0) {
|
|
12383
11277
|
return;
|
|
12384
11278
|
}
|
|
12385
11279
|
context.pausedHistory = null;
|
|
12386
|
-
const result = applyLocalOps(
|
|
12387
|
-
origin: "local",
|
|
12388
|
-
via: "history",
|
|
12389
|
-
action: "redo"
|
|
12390
|
-
});
|
|
12391
|
-
context.undoStack.push({ id: item.id, frames: result.reverse });
|
|
12392
|
-
notifyPrivateHistory({ action: "redo", id: item.id });
|
|
11280
|
+
const result = applyLocalOps(frames);
|
|
12393
11281
|
notify(result.updates);
|
|
11282
|
+
context.undoStack.push(result.reverse);
|
|
12394
11283
|
onHistoryChange();
|
|
12395
11284
|
for (const op of result.opsToEmit) {
|
|
12396
11285
|
context.buffer.storageOperations.push(op);
|
|
@@ -12400,8 +11289,6 @@ function createRoom(options, config) {
|
|
|
12400
11289
|
function clear() {
|
|
12401
11290
|
context.undoStack.length = 0;
|
|
12402
11291
|
context.redoStack.length = 0;
|
|
12403
|
-
notifyPrivateHistory({ action: "clear" });
|
|
12404
|
-
onHistoryChange();
|
|
12405
11292
|
}
|
|
12406
11293
|
function batch2(callback) {
|
|
12407
11294
|
if (context.activeBatch) {
|
|
@@ -12430,7 +11317,7 @@ function createRoom(options, config) {
|
|
|
12430
11317
|
commitPausedHistoryToUndoStack();
|
|
12431
11318
|
}
|
|
12432
11319
|
if (currentBatch.ops.length > 0) {
|
|
12433
|
-
|
|
11320
|
+
context.redoStack.length = 0;
|
|
12434
11321
|
}
|
|
12435
11322
|
if (currentBatch.ops.length > 0) {
|
|
12436
11323
|
dispatchOps(currentBatch.ops);
|
|
@@ -12459,6 +11346,7 @@ function createRoom(options, config) {
|
|
|
12459
11346
|
}
|
|
12460
11347
|
commitPausedHistoryToUndoStack();
|
|
12461
11348
|
}
|
|
11349
|
+
let historyDisabled = 0;
|
|
12462
11350
|
function disableHistory(fn) {
|
|
12463
11351
|
const origUndo = context.undoStack;
|
|
12464
11352
|
const origRedo = context.redoStack;
|
|
@@ -12548,8 +11436,8 @@ function createRoom(options, config) {
|
|
|
12548
11436
|
async function getThreads(options2) {
|
|
12549
11437
|
return httpClient.getThreads({
|
|
12550
11438
|
roomId,
|
|
12551
|
-
query: _optionalChain([options2, 'optionalAccess',
|
|
12552
|
-
cursor: _optionalChain([options2, 'optionalAccess',
|
|
11439
|
+
query: _optionalChain([options2, 'optionalAccess', _266 => _266.query]),
|
|
11440
|
+
cursor: _optionalChain([options2, 'optionalAccess', _267 => _267.cursor])
|
|
12553
11441
|
});
|
|
12554
11442
|
}
|
|
12555
11443
|
async function getThread(threadId) {
|
|
@@ -12560,6 +11448,7 @@ function createRoom(options, config) {
|
|
|
12560
11448
|
roomId,
|
|
12561
11449
|
threadId: options2.threadId,
|
|
12562
11450
|
commentId: options2.commentId,
|
|
11451
|
+
visibility: options2.visibility,
|
|
12563
11452
|
metadata: options2.metadata,
|
|
12564
11453
|
body: options2.body,
|
|
12565
11454
|
commentMetadata: options2.commentMetadata,
|
|
@@ -12671,7 +11560,7 @@ function createRoom(options, config) {
|
|
|
12671
11560
|
function getSubscriptionSettings(options2) {
|
|
12672
11561
|
return httpClient.getSubscriptionSettings({
|
|
12673
11562
|
roomId,
|
|
12674
|
-
signal: _optionalChain([options2, 'optionalAccess',
|
|
11563
|
+
signal: _optionalChain([options2, 'optionalAccess', _268 => _268.signal])
|
|
12675
11564
|
});
|
|
12676
11565
|
}
|
|
12677
11566
|
function updateSubscriptionSettings(settings) {
|
|
@@ -12693,39 +11582,24 @@ function createRoom(options, config) {
|
|
|
12693
11582
|
{
|
|
12694
11583
|
[kInternal]: {
|
|
12695
11584
|
get presenceBuffer() {
|
|
12696
|
-
return deepClone(_nullishCoalesce(_optionalChain([context, 'access',
|
|
11585
|
+
return deepClone(_nullishCoalesce(_optionalChain([context, 'access', _269 => _269.buffer, 'access', _270 => _270.presenceUpdates, 'optionalAccess', _271 => _271.data]), () => ( null)));
|
|
12697
11586
|
},
|
|
12698
11587
|
// prettier-ignore
|
|
12699
11588
|
get undoStack() {
|
|
12700
|
-
return
|
|
12701
|
-
context.undoStack.map((item) => ({
|
|
12702
|
-
id: item.id,
|
|
12703
|
-
frames: item.frames
|
|
12704
|
-
}))
|
|
12705
|
-
);
|
|
12706
|
-
},
|
|
12707
|
-
// prettier-ignore
|
|
12708
|
-
get redoStack() {
|
|
12709
|
-
return structuredClone(
|
|
12710
|
-
context.redoStack.map((item) => ({
|
|
12711
|
-
id: item.id,
|
|
12712
|
-
frames: item.frames
|
|
12713
|
-
}))
|
|
12714
|
-
);
|
|
11589
|
+
return deepClone(context.undoStack);
|
|
12715
11590
|
},
|
|
12716
11591
|
// prettier-ignore
|
|
12717
11592
|
get nodeCount() {
|
|
12718
11593
|
return context.pool.nodes.size;
|
|
12719
11594
|
},
|
|
12720
11595
|
// prettier-ignore
|
|
12721
|
-
history: eventHub.privateHistory.observable,
|
|
12722
11596
|
getYjsProvider() {
|
|
12723
11597
|
return context.yjsProvider;
|
|
12724
11598
|
},
|
|
12725
11599
|
setYjsProvider(newProvider) {
|
|
12726
|
-
_optionalChain([context, 'access',
|
|
11600
|
+
_optionalChain([context, 'access', _272 => _272.yjsProvider, 'optionalAccess', _273 => _273.off, 'call', _274 => _274("status", yjsStatusDidChange)]);
|
|
12727
11601
|
context.yjsProvider = newProvider;
|
|
12728
|
-
_optionalChain([newProvider, 'optionalAccess',
|
|
11602
|
+
_optionalChain([newProvider, 'optionalAccess', _275 => _275.on, 'call', _276 => _276("status", yjsStatusDidChange)]);
|
|
12729
11603
|
context.yjsProviderDidChange.notify();
|
|
12730
11604
|
},
|
|
12731
11605
|
yjsProviderDidChange: context.yjsProviderDidChange.observable,
|
|
@@ -12785,7 +11659,7 @@ ${dumpPool(
|
|
|
12785
11659
|
source.dispose();
|
|
12786
11660
|
}
|
|
12787
11661
|
eventHub.roomWillDestroy.notify();
|
|
12788
|
-
_optionalChain([context, 'access',
|
|
11662
|
+
_optionalChain([context, 'access', _277 => _277.yjsProvider, 'optionalAccess', _278 => _278.off, 'call', _279 => _279("status", yjsStatusDidChange)]);
|
|
12789
11663
|
syncSourceForStorage.destroy();
|
|
12790
11664
|
syncSourceForYjs.destroy();
|
|
12791
11665
|
uninstallBgTabSpy();
|
|
@@ -12947,7 +11821,7 @@ function makeClassicSubscribeFn(roomId, events, errorEvents) {
|
|
|
12947
11821
|
}
|
|
12948
11822
|
if (isLiveNode(first)) {
|
|
12949
11823
|
const node = first;
|
|
12950
|
-
if (_optionalChain([options, 'optionalAccess',
|
|
11824
|
+
if (_optionalChain([options, 'optionalAccess', _280 => _280.isDeep])) {
|
|
12951
11825
|
const storageCallback = second;
|
|
12952
11826
|
return subscribeToLiveStructureDeeply(node, storageCallback);
|
|
12953
11827
|
} else {
|
|
@@ -13037,8 +11911,8 @@ function createClient(options) {
|
|
|
13037
11911
|
const authManager = createAuthManager(options, (token) => {
|
|
13038
11912
|
currentUserId.set(() => token.uid);
|
|
13039
11913
|
});
|
|
13040
|
-
const fetchPolyfill = _optionalChain([clientOptions, 'access',
|
|
13041
|
-
_optionalChain([globalThis, 'access',
|
|
11914
|
+
const fetchPolyfill = _optionalChain([clientOptions, 'access', _281 => _281.polyfills, 'optionalAccess', _282 => _282.fetch]) || /* istanbul ignore next */
|
|
11915
|
+
_optionalChain([globalThis, 'access', _283 => _283.fetch, 'optionalAccess', _284 => _284.bind, 'call', _285 => _285(globalThis)]);
|
|
13042
11916
|
const httpClient = createApiClient({
|
|
13043
11917
|
baseUrl,
|
|
13044
11918
|
fetchPolyfill,
|
|
@@ -13055,7 +11929,7 @@ function createClient(options) {
|
|
|
13055
11929
|
delegates: {
|
|
13056
11930
|
createSocket: makeCreateSocketDelegateForAi(
|
|
13057
11931
|
baseUrl,
|
|
13058
|
-
_optionalChain([clientOptions, 'access',
|
|
11932
|
+
_optionalChain([clientOptions, 'access', _286 => _286.polyfills, 'optionalAccess', _287 => _287.WebSocket])
|
|
13059
11933
|
),
|
|
13060
11934
|
authenticate: async () => {
|
|
13061
11935
|
const resp = await authManager.getAuthValue({
|
|
@@ -13126,7 +12000,7 @@ function createClient(options) {
|
|
|
13126
12000
|
createSocket: makeCreateSocketDelegateForRoom(
|
|
13127
12001
|
roomId,
|
|
13128
12002
|
baseUrl,
|
|
13129
|
-
_optionalChain([clientOptions, 'access',
|
|
12003
|
+
_optionalChain([clientOptions, 'access', _288 => _288.polyfills, 'optionalAccess', _289 => _289.WebSocket])
|
|
13130
12004
|
),
|
|
13131
12005
|
authenticate: makeAuthDelegateForRoom(roomId, authManager)
|
|
13132
12006
|
})),
|
|
@@ -13148,7 +12022,7 @@ function createClient(options) {
|
|
|
13148
12022
|
const shouldConnect = _nullishCoalesce(options2.autoConnect, () => ( true));
|
|
13149
12023
|
if (shouldConnect) {
|
|
13150
12024
|
if (typeof atob === "undefined") {
|
|
13151
|
-
if (_optionalChain([clientOptions, 'access',
|
|
12025
|
+
if (_optionalChain([clientOptions, 'access', _290 => _290.polyfills, 'optionalAccess', _291 => _291.atob]) === void 0) {
|
|
13152
12026
|
throw new Error(
|
|
13153
12027
|
"You need to polyfill atob to use the client in your environment. Please follow the instructions at https://liveblocks.io/docs/errors/liveblocks-client/atob-polyfill"
|
|
13154
12028
|
);
|
|
@@ -13160,7 +12034,7 @@ function createClient(options) {
|
|
|
13160
12034
|
return leaseRoom(newRoomDetails);
|
|
13161
12035
|
}
|
|
13162
12036
|
function getRoom(roomId) {
|
|
13163
|
-
const room = _optionalChain([roomsById, 'access',
|
|
12037
|
+
const room = _optionalChain([roomsById, 'access', _292 => _292.get, 'call', _293 => _293(roomId), 'optionalAccess', _294 => _294.room]);
|
|
13164
12038
|
return room ? room : null;
|
|
13165
12039
|
}
|
|
13166
12040
|
function logout() {
|
|
@@ -13176,7 +12050,7 @@ function createClient(options) {
|
|
|
13176
12050
|
const batchedResolveUsers = new Batch(
|
|
13177
12051
|
async (batchedUserIds) => {
|
|
13178
12052
|
const userIds = batchedUserIds.flat();
|
|
13179
|
-
const users = await _optionalChain([resolveUsers, 'optionalCall',
|
|
12053
|
+
const users = await _optionalChain([resolveUsers, 'optionalCall', _295 => _295({ userIds })]);
|
|
13180
12054
|
warnOnceIf(
|
|
13181
12055
|
!resolveUsers,
|
|
13182
12056
|
"Set the resolveUsers option in createClient to specify user info."
|
|
@@ -13193,7 +12067,7 @@ function createClient(options) {
|
|
|
13193
12067
|
const batchedResolveRoomsInfo = new Batch(
|
|
13194
12068
|
async (batchedRoomIds) => {
|
|
13195
12069
|
const roomIds = batchedRoomIds.flat();
|
|
13196
|
-
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall',
|
|
12070
|
+
const roomsInfo = await _optionalChain([resolveRoomsInfo, 'optionalCall', _296 => _296({ roomIds })]);
|
|
13197
12071
|
warnOnceIf(
|
|
13198
12072
|
!resolveRoomsInfo,
|
|
13199
12073
|
"Set the resolveRoomsInfo option in createClient to specify room info."
|
|
@@ -13210,7 +12084,7 @@ function createClient(options) {
|
|
|
13210
12084
|
const batchedResolveGroupsInfo = new Batch(
|
|
13211
12085
|
async (batchedGroupIds) => {
|
|
13212
12086
|
const groupIds = batchedGroupIds.flat();
|
|
13213
|
-
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall',
|
|
12087
|
+
const groupsInfo = await _optionalChain([resolveGroupsInfo, 'optionalCall', _297 => _297({ groupIds })]);
|
|
13214
12088
|
warnOnceIf(
|
|
13215
12089
|
!resolveGroupsInfo,
|
|
13216
12090
|
"Set the resolveGroupsInfo option in createClient to specify group info."
|
|
@@ -13269,7 +12143,7 @@ function createClient(options) {
|
|
|
13269
12143
|
}
|
|
13270
12144
|
};
|
|
13271
12145
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
13272
|
-
_optionalChain([win, 'optionalAccess',
|
|
12146
|
+
_optionalChain([win, 'optionalAccess', _298 => _298.addEventListener, 'call', _299 => _299("beforeunload", maybePreventClose)]);
|
|
13273
12147
|
}
|
|
13274
12148
|
async function getNotificationSettings(options2) {
|
|
13275
12149
|
const plainSettings = await httpClient.getNotificationSettings(options2);
|
|
@@ -13397,7 +12271,7 @@ var commentBodyElementsTypes = {
|
|
|
13397
12271
|
mention: "inline"
|
|
13398
12272
|
};
|
|
13399
12273
|
function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
13400
|
-
if (!body || !_optionalChain([body, 'optionalAccess',
|
|
12274
|
+
if (!body || !_optionalChain([body, 'optionalAccess', _300 => _300.content])) {
|
|
13401
12275
|
return;
|
|
13402
12276
|
}
|
|
13403
12277
|
const element = typeof elementOrVisitor === "string" ? elementOrVisitor : void 0;
|
|
@@ -13407,13 +12281,13 @@ function traverseCommentBody(body, elementOrVisitor, possiblyVisitor) {
|
|
|
13407
12281
|
for (const block of body.content) {
|
|
13408
12282
|
if (type === "all" || type === "block") {
|
|
13409
12283
|
if (guard(block)) {
|
|
13410
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12284
|
+
_optionalChain([visitor, 'optionalCall', _301 => _301(block)]);
|
|
13411
12285
|
}
|
|
13412
12286
|
}
|
|
13413
12287
|
if (type === "all" || type === "inline") {
|
|
13414
12288
|
for (const inline of block.children) {
|
|
13415
12289
|
if (guard(inline)) {
|
|
13416
|
-
_optionalChain([visitor, 'optionalCall',
|
|
12290
|
+
_optionalChain([visitor, 'optionalCall', _302 => _302(inline)]);
|
|
13417
12291
|
}
|
|
13418
12292
|
}
|
|
13419
12293
|
}
|
|
@@ -13583,7 +12457,7 @@ var stringifyCommentBodyPlainElements = {
|
|
|
13583
12457
|
text: ({ element }) => element.text,
|
|
13584
12458
|
link: ({ element }) => _nullishCoalesce(element.text, () => ( element.url)),
|
|
13585
12459
|
mention: ({ element, user, group }) => {
|
|
13586
|
-
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12460
|
+
return `@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _303 => _303.name]), () => ( _optionalChain([group, 'optionalAccess', _304 => _304.name]))), () => ( element.id))}`;
|
|
13587
12461
|
}
|
|
13588
12462
|
};
|
|
13589
12463
|
var stringifyCommentBodyHtmlElements = {
|
|
@@ -13613,7 +12487,7 @@ var stringifyCommentBodyHtmlElements = {
|
|
|
13613
12487
|
return html`<a href="${href}" target="_blank" rel="noopener noreferrer">${element.text ? html`${element.text}` : element.url}</a>`;
|
|
13614
12488
|
},
|
|
13615
12489
|
mention: ({ element, user, group }) => {
|
|
13616
|
-
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess',
|
|
12490
|
+
return html`<span data-mention>@${_optionalChain([user, 'optionalAccess', _305 => _305.name]) ? html`${_optionalChain([user, 'optionalAccess', _306 => _306.name])}` : _optionalChain([group, 'optionalAccess', _307 => _307.name]) ? html`${_optionalChain([group, 'optionalAccess', _308 => _308.name])}` : element.id}</span>`;
|
|
13617
12491
|
}
|
|
13618
12492
|
};
|
|
13619
12493
|
var stringifyCommentBodyMarkdownElements = {
|
|
@@ -13643,20 +12517,20 @@ var stringifyCommentBodyMarkdownElements = {
|
|
|
13643
12517
|
return markdown`[${_nullishCoalesce(element.text, () => ( element.url))}](${href})`;
|
|
13644
12518
|
},
|
|
13645
12519
|
mention: ({ element, user, group }) => {
|
|
13646
|
-
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess',
|
|
12520
|
+
return markdown`@${_nullishCoalesce(_nullishCoalesce(_optionalChain([user, 'optionalAccess', _309 => _309.name]), () => ( _optionalChain([group, 'optionalAccess', _310 => _310.name]))), () => ( element.id))}`;
|
|
13647
12521
|
}
|
|
13648
12522
|
};
|
|
13649
12523
|
async function stringifyCommentBody(body, options) {
|
|
13650
|
-
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
13651
|
-
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12524
|
+
const format = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _311 => _311.format]), () => ( "plain"));
|
|
12525
|
+
const separator = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _312 => _312.separator]), () => ( (format === "markdown" ? "\n\n" : "\n")));
|
|
13652
12526
|
const elements = {
|
|
13653
12527
|
...format === "html" ? stringifyCommentBodyHtmlElements : format === "markdown" ? stringifyCommentBodyMarkdownElements : stringifyCommentBodyPlainElements,
|
|
13654
|
-
..._optionalChain([options, 'optionalAccess',
|
|
12528
|
+
..._optionalChain([options, 'optionalAccess', _313 => _313.elements])
|
|
13655
12529
|
};
|
|
13656
12530
|
const { users: resolvedUsers, groups: resolvedGroupsInfo } = await resolveMentionsInCommentBody(
|
|
13657
12531
|
body,
|
|
13658
|
-
_optionalChain([options, 'optionalAccess',
|
|
13659
|
-
_optionalChain([options, 'optionalAccess',
|
|
12532
|
+
_optionalChain([options, 'optionalAccess', _314 => _314.resolveUsers]),
|
|
12533
|
+
_optionalChain([options, 'optionalAccess', _315 => _315.resolveGroupsInfo])
|
|
13660
12534
|
);
|
|
13661
12535
|
const blocks = body.content.flatMap((block, blockIndex) => {
|
|
13662
12536
|
switch (block.type) {
|
|
@@ -13738,12 +12612,6 @@ function toPlainLson(lson) {
|
|
|
13738
12612
|
liveblocksType: "LiveList",
|
|
13739
12613
|
data: [...lson].map((item) => toPlainLson(item))
|
|
13740
12614
|
};
|
|
13741
|
-
} else if (lson instanceof LiveText) {
|
|
13742
|
-
return {
|
|
13743
|
-
liveblocksType: "LiveText",
|
|
13744
|
-
data: lson.toJSON(),
|
|
13745
|
-
version: lson.version
|
|
13746
|
-
};
|
|
13747
12615
|
} else {
|
|
13748
12616
|
return lson;
|
|
13749
12617
|
}
|
|
@@ -13797,9 +12665,9 @@ function makePoller(callback, intervalMs, options) {
|
|
|
13797
12665
|
const startTime = performance.now();
|
|
13798
12666
|
const doc = typeof document !== "undefined" ? document : void 0;
|
|
13799
12667
|
const win = typeof window !== "undefined" ? window : void 0;
|
|
13800
|
-
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess',
|
|
12668
|
+
const maxStaleTimeMs = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _316 => _316.maxStaleTimeMs]), () => ( Number.POSITIVE_INFINITY));
|
|
13801
12669
|
const context = {
|
|
13802
|
-
inForeground: _optionalChain([doc, 'optionalAccess',
|
|
12670
|
+
inForeground: _optionalChain([doc, 'optionalAccess', _317 => _317.visibilityState]) !== "hidden",
|
|
13803
12671
|
lastSuccessfulPollAt: startTime,
|
|
13804
12672
|
count: 0,
|
|
13805
12673
|
backoff: 0
|
|
@@ -13880,11 +12748,11 @@ function makePoller(callback, intervalMs, options) {
|
|
|
13880
12748
|
pollNowIfStale();
|
|
13881
12749
|
}
|
|
13882
12750
|
function onVisibilityChange() {
|
|
13883
|
-
setInForeground(_optionalChain([doc, 'optionalAccess',
|
|
12751
|
+
setInForeground(_optionalChain([doc, 'optionalAccess', _318 => _318.visibilityState]) !== "hidden");
|
|
13884
12752
|
}
|
|
13885
|
-
_optionalChain([doc, 'optionalAccess',
|
|
13886
|
-
_optionalChain([win, 'optionalAccess',
|
|
13887
|
-
_optionalChain([win, 'optionalAccess',
|
|
12753
|
+
_optionalChain([doc, 'optionalAccess', _319 => _319.addEventListener, 'call', _320 => _320("visibilitychange", onVisibilityChange)]);
|
|
12754
|
+
_optionalChain([win, 'optionalAccess', _321 => _321.addEventListener, 'call', _322 => _322("online", onVisibilityChange)]);
|
|
12755
|
+
_optionalChain([win, 'optionalAccess', _323 => _323.addEventListener, 'call', _324 => _324("focus", pollNowIfStale)]);
|
|
13888
12756
|
fsm.start();
|
|
13889
12757
|
return {
|
|
13890
12758
|
inc,
|
|
@@ -14029,10 +12897,5 @@ detectDupes(PKG_NAME, PKG_VERSION, PKG_FORMAT);
|
|
|
14029
12897
|
|
|
14030
12898
|
|
|
14031
12899
|
|
|
14032
|
-
|
|
14033
|
-
|
|
14034
|
-
|
|
14035
|
-
|
|
14036
|
-
|
|
14037
|
-
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveText = LiveText; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.applyLiveTextOperations = applyLiveTextOperations; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isTextStorageNode = isTextStorageNode; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.kStorageUpdateSource = kStorageUpdateSource; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.transformTextOperations = transformTextOperations; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
12900
|
+
exports.ClientMsgCode = ClientMsgCode; exports.CrdtType = CrdtType; exports.DefaultMap = DefaultMap; exports.Deque = Deque; exports.DerivedSignal = DerivedSignal; exports.FeedRequestErrorCode = FeedRequestErrorCode; exports.HttpError = HttpError; exports.LiveList = LiveList; exports.LiveMap = LiveMap; exports.LiveObject = LiveObject; exports.LiveblocksError = LiveblocksError; exports.MENTION_CHARACTER = MENTION_CHARACTER; exports.MutableSignal = MutableSignal; exports.OpCode = OpCode; exports.Permission = Permission; exports.Promise_withResolvers = Promise_withResolvers; exports.ServerMsgCode = ServerMsgCode; exports.Signal = Signal; exports.SortedList = SortedList; exports.TextEditorType = TextEditorType; exports.WebsocketCloseCodes = WebsocketCloseCodes; exports.asPos = asPos; exports.assert = assert; exports.assertNever = assertNever; exports.autoRetry = autoRetry; exports.b64decode = b64decode; exports.batch = batch; exports.checkBounds = checkBounds; exports.chunk = chunk; exports.cloneLson = cloneLson; exports.compactNodesToNodeStream = compactNodesToNodeStream; exports.compactObject = compactObject; exports.console = fancy_console_exports; exports.convertToCommentData = convertToCommentData; exports.convertToCommentUserReaction = convertToCommentUserReaction; exports.convertToGroupData = convertToGroupData; exports.convertToInboxNotificationData = convertToInboxNotificationData; exports.convertToSubscriptionData = convertToSubscriptionData; exports.convertToThreadData = convertToThreadData; exports.convertToUserSubscriptionData = convertToUserSubscriptionData; exports.createClient = createClient; exports.createCommentAttachmentId = createCommentAttachmentId; exports.createCommentId = createCommentId; exports.createInboxNotificationId = createInboxNotificationId; exports.createManagedPool = createManagedPool; exports.createNotificationSettings = createNotificationSettings; exports.createThreadId = createThreadId; exports.deepLiveify = deepLiveify; exports.defineAiTool = defineAiTool; exports.deprecate = deprecate; exports.deprecateIf = deprecateIf; exports.detectDupes = detectDupes; exports.entries = entries; exports.errorIf = errorIf; exports.findLastIndex = findLastIndex; exports.freeze = freeze; exports.generateUrl = generateUrl; exports.getMentionsFromCommentBody = getMentionsFromCommentBody; exports.getSubscriptionKey = getSubscriptionKey; exports.hasPermissionAccess = hasPermissionAccess; exports.html = html; exports.htmlSafe = htmlSafe; exports.isCommentBodyLink = isCommentBodyLink; exports.isCommentBodyMention = isCommentBodyMention; exports.isCommentBodyText = isCommentBodyText; exports.isJsonArray = isJsonArray; exports.isJsonObject = isJsonObject; exports.isJsonScalar = isJsonScalar; exports.isListStorageNode = isListStorageNode; exports.isLiveNode = isLiveNode; exports.isMapStorageNode = isMapStorageNode; exports.isNotificationChannelEnabled = isNotificationChannelEnabled; exports.isNumberOperator = isNumberOperator; exports.isObjectStorageNode = isObjectStorageNode; exports.isPlainObject = isPlainObject; exports.isRegisterStorageNode = isRegisterStorageNode; exports.isRootStorageNode = isRootStorageNode; exports.isStartsWithOperator = isStartsWithOperator; exports.isUrl = isUrl; exports.kInternal = kInternal; exports.keys = keys; exports.makeAbortController = makeAbortController; exports.makeEventSource = makeEventSource; exports.makePoller = makePoller; exports.makePosition = makePosition; exports.mapValues = mapValues; exports.memoizeOnSuccess = memoizeOnSuccess; exports.mergeRoomPermissionScopes = mergeRoomPermissionScopes; exports.nanoid = nanoid; exports.nn = nn; exports.nodeStreamToCompactNodes = nodeStreamToCompactNodes; exports.normalizeRoomAccesses = normalizeRoomAccesses; exports.normalizeRoomPermissions = normalizeRoomPermissions; exports.normalizeUpdateRoomAccesses = normalizeUpdateRoomAccesses; exports.objectToQuery = objectToQuery; exports.patchNotificationSettings = patchNotificationSettings; exports.permissionMatrixFromScopes = permissionMatrixFromScopes; exports.raise = raise; exports.resolveMentionsInCommentBody = resolveMentionsInCommentBody; exports.sanitizeUrl = sanitizeUrl; exports.shallow = shallow; exports.shallow2 = shallow2; exports.stableStringify = stableStringify; exports.stringifyCommentBody = stringifyCommentBody; exports.throwUsageError = throwUsageError; exports.toPlainLson = toPlainLson; exports.tryParseJson = tryParseJson; exports.url = url; exports.urljoin = urljoin; exports.validatePermissionsSet = validatePermissionsSet; exports.wait = wait; exports.warnOnce = warnOnce; exports.warnOnceIf = warnOnceIf; exports.withTimeout = withTimeout;
|
|
14038
12901
|
//# sourceMappingURL=index.cjs.map
|