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.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["getOtelLogger","invoker?: LoggerInvoker","traceId?: string","serviceName?: string","spanId?: string","attributes: Record<string, string | undefined>","otelContext","address: string","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.mjs","names":["getOtelLogger","traceId?: string","serviceName?: string","spanId?: string","attributes: Record<string, string | undefined>","otelContext","address: string","fullTrigger: RegisterTriggerMessage","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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"}
|
|
@@ -4,7 +4,7 @@ let ws = require("ws");
|
|
|
4
4
|
let __opentelemetry_api_logs = require("@opentelemetry/api-logs");
|
|
5
5
|
let __opentelemetry_resources = require("@opentelemetry/resources");
|
|
6
6
|
let __opentelemetry_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
7
|
-
let
|
|
7
|
+
let node_crypto = require("node:crypto");
|
|
8
8
|
let __opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base");
|
|
9
9
|
let __opentelemetry_sdk_metrics = require("@opentelemetry/sdk-metrics");
|
|
10
10
|
let __opentelemetry_core = require("@opentelemetry/core");
|
|
@@ -20,9 +20,9 @@ let node_perf_hooks = require("node:perf_hooks");
|
|
|
20
20
|
*/
|
|
21
21
|
/** Engine function paths for internal operations */
|
|
22
22
|
const EngineFunctions = {
|
|
23
|
-
LIST_FUNCTIONS: "engine
|
|
24
|
-
LIST_WORKERS: "engine
|
|
25
|
-
REGISTER_WORKER: "engine
|
|
23
|
+
LIST_FUNCTIONS: "engine::functions::list",
|
|
24
|
+
LIST_WORKERS: "engine::workers::list",
|
|
25
|
+
REGISTER_WORKER: "engine::workers::register"
|
|
26
26
|
};
|
|
27
27
|
/** Engine trigger types */
|
|
28
28
|
const EngineTriggers = {
|
|
@@ -31,10 +31,10 @@ const EngineTriggers = {
|
|
|
31
31
|
};
|
|
32
32
|
/** Log function paths */
|
|
33
33
|
const LogFunctions = {
|
|
34
|
-
INFO: "log
|
|
35
|
-
WARN: "log
|
|
36
|
-
ERROR: "log
|
|
37
|
-
DEBUG: "log
|
|
34
|
+
INFO: "engine::log::info",
|
|
35
|
+
WARN: "engine::log::warn",
|
|
36
|
+
ERROR: "engine::log::error",
|
|
37
|
+
DEBUG: "engine::log::debug"
|
|
38
38
|
};
|
|
39
39
|
/** Default reconnection configuration */
|
|
40
40
|
const DEFAULT_BRIDGE_RECONNECTION_CONFIG = {
|
|
@@ -64,6 +64,21 @@ const DEFAULT_RECONNECTION_CONFIG = {
|
|
|
64
64
|
jitterFactor: .3,
|
|
65
65
|
maxRetries: -1
|
|
66
66
|
};
|
|
67
|
+
/** Default configuration values for OpenTelemetry initialization. */
|
|
68
|
+
const DEFAULT_OTEL_CONFIG = {
|
|
69
|
+
enabled: true,
|
|
70
|
+
serviceName: "iii-node",
|
|
71
|
+
serviceVersion: "unknown",
|
|
72
|
+
engineWsUrl: "ws://localhost:49134",
|
|
73
|
+
metricsEnabled: true,
|
|
74
|
+
metricsExportIntervalMs: 6e4
|
|
75
|
+
};
|
|
76
|
+
/** Parse a boolean environment variable, recognizing 'false', '0', 'no', 'off' as false. */
|
|
77
|
+
function parseBoolEnv(value, defaultValue) {
|
|
78
|
+
if (value === void 0) return defaultValue;
|
|
79
|
+
const lower = value.toLowerCase();
|
|
80
|
+
return lower !== "false" && lower !== "0" && lower !== "no" && lower !== "off";
|
|
81
|
+
}
|
|
67
82
|
|
|
68
83
|
//#endregion
|
|
69
84
|
//#region src/telemetry-system/connection.ts
|
|
@@ -456,7 +471,7 @@ function currentSpanId() {
|
|
|
456
471
|
function injectTraceparent() {
|
|
457
472
|
const carrier = {};
|
|
458
473
|
__opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
|
|
459
|
-
return carrier
|
|
474
|
+
return carrier.traceparent;
|
|
460
475
|
}
|
|
461
476
|
/**
|
|
462
477
|
* Extract a trace context from a W3C traceparent header string.
|
|
@@ -471,7 +486,7 @@ function extractTraceparent(traceparent) {
|
|
|
471
486
|
function injectBaggage() {
|
|
472
487
|
const carrier = {};
|
|
473
488
|
__opentelemetry_api.propagation.inject(__opentelemetry_api.context.active(), carrier);
|
|
474
|
-
return carrier
|
|
489
|
+
return carrier.baggage;
|
|
475
490
|
}
|
|
476
491
|
/**
|
|
477
492
|
* Extract baggage from a W3C baggage header string.
|
|
@@ -485,8 +500,8 @@ function extractBaggage(baggage) {
|
|
|
485
500
|
*/
|
|
486
501
|
function extractContext(traceparent, baggage) {
|
|
487
502
|
const carrier = {};
|
|
488
|
-
if (traceparent) carrier
|
|
489
|
-
if (baggage) carrier
|
|
503
|
+
if (traceparent) carrier.traceparent = traceparent;
|
|
504
|
+
if (baggage) carrier.baggage = baggage;
|
|
490
505
|
return __opentelemetry_api.propagation.extract(__opentelemetry_api.context.active(), carrier);
|
|
491
506
|
}
|
|
492
507
|
/**
|
|
@@ -544,16 +559,16 @@ let serviceName = "iii-node-iii";
|
|
|
544
559
|
* This should be called once at application startup.
|
|
545
560
|
*/
|
|
546
561
|
function initOtel(config = {}) {
|
|
547
|
-
if (!(config.enabled ?? (process.env.OTEL_ENABLED
|
|
548
|
-
console.
|
|
562
|
+
if (!(config.enabled ?? parseBoolEnv(process.env.OTEL_ENABLED, DEFAULT_OTEL_CONFIG.enabled))) {
|
|
563
|
+
console.debug("[OTel] OpenTelemetry is disabled. To enable, remove OTEL_ENABLED=false or set enabled: true in config.");
|
|
549
564
|
return;
|
|
550
565
|
}
|
|
551
566
|
if (config.instrumentations?.length) (0, __opentelemetry_instrumentation.registerInstrumentations)({ instrumentations: config.instrumentations });
|
|
552
|
-
serviceName = config.serviceName ?? process.env.OTEL_SERVICE_NAME ??
|
|
553
|
-
const serviceVersion = config.serviceVersion ?? process.env.SERVICE_VERSION ??
|
|
567
|
+
serviceName = config.serviceName ?? process.env.OTEL_SERVICE_NAME ?? DEFAULT_OTEL_CONFIG.serviceName;
|
|
568
|
+
const serviceVersion = config.serviceVersion ?? process.env.SERVICE_VERSION ?? DEFAULT_OTEL_CONFIG.serviceVersion;
|
|
554
569
|
const serviceNamespace = config.serviceNamespace ?? process.env.SERVICE_NAMESPACE;
|
|
555
|
-
const serviceInstanceId = config.serviceInstanceId ?? process.env.SERVICE_INSTANCE_ID ?? (0,
|
|
556
|
-
const engineWsUrl = config.engineWsUrl ?? process.env.III_BRIDGE_URL ??
|
|
570
|
+
const serviceInstanceId = config.serviceInstanceId ?? process.env.SERVICE_INSTANCE_ID ?? (0, node_crypto.randomUUID)();
|
|
571
|
+
const engineWsUrl = config.engineWsUrl ?? process.env.III_BRIDGE_URL ?? DEFAULT_OTEL_CONFIG.engineWsUrl;
|
|
557
572
|
const resourceAttributes = {
|
|
558
573
|
[__opentelemetry_semantic_conventions.ATTR_SERVICE_NAME]: serviceName,
|
|
559
574
|
[ATTR_SERVICE_VERSION]: serviceVersion,
|
|
@@ -569,10 +584,10 @@ function initOtel(config = {}) {
|
|
|
569
584
|
__opentelemetry_api.propagation.setGlobalPropagator(new __opentelemetry_core.CompositePropagator({ propagators: [new __opentelemetry_core.W3CTraceContextPropagator(), new __opentelemetry_core.W3CBaggagePropagator()] }));
|
|
570
585
|
tracerProvider.register();
|
|
571
586
|
tracer = __opentelemetry_api.trace.getTracer(serviceName);
|
|
572
|
-
console.
|
|
573
|
-
if (config.metricsEnabled ?? (process.env.OTEL_METRICS_ENABLED
|
|
587
|
+
console.debug(`[OTel] Traces initialized: engine=${engineWsUrl}, service=${serviceName}`);
|
|
588
|
+
if (config.metricsEnabled ?? parseBoolEnv(process.env.OTEL_METRICS_ENABLED, DEFAULT_OTEL_CONFIG.metricsEnabled)) {
|
|
574
589
|
const metricsExporter = new EngineMetricsExporter(sharedConnection);
|
|
575
|
-
const exportIntervalMs = config.metricsExportIntervalMs ??
|
|
590
|
+
const exportIntervalMs = config.metricsExportIntervalMs ?? DEFAULT_OTEL_CONFIG.metricsExportIntervalMs;
|
|
576
591
|
meterProvider = new __opentelemetry_sdk_metrics.MeterProvider({
|
|
577
592
|
resource,
|
|
578
593
|
readers: [new __opentelemetry_sdk_metrics.PeriodicExportingMetricReader({
|
|
@@ -582,13 +597,13 @@ function initOtel(config = {}) {
|
|
|
582
597
|
});
|
|
583
598
|
__opentelemetry_api.metrics.setGlobalMeterProvider(meterProvider);
|
|
584
599
|
meter = meterProvider.getMeter(serviceName);
|
|
585
|
-
console.
|
|
600
|
+
console.debug(`[OTel] Metrics initialized: interval=${exportIntervalMs}ms`);
|
|
586
601
|
}
|
|
587
602
|
const logExporter = new EngineLogExporter(sharedConnection);
|
|
588
603
|
loggerProvider = new __opentelemetry_sdk_logs.LoggerProvider({ resource });
|
|
589
604
|
loggerProvider.addLogRecordProcessor(new __opentelemetry_sdk_logs.SimpleLogRecordProcessor(logExporter));
|
|
590
605
|
logger = loggerProvider.getLogger(serviceName);
|
|
591
|
-
console.
|
|
606
|
+
console.debug("[OTel] Logs initialized");
|
|
592
607
|
}
|
|
593
608
|
/**
|
|
594
609
|
* Shutdown OpenTelemetry, flushing any pending data.
|
|
@@ -1061,4 +1076,4 @@ Object.defineProperty(exports, 'withSpan', {
|
|
|
1061
1076
|
return withSpan;
|
|
1062
1077
|
}
|
|
1063
1078
|
});
|
|
1064
|
-
//# sourceMappingURL=otel-worker-gauges-
|
|
1079
|
+
//# sourceMappingURL=otel-worker-gauges-8AUNGQgJ.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"otel-worker-gauges-8AUNGQgJ.cjs","names":["DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig","DEFAULT_RECONNECTION_CONFIG: ReconnectionConfig","WebSocket","JsonTraceSerializer","ExportResultCode","metrics","JsonMetricsSerializer","ExportResultCode","JsonLogsSerializer","ExportResultCode","trace","carrier: Record<string, string>","context","propagation","entries: Record<string, string>","sharedConnection: SharedEngineConnection | null","tracerProvider: NodeTracerProvider | null","meterProvider: MeterProvider | null","loggerProvider: LoggerProvider | null","tracer: Tracer | null","meter: Meter | null","logger: Logger | null","serviceName: string","resourceAttributes: Record<string, string>","ATTR_SERVICE_NAME","Resource","NodeTracerProvider","SimpleSpanProcessor","CompositePropagator","W3CTraceContextPropagator","W3CBaggagePropagator","trace","MeterProvider","PeriodicExportingMetricReader","LoggerProvider","SimpleLogRecordProcessor","noopSpan: Span","context","SpanKind","SpanStatusCode","performance","metricsCollector: WorkerMetricsCollector | null","registeredMeter: Meter | null","registeredBatchCallback: ((observableResult: BatchObservableResult) => void) | null","registeredObservables: Observable[]","meter","metrics"],"sources":["../src/iii-constants.ts","../src/telemetry-system/types.ts","../src/telemetry-system/connection.ts","../src/telemetry-system/span-exporter.ts","../src/telemetry-system/metrics-exporter.ts","../src/telemetry-system/log-exporter.ts","../src/telemetry-system/context.ts","../src/telemetry-system/index.ts","../src/utils.ts","../src/worker-metrics.ts","../src/otel-worker-gauges.ts"],"sourcesContent":["/**\n * Constants for the III module.\n */\n\n/** Engine function paths for internal operations */\nexport const EngineFunctions = {\n LIST_FUNCTIONS: 'engine::functions::list',\n LIST_WORKERS: 'engine::workers::list',\n REGISTER_WORKER: 'engine::workers::register',\n} as const\n\n/** Engine trigger types */\nexport const EngineTriggers = {\n FUNCTIONS_AVAILABLE: 'engine::functions-available',\n LOG: 'log',\n} as const\n\n/** Log function paths */\nexport const LogFunctions = {\n INFO: 'engine::log::info',\n WARN: 'engine::log::warn',\n ERROR: 'engine::log::error',\n DEBUG: 'engine::log::debug',\n} as const\n\n/** Connection state for the III WebSocket */\nexport type IIIConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface IIIReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_BRIDGE_RECONNECTION_CONFIG: IIIReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Default invocation timeout in milliseconds */\nexport const DEFAULT_INVOCATION_TIMEOUT_MS = 30000\n","/**\n * Types, interfaces, and constants for the OpenTelemetry module.\n */\n\nimport type { Instrumentation } from '@opentelemetry/instrumentation'\n\n// Semantic convention constants for compatibility across versions\nexport const ATTR_SERVICE_VERSION = 'service.version'\nexport const ATTR_SERVICE_NAMESPACE = 'service.namespace'\nexport const ATTR_SERVICE_INSTANCE_ID = 'service.instance.id'\n\n/** Magic prefixes for binary frames over WebSocket */\nexport const PREFIX_TRACES = 'OTLP'\nexport const PREFIX_METRICS = 'MTRC'\nexport const PREFIX_LOGS = 'LOGS'\n\n/** Connection state for the shared WebSocket */\nexport type ConnectionState =\n | 'disconnected'\n | 'connecting'\n | 'connected'\n | 'reconnecting'\n | 'failed'\n\n/** Configuration for WebSocket reconnection behavior */\nexport interface ReconnectionConfig {\n /** Starting delay in milliseconds (default: 1000ms) */\n initialDelayMs: number\n /** Maximum delay cap in milliseconds (default: 30000ms) */\n maxDelayMs: number\n /** Exponential backoff multiplier (default: 2) */\n backoffMultiplier: number\n /** Random jitter factor 0-1 (default: 0.3) */\n jitterFactor: number\n /** Maximum retry attempts, -1 for infinite (default: -1) */\n maxRetries: number\n}\n\n/** Default reconnection configuration */\nexport const DEFAULT_RECONNECTION_CONFIG: ReconnectionConfig = {\n initialDelayMs: 1000,\n maxDelayMs: 30000,\n backoffMultiplier: 2,\n jitterFactor: 0.3,\n maxRetries: -1,\n}\n\n/** Configuration for OpenTelemetry initialization. */\nexport interface OtelConfig {\n /** Whether OpenTelemetry export is enabled. Defaults to true. Set to false or OTEL_ENABLED=false/0/no/off to disable. */\n enabled?: boolean\n /** The service name to report. Defaults to OTEL_SERVICE_NAME or \"iii-node\". */\n serviceName?: string\n /** The service version to report. Defaults to SERVICE_VERSION env var or \"unknown\". */\n serviceVersion?: string\n /** The service namespace to report. Defaults to SERVICE_NAMESPACE env var. */\n serviceNamespace?: string\n /** The service instance ID to report. Defaults to SERVICE_INSTANCE_ID env var or auto-generated UUID. */\n serviceInstanceId?: string\n /** III Engine WebSocket URL. Defaults to III_BRIDGE_URL or \"ws://localhost:49134\". */\n engineWsUrl?: string\n /** OpenTelemetry instrumentations to register (e.g., PrismaInstrumentation). */\n instrumentations?: Instrumentation[]\n /** Whether OpenTelemetry metrics export is enabled. Defaults to true. Set to false or OTEL_METRICS_ENABLED=false/0/no/off to disable. */\n metricsEnabled?: boolean\n /** Metrics export interval in milliseconds. Defaults to 60000 (60 seconds). */\n metricsExportIntervalMs?: number\n /** Optional reconnection configuration for the WebSocket connection. */\n reconnectionConfig?: Partial<ReconnectionConfig>\n}\n\n/** Default configuration values for OpenTelemetry initialization. */\nexport const DEFAULT_OTEL_CONFIG = {\n enabled: true,\n serviceName: 'iii-node',\n serviceVersion: 'unknown',\n engineWsUrl: 'ws://localhost:49134',\n metricsEnabled: true,\n metricsExportIntervalMs: 60000,\n} as const satisfies Partial<OtelConfig>\n\n/** Parse a boolean environment variable, recognizing 'false', '0', 'no', 'off' as false. */\nexport function parseBoolEnv(value: string | undefined, defaultValue: boolean): boolean {\n if (value === undefined) return defaultValue\n const lower = value.toLowerCase()\n return lower !== 'false' && lower !== '0' && lower !== 'no' && lower !== 'off'\n}\n","/**\n * Shared WebSocket connection for OpenTelemetry exporters.\n */\n\nimport { WebSocket } from 'ws'\nimport { type ConnectionState, type ReconnectionConfig, DEFAULT_RECONNECTION_CONFIG } from './types'\n\n/**\n * Shared WebSocket connection for all OTEL exporters (traces, metrics, logs).\n * Uses a single connection with message prefixes to identify signal type.\n */\nexport class SharedEngineConnection {\n private static readonly MAX_PENDING_MESSAGES = 1000\n private ws: WebSocket | null = null\n private wsUrl: string\n private connecting = false\n private shuttingDown = false\n private pendingMessages: Array<{ frame: Buffer; callback?: (err?: Error) => void }> = []\n private reconnectAttempt = 0\n private reconnectTimeout: NodeJS.Timeout | null = null\n private config: ReconnectionConfig\n private state: ConnectionState = 'disconnected'\n private onConnectedCallbacks: Array<() => void> = []\n\n constructor(wsUrl: string, config: Partial<ReconnectionConfig> = {}) {\n this.wsUrl = wsUrl\n this.config = { ...DEFAULT_RECONNECTION_CONFIG, ...config }\n this.connect()\n }\n\n private connect(): void {\n if (this.connecting || (this.ws && this.ws.readyState === WebSocket.OPEN)) {\n return\n }\n\n this.connecting = true\n this.state = 'connecting'\n\n try {\n this.ws = new WebSocket(this.wsUrl)\n\n this.ws.on('open', () => {\n this.connecting = false\n this.state = 'connected'\n console.log(`[OTel] Connected to engine at ${this.wsUrl}`)\n\n // Reset reconnection state\n if (this.reconnectAttempt > 0) {\n console.log('[OTel] Successfully reconnected')\n }\n this.reconnectAttempt = 0\n\n // Clear any pending reconnect timer to prevent race conditions\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = null\n }\n\n // Flush pending messages\n const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n for (const { frame, callback } of pending) {\n this.ws?.send(frame, err => callback?.(err))\n }\n\n // Notify callbacks\n for (const cb of this.onConnectedCallbacks) {\n cb()\n }\n })\n\n this.ws.on('close', () => {\n this.connecting = false\n this.ws = null\n\n // Skip reconnection if we're shutting down intentionally\n if (this.shuttingDown) {\n this.state = 'disconnected'\n console.log('[OTel] Connection closed during shutdown')\n return\n }\n\n this.state = 'disconnected'\n console.log('[OTel] Disconnected from engine, will reconnect...')\n this.scheduleReconnect()\n })\n\n this.ws.on('error', err => {\n this.connecting = false\n\n // Skip error handling if we're shutting down intentionally\n if (this.shuttingDown) {\n return\n }\n\n console.error('[OTel] WebSocket error:', err.message)\n })\n } catch (err) {\n this.connecting = false\n console.error('[OTel] Connection failed:', err)\n this.scheduleReconnect()\n }\n }\n\n private scheduleReconnect(): void {\n if (this.config.maxRetries !== -1 && this.reconnectAttempt >= this.config.maxRetries) {\n this.state = 'failed'\n console.error(`[OTel] Max retries (${this.config.maxRetries}) reached, giving up`)\n\n // Notify pending message callbacks that they won't be delivered\n const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n const failedError = new Error('Connection failed after max retries')\n for (const { callback } of pending) {\n callback?.(failedError)\n }\n return\n }\n\n if (this.reconnectTimeout) {\n return // Already scheduled\n }\n\n const exponentialDelay =\n this.config.initialDelayMs * this.config.backoffMultiplier ** this.reconnectAttempt\n const cappedDelay = Math.min(exponentialDelay, this.config.maxDelayMs)\n const jitter = cappedDelay * this.config.jitterFactor * (2 * Math.random() - 1)\n const delay = Math.max(0, Math.floor(cappedDelay + jitter))\n\n this.state = 'reconnecting'\n console.log(`[OTel] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempt + 1})...`)\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null\n this.reconnectAttempt++\n this.connect()\n }, delay)\n }\n\n /**\n * Send a message with a signal prefix.\n */\n send(prefix: string, data: Uint8Array, callback?: (err?: Error) => void): void {\n const prefixBytes = Buffer.from(prefix, 'utf-8')\n const frame = Buffer.concat([prefixBytes, Buffer.from(data)])\n\n if (this.ws && this.ws.readyState === WebSocket.OPEN) {\n this.ws.send(frame, callback)\n } else {\n // Queue for later with bounded size to prevent memory exhaustion\n if (this.pendingMessages.length >= SharedEngineConnection.MAX_PENDING_MESSAGES) {\n console.warn('[OTel] Pending message queue full, dropping oldest message')\n const dropped = this.pendingMessages.shift()\n dropped?.callback?.(new Error('Message dropped due to queue overflow'))\n }\n this.pendingMessages.push({ frame, callback })\n this.connect()\n }\n }\n\n /**\n * Register a callback to be called when connected.\n */\n onConnected(callback: () => void): void {\n this.onConnectedCallbacks.push(callback)\n if (this.state === 'connected') {\n callback()\n }\n }\n\n /**\n * Get the current connection state.\n */\n getState(): ConnectionState {\n return this.state\n }\n\n /**\n * Shutdown the connection.\n */\n async shutdown(): Promise<void> {\n // Set shutdown flag to prevent reconnection attempts\n this.shuttingDown = true\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout)\n this.reconnectTimeout = null\n }\n\n if (this.ws) {\n this.ws.close()\n this.ws = null\n }\n\n // Notify pending message callbacks that they won't be delivered\n const pending = this.pendingMessages.splice(0, this.pendingMessages.length)\n const shutdownError = new Error('Connection shutdown before message could be sent')\n for (const { callback } of pending) {\n callback?.(shutdownError)\n }\n this.onConnectedCallbacks = []\n this.state = 'disconnected'\n }\n}\n","/**\n * Span exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base'\nimport { JsonTraceSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_TRACES } from './types'\n\n/**\n * Span exporter using the shared WebSocket connection.\n */\nexport class EngineSpanExporter implements SpanExporter {\n private static readonly MAX_PENDING_EXPORTS = 100\n private connection: SharedEngineConnection\n private pendingExports: Array<{\n spans: ReadableSpan[]\n resultCallback?: (result: ExportResult) => void\n }> = []\n\n constructor(connection: SharedEngineConnection) {\n this.connection = connection\n this.connection.onConnected(() => this.flushPending())\n }\n\n private flushPending(): void {\n const pending = this.pendingExports.splice(0, this.pendingExports.length)\n for (const { spans, resultCallback } of pending) {\n this.sendExport(spans, resultCallback)\n }\n }\n\n private sendExport(spans: ReadableSpan[], resultCallback?: (result: ExportResult) => void): void {\n try {\n const serialized = JsonTraceSerializer.serializeRequest(spans)\n if (!serialized) {\n resultCallback?.({ code: ExportResultCode.SUCCESS })\n return\n }\n\n this.connection.send(PREFIX_TRACES, serialized, err => {\n if (err) {\n console.error('[OTel] Failed to send spans:', err.message)\n resultCallback?.({ code: ExportResultCode.FAILED, error: err })\n } else {\n resultCallback?.({ code: ExportResultCode.SUCCESS })\n }\n })\n } catch (err) {\n console.error('[OTel] Error exporting spans:', err)\n resultCallback?.({ code: ExportResultCode.FAILED, error: err as Error })\n }\n }\n\n private doExport(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {\n if (this.connection.getState() !== 'connected') {\n if (this.pendingExports.length >= EngineSpanExporter.MAX_PENDING_EXPORTS) {\n const dropped = this.pendingExports.shift()\n dropped?.resultCallback?.({\n code: ExportResultCode.FAILED,\n error: new Error('Queue overflow'),\n })\n console.warn('[OTel] Spans export queue full, dropped oldest entry')\n }\n this.pendingExports.push({ spans, resultCallback })\n // Don't call resultCallback here - it will be called when actually sent or on shutdown\n return\n }\n\n this.sendExport(spans, resultCallback)\n }\n\n export(spans: ReadableSpan[], resultCallback: (result: ExportResult) => void): void {\n this.doExport(spans, resultCallback)\n }\n\n async shutdown(): Promise<void> {\n const pending = this.pendingExports.splice(0, this.pendingExports.length)\n const shutdownError = new Error('Exporter shutdown before export completed')\n for (const { resultCallback } of pending) {\n resultCallback?.({ code: ExportResultCode.FAILED, error: shutdownError })\n }\n }\n\n async forceFlush(): Promise<void> {\n // No-op, spans are sent immediately\n }\n}\n","/**\n * Metrics exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { PushMetricExporter, ResourceMetrics } from '@opentelemetry/sdk-metrics'\nimport { JsonMetricsSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_METRICS } from './types'\n\n/**\n * Metrics exporter using the shared WebSocket connection.\n */\nexport class EngineMetricsExporter implements PushMetricExporter {\n private static readonly MAX_PENDING_EXPORTS = 100\n private connection: SharedEngineConnection\n private pendingExports: Array<{\n metrics: ResourceMetrics\n resultCallback?: (result: ExportResult) => void\n }> = []\n\n constructor(connection: SharedEngineConnection) {\n this.connection = connection\n this.connection.onConnected(() => this.flushPending())\n }\n\n private flushPending(): void {\n const pending = this.pendingExports.splice(0, this.pendingExports.length)\n for (const { metrics, resultCallback } of pending) {\n this.sendExport(metrics, resultCallback)\n }\n }\n\n private sendExport(\n metricsData: ResourceMetrics,\n resultCallback?: (result: ExportResult) => void,\n ): void {\n try {\n const serialized = JsonMetricsSerializer.serializeRequest(metricsData)\n if (!serialized) {\n resultCallback?.({ code: ExportResultCode.SUCCESS })\n return\n }\n\n this.connection.send(PREFIX_METRICS, serialized, err => {\n if (err) {\n console.error('[OTel] Failed to send metrics:', err.message)\n resultCallback?.({ code: ExportResultCode.FAILED, error: err })\n } else {\n resultCallback?.({ code: ExportResultCode.SUCCESS })\n }\n })\n } catch (err) {\n console.error('[OTel] Error exporting metrics:', err)\n resultCallback?.({ code: ExportResultCode.FAILED, error: err as Error })\n }\n }\n\n private doExport(\n metricsData: ResourceMetrics,\n resultCallback: (result: ExportResult) => void,\n ): void {\n if (this.connection.getState() !== 'connected') {\n if (this.pendingExports.length >= EngineMetricsExporter.MAX_PENDING_EXPORTS) {\n const dropped = this.pendingExports.shift()\n dropped?.resultCallback?.({\n code: ExportResultCode.FAILED,\n error: new Error('Queue overflow'),\n })\n console.warn('[OTel] Metrics export queue full, dropped oldest entry')\n }\n this.pendingExports.push({ metrics: metricsData, resultCallback })\n // Don't call resultCallback here - it will be called when actually sent or on shutdown\n return\n }\n\n this.sendExport(metricsData, resultCallback)\n }\n\n export(metrics: ResourceMetrics, resultCallback: (result: ExportResult) => void): void {\n this.doExport(metrics, resultCallback)\n }\n\n async shutdown(): Promise<void> {\n const pending = this.pendingExports.splice(0, this.pendingExports.length)\n const shutdownError = new Error('Exporter shutdown before export completed')\n for (const { resultCallback } of pending) {\n resultCallback?.({ code: ExportResultCode.FAILED, error: shutdownError })\n }\n }\n\n async forceFlush(): Promise<void> {\n // No-op\n }\n}\n","/**\n * Log exporter for the III Engine.\n */\n\nimport { ExportResultCode, type ExportResult } from '@opentelemetry/core'\nimport type { LogRecordExporter, ReadableLogRecord } from '@opentelemetry/sdk-logs'\nimport { JsonLogsSerializer } from '@opentelemetry/otlp-transformer'\n\nimport type { SharedEngineConnection } from './connection'\nimport { PREFIX_LOGS } from './types'\n\n/**\n * Log exporter using the shared WebSocket connection.\n */\nexport class EngineLogExporter implements LogRecordExporter {\n private connection: SharedEngineConnection\n private pendingExports: Array<{\n logs: ReadableLogRecord[]\n callback: (result: ExportResult) => void\n }> = []\n\n constructor(connection: SharedEngineConnection) {\n this.connection = connection\n this.connection.onConnected(() => this.flushPending())\n }\n\n private flushPending(): void {\n const pending = this.pendingExports.splice(0, this.pendingExports.length)\n for (const { logs, callback } of pending) {\n this.doExport(logs, callback)\n }\n }\n\n private doExport(\n logs: ReadableLogRecord[],\n resultCallback: (result: ExportResult) => void,\n ): void {\n if (this.connection.getState() !== 'connected') {\n this.pendingExports.push({ logs, callback: resultCallback })\n return\n }\n\n try {\n const serialized = JsonLogsSerializer.serializeRequest(logs)\n if (!serialized) {\n resultCallback({ code: ExportResultCode.SUCCESS })\n return\n }\n\n this.connection.send(PREFIX_LOGS, serialized, err => {\n if (err) {\n console.error('[OTel] Failed to send logs:', err.message)\n resultCallback({ code: ExportResultCode.FAILED, error: err })\n } else {\n resultCallback({ code: ExportResultCode.SUCCESS })\n }\n })\n } catch (err) {\n console.error('[OTel] Error exporting logs:', err)\n resultCallback({ code: ExportResultCode.FAILED, error: err as Error })\n }\n }\n\n export(logs: ReadableLogRecord[], resultCallback: (result: ExportResult) => void): void {\n this.doExport(logs, resultCallback)\n }\n\n async shutdown(): Promise<void> {\n for (const { callback } of this.pendingExports) {\n callback({ code: ExportResultCode.FAILED, error: new Error('Exporter shutdown') })\n }\n this.pendingExports = []\n }\n}\n","/**\n * Trace context and baggage propagation utilities.\n */\n\nimport { trace, context, propagation, type Context } from '@opentelemetry/api'\n\n/**\n * Extract the current trace ID from the active span context.\n */\nexport function currentTraceId(): string | undefined {\n const span = trace.getActiveSpan()\n if (span) {\n const spanContext = span.spanContext()\n if (spanContext.traceId && spanContext.traceId !== '00000000000000000000000000000000') {\n return spanContext.traceId\n }\n }\n return undefined\n}\n\n/**\n * Extract the current span ID from the active span context.\n */\nexport function currentSpanId(): string | undefined {\n const span = trace.getActiveSpan()\n if (span) {\n const spanContext = span.spanContext()\n if (spanContext.spanId && spanContext.spanId !== '0000000000000000') {\n return spanContext.spanId\n }\n }\n return undefined\n}\n\n/**\n * Inject the current trace context into a W3C traceparent header string.\n */\nexport function injectTraceparent(): string | undefined {\n const carrier: Record<string, string> = {}\n propagation.inject(context.active(), carrier)\n return carrier.traceparent\n}\n\n/**\n * Extract a trace context from a W3C traceparent header string.\n */\nexport function extractTraceparent(traceparent: string): Context {\n const carrier: Record<string, string> = { traceparent }\n return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Inject the current baggage into a W3C baggage header string.\n */\nexport function injectBaggage(): string | undefined {\n const carrier: Record<string, string> = {}\n propagation.inject(context.active(), carrier)\n return carrier.baggage\n}\n\n/**\n * Extract baggage from a W3C baggage header string.\n */\nexport function extractBaggage(baggage: string): Context {\n const carrier: Record<string, string> = { baggage }\n return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Extract both trace context and baggage from their respective headers.\n */\nexport function extractContext(traceparent?: string, baggage?: string): Context {\n const carrier: Record<string, string> = {}\n if (traceparent) {\n carrier.traceparent = traceparent\n }\n if (baggage) {\n carrier.baggage = baggage\n }\n return propagation.extract(context.active(), carrier)\n}\n\n/**\n * Get a baggage entry from the current context.\n */\nexport function getBaggageEntry(key: string): string | undefined {\n const bag = propagation.getBaggage(context.active())\n return bag?.getEntry(key)?.value\n}\n\n/**\n * Set a baggage entry in the current context.\n */\nexport function setBaggageEntry(key: string, value: string): Context {\n let bag = propagation.getBaggage(context.active()) ?? propagation.createBaggage()\n bag = bag.setEntry(key, { value })\n return propagation.setBaggage(context.active(), bag)\n}\n\n/**\n * Remove a baggage entry from the current context.\n */\nexport function removeBaggageEntry(key: string): Context {\n const bag = propagation.getBaggage(context.active())\n if (!bag) {\n return context.active()\n }\n const newBag = bag.removeEntry(key)\n return propagation.setBaggage(context.active(), newBag)\n}\n\n/**\n * Get all baggage entries from the current context.\n */\nexport function getAllBaggage(): Record<string, string> {\n const bag = propagation.getBaggage(context.active())\n if (!bag) {\n return {}\n }\n const entries: Record<string, string> = {}\n for (const [key, entry] of bag.getAllEntries()) {\n entries[key] = entry.value\n }\n return entries\n}\n","/**\n * OpenTelemetry initialization for the III Node SDK.\n *\n * This module provides trace, metrics, and log export to the III Engine\n * via a shared WebSocket connection using OTLP JSON format.\n */\n\nimport { Resource } from '@opentelemetry/resources'\nimport { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'\nimport { randomUUID } from 'node:crypto'\nimport {\n trace,\n context,\n propagation,\n SpanKind,\n SpanStatusCode,\n metrics,\n type Span,\n type Context,\n type Tracer,\n type Meter,\n} from '@opentelemetry/api'\nimport { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base'\nimport { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'\nimport {\n CompositePropagator,\n W3CBaggagePropagator,\n W3CTraceContextPropagator,\n} from '@opentelemetry/core'\nimport { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'\nimport { registerInstrumentations } from '@opentelemetry/instrumentation'\nimport { LoggerProvider, SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs'\nimport { type Logger, SeverityNumber } from '@opentelemetry/api-logs'\n\nimport {\n type OtelConfig,\n DEFAULT_OTEL_CONFIG,\n parseBoolEnv,\n ATTR_SERVICE_VERSION,\n ATTR_SERVICE_NAMESPACE,\n ATTR_SERVICE_INSTANCE_ID,\n} from './types'\nimport { SharedEngineConnection } from './connection'\nimport { EngineSpanExporter, EngineMetricsExporter, EngineLogExporter } from './exporters'\nimport { extractTraceparent } from './context'\n\n// Re-export everything from submodules\nexport * from './types'\nexport * from './context'\n\n// Module-level state\nlet sharedConnection: SharedEngineConnection | null = null\nlet tracerProvider: NodeTracerProvider | null = null\nlet meterProvider: MeterProvider | null = null\nlet loggerProvider: LoggerProvider | null = null\nlet tracer: Tracer | null = null\nlet meter: Meter | null = null\nlet logger: Logger | null = null\nlet serviceName: string = 'iii-node-iii'\n\n/**\n * Initialize OpenTelemetry with the given configuration.\n * This should be called once at application startup.\n */\nexport function initOtel(config: OtelConfig = {}): void {\n const enabled =\n config.enabled ?? parseBoolEnv(process.env.OTEL_ENABLED, DEFAULT_OTEL_CONFIG.enabled)\n\n if (!enabled) {\n console.debug(\n '[OTel] OpenTelemetry is disabled. To enable, remove OTEL_ENABLED=false or set enabled: true in config.',\n )\n return\n }\n\n // Register any provided instrumentations\n if (config.instrumentations?.length) {\n registerInstrumentations({ instrumentations: config.instrumentations })\n }\n\n // Configure service identity\n serviceName =\n config.serviceName ?? process.env.OTEL_SERVICE_NAME ?? DEFAULT_OTEL_CONFIG.serviceName\n const serviceVersion =\n config.serviceVersion ?? process.env.SERVICE_VERSION ?? DEFAULT_OTEL_CONFIG.serviceVersion\n const serviceNamespace = config.serviceNamespace ?? process.env.SERVICE_NAMESPACE\n const serviceInstanceId =\n config.serviceInstanceId ?? process.env.SERVICE_INSTANCE_ID ?? randomUUID()\n const engineWsUrl =\n config.engineWsUrl ?? process.env.III_BRIDGE_URL ?? DEFAULT_OTEL_CONFIG.engineWsUrl\n\n // Build resource attributes\n const resourceAttributes: Record<string, string> = {\n [ATTR_SERVICE_NAME]: serviceName,\n [ATTR_SERVICE_VERSION]: serviceVersion,\n [ATTR_SERVICE_INSTANCE_ID]: serviceInstanceId,\n }\n if (serviceNamespace) {\n resourceAttributes[ATTR_SERVICE_NAMESPACE] = serviceNamespace\n }\n const resource = new Resource(resourceAttributes)\n\n // Create shared WebSocket connection\n sharedConnection = new SharedEngineConnection(engineWsUrl, config.reconnectionConfig)\n\n // Initialize tracer\n const spanExporter = new EngineSpanExporter(sharedConnection)\n tracerProvider = new NodeTracerProvider({\n resource,\n spanProcessors: [new SimpleSpanProcessor(spanExporter)],\n })\n\n // Register W3C Trace Context and Baggage propagators\n propagation.setGlobalPropagator(\n new CompositePropagator({\n propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()],\n }),\n )\n\n tracerProvider.register()\n tracer = trace.getTracer(serviceName)\n\n console.debug(`[OTel] Traces initialized: engine=${engineWsUrl}, service=${serviceName}`)\n\n // Initialize metrics (enabled by default, opt-out via config or env)\n const metricsEnabled =\n config.metricsEnabled ??\n parseBoolEnv(process.env.OTEL_METRICS_ENABLED, DEFAULT_OTEL_CONFIG.metricsEnabled)\n\n if (metricsEnabled) {\n const metricsExporter = new EngineMetricsExporter(sharedConnection)\n const exportIntervalMs =\n config.metricsExportIntervalMs ?? DEFAULT_OTEL_CONFIG.metricsExportIntervalMs\n\n const metricReader = new PeriodicExportingMetricReader({\n exporter: metricsExporter,\n exportIntervalMillis: exportIntervalMs,\n })\n\n meterProvider = new MeterProvider({\n resource,\n readers: [metricReader],\n })\n\n metrics.setGlobalMeterProvider(meterProvider)\n meter = meterProvider.getMeter(serviceName)\n\n console.debug(`[OTel] Metrics initialized: interval=${exportIntervalMs}ms`)\n }\n\n // Initialize logs (always enabled when OTEL is enabled)\n const logExporter = new EngineLogExporter(sharedConnection)\n loggerProvider = new LoggerProvider({ resource })\n loggerProvider.addLogRecordProcessor(new SimpleLogRecordProcessor(logExporter))\n logger = loggerProvider.getLogger(serviceName)\n\n console.debug('[OTel] Logs initialized')\n}\n\n/**\n * Shutdown OpenTelemetry, flushing any pending data.\n */\nexport async function shutdownOtel(): Promise<void> {\n if (tracerProvider) {\n await tracerProvider.shutdown()\n tracerProvider = null\n }\n\n if (meterProvider) {\n await meterProvider.shutdown()\n meterProvider = null\n }\n\n if (loggerProvider) {\n await loggerProvider.shutdown()\n loggerProvider = null\n }\n\n if (sharedConnection) {\n await sharedConnection.shutdown()\n sharedConnection = null\n }\n\n tracer = null\n meter = null\n logger = null\n}\n\n/**\n * Get the OpenTelemetry tracer instance.\n */\nexport function getTracer(): Tracer | null {\n return tracer\n}\n\n/**\n * Get the OpenTelemetry meter instance.\n */\nexport function getMeter(): Meter | null {\n return meter\n}\n\n/**\n * Get the OpenTelemetry logger instance.\n */\nexport function getLogger(): Logger | null {\n return logger\n}\n\n/**\n * Start a new span with the given name and run the callback within it.\n */\nexport async function withSpan<T>(\n name: string,\n options: { kind?: SpanKind; traceparent?: string },\n fn: (span: Span) => Promise<T>,\n): Promise<T> {\n if (!tracer) {\n // Execute without span context when tracer is not initialized\n // Provide a no-op span to avoid runtime errors if fn calls span methods\n const noopSpan: Span = {\n spanContext: () => ({ traceId: '', spanId: '', traceFlags: 0 }),\n setAttribute: () => noopSpan,\n setAttributes: () => noopSpan,\n addEvent: () => noopSpan,\n addLink: () => noopSpan,\n setStatus: () => noopSpan,\n updateName: () => noopSpan,\n end: () => {},\n isRecording: () => false,\n recordException: () => {},\n addLinks: () => noopSpan,\n }\n return fn(noopSpan)\n }\n\n const parentContext = options.traceparent\n ? extractTraceparent(options.traceparent)\n : context.active()\n\n return tracer.startActiveSpan(\n name,\n { kind: options.kind ?? SpanKind.INTERNAL },\n parentContext,\n async span => {\n try {\n const result = await fn(span)\n span.setStatus({ code: SpanStatusCode.OK })\n return result\n } catch (error) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: (error as Error).message })\n span.recordException(error as Error)\n throw error\n } finally {\n span.end()\n }\n },\n )\n}\n\n// Re-export OTEL types for convenience\nexport {\n SpanKind,\n SpanStatusCode,\n SeverityNumber,\n type Span,\n type Context,\n type Tracer,\n type Meter,\n type Logger,\n}\n","/**\n * Safely stringify a value, handling circular references, BigInt, and other edge cases.\n * Returns \"[unserializable]\" if serialization fails for any reason.\n */\nexport function safeStringify(value: unknown): string {\n const seen = new WeakSet<object>()\n\n try {\n return JSON.stringify(value, (_key, val) => {\n // Handle BigInt\n if (typeof val === 'bigint') {\n return val.toString()\n }\n\n // Handle circular references\n if (val !== null && typeof val === 'object') {\n if (seen.has(val)) {\n return '[Circular]'\n }\n seen.add(val)\n }\n\n return val\n })\n } catch {\n return '[unserializable]'\n }\n}\n","/**\n * Worker metrics collection for the III Node SDK.\n *\n * Collects CPU, memory, and event loop metrics for worker health monitoring.\n * Uses the Node.js built-in `monitorEventLoopDelay` API for accurate\n * event loop lag measurements.\n */\n\nimport { type IntervalHistogram, monitorEventLoopDelay, performance } from 'node:perf_hooks'\n\n/**\n * Worker metrics data structure used internally for OTEL metric collection.\n */\nexport type WorkerMetrics = {\n memory_heap_used?: number\n memory_heap_total?: number\n memory_rss?: number\n memory_external?: number\n cpu_user_micros?: number\n cpu_system_micros?: number\n cpu_percent?: number\n event_loop_lag_ms?: number\n uptime_seconds?: number\n timestamp_ms: number\n runtime: string\n}\n\n/**\n * Configuration options for the WorkerMetricsCollector.\n */\nexport interface WorkerMetricsCollectorOptions {\n /**\n * Event loop delay histogram resolution in milliseconds.\n * Lower values provide more accurate measurements but use more resources.\n * @default 20\n */\n eventLoopResolutionMs?: number\n}\n\n/**\n * Collects worker resource metrics including CPU, memory, and event loop lag.\n *\n * Uses the Node.js `monitorEventLoopDelay` API for high-precision event loop\n * delay measurements instead of manual `setImmediate` timing.\n *\n * @example\n * ```typescript\n * const collector = new WorkerMetricsCollector()\n *\n * // Collect metrics periodically\n * setInterval(() => {\n * const metrics = collector.collect()\n * console.log('CPU:', metrics.cpu_percent, '%')\n * console.log('Event Loop Lag:', metrics.event_loop_lag_ms, 'ms')\n * }, 5000)\n *\n * // Clean up when done\n * collector.stopMonitoring()\n * ```\n */\nexport class WorkerMetricsCollector {\n private readonly startTime: number\n private lastCpuUsage: NodeJS.CpuUsage\n private lastCpuTime: number\n private eventLoopHistogram: IntervalHistogram | null = null\n\n /**\n * Creates a new WorkerMetricsCollector instance.\n *\n * @param options - Configuration options\n */\n constructor(options: WorkerMetricsCollectorOptions = {}) {\n this.startTime = Date.now()\n this.lastCpuUsage = process.cpuUsage()\n this.lastCpuTime = performance.now()\n this.startEventLoopMonitoring(options.eventLoopResolutionMs ?? 20)\n }\n\n /**\n * Starts the event loop delay histogram monitoring.\n *\n * @param resolutionMs - Histogram resolution in milliseconds\n */\n private startEventLoopMonitoring(resolutionMs: number): void {\n // Sanitize resolution: must be a positive finite number, minimum 1ms\n const safeResolutionMs =\n Number.isFinite(resolutionMs) && resolutionMs > 0 ? Math.max(1, Math.floor(resolutionMs)) : 20 // Default fallback\n\n this.eventLoopHistogram = monitorEventLoopDelay({ resolution: safeResolutionMs })\n this.eventLoopHistogram.enable()\n }\n\n /**\n * Stops the event loop monitoring and releases resources.\n * Should be called when the collector is no longer needed.\n */\n public stopMonitoring(): void {\n if (this.eventLoopHistogram) {\n this.eventLoopHistogram.disable()\n this.eventLoopHistogram = null\n }\n }\n\n /**\n * Collects current worker metrics.\n *\n * This method calculates CPU usage since the last collection,\n * reads memory usage, and gets event loop delay statistics.\n * The event loop histogram is reset after each collection for\n * accurate per-interval measurements.\n *\n * @returns Current worker metrics snapshot\n */\n collect(): WorkerMetrics {\n const memoryUsage = process.memoryUsage()\n const cpuUsage = process.cpuUsage()\n const now = performance.now()\n\n // Calculate CPU percentage since last collection\n const cpuDelta = {\n user: cpuUsage.user - this.lastCpuUsage.user,\n system: cpuUsage.system - this.lastCpuUsage.system,\n }\n const timeDelta = (now - this.lastCpuTime) * 1000 // Convert ms to microseconds\n const cpuPercent = timeDelta > 0 ? ((cpuDelta.user + cpuDelta.system) / timeDelta) * 100 : 0\n\n // Update state for next collection\n this.lastCpuUsage = cpuUsage\n this.lastCpuTime = now\n\n // Get event loop lag from histogram (in nanoseconds, convert to ms)\n let eventLoopLagMs = 0\n if (this.eventLoopHistogram) {\n // Mean is in nanoseconds, convert to milliseconds\n eventLoopLagMs = this.eventLoopHistogram.mean / 1_000_000\n // Reset histogram for next collection interval\n this.eventLoopHistogram.reset()\n }\n\n return {\n memory_heap_used: memoryUsage.heapUsed,\n memory_heap_total: memoryUsage.heapTotal,\n memory_rss: memoryUsage.rss,\n memory_external: memoryUsage.external,\n cpu_user_micros: cpuUsage.user,\n cpu_system_micros: cpuUsage.system,\n cpu_percent: Math.min(cpuPercent, 100), // Cap at 100%\n event_loop_lag_ms: eventLoopLagMs,\n uptime_seconds: Math.floor((Date.now() - this.startTime) / 1000),\n timestamp_ms: Date.now(),\n runtime: 'node',\n }\n }\n}\n","import type { Meter, BatchObservableResult, Observable } from '@opentelemetry/api'\nimport { WorkerMetricsCollector } from './worker-metrics'\n\nexport interface WorkerGaugesOptions {\n workerId: string\n workerName?: string\n}\n\nlet registeredGauges = false\nlet metricsCollector: WorkerMetricsCollector | null = null\nlet registeredMeter: Meter | null = null\nlet registeredBatchCallback: ((observableResult: BatchObservableResult) => void) | null = null\nlet registeredObservables: Observable[] = []\n\nexport function registerWorkerGauges(meter: Meter, options: WorkerGaugesOptions): void {\n if (registeredGauges) {\n return\n }\n\n const { workerId, workerName } = options\n const baseAttributes = {\n 'worker.id': workerId,\n ...(workerName && { 'worker.name': workerName }),\n }\n\n metricsCollector = new WorkerMetricsCollector()\n\n const memoryHeapUsed = meter.createObservableGauge('iii.worker.memory.heap_used', {\n description: 'Worker heap memory used in bytes',\n unit: 'bytes',\n })\n\n const memoryHeapTotal = meter.createObservableGauge('iii.worker.memory.heap_total', {\n description: 'Worker total heap memory in bytes',\n unit: 'bytes',\n })\n\n const memoryRss = meter.createObservableGauge('iii.worker.memory.rss', {\n description: 'Worker resident set size in bytes',\n unit: 'bytes',\n })\n\n const memoryExternal = meter.createObservableGauge('iii.worker.memory.external', {\n description: 'Worker external memory in bytes',\n unit: 'bytes',\n })\n\n const cpuPercent = meter.createObservableGauge('iii.worker.cpu.percent', {\n description: 'Worker CPU usage percentage',\n unit: '%',\n })\n\n const cpuUserMicros = meter.createObservableGauge('iii.worker.cpu.user_micros', {\n description: 'Worker CPU user time in microseconds',\n unit: 'us',\n })\n\n const cpuSystemMicros = meter.createObservableGauge('iii.worker.cpu.system_micros', {\n description: 'Worker CPU system time in microseconds',\n unit: 'us',\n })\n\n const eventLoopLag = meter.createObservableGauge('iii.worker.event_loop.lag_ms', {\n description: 'Worker event loop lag in milliseconds',\n unit: 'ms',\n })\n\n const uptimeSeconds = meter.createObservableGauge('iii.worker.uptime_seconds', {\n description: 'Worker uptime in seconds',\n unit: 's',\n })\n\n const batchCallback = (observableResult: BatchObservableResult) => {\n if (!metricsCollector) return\n\n const metrics = metricsCollector.collect()\n\n if (metrics.memory_heap_used !== undefined) {\n observableResult.observe(memoryHeapUsed, metrics.memory_heap_used, baseAttributes)\n }\n if (metrics.memory_heap_total !== undefined) {\n observableResult.observe(memoryHeapTotal, metrics.memory_heap_total, baseAttributes)\n }\n if (metrics.memory_rss !== undefined) {\n observableResult.observe(memoryRss, metrics.memory_rss, baseAttributes)\n }\n if (metrics.memory_external !== undefined) {\n observableResult.observe(memoryExternal, metrics.memory_external, baseAttributes)\n }\n if (metrics.cpu_percent !== undefined) {\n observableResult.observe(cpuPercent, metrics.cpu_percent, baseAttributes)\n }\n if (metrics.cpu_user_micros !== undefined) {\n observableResult.observe(cpuUserMicros, metrics.cpu_user_micros, baseAttributes)\n }\n if (metrics.cpu_system_micros !== undefined) {\n observableResult.observe(cpuSystemMicros, metrics.cpu_system_micros, baseAttributes)\n }\n if (metrics.event_loop_lag_ms !== undefined) {\n observableResult.observe(eventLoopLag, metrics.event_loop_lag_ms, baseAttributes)\n }\n if (metrics.uptime_seconds !== undefined) {\n observableResult.observe(uptimeSeconds, metrics.uptime_seconds, baseAttributes)\n }\n }\n\n meter.addBatchObservableCallback(batchCallback, [\n memoryHeapUsed,\n memoryHeapTotal,\n memoryRss,\n memoryExternal,\n cpuPercent,\n cpuUserMicros,\n cpuSystemMicros,\n eventLoopLag,\n uptimeSeconds,\n ])\n\n registeredMeter = meter\n registeredBatchCallback = batchCallback\n registeredObservables = [\n memoryHeapUsed,\n memoryHeapTotal,\n memoryRss,\n memoryExternal,\n cpuPercent,\n cpuUserMicros,\n cpuSystemMicros,\n eventLoopLag,\n uptimeSeconds,\n ]\n\n registeredGauges = true\n}\n\nexport function stopWorkerGauges(): void {\n // Remove the batch observable callback before stopping\n if (registeredMeter && registeredBatchCallback) {\n registeredMeter.removeBatchObservableCallback(registeredBatchCallback, registeredObservables)\n }\n\n if (metricsCollector) {\n metricsCollector.stopMonitoring()\n metricsCollector = null\n }\n\n registeredMeter = null\n registeredBatchCallback = null\n registeredObservables = []\n registeredGauges = false\n}\n"],"mappings":"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"}
|