@nimbus-sh/platform 0.4.0 → 0.5.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/dist/limits.d.ts CHANGED
@@ -18,6 +18,13 @@ export declare const CHUNK_SIZE = 65536;
18
18
  export declare const MAX_TX_BLOB_BYTES: number;
19
19
  export declare const MAX_TX_LOGICAL_ROWS = 256;
20
20
  export declare const MAX_TX_SQL_EXECS = 64;
21
+ /**
22
+ * Bound parameters per SQL statement on Durable Objects SQLite. Measured
23
+ * 2026-09-21 on workerd: 100 bind, 101 fail as `too many SQL variables`
24
+ * (a 9-row insert of 12 columns fails, 8 rows succeed). Every IN-list and
25
+ * multi-row VALUES statement is sized from this.
26
+ */
27
+ export declare const SQL_MAX_BOUND_PARAMETERS = 100;
21
28
  /**
22
29
  * Storage per SQLite-backed Durable Object: 10 decimal GB documented
23
30
  * (Workers Paid), shared by the root object, every facet beneath it, and
@@ -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;AAInC;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,sBAAsB,cAAiB,CAAC;AAErD;;;;;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;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAOhD,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AA6B3D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AAO9D,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;AAErD;;;;;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;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,QAAS,CAAC;AAOhD,eAAO,MAAM,0BAA0B,QAAmB,CAAC;AA6B3D,eAAO,MAAM,6BAA6B,QAAmB,CAAC;AAO9D,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
@@ -24,6 +24,13 @@ export const CHUNK_SIZE = 65_536;
24
24
  export const MAX_TX_BLOB_BYTES = 1 * 1024 * 1024;
25
25
  export const MAX_TX_LOGICAL_ROWS = 256;
26
26
  export const MAX_TX_SQL_EXECS = 64;
27
+ /**
28
+ * Bound parameters per SQL statement on Durable Objects SQLite. Measured
29
+ * 2026-09-21 on workerd: 100 bind, 101 fail as `too many SQL variables`
30
+ * (a 9-row insert of 12 columns fails, 8 rows succeed). Every IN-list and
31
+ * multi-row VALUES statement is sized from this.
32
+ */
33
+ export const SQL_MAX_BOUND_PARAMETERS = 100;
27
34
  // ── SQLite storage walls ────────────────────────────────────────────────
28
35
  /**
29
36
  * Storage per SQLite-backed Durable Object: 10 decimal GB documented
package/dist/w7-frame.js CHANGED
@@ -77,7 +77,7 @@ export async function decodeWriteBatchStream(stream, options = {}) {
77
77
  catch {
78
78
  throw new Error('w7-frame: stream must be a byte-oriented ReadableStream');
79
79
  }
80
- const buffer = new ExactByteReader(reader);
80
+ const buffer = new ExactByteReader(reader, options.signal);
81
81
  let handedOff = false;
82
82
  try {
83
83
  throwIfAborted(options.signal);
@@ -796,9 +796,24 @@ async function cancelReader(reader, reason) {
796
796
  }
797
797
  class ExactByteReader {
798
798
  reader;
799
+ signal;
799
800
  done = false;
800
- constructor(reader) {
801
+ constructor(reader, signal) {
801
802
  this.reader = reader;
803
+ this.signal = signal;
804
+ }
805
+ async read(read, cancel) {
806
+ throwIfAborted(this.signal);
807
+ const abort = () => { void cancel().catch(() => { }); };
808
+ this.signal?.addEventListener('abort', abort, { once: true });
809
+ try {
810
+ const result = await read();
811
+ throwIfAborted(this.signal);
812
+ return result;
813
+ }
814
+ finally {
815
+ this.signal?.removeEventListener('abort', abort);
816
+ }
802
817
  }
803
818
  async readExact(length, label) {
804
819
  if (length === 0)
@@ -809,7 +824,7 @@ class ExactByteReader {
809
824
  if (this.done) {
810
825
  throw new Error(`w7-frame: stream ended ${offset} bytes into expected ${length}-byte ${label}`);
811
826
  }
812
- const next = await this.reader.read(new Uint8Array(length - offset));
827
+ const next = await this.read(() => this.reader.read(new Uint8Array(length - offset)), () => this.reader.cancel(this.signal?.reason));
813
828
  if (next.done)
814
829
  this.done = true;
815
830
  else if (next.value.byteLength > 0) {
@@ -825,7 +840,7 @@ class ExactByteReader {
825
840
  this.reader.releaseLock();
826
841
  const reader = stream.getReader();
827
842
  try {
828
- const next = await reader.read();
843
+ const next = await this.read(() => reader.read(), () => reader.cancel(this.signal?.reason));
829
844
  if (!next.done && next.value.byteLength > 0) {
830
845
  await reader.cancel(new Error('w7-frame: trailing bytes after batch-end'));
831
846
  throw new Error('w7-frame: trailing bytes after batch-end');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nimbus-sh/platform",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "The measured Cloudflare platform truths Nimbus is built on — 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
@@ -28,6 +28,14 @@ export const MAX_TX_BLOB_BYTES = 1 * 1024 * 1024;
28
28
  export const MAX_TX_LOGICAL_ROWS = 256;
29
29
  export const MAX_TX_SQL_EXECS = 64;
30
30
 
31
+ /**
32
+ * Bound parameters per SQL statement on Durable Objects SQLite. Measured
33
+ * 2026-09-21 on workerd: 100 bind, 101 fail as `too many SQL variables`
34
+ * (a 9-row insert of 12 columns fails, 8 rows succeed). Every IN-list and
35
+ * multi-row VALUES statement is sized from this.
36
+ */
37
+ export const SQL_MAX_BOUND_PARAMETERS = 100;
38
+
31
39
  // ── SQLite storage walls ────────────────────────────────────────────────
