Current section

Files

Jump to
smol src bun.ffi.mjs
Raw

src/bun.ffi.mjs

import { Result$Error } from "./gleam.mjs";
import { adapt } from "./adapt.ffi.mjs";
import { started } from "./smol.mjs";
import { from_file as nodeFromFile } from "./node.ffi.mjs";
import { upgrade } from "./smol.ffi.mjs";
import {
Builder$Builder$handler,
Builder$Builder$port,
Builder$Builder$interface,
Builder$Builder$on_error,
Builder$Builder$after_start,
} from "./smol/internal/builder.mjs";
export function start(builder) {
try {
const handler = adapt(Builder$Builder$handler(builder));
const server = Bun.serve({
port: Builder$Builder$port(builder),
hostname: Builder$Builder$interface(builder),
development: false,
async fetch(req, server) {
const res = await handler(req);
if (
res.body[upgrade] &&
server.upgrade(req, {
headers: res.headers,
data: res.body[upgrade],
})
) {
return;
} else {
return res;
}
},
error(error) {
Builder$Builder$on_error(builder)(error.stack, error);
return new Response("Internal Server Error", { status: 500 });
},
websocket: {
perMessageDeflate: true,
open(ws) {
const runtime = ws.data;
runtime.send = (message) => ws.send(message);
runtime.close = () => ws.close();
runtime.onOpen();
},
message(ws, message) {
ws.data.onMessage(message);
},
close(ws) {
ws.data.onClose();
},
},
});
let disposed = false;
const stop = async () => {
if (disposed) {
return;
}
disposed = true;
process.off("SIGINT", onExit);
process.off("SIGTERM", onExit);
process.off("exit", onExit);
await server.stop();
};
const onExit = async () => {
try {
await stop();
} finally {
process.exit();
}
};
process.on("SIGINT", onExit);
process.on("SIGTERM", onExit);
process.on("exit", onExit);
Builder$Builder$after_start(builder)(server.port, server.hostname);
return Promise.resolve(started(server.port, server.hostname, stop));
} catch (e) {
return Promise.resolve(Result$Error(undefined));
}
}
export function from_file(path, offset, limit) {
if (limit > 1) {
// TODO: because bun is very buggy, it has an off-by-one error here.
// this makes it impossible to send back a single byte, so in those cases
// you will get 2 bytes. oh well.
limit -= 1;
}
return nodeFromFile(path, offset, limit);
}