@nimbus-sh/platform 0.8.0 → 0.8.1

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/limits.d.ts CHANGED
@@ -74,14 +74,14 @@ export declare const BLOCK_CONCURRENCY_CANCEL_MS = 30000;
74
74
  */
75
75
  export declare const RESIDENT_KEEPALIVE_MS = 5000;
76
76
  /**
77
- * How long the keep-alive holds a session after its last client is gone.
77
+ * How long the keep-alive holds a resident after its last client traffic.
78
78
  *
79
79
  * The keep-alive exists so a quiet process survives while its user is
80
80
  * present. Unbounded, it made every abandoned session with a dev server
81
81
  * run forever: the probe suite's cancelled runs left staging with resident
82
82
  * watchers polling `stat` at ~7.5/s in the isolate every session shares,
83
83
  * and launches that pass on a fresh Worker reset there (2026-09-22). Past
84
- * this grace with no attached socket and no request, the session idles
84
+ * this grace without runtime client traffic, even with idle sockets, the session idles
85
85
  * out as it did before the keep-alive, and the launch journal re-drives
86
86
  * the process when a client returns. Long enough for a tab reload.
87
87
  */
package/dist/limits.js CHANGED
@@ -87,14 +87,14 @@ export const BLOCK_CONCURRENCY_CANCEL_MS = 30_000;
87
87
  */
88
88
  export const RESIDENT_KEEPALIVE_MS = 5_000;
89
89
  /**
90
- * How long the keep-alive holds a session after its last client is gone.
90
+ * How long the keep-alive holds a resident after its last client traffic.
91
91
  *
92
92
  * The keep-alive exists so a quiet process survives while its user is
93
93
  * present. Unbounded, it made every abandoned session with a dev server
94
94
  * run forever: the probe suite's cancelled runs left staging with resident
95
95
  * watchers polling `stat` at ~7.5/s in the isolate every session shares,
96
96
  * and launches that pass on a fresh Worker reset there (2026-09-22). Past
97
- * this grace with no attached socket and no request, the session idles
97
+ * this grace without runtime client traffic, even with idle sockets, the session idles
98
98
  * out as it did before the keep-alive, and the launch journal re-drives
99
99
  * the process when a client returns. Long enough for a tab reload.
100
100
  */