32
40
 
33
41
  /**
package/src/w7-frame.ts CHANGED
@@ -220,7 +220,7 @@ export async function decodeWriteBatchStream(
220
220
  } catch {
221
221
  throw new Error('w7-frame: stream must be a byte-oriented ReadableStream');
222
222
  }
223
- const buffer = new ExactByteReader(reader);
223
+ const buffer = new ExactByteReader(reader, options.signal);
224
224
  let handedOff = false;
225
225
  try {
226
226
  throwIfAborted(options.signal);
@@ -1006,7 +1006,20 @@ async function cancelReader(
1006
1006
  class ExactByteReader {
1007
1007
  private done = false;
1008
1008
 
1009
- constructor(private readonly reader: ReadableStreamBYOBReader) {}
1009
+ constructor(private readonly reader: ReadableStreamBYOBReader, private readonly signal?: AbortSignal) {}
1010
+
1011
+ private async read<T>(read: () => Promise<T>, cancel: () => Promise<void>): Promise<T> {
1012
+ throwIfAborted(this.signal);
1013
+ const abort = () => { void cancel().catch(() => {}); };
1014
+ this.signal?.addEventListener('abort', abort, { once: true });
1015
+ try {
1016
+ const result = await read();
1017
+ throwIfAborted(this.signal);
1018
+ return result;
1019
+ } finally {
1020
+ this.signal?.removeEventListener('abort', abort);
1021
+ }
1022
+ }
1010
1023
 
1011
1024
  async readExact(length: number, label: string): Promise<Uint8Array> {
1012
1025
  if (length === 0) return new Uint8Array(0);
@@ -1018,7 +1031,10 @@ class ExactByteReader {
1018
1031
  `w7-frame: stream ended ${offset} bytes into expected ${length}-byte ${label}`,
1019
1032
  );
1020
1033
  }
1021
- const next = await this.reader.read(new Uint8Array(length - offset));
1034
+ const next = await this.read(
1035
+ () => this.reader.read(new Uint8Array(length - offset)),
1036
+ () => this.reader.cancel(this.signal?.reason),
1037
+ );
1022
1038
  if (next.done) this.done = true;
1023
1039
  else if (next.value.byteLength > 0) {
1024
1040
  output.set(next.value, offset);
@@ -1033,7 +1049,7 @@ class ExactByteReader {
1033
1049
  this.reader.releaseLock();
1034
1050
  const reader = stream.getReader();
1035
1051
  try {
1036
- const next = await reader.read();
1052
+ const next = await this.read(() => reader.read(), () => reader.cancel(this.signal?.reason));
1037
1053
  if (!next.done && next.value.byteLength > 0) {
1038
1054
  await reader.cancel(new Error('w7-frame: trailing bytes after batch-end'));
1039
1055
  throw new Error('w7-frame: trailing bytes after batch-end');