iii-sdk 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{iii-DhZKdyS8.d.mts → iii-7FpY7bi9.d.mts} +24 -27
- package/dist/iii-7FpY7bi9.d.mts.map +1 -0
- package/dist/{iii-BZ-tGd_y.d.cts → iii-BhtLRYBs.d.cts} +24 -27
- package/dist/iii-BhtLRYBs.d.cts.map +1 -0
- package/dist/index.cjs +78 -49
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -28
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +7 -28
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +74 -45
- package/dist/index.mjs.map +1 -1
- package/dist/{otel-worker-gauges-bAp_yKcU.cjs → otel-worker-gauges-8AUNGQgJ.cjs} +39 -24
- package/dist/otel-worker-gauges-8AUNGQgJ.cjs.map +1 -0
- package/dist/{otel-worker-gauges-CshKEITX.mjs → otel-worker-gauges-Dka1CFDy.mjs} +38 -23
- package/dist/otel-worker-gauges-Dka1CFDy.mjs.map +1 -0
- package/dist/stream-Bzpo5JNV.d.mts.map +1 -1
- package/dist/telemetry.cjs +1 -1
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.mts +1 -1
- package/dist/telemetry.mjs +1 -1
- package/package.json +1 -1
- package/tests/healthcheck.test.ts +1 -1
- package/tests/otel-defaults.test.ts +268 -0
- package/tests/state.test.ts +20 -20
- package/tests/stream.test.ts +21 -21
- package/tests/utils.ts +1 -2
- package/dist/iii-BZ-tGd_y.d.cts.map +0 -1
- package/dist/iii-DhZKdyS8.d.mts.map +0 -1
- package/dist/otel-worker-gauges-CshKEITX.mjs.map +0 -1
- package/dist/otel-worker-gauges-bAp_yKcU.cjs.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["getOtelLogger","invoker?: LoggerInvoker","traceId?: string","serviceName?: string","spanId?: string","attributes: Record<string, string | undefined>","safeStringify","SeverityNumber","AsyncLocalStorage","otelContext","address: string","getTracer","extractContext","context","withSpan","SpanKind","currentTraceId","currentSpanId","injectTraceparent","injectBaggage","EngineFunctions","EngineTriggers","shutdownOtel","DEFAULT_INVOCATION_TIMEOUT_MS","DEFAULT_BRIDGE_RECONNECTION_CONFIG","WebSocket","getMeter","getLogger","SeverityNumber","type: MessageType","message: Omit<IIIMessage, 'type'>"],"sources":["../src/iii-types.ts","../src/logger.ts","../src/context.ts","../src/iii.ts"],"sourcesContent":["export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n RegisterService = 'registerservice',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n type: MessageType.UnregisterTrigger\n id: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n type: MessageType.TriggerRegistrationResult\n id: string\n trigger_type: string\n function_id: string\n result?: any\n error?: any\n}\n\nexport type RegisterTriggerMessage = {\n type: MessageType.RegisterTrigger\n\n id: string\n /**\n * The type of trigger. Can be 'cron', 'event', 'http', etc.\n */\n trigger_type: string\n /**\n * Engine path for the function, including the service and function name\n * Example: software.engineering.code.rust\n * Where software, engineering, and code are the service ids\n */\n function_id: string\n config: any\n}\n\nexport type RegisterServiceMessage = {\n type: MessageType.RegisterService\n id: string\n description?: string\n parent_service_id?: string\n}\n\nexport type RegisterFunctionFormat = {\n name: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map'\n /**\n * The body of the parameter\n */\n body?: RegisterFunctionFormat[]\n /**\n * The items of the parameter\n */\n items?: RegisterFunctionFormat\n /**\n * Whether the parameter is required\n */\n required?: boolean\n}\n\nexport type RegisterFunctionMessage = {\n type: MessageType.RegisterFunction\n /**\n * The path of the function\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n}\n\nexport type InvokeFunctionMessage = {\n type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: any\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type InvocationResultMessage = {\n type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: any\n error?: any\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type FunctionInfo = {\n function_id: string\n description?: string\n request_format?: RegisterFunctionFormat\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n}\n\nexport type WorkerStatus = 'connected' | 'available' | 'busy' | 'disconnected'\n\nexport type WorkerInfo = {\n id: string\n name?: string\n runtime?: string\n version?: string\n os?: string\n ip_address?: string\n status: WorkerStatus\n connected_at_ms: number\n function_count: number\n functions: string[]\n active_invocations: number\n}\n\nexport type WorkerRegisteredMessage = {\n type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n type: MessageType.UnregisterFunction\n id: string\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterServiceMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import { SeverityNumber } from '@opentelemetry/api-logs'\nimport { getLogger as getOtelLogger } from './telemetry-system'\nimport { safeStringify } from './utils'\n\nexport type LoggerParams = {\n message: string\n trace_id?: string\n span_id?: string\n service_name?: string\n data?: any\n /** @deprecated Use service_name instead */\n function_name?: string\n}\n\n/**\n * @deprecated Use OpenTelemetry Logger directly via getLogger() from telemetry module.\n * This invoker pattern is maintained for backward compatibility only.\n */\nexport type LoggerInvoker = (function_id: string, params: LoggerParams) => Promise<void> | void\n\nexport class Logger {\n private _otelLogger: ReturnType<typeof getOtelLogger> | null = null\n\n private get otelLogger() {\n // Lazy initialization: re-fetch logger if not yet available\n if (!this._otelLogger) {\n this._otelLogger = getOtelLogger()\n }\n return this._otelLogger\n }\n\n constructor(\n /**\n * @deprecated This parameter is ignored. Logger now uses OpenTelemetry internally.\n */\n private readonly invoker?: LoggerInvoker,\n private readonly traceId?: string,\n private readonly serviceName?: string,\n private readonly spanId?: string,\n ) {}\n\n private emit(message: string, severity: SeverityNumber, data?: any): void {\n const attributes: Record<string, string | undefined> = {}\n\n if (this.traceId) {\n attributes.trace_id = this.traceId\n }\n if (this.spanId) {\n attributes.span_id = this.spanId\n }\n if (this.serviceName) {\n attributes['service.name'] = this.serviceName\n }\n if (data !== undefined) {\n attributes['log.data'] = typeof data === 'string' ? data : safeStringify(data)\n }\n\n if (this.otelLogger) {\n this.otelLogger.emit({\n severityNumber: severity,\n body: message,\n attributes: Object.keys(attributes).length > 0 ? attributes : undefined,\n })\n } else {\n // Fallback to console when OTEL is not available\n switch (severity) {\n case SeverityNumber.DEBUG:\n console.debug(message, data)\n break\n case SeverityNumber.INFO:\n console.info(message, data)\n break\n case SeverityNumber.WARN:\n console.warn(message, data)\n break\n case SeverityNumber.ERROR:\n console.error(message, data)\n break\n default:\n console.log(message, data)\n }\n }\n }\n\n info(message: string, data?: any): void {\n this.emit(message, SeverityNumber.INFO, data)\n }\n\n warn(message: string, data?: any): void {\n this.emit(message, SeverityNumber.WARN, data)\n }\n\n error(message: string, data?: any): void {\n this.emit(message, SeverityNumber.ERROR, data)\n }\n\n debug(message: string, data?: any): void {\n this.emit(message, SeverityNumber.DEBUG, data)\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Span } from '@opentelemetry/api'\nimport { context as otelContext } from '@opentelemetry/api'\nimport { Logger } from './logger'\n\nexport type Context = {\n logger: Logger\n /** The active OpenTelemetry span for adding custom attributes, events, etc. */\n trace?: Span\n}\n\nconst globalStorage = new AsyncLocalStorage<Context>()\n\nexport const withContext = async <T>(\n fn: (context: Context) => Promise<T>,\n ctx: Context,\n): Promise<T> => {\n // Capture the current OTel context before entering AsyncLocalStorage.run()\n // This preserves the OpenTelemetry trace context across async boundaries\n const currentOtelContext = otelContext.active()\n\n return globalStorage.run(ctx, async () => {\n // Restore the OTel context inside the run() scope\n // This ensures trace propagation works when handlers call iii.call\n return otelContext.with(currentOtelContext, async () => await fn(ctx))\n })\n}\n\nexport const getContext = (): Context => {\n const store = globalStorage.getStore()\n if (store) {\n return store\n }\n\n const logger = new Logger()\n\n return { logger }\n}\n","import { context } from '@opentelemetry/api'\nimport { createRequire } from 'module'\nimport * as os from 'os'\nimport { type Data, WebSocket } from 'ws'\nimport {\n type IIIConnectionState,\n type IIIReconnectionConfig,\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n EngineTriggers,\n} from './iii-constants'\nimport {\n type IIIMessage,\n type FunctionInfo,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterServiceMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type WorkerInfo,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { withContext } from './context'\nimport { Logger } from './logger'\nimport type { IStream } from './stream'\nimport {\n currentSpanId,\n currentTraceId,\n extractContext,\n getLogger,\n getMeter,\n getTracer,\n injectBaggage,\n injectTraceparent,\n initOtel,\n shutdownOtel,\n SeverityNumber,\n SpanKind,\n withSpan,\n type OtelConfig,\n} from './telemetry-system'\nimport { registerWorkerGauges, stopWorkerGauges } from './otel-worker-gauges'\nimport type { TriggerHandler } from './triggers'\nimport type {\n ISdk,\n FunctionsAvailableCallback,\n Invocation,\n LogCallback,\n LogConfig,\n LogSeverityLevel,\n OtelLogEvent,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n FunctionRef,\n} from './types'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** Callback type for connection state changes */\nexport type ConnectionStateCallback = (state: IIIConnectionState) => void\n\nexport type InitOptions = {\n workerName?: string\n enableMetricsReporting?: boolean\n /** Default timeout for function invocations in milliseconds */\n invocationTimeoutMs?: number\n /** Configuration for WebSocket reconnection behavior */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\n /** OpenTelemetry configuration. If provided, OTEL will be initialized automatically.\n * The engineWsUrl is set automatically from the III address. */\n otel?: Omit<OtelConfig, 'engineWsUrl'>\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private services = new Map<string, Omit<RegisterServiceMessage, 'functions'>>()\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 functionsAvailableCallbacks = new Set<FunctionsAvailableCallback>()\n private functionsAvailableTrigger?: Trigger\n private functionsAvailableFunctionPath?: string\n private logCallbacks = new Map<LogCallback, LogConfig>()\n private logTrigger?: Trigger\n private logFunctionPath?: string\n private messagesToSend: IIIMessage[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private stateCallbacks = new Set<ConnectionStateCallback>()\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry if config is provided\n if (options?.otel) {\n initOtel({ ...options.otel, engineWsUrl: this.address })\n }\n\n this.connect()\n }\n\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'type'>,\n handler: TriggerHandler<TConfig>,\n ): void => {\n this.sendMessage(MessageType.RegisterTriggerType, triggerType, true)\n this.triggerTypes.set(triggerType.id, {\n message: { ...triggerType, type: MessageType.RegisterTriggerType },\n handler,\n })\n }\n\n on = (event: string, callback: (arg?: unknown) => void): void => {\n this.ws?.on(event, callback)\n }\n\n unregisterTriggerType = (triggerType: Omit<RegisterTriggerTypeMessage, 'type'>): void => {\n this.sendMessage(MessageType.UnregisterTriggerType, triggerType, true)\n this.triggerTypes.delete(triggerType.id)\n }\n\n registerTrigger = (trigger: Omit<RegisterTriggerMessage, 'type' | 'id'>): Trigger => {\n const id = crypto.randomUUID()\n this.sendMessage(MessageType.RegisterTrigger, { ...trigger, id }, true)\n this.triggers.set(id, { ...trigger, id, type: MessageType.RegisterTrigger })\n\n return {\n unregister: () => {\n this.sendMessage(MessageType.UnregisterTrigger, {\n id,\n trigger_type: MessageType.UnregisterTrigger,\n })\n this.triggers.delete(id)\n },\n }\n }\n\n registerFunction = (\n message: Omit<RegisterFunctionMessage, 'type'>,\n handler: RemoteFunctionHandler,\n ): FunctionRef => {\n if (!message.id || message.id.trim() === '') {\n throw new Error('id is required')\n }\n\n this.sendMessage(MessageType.RegisterFunction, message, true)\n this.functions.set(message.id, {\n message: { ...message, type: MessageType.RegisterFunction },\n handler: async (input, traceparent?: string, baggage?: string) => {\n // If we have a tracer, wrap in a span and pass it to the context\n if (getTracer()) {\n // Extract both traceparent and baggage into a parent context\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`invoke ${message.id}`, { kind: SpanKind.SERVER }, async span => {\n const traceId = currentTraceId() ?? crypto.randomUUID()\n const spanId = currentSpanId()\n const logger = new Logger(undefined, traceId, message.id, spanId)\n const ctx = { logger, trace: span }\n\n return withContext(async () => await handler(input), ctx)\n }),\n )\n }\n\n // Fallback without tracing\n const traceId = crypto.randomUUID()\n const logger = new Logger(undefined, traceId, message.id)\n const ctx = { logger }\n\n return withContext(async () => await handler(input), ctx)\n },\n })\n\n return {\n id: message.id,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: message.id }, true)\n this.functions.delete(message.id)\n },\n }\n }\n\n registerService = (message: Omit<RegisterServiceMessage, 'type'>): void => {\n this.sendMessage(MessageType.RegisterService, message, true)\n this.services.set(message.id, { ...message, type: MessageType.RegisterService })\n }\n\n call = async <TInput, TOutput>(\n function_id: string,\n data: TInput,\n timeoutMs?: number,\n ): Promise<TOutput> => {\n const invocation_id = crypto.randomUUID()\n // Inject trace context and baggage if available\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\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(new Error(`Invocation timeout after ${effectiveTimeout}ms: ${function_id}`))\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 timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data,\n traceparent,\n baggage,\n })\n })\n }\n\n callVoid = <TInput>(function_id: string, data: TInput): void => {\n // Inject trace context and baggage if available\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, { function_id, data, traceparent, baggage })\n }\n\n listFunctions = async (): Promise<FunctionInfo[]> => {\n const result = await this.call<Record<string, never>, { functions: FunctionInfo[] }>(\n EngineFunctions.LIST_FUNCTIONS,\n {},\n )\n return result.functions\n }\n\n listWorkers = async (): Promise<WorkerInfo[]> => {\n const result = await this.call<Record<string, never>, { workers: WorkerInfo[] }>(\n EngineFunctions.LIST_WORKERS,\n {},\n )\n return result.workers\n }\n\n private registerWorkerMetadata(): void {\n this.callVoid(EngineFunctions.REGISTER_WORKER, {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n })\n }\n\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction({ id: `stream.get(${streamName})` }, stream.get.bind(stream))\n this.registerFunction({ id: `stream.set(${streamName})` }, stream.set.bind(stream))\n this.registerFunction({ id: `stream.delete(${streamName})` }, stream.delete.bind(stream))\n this.registerFunction({ id: `stream.list(${streamName})` }, stream.list.bind(stream))\n this.registerFunction(\n { id: `stream.list_groups(${streamName})` },\n stream.listGroups.bind(stream),\n )\n }\n\n onFunctionsAvailable = (callback: FunctionsAvailableCallback): (() => void) => {\n this.functionsAvailableCallbacks.add(callback)\n\n if (!this.functionsAvailableTrigger) {\n if (!this.functionsAvailableFunctionPath) {\n this.functionsAvailableFunctionPath = `engine.on_functions_available.${crypto.randomUUID()}`\n }\n\n const function_id = this.functionsAvailableFunctionPath\n if (!this.functions.has(function_id)) {\n this.registerFunction(\n { id: function_id },\n async ({ functions }: { functions: FunctionInfo[] }) => {\n this.functionsAvailableCallbacks.forEach(handler => {\n handler(functions)\n })\n return null\n },\n )\n }\n\n this.functionsAvailableTrigger = this.registerTrigger({\n trigger_type: EngineTriggers.FUNCTIONS_AVAILABLE,\n function_id,\n config: {},\n })\n }\n\n return () => {\n this.functionsAvailableCallbacks.delete(callback)\n if (this.functionsAvailableCallbacks.size === 0 && this.functionsAvailableTrigger) {\n this.functionsAvailableTrigger.unregister()\n this.functionsAvailableTrigger = undefined\n }\n }\n }\n\n onLog = (callback: LogCallback, config?: LogConfig): (() => void) => {\n const effectiveConfig = config ?? { level: 'all' }\n this.logCallbacks.set(callback, effectiveConfig)\n\n if (!this.logTrigger) {\n if (!this.logFunctionPath) {\n this.logFunctionPath = `engine.on_log.${crypto.randomUUID()}`\n }\n\n const function_id = this.logFunctionPath\n if (!this.functions.has(function_id)) {\n this.registerFunction({ id: function_id }, async (log: OtelLogEvent) => {\n this.logCallbacks.forEach((cfg, handler) => {\n try {\n const minSeverity = this.severityTextToNumber(cfg.level ?? 'all')\n if (cfg.level === 'all' || log.severity_number >= minSeverity) {\n handler(log)\n }\n } catch (error) {\n this.logError('Log callback handler threw an exception', error)\n }\n })\n return null\n })\n }\n\n this.logTrigger = this.registerTrigger({\n trigger_type: EngineTriggers.LOG,\n function_id,\n config: { level: 'all', severity_min: 0 },\n })\n }\n\n return () => {\n this.logCallbacks.delete(callback)\n if (this.logCallbacks.size === 0 && this.logTrigger) {\n this.logTrigger.unregister()\n this.logTrigger = undefined\n }\n }\n }\n\n /**\n * Get the current connection state.\n */\n getConnectionState = (): IIIConnectionState => {\n return this.connectionState\n }\n\n /**\n * Register a callback to be notified of connection state changes.\n * @returns A function to unregister the callback\n */\n onConnectionStateChange = (callback: ConnectionStateCallback): (() => void) => {\n this.stateCallbacks.add(callback)\n // Immediately notify of current state\n callback(this.connectionState)\n return () => this.stateCallbacks.delete(callback)\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.close()\n this.ws = undefined\n }\n\n // Clear callbacks\n this.stateCallbacks.clear()\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 for (const callback of this.stateCallbacks) {\n try {\n callback(state)\n } catch (error) {\n this.logError('Error in connection state callback', error)\n }\n }\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 this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } =\n this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.services.forEach(service => {\n this.sendMessage(MessageType.RegisterService, service, 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 // Skip InvokeFunction messages for timed-out invocations\n if (\n message.type === MessageType.InvokeFunction &&\n message.invocation_id &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, err => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private sendMessage(\n type: MessageType,\n message: Omit<IIIMessage, 'type'>,\n skipIfClosed = false,\n ): void {\n const fullMessage = { ...message, type }\n if (this.isOpen()) {\n this.sendMessageRaw(JSON.stringify(fullMessage))\n } else if (!skipIfClosed) {\n this.messagesToSend.push(fullMessage as IIIMessage)\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 severityTextToNumber(level: LogSeverityLevel): number {\n switch (level) {\n case 'trace':\n return 1\n case 'debug':\n return 5\n case 'info':\n return 9\n case 'warn':\n return 13\n case 'error':\n return 17\n case 'fatal':\n return 21\n case 'all':\n return 0\n default:\n return 0\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n error ? invocation.reject(error) : invocation.resolve(result)\n }\n\n this.invocations.delete(invocation_id)\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n // Get response traceparent/baggage after handler runs (will be current span's context)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n if (fn) {\n if (!invocation_id) {\n try {\n await fn.handler(input, 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(input, 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 this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: 'invocation_failed', message: (error as Error).message },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: 'function_not_found', message: 'Function not found' },\n traceparent,\n baggage,\n })\n }\n }\n\n private async onRegisterTrigger(message: RegisterTriggerMessage) {\n const triggerTypeData = this.triggerTypes.get(message.trigger_type)\n const { id, trigger_type, function_id, config } = message\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config })\n this.sendMessage(MessageType.TriggerRegistrationResult, { id, trigger_type, function_id })\n } catch (error) {\n this.sendMessage(MessageType.TriggerRegistrationResult, {\n id,\n 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 trigger_type,\n function_id,\n error: { code: 'trigger_type_not_found', message: 'Trigger type not found' },\n })\n }\n }\n\n private onMessage(socketMessage: Data): void {\n let type: MessageType\n let message: Omit<IIIMessage, 'type'>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as IIIMessage\n type = parsed.type\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 (type === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (type === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } =\n message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (type === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(message as RegisterTriggerMessage)\n } else if (type === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\nexport const init = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["getOtelLogger","traceId?: string","serviceName?: string","spanId?: string","attributes: Record<string, string | undefined>","safeStringify","SeverityNumber","AsyncLocalStorage","otelContext","os","address: string","fullTrigger: RegisterTriggerMessage","getTracer","extractContext","context","withSpan","SpanKind","currentTraceId","currentSpanId","injectTraceparent","injectBaggage","EngineFunctions","EngineTriggers","shutdownOtel","DEFAULT_INVOCATION_TIMEOUT_MS","DEFAULT_BRIDGE_RECONNECTION_CONFIG","WebSocket","getMeter","getLogger","SeverityNumber","msgType: MessageType","message: Record<string, unknown>"],"sources":["../src/iii-types.ts","../src/logger.ts","../src/context.ts","../src/iii.ts"],"sourcesContent":["export enum MessageType {\n RegisterFunction = 'registerfunction',\n UnregisterFunction = 'unregisterfunction',\n RegisterService = 'registerservice',\n InvokeFunction = 'invokefunction',\n InvocationResult = 'invocationresult',\n RegisterTriggerType = 'registertriggertype',\n RegisterTrigger = 'registertrigger',\n UnregisterTrigger = 'unregistertrigger',\n UnregisterTriggerType = 'unregistertriggertype',\n TriggerRegistrationResult = 'triggerregistrationresult',\n WorkerRegistered = 'workerregistered',\n}\n\nexport type RegisterTriggerTypeMessage = {\n message_type: MessageType.RegisterTriggerType\n id: string\n description: string\n}\n\nexport type UnregisterTriggerTypeMessage = {\n message_type: MessageType.UnregisterTriggerType\n id: string\n}\n\nexport type UnregisterTriggerMessage = {\n message_type: MessageType.UnregisterTrigger\n id: string\n type?: string\n}\n\nexport type TriggerRegistrationResultMessage = {\n message_type: MessageType.TriggerRegistrationResult\n id: string\n type: string\n function_id: string\n result?: unknown\n error?: unknown\n}\n\nexport type RegisterTriggerMessage = {\n message_type: MessageType.RegisterTrigger\n id: string\n type: string\n function_id: string\n config: unknown\n}\n\nexport type RegisterServiceMessage = {\n message_type: MessageType.RegisterService\n id: string\n description?: string\n parent_service_id?: string\n}\n\nexport type RegisterFunctionFormat = {\n name: string\n /**\n * The description of the parameter\n */\n description?: string\n /**\n * The type of the parameter\n */\n type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null' | 'map'\n /**\n * The body of the parameter\n */\n body?: RegisterFunctionFormat[]\n /**\n * The items of the parameter\n */\n items?: RegisterFunctionFormat\n /**\n * Whether the parameter is required\n */\n required?: boolean\n}\n\nexport type RegisterFunctionMessage = {\n message_type: MessageType.RegisterFunction\n /**\n * The path of the function\n */\n id: string\n /**\n * The description of the function\n */\n description?: string\n /**\n * The request format of the function\n */\n request_format?: RegisterFunctionFormat\n /**\n * The response format of the function\n */\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n}\n\nexport type InvokeFunctionMessage = {\n message_type: MessageType.InvokeFunction\n /**\n * This is optional for async invocations\n */\n invocation_id?: string\n /**\n * The path of the function\n */\n function_id: string\n /**\n * The data to pass to the function\n */\n data: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type InvocationResultMessage = {\n message_type: MessageType.InvocationResult\n /**\n * The id of the invocation\n */\n invocation_id: string\n /**\n * The path of the function\n */\n function_id: string\n result?: unknown\n error?: unknown\n /**\n * W3C trace-context traceparent header for distributed tracing\n */\n traceparent?: string\n /**\n * W3C baggage header for cross-cutting context propagation\n */\n baggage?: string\n}\n\nexport type FunctionInfo = {\n function_id: string\n description?: string\n request_format?: RegisterFunctionFormat\n response_format?: RegisterFunctionFormat\n metadata?: Record<string, unknown>\n}\n\nexport type WorkerStatus = 'connected' | 'available' | 'busy' | 'disconnected'\n\nexport type WorkerInfo = {\n id: string\n name?: string\n runtime?: string\n version?: string\n os?: string\n ip_address?: string\n status: WorkerStatus\n connected_at_ms: number\n function_count: number\n functions: string[]\n active_invocations: number\n}\n\nexport type WorkerRegisteredMessage = {\n message_type: MessageType.WorkerRegistered\n worker_id: string\n}\n\nexport type UnregisterFunctionMessage = {\n message_type: MessageType.UnregisterFunction\n id: string\n}\n\nexport type IIIMessage =\n | RegisterFunctionMessage\n | UnregisterFunctionMessage\n | InvokeFunctionMessage\n | InvocationResultMessage\n | RegisterServiceMessage\n | RegisterTriggerMessage\n | RegisterTriggerTypeMessage\n | UnregisterTriggerMessage\n | UnregisterTriggerTypeMessage\n | TriggerRegistrationResultMessage\n | WorkerRegisteredMessage\n","import { SeverityNumber } from '@opentelemetry/api-logs'\nimport { getLogger as getOtelLogger } from './telemetry-system'\nimport { safeStringify } from './utils'\n\nexport type LoggerParams = {\n message: string\n trace_id?: string\n span_id?: string\n service_name?: string\n data?: unknown\n /** @deprecated Use service_name instead */\n function_name?: string\n}\n\nexport class Logger {\n private _otelLogger: ReturnType<typeof getOtelLogger> | null = null\n\n private get otelLogger() {\n // Lazy initialization: re-fetch logger if not yet available\n if (!this._otelLogger) {\n this._otelLogger = getOtelLogger()\n }\n return this._otelLogger\n }\n\n constructor(\n private readonly traceId?: string,\n private readonly serviceName?: string,\n private readonly spanId?: string,\n ) {}\n\n private emit(message: string, severity: SeverityNumber, data?: unknown): void {\n const attributes: Record<string, string | undefined> = {}\n\n if (this.traceId) {\n attributes.trace_id = this.traceId\n }\n if (this.spanId) {\n attributes.span_id = this.spanId\n }\n if (this.serviceName) {\n attributes['service.name'] = this.serviceName\n }\n if (data !== undefined) {\n attributes['log.data'] = typeof data === 'string' ? data : safeStringify(data)\n }\n\n if (this.otelLogger) {\n this.otelLogger.emit({\n severityNumber: severity,\n body: message,\n attributes: Object.keys(attributes).length > 0 ? attributes : undefined,\n })\n } else {\n // Fallback to console when OTEL is not available\n switch (severity) {\n case SeverityNumber.DEBUG:\n console.debug(message, data)\n break\n case SeverityNumber.INFO:\n console.info(message, data)\n break\n case SeverityNumber.WARN:\n console.warn(message, data)\n break\n case SeverityNumber.ERROR:\n console.error(message, data)\n break\n default:\n console.log(message, data)\n }\n }\n }\n\n info(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.INFO, data)\n }\n\n warn(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.WARN, data)\n }\n\n error(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.ERROR, data)\n }\n\n debug(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.DEBUG, data)\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Span } from '@opentelemetry/api'\nimport { context as otelContext } from '@opentelemetry/api'\nimport { Logger } from './logger'\n\nexport type Context = {\n logger: Logger\n /** The active OpenTelemetry span for adding custom attributes, events, etc. */\n trace?: Span\n}\n\nconst globalStorage = new AsyncLocalStorage<Context>()\n\nexport const withContext = async <T>(\n fn: (context: Context) => Promise<T>,\n ctx: Context,\n): Promise<T> => {\n // Capture the current OTel context before entering AsyncLocalStorage.run()\n // This preserves the OpenTelemetry trace context across async boundaries\n const currentOtelContext = otelContext.active()\n\n return globalStorage.run(ctx, async () => {\n // Restore the OTel context inside the run() scope\n // This ensures trace propagation works when handlers call iii.call\n return otelContext.with(currentOtelContext, async () => await fn(ctx))\n })\n}\n\nexport const getContext = (): Context => {\n const store = globalStorage.getStore()\n if (store) {\n return store\n }\n\n const logger = new Logger()\n\n return { logger }\n}\n","import { context } from '@opentelemetry/api'\nimport { createRequire } from 'node:module'\nimport * as os from 'node:os'\nimport { type Data, WebSocket } from 'ws'\nimport {\n type IIIConnectionState,\n type IIIReconnectionConfig,\n DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n DEFAULT_INVOCATION_TIMEOUT_MS,\n EngineFunctions,\n EngineTriggers,\n} from './iii-constants'\nimport {\n type IIIMessage,\n type FunctionInfo,\n type InvocationResultMessage,\n type InvokeFunctionMessage,\n MessageType,\n type RegisterFunctionMessage,\n type RegisterServiceMessage,\n type RegisterTriggerMessage,\n type RegisterTriggerTypeMessage,\n type TriggerRegistrationResultMessage,\n type WorkerInfo,\n type WorkerRegisteredMessage,\n} from './iii-types'\nimport { withContext } from './context'\nimport { Logger } from './logger'\nimport type { IStream } from './stream'\nimport {\n currentSpanId,\n currentTraceId,\n extractContext,\n getLogger,\n getMeter,\n getTracer,\n injectBaggage,\n injectTraceparent,\n initOtel,\n shutdownOtel,\n SeverityNumber,\n SpanKind,\n withSpan,\n type OtelConfig,\n} from './telemetry-system'\nimport { registerWorkerGauges, stopWorkerGauges } from './otel-worker-gauges'\nimport type { TriggerHandler } from './triggers'\nimport type {\n ISdk,\n FunctionsAvailableCallback,\n Invocation,\n LogCallback,\n LogConfig,\n LogSeverityLevel,\n OtelLogEvent,\n RemoteFunctionData,\n RemoteFunctionHandler,\n RemoteTriggerTypeData,\n Trigger,\n FunctionRef,\n} from './types'\n\nconst require = createRequire(import.meta.url)\nconst { version: SDK_VERSION } = require('../package.json')\n\nfunction getOsInfo(): string {\n return `${os.platform()} ${os.release()} (${os.arch()})`\n}\n\nfunction getDefaultWorkerName(): string {\n return `${os.hostname()}:${process.pid}`\n}\n\n/** Callback type for connection state changes */\nexport type ConnectionStateCallback = (state: IIIConnectionState) => void\n\nexport type InitOptions = {\n workerName?: string\n enableMetricsReporting?: boolean\n /** Default timeout for function invocations in milliseconds */\n invocationTimeoutMs?: number\n /** Configuration for WebSocket reconnection behavior */\n reconnectionConfig?: Partial<IIIReconnectionConfig>\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 otel?: Omit<OtelConfig, 'engineWsUrl'>\n}\n\nclass Sdk implements ISdk {\n private ws?: WebSocket\n private functions = new Map<string, RemoteFunctionData>()\n private services = new Map<string, Omit<RegisterServiceMessage, 'functions'>>()\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 functionsAvailableCallbacks = new Set<FunctionsAvailableCallback>()\n private functionsAvailableTrigger?: Trigger\n private functionsAvailableFunctionPath?: string\n private logCallbacks = new Map<LogCallback, LogConfig>()\n private logTrigger?: Trigger\n private logFunctionPath?: string\n private messagesToSend: Record<string, unknown>[] = []\n private workerName: string\n private workerId?: string\n private reconnectTimeout?: NodeJS.Timeout\n private metricsReportingEnabled: boolean\n private invocationTimeoutMs: number\n private reconnectionConfig: IIIReconnectionConfig\n private reconnectAttempt = 0\n private connectionState: IIIConnectionState = 'disconnected'\n private stateCallbacks = new Set<ConnectionStateCallback>()\n private isShuttingDown = false\n\n constructor(\n private readonly address: string,\n options?: InitOptions,\n ) {\n this.workerName = options?.workerName ?? getDefaultWorkerName()\n this.metricsReportingEnabled = options?.enableMetricsReporting ?? true\n this.invocationTimeoutMs = options?.invocationTimeoutMs ?? DEFAULT_INVOCATION_TIMEOUT_MS\n this.reconnectionConfig = {\n ...DEFAULT_BRIDGE_RECONNECTION_CONFIG,\n ...options?.reconnectionConfig,\n }\n\n // Initialize OpenTelemetry (enabled by default, opt-out via config or env)\n initOtel({ ...options?.otel, engineWsUrl: this.address })\n\n this.connect()\n }\n\n registerTriggerType = <TConfig>(\n triggerType: Omit<RegisterTriggerTypeMessage, 'message_type'>,\n handler: TriggerHandler<TConfig>,\n ): void => {\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\n on = (event: string, callback: (arg?: unknown) => void): void => {\n this.ws?.on(event, callback)\n }\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 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 registerFunction = (\n message: Omit<RegisterFunctionMessage, 'message_type'>,\n handler: RemoteFunctionHandler,\n ): FunctionRef => {\n if (!message.id || message.id.trim() === '') {\n throw new Error('id is required')\n }\n\n this.sendMessage(MessageType.RegisterFunction, message, true)\n this.functions.set(message.id, {\n message: { ...message, message_type: MessageType.RegisterFunction },\n handler: async (input, traceparent?: string, baggage?: string) => {\n // If we have a tracer, wrap in a span and pass it to the context\n if (getTracer()) {\n // Extract both traceparent and baggage into a parent context\n const parentContext = extractContext(traceparent, baggage)\n\n return context.with(parentContext, () =>\n withSpan(`invoke ${message.id}`, { kind: SpanKind.SERVER }, async span => {\n const traceId = currentTraceId() ?? crypto.randomUUID()\n const spanId = currentSpanId()\n const logger = new Logger(traceId, message.id, spanId)\n const ctx = { logger, trace: span }\n\n return withContext(async () => await handler(input), ctx)\n }),\n )\n }\n\n // Fallback without tracing\n const traceId = crypto.randomUUID()\n const logger = new Logger(traceId, message.id)\n const ctx = { logger }\n\n return withContext(async () => await handler(input), ctx)\n },\n })\n\n return {\n id: message.id,\n unregister: () => {\n this.sendMessage(MessageType.UnregisterFunction, { id: message.id }, true)\n this.functions.delete(message.id)\n },\n }\n }\n\n registerService = (message: Omit<RegisterServiceMessage, 'message_type'>): void => {\n this.sendMessage(MessageType.RegisterService, message, true)\n this.services.set(message.id, { ...message, message_type: MessageType.RegisterService })\n }\n\n call = async <TInput, TOutput>(\n function_id: string,\n data: TInput,\n timeoutMs?: number,\n ): Promise<TOutput> => {\n const invocation_id = crypto.randomUUID()\n // Inject trace context and baggage if available\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n const effectiveTimeout = timeoutMs ?? this.invocationTimeoutMs\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(new Error(`Invocation timeout after ${effectiveTimeout}ms: ${function_id}`))\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 timeout,\n })\n\n this.sendMessage(MessageType.InvokeFunction, {\n invocation_id,\n function_id,\n data,\n traceparent,\n baggage,\n })\n })\n }\n\n callVoid = <TInput>(function_id: string, data: TInput): void => {\n // Inject trace context and baggage if available\n const traceparent = injectTraceparent()\n const baggage = injectBaggage()\n this.sendMessage(MessageType.InvokeFunction, { function_id, data, traceparent, baggage })\n }\n\n listFunctions = async (): Promise<FunctionInfo[]> => {\n const result = await this.call<Record<string, never>, { functions: FunctionInfo[] }>(\n EngineFunctions.LIST_FUNCTIONS,\n {},\n )\n return result.functions\n }\n\n listWorkers = async (): Promise<WorkerInfo[]> => {\n const result = await this.call<Record<string, never>, { workers: WorkerInfo[] }>(\n EngineFunctions.LIST_WORKERS,\n {},\n )\n return result.workers\n }\n\n private registerWorkerMetadata(): void {\n this.callVoid(EngineFunctions.REGISTER_WORKER, {\n runtime: 'node',\n version: SDK_VERSION,\n name: this.workerName,\n os: getOsInfo(),\n })\n }\n\n createStream = <TData>(streamName: string, stream: IStream<TData>): void => {\n this.registerFunction({ id: `stream::get(${streamName})` }, stream.get.bind(stream))\n this.registerFunction({ id: `stream::set(${streamName})` }, stream.set.bind(stream))\n this.registerFunction({ id: `stream::delete(${streamName})` }, stream.delete.bind(stream))\n this.registerFunction({ id: `stream::list(${streamName})` }, stream.list.bind(stream))\n this.registerFunction(\n { id: `stream::list_groups(${streamName})` },\n stream.listGroups.bind(stream),\n )\n }\n\n onFunctionsAvailable = (callback: FunctionsAvailableCallback): (() => void) => {\n this.functionsAvailableCallbacks.add(callback)\n\n if (!this.functionsAvailableTrigger) {\n if (!this.functionsAvailableFunctionPath) {\n this.functionsAvailableFunctionPath = `engine.on_functions_available.${crypto.randomUUID()}`\n }\n\n const function_id = this.functionsAvailableFunctionPath\n if (!this.functions.has(function_id)) {\n this.registerFunction(\n { id: function_id },\n async ({ functions }: { functions: FunctionInfo[] }) => {\n this.functionsAvailableCallbacks.forEach(handler => {\n handler(functions)\n })\n return null\n },\n )\n }\n\n this.functionsAvailableTrigger = this.registerTrigger({\n type: EngineTriggers.FUNCTIONS_AVAILABLE,\n function_id,\n config: {},\n })\n }\n\n return () => {\n this.functionsAvailableCallbacks.delete(callback)\n if (this.functionsAvailableCallbacks.size === 0 && this.functionsAvailableTrigger) {\n this.functionsAvailableTrigger.unregister()\n this.functionsAvailableTrigger = undefined\n }\n }\n }\n\n onLog = (callback: LogCallback, config?: LogConfig): (() => void) => {\n const effectiveConfig = config ?? { level: 'all' }\n this.logCallbacks.set(callback, effectiveConfig)\n\n if (!this.logTrigger) {\n if (!this.logFunctionPath) {\n this.logFunctionPath = `engine.on_log.${crypto.randomUUID()}`\n }\n\n const function_id = this.logFunctionPath\n if (!this.functions.has(function_id)) {\n this.registerFunction({ id: function_id }, async (log: OtelLogEvent) => {\n this.logCallbacks.forEach((cfg, handler) => {\n try {\n const minSeverity = this.severityTextToNumber(cfg.level ?? 'all')\n if (cfg.level === 'all' || log.severity_number >= minSeverity) {\n handler(log)\n }\n } catch (error) {\n this.logError('Log callback handler threw an exception', error)\n }\n })\n return null\n })\n }\n\n this.logTrigger = this.registerTrigger({\n type: EngineTriggers.LOG,\n function_id,\n config: { level: 'all', severity_min: 0 },\n })\n }\n\n return () => {\n this.logCallbacks.delete(callback)\n if (this.logCallbacks.size === 0 && this.logTrigger) {\n this.logTrigger.unregister()\n this.logTrigger = undefined\n }\n }\n }\n\n /**\n * Get the current connection state.\n */\n getConnectionState = (): IIIConnectionState => {\n return this.connectionState\n }\n\n /**\n * Register a callback to be notified of connection state changes.\n * @returns A function to unregister the callback\n */\n onConnectionStateChange = (callback: ConnectionStateCallback): (() => void) => {\n this.stateCallbacks.add(callback)\n // Immediately notify of current state\n callback(this.connectionState)\n return () => this.stateCallbacks.delete(callback)\n }\n\n /**\n * Gracefully shutdown the iii, cleaning up all resources.\n */\n shutdown = async (): Promise<void> => {\n this.isShuttingDown = true\n\n this.stopMetricsReporting()\n\n // Shutdown OpenTelemetry\n await shutdownOtel()\n\n // Clear reconnection timeout\n this.clearReconnectTimeout()\n\n // Reject all pending invocations\n for (const [_id, invocation] of this.invocations) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n invocation.reject(new Error('iii is shutting down'))\n }\n this.invocations.clear()\n\n // Close WebSocket\n if (this.ws) {\n this.ws.removeAllListeners()\n this.ws.close()\n this.ws = undefined\n }\n\n // Clear callbacks\n this.stateCallbacks.clear()\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 for (const callback of this.stateCallbacks) {\n try {\n callback(state)\n } catch (error) {\n this.logError('Error in connection state callback', error)\n }\n }\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 this.ws.on('open', this.onSocketOpen.bind(this))\n this.ws.on('close', this.onSocketClose.bind(this))\n this.ws.on('error', this.onSocketError.bind(this))\n }\n\n private clearReconnectTimeout(): void {\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = undefined\n }\n }\n\n private scheduleReconnect(): void {\n if (this.isShuttingDown) {\n return\n }\n\n const { maxRetries, initialDelayMs, backoffMultiplier, maxDelayMs, jitterFactor } =\n this.reconnectionConfig\n\n if (maxRetries !== -1 && this.reconnectAttempt >= maxRetries) {\n this.setConnectionState('failed')\n this.logError(`Max reconnection retries (${maxRetries}) reached, giving up`)\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay = initialDelayMs * backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, maxDelayMs)\n const jitter = cappedDelay * jitterFactor * (2 * Math.random() - 1)\n const delay = Math.floor(cappedDelay + jitter)\n\n this.setConnectionState('reconnecting')\n console.debug(`[iii] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = undefined\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n private onSocketError(error: Error): void {\n this.logError('WebSocket error', error)\n }\n\n private startMetricsReporting(): void {\n if (!this.metricsReportingEnabled || !this.workerId) {\n return\n }\n\n const meter = getMeter()\n if (!meter) {\n console.warn(\n '[iii] Worker metrics disabled: OpenTelemetry not initialized. Call initOtel() with metricsEnabled: true before creating the iii.',\n )\n return\n }\n\n registerWorkerGauges(meter, {\n workerId: this.workerId,\n workerName: this.workerName,\n })\n }\n\n private stopMetricsReporting(): void {\n stopWorkerGauges()\n }\n\n private onSocketClose(): void {\n this.ws?.removeAllListeners()\n this.ws?.terminate()\n this.ws = undefined\n\n this.setConnectionState('disconnected')\n this.stopMetricsReporting()\n this.scheduleReconnect()\n }\n\n private onSocketOpen(): void {\n this.clearReconnectTimeout()\n this.reconnectAttempt = 0\n this.setConnectionState('connected')\n\n this.ws?.on('message', this.onMessage.bind(this))\n\n this.triggerTypes.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterTriggerType, message, true)\n })\n this.services.forEach(service => {\n this.sendMessage(MessageType.RegisterService, service, true)\n })\n this.functions.forEach(({ message }) => {\n this.sendMessage(MessageType.RegisterFunction, message, true)\n })\n this.triggers.forEach(trigger => {\n this.sendMessage(MessageType.RegisterTrigger, trigger, true)\n })\n\n // Optimized: swap with empty array instead of splice\n const pending = this.messagesToSend\n this.messagesToSend = []\n for (const message of pending) {\n if (\n message.type === MessageType.InvokeFunction &&\n typeof message.invocation_id === 'string' &&\n !this.invocations.has(message.invocation_id)\n ) {\n continue\n }\n this.sendMessageRaw(JSON.stringify(message))\n }\n\n this.registerWorkerMetadata()\n }\n\n private isOpen(): boolean {\n return this.ws?.readyState === WebSocket.OPEN\n }\n\n private sendMessageRaw(data: string): void {\n if (this.ws && this.isOpen()) {\n try {\n this.ws.send(data, err => {\n if (err) {\n this.logError('Failed to send message', err)\n }\n })\n } catch (error) {\n this.logError('Exception while sending message', error)\n }\n }\n }\n\n private toWireFormat(\n messageType: MessageType,\n message: Omit<IIIMessage, 'message_type'>,\n ): 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(\n messageType: MessageType,\n message: Omit<IIIMessage, 'message_type'>,\n skipIfClosed = false,\n ): 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 severityTextToNumber(level: LogSeverityLevel): number {\n switch (level) {\n case 'trace':\n return 1\n case 'debug':\n return 5\n case 'info':\n return 9\n case 'warn':\n return 13\n case 'error':\n return 17\n case 'fatal':\n return 21\n case 'all':\n return 0\n default:\n return 0\n }\n }\n\n private onInvocationResult(invocation_id: string, result: unknown, error: unknown): void {\n const invocation = this.invocations.get(invocation_id)\n\n if (invocation) {\n if (invocation.timeout) {\n clearTimeout(invocation.timeout)\n }\n error ? invocation.reject(error) : invocation.resolve(result)\n }\n\n this.invocations.delete(invocation_id)\n }\n\n private async onInvokeFunction<TInput>(\n invocation_id: string | undefined,\n function_id: string,\n input: TInput,\n traceparent?: string,\n baggage?: string,\n ): Promise<unknown> {\n const fn = this.functions.get(function_id)\n // Get response traceparent/baggage after handler runs (will be current span's context)\n const getResponseTraceparent = () => injectTraceparent() ?? traceparent\n const getResponseBaggage = () => injectBaggage() ?? baggage\n\n if (fn) {\n if (!invocation_id) {\n try {\n await fn.handler(input, 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(input, 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 this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: 'invocation_failed', message: (error as Error).message },\n traceparent: getResponseTraceparent(),\n baggage: getResponseBaggage(),\n })\n }\n } else {\n this.sendMessage(MessageType.InvocationResult, {\n invocation_id,\n function_id,\n error: { code: 'function_not_found', message: 'Function not found' },\n traceparent,\n baggage,\n })\n }\n }\n\n private async onRegisterTrigger(message: {\n trigger_type: string\n id: string\n function_id: string\n config: unknown\n }) {\n const { trigger_type, id, function_id, config } = message\n const triggerTypeData = this.triggerTypes.get(trigger_type)\n\n if (triggerTypeData) {\n try {\n await triggerTypeData.handler.registerTrigger({ id, function_id, config })\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 onMessage(socketMessage: Data): void {\n let msgType: MessageType\n let message: Record<string, unknown>\n\n try {\n const parsed = JSON.parse(socketMessage.toString()) as Record<string, unknown>\n msgType = parsed.type as MessageType\n const { type: _, ...rest } = parsed\n message = rest\n } catch (error) {\n this.logError('Failed to parse incoming message', error)\n return\n }\n\n if (msgType === MessageType.InvocationResult) {\n const { invocation_id, result, error } = message as InvocationResultMessage\n this.onInvocationResult(invocation_id, result, error)\n } else if (msgType === MessageType.InvokeFunction) {\n const { invocation_id, function_id, data, traceparent, baggage } =\n message as InvokeFunctionMessage\n this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage)\n } else if (msgType === MessageType.RegisterTrigger) {\n this.onRegisterTrigger(\n message as { trigger_type: string; id: string; function_id: string; config: unknown },\n )\n } else if (msgType === MessageType.WorkerRegistered) {\n const { worker_id } = message as WorkerRegisteredMessage\n this.workerId = worker_id\n console.debug('[iii] Worker registered with ID:', worker_id)\n this.startMetricsReporting()\n }\n }\n}\n\nexport const init = (address: string, options?: InitOptions): ISdk => new Sdk(address, options)\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,41 +1,20 @@
|
|
|
1
|
-
import { a as ApiResponse, i as ApiRequest, n as InitOptions, r as init, s as ISdk } from "./iii-
|
|
1
|
+
import { a as ApiResponse, i as ApiRequest, n as InitOptions, r as init, s as ISdk } from "./iii-BhtLRYBs.cjs";
|
|
2
2
|
import { Span } from "@opentelemetry/api";
|
|
3
3
|
|
|
4
4
|
//#region src/logger.d.ts
|
|
5
|
-
|
|
6
|
-
message: string;
|
|
7
|
-
trace_id?: string;
|
|
8
|
-
span_id?: string;
|
|
9
|
-
service_name?: string;
|
|
10
|
-
data?: any;
|
|
11
|
-
/** @deprecated Use service_name instead */
|
|
12
|
-
function_name?: string;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* @deprecated Use OpenTelemetry Logger directly via getLogger() from telemetry module.
|
|
16
|
-
* This invoker pattern is maintained for backward compatibility only.
|
|
17
|
-
*/
|
|
18
|
-
type LoggerInvoker = (function_id: string, params: LoggerParams) => Promise<void> | void;
|
|
5
|
+
|
|
19
6
|
declare class Logger {
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated This parameter is ignored. Logger now uses OpenTelemetry internally.
|
|
22
|
-
*/
|
|
23
|
-
private readonly invoker?;
|
|
24
7
|
private readonly traceId?;
|
|
25
8
|
private readonly serviceName?;
|
|
26
9
|
private readonly spanId?;
|
|
27
10
|
private _otelLogger;
|
|
28
11
|
private get otelLogger();
|
|
29
|
-
constructor(
|
|
30
|
-
/**
|
|
31
|
-
* @deprecated This parameter is ignored. Logger now uses OpenTelemetry internally.
|
|
32
|
-
*/
|
|
33
|
-
invoker?: LoggerInvoker | undefined, traceId?: string | undefined, serviceName?: string | undefined, spanId?: string | undefined);
|
|
12
|
+
constructor(traceId?: string | undefined, serviceName?: string | undefined, spanId?: string | undefined);
|
|
34
13
|
private emit;
|
|
35
|
-
info(message: string, data?:
|
|
36
|
-
warn(message: string, data?:
|
|
37
|
-
error(message: string, data?:
|
|
38
|
-
debug(message: string, data?:
|
|
14
|
+
info(message: string, data?: unknown): void;
|
|
15
|
+
warn(message: string, data?: unknown): void;
|
|
16
|
+
error(message: string, data?: unknown): void;
|
|
17
|
+
debug(message: string, data?: unknown): void;
|
|
39
18
|
}
|
|
40
19
|
//#endregion
|
|
41
20
|
//#region src/context.d.ts
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/logger.ts","../src/context.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/logger.ts","../src/context.ts"],"sourcesContent":[],"mappings":";;;;;ACaa,cDCA,MAAA,CCYZ;EAZe,iBAAA,OAAA;EAAoB,iBAAA,WAAA;EAAR,iBAAA,MAAA;EACrB,QAAA,WAAA;EACI,YAAA,UAAA,CAAA;EAAR,WAAA,CAAA,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA,EAAA,WAAA,CAAA,EAAA,MAAA,GAAA,SAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAAO,QAAA,IAAA;EAYG,IAAA,CAAA,OAAA,EASZ,MAAA,EAAA,IAAA,CAT6B,EAAA,OAS7B,CAAA,EAAA,IAAA;;;;;;;KAhCW,OAAA;UACF;EDQG;UCNH;;cAKG,+BACG,YAAY,QAAQ,SAC7B,YACJ,QAAQ;AAXC,cAuBC,UAtBH,EAAA,GAEA,GAoBoB,OApBhB"}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,41 +1,20 @@
|
|
|
1
|
-
import { a as ApiResponse, i as ApiRequest, n as InitOptions, r as init, s as ISdk } from "./iii-
|
|
1
|
+
import { a as ApiResponse, i as ApiRequest, n as InitOptions, r as init, s as ISdk } from "./iii-7FpY7bi9.mjs";
|
|
2
2
|
import { Span } from "@opentelemetry/api";
|
|
3
3
|
|
|
4
4
|
//#region src/logger.d.ts
|
|
5
|
-
|
|
6
|
-
message: string;
|
|
7
|
-
trace_id?: string;
|
|
8
|
-
span_id?: string;
|
|
9
|
-
service_name?: string;
|
|
10
|
-
data?: any;
|
|
11
|
-
/** @deprecated Use service_name instead */
|
|
12
|
-
function_name?: string;
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* @deprecated Use OpenTelemetry Logger directly via getLogger() from telemetry module.
|
|
16
|
-
* This invoker pattern is maintained for backward compatibility only.
|
|
17
|
-
*/
|
|
18
|
-
type LoggerInvoker = (function_id: string, params: LoggerParams) => Promise<void> | void;
|
|
5
|
+
|
|
19
6
|
declare class Logger {
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated This parameter is ignored. Logger now uses OpenTelemetry internally.
|
|
22
|
-
*/
|
|
23
|
-
private readonly invoker?;
|
|
24
7
|
private readonly traceId?;
|
|
25
8
|
private readonly serviceName?;
|
|
26
9
|
private readonly spanId?;
|
|
27
10
|
private _otelLogger;
|
|
28
11
|
private get otelLogger();
|
|
29
|
-
constructor(
|
|
30
|
-
/**
|
|
31
|
-
* @deprecated This parameter is ignored. Logger now uses OpenTelemetry internally.
|
|
32
|
-
*/
|
|
33
|
-
invoker?: LoggerInvoker | undefined, traceId?: string | undefined, serviceName?: string | undefined, spanId?: string | undefined);
|
|
12
|
+
constructor(traceId?: string | undefined, serviceName?: string | undefined, spanId?: string | undefined);
|
|
34
13
|
private emit;
|
|
35
|
-
info(message: string, data?:
|
|
36
|
-
warn(message: string, data?:
|
|
37
|
-
error(message: string, data?:
|
|
38
|
-
debug(message: string, data?:
|
|
14
|
+
info(message: string, data?: unknown): void;
|
|
15
|
+
warn(message: string, data?: unknown): void;
|
|
16
|
+
error(message: string, data?: unknown): void;
|
|
17
|
+
debug(message: string, data?: unknown): void;
|
|
39
18
|
}
|
|
40
19
|
//#endregion
|
|
41
20
|
//#region src/context.d.ts
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/logger.ts","../src/context.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/logger.ts","../src/context.ts"],"sourcesContent":[],"mappings":";;;;;ACaa,cDCA,MAAA,CCYZ;EAZe,iBAAA,OAAA;EAAoB,iBAAA,WAAA;EAAR,iBAAA,MAAA;EACrB,QAAA,WAAA;EACI,YAAA,UAAA,CAAA;EAAR,WAAA,CAAA,OAAA,CAAA,EAAA,MAAA,GAAA,SAAA,EAAA,WAAA,CAAA,EAAA,MAAA,GAAA,SAAA,EAAA,MAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EAAO,QAAA,IAAA;EAYG,IAAA,CAAA,OAAA,EASZ,MAAA,EAAA,IAAA,CAT6B,EAAA,OAS7B,CAAA,EAAA,IAAA;;;;;;;KAhCW,OAAA;UACF;EDQG;UCNH;;cAKG,+BACG,YAAY,QAAQ,SAC7B,YACJ,QAAQ;AAXC,cAuBC,UAtBH,EAAA,GAEA,GAoBoB,OApBhB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as EngineFunctions, E as DEFAULT_INVOCATION_TIMEOUT_MS, O as EngineTriggers, S as injectTraceparent, T as DEFAULT_BRIDGE_RECONNECTION_CONFIG, _ as extractContext, a as SeverityNumber$1, c as getLogger, d as initOtel, f as shutdownOtel, h as currentTraceId, i as safeStringify, l as getMeter, m as currentSpanId, n as stopWorkerGauges, o as SpanKind, p as withSpan, t as registerWorkerGauges, u as getTracer, x as injectBaggage } from "./otel-worker-gauges-
|
|
1
|
+
import { D as EngineFunctions, E as DEFAULT_INVOCATION_TIMEOUT_MS, O as EngineTriggers, S as injectTraceparent, T as DEFAULT_BRIDGE_RECONNECTION_CONFIG, _ as extractContext, a as SeverityNumber$1, c as getLogger, d as initOtel, f as shutdownOtel, h as currentTraceId, i as safeStringify, l as getMeter, m as currentSpanId, n as stopWorkerGauges, o as SpanKind, p as withSpan, t as registerWorkerGauges, u as getTracer, x as injectBaggage } from "./otel-worker-gauges-Dka1CFDy.mjs";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { context } from "@opentelemetry/api";
|
|
3
|
-
import
|
|
4
|
-
import * as os from "os";
|
|
4
|
+
import * as os from "node:os";
|
|
5
5
|
import { WebSocket } from "ws";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { SeverityNumber } from "@opentelemetry/api-logs";
|
|
@@ -29,8 +29,7 @@ var Logger = class {
|
|
|
29
29
|
if (!this._otelLogger) this._otelLogger = getLogger();
|
|
30
30
|
return this._otelLogger;
|
|
31
31
|
}
|
|
32
|
-
constructor(
|
|
33
|
-
this.invoker = invoker;
|
|
32
|
+
constructor(traceId, serviceName, spanId) {
|
|
34
33
|
this.traceId = traceId;
|
|
35
34
|
this.serviceName = serviceName;
|
|
36
35
|
this.spanId = spanId;
|
|
@@ -121,7 +120,7 @@ var Sdk = class {
|
|
|
121
120
|
this.triggerTypes.set(triggerType.id, {
|
|
122
121
|
message: {
|
|
123
122
|
...triggerType,
|
|
124
|
-
|
|
123
|
+
message_type: MessageType.RegisterTriggerType
|
|
125
124
|
},
|
|
126
125
|
handler
|
|
127
126
|
});
|
|
@@ -135,19 +134,18 @@ var Sdk = class {
|
|
|
135
134
|
};
|
|
136
135
|
this.registerTrigger = (trigger) => {
|
|
137
136
|
const id = crypto.randomUUID();
|
|
138
|
-
|
|
139
|
-
...trigger,
|
|
140
|
-
id
|
|
141
|
-
}, true);
|
|
142
|
-
this.triggers.set(id, {
|
|
137
|
+
const fullTrigger = {
|
|
143
138
|
...trigger,
|
|
144
139
|
id,
|
|
145
|
-
|
|
146
|
-
}
|
|
140
|
+
message_type: MessageType.RegisterTrigger
|
|
141
|
+
};
|
|
142
|
+
this.sendMessage(MessageType.RegisterTrigger, fullTrigger, true);
|
|
143
|
+
this.triggers.set(id, fullTrigger);
|
|
147
144
|
return { unregister: () => {
|
|
148
145
|
this.sendMessage(MessageType.UnregisterTrigger, {
|
|
149
146
|
id,
|
|
150
|
-
|
|
147
|
+
message_type: MessageType.UnregisterTrigger,
|
|
148
|
+
type: fullTrigger.type
|
|
151
149
|
});
|
|
152
150
|
this.triggers.delete(id);
|
|
153
151
|
} };
|
|
@@ -158,7 +156,7 @@ var Sdk = class {
|
|
|
158
156
|
this.functions.set(message.id, {
|
|
159
157
|
message: {
|
|
160
158
|
...message,
|
|
161
|
-
|
|
159
|
+
message_type: MessageType.RegisterFunction
|
|
162
160
|
},
|
|
163
161
|
handler: async (input, traceparent, baggage) => {
|
|
164
162
|
if (getTracer()) {
|
|
@@ -167,12 +165,12 @@ var Sdk = class {
|
|
|
167
165
|
const traceId = currentTraceId() ?? crypto.randomUUID();
|
|
168
166
|
const spanId = currentSpanId();
|
|
169
167
|
return withContext(async () => await handler(input), {
|
|
170
|
-
logger: new Logger(
|
|
168
|
+
logger: new Logger(traceId, message.id, spanId),
|
|
171
169
|
trace: span
|
|
172
170
|
});
|
|
173
171
|
}));
|
|
174
172
|
}
|
|
175
|
-
return withContext(async () => await handler(input), { logger: new Logger(
|
|
173
|
+
return withContext(async () => await handler(input), { logger: new Logger(crypto.randomUUID(), message.id) });
|
|
176
174
|
}
|
|
177
175
|
});
|
|
178
176
|
return {
|
|
@@ -187,7 +185,7 @@ var Sdk = class {
|
|
|
187
185
|
this.sendMessage(MessageType.RegisterService, message, true);
|
|
188
186
|
this.services.set(message.id, {
|
|
189
187
|
...message,
|
|
190
|
-
|
|
188
|
+
message_type: MessageType.RegisterService
|
|
191
189
|
});
|
|
192
190
|
};
|
|
193
191
|
this.call = async (function_id, data, timeoutMs) => {
|
|
@@ -239,11 +237,11 @@ var Sdk = class {
|
|
|
239
237
|
return (await this.call(EngineFunctions.LIST_WORKERS, {})).workers;
|
|
240
238
|
};
|
|
241
239
|
this.createStream = (streamName, stream) => {
|
|
242
|
-
this.registerFunction({ id: `stream
|
|
243
|
-
this.registerFunction({ id: `stream
|
|
244
|
-
this.registerFunction({ id: `stream
|
|
245
|
-
this.registerFunction({ id: `stream
|
|
246
|
-
this.registerFunction({ id: `stream
|
|
240
|
+
this.registerFunction({ id: `stream::get(${streamName})` }, stream.get.bind(stream));
|
|
241
|
+
this.registerFunction({ id: `stream::set(${streamName})` }, stream.set.bind(stream));
|
|
242
|
+
this.registerFunction({ id: `stream::delete(${streamName})` }, stream.delete.bind(stream));
|
|
243
|
+
this.registerFunction({ id: `stream::list(${streamName})` }, stream.list.bind(stream));
|
|
244
|
+
this.registerFunction({ id: `stream::list_groups(${streamName})` }, stream.listGroups.bind(stream));
|
|
247
245
|
};
|
|
248
246
|
this.onFunctionsAvailable = (callback) => {
|
|
249
247
|
this.functionsAvailableCallbacks.add(callback);
|
|
@@ -257,7 +255,7 @@ var Sdk = class {
|
|
|
257
255
|
return null;
|
|
258
256
|
});
|
|
259
257
|
this.functionsAvailableTrigger = this.registerTrigger({
|
|
260
|
-
|
|
258
|
+
type: EngineTriggers.FUNCTIONS_AVAILABLE,
|
|
261
259
|
function_id,
|
|
262
260
|
config: {}
|
|
263
261
|
});
|
|
@@ -288,7 +286,7 @@ var Sdk = class {
|
|
|
288
286
|
return null;
|
|
289
287
|
});
|
|
290
288
|
this.logTrigger = this.registerTrigger({
|
|
291
|
-
|
|
289
|
+
type: EngineTriggers.LOG,
|
|
292
290
|
function_id,
|
|
293
291
|
config: {
|
|
294
292
|
level: "all",
|
|
@@ -337,8 +335,8 @@ var Sdk = class {
|
|
|
337
335
|
...DEFAULT_BRIDGE_RECONNECTION_CONFIG,
|
|
338
336
|
...options?.reconnectionConfig
|
|
339
337
|
};
|
|
340
|
-
|
|
341
|
-
...options
|
|
338
|
+
initOtel({
|
|
339
|
+
...options?.otel,
|
|
342
340
|
engineWsUrl: this.address
|
|
343
341
|
});
|
|
344
342
|
this.connect();
|
|
@@ -442,7 +440,7 @@ var Sdk = class {
|
|
|
442
440
|
const pending = this.messagesToSend;
|
|
443
441
|
this.messagesToSend = [];
|
|
444
442
|
for (const message of pending) {
|
|
445
|
-
if (message.type === MessageType.InvokeFunction && message.invocation_id && !this.invocations.has(message.invocation_id)) continue;
|
|
443
|
+
if (message.type === MessageType.InvokeFunction && typeof message.invocation_id === "string" && !this.invocations.has(message.invocation_id)) continue;
|
|
446
444
|
this.sendMessageRaw(JSON.stringify(message));
|
|
447
445
|
}
|
|
448
446
|
this.registerWorkerMetadata();
|
|
@@ -459,13 +457,41 @@ var Sdk = class {
|
|
|
459
457
|
this.logError("Exception while sending message", error);
|
|
460
458
|
}
|
|
461
459
|
}
|
|
462
|
-
|
|
463
|
-
const
|
|
464
|
-
|
|
465
|
-
type
|
|
460
|
+
toWireFormat(messageType, message) {
|
|
461
|
+
const { message_type: _, ...rest } = message;
|
|
462
|
+
if (messageType === MessageType.RegisterTrigger && "type" in message) {
|
|
463
|
+
const { type: triggerType, ...triggerRest } = message;
|
|
464
|
+
return {
|
|
465
|
+
type: messageType,
|
|
466
|
+
...triggerRest,
|
|
467
|
+
trigger_type: triggerType
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
if (messageType === MessageType.UnregisterTrigger && "type" in message) {
|
|
471
|
+
const { type: triggerType, ...triggerRest } = message;
|
|
472
|
+
return {
|
|
473
|
+
type: messageType,
|
|
474
|
+
...triggerRest,
|
|
475
|
+
trigger_type: triggerType
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
if (messageType === MessageType.TriggerRegistrationResult && "type" in message) {
|
|
479
|
+
const { type: triggerType, ...resultRest } = message;
|
|
480
|
+
return {
|
|
481
|
+
type: messageType,
|
|
482
|
+
...resultRest,
|
|
483
|
+
trigger_type: triggerType
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
return {
|
|
487
|
+
type: messageType,
|
|
488
|
+
...rest
|
|
466
489
|
};
|
|
467
|
-
|
|
468
|
-
|
|
490
|
+
}
|
|
491
|
+
sendMessage(messageType, message, skipIfClosed = false) {
|
|
492
|
+
const wireMessage = this.toWireFormat(messageType, message);
|
|
493
|
+
if (this.isOpen()) this.sendMessageRaw(JSON.stringify(wireMessage));
|
|
494
|
+
else if (!skipIfClosed) this.messagesToSend.push(wireMessage);
|
|
469
495
|
}
|
|
470
496
|
logError(message, error) {
|
|
471
497
|
const otelLogger = getLogger();
|
|
@@ -542,8 +568,8 @@ var Sdk = class {
|
|
|
542
568
|
});
|
|
543
569
|
}
|
|
544
570
|
async onRegisterTrigger(message) {
|
|
545
|
-
const
|
|
546
|
-
const
|
|
571
|
+
const { trigger_type, id, function_id, config } = message;
|
|
572
|
+
const triggerTypeData = this.triggerTypes.get(trigger_type);
|
|
547
573
|
if (triggerTypeData) try {
|
|
548
574
|
await triggerTypeData.handler.registerTrigger({
|
|
549
575
|
id,
|
|
@@ -552,13 +578,15 @@ var Sdk = class {
|
|
|
552
578
|
});
|
|
553
579
|
this.sendMessage(MessageType.TriggerRegistrationResult, {
|
|
554
580
|
id,
|
|
555
|
-
|
|
581
|
+
message_type: MessageType.TriggerRegistrationResult,
|
|
582
|
+
type: trigger_type,
|
|
556
583
|
function_id
|
|
557
584
|
});
|
|
558
585
|
} catch (error) {
|
|
559
586
|
this.sendMessage(MessageType.TriggerRegistrationResult, {
|
|
560
587
|
id,
|
|
561
|
-
|
|
588
|
+
message_type: MessageType.TriggerRegistrationResult,
|
|
589
|
+
type: trigger_type,
|
|
562
590
|
function_id,
|
|
563
591
|
error: {
|
|
564
592
|
code: "trigger_registration_failed",
|
|
@@ -568,7 +596,8 @@ var Sdk = class {
|
|
|
568
596
|
}
|
|
569
597
|
else this.sendMessage(MessageType.TriggerRegistrationResult, {
|
|
570
598
|
id,
|
|
571
|
-
|
|
599
|
+
message_type: MessageType.TriggerRegistrationResult,
|
|
600
|
+
type: trigger_type,
|
|
572
601
|
function_id,
|
|
573
602
|
error: {
|
|
574
603
|
code: "trigger_type_not_found",
|
|
@@ -577,25 +606,25 @@ var Sdk = class {
|
|
|
577
606
|
});
|
|
578
607
|
}
|
|
579
608
|
onMessage(socketMessage) {
|
|
580
|
-
let
|
|
609
|
+
let msgType;
|
|
581
610
|
let message;
|
|
582
611
|
try {
|
|
583
612
|
const parsed = JSON.parse(socketMessage.toString());
|
|
584
|
-
|
|
613
|
+
msgType = parsed.type;
|
|
585
614
|
const { type: _, ...rest } = parsed;
|
|
586
615
|
message = rest;
|
|
587
616
|
} catch (error) {
|
|
588
617
|
this.logError("Failed to parse incoming message", error);
|
|
589
618
|
return;
|
|
590
619
|
}
|
|
591
|
-
if (
|
|
620
|
+
if (msgType === MessageType.InvocationResult) {
|
|
592
621
|
const { invocation_id, result, error } = message;
|
|
593
622
|
this.onInvocationResult(invocation_id, result, error);
|
|
594
|
-
} else if (
|
|
623
|
+
} else if (msgType === MessageType.InvokeFunction) {
|
|
595
624
|
const { invocation_id, function_id, data, traceparent, baggage } = message;
|
|
596
625
|
this.onInvokeFunction(invocation_id, function_id, data, traceparent, baggage);
|
|
597
|
-
} else if (
|
|
598
|
-
else if (
|
|
626
|
+
} else if (msgType === MessageType.RegisterTrigger) this.onRegisterTrigger(message);
|
|
627
|
+
else if (msgType === MessageType.WorkerRegistered) {
|
|
599
628
|
const { worker_id } = message;
|
|
600
629
|
this.workerId = worker_id;
|
|
601
630
|
console.debug("[iii] Worker registered with ID:", worker_id);
|