iii-sdk 0.22.0-alpha.5 → 0.22.0-alpha.7
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/channel.d.cts +1 -1
- package/dist/channel.d.mts +1 -1
- package/dist/engine.d.cts +1 -1
- package/dist/engine.d.mts +1 -1
- package/dist/helpers.d.cts +1 -1
- package/dist/helpers.d.mts +1 -1
- package/dist/index.cjs +22 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -7
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +16 -7
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +22 -6
- package/dist/index.mjs.map +1 -1
- package/dist/internal.d.cts +1 -1
- package/dist/internal.d.mts +1 -1
- package/dist/protocol.d.cts +1 -1
- package/dist/protocol.d.mts +1 -1
- package/dist/runtime.d.cts +1 -1
- package/dist/runtime.d.mts +1 -1
- package/dist/trigger.d.cts +1 -1
- package/dist/trigger.d.mts +1 -1
- package/dist/{types-DEiuZFsp.d.cts → types-C43VHoZq.d.cts} +6 -1
- package/dist/{types-DEiuZFsp.d.cts.map → types-C43VHoZq.d.cts.map} +1 -1
- package/dist/{types-LJLev920.d.mts → types-CPReRK1z.d.mts} +6 -1
- package/dist/{types-LJLev920.d.mts.map → types-CPReRK1z.d.mts.map} +1 -1
- package/package.json +2 -2
package/dist/channel.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as ChannelWriter, M as StreamChannelRef, S as ChannelReader, t as Channel } from "./types-
|
|
1
|
+
import { C as ChannelWriter, M as StreamChannelRef, S as ChannelReader, t as Channel } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { type Channel, ChannelReader, ChannelWriter, type StreamChannelRef };
|
package/dist/channel.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as ChannelWriter, M as StreamChannelRef, S as ChannelReader, t as Channel } from "./types-
|
|
1
|
+
import { C as ChannelWriter, M as StreamChannelRef, S as ChannelReader, t as Channel } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { type Channel, ChannelReader, ChannelWriter, type StreamChannelRef };
|
package/dist/engine.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as EngineTriggers, g as EngineFunctions, l as RemoteFunctionHandler } from "./types-
|
|
1
|
+
import { _ as EngineTriggers, g as EngineFunctions, l as RemoteFunctionHandler } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { EngineFunctions, EngineTriggers, type RemoteFunctionHandler };
|
package/dist/engine.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { _ as EngineTriggers, g as EngineFunctions, l as RemoteFunctionHandler } from "./types-
|
|
1
|
+
import { _ as EngineTriggers, g as EngineFunctions, l as RemoteFunctionHandler } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { EngineFunctions, EngineTriggers, type RemoteFunctionHandler };
|
package/dist/helpers.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as StreamChannelRef, b as ChannelDirection, r as IIIClient, t as Channel, x as ChannelItem } from "./types-
|
|
1
|
+
import { M as StreamChannelRef, b as ChannelDirection, r as IIIClient, t as Channel, x as ChannelItem } from "./types-C43VHoZq.cjs";
|
|
2
2
|
import { IStream } from "./stream.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utils.d.ts
|
package/dist/helpers.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { M as StreamChannelRef, b as ChannelDirection, r as IIIClient, t as Channel, x as ChannelItem } from "./types-
|
|
1
|
+
import { M as StreamChannelRef, b as ChannelDirection, r as IIIClient, t as Channel, x as ChannelItem } from "./types-CPReRK1z.mjs";
|
|
2
2
|
import { IStream } from "./stream.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/utils.d.ts
|
package/dist/index.cjs
CHANGED
|
@@ -34,6 +34,18 @@ function getDefaultWorkerName() {
|
|
|
34
34
|
if (managedName) return managedName;
|
|
35
35
|
return `${node_os.hostname()}:${process.pid}`;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Engine address used when neither an explicit address nor `III_URL` is set.
|
|
39
|
+
* The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`
|
|
40
|
+
* on a host whose engine only listens on IPv4.
|
|
41
|
+
*/
|
|
42
|
+
const DEFAULT_ENGINE_URL = "ws://127.0.0.1:49134";
|
|
43
|
+
function resolveAddress(address) {
|
|
44
|
+
if (address) return address;
|
|
45
|
+
const fromEnv = process.env.III_URL;
|
|
46
|
+
if (fromEnv) return fromEnv;
|
|
47
|
+
return DEFAULT_ENGINE_URL;
|
|
48
|
+
}
|
|
37
49
|
function resolveNamespace(optionNamespace) {
|
|
38
50
|
if (optionNamespace) return optionNamespace;
|
|
39
51
|
const managedNamespace = process.env.III_NAMESPACE;
|
|
@@ -266,6 +278,7 @@ var Sdk = class {
|
|
|
266
278
|
this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream));
|
|
267
279
|
};
|
|
268
280
|
this.getConnectionState = () => this.connectionState;
|
|
281
|
+
this.getAddress = () => this.address;
|
|
269
282
|
this.getFatalError = () => this.fatalError;
|
|
270
283
|
this.shutdown = async () => {
|
|
271
284
|
this.isShuttingDown = true;
|
|
@@ -783,7 +796,8 @@ const TriggerAction = {
|
|
|
783
796
|
* Register the worker with a iii instance, returns a connected worker client.
|
|
784
797
|
* The WebSocket connection is established automatically.
|
|
785
798
|
*
|
|
786
|
-
* @param address - WebSocket URL of the III engine
|
|
799
|
+
* @param address - WebSocket URL of the III engine. Omit to resolve it from
|
|
800
|
+
* `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.
|
|
787
801
|
* @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.
|
|
788
802
|
* @returns A connected {@link IIIClient} instance.
|
|
789
803
|
*
|
|
@@ -791,14 +805,17 @@ const TriggerAction = {
|
|
|
791
805
|
* ```typescript
|
|
792
806
|
* import { registerWorker } from 'iii-sdk'
|
|
793
807
|
*
|
|
794
|
-
*
|
|
795
|
-
*
|
|
796
|
-
*
|
|
808
|
+
* // Address from III_URL, set by whatever supervisor spawned this worker.
|
|
809
|
+
* const worker = registerWorker()
|
|
810
|
+
*
|
|
811
|
+
* // Or explicitly, which always wins over the environment.
|
|
812
|
+
* const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })
|
|
797
813
|
* ```
|
|
798
814
|
*/
|
|
799
|
-
const registerWorker = (address, options) => new Sdk(address, options);
|
|
815
|
+
const registerWorker = (address, options) => new Sdk(resolveAddress(address), options);
|
|
800
816
|
|
|
801
817
|
//#endregion
|
|
818
|
+
exports.DEFAULT_ENGINE_URL = DEFAULT_ENGINE_URL;
|
|
802
819
|
exports.InvocationError = require_errors.InvocationError;
|
|
803
820
|
exports.RegistrationRejectedError = require_errors.RegistrationRejectedError;
|
|
804
821
|
exports.TriggerAction = TriggerAction;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["os","MessageType","context","SpanKind","trace","ChannelWriter","ChannelReader","InvocationError","DEFAULT_BRIDGE_RECONNECTION_CONFIG","EngineFunctions","detectProjectName","WebSocket","WS_HANDSHAKE_TIMEOUT_MS","WS_IDLE_TIMEOUT_MS","WS_PING_INTERVAL_MS","SeverityNumber","RegistrationRejectedError","isErrorBody","isChannelRef"],"sources":["../src/iii.ts"],"sourcesContent":["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 { InvocationError, isErrorBody, RegistrationRejectedError } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n WS_HANDSHAKE_TIMEOUT_MS,\n WS_IDLE_TIMEOUT_MS,\n WS_PING_INTERVAL_MS,\n} from './iii-constants'\nimport type { HttpInvocationConfig } from '@iii-dev/helpers/http'\nimport {\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n type JsonValue,\n MessageType,\n type RegisterFunctionMessage,\n type RegistrationRejectedMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/helpers/observability'\nimport { getMeter, getTracer } from '@iii-dev/helpers/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/helpers/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n IIIClient,\n Invocation,\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\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker\n * already holds this `(namespace, worker_name)`. The engine closes the\n * connection -- fatal.\n */\nconst WORKER_NAMESPACE_CONFLICT = 'WORKER_NAMESPACE_CONFLICT'\n\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker in\n * this namespace already exports this one function id. The connection stays\n * open -- non-fatal.\n */\nconst FUNCTION_NAMESPACE_CONFLICT = 'FUNCTION_NAMESPACE_CONFLICT'\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n // III_WORKER_NAME carries the config.yaml entry name for managed workers\n // (set by iii-worker at spawn). Engine truth (`iii worker status`/`list`)\n // matches connections by name, so the managed identity must win over the\n // hostname:pid fallback.\n const managedName = process.env.III_WORKER_NAME\n if (managedName) {\n return managedName\n }\n return `${os.hostname()}:${process.pid}`\n}\n\nfunction resolveNamespace(optionNamespace?: string): string | undefined {\n // III_NAMESPACE carries the namespace for managed workers (set by iii-worker\n // at spawn), mirroring III_WORKER_NAME. An explicit option wins; otherwise\n // the env var provides the managed identity. Absent in both means undefined\n // -- the engine applies its `default` namespace when none is on the wire.\n if (optionNamespace) {\n return optionNamespace\n }\n const managedNamespace = process.env.III_NAMESPACE\n if (managedNamespace) {\n return managedNamespace\n }\n return undefined\n}\n\n/** Worker metadata reported to the engine (language, framework, project). */\nexport type TelemetryOptions = {\n /** Programming language of the worker. */\n language?: string\n /** Name of the project this worker belongs to. */\n project_name?: string\n /** Framework name, if applicable. */\n framework?: string\n /** Amplitude API key for product analytics. */\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const worker = 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 /**\n * Namespace this worker registers under. Resolution order:\n * `options.namespace` -> `process.env.III_NAMESPACE` -> undefined. When\n * undefined the engine applies its `default` namespace. Scopes worker and\n * function registrations so identically-named entries can coexist across\n * namespaces.\n */\n namespace?: string\n /**\n * One-line, human/LLM-readable summary of what this worker does.\n * Surfaces in `engine::workers::list` / `engine::workers::info`.\n */\n workerDescription?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `worker.trigger()` invocations 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 IIIClient {\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 namespace?: string\n private workerDescription?: string\n private workerId?: string\n private reattachToken?: string\n private reconnectTimeout?: NodeJS.Timeout\n private heartbeatInterval?: NodeJS.Timeout\n private idleTimeout?: 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 // Set when the engine fatally rejects this worker's registration (e.g. a\n // namespace/name collision). Terminal: no reconnect follows. Mirrors the\n // Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n private fatalError?: RegistrationRejectedError\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.namespace = resolveNamespace(options?.namespace)\n this.workerDescription = options?.workerDescription\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 * worker.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 // This typed helper pairs a function with its trigger, so it defaults the\n // trigger's namespace to this worker's — otherwise the function would land\n // in the worker's namespace and the trigger in `default`, and never resolve\n // it. The low-level `registerTrigger` keeps the engine default (`default`).\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 namespace: this.namespace,\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 namespace: this.namespace,\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 = worker.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 = worker.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, metadata?: JsonValue, 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, metadata)\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 // INTERNAL and named `execute` (not `call`/`trigger`): the engine\n // suppresses its own `call <fn>` span for worker-routed functions\n // (this span is the canonical one for the invocation) but still\n // emits engine-side wrappers like `trigger <fn>` from fire_triggers\n // and `call <fn>` for builtins. Reusing those names would read as\n // duplicate engine spans under the worker's service. `execute` is\n // unique, so the worker handler span reads as a clean internal\n // child (and is collapsible by a single rule).\n return context.with(parentContext, () =>\n withSpan(`execute ${functionId}`, { kind: SpanKind.INTERNAL }, 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 * @internal Implementation backing the `createChannel` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\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 __helpers_create_channel = 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 * @param request.metadata - Optional per-invocation metadata (arbitrary JSON)\n * surfaced to the target handler as its second argument.\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 worker.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await worker.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 * worker.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n // biome-ignore lint/suspicious/noExplicitAny: TOutput defaults to any so untyped calls type-check (the engine cannot express the return type statically)\n trigger = async <TInput = unknown, TOutput = any>(\n request: TriggerRequest<TInput>,\n ): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs, metadata, namespace } = 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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 InvocationError({\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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 description: this.workerDescription,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n // Omit when absent so the engine falls back to its `default` namespace.\n ...(this.namespace !== undefined ? { namespace: this.namespace } : {}),\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 * @internal Implementation backing the `createStream` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\n *\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name. Registers 5 of the 6 `IStream` methods\n * (`get`, `set`, `delete`, `list`, `listGroups`). The `update` method is\n * not registered; atomic updates are handled by the engine's built-in\n * stream update logic.\n */\n __helpers_create_stream = <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 * The current WebSocket connection state. `'failed'` is terminal — it follows\n * a fatal registration rejection (see {@link getFatalError}). Mirrors the\n * Python/Rust SDKs' `get_connection_state()`.\n */\n getConnectionState = (): IIIConnectionState => this.connectionState\n\n /**\n * The fatal registration rejection that terminated this connection, if any\n * (e.g. a `WORKER_NAMESPACE_CONFLICT`). `undefined` while healthy. Mirrors the\n * Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n */\n getFatalError = (): RegistrationRejectedError | undefined => this.fatalError\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 and keepalive heartbeat (shutdown never\n // reaches onSocketClose: listeners are removed before close() below)\n this.clearReconnectTimeout()\n this.stopHeartbeat()\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, {\n headers: this.options?.headers,\n handshakeTimeout: WS_HANDSHAKE_TIMEOUT_MS,\n })\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 startHeartbeat(): void {\n this.stopHeartbeat()\n // Dedicated deadline, refresh()ed on every inbound frame, so it fires\n // exactly WS_IDLE_TIMEOUT_MS after the last frame instead of on the next\n // ping tick (which could add up to a full WS_PING_INTERVAL_MS of delay).\n this.idleTimeout = setTimeout(() => {\n this.logError(`No inbound data for ${WS_IDLE_TIMEOUT_MS}ms, terminating connection to force reconnect`)\n this.ws?.terminate() // 'close' fires -> onSocketClose stops the heartbeat and schedules reconnect\n }, WS_IDLE_TIMEOUT_MS)\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.isOpen()) {\n this.ws.ping()\n }\n }, WS_PING_INTERVAL_MS)\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = undefined\n }\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout)\n this.idleTimeout = 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.stopHeartbeat()\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 // Reset the idle deadline on any inbound frame (message/ping/pong), Rust SDK parity\n const touch = () => {\n this.idleTimeout?.refresh()\n }\n this.ws?.on('message', touch)\n this.ws?.on('ping', touch)\n this.ws?.on('pong', touch)\n this.startHeartbeat()\n\n // Reconnect: present the previous engine-assigned identity BEFORE the\n // metadata announce and registration replay so the engine retires the old\n // connection and the replay lands on a clean slate instead of racing its\n // cleanup. This must precede registerWorkerMetadata(): otherwise the old\n // connection still holds this (namespace, worker_name) and the announce\n // would trip WORKER_NAMESPACE_CONFLICT against ourselves. The token proves\n // we ARE that worker (ids alone are publicly listable).\n if (this.workerId) {\n this.sendMessageRaw(\n JSON.stringify({\n type: MessageType.Reattach,\n previous_worker_id: this.workerId,\n reattach_token: this.reattachToken,\n }),\n )\n }\n\n // Announce worker metadata (carrying the namespace) before flushing any\n // registrations so the engine knows this connection's namespace up front.\n this.registerWorkerMetadata()\n\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\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 logWarn(message: string): void {\n const otelLogger = getLogger()\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.WARN,\n body: `[iii] ${message}`,\n })\n } else {\n console.warn(`[iii] ${message}`)\n }\n }\n\n /**\n * Handle a `registrationrejected` from the engine. The `code` decides the\n * severity:\n *\n * - {@link WORKER_NAMESPACE_CONFLICT}: another live worker already holds this\n * `(namespace, worker_name)`. The engine closes the connection, so this is\n * fatal -- stop the worker, do not reconnect, and surface a\n * {@link RegistrationRejectedError} to every pending invocation.\n * - {@link FUNCTION_NAMESPACE_CONFLICT}: another live worker in this namespace\n * already exports this one function id. Only that registration is refused;\n * the engine keeps the connection open and the worker keeps serving its\n * other functions. Non-fatal -- log a warning and continue. Here\n * `worker_name` carries the contested function id (the engine reuses the\n * struct).\n * - Any other code: treated as fatal (safe default).\n */\n private onRegistrationRejected(init: {\n code: string\n namespace: string\n worker_name: string\n owner_worker_id: string\n }): void {\n if (init.code === FUNCTION_NAMESPACE_CONFLICT) {\n this.logWarn(\n `Function registration rejected: function \"${init.worker_name}\" in namespace \"${init.namespace}\" is already exported by worker ${init.owner_worker_id}. The worker stays connected and keeps serving its other functions.`,\n )\n return\n }\n\n const error = new RegistrationRejectedError(init)\n // Record it so callers can poll for the terminal cause (parity with the\n // Python/Rust SDKs); the connection also transitions to `failed` below.\n this.fatalError = error\n if (init.code === WORKER_NAMESPACE_CONFLICT) {\n this.logError('Registration rejected by engine', error)\n } else {\n this.logError(`Registration rejected by engine with unknown code \"${init.code}\"; treating as fatal`, error)\n }\n\n // Mark shutdown first so neither onSocketClose nor scheduleReconnect can\n // schedule a reconnect for a rejection that would only be rejected again.\n this.isShuttingDown = true\n this.clearReconnectTimeout()\n this.stopHeartbeat()\n\n // Reject every in-flight invocation with the fatal error.\n for (const [, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(error)\n }\n this.invocations.clear()\n\n // Tear down the socket without triggering the reconnect path.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.terminate()\n } catch {\n // ignore, stopping anyway\n }\n this.ws = undefined\n }\n\n this.stopMetricsReporting()\n this.setConnectionState('failed')\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 InvocationError} 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 InvocationError({\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 InvocationError({\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 metadata?: JsonValue,\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, metadata, 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, metadata, 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: {\n trigger_type: string\n id: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n namespace?: string\n }) {\n const { trigger_type, id, function_id, config, metadata, namespace } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n // Surface the namespace to the handler: a provider that fires the target\n // later needs it to resolve in the right namespace, not `default`.\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata, namespace })\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 async onUnregisterTrigger(message: {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n }) {\n const trigger_type = message.trigger_type\n if (!trigger_type) return\n\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n if (!triggerTypeData) return\n\n const { id, function_id = '', config, metadata } = message\n try {\n await triggerTypeData.handler.unregisterTrigger({ id, function_id, config, metadata })\n } catch (error) {\n this.logError(`Error unregistering trigger ${id}`, error)\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, metadata, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, metadata, 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.UnregisterTrigger) {\n this.onUnregisterTrigger(\n message as {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n },\n )\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, reattach_token } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n this.reattachToken = reattach_token\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n } else if (msgType === MessageType.RegistrationRejected) {\n const { code, namespace, worker_name, owner_worker_id } = message as RegistrationRejectedMessage\n this.onRegistrationRejected({ code, namespace, worker_name, owner_worker_id })\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link IIIClient.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * worker.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * worker.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 * Requires a queue worker in the project. Run `iii worker add queue`.\n * Without it the trigger rejects with `enqueue_error` (no queue provider).\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }) => ({ type: 'enqueue' as const, ...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: () => ({ type: 'void' as const }),\n} as const\n\n/**\n * Register the worker with a iii instance, returns a connected worker client.\n * The WebSocket connection is established automatically.\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 IIIClient} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const worker = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): IIIClient => new Sdk(address, options)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["os","MessageType","context","SpanKind","trace","ChannelWriter","ChannelReader","InvocationError","DEFAULT_BRIDGE_RECONNECTION_CONFIG","EngineFunctions","detectProjectName","WebSocket","WS_HANDSHAKE_TIMEOUT_MS","WS_IDLE_TIMEOUT_MS","WS_PING_INTERVAL_MS","SeverityNumber","RegistrationRejectedError","isErrorBody","isChannelRef"],"sources":["../src/iii.ts"],"sourcesContent":["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 { InvocationError, isErrorBody, RegistrationRejectedError } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n WS_HANDSHAKE_TIMEOUT_MS,\n WS_IDLE_TIMEOUT_MS,\n WS_PING_INTERVAL_MS,\n} from './iii-constants'\nimport type { HttpInvocationConfig } from '@iii-dev/helpers/http'\nimport {\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n type JsonValue,\n MessageType,\n type RegisterFunctionMessage,\n type RegistrationRejectedMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/helpers/observability'\nimport { getMeter, getTracer } from '@iii-dev/helpers/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/helpers/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n IIIClient,\n Invocation,\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\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker\n * already holds this `(namespace, worker_name)`. The engine closes the\n * connection -- fatal.\n */\nconst WORKER_NAMESPACE_CONFLICT = 'WORKER_NAMESPACE_CONFLICT'\n\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker in\n * this namespace already exports this one function id. The connection stays\n * open -- non-fatal.\n */\nconst FUNCTION_NAMESPACE_CONFLICT = 'FUNCTION_NAMESPACE_CONFLICT'\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n // III_WORKER_NAME carries the config.yaml entry name for managed workers\n // (set by iii-worker at spawn). Engine truth (`iii worker status`/`list`)\n // matches connections by name, so the managed identity must win over the\n // hostname:pid fallback.\n const managedName = process.env.III_WORKER_NAME\n if (managedName) {\n return managedName\n }\n return `${os.hostname()}:${process.pid}`\n}\n\n/**\n * Engine address used when neither an explicit address nor `III_URL` is set.\n * The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`\n * on a host whose engine only listens on IPv4.\n */\nexport const DEFAULT_ENGINE_URL = 'ws://127.0.0.1:49134'\n\nfunction resolveAddress(address?: string): string {\n // The supervisor that spawned this process -- `iii compose`, a container\n // runtime, systemd -- sets III_URL, the same way it sets III_NAMESPACE and\n // III_WORKER_NAME. An explicit address still wins.\n if (address) {\n return address\n }\n const fromEnv = process.env.III_URL\n if (fromEnv) {\n return fromEnv\n }\n return DEFAULT_ENGINE_URL\n}\n\nfunction resolveNamespace(optionNamespace?: string): string | undefined {\n // III_NAMESPACE carries the namespace for managed workers (set by iii-worker\n // at spawn), mirroring III_WORKER_NAME. An explicit option wins; otherwise\n // the env var provides the managed identity. Absent in both means undefined\n // -- the engine applies its `default` namespace when none is on the wire.\n if (optionNamespace) {\n return optionNamespace\n }\n const managedNamespace = process.env.III_NAMESPACE\n if (managedNamespace) {\n return managedNamespace\n }\n return undefined\n}\n\n/** Worker metadata reported to the engine (language, framework, project). */\nexport type TelemetryOptions = {\n /** Programming language of the worker. */\n language?: string\n /** Name of the project this worker belongs to. */\n project_name?: string\n /** Framework name, if applicable. */\n framework?: string\n /** Amplitude API key for product analytics. */\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const worker = 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 /**\n * Namespace this worker registers under. Resolution order:\n * `options.namespace` -> `process.env.III_NAMESPACE` -> undefined. When\n * undefined the engine applies its `default` namespace. Scopes worker and\n * function registrations so identically-named entries can coexist across\n * namespaces.\n */\n namespace?: string\n /**\n * One-line, human/LLM-readable summary of what this worker does.\n * Surfaces in `engine::workers::list` / `engine::workers::info`.\n */\n workerDescription?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `worker.trigger()` invocations 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 IIIClient {\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 namespace?: string\n private workerDescription?: string\n private workerId?: string\n private reattachToken?: string\n private reconnectTimeout?: NodeJS.Timeout\n private heartbeatInterval?: NodeJS.Timeout\n private idleTimeout?: 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 // Set when the engine fatally rejects this worker's registration (e.g. a\n // namespace/name collision). Terminal: no reconnect follows. Mirrors the\n // Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n private fatalError?: RegistrationRejectedError\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.namespace = resolveNamespace(options?.namespace)\n this.workerDescription = options?.workerDescription\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 * worker.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 // This typed helper pairs a function with its trigger, so it defaults the\n // trigger's namespace to this worker's — otherwise the function would land\n // in the worker's namespace and the trigger in `default`, and never resolve\n // it. The low-level `registerTrigger` keeps the engine default (`default`).\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 namespace: this.namespace,\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 namespace: this.namespace,\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 = worker.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 = worker.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, metadata?: JsonValue, 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, metadata)\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 // INTERNAL and named `execute` (not `call`/`trigger`): the engine\n // suppresses its own `call <fn>` span for worker-routed functions\n // (this span is the canonical one for the invocation) but still\n // emits engine-side wrappers like `trigger <fn>` from fire_triggers\n // and `call <fn>` for builtins. Reusing those names would read as\n // duplicate engine spans under the worker's service. `execute` is\n // unique, so the worker handler span reads as a clean internal\n // child (and is collapsible by a single rule).\n return context.with(parentContext, () =>\n withSpan(`execute ${functionId}`, { kind: SpanKind.INTERNAL }, 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 * @internal Implementation backing the `createChannel` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\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 __helpers_create_channel = 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 * @param request.metadata - Optional per-invocation metadata (arbitrary JSON)\n * surfaced to the target handler as its second argument.\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 worker.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await worker.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 * worker.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n // biome-ignore lint/suspicious/noExplicitAny: TOutput defaults to any so untyped calls type-check (the engine cannot express the return type statically)\n trigger = async <TInput = unknown, TOutput = any>(\n request: TriggerRequest<TInput>,\n ): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs, metadata, namespace } = 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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 InvocationError({\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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 description: this.workerDescription,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n // Omit when absent so the engine falls back to its `default` namespace.\n ...(this.namespace !== undefined ? { namespace: this.namespace } : {}),\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 * @internal Implementation backing the `createStream` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\n *\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name. Registers 5 of the 6 `IStream` methods\n * (`get`, `set`, `delete`, `list`, `listGroups`). The `update` method is\n * not registered; atomic updates are handled by the engine's built-in\n * stream update logic.\n */\n __helpers_create_stream = <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 * The current WebSocket connection state. `'failed'` is terminal — it follows\n * a fatal registration rejection (see {@link getFatalError}). Mirrors the\n * Python/Rust SDKs' `get_connection_state()`.\n */\n getConnectionState = (): IIIConnectionState => this.connectionState\n\n /**\n * Engine address this worker resolved to: the explicit argument, else\n * `III_URL`, else {@link DEFAULT_ENGINE_URL}. Mirrors the Rust SDK's\n * `address()` and the Python SDK's `get_address()`.\n */\n getAddress = (): string => this.address\n\n /**\n * The fatal registration rejection that terminated this connection, if any\n * (e.g. a `WORKER_NAMESPACE_CONFLICT`). `undefined` while healthy. Mirrors the\n * Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n */\n getFatalError = (): RegistrationRejectedError | undefined => this.fatalError\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 and keepalive heartbeat (shutdown never\n // reaches onSocketClose: listeners are removed before close() below)\n this.clearReconnectTimeout()\n this.stopHeartbeat()\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, {\n headers: this.options?.headers,\n handshakeTimeout: WS_HANDSHAKE_TIMEOUT_MS,\n })\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 startHeartbeat(): void {\n this.stopHeartbeat()\n // Dedicated deadline, refresh()ed on every inbound frame, so it fires\n // exactly WS_IDLE_TIMEOUT_MS after the last frame instead of on the next\n // ping tick (which could add up to a full WS_PING_INTERVAL_MS of delay).\n this.idleTimeout = setTimeout(() => {\n this.logError(`No inbound data for ${WS_IDLE_TIMEOUT_MS}ms, terminating connection to force reconnect`)\n this.ws?.terminate() // 'close' fires -> onSocketClose stops the heartbeat and schedules reconnect\n }, WS_IDLE_TIMEOUT_MS)\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.isOpen()) {\n this.ws.ping()\n }\n }, WS_PING_INTERVAL_MS)\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = undefined\n }\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout)\n this.idleTimeout = 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.stopHeartbeat()\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 // Reset the idle deadline on any inbound frame (message/ping/pong), Rust SDK parity\n const touch = () => {\n this.idleTimeout?.refresh()\n }\n this.ws?.on('message', touch)\n this.ws?.on('ping', touch)\n this.ws?.on('pong', touch)\n this.startHeartbeat()\n\n // Reconnect: present the previous engine-assigned identity BEFORE the\n // metadata announce and registration replay so the engine retires the old\n // connection and the replay lands on a clean slate instead of racing its\n // cleanup. This must precede registerWorkerMetadata(): otherwise the old\n // connection still holds this (namespace, worker_name) and the announce\n // would trip WORKER_NAMESPACE_CONFLICT against ourselves. The token proves\n // we ARE that worker (ids alone are publicly listable).\n if (this.workerId) {\n this.sendMessageRaw(\n JSON.stringify({\n type: MessageType.Reattach,\n previous_worker_id: this.workerId,\n reattach_token: this.reattachToken,\n }),\n )\n }\n\n // Announce worker metadata (carrying the namespace) before flushing any\n // registrations so the engine knows this connection's namespace up front.\n this.registerWorkerMetadata()\n\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\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 logWarn(message: string): void {\n const otelLogger = getLogger()\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.WARN,\n body: `[iii] ${message}`,\n })\n } else {\n console.warn(`[iii] ${message}`)\n }\n }\n\n /**\n * Handle a `registrationrejected` from the engine. The `code` decides the\n * severity:\n *\n * - {@link WORKER_NAMESPACE_CONFLICT}: another live worker already holds this\n * `(namespace, worker_name)`. The engine closes the connection, so this is\n * fatal -- stop the worker, do not reconnect, and surface a\n * {@link RegistrationRejectedError} to every pending invocation.\n * - {@link FUNCTION_NAMESPACE_CONFLICT}: another live worker in this namespace\n * already exports this one function id. Only that registration is refused;\n * the engine keeps the connection open and the worker keeps serving its\n * other functions. Non-fatal -- log a warning and continue. Here\n * `worker_name` carries the contested function id (the engine reuses the\n * struct).\n * - Any other code: treated as fatal (safe default).\n */\n private onRegistrationRejected(init: {\n code: string\n namespace: string\n worker_name: string\n owner_worker_id: string\n }): void {\n if (init.code === FUNCTION_NAMESPACE_CONFLICT) {\n this.logWarn(\n `Function registration rejected: function \"${init.worker_name}\" in namespace \"${init.namespace}\" is already exported by worker ${init.owner_worker_id}. The worker stays connected and keeps serving its other functions.`,\n )\n return\n }\n\n const error = new RegistrationRejectedError(init)\n // Record it so callers can poll for the terminal cause (parity with the\n // Python/Rust SDKs); the connection also transitions to `failed` below.\n this.fatalError = error\n if (init.code === WORKER_NAMESPACE_CONFLICT) {\n this.logError('Registration rejected by engine', error)\n } else {\n this.logError(`Registration rejected by engine with unknown code \"${init.code}\"; treating as fatal`, error)\n }\n\n // Mark shutdown first so neither onSocketClose nor scheduleReconnect can\n // schedule a reconnect for a rejection that would only be rejected again.\n this.isShuttingDown = true\n this.clearReconnectTimeout()\n this.stopHeartbeat()\n\n // Reject every in-flight invocation with the fatal error.\n for (const [, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(error)\n }\n this.invocations.clear()\n\n // Tear down the socket without triggering the reconnect path.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.terminate()\n } catch {\n // ignore, stopping anyway\n }\n this.ws = undefined\n }\n\n this.stopMetricsReporting()\n this.setConnectionState('failed')\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 InvocationError} 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 InvocationError({\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 InvocationError({\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 metadata?: JsonValue,\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, metadata, 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, metadata, 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: {\n trigger_type: string\n id: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n namespace?: string\n }) {\n const { trigger_type, id, function_id, config, metadata, namespace } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n // Surface the namespace to the handler: a provider that fires the target\n // later needs it to resolve in the right namespace, not `default`.\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata, namespace })\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 async onUnregisterTrigger(message: {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n }) {\n const trigger_type = message.trigger_type\n if (!trigger_type) return\n\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n if (!triggerTypeData) return\n\n const { id, function_id = '', config, metadata } = message\n try {\n await triggerTypeData.handler.unregisterTrigger({ id, function_id, config, metadata })\n } catch (error) {\n this.logError(`Error unregistering trigger ${id}`, error)\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, metadata, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, metadata, 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.UnregisterTrigger) {\n this.onUnregisterTrigger(\n message as {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n },\n )\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, reattach_token } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n this.reattachToken = reattach_token\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n } else if (msgType === MessageType.RegistrationRejected) {\n const { code, namespace, worker_name, owner_worker_id } = message as RegistrationRejectedMessage\n this.onRegistrationRejected({ code, namespace, worker_name, owner_worker_id })\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link IIIClient.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * worker.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * worker.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 * Requires a queue worker in the project. Run `iii worker add queue`.\n * Without it the trigger rejects with `enqueue_error` (no queue provider).\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }) => ({ type: 'enqueue' as const, ...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: () => ({ type: 'void' as const }),\n} as const\n\n/**\n * Register the worker with a iii instance, returns a connected worker client.\n * The WebSocket connection is established automatically.\n *\n * @param address - WebSocket URL of the III engine. Omit to resolve it from\n * `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link IIIClient} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * // Address from III_URL, set by whatever supervisor spawned this worker.\n * const worker = registerWorker()\n *\n * // Or explicitly, which always wins over the environment.\n * const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })\n * ```\n */\nexport const registerWorker = (address?: string, options?: InitOptions): IIIClient =>\n new Sdk(resolveAddress(address), options)\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { D as MiddlewareFunctionInput, T as JsonValue, d as StreamResponse, r as IIIClient, u as StreamRequest, v as IIIConnectionState, y as IIIReconnectionConfig } from "./types-
|
|
1
|
+
import { D as MiddlewareFunctionInput, T as JsonValue, d as StreamResponse, r as IIIClient, u as StreamRequest, v as IIIConnectionState, y as IIIReconnectionConfig } from "./types-C43VHoZq.cjs";
|
|
2
2
|
import { n as InvocationErrorInit, r as RegistrationRejectedError, t as InvocationError } from "./errors-CKW836UA.cjs";
|
|
3
3
|
import { OtelConfig } from "@iii-dev/helpers/observability";
|
|
4
4
|
import { EnqueueResult } from "@iii-dev/helpers/queue";
|
|
5
5
|
|
|
6
6
|
//#region src/iii.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Engine address used when neither an explicit address nor `III_URL` is set.
|
|
9
|
+
* The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`
|
|
10
|
+
* on a host whose engine only listens on IPv4.
|
|
11
|
+
*/
|
|
12
|
+
declare const DEFAULT_ENGINE_URL = "ws://127.0.0.1:49134";
|
|
7
13
|
/** Worker metadata reported to the engine (language, framework, project). */
|
|
8
14
|
type TelemetryOptions = {
|
|
9
15
|
/** Programming language of the worker. */language?: string; /** Name of the project this worker belongs to. */
|
|
@@ -107,7 +113,8 @@ declare const TriggerAction: {
|
|
|
107
113
|
* Register the worker with a iii instance, returns a connected worker client.
|
|
108
114
|
* The WebSocket connection is established automatically.
|
|
109
115
|
*
|
|
110
|
-
* @param address - WebSocket URL of the III engine
|
|
116
|
+
* @param address - WebSocket URL of the III engine. Omit to resolve it from
|
|
117
|
+
* `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.
|
|
111
118
|
* @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.
|
|
112
119
|
* @returns A connected {@link IIIClient} instance.
|
|
113
120
|
*
|
|
@@ -115,12 +122,14 @@ declare const TriggerAction: {
|
|
|
115
122
|
* ```typescript
|
|
116
123
|
* import { registerWorker } from 'iii-sdk'
|
|
117
124
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
125
|
+
* // Address from III_URL, set by whatever supervisor spawned this worker.
|
|
126
|
+
* const worker = registerWorker()
|
|
127
|
+
*
|
|
128
|
+
* // Or explicitly, which always wins over the environment.
|
|
129
|
+
* const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })
|
|
121
130
|
* ```
|
|
122
131
|
*/
|
|
123
|
-
declare const registerWorker: (address
|
|
132
|
+
declare const registerWorker: (address?: string, options?: InitOptions) => IIIClient;
|
|
124
133
|
//#endregion
|
|
125
|
-
export { type EnqueueResult, type IIIClient, type IIIConnectionState, type InitOptions, InvocationError, type InvocationErrorInit, type JsonValue, type MiddlewareFunctionInput, RegistrationRejectedError, type StreamRequest, type StreamResponse, type TelemetryOptions, TriggerAction, registerWorker };
|
|
134
|
+
export { DEFAULT_ENGINE_URL, type EnqueueResult, type IIIClient, type IIIConnectionState, type InitOptions, InvocationError, type InvocationErrorInit, type JsonValue, type MiddlewareFunctionInput, RegistrationRejectedError, type StreamRequest, type StreamResponse, type TelemetryOptions, TriggerAction, registerWorker };
|
|
126
135
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/iii.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/iii.ts"],"mappings":";;;;;;;;;AAuGA;;cAAa,kBAAA;;KAgCD,gBAAA;EAAA,0CAEV,QAAA;EAEA,YAAA,WAFA;EAIA,SAAA;EAEA,iBAAA;AAAA;;AAeF;;;;;;;;;;;KAAY,WAAA;EAUV,gEARA,UAAA;EAeA;;;;;;;EAPA,SAAA;EAuBA;;;;EAlBA,iBAAA,WAoB4B;EAlB5B,sBAAA,YAqqCQ;EAnqCR,mBAAA;EAmqCQ;;;;;EA7pCR,kBAAA,GAAqB,OAAA,CAAQ,qBAAA;;;;;AAmrC/B;EA7qCE,IAAA,GAAO,IAAA,CAAK,UAAA;EAEZ,OAAA,GAAU,MAAA,kBA2qCmB;EAzqC7B,SAAA,GAAY,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;cAioCD,aAAA;;;;;;;;;;;;;IAYO,KAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BP,cAAA,GAAkB,OAAA,WAAkB,OAAA,GAAU,WAAA,KAAc,SAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { D as MiddlewareFunctionInput, T as JsonValue, d as StreamResponse, r as IIIClient, u as StreamRequest, v as IIIConnectionState, y as IIIReconnectionConfig } from "./types-
|
|
1
|
+
import { D as MiddlewareFunctionInput, T as JsonValue, d as StreamResponse, r as IIIClient, u as StreamRequest, v as IIIConnectionState, y as IIIReconnectionConfig } from "./types-CPReRK1z.mjs";
|
|
2
2
|
import { n as InvocationErrorInit, r as RegistrationRejectedError, t as InvocationError } from "./errors-DQVZBqCr.mjs";
|
|
3
3
|
import { OtelConfig } from "@iii-dev/helpers/observability";
|
|
4
4
|
import { EnqueueResult } from "@iii-dev/helpers/queue";
|
|
5
5
|
|
|
6
6
|
//#region src/iii.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Engine address used when neither an explicit address nor `III_URL` is set.
|
|
9
|
+
* The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`
|
|
10
|
+
* on a host whose engine only listens on IPv4.
|
|
11
|
+
*/
|
|
12
|
+
declare const DEFAULT_ENGINE_URL = "ws://127.0.0.1:49134";
|
|
7
13
|
/** Worker metadata reported to the engine (language, framework, project). */
|
|
8
14
|
type TelemetryOptions = {
|
|
9
15
|
/** Programming language of the worker. */language?: string; /** Name of the project this worker belongs to. */
|
|
@@ -107,7 +113,8 @@ declare const TriggerAction: {
|
|
|
107
113
|
* Register the worker with a iii instance, returns a connected worker client.
|
|
108
114
|
* The WebSocket connection is established automatically.
|
|
109
115
|
*
|
|
110
|
-
* @param address - WebSocket URL of the III engine
|
|
116
|
+
* @param address - WebSocket URL of the III engine. Omit to resolve it from
|
|
117
|
+
* `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.
|
|
111
118
|
* @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.
|
|
112
119
|
* @returns A connected {@link IIIClient} instance.
|
|
113
120
|
*
|
|
@@ -115,12 +122,14 @@ declare const TriggerAction: {
|
|
|
115
122
|
* ```typescript
|
|
116
123
|
* import { registerWorker } from 'iii-sdk'
|
|
117
124
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
125
|
+
* // Address from III_URL, set by whatever supervisor spawned this worker.
|
|
126
|
+
* const worker = registerWorker()
|
|
127
|
+
*
|
|
128
|
+
* // Or explicitly, which always wins over the environment.
|
|
129
|
+
* const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })
|
|
121
130
|
* ```
|
|
122
131
|
*/
|
|
123
|
-
declare const registerWorker: (address
|
|
132
|
+
declare const registerWorker: (address?: string, options?: InitOptions) => IIIClient;
|
|
124
133
|
//#endregion
|
|
125
|
-
export { type EnqueueResult, type IIIClient, type IIIConnectionState, type InitOptions, InvocationError, type InvocationErrorInit, type JsonValue, type MiddlewareFunctionInput, RegistrationRejectedError, type StreamRequest, type StreamResponse, type TelemetryOptions, TriggerAction, registerWorker };
|
|
134
|
+
export { DEFAULT_ENGINE_URL, type EnqueueResult, type IIIClient, type IIIConnectionState, type InitOptions, InvocationError, type InvocationErrorInit, type JsonValue, type MiddlewareFunctionInput, RegistrationRejectedError, type StreamRequest, type StreamResponse, type TelemetryOptions, TriggerAction, registerWorker };
|
|
126
135
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/iii.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/iii.ts"],"mappings":";;;;;;;;;AAuGA;;cAAa,kBAAA;;KAgCD,gBAAA;EAAA,0CAEV,QAAA;EAEA,YAAA,WAFA;EAIA,SAAA;EAEA,iBAAA;AAAA;;AAeF;;;;;;;;;;;KAAY,WAAA;EAUV,gEARA,UAAA;EAeA;;;;;;;EAPA,SAAA;EAuBA;;;;EAlBA,iBAAA,WAoB4B;EAlB5B,sBAAA,YAqqCQ;EAnqCR,mBAAA;EAmqCQ;;;;;EA7pCR,kBAAA,GAAqB,OAAA,CAAQ,qBAAA;;;;;AAmrC/B;EA7qCE,IAAA,GAAO,IAAA,CAAK,UAAA;EAEZ,OAAA,GAAU,MAAA,kBA2qCmB;EAzqC7B,SAAA,GAAY,gBAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;cAioCD,aAAA;;;;;;;;;;;;;IAYO,KAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA4BP,cAAA,GAAkB,OAAA,WAAkB,OAAA,GAAU,WAAA,KAAc,SAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -32,6 +32,18 @@ function getDefaultWorkerName() {
|
|
|
32
32
|
if (managedName) return managedName;
|
|
33
33
|
return `${os.hostname()}:${process.pid}`;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Engine address used when neither an explicit address nor `III_URL` is set.
|
|
37
|
+
* The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`
|
|
38
|
+
* on a host whose engine only listens on IPv4.
|
|
39
|
+
*/
|
|
40
|
+
const DEFAULT_ENGINE_URL = "ws://127.0.0.1:49134";
|
|
41
|
+
function resolveAddress(address) {
|
|
42
|
+
if (address) return address;
|
|
43
|
+
const fromEnv = process.env.III_URL;
|
|
44
|
+
if (fromEnv) return fromEnv;
|
|
45
|
+
return DEFAULT_ENGINE_URL;
|
|
46
|
+
}
|
|
35
47
|
function resolveNamespace(optionNamespace) {
|
|
36
48
|
if (optionNamespace) return optionNamespace;
|
|
37
49
|
const managedNamespace = process.env.III_NAMESPACE;
|
|
@@ -264,6 +276,7 @@ var Sdk = class {
|
|
|
264
276
|
this.registerFunction(`stream::list_groups(${streamName})`, stream.listGroups.bind(stream));
|
|
265
277
|
};
|
|
266
278
|
this.getConnectionState = () => this.connectionState;
|
|
279
|
+
this.getAddress = () => this.address;
|
|
267
280
|
this.getFatalError = () => this.fatalError;
|
|
268
281
|
this.shutdown = async () => {
|
|
269
282
|
this.isShuttingDown = true;
|
|
@@ -781,7 +794,8 @@ const TriggerAction = {
|
|
|
781
794
|
* Register the worker with a iii instance, returns a connected worker client.
|
|
782
795
|
* The WebSocket connection is established automatically.
|
|
783
796
|
*
|
|
784
|
-
* @param address - WebSocket URL of the III engine
|
|
797
|
+
* @param address - WebSocket URL of the III engine. Omit to resolve it from
|
|
798
|
+
* `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.
|
|
785
799
|
* @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.
|
|
786
800
|
* @returns A connected {@link IIIClient} instance.
|
|
787
801
|
*
|
|
@@ -789,13 +803,15 @@ const TriggerAction = {
|
|
|
789
803
|
* ```typescript
|
|
790
804
|
* import { registerWorker } from 'iii-sdk'
|
|
791
805
|
*
|
|
792
|
-
*
|
|
793
|
-
*
|
|
794
|
-
*
|
|
806
|
+
* // Address from III_URL, set by whatever supervisor spawned this worker.
|
|
807
|
+
* const worker = registerWorker()
|
|
808
|
+
*
|
|
809
|
+
* // Or explicitly, which always wins over the environment.
|
|
810
|
+
* const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })
|
|
795
811
|
* ```
|
|
796
812
|
*/
|
|
797
|
-
const registerWorker = (address, options) => new Sdk(address, options);
|
|
813
|
+
const registerWorker = (address, options) => new Sdk(resolveAddress(address), options);
|
|
798
814
|
|
|
799
815
|
//#endregion
|
|
800
|
-
export { InvocationError, RegistrationRejectedError, TriggerAction, registerWorker };
|
|
816
|
+
export { DEFAULT_ENGINE_URL, InvocationError, RegistrationRejectedError, TriggerAction, registerWorker };
|
|
801
817
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/iii.ts"],"sourcesContent":["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 { InvocationError, isErrorBody, RegistrationRejectedError } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n WS_HANDSHAKE_TIMEOUT_MS,\n WS_IDLE_TIMEOUT_MS,\n WS_PING_INTERVAL_MS,\n} from './iii-constants'\nimport type { HttpInvocationConfig } from '@iii-dev/helpers/http'\nimport {\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n type JsonValue,\n MessageType,\n type RegisterFunctionMessage,\n type RegistrationRejectedMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/helpers/observability'\nimport { getMeter, getTracer } from '@iii-dev/helpers/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/helpers/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n IIIClient,\n Invocation,\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\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker\n * already holds this `(namespace, worker_name)`. The engine closes the\n * connection -- fatal.\n */\nconst WORKER_NAMESPACE_CONFLICT = 'WORKER_NAMESPACE_CONFLICT'\n\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker in\n * this namespace already exports this one function id. The connection stays\n * open -- non-fatal.\n */\nconst FUNCTION_NAMESPACE_CONFLICT = 'FUNCTION_NAMESPACE_CONFLICT'\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n // III_WORKER_NAME carries the config.yaml entry name for managed workers\n // (set by iii-worker at spawn). Engine truth (`iii worker status`/`list`)\n // matches connections by name, so the managed identity must win over the\n // hostname:pid fallback.\n const managedName = process.env.III_WORKER_NAME\n if (managedName) {\n return managedName\n }\n return `${os.hostname()}:${process.pid}`\n}\n\nfunction resolveNamespace(optionNamespace?: string): string | undefined {\n // III_NAMESPACE carries the namespace for managed workers (set by iii-worker\n // at spawn), mirroring III_WORKER_NAME. An explicit option wins; otherwise\n // the env var provides the managed identity. Absent in both means undefined\n // -- the engine applies its `default` namespace when none is on the wire.\n if (optionNamespace) {\n return optionNamespace\n }\n const managedNamespace = process.env.III_NAMESPACE\n if (managedNamespace) {\n return managedNamespace\n }\n return undefined\n}\n\n/** Worker metadata reported to the engine (language, framework, project). */\nexport type TelemetryOptions = {\n /** Programming language of the worker. */\n language?: string\n /** Name of the project this worker belongs to. */\n project_name?: string\n /** Framework name, if applicable. */\n framework?: string\n /** Amplitude API key for product analytics. */\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const worker = 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 /**\n * Namespace this worker registers under. Resolution order:\n * `options.namespace` -> `process.env.III_NAMESPACE` -> undefined. When\n * undefined the engine applies its `default` namespace. Scopes worker and\n * function registrations so identically-named entries can coexist across\n * namespaces.\n */\n namespace?: string\n /**\n * One-line, human/LLM-readable summary of what this worker does.\n * Surfaces in `engine::workers::list` / `engine::workers::info`.\n */\n workerDescription?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `worker.trigger()` invocations 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 IIIClient {\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 namespace?: string\n private workerDescription?: string\n private workerId?: string\n private reattachToken?: string\n private reconnectTimeout?: NodeJS.Timeout\n private heartbeatInterval?: NodeJS.Timeout\n private idleTimeout?: 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 // Set when the engine fatally rejects this worker's registration (e.g. a\n // namespace/name collision). Terminal: no reconnect follows. Mirrors the\n // Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n private fatalError?: RegistrationRejectedError\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.namespace = resolveNamespace(options?.namespace)\n this.workerDescription = options?.workerDescription\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 * worker.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 // This typed helper pairs a function with its trigger, so it defaults the\n // trigger's namespace to this worker's — otherwise the function would land\n // in the worker's namespace and the trigger in `default`, and never resolve\n // it. The low-level `registerTrigger` keeps the engine default (`default`).\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 namespace: this.namespace,\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 namespace: this.namespace,\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 = worker.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 = worker.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, metadata?: JsonValue, 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, metadata)\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 // INTERNAL and named `execute` (not `call`/`trigger`): the engine\n // suppresses its own `call <fn>` span for worker-routed functions\n // (this span is the canonical one for the invocation) but still\n // emits engine-side wrappers like `trigger <fn>` from fire_triggers\n // and `call <fn>` for builtins. Reusing those names would read as\n // duplicate engine spans under the worker's service. `execute` is\n // unique, so the worker handler span reads as a clean internal\n // child (and is collapsible by a single rule).\n return context.with(parentContext, () =>\n withSpan(`execute ${functionId}`, { kind: SpanKind.INTERNAL }, 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 * @internal Implementation backing the `createChannel` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\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 __helpers_create_channel = 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 * @param request.metadata - Optional per-invocation metadata (arbitrary JSON)\n * surfaced to the target handler as its second argument.\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 worker.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await worker.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 * worker.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n // biome-ignore lint/suspicious/noExplicitAny: TOutput defaults to any so untyped calls type-check (the engine cannot express the return type statically)\n trigger = async <TInput = unknown, TOutput = any>(\n request: TriggerRequest<TInput>,\n ): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs, metadata, namespace } = 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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 InvocationError({\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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 description: this.workerDescription,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n // Omit when absent so the engine falls back to its `default` namespace.\n ...(this.namespace !== undefined ? { namespace: this.namespace } : {}),\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 * @internal Implementation backing the `createStream` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\n *\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name. Registers 5 of the 6 `IStream` methods\n * (`get`, `set`, `delete`, `list`, `listGroups`). The `update` method is\n * not registered; atomic updates are handled by the engine's built-in\n * stream update logic.\n */\n __helpers_create_stream = <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 * The current WebSocket connection state. `'failed'` is terminal — it follows\n * a fatal registration rejection (see {@link getFatalError}). Mirrors the\n * Python/Rust SDKs' `get_connection_state()`.\n */\n getConnectionState = (): IIIConnectionState => this.connectionState\n\n /**\n * The fatal registration rejection that terminated this connection, if any\n * (e.g. a `WORKER_NAMESPACE_CONFLICT`). `undefined` while healthy. Mirrors the\n * Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n */\n getFatalError = (): RegistrationRejectedError | undefined => this.fatalError\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 and keepalive heartbeat (shutdown never\n // reaches onSocketClose: listeners are removed before close() below)\n this.clearReconnectTimeout()\n this.stopHeartbeat()\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, {\n headers: this.options?.headers,\n handshakeTimeout: WS_HANDSHAKE_TIMEOUT_MS,\n })\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 startHeartbeat(): void {\n this.stopHeartbeat()\n // Dedicated deadline, refresh()ed on every inbound frame, so it fires\n // exactly WS_IDLE_TIMEOUT_MS after the last frame instead of on the next\n // ping tick (which could add up to a full WS_PING_INTERVAL_MS of delay).\n this.idleTimeout = setTimeout(() => {\n this.logError(`No inbound data for ${WS_IDLE_TIMEOUT_MS}ms, terminating connection to force reconnect`)\n this.ws?.terminate() // 'close' fires -> onSocketClose stops the heartbeat and schedules reconnect\n }, WS_IDLE_TIMEOUT_MS)\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.isOpen()) {\n this.ws.ping()\n }\n }, WS_PING_INTERVAL_MS)\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = undefined\n }\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout)\n this.idleTimeout = 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.stopHeartbeat()\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 // Reset the idle deadline on any inbound frame (message/ping/pong), Rust SDK parity\n const touch = () => {\n this.idleTimeout?.refresh()\n }\n this.ws?.on('message', touch)\n this.ws?.on('ping', touch)\n this.ws?.on('pong', touch)\n this.startHeartbeat()\n\n // Reconnect: present the previous engine-assigned identity BEFORE the\n // metadata announce and registration replay so the engine retires the old\n // connection and the replay lands on a clean slate instead of racing its\n // cleanup. This must precede registerWorkerMetadata(): otherwise the old\n // connection still holds this (namespace, worker_name) and the announce\n // would trip WORKER_NAMESPACE_CONFLICT against ourselves. The token proves\n // we ARE that worker (ids alone are publicly listable).\n if (this.workerId) {\n this.sendMessageRaw(\n JSON.stringify({\n type: MessageType.Reattach,\n previous_worker_id: this.workerId,\n reattach_token: this.reattachToken,\n }),\n )\n }\n\n // Announce worker metadata (carrying the namespace) before flushing any\n // registrations so the engine knows this connection's namespace up front.\n this.registerWorkerMetadata()\n\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\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 logWarn(message: string): void {\n const otelLogger = getLogger()\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.WARN,\n body: `[iii] ${message}`,\n })\n } else {\n console.warn(`[iii] ${message}`)\n }\n }\n\n /**\n * Handle a `registrationrejected` from the engine. The `code` decides the\n * severity:\n *\n * - {@link WORKER_NAMESPACE_CONFLICT}: another live worker already holds this\n * `(namespace, worker_name)`. The engine closes the connection, so this is\n * fatal -- stop the worker, do not reconnect, and surface a\n * {@link RegistrationRejectedError} to every pending invocation.\n * - {@link FUNCTION_NAMESPACE_CONFLICT}: another live worker in this namespace\n * already exports this one function id. Only that registration is refused;\n * the engine keeps the connection open and the worker keeps serving its\n * other functions. Non-fatal -- log a warning and continue. Here\n * `worker_name` carries the contested function id (the engine reuses the\n * struct).\n * - Any other code: treated as fatal (safe default).\n */\n private onRegistrationRejected(init: {\n code: string\n namespace: string\n worker_name: string\n owner_worker_id: string\n }): void {\n if (init.code === FUNCTION_NAMESPACE_CONFLICT) {\n this.logWarn(\n `Function registration rejected: function \"${init.worker_name}\" in namespace \"${init.namespace}\" is already exported by worker ${init.owner_worker_id}. The worker stays connected and keeps serving its other functions.`,\n )\n return\n }\n\n const error = new RegistrationRejectedError(init)\n // Record it so callers can poll for the terminal cause (parity with the\n // Python/Rust SDKs); the connection also transitions to `failed` below.\n this.fatalError = error\n if (init.code === WORKER_NAMESPACE_CONFLICT) {\n this.logError('Registration rejected by engine', error)\n } else {\n this.logError(`Registration rejected by engine with unknown code \"${init.code}\"; treating as fatal`, error)\n }\n\n // Mark shutdown first so neither onSocketClose nor scheduleReconnect can\n // schedule a reconnect for a rejection that would only be rejected again.\n this.isShuttingDown = true\n this.clearReconnectTimeout()\n this.stopHeartbeat()\n\n // Reject every in-flight invocation with the fatal error.\n for (const [, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(error)\n }\n this.invocations.clear()\n\n // Tear down the socket without triggering the reconnect path.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.terminate()\n } catch {\n // ignore, stopping anyway\n }\n this.ws = undefined\n }\n\n this.stopMetricsReporting()\n this.setConnectionState('failed')\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 InvocationError} 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 InvocationError({\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 InvocationError({\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 metadata?: JsonValue,\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, metadata, 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, metadata, 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: {\n trigger_type: string\n id: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n namespace?: string\n }) {\n const { trigger_type, id, function_id, config, metadata, namespace } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n // Surface the namespace to the handler: a provider that fires the target\n // later needs it to resolve in the right namespace, not `default`.\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata, namespace })\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 async onUnregisterTrigger(message: {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n }) {\n const trigger_type = message.trigger_type\n if (!trigger_type) return\n\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n if (!triggerTypeData) return\n\n const { id, function_id = '', config, metadata } = message\n try {\n await triggerTypeData.handler.unregisterTrigger({ id, function_id, config, metadata })\n } catch (error) {\n this.logError(`Error unregistering trigger ${id}`, error)\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, metadata, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, metadata, 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.UnregisterTrigger) {\n this.onUnregisterTrigger(\n message as {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n },\n )\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, reattach_token } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n this.reattachToken = reattach_token\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n } else if (msgType === MessageType.RegistrationRejected) {\n const { code, namespace, worker_name, owner_worker_id } = message as RegistrationRejectedMessage\n this.onRegistrationRejected({ code, namespace, worker_name, owner_worker_id })\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link IIIClient.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * worker.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * worker.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 * Requires a queue worker in the project. Run `iii worker add queue`.\n * Without it the trigger rejects with `enqueue_error` (no queue provider).\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }) => ({ type: 'enqueue' as const, ...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: () => ({ type: 'void' as const }),\n} as const\n\n/**\n * Register the worker with a iii instance, returns a connected worker client.\n * The WebSocket connection is established automatically.\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 IIIClient} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * const worker = registerWorker(process.env.III_URL ?? 'ws://localhost:49134', {\n * workerName: 'my-worker',\n * })\n * ```\n */\nexport const registerWorker = (address: string, options?: InitOptions): IIIClient => new Sdk(address, options)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/iii.ts"],"sourcesContent":["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 { InvocationError, isErrorBody, RegistrationRejectedError } from './errors'\nimport {\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n type IIIConnectionState,\n type IIIReconnectionConfig,\n WS_HANDSHAKE_TIMEOUT_MS,\n WS_IDLE_TIMEOUT_MS,\n WS_PING_INTERVAL_MS,\n} from './iii-constants'\nimport type { HttpInvocationConfig } from '@iii-dev/helpers/http'\nimport {\n type IIIMessage,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n type JsonValue,\n MessageType,\n type RegisterFunctionMessage,\n type RegistrationRejectedMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type StreamChannelRef,\n type TriggerRegistrationResultMessage,\n type TriggerRequest,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { registerWorkerGauges, stopWorkerGauges } from '@iii-dev/helpers/observability'\nimport { getMeter, getTracer } from '@iii-dev/helpers/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/helpers/observability'\nimport type { TriggerHandler } from './triggers'\nimport type {\n FunctionRef,\n IIIClient,\n Invocation,\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\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker\n * already holds this `(namespace, worker_name)`. The engine closes the\n * connection -- fatal.\n */\nconst WORKER_NAMESPACE_CONFLICT = 'WORKER_NAMESPACE_CONFLICT'\n\n/**\n * `registrationrejected` code (engine `protocol.rs`): another live worker in\n * this namespace already exports this one function id. The connection stays\n * open -- non-fatal.\n */\nconst FUNCTION_NAMESPACE_CONFLICT = 'FUNCTION_NAMESPACE_CONFLICT'\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n // III_WORKER_NAME carries the config.yaml entry name for managed workers\n // (set by iii-worker at spawn). Engine truth (`iii worker status`/`list`)\n // matches connections by name, so the managed identity must win over the\n // hostname:pid fallback.\n const managedName = process.env.III_WORKER_NAME\n if (managedName) {\n return managedName\n }\n return `${os.hostname()}:${process.pid}`\n}\n\n/**\n * Engine address used when neither an explicit address nor `III_URL` is set.\n * The IPv4 loopback is spelled out on purpose: `localhost` can resolve to `::1`\n * on a host whose engine only listens on IPv4.\n */\nexport const DEFAULT_ENGINE_URL = 'ws://127.0.0.1:49134'\n\nfunction resolveAddress(address?: string): string {\n // The supervisor that spawned this process -- `iii compose`, a container\n // runtime, systemd -- sets III_URL, the same way it sets III_NAMESPACE and\n // III_WORKER_NAME. An explicit address still wins.\n if (address) {\n return address\n }\n const fromEnv = process.env.III_URL\n if (fromEnv) {\n return fromEnv\n }\n return DEFAULT_ENGINE_URL\n}\n\nfunction resolveNamespace(optionNamespace?: string): string | undefined {\n // III_NAMESPACE carries the namespace for managed workers (set by iii-worker\n // at spawn), mirroring III_WORKER_NAME. An explicit option wins; otherwise\n // the env var provides the managed identity. Absent in both means undefined\n // -- the engine applies its `default` namespace when none is on the wire.\n if (optionNamespace) {\n return optionNamespace\n }\n const managedNamespace = process.env.III_NAMESPACE\n if (managedNamespace) {\n return managedNamespace\n }\n return undefined\n}\n\n/** Worker metadata reported to the engine (language, framework, project). */\nexport type TelemetryOptions = {\n /** Programming language of the worker. */\n language?: string\n /** Name of the project this worker belongs to. */\n project_name?: string\n /** Framework name, if applicable. */\n framework?: string\n /** Amplitude API key for product analytics. */\n amplitude_api_key?: string\n}\n\n/**\n * Configuration options passed to {@link registerWorker}.\n *\n * @example\n * ```typescript\n * const worker = 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 /**\n * Namespace this worker registers under. Resolution order:\n * `options.namespace` -> `process.env.III_NAMESPACE` -> undefined. When\n * undefined the engine applies its `default` namespace. Scopes worker and\n * function registrations so identically-named entries can coexist across\n * namespaces.\n */\n namespace?: string\n /**\n * One-line, human/LLM-readable summary of what this worker does.\n * Surfaces in `engine::workers::list` / `engine::workers::info`.\n */\n workerDescription?: string\n /** Enable worker metrics via OpenTelemetry. Defaults to `true`. */\n enableMetricsReporting?: boolean\n /** Default timeout for `worker.trigger()` invocations 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 IIIClient {\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 namespace?: string\n private workerDescription?: string\n private workerId?: string\n private reattachToken?: string\n private reconnectTimeout?: NodeJS.Timeout\n private heartbeatInterval?: NodeJS.Timeout\n private idleTimeout?: 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 // Set when the engine fatally rejects this worker's registration (e.g. a\n // namespace/name collision). Terminal: no reconnect follows. Mirrors the\n // Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n private fatalError?: RegistrationRejectedError\n\n constructor(\n private readonly address: string,\n private readonly options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.namespace = resolveNamespace(options?.namespace)\n this.workerDescription = options?.workerDescription\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 * worker.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 // This typed helper pairs a function with its trigger, so it defaults the\n // trigger's namespace to this worker's — otherwise the function would land\n // in the worker's namespace and the trigger in `default`, and never resolve\n // it. The low-level `registerTrigger` keeps the engine default (`default`).\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 namespace: this.namespace,\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 namespace: this.namespace,\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 = worker.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 = worker.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, metadata?: JsonValue, 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, metadata)\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 // INTERNAL and named `execute` (not `call`/`trigger`): the engine\n // suppresses its own `call <fn>` span for worker-routed functions\n // (this span is the canonical one for the invocation) but still\n // emits engine-side wrappers like `trigger <fn>` from fire_triggers\n // and `call <fn>` for builtins. Reusing those names would read as\n // duplicate engine spans under the worker's service. `execute` is\n // unique, so the worker handler span reads as a clean internal\n // child (and is collapsible by a single rule).\n return context.with(parentContext, () =>\n withSpan(`execute ${functionId}`, { kind: SpanKind.INTERNAL }, 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 * @internal Implementation backing the `createChannel` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\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 __helpers_create_channel = 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 * @param request.metadata - Optional per-invocation metadata (arbitrary JSON)\n * surfaced to the target handler as its second argument.\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 worker.trigger({ function_id: 'get-order', payload: { id: '123' } })\n *\n * // Enqueue\n * const { messageReceiptId } = await worker.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 * worker.trigger({\n * function_id: 'notifications::send',\n * payload: { userId: '123' },\n * action: TriggerAction.Void(),\n * })\n * ```\n */\n // biome-ignore lint/suspicious/noExplicitAny: TOutput defaults to any so untyped calls type-check (the engine cannot express the return type statically)\n trigger = async <TInput = unknown, TOutput = any>(\n request: TriggerRequest<TInput>,\n ): Promise<TOutput> => {\n const { function_id, payload, action, timeoutMs, metadata, namespace } = 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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 InvocationError({\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 metadata,\n // Omit when absent so the engine routes within its default namespace.\n ...(namespace !== undefined ? { namespace } : {}),\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 description: this.workerDescription,\n os: getOsInfo(),\n pid: process.pid,\n isolation: process.env.III_ISOLATION || null,\n // Omit when absent so the engine falls back to its `default` namespace.\n ...(this.namespace !== undefined ? { namespace: this.namespace } : {}),\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 * @internal Implementation backing the `createStream` helper in the\n * `iii-sdk/helpers` submodule. Not part of the public `IIIClient` surface.\n *\n * Registers a custom stream implementation, overriding the engine default\n * for the given stream name. Registers 5 of the 6 `IStream` methods\n * (`get`, `set`, `delete`, `list`, `listGroups`). The `update` method is\n * not registered; atomic updates are handled by the engine's built-in\n * stream update logic.\n */\n __helpers_create_stream = <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 * The current WebSocket connection state. `'failed'` is terminal — it follows\n * a fatal registration rejection (see {@link getFatalError}). Mirrors the\n * Python/Rust SDKs' `get_connection_state()`.\n */\n getConnectionState = (): IIIConnectionState => this.connectionState\n\n /**\n * Engine address this worker resolved to: the explicit argument, else\n * `III_URL`, else {@link DEFAULT_ENGINE_URL}. Mirrors the Rust SDK's\n * `address()` and the Python SDK's `get_address()`.\n */\n getAddress = (): string => this.address\n\n /**\n * The fatal registration rejection that terminated this connection, if any\n * (e.g. a `WORKER_NAMESPACE_CONFLICT`). `undefined` while healthy. Mirrors the\n * Python (`_fatal_error`) and Rust (`fatal_error()`) SDKs.\n */\n getFatalError = (): RegistrationRejectedError | undefined => this.fatalError\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 and keepalive heartbeat (shutdown never\n // reaches onSocketClose: listeners are removed before close() below)\n this.clearReconnectTimeout()\n this.stopHeartbeat()\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, {\n headers: this.options?.headers,\n handshakeTimeout: WS_HANDSHAKE_TIMEOUT_MS,\n })\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 startHeartbeat(): void {\n this.stopHeartbeat()\n // Dedicated deadline, refresh()ed on every inbound frame, so it fires\n // exactly WS_IDLE_TIMEOUT_MS after the last frame instead of on the next\n // ping tick (which could add up to a full WS_PING_INTERVAL_MS of delay).\n this.idleTimeout = setTimeout(() => {\n this.logError(`No inbound data for ${WS_IDLE_TIMEOUT_MS}ms, terminating connection to force reconnect`)\n this.ws?.terminate() // 'close' fires -> onSocketClose stops the heartbeat and schedules reconnect\n }, WS_IDLE_TIMEOUT_MS)\n this.heartbeatInterval = setInterval(() => {\n if (this.ws && this.isOpen()) {\n this.ws.ping()\n }\n }, WS_PING_INTERVAL_MS)\n }\n\n private stopHeartbeat(): void {\n if (this.heartbeatInterval) {\n clearInterval(this.heartbeatInterval)\n this.heartbeatInterval = undefined\n }\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout)\n this.idleTimeout = 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.stopHeartbeat()\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 // Reset the idle deadline on any inbound frame (message/ping/pong), Rust SDK parity\n const touch = () => {\n this.idleTimeout?.refresh()\n }\n this.ws?.on('message', touch)\n this.ws?.on('ping', touch)\n this.ws?.on('pong', touch)\n this.startHeartbeat()\n\n // Reconnect: present the previous engine-assigned identity BEFORE the\n // metadata announce and registration replay so the engine retires the old\n // connection and the replay lands on a clean slate instead of racing its\n // cleanup. This must precede registerWorkerMetadata(): otherwise the old\n // connection still holds this (namespace, worker_name) and the announce\n // would trip WORKER_NAMESPACE_CONFLICT against ourselves. The token proves\n // we ARE that worker (ids alone are publicly listable).\n if (this.workerId) {\n this.sendMessageRaw(\n JSON.stringify({\n type: MessageType.Reattach,\n previous_worker_id: this.workerId,\n reattach_token: this.reattachToken,\n }),\n )\n }\n\n // Announce worker metadata (carrying the namespace) before flushing any\n // registrations so the engine knows this connection's namespace up front.\n this.registerWorkerMetadata()\n\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\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 logWarn(message: string): void {\n const otelLogger = getLogger()\n if (otelLogger) {\n otelLogger.emit({\n severityNumber: SeverityNumber.WARN,\n body: `[iii] ${message}`,\n })\n } else {\n console.warn(`[iii] ${message}`)\n }\n }\n\n /**\n * Handle a `registrationrejected` from the engine. The `code` decides the\n * severity:\n *\n * - {@link WORKER_NAMESPACE_CONFLICT}: another live worker already holds this\n * `(namespace, worker_name)`. The engine closes the connection, so this is\n * fatal -- stop the worker, do not reconnect, and surface a\n * {@link RegistrationRejectedError} to every pending invocation.\n * - {@link FUNCTION_NAMESPACE_CONFLICT}: another live worker in this namespace\n * already exports this one function id. Only that registration is refused;\n * the engine keeps the connection open and the worker keeps serving its\n * other functions. Non-fatal -- log a warning and continue. Here\n * `worker_name` carries the contested function id (the engine reuses the\n * struct).\n * - Any other code: treated as fatal (safe default).\n */\n private onRegistrationRejected(init: {\n code: string\n namespace: string\n worker_name: string\n owner_worker_id: string\n }): void {\n if (init.code === FUNCTION_NAMESPACE_CONFLICT) {\n this.logWarn(\n `Function registration rejected: function \"${init.worker_name}\" in namespace \"${init.namespace}\" is already exported by worker ${init.owner_worker_id}. The worker stays connected and keeps serving its other functions.`,\n )\n return\n }\n\n const error = new RegistrationRejectedError(init)\n // Record it so callers can poll for the terminal cause (parity with the\n // Python/Rust SDKs); the connection also transitions to `failed` below.\n this.fatalError = error\n if (init.code === WORKER_NAMESPACE_CONFLICT) {\n this.logError('Registration rejected by engine', error)\n } else {\n this.logError(`Registration rejected by engine with unknown code \"${init.code}\"; treating as fatal`, error)\n }\n\n // Mark shutdown first so neither onSocketClose nor scheduleReconnect can\n // schedule a reconnect for a rejection that would only be rejected again.\n this.isShuttingDown = true\n this.clearReconnectTimeout()\n this.stopHeartbeat()\n\n // Reject every in-flight invocation with the fatal error.\n for (const [, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(error)\n }\n this.invocations.clear()\n\n // Tear down the socket without triggering the reconnect path.\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.on('error', () => {})\n try {\n this.ws.terminate()\n } catch {\n // ignore, stopping anyway\n }\n this.ws = undefined\n }\n\n this.stopMetricsReporting()\n this.setConnectionState('failed')\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 InvocationError} 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 InvocationError({\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 InvocationError({\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 metadata?: JsonValue,\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, metadata, 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, metadata, 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: {\n trigger_type: string\n id: string\n function_id: string\n config: unknown\n metadata?: Record<string, unknown>\n namespace?: string\n }) {\n const { trigger_type, id, function_id, config, metadata, namespace } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n // Surface the namespace to the handler: a provider that fires the target\n // later needs it to resolve in the right namespace, not `default`.\n await triggerTypeData.handler.registerTrigger({ id, function_id, config, metadata, namespace })\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 async onUnregisterTrigger(message: {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n }) {\n const trigger_type = message.trigger_type\n if (!trigger_type) return\n\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n if (!triggerTypeData) return\n\n const { id, function_id = '', config, metadata } = message\n try {\n await triggerTypeData.handler.unregisterTrigger({ id, function_id, config, metadata })\n } catch (error) {\n this.logError(`Error unregistering trigger ${id}`, error)\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, metadata, traceparent, baggage } = message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, metadata, 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.UnregisterTrigger) {\n this.onUnregisterTrigger(\n message as {\n trigger_type?: string\n id: string\n function_id?: string\n config?: unknown\n metadata?: Record<string, unknown>\n },\n )\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, reattach_token } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n this.reattachToken = reattach_token\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n } else if (msgType === MessageType.RegistrationRejected) {\n const { code, namespace, worker_name, owner_worker_id } = message as RegistrationRejectedMessage\n this.onRegistrationRejected({ code, namespace, worker_name, owner_worker_id })\n }\n }\n}\n\n/**\n * Factory object that constructs routing actions for {@link IIIClient.trigger}.\n *\n * @example\n * ```typescript\n * import { TriggerAction } from 'iii-sdk'\n *\n * // Enqueue to a named queue\n * worker.trigger({\n * function_id: 'process',\n * payload: { data: 'hello' },\n * action: TriggerAction.Enqueue({ queue: 'jobs' }),\n * })\n *\n * // Fire-and-forget\n * worker.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 * Requires a queue worker in the project. Run `iii worker add queue`.\n * Without it the trigger rejects with `enqueue_error` (no queue provider).\n *\n * @param opts - Queue routing options.\n * @param opts.queue - Name of the target queue.\n */\n Enqueue: (opts: { queue: string }) => ({ type: 'enqueue' as const, ...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: () => ({ type: 'void' as const }),\n} as const\n\n/**\n * Register the worker with a iii instance, returns a connected worker client.\n * The WebSocket connection is established automatically.\n *\n * @param address - WebSocket URL of the III engine. Omit to resolve it from\n * `process.env.III_URL`, falling back to {@link DEFAULT_ENGINE_URL}.\n * @param options - Optional {@link InitOptions} for worker name, timeouts, reconnection, and OTel.\n * @returns A connected {@link IIIClient} instance.\n *\n * @example\n * ```typescript\n * import { registerWorker } from 'iii-sdk'\n *\n * // Address from III_URL, set by whatever supervisor spawned this worker.\n * const worker = registerWorker()\n *\n * // Or explicitly, which always wins over the environment.\n * const other = registerWorker('ws://localhost:49134', { workerName: 'my-worker' })\n * ```\n */\nexport const registerWorker = (address?: string, options?: InitOptions): IIIClient =>\n new Sdk(resolveAddress(address), options)\n"],"mappings":"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"}
|
package/dist/internal.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as InternalHttpRequest } from "./types-
|
|
1
|
+
import { i as InternalHttpRequest } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { type InternalHttpRequest };
|
package/dist/internal.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as InternalHttpRequest } from "./types-
|
|
1
|
+
import { i as InternalHttpRequest } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { type InternalHttpRequest };
|
package/dist/protocol.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as RegisterTriggerMessage, E as MessageType, N as TriggerRequest, O as RegisterFunctionFormat, a as RegisterFunctionInput, c as RegisterTriggerTypeInput, j as RegisterTriggerTypeMessage, k as RegisterFunctionMessage, o as RegisterFunctionOptions, s as RegisterTriggerInput, w as ErrorBody } from "./types-
|
|
1
|
+
import { A as RegisterTriggerMessage, E as MessageType, N as TriggerRequest, O as RegisterFunctionFormat, a as RegisterFunctionInput, c as RegisterTriggerTypeInput, j as RegisterTriggerTypeMessage, k as RegisterFunctionMessage, o as RegisterFunctionOptions, s as RegisterTriggerInput, w as ErrorBody } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { type ErrorBody, MessageType, type RegisterFunctionFormat, type RegisterFunctionInput, type RegisterFunctionMessage, type RegisterFunctionOptions, type RegisterTriggerInput, type RegisterTriggerMessage, type RegisterTriggerTypeInput, type RegisterTriggerTypeMessage, type TriggerRequest };
|
package/dist/protocol.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as RegisterTriggerMessage, E as MessageType, N as TriggerRequest, O as RegisterFunctionFormat, a as RegisterFunctionInput, c as RegisterTriggerTypeInput, j as RegisterTriggerTypeMessage, k as RegisterFunctionMessage, o as RegisterFunctionOptions, s as RegisterTriggerInput, w as ErrorBody } from "./types-
|
|
1
|
+
import { A as RegisterTriggerMessage, E as MessageType, N as TriggerRequest, O as RegisterFunctionFormat, a as RegisterFunctionInput, c as RegisterTriggerTypeInput, j as RegisterTriggerTypeMessage, k as RegisterFunctionMessage, o as RegisterFunctionOptions, s as RegisterTriggerInput, w as ErrorBody } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { type ErrorBody, MessageType, type RegisterFunctionFormat, type RegisterFunctionInput, type RegisterFunctionMessage, type RegisterFunctionOptions, type RegisterTriggerInput, type RegisterTriggerMessage, type RegisterTriggerTypeInput, type RegisterTriggerTypeMessage, type TriggerRequest };
|
package/dist/runtime.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as FunctionRef, p as TriggerTypeRef, v as IIIConnectionState } from "./types-
|
|
1
|
+
import { n as FunctionRef, p as TriggerTypeRef, v as IIIConnectionState } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { type FunctionRef, type IIIConnectionState, type TriggerTypeRef };
|
package/dist/runtime.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as FunctionRef, p as TriggerTypeRef, v as IIIConnectionState } from "./types-
|
|
1
|
+
import { n as FunctionRef, p as TriggerTypeRef, v as IIIConnectionState } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { type FunctionRef, type IIIConnectionState, type TriggerTypeRef };
|
package/dist/trigger.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { f as Trigger, h as TriggerHandler, m as TriggerConfig } from "./types-
|
|
1
|
+
import { f as Trigger, h as TriggerHandler, m as TriggerConfig } from "./types-C43VHoZq.cjs";
|
|
2
2
|
export { type Trigger, type TriggerConfig, type TriggerHandler };
|
package/dist/trigger.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { f as Trigger, h as TriggerHandler, m as TriggerConfig } from "./types-
|
|
1
|
+
import { f as Trigger, h as TriggerHandler, m as TriggerConfig } from "./types-CPReRK1z.mjs";
|
|
2
2
|
export { type Trigger, type TriggerConfig, type TriggerHandler };
|
|
@@ -505,6 +505,11 @@ interface IIIClient {
|
|
|
505
505
|
* Python/Rust SDKs' `get_connection_state()`.
|
|
506
506
|
*/
|
|
507
507
|
getConnectionState(): IIIConnectionState;
|
|
508
|
+
/**
|
|
509
|
+
* Engine address this worker resolved to: the explicit `registerWorker`
|
|
510
|
+
* argument, else `III_URL`, else `ws://127.0.0.1:49134`.
|
|
511
|
+
*/
|
|
512
|
+
getAddress(): string;
|
|
508
513
|
/**
|
|
509
514
|
* The fatal registration rejection that terminated this connection, if any
|
|
510
515
|
* (e.g. a `WORKER_NAMESPACE_CONFLICT`); `undefined` while healthy. Mirrors the
|
|
@@ -623,4 +628,4 @@ type StreamResponse = {
|
|
|
623
628
|
type StreamRequest<TBody = unknown> = Omit<InternalHttpRequest<TBody>, 'response'>;
|
|
624
629
|
//#endregion
|
|
625
630
|
export { RegisterTriggerMessage as A, ChannelWriter as C, MiddlewareFunctionInput as D, MessageType as E, StreamChannelRef as M, TriggerRequest as N, RegisterFunctionFormat as O, ChannelReader as S, JsonValue as T, EngineTriggers as _, RegisterFunctionInput as a, ChannelDirection as b, RegisterTriggerTypeInput as c, StreamResponse as d, Trigger as f, EngineFunctions as g, TriggerHandler as h, InternalHttpRequest as i, RegisterTriggerTypeMessage as j, RegisterFunctionMessage as k, RemoteFunctionHandler as l, TriggerConfig as m, FunctionRef as n, RegisterFunctionOptions as o, TriggerTypeRef as p, IIIClient as r, RegisterTriggerInput as s, Channel as t, StreamRequest as u, IIIConnectionState as v, ErrorBody as w, ChannelItem as x, IIIReconnectionConfig as y };
|
|
626
|
-
//# sourceMappingURL=types-
|
|
631
|
+
//# sourceMappingURL=types-C43VHoZq.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-
|
|
1
|
+
{"version":3,"file":"types-C43VHoZq.d.cts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts"],"mappings":"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"}
|
|
@@ -505,6 +505,11 @@ interface IIIClient {
|
|
|
505
505
|
* Python/Rust SDKs' `get_connection_state()`.
|
|
506
506
|
*/
|
|
507
507
|
getConnectionState(): IIIConnectionState;
|
|
508
|
+
/**
|
|
509
|
+
* Engine address this worker resolved to: the explicit `registerWorker`
|
|
510
|
+
* argument, else `III_URL`, else `ws://127.0.0.1:49134`.
|
|
511
|
+
*/
|
|
512
|
+
getAddress(): string;
|
|
508
513
|
/**
|
|
509
514
|
* The fatal registration rejection that terminated this connection, if any
|
|
510
515
|
* (e.g. a `WORKER_NAMESPACE_CONFLICT`); `undefined` while healthy. Mirrors the
|
|
@@ -623,4 +628,4 @@ type StreamResponse = {
|
|
|
623
628
|
type StreamRequest<TBody = unknown> = Omit<InternalHttpRequest<TBody>, 'response'>;
|
|
624
629
|
//#endregion
|
|
625
630
|
export { RegisterTriggerMessage as A, ChannelWriter as C, MiddlewareFunctionInput as D, MessageType as E, StreamChannelRef as M, TriggerRequest as N, RegisterFunctionFormat as O, ChannelReader as S, JsonValue as T, EngineTriggers as _, RegisterFunctionInput as a, ChannelDirection as b, RegisterTriggerTypeInput as c, StreamResponse as d, Trigger as f, EngineFunctions as g, TriggerHandler as h, InternalHttpRequest as i, RegisterTriggerTypeMessage as j, RegisterFunctionMessage as k, RemoteFunctionHandler as l, TriggerConfig as m, FunctionRef as n, RegisterFunctionOptions as o, TriggerTypeRef as p, IIIClient as r, RegisterTriggerInput as s, Channel as t, StreamRequest as u, IIIConnectionState as v, ErrorBody as w, ChannelItem as x, IIIReconnectionConfig as y };
|
|
626
|
-
//# sourceMappingURL=types-
|
|
631
|
+
//# sourceMappingURL=types-CPReRK1z.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types-
|
|
1
|
+
{"version":3,"file":"types-CPReRK1z.d.mts","names":[],"sources":["../src/iii-types.ts","../src/channels.ts","../src/iii-constants.ts","../src/triggers.ts","../src/types.ts"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iii-sdk",
|
|
3
|
-
"version": "0.22.0-alpha.
|
|
3
|
+
"version": "0.22.0-alpha.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@opentelemetry/api": "^1.9.0",
|
|
76
76
|
"ws": "^8.18.3",
|
|
77
|
-
"@iii-dev/helpers": "0.22.0-alpha.
|
|
77
|
+
"@iii-dev/helpers": "0.22.0-alpha.7"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@opentelemetry/context-async-hooks": "^2.7.1",
|