evlog 2.19.1 → 2.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +30 -1
  2. package/dist/adapters/axiom.d.mts +1 -1
  3. package/dist/adapters/axiom.mjs +2 -2
  4. package/dist/adapters/better-stack.d.mts +1 -1
  5. package/dist/adapters/better-stack.mjs +2 -2
  6. package/dist/adapters/datadog.d.mts +1 -1
  7. package/dist/adapters/datadog.mjs +2 -2
  8. package/dist/adapters/fs.d.mts +1 -1
  9. package/dist/adapters/fs.mjs +1 -1
  10. package/dist/adapters/hyperdx.d.mts +1 -1
  11. package/dist/adapters/hyperdx.mjs +1 -1
  12. package/dist/adapters/memory.d.mts +1 -1
  13. package/dist/adapters/memory.mjs +1 -1
  14. package/dist/adapters/otlp.d.mts +1 -1
  15. package/dist/adapters/otlp.mjs +2 -2
  16. package/dist/adapters/posthog.d.mts +1 -1
  17. package/dist/adapters/posthog.mjs +2 -2
  18. package/dist/adapters/sentry.d.mts +1 -1
  19. package/dist/adapters/sentry.mjs +2 -2
  20. package/dist/ai/index.d.mts +27 -10
  21. package/dist/ai/index.d.mts.map +1 -1
  22. package/dist/ai/index.mjs +80 -15
  23. package/dist/ai/index.mjs.map +1 -1
  24. package/dist/asyncStorageScope-DnF7Xk8l.mjs +81 -0
  25. package/dist/asyncStorageScope-DnF7Xk8l.mjs.map +1 -0
  26. package/dist/{audit-BQt8yAHo.mjs → audit-BXCYMjcC.mjs} +31 -93
  27. package/dist/audit-BXCYMjcC.mjs.map +1 -0
  28. package/dist/{audit-D7v6JHj0.d.mts → audit-BZrUvjfW.d.mts} +71 -53
  29. package/dist/audit-BZrUvjfW.d.mts.map +1 -0
  30. package/dist/audit-action.d.mts +2 -0
  31. package/dist/audit-action.mjs +74 -0
  32. package/dist/audit-action.mjs.map +1 -0
  33. package/dist/audit.d.mts +2 -0
  34. package/dist/audit.mjs +3 -0
  35. package/dist/better-auth/index.d.mts +1 -1
  36. package/dist/browser.d.mts +1 -1
  37. package/dist/{index-EvnrXvQM.d.mts → catalog-1cQnNxR2.d.mts} +4 -3
  38. package/dist/catalog-1cQnNxR2.d.mts.map +1 -0
  39. package/dist/catalog.d.mts +2 -0
  40. package/dist/catalog.mjs +205 -0
  41. package/dist/catalog.mjs.map +1 -0
  42. package/dist/{define-DTQpu4f6.d.mts → define-Ct2QyrE9.d.mts} +3 -3
  43. package/dist/{define-DTQpu4f6.d.mts.map → define-Ct2QyrE9.d.mts.map} +1 -1
  44. package/dist/{drain-fDb-eNwz.mjs → drain-Dl2ZJKRA.mjs} +3 -3
  45. package/dist/{drain-fDb-eNwz.mjs.map → drain-Dl2ZJKRA.mjs.map} +1 -1
  46. package/dist/elysia/index.d.mts +8 -7
  47. package/dist/elysia/index.d.mts.map +1 -1
  48. package/dist/elysia/index.mjs +11 -8
  49. package/dist/elysia/index.mjs.map +1 -1
  50. package/dist/{enrich-error-stack-next.node-Dgm_rCf5.mjs → enrich-error-stack-next.node-KB0Oap7R.mjs} +1 -1
  51. package/dist/{enrich-error-stack-next.node-Dgm_rCf5.mjs.map → enrich-error-stack-next.node-KB0Oap7R.mjs.map} +1 -1
  52. package/dist/{enricher-CBRmQw6e.d.mts → enricher-BOzt2FCi.d.mts} +2 -2
  53. package/dist/{enricher-CBRmQw6e.d.mts.map → enricher-BOzt2FCi.d.mts.map} +1 -1
  54. package/dist/enrichers.d.mts +2 -2
  55. package/dist/{error-CpghjrkY.d.mts → error-BRymuv8U.d.mts} +2 -2
  56. package/dist/{error-CpghjrkY.d.mts.map → error-BRymuv8U.d.mts.map} +1 -1
  57. package/dist/error.d.mts +1 -1
  58. package/dist/{errors-BLU4Tfpe.d.mts → errors-C7qA6CAi.d.mts} +2 -2
  59. package/dist/{errors-BLU4Tfpe.d.mts.map → errors-C7qA6CAi.d.mts.map} +1 -1
  60. package/dist/eve/index.d.mts +72 -0
  61. package/dist/eve/index.d.mts.map +1 -0
  62. package/dist/eve/index.mjs +593 -0
  63. package/dist/eve/index.mjs.map +1 -0
  64. package/dist/express/index.d.mts +4 -4
  65. package/dist/express/index.d.mts.map +1 -1
  66. package/dist/express/index.mjs +3 -3
  67. package/dist/express/index.mjs.map +1 -1
  68. package/dist/fastify/index.d.mts +4 -4
  69. package/dist/fastify/index.d.mts.map +1 -1
  70. package/dist/fastify/index.mjs +4 -2
  71. package/dist/fastify/index.mjs.map +1 -1
  72. package/dist/fork-S9gpZmF8.mjs +72 -0
  73. package/dist/fork-S9gpZmF8.mjs.map +1 -0
  74. package/dist/hono/index.d.mts +3 -3
  75. package/dist/hono/index.d.mts.map +1 -1
  76. package/dist/hono/index.mjs +3 -6
  77. package/dist/hono/index.mjs.map +1 -1
  78. package/dist/{http-ChVS9GYc.mjs → http-pKfd8UDu.mjs} +2 -2
  79. package/dist/{http-ChVS9GYc.mjs.map → http-pKfd8UDu.mjs.map} +1 -1
  80. package/dist/http.d.mts +1 -1
  81. package/dist/index.d.mts +9 -9
  82. package/dist/index.mjs +3 -203
  83. package/dist/{instrumentation-create-BrjQtSKD.d.mts → instrumentation-create-gSDk0leX.d.mts} +2 -2
  84. package/dist/{instrumentation-create-BrjQtSKD.d.mts.map → instrumentation-create-gSDk0leX.d.mts.map} +1 -1
  85. package/dist/{integration-DYp2uw8O.mjs → integration-CeL90DtN.mjs} +3 -2
  86. package/dist/{integration-DYp2uw8O.mjs.map → integration-CeL90DtN.mjs.map} +1 -1
  87. package/dist/{logger-mHIWxBhJ.d.mts → logger-CxWz7QJ3.d.mts} +7 -3
  88. package/dist/logger-CxWz7QJ3.d.mts.map +1 -0
  89. package/dist/logger.d.mts +2 -2
  90. package/dist/logger.mjs +2 -2
  91. package/dist/{fork-CgGlAaHa.mjs → middleware-Cdebyfdt.mjs} +3 -69
  92. package/dist/middleware-Cdebyfdt.mjs.map +1 -0
  93. package/dist/{middleware-B_k4Mrzg.d.mts → middleware-fbtEs6bq.d.mts} +3 -3
  94. package/dist/middleware-fbtEs6bq.d.mts.map +1 -0
  95. package/dist/nestjs/index.d.mts +5 -5
  96. package/dist/nestjs/index.d.mts.map +1 -1
  97. package/dist/nestjs/index.mjs +4 -3
  98. package/dist/nestjs/index.mjs.map +1 -1
  99. package/dist/next/client.d.mts +1 -1
  100. package/dist/next/index.d.mts +5 -5
  101. package/dist/next/index.d.mts.map +1 -1
  102. package/dist/next/index.mjs +3 -3
  103. package/dist/next/index.mjs.map +1 -1
  104. package/dist/next/instrumentation/create.d.mts +1 -1
  105. package/dist/next/instrumentation/create.mjs +3 -1
  106. package/dist/next/instrumentation/create.mjs.map +1 -1
  107. package/dist/next/instrumentation.d.mts +1 -1
  108. package/dist/next/stream.d.mts +1 -1
  109. package/dist/nitro/errorHandler.mjs +9 -4
  110. package/dist/nitro/errorHandler.mjs.map +1 -1
  111. package/dist/nitro/module.d.mts +2 -2
  112. package/dist/nitro/module.mjs +1 -1
  113. package/dist/nitro/plugin.mjs +2 -2
  114. package/dist/nitro/v3/errorHandler.d.mts +0 -10
  115. package/dist/nitro/v3/errorHandler.mjs +13 -3
  116. package/dist/nitro/v3/errorHandler.mjs.map +1 -1
  117. package/dist/nitro/v3/index.d.mts +2 -2
  118. package/dist/nitro/v3/module.d.mts +1 -1
  119. package/dist/nitro/v3/module.mjs +1 -1
  120. package/dist/nitro/v3/plugin.mjs +2 -2
  121. package/dist/nitro/v3/useLogger.d.mts +2 -2
  122. package/dist/nitro/v3/useLogger.d.mts.map +1 -1
  123. package/dist/nitro/v3/useLogger.mjs.map +1 -1
  124. package/dist/{nitro-_Hda8Deo.d.mts → nitro-CcN7HDnr.d.mts} +2 -2
  125. package/dist/{nitro-_Hda8Deo.d.mts.map → nitro-CcN7HDnr.d.mts.map} +1 -1
  126. package/dist/{nitro-ClRZLD1g.mjs → nitro-DYFCSlho.mjs} +30 -3
  127. package/dist/nitro-DYFCSlho.mjs.map +1 -0
  128. package/dist/{nitroConfigBridge-BkVWnSV3.mjs → nitroConfigBridge-lHPsE5zG.mjs} +8 -6
  129. package/dist/nitroConfigBridge-lHPsE5zG.mjs.map +1 -0
  130. package/dist/{nodeResponse-CIEEbrNE.mjs → nodeResponse-Dsl7gZUf.mjs} +1 -1
  131. package/dist/{nodeResponse-CIEEbrNE.mjs.map → nodeResponse-Dsl7gZUf.mjs.map} +1 -1
  132. package/dist/nuxt/module.d.mts +1 -1
  133. package/dist/nuxt/module.mjs +2 -2
  134. package/dist/orpc/index.d.mts +4 -4
  135. package/dist/orpc/index.d.mts.map +1 -1
  136. package/dist/orpc/index.mjs +2 -2
  137. package/dist/orpc/index.mjs.map +1 -1
  138. package/dist/{package-CNV_CXs8.mjs → package-Drb3wqqt.mjs} +2 -2
  139. package/dist/package-Drb3wqqt.mjs.map +1 -0
  140. package/dist/{parseError-BeBXEd2V.d.mts → parseError-BmoJ7XeF.d.mts} +2 -2
  141. package/dist/parseError-BmoJ7XeF.d.mts.map +1 -0
  142. package/dist/react-router/index.d.mts +4 -4
  143. package/dist/react-router/index.d.mts.map +1 -1
  144. package/dist/react-router/index.mjs +3 -2
  145. package/dist/react-router/index.mjs.map +1 -1
  146. package/dist/register-disk-snippet-B5svlT8-.mjs +21 -0
  147. package/dist/register-disk-snippet-B5svlT8-.mjs.map +1 -0
  148. package/dist/runtime/client/log.d.mts +1 -1
  149. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
  150. package/dist/runtime/server/useLogger.d.mts +1 -1
  151. package/dist/runtime/server/useLogger.mjs.map +1 -1
  152. package/dist/runtime/utils/parseError.d.mts +2 -2
  153. package/dist/{storage-7X37OToT.mjs → storage-BeFdoGTI.mjs} +1 -1
  154. package/dist/storage-BeFdoGTI.mjs.map +1 -0
  155. package/dist/stream.d.mts +1 -1
  156. package/dist/stream.d.mts.map +1 -1
  157. package/dist/stream.mjs +7 -1
  158. package/dist/stream.mjs.map +1 -1
  159. package/dist/sveltekit/index.d.mts +3 -4
  160. package/dist/sveltekit/index.d.mts.map +1 -1
  161. package/dist/sveltekit/index.mjs +6 -3
  162. package/dist/sveltekit/index.mjs.map +1 -1
  163. package/dist/toolkit.d.mts +7 -7
  164. package/dist/toolkit.d.mts.map +1 -1
  165. package/dist/toolkit.mjs +7 -6
  166. package/dist/types.d.mts +1 -1
  167. package/dist/{useLogger-Cfv8Ck8b.d.mts → useLogger-BupVLO9_.d.mts} +3 -3
  168. package/dist/useLogger-BupVLO9_.d.mts.map +1 -0
  169. package/dist/{utils-CJJG0ZYW.d.mts → utils-D_LY-J1k.d.mts} +2 -2
  170. package/dist/{utils-CJJG0ZYW.d.mts.map → utils-D_LY-J1k.d.mts.map} +1 -1
  171. package/dist/utils.d.mts +1 -1
  172. package/dist/vite/index.d.mts +1 -1
  173. package/dist/workers.d.mts +3 -3
  174. package/dist/workers.d.mts.map +1 -1
  175. package/dist/workers.mjs +1 -1
  176. package/dist/workers.mjs.map +1 -1
  177. package/package.json +25 -2
  178. package/dist/audit-BQt8yAHo.mjs.map +0 -1
  179. package/dist/audit-D7v6JHj0.d.mts.map +0 -1
  180. package/dist/fork-CgGlAaHa.mjs.map +0 -1
  181. package/dist/index-EvnrXvQM.d.mts.map +0 -1
  182. package/dist/index.mjs.map +0 -1
  183. package/dist/logger-mHIWxBhJ.d.mts.map +0 -1
  184. package/dist/middleware-B_k4Mrzg.d.mts.map +0 -1
  185. package/dist/nitro-ClRZLD1g.mjs.map +0 -1
  186. package/dist/nitroConfigBridge-BkVWnSV3.mjs.map +0 -1
  187. package/dist/package-CNV_CXs8.mjs.map +0 -1
  188. package/dist/parseError-BeBXEd2V.d.mts.map +0 -1
  189. package/dist/storage-7X37OToT.mjs.map +0 -1
  190. package/dist/useLogger-Cfv8Ck8b.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/eve/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport { defineHook, type HookContext, type HookDefinition } from 'eve/hooks'\nimport type { AuditableLogger } from '../audit'\nimport type { AIToolExecution, AIEventData, ModelCost } from '../ai/index'\nimport { initLogger, isLoggerInitialized, isLoggerLocked } from '../logger'\nimport type { LoggerConfig } from '../types'\nimport type { BaseEvlogOptions, MiddlewareLoggerOptions } from '../shared/middleware'\nimport { createMiddlewareLogger } from '../shared/middleware'\nimport {\n bindAsyncLocalStorage,\n clearAsyncLocalStorage,\n patchAsyncLocalStorageEnterWith,\n} from '../shared/asyncStorageScope'\n\nconst DEFAULT_MAX_SESSIONS = 256\n\n/** Options for {@link defineEvlogHook}. */\nexport interface EvlogEveOptions extends BaseEvlogOptions {\n /** Passed to {@link initLogger} on the first hook invocation. */\n init?: LoggerConfig\n /**\n * When `true` (default), user message content from `message.received` is\n * omitted from the wide event. Set to `false` to include a truncated preview.\n */\n redactMessage?: boolean\n /**\n * Pricing map for {@link AIEventData.estimatedCost}. Keys are model IDs,\n * values are dollars per 1M tokens — same shape as `evlog/ai`.\n */\n cost?: Record<string, ModelCost>\n /**\n * Model ID used with `cost` when eve stream events do not expose the model\n * name. When `cost` has exactly one entry, that key is used automatically.\n */\n model?: string\n /**\n * Max in-memory sessions for context carry-over and approval state.\n * Oldest sessions are evicted when exceeded. Default `256`.\n */\n maxSessions?: number\n}\n\n/** Minimal session shape accepted by {@link useLogger} as a fallback lookup key. */\nexport interface EveTurnSessionContext {\n readonly session: {\n readonly id: string\n readonly turn?: { readonly id?: string }\n }\n}\n\ninterface PendingAction {\n toolName: string\n startedAt: number\n turnId: string\n}\n\ninterface EveApprovalPending {\n toolName: string\n callId: string\n}\n\ninterface SessionRollup {\n turnCount: number\n lastAccess: number\n}\n\ninterface EveSubagentRecord {\n callId: string\n name: string\n toolName?: string\n childSessionId?: string\n status: 'called' | 'completed'\n output?: string\n}\n\ninterface TurnAccumulator {\n calls: number\n steps: number\n inputTokens: number\n outputTokens: number\n cacheReadTokens: number\n cacheWriteTokens: number\n finishReason?: string\n toolExecutions: AIToolExecution[]\n subagents: EveSubagentRecord[]\n pausedForInput: boolean\n stepStartedAt?: number\n costMap?: Record<string, ModelCost>\n costModel?: string\n}\n\ninterface TurnState {\n logger: AuditableLogger\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n middlewareOptions: MiddlewareLoggerOptions\n accumulator: TurnAccumulator\n sessionId: string\n turnId: string\n}\n\n/** Top-level wide-event keys that stay turn-scoped and are not carried across turns. */\nconst TURN_ONLY_KEYS = new Set([\n 'eve',\n 'ai',\n 'message',\n 'method',\n 'path',\n 'status',\n 'duration',\n 'level',\n 'error',\n 'agent',\n 'channel',\n 'approval',\n 'audit',\n 'requestId',\n 'service',\n 'timestamp',\n 'traceId',\n 'spanId',\n])\n\nfunction turnKey(sessionId: string, turnId: string): string {\n return `${sessionId}:${turnId}`\n}\n\nfunction freshAccumulator(options: EvlogEveOptions): TurnAccumulator {\n return {\n calls: 0,\n steps: 0,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n toolExecutions: [],\n subagents: [],\n pausedForInput: false,\n costMap: options.cost,\n costModel: resolveCostModel(options),\n }\n}\n\nfunction resolveCostModel(options: EvlogEveOptions): string | undefined {\n if (options.model) return options.model\n const keys = options.cost ? Object.keys(options.cost) : []\n if (keys.length === 1) return keys[0]\n return undefined\n}\n\nfunction computeEstimatedCost(state: TurnAccumulator): number | undefined {\n if (!state.costMap || !state.costModel) return undefined\n const pricing = state.costMap[state.costModel]\n if (!pricing) return undefined\n const inputCost = (state.inputTokens / 1_000_000) * pricing.input\n const outputCost = (state.outputTokens / 1_000_000) * pricing.output\n const total = inputCost + outputCost\n return total > 0 ? Math.round(total * 1_000_000) / 1_000_000 : undefined\n}\n\nfunction buildAiField(state: TurnAccumulator): AIEventData {\n const totalTokens = state.inputTokens + state.outputTokens\n const data: AIEventData = {\n calls: state.calls,\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens,\n steps: state.steps,\n }\n if (state.costModel) data.model = state.costModel\n if (state.cacheReadTokens > 0) data.cacheReadTokens = state.cacheReadTokens\n if (state.cacheWriteTokens > 0) data.cacheWriteTokens = state.cacheWriteTokens\n if (state.finishReason) data.finishReason = state.finishReason\n const estimatedCost = computeEstimatedCost(state)\n if (estimatedCost !== undefined) data.estimatedCost = estimatedCost\n if (state.toolExecutions.length > 0) {\n data.tools = state.toolExecutions.map(t => ({ ...t }))\n }\n return data\n}\n\nfunction extractToolName(result: unknown): string {\n if (result && typeof result === 'object') {\n const record = result as Record<string, unknown>\n if (typeof record.toolName === 'string') return record.toolName\n if (typeof record.subagentName === 'string') return record.subagentName\n if (typeof record.name === 'string') return record.name\n }\n return 'unknown'\n}\n\nfunction extractCallId(result: unknown): string | undefined {\n if (result && typeof result === 'object') {\n const { callId } = result as Record<string, unknown>\n if (typeof callId === 'string') return callId\n }\n return undefined\n}\n\nfunction truncateMessage(message: string, maxLength = 500): string {\n if (message.length <= maxLength) return message\n return `${message.slice(0, maxLength)}…`\n}\n\nfunction ensureInit(options: EvlogEveOptions): void {\n const state = getEveGlobalState()\n if (options.maxSessions !== undefined) {\n state.maxSessions = options.maxSessions\n }\n if (isEveInitialized()) return\n if (!isLoggerLocked() && !isLoggerInitialized()) {\n initLogger(options.init ?? { env: { service: 'eve-agent' } })\n }\n setEveInitialized(true)\n}\n\nconst turnLoggerStorage = new AsyncLocalStorage<AuditableLogger>()\npatchAsyncLocalStorageEnterWith(turnLoggerStorage)\nconst activeTurnLoggers = new WeakSet<AuditableLogger>()\n\nfunction bindTurnLogger(logger: AuditableLogger): void {\n bindAsyncLocalStorage(turnLoggerStorage, logger)\n activeTurnLoggers.add(logger)\n}\n\nfunction unbindTurnLogger(logger: AuditableLogger): void {\n activeTurnLoggers.delete(logger)\n if (turnLoggerStorage.getStore() === logger) {\n clearAsyncLocalStorage(turnLoggerStorage)\n }\n}\n\nfunction resolveTurnLogger(ctx: EveTurnSessionContext): AuditableLogger {\n const sessionId = ctx.session.id\n const turnId = ctx.session.turn?.id ?? activeTurnBySession().get(sessionId)\n\n if (!turnId) {\n throw new Error(\n '[evlog] useLogger() could not resolve the active turn. '\n + 'Ensure defineEvlogHook() is registered and the turn has started.',\n )\n }\n\n const state = turnStates().get(turnKey(sessionId, turnId))\n if (!state) {\n throw new Error(\n '[evlog] useLogger() could not find a logger for the current turn. '\n + 'Ensure defineEvlogHook() is registered and the turn has started.',\n )\n }\n\n return state.logger\n}\n\n/**\n * Turn-scoped logger for eve tool `execute()` handlers.\n *\n * When {@link defineEvlogHook} is registered, the logger is bound via\n * AsyncLocalStorage on `turn.started`. Inside tool handlers, `useLogger()`\n * resolves from ALS when it propagated, otherwise from the sole active turn\n * in the process (typical eve dev). Pass eve tool `ctx` only when multiple\n * sessions are active concurrently.\n *\n * @example\n * ```ts\n * import { useLogger } from 'evlog/eve'\n *\n * export default defineTool({\n * async execute(input) {\n * const log = useLogger()\n * log.set({ order: { id: input.orderId } })\n * },\n * })\n * ```\n */\nfunction resolveActiveTurnLogger(): AuditableLogger | null {\n const active = activeTurnBySession()\n if (active.size !== 1) return null\n\n const [sessionId, turnId] = active.entries().next().value!\n return turnStates().get(turnKey(sessionId, turnId))?.logger ?? null\n}\n\nexport function useLogger(ctx?: EveTurnSessionContext): AuditableLogger {\n const fromStorage = turnLoggerStorage.getStore()\n if (fromStorage && activeTurnLoggers.has(fromStorage)) {\n return fromStorage\n }\n\n if (ctx?.session?.id) {\n return resolveTurnLogger(ctx)\n }\n\n const active = resolveActiveTurnLogger()\n if (active) return active\n\n throw new Error(\n '[evlog] useLogger() was called outside an evlog eve turn. '\n + 'Add agent/hooks/evlog.ts with defineEvlogHook() or pass ctx from the tool handler.',\n )\n}\n\ninterface EveGlobalState {\n turnStates: Map<string, TurnState>\n activeTurnBySession: Map<string, string>\n sessionSnapshots: Map<string, Record<string, unknown>>\n sessionPendingActions: Map<string, Map<string, PendingAction>>\n sessionApprovals: Map<string, EveApprovalPending[]>\n sessionRollups: Map<string, SessionRollup>\n maxSessions: number\n initialized: boolean\n}\n\nconst EVE_GLOBAL_STATE = Symbol.for('evlog.eve.state')\n\nfunction getEveGlobalState(): EveGlobalState {\n const host = globalThis as typeof globalThis & {\n [EVE_GLOBAL_STATE]?: EveGlobalState\n }\n if (!host[EVE_GLOBAL_STATE]) {\n host[EVE_GLOBAL_STATE] = {\n turnStates: new Map(),\n activeTurnBySession: new Map(),\n sessionSnapshots: new Map(),\n sessionPendingActions: new Map(),\n sessionApprovals: new Map(),\n sessionRollups: new Map(),\n maxSessions: DEFAULT_MAX_SESSIONS,\n initialized: false,\n }\n }\n return host[EVE_GLOBAL_STATE]\n}\n\nfunction turnStates(): Map<string, TurnState> {\n return getEveGlobalState().turnStates\n}\n\nfunction activeTurnBySession(): Map<string, string> {\n return getEveGlobalState().activeTurnBySession\n}\n\nfunction sessionSnapshots(): Map<string, Record<string, unknown>> {\n return getEveGlobalState().sessionSnapshots\n}\n\nfunction sessionPendingActions(): Map<string, Map<string, PendingAction>> {\n return getEveGlobalState().sessionPendingActions\n}\n\nfunction sessionApprovals(): Map<string, EveApprovalPending[]> {\n return getEveGlobalState().sessionApprovals\n}\n\nfunction sessionRollups(): Map<string, SessionRollup> {\n return getEveGlobalState().sessionRollups\n}\n\nfunction touchSession(sessionId: string): void {\n const rollups = sessionRollups()\n const rollup = rollups.get(sessionId) ?? { turnCount: 0, lastAccess: 0 }\n rollup.lastAccess = Date.now()\n rollups.set(sessionId, rollup)\n evictStaleSessions()\n}\n\nfunction clearSessionState(sessionId: string): void {\n sessionSnapshots().delete(sessionId)\n sessionRollups().delete(sessionId)\n sessionPendingActions().delete(sessionId)\n sessionApprovals().delete(sessionId)\n}\n\nfunction evictStaleSessions(): void {\n const { maxSessions } = getEveGlobalState()\n const rollups = sessionRollups()\n if (rollups.size <= maxSessions) return\n\n const oldest = [...rollups.entries()]\n .sort((a, b) => a[1].lastAccess - b[1].lastAccess)\n .slice(0, rollups.size - maxSessions)\n\n for (const [sessionId] of oldest) {\n if (activeTurnBySession().has(sessionId)) continue\n clearSessionState(sessionId)\n }\n}\n\nfunction pruneEmptySessionMaps(sessionId: string): void {\n const pending = sessionPendingActions().get(sessionId)\n if (pending?.size === 0) sessionPendingActions().delete(sessionId)\n\n const approvals = sessionApprovals().get(sessionId)\n if (approvals?.length === 0) sessionApprovals().delete(sessionId)\n}\n\nfunction bumpSessionTurnCount(sessionId: string): number {\n touchSession(sessionId)\n const rollup = sessionRollups().get(sessionId)!\n rollup.turnCount += 1\n return rollup.turnCount\n}\n\n/** Turn-level label — only set when the turn ends in a non-routine state. */\nfunction derivePhase(\n ctx: Record<string, unknown>,\n accumulator: TurnAccumulator,\n httpStatus: number,\n): string | undefined {\n const approval = ctx.approval as { status?: string } | undefined\n if (approval?.status === 'rejected') return 'rejected'\n if (approval?.status === 'pending' || accumulator.pausedForInput) return 'awaiting-approval'\n if (httpStatus >= 400) return 'failed'\n return undefined\n}\n\nfunction getSessionPendingActions(sessionId: string): Map<string, PendingAction> {\n let map = sessionPendingActions().get(sessionId)\n if (!map) {\n map = new Map()\n sessionPendingActions().set(sessionId, map)\n }\n return map\n}\n\nfunction trackPendingAction(\n sessionId: string,\n turnId: string,\n action: { callId: string, toolName: string, startedAt?: number },\n): void {\n touchSession(sessionId)\n getSessionPendingActions(sessionId).set(action.callId, {\n toolName: action.toolName,\n startedAt: action.startedAt ?? Date.now(),\n turnId,\n })\n}\n\nfunction resolveToolDurationMs(\n state: TurnState,\n callId: string | undefined,\n): number {\n const pending = callId ? getSessionPendingActions(state.sessionId).get(callId) : undefined\n if (pending) {\n if (pending.turnId !== state.turnId && state.accumulator.stepStartedAt !== undefined) {\n return Math.max(0, Date.now() - state.accumulator.stepStartedAt)\n }\n return Math.max(0, Date.now() - pending.startedAt)\n }\n if (state.accumulator.stepStartedAt !== undefined) {\n return Math.max(0, Date.now() - state.accumulator.stepStartedAt)\n }\n return 0\n}\n\nfunction consumeSessionApproval(\n sessionId: string,\n toolName: string,\n callId?: string,\n): EveApprovalPending | undefined {\n const list = sessionApprovals().get(sessionId)\n if (!list?.length) return undefined\n const index = list.findIndex(approval =>\n callId ? approval.callId === callId : approval.toolName === toolName,\n )\n if (index === -1) return undefined\n const [approval] = list.splice(index, 1)\n if (list.length === 0) sessionApprovals().delete(sessionId)\n return approval\n}\n\nfunction storeSessionApprovals(sessionId: string, pending: EveApprovalPending[]): void {\n touchSession(sessionId)\n const existing = sessionApprovals().get(sessionId) ?? []\n sessionApprovals().set(sessionId, [...existing, ...pending])\n}\n\nfunction isEveInitialized(): boolean {\n return getEveGlobalState().initialized\n}\n\nfunction setEveInitialized(value: boolean): void {\n getEveGlobalState().initialized = value\n}\n\nfunction applySessionContext(sessionId: string, logger: AuditableLogger): void {\n touchSession(sessionId)\n const snapshot = sessionSnapshots().get(sessionId)\n if (snapshot && Object.keys(snapshot).length > 0) {\n logger.set({ ...snapshot })\n }\n}\n\nfunction persistSessionContext(sessionId: string, logger: AuditableLogger): void {\n const ctx = logger.getContext() as Record<string, unknown>\n const snapshot = { ...(sessionSnapshots().get(sessionId) ?? {}) }\n for (const [key, value] of Object.entries(ctx)) {\n if (!TURN_ONLY_KEYS.has(key) && value !== undefined) {\n snapshot[key] = value\n }\n }\n sessionSnapshots().set(sessionId, snapshot)\n}\n\nfunction flushEveMetadata(state: TurnState): void {\n if (state.accumulator.subagents.length === 0) return\n state.logger.set({\n eve: {\n subagents: state.accumulator.subagents.map(s => ({ ...s })),\n },\n })\n}\n\nfunction getOrCreateTurnState(\n sessionId: string,\n turnId: string,\n options: EvlogEveOptions,\n ctx: HookContext,\n): TurnState | null {\n const key = turnKey(sessionId, turnId)\n const existing = turnStates().get(key)\n if (existing) return existing\n\n touchSession(sessionId)\n\n const path = `/sessions/${sessionId}/turns/${turnId}`\n const middlewareOptions: MiddlewareLoggerOptions = {\n method: 'EVE',\n path,\n requestId: turnId,\n drain: options.drain,\n enrich: options.enrich,\n keep: options.keep,\n redact: options.redact,\n plugins: options.plugins,\n include: options.include,\n exclude: options.exclude,\n routes: options.routes,\n }\n\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOptions)\n if (skipped) return null\n\n const state: TurnState = {\n logger,\n finish,\n middlewareOptions,\n accumulator: freshAccumulator(options),\n sessionId,\n turnId,\n }\n\n applySessionContext(sessionId, logger)\n\n logger.set({\n eve: {\n sessionId,\n turnId,\n },\n agent: {\n name: ctx.agent.name,\n ...(ctx.agent.nodeId ? { nodeId: ctx.agent.nodeId } : {}),\n },\n channel: {\n kind: ctx.channel.kind ?? 'unknown',\n ...(ctx.channel.continuationToken ? { continuing: true } : {}),\n },\n })\n\n turnStates().set(key, state)\n activeTurnBySession().set(sessionId, turnId)\n return state\n}\n\nfunction flushAi(state: TurnState): void {\n state.logger.set({ ai: buildAiField(state.accumulator) })\n}\n\nasync function finishTurn(\n sessionId: string,\n turnId: string,\n opts: { status?: number; error?: Error },\n): Promise<void> {\n const key = turnKey(sessionId, turnId)\n const state = turnStates().get(key)\n if (!state) return\n\n try {\n flushEveMetadata(state)\n flushAi(state)\n const httpStatus = opts.status ?? (opts.error ? 500 : 200)\n const ctx = state.logger.getContext() as Record<string, unknown>\n const phase = derivePhase(ctx, state.accumulator, httpStatus)\n const sessionTurns = bumpSessionTurnCount(sessionId)\n state.logger.set({\n eve: {\n ...(phase ? { phase } : {}),\n sessionTurns,\n },\n })\n persistSessionContext(sessionId, state.logger)\n await state.finish(opts)\n } finally {\n unbindTurnLogger(state.logger)\n turnStates().delete(key)\n if (activeTurnBySession().get(sessionId) === turnId) {\n activeTurnBySession().delete(sessionId)\n }\n pruneEmptySessionMaps(sessionId)\n }\n}\n\nfunction runSafe(fn: () => void | Promise<void>): void {\n void (async () => {\n try {\n await fn()\n } catch (err) {\n console.error('[evlog] eve hook handler failed:', err)\n }\n })()\n}\n\nfunction getTurnState(sessionId: string, turnId: string): TurnState | undefined {\n return turnStates().get(turnKey(sessionId, turnId))\n}\n\n/**\n * Create an eve stream hook that emits one evlog wide event per agent turn.\n *\n * Export the result as the default export of `agent/hooks/evlog.ts`. eve\n * auto-discovers hook files; evlog maps turn lifecycle events to a wide event\n * with AI usage, tool executions, and your drain/enrich/keep pipeline.\n *\n * Complements eve Agent Runs and OpenTelemetry — it does not replace them.\n *\n * @example\n * ```ts\n * // agent/hooks/evlog.ts\n * import { defineEvlogHook } from 'evlog/eve'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * export default defineEvlogHook({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.runtime = process.env.VERCEL_REGION\n * },\n * })\n * ```\n */\nexport function defineEvlogHook(options: EvlogEveOptions = {}): HookDefinition {\n const redactMessage = options.redactMessage ?? true\n\n return defineHook({\n events: {\n 'turn.started'(event, ctx) {\n try {\n ensureInit(options)\n const state = getOrCreateTurnState(ctx.session.id, event.data.turnId, options, ctx)\n state?.logger.set({\n eve: { turnSequence: event.data.sequence },\n })\n if (state) bindTurnLogger(state.logger)\n } catch (err) {\n console.error('[evlog] eve hook handler failed:', err)\n }\n },\n\n 'message.received'(event, ctx) {\n runSafe(() => {\n if (redactMessage) return\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n state.logger.set({\n message: { received: truncateMessage(event.data.message) },\n })\n })\n },\n\n 'step.started'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n state.accumulator.stepStartedAt = Date.now()\n })\n },\n\n 'step.completed'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n const acc = state.accumulator\n acc.steps += 1\n acc.calls += 1\n acc.finishReason = event.data.finishReason\n const { usage } = event.data\n if (usage) {\n acc.inputTokens += usage.inputTokens ?? 0\n acc.outputTokens += usage.outputTokens ?? 0\n acc.cacheReadTokens += usage.cacheReadTokens ?? 0\n acc.cacheWriteTokens += usage.cacheWriteTokens ?? 0\n }\n })\n },\n\n 'actions.requested'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n bindTurnLogger(state.logger)\n const startedAt = Date.now()\n for (const action of event.data.actions) {\n if (action.kind === 'tool-call') {\n trackPendingAction(ctx.session.id, event.data.turnId, {\n callId: action.callId,\n toolName: action.toolName,\n startedAt,\n })\n }\n }\n })\n },\n\n 'input.requested'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n state.accumulator.pausedForInput = true\n const pending = event.data.requests.map(req => ({\n toolName: req.action.toolName,\n callId: req.action.callId,\n }))\n storeSessionApprovals(ctx.session.id, pending)\n const [first] = pending\n if (first) {\n state.logger.set({\n approval: { status: 'pending', tool: first.toolName },\n })\n }\n })\n },\n\n 'action.result'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n const callId = extractCallId(event.data.result)\n const sessionPending = getSessionPendingActions(state.sessionId)\n const turnPending = callId ? sessionPending.get(callId) : undefined\n\n const { status } = event.data\n const rejected = status === 'rejected'\n const success = status === 'completed'\n const toolName = turnPending?.toolName ?? extractToolName(event.data.result)\n const durationMs = resolveToolDurationMs(state, callId)\n\n if (callId) sessionPending.delete(callId)\n\n const execution: AIToolExecution = {\n name: toolName,\n durationMs,\n success,\n }\n if (rejected) {\n execution.error = 'rejected'\n state.accumulator.pausedForInput = false\n consumeSessionApproval(state.sessionId, toolName, callId)\n state.logger.set({\n approval: { status: 'rejected', tool: toolName },\n })\n } else if (success) {\n const approval = consumeSessionApproval(state.sessionId, toolName, callId)\n if (approval) {\n state.accumulator.pausedForInput = false\n state.logger.set({\n approval: { status: 'approved', tool: approval.toolName },\n })\n }\n } else if (event.data.error) {\n execution.error = event.data.error.message\n }\n state.accumulator.toolExecutions.push(execution)\n })\n },\n\n 'subagent.called'(event, ctx) {\n runSafe(() => {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n if (!state) return\n state.accumulator.subagents.push({\n callId: event.data.callId,\n name: event.data.name,\n toolName: event.data.toolName,\n childSessionId: event.data.childSessionId,\n status: 'called',\n })\n })\n },\n\n 'subagent.completed'(event, ctx) {\n runSafe(() => {\n const sessionId = ctx.session.id\n const turnId = activeTurnBySession().get(sessionId)\n if (!turnId) return\n const state = getTurnState(sessionId, turnId)\n if (!state) return\n const existing = state.accumulator.subagents.find(s => s.callId === event.data.callId)\n if (existing) {\n existing.status = 'completed'\n existing.output = event.data.output\n } else {\n state.accumulator.subagents.push({\n callId: event.data.callId,\n name: event.data.subagentName,\n status: 'completed',\n output: event.data.output,\n })\n }\n })\n },\n\n async 'turn.completed'(event, ctx) {\n try {\n await finishTurn(ctx.session.id, event.data.turnId, { status: 200 })\n } catch (err) {\n console.error('[evlog] eve hook handler failed:', err)\n }\n },\n\n async 'turn.failed'(event, ctx) {\n try {\n const state = getTurnState(ctx.session.id, event.data.turnId)\n state?.logger.set({\n eve: {\n failure: {\n code: event.data.code,\n message: event.data.message,\n ...(event.data.details ? { details: event.data.details } : {}),\n },\n },\n })\n const error = new Error(event.data.message)\n error.name = event.data.code\n await finishTurn(ctx.session.id, event.data.turnId, { error, status: 500 })\n } catch (err) {\n console.error('[evlog] eve hook handler failed:', err)\n }\n },\n },\n })\n}\n\n/** @internal Simulates eve tool execution where AsyncLocalStorage did not propagate. */\nexport function detachActiveTurnLoggerForTests(): void {\n const logger = turnLoggerStorage.getStore()\n if (logger) unbindTurnLogger(logger)\n}\n\n/** @internal Resets module state between unit tests. Clears turn maps, session context, and the Eve init flag. */\nexport function resetEvlogEveForTests(): void {\n clearAsyncLocalStorage(turnLoggerStorage)\n turnStates().clear()\n activeTurnBySession().clear()\n sessionSnapshots().clear()\n sessionPendingActions().clear()\n sessionApprovals().clear()\n sessionRollups().clear()\n setEveInitialized(false)\n delete (globalThis as typeof globalThis & { [EVE_GLOBAL_STATE]?: EveGlobalState })[EVE_GLOBAL_STATE]\n}\n\nexport type { ModelCost } from '../ai/index'\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- import { rt as RequestLogger } from "../audit-D7v6JHj0.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-B_k4Mrzg.mjs";
