iii-sdk 0.16.0 → 0.16.2-next.1

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.cjs CHANGED
@@ -33,6 +33,7 @@ let node_module = require("node:module");
33
33
  let node_os = require("node:os");
34
34
  node_os = __toESM(node_os);
35
35
  let _iii_dev_observability = require("@iii-dev/observability");
36
+ let _iii_dev_observability_internal = require("@iii-dev/observability/internal");
36
37
  let node_fs = require("node:fs");
37
38
  node_fs = __toESM(node_fs);
38
39
  let node_path = require("node:path");
@@ -512,9 +513,9 @@ var Sdk = class {
512
513
  throw err;
513
514
  }
514
515
  };
515
- if ((0, _iii_dev_observability.getTracer)()) {
516
+ if ((0, _iii_dev_observability_internal.getTracer)()) {
516
517
  const parentContext = (0, _iii_dev_observability.extractContext)(traceparent, baggage);
517
- return _opentelemetry_api.context.with(parentContext, () => (0, _iii_dev_observability.withSpan)(`call ${functionId}`, { kind: _iii_dev_observability.SpanKind.SERVER }, async () => await runHandler()));
518
+ return _opentelemetry_api.context.with(parentContext, () => (0, _iii_dev_observability.withSpan)(`call ${functionId}`, { kind: _opentelemetry_api.SpanKind.SERVER }, async () => await runHandler()));
518
519
  }
519
520
  const traceId = crypto.randomUUID().replace(/-/g, "");
520
521
  const spanId = crypto.randomUUID().replace(/-/g, "").slice(0, 16);
@@ -703,7 +704,7 @@ var Sdk = class {
703
704
  }
704
705
  startMetricsReporting() {
705
706
  if (!this.metricsReportingEnabled || !this.workerId) return;
706
- const meter = (0, _iii_dev_observability.getMeter)();
707
+ const meter = (0, _iii_dev_observability_internal.getMeter)();
707
708
  if (!meter) {
708
709
  console.warn("[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.");
709
710
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Writable","WebSocket","Readable","path","fs","os","context","SpanKind","trace","WebSocket","SeverityNumber"],"sources":["../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/iii-types.ts","../src/utils.ts","../src/iii.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","/**\n * Typed error surfaced when an invocation dispatched over the SDK fails — RBAC\n * rejection (FORBIDDEN), handler-level failure, or a timeout waiting for the\n * engine to respond. Wraps the wire `ErrorBody` shape plus the `function_id`\n * that was targeted, so callers get a single error type across all failure\n * modes and can disambiguate via `err.code`.\n *\n * Before this existed, rejection values were plain `ErrorBody`-shaped objects,\n * which printed as `[object Object]` when stringified — leaving developers to\n * grep through SDK source to figure out what tripped. The class name, `code`\n * prefix in the message, and `function_id` field together make a rejection\n * self-describing.\n */\nexport type IIIInvocationErrorInit = {\n code: string\n message: string\n function_id?: string\n stacktrace?: string\n}\n\nexport class IIIInvocationError extends Error {\n public readonly code: string\n public readonly function_id?: string\n public readonly stacktrace?: string\n\n constructor(init: IIIInvocationErrorInit) {\n super(`${init.code}: ${init.message}`)\n this.name = 'IIIInvocationError'\n this.code = init.code\n this.function_id = init.function_id\n this.stacktrace = init.stacktrace\n }\n}\n\n/**\n * True when `value` looks like the wire `ErrorBody` the engine sends in\n * `InvocationResult.error`: `{ code: string, message: string, stacktrace?: string }`.\n * Used to distinguish an engine rejection (which we wrap in\n * {@link IIIInvocationError}) from a JS `Error` thrown elsewhere.\n */\nexport function isErrorBody(value: unknown): value is {\n code: string\n message: string\n stacktrace?: string\n} {\n if (typeof value !== 'object' || value === null) return false\n const v = value as { code?: unknown; message?: unknown; stacktrace?: unknown }\n return (\n typeof v.code === 'string' &&\n typeof v.message === 'string' &&\n (v.stacktrace === undefined || typeof v.stacktrace === 'string')\n )\n}\n","/**\n * Constants for the III module.\n */\n\n/**\n * Engine function paths for internal operations.\n *\n * Naming note: `LIST_TRIGGERS` / `INFO_TRIGGERS` cover trigger TYPES\n * (templates). `LIST_REGISTERED_TRIGGERS` / `INFO_REGISTERED_TRIGGERS`\n * cover trigger INSTANCES (subscriber rows). The old\n * `engine::trigger-types::list` builtin has been removed and is now\n * served by `engine::triggers::list`.\n */\nexport const EngineFunctions = {\n LIST_FUNCTIONS: 'engine::functions::list',\n INFO_FUNCTIONS: 'engine::functions::info',\n LIST_WORKERS: 'engine::workers::list',\n INFO_WORKERS: 'engine::workers::info',\n LIST_TRIGGERS: 'engine::triggers::list',\n INFO_TRIGGERS: 'engine::triggers::info',\n LIST_REGISTERED_TRIGGERS: 'engine::registered-triggers::list',\n INFO_REGISTERED_TRIGGERS: 'engine::registered-triggers::info',\n REGISTER_WORKER: 'engine::workers::register',\n} as const\n\n/** Engine trigger types */\nexport const EngineTriggers = {\n FUNCTIONS_AVAILABLE: 'engine::functions-available',\n LOG: 'log',\n} as const\n\n/** Log function paths */\nexport const LogFunctions = {\n INFO: 'engine::log::info',\n WARN: 'engine::log::warn',\n ERROR: 'engine::log::error',\n DEBUG: 'engine::log::debug',\n} as const\n\n/** Connection state for the III WebSocket */\nexport type IIIConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface IIIReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Default invocation timeout in milliseconds */\nexport const DEFAULT_INVOCATION_TIMEOUT_MS = 30000\n","export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n message_type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n message_type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n message_type: MessageType.UnregisterTrigger\n id: string\n type?: string\n}\n\nexport type ErrorBody = {\n code: string\n message: string\n stacktrace?: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n message_type: MessageType.TriggerRegistrationResult\n id: string\n type: string\n function_id: string\n error?: ErrorBody\n}\n\nexport type RegisterTriggerMessage = {\n message_type: MessageType.RegisterTrigger\n id: string\n type: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n}\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\nexport type RegisterFunctionFormat = {\n /**\n * The name of the parameter\n */\n name?: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map' | 'integer'\n /**\n * The body of the parameter (for objects)\n */\n properties?: Record<string, unknown>\n /**\n * The items of the parameter (for arrays)\n */\n items?: unknown\n /**\n * Whether the parameter is required\n */\n required?: string[]\n [key: string]: unknown\n}\n\nexport type RegisterFunctionMessage = {\n message_type: MessageType.RegisterFunction\n /**\n * The path of the function (use :: for namespacing, e.g. external::my_lambda)\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n /**\n * HTTP invocation config for external HTTP functions (Lambda, Cloudflare Workers, etc.)\n */\n invocation?: HttpInvocationConfig\n}\n\n/**\n * Routing action for {@link TriggerRequest}. Determines how the engine\n * handles the invocation.\n *\n * - `enqueue` -- Routes through a named queue for async processing.\n * - `void` -- Fire-and-forget, no response.\n */\nexport type TriggerAction = { type: 'enqueue'; queue: string } | { type: 'void' }\n\n/**\n * Input passed to the RBAC auth function during WebSocket upgrade.\n * Contains the HTTP headers, query parameters, and client IP from the\n * connecting worker's upgrade request.\n */\nexport type AuthInput = {\n /** HTTP headers from the WebSocket upgrade request. */\n headers: Record<string, string>\n /** Query parameters from the upgrade URL. Each key maps to an array of values to support repeated keys. */\n query_params: Record<string, string[]>\n /** IP address of the connecting client. */\n ip_address: string\n}\n\n/**\n * Return value from the RBAC auth function. Controls which functions the\n * authenticated worker can invoke and what context is forwarded to the\n * middleware.\n */\nexport type AuthResult = {\n /** Additional function IDs to allow beyond the `expose_functions` config. */\n allowed_functions: string[]\n /** Function IDs to deny even if they match `expose_functions`. Takes precedence over allowed. */\n forbidden_functions: string[]\n /** Trigger type IDs the worker may register triggers for. When omitted, all types are allowed. */\n allowed_trigger_types?: string[]\n /** Whether the worker may register new trigger types. */\n allow_trigger_type_registration: boolean\n /** Whether the worker may register new functions. Defaults to `true` if omitted. */\n allow_function_registration?: boolean\n /** Arbitrary context forwarded to the middleware function on every invocation. */\n context: Record<string, unknown>\n /** Optional prefix applied to all function IDs registered by this worker. */\n function_registration_prefix?: string\n}\n\n/**\n * Input passed to the RBAC middleware function on every function invocation\n * through the RBAC port. The middleware can inspect, modify, or reject the\n * call before it reaches the target function.\n */\nexport type MiddlewareFunctionInput = {\n /** ID of the function being invoked. */\n function_id: string\n /** Payload sent by the caller. */\n payload: Record<string, unknown>\n /** Routing action, if any. */\n action?: TriggerAction\n /** Auth context returned by the auth function for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Input passed to the `on_trigger_type_registration_function_id` hook\n * when a worker attempts to register a new trigger type through the RBAC port.\n * Return an {@link OnTriggerTypeRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerTypeRegistrationInput = {\n /** ID of the trigger type being registered. */\n trigger_type_id: string\n /** Human-readable description of the trigger type. */\n description: string\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_type_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerTypeRegistrationResult = {\n /** Mapped trigger type ID. */\n trigger_type_id?: string\n /** Mapped description. */\n description?: string\n}\n\n/**\n * Input passed to the `on_trigger_registration_function_id` hook\n * when a worker attempts to register a trigger through the RBAC port.\n * Return an {@link OnTriggerRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerRegistrationInput = {\n /** ID of the trigger being registered. */\n trigger_id: string\n /** Trigger type identifier. */\n trigger_type: string\n /** ID of the function this trigger is bound to. */\n function_id: string\n /** Trigger-specific configuration. */\n config: unknown\n /** Arbitrary metadata attached to the trigger. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerRegistrationResult = {\n /** Mapped trigger ID. */\n trigger_id?: string\n /** Mapped trigger type. */\n trigger_type?: string\n /** Mapped function ID. */\n function_id?: string\n /** Mapped trigger configuration. */\n config?: unknown\n}\n\n/**\n * Input passed to the `on_function_registration_function_id` hook\n * when a worker attempts to register a function through the RBAC port.\n * Return an {@link OnFunctionRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnFunctionRegistrationInput = {\n /** ID of the function being registered. */\n function_id: string\n /** Human-readable description of the function. */\n description?: string\n /** Arbitrary metadata attached to the function. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_function_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnFunctionRegistrationResult = {\n /** Mapped function ID. */\n function_id?: string\n /** Mapped description. */\n description?: string\n /** Mapped metadata. */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Result returned when a function is invoked with `TriggerAction.Enqueue`.\n */\nexport type EnqueueResult = {\n /** Unique receipt ID for the enqueued message. */\n messageReceiptId: string\n}\n\n/**\n * Request object passed to {@link ISdk.trigger}.\n *\n * @typeParam TInput - Type of the payload.\n */\nexport type TriggerRequest<TInput = unknown> = {\n /** ID of the function to invoke. */\n function_id: string\n /** Payload to pass to the function. */\n payload: TInput\n /** Routing action. Omit for synchronous request/response. */\n action?: TriggerAction\n /** Override the default invocation timeout in milliseconds. */\n timeoutMs?: number\n}\n\nexport type InvokeFunctionMessage = {\n message_type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n /**\n * Trigger action for queue routing or fire-and-forget\n */\n action?: TriggerAction\n}\n\nexport type InvocationResultMessage = {\n message_type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: unknown\n error?: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type WorkerRegisteredMessage = {\n message_type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n message_type: MessageType.UnregisterFunction\n id: string\n}\n\n/**\n * Serializable reference to one end of a streaming channel. Can be included\n * in invocation payloads to pass channel endpoints between workers.\n */\nexport type StreamChannelRef = {\n /** Unique channel identifier. */\n channel_id: string\n /** Access key for authentication. */\n access_key: string\n /** Whether this ref is for reading or writing. */\n direction: 'read' | 'write'\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n","import { context, trace } from '@opentelemetry/api'\nimport { createRequire } from 'node:module'\nimport * as os from 'node:os'\nimport { type Data, WebSocket } from 'ws'\nimport { ChannelReader, ChannelWriter } from './channels'\nimport { IIIInvocationError, isErrorBody } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n} from './iii-constants'\nimport {\n type HttpInvocationConfig,\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerAction as TriggerActionType,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/observability'\nimport type { IStream } from './stream'\nimport { detectProjectName } from './utils'\nimport {\n extractContext,\n getLogger,\n getMeter,\n getTracer,\n initOtel,\n injectBaggage,\n injectTraceparent,\n type OtelConfig,\n recordSpanEvent,\n redactAndTruncate,\n resolveMaxBytesFromEnv,\n SeverityNumber,\n shutdownOtel,\n SpanKind,\n withSpan,\n} from '@iii-dev/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n Invocation,\n ISdk,\n RegisterFunctionOptions,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n TriggerTypeRef,\n} from './types'\nimport { isChannelRef } from './utils'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** @internal */\nexport type TelemetryOptions = {\n language?: string\n project_name?: string\n framework?: string\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const iii = registerWorker('ws://localhost:49134', {\n * workerName: 'my-worker',\n * invocationTimeoutMs: 10000,\n * reconnectionConfig: { maxRetries: 5 },\n * })\n * ```\n */\nexport type InitOptions = {\n /** Display name for this worker. Defaults to `hostname:pid`. */\n workerName?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `trigger()` in milliseconds. Defaults to `30000`. */\n invocationTimeoutMs?: number\n /**\n * WebSocket reconnection behavior.\n *\n * @see {@link IIIReconnectionConfig} for available fields and defaults.\n */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\n /**\n * OpenTelemetry configuration. OTel is initialized automatically by default.\n * Set `{ enabled: false }` or env `OTEL_ENABLED=false/0/no/off` to disable.\n * The `engineWsUrl` is set automatically from the III address.\n */\n otel?: Omit<OtelConfig, 'engineWsUrl'>\n /** Custom HTTP headers sent during the WebSocket handshake. */\n headers?: Record<string, string>\n /** @internal */\n telemetry?: TelemetryOptions\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private invocations = new Map<string, Invocation & { timeout?: NodeJS.Timeout }>()\n private triggers = new Map<string, RegisterTriggerMessage>()\n private triggerTypes = new Map<string, RemoteTriggerTypeData>()\n private messagesToSend: Record<string, unknown>[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry (enabled by default, opt-out via config or env)\n initOtel({ ...options?.otel, engineWsUrl: this.address })\n\n this.connect()\n }\n\n /**\n * Registers a custom trigger type with the engine. A trigger type defines\n * how external events (HTTP, cron, queue, etc.) map to function invocations.\n *\n * @param triggerType - Trigger type registration input.\n * @param triggerType.id - Unique trigger type identifier.\n * @param triggerType.description - Human-readable description.\n * @param handler - Handler with `registerTrigger` / `unregisterTrigger` callbacks.\n *\n * @example\n * ```typescript\n * iii.registerTriggerType(\n * { id: 'my-trigger', description: 'Custom trigger' },\n * {\n * async registerTrigger({ id, function_id, config }) { },\n * async unregisterTrigger({ id, function_id, config }) { },\n * },\n * )\n * ```\n */\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>,\n handler: TriggerHandler<TConfig>,\n ): TriggerTypeRef<TConfig> => {\n this.sendMessage(MessageType.RegisterTriggerType, triggerType, true)\n this.triggerTypes.set(triggerType.id, {\n message: { ...triggerType, message_type: MessageType.RegisterTriggerType },\n handler,\n })\n\n return {\n id: triggerType.id,\n registerTrigger: (functionId: string, config: TConfig, metadata?: Record<string, unknown>) => {\n return this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n },\n registerFunction: (functionId, handler, config, metadata?) => {\n const ref = this.registerFunction(functionId, handler)\n this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n return ref\n },\n unregister: () => {\n this.unregisterTriggerType(triggerType)\n },\n }\n }\n\n /**\n * Unregisters a previously registered trigger type.\n *\n * @param triggerType - The trigger type to unregister (must match the `id` used during registration).\n */\n unregisterTriggerType = (triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>): void => {\n this.sendMessage(MessageType.UnregisterTriggerType, triggerType, true)\n this.triggerTypes.delete(triggerType.id)\n }\n\n /**\n * Binds a trigger configuration to a registered function. When the trigger\n * fires, the engine invokes the target function.\n *\n * @param trigger - Trigger registration input.\n * @param trigger.type - Trigger type (e.g. `http`, `durable:subscriber`, `cron`).\n * @param trigger.function_id - ID of the function to invoke.\n * @param trigger.config - Trigger-specific configuration.\n * @returns A {@link Trigger} handle with an `unregister()` method.\n *\n * @example\n * ```typescript\n * const trigger = iii.registerTrigger({\n * type: 'http',\n * function_id: 'greet',\n * config: { api_path: '/greet', http_method: 'GET' },\n * })\n *\n * // Later...\n * trigger.unregister()\n * ```\n */\n registerTrigger = (trigger: Omit<RegisterTriggerMessage, 'message_type' | 'id'>): Trigger => {\n const id = crypto.randomUUID()\n const fullTrigger: RegisterTriggerMessage = {\n ...trigger,\n id,\n message_type: MessageType.RegisterTrigger,\n }\n this.sendMessage(MessageType.RegisterTrigger, fullTrigger, true)\n this.triggers.set(id, fullTrigger)\n\n return {\n unregister: () => {\n this.sendMessage(MessageType.UnregisterTrigger, {\n id,\n message_type: MessageType.UnregisterTrigger,\n type: fullTrigger.type,\n })\n this.triggers.delete(id)\n },\n }\n }\n\n /**\n * Registers a function with the engine. The `functionId` is the unique identifier\n * used by triggers and invocations.\n *\n * Pass a handler for local execution, or an {@link HttpInvocationConfig}\n * for HTTP-invoked functions (Lambda, Cloudflare Workers, etc.).\n *\n * @param functionId - Unique function identifier.\n * @param handlerOrInvocation - Async handler or HTTP invocation config.\n * @param options - Optional function registration options (description, request/response formats, metadata).\n * @returns A {@link FunctionRef} with `id` and `unregister()`.\n *\n * @example\n * ```typescript\n * const fn = iii.registerFunction(\n * 'greet',\n * async (input: { name: string }) => {\n * return { message: `Hello, ${input.name}!` }\n * },\n * { description: 'Greets a user' },\n * )\n * ```\n */\n registerFunction = (\n functionId: string,\n handlerOrInvocation: RemoteFunctionHandler | HttpInvocationConfig,\n options?: RegisterFunctionOptions,\n ): FunctionRef => {\n if (!functionId || functionId.trim() === '') {\n throw new Error('id is required')\n }\n if (this.functions.has(functionId)) {\n throw new Error(`function id already registered: ${functionId}`)\n }\n\n const isHandler = typeof handlerOrInvocation === 'function'\n\n const fullMessage: RegisterFunctionMessage = isHandler\n ? { ...options, id: functionId, message_type: MessageType.RegisterFunction }\n : {\n ...options,\n id: functionId,\n message_type: MessageType.RegisterFunction,\n invocation: {\n url: handlerOrInvocation.url,\n method: handlerOrInvocation.method ?? 'POST',\n timeout_ms: handlerOrInvocation.timeout_ms,\n headers: handlerOrInvocation.headers,\n auth: handlerOrInvocation.auth,\n },\n }\n\n this.sendMessage(MessageType.RegisterFunction, fullMessage, true)\n\n if (isHandler) {\n const handler = handlerOrInvocation as RemoteFunctionHandler\n this.functions.set(functionId, {\n message: fullMessage,\n handler: async (input, traceparent?: string, baggage?: string) => {\n const tracePayloads = !(\n process.env.III_DISABLE_TRACE_PAYLOADS === '1' ||\n process.env.III_DISABLE_TRACE_PAYLOADS?.toLowerCase() === 'true'\n )\n const payloadMaxBytes = resolveMaxBytesFromEnv()\n\n const runHandler = async () => {\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(input, payloadMaxBytes)\n recordSpanEvent('iii.invocation.input', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n })\n }\n try {\n const result = await handler(input)\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(result, payloadMaxBytes)\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': true,\n })\n }\n return result\n } catch (err) {\n if (tracePayloads) {\n const errMsg = err instanceof Error ? err.message : String(err)\n const { json, truncated } = redactAndTruncate(\n { error: errMsg },\n payloadMaxBytes,\n )\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': false,\n })\n }\n throw err\n }\n }\n\n if (getTracer()) {\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`call ${functionId}`, { kind: SpanKind.SERVER }, async () => await runHandler()),\n )\n }\n\n const traceId = crypto.randomUUID().replace(/-/g, '')\n const spanId = crypto.randomUUID().replace(/-/g, '').slice(0, 16)\n const syntheticSpan = trace.wrapSpanContext({ traceId, spanId, traceFlags: 1 })\n\n return context.with(trace.setSpan(context.active(), syntheticSpan), async () => await runHandler())\n },\n })\n } else {\n this.functions.set(functionId, { message: fullMessage })\n }\n\n return {\n id: functionId,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: functionId }, true)\n this.functions.delete(functionId)\n },\n }\n }\n\n /**\n * Creates a streaming channel pair for worker-to-worker data transfer.\n * Returns a {@link Channel} with a local writer/reader and serializable refs\n * that can be passed as fields in invocation data to other functions.\n *\n * @param bufferSize - Optional buffer size for the channel (default: 64).\n * @returns A {@link Channel} with `writer`, `reader`, and their serializable refs.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.close()\n * ```\n */\n createChannel = async (bufferSize?: number): Promise<import('./types').Channel> => {\n const result = await this.trigger<{ buffer_size?: number }, { writer: StreamChannelRef; reader: StreamChannelRef }>(\n { function_id: 'engine::channels::create', payload: { buffer_size: bufferSize } },\n )\n\n return {\n writer: new ChannelWriter(this.address, result.writer),\n reader: new ChannelReader(this.address, result.reader),\n writerRef: result.writer,\n readerRef: result.reader,\n }\n }\n\n /**\n * Invokes a remote function. The routing behavior and return type depend\n * on the `action` field of the request.\n *\n * | `action` | Behavior | Return type |\n * |-------------------------------|----------------------------------------------------|----------------------- |\n * | _(none)_ | Synchronous -- waits for the function to return | `Promise<TOutput>` |\n * | `TriggerAction.Enqueue(...)` | Async via named queue -- engine acknowledges enqueue | `Promise<EnqueueResult>` |\n * | `TriggerAction.Void()` | Fire-and-forget -- no response | `Promise<undefined>` |\n *\n * @param request - The trigger request.\n * @param request.function_id - ID of the function to invoke.\n * @param request.payload - Payload to pass to the function.\n * @param request.action - Routing action. Omit for synchronous request/response.\n * @param request.timeoutMs - Override the default invocation timeout.\n * @returns The result of the function invocation.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Synchronous\n * const result = await iii.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await iii.trigger({\n * function_id: 'payments::charge',\n * payload: { orderId: '123', amount: 49.99 },\n * action: TriggerAction.Enqueue({ queue: 'payment' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n trigger = async <TInput, TOutput>(request: TriggerRequest<TInput>): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs } = request\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\n\n // Void is fire-and-forget — no invocation_id, no response\n if (action?.type === 'void') {\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, {\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n return undefined as TOutput\n }\n\n // Enqueue and default: send invocation_id, await response\n const invocation_id = crypto.randomUUID()\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n\n return new Promise<TOutput>((resolve, reject) => {\n const timeout = setTimeout(() => {\n const invocation = this.invocations.get(invocation_id)\n if (invocation) {\n this.invocations.delete(invocation_id)\n reject(\n new IIIInvocationError({\n code: 'TIMEOUT',\n message: `invocation timed out after ${effectiveTimeout}ms`,\n function_id,\n }),\n )\n }\n }, effectiveTimeout)\n\n this.invocations.set(invocation_id, {\n resolve: (result: TOutput) => {\n clearTimeout(timeout)\n resolve(result)\n },\n reject: (error: unknown) => {\n clearTimeout(timeout)\n reject(error)\n },\n function_id,\n timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n })\n }\n\n private registerWorkerMetadata(): void {\n const telemetryOpts = this.options?.telemetry\n const language =\n telemetryOpts?.language ?? Intl.DateTimeFormat().resolvedOptions().locale ?? process.env.LANG?.split('.')[0]\n\n this.trigger({\n function_id: EngineFunctions.REGISTER_WORKER,\n payload: {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n telemetry: {\n language,\n project_name: telemetryOpts?.project_name ?? detectProjectName(),\n framework: telemetryOpts?.framework?.trim() || 'iii-node',\n amplitude_api_key: telemetryOpts?.amplitude_api_key,\n },\n },\n action: { type: 'void' },\n })\n }\n\n /**\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name.\n *\n * Registers 5 of the 6 `IStream` methods (`get`, `set`, `delete`, `list`,\n * `listGroups`). The `update` method is not registered -- atomic updates are\n * handled by the engine's built-in stream update logic.\n *\n * @param streamName - Name of the stream.\n * @param stream - Object implementing the {@link IStream} interface.\n *\n * @example\n * ```typescript\n * iii.createStream('my-stream', {\n * async get(input) { return null },\n * async set(input) { return null },\n * async delete(input) { return { old_value: undefined } },\n * async list(input) { return [] },\n * async listGroups(input) { return [] },\n * async update(input) { return null },\n * })\n * ```\n */\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction(`stream::get(${streamName})`, stream.get.bind(stream))\n this.registerFunction(`stream::set(${streamName})`, stream.set.bind(stream))\n this.registerFunction(`stream::delete(${streamName})`, stream.delete.bind(stream))\n this.registerFunction(`stream::list(${streamName})`, stream.list.bind(stream))\n this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream))\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket. Swallow any close-time errors (most commonly\n // \"WebSocket was closed before the connection was established\" —\n // emitted when `close()` fires while still in CONNECTING state\n // and there's no error listener). Without a catch-all listener,\n // that event becomes an unhandled exception because we remove\n // every listener right above the close call.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.close()\n } catch {\n // ignore — shutting down anyway\n }\n this.ws = undefined\n }\n\n this.setConnectionState('disconnected')\n }\n\n // private methods\n\n private setConnectionState(state: IIIConnectionState): void {\n if (this.connectionState !== state) {\n this.connectionState = state\n }\n }\n\n private connect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n this.setConnectionState('connecting')\n this.ws = new WebSocket(this.address, { headers: this.options?.headers })\n this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } = this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.functions.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterFunction, message, true)\n })\n this.triggers.forEach((trigger) => {\n this.sendMessage(MessageType.RegisterTrigger, trigger, true)\n })\n\n // Optimized: swap with empty array instead of splice\n const pending = this.messagesToSend\n this.messagesToSend = []\n for (const message of pending) {\n if (\n message.type === MessageType.InvokeFunction &&\n typeof message.invocation_id === 'string' &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, (err) => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private toWireFormat(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>): Record<string, unknown> {\n const { message_type: _, ...rest } = message as Record<string, unknown>\n if (messageType === MessageType.RegisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.UnregisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.TriggerRegistrationResult && 'type' in message) {\n const { type: triggerType, ...resultRest } = message as TriggerRegistrationResultMessage\n return { type: messageType, ...resultRest, trigger_type: triggerType }\n }\n return { type: messageType, ...rest } as Record<string, unknown>\n }\n\n private sendMessage(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>, skipIfClosed = false): void {\n const wireMessage = this.toWireFormat(messageType, message)\n if (this.isOpen()) {\n this.sendMessageRaw(JSON.stringify(wireMessage))\n } else if (!skipIfClosed) {\n this.messagesToSend.push(wireMessage)\n }\n }\n\n private logError(message: string, error?: unknown): void {\n const otelLogger = getLogger()\n const errorMessage = error instanceof Error ? error.message : String(error ?? '')\n\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.ERROR,\n body: `[iii] ${message}${errorMessage ? `: ${errorMessage}` : ''}`,\n })\n } else {\n console.error(`[iii] ${message}`, error ?? '')\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n if (error) {\n invocation.reject(this.toInvocationError(error, invocation.function_id))\n } else {\n invocation.resolve(result)\n }\n }\n\n this.invocations.delete(invocation_id)\n }\n\n /**\n * Wrap a wire-format `ErrorBody` in {@link IIIInvocationError} so callers get\n * a real `Error` with a readable `.message` and a typed `.code`. Pass-through\n * for values that are already `Error` subclasses. Everything else is wrapped\n * under an `UNKNOWN` code so `String(err) !== '[object Object]'` holds for\n * every rejection path.\n */\n private toInvocationError(error: unknown, function_id?: string): Error {\n if (error instanceof Error) {\n return error\n }\n if (isErrorBody(error)) {\n return new IIIInvocationError({\n code: error.code,\n message: error.message,\n function_id,\n stacktrace: error.stacktrace,\n })\n }\n // JSON.stringify(undefined) returns undefined (not \"undefined\"), which\n // would set message to the literal string \"undefined\" after type coercion\n // and leak an uninformative rejection. Fall back through String(error)\n // so every path produces a concrete, readable string.\n const message =\n typeof error === 'string'\n ? error\n : (JSON.stringify(error) ?? String(error))\n return new IIIInvocationError({\n code: 'UNKNOWN',\n message,\n function_id,\n })\n }\n\n private resolveChannelValue(value: unknown): unknown {\n if (isChannelRef(value)) {\n return value.direction === 'read'\n ? new ChannelReader(this.address, value)\n : new ChannelWriter(this.address, value)\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.resolveChannelValue(item))\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = this.resolveChannelValue(v)\n }\n return out\n }\n return value\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n const resolvedInput = this.resolveChannelValue(input) as TInput\n\n if (fn?.handler) {\n if (!invocation_id) {\n try {\n await fn.handler(resolvedInput, traceparent, baggage)\n } catch (error) {\n this.logError(`Error invoking function ${function_id}`, error)\n }\n return\n }\n\n try {\n const result = await fn.handler(resolvedInput, traceparent, baggage)\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n result,\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n } catch (error) {\n const isError = error instanceof Error\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: {\n code: 'invocation_failed',\n message: isError ? error.message : String(error),\n stacktrace: isError ? error.stack : undefined,\n },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n const errorCode = fn ? 'function_not_invokable' : 'function_not_found'\n const errorMessage = fn ? 'Function is HTTP-invoked and cannot be invoked locally' : 'Function not found'\n if (invocation_id) {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: errorCode, message: errorMessage },\n traceparent,\n baggage,\n })\n }\n }\n }\n\n private async onRegisterTrigger(message: { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> }) {\n const { trigger_type, id, function_id, config, metadata } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata })\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n })\n } catch (error) {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_registration_failed', message: (error as Error).message },\n })\n }\n } else {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_type_not_found', message: 'Trigger type not found' },\n })\n }\n }\n\n private onTriggerRegistrationResult(\n message: { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n ): void {\n if (!message.error) return\n const triggerType = message.trigger_type ?? message.type ?? ''\n console.error(\n `[iii] Trigger registration failed for \"${message.id}\" (${triggerType}): ${message.error.message}`,\n )\n }\n\n private onMessage(socketMessage: Data): void {\n let msgType: MessageType\n let message: Record<string, unknown>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as Record<string, unknown>\n msgType = parsed.type as MessageType\n const { type: _, ...rest } = parsed\n message = rest\n } catch (error) {\n this.logError('Failed to parse incoming message', error)\n return\n }\n\n if (msgType === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (msgType === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (msgType === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(message as { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> })\n } else if (msgType === MessageType.TriggerRegistrationResult) {\n this.onTriggerRegistrationResult(\n message as { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n )\n } else if (msgType === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link ISdk.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * iii.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notify',\n * payload: {},\n * action: TriggerAction.Void(),\n * })\n * ```\n */\nexport const TriggerAction = {\n /**\n * Routes the invocation through a named queue. The engine enqueues the job,\n * acknowledges the caller with `{ messageReceiptId }`, and processes it\n * asynchronously.\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }): TriggerActionType => ({ type: 'enqueue', ...opts }),\n /**\n * Fire-and-forget routing. The engine forwards the invocation without\n * waiting for a response or queuing the job.\n */\n Void: (): TriggerActionType => ({ type: 'void' }),\n} as const\n\n/**\n * Creates and returns a connected SDK instance. The WebSocket connection is\n * established automatically -- there is no separate `connect()` call.\n *\n * @param address - WebSocket URL of the III engine (e.g. `ws://localhost:49134`).\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link ISdk} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const iii = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Writable","WebSocket","Readable","path","fs","os","context","SpanKind","trace","WebSocket","SeverityNumber"],"sources":["../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/iii-types.ts","../src/utils.ts","../src/iii.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","/**\n * Typed error surfaced when an invocation dispatched over the SDK fails — RBAC\n * rejection (FORBIDDEN), handler-level failure, or a timeout waiting for the\n * engine to respond. Wraps the wire `ErrorBody` shape plus the `function_id`\n * that was targeted, so callers get a single error type across all failure\n * modes and can disambiguate via `err.code`.\n *\n * Before this existed, rejection values were plain `ErrorBody`-shaped objects,\n * which printed as `[object Object]` when stringified — leaving developers to\n * grep through SDK source to figure out what tripped. The class name, `code`\n * prefix in the message, and `function_id` field together make a rejection\n * self-describing.\n */\nexport type IIIInvocationErrorInit = {\n code: string\n message: string\n function_id?: string\n stacktrace?: string\n}\n\nexport class IIIInvocationError extends Error {\n public readonly code: string\n public readonly function_id?: string\n public readonly stacktrace?: string\n\n constructor(init: IIIInvocationErrorInit) {\n super(`${init.code}: ${init.message}`)\n this.name = 'IIIInvocationError'\n this.code = init.code\n this.function_id = init.function_id\n this.stacktrace = init.stacktrace\n }\n}\n\n/**\n * True when `value` looks like the wire `ErrorBody` the engine sends in\n * `InvocationResult.error`: `{ code: string, message: string, stacktrace?: string }`.\n * Used to distinguish an engine rejection (which we wrap in\n * {@link IIIInvocationError}) from a JS `Error` thrown elsewhere.\n */\nexport function isErrorBody(value: unknown): value is {\n code: string\n message: string\n stacktrace?: string\n} {\n if (typeof value !== 'object' || value === null) return false\n const v = value as { code?: unknown; message?: unknown; stacktrace?: unknown }\n return (\n typeof v.code === 'string' &&\n typeof v.message === 'string' &&\n (v.stacktrace === undefined || typeof v.stacktrace === 'string')\n )\n}\n","/**\n * Constants for the III module.\n */\n\n/**\n * Engine function paths for internal operations.\n *\n * Naming note: `LIST_TRIGGERS` / `INFO_TRIGGERS` cover trigger TYPES\n * (templates). `LIST_REGISTERED_TRIGGERS` / `INFO_REGISTERED_TRIGGERS`\n * cover trigger INSTANCES (subscriber rows). The old\n * `engine::trigger-types::list` builtin has been removed and is now\n * served by `engine::triggers::list`.\n */\nexport const EngineFunctions = {\n LIST_FUNCTIONS: 'engine::functions::list',\n INFO_FUNCTIONS: 'engine::functions::info',\n LIST_WORKERS: 'engine::workers::list',\n INFO_WORKERS: 'engine::workers::info',\n LIST_TRIGGERS: 'engine::triggers::list',\n INFO_TRIGGERS: 'engine::triggers::info',\n LIST_REGISTERED_TRIGGERS: 'engine::registered-triggers::list',\n INFO_REGISTERED_TRIGGERS: 'engine::registered-triggers::info',\n REGISTER_WORKER: 'engine::workers::register',\n} as const\n\n/** Engine trigger types */\nexport const EngineTriggers = {\n FUNCTIONS_AVAILABLE: 'engine::functions-available',\n LOG: 'log',\n} as const\n\n/** Log function paths */\nexport const LogFunctions = {\n INFO: 'engine::log::info',\n WARN: 'engine::log::warn',\n ERROR: 'engine::log::error',\n DEBUG: 'engine::log::debug',\n} as const\n\n/** Connection state for the III WebSocket */\nexport type IIIConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface IIIReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Default invocation timeout in milliseconds */\nexport const DEFAULT_INVOCATION_TIMEOUT_MS = 30000\n","export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n message_type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n message_type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n message_type: MessageType.UnregisterTrigger\n id: string\n type?: string\n}\n\nexport type ErrorBody = {\n code: string\n message: string\n stacktrace?: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n message_type: MessageType.TriggerRegistrationResult\n id: string\n type: string\n function_id: string\n error?: ErrorBody\n}\n\nexport type RegisterTriggerMessage = {\n message_type: MessageType.RegisterTrigger\n id: string\n type: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n}\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\nexport type RegisterFunctionFormat = {\n /**\n * The name of the parameter\n */\n name?: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map' | 'integer'\n /**\n * The body of the parameter (for objects)\n */\n properties?: Record<string, unknown>\n /**\n * The items of the parameter (for arrays)\n */\n items?: unknown\n /**\n * Whether the parameter is required\n */\n required?: string[]\n [key: string]: unknown\n}\n\nexport type RegisterFunctionMessage = {\n message_type: MessageType.RegisterFunction\n /**\n * The path of the function (use :: for namespacing, e.g. external::my_lambda)\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n /**\n * HTTP invocation config for external HTTP functions (Lambda, Cloudflare Workers, etc.)\n */\n invocation?: HttpInvocationConfig\n}\n\n/**\n * Routing action for {@link TriggerRequest}. Determines how the engine\n * handles the invocation.\n *\n * - `enqueue` -- Routes through a named queue for async processing.\n * - `void` -- Fire-and-forget, no response.\n */\nexport type TriggerAction = { type: 'enqueue'; queue: string } | { type: 'void' }\n\n/**\n * Input passed to the RBAC auth function during WebSocket upgrade.\n * Contains the HTTP headers, query parameters, and client IP from the\n * connecting worker's upgrade request.\n */\nexport type AuthInput = {\n /** HTTP headers from the WebSocket upgrade request. */\n headers: Record<string, string>\n /** Query parameters from the upgrade URL. Each key maps to an array of values to support repeated keys. */\n query_params: Record<string, string[]>\n /** IP address of the connecting client. */\n ip_address: string\n}\n\n/**\n * Return value from the RBAC auth function. Controls which functions the\n * authenticated worker can invoke and what context is forwarded to the\n * middleware.\n */\nexport type AuthResult = {\n /** Additional function IDs to allow beyond the `expose_functions` config. */\n allowed_functions: string[]\n /** Function IDs to deny even if they match `expose_functions`. Takes precedence over allowed. */\n forbidden_functions: string[]\n /** Trigger type IDs the worker may register triggers for. When omitted, all types are allowed. */\n allowed_trigger_types?: string[]\n /** Whether the worker may register new trigger types. */\n allow_trigger_type_registration: boolean\n /** Whether the worker may register new functions. Defaults to `true` if omitted. */\n allow_function_registration?: boolean\n /** Arbitrary context forwarded to the middleware function on every invocation. */\n context: Record<string, unknown>\n /** Optional prefix applied to all function IDs registered by this worker. */\n function_registration_prefix?: string\n}\n\n/**\n * Input passed to the RBAC middleware function on every function invocation\n * through the RBAC port. The middleware can inspect, modify, or reject the\n * call before it reaches the target function.\n */\nexport type MiddlewareFunctionInput = {\n /** ID of the function being invoked. */\n function_id: string\n /** Payload sent by the caller. */\n payload: Record<string, unknown>\n /** Routing action, if any. */\n action?: TriggerAction\n /** Auth context returned by the auth function for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Input passed to the `on_trigger_type_registration_function_id` hook\n * when a worker attempts to register a new trigger type through the RBAC port.\n * Return an {@link OnTriggerTypeRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerTypeRegistrationInput = {\n /** ID of the trigger type being registered. */\n trigger_type_id: string\n /** Human-readable description of the trigger type. */\n description: string\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_type_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerTypeRegistrationResult = {\n /** Mapped trigger type ID. */\n trigger_type_id?: string\n /** Mapped description. */\n description?: string\n}\n\n/**\n * Input passed to the `on_trigger_registration_function_id` hook\n * when a worker attempts to register a trigger through the RBAC port.\n * Return an {@link OnTriggerRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerRegistrationInput = {\n /** ID of the trigger being registered. */\n trigger_id: string\n /** Trigger type identifier. */\n trigger_type: string\n /** ID of the function this trigger is bound to. */\n function_id: string\n /** Trigger-specific configuration. */\n config: unknown\n /** Arbitrary metadata attached to the trigger. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerRegistrationResult = {\n /** Mapped trigger ID. */\n trigger_id?: string\n /** Mapped trigger type. */\n trigger_type?: string\n /** Mapped function ID. */\n function_id?: string\n /** Mapped trigger configuration. */\n config?: unknown\n}\n\n/**\n * Input passed to the `on_function_registration_function_id` hook\n * when a worker attempts to register a function through the RBAC port.\n * Return an {@link OnFunctionRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnFunctionRegistrationInput = {\n /** ID of the function being registered. */\n function_id: string\n /** Human-readable description of the function. */\n description?: string\n /** Arbitrary metadata attached to the function. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_function_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnFunctionRegistrationResult = {\n /** Mapped function ID. */\n function_id?: string\n /** Mapped description. */\n description?: string\n /** Mapped metadata. */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Result returned when a function is invoked with `TriggerAction.Enqueue`.\n */\nexport type EnqueueResult = {\n /** Unique receipt ID for the enqueued message. */\n messageReceiptId: string\n}\n\n/**\n * Request object passed to {@link ISdk.trigger}.\n *\n * @typeParam TInput - Type of the payload.\n */\nexport type TriggerRequest<TInput = unknown> = {\n /** ID of the function to invoke. */\n function_id: string\n /** Payload to pass to the function. */\n payload: TInput\n /** Routing action. Omit for synchronous request/response. */\n action?: TriggerAction\n /** Override the default invocation timeout in milliseconds. */\n timeoutMs?: number\n}\n\nexport type InvokeFunctionMessage = {\n message_type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n /**\n * Trigger action for queue routing or fire-and-forget\n */\n action?: TriggerAction\n}\n\nexport type InvocationResultMessage = {\n message_type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: unknown\n error?: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type WorkerRegisteredMessage = {\n message_type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n message_type: MessageType.UnregisterFunction\n id: string\n}\n\n/**\n * Serializable reference to one end of a streaming channel. Can be included\n * in invocation payloads to pass channel endpoints between workers.\n */\nexport type StreamChannelRef = {\n /** Unique channel identifier. */\n channel_id: string\n /** Access key for authentication. */\n access_key: string\n /** Whether this ref is for reading or writing. */\n direction: 'read' | 'write'\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n","import { context, trace } from '@opentelemetry/api'\nimport { createRequire } from 'node:module'\nimport * as os from 'node:os'\nimport { type Data, WebSocket } from 'ws'\nimport { ChannelReader, ChannelWriter } from './channels'\nimport { IIIInvocationError, isErrorBody } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n} from './iii-constants'\nimport {\n type HttpInvocationConfig,\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerAction as TriggerActionType,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/observability'\nimport { getMeter, getTracer } from '@iii-dev/observability/internal'\nimport { SpanKind } from '@opentelemetry/api'\nimport type { IStream } from './stream'\nimport { detectProjectName } from './utils'\nimport {\n extractContext,\n getLogger,\n initOtel,\n injectBaggage,\n injectTraceparent,\n type OtelConfig,\n recordSpanEvent,\n redactAndTruncate,\n resolveMaxBytesFromEnv,\n SeverityNumber,\n shutdownOtel,\n withSpan,\n} from '@iii-dev/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n Invocation,\n ISdk,\n RegisterFunctionOptions,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n TriggerTypeRef,\n} from './types'\nimport { isChannelRef } from './utils'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** @internal */\nexport type TelemetryOptions = {\n language?: string\n project_name?: string\n framework?: string\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const iii = registerWorker('ws://localhost:49134', {\n * workerName: 'my-worker',\n * invocationTimeoutMs: 10000,\n * reconnectionConfig: { maxRetries: 5 },\n * })\n * ```\n */\nexport type InitOptions = {\n /** Display name for this worker. Defaults to `hostname:pid`. */\n workerName?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `trigger()` in milliseconds. Defaults to `30000`. */\n invocationTimeoutMs?: number\n /**\n * WebSocket reconnection behavior.\n *\n * @see {@link IIIReconnectionConfig} for available fields and defaults.\n */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\n /**\n * OpenTelemetry configuration. OTel is initialized automatically by default.\n * Set `{ enabled: false }` or env `OTEL_ENABLED=false/0/no/off` to disable.\n * The `engineWsUrl` is set automatically from the III address.\n */\n otel?: Omit<OtelConfig, 'engineWsUrl'>\n /** Custom HTTP headers sent during the WebSocket handshake. */\n headers?: Record<string, string>\n /** @internal */\n telemetry?: TelemetryOptions\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private invocations = new Map<string, Invocation & { timeout?: NodeJS.Timeout }>()\n private triggers = new Map<string, RegisterTriggerMessage>()\n private triggerTypes = new Map<string, RemoteTriggerTypeData>()\n private messagesToSend: Record<string, unknown>[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry (enabled by default, opt-out via config or env)\n initOtel({ ...options?.otel, engineWsUrl: this.address })\n\n this.connect()\n }\n\n /**\n * Registers a custom trigger type with the engine. A trigger type defines\n * how external events (HTTP, cron, queue, etc.) map to function invocations.\n *\n * @param triggerType - Trigger type registration input.\n * @param triggerType.id - Unique trigger type identifier.\n * @param triggerType.description - Human-readable description.\n * @param handler - Handler with `registerTrigger` / `unregisterTrigger` callbacks.\n *\n * @example\n * ```typescript\n * iii.registerTriggerType(\n * { id: 'my-trigger', description: 'Custom trigger' },\n * {\n * async registerTrigger({ id, function_id, config }) { },\n * async unregisterTrigger({ id, function_id, config }) { },\n * },\n * )\n * ```\n */\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>,\n handler: TriggerHandler<TConfig>,\n ): TriggerTypeRef<TConfig> => {\n this.sendMessage(MessageType.RegisterTriggerType, triggerType, true)\n this.triggerTypes.set(triggerType.id, {\n message: { ...triggerType, message_type: MessageType.RegisterTriggerType },\n handler,\n })\n\n return {\n id: triggerType.id,\n registerTrigger: (functionId: string, config: TConfig, metadata?: Record<string, unknown>) => {\n return this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n },\n registerFunction: (functionId, handler, config, metadata?) => {\n const ref = this.registerFunction(functionId, handler)\n this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n return ref\n },\n unregister: () => {\n this.unregisterTriggerType(triggerType)\n },\n }\n }\n\n /**\n * Unregisters a previously registered trigger type.\n *\n * @param triggerType - The trigger type to unregister (must match the `id` used during registration).\n */\n unregisterTriggerType = (triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>): void => {\n this.sendMessage(MessageType.UnregisterTriggerType, triggerType, true)\n this.triggerTypes.delete(triggerType.id)\n }\n\n /**\n * Binds a trigger configuration to a registered function. When the trigger\n * fires, the engine invokes the target function.\n *\n * @param trigger - Trigger registration input.\n * @param trigger.type - Trigger type (e.g. `http`, `durable:subscriber`, `cron`).\n * @param trigger.function_id - ID of the function to invoke.\n * @param trigger.config - Trigger-specific configuration.\n * @returns A {@link Trigger} handle with an `unregister()` method.\n *\n * @example\n * ```typescript\n * const trigger = iii.registerTrigger({\n * type: 'http',\n * function_id: 'greet',\n * config: { api_path: '/greet', http_method: 'GET' },\n * })\n *\n * // Later...\n * trigger.unregister()\n * ```\n */\n registerTrigger = (trigger: Omit<RegisterTriggerMessage, 'message_type' | 'id'>): Trigger => {\n const id = crypto.randomUUID()\n const fullTrigger: RegisterTriggerMessage = {\n ...trigger,\n id,\n message_type: MessageType.RegisterTrigger,\n }\n this.sendMessage(MessageType.RegisterTrigger, fullTrigger, true)\n this.triggers.set(id, fullTrigger)\n\n return {\n unregister: () => {\n this.sendMessage(MessageType.UnregisterTrigger, {\n id,\n message_type: MessageType.UnregisterTrigger,\n type: fullTrigger.type,\n })\n this.triggers.delete(id)\n },\n }\n }\n\n /**\n * Registers a function with the engine. The `functionId` is the unique identifier\n * used by triggers and invocations.\n *\n * Pass a handler for local execution, or an {@link HttpInvocationConfig}\n * for HTTP-invoked functions (Lambda, Cloudflare Workers, etc.).\n *\n * @param functionId - Unique function identifier.\n * @param handlerOrInvocation - Async handler or HTTP invocation config.\n * @param options - Optional function registration options (description, request/response formats, metadata).\n * @returns A {@link FunctionRef} with `id` and `unregister()`.\n *\n * @example\n * ```typescript\n * const fn = iii.registerFunction(\n * 'greet',\n * async (input: { name: string }) => {\n * return { message: `Hello, ${input.name}!` }\n * },\n * { description: 'Greets a user' },\n * )\n * ```\n */\n registerFunction = (\n functionId: string,\n handlerOrInvocation: RemoteFunctionHandler | HttpInvocationConfig,\n options?: RegisterFunctionOptions,\n ): FunctionRef => {\n if (!functionId || functionId.trim() === '') {\n throw new Error('id is required')\n }\n if (this.functions.has(functionId)) {\n throw new Error(`function id already registered: ${functionId}`)\n }\n\n const isHandler = typeof handlerOrInvocation === 'function'\n\n const fullMessage: RegisterFunctionMessage = isHandler\n ? { ...options, id: functionId, message_type: MessageType.RegisterFunction }\n : {\n ...options,\n id: functionId,\n message_type: MessageType.RegisterFunction,\n invocation: {\n url: handlerOrInvocation.url,\n method: handlerOrInvocation.method ?? 'POST',\n timeout_ms: handlerOrInvocation.timeout_ms,\n headers: handlerOrInvocation.headers,\n auth: handlerOrInvocation.auth,\n },\n }\n\n this.sendMessage(MessageType.RegisterFunction, fullMessage, true)\n\n if (isHandler) {\n const handler = handlerOrInvocation as RemoteFunctionHandler\n this.functions.set(functionId, {\n message: fullMessage,\n handler: async (input, traceparent?: string, baggage?: string) => {\n const tracePayloads = !(\n process.env.III_DISABLE_TRACE_PAYLOADS === '1' ||\n process.env.III_DISABLE_TRACE_PAYLOADS?.toLowerCase() === 'true'\n )\n const payloadMaxBytes = resolveMaxBytesFromEnv()\n\n const runHandler = async () => {\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(input, payloadMaxBytes)\n recordSpanEvent('iii.invocation.input', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n })\n }\n try {\n const result = await handler(input)\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(result, payloadMaxBytes)\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': true,\n })\n }\n return result\n } catch (err) {\n if (tracePayloads) {\n const errMsg = err instanceof Error ? err.message : String(err)\n const { json, truncated } = redactAndTruncate(\n { error: errMsg },\n payloadMaxBytes,\n )\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': false,\n })\n }\n throw err\n }\n }\n\n if (getTracer()) {\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`call ${functionId}`, { kind: SpanKind.SERVER }, async () => await runHandler()),\n )\n }\n\n const traceId = crypto.randomUUID().replace(/-/g, '')\n const spanId = crypto.randomUUID().replace(/-/g, '').slice(0, 16)\n const syntheticSpan = trace.wrapSpanContext({ traceId, spanId, traceFlags: 1 })\n\n return context.with(trace.setSpan(context.active(), syntheticSpan), async () => await runHandler())\n },\n })\n } else {\n this.functions.set(functionId, { message: fullMessage })\n }\n\n return {\n id: functionId,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: functionId }, true)\n this.functions.delete(functionId)\n },\n }\n }\n\n /**\n * Creates a streaming channel pair for worker-to-worker data transfer.\n * Returns a {@link Channel} with a local writer/reader and serializable refs\n * that can be passed as fields in invocation data to other functions.\n *\n * @param bufferSize - Optional buffer size for the channel (default: 64).\n * @returns A {@link Channel} with `writer`, `reader`, and their serializable refs.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.close()\n * ```\n */\n createChannel = async (bufferSize?: number): Promise<import('./types').Channel> => {\n const result = await this.trigger<{ buffer_size?: number }, { writer: StreamChannelRef; reader: StreamChannelRef }>(\n { function_id: 'engine::channels::create', payload: { buffer_size: bufferSize } },\n )\n\n return {\n writer: new ChannelWriter(this.address, result.writer),\n reader: new ChannelReader(this.address, result.reader),\n writerRef: result.writer,\n readerRef: result.reader,\n }\n }\n\n /**\n * Invokes a remote function. The routing behavior and return type depend\n * on the `action` field of the request.\n *\n * | `action` | Behavior | Return type |\n * |-------------------------------|----------------------------------------------------|----------------------- |\n * | _(none)_ | Synchronous -- waits for the function to return | `Promise<TOutput>` |\n * | `TriggerAction.Enqueue(...)` | Async via named queue -- engine acknowledges enqueue | `Promise<EnqueueResult>` |\n * | `TriggerAction.Void()` | Fire-and-forget -- no response | `Promise<undefined>` |\n *\n * @param request - The trigger request.\n * @param request.function_id - ID of the function to invoke.\n * @param request.payload - Payload to pass to the function.\n * @param request.action - Routing action. Omit for synchronous request/response.\n * @param request.timeoutMs - Override the default invocation timeout.\n * @returns The result of the function invocation.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Synchronous\n * const result = await iii.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await iii.trigger({\n * function_id: 'payments::charge',\n * payload: { orderId: '123', amount: 49.99 },\n * action: TriggerAction.Enqueue({ queue: 'payment' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n trigger = async <TInput, TOutput>(request: TriggerRequest<TInput>): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs } = request\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\n\n // Void is fire-and-forget — no invocation_id, no response\n if (action?.type === 'void') {\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, {\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n return undefined as TOutput\n }\n\n // Enqueue and default: send invocation_id, await response\n const invocation_id = crypto.randomUUID()\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n\n return new Promise<TOutput>((resolve, reject) => {\n const timeout = setTimeout(() => {\n const invocation = this.invocations.get(invocation_id)\n if (invocation) {\n this.invocations.delete(invocation_id)\n reject(\n new IIIInvocationError({\n code: 'TIMEOUT',\n message: `invocation timed out after ${effectiveTimeout}ms`,\n function_id,\n }),\n )\n }\n }, effectiveTimeout)\n\n this.invocations.set(invocation_id, {\n resolve: (result: TOutput) => {\n clearTimeout(timeout)\n resolve(result)\n },\n reject: (error: unknown) => {\n clearTimeout(timeout)\n reject(error)\n },\n function_id,\n timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n })\n }\n\n private registerWorkerMetadata(): void {\n const telemetryOpts = this.options?.telemetry\n const language =\n telemetryOpts?.language ?? Intl.DateTimeFormat().resolvedOptions().locale ?? process.env.LANG?.split('.')[0]\n\n this.trigger({\n function_id: EngineFunctions.REGISTER_WORKER,\n payload: {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n telemetry: {\n language,\n project_name: telemetryOpts?.project_name ?? detectProjectName(),\n framework: telemetryOpts?.framework?.trim() || 'iii-node',\n amplitude_api_key: telemetryOpts?.amplitude_api_key,\n },\n },\n action: { type: 'void' },\n })\n }\n\n /**\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name.\n *\n * Registers 5 of the 6 `IStream` methods (`get`, `set`, `delete`, `list`,\n * `listGroups`). The `update` method is not registered -- atomic updates are\n * handled by the engine's built-in stream update logic.\n *\n * @param streamName - Name of the stream.\n * @param stream - Object implementing the {@link IStream} interface.\n *\n * @example\n * ```typescript\n * iii.createStream('my-stream', {\n * async get(input) { return null },\n * async set(input) { return null },\n * async delete(input) { return { old_value: undefined } },\n * async list(input) { return [] },\n * async listGroups(input) { return [] },\n * async update(input) { return null },\n * })\n * ```\n */\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction(`stream::get(${streamName})`, stream.get.bind(stream))\n this.registerFunction(`stream::set(${streamName})`, stream.set.bind(stream))\n this.registerFunction(`stream::delete(${streamName})`, stream.delete.bind(stream))\n this.registerFunction(`stream::list(${streamName})`, stream.list.bind(stream))\n this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream))\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket. Swallow any close-time errors (most commonly\n // \"WebSocket was closed before the connection was established\" —\n // emitted when `close()` fires while still in CONNECTING state\n // and there's no error listener). Without a catch-all listener,\n // that event becomes an unhandled exception because we remove\n // every listener right above the close call.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.close()\n } catch {\n // ignore — shutting down anyway\n }\n this.ws = undefined\n }\n\n this.setConnectionState('disconnected')\n }\n\n // private methods\n\n private setConnectionState(state: IIIConnectionState): void {\n if (this.connectionState !== state) {\n this.connectionState = state\n }\n }\n\n private connect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n this.setConnectionState('connecting')\n this.ws = new WebSocket(this.address, { headers: this.options?.headers })\n this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } = this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.functions.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterFunction, message, true)\n })\n this.triggers.forEach((trigger) => {\n this.sendMessage(MessageType.RegisterTrigger, trigger, true)\n })\n\n // Optimized: swap with empty array instead of splice\n const pending = this.messagesToSend\n this.messagesToSend = []\n for (const message of pending) {\n if (\n message.type === MessageType.InvokeFunction &&\n typeof message.invocation_id === 'string' &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, (err) => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private toWireFormat(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>): Record<string, unknown> {\n const { message_type: _, ...rest } = message as Record<string, unknown>\n if (messageType === MessageType.RegisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.UnregisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.TriggerRegistrationResult && 'type' in message) {\n const { type: triggerType, ...resultRest } = message as TriggerRegistrationResultMessage\n return { type: messageType, ...resultRest, trigger_type: triggerType }\n }\n return { type: messageType, ...rest } as Record<string, unknown>\n }\n\n private sendMessage(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>, skipIfClosed = false): void {\n const wireMessage = this.toWireFormat(messageType, message)\n if (this.isOpen()) {\n this.sendMessageRaw(JSON.stringify(wireMessage))\n } else if (!skipIfClosed) {\n this.messagesToSend.push(wireMessage)\n }\n }\n\n private logError(message: string, error?: unknown): void {\n const otelLogger = getLogger()\n const errorMessage = error instanceof Error ? error.message : String(error ?? '')\n\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.ERROR,\n body: `[iii] ${message}${errorMessage ? `: ${errorMessage}` : ''}`,\n })\n } else {\n console.error(`[iii] ${message}`, error ?? '')\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n if (error) {\n invocation.reject(this.toInvocationError(error, invocation.function_id))\n } else {\n invocation.resolve(result)\n }\n }\n\n this.invocations.delete(invocation_id)\n }\n\n /**\n * Wrap a wire-format `ErrorBody` in {@link IIIInvocationError} so callers get\n * a real `Error` with a readable `.message` and a typed `.code`. Pass-through\n * for values that are already `Error` subclasses. Everything else is wrapped\n * under an `UNKNOWN` code so `String(err) !== '[object Object]'` holds for\n * every rejection path.\n */\n private toInvocationError(error: unknown, function_id?: string): Error {\n if (error instanceof Error) {\n return error\n }\n if (isErrorBody(error)) {\n return new IIIInvocationError({\n code: error.code,\n message: error.message,\n function_id,\n stacktrace: error.stacktrace,\n })\n }\n // JSON.stringify(undefined) returns undefined (not \"undefined\"), which\n // would set message to the literal string \"undefined\" after type coercion\n // and leak an uninformative rejection. Fall back through String(error)\n // so every path produces a concrete, readable string.\n const message =\n typeof error === 'string'\n ? error\n : (JSON.stringify(error) ?? String(error))\n return new IIIInvocationError({\n code: 'UNKNOWN',\n message,\n function_id,\n })\n }\n\n private resolveChannelValue(value: unknown): unknown {\n if (isChannelRef(value)) {\n return value.direction === 'read'\n ? new ChannelReader(this.address, value)\n : new ChannelWriter(this.address, value)\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.resolveChannelValue(item))\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = this.resolveChannelValue(v)\n }\n return out\n }\n return value\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n const resolvedInput = this.resolveChannelValue(input) as TInput\n\n if (fn?.handler) {\n if (!invocation_id) {\n try {\n await fn.handler(resolvedInput, traceparent, baggage)\n } catch (error) {\n this.logError(`Error invoking function ${function_id}`, error)\n }\n return\n }\n\n try {\n const result = await fn.handler(resolvedInput, traceparent, baggage)\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n result,\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n } catch (error) {\n const isError = error instanceof Error\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: {\n code: 'invocation_failed',\n message: isError ? error.message : String(error),\n stacktrace: isError ? error.stack : undefined,\n },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n const errorCode = fn ? 'function_not_invokable' : 'function_not_found'\n const errorMessage = fn ? 'Function is HTTP-invoked and cannot be invoked locally' : 'Function not found'\n if (invocation_id) {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: errorCode, message: errorMessage },\n traceparent,\n baggage,\n })\n }\n }\n }\n\n private async onRegisterTrigger(message: { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> }) {\n const { trigger_type, id, function_id, config, metadata } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata })\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n })\n } catch (error) {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_registration_failed', message: (error as Error).message },\n })\n }\n } else {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_type_not_found', message: 'Trigger type not found' },\n })\n }\n }\n\n private onTriggerRegistrationResult(\n message: { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n ): void {\n if (!message.error) return\n const triggerType = message.trigger_type ?? message.type ?? ''\n console.error(\n `[iii] Trigger registration failed for \"${message.id}\" (${triggerType}): ${message.error.message}`,\n )\n }\n\n private onMessage(socketMessage: Data): void {\n let msgType: MessageType\n let message: Record<string, unknown>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as Record<string, unknown>\n msgType = parsed.type as MessageType\n const { type: _, ...rest } = parsed\n message = rest\n } catch (error) {\n this.logError('Failed to parse incoming message', error)\n return\n }\n\n if (msgType === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (msgType === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (msgType === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(message as { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> })\n } else if (msgType === MessageType.TriggerRegistrationResult) {\n this.onTriggerRegistrationResult(\n message as { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n )\n } else if (msgType === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link ISdk.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * iii.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notify',\n * payload: {},\n * action: TriggerAction.Void(),\n * })\n * ```\n */\nexport const TriggerAction = {\n /**\n * Routes the invocation through a named queue. The engine enqueues the job,\n * acknowledges the caller with `{ messageReceiptId }`, and processes it\n * asynchronously.\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }): TriggerActionType => ({ type: 'enqueue', ...opts }),\n /**\n * Fire-and-forget routing. The engine forwards the invocation without\n * waiting for a response or queuing the job.\n */\n Void: (): TriggerActionType => ({ type: 'void' }),\n} as const\n\n/**\n * Creates and returns a connected SDK instance. The WebSocket connection is\n * established automatically -- there is no separate `connect()` call.\n *\n * @param address - WebSocket URL of the III engine (e.g. `ws://localhost:49134`).\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link ISdk} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const iii = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAa,gBAAb,MAAa,cAAc;;oBACY,KAAK;;CAW1C,YAAY,cAAsB,KAAuB;YAV1B;iBACb;yBAIZ,EAAE;AAMN,OAAK,MAAM,gBAAgB,cAAc,IAAI,YAAY,IAAI,YAAY,QAAQ;AAEjF,OAAK,SAAS,IAAIA,qBAAS;GACzB,QAAQ,OAAe,WAAW,aAAa;IAC7C,MAAM,MAAM,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM;AAC/D,SAAK,YAAY,KAAK,SAAS;;GAEjC,QAAQ,aAAa;AACnB,QAAI,CAAC,KAAK,IAAI;AACZ,eAAU;AACV;;IAKF,MAAM,gBAAgB;AACpB,SAAI,KAAK,GACP,MAAK,GAAG,MAAM,KAAM,kBAAkB;AAExC,eAAU;;AAEZ,QAAI,KAAK,QACP,YAAW,SAAS,GAAG;QAEvB,MAAK,GAAG,GAAG,cAAc,WAAW,SAAS,GAAG,CAAC;;GAGrD,UAAU,KAAK,aAAa;AAC1B,QAAI,KAAK,GAAI,MAAK,GAAG,WAAW;AAChC,aAAS,IAAI;;GAEhB,CAAC;;CAGJ,AAAQ,kBAAwB;AAC9B,MAAI,KAAK,GAAI;AACb,OAAK,KAAK,IAAIC,aAAU,KAAK,IAAI;AAEjC,OAAK,GAAG,GAAG,cAAc;AACvB,QAAK,UAAU;AACf,QAAK,MAAM,EAAE,MAAM,cAAc,KAAK,gBACpC,MAAK,IAAI,KAAK,MAAM,SAAS;AAE/B,QAAK,gBAAgB,SAAS;IAC9B;AAEF,OAAK,GAAG,GAAG,UAAU,QAAQ;AAC3B,QAAK,OAAO,QAAQ,IAAI;IACxB;AAEF,OAAK,GAAG,GAAG,eAAe;AACxB,OAAI,CAAC,KAAK,OAAO,UACf,MAAK,OAAO,SAAS;IAEvB;;;CAIJ,YAAY,KAAmB;AAC7B,OAAK,iBAAiB;AACtB,OAAK,QAAQ,MAAM,QAAQ;AACzB,OAAI,IAAK,MAAK,OAAO,QAAQ,IAAI;IACjC;;;CAIJ,QAAc;AACZ,MAAI,CAAC,KAAK,GAAI;EACd,MAAM,gBAAgB;AACpB,OAAI,KAAK,GACP,MAAK,GAAG,MAAM,KAAM,gBAAgB;;AAGxC,MAAI,KAAK,QACP,UAAS;MAET,MAAK,GAAG,GAAG,cAAc,SAAS,CAAC;;CAIvC,AAAQ,YAAY,MAAc,UAA8C;EAC9E,IAAI,SAAS;EACb,MAAM,YAAY,QAA6B;AAC7C,OAAI,KAAK;AACP,aAAS,IAAI;AACb;;AAGF,OAAI,UAAU,KAAK,QAAQ;AACzB,aAAS,KAAK;AACd;;GAGF,MAAM,MAAM,KAAK,IAAI,SAAS,cAAc,YAAY,KAAK,OAAO;GACpE,MAAM,OAAO,KAAK,SAAS,QAAQ,IAAI;AACvC,YAAS;AACT,QAAK,QAAQ,MAAM,SAAS;;AAE9B,WAAS,KAAK;;CAGhB,AAAQ,QAAQ,MAAuB,UAA8C;AACnF,OAAK,iBAAiB;AACtB,MAAI,KAAK,WAAW,KAAK,GACvB,MAAK,GAAG,KAAK,OAAO,QAAQ,SAAS,OAAO,KAAK,CAAC;MAElD,MAAK,gBAAgB,KAAK;GAAE;GAAM;GAAU,CAAC;;;;;;;;;;;;;;;;;;AAoBnD,IAAa,gBAAb,MAA2B;CAQzB,YAAY,cAAsB,KAAuB;YAP1B;mBACX;0BAC8C,EAAE;AAMlE,OAAK,MAAM,gBAAgB,cAAc,IAAI,YAAY,IAAI,YAAY,OAAO;EAEhF,MAAM,OAAO;AACb,OAAK,SAAS,IAAIC,qBAAS;GACzB,OAAO;AACL,SAAK,iBAAiB;AACtB,QAAI,KAAK,GAAI,MAAK,GAAG,QAAQ;;GAE/B,QAAQ,KAAK,UAAU;AACrB,QAAI,KAAK,MAAM,KAAK,GAAG,eAAeD,aAAU,OAC9C,MAAK,GAAG,WAAW;AAErB,SAAK,KAAK;AACV,aAAS,IAAI;;GAEhB,CAAC;;CAGJ,AAAQ,kBAAwB;AAC9B,MAAI,KAAK,UAAW;AACpB,OAAK,YAAY;AACjB,OAAK,KAAK,IAAIA,aAAU,KAAK,IAAI;AAEjC,OAAK,GAAG,GAAG,cAAc;AACtB,GAAC,KAAK,GAAyC,aAAa;IAC7D;AAEF,OAAK,GAAG,GAAG,YAAY,MAAc,aAAsB;AACzD,OAAI,UACF;QAAI,CAAC,KAAK,OAAO,KAAK,KAAK,CACzB,MAAK,IAAI,OAAO;UAEb;IACL,MAAM,MAAM,KAAK,SAAS,QAAQ;AAClC,SAAK,MAAM,MAAM,KAAK,iBACpB,IAAG,IAAI;;IAGX;AAEF,OAAK,GAAG,GAAG,eAAe;AACxB,QAAK,KAAK;AACV,OAAI,CAAC,KAAK,OAAO,UAAW,MAAK,OAAO,KAAK,KAAK;IAClD;AAEF,OAAK,GAAG,GAAG,UAAU,QAAQ;AAC3B,QAAK,OAAO,QAAQ,IAAI;IACxB;;;CAIJ,UAAU,UAAuC;AAC/C,OAAK,iBAAiB,KAAK,SAAS;;CAGtC,MAAM,UAA2B;AAC/B,OAAK,iBAAiB;EACtB,MAAM,SAAmB,EAAE;AAE3B,aAAW,MAAM,SAAS,KAAK,OAC7B,QAAO,KAAK,OAAO,SAAS,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM,CAAC;AAGlE,SAAO,OAAO,OAAO,OAAO;;CAG9B,QAAc;AACZ,MAAI,KAAK,MAAM,KAAK,GAAG,eAAeA,aAAU,OAC9C,MAAK,GAAG,MAAM,KAAM,gBAAgB;;;AAK1C,SAAS,gBACP,cACA,WACA,WACA,WACQ;AAER,QAAO,GADM,aAAa,QAAQ,OAAO,GAAG,CAC7B,eAAe,UAAU,OAAO,mBAAmB,UAAU,CAAC,OAAO;;;;;ACrOtF,IAAa,qBAAb,cAAwC,MAAM;CAK5C,YAAY,MAA8B;AACxC,QAAM,GAAG,KAAK,KAAK,IAAI,KAAK,UAAU;AACtC,OAAK,OAAO;AACZ,OAAK,OAAO,KAAK;AACjB,OAAK,cAAc,KAAK;AACxB,OAAK,aAAa,KAAK;;;;;;;;;AAU3B,SAAgB,YAAY,OAI1B;AACA,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,IAAI;AACV,QACE,OAAO,EAAE,SAAS,YAClB,OAAO,EAAE,YAAY,aACpB,EAAE,eAAe,UAAa,OAAO,EAAE,eAAe;;;;;;;;;;;;;;;;;ACrC3D,MAAa,kBAAkB;CAC7B,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,cAAc;CACd,eAAe;CACf,eAAe;CACf,0BAA0B;CAC1B,0BAA0B;CAC1B,iBAAiB;CAClB;;AAGD,MAAa,iBAAiB;CAC5B,qBAAqB;CACrB,KAAK;CACN;;AAiCD,MAAa,qCAA4D;CACvE,gBAAgB;CAChB,YAAY;CACZ,mBAAmB;CACnB,cAAc;CACd,YAAY;CACb;;AAGD,MAAa,gCAAgC;;;;ACvE7C,IAAY,cAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;KACD;;;;;;;;;;;;;ACGD,SAAgB,kBAAkB,MAAc,QAAQ,KAAK,EAAsB;AACjF,KAAI;EACF,MAAM,WAAWE,UAAK,KAAK,KAAK,eAAe;AAC/C,MAAIC,QAAG,WAAW,SAAS,EAAE;GAC3B,MAAM,SAAS,KAAK,MAAMA,QAAG,aAAa,UAAU,OAAO,CAAC;AAC5D,OAAI,OAAO,OAAO,SAAS,UAAU;IACnC,MAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAI,QAAS,QAAO;;;SAGlB;AAKR,QADaD,UAAK,SAAS,IAAI,CAAC,MAAM,IACvB;;;;;;;;;;;;;;;;;;;;;;;;AAyBjB,MAAa,QAEX,aACG;AACH,QAAO,OAAO,QAA6B;EACzC,MAAM,EAAE,UAAU,GAAG,YAAY;AAWjC,SAAO,SAAS,SATmB;GACjC,SAAS,gBACP,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAc;IAAa,CAAC,CAAC;GAC3E,UAAU,YACR,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAe;IAAS,CAAC,CAAC;GACxE,QAAQ,SAAS;GACjB,aAAa,SAAS,OAAO;GAC9B,CAEqC;;;;;;;;;AAU1C,MAAa,gBAAgB,UAA8C;AACzE,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;CACxD,MAAM,QAAQ;AACd,QACE,OAAO,MAAM,eAAe,YAC5B,OAAO,MAAM,eAAe,aAC3B,MAAM,cAAc,UAAU,MAAM,cAAc;;;;;ACxBvD,MAAM,EAAE,SAAS,6FAD6B,CACL,kBAAkB;AAE3D,SAAS,YAAoB;AAC3B,QAAO,GAAGE,QAAG,UAAU,CAAC,GAAGA,QAAG,SAAS,CAAC,IAAIA,QAAG,MAAM,CAAC;;AAGxD,SAAS,uBAA+B;AACtC,QAAO,GAAGA,QAAG,UAAU,CAAC,GAAG,QAAQ;;AAgDrC,IAAM,MAAN,MAA0B;CAiBxB,YACE,AAAiB,SACjB,AAAiB,SACjB;EAFiB;EACA;mCAjBC,IAAI,KAAiC;qCACnC,IAAI,KAAwD;kCAC/D,IAAI,KAAqC;sCACrC,IAAI,KAAoC;wBACX,EAAE;0BAO3B;yBACmB;wBACrB;8BAyCvB,aACA,YAC4B;AAC5B,QAAK,YAAY,YAAY,qBAAqB,aAAa,KAAK;AACpE,QAAK,aAAa,IAAI,YAAY,IAAI;IACpC,SAAS;KAAE,GAAG;KAAa,cAAc,YAAY;KAAqB;IAC1E;IACD,CAAC;AAEF,UAAO;IACL,IAAI,YAAY;IAChB,kBAAkB,YAAoB,QAAiB,aAAuC;AAC5F,YAAO,KAAK,gBAAgB;MAC1B,MAAM,YAAY;MAClB,aAAa;MACb;MACA;MACD,CAAC;;IAEJ,mBAAmB,YAAY,SAAS,QAAQ,aAAc;KAC5D,MAAM,MAAM,KAAK,iBAAiB,YAAY,QAAQ;AACtD,UAAK,gBAAgB;MACnB,MAAM,YAAY;MAClB,aAAa;MACb;MACA;MACD,CAAC;AACF,YAAO;;IAET,kBAAkB;AAChB,UAAK,sBAAsB,YAAY;;IAE1C;;gCAQsB,gBAAwE;AAC/F,QAAK,YAAY,YAAY,uBAAuB,aAAa,KAAK;AACtE,QAAK,aAAa,OAAO,YAAY,GAAG;;0BAyBvB,YAA0E;GAC3F,MAAM,KAAK,OAAO,YAAY;GAC9B,MAAM,cAAsC;IAC1C,GAAG;IACH;IACA,cAAc,YAAY;IAC3B;AACD,QAAK,YAAY,YAAY,iBAAiB,aAAa,KAAK;AAChE,QAAK,SAAS,IAAI,IAAI,YAAY;AAElC,UAAO,EACL,kBAAkB;AAChB,SAAK,YAAY,YAAY,mBAAmB;KAC9C;KACA,cAAc,YAAY;KAC1B,MAAM,YAAY;KACnB,CAAC;AACF,SAAK,SAAS,OAAO,GAAG;MAE3B;;2BA2BD,YACA,qBACA,YACgB;AAChB,OAAI,CAAC,cAAc,WAAW,MAAM,KAAK,GACvC,OAAM,IAAI,MAAM,iBAAiB;AAEnC,OAAI,KAAK,UAAU,IAAI,WAAW,CAChC,OAAM,IAAI,MAAM,mCAAmC,aAAa;GAGlE,MAAM,YAAY,OAAO,wBAAwB;GAEjD,MAAM,cAAuC,YACzC;IAAE,GAAG;IAAS,IAAI;IAAY,cAAc,YAAY;IAAkB,GAC1E;IACE,GAAG;IACH,IAAI;IACJ,cAAc,YAAY;IAC1B,YAAY;KACV,KAAK,oBAAoB;KACzB,QAAQ,oBAAoB,UAAU;KACtC,YAAY,oBAAoB;KAChC,SAAS,oBAAoB;KAC7B,MAAM,oBAAoB;KAC3B;IACF;AAEL,QAAK,YAAY,YAAY,kBAAkB,aAAa,KAAK;AAEjE,OAAI,WAAW;IACb,MAAM,UAAU;AAChB,SAAK,UAAU,IAAI,YAAY;KAC7B,SAAS;KACT,SAAS,OAAO,OAAO,aAAsB,YAAqB;MAChE,MAAM,gBAAgB,EACpB,QAAQ,IAAI,+BAA+B,OAC3C,QAAQ,IAAI,4BAA4B,aAAa,KAAK;MAE5D,MAAM,sEAA0C;MAEhD,MAAM,aAAa,YAAY;AAC7B,WAAI,eAAe;QACjB,MAAM,EAAE,MAAM,4DAAgC,OAAO,gBAAgB;AACrE,oDAAgB,wBAAwB;SACtC,oBAAoB;SACpB,yBAAyB;SAC1B,CAAC;;AAEJ,WAAI;QACF,MAAM,SAAS,MAAM,QAAQ,MAAM;AACnC,YAAI,eAAe;SACjB,MAAM,EAAE,MAAM,4DAAgC,QAAQ,gBAAgB;AACtE,qDAAgB,yBAAyB;UACvC,oBAAoB;UACpB,yBAAyB;UACzB,kBAAkB;UACnB,CAAC;;AAEJ,eAAO;gBACA,KAAK;AACZ,YAAI,eAAe;SAEjB,MAAM,EAAE,MAAM,4DACZ,EAAE,OAFW,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI,EAE5C,EACjB,gBACD;AACD,qDAAgB,yBAAyB;UACvC,oBAAoB;UACpB,yBAAyB;UACzB,kBAAkB;UACnB,CAAC;;AAEJ,cAAM;;;AAIV,0DAAe,EAAE;OACf,MAAM,2DAA+B,aAAa,QAAQ;AAE1D,cAAOC,2BAAQ,KAAK,0DACT,QAAQ,cAAc,EAAE,MAAMC,4BAAS,QAAQ,EAAE,YAAY,MAAM,YAAY,CAAC,CAC1F;;MAGH,MAAM,UAAU,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG;MACrD,MAAM,SAAS,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,MAAM,GAAG,GAAG;MACjE,MAAM,gBAAgBC,yBAAM,gBAAgB;OAAE;OAAS;OAAQ,YAAY;OAAG,CAAC;AAE/E,aAAOF,2BAAQ,KAAKE,yBAAM,QAAQF,2BAAQ,QAAQ,EAAE,cAAc,EAAE,YAAY,MAAM,YAAY,CAAC;;KAEtG,CAAC;SAEF,MAAK,UAAU,IAAI,YAAY,EAAE,SAAS,aAAa,CAAC;AAG1D,UAAO;IACL,IAAI;IACJ,kBAAkB;AAChB,UAAK,YAAY,YAAY,oBAAoB,EAAE,IAAI,YAAY,EAAE,KAAK;AAC1E,UAAK,UAAU,OAAO,WAAW;;IAEpC;;uBAkBa,OAAO,eAA4D;GACjF,MAAM,SAAS,MAAM,KAAK,QACxB;IAAE,aAAa;IAA4B,SAAS,EAAE,aAAa,YAAY;IAAE,CAClF;AAED,UAAO;IACL,QAAQ,IAAI,cAAc,KAAK,SAAS,OAAO,OAAO;IACtD,QAAQ,IAAI,cAAc,KAAK,SAAS,OAAO,OAAO;IACtD,WAAW,OAAO;IAClB,WAAW,OAAO;IACnB;;iBA0CO,OAAwB,YAAsD;GACtF,MAAM,EAAE,aAAa,SAAS,QAAQ,cAAc;GACpD,MAAM,mBAAmB,aAAa,KAAK;AAG3C,OAAI,QAAQ,SAAS,QAAQ;IAC3B,MAAM,6DAAiC;IACvC,MAAM,qDAAyB;AAC/B,SAAK,YAAY,YAAY,gBAAgB;KAC3C;KACA,MAAM;KACN;KACA;KACA;KACD,CAAC;AACF;;GAIF,MAAM,gBAAgB,OAAO,YAAY;GACzC,MAAM,6DAAiC;GACvC,MAAM,qDAAyB;AAE/B,UAAO,IAAI,SAAkB,SAAS,WAAW;IAC/C,MAAM,UAAU,iBAAiB;AAE/B,SADmB,KAAK,YAAY,IAAI,cAAc,EACtC;AACd,WAAK,YAAY,OAAO,cAAc;AACtC,aACE,IAAI,mBAAmB;OACrB,MAAM;OACN,SAAS,8BAA8B,iBAAiB;OACxD;OACD,CAAC,CACH;;OAEF,iBAAiB;AAEpB,SAAK,YAAY,IAAI,eAAe;KAClC,UAAU,WAAoB;AAC5B,mBAAa,QAAQ;AACrB,cAAQ,OAAO;;KAEjB,SAAS,UAAmB;AAC1B,mBAAa,QAAQ;AACrB,aAAO,MAAM;;KAEf;KACA;KACD,CAAC;AAEF,SAAK,YAAY,YAAY,gBAAgB;KAC3C;KACA;KACA,MAAM;KACN;KACA;KACA;KACD,CAAC;KACF;;uBAmDmB,YAAoB,WAAiC;AAC1E,QAAK,iBAAiB,eAAe,WAAW,IAAI,OAAO,IAAI,KAAK,OAAO,CAAC;AAC5E,QAAK,iBAAiB,eAAe,WAAW,IAAI,OAAO,IAAI,KAAK,OAAO,CAAC;AAC5E,QAAK,iBAAiB,kBAAkB,WAAW,IAAI,OAAO,OAAO,KAAK,OAAO,CAAC;AAClF,QAAK,iBAAiB,gBAAgB,WAAW,IAAI,OAAO,KAAK,KAAK,OAAO,CAAC;AAC9E,QAAK,iBAAiB,uBAAuB,WAAW,IAAI,OAAO,WAAW,KAAK,OAAO,CAAC;;kBAMlF,YAA2B;AACpC,QAAK,iBAAiB;AAEtB,QAAK,sBAAsB;AAG3B,mDAAoB;AAGpB,QAAK,uBAAuB;AAG5B,QAAK,MAAM,CAAC,KAAK,eAAe,KAAK,aAAa;AAChD,QAAI,WAAW,QACb,cAAa,WAAW,QAAQ;AAElC,eAAW,uBAAO,IAAI,MAAM,uBAAuB,CAAC;;AAEtD,QAAK,YAAY,OAAO;AAQxB,OAAI,KAAK,IAAI;AACX,SAAK,GAAG,oBAAoB;AAC5B,SAAK,GAAG,GAAG,eAAe,GAAG;AAC7B,QAAI;AACF,UAAK,GAAG,OAAO;YACT;AAGR,SAAK,KAAK;;AAGZ,QAAK,mBAAmB,eAAe;;AA9dvC,OAAK,aAAa,SAAS,cAAc,sBAAsB;AAC/D,OAAK,0BAA0B,SAAS,0BAA0B;AAClE,OAAK,sBAAsB,SAAS;AACpC,OAAK,qBAAqB;GACxB,GAAG;GACH,GAAG,SAAS;GACb;AAGD,uCAAS;GAAE,GAAG,SAAS;GAAM,aAAa,KAAK;GAAS,CAAC;AAEzD,OAAK,SAAS;;CAmXhB,AAAQ,yBAA+B;EACrC,MAAM,gBAAgB,KAAK,SAAS;EACpC,MAAM,WACJ,eAAe,YAAY,KAAK,gBAAgB,CAAC,iBAAiB,CAAC,UAAU,QAAQ,IAAI,MAAM,MAAM,IAAI,CAAC;AAE5G,OAAK,QAAQ;GACX,aAAa,gBAAgB;GAC7B,SAAS;IACP,SAAS;IACT,SAAS;IACT,MAAM,KAAK;IACX,IAAI,WAAW;IACf,KAAK,QAAQ;IACb,WAAW,QAAQ,IAAI,iBAAiB;IACxC,WAAW;KACT;KACA,cAAc,eAAe,gBAAgB,mBAAmB;KAChE,WAAW,eAAe,WAAW,MAAM,IAAI;KAC/C,mBAAmB,eAAe;KACnC;IACF;GACD,QAAQ,EAAE,MAAM,QAAQ;GACzB,CAAC;;CA+EJ,AAAQ,mBAAmB,OAAiC;AAC1D,MAAI,KAAK,oBAAoB,MAC3B,MAAK,kBAAkB;;CAI3B,AAAQ,UAAgB;AACtB,MAAI,KAAK,eACP;AAGF,OAAK,mBAAmB,aAAa;AACrC,OAAK,KAAK,IAAIG,aAAU,KAAK,SAAS,EAAE,SAAS,KAAK,SAAS,SAAS,CAAC;AACzE,OAAK,GAAG,GAAG,QAAQ,KAAK,aAAa,KAAK,KAAK,CAAC;AAChD,OAAK,GAAG,GAAG,SAAS,KAAK,cAAc,KAAK,KAAK,CAAC;AAClD,OAAK,GAAG,GAAG,SAAS,KAAK,cAAc,KAAK,KAAK,CAAC;;CAGpD,AAAQ,wBAA8B;AACpC,MAAI,KAAK,kBAAkB;AACzB,gBAAa,KAAK,iBAAiB;AACnC,QAAK,mBAAmB;;;CAI5B,AAAQ,oBAA0B;AAChC,MAAI,KAAK,eACP;EAGF,MAAM,EAAE,YAAY,gBAAgB,mBAAmB,YAAY,iBAAiB,KAAK;AAEzF,MAAI,eAAe,MAAM,KAAK,oBAAoB,YAAY;AAC5D,QAAK,mBAAmB,SAAS;AACjC,QAAK,SAAS,6BAA6B,WAAW,sBAAsB;AAC5E;;AAGF,MAAI,KAAK,iBACP;EAGF,MAAM,mBAAmB,iBAAiB,qBAAqB,KAAK;EACpE,MAAM,cAAc,KAAK,IAAI,kBAAkB,WAAW;EAC1D,MAAM,SAAS,cAAc,gBAAgB,IAAI,KAAK,QAAQ,GAAG;EACjE,MAAM,QAAQ,KAAK,MAAM,cAAc,OAAO;AAE9C,OAAK,mBAAmB,eAAe;AACvC,UAAQ,MAAM,yBAAyB,MAAM,cAAc,KAAK,mBAAmB,EAAE,MAAM;AAE3F,OAAK,mBAAmB,iBAAiB;AACvC,QAAK,mBAAmB;AACxB,QAAK;AACL,QAAK,SAAS;KACb,MAAM;;CAGX,AAAQ,cAAc,OAAoB;AACxC,OAAK,SAAS,mBAAmB,MAAM;;CAGzC,AAAQ,wBAA8B;AACpC,MAAI,CAAC,KAAK,2BAA2B,CAAC,KAAK,SACzC;EAGF,MAAM,uDAAkB;AACxB,MAAI,CAAC,OAAO;AACV,WAAQ,KACN,mIACD;AACD;;AAGF,mDAAqB,OAAO;GAC1B,UAAU,KAAK;GACf,YAAY,KAAK;GAClB,CAAC;;CAGJ,AAAQ,uBAA6B;AACnC,gDAAkB;;CAGpB,AAAQ,gBAAsB;AAC5B,OAAK,IAAI,oBAAoB;AAC7B,OAAK,IAAI,WAAW;AACpB,OAAK,KAAK;AAEV,OAAK,mBAAmB,eAAe;AACvC,OAAK,sBAAsB;AAC3B,OAAK,mBAAmB;;CAG1B,AAAQ,eAAqB;AAC3B,OAAK,uBAAuB;AAC5B,OAAK,mBAAmB;AACxB,OAAK,mBAAmB,YAAY;AAEpC,OAAK,IAAI,GAAG,WAAW,KAAK,UAAU,KAAK,KAAK,CAAC;AAEjD,OAAK,aAAa,SAAS,EAAE,cAAc;AACzC,QAAK,YAAY,YAAY,qBAAqB,SAAS,KAAK;IAChE;AACF,OAAK,UAAU,SAAS,EAAE,cAAc;AACtC,QAAK,YAAY,YAAY,kBAAkB,SAAS,KAAK;IAC7D;AACF,OAAK,SAAS,SAAS,YAAY;AACjC,QAAK,YAAY,YAAY,iBAAiB,SAAS,KAAK;IAC5D;EAGF,MAAM,UAAU,KAAK;AACrB,OAAK,iBAAiB,EAAE;AACxB,OAAK,MAAM,WAAW,SAAS;AAC7B,OACE,QAAQ,SAAS,YAAY,kBAC7B,OAAO,QAAQ,kBAAkB,YACjC,CAAC,KAAK,YAAY,IAAI,QAAQ,cAAc,CAE5C;AAEF,QAAK,eAAe,KAAK,UAAU,QAAQ,CAAC;;AAG9C,OAAK,wBAAwB;;CAG/B,AAAQ,SAAkB;AACxB,SAAO,KAAK,IAAI,eAAeA,aAAU;;CAG3C,AAAQ,eAAe,MAAoB;AACzC,MAAI,KAAK,MAAM,KAAK,QAAQ,CAC1B,KAAI;AACF,QAAK,GAAG,KAAK,OAAO,QAAQ;AAC1B,QAAI,IACF,MAAK,SAAS,0BAA0B,IAAI;KAE9C;WACK,OAAO;AACd,QAAK,SAAS,mCAAmC,MAAM;;;CAK7D,AAAQ,aAAa,aAA0B,SAAoE;EACjH,MAAM,EAAE,cAAc,GAAG,GAAG,SAAS;AACrC,MAAI,gBAAgB,YAAY,mBAAmB,UAAU,SAAS;GACpE,MAAM,EAAE,MAAM,aAAa,GAAG,gBAAgB;AAC9C,UAAO;IAAE,MAAM;IAAa,GAAG;IAAa,cAAc;IAAa;;AAEzE,MAAI,gBAAgB,YAAY,qBAAqB,UAAU,SAAS;GACtE,MAAM,EAAE,MAAM,aAAa,GAAG,gBAAgB;AAC9C,UAAO;IAAE,MAAM;IAAa,GAAG;IAAa,cAAc;IAAa;;AAEzE,MAAI,gBAAgB,YAAY,6BAA6B,UAAU,SAAS;GAC9E,MAAM,EAAE,MAAM,aAAa,GAAG,eAAe;AAC7C,UAAO;IAAE,MAAM;IAAa,GAAG;IAAY,cAAc;IAAa;;AAExE,SAAO;GAAE,MAAM;GAAa,GAAG;GAAM;;CAGvC,AAAQ,YAAY,aAA0B,SAA2C,eAAe,OAAa;EACnH,MAAM,cAAc,KAAK,aAAa,aAAa,QAAQ;AAC3D,MAAI,KAAK,QAAQ,CACf,MAAK,eAAe,KAAK,UAAU,YAAY,CAAC;WACvC,CAAC,aACV,MAAK,eAAe,KAAK,YAAY;;CAIzC,AAAQ,SAAS,SAAiB,OAAuB;EACvD,MAAM,oDAAwB;EAC9B,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,SAAS,GAAG;AAEjF,MAAI,WACF,YAAW,KAAK;GACd,gBAAgBC,sCAAe;GAC/B,MAAM,SAAS,UAAU,eAAe,KAAK,iBAAiB;GAC/D,CAAC;MAEF,SAAQ,MAAM,SAAS,WAAW,SAAS,GAAG;;CAIlD,AAAQ,mBAAmB,eAAuB,QAAiB,OAAsB;EACvF,MAAM,aAAa,KAAK,YAAY,IAAI,cAAc;AAEtD,MAAI,YAAY;AACd,OAAI,WAAW,QACb,cAAa,WAAW,QAAQ;AAElC,OAAI,MACF,YAAW,OAAO,KAAK,kBAAkB,OAAO,WAAW,YAAY,CAAC;OAExE,YAAW,QAAQ,OAAO;;AAI9B,OAAK,YAAY,OAAO,cAAc;;;;;;;;;CAUxC,AAAQ,kBAAkB,OAAgB,aAA6B;AACrE,MAAI,iBAAiB,MACnB,QAAO;AAET,MAAI,YAAY,MAAM,CACpB,QAAO,IAAI,mBAAmB;GAC5B,MAAM,MAAM;GACZ,SAAS,MAAM;GACf;GACA,YAAY,MAAM;GACnB,CAAC;AAUJ,SAAO,IAAI,mBAAmB;GAC5B,MAAM;GACN,SALA,OAAO,UAAU,WACb,QACC,KAAK,UAAU,MAAM,IAAI,OAAO,MAAM;GAI3C;GACD,CAAC;;CAGJ,AAAQ,oBAAoB,OAAyB;AACnD,MAAI,aAAa,MAAM,CACrB,QAAO,MAAM,cAAc,SACvB,IAAI,cAAc,KAAK,SAAS,MAAM,GACtC,IAAI,cAAc,KAAK,SAAS,MAAM;AAE5C,MAAI,MAAM,QAAQ,MAAM,CACtB,QAAO,MAAM,KAAK,SAAS,KAAK,oBAAoB,KAAK,CAAC;AAE5D,MAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;GAC/C,MAAM,MAA+B,EAAE;AACvC,QAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,MAAiC,CACnE,KAAI,KAAK,KAAK,oBAAoB,EAAE;AAEtC,UAAO;;AAET,SAAO;;CAGT,MAAc,iBACZ,eACA,aACA,OACA,aACA,SACkB;EAClB,MAAM,KAAK,KAAK,UAAU,IAAI,YAAY;EAC1C,MAAM,8EAAkD,IAAI;EAC5D,MAAM,sEAA0C,IAAI;EAEpD,MAAM,gBAAgB,KAAK,oBAAoB,MAAM;AAErD,MAAI,IAAI,SAAS;AACf,OAAI,CAAC,eAAe;AAClB,QAAI;AACF,WAAM,GAAG,QAAQ,eAAe,aAAa,QAAQ;aAC9C,OAAO;AACd,UAAK,SAAS,2BAA2B,eAAe,MAAM;;AAEhE;;AAGF,OAAI;IACF,MAAM,SAAS,MAAM,GAAG,QAAQ,eAAe,aAAa,QAAQ;AACpE,SAAK,YAAY,YAAY,kBAAkB;KAC7C;KACA;KACA;KACA,aAAa,wBAAwB;KACrC,SAAS,oBAAoB;KAC9B,CAAC;YACK,OAAO;IACd,MAAM,UAAU,iBAAiB;AACjC,SAAK,YAAY,YAAY,kBAAkB;KAC7C;KACA;KACA,OAAO;MACL,MAAM;MACN,SAAS,UAAU,MAAM,UAAU,OAAO,MAAM;MAChD,YAAY,UAAU,MAAM,QAAQ;MACrC;KACD,aAAa,wBAAwB;KACrC,SAAS,oBAAoB;KAC9B,CAAC;;SAEC;GACL,MAAM,YAAY,KAAK,2BAA2B;GAClD,MAAM,eAAe,KAAK,2DAA2D;AACrF,OAAI,cACF,MAAK,YAAY,YAAY,kBAAkB;IAC7C;IACA;IACA,OAAO;KAAE,MAAM;KAAW,SAAS;KAAc;IACjD;IACA;IACD,CAAC;;;CAKR,MAAc,kBAAkB,SAAyH;EACvJ,MAAM,EAAE,cAAc,IAAI,aAAa,QAAQ,aAAa;EAC5D,MAAM,kBAAkB,KAAK,aAAa,IAAI,aAAa;AAE3D,MAAI,gBACF,KAAI;AACF,SAAM,gBAAgB,QAAQ,gBAAgB;IAAE;IAAI;IAAa;IAAQ;IAAU,CAAC;AACpF,QAAK,YAAY,YAAY,2BAA2B;IACtD;IACA,cAAc,YAAY;IAC1B,MAAM;IACN;IACD,CAAC;WACK,OAAO;AACd,QAAK,YAAY,YAAY,2BAA2B;IACtD;IACA,cAAc,YAAY;IAC1B,MAAM;IACN;IACA,OAAO;KAAE,MAAM;KAA+B,SAAU,MAAgB;KAAS;IAClF,CAAC;;MAGJ,MAAK,YAAY,YAAY,2BAA2B;GACtD;GACA,cAAc,YAAY;GAC1B,MAAM;GACN;GACA,OAAO;IAAE,MAAM;IAA0B,SAAS;IAA0B;GAC7E,CAAC;;CAIN,AAAQ,4BACN,SACM;AACN,MAAI,CAAC,QAAQ,MAAO;EACpB,MAAM,cAAc,QAAQ,gBAAgB,QAAQ,QAAQ;AAC5D,UAAQ,MACN,0CAA0C,QAAQ,GAAG,KAAK,YAAY,KAAK,QAAQ,MAAM,UAC1F;;CAGH,AAAQ,UAAU,eAA2B;EAC3C,IAAI;EACJ,IAAI;AAEJ,MAAI;GACF,MAAM,SAAS,KAAK,MAAM,cAAc,UAAU,CAAC;AACnD,aAAU,OAAO;GACjB,MAAM,EAAE,MAAM,GAAG,GAAG,SAAS;AAC7B,aAAU;WACH,OAAO;AACd,QAAK,SAAS,oCAAoC,MAAM;AACxD;;AAGF,MAAI,YAAY,YAAY,kBAAkB;GAC5C,MAAM,EAAE,eAAe,QAAQ,UAAU;AACzC,QAAK,mBAAmB,eAAe,QAAQ,MAAM;aAC5C,YAAY,YAAY,gBAAgB;GACjD,MAAM,EAAE,eAAe,aAAa,MAAM,aAAa,YAAY;AACnE,QAAK,iBAAiB,eAAe,aAAa,MAAM,aAAa,QAAQ;aACpE,YAAY,YAAY,gBACjC,MAAK,kBAAkB,QAA0H;WACxI,YAAY,YAAY,0BACjC,MAAK,4BACH,QACD;WACQ,YAAY,YAAY,kBAAkB;GACnD,MAAM,EAAE,cAAc;AACtB,QAAK,WAAW;AAChB,WAAQ,MAAM,oCAAoC,UAAU;AAC5D,QAAK,uBAAuB;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BlC,MAAa,gBAAgB;CAS3B,UAAU,UAAgD;EAAE,MAAM;EAAW,GAAG;EAAM;CAKtF,aAAgC,EAAE,MAAM,QAAQ;CACjD;;;;;;;;;;;;;;;;;;AAmBD,MAAa,kBAAkB,SAAiB,YAAgC,IAAI,IAAI,SAAS,QAAQ"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts","../src/iii.ts","../src/utils.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts","../src/iii.ts","../src/utils.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts","../src/iii.ts","../src/utils.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts","../src/iii.ts","../src/utils.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { Readable, Writable } from "node:stream";
3
3
  import { WebSocket } from "ws";
4
- import { context, trace } from "@opentelemetry/api";
4
+ import { SpanKind, context, trace } from "@opentelemetry/api";
5
5
  import * as os from "node:os";
6
- import { Logger, SeverityNumber, SpanKind, extractContext, getLogger, getMeter, getTracer, initOtel, injectBaggage, injectTraceparent, recordSpanEvent, redactAndTruncate, registerWorkerGauges, resolveMaxBytesFromEnv, shutdownOtel, stopWorkerGauges, withSpan } from "@iii-dev/observability";
6
+ import { Logger, SeverityNumber, extractContext, getLogger, initOtel, injectBaggage, injectTraceparent, recordSpanEvent, redactAndTruncate, registerWorkerGauges, resolveMaxBytesFromEnv, shutdownOtel, stopWorkerGauges, withSpan } from "@iii-dev/observability";
7
+ import { getMeter, getTracer } from "@iii-dev/observability/internal";
7
8
  import * as fs from "node:fs";
8
9
  import * as path from "node:path";
9
10
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/iii-types.ts","../src/utils.ts","../src/iii.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","/**\n * Typed error surfaced when an invocation dispatched over the SDK fails — RBAC\n * rejection (FORBIDDEN), handler-level failure, or a timeout waiting for the\n * engine to respond. Wraps the wire `ErrorBody` shape plus the `function_id`\n * that was targeted, so callers get a single error type across all failure\n * modes and can disambiguate via `err.code`.\n *\n * Before this existed, rejection values were plain `ErrorBody`-shaped objects,\n * which printed as `[object Object]` when stringified — leaving developers to\n * grep through SDK source to figure out what tripped. The class name, `code`\n * prefix in the message, and `function_id` field together make a rejection\n * self-describing.\n */\nexport type IIIInvocationErrorInit = {\n code: string\n message: string\n function_id?: string\n stacktrace?: string\n}\n\nexport class IIIInvocationError extends Error {\n public readonly code: string\n public readonly function_id?: string\n public readonly stacktrace?: string\n\n constructor(init: IIIInvocationErrorInit) {\n super(`${init.code}: ${init.message}`)\n this.name = 'IIIInvocationError'\n this.code = init.code\n this.function_id = init.function_id\n this.stacktrace = init.stacktrace\n }\n}\n\n/**\n * True when `value` looks like the wire `ErrorBody` the engine sends in\n * `InvocationResult.error`: `{ code: string, message: string, stacktrace?: string }`.\n * Used to distinguish an engine rejection (which we wrap in\n * {@link IIIInvocationError}) from a JS `Error` thrown elsewhere.\n */\nexport function isErrorBody(value: unknown): value is {\n code: string\n message: string\n stacktrace?: string\n} {\n if (typeof value !== 'object' || value === null) return false\n const v = value as { code?: unknown; message?: unknown; stacktrace?: unknown }\n return (\n typeof v.code === 'string' &&\n typeof v.message === 'string' &&\n (v.stacktrace === undefined || typeof v.stacktrace === 'string')\n )\n}\n","/**\n * Constants for the III module.\n */\n\n/**\n * Engine function paths for internal operations.\n *\n * Naming note: `LIST_TRIGGERS` / `INFO_TRIGGERS` cover trigger TYPES\n * (templates). `LIST_REGISTERED_TRIGGERS` / `INFO_REGISTERED_TRIGGERS`\n * cover trigger INSTANCES (subscriber rows). The old\n * `engine::trigger-types::list` builtin has been removed and is now\n * served by `engine::triggers::list`.\n */\nexport const EngineFunctions = {\n LIST_FUNCTIONS: 'engine::functions::list',\n INFO_FUNCTIONS: 'engine::functions::info',\n LIST_WORKERS: 'engine::workers::list',\n INFO_WORKERS: 'engine::workers::info',\n LIST_TRIGGERS: 'engine::triggers::list',\n INFO_TRIGGERS: 'engine::triggers::info',\n LIST_REGISTERED_TRIGGERS: 'engine::registered-triggers::list',\n INFO_REGISTERED_TRIGGERS: 'engine::registered-triggers::info',\n REGISTER_WORKER: 'engine::workers::register',\n} as const\n\n/** Engine trigger types */\nexport const EngineTriggers = {\n FUNCTIONS_AVAILABLE: 'engine::functions-available',\n LOG: 'log',\n} as const\n\n/** Log function paths */\nexport const LogFunctions = {\n INFO: 'engine::log::info',\n WARN: 'engine::log::warn',\n ERROR: 'engine::log::error',\n DEBUG: 'engine::log::debug',\n} as const\n\n/** Connection state for the III WebSocket */\nexport type IIIConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface IIIReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Default invocation timeout in milliseconds */\nexport const DEFAULT_INVOCATION_TIMEOUT_MS = 30000\n","export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n message_type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n message_type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n message_type: MessageType.UnregisterTrigger\n id: string\n type?: string\n}\n\nexport type ErrorBody = {\n code: string\n message: string\n stacktrace?: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n message_type: MessageType.TriggerRegistrationResult\n id: string\n type: string\n function_id: string\n error?: ErrorBody\n}\n\nexport type RegisterTriggerMessage = {\n message_type: MessageType.RegisterTrigger\n id: string\n type: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n}\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\nexport type RegisterFunctionFormat = {\n /**\n * The name of the parameter\n */\n name?: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map' | 'integer'\n /**\n * The body of the parameter (for objects)\n */\n properties?: Record<string, unknown>\n /**\n * The items of the parameter (for arrays)\n */\n items?: unknown\n /**\n * Whether the parameter is required\n */\n required?: string[]\n [key: string]: unknown\n}\n\nexport type RegisterFunctionMessage = {\n message_type: MessageType.RegisterFunction\n /**\n * The path of the function (use :: for namespacing, e.g. external::my_lambda)\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n /**\n * HTTP invocation config for external HTTP functions (Lambda, Cloudflare Workers, etc.)\n */\n invocation?: HttpInvocationConfig\n}\n\n/**\n * Routing action for {@link TriggerRequest}. Determines how the engine\n * handles the invocation.\n *\n * - `enqueue` -- Routes through a named queue for async processing.\n * - `void` -- Fire-and-forget, no response.\n */\nexport type TriggerAction = { type: 'enqueue'; queue: string } | { type: 'void' }\n\n/**\n * Input passed to the RBAC auth function during WebSocket upgrade.\n * Contains the HTTP headers, query parameters, and client IP from the\n * connecting worker's upgrade request.\n */\nexport type AuthInput = {\n /** HTTP headers from the WebSocket upgrade request. */\n headers: Record<string, string>\n /** Query parameters from the upgrade URL. Each key maps to an array of values to support repeated keys. */\n query_params: Record<string, string[]>\n /** IP address of the connecting client. */\n ip_address: string\n}\n\n/**\n * Return value from the RBAC auth function. Controls which functions the\n * authenticated worker can invoke and what context is forwarded to the\n * middleware.\n */\nexport type AuthResult = {\n /** Additional function IDs to allow beyond the `expose_functions` config. */\n allowed_functions: string[]\n /** Function IDs to deny even if they match `expose_functions`. Takes precedence over allowed. */\n forbidden_functions: string[]\n /** Trigger type IDs the worker may register triggers for. When omitted, all types are allowed. */\n allowed_trigger_types?: string[]\n /** Whether the worker may register new trigger types. */\n allow_trigger_type_registration: boolean\n /** Whether the worker may register new functions. Defaults to `true` if omitted. */\n allow_function_registration?: boolean\n /** Arbitrary context forwarded to the middleware function on every invocation. */\n context: Record<string, unknown>\n /** Optional prefix applied to all function IDs registered by this worker. */\n function_registration_prefix?: string\n}\n\n/**\n * Input passed to the RBAC middleware function on every function invocation\n * through the RBAC port. The middleware can inspect, modify, or reject the\n * call before it reaches the target function.\n */\nexport type MiddlewareFunctionInput = {\n /** ID of the function being invoked. */\n function_id: string\n /** Payload sent by the caller. */\n payload: Record<string, unknown>\n /** Routing action, if any. */\n action?: TriggerAction\n /** Auth context returned by the auth function for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Input passed to the `on_trigger_type_registration_function_id` hook\n * when a worker attempts to register a new trigger type through the RBAC port.\n * Return an {@link OnTriggerTypeRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerTypeRegistrationInput = {\n /** ID of the trigger type being registered. */\n trigger_type_id: string\n /** Human-readable description of the trigger type. */\n description: string\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_type_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerTypeRegistrationResult = {\n /** Mapped trigger type ID. */\n trigger_type_id?: string\n /** Mapped description. */\n description?: string\n}\n\n/**\n * Input passed to the `on_trigger_registration_function_id` hook\n * when a worker attempts to register a trigger through the RBAC port.\n * Return an {@link OnTriggerRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerRegistrationInput = {\n /** ID of the trigger being registered. */\n trigger_id: string\n /** Trigger type identifier. */\n trigger_type: string\n /** ID of the function this trigger is bound to. */\n function_id: string\n /** Trigger-specific configuration. */\n config: unknown\n /** Arbitrary metadata attached to the trigger. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerRegistrationResult = {\n /** Mapped trigger ID. */\n trigger_id?: string\n /** Mapped trigger type. */\n trigger_type?: string\n /** Mapped function ID. */\n function_id?: string\n /** Mapped trigger configuration. */\n config?: unknown\n}\n\n/**\n * Input passed to the `on_function_registration_function_id` hook\n * when a worker attempts to register a function through the RBAC port.\n * Return an {@link OnFunctionRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnFunctionRegistrationInput = {\n /** ID of the function being registered. */\n function_id: string\n /** Human-readable description of the function. */\n description?: string\n /** Arbitrary metadata attached to the function. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_function_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnFunctionRegistrationResult = {\n /** Mapped function ID. */\n function_id?: string\n /** Mapped description. */\n description?: string\n /** Mapped metadata. */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Result returned when a function is invoked with `TriggerAction.Enqueue`.\n */\nexport type EnqueueResult = {\n /** Unique receipt ID for the enqueued message. */\n messageReceiptId: string\n}\n\n/**\n * Request object passed to {@link ISdk.trigger}.\n *\n * @typeParam TInput - Type of the payload.\n */\nexport type TriggerRequest<TInput = unknown> = {\n /** ID of the function to invoke. */\n function_id: string\n /** Payload to pass to the function. */\n payload: TInput\n /** Routing action. Omit for synchronous request/response. */\n action?: TriggerAction\n /** Override the default invocation timeout in milliseconds. */\n timeoutMs?: number\n}\n\nexport type InvokeFunctionMessage = {\n message_type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n /**\n * Trigger action for queue routing or fire-and-forget\n */\n action?: TriggerAction\n}\n\nexport type InvocationResultMessage = {\n message_type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: unknown\n error?: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type WorkerRegisteredMessage = {\n message_type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n message_type: MessageType.UnregisterFunction\n id: string\n}\n\n/**\n * Serializable reference to one end of a streaming channel. Can be included\n * in invocation payloads to pass channel endpoints between workers.\n */\nexport type StreamChannelRef = {\n /** Unique channel identifier. */\n channel_id: string\n /** Access key for authentication. */\n access_key: string\n /** Whether this ref is for reading or writing. */\n direction: 'read' | 'write'\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n","import { context, trace } from '@opentelemetry/api'\nimport { createRequire } from 'node:module'\nimport * as os from 'node:os'\nimport { type Data, WebSocket } from 'ws'\nimport { ChannelReader, ChannelWriter } from './channels'\nimport { IIIInvocationError, isErrorBody } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n} from './iii-constants'\nimport {\n type HttpInvocationConfig,\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerAction as TriggerActionType,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/observability'\nimport type { IStream } from './stream'\nimport { detectProjectName } from './utils'\nimport {\n extractContext,\n getLogger,\n getMeter,\n getTracer,\n initOtel,\n injectBaggage,\n injectTraceparent,\n type OtelConfig,\n recordSpanEvent,\n redactAndTruncate,\n resolveMaxBytesFromEnv,\n SeverityNumber,\n shutdownOtel,\n SpanKind,\n withSpan,\n} from '@iii-dev/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n Invocation,\n ISdk,\n RegisterFunctionOptions,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n TriggerTypeRef,\n} from './types'\nimport { isChannelRef } from './utils'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** @internal */\nexport type TelemetryOptions = {\n language?: string\n project_name?: string\n framework?: string\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const iii = registerWorker('ws://localhost:49134', {\n * workerName: 'my-worker',\n * invocationTimeoutMs: 10000,\n * reconnectionConfig: { maxRetries: 5 },\n * })\n * ```\n */\nexport type InitOptions = {\n /** Display name for this worker. Defaults to `hostname:pid`. */\n workerName?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `trigger()` in milliseconds. Defaults to `30000`. */\n invocationTimeoutMs?: number\n /**\n * WebSocket reconnection behavior.\n *\n * @see {@link IIIReconnectionConfig} for available fields and defaults.\n */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\n /**\n * OpenTelemetry configuration. OTel is initialized automatically by default.\n * Set `{ enabled: false }` or env `OTEL_ENABLED=false/0/no/off` to disable.\n * The `engineWsUrl` is set automatically from the III address.\n */\n otel?: Omit<OtelConfig, 'engineWsUrl'>\n /** Custom HTTP headers sent during the WebSocket handshake. */\n headers?: Record<string, string>\n /** @internal */\n telemetry?: TelemetryOptions\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private invocations = new Map<string, Invocation & { timeout?: NodeJS.Timeout }>()\n private triggers = new Map<string, RegisterTriggerMessage>()\n private triggerTypes = new Map<string, RemoteTriggerTypeData>()\n private messagesToSend: Record<string, unknown>[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry (enabled by default, opt-out via config or env)\n initOtel({ ...options?.otel, engineWsUrl: this.address })\n\n this.connect()\n }\n\n /**\n * Registers a custom trigger type with the engine. A trigger type defines\n * how external events (HTTP, cron, queue, etc.) map to function invocations.\n *\n * @param triggerType - Trigger type registration input.\n * @param triggerType.id - Unique trigger type identifier.\n * @param triggerType.description - Human-readable description.\n * @param handler - Handler with `registerTrigger` / `unregisterTrigger` callbacks.\n *\n * @example\n * ```typescript\n * iii.registerTriggerType(\n * { id: 'my-trigger', description: 'Custom trigger' },\n * {\n * async registerTrigger({ id, function_id, config }) { },\n * async unregisterTrigger({ id, function_id, config }) { },\n * },\n * )\n * ```\n */\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>,\n handler: TriggerHandler<TConfig>,\n ): TriggerTypeRef<TConfig> => {\n this.sendMessage(MessageType.RegisterTriggerType, triggerType, true)\n this.triggerTypes.set(triggerType.id, {\n message: { ...triggerType, message_type: MessageType.RegisterTriggerType },\n handler,\n })\n\n return {\n id: triggerType.id,\n registerTrigger: (functionId: string, config: TConfig, metadata?: Record<string, unknown>) => {\n return this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n },\n registerFunction: (functionId, handler, config, metadata?) => {\n const ref = this.registerFunction(functionId, handler)\n this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n return ref\n },\n unregister: () => {\n this.unregisterTriggerType(triggerType)\n },\n }\n }\n\n /**\n * Unregisters a previously registered trigger type.\n *\n * @param triggerType - The trigger type to unregister (must match the `id` used during registration).\n */\n unregisterTriggerType = (triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>): void => {\n this.sendMessage(MessageType.UnregisterTriggerType, triggerType, true)\n this.triggerTypes.delete(triggerType.id)\n }\n\n /**\n * Binds a trigger configuration to a registered function. When the trigger\n * fires, the engine invokes the target function.\n *\n * @param trigger - Trigger registration input.\n * @param trigger.type - Trigger type (e.g. `http`, `durable:subscriber`, `cron`).\n * @param trigger.function_id - ID of the function to invoke.\n * @param trigger.config - Trigger-specific configuration.\n * @returns A {@link Trigger} handle with an `unregister()` method.\n *\n * @example\n * ```typescript\n * const trigger = iii.registerTrigger({\n * type: 'http',\n * function_id: 'greet',\n * config: { api_path: '/greet', http_method: 'GET' },\n * })\n *\n * // Later...\n * trigger.unregister()\n * ```\n */\n registerTrigger = (trigger: Omit<RegisterTriggerMessage, 'message_type' | 'id'>): Trigger => {\n const id = crypto.randomUUID()\n const fullTrigger: RegisterTriggerMessage = {\n ...trigger,\n id,\n message_type: MessageType.RegisterTrigger,\n }\n this.sendMessage(MessageType.RegisterTrigger, fullTrigger, true)\n this.triggers.set(id, fullTrigger)\n\n return {\n unregister: () => {\n this.sendMessage(MessageType.UnregisterTrigger, {\n id,\n message_type: MessageType.UnregisterTrigger,\n type: fullTrigger.type,\n })\n this.triggers.delete(id)\n },\n }\n }\n\n /**\n * Registers a function with the engine. The `functionId` is the unique identifier\n * used by triggers and invocations.\n *\n * Pass a handler for local execution, or an {@link HttpInvocationConfig}\n * for HTTP-invoked functions (Lambda, Cloudflare Workers, etc.).\n *\n * @param functionId - Unique function identifier.\n * @param handlerOrInvocation - Async handler or HTTP invocation config.\n * @param options - Optional function registration options (description, request/response formats, metadata).\n * @returns A {@link FunctionRef} with `id` and `unregister()`.\n *\n * @example\n * ```typescript\n * const fn = iii.registerFunction(\n * 'greet',\n * async (input: { name: string }) => {\n * return { message: `Hello, ${input.name}!` }\n * },\n * { description: 'Greets a user' },\n * )\n * ```\n */\n registerFunction = (\n functionId: string,\n handlerOrInvocation: RemoteFunctionHandler | HttpInvocationConfig,\n options?: RegisterFunctionOptions,\n ): FunctionRef => {\n if (!functionId || functionId.trim() === '') {\n throw new Error('id is required')\n }\n if (this.functions.has(functionId)) {\n throw new Error(`function id already registered: ${functionId}`)\n }\n\n const isHandler = typeof handlerOrInvocation === 'function'\n\n const fullMessage: RegisterFunctionMessage = isHandler\n ? { ...options, id: functionId, message_type: MessageType.RegisterFunction }\n : {\n ...options,\n id: functionId,\n message_type: MessageType.RegisterFunction,\n invocation: {\n url: handlerOrInvocation.url,\n method: handlerOrInvocation.method ?? 'POST',\n timeout_ms: handlerOrInvocation.timeout_ms,\n headers: handlerOrInvocation.headers,\n auth: handlerOrInvocation.auth,\n },\n }\n\n this.sendMessage(MessageType.RegisterFunction, fullMessage, true)\n\n if (isHandler) {\n const handler = handlerOrInvocation as RemoteFunctionHandler\n this.functions.set(functionId, {\n message: fullMessage,\n handler: async (input, traceparent?: string, baggage?: string) => {\n const tracePayloads = !(\n process.env.III_DISABLE_TRACE_PAYLOADS === '1' ||\n process.env.III_DISABLE_TRACE_PAYLOADS?.toLowerCase() === 'true'\n )\n const payloadMaxBytes = resolveMaxBytesFromEnv()\n\n const runHandler = async () => {\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(input, payloadMaxBytes)\n recordSpanEvent('iii.invocation.input', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n })\n }\n try {\n const result = await handler(input)\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(result, payloadMaxBytes)\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': true,\n })\n }\n return result\n } catch (err) {\n if (tracePayloads) {\n const errMsg = err instanceof Error ? err.message : String(err)\n const { json, truncated } = redactAndTruncate(\n { error: errMsg },\n payloadMaxBytes,\n )\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': false,\n })\n }\n throw err\n }\n }\n\n if (getTracer()) {\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`call ${functionId}`, { kind: SpanKind.SERVER }, async () => await runHandler()),\n )\n }\n\n const traceId = crypto.randomUUID().replace(/-/g, '')\n const spanId = crypto.randomUUID().replace(/-/g, '').slice(0, 16)\n const syntheticSpan = trace.wrapSpanContext({ traceId, spanId, traceFlags: 1 })\n\n return context.with(trace.setSpan(context.active(), syntheticSpan), async () => await runHandler())\n },\n })\n } else {\n this.functions.set(functionId, { message: fullMessage })\n }\n\n return {\n id: functionId,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: functionId }, true)\n this.functions.delete(functionId)\n },\n }\n }\n\n /**\n * Creates a streaming channel pair for worker-to-worker data transfer.\n * Returns a {@link Channel} with a local writer/reader and serializable refs\n * that can be passed as fields in invocation data to other functions.\n *\n * @param bufferSize - Optional buffer size for the channel (default: 64).\n * @returns A {@link Channel} with `writer`, `reader`, and their serializable refs.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.close()\n * ```\n */\n createChannel = async (bufferSize?: number): Promise<import('./types').Channel> => {\n const result = await this.trigger<{ buffer_size?: number }, { writer: StreamChannelRef; reader: StreamChannelRef }>(\n { function_id: 'engine::channels::create', payload: { buffer_size: bufferSize } },\n )\n\n return {\n writer: new ChannelWriter(this.address, result.writer),\n reader: new ChannelReader(this.address, result.reader),\n writerRef: result.writer,\n readerRef: result.reader,\n }\n }\n\n /**\n * Invokes a remote function. The routing behavior and return type depend\n * on the `action` field of the request.\n *\n * | `action` | Behavior | Return type |\n * |-------------------------------|----------------------------------------------------|----------------------- |\n * | _(none)_ | Synchronous -- waits for the function to return | `Promise<TOutput>` |\n * | `TriggerAction.Enqueue(...)` | Async via named queue -- engine acknowledges enqueue | `Promise<EnqueueResult>` |\n * | `TriggerAction.Void()` | Fire-and-forget -- no response | `Promise<undefined>` |\n *\n * @param request - The trigger request.\n * @param request.function_id - ID of the function to invoke.\n * @param request.payload - Payload to pass to the function.\n * @param request.action - Routing action. Omit for synchronous request/response.\n * @param request.timeoutMs - Override the default invocation timeout.\n * @returns The result of the function invocation.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Synchronous\n * const result = await iii.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await iii.trigger({\n * function_id: 'payments::charge',\n * payload: { orderId: '123', amount: 49.99 },\n * action: TriggerAction.Enqueue({ queue: 'payment' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n trigger = async <TInput, TOutput>(request: TriggerRequest<TInput>): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs } = request\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\n\n // Void is fire-and-forget — no invocation_id, no response\n if (action?.type === 'void') {\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, {\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n return undefined as TOutput\n }\n\n // Enqueue and default: send invocation_id, await response\n const invocation_id = crypto.randomUUID()\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n\n return new Promise<TOutput>((resolve, reject) => {\n const timeout = setTimeout(() => {\n const invocation = this.invocations.get(invocation_id)\n if (invocation) {\n this.invocations.delete(invocation_id)\n reject(\n new IIIInvocationError({\n code: 'TIMEOUT',\n message: `invocation timed out after ${effectiveTimeout}ms`,\n function_id,\n }),\n )\n }\n }, effectiveTimeout)\n\n this.invocations.set(invocation_id, {\n resolve: (result: TOutput) => {\n clearTimeout(timeout)\n resolve(result)\n },\n reject: (error: unknown) => {\n clearTimeout(timeout)\n reject(error)\n },\n function_id,\n timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n })\n }\n\n private registerWorkerMetadata(): void {\n const telemetryOpts = this.options?.telemetry\n const language =\n telemetryOpts?.language ?? Intl.DateTimeFormat().resolvedOptions().locale ?? process.env.LANG?.split('.')[0]\n\n this.trigger({\n function_id: EngineFunctions.REGISTER_WORKER,\n payload: {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n telemetry: {\n language,\n project_name: telemetryOpts?.project_name ?? detectProjectName(),\n framework: telemetryOpts?.framework?.trim() || 'iii-node',\n amplitude_api_key: telemetryOpts?.amplitude_api_key,\n },\n },\n action: { type: 'void' },\n })\n }\n\n /**\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name.\n *\n * Registers 5 of the 6 `IStream` methods (`get`, `set`, `delete`, `list`,\n * `listGroups`). The `update` method is not registered -- atomic updates are\n * handled by the engine's built-in stream update logic.\n *\n * @param streamName - Name of the stream.\n * @param stream - Object implementing the {@link IStream} interface.\n *\n * @example\n * ```typescript\n * iii.createStream('my-stream', {\n * async get(input) { return null },\n * async set(input) { return null },\n * async delete(input) { return { old_value: undefined } },\n * async list(input) { return [] },\n * async listGroups(input) { return [] },\n * async update(input) { return null },\n * })\n * ```\n */\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction(`stream::get(${streamName})`, stream.get.bind(stream))\n this.registerFunction(`stream::set(${streamName})`, stream.set.bind(stream))\n this.registerFunction(`stream::delete(${streamName})`, stream.delete.bind(stream))\n this.registerFunction(`stream::list(${streamName})`, stream.list.bind(stream))\n this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream))\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket. Swallow any close-time errors (most commonly\n // \"WebSocket was closed before the connection was established\" —\n // emitted when `close()` fires while still in CONNECTING state\n // and there's no error listener). Without a catch-all listener,\n // that event becomes an unhandled exception because we remove\n // every listener right above the close call.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.close()\n } catch {\n // ignore — shutting down anyway\n }\n this.ws = undefined\n }\n\n this.setConnectionState('disconnected')\n }\n\n // private methods\n\n private setConnectionState(state: IIIConnectionState): void {\n if (this.connectionState !== state) {\n this.connectionState = state\n }\n }\n\n private connect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n this.setConnectionState('connecting')\n this.ws = new WebSocket(this.address, { headers: this.options?.headers })\n this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } = this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.functions.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterFunction, message, true)\n })\n this.triggers.forEach((trigger) => {\n this.sendMessage(MessageType.RegisterTrigger, trigger, true)\n })\n\n // Optimized: swap with empty array instead of splice\n const pending = this.messagesToSend\n this.messagesToSend = []\n for (const message of pending) {\n if (\n message.type === MessageType.InvokeFunction &&\n typeof message.invocation_id === 'string' &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, (err) => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private toWireFormat(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>): Record<string, unknown> {\n const { message_type: _, ...rest } = message as Record<string, unknown>\n if (messageType === MessageType.RegisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.UnregisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.TriggerRegistrationResult && 'type' in message) {\n const { type: triggerType, ...resultRest } = message as TriggerRegistrationResultMessage\n return { type: messageType, ...resultRest, trigger_type: triggerType }\n }\n return { type: messageType, ...rest } as Record<string, unknown>\n }\n\n private sendMessage(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>, skipIfClosed = false): void {\n const wireMessage = this.toWireFormat(messageType, message)\n if (this.isOpen()) {\n this.sendMessageRaw(JSON.stringify(wireMessage))\n } else if (!skipIfClosed) {\n this.messagesToSend.push(wireMessage)\n }\n }\n\n private logError(message: string, error?: unknown): void {\n const otelLogger = getLogger()\n const errorMessage = error instanceof Error ? error.message : String(error ?? '')\n\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.ERROR,\n body: `[iii] ${message}${errorMessage ? `: ${errorMessage}` : ''}`,\n })\n } else {\n console.error(`[iii] ${message}`, error ?? '')\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n if (error) {\n invocation.reject(this.toInvocationError(error, invocation.function_id))\n } else {\n invocation.resolve(result)\n }\n }\n\n this.invocations.delete(invocation_id)\n }\n\n /**\n * Wrap a wire-format `ErrorBody` in {@link IIIInvocationError} so callers get\n * a real `Error` with a readable `.message` and a typed `.code`. Pass-through\n * for values that are already `Error` subclasses. Everything else is wrapped\n * under an `UNKNOWN` code so `String(err) !== '[object Object]'` holds for\n * every rejection path.\n */\n private toInvocationError(error: unknown, function_id?: string): Error {\n if (error instanceof Error) {\n return error\n }\n if (isErrorBody(error)) {\n return new IIIInvocationError({\n code: error.code,\n message: error.message,\n function_id,\n stacktrace: error.stacktrace,\n })\n }\n // JSON.stringify(undefined) returns undefined (not \"undefined\"), which\n // would set message to the literal string \"undefined\" after type coercion\n // and leak an uninformative rejection. Fall back through String(error)\n // so every path produces a concrete, readable string.\n const message =\n typeof error === 'string'\n ? error\n : (JSON.stringify(error) ?? String(error))\n return new IIIInvocationError({\n code: 'UNKNOWN',\n message,\n function_id,\n })\n }\n\n private resolveChannelValue(value: unknown): unknown {\n if (isChannelRef(value)) {\n return value.direction === 'read'\n ? new ChannelReader(this.address, value)\n : new ChannelWriter(this.address, value)\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.resolveChannelValue(item))\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = this.resolveChannelValue(v)\n }\n return out\n }\n return value\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n const resolvedInput = this.resolveChannelValue(input) as TInput\n\n if (fn?.handler) {\n if (!invocation_id) {\n try {\n await fn.handler(resolvedInput, traceparent, baggage)\n } catch (error) {\n this.logError(`Error invoking function ${function_id}`, error)\n }\n return\n }\n\n try {\n const result = await fn.handler(resolvedInput, traceparent, baggage)\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n result,\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n } catch (error) {\n const isError = error instanceof Error\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: {\n code: 'invocation_failed',\n message: isError ? error.message : String(error),\n stacktrace: isError ? error.stack : undefined,\n },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n const errorCode = fn ? 'function_not_invokable' : 'function_not_found'\n const errorMessage = fn ? 'Function is HTTP-invoked and cannot be invoked locally' : 'Function not found'\n if (invocation_id) {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: errorCode, message: errorMessage },\n traceparent,\n baggage,\n })\n }\n }\n }\n\n private async onRegisterTrigger(message: { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> }) {\n const { trigger_type, id, function_id, config, metadata } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata })\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n })\n } catch (error) {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_registration_failed', message: (error as Error).message },\n })\n }\n } else {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_type_not_found', message: 'Trigger type not found' },\n })\n }\n }\n\n private onTriggerRegistrationResult(\n message: { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n ): void {\n if (!message.error) return\n const triggerType = message.trigger_type ?? message.type ?? ''\n console.error(\n `[iii] Trigger registration failed for \"${message.id}\" (${triggerType}): ${message.error.message}`,\n )\n }\n\n private onMessage(socketMessage: Data): void {\n let msgType: MessageType\n let message: Record<string, unknown>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as Record<string, unknown>\n msgType = parsed.type as MessageType\n const { type: _, ...rest } = parsed\n message = rest\n } catch (error) {\n this.logError('Failed to parse incoming message', error)\n return\n }\n\n if (msgType === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (msgType === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (msgType === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(message as { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> })\n } else if (msgType === MessageType.TriggerRegistrationResult) {\n this.onTriggerRegistrationResult(\n message as { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n )\n } else if (msgType === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link ISdk.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * iii.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notify',\n * payload: {},\n * action: TriggerAction.Void(),\n * })\n * ```\n */\nexport const TriggerAction = {\n /**\n * Routes the invocation through a named queue. The engine enqueues the job,\n * acknowledges the caller with `{ messageReceiptId }`, and processes it\n * asynchronously.\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }): TriggerActionType => ({ type: 'enqueue', ...opts }),\n /**\n * Fire-and-forget routing. The engine forwards the invocation without\n * waiting for a response or queuing the job.\n */\n Void: (): TriggerActionType => ({ type: 'void' }),\n} as const\n\n/**\n * Creates and returns a connected SDK instance. The WebSocket connection is\n * established automatically -- there is no separate `connect()` call.\n *\n * @param address - WebSocket URL of the III engine (e.g. `ws://localhost:49134`).\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link ISdk} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const iii = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/channels.ts","../src/errors.ts","../src/iii-constants.ts","../src/iii-types.ts","../src/utils.ts","../src/iii.ts"],"sourcesContent":["import { Readable, Writable } from 'node:stream'\nimport { WebSocket } from 'ws'\nimport type { StreamChannelRef } from './iii-types'\n\n/**\n * Write end of a streaming channel. Provides both a Node.js `Writable` stream\n * and a `sendMessage` method for sending structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.stream.end()\n *\n * // Or send text messages\n * channel.writer.sendMessage(JSON.stringify({ type: 'event', data: 'test' }))\n * channel.writer.close()\n * ```\n */\nexport class ChannelWriter {\n private static readonly FRAME_SIZE = 64 * 1024\n private ws: WebSocket | null = null\n private wsReady = false\n private readonly pendingMessages: {\n data: Buffer | string\n callback: (err?: Error | null) => void\n }[] = []\n /** Node.js Writable stream for binary data. */\n public readonly stream: Writable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'write')\n\n this.stream = new Writable({\n write: (chunk: Buffer, _encoding, callback) => {\n const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)\n this.sendChunked(buf, callback)\n },\n final: (callback) => {\n if (!this.ws) {\n callback()\n return\n }\n // Delay the close frame slightly to allow the TCP stack to flush\n // all buffered send() data. Without this, the close frame can arrive\n // at the engine before all data frames, causing data truncation.\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'stream_complete')\n }\n callback()\n }\n if (this.wsReady) {\n setTimeout(doClose, 10)\n } else {\n this.ws.on('open', () => setTimeout(doClose, 10))\n }\n },\n destroy: (err, callback) => {\n if (this.ws) this.ws.terminate()\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.ws) return\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n this.wsReady = true\n for (const { data, callback } of this.pendingMessages) {\n this.ws?.send(data, callback)\n }\n this.pendingMessages.length = 0\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n\n this.ws.on('close', () => {\n if (!this.stream.destroyed) {\n this.stream.destroy()\n }\n })\n }\n\n /** Send a text message through the channel. */\n sendMessage(msg: string): void {\n this.ensureConnected()\n this.sendRaw(msg, (err) => {\n if (err) this.stream.destroy(err)\n })\n }\n\n /** Close the channel writer. */\n close(): void {\n if (!this.ws) return\n const doClose = () => {\n if (this.ws) {\n this.ws.close(1000, 'channel_close')\n }\n }\n if (this.wsReady) {\n doClose()\n } else {\n this.ws.on('open', () => doClose())\n }\n }\n\n private sendChunked(data: Buffer, callback: (err?: Error | null) => void): void {\n let offset = 0\n const sendNext = (err?: Error | null): void => {\n if (err) {\n callback(err)\n return\n }\n\n if (offset >= data.length) {\n callback(null)\n return\n }\n\n const end = Math.min(offset + ChannelWriter.FRAME_SIZE, data.length)\n const part = data.subarray(offset, end)\n offset = end\n this.sendRaw(part, sendNext)\n }\n sendNext(null)\n }\n\n private sendRaw(data: Buffer | string, callback: (err?: Error | null) => void): void {\n this.ensureConnected()\n if (this.wsReady && this.ws) {\n this.ws.send(data, (err) => callback(err ?? null))\n } else {\n this.pendingMessages.push({ data, callback })\n }\n }\n}\n\n/**\n * Read end of a streaming channel. Provides both a Node.js `Readable` stream\n * for binary data and an `onMessage` callback for structured text messages.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n *\n * // Stream binary data\n * channel.reader.stream.on('data', (chunk) => console.log(chunk))\n *\n * // Or receive text messages\n * channel.reader.onMessage((msg) => console.log('Got:', msg))\n * ```\n */\nexport class ChannelReader {\n private ws: WebSocket | null = null\n private connected = false\n private readonly messageCallbacks: Array<(msg: string) => void> = []\n /** Node.js Readable stream for binary data. */\n public readonly stream: Readable\n private readonly url: string\n\n constructor(engineWsBase: string, ref: StreamChannelRef) {\n this.url = buildChannelUrl(engineWsBase, ref.channel_id, ref.access_key, 'read')\n\n const self = this\n this.stream = new Readable({\n read() {\n self.ensureConnected()\n if (self.ws) self.ws.resume()\n },\n destroy(err, callback) {\n if (self.ws && self.ws.readyState !== WebSocket.CLOSED) {\n self.ws.terminate()\n }\n self.ws = null\n callback(err)\n },\n })\n }\n\n private ensureConnected(): void {\n if (this.connected) return\n this.connected = true\n this.ws = new WebSocket(this.url)\n\n this.ws.on('open', () => {\n ;(this.ws as unknown as { binaryType: string }).binaryType = 'nodebuffer'\n })\n\n this.ws.on('message', (data: Buffer, isBinary: boolean) => {\n if (isBinary) {\n if (!this.stream.push(data)) {\n this.ws?.pause()\n }\n } else {\n const msg = data.toString('utf-8')\n for (const cb of this.messageCallbacks) {\n cb(msg)\n }\n }\n })\n\n this.ws.on('close', () => {\n this.ws = null\n if (!this.stream.destroyed) this.stream.push(null)\n })\n\n this.ws.on('error', (err) => {\n this.stream.destroy(err)\n })\n }\n\n /** Register a callback to receive text messages from the channel. */\n onMessage(callback: (msg: string) => void): void {\n this.messageCallbacks.push(callback)\n }\n\n async readAll(): Promise<Buffer> {\n this.ensureConnected()\n const chunks: Buffer[] = []\n\n for await (const chunk of this.stream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk))\n }\n\n return Buffer.concat(chunks)\n }\n\n close(): void {\n if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {\n this.ws.close(1000, 'channel_close')\n }\n }\n}\n\nfunction buildChannelUrl(\n engineWsBase: string,\n channelId: string,\n accessKey: string,\n direction: 'read' | 'write',\n): string {\n const base = engineWsBase.replace(/\\/$/, '')\n return `${base}/ws/channels/${channelId}?key=${encodeURIComponent(accessKey)}&dir=${direction}`\n}\n","/**\n * Typed error surfaced when an invocation dispatched over the SDK fails — RBAC\n * rejection (FORBIDDEN), handler-level failure, or a timeout waiting for the\n * engine to respond. Wraps the wire `ErrorBody` shape plus the `function_id`\n * that was targeted, so callers get a single error type across all failure\n * modes and can disambiguate via `err.code`.\n *\n * Before this existed, rejection values were plain `ErrorBody`-shaped objects,\n * which printed as `[object Object]` when stringified — leaving developers to\n * grep through SDK source to figure out what tripped. The class name, `code`\n * prefix in the message, and `function_id` field together make a rejection\n * self-describing.\n */\nexport type IIIInvocationErrorInit = {\n code: string\n message: string\n function_id?: string\n stacktrace?: string\n}\n\nexport class IIIInvocationError extends Error {\n public readonly code: string\n public readonly function_id?: string\n public readonly stacktrace?: string\n\n constructor(init: IIIInvocationErrorInit) {\n super(`${init.code}: ${init.message}`)\n this.name = 'IIIInvocationError'\n this.code = init.code\n this.function_id = init.function_id\n this.stacktrace = init.stacktrace\n }\n}\n\n/**\n * True when `value` looks like the wire `ErrorBody` the engine sends in\n * `InvocationResult.error`: `{ code: string, message: string, stacktrace?: string }`.\n * Used to distinguish an engine rejection (which we wrap in\n * {@link IIIInvocationError}) from a JS `Error` thrown elsewhere.\n */\nexport function isErrorBody(value: unknown): value is {\n code: string\n message: string\n stacktrace?: string\n} {\n if (typeof value !== 'object' || value === null) return false\n const v = value as { code?: unknown; message?: unknown; stacktrace?: unknown }\n return (\n typeof v.code === 'string' &&\n typeof v.message === 'string' &&\n (v.stacktrace === undefined || typeof v.stacktrace === 'string')\n )\n}\n","/**\n * Constants for the III module.\n */\n\n/**\n * Engine function paths for internal operations.\n *\n * Naming note: `LIST_TRIGGERS` / `INFO_TRIGGERS` cover trigger TYPES\n * (templates). `LIST_REGISTERED_TRIGGERS` / `INFO_REGISTERED_TRIGGERS`\n * cover trigger INSTANCES (subscriber rows). The old\n * `engine::trigger-types::list` builtin has been removed and is now\n * served by `engine::triggers::list`.\n */\nexport const EngineFunctions = {\n LIST_FUNCTIONS: 'engine::functions::list',\n INFO_FUNCTIONS: 'engine::functions::info',\n LIST_WORKERS: 'engine::workers::list',\n INFO_WORKERS: 'engine::workers::info',\n LIST_TRIGGERS: 'engine::triggers::list',\n INFO_TRIGGERS: 'engine::triggers::info',\n LIST_REGISTERED_TRIGGERS: 'engine::registered-triggers::list',\n INFO_REGISTERED_TRIGGERS: 'engine::registered-triggers::info',\n REGISTER_WORKER: 'engine::workers::register',\n} as const\n\n/** Engine trigger types */\nexport const EngineTriggers = {\n FUNCTIONS_AVAILABLE: 'engine::functions-available',\n LOG: 'log',\n} as const\n\n/** Log function paths */\nexport const LogFunctions = {\n INFO: 'engine::log::info',\n WARN: 'engine::log::warn',\n ERROR: 'engine::log::error',\n DEBUG: 'engine::log::debug',\n} as const\n\n/** Connection state for the III WebSocket */\nexport type IIIConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface IIIReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Default invocation timeout in milliseconds */\nexport const DEFAULT_INVOCATION_TIMEOUT_MS = 30000\n","export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n message_type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n message_type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n message_type: MessageType.UnregisterTrigger\n id: string\n type?: string\n}\n\nexport type ErrorBody = {\n code: string\n message: string\n stacktrace?: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n message_type: MessageType.TriggerRegistrationResult\n id: string\n type: string\n function_id: string\n error?: ErrorBody\n}\n\nexport type RegisterTriggerMessage = {\n message_type: MessageType.RegisterTrigger\n id: string\n type: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n}\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\nexport type RegisterFunctionFormat = {\n /**\n * The name of the parameter\n */\n name?: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map' | 'integer'\n /**\n * The body of the parameter (for objects)\n */\n properties?: Record<string, unknown>\n /**\n * The items of the parameter (for arrays)\n */\n items?: unknown\n /**\n * Whether the parameter is required\n */\n required?: string[]\n [key: string]: unknown\n}\n\nexport type RegisterFunctionMessage = {\n message_type: MessageType.RegisterFunction\n /**\n * The path of the function (use :: for namespacing, e.g. external::my_lambda)\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n /**\n * HTTP invocation config for external HTTP functions (Lambda, Cloudflare Workers, etc.)\n */\n invocation?: HttpInvocationConfig\n}\n\n/**\n * Routing action for {@link TriggerRequest}. Determines how the engine\n * handles the invocation.\n *\n * - `enqueue` -- Routes through a named queue for async processing.\n * - `void` -- Fire-and-forget, no response.\n */\nexport type TriggerAction = { type: 'enqueue'; queue: string } | { type: 'void' }\n\n/**\n * Input passed to the RBAC auth function during WebSocket upgrade.\n * Contains the HTTP headers, query parameters, and client IP from the\n * connecting worker's upgrade request.\n */\nexport type AuthInput = {\n /** HTTP headers from the WebSocket upgrade request. */\n headers: Record<string, string>\n /** Query parameters from the upgrade URL. Each key maps to an array of values to support repeated keys. */\n query_params: Record<string, string[]>\n /** IP address of the connecting client. */\n ip_address: string\n}\n\n/**\n * Return value from the RBAC auth function. Controls which functions the\n * authenticated worker can invoke and what context is forwarded to the\n * middleware.\n */\nexport type AuthResult = {\n /** Additional function IDs to allow beyond the `expose_functions` config. */\n allowed_functions: string[]\n /** Function IDs to deny even if they match `expose_functions`. Takes precedence over allowed. */\n forbidden_functions: string[]\n /** Trigger type IDs the worker may register triggers for. When omitted, all types are allowed. */\n allowed_trigger_types?: string[]\n /** Whether the worker may register new trigger types. */\n allow_trigger_type_registration: boolean\n /** Whether the worker may register new functions. Defaults to `true` if omitted. */\n allow_function_registration?: boolean\n /** Arbitrary context forwarded to the middleware function on every invocation. */\n context: Record<string, unknown>\n /** Optional prefix applied to all function IDs registered by this worker. */\n function_registration_prefix?: string\n}\n\n/**\n * Input passed to the RBAC middleware function on every function invocation\n * through the RBAC port. The middleware can inspect, modify, or reject the\n * call before it reaches the target function.\n */\nexport type MiddlewareFunctionInput = {\n /** ID of the function being invoked. */\n function_id: string\n /** Payload sent by the caller. */\n payload: Record<string, unknown>\n /** Routing action, if any. */\n action?: TriggerAction\n /** Auth context returned by the auth function for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Input passed to the `on_trigger_type_registration_function_id` hook\n * when a worker attempts to register a new trigger type through the RBAC port.\n * Return an {@link OnTriggerTypeRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerTypeRegistrationInput = {\n /** ID of the trigger type being registered. */\n trigger_type_id: string\n /** Human-readable description of the trigger type. */\n description: string\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_type_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerTypeRegistrationResult = {\n /** Mapped trigger type ID. */\n trigger_type_id?: string\n /** Mapped description. */\n description?: string\n}\n\n/**\n * Input passed to the `on_trigger_registration_function_id` hook\n * when a worker attempts to register a trigger through the RBAC port.\n * Return an {@link OnTriggerRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnTriggerRegistrationInput = {\n /** ID of the trigger being registered. */\n trigger_id: string\n /** Trigger type identifier. */\n trigger_type: string\n /** ID of the function this trigger is bound to. */\n function_id: string\n /** Trigger-specific configuration. */\n config: unknown\n /** Arbitrary metadata attached to the trigger. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_trigger_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnTriggerRegistrationResult = {\n /** Mapped trigger ID. */\n trigger_id?: string\n /** Mapped trigger type. */\n trigger_type?: string\n /** Mapped function ID. */\n function_id?: string\n /** Mapped trigger configuration. */\n config?: unknown\n}\n\n/**\n * Input passed to the `on_function_registration_function_id` hook\n * when a worker attempts to register a function through the RBAC port.\n * Return an {@link OnFunctionRegistrationResult} with the (possibly mapped)\n * fields, or throw to deny the registration.\n */\nexport type OnFunctionRegistrationInput = {\n /** ID of the function being registered. */\n function_id: string\n /** Human-readable description of the function. */\n description?: string\n /** Arbitrary metadata attached to the function. */\n metadata?: Record<string, unknown>\n /** Auth context from `AuthResult.context` for this session. */\n context: Record<string, unknown>\n}\n\n/**\n * Result returned from the `on_function_registration_function_id` hook.\n * All fields are optional -- omitted fields keep the original value from the\n * registration request.\n */\nexport type OnFunctionRegistrationResult = {\n /** Mapped function ID. */\n function_id?: string\n /** Mapped description. */\n description?: string\n /** Mapped metadata. */\n metadata?: Record<string, unknown>\n}\n\n/**\n * Result returned when a function is invoked with `TriggerAction.Enqueue`.\n */\nexport type EnqueueResult = {\n /** Unique receipt ID for the enqueued message. */\n messageReceiptId: string\n}\n\n/**\n * Request object passed to {@link ISdk.trigger}.\n *\n * @typeParam TInput - Type of the payload.\n */\nexport type TriggerRequest<TInput = unknown> = {\n /** ID of the function to invoke. */\n function_id: string\n /** Payload to pass to the function. */\n payload: TInput\n /** Routing action. Omit for synchronous request/response. */\n action?: TriggerAction\n /** Override the default invocation timeout in milliseconds. */\n timeoutMs?: number\n}\n\nexport type InvokeFunctionMessage = {\n message_type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n /**\n * Trigger action for queue routing or fire-and-forget\n */\n action?: TriggerAction\n}\n\nexport type InvocationResultMessage = {\n message_type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: unknown\n error?: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type WorkerRegisteredMessage = {\n message_type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n message_type: MessageType.UnregisterFunction\n id: string\n}\n\n/**\n * Serializable reference to one end of a streaming channel. Can be included\n * in invocation payloads to pass channel endpoints between workers.\n */\nexport type StreamChannelRef = {\n /** Unique channel identifier. */\n channel_id: string\n /** Access key for authentication. */\n access_key: string\n /** Whether this ref is for reading or writing. */\n direction: 'read' | 'write'\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport type { StreamChannelRef } from './iii-types'\nimport type { ApiResponse, HttpRequest, HttpResponse, InternalHttpRequest } from './types'\n\n/**\n * Returns a project identifier for telemetry, derived from the current working\n * directory. Reads `package.json` `name` if present at `cwd`; otherwise falls\n * back to the basename of `cwd`. Returns `undefined` only when both signals\n * are unavailable (e.g. cwd is the filesystem root).\n *\n * No directory walking — only inspects `cwd` itself, so the SDK never reads\n * files outside the user's explicit working directory.\n */\nexport function detectProjectName(cwd: string = process.cwd()): string | undefined {\n try {\n const manifest = path.join(cwd, 'package.json')\n if (fs.existsSync(manifest)) {\n const parsed = JSON.parse(fs.readFileSync(manifest, 'utf8')) as { name?: unknown }\n if (typeof parsed.name === 'string') {\n const trimmed = parsed.name.trim()\n if (trimmed) return trimmed\n }\n }\n } catch {\n // fall through to directory-name fallback\n }\n\n const base = path.basename(cwd).trim()\n return base || undefined\n}\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving an {@link HttpRequest} and {@link HttpResponse}.\n * @returns A function handler compatible with {@link ISdk.registerFunction}.\n *\n * @example\n * ```typescript\n * import { http } from 'iii-sdk'\n *\n * iii.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpRequest, res: HttpResponse) => Promise<void | ApiResponse>,\n) => {\n return async (req: InternalHttpRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n\n/**\n * Type guard that checks if a value is a {@link StreamChannelRef}.\n *\n * @param value - Value to check.\n * @returns `true` if the value is a valid `StreamChannelRef`.\n */\nexport const isChannelRef = (value: unknown): value is StreamChannelRef => {\n if (typeof value !== 'object' || value === null) return false\n const maybe = value as Partial<StreamChannelRef>\n return (\n typeof maybe.channel_id === 'string' &&\n typeof maybe.access_key === 'string' &&\n (maybe.direction === 'read' || maybe.direction === 'write')\n )\n}\n","import { context, trace } from '@opentelemetry/api'\nimport { createRequire } from 'node:module'\nimport * as os from 'node:os'\nimport { type Data, WebSocket } from 'ws'\nimport { ChannelReader, ChannelWriter } from './channels'\nimport { IIIInvocationError, isErrorBody } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n} from './iii-constants'\nimport {\n type HttpInvocationConfig,\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerAction as TriggerActionType,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/observability'\nimport { getMeter, getTracer } from '@iii-dev/observability/internal'\nimport { SpanKind } from '@opentelemetry/api'\nimport type { IStream } from './stream'\nimport { detectProjectName } from './utils'\nimport {\n extractContext,\n getLogger,\n initOtel,\n injectBaggage,\n injectTraceparent,\n type OtelConfig,\n recordSpanEvent,\n redactAndTruncate,\n resolveMaxBytesFromEnv,\n SeverityNumber,\n shutdownOtel,\n withSpan,\n} from '@iii-dev/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n Invocation,\n ISdk,\n RegisterFunctionOptions,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n TriggerTypeRef,\n} from './types'\nimport { isChannelRef } from './utils'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** @internal */\nexport type TelemetryOptions = {\n language?: string\n project_name?: string\n framework?: string\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const iii = registerWorker('ws://localhost:49134', {\n * workerName: 'my-worker',\n * invocationTimeoutMs: 10000,\n * reconnectionConfig: { maxRetries: 5 },\n * })\n * ```\n */\nexport type InitOptions = {\n /** Display name for this worker. Defaults to `hostname:pid`. */\n workerName?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `trigger()` in milliseconds. Defaults to `30000`. */\n invocationTimeoutMs?: number\n /**\n * WebSocket reconnection behavior.\n *\n * @see {@link IIIReconnectionConfig} for available fields and defaults.\n */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\n /**\n * OpenTelemetry configuration. OTel is initialized automatically by default.\n * Set `{ enabled: false }` or env `OTEL_ENABLED=false/0/no/off` to disable.\n * The `engineWsUrl` is set automatically from the III address.\n */\n otel?: Omit<OtelConfig, 'engineWsUrl'>\n /** Custom HTTP headers sent during the WebSocket handshake. */\n headers?: Record<string, string>\n /** @internal */\n telemetry?: TelemetryOptions\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private invocations = new Map<string, Invocation & { timeout?: NodeJS.Timeout }>()\n private triggers = new Map<string, RegisterTriggerMessage>()\n private triggerTypes = new Map<string, RemoteTriggerTypeData>()\n private messagesToSend: Record<string, unknown>[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry (enabled by default, opt-out via config or env)\n initOtel({ ...options?.otel, engineWsUrl: this.address })\n\n this.connect()\n }\n\n /**\n * Registers a custom trigger type with the engine. A trigger type defines\n * how external events (HTTP, cron, queue, etc.) map to function invocations.\n *\n * @param triggerType - Trigger type registration input.\n * @param triggerType.id - Unique trigger type identifier.\n * @param triggerType.description - Human-readable description.\n * @param handler - Handler with `registerTrigger` / `unregisterTrigger` callbacks.\n *\n * @example\n * ```typescript\n * iii.registerTriggerType(\n * { id: 'my-trigger', description: 'Custom trigger' },\n * {\n * async registerTrigger({ id, function_id, config }) { },\n * async unregisterTrigger({ id, function_id, config }) { },\n * },\n * )\n * ```\n */\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>,\n handler: TriggerHandler<TConfig>,\n ): TriggerTypeRef<TConfig> => {\n this.sendMessage(MessageType.RegisterTriggerType, triggerType, true)\n this.triggerTypes.set(triggerType.id, {\n message: { ...triggerType, message_type: MessageType.RegisterTriggerType },\n handler,\n })\n\n return {\n id: triggerType.id,\n registerTrigger: (functionId: string, config: TConfig, metadata?: Record<string, unknown>) => {\n return this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n },\n registerFunction: (functionId, handler, config, metadata?) => {\n const ref = this.registerFunction(functionId, handler)\n this.registerTrigger({\n type: triggerType.id,\n function_id: functionId,\n config,\n metadata,\n })\n return ref\n },\n unregister: () => {\n this.unregisterTriggerType(triggerType)\n },\n }\n }\n\n /**\n * Unregisters a previously registered trigger type.\n *\n * @param triggerType - The trigger type to unregister (must match the `id` used during registration).\n */\n unregisterTriggerType = (triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>): void => {\n this.sendMessage(MessageType.UnregisterTriggerType, triggerType, true)\n this.triggerTypes.delete(triggerType.id)\n }\n\n /**\n * Binds a trigger configuration to a registered function. When the trigger\n * fires, the engine invokes the target function.\n *\n * @param trigger - Trigger registration input.\n * @param trigger.type - Trigger type (e.g. `http`, `durable:subscriber`, `cron`).\n * @param trigger.function_id - ID of the function to invoke.\n * @param trigger.config - Trigger-specific configuration.\n * @returns A {@link Trigger} handle with an `unregister()` method.\n *\n * @example\n * ```typescript\n * const trigger = iii.registerTrigger({\n * type: 'http',\n * function_id: 'greet',\n * config: { api_path: '/greet', http_method: 'GET' },\n * })\n *\n * // Later...\n * trigger.unregister()\n * ```\n */\n registerTrigger = (trigger: Omit<RegisterTriggerMessage, 'message_type' | 'id'>): Trigger => {\n const id = crypto.randomUUID()\n const fullTrigger: RegisterTriggerMessage = {\n ...trigger,\n id,\n message_type: MessageType.RegisterTrigger,\n }\n this.sendMessage(MessageType.RegisterTrigger, fullTrigger, true)\n this.triggers.set(id, fullTrigger)\n\n return {\n unregister: () => {\n this.sendMessage(MessageType.UnregisterTrigger, {\n id,\n message_type: MessageType.UnregisterTrigger,\n type: fullTrigger.type,\n })\n this.triggers.delete(id)\n },\n }\n }\n\n /**\n * Registers a function with the engine. The `functionId` is the unique identifier\n * used by triggers and invocations.\n *\n * Pass a handler for local execution, or an {@link HttpInvocationConfig}\n * for HTTP-invoked functions (Lambda, Cloudflare Workers, etc.).\n *\n * @param functionId - Unique function identifier.\n * @param handlerOrInvocation - Async handler or HTTP invocation config.\n * @param options - Optional function registration options (description, request/response formats, metadata).\n * @returns A {@link FunctionRef} with `id` and `unregister()`.\n *\n * @example\n * ```typescript\n * const fn = iii.registerFunction(\n * 'greet',\n * async (input: { name: string }) => {\n * return { message: `Hello, ${input.name}!` }\n * },\n * { description: 'Greets a user' },\n * )\n * ```\n */\n registerFunction = (\n functionId: string,\n handlerOrInvocation: RemoteFunctionHandler | HttpInvocationConfig,\n options?: RegisterFunctionOptions,\n ): FunctionRef => {\n if (!functionId || functionId.trim() === '') {\n throw new Error('id is required')\n }\n if (this.functions.has(functionId)) {\n throw new Error(`function id already registered: ${functionId}`)\n }\n\n const isHandler = typeof handlerOrInvocation === 'function'\n\n const fullMessage: RegisterFunctionMessage = isHandler\n ? { ...options, id: functionId, message_type: MessageType.RegisterFunction }\n : {\n ...options,\n id: functionId,\n message_type: MessageType.RegisterFunction,\n invocation: {\n url: handlerOrInvocation.url,\n method: handlerOrInvocation.method ?? 'POST',\n timeout_ms: handlerOrInvocation.timeout_ms,\n headers: handlerOrInvocation.headers,\n auth: handlerOrInvocation.auth,\n },\n }\n\n this.sendMessage(MessageType.RegisterFunction, fullMessage, true)\n\n if (isHandler) {\n const handler = handlerOrInvocation as RemoteFunctionHandler\n this.functions.set(functionId, {\n message: fullMessage,\n handler: async (input, traceparent?: string, baggage?: string) => {\n const tracePayloads = !(\n process.env.III_DISABLE_TRACE_PAYLOADS === '1' ||\n process.env.III_DISABLE_TRACE_PAYLOADS?.toLowerCase() === 'true'\n )\n const payloadMaxBytes = resolveMaxBytesFromEnv()\n\n const runHandler = async () => {\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(input, payloadMaxBytes)\n recordSpanEvent('iii.invocation.input', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n })\n }\n try {\n const result = await handler(input)\n if (tracePayloads) {\n const { json, truncated } = redactAndTruncate(result, payloadMaxBytes)\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': true,\n })\n }\n return result\n } catch (err) {\n if (tracePayloads) {\n const errMsg = err instanceof Error ? err.message : String(err)\n const { json, truncated } = redactAndTruncate(\n { error: errMsg },\n payloadMaxBytes,\n )\n recordSpanEvent('iii.invocation.output', {\n 'iii.payload.json': json,\n 'iii.payload.truncated': truncated,\n 'iii.payload.ok': false,\n })\n }\n throw err\n }\n }\n\n if (getTracer()) {\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`call ${functionId}`, { kind: SpanKind.SERVER }, async () => await runHandler()),\n )\n }\n\n const traceId = crypto.randomUUID().replace(/-/g, '')\n const spanId = crypto.randomUUID().replace(/-/g, '').slice(0, 16)\n const syntheticSpan = trace.wrapSpanContext({ traceId, spanId, traceFlags: 1 })\n\n return context.with(trace.setSpan(context.active(), syntheticSpan), async () => await runHandler())\n },\n })\n } else {\n this.functions.set(functionId, { message: fullMessage })\n }\n\n return {\n id: functionId,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: functionId }, true)\n this.functions.delete(functionId)\n },\n }\n }\n\n /**\n * Creates a streaming channel pair for worker-to-worker data transfer.\n * Returns a {@link Channel} with a local writer/reader and serializable refs\n * that can be passed as fields in invocation data to other functions.\n *\n * @param bufferSize - Optional buffer size for the channel (default: 64).\n * @returns A {@link Channel} with `writer`, `reader`, and their serializable refs.\n *\n * @example\n * ```typescript\n * const channel = await iii.createChannel()\n * channel.writer.stream.write(Buffer.from('hello'))\n * channel.writer.close()\n * ```\n */\n createChannel = async (bufferSize?: number): Promise<import('./types').Channel> => {\n const result = await this.trigger<{ buffer_size?: number }, { writer: StreamChannelRef; reader: StreamChannelRef }>(\n { function_id: 'engine::channels::create', payload: { buffer_size: bufferSize } },\n )\n\n return {\n writer: new ChannelWriter(this.address, result.writer),\n reader: new ChannelReader(this.address, result.reader),\n writerRef: result.writer,\n readerRef: result.reader,\n }\n }\n\n /**\n * Invokes a remote function. The routing behavior and return type depend\n * on the `action` field of the request.\n *\n * | `action` | Behavior | Return type |\n * |-------------------------------|----------------------------------------------------|----------------------- |\n * | _(none)_ | Synchronous -- waits for the function to return | `Promise<TOutput>` |\n * | `TriggerAction.Enqueue(...)` | Async via named queue -- engine acknowledges enqueue | `Promise<EnqueueResult>` |\n * | `TriggerAction.Void()` | Fire-and-forget -- no response | `Promise<undefined>` |\n *\n * @param request - The trigger request.\n * @param request.function_id - ID of the function to invoke.\n * @param request.payload - Payload to pass to the function.\n * @param request.action - Routing action. Omit for synchronous request/response.\n * @param request.timeoutMs - Override the default invocation timeout.\n * @returns The result of the function invocation.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Synchronous\n * const result = await iii.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await iii.trigger({\n * function_id: 'payments::charge',\n * payload: { orderId: '123', amount: 49.99 },\n * action: TriggerAction.Enqueue({ queue: 'payment' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n trigger = async <TInput, TOutput>(request: TriggerRequest<TInput>): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs } = request\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\n\n // Void is fire-and-forget — no invocation_id, no response\n if (action?.type === 'void') {\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, {\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n return undefined as TOutput\n }\n\n // Enqueue and default: send invocation_id, await response\n const invocation_id = crypto.randomUUID()\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n\n return new Promise<TOutput>((resolve, reject) => {\n const timeout = setTimeout(() => {\n const invocation = this.invocations.get(invocation_id)\n if (invocation) {\n this.invocations.delete(invocation_id)\n reject(\n new IIIInvocationError({\n code: 'TIMEOUT',\n message: `invocation timed out after ${effectiveTimeout}ms`,\n function_id,\n }),\n )\n }\n }, effectiveTimeout)\n\n this.invocations.set(invocation_id, {\n resolve: (result: TOutput) => {\n clearTimeout(timeout)\n resolve(result)\n },\n reject: (error: unknown) => {\n clearTimeout(timeout)\n reject(error)\n },\n function_id,\n timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data: payload,\n traceparent,\n baggage,\n action,\n })\n })\n }\n\n private registerWorkerMetadata(): void {\n const telemetryOpts = this.options?.telemetry\n const language =\n telemetryOpts?.language ?? Intl.DateTimeFormat().resolvedOptions().locale ?? process.env.LANG?.split('.')[0]\n\n this.trigger({\n function_id: EngineFunctions.REGISTER_WORKER,\n payload: {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n telemetry: {\n language,\n project_name: telemetryOpts?.project_name ?? detectProjectName(),\n framework: telemetryOpts?.framework?.trim() || 'iii-node',\n amplitude_api_key: telemetryOpts?.amplitude_api_key,\n },\n },\n action: { type: 'void' },\n })\n }\n\n /**\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name.\n *\n * Registers 5 of the 6 `IStream` methods (`get`, `set`, `delete`, `list`,\n * `listGroups`). The `update` method is not registered -- atomic updates are\n * handled by the engine's built-in stream update logic.\n *\n * @param streamName - Name of the stream.\n * @param stream - Object implementing the {@link IStream} interface.\n *\n * @example\n * ```typescript\n * iii.createStream('my-stream', {\n * async get(input) { return null },\n * async set(input) { return null },\n * async delete(input) { return { old_value: undefined } },\n * async list(input) { return [] },\n * async listGroups(input) { return [] },\n * async update(input) { return null },\n * })\n * ```\n */\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction(`stream::get(${streamName})`, stream.get.bind(stream))\n this.registerFunction(`stream::set(${streamName})`, stream.set.bind(stream))\n this.registerFunction(`stream::delete(${streamName})`, stream.delete.bind(stream))\n this.registerFunction(`stream::list(${streamName})`, stream.list.bind(stream))\n this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream))\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket. Swallow any close-time errors (most commonly\n // \"WebSocket was closed before the connection was established\" —\n // emitted when `close()` fires while still in CONNECTING state\n // and there's no error listener). Without a catch-all listener,\n // that event becomes an unhandled exception because we remove\n // every listener right above the close call.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.close()\n } catch {\n // ignore — shutting down anyway\n }\n this.ws = undefined\n }\n\n this.setConnectionState('disconnected')\n }\n\n // private methods\n\n private setConnectionState(state: IIIConnectionState): void {\n if (this.connectionState !== state) {\n this.connectionState = state\n }\n }\n\n private connect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n this.setConnectionState('connecting')\n this.ws = new WebSocket(this.address, { headers: this.options?.headers })\n this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } = this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.functions.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterFunction, message, true)\n })\n this.triggers.forEach((trigger) => {\n this.sendMessage(MessageType.RegisterTrigger, trigger, true)\n })\n\n // Optimized: swap with empty array instead of splice\n const pending = this.messagesToSend\n this.messagesToSend = []\n for (const message of pending) {\n if (\n message.type === MessageType.InvokeFunction &&\n typeof message.invocation_id === 'string' &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, (err) => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private toWireFormat(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>): Record<string, unknown> {\n const { message_type: _, ...rest } = message as Record<string, unknown>\n if (messageType === MessageType.RegisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.UnregisterTrigger && 'type' in message) {\n const { type: triggerType, ...triggerRest } = message as RegisterTriggerMessage\n return { type: messageType, ...triggerRest, trigger_type: triggerType }\n }\n if (messageType === MessageType.TriggerRegistrationResult && 'type' in message) {\n const { type: triggerType, ...resultRest } = message as TriggerRegistrationResultMessage\n return { type: messageType, ...resultRest, trigger_type: triggerType }\n }\n return { type: messageType, ...rest } as Record<string, unknown>\n }\n\n private sendMessage(messageType: MessageType, message: Omit<IIIMessage, 'message_type'>, skipIfClosed = false): void {\n const wireMessage = this.toWireFormat(messageType, message)\n if (this.isOpen()) {\n this.sendMessageRaw(JSON.stringify(wireMessage))\n } else if (!skipIfClosed) {\n this.messagesToSend.push(wireMessage)\n }\n }\n\n private logError(message: string, error?: unknown): void {\n const otelLogger = getLogger()\n const errorMessage = error instanceof Error ? error.message : String(error ?? '')\n\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.ERROR,\n body: `[iii] ${message}${errorMessage ? `: ${errorMessage}` : ''}`,\n })\n } else {\n console.error(`[iii] ${message}`, error ?? '')\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n if (error) {\n invocation.reject(this.toInvocationError(error, invocation.function_id))\n } else {\n invocation.resolve(result)\n }\n }\n\n this.invocations.delete(invocation_id)\n }\n\n /**\n * Wrap a wire-format `ErrorBody` in {@link IIIInvocationError} so callers get\n * a real `Error` with a readable `.message` and a typed `.code`. Pass-through\n * for values that are already `Error` subclasses. Everything else is wrapped\n * under an `UNKNOWN` code so `String(err) !== '[object Object]'` holds for\n * every rejection path.\n */\n private toInvocationError(error: unknown, function_id?: string): Error {\n if (error instanceof Error) {\n return error\n }\n if (isErrorBody(error)) {\n return new IIIInvocationError({\n code: error.code,\n message: error.message,\n function_id,\n stacktrace: error.stacktrace,\n })\n }\n // JSON.stringify(undefined) returns undefined (not \"undefined\"), which\n // would set message to the literal string \"undefined\" after type coercion\n // and leak an uninformative rejection. Fall back through String(error)\n // so every path produces a concrete, readable string.\n const message =\n typeof error === 'string'\n ? error\n : (JSON.stringify(error) ?? String(error))\n return new IIIInvocationError({\n code: 'UNKNOWN',\n message,\n function_id,\n })\n }\n\n private resolveChannelValue(value: unknown): unknown {\n if (isChannelRef(value)) {\n return value.direction === 'read'\n ? new ChannelReader(this.address, value)\n : new ChannelWriter(this.address, value)\n }\n if (Array.isArray(value)) {\n return value.map((item) => this.resolveChannelValue(item))\n }\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = this.resolveChannelValue(v)\n }\n return out\n }\n return value\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n const resolvedInput = this.resolveChannelValue(input) as TInput\n\n if (fn?.handler) {\n if (!invocation_id) {\n try {\n await fn.handler(resolvedInput, traceparent, baggage)\n } catch (error) {\n this.logError(`Error invoking function ${function_id}`, error)\n }\n return\n }\n\n try {\n const result = await fn.handler(resolvedInput, traceparent, baggage)\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n result,\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n } catch (error) {\n const isError = error instanceof Error\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: {\n code: 'invocation_failed',\n message: isError ? error.message : String(error),\n stacktrace: isError ? error.stack : undefined,\n },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n const errorCode = fn ? 'function_not_invokable' : 'function_not_found'\n const errorMessage = fn ? 'Function is HTTP-invoked and cannot be invoked locally' : 'Function not found'\n if (invocation_id) {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: errorCode, message: errorMessage },\n traceparent,\n baggage,\n })\n }\n }\n }\n\n private async onRegisterTrigger(message: { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> }) {\n const { trigger_type, id, function_id, config, metadata } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata })\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n })\n } catch (error) {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_registration_failed', message: (error as Error).message },\n })\n }\n } else {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n message_type: MessageType.TriggerRegistrationResult,\n type: trigger_type,\n function_id,\n error: { code: 'trigger_type_not_found', message: 'Trigger type not found' },\n })\n }\n }\n\n private onTriggerRegistrationResult(\n message: { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n ): void {\n if (!message.error) return\n const triggerType = message.trigger_type ?? message.type ?? ''\n console.error(\n `[iii] Trigger registration failed for \"${message.id}\" (${triggerType}): ${message.error.message}`,\n )\n }\n\n private onMessage(socketMessage: Data): void {\n let msgType: MessageType\n let message: Record<string, unknown>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as Record<string, unknown>\n msgType = parsed.type as MessageType\n const { type: _, ...rest } = parsed\n message = rest\n } catch (error) {\n this.logError('Failed to parse incoming message', error)\n return\n }\n\n if (msgType === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (msgType === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (msgType === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(message as { trigger_type: string; id: string; function_id: string; config: unknown; metadata?: Record<string, unknown> })\n } else if (msgType === MessageType.TriggerRegistrationResult) {\n this.onTriggerRegistrationResult(\n message as { id: string; trigger_type?: string; type?: string; function_id: string; error?: { code: string; message: string; stacktrace?: string } },\n )\n } else if (msgType === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link ISdk.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * iii.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * iii.trigger({\n * function_id: 'notify',\n * payload: {},\n * action: TriggerAction.Void(),\n * })\n * ```\n */\nexport const TriggerAction = {\n /**\n * Routes the invocation through a named queue. The engine enqueues the job,\n * acknowledges the caller with `{ messageReceiptId }`, and processes it\n * asynchronously.\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }): TriggerActionType => ({ type: 'enqueue', ...opts }),\n /**\n * Fire-and-forget routing. The engine forwards the invocation without\n * waiting for a response or queuing the job.\n */\n Void: (): TriggerActionType => ({ type: 'void' }),\n} as const\n\n/**\n * Creates and returns a connected SDK instance. The WebSocket connection is\n * established automatically -- there is no separate `connect()` call.\n *\n * @param address - WebSocket URL of the III engine (e.g. `ws://localhost:49134`).\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link ISdk} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const iii = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iii-sdk",
3
- "version": "0.16.0",
3
+ "version": "0.16.2-next.1",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -34,7 +34,7 @@
34
34
  "dependencies": {
35
35
  "@opentelemetry/api": "^1.9.0",
36
36
  "ws": "^8.18.3",
37
- "@iii-dev/observability": "0.16.0"
37
+ "@iii-dev/observability": "0.16.2-next.1"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@opentelemetry/context-async-hooks": "^2.7.1",
package/vitest.config.ts CHANGED
@@ -7,6 +7,10 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
7
  export default defineConfig({
8
8
  resolve: {
9
9
  alias: {
10
+ '@iii-dev/observability/internal': path.resolve(
11
+ __dirname,
12
+ '../observability/src/internal.ts',
13
+ ),
10
14
  '@iii-dev/observability': path.resolve(__dirname, '../observability/src/index.ts'),
11
15
  },
12
16
  },