@iii-dev/helpers 0.21.6 → 0.21.7-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["/**\n * HTTP method accepted by {@link HttpInvocationConfig}. Distinct from the core\n * `builtin_triggers` HTTP method enum, which also covers HEAD/OPTIONS.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: HttpMethod\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\n/**\n * Incoming buffered HTTP request received by a function handler.\n *\n * @typeParam TBody - Type of the parsed request body.\n */\nexport type HttpRequest<TBody = unknown> = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: TBody\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/**\n * Structured buffered HTTP response returned from function handlers.\n *\n * @typeParam TStatus - HTTP status code literal type.\n * @typeParam TBody - Type of the response body.\n *\n * @example\n * ```typescript\n * const response: HttpResponse = {\n * status_code: 200,\n * headers: { 'content-type': 'application/json' },\n * body: { message: 'ok' },\n * }\n * ```\n */\nexport type HttpResponse<\n TStatus extends number = number,\n TBody = string | Buffer | Record<string, unknown>,\n> = {\n /** HTTP status code. */\n status_code: TStatus\n /** Response headers. */\n headers?: Record<string, string>\n /** Response body. */\n body?: TBody\n}\n\n/**\n * Structural shape of the reader end of a stream channel. Declared locally so\n * the helpers package does not runtime-depend on the core SDK.\n */\ntype HttpStreamReader = {\n stream: NodeJS.ReadableStream\n readAll: () => Promise<Buffer>\n onMessage: (callback: (msg: string) => void) => void\n close: () => void\n}\n\n/** Structural shape of the writer end of a stream channel. */\ntype HttpStreamWriter = {\n sendMessage: (message: string) => unknown\n stream: NodeJS.WritableStream\n close: () => unknown\n}\n\n/** Structural shape of a streaming request passed to the {@link http} handler. */\ntype HttpStreamingRequest = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: unknown\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/** Structural shape of the streaming response passed to the {@link http} handler. */\ntype HttpStreamingResponse = {\n status: (statusCode: number) => void\n headers: (headers: Record<string, string>) => void\n stream: NodeJS.WritableStream\n close: () => void\n}\n\n/** Structural shape of the internal request delivered by the runtime. */\ntype HttpInternalRequest = HttpStreamingRequest & { response: HttpStreamWriter }\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving a streaming request and response.\n * @returns A function handler compatible with `IIIClient.registerFunction`.\n *\n * @example\n * ```typescript\n * import { http } from '@iii-dev/helpers/http'\n *\n * worker.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpStreamingRequest, res: HttpStreamingResponse) => Promise<void | HttpResponse>,\n) => {\n return async (req: HttpInternalRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpStreamingResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAyIA,MAAa,QAEX,aACG;AACH,QAAO,OAAO,QAA6B;EACzC,MAAM,EAAE,UAAU,GAAG,YAAY;AAWjC,SAAO,SAAS,SAT4B;GAC1C,SAAS,gBACP,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAc;IAAa,CAAC,CAAC;GAC3E,UAAU,YACR,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAe;IAAS,CAAC,CAAC;GACxE,QAAQ,SAAS;GACjB,aAAa,SAAS,OAAO;GAC9B,CAEqC"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["/**\n * HTTP method accepted by {@link HttpInvocationConfig}. Distinct from the core\n * `builtin_triggers` HTTP method enum, which also covers HEAD/OPTIONS.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac`: HMAC signature verification using a shared secret.\n * - `bearer`: Bearer token authentication.\n * - `api_key`: API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for an HTTP-invoked function (Lambda, Cloudflare Workers, etc.).\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: HttpMethod\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\n/**\n * Incoming buffered HTTP request received by a function handler.\n *\n * @typeParam TBody - Type of the parsed request body.\n */\nexport type HttpRequest<TBody = unknown> = {\n /** Path parameters extracted from the matched route. */\n path_params: Record<string, string>\n /** Query-string parameters from the request URL. */\n query_params: Record<string, string | string[]>\n /** Parsed request body. */\n body: TBody\n /** Request headers. */\n headers: Record<string, string | string[]>\n /** HTTP method of the request (e.g. `GET`, `POST`). */\n method: string\n /** Streaming reader for the raw request body. */\n request_body: HttpStreamReader\n}\n\n/**\n * Structured buffered HTTP response returned from function handlers.\n *\n * @typeParam TStatus - HTTP status code literal type.\n * @typeParam TBody - Type of the response body.\n *\n * @example\n * ```typescript\n * const response: HttpResponse = {\n * status_code: 200,\n * headers: { 'content-type': 'application/json' },\n * body: { message: 'ok' },\n * }\n * ```\n */\nexport type HttpResponse<\n TStatus extends number = number,\n TBody = string | Buffer | Record<string, unknown>,\n> = {\n /** HTTP status code. */\n status_code: TStatus\n /** Response headers. */\n headers?: Record<string, string>\n /** Response body. */\n body?: TBody\n}\n\n/**\n * Structural shape of the reader end of a stream channel. Declared locally so\n * the helpers package does not runtime-depend on the core SDK.\n */\ntype HttpStreamReader = {\n stream: NodeJS.ReadableStream\n readAll: () => Promise<Buffer>\n onMessage: (callback: (msg: string) => void) => void\n close: () => void\n}\n\n/** Structural shape of the writer end of a stream channel. */\ntype HttpStreamWriter = {\n sendMessage: (message: string) => unknown\n stream: NodeJS.WritableStream\n close: () => unknown\n}\n\n/** Structural shape of a streaming request passed to the {@link http} handler. */\ntype HttpStreamingRequest = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: unknown\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/** Structural shape of the streaming response passed to the {@link http} handler. */\ntype HttpStreamingResponse = {\n status: (statusCode: number) => void\n headers: (headers: Record<string, string>) => void\n stream: NodeJS.WritableStream\n close: () => void\n}\n\n/** Structural shape of the internal request delivered by the runtime. */\ntype HttpInternalRequest = HttpStreamingRequest & { response: HttpStreamWriter }\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving a streaming request and response.\n * @returns A function handler compatible with `IIIClient.registerFunction`.\n *\n * @example\n * ```typescript\n * import { http } from '@iii-dev/helpers/http'\n *\n * worker.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpStreamingRequest, res: HttpStreamingResponse) => Promise<void | HttpResponse>,\n) => {\n return async (req: HttpInternalRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpStreamingResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8IA,MAAa,QAEX,aACG;AACH,QAAO,OAAO,QAA6B;EACzC,MAAM,EAAE,UAAU,GAAG,YAAY;AAWjC,SAAO,SAAS,SAT4B;GAC1C,SAAS,gBACP,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAc;IAAa,CAAC,CAAC;GAC3E,UAAU,YACR,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAe;IAAS,CAAC,CAAC;GACxE,QAAQ,SAAS;GACjB,aAAa,SAAS,OAAO;GAC9B,CAEqC"}
@@ -7,9 +7,9 @@ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
7
7
  /**
8
8
  * Authentication configuration for HTTP-invoked functions.
9
9
  *
10
- * - `hmac` -- HMAC signature verification using a shared secret.
11
- * - `bearer` -- Bearer token authentication.
12
- * - `api_key` -- API key sent via a custom header.
10
+ * - `hmac`: HMAC signature verification using a shared secret.
11
+ * - `bearer`: Bearer token authentication.
12
+ * - `api_key`: API key sent via a custom header.
13
13
  */
14
14
  type HttpAuthConfig = {
15
15
  type: 'hmac';
@@ -23,8 +23,7 @@ type HttpAuthConfig = {
23
23
  value_key: string;
24
24
  };
25
25
  /**
26
- * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare
27
- * Workers, etc.) instead of a local handler.
26
+ * Configuration for an HTTP-invoked function (Lambda, Cloudflare Workers, etc.).
28
27
  */
29
28
  type HttpInvocationConfig = {
30
29
  /** URL to invoke. */url: string; /** HTTP method. Defaults to `POST`. */
@@ -39,11 +38,11 @@ type HttpInvocationConfig = {
39
38
  * @typeParam TBody - Type of the parsed request body.
40
39
  */
41
40
  type HttpRequest<TBody = unknown> = {
42
- path_params: Record<string, string>;
43
- query_params: Record<string, string | string[]>;
44
- body: TBody;
45
- headers: Record<string, string | string[]>;
46
- method: string;
41
+ /** Path parameters extracted from the matched route. */path_params: Record<string, string>; /** Query-string parameters from the request URL. */
42
+ query_params: Record<string, string | string[]>; /** Parsed request body. */
43
+ body: TBody; /** Request headers. */
44
+ headers: Record<string, string | string[]>; /** HTTP method of the request (e.g. `GET`, `POST`). */
45
+ method: string; /** Streaming reader for the raw request body. */
47
46
  request_body: HttpStreamReader;
48
47
  };
49
48
  /**
@@ -7,9 +7,9 @@ type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
7
7
  /**
8
8
  * Authentication configuration for HTTP-invoked functions.
9
9
  *
10
- * - `hmac` -- HMAC signature verification using a shared secret.
11
- * - `bearer` -- Bearer token authentication.
12
- * - `api_key` -- API key sent via a custom header.
10
+ * - `hmac`: HMAC signature verification using a shared secret.
11
+ * - `bearer`: Bearer token authentication.
12
+ * - `api_key`: API key sent via a custom header.
13
13
  */
14
14
  type HttpAuthConfig = {
15
15
  type: 'hmac';
@@ -23,8 +23,7 @@ type HttpAuthConfig = {
23
23
  value_key: string;
24
24
  };
25
25
  /**
26
- * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare
27
- * Workers, etc.) instead of a local handler.
26
+ * Configuration for an HTTP-invoked function (Lambda, Cloudflare Workers, etc.).
28
27
  */
29
28
  type HttpInvocationConfig = {
30
29
  /** URL to invoke. */url: string; /** HTTP method. Defaults to `POST`. */
@@ -39,11 +38,11 @@ type HttpInvocationConfig = {
39
38
  * @typeParam TBody - Type of the parsed request body.
40
39
  */
41
40
  type HttpRequest<TBody = unknown> = {
42
- path_params: Record<string, string>;
43
- query_params: Record<string, string | string[]>;
44
- body: TBody;
45
- headers: Record<string, string | string[]>;
46
- method: string;
41
+ /** Path parameters extracted from the matched route. */path_params: Record<string, string>; /** Query-string parameters from the request URL. */
42
+ query_params: Record<string, string | string[]>; /** Parsed request body. */
43
+ body: TBody; /** Request headers. */
44
+ headers: Record<string, string | string[]>; /** HTTP method of the request (e.g. `GET`, `POST`). */
45
+ method: string; /** Streaming reader for the raw request body. */
47
46
  request_body: HttpStreamReader;
48
47
  };
49
48
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["/**\n * HTTP method accepted by {@link HttpInvocationConfig}. Distinct from the core\n * `builtin_triggers` HTTP method enum, which also covers HEAD/OPTIONS.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac` -- HMAC signature verification using a shared secret.\n * - `bearer` -- Bearer token authentication.\n * - `api_key` -- API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for registering an HTTP-invoked function (Lambda, Cloudflare\n * Workers, etc.) instead of a local handler.\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: HttpMethod\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\n/**\n * Incoming buffered HTTP request received by a function handler.\n *\n * @typeParam TBody - Type of the parsed request body.\n */\nexport type HttpRequest<TBody = unknown> = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: TBody\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/**\n * Structured buffered HTTP response returned from function handlers.\n *\n * @typeParam TStatus - HTTP status code literal type.\n * @typeParam TBody - Type of the response body.\n *\n * @example\n * ```typescript\n * const response: HttpResponse = {\n * status_code: 200,\n * headers: { 'content-type': 'application/json' },\n * body: { message: 'ok' },\n * }\n * ```\n */\nexport type HttpResponse<\n TStatus extends number = number,\n TBody = string | Buffer | Record<string, unknown>,\n> = {\n /** HTTP status code. */\n status_code: TStatus\n /** Response headers. */\n headers?: Record<string, string>\n /** Response body. */\n body?: TBody\n}\n\n/**\n * Structural shape of the reader end of a stream channel. Declared locally so\n * the helpers package does not runtime-depend on the core SDK.\n */\ntype HttpStreamReader = {\n stream: NodeJS.ReadableStream\n readAll: () => Promise<Buffer>\n onMessage: (callback: (msg: string) => void) => void\n close: () => void\n}\n\n/** Structural shape of the writer end of a stream channel. */\ntype HttpStreamWriter = {\n sendMessage: (message: string) => unknown\n stream: NodeJS.WritableStream\n close: () => unknown\n}\n\n/** Structural shape of a streaming request passed to the {@link http} handler. */\ntype HttpStreamingRequest = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: unknown\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/** Structural shape of the streaming response passed to the {@link http} handler. */\ntype HttpStreamingResponse = {\n status: (statusCode: number) => void\n headers: (headers: Record<string, string>) => void\n stream: NodeJS.WritableStream\n close: () => void\n}\n\n/** Structural shape of the internal request delivered by the runtime. */\ntype HttpInternalRequest = HttpStreamingRequest & { response: HttpStreamWriter }\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving a streaming request and response.\n * @returns A function handler compatible with `IIIClient.registerFunction`.\n *\n * @example\n * ```typescript\n * import { http } from '@iii-dev/helpers/http'\n *\n * worker.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpStreamingRequest, res: HttpStreamingResponse) => Promise<void | HttpResponse>,\n) => {\n return async (req: HttpInternalRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpStreamingResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyIA,MAAa,QAEX,aACG;AACH,QAAO,OAAO,QAA6B;EACzC,MAAM,EAAE,UAAU,GAAG,YAAY;AAWjC,SAAO,SAAS,SAT4B;GAC1C,SAAS,gBACP,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAc;IAAa,CAAC,CAAC;GAC3E,UAAU,YACR,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAe;IAAS,CAAC,CAAC;GACxE,QAAQ,SAAS;GACjB,aAAa,SAAS,OAAO;GAC9B,CAEqC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["/**\n * HTTP method accepted by {@link HttpInvocationConfig}. Distinct from the core\n * `builtin_triggers` HTTP method enum, which also covers HEAD/OPTIONS.\n */\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'\n\n/**\n * Authentication configuration for HTTP-invoked functions.\n *\n * - `hmac`: HMAC signature verification using a shared secret.\n * - `bearer`: Bearer token authentication.\n * - `api_key`: API key sent via a custom header.\n */\nexport type HttpAuthConfig =\n | { type: 'hmac'; secret_key: string }\n | { type: 'bearer'; token_key: string }\n | { type: 'api_key'; header: string; value_key: string }\n\n/**\n * Configuration for an HTTP-invoked function (Lambda, Cloudflare Workers, etc.).\n */\nexport type HttpInvocationConfig = {\n /** URL to invoke. */\n url: string\n /** HTTP method. Defaults to `POST`. */\n method?: HttpMethod\n /** Timeout in milliseconds. */\n timeout_ms?: number\n /** Custom headers to send with the request. */\n headers?: Record<string, string>\n /** Authentication configuration. */\n auth?: HttpAuthConfig\n}\n\n/**\n * Incoming buffered HTTP request received by a function handler.\n *\n * @typeParam TBody - Type of the parsed request body.\n */\nexport type HttpRequest<TBody = unknown> = {\n /** Path parameters extracted from the matched route. */\n path_params: Record<string, string>\n /** Query-string parameters from the request URL. */\n query_params: Record<string, string | string[]>\n /** Parsed request body. */\n body: TBody\n /** Request headers. */\n headers: Record<string, string | string[]>\n /** HTTP method of the request (e.g. `GET`, `POST`). */\n method: string\n /** Streaming reader for the raw request body. */\n request_body: HttpStreamReader\n}\n\n/**\n * Structured buffered HTTP response returned from function handlers.\n *\n * @typeParam TStatus - HTTP status code literal type.\n * @typeParam TBody - Type of the response body.\n *\n * @example\n * ```typescript\n * const response: HttpResponse = {\n * status_code: 200,\n * headers: { 'content-type': 'application/json' },\n * body: { message: 'ok' },\n * }\n * ```\n */\nexport type HttpResponse<\n TStatus extends number = number,\n TBody = string | Buffer | Record<string, unknown>,\n> = {\n /** HTTP status code. */\n status_code: TStatus\n /** Response headers. */\n headers?: Record<string, string>\n /** Response body. */\n body?: TBody\n}\n\n/**\n * Structural shape of the reader end of a stream channel. Declared locally so\n * the helpers package does not runtime-depend on the core SDK.\n */\ntype HttpStreamReader = {\n stream: NodeJS.ReadableStream\n readAll: () => Promise<Buffer>\n onMessage: (callback: (msg: string) => void) => void\n close: () => void\n}\n\n/** Structural shape of the writer end of a stream channel. */\ntype HttpStreamWriter = {\n sendMessage: (message: string) => unknown\n stream: NodeJS.WritableStream\n close: () => unknown\n}\n\n/** Structural shape of a streaming request passed to the {@link http} handler. */\ntype HttpStreamingRequest = {\n path_params: Record<string, string>\n query_params: Record<string, string | string[]>\n body: unknown\n headers: Record<string, string | string[]>\n method: string\n request_body: HttpStreamReader\n}\n\n/** Structural shape of the streaming response passed to the {@link http} handler. */\ntype HttpStreamingResponse = {\n status: (statusCode: number) => void\n headers: (headers: Record<string, string>) => void\n stream: NodeJS.WritableStream\n close: () => void\n}\n\n/** Structural shape of the internal request delivered by the runtime. */\ntype HttpInternalRequest = HttpStreamingRequest & { response: HttpStreamWriter }\n\n/**\n * Helper that wraps an HTTP-style handler (with separate `req`/`res` arguments)\n * into the function handler format expected by the SDK.\n *\n * @param callback - Async handler receiving a streaming request and response.\n * @returns A function handler compatible with `IIIClient.registerFunction`.\n *\n * @example\n * ```typescript\n * import { http } from '@iii-dev/helpers/http'\n *\n * worker.registerFunction(\n * 'my-api',\n * http(async (req, res) => {\n * res.status(200)\n * res.headers({ 'content-type': 'application/json' })\n * res.stream.end(JSON.stringify({ hello: 'world' }))\n * res.close()\n * }),\n * )\n * ```\n */\nexport const http = (\n // biome-ignore lint/suspicious/noConfusingVoidType: void is necessary here\n callback: (req: HttpStreamingRequest, res: HttpStreamingResponse) => Promise<void | HttpResponse>,\n) => {\n return async (req: HttpInternalRequest) => {\n const { response, ...request } = req\n\n const httpResponse: HttpStreamingResponse = {\n status: (status_code: number) =>\n response.sendMessage(JSON.stringify({ type: 'set_status', status_code })),\n headers: (headers: Record<string, string>) =>\n response.sendMessage(JSON.stringify({ type: 'set_headers', headers })),\n stream: response.stream,\n close: () => response.close(),\n }\n\n return callback(request, httpResponse)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8IA,MAAa,QAEX,aACG;AACH,QAAO,OAAO,QAA6B;EACzC,MAAM,EAAE,UAAU,GAAG,YAAY;AAWjC,SAAO,SAAS,SAT4B;GAC1C,SAAS,gBACP,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAc;IAAa,CAAC,CAAC;GAC3E,UAAU,YACR,SAAS,YAAY,KAAK,UAAU;IAAE,MAAM;IAAe;IAAS,CAAC,CAAC;GACxE,QAAQ,SAAS;GACjB,aAAa,SAAS,OAAO;GAC9B,CAEqC"}
@@ -69,6 +69,8 @@ declare function currentSpanId(): string | undefined;
69
69
  declare function injectTraceparent(): string | undefined;
70
70
  /**
71
71
  * Extract a trace context from a W3C traceparent header string.
72
+ *
73
+ * @param traceparent - W3C `traceparent` header value to parse.
72
74
  */
73
75
  declare function extractTraceparent(traceparent: string): Context;
74
76
  /**
@@ -77,22 +79,34 @@ declare function extractTraceparent(traceparent: string): Context;
77
79
  declare function injectBaggage(): string | undefined;
78
80
  /**
79
81
  * Extract baggage from a W3C baggage header string.
82
+ *
83
+ * @param baggage - W3C `baggage` header value to parse.
80
84
  */
81
85
  declare function extractBaggage(baggage: string): Context;
82
86
  /**
83
87
  * Extract both trace context and baggage from their respective headers.
88
+ *
89
+ * @param traceparent - W3C `traceparent` header value to parse.
90
+ * @param baggage - W3C `baggage` header value to parse.
84
91
  */
85
92
  declare function extractContext(traceparent?: string, baggage?: string): Context;
86
93
  /**
87
94
  * Get a baggage entry from the current context.
95
+ *
96
+ * @param key - Baggage entry key to read.
88
97
  */
89
98
  declare function getBaggageEntry(key: string): string | undefined;
90
99
  /**
91
100
  * Set a baggage entry in the current context.
101
+ *
102
+ * @param key - Baggage entry key to set.
103
+ * @param value - Baggage entry value to set.
92
104
  */
93
105
  declare function setBaggageEntry(key: string, value: string): Context;
94
106
  /**
95
107
  * Remove a baggage entry from the current context.
108
+ *
109
+ * @param key - Baggage entry key to remove.
96
110
  */
97
111
  declare function removeBaggageEntry(key: string): Context;
98
112
  /**
@@ -101,6 +115,10 @@ declare function removeBaggageEntry(key: string): Context;
101
115
  declare function getAllBaggage(): Record<string, string>;
102
116
  //#endregion
103
117
  //#region src/observability/telemetry-system/baggage-span-processor.d.ts
118
+ /**
119
+ * OpenTelemetry span processor that copies OTel baggage entries onto each
120
+ * started span as attributes.
121
+ */
104
122
  declare class BaggageSpanProcessor implements SpanProcessor {
105
123
  onStart(span: Span, parentContext: Context): void;
106
124
  onEnd(_span: ReadableSpan): void;
@@ -111,20 +129,47 @@ declare class BaggageSpanProcessor implements SpanProcessor {
111
129
  //#region src/observability/telemetry-system/span-ops.d.ts
112
130
  /** Returns `false` when there is no active span or the sampler dropped it. */
113
131
  declare function currentSpanIsRecording(): boolean;
114
- /** No-op when the current span is not recording. */
132
+ /**
133
+ * No-op when the current span is not recording.
134
+ *
135
+ * @param key - Attribute key to set on the active span.
136
+ * @param value - Attribute value to set.
137
+ */
115
138
  declare function setCurrentSpanAttribute(key: string, value: AttributeValue): void;
116
- /** No-op when there is no active span. */
139
+ /**
140
+ * No-op when there is no active span.
141
+ *
142
+ * @param message - Error message to set as the span's error status.
143
+ */
117
144
  declare function setCurrentSpanError(message: string): void;
118
- /** No-op when the current span is not recording. */
145
+ /**
146
+ * No-op when the current span is not recording.
147
+ *
148
+ * @param name - Name of the event to add to the active span.
149
+ * @param attrs - Optional attributes to attach to the event.
150
+ */
119
151
  declare function recordSpanEvent(name: string, attrs?: Attributes): void;
120
152
  //#endregion
121
153
  //#region src/observability/telemetry-system/payload.d.ts
122
154
  /** Payload redaction + truncation for invocation event capture. */
123
155
  declare const REDACTED_PLACEHOLDER = "[REDACTED]";
156
+ /**
157
+ * Resolve the payload byte cap from the environment, returning undefined when
158
+ * unset.
159
+ */
124
160
  declare function resolveMaxBytesFromEnv(): number | null;
125
- /** Recursively redact values of sensitive keys. Returns a new value. */
161
+ /**
162
+ * Recursively redact values of sensitive keys. Returns a new value.
163
+ *
164
+ * @param value - The value to recursively redact.
165
+ */
126
166
  declare function redact(value: unknown): unknown;
127
- /** Redact then serialize to JSON, optionally capped at `maxBytes`. */
167
+ /**
168
+ * Redact then serialize to JSON, optionally capped at `maxBytes`.
169
+ *
170
+ * @param value - The value to redact and serialize.
171
+ * @param maxBytes - Maximum serialized size in bytes; null leaves it uncapped.
172
+ */
128
173
  declare function redactAndTruncate(value: unknown, maxBytes?: number | null): {
129
174
  json: string;
130
175
  truncated: boolean;
@@ -134,10 +179,13 @@ declare function redactAndTruncate(value: unknown, maxBytes?: number | null): {
134
179
  /**
135
180
  * Initialize OpenTelemetry with the given configuration.
136
181
  * This should be called once at application startup.
182
+ *
183
+ * @param config - OpenTelemetry configuration; env vars fill in unset fields.
137
184
  */
138
185
  declare function initOtel(config?: OtelConfig): void;
139
186
  /**
140
- * Shutdown OpenTelemetry, flushing any pending data.
187
+ * Shut down OpenTelemetry, best-effort flushing any pending data before
188
+ * teardown.
141
189
  */
142
190
  declare function shutdownOtel(): Promise<void>;
143
191
  /**
@@ -162,6 +210,10 @@ declare function getMeter(): Meter$1 | null;
162
210
  declare function getLogger(): Logger | null;
163
211
  /**
164
212
  * Start a new span with the given name and run the callback within it.
213
+ *
214
+ * @param name - Name of the span to create.
215
+ * @param options - Span options: `kind` sets the span kind, `traceparent` sets the parent context from a W3C traceparent header.
216
+ * @param fn - Callback run inside the active span; its result is returned.
165
217
  */
166
218
  declare function withSpan<T>(name: string, options: {
167
219
  kind?: SpanKind;
@@ -169,4 +221,4 @@ declare function withSpan<T>(name: string, options: {
169
221
  }, fn: (span: Span$1) => Promise<T>): Promise<T>;
170
222
  //#endregion
171
223
  export { removeBaggageEntry as A, extractBaggage as C, getBaggageEntry as D, getAllBaggage as E, OtelConfig as M, ReconnectionConfig as N, injectBaggage as O, currentTraceId as S, extractTraceparent as T, recordSpanEvent as _, flushOtel as a, BaggageSpanProcessor as b, getTracer as c, withSpan as d, REDACTED_PLACEHOLDER as f, currentSpanIsRecording as g, resolveMaxBytesFromEnv as h, Span$1 as i, setBaggageEntry as j, injectTraceparent as k, initOtel as l, redactAndTruncate as m, Meter$1 as n, getLogger as o, redact as p, SeverityNumber as r, getMeter as s, Logger as t, shutdownOtel as u, setCurrentSpanAttribute as v, extractContext as w, currentSpanId as x, setCurrentSpanError as y };
172
- //# sourceMappingURL=index-BrvCdiQj.d.cts.map
224
+ //# sourceMappingURL=index-CFP8erFF.d.cts.map
@@ -69,6 +69,8 @@ declare function currentSpanId(): string | undefined;
69
69
  declare function injectTraceparent(): string | undefined;
70
70
  /**
71
71
  * Extract a trace context from a W3C traceparent header string.
72
+ *
73
+ * @param traceparent - W3C `traceparent` header value to parse.
72
74
  */
73
75
  declare function extractTraceparent(traceparent: string): Context;
74
76
  /**
@@ -77,22 +79,34 @@ declare function extractTraceparent(traceparent: string): Context;
77
79
  declare function injectBaggage(): string | undefined;
78
80
  /**
79
81
  * Extract baggage from a W3C baggage header string.
82
+ *
83
+ * @param baggage - W3C `baggage` header value to parse.
80
84
  */
81
85
  declare function extractBaggage(baggage: string): Context;
82
86
  /**
83
87
  * Extract both trace context and baggage from their respective headers.
88
+ *
89
+ * @param traceparent - W3C `traceparent` header value to parse.
90
+ * @param baggage - W3C `baggage` header value to parse.
84
91
  */
85
92
  declare function extractContext(traceparent?: string, baggage?: string): Context;
86
93
  /**
87
94
  * Get a baggage entry from the current context.
95
+ *
96
+ * @param key - Baggage entry key to read.
88
97
  */
89
98
  declare function getBaggageEntry(key: string): string | undefined;
90
99
  /**
91
100
  * Set a baggage entry in the current context.
101
+ *
102
+ * @param key - Baggage entry key to set.
103
+ * @param value - Baggage entry value to set.
92
104
  */
93
105
  declare function setBaggageEntry(key: string, value: string): Context;
94
106
  /**
95
107
  * Remove a baggage entry from the current context.
108
+ *
109
+ * @param key - Baggage entry key to remove.
96
110
  */
97
111
  declare function removeBaggageEntry(key: string): Context;
98
112
  /**
@@ -101,6 +115,10 @@ declare function removeBaggageEntry(key: string): Context;
101
115
  declare function getAllBaggage(): Record<string, string>;
102
116
  //#endregion
103
117
  //#region src/observability/telemetry-system/baggage-span-processor.d.ts
118
+ /**
119
+ * OpenTelemetry span processor that copies OTel baggage entries onto each
120
+ * started span as attributes.
121
+ */
104
122
  declare class BaggageSpanProcessor implements SpanProcessor {
105
123
  onStart(span: Span, parentContext: Context): void;
106
124
  onEnd(_span: ReadableSpan): void;
@@ -111,20 +129,47 @@ declare class BaggageSpanProcessor implements SpanProcessor {
111
129
  //#region src/observability/telemetry-system/span-ops.d.ts
112
130
  /** Returns `false` when there is no active span or the sampler dropped it. */
113
131
  declare function currentSpanIsRecording(): boolean;
114
- /** No-op when the current span is not recording. */
132
+ /**
133
+ * No-op when the current span is not recording.
134
+ *
135
+ * @param key - Attribute key to set on the active span.
136
+ * @param value - Attribute value to set.
137
+ */
115
138
  declare function setCurrentSpanAttribute(key: string, value: AttributeValue): void;
116
- /** No-op when there is no active span. */
139
+ /**
140
+ * No-op when there is no active span.
141
+ *
142
+ * @param message - Error message to set as the span's error status.
143
+ */
117
144
  declare function setCurrentSpanError(message: string): void;
118
- /** No-op when the current span is not recording. */
145
+ /**
146
+ * No-op when the current span is not recording.
147
+ *
148
+ * @param name - Name of the event to add to the active span.
149
+ * @param attrs - Optional attributes to attach to the event.
150
+ */
119
151
  declare function recordSpanEvent(name: string, attrs?: Attributes): void;
120
152
  //#endregion
121
153
  //#region src/observability/telemetry-system/payload.d.ts
122
154
  /** Payload redaction + truncation for invocation event capture. */
123
155
  declare const REDACTED_PLACEHOLDER = "[REDACTED]";
156
+ /**
157
+ * Resolve the payload byte cap from the environment, returning undefined when
158
+ * unset.
159
+ */
124
160
  declare function resolveMaxBytesFromEnv(): number | null;
125
- /** Recursively redact values of sensitive keys. Returns a new value. */
161
+ /**
162
+ * Recursively redact values of sensitive keys. Returns a new value.
163
+ *
164
+ * @param value - The value to recursively redact.
165
+ */
126
166
  declare function redact(value: unknown): unknown;
127
- /** Redact then serialize to JSON, optionally capped at `maxBytes`. */
167
+ /**
168
+ * Redact then serialize to JSON, optionally capped at `maxBytes`.
169
+ *
170
+ * @param value - The value to redact and serialize.
171
+ * @param maxBytes - Maximum serialized size in bytes; null leaves it uncapped.
172
+ */
128
173
  declare function redactAndTruncate(value: unknown, maxBytes?: number | null): {
129
174
  json: string;
130
175
  truncated: boolean;
@@ -134,10 +179,13 @@ declare function redactAndTruncate(value: unknown, maxBytes?: number | null): {
134
179
  /**
135
180
  * Initialize OpenTelemetry with the given configuration.
136
181
  * This should be called once at application startup.
182
+ *
183
+ * @param config - OpenTelemetry configuration; env vars fill in unset fields.
137
184
  */
138
185
  declare function initOtel(config?: OtelConfig): void;
139
186
  /**
140
- * Shutdown OpenTelemetry, flushing any pending data.
187
+ * Shut down OpenTelemetry, best-effort flushing any pending data before
188
+ * teardown.
141
189
  */
142
190
  declare function shutdownOtel(): Promise<void>;
143
191
  /**
@@ -162,6 +210,10 @@ declare function getMeter(): Meter$1 | null;
162
210
  declare function getLogger(): Logger | null;
163
211
  /**
164
212
  * Start a new span with the given name and run the callback within it.
213
+ *
214
+ * @param name - Name of the span to create.
215
+ * @param options - Span options: `kind` sets the span kind, `traceparent` sets the parent context from a W3C traceparent header.
216
+ * @param fn - Callback run inside the active span; its result is returned.
165
217
  */
166
218
  declare function withSpan<T>(name: string, options: {
167
219
  kind?: SpanKind$1;
@@ -169,4 +221,4 @@ declare function withSpan<T>(name: string, options: {
169
221
  }, fn: (span: Span$1) => Promise<T>): Promise<T>;
170
222
  //#endregion
171
223
  export { removeBaggageEntry as A, extractBaggage as C, getBaggageEntry as D, getAllBaggage as E, OtelConfig as M, ReconnectionConfig as N, injectBaggage as O, currentTraceId as S, extractTraceparent as T, recordSpanEvent as _, flushOtel as a, BaggageSpanProcessor as b, getTracer as c, withSpan as d, REDACTED_PLACEHOLDER as f, currentSpanIsRecording as g, resolveMaxBytesFromEnv as h, Span$1 as i, setBaggageEntry as j, injectTraceparent as k, initOtel as l, redactAndTruncate as m, Meter$1 as n, getLogger as o, redact as p, SeverityNumber$1 as r, getMeter as s, Logger as t, shutdownOtel as u, setCurrentSpanAttribute as v, extractContext as w, currentSpanId as x, setCurrentSpanError as y };
172
- //# sourceMappingURL=index-DnQ__58E.d.mts.map
224
+ //# sourceMappingURL=index-DObZ7kdy.d.mts.map
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_telemetry_system = require('../telemetry-system-p24MCQGC.cjs');
2
+ const require_telemetry_system = require('../telemetry-system-Dd45rFx-.cjs');
3
3
  let _opentelemetry_api_logs = require("@opentelemetry/api-logs");
4
4
  let _opentelemetry_api = require("@opentelemetry/api");
5
5
  let node_perf_hooks = require("node:perf_hooks");
@@ -147,6 +147,9 @@ const SAFE_RESPONSE_HEADERS = ["content-type"];
147
147
  * Mirrors the Rust execute_traced_request shape: injects W3C traceparent into
148
148
  * outgoing headers, records HTTP semantic-convention attributes, and sets
149
149
  * ERROR span status for HTTP responses with status >= 400 or network errors.
150
+ *
151
+ * @param input - The resource to fetch: a URL string, `URL`, or `Request`.
152
+ * @param init - Fetch options, plus an optional `tracer` to create the span.
150
153
  */
151
154
  async function executeTracedRequest(input, init) {
152
155
  const tracer = init?.tracer ?? _opentelemetry_api.trace.getTracer("iii-node-sdk");
@@ -334,6 +337,10 @@ let metricsCollector = null;
334
337
  let registeredMeter = null;
335
338
  let registeredBatchCallback = null;
336
339
  let registeredObservables = [];
340
+ /**
341
+ * Register OpenTelemetry observable gauges that report worker resource metrics
342
+ * (CPU, memory, event-loop) on each collection cycle.
343
+ */
337
344
  function registerWorkerGauges(meter, options) {
338
345
  if (registeredGauges) return;
339
346
  const { workerId, workerName } = options;
@@ -417,6 +424,9 @@ function registerWorkerGauges(meter, options) {
417
424
  ];
418
425
  registeredGauges = true;
419
426
  }
427
+ /**
428
+ * Stop and unregister the worker resource gauges.
429
+ */
420
430
  function stopWorkerGauges() {
421
431
  if (registeredMeter && registeredBatchCallback) registeredMeter.removeBatchObservableCallback(registeredBatchCallback, registeredObservables);
422
432
  if (metricsCollector) {
@@ -434,6 +444,8 @@ function stopWorkerGauges() {
434
444
  /**
435
445
  * Safely stringify a value, handling circular references, BigInt, and other edge cases.
436
446
  * Returns "[unserializable]" if serialization fails for any reason.
447
+ *
448
+ * @param value - The value to serialize to JSON.
437
449
  */
438
450
  function safeStringify(value) {
439
451
  const seen = /* @__PURE__ */ new WeakSet();
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["getOtelLogger","currentTraceId","currentSpanId","SeverityNumber","trace","SpanKind","otelContext","SpanStatusCode","performance"],"sources":["../../src/observability/logger.ts","../../src/observability/http-instrumentation.ts","../../src/observability/worker-metrics.ts","../../src/observability/otel-worker-gauges.ts","../../src/observability/utils.ts"],"sourcesContent":["import { AnyValue, AnyValueMap, SeverityNumber } from '@opentelemetry/api-logs'\nimport {\n currentSpanId,\n currentTraceId,\n getLogger as getOtelLogger,\n} from './telemetry-system'\n\n/** @internal */\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\n/**\n * Structured logger that emits logs as OpenTelemetry LogRecords.\n *\n * Every log call automatically captures the active trace and span context,\n * correlating your logs with distributed traces without any manual wiring.\n * When OTel is not initialized, Logger gracefully falls back to `console.*`.\n *\n * Pass structured data as the second argument to any log method. Using an\n * object of key-value pairs (instead of string interpolation) lets you\n * filter, aggregate, and build dashboards in your observability backend.\n *\n * @example\n * ```typescript\n * import { Logger } from 'iii-sdk'\n *\n * const logger = new Logger()\n *\n * // Basic logging, trace context is injected automatically\n * logger.info('Worker connected')\n *\n * // Structured context for dashboards and alerting\n * logger.info('Order processed', { orderId: 'ord_123', amount: 49.99, currency: 'USD' })\n * logger.warn('Retry attempt', { attempt: 3, maxRetries: 5, endpoint: '/api/charge' })\n * logger.error('Payment failed', { orderId: 'ord_123', gateway: 'stripe', errorCode: 'card_declined' })\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: AnyValueMap = {}\n const traceId = this.traceId ?? currentTraceId()\n const spanId = this.spanId ?? currentSpanId()\n\n if (traceId) {\n attributes.trace_id = traceId\n }\n if (spanId) {\n attributes.span_id = spanId\n }\n if (this.serviceName) {\n attributes['service.name'] = this.serviceName\n }\n if (data !== undefined) {\n attributes['log.data'] = data as AnyValue\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 /**\n * Log an info-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.info('Order processed', { orderId: 'ord_123', status: 'completed' })\n * ```\n */\n info(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.INFO, data)\n }\n\n /**\n * Log a warning-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.warn('Retry attempt', { attempt: 3, maxRetries: 5, endpoint: '/api/charge' })\n * ```\n */\n warn(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.WARN, data)\n }\n\n /**\n * Log an error-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.error('Payment failed', { orderId: 'ord_123', gateway: 'stripe', errorCode: 'card_declined' })\n * ```\n */\n error(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.ERROR, data)\n }\n\n /**\n * Log a debug-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.debug('Cache lookup', { key: 'user:42', hit: false })\n * ```\n */\n debug(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.DEBUG, data)\n }\n}\n","import { context as otelContext, propagation, SpanKind, SpanStatusCode, trace, type Tracer } from '@opentelemetry/api'\n\nconst SAFE_REQUEST_HEADERS = ['content-type', 'accept'] as const\nconst SAFE_RESPONSE_HEADERS = ['content-type'] as const\n\nexport interface TracedFetchInit extends RequestInit {\n tracer?: Tracer\n}\n\n/**\n * Execute a fetch request inside an OTel CLIENT span.\n *\n * Mirrors the Rust execute_traced_request shape: injects W3C traceparent into\n * outgoing headers, records HTTP semantic-convention attributes, and sets\n * ERROR span status for HTTP responses with status >= 400 or network errors.\n */\nexport async function executeTracedRequest(\n input: RequestInfo | URL,\n init?: TracedFetchInit,\n): Promise<Response> {\n const tracer = init?.tracer ?? trace.getTracer('iii-node-sdk')\n const rawUrl = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n let url: URL | null\n try {\n url = new URL(rawUrl)\n } catch {\n url = null\n }\n const method = (init?.method ?? (typeof input === 'object' && 'method' in input ? input.method : 'GET') ?? 'GET').toUpperCase()\n const name = url?.pathname ? `${method} ${url.pathname}` : method\n\n return tracer.startActiveSpan(\n name,\n {\n kind: SpanKind.CLIENT,\n attributes: {\n 'http.request.method': method,\n 'url.full': url?.toString() ?? rawUrl,\n 'network.protocol.name': 'http',\n ...(url\n ? {\n 'server.address': url.hostname,\n 'url.scheme': url.protocol.replace(':', ''),\n 'url.path': url.pathname,\n }\n : {}),\n ...(url?.port ? { 'server.port': Number(url.port) } : {}),\n ...(url?.search ? { 'url.query': url.search.slice(1) } : {}),\n },\n },\n async (span) => {\n try {\n // Seed with the Request's own headers so they survive when caller\n // passes a Request object; init.headers (if any) then overrides.\n const baseHeaders =\n typeof input === 'object' && 'headers' in input ? input.headers : undefined\n const headers = new Headers(baseHeaders)\n if (init?.headers) {\n for (const [k, v] of new Headers(init.headers).entries()) headers.set(k, v)\n }\n const carrier: Record<string, string> = {}\n propagation.inject(otelContext.active(), carrier)\n for (const [k, v] of Object.entries(carrier)) headers.set(k, v)\n\n for (const h of SAFE_REQUEST_HEADERS) {\n const v = headers.get(h)\n if (v) span.setAttribute(`http.request.header.${h}`, v)\n }\n\n const response = await fetch(input, { ...init, headers })\n span.setAttribute('http.response.status_code', response.status)\n const cl = response.headers.get('content-length')\n if (cl) span.setAttribute('http.response.body.size', Number(cl))\n for (const h of SAFE_RESPONSE_HEADERS) {\n const v = response.headers.get(h)\n if (v) span.setAttribute(`http.response.header.${h}`, v)\n }\n\n if (response.status >= 400) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: String(response.status) })\n span.setAttribute('error.type', String(response.status))\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n return response\n } catch (err) {\n const error = err as Error\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.setAttribute('error.type', error.name)\n throw err\n } finally {\n span.end()\n }\n },\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","/**\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 const result = 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 return result ?? '[unserializable]'\n } catch {\n return '[unserializable]'\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["getOtelLogger","currentTraceId","currentSpanId","SeverityNumber","trace","SpanKind","otelContext","SpanStatusCode","performance"],"sources":["../../src/observability/logger.ts","../../src/observability/http-instrumentation.ts","../../src/observability/worker-metrics.ts","../../src/observability/otel-worker-gauges.ts","../../src/observability/utils.ts"],"sourcesContent":["import { AnyValue, AnyValueMap, SeverityNumber } from '@opentelemetry/api-logs'\nimport {\n currentSpanId,\n currentTraceId,\n getLogger as getOtelLogger,\n} from './telemetry-system'\n\n/** @internal */\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\n/**\n * Structured logger that emits logs as OpenTelemetry LogRecords.\n *\n * Every log call automatically captures the active trace and span context,\n * correlating your logs with distributed traces without any manual wiring.\n * When OTel is not initialized, Logger gracefully falls back to `console.*`.\n *\n * Pass structured data as the second argument to any log method. Using an\n * object of key-value pairs (instead of string interpolation) lets you\n * filter, aggregate, and build dashboards in your observability backend.\n *\n * @example\n * ```typescript\n * import { Logger } from 'iii-sdk'\n *\n * const logger = new Logger()\n *\n * // Basic logging, trace context is injected automatically\n * logger.info('Worker connected')\n *\n * // Structured context for dashboards and alerting\n * logger.info('Order processed', { orderId: 'ord_123', amount: 49.99, currency: 'USD' })\n * logger.warn('Retry attempt', { attempt: 3, maxRetries: 5, endpoint: '/api/charge' })\n * logger.error('Payment failed', { orderId: 'ord_123', gateway: 'stripe', errorCode: 'card_declined' })\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: AnyValueMap = {}\n const traceId = this.traceId ?? currentTraceId()\n const spanId = this.spanId ?? currentSpanId()\n\n if (traceId) {\n attributes.trace_id = traceId\n }\n if (spanId) {\n attributes.span_id = spanId\n }\n if (this.serviceName) {\n attributes['service.name'] = this.serviceName\n }\n if (data !== undefined) {\n attributes['log.data'] = data as AnyValue\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 /**\n * Log an info-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.info('Order processed', { orderId: 'ord_123', status: 'completed' })\n * ```\n */\n info(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.INFO, data)\n }\n\n /**\n * Log a warning-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.warn('Retry attempt', { attempt: 3, maxRetries: 5, endpoint: '/api/charge' })\n * ```\n */\n warn(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.WARN, data)\n }\n\n /**\n * Log an error-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.error('Payment failed', { orderId: 'ord_123', gateway: 'stripe', errorCode: 'card_declined' })\n * ```\n */\n error(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.ERROR, data)\n }\n\n /**\n * Log a debug-level message.\n *\n * @param message - Human-readable log message.\n * @param data - Structured context attached as OTel log attributes.\n * Use key-value objects to enable filtering and aggregation in your\n * observability backend (e.g. Grafana, Datadog, New Relic).\n *\n * @example\n * ```typescript\n * logger.debug('Cache lookup', { key: 'user:42', hit: false })\n * ```\n */\n debug(message: string, data?: unknown): void {\n this.emit(message, SeverityNumber.DEBUG, data)\n }\n}\n","import { context as otelContext, propagation, SpanKind, SpanStatusCode, trace, type Tracer } from '@opentelemetry/api'\n\nconst SAFE_REQUEST_HEADERS = ['content-type', 'accept'] as const\nconst SAFE_RESPONSE_HEADERS = ['content-type'] as const\n\nexport interface TracedFetchInit extends RequestInit {\n /** Tracer used to create the client span for the outgoing request. */\n tracer?: Tracer\n}\n\n/**\n * Execute a fetch request inside an OTel CLIENT span.\n *\n * Mirrors the Rust execute_traced_request shape: injects W3C traceparent into\n * outgoing headers, records HTTP semantic-convention attributes, and sets\n * ERROR span status for HTTP responses with status >= 400 or network errors.\n *\n * @param input - The resource to fetch: a URL string, `URL`, or `Request`.\n * @param init - Fetch options, plus an optional `tracer` to create the span.\n */\nexport async function executeTracedRequest(\n input: RequestInfo | URL,\n init?: TracedFetchInit,\n): Promise<Response> {\n const tracer = init?.tracer ?? trace.getTracer('iii-node-sdk')\n const rawUrl = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url\n let url: URL | null\n try {\n url = new URL(rawUrl)\n } catch {\n url = null\n }\n const method = (init?.method ?? (typeof input === 'object' && 'method' in input ? input.method : 'GET') ?? 'GET').toUpperCase()\n const name = url?.pathname ? `${method} ${url.pathname}` : method\n\n return tracer.startActiveSpan(\n name,\n {\n kind: SpanKind.CLIENT,\n attributes: {\n 'http.request.method': method,\n 'url.full': url?.toString() ?? rawUrl,\n 'network.protocol.name': 'http',\n ...(url\n ? {\n 'server.address': url.hostname,\n 'url.scheme': url.protocol.replace(':', ''),\n 'url.path': url.pathname,\n }\n : {}),\n ...(url?.port ? { 'server.port': Number(url.port) } : {}),\n ...(url?.search ? { 'url.query': url.search.slice(1) } : {}),\n },\n },\n async (span) => {\n try {\n // Seed with the Request's own headers so they survive when caller\n // passes a Request object; init.headers (if any) then overrides.\n const baseHeaders =\n typeof input === 'object' && 'headers' in input ? input.headers : undefined\n const headers = new Headers(baseHeaders)\n if (init?.headers) {\n for (const [k, v] of new Headers(init.headers).entries()) headers.set(k, v)\n }\n const carrier: Record<string, string> = {}\n propagation.inject(otelContext.active(), carrier)\n for (const [k, v] of Object.entries(carrier)) headers.set(k, v)\n\n for (const h of SAFE_REQUEST_HEADERS) {\n const v = headers.get(h)\n if (v) span.setAttribute(`http.request.header.${h}`, v)\n }\n\n const response = await fetch(input, { ...init, headers })\n span.setAttribute('http.response.status_code', response.status)\n const cl = response.headers.get('content-length')\n if (cl) span.setAttribute('http.response.body.size', Number(cl))\n for (const h of SAFE_RESPONSE_HEADERS) {\n const v = response.headers.get(h)\n if (v) span.setAttribute(`http.response.header.${h}`, v)\n }\n\n if (response.status >= 400) {\n span.setStatus({ code: SpanStatusCode.ERROR, message: String(response.status) })\n span.setAttribute('error.type', String(response.status))\n } else {\n span.setStatus({ code: SpanStatusCode.OK })\n }\n return response\n } catch (err) {\n const error = err as Error\n span.recordException(error)\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message })\n span.setAttribute('error.type', error.name)\n throw err\n } finally {\n span.end()\n }\n },\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 * <!-- docs:internal -->\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 /** Stable identifier of the worker the gauges are reported for. */\n workerId: string\n /** Human-readable name of the worker. */\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\n/**\n * Register OpenTelemetry observable gauges that report worker resource metrics\n * (CPU, memory, event-loop) on each collection cycle.\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\n/**\n * Stop and unregister the worker resource gauges.\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","/**\n * Safely stringify a value, handling circular references, BigInt, and other edge cases.\n * Returns \"[unserializable]\" if serialization fails for any reason.\n *\n * @param value - The value to serialize to JSON.\n */\nexport function safeStringify(value: unknown): string {\n const seen = new WeakSet<object>()\n\n try {\n const result = 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 return result ?? '[unserializable]'\n } catch {\n return '[unserializable]'\n }\n}\n"],"mappings":"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"}