@owlmeans/server-socket 0.1.18-rc.2 → 0.1.18-rc.21
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 +14 -9
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-socket/SKILL.md +17 -22
- package/build/helper.d.ts +4 -2
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +15 -0
- package/build/helper.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +4 -6
- package/build/service.js.map +1 -1
- package/package.json +10 -10
- package/src/helper.ts +37 -2
- package/src/service.ts +5 -7
- package/build/.gitkeep +0 -0
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Server-side WebSocket connection handler and service for OwlMeans backends.
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
- `
|
|
7
|
+
- `connection(protocol, callback)` creates a typed WebSocket binding for one protocol
|
|
8
8
|
- `appendSocketService()` + `createSocketMiddleware()` wire the WebSocket service into a server context
|
|
9
9
|
- Used in viable for real-time thinking journal updates and file watching
|
|
10
10
|
- The `Connection` interface (from `@owlmeans/socket`) is the runtime object passed to your handler
|
|
@@ -12,18 +12,20 @@ Server-side WebSocket connection handler and service for OwlMeans backends.
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
bun add @owlmeans/server-socket
|
|
15
|
+
bun add @owlmeans/server-socket@^0.1.18-rc.17
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
Handle a WebSocket connection on
|
|
20
|
+
Handle a WebSocket connection on an entrypoint route:
|
|
21
21
|
|
|
22
22
|
```typescript
|
|
23
|
-
import {
|
|
23
|
+
import { connection } from '@owlmeans/server-socket'
|
|
24
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
24
25
|
import type { Connection } from '@owlmeans/socket'
|
|
26
|
+
import { appEntrypoints as protocols } from 'my-app-common'
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
const watch = connection(protocols.api.fileWatch, async (conn, context, req) => {
|
|
27
29
|
const ctx = context as Context
|
|
28
30
|
const projectId = req.params.id as string
|
|
29
31
|
|
|
@@ -33,17 +35,20 @@ export const watch = handleConnection<Connection>(async (conn, context, req) =>
|
|
|
33
35
|
})
|
|
34
36
|
|
|
35
37
|
// Push updates to the client
|
|
36
|
-
const
|
|
38
|
+
const unsubscribeStore = await ctx.fileStore().subscribe(record => {
|
|
37
39
|
conn.notify('file-update', record)
|
|
38
40
|
})
|
|
39
41
|
})
|
|
42
|
+
|
|
43
|
+
export const entrypoints = [bind(protocols.api.fileWatch, watch)]
|
|
40
44
|
```
|
|
41
45
|
|
|
42
46
|
## API
|
|
43
47
|
|
|
44
|
-
### `
|
|
48
|
+
### `connection(protocol, handler): BoundEntrypointHandler`
|
|
45
49
|
|
|
46
|
-
|
|
50
|
+
Creates a protocol-bound WebSocket handler. The callback receives `(conn, ctx, req, res)` with
|
|
51
|
+
request and response types inferred from the protocol.
|
|
47
52
|
|
|
48
53
|
```typescript
|
|
49
54
|
handler: (conn: T, ctx: Context, req: AbstractRequest, res: AbstractResponse) => Promise<void>
|
|
@@ -73,7 +78,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
73
78
|
your project's skill store (`.agents/skills/`):
|
|
74
79
|
|
|
75
80
|
```sh
|
|
76
|
-
npx @owlmeans/agent-skills
|
|
81
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.15
|
|
77
82
|
```
|
|
78
83
|
|
|
79
84
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/server-socket",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.21",
|
|
5
|
+
"generatedAt": "2026-09-12T08:39:52.732Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -1,32 +1,27 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: server-socket
|
|
3
|
-
description:
|
|
4
|
-
user-invocable: false
|
|
3
|
+
description: Bind OwlMeans socket protocol declarations to Fastify WebSocket handlers.
|
|
5
4
|
---
|
|
6
5
|
<!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
|
|
7
6
|
|
|
8
|
-
#
|
|
7
|
+
# Socket protocol handlers
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
Declare a socket route and its contract in the shared protocol package. Bind it on the server with
|
|
10
|
+
`connection()` and `bind()`.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
```ts
|
|
13
|
+
import { bind } from '@owlmeans/server-entrypoint'
|
|
14
|
+
import { connection } from '@owlmeans/server-socket'
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
## Usage
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
import { makeSocketService } from '@owlmeans/server-socket'
|
|
26
|
-
context.registerService(makeSocketService())
|
|
16
|
+
export const appEntrypoints = [
|
|
17
|
+
bind(streamEntrypoints.watch, connection(streamEntrypoints.watch,
|
|
18
|
+
async (connection, context, request) => {
|
|
19
|
+
await connection.send({ type: 'ready' })
|
|
20
|
+
}
|
|
21
|
+
)),
|
|
22
|
+
]
|
|
27
23
|
```
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- `@fastify/websocket` (runtime)
|
|
25
|
+
The handler receives a typed connection, context, request and response boundary. Guards and gates
|
|
26
|
+
are inherited from the protocol tree and enforced before the WebSocket handler runs. Do not expose
|
|
27
|
+
Fastify request objects through a shared contract.
|
package/build/helper.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { AbstractRequest, AbstractResponse } from '@owlmeans/entrypoint';
|
|
1
|
+
import type { AbstractRequest, AbstractResponse, EntrypointProtocolDeclaration, HandlerRequest, RequestOf, ResponseOf } from '@owlmeans/entrypoint';
|
|
2
2
|
import type { Context } from '@owlmeans/server-api';
|
|
3
|
-
import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
|
|
3
|
+
import type { BoundEntrypointHandler, RefedEntrypointHandler } from '@owlmeans/server-entrypoint';
|
|
4
4
|
import type { Connection } from '@owlmeans/socket';
|
|
5
5
|
import type { WebSocket } from '@fastify/websocket';
|
|
6
|
+
/** Bind a socket protocol to its connection lifecycle without an alias lookup. */
|
|
7
|
+
export declare const connection: <Protocol extends EntrypointProtocolDeclaration, SocketContext extends Context = Context, SocketConnection extends Connection = Connection>(protocol: Protocol, handler: (connection: SocketConnection, context: SocketContext, request: HandlerRequest<RequestOf<Protocol>>, response: AbstractResponse<ResponseOf<Protocol>>) => Promise<void>) => BoundEntrypointHandler<Protocol>;
|
|
6
8
|
export declare const handleConnection: <T extends Connection = Connection>(handler: (conn: T, ctx: Context, req: AbstractRequest<WebSocket>, res: AbstractResponse<any>) => Promise<void>) => RefedEntrypointHandler<AbstractResponse<any>>;
|
|
7
9
|
//# sourceMappingURL=helper.d.ts.map
|
package/build/helper.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EACxG,MAAM,sBAAsB,CAAA;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AACnD,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACjG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAA;AAGnD,kFAAkF;AAClF,eAAO,MAAM,UAAU,GACrB,QAAQ,SAAS,6BAA6B,EAC9C,aAAa,SAAS,OAAO,GAAG,OAAO,EACvC,gBAAgB,SAAS,UAAU,GAAG,UAAU,YAEtC,QAAQ,WACT,CACP,UAAU,EAAE,gBAAgB,EAC5B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,cAAc,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAC5C,QAAQ,EAAE,gBAAgB,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,KAC7C,OAAO,CAAC,IAAI,CAAC,KACjB,sBAAsB,CAAC,QAAQ,CAkBhC,CAAA;AAEF,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAC/D,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,gBAAgB,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,KAC3G,sBAAsB,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAUhD,CAAA"}
|
package/build/helper.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { assertContext } from '@owlmeans/context';
|
|
2
2
|
import { makeConnection } from './utils/connection.js';
|
|
3
|
+
/** Bind a socket protocol to its connection lifecycle without an alias lookup. */
|
|
4
|
+
export const connection = (protocol, handler) => ({
|
|
5
|
+
protocol,
|
|
6
|
+
bind: ref => async (request, response) => {
|
|
7
|
+
const context = assertContext(ref.ref?.ctx, protocol.alias);
|
|
8
|
+
try {
|
|
9
|
+
await handler(makeConnection(request, context), context, request, response);
|
|
10
|
+
response.resolve(undefined);
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
response.reject(error);
|
|
14
|
+
}
|
|
15
|
+
return response.value;
|
|
16
|
+
},
|
|
17
|
+
});
|
|
3
18
|
export const handleConnection = handler => ref => async (req, res) => {
|
|
4
19
|
const ctx = assertContext(ref.ref?.ctx);
|
|
5
20
|
try {
|
package/build/helper.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAQjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,CAKxB,QAAkB,EAClB,OAKkB,EACgB,EAAE,CAAC,CAAC;IACtC,QAAQ;IACR,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE;QACvC,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,KAAK,CAAkB,CAAA;QAC5E,IAAI,CAAC;YACH,MAAM,OAAO,CACX,cAAc,CAAC,OAAqC,EAAE,OAAO,CAAqB,EAClF,OAAO,EACP,OAAyD,EACzD,QAAkD,CACnD,CAAA;YACD,QAAQ,CAAC,OAAO,CAAC,SAAiC,CAAC,CAAA;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,MAAM,CAAC,KAAc,CAAC,CAAA;QACjC,CAAC;QAED,OAAO,QAAQ,CAAC,KAAK,CAAA;IACvB,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAEwB,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACxF,MAAM,GAAG,GAAG,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAY,CAAA;IAClD,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,cAAc,CAAC,GAAG,EAAE,GAAG,CAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;IAC/D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,CAAU,CAAC,CAAA;IACxB,CAAC;IAED,yDAAyD;IACzD,OAAO,GAAG,CAAC,KAAK,CAAA;AAClB,CAAC,CAAA"}
|
package/build/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAW,MAAM,sBAAsB,CAAA;AAWpE,eAAO,MAAM,mBAAmB,WAAW,MAAM,KAAmB,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAW,MAAM,sBAAsB,CAAA;AAWpE,eAAO,MAAM,mBAAmB,WAAW,MAAM,KAAmB,aA0GnE,CAAA;AAED,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,OACnE,CAAC,UAAS,MAAM,KACpB,CAOF,CAAA"}
|
package/build/service.js
CHANGED
|
@@ -20,8 +20,7 @@ export const createSocketService = (alias = DEFAULT_ALIAS) => {
|
|
|
20
20
|
.filter(module => canServerModule(context, module) && !module.route.isIntermediate())
|
|
21
21
|
.reduce(async (ctx, module) => {
|
|
22
22
|
let context = await ctx;
|
|
23
|
-
|
|
24
|
-
if (!module.route.match(req)) {
|
|
23
|
+
if (!module.route.match(req, module.mount())) {
|
|
25
24
|
return context;
|
|
26
25
|
}
|
|
27
26
|
if (reply.sent) {
|
|
@@ -55,12 +54,11 @@ export const createSocketService = (alias = DEFAULT_ALIAS) => {
|
|
|
55
54
|
return context;
|
|
56
55
|
}, Promise.resolve(context));
|
|
57
56
|
});
|
|
58
|
-
|
|
59
|
-
await module.resolve();
|
|
57
|
+
ctx.entrypoints().filter(module => canServerModule(ctx, module) && !module.route.isIntermediate()).forEach(module => {
|
|
60
58
|
if (module.handle == null) {
|
|
61
59
|
return;
|
|
62
60
|
}
|
|
63
|
-
server.get(module.
|
|
61
|
+
server.get(module.mount(), {
|
|
64
62
|
schema: {
|
|
65
63
|
querystring: module.filter?.query ?? {},
|
|
66
64
|
params: module.filter?.params ?? {},
|
|
@@ -92,7 +90,7 @@ export const createSocketService = (alias = DEFAULT_ALIAS) => {
|
|
|
92
90
|
}
|
|
93
91
|
});
|
|
94
92
|
});
|
|
95
|
-
})
|
|
93
|
+
});
|
|
96
94
|
});
|
|
97
95
|
}
|
|
98
96
|
}, service => async () => {
|
package/build/service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE3C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AACrI,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAK,GAAW,aAAa,EAAiB,EAAE;IAClF,MAAM,OAAO,GAAkB,aAAa,CAAgB,KAAK,EAAE;QACjE,MAAM,EAAE,KAAK,EAAC,GAAG,EAAC,EAAE;YAClB,MAAM,cAAc,GAAuB,EAAE,CAAA;YAC7C,MAAM,GAAG,GAAG,aAAa,CAAkB,OAAO,CAAC,GAAc,EAAE,KAAK,CAAC,CAAA;YACzE,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE;gBAC1C,QAAQ,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;aAC/D,CAAC,CAAA;YAEF,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAC,MAAM,EAAC,EAAE;gBACvC,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;oBAChD,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,GAAc,EAAE,KAAK,CAAC,CAAA;oBAClE,MAAM,OAAO,EAAE,WAAW,EAA6B;yBACpD,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,CAAC;yBACpF,MAAM,CAAmB,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;wBAC9C,IAAI,OAAO,GAAG,MAAM,GAAG,CAAA;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/server-socket",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.21",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@fastify/websocket": "^11.0.1",
|
|
34
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/basic-envelope": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
37
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
38
|
-
"@owlmeans/server-api": "^0.1.18-rc.
|
|
39
|
-
"@owlmeans/server-auth": "^0.1.18-rc.
|
|
40
|
-
"@owlmeans/server-context": "^0.1.18-rc.
|
|
41
|
-
"@owlmeans/server-entrypoint": "^0.1.18-rc.
|
|
42
|
-
"@owlmeans/socket": "^0.1.18-rc.
|
|
34
|
+
"@owlmeans/auth": "^0.1.18-rc.12",
|
|
35
|
+
"@owlmeans/basic-envelope": "^0.1.18-rc.15",
|
|
36
|
+
"@owlmeans/context": "^0.1.18-rc.11",
|
|
37
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.14",
|
|
38
|
+
"@owlmeans/server-api": "^0.1.18-rc.20",
|
|
39
|
+
"@owlmeans/server-auth": "^0.1.18-rc.21",
|
|
40
|
+
"@owlmeans/server-context": "^0.1.18-rc.15",
|
|
41
|
+
"@owlmeans/server-entrypoint": "^0.1.18-rc.14",
|
|
42
|
+
"@owlmeans/socket": "^0.1.18-rc.12"
|
|
43
43
|
},
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
package/src/helper.ts
CHANGED
|
@@ -1,11 +1,46 @@
|
|
|
1
1
|
import { assertContext } from '@owlmeans/context'
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
AbstractRequest, AbstractResponse, EntrypointProtocolDeclaration, HandlerRequest, RequestOf, ResponseOf,
|
|
4
|
+
} from '@owlmeans/entrypoint'
|
|
3
5
|
import type { Context } from '@owlmeans/server-api'
|
|
4
|
-
import type { RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
|
|
6
|
+
import type { BoundEntrypointHandler, RefedEntrypointHandler } from '@owlmeans/server-entrypoint'
|
|
5
7
|
import type { Connection } from '@owlmeans/socket'
|
|
6
8
|
import type { WebSocket } from '@fastify/websocket'
|
|
7
9
|
import { makeConnection } from './utils/connection.js'
|
|
8
10
|
|
|
11
|
+
/** Bind a socket protocol to its connection lifecycle without an alias lookup. */
|
|
12
|
+
export const connection = <
|
|
13
|
+
Protocol extends EntrypointProtocolDeclaration,
|
|
14
|
+
SocketContext extends Context = Context,
|
|
15
|
+
SocketConnection extends Connection = Connection,
|
|
16
|
+
>(
|
|
17
|
+
protocol: Protocol,
|
|
18
|
+
handler: (
|
|
19
|
+
connection: SocketConnection,
|
|
20
|
+
context: SocketContext,
|
|
21
|
+
request: HandlerRequest<RequestOf<Protocol>>,
|
|
22
|
+
response: AbstractResponse<ResponseOf<Protocol>>,
|
|
23
|
+
) => Promise<void>,
|
|
24
|
+
): BoundEntrypointHandler<Protocol> => ({
|
|
25
|
+
protocol,
|
|
26
|
+
bind: ref => async (request, response) => {
|
|
27
|
+
const context = assertContext(ref.ref?.ctx, protocol.alias) as SocketContext
|
|
28
|
+
try {
|
|
29
|
+
await handler(
|
|
30
|
+
makeConnection(request as AbstractRequest<WebSocket>, context) as SocketConnection,
|
|
31
|
+
context,
|
|
32
|
+
request as unknown as HandlerRequest<RequestOf<Protocol>>,
|
|
33
|
+
response as AbstractResponse<ResponseOf<Protocol>>,
|
|
34
|
+
)
|
|
35
|
+
response.resolve(undefined as ResponseOf<Protocol>)
|
|
36
|
+
} catch (error) {
|
|
37
|
+
response.reject(error as Error)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return response.value
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
|
|
9
44
|
export const handleConnection: <T extends Connection = Connection>(
|
|
10
45
|
handler: (conn: T, ctx: Context, req: AbstractRequest<WebSocket>, res: AbstractResponse<any>) => Promise<void>
|
|
11
46
|
) => RefedEntrypointHandler<AbstractResponse<any>> = handler => ref => async (req, res) => {
|
package/src/service.ts
CHANGED
|
@@ -27,9 +27,8 @@ export const createSocketService = (alias: string = DEFAULT_ALIAS): SocketServic
|
|
|
27
27
|
.filter(module => canServerModule(context, module) && !module.route.isIntermediate())
|
|
28
28
|
.reduce<Promise<Context>>(async (ctx, module) => {
|
|
29
29
|
let context = await ctx
|
|
30
|
-
await module.resolve()
|
|
31
30
|
|
|
32
|
-
if (!module.route.match(req)) {
|
|
31
|
+
if (!module.route.match(req, module.mount())) {
|
|
33
32
|
return context
|
|
34
33
|
}
|
|
35
34
|
|
|
@@ -68,15 +67,14 @@ export const createSocketService = (alias: string = DEFAULT_ALIAS): SocketServic
|
|
|
68
67
|
}, Promise.resolve(context))
|
|
69
68
|
})
|
|
70
69
|
|
|
71
|
-
|
|
70
|
+
ctx.entrypoints<ServerEntrypoint<Request>>().filter(
|
|
72
71
|
module => canServerModule(ctx, module) && !module.route.isIntermediate()
|
|
73
|
-
).
|
|
74
|
-
await module.resolve()
|
|
72
|
+
).forEach(module => {
|
|
75
73
|
if (module.handle == null) {
|
|
76
74
|
return
|
|
77
75
|
}
|
|
78
76
|
|
|
79
|
-
server.get(module.
|
|
77
|
+
server.get(module.mount(), {
|
|
80
78
|
schema: {
|
|
81
79
|
querystring: module.filter?.query ?? {},
|
|
82
80
|
params: module.filter?.params ?? {},
|
|
@@ -111,7 +109,7 @@ export const createSocketService = (alias: string = DEFAULT_ALIAS): SocketServic
|
|
|
111
109
|
}
|
|
112
110
|
})
|
|
113
111
|
})
|
|
114
|
-
})
|
|
112
|
+
})
|
|
115
113
|
})
|
|
116
114
|
}
|
|
117
115
|
}, service => async () => {
|
package/build/.gitkeep
DELETED
|
File without changes
|