Stop rolling up trailbase-wasm types to avoid duplicating types per module and confusing tsc.

This commit is contained in:
Sebastian Jeltsch
2026-02-19 14:51:22 +01:00
parent ada26e2a7b
commit def4c72b49
6 changed files with 82 additions and 81 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
import { defineConfig, addPeriodicCallback } from "trailbase-wasm";
import { HttpHandler, JsonResponse } from "trailbase-wasm/http";
import { HttpHandler, HttpResponse } from "trailbase-wasm/http";
import { JobHandler } from "trailbase-wasm/job";
import { query } from "trailbase-wasm/db";
@@ -43,7 +43,7 @@ export default defineConfig({
});
function jsonHandler(req) {
return JsonResponse.from(
return HttpResponse.json(
req.json() ?? {
int: 5,
real: 4.2,
+12 -12
View File
@@ -8,27 +8,27 @@
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"types": "./dist/src/index.d.ts"
},
"./db": {
"import": "./dist/db.js",
"types": "./dist/db.d.ts"
"types": "./dist/src/db/index.d.ts"
},
"./fs": {
"import": "./dist/fs.js",
"types": "./dist/fs.d.ts"
"types": "./dist/src/fs/index.d.ts"
},
"./http": {
"import": "./dist/http.js",
"types": "./dist/http.d.ts"
"types": "./dist/src/http/index.d.ts"
},
"./job": {
"import": "./dist/job.js",
"types": "./dist/job.d.ts"
"types": "./dist/src/job/index.d.ts"
},
"./kv": {
"import": "./dist/kv.js",
"types": "./dist/kv.d.ts"
"types": "./dist/src/kv/index.d.ts"
}
},
"publishConfig": {
@@ -36,27 +36,27 @@
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
"types": "./dist/src/index.d.ts"
},
"./db": {
"import": "./dist/db.js",
"types": "./dist/db.d.ts"
"types": "./dist/src/db/index.d.ts"
},
"./fs": {
"import": "./dist/fs.js",
"types": "./dist/fs.d.ts"
"types": "./dist/src/fs/index.d.ts"
},
"./http": {
"import": "./dist/http.js",
"types": "./dist/http.d.ts"
"types": "./dist/src/http/index.d.ts"
},
"./job": {
"import": "./dist/job.js",
"types": "./dist/job.d.ts"
"types": "./dist/src/job/index.d.ts"
},
"./kv": {
"import": "./dist/kv.js",
"types": "./dist/kv.d.ts"
"types": "./dist/src/kv/index.d.ts"
}
}
},
+49 -5
View File
@@ -8,11 +8,7 @@ import {
import type { HttpContext } from "@common/HttpContext";
import type { HttpHandlerInterface, ResponseType } from "./index";
import { StatusCode } from "./index";
import {
HttpError,
responseToOutgoingResponse,
errorToOutgoingResponse,
} from "./response";
import { HttpError, HttpResponse, buildResponse } from "./response";
import { type Method, HttpRequestImpl } from "./request";
import { JobHandlerInterface } from "../job";
import { awaitPendingTimers } from "../timer";
@@ -85,6 +81,54 @@ export function buildIncomingHttpHandler(args: {
};
}
export function responseToOutgoingResponse(
resp: ResponseType,
): OutgoingResponse {
if (resp instanceof OutgoingResponse) {
return resp;
} else if (resp instanceof HttpResponse) {
return buildResponse({
status: resp.status,
headers: resp.headers,
body: resp.body ?? new Uint8Array(),
});
} else if (resp instanceof Uint8Array) {
return buildResponse({
status: StatusCode.OK,
headers: [],
body: resp,
});
} else if (typeof resp === "string") {
return buildResponse({
status: StatusCode.OK,
headers: [],
body: encodeBytes(resp),
});
} else {
// void case.
return buildResponse({
status: StatusCode.OK,
headers: [],
body: new Uint8Array(),
});
}
}
export function errorToOutgoingResponse(err: unknown): OutgoingResponse {
if (err instanceof HttpError) {
return buildResponse({
status: err.status,
headers: [["Content-Type", encodeBytes("text/plain; charset=utf-8")]],
body: err.message ? encodeBytes(err.message) : new Uint8Array(),
});
}
return buildResponse({
body: encodeBytes(`uncaught: ${err}`),
status: StatusCode.INTERNAL_SERVER_ERROR,
headers: [],
});
}
function writeResponse(
responseOutparam: ResponseOutparam,
response: OutgoingResponse,
+9 -2
View File
@@ -1,6 +1,7 @@
import { OutgoingResponse } from "wasi:http/types@0.2.3";
import { HttpRequest } from "./request";
import type { Method } from "./request";
import type { ResponseType } from "./response";
import { HttpResponse } from "./response";
// Override setInterval/setTimeout.
import "../timer";
@@ -10,7 +11,13 @@ export { OutgoingResponse } from "wasi:http/types@0.2.3";
export { StatusCode } from "./status";
export type { Method, HttpRequest, Scheme, User } from "./request";
export { HttpResponse, HttpError } from "./response";
export type { ResponseType } from "./response";
export type ResponseType =
| string
| Uint8Array
| HttpResponse
| OutgoingResponse
| void;
export type HttpHandlerCallback = (
req: HttpRequest,
+1 -56
View File
@@ -2,13 +2,6 @@ import { Fields, OutgoingBody, OutgoingResponse } from "wasi:http/types@0.2.3";
import { StatusCode } from "./status";
import { encodeBytes } from "./incoming";
export type ResponseType =
| string
| Uint8Array
| HttpResponse
| OutgoingResponse
| void;
export class HttpResponse {
protected constructor(
public readonly status: StatusCode,
@@ -78,61 +71,13 @@ export class HttpError extends Error {
}
}
export function responseToOutgoingResponse(
resp: ResponseType,
): OutgoingResponse {
if (resp instanceof OutgoingResponse) {
return resp;
} else if (resp instanceof HttpResponse) {
return buildResponse({
status: resp.status,
headers: resp.headers,
body: resp.body ?? new Uint8Array(),
});
} else if (resp instanceof Uint8Array) {
return buildResponse({
status: StatusCode.OK,
headers: [],
body: resp,
});
} else if (typeof resp === "string") {
return buildResponse({
status: StatusCode.OK,
headers: [],
body: encodeBytes(resp),
});
} else {
// void case.
return buildResponse({
status: StatusCode.OK,
headers: [],
body: new Uint8Array(),
});
}
}
export function errorToOutgoingResponse(err: unknown): OutgoingResponse {
if (err instanceof HttpError) {
return buildResponse({
status: err.status,
headers: [["Content-Type", encodeBytes("text/plain; charset=utf-8")]],
body: err.message ? encodeBytes(err.message) : new Uint8Array(),
});
}
return buildResponse({
body: encodeBytes(`uncaught: ${err}`),
status: StatusCode.INTERNAL_SERVER_ERROR,
headers: [],
});
}
type ResponseOptions = {
status: StatusCode;
headers: [string, Uint8Array][];
body: Uint8Array;
};
function buildResponse(opts: ResponseOptions): OutgoingResponse {
export function buildResponse(opts: ResponseOptions): OutgoingResponse {
// NOTE: `outputStream.blockingWriteAndFlush` only writes up to 4kB, see documentation.
if (opts.body.length <= 4096) {
return buildSmallResponse(opts);
+9 -4
View File
@@ -26,11 +26,16 @@ export default defineConfig({
},
rollupOptions: {
plugins: [
// NOTE: Needs to be in `rollupOptions` rather than vite's plugins to apply to each input.
dts({
rollupTypes: true,
// NOTE: We could try to roll-up all types into a single declaration file per module,
// however due to cross-module deps this leads to duplicate type declarations,
// e.g. HttpHandlerInterface and all its dependent types are declared both in the
// "index" and "http" modules.
// This confuses the heck out of tsc for downstream users of this library.
// Maybe there are some rollup(Config|Options) that woudl address this :shrug:.
rollupTypes: false,
// NOTE: Include .d.ts files generated by `jco`.
copyDtsFiles: false,
copyDtsFiles: true,
// NOTE: The .d.ts files generated by `jco` contain dynamic imports.
staticImport: true,
}),
@@ -39,7 +44,7 @@ export default defineConfig({
output: {
entryFileNames: "[name].js",
},
external,
external: external,
},
},
});