@ultimat3/http 19.0.0 → 19.1.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 +24 -0
- package/package.json +5 -5
- package/src/error-map.ts +6 -0
package/README.md
CHANGED
|
@@ -257,6 +257,30 @@ const handle = createServer({
|
|
|
257
257
|
Static paths are registered in Bun's native `routes` table; param/wildcard paths fall
|
|
258
258
|
through to `fetch`. Method resolution stays ours so a 405 still carries problem+json.
|
|
259
259
|
|
|
260
|
+
### No WebSocket upgrade on the `web` role, and no hand-written `api/` route
|
|
261
|
+
|
|
262
|
+
`As of 2026-09-05`, and stated because an app went looking for both. The `web` role's
|
|
263
|
+
`Bun.serve` is built with no `websocket` handler (`server.ts`: "the `web` role does not use one"),
|
|
264
|
+
so nothing under `/api` can `server.upgrade()` a request; and `/api/*` is a **projection** —
|
|
265
|
+
`apiRoutes()` in `@ultimat3/cli` mounts every `action` and `query` the registries hold, and
|
|
266
|
+
`x g route --surface api` does not exist (`readSurface` refuses `api` by name). A raw socket is
|
|
267
|
+
not an action, so it has no home on this role.
|
|
268
|
+
|
|
269
|
+
The framework's one WebSocket is the `sync` role's (`@ultimat3/realtime/server`, `PORT + 1`),
|
|
270
|
+
authenticated by `SyncAuthenticator` and reached from the browser through `LiveClient`. A
|
|
271
|
+
bidirectional stream — a PTY, a log tail — is written as **two halves that already exist**:
|
|
272
|
+
|
|
273
|
+
| Direction | Primitive | Why |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| server → browser | a `channel` topic on the sync socket (`ChannelHub`, `topic(...)`, `client.subscribe(topic, …)`) | ordered frames, reconnect and backpressure are the sync node's, not a second socket's |
|
|
276
|
+
| browser → server | an `action` — one call per keystroke batch | it gets a policy, a schema, rate limiting, audit and the typed client for free; a socket message gets none |
|
|
277
|
+
|
|
278
|
+
A `web`-role upgrade hook was refused rather than half-built: the pipeline returns a `Response` at
|
|
279
|
+
every stage (middleware, finalize, security headers), and an upgraded request must return
|
|
280
|
+
`undefined` from `fetch` — a second exit from the pipeline with none of its guarantees. If the two
|
|
281
|
+
halves above cannot carry a case, the fallback is a long-poll `action` (`GET`-shaped, returning
|
|
282
|
+
`{ frames, cursor }` and re-called on return), which is what the app that asked shipped.
|
|
283
|
+
|
|
260
284
|
## Inbound webhooks
|
|
261
285
|
|
|
262
286
|
`verifyWebhookSignature(request, { secret })` is the receiving half of the framework's webhook
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/http",
|
|
3
|
-
"version": "19.
|
|
3
|
+
"version": "19.1.0",
|
|
4
4
|
"description": "Owned request lifecycle over Bun.serve: router, ordered pipeline, problem+json errors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"test": "bun test"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ultimat3/core": "19.
|
|
35
|
-
"@ultimat3/i18n": "19.
|
|
36
|
-
"@ultimat3/schema": "19.
|
|
37
|
-
"@ultimat3/time": "19.
|
|
34
|
+
"@ultimat3/core": "19.1.0",
|
|
35
|
+
"@ultimat3/i18n": "19.1.0",
|
|
36
|
+
"@ultimat3/schema": "19.1.0",
|
|
37
|
+
"@ultimat3/time": "19.1.0"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/error-map.ts
CHANGED
|
@@ -141,6 +141,12 @@ export const ERROR_STATUS = {
|
|
|
141
141
|
X_INVARIANT_VIOLATED: 422,
|
|
142
142
|
X_TENANCY_UNSCOPED: 500,
|
|
143
143
|
X_DB_DRIFT: 500,
|
|
144
|
+
// Both are the server's verdict on a statement the app wrote, which is the app's fault and not
|
|
145
|
+
// the caller's: a request cannot repair a missing migration or a wrong column list.
|
|
146
|
+
X_DB_SCHEMA_STALE: 500,
|
|
147
|
+
X_DB_STATEMENT_FAILED: 500,
|
|
148
|
+
// Logged at boot, never thrown into a request; the row exists so the table stays closed.
|
|
149
|
+
X_MCP_APP_UNMOUNTED: 500,
|
|
144
150
|
// The three tenancy refusals, all 403, and all deliberately NOT the 404 `X_STORAGE_ORG_MISMATCH`
|
|
145
151
|
// takes: that one answers 404 because a 403 on a KEY the caller supplied confirms the key exists.
|
|
146
152
|
// These three name no resource and read no row — the comparison is the actor against an argument
|