logixia 2.0.10 → 2.0.11

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.
Files changed (125) hide show
  1. package/dist/{async-context-COuvmwsS.mjs → async-context-BGUCdYAa.mjs} +3 -3
  2. package/dist/{async-context-COuvmwsS.mjs.map → async-context-BGUCdYAa.mjs.map} +1 -1
  3. package/dist/{async-context-Dv0bmPC-.js → async-context-D8um9I5V.js} +3 -3
  4. package/dist/{async-context-Dv0bmPC-.js.map → async-context-D8um9I5V.js.map} +1 -1
  5. package/dist/{azure-monitor.transport-D6ryi8rA.js → azure-monitor.transport-C8KdmsSw.js} +19 -8
  6. package/dist/{azure-monitor.transport-D6ryi8rA.js.map → azure-monitor.transport-C8KdmsSw.js.map} +1 -1
  7. package/dist/{azure-monitor.transport-Coz5Gesu.mjs → azure-monitor.transport-CTnfwA0F.mjs} +19 -8
  8. package/dist/{azure-monitor.transport-Coz5Gesu.mjs.map → azure-monitor.transport-CTnfwA0F.mjs.map} +1 -1
  9. package/dist/azure.js +1 -1
  10. package/dist/azure.mjs +1 -1
  11. package/dist/{batch-buffer-CQUWDMYq.mjs → batch-buffer-BJqzpfpT.mjs} +11 -7
  12. package/dist/{batch-buffer-CQUWDMYq.mjs.map → batch-buffer-BJqzpfpT.mjs.map} +1 -1
  13. package/dist/{batch-buffer-CFzKnuNZ.js → batch-buffer-BTQdAXwC.js} +11 -7
  14. package/dist/{batch-buffer-CFzKnuNZ.js.map → batch-buffer-BTQdAXwC.js.map} +1 -1
  15. package/dist/browser.js +24 -9
  16. package/dist/browser.js.map +1 -1
  17. package/dist/browser.mjs +24 -9
  18. package/dist/browser.mjs.map +1 -1
  19. package/dist/{builder-Bj3mDeBw.mjs → builder-C6kKEVrU.mjs} +149 -51
  20. package/dist/builder-C6kKEVrU.mjs.map +1 -0
  21. package/dist/{builder-BLIStsCK.js → builder-Up4YxX7l.js} +153 -55
  22. package/dist/builder-Up4YxX7l.js.map +1 -0
  23. package/dist/cli/index.js +21 -16
  24. package/dist/cloudwatch.js +1 -1
  25. package/dist/cloudwatch.mjs +1 -1
  26. package/dist/{cloudwatch.transport-Cr1aeTGj.mjs → cloudwatch.transport-Bl1qzdBx.mjs} +24 -9
  27. package/dist/{cloudwatch.transport-Cr1aeTGj.mjs.map → cloudwatch.transport-Bl1qzdBx.mjs.map} +1 -1
  28. package/dist/{cloudwatch.transport-D4G5xYfG.js → cloudwatch.transport-BoCyxNKO.js} +24 -9
  29. package/dist/{cloudwatch.transport-D4G5xYfG.js.map → cloudwatch.transport-BoCyxNKO.js.map} +1 -1
  30. package/dist/correlation.js +3 -3
  31. package/dist/correlation.mjs +3 -3
  32. package/dist/{coerce.utils-C1C5sIX0.js → csv.utils-CbVHY1pd.js} +24 -1
  33. package/dist/csv.utils-CbVHY1pd.js.map +1 -0
  34. package/dist/{coerce.utils-B_rEudCn.mjs → csv.utils-ZdxSod5g.mjs} +19 -2
  35. package/dist/csv.utils-ZdxSod5g.mjs.map +1 -0
  36. package/dist/{entry-fields-CVwoQplO.js → entry-fields-CJbeaoBs.js} +2 -2
  37. package/dist/{entry-fields-CVwoQplO.js.map → entry-fields-CJbeaoBs.js.map} +1 -1
  38. package/dist/{entry-fields-DNTKQxoU.mjs → entry-fields-D_aNnjg0.mjs} +2 -2
  39. package/dist/{entry-fields-DNTKQxoU.mjs.map → entry-fields-D_aNnjg0.mjs.map} +1 -1
  40. package/dist/gcp.js +1 -1
  41. package/dist/gcp.mjs +1 -1
  42. package/dist/{gcp.transport-LLK2bw2-.mjs → gcp.transport-DOH4bpWM.mjs} +18 -9
  43. package/dist/{gcp.transport-LLK2bw2-.mjs.map → gcp.transport-DOH4bpWM.mjs.map} +1 -1
  44. package/dist/{gcp.transport-CVuRpchl.js → gcp.transport-D_NHVZrw.js} +18 -9
  45. package/dist/{gcp.transport-CVuRpchl.js.map → gcp.transport-D_NHVZrw.js.map} +1 -1
  46. package/dist/index.d.mts +1 -1
  47. package/dist/index.d.mts.map +1 -1
  48. package/dist/index.d.ts +1 -1
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +35 -19
  51. package/dist/index.js.map +1 -1
  52. package/dist/index.mjs +32 -16
  53. package/dist/index.mjs.map +1 -1
  54. package/dist/logitron-logger-DVUdgmBY.d.ts.map +1 -1
  55. package/dist/logitron-logger-DoWmMjYB.d.mts.map +1 -1
  56. package/dist/middleware.d.mts.map +1 -1
  57. package/dist/middleware.d.ts.map +1 -1
  58. package/dist/middleware.js +10 -6
  59. package/dist/middleware.js.map +1 -1
  60. package/dist/middleware.mjs +10 -6
  61. package/dist/middleware.mjs.map +1 -1
  62. package/dist/nest.d.mts +4 -3
  63. package/dist/nest.d.mts.map +1 -1
  64. package/dist/nest.d.ts +4 -3
  65. package/dist/nest.d.ts.map +1 -1
  66. package/dist/nest.js +41 -20
  67. package/dist/nest.js.map +1 -1
  68. package/dist/nest.mjs +39 -18
  69. package/dist/nest.mjs.map +1 -1
  70. package/dist/{otel-DOuwGPCd.mjs → otel-DAVxpArV.mjs} +135 -56
  71. package/dist/otel-DAVxpArV.mjs.map +1 -0
  72. package/dist/{otel-ChnVYRLA.js → otel-DH6-G6DR.js} +137 -58
  73. package/dist/otel-DH6-G6DR.js.map +1 -0
  74. package/dist/{request-trace-ByujsUZk.js → request-trace-C7kXMjx5.js} +5 -6
  75. package/dist/{request-trace-ByujsUZk.js.map → request-trace-C7kXMjx5.js.map} +1 -1
  76. package/dist/{request-trace-BgNykH9M.mjs → request-trace-Dekcnenb.mjs} +5 -6
  77. package/dist/{request-trace-BgNykH9M.mjs.map → request-trace-Dekcnenb.mjs.map} +1 -1
  78. package/dist/{safe-stringify-CN7icp8S.js → safe-stringify-CJisLyZ3.js} +2 -2
  79. package/dist/{safe-stringify-CN7icp8S.js.map → safe-stringify-CJisLyZ3.js.map} +1 -1
  80. package/dist/{safe-stringify--7gbe95n.mjs → safe-stringify-pZOnzGRJ.mjs} +2 -2
  81. package/dist/{safe-stringify--7gbe95n.mjs.map → safe-stringify-pZOnzGRJ.mjs.map} +1 -1
  82. package/dist/{search-DPwTKPve.d.ts → search-B4eEzrhM.d.ts} +3 -6
  83. package/dist/{search-DPwTKPve.d.ts.map → search-B4eEzrhM.d.ts.map} +1 -1
  84. package/dist/{search-CRjhHxe9.js → search-CJw_xoQl.js} +44 -35
  85. package/dist/search-CJw_xoQl.js.map +1 -0
  86. package/dist/{search-DAXKE-P9.mjs → search-CjYl-mo5.mjs} +41 -32
  87. package/dist/search-CjYl-mo5.mjs.map +1 -0
  88. package/dist/{search-D-8HJADE.d.mts → search-Crf2IEoA.d.mts} +3 -6
  89. package/dist/{search-D-8HJADE.d.mts.map → search-Crf2IEoA.d.mts.map} +1 -1
  90. package/dist/search.d.mts +1 -1
  91. package/dist/search.d.ts +1 -1
  92. package/dist/search.js +1 -1
  93. package/dist/search.mjs +1 -1
  94. package/dist/{secret-config-BvFl2dC8.js → secret-config-6hdODxBb.js} +2 -2
  95. package/dist/{secret-config-BvFl2dC8.js.map → secret-config-6hdODxBb.js.map} +1 -1
  96. package/dist/{secret-config-ByGq7kJd.mjs → secret-config-D1F4MW69.mjs} +2 -2
  97. package/dist/{secret-config-ByGq7kJd.mjs.map → secret-config-D1F4MW69.mjs.map} +1 -1
  98. package/dist/{sensitive-names-CHMowujD.js → sensitive-names-CNgHaqv9.js} +7 -1
  99. package/dist/{sensitive-names-CHMowujD.js.map → sensitive-names-CNgHaqv9.js.map} +1 -1
  100. package/dist/{sensitive-names-o__1PUUR.mjs → sensitive-names-wv27qBQC.mjs} +2 -2
  101. package/dist/{sensitive-names-o__1PUUR.mjs.map → sensitive-names-wv27qBQC.mjs.map} +1 -1
  102. package/dist/{slack.transport-zLQ9MGxS.js → slack.transport-CEYBVzUj.js} +46 -18
  103. package/dist/{slack.transport-zLQ9MGxS.js.map → slack.transport-CEYBVzUj.js.map} +1 -1
  104. package/dist/{slack.transport-CSj1j0_X.mjs → slack.transport-YvaLJxNv.mjs} +46 -18
  105. package/dist/{slack.transport-CSj1j0_X.mjs.map → slack.transport-YvaLJxNv.mjs.map} +1 -1
  106. package/dist/transports.d.mts.map +1 -1
  107. package/dist/transports.d.ts.map +1 -1
  108. package/dist/transports.js +6 -6
  109. package/dist/transports.mjs +6 -6
  110. package/dist/worker-entry.js +109 -41
  111. package/dist/worker.js +1 -1
  112. package/dist/worker.mjs +1 -1
  113. package/dist/{worker.transport-DQDv1nAJ.js → worker.transport-CwNpH98o.js} +21 -13
  114. package/dist/{worker.transport-DQDv1nAJ.js.map → worker.transport-CwNpH98o.js.map} +1 -1
  115. package/dist/{worker.transport-D78xhNhB.mjs → worker.transport-DgK_ZXlB.mjs} +21 -13
  116. package/dist/{worker.transport-D78xhNhB.mjs.map → worker.transport-DgK_ZXlB.mjs.map} +1 -1
  117. package/package.json +10 -3
  118. package/dist/builder-BLIStsCK.js.map +0 -1
  119. package/dist/builder-Bj3mDeBw.mjs.map +0 -1
  120. package/dist/coerce.utils-B_rEudCn.mjs.map +0 -1
  121. package/dist/coerce.utils-C1C5sIX0.js.map +0 -1
  122. package/dist/otel-ChnVYRLA.js.map +0 -1
  123. package/dist/otel-DOuwGPCd.mjs.map +0 -1
  124. package/dist/search-CRjhHxe9.js.map +0 -1
  125. package/dist/search-DAXKE-P9.mjs.map +0 -1
