sleepy-serv 0.20.0 → 0.22.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 +43 -5
- package/dist/cli/run.d.ts +3 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/socket.d.ts +3 -2
- package/dist/core/socket.d.ts.map +1 -1
- package/dist/core/utils.d.ts +1 -1
- package/dist/core/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/index.ts +7 -2
- package/src/cli/{dev.ts → run.ts} +11 -3
- package/src/core/index.ts +37 -21
- package/src/core/socket.ts +21 -36
- package/src/core/utils.ts +1 -1
- package/dist/cli/dev.d.ts +0 -2
- package/dist/cli/dev.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -43,12 +43,15 @@ filesystem and generate static imports for every route at load time. This
|
|
|
43
43
|
replaces the previous dynamic `import()` and `fs.readdirSync()` approach
|
|
44
44
|
and enables compatibility with `bun build --compile --bytecode`.
|
|
45
45
|
|
|
46
|
-
The plugin is loaded automatically by the CLI commands (`sleepy dev
|
|
47
|
-
`sleepy build`). If you prefer to run your entrypoint directly, preload
|
|
46
|
+
The plugin is loaded automatically by the CLI commands (`sleepy dev`,
|
|
47
|
+
`sleepy prod`, and `sleepy build`). If you prefer to run your entrypoint directly, preload
|
|
48
48
|
the plugin yourself:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
|
|
51
|
+
sleepy init # creates a new project
|
|
52
|
+
sleepy dev # runs the app (watch mode)
|
|
53
|
+
sleepy prod # runs the app (NO watch mode)
|
|
54
|
+
sleepy build # for building a single-file bundle via `bun build` (recommended)
|
|
52
55
|
```
|
|
53
56
|
|
|
54
57
|
### Return Value
|
|
@@ -473,7 +476,13 @@ const app = createApp(3000, {
|
|
|
473
476
|
|
|
474
477
|
App-level middleware is executed before any directory-level or route-level middleware.
|
|
475
478
|
|
|
476
|
-
|
|
479
|
+
When WebSocket support is enabled (`ws: true` or `ws: { ... }`), the
|
|
480
|
+
reserved `/ws` handshake routes are folded into these same chains, so
|
|
481
|
+
app-level middleware runs against them too. A catch-all validator (for
|
|
482
|
+
example a `validateSchemas` that requires a JSON body or a specific
|
|
483
|
+
header on every request) will therefore also run against the body-less
|
|
484
|
+
`/ws` handshake requests and reject them. Scope such validators below
|
|
485
|
+
the reserved paths rather than applying them app-wide.
|
|
477
486
|
|
|
478
487
|
### `hostname`
|
|
479
488
|
|
|
@@ -525,7 +534,14 @@ const app = createApp(3000, {
|
|
|
525
534
|
|
|
526
535
|
### `ws`
|
|
527
536
|
|
|
528
|
-
WebSocket
|
|
537
|
+
WebSocket support is opt-in. Pass `ws: true` to enable with defaults,
|
|
538
|
+
or pass an options object to customize behavior:
|
|
539
|
+
|
|
540
|
+
```js
|
|
541
|
+
createApp(3000, { ws: true })
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
With custom tuning and lifecycle hooks:
|
|
529
545
|
|
|
530
546
|
```js
|
|
531
547
|
const app = createApp(3000, {
|
|
@@ -540,6 +556,10 @@ const app = createApp(3000, {
|
|
|
540
556
|
})
|
|
541
557
|
```
|
|
542
558
|
|
|
559
|
+
When `ws` is omitted (or `false`), no `/ws` endpoints are registered
|
|
560
|
+
and the server does not accept WebSocket upgrades. Calling `app.ws` or
|
|
561
|
+
`req.ws` methods when WebSocket support is disabled throws an error.
|
|
562
|
+
|
|
543
563
|
- `heartbeatInterval`: how often the client should send heartbeats, in milliseconds. Sent to the client in the welcome message. Defaults to `30_000`.
|
|
544
564
|
- `dropThreshold`: how long the server waits without an inbound message before reaping the connection, in milliseconds. Defaults to `120_000`.
|
|
545
565
|
- `reclaimTtl`: how long an inactive (reaped/dropped) session stays reclaimable, in milliseconds. Defaults to `300_000`.
|
|
@@ -610,6 +630,24 @@ Equivalent to:
|
|
|
610
630
|
bun --watch --preload sleepy-serv/plugin src/index.ts
|
|
611
631
|
```
|
|
612
632
|
|
|
633
|
+
### `sleepy prod`
|
|
634
|
+
|
|
635
|
+
Starts the production server with the plugin preloaded (no watch mode):
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
sleepy prod
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
Equivalent to:
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
bun --preload sleepy-serv/plugin src/index.ts
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Use this when `bun build --compile` is not an option (e.g. dynamic
|
|
648
|
+
imports, native dependencies like `pg`, or when a single-file
|
|
649
|
+
executable is not desired).
|
|
650
|
+
|
|
613
651
|
### `sleepy build`
|
|
614
652
|
|
|
615
653
|
Produces a production build using `Bun.build()` with the plugin:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AA4BA,wBAAsB,GAAG,IAAK,OAAO,CAAC,IAAI,CAAC,CAE1C;AAED,wBAAsB,IAAI,IAAK,OAAO,CAAC,IAAI,CAAC,CAE3C"}
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAOV,WAAW,EAEX,cAAc,EAEd,UAAU,EACV,MAAM,EACP,MAAM,SAAS,CAAA;AAOhB,cAAc,UAAU,CAAA;AACxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAExE,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,eAAe,GAChB,MAAM,cAAc,CAAA;AAErB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAErE,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,cAAc,EACd,OAAO,EACP,SAAS,EACT,UAAU,EACV,eAAe,EACf,MAAM,EACN,aAAa,EACb,OAAO,EACP,WAAW,EACX,eAAe,EACf,MAAM,EACN,gBAAgB,EAChB,aAAa,EACb,gBAAgB,GACjB,MAAM,SAAS,CAAA;AAEhB,YAAY,EACV,cAAc,EACd,eAAe,EACf,iBAAiB,GAClB,MAAM,cAAc,CAAA;AAErB,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AA0B5C,KAAK,OAAO,GAAG,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEjD,MAAM,MAAM,GAAG,GAAG;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,YAAY,CAAA;IACpB,EAAE,EAAE,cAAc,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;CACf,CAAA;AAsRD,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,WAAW,EACnB,IAAI,GAAE,UAAe,GACpB,GAAG,CAqBL"}
|
package/dist/core/socket.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CloseReason } from './utils';
|
|
2
2
|
import type { WebSocketHandler } from 'bun';
|
|
3
|
-
import type { AsyncHandlerResult, HttpMethod, Request, MiddlewareChain, SocketCommands, SocketData, ActiveSession, InactiveSession,
|
|
3
|
+
import type { AsyncHandlerResult, HttpMethod, Request, MiddlewareChain, SocketCommands, SocketData, ActiveSession, InactiveSession, SocketOptions } from './utils';
|
|
4
4
|
type SocketHandler = (req: Request, res: unknown) => AsyncHandlerResult;
|
|
5
5
|
type SocketEndpoint = {
|
|
6
6
|
method: HttpMethod;
|
|
@@ -30,9 +30,10 @@ export type SocketRoute = {
|
|
|
30
30
|
segments: string[];
|
|
31
31
|
chain: MiddlewareChain;
|
|
32
32
|
};
|
|
33
|
-
export declare function buildSocketState(opts?:
|
|
33
|
+
export declare function buildSocketState(opts?: SocketOptions): SocketState;
|
|
34
34
|
export declare function buildSocketServer(routes: SocketRoute[], state: SocketState, commands: SocketCommands): WebSocketHandler<SocketData>;
|
|
35
35
|
export declare function buildSocketHandlers(state: SocketState): SocketEndpoint[];
|
|
36
|
+
export declare function buildDisabledSocketCommands(): SocketCommands;
|
|
36
37
|
export declare function buildSocketCommands(state: SocketState): SocketCommands;
|
|
37
38
|
export {};
|
|
38
39
|
//# sourceMappingURL=socket.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/core/socket.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,WAAW,EAIZ,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/core/socket.ts"],"names":[],"mappings":"AAUA,OAAO,EAGL,WAAW,EAIZ,MAAM,SAAS,CAAA;AAahB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,KAAK,CAAA;AAE3C,OAAO,KAAK,EACV,kBAAkB,EAClB,UAAU,EACV,OAAO,EACP,eAAe,EACf,cAAc,EAGd,UAAU,EAEV,aAAa,EACb,eAAe,EAEf,aAAa,EACd,MAAM,SAAS,CAAA;AAShB,KAAK,aAAa,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,KAAK,kBAAkB,CAAA;AAYvE,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,aAAa,CAAA;CACvB,CAAA;AAqBD,MAAM,MAAM,MAAM,GAAG;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC1C,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IAC9C,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;IAC3C,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,CAAA;CAClE,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,KAAK,EAAE,eAAe,CAAA;CACvB,CAAA;AAyRD,wBAAgB,gBAAgB,CAAE,IAAI,GAAE,aAAkB,GAAG,WAAW,CAavE;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,cAAc,GACvB,gBAAgB,CAAC,UAAU,CAAC,CAoJ9B;AAED,wBAAgB,mBAAmB,CAAE,KAAK,EAAE,WAAW,GAAG,cAAc,EAAE,CAwIzE;AAED,wBAAgB,2BAA2B,IAAK,cAAc,CAS7D;AAED,wBAAgB,mBAAmB,CAAE,KAAK,EAAE,WAAW,GAAG,cAAc,CAgEvE"}
|
package/dist/core/utils.d.ts
CHANGED
|
@@ -177,7 +177,7 @@ export type AppOptions = {
|
|
|
177
177
|
hostname?: string;
|
|
178
178
|
mountPath?: string;
|
|
179
179
|
middleware?: Middleware[];
|
|
180
|
-
ws?: SocketOptions;
|
|
180
|
+
ws?: boolean | SocketOptions;
|
|
181
181
|
onClose?: () => Promise<void> | void;
|
|
182
182
|
};
|
|
183
183
|
export declare function toSegments(pathString: string): string[];
|
package/dist/core/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/core/utils.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/core/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { parseArgs } from 'node:util'
|
|
4
4
|
import { init } from './init'
|
|
5
|
-
import { dev } from './dev'
|
|
6
5
|
import { build } from './build'
|
|
6
|
+
import { dev, prod } from './run'
|
|
7
7
|
|
|
8
8
|
const USAGE = `
|
|
9
9
|
Usage: sleepy <command>
|
|
@@ -11,7 +11,8 @@ Usage: sleepy <command>
|
|
|
11
11
|
Commands:
|
|
12
12
|
init Create a new sleepy-serv project
|
|
13
13
|
dev Start the dev server (watch mode)
|
|
14
|
-
|
|
14
|
+
prod Start the production server
|
|
15
|
+
build Build for production (single-file executable)
|
|
15
16
|
|
|
16
17
|
Options:
|
|
17
18
|
--help Show this help message
|
|
@@ -43,6 +44,10 @@ switch (command) {
|
|
|
43
44
|
await dev()
|
|
44
45
|
break
|
|
45
46
|
|
|
47
|
+
case 'prod':
|
|
48
|
+
await prod()
|
|
49
|
+
break
|
|
50
|
+
|
|
46
51
|
case 'build':
|
|
47
52
|
await build()
|
|
48
53
|
break
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs'
|
|
2
2
|
import { loadConfig } from '../plugin/config'
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
async function run (watch: boolean): Promise<void> {
|
|
5
5
|
const config = await loadConfig()
|
|
6
6
|
const entrypoint = config.app?.entrypoint ?? './src/index.ts'
|
|
7
7
|
|
|
@@ -12,10 +12,10 @@ export async function dev (): Promise<void> {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
const proc = Bun.spawn([
|
|
15
|
-
'bun', '--watch',
|
|
15
|
+
'bun', watch ? '--watch' : '',
|
|
16
16
|
'--preload', 'sleepy-serv/plugin',
|
|
17
17
|
entrypoint,
|
|
18
|
-
], {
|
|
18
|
+
].filter(Boolean), {
|
|
19
19
|
stdout: 'inherit',
|
|
20
20
|
stderr: 'inherit',
|
|
21
21
|
stdin: 'inherit',
|
|
@@ -25,3 +25,11 @@ export async function dev (): Promise<void> {
|
|
|
25
25
|
|
|
26
26
|
process.exit(code)
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
export async function dev (): Promise<void> {
|
|
30
|
+
await run(true)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function prod (): Promise<void> {
|
|
34
|
+
await run(false)
|
|
35
|
+
}
|
package/src/core/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
buildSocketServer,
|
|
14
14
|
buildSocketHandlers,
|
|
15
15
|
buildSocketCommands,
|
|
16
|
+
buildDisabledSocketCommands,
|
|
16
17
|
} from './socket'
|
|
17
18
|
|
|
18
19
|
import {
|
|
@@ -34,6 +35,7 @@ import type {
|
|
|
34
35
|
RouteConfig,
|
|
35
36
|
RouteDefinition,
|
|
36
37
|
SocketCommands,
|
|
38
|
+
SocketOptions,
|
|
37
39
|
AppOptions,
|
|
38
40
|
Server,
|
|
39
41
|
} from './utils'
|
|
@@ -131,6 +133,20 @@ function defaultMethodMap (): Record<string, EndpointHandler> {
|
|
|
131
133
|
}
|
|
132
134
|
}
|
|
133
135
|
|
|
136
|
+
function resolveSocketOptions (
|
|
137
|
+
ws: boolean | SocketOptions | undefined,
|
|
138
|
+
): SocketOptions | null {
|
|
139
|
+
if (!ws) {
|
|
140
|
+
return null
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (ws === true) {
|
|
144
|
+
return {}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return ws
|
|
148
|
+
}
|
|
149
|
+
|
|
134
150
|
function buildEndpointRequest (
|
|
135
151
|
bunReq: BunRequest,
|
|
136
152
|
server: Server,
|
|
@@ -162,9 +178,7 @@ function buildEndpointRequest (
|
|
|
162
178
|
}
|
|
163
179
|
}
|
|
164
180
|
|
|
165
|
-
function normalizeChain (
|
|
166
|
-
route: RouteDefinition,
|
|
167
|
-
): ChainRoute {
|
|
181
|
+
function normalizeChain (route: RouteDefinition): ChainRoute {
|
|
168
182
|
const chain = Array.isArray(route.chain)
|
|
169
183
|
? route.chain
|
|
170
184
|
: [route.chain]
|
|
@@ -268,7 +282,7 @@ function buildOutputRoutes (moduleRoutes: ModuleRoute[]): OutputRoutes {
|
|
|
268
282
|
|
|
269
283
|
function buildRoutes (
|
|
270
284
|
config: RouteConfig,
|
|
271
|
-
state: SocketState,
|
|
285
|
+
state: SocketState | null,
|
|
272
286
|
ws: SocketCommands,
|
|
273
287
|
opts: AppOptions,
|
|
274
288
|
): AppRoutes {
|
|
@@ -294,13 +308,9 @@ function buildRoutes (
|
|
|
294
308
|
}
|
|
295
309
|
})
|
|
296
310
|
|
|
297
|
-
const mergedRoutes =
|
|
298
|
-
normalRoutes,
|
|
299
|
-
|
|
300
|
-
meta,
|
|
301
|
-
state,
|
|
302
|
-
mountPath,
|
|
303
|
-
)
|
|
311
|
+
const mergedRoutes = state
|
|
312
|
+
? buildMergedRoutes(normalRoutes, middleware, meta, state, mountPath)
|
|
313
|
+
: normalRoutes
|
|
304
314
|
|
|
305
315
|
const socketRoutes = buildSocketRoutes(mergedRoutes)
|
|
306
316
|
const moduleRoutes = buildModuleRoutes(socketRoutes, ws)
|
|
@@ -317,23 +327,21 @@ function buildRoutes (
|
|
|
317
327
|
function buildServer (
|
|
318
328
|
port: number,
|
|
319
329
|
routes: AppRoutes,
|
|
320
|
-
state: SocketState,
|
|
330
|
+
state: SocketState | null,
|
|
321
331
|
ws: SocketCommands,
|
|
322
332
|
opts: AppOptions,
|
|
323
333
|
): Server {
|
|
324
334
|
const hostname = opts.hostname || '0.0.0.0'
|
|
325
335
|
|
|
326
|
-
const
|
|
327
|
-
routes.socket,
|
|
328
|
-
|
|
329
|
-
ws,
|
|
330
|
-
)
|
|
336
|
+
const websocket = state
|
|
337
|
+
? buildSocketServer(routes.socket, state, ws)
|
|
338
|
+
: undefined
|
|
331
339
|
|
|
332
340
|
return Bun.serve({
|
|
333
341
|
port,
|
|
334
342
|
hostname,
|
|
335
343
|
routes: routes.server,
|
|
336
|
-
websocket:
|
|
344
|
+
...(websocket ? { websocket } : {}),
|
|
337
345
|
async fetch (_req, _server) {
|
|
338
346
|
throw new NotFoundError()
|
|
339
347
|
},
|
|
@@ -346,7 +354,7 @@ function buildServer (
|
|
|
346
354
|
|
|
347
355
|
return Response.json(httpError.output, { status })
|
|
348
356
|
},
|
|
349
|
-
})
|
|
357
|
+
}) as Server
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
function processIO (server: Server, opts: AppOptions): CloseFn {
|
|
@@ -391,8 +399,16 @@ export function createApp (
|
|
|
391
399
|
config: RouteConfig,
|
|
392
400
|
opts: AppOptions = {},
|
|
393
401
|
): App {
|
|
394
|
-
const
|
|
395
|
-
|
|
402
|
+
const socketOpts = resolveSocketOptions(opts.ws)
|
|
403
|
+
|
|
404
|
+
const state = socketOpts
|
|
405
|
+
? buildSocketState(socketOpts)
|
|
406
|
+
: null
|
|
407
|
+
|
|
408
|
+
const ws = state
|
|
409
|
+
? buildSocketCommands(state)
|
|
410
|
+
: buildDisabledSocketCommands()
|
|
411
|
+
|
|
396
412
|
const routes = buildRoutes(config, state, ws, opts)
|
|
397
413
|
const server = buildServer(port, routes, state, ws, opts)
|
|
398
414
|
const close = processIO(server, opts)
|
package/src/core/socket.ts
CHANGED
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
|
|
20
20
|
import {
|
|
21
21
|
RequestError,
|
|
22
|
-
BadRequestError,
|
|
23
22
|
NotFoundError,
|
|
24
23
|
UnauthorizedError,
|
|
25
24
|
MethodNotAllowedError,
|
|
@@ -44,7 +43,7 @@ import type {
|
|
|
44
43
|
ActiveSession,
|
|
45
44
|
InactiveSession,
|
|
46
45
|
Session,
|
|
47
|
-
|
|
46
|
+
SocketOptions,
|
|
48
47
|
} from './utils'
|
|
49
48
|
|
|
50
49
|
import type {
|
|
@@ -240,30 +239,6 @@ function parseMessage (raw: string | Buffer): RawMessage | undefined {
|
|
|
240
239
|
}
|
|
241
240
|
}
|
|
242
241
|
|
|
243
|
-
async function parseJsonBody (req: Request): Promise<unknown> {
|
|
244
|
-
try {
|
|
245
|
-
const body = await req.json()
|
|
246
|
-
|
|
247
|
-
return body
|
|
248
|
-
} catch {
|
|
249
|
-
throw new BadRequestError('Invalid JSON')
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
async function parseJsonBodyAppData (req: Request): Promise<unknown> {
|
|
254
|
-
const contentType = req.headers.get('content-type')
|
|
255
|
-
const usingJsonBody = contentType?.startsWith('application/json')
|
|
256
|
-
|
|
257
|
-
if (!usingJsonBody) {
|
|
258
|
-
return null
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const rawBody = await parseJsonBody(req)
|
|
262
|
-
const appData = (rawBody as Record<string, unknown> | null)?.data ?? null
|
|
263
|
-
|
|
264
|
-
return appData
|
|
265
|
-
}
|
|
266
|
-
|
|
267
242
|
function sweepInactiveSessions (state: SocketState): void {
|
|
268
243
|
for (const [key, session] of state.inactiveSessions) {
|
|
269
244
|
if (!isSessionActive(session)) {
|
|
@@ -420,18 +395,18 @@ function getCloseReason (ws: SocketConnection, code: number): CloseReason {
|
|
|
420
395
|
return CloseReason.Dropped
|
|
421
396
|
}
|
|
422
397
|
|
|
423
|
-
export function buildSocketState (opts:
|
|
398
|
+
export function buildSocketState (opts: SocketOptions = {}): SocketState {
|
|
424
399
|
return {
|
|
425
|
-
dropThreshold: opts.
|
|
426
|
-
heartbeatInterval: opts.
|
|
427
|
-
maxTickets: opts.
|
|
428
|
-
reclaimTtl: opts.
|
|
429
|
-
ticketTtl: opts.
|
|
400
|
+
dropThreshold: opts.dropThreshold ?? 120_000,
|
|
401
|
+
heartbeatInterval: opts.heartbeatInterval ?? 30_000,
|
|
402
|
+
maxTickets: opts.maxTickets ?? 100_000,
|
|
403
|
+
reclaimTtl: opts.reclaimTtl ?? 300_000,
|
|
404
|
+
ticketTtl: opts.ticketTtl ?? 10_000,
|
|
430
405
|
tickets: new Map(),
|
|
431
406
|
activeSessions: new Map(),
|
|
432
407
|
inactiveSessions: new Map(),
|
|
433
|
-
onOpen: opts.
|
|
434
|
-
onClose: opts.
|
|
408
|
+
onOpen: opts.onOpen ?? null,
|
|
409
|
+
onClose: opts.onClose ?? null,
|
|
435
410
|
}
|
|
436
411
|
}
|
|
437
412
|
|
|
@@ -677,8 +652,7 @@ export function buildSocketHandlers (state: SocketState): SocketEndpoint[] {
|
|
|
677
652
|
validateSchema(req, createTicketValidator)
|
|
678
653
|
|
|
679
654
|
const clientId = crypto.randomUUID()
|
|
680
|
-
const
|
|
681
|
-
const ticket = issueTicket(clientId, appData)
|
|
655
|
+
const ticket = issueTicket(clientId, res)
|
|
682
656
|
|
|
683
657
|
return Response.json({
|
|
684
658
|
clientId,
|
|
@@ -728,6 +702,17 @@ export function buildSocketHandlers (state: SocketState): SocketEndpoint[] {
|
|
|
728
702
|
]
|
|
729
703
|
}
|
|
730
704
|
|
|
705
|
+
export function buildDisabledSocketCommands (): SocketCommands {
|
|
706
|
+
const msg = 'WebSocket support is not enabled'
|
|
707
|
+
|
|
708
|
+
return {
|
|
709
|
+
broadcast () { throw new Error(msg) },
|
|
710
|
+
send () { throw new Error(msg) },
|
|
711
|
+
drop () { throw new Error(msg) },
|
|
712
|
+
query () { throw new Error(msg) },
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
|
|
731
716
|
export function buildSocketCommands (state: SocketState): SocketCommands {
|
|
732
717
|
function sendToClient (clientId: string, event: string, body: unknown) {
|
|
733
718
|
const session = state.activeSessions.get(clientId)
|
package/src/core/utils.ts
CHANGED
package/dist/cli/dev.d.ts
DELETED
package/dist/cli/dev.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/cli/dev.ts"],"names":[],"mappings":"AAGA,wBAAsB,GAAG,IAAK,OAAO,CAAC,IAAI,CAAC,CAuB1C"}
|