@sproutboat/runtime 0.19.1 → 0.19.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sproutboat/runtime
2
2
 
3
+ ## 0.19.2
4
+
5
+ ### Patch Changes
6
+
7
+ - bc3fd25: `Response.body` and `Request.body` are `ReadableStream`s only from compatibility date `2026-10-21`. 0.19.0 changed this for every app, which broke handlers that read `request.body` as a string, such as `JSON.parse(request.body)` in the CLI's own D1 example. An app with an earlier `compatibility_date` keeps the raw body, as before. To opt in, move `compatibility_date` to `2026-10-21` or later and rebuild.
8
+
3
9
  ## 0.19.1
4
10
 
5
11
  ### Patch Changes
package/WEB_STREAMS.md CHANGED
@@ -20,8 +20,10 @@ runtime links no zlib. Compression writes one fixed-Huffman block per chunk as i
20
20
  (close to zlib on text: 252 bytes against 221 for 22.5 KB); decompression inflates all
21
21
  block types once the input ends and checks the CRC-32 or Adler-32. Response and Request
22
22
  bodies that are ReadableStreams are read by text(), json(), arrayBuffer() and blob(), and
23
- their chunks must be bytes, as in workerd. `body` is a ReadableStream for every body type,
24
- as in Fetch: a stream body itself, otherwise a stream made once over the bytes.
23
+ their chunks must be bytes, as in workerd. From compatibility date 2026-10-21, `body` is a
24
+ ReadableStream for every body type, as in Fetch: a stream body itself, otherwise a stream made
25
+ once over the bytes. Before that date it is the value as given, as apps written for earlier
26
+ releases read it (`JSON.parse(request.body)`).
25
27
  BYOB buffer detachment requires transfer support from the underlying engine;
26
28
  the polyfill cannot supply that engine primitive. Full Web Platform Tests
27
29
  conformance has not been established for Porffor.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sproutboat/runtime",
3
- "version": "0.19.1",
3
+ "version": "0.19.2",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -92,7 +92,7 @@ try {
92
92
  const prelude = core.replace(TRANSPORT_MARKER, broker);
93
93
  const generated = join(workdir, "bodies.generated.js");
94
94
  const binary = join(workdir, "bodies-native");
95
- await writeFile(generated, wrapNativeFetchHandler(handler, prelude, undefined, undefined, undefined, "2026-10-01"));
95
+ await writeFile(generated, wrapNativeFetchHandler(handler, prelude, undefined, undefined, undefined, "2026-10-21"));
96
96
  await rm(binary, { force: true });
97
97
 
98
98
  const compile = Bun.spawn([node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"], {
@@ -19,8 +19,9 @@ const CASES = [
19
19
  `new Request("http://a.test/x", { method: "post" }).method`,
20
20
  ];
21
21
  const handler = `export default {async fetch(request) {
22
- // The incoming request: its body is a ReadableStream, and text() still reads it.
23
- if (request.method === "POST") { const viaStream = await new Response(request.body).text(); return new Response((request.body instanceof ReadableStream) + ":" + viaStream); }
22
+ // Before compatibility date 2026-10-21 (this build has the baseline date) the incoming body is
23
+ // the raw value, as apps written against earlier releases read it; text() decodes it.
24
+ if (request.method === "POST") return new Response((request.body instanceof ReadableStream) + ":" + (typeof request.body) + ":" + (await request.text()));
24
25
  const cases = [
25
26
  ${CASES.map((c) => ` () => (${c}),`).join("\n")}
26
27
  ];
@@ -94,8 +95,8 @@ try {
94
95
  const diffs = CASES.flatMap((c, i) => (got[i] === want[i] ? [] : [`${c}\n want ${JSON.stringify(want[i])}\n got ${JSON.stringify(got[i])}`]));
95
96
  assert.deepEqual(diffs, [], `Request copies differ from Bun in ${diffs.length} of ${CASES.length} cases:\n${diffs.join("\n")}`);
96
97
  const posted = await (await fetch(`http://127.0.0.1:${port}/`, { method: "POST", body: "posted é" })).text();
97
- assert.equal(posted, "true:posted é", "the incoming request body is a stream and text() reads it");
98
- console.log(`Native Request copies match Bun in all ${CASES.length} cases; the incoming body is a stream`);
98
+ assert.equal(posted, "false:string:posted é", "before 2026-10-21 the incoming body stays the raw value");
99
+ console.log(`Native Request copies match Bun in all ${CASES.length} cases; an app before 2026-10-21 keeps its raw body`);
99
100
  } finally {
100
101
  if (server) {
101
102
  server.kill(9);
@@ -23,7 +23,7 @@ export default {
23
23
  if (request.method === "POST") {
24
24
  env.UPLOADS.put("upload", request.body);
25
25
  await env.KV.put("upload", request.body);
26
- return Response.json({ r2: env.UPLOADS.get("upload").text(), kv: await env.KV.get("upload") });
26
+ return Response.json({ r2: env.UPLOADS.get("upload").text(), kv: await env.KV.get("upload"), stream: await new Response(request.body).text() });
27
27
  }
28
28
  await env.KV.put("k", ${JSON.stringify(text)});
29
29
  const kv = await env.KV.get("k");
@@ -65,7 +65,7 @@ try {
65
65
  assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
66
66
  const generated = join(workdir, "utf8.generated.js");
67
67
  const binary = join(workdir, "utf8-native");
68
- await writeFile(generated, wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, transport), {}, bindings));
68
+ await writeFile(generated, wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, transport), {}, bindings, undefined, "2026-10-21"));
69
69
 
70
70
  const compile = Bun.spawn([node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"], {
71
71
  cwd: workdir,
@@ -121,7 +121,7 @@ try {
121
121
  assert.match(body.error, /tabellà/);
122
122
  assert.equal(body.url, "shadowed");
123
123
  const stored = await (await fetch(`http://127.0.0.1:${port}/`, { method: "POST", body: "uploaded é" })).json();
124
- assert.deepEqual(stored, { r2: "uploaded é", kv: "uploaded é" }, "put(key, request.body) stores the request body");
124
+ assert.deepEqual(stored, { r2: "uploaded é", kv: "uploaded é", stream: "uploaded é" }, "put(key, request.body) stores the request body, and body reads as UTF-8");
125
125
  console.log("Non-ASCII KV, D1 and error text round-trip through the broker; a handler-level URL stays scoped; put(key, request.body) stores the body");
126
126
  } finally {
127
127
  if (server) {