@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,35 +1,89 @@
1
- import { longestEndpointMatch, sortEndpointsByLongestMatch } from '../endpoint-policy';
2
- import { JourneyStepTag } from './step-tag';
3
- const DEFAULT_REQUEST_TIMEOUTS = {
1
+ import { getAutoAttributeRequests as getSharedAutoAttributeRequests, getHttpAbortedRequestsPolicy as getSharedHttpAbortedRequestsPolicy, getHttpClientErrorRequestsPolicy as getSharedHttpClientErrorRequestsPolicy, getSharedSlowRequests, isJourneyDebugEnabled } from '../global';
2
+ import { isCanceledError } from './abort-error';
3
+ import { resolveEndpointPolicy, sortEndpointsByLongestMatch } from './endpoint-policy';
4
+ import { clampMaxSteps, DEFAULT_MAX_STEPS, DEFAULT_JOURNEY_IDLE_MS, finiteSlowRequestMs, finiteTimeoutMs, MAX_ATTRIBUTED_REQUEST_KEYS, MAX_TAG_KEYS, resolveJourneyTimeoutMs } from './limits';
5
+ import { assignRecord, emptyRecord, sanitizeJourneyEvent, setSafeAttribute } from './sanitize';
6
+ import { JourneyStepStamp, resolveStampOpts } from './step-tag';
7
+ import { JOURNEY_ENGINE } from './types';
8
+ const DEFAULT_SLOW_REQUESTS = {
4
9
  defaultMs: 4000,
5
10
  endpoints: []
6
11
  };
7
12
  const noopStep = {
8
- name: null,
13
+ journeyName: null,
9
14
  setAttribute () {},
10
15
  setTags () {},
11
- complete () {},
12
- fail () {},
13
- tag: ()=>({})
16
+ completeJourney () {},
17
+ failJourney () {},
18
+ stamp: ()=>undefined
14
19
  };
15
20
  function toName(target) {
16
- return typeof target === 'string' ? target : target.name;
21
+ if (typeof target === 'string') {
22
+ return target;
23
+ }
24
+ return 'config' in target ? target.config.name : target.name;
25
+ }
26
+ function freezeJourneyDef(config, tags) {
27
+ const endpoints = sortEndpointsByLongestMatch(config.endpoints);
28
+ return Object.freeze({
29
+ ...config,
30
+ timeoutMs: config.timeoutMs !== undefined ? finiteTimeoutMs(config.timeoutMs) : undefined,
31
+ stepTimeoutMs: config.stepTimeoutMs !== undefined ? finiteTimeoutMs(config.stepTimeoutMs) : undefined,
32
+ slowRequestMs: finiteSlowRequestMs(config.slowRequestMs),
33
+ maxSteps: config.maxSteps !== undefined ? clampMaxSteps(config.maxSteps) : undefined,
34
+ endpoints: endpoints ? Object.freeze([
35
+ ...endpoints
36
+ ]) : undefined,
37
+ expected: config.expected ? Object.freeze([
38
+ ...config.expected
39
+ ]) : undefined,
40
+ tags: Object.freeze({
41
+ ...tags
42
+ })
43
+ });
44
+ }
45
+ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
46
+ return {
47
+ failJourney (reason) {
48
+ api.failJourney(journey, reason);
49
+ },
50
+ exclude () {
51
+ api.excludeJourney(journey);
52
+ },
53
+ shouldIgnoreRequest (key) {
54
+ return shouldIgnoreRequest(journey, key);
55
+ },
56
+ reportBackendRequest (step, status, durationMs, requestKey) {
57
+ api.reportBackendRequest(step, status, durationMs, requestKey);
58
+ },
59
+ getHttpAbortedRequestsPolicy () {
60
+ return api.getHttpAbortedRequestsPolicy();
61
+ },
62
+ getHttpClientErrorRequestsPolicy () {
63
+ return api.getHttpClientErrorRequestsPolicy();
64
+ }
65
+ };
17
66
  }
