acrylblends 0.9.2 → 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/dist/index.js.map +1 -1
- package/docs/framework/cordis/node-server.md +25 -3
- package/lib/bun.d.ts +1 -1
- package/lib/cloudflare-workers.d.ts +1 -1
- package/lib/cordis/door.d.ts +2 -1
- package/lib/cordis/door.js +7 -4
- package/lib/cordis/inspect.js +1 -1
- package/lib/cordis/node-server.d.ts +14 -2
- package/lib/cordis/node-server.js +27 -3
- package/lib/cordis/router-http.d.ts +25 -2
- package/lib/cordis/router-http.js +54 -6
- package/lib/cordis/router.d.ts +1 -1
- package/lib/cordis/router.js +1 -1
- package/lib/cordis/state.js +1 -1
- package/lib/door/host.js +1 -1
- package/lib/{index-BvFh1Gfx.d.ts → index-C-SklY6u.d.ts} +3 -0
- package/lib/{index-BqVQkTnu.d.ts → index-D4nVR3wu.d.ts} +18 -3
- package/lib/node-server.d.ts +2 -38
- package/lib/node-server.js +2 -2
- package/lib/{snapshot-text-D3NspDyT.js → snapshot-text-yaWlezbd.js} +1 -1
- package/lib/{src-CwABFr6r.js → src-DNzw0Qsb.js} +3 -2
- package/lib/test-websocket-DyeS50Tr.d.ts +136 -0
- package/lib/{server-DvgMGtzo.js → test-websocket-ZXHNHQSU.js} +225 -3
- package/lib/ws.d.ts +1 -1
- package/lib/ws.js +3 -0
- package/package.json +6 -2
- package/plugins/acryl-door/src/host/door.ts +5 -3
- package/plugins/acryl-door/src/index.ts +1 -1
- package/plugins/acryl-node-server/plugin.json +1 -1
- package/plugins/acryl-node-server/src/adapter/websocket-types.ts +5 -1
- package/plugins/acryl-node-server/src/adapter/websocket.ts +33 -5
- package/plugins/acryl-node-server/src/index.ts +35 -1
- package/plugins/acryl-node-server/src/test-websocket.ts +110 -0
- package/plugins/acryl-node-server/src/upgrade-hub.ts +152 -0
- package/plugins/acryl-router/src/core/helper/websocket/index.ts +5 -0
- package/plugins/acryl-router/src/service.ts +18 -4
- package/plugins/acryl-router-http/plugin.json +2 -2
- package/plugins/acryl-router-http/src/index.ts +70 -6
- package/plugins/agent-panel/client/main.ts +70 -2
- package/plugins/agent-panel/drivers.ts +83 -0
- package/plugins/agent-panel/headless.ts +154 -0
- package/plugins/agent-panel/index.ts +42 -125
- package/plugins/agent-panel/plugin.json +1 -1
- package/plugins/driver-pty/client/terminal.ts +188 -0
- package/plugins/driver-pty/client/vendor/LICENSE +21 -0
- package/plugins/driver-pty/client/vendor/LICENSE-addon-fit +19 -0
- package/plugins/driver-pty/client/vendor/VERSION +4 -0
- package/plugins/driver-pty/client/vendor/addon-fit.d.mts +6 -0
- package/plugins/driver-pty/client/vendor/addon-fit.mjs +18 -0
- package/plugins/driver-pty/client/vendor/xterm-css.d.mts +2 -0
- package/plugins/driver-pty/client/vendor/xterm-css.mjs +2 -0
- package/plugins/driver-pty/client/vendor/xterm.d.mts +17 -0
- package/plugins/driver-pty/client/vendor/xterm.mjs +53 -0
- package/plugins/driver-pty/index.ts +249 -0
- package/plugins/driver-pty/plugin.json +13 -0
- package/plugins/driver-pty/spawn.ts +36 -0
- package/plugins/driver-pty/terminal.ts +84 -0
- package/shared/AGENTS.core.md +1 -1
- package/shared/DEFAULTS.md +1 -1
- package/lib/error-t4N2js2I.d.ts +0 -8
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { t as RequestError } from "../
|
|
1
|
+
import { c as UpgradeHubOptions, i as testWebSocket, l as UpgradeRouter, n as TestWebSocketOptions, o as UpgradeEmitter, p as WebSocketLike, r as TestWebSocketResult, s as UpgradeHub, t as TestSocket, u as RequestError } from "../test-websocket-DyeS50Tr.js";
|
|
2
|
+
import { n as UpgradeWebSocket } from "../index-C-SklY6u.js";
|
|
2
3
|
import { ServeStaticOptions, serveStatic } from "../node-server/serve-static.js";
|
|
3
4
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
4
5
|
import z from "@deepseek-ai/schemastery";
|
|
@@ -11,6 +12,8 @@ interface Config {
|
|
|
11
12
|
hostname: string;
|
|
12
13
|
port: number;
|
|
13
14
|
scan: number;
|
|
15
|
+
/** Limits of WebSocket upgrades (`upgrades()`); the defaults suit most apps. */
|
|
16
|
+
websocket: UpgradeHubOptions;
|
|
14
17
|
}
|
|
15
18
|
/** Every field has a default, so a caller passes only what it changes: `ctx.plugin(plugin, { ... })` takes the partial shape. */
|
|
16
19
|
declare const Config: z<Partial<Config>, Config>;
|
|
@@ -23,8 +26,17 @@ declare class NodeServer extends Service {
|
|
|
23
26
|
readonly hostname: string;
|
|
24
27
|
readonly config: Config;
|
|
25
28
|
private readonly server;
|
|
29
|
+
private hub;
|
|
26
30
|
private bound;
|
|
27
31
|
constructor(ctx: Context, config: Config);
|
|
32
|
+
/**
|
|
33
|
+
* `upgradeWebSocket` for the plugin that asks (call it once, in `apply`): `app.get('/ws', upgrade((c) => ({ onMessage(event, ws) { ... } })))`. Checks go in ordinary middleware on the
|
|
34
|
+
* route, and a handler that returns a `Response` refuses the upgrade with that status before any handshake. Every socket it accepts belongs to the calling plugin: when the plugin
|
|
35
|
+
* unloads they are closed with 1001 within `websocket.grace` and the handler sees `close` once. Pass `{ textOnly: true }` to drop binary frames. Needs the `ws` package.
|
|
36
|
+
*/
|
|
37
|
+
upgrades(): UpgradeWebSocket<WebSocketLike>;
|
|
38
|
+
/** How many WebSocket connections are open now. */
|
|
39
|
+
get sockets(): number;
|
|
28
40
|
/** The port in use, 0 before the server listens. */
|
|
29
41
|
get port(): number;
|
|
30
42
|
/** The address clients use. */
|
|
@@ -42,4 +54,4 @@ declare function isPortUnavailable(error: unknown, platform?: NodeJS.Platform):
|
|
|
42
54
|
/** Loads once the server listens, so a plugin that injects `nodeServer` can rely on `url`. A failure to bind fails the plugin. */
|
|
43
55
|
declare function apply(ctx: Context, config?: Partial<Config>): Promise<void>;
|
|
44
56
|
//#endregion
|
|
45
|
-
export { Config, NodeServer, RequestError, type ServeStaticOptions, apply, inject, isPortUnavailable, name, serveStatic };
|
|
57
|
+
export { Config, NodeServer, RequestError, type ServeStaticOptions, type TestSocket, type TestWebSocketOptions, type TestWebSocketResult, UpgradeEmitter, UpgradeHub, type UpgradeHubOptions, type UpgradeRouter, apply, inject, isPortUnavailable, name, serveStatic, testWebSocket };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { c as Request, i as createAdaptorServer, l as RequestError, n as UpgradeEmitter, r as UpgradeHub, t as testWebSocket } from "../test-websocket-ZXHNHQSU.js";
|
|
2
2
|
import { t as serveStatic } from "../serve-static-3uo_9rjF.js";
|
|
3
3
|
import { Service } from "@deepseek-ai/cordis";
|
|
4
4
|
import z from "@deepseek-ai/schemastery";
|
|
@@ -10,12 +10,18 @@ const inject = ["router"];
|
|
|
10
10
|
const Config = z.object({
|
|
11
11
|
hostname: z.string().default("127.0.0.1").description("Address to bind. Loopback by default; binding elsewhere exposes the app to the network."),
|
|
12
12
|
port: z.number().min(0).max(65535).default(0).description("Port to listen on; 0 lets the system choose. A taken port is followed by the next free one."),
|
|
13
|
-
scan: z.number().min(0).default(20).description("How many further ports to try when the configured one is taken.")
|
|
13
|
+
scan: z.number().min(0).default(20).description("How many further ports to try when the configured one is taken."),
|
|
14
|
+
websocket: z.object({
|
|
15
|
+
maxPayload: z.number().min(1).default(1024 * 1024).description("The largest WebSocket frame accepted, in bytes; a bigger one closes the socket with 1009."),
|
|
16
|
+
heartbeat: z.number().min(0).default(3e4).description("Milliseconds between pings; a peer that did not answer the last one is terminated. 0 turns it off."),
|
|
17
|
+
grace: z.number().min(0).default(2e3).description("Milliseconds a closing socket gets before it is terminated when its plugin unloads.")
|
|
18
|
+
}).default({})
|
|
14
19
|
});
|
|
15
20
|
var NodeServer = class extends Service {
|
|
16
21
|
hostname;
|
|
17
22
|
config;
|
|
18
23
|
server;
|
|
24
|
+
hub;
|
|
19
25
|
bound = 0;
|
|
20
26
|
constructor(ctx, config) {
|
|
21
27
|
super(ctx, "nodeServer");
|
|
@@ -31,6 +37,7 @@ var NodeServer = class extends Service {
|
|
|
31
37
|
overrideGlobalObjects: false
|
|
32
38
|
});
|
|
33
39
|
ctx.effect(() => async () => {
|
|
40
|
+
await this.hub?.close();
|
|
34
41
|
this.server.closeAllConnections();
|
|
35
42
|
if (this.server.listening) await new Promise((resolve) => {
|
|
36
43
|
this.server.close(() => {
|
|
@@ -39,6 +46,22 @@ var NodeServer = class extends Service {
|
|
|
39
46
|
});
|
|
40
47
|
}, "acryl-node-server: close listener and open connections");
|
|
41
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* `upgradeWebSocket` for the plugin that asks (call it once, in `apply`): `app.get('/ws', upgrade((c) => ({ onMessage(event, ws) { ... } })))`. Checks go in ordinary middleware on the
|
|
51
|
+
* route, and a handler that returns a `Response` refuses the upgrade with that status before any handshake. Every socket it accepts belongs to the calling plugin: when the plugin
|
|
52
|
+
* unloads they are closed with 1001 within `websocket.grace` and the handler sees `close` once. Pass `{ textOnly: true }` to drop binary frames. Needs the `ws` package.
|
|
53
|
+
*/
|
|
54
|
+
upgrades() {
|
|
55
|
+
if (!this.hub) {
|
|
56
|
+
this.hub = new UpgradeHub(this.config.websocket);
|
|
57
|
+
this.hub.attach(this.server, this.ctx.router);
|
|
58
|
+
}
|
|
59
|
+
return this.hub.upgradeWebSocketFor(this.ctx);
|
|
60
|
+
}
|
|
61
|
+
/** How many WebSocket connections are open now. */
|
|
62
|
+
get sockets() {
|
|
63
|
+
return this.hub?.size ?? 0;
|
|
64
|
+
}
|
|
42
65
|
/** The port in use, 0 before the server listens. */
|
|
43
66
|
get port() {
|
|
44
67
|
return this.bound;
|
|
@@ -86,8 +109,9 @@ async function apply(ctx, config = {}) {
|
|
|
86
109
|
hostname: "127.0.0.1",
|
|
87
110
|
port: 0,
|
|
88
111
|
scan: 20,
|
|
112
|
+
websocket: {},
|
|
89
113
|
...config
|
|
90
114
|
}).listen();
|
|
91
115
|
}
|
|
92
116
|
//#endregion
|
|
93
|
-
export { Config, NodeServer, RequestError, apply, inject, isPortUnavailable, name, serveStatic };
|
|
117
|
+
export { Config, NodeServer, RequestError, UpgradeEmitter, UpgradeHub, apply, inject, isPortUnavailable, name, serveStatic, testWebSocket };
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as UpgradeWebSocket } from "../index-C-SklY6u.js";
|
|
2
|
+
import { i as RouterHttpService } from "../index-D4nVR3wu.js";
|
|
2
3
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
4
|
+
import { Duplex } from "node:stream";
|
|
3
5
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
4
6
|
|
|
5
7
|
//#region ../../plugins/acryl-router-http/src/serve.d.ts
|
|
@@ -40,16 +42,37 @@ interface WebServerPort {
|
|
|
40
42
|
readonly path: string;
|
|
41
43
|
readonly handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
42
44
|
}): () => void;
|
|
45
|
+
/** One exact-path upgrade claim (`WebUpgradeRoute` of the web server); optional because an older web server has none. */
|
|
46
|
+
registerUpgrade?(route: {
|
|
47
|
+
readonly path: string;
|
|
48
|
+
readonly handler: (req: IncomingMessage, socket: Duplex, head: Buffer) => void | Promise<void>;
|
|
49
|
+
}): () => void;
|
|
43
50
|
}
|
|
44
51
|
declare class RouterHttp extends Service implements RouterHttpService {
|
|
45
52
|
private readonly router;
|
|
46
53
|
private readonly web;
|
|
54
|
+
private hub;
|
|
55
|
+
/** The adapter's own context: the hub lives as long as the adapter, whichever plugin asked for it first (`this.ctx` is the caller's). */
|
|
56
|
+
private readonly home;
|
|
57
|
+
private readonly upgradesIn;
|
|
47
58
|
constructor(ctx: Context);
|
|
48
59
|
/**
|
|
49
60
|
* Serve `prefix` and everything below it through the router. Returns a remover; the mount also goes away when the
|
|
50
61
|
* calling plugin unloads. A prefix another route already claims throws, as the webServer treats it as misconfiguration.
|
|
62
|
+
* `options.upgrade` names the exact paths that may be upgraded to a WebSocket: each must be inside the prefix, and each is one
|
|
63
|
+
* exact-path upgrade route of the web server, removed with the mount. No other path of the mount accepts an upgrade.
|
|
64
|
+
*/
|
|
65
|
+
mount(prefix: string, options?: {
|
|
66
|
+
readonly upgrade?: readonly string[];
|
|
67
|
+
}): () => void;
|
|
68
|
+
/**
|
|
69
|
+
* `upgradeWebSocket` for the calling plugin: the sockets its routes accept are closed with 1001 when it unloads. Needs the `ws` package.
|
|
70
|
+
* The route must be on a path the plugin mounted with `upgrade: [path]`.
|
|
51
71
|
*/
|
|
52
|
-
|
|
72
|
+
upgrades(): UpgradeWebSocket;
|
|
73
|
+
/** How many WebSocket connections are open now. */
|
|
74
|
+
get sockets(): number;
|
|
75
|
+
private ensureHub;
|
|
53
76
|
}
|
|
54
77
|
declare function apply(ctx: Context): void;
|
|
55
78
|
//#endregion
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { n as UpgradeEmitter, r as UpgradeHub } from "../test-websocket-ZXHNHQSU.js";
|
|
2
|
+
import "./node-server.js";
|
|
1
3
|
import { pipeline } from "node:stream/promises";
|
|
2
4
|
import { Readable } from "node:stream";
|
|
3
5
|
import { Service } from "@deepseek-ai/cordis";
|
|
@@ -88,27 +90,73 @@ const PREFIX_PATTERN = /^\/[A-Za-z0-9._~\-/]*[A-Za-z0-9._~-]$/;
|
|
|
88
90
|
var RouterHttp = class extends Service {
|
|
89
91
|
router;
|
|
90
92
|
web;
|
|
93
|
+
hub;
|
|
94
|
+
/** The adapter's own context: the hub lives as long as the adapter, whichever plugin asked for it first (`this.ctx` is the caller's). */
|
|
95
|
+
home;
|
|
96
|
+
upgradesIn = new UpgradeEmitter();
|
|
91
97
|
constructor(ctx) {
|
|
92
98
|
super(ctx, "routerHttp");
|
|
99
|
+
this.home = ctx;
|
|
93
100
|
this.router = ctx.router;
|
|
94
101
|
this.web = ctx.get("webServer");
|
|
95
102
|
}
|
|
96
103
|
/**
|
|
97
104
|
* Serve `prefix` and everything below it through the router. Returns a remover; the mount also goes away when the
|
|
98
105
|
* calling plugin unloads. A prefix another route already claims throws, as the webServer treats it as misconfiguration.
|
|
106
|
+
* `options.upgrade` names the exact paths that may be upgraded to a WebSocket: each must be inside the prefix, and each is one
|
|
107
|
+
* exact-path upgrade route of the web server, removed with the mount. No other path of the mount accepts an upgrade.
|
|
99
108
|
*/
|
|
100
|
-
mount(prefix) {
|
|
109
|
+
mount(prefix, options = {}) {
|
|
101
110
|
if (!PREFIX_PATTERN.test(prefix)) throw new TypeError(`acryl-router-http: "${prefix}" is not a mountable path prefix`);
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
const upgrade = options.upgrade ?? [];
|
|
112
|
+
for (const path of upgrade) if (!PREFIX_PATTERN.test(path) || !(path === prefix || path.startsWith(`${prefix}/`))) throw new TypeError(`acryl-router-http: the upgrade path "${path}" is not inside the prefix "${prefix}"`);
|
|
113
|
+
if (upgrade.length > 0 && this.web.registerUpgrade === void 0) throw new TypeError("acryl-router-http: this web server cannot take WebSocket upgrades (it has no registerUpgrade)");
|
|
114
|
+
const removers = [];
|
|
115
|
+
try {
|
|
116
|
+
if (upgrade.length > 0) this.ensureHub();
|
|
117
|
+
for (const path of upgrade) removers.push(this.web.registerUpgrade({
|
|
118
|
+
path,
|
|
119
|
+
handler: (req, socket, head) => {
|
|
120
|
+
this.upgradesIn.emit("upgrade", req, socket, head);
|
|
121
|
+
}
|
|
122
|
+
}));
|
|
123
|
+
removers.push(this.web.register({
|
|
124
|
+
kind: "prefix",
|
|
125
|
+
path: prefix,
|
|
126
|
+
handler: (req, res) => serve(this.router, req, res)
|
|
127
|
+
}));
|
|
128
|
+
} catch (error) {
|
|
129
|
+
for (const remove of removers) remove();
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
const remove = () => {
|
|
133
|
+
for (const undo of removers.splice(0)) undo();
|
|
134
|
+
};
|
|
107
135
|
this.ctx.effect(() => () => {
|
|
108
136
|
remove();
|
|
109
137
|
}, `acryl-router-http: mount ${prefix}`);
|
|
110
138
|
return remove;
|
|
111
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* `upgradeWebSocket` for the calling plugin: the sockets its routes accept are closed with 1001 when it unloads. Needs the `ws` package.
|
|
142
|
+
* The route must be on a path the plugin mounted with `upgrade: [path]`.
|
|
143
|
+
*/
|
|
144
|
+
upgrades() {
|
|
145
|
+
return this.ensureHub().upgradeWebSocketFor(this.ctx);
|
|
146
|
+
}
|
|
147
|
+
/** How many WebSocket connections are open now. */
|
|
148
|
+
get sockets() {
|
|
149
|
+
return this.hub?.size ?? 0;
|
|
150
|
+
}
|
|
151
|
+
ensureHub() {
|
|
152
|
+
if (!this.hub) {
|
|
153
|
+
const hub = new UpgradeHub();
|
|
154
|
+
hub.attach(this.upgradesIn, this.router);
|
|
155
|
+
this.hub = hub;
|
|
156
|
+
this.home.effect(() => () => hub.close(), "acryl-router-http: WebSocket hub");
|
|
157
|
+
}
|
|
158
|
+
return this.hub;
|
|
159
|
+
}
|
|
112
160
|
};
|
|
113
161
|
function apply(ctx) {
|
|
114
162
|
new RouterHttp(ctx);
|
package/lib/cordis/router.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import { c as StatusCode, n as ContentfulStatusCode } from "../http-status-DaAwG
|
|
|
3
3
|
import { a as getConnInfo, i as connectionOf, n as RouterBindings, r as RouterEnv, t as ConnectionInfo } from "../connection-ZLEso7XL.js";
|
|
4
4
|
import { t as Acryl } from "../app-D8riatvv.js";
|
|
5
5
|
import { n as AppRequest, t as App } from "../deprecated-CTy4N7ng.js";
|
|
6
|
-
import { a as TrailingSlash, i as RouterHttpService, n as MountableApp, o as apply, r as Router, s as name, t as Config } from "../index-
|
|
6
|
+
import { a as TrailingSlash, i as RouterHttpService, n as MountableApp, o as apply, r as Router, s as name, t as Config } from "../index-D4nVR3wu.js";
|
|
7
7
|
import { t as HTTPException } from "../http-exception-kpGJkmpi.js";
|
|
8
8
|
export { Acryl, type AcrylRequest, App, type AppRequest, Config, type ConnectionInfo, type ContentfulStatusCode, Context, type ContextRenderer, type ContextVariableMap, type Env, type ErrorHandler, type ExecutionContext, HTTPException, type Handler, type Input, type MiddlewareHandler, type MountableApp, type Next, type NotFoundHandler, type NotFoundResponse, Router, type RouterBindings, type RouterEnv, type RouterHttpService, type Schema, type StatusCode, type ToSchema, type TrailingSlash, type TypedResponse, type ValidationTargets, apply, connectionOf, getConnInfo, name };
|
package/lib/cordis/router.js
CHANGED
|
@@ -3,5 +3,5 @@ import { t as Context } from "../context-DDO0cfuP.js";
|
|
|
3
3
|
import { t as Acryl } from "../app-BM0rTCp7.js";
|
|
4
4
|
import { t as App } from "../deprecated-BP4fPt38.js";
|
|
5
5
|
import { n as getConnInfo, t as connectionOf } from "../connection-C7xgP1hP.js";
|
|
6
|
-
import { i as name, n as Router, r as apply, t as Config } from "../src-
|
|
6
|
+
import { i as name, n as Router, r as apply, t as Config } from "../src-DNzw0Qsb.js";
|
|
7
7
|
export { Acryl, App, Config, Context, HTTPException, Router, apply, connectionOf, getConnInfo, name };
|
package/lib/cordis/state.js
CHANGED
|
@@ -3,7 +3,7 @@ import { methodNotAllowed } from "../method-not-allowed.js";
|
|
|
3
3
|
import { r as streamSSE } from "../streaming-DHST3Scg.js";
|
|
4
4
|
import { loopbackOnly } from "../loopback-only.js";
|
|
5
5
|
import "../helpers-CvTauQT5.js";
|
|
6
|
-
import "../src-
|
|
6
|
+
import "../src-DNzw0Qsb.js";
|
|
7
7
|
import "../middleware-CPQ8himN.js";
|
|
8
8
|
import { Service } from "@deepseek-ai/cordis";
|
|
9
9
|
//#region ../../plugins/acryl-state/src/cell.ts
|
package/lib/door/host.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { d as AuditLog, f as auditPath, n as HEARTBEAT_MS, p as UiChannel, r as pageChannelRoutes, t as renderSnapshot } from "../snapshot-text-
|
|
1
|
+
import { d as AuditLog, f as auditPath, n as HEARTBEAT_MS, p as UiChannel, r as pageChannelRoutes, t as renderSnapshot } from "../snapshot-text-yaWlezbd.js";
|
|
2
2
|
export { AuditLog, HEARTBEAT_MS, UiChannel, auditPath, pageChannelRoutes, renderSnapshot };
|
|
@@ -33,6 +33,8 @@ interface WSContextInit<T = unknown> {
|
|
|
33
33
|
close(code?: number, reason?: string): void;
|
|
34
34
|
raw?: T;
|
|
35
35
|
readyState: WSReadyState;
|
|
36
|
+
/** Bytes queued to send and not yet written to the socket; a sender that cares about back-pressure reads it. */
|
|
37
|
+
bufferedAmount?: number;
|
|
36
38
|
url?: string | URL | null;
|
|
37
39
|
protocol?: string | null;
|
|
38
40
|
}
|
|
@@ -52,6 +54,7 @@ declare class WSContext<T = unknown> {
|
|
|
52
54
|
raw?: T;
|
|
53
55
|
binaryType: BinaryType;
|
|
54
56
|
get readyState(): WSReadyState;
|
|
57
|
+
get bufferedAmount(): number;
|
|
55
58
|
url: URL | null;
|
|
56
59
|
protocol: string | null;
|
|
57
60
|
close(code?: number, reason?: string): void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { B as NotFoundHandler, y as ErrorHandler } from "./context-DS3fYyG-.js";
|
|
2
2
|
import { t as ConnectionInfo } from "./connection-ZLEso7XL.js";
|
|
3
|
+
import { n as UpgradeWebSocket } from "./index-C-SklY6u.js";
|
|
3
4
|
import { Context, Service } from "@deepseek-ai/cordis";
|
|
4
5
|
import z from "@deepseek-ai/schemastery";
|
|
5
6
|
|
|
@@ -18,8 +19,21 @@ declare const Config: z<Partial<Config>, Config>;
|
|
|
18
19
|
* served over HTTP without depending on the adapter package.
|
|
19
20
|
*/
|
|
20
21
|
interface RouterHttpService {
|
|
21
|
-
/**
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Serve `prefix` and everything below it through the router; returns a remover. The mount also goes away when the calling plugin unloads.
|
|
24
|
+
* `options.upgrade` lists the exact paths below the prefix that may be upgraded to a WebSocket (each must be inside the prefix); no other path of the mount accepts an upgrade.
|
|
25
|
+
*/
|
|
26
|
+
mount(prefix: string, options?: {
|
|
27
|
+
readonly upgrade?: readonly string[];
|
|
28
|
+
}): () => void;
|
|
29
|
+
/**
|
|
30
|
+
* `upgradeWebSocket` for the calling plugin: `app.get('/terminal', upgrade((c) => ({ onMessage(event, ws) { ... } })))` on a route the plugin mounted with `upgrade: ['/terminal']`.
|
|
31
|
+
* Checks go in ordinary middleware on the route; a handler that returns a `Response` refuses with that status before any handshake. The sockets it accepts belong to the calling
|
|
32
|
+
* plugin: when it unloads they are closed with 1001 and the handler sees `close` once. Needs the `ws` package.
|
|
33
|
+
*/
|
|
34
|
+
upgrades(): UpgradeWebSocket;
|
|
35
|
+
/** How many WebSocket connections are open now. */
|
|
36
|
+
readonly sockets: number;
|
|
23
37
|
}
|
|
24
38
|
declare module '@deepseek-ai/cordis' {
|
|
25
39
|
interface Context {
|
|
@@ -83,8 +97,9 @@ declare class Router extends Service {
|
|
|
83
97
|
* Run a request in process. Never throws: failures become a 500, a disposed router answers 503. `connection` describes the transport
|
|
84
98
|
* (an HTTP adapter passes the socket's peer address and local port); an in-process caller omits it. Handlers read it with
|
|
85
99
|
* `connectionOf(c)`, abort with `c.req.raw.signal` and keep the request in flight with `c.executionCtx.waitUntil(task)`.
|
|
100
|
+
* `bindings` is an object an adapter hands to the handler as `c.env` (an upgrade request's socket hooks, for `upgradeWebSocket`); `connection` is added to it.
|
|
86
101
|
*/
|
|
87
|
-
fetch(request: Request, connection?: ConnectionInfo): Promise<Response>;
|
|
102
|
+
fetch(request: Request, connection?: ConnectionInfo, bindings?: object): Promise<Response>;
|
|
88
103
|
private dispatch;
|
|
89
104
|
private app;
|
|
90
105
|
/**
|
package/lib/node-server.d.ts
CHANGED
|
@@ -1,42 +1,12 @@
|
|
|
1
1
|
import { t as Acryl } from "./app-D8riatvv.js";
|
|
2
|
-
import { n as
|
|
3
|
-
import { t as RequestError } from "./error-t4N2js2I.js";
|
|
2
|
+
import { a as Owner, c as UpgradeHubOptions, d as upgradeWebSocket, f as WebSocketData, i as testWebSocket, l as UpgradeRouter, m as WebSocketServerLike, n as TestWebSocketOptions, o as UpgradeEmitter, p as WebSocketLike, r as TestWebSocketResult, s as UpgradeHub, t as TestSocket, u as RequestError } from "./test-websocket-DyeS50Tr.js";
|
|
4
3
|
import { ServeStaticOptions, serveStatic } from "./node-server/serve-static.js";
|
|
5
4
|
import { getConnInfo } from "./node-server/conninfo.js";
|
|
6
5
|
import { AddressInfo } from "node:net";
|
|
7
6
|
import { IncomingMessage, Server, ServerOptions, ServerResponse, createServer } from "node:http";
|
|
8
7
|
import { Http2SecureServer, Http2Server, Http2ServerRequest, Http2ServerResponse, SecureServerOptions, ServerOptions as ServerOptions$1, createSecureServer, createServer as createServer$1 } from "node:http2";
|
|
9
|
-
import { Duplex } from "node:stream";
|
|
10
8
|
import { Server as Server$1, ServerOptions as ServerOptions$2, createServer as createServer$2 } from "node:https";
|
|
11
9
|
|
|
12
|
-
//#region ../../plugins/acryl-node-server/src/adapter/websocket-types.d.ts
|
|
13
|
-
type WSReadyState = 0 | 1 | 2 | 3;
|
|
14
|
-
type WebSocketData = string | ArrayBuffer | Uint8Array | readonly Uint8Array[];
|
|
15
|
-
type WebSocketSendOptions = {
|
|
16
|
-
compress?: boolean;
|
|
17
|
-
};
|
|
18
|
-
interface WebSocketLike {
|
|
19
|
-
protocol: string;
|
|
20
|
-
readyState: WSReadyState;
|
|
21
|
-
close(code?: number, reason?: string): void;
|
|
22
|
-
send(data: string | ArrayBuffer | ArrayBufferView, options?: WebSocketSendOptions): void;
|
|
23
|
-
on(event: 'message', listener: (data: WebSocketData, isBinary: boolean) => void): this;
|
|
24
|
-
on(event: 'close', listener: (code: number, reason: Uint8Array) => void): this;
|
|
25
|
-
on(event: 'error', listener: (error: unknown) => void): this;
|
|
26
|
-
off(event: 'message', listener: (data: WebSocketData, isBinary: boolean) => void): this;
|
|
27
|
-
}
|
|
28
|
-
interface WebSocketServerLike {
|
|
29
|
-
options: {
|
|
30
|
-
noServer?: boolean;
|
|
31
|
-
};
|
|
32
|
-
on(event: 'connection', listener: (ws: WebSocketLike, request: IncomingMessage) => void): this;
|
|
33
|
-
on(event: 'headers', listener: (headers: string[]) => void): this;
|
|
34
|
-
off(event: 'headers', listener: (headers: string[]) => void): this;
|
|
35
|
-
emit(event: 'connection', ws: WebSocketLike, request: IncomingMessage): boolean;
|
|
36
|
-
handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer, callback: (ws: WebSocketLike) => void): void;
|
|
37
|
-
close(): void;
|
|
38
|
-
}
|
|
39
|
-
//#endregion
|
|
40
10
|
//#region ../../plugins/acryl-node-server/src/adapter/types.d.ts
|
|
41
11
|
type HttpBindings = {
|
|
42
12
|
incoming: IncomingMessage;
|
|
@@ -107,12 +77,6 @@ declare function serve(options: HttpsOptions, listeningListener?: (info: Address
|
|
|
107
77
|
declare function serve(options: HttpOptions, listeningListener?: (info: AddressInfo) => void): Server;
|
|
108
78
|
declare function serve(options: Options, listeningListener?: (info: AddressInfo) => void): ServerType;
|
|
109
79
|
//#endregion
|
|
110
|
-
//#region ../../plugins/acryl-node-server/src/adapter/websocket.d.ts
|
|
111
|
-
type UpgradeWebSocketOptions = {
|
|
112
|
-
onError: (err: unknown) => void;
|
|
113
|
-
};
|
|
114
|
-
declare const upgradeWebSocket: UpgradeWebSocket<WebSocketLike, UpgradeWebSocketOptions>;
|
|
115
|
-
//#endregion
|
|
116
80
|
//#region ../../plugins/acryl-node-server/src/adapter/listener.d.ts
|
|
117
81
|
declare const getRequestListener: (fetchCallback: FetchCallback, options?: {
|
|
118
82
|
hostname?: string;
|
|
@@ -161,4 +125,4 @@ declare function clientModules(options: ClientModulesOptions): Acryl;
|
|
|
161
125
|
*/
|
|
162
126
|
declare function buildClientModules(options: BuildClientModulesOptions): string[];
|
|
163
127
|
//#endregion
|
|
164
|
-
export { type BuildClientModulesOptions, type ClientModulesOptions, type Http2Bindings, type HttpBindings, RequestError, type ServeStaticOptions, type ServerType, type WebSocketData, type WebSocketLike, type WebSocketServerLike, buildClientModules, clientModules, createAdaptorServer, getConnInfo, getRequestListener, serve, serveStatic, upgradeWebSocket };
|
|
128
|
+
export { type BuildClientModulesOptions, type ClientModulesOptions, type Http2Bindings, type HttpBindings, type Owner, RequestError, type ServeStaticOptions, type ServerType, type TestSocket, type TestWebSocketOptions, type TestWebSocketResult, UpgradeEmitter, UpgradeHub, type UpgradeHubOptions, type UpgradeRouter, type WebSocketData, type WebSocketLike, type WebSocketServerLike, buildClientModules, clientModules, createAdaptorServer, getConnInfo, getRequestListener, serve, serveStatic, testWebSocket, upgradeWebSocket };
|
package/lib/node-server.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { a as serve, i as createAdaptorServer, l as RequestError, n as UpgradeEmitter, o as upgradeWebSocket, r as UpgradeHub, s as getRequestListener, t as testWebSocket } from "./test-websocket-ZXHNHQSU.js";
|
|
2
2
|
import { t as serveStatic } from "./serve-static-3uo_9rjF.js";
|
|
3
3
|
import { getConnInfo } from "./node-server/conninfo.js";
|
|
4
4
|
import { n as clientModules, t as buildClientModules } from "./client-modules-CLvWOjbd.js";
|
|
5
|
-
export { RequestError, buildClientModules, clientModules, createAdaptorServer, getConnInfo, getRequestListener, serve, serveStatic, upgradeWebSocket };
|
|
5
|
+
export { RequestError, UpgradeEmitter, UpgradeHub, buildClientModules, clientModules, createAdaptorServer, getConnInfo, getRequestListener, serve, serveStatic, testWebSocket, upgradeWebSocket };
|
|
@@ -5,7 +5,7 @@ import { r as streamSSE } from "./streaming-DHST3Scg.js";
|
|
|
5
5
|
import { loopbackAuthority, loopbackOnly } from "./loopback-only.js";
|
|
6
6
|
import "./helpers-CvTauQT5.js";
|
|
7
7
|
import { UiControlError, WINDOW_ID, parseChannelToHost } from "./door/protocol.js";
|
|
8
|
-
import "./src-
|
|
8
|
+
import "./src-DNzw0Qsb.js";
|
|
9
9
|
import "./middleware-CPQ8himN.js";
|
|
10
10
|
import { dirname, join } from "node:path";
|
|
11
11
|
import { timingSafeEqual } from "node:crypto";
|
|
@@ -186,8 +186,9 @@ var Router = class extends Service {
|
|
|
186
186
|
* Run a request in process. Never throws: failures become a 500, a disposed router answers 503. `connection` describes the transport
|
|
187
187
|
* (an HTTP adapter passes the socket's peer address and local port); an in-process caller omits it. Handlers read it with
|
|
188
188
|
* `connectionOf(c)`, abort with `c.req.raw.signal` and keep the request in flight with `c.executionCtx.waitUntil(task)`.
|
|
189
|
+
* `bindings` is an object an adapter hands to the handler as `c.env` (an upgrade request's socket hooks, for `upgradeWebSocket`); `connection` is added to it.
|
|
189
190
|
*/
|
|
190
|
-
fetch(request, connection = {}) {
|
|
191
|
+
fetch(request, connection = {}, bindings) {
|
|
191
192
|
if (this.state.closing) return Promise.resolve(new Response("Service Unavailable", { status: 503 }));
|
|
192
193
|
const controller = new AbortController();
|
|
193
194
|
const forward = () => controller.abort();
|
|
@@ -201,7 +202,7 @@ var Router = class extends Service {
|
|
|
201
202
|
passThroughOnException: () => {},
|
|
202
203
|
props: {}
|
|
203
204
|
};
|
|
204
|
-
const env = { connection };
|
|
205
|
+
const env = bindings === void 0 ? { connection } : Object.assign(bindings, { connection });
|
|
205
206
|
let bodyDone = Promise.resolve();
|
|
206
207
|
let endBody = () => {};
|
|
207
208
|
let resolveSettled;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { n as UpgradeWebSocket } from "./index-C-SklY6u.js";
|
|
2
|
+
import { IncomingMessage } from "node:http";
|
|
3
|
+
import { Duplex } from "node:stream";
|
|
4
|
+
import { EventEmitter } from "node:events";
|
|
5
|
+
|
|
6
|
+
//#region ../../plugins/acryl-node-server/src/adapter/websocket-types.d.ts
|
|
7
|
+
type WSReadyState = 0 | 1 | 2 | 3;
|
|
8
|
+
type WebSocketData = string | ArrayBuffer | Uint8Array | readonly Uint8Array[];
|
|
9
|
+
type WebSocketSendOptions = {
|
|
10
|
+
compress?: boolean;
|
|
11
|
+
};
|
|
12
|
+
interface WebSocketLike {
|
|
13
|
+
protocol: string;
|
|
14
|
+
readyState: WSReadyState;
|
|
15
|
+
bufferedAmount: number;
|
|
16
|
+
close(code?: number, reason?: string): void;
|
|
17
|
+
send(data: string | ArrayBuffer | ArrayBufferView, options?: WebSocketSendOptions): void;
|
|
18
|
+
on(event: 'message', listener: (data: WebSocketData, isBinary: boolean) => void): this;
|
|
19
|
+
on(event: 'close', listener: (code: number, reason: Uint8Array) => void): this;
|
|
20
|
+
on(event: 'error', listener: (error: unknown) => void): this;
|
|
21
|
+
on(event: 'pong', listener: () => void): this;
|
|
22
|
+
ping(): void;
|
|
23
|
+
terminate(): void;
|
|
24
|
+
off(event: 'message', listener: (data: WebSocketData, isBinary: boolean) => void): this;
|
|
25
|
+
}
|
|
26
|
+
interface WebSocketServerLike {
|
|
27
|
+
options: {
|
|
28
|
+
noServer?: boolean;
|
|
29
|
+
};
|
|
30
|
+
on(event: 'connection', listener: (ws: WebSocketLike, request: IncomingMessage) => void): this;
|
|
31
|
+
on(event: 'headers', listener: (headers: string[]) => void): this;
|
|
32
|
+
off(event: 'headers', listener: (headers: string[]) => void): this;
|
|
33
|
+
emit(event: 'connection', ws: WebSocketLike, request: IncomingMessage): boolean;
|
|
34
|
+
handleUpgrade(request: IncomingMessage, socket: Duplex, head: Buffer, callback: (ws: WebSocketLike) => void): void;
|
|
35
|
+
close(callback?: () => void): void;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ../../plugins/acryl-node-server/src/adapter/websocket.d.ts
|
|
39
|
+
type UpgradeWebSocketOptions = {
|
|
40
|
+
onError: (err: unknown) => void; /** Hand the handler text frames only; binary frames are dropped before `onMessage`. */
|
|
41
|
+
textOnly?: boolean; /** Called with each accepted socket: the mounting plugin's scope keeps it to close it when the plugin unloads. */
|
|
42
|
+
track?: (ws: WebSocketLike) => void;
|
|
43
|
+
};
|
|
44
|
+
/** The part of a server `setupWebSocket` listens to: the Host's web server hands upgrades to a plain emitter with the same two methods. */
|
|
45
|
+
interface UpgradeSource {
|
|
46
|
+
on(event: 'upgrade', listener: (request: IncomingMessage, socket: Duplex, head: Buffer) => void): unknown;
|
|
47
|
+
on(event: 'close', listener: () => void): unknown;
|
|
48
|
+
listenerCount(event: 'upgrade'): number;
|
|
49
|
+
}
|
|
50
|
+
declare const upgradeWebSocket: UpgradeWebSocket<WebSocketLike, UpgradeWebSocketOptions>;
|
|
51
|
+
//#endregion
|
|
52
|
+
//#region ../../plugins/acryl-node-server/src/adapter/error.d.ts
|
|
53
|
+
declare class RequestError extends Error {
|
|
54
|
+
constructor(message: string, options?: {
|
|
55
|
+
cause?: unknown;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region ../../plugins/acryl-node-server/src/upgrade-hub.d.ts
|
|
60
|
+
interface UpgradeHubOptions {
|
|
61
|
+
/** The largest frame accepted, in bytes; a bigger one closes the socket with 1009. Default 1 MiB. */
|
|
62
|
+
maxPayload?: number;
|
|
63
|
+
/** Milliseconds between pings; a peer that did not answer the previous one is terminated. Default 30 000; 0 turns the heartbeat off. */
|
|
64
|
+
heartbeat?: number;
|
|
65
|
+
/** Milliseconds a closing socket gets to finish its close handshake before it is terminated. Default 2000. */
|
|
66
|
+
grace?: number;
|
|
67
|
+
}
|
|
68
|
+
/** The part of the router a hub calls: run a request with connection facts and the adapter's bindings. */
|
|
69
|
+
interface UpgradeRouter {
|
|
70
|
+
fetch(request: Request, connection: {
|
|
71
|
+
remoteAddress?: string | undefined;
|
|
72
|
+
localPort?: number | undefined;
|
|
73
|
+
}, bindings?: object): Promise<Response>;
|
|
74
|
+
}
|
|
75
|
+
/** What a hub needs of a Cordis context: tying a disposer to the plugin that asked. */
|
|
76
|
+
interface Owner {
|
|
77
|
+
effect(execute: () => () => unknown, label?: string): unknown;
|
|
78
|
+
}
|
|
79
|
+
declare class UpgradeHub {
|
|
80
|
+
readonly server: WebSocketServerLike;
|
|
81
|
+
private readonly all;
|
|
82
|
+
private readonly alive;
|
|
83
|
+
private readonly grace;
|
|
84
|
+
private timer;
|
|
85
|
+
private closed;
|
|
86
|
+
constructor(options?: UpgradeHubOptions);
|
|
87
|
+
/**
|
|
88
|
+
* Accept upgrades from `source` and answer them with `router`: the request runs through the router's middleware with the socket's peer address and local port as connection
|
|
89
|
+
* facts (so the same loopback, origin and host checks work), and the upgrade bindings travel in `c.env` for `upgradeWebSocket`.
|
|
90
|
+
*/
|
|
91
|
+
attach(source: UpgradeSource, router: UpgradeRouter): void;
|
|
92
|
+
/** How many sockets are open. */
|
|
93
|
+
get size(): number;
|
|
94
|
+
/** `upgradeWebSocket` for the plugin `owner`: the sockets it accepts are closed with 1001 when that plugin unloads. */
|
|
95
|
+
upgradeWebSocketFor(owner: Owner): UpgradeWebSocket<WebSocketLike>;
|
|
96
|
+
/** Close `sockets` with `code`, wait for their close handshakes up to the grace, terminate what is left. */
|
|
97
|
+
closeAll(sockets: Iterable<WebSocketLike>, code: number, reason: string): Promise<void>;
|
|
98
|
+
/** End everything: every socket closes with 1001, the heartbeat stops, the `ws` server closes. */
|
|
99
|
+
close(): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
/** A stand-in for a server's `upgrade` events, for transports that dispatch upgrades themselves (the Host web server's exact-path routes). */
|
|
102
|
+
declare class UpgradeEmitter extends EventEmitter {}
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region ../../plugins/acryl-node-server/src/test-websocket.d.ts
|
|
105
|
+
/** The client side of an accepted test connection. */
|
|
106
|
+
interface TestSocket {
|
|
107
|
+
/** Frames the handler sent, in order (text only). */
|
|
108
|
+
readonly received: string[];
|
|
109
|
+
/** The code and reason the handler closed with, when it did. */
|
|
110
|
+
readonly closed: {
|
|
111
|
+
readonly code: number | undefined;
|
|
112
|
+
readonly reason: string | undefined;
|
|
113
|
+
} | undefined;
|
|
114
|
+
/** Send a text frame to the handler. */
|
|
115
|
+
send(text: string): void;
|
|
116
|
+
/** Close from the client side. */
|
|
117
|
+
close(code?: number, reason?: string): void;
|
|
118
|
+
}
|
|
119
|
+
interface TestWebSocketOptions {
|
|
120
|
+
readonly headers?: Record<string, string>;
|
|
121
|
+
/** The socket's peer address and local port, as an adapter would pass them. */
|
|
122
|
+
readonly connection?: {
|
|
123
|
+
readonly remoteAddress?: string;
|
|
124
|
+
readonly localPort?: number;
|
|
125
|
+
};
|
|
126
|
+
/** The URL origin the request is made against; default `http://127.0.0.1`. */
|
|
127
|
+
readonly base?: string;
|
|
128
|
+
}
|
|
129
|
+
interface TestWebSocketResult {
|
|
130
|
+
/** The refusal's status, or 101 when the upgrade was accepted. */
|
|
131
|
+
readonly status: number;
|
|
132
|
+
readonly socket?: TestSocket;
|
|
133
|
+
}
|
|
134
|
+
declare function testWebSocket(fetch: (request: Request, env: object) => Promise<Response>, path: string, options?: TestWebSocketOptions): Promise<TestWebSocketResult>;
|
|
135
|
+
//#endregion
|
|
136
|
+
export { Owner as a, UpgradeHubOptions as c, upgradeWebSocket as d, WebSocketData as f, testWebSocket as i, UpgradeRouter as l, WebSocketServerLike as m, TestWebSocketOptions as n, UpgradeEmitter as o, WebSocketLike as p, TestWebSocketResult as r, UpgradeHub as s, TestSocket as t, RequestError as u };
|