@sproutboat/runtime 0.42.2 → 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 +6 -0
- package/package.json +1 -1
- package/src/native-fetch-prelude.js +137 -14
- 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 +3 -20
- 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
package/test/native-cpu-stamp.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
|
// The x-sb-cpu-ms stamp is added to the handler's own Response (it used to build a second one),
|
|
@@ -52,29 +52,12 @@ async function start(binary: string, env: Record<string, string>): Promise<numbe
|
|
|
52
52
|
throw new Error("compiled handler did not start");
|
|
53
53
|
}
|
|
54
54
|
try {
|
|
55
|
-
const porffor = await ensurePorffor();
|
|
56
|
-
const node = Bun.which("node");
|
|
57
|
-
if (!node) throw new Error("native cpu stamp test needs node on PATH");
|
|
58
55
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
59
56
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
60
57
|
const generated = join(workdir, "stamp.generated.js");
|
|
61
58
|
const binary = join(workdir, "stamp-native");
|
|
62
59
|
await writeFile(generated, wrapNativeFetchHandler(handler, core.replace(TRANSPORT_MARKER, broker)));
|
|
63
|
-
|
|
64
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
65
|
-
{
|
|
66
|
-
cwd: workdir,
|
|
67
|
-
env: process.env,
|
|
68
|
-
stdout: "pipe",
|
|
69
|
-
stderr: "pipe",
|
|
70
|
-
},
|
|
71
|
-
);
|
|
72
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
73
|
-
compile.exited,
|
|
74
|
-
new Response(compile.stdout).text(),
|
|
75
|
-
new Response(compile.stderr).text(),
|
|
76
|
-
]);
|
|
77
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
60
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
78
61
|
|
|
79
62
|
const port = await start(binary, {});
|
|
80
63
|
const get = (path: string, headers: Record<string, string> = {}, p = port) =>
|
package/test/native-crypto.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
|
// These values come from Bun WebCrypto and node:crypto, not from the runtime
|
|
@@ -68,10 +67,6 @@ function freePort(): number {
|
|
|
68
67
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-crypto-"));
|
|
69
68
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
70
69
|
try {
|
|
71
|
-
const porffor = await ensurePorffor({ cacheRoot: workdir });
|
|
72
|
-
const node = Bun.which("node");
|
|
73
|
-
if (!node) throw new Error("native crypto test needs node on PATH");
|
|
74
|
-
|
|
75
70
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
76
71
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
77
72
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -85,21 +80,7 @@ try {
|
|
|
85
80
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
86
81
|
await rm(binary, { force: true });
|
|
87
82
|
|
|
88
|
-
|
|
89
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
90
|
-
{
|
|
91
|
-
cwd: workdir,
|
|
92
|
-
env: { ...process.env, ...(await bearsslEnv()) },
|
|
93
|
-
stdout: "pipe",
|
|
94
|
-
stderr: "pipe",
|
|
95
|
-
},
|
|
96
|
-
);
|
|
97
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
98
|
-
compile.exited,
|
|
99
|
-
new Response(compile.stdout).text(),
|
|
100
|
-
new Response(compile.stderr).text(),
|
|
101
|
-
]);
|
|
102
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
83
|
+
await compileNative({ generated, binary, dir: workdir, cacheRoot: workdir, bearssl: true });
|
|
103
84
|
|
|
104
85
|
const port = freePort();
|
|
105
86
|
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
|
// DOMException in a compiled handler, compared with Bun. Porffor ships a stub global that
|
|
@@ -47,10 +47,6 @@ function freePort(): number {
|
|
|
47
47
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-domexception-"));
|
|
48
48
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
49
49
|
try {
|
|
50
|
-
const porffor = await ensurePorffor();
|
|
51
|
-
const node = Bun.which("node");
|
|
52
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
53
|
-
|
|
54
50
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
55
51
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
56
52
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -59,21 +55,7 @@ try {
|
|
|
59
55
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
60
56
|
await rm(binary, { force: true });
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
64
|
-
{
|
|
65
|
-
cwd: workdir,
|
|
66
|
-
env: process.env,
|
|
67
|
-
stdout: "pipe",
|
|
68
|
-
stderr: "pipe",
|
|
69
|
-
},
|
|
70
|
-
);
|
|
71
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
72
|
-
compile.exited,
|
|
73
|
-
new Response(compile.stdout).text(),
|
|
74
|
-
new Response(compile.stderr).text(),
|
|
75
|
-
]);
|
|
76
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
58
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
77
59
|
|
|
78
60
|
const port = freePort();
|
|
79
61
|
server = Bun.spawn([binary], {
|
package/test/native-errors.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
|
// Error.stack as V8 starts it (Bun is the reference for the first line): Porffor keeps no
|
|
@@ -40,14 +40,7 @@ function freePort(): number {
|
|
|
40
40
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-errors-"));
|
|
41
41
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
42
42
|
try {
|
|
43
|
-
const
|
|
44
|
-
const node = Bun.which("node");
|
|
45
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
46
|
-
|
|
47
|
-
const [core, broker] = await Promise.all([
|
|
48
|
-
readFile(preludePath, "utf8"),
|
|
49
|
-
readFile(transportPath("broker"), "utf8"),
|
|
50
|
-
]);
|
|
43
|
+
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
51
44
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
52
45
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
53
46
|
const generated = join(workdir, "errors.generated.js");
|
|
@@ -55,18 +48,7 @@ try {
|
|
|
55
48
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
56
49
|
await rm(binary, { force: true });
|
|
57
50
|
|
|
58
|
-
|
|
59
|
-
cwd: workdir,
|
|
60
|
-
env: process.env,
|
|
61
|
-
stdout: "pipe",
|
|
62
|
-
stderr: "pipe",
|
|
63
|
-
});
|
|
64
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
65
|
-
compile.exited,
|
|
66
|
-
new Response(compile.stdout).text(),
|
|
67
|
-
new Response(compile.stderr).text(),
|
|
68
|
-
]);
|
|
69
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
51
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
70
52
|
|
|
71
53
|
const port = freePort();
|
|
72
54
|
server = Bun.spawn([binary], {
|
|
@@ -89,8 +71,14 @@ try {
|
|
|
89
71
|
// SAFETY: the handler above is the only producer of this body: a JSON array with one
|
|
90
72
|
// string per case; the comparison below reports any entry that differs.
|
|
91
73
|
const got = JSON.parse(await (await fetch(`http://127.0.0.1:${port}/`)).text()) as string[];
|
|
92
|
-
const diffs = CASES.flatMap((c, i) =>
|
|
93
|
-
|
|
74
|
+
const diffs = CASES.flatMap((c, i) =>
|
|
75
|
+
got[i] === want[i] ? [] : [`${c}\n want ${JSON.stringify(want[i])}\n got ${JSON.stringify(got[i])}`],
|
|
76
|
+
);
|
|
77
|
+
assert.deepEqual(
|
|
78
|
+
diffs,
|
|
79
|
+
[],
|
|
80
|
+
`Error.stack differs from V8 in ${diffs.length} of ${CASES.length} cases:\n${diffs.join("\n")}`,
|
|
81
|
+
);
|
|
94
82
|
console.log(`Native Error.stack starts like V8 in all ${CASES.length} cases`);
|
|
95
83
|
} finally {
|
|
96
84
|
if (server) {
|
package/test/native-events.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
|
// structuredClone, Event/EventTarget and AbortController in a compiled handler,
|
|
@@ -29,7 +29,15 @@ ${CASES.map((c) => ` () => (${c}),`).join("\n")}
|
|
|
29
29
|
}
|
|
30
30
|
return new Response(JSON.stringify(out));
|
|
31
31
|
}};`;
|
|
32
|
-
const want = await Promise.all(
|
|
32
|
+
const want = await Promise.all(
|
|
33
|
+
CASES.map(async (c) => {
|
|
34
|
+
try {
|
|
35
|
+
return String(await new Function("return " + c)());
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return "THROWS " + (e instanceof Error ? e.message : String(e));
|
|
38
|
+
}
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
33
41
|
|
|
34
42
|
function freePort(): number {
|
|
35
43
|
const listener = Bun.listen({ hostname: "127.0.0.1", port: 0, socket: { data() {} } });
|
|
@@ -41,14 +49,7 @@ function freePort(): number {
|
|
|
41
49
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-events-"));
|
|
42
50
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
43
51
|
try {
|
|
44
|
-
const
|
|
45
|
-
const node = Bun.which("node");
|
|
46
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
47
|
-
|
|
48
|
-
const [core, broker] = await Promise.all([
|
|
49
|
-
readFile(preludePath, "utf8"),
|
|
50
|
-
readFile(transportPath("broker"), "utf8"),
|
|
51
|
-
]);
|
|
52
|
+
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
52
53
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
53
54
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
54
55
|
const generated = join(workdir, "events.generated.js");
|
|
@@ -56,18 +57,7 @@ try {
|
|
|
56
57
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
57
58
|
await rm(binary, { force: true });
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
cwd: workdir,
|
|
61
|
-
env: process.env,
|
|
62
|
-
stdout: "pipe",
|
|
63
|
-
stderr: "pipe",
|
|
64
|
-
});
|
|
65
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
66
|
-
compile.exited,
|
|
67
|
-
new Response(compile.stdout).text(),
|
|
68
|
-
new Response(compile.stderr).text(),
|
|
69
|
-
]);
|
|
70
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
60
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
71
61
|
|
|
72
62
|
const port = freePort();
|
|
73
63
|
server = Bun.spawn([binary], {
|
|
@@ -90,8 +80,14 @@ try {
|
|
|
90
80
|
// SAFETY: the handler above is the only producer of this body: a JSON array with one
|
|
91
81
|
// string per case; the comparison below reports any entry that differs.
|
|
92
82
|
const got = JSON.parse(await (await fetch(`http://127.0.0.1:${port}/`)).text()) as string[];
|
|
93
|
-
const diffs = CASES.flatMap((c, i) =>
|
|
94
|
-
|
|
83
|
+
const diffs = CASES.flatMap((c, i) =>
|
|
84
|
+
got[i] === want[i] ? [] : [`${c}\n want ${JSON.stringify(want[i])}\n got ${JSON.stringify(got[i])}`],
|
|
85
|
+
);
|
|
86
|
+
assert.deepEqual(
|
|
87
|
+
diffs,
|
|
88
|
+
[],
|
|
89
|
+
`Event, abort and clone results differ from Bun in ${diffs.length} of ${CASES.length} cases:\n${diffs.join("\n")}`,
|
|
90
|
+
);
|
|
95
91
|
console.log(`Native events, abort and structuredClone match Bun in all ${CASES.length} cases`);
|
|
96
92
|
} finally {
|
|
97
93
|
if (server) {
|
|
@@ -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
|
|
|
@@ -124,21 +124,18 @@ const brokerServer = listen(broker, "127.0.0.1", 0);
|
|
|
124
124
|
const servers: ReturnType<typeof Bun.spawn>[] = [];
|
|
125
125
|
|
|
126
126
|
// Compiles the handler at `date` and starts it; resolves to a GET helper for it.
|
|
127
|
-
async function start(
|
|
127
|
+
async function start(source: string, date: string) {
|
|
128
128
|
const port = freePort();
|
|
129
129
|
const generated = join(workdir, `fetch-request-${date}.generated.js`);
|
|
130
130
|
const binary = join(workdir, `fetch-request-${date}`);
|
|
131
131
|
await writeFile(generated, wrapNativeFetchHandler(handler, source, {}, EMPTY_BINDINGS, undefined, date));
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
);
|
|
140
|
-
const [exitCode, stderr] = await Promise.all([compile.exited, new Response(compile.stderr).text()]);
|
|
141
|
-
assert.equal(exitCode, 0, `Porffor native compile at ${date} failed:\n${stderr}`);
|
|
132
|
+
await compileNative({
|
|
133
|
+
generated,
|
|
134
|
+
binary,
|
|
135
|
+
dir: workdir,
|
|
136
|
+
cacheRoot: workdir,
|
|
137
|
+
failure: `Porffor native compile at ${date} failed`,
|
|
138
|
+
});
|
|
142
139
|
const server = Bun.spawn([binary], {
|
|
143
140
|
cwd: workdir,
|
|
144
141
|
env: {
|
|
@@ -174,19 +171,13 @@ async function start(porffor: string, node: string, source: string, date: string
|
|
|
174
171
|
}
|
|
175
172
|
|
|
176
173
|
try {
|
|
177
|
-
const porffor = await ensurePorffor({ cacheRoot: workdir });
|
|
178
|
-
const node = Bun.which("node");
|
|
179
|
-
if (!node) throw new Error("native fetch-request test needs node on PATH");
|
|
180
174
|
const [core, transport] = await Promise.all([
|
|
181
175
|
readFile(preludePath, "utf8"),
|
|
182
176
|
readFile(transportPath("broker"), "utf8"),
|
|
183
177
|
]);
|
|
184
178
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
185
179
|
const source = core.replace(TRANSPORT_MARKER, transport);
|
|
186
|
-
const [strict, legacy] = await Promise.all([
|
|
187
|
-
start(porffor, node, source, "2026-10-23"),
|
|
188
|
-
start(porffor, node, source, "2026-10-22"),
|
|
189
|
-
]);
|
|
180
|
+
const [strict, legacy] = await Promise.all([start(source, "2026-10-23"), start(source, "2026-10-22")]);
|
|
190
181
|
|
|
191
182
|
const echo = (method: string, from: string | null, type: string | null, body: string) => ({
|
|
192
183
|
method,
|
|
@@ -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
|
// crypto.getRandomValues on wider integer views, in a compiled handler, compared with Bun. It filled only the
|
|
@@ -50,10 +50,6 @@ function freePort(): number {
|
|
|
50
50
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-getrandomvalues-"));
|
|
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 streams test needs node on PATH");
|
|
56
|
-
|
|
57
53
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
58
54
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
59
55
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -62,21 +58,7 @@ try {
|
|
|
62
58
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
63
59
|
await rm(binary, { force: true });
|
|
64
60
|
|
|
65
|
-
|
|
66
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
67
|
-
{
|
|
68
|
-
cwd: workdir,
|
|
69
|
-
env: process.env,
|
|
70
|
-
stdout: "pipe",
|
|
71
|
-
stderr: "pipe",
|
|
72
|
-
},
|
|
73
|
-
);
|
|
74
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
75
|
-
compile.exited,
|
|
76
|
-
new Response(compile.stdout).text(),
|
|
77
|
-
new Response(compile.stderr).text(),
|
|
78
|
-
]);
|
|
79
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
61
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
80
62
|
|
|
81
63
|
const port = freePort();
|
|
82
64
|
server = Bun.spawn([binary], {
|
package/test/native-headers.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
|
// Headers validates a name and trims a value in C before it falls back to the regular expression and
|
|
@@ -54,10 +54,6 @@ function expectedValue(value: string): string {
|
|
|
54
54
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-headers-"));
|
|
55
55
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
56
56
|
try {
|
|
57
|
-
const porffor = await ensurePorffor();
|
|
58
|
-
const node = Bun.which("node");
|
|
59
|
-
if (!node) throw new Error("native headers test needs node on PATH");
|
|
60
|
-
|
|
61
57
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
62
58
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
63
59
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -66,21 +62,7 @@ try {
|
|
|
66
62
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
67
63
|
await rm(binary, { force: true });
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
71
|
-
{
|
|
72
|
-
cwd: workdir,
|
|
73
|
-
env: process.env,
|
|
74
|
-
stdout: "pipe",
|
|
75
|
-
stderr: "pipe",
|
|
76
|
-
},
|
|
77
|
-
);
|
|
78
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
79
|
-
compile.exited,
|
|
80
|
-
new Response(compile.stdout).text(),
|
|
81
|
-
new Response(compile.stderr).text(),
|
|
82
|
-
]);
|
|
83
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
65
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
84
66
|
|
|
85
67
|
const port = freePort();
|
|
86
68
|
server = Bun.spawn([binary], {
|
package/test/native-http.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { createHash } from "node:crypto";
|
|
|
3
3
|
import { mkdtemp, readFile, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { connect } from "node:net";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
|
-
import { join
|
|
7
|
-
import {
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
import { compileNative } from "./native-compile";
|
|
8
8
|
import { preludePath, TRANSPORT_MARKER, transportPath, wrapNativeFetchHandler } from "../src/wrap";
|
|
9
9
|
|
|
10
10
|
// The native HTTP server's wire behaviour with raw sockets: keep-alive, pipelining (responses in
|
|
@@ -188,6 +188,13 @@ async function suite(port: number, label: string) {
|
|
|
188
188
|
assert.equal(got[0].body.toString(), "n=close");
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
// #236: an HTTP/1.0 request line (nginx's default proxy_http_version) is answered, not refused with 505.
|
|
192
|
+
{
|
|
193
|
+
const got = await exchange(port, [Buffer.from("GET /n/old HTTP/1.0\r\nHost: t\r\n\r\n")], 1);
|
|
194
|
+
assert.equal(got[0].status, 200, `${label}: HTTP/1.0 request status`);
|
|
195
|
+
assert.equal(got[0].body.toString(), "n=old", `${label}: HTTP/1.0 request body`);
|
|
196
|
+
}
|
|
197
|
+
|
|
191
198
|
// 150 connections at once, 4 pipelined requests each, with garbage-heavy requests mixed in.
|
|
192
199
|
{
|
|
193
200
|
const results = await Promise.all(
|
|
@@ -210,9 +217,6 @@ async function suite(port: number, label: string) {
|
|
|
210
217
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-http-"));
|
|
211
218
|
const servers: Array<ReturnType<typeof Bun.spawn>> = [];
|
|
212
219
|
try {
|
|
213
|
-
const porffor = await ensurePorffor();
|
|
214
|
-
const node = Bun.which("node");
|
|
215
|
-
if (!node) throw new Error("native http test needs node on PATH");
|
|
216
220
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
217
221
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
218
222
|
const generated = join(workdir, "http.generated.js");
|
|
@@ -228,21 +232,7 @@ try {
|
|
|
228
232
|
"2026-10-21",
|
|
229
233
|
),
|
|
230
234
|
);
|
|
231
|
-
|
|
232
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
233
|
-
{
|
|
234
|
-
cwd: workdir,
|
|
235
|
-
env: process.env,
|
|
236
|
-
stdout: "pipe",
|
|
237
|
-
stderr: "pipe",
|
|
238
|
-
},
|
|
239
|
-
);
|
|
240
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
241
|
-
compile.exited,
|
|
242
|
-
new Response(compile.stdout).text(),
|
|
243
|
-
new Response(compile.stderr).text(),
|
|
244
|
-
]);
|
|
245
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
235
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
246
236
|
|
|
247
237
|
for (const every of ["1", "8"]) {
|
|
248
238
|
const port = freePort();
|
package/test/native-iterators.ts
CHANGED
|
@@ -1,16 +1,31 @@
|
|
|
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
|
const expected = {
|
|
9
|
-
query: [
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
query: [
|
|
10
|
+
["a", "1"],
|
|
11
|
+
["a", "2"],
|
|
12
|
+
["b", "3"],
|
|
13
|
+
],
|
|
14
|
+
keys: ["a", "a", "b"],
|
|
15
|
+
values: ["1", "2", "3"],
|
|
16
|
+
live: ["x", "y", true],
|
|
17
|
+
form: [
|
|
18
|
+
["x", "1"],
|
|
19
|
+
["x", "2"],
|
|
20
|
+
],
|
|
21
|
+
formLive: ["x", "y", true],
|
|
22
|
+
self: true,
|
|
23
|
+
headers: [
|
|
24
|
+
["a", "1"],
|
|
25
|
+
["b", "2"],
|
|
26
|
+
],
|
|
27
|
+
headersMap: 2,
|
|
28
|
+
headersFromEntries: { a: "1", b: "2" },
|
|
14
29
|
};
|
|
15
30
|
const handler = `export default { fetch(request) {
|
|
16
31
|
if (new URL(request.url).pathname === "/null") return new Response(null);
|
|
@@ -47,14 +62,7 @@ function freePort(): number {
|
|
|
47
62
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-iterators-"));
|
|
48
63
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
49
64
|
try {
|
|
50
|
-
const
|
|
51
|
-
const node = Bun.which("node");
|
|
52
|
-
if (!node) throw new Error("native iterators test needs node on PATH");
|
|
53
|
-
|
|
54
|
-
const [core, broker] = await Promise.all([
|
|
55
|
-
readFile(preludePath, "utf8"),
|
|
56
|
-
readFile(transportPath("broker"), "utf8"),
|
|
57
|
-
]);
|
|
65
|
+
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
58
66
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
59
67
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
60
68
|
const generated = join(workdir, "iterators.generated.js");
|
|
@@ -62,18 +70,7 @@ try {
|
|
|
62
70
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
63
71
|
await rm(binary, { force: true });
|
|
64
72
|
|
|
65
|
-
|
|
66
|
-
cwd: workdir,
|
|
67
|
-
env: process.env,
|
|
68
|
-
stdout: "pipe",
|
|
69
|
-
stderr: "pipe",
|
|
70
|
-
});
|
|
71
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
72
|
-
compile.exited,
|
|
73
|
-
new Response(compile.stdout).text(),
|
|
74
|
-
new Response(compile.stderr).text(),
|
|
75
|
-
]);
|
|
76
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
73
|
+
await compileNative({ generated, binary, dir: workdir, cacheRoot: workdir });
|
|
77
74
|
|
|
78
75
|
const port = freePort();
|
|
79
76
|
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
|
// JSON.stringify of strings as the spec defines it (Bun is the reference): quotes and backslash,
|
|
@@ -61,10 +61,6 @@ function freePort(): number {
|
|
|
61
61
|
const workdir = await mkdtemp(join(tmpdir(), "sb-native-json-strings-"));
|
|
62
62
|
let server: ReturnType<typeof Bun.spawn> | undefined;
|
|
63
63
|
try {
|
|
64
|
-
const porffor = await ensurePorffor();
|
|
65
|
-
const node = Bun.which("node");
|
|
66
|
-
if (!node) throw new Error("native streams test needs node on PATH");
|
|
67
|
-
|
|
68
64
|
const [core, broker] = await Promise.all([readFile(preludePath, "utf8"), readFile(transportPath("broker"), "utf8")]);
|
|
69
65
|
assert(core.includes(TRANSPORT_MARKER), "runtime prelude is missing its transport marker");
|
|
70
66
|
const prelude = core.replace(TRANSPORT_MARKER, broker);
|
|
@@ -73,21 +69,7 @@ try {
|
|
|
73
69
|
await writeFile(generated, wrapNativeFetchHandler(handler, prelude));
|
|
74
70
|
await rm(binary, { force: true });
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
[node, resolve(porffor, "runtime/index.js"), "native", generated, "-o", binary, "-s", "-O0"],
|
|
78
|
-
{
|
|
79
|
-
cwd: workdir,
|
|
80
|
-
env: process.env,
|
|
81
|
-
stdout: "pipe",
|
|
82
|
-
stderr: "pipe",
|
|
83
|
-
},
|
|
84
|
-
);
|
|
85
|
-
const [exitCode, stdout, stderr] = await Promise.all([
|
|
86
|
-
compile.exited,
|
|
87
|
-
new Response(compile.stdout).text(),
|
|
88
|
-
new Response(compile.stderr).text(),
|
|
89
|
-
]);
|
|
90
|
-
assert.equal(exitCode, 0, `Porffor native compile failed:\n${stderr}\n${stdout}`);
|
|
72
|
+
await compileNative({ generated, binary, dir: workdir });
|
|
91
73
|
|
|
92
74
|
const port = freePort();
|
|
93
75
|
server = Bun.spawn([binary], {
|