18
67
  /**
19
68
  * @internal Private — not part of the public package API.
20
69
  * Build an isolated engine. Rarely needed — apps use the default via free helpers.
21
70
  */ export function createJourneyRuntime(options = {}) {
22
- var _options_sinks, _ref, _ref1;
23
- var _options_requestTimeouts, _options_requestTimeouts1;
71
+ var _options_sinks, _ref, _ref1, _options_maxSteps, _options_defaultJourneyIdleMs;
72
+ var _options_slowRequests, _options_slowRequests1;
73
+ let id = typeof options.id === 'string' && options.id !== '' ? options.id : '';
24
74
  const journeys = new Map();
25
75
  const inFlight = new Set();
26
76
  let sinks = [
27
77
  ...(_options_sinks = options.sinks) !== null && _options_sinks !== void 0 ? _options_sinks : []
28
78
  ];
29
- let requestTimeouts = {
30
- defaultMs: (_ref = (_options_requestTimeouts = options.requestTimeouts) === null || _options_requestTimeouts === void 0 ? void 0 : _options_requestTimeouts.defaultMs) !== null && _ref !== void 0 ? _ref : DEFAULT_REQUEST_TIMEOUTS.defaultMs,
31
- endpoints: sortEndpointsByLongestMatch((_ref1 = (_options_requestTimeouts1 = options.requestTimeouts) === null || _options_requestTimeouts1 === void 0 ? void 0 : _options_requestTimeouts1.endpoints) !== null && _ref1 !== void 0 ? _ref1 : DEFAULT_REQUEST_TIMEOUTS.endpoints)
79
+ let sinksConfigured = false;
80
+ let overlay = {};
81
+ let slowRequests = {
82
+ defaultMs: (_ref = (_options_slowRequests = options.slowRequests) === null || _options_slowRequests === void 0 ? void 0 : _options_slowRequests.defaultMs) !== null && _ref !== void 0 ? _ref : DEFAULT_SLOW_REQUESTS.defaultMs,
83
+ endpoints: sortEndpointsByLongestMatch((_ref1 = (_options_slowRequests1 = options.slowRequests) === null || _options_slowRequests1 === void 0 ? void 0 : _options_slowRequests1.endpoints) !== null && _ref1 !== void 0 ? _ref1 : DEFAULT_SLOW_REQUESTS.endpoints)
32
84
  };
85
+ let maxSteps = clampMaxSteps((_options_maxSteps = options.maxSteps) !== null && _options_maxSteps !== void 0 ? _options_maxSteps : DEFAULT_MAX_STEPS);
86
+ let defaultJourneyIdleMs = finiteTimeoutMs((_options_defaultJourneyIdleMs = options.defaultJourneyIdleMs) !== null && _options_defaultJourneyIdleMs !== void 0 ? _options_defaultJourneyIdleMs : DEFAULT_JOURNEY_IDLE_MS);
33
87
  function getInFlightSteps(journey) {
34
88
  const out = [];
35
89
  for (const step of inFlight){
@@ -45,6 +99,19 @@ function toName(target) {
45
99
  function leaveStep(step) {
46
100
  inFlight.delete(step);
47
101
  }
102
+ function releaseInFlightSteps(journey) {
103
+ for (const step of [
104
+ ...inFlight
105
+ ]){
106
+ if (step.journey !== journey) {
107
+ continue;
108
+ }
109
+ if (step.durationMs === 0) {
110
+ step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);
111
+ }
112
+ inFlight.delete(step);
113
+ }
114
+ }
48
115
  function clearCountdown(journey) {
49
116
  if (journey.timer != null) {
50
117
  clearTimeout(journey.timer);
@@ -52,9 +119,10 @@ function toName(target) {
52
119
  }
53
120
  }
54
121
  function emit(payload) {
122
+ const safePayload = sanitizeJourneyEvent(payload);
55
123
  for (const sink of sinks){
56
124
  try {
57
- sink(payload);
125
+ sink(safePayload);
58
126
  } catch (unused) {
59
127
  // One sinking throw must not block the remaining sinks.
60
128
  }
@@ -66,17 +134,15 @@ function toName(target) {
66
134
  return;
67
135
  }
68
136
  journey.closed = true;
69
- journeys.delete(journey.name);
70
- clearCountdown(journey);
71
- for (const step of getInFlightSteps(journey)){
72
- if (step.durationMs === 0) {
73
- step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);
74
- }
137
+ if (journeys.get(journey.name) === journey) {
138
+ journeys.delete(journey.name);
75
139
  }
140
+ clearCountdown(journey);
141
+ releaseInFlightSteps(journey);
76
142
  let finalReason = (_journey_reason = journey.reason) !== null && _journey_reason !== void 0 ? _journey_reason : reason;
77
143
  let finalOutcome = outcome;
78
144
  const durationMs = Math.round(globalThis.performance.now() - journey.startedAt);
79
- if (journey.timeoutMs > 0 && durationMs > journey.timeoutMs) {
145
+ if (journey.timeoutExplicit && journey.timeoutMs > 0 && durationMs > journey.timeoutMs) {
80
146
  finalOutcome = 'bad';
81
147
  finalReason = finalReason !== null && finalReason !== void 0 ? finalReason : 'journey-timeout';
82
148
  }
@@ -92,7 +158,9 @@ function toName(target) {
92
158
  httpStatus: s.httpStatus
93
159
  } : {},
94
160
  ...Object.keys(s.attributes).length ? {
95
- attributes: s.attributes
161
+ attributes: {
162
+ ...s.attributes
163
+ }
96
164
  } : {}
97
165
  }));
98
166
  emit({
@@ -102,7 +170,7 @@ function toName(target) {
102
170
  group: journey.group,
103
171
  service: journey.service,
104
172
  outcome: finalOutcome,
105
- ...finalOutcome === 'bad' && finalReason ? {
173
+ ...finalReason ? {
106
174
  reason: finalReason
107
175
  } : {},
108
176
  durationMs,
@@ -111,40 +179,44 @@ function toName(target) {
111
179
  expected: journey.expected
112
180
  } : {},
113
181
  ...Object.keys(journey.tags).length ? {
114
- tags: journey.tags
182
+ tags: {
183
+ ...journey.tags
184
+ }
115
185
  } : {}
116
186
  }
117
187
  });
118
188
  }
119
- function armCountdown(journey) {
120
- if (journey.timeoutMs <= 0) {
189
+ function armCountdown(journey, delayMs = journey.timeoutMs) {
190
+ if (delayMs <= 0) {
121
191
  return;
122
192
  }
123
193
  journey.timer = setTimeout(()=>{
124
- finish(journey, 'bad', 'journey-timeout');
125
- }, journey.timeoutMs);
194
+ if (journey.timeoutExplicit) {
195
+ finish(journey, 'bad', 'journey-timeout');
196
+ return;
197
+ }
198
+ finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded', 'journey-idle-timeout');
199
+ }, delayMs);
126
200
  }
127
- function resolveRequestTimeoutMs(journey, key) {
128
- const own = longestEndpointMatch(journey.endpoints, key);
129
- if (own === null || own === void 0 ? void 0 : own.timeoutMs) {
130
- return own.timeoutMs;
131
- }
132
- const app = longestEndpointMatch(requestTimeouts.endpoints, key);
133
- if (app === null || app === void 0 ? void 0 : app.timeoutMs) {
134
- return app.timeoutMs;
135
- }
136
- if (journey.requestTimeoutMs != null) {
137
- return journey.requestTimeoutMs;
138
- }
139
- return requestTimeouts.defaultMs;
201
+ function effectiveSlowRequests() {
202
+ var _ref, _overlay_slowRequests;
203
+ return (_ref = (_overlay_slowRequests = overlay.slowRequests) !== null && _overlay_slowRequests !== void 0 ? _overlay_slowRequests : getSharedSlowRequests()) !== null && _ref !== void 0 ? _ref : slowRequests;
140
204
  }
141
205
  function shouldIgnoreRequest(journey, key) {
142
- var _longestEndpointMatch;
143
- const own = longestEndpointMatch(journey.endpoints, key);
144
- if (own) {
145
- return own.ignore === true;
206
+ return resolveEndpointPolicy(journey, effectiveSlowRequests(), key).ignore;
207
+ }
208
+ function trackAttributedKey(step, requestKey) {
209
+ var _step, _attributedRequestKeys;
210
+ if (!requestKey) {
211
+ return;
212
+ }
213
+ (_attributedRequestKeys = (_step = step).attributedRequestKeys) !== null && _attributedRequestKeys !== void 0 ? _attributedRequestKeys : _step.attributedRequestKeys = [];
214
+ if (step.attributedRequestKeys.length >= MAX_ATTRIBUTED_REQUEST_KEYS) {
215
+ return;
216
+ }
217
+ if (!step.attributedRequestKeys.includes(requestKey)) {
218
+ step.attributedRequestKeys.push(requestKey);
146
219
  }
147
- return ((_longestEndpointMatch = longestEndpointMatch(requestTimeouts.endpoints, key)) === null || _longestEndpointMatch === void 0 ? void 0 : _longestEndpointMatch.ignore) === true;
148
220
  }
149
221
  function resolveJourneyName(journey) {
150
222
  if (journey == null) {
@@ -153,52 +225,169 @@ function toName(target) {
153
225
  if (typeof journey === 'string' || !Array.isArray(journey)) {
154
226
  return toName(journey);
155
227
  }
156
- return api.firstOpenJourney(journey.map(toName));
228
+ return api.firstOpenJourneyName(journey.map(toName));
229
+ }
230
+ function configFromTarget(target) {
231
+ if (typeof target === 'string') {
232
+ return undefined;
233
+ }
234
+ if ('config' in target && target.config != null && typeof target.config === 'object') {
235
+ return target.config;
236
+ }
237
+ const rec = target;
238
+ if (typeof rec.name === 'string' && typeof rec.team === 'string' && typeof rec.group === 'string' && typeof rec.service === 'string') {
239
+ return target;
240
+ }
241
+ return undefined;
242
+ }
243
+ function maybeAutoStart(target) {
244
+ if (target == null || typeof target === 'string' || Array.isArray(target)) {
245
+ return;
246
+ }
247
+ const def = configFromTarget(target);
248
+ if (def && !api.getOpenJourney(def.name)) {
249
+ api.startJourney(def);
250
+ }
157
251
  }
158
252
  function createStepHandle(journeyName, step) {
159
253
  return {
160
- name: journeyName,
254
+ journeyName,
161
255
  setAttribute (key, value) {
162
- step.attributes[key] = value;
256
+ setSafeAttribute(step.attributes, key, value);
163
257
  },
164
258
  setTags (tags) {
165
- api.setJourneyTags(journeyName, tags);
259
+ if (step.journey.closed) {
260
+ return;
261
+ }
262
+ assignRecord(step.journey.tags, tags, MAX_TAG_KEYS);
166
263
  },
167
- complete (tags) {
168
- api.completeJourney(journeyName, tags);
264
+ completeJourney (tags) {
265
+ api.completeJourneyState(step.journey, tags);
169
266
  },
170
- fail (reason) {
171
- api.failJourney(journeyName, reason);
267
+ failJourney (reason) {
268
+ api.failJourney(step.journey, reason);
172
269
  },
173
- // Box in JourneyStepTag — raw StepRecord is circular and blows jQuery/axios deep-merge.
174
- tag: ()=>({
175
- journeyStep: new JourneyStepTag(step)
176
- })
270
+ // Box in JourneyStepStamp — raw StepRecord is circular and blows jQuery/axios deep-merge.
271
+ stamp: (scoreOrOpts)=>new JourneyStepStamp(step, resolveStampOpts(scoreOrOpts))
177
272
  };
178
273
  }
179
274
  const api = {
180
- getRequestTimeouts () {
181
- return requestTimeouts;
275
+ get id () {
276
+ return id;
277
+ },
278
+ set id (next){
279
+ id = next;
182
280
  },
183
- setRequestTimeouts (next) {
184
- requestTimeouts = {
185
- ...next,
186
- endpoints: sortEndpointsByLongestMatch(next.endpoints)
281
+ getSlowRequests () {
282
+ return effectiveSlowRequests();
283
+ },
284
+ setSlowRequests (next1) {
285
+ slowRequests = {
286
+ ...next1,
287
+ endpoints: sortEndpointsByLongestMatch(next1.endpoints)
187
288
  };
188
289
  },
189
- setSinks (next) {
290
+ getMaxSteps () {
291
+ return maxSteps;
292
+ },
293
+ setMaxSteps (next1) {
294
+ maxSteps = clampMaxSteps(next1);
295
+ },
296
+ getDefaultJourneyIdleMs () {
297
+ return defaultJourneyIdleMs;
298
+ },
299
+ setDefaultJourneyIdleMs (next1) {
300
+ defaultJourneyIdleMs = finiteTimeoutMs(next1);
301
+ },
302
+ setSinks (next1) {
303
+ sinks = [
304
+ ...next1
305
+ ];
306
+ },
307
+ trySetConfiguredSinks (next1) {
308
+ if (sinksConfigured) {
309
+ return false;
310
+ }
190
311
  sinks = [
191
- ...next
312
+ ...next1
192
313
  ];
314
+ sinksConfigured = true;
315
+ return true;
193
316
  },
194
317
  addSink (sink) {
195
318
  sinks.push(sink);
196
319
  },
197
320
  emit,
321
+ setPolicyOverlay (next1) {
322
+ overlay = {
323
+ ...overlay,
324
+ ...next1
325
+ };
326
+ },
327
+ getAutoAttributeRequests () {
328
+ if (overlay.autoAttributeRequests !== undefined) {
329
+ return overlay.autoAttributeRequests;
330
+ }
331
+ return getSharedAutoAttributeRequests();
332
+ },
333
+ getHttpAbortedRequestsPolicy () {
334
+ var _overlay_httpAbortedRequests;
335
+ return (_overlay_httpAbortedRequests = overlay.httpAbortedRequests) !== null && _overlay_httpAbortedRequests !== void 0 ? _overlay_httpAbortedRequests : getSharedHttpAbortedRequestsPolicy();
336
+ },
337
+ getHttpClientErrorRequestsPolicy () {
338
+ var _overlay_httpClientErrorRequests;
339
+ return (_overlay_httpClientErrorRequests = overlay.httpClientErrorRequests) !== null && _overlay_httpClientErrorRequests !== void 0 ? _overlay_httpClientErrorRequests : getSharedHttpClientErrorRequestsPolicy();
340
+ },
198
341
  getOpenJourney (name) {
199
342
  return journeys.get(name);
200
343
  },
201
- firstOpenJourney (names) {
344
+ getDebugSnapshot () {
345
+ const active = api.activeJourneyStep();
346
+ return {
347
+ id: api.id,
348
+ openJourneys: [
349
+ ...journeys.values()
350
+ ].map((journey)=>({
351
+ name: journey.name,
352
+ team: journey.team,
353
+ group: journey.group,
354
+ service: journey.service,
355
+ verdict: journey.verdict,
356
+ reason: journey.reason,
357
+ tags: {
358
+ ...journey.tags
359
+ },
360
+ stepsInFlight: getInFlightSteps(journey).map((step)=>step.name),
361
+ steps: journey.steps.map((step)=>{
362
+ var _step_attributedRequestKeys;
363
+ return {
364
+ name: step.name,
365
+ outcome: step.outcome,
366
+ durationMs: step.durationMs,
367
+ ...step.reason ? {
368
+ reason: step.reason
369
+ } : {},
370
+ ...((_step_attributedRequestKeys = step.attributedRequestKeys) === null || _step_attributedRequestKeys === void 0 ? void 0 : _step_attributedRequestKeys.length) ? {
371
+ attributedRequestKeys: [
372
+ ...step.attributedRequestKeys
373
+ ]
374
+ } : {}
375
+ };
376
+ })
377
+ })),
378
+ activeStep: active ? {
379
+ journey: active.journey.name,
380
+ name: active.name
381
+ } : null,
382
+ policyOverlay: {
383
+ slowRequests: overlay.slowRequests != null,
384
+ httpAbortedRequests: overlay.httpAbortedRequests != null,
385
+ httpClientErrorRequests: overlay.httpClientErrorRequests != null,
386
+ autoAttributeRequests: overlay.autoAttributeRequests != null
387
+ }
388
+ };
389
+ },
390
+ firstOpenJourneyName (names) {
202
391
  for (const name of names){
203
392
  if (journeys.has(name)) {
204
393
  return name;
@@ -209,41 +398,46 @@ function toName(target) {
209
398
  setJourneyTags (name, tags) {
210
399
  const journey = name ? journeys.get(name) : undefined;
211
400
  if (journey) {
212
- Object.assign(journey.tags, tags);
401
+ assignRecord(journey.tags, tags, MAX_TAG_KEYS);
213
402
  }
214
403
  },
215
- startJourney (def) {
216
- var _def_timeoutMs, _def_tags;
217
- const existing = journeys.get(def.name);
404
+ startJourney (config) {
405
+ const existing = journeys.get(config.name);
218
406
  if (existing) {
219
407
  finish(existing, existing.verdict === 'bad' ? 'bad' : 'excluded');
220
408
  }
409
+ const tags = emptyRecord();
410
+ assignRecord(tags, config.tags, MAX_TAG_KEYS);
411
+ const snapshot = freezeJourneyDef(config, tags);
412
+ const timeout = resolveJourneyTimeoutMs(snapshot.timeoutMs, defaultJourneyIdleMs);
221
413
  const journey = {
222
- name: def.name,
223
- team: def.team,
224
- group: def.group,
225
- service: def.service,
414
+ config: snapshot,
415
+ name: snapshot.name,
416
+ team: snapshot.team,
417
+ group: snapshot.group,
418
+ service: snapshot.service,
226
419
  verdict: 'good',
227
420
  startedAt: globalThis.performance.now(),
228
- timeoutMs: (_def_timeoutMs = def.timeoutMs) !== null && _def_timeoutMs !== void 0 ? _def_timeoutMs : 0,
229
- stepTimeoutMs: def.stepTimeoutMs,
421
+ timeoutMs: timeout.ms,
422
+ timeoutExplicit: timeout.explicit,
423
+ stepTimeoutMs: snapshot.stepTimeoutMs !== undefined ? finiteTimeoutMs(snapshot.stepTimeoutMs) : undefined,
230
424
  reason: null,
231
425
  steps: [],
232
- expected: def.steps ? [
233
- ...def.steps
426
+ expected: snapshot.expected ? [
427
+ ...snapshot.expected
234
428
  ] : null,
235
- tags: {
236
- ...(_def_tags = def.tags) !== null && _def_tags !== void 0 ? _def_tags : {}
237
- },
238
- requestTimeoutMs: def.requestTimeoutMs,
239
- endpoints: sortEndpointsByLongestMatch(def.endpoints),
429
+ tags,
430
+ slowRequestMs: finiteSlowRequestMs(snapshot.slowRequestMs),
431
+ endpoints: snapshot.endpoints,
240
432
  timer: null,
241
- closed: false
433
+ closed: false,
434
+ maxSteps: snapshot.maxSteps !== undefined ? clampMaxSteps(snapshot.maxSteps) : undefined
242
435
  };
243
- journeys.set(def.name, journey);
436
+ journeys.set(config.name, journey);
437
+ journey[JOURNEY_ENGINE] = bindJourneyEngine(api, journey, shouldIgnoreRequest);
244
438
  armCountdown(journey);
245
439
  },
246
- failJourneyNow (journey, reason) {
440
+ failJourney (journey, reason) {
247
441
  var _journey, _reason;
248
442
  if (journey.closed) {
249
443
  return;
@@ -252,42 +446,87 @@ function toName(target) {
252
446
  (_reason = (_journey = journey).reason) !== null && _reason !== void 0 ? _reason : _journey.reason = reason;
253
447
  finish(journey, 'bad');
254
448
  },
255
- failJourney (name, reason) {
449
+ completeJourney (name, tags) {
450
+ if (!name) {
451
+ return;
452
+ }
256
453
  const journey = journeys.get(name);
257
454
  if (journey) {
258
- api.failJourneyNow(journey, reason);
455
+ api.completeJourneyState(journey, tags);
259
456
  }
260
457
  },
261
- completeJourney (name, tags) {
262
- if (!name) {
458
+ completeJourneyState (journey, tags) {
459
+ if (journey.closed) {
263
460
  return;
264
461
  }
265
462
  if (tags) {
266
- api.setJourneyTags(name, tags);
463
+ assignRecord(journey.tags, tags, MAX_TAG_KEYS);
267
464
  }
268
- const journey = journeys.get(name);
269
- if (journey) {
270
- finish(journey, journey.verdict === 'bad' ? 'bad' : 'good');
465
+ finish(journey, journey.verdict === 'bad' ? 'bad' : 'good');
466
+ },
467
+ excludeJourney (journey) {
468
+ if (journey.closed) {
469
+ return;
271
470
  }
471
+ finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded');
272
472
  },
273
- excludeJourney (name) {
274
- const journey = journeys.get(name);
275
- if (journey) {
276
- finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded');
473
+ updateOpenJourney (config) {
474
+ const journey = journeys.get(config.name);
475
+ if (!journey || journey.closed) {
476
+ return;
477
+ }
478
+ journey.team = config.team;
479
+ journey.group = config.group;
480
+ journey.service = config.service;
481
+ const timeout = resolveJourneyTimeoutMs(config.timeoutMs, defaultJourneyIdleMs);
482
+ journey.timeoutMs = timeout.ms;
483
+ journey.timeoutExplicit = timeout.explicit;
484
+ journey.stepTimeoutMs = config.stepTimeoutMs !== undefined ? finiteTimeoutMs(config.stepTimeoutMs) : undefined;
485
+ journey.slowRequestMs = finiteSlowRequestMs(config.slowRequestMs);
486
+ journey.endpoints = sortEndpointsByLongestMatch(config.endpoints);
487
+ journey.expected = config.expected ? [
488
+ ...config.expected
489
+ ] : null;
490
+ journey.maxSteps = config.maxSteps !== undefined ? clampMaxSteps(config.maxSteps) : undefined;
491
+ if (config.tags) {
492
+ assignRecord(journey.tags, config.tags, MAX_TAG_KEYS);
493
+ }
494
+ clearCountdown(journey);
495
+ if (journey.timeoutMs <= 0) {
496
+ return;
497
+ }
498
+ const elapsedMs = globalThis.performance.now() - journey.startedAt;
499
+ const remainingMs = journey.timeoutMs - elapsedMs;
500
+ if (remainingMs <= 0) {
501
+ if (journey.timeoutExplicit) {
502
+ finish(journey, 'bad', 'journey-timeout');
503
+ return;
504
+ }
505
+ finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded', 'journey-idle-timeout');
506
+ return;
277
507
  }
508
+ armCountdown(journey, remainingMs);
278
509
  },
279
510
  activeJourneyStep () {
280
511
  var _inFlight_values_next_value;
512
+ if (!api.getAutoAttributeRequests()) {
513
+ return null;
514
+ }
281
515
  if (inFlight.size !== 1) {
282
516
  return null;
283
517
  }
284
518
  return (_inFlight_values_next_value = inFlight.values().next().value) !== null && _inFlight_values_next_value !== void 0 ? _inFlight_values_next_value : null;
285
519
  },
286
520
  async journeyStep (journey, stepName, fn, opts) {
287
- var _ref, _ref1;
521
+ var _open_maxSteps, _ref, _ref1;
522
+ maybeAutoStart(journey);
288
523
  const journeyName = resolveJourneyName(journey);
289
524
  const open = journeyName ? journeys.get(journeyName) : undefined;
290
525
  if (!open || !journeyName) {
526
+ if (isJourneyDebugEnabled()) {
527
+ // eslint-disable-next-line no-console -- debug-only untraced hint
528
+ console.debug(`[journey] step "${stepName}" ran untraced (no open journey)`);
529
+ }
291
530
  return fn(noopStep);
292
531
  }
293
532
  const step = {
@@ -295,10 +534,15 @@ function toName(target) {
295
534
  startedAt: globalThis.performance.now(),
296
535
  durationMs: 0,
297
536
  outcome: 'good',
298
- attributes: {},
537
+ attributes: emptyRecord(),
299
538
  journey: open
300
539
  };
301
- open.steps.push(step);
540
+ const cap = (_open_maxSteps = open.maxSteps) !== null && _open_maxSteps !== void 0 ? _open_maxSteps : maxSteps;
541
+ if (open.steps.length >= cap) {
542
+ open.tags.steps_truncated = true;
543
+ } else {
544
+ open.steps.push(step);
545
+ }
302
546
  const handle = createStepHandle(journeyName, step);
303
547
  const stepTimeoutMs = (_ref = (_ref1 = opts === null || opts === void 0 ? void 0 : opts.timeoutMs) !== null && _ref1 !== void 0 ? _ref1 : open.stepTimeoutMs) !== null && _ref !== void 0 ? _ref : 0;
304
548
  let timeoutTimer = null;
@@ -312,19 +556,23 @@ function toName(target) {
312
556
  (_reason = (_step = step).reason) !== null && _reason !== void 0 ? _reason : _step.reason = 'step-timeout';
313
557
  (_timeout_ms = (_step_attributes = step.attributes).timeout_ms) !== null && _timeout_ms !== void 0 ? _timeout_ms : _step_attributes.timeout_ms = stepTimeoutMs;
314
558
  step.durationMs = Math.round(globalThis.performance.now() - step.startedAt);
315
- api.failJourneyNow(open, 'step-timeout');
559
+ api.failJourney(open, 'step-timeout');
316
560
  }, stepTimeoutMs);
317
561
  }
318
562
  enterStep(step);
319
563
  try {
320
564
  return await fn(handle);
321
565
  } catch (err) {
322
- var _step, _reason, _step_attributes, _error;
323
- const message = err instanceof Error ? err.message : String(err);
324
- step.outcome = 'bad';
325
- (_reason = (_step = step).reason) !== null && _reason !== void 0 ? _reason : _step.reason = 'step-error';
326
- (_error = (_step_attributes = step.attributes).error) !== null && _error !== void 0 ? _error : _step_attributes.error = message;
327
- api.failJourneyNow(open, 'step-error');
566
+ if (isCanceledError(err)) {
567
+ /*
568
+ * Attributed abort is scored in onHttpComplete. Unattributed /
569
+ * ignored abort throws must not apply policy (empty requestKey).
570
+ */ } else {
571
+ var _step, _reason;
572
+ step.outcome = 'bad';
573
+ (_reason = (_step = step).reason) !== null && _reason !== void 0 ? _reason : _step.reason = 'step-error';
574
+ api.failJourney(open, 'step-error');
575
+ }
328
576
  throw err;
329
577
  } finally{
330
578
  if (timeoutTimer != null) {
@@ -340,20 +588,24 @@ function toName(target) {
340
588
  await Promise.resolve();
341
589
  return api.journeyStep(journey, stepName, fn, opts);
342
590
  },
591
+ shouldIgnoreRequest,
343
592
  reportBackendRequest (step, status, durationMs, requestKey) {
344
593
  var _step, _reason;
345
- if (!step) {
594
+ if (!(step === null || step === void 0 ? void 0 : step.journey)) {
346
595
  return;
347
596
  }
348
597
  const journey = step.journey;
349
598
  if (journey.closed) {
350
599
  return;
351
600
  }
352
- if (shouldIgnoreRequest(journey, requestKey)) {
601
+ trackAttributedKey(step, requestKey);
602
+ const endpointPolicy = resolveEndpointPolicy(journey, effectiveSlowRequests(), requestKey);
603
+ if (endpointPolicy.ignore) {
353
604
  return;
354
605
  }
355
606
  const failed = status === undefined || status >= 500;
356
- const slow = durationMs > resolveRequestTimeoutMs(journey, requestKey);
607
+ const threshold = endpointPolicy.slowRequestMs;
608
+ const slow = threshold > 0 && durationMs > threshold;
357
609
  if (!failed && !slow) {
358
610
  return;
359
611
  }
@@ -363,11 +615,11 @@ function toName(target) {
363
615
  if (failed && status !== undefined) {
364
616
  step.httpStatus = status;
365
617
  }
366
- api.failJourneyNow(journey, category);
618
+ api.failJourney(journey, category);
367
619
  },
368
- reset (next = {}) {
369
- var _next_sinks, _ref, _ref1;
370
- var _next_requestTimeouts, _next_requestTimeouts1;
620
+ reset (next1 = {}) {
621
+ var _next_sinks, _ref, _ref1, _next_defaultJourneyIdleMs;
622
+ var _next_slowRequests, _next_slowRequests1;
371
623
  for (const journey of [
372
624
  ...journeys.values()
373
625
  ]){
@@ -376,26 +628,85 @@ function toName(target) {
376
628
  }
377
629
  journeys.clear();
378
630
  inFlight.clear();
631
+ overlay = {};
632
+ sinksConfigured = false;
379
633
  sinks = [
380
- ...(_next_sinks = next.sinks) !== null && _next_sinks !== void 0 ? _next_sinks : []
634
+ ...(_next_sinks = next1.sinks) !== null && _next_sinks !== void 0 ? _next_sinks : []
381
635
  ];
382
- requestTimeouts = {
383
- defaultMs: (_ref = (_next_requestTimeouts = next.requestTimeouts) === null || _next_requestTimeouts === void 0 ? void 0 : _next_requestTimeouts.defaultMs) !== null && _ref !== void 0 ? _ref : DEFAULT_REQUEST_TIMEOUTS.defaultMs,
384
- endpoints: sortEndpointsByLongestMatch((_ref1 = (_next_requestTimeouts1 = next.requestTimeouts) === null || _next_requestTimeouts1 === void 0 ? void 0 : _next_requestTimeouts1.endpoints) !== null && _ref1 !== void 0 ? _ref1 : DEFAULT_REQUEST_TIMEOUTS.endpoints)
636
+ slowRequests = {
637
+ defaultMs: (_ref = (_next_slowRequests = next1.slowRequests) === null || _next_slowRequests === void 0 ? void 0 : _next_slowRequests.defaultMs) !== null && _ref !== void 0 ? _ref : DEFAULT_SLOW_REQUESTS.defaultMs,
638
+ endpoints: sortEndpointsByLongestMatch((_ref1 = (_next_slowRequests1 = next1.slowRequests) === null || _next_slowRequests1 === void 0 ? void 0 : _next_slowRequests1.endpoints) !== null && _ref1 !== void 0 ? _ref1 : DEFAULT_SLOW_REQUESTS.endpoints)
385
639
  };
640
+ maxSteps = next1.maxSteps !== undefined ? clampMaxSteps(next1.maxSteps) : DEFAULT_MAX_STEPS;
641
+ defaultJourneyIdleMs = finiteTimeoutMs((_next_defaultJourneyIdleMs = next1.defaultJourneyIdleMs) !== null && _next_defaultJourneyIdleMs !== void 0 ? _next_defaultJourneyIdleMs : DEFAULT_JOURNEY_IDLE_MS);
386
642
  }
387
643
  };
388
644
  return api;
389
645
  }
390
646
  /**
391
647
  * @internal Private — not part of the public package API.
392
- * Process-wide engine used by free helpers. App code does not need to touch this.
393
- */ export const defaultRuntime = createJourneyRuntime();
648
+ * Module-scoped engine used by free helpers. App code does not need to touch this.
649
+ * Each host/MFE bundle gets its own copy when the package is duplicated.
650
+ */ export const moduleRuntime = createJourneyRuntime();
651
+ const noopEngine = {
652
+ failJourney () {},
653
+ exclude () {},
654
+ shouldIgnoreRequest () {
655
+ return false;
656
+ },
657
+ reportBackendRequest () {},
658
+ getHttpAbortedRequestsPolicy () {
659
+ return 'continue';
660
+ },
661
+ getHttpClientErrorRequestsPolicy () {
662
+ return 'continue';
663
+ }
664
+ };
665
+ /**
666
+ * True when this bundle can fail/exclude/report the journey: stamped engine, or
667
+ * this runtime's own unstamped object. False for a foreign older-copy journey.
668
+ */ export function canRouteHttpToJourney(journey) {
669
+ return journey[JOURNEY_ENGINE] != null || moduleRuntime.getOpenJourney(journey.name) === journey;
670
+ }
671
+ /**
672
+ * @internal Prefer the creating engine on a journey (MFE `step.stamp()` on a host transport).
673
+ * Falls back to this bundle's module runtime only when this runtime owns the object.
674
+ * Unstamped foreign journeys (older package copies) are a no-op so a same-named
675
+ * host journey is not deleted from this map.
676
+ */ export function resolveJourneyEngine(journey) {
677
+ const stamped = journey[JOURNEY_ENGINE];
678
+ if (stamped) {
679
+ return stamped;
680
+ }
681
+ if (moduleRuntime.getOpenJourney(journey.name) !== journey) {
682
+ return noopEngine;
683
+ }
684
+ return {
685
+ failJourney (reason) {
686
+ moduleRuntime.failJourney(journey, reason);
687
+ },
688
+ exclude () {
689
+ moduleRuntime.excludeJourney(journey);
690
+ },
691
+ shouldIgnoreRequest (key) {
692
+ return moduleRuntime.shouldIgnoreRequest(journey, key);
693
+ },
694
+ reportBackendRequest (step, status, durationMs, requestKey) {
695
+ moduleRuntime.reportBackendRequest(step, status, durationMs, requestKey);
696
+ },
697
+ getHttpAbortedRequestsPolicy () {
698
+ return moduleRuntime.getHttpAbortedRequestsPolicy();
699
+ },
700
+ getHttpClientErrorRequestsPolicy () {
701
+ return moduleRuntime.getHttpClientErrorRequestsPolicy();
702
+ }
703
+ };
704
+ }
394
705
  /**
395
- * Reset the default engine (open journeys, ambient steps, sinks, request thresholds).
706
+ * @internal Reset the module engine (open journeys, ambient steps, sinks, slow-request thresholds).
396
707
  * Intended for tests — call in `beforeEach` / `afterEach` instead of manual cleanup.
397
708
  */ export function resetJourney(options) {
398
- defaultRuntime.reset(options);
709
+ moduleRuntime.reset(options);
399
710
  }
400
711
 
401
712
  //# sourceMappingURL=runtime.js.map