@smithers-orchestrator/server 0.17.0 → 0.19.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/package.json +14 -14
- package/src/GatewayOptions.ts +2 -0
- package/src/GatewayRegisterOptions.ts +8 -0
- package/src/GatewayUiConfig.ts +20 -0
- package/src/gateway.js +352 -3
- package/src/gatewayUi/createGatewayUiApp.js +47 -0
- package/src/index.d.ts +273 -48
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smithers-orchestrator/server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "HTTP, WebSocket, gateway, cron, webhook, and metrics servers for Smithers",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,28 +26,28 @@
|
|
|
26
26
|
"effect": "^3.21.1",
|
|
27
27
|
"hono": "^4.12.14",
|
|
28
28
|
"ws": "^8.20.0",
|
|
29
|
-
"@smithers-orchestrator/db": "0.
|
|
30
|
-
"@smithers-orchestrator/
|
|
31
|
-
"@smithers-orchestrator/
|
|
32
|
-
"@smithers-orchestrator/
|
|
33
|
-
"@smithers-orchestrator/
|
|
34
|
-
"@smithers-orchestrator/
|
|
35
|
-
"@smithers-orchestrator/
|
|
36
|
-
"@smithers-orchestrator/
|
|
37
|
-
"@smithers-orchestrator/protocol": "0.
|
|
38
|
-
"@smithers-orchestrator/scheduler": "0.
|
|
39
|
-
"@smithers-orchestrator/time-travel": "0.
|
|
29
|
+
"@smithers-orchestrator/db": "0.19.0",
|
|
30
|
+
"@smithers-orchestrator/components": "0.19.0",
|
|
31
|
+
"@smithers-orchestrator/driver": "0.19.0",
|
|
32
|
+
"@smithers-orchestrator/devtools": "0.19.0",
|
|
33
|
+
"@smithers-orchestrator/engine": "0.19.0",
|
|
34
|
+
"@smithers-orchestrator/errors": "0.19.0",
|
|
35
|
+
"@smithers-orchestrator/observability": "0.19.0",
|
|
36
|
+
"@smithers-orchestrator/gateway": "0.19.0",
|
|
37
|
+
"@smithers-orchestrator/protocol": "0.19.0",
|
|
38
|
+
"@smithers-orchestrator/scheduler": "0.19.0",
|
|
39
|
+
"@smithers-orchestrator/time-travel": "0.19.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bun": "latest",
|
|
43
43
|
"react": "^19.2.5",
|
|
44
44
|
"typescript": "~5.9.3",
|
|
45
45
|
"zod": "^4.3.6",
|
|
46
|
-
"@smithers-orchestrator/graph": "0.
|
|
46
|
+
"@smithers-orchestrator/graph": "0.19.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"test": "bun test tests",
|
|
50
50
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
51
|
-
"build": "tsup --dts-only"
|
|
51
|
+
"build": "rm -f src/index.d.ts && node ../../node_modules/tsup/dist/cli-default.js --dts-only"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/src/GatewayOptions.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { GatewayAuthConfig } from "./GatewayAuthConfig.js";
|
|
2
2
|
import type { GatewayDefaults } from "./GatewayDefaults.js";
|
|
3
|
+
import type { GatewayUiConfig } from "./GatewayUiConfig.js";
|
|
3
4
|
|
|
4
5
|
export type GatewayOptions = {
|
|
5
6
|
protocol?: number;
|
|
6
7
|
features?: string[];
|
|
7
8
|
heartbeatMs?: number;
|
|
8
9
|
auth?: GatewayAuthConfig;
|
|
10
|
+
ui?: GatewayUiConfig;
|
|
9
11
|
defaults?: GatewayDefaults;
|
|
10
12
|
maxBodyBytes?: number;
|
|
11
13
|
maxPayload?: number;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type GatewayUiConfig = {
|
|
2
|
+
/**
|
|
3
|
+
* Browser entry module for the React app. Smithers bundles this with Bun and
|
|
4
|
+
* serves it from the Gateway origin.
|
|
5
|
+
*/
|
|
6
|
+
entry: string;
|
|
7
|
+
/**
|
|
8
|
+
* URL path where the UI is mounted. Gateway-level UI defaults to `/`;
|
|
9
|
+
* workflow-level UI defaults to `/workflows/<workflowKey>`.
|
|
10
|
+
*/
|
|
11
|
+
path?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Document title for the generated HTML shell.
|
|
14
|
+
*/
|
|
15
|
+
title?: string;
|
|
16
|
+
/**
|
|
17
|
+
* JSON-serializable boot data exposed to the browser.
|
|
18
|
+
*/
|
|
19
|
+
props?: Record<string, unknown>;
|
|
20
|
+
};
|
package/src/gateway.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
// @smithers-type-exports-begin
|
|
2
2
|
/** @typedef {import("./EventFrame.js").EventFrame} EventFrame */
|
|
3
3
|
/** @typedef {import("./GatewayDefaults.js").GatewayDefaults} GatewayDefaults */
|
|
4
|
+
/** @typedef {import("./GatewayRegisterOptions.js").GatewayRegisterOptions} GatewayRegisterOptions */
|
|
4
5
|
/** @typedef {import("./GatewayTokenGrant.js").GatewayTokenGrant} GatewayTokenGrant */
|
|
6
|
+
/** @typedef {import("./GatewayUiConfig.js").GatewayUiConfig} GatewayUiConfig */
|
|
5
7
|
/** @typedef {import("./HelloResponse.js").HelloResponse} HelloResponse */
|
|
6
8
|
// @smithers-type-exports-end
|
|
7
9
|
|
|
8
10
|
import { createServer } from "node:http";
|
|
9
11
|
import { createHash, createHmac, randomUUID, timingSafeEqual } from "node:crypto";
|
|
12
|
+
import { resolve } from "node:path";
|
|
10
13
|
import { CronExpressionParser } from "cron-parser";
|
|
11
14
|
import { Effect, Metric } from "effect";
|
|
12
15
|
import { WebSocketServer } from "ws";
|
|
@@ -36,6 +39,7 @@ import { writeRewindAuditRow } from "@smithers-orchestrator/time-travel/writeRew
|
|
|
36
39
|
import { recoverInProgressRewindAudits } from "@smithers-orchestrator/time-travel/recoverInProgressRewindAudits";
|
|
37
40
|
import { GATEWAY_EVENT_WINDOW_DEFAULT, SMITHERS_API_VERSION, getRequiredScopeForGatewayMethod, } from "@smithers-orchestrator/gateway/rpc";
|
|
38
41
|
import { hasGatewayScope } from "@smithers-orchestrator/gateway/auth/scopes";
|
|
42
|
+
import { createGatewayUiApp } from "./gatewayUi/createGatewayUiApp.js";
|
|
39
43
|
/** @typedef {import("./GatewayWebhookRunConfig.js").GatewayWebhookRunConfig} GatewayWebhookRunConfig */
|
|
40
44
|
/** @typedef {import("./GatewayWebhookSignalConfig.js").GatewayWebhookSignalConfig} GatewayWebhookSignalConfig */
|
|
41
45
|
/** @typedef {import("./ConnectRequest.js").ConnectRequest} ConnectRequest */
|
|
@@ -90,6 +94,7 @@ import { hasGatewayScope } from "@smithers-orchestrator/gateway/auth/scopes";
|
|
|
90
94
|
* key: string;
|
|
91
95
|
* schedule?: string;
|
|
92
96
|
* webhook?: GatewayWebhookConfig;
|
|
97
|
+
* ui?: ResolvedGatewayUiConfig | null;
|
|
93
98
|
* }} RegisteredWorkflow
|
|
94
99
|
*/
|
|
95
100
|
/**
|
|
@@ -100,6 +105,21 @@ import { hasGatewayScope } from "@smithers-orchestrator/gateway/auth/scopes";
|
|
|
100
105
|
* adapter: SmithersDb;
|
|
101
106
|
* }} ResolvedRun
|
|
102
107
|
*/
|
|
108
|
+
/**
|
|
109
|
+
* @typedef {{
|
|
110
|
+
* entry: string;
|
|
111
|
+
* path: string;
|
|
112
|
+
* title?: string;
|
|
113
|
+
* props?: Record<string, unknown>;
|
|
114
|
+
* }} ResolvedGatewayUiConfig
|
|
115
|
+
*/
|
|
116
|
+
/**
|
|
117
|
+
* @typedef {{
|
|
118
|
+
* kind: "gateway" | "workflow";
|
|
119
|
+
* workflowKey: string | null;
|
|
120
|
+
* config: ResolvedGatewayUiConfig;
|
|
121
|
+
* }} GatewayUiMount
|
|
122
|
+
*/
|
|
103
123
|
|
|
104
124
|
const DEFAULT_PROTOCOL = 1;
|
|
105
125
|
const DEFAULT_HEARTBEAT_MS = 15_000;
|
|
@@ -117,6 +137,115 @@ export const GATEWAY_FRAME_ID_MAX_LENGTH = 128;
|
|
|
117
137
|
export const GATEWAY_RPC_INPUT_MAX_BYTES = GATEWAY_RPC_MAX_PAYLOAD_BYTES;
|
|
118
138
|
export const GATEWAY_RPC_INPUT_MAX_DEPTH = GATEWAY_RPC_MAX_DEPTH;
|
|
119
139
|
const GATEWAY_METHOD_NAME_PATTERN = /^[a-z][a-zA-Z0-9]*(?:\.[a-z][a-zA-Z0-9]*)*$/;
|
|
140
|
+
const GATEWAY_UI_ASSET_PREFIX = "__smithers_ui";
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @param {string} value
|
|
144
|
+
* @returns {string}
|
|
145
|
+
*/
|
|
146
|
+
function escapeHtml(value) {
|
|
147
|
+
return value
|
|
148
|
+
.replaceAll("&", "&")
|
|
149
|
+
.replaceAll("<", "<")
|
|
150
|
+
.replaceAll(">", ">")
|
|
151
|
+
.replaceAll('"', """);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @param {unknown} value
|
|
156
|
+
* @returns {string}
|
|
157
|
+
*/
|
|
158
|
+
function safeJsonScript(value) {
|
|
159
|
+
return JSON.stringify(value).replaceAll("<", "\\u003c");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @param {string | undefined} rawPath
|
|
164
|
+
* @param {string} fallbackPath
|
|
165
|
+
* @returns {string}
|
|
166
|
+
*/
|
|
167
|
+
function normalizeUiMountPath(rawPath, fallbackPath) {
|
|
168
|
+
const candidate = (rawPath && rawPath.trim()) || fallbackPath;
|
|
169
|
+
const withSlash = candidate.startsWith("/") ? candidate : `/${candidate}`;
|
|
170
|
+
const withoutTrailing = withSlash.length > 1 ? withSlash.replace(/\/+$/, "") : withSlash;
|
|
171
|
+
if (!/^\/[A-Za-z0-9/_:.-]*$/.test(withoutTrailing)) {
|
|
172
|
+
throw new SmithersError("INVALID_INPUT", `Gateway UI path is invalid: ${candidate}`);
|
|
173
|
+
}
|
|
174
|
+
return withoutTrailing;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @param {string} mountPath
|
|
179
|
+
* @param {string} suffix
|
|
180
|
+
* @returns {string}
|
|
181
|
+
*/
|
|
182
|
+
function joinUiPath(mountPath, suffix) {
|
|
183
|
+
if (mountPath === "/") {
|
|
184
|
+
return `/${suffix.replace(/^\/+/, "")}`;
|
|
185
|
+
}
|
|
186
|
+
return `${mountPath}/${suffix.replace(/^\/+/, "")}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* @param {GatewayUiConfig | undefined} ui
|
|
191
|
+
* @param {string} fallbackPath
|
|
192
|
+
* @returns {ResolvedGatewayUiConfig | null}
|
|
193
|
+
*/
|
|
194
|
+
function resolveGatewayUiConfig(ui, fallbackPath) {
|
|
195
|
+
if (!ui) {
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
if (typeof ui.entry !== "string" || !ui.entry.trim()) {
|
|
199
|
+
throw new SmithersError("INVALID_INPUT", "Gateway UI config requires a non-empty entry path.");
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
entry: resolve(process.cwd(), ui.entry),
|
|
203
|
+
path: normalizeUiMountPath(ui.path, fallbackPath),
|
|
204
|
+
...(typeof ui.title === "string" ? { title: ui.title } : {}),
|
|
205
|
+
...(ui.props && typeof ui.props === "object" && !Array.isArray(ui.props)
|
|
206
|
+
? { props: ui.props }
|
|
207
|
+
: {}),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* @param {import("node:http").IncomingHttpHeaders} headers
|
|
213
|
+
* @returns {Headers}
|
|
214
|
+
*/
|
|
215
|
+
function nodeHeadersToFetchHeaders(headers) {
|
|
216
|
+
const out = new Headers();
|
|
217
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
218
|
+
if (value === undefined) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (Array.isArray(value)) {
|
|
222
|
+
for (const entry of value) {
|
|
223
|
+
out.append(key, entry);
|
|
224
|
+
}
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
out.set(key, value);
|
|
228
|
+
}
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* @param {ServerResponse} res
|
|
234
|
+
* @param {Response} response
|
|
235
|
+
* @param {boolean} headOnly
|
|
236
|
+
*/
|
|
237
|
+
async function writeFetchResponse(res, response, headOnly = false) {
|
|
238
|
+
res.statusCode = response.status;
|
|
239
|
+
response.headers.forEach((value, key) => {
|
|
240
|
+
res.setHeader(key, value);
|
|
241
|
+
});
|
|
242
|
+
if (headOnly) {
|
|
243
|
+
res.end();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
const body = Buffer.from(await response.arrayBuffer());
|
|
247
|
+
res.end(body);
|
|
248
|
+
}
|
|
120
249
|
/**
|
|
121
250
|
* @template T
|
|
122
251
|
* @param {string | null | undefined} value
|
|
@@ -1054,6 +1183,8 @@ export class Gateway {
|
|
|
1054
1183
|
headersTimeout;
|
|
1055
1184
|
requestTimeout;
|
|
1056
1185
|
auth;
|
|
1186
|
+
ui;
|
|
1187
|
+
uiApp;
|
|
1057
1188
|
defaults;
|
|
1058
1189
|
workflows = new Map();
|
|
1059
1190
|
connections = new Set();
|
|
@@ -1066,6 +1197,7 @@ export class Gateway {
|
|
|
1066
1197
|
devtoolsSubscriberCounts = new Map();
|
|
1067
1198
|
/** Flagged subscriber IDs that should force a snapshot on their next emit. */
|
|
1068
1199
|
devtoolsInvalidateFlags = new Set();
|
|
1200
|
+
uiAssetCache = new Map();
|
|
1069
1201
|
server = null;
|
|
1070
1202
|
wsServer = null;
|
|
1071
1203
|
schedulerTimer = null;
|
|
@@ -1097,8 +1229,193 @@ export class Gateway {
|
|
|
1097
1229
|
? DEFAULT_REQUEST_TIMEOUT
|
|
1098
1230
|
: Math.floor(assertPositiveFiniteInteger("requestTimeout", Number(options.requestTimeout)));
|
|
1099
1231
|
this.auth = options.auth;
|
|
1232
|
+
this.ui = resolveGatewayUiConfig(options.ui, "/");
|
|
1233
|
+
this.uiApp = createGatewayUiApp({
|
|
1234
|
+
resolveMatch: (pathname) => this.resolveUiMatch(pathname),
|
|
1235
|
+
renderIndex: (match) => this.renderUiIndex(match),
|
|
1236
|
+
renderAsset: (match) => this.renderUiAsset(match),
|
|
1237
|
+
});
|
|
1100
1238
|
this.defaults = options.defaults;
|
|
1101
1239
|
}
|
|
1240
|
+
/**
|
|
1241
|
+
* @returns {GatewayUiMount[]}
|
|
1242
|
+
*/
|
|
1243
|
+
getUiMounts() {
|
|
1244
|
+
const mounts = [];
|
|
1245
|
+
if (this.ui) {
|
|
1246
|
+
mounts.push({ kind: "gateway", workflowKey: null, config: this.ui });
|
|
1247
|
+
}
|
|
1248
|
+
for (const [workflowKey, entry] of this.workflows.entries()) {
|
|
1249
|
+
if (entry.ui) {
|
|
1250
|
+
mounts.push({ kind: "workflow", workflowKey, config: entry.ui });
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
return mounts.sort((left, right) => right.config.path.length - left.config.path.length);
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* @param {string} pathname
|
|
1257
|
+
* @returns {GatewayUiMount | null}
|
|
1258
|
+
*/
|
|
1259
|
+
findUiMount(pathname) {
|
|
1260
|
+
for (const mount of this.getUiMounts()) {
|
|
1261
|
+
const mountPath = mount.config.path;
|
|
1262
|
+
if (mountPath === "/" || pathname === mountPath || pathname.startsWith(`${mountPath}/`)) {
|
|
1263
|
+
return mount;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
return null;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* @param {string} pathname
|
|
1270
|
+
*/
|
|
1271
|
+
resolveUiMatch(pathname) {
|
|
1272
|
+
const mount = this.findUiMount(pathname);
|
|
1273
|
+
if (!mount) {
|
|
1274
|
+
return null;
|
|
1275
|
+
}
|
|
1276
|
+
const assetBase = joinUiPath(mount.config.path, `${GATEWAY_UI_ASSET_PREFIX}/`);
|
|
1277
|
+
const assetPath = pathname.startsWith(assetBase)
|
|
1278
|
+
? pathname.slice(assetBase.length)
|
|
1279
|
+
: null;
|
|
1280
|
+
return {
|
|
1281
|
+
pathname,
|
|
1282
|
+
mountPath: mount.config.path,
|
|
1283
|
+
assetPath,
|
|
1284
|
+
config: mount,
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* @param {GatewayUiMount} mount
|
|
1289
|
+
*/
|
|
1290
|
+
uiBootConfig(mount) {
|
|
1291
|
+
return {
|
|
1292
|
+
apiVersion: SMITHERS_API_VERSION,
|
|
1293
|
+
kind: mount.kind,
|
|
1294
|
+
workflowKey: mount.workflowKey,
|
|
1295
|
+
mountPath: mount.config.path,
|
|
1296
|
+
rpcPath: "/v1/rpc",
|
|
1297
|
+
wsPath: "/",
|
|
1298
|
+
assetBasePath: joinUiPath(mount.config.path, `${GATEWAY_UI_ASSET_PREFIX}/`),
|
|
1299
|
+
props: mount.config.props ?? {},
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
/**
|
|
1303
|
+
* @param {{ config: GatewayUiMount }} match
|
|
1304
|
+
*/
|
|
1305
|
+
renderUiIndex(match) {
|
|
1306
|
+
const mount = match.config;
|
|
1307
|
+
const title = mount.config.title ?? (mount.workflowKey ? `${mount.workflowKey} | Smithers` : "Smithers");
|
|
1308
|
+
const boot = this.uiBootConfig(mount);
|
|
1309
|
+
const assetSrc = joinUiPath(mount.config.path, `${GATEWAY_UI_ASSET_PREFIX}/client.js`);
|
|
1310
|
+
return `<!doctype html>
|
|
1311
|
+
<html lang="en">
|
|
1312
|
+
<head>
|
|
1313
|
+
<meta charset="utf-8">
|
|
1314
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
1315
|
+
<title>${escapeHtml(title)}</title>
|
|
1316
|
+
</head>
|
|
1317
|
+
<body>
|
|
1318
|
+
<div id="root"></div>
|
|
1319
|
+
<script>globalThis.__SMITHERS_GATEWAY_UI__=${safeJsonScript(boot)};</script>
|
|
1320
|
+
<script type="module" src="${escapeHtml(assetSrc)}"></script>
|
|
1321
|
+
</body>
|
|
1322
|
+
</html>`;
|
|
1323
|
+
}
|
|
1324
|
+
/**
|
|
1325
|
+
* @param {{ config: GatewayUiMount; assetPath: string | null }} match
|
|
1326
|
+
*/
|
|
1327
|
+
async renderUiAsset(match) {
|
|
1328
|
+
if (match.assetPath !== "client.js") {
|
|
1329
|
+
return null;
|
|
1330
|
+
}
|
|
1331
|
+
const body = await this.bundleUiEntry(match.config.config);
|
|
1332
|
+
return {
|
|
1333
|
+
body,
|
|
1334
|
+
contentType: "text/javascript; charset=utf-8",
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
/**
|
|
1338
|
+
* @param {ResolvedGatewayUiConfig} config
|
|
1339
|
+
* @returns {Promise<string>}
|
|
1340
|
+
*/
|
|
1341
|
+
async bundleUiEntry(config) {
|
|
1342
|
+
const cached = this.uiAssetCache.get(config.entry);
|
|
1343
|
+
if (cached) {
|
|
1344
|
+
return cached;
|
|
1345
|
+
}
|
|
1346
|
+
if (typeof Bun === "undefined" || typeof Bun.build !== "function") {
|
|
1347
|
+
throw new SmithersError("INVALID_INPUT", "Gateway UI bundling requires Bun.build.");
|
|
1348
|
+
}
|
|
1349
|
+
const result = await Bun.build({
|
|
1350
|
+
entrypoints: [config.entry],
|
|
1351
|
+
root: process.cwd(),
|
|
1352
|
+
target: "browser",
|
|
1353
|
+
format: "esm",
|
|
1354
|
+
sourcemap: "inline",
|
|
1355
|
+
minify: false,
|
|
1356
|
+
jsx: {
|
|
1357
|
+
runtime: "automatic",
|
|
1358
|
+
importSource: "react",
|
|
1359
|
+
},
|
|
1360
|
+
});
|
|
1361
|
+
if (!result.success) {
|
|
1362
|
+
const message = result.logs?.map((entry) => entry.message).filter(Boolean).join("\n")
|
|
1363
|
+
|| `Failed to build Gateway UI entry ${config.entry}`;
|
|
1364
|
+
throw new SmithersError("INVALID_INPUT", message);
|
|
1365
|
+
}
|
|
1366
|
+
const output = result.outputs.find((entry) => entry.path.endsWith(".js")) ?? result.outputs[0];
|
|
1367
|
+
const body = await output.text();
|
|
1368
|
+
this.uiAssetCache.set(config.entry, body);
|
|
1369
|
+
return body;
|
|
1370
|
+
}
|
|
1371
|
+
/**
|
|
1372
|
+
* @param {IncomingMessage} req
|
|
1373
|
+
* @param {ServerResponse} res
|
|
1374
|
+
*/
|
|
1375
|
+
async handleUiHttp(req, res) {
|
|
1376
|
+
if ((req.method ?? "GET") !== "GET" && (req.method ?? "GET") !== "HEAD") {
|
|
1377
|
+
return false;
|
|
1378
|
+
}
|
|
1379
|
+
const host = headerValue(req, "host") ?? "127.0.0.1";
|
|
1380
|
+
const request = new Request(`http://${host}${req.url ?? "/"}`, {
|
|
1381
|
+
method: "GET",
|
|
1382
|
+
headers: nodeHeadersToFetchHeaders(req.headers),
|
|
1383
|
+
});
|
|
1384
|
+
const response = await this.uiApp.fetch(request);
|
|
1385
|
+
if (response.status === 404 && response.headers.get("x-smithers-ui-miss") === "1") {
|
|
1386
|
+
return false;
|
|
1387
|
+
}
|
|
1388
|
+
await writeFetchResponse(res, response, (req.method ?? "GET") === "HEAD");
|
|
1389
|
+
return true;
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1392
|
+
* @param {string} key
|
|
1393
|
+
* @param {RegisteredWorkflow} entry
|
|
1394
|
+
*/
|
|
1395
|
+
workflowSummary(key, entry) {
|
|
1396
|
+
return {
|
|
1397
|
+
key,
|
|
1398
|
+
...(entry.workflow.readableName ? { readableName: entry.workflow.readableName } : {}),
|
|
1399
|
+
...(entry.workflow.description ? { description: entry.workflow.description } : {}),
|
|
1400
|
+
hasUi: Boolean(entry.ui),
|
|
1401
|
+
uiPath: entry.ui?.path ?? null,
|
|
1402
|
+
};
|
|
1403
|
+
}
|
|
1404
|
+
/**
|
|
1405
|
+
* @param {boolean | undefined} hasUi
|
|
1406
|
+
*/
|
|
1407
|
+
listWorkflowSummaries(hasUi) {
|
|
1408
|
+
const rows = [];
|
|
1409
|
+
for (const [key, entry] of this.workflows.entries()) {
|
|
1410
|
+
const summary = this.workflowSummary(key, entry);
|
|
1411
|
+
if (hasUi !== undefined && summary.hasUi !== hasUi) {
|
|
1412
|
+
continue;
|
|
1413
|
+
}
|
|
1414
|
+
rows.push(summary);
|
|
1415
|
+
}
|
|
1416
|
+
rows.sort((left, right) => left.key.localeCompare(right.key));
|
|
1417
|
+
return rows;
|
|
1418
|
+
}
|
|
1102
1419
|
authModeLabel() {
|
|
1103
1420
|
return gatewayAuthMode(this.auth);
|
|
1104
1421
|
}
|
|
@@ -1770,16 +2087,18 @@ export class Gateway {
|
|
|
1770
2087
|
/**
|
|
1771
2088
|
* @param {string} key
|
|
1772
2089
|
* @param {SmithersWorkflow} workflow
|
|
1773
|
-
* @param {
|
|
2090
|
+
* @param {GatewayRegisterOptions} [options]
|
|
1774
2091
|
* @returns {this}
|
|
1775
2092
|
*/
|
|
1776
2093
|
register(key, workflow, options) {
|
|
1777
2094
|
ensureSmithersTables(workflow.db);
|
|
2095
|
+
const ui = resolveGatewayUiConfig(options?.ui, `/workflows/${encodeURIComponent(key)}`);
|
|
1778
2096
|
this.workflows.set(key, {
|
|
1779
2097
|
key,
|
|
1780
2098
|
workflow,
|
|
1781
2099
|
schedule: options?.schedule,
|
|
1782
2100
|
webhook: options?.webhook,
|
|
2101
|
+
ui,
|
|
1783
2102
|
});
|
|
1784
2103
|
// Startup recovery: any audit row left in `in_progress` from a prior
|
|
1785
2104
|
// crash is flipped to `partial` and the associated run is flagged as
|
|
@@ -1795,7 +2114,7 @@ export class Gateway {
|
|
|
1795
2114
|
return this;
|
|
1796
2115
|
}
|
|
1797
2116
|
/**
|
|
1798
|
-
* @param {{ port?: number; host?: string }} [options]
|
|
2117
|
+
* @param {{ port?: number; host?: string; path?: string }} [options]
|
|
1799
2118
|
*/
|
|
1800
2119
|
async listen(options = {}) {
|
|
1801
2120
|
if (this.server) {
|
|
@@ -1832,6 +2151,9 @@ export class Gateway {
|
|
|
1832
2151
|
if ((req.method ?? "GET") === "POST" && (req.url ?? "/") === "/rpc") {
|
|
1833
2152
|
return this.handleHttpRpc(req, res);
|
|
1834
2153
|
}
|
|
2154
|
+
if (await this.handleUiHttp(req, res)) {
|
|
2155
|
+
return;
|
|
2156
|
+
}
|
|
1835
2157
|
return sendJson(res, 404, { error: { code: "NOT_FOUND", message: "Route not found" } });
|
|
1836
2158
|
});
|
|
1837
2159
|
server.headersTimeout = this.headersTimeout;
|
|
@@ -1863,6 +2185,10 @@ export class Gateway {
|
|
|
1863
2185
|
});
|
|
1864
2186
|
});
|
|
1865
2187
|
await new Promise((resolve) => {
|
|
2188
|
+
if (options.path !== undefined) {
|
|
2189
|
+
server.listen(options.path, () => resolve());
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
1866
2192
|
if (options.host === undefined) {
|
|
1867
2193
|
server.listen(options.port ?? 7331, () => resolve());
|
|
1868
2194
|
return;
|
|
@@ -2698,6 +3024,7 @@ export class Gateway {
|
|
|
2698
3024
|
const request = parseApprovalRequest(parseJson(approval.requestJson), node?.label ?? approval.nodeId);
|
|
2699
3025
|
approvals.push({
|
|
2700
3026
|
runId: approval.runId,
|
|
3027
|
+
workflowKey: entry.key,
|
|
2701
3028
|
nodeId: approval.nodeId,
|
|
2702
3029
|
iteration: approval.iteration ?? 0,
|
|
2703
3030
|
requestTitle: request.title ?? node?.label ?? approval.nodeId,
|
|
@@ -2945,6 +3272,12 @@ export class Gateway {
|
|
|
2945
3272
|
const status = asString(params.status) ?? asString(filter.status);
|
|
2946
3273
|
return responseOk(frame.id, await this.listRunsAcrossWorkflows(limit, status));
|
|
2947
3274
|
}
|
|
3275
|
+
case "workflows.list":
|
|
3276
|
+
case "listWorkflows": {
|
|
3277
|
+
const filter = asObject(params.filter) ?? {};
|
|
3278
|
+
const hasUi = asBoolean(params.hasUi) ?? asBoolean(filter.hasUi);
|
|
3279
|
+
return responseOk(frame.id, this.listWorkflowSummaries(hasUi));
|
|
3280
|
+
}
|
|
2948
3281
|
case "runs.create":
|
|
2949
3282
|
case "launchRun": {
|
|
2950
3283
|
const workflowKey = asString(params.workflow);
|
|
@@ -3548,7 +3881,23 @@ export class Gateway {
|
|
|
3548
3881
|
return responseOk(frame.id, diffRawSnapshots(leftSnapshot, rightSnapshot));
|
|
3549
3882
|
}
|
|
3550
3883
|
case "approvals.list":
|
|
3551
|
-
|
|
3884
|
+
case "listApprovals": {
|
|
3885
|
+
const filter = asObject(params.filter) ?? {};
|
|
3886
|
+
const runId = asString(params.runId) ?? asString(filter.runId);
|
|
3887
|
+
const workflow = asString(params.workflow) ?? asString(filter.workflow);
|
|
3888
|
+
const limit = asOptionalPositiveInt(params.limit ?? filter.limit, "limit");
|
|
3889
|
+
let approvals = await this.listPendingApprovals();
|
|
3890
|
+
if (runId) {
|
|
3891
|
+
approvals = approvals.filter((approval) => approval.runId === runId);
|
|
3892
|
+
}
|
|
3893
|
+
if (workflow) {
|
|
3894
|
+
approvals = approvals.filter((approval) => approval.workflowKey === workflow);
|
|
3895
|
+
}
|
|
3896
|
+
if (limit !== undefined) {
|
|
3897
|
+
approvals = approvals.slice(0, limit);
|
|
3898
|
+
}
|
|
3899
|
+
return responseOk(frame.id, approvals);
|
|
3900
|
+
}
|
|
3552
3901
|
case "approvals.decide":
|
|
3553
3902
|
case "submitApproval": {
|
|
3554
3903
|
const runId = asString(params.runId);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {{
|
|
5
|
+
* pathname: string;
|
|
6
|
+
* mountPath: string;
|
|
7
|
+
* assetPath: string | null;
|
|
8
|
+
* config: Record<string, unknown>;
|
|
9
|
+
* }} GatewayUiMatch
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {{
|
|
14
|
+
* resolveMatch: (pathname: string) => GatewayUiMatch | null;
|
|
15
|
+
* renderIndex: (match: GatewayUiMatch) => string;
|
|
16
|
+
* renderAsset: (match: GatewayUiMatch) => Promise<{ body: string; contentType: string } | null>;
|
|
17
|
+
* }} options
|
|
18
|
+
*/
|
|
19
|
+
export function createGatewayUiApp(options) {
|
|
20
|
+
const app = new Hono();
|
|
21
|
+
app.get("*", async (c) => {
|
|
22
|
+
const url = new URL(c.req.url);
|
|
23
|
+
const match = options.resolveMatch(url.pathname);
|
|
24
|
+
if (!match) {
|
|
25
|
+
return new Response("Not Found", {
|
|
26
|
+
status: 404,
|
|
27
|
+
headers: { "x-smithers-ui-miss": "1" },
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
if (match.assetPath) {
|
|
31
|
+
const asset = await options.renderAsset(match);
|
|
32
|
+
if (!asset) {
|
|
33
|
+
return c.text("Not Found", 404);
|
|
34
|
+
}
|
|
35
|
+
return c.body(asset.body, 200, {
|
|
36
|
+
"Content-Type": asset.contentType,
|
|
37
|
+
"Cache-Control": "no-store",
|
|
38
|
+
"X-Content-Type-Options": "nosniff",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return c.html(options.renderIndex(match), 200, {
|
|
42
|
+
"Cache-Control": "no-store",
|
|
43
|
+
"X-Content-Type-Options": "nosniff",
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
return app;
|
|
47
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _smithers_orchestrator_db_adapter_RunRow from '@smithers-orchestrator/db/adapter/RunRow';
|
|
2
2
|
import * as node_http from 'node:http';
|
|
3
|
-
import
|
|
4
|
-
import * as
|
|
5
|
-
import * as _smithers_components_SmithersWorkflow from '@smithers-orchestrator/components/SmithersWorkflow';
|
|
3
|
+
import * as _smithers_orchestrator_observability_SmithersEvent from '@smithers-orchestrator/observability/SmithersEvent';
|
|
4
|
+
import * as _smithers_orchestrator_components_SmithersWorkflow from '@smithers-orchestrator/components/SmithersWorkflow';
|
|
6
5
|
import { SmithersWorkflow as SmithersWorkflow$1 } from '@smithers-orchestrator/components/SmithersWorkflow';
|
|
6
|
+
import * as hono from 'hono';
|
|
7
|
+
import { Hono } from 'hono';
|
|
8
|
+
import * as hono_types from 'hono/types';
|
|
7
9
|
import { Effect } from 'effect';
|
|
8
|
-
import * as
|
|
10
|
+
import * as _smithers_orchestrator_db_adapter from '@smithers-orchestrator/db/adapter';
|
|
9
11
|
import { SmithersDb as SmithersDb$4 } from '@smithers-orchestrator/db/adapter';
|
|
10
|
-
import * as hono_types from 'hono/types';
|
|
11
|
-
import { Hono } from 'hono';
|
|
12
12
|
import * as effect_Fiber from 'effect/Fiber';
|
|
13
|
-
import * as
|
|
14
|
-
import * as
|
|
15
|
-
import * as
|
|
16
|
-
import * as
|
|
13
|
+
import * as _smithers_orchestrator_protocol_errors from '@smithers-orchestrator/protocol/errors';
|
|
14
|
+
import * as _smithers_orchestrator_devtools_snapshotSerializer from '@smithers-orchestrator/devtools/snapshotSerializer';
|
|
15
|
+
import * as _smithers_orchestrator_protocol_devtools from '@smithers-orchestrator/protocol/devtools';
|
|
16
|
+
import * as _smithers_orchestrator_engine_effect_DiffBundle from '@smithers-orchestrator/engine/effect/DiffBundle';
|
|
17
17
|
import { DiffBundle } from '@smithers-orchestrator/engine/effect/DiffBundle';
|
|
18
18
|
import { selectOutputRow } from '@smithers-orchestrator/db/output';
|
|
19
|
-
import * as
|
|
19
|
+
import * as _smithers_orchestrator_time_travel_jumpToFrame from '@smithers-orchestrator/time-travel/jumpToFrame';
|
|
20
20
|
export { JumpToFrameError } from '@smithers-orchestrator/time-travel/jumpToFrame';
|
|
21
21
|
|
|
22
22
|
type ServerOptions$1 = {
|
|
@@ -26,16 +26,33 @@ type ServerOptions$1 = {
|
|
|
26
26
|
maxBodyBytes?: number;
|
|
27
27
|
rootDir?: string;
|
|
28
28
|
allowNetwork?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Maximum time (in milliseconds) allowed for the HTTP parser to receive the
|
|
31
|
+
* complete headers of a single request. Helps mitigate slowloris attacks.
|
|
32
|
+
* @default 30000
|
|
33
|
+
*/
|
|
34
|
+
headersTimeout?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Maximum time (in milliseconds) allowed for a single request to be received
|
|
37
|
+
* and parsed, including the body. Helps mitigate slowloris attacks.
|
|
38
|
+
* @default 60000
|
|
39
|
+
*/
|
|
40
|
+
requestTimeout?: number;
|
|
29
41
|
};
|
|
30
42
|
|
|
31
43
|
type ResponseFrame$1 = {
|
|
32
44
|
type: "res";
|
|
33
45
|
id: string;
|
|
34
46
|
ok: boolean;
|
|
47
|
+
apiVersion?: "v1";
|
|
35
48
|
payload?: unknown;
|
|
36
49
|
error?: {
|
|
50
|
+
version?: "v1";
|
|
37
51
|
code: string;
|
|
38
52
|
message: string;
|
|
53
|
+
requiredScope?: string;
|
|
54
|
+
refresh?: string;
|
|
55
|
+
details?: unknown;
|
|
39
56
|
};
|
|
40
57
|
};
|
|
41
58
|
|
|
@@ -70,6 +87,10 @@ type GatewayTokenGrant$1 = {
|
|
|
70
87
|
role: string;
|
|
71
88
|
scopes: string[];
|
|
72
89
|
userId?: string;
|
|
90
|
+
tokenId?: string;
|
|
91
|
+
issuedAtMs?: number;
|
|
92
|
+
expiresAtMs?: number;
|
|
93
|
+
revokedAtMs?: number;
|
|
73
94
|
};
|
|
74
95
|
|
|
75
96
|
type GatewayAuthConfig$1 = {
|
|
@@ -98,15 +119,54 @@ type GatewayDefaults$1 = {
|
|
|
98
119
|
cliAgentTools?: "all" | "explicit-only";
|
|
99
120
|
};
|
|
100
121
|
|
|
122
|
+
type GatewayUiConfig$1 = {
|
|
123
|
+
/**
|
|
124
|
+
* Browser entry module for the React app. Smithers bundles this with Bun and
|
|
125
|
+
* serves it from the Gateway origin.
|
|
126
|
+
*/
|
|
127
|
+
entry: string;
|
|
128
|
+
/**
|
|
129
|
+
* URL path where the UI is mounted. Gateway-level UI defaults to `/`;
|
|
130
|
+
* workflow-level UI defaults to `/workflows/<workflowKey>`.
|
|
131
|
+
*/
|
|
132
|
+
path?: string;
|
|
133
|
+
/**
|
|
134
|
+
* Document title for the generated HTML shell.
|
|
135
|
+
*/
|
|
136
|
+
title?: string;
|
|
137
|
+
/**
|
|
138
|
+
* JSON-serializable boot data exposed to the browser.
|
|
139
|
+
*/
|
|
140
|
+
props?: Record<string, unknown>;
|
|
141
|
+
};
|
|
142
|
+
|
|
101
143
|
type GatewayOptions$1 = {
|
|
102
144
|
protocol?: number;
|
|
103
145
|
features?: string[];
|
|
104
146
|
heartbeatMs?: number;
|
|
105
147
|
auth?: GatewayAuthConfig$1;
|
|
148
|
+
ui?: GatewayUiConfig$1;
|
|
106
149
|
defaults?: GatewayDefaults$1;
|
|
107
150
|
maxBodyBytes?: number;
|
|
108
151
|
maxPayload?: number;
|
|
109
152
|
maxConnections?: number;
|
|
153
|
+
/**
|
|
154
|
+
* Per-run replay window for Gateway run event streams.
|
|
155
|
+
* @default 10000
|
|
156
|
+
*/
|
|
157
|
+
eventWindowSize?: number;
|
|
158
|
+
/**
|
|
159
|
+
* Maximum time (in milliseconds) allowed for the HTTP parser to receive the
|
|
160
|
+
* complete headers of a single request. Helps mitigate slowloris attacks.
|
|
161
|
+
* @default 30000
|
|
162
|
+
*/
|
|
163
|
+
headersTimeout?: number;
|
|
164
|
+
/**
|
|
165
|
+
* Maximum time (in milliseconds) allowed for a single request to be received
|
|
166
|
+
* and parsed, including the body. Helps mitigate slowloris attacks.
|
|
167
|
+
* @default 60000
|
|
168
|
+
*/
|
|
169
|
+
requestTimeout?: number;
|
|
110
170
|
};
|
|
111
171
|
|
|
112
172
|
type ConnectRequest$1 = {
|
|
@@ -144,12 +204,19 @@ type HelloResponse$1 = {
|
|
|
144
204
|
};
|
|
145
205
|
};
|
|
146
206
|
|
|
207
|
+
type GatewayRegisterOptions$1 = {
|
|
208
|
+
schedule?: string;
|
|
209
|
+
webhook?: GatewayWebhookConfig$1;
|
|
210
|
+
ui?: GatewayUiConfig$1;
|
|
211
|
+
};
|
|
212
|
+
|
|
147
213
|
type EventFrame$1 = {
|
|
148
214
|
type: "event";
|
|
149
215
|
event: string;
|
|
150
216
|
payload?: unknown;
|
|
151
217
|
seq: number;
|
|
152
218
|
stateVersion: number;
|
|
219
|
+
apiVersion?: "v1";
|
|
153
220
|
};
|
|
154
221
|
|
|
155
222
|
/**
|
|
@@ -175,7 +242,7 @@ declare function assertGatewayInputDepthWithinBounds(value: unknown, maxDepth?:
|
|
|
175
242
|
/**
|
|
176
243
|
* @param {string | undefined} code
|
|
177
244
|
*/
|
|
178
|
-
declare function statusForRpcError(code: string | undefined): 401 | 403 | 404 |
|
|
245
|
+
declare function statusForRpcError(code: string | undefined): 400 | 401 | 403 | 404 | 409 | 429 | 413 | 501 | 500;
|
|
179
246
|
declare const GATEWAY_RPC_MAX_PAYLOAD_BYTES: 1048576;
|
|
180
247
|
declare const GATEWAY_RPC_MAX_DEPTH: 32;
|
|
181
248
|
declare const GATEWAY_RPC_MAX_ARRAY_LENGTH: 256;
|
|
@@ -195,7 +262,12 @@ declare class Gateway {
|
|
|
195
262
|
maxBodyBytes: number;
|
|
196
263
|
maxPayload: number;
|
|
197
264
|
maxConnections: number;
|
|
265
|
+
eventWindowSize: number;
|
|
266
|
+
headersTimeout: number;
|
|
267
|
+
requestTimeout: number;
|
|
198
268
|
auth: GatewayAuthConfig$1 | undefined;
|
|
269
|
+
ui: ResolvedGatewayUiConfig | null;
|
|
270
|
+
uiApp: hono.Hono<hono_types.BlankEnv, hono_types.BlankSchema, "/">;
|
|
199
271
|
defaults: GatewayDefaults$1 | undefined;
|
|
200
272
|
workflows: Map<any, any>;
|
|
201
273
|
connections: Set<any>;
|
|
@@ -203,15 +275,95 @@ declare class Gateway {
|
|
|
203
275
|
activeRuns: Map<any, any>;
|
|
204
276
|
inflightRuns: Map<any, any>;
|
|
205
277
|
devtoolsSubscribers: Map<any, any>;
|
|
278
|
+
runEventWindows: Map<any, any>;
|
|
206
279
|
/** Absolute active subscriber count per runId (gauge source of truth). */
|
|
207
280
|
devtoolsSubscriberCounts: Map<any, any>;
|
|
208
281
|
/** Flagged subscriber IDs that should force a snapshot on their next emit. */
|
|
209
282
|
devtoolsInvalidateFlags: Set<any>;
|
|
283
|
+
uiAssetCache: Map<any, any>;
|
|
210
284
|
server: null;
|
|
211
285
|
wsServer: null;
|
|
212
286
|
schedulerTimer: null;
|
|
213
287
|
stateVersion: number;
|
|
214
288
|
startedAtMs: number;
|
|
289
|
+
/**
|
|
290
|
+
* @returns {GatewayUiMount[]}
|
|
291
|
+
*/
|
|
292
|
+
getUiMounts(): GatewayUiMount[];
|
|
293
|
+
/**
|
|
294
|
+
* @param {string} pathname
|
|
295
|
+
* @returns {GatewayUiMount | null}
|
|
296
|
+
*/
|
|
297
|
+
findUiMount(pathname: string): GatewayUiMount | null;
|
|
298
|
+
/**
|
|
299
|
+
* @param {string} pathname
|
|
300
|
+
*/
|
|
301
|
+
resolveUiMatch(pathname: string): {
|
|
302
|
+
pathname: string;
|
|
303
|
+
mountPath: string;
|
|
304
|
+
assetPath: string | null;
|
|
305
|
+
config: GatewayUiMount;
|
|
306
|
+
} | null;
|
|
307
|
+
/**
|
|
308
|
+
* @param {GatewayUiMount} mount
|
|
309
|
+
*/
|
|
310
|
+
uiBootConfig(mount: GatewayUiMount): {
|
|
311
|
+
apiVersion: "v1";
|
|
312
|
+
kind: "workflow" | "gateway";
|
|
313
|
+
workflowKey: string | null;
|
|
314
|
+
mountPath: string;
|
|
315
|
+
rpcPath: string;
|
|
316
|
+
wsPath: string;
|
|
317
|
+
assetBasePath: string;
|
|
318
|
+
props: Record<string, unknown>;
|
|
319
|
+
};
|
|
320
|
+
/**
|
|
321
|
+
* @param {{ config: GatewayUiMount }} match
|
|
322
|
+
*/
|
|
323
|
+
renderUiIndex(match: {
|
|
324
|
+
config: GatewayUiMount;
|
|
325
|
+
}): string;
|
|
326
|
+
/**
|
|
327
|
+
* @param {{ config: GatewayUiMount; assetPath: string | null }} match
|
|
328
|
+
*/
|
|
329
|
+
renderUiAsset(match: {
|
|
330
|
+
config: GatewayUiMount;
|
|
331
|
+
assetPath: string | null;
|
|
332
|
+
}): Promise<{
|
|
333
|
+
body: string;
|
|
334
|
+
contentType: string;
|
|
335
|
+
} | null>;
|
|
336
|
+
/**
|
|
337
|
+
* @param {ResolvedGatewayUiConfig} config
|
|
338
|
+
* @returns {Promise<string>}
|
|
339
|
+
*/
|
|
340
|
+
bundleUiEntry(config: ResolvedGatewayUiConfig): Promise<string>;
|
|
341
|
+
/**
|
|
342
|
+
* @param {IncomingMessage} req
|
|
343
|
+
* @param {ServerResponse} res
|
|
344
|
+
*/
|
|
345
|
+
handleUiHttp(req: IncomingMessage, res: ServerResponse$1): Promise<boolean>;
|
|
346
|
+
/**
|
|
347
|
+
* @param {string} key
|
|
348
|
+
* @param {RegisteredWorkflow} entry
|
|
349
|
+
*/
|
|
350
|
+
workflowSummary(key: string, entry: RegisteredWorkflow): {
|
|
351
|
+
hasUi: boolean;
|
|
352
|
+
uiPath: string | null;
|
|
353
|
+
description?: string | undefined;
|
|
354
|
+
readableName?: string | undefined;
|
|
355
|
+
key: string;
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* @param {boolean | undefined} hasUi
|
|
359
|
+
*/
|
|
360
|
+
listWorkflowSummaries(hasUi: boolean | undefined): {
|
|
361
|
+
hasUi: boolean;
|
|
362
|
+
uiPath: string | null;
|
|
363
|
+
description?: string | undefined;
|
|
364
|
+
readableName?: string | undefined;
|
|
365
|
+
key: string;
|
|
366
|
+
}[];
|
|
215
367
|
authModeLabel(): string;
|
|
216
368
|
/**
|
|
217
369
|
* @param {string} [runId]
|
|
@@ -269,6 +421,61 @@ declare class Gateway {
|
|
|
269
421
|
*/
|
|
270
422
|
cleanupDevToolsSubscribers(connection: ConnectionState): void;
|
|
271
423
|
/**
|
|
424
|
+
* @param {string} runId
|
|
425
|
+
* @returns {{ nextSeq: number; window: Array<Record<string, unknown>> }}
|
|
426
|
+
*/
|
|
427
|
+
getRunEventWindow(runId: string): {
|
|
428
|
+
nextSeq: number;
|
|
429
|
+
window: Array<Record<string, unknown>>;
|
|
430
|
+
};
|
|
431
|
+
/**
|
|
432
|
+
* @param {string} event
|
|
433
|
+
* @param {unknown} payload
|
|
434
|
+
* @param {number} stateVersion
|
|
435
|
+
* @returns {Record<string, unknown> | null}
|
|
436
|
+
*/
|
|
437
|
+
appendRunEventWindow(event: string, payload: unknown, stateVersion: number): Record<string, unknown> | null;
|
|
438
|
+
/**
|
|
439
|
+
* @param {string} runId
|
|
440
|
+
* @returns {number}
|
|
441
|
+
*/
|
|
442
|
+
getRunEventCurrentSeq(runId: string): number;
|
|
443
|
+
/**
|
|
444
|
+
* @param {ConnectionState} connection
|
|
445
|
+
* @param {string} streamId
|
|
446
|
+
* @param {string} runId
|
|
447
|
+
* @returns {() => void}
|
|
448
|
+
*/
|
|
449
|
+
registerRunEventSubscriber(connection: ConnectionState, streamId: string, runId: string): () => void;
|
|
450
|
+
/**
|
|
451
|
+
* @param {ConnectionState} connection
|
|
452
|
+
* @param {string} streamId
|
|
453
|
+
*/
|
|
454
|
+
unregisterRunEventSubscriber(connection: ConnectionState, streamId: string): void;
|
|
455
|
+
/**
|
|
456
|
+
* @param {ConnectionState} connection
|
|
457
|
+
*/
|
|
458
|
+
cleanupRunEventSubscribers(connection: ConnectionState): void;
|
|
459
|
+
/**
|
|
460
|
+
* @param {ConnectionState} connection
|
|
461
|
+
* @param {string} streamId
|
|
462
|
+
* @param {Record<string, unknown>} frame
|
|
463
|
+
*/
|
|
464
|
+
sendRunEventStreamFrame(connection: ConnectionState, streamId: string, frame: Record<string, unknown>): void;
|
|
465
|
+
/**
|
|
466
|
+
* @param {ConnectionState} connection
|
|
467
|
+
* @param {string} streamId
|
|
468
|
+
* @param {string} runId
|
|
469
|
+
* @param {number} fromSeq
|
|
470
|
+
* @param {number} toSeq
|
|
471
|
+
* @param {unknown} snapshot
|
|
472
|
+
*/
|
|
473
|
+
sendRunGapResync(connection: ConnectionState, streamId: string, runId: string, fromSeq: number, toSeq: number, snapshot: unknown): void;
|
|
474
|
+
/**
|
|
475
|
+
* @param {string} runId
|
|
476
|
+
*/
|
|
477
|
+
buildRunSnapshot(runId: string): Promise<any>;
|
|
478
|
+
/**
|
|
272
479
|
* @param {GatewayTransport} transport
|
|
273
480
|
* @param {string} frameType
|
|
274
481
|
* @param {GatewayMetricLabels} [labels]
|
|
@@ -307,7 +514,7 @@ declare class Gateway {
|
|
|
307
514
|
* @param {number} status
|
|
308
515
|
* @param {ResponseFrame} response
|
|
309
516
|
*/
|
|
310
|
-
sendHttpRpcResponse(res: ServerResponse, status: number, response: ResponseFrame): void;
|
|
517
|
+
sendHttpRpcResponse(res: ServerResponse$1, status: number, response: ResponseFrame): void;
|
|
311
518
|
/**
|
|
312
519
|
* @param {SmithersDb} adapter
|
|
313
520
|
* @param {string} runId
|
|
@@ -327,23 +534,21 @@ declare class Gateway {
|
|
|
327
534
|
* @param {ServerResponse} res
|
|
328
535
|
* @param {string} workflowKey
|
|
329
536
|
*/
|
|
330
|
-
handleWebhook(req: IncomingMessage, res: ServerResponse, workflowKey: string): Promise<void>;
|
|
537
|
+
handleWebhook(req: IncomingMessage, res: ServerResponse$1, workflowKey: string): Promise<void>;
|
|
331
538
|
/**
|
|
332
539
|
* @param {string} key
|
|
333
540
|
* @param {SmithersWorkflow} workflow
|
|
334
|
-
* @param {
|
|
541
|
+
* @param {GatewayRegisterOptions} [options]
|
|
335
542
|
* @returns {this}
|
|
336
543
|
*/
|
|
337
|
-
register(key: string, workflow: SmithersWorkflow, options?:
|
|
338
|
-
schedule?: string;
|
|
339
|
-
webhook?: GatewayWebhookConfig;
|
|
340
|
-
}): this;
|
|
544
|
+
register(key: string, workflow: SmithersWorkflow, options?: GatewayRegisterOptions): this;
|
|
341
545
|
/**
|
|
342
|
-
* @param {{ port?: number; host?: string }} [options]
|
|
546
|
+
* @param {{ port?: number; host?: string; path?: string }} [options]
|
|
343
547
|
*/
|
|
344
548
|
listen(options?: {
|
|
345
549
|
port?: number;
|
|
346
550
|
host?: string;
|
|
551
|
+
path?: string;
|
|
347
552
|
}): Promise<node_http.Server<typeof node_http.IncomingMessage, typeof node_http.ServerResponse>>;
|
|
348
553
|
close(): Promise<void>;
|
|
349
554
|
startScheduler(): void;
|
|
@@ -419,8 +624,9 @@ declare class Gateway {
|
|
|
419
624
|
/**
|
|
420
625
|
* @param {IncomingMessage} req
|
|
421
626
|
* @param {ServerResponse} res
|
|
627
|
+
* @param {string} [forcedMethod]
|
|
422
628
|
*/
|
|
423
|
-
handleHttpRpc(req: IncomingMessage, res: ServerResponse): Promise<void>;
|
|
629
|
+
handleHttpRpc(req: IncomingMessage, res: ServerResponse$1, forcedMethod?: string): Promise<void>;
|
|
424
630
|
/**
|
|
425
631
|
* @param {ConnectionState} connection
|
|
426
632
|
* @param {ResponseFrame} frame
|
|
@@ -441,6 +647,7 @@ declare class Gateway {
|
|
|
441
647
|
runs: any[];
|
|
442
648
|
approvals: {
|
|
443
649
|
runId: any;
|
|
650
|
+
workflowKey: any;
|
|
444
651
|
nodeId: any;
|
|
445
652
|
iteration: any;
|
|
446
653
|
requestTitle: any;
|
|
@@ -465,6 +672,7 @@ declare class Gateway {
|
|
|
465
672
|
listRunsAcrossWorkflows(limit?: number, status?: string): Promise<any[]>;
|
|
466
673
|
listPendingApprovals(): Promise<{
|
|
467
674
|
runId: any;
|
|
675
|
+
workflowKey: any;
|
|
468
676
|
nodeId: any;
|
|
469
677
|
iteration: any;
|
|
470
678
|
requestTitle: any;
|
|
@@ -511,7 +719,9 @@ declare class Gateway {
|
|
|
511
719
|
}
|
|
512
720
|
type EventFrame = EventFrame$1;
|
|
513
721
|
type GatewayDefaults = GatewayDefaults$1;
|
|
722
|
+
type GatewayRegisterOptions = GatewayRegisterOptions$1;
|
|
514
723
|
type GatewayTokenGrant = GatewayTokenGrant$1;
|
|
724
|
+
type GatewayUiConfig = GatewayUiConfig$1;
|
|
515
725
|
type HelloResponse = HelloResponse$1;
|
|
516
726
|
type GatewayWebhookRunConfig = GatewayWebhookRunConfig$1;
|
|
517
727
|
type GatewayWebhookSignalConfig = GatewayWebhookSignalConfig$1;
|
|
@@ -522,9 +732,9 @@ type GatewayWebhookConfig = GatewayWebhookConfig$1;
|
|
|
522
732
|
type IncomingMessage = node_http.IncomingMessage;
|
|
523
733
|
type RequestFrame = RequestFrame$1;
|
|
524
734
|
type ResponseFrame = ResponseFrame$1;
|
|
525
|
-
type ServerResponse = node_http.ServerResponse;
|
|
526
|
-
type SmithersWorkflow =
|
|
527
|
-
type SmithersEvent$1 =
|
|
735
|
+
type ServerResponse$1 = node_http.ServerResponse;
|
|
736
|
+
type SmithersWorkflow = _smithers_orchestrator_components_SmithersWorkflow.SmithersWorkflow<unknown>;
|
|
737
|
+
type SmithersEvent$1 = _smithers_orchestrator_observability_SmithersEvent.SmithersEvent;
|
|
528
738
|
type GatewayMetricLabels = Record<string, string | number | null | undefined>;
|
|
529
739
|
type GatewayTransport = "ws" | "http";
|
|
530
740
|
type GatewayRequestContext = {
|
|
@@ -532,6 +742,7 @@ type GatewayRequestContext = {
|
|
|
532
742
|
role?: string;
|
|
533
743
|
scopes?: string[];
|
|
534
744
|
userId?: string | null;
|
|
745
|
+
tokenId?: string | null;
|
|
535
746
|
origin?: string;
|
|
536
747
|
transport?: GatewayTransport;
|
|
537
748
|
};
|
|
@@ -550,6 +761,7 @@ type RunStartAuthContext = {
|
|
|
550
761
|
role: string;
|
|
551
762
|
scopes: string[];
|
|
552
763
|
userId?: string | null;
|
|
764
|
+
tokenId?: string | null;
|
|
553
765
|
connectionId?: string;
|
|
554
766
|
};
|
|
555
767
|
type RegisteredWorkflow = {
|
|
@@ -558,6 +770,7 @@ type RegisteredWorkflow = {
|
|
|
558
770
|
key: string;
|
|
559
771
|
schedule?: string;
|
|
560
772
|
webhook?: GatewayWebhookConfig;
|
|
773
|
+
ui?: ResolvedGatewayUiConfig | null;
|
|
561
774
|
};
|
|
562
775
|
type ResolvedRun = {
|
|
563
776
|
runId: string;
|
|
@@ -565,6 +778,17 @@ type ResolvedRun = {
|
|
|
565
778
|
workflow: SmithersWorkflow;
|
|
566
779
|
adapter: SmithersDb$4;
|
|
567
780
|
};
|
|
781
|
+
type ResolvedGatewayUiConfig = {
|
|
782
|
+
entry: string;
|
|
783
|
+
path: string;
|
|
784
|
+
title?: string;
|
|
785
|
+
props?: Record<string, unknown>;
|
|
786
|
+
};
|
|
787
|
+
type GatewayUiMount = {
|
|
788
|
+
kind: "gateway" | "workflow";
|
|
789
|
+
workflowKey: string | null;
|
|
790
|
+
config: ResolvedGatewayUiConfig;
|
|
791
|
+
};
|
|
568
792
|
|
|
569
793
|
type ServeOptions$1 = {
|
|
570
794
|
workflow: SmithersWorkflow$1<unknown>;
|
|
@@ -614,7 +838,7 @@ declare class NodeOutputRouteError extends Error {
|
|
|
614
838
|
/** @type {NodeOutputErrorCode} */
|
|
615
839
|
code: NodeOutputErrorCode;
|
|
616
840
|
}
|
|
617
|
-
type NodeOutputErrorCode =
|
|
841
|
+
type NodeOutputErrorCode = _smithers_orchestrator_protocol_errors.NodeOutputErrorCode;
|
|
618
842
|
|
|
619
843
|
/**
|
|
620
844
|
* @returns {DevToolsNode}
|
|
@@ -701,11 +925,11 @@ declare class DevToolsRouteError extends Error {
|
|
|
701
925
|
hint: string | undefined;
|
|
702
926
|
}
|
|
703
927
|
declare const DEVTOOLS_EMPTY_ROOT_ID: 0;
|
|
704
|
-
type SmithersDb$3 =
|
|
705
|
-
type DevToolsNode =
|
|
706
|
-
type DevToolsSnapshot =
|
|
707
|
-
type DevToolsNodeType =
|
|
708
|
-
type SnapshotSerializerWarning$1 =
|
|
928
|
+
type SmithersDb$3 = _smithers_orchestrator_db_adapter.SmithersDb;
|
|
929
|
+
type DevToolsNode = _smithers_orchestrator_protocol_devtools.DevToolsNode;
|
|
930
|
+
type DevToolsSnapshot = _smithers_orchestrator_protocol_devtools.DevToolsSnapshot;
|
|
931
|
+
type DevToolsNodeType = _smithers_orchestrator_protocol_devtools.DevToolsNodeType;
|
|
932
|
+
type SnapshotSerializerWarning$1 = _smithers_orchestrator_devtools_snapshotSerializer.SnapshotSerializerWarning;
|
|
709
933
|
|
|
710
934
|
type DiffSummary$1 = {
|
|
711
935
|
filesChanged: number;
|
|
@@ -752,7 +976,7 @@ type GetNodeDiffRouteResult$1 = {
|
|
|
752
976
|
* }} opts
|
|
753
977
|
* @returns {Promise<GetNodeDiffRouteResult>}
|
|
754
978
|
*/
|
|
755
|
-
declare function getNodeDiffRoute({ runId: rawRunId, nodeId: rawNodeId, iteration: rawIteration, resolveRun, emitEffect, computeDiffBundleImpl, computeDiffBundleBetweenRefsImpl, getCurrentPointerImpl, resolveCommitPointerImpl, restorePointerImpl, nowMs, stat, }: {
|
|
979
|
+
declare function getNodeDiffRoute({ runId: rawRunId, nodeId: rawNodeId, iteration: rawIteration, resolveRun, emitEffect, computeDiffBundleImpl, computeDiffBundleBetweenRefsImpl, getCurrentPointerImpl: _getCurrentPointerImpl, resolveCommitPointerImpl, restorePointerImpl: _restorePointerImpl, nowMs, stat, }: {
|
|
756
980
|
runId: unknown;
|
|
757
981
|
nodeId: unknown;
|
|
758
982
|
iteration: unknown;
|
|
@@ -760,8 +984,8 @@ declare function getNodeDiffRoute({ runId: rawRunId, nodeId: rawNodeId, iteratio
|
|
|
760
984
|
adapter: SmithersDb$2;
|
|
761
985
|
} | null>;
|
|
762
986
|
emitEffect?: (effect: Effect.Effect<void>) => Promise<unknown>;
|
|
763
|
-
computeDiffBundleImpl?: (baseRef: string, cwd: string, seq?: number) => Promise<
|
|
764
|
-
computeDiffBundleBetweenRefsImpl?: (baseRef: string, targetRef: string, cwd: string, seq?: number) => Promise<
|
|
987
|
+
computeDiffBundleImpl?: (baseRef: string, cwd: string, seq?: number) => Promise<_smithers_orchestrator_engine_effect_DiffBundle.DiffBundle>;
|
|
988
|
+
computeDiffBundleBetweenRefsImpl?: (baseRef: string, targetRef: string, cwd: string, seq?: number) => Promise<_smithers_orchestrator_engine_effect_DiffBundle.DiffBundle>;
|
|
765
989
|
getCurrentPointerImpl?: (cwd: string) => Promise<string | null>;
|
|
766
990
|
resolveCommitPointerImpl?: (pointer: string, cwd: string) => Promise<string | null>;
|
|
767
991
|
restorePointerImpl?: (pointer: string, cwd: string) => Promise<{
|
|
@@ -771,8 +995,8 @@ declare function getNodeDiffRoute({ runId: rawRunId, nodeId: rawNodeId, iteratio
|
|
|
771
995
|
nowMs?: () => number;
|
|
772
996
|
stat?: boolean;
|
|
773
997
|
}): Promise<GetNodeDiffRouteResult>;
|
|
774
|
-
type SmithersDb$2 =
|
|
775
|
-
type AttemptRow =
|
|
998
|
+
type SmithersDb$2 = _smithers_orchestrator_db_adapter.SmithersDb;
|
|
999
|
+
type AttemptRow = _smithers_orchestrator_db_adapter.AttemptRow;
|
|
776
1000
|
type GetNodeDiffRouteResult = GetNodeDiffRouteResult$1;
|
|
777
1001
|
type DiffSummary = DiffSummary$1;
|
|
778
1002
|
|
|
@@ -832,8 +1056,8 @@ declare function getNodeOutputRoute(params: {
|
|
|
832
1056
|
nodeId: unknown;
|
|
833
1057
|
iteration: unknown;
|
|
834
1058
|
resolveRun: (runId: string) => Promise<{
|
|
835
|
-
workflow:
|
|
836
|
-
adapter:
|
|
1059
|
+
workflow: _smithers_orchestrator_components_SmithersWorkflow.SmithersWorkflow<unknown>;
|
|
1060
|
+
adapter: _smithers_orchestrator_db_adapter.SmithersDb;
|
|
837
1061
|
} | null>;
|
|
838
1062
|
selectOutputRowImpl?: typeof selectOutputRow;
|
|
839
1063
|
emitEffect?: (effect: Effect.Effect<void>) => Promise<unknown>;
|
|
@@ -883,9 +1107,9 @@ declare function jumpToFrameRoute(input: {
|
|
|
883
1107
|
onLog?: (level: "info" | "warn" | "error", message: string, fields?: Record<string, unknown>) => Promise<void> | void;
|
|
884
1108
|
}): Promise<JumpResult>;
|
|
885
1109
|
|
|
886
|
-
type SmithersDb$1 =
|
|
887
|
-
type SmithersEvent =
|
|
888
|
-
type JumpResult =
|
|
1110
|
+
type SmithersDb$1 = _smithers_orchestrator_db_adapter.SmithersDb;
|
|
1111
|
+
type SmithersEvent = _smithers_orchestrator_observability_SmithersEvent.SmithersEvent;
|
|
1112
|
+
type JumpResult = _smithers_orchestrator_time_travel_jumpToFrame.JumpResult;
|
|
889
1113
|
|
|
890
1114
|
/**
|
|
891
1115
|
* @param {{
|
|
@@ -934,20 +1158,21 @@ declare function streamDevToolsRoute(input: {
|
|
|
934
1158
|
declare const DEVTOOLS_REBASELINE_INTERVAL: 50;
|
|
935
1159
|
declare const DEVTOOLS_BACKPRESSURE_LIMIT: 1000;
|
|
936
1160
|
declare const DEVTOOLS_POLL_INTERVAL_MS: 25;
|
|
937
|
-
type SmithersDb =
|
|
938
|
-
type DevToolsEvent =
|
|
939
|
-
type SnapshotSerializerWarning =
|
|
1161
|
+
type SmithersDb = _smithers_orchestrator_db_adapter.SmithersDb;
|
|
1162
|
+
type DevToolsEvent = _smithers_orchestrator_protocol_devtools.DevToolsEvent;
|
|
1163
|
+
type SnapshotSerializerWarning = _smithers_orchestrator_devtools_snapshotSerializer.SnapshotSerializerWarning;
|
|
940
1164
|
|
|
941
1165
|
/**
|
|
942
1166
|
* @param {ServerOptions} [opts]
|
|
943
1167
|
*/
|
|
944
|
-
declare function startServerEffect(opts?: ServerOptions): Effect.Effect<node_http.Server<typeof IncomingMessage
|
|
1168
|
+
declare function startServerEffect(opts?: ServerOptions): Effect.Effect<node_http.Server<typeof node_http.IncomingMessage, typeof node_http.ServerResponse>, never, never>;
|
|
945
1169
|
/**
|
|
946
1170
|
* @param {ServerOptions} [opts]
|
|
947
1171
|
*/
|
|
948
|
-
declare function startServer(opts?: ServerOptions): node_http.Server<typeof IncomingMessage
|
|
1172
|
+
declare function startServer(opts?: ServerOptions): node_http.Server<typeof node_http.IncomingMessage, typeof node_http.ServerResponse>;
|
|
949
1173
|
|
|
950
|
-
type RunRow =
|
|
1174
|
+
type RunRow = _smithers_orchestrator_db_adapter_RunRow.RunRow;
|
|
1175
|
+
type ServerResponse = node_http.ServerResponse;
|
|
951
1176
|
type ServerOptions = ServerOptions$1;
|
|
952
1177
|
|
|
953
|
-
export { type AttemptRow, type ConnectRequest, type ConnectionState, DEVTOOLS_BACKPRESSURE_LIMIT, DEVTOOLS_EMPTY_ROOT_ID, DEVTOOLS_MAX_FRAME_NO, DEVTOOLS_POLL_INTERVAL_MS, DEVTOOLS_REBASELINE_INTERVAL, DEVTOOLS_RUN_ID_PATTERN, DEVTOOLS_TREE_MAX_DEPTH, type DevToolsEvent, type DevToolsNode, type DevToolsNodeType, DevToolsRouteError, type DiffSummary, type EventFrame, GATEWAY_FRAME_ID_MAX_LENGTH, GATEWAY_METHOD_NAME_MAX_LENGTH, GATEWAY_RPC_INPUT_MAX_BYTES, GATEWAY_RPC_INPUT_MAX_DEPTH, GATEWAY_RPC_MAX_ARRAY_LENGTH, GATEWAY_RPC_MAX_DEPTH, GATEWAY_RPC_MAX_PAYLOAD_BYTES, GATEWAY_RPC_MAX_STRING_LENGTH, Gateway, type GatewayAuthConfig, type GatewayDefaults, type GatewayMetricLabels, type GatewayOptions, type GatewayRequestContext, type GatewayTokenGrant, type GatewayTransport, type GatewayWebhookConfig, type GatewayWebhookRunConfig, type GatewayWebhookSignalConfig, type GetNodeDiffRouteResult, type HelloResponse, ITERATION_MAX, type IncomingMessage, type JumpResult, NODE_ID_PATTERN, NODE_OUTPUT_MAX_BYTES, NODE_OUTPUT_WARN_BYTES, type NodeOutputErrorCode, type NodeOutputResponse, NodeOutputRouteError, RUN_ID_PATTERN, type RegisteredWorkflow, type RequestFrame, type ResolvedRun, type ResponseFrame, type RunRow, type RunStartAuthContext, type ServeOptions, type ServerOptions, type ServerResponse, type SmithersWorkflow, assertGatewayInputDepthWithinBounds, createServeApp, emptyDevToolsRoot, getDevToolsSnapshotRoute, getGatewayInputDepth, getNodeDiffRoute, getNodeOutputRoute, jumpToFrameRoute, parseGatewayRequestFrame, parseXmlToDevToolsRoot, runFork, runPromise, runSync, snapshotFromFrameRow, startServer, startServerEffect, statusForRpcError, streamDevToolsRoute, summarizeBundle, validateFrameNoInput, validateFromSeqInput, validateGatewayMethodName, validateRequestedFrameNo, validateRunId };
|
|
1178
|
+
export { type AttemptRow, type ConnectRequest, type ConnectionState, DEVTOOLS_BACKPRESSURE_LIMIT, DEVTOOLS_EMPTY_ROOT_ID, DEVTOOLS_MAX_FRAME_NO, DEVTOOLS_POLL_INTERVAL_MS, DEVTOOLS_REBASELINE_INTERVAL, DEVTOOLS_RUN_ID_PATTERN, DEVTOOLS_TREE_MAX_DEPTH, type DevToolsEvent, type DevToolsNode, type DevToolsNodeType, DevToolsRouteError, type DiffSummary, type EventFrame, GATEWAY_FRAME_ID_MAX_LENGTH, GATEWAY_METHOD_NAME_MAX_LENGTH, GATEWAY_RPC_INPUT_MAX_BYTES, GATEWAY_RPC_INPUT_MAX_DEPTH, GATEWAY_RPC_MAX_ARRAY_LENGTH, GATEWAY_RPC_MAX_DEPTH, GATEWAY_RPC_MAX_PAYLOAD_BYTES, GATEWAY_RPC_MAX_STRING_LENGTH, Gateway, type GatewayAuthConfig, type GatewayDefaults, type GatewayMetricLabels, type GatewayOptions, type GatewayRegisterOptions, type GatewayRequestContext, type GatewayTokenGrant, type GatewayTransport, type GatewayUiConfig, type GatewayUiMount, type GatewayWebhookConfig, type GatewayWebhookRunConfig, type GatewayWebhookSignalConfig, type GetNodeDiffRouteResult, type HelloResponse, ITERATION_MAX, type IncomingMessage, type JumpResult, NODE_ID_PATTERN, NODE_OUTPUT_MAX_BYTES, NODE_OUTPUT_WARN_BYTES, type NodeOutputErrorCode, type NodeOutputResponse, NodeOutputRouteError, RUN_ID_PATTERN, type RegisteredWorkflow, type RequestFrame, type ResolvedGatewayUiConfig, type ResolvedRun, type ResponseFrame, type RunRow, type RunStartAuthContext, type ServeOptions, type ServerOptions, type ServerResponse, type SmithersWorkflow, assertGatewayInputDepthWithinBounds, createServeApp, emptyDevToolsRoot, getDevToolsSnapshotRoute, getGatewayInputDepth, getNodeDiffRoute, getNodeOutputRoute, jumpToFrameRoute, parseGatewayRequestFrame, parseXmlToDevToolsRoot, runFork, runPromise, runSync, snapshotFromFrameRow, startServer, startServerEffect, statusForRpcError, streamDevToolsRoute, summarizeBundle, validateFrameNoInput, validateFromSeqInput, validateGatewayMethodName, validateRequestedFrameNo, validateRunId };
|