capnweb-experimental-hibernation 0.6.3 → 0.6.5
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-workers.cjs +76 -28
- package/dist/index-workers.cjs.map +1 -1
- package/dist/index-workers.d.cts +1 -1
- package/dist/index-workers.d.ts +1 -1
- package/dist/index-workers.js +76 -29
- package/dist/index-workers.js.map +1 -1
- package/dist/index.cjs +76 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +41 -89
- package/dist/index.d.ts +41 -89
- package/dist/index.js +76 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index-workers.cjs
CHANGED
|
@@ -2853,15 +2853,16 @@ var RpcSessionImpl = class {
|
|
|
2853
2853
|
}
|
|
2854
2854
|
sendCall(id, path, args) {
|
|
2855
2855
|
if (this.abortReason) throw this.abortReason;
|
|
2856
|
-
let entry = new ImportTableEntry(this, this.imports.length, false);
|
|
2857
|
-
this.imports.push(entry);
|
|
2858
2856
|
let value = ["pipeline", id, path];
|
|
2859
2857
|
if (args) {
|
|
2860
2858
|
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
2861
2859
|
value.push(devalue[0]);
|
|
2862
2860
|
}
|
|
2863
|
-
this.
|
|
2864
|
-
this.
|
|
2861
|
+
const importId = this.imports.length;
|
|
2862
|
+
this.send(["push", importId, value]);
|
|
2863
|
+
const entry = new ImportTableEntry(this, importId, false);
|
|
2864
|
+
this.imports.push(entry);
|
|
2865
|
+
this.trace("sendCall", { importId, targetImportId: id, pathLength: path.length, hasArgs: !!args });
|
|
2865
2866
|
return new RpcImportHook(
|
|
2866
2867
|
/*isPromise=*/
|
|
2867
2868
|
true,
|
|
@@ -2870,7 +2871,11 @@ var RpcSessionImpl = class {
|
|
|
2870
2871
|
}
|
|
2871
2872
|
sendStream(id, path, args) {
|
|
2872
2873
|
if (this.abortReason) throw this.abortReason;
|
|
2873
|
-
let
|
|
2874
|
+
let value = ["pipeline", id, path];
|
|
2875
|
+
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
2876
|
+
value.push(devalue[0]);
|
|
2877
|
+
const importId = this.imports.length;
|
|
2878
|
+
let size = this.send(["stream", importId, value]);
|
|
2874
2879
|
let entry = new ImportTableEntry(
|
|
2875
2880
|
this,
|
|
2876
2881
|
importId,
|
|
@@ -2880,10 +2885,6 @@ var RpcSessionImpl = class {
|
|
|
2880
2885
|
entry.remoteRefcount = 0;
|
|
2881
2886
|
entry.localRefcount = 1;
|
|
2882
2887
|
this.imports.push(entry);
|
|
2883
|
-
let value = ["pipeline", id, path];
|
|
2884
|
-
let devalue = Devaluator.devaluate(args.value, void 0, this, args);
|
|
2885
|
-
value.push(devalue[0]);
|
|
2886
|
-
let size = this.send(["stream", importId, value]);
|
|
2887
2888
|
this.trace("sendStream", { importId, targetImportId: id, pathLength: path.length, size });
|
|
2888
2889
|
let promise = entry.awaitResolution().then(
|
|
2889
2890
|
(p) => {
|
|
@@ -2905,18 +2906,19 @@ var RpcSessionImpl = class {
|
|
|
2905
2906
|
throw this.abortReason;
|
|
2906
2907
|
}
|
|
2907
2908
|
let devaluedCaptures = captures.map((hook) => {
|
|
2908
|
-
let
|
|
2909
|
-
if (
|
|
2910
|
-
return ["import",
|
|
2909
|
+
let importId2 = this.getImport(hook);
|
|
2910
|
+
if (importId2 !== void 0) {
|
|
2911
|
+
return ["import", importId2];
|
|
2911
2912
|
} else {
|
|
2912
2913
|
return ["export", this.exportStub(hook)];
|
|
2913
2914
|
}
|
|
2914
2915
|
});
|
|
2915
2916
|
let value = ["remap", id, path, devaluedCaptures, instructions];
|
|
2916
|
-
|
|
2917
|
+
const importId = this.imports.length;
|
|
2918
|
+
this.send(["push", importId, value]);
|
|
2919
|
+
const entry = new ImportTableEntry(this, importId, false);
|
|
2917
2920
|
this.imports.push(entry);
|
|
2918
|
-
this.
|
|
2919
|
-
this.trace("sendMap", { importId: entry.importId, targetImportId: id, pathLength: path.length, captureCount: captures.length });
|
|
2921
|
+
this.trace("sendMap", { importId, targetImportId: id, pathLength: path.length, captureCount: captures.length });
|
|
2920
2922
|
return new RpcImportHook(
|
|
2921
2923
|
/*isPromise=*/
|
|
2922
2924
|
true,
|
|
@@ -2989,8 +2991,9 @@ var RpcSessionImpl = class {
|
|
|
2989
2991
|
case "push":
|
|
2990
2992
|
if (msg.length > 2 && typeof msg[1] === "number") {
|
|
2991
2993
|
let exportId = msg[1];
|
|
2994
|
+
let sourceExpr = cloneRpcExpr(msg[2]);
|
|
2992
2995
|
if (containsImportedCapabilityReference(msg[2])) {
|
|
2993
|
-
this.importReplays.push({ expr:
|
|
2996
|
+
this.importReplays.push({ expr: sourceExpr });
|
|
2994
2997
|
this.trace("readLoop.push.recordImportReplay", {
|
|
2995
2998
|
exportId,
|
|
2996
2999
|
replayCount: this.importReplays.length
|
|
@@ -3002,7 +3005,7 @@ var RpcSessionImpl = class {
|
|
|
3002
3005
|
this.replacePositiveExport(exportId, {
|
|
3003
3006
|
hook,
|
|
3004
3007
|
refcount: 1,
|
|
3005
|
-
sourceExpr
|
|
3008
|
+
sourceExpr
|
|
3006
3009
|
});
|
|
3007
3010
|
this.trace("readLoop.push", { exportId, hookType: hook.constructor?.name ?? null });
|
|
3008
3011
|
continue;
|
|
@@ -3011,13 +3014,14 @@ var RpcSessionImpl = class {
|
|
|
3011
3014
|
case "stream": {
|
|
3012
3015
|
if (msg.length > 2 && typeof msg[1] === "number") {
|
|
3013
3016
|
let exportId = msg[1];
|
|
3017
|
+
let sourceExpr = cloneRpcExpr(msg[2]);
|
|
3014
3018
|
let payload = this.evaluateWithCurrentProvenance(msg[2]);
|
|
3015
3019
|
let hook = new PayloadStubHook(payload);
|
|
3016
3020
|
hook.ignoreUnhandledRejections();
|
|
3017
3021
|
this.replacePositiveExport(exportId, {
|
|
3018
3022
|
hook,
|
|
3019
3023
|
refcount: 1,
|
|
3020
|
-
sourceExpr
|
|
3024
|
+
sourceExpr,
|
|
3021
3025
|
autoRelease: true
|
|
3022
3026
|
});
|
|
3023
3027
|
this.trace("readLoop.stream", { exportId, hookType: hook.constructor?.name ?? null });
|
|
@@ -3386,7 +3390,10 @@ async function __experimental_newHibernatableWebSocketRpcSession(webSocket, loca
|
|
|
3386
3390
|
webSocket.close(1011, "stale session");
|
|
3387
3391
|
} catch {
|
|
3388
3392
|
}
|
|
3389
|
-
|
|
3393
|
+
if (options.sessionStore) {
|
|
3394
|
+
await options.sessionStore.delete(sessionId);
|
|
3395
|
+
}
|
|
3396
|
+
return void 0;
|
|
3390
3397
|
}
|
|
3391
3398
|
throw err;
|
|
3392
3399
|
}
|
|
@@ -3410,6 +3417,11 @@ async function __experimental_newHibernatableWebSocketRpcSession(webSocket, loca
|
|
|
3410
3417
|
},
|
|
3411
3418
|
handleClose(code, reason, wasClean) {
|
|
3412
3419
|
transport.notifyClosed(code, reason, wasClean);
|
|
3420
|
+
if (options.sessionStore) {
|
|
3421
|
+
options.sessionStore.delete(sessionId).catch((err) => {
|
|
3422
|
+
console.error(`[capnweb] Failed to delete session ${sessionId} from store:`, err);
|
|
3423
|
+
});
|
|
3424
|
+
}
|
|
3413
3425
|
},
|
|
3414
3426
|
handleError(error) {
|
|
3415
3427
|
transport.notifyError(error);
|
|
@@ -3418,24 +3430,35 @@ async function __experimental_newHibernatableWebSocketRpcSession(webSocket, loca
|
|
|
3418
3430
|
async function persistSnapshot() {
|
|
3419
3431
|
try {
|
|
3420
3432
|
let snap = rpc.__experimental_snapshot();
|
|
3421
|
-
webSocket.serializeAttachment?.({
|
|
3422
|
-
sessionId,
|
|
3423
|
-
version: 1,
|
|
3424
|
-
snapshot: snap
|
|
3425
|
-
});
|
|
3426
3433
|
if (options.sessionStore) {
|
|
3427
3434
|
await options.sessionStore.save(sessionId, snap);
|
|
3428
3435
|
}
|
|
3436
|
+
let capnwebData = options.sessionStore ? { sessionId, version: 1 } : { sessionId, version: 1, snapshot: snap };
|
|
3437
|
+
let existing = webSocket.deserializeAttachment?.() ?? {};
|
|
3438
|
+
if (typeof existing !== "object" || existing === null) existing = {};
|
|
3439
|
+
webSocket.serializeAttachment?.({ ...existing, __capnweb: capnwebData });
|
|
3429
3440
|
} catch (err) {
|
|
3430
3441
|
transport.abort?.(err);
|
|
3431
3442
|
}
|
|
3432
3443
|
}
|
|
3433
3444
|
}
|
|
3445
|
+
async function __experimental_cleanupOrphanedSessions(webSockets, sessionStore) {
|
|
3446
|
+
if (!sessionStore.deleteOrphans) return 0;
|
|
3447
|
+
const liveIds = /* @__PURE__ */ new Set();
|
|
3448
|
+
for (const ws of webSockets) {
|
|
3449
|
+
const attachment = getAttachment(ws);
|
|
3450
|
+
if (attachment?.sessionId) {
|
|
3451
|
+
liveIds.add(attachment.sessionId);
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
return sessionStore.deleteOrphans(liveIds);
|
|
3455
|
+
}
|
|
3434
3456
|
async function __experimental_resumeHibernatableWebSocketRpcSession(webSocket, localMain, options) {
|
|
3435
3457
|
return __experimental_newHibernatableWebSocketRpcSession(webSocket, localMain, options);
|
|
3436
3458
|
}
|
|
3437
3459
|
function getAttachment(webSocket) {
|
|
3438
|
-
let
|
|
3460
|
+
let raw = webSocket.deserializeAttachment?.();
|
|
3461
|
+
let attachment = raw?.__capnweb ?? raw;
|
|
3439
3462
|
if (attachment?.version === 1 && typeof attachment.sessionId === "string") {
|
|
3440
3463
|
return attachment;
|
|
3441
3464
|
}
|
|
@@ -3514,7 +3537,11 @@ var WebSocketTransport = class {
|
|
|
3514
3537
|
if (reason instanceof Error) {
|
|
3515
3538
|
message = reason.message;
|
|
3516
3539
|
} else {
|
|
3517
|
-
|
|
3540
|
+
try {
|
|
3541
|
+
message = JSON.stringify(reason);
|
|
3542
|
+
} catch {
|
|
3543
|
+
message = `${reason}`;
|
|
3544
|
+
}
|
|
3518
3545
|
}
|
|
3519
3546
|
this.#webSocket.close(3e3, message);
|
|
3520
3547
|
if (!this.#error) {
|
|
@@ -3599,7 +3626,11 @@ var HibernatableWebSocketTransport = class {
|
|
|
3599
3626
|
if (reason instanceof Error) {
|
|
3600
3627
|
message = reason.message;
|
|
3601
3628
|
} else {
|
|
3602
|
-
|
|
3629
|
+
try {
|
|
3630
|
+
message = JSON.stringify(reason);
|
|
3631
|
+
} catch {
|
|
3632
|
+
message = `${reason}`;
|
|
3633
|
+
}
|
|
3603
3634
|
}
|
|
3604
3635
|
try {
|
|
3605
3636
|
this.webSocket.close(3e3, message);
|
|
@@ -4190,7 +4221,22 @@ function __experimental_newDurableObjectSessionStore(storage, prefix = "capnweb:
|
|
|
4190
4221
|
await storage.put(`${prefix}${sessionId}`, snapshot);
|
|
4191
4222
|
},
|
|
4192
4223
|
async delete(sessionId) {
|
|
4193
|
-
await storage.delete
|
|
4224
|
+
await storage.delete(`${prefix}${sessionId}`);
|
|
4225
|
+
},
|
|
4226
|
+
async deleteOrphans(liveSessionIds) {
|
|
4227
|
+
if (!storage.list) return 0;
|
|
4228
|
+
const stored = await storage.list({ prefix });
|
|
4229
|
+
const orphanKeys = [];
|
|
4230
|
+
for (const key of stored.keys()) {
|
|
4231
|
+
const sessionId = key.slice(prefix.length);
|
|
4232
|
+
if (!liveSessionIds.has(sessionId)) {
|
|
4233
|
+
orphanKeys.push(key);
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
if (orphanKeys.length > 0) {
|
|
4237
|
+
await storage.delete(orphanKeys);
|
|
4238
|
+
}
|
|
4239
|
+
return orphanKeys.length;
|
|
4194
4240
|
}
|
|
4195
4241
|
};
|
|
4196
4242
|
}
|
|
@@ -4203,6 +4249,7 @@ var newHttpBatchRpcSession2 = newHttpBatchRpcSession;
|
|
|
4203
4249
|
var newMessagePortRpcSession2 = newMessagePortRpcSession;
|
|
4204
4250
|
var __experimental_newHibernatableWebSocketRpcSession2 = __experimental_newHibernatableWebSocketRpcSession;
|
|
4205
4251
|
var __experimental_resumeHibernatableWebSocketRpcSession2 = __experimental_resumeHibernatableWebSocketRpcSession;
|
|
4252
|
+
var __experimental_cleanupOrphanedSessions2 = __experimental_cleanupOrphanedSessions;
|
|
4206
4253
|
var __experimental_debugRpcReference2 = __experimental_debugRpcReference;
|
|
4207
4254
|
async function newWorkersRpcResponse(request, localMain) {
|
|
4208
4255
|
if (request.method === "POST") {
|
|
@@ -4220,6 +4267,7 @@ exports.RpcPromise = RpcPromise2;
|
|
|
4220
4267
|
exports.RpcSession = RpcSession2;
|
|
4221
4268
|
exports.RpcStub = RpcStub2;
|
|
4222
4269
|
exports.RpcTarget = RpcTarget4;
|
|
4270
|
+
exports.__experimental_cleanupOrphanedSessions = __experimental_cleanupOrphanedSessions2;
|
|
4223
4271
|
exports.__experimental_debugRpcReference = __experimental_debugRpcReference2;
|
|
4224
4272
|
exports.__experimental_newDurableObjectSessionStore = __experimental_newDurableObjectSessionStore;
|
|
4225
4273
|
exports.__experimental_newHibernatableWebSocketRpcSession = __experimental_newHibernatableWebSocketRpcSession2;
|