1
+ import { l as AuditableLogger } from "../audit-BZrUvjfW.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-fbtEs6bq.mjs";
3
3
  import { RequestHandler } from "express";
4
4
 
5
5
  //#region src/express/index.d.ts
6
- declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
6
+ declare const useLogger: <T extends object = Record<string, unknown>>() => AuditableLogger<T>;
7
7
  type EvlogExpressOptions = BaseEvlogOptions;
8
8
  declare module 'express-serve-static-core' {
9
9
  interface Request {
10
- log?: RequestLogger;
10
+ log?: AuditableLogger;
11
11
  }
12
12
  }
13
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/express/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,OAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;;;;;;;;;AANV;;;;;AAEoB;;;;;iBAwCJ,KAAA,CAAM,OAAA,GAAS,mBAAA,GAA2B,cAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/express/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,eAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,OAAA;IACR,GAAA,GAAM,eAAA;EAAA;AAAA;;;;;;;;;AANV;;;;;AAEoB;;;;;iBAwCJ,KAAA,CAAM,OAAA,GAAS,mBAAA,GAA2B,cAAA"}
@@ -1,6 +1,6 @@
1
- import { t as defineFrameworkIntegration } from "../integration-DYp2uw8O.mjs";
2
- import { t as bindNodeResponseLifecycle } from "../nodeResponse-CIEEbrNE.mjs";
3
- import { t as createLoggerStorage } from "../storage-7X37OToT.mjs";
1
+ import { t as defineFrameworkIntegration } from "../integration-CeL90DtN.mjs";
2
+ import { t as bindNodeResponseLifecycle } from "../nodeResponse-Dsl7gZUf.mjs";
3
+ import { t as createLoggerStorage } from "../storage-BeFdoGTI.mjs";
4
4
  //#region src/express/index.ts