@@ -22,10 +22,10 @@ const TRACE_CONTEXT_KEY = "traceId";
22
22
  * TraceContext.instance.getCurrentTraceId() // same as standalone fn
23
23
  */
24
24
  var TraceContext = class TraceContext {
25
- constructor() {
26
- this.storage = new AsyncLocalStorage();
27
- this._contextKey = TRACE_CONTEXT_KEY;
28
- }
25
+ static _instance = null;
26
+ storage = new AsyncLocalStorage();
27
+ _contextKey = TRACE_CONTEXT_KEY;
28
+ constructor() {}
29
29
  /** The process-wide singleton. */
30
30
  static get instance() {
31
31
  if (!TraceContext._instance) TraceContext._instance = new TraceContext();
@@ -84,7 +84,6 @@ var TraceContext = class TraceContext {
84
84
  ...data
85
85
  }, fn);
86
86
  }
87
- static #_ = () => this._instance = null;
88
87
  };
89
88
  /**
90
89
  * The shared AsyncLocalStorage instance.
@@ -306,4 +305,4 @@ function resolveRequestTraceId(req, headers) {
306
305
  }
307
306
  export { TRACE_CONTEXT_KEY as a, createTraceMiddleware as c, getTraceContextKey as d, runWithTraceId as f, traceStorage as h, MAX_INCOMING_ID_LENGTH as i, extractTraceId as l, setTraceId as m, resolveTraceHeaders as n, TraceContext as o, sanitizeIncomingId as p, DEFAULT_TRACE_HEADERS as r, _setActiveContextKey as s, resolveRequestTraceId as t, getCurrentTraceId as u };
308
307
 
309
- //# sourceMappingURL=request-trace-BgNykH9M.mjs.map
308
+ //# sourceMappingURL=request-trace-Dekcnenb.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"request-trace-BgNykH9M.mjs","names":[],"sources":["../src/utils/trace.utils.ts","../src/utils/request-trace.ts"],"sourcesContent":["/**\n * Trace ID utilities for Logitron\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\n\nimport type { TraceIdConfig, TraceIdExtractorConfig } from '../types';\n\n/** Default key used to store the trace ID in AsyncLocalStorage. */\nexport const TRACE_CONTEXT_KEY = 'traceId' as const;\n\n// ── TraceContext class ────────────────────────────────────────────────────────\n\n/**\n * Singleton that owns the AsyncLocalStorage and the active contextKey.\n *\n * Why a class instead of bare module-level variables?\n * - The contextKey is user-configurable; encapsulating it here means there is\n * exactly one place that reads and writes it.\n * - All helpers (getCurrentTraceId, runWithTraceId, etc.) delegate to this\n * instance, so the key is always in sync without hidden global state.\n * - Easier to test: you can reset the singleton between test cases.\n *\n * Usage (advanced):\n * import { TraceContext } from 'logixia';\n * TraceContext.instance.contextKey // → 'traceId' (or custom)\n * TraceContext.instance.getCurrentTraceId() // same as standalone fn\n */\nexport class TraceContext {\n private static _instance: TraceContext | null = null;\n\n readonly storage = new AsyncLocalStorage<Record<string, unknown>>();\n private _contextKey: string = TRACE_CONTEXT_KEY;\n\n private constructor() {}\n\n /** The process-wide singleton. */\n static get instance(): TraceContext {\n if (!TraceContext._instance) {\n TraceContext._instance = new TraceContext();\n }\n return TraceContext._instance;\n }\n\n /** @internal Reset the singleton (useful in tests). */\n static _reset(): void {\n TraceContext._instance = null;\n }\n\n // ── Key management ──────────────────────────────────────────────────────────\n\n /** The AsyncLocalStorage key that holds the trace ID value. */\n get contextKey(): string {\n return this._contextKey;\n }\n\n /** @internal Called by TraceMiddleware when it boots to register the user's key. */\n setContextKey(key: string): void {\n this._contextKey = key;\n }\n\n // ── Core operations ─────────────────────────────────────────────────────────\n\n /** UUID v4 generator (default). */\n generate(): string {\n return randomUUID();\n }\n\n /** Read the trace ID from the current async context. */\n getCurrentTraceId(): string | undefined {\n return this.storage.getStore()?.[this._contextKey] as string | undefined;\n }\n\n /**\n * Mutate the CURRENT async context in-place.\n *\n * ⚠️ DEPRECATED — unsafe for concurrent requests.\n *\n * Uses `AsyncLocalStorage.enterWith()`, which mutates the current async\n * execution context and every Promise chain spawned from it. In a server\n * processing overlapping requests this can cause a trace ID set for one\n * request to bleed into *other* in-flight requests that share the same\n * async parent (e.g. a module-level setup function or a cached handler).\n *\n * Use {@link run} instead — it scopes the context to a callback so there\n * is no risk of cross-request leakage.\n *\n * @deprecated Use `TraceContext.instance.run(traceId, fn)` — do not call\n * `setTraceId` from request-handling code.\n */\n setTraceId(traceId: string, data?: Record<string, unknown>): void {\n const current = this.storage.getStore() ?? {};\n this.storage.enterWith({ ...current, [this._contextKey]: traceId, ...data });\n }\n\n /** Run `fn` inside a new async context that carries `traceId`. */\n run<T>(traceId: string, fn: () => T, data?: Record<string, unknown>): T {\n return this.storage.run({ [this._contextKey]: traceId, ...data }, fn);\n }\n}\n\n// ── Module-level aliases (backwards-compatible public API) ────────────────────\n\n/**\n * The shared AsyncLocalStorage instance.\n * @deprecated Prefer `TraceContext.instance.storage` for new code.\n */\nexport const traceStorage = TraceContext.instance.storage;\n\n/** Returns the key currently used to store the trace ID in AsyncLocalStorage. */\nexport function getTraceContextKey(): string {\n return TraceContext.instance.contextKey;\n}\n\n/** @internal Called by TraceMiddleware / traceMiddleware() when they boot. */\nexport function _setActiveContextKey(key: string): void {\n TraceContext.instance.setContextKey(key);\n}\n\n/** Generate a UUID v4 trace ID. */\nexport function generateTraceId(): string {\n return TraceContext.instance.generate();\n}\n\n/**\n * Get the current trace ID from async context.\n * Returns `undefined` when called outside a traced request.\n */\nexport function getCurrentTraceId(): string | undefined {\n return TraceContext.instance.getCurrentTraceId();\n}\n\n/**\n * Set trace ID in the CURRENT async context without starting a new one.\n *\n * ⚠️ DEPRECATED — unsafe for concurrent requests.\n *\n * Uses `AsyncLocalStorage.enterWith()`, which mutates the current async\n * execution context and every Promise chain spawned from it. Under load this\n * can cause a trace ID from one request to bleed into others sharing the same\n * async parent.\n *\n * Use {@link runWithTraceId} instead. Migration patterns:\n *\n * **Express / Fastify middleware — before:**\n * ```ts\n * app.use((req, _res, next) => {\n * setTraceId(req.headers['x-trace-id'] ?? generateTraceId());\n * next();\n * });\n * ```\n * **after:**\n * ```ts\n * app.use((req, _res, next) => {\n * runWithTraceId(req.headers['x-trace-id'] ?? generateTraceId(), () => next());\n * });\n * ```\n *\n * **Kafka / queue consumer — before:**\n * ```ts\n * async function handle(msg) {\n * setTraceId(msg.headers['x-trace-id']);\n * await processMessage(msg);\n * }\n * ```\n * **after:**\n * ```ts\n * async function handle(msg) {\n * await runWithTraceId(msg.headers['x-trace-id'], () => processMessage(msg));\n * }\n * ```\n *\n * **Background job — before:**\n * ```ts\n * setTraceId(generateTraceId(), { jobId: job.id });\n * await job.run();\n * ```\n * **after:**\n * ```ts\n * await runWithTraceId(generateTraceId(), () => job.run(), { jobId: job.id });\n * ```\n *\n * @deprecated Use `runWithTraceId(traceId, fn)` — do not call `setTraceId`\n * from request-handling code.\n */\nexport function setTraceId(traceId: string, data?: Record<string, unknown>): void {\n TraceContext.instance.setTraceId(traceId, data);\n}\n\n/** Run `fn` inside a new async context carrying `traceId`. */\nexport function runWithTraceId<T>(traceId: string, fn: () => T, data?: Record<string, unknown>): T {\n return TraceContext.instance.run(traceId, fn, data);\n}\n\n// ── Request extraction ────────────────────────────────────────────────────────\n\ntype HeaderValue = string | string[] | undefined;\n\n/** Shape that extractTraceId accepts (Express-compatible) */\ninterface RequestLike {\n headers?: Record<string, HeaderValue>;\n query?: Record<string, HeaderValue>;\n body?: Record<string, string | undefined>;\n params?: Record<string, string | undefined>;\n}\n\n/** Maximum accepted length for an incoming trace / correlation / request ID. */\nexport const MAX_INCOMING_ID_LENGTH = 128;\n\nconst SAFE_INCOMING_ID = /^[A-Za-z0-9._:-]{1,128}$/;\n\n/**\n * Validate an externally supplied identifier (trace ID, correlation ID, origin\n * service name, message-queue ID). Accepts only 1-128 characters from\n * `[A-Za-z0-9._:-]`; surrounding whitespace is trimmed first. Arrays use their\n * first element. Returns the cleaned value, or `undefined` when it is unusable\n * so callers can generate a fresh ID instead of passing client text through.\n */\nexport function sanitizeIncomingId(value: unknown): string | undefined {\n const first = Array.isArray(value) ? value[0] : value;\n if (typeof first !== 'string' || first.length > MAX_INCOMING_ID_LENGTH * 2) return undefined;\n const trimmed = first.trim();\n return SAFE_INCOMING_ID.test(trimmed) ? trimmed : undefined;\n}\n\n/** W3C trace-context: `version-traceId(32hex)-spanId(16hex)-flags(2hex)`. */\nconst W3C_TRACEPARENT_RE = /^[\\da-f]{2}-([\\da-f]{32})-[\\da-f]{16}-[\\da-f]{2}$/i;\n\n/**\n * Extract the 32-hex trace-id segment from a W3C `traceparent` header value.\n * Returns the parsed trace ID, or the original value unchanged when it is not a\n * well-formed traceparent (so non-W3C propagation still works).\n */\nfunction parseTraceparent(value: string): string {\n const m = W3C_TRACEPARENT_RE.exec(value);\n return m ? m[1]! : value;\n}\n\n/** Extract trace ID from request using configuration (header → query → body → params). */\nexport function extractTraceId(\n request: unknown,\n config: TraceIdExtractorConfig\n): string | undefined {\n const req = request as RequestLike;\n\n if (config.header) {\n const headers = Array.isArray(config.header) ? config.header : [config.header];\n for (const header of headers) {\n const lower = header.toLowerCase();\n const value = sanitizeIncomingId(req.headers?.[lower]);\n if (value) return lower === 'traceparent' ? parseTraceparent(value) : value;\n }\n }\n\n if (config.query) {\n const queries = Array.isArray(config.query) ? config.query : [config.query];\n for (const query of queries) {\n const value = sanitizeIncomingId(req.query?.[query]);\n if (value) return value;\n }\n }\n\n if (config.body) {\n const bodyFields = Array.isArray(config.body) ? config.body : [config.body];\n for (const field of bodyFields) {\n const value = sanitizeIncomingId(req.body?.[field]);\n if (value) return value;\n }\n }\n\n if (config.params) {\n const paramFields = Array.isArray(config.params) ? config.params : [config.params];\n for (const param of paramFields) {\n const value = sanitizeIncomingId(req.params?.[param]);\n if (value) return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Default headers checked for incoming trace ID propagation, in priority order:\n * traceparent (W3C/OTel) → x-trace-id → x-request-id → x-correlation-id → trace-id\n */\nexport const DEFAULT_TRACE_HEADERS = [\n 'traceparent',\n 'x-trace-id',\n 'x-request-id',\n 'x-correlation-id',\n 'trace-id',\n];\n\n/**\n * Create trace ID middleware for Express/NestJS\n */\nexport function createTraceMiddleware(config: TraceIdConfig) {\n const defaultExtractor = {\n header: DEFAULT_TRACE_HEADERS,\n query: ['traceId', 'trace_id'],\n };\n const resolvedConfig: TraceIdConfig = {\n ...config,\n extractor: config?.extractor ? { ...defaultExtractor, ...config.extractor } : defaultExtractor,\n };\n\n _setActiveContextKey(resolvedConfig.contextKey ?? TRACE_CONTEXT_KEY);\n\n return (req: unknown, res: unknown, next: () => void) => {\n let traceId: string | undefined;\n\n if (resolvedConfig.extractor) {\n traceId = extractTraceId(req, resolvedConfig.extractor);\n }\n\n if (!traceId) {\n traceId = resolvedConfig.generator ? resolvedConfig.generator() : generateTraceId();\n }\n\n (req as Record<string, unknown>).traceId = traceId;\n // Echo the trace ID back on the response, tolerating different response APIs:\n // Express/Node use res.setHeader(), Fastify replies use reply.header(). Guard\n // both and never let a missing/!function method (or already-sent headers)\n // crash the request — the trace ID is still propagated via async context.\n const resObj = res as {\n setHeader?: (k: string, v: string) => void;\n header?: (k: string, v: string) => void;\n headersSent?: boolean;\n };\n if (!resObj.headersSent) {\n try {\n if (typeof resObj.setHeader === 'function') {\n resObj.setHeader('X-Trace-Id', traceId);\n } else if (typeof resObj.header === 'function') {\n resObj.header('X-Trace-Id', traceId);\n }\n } catch {\n /* response not in a header-settable state — context propagation still works */\n }\n }\n\n runWithTraceId(traceId, () => next());\n };\n}\n","/**\n * Per-request trace ID resolution shared by the HTTP logger middleware and the\n * context helpers. Internal: not re-exported from the package entry points.\n */\n\nimport type { HttpRequestShape } from '../types/http-shapes';\nimport {\n DEFAULT_TRACE_HEADERS,\n extractTraceId,\n generateTraceId,\n sanitizeIncomingId,\n} from './trace.utils';\n\nexport type TraceHeaderOption = string | readonly string[];\n\n/** Minimal structural request shape; Express and Fastify requests satisfy it. */\nexport type ContextRequestLike = HttpRequestShape;\n\n/** Fastify's default `genReqId` output (`req-` + base36 counter), unique only per process. */\nconst FASTIFY_COUNTER_ID = /^req-[\\da-z]+$/;\n\nconst FALLBACK_KEY = '_logixiaFallbackId';\n\n/** Header names to read a trace ID from, defaulting to the library-wide list. */\nexport function resolveTraceHeaders(option: TraceHeaderOption | undefined): readonly string[] {\n if (option === undefined) return DEFAULT_TRACE_HEADERS;\n return typeof option === 'string' ? [option] : option;\n}\n\n/**\n * Resolve the trace ID for a request: a sanitised incoming header (honouring\n * `traceparent`), then a non-counter `request.id`, then a generated ID. Header\n * and `request.id` are recomputed per call so each caller's own header list is\n * honoured; only the generated fallback is stored on the request so every helper\n * agrees when no ID was sent.\n */\nexport function resolveRequestTraceId(req: ContextRequestLike, headers: readonly string[]): string {\n const fromHeader = extractTraceId(req, { header: [...headers] });\n if (fromHeader !== undefined) return fromHeader;\n\n const fromId = sanitizeIncomingId(req.id);\n if (fromId !== undefined && !FASTIFY_COUNTER_ID.test(fromId)) return fromId;\n\n const holder = req as Record<string, unknown>;\n const cached = holder[FALLBACK_KEY];\n if (typeof cached === 'string') return cached;\n const generated = generateTraceId();\n try {\n holder[FALLBACK_KEY] = generated;\n } catch {\n // frozen request object: each caller generates its own\n }\n return generated;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"request-trace-Dekcnenb.mjs","names":[],"sources":["../src/utils/trace.utils.ts","../src/utils/request-trace.ts"],"sourcesContent":["/**\n * Trace ID utilities for Logitron\n */\n\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\n\nimport type { TraceIdConfig, TraceIdExtractorConfig } from '../types';\n\n/** Default key used to store the trace ID in AsyncLocalStorage. */\nexport const TRACE_CONTEXT_KEY = 'traceId' as const;\n\n// ── TraceContext class ────────────────────────────────────────────────────────\n\n/**\n * Singleton that owns the AsyncLocalStorage and the active contextKey.\n *\n * Why a class instead of bare module-level variables?\n * - The contextKey is user-configurable; encapsulating it here means there is\n * exactly one place that reads and writes it.\n * - All helpers (getCurrentTraceId, runWithTraceId, etc.) delegate to this\n * instance, so the key is always in sync without hidden global state.\n * - Easier to test: you can reset the singleton between test cases.\n *\n * Usage (advanced):\n * import { TraceContext } from 'logixia';\n * TraceContext.instance.contextKey // → 'traceId' (or custom)\n * TraceContext.instance.getCurrentTraceId() // same as standalone fn\n */\nexport class TraceContext {\n private static _instance: TraceContext | null = null;\n\n readonly storage = new AsyncLocalStorage<Record<string, unknown>>();\n private _contextKey: string = TRACE_CONTEXT_KEY;\n\n private constructor() {}\n\n /** The process-wide singleton. */\n static get instance(): TraceContext {\n if (!TraceContext._instance) {\n TraceContext._instance = new TraceContext();\n }\n return TraceContext._instance;\n }\n\n /** @internal Reset the singleton (useful in tests). */\n static _reset(): void {\n TraceContext._instance = null;\n }\n\n // ── Key management ──────────────────────────────────────────────────────────\n\n /** The AsyncLocalStorage key that holds the trace ID value. */\n get contextKey(): string {\n return this._contextKey;\n }\n\n /** @internal Called by TraceMiddleware when it boots to register the user's key. */\n setContextKey(key: string): void {\n this._contextKey = key;\n }\n\n // ── Core operations ─────────────────────────────────────────────────────────\n\n /** UUID v4 generator (default). */\n generate(): string {\n return randomUUID();\n }\n\n /** Read the trace ID from the current async context. */\n getCurrentTraceId(): string | undefined {\n return this.storage.getStore()?.[this._contextKey] as string | undefined;\n }\n\n /**\n * Mutate the CURRENT async context in-place.\n *\n * ⚠️ DEPRECATED — unsafe for concurrent requests.\n *\n * Uses `AsyncLocalStorage.enterWith()`, which mutates the current async\n * execution context and every Promise chain spawned from it. In a server\n * processing overlapping requests this can cause a trace ID set for one\n * request to bleed into *other* in-flight requests that share the same\n * async parent (e.g. a module-level setup function or a cached handler).\n *\n * Use {@link run} instead — it scopes the context to a callback so there\n * is no risk of cross-request leakage.\n *\n * @deprecated Use `TraceContext.instance.run(traceId, fn)` — do not call\n * `setTraceId` from request-handling code.\n */\n setTraceId(traceId: string, data?: Record<string, unknown>): void {\n const current = this.storage.getStore() ?? {};\n this.storage.enterWith({ ...current, [this._contextKey]: traceId, ...data });\n }\n\n /** Run `fn` inside a new async context that carries `traceId`. */\n run<T>(traceId: string, fn: () => T, data?: Record<string, unknown>): T {\n return this.storage.run({ [this._contextKey]: traceId, ...data }, fn);\n }\n}\n\n// ── Module-level aliases (backwards-compatible public API) ────────────────────\n\n/**\n * The shared AsyncLocalStorage instance.\n * @deprecated Prefer `TraceContext.instance.storage` for new code.\n */\nexport const traceStorage = TraceContext.instance.storage;\n\n/** Returns the key currently used to store the trace ID in AsyncLocalStorage. */\nexport function getTraceContextKey(): string {\n return TraceContext.instance.contextKey;\n}\n\n/** @internal Called by TraceMiddleware / traceMiddleware() when they boot. */\nexport function _setActiveContextKey(key: string): void {\n TraceContext.instance.setContextKey(key);\n}\n\n/** Generate a UUID v4 trace ID. */\nexport function generateTraceId(): string {\n return TraceContext.instance.generate();\n}\n\n/**\n * Get the current trace ID from async context.\n * Returns `undefined` when called outside a traced request.\n */\nexport function getCurrentTraceId(): string | undefined {\n return TraceContext.instance.getCurrentTraceId();\n}\n\n/**\n * Set trace ID in the CURRENT async context without starting a new one.\n *\n * ⚠️ DEPRECATED — unsafe for concurrent requests.\n *\n * Uses `AsyncLocalStorage.enterWith()`, which mutates the current async\n * execution context and every Promise chain spawned from it. Under load this\n * can cause a trace ID from one request to bleed into others sharing the same\n * async parent.\n *\n * Use {@link runWithTraceId} instead. Migration patterns:\n *\n * **Express / Fastify middleware — before:**\n * ```ts\n * app.use((req, _res, next) => {\n * setTraceId(req.headers['x-trace-id'] ?? generateTraceId());\n * next();\n * });\n * ```\n * **after:**\n * ```ts\n * app.use((req, _res, next) => {\n * runWithTraceId(req.headers['x-trace-id'] ?? generateTraceId(), () => next());\n * });\n * ```\n *\n * **Kafka / queue consumer — before:**\n * ```ts\n * async function handle(msg) {\n * setTraceId(msg.headers['x-trace-id']);\n * await processMessage(msg);\n * }\n * ```\n * **after:**\n * ```ts\n * async function handle(msg) {\n * await runWithTraceId(msg.headers['x-trace-id'], () => processMessage(msg));\n * }\n * ```\n *\n * **Background job — before:**\n * ```ts\n * setTraceId(generateTraceId(), { jobId: job.id });\n * await job.run();\n * ```\n * **after:**\n * ```ts\n * await runWithTraceId(generateTraceId(), () => job.run(), { jobId: job.id });\n * ```\n *\n * @deprecated Use `runWithTraceId(traceId, fn)` — do not call `setTraceId`\n * from request-handling code.\n */\nexport function setTraceId(traceId: string, data?: Record<string, unknown>): void {\n TraceContext.instance.setTraceId(traceId, data);\n}\n\n/** Run `fn` inside a new async context carrying `traceId`. */\nexport function runWithTraceId<T>(traceId: string, fn: () => T, data?: Record<string, unknown>): T {\n return TraceContext.instance.run(traceId, fn, data);\n}\n\n// ── Request extraction ────────────────────────────────────────────────────────\n\ntype HeaderValue = string | string[] | undefined;\n\n/** Shape that extractTraceId accepts (Express-compatible) */\ninterface RequestLike {\n headers?: Record<string, HeaderValue>;\n query?: Record<string, HeaderValue>;\n body?: Record<string, string | undefined>;\n params?: Record<string, string | undefined>;\n}\n\n/** Maximum accepted length for an incoming trace / correlation / request ID. */\nexport const MAX_INCOMING_ID_LENGTH = 128;\n\nconst SAFE_INCOMING_ID = /^[A-Za-z0-9._:-]{1,128}$/;\n\n/**\n * Validate an externally supplied identifier (trace ID, correlation ID, origin\n * service name, message-queue ID). Accepts only 1-128 characters from\n * `[A-Za-z0-9._:-]`; surrounding whitespace is trimmed first. Arrays use their\n * first element. Returns the cleaned value, or `undefined` when it is unusable\n * so callers can generate a fresh ID instead of passing client text through.\n */\nexport function sanitizeIncomingId(value: unknown): string | undefined {\n const first = Array.isArray(value) ? value[0] : value;\n if (typeof first !== 'string' || first.length > MAX_INCOMING_ID_LENGTH * 2) return undefined;\n const trimmed = first.trim();\n return SAFE_INCOMING_ID.test(trimmed) ? trimmed : undefined;\n}\n\n/** W3C trace-context: `version-traceId(32hex)-spanId(16hex)-flags(2hex)`. */\nconst W3C_TRACEPARENT_RE = /^[\\da-f]{2}-([\\da-f]{32})-[\\da-f]{16}-[\\da-f]{2}$/i;\n\n/**\n * Extract the 32-hex trace-id segment from a W3C `traceparent` header value.\n * Returns the parsed trace ID, or the original value unchanged when it is not a\n * well-formed traceparent (so non-W3C propagation still works).\n */\nfunction parseTraceparent(value: string): string {\n const m = W3C_TRACEPARENT_RE.exec(value);\n return m ? m[1]! : value;\n}\n\n/** Extract trace ID from request using configuration (header → query → body → params). */\nexport function extractTraceId(\n request: unknown,\n config: TraceIdExtractorConfig\n): string | undefined {\n const req = request as RequestLike;\n\n if (config.header) {\n const headers = Array.isArray(config.header) ? config.header : [config.header];\n for (const header of headers) {\n const lower = header.toLowerCase();\n const value = sanitizeIncomingId(req.headers?.[lower]);\n if (value) return lower === 'traceparent' ? parseTraceparent(value) : value;\n }\n }\n\n if (config.query) {\n const queries = Array.isArray(config.query) ? config.query : [config.query];\n for (const query of queries) {\n const value = sanitizeIncomingId(req.query?.[query]);\n if (value) return value;\n }\n }\n\n if (config.body) {\n const bodyFields = Array.isArray(config.body) ? config.body : [config.body];\n for (const field of bodyFields) {\n const value = sanitizeIncomingId(req.body?.[field]);\n if (value) return value;\n }\n }\n\n if (config.params) {\n const paramFields = Array.isArray(config.params) ? config.params : [config.params];\n for (const param of paramFields) {\n const value = sanitizeIncomingId(req.params?.[param]);\n if (value) return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Default headers checked for incoming trace ID propagation, in priority order:\n * traceparent (W3C/OTel) → x-trace-id → x-request-id → x-correlation-id → trace-id\n */\nexport const DEFAULT_TRACE_HEADERS = [\n 'traceparent',\n 'x-trace-id',\n 'x-request-id',\n 'x-correlation-id',\n 'trace-id',\n];\n\n/**\n * Create trace ID middleware for Express/NestJS\n */\nexport function createTraceMiddleware(config: TraceIdConfig) {\n const defaultExtractor = {\n header: DEFAULT_TRACE_HEADERS,\n query: ['traceId', 'trace_id'],\n };\n const resolvedConfig: TraceIdConfig = {\n ...config,\n extractor: config?.extractor ? { ...defaultExtractor, ...config.extractor } : defaultExtractor,\n };\n\n _setActiveContextKey(resolvedConfig.contextKey ?? TRACE_CONTEXT_KEY);\n\n return (req: unknown, res: unknown, next: () => void) => {\n let traceId: string | undefined;\n\n if (resolvedConfig.extractor) {\n traceId = extractTraceId(req, resolvedConfig.extractor);\n }\n\n if (!traceId) {\n traceId = resolvedConfig.generator ? resolvedConfig.generator() : generateTraceId();\n }\n\n (req as Record<string, unknown>).traceId = traceId;\n // Echo the trace ID back on the response, tolerating different response APIs:\n // Express/Node use res.setHeader(), Fastify replies use reply.header(). Guard\n // both and never let a missing/!function method (or already-sent headers)\n // crash the request — the trace ID is still propagated via async context.\n const resObj = res as {\n setHeader?: (k: string, v: string) => void;\n header?: (k: string, v: string) => void;\n headersSent?: boolean;\n };\n if (!resObj.headersSent) {\n try {\n if (typeof resObj.setHeader === 'function') {\n resObj.setHeader('X-Trace-Id', traceId);\n } else if (typeof resObj.header === 'function') {\n resObj.header('X-Trace-Id', traceId);\n }\n } catch {\n /* response not in a header-settable state — context propagation still works */\n }\n }\n\n runWithTraceId(traceId, () => next());\n };\n}\n","/**\n * Per-request trace ID resolution shared by the HTTP logger middleware and the\n * context helpers. Internal: not re-exported from the package entry points.\n */\n\nimport type { HttpRequestShape } from '../types/http-shapes';\nimport {\n DEFAULT_TRACE_HEADERS,\n extractTraceId,\n generateTraceId,\n sanitizeIncomingId,\n} from './trace.utils';\n\nexport type TraceHeaderOption = string | readonly string[];\n\n/** Minimal structural request shape; Express and Fastify requests satisfy it. */\nexport type ContextRequestLike = HttpRequestShape;\n\n/** Fastify's default `genReqId` output (`req-` + base36 counter), unique only per process. */\nconst FASTIFY_COUNTER_ID = /^req-[\\da-z]+$/;\n\nconst FALLBACK_KEY = '_logixiaFallbackId';\n\n/** Header names to read a trace ID from, defaulting to the library-wide list. */\nexport function resolveTraceHeaders(option: TraceHeaderOption | undefined): readonly string[] {\n if (option === undefined) return DEFAULT_TRACE_HEADERS;\n return typeof option === 'string' ? [option] : option;\n}\n\n/**\n * Resolve the trace ID for a request: a sanitised incoming header (honouring\n * `traceparent`), then a non-counter `request.id`, then a generated ID. Header\n * and `request.id` are recomputed per call so each caller's own header list is\n * honoured; only the generated fallback is stored on the request so every helper\n * agrees when no ID was sent.\n */\nexport function resolveRequestTraceId(req: ContextRequestLike, headers: readonly string[]): string {\n const fromHeader = extractTraceId(req, { header: [...headers] });\n if (fromHeader !== undefined) return fromHeader;\n\n const fromId = sanitizeIncomingId(req.id);\n if (fromId !== undefined && !FASTIFY_COUNTER_ID.test(fromId)) return fromId;\n\n const holder = req as Record<string, unknown>;\n const cached = holder[FALLBACK_KEY];\n if (typeof cached === 'string') return cached;\n const generated = generateTraceId();\n try {\n holder[FALLBACK_KEY] = generated;\n } catch {\n // frozen request object: each caller generates its own\n }\n return generated;\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const require_sensitive_names = require("./sensitive-names-CHMowujD.js");
1
+ const require_sensitive_names = require("./sensitive-names-CNgHaqv9.js");
2
2
  // src/utils/safe-stringify.ts
