@liveblocks/core 3.19.1 → 3.19.3
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 +51 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +51 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
|
|
7
7
|
// src/version.ts
|
|
8
8
|
var PKG_NAME = "@liveblocks/core";
|
|
9
|
-
var PKG_VERSION = "3.19.
|
|
9
|
+
var PKG_VERSION = "3.19.3";
|
|
10
10
|
var PKG_FORMAT = "esm";
|
|
11
11
|
|
|
12
12
|
// src/dupe-detection.ts
|
|
@@ -2715,6 +2715,7 @@ var HttpClient = class {
|
|
|
2715
2715
|
};
|
|
2716
2716
|
|
|
2717
2717
|
// src/lib/fsm.ts
|
|
2718
|
+
var IGNORE = /* @__PURE__ */ Symbol("fsm.ignore");
|
|
2718
2719
|
function distance(state1, state2) {
|
|
2719
2720
|
if (state1 === state2) {
|
|
2720
2721
|
return [0, 0];
|
|
@@ -2887,7 +2888,7 @@ var FSM = class {
|
|
|
2887
2888
|
this.#eventHub = {
|
|
2888
2889
|
didReceiveEvent: makeEventSource(),
|
|
2889
2890
|
willTransition: makeEventSource(),
|
|
2890
|
-
|
|
2891
|
+
didIgnoreUnexpectedEvent: makeEventSource(),
|
|
2891
2892
|
willExitState: makeEventSource(),
|
|
2892
2893
|
didEnterState: makeEventSource(),
|
|
2893
2894
|
didExitState: makeEventSource()
|
|
@@ -2895,7 +2896,7 @@ var FSM = class {
|
|
|
2895
2896
|
this.events = {
|
|
2896
2897
|
didReceiveEvent: this.#eventHub.didReceiveEvent.observable,
|
|
2897
2898
|
willTransition: this.#eventHub.willTransition.observable,
|
|
2898
|
-
|
|
2899
|
+
didIgnoreUnexpectedEvent: this.#eventHub.didIgnoreUnexpectedEvent.observable,
|
|
2899
2900
|
willExitState: this.#eventHub.willExitState.observable,
|
|
2900
2901
|
didEnterState: this.#eventHub.didEnterState.observable,
|
|
2901
2902
|
didExitState: this.#eventHub.didExitState.observable
|
|
@@ -3018,9 +3019,14 @@ var FSM = class {
|
|
|
3018
3019
|
* `context` params to conditionally decide which next state to transition
|
|
3019
3020
|
* to.
|
|
3020
3021
|
*
|
|
3021
|
-
* If you
|
|
3022
|
-
*
|
|
3023
|
-
*
|
|
3022
|
+
* If you don't define a target for a transition, the event is treated
|
|
3023
|
+
* as unhandled in this state: `didIgnoreUnexpectedEvent` fires and the
|
|
3024
|
+
* state does not change.
|
|
3025
|
+
*
|
|
3026
|
+
* To declare an event as an intentional silent no-op in this state, use
|
|
3027
|
+
* the {@link IGNORE} sentinel — either statically (`{ EVENT: IGNORE }`)
|
|
3028
|
+
* or as a return value from a target function. IGNORE'd events do not
|
|
3029
|
+
* fire `didIgnoreUnexpectedEvent`.
|
|
3024
3030
|
*/
|
|
3025
3031
|
addTransitions(nameOrPattern, mapping) {
|
|
3026
3032
|
if (this.#runningState !== 0 /* NOT_STARTED_YET */) {
|
|
@@ -3040,7 +3046,12 @@ var FSM = class {
|
|
|
3040
3046
|
}
|
|
3041
3047
|
const target = target_;
|
|
3042
3048
|
this.#knownEventTypes.add(type);
|
|
3043
|
-
if (target
|
|
3049
|
+
if (target === void 0) {
|
|
3050
|
+
continue;
|
|
3051
|
+
}
|
|
3052
|
+
if (target === IGNORE) {
|
|
3053
|
+
map.set(type, IGNORE);
|
|
3054
|
+
} else {
|
|
3044
3055
|
const targetFn = typeof target === "function" ? target : () => target;
|
|
3045
3056
|
map.set(type, targetFn);
|
|
3046
3057
|
}
|
|
@@ -3139,12 +3150,14 @@ var FSM = class {
|
|
|
3139
3150
|
if (this.#runningState === 2 /* STOPPED */) {
|
|
3140
3151
|
return;
|
|
3141
3152
|
}
|
|
3142
|
-
const
|
|
3143
|
-
if (
|
|
3144
|
-
return
|
|
3145
|
-
}
|
|
3146
|
-
|
|
3153
|
+
const entry = this.#getTargetFn(event.type);
|
|
3154
|
+
if (entry === IGNORE) {
|
|
3155
|
+
return;
|
|
3156
|
+
}
|
|
3157
|
+
if (entry !== void 0) {
|
|
3158
|
+
return this.#transition(event, entry);
|
|
3147
3159
|
}
|
|
3160
|
+
this.#eventHub.didIgnoreUnexpectedEvent.notify(event);
|
|
3148
3161
|
}
|
|
3149
3162
|
#transition(event, target) {
|
|
3150
3163
|
this.#eventHub.didReceiveEvent.notify(event);
|
|
@@ -3153,8 +3166,7 @@ var FSM = class {
|
|
|
3153
3166
|
const nextTarget = targetFn(event, this.#currentContext.current);
|
|
3154
3167
|
let nextState;
|
|
3155
3168
|
let effects = void 0;
|
|
3156
|
-
if (nextTarget ===
|
|
3157
|
-
this.#eventHub.didIgnoreEvent.notify(event);
|
|
3169
|
+
if (nextTarget === IGNORE) {
|
|
3158
3170
|
return;
|
|
3159
3171
|
}
|
|
3160
3172
|
if (typeof nextTarget === "string") {
|
|
@@ -3373,8 +3385,8 @@ function enableTracing(machine) {
|
|
|
3373
3385
|
machine.events.didExitState.subscribe(
|
|
3374
3386
|
({ state, durationMs }) => log2(`Exited ${state} after ${durationMs.toFixed(0)}ms`)
|
|
3375
3387
|
),
|
|
3376
|
-
machine.events.
|
|
3377
|
-
(e) => log2("Ignored event", e.type, e, "(
|
|
3388
|
+
machine.events.didIgnoreUnexpectedEvent.subscribe(
|
|
3389
|
+
(e) => log2("Ignored unexpected event", e.type, e, "(no transition declared)")
|
|
3378
3390
|
)
|
|
3379
3391
|
];
|
|
3380
3392
|
return () => {
|
|
@@ -3486,7 +3498,12 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3486
3498
|
);
|
|
3487
3499
|
const onSocketError = (event) => machine.send({ type: "EXPLICIT_SOCKET_ERROR", event });
|
|
3488
3500
|
const onSocketClose = (event) => machine.send({ type: "EXPLICIT_SOCKET_CLOSE", event });
|
|
3489
|
-
const onSocketMessage = (event) =>
|
|
3501
|
+
const onSocketMessage = (event) => {
|
|
3502
|
+
machine.send({ type: "ALIVE" });
|
|
3503
|
+
if (event.data !== "pong") {
|
|
3504
|
+
onMessage.notify(event);
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3490
3507
|
function teardownSocket(socket) {
|
|
3491
3508
|
if (socket) {
|
|
3492
3509
|
socket.removeEventListener("error", onSocketError);
|
|
@@ -3656,7 +3673,13 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3656
3673
|
effect: [increaseBackoffDelay, logPrematureErrorOrCloseEvent(err)]
|
|
3657
3674
|
};
|
|
3658
3675
|
}
|
|
3659
|
-
)
|
|
3676
|
+
).addTransitions("@connecting.busy", {
|
|
3677
|
+
// The socket message listener is attached during @connecting.busy (see
|
|
3678
|
+
// onEnterAsync above), so server frames (most notably the actor-id
|
|
3679
|
+
// handshake) can fire onSocketMessage and emit a ALIVE before we
|
|
3680
|
+
// reach @ok.*. That's fine. Heartbeat only matters in @ok.*.
|
|
3681
|
+
ALIVE: IGNORE
|
|
3682
|
+
});
|
|
3660
3683
|
const sendHeartbeat = {
|
|
3661
3684
|
target: "@ok.awaiting-pong",
|
|
3662
3685
|
effect: (ctx) => {
|
|
@@ -3671,7 +3694,8 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3671
3694
|
machine.addTimedTransition("@ok.connected", HEARTBEAT_INTERVAL, maybeHeartbeat).addTransitions("@ok.connected", {
|
|
3672
3695
|
NAVIGATOR_OFFLINE: maybeHeartbeat,
|
|
3673
3696
|
// Don't take the browser's word for it when it says it's offline. Do a ping/pong to make sure.
|
|
3674
|
-
WINDOW_GOT_FOCUS: sendHeartbeat
|
|
3697
|
+
WINDOW_GOT_FOCUS: sendHeartbeat,
|
|
3698
|
+
ALIVE: IGNORE
|
|
3675
3699
|
});
|
|
3676
3700
|
machine.addTransitions("@idle.zombie", {
|
|
3677
3701
|
WINDOW_GOT_FOCUS: "@connecting.backoff"
|
|
@@ -3692,7 +3716,7 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3692
3716
|
clearTimeout(timerID);
|
|
3693
3717
|
onMessage.pause();
|
|
3694
3718
|
};
|
|
3695
|
-
}).addTransitions("@ok.awaiting-pong", {
|
|
3719
|
+
}).addTransitions("@ok.awaiting-pong", { ALIVE: "@ok.connected" }).addTimedTransition("@ok.awaiting-pong", PONG_TIMEOUT, {
|
|
3696
3720
|
target: "@connecting.busy",
|
|
3697
3721
|
// Log implicit connection loss and drop the current open socket
|
|
3698
3722
|
effect: log(
|
|
@@ -3705,7 +3729,7 @@ function createConnectionStateMachine(delegates, options) {
|
|
|
3705
3729
|
// not. When still OPEN, don't transition.
|
|
3706
3730
|
EXPLICIT_SOCKET_ERROR: (_, context) => {
|
|
3707
3731
|
if (context.socket?.readyState === 1) {
|
|
3708
|
-
return
|
|
3732
|
+
return IGNORE;
|
|
3709
3733
|
}
|
|
3710
3734
|
return {
|
|
3711
3735
|
target: "@connecting.backoff",
|
|
@@ -9296,10 +9320,10 @@ function createRoom(options, config) {
|
|
|
9296
9320
|
// - The `backgroundKeepAliveTimeout` client option is configured
|
|
9297
9321
|
// - The browser window has been in the background for at least
|
|
9298
9322
|
// `backgroundKeepAliveTimeout` milliseconds
|
|
9299
|
-
// - There are no pending changes
|
|
9323
|
+
// - There are no pending changes scoped to this room (Storage, Yjs)
|
|
9300
9324
|
//
|
|
9301
9325
|
canZombie() {
|
|
9302
|
-
return config.backgroundKeepAliveTimeout !== void 0 && inBackgroundSince.current !== null && Date.now() > inBackgroundSince.current + config.backgroundKeepAliveTimeout &&
|
|
9326
|
+
return config.backgroundKeepAliveTimeout !== void 0 && inBackgroundSince.current !== null && Date.now() > inBackgroundSince.current + config.backgroundKeepAliveTimeout && syncSourceForStorage.getStatus() !== "synchronizing" && syncSourceForYjs.getStatus() !== "synchronizing";
|
|
9303
9327
|
}
|
|
9304
9328
|
};
|
|
9305
9329
|
const managedSocket = new ManagedSocket(
|
|
@@ -11394,6 +11418,9 @@ function createClient(options) {
|
|
|
11394
11418
|
function setSyncStatus(status) {
|
|
11395
11419
|
source.set(status);
|
|
11396
11420
|
}
|
|
11421
|
+
function getStatus() {
|
|
11422
|
+
return source.get();
|
|
11423
|
+
}
|
|
11397
11424
|
function destroy() {
|
|
11398
11425
|
unsub();
|
|
11399
11426
|
const index = syncStatusSources.findIndex((item) => item === source);
|
|
@@ -11405,7 +11432,7 @@ function createClient(options) {
|
|
|
11405
11432
|
}
|
|
11406
11433
|
}
|
|
11407
11434
|
}
|
|
11408
|
-
return { setSyncStatus, destroy };
|
|
11435
|
+
return { setSyncStatus, getStatus, destroy };
|
|
11409
11436
|
}
|
|
11410
11437
|
{
|
|
11411
11438
|
const maybePreventClose = (e) => {
|