5
5
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure app.use(evlog()) is registered before your routes.");
6
6
  const integration = defineFrameworkIntegration({
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/express/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express'\nimport type { RequestLogger } from '../types'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { bindNodeResponseLifecycle } from '../shared/nodeResponse'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure app.use(evlog()) is registered before your routes.',\n)\n\nexport type EvlogExpressOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: RequestLogger\n }\n}\n\nconst integration = defineFrameworkIntegration<Request>({\n name: 'express',\n extractRequest: (req) => ({\n method: req.method,\n path: new URL(req.originalUrl || req.url || '/', 'http://localhost').pathname,\n headers: req.headers,\n requestId: req.get('x-request-id'),\n }),\n attachLogger: (req, logger) => {\n req.log = logger\n },\n storage,\n})\n\n/**\n * Create an evlog middleware for Express.\n *\n * @example\n * ```ts\n * import express from 'express'\n * import { evlog } from 'evlog/express'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = express()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogExpressOptions = {}): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const { logger, finish, skipped, runWith } = integration.start(req, options)\n\n if (skipped) {\n next()\n return\n }\n\n bindNodeResponseLifecycle(res, logger, finish)\n\n void runWith(() => next())\n }\n}\n"],"mappings":";;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,mFACD;AAYD,MAAM,cAAc,2BAAoC;CACtD,MAAM;CACN,iBAAiB,SAAS;EACxB,QAAQ,IAAI;EACZ,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB,CAAC;EACrE,SAAS,IAAI;EACb,WAAW,IAAI,IAAI,eAAe;EACnC;CACD,eAAe,KAAK,WAAW;AAC7B,MAAI,MAAM;;CAEZ;CACD,CAAC;;;;;;;;;;;;;;;;;;;AAoBF,SAAgB,MAAM,UAA+B,EAAE,EAAkB;AACvE,SAAQ,KAAc,KAAe,SAAuB;EAC1D,MAAM,EAAE,QAAQ,QAAQ,SAAS,YAAY,YAAY,MAAM,KAAK,QAAQ;AAE5E,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,4BAA0B,KAAK,QAAQ,OAAO;AAEzC,gBAAc,MAAM,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/express/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express'\nimport type { AuditableLogger } from '../audit'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { bindNodeResponseLifecycle } from '../shared/nodeResponse'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure app.use(evlog()) is registered before your routes.',\n)\n\nexport type EvlogExpressOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: AuditableLogger\n }\n}\n\nconst integration = defineFrameworkIntegration<Request>({\n name: 'express',\n extractRequest: (req) => ({\n method: req.method,\n path: new URL(req.originalUrl || req.url || '/', 'http://localhost').pathname,\n headers: req.headers,\n requestId: req.get('x-request-id'),\n }),\n attachLogger: (req, logger) => {\n req.log = logger\n },\n storage,\n})\n\n/**\n * Create an evlog middleware for Express.\n *\n * @example\n * ```ts\n * import express from 'express'\n * import { evlog } from 'evlog/express'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = express()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogExpressOptions = {}): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const { logger, finish, skipped, runWith } = integration.start(req, options)\n\n if (skipped) {\n next()\n return\n }\n\n bindNodeResponseLifecycle(res, logger, finish)\n\n void runWith(() => next())\n }\n}\n"],"mappings":";;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,mFACD;AAYD,MAAM,cAAc,2BAAoC;CACtD,MAAM;CACN,iBAAiB,SAAS;EACxB,QAAQ,IAAI;EACZ,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB,CAAC;EACrE,SAAS,IAAI;EACb,WAAW,IAAI,IAAI,eAAe;EACnC;CACD,eAAe,KAAK,WAAW;AAC7B,MAAI,MAAM;;CAEZ;CACD,CAAC;;;;;;;;;;;;;;;;;;;AAoBF,SAAgB,MAAM,UAA+B,EAAE,EAAkB;AACvE,SAAQ,KAAc,KAAe,SAAuB;EAC1D,MAAM,EAAE,QAAQ,QAAQ,SAAS,YAAY,YAAY,MAAM,KAAK,QAAQ;AAE5E,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,4BAA0B,KAAK,QAAQ,OAAO;AAEzC,gBAAc,MAAM,CAAC"}
@@ -1,13 +1,13 @@
1
- import { rt as RequestLogger } from "../audit-D7v6JHj0.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-B_k4Mrzg.mjs";
1
+ import { l as AuditableLogger } from "../audit-BZrUvjfW.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-fbtEs6bq.mjs";
3
3
  import { FastifyPluginCallback } from "fastify";
4
4
 
5
5
  //#region src/fastify/index.d.ts
6
- declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
6
+ declare const useLogger: <T extends object = Record<string, unknown>>() => AuditableLogger<T>;
7
7
  type EvlogFastifyOptions = BaseEvlogOptions;
8
8
  declare module 'fastify' {
9
9
  interface FastifyRequest {
10
- log: RequestLogger;
10
+ log: AuditableLogger;
11
11
  }
12
12
  }
13
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/fastify/index.ts"],"mappings":";;;;;cAMiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,cAAA;IAER,GAAA,EAAK,aAAA;EAAA;AAAA;;;;;;;;;AAPT;;;;;AAEoB;;;;;;;;;;AAqFpB;cAAa,KAAA,EAAK,qBAAA,CAAA,gBAAA;EAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/fastify/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,eAAA,CAAA,CAAA;AAAA,KAMd,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,cAAA;IAER,GAAA,EAAK,eAAA;EAAA;AAAA;;;;;;;;;AAPT;;;;;AAEoB;;;;;;;;;;AAqFpB;cAAa,KAAA,EAAK,qBAAA,CAAA,gBAAA;EAAA"}
@@ -1,7 +1,9 @@
1
- import { t as defineFrameworkIntegration } from "../integration-DYp2uw8O.mjs";
2
- import { t as createLoggerStorage } from "../storage-7X37OToT.mjs";
1
+ import { t as registerDiskPrettyErrorSnippetReader } from "../register-disk-snippet-B5svlT8-.mjs";
2
+ import { t as defineFrameworkIntegration } from "../integration-CeL90DtN.mjs";
3
+ import { t as createLoggerStorage } from "../storage-BeFdoGTI.mjs";
3
4
  //#region src/fastify/index.ts
4
5
  const { storage, useLogger } = createLoggerStorage("plugin context. Make sure app.register(evlog) is called before your routes.");
6
+ registerDiskPrettyErrorSnippetReader();
5
7
  const integration = defineFrameworkIntegration({
6
8
  name: "fastify",
7
9
  extractRequest: (req) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/fastify/index.ts"],"sourcesContent":["import type { FastifyPluginCallback, FastifyRequest } from 'fastify'\nimport type { RequestLogger } from '../types'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'plugin context. Make sure app.register(evlog) is called before your routes.',\n)\n\nexport type EvlogFastifyOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n // @ts-expect-error intentionally overrides Fastify's built-in pino logger with evlog's RequestLogger\n log: RequestLogger\n }\n}\n\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n}\n\nconst integration = defineFrameworkIntegration<FastifyRequest>({\n name: 'fastify',\n extractRequest: (req) => ({\n method: req.method,\n path: new URL(req.url, 'http://localhost').pathname,\n headers: req.headers,\n requestId: typeof req.headers['x-request-id'] === 'string' ? req.headers['x-request-id'] : undefined,\n }),\n attachLogger: (req, logger) => {\n // @ts-expect-error evlog replaces Fastify's built-in pino logger with RequestLogger\n req.log = logger\n },\n storage,\n})\n\nconst evlogPlugin: FastifyPluginCallback<EvlogFastifyOptions> = (fastify, options, done) => {\n const emitted = new WeakSet<object>()\n const requestState = new WeakMap<object, RequestState>()\n\n fastify.addHook('onRequest', (request, _reply, next) => {\n const { finish, skipped, runWith } = integration.start(request, options)\n if (skipped) {\n next()\n return\n }\n requestState.set(request, { finish })\n void runWith(() => next())\n })\n\n fastify.addHook('onResponse', async (request, reply) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n await state.finish({ status: reply.statusCode })\n })\n\n fastify.addHook('onError', async (request, _reply, error) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n const err = error instanceof Error ? error : new Error(String(error))\n request.log.error(err)\n await state.finish({ error: err })\n })\n\n done()\n}\n\n/**\n * Create an evlog plugin for Fastify.\n *\n * Plugin metadata symbols (`skip-override`, `fastify.display-name`) are attached\n * for @fastify/autoload — they are not part of `FastifyPluginCallback`.\n *\n * @example\n * ```ts\n * import Fastify from 'fastify'\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/fastify'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'fastify-api' } })\n *\n * const app = Fastify()\n * await app.register(evlog, {\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n */\nexport const evlog = Object.assign(evlogPlugin, {\n [Symbol.for('skip-override')]: true,\n [Symbol.for('fastify.display-name')]: 'evlog',\n})\n"],"mappings":";;;AAMA,MAAM,EAAE,SAAS,cAAc,oBAC7B,8EACD;AAiBD,MAAM,cAAc,2BAA2C;CAC7D,MAAM;CACN,iBAAiB,SAAS;EACxB,QAAQ,IAAI;EACZ,MAAM,IAAI,IAAI,IAAI,KAAK,mBAAmB,CAAC;EAC3C,SAAS,IAAI;EACb,WAAW,OAAO,IAAI,QAAQ,oBAAoB,WAAW,IAAI,QAAQ,kBAAkB,KAAA;EAC5F;CACD,eAAe,KAAK,WAAW;AAE7B,MAAI,MAAM;;CAEZ;CACD,CAAC;AAEF,MAAM,eAA2D,SAAS,SAAS,SAAS;CAC1F,MAAM,0BAAU,IAAI,SAAiB;CACrC,MAAM,+BAAe,IAAI,SAA+B;AAExD,SAAQ,QAAQ,cAAc,SAAS,QAAQ,SAAS;EACtD,MAAM,EAAE,QAAQ,SAAS,YAAY,YAAY,MAAM,SAAS,QAAQ;AACxE,MAAI,SAAS;AACX,SAAM;AACN;;AAEF,eAAa,IAAI,SAAS,EAAE,QAAQ,CAAC;AAChC,gBAAc,MAAM,CAAC;GAC1B;AAEF,SAAQ,QAAQ,cAAc,OAAO,SAAS,UAAU;EACtD,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;AACpB,QAAM,MAAM,OAAO,EAAE,QAAQ,MAAM,YAAY,CAAC;GAChD;AAEF,SAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,UAAU;EAC3D,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;EACpB,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,UAAQ,IAAI,MAAM,IAAI;AACtB,QAAM,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;GAClC;AAEF,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BR,MAAa,QAAQ,OAAO,OAAO,aAAa;EAC7C,OAAO,IAAI,gBAAgB,GAAG;EAC9B,OAAO,IAAI,uBAAuB,GAAG;CACvC,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/fastify/index.ts"],"sourcesContent":["import type { FastifyPluginCallback, FastifyRequest } from 'fastify'\nimport type { AuditableLogger } from '../audit'\nimport { registerDiskPrettyErrorSnippetReader } from '../shared/register-disk-snippet'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'plugin context. Make sure app.register(evlog) is called before your routes.',\n)\n\nvoid registerDiskPrettyErrorSnippetReader()\n\nexport type EvlogFastifyOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n // @ts-expect-error intentionally overrides Fastify's built-in pino logger with evlog's AuditableLogger\n log: AuditableLogger\n }\n}\n\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n}\n\nconst integration = defineFrameworkIntegration<FastifyRequest>({\n name: 'fastify',\n extractRequest: (req) => ({\n method: req.method,\n path: new URL(req.url, 'http://localhost').pathname,\n headers: req.headers,\n requestId: typeof req.headers['x-request-id'] === 'string' ? req.headers['x-request-id'] : undefined,\n }),\n attachLogger: (req, logger) => {\n // @ts-expect-error evlog replaces Fastify's built-in pino logger with RequestLogger\n req.log = logger\n },\n storage,\n})\n\nconst evlogPlugin: FastifyPluginCallback<EvlogFastifyOptions> = (fastify, options, done) => {\n const emitted = new WeakSet<object>()\n const requestState = new WeakMap<object, RequestState>()\n\n fastify.addHook('onRequest', (request, _reply, next) => {\n const { finish, skipped, runWith } = integration.start(request, options)\n if (skipped) {\n next()\n return\n }\n requestState.set(request, { finish })\n void runWith(() => next())\n })\n\n fastify.addHook('onResponse', async (request, reply) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n await state.finish({ status: reply.statusCode })\n })\n\n fastify.addHook('onError', async (request, _reply, error) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n const err = error instanceof Error ? error : new Error(String(error))\n request.log.error(err)\n await state.finish({ error: err })\n })\n\n done()\n}\n\n/**\n * Create an evlog plugin for Fastify.\n *\n * Plugin metadata symbols (`skip-override`, `fastify.display-name`) are attached\n * for @fastify/autoload — they are not part of `FastifyPluginCallback`.\n *\n * @example\n * ```ts\n * import Fastify from 'fastify'\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/fastify'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'fastify-api' } })\n *\n * const app = Fastify()\n * await app.register(evlog, {\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n */\nexport const evlog = Object.assign(evlogPlugin, {\n [Symbol.for('skip-override')]: true,\n [Symbol.for('fastify.display-name')]: 'evlog',\n})\n"],"mappings":";;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,8EACD;AAEI,sCAAsC;AAiB3C,MAAM,cAAc,2BAA2C;CAC7D,MAAM;CACN,iBAAiB,SAAS;EACxB,QAAQ,IAAI;EACZ,MAAM,IAAI,IAAI,IAAI,KAAK,mBAAmB,CAAC;EAC3C,SAAS,IAAI;EACb,WAAW,OAAO,IAAI,QAAQ,oBAAoB,WAAW,IAAI,QAAQ,kBAAkB,KAAA;EAC5F;CACD,eAAe,KAAK,WAAW;AAE7B,MAAI,MAAM;;CAEZ;CACD,CAAC;AAEF,MAAM,eAA2D,SAAS,SAAS,SAAS;CAC1F,MAAM,0BAAU,IAAI,SAAiB;CACrC,MAAM,+BAAe,IAAI,SAA+B;AAExD,SAAQ,QAAQ,cAAc,SAAS,QAAQ,SAAS;EACtD,MAAM,EAAE,QAAQ,SAAS,YAAY,YAAY,MAAM,SAAS,QAAQ;AACxE,MAAI,SAAS;AACX,SAAM;AACN;;AAEF,eAAa,IAAI,SAAS,EAAE,QAAQ,CAAC;AAChC,gBAAc,MAAM,CAAC;GAC1B;AAEF,SAAQ,QAAQ,cAAc,OAAO,SAAS,UAAU;EACtD,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;AACpB,QAAM,MAAM,OAAO,EAAE,QAAQ,MAAM,YAAY,CAAC;GAChD;AAEF,SAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,UAAU;EAC3D,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;EACpB,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,UAAQ,IAAI,MAAM,IAAI;AACtB,QAAM,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;GAClC;AAEF,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BR,MAAa,QAAQ,OAAO,OAAO,aAAa;EAC7C,OAAO,IAAI,gBAAgB,GAAG;EAC9B,OAAO,IAAI,uBAAuB,GAAG;CACvC,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { _ as createRequestLogger, y as getGlobalDrain } from "./audit-BXCYMjcC.mjs";