3
3
  /**
4
4
  * logixia — robust JSON serialization for log payloads.
@@ -162,4 +162,4 @@ Object.defineProperty(exports, "stringifyForLog", {
162
162
  }
163
163
  });
164
164
 
165
- //# sourceMappingURL=safe-stringify-CN7icp8S.js.map
165
+ //# sourceMappingURL=safe-stringify-CJisLyZ3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-stringify-CN7icp8S.js","names":[],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nimport { assignOwn } from './own-property';\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n assignOwn(obj, k, transform(rec[k]));\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n assignOwn(obj, k, walk(rec[k], [...path, k]));\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const UNRESOLVED = Symbol('unresolved');\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n if (node === null || typeof node !== 'object') return UNRESOLVED;\n if (!Object.prototype.hasOwnProperty.call(node, s)) return UNRESOLVED;\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n const target = resolve((child as { $ref: string }).$ref);\n if (target === UNRESOLVED) walk(child);\n else assignOwn(rec, k, target);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"safe-stringify-CJisLyZ3.js","names":[],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nimport { assignOwn } from './own-property';\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n assignOwn(obj, k, transform(rec[k]));\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n assignOwn(obj, k, walk(rec[k], [...path, k]));\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const UNRESOLVED = Symbol('unresolved');\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n if (node === null || typeof node !== 'object') return UNRESOLVED;\n if (!Object.prototype.hasOwnProperty.call(node, s)) return UNRESOLVED;\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n const target = resolve((child as { $ref: string }).$ref);\n if (target === UNRESOLVED) walk(child);\n else assignOwn(rec, k, target);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { l as assignOwn } from "./sensitive-names-o__1PUUR.mjs";
1
+ import { u as assignOwn } from "./sensitive-names-wv27qBQC.mjs";
2
2
  // src/utils/safe-stringify.ts
3
3
  /**
4
4
  * logixia — robust JSON serialization for log payloads.
@@ -139,4 +139,4 @@ function stringifyForLog(value) {
139
139
  }
140
140
  export { stringifyForLog as i, retrocycle as n, safeStringify as r, decycleValue as t };
141
141
 
142
- //# sourceMappingURL=safe-stringify--7gbe95n.mjs.map
142
+ //# sourceMappingURL=safe-stringify-pZOnzGRJ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"safe-stringify--7gbe95n.mjs","names":[],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nimport { assignOwn } from './own-property';\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n assignOwn(obj, k, transform(rec[k]));\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n assignOwn(obj, k, walk(rec[k], [...path, k]));\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const UNRESOLVED = Symbol('unresolved');\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n if (node === null || typeof node !== 'object') return UNRESOLVED;\n if (!Object.prototype.hasOwnProperty.call(node, s)) return UNRESOLVED;\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n const target = resolve((child as { $ref: string }).$ref);\n if (target === UNRESOLVED) walk(child);\n else assignOwn(rec, k, target);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"safe-stringify-pZOnzGRJ.mjs","names":[],"sources":["../src/utils/safe-stringify.ts"],"sourcesContent":["/**\n * logixia — robust JSON serialization for log payloads.\n *\n * Modern Winston/Pino already neutralize circular refs to `[Circular]` (via\n * safe-stable-stringify / fast-safe-stringify), so merely \"surviving cycles\" is\n * not a differentiator. This goes one notch further:\n *\n * - **BigInt** → serialized (as a string by default; JSON.stringify throws on\n * BigInt, which silently breaks logging of e.g. DB bigint ids).\n * - **Deterministic key order** (optional) so identical objects hash/diff equal.\n * - **True decycle** (optional) — replace repeated references with JSONPath\n * `$ref` pointers that round-trip back to the original object graph, instead\n * of the lossy `[Circular]` tag. Useful when you need to reconstruct shared\n * structure downstream.\n *\n * @example\n * ```ts\n * safeStringify({ id: 10n, self: obj }); // → BigInt + cycle safe\n * safeStringify(graph, { decycle: true }); // → round-trippable $ref pointers\n * const back = retrocycle(JSON.parse(json)); // → reconstruct shared refs\n * ```\n */\n\nimport { assignOwn } from './own-property';\n\nexport interface SafeStringifyOptions {\n /** Indentation passed to JSON.stringify (number of spaces or a string). */\n indent?: number | string;\n /** Sort object keys for deterministic output. Default: false. */\n deterministic?: boolean;\n /**\n * Use round-trippable `$ref` JSONPath pointers for repeated references instead\n * of the lossy \"[Circular]\" tag. Default: false.\n */\n decycle?: boolean;\n /** How to render BigInt: 'string' (default) or 'number' (may lose precision). */\n bigint?: 'string' | 'number';\n}\n\n/** Build a JSONPath like `$[\"a\"][0][\"b\"]` for a decycle pointer. */\nfunction jsonPath(parts: Array<string | number>): string {\n let path = '$';\n for (const p of parts) {\n path += typeof p === 'number' ? `[${p}]` : `[${JSON.stringify(p)}]`;\n }\n return path;\n}\n\n/**\n * Serialize any value to JSON without throwing on circular references or BigInt.\n * Circular refs become `\"[Circular]\"` (or `{ $ref }` pointers when `decycle`).\n */\nexport function safeStringify(value: unknown, options: SafeStringifyOptions = {}): string {\n const { indent, deterministic = false, decycle = false, bigint = 'string' } = options;\n\n if (decycle) {\n return JSON.stringify(decycleValue(value, bigint), undefined, indent);\n }\n\n const seen = new WeakSet<object>();\n\n const transform = (val: unknown): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (typeof val === 'function') return `[Function: ${val.name || 'anonymous'}]`;\n if (typeof val === 'symbol') return val.toString();\n if (val === null || typeof val !== 'object') return val;\n\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n\n let out: unknown;\n const toJSON = (val as { toJSON?: unknown }).toJSON;\n if (Array.isArray(val)) {\n out = val.map((item) => transform(item));\n } else if (typeof toJSON === 'function') {\n // Dates, URLs, Buffers and classes with their own toJSON print the way\n // JSON.stringify would; a toJSON that returns `this` hits the cycle check.\n out = transform(toJSON.call(val));\n } else {\n const rec = val as Record<string, unknown>;\n const keys = deterministic ? Object.keys(rec).sort() : Object.keys(rec);\n const obj: Record<string, unknown> = {};\n for (const k of keys) {\n assignOwn(obj, k, transform(rec[k]));\n }\n out = obj;\n }\n // Allow the same object to appear in sibling branches (not a true cycle):\n // remove from `seen` after we finish its subtree.\n seen.delete(val);\n return out;\n };\n\n return JSON.stringify(transform(value), undefined, indent);\n}\n\n/**\n * Replace repeated object references with round-trippable `{ \"$ref\": \"$...\" }`\n * JSONPath pointers (the classic Crockford decycle). Pair with {@link retrocycle}\n * to reconstruct the original shared/circular graph.\n */\nexport function decycleValue(value: unknown, bigint: 'string' | 'number' = 'string'): unknown {\n const paths = new WeakMap<object, string>();\n\n const walk = (val: unknown, path: Array<string | number>): unknown => {\n if (typeof val === 'bigint') return bigint === 'number' ? Number(val) : val.toString();\n if (val === null || typeof val !== 'object') return val;\n if (val instanceof Date) return val.toISOString();\n\n const existing = paths.get(val);\n if (existing !== undefined) return { $ref: existing };\n paths.set(val, jsonPath(path));\n\n if (Array.isArray(val)) {\n return val.map((item, i) => walk(item, [...path, i]));\n }\n const rec = val as Record<string, unknown>;\n const obj: Record<string, unknown> = {};\n for (const k of Object.keys(rec)) {\n assignOwn(obj, k, walk(rec[k], [...path, k]));\n }\n return obj;\n };\n\n return walk(value, []);\n}\n\n/**\n * Inverse of {@link decycleValue}: resolve `{ \"$ref\": \"$...\" }` pointers back\n * into the live object graph (mutates and returns the parsed input).\n */\nexport function retrocycle<T>(root: T): T {\n const refRe = /^\\$(?:\\[(?:\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\])*$/;\n\n const UNRESOLVED = Symbol('unresolved');\n const resolve = (path: string): unknown => {\n // Parse the JSONPath segments back out.\n const segs: Array<string | number> = [];\n const partRe = /\\[(\\d+|\"(?:[^\"\\\\]|\\\\.)*\")\\]/g;\n let m: RegExpExecArray | null;\n while ((m = partRe.exec(path)) !== null) {\n const raw = m[1]!;\n segs.push(raw.startsWith('\"') ? (JSON.parse(raw) as string) : Number(raw));\n }\n let node: unknown = root;\n for (const s of segs) {\n if (node === null || typeof node !== 'object') return UNRESOLVED;\n if (!Object.prototype.hasOwnProperty.call(node, s)) return UNRESOLVED;\n node = (node as Record<string | number, unknown>)[s];\n }\n return node;\n };\n\n const walk = (val: unknown): void => {\n if (val === null || typeof val !== 'object') return;\n const rec = val as Record<string, unknown>;\n for (const k of Object.keys(rec)) {\n const child = rec[k];\n if (\n child !== null &&\n typeof child === 'object' &&\n typeof (child as { $ref?: unknown }).$ref === 'string' &&\n refRe.test((child as { $ref: string }).$ref)\n ) {\n const target = resolve((child as { $ref: string }).$ref);\n if (target === UNRESOLVED) walk(child);\n else assignOwn(rec, k, target);\n } else {\n walk(child);\n }\n }\n };\n\n walk(root);\n return root;\n}\n\n/**\n * `JSON.stringify` for log output. Takes the plain fast path first and only\n * falls back to {@link safeStringify} when that throws (a cycle, a BigInt, a\n * throwing `toJSON`), so a bad payload costs nothing until it shows up.\n * Never throws: if even the safe walk fails, the value is replaced by a marker.\n */\nexport function stringifyForLog(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch {\n try {\n return safeStringify(value);\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error);\n return JSON.stringify(`[Unserializable: ${reason}]`);\n }\n }\n}\n"],"mappings":"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"}
@@ -728,9 +728,6 @@ declare class CorrelationEngine {
728
728
  private convertToCorrelatedLogs;
729
729
  private generateSummary;
730
730
  }
731
- /**
732
- * NLP-enhanced search engine
733
- */
734
731
  declare class NLPSearchEngine extends BasicSearchEngine {
735
732
  private intentPatterns;
736
733
  private entityPatterns;
@@ -738,11 +735,11 @@ declare class NLPSearchEngine extends BasicSearchEngine {
738
735
  /**
739
736
  * Enhanced natural language query parsing
740
737
  */
741
- parseNaturalLanguageQuery(query: string): Promise<ParsedNLQuery>;
738
+ parseNaturalLanguageQuery(rawQuery: string): Promise<ParsedNLQuery>;
742
739
  /**
743
740
  * Enhanced natural language search
744
741
  */
745
- naturalLanguageSearch(query: string): Promise<SearchResult[]>;
742
+ naturalLanguageSearch(rawQuery: string): Promise<SearchResult[]>;
746
743
  private initializePatterns;
747
744
  private detectIntent;
748
745
  private extractEntities;
@@ -795,4 +792,4 @@ declare class PatternRecognitionEngine {
795
792
  private doesLogMatchPattern;
796
793
  }
797
794
  export { SearchStats as A, SearchFilters as C, SearchPreset as D, SearchOptions as E, SuggestionType as F, TimeRange as I, TimelineEvent as L, SemanticIndex as M, SimilarLog as N, SearchQuery as O, SortField as P, RelativeTime as S, SearchMatch as T, ParsedNLQuery as _, ILogSearchEngine as a, RelatedLog as b, SearchManager as c, CorrelatedLogs as d, EntityType as f, LogPattern as g, LogCorrelationSummary as h, BasicSearchEngine as i, SearchSuggestion as j, SearchResult as k, SearchManagerConfig as l, LogCluster as m, NLPSearchEngine as n, BasicLogIndexer as o, ExportOptions as p, CorrelationEngine as r, ILogIndexer as s, PatternRecognitionEngine as t, AnomalyDetection as u, QueryEntity as v, SearchHighlight as w, RelationshipType as x, QueryIntent as y };
798
- //# sourceMappingURL=search-DPwTKPve.d.ts.map
795
+ //# sourceMappingURL=search-B4eEzrhM.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"search-DPwTKPve.d.ts","names":[],"sources":["../src/search/types/search.types.ts","../src/search/search-manager.ts","../src/search/core/log-indexer.interface.ts","../src/search/core/basic-log-indexer.ts","../src/search/core/search-engine.interface.ts","../src/search/core/basic-search-engine.ts","../src/search/engines/correlation-engine.ts","../src/search/engines/nlp-search-engine.ts","../src/search/engines/pattern-recognition-engine.ts"],"mappings":";;;;UASiB;EACf;EACA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;EACA;EACA;EACA,eAAe;;;;;UAMA;EACf,OAAO;EACP,MAAM;EACN,WAAW;;;;;UAMI;EACf;EACA;;;;;UAMe;EACf,KAAK;EACL;EACA,aAAa;EACb,UAAU;EACV,UAAU;EACV,cAAc;;;;;UAMC;EACf;EACA;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;;;;;UAMe;EACf,KAAK;EACL,cAAc;EACd;;;;;KAMU;;;;UAWK;EACf;EACA;EACA,MAAM;EACN,UAAU;EACV,UAAU;;;;;UAMK;EACf,WAAW;EACX,KAAK;EACL;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;EACA;EACA,eAAe;;;;;UAMA;EACf,KAAK;EACL;EACA;EACA;;;;;UAMe;EACf;EACA,UAAU;EACV,UAAU;EACV,WAAW;EACX;;;;;UAMe;EACf;EACA;EACA,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;;;;;KAMU;;;;UAKK;EACf;EACA,MAAM;EACN;EACA;EACA,WAAW;;;;;KAMD;;;;UAMK;EACf;EACA;EACA;EACA;EACA;;;;;UAMe;EACf;EACA;EACA,aAAa;EACb,aAAa;EACb,WAAW;;;;;UAMI;EACf;EACA;EACA,MAAM;EACN;EACA;EACA;;;;;UAMe;EACf;EACA;EACA,QAAQ;EACR,UAAU;EACV;EACA,UAAU;EACV;EACA;;;;;UAMe;EACf,KAAK;EACL;EACA;EACA;EACA;;;;;UAMe;EACf;;EAEA;EACA,QAAQ;EACR,UAAU;EACV,SAAS;EACT,YAAY;EACZ;;;;;KAMU;;;;UAaK;EACf,MAAM;EACN;EACA;EACA;;;;;KAMU;;;;UAMK;EACf;EACA;EACA;EACA;EACA,SAAS;EACT,SAAS;EACT,WAAW;EACX,WAAW;EACX;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;;;;;UCtRe;EACf;EACA;EACA;EACA;EACA;;;;;cAMW;UACH;UACA;UACA;UACA;UACA;EAEI,YAAA,SAAS;;;;EA8Bf,UAAU,MAAM,aAAa;;;;EAa7B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"}
1
+ {"version":3,"file":"search-B4eEzrhM.d.ts","names":[],"sources":["../src/search/types/search.types.ts","../src/search/search-manager.ts","../src/search/core/log-indexer.interface.ts","../src/search/core/basic-log-indexer.ts","../src/search/core/search-engine.interface.ts","../src/search/core/basic-search-engine.ts","../src/search/engines/correlation-engine.ts","../src/search/engines/nlp-search-engine.ts","../src/search/engines/pattern-recognition-engine.ts"],"mappings":";;;;UASiB;EACf;EACA;EACA;EACA,YAAY;EACZ;EACA;EACA;EACA;EACA;EACA;EACA,eAAe;;;;;UAMA;EACf,OAAO;EACP,MAAM;EACN,WAAW;;;;;UAMI;EACf;EACA;;;;;UAMe;EACf,KAAK;EACL;EACA,aAAa;EACb,UAAU;EACV,UAAU;EACV,cAAc;;;;;UAMC;EACf;EACA;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;;;;;UAMe;EACf,KAAK;EACL,cAAc;EACd;;;;;KAMU;;;;UAWK;EACf;EACA;EACA,MAAM;EACN,UAAU;EACV,UAAU;;;;;UAMK;EACf,WAAW;EACX,KAAK;EACL;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;EACA;EACA,eAAe;;;;;UAMA;EACf,KAAK;EACL;EACA;EACA;;;;;UAMe;EACf;EACA,UAAU;EACV,UAAU;EACV,WAAW;EACX;;;;;UAMe;EACf;EACA;EACA,SAAS;EACT;EACA;EACA;EACA;EACA;EACA;EACA;;;;;KAMU;;;;UAKK;EACf;EACA,MAAM;EACN;EACA;EACA,WAAW;;;;;KAMD;;;;UAMK;EACf;EACA;EACA;EACA;EACA;;;;;UAMe;EACf;EACA;EACA,aAAa;EACb,aAAa;EACb,WAAW;;;;;UAMI;EACf;EACA;EACA,MAAM;EACN;EACA;EACA;;;;;UAMe;EACf;EACA;EACA,QAAQ;EACR,UAAU;EACV;EACA,UAAU;EACV;EACA;;;;;UAMe;EACf,KAAK;EACL;EACA;EACA;EACA;;;;;UAMe;EACf;;EAEA;EACA,QAAQ;EACR,UAAU;EACV,SAAS;EACT,YAAY;EACZ;;;;;KAMU;;;;UAaK;EACf,MAAM;EACN;EACA;EACA;;;;;KAMU;;;;UAMK;EACf;EACA;EACA;EACA;EACA,SAAS;EACT,SAAS;EACT,WAAW;EACX,WAAW;EACX;EACA;;;;;UAMe;EACf;EACA;EACA;EACA;;;;;UCtRe;EACf;EACA;EACA;EACA;EACA;;;;;cAMW;UACH;UACA;UACA;UACA;UACA;EAEI,YAAA,SAAS;;;;EA8Bf,UAAU,MAAM,aAAa;;;;EAa7B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"}
@@ -1,32 +1,25 @@
1
- const require_coerce_utils = require("./coerce.utils-C1C5sIX0.js");
2
- // src/utils/csv.utils.ts
3
- const CSV_FORMULA_PREFIX = /^[=+\-@\t\r]/;
4
- /**
5
- * Render one CSV field. String values that a spreadsheet would treat as a
6
- * formula (leading `=`, `+`, `-`, `@`, tab or CR) are prefixed with `'`.
7
- * Objects are JSON-encoded. Fields containing a comma, quote, CR or LF are quoted;
8
- * `alwaysQuote` quotes every field. `null` / `undefined` render as empty.
9
- */
10
- function csvField(value, alwaysQuote = false) {
11
- if (value === void 0 || value === null) return alwaysQuote ? "\"\"" : "";
12
- let str;
13
- if (typeof value === "string") str = CSV_FORMULA_PREFIX.test(value) ? `'${value}` : value;
14
- else if (typeof value === "object") str = JSON.stringify(value);
15
- else str = String(value);
16
- if (alwaysQuote || /[",\r\n]/.test(str)) return `"${str.replace(/"/g, "\"\"")}"`;
17
- return str;
18
- }
1
+ const require_csv_utils = require("./csv.utils-CbVHY1pd.js");
19
2
  // src/search/core/basic-log-indexer.ts
20
3
  /**
21
4
  * Basic log indexer implementation
22
5
  */
23
6
  var BasicLogIndexer = class {
7
+ options;
8
+ index = /* @__PURE__ */ new Map();
9
+ fieldIndices = /* @__PURE__ */ new Map();
10
+ semanticIndex;
11
+ lastOptimized;
12
+ /**
13
+ * Running estimate of the serialized index size in bytes, maintained
14
+ * incrementally. The previous implementation JSON.stringify'd EVERY log on
15
+ * each getIndexStats() call — O(n) per call, which for the default 1M-entry
16
+ * cap means stringifying a million objects and blocking the event loop.
17
+ * We keep a per-log byte estimate so the lookup is O(1).
18
+ */
19
+ indexSizeBytes = 0;
20
+ logSizeById = /* @__PURE__ */ new Map();
24
21
  constructor(options) {
25
22
  this.options = options;
26
- this.index = /* @__PURE__ */ new Map();
27
- this.fieldIndices = /* @__PURE__ */ new Map();
28
- this.indexSizeBytes = 0;
29
- this.logSizeById = /* @__PURE__ */ new Map();
30
23
  this.options = {
31
24
  maxIndexSize: 1e6,
32
25
  autoOptimize: true,
@@ -283,12 +276,13 @@ function extractUserId(query) {
283
276
  * Basic search engine implementation
284
277
  */
285
278
  var BasicSearchEngine = class {
279
+ options;
280
+ logs = [];
281
+ presets = /* @__PURE__ */ new Map();
282
+ searchHistory = [];
283
+ suggestionCache = /* @__PURE__ */ new Map();
286
284
  constructor(options) {
287
285
  this.options = options;
288
- this.logs = [];
289
- this.presets = /* @__PURE__ */ new Map();
290
- this.searchHistory = [];
291
- this.suggestionCache = /* @__PURE__ */ new Map();
292
286
  this.options = {
293
287
  maxHistorySize: 1e3,
294
288
  cacheSize: 100,
@@ -602,7 +596,7 @@ var BasicSearchEngine = class {
602
596
  return text;
603
597
  }
604
598
  getSearchableText(log) {
605
- const payloadText = log.payload ? require_coerce_utils.safeToString(log.payload) : "";
599
+ const payloadText = log.payload ? require_csv_utils.safeToString(log.payload) : "";
606
600
  return [
607
601
  log.message,
608
602
  log.level,
@@ -864,6 +858,7 @@ function matchesAny(value, allowed) {
864
858
  * Correlation engine for log analysis
865
859
  */
866
860
  var CorrelationEngine = class {
861
+ options;
867
862
  constructor(options) {
868
863
  this.options = options;
869
864
  this.options = {
@@ -1132,7 +1127,13 @@ var CorrelationEngine = class {
1132
1127
  /**
1133
1128
  * NLP-enhanced search engine
1134
1129
  */
1130
+ const MAX_QUERY_LENGTH = 2e3;
1131
+ function capQuery(query) {
1132
+ return query.length > MAX_QUERY_LENGTH ? query.slice(0, MAX_QUERY_LENGTH) : query;
1133
+ }
1135
1134
  var NLPSearchEngine = class extends BasicSearchEngine {
1135
+ intentPatterns;
1136
+ entityPatterns;
1136
1137
  constructor(options) {
1137
1138
  super(options);
1138
1139
  this.initializePatterns();
@@ -1140,7 +1141,8 @@ var NLPSearchEngine = class extends BasicSearchEngine {
1140
1141
  /**
1141
1142
  * Enhanced natural language query parsing
1142
1143
  */
1143
- async parseNaturalLanguageQuery(query) {
1144
+ async parseNaturalLanguageQuery(rawQuery) {
1145
+ const query = capQuery(rawQuery);
1144
1146
  const entities = [];
1145
1147
  const filters = {};
1146
1148
  const intent = this.detectIntent(query);
@@ -1162,7 +1164,8 @@ var NLPSearchEngine = class extends BasicSearchEngine {
1162
1164
  /**
1163
1165
  * Enhanced natural language search
1164
1166
  */
1165
- async naturalLanguageSearch(query) {
1167
+ async naturalLanguageSearch(rawQuery) {
1168
+ const query = capQuery(rawQuery);
1166
1169
  const parsed = await this.parseNaturalLanguageQuery(query);
1167
1170
  const options = this.getOptionsForIntent(parsed.intent);
1168
1171
  const cleanQuery = this.extractCleanQuery(query, parsed.entities);
@@ -1218,7 +1221,7 @@ var NLPSearchEngine = class extends BasicSearchEngine {
1218
1221
  ["service", /(?:from|in)\s+(?:the\s+)?(\w+)\s+(?:service|app|application)/i],
1219
1222
  ["trace_id", /trace\s+(?:id\s+)?['"]?([\w-]+)['"]?/i],
1220
1223
  ["time", /(?:last|past|previous)\s+(\d+)\s+(second|minute|hour|day|week)s?/i],
1221
- ["error_type", /(\w+Error|\w+Exception)/i]
1224
+ ["error_type", /\b(\w{0,64}(?:Error|Exception))\b/i]
1222
1225
  ]);
1223
1226
  }
1224
1227
  detectIntent(query) {
@@ -1427,10 +1430,11 @@ function hasStackFrame(message) {
1427
1430
  * Pattern recognition engine for log analysis
1428
1431
  */
1429
1432
  var PatternRecognitionEngine = class {
1433
+ options;
1434
+ patterns = /* @__PURE__ */ new Map();
1435
+ patternFrequencies = /* @__PURE__ */ new Map();
1430
1436
  constructor(options) {
1431
1437
  this.options = options;
1432
- this.patterns = /* @__PURE__ */ new Map();
1433
- this.patternFrequencies = /* @__PURE__ */ new Map();
1434
1438
  this.options = {
1435
1439
  minFrequency: 3,
1436
1440
  maxPatterns: 1e3,
@@ -1614,6 +1618,11 @@ var PatternRecognitionEngine = class {
1614
1618
  * Main search manager class
1615
1619
  */
1616
1620
  var SearchManager = class {
1621
+ searchEngine;
1622
+ indexer;
1623
+ patternEngine;
1624
+ correlationEngine;
1625
+ config;
1617
1626
  constructor(config) {
1618
1627
  this.config = {
1619
1628
  enableNLP: true,
@@ -1807,10 +1816,10 @@ var SearchManager = class {
1807
1816
  "appName",
1808
1817
  "message"
1809
1818
  ];
1810
- return [fields.map((f) => csvField(f)).join(","), ...logs.map((log) => {
1819
+ return [fields.map((f) => require_csv_utils.csvField(f)).join(","), ...logs.map((log) => {
1811
1820
  return fields.map((field) => {
1812
1821
  const value = log[field];
1813
- return csvField(value);
1822
+ return require_csv_utils.csvField(value);
1814
1823
  }).join(",");
1815
1824
  })].join("\n");
1816
1825
  }
@@ -1878,4 +1887,4 @@ Object.defineProperty(exports, "SearchManager", {
1878
1887
  }
1879
1888
  });
1880
1889
 
1881
- //# sourceMappingURL=search-CRjhHxe9.js.map
1890
+ //# sourceMappingURL=search-CJw_xoQl.js.map