@workerdeck/server 2.8.0 → 2.9.0
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/build/index.d.mts +21 -6
- package/build/index.mjs +128 -23
- package/build/index.mjs.map +1 -1
- package/package.json +5 -5
package/build/index.d.mts
CHANGED
|
@@ -29,21 +29,22 @@ declare class SessionNotifier {
|
|
|
29
29
|
#private;
|
|
30
30
|
constructor(options: SessionNotificationOptions);
|
|
31
31
|
get idle(): boolean;
|
|
32
|
-
watch(runner: Runner, afterSeq?: number): void;
|
|
32
|
+
watch(runner: Runner, afterSeq?: number): () => void;
|
|
33
33
|
}
|
|
34
34
|
//#endregion
|
|
35
35
|
//#region src/services/registry.d.ts
|
|
36
36
|
type SessionRegistryOptions = {
|
|
37
|
-
onRegister?: (runner: Runner) =>
|
|
37
|
+
onRegister?: (runner: Runner) => unknown;
|
|
38
38
|
};
|
|
39
39
|
declare class SessionRegistry {
|
|
40
40
|
#private;
|
|
41
41
|
constructor(options?: SessionRegistryOptions);
|
|
42
|
-
observe(listener: (runner: Runner) =>
|
|
42
|
+
observe(listener: (runner: Runner) => unknown): () => void;
|
|
43
43
|
create(config: SessionRunnerConfig): Runner;
|
|
44
44
|
prepare(config: SessionRunnerConfig): Runner;
|
|
45
45
|
adopt(runner: Runner): Runner;
|
|
46
46
|
register(runner: Runner): Runner;
|
|
47
|
+
retain(id: string, detach: () => void): void;
|
|
47
48
|
get(id: string): Runner | undefined;
|
|
48
49
|
list(): SessionInfo[];
|
|
49
50
|
remove(id: string): boolean;
|
|
@@ -72,6 +73,7 @@ type DormantSessionRecord = {
|
|
|
72
73
|
savedAt: number;
|
|
73
74
|
};
|
|
74
75
|
type StoredSessionRecord = ParkedSessionRecord | DormantSessionRecord;
|
|
76
|
+
declare function isDormant(record: StoredSessionRecord): record is DormantSessionRecord;
|
|
75
77
|
interface SessionStore {
|
|
76
78
|
save(record: StoredSessionRecord): Promise<void>;
|
|
77
79
|
get(id: string): Promise<StoredSessionRecord | null>;
|
|
@@ -119,6 +121,9 @@ declare class SessionParkManager {
|
|
|
119
121
|
touch(runner: Runner): void;
|
|
120
122
|
hydrate(): Promise<void>;
|
|
121
123
|
watch(runner: Runner, afterSeq?: number): () => void;
|
|
124
|
+
release(sessionId: string): SessionRunnerConfig | undefined;
|
|
125
|
+
adopt(runner: Runner, config?: SessionRunnerConfig): void;
|
|
126
|
+
flush(sessionId?: string): Promise<void>;
|
|
122
127
|
onDetach(sessionId: string): void;
|
|
123
128
|
sessionFor(executionId: string): string | undefined;
|
|
124
129
|
get(id: string): Promise<StoredSessionRecord | null>;
|
|
@@ -223,6 +228,10 @@ type QueueServerOptions = {
|
|
|
223
228
|
webhookRetryDelayMs?: number;
|
|
224
229
|
onEvent?: (event: JobEvent) => void;
|
|
225
230
|
};
|
|
231
|
+
type CarriedSession = {
|
|
232
|
+
runner: Runner;
|
|
233
|
+
config?: SessionRunnerConfig;
|
|
234
|
+
};
|
|
226
235
|
type DrainReport = {
|
|
227
236
|
working: string[];
|
|
228
237
|
awaitingHuman: string[];
|
|
@@ -243,6 +252,8 @@ type WorkerServer = {
|
|
|
243
252
|
port: number;
|
|
244
253
|
}>;
|
|
245
254
|
drain: (options?: DrainOptions) => Promise<DrainReport>;
|
|
255
|
+
releaseSession: (id: string) => CarriedSession | undefined;
|
|
256
|
+
adoptSession: (carried: CarriedSession) => boolean;
|
|
246
257
|
close: () => Promise<void>;
|
|
247
258
|
};
|
|
248
259
|
//#endregion
|
|
@@ -281,6 +292,10 @@ type ProviderRunnerOptions = {
|
|
|
281
292
|
};
|
|
282
293
|
declare function createProviderRunner(ctx: EngineRunnerContext, options: ProviderRunnerOptions): Promise<Runner>;
|
|
283
294
|
//#endregion
|
|
295
|
+
//#region src/lib/reload-plan.d.ts
|
|
296
|
+
type ReloadPlan = 'carry' | 'persist' | 'drop';
|
|
297
|
+
declare function reloadPlan(runner: Runner): ReloadPlan;
|
|
298
|
+
//#endregion
|
|
284
299
|
//#region src/services/attachments.d.ts
|
|
285
300
|
type AttachmentStoreOptions = {
|
|
286
301
|
maxFileBytes?: number;
|
|
@@ -332,7 +347,7 @@ type ProducedFile = {
|
|
|
332
347
|
};
|
|
333
348
|
declare class ProducedFileStore {
|
|
334
349
|
#private;
|
|
335
|
-
watch(runner: Runner): void;
|
|
350
|
+
watch(runner: Runner): () => void;
|
|
336
351
|
get(sessionId: string, fileId: string): ProducedFile | undefined;
|
|
337
352
|
list(sessionId: string): ProducedFile[];
|
|
338
353
|
drop(sessionId: string): void;
|
|
@@ -341,9 +356,9 @@ declare class ProducedFileStore {
|
|
|
341
356
|
//#region src/services/profile-usage.d.ts
|
|
342
357
|
declare class ProfileUsageTracker {
|
|
343
358
|
#private;
|
|
344
|
-
watch(runner: Runner): void;
|
|
359
|
+
watch(runner: Runner): () => void;
|
|
345
360
|
usage(profile: string, now?: number): ProfileUsage | undefined;
|
|
346
361
|
}
|
|
347
362
|
//#endregion
|
|
348
|
-
export { AttachmentStore, type AttachmentStoreOptions, type Authenticator, BridgeHub, type BridgeHubOptions, type EngineRunnerContext, type FileSessionStoreOptions, MemorySessionStore, type ParkedSessionRecord, type ProducedFile, ProducedFileStore, type ProfileStore, ProfileUsageTracker, type ProviderRunnerOptions, type QueueServerOptions, type SdkSessionLister, type SessionNotificationOptions, SessionNotifier, SessionParkManager, type SessionParkOptions, SessionRegistry, type SessionRegistryOptions, type SessionStore, type WorkerServer, type WorkerServerOptions, createFileProfileStore, createFileSessionStore, createMemoryProfileStore, createProviderRunner, createWorkerServer, sandboxedProviderProfile, toDurableRecord };
|
|
363
|
+
export { AttachmentStore, type AttachmentStoreOptions, type Authenticator, BridgeHub, type BridgeHubOptions, type CarriedSession, type EngineRunnerContext, type FileSessionStoreOptions, MemorySessionStore, type ParkedSessionRecord, type ProducedFile, ProducedFileStore, type ProfileStore, ProfileUsageTracker, type ProviderRunnerOptions, type QueueServerOptions, type ReloadPlan, type SdkSessionLister, type SessionNotificationOptions, SessionNotifier, SessionParkManager, type SessionParkOptions, SessionRegistry, type SessionRegistryOptions, type SessionStore, type StoredSessionRecord, type WorkerServer, type WorkerServerOptions, createFileProfileStore, createFileSessionStore, createMemoryProfileStore, createProviderRunner, createWorkerServer, isDormant, reloadPlan, sandboxedProviderProfile, toDurableRecord };
|
|
349
364
|
//# sourceMappingURL=index.d.mts.map
|
package/build/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createServer } from "node:http";
|
|
|
2
2
|
import { WebSocketServer } from "ws";
|
|
3
3
|
import { BrowserBridgeExecutor, SessionRunner, attachmentKind, checkClaudeAuth, createEngineSession, getEngineAdapter, normalizeMediaType } from "@workerdeck/core";
|
|
4
4
|
import { JobQueue } from "@workerdeck/queue";
|
|
5
|
-
import { ENGINE_CAPABILITIES, PROTOCOL_VERSION, SHELL_COMMAND_MAX, imagePartRef, sessionState, supportsPermissionMode } from "@workerdeck/protocol";
|
|
5
|
+
import { ENGINE_CAPABILITIES, PROTOCOL_VERSION, SHELL_COMMAND_MAX, imagePartRef, isJobRun, sessionState, supportsPermissionMode } from "@workerdeck/protocol";
|
|
6
6
|
import { createHash, randomUUID } from "node:crypto";
|
|
7
7
|
import { closeSync, constants, createReadStream, existsSync, fstatSync, ftruncateSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { constants as constants$1, homedir } from "node:os";
|
|
@@ -211,6 +211,15 @@ function parseSessionRoute(basePath, url) {
|
|
|
211
211
|
return null;
|
|
212
212
|
}
|
|
213
213
|
//#endregion
|
|
214
|
+
//#region src/lib/reload-plan.ts
|
|
215
|
+
function reloadPlan(runner) {
|
|
216
|
+
const info = runner.info();
|
|
217
|
+
if (info.status === "closed" || info.status === "failed") return "drop";
|
|
218
|
+
if (isJobRun(info)) return "drop";
|
|
219
|
+
if (runner.snapshot !== void 0) return "persist";
|
|
220
|
+
return "carry";
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
214
223
|
//#region src/routes/executions.ts
|
|
215
224
|
async function handleExecutionResult(ctx, req, res, pathname, auth) {
|
|
216
225
|
const { auth: authSvc, basePath, parking, registry } = ctx;
|
|
@@ -1808,6 +1817,7 @@ function attachClient(ctx, ws, runner, req, access) {
|
|
|
1808
1817
|
imageRefs
|
|
1809
1818
|
});
|
|
1810
1819
|
const detachBridge = bridge.attach(runner.id, send);
|
|
1820
|
+
runner.refreshUsage?.().catch(() => {});
|
|
1811
1821
|
ws.on("message", (data) => {
|
|
1812
1822
|
let frame;
|
|
1813
1823
|
try {
|
|
@@ -2209,8 +2219,8 @@ var SessionNotifier = class {
|
|
|
2209
2219
|
return !this.#options.webhook && !this.#options.onNotification;
|
|
2210
2220
|
}
|
|
2211
2221
|
watch(runner, afterSeq = runner.info().lastSeq) {
|
|
2212
|
-
if (this.idle) return;
|
|
2213
|
-
runner.subscribe((event) => {
|
|
2222
|
+
if (this.idle) return () => {};
|
|
2223
|
+
return runner.subscribe((event) => {
|
|
2214
2224
|
switch (event.type) {
|
|
2215
2225
|
case "permission_requested":
|
|
2216
2226
|
this.#emit(runner, event.seq, event.ts, {
|
|
@@ -2301,6 +2311,7 @@ var SessionParkManager = class {
|
|
|
2301
2311
|
#configs = /* @__PURE__ */ new Map();
|
|
2302
2312
|
#remembered = /* @__PURE__ */ new Set();
|
|
2303
2313
|
#storeOps = /* @__PURE__ */ new Map();
|
|
2314
|
+
#watches = /* @__PURE__ */ new Map();
|
|
2304
2315
|
#closed = false;
|
|
2305
2316
|
constructor(options) {
|
|
2306
2317
|
this.#options = options;
|
|
@@ -2320,7 +2331,8 @@ var SessionParkManager = class {
|
|
|
2320
2331
|
}
|
|
2321
2332
|
}
|
|
2322
2333
|
watch(runner, afterSeq = 0) {
|
|
2323
|
-
|
|
2334
|
+
this.#watches.get(runner.id)?.();
|
|
2335
|
+
const unsubscribe = runner.subscribe((event) => {
|
|
2324
2336
|
switch (event.type) {
|
|
2325
2337
|
case "execution_dispatched":
|
|
2326
2338
|
if (!event.deferred) return;
|
|
@@ -2360,6 +2372,35 @@ var SessionParkManager = class {
|
|
|
2360
2372
|
default: return;
|
|
2361
2373
|
}
|
|
2362
2374
|
}, afterSeq);
|
|
2375
|
+
const detach = () => {
|
|
2376
|
+
if (this.#watches.get(runner.id) === detach) this.#watches.delete(runner.id);
|
|
2377
|
+
unsubscribe();
|
|
2378
|
+
};
|
|
2379
|
+
this.#watches.set(runner.id, detach);
|
|
2380
|
+
return detach;
|
|
2381
|
+
}
|
|
2382
|
+
release(sessionId) {
|
|
2383
|
+
this.#watches.get(sessionId)?.();
|
|
2384
|
+
this.#watches.delete(sessionId);
|
|
2385
|
+
clearTimeout(this.#detachTimers.get(sessionId));
|
|
2386
|
+
this.#detachTimers.delete(sessionId);
|
|
2387
|
+
const config = this.#configs.get(sessionId);
|
|
2388
|
+
this.#configs.delete(sessionId);
|
|
2389
|
+
this.#remembered.delete(sessionId);
|
|
2390
|
+
return config;
|
|
2391
|
+
}
|
|
2392
|
+
adopt(runner, config) {
|
|
2393
|
+
this.#options.registry.register(runner);
|
|
2394
|
+
if (config) this.remember(runner.id, config);
|
|
2395
|
+
this.watch(runner, runner.info().lastSeq);
|
|
2396
|
+
this.touch(runner);
|
|
2397
|
+
}
|
|
2398
|
+
async flush(sessionId) {
|
|
2399
|
+
if (sessionId === void 0) {
|
|
2400
|
+
await Promise.all(this.#storeOps.values());
|
|
2401
|
+
return;
|
|
2402
|
+
}
|
|
2403
|
+
await this.#storeOps.get(sessionId);
|
|
2363
2404
|
}
|
|
2364
2405
|
onDetach(sessionId) {
|
|
2365
2406
|
if (this.#closed) return;
|
|
@@ -2411,6 +2452,7 @@ var SessionParkManager = class {
|
|
|
2411
2452
|
};
|
|
2412
2453
|
}
|
|
2413
2454
|
async discard(sessionId) {
|
|
2455
|
+
this.#watches.delete(sessionId);
|
|
2414
2456
|
clearTimeout(this.#detachTimers.get(sessionId));
|
|
2415
2457
|
this.#detachTimers.delete(sessionId);
|
|
2416
2458
|
this.#configs.delete(sessionId);
|
|
@@ -2639,7 +2681,7 @@ var SessionParkManager = class {
|
|
|
2639
2681
|
var ProducedFileStore = class {
|
|
2640
2682
|
#bySession = /* @__PURE__ */ new Map();
|
|
2641
2683
|
watch(runner) {
|
|
2642
|
-
runner.subscribe((event) => {
|
|
2684
|
+
return runner.subscribe((event) => {
|
|
2643
2685
|
if (event.type !== "file_produced") return;
|
|
2644
2686
|
const held = this.#bySession.get(runner.id) ?? /* @__PURE__ */ new Map();
|
|
2645
2687
|
held.set(event.fileId, {
|
|
@@ -2790,8 +2832,8 @@ var ProfileUsageTracker = class {
|
|
|
2790
2832
|
#profiles = /* @__PURE__ */ new Map();
|
|
2791
2833
|
watch(runner) {
|
|
2792
2834
|
const profile = runner.info().profile;
|
|
2793
|
-
if (!profile) return;
|
|
2794
|
-
runner.subscribe((event) => {
|
|
2835
|
+
if (!profile) return () => {};
|
|
2836
|
+
return runner.subscribe((event) => {
|
|
2795
2837
|
if (event.type !== "rate_limit") return;
|
|
2796
2838
|
const type = event.info.rateLimitType;
|
|
2797
2839
|
if (!type) return;
|
|
@@ -2835,12 +2877,13 @@ var SessionRegistry = class {
|
|
|
2835
2877
|
#sessions = /* @__PURE__ */ new Map();
|
|
2836
2878
|
#options;
|
|
2837
2879
|
#observers = /* @__PURE__ */ new Set();
|
|
2880
|
+
#detachers = /* @__PURE__ */ new Map();
|
|
2838
2881
|
constructor(options = {}) {
|
|
2839
2882
|
this.#options = options;
|
|
2840
2883
|
}
|
|
2841
2884
|
observe(listener) {
|
|
2842
2885
|
this.#observers.add(listener);
|
|
2843
|
-
for (const runner of this.#sessions.values()) listener(runner);
|
|
2886
|
+
for (const runner of this.#sessions.values()) this.#retain(runner.id, listener(runner));
|
|
2844
2887
|
return () => void this.#observers.delete(listener);
|
|
2845
2888
|
}
|
|
2846
2889
|
create(config) {
|
|
@@ -2858,11 +2901,14 @@ var SessionRegistry = class {
|
|
|
2858
2901
|
const existing = this.#sessions.get(runner.id);
|
|
2859
2902
|
this.#sessions.set(runner.id, runner);
|
|
2860
2903
|
if (existing !== runner) {
|
|
2861
|
-
this.#options.onRegister?.(runner);
|
|
2862
|
-
for (const listener of this.#observers) listener(runner);
|
|
2904
|
+
this.#retain(runner.id, this.#options.onRegister?.(runner));
|
|
2905
|
+
for (const listener of this.#observers) this.#retain(runner.id, listener(runner));
|
|
2863
2906
|
}
|
|
2864
2907
|
return runner;
|
|
2865
2908
|
}
|
|
2909
|
+
retain(id, detach) {
|
|
2910
|
+
this.#retain(id, detach);
|
|
2911
|
+
}
|
|
2866
2912
|
get(id) {
|
|
2867
2913
|
return this.#sessions.get(id);
|
|
2868
2914
|
}
|
|
@@ -2873,14 +2919,30 @@ var SessionRegistry = class {
|
|
|
2873
2919
|
const runner = this.#sessions.get(id);
|
|
2874
2920
|
if (!runner) return false;
|
|
2875
2921
|
runner.close("server");
|
|
2922
|
+
this.#detach(id);
|
|
2876
2923
|
return this.#sessions.delete(id);
|
|
2877
2924
|
}
|
|
2878
2925
|
evict(id) {
|
|
2926
|
+
this.#detach(id);
|
|
2879
2927
|
return this.#sessions.delete(id);
|
|
2880
2928
|
}
|
|
2881
2929
|
closeAll() {
|
|
2882
2930
|
for (const runner of this.#sessions.values()) runner.close("server");
|
|
2883
2931
|
}
|
|
2932
|
+
#retain(id, detach) {
|
|
2933
|
+
if (typeof detach !== "function") return;
|
|
2934
|
+
const run = detach;
|
|
2935
|
+
const existing = this.#detachers.get(id);
|
|
2936
|
+
if (existing) {
|
|
2937
|
+
existing.push(run);
|
|
2938
|
+
return;
|
|
2939
|
+
}
|
|
2940
|
+
this.#detachers.set(id, [run]);
|
|
2941
|
+
}
|
|
2942
|
+
#detach(id) {
|
|
2943
|
+
for (const detach of this.#detachers.get(id) ?? []) detach();
|
|
2944
|
+
this.#detachers.delete(id);
|
|
2945
|
+
}
|
|
2884
2946
|
};
|
|
2885
2947
|
//#endregion
|
|
2886
2948
|
//#region src/services/session-factory.ts
|
|
@@ -3052,7 +3114,7 @@ function createSessionFactory(deps) {
|
|
|
3052
3114
|
};
|
|
3053
3115
|
const watchAuthSource = (runner) => {
|
|
3054
3116
|
let seen = false;
|
|
3055
|
-
runner.subscribe((event) => {
|
|
3117
|
+
return runner.subscribe((event) => {
|
|
3056
3118
|
if (seen || event.type !== "system_init") return;
|
|
3057
3119
|
seen = true;
|
|
3058
3120
|
if (event.apiKeySource !== "oauth") return;
|
|
@@ -3084,6 +3146,8 @@ function createSessionFactory(deps) {
|
|
|
3084
3146
|
//#endregion
|
|
3085
3147
|
//#region src/server.ts
|
|
3086
3148
|
const SOCKET_CLOSE_GRACE_MS = 250;
|
|
3149
|
+
const CLOSE_DEADLINE_MS = 1e3;
|
|
3150
|
+
const USAGE_STALE_MS = 3e5;
|
|
3087
3151
|
function surveyDrain(registry) {
|
|
3088
3152
|
const working = [];
|
|
3089
3153
|
const awaitingHuman = [];
|
|
@@ -3110,6 +3174,19 @@ function createWorkerServer(options = {}) {
|
|
|
3110
3174
|
const adapterFor = (engine) => options.engines?.[engine ?? "claude"] ?? getEngineAdapter(engine);
|
|
3111
3175
|
const profileDefaultModels = /* @__PURE__ */ new Map();
|
|
3112
3176
|
const profileUsage = new ProfileUsageTracker();
|
|
3177
|
+
const refreshStaleUsage = (name) => {
|
|
3178
|
+
const held = profileUsage.usage(name);
|
|
3179
|
+
const newest = Math.max(0, ...Object.values(held ?? {}).map((window) => window.updatedAt ?? 0));
|
|
3180
|
+
if (Date.now() - newest < USAGE_STALE_MS) return;
|
|
3181
|
+
for (const info of refs.registry?.list() ?? []) {
|
|
3182
|
+
if (info.profile !== name) continue;
|
|
3183
|
+
const runner = refs.registry?.get(info.id);
|
|
3184
|
+
if (runner?.refreshUsage) {
|
|
3185
|
+
runner.refreshUsage().catch(() => {});
|
|
3186
|
+
return;
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
};
|
|
3113
3190
|
const detected = options.profiles ? [] : detectDefaultProfiles();
|
|
3114
3191
|
const profiles = new ProfileService({
|
|
3115
3192
|
declared: options.profiles ?? (options.profileStore ? [] : detected),
|
|
@@ -3122,7 +3199,10 @@ function createWorkerServer(options = {}) {
|
|
|
3122
3199
|
decorate: {
|
|
3123
3200
|
defaultModel: (name) => profileDefaultModels.get(name),
|
|
3124
3201
|
availability: (name) => availability.get(name),
|
|
3125
|
-
usage: (name) =>
|
|
3202
|
+
usage: (name) => {
|
|
3203
|
+
refreshStaleUsage(name);
|
|
3204
|
+
return profileUsage.usage(name);
|
|
3205
|
+
}
|
|
3126
3206
|
}
|
|
3127
3207
|
});
|
|
3128
3208
|
for (const p of options.profiles ?? []) {
|
|
@@ -3155,16 +3235,20 @@ function createWorkerServer(options = {}) {
|
|
|
3155
3235
|
const producedFiles = new ProducedFileStore();
|
|
3156
3236
|
const shell = options.shell?.enabled === true ? createShellService(options.shell) : null;
|
|
3157
3237
|
const registry = new SessionRegistry({ onRegister: (runner) => {
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3238
|
+
const detachers = [
|
|
3239
|
+
notifier.watch(runner),
|
|
3240
|
+
producedFiles.watch(runner),
|
|
3241
|
+
profileUsage.watch(runner),
|
|
3242
|
+
shell?.watch(runner)
|
|
3243
|
+
];
|
|
3162
3244
|
const profile = runner.info().profile;
|
|
3163
|
-
if (
|
|
3164
|
-
runner.subscribe((event) => {
|
|
3245
|
+
if (profile) detachers.push(runner.subscribe((event) => {
|
|
3165
3246
|
if (event.type !== "capabilities" || !event.defaultModel) return;
|
|
3166
3247
|
profileDefaultModels.set(profile, event.defaultModel);
|
|
3167
|
-
});
|
|
3248
|
+
}));
|
|
3249
|
+
return () => {
|
|
3250
|
+
for (const detach of detachers) detach?.();
|
|
3251
|
+
};
|
|
3168
3252
|
} });
|
|
3169
3253
|
const attachmentStore = new AttachmentStore(options.attachments);
|
|
3170
3254
|
const bridge = new BridgeHub({
|
|
@@ -3445,6 +3529,24 @@ function createWorkerServer(options = {}) {
|
|
|
3445
3529
|
});
|
|
3446
3530
|
});
|
|
3447
3531
|
},
|
|
3532
|
+
releaseSession: (id) => {
|
|
3533
|
+
const runner = registry.get(id);
|
|
3534
|
+
if (!runner) return;
|
|
3535
|
+
const plan = reloadPlan(runner);
|
|
3536
|
+
if (plan !== "carry") throw new Error(`session ${id} cannot be carried by identity (${plan})`);
|
|
3537
|
+
const config = parking.release(id);
|
|
3538
|
+
registry.evict(id);
|
|
3539
|
+
return {
|
|
3540
|
+
runner,
|
|
3541
|
+
config
|
|
3542
|
+
};
|
|
3543
|
+
},
|
|
3544
|
+
adoptSession: ({ runner, config }) => {
|
|
3545
|
+
if (reloadPlan(runner) !== "carry") return false;
|
|
3546
|
+
parking.adopt(runner, config);
|
|
3547
|
+
registry.retain(runner.id, factory.watchAuthSource(runner));
|
|
3548
|
+
return true;
|
|
3549
|
+
},
|
|
3448
3550
|
drain: async (drainOptions = {}) => {
|
|
3449
3551
|
const { timeoutMs = 3e4, pollMs = 250, onProgress } = drainOptions;
|
|
3450
3552
|
draining = true;
|
|
@@ -3477,12 +3579,15 @@ function createWorkerServer(options = {}) {
|
|
|
3477
3579
|
for (const ws of wss.clients) ws.terminate();
|
|
3478
3580
|
}, SOCKET_CLOSE_GRACE_MS);
|
|
3479
3581
|
force.unref();
|
|
3480
|
-
|
|
3481
|
-
|
|
3582
|
+
const deadline = setTimeout(() => resolve(), CLOSE_DEADLINE_MS);
|
|
3583
|
+
deadline.unref();
|
|
3584
|
+
const drained = Promise.all([new Promise((done) => wss.close(() => done())), new Promise((done) => server.close(() => done()))]);
|
|
3585
|
+
server.closeAllConnections();
|
|
3586
|
+
drained.then(() => {
|
|
3482
3587
|
clearTimeout(force);
|
|
3588
|
+
clearTimeout(deadline);
|
|
3483
3589
|
resolve();
|
|
3484
3590
|
});
|
|
3485
|
-
server.closeAllConnections();
|
|
3486
3591
|
});
|
|
3487
3592
|
return closing;
|
|
3488
3593
|
}
|
|
@@ -3579,6 +3684,6 @@ function createFileProfileStore(path = join(process.cwd(), ".workerdeck", "profi
|
|
|
3579
3684
|
};
|
|
3580
3685
|
}
|
|
3581
3686
|
//#endregion
|
|
3582
|
-
export { AttachmentStore, BridgeHub, MemorySessionStore, ProducedFileStore, ProfileUsageTracker, SessionNotifier, SessionParkManager, SessionRegistry, createFileProfileStore, createFileSessionStore, createMemoryProfileStore, createProviderRunner, createWorkerServer, sandboxedProviderProfile, toDurableRecord };
|
|
3687
|
+
export { AttachmentStore, BridgeHub, MemorySessionStore, ProducedFileStore, ProfileUsageTracker, SessionNotifier, SessionParkManager, SessionRegistry, createFileProfileStore, createFileSessionStore, createMemoryProfileStore, createProviderRunner, createWorkerServer, isDormant, reloadPlan, sandboxedProviderProfile, toDurableRecord };
|
|
3583
3688
|
|
|
3584
3689
|
//# sourceMappingURL=index.mjs.map
|