@@ -0,0 +1,31 @@
1
+ /** A deployed source asset: its digest, not its pathname, is its identity. */
2
+ export interface ModuleSourceAsset {
3
+ path: string;
4
+ sha256: string;
5
+ }
6
+ export interface ModuleSourceEnv {
7
+ ASSETS?: {
8
+ fetch(request: Request): Promise<Response>;
9
+ };
10
+ }
11
+ /** Source already verified against its deployment pin. Shared across generated programs. */
12
+ export declare class ImmutableModuleSource {
13
+ readonly asset: ModuleSourceAsset;
14
+ readonly byteLength: number;
15
+ readonly text: string;
16
+ constructor(bytes: ArrayBuffer | Uint8Array, asset: ModuleSourceAsset);
17
+ }
18
+ export type ModuleSourcePart = string | ImmutableModuleSource;
19
+ export type ModuleSourceRecipe = (string | ModuleSourceAsset)[];
20
+ /** A generated module retains its immutable pieces until the Loader needs its complete text. */
21
+ export declare class ModuleSource {
22
+ readonly parts: readonly ModuleSourcePart[];
23
+ private joined;
24
+ readonly byteLength: number;
25
+ constructor(parts: readonly ModuleSourcePart[]);
26
+ get text(): string;
27
+ recipe(): ModuleSourceRecipe;
28
+ }
29
+ /** Template interpolation without flattening immutable runtime libraries into process-owned text. */
30
+ export declare function moduleSource(strings: TemplateStringsArray, ...values: (string | number | boolean | null | undefined | ImmutableModuleSource | ModuleSource)[]): ModuleSource;
31
+ //# sourceMappingURL=module-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-source.d.ts","sourceRoot":"","sources":["../src/module-source.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;CACzD;AAED,4FAA4F;AAC5F,qBAAa,qBAAqB;IAGa,QAAQ,CAAC,KAAK,EAAE,iBAAiB;IAF9E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,KAAK,EAAE,WAAW,GAAG,UAAU,EAAW,KAAK,EAAE,iBAAiB;CAI/E;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,qBAAqB,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC,EAAE,CAAC;AAEhE,gGAAgG;AAChG,qBAAa,YAAY;IAGX,QAAQ,CAAC,KAAK,EAAE,SAAS,gBAAgB,EAAE;IAFvD,OAAO,CAAC,MAAM,CAAqB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBACP,KAAK,EAAE,SAAS,gBAAgB,EAAE;IAGvD,IAAI,IAAI,IAAI,MAAM,CAEjB;IACD,MAAM,IAAI,kBAAkB;CAG7B;AAED,qGAAqG;AACrG,wBAAgB,YAAY,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,qBAAqB,GAAG,YAAY,CAAC,EAAE,GAAG,YAAY,CAiB5K"}
@@ -0,0 +1,52 @@
1
+ /** Source already verified against its deployment pin. Shared across generated programs. */
2
+ export class ImmutableModuleSource {
3
+ asset;
4
+ byteLength;
5
+ text;
6
+ constructor(bytes, asset) {
7
+ this.asset = asset;
8
+ this.text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
9
+ this.byteLength = bytes.byteLength;
10
+ }
11
+ }
12
+ /** A generated module retains its immutable pieces until the Loader needs its complete text. */
13
+ export class ModuleSource {
14
+ parts;
15
+ joined;
16
+ byteLength;
17
+ constructor(parts) {
18
+ this.parts = parts;
19
+ this.byteLength = parts.reduce((bytes, part) => bytes + (typeof part === 'string' ? new TextEncoder().encode(part).byteLength : part.byteLength), 0);
20
+ }
21
+ get text() {
22
+ return this.joined ??= this.parts.map((part) => typeof part === 'string' ? part : part.text).join('');
23
+ }
24
+ recipe() {
25
+ return this.parts.map((part) => typeof part === 'string' ? part : part.asset);
26
+ }
27
+ }
28
+ /** Template interpolation without flattening immutable runtime libraries into process-owned text. */
29
+ export function moduleSource(strings, ...values) {
30
+ const parts = [];
31
+ const append = (part) => {
32
+ if (part === '')
33
+ return;
34
+ const last = parts.length - 1;
35
+ const previous = parts[last];
36
+ if (typeof part === 'string' && typeof previous === 'string')
37
+ parts[last] = previous + part;
38
+ else
39
+ parts.push(part);
40
+ };
41
+ for (const [i, literal] of strings.entries()) {
42
+ append(literal);
43
+ if (i === values.length)
44
+ continue;
45
+ const value = values[i];
46
+ if (value instanceof ModuleSource)
47
+ value.parts.forEach(append);
48
+ else
49
+ append(value instanceof ImmutableModuleSource ? value : String(value));
50
+ }
51
+ return new ModuleSource(parts);
52
+ }
package/dist/retry.d.ts CHANGED
@@ -12,8 +12,8 @@
12
12
  * Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
13
13
  * that failed together do not try again together.
14
14
  *
15
- * Self-contained, both functions: a facet that cannot import carries them
16
- * by source (fn.toString(); the npm install facet's preamble does).
15
+ * A facet carries these same functions and their dependencies in its
16
+ * build-time compiled task expression (the npm install facet does).
17
17
  */
18
18
  /**
19
19
  * The wait before re-try `attempt` (0-based, the try that just failed):
package/dist/retry.js CHANGED
@@ -12,8 +12,8 @@
12
12
  * Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
13
13
  * that failed together do not try again together.
14
14
  *
15
- * Self-contained, both functions: a facet that cannot import carries them
16
- * by source (fn.toString(); the npm install facet's preamble does).
15
+ * A facet carries these same functions and their dependencies in its
16
+ * build-time compiled task expression (the npm install facet does).
17
17
  */
18
18
  /**
19
19
  * The wait before re-try `attempt` (0-based, the try that just failed):
@@ -319,7 +319,9 @@ export declare class WaveWriter<Meta = undefined> {
319
319
  /**
320
320
  * The epoch this writer's waves are fenced under: opened before its first
321
321
  * wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
322
- * never sent under an epoch about to close.
322
+ * never sent under an epoch about to close. Opened under the lost-call
323
+ * policy (openWaveEpoch); an open that failed even so is not the writer's
324
+ * epoch, and the next wave opens again.
323
325
  */
324
326
  private currentEpoch;
325
327
  /** The directories the buffered records publish, shallowest first. */
@@ -366,6 +368,24 @@ export interface WaveTimers {
366
368
  * W7 producer sends: the wave writer, and a process's filesystem client.
367
369
  */
368
370
  export declare function sendWaveAttempts(options: WaveAttempts): Promise<unknown>;
371
+ /**
372
+ * Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
373
+ * process's openWriter), again while the call is lost or shed, under a
374
+ * wave's lost-call policy and budget (isLostFencedCall,
375
+ * LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
376
+ * never ran issued nothing, and one whose answer was lost issued an epoch
377
+ * nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
378
+ * it answered is its verdict. A shed open would otherwise fail every write
379
+ * the epoch was for, unsent: measured, create-next-app lost 31 of 42
380
+ * packages to one.
381
+ */
382
+ export declare function openWaveEpoch(open: () => Promise<string | null>, options?: {
383
+ retry?: {
384
+ backoffMs: readonly number[];
385
+ };
386
+ resent?: (lost: Record<string, string | number>) => void;
387
+ timers?: WaveTimers;
388
+ }): Promise<string | null>;
369
389
  /** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
370
390
  export declare function waveAttemptsOf(bytes: Uint8Array): () => ReadableStream<Uint8Array>;
371
391
  export declare function createWaveWriter<Meta = undefined>(options: WaveWriterOptions<Meta>): WaveWriter<Meta>;
@@ -1 +1 @@
1
- {"version":3,"file":"wave-writer.d.ts","sourceRoot":"","sources":["../src/wave-writer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wave-writer.d.ts","sourceRoot":"","sources":["../src/wave-writer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AA0BH,mGAAmG;AACnG,eAAO,MAAM,UAAU,QAA6B,CAAC;AACrD,eAAO,MAAM,eAAe,QAAqC,CAAC;AAClE,gDAAgD;AAChD,eAAO,MAAM,UAAU,QAAkB,CAAC;AAK1C;;;;;;GAMG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1G;;;;OAIG;IACH,cAAc,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3C;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED,kFAAkF;AAClF,MAAM,WAAW,OAAO,CAAC,IAAI;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;KAAE,EAAE,CAAC;IAClD,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB,CAAC,IAAI,GAAG,SAAS;IACjD,UAAU,EAAE,cAAc,CAAC;IAC3B;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACrD,gEAAgE;IAChE,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;IACrC,gDAAgD;IAChD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,6FAA6F;IAC7F,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yEAAyE;IACzE,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IACpF,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;CACpB;AAiBD,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBACV,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAKzC;AA6DD,qBAAa,UAAU,CAAC,IAAI,GAAG,SAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2C;IACnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,4DAA4D;IAC5D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,4FAA4F;IAC5F,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,GAAG,CAAoB;IAC/B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,OAAO,CAA4B;IAC3C,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAC7D,+FAA+F;IAC/F,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;IAClD,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA2B;IACtD,yFAAyF;IACzF,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAYvB;IACF,oFAAoF;IACpF,OAAO,CAAC,KAAK,CAAqE;IAClF,2FAA2F;IAC3F,OAAO,CAAC,SAAS,CAAuC;gBAE5C,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC;IAM5C,sEAAsE;IACtE,OAAO,CAAC,SAAS;IAMjB;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/E,mCAAmC;IACnC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAYjE;;;;OAIG;IACH,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,EACjC,IAAI,CAAC,EAAE,IAAI,GACV,OAAO,CAAC,IAAI,CAAC;IAYhB,gFAAgF;IAChF,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAetC;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IActD;;;;;OAKG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,IAAI;IAIzD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM5B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAK9C,mFAAmF;IACnF,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS;IAQ5G,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1C,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIvC,aAAa,IAAI;QAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAA;KAAE;IAItG,2EAA2E;IAC3E,IAAI,sBAAsB,IAAI,OAAO,CAEpC;IAID,4FAA4F;IAC5F,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,0DAA0D;IACpD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B,aAAa,IAAI,IAAI;IAIrB,6EAA6E;IAC7E,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS;IAI/C;;;;OAIG;IACH,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO;IAO/B,OAAO,CAAC,kBAAkB;IAO1B,IAAI,MAAM,IAAI,WAAW,GAAG,IAAI,CAE/B;IAED,KAAK,IAAI,SAAS;IAMlB,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,KAAK;IAIb,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,OAAO;IAQf,6FAA6F;IAC7F,OAAO,CAAC,SAAS;IAmBjB;;;;;OAKG;YACW,YAAY;IAI1B,uFAAuF;YACzE,KAAK;IAwBnB,OAAO,CAAC,MAAM;IAad,OAAO,CAAC,IAAI;YAQE,SAAS;IAQvB;;;OAGG;IACH,OAAO,CAAC,GAAG;YAMG,MAAM;IAiIpB;;;;;;;;;;;;;;;OAeG;YACW,IAAI;IAWlB,kEAAkE;IAClE,OAAO,CAAC,YAAY;IAepB;;;;;;OAMG;YACW,YAAY;IAqB1B,sEAAsE;IACtE,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,SAAS;CASlB;AAED,4GAA4G;AAC5G,8CAA8C;AAC9C,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,cAAc,CAAC;IAC3B,sFAAsF;IACtF,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrC,2DAA2D;IAC3D,IAAI,EAAE,MAAM,cAAc,CAAC,UAAU,CAAC,CAAC;IACvC,uEAAuE;IACvE,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,yFAAyF;IACzF,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IACpF,+DAA+D;IAC/D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IACzD,sFAAsF;IACtF,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,8DAA8D;AAC9D,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IACtD,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAC;CACpC;AAOD;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAiC9E;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,EAClC,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE;QAAE,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAA;CAAO,GACxI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB;AAED,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,cAAc,CAAC,UAAU,CAAC,CAElF;AAkHD,wBAAgB,gBAAgB,CAAC,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,iBAAiB,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAErG"}
@@ -657,7 +657,9 @@ export class WaveWriter {
657
657
  /**
658
658
  * The epoch this writer's waves are fenced under: opened before its first
659
659
  * wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
660
- * never sent under an epoch about to close.
660
+ * never sent under an epoch about to close. Opened under the lost-call
661
+ * policy (openWaveEpoch); an open that failed even so is not the writer's
662
+ * epoch, and the next wave opens again.
661
663
  */
662
664
  async currentEpoch() {
663
665
  const supervisor = this.options.supervisor;
@@ -668,7 +670,16 @@ export class WaveWriter {
668
670
  if (held === null || (held.writer !== null && now - held.openedAt >= WAVE_EPOCH_TTL_MS / 2)) {
669
671
  // Called as a method of the supervisor, never through .call/.apply:
670
672
  // on an RPC stub those are remote method names too.
671
- this.epoch = supervisor.openWaveWriter().then((writer) => ({ writer, openedAt: now }));
673
+ const opening = openWaveEpoch(() => supervisor.openWaveWriter(), {
674
+ ...(this.options.retry === undefined ? {} : { retry: this.options.retry }),
675
+ resent: (lost) => {
676
+ this.counters.retries++;
677
+ this.options.onResend?.(lost);
678
+ },
679
+ }).then((writer) => ({ writer, openedAt: now }));
680
+ this.epoch = opening;
681
+ opening.catch(() => { if (this.epoch === opening)
682
+ this.epoch = null; });
672
683
  }
673
684
  return (await this.epoch).writer;
674
685
  }
@@ -759,6 +770,37 @@ export async function sendWaveAttempts(options) {
759
770
  }
760
771
  }
761
772
  }
773
+ /**
774
+ * Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
775
+ * process's openWriter), again while the call is lost or shed, under a
776
+ * wave's lost-call policy and budget (isLostFencedCall,
777
+ * LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
778
+ * never ran issued nothing, and one whose answer was lost issued an epoch
779
+ * nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
780
+ * it answered is its verdict. A shed open would otherwise fail every write
781
+ * the epoch was for, unsent: measured, create-next-app lost 31 of 42
782
+ * packages to one.
783
+ */
784
+ export async function openWaveEpoch(open, options = {}) {
785
+ const backoffMs = options.retry?.backoffMs ?? LOST_CALL_RESEND_BACKOFF_MS;
786
+ const timers = options.timers ?? GLOBAL_TIMERS;
787
+ for (let attempt = 0;; attempt++) {
788
+ try {
789
+ return await open();
790
+ }
791
+ catch (error) {
792
+ if (!isLostFencedCall(error) || attempt >= backoffMs.length)
793
+ throw error;
794
+ options.resent?.(lostCallAttributes({
795
+ operation: 'openWaveWriter',
796
+ attempt: attempt + 1,
797
+ of: backoffMs.length,
798
+ reason: error instanceof Error ? error.message : String(error),
799
+ }));
800
+ await new Promise((resolve) => { timers.setTimeout(resolve, retryDelayMs(backoffMs, attempt)); });
801
+ }
802
+ }
803
+ }
762
804
  /** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
763
805
  export function waveAttemptsOf(bytes) {
764
806
  return piecesOf(bytes, SEND_SLICE_BYTES);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimbus-sh/platform",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "The measured Cloudflare platform truths Nimbus is built on \u2014 error taxonomy, limits tables, budget coordination, and wire-format primitives, with zero runtime dependencies.",
5
5
  "keywords": [
6
6
  "cloudflare",
package/src/limits.ts CHANGED
@@ -101,14 +101,14 @@ export const BLOCK_CONCURRENCY_CANCEL_MS = 30_000;
101
101
  export const RESIDENT_KEEPALIVE_MS = 5_000;
102
102
 
103
103
  /**
104
- * How long the keep-alive holds a session after its last client is gone.
104
+ * How long the keep-alive holds a resident after its last client traffic.
105
105
  *
106
106
  * The keep-alive exists so a quiet process survives while its user is
107
107
  * present. Unbounded, it made every abandoned session with a dev server
108
108
  * run forever: the probe suite's cancelled runs left staging with resident
109
109
  * watchers polling `stat` at ~7.5/s in the isolate every session shares,
110
110
  * and launches that pass on a fresh Worker reset there (2026-09-22). Past
111
- * this grace with no attached socket and no request, the session idles
111
+ * this grace without runtime client traffic, even with idle sockets, the session idles
112
112
  * out as it did before the keep-alive, and the launch journal re-drives
113
113
  * the process when a client returns. Long enough for a tab reload.
114
114
  */
@@ -0,0 +1,57 @@
1
+ /** A deployed source asset: its digest, not its pathname, is its identity. */
2
+ export interface ModuleSourceAsset {
3
+ path: string;
4
+ sha256: string;
5
+ }
6
+
7
+ export interface ModuleSourceEnv {
8
+ ASSETS?: { fetch(request: Request): Promise<Response> };
9
+ }
10
+
11
+ /** Source already verified against its deployment pin. Shared across generated programs. */
12
+ export class ImmutableModuleSource {
13
+ readonly byteLength: number;
14
+ readonly text: string;
15
+ constructor(bytes: ArrayBuffer | Uint8Array, readonly asset: ModuleSourceAsset) {
16
+ this.text = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
17
+ this.byteLength = bytes.byteLength;
18
+ }
19
+ }
20
+
21
+ export type ModuleSourcePart = string | ImmutableModuleSource;
22
+ export type ModuleSourceRecipe = (string | ModuleSourceAsset)[];
23
+
24
+ /** A generated module retains its immutable pieces until the Loader needs its complete text. */
25
+ export class ModuleSource {
26
+ private joined: string | undefined;
27
+ readonly byteLength: number;
28
+ constructor(readonly parts: readonly ModuleSourcePart[]) {
29
+ this.byteLength = parts.reduce((bytes, part) => bytes + (typeof part === 'string' ? new TextEncoder().encode(part).byteLength : part.byteLength), 0);
30
+ }
31
+ get text(): string {
32
+ return this.joined ??= this.parts.map((part) => typeof part === 'string' ? part : part.text).join('');
33
+ }
34
+ recipe(): ModuleSourceRecipe {
35
+ return this.parts.map((part) => typeof part === 'string' ? part : part.asset);
36
+ }
37
+ }
38
+
39
+ /** Template interpolation without flattening immutable runtime libraries into process-owned text. */
40
+ export function moduleSource(strings: TemplateStringsArray, ...values: (string | number | boolean | null | undefined | ImmutableModuleSource | ModuleSource)[]): ModuleSource {
41
+ const parts: ModuleSourcePart[] = [];
42
+ const append = (part: ModuleSourcePart) => {
43
+ if (part === '') return;
44
+ const last = parts.length - 1;
45
+ const previous = parts[last];
46
+ if (typeof part === 'string' && typeof previous === 'string') parts[last] = previous + part;
47
+ else parts.push(part);
48
+ };
49
+ for (const [i, literal] of strings.entries()) {
50
+ append(literal);
51
+ if (i === values.length) continue;
52
+ const value = values[i];
53
+ if (value instanceof ModuleSource) value.parts.forEach(append);
54
+ else append(value instanceof ImmutableModuleSource ? value : String(value));
55
+ }
56
+ return new ModuleSource(parts);
57
+ }
package/src/retry.ts CHANGED
@@ -12,8 +12,8 @@
12
12
  * Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
13
13
  * that failed together do not try again together.
14
14
  *
15
- * Self-contained, both functions: a facet that cannot import carries them
16
- * by source (fn.toString(); the npm install facet's preamble does).
15
+ * A facet carries these same functions and their dependencies in its
16
+ * build-time compiled task expression (the npm install facet does).
17
17
  */
18
18
 
19
19
  /**
@@ -820,7 +820,9 @@ export class WaveWriter<Meta = undefined> {
820
820
  /**
821
821
  * The epoch this writer's waves are fenced under: opened before its first
822
822
  * wave, and again once half of WAVE_EPOCH_TTL_MS has passed, so a wave is
823
- * never sent under an epoch about to close.
823
+ * never sent under an epoch about to close. Opened under the lost-call
824
+ * policy (openWaveEpoch); an open that failed even so is not the writer's
825
+ * epoch, and the next wave opens again.
824
826
  */
825
827
  private async currentEpoch(): Promise<string | null> {
826
828
  const supervisor = this.options.supervisor;
@@ -830,7 +832,15 @@ export class WaveWriter<Meta = undefined> {
830
832
  if (held === null || (held.writer !== null && now - held.openedAt >= WAVE_EPOCH_TTL_MS / 2)) {
831
833
  // Called as a method of the supervisor, never through .call/.apply:
832
834
  // on an RPC stub those are remote method names too.
833
- this.epoch = supervisor.openWaveWriter().then((writer) => ({ writer, openedAt: now }));
835
+ const opening = openWaveEpoch(() => supervisor.openWaveWriter!(), {
836
+ ...(this.options.retry === undefined ? {} : { retry: this.options.retry }),
837
+ resent: (lost) => {
838
+ this.counters.retries++;
839
+ this.options.onResend?.(lost);
840
+ },
841
+ }).then((writer) => ({ writer, openedAt: now }));
842
+ this.epoch = opening;
843
+ opening.catch(() => { if (this.epoch === opening) this.epoch = null; });
834
844
  }
835
845
  return (await this.epoch!).writer;
836
846
  }
@@ -943,6 +953,39 @@ export async function sendWaveAttempts(options: WaveAttempts): Promise<unknown>
943
953
  }
944
954
  }
945
955
 
956
+ /**
957
+ * Open a writer epoch (`open`: the supervisor's openWaveWriter, or a
958
+ * process's openWriter), again while the call is lost or shed, under a
959
+ * wave's lost-call policy and budget (isLostFencedCall,
960
+ * LOST_CALL_RESEND_BACKOFF_MS). Re-opening is safe: an open the session
961
+ * never ran issued nothing, and one whose answer was lost issued an epoch
962
+ * nothing is sent under, which closes at WAVE_EPOCH_TTL_MS. Anything else
963
+ * it answered is its verdict. A shed open would otherwise fail every write
964
+ * the epoch was for, unsent: measured, create-next-app lost 31 of 42
965
+ * packages to one.
966
+ */
967
+ export async function openWaveEpoch(
968
+ open: () => Promise<string | null>,
969
+ options: { retry?: { backoffMs: readonly number[] }; resent?: (lost: Record<string, string | number>) => void; timers?: WaveTimers } = {},
970
+ ): Promise<string | null> {
971
+ const backoffMs = options.retry?.backoffMs ?? LOST_CALL_RESEND_BACKOFF_MS;
972
+ const timers = options.timers ?? GLOBAL_TIMERS;
973
+ for (let attempt = 0; ; attempt++) {
974
+ try {
975
+ return await open();
976
+ } catch (error) {
977
+ if (!isLostFencedCall(error) || attempt >= backoffMs.length) throw error;
978
+ options.resent?.(lostCallAttributes({
979
+ operation: 'openWaveWriter',
980
+ attempt: attempt + 1,
981
+ of: backoffMs.length,
982
+ reason: error instanceof Error ? error.message : String(error),
983
+ }));
984
+ await new Promise<void>((resolve) => { timers.setTimeout(resolve, retryDelayMs(backoffMs, attempt)); });
985
+ }
986
+ }
987
+ }
988
+
946
989
  /** A wave's encoded bytes as each attempt's stream (in SEND_SLICE_BYTES pieces, each a copy). */
947
990
  export function waveAttemptsOf(bytes: Uint8Array): () => ReadableStream<Uint8Array> {
948
991
  return piecesOf(bytes, SEND_SLICE_BYTES);