@servicetitan/journey 2.0.0 → 2.1.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 (150) hide show
  1. package/dist/__test-utils__/test-runtime.d.ts.map +1 -0
  2. package/dist/__test-utils__/test-runtime.js +47 -0
  3. package/dist/__test-utils__/test-runtime.js.map +1 -0
  4. package/dist/__tests__/core/ambient.test.d.ts.map +1 -0
  5. package/dist/__tests__/core/api.test.d.ts +2 -0
  6. package/dist/__tests__/core/api.test.d.ts.map +1 -0
  7. package/dist/__tests__/core/define-journey.test.d.ts.map +1 -0
  8. package/dist/__tests__/core/requests.test.d.ts.map +1 -0
  9. package/dist/__tests__/core/runtime.test.d.ts.map +1 -0
  10. package/dist/__tests__/core/step.test.d.ts.map +1 -0
  11. package/dist/__tests__/core/timeouts.test.d.ts.map +1 -0
  12. package/dist/__tests__/global.test.d.ts +3 -0
  13. package/dist/__tests__/global.test.d.ts.map +1 -0
  14. package/dist/__tests__/integrations/axios.test.d.ts.map +1 -0
  15. package/dist/__tests__/integrations/context.test.d.ts.map +1 -0
  16. package/dist/__tests__/integrations/expose-app-journey.test.d.ts.map +1 -0
  17. package/dist/__tests__/integrations/fetch.test.d.ts.map +1 -0
  18. package/dist/__tests__/integrations/jquery.test.d.ts.map +1 -0
  19. package/dist/__tests__/integrations/request-key.test.d.ts.map +1 -0
  20. package/dist/__tests__/integrations/scope.test.d.ts.map +1 -0
  21. package/dist/__tests__/sinks/console.test.d.ts +2 -0
  22. package/dist/__tests__/sinks/console.test.d.ts.map +1 -0
  23. package/dist/__tests__/sinks/datadog.test.d.ts.map +1 -0
  24. package/dist/__tests__/sinks/sinks.test.d.ts.map +1 -0
  25. package/dist/config.d.ts +8 -4
  26. package/dist/config.d.ts.map +1 -1
  27. package/dist/config.js +19 -13
  28. package/dist/config.js.map +1 -1
  29. package/dist/core/{registry.d.ts → api.d.ts} +2 -22
  30. package/dist/core/api.d.ts.map +1 -0
  31. package/dist/core/{registry.js → api.js} +13 -40
  32. package/dist/core/api.js.map +1 -0
  33. package/dist/core/endpoint-policy.d.ts.map +1 -0
  34. package/dist/core/endpoint-policy.js.map +1 -0
  35. package/dist/core/index.d.ts +4 -4
  36. package/dist/core/index.d.ts.map +1 -1
  37. package/dist/core/index.js +3 -2
  38. package/dist/core/index.js.map +1 -1
  39. package/dist/core/runtime.d.ts +35 -7
  40. package/dist/core/runtime.d.ts.map +1 -1
  41. package/dist/core/runtime.js +39 -5
  42. package/dist/core/runtime.js.map +1 -1
  43. package/dist/core/step-tag.d.ts +6 -0
  44. package/dist/core/step-tag.d.ts.map +1 -1
  45. package/dist/core/step-tag.js +7 -0
  46. package/dist/core/step-tag.js.map +1 -1
  47. package/dist/core/types.d.ts +3 -1
  48. package/dist/core/types.d.ts.map +1 -1
  49. package/dist/core/types.js.map +1 -1
  50. package/dist/global.d.ts +67 -0
  51. package/dist/global.d.ts.map +1 -0
  52. package/dist/global.js +116 -0
  53. package/dist/global.js.map +1 -0
  54. package/dist/index.d.ts +8 -3
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +11 -5
  57. package/dist/index.js.map +1 -1
  58. package/dist/integrations/fetch.d.ts +3 -2
  59. package/dist/integrations/fetch.d.ts.map +1 -1
  60. package/dist/integrations/fetch.js.map +1 -1
  61. package/dist/integrations/jquery/index.d.ts +2 -2
  62. package/dist/integrations/jquery/index.d.ts.map +1 -1
  63. package/dist/integrations/jquery/index.js +3 -2
  64. package/dist/integrations/jquery/index.js.map +1 -1
  65. package/dist/integrations/react/scope.d.ts.map +1 -1
  66. package/dist/integrations/react/scope.js +3 -2
  67. package/dist/integrations/react/scope.js.map +1 -1
  68. package/dist/sinks/console.d.ts +11 -0
  69. package/dist/sinks/console.d.ts.map +1 -0
  70. package/dist/sinks/console.js +18 -0
  71. package/dist/sinks/console.js.map +1 -0
  72. package/dist/sinks/datadog.d.ts +12 -1
  73. package/dist/sinks/datadog.d.ts.map +1 -1
  74. package/dist/sinks/datadog.js +28 -7
  75. package/dist/sinks/datadog.js.map +1 -1
  76. package/package.json +2 -2
  77. package/src/{__mocks__ → __test-utils__}/test-runtime.ts +6 -2
  78. package/src/__tests__/config.test.ts +9 -12
  79. package/src/__tests__/{ambient.test.ts → core/ambient.test.ts} +8 -7
  80. package/src/__tests__/{registry.test.ts → core/api.test.ts} +30 -25
  81. package/src/__tests__/{define-journey.test.ts → core/define-journey.test.ts} +5 -4
  82. package/src/__tests__/{requests.test.ts → core/requests.test.ts} +12 -8
  83. package/src/__tests__/{runtime.test.ts → core/runtime.test.ts} +18 -18
  84. package/src/__tests__/{step.test.ts → core/step.test.ts} +16 -18
  85. package/src/__tests__/{timeouts.test.ts → core/timeouts.test.ts} +15 -10
  86. package/src/__tests__/global.test.ts +113 -0
  87. package/src/__tests__/{axios.test.ts → integrations/axios.test.ts} +46 -15
  88. package/src/__tests__/{context.test.tsx → integrations/context.test.tsx} +1 -1
  89. package/src/__tests__/{expose-app-journey.test.ts → integrations/expose-app-journey.test.ts} +2 -2
  90. package/src/__tests__/{fetch.test.ts → integrations/fetch.test.ts} +6 -6
  91. package/src/__tests__/{jquery.test.ts → integrations/jquery.test.ts} +49 -12
  92. package/src/__tests__/{request-key.test.ts → integrations/request-key.test.ts} +1 -1
  93. package/src/__tests__/{scope.test.tsx → integrations/scope.test.tsx} +4 -4
  94. package/src/__tests__/sinks/console.test.ts +98 -0
  95. package/src/__tests__/{datadog.test.ts → sinks/datadog.test.ts} +62 -5
  96. package/src/__tests__/{sinks.test.ts → sinks/sinks.test.ts} +13 -12
  97. package/src/config.ts +20 -12
  98. package/src/core/{registry.ts → api.ts} +12 -65
  99. package/src/core/index.ts +5 -14
  100. package/src/core/runtime.ts +56 -7
  101. package/src/core/step-tag.ts +9 -0
  102. package/src/core/types.ts +3 -1
  103. package/src/global.ts +196 -0
  104. package/src/index.ts +20 -7
  105. package/src/integrations/fetch.ts +2 -2
  106. package/src/integrations/jquery/index.ts +4 -9
  107. package/src/integrations/react/scope.tsx +3 -2
  108. package/src/sinks/console.ts +20 -0
  109. package/src/sinks/datadog.ts +31 -6
  110. package/dist/__mocks__/test-runtime.d.ts.map +0 -1
  111. package/dist/__tests__/ambient.test.d.ts.map +0 -1
  112. package/dist/__tests__/axios.test.d.ts.map +0 -1
  113. package/dist/__tests__/context.test.d.ts.map +0 -1
  114. package/dist/__tests__/datadog.test.d.ts.map +0 -1
  115. package/dist/__tests__/define-journey.test.d.ts.map +0 -1
  116. package/dist/__tests__/expose-app-journey.test.d.ts.map +0 -1
  117. package/dist/__tests__/fetch.test.d.ts.map +0 -1
  118. package/dist/__tests__/jquery.test.d.ts.map +0 -1
  119. package/dist/__tests__/registry.test.d.ts +0 -2
  120. package/dist/__tests__/registry.test.d.ts.map +0 -1
  121. package/dist/__tests__/request-key.test.d.ts.map +0 -1
  122. package/dist/__tests__/requests.test.d.ts.map +0 -1
  123. package/dist/__tests__/runtime.test.d.ts.map +0 -1
  124. package/dist/__tests__/scope.test.d.ts.map +0 -1
  125. package/dist/__tests__/sinks.test.d.ts.map +0 -1
  126. package/dist/__tests__/step.test.d.ts.map +0 -1
  127. package/dist/__tests__/timeouts.test.d.ts.map +0 -1
  128. package/dist/core/registry.d.ts.map +0 -1
  129. package/dist/core/registry.js.map +0 -1
  130. package/dist/endpoint-policy.d.ts.map +0 -1
  131. package/dist/endpoint-policy.js.map +0 -1
  132. /package/dist/{__mocks__ → __test-utils__}/test-runtime.d.ts +0 -0
  133. /package/dist/__tests__/{ambient.test.d.ts → core/ambient.test.d.ts} +0 -0
  134. /package/dist/__tests__/{define-journey.test.d.ts → core/define-journey.test.d.ts} +0 -0
  135. /package/dist/__tests__/{requests.test.d.ts → core/requests.test.d.ts} +0 -0
  136. /package/dist/__tests__/{runtime.test.d.ts → core/runtime.test.d.ts} +0 -0
  137. /package/dist/__tests__/{step.test.d.ts → core/step.test.d.ts} +0 -0
  138. /package/dist/__tests__/{timeouts.test.d.ts → core/timeouts.test.d.ts} +0 -0
  139. /package/dist/__tests__/{axios.test.d.ts → integrations/axios.test.d.ts} +0 -0
  140. /package/dist/__tests__/{context.test.d.ts → integrations/context.test.d.ts} +0 -0
  141. /package/dist/__tests__/{expose-app-journey.test.d.ts → integrations/expose-app-journey.test.d.ts} +0 -0
  142. /package/dist/__tests__/{fetch.test.d.ts → integrations/fetch.test.d.ts} +0 -0
  143. /package/dist/__tests__/{jquery.test.d.ts → integrations/jquery.test.d.ts} +0 -0
  144. /package/dist/__tests__/{request-key.test.d.ts → integrations/request-key.test.d.ts} +0 -0
  145. /package/dist/__tests__/{scope.test.d.ts → integrations/scope.test.d.ts} +0 -0
  146. /package/dist/__tests__/{datadog.test.d.ts → sinks/datadog.test.d.ts} +0 -0
  147. /package/dist/__tests__/{sinks.test.d.ts → sinks/sinks.test.d.ts} +0 -0
  148. /package/dist/{endpoint-policy.d.ts → core/endpoint-policy.d.ts} +0 -0
  149. /package/dist/{endpoint-policy.js → core/endpoint-policy.js} +0 -0
  150. /package/src/{endpoint-policy.ts → core/endpoint-policy.ts} +0 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/*\n * Force-evaluate config so the default Datadog sink registers even when consumers only\n * import core APIs (defineJourney, etc.). Paired with package.json \"sideEffects\" for\n * config — otherwise bundlers with sideEffects:false would drop an unused re-export.\n */\nimport './config';\n\nexport {\n // Custom transport adapters only.\n activeJourneyStep,\n // Prefer defineJourney(...).complete/fail/… free helpers for name-from-context call sites.\n completeJourney,\n defineJourney,\n excludeJourney,\n failJourney,\n journeyStep,\n reportBackendRequest,\n resolveJourneyStep,\n setJourneyTags,\n JourneyStepTag,\n type JourneyDef,\n type JourneyHandle,\n type JourneyNameLike,\n type JourneyStepOptions,\n type JourneyStepRef,\n type JourneyStepTarget,\n type StepHandle,\n} from './core';\n\nexport {\n configureJourney,\n type AppRequestTimeouts,\n type EndpointPolicy,\n type JourneyConfig,\n} from './config';\n\nexport type { JourneySink } from './core';\n\n/** Test helperclears open journeys / ambient steps on the default engine. */\nexport { resetJourney } from './core';\n\nexport { instrumentAxios } from './integrations/axios';\nexport { instrumentFetch } from './integrations/fetch';\nexport { exposeAppJourney, instrumentJquery } from './integrations/jquery';\nexport { requestKey, type JourneyTimedMeta } from './integrations/request-key';\nexport { sendToDatadog, setJourneyRum } from './sinks/datadog';\n\nexport type { JourneyEvent, JourneyStepEvent, TagValue } from './core';\n\nexport { useJourneyName, useOptionalJourneyName } from './integrations/react/context';\nexport { JourneyScope } from './integrations/react/scope';\n"],"names":["activeJourneyStep","completeJourney","defineJourney","excludeJourney","failJourney","journeyStep","reportBackendRequest","resolveJourneyStep","setJourneyTags","JourneyStepTag","configureJourney","resetJourney","instrumentAxios","instrumentFetch","exposeAppJourney","instrumentJquery","requestKey","sendToDatadog","setJourneyRum","useJourneyName","useOptionalJourneyName","JourneyScope"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,WAAW;AAElB,SACI,kCAAkC;AAClCA,iBAAiB,EACjB,6FAA6F;AAC7FC,eAAe,EACfC,aAAa,EACbC,cAAc,EACdC,WAAW,EACXC,WAAW,EACXC,oBAAoB,EACpBC,kBAAkB,EAClBC,cAAc,EACdC,cAAc,QAQX,SAAS;AAEhB,SACIC,gBAAgB,QAIb,WAAW;AAIlB,8EAA8E,GAC9E,SAASC,YAAY,QAAQ,SAAS;AAEtC,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,gBAAgB,EAAEC,gBAAgB,QAAQ,wBAAwB;AAC3E,SAASC,UAAU,QAA+B,6BAA6B;AAC/E,SAASC,aAAa,EAAEC,aAAa,QAAQ,kBAAkB;AAI/D,SAASC,cAAc,EAAEC,sBAAsB,QAAQ,+BAA+B;AACtF,SAASC,YAAY,QAAQ,6BAA6B"}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/*\n * Force-evaluate config so the default Datadog sink registers even when consumers only\n * import core APIs (defineJourney, etc.). Paired with package.json \"sideEffects\" for\n * config — otherwise bundlers with sideEffects:false would drop an unused re-export.\n */\nimport './config';\n\nexport {\n // Preferred app API.\n defineJourney,\n // Name-string lifecycle (prefer handle methods when you own the journey).\n completeJourney,\n excludeJourney,\n failJourney,\n journeyStep,\n setJourneyTags,\n // Custom transport adapters / request attribution.\n activeJourneyStep,\n reportBackendRequest,\n resolveJourneyStep,\n JourneyStepTag,\n type JourneyDef,\n type JourneyHandle,\n type JourneyNameLike,\n type JourneyStepOptions,\n type JourneyStepRef,\n type JourneyStepTarget,\n type StepHandle,\n} from './core';\n\nexport {\n configureJourney,\n type AppRequestTimeouts,\n type EndpointPolicy,\n type JourneyConfig,\n} from './config';\n\nexport type { JourneySink } from './core';\n\n/**\n * @internal Accidentally exported removing it is a breaking change, so it stays\n * for compatibility. Not part of the supported public API. Test helper only.\n */\nexport { resetJourney } from './core';\n\nexport { instrumentAxios } from './integrations/axios';\nexport { instrumentFetch } from './integrations/fetch';\nexport { exposeAppJourney, instrumentJquery } from './integrations/jquery';\nexport { requestKey, type JourneyTimedMeta } from './integrations/request-key';\nexport {\n disableJourney,\n disableJourneyDebugging,\n enableJourney,\n enableJourneyDebugging,\n isJourneyDebugEnabled,\n isJourneyEnabled,\n} from './global';\nexport { sendToConsole } from './sinks/console';\nexport { normalizeTagValue, sendToDatadog, setJourneyRum } from './sinks/datadog';\n\nexport type { JourneyEvent, JourneyStepEvent, TagValue } from './core';\n\nexport { useJourneyName, useOptionalJourneyName } from './integrations/react/context';\nexport { JourneyScope } from './integrations/react/scope';\n"],"names":["defineJourney","completeJourney","excludeJourney","failJourney","journeyStep","setJourneyTags","activeJourneyStep","reportBackendRequest","resolveJourneyStep","JourneyStepTag","configureJourney","resetJourney","instrumentAxios","instrumentFetch","exposeAppJourney","instrumentJquery","requestKey","disableJourney","disableJourneyDebugging","enableJourney","enableJourneyDebugging","isJourneyDebugEnabled","isJourneyEnabled","sendToConsole","normalizeTagValue","sendToDatadog","setJourneyRum","useJourneyName","useOptionalJourneyName","JourneyScope"],"mappings":"AAAA;;;;CAIC,GACD,OAAO,WAAW;AAElB,SACI,qBAAqB;AACrBA,aAAa,EACb,0EAA0E;AAC1EC,eAAe,EACfC,cAAc,EACdC,WAAW,EACXC,WAAW,EACXC,cAAc,EACd,mDAAmD;AACnDC,iBAAiB,EACjBC,oBAAoB,EACpBC,kBAAkB,EAClBC,cAAc,QAQX,SAAS;AAEhB,SACIC,gBAAgB,QAIb,WAAW;AAIlB;;;CAGC,GACD,SAASC,YAAY,QAAQ,SAAS;AAEtC,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,eAAe,QAAQ,uBAAuB;AACvD,SAASC,gBAAgB,EAAEC,gBAAgB,QAAQ,wBAAwB;AAC3E,SAASC,UAAU,QAA+B,6BAA6B;AAC/E,SACIC,cAAc,EACdC,uBAAuB,EACvBC,aAAa,EACbC,sBAAsB,EACtBC,qBAAqB,EACrBC,gBAAgB,QACb,WAAW;AAClB,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,iBAAiB,EAAEC,aAAa,EAAEC,aAAa,QAAQ,kBAAkB;AAIlF,SAASC,cAAc,EAAEC,sBAAsB,QAAQ,+BAA+B;AACtF,SAASC,YAAY,QAAQ,6BAA6B"}
@@ -1,9 +1,9 @@
1
1
  /** Minimal structural fetch shape. */
2
- export type FetchLike = (input: any, init?: any) => Promise<{
2
+ type FetchLike = (input: any, init?: any) => Promise<{
3
3
  status: number;
4
4
  }>;
5
5
  /** Holder of a `fetch` property — globalThis by default, or a scoped object. */
6
- export interface FetchTarget {
6
+ interface FetchTarget {
7
7
  fetch: FetchLike;
8
8
  }
9
9
  export interface InstrumentFetchOptions {
@@ -18,4 +18,5 @@ export interface InstrumentFetchOptions {
18
18
  * function that puts the original fetch back. Observation-only.
19
19
  */
20
20
  export declare function instrumentFetch(options?: InstrumentFetchOptions): () => void;
21
+ export {};
21
22
  //# sourceMappingURL=fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/integrations/fetch.ts"],"names":[],"mappings":"AAGA,sCAAsC;AACtC,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEhF,gFAAgF;AAChF,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACnC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,IAAI,CAyDhF"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/integrations/fetch.ts"],"names":[],"mappings":"AAGA,sCAAsC;AACtC,KAAK,SAAS,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEzE,gFAAgF;AAChF,UAAU,WAAW;IACjB,KAAK,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACnC,+DAA+D;IAC/D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAkBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,MAAM,IAAI,CAyDhF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/integrations/fetch.ts"],"sourcesContent":["import { activeJourneyStep, reportBackendRequest, resolveJourneyStep } from '../core';\nimport { requestKey, type JourneyTimedMeta } from './request-key';\n\n/** Minimal structural fetch shape. */\nexport type FetchLike = (input: any, init?: any) => Promise<{ status: number }>;\n\n/** Holder of a `fetch` property — globalThis by default, or a scoped object. */\nexport interface FetchTarget {\n fetch: FetchLike;\n}\n\nexport interface InstrumentFetchOptions {\n /** Object whose `fetch` is wrapped. Defaults to globalThis. */\n target?: FetchTarget;\n /** Home API base URL for request-key origin resolution. */\n baseURL?: string;\n}\n\nconst instrumented = new WeakSet<object>();\nconst originals = new WeakMap<object, FetchLike>();\n\nfunction resolveUrl(input: any): string | undefined {\n if (typeof input === 'string') {\n return input;\n }\n if (input && typeof input.url === 'string') {\n return input.url;\n }\n if (input && typeof input.href === 'string') {\n return input.href;\n }\n return undefined;\n}\n\n/**\n * Wrap a target's fetch so requests inside a journeyStep are attributed and timed.\n * Call once per target (idempotent — second call is a no-op). Returns a restore\n * function that puts the original fetch back. Observation-only.\n */\nexport function instrumentFetch(options: InstrumentFetchOptions = {}): () => void {\n const target = options.target ?? (globalThis as unknown as FetchTarget);\n const key = target as object;\n\n if (instrumented.has(key)) {\n return () => {};\n }\n\n const original = target.fetch;\n originals.set(key, original);\n instrumented.add(key);\n\n // Call through `target` — native fetch throws \"Illegal invocation\" with the wrong receiver.\n const wrapped: FetchLike = (input, init) => {\n // Prefer explicit step.tag(); else soft ambient.\n const explicit = resolveJourneyStep((init as JourneyTimedMeta | undefined)?.journeyStep);\n const step = explicit ?? activeJourneyStep();\n if (!step) {\n return original.call(target, input, init);\n }\n\n const start = globalThis.performance.now();\n const endpointKey = requestKey(resolveUrl(input), undefined, options.baseURL);\n const promise = original.call(target, input, init);\n return promise.then(\n response => {\n reportBackendRequest(\n step,\n response.status,\n globalThis.performance.now() - start,\n endpointKey\n );\n return response;\n },\n (error: unknown) => {\n reportBackendRequest(\n step,\n undefined,\n globalThis.performance.now() - start,\n endpointKey\n );\n // Passthrough original rejection reason; do not wrap (identity / AbortError).\n return Promise.reject(error as Error);\n }\n );\n };\n\n target.fetch = wrapped;\n\n return () => {\n if (!instrumented.has(key)) {\n return;\n }\n target.fetch = originals.get(key) ?? original;\n instrumented.delete(key);\n originals.delete(key);\n };\n}\n"],"names":["activeJourneyStep","reportBackendRequest","resolveJourneyStep","requestKey","instrumented","WeakSet","originals","WeakMap","resolveUrl","input","url","href","undefined","instrumentFetch","options","target","globalThis","key","has","original","fetch","set","add","wrapped","init","explicit","journeyStep","step","call","start","performance","now","endpointKey","baseURL","promise","then","response","status","error","Promise","reject","get","delete"],"mappings":"AAAA,SAASA,iBAAiB,EAAEC,oBAAoB,EAAEC,kBAAkB,QAAQ,UAAU;AACtF,SAASC,UAAU,QAA+B,gBAAgB;AAiBlE,MAAMC,eAAe,IAAIC;AACzB,MAAMC,YAAY,IAAIC;AAEtB,SAASC,WAAWC,KAAU;IAC1B,IAAI,OAAOA,UAAU,UAAU;QAC3B,OAAOA;IACX;IACA,IAAIA,SAAS,OAAOA,MAAMC,GAAG,KAAK,UAAU;QACxC,OAAOD,MAAMC,GAAG;IACpB;IACA,IAAID,SAAS,OAAOA,MAAME,IAAI,KAAK,UAAU;QACzC,OAAOF,MAAME,IAAI;IACrB;IACA,OAAOC;AACX;AAEA;;;;CAIC,GACD,OAAO,SAASC,gBAAgBC,UAAkC,CAAC,CAAC;QACjDA;IAAf,MAAMC,UAASD,kBAAAA,QAAQC,MAAM,cAAdD,6BAAAA,kBAAmBE;IAClC,MAAMC,MAAMF;IAEZ,IAAIX,aAAac,GAAG,CAACD,MAAM;QACvB,OAAO,KAAO;IAClB;IAEA,MAAME,WAAWJ,OAAOK,KAAK;IAC7Bd,UAAUe,GAAG,CAACJ,KAAKE;IACnBf,aAAakB,GAAG,CAACL;IAEjB,4FAA4F;IAC5F,MAAMM,UAAqB,CAACd,OAAOe;QAC/B,iDAAiD;QACjD,MAAMC,WAAWvB,mBAAoBsB,iBAAAA,2BAAD,AAACA,KAAuCE,WAAW;QACvF,MAAMC,OAAOF,qBAAAA,sBAAAA,WAAYzB;QACzB,IAAI,CAAC2B,MAAM;YACP,OAAOR,SAASS,IAAI,CAACb,QAAQN,OAAOe;QACxC;QAEA,MAAMK,QAAQb,WAAWc,WAAW,CAACC,GAAG;QACxC,MAAMC,cAAc7B,WAAWK,WAAWC,QAAQG,WAAWE,QAAQmB,OAAO;QAC5E,MAAMC,UAAUf,SAASS,IAAI,CAACb,QAAQN,OAAOe;QAC7C,OAAOU,QAAQC,IAAI,CACfC,CAAAA;YACInC,qBACI0B,MACAS,SAASC,MAAM,EACfrB,WAAWc,WAAW,CAACC,GAAG,KAAKF,OAC/BG;YAEJ,OAAOI;QACX,GACA,CAACE;YACGrC,qBACI0B,MACAf,WACAI,WAAWc,WAAW,CAACC,GAAG,KAAKF,OAC/BG;YAEJ,8EAA8E;YAC9E,OAAOO,QAAQC,MAAM,CAACF;QAC1B;IAER;IAEAvB,OAAOK,KAAK,GAAGG;IAEf,OAAO;YAIYjB;QAHf,IAAI,CAACF,aAAac,GAAG,CAACD,MAAM;YACxB;QACJ;QACAF,OAAOK,KAAK,IAAGd,iBAAAA,UAAUmC,GAAG,CAACxB,kBAAdX,4BAAAA,iBAAsBa;QACrCf,aAAasC,MAAM,CAACzB;QACpBX,UAAUoC,MAAM,CAACzB;IACrB;AACJ"}
1
+ {"version":3,"sources":["../../src/integrations/fetch.ts"],"sourcesContent":["import { activeJourneyStep, reportBackendRequest, resolveJourneyStep } from '../core';\nimport { requestKey, type JourneyTimedMeta } from './request-key';\n\n/** Minimal structural fetch shape. */\ntype FetchLike = (input: any, init?: any) => Promise<{ status: number }>;\n\n/** Holder of a `fetch` property — globalThis by default, or a scoped object. */\ninterface FetchTarget {\n fetch: FetchLike;\n}\n\nexport interface InstrumentFetchOptions {\n /** Object whose `fetch` is wrapped. Defaults to globalThis. */\n target?: FetchTarget;\n /** Home API base URL for request-key origin resolution. */\n baseURL?: string;\n}\n\nconst instrumented = new WeakSet<object>();\nconst originals = new WeakMap<object, FetchLike>();\n\nfunction resolveUrl(input: any): string | undefined {\n if (typeof input === 'string') {\n return input;\n }\n if (input && typeof input.url === 'string') {\n return input.url;\n }\n if (input && typeof input.href === 'string') {\n return input.href;\n }\n return undefined;\n}\n\n/**\n * Wrap a target's fetch so requests inside a journeyStep are attributed and timed.\n * Call once per target (idempotent — second call is a no-op). Returns a restore\n * function that puts the original fetch back. Observation-only.\n */\nexport function instrumentFetch(options: InstrumentFetchOptions = {}): () => void {\n const target = options.target ?? (globalThis as unknown as FetchTarget);\n const key = target as object;\n\n if (instrumented.has(key)) {\n return () => {};\n }\n\n const original = target.fetch;\n originals.set(key, original);\n instrumented.add(key);\n\n // Call through `target` — native fetch throws \"Illegal invocation\" with the wrong receiver.\n const wrapped: FetchLike = (input, init) => {\n // Prefer explicit step.tag(); else soft ambient.\n const explicit = resolveJourneyStep((init as JourneyTimedMeta | undefined)?.journeyStep);\n const step = explicit ?? activeJourneyStep();\n if (!step) {\n return original.call(target, input, init);\n }\n\n const start = globalThis.performance.now();\n const endpointKey = requestKey(resolveUrl(input), undefined, options.baseURL);\n const promise = original.call(target, input, init);\n return promise.then(\n response => {\n reportBackendRequest(\n step,\n response.status,\n globalThis.performance.now() - start,\n endpointKey\n );\n return response;\n },\n (error: unknown) => {\n reportBackendRequest(\n step,\n undefined,\n globalThis.performance.now() - start,\n endpointKey\n );\n // Passthrough original rejection reason; do not wrap (identity / AbortError).\n return Promise.reject(error as Error);\n }\n );\n };\n\n target.fetch = wrapped;\n\n return () => {\n if (!instrumented.has(key)) {\n return;\n }\n target.fetch = originals.get(key) ?? original;\n instrumented.delete(key);\n originals.delete(key);\n };\n}\n"],"names":["activeJourneyStep","reportBackendRequest","resolveJourneyStep","requestKey","instrumented","WeakSet","originals","WeakMap","resolveUrl","input","url","href","undefined","instrumentFetch","options","target","globalThis","key","has","original","fetch","set","add","wrapped","init","explicit","journeyStep","step","call","start","performance","now","endpointKey","baseURL","promise","then","response","status","error","Promise","reject","get","delete"],"mappings":"AAAA,SAASA,iBAAiB,EAAEC,oBAAoB,EAAEC,kBAAkB,QAAQ,UAAU;AACtF,SAASC,UAAU,QAA+B,gBAAgB;AAiBlE,MAAMC,eAAe,IAAIC;AACzB,MAAMC,YAAY,IAAIC;AAEtB,SAASC,WAAWC,KAAU;IAC1B,IAAI,OAAOA,UAAU,UAAU;QAC3B,OAAOA;IACX;IACA,IAAIA,SAAS,OAAOA,MAAMC,GAAG,KAAK,UAAU;QACxC,OAAOD,MAAMC,GAAG;IACpB;IACA,IAAID,SAAS,OAAOA,MAAME,IAAI,KAAK,UAAU;QACzC,OAAOF,MAAME,IAAI;IACrB;IACA,OAAOC;AACX;AAEA;;;;CAIC,GACD,OAAO,SAASC,gBAAgBC,UAAkC,CAAC,CAAC;QACjDA;IAAf,MAAMC,UAASD,kBAAAA,QAAQC,MAAM,cAAdD,6BAAAA,kBAAmBE;IAClC,MAAMC,MAAMF;IAEZ,IAAIX,aAAac,GAAG,CAACD,MAAM;QACvB,OAAO,KAAO;IAClB;IAEA,MAAME,WAAWJ,OAAOK,KAAK;IAC7Bd,UAAUe,GAAG,CAACJ,KAAKE;IACnBf,aAAakB,GAAG,CAACL;IAEjB,4FAA4F;IAC5F,MAAMM,UAAqB,CAACd,OAAOe;QAC/B,iDAAiD;QACjD,MAAMC,WAAWvB,mBAAoBsB,iBAAAA,2BAAD,AAACA,KAAuCE,WAAW;QACvF,MAAMC,OAAOF,qBAAAA,sBAAAA,WAAYzB;QACzB,IAAI,CAAC2B,MAAM;YACP,OAAOR,SAASS,IAAI,CAACb,QAAQN,OAAOe;QACxC;QAEA,MAAMK,QAAQb,WAAWc,WAAW,CAACC,GAAG;QACxC,MAAMC,cAAc7B,WAAWK,WAAWC,QAAQG,WAAWE,QAAQmB,OAAO;QAC5E,MAAMC,UAAUf,SAASS,IAAI,CAACb,QAAQN,OAAOe;QAC7C,OAAOU,QAAQC,IAAI,CACfC,CAAAA;YACInC,qBACI0B,MACAS,SAASC,MAAM,EACfrB,WAAWc,WAAW,CAACC,GAAG,KAAKF,OAC/BG;YAEJ,OAAOI;QACX,GACA,CAACE;YACGrC,qBACI0B,MACAf,WACAI,WAAWc,WAAW,CAACC,GAAG,KAAKF,OAC/BG;YAEJ,8EAA8E;YAC9E,OAAOO,QAAQC,MAAM,CAACF;QAC1B;IAER;IAEAvB,OAAOK,KAAK,GAAGG;IAEf,OAAO;YAIYjB;QAHf,IAAI,CAACF,aAAac,GAAG,CAACD,MAAM;YACxB;QACJ;QACAF,OAAOK,KAAK,IAAGd,iBAAAA,UAAUmC,GAAG,CAACxB,kBAAdX,4BAAAA,iBAAsBa;QACrCf,aAAasC,MAAM,CAACzB;QACpBX,UAAUoC,MAAM,CAACzB;IACrB;AACJ"}
@@ -3,7 +3,7 @@ import { type JourneyDef, type JourneyHandle, type JourneyStepOptions, type Jour
3
3
  * Knockout / desktop-legacy bridge on `window.App.Journey`.
4
4
  * Prefer `defineJourney` handles; `journeyStep` / `firstOpenJourney` cover multi-journey steps.
5
5
  */
6
- export interface AppJourneyApi {
6
+ interface AppJourneyApi {
7
7
  defineJourney(def: JourneyDef): JourneyHandle;
8
8
  journeyStep<T>(journey: JourneyStepTarget, stepName: string, fn: (step: StepHandle) => T | Promise<T>, opts?: JourneyStepOptions): Promise<T>;
9
9
  firstOpenJourney(names: readonly string[]): string | null;
@@ -18,5 +18,5 @@ export type WindowWithAppJourney = Window & {
18
18
  * Optional `target` is for tests.
19
19
  */
20
20
  export declare function exposeAppJourney(target?: WindowWithAppJourney): AppJourneyApi;
21
- export { instrumentJquery, type JqueryAjaxSettings, type JqueryStatic, type JqueryXHR, } from './instrument';
21
+ export { instrumentJquery, type JqueryStatic } from './instrument';
22
22
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/jquery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,CAAC;IAC9C,WAAW,CAAC,CAAC,EACT,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACxC,IAAI,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;CAC7D;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG;IACxC,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,aAAa,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/D,CAAC;AAKF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,oBAA6B,GAAG,aAAa,CAiBrF;AAED,OAAO,EACH,gBAAgB,EAChB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,SAAS,GACjB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/jquery/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAClB,MAAM,YAAY,CAAC;AAGpB;;;GAGG;AACH,UAAU,aAAa;IACnB,aAAa,CAAC,GAAG,EAAE,UAAU,GAAG,aAAa,CAAC;IAC9C,WAAW,CAAC,CAAC,EACT,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EACxC,IAAI,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC,CAAC;IACd,gBAAgB,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC;CAC7D;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG;IACxC,GAAG,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,aAAa,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/D,CAAC;AAKF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,oBAA6B,GAAG,aAAa,CAiBrF;AAED,OAAO,EAAE,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -1,4 +1,5 @@
1
- import { defineJourney, firstOpenJourney, journeyStep } from '../../core';
1
+ import { defineJourney, journeyStep } from '../../core';
2
+ import { moduleRuntime } from '../../core/runtime';
2
3
  let journeyExposed = false;
3
4
  let windowJourneyApi;
4
5
  /**
@@ -12,7 +13,7 @@ let windowJourneyApi;
12
13
  const api = {
13
14
  defineJourney,
14
15
  journeyStep,
15
- firstOpenJourney
16
+ firstOpenJourney: (names)=>moduleRuntime.firstOpenJourney(names)
16
17
  };
17
18
  target.App = (_target_App = target.App) !== null && _target_App !== void 0 ? _target_App : {};
18
19
  target.App.Journey = api;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/integrations/jquery/index.ts"],"sourcesContent":["import {\n defineJourney,\n firstOpenJourney,\n journeyStep,\n type JourneyDef,\n type JourneyHandle,\n type JourneyStepOptions,\n type JourneyStepTarget,\n type StepHandle,\n} from '../../core';\n\n/**\n * Knockout / desktop-legacy bridge on `window.App.Journey`.\n * Prefer `defineJourney` handles; `journeyStep` / `firstOpenJourney` cover multi-journey steps.\n */\nexport interface AppJourneyApi {\n defineJourney(def: JourneyDef): JourneyHandle;\n journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n firstOpenJourney(names: readonly string[]): string | null;\n}\n\nexport type WindowWithAppJourney = Window & {\n App?: { Journey?: AppJourneyApi } & Record<string, unknown>;\n};\n\nlet journeyExposed = false;\nlet windowJourneyApi: AppJourneyApi | undefined;\n\n/**\n * Publish the Knockout bridge on window.App.Journey. Idempotent for the real window.\n * Optional `target` is for tests.\n */\nexport function exposeAppJourney(target: WindowWithAppJourney = window): AppJourneyApi {\n if (journeyExposed && target === window && windowJourneyApi) {\n return windowJourneyApi;\n }\n\n const api: AppJourneyApi = {\n defineJourney,\n journeyStep,\n firstOpenJourney,\n };\n target.App = target.App ?? {};\n target.App.Journey = api;\n if (target === window) {\n journeyExposed = true;\n windowJourneyApi = api;\n }\n return api;\n}\n\nexport {\n instrumentJquery,\n type JqueryAjaxSettings,\n type JqueryStatic,\n type JqueryXHR,\n} from './instrument';\n"],"names":["defineJourney","firstOpenJourney","journeyStep","journeyExposed","windowJourneyApi","exposeAppJourney","target","window","api","App","Journey","instrumentJquery"],"mappings":"AAAA,SACIA,aAAa,EACbC,gBAAgB,EAChBC,WAAW,QAMR,aAAa;AAqBpB,IAAIC,iBAAiB;AACrB,IAAIC;AAEJ;;;CAGC,GACD,OAAO,SAASC,iBAAiBC,SAA+BC,MAAM;QAUrDD;IATb,IAAIH,kBAAkBG,WAAWC,UAAUH,kBAAkB;QACzD,OAAOA;IACX;IAEA,MAAMI,MAAqB;QACvBR;QACAE;QACAD;IACJ;IACAK,OAAOG,GAAG,IAAGH,cAAAA,OAAOG,GAAG,cAAVH,yBAAAA,cAAc,CAAC;IAC5BA,OAAOG,GAAG,CAACC,OAAO,GAAGF;IACrB,IAAIF,WAAWC,QAAQ;QACnBJ,iBAAiB;QACjBC,mBAAmBI;IACvB;IACA,OAAOA;AACX;AAEA,SACIG,gBAAgB,QAIb,eAAe"}
1
+ {"version":3,"sources":["../../../src/integrations/jquery/index.ts"],"sourcesContent":["import {\n defineJourney,\n journeyStep,\n type JourneyDef,\n type JourneyHandle,\n type JourneyStepOptions,\n type JourneyStepTarget,\n type StepHandle,\n} from '../../core';\nimport { moduleRuntime } from '../../core/runtime';\n\n/**\n * Knockout / desktop-legacy bridge on `window.App.Journey`.\n * Prefer `defineJourney` handles; `journeyStep` / `firstOpenJourney` cover multi-journey steps.\n */\ninterface AppJourneyApi {\n defineJourney(def: JourneyDef): JourneyHandle;\n journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n ): Promise<T>;\n firstOpenJourney(names: readonly string[]): string | null;\n}\n\nexport type WindowWithAppJourney = Window & {\n App?: { Journey?: AppJourneyApi } & Record<string, unknown>;\n};\n\nlet journeyExposed = false;\nlet windowJourneyApi: AppJourneyApi | undefined;\n\n/**\n * Publish the Knockout bridge on window.App.Journey. Idempotent for the real window.\n * Optional `target` is for tests.\n */\nexport function exposeAppJourney(target: WindowWithAppJourney = window): AppJourneyApi {\n if (journeyExposed && target === window && windowJourneyApi) {\n return windowJourneyApi;\n }\n\n const api: AppJourneyApi = {\n defineJourney,\n journeyStep,\n firstOpenJourney: names => moduleRuntime.firstOpenJourney(names),\n };\n target.App = target.App ?? {};\n target.App.Journey = api;\n if (target === window) {\n journeyExposed = true;\n windowJourneyApi = api;\n }\n return api;\n}\n\nexport { instrumentJquery, type JqueryStatic } from './instrument';\n"],"names":["defineJourney","journeyStep","moduleRuntime","journeyExposed","windowJourneyApi","exposeAppJourney","target","window","api","firstOpenJourney","names","App","Journey","instrumentJquery"],"mappings":"AAAA,SACIA,aAAa,EACbC,WAAW,QAMR,aAAa;AACpB,SAASC,aAAa,QAAQ,qBAAqB;AAqBnD,IAAIC,iBAAiB;AACrB,IAAIC;AAEJ;;;CAGC,GACD,OAAO,SAASC,iBAAiBC,SAA+BC,MAAM;QAUrDD;IATb,IAAIH,kBAAkBG,WAAWC,UAAUH,kBAAkB;QACzD,OAAOA;IACX;IAEA,MAAMI,MAAqB;QACvBR;QACAC;QACAQ,kBAAkBC,CAAAA,QAASR,cAAcO,gBAAgB,CAACC;IAC9D;IACAJ,OAAOK,GAAG,IAAGL,cAAAA,OAAOK,GAAG,cAAVL,yBAAAA,cAAc,CAAC;IAC5BA,OAAOK,GAAG,CAACC,OAAO,GAAGJ;IACrB,IAAIF,WAAWC,QAAQ;QACnBJ,iBAAiB;QACjBC,mBAAmBI;IACvB;IACA,OAAOA;AACX;AAEA,SAASK,gBAAgB,QAA2B,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/integrations/react/scope.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAgD,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EACzB,IAAI,EACJ,QAAQ,EACR,GAAG,GAAG,EACT,EAAE,UAAU,GAAG;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,QAAQ,EAAE,SAAS,CAAC;CACvB,2CAaA"}
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../../src/integrations/react/scope.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAElD,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAGjD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EACzB,IAAI,EACJ,QAAQ,EACR,GAAG,GAAG,EACT,EAAE,UAAU,GAAG;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,QAAQ,EAAE,SAAS,CAAC;CACvB,2CAaA"}
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect } from 'react';
3
- import { excludeJourney, setJourneyTags, startJourney } from '../../core';
3
+ import { excludeJourney, setJourneyTags } from '../../core';
4
+ import { moduleRuntime } from '../../core/runtime';
4
5
  import { JourneyNameContext } from './context';
5
6
  /**
6
7
  * Opens a journey while the subtree is mounted; Excludes on unmount.
@@ -9,7 +10,7 @@ import { JourneyNameContext } from './context';
9
10
  */ export function JourneyScope({ tags, children, ...def }) {
10
11
  const { name } = def;
11
12
  useEffect(()=>{
12
- startJourney(def);
13
+ moduleRuntime.startJourney(def);
13
14
  if (tags) {
14
15
  setJourneyTags(name, tags);
15
16
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/integrations/react/scope.tsx"],"sourcesContent":["import { useEffect, type ReactNode } from 'react';\n\nimport { excludeJourney, setJourneyTags, startJourney, type JourneyDef } from '../../core';\nimport type { TagValue } from '../../core/types';\nimport { JourneyNameContext } from './context';\n\n/**\n * Opens a journey while the subtree is mounted; Excludes on unmount.\n * Config (timeouts, endpoints, tags, …) is captured when the journey opens;\n * only a `name` change re-opens.\n */\nexport function JourneyScope({\n tags,\n children,\n ...def\n}: JourneyDef & {\n tags?: Record<string, TagValue>;\n children: ReactNode;\n}) {\n const { name } = def;\n\n useEffect(() => {\n startJourney(def);\n if (tags) {\n setJourneyTags(name, tags);\n }\n return () => excludeJourney(name);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- freeze-on-mount; name is the lifecycle key\n }, [name]);\n\n return <JourneyNameContext.Provider value={name}>{children}</JourneyNameContext.Provider>;\n}\n"],"names":["useEffect","excludeJourney","setJourneyTags","startJourney","JourneyNameContext","JourneyScope","tags","children","def","name","Provider","value"],"mappings":";AAAA,SAASA,SAAS,QAAwB,QAAQ;AAElD,SAASC,cAAc,EAAEC,cAAc,EAAEC,YAAY,QAAyB,aAAa;AAE3F,SAASC,kBAAkB,QAAQ,YAAY;AAE/C;;;;CAIC,GACD,OAAO,SAASC,aAAa,EACzBC,IAAI,EACJC,QAAQ,EACR,GAAGC,KAIN;IACG,MAAM,EAAEC,IAAI,EAAE,GAAGD;IAEjBR,UAAU;QACNG,aAAaK;QACb,IAAIF,MAAM;YACNJ,eAAeO,MAAMH;QACzB;QACA,OAAO,IAAML,eAAeQ;IAC5B,qGAAqG;IACzG,GAAG;QAACA;KAAK;IAET,qBAAO,KAACL,mBAAmBM,QAAQ;QAACC,OAAOF;kBAAOF;;AACtD"}
1
+ {"version":3,"sources":["../../../src/integrations/react/scope.tsx"],"sourcesContent":["import { useEffect, type ReactNode } from 'react';\n\nimport { excludeJourney, setJourneyTags, type JourneyDef } from '../../core';\nimport { moduleRuntime } from '../../core/runtime';\nimport type { TagValue } from '../../core/types';\nimport { JourneyNameContext } from './context';\n\n/**\n * Opens a journey while the subtree is mounted; Excludes on unmount.\n * Config (timeouts, endpoints, tags, …) is captured when the journey opens;\n * only a `name` change re-opens.\n */\nexport function JourneyScope({\n tags,\n children,\n ...def\n}: JourneyDef & {\n tags?: Record<string, TagValue>;\n children: ReactNode;\n}) {\n const { name } = def;\n\n useEffect(() => {\n moduleRuntime.startJourney(def);\n if (tags) {\n setJourneyTags(name, tags);\n }\n return () => excludeJourney(name);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- freeze-on-mount; name is the lifecycle key\n }, [name]);\n\n return <JourneyNameContext.Provider value={name}>{children}</JourneyNameContext.Provider>;\n}\n"],"names":["useEffect","excludeJourney","setJourneyTags","moduleRuntime","JourneyNameContext","JourneyScope","tags","children","def","name","startJourney","Provider","value"],"mappings":";AAAA,SAASA,SAAS,QAAwB,QAAQ;AAElD,SAASC,cAAc,EAAEC,cAAc,QAAyB,aAAa;AAC7E,SAASC,aAAa,QAAQ,qBAAqB;AAEnD,SAASC,kBAAkB,QAAQ,YAAY;AAE/C;;;;CAIC,GACD,OAAO,SAASC,aAAa,EACzBC,IAAI,EACJC,QAAQ,EACR,GAAGC,KAIN;IACG,MAAM,EAAEC,IAAI,EAAE,GAAGD;IAEjBR,UAAU;QACNG,cAAcO,YAAY,CAACF;QAC3B,IAAIF,MAAM;YACNJ,eAAeO,MAAMH;QACzB;QACA,OAAO,IAAML,eAAeQ;IAC5B,qGAAqG;IACzG,GAAG;QAACA;KAAK;IAET,qBAAO,KAACL,mBAAmBO,QAAQ;QAACC,OAAOH;kBAAOF;;AACtD"}
@@ -0,0 +1,11 @@
1
+ import type { JourneyEvent } from '../core/types';
2
+ /**
3
+ * Log a terminal journey to the browser console when debugging is enabled.
4
+ * No-op unless `__stJourney.enableDebugging()` / `enableJourneyDebugging()` was used
5
+ * (reload after enabling from DevTools).
6
+ *
7
+ * There is no reliable cross-browser API to detect an open DevTools console;
8
+ * use the explicit debug flag instead.
9
+ */
10
+ export declare function sendToConsole(event: JourneyEvent): void;
11
+ //# sourceMappingURL=console.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../src/sinks/console.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAQvD"}
@@ -0,0 +1,18 @@
1
+ import { isJourneyDebugEnabled } from '../global';
2
+ /**
3
+ * Log a terminal journey to the browser console when debugging is enabled.
4
+ * No-op unless `__stJourney.enableDebugging()` / `enableJourneyDebugging()` was used
5
+ * (reload after enabling from DevTools).
6
+ *
7
+ * There is no reliable cross-browser API to detect an open DevTools console;
8
+ * use the explicit debug flag instead.
9
+ */ export function sendToConsole(event) {
10
+ if (!isJourneyDebugEnabled()) {
11
+ return;
12
+ }
13
+ const j = event.journey;
14
+ // eslint-disable-next-line no-console -- intentional debug sink
15
+ console.debug(`[journey] ${j.name} → ${j.outcome}`, j);
16
+ }
17
+
18
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sinks/console.ts"],"sourcesContent":["import { isJourneyDebugEnabled } from '../global';\nimport type { JourneyEvent } from '../core/types';\n\n/**\n * Log a terminal journey to the browser console when debugging is enabled.\n * No-op unless `__stJourney.enableDebugging()` / `enableJourneyDebugging()` was used\n * (reload after enabling from DevTools).\n *\n * There is no reliable cross-browser API to detect an open DevTools console;\n * use the explicit debug flag instead.\n */\nexport function sendToConsole(event: JourneyEvent): void {\n if (!isJourneyDebugEnabled()) {\n return;\n }\n\n const j = event.journey;\n // eslint-disable-next-line no-console -- intentional debug sink\n console.debug(`[journey] ${j.name} → ${j.outcome}`, j);\n}\n"],"names":["isJourneyDebugEnabled","sendToConsole","event","j","journey","console","debug","name","outcome"],"mappings":"AAAA,SAASA,qBAAqB,QAAQ,YAAY;AAGlD;;;;;;;CAOC,GACD,OAAO,SAASC,cAAcC,KAAmB;IAC7C,IAAI,CAACF,yBAAyB;QAC1B;IACJ;IAEA,MAAMG,IAAID,MAAME,OAAO;IACvB,gEAAgE;IAChEC,QAAQC,KAAK,CAAC,CAAC,UAAU,EAAEH,EAAEI,IAAI,CAAC,GAAG,EAAEJ,EAAEK,OAAO,EAAE,EAAEL;AACxD"}
@@ -1,6 +1,17 @@
1
1
  import type { JourneyEvent } from '../core/types';
2
- /** Host-only: publish the initialized RUM instance so MFE bundles share the same session. */
2
+ /**
3
+ * Publish a RUM instance for MFE bundles to share — **only needed if
4
+ * `globalThis.DD_RUM` is not set**.
5
+ *
6
+ * Prefer exposing the initialized instance as `globalThis.DD_RUM` (ST host:
7
+ * `datadogGuard`). `sendToDatadog` resolves `DD_RUM` first, then `__stJourney.rum`
8
+ * (this fallback), then the bundle's imported `datadogRum`.
9
+ *
10
+ * Calling `setJourneyRum` while `globalThis.DD_RUM` is already set logs a warning —
11
+ * the call is redundant because `sendToDatadog` prefers `DD_RUM`.
12
+ */
3
13
  export declare function setJourneyRum(rum: unknown): void;
14
+ export declare function normalizeTagValue(value: string): string;
4
15
  /** Ship one terminal journey as a RUM custom action (`user_journey`). */
5
16
  export declare function sendToDatadog(payload: JourneyEvent): void;
6
17
  //# sourceMappingURL=datadog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"datadog.d.ts","sourceRoot":"","sources":["../../src/sinks/datadog.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,eAAe,CAAC;AAM9E,6FAA6F;AAC7F,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAEhD;AAwCD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAkBzD"}
1
+ {"version":3,"file":"datadog.d.ts","sourceRoot":"","sources":["../../src/sinks/datadog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAA8B,MAAM,eAAe,CAAC;AAU9E;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAQhD;AAaD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOvD;AAwBD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAkBzD"}
@@ -1,16 +1,37 @@
1
1
  import { datadogRum } from '@datadog/browser-rum';
2
+ import { getJourneyRumFallback, setJourneyRumFallback } from '../global';
2
3
  const JOURNEY_ACTION = 'user_journey';
3
- const RUM_GLOBAL_KEY = '__stJourneyRum';
4
- /** Host-only: publish the initialized RUM instance so MFE bundles share the same session. */ export function setJourneyRum(rum) {
5
- globalThis[RUM_GLOBAL_KEY] = rum;
4
+ const DD_RUM_KEY = 'DD_RUM';
5
+ function getDdRum() {
6
+ return globalThis[DD_RUM_KEY];
7
+ }
8
+ /**
9
+ * Publish a RUM instance for MFE bundles to share — **only needed if
10
+ * `globalThis.DD_RUM` is not set**.
11
+ *
12
+ * Prefer exposing the initialized instance as `globalThis.DD_RUM` (ST host:
13
+ * `datadogGuard`). `sendToDatadog` resolves `DD_RUM` first, then `__stJourney.rum`
14
+ * (this fallback), then the bundle's imported `datadogRum`.
15
+ *
16
+ * Calling `setJourneyRum` while `globalThis.DD_RUM` is already set logs a warning —
17
+ * the call is redundant because `sendToDatadog` prefers `DD_RUM`.
18
+ */ export function setJourneyRum(rum) {
19
+ if (getDdRum()) {
20
+ // eslint-disable-next-line no-console -- soft-deprecate redundant bridge use
21
+ console.warn('[journey] setJourneyRum() is unnecessary when globalThis.DD_RUM is set — sendToDatadog already prefers DD_RUM');
22
+ }
23
+ setJourneyRumFallback(rum);
6
24
  }
7
25
  function resolveRum() {
8
- const shared = globalThis[RUM_GLOBAL_KEY];
26
+ const ddRum = getDdRum();
27
+ if (ddRum) {
28
+ return ddRum;
29
+ }
30
+ const shared = getJourneyRumFallback();
9
31
  return shared !== null && shared !== void 0 ? shared : datadogRum;
10
32
  }
11
- // Match Datadog metric-tag value rules so RUM attributes join derived SLO tags.
12
- const MAX_TAG_VALUE_LEN = 200;
13
- function normalizeTagValue(value) {
33
+ /** Match Datadog metric-tag value rules so RUM attributes / globals join derived SLO tags. */ const MAX_TAG_VALUE_LEN = 200;
34
+ export function normalizeTagValue(value) {
14
35
  return value.toLowerCase().replace(/[^a-z0-9_\-:./]/g, '_').replace(/_+/g, '_').slice(0, MAX_TAG_VALUE_LEN).replace(/_+$/, '');
15
36
  }
16
37
  function normalizeTags(tags) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sinks/datadog.ts"],"sourcesContent":["import { datadogRum } from '@datadog/browser-rum';\n\nimport type { JourneyEvent, JourneyStepEvent, TagValue } from '../core/types';\n\nconst JOURNEY_ACTION = 'user_journey';\n\nconst RUM_GLOBAL_KEY = '__stJourneyRum';\n\n/** Host-only: publish the initialized RUM instance so MFE bundles share the same session. */\nexport function setJourneyRum(rum: unknown): void {\n (globalThis as Record<string, unknown>)[RUM_GLOBAL_KEY] = rum;\n}\n\nfunction resolveRum(): typeof datadogRum {\n const shared = (globalThis as Record<string, unknown>)[RUM_GLOBAL_KEY];\n return (shared as typeof datadogRum | undefined) ?? datadogRum;\n}\n\n// Match Datadog metric-tag value rules so RUM attributes join derived SLO tags.\nconst MAX_TAG_VALUE_LEN = 200;\nfunction 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\nfunction normalizeTags(tags: Record<string, TagValue>): Record<string, TagValue> {\n const out: Record<string, TagValue> = {};\n for (const [key, value] of Object.entries(tags)) {\n out[key] = typeof value === 'string' ? normalizeTagValue(value) : value;\n }\n return out;\n}\n\nfunction toDatadogStep(step: JourneyStepEvent) {\n /* eslint-disable @typescript-eslint/naming-convention -- Datadog RUM wire format (snake_case) */\n return {\n name: step.name,\n start_ms: step.startMs,\n duration_ms: step.durationMs,\n outcome: step.outcome,\n ...(step.reason ? { reason: step.reason } : {}),\n ...(step.httpStatus !== undefined ? { http_status: step.httpStatus } : {}),\n ...(step.attributes ? { attributes: step.attributes } : {}),\n };\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n\n/** Ship one terminal journey as a RUM custom action (`user_journey`). */\nexport function sendToDatadog(payload: JourneyEvent): void {\n const j = payload.journey;\n /* eslint-disable @typescript-eslint/naming-convention -- Datadog RUM wire format (snake_case) */\n resolveRum().addAction(JOURNEY_ACTION, {\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 duration_ms: j.durationMs,\n steps: j.steps.map(toDatadogStep),\n ...(j.expected ? { expected: j.expected } : {}),\n ...(j.tags ? { tags: normalizeTags(j.tags) } : {}),\n },\n });\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n"],"names":["datadogRum","JOURNEY_ACTION","RUM_GLOBAL_KEY","setJourneyRum","rum","globalThis","resolveRum","shared","MAX_TAG_VALUE_LEN","normalizeTagValue","value","toLowerCase","replace","slice","normalizeTags","tags","out","key","Object","entries","toDatadogStep","step","name","start_ms","startMs","duration_ms","durationMs","outcome","reason","httpStatus","undefined","http_status","attributes","sendToDatadog","payload","j","journey","addAction","team","group","service","steps","map","expected"],"mappings":"AAAA,SAASA,UAAU,QAAQ,uBAAuB;AAIlD,MAAMC,iBAAiB;AAEvB,MAAMC,iBAAiB;AAEvB,2FAA2F,GAC3F,OAAO,SAASC,cAAcC,GAAY;IACrCC,UAAsC,CAACH,eAAe,GAAGE;AAC9D;AAEA,SAASE;IACL,MAAMC,SAAS,AAACF,UAAsC,CAACH,eAAe;IACtE,OAAQK,mBAAAA,oBAAAA,SAA4CP;AACxD;AAEA,gFAAgF;AAChF,MAAMQ,oBAAoB;AAC1B,SAASC,kBAAkBC,KAAa;IACpC,OAAOA,MACFC,WAAW,GACXC,OAAO,CAAC,oBAAoB,KAC5BA,OAAO,CAAC,OAAO,KACfC,KAAK,CAAC,GAAGL,mBACTI,OAAO,CAAC,OAAO;AACxB;AAEA,SAASE,cAAcC,IAA8B;IACjD,MAAMC,MAAgC,CAAC;IACvC,KAAK,MAAM,CAACC,KAAKP,MAAM,IAAIQ,OAAOC,OAAO,CAACJ,MAAO;QAC7CC,GAAG,CAACC,IAAI,GAAG,OAAOP,UAAU,WAAWD,kBAAkBC,SAASA;IACtE;IACA,OAAOM;AACX;AAEA,SAASI,cAAcC,IAAsB;IACzC,+FAA+F,GAC/F,OAAO;QACHC,MAAMD,KAAKC,IAAI;QACfC,UAAUF,KAAKG,OAAO;QACtBC,aAAaJ,KAAKK,UAAU;QAC5BC,SAASN,KAAKM,OAAO;QACrB,GAAIN,KAAKO,MAAM,GAAG;YAAEA,QAAQP,KAAKO,MAAM;QAAC,IAAI,CAAC,CAAC;QAC9C,GAAIP,KAAKQ,UAAU,KAAKC,YAAY;YAAEC,aAAaV,KAAKQ,UAAU;QAAC,IAAI,CAAC,CAAC;QACzE,GAAIR,KAAKW,UAAU,GAAG;YAAEA,YAAYX,KAAKW,UAAU;QAAC,IAAI,CAAC,CAAC;IAC9D;AACA,sDAAsD,GAC1D;AAEA,uEAAuE,GACvE,OAAO,SAASC,cAAcC,OAAqB;IAC/C,MAAMC,IAAID,QAAQE,OAAO;IACzB,+FAA+F,GAC/F9B,aAAa+B,SAAS,CAACpC,gBAAgB;QACnCmC,SAAS;YACLd,MAAMb,kBAAkB0B,EAAEb,IAAI;YAC9BgB,MAAM7B,kBAAkB0B,EAAEG,IAAI;YAC9BC,OAAO9B,kBAAkB0B,EAAEI,KAAK;YAChCC,SAAS/B,kBAAkB0B,EAAEK,OAAO;YACpCb,SAASQ,EAAER,OAAO;YAClB,GAAIQ,EAAEP,MAAM,GAAG;gBAAEA,QAAQnB,kBAAkB0B,EAAEP,MAAM;YAAE,IAAI,CAAC,CAAC;YAC3DH,aAAaU,EAAET,UAAU;YACzBe,OAAON,EAAEM,KAAK,CAACC,GAAG,CAACtB;YACnB,GAAIe,EAAEQ,QAAQ,GAAG;gBAAEA,UAAUR,EAAEQ,QAAQ;YAAC,IAAI,CAAC,CAAC;YAC9C,GAAIR,EAAEpB,IAAI,GAAG;gBAAEA,MAAMD,cAAcqB,EAAEpB,IAAI;YAAE,IAAI,CAAC,CAAC;QACrD;IACJ;AACA,sDAAsD,GAC1D"}
1
+ {"version":3,"sources":["../../src/sinks/datadog.ts"],"sourcesContent":["import { datadogRum } from '@datadog/browser-rum';\n\nimport { getJourneyRumFallback, setJourneyRumFallback } from '../global';\nimport type { JourneyEvent, JourneyStepEvent, TagValue } from '../core/types';\n\nconst JOURNEY_ACTION = 'user_journey';\n\nconst DD_RUM_KEY = 'DD_RUM';\n\nfunction getDdRum(): typeof datadogRum | undefined {\n return (globalThis as Record<string, unknown>)[DD_RUM_KEY] as typeof datadogRum | undefined;\n}\n\n/**\n * Publish a RUM instance for MFE bundles to share — **only needed if\n * `globalThis.DD_RUM` is not set**.\n *\n * Prefer exposing the initialized instance as `globalThis.DD_RUM` (ST host:\n * `datadogGuard`). `sendToDatadog` resolves `DD_RUM` first, then `__stJourney.rum`\n * (this fallback), then the bundle's imported `datadogRum`.\n *\n * Calling `setJourneyRum` while `globalThis.DD_RUM` is already set logs a warning —\n * the call is redundant because `sendToDatadog` prefers `DD_RUM`.\n */\nexport function setJourneyRum(rum: unknown): void {\n if (getDdRum()) {\n // eslint-disable-next-line no-console -- soft-deprecate redundant bridge use\n console.warn(\n '[journey] setJourneyRum() is unnecessary when globalThis.DD_RUM is set — sendToDatadog already prefers DD_RUM'\n );\n }\n setJourneyRumFallback(rum);\n}\n\nfunction resolveRum(): typeof datadogRum {\n const ddRum = getDdRum();\n if (ddRum) {\n return ddRum;\n }\n const shared = getJourneyRumFallback();\n return (shared as typeof datadogRum | undefined) ?? datadogRum;\n}\n\n/** Match Datadog metric-tag value rules so RUM attributes / globals join derived SLO tags. */\nconst MAX_TAG_VALUE_LEN = 200;\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\nfunction normalizeTags(tags: Record<string, TagValue>): Record<string, TagValue> {\n const out: Record<string, TagValue> = {};\n for (const [key, value] of Object.entries(tags)) {\n out[key] = typeof value === 'string' ? normalizeTagValue(value) : value;\n }\n return out;\n}\n\nfunction toDatadogStep(step: JourneyStepEvent) {\n /* eslint-disable @typescript-eslint/naming-convention -- Datadog RUM wire format (snake_case) */\n return {\n name: step.name,\n start_ms: step.startMs,\n duration_ms: step.durationMs,\n outcome: step.outcome,\n ...(step.reason ? { reason: step.reason } : {}),\n ...(step.httpStatus !== undefined ? { http_status: step.httpStatus } : {}),\n ...(step.attributes ? { attributes: step.attributes } : {}),\n };\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n\n/** Ship one terminal journey as a RUM custom action (`user_journey`). */\nexport function sendToDatadog(payload: JourneyEvent): void {\n const j = payload.journey;\n /* eslint-disable @typescript-eslint/naming-convention -- Datadog RUM wire format (snake_case) */\n resolveRum().addAction(JOURNEY_ACTION, {\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 duration_ms: j.durationMs,\n steps: j.steps.map(toDatadogStep),\n ...(j.expected ? { expected: j.expected } : {}),\n ...(j.tags ? { tags: normalizeTags(j.tags) } : {}),\n },\n });\n /* eslint-enable @typescript-eslint/naming-convention */\n}\n"],"names":["datadogRum","getJourneyRumFallback","setJourneyRumFallback","JOURNEY_ACTION","DD_RUM_KEY","getDdRum","globalThis","setJourneyRum","rum","console","warn","resolveRum","ddRum","shared","MAX_TAG_VALUE_LEN","normalizeTagValue","value","toLowerCase","replace","slice","normalizeTags","tags","out","key","Object","entries","toDatadogStep","step","name","start_ms","startMs","duration_ms","durationMs","outcome","reason","httpStatus","undefined","http_status","attributes","sendToDatadog","payload","j","journey","addAction","team","group","service","steps","map","expected"],"mappings":"AAAA,SAASA,UAAU,QAAQ,uBAAuB;AAElD,SAASC,qBAAqB,EAAEC,qBAAqB,QAAQ,YAAY;AAGzE,MAAMC,iBAAiB;AAEvB,MAAMC,aAAa;AAEnB,SAASC;IACL,OAAO,AAACC,UAAsC,CAACF,WAAW;AAC9D;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASG,cAAcC,GAAY;IACtC,IAAIH,YAAY;QACZ,6EAA6E;QAC7EI,QAAQC,IAAI,CACR;IAER;IACAR,sBAAsBM;AAC1B;AAEA,SAASG;IACL,MAAMC,QAAQP;IACd,IAAIO,OAAO;QACP,OAAOA;IACX;IACA,MAAMC,SAASZ;IACf,OAAQY,mBAAAA,oBAAAA,SAA4Cb;AACxD;AAEA,4FAA4F,GAC5F,MAAMc,oBAAoB;AAC1B,OAAO,SAASC,kBAAkBC,KAAa;IAC3C,OAAOA,MACFC,WAAW,GACXC,OAAO,CAAC,oBAAoB,KAC5BA,OAAO,CAAC,OAAO,KACfC,KAAK,CAAC,GAAGL,mBACTI,OAAO,CAAC,OAAO;AACxB;AAEA,SAASE,cAAcC,IAA8B;IACjD,MAAMC,MAAgC,CAAC;IACvC,KAAK,MAAM,CAACC,KAAKP,MAAM,IAAIQ,OAAOC,OAAO,CAACJ,MAAO;QAC7CC,GAAG,CAACC,IAAI,GAAG,OAAOP,UAAU,WAAWD,kBAAkBC,SAASA;IACtE;IACA,OAAOM;AACX;AAEA,SAASI,cAAcC,IAAsB;IACzC,+FAA+F,GAC/F,OAAO;QACHC,MAAMD,KAAKC,IAAI;QACfC,UAAUF,KAAKG,OAAO;QACtBC,aAAaJ,KAAKK,UAAU;QAC5BC,SAASN,KAAKM,OAAO;QACrB,GAAIN,KAAKO,MAAM,GAAG;YAAEA,QAAQP,KAAKO,MAAM;QAAC,IAAI,CAAC,CAAC;QAC9C,GAAIP,KAAKQ,UAAU,KAAKC,YAAY;YAAEC,aAAaV,KAAKQ,UAAU;QAAC,IAAI,CAAC,CAAC;QACzE,GAAIR,KAAKW,UAAU,GAAG;YAAEA,YAAYX,KAAKW,UAAU;QAAC,IAAI,CAAC,CAAC;IAC9D;AACA,sDAAsD,GAC1D;AAEA,uEAAuE,GACvE,OAAO,SAASC,cAAcC,OAAqB;IAC/C,MAAMC,IAAID,QAAQE,OAAO;IACzB,+FAA+F,GAC/F/B,aAAagC,SAAS,CAACxC,gBAAgB;QACnCuC,SAAS;YACLd,MAAMb,kBAAkB0B,EAAEb,IAAI;YAC9BgB,MAAM7B,kBAAkB0B,EAAEG,IAAI;YAC9BC,OAAO9B,kBAAkB0B,EAAEI,KAAK;YAChCC,SAAS/B,kBAAkB0B,EAAEK,OAAO;YACpCb,SAASQ,EAAER,OAAO;YAClB,GAAIQ,EAAEP,MAAM,GAAG;gBAAEA,QAAQnB,kBAAkB0B,EAAEP,MAAM;YAAE,IAAI,CAAC,CAAC;YAC3DH,aAAaU,EAAET,UAAU;YACzBe,OAAON,EAAEM,KAAK,CAACC,GAAG,CAACtB;YACnB,GAAIe,EAAEQ,QAAQ,GAAG;gBAAEA,UAAUR,EAAEQ,QAAQ;YAAC,IAAI,CAAC,CAAC;YAC9C,GAAIR,EAAEpB,IAAI,GAAG;gBAAEA,MAAMD,cAAcqB,EAAEpB,IAAI;YAAE,IAAI,CAAC,CAAC;QACrD;IACJ;AACA,sDAAsD,GAC1D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/journey",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Critical user journey monitoring — reports good/bad/excluded verdicts to Datadog RUM as a custom action",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/journey",
6
6
  "repository": {
@@ -41,5 +41,5 @@
41
41
  "cli": {
42
42
  "webpack": false
43
43
  },
44
- "gitHead": "af4dee1e6d65f7b611a03a15771adf5a6fa6f45d"
44
+ "gitHead": "f4f3b8308ccf1237e7671e3669e71af47d6b48af"
45
45
  }
@@ -1,6 +1,10 @@
1
- import { resetJourney } from '../core';
1
+ import { resetJourney } from '../core/runtime';
2
+ import { sendToConsole } from '../sinks/console';
2
3
  import { sendToDatadog } from '../sinks/datadog';
3
4
 
5
+ /** Package default sinks installed by `config.ts` bootstrap. */
6
+ const DEFAULT_SINKS = [sendToDatadog, sendToConsole] as const;
7
+
4
8
  /** Standard journey def used across engine suites. */
5
9
  export const baseJourneyDef = {
6
10
  name: 'journey-under-test',
@@ -30,7 +34,7 @@ export function useJourneyTestRuntime(emitMock: jest.Mock) {
30
34
 
31
35
  afterEach(() => {
32
36
  resetJourney({
33
- sinks: [sendToDatadog],
37
+ sinks: [...DEFAULT_SINKS],
34
38
  requestTimeouts: { defaultMs: 4_000, endpoints: [] },
35
39
  });
36
40
  });
@@ -16,15 +16,11 @@ jest.mock('../integrations/jquery', () => ({
16
16
  exposeAppJourney: jest.fn(),
17
17
  }));
18
18
 
19
- import {
20
- configureJourney,
21
- getRequestTimeouts,
22
- longestEndpointMatch,
23
- sortEndpointsByLongestMatch,
24
- } from '../config';
19
+ import { configureJourney, getRequestTimeouts } from '../config';
25
20
  import { resetJourney } from '../core';
26
- import { emitJourneyEvent } from '../core/registry';
21
+ import { moduleRuntime } from '../core/runtime';
27
22
  import type { JourneyEvent } from '../core/types';
23
+ import { longestEndpointMatch, sortEndpointsByLongestMatch } from '../core/endpoint-policy';
28
24
  import { instrumentAxios } from '../integrations/axios';
29
25
  import { instrumentFetch } from '../integrations/fetch';
30
26
  import {
@@ -32,6 +28,7 @@ import {
32
28
  instrumentJquery,
33
29
  type WindowWithAppJourney,
34
30
  } from '../integrations/jquery';
31
+ import { sendToConsole } from '../sinks/console';
35
32
  import { sendToDatadog } from '../sinks/datadog';
36
33
 
37
34
  const instrumentAxiosMock = jest.mocked(instrumentAxios);
@@ -42,7 +39,7 @@ const exposeAppJourneyMock = jest.mocked(exposeAppJourney);
42
39
  describe('[journey] configureJourney / getRequestTimeouts', () => {
43
40
  afterEach(() => {
44
41
  resetJourney({
45
- sinks: [sendToDatadog],
42
+ sinks: [sendToDatadog, sendToConsole],
46
43
  requestTimeouts: { defaultMs: 4_000, endpoints: [] },
47
44
  });
48
45
  instrumentAxiosMock.mockClear();
@@ -97,7 +94,7 @@ describe('[journey] configureJourney / getRequestTimeouts', () => {
97
94
 
98
95
  test('replaces the sink list', () => {
99
96
  configureJourney({ sinks: [custom] });
100
- emitJourneyEvent(payload);
97
+ moduleRuntime.emit(payload);
101
98
 
102
99
  expect(custom).toHaveBeenCalledWith(payload);
103
100
  expect(sendToDatadog).not.toHaveBeenCalled();
@@ -106,7 +103,7 @@ describe('[journey] configureJourney / getRequestTimeouts', () => {
106
103
  test('leaves sinks unchanged when sinks is omitted', () => {
107
104
  configureJourney({ sinks: [custom] });
108
105
  configureJourney({ requestTimeouts: { defaultMs: 2_000, endpoints: [] } });
109
- emitJourneyEvent(payload);
106
+ moduleRuntime.emit(payload);
110
107
 
111
108
  expect(custom).toHaveBeenCalledWith(payload);
112
109
  expect(sendToDatadog).not.toHaveBeenCalled();
@@ -114,7 +111,7 @@ describe('[journey] configureJourney / getRequestTimeouts', () => {
114
111
 
115
112
  test('disables emission when sinks is empty', () => {
116
113
  configureJourney({ sinks: [] });
117
- emitJourneyEvent(payload);
114
+ moduleRuntime.emit(payload);
118
115
 
119
116
  expect(sendToDatadog).not.toHaveBeenCalled();
120
117
  expect(custom).not.toHaveBeenCalled();
@@ -219,7 +216,7 @@ describe('longestEndpointMatch', () => {
219
216
  describe('configureJourney endpoint ordering', () => {
220
217
  afterEach(() => {
221
218
  resetJourney({
222
- sinks: [sendToDatadog],
219
+ sinks: [sendToDatadog, sendToConsole],
223
220
  requestTimeouts: { defaultMs: 4_000, endpoints: [] },
224
221
  });
225
222
  });
@@ -1,6 +1,7 @@
1
1
  /** @jest-environment jsdom */
2
- import { baseJourneyDef, useJourneyTestRuntime } from '../__mocks__/test-runtime';
3
- import { activeJourneyStep, completeJourney, journeyStep, startJourney } from '../core';
2
+ import { baseJourneyDef, useJourneyTestRuntime } from '../../__test-utils__/test-runtime';
3
+ import { activeJourneyStep, completeJourney, journeyStep } from '../../core';
4
+ import { moduleRuntime } from '../../core/runtime';
4
5
 
5
6
  const emitMock = jest.fn();
6
7
  const baseDef = { ...baseJourneyDef, name: 'ambient-a' };
@@ -11,7 +12,7 @@ describe('[journey] activeJourneyStep', () => {
11
12
 
12
13
  describe('around a single step', () => {
13
14
  beforeEach(() => {
14
- startJourney(baseDef);
15
+ moduleRuntime.startJourney(baseDef);
15
16
  });
16
17
 
17
18
  test('is set only while the step is running', async () => {
@@ -31,8 +32,8 @@ describe('[journey] activeJourneyStep', () => {
31
32
  let stepA: Promise<unknown>;
32
33
 
33
34
  beforeEach(() => {
34
- startJourney(baseDef);
35
- startJourney(otherDef);
35
+ moduleRuntime.startJourney(baseDef);
36
+ moduleRuntime.startJourney(otherDef);
36
37
 
37
38
  const gateA = new Promise<void>(r => {
38
39
  releaseA = r;
@@ -62,8 +63,8 @@ describe('[journey] activeJourneyStep', () => {
62
63
  let ambientWhileBAlone: ReturnType<typeof activeJourneyStep> | 'unset';
63
64
 
64
65
  beforeEach(() => {
65
- startJourney(baseDef);
66
- startJourney(otherDef);
66
+ moduleRuntime.startJourney(baseDef);
67
+ moduleRuntime.startJourney(otherDef);
67
68
  ambientWhileBAlone = 'unset';
68
69
 
69
70
  const gateB = new Promise<void>(r => {