2
+ import { t as extractErrorStatus } from "./errors-DA0cyr8q.mjs";
3
+ import { r as runEnrichAndDrain } from "./middleware-Cdebyfdt.mjs";
4
+ //#region src/shared/fork.ts
5
+ /**
6
+ * Attach {@link RequestLogger.fork} to a request logger. Replaces any existing `fork`.
7
+ */
8
+ function attachForkToLogger(storage, parent, middlewareOptions, lifecycle) {
9
+ const log = parent;
10
+ log.fork = (label, fn) => {
11
+ forkBackgroundLogger({
12
+ storage,
13
+ parent,
14
+ middlewareOptions,
15
+ label,
16
+ fn,
17
+ lifecycle
18
+ });
19
+ };
20
+ }
21
+ /**
22
+ * Run background work under a child request logger so `useLogger()` resolves to the
23
+ * child while `fn` runs. The child emits a separate wide event when `fn` settles,
24
+ * with `operation` and `_parentRequestId` set for correlation.
25
+ *
26
+ * @beta Part of `evlog/toolkit` — used by framework integrations; prefer `log.fork()`
27
+ * on the request logger when available.
28
+ */
29
+ function forkBackgroundLogger(options) {
30
+ const { storage, parent, middlewareOptions, label, fn, lifecycle } = options;
31
+ const parentCtx = parent.getContext();
32
+ const parentRequestId = parentCtx.requestId;
33
+ if (typeof parentRequestId !== "string" || parentRequestId.length === 0) throw new Error("[evlog] log.fork() requires the parent logger to have a requestId. Ensure the request was created by evlog middleware.");
34
+ const method = String(parentCtx.method ?? middlewareOptions.method);
35
+ const path = String(parentCtx.path ?? middlewareOptions.path);
36
+ const child = createRequestLogger({
37
+ method,
38
+ path,
39
+ requestId: crypto.randomUUID()
40
+ }, { _deferDrain: true });
41
+ child.set({
42
+ operation: label,
43
+ _parentRequestId: parentRequestId
44
+ });
45
+ const childRequestInfo = {
46
+ method,
47
+ path,
48
+ requestId: child.getContext().requestId
49
+ };
50
+ storage.run(child, () => {
51
+ lifecycle?.onChildEnter?.(child);
52
+ Promise.resolve().then(() => fn()).then(async () => {
53
+ const emittedEvent = child.emit();
54
+ const ctxStatus = child.getContext().status;
55
+ const status = emittedEvent?.status ?? (typeof ctxStatus === "number" ? ctxStatus : void 0);
56
+ if (emittedEvent && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())) await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status);
57
+ }).catch(async (err) => {
58
+ const error = err instanceof Error ? err : new Error(String(err));
59
+ child.error(error);
60
+ child.set({ status: extractErrorStatus(error) });
61
+ const emittedEvent = child.emit();
62
+ const status = extractErrorStatus(error);
63
+ if (emittedEvent && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())) await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status);
64
+ }).finally(() => {
65
+ lifecycle?.onChildExit?.(child);
66
+ });
67
+ });
68
+ }
69
+ //#endregion
70
+ export { forkBackgroundLogger as n, attachForkToLogger as t };
71
+
72
+ //# sourceMappingURL=fork-S9gpZmF8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork-S9gpZmF8.mjs","names":[],"sources":["../src/shared/fork.ts"],"sourcesContent":["import type { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\nimport { createRequestLogger, getGlobalDrain } from '../logger'\nimport { extractErrorStatus } from './errors'\nimport type { MiddlewareLoggerOptions } from './middleware'\nimport { runEnrichAndDrain } from './middleware'\n\n/**\n * Optional hooks for integrations that track active loggers (e.g. Elysia `activeLoggers`).\n */\nexport interface ForkLifecycle {\n /** Called after the child logger is installed in storage, before `fn` runs. */\n onChildEnter?: (child: RequestLogger) => void\n /** Called after the child has finished (emit + enrich/drain), success or failure. */\n onChildExit?: (child: RequestLogger) => void\n}\n\n/**\n * Options for {@link forkBackgroundLogger}.\n *\n * @beta Part of `evlog/toolkit`\n */\nexport interface ForkBackgroundLoggerOptions {\n storage: AsyncLocalStorage<RequestLogger>\n parent: RequestLogger\n middlewareOptions: MiddlewareLoggerOptions\n label: string\n fn: () => void | Promise<void>\n lifecycle?: ForkLifecycle\n}\n\n/**\n * Attach {@link RequestLogger.fork} to a request logger. Replaces any existing `fork`.\n */\nexport function attachForkToLogger(\n storage: AsyncLocalStorage<RequestLogger>,\n parent: RequestLogger,\n middlewareOptions: MiddlewareLoggerOptions,\n lifecycle?: ForkLifecycle,\n): void {\n const log = parent as RequestLogger & { fork?: (label: string, fn: () => void | Promise<void>) => void }\n log.fork = (label: string, fn: () => void | Promise<void>) => {\n forkBackgroundLogger({ storage, parent, middlewareOptions, label, fn, lifecycle })\n }\n}\n\n/**\n * Run background work under a child request logger so `useLogger()` resolves to the\n * child while `fn` runs. The child emits a separate wide event when `fn` settles,\n * with `operation` and `_parentRequestId` set for correlation.\n *\n * @beta Part of `evlog/toolkit` — used by framework integrations; prefer `log.fork()`\n * on the request logger when available.\n */\nexport function forkBackgroundLogger(options: ForkBackgroundLoggerOptions): void {\n const { storage, parent, middlewareOptions, label, fn, lifecycle } = options\n\n const parentCtx = parent.getContext() as Record<string, unknown>\n const parentRequestId = parentCtx.requestId\n if (typeof parentRequestId !== 'string' || parentRequestId.length === 0) {\n throw new Error(\n '[evlog] log.fork() requires the parent logger to have a requestId. '\n + 'Ensure the request was created by evlog middleware.',\n )\n }\n\n const method = String(parentCtx.method ?? middlewareOptions.method)\n const path = String(parentCtx.path ?? middlewareOptions.path)\n\n const child = createRequestLogger(\n {\n method,\n path,\n requestId: crypto.randomUUID(),\n },\n { _deferDrain: true },\n )\n\n child.set({\n operation: label,\n _parentRequestId: parentRequestId,\n })\n\n const childRequestInfo = {\n method,\n path,\n requestId: child.getContext().requestId as string,\n }\n\n storage.run(child, () => {\n lifecycle?.onChildEnter?.(child)\n void Promise.resolve()\n .then(() => fn())\n .then(async () => {\n const emittedEvent = child.emit()\n const ctxStatus = child.getContext().status\n const status = (emittedEvent?.status\n ?? (typeof ctxStatus === 'number' ? ctxStatus : undefined)) as number | undefined\n if (\n emittedEvent\n && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())\n ) {\n await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status)\n }\n })\n .catch(async (err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err))\n child.error(error)\n child.set({ status: extractErrorStatus(error) })\n const emittedEvent = child.emit()\n const status = extractErrorStatus(error)\n if (\n emittedEvent\n && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())\n ) {\n await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status)\n }\n })\n .finally(() => {\n lifecycle?.onChildExit?.(child)\n })\n })\n}\n"],"mappings":";;;;;;;AAkCA,SAAgB,mBACd,SACA,QACA,mBACA,WACM;CACN,MAAM,MAAM;AACZ,KAAI,QAAQ,OAAe,OAAmC;AAC5D,uBAAqB;GAAE;GAAS;GAAQ;GAAmB;GAAO;GAAI;GAAW,CAAC;;;;;;;;;;;AAYtF,SAAgB,qBAAqB,SAA4C;CAC/E,MAAM,EAAE,SAAS,QAAQ,mBAAmB,OAAO,IAAI,cAAc;CAErE,MAAM,YAAY,OAAO,YAAY;CACrC,MAAM,kBAAkB,UAAU;AAClC,KAAI,OAAO,oBAAoB,YAAY,gBAAgB,WAAW,EACpE,OAAM,IAAI,MACR,yHAED;CAGH,MAAM,SAAS,OAAO,UAAU,UAAU,kBAAkB,OAAO;CACnE,MAAM,OAAO,OAAO,UAAU,QAAQ,kBAAkB,KAAK;CAE7D,MAAM,QAAQ,oBACZ;EACE;EACA;EACA,WAAW,OAAO,YAAY;EAC/B,EACD,EAAE,aAAa,MAAM,CACtB;AAED,OAAM,IAAI;EACR,WAAW;EACX,kBAAkB;EACnB,CAAC;CAEF,MAAM,mBAAmB;EACvB;EACA;EACA,WAAW,MAAM,YAAY,CAAC;EAC/B;AAED,SAAQ,IAAI,aAAa;AACvB,aAAW,eAAe,MAAM;AAC3B,UAAQ,SAAS,CACnB,WAAW,IAAI,CAAC,CAChB,KAAK,YAAY;GAChB,MAAM,eAAe,MAAM,MAAM;GACjC,MAAM,YAAY,MAAM,YAAY,CAAC;GACrC,MAAM,SAAU,cAAc,WACxB,OAAO,cAAc,WAAW,YAAY,KAAA;AAClD,OACE,iBACI,kBAAkB,UAAU,kBAAkB,SAAS,gBAAgB,EAE3E,OAAM,kBAAkB,cAAc,mBAAmB,kBAAkB,OAAO;IAEpF,CACD,MAAM,OAAO,QAAiB;GAC7B,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;AACjE,SAAM,MAAM,MAAM;AAClB,SAAM,IAAI,EAAE,QAAQ,mBAAmB,MAAM,EAAE,CAAC;GAChD,MAAM,eAAe,MAAM,MAAM;GACjC,MAAM,SAAS,mBAAmB,MAAM;AACxC,OACE,iBACI,kBAAkB,UAAU,kBAAkB,SAAS,gBAAgB,EAE3E,OAAM,kBAAkB,cAAc,mBAAmB,kBAAkB,OAAO;IAEpF,CACD,cAAc;AACb,cAAW,cAAc,MAAM;IAC/B;GACJ"}
@@ -1,5 +1,5 @@
1
- import { rt as RequestLogger } from "../audit-D7v6JHj0.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-B_k4Mrzg.mjs";
1
+ import { l as AuditableLogger } from "../audit-BZrUvjfW.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-fbtEs6bq.mjs";
3
3
  import { MiddlewareHandler } from "hono";
