| 1 | // generated by crates/tui/extension-host/build.mjs from src/rpc.ts; do not edit. |
| 2 | |
| 3 | // src/protocol.generated.ts |
| 4 | var MAGIC_ASCII = "CWX1"; |
| 5 | var MAX_INFLIGHT = 256; |
| 6 | var ErrorCode = { |
| 7 | ParseError: -32700, |
| 8 | InvalidRequest: -32600, |
| 9 | MethodNotFound: -32601, |
| 10 | InvalidParams: -32602, |
| 11 | Internal: -32603, |
| 12 | ExecutionFailed: -32e3, |
| 13 | NotAvailable: -32001, |
| 14 | Refused: -32002, |
| 15 | Denied: -32003, |
| 16 | Cancelled: -32800 |
| 17 | }; |
| 18 | var METHODS = [ |
| 19 | { name: "host/initialize", direction: "core_to_host", request: true, params: "InitializeParams", tiers: ["plugin", "builtin"] }, |
| 20 | { name: "host/ping", direction: "core_to_host", request: true, params: "EmptyParams", tiers: ["plugin", "builtin"] }, |
| 21 | { name: "host/shutdown", direction: "core_to_host", request: true, params: "EmptyParams", tiers: ["plugin", "builtin"] }, |
| 22 | { name: "ext/activate", direction: "core_to_host", request: true, params: "ActivateParams", tiers: ["plugin", "builtin"] }, |
| 23 | { name: "ext/deactivate", direction: "core_to_host", request: true, params: "DeactivateParams", tiers: ["plugin", "builtin"] }, |
| 24 | { name: "tool/call", direction: "core_to_host", request: true, params: "ToolCallParams", tiers: ["plugin", "builtin"] }, |
| 25 | { name: "command/run", direction: "core_to_host", request: true, params: "CommandRunParams", tiers: ["plugin", "builtin"] }, |
| 26 | { name: "hook/evaluate", direction: "core_to_host", request: true, params: "HookEvaluateParams", tiers: ["plugin", "builtin"] }, |
| 27 | { name: "mcp/open", direction: "core_to_host", request: true, params: "McpOpenParams", tiers: ["builtin"] }, |
| 28 | { name: "mcp/request", direction: "core_to_host", request: true, params: "McpRequestParams", tiers: ["builtin"] }, |
| 29 | { name: "mcp/close", direction: "core_to_host", request: true, params: "McpCloseParams", tiers: ["builtin"] }, |
| 30 | { name: "harness/run", direction: "core_to_host", request: true, params: "HarnessRunParams", tiers: ["builtin"] }, |
| 31 | { name: "$/cancel", direction: "core_to_host", request: false, params: "CancelParams", tiers: ["plugin", "builtin"] }, |
| 32 | { name: "host/hello", direction: "host_to_core", request: false, params: "HelloParams", tiers: ["plugin", "builtin"] }, |
| 33 | { name: "host/ready", direction: "host_to_core", request: false, params: "EmptyParams", tiers: ["plugin", "builtin"] }, |
| 34 | { name: "registry/register", direction: "host_to_core", request: true, params: "RegisterParams", tiers: ["plugin", "builtin"] }, |
| 35 | { name: "registry/unregister", direction: "host_to_core", request: true, params: "UnregisterParams", tiers: ["plugin", "builtin"] }, |
| 36 | { name: "core/call", direction: "host_to_core", request: true, params: "CoreCallParams", tiers: ["plugin", "builtin"] }, |
| 37 | { name: "proc/launch", direction: "host_to_core", request: true, params: "ProcLaunchParams", tiers: ["builtin"] }, |
| 38 | { name: "proc/read", direction: "host_to_core", request: true, params: "ProcSessionParams", tiers: ["builtin"] }, |
| 39 | { name: "proc/write", direction: "host_to_core", request: true, params: "ProcWriteParams", tiers: ["builtin"] }, |
| 40 | { name: "proc/close", direction: "host_to_core", request: true, params: "ProcSessionParams", tiers: ["builtin"] }, |
| 41 | { name: "net/start", direction: "host_to_core", request: true, params: "ProcLaunchParams", tiers: ["builtin"] }, |
| 42 | { name: "net/fetch", direction: "host_to_core", request: true, params: "NetFetchParams", tiers: ["builtin"] }, |
| 43 | { name: "net/read", direction: "host_to_core", request: true, params: "NetReadParams", tiers: ["builtin"] }, |
| 44 | { name: "net/release", direction: "host_to_core", request: true, params: "NetReadParams", tiers: ["builtin"] }, |
| 45 | { name: "net/close", direction: "host_to_core", request: true, params: "ProcSessionParams", tiers: ["builtin"] }, |
| 46 | { name: "exec/redeem", direction: "host_to_core", request: true, params: "ExecutionRedeemParams", tiers: ["builtin"] }, |
| 47 | { name: "ext/faulted", direction: "host_to_core", request: false, params: "FaultedParams", tiers: ["plugin", "builtin"] }, |
| 48 | { name: "log", direction: "host_to_core", request: false, params: "LogParams", tiers: ["plugin", "builtin"] }, |
| 49 | { name: "$/cancel", direction: "host_to_core", request: false, params: "CancelParams", tiers: ["plugin", "builtin"] } |
| 50 | ]; |
| 51 | var SHAPES = { |
| 52 | ActivateParams: { |
| 53 | strict: false, |
| 54 | required: { owner: { ref: "OwnerRef" }, plugin_name: "string", entry: { ref: "EntryRef" } }, |
| 55 | optional: { scope: { ref: "EntryRef" }, config: "json", data_dir: "string" } |
| 56 | }, |
| 57 | CancelParams: { |
| 58 | strict: true, |
| 59 | required: { id: "uint" }, |
| 60 | optional: {} |
| 61 | }, |
| 62 | CommandRunParams: { |
| 63 | strict: false, |
| 64 | required: { handle: "uint", command_id: "string", raw_input: "string", deadline_ms: "uint" }, |
| 65 | optional: { workspace: "string", session_id: "string", agent_id: "string", origin_turn_id: "string" } |
| 66 | }, |
| 67 | CoreCallParams: { |
| 68 | strict: true, |
| 69 | required: { owner: { ref: "OwnerRef" }, ticket: "string", name: "string", input: "json" }, |
| 70 | optional: {} |
| 71 | }, |
| 72 | DeactivateParams: { |
| 73 | strict: false, |
| 74 | required: { owner: { ref: "OwnerRef" } }, |
| 75 | optional: { entry: { ref: "EntryRef" } } |
| 76 | }, |
| 77 | EmptyParams: { |
| 78 | strict: true, |
| 79 | required: {}, |
| 80 | optional: {} |
| 81 | }, |
| 82 | EntryRef: { |
| 83 | strict: false, |
| 84 | required: { path: "string", sha256: "string" }, |
| 85 | optional: {} |
| 86 | }, |
| 87 | ExecutionRedeemParams: { |
| 88 | strict: true, |
| 89 | required: { owner: { ref: "OwnerRef" }, execution_id: "string", ticket: "string" }, |
| 90 | optional: {} |
| 91 | }, |
| 92 | FaultedParams: { |
| 93 | strict: true, |
| 94 | required: { owner: { ref: "OwnerRef" }, error: "string" }, |
| 95 | optional: {} |
| 96 | }, |
| 97 | HarnessRunParams: { |
| 98 | strict: true, |
| 99 | required: { owner: { ref: "OwnerRef" }, execution_id: "string", ticket: "string", deadline_ms: "uint" }, |
| 100 | optional: { hook: { ref: "HookDispatchWire" } } |
| 101 | }, |
| 102 | HelloParams: { |
| 103 | strict: true, |
| 104 | required: { protocol: { ref: "ProtocolRange" }, host_version: "string", bundle_sha256: "string", runtime: { ref: "HelloRuntime" }, tier: { enum: ["builtin", "plugin"] }, builtin_modules: { items: { ref: "ModuleDigestWire" } } }, |
| 105 | optional: { memory_limit_mib: "uint" } |
| 106 | }, |
| 107 | HelloRuntime: { |
| 108 | strict: true, |
| 109 | required: { name: "string", version: "string" }, |
| 110 | optional: {} |
| 111 | }, |
| 112 | HookCallPayload: { |
| 113 | strict: true, |
| 114 | required: { name: "string", call_id: "string", input: "json", mode: "string", workspace: "string", model: "string" }, |
| 115 | optional: {} |
| 116 | }, |
| 117 | HookDispatchWire: { |
| 118 | strict: true, |
| 119 | required: { event: "string", dialect: "string", point: "string", query: "string" }, |
| 120 | optional: { matcher: "string" } |
| 121 | }, |
| 122 | HookEvaluateParams: { |
| 123 | strict: true, |
| 124 | required: { handle: "uint", event: "string", payload: { ref: "HookCallPayload" }, deadline_ms: "uint" }, |
| 125 | optional: {} |
| 126 | }, |
| 127 | HostLimits: { |
| 128 | strict: false, |
| 129 | required: { max_frame: "uint", max_inflight: "uint", dispose_deadline_ms: "uint", activate_deadline_ms: "uint" }, |
| 130 | optional: {} |
| 131 | }, |
| 132 | InitializeParams: { |
| 133 | strict: false, |
| 134 | required: { protocol: "uint", limits: { ref: "HostLimits" } }, |
| 135 | optional: {} |
| 136 | }, |
| 137 | LogParams: { |
| 138 | strict: true, |
| 139 | required: { level: "string", msg: "string" }, |
| 140 | optional: { plugin_id: "string" } |
| 141 | }, |
| 142 | McpCloseParams: { |
| 143 | strict: true, |
| 144 | required: { owner: { ref: "OwnerRef" }, session_id: "string", deadline_ms: "uint" }, |
| 145 | optional: {} |
| 146 | }, |
| 147 | McpHttpHeaders: { |
| 148 | strict: true, |
| 149 | required: {}, |
| 150 | optional: { accept: "string", content_type: "string", mcp_session_id: "string", mcp_protocol_version: "string" } |
| 151 | }, |
| 152 | McpOpenParams: { |
| 153 | strict: true, |
| 154 | required: { owner: { ref: "OwnerRef" }, session_id: "string", launch_ticket: "string", transport: "string", initialize_grant: { ref: "McpOperationGrant" }, initialized_grant: { ref: "McpOperationGrant" }, client_version: "string", deadline_ms: "uint" }, |
| 155 | optional: {} |
| 156 | }, |
| 157 | McpOperationGrant: { |
| 158 | strict: true, |
| 159 | required: { ticket: "string", operation_id: "string", method: "string", params: "json" }, |
| 160 | optional: { wire_id: "string" } |
| 161 | }, |
| 162 | McpRequestParams: { |
| 163 | strict: true, |
| 164 | required: { owner: { ref: "OwnerRef" }, session_id: "string", grant: { ref: "McpOperationGrant" }, deadline_ms: "uint" }, |
| 165 | optional: {} |
| 166 | }, |
| 167 | ModuleDigestWire: { |
| 168 | strict: true, |
| 169 | required: { id: "string", sha256: "string" }, |
| 170 | optional: {} |
| 171 | }, |
| 172 | NetFetchParams: { |
| 173 | strict: true, |
| 174 | required: { owner: { ref: "OwnerRef" }, session_id: "string", url: "string", method: "string", headers: { ref: "McpHttpHeaders" } }, |
| 175 | optional: { frame: "json", ticket: "string", operation_id: "string" } |
| 176 | }, |
| 177 | NetReadParams: { |
| 178 | strict: true, |
| 179 | required: { owner: { ref: "OwnerRef" }, session_id: "string", response_id: "string" }, |
| 180 | optional: {} |
| 181 | }, |
| 182 | OwnerRef: { |
| 183 | strict: true, |
| 184 | required: { plugin_id: "string", generation: "uint", owner_token: "string" }, |
| 185 | optional: {} |
| 186 | }, |
| 187 | ProcLaunchParams: { |
| 188 | strict: true, |
| 189 | required: { owner: { ref: "OwnerRef" }, session_id: "string", ticket: "string" }, |
| 190 | optional: {} |
| 191 | }, |
| 192 | ProcSessionParams: { |
| 193 | strict: true, |
| 194 | required: { owner: { ref: "OwnerRef" }, session_id: "string" }, |
| 195 | optional: {} |
| 196 | }, |
| 197 | ProcWriteParams: { |
| 198 | strict: true, |
| 199 | required: { owner: { ref: "OwnerRef" }, session_id: "string", frame: "json" }, |
| 200 | optional: { ticket: "string", operation_id: "string" } |
| 201 | }, |
| 202 | ProtocolRange: { |
| 203 | strict: true, |
| 204 | required: { min: "uint", max: "uint" }, |
| 205 | optional: {} |
| 206 | }, |
| 207 | RegisterParams: { |
| 208 | strict: true, |
| 209 | required: { owner: { ref: "OwnerRef" }, kind: { enum: ["tool", "command", "hook", "prompt_section", "prompt_template", "skill_root", "shell_hook", "mcp_server"] }, spec: { ref: "RegisterSpecWire" } }, |
| 210 | optional: { scope: { ref: "EntryRef" } } |
| 211 | }, |
| 212 | RegisterSpecWire: { |
| 213 | strict: true, |
| 214 | required: { name: "string", description: "string" }, |
| 215 | optional: { input_schema: "object", argument_hint: "string" } |
| 216 | }, |
| 217 | RpcErrorWire: { |
| 218 | strict: true, |
| 219 | required: { code: "integer", message: "string" }, |
| 220 | optional: { data: "json" } |
| 221 | }, |
| 222 | ToolCallParams: { |
| 223 | strict: false, |
| 224 | required: { handle: "uint", call_id: "string", input: "json", deadline_ms: "uint" }, |
| 225 | optional: { workspace: "string", ticket: "string", session_id: "string", agent_id: "string", origin_turn_id: "string" } |
| 226 | }, |
| 227 | UnregisterParams: { |
| 228 | strict: true, |
| 229 | required: { owner: { ref: "OwnerRef" }, handle: "uint" }, |
| 230 | optional: {} |
| 231 | } |
| 232 | }; |
| 233 | |
| 234 | // src/protocol.ts |
| 235 | var MAGIC = Buffer.from(MAGIC_ASCII, "ascii"); |
| 236 | var ProtocolError = class extends Error { |
| 237 | constructor(message) { |
| 238 | super(message); |
| 239 | this.name = "ProtocolError"; |
| 240 | } |
| 241 | }; |
| 242 | function isObject(value) { |
| 243 | return typeof value === "object" && value !== null && !Array.isArray(value); |
| 244 | } |
| 245 | function checkShape(where, value, shape) { |
| 246 | if (!isObject(value)) throw new ProtocolError(`${where}: expected an object`); |
| 247 | for (const [key, kind] of Object.entries(shape.required)) { |
| 248 | if (!(key in value)) throw new ProtocolError(`${where}: missing field \`${key}\``); |
| 249 | checkKind(`${where}.${key}`, value[key], kind); |
| 250 | } |
| 251 | for (const [key, kind] of Object.entries(shape.optional)) { |
| 252 | if (value[key] !== void 0 && value[key] !== null) checkKind(`${where}.${key}`, value[key], kind); |
| 253 | } |
| 254 | if (shape.strict) { |
| 255 | for (const key of Object.keys(value)) { |
| 256 | if (!(key in shape.required) && !(key in shape.optional)) { |
| 257 | throw new ProtocolError(`${where}: unknown field \`${key}\``); |
| 258 | } |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 | function checkKind(where, value, kind) { |
| 263 | if (typeof kind === "object") { |
| 264 | if ("ref" in kind) return checkShape(where, value, SHAPES[kind.ref]); |
| 265 | if ("enum" in kind) { |
| 266 | if (typeof value !== "string" || !kind.enum.includes(value)) { |
| 267 | throw new ProtocolError(`${where}: expected one of ${kind.enum.map((v) => `\`${v}\``).join(", ")}`); |
| 268 | } |
| 269 | return; |
| 270 | } |
| 271 | if (!Array.isArray(value)) throw new ProtocolError(`${where}: expected an array`); |
| 272 | value.forEach((item, index) => checkKind(`${where}[${index}]`, item, kind.items)); |
| 273 | return; |
| 274 | } |
| 275 | switch (kind) { |
| 276 | case "string": |
| 277 | if (typeof value !== "string") throw new ProtocolError(`${where}: expected a string`); |
| 278 | return; |
| 279 | case "uint": |
| 280 | if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) { |
| 281 | throw new ProtocolError(`${where}: expected an unsigned integer`); |
| 282 | } |
| 283 | return; |
| 284 | case "integer": |
| 285 | if (typeof value !== "number" || !Number.isSafeInteger(value)) throw new ProtocolError(`${where}: expected an integer`); |
| 286 | return; |
| 287 | case "boolean": |
| 288 | if (typeof value !== "boolean") throw new ProtocolError(`${where}: expected a boolean`); |
| 289 | return; |
| 290 | case "object": |
| 291 | if (!isObject(value)) throw new ProtocolError(`${where}: expected an object`); |
| 292 | return; |
| 293 | case "json": |
| 294 | return; |
| 295 | } |
| 296 | } |
| 297 | function validateMessage(value, direction, tier, methods = METHODS) { |
| 298 | const strict = direction === "host_to_core"; |
| 299 | if (!isObject(value)) throw new ProtocolError("message: expected an object"); |
| 300 | if (value.jsonrpc !== "2.0") throw new ProtocolError('message: jsonrpc must be "2.0"'); |
| 301 | const hasId = "id" in value; |
| 302 | if (hasId) checkKind("message.id", value.id, "uint"); |
| 303 | if ("method" in value) { |
| 304 | checkShape("message", value, { strict, required: { jsonrpc: "string", method: "string" }, optional: { id: "uint", params: "json" } }); |
| 305 | const method = value.method; |
| 306 | const spec = methods.find((entry) => entry.name === method && entry.direction === direction); |
| 307 | if (!spec) throw new ProtocolError(`unknown ${direction} method \`${method}\``); |
| 308 | if (!spec.tiers.includes(tier)) throw new ProtocolError(`\`${method}\` is not allowed on the ${tier} tier`); |
| 309 | if (spec.request !== hasId) { |
| 310 | throw new ProtocolError(`\`${method}\` must be ${spec.request ? "a request (with id)" : "a notification (no id)"}`); |
| 311 | } |
| 312 | const params = "params" in value ? value.params : {}; |
| 313 | checkShape(method, params, SHAPES[spec.params]); |
| 314 | if (method === "host/hello" && params.runtime.name !== "bun" && params.runtime.name !== "node") { |
| 315 | throw new ProtocolError(`host/hello.runtime.name: unknown runtime \`${params.runtime.name}\``); |
| 316 | } |
| 317 | if (method === "registry/register") { |
| 318 | const { kind, spec: spec2 } = params; |
| 319 | const reason = kind === "tool" && spec2.input_schema == null ? "a tool registration needs `spec.input_schema`" : kind === "tool" && spec2.argument_hint != null ? "a tool registration has no `spec.argument_hint`" : kind === "command" && spec2.input_schema != null ? "a command registration has no `spec.input_schema`" : (kind === "hook" || kind === "prompt_section" || kind === "prompt_template" || kind === "skill_root" || kind === "shell_hook" || kind === "mcp_server") && (spec2.input_schema != null || spec2.argument_hint != null) ? "a hook, prompt or skill root registration has no input schema or argument hint" : void 0; |
| 320 | if (reason !== void 0) throw new ProtocolError(`${method}: ${reason}`); |
| 321 | } |
| 322 | return value; |
| 323 | } |
| 324 | if (!hasId) throw new ProtocolError("response: missing id"); |
| 325 | if ("error" in value) { |
| 326 | checkShape("message", value, { strict, required: { jsonrpc: "string", id: "uint", error: { ref: "RpcErrorWire" } }, optional: {} }); |
| 327 | return value; |
| 328 | } |
| 329 | if (!("result" in value)) throw new ProtocolError("response: needs result or error"); |
| 330 | checkShape("message", value, { strict, required: { jsonrpc: "string", id: "uint", result: "json" }, optional: {} }); |
| 331 | return value; |
| 332 | } |
| 333 | |
| 334 | // src/rpc.ts |
| 335 | var RpcError = class extends Error { |
| 336 | constructor(code, message, data) { |
| 337 | super(message); |
| 338 | this.code = code; |
| 339 | this.data = data; |
| 340 | this.name = "RpcError"; |
| 341 | } |
| 342 | code; |
| 343 | data; |
| 344 | toWire() { |
| 345 | return this.data === void 0 ? { code: this.code, message: this.message } : { code: this.code, message: this.message, data: this.data }; |
| 346 | } |
| 347 | }; |
| 348 | var RpcPeer = class { |
| 349 | constructor(send, tier) { |
| 350 | this.send = send; |
| 351 | this.tier = tier; |
| 352 | } |
| 353 | send; |
| 354 | tier; |
| 355 | nextId = 1; |
| 356 | pending = /* @__PURE__ */ new Map(); |
| 357 | inbound = /* @__PURE__ */ new Map(); |
| 358 | requestHandlers = /* @__PURE__ */ new Map(); |
| 359 | notificationHandlers = /* @__PURE__ */ new Map(); |
| 360 | closed = false; |
| 361 | onRequest(method, handler) { |
| 362 | this.requestHandlers.set(method, handler); |
| 363 | } |
| 364 | onNotification(method, handler) { |
| 365 | this.notificationHandlers.set(method, handler); |
| 366 | } |
| 367 | /** |
| 368 | * Send a host→core request. Outbound messages are validated strictly first. |
| 369 | * When `signal` aborts before the answer, the core is sent `$/cancel` for it |
| 370 | * and the promise rejects as cancelled at once; an answer that still arrives |
| 371 | * is dropped (the core drops its own after a cancel as well). |
| 372 | */ |
| 373 | request(method, params, signal) { |
| 374 | if (this.closed) return Promise.reject(new RpcError(ErrorCode.NotAvailable, "channel closed")); |
| 375 | if (signal?.aborted) return Promise.reject(new RpcError(ErrorCode.Cancelled, "cancelled")); |
| 376 | if (this.pending.size >= MAX_INFLIGHT) { |
| 377 | return Promise.reject(new RpcError(ErrorCode.Internal, `more than ${MAX_INFLIGHT} requests in flight`)); |
| 378 | } |
| 379 | const id = this.nextId++; |
| 380 | const message = { jsonrpc: "2.0", id, method, params }; |
| 381 | validateMessage(message, "host_to_core", this.tier); |
| 382 | return new Promise((resolve, reject) => { |
| 383 | const onAbort = () => { |
| 384 | if (!this.pending.delete(id)) return; |
| 385 | this.notify("$/cancel", { id }); |
| 386 | reject(new RpcError(ErrorCode.Cancelled, "cancelled")); |
| 387 | }; |
| 388 | this.pending.set(id, { |
| 389 | resolve: (value) => { |
| 390 | signal?.removeEventListener("abort", onAbort); |
| 391 | resolve(value); |
| 392 | }, |
| 393 | reject: (error) => { |
| 394 | signal?.removeEventListener("abort", onAbort); |
| 395 | reject(error); |
| 396 | } |
| 397 | }); |
| 398 | signal?.addEventListener("abort", onAbort, { once: true }); |
| 399 | this.send(message); |
| 400 | }); |
| 401 | } |
| 402 | notify(method, params) { |
| 403 | if (this.closed) return; |
| 404 | const message = { jsonrpc: "2.0", method, params }; |
| 405 | validateMessage(message, "host_to_core", this.tier); |
| 406 | this.send(message); |
| 407 | } |
| 408 | /** Dispatch one decoded core→host message. Throws `ProtocolError` for malformed input. */ |
| 409 | handle(raw) { |
| 410 | const message = validateMessage(raw, "core_to_host", this.tier); |
| 411 | if ("method" in message) { |
| 412 | if (message.method === "$/cancel") { |
| 413 | this.inbound.get(message.params.id)?.abort(); |
| 414 | return; |
| 415 | } |
| 416 | if ("id" in message) { |
| 417 | void this.dispatchRequest(message.id, message.method, message.params ?? {}); |
| 418 | return; |
| 419 | } |
| 420 | this.notificationHandlers.get(message.method)?.(message.params ?? {}); |
| 421 | return; |
| 422 | } |
| 423 | const waiter = this.pending.get(message.id); |
| 424 | if (!waiter) return; |
| 425 | this.pending.delete(message.id); |
| 426 | if ("error" in message) { |
| 427 | waiter.reject(new RpcError(message.error.code, message.error.message, message.error.data)); |
| 428 | } else { |
| 429 | waiter.resolve(message.result); |
| 430 | } |
| 431 | } |
| 432 | /** Fail every outbound request; used when the channel closes. */ |
| 433 | close(reason) { |
| 434 | this.closed = true; |
| 435 | for (const [, waiter] of this.pending) waiter.reject(new RpcError(ErrorCode.NotAvailable, reason)); |
| 436 | this.pending.clear(); |
| 437 | for (const [, controller] of this.inbound) controller.abort(); |
| 438 | } |
| 439 | async dispatchRequest(id, method, params) { |
| 440 | const handler = this.requestHandlers.get(method); |
| 441 | if (!handler) { |
| 442 | this.reply(id, void 0, new RpcError(ErrorCode.MethodNotFound, `no handler for \`${method}\``)); |
| 443 | return; |
| 444 | } |
| 445 | const controller = new AbortController(); |
| 446 | this.inbound.set(id, controller); |
| 447 | try { |
| 448 | const result = await handler(params, { id, signal: controller.signal }); |
| 449 | this.reply(id, result ?? {}); |
| 450 | } catch (error) { |
| 451 | this.reply(id, void 0, toRpcError(error, controller.signal)); |
| 452 | } finally { |
| 453 | this.inbound.delete(id); |
| 454 | } |
| 455 | } |
| 456 | reply(id, result, error) { |
| 457 | if (this.closed) return; |
| 458 | this.send(error ? { jsonrpc: "2.0", id, error: error.toWire() } : { jsonrpc: "2.0", id, result }); |
| 459 | } |
| 460 | }; |
| 461 | function toRpcError(error, signal) { |
| 462 | if (error instanceof RpcError) return error; |
| 463 | if (signal?.aborted) return new RpcError(ErrorCode.Cancelled, "cancelled"); |
| 464 | const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error); |
| 465 | return new RpcError(ErrorCode.ExecutionFailed, message.slice(0, 4096)); |
| 466 | } |
| 467 | export { |
| 468 | RpcError, |
| 469 | RpcPeer, |
| 470 | toRpcError |
| 471 | }; |
| 472 |