@workerdeck/server 1.2.0 → 1.4.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 +1 -12
- package/build/index.mjs +10 -15
- package/build/index.mjs.map +1 -1
- package/package.json +5 -5
package/build/index.d.mts
CHANGED
|
@@ -39,6 +39,7 @@ type SessionRegistryOptions = {
|
|
|
39
39
|
declare class SessionRegistry {
|
|
40
40
|
#private;
|
|
41
41
|
constructor(options?: SessionRegistryOptions);
|
|
42
|
+
observe(listener: (runner: Runner) => void): () => void;
|
|
42
43
|
create(config: SessionRunnerConfig): Runner;
|
|
43
44
|
prepare(config: SessionRunnerConfig): Runner;
|
|
44
45
|
adopt(runner: Runner): Runner;
|
|
@@ -216,20 +217,12 @@ type QueueServerOptions = {
|
|
|
216
217
|
webhookRetryDelayMs?: number;
|
|
217
218
|
onEvent?: (event: JobEvent) => void;
|
|
218
219
|
};
|
|
219
|
-
/** A point-in-time answer to "is it safe to stop yet?", as reported while draining. */
|
|
220
220
|
type DrainReport = {
|
|
221
|
-
/** Sessions mid-turn. These resolve on their own, so the drain waits for them. */
|
|
222
221
|
working: string[];
|
|
223
|
-
/**
|
|
224
|
-
* Sessions blocked on a human — a pending approval. The drain names these but never waits for them: nothing about
|
|
225
|
-
* shutting down will answer the prompt, so waiting is a hang with better manners.
|
|
226
|
-
*/
|
|
227
222
|
awaitingHuman: string[];
|
|
228
|
-
/** True when the deadline passed with work still running. */
|
|
229
223
|
timedOut: boolean;
|
|
230
224
|
};
|
|
231
225
|
type DrainOptions = {
|
|
232
|
-
/** Overall budget. The drain gives up and reports rather than blocking shutdown forever. */
|
|
233
226
|
timeoutMs?: number;
|
|
234
227
|
pollMs?: number;
|
|
235
228
|
onProgress?: (report: DrainReport) => void;
|
|
@@ -243,10 +236,6 @@ type WorkerServer = {
|
|
|
243
236
|
listen: (port: number, host?: string) => Promise<{
|
|
244
237
|
port: number;
|
|
245
238
|
}>;
|
|
246
|
-
/**
|
|
247
|
-
* Let running turns finish before `close()`. A courtesy, never a correctness requirement: records are written
|
|
248
|
-
* continuously, so a hard stop already loses nothing. Refuses new sessions for as long as it runs.
|
|
249
|
-
*/
|
|
250
239
|
drain: (options?: DrainOptions) => Promise<DrainReport>;
|
|
251
240
|
close: () => Promise<void>;
|
|
252
241
|
};
|
package/build/index.mjs
CHANGED
|
@@ -732,12 +732,6 @@ async function handleHostFiles(ctx, req, res, pathname) {
|
|
|
732
732
|
}
|
|
733
733
|
//#endregion
|
|
734
734
|
//#region src/routes/create-vet.ts
|
|
735
|
-
/**
|
|
736
|
-
* The one create-validation ladder, run by both create doors — `POST /sessions` and the
|
|
737
|
-
* `session` block of `POST /jobs`. The scope design claims the two are indistinguishable, so
|
|
738
|
-
* the order and the refusals have to come from a single place rather than two copies that can
|
|
739
|
-
* drift. Mutates `req`: strips inert fields and pins the resolved profile name.
|
|
740
|
-
*/
|
|
741
735
|
function vetCreateRequest(ctx, req, auth) {
|
|
742
736
|
const { availability, factory } = ctx;
|
|
743
737
|
const refusedScope = factory.applyScope(req, auth);
|
|
@@ -2662,9 +2656,15 @@ function serveWindow(held, now) {
|
|
|
2662
2656
|
var SessionRegistry = class {
|
|
2663
2657
|
#sessions = /* @__PURE__ */ new Map();
|
|
2664
2658
|
#options;
|
|
2659
|
+
#observers = /* @__PURE__ */ new Set();
|
|
2665
2660
|
constructor(options = {}) {
|
|
2666
2661
|
this.#options = options;
|
|
2667
2662
|
}
|
|
2663
|
+
observe(listener) {
|
|
2664
|
+
this.#observers.add(listener);
|
|
2665
|
+
for (const runner of this.#sessions.values()) listener(runner);
|
|
2666
|
+
return () => void this.#observers.delete(listener);
|
|
2667
|
+
}
|
|
2668
2668
|
create(config) {
|
|
2669
2669
|
return this.adopt(new SessionRunner(config));
|
|
2670
2670
|
}
|
|
@@ -2679,7 +2679,10 @@ var SessionRegistry = class {
|
|
|
2679
2679
|
register(runner) {
|
|
2680
2680
|
const existing = this.#sessions.get(runner.id);
|
|
2681
2681
|
this.#sessions.set(runner.id, runner);
|
|
2682
|
-
if (existing !== runner)
|
|
2682
|
+
if (existing !== runner) {
|
|
2683
|
+
this.#options.onRegister?.(runner);
|
|
2684
|
+
for (const listener of this.#observers) listener(runner);
|
|
2685
|
+
}
|
|
2683
2686
|
return runner;
|
|
2684
2687
|
}
|
|
2685
2688
|
get(id) {
|
|
@@ -2898,15 +2901,7 @@ function createSessionFactory(deps) {
|
|
|
2898
2901
|
}
|
|
2899
2902
|
//#endregion
|
|
2900
2903
|
//#region src/server.ts
|
|
2901
|
-
/** How long a client gets to acknowledge the shutdown close frame before its socket is torn down. */
|
|
2902
2904
|
const SOCKET_CLOSE_GRACE_MS = 250;
|
|
2903
|
-
/**
|
|
2904
|
-
* Split live sessions into "will finish by itself" and "needs a person".
|
|
2905
|
-
*
|
|
2906
|
-
* `sessionState` is the vocabulary the dashboard, the session list and `workerdeck guard` already sort by, and it
|
|
2907
|
-
* draws exactly the line a drain needs: `working` covers starting/running and running subagents, while `attention`
|
|
2908
|
-
* covers a pending approval. Re-spelling that set here is how the two definitions would drift apart.
|
|
2909
|
-
*/
|
|
2910
2905
|
function surveyDrain(registry) {
|
|
2911
2906
|
const working = [];
|
|
2912
2907
|
const awaitingHuman = [];
|