4
4
 
5
5
  //#region src/hono/index.d.ts
@@ -20,7 +20,7 @@ type EvlogHonoOptions = BaseEvlogOptions;
20
20
  */
21
21
  type EvlogVariables = {
22
22
  Variables: {
23
- log: RequestLogger;
23
+ log: AuditableLogger;
24
24
  };
25
25
  };
26
26
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/hono/index.ts"],"mappings":";;;;;KAMY,gBAAA,GAAmB,gBAAA;;AAA/B;;;;;AAgBA;;;;;;;;KAAY,cAAA;EAAmB,SAAA;IAAa,GAAA,EAAK,aAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAiCjC,KAAA,CAAM,OAAA,GAAS,gBAAA,GAAwB,iBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/hono/index.ts"],"mappings":";;;;;KAMY,gBAAA,GAAmB,gBAAA;;AAA/B;;;;;AAgBA;;;;;;;;KAAY,cAAA;EAAmB,SAAA;IAAa,GAAA,EAAK,eAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAiCjC,KAAA,CAAM,OAAA,GAAS,gBAAA,GAAwB,iBAAA"}
@@ -1,5 +1,5 @@
1
1
  import { r as shouldDeferEmitForResponse } from "../streamResponse-CmQ3qUbF.mjs";
2
- import { t as defineFrameworkIntegration } from "../integration-DYp2uw8O.mjs";
2
+ import { t as defineFrameworkIntegration } from "../integration-CeL90DtN.mjs";
3
3
  //#region src/hono/index.ts
