@servicetitan/journey 2.0.0 → 3.0.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 (233) hide show
  1. package/README.md +1 -1
  2. package/dist/__test-utils__/test-runtime.d.ts.map +1 -0
  3. package/dist/__test-utils__/test-runtime.js +54 -0
  4. package/dist/__test-utils__/test-runtime.js.map +1 -0
  5. package/dist/__tests__/core/ambient.test.d.ts.map +1 -0
  6. package/dist/__tests__/core/api.test.d.ts +2 -0
  7. package/dist/__tests__/core/api.test.d.ts.map +1 -0
  8. package/dist/__tests__/core/define-journey.test.d.ts.map +1 -0
  9. package/dist/__tests__/core/requests.test.d.ts.map +1 -0
  10. package/dist/__tests__/core/runtime.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/sanitize.test.d.ts +2 -0
  12. package/dist/__tests__/core/sanitize.test.d.ts.map +1 -0
  13. package/dist/__tests__/core/step.test.d.ts.map +1 -0
  14. package/dist/__tests__/core/timeouts.test.d.ts.map +1 -0
  15. package/dist/__tests__/global.test.d.ts +3 -0
  16. package/dist/__tests__/global.test.d.ts.map +1 -0
  17. package/dist/__tests__/hardening.test.d.ts +2 -0
  18. package/dist/__tests__/hardening.test.d.ts.map +1 -0
  19. package/dist/__tests__/integrations/axios.test.d.ts.map +1 -0
  20. package/dist/__tests__/integrations/context.test.d.ts.map +1 -0
  21. package/dist/__tests__/integrations/expose-app-journey.test.d.ts.map +1 -0
  22. package/dist/__tests__/integrations/fetch.test.d.ts.map +1 -0
  23. package/dist/__tests__/integrations/host-mfe.test.d.ts +2 -0
  24. package/dist/__tests__/integrations/host-mfe.test.d.ts.map +1 -0
  25. package/dist/__tests__/integrations/jquery.test.d.ts.map +1 -0
  26. package/dist/__tests__/integrations/request-key.test.d.ts.map +1 -0
  27. package/dist/__tests__/integrations/scope.test.d.ts.map +1 -0
  28. package/dist/__tests__/integrations/use-journey-step.test.d.ts +2 -0
  29. package/dist/__tests__/integrations/use-journey-step.test.d.ts.map +1 -0
  30. package/dist/__tests__/sinks/console.test.d.ts +2 -0
  31. package/dist/__tests__/sinks/console.test.d.ts.map +1 -0
  32. package/dist/__tests__/sinks/datadog.test.d.ts.map +1 -0
  33. package/dist/__tests__/sinks/sinks.test.d.ts.map +1 -0
  34. package/dist/config.d.ts +61 -13
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +98 -29
  37. package/dist/config.js.map +1 -1
  38. package/dist/core/abort-error.d.ts +4 -0
  39. package/dist/core/abort-error.d.ts.map +1 -0
  40. package/dist/core/abort-error.js +22 -0
  41. package/dist/core/abort-error.js.map +1 -0
  42. package/dist/core/api.d.ts +43 -0
  43. package/dist/core/api.d.ts.map +1 -0
  44. package/dist/core/api.js +122 -0
  45. package/dist/core/api.js.map +1 -0
  46. package/dist/{endpoint-policy.d.ts → core/endpoint-policy.d.ts} +14 -4
  47. package/dist/core/endpoint-policy.d.ts.map +1 -0
  48. package/dist/core/endpoint-policy.js +70 -0
  49. package/dist/core/endpoint-policy.js.map +1 -0
  50. package/dist/core/index.d.ts +6 -5
  51. package/dist/core/index.d.ts.map +1 -1
  52. package/dist/core/index.js +4 -3
  53. package/dist/core/index.js.map +1 -1
  54. package/dist/core/limits.d.ts +29 -0
  55. package/dist/core/limits.d.ts.map +1 -0
  56. package/dist/core/limits.js +63 -0
  57. package/dist/core/limits.js.map +1 -0
  58. package/dist/core/request-policy.d.ts +39 -0
  59. package/dist/core/request-policy.d.ts.map +1 -0
  60. package/dist/core/request-policy.js +18 -0
  61. package/dist/core/request-policy.js.map +1 -0
  62. package/dist/core/runtime.d.ts +95 -17
  63. package/dist/core/runtime.d.ts.map +1 -1
  64. package/dist/core/runtime.js +435 -124
  65. package/dist/core/runtime.js.map +1 -1
  66. package/dist/core/sanitize.d.ts +23 -0
  67. package/dist/core/sanitize.d.ts.map +1 -0
  68. package/dist/core/sanitize.js +143 -0
  69. package/dist/core/sanitize.js.map +1 -0
  70. package/dist/core/step-tag.d.ts +31 -6
  71. package/dist/core/step-tag.d.ts.map +1 -1
  72. package/dist/core/step-tag.js +62 -9
  73. package/dist/core/step-tag.js.map +1 -1
  74. package/dist/core/types.d.ts +76 -26
  75. package/dist/core/types.d.ts.map +1 -1
  76. package/dist/core/types.js +4 -1
  77. package/dist/core/types.js.map +1 -1
  78. package/dist/global.d.ts +145 -0
  79. package/dist/global.d.ts.map +1 -0
  80. package/dist/global.js +326 -0
  81. package/dist/global.js.map +1 -0
  82. package/dist/index.d.ts +9 -5
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +9 -5
  85. package/dist/index.js.map +1 -1
  86. package/dist/integrations/axios.d.ts +5 -1
  87. package/dist/integrations/axios.d.ts.map +1 -1
  88. package/dist/integrations/axios.js +146 -34
  89. package/dist/integrations/axios.js.map +1 -1
  90. package/dist/integrations/fetch.d.ts +6 -4
  91. package/dist/integrations/fetch.d.ts.map +1 -1
  92. package/dist/integrations/fetch.js +105 -26
  93. package/dist/integrations/fetch.js.map +1 -1
  94. package/dist/integrations/http-report.d.ts +27 -0
  95. package/dist/integrations/http-report.d.ts.map +1 -0
  96. package/dist/integrations/http-report.js +123 -0
  97. package/dist/integrations/http-report.js.map +1 -0
  98. package/dist/integrations/jquery/index.d.ts +10 -6
  99. package/dist/integrations/jquery/index.d.ts.map +1 -1
  100. package/dist/integrations/jquery/index.js +28 -9
  101. package/dist/integrations/jquery/index.js.map +1 -1
  102. package/dist/integrations/jquery/instrument.d.ts +14 -5
  103. package/dist/integrations/jquery/instrument.d.ts.map +1 -1
  104. package/dist/integrations/jquery/instrument.js +111 -29
  105. package/dist/integrations/jquery/instrument.js.map +1 -1
  106. package/dist/integrations/react/context.d.ts +4 -1
  107. package/dist/integrations/react/context.d.ts.map +1 -1
  108. package/dist/integrations/react/context.js +4 -1
  109. package/dist/integrations/react/context.js.map +1 -1
  110. package/dist/integrations/react/scope.d.ts +14 -3
  111. package/dist/integrations/react/scope.d.ts.map +1 -1
  112. package/dist/integrations/react/scope.js +48 -9
  113. package/dist/integrations/react/scope.js.map +1 -1
  114. package/dist/integrations/react/stable-config-keys.d.ts +6 -0
  115. package/dist/integrations/react/stable-config-keys.d.ts.map +1 -0
  116. package/dist/integrations/react/stable-config-keys.js +21 -0
  117. package/dist/integrations/react/stable-config-keys.js.map +1 -0
  118. package/dist/integrations/react/use-journey-step.d.ts +11 -0
  119. package/dist/integrations/react/use-journey-step.d.ts.map +1 -0
  120. package/dist/integrations/react/use-journey-step.js +19 -0
  121. package/dist/integrations/react/use-journey-step.js.map +1 -0
  122. package/dist/integrations/request-key.d.ts +8 -3
  123. package/dist/integrations/request-key.d.ts.map +1 -1
  124. package/dist/integrations/request-key.js +10 -9
  125. package/dist/integrations/request-key.js.map +1 -1
  126. package/dist/integrations/soft-skip.d.ts +7 -0
  127. package/dist/integrations/soft-skip.d.ts.map +1 -0
  128. package/dist/integrations/soft-skip.js +30 -0
  129. package/dist/integrations/soft-skip.js.map +1 -0
  130. package/dist/sinks/console.d.ts +11 -0
  131. package/dist/sinks/console.d.ts.map +1 -0
  132. package/dist/sinks/console.js +19 -0
  133. package/dist/sinks/console.js.map +1 -0
  134. package/dist/sinks/datadog.d.ts +12 -1
  135. package/dist/sinks/datadog.d.ts.map +1 -1
  136. package/dist/sinks/datadog.js +42 -25
  137. package/dist/sinks/datadog.js.map +1 -1
  138. package/package.json +2 -2
  139. package/src/{__mocks__ → __test-utils__}/test-runtime.ts +15 -4
  140. package/src/__tests__/config.test.ts +158 -42
  141. package/src/__tests__/{ambient.test.ts → core/ambient.test.ts} +23 -16
  142. package/src/__tests__/{registry.test.ts → core/api.test.ts} +35 -30
  143. package/src/__tests__/{define-journey.test.ts → core/define-journey.test.ts} +33 -15
  144. package/src/__tests__/{requests.test.ts → core/requests.test.ts} +61 -39
  145. package/src/__tests__/{runtime.test.ts → core/runtime.test.ts} +84 -37
  146. package/src/__tests__/core/sanitize.test.ts +69 -0
  147. package/src/__tests__/{step.test.ts → core/step.test.ts} +146 -52
  148. package/src/__tests__/{timeouts.test.ts → core/timeouts.test.ts} +83 -13
  149. package/src/__tests__/global.test.ts +154 -0
  150. package/src/__tests__/hardening.test.ts +613 -0
  151. package/src/__tests__/integrations/axios.test.ts +616 -0
  152. package/src/__tests__/{context.test.tsx → integrations/context.test.tsx} +1 -1
  153. package/src/__tests__/{expose-app-journey.test.ts → integrations/expose-app-journey.test.ts} +11 -5
  154. package/src/__tests__/{fetch.test.ts → integrations/fetch.test.ts} +159 -25
  155. package/src/__tests__/integrations/host-mfe.test.ts +548 -0
  156. package/src/__tests__/integrations/jquery.test.ts +539 -0
  157. package/src/__tests__/{request-key.test.ts → integrations/request-key.test.ts} +1 -1
  158. package/src/__tests__/integrations/scope.test.tsx +286 -0
  159. package/src/__tests__/integrations/use-journey-step.test.tsx +43 -0
  160. package/src/__tests__/sinks/console.test.ts +103 -0
  161. package/src/__tests__/{datadog.test.ts → sinks/datadog.test.ts} +109 -5
  162. package/src/__tests__/{sinks.test.ts → sinks/sinks.test.ts} +13 -12
  163. package/src/config.ts +173 -41
  164. package/src/core/abort-error.ts +24 -0
  165. package/src/core/api.ts +159 -0
  166. package/src/{endpoint-policy.ts → core/endpoint-policy.ts} +46 -4
  167. package/src/core/index.ts +16 -17
  168. package/src/core/limits.ts +73 -0
  169. package/src/core/request-policy.ts +66 -0
  170. package/src/core/runtime.ts +560 -137
  171. package/src/core/sanitize.ts +177 -0
  172. package/src/core/step-tag.ts +90 -11
  173. package/src/core/types.ts +82 -26
  174. package/src/global.ts +466 -0
  175. package/src/index.ts +31 -18
  176. package/src/integrations/axios.ts +183 -45
  177. package/src/integrations/fetch.ts +127 -41
  178. package/src/integrations/http-report.ts +184 -0
  179. package/src/integrations/jquery/index.ts +37 -18
  180. package/src/integrations/jquery/instrument.ts +126 -42
  181. package/src/integrations/react/context.ts +4 -1
  182. package/src/integrations/react/scope.tsx +61 -10
  183. package/src/integrations/react/stable-config-keys.ts +28 -0
  184. package/src/integrations/react/use-journey-step.ts +31 -0
  185. package/src/integrations/request-key.ts +18 -10
  186. package/src/integrations/soft-skip.ts +35 -0
  187. package/src/sinks/console.ts +21 -0
  188. package/src/sinks/datadog.ts +52 -33
  189. package/dist/__mocks__/test-runtime.d.ts.map +0 -1
  190. package/dist/__tests__/ambient.test.d.ts.map +0 -1
  191. package/dist/__tests__/axios.test.d.ts.map +0 -1
  192. package/dist/__tests__/context.test.d.ts.map +0 -1
  193. package/dist/__tests__/datadog.test.d.ts.map +0 -1
  194. package/dist/__tests__/define-journey.test.d.ts.map +0 -1
  195. package/dist/__tests__/expose-app-journey.test.d.ts.map +0 -1
  196. package/dist/__tests__/fetch.test.d.ts.map +0 -1
  197. package/dist/__tests__/jquery.test.d.ts.map +0 -1
  198. package/dist/__tests__/registry.test.d.ts +0 -2
  199. package/dist/__tests__/registry.test.d.ts.map +0 -1
  200. package/dist/__tests__/request-key.test.d.ts.map +0 -1
  201. package/dist/__tests__/requests.test.d.ts.map +0 -1
  202. package/dist/__tests__/runtime.test.d.ts.map +0 -1
  203. package/dist/__tests__/scope.test.d.ts.map +0 -1
  204. package/dist/__tests__/sinks.test.d.ts.map +0 -1
  205. package/dist/__tests__/step.test.d.ts.map +0 -1
  206. package/dist/__tests__/timeouts.test.d.ts.map +0 -1
  207. package/dist/core/registry.d.ts +0 -50
  208. package/dist/core/registry.d.ts.map +0 -1
  209. package/dist/core/registry.js +0 -102
  210. package/dist/core/registry.js.map +0 -1
  211. package/dist/endpoint-policy.d.ts.map +0 -1
  212. package/dist/endpoint-policy.js +0 -39
  213. package/dist/endpoint-policy.js.map +0 -1
  214. package/src/__tests__/axios.test.ts +0 -365
  215. package/src/__tests__/jquery.test.ts +0 -327
  216. package/src/__tests__/scope.test.tsx +0 -128
  217. package/src/core/registry.ts +0 -162
  218. /package/dist/{__mocks__ → __test-utils__}/test-runtime.d.ts +0 -0
  219. /package/dist/__tests__/{ambient.test.d.ts → core/ambient.test.d.ts} +0 -0
  220. /package/dist/__tests__/{define-journey.test.d.ts → core/define-journey.test.d.ts} +0 -0
  221. /package/dist/__tests__/{requests.test.d.ts → core/requests.test.d.ts} +0 -0
  222. /package/dist/__tests__/{runtime.test.d.ts → core/runtime.test.d.ts} +0 -0
  223. /package/dist/__tests__/{step.test.d.ts → core/step.test.d.ts} +0 -0
  224. /package/dist/__tests__/{timeouts.test.d.ts → core/timeouts.test.d.ts} +0 -0
  225. /package/dist/__tests__/{axios.test.d.ts → integrations/axios.test.d.ts} +0 -0
  226. /package/dist/__tests__/{context.test.d.ts → integrations/context.test.d.ts} +0 -0
  227. /package/dist/__tests__/{expose-app-journey.test.d.ts → integrations/expose-app-journey.test.d.ts} +0 -0
  228. /package/dist/__tests__/{fetch.test.d.ts → integrations/fetch.test.d.ts} +0 -0
  229. /package/dist/__tests__/{jquery.test.d.ts → integrations/jquery.test.d.ts} +0 -0
  230. /package/dist/__tests__/{request-key.test.d.ts → integrations/request-key.test.d.ts} +0 -0
  231. /package/dist/__tests__/{scope.test.d.ts → integrations/scope.test.d.ts} +0 -0
  232. /package/dist/__tests__/{datadog.test.d.ts → sinks/datadog.test.d.ts} +0 -0
  233. /package/dist/__tests__/{sinks.test.d.ts → sinks/sinks.test.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/runtime.ts"],"sourcesContent":["import {\n longestEndpointMatch,\n sortEndpointsByLongestMatch,\n type AppRequestTimeouts,\n} from '../endpoint-policy';\nimport { JourneyStepTag } from './step-tag';\nimport type {\n JourneyDef,\n JourneyEvent,\n JourneySink,\n JourneyState,\n JourneyStepEvent,\n JourneyStepOptions,\n JourneyStepRef,\n JourneyStepTarget,\n Outcome,\n StepHandle,\n StepRecord,\n TagValue,\n} from './types';\n\nconst DEFAULT_REQUEST_TIMEOUTS: AppRequestTimeouts = { defaultMs: 4_000, endpoints: [] };\n\nconst noopStep: StepHandle = {\n name: null,\n setAttribute() {},\n setTags() {},\n complete() {},\n fail() {},\n tag: () => ({}),\n};\n\nfunction toName(target: string | { readonly name: string }): string {\n return typeof target === 'string' ? target : target.name;\n}\n\n/** @internal Private — not part of the public package API. */\nexport interface JourneyRuntimeOptions {\n /** Initial sinks. Defaults to `[]` — package bootstrap installs Datadog on the default runtime. */\n sinks?: readonly JourneySink[];\n requestTimeouts?: AppRequestTimeouts;\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Isolated journey engine (open journeys, ambient steps, sinks, request thresholds).\n * App code should keep using free helpers (`defineJourney`, `journeyStep`, …) — they\n * bind to the process default runtime. Prefer `resetJourney()` in tests.\n */\nexport interface JourneyRuntime {\n getRequestTimeouts(): AppRequestTimeouts;\n setRequestTimeouts(next: AppRequestTimeouts): void;\n\n setSinks(next: readonly JourneySink[]): void;\n addSink(sink: JourneySink): void;\n emit(payload: JourneyEvent): void;\n\n getOpenJourney(name: string): JourneyState | undefined;\n firstOpenJourney(names: readonly string[]): string | null;\n setJourneyTags(name: string | null, tags: Record<string, TagValue>): void;\n startJourney(def: JourneyDef): void;\n failJourneyNow(journey: JourneyState, reason: string): void;\n failJourney(name: string, reason: string): void;\n completeJourney(name: string | null, tags?: Record<string, TagValue>): void;\n excludeJourney(name: string): void;\n\n activeJourneyStep(): JourneyStepRef | null;\n journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n journeyMountStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n\n reportBackendRequest(\n step: JourneyStepRef | undefined,\n status: number | undefined,\n durationMs: number,\n requestKey: string\n ): void;\n\n /** Close open journeys, clear ambient steps, restore default timeouts/sinks. */\n reset(options?: JourneyRuntimeOptions): void;\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Build an isolated engine. Rarely needed — apps use the default via free helpers.\n */\nexport function createJourneyRuntime(options: JourneyRuntimeOptions = {}): JourneyRuntime {\n const journeys = new Map<string, JourneyState>();\n const inFlight = new Set<StepRecord>();\n let sinks: JourneySink[] = [...(options.sinks ?? [])];\n let requestTimeouts: AppRequestTimeouts = {\n defaultMs: options.requestTimeouts?.defaultMs ?? DEFAULT_REQUEST_TIMEOUTS.defaultMs,\n endpoints: sortEndpointsByLongestMatch(\n options.requestTimeouts?.endpoints ?? DEFAULT_REQUEST_TIMEOUTS.endpoints\n ),\n };\n\n function getInFlightSteps(journey: JourneyState): StepRecord[] {\n const out: StepRecord[] = [];\n for (const step of inFlight) {\n if (step.journey === journey) {\n out.push(step);\n }\n }\n return out;\n }\n\n function enterStep(step: StepRecord): void {\n inFlight.add(step);\n }\n\n function leaveStep(step: StepRecord): void {\n inFlight.delete(step);\n }\n\n function clearCountdown(journey: JourneyState): void {\n if (journey.timer != null) {\n clearTimeout(journey.timer);\n journey.timer = null;\n }\n }\n\n function emit(payload: JourneyEvent): void {\n for (const sink of sinks) {\n try {\n sink(payload);\n } catch {\n // One sinking throw must not block the remaining sinks.\n }\n }\n }\n\n function finish(journey: JourneyState, outcome: Outcome, reason?: string): void {\n if (journey.closed) {\n return;\n }\n journey.closed = true;\n journeys.delete(journey.name);\n clearCountdown(journey);\n\n for (const step of getInFlightSteps(journey)) {\n if (step.durationMs === 0) {\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n }\n }\n\n let finalReason = journey.reason ?? reason;\n let finalOutcome = outcome;\n const durationMs = Math.round(globalThis.performance.now() - journey.startedAt);\n if (journey.timeoutMs > 0 && durationMs > journey.timeoutMs) {\n finalOutcome = 'bad';\n finalReason = finalReason ?? 'journey-timeout';\n }\n\n const steps: JourneyStepEvent[] = journey.steps.map(s => ({\n name: s.name,\n startMs: Math.round(s.startedAt - journey.startedAt),\n durationMs: s.durationMs,\n outcome: s.outcome,\n ...(s.reason ? { reason: s.reason } : {}),\n ...(s.httpStatus !== undefined ? { httpStatus: s.httpStatus } : {}),\n ...(Object.keys(s.attributes).length ? { attributes: s.attributes } : {}),\n }));\n\n emit({\n journey: {\n name: journey.name,\n team: journey.team,\n group: journey.group,\n service: journey.service,\n outcome: finalOutcome,\n ...(finalOutcome === 'bad' && finalReason ? { reason: finalReason } : {}),\n durationMs,\n steps,\n ...(journey.expected ? { expected: journey.expected } : {}),\n ...(Object.keys(journey.tags).length ? { tags: journey.tags } : {}),\n },\n });\n }\n\n function armCountdown(journey: JourneyState): void {\n if (journey.timeoutMs <= 0) {\n return;\n }\n journey.timer = setTimeout(() => {\n finish(journey, 'bad', 'journey-timeout');\n }, journey.timeoutMs);\n }\n\n function resolveRequestTimeoutMs(journey: JourneyState, key: string): number {\n const own = longestEndpointMatch(journey.endpoints, key);\n if (own?.timeoutMs) {\n return own.timeoutMs;\n }\n\n const app = longestEndpointMatch(requestTimeouts.endpoints, key);\n if (app?.timeoutMs) {\n return app.timeoutMs;\n }\n\n if (journey.requestTimeoutMs != null) {\n return journey.requestTimeoutMs;\n }\n\n return requestTimeouts.defaultMs;\n }\n\n function shouldIgnoreRequest(journey: JourneyState, key: string): boolean {\n const own = longestEndpointMatch(journey.endpoints, key);\n if (own) {\n return own.ignore === true;\n }\n return longestEndpointMatch(requestTimeouts.endpoints, key)?.ignore === true;\n }\n\n function resolveJourneyName(journey: JourneyStepTarget): string | null {\n if (journey == null) {\n return null;\n }\n if (typeof journey === 'string' || !Array.isArray(journey)) {\n return toName(journey as string | { readonly name: string });\n }\n return api.firstOpenJourney(journey.map(toName));\n }\n\n function createStepHandle(journeyName: string, step: StepRecord): StepHandle {\n return {\n name: journeyName,\n setAttribute(key, value) {\n step.attributes[key] = value;\n },\n setTags(tags) {\n api.setJourneyTags(journeyName, tags);\n },\n complete(tags) {\n api.completeJourney(journeyName, tags);\n },\n fail(reason) {\n api.failJourney(journeyName, reason);\n },\n // Box in JourneyStepTag — raw StepRecord is circular and blows jQuery/axios deep-merge.\n tag: () => ({ journeyStep: new JourneyStepTag(step) }),\n };\n }\n\n const api: JourneyRuntime = {\n getRequestTimeouts() {\n return requestTimeouts;\n },\n\n setRequestTimeouts(next) {\n requestTimeouts = {\n ...next,\n endpoints: sortEndpointsByLongestMatch(next.endpoints),\n };\n },\n\n setSinks(next) {\n sinks = [...next];\n },\n\n addSink(sink) {\n sinks.push(sink);\n },\n\n emit,\n\n getOpenJourney(name) {\n return journeys.get(name);\n },\n\n firstOpenJourney(names) {\n for (const name of names) {\n if (journeys.has(name)) {\n return name;\n }\n }\n return null;\n },\n\n setJourneyTags(name, tags) {\n const journey = name ? journeys.get(name) : undefined;\n if (journey) {\n Object.assign(journey.tags, tags);\n }\n },\n\n startJourney(def) {\n const existing = journeys.get(def.name);\n if (existing) {\n finish(existing, existing.verdict === 'bad' ? 'bad' : 'excluded');\n }\n\n const journey: JourneyState = {\n name: def.name,\n team: def.team,\n group: def.group,\n service: def.service,\n verdict: 'good',\n startedAt: globalThis.performance.now(),\n timeoutMs: def.timeoutMs ?? 0,\n stepTimeoutMs: def.stepTimeoutMs,\n reason: null,\n steps: [],\n expected: def.steps ? [...def.steps] : null,\n tags: { ...(def.tags ?? {}) },\n requestTimeoutMs: def.requestTimeoutMs,\n endpoints: sortEndpointsByLongestMatch(def.endpoints),\n timer: null,\n closed: false,\n };\n journeys.set(def.name, journey);\n armCountdown(journey);\n },\n\n failJourneyNow(journey, reason) {\n if (journey.closed) {\n return;\n }\n journey.verdict = 'bad';\n journey.reason ??= reason;\n finish(journey, 'bad');\n },\n\n failJourney(name, reason) {\n const journey = journeys.get(name);\n if (journey) {\n api.failJourneyNow(journey, reason);\n }\n },\n\n completeJourney(name, tags) {\n if (!name) {\n return;\n }\n if (tags) {\n api.setJourneyTags(name, tags);\n }\n const journey = journeys.get(name);\n if (journey) {\n finish(journey, journey.verdict === 'bad' ? 'bad' : 'good');\n }\n },\n\n excludeJourney(name) {\n const journey = journeys.get(name);\n if (journey) {\n finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded');\n }\n },\n\n activeJourneyStep() {\n if (inFlight.size !== 1) {\n return null;\n }\n return inFlight.values().next().value ?? null;\n },\n\n async journeyStep(journey, stepName, fn, opts) {\n const journeyName = resolveJourneyName(journey);\n const open = journeyName ? journeys.get(journeyName) : undefined;\n if (!open || !journeyName) {\n return fn(noopStep);\n }\n\n const step: StepRecord = {\n name: stepName,\n startedAt: globalThis.performance.now(),\n durationMs: 0,\n outcome: 'good',\n attributes: {},\n journey: open,\n };\n open.steps.push(step);\n\n const handle = createStepHandle(journeyName, step);\n\n const stepTimeoutMs = opts?.timeoutMs ?? open.stepTimeoutMs ?? 0;\n let timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n if (stepTimeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n if (open.closed) {\n return;\n }\n step.outcome = 'bad';\n step.reason ??= 'step-timeout';\n step.attributes.timeout_ms ??= stepTimeoutMs;\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n api.failJourneyNow(open, 'step-timeout');\n }, stepTimeoutMs);\n }\n\n enterStep(step);\n try {\n return await fn(handle);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n step.outcome = 'bad';\n step.reason ??= 'step-error';\n step.attributes.error ??= message;\n api.failJourneyNow(open, 'step-error');\n throw err;\n } finally {\n if (timeoutTimer != null) {\n clearTimeout(timeoutTimer);\n }\n if (step.durationMs === 0) {\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n }\n leaveStep(step);\n }\n },\n\n async journeyMountStep(journey, stepName, fn, opts) {\n await Promise.resolve();\n return api.journeyStep(journey, stepName, fn, opts);\n },\n\n reportBackendRequest(step, status, durationMs, requestKey) {\n if (!step) {\n return;\n }\n const journey = step.journey;\n if (journey.closed) {\n return;\n }\n if (shouldIgnoreRequest(journey, requestKey)) {\n return;\n }\n\n const failed = status === undefined || status >= 500;\n const slow = durationMs > resolveRequestTimeoutMs(journey, requestKey);\n if (!failed && !slow) {\n return;\n }\n\n const category = failed ? 'request-error' : 'request-latency';\n\n step.outcome = 'bad';\n step.reason ??= category;\n if (failed && status !== undefined) {\n step.httpStatus = status;\n }\n\n api.failJourneyNow(journey, category);\n },\n\n reset(next = {}) {\n for (const journey of [...journeys.values()]) {\n clearCountdown(journey);\n journey.closed = true;\n }\n journeys.clear();\n inFlight.clear();\n sinks = [...(next.sinks ?? [])];\n requestTimeouts = {\n defaultMs: next.requestTimeouts?.defaultMs ?? DEFAULT_REQUEST_TIMEOUTS.defaultMs,\n endpoints: sortEndpointsByLongestMatch(\n next.requestTimeouts?.endpoints ?? DEFAULT_REQUEST_TIMEOUTS.endpoints\n ),\n };\n },\n };\n\n return api;\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Process-wide engine used by free helpers. App code does not need to touch this.\n */\nexport const defaultRuntime: JourneyRuntime = createJourneyRuntime();\n\n/**\n * Reset the default engine (open journeys, ambient steps, sinks, request thresholds).\n * Intended for tests — call in `beforeEach` / `afterEach` instead of manual cleanup.\n */\nexport function resetJourney(options?: JourneyRuntimeOptions): void {\n defaultRuntime.reset(options);\n}\n"],"names":["longestEndpointMatch","sortEndpointsByLongestMatch","JourneyStepTag","DEFAULT_REQUEST_TIMEOUTS","defaultMs","endpoints","noopStep","name","setAttribute","setTags","complete","fail","tag","toName","target","createJourneyRuntime","options","journeys","Map","inFlight","Set","sinks","requestTimeouts","getInFlightSteps","journey","out","step","push","enterStep","add","leaveStep","delete","clearCountdown","timer","clearTimeout","emit","payload","sink","finish","outcome","reason","closed","durationMs","Math","round","globalThis","performance","now","startedAt","finalReason","finalOutcome","timeoutMs","steps","map","s","startMs","httpStatus","undefined","Object","keys","attributes","length","team","group","service","expected","tags","armCountdown","setTimeout","resolveRequestTimeoutMs","key","own","app","requestTimeoutMs","shouldIgnoreRequest","ignore","resolveJourneyName","Array","isArray","api","firstOpenJourney","createStepHandle","journeyName","value","setJourneyTags","completeJourney","failJourney","journeyStep","getRequestTimeouts","setRequestTimeouts","next","setSinks","addSink","getOpenJourney","get","names","has","assign","startJourney","def","existing","verdict","stepTimeoutMs","set","failJourneyNow","excludeJourney","activeJourneyStep","size","values","stepName","fn","opts","open","handle","timeoutTimer","timeout_ms","err","message","Error","String","error","journeyMountStep","Promise","resolve","reportBackendRequest","status","requestKey","failed","slow","category","reset","clear","defaultRuntime","resetJourney"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/runtime.ts"],"sourcesContent":["import {\n getAutoAttributeRequests as getSharedAutoAttributeRequests,\n getHttpAbortedRequestsPolicy as getSharedHttpAbortedRequestsPolicy,\n getHttpClientErrorRequestsPolicy as getSharedHttpClientErrorRequestsPolicy,\n getSharedSlowRequests,\n isJourneyDebugEnabled,\n} from '../global';\nimport { isCanceledError } from './abort-error';\nimport {\n resolveEndpointPolicy,\n sortEndpointsByLongestMatch,\n type SlowRequestConfig,\n} from './endpoint-policy';\nimport {\n clampMaxSteps,\n DEFAULT_MAX_STEPS,\n DEFAULT_JOURNEY_IDLE_MS,\n finiteSlowRequestMs,\n finiteTimeoutMs,\n MAX_ATTRIBUTED_REQUEST_KEYS,\n MAX_TAG_KEYS,\n resolveJourneyTimeoutMs,\n} from './limits';\nimport { assignRecord, emptyRecord, sanitizeJourneyEvent, setSafeAttribute } from './sanitize';\nimport { JourneyStepStamp, resolveStampOpts } from './step-tag';\nimport type { RequestPolicyConfig } from './request-policy';\nimport {\n JOURNEY_ENGINE,\n type JourneyDef,\n type JourneyEngine,\n type JourneyEvent,\n type JourneyNameLike,\n type JourneySink,\n type JourneyState,\n type JourneyStepEvent,\n type JourneyStepOptions,\n type JourneyStepTarget,\n type Outcome,\n type StepHandle,\n type StepRecord,\n type TagValue,\n} from './types';\n\nconst DEFAULT_SLOW_REQUESTS: SlowRequestConfig = { defaultMs: 4_000, endpoints: [] };\n\nconst noopStep: StepHandle = {\n journeyName: null,\n setAttribute() {},\n setTags() {},\n completeJourney() {},\n failJourney() {},\n stamp: () => undefined,\n};\n\nfunction toName(target: JourneyNameLike): string {\n if (typeof target === 'string') {\n return target;\n }\n return 'config' in target ? target.config.name : target.name;\n}\n\n/** @internal Private — not part of the public package API. */\nexport interface JourneyRuntimeOptions {\n /**\n * DevTools label for this engine copy (`__stJourney.getDebugState().runtimes`).\n * Auto-assigned `runtime-N` from the current `__stJourney` registration count\n * when omitted at `registerJourneyRuntime`.\n */\n id?: string;\n /** Initial sinks. Defaults to `[]` — package bootstrap installs Datadog on the module runtime. */\n sinks?: readonly JourneySink[];\n slowRequests?: SlowRequestConfig;\n /** Cap recorded steps; default 50. */\n maxSteps?: number;\n /** Default timeout when JourneyDef.timeoutMs is omitted. 0 disables idle countdown. */\n defaultJourneyIdleMs?: number;\n}\n\n/** @internal Read-only snapshot for DevTools (`__stJourney.getDebugState`; empty unless debugging). */\nexport interface JourneyRuntimeDebugSnapshot {\n id: string;\n openJourneys: readonly {\n name: string;\n team: string;\n group: string;\n service: string;\n verdict: Outcome;\n reason: string | null;\n tags: Record<string, TagValue>;\n stepsInFlight: readonly string[];\n steps: readonly {\n name: string;\n outcome: 'good' | 'bad';\n durationMs: number;\n reason?: string;\n attributedRequestKeys?: readonly string[];\n }[];\n }[];\n activeStep: { journey: string; name: string } | null;\n /** Which shared policy knobs this runtime overrode (false = inherit global). */\n policyOverlay: {\n slowRequests: boolean;\n httpAbortedRequests: boolean;\n httpClientErrorRequests: boolean;\n autoAttributeRequests: boolean;\n };\n}\n\nfunction freezeJourneyDef(config: JourneyDef, tags: Record<string, TagValue>): JourneyDef {\n const endpoints = sortEndpointsByLongestMatch(config.endpoints);\n return Object.freeze({\n ...config,\n timeoutMs: config.timeoutMs !== undefined ? finiteTimeoutMs(config.timeoutMs) : undefined,\n stepTimeoutMs:\n config.stepTimeoutMs !== undefined ? finiteTimeoutMs(config.stepTimeoutMs) : undefined,\n slowRequestMs: finiteSlowRequestMs(config.slowRequestMs),\n maxSteps: config.maxSteps !== undefined ? clampMaxSteps(config.maxSteps) : undefined,\n endpoints: endpoints ? Object.freeze([...endpoints]) : undefined,\n expected: config.expected ? Object.freeze([...config.expected]) : undefined,\n tags: Object.freeze({ ...tags }),\n });\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Isolated journey engine (open journeys, ambient steps, sinks, request thresholds).\n * App code should keep using free helpers (`defineJourney`, `journeyStep`, …) — they\n * bind to the module runtime. Prefer `resetJourney()` in tests.\n */\nexport interface JourneyRuntime {\n /** DevTools id for this engine copy. Auto `runtime-N` when registered without an id. */\n readonly id: string;\n getSlowRequests(): SlowRequestConfig;\n setSlowRequests(next: SlowRequestConfig): void;\n getMaxSteps(): number;\n setMaxSteps(next: number): void;\n getDefaultJourneyIdleMs(): number;\n setDefaultJourneyIdleMs(next: number): void;\n\n setSinks(next: readonly JourneySink[]): void;\n /** First `configureJourney({ sinks })` on this runtime wins. Returns false if already set. */\n trySetConfiguredSinks(next: readonly JourneySink[]): boolean;\n addSink(sink: JourneySink): void;\n emit(payload: JourneyEvent): void;\n\n setPolicyOverlay(next: {\n slowRequests?: SlowRequestConfig;\n httpAbortedRequests?: RequestPolicyConfig;\n httpClientErrorRequests?: RequestPolicyConfig;\n autoAttributeRequests?: boolean;\n }): void;\n getAutoAttributeRequests(): boolean;\n getHttpAbortedRequestsPolicy(): RequestPolicyConfig;\n getHttpClientErrorRequestsPolicy(): RequestPolicyConfig;\n\n getOpenJourney(name: string): JourneyState | undefined;\n /** @internal DevTools snapshot of open journeys / ambient step. */\n getDebugSnapshot(): JourneyRuntimeDebugSnapshot;\n firstOpenJourneyName(names: readonly string[]): string | null;\n setJourneyTags(name: string | null, tags: Record<string, TagValue>): void;\n startJourney(config: JourneyDef): void;\n failJourney(journey: JourneyState, reason: string): void;\n completeJourney(name: string | null, tags?: Record<string, TagValue>): void;\n completeJourneyState(journey: JourneyState, tags?: Record<string, TagValue>): void;\n excludeJourney(journey: JourneyState): void;\n updateOpenJourney(config: JourneyDef): void;\n\n activeJourneyStep(): StepRecord | null;\n journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n journeyMountStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n\n reportBackendRequest(\n step: StepRecord | undefined,\n status: number | undefined,\n durationMs: number,\n requestKey: string\n ): void;\n /** True when this request key is ignored for the step's journey (never changes verdict). */\n shouldIgnoreRequest(journey: JourneyState, key: string): boolean;\n\n /** Close open journeys, clear ambient steps, restore default timeouts/sinks. */\n reset(options?: JourneyRuntimeOptions): void;\n}\n\nfunction bindJourneyEngine(\n api: JourneyRuntime,\n journey: JourneyState,\n shouldIgnoreRequest: (target: JourneyState, key: string) => boolean\n): JourneyEngine {\n return {\n failJourney(reason) {\n api.failJourney(journey, reason);\n },\n exclude() {\n api.excludeJourney(journey);\n },\n shouldIgnoreRequest(key) {\n return shouldIgnoreRequest(journey, key);\n },\n reportBackendRequest(step, status, durationMs, requestKey) {\n api.reportBackendRequest(step, status, durationMs, requestKey);\n },\n getHttpAbortedRequestsPolicy() {\n return api.getHttpAbortedRequestsPolicy();\n },\n getHttpClientErrorRequestsPolicy() {\n return api.getHttpClientErrorRequestsPolicy();\n },\n };\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Build an isolated engine. Rarely needed — apps use the default via free helpers.\n */\nexport function createJourneyRuntime(options: JourneyRuntimeOptions = {}): JourneyRuntime {\n let id = typeof options.id === 'string' && options.id !== '' ? options.id : '';\n const journeys = new Map<string, JourneyState>();\n const inFlight = new Set<StepRecord>();\n let sinks: JourneySink[] = [...(options.sinks ?? [])];\n let sinksConfigured = false;\n let overlay: {\n slowRequests?: SlowRequestConfig;\n httpAbortedRequests?: RequestPolicyConfig;\n httpClientErrorRequests?: RequestPolicyConfig;\n autoAttributeRequests?: boolean;\n } = {};\n let slowRequests: SlowRequestConfig = {\n defaultMs: options.slowRequests?.defaultMs ?? DEFAULT_SLOW_REQUESTS.defaultMs,\n endpoints: sortEndpointsByLongestMatch(\n options.slowRequests?.endpoints ?? DEFAULT_SLOW_REQUESTS.endpoints\n ),\n };\n let maxSteps = clampMaxSteps(options.maxSteps ?? DEFAULT_MAX_STEPS);\n let defaultJourneyIdleMs = finiteTimeoutMs(\n options.defaultJourneyIdleMs ?? DEFAULT_JOURNEY_IDLE_MS\n );\n\n function getInFlightSteps(journey: JourneyState): StepRecord[] {\n const out: StepRecord[] = [];\n for (const step of inFlight) {\n if (step.journey === journey) {\n out.push(step);\n }\n }\n return out;\n }\n\n function enterStep(step: StepRecord): void {\n inFlight.add(step);\n }\n\n function leaveStep(step: StepRecord): void {\n inFlight.delete(step);\n }\n\n function releaseInFlightSteps(journey: JourneyState): void {\n for (const step of [...inFlight]) {\n if (step.journey !== journey) {\n continue;\n }\n if (step.durationMs === 0) {\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n }\n inFlight.delete(step);\n }\n }\n\n function clearCountdown(journey: JourneyState): void {\n if (journey.timer != null) {\n clearTimeout(journey.timer);\n journey.timer = null;\n }\n }\n\n function emit(payload: JourneyEvent): void {\n const safePayload = sanitizeJourneyEvent(payload);\n for (const sink of sinks) {\n try {\n sink(safePayload);\n } catch {\n // One sinking throw must not block the remaining sinks.\n }\n }\n }\n\n function finish(journey: JourneyState, outcome: Outcome, reason?: string): void {\n if (journey.closed) {\n return;\n }\n journey.closed = true;\n if (journeys.get(journey.name) === journey) {\n journeys.delete(journey.name);\n }\n clearCountdown(journey);\n releaseInFlightSteps(journey);\n\n let finalReason = journey.reason ?? reason;\n let finalOutcome = outcome;\n const durationMs = Math.round(globalThis.performance.now() - journey.startedAt);\n if (journey.timeoutExplicit && journey.timeoutMs > 0 && durationMs > journey.timeoutMs) {\n finalOutcome = 'bad';\n finalReason = finalReason ?? 'journey-timeout';\n }\n\n const steps: JourneyStepEvent[] = journey.steps.map(s => ({\n name: s.name,\n startMs: Math.round(s.startedAt - journey.startedAt),\n durationMs: s.durationMs,\n outcome: s.outcome,\n ...(s.reason ? { reason: s.reason } : {}),\n ...(s.httpStatus !== undefined ? { httpStatus: s.httpStatus } : {}),\n ...(Object.keys(s.attributes).length ? { attributes: { ...s.attributes } } : {}),\n }));\n\n emit({\n journey: {\n name: journey.name,\n team: journey.team,\n group: journey.group,\n service: journey.service,\n outcome: finalOutcome,\n ...(finalReason ? { reason: finalReason } : {}),\n durationMs,\n steps,\n ...(journey.expected ? { expected: journey.expected } : {}),\n ...(Object.keys(journey.tags).length ? { tags: { ...journey.tags } } : {}),\n },\n });\n }\n\n function armCountdown(journey: JourneyState, delayMs: number = journey.timeoutMs): void {\n if (delayMs <= 0) {\n return;\n }\n journey.timer = setTimeout(() => {\n if (journey.timeoutExplicit) {\n finish(journey, 'bad', 'journey-timeout');\n return;\n }\n finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded', 'journey-idle-timeout');\n }, delayMs);\n }\n\n function effectiveSlowRequests(): SlowRequestConfig {\n return overlay.slowRequests ?? getSharedSlowRequests() ?? slowRequests;\n }\n\n function shouldIgnoreRequest(journey: JourneyState, key: string): boolean {\n return resolveEndpointPolicy(journey, effectiveSlowRequests(), key).ignore;\n }\n\n function trackAttributedKey(step: StepRecord, requestKey: string): void {\n if (!requestKey) {\n return;\n }\n step.attributedRequestKeys ??= [];\n if (step.attributedRequestKeys.length >= MAX_ATTRIBUTED_REQUEST_KEYS) {\n return;\n }\n if (!step.attributedRequestKeys.includes(requestKey)) {\n step.attributedRequestKeys.push(requestKey);\n }\n }\n\n function resolveJourneyName(journey: JourneyStepTarget): string | null {\n if (journey == null) {\n return null;\n }\n if (typeof journey === 'string' || !Array.isArray(journey)) {\n return toName(journey as JourneyNameLike);\n }\n return api.firstOpenJourneyName(journey.map(toName));\n }\n\n function configFromTarget(target: JourneyNameLike): JourneyDef | undefined {\n if (typeof target === 'string') {\n return undefined;\n }\n if ('config' in target && target.config != null && typeof target.config === 'object') {\n return target.config;\n }\n const rec = target as {\n name?: unknown;\n team?: unknown;\n group?: unknown;\n service?: unknown;\n };\n if (\n typeof rec.name === 'string' &&\n typeof rec.team === 'string' &&\n typeof rec.group === 'string' &&\n typeof rec.service === 'string'\n ) {\n return target as JourneyDef;\n }\n return undefined;\n }\n\n function maybeAutoStart(target: JourneyStepTarget): void {\n if (target == null || typeof target === 'string' || Array.isArray(target)) {\n return;\n }\n const def = configFromTarget(target as JourneyNameLike);\n if (def && !api.getOpenJourney(def.name)) {\n api.startJourney(def);\n }\n }\n\n function createStepHandle(journeyName: string, step: StepRecord): StepHandle {\n return {\n journeyName,\n setAttribute(key, value) {\n setSafeAttribute(step.attributes, key, value);\n },\n setTags(tags) {\n if (step.journey.closed) {\n return;\n }\n assignRecord(step.journey.tags, tags, MAX_TAG_KEYS);\n },\n completeJourney(tags) {\n api.completeJourneyState(step.journey, tags);\n },\n failJourney(reason) {\n api.failJourney(step.journey, reason);\n },\n // Box in JourneyStepStamp — raw StepRecord is circular and blows jQuery/axios deep-merge.\n stamp: scoreOrOpts => new JourneyStepStamp(step, resolveStampOpts(scoreOrOpts)),\n };\n }\n\n const api: JourneyRuntime = {\n get id() {\n return id;\n },\n set id(next: string) {\n id = next;\n },\n getSlowRequests() {\n return effectiveSlowRequests();\n },\n\n setSlowRequests(next) {\n slowRequests = {\n ...next,\n endpoints: sortEndpointsByLongestMatch(next.endpoints),\n };\n },\n\n getMaxSteps() {\n return maxSteps;\n },\n\n setMaxSteps(next) {\n maxSteps = clampMaxSteps(next);\n },\n\n getDefaultJourneyIdleMs() {\n return defaultJourneyIdleMs;\n },\n\n setDefaultJourneyIdleMs(next) {\n defaultJourneyIdleMs = finiteTimeoutMs(next);\n },\n\n setSinks(next) {\n sinks = [...next];\n },\n\n trySetConfiguredSinks(next) {\n if (sinksConfigured) {\n return false;\n }\n sinks = [...next];\n sinksConfigured = true;\n return true;\n },\n\n addSink(sink) {\n sinks.push(sink);\n },\n\n emit,\n\n setPolicyOverlay(next) {\n overlay = { ...overlay, ...next };\n },\n\n getAutoAttributeRequests() {\n if (overlay.autoAttributeRequests !== undefined) {\n return overlay.autoAttributeRequests;\n }\n return getSharedAutoAttributeRequests();\n },\n\n getHttpAbortedRequestsPolicy() {\n return overlay.httpAbortedRequests ?? getSharedHttpAbortedRequestsPolicy();\n },\n\n getHttpClientErrorRequestsPolicy() {\n return overlay.httpClientErrorRequests ?? getSharedHttpClientErrorRequestsPolicy();\n },\n\n getOpenJourney(name) {\n return journeys.get(name);\n },\n\n getDebugSnapshot() {\n const active = api.activeJourneyStep();\n return {\n id: api.id,\n openJourneys: [...journeys.values()].map(journey => ({\n name: journey.name,\n team: journey.team,\n group: journey.group,\n service: journey.service,\n verdict: journey.verdict,\n reason: journey.reason,\n tags: { ...journey.tags },\n stepsInFlight: getInFlightSteps(journey).map(step => step.name),\n steps: journey.steps.map(step => ({\n name: step.name,\n outcome: step.outcome,\n durationMs: step.durationMs,\n ...(step.reason ? { reason: step.reason } : {}),\n ...(step.attributedRequestKeys?.length\n ? { attributedRequestKeys: [...step.attributedRequestKeys] }\n : {}),\n })),\n })),\n activeStep: active ? { journey: active.journey.name, name: active.name } : null,\n policyOverlay: {\n slowRequests: overlay.slowRequests != null,\n httpAbortedRequests: overlay.httpAbortedRequests != null,\n httpClientErrorRequests: overlay.httpClientErrorRequests != null,\n autoAttributeRequests: overlay.autoAttributeRequests != null,\n },\n };\n },\n\n firstOpenJourneyName(names) {\n for (const name of names) {\n if (journeys.has(name)) {\n return name;\n }\n }\n return null;\n },\n\n setJourneyTags(name, tags) {\n const journey = name ? journeys.get(name) : undefined;\n if (journey) {\n assignRecord(journey.tags, tags, MAX_TAG_KEYS);\n }\n },\n\n startJourney(config) {\n const existing = journeys.get(config.name);\n if (existing) {\n finish(existing, existing.verdict === 'bad' ? 'bad' : 'excluded');\n }\n\n const tags = emptyRecord();\n assignRecord(tags, config.tags, MAX_TAG_KEYS);\n const snapshot = freezeJourneyDef(config, tags);\n const timeout = resolveJourneyTimeoutMs(snapshot.timeoutMs, defaultJourneyIdleMs);\n const journey: JourneyState = {\n config: snapshot,\n name: snapshot.name,\n team: snapshot.team,\n group: snapshot.group,\n service: snapshot.service,\n verdict: 'good',\n startedAt: globalThis.performance.now(),\n timeoutMs: timeout.ms,\n timeoutExplicit: timeout.explicit,\n stepTimeoutMs:\n snapshot.stepTimeoutMs !== undefined\n ? finiteTimeoutMs(snapshot.stepTimeoutMs)\n : undefined,\n reason: null,\n steps: [],\n expected: snapshot.expected ? [...snapshot.expected] : null,\n tags,\n slowRequestMs: finiteSlowRequestMs(snapshot.slowRequestMs),\n endpoints: snapshot.endpoints,\n timer: null,\n closed: false,\n maxSteps:\n snapshot.maxSteps !== undefined ? clampMaxSteps(snapshot.maxSteps) : undefined,\n };\n journeys.set(config.name, journey);\n journey[JOURNEY_ENGINE] = bindJourneyEngine(api, journey, shouldIgnoreRequest);\n armCountdown(journey);\n },\n\n failJourney(journey, reason) {\n if (journey.closed) {\n return;\n }\n journey.verdict = 'bad';\n journey.reason ??= reason;\n finish(journey, 'bad');\n },\n\n completeJourney(name, tags) {\n if (!name) {\n return;\n }\n const journey = journeys.get(name);\n if (journey) {\n api.completeJourneyState(journey, tags);\n }\n },\n\n completeJourneyState(journey, tags) {\n if (journey.closed) {\n return;\n }\n if (tags) {\n assignRecord(journey.tags, tags, MAX_TAG_KEYS);\n }\n finish(journey, journey.verdict === 'bad' ? 'bad' : 'good');\n },\n\n excludeJourney(journey) {\n if (journey.closed) {\n return;\n }\n finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded');\n },\n\n updateOpenJourney(config) {\n const journey = journeys.get(config.name);\n if (!journey || journey.closed) {\n return;\n }\n journey.team = config.team;\n journey.group = config.group;\n journey.service = config.service;\n const timeout = resolveJourneyTimeoutMs(config.timeoutMs, defaultJourneyIdleMs);\n journey.timeoutMs = timeout.ms;\n journey.timeoutExplicit = timeout.explicit;\n journey.stepTimeoutMs =\n config.stepTimeoutMs !== undefined\n ? finiteTimeoutMs(config.stepTimeoutMs)\n : undefined;\n journey.slowRequestMs = finiteSlowRequestMs(config.slowRequestMs);\n journey.endpoints = sortEndpointsByLongestMatch(config.endpoints);\n journey.expected = config.expected ? [...config.expected] : null;\n journey.maxSteps =\n config.maxSteps !== undefined ? clampMaxSteps(config.maxSteps) : undefined;\n if (config.tags) {\n assignRecord(journey.tags, config.tags, MAX_TAG_KEYS);\n }\n clearCountdown(journey);\n if (journey.timeoutMs <= 0) {\n return;\n }\n const elapsedMs = globalThis.performance.now() - journey.startedAt;\n const remainingMs = journey.timeoutMs - elapsedMs;\n if (remainingMs <= 0) {\n if (journey.timeoutExplicit) {\n finish(journey, 'bad', 'journey-timeout');\n return;\n }\n finish(\n journey,\n journey.verdict === 'bad' ? 'bad' : 'excluded',\n 'journey-idle-timeout'\n );\n return;\n }\n armCountdown(journey, remainingMs);\n },\n\n activeJourneyStep() {\n if (!api.getAutoAttributeRequests()) {\n return null;\n }\n if (inFlight.size !== 1) {\n return null;\n }\n return inFlight.values().next().value ?? null;\n },\n\n async journeyStep(journey, stepName, fn, opts) {\n maybeAutoStart(journey);\n const journeyName = resolveJourneyName(journey);\n const open = journeyName ? journeys.get(journeyName) : undefined;\n if (!open || !journeyName) {\n if (isJourneyDebugEnabled()) {\n // eslint-disable-next-line no-console -- debug-only untraced hint\n console.debug(`[journey] step \"${stepName}\" ran untraced (no open journey)`);\n }\n return fn(noopStep);\n }\n\n const step: StepRecord = {\n name: stepName,\n startedAt: globalThis.performance.now(),\n durationMs: 0,\n outcome: 'good',\n attributes: emptyRecord(),\n journey: open,\n };\n const cap = open.maxSteps ?? maxSteps;\n if (open.steps.length >= cap) {\n open.tags.steps_truncated = true;\n } else {\n open.steps.push(step);\n }\n\n const handle = createStepHandle(journeyName, step);\n\n const stepTimeoutMs = opts?.timeoutMs ?? open.stepTimeoutMs ?? 0;\n let timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n if (stepTimeoutMs > 0) {\n timeoutTimer = setTimeout(() => {\n if (open.closed) {\n return;\n }\n step.outcome = 'bad';\n step.reason ??= 'step-timeout';\n step.attributes.timeout_ms ??= stepTimeoutMs;\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n api.failJourney(open, 'step-timeout');\n }, stepTimeoutMs);\n }\n\n enterStep(step);\n try {\n return await fn(handle);\n } catch (err) {\n if (isCanceledError(err)) {\n /*\n * Attributed abort is scored in onHttpComplete. Unattributed /\n * ignored abort throws must not apply policy (empty requestKey).\n */\n } else {\n step.outcome = 'bad';\n step.reason ??= 'step-error';\n api.failJourney(open, 'step-error');\n }\n throw err;\n } finally {\n if (timeoutTimer != null) {\n clearTimeout(timeoutTimer);\n }\n if (step.durationMs === 0) {\n step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);\n }\n leaveStep(step);\n }\n },\n\n async journeyMountStep(journey, stepName, fn, opts) {\n await Promise.resolve();\n return api.journeyStep(journey, stepName, fn, opts);\n },\n\n shouldIgnoreRequest,\n\n reportBackendRequest(step, status, durationMs, requestKey) {\n if (!step?.journey) {\n return;\n }\n const journey = step.journey;\n if (journey.closed) {\n return;\n }\n trackAttributedKey(step, requestKey);\n const endpointPolicy = resolveEndpointPolicy(\n journey,\n effectiveSlowRequests(),\n requestKey\n );\n if (endpointPolicy.ignore) {\n return;\n }\n\n const failed = status === undefined || status >= 500;\n const threshold = endpointPolicy.slowRequestMs;\n const slow = threshold > 0 && durationMs > threshold;\n if (!failed && !slow) {\n return;\n }\n\n const category = failed ? 'request-error' : 'request-latency';\n\n step.outcome = 'bad';\n step.reason ??= category;\n if (failed && status !== undefined) {\n step.httpStatus = status;\n }\n\n api.failJourney(journey, category);\n },\n\n reset(next = {}) {\n for (const journey of [...journeys.values()]) {\n clearCountdown(journey);\n journey.closed = true;\n }\n journeys.clear();\n inFlight.clear();\n overlay = {};\n sinksConfigured = false;\n sinks = [...(next.sinks ?? [])];\n slowRequests = {\n defaultMs: next.slowRequests?.defaultMs ?? DEFAULT_SLOW_REQUESTS.defaultMs,\n endpoints: sortEndpointsByLongestMatch(\n next.slowRequests?.endpoints ?? DEFAULT_SLOW_REQUESTS.endpoints\n ),\n };\n maxSteps =\n next.maxSteps !== undefined ? clampMaxSteps(next.maxSteps) : DEFAULT_MAX_STEPS;\n defaultJourneyIdleMs = finiteTimeoutMs(\n next.defaultJourneyIdleMs ?? DEFAULT_JOURNEY_IDLE_MS\n );\n },\n };\n\n return api;\n}\n\n/**\n * @internal Private — not part of the public package API.\n * Module-scoped engine used by free helpers. App code does not need to touch this.\n * Each host/MFE bundle gets its own copy when the package is duplicated.\n */\nexport const moduleRuntime: JourneyRuntime = createJourneyRuntime();\n\nconst noopEngine: JourneyEngine = {\n failJourney() {},\n exclude() {},\n shouldIgnoreRequest() {\n return false;\n },\n reportBackendRequest() {},\n getHttpAbortedRequestsPolicy() {\n return 'continue';\n },\n getHttpClientErrorRequestsPolicy() {\n return 'continue';\n },\n};\n\n/**\n * True when this bundle can fail/exclude/report the journey: stamped engine, or\n * this runtime's own unstamped object. False for a foreign older-copy journey.\n */\nexport function canRouteHttpToJourney(journey: JourneyState): boolean {\n return (\n journey[JOURNEY_ENGINE] != null || moduleRuntime.getOpenJourney(journey.name) === journey\n );\n}\n\n/**\n * @internal Prefer the creating engine on a journey (MFE `step.stamp()` on a host transport).\n * Falls back to this bundle's module runtime only when this runtime owns the object.\n * Unstamped foreign journeys (older package copies) are a no-op so a same-named\n * host journey is not deleted from this map.\n */\nexport function resolveJourneyEngine(journey: JourneyState): JourneyEngine {\n const stamped = journey[JOURNEY_ENGINE];\n if (stamped) {\n return stamped;\n }\n if (moduleRuntime.getOpenJourney(journey.name) !== journey) {\n return noopEngine;\n }\n return {\n failJourney(reason) {\n moduleRuntime.failJourney(journey, reason);\n },\n exclude() {\n moduleRuntime.excludeJourney(journey);\n },\n shouldIgnoreRequest(key) {\n return moduleRuntime.shouldIgnoreRequest(journey, key);\n },\n reportBackendRequest(step, status, durationMs, requestKey) {\n moduleRuntime.reportBackendRequest(step, status, durationMs, requestKey);\n },\n getHttpAbortedRequestsPolicy() {\n return moduleRuntime.getHttpAbortedRequestsPolicy();\n },\n getHttpClientErrorRequestsPolicy() {\n return moduleRuntime.getHttpClientErrorRequestsPolicy();\n },\n };\n}\n\n/**\n * @internal Reset the module engine (open journeys, ambient steps, sinks, slow-request thresholds).\n * Intended for tests — call in `beforeEach` / `afterEach` instead of manual cleanup.\n */\nexport function resetJourney(options?: JourneyRuntimeOptions): void {\n moduleRuntime.reset(options);\n}\n"],"names":["getAutoAttributeRequests","getSharedAutoAttributeRequests","getHttpAbortedRequestsPolicy","getSharedHttpAbortedRequestsPolicy","getHttpClientErrorRequestsPolicy","getSharedHttpClientErrorRequestsPolicy","getSharedSlowRequests","isJourneyDebugEnabled","isCanceledError","resolveEndpointPolicy","sortEndpointsByLongestMatch","clampMaxSteps","DEFAULT_MAX_STEPS","DEFAULT_JOURNEY_IDLE_MS","finiteSlowRequestMs","finiteTimeoutMs","MAX_ATTRIBUTED_REQUEST_KEYS","MAX_TAG_KEYS","resolveJourneyTimeoutMs","assignRecord","emptyRecord","sanitizeJourneyEvent","setSafeAttribute","JourneyStepStamp","resolveStampOpts","JOURNEY_ENGINE","DEFAULT_SLOW_REQUESTS","defaultMs","endpoints","noopStep","journeyName","setAttribute","setTags","completeJourney","failJourney","stamp","undefined","toName","target","config","name","freezeJourneyDef","tags","Object","freeze","timeoutMs","stepTimeoutMs","slowRequestMs","maxSteps","expected","bindJourneyEngine","api","journey","shouldIgnoreRequest","reason","exclude","excludeJourney","key","reportBackendRequest","step","status","durationMs","requestKey","createJourneyRuntime","options","id","journeys","Map","inFlight","Set","sinks","sinksConfigured","overlay","slowRequests","defaultJourneyIdleMs","getInFlightSteps","out","push","enterStep","add","leaveStep","delete","releaseInFlightSteps","Math","round","globalThis","performance","now","startedAt","clearCountdown","timer","clearTimeout","emit","payload","safePayload","sink","finish","outcome","closed","get","finalReason","finalOutcome","timeoutExplicit","steps","map","s","startMs","httpStatus","keys","attributes","length","team","group","service","armCountdown","delayMs","setTimeout","verdict","effectiveSlowRequests","ignore","trackAttributedKey","attributedRequestKeys","includes","resolveJourneyName","Array","isArray","firstOpenJourneyName","configFromTarget","rec","maybeAutoStart","def","getOpenJourney","startJourney","createStepHandle","value","completeJourneyState","scoreOrOpts","next","getSlowRequests","setSlowRequests","getMaxSteps","setMaxSteps","getDefaultJourneyIdleMs","setDefaultJourneyIdleMs","setSinks","trySetConfiguredSinks","addSink","setPolicyOverlay","autoAttributeRequests","httpAbortedRequests","httpClientErrorRequests","getDebugSnapshot","active","activeJourneyStep","openJourneys","values","stepsInFlight","activeStep","policyOverlay","names","has","setJourneyTags","existing","snapshot","timeout","ms","explicit","set","updateOpenJourney","elapsedMs","remainingMs","size","journeyStep","stepName","fn","opts","open","console","debug","cap","steps_truncated","handle","timeoutTimer","timeout_ms","err","journeyMountStep","Promise","resolve","endpointPolicy","failed","threshold","slow","category","reset","clear","moduleRuntime","noopEngine","canRouteHttpToJourney","resolveJourneyEngine","stamped","resetJourney"],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { JourneyEvent, TagValue } from './types';
2
+ /** Match Datadog metric-tag value rules so RUM attributes / globals join derived SLO tags. */
3
+ export declare function normalizeTagValue(value: string): string;
4
+ export declare function emptyRecord(): Record<string, TagValue>;
5
+ export interface CopyRecordOptions {
6
+ maxKeys: number;
7
+ /** When true, keys are run through {@link normalizeTagValue} (sink / wire). */
8
+ normalizeKeys?: boolean;
9
+ /** When true (default), string values are normalized. */
10
+ normalizeStringValues?: boolean;
11
+ }
12
+ /**
13
+ * Own-key copy onto a null-prototype object. Skips unsafe keys and excess keys.
14
+ */
15
+ export declare function copyRecord(src: Record<string, unknown> | undefined, options: CopyRecordOptions): Record<string, TagValue>;
16
+ /** Merge `src` into `target` (null-prototype), honouring caps and unsafe-key skips. */
17
+ export declare function assignRecord(target: Record<string, TagValue>, src: Record<string, unknown> | undefined, maxKeys: number): void;
18
+ export declare function setSafeAttribute(attributes: Record<string, TagValue>, key: string, value: string | number | boolean): void;
19
+ /** Default-sink payload: normalized keys/names, capped maps, no unsafe keys. */
20
+ export declare function sanitizeJourneyEvent(event: JourneyEvent): JourneyEvent;
21
+ /** True when payload already passed through sanitizeJourneyEvent. */
22
+ export declare function isSanitizedJourneyEvent(event: JourneyEvent): boolean;
23
+ //# sourceMappingURL=sanitize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/core/sanitize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAoB,QAAQ,EAAE,MAAM,SAAS,CAAC;AAIxE,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAEtD;AAYD,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,yDAAyD;IACzD,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED;;GAEG;AACH,wBAAgB,UAAU,CACtB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACxC,OAAO,EAAE,iBAAiB,GAC3B,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAkC1B;AAED,uFAAuF;AACvF,wBAAgB,YAAY,CACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACxC,OAAO,EAAE,MAAM,GAChB,IAAI,CAsBN;AAED,wBAAgB,gBAAgB,CAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,EACpC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GACjC,IAAI,CAYN;AAmBD,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CA2BtE;AAED,qEAAqE;AACrE,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEpE"}
@@ -0,0 +1,143 @@
1
+ import { isUnsafeKey, MAX_ATTRIBUTE_KEYS, MAX_TAG_KEYS, MAX_TAG_VALUE_LEN } from './limits';
2
+ const SANITIZED_EVENT = Symbol.for('st.journey.sanitized');
3
+ /** Match Datadog metric-tag value rules so RUM attributes / globals join derived SLO tags. */ export function normalizeTagValue(value) {
4
+ return value.toLowerCase().replace(/[^a-z0-9_\-:./]/g, '_').replace(/_+/g, '_').slice(0, MAX_TAG_VALUE_LEN).replace(/_+$/, '');
5
+ }
6
+ export function emptyRecord() {
7
+ return Object.create(null);
8
+ }
9
+ function asTagValue(value) {
10
+ if (typeof value === 'string') {
11
+ return normalizeTagValue(value);
12
+ }
13
+ if (typeof value === 'number' || typeof value === 'boolean') {
14
+ return value;
15
+ }
16
+ return undefined;
17
+ }
18
+ /**
19
+ * Own-key copy onto a null-prototype object. Skips unsafe keys and excess keys.
20
+ */ export function copyRecord(src, options) {
21
+ const out = emptyRecord();
22
+ if (src == null || typeof src !== 'object') {
23
+ return out;
24
+ }
25
+ const normalizeKeys = options.normalizeKeys === true;
26
+ const normalizeStringValues = options.normalizeStringValues !== false;
27
+ for (const key of Object.keys(src)){
28
+ if (isUnsafeKey(key)) {
29
+ continue;
30
+ }
31
+ const destKey = normalizeKeys ? normalizeTagValue(key) : key;
32
+ if (!destKey || isUnsafeKey(destKey)) {
33
+ continue;
34
+ }
35
+ const raw = src[key];
36
+ const value = normalizeStringValues ? asTagValue(raw) : typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean' ? raw : undefined;
37
+ if (value === undefined) {
38
+ continue;
39
+ }
40
+ if (Object.prototype.hasOwnProperty.call(out, destKey)) {
41
+ out[destKey] = value;
42
+ continue;
43
+ }
44
+ if (Object.keys(out).length >= options.maxKeys) {
45
+ continue;
46
+ }
47
+ out[destKey] = value;
48
+ }
49
+ return out;
50
+ }
51
+ /** Merge `src` into `target` (null-prototype), honouring caps and unsafe-key skips. */ export function assignRecord(target, src, maxKeys) {
52
+ if (src == null || typeof src !== 'object') {
53
+ return;
54
+ }
55
+ let room = maxKeys - Object.keys(target).length;
56
+ for (const key of Object.keys(src)){
57
+ if (isUnsafeKey(key)) {
58
+ continue;
59
+ }
60
+ const raw = src[key];
61
+ if (typeof raw !== 'string' && typeof raw !== 'number' && typeof raw !== 'boolean') {
62
+ continue;
63
+ }
64
+ const exists = Object.prototype.hasOwnProperty.call(target, key);
65
+ if (!exists && room <= 0) {
66
+ continue;
67
+ }
68
+ if (!exists) {
69
+ room -= 1;
70
+ }
71
+ target[key] = raw;
72
+ }
73
+ }
74
+ export function setSafeAttribute(attributes, key, value) {
75
+ if (isUnsafeKey(key)) {
76
+ return;
77
+ }
78
+ const exists = Object.prototype.hasOwnProperty.call(attributes, key);
79
+ if (!exists && Object.keys(attributes).length >= MAX_ATTRIBUTE_KEYS) {
80
+ return;
81
+ }
82
+ const next = asTagValue(value);
83
+ if (next !== undefined) {
84
+ attributes[key] = next;
85
+ }
86
+ }
87
+ function sanitizeStep(step) {
88
+ const name = normalizeTagValue(step.name);
89
+ return {
90
+ ...step,
91
+ name: name || step.name,
92
+ ...step.reason ? {
93
+ reason: normalizeTagValue(step.reason)
94
+ } : {},
95
+ ...step.attributes ? {
96
+ attributes: copyRecord(step.attributes, {
97
+ maxKeys: MAX_ATTRIBUTE_KEYS,
98
+ normalizeKeys: true
99
+ })
100
+ } : {}
101
+ };
102
+ }
103
+ /** Default-sink payload: normalized keys/names, capped maps, no unsafe keys. */ export function sanitizeJourneyEvent(event) {
104
+ var _j_expected;
105
+ const j = event.journey;
106
+ const expected = (_j_expected = j.expected) === null || _j_expected === void 0 ? void 0 : _j_expected.map((name)=>normalizeTagValue(name)).filter((name)=>name !== '');
107
+ const tags = j.tags ? copyRecord(j.tags, {
108
+ maxKeys: MAX_TAG_KEYS,
109
+ normalizeKeys: true
110
+ }) : undefined;
111
+ const tagKeys = tags ? Object.keys(tags) : [];
112
+ const sanitized = {
113
+ journey: {
114
+ name: normalizeTagValue(j.name),
115
+ team: normalizeTagValue(j.team),
116
+ group: normalizeTagValue(j.group),
117
+ service: normalizeTagValue(j.service),
118
+ outcome: j.outcome,
119
+ ...j.reason ? {
120
+ reason: normalizeTagValue(j.reason)
121
+ } : {},
122
+ durationMs: j.durationMs,
123
+ steps: j.steps.map(sanitizeStep),
124
+ ...(expected === null || expected === void 0 ? void 0 : expected.length) ? {
125
+ expected
126
+ } : {},
127
+ ...tagKeys.length ? {
128
+ tags
129
+ } : {}
130
+ }
131
+ };
132
+ Object.defineProperty(sanitized, SANITIZED_EVENT, {
133
+ value: true,
134
+ enumerable: false,
135
+ configurable: false
136
+ });
137
+ return sanitized;
138
+ }
139
+ /** True when payload already passed through sanitizeJourneyEvent. */ export function isSanitizedJourneyEvent(event) {
140
+ return event[SANITIZED_EVENT] === true;
141
+ }
142
+
143
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/sanitize.ts"],"sourcesContent":["import { isUnsafeKey, MAX_ATTRIBUTE_KEYS, MAX_TAG_KEYS, MAX_TAG_VALUE_LEN } from './limits';\nimport type { JourneyEvent, JourneyStepEvent, TagValue } from './types';\n\nconst SANITIZED_EVENT = Symbol.for('st.journey.sanitized');\n\n/** Match Datadog metric-tag value rules so RUM attributes / globals join derived SLO tags. */\nexport function normalizeTagValue(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9_\\-:./]/g, '_')\n .replace(/_+/g, '_')\n .slice(0, MAX_TAG_VALUE_LEN)\n .replace(/_+$/, '');\n}\n\nexport function emptyRecord(): Record<string, TagValue> {\n return Object.create(null) as Record<string, TagValue>;\n}\n\nfunction asTagValue(value: unknown): TagValue | undefined {\n if (typeof value === 'string') {\n return normalizeTagValue(value);\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value;\n }\n return undefined;\n}\n\nexport interface CopyRecordOptions {\n maxKeys: number;\n /** When true, keys are run through {@link normalizeTagValue} (sink / wire). */\n normalizeKeys?: boolean;\n /** When true (default), string values are normalized. */\n normalizeStringValues?: boolean;\n}\n\n/**\n * Own-key copy onto a null-prototype object. Skips unsafe keys and excess keys.\n */\nexport function copyRecord(\n src: Record<string, unknown> | undefined,\n options: CopyRecordOptions\n): Record<string, TagValue> {\n const out = emptyRecord();\n if (src == null || typeof src !== 'object') {\n return out;\n }\n const normalizeKeys = options.normalizeKeys === true;\n const normalizeStringValues = options.normalizeStringValues !== false;\n for (const key of Object.keys(src)) {\n if (isUnsafeKey(key)) {\n continue;\n }\n const destKey = normalizeKeys ? normalizeTagValue(key) : key;\n if (!destKey || isUnsafeKey(destKey)) {\n continue;\n }\n const raw = src[key];\n const value = normalizeStringValues\n ? asTagValue(raw)\n : typeof raw === 'string' || typeof raw === 'number' || typeof raw === 'boolean'\n ? raw\n : undefined;\n if (value === undefined) {\n continue;\n }\n if (Object.prototype.hasOwnProperty.call(out, destKey)) {\n out[destKey] = value;\n continue;\n }\n if (Object.keys(out).length >= options.maxKeys) {\n continue;\n }\n out[destKey] = value;\n }\n return out;\n}\n\n/** Merge `src` into `target` (null-prototype), honouring caps and unsafe-key skips. */\nexport function assignRecord(\n target: Record<string, TagValue>,\n src: Record<string, unknown> | undefined,\n maxKeys: number\n): void {\n if (src == null || typeof src !== 'object') {\n return;\n }\n let room = maxKeys - Object.keys(target).length;\n for (const key of Object.keys(src)) {\n if (isUnsafeKey(key)) {\n continue;\n }\n const raw = src[key];\n if (typeof raw !== 'string' && typeof raw !== 'number' && typeof raw !== 'boolean') {\n continue;\n }\n const exists = Object.prototype.hasOwnProperty.call(target, key);\n if (!exists && room <= 0) {\n continue;\n }\n if (!exists) {\n room -= 1;\n }\n target[key] = raw;\n }\n}\n\nexport function setSafeAttribute(\n attributes: Record<string, TagValue>,\n key: string,\n value: string | number | boolean\n): void {\n if (isUnsafeKey(key)) {\n return;\n }\n const exists = Object.prototype.hasOwnProperty.call(attributes, key);\n if (!exists && Object.keys(attributes).length >= MAX_ATTRIBUTE_KEYS) {\n return;\n }\n const next = asTagValue(value);\n if (next !== undefined) {\n attributes[key] = next;\n }\n}\n\nfunction sanitizeStep(step: JourneyStepEvent): JourneyStepEvent {\n const name = normalizeTagValue(step.name);\n return {\n ...step,\n name: name || step.name,\n ...(step.reason ? { reason: normalizeTagValue(step.reason) } : {}),\n ...(step.attributes\n ? {\n attributes: copyRecord(step.attributes, {\n maxKeys: MAX_ATTRIBUTE_KEYS,\n normalizeKeys: true,\n }),\n }\n : {}),\n };\n}\n\n/** Default-sink payload: normalized keys/names, capped maps, no unsafe keys. */\nexport function sanitizeJourneyEvent(event: JourneyEvent): JourneyEvent {\n const j = event.journey;\n const expected = j.expected?.map(name => normalizeTagValue(name)).filter(name => name !== '');\n const tags = j.tags\n ? copyRecord(j.tags, { maxKeys: MAX_TAG_KEYS, normalizeKeys: true })\n : undefined;\n const tagKeys = tags ? Object.keys(tags) : [];\n const sanitized: JourneyEvent = {\n journey: {\n name: normalizeTagValue(j.name),\n team: normalizeTagValue(j.team),\n group: normalizeTagValue(j.group),\n service: normalizeTagValue(j.service),\n outcome: j.outcome,\n ...(j.reason ? { reason: normalizeTagValue(j.reason) } : {}),\n durationMs: j.durationMs,\n steps: j.steps.map(sanitizeStep),\n ...(expected?.length ? { expected } : {}),\n ...(tagKeys.length ? { tags } : {}),\n },\n };\n Object.defineProperty(sanitized, SANITIZED_EVENT, {\n value: true,\n enumerable: false,\n configurable: false,\n });\n return sanitized;\n}\n\n/** True when payload already passed through sanitizeJourneyEvent. */\nexport function isSanitizedJourneyEvent(event: JourneyEvent): boolean {\n return (event as unknown as Record<PropertyKey, unknown>)[SANITIZED_EVENT] === true;\n}\n"],"names":["isUnsafeKey","MAX_ATTRIBUTE_KEYS","MAX_TAG_KEYS","MAX_TAG_VALUE_LEN","SANITIZED_EVENT","Symbol","for","normalizeTagValue","value","toLowerCase","replace","slice","emptyRecord","Object","create","asTagValue","undefined","copyRecord","src","options","out","normalizeKeys","normalizeStringValues","key","keys","destKey","raw","prototype","hasOwnProperty","call","length","maxKeys","assignRecord","target","room","exists","setSafeAttribute","attributes","next","sanitizeStep","step","name","reason","sanitizeJourneyEvent","event","j","journey","expected","map","filter","tags","tagKeys","sanitized","team","group","service","outcome","durationMs","steps","defineProperty","enumerable","configurable","isSanitizedJourneyEvent"],"mappings":"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"}
@@ -1,16 +1,41 @@
1
- import type { JourneyStepRef, StepRecord } from './types';
1
+ import type { JourneyHttpScore, JourneyStampOptions } from './request-policy';
2
+ import type { StepRecord } from './types';
3
+ /** Cross-realm brand so duplicate package copies can unwrap stamps safely. */
4
+ export declare const JOURNEY_STEP_STAMP_BRAND: unique symbol;
2
5
  /**
3
- * Non-plain wrapper for {@link StepHandle.tag}.
6
+ * Non-plain wrapper for {@link StepHandle.stamp}.
4
7
  *
5
8
  * jQuery `ajaxSetup` / axios `mergeConfig` deep-merge plain objects. A raw
6
9
  * {@link StepRecord} is circular (`step.journey.steps → step`), so putting it
7
10
  * on ajax/axios options causes "Maximum call stack size exceeded". Class
8
11
  * instances are assigned by reference instead of recursed.
9
12
  */
10
- export declare class JourneyStepTag {
13
+ export declare class JourneyStepStamp {
14
+ readonly [JOURNEY_STEP_STAMP_BRAND]: true;
15
+ /** Present only on explicit `step.stamp(score)` — never on auto-attribute. */
16
+ readonly score?: JourneyHttpScore;
17
+ /** Present only on explicit `step.stamp({ ignore: true })` — never on auto-attribute. */
18
+ readonly ignore?: boolean;
19
+ /**
20
+ * @internal Engine record — adapters unwrap via `resolveStamp` /
21
+ * `onHttpComplete`. Not part of the supported public surface.
22
+ */
11
23
  readonly step: StepRecord;
12
- constructor(step: StepRecord);
24
+ constructor(step: StepRecord, opts?: JourneyStampOptions);
25
+ /**
26
+ * Circular by design (`step.journey.steps → step`) for mergeConfig/deep-merge
27
+ * safety. Prevent accidental `JSON.stringify` (e.g. AxiosError.toJSON() includes
28
+ * config by reference) elsewhere in the app from throwing "circular structure".
29
+ */
30
+ toJSON(): string;
13
31
  }
14
- /** Unwrap `step.tag().journeyStep` or a JourneyStepTag / StepRecord stamp. */
15
- export declare function resolveJourneyStep(value: unknown): JourneyStepRef | undefined;
32
+ /**
33
+ * Same-realm stamp, or a branded foreign copy with score/ignore copied.
34
+ * Does not fall back to ambient. Raw StepRecords are not stamps.
35
+ */
36
+ export declare function adoptJourneyStepStamp(value: unknown): JourneyStepStamp | undefined;
37
+ /** @internal Unwrap a stamp to the engine record. */
38
+ export declare function resolveJourneyStep(value: unknown): StepRecord | undefined;
39
+ /** Normalize `step.stamp(fn)` / `step.stamp({ score, ignore })`. */
40
+ export declare function resolveStampOpts(scoreOrOpts?: JourneyHttpScore | JourneyStampOptions): JourneyStampOptions | undefined;
16
41
  //# sourceMappingURL=step-tag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"step-tag.d.ts","sourceRoot":"","sources":["../../src/core/step-tag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;;;GAOG;AACH,qBAAa,cAAc;IACX,QAAQ,CAAC,IAAI,EAAE,UAAU;gBAAhB,IAAI,EAAE,UAAU;CACxC;AAED,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAQ7E"}
1
+ {"version":3,"file":"step-tag.d.ts","sourceRoot":"","sources":["../../src/core/step-tag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1C,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,eAAiC,CAAC;AAEvE;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACzB,QAAQ,CAAC,CAAC,wBAAwB,CAAC,EAAG,IAAI,CAAU;IACpD,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAClC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;gBAEd,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,mBAAmB;IAMxD;;;;OAIG;IACH,MAAM,IAAI,MAAM;CAGnB;AAYD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CA2BlF;AAED,qDAAqD;AACrD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAEzE;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAC5B,WAAW,CAAC,EAAE,gBAAgB,GAAG,mBAAmB,GACrD,mBAAmB,GAAG,SAAS,CAQjC"}
@@ -9,27 +9,80 @@ function _define_property(obj, key, value) {
9
9
  } else obj[key] = value;
10
10
  return obj;
11
11
  }
12
+ /** Cross-realm brand so duplicate package copies can unwrap stamps safely. */ export const JOURNEY_STEP_STAMP_BRAND = Symbol.for('st.journey.stamp');
13
+ let _JOURNEY_STEP_STAMP_BRAND = JOURNEY_STEP_STAMP_BRAND;
12
14
  /**
13
- * Non-plain wrapper for {@link StepHandle.tag}.
15
+ * Non-plain wrapper for {@link StepHandle.stamp}.
14
16
  *
15
17
  * jQuery `ajaxSetup` / axios `mergeConfig` deep-merge plain objects. A raw
16
18
  * {@link StepRecord} is circular (`step.journey.steps → step`), so putting it
17
19
  * on ajax/axios options causes "Maximum call stack size exceeded". Class
18
20
  * instances are assigned by reference instead of recursed.
19
- */ export class JourneyStepTag {
20
- constructor(step){
21
- _define_property(this, "step", void 0);
21
+ */ export class JourneyStepStamp {
22
+ /**
23
+ * Circular by design (`step.journey.steps step`) for mergeConfig/deep-merge
24
+ * safety. Prevent accidental `JSON.stringify` (e.g. AxiosError.toJSON() includes
25
+ * config by reference) elsewhere in the app from throwing "circular structure".
26
+ */ toJSON() {
27
+ return '[JourneyStepStamp]';
28
+ }
29
+ constructor(step, opts){
30
+ _define_property(this, _JOURNEY_STEP_STAMP_BRAND, true);
31
+ /** Present only on explicit `step.stamp(score)` — never on auto-attribute. */ _define_property(this, "score", void 0);
32
+ /** Present only on explicit `step.stamp({ ignore: true })` — never on auto-attribute. */ _define_property(this, "ignore", void 0);
33
+ /**
34
+ * @internal Engine record — adapters unwrap via `resolveStamp` /
35
+ * `onHttpComplete`. Not part of the supported public surface.
36
+ */ _define_property(this, "step", void 0);
22
37
  this.step = step;
38
+ this.score = opts === null || opts === void 0 ? void 0 : opts.score;
39
+ this.ignore = opts === null || opts === void 0 ? void 0 : opts.ignore;
23
40
  }
24
41
  }
25
- /** Unwrap `step.tag().journeyStep` or a JourneyStepTag / StepRecord stamp. */ export function resolveJourneyStep(value) {
26
- if (value instanceof JourneyStepTag) {
27
- return value.step;
42
+ function isStepRecord(value) {
43
+ const record = value;
44
+ return typeof record.name === 'string' && record.journey != null && typeof record.journey === 'object' && typeof record.journey.name === 'string';
45
+ }
46
+ /**
47
+ * Same-realm stamp, or a branded foreign copy with score/ignore copied.
48
+ * Does not fall back to ambient. Raw StepRecords are not stamps.
49
+ */ export function adoptJourneyStepStamp(value) {
50
+ if (value == null || typeof value !== 'object') {
51
+ return undefined;
28
52
  }
29
- if (value && typeof value === 'object') {
53
+ if (value instanceof JourneyStepStamp) {
30
54
  return value;
31
55
  }
32
- return undefined;
56
+ const branded = value;
57
+ if (branded[JOURNEY_STEP_STAMP_BRAND] !== true || branded.step == null) {
58
+ return undefined;
59
+ }
60
+ if (typeof branded.step !== 'object' || !isStepRecord(branded.step)) {
61
+ return undefined;
62
+ }
63
+ const opts = {};
64
+ if (typeof branded.score === 'function') {
65
+ opts.score = branded.score;
66
+ }
67
+ if (branded.ignore === true) {
68
+ opts.ignore = true;
69
+ }
70
+ return new JourneyStepStamp(branded.step, opts);
71
+ }
72
+ /** @internal Unwrap a stamp to the engine record. */ export function resolveJourneyStep(value) {
73
+ var _adoptJourneyStepStamp;
74
+ return (_adoptJourneyStepStamp = adoptJourneyStepStamp(value)) === null || _adoptJourneyStepStamp === void 0 ? void 0 : _adoptJourneyStepStamp.step;
75
+ }
76
+ /** Normalize `step.stamp(fn)` / `step.stamp({ score, ignore })`. */ export function resolveStampOpts(scoreOrOpts) {
77
+ if (scoreOrOpts == null) {
78
+ return undefined;
79
+ }
80
+ if (typeof scoreOrOpts === 'function') {
81
+ return {
82
+ score: scoreOrOpts
83
+ };
84
+ }
85
+ return scoreOrOpts;
33
86
  }
34
87
 
35
88
  //# sourceMappingURL=step-tag.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/step-tag.ts"],"sourcesContent":["import type { JourneyStepRef, StepRecord } from './types';\n\n/**\n * Non-plain wrapper for {@link StepHandle.tag}.\n *\n * jQuery `ajaxSetup` / axios `mergeConfig` deep-merge plain objects. A raw\n * {@link StepRecord} is circular (`step.journey.steps → step`), so putting it\n * on ajax/axios options causes \"Maximum call stack size exceeded\". Class\n * instances are assigned by reference instead of recursed.\n */\nexport class JourneyStepTag {\n constructor(readonly step: StepRecord) {}\n}\n\n/** Unwrap `step.tag().journeyStep` or a JourneyStepTag / StepRecord stamp. */\nexport function resolveJourneyStep(value: unknown): JourneyStepRef | undefined {\n if (value instanceof JourneyStepTag) {\n return value.step;\n }\n if (value && typeof value === 'object') {\n return value as JourneyStepRef;\n }\n return undefined;\n}\n"],"names":["JourneyStepTag","step","resolveJourneyStep","value","undefined"],"mappings":";;;;;;;;;;;AAEA;;;;;;;CAOC,GACD,OAAO,MAAMA;IACT,YAAY,AAASC,IAAgB,CAAE;;aAAlBA,OAAAA;IAAmB;AAC5C;AAEA,4EAA4E,GAC5E,OAAO,SAASC,mBAAmBC,KAAc;IAC7C,IAAIA,iBAAiBH,gBAAgB;QACjC,OAAOG,MAAMF,IAAI;IACrB;IACA,IAAIE,SAAS,OAAOA,UAAU,UAAU;QACpC,OAAOA;IACX;IACA,OAAOC;AACX"}
1
+ {"version":3,"sources":["../../src/core/step-tag.ts"],"sourcesContent":["import type { JourneyHttpScore, JourneyStampOptions } from './request-policy';\nimport type { StepRecord } from './types';\n\n/** Cross-realm brand so duplicate package copies can unwrap stamps safely. */\nexport const JOURNEY_STEP_STAMP_BRAND = Symbol.for('st.journey.stamp');\n\n/**\n * Non-plain wrapper for {@link StepHandle.stamp}.\n *\n * jQuery `ajaxSetup` / axios `mergeConfig` deep-merge plain objects. A raw\n * {@link StepRecord} is circular (`step.journey.steps → step`), so putting it\n * on ajax/axios options causes \"Maximum call stack size exceeded\". Class\n * instances are assigned by reference instead of recursed.\n */\nexport class JourneyStepStamp {\n readonly [JOURNEY_STEP_STAMP_BRAND] = true as const;\n /** Present only on explicit `step.stamp(score)` — never on auto-attribute. */\n readonly score?: JourneyHttpScore;\n /** Present only on explicit `step.stamp({ ignore: true })` — never on auto-attribute. */\n readonly ignore?: boolean;\n\n /**\n * @internal Engine record — adapters unwrap via `resolveStamp` /\n * `onHttpComplete`. Not part of the supported public surface.\n */\n readonly step: StepRecord;\n\n constructor(step: StepRecord, opts?: JourneyStampOptions) {\n this.step = step;\n this.score = opts?.score;\n this.ignore = opts?.ignore;\n }\n\n /**\n * Circular by design (`step.journey.steps → step`) for mergeConfig/deep-merge\n * safety. Prevent accidental `JSON.stringify` (e.g. AxiosError.toJSON() includes\n * config by reference) elsewhere in the app from throwing \"circular structure\".\n */\n toJSON(): string {\n return '[JourneyStepStamp]';\n }\n}\n\nfunction isStepRecord(value: object): value is StepRecord {\n const record = value as StepRecord;\n return (\n typeof record.name === 'string' &&\n record.journey != null &&\n typeof record.journey === 'object' &&\n typeof (record.journey as { name?: unknown }).name === 'string'\n );\n}\n\n/**\n * Same-realm stamp, or a branded foreign copy with score/ignore copied.\n * Does not fall back to ambient. Raw StepRecords are not stamps.\n */\nexport function adoptJourneyStepStamp(value: unknown): JourneyStepStamp | undefined {\n if (value == null || typeof value !== 'object') {\n return undefined;\n }\n if (value instanceof JourneyStepStamp) {\n return value;\n }\n const branded = value as {\n [JOURNEY_STEP_STAMP_BRAND]?: unknown;\n step?: unknown;\n score?: unknown;\n ignore?: unknown;\n };\n if (branded[JOURNEY_STEP_STAMP_BRAND] !== true || branded.step == null) {\n return undefined;\n }\n if (typeof branded.step !== 'object' || !isStepRecord(branded.step)) {\n return undefined;\n }\n const opts: JourneyStampOptions = {};\n if (typeof branded.score === 'function') {\n opts.score = branded.score as JourneyHttpScore;\n }\n if (branded.ignore === true) {\n opts.ignore = true;\n }\n return new JourneyStepStamp(branded.step, opts);\n}\n\n/** @internal Unwrap a stamp to the engine record. */\nexport function resolveJourneyStep(value: unknown): StepRecord | undefined {\n return adoptJourneyStepStamp(value)?.step;\n}\n\n/** Normalize `step.stamp(fn)` / `step.stamp({ score, ignore })`. */\nexport function resolveStampOpts(\n scoreOrOpts?: JourneyHttpScore | JourneyStampOptions\n): JourneyStampOptions | undefined {\n if (scoreOrOpts == null) {\n return undefined;\n }\n if (typeof scoreOrOpts === 'function') {\n return { score: scoreOrOpts };\n }\n return scoreOrOpts;\n}\n"],"names":["JOURNEY_STEP_STAMP_BRAND","Symbol","for","JourneyStepStamp","toJSON","step","opts","score","ignore","isStepRecord","value","record","name","journey","adoptJourneyStepStamp","undefined","branded","resolveJourneyStep","resolveStampOpts","scoreOrOpts"],"mappings":";;;;;;;;;;;AAGA,4EAA4E,GAC5E,OAAO,MAAMA,2BAA2BC,OAAOC,GAAG,CAAC,oBAAoB;IAWzDF,4BAAAA;AATd;;;;;;;CAOC,GACD,OAAO,MAAMG;IAmBT;;;;KAIC,GACDC,SAAiB;QACb,OAAO;IACX;IAbA,YAAYC,IAAgB,EAAEC,IAA0B,CAAE;QAZ1D,uBAAUN,2BAA4B;QACtC,4EAA4E,GAC5E,uBAASO,SAAT,KAAA;QACA,uFAAuF,GACvF,uBAASC,UAAT,KAAA;QAEA;;;KAGC,GACD,uBAASH,QAAT,KAAA;QAGI,IAAI,CAACA,IAAI,GAAGA;QACZ,IAAI,CAACE,KAAK,GAAGD,iBAAAA,2BAAAA,KAAMC,KAAK;QACxB,IAAI,CAACC,MAAM,GAAGF,iBAAAA,2BAAAA,KAAME,MAAM;IAC9B;AAUJ;AAEA,SAASC,aAAaC,KAAa;IAC/B,MAAMC,SAASD;IACf,OACI,OAAOC,OAAOC,IAAI,KAAK,YACvBD,OAAOE,OAAO,IAAI,QAClB,OAAOF,OAAOE,OAAO,KAAK,YAC1B,OAAO,AAACF,OAAOE,OAAO,CAAwBD,IAAI,KAAK;AAE/D;AAEA;;;CAGC,GACD,OAAO,SAASE,sBAAsBJ,KAAc;IAChD,IAAIA,SAAS,QAAQ,OAAOA,UAAU,UAAU;QAC5C,OAAOK;IACX;IACA,IAAIL,iBAAiBP,kBAAkB;QACnC,OAAOO;IACX;IACA,MAAMM,UAAUN;IAMhB,IAAIM,OAAO,CAAChB,yBAAyB,KAAK,QAAQgB,QAAQX,IAAI,IAAI,MAAM;QACpE,OAAOU;IACX;IACA,IAAI,OAAOC,QAAQX,IAAI,KAAK,YAAY,CAACI,aAAaO,QAAQX,IAAI,GAAG;QACjE,OAAOU;IACX;IACA,MAAMT,OAA4B,CAAC;IACnC,IAAI,OAAOU,QAAQT,KAAK,KAAK,YAAY;QACrCD,KAAKC,KAAK,GAAGS,QAAQT,KAAK;IAC9B;IACA,IAAIS,QAAQR,MAAM,KAAK,MAAM;QACzBF,KAAKE,MAAM,GAAG;IAClB;IACA,OAAO,IAAIL,iBAAiBa,QAAQX,IAAI,EAAEC;AAC9C;AAEA,mDAAmD,GACnD,OAAO,SAASW,mBAAmBP,KAAc;QACtCI;IAAP,QAAOA,yBAAAA,sBAAsBJ,oBAAtBI,6CAAAA,uBAA8BT,IAAI;AAC7C;AAEA,kEAAkE,GAClE,OAAO,SAASa,iBACZC,WAAoD;IAEpD,IAAIA,eAAe,MAAM;QACrB,OAAOJ;IACX;IACA,IAAI,OAAOI,gBAAgB,YAAY;QACnC,OAAO;YAAEZ,OAAOY;QAAY;IAChC;IACA,OAAOA;AACX"}