@ouispec/agent-realtime 0.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/LICENSE +21 -0
- package/README.md +103 -0
- package/dist/approvals/client-event.d.ts +4 -0
- package/dist/approvals/client-event.d.ts.map +1 -0
- package/dist/approvals/client-event.js +25 -0
- package/dist/approvals/client-event.js.map +1 -0
- package/dist/approvals/routes.d.ts +19 -0
- package/dist/approvals/routes.d.ts.map +1 -0
- package/dist/approvals/routes.js +100 -0
- package/dist/approvals/routes.js.map +1 -0
- package/dist/approvals/schemas.d.ts +7 -0
- package/dist/approvals/schemas.d.ts.map +1 -0
- package/dist/approvals/schemas.js +45 -0
- package/dist/approvals/schemas.js.map +1 -0
- package/dist/approvals/store.d.ts +33 -0
- package/dist/approvals/store.d.ts.map +1 -0
- package/dist/approvals/store.js +206 -0
- package/dist/approvals/store.js.map +1 -0
- package/dist/approvals/token.d.ts +19 -0
- package/dist/approvals/token.d.ts.map +1 -0
- package/dist/approvals/token.js +73 -0
- package/dist/approvals/token.js.map +1 -0
- package/dist/client-events/builtin.d.ts +30 -0
- package/dist/client-events/builtin.d.ts.map +1 -0
- package/dist/client-events/builtin.js +161 -0
- package/dist/client-events/builtin.js.map +1 -0
- package/dist/client-events/chain.d.ts +80 -0
- package/dist/client-events/chain.d.ts.map +1 -0
- package/dist/client-events/chain.js +92 -0
- package/dist/client-events/chain.js.map +1 -0
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +85 -0
- package/dist/config.js.map +1 -0
- package/dist/events/declared.d.ts +18 -0
- package/dist/events/declared.d.ts.map +1 -0
- package/dist/events/declared.js +30 -0
- package/dist/events/declared.js.map +1 -0
- package/dist/events/settlements.d.ts +28 -0
- package/dist/events/settlements.d.ts.map +1 -0
- package/dist/events/settlements.js +29 -0
- package/dist/events/settlements.js.map +1 -0
- package/dist/http/routes.d.ts +91 -0
- package/dist/http/routes.d.ts.map +1 -0
- package/dist/http/routes.js +290 -0
- package/dist/http/routes.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +14 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +22 -0
- package/dist/logger.js.map +1 -0
- package/dist/oui/results.d.ts +46 -0
- package/dist/oui/results.d.ts.map +1 -0
- package/dist/oui/results.js +56 -0
- package/dist/oui/results.js.map +1 -0
- package/dist/redis-waits.d.ts +32 -0
- package/dist/redis-waits.d.ts.map +1 -0
- package/dist/redis-waits.js +62 -0
- package/dist/redis-waits.js.map +1 -0
- package/dist/rooms/join.d.ts +13 -0
- package/dist/rooms/join.d.ts.map +1 -0
- package/dist/rooms/join.js +27 -0
- package/dist/rooms/join.js.map +1 -0
- package/dist/rooms/room-token.d.ts +19 -0
- package/dist/rooms/room-token.d.ts.map +1 -0
- package/dist/rooms/room-token.js +55 -0
- package/dist/rooms/room-token.js.map +1 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +168 -0
- package/dist/server.js.map +1 -0
- package/dist/testing/index.d.ts +7 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +87 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types.d.ts +135 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @ouispec/agent-realtime/testing — what a product's tests need to
|
|
3
|
+
* run the real server: a Redis to meet in.
|
|
4
|
+
*
|
|
5
|
+
* `REDIS_URL` names one (CI runs a Redis service); otherwise a private
|
|
6
|
+
* `redis-server` is started on a free port and stopped afterwards. Neither
|
|
7
|
+
* available is an error, never a skipped test: the server cannot run without
|
|
8
|
+
* Redis, so neither can a test of it.
|
|
9
|
+
*/
|
|
10
|
+
import { spawn } from 'node:child_process';
|
|
11
|
+
import net from 'node:net';
|
|
12
|
+
function freePort() {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const srv = net.createServer();
|
|
15
|
+
srv.once('error', reject);
|
|
16
|
+
srv.listen(0, '127.0.0.1', () => {
|
|
17
|
+
const { port } = srv.address();
|
|
18
|
+
srv.close(() => resolve(port));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function reachable(host, port, timeoutMs) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
const socket = net.connect({ host, port });
|
|
25
|
+
const done = (ok) => {
|
|
26
|
+
socket.destroy();
|
|
27
|
+
resolve(ok);
|
|
28
|
+
};
|
|
29
|
+
socket.setTimeout(timeoutMs, () => done(false));
|
|
30
|
+
socket.once('connect', () => done(true));
|
|
31
|
+
socket.once('error', () => done(false));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export async function startTestRedis() {
|
|
35
|
+
const url = process.env.REDIS_URL;
|
|
36
|
+
if (url) {
|
|
37
|
+
const parsed = new URL(url);
|
|
38
|
+
const config = {
|
|
39
|
+
host: parsed.hostname,
|
|
40
|
+
port: Number(parsed.port || 6379),
|
|
41
|
+
tls: parsed.protocol === 'rediss:',
|
|
42
|
+
...(parsed.username ? { username: decodeURIComponent(parsed.username) } : {}),
|
|
43
|
+
...(parsed.password ? { password: decodeURIComponent(parsed.password) } : {}),
|
|
44
|
+
};
|
|
45
|
+
if (!(await reachable(config.host, config.port, 2_000))) {
|
|
46
|
+
throw new Error(`REDIS_URL names ${config.host}:${config.port}, which is not reachable`);
|
|
47
|
+
}
|
|
48
|
+
return { config, stop: async () => { } };
|
|
49
|
+
}
|
|
50
|
+
const port = await freePort();
|
|
51
|
+
let child;
|
|
52
|
+
try {
|
|
53
|
+
child = spawn('redis-server', ['--port', String(port), '--bind', '127.0.0.1', '--save', '', '--appendonly', 'no'], {
|
|
54
|
+
stdio: 'ignore',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw new Error(`No REDIS_URL, and redis-server could not be started: ${String(err)}`, { cause: err });
|
|
59
|
+
}
|
|
60
|
+
const spawnError = new Promise((_, reject) => child.once('error', (err) => reject(new Error(`No REDIS_URL, and redis-server could not be started: ${err.message}`))));
|
|
61
|
+
const deadline = Date.now() + 5_000;
|
|
62
|
+
const ready = (async () => {
|
|
63
|
+
while (Date.now() < deadline) {
|
|
64
|
+
if (await reachable('127.0.0.1', port, 200))
|
|
65
|
+
return;
|
|
66
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
67
|
+
}
|
|
68
|
+
throw new Error(`redis-server on port ${port} did not accept connections within 5 s`);
|
|
69
|
+
})();
|
|
70
|
+
try {
|
|
71
|
+
await Promise.race([ready, spawnError]);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
child.kill('SIGKILL');
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
config: { host: '127.0.0.1', port, tls: false },
|
|
79
|
+
stop: () => new Promise((resolve) => {
|
|
80
|
+
if (child.exitCode !== null)
|
|
81
|
+
return resolve();
|
|
82
|
+
child.once('exit', () => resolve());
|
|
83
|
+
child.kill('SIGTERM');
|
|
84
|
+
}),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The realtime server's seams (ADR-0227 §2.2). The product supplies every one;
|
|
3
|
+
* the server refuses to start, naming the seam, when one is missing. None has
|
|
4
|
+
* a default taken from any one product.
|
|
5
|
+
*/
|
|
6
|
+
import type { EventCatalog } from '@ouispec/agent-events';
|
|
7
|
+
import type { ClientEvent } from './client-events/chain.js';
|
|
8
|
+
import type { RealtimeLogger } from './logger.js';
|
|
9
|
+
/**
|
|
10
|
+
* Auth verifier: verifies the product's own user tokens. Called once per
|
|
11
|
+
* socket, at connection; the identity it returns is the only identity any
|
|
12
|
+
* client event is authorized against.
|
|
13
|
+
*/
|
|
14
|
+
export interface AuthAdapter {
|
|
15
|
+
verify(token: string): Promise<AuthResult>;
|
|
16
|
+
}
|
|
17
|
+
export interface AuthResult {
|
|
18
|
+
userId: string;
|
|
19
|
+
accountId?: string;
|
|
20
|
+
platformAdmin?: boolean;
|
|
21
|
+
metadata?: Record<string, unknown>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Room policy: which rooms exist, which a socket is placed in by its identity,
|
|
25
|
+
* and who may join the rest.
|
|
26
|
+
*
|
|
27
|
+
* A room that `requiresToken` is joined only with a room token minted for this
|
|
28
|
+
* user and this exact room (`POST /internal/room-token`). The product decides
|
|
29
|
+
* who gets one, by running the resource's own read authorization before it
|
|
30
|
+
* asks for the token — for Closure, studio-api's `POST /realtime/room-tokens`.
|
|
31
|
+
* The server only signs and checks.
|
|
32
|
+
*/
|
|
33
|
+
export interface RoomPolicy {
|
|
34
|
+
/** A well-formed room name this product uses. Anything else is refused everywhere. */
|
|
35
|
+
isValidRoom(room: string): boolean;
|
|
36
|
+
/** The rooms a socket joins on connect, from its identity alone. It can never leave them. */
|
|
37
|
+
identityRooms(user: AuthResult): string[];
|
|
38
|
+
/** True when joining `room` needs a room token; tokens are minted only for these rooms. */
|
|
39
|
+
requiresToken(room: string): boolean;
|
|
40
|
+
/** For a room that needs no token: may this identity join it? */
|
|
41
|
+
canJoin(room: string, user: AuthResult): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** What validates a payload. Joi schemas satisfy it. */
|
|
44
|
+
export interface PayloadSchema {
|
|
45
|
+
validate(value: unknown, options?: Record<string, unknown>): {
|
|
46
|
+
value?: unknown;
|
|
47
|
+
error?: {
|
|
48
|
+
message: string;
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* An event a client may relay. With `events`, the declaration supplies the
|
|
54
|
+
* rooms it may go to and its data schema, and both fields may be left out;
|
|
55
|
+
* without them, both are required.
|
|
56
|
+
*/
|
|
57
|
+
export interface RelayRule {
|
|
58
|
+
/** The room prefix this event may be relayed to, e.g. 'avatar' for `avatar:{id}`. */
|
|
59
|
+
roomPrefix?: string;
|
|
60
|
+
/** The event's `data`. */
|
|
61
|
+
data?: PayloadSchema;
|
|
62
|
+
}
|
|
63
|
+
export interface RedisConfig {
|
|
64
|
+
host: string;
|
|
65
|
+
port: number;
|
|
66
|
+
tls: boolean;
|
|
67
|
+
username?: string;
|
|
68
|
+
password?: string;
|
|
69
|
+
}
|
|
70
|
+
export interface RoomTokenConfig {
|
|
71
|
+
/**
|
|
72
|
+
* Signs room tokens (HMAC-SHA256). At least 32 characters, one per
|
|
73
|
+
* environment, from the product's secret store. It is not the internal key:
|
|
74
|
+
* a token secret and an API key are different secrets.
|
|
75
|
+
*/
|
|
76
|
+
secret: string;
|
|
77
|
+
/** How long a token admits its holder. Default 15 minutes. */
|
|
78
|
+
ttlMs?: number;
|
|
79
|
+
}
|
|
80
|
+
export interface ApprovalsConfig {
|
|
81
|
+
/**
|
|
82
|
+
* Signs approval tokens (HS256, ADR-0228 §2.3). At least 32 characters, one
|
|
83
|
+
* per environment, from the product's secret store. It is neither the
|
|
84
|
+
* internal key nor the room-token secret: an engine that verifies approval
|
|
85
|
+
* tokens holds this key and nothing else.
|
|
86
|
+
*/
|
|
87
|
+
signingKey: string;
|
|
88
|
+
}
|
|
89
|
+
/** Everything the server needs. Every field without a `?` is a required seam. */
|
|
90
|
+
export interface RealtimeServerConfig {
|
|
91
|
+
auth: AuthAdapter;
|
|
92
|
+
roomPolicy: RoomPolicy;
|
|
93
|
+
/** Guards every internal endpoint: emit, room tokens, UI action results, approvals. */
|
|
94
|
+
internalApiKey: string;
|
|
95
|
+
roomTokens: RoomTokenConfig;
|
|
96
|
+
/** The approval store: an irreversible action runs only on an approval the user gave (ADR-0228). */
|
|
97
|
+
approvals: ApprovalsConfig;
|
|
98
|
+
/**
|
|
99
|
+
* UI action results and room fan-out across instances meet here, so a
|
|
100
|
+
* worker's wait can be served by an instance other than the client's.
|
|
101
|
+
*/
|
|
102
|
+
redis: RedisConfig;
|
|
103
|
+
/** Browser origins allowed to connect. Pass `['*']` only deliberately. */
|
|
104
|
+
corsOrigins: string[];
|
|
105
|
+
/** The port to listen on. `0` picks a free one (see `RealtimeServerInstance.port`). */
|
|
106
|
+
port: number;
|
|
107
|
+
/**
|
|
108
|
+
* The product's event declarations, with the platform's own
|
|
109
|
+
* (`createEventCatalog(PLATFORM_EVENTS, productEvents)`, ADR-0227 §2.4).
|
|
110
|
+
* Given them, `/api/emit` refuses an undeclared event, a payload its schema
|
|
111
|
+
* rejects and a room it is not declared for; a client relays only a
|
|
112
|
+
* declared notice; and every completion or failure is kept as its job's
|
|
113
|
+
* settlement (`GET /internal/events/settlements/:kind/:id`).
|
|
114
|
+
*/
|
|
115
|
+
events?: EventCatalog;
|
|
116
|
+
/**
|
|
117
|
+
* The only events a client may relay to other clients: the room prefix each
|
|
118
|
+
* may go to, and its data schema. Anything not listed is refused, and a
|
|
119
|
+
* client relays only into rooms its socket has joined. Server events (turn,
|
|
120
|
+
* UI action and job events) must never be listed; with `events`, listing
|
|
121
|
+
* one fails at start-up.
|
|
122
|
+
*/
|
|
123
|
+
relay?: Readonly<Record<string, RelayRule>>;
|
|
124
|
+
/**
|
|
125
|
+
* The product's own client events, beside the built-in `subscribe`,
|
|
126
|
+
* `unsubscribe`, `relay` and the OUI action result. Each goes through the
|
|
127
|
+
* same chain (declared, rate-limited, schema-checked, authorized).
|
|
128
|
+
*/
|
|
129
|
+
clientEvents?: readonly ClientEvent[];
|
|
130
|
+
/** Structured logger; pino satisfies it. Default: JSON lines on the console. */
|
|
131
|
+
logger?: RealtimeLogger;
|
|
132
|
+
pingInterval?: number;
|
|
133
|
+
pingTimeout?: number;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ouispec/agent-realtime",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Realtime server for agent turns and UI actions — declared client events, room tokens, the UI action result store, the approval store, declared product events and their job settlements, Redis fan-out; the product supplies auth, room policy and keys",
|
|
5
|
+
"homepage": "https://github.com/wesreid/oui/tree/main/packages/agent-realtime#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/wesreid/oui/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/wesreid/oui.git",
|
|
12
|
+
"directory": "packages/agent-realtime"
|
|
13
|
+
},
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./testing": {
|
|
24
|
+
"types": "./dist/testing/index.d.ts",
|
|
25
|
+
"import": "./dist/testing/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@socket.io/redis-adapter": "^8.3.0",
|
|
34
|
+
"cors": "^2.8.5",
|
|
35
|
+
"express": "^5.1.0",
|
|
36
|
+
"helmet": "^8.1.0",
|
|
37
|
+
"ioredis": "^5.6.0",
|
|
38
|
+
"joi": "^17.13.3",
|
|
39
|
+
"socket.io": "^4.8.0",
|
|
40
|
+
"@ouispec/agent-core": "^0.1.0",
|
|
41
|
+
"@ouispec/agent-events": "^0.1.0",
|
|
42
|
+
"oui-spec": "^0.6.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/cors": "^2.8.0",
|
|
46
|
+
"@types/express": "^5.0.0",
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"socket.io-client": "^4.7.0",
|
|
49
|
+
"typescript": "^5.8.0",
|
|
50
|
+
"vitest": "^3.2.0"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public",
|
|
54
|
+
"provenance": true
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsc -p tsconfig.build.json",
|
|
58
|
+
"typecheck": "tsc --noEmit",
|
|
59
|
+
"test": "vitest run --passWithNoTests",
|
|
60
|
+
"clean": "rm -rf dist"
|
|
61
|
+
}
|
|
62
|
+
}
|