@daloyjs/core 0.9.1 → 0.11.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/README.md +50 -36
- package/dist/adapters/bun.d.ts.map +1 -1
- package/dist/adapters/bun.js +178 -2
- package/dist/adapters/bun.js.map +1 -1
- package/dist/adapters/node.d.ts.map +1 -1
- package/dist/adapters/node.js +272 -10
- package/dist/adapters/node.js.map +1 -1
- package/dist/app.d.ts +13 -3
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +76 -19
- package/dist/app.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/websocket.d.ts +275 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +505 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -14,14 +14,14 @@ DaloyJS is maintained in the GitHub organization at <https://github.com/daloyjs>
|
|
|
14
14
|
|
|
15
15
|
DaloyJS exists to be the framework you'd build if you took the best ideas from each modern stack:
|
|
16
16
|
|
|
17
|
-
| You want
|
|
18
|
-
|
|
19
|
-
| Best **OpenAPI ergonomics**
|
|
20
|
-
| Best **Vercel / serverless / edge fit**
|
|
21
|
-
| Mature **Swagger / docs / ops** in Node
|
|
22
|
-
| Modern **TS-first DX**, Bun acceptable
|
|
23
|
-
| Best-in-class **typed client codegen** for any consumer | [Hey API](https://heyapi.dev/openapi-ts/get-started)
|
|
24
|
-
| **Supply-chain-hardened installs and publishing**
|
|
17
|
+
| You want | Today's best-of | What DaloyJS gives you |
|
|
18
|
+
| ------------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
19
|
+
| Best **OpenAPI ergonomics** | [FastAPI](https://fastapi.tiangolo.com) | First-class OpenAPI 3.1 generation from a single route definition. |
|
|
20
|
+
| Best **Vercel / serverless / edge fit** | [Hono](https://hono.dev/docs/) | Web-standard `Request → Response` core, multi-runtime adapters. |
|
|
21
|
+
| Mature **Swagger / docs / ops** in Node | [Fastify](https://fastify.dev/docs/latest/Reference/) | Encapsulated plugins, structured logger, graceful shutdown, request ids, hooks. |
|
|
22
|
+
| Modern **TS-first DX**, Bun acceptable | [Elysia](https://elysiajs.com/at-glance.html) | End-to-end typed handlers, typed context, typed client. |
|
|
23
|
+
| Best-in-class **typed client codegen** for any consumer | [Hey API](https://heyapi.dev/openapi-ts/get-started) | One command (`pnpm gen`) emits a fully-typed fetch SDK from your spec. |
|
|
24
|
+
| **Supply-chain-hardened installs and publishing** | [pnpm](https://pnpm.io/motivation) + hardened CI/CD | `ignore-scripts`, release-age cooldown, explicit build allowlist, SHA-pinned actions, isolated OIDC publish with provenance. |
|
|
25
25
|
|
|
26
26
|
```
|
|
27
27
|
framework test suite passing · 100% line + function coverage · clean strict TypeScript 6
|
|
@@ -101,7 +101,13 @@ Run `pnpm audit --prod` regularly (or `pnpm run audit` in this repo) — and `pn
|
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
103
|
import { z } from "zod";
|
|
104
|
-
import {
|
|
104
|
+
import {
|
|
105
|
+
App,
|
|
106
|
+
NotFoundError,
|
|
107
|
+
secureHeaders,
|
|
108
|
+
rateLimit,
|
|
109
|
+
requestId,
|
|
110
|
+
} from "@daloyjs/core";
|
|
105
111
|
import { serve } from "@daloyjs/core/node";
|
|
106
112
|
|
|
107
113
|
const app = new App({ bodyLimitBytes: 1024 * 1024, requestTimeoutMs: 5_000 });
|
|
@@ -118,7 +124,10 @@ app.route({
|
|
|
118
124
|
tags: ["Books"],
|
|
119
125
|
request: { params: z.object({ id: z.string() }) },
|
|
120
126
|
responses: {
|
|
121
|
-
200: {
|
|
127
|
+
200: {
|
|
128
|
+
description: "Found",
|
|
129
|
+
body: z.object({ id: z.string(), title: z.string() }),
|
|
130
|
+
},
|
|
122
131
|
404: { description: "Not found" },
|
|
123
132
|
},
|
|
124
133
|
handler: async ({ params }) => ({
|
|
@@ -156,7 +165,7 @@ That single command runs the two scripts:
|
|
|
156
165
|
```ts
|
|
157
166
|
import { defineConfig } from "@hey-api/openapi-ts";
|
|
158
167
|
export default defineConfig({
|
|
159
|
-
input:
|
|
168
|
+
input: "./generated/openapi.json",
|
|
160
169
|
output: { path: "./generated/client", postProcess: ["prettier"] },
|
|
161
170
|
plugins: ["@hey-api/client-fetch", "@hey-api/typescript", "@hey-api/sdk"],
|
|
162
171
|
});
|
|
@@ -192,24 +201,24 @@ path is used. Others are first-party middleware so applications can choose the
|
|
|
192
201
|
right CORS policy, rate-limit key, CSP, session secret, or CSRF rollout for their
|
|
193
202
|
deployment.
|
|
194
203
|
|
|
195
|
-
| Threat
|
|
196
|
-
|
|
197
|
-
| **Body-size DoS**
|
|
198
|
-
| **Prototype pollution**
|
|
199
|
-
| **Header / response splitting**
|
|
200
|
-
| **Path traversal**
|
|
201
|
-
| **Slow-loris / hung handlers**
|
|
202
|
-
| **MIME sniffing**
|
|
203
|
-
| **Clickjacking**
|
|
204
|
-
| **XSS via injected scripts**
|
|
205
|
-
| **Cross-origin leakage**
|
|
206
|
-
| **Information disclosure (5xx)** | Production mode strips `detail` from 5xx problem+json automatically.
|
|
207
|
-
| **Credential timing attacks**
|
|
208
|
-
| **Brute-force / scraping**
|
|
209
|
-
| **Method confusion**
|
|
210
|
-
| **CORS misconfig**
|
|
211
|
-
| **Request correlation**
|
|
212
|
-
| **Supply chain**
|
|
204
|
+
| Threat | Built-in behavior |
|
|
205
|
+
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
206
|
+
| **Body-size DoS** | Core-enforced streamed read with a hard cap (default 1 MiB); `Content-Length` checked first. |
|
|
207
|
+
| **Prototype pollution** | Core JSON parser strips `__proto__` / `constructor` / `prototype` via reviver. |
|
|
208
|
+
| **Header / response splitting** | Core header sanitizers reject CRLF + NUL. |
|
|
209
|
+
| **Path traversal** | Core router rejects `..` segments and `//` before walking. |
|
|
210
|
+
| **Slow-loris / hung handlers** | Core `requestTimeoutMs` aborts handlers (default 30 s); Node adapter sets `requestTimeout` + `headersTimeout` + `maxHeaderSize`. |
|
|
211
|
+
| **MIME sniffing** | First-party `secureHeaders()` sets `X-Content-Type-Options: nosniff`; scaffolded apps enable it. |
|
|
212
|
+
| **Clickjacking** | First-party `secureHeaders()` sets `X-Frame-Options: DENY` + CSP `frame-ancestors 'none'`; scaffolded apps enable it. |
|
|
213
|
+
| **XSS via injected scripts** | First-party `secureHeaders()` provides a strict CSP `default-src 'self'` baseline; scaffolded apps enable it. |
|
|
214
|
+
| **Cross-origin leakage** | First-party `secureHeaders()` sets `cross-origin-opener-policy` + `cross-origin-resource-policy` to `same-origin`; scaffolded apps enable it. |
|
|
215
|
+
| **Information disclosure (5xx)** | Production mode strips `detail` from 5xx problem+json automatically. |
|
|
216
|
+
| **Credential timing attacks** | First-party `timingSafeEqual()` helper for tokens & signatures. |
|
|
217
|
+
| **Brute-force / scraping** | First-party `rateLimit()` with token-bucket + `Retry-After`; Node/Bun/Deno scaffolded apps enable it. |
|
|
218
|
+
| **Method confusion** | Real **405** with `Allow` header, not a misleading 404. |
|
|
219
|
+
| **CORS misconfig** | First-party `cors()` requires an explicit allowlist and throws for `*` with credentials. |
|
|
220
|
+
| **Request correlation** | First-party `requestId()` uses cryptographic ids; scaffolded apps enable it. |
|
|
221
|
+
| **Supply chain** | pnpm `ignore-scripts=true`, `minimum-release-age=1440`, verified store, reproducible lockfile, lockfile source verification, provenance publishing, and CI/CD hardening against cache poisoning and OIDC token abuse. |
|
|
213
222
|
|
|
214
223
|
The publish pipeline is also hardened: no `pull_request_target`, no GitHub Actions cache in CI, top-level `permissions: {}`, `step-security/harden-runner`, a separate protected `release.yml` workflow, npm trusted publishing with `--provenance`, CodeQL, OpenSSF Scorecard, zizmor workflow linting, Dependabot, and CODEOWNERS on workflow/package files. See [SECURITY.md](SECURITY.md) and the [supply-chain security docs](https://daloyjs.dev/docs/security/supply-chain).
|
|
215
224
|
|
|
@@ -251,9 +260,13 @@ The contract runner verifies that declared examples actually match their schemas
|
|
|
251
260
|
const usersPlugin = {
|
|
252
261
|
name: "users",
|
|
253
262
|
register(app) {
|
|
254
|
-
app.route({
|
|
263
|
+
app.route({
|
|
264
|
+
method: "GET",
|
|
265
|
+
path: "/me",
|
|
266
|
+
operationId: "me",
|
|
255
267
|
responses: { 200: { description: "ok" } },
|
|
256
|
-
handler: async () => ({ status: 200, body: { user: "alice" } })
|
|
268
|
+
handler: async () => ({ status: 200, body: { user: "alice" } }),
|
|
269
|
+
});
|
|
257
270
|
},
|
|
258
271
|
};
|
|
259
272
|
app.register(usersPlugin, { prefix: "/users", tags: ["Users"] });
|
|
@@ -265,17 +278,17 @@ await app.ready();
|
|
|
265
278
|
## Multi-runtime
|
|
266
279
|
|
|
267
280
|
```ts
|
|
268
|
-
import { serve } from "@daloyjs/core/node";
|
|
269
|
-
import { serve } from "@daloyjs/core/bun";
|
|
270
|
-
import { serve } from "@daloyjs/core/deno";
|
|
281
|
+
import { serve } from "@daloyjs/core/node"; // Node (Heroku, Railway, Render, Fly.io, any PaaS)
|
|
282
|
+
import { serve } from "@daloyjs/core/bun"; // Bun
|
|
283
|
+
import { serve } from "@daloyjs/core/deno"; // Deno
|
|
271
284
|
import { toFetchHandler } from "@daloyjs/core/cloudflare"; // Cloudflare Workers
|
|
272
285
|
import {
|
|
273
286
|
toFetchHandler as toVercelFetchHandler,
|
|
274
287
|
toRouteHandlers,
|
|
275
288
|
toWebHandler,
|
|
276
289
|
} from "@daloyjs/core/vercel"; // Vercel Node / Edge / Next.js / Netlify Edge
|
|
277
|
-
import { installFastlyListener } from "@daloyjs/core/fastly";
|
|
278
|
-
import { toLambdaHandler }
|
|
290
|
+
import { installFastlyListener } from "@daloyjs/core/fastly"; // Fastly Compute
|
|
291
|
+
import { toLambdaHandler } from "@daloyjs/core/lambda"; // AWS Lambda / Netlify Functions / Lambda Function URLs
|
|
279
292
|
```
|
|
280
293
|
|
|
281
294
|
The core only ever sees `Request → Response`. Adapters live at the edge.
|
|
@@ -304,6 +317,7 @@ What works today, at a glance:
|
|
|
304
317
|
- Adapters for Node (Heroku/Railway/Render/Fly.io), Bun, Deno, Cloudflare Workers, Vercel Node / Edge / Next.js / Netlify Edge, Fastly Compute, and AWS Lambda / Netlify Functions / Lambda Function URLs.
|
|
305
318
|
- Built-in security primitives (body limits, prototype-pollution-safe JSON, path-traversal guard, request timeouts, header injection guards) plus first-party middleware (`secureHeaders`, `cors`, `rateLimit`, `requestId`, `bearerAuth`, `csrf`, `session`, `timing` / `timingSafeEqual`).
|
|
306
319
|
- Streaming helpers (SSE + NDJSON), multipart ergonomics, OpenTelemetry-compatible tracing, signed-cookie sessions with pluggable stores, and a Redis-backed rate-limit store at `@daloyjs/core/rate-limit-redis`.
|
|
320
|
+
- WebSocket primitives with the same Bun-style handler shape (`open`/`message`/`close`/`drain`/`error`) running on both Node and Bun adapters, plus typed `app.ws(path, handler)` registration and route-table awareness so the upgrade listener is only installed when WS routes exist.
|
|
307
321
|
- Pretty `printStartupBanner()` / `formatStartupBanner()` startup helpers at `@daloyjs/core/banner`, used by every starter template so `pnpm dev` greets you with a colorized boxed panel (TTY + `NO_COLOR` / `FORCE_COLOR` aware, with an ASCII fallback for dumb terminals).
|
|
308
322
|
- In-process test client (`app.request()`), contract-test runner, in-process typed client, and Hey API codegen via `pnpm gen`.
|
|
309
323
|
- `pnpm create daloy` scaffolder with Node, Bun, Deno, Cloudflare Worker, and Vercel Edge templates, plus optional `--with-ci` GitHub Actions / Dependabot / CODEOWNERS / SECURITY.md hardening.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAcrC,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wFAAwF;IACxF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,GAAG,CAAC,EAAE,aAAa,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,GAAG,GAAG,SAAS,CAAC;IACrB,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,eAAoB,GAAG,eAAe,CAuE3E"}
|
package/dist/adapters/bun.js
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
|
+
import { WS_READY_STATE, WS_CLOSE_CODE, WS_MAX_CONTROL_PAYLOAD, encodeSendPayload, parseSubprotocols, validateSelectedSubprotocol, WebSocketProtocolError, } from "../websocket.js";
|
|
1
2
|
export function serve(app, opts = {}) {
|
|
2
3
|
const Bun = globalThis.Bun;
|
|
3
4
|
if (!Bun?.serve)
|
|
4
5
|
throw new Error("Bun runtime not detected");
|
|
6
|
+
const hasWs = app.webSocketRoutes.size > 0;
|
|
5
7
|
const cfg = {
|
|
6
8
|
maxRequestBodySize: opts.maxRequestBodySize ?? 16 * 1024 * 1024,
|
|
7
|
-
fetch:
|
|
9
|
+
fetch: hasWs
|
|
10
|
+
? (req, server) => {
|
|
11
|
+
if (req.headers.get("upgrade")?.toLowerCase() === "websocket") {
|
|
12
|
+
return tryBunUpgrade(app, req, server);
|
|
13
|
+
}
|
|
14
|
+
return app.fetch(req);
|
|
15
|
+
}
|
|
16
|
+
: (req) => app.fetch(req),
|
|
8
17
|
error: (err) => new Response(JSON.stringify({
|
|
9
18
|
type: "https://daloyjs.dev/errors/internal",
|
|
10
19
|
title: "Internal Server Error",
|
|
11
20
|
status: 500,
|
|
12
21
|
detail: err.message,
|
|
13
|
-
}), {
|
|
22
|
+
}), {
|
|
23
|
+
status: 500,
|
|
24
|
+
headers: { "content-type": "application/problem+json" },
|
|
25
|
+
}),
|
|
14
26
|
};
|
|
27
|
+
if (hasWs)
|
|
28
|
+
cfg.websocket = buildBunWebSocketConfig(app);
|
|
15
29
|
if (opts.unix === undefined) {
|
|
16
30
|
cfg.port = opts.port ?? 3000;
|
|
17
31
|
cfg.hostname = opts.hostname ?? "0.0.0.0";
|
|
@@ -34,4 +48,166 @@ export function serve(app, opts = {}) {
|
|
|
34
48
|
},
|
|
35
49
|
};
|
|
36
50
|
}
|
|
51
|
+
async function tryBunUpgrade(app, req, server) {
|
|
52
|
+
const url = new URL(req.url);
|
|
53
|
+
const match = app.webSocketRoutes.find(url.pathname);
|
|
54
|
+
if (!match)
|
|
55
|
+
return new Response("Not Found", { status: 404 });
|
|
56
|
+
const ctx = {
|
|
57
|
+
request: req,
|
|
58
|
+
params: match.params,
|
|
59
|
+
query: Object.fromEntries(url.searchParams.entries()),
|
|
60
|
+
headers: Object.fromEntries(req.headers.entries()),
|
|
61
|
+
state: match.handler.createState(),
|
|
62
|
+
protocols: parseSubprotocols(req.headers.get("sec-websocket-protocol")),
|
|
63
|
+
};
|
|
64
|
+
const handler = match.handler.handler;
|
|
65
|
+
let chosenProtocol = "";
|
|
66
|
+
try {
|
|
67
|
+
const decision = await handler.beforeUpgrade?.(req, ctx);
|
|
68
|
+
if (decision instanceof Response)
|
|
69
|
+
return decision;
|
|
70
|
+
if (typeof decision === "string")
|
|
71
|
+
chosenProtocol = validateSelectedSubprotocol(decision, ctx.protocols);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
if (err instanceof WebSocketProtocolError) {
|
|
75
|
+
return new Response(err.message, { status: 400 });
|
|
76
|
+
}
|
|
77
|
+
app.log.error({ err }, "WebSocket beforeUpgrade hook failed");
|
|
78
|
+
return new Response("Internal Server Error", { status: 500 });
|
|
79
|
+
}
|
|
80
|
+
const headers = {};
|
|
81
|
+
if (chosenProtocol)
|
|
82
|
+
headers["sec-websocket-protocol"] = chosenProtocol;
|
|
83
|
+
const data = { handler, ctx, protocol: chosenProtocol };
|
|
84
|
+
const ok = server.upgrade(req, { data, headers });
|
|
85
|
+
if (!ok)
|
|
86
|
+
return new Response("Upgrade Failed", { status: 500 });
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
function buildBunWebSocketConfig(app) {
|
|
90
|
+
return {
|
|
91
|
+
open(ws) {
|
|
92
|
+
const data = ws.data;
|
|
93
|
+
if (!data)
|
|
94
|
+
return;
|
|
95
|
+
const conn = new BunWebSocketConnection(ws, data.protocol);
|
|
96
|
+
data.conn = conn;
|
|
97
|
+
invokeBunHandler(app, data, "WebSocket open() handler failed", () => data.handler.open?.(conn, data.ctx), true);
|
|
98
|
+
},
|
|
99
|
+
message(ws, msg) {
|
|
100
|
+
const data = ws.data;
|
|
101
|
+
if (!data?.conn)
|
|
102
|
+
return;
|
|
103
|
+
const isBinary = typeof msg !== "string";
|
|
104
|
+
invokeBunHandler(app, data, "WebSocket message() handler failed", () => data.handler.message?.(data.conn, msg, isBinary), true);
|
|
105
|
+
},
|
|
106
|
+
close(ws, code, reason) {
|
|
107
|
+
const data = ws.data;
|
|
108
|
+
if (!data?.conn)
|
|
109
|
+
return;
|
|
110
|
+
data.conn._markClosed();
|
|
111
|
+
invokeBunHandler(app, data, "WebSocket close() handler threw", () => data.handler.close?.(data.conn, code ?? WS_CLOSE_CODE.NO_STATUS_RECEIVED, reason ?? ""));
|
|
112
|
+
},
|
|
113
|
+
drain(ws) {
|
|
114
|
+
const data = ws.data;
|
|
115
|
+
if (!data?.conn)
|
|
116
|
+
return;
|
|
117
|
+
invokeBunHandler(app, data, "WebSocket drain() handler threw", () => data.handler.drain?.(data.conn));
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
class BunWebSocketConnection {
|
|
122
|
+
ws;
|
|
123
|
+
protocol;
|
|
124
|
+
readyState = WS_READY_STATE.OPEN;
|
|
125
|
+
extensions = "";
|
|
126
|
+
data = undefined;
|
|
127
|
+
constructor(ws, protocol) {
|
|
128
|
+
this.ws = ws;
|
|
129
|
+
this.protocol = protocol;
|
|
130
|
+
}
|
|
131
|
+
get binaryType() {
|
|
132
|
+
const v = this.ws.binaryType;
|
|
133
|
+
return v === "arraybuffer" ? "arraybuffer" : "nodebuffer";
|
|
134
|
+
}
|
|
135
|
+
set binaryType(v) {
|
|
136
|
+
this.ws.binaryType = v;
|
|
137
|
+
}
|
|
138
|
+
get bufferedAmount() {
|
|
139
|
+
return this.ws.getBufferedAmount?.() ?? 0;
|
|
140
|
+
}
|
|
141
|
+
send(data) {
|
|
142
|
+
if (this.readyState !== WS_READY_STATE.OPEN)
|
|
143
|
+
return;
|
|
144
|
+
if (typeof data === "string") {
|
|
145
|
+
this.ws.send(data);
|
|
146
|
+
}
|
|
147
|
+
else if (data instanceof ArrayBuffer) {
|
|
148
|
+
this.ws.send(data);
|
|
149
|
+
}
|
|
150
|
+
else if (ArrayBuffer.isView(data)) {
|
|
151
|
+
this.ws.send(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
this.ws.send(new Uint8Array(data));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
close(code = WS_CLOSE_CODE.NORMAL_CLOSURE, reason = "") {
|
|
158
|
+
if (this.readyState >= WS_READY_STATE.CLOSING)
|
|
159
|
+
return;
|
|
160
|
+
this.readyState = WS_READY_STATE.CLOSING;
|
|
161
|
+
this.ws.close(code, reason);
|
|
162
|
+
}
|
|
163
|
+
ping(data) {
|
|
164
|
+
validateControlPayload(data);
|
|
165
|
+
this.ws.ping(toBunBinary(data));
|
|
166
|
+
}
|
|
167
|
+
pong(data) {
|
|
168
|
+
validateControlPayload(data);
|
|
169
|
+
this.ws.pong(toBunBinary(data));
|
|
170
|
+
}
|
|
171
|
+
terminate() {
|
|
172
|
+
this.readyState = WS_READY_STATE.CLOSED;
|
|
173
|
+
this.ws.terminate();
|
|
174
|
+
}
|
|
175
|
+
_markClosed() {
|
|
176
|
+
this.readyState = WS_READY_STATE.CLOSED;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
function invokeBunHandler(app, data, label, run, notifyError = false) {
|
|
180
|
+
try {
|
|
181
|
+
const result = run();
|
|
182
|
+
if (result && typeof result.then === "function") {
|
|
183
|
+
void result.catch((err) => reportBunHandlerFailure(app, data, label, err, notifyError));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
reportBunHandlerFailure(app, data, label, err, notifyError);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function reportBunHandlerFailure(app, data, label, err, notifyError) {
|
|
191
|
+
app.log.error({ err }, label);
|
|
192
|
+
if (notifyError && data.conn) {
|
|
193
|
+
invokeBunHandler(app, data, "WebSocket error() handler threw", () => data.handler.error?.(data.conn, err));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function validateControlPayload(data) {
|
|
197
|
+
if (data !== undefined &&
|
|
198
|
+
encodeSendPayload(data).payload.length > WS_MAX_CONTROL_PAYLOAD) {
|
|
199
|
+
throw new WebSocketProtocolError("Control frame payload exceeds 125 bytes");
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function toBunBinary(data) {
|
|
203
|
+
if (data === undefined)
|
|
204
|
+
return undefined;
|
|
205
|
+
if (typeof data === "string")
|
|
206
|
+
return data;
|
|
207
|
+
if (data instanceof Uint8Array)
|
|
208
|
+
return data;
|
|
209
|
+
if (ArrayBuffer.isView(data))
|
|
210
|
+
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
211
|
+
return new Uint8Array(data);
|
|
212
|
+
}
|
|
37
213
|
//# sourceMappingURL=bun.js.map
|
package/dist/adapters/bun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.js","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bun.js","sourceRoot":"","sources":["../../src/adapters/bun.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/adapters/node.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAIL,KAAK,MAAM,EACZ,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAkBrC,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2DAA2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAAG,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAAE;AAE3F,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CAmD5C"}
|