Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/preview3-shim/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# TypeScript build outputs
/dist/
29 changes: 19 additions & 10 deletions packages/preview3-shim/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,44 @@
},
"files": [
"types",
"lib"
"dist"
],
"type": "module",
"types": "./types/index.d.ts",
"exports": {
".": {
"types": "./types/index.d.ts",
"node": "./lib/nodejs/index.js"
"types": "./dist/nodejs/index.d.ts",
"node": "./dist/nodejs/index.js"
},
"./*": {
"types": "./types/*.d.ts",
"node": "./lib/nodejs/*.js"
"types": "./dist/nodejs/*.d.ts",
"node": "./dist/nodejs/*.js"
},
"./interfaces/*": {
"types": "./types/interfaces/*.d.ts"
}
},
"scripts": {
"compile:check": "tsc --noEmit types/index.d.ts",
"build": "tsc --project tsconfig.build.json",
"build:watch": "tsc --watch",
"types:check": "tsc --noEmit",
"fmt": "oxfmt",
"fmt:check": "oxfmt --check",
"lint": "oxlint",
"lint:fix": "oxlint --fix",
"pretest": "pnpm run build",
"test": "vitest --run",
"bench": "vitest bench --run"
"prebench": "pnpm run build",
"bench": "vitest bench --run",
"prepack": "pnpm run build"
},
"dependencies": {
"@bytecodealliance/preview2-shim": "^0.18.1"
"@bytecodealliance/preview2-shim": "^0.19.0"
},
"devDependencies": {
"@types/node": "^24.12.4",
"globals": "^17.6.0",
"typescript": "catalog:",
"vite": "^8.0.16",
"vitest": "^4.1.0"
"vitest": "catalog:"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ import { ResourceWorker } from "./workers/resource-worker.js";
import { StreamReader, readableByteStreamFromReader } from "./stream.js";
import { future } from "./future.js";

import { environment as environmentV2 } from "@bytecodealliance/preview2-shim/cli";
import * as cliV2 from "@bytecodealliance/preview2-shim/cli";

export {
type Preview2NodeCli = typeof cliV2 & {
_appendEnv: (env: Record<string, string>) => void;
_setTerminalStdin: (terminalStdin: unknown) => void;
_setTerminalStdout: (terminalStdout: unknown) => void;
_setTerminalStderr: (terminalStderr: unknown) => void;
};

const nodeCliV2 = cliV2 as Preview2NodeCli;

export const {
_appendEnv,
_setEnv,
_setArgs,
Expand All @@ -21,15 +30,15 @@ export {
terminalStdin,
terminalStdout,
terminalStderr,
} from "@bytecodealliance/preview2-shim/cli";
} = nodeCliV2;

// `wasi:cli/environment` renamed `initial-cwd` to `get-initial-cwd` between
// p2 and p3. Adapt the p2-shim shape to the p3 WIT member name while
// re-exporting the unchanged members.
export const environment = {
getEnvironment: environmentV2.getEnvironment,
getArguments: environmentV2.getArguments,
getInitialCwd: environmentV2.initialCwd,
getEnvironment: cliV2.environment.getEnvironment,
getArguments: cliV2.environment.getArguments,
getInitialCwd: cliV2.environment.initialCwd,
};

let WORKER = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,16 @@ function getErrorTag(e) {
* Custom error for File operations with JCO compatible payload.
*/
export class FSError extends Error {
payload;

/**
* @param {string} tag – machine‐readable error tag
* @param {string} [message] – human‐readable message
* @param {any} [val] – optional extra data
* @param {object} [opts]
* @param {Error} [opts.cause]
*/
constructor(tag, message, val, opts = {}) {
constructor(tag, message = undefined, val = undefined, opts: { cause?: unknown } = {}) {
super(message ?? `Error: ${tag}`, { cause: opts.cause });
this.name = "FSError";
this.payload = val !== undefined ? { tag, val } : { tag };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
let REGISTRY = null;
let REGISTRY: FinalizationRegistry<() => void> | null = null;

function getRegistry() {
if (!REGISTRY) {
Expand Down Expand Up @@ -27,7 +27,7 @@ export function registerDispose(resource, parent = null, id, disposeFn) {
return finalizer;
}

export function earlyDispose(finalizer) {
export function earlyDispose(finalizer: () => void) {
getRegistry().unregister(finalizer);
finalizer();
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { MessageChannel } from "node:worker_threads";

import { ResourceWorker } from "../workers/resource-worker.js";
import { StreamReader, readableByteStreamFromReader } from "../stream.js";
import { FutureReader, future } from "../future.js";
Expand Down Expand Up @@ -63,7 +65,7 @@ export const client = {
const { port1: tx, port2: rx } = new MessageChannel();
const { port1: transmitRx, port2: transmitTx } = new MessageChannel();

const transfer = [rx, transmitTx];
const transfer = [rx, transmitTx] as any[];
const stream = body ? readableByteStreamFromReader(body, { name: "request body" }) : undefined;
if (stream) {
transfer.unshift(stream);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
* https://bytecodealliance.github.io/jco/wit-type-representations.html#result-considerations-idiomatic-js-errors-for-host-implementations
*/
export class HttpError extends Error {
payload;

/**
* Create a new WASI http error
* @param {string} tag - The error tag/type
* @param {string} [message] - Human-readable error message
* @param {any} [val] - Optional value/data for the error
*/
constructor(tag, message, val, opts = {}) {
constructor(tag, message = undefined, val = undefined, opts: { cause?: unknown } = {}) {
super(message || `Error: ${tag}`, { cause: opts.cause });
this.name = "HttpError";
this.payload = val !== undefined ? { tag, val } : { tag };
Expand Down Expand Up @@ -57,7 +59,7 @@ export class HttpError extends Error {
}
}

function getFirstError(e) {
function getFirstError(e: any) {
if (typeof e !== "object" || e === null) {
return e;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class Request {
* @throws {HttpError} with payload.tag 'invalid-argument' for invalid arguments
*
*/
static new(headers, contents, trailers, options) {
static new(headers, contents, trailers, options): [Request, FutureReader] {
if (options != null && !(options instanceof RequestOptions)) {
throw new HttpError("invalid-argument", "options must be RequestOptions");
}
Expand Down Expand Up @@ -541,7 +541,7 @@ function readOpts(remaining) {
? remaining
: BigInt(DEFAULT_BYTE_STREAM_CHUNK_SIZE),
);
const opts = { count };
const opts: { count: number; rejectLength?: number } = { count };
if (remaining <= BigInt(Number.MAX_SAFE_INTEGER)) {
opts.rejectLength = Number(remaining);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class Response {
* @returns {{ res: Response, future: FutureReader }}
* @throws {HttpError} with payload.tag 'invalid-argument' for invalid arguments
*/
static new(headers, contents, trailers) {
static new(headers, contents, trailers): [Response, FutureReader] {
if (!(headers instanceof Fields)) {
throw new HttpError("invalid-argument", "headers must be Fields");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { EventEmitter } from "node:events";
import { MessageChannel } from "node:worker_threads";

import { ResourceWorker } from "../workers/resource-worker.js";
import { StreamReader, readableByteStreamFromReader } from "../stream.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@ export const CODE_MAP = {
* https://bytecodealliance.github.io/jco/wit-type-representations.html#result-considerations-idiomatic-js-errors-for-host-implementations
*/
export class SocketError extends Error {
payload;

/**
* @param {string} tag – machine‐readable error tag
* @param {string} [message] – human‐readable message
* @param {any} [val] – optional extra data
*/
constructor(tag, message, val, opts = {}) {
constructor(tag, message = undefined, val = undefined, opts: { cause?: unknown } = {}) {
super(message ?? `Error: ${tag}`, { cause: opts.cause });
this.name = "SocketError";
this.payload = val !== undefined ? { tag, val } : { tag };
Expand All @@ -88,9 +90,7 @@ export class SocketError extends Error {
return err;
}

let tag,
message = undefined,
val = undefined;
let tag, message, val;

if (typeof err === "number") {
tag = CODE_MAP[err] ?? "other";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export class TcpSocket {
hopLimit: 1,
receiveBufferSize: 65_536n,
sendBufferSize: 65_536n,
listenBacklogSize: 128n,
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ function assertByte(value) {
* expect(done).toBeNull();
*
*/
export function stream(opts = {}) {
export function stream(opts: { readableHWM?: number; writableHWM?: number } = {}) {
const { readableHWM = 64 * 1024, writableHWM = 64 * 1024 } = opts;

const transform = new TransformStream(
Expand Down Expand Up @@ -206,7 +206,7 @@ export class StreamReader {
* @param {AsyncIterable|Iterable} source - An async or sync iterable to consume e.g. ReadableStream, async generator, array.
* @throws {Error} If the provided source does not implement `[Symbol.asyncIterator]` or `[Symbol.iterator]`.
*/
constructor(source, opts = {}) {
constructor(source, opts: { preventCancel?: boolean } = {}) {
if (
!source ||
(typeof source[Symbol.asyncIterator] !== "function" &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Readable, Writable, PassThrough } from "node:stream";
import { pipeline } from "stream/promises";
import { MessageChannel } from "node:worker_threads";

import { createServer } from "node:http";
import { request as httpRequest, Agent as HttpAgent } from "node:http";
Expand All @@ -21,6 +22,9 @@ Router()
.op("client-request", handleRequest);

class Queue {
_items = [];
_resolvers = [];

constructor() {
this._items = [];
this._resolvers = [];
Expand Down Expand Up @@ -62,7 +66,7 @@ async function handleHttpServerStart({ port, host }) {

await new Promise((resolve, reject) => {
server.on("error", reject);
server.listen(port, host, resolve);
server.listen(port, host, () => resolve(undefined));
});

servers.set(serverId, { server, pending, inflight });
Expand Down Expand Up @@ -343,7 +347,7 @@ function endRequest(req) {
req.once("close", onClose);

try {
req.end(() => settle(resolve));
req.end(() => settle(resolve, undefined));
} catch (err) {
settle(reject, err);
}
Expand Down Expand Up @@ -410,7 +414,7 @@ const toObject = (entries) => {

const encoder = new TextEncoder();

const toEntries = (obj) => {
const toEntries = (obj: Record<string, any>) => {
return Object.entries(obj).flatMap(([k, v]) =>
Array.isArray(v) ? v.map((val) => [k, encoder.encode(val)]) : [[k, encoder.encode(v)]],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,12 @@ export function Router() {
};
}

function serializeError(err) {
function serializeError(err: any) {
if (!(err instanceof Error)) {
return err;
}

const serialized = {
const serialized: any = {
__resourceWorkerError: true,
name: err.name,
message: err.message,
Expand All @@ -167,7 +167,7 @@ function serializeError(err) {
return serialized;
}

function deserializeError(err) {
function deserializeError(err: any) {
if (!err || typeof err !== "object" || err.__resourceWorkerError !== true) {
return err;
}
Expand Down
Loading
Loading