@sproutboat/runtime 0.42.1 → 0.43.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/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/native-fetch-prelude.js +186 -24
- package/src/transport-embedded.js +35 -6
- package/test/native-base64.ts +12 -26
- package/test/native-bodies.ts +19 -26
- package/test/native-byte-text.ts +3 -19
- package/test/native-compile.ts +163 -0
- package/test/native-cpu-requests.ts +3 -20
- package/test/native-cpu-stamp.ts +3 -20
- package/test/native-crypto.ts +3 -22
- package/test/native-domexception.ts +3 -21
- package/test/native-errors.ts +12 -24
- package/test/native-events.ts +21 -25
- package/test/native-fetch-request.ts +11 -20
- package/test/native-getrandomvalues.ts +3 -21
- package/test/native-headers.ts +3 -21
- package/test/native-http.ts +10 -20
- package/test/native-iterators.ts +24 -27
- package/test/native-json-strings.ts +3 -21
- package/test/native-json.ts +15 -25
- package/test/native-jwt.ts +3 -22
- package/test/native-model-resolver.ts +5 -24
- package/test/native-raw-body.ts +7 -53
- package/test/native-request-log.ts +197 -0
- package/test/native-request-streaming.ts +3 -19
- package/test/native-request.ts +24 -26
- package/test/native-response-defaults.ts +4 -22
- package/test/native-service-bindings.ts +53 -27
- package/test/native-sockets-broker.ts +65 -20
- package/test/native-sockets-starttls.ts +404 -0
- package/test/native-streaming.ts +4 -22
- package/test/native-streams.ts +22 -25
- package/test/native-subtle.ts +3 -21
- package/test/native-textdecoder-encodings.ts +3 -21
- package/test/native-timers.ts +4 -22
- package/test/native-unhandled-rejection.ts +3 -20
- package/test/native-url.ts +15 -25
- package/test/native-utf8.ts +15 -21
- package/test/native-waituntil.ts +7 -23
- package/test/native-web-apis.ts +3 -22
- package/test/native-websockets.ts +3 -19
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
6
6
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
7
7
|
|
|
8
8
|
// A promise that rejects with nobody waiting on it (a binding call that failed and was never
|
|
@@ -50,9 +50,6 @@ for (const date of ["2026-09-28", "2026-10-24"]) {
|
|
|
50
50
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-unhandled-"));
|
|
51
51
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
52
52
|
try {
|
|
53
|
-
const porffor = await ensurePorffor();
|
|
54
|
-
const node = Bun.which("node");
|
|
55
|
-
if (!node) throw new Error("native unhandled rejection test needs node on PATH");
|
|
56
53
|
const [core, broker] = await Promise.all([
|
|
57
54
|
readFile(preludePath, "utf8"),
|
|
58
55
|
readFile(transportPath("broker"), "utf8"),
|
|
@@ -64,21 +61,7 @@ for (const date of ["2026-09-28", "2026-10-24"]) {
|
|
|
64
61
|
generated,
|
|
65
62
|
wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, broker), undefined, undefined, undefined, date),
|
|
66
63
|
);
|
|
67
|
-
|
|
68
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
69
|
-
{
|
|
70
|
-
cwd: workdir,
|
|
71
|
-
env: process.env,
|
|
72
|
-
stdout: "pipe",
|
|
73
|
-
stderr: "pipe",
|
|
74
|
-
},
|
|
75
|
-
);
|
|
76
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
77
|
-
compile.exited,
|
|
78
|
-
new Response(compile.stdout).text(),
|
|
79
|
-
new Response(compile.stderr).text(),
|
|
80
|
-
]);
|
|
81
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
64
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
82
65
|
|
|
83
66
|
const port = freePort();
|
|
84
67
|
server = Bun.spawn([binary], {
|
package/test/native-url.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
6
6
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
7
7
|
|
|
8
8
|
// URL as WHATWG defines it (Bun's URL is the reference): base URLs, setters on every
|
|
@@ -84,14 +84,7 @@ function freePort(): number {
|
|
|
84
84
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-url-"));
|
|
85
85
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
86
86
|
try {
|
|
87
|
-
const
|
|
88
|
-
const node = Bun.which("node");
|
|
89
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
90
|
-
|
|
91
|
-
const [core, broker] = await Promise.all([
|
|
92
|
-
readFile(preludePath, "utf8"),
|
|
93
|
-
readFile(transportPath("broker"), "utf8"),
|
|
94
|
-
]);
|
|
87
|
+
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
95
88
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
96
89
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
97
90
|
const generated = join(workdir, "url.generated.js");
|
|
@@ -99,18 +92,7 @@ try {
|
|
|
99
92
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
100
93
|
await rm(binary, { force: true });
|
|
101
94
|
|
|
102
|
-
|
|
103
|
-
cwd: workdir,
|
|
104
|
-
env: process.env,
|
|
105
|
-
stdout: "pipe",
|
|
106
|
-
stderr: "pipe",
|
|
107
|
-
});
|
|
108
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
109
|
-
compile.exited,
|
|
110
|
-
new Response(compile.stdout).text(),
|
|
111
|
-
new Response(compile.stderr).text(),
|
|
112
|
-
]);
|
|
113
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
95
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
114
96
|
|
|
115
97
|
const port = freePort();
|
|
116
98
|
server = Bun.spawn([binary], {
|
|
@@ -133,9 +115,17 @@ try {
|
|
|
133
115
|
// SAFETY: the handler above is the only producer of this body: a JSON array with one
|
|
134
116
|
// string per case; the comparison below reports any entry that differs.
|
|
135
117
|
const got = JSON.parse(await (await fetch(`http://127.0.0.1:${port}/`)).text()) as string[];
|
|
136
|
-
const diffs = CASES.flatMap((c, i) =>
|
|
137
|
-
|
|
138
|
-
|
|
118
|
+
const diffs = CASES.flatMap((c, i) =>
|
|
119
|
+
got[i] === want[i] ? [] : [`${c}\n want ${JSON.stringify(want[i])}\n got ${JSON.stringify(got[i])}`],
|
|
120
|
+
);
|
|
121
|
+
assert.deepEqual(
|
|
122
|
+
diffs,
|
|
123
|
+
[],
|
|
124
|
+
`URL differs from WHATWG in ${diffs.length} of ${CASES.length} cases:\n${diffs.join("\n")}`,
|
|
125
|
+
);
|
|
126
|
+
console.log(
|
|
127
|
+
`Native URL matches WHATWG URL in all ${CASES.length} cases: base URLs, setters, hash, ports, dot segments, encoding, searchParams`,
|
|
128
|
+
);
|
|
139
129
|
} finally {
|
|
140
130
|
if (server) {
|
|
141
131
|
server.kill(9);
|
package/test/native-utf8.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
6
6
|
import { createBroker, listen } from "../../wire/src/broker";
|
|
7
7
|
import { EMPTY_BINDINGS, preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
8
8
|
|
|
@@ -54,10 +54,6 @@ const broker = createBroker({
|
|
|
54
54
|
const brokerServer = listen(broker, "127.0.0.1", 0);
|
|
55
55
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
56
56
|
try {
|
|
57
|
-
const porffor = await ensurePorffor({ cacheRoot: workdir });
|
|
58
|
-
const node = Bun.which("node");
|
|
59
|
-
if (!node) throw new Error("native UTF-8 test needs node on PATH");
|
|
60
|
-
|
|
61
57
|
const [core, transport] = await Promise.all([
|
|
62
58
|
readFile(preludePath, "utf8"),
|
|
63
59
|
readFile(transportPath("broker"), "utf8"),
|
|
@@ -65,20 +61,12 @@ try {
|
|
|
65
61
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
66
62
|
const generated = join(workdir, "utf8.generated.js");
|
|
67
63
|
const binary = join(workdir, "utf8-native");
|
|
68
|
-
await writeFile(
|
|
64
|
+
await writeFile(
|
|
65
|
+
generated,
|
|
66
|
+
wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, transport), {}, bindings, undefined, "2026-10-21"),
|
|
67
|
+
);
|
|
69
68
|
|
|
70
|
-
|
|
71
|
-
cwd: workdir,
|
|
72
|
-
env: process.env,
|
|
73
|
-
stdout: "pipe",
|
|
74
|
-
stderr: "pipe",
|
|
75
|
-
});
|
|
76
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
77
|
-
compile.exited,
|
|
78
|
-
new Response(compile.stdout).text(),
|
|
79
|
-
new Response(compile.stderr).text(),
|
|
80
|
-
]);
|
|
81
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
69
|
+
await compileNative({ generated, binary, dir: workdir, cacheRoot: workdir });
|
|
82
70
|
|
|
83
71
|
const port = freePort();
|
|
84
72
|
server = Bun.spawn([binary], {
|
|
@@ -121,8 +109,14 @@ try {
|
|
|
121
109
|
assert.match(body.error, /tabellà/);
|
|
122
110
|
assert.equal(body.url, "shadowed");
|
|
123
111
|
const stored = await (await fetch(`http://127.0.0.1:${port}/`, { method: "POST", body: "uploaded é" })).json();
|
|
124
|
-
assert.deepEqual(
|
|
125
|
-
|
|
112
|
+
assert.deepEqual(
|
|
113
|
+
stored,
|
|
114
|
+
{ r2: "uploaded é", kv: "uploaded é", stream: "uploaded é" },
|
|
115
|
+
"put(key, request.body) stores the request body, and body reads as UTF-8",
|
|
116
|
+
);
|
|
117
|
+
console.log(
|
|
118
|
+
"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",
|
|
119
|
+
);
|
|
126
120
|
} finally {
|
|
127
121
|
if (server) {
|
|
128
122
|
server.kill(9);
|
package/test/native-waituntil.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
6
6
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
7
7
|
|
|
8
8
|
// ctx.waitUntil work runs after the response, as in workerd: the response does not wait
|
|
@@ -32,14 +32,7 @@ function freePort(): number {
|
|
|
32
32
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-waituntil-"));
|
|
33
33
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
34
34
|
try {
|
|
35
|
-
const
|
|
36
|
-
const node = Bun.which("node");
|
|
37
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
38
|
-
|
|
39
|
-
const [core, broker] = await Promise.all([
|
|
40
|
-
readFile(preludePath, "utf8"),
|
|
41
|
-
readFile(transportPath("broker"), "utf8"),
|
|
42
|
-
]);
|
|
35
|
+
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
43
36
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
44
37
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
45
38
|
const generated = join(workdir, "waituntil.generated.js");
|
|
@@ -47,18 +40,7 @@ try {
|
|
|
47
40
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude, undefined, undefined, undefined, "2026-10-01"));
|
|
48
41
|
await rm(binary, { force: true });
|
|
49
42
|
|
|
50
|
-
|
|
51
|
-
cwd: workdir,
|
|
52
|
-
env: process.env,
|
|
53
|
-
stdout: "pipe",
|
|
54
|
-
stderr: "pipe",
|
|
55
|
-
});
|
|
56
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
57
|
-
compile.exited,
|
|
58
|
-
new Response(compile.stdout).text(),
|
|
59
|
-
new Response(compile.stderr).text(),
|
|
60
|
-
]);
|
|
61
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
43
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
62
44
|
|
|
63
45
|
const port = freePort();
|
|
64
46
|
server = Bun.spawn([binary], {
|
|
@@ -97,7 +79,9 @@ try {
|
|
|
97
79
|
assert.equal(await cron.text(), "");
|
|
98
80
|
assert.equal(await (await fetch(`http://127.0.0.1:${port}/cron`)).text(), "*/5 * * * *");
|
|
99
81
|
assert.equal(server.exitCode, null, "the server exited after a scheduled trigger");
|
|
100
|
-
console.log(
|
|
82
|
+
console.log(
|
|
83
|
+
`Native waitUntil runs after the response (${Math.round(elapsed)} ms) and completes; scheduled() answers 204`,
|
|
84
|
+
);
|
|
101
85
|
} finally {
|
|
102
86
|
if (server) {
|
|
103
87
|
server.kill(9);
|
package/test/native-web-apis.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
6
|
-
import { bearsslEnv } from "./bearssl";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
7
6
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
8
7
|
|
|
9
8
|
// Web API behaviour the W2 conformance suite found wrong, compared with Bun: Headers
|
|
@@ -59,10 +58,6 @@ function freePort(): number {
|
|
|
59
58
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-web-apis-"));
|
|
60
59
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
61
60
|
try {
|
|
62
|
-
const porffor = await ensurePorffor();
|
|
63
|
-
const node = Bun.which("node");
|
|
64
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
65
|
-
|
|
66
61
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
67
62
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
68
63
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -71,21 +66,7 @@ try {
|
|
|
71
66
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
72
67
|
await rm(binary, { force: true });
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
76
|
-
{
|
|
77
|
-
cwd: workdir,
|
|
78
|
-
env: { ...process.env, ...(await bearsslEnv()) },
|
|
79
|
-
stdout: "pipe",
|
|
80
|
-
stderr: "pipe",
|
|
81
|
-
},
|
|
82
|
-
);
|
|
83
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
84
|
-
compile.exited,
|
|
85
|
-
new Response(compile.stdout).text(),
|
|
86
|
-
new Response(compile.stderr).text(),
|
|
87
|
-
]);
|
|
88
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
69
|
+
await compileNative({ generated, binary, dir: workdir, bearssl: true });
|
|
89
70
|
|
|
90
71
|
const port = freePort();
|
|
91
72
|
server = Bun.spawn([binary], {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
|
-
import { join
|
|
5
|
-
import {
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { compileNative } from "./native-compile";
|
|
6
6
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
7
7
|
|
|
8
8
|
// WebSockets from compatibility date 2026-10-30: a WebSocketPair whose ends both stay in
|
|
@@ -105,9 +105,6 @@ function freePort(): number {
|
|
|
105
105
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-websockets-"));
|
|
106
106
|
const servers: ReturnType<typeof Bun.spawn>[] = [];
|
|
107
107
|
try {
|
|
108
|
-
const porffor = await ensurePorffor();
|
|
109
|
-
const node = Bun.which("node");
|
|
110
|
-
if (!node) throw new Error("native WebSocket test needs node on PATH");
|
|
111
108
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
112
109
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
113
110
|
const start = async (date: string) => {
|
|
@@ -117,20 +114,7 @@ try {
|
|
|
117
114
|
generated,
|
|
118
115
|
wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, broker), {}, undefined, undefined, date),
|
|
119
116
|
);
|
|
120
|
-
|
|
121
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
122
|
-
{
|
|
123
|
-
cwd: workdir,
|
|
124
|
-
stdout: "pipe",
|
|
125
|
-
stderr: "pipe",
|
|
126
|
-
},
|
|
127
|
-
);
|
|
128
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
129
|
-
compile.exited,
|
|
130
|
-
new Response(compile.stdout).text(),
|
|
131
|
-
new Response(compile.stderr).text(),
|
|
132
|
-
]);
|
|
133
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
117
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
134
118
|
const port = freePort();
|
|
135
119
|
const server = Bun.spawn([binary], {
|
|
136
120
|
cwd: workdir,
|