4
4
  const integration = defineFrameworkIntegration({
5
5
  name: "hono",
@@ -41,11 +41,8 @@ function evlog(options = {}) {
41
41
  try {
42
42
  await next();
43
43
  if (shouldDeferEmitForResponse(c.res)) {
44
- const response = new Response(c.res.body, {
45
- status: c.res.status,
46
- headers: c.res.headers
47
- });
48
- return finishResponse(response, { status: response.status });
44
+ c.res = await finishResponse(c.res, { status: c.res.status });
45
+ return;
49
46
  }
50
47
  await finish({ status: c.res.status });
51
48
  } catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono'\nimport type { RequestLogger } from '../types'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { shouldDeferEmitForResponse } from '../shared/streamResponse'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\nconst integration = defineFrameworkIntegration<Context>({\n name: 'hono',\n extractRequest: (c) => ({\n method: c.req.method,\n path: c.req.path,\n headers: c.req.raw.headers,\n requestId: c.req.header('x-request-id'),\n }),\n attachLogger: (c, logger) => {\n c.set('log', logger)\n },\n})\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { skipped, finish, finishResponse } = integration.start(c, options)\n if (skipped) {\n await next()\n return\n }\n try {\n await next()\n if (shouldDeferEmitForResponse(c.res)) {\n const response = new Response(c.res.body, {\n status: c.res.status,\n headers: c.res.headers,\n })\n return finishResponse(response, { status: response.status })\n }\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;AAwBA,MAAM,cAAc,2BAAoC;CACtD,MAAM;CACN,iBAAiB,OAAO;EACtB,QAAQ,EAAE,IAAI;EACd,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI,IAAI;EACnB,WAAW,EAAE,IAAI,OAAO,eAAe;EACxC;CACD,eAAe,GAAG,WAAW;AAC3B,IAAE,IAAI,OAAO,OAAO;;CAEvB,CAAC;;;;;;;;;;;;;;;;;;;AAoBF,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,SAAS,QAAQ,mBAAmB,YAAY,MAAM,GAAG,QAAQ;AACzE,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAEF,MAAI;AACF,SAAM,MAAM;AACZ,OAAI,2BAA2B,EAAE,IAAI,EAAE;IACrC,MAAM,WAAW,IAAI,SAAS,EAAE,IAAI,MAAM;KACxC,QAAQ,EAAE,IAAI;KACd,SAAS,EAAE,IAAI;KAChB,CAAC;AACF,WAAO,eAAe,UAAU,EAAE,QAAQ,SAAS,QAAQ,CAAC;;AAE9D,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { Context, MiddlewareHandler } from 'hono'\nimport type { AuditableLogger } from '../audit'\nimport { defineFrameworkIntegration } from '../shared/integration'\nimport type { BaseEvlogOptions } from '../shared/middleware'\nimport { shouldDeferEmitForResponse } from '../shared/streamResponse'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: AuditableLogger } }\n\nconst integration = defineFrameworkIntegration<Context>({\n name: 'hono',\n extractRequest: (c) => ({\n method: c.req.method,\n path: c.req.path,\n headers: c.req.raw.headers,\n requestId: c.req.header('x-request-id'),\n }),\n attachLogger: (c, logger) => {\n c.set('log', logger)\n },\n})\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { skipped, finish, finishResponse } = integration.start(c, options)\n if (skipped) {\n await next()\n return\n }\n try {\n await next()\n if (shouldDeferEmitForResponse(c.res)) {\n // Assign directly Hono's compose ignores middleware return values when\n // context.finalized is already true, so returning the wrapped response\n // would leave c.res with a locked body stream.\n c.res = await finishResponse(c.res, { status: c.res.status })\n return\n }\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;AAwBA,MAAM,cAAc,2BAAoC;CACtD,MAAM;CACN,iBAAiB,OAAO;EACtB,QAAQ,EAAE,IAAI;EACd,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI,IAAI;EACnB,WAAW,EAAE,IAAI,OAAO,eAAe;EACxC;CACD,eAAe,GAAG,WAAW;AAC3B,IAAE,IAAI,OAAO,OAAO;;CAEvB,CAAC;;;;;;;;;;;;;;;;;;;AAoBF,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,SAAS,QAAQ,mBAAmB,YAAY,MAAM,GAAG,QAAQ;AACzE,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAEF,MAAI;AACF,SAAM,MAAM;AACZ,OAAI,2BAA2B,EAAE,IAAI,EAAE;AAIrC,MAAE,MAAM,MAAM,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;AAC7D;;AAEF,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
@@ -1,4 +1,4 @@
1
- import { n as version } from "./package-CNV_CXs8.mjs";
1
+ import { n as version } from "./package-Drb3wqqt.mjs";
2
2
  //#region src/shared/http.ts
3
3
  /**
4
4
  * Minimal HTTP transport for drain adapters: abort-based timeouts, exponential
@@ -79,4 +79,4 @@ async function httpPost({ url, headers, body, timeout, label, retries = 2, userA
79
79
  //#endregion
80
80
  export { withEvlogIdentityHeaders as i, EVLOG_VERSION as n, httpPost as r, EVLOG_USER_AGENT as t };
81
81
 
82
- //# sourceMappingURL=http-ChVS9GYc.mjs.map
82
+ //# sourceMappingURL=http-pKfd8UDu.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"http-ChVS9GYc.mjs","names":["PKG_VERSION"],"sources":["../src/shared/http.ts"],"sourcesContent":["/**\n * Minimal HTTP transport for drain adapters: abort-based timeouts, exponential\n * backoff on `5xx` / network errors, response bodies truncated in error messages.\n *\n * Identifies every outgoing request as coming from evlog via:\n * - `User-Agent: evlog/<version>` (Node / server runtimes only — browsers strip this)\n * - `X-Evlog-Source: <source>` when {@link HttpPostOptions.source} is set\n */\n\nimport { version as PKG_VERSION } from '../../package.json'\n\n/** Build-time evlog package version, e.g. `2.16.0`. */\nexport const EVLOG_VERSION: string = PKG_VERSION\n\n/** Default `User-Agent` value injected into outgoing drain requests. */\nexport const EVLOG_USER_AGENT = `evlog/${EVLOG_VERSION}`\n\nexport interface HttpPostOptions {\n url: string\n /** Caller is responsible for `Content-Type`. */\n headers: Record<string, string>\n /** Pre-serialized request body. */\n body: string\n /** Abort the request after this many milliseconds. */\n timeout: number\n /** Prefix used in error messages. */\n label: string\n /**\n * Retries network errors, aborts, and `5xx` responses with exponential backoff.\n * @default 2\n */\n retries?: number\n /**\n * Override the default `User-Agent: evlog/<version>` header. Pass `false` or\n * an empty string to suppress it entirely (e.g. when the underlying transport\n * forbids overriding `User-Agent`).\n */\n userAgent?: string | false\n /**\n * When set, sends `X-Evlog-Source: <source>` so the receiving system can\n * distinguish evlog traffic from other clients. Typically the adapter name\n * (`axiom`, `datadog`, ...) or `client` for browser-originated drains.\n */\n source?: string\n}\n\nfunction hasHeader(headers: Record<string, string>, target: string): boolean {\n const lower = target.toLowerCase()\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lower) return true\n }\n return false\n}\n\n/**\n * Returns a copy of `headers` with evlog identity headers injected when\n * absent. Caller-provided values always win.\n *\n * @internal Exposed for tests. Use {@link httpPost} from drains.\n */\nexport function withEvlogIdentityHeaders(\n headers: Record<string, string>,\n { userAgent, source }: { userAgent?: string | false; source?: string } = {},\n): Record<string, string> {\n const out = { ...headers }\n if (userAgent !== false && !hasHeader(out, 'user-agent')) {\n const ua = typeof userAgent === 'string' && userAgent.length > 0 ? userAgent : EVLOG_USER_AGENT\n out['User-Agent'] = ua\n }\n if (source && !hasHeader(out, 'x-evlog-source')) {\n out['X-Evlog-Source'] = source\n }\n return out\n}\n\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DOMException && error.name === 'AbortError') return true\n if (error instanceof TypeError) return true\n if (error instanceof Error) {\n const match = error.message.match(/API error: (\\d+)/)\n if (match) return Number.parseInt(match[1]) >= 500\n }\n return false\n}\n\n/**\n * POST a body with timeout + retry. Throws label-prefixed errors with a\n * truncated response body. Safe to call from any drain `send()`.\n */\nexport async function httpPost({ url, headers, body, timeout, label, retries = 2, userAgent, source }: HttpPostOptions): Promise<void> {\n const normalizedRetries = Number.isFinite(retries) && retries >= 0 ? Math.floor(retries) : 2\n const finalHeaders = withEvlogIdentityHeaders(headers, { userAgent, source })\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= normalizedRetries; attempt++) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: finalHeaders,\n body,\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => 'Unknown error')\n const safeText = text.length > 200 ? `${text.slice(0, 200)}...[truncated]` : text\n throw new Error(`${label} API error: ${response.status} ${response.statusText} - ${safeText}`)\n }\n\n clearTimeout(timeoutId)\n return\n } catch (error) {\n clearTimeout(timeoutId)\n\n if (error instanceof DOMException && error.name === 'AbortError') {\n lastError = new Error(`${label} request timed out after ${timeout}ms`)\n } else {\n lastError = error as Error\n }\n\n if (!isRetryable(error) || attempt === normalizedRetries) {\n throw lastError\n }\n\n await new Promise<void>(r => setTimeout(r, 200 * 2 ** attempt))\n }\n }\n\n throw lastError!\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,gBAAwBA;;AAGrC,MAAa,mBAAmB,SAAS;AA+BzC,SAAS,UAAU,SAAiC,QAAyB;CAC3E,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,CACpC,KAAI,IAAI,aAAa,KAAK,MAAO,QAAO;AAE1C,QAAO;;;;;;;;AAST,SAAgB,yBACd,SACA,EAAE,WAAW,WAA4D,EAAE,EACnD;CACxB,MAAM,MAAM,EAAE,GAAG,SAAS;AAC1B,KAAI,cAAc,SAAS,CAAC,UAAU,KAAK,aAAa,CAEtD,KAAI,gBADO,OAAO,cAAc,YAAY,UAAU,SAAS,IAAI,YAAY;AAGjF,KAAI,UAAU,CAAC,UAAU,KAAK,iBAAiB,CAC7C,KAAI,oBAAoB;AAE1B,QAAO;;AAGT,SAAS,YAAY,OAAyB;AAC5C,KAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAAc,QAAO;AACzE,KAAI,iBAAiB,UAAW,QAAO;AACvC,KAAI,iBAAiB,OAAO;EAC1B,MAAM,QAAQ,MAAM,QAAQ,MAAM,mBAAmB;AACrD,MAAI,MAAO,QAAO,OAAO,SAAS,MAAM,GAAG,IAAI;;AAEjD,QAAO;;;;;;AAOT,eAAsB,SAAS,EAAE,KAAK,SAAS,MAAM,SAAS,OAAO,UAAU,GAAG,WAAW,UAA0C;CACrI,MAAM,oBAAoB,OAAO,SAAS,QAAQ,IAAI,WAAW,IAAI,KAAK,MAAM,QAAQ,GAAG;CAC3F,MAAM,eAAe,yBAAyB,SAAS;EAAE;EAAW;EAAQ,CAAC;CAE7E,IAAI;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,mBAAmB,WAAW;EAC7D,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,QAAQ;AAE/D,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ;IACR,SAAS;IACT;IACA,QAAQ,WAAW;IACpB,CAAC;AAEF,OAAI,CAAC,SAAS,IAAI;IAChB,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,YAAY,gBAAgB;IAC/D,MAAM,WAAW,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC,kBAAkB;AAC7E,UAAM,IAAI,MAAM,GAAG,MAAM,cAAc,SAAS,OAAO,GAAG,SAAS,WAAW,KAAK,WAAW;;AAGhG,gBAAa,UAAU;AACvB;WACO,OAAO;AACd,gBAAa,UAAU;AAEvB,OAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAClD,6BAAY,IAAI,MAAM,GAAG,MAAM,2BAA2B,QAAQ,IAAI;OAEtE,aAAY;AAGd,OAAI,CAAC,YAAY,MAAM,IAAI,YAAY,kBACrC,OAAM;AAGR,SAAM,IAAI,SAAc,MAAK,WAAW,GAAG,MAAM,KAAK,QAAQ,CAAC;;;AAInE,OAAM"}
1
+ {"version":3,"file":"http-pKfd8UDu.mjs","names":["PKG_VERSION"],"sources":["../src/shared/http.ts"],"sourcesContent":["/**\n * Minimal HTTP transport for drain adapters: abort-based timeouts, exponential\n * backoff on `5xx` / network errors, response bodies truncated in error messages.\n *\n * Identifies every outgoing request as coming from evlog via:\n * - `User-Agent: evlog/<version>` (Node / server runtimes only — browsers strip this)\n * - `X-Evlog-Source: <source>` when {@link HttpPostOptions.source} is set\n */\n\nimport { version as PKG_VERSION } from '../../package.json'\n\n/** Build-time evlog package version, e.g. `2.16.0`. */\nexport const EVLOG_VERSION: string = PKG_VERSION\n\n/** Default `User-Agent` value injected into outgoing drain requests. */\nexport const EVLOG_USER_AGENT = `evlog/${EVLOG_VERSION}`\n\nexport interface HttpPostOptions {\n url: string\n /** Caller is responsible for `Content-Type`. */\n headers: Record<string, string>\n /** Pre-serialized request body. */\n body: string\n /** Abort the request after this many milliseconds. */\n timeout: number\n /** Prefix used in error messages. */\n label: string\n /**\n * Retries network errors, aborts, and `5xx` responses with exponential backoff.\n * @default 2\n */\n retries?: number\n /**\n * Override the default `User-Agent: evlog/<version>` header. Pass `false` or\n * an empty string to suppress it entirely (e.g. when the underlying transport\n * forbids overriding `User-Agent`).\n */\n userAgent?: string | false\n /**\n * When set, sends `X-Evlog-Source: <source>` so the receiving system can\n * distinguish evlog traffic from other clients. Typically the adapter name\n * (`axiom`, `datadog`, ...) or `client` for browser-originated drains.\n */\n source?: string\n}\n\nfunction hasHeader(headers: Record<string, string>, target: string): boolean {\n const lower = target.toLowerCase()\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === lower) return true\n }\n return false\n}\n\n/**\n * Returns a copy of `headers` with evlog identity headers injected when\n * absent. Caller-provided values always win.\n *\n * @internal Exposed for tests. Use {@link httpPost} from drains.\n */\nexport function withEvlogIdentityHeaders(\n headers: Record<string, string>,\n { userAgent, source }: { userAgent?: string | false; source?: string } = {},\n): Record<string, string> {\n const out = { ...headers }\n if (userAgent !== false && !hasHeader(out, 'user-agent')) {\n const ua = typeof userAgent === 'string' && userAgent.length > 0 ? userAgent : EVLOG_USER_AGENT\n out['User-Agent'] = ua\n }\n if (source && !hasHeader(out, 'x-evlog-source')) {\n out['X-Evlog-Source'] = source\n }\n return out\n}\n\nfunction isRetryable(error: unknown): boolean {\n if (error instanceof DOMException && error.name === 'AbortError') return true\n if (error instanceof TypeError) return true\n if (error instanceof Error) {\n const match = error.message.match(/API error: (\\d+)/)\n if (match) return Number.parseInt(match[1]) >= 500\n }\n return false\n}\n\n/**\n * POST a body with timeout + retry. Throws label-prefixed errors with a\n * truncated response body. Safe to call from any drain `send()`.\n */\nexport async function httpPost({ url, headers, body, timeout, label, retries = 2, userAgent, source }: HttpPostOptions): Promise<void> {\n const normalizedRetries = Number.isFinite(retries) && retries >= 0 ? Math.floor(retries) : 2\n const finalHeaders = withEvlogIdentityHeaders(headers, { userAgent, source })\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= normalizedRetries; attempt++) {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers: finalHeaders,\n body,\n signal: controller.signal,\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => 'Unknown error')\n const safeText = text.length > 200 ? `${text.slice(0, 200)}...[truncated]` : text\n throw new Error(`${label} API error: ${response.status} ${response.statusText} - ${safeText}`)\n }\n\n clearTimeout(timeoutId)\n return\n } catch (error) {\n clearTimeout(timeoutId)\n\n if (error instanceof DOMException && error.name === 'AbortError') {\n lastError = new Error(`${label} request timed out after ${timeout}ms`)\n } else {\n lastError = error as Error\n }\n\n if (!isRetryable(error) || attempt === normalizedRetries) {\n throw lastError\n }\n\n await new Promise<void>(r => setTimeout(r, 200 * 2 ** attempt))\n }\n }\n\n throw lastError!\n}\n"],"mappings":";;;;;;;;;;;AAYA,MAAa,gBAAwBA;;AAGrC,MAAa,mBAAmB,SAAS;AA+BzC,SAAS,UAAU,SAAiC,QAAyB;CAC3E,MAAM,QAAQ,OAAO,aAAa;AAClC,MAAK,MAAM,OAAO,OAAO,KAAK,QAAQ,CACpC,KAAI,IAAI,aAAa,KAAK,MAAO,QAAO;AAE1C,QAAO;;;;;;;;AAST,SAAgB,yBACd,SACA,EAAE,WAAW,WAA4D,EAAE,EACnD;CACxB,MAAM,MAAM,EAAE,GAAG,SAAS;AAC1B,KAAI,cAAc,SAAS,CAAC,UAAU,KAAK,aAAa,CAEtD,KAAI,gBADO,OAAO,cAAc,YAAY,UAAU,SAAS,IAAI,YAAY;AAGjF,KAAI,UAAU,CAAC,UAAU,KAAK,iBAAiB,CAC7C,KAAI,oBAAoB;AAE1B,QAAO;;AAGT,SAAS,YAAY,OAAyB;AAC5C,KAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAAc,QAAO;AACzE,KAAI,iBAAiB,UAAW,QAAO;AACvC,KAAI,iBAAiB,OAAO;EAC1B,MAAM,QAAQ,MAAM,QAAQ,MAAM,mBAAmB;AACrD,MAAI,MAAO,QAAO,OAAO,SAAS,MAAM,GAAG,IAAI;;AAEjD,QAAO;;;;;;AAOT,eAAsB,SAAS,EAAE,KAAK,SAAS,MAAM,SAAS,OAAO,UAAU,GAAG,WAAW,UAA0C;CACrI,MAAM,oBAAoB,OAAO,SAAS,QAAQ,IAAI,WAAW,IAAI,KAAK,MAAM,QAAQ,GAAG;CAC3F,MAAM,eAAe,yBAAyB,SAAS;EAAE;EAAW;EAAQ,CAAC;CAE7E,IAAI;AAEJ,MAAK,IAAI,UAAU,GAAG,WAAW,mBAAmB,WAAW;EAC7D,MAAM,aAAa,IAAI,iBAAiB;EACxC,MAAM,YAAY,iBAAiB,WAAW,OAAO,EAAE,QAAQ;AAE/D,MAAI;GACF,MAAM,WAAW,MAAM,MAAM,KAAK;IAChC,QAAQ;IACR,SAAS;IACT;IACA,QAAQ,WAAW;IACpB,CAAC;AAEF,OAAI,CAAC,SAAS,IAAI;IAChB,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,YAAY,gBAAgB;IAC/D,MAAM,WAAW,KAAK,SAAS,MAAM,GAAG,KAAK,MAAM,GAAG,IAAI,CAAC,kBAAkB;AAC7E,UAAM,IAAI,MAAM,GAAG,MAAM,cAAc,SAAS,OAAO,GAAG,SAAS,WAAW,KAAK,WAAW;;AAGhG,gBAAa,UAAU;AACvB;WACO,OAAO;AACd,gBAAa,UAAU;AAEvB,OAAI,iBAAiB,gBAAgB,MAAM,SAAS,aAClD,6BAAY,IAAI,MAAM,GAAG,MAAM,2BAA2B,QAAQ,IAAI;OAEtE,aAAY;AAGd,OAAI,CAAC,YAAY,MAAM,IAAI,YAAY,kBACrC,OAAM;AAGR,SAAM,IAAI,SAAc,MAAK,WAAW,GAAG,MAAM,KAAK,QAAQ,CAAC;;;AAInE,OAAM"}
package/dist/http.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { B as DrainContext } from "./audit-D7v6JHj0.mjs";
1
+ import { U as DrainContext } from "./audit-BZrUvjfW.mjs";
2
2
  import { DrainPipelineOptions, PipelineDrainFn } from "./pipeline.mjs";
3
3
 
4
4
  //#region src/http.d.ts
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { $ as RedactConfig, A as AuditActionDefinition, B as DrainContext, C as buildAuditFields, Ct as enricherPlugin, D as withAudit, E as signed, F as AuditPatchOp, G as FieldContext, H as EnvironmentContext, I as AuditSeverity, J as InternalFields, K as H3EventContext, L as AuditTarget, M as AuditChanges, N as AuditFields, O as withAuditMethods, P as AuditLoggerMethod, Q as ParsedError, R as BaseWideEvent, S as auditRedactPreset, St as drainPlugin, T as mockAudit, U as ErrorCode, V as EnrichContext, W as ErrorOptions, X as LogLevel, Y as Log, Z as LoggerConfig, _ as WithAuditOptions, _t as PluginSetupContext, a as AuditInput, b as auditEnricher, c as AuditOnlyOptions, ct as ServerEvent, d as DefinedAuditAction, dt as TransportConfig, et as RegisteredAuditCatalogs, f as DrainFn, ft as WideEvent, g as WithAuditContext, gt as PluginRunner, h as SignedOptions, ht as EvlogPlugin, i as AuditEnricherOptions, it as RequestLoggerOptions, j as AuditActor, k as AuditAction, l as AuditableLogger, lt as TailSamplingCondition, m as SignedChainState, mt as ClientLogContext, n as AuditDeniedError, o as AuditMatcher, ot as SamplingConfig, p as MockAudit, q as IngestPayload, r as AuditDiffOptions, rt as RequestLogger, s as AuditMethod, st as SamplingRates, t as AUDIT_SCHEMA_VERSION, tt as RegisteredErrorCatalogs, u as DefineAuditActionOptions, ut as TailSamplingContext, v as audit, vt as RequestFinishContext, w as defineAuditAction, x as auditOnly, xt as definePlugin, y as auditDiff, yt as RequestLifecycleContext, z as DeepPartial } from "./audit-D7v6JHj0.mjs";
2
- import { n as createError, t as EvlogError } from "./error-CpghjrkY.mjs";
3
- import { a as DefinedError, c as ErrorCatalogMap, d as defineAuditCatalog, f as defineError, i as DefinedCatalogAudit, l as ErrorFactoryOpts, n as AuditCatalogEntry, o as ErrorCatalog, p as defineErrorCatalog, r as AuditCatalogMap, s as ErrorCatalogEntry, t as AuditCatalog, u as ErrorFactoryOverrides } from "./index-EvnrXvQM.mjs";
4
- import { a as getEnvironment, c as initLogger, i as createRequestLogger, l as isEnabled, m as shouldKeep, n as _log, r as createLogger } from "./logger-mHIWxBhJ.mjs";
5
- import { h as isLevelEnabled } from "./utils-CJJG0ZYW.mjs";
6
- import { t as useLogger } from "./useLogger-Cfv8Ck8b.mjs";
7
- import { t as parseError } from "./parseError-BeBXEd2V.mjs";
8
- import { i as toMiddlewareOptions, n as defineEvlog, r as toLoggerConfig, t as EvlogConfig } from "./define-DTQpu4f6.mjs";
9
- export { AUDIT_SCHEMA_VERSION, AuditAction, AuditActionDefinition, AuditActor, AuditCatalog, AuditCatalogEntry, AuditCatalogMap, AuditChanges, AuditDeniedError, AuditDiffOptions, AuditEnricherOptions, AuditFields, AuditInput, AuditLoggerMethod, AuditMatcher, AuditMethod, AuditOnlyOptions, AuditPatchOp, AuditSeverity, AuditTarget, AuditableLogger, BaseWideEvent, ClientLogContext, DeepPartial, DefineAuditActionOptions, DefinedAuditAction, DefinedCatalogAudit, DefinedError, DrainContext, DrainFn, EnrichContext, EnvironmentContext, ErrorCatalog, ErrorCatalogEntry, ErrorCatalogMap, ErrorCode, ErrorFactoryOpts, ErrorFactoryOverrides, ErrorOptions, EvlogConfig, EvlogError, EvlogPlugin, FieldContext, H3EventContext, IngestPayload, InternalFields, Log, LogLevel, LoggerConfig, MockAudit, ParsedError, PluginRunner, PluginSetupContext, RedactConfig, RegisteredAuditCatalogs, RegisteredErrorCatalogs, RequestFinishContext, RequestLifecycleContext, RequestLogger, RequestLoggerOptions, SamplingConfig, SamplingRates, ServerEvent, SignedChainState, SignedOptions, TailSamplingCondition, TailSamplingContext, TransportConfig, WideEvent, WithAuditContext, WithAuditOptions, audit, auditDiff, auditEnricher, auditOnly, auditRedactPreset, buildAuditFields, createError, createError as createEvlogError, createLogger, createRequestLogger, defineAuditAction, defineAuditCatalog, defineError, defineErrorCatalog, defineEvlog, definePlugin, drainPlugin, enricherPlugin, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, mockAudit, parseError, shouldKeep, signed, toLoggerConfig, toMiddlewareOptions, useLogger, withAudit, withAuditMethods };
1
+ import { $ as LogLevel, A as DefinedAuditAction, B as AuditTarget, D as withAuditMethods, E as withAudit, Et as enricherPlugin, F as AuditChanges, G as EnvironmentContext, H as DeepPartial, I as AuditFields, J as FieldContext, K as ErrorCode, L as AuditLoggerMethod, M as AuditAction, N as AuditActionDefinition, O as AuditInput, P as AuditActor, Q as Log, R as AuditPatchOp, St as RequestLifecycleContext, T as signed, Tt as drainPlugin, U as DrainContext, V as BaseWideEvent, W as EnrichContext, X as IngestPayload, Y as H3EventContext, Z as InternalFields, _ as auditDiff, _t as ClientLogContext, a as AuditEnricherOptions, b as auditRedactPreset, bt as PluginSetupContext, c as AuditOnlyOptions, d as MockAudit, dt as ServerEvent, et as LoggerConfig, f as SignedChainState, ft as TailSamplingCondition, g as audit, h as WithAuditOptions, ht as WideEvent, it as RegisteredErrorCatalogs, j as defineAuditAction, k as DefineAuditActionOptions, l as AuditableLogger, lt as SamplingConfig, m as WithAuditContext, mt as TransportConfig, n as AuditDeniedError, nt as RedactConfig, o as AuditMatcher, ot as RequestLogger, p as SignedOptions, pt as TailSamplingContext, q as ErrorOptions, r as AuditDiffOptions, rt as RegisteredAuditCatalogs, s as AuditMethod, st as RequestLoggerOptions, t as AUDIT_SCHEMA_VERSION, tt as ParsedError, u as DrainFn, ut as SamplingRates, v as auditEnricher, vt as EvlogPlugin, w as mockAudit, wt as definePlugin, x as buildAuditFields, xt as RequestFinishContext, y as auditOnly, yt as PluginRunner, z as AuditSeverity } from "./audit-BZrUvjfW.mjs";
2
+ import { n as createError, t as EvlogError } from "./error-BRymuv8U.mjs";
3
+ import { a as DefinedError, c as ErrorCatalogMap, d as defineAuditCatalog, f as defineError, i as DefinedCatalogAudit, l as ErrorFactoryOpts, n as AuditCatalogEntry, o as ErrorCatalog, p as defineErrorCatalog, r as AuditCatalogMap, s as ErrorCatalogEntry, t as AuditCatalog, u as ErrorFactoryOverrides } from "./catalog-1cQnNxR2.mjs";
4
+ import { a as getEnvironment, c as initLogger, h as shouldKeep, i as createRequestLogger, l as isEnabled, n as _log, r as createLogger } from "./logger-CxWz7QJ3.mjs";
5
+ import { h as isLevelEnabled } from "./utils-D_LY-J1k.mjs";
6
+ import { t as useLogger } from "./useLogger-BupVLO9_.mjs";
7
+ import { t as parseError } from "./parseError-BmoJ7XeF.mjs";
8
+ import { i as toMiddlewareOptions, n as defineEvlog, r as toLoggerConfig, t as EvlogConfig } from "./define-Ct2QyrE9.mjs";
9
+ export { AUDIT_SCHEMA_VERSION, type AuditAction, type AuditActionDefinition, type AuditActor, type AuditCatalog, type AuditCatalogEntry, type AuditCatalogMap, type AuditChanges, AuditDeniedError, type AuditDiffOptions, type AuditEnricherOptions, type AuditFields, type AuditInput, type AuditLoggerMethod, type AuditMatcher, type AuditMethod, type AuditOnlyOptions, type AuditPatchOp, type AuditSeverity, type AuditTarget, type AuditableLogger, type BaseWideEvent, type ClientLogContext, type DeepPartial, type DefineAuditActionOptions, type DefinedAuditAction, type DefinedCatalogAudit, type DefinedError, type DrainContext, type DrainFn, type EnrichContext, type EnvironmentContext, type ErrorCatalog, type ErrorCatalogEntry, type ErrorCatalogMap, type ErrorCode, type ErrorFactoryOpts, type ErrorFactoryOverrides, type ErrorOptions, type EvlogConfig, EvlogError, type EvlogPlugin, type FieldContext, type H3EventContext, type IngestPayload, type InternalFields, type Log, type LogLevel, type LoggerConfig, type MockAudit, type ParsedError, type PluginRunner, type PluginSetupContext, type RedactConfig, type RegisteredAuditCatalogs, type RegisteredErrorCatalogs, type RequestFinishContext, type RequestLifecycleContext, type RequestLogger, type RequestLoggerOptions, type SamplingConfig, type SamplingRates, type ServerEvent, type SignedChainState, type SignedOptions, type TailSamplingCondition, type TailSamplingContext, type TransportConfig, type WideEvent, type WithAuditContext, type WithAuditOptions, audit, auditDiff, auditEnricher, auditOnly, auditRedactPreset, buildAuditFields, createError, createError as createEvlogError, createLogger, createRequestLogger, defineAuditAction, defineAuditCatalog, defineError, defineErrorCatalog, defineEvlog, definePlugin, drainPlugin, enricherPlugin, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, mockAudit, parseError, shouldKeep, signed, toLoggerConfig, toMiddlewareOptions, useLogger, withAudit, withAuditMethods };