@nimbus-sh/platform 0.7.0 → 0.8.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/README.md CHANGED
@@ -124,7 +124,7 @@ export function* slices(bytes: Uint8Array): Generator<Uint8Array> {
124
124
  | `MAX_TX_LOGICAL_ROWS` / `MAX_TX_SQL_EXECS` | 256 / 64 | rows and execs in that same transaction |
125
125
  | `SQLITE_MAX_ROW_BYTES` | 2,000,000 | bytes per ROW, key length included; budget values against the row bound |
126
126
  | `SQLITE_MAX_STATEMENT_BYTES` | 100 KiB | SQL text per exec |
127
- | `SQLITE_MAX_BOUND_PARAMETERS` | 100 | bound parameters per query; a batched insert breaches this first |
127
+ | `SQL_MAX_BOUND_PARAMETERS` | 100 | bound parameters per statement (101 fail); a batched insert breaches this first |
128
128
  | `DO_STORAGE_LIMIT_BYTES` | 10,000,000,000 | storage per Durable Object, shared by every facet and clone under it, with no copy-on-write credit |
129
129
  | `BLOCK_CONCURRENCY_CANCEL_MS` | 30,000 | how long a `blockConcurrencyWhile()` callback may run before the object is reset |
130
130
  | `WS_ATTACHMENT_LIMIT_BYTES` | 16,384 | serialized bytes per hibernatable WebSocket attachment |
@@ -113,6 +113,15 @@ export interface DiagCounters {
113
113
  * Empty when the most recent batch had zero errors. */
114
114
  errorsByModule: Record<string, string>;
115
115
  };
116
+ /**
117
+ * File contents and stdin the session has handed its processes, cumulative
118
+ * since isolate start: the bytes of each supervisor envelope's answer as it
119
+ * leaves the session (worker session/supervisor-op.ts answerSupervisorOp)
120
+ * from readFile, readFileBytes, fsRead, fsReadRange, fsReadBatch, the read
121
+ * an fsAcquired carries, and cpReadStdin (a pipe's read ahead). A run's
122
+ * delta is what it was handed, which bounds what it can hold.
123
+ */
124
+ supervisorAnsweredBytes: number;
116
125
  /** Pipelined R2 race outcomes. All counts are cumulative since
117
126
  * DO-isolate start. Per-tier cache statistics live in cache-stats. */
118
127
  r2: {
@@ -130,6 +139,8 @@ export interface DiagCounters {
130
139
  }
131
140
  /** Read a snapshot — caller-side mutations don't affect the singleton. */
132
141
  export declare function readDiagCounters(): DiagCounters;
142
+ /** Count `bytes` the session answered a process's supervisor call with. */
143
+ export declare function recordSupervisorAnswer(bytes: number): void;
133
144
  /** Set the install phase. */
134
145
  export declare function setInstallPhase(p: InstallPhase): void;
135
146
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"diag-counters.d.ts","sourceRoot":"","sources":["../src/diag-counters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diag-counters.d.ts","sourceRoot":"","sources":["../src/diag-counters.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,7 @@ const _counters = {
23
23
  inFlightRpcPayloadBytes: 0,
24
24
  prefetchBundleBytes: 0,
25
25
  prefetchCacheBytes: 0,
26
+ supervisorAnsweredBytes: 0,
26
27
  installFacet: {
27
28
  tarballsCompleted: 0,
28
29
  cumulativeBytesDecoded: 0,
@@ -47,6 +48,10 @@ const _counters = {
47
48
  export function readDiagCounters() {
48
49
  return { ..._counters };
49
50
  }
51
+ /** Count `bytes` the session answered a process's supervisor call with. */
52
+ export function recordSupervisorAnswer(bytes) {
53
+ _counters.supervisorAnsweredBytes += bytes;
54
+ }
50
55
  /** Set the install phase. */
51
56
  export function setInstallPhase(p) {
52
57
  _counters.installPhase = p;
@@ -51,7 +51,10 @@ export declare class SupervisorAllocationBudget {
51
51
  * stops a large read overlapping a large write.
52
52
  */
53
53
  acquireWithoutLifecycle(bytes: number, signal?: AbortSignal): Promise<ResizableCreditLease>;
54
+ /** Reserve bytes now or not at all, driving the lifecycle as acquire does. */
55
+ tryAcquire(bytes: number): ResizableCreditLease | null;
54
56
  private _acquire;
57
+ private wrap;
55
58
  }
56
59
  /**
57
60
  * A registered observer (typically a SqliteVFS) receives shrink/restore
@@ -77,6 +80,8 @@ export declare function registerAllocObserver(o: AllocObserver): () => void;
77
80
  * Reserve an exact number of supervisor-resident bytes.
78
81
  */
79
82
  export declare function acquireSupervisorAllocation(bytes: number, signal?: AbortSignal): Promise<ResizableCreditLease>;
83
+ /** Reserve bytes now if they can be granted without waiting, else null. */
84
+ export declare function tryAcquireSupervisorAllocation(bytes: number): ResizableCreditLease | null;
80
85
  /**
81
86
  * Reserve bytes for a filesystem READ. Takes the same byte credit as any
82
87
  * other owner but does not shrink the disposable VFS cache, which reads are
@@ -1 +1 @@
1
- {"version":3,"file":"heavy-alloc-coord.d.ts","sourceRoot":"","sources":["../src/heavy-alloc-coord.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,yBAAyB;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,0BAA0B;IAWnC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAX5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAK;gBAGlB,QAAQ,EAAE,MAAM,EACR,SAAS,GAAE,yBAA8B,EAC1D,OAAO,GAAE,yBAA8B;IAKzC,IAAI,KAAK,IAAI,+BAA+B,CAK3C;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAI3E;;;;;;;;OAQG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;YAI7E,QAAQ;CAmCvB;AAED;;;GAGG;AACH,UAAU,aAAa;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,IAAI,CAWlE;AAqCD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAMjF;AAED,wBAAgB,8BAA8B,IAAI,+BAA+B,CAEhF"}
1
+ {"version":3,"file":"heavy-alloc-coord.d.ts","sourceRoot":"","sources":["../src/heavy-alloc-coord.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC/B,MAAM,2BAA2B,CAAC;AAEnC,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,yBAAyB;IACjC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,0BAA0B;IAWnC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAX5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB,CAAK;gBAGlB,QAAQ,EAAE,MAAM,EACR,SAAS,GAAE,yBAA8B,EAC1D,OAAO,GAAE,yBAA8B;IAKzC,IAAI,KAAK,IAAI,+BAA+B,CAK3C;IAED;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAI3E;;;;;;;;OAQG;IACH,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAI3F,8EAA8E;IAC9E,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;YAKxC,QAAQ;IAQtB,OAAO,CAAC,IAAI;CA8Bb;AAED;;;GAGG;AACH,UAAU,aAAa;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,IAAI,CAWlE;AAqCD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED,2EAA2E;AAC3E,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAEzF;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,oBAAoB,CAAC,CAE/B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAMjF;AAED,wBAAgB,8BAA8B,IAAI,+BAA+B,CAEhF"}
@@ -55,8 +55,15 @@ export class SupervisorAllocationBudget {
55
55
  acquireWithoutLifecycle(bytes, signal) {
56
56
  return this._acquire(bytes, signal, false);
57
57
  }
58
+ /** Reserve bytes now or not at all, driving the lifecycle as acquire does. */
59
+ tryAcquire(bytes) {
60
+ const credit = this.credits.tryAcquire(bytes);
61
+ return credit ? this.wrap(credit, true) : null;
62
+ }
58
63
  async _acquire(bytes, signal, drivesLifecycle) {
59
- const credit = await this.credits.acquire(bytes, signal);
64
+ return this.wrap(await this.credits.acquire(bytes, signal), drivesLifecycle);
65
+ }
66
+ wrap(credit, drivesLifecycle) {
60
67
  if (drivesLifecycle) {
61
68
  this.lifecycleHolders++;
62
69
  if (!this.active) {
@@ -160,6 +167,10 @@ const supervisorAllocationBudget = new SupervisorAllocationBudget(SUPERVISOR_IN_
160
167
  export function acquireSupervisorAllocation(bytes, signal) {
161
168
  return supervisorAllocationBudget.acquire(bytes, signal);
162
169
  }
170
+ /** Reserve bytes now if they can be granted without waiting, else null. */
171
+ export function tryAcquireSupervisorAllocation(bytes) {
172
+ return supervisorAllocationBudget.tryAcquire(bytes);
173
+ }
163
174
  /**
164
175
  * Reserve bytes for a filesystem READ. Takes the same byte credit as any
165
176
  * other owner but does not shrink the disposable VFS cache, which reads are
package/dist/limits.d.ts CHANGED
@@ -46,12 +46,6 @@ export declare const HYDRATION_DEADLINE_MS = 30000;
46
46
  * statements, a batched multi-VALUES insert being the realistic breach).
47
47
  */
48
48
  export declare const SQLITE_MAX_STATEMENT_BYTES: number;
49
- /**
50
- * Maximum bound parameters per query. The easiest cap to hit accidentally:
51
- * a batched insert of more than 100/columns rows in one statement breaches
52
- * it.
53
- */
54
- export declare const SQLITE_MAX_BOUND_PARAMETERS = 100;
55
49
  /**
56
50
  * Maximum bytes of one string, BLOB, or table ROW — the bound is per ROW,
57
51
  * key length included, not per value. The measured single-value ceiling is
@@ -107,6 +101,7 @@ export declare const MAX_RPC_SAFE_PAYLOAD_BYTES: number;
107
101
  export declare const ONE_SHOT_MODULE_MAP_MAX_BYTES: number;
108
102
  export declare const SUPERVISOR_HEAP_CEILING_BYTES: number;
109
103
  export declare const FACET_OWN_WRITE_MEMORY_BYTES: number;
104
+ export declare const WASI_RESIDENT_STORE_BYTES: number;
110
105
  export declare const SUPERVISOR_IN_FLIGHT_ALLOCATION_BUDGET_BYTES: number;
111
106
  export declare const SUPERVISOR_READ_RESERVE_BYTES: number;
112
107
  export declare const MAX_GLOBAL_WRITE_STREAM_CREDIT_BYTES: number;
@@ -1 +1 @@
1
- {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAS,CAAC;AAEjC,eAAO,MAAM,iBAAiB,QAAkB,CAAC;AACjD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAI5C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,cAAiB,CAAC;AAMrD,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAI9C;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAIlD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAIrD;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAOhD,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAmB3D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AA6B9D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AAM9D,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAO7D,eAAO,MAAM,4CAA4C,QAAmB,CAAC;AAY7E,eAAO,MAAM,6BAA6B,QAAc,CAAC;AAKzD,eAAO,MAAM,oCAAoC,QAAkB,CAAC;AAQpE,eAAO,MAAM,0BAA0B,QAA6B,CAAC;AACrE,eAAO,MAAM,sBAAsB,IAAI,CAAC"}
1
+ {"version":3,"file":"limits.d.ts","sourceRoot":"","sources":["../src/limits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,QAAS,CAAC;AAEjC,eAAO,MAAM,iBAAiB,QAAkB,CAAC;AACjD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAI5C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,cAAiB,CAAC;AAMrD,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,QAAa,CAAC;AAErD;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,UAAY,CAAC;AAI9C;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAIlD;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAE3C;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,8BAA8B,QAAS,CAAC;AAIrD;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAOhD,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AAmB3D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AA6B9D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AAM9D,eAAO,MAAM,4BAA4B,QAAmB,CAAC;AAQ7D,eAAO,MAAM,yBAAyB,QAAmB,CAAC;AAO1D,eAAO,MAAM,4CAA4C,QAAmB,CAAC;AAY7E,eAAO,MAAM,6BAA6B,QAAc,CAAC;AAKzD,eAAO,MAAM,oCAAoC,QAAkB,CAAC;AAQpE,eAAO,MAAM,0BAA0B,QAA6B,CAAC;AACrE,eAAO,MAAM,sBAAsB,IAAI,CAAC"}
package/dist/limits.js CHANGED
@@ -57,12 +57,6 @@ export const HYDRATION_DEADLINE_MS = 30_000;
57
57
  * statements, a batched multi-VALUES insert being the realistic breach).
58
58
  */
59
59
  export const SQLITE_MAX_STATEMENT_BYTES = 100 * 1024;
60
- /**
61
- * Maximum bound parameters per query. The easiest cap to hit accidentally:
62
- * a batched insert of more than 100/columns rows in one statement breaches
63
- * it.
64
- */
65
- export const SQLITE_MAX_BOUND_PARAMETERS = 100;
66
60
  /**
67
61
  * Maximum bytes of one string, BLOB, or table ROW — the bound is per ROW,
68
62
  * key length included, not per value. The measured single-value ceiling is
@@ -173,6 +167,13 @@ export const SUPERVISOR_HEAP_CEILING_BYTES = 64 * 1024 * 1024;
173
167
  // works: at most this many bytes, least recently used out first. An eighth
174
168
  // of a facet's measured ~208-256 MiB, the rest left to the program.
175
169
  export const FACET_OWN_WRITE_MEMORY_BYTES = 32 * 1024 * 1024;
170
+ // A WASI process's copy of the namespace and of the files it reads
171
+ // (core runtime/wasi/resident-filesystem.ts): held in its facet's heap beside
172
+ // the guest's linear memory, and never past this. Names are listed and bytes
173
+ // fetched only as the program asks for them, so the cap bounds a tree walker
174
+ // or a program that reads much, not what a short run holds. Past it the store
175
+ // holds nothing more and the session answers.
176
+ export const WASI_RESIDENT_STORE_BYTES = 32 * 1024 * 1024;
176
177
  // Shared allowance for transient allocations in the supervisor DO. With the
177
178
  // VFS LRU shrunk to 8 MiB during an active reservation, 40 MiB of admitted
178
179
  // payload plus the 9 MiB bundle baseline stays below the 64 MiB soft ceiling
@@ -0,0 +1,62 @@
1
+ /**
2
+ * lost-call.ts — the one policy for a call that never reaches the session.
3
+ *
4
+ * The platform drops calls into a Durable Object now and then, and the
5
+ * caller cannot tell a call that never arrived from one that is slow:
6
+ * - reads, SupervisorRPC → session, under three concurrent sessions
7
+ * (2026-09-28): 11 of 521 read batches never reached the session and
8
+ * were still pending 110-560 s later; every read that answered did so
9
+ * within 5 s;
10
+ * - write waves, a facet's writeBatchStream (2026-10-06, two next.js
11
+ * clones): the transport read the stream's first ~1 MiB within 0.1 s
12
+ * and nothing more, while the session held no stream, credit,
13
+ * allocation or transaction for it and kept committing other waves;
14
+ * healthy, with 8 producers saturating one session, the longest gap
15
+ * between a wave's reads was 2.5 s and the slowest wave 5.3 s;
16
+ * - calls that fail at once, "Network connection lost." (`retryable`),
17
+ * which classifyDoCall names.
18
+ *
19
+ * Detection and timings live here; the recovery depends on what a second
20
+ * delivery would do. A read is idempotent, so it is hedged: the same call
21
+ * on a fresh stub, the first answer taken (fabric do-calls `hedgeAfterMs`).
22
+ * A write wave carries a stream the first attempt consumes, so it cannot be
23
+ * hedged: it is re-encoded and re-sent under a fence (`WaveFence`), and the
24
+ * session refuses an attempt older than one it has seen from the same
25
+ * writer, so a late original never applies over its re-send.
26
+ */
27
+ /** An idempotent call unanswered this long is hedged on a fresh stub. */
28
+ export declare const LOST_CALL_HEDGE_AFTER_MS = 5000;
29
+ /** A stream nothing has read for this long, before its end, never reached the session. */
30
+ export declare const LOST_STREAM_STALL_MS = 10000;
31
+ /** A call unanswered this long after its stream ended is taken as lost. */
32
+ export declare const LOST_STREAM_ANSWER_MS = 20000;
33
+ /**
34
+ * How long a write-wave epoch the session issued admits attempts. Anything
35
+ * sent under an epoch the session does not know, or one past this, is
36
+ * refused: a call lost for longer than this can only be refused, never
37
+ * admitted. A writer opens a new epoch once half of this has passed.
38
+ */
39
+ export declare const WAVE_EPOCH_TTL_MS: number;
40
+ /**
41
+ * Waits before each re-send of a lost non-idempotent call (±25% jitter):
42
+ * ~42 s in all, to outlast a coordinator queue deep enough to shed. Its
43
+ * length is the bound on re-sends.
44
+ */
45
+ export declare const LOST_CALL_RESEND_BACKOFF_MS: readonly number[];
46
+ /**
47
+ * Whether `error` is the platform losing a fenced call: a dropped
48
+ * connection, a replaced isolate, a storage reset, or an object that shed
49
+ * it. Overloaded is included for fenced re-sends only: the platform's advice
50
+ * is not to retry an overloaded object, but these are few and backed off,
51
+ * and npm measured one re-send recover a 119-package install that one shed
52
+ * cost 31 packages (do-calls' unfenced verbs still never retry it).
53
+ */
54
+ export declare function isLostFencedCall(error: unknown): boolean;
55
+ /** The attributes a lost call is logged and traced under, by every caller. */
56
+ export declare function lostCallAttributes(lost: {
57
+ operation: string;
58
+ attempt: number;
59
+ of: number;
60
+ reason: string;
61
+ }): Record<string, string | number>;
62
+ //# sourceMappingURL=lost-call.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lost-call.d.ts","sourceRoot":"","sources":["../src/lost-call.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,yEAAyE;AACzE,eAAO,MAAM,wBAAwB,OAAQ,CAAC;AAE9C,0FAA0F;AAC1F,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,QAAc,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAA+C,CAAC;AAEzG;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAOlC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * lost-call.ts — the one policy for a call that never reaches the session.
3
+ *
4
+ * The platform drops calls into a Durable Object now and then, and the
5
+ * caller cannot tell a call that never arrived from one that is slow:
6
+ * - reads, SupervisorRPC → session, under three concurrent sessions
7
+ * (2026-09-28): 11 of 521 read batches never reached the session and
8
+ * were still pending 110-560 s later; every read that answered did so
9
+ * within 5 s;
10
+ * - write waves, a facet's writeBatchStream (2026-10-06, two next.js
11
+ * clones): the transport read the stream's first ~1 MiB within 0.1 s
12
+ * and nothing more, while the session held no stream, credit,
13
+ * allocation or transaction for it and kept committing other waves;
14
+ * healthy, with 8 producers saturating one session, the longest gap
15
+ * between a wave's reads was 2.5 s and the slowest wave 5.3 s;
16
+ * - calls that fail at once, "Network connection lost." (`retryable`),
17
+ * which classifyDoCall names.
18
+ *
19
+ * Detection and timings live here; the recovery depends on what a second
20
+ * delivery would do. A read is idempotent, so it is hedged: the same call
21
+ * on a fresh stub, the first answer taken (fabric do-calls `hedgeAfterMs`).
22
+ * A write wave carries a stream the first attempt consumes, so it cannot be
23
+ * hedged: it is re-encoded and re-sent under a fence (`WaveFence`), and the
24
+ * session refuses an attempt older than one it has seen from the same
25
+ * writer, so a late original never applies over its re-send.
26
+ */
27
+ import { classifyDoCall, isRetryableDoCall } from './oom-classify.js';
28
+ /** An idempotent call unanswered this long is hedged on a fresh stub. */
29
+ export const LOST_CALL_HEDGE_AFTER_MS = 5_000;
30
+ /** A stream nothing has read for this long, before its end, never reached the session. */
31
+ export const LOST_STREAM_STALL_MS = 10_000;
32
+ /** A call unanswered this long after its stream ended is taken as lost. */
33
+ export const LOST_STREAM_ANSWER_MS = 20_000;
34
+ /**
35
+ * How long a write-wave epoch the session issued admits attempts. Anything
36
+ * sent under an epoch the session does not know, or one past this, is
37
+ * refused: a call lost for longer than this can only be refused, never
38
+ * admitted. A writer opens a new epoch once half of this has passed.
39
+ */
40
+ export const WAVE_EPOCH_TTL_MS = 10 * 60_000;
41
+ /**
42
+ * Waits before each re-send of a lost non-idempotent call (±25% jitter):
43
+ * ~42 s in all, to outlast a coordinator queue deep enough to shed. Its
44
+ * length is the bound on re-sends.
45
+ */
46
+ export const LOST_CALL_RESEND_BACKOFF_MS = [250, 1_000, 3_000, 6_000, 12_000, 20_000];
47
+ /**
48
+ * Whether `error` is the platform losing a fenced call: a dropped
49
+ * connection, a replaced isolate, a storage reset, or an object that shed
50
+ * it. Overloaded is included for fenced re-sends only: the platform's advice
51
+ * is not to retry an overloaded object, but these are few and backed off,
52
+ * and npm measured one re-send recover a 119-package install that one shed
53
+ * cost 31 packages (do-calls' unfenced verbs still never retry it).
54
+ */
55
+ export function isLostFencedCall(error) {
56
+ const kind = classifyDoCall(error);
57
+ return isRetryableDoCall(kind) || kind === 'overloaded';
58
+ }
59
+ /** The attributes a lost call is logged and traced under, by every caller. */
60
+ export function lostCallAttributes(lost) {
61
+ return {
62
+ 'do_call.operation': lost.operation,
63
+ 'do_call.attempts': lost.attempt,
64
+ 'do_call.max_attempts': lost.of,
65
+ 'do_call.lost_reason': lost.reason,
66
+ };
67
+ }
@@ -110,6 +110,20 @@ export declare function classifyMessage(msg: string): OomCause;
110
110
  * (`loaders/process-fabric.ts`) — recurs, exhausts the budget and surfaces.
111
111
  */
112
112
  export declare function isTransientDoReset(input: unknown): boolean;
113
+ /**
114
+ * The platform's own word that the actor a call reached was reset or killed:
115
+ * its `durableObjectReset` flag, or one of its termination sentences, whole.
116
+ * Text a program wrote never counts, however it reads: a process whose host
117
+ * this matches is ended (fabric process-host.ts HostLoss).
118
+ */
119
+ export declare function isHostReset(input: unknown): boolean;
120
+ /**
121
+ * A failure the platform reports without a cause: workerd's "internal error;
122
+ * reference = <id>", whose reference only Cloudflare can look up. The error
123
+ * may carry `durableObjectReset` (the object it reached was reset), and
124
+ * nothing else; the caller has to name what it was doing.
125
+ */
126
+ export declare function isUnexplainedPlatformError(input: unknown): boolean;
113
127
  /**
114
128
  * Workerd shed the call because the target Durable Object's input-gate
115
129
  * queue was too deep or too old: "Durable Object is overloaded."
@@ -1 +1 @@
1
- {"version":3,"file":"oom-classify.d.ts","sourceRoot":"","sources":["../src/oom-classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH,QAAA,MAAM,UAAU,kLAYN,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAEjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAItD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAmErD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW;AACrB,8CAA8C;AAC5C,oBAAoB;AACtB,8CAA8C;GAC5C,iBAAiB;AACnB,uEAAuE;GACrE,eAAe;AACjB,wDAAwD;GACtD,gBAAgB;AAClB;kDACkD;GAChD,YAAY;AACd,kEAAkE;GAChE,WAAW,CAAC;AAEhB;2DAC2D;AAC3D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAK7D;AAmBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAsB1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiBpD"}
1
+ {"version":3,"file":"oom-classify.d.ts","sourceRoot":"","sources":["../src/oom-classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAEH,QAAA,MAAM,UAAU,kLAYN,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;AAEjD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAItD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAmErD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO1D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAInD;AAYD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAElE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,WAAW;AACrB,8CAA8C;AAC5C,oBAAoB;AACtB,8CAA8C;GAC5C,iBAAiB;AACnB,uEAAuE;GACrE,eAAe;AACjB,wDAAwD;GACtD,gBAAgB;AAClB;kDACkD;GAChD,YAAY;AACd,kEAAkE;GAChE,WAAW,CAAC;AAEhB;2DAC2D;AAC3D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAK7D;AAmBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAsB1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAiBpD"}
@@ -214,6 +214,36 @@ export function isTransientDoReset(input) {
214
214
  return true;
215
215
  return false;
216
216
  }
217
+ /**
218
+ * The platform's own word that the actor a call reached was reset or killed:
219
+ * its `durableObjectReset` flag, or one of its termination sentences, whole.
220
+ * Text a program wrote never counts, however it reads: a process whose host
221
+ * this matches is ended (fabric process-host.ts HostLoss).
222
+ */
223
+ export function isHostReset(input) {
224
+ if (typeof input === 'object' && input !== null && Reflect.get(input, 'durableObjectReset') === true)
225
+ return true;
226
+ const message = readMessage(input).trim().replace(/^broken\.\w+;\s*jsg\.\w+:\s*/, '');
227
+ return HOST_TERMINATIONS.some((signature) => signature.test(message));
228
+ }
229
+ const HOST_TERMINATIONS = [
230
+ /^Durable Object's isolate exceeded its memory limit (?:and was reset\.|due to )/,
231
+ /^Worker (?:has )?exceeded memory limit\.$/,
232
+ /^(?:Python )?Worker exceeded CPU time limit\.?$/,
233
+ /^Durable Object exceeded its CPU time limit and was reset\.$/,
234
+ /^Durable Object reset because its code was updated\.$/,
235
+ /^Internal error (?:in|while starting up) Durable Object storage caused object to be reset; reference = \S+$/,
236
+ /^Durable Object storage operation exceeded timeout which caused the object to be reset\.$/,
237
+ ];
238
+ /**
239
+ * A failure the platform reports without a cause: workerd's "internal error;
240
+ * reference = <id>", whose reference only Cloudflare can look up. The error
241
+ * may carry `durableObjectReset` (the object it reached was reset), and
242
+ * nothing else; the caller has to name what it was doing.
243
+ */
244
+ export function isUnexplainedPlatformError(input) {
245
+ return /^internal error; reference = \S+$/i.test(readMessage(input).trim());
246
+ }
217
247
  /**
218
248
  * Workerd shed the call because the target Durable Object's input-gate
219
249
  * queue was too deep or too old: "Durable Object is overloaded."
@@ -0,0 +1,49 @@
1
+ /**
2
+ * retry.ts — the one retry policy: the loop that tries an operation again
3
+ * when its outcome is worth another try, and the wait between tries.
4
+ *
5
+ * Each caller names what is worth another try and how far apart, because
6
+ * that is what differs and was measured per transport:
7
+ * - the npm registry (npm/registry-retry.ts): a 5xx or a request that
8
+ * never answered, 500/1500/4500 ms;
9
+ * - a git server (git/pack/transport.ts): an idempotent request that
10
+ * failed in transit, stalled, or met a transient edge status, 1/3 s;
11
+ * - a lost write wave (lost-call.ts LOST_CALL_RESEND_BACKOFF_MS).
12
+ * Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
13
+ * that failed together do not try again together.
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).
17
+ */
18
+ /**
19
+ * The wait before re-try `attempt` (0-based, the try that just failed):
20
+ * `schedule[attempt]`, its last entry once past the end, ±25%.
21
+ */
22
+ export declare function retryDelayMs(schedule: readonly number[], attempt: number): number;
23
+ /** An attempt's outcome: what it returned, or what it threw. */
24
+ export type RetryOutcome<T> = {
25
+ readonly ok: true;
26
+ readonly value: T;
27
+ } | {
28
+ readonly ok: false;
29
+ readonly error: unknown;
30
+ };
31
+ export interface RetryPolicy<T> {
32
+ /** How many times to try again after the first try. */
33
+ readonly retries: number;
34
+ /** The waits before each re-try, for retryDelayMs. */
35
+ readonly schedule: readonly number[];
36
+ /** Why `outcome` is worth another try, or null to keep it. Not asked of the last try. */
37
+ retryReason(outcome: RetryOutcome<T>): string | null;
38
+ /** A returned value given up for another try (its body cancelled, its stub disposed). */
39
+ discard?(value: T): unknown;
40
+ /** Each re-try, 1-based, with its wait and why. */
41
+ onRetry?(retry: number, of: number, delayMs: number, reason: string): void;
42
+ }
43
+ /**
44
+ * `attempt(n)` for n = 0, 1, … until its outcome is not worth another try
45
+ * or the policy's re-tries are spent; then that outcome: its value
46
+ * returned, its error thrown.
47
+ */
48
+ export declare function retrying<T>(attempt: (n: number) => Promise<T>, policy: RetryPolicy<T>): Promise<T>;
49
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGjF;AAED,gEAAgE;AAChE,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,yFAAyF;IACzF,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,yFAAyF;IACzF,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAC5B,mDAAmD;IACnD,OAAO,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5E;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAyBxG"}
package/dist/retry.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * retry.ts — the one retry policy: the loop that tries an operation again
3
+ * when its outcome is worth another try, and the wait between tries.
4
+ *
5
+ * Each caller names what is worth another try and how far apart, because
6
+ * that is what differs and was measured per transport:
7
+ * - the npm registry (npm/registry-retry.ts): a 5xx or a request that
8
+ * never answered, 500/1500/4500 ms;
9
+ * - a git server (git/pack/transport.ts): an idempotent request that
10
+ * failed in transit, stalled, or met a transient edge status, 1/3 s;
11
+ * - a lost write wave (lost-call.ts LOST_CALL_RESEND_BACKOFF_MS).
12
+ * Every wait is its schedule's entry ±25%, uniformly, so concurrent callers
13
+ * that failed together do not try again together.
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).
17
+ */
18
+ /**
19
+ * The wait before re-try `attempt` (0-based, the try that just failed):
20
+ * `schedule[attempt]`, its last entry once past the end, ±25%.
21
+ */
22
+ export function retryDelayMs(schedule, attempt) {
23
+ const base = schedule[Math.min(attempt, schedule.length - 1)] ?? 0;
24
+ return Math.max(0, Math.round(base + (Math.random() * 2 - 1) * base * 0.25));
25
+ }
26
+ /**
27
+ * `attempt(n)` for n = 0, 1, … until its outcome is not worth another try
28
+ * or the policy's re-tries are spent; then that outcome: its value
29
+ * returned, its error thrown.
30
+ */
31
+ export async function retrying(attempt, policy) {
32
+ for (let n = 0;; n++) {
33
+ let outcome;
34
+ try {
35
+ outcome = { ok: true, value: await attempt(n) };
36
+ }
37
+ catch (error) {
38
+ outcome = { ok: false, error };
39
+ }
40
+ const reason = n < policy.retries ? policy.retryReason(outcome) : null;
41
+ if (reason === null) {
42
+ if (outcome.ok)
43
+ return outcome.value;
44
+ throw outcome.error;
45
+ }
46
+ if (outcome.ok && policy.discard) {
47
+ try {
48
+ await policy.discard(outcome.value);
49
+ }
50
+ catch {
51
+ // It is being given up either way.
52
+ }
53
+ }
54
+ const delayMs = retryDelayMs(policy.schedule, n);
55
+ policy.onRetry?.(n + 1, policy.retries, delayMs, reason);
56
+ // The executor form: this package's lib (ES2022) has no Promise.withResolvers.
57
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
58
+ }
59
+ }
package/dist/utf8.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * utf8.ts — the UTF-8 length of a string, without encoding it.
3
+ *
4
+ * Bounds on names and payloads are in bytes, and the hot ones (every path a
5
+ * W7 wave or a listing page carries) were measured by encoding the string
6
+ * into a new buffer only to read its length. This counts the same bytes
7
+ * TextEncoder would write: one to four per code point, and three for a
8
+ * lone surrogate, which it writes as U+FFFD.
9
+ */
10
+ export declare function utf8Length(text: string): number;
11
+ //# sourceMappingURL=utf8.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utf8.d.ts","sourceRoot":"","sources":["../src/utf8.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqB/C"}
package/dist/utf8.js ADDED
@@ -0,0 +1,35 @@
1
+ /**
2
+ * utf8.ts — the UTF-8 length of a string, without encoding it.
3
+ *
4
+ * Bounds on names and payloads are in bytes, and the hot ones (every path a
5
+ * W7 wave or a listing page carries) were measured by encoding the string
6
+ * into a new buffer only to read its length. This counts the same bytes
7
+ * TextEncoder would write: one to four per code point, and three for a
8
+ * lone surrogate, which it writes as U+FFFD.
9
+ */
10
+ export function utf8Length(text) {
11
+ let bytes = text.length;
12
+ for (let index = 0; index < text.length; index++) {
13
+ const unit = text.charCodeAt(index);
14
+ if (unit < 0x80)
15
+ continue;
16
+ if (unit < 0x800) {
17
+ bytes += 1;
18
+ }
19
+ else if (unit >= 0xd800 && unit <= 0xdbff && index + 1 < text.length) {
20
+ const next = text.charCodeAt(index + 1);
21
+ if (next >= 0xdc00 && next <= 0xdfff) {
22
+ // A pair: two units, four bytes.
23
+ bytes += 2;
24
+ index++;
25
+ }
26
+ else {
27
+ bytes += 2;
28
+ }
29
+ }
30
+ else {
31
+ bytes += 2;
32
+ }
33
+ }
34
+ return bytes;
35
+ }