@servicetitan/journey 3.0.0 → 4.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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=persist.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/core/persist.test.ts"],"names":[],"mappings":""}
@@ -1,5 +1,5 @@
1
1
  import { JourneyStepStamp } from './step-tag';
2
- import type { JourneyDef, JourneyHandle, JourneyStepOptions, JourneyStepTarget, StepHandle, StepRecord, TagValue } from './types';
2
+ import type { JourneyDef, JourneyHandle, JourneyStepOptions, JourneyStepTarget, SerializedJourneyState, StepHandle, StepRecord, TagValue } from './types';
3
3
  /**
4
4
  * Unique in-flight step as a stamp-ready {@link JourneyStepStamp}, or null when
5
5
  * auto-attribute is disabled, or when 0 or 2+ steps are in flight app-wide.
@@ -40,4 +40,16 @@ export declare function completeJourney(name: string | null, tags?: Record<strin
40
40
  export declare function excludeJourney(name: string): void;
41
41
  /** Turn a journey config into a handle with bound lifecycle methods. Preferred public API. */
42
42
  export declare function defineJourney(config: JourneyDef): JourneyHandle;
43
+ /**
44
+ * Snapshot an open journey for cross-page transfer (e.g. into a cookie). Does
45
+ * NOT close the journey. Returns `null` when no journey is open under `name`.
46
+ */
47
+ export declare function serializeJourneyState(name: string): SerializedJourneyState | null;
48
+ /**
49
+ * Rehydrate a serialized journey onto this runtime. Returns `true` when the
50
+ * journey is now open; `false` when it exhausted its budget in transit (a
51
+ * `bad` `journey-timeout` event is emitted) or when a journey under the
52
+ * same name is already open.
53
+ */
54
+ export declare function restoreJourney(serialized: SerializedJourneyState, config: JourneyDef): boolean;
43
55
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/core/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EACR,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,QAAQ,EACX,MAAM,SAAS,CAAC;AAKjB;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,gBAAgB,GAAG,IAAI,CAiBnE;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACnB,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAC/B,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,CAEZ;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAExF;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED,yHAAyH;AACzH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAE1F;AAED,qHAAqH;AACrH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKjD;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAoC/D"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/core/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAyB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EACR,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,UAAU,EACV,QAAQ,EACX,MAAM,SAAS,CAAC;AAKjB;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,IAAI,gBAAgB,GAAG,IAAI,CAiBnE;AAED,uEAAuE;AACvE,wBAAgB,sBAAsB,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,IAAI,CAK9D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,IAAI,EAAE,UAAU,GAAG,SAAS,EAC5B,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACnB,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAC/B,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,CAEZ;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAExF;AAED,sFAAsF;AACtF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAK9D;AAED,yHAAyH;AACzH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAE1F;AAED,qHAAqH;AACrH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKjD;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,aAAa,CAoC/D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAEjF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,sBAAsB,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAE9F"}
package/dist/core/api.js CHANGED
@@ -118,5 +118,19 @@ let ambientStep = null;
118
118
  }
119
119
  };
120
120
  }
121
+ /**
122
+ * Snapshot an open journey for cross-page transfer (e.g. into a cookie). Does
123
+ * NOT close the journey. Returns `null` when no journey is open under `name`.
124
+ */ export function serializeJourneyState(name) {
125
+ return moduleRuntime.serializeJourneyState(name);
126
+ }
127
+ /**
128
+ * Rehydrate a serialized journey onto this runtime. Returns `true` when the
129
+ * journey is now open; `false` when it exhausted its budget in transit (a
130
+ * `bad` `journey-timeout` event is emitted) or when a journey under the
131
+ * same name is already open.
132
+ */ export function restoreJourney(serialized, config) {
133
+ return moduleRuntime.restoreJourney(serialized, config) !== null;
134
+ }
121
135
 
122
136
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/api.ts"],"sourcesContent":["import { moduleRuntime, resolveJourneyEngine } from './runtime';\nimport { adoptJourneyStepStamp, JourneyStepStamp } from './step-tag';\nimport type {\n JourneyDef,\n JourneyHandle,\n JourneyStepOptions,\n JourneyStepTarget,\n StepHandle,\n StepRecord,\n TagValue,\n} from './types';\n\nlet ambientStamp: JourneyStepStamp | null = null;\nlet ambientStep: StepRecord | null = null;\n\n/**\n * Unique in-flight step as a stamp-ready {@link JourneyStepStamp}, or null when\n * auto-attribute is disabled, or when 0 or 2+ steps are in flight app-wide.\n * Ambient stamps never carry `score` or `ignore`. Untagged traffic is attributed\n * to that lone step even if unrelated — prefer `step.stamp()` when the page has\n * background instrumented requests. Disable via\n * `configureJourney({ autoAttributeRequests: false })`.\n */\nexport function singleInFlightJourneyStep(): JourneyStepStamp | null {\n if (ambientStep?.journey.closed) {\n ambientStep = null;\n ambientStamp = null;\n }\n const activeStep = moduleRuntime.activeJourneyStep();\n if (!activeStep) {\n ambientStamp = null;\n ambientStep = null;\n return null;\n }\n if (ambientStep === activeStep && ambientStamp) {\n return ambientStamp;\n }\n ambientStep = activeStep;\n ambientStamp = new JourneyStepStamp(activeStep);\n return ambientStamp;\n}\n\n/** @internal Clear cached ambient stamp when runtime state changes. */\nexport function invalidateAmbientStamp(step?: StepRecord): void {\n if (!step || step === ambientStep) {\n ambientStamp = null;\n ambientStep = null;\n }\n}\n\n/**\n * Prefer an explicit `step.stamp()` value; else the ambient in-flight stamp.\n * Same-realm stamps are returned as-is (identity + score + ignore). Branded\n * foreign copies are adopted into a local stamp. Raw StepRecords are not stamps.\n */\nexport function resolveStamp(explicit?: unknown): JourneyStepStamp | undefined {\n const fromExplicit = adoptJourneyStepStamp(explicit);\n if (fromExplicit) {\n return fromExplicit;\n }\n return singleInFlightJourneyStep() ?? undefined;\n}\n\n/**\n * Record a finished backend request against a captured step.\n * 5xx / network / slow (over threshold) mark Bad; 4xx is not counted. Fail-fast on breach.\n * @internal Prefer {@link onHttpComplete} from adapters.\n */\nexport function reportBackendRequest(\n step: StepRecord | undefined,\n status: number | undefined,\n durationMs: number,\n requestKey: string\n): void {\n if (!step?.journey) {\n return;\n }\n resolveJourneyEngine(step.journey).reportBackendRequest(step, status, durationMs, requestKey);\n}\n\n/**\n * Run one step of a named journey. Runs untraced (noop handle) when no matching journey is open.\n * `journey` may be a name, null, an ordered candidate list, a def, or a handle.\n * A def or handle auto-starts when that journey is not already open; a bare name does not.\n * Prefer `defineJourney(...).step` when you own the journey config.\n */\nexport async function journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n): Promise<T> {\n return moduleRuntime.journeyStep(journey, stepName, fn, opts);\n}\n\n/** Merge custom tags onto an open journey. No-op if not open. Prefer `handle.setTags`. */\nexport function setJourneyTags(name: string | null, tags: Record<string, TagValue>): void {\n moduleRuntime.setJourneyTags(name, tags);\n}\n\n/** Mark a named journey Bad for a custom reason (fail-fast). Prefer `handle.fail`. */\nexport function failJourney(name: string, reason: string): void {\n const journey = moduleRuntime.getOpenJourney(name);\n if (journey) {\n moduleRuntime.failJourney(journey, reason);\n }\n}\n\n/** Successful end. Outcome stays Bad if a breach already occurred. No-op when name is null. Prefer `handle.complete`. */\nexport function completeJourney(name: string | null, tags?: Record<string, TagValue>): void {\n moduleRuntime.completeJourney(name, tags);\n}\n\n/** User left before finishing. Stays Bad if a breach already occurred (breach-anchored). Prefer `handle.exclude`. */\nexport function excludeJourney(name: string): void {\n const journey = moduleRuntime.getOpenJourney(name);\n if (journey) {\n moduleRuntime.excludeJourney(journey);\n }\n}\n\n/** Turn a journey config into a handle with bound lifecycle methods. Preferred public API. */\nexport function defineJourney(config: JourneyDef): JourneyHandle {\n return {\n config,\n start(tags) {\n moduleRuntime.startJourney(config);\n if (tags) {\n moduleRuntime.setJourneyTags(config.name, tags);\n }\n },\n step(stepName, fn, opts) {\n if (!moduleRuntime.getOpenJourney(config.name)) {\n moduleRuntime.startJourney(config);\n }\n return journeyStep(config.name, stepName, fn, opts);\n },\n async mountStep(stepName, fn, opts) {\n // Defer so a parent <JourneyScope> opens first (child effects run before parent).\n await Promise.resolve();\n if (!moduleRuntime.getOpenJourney(config.name)) {\n moduleRuntime.startJourney(config);\n }\n return journeyStep(config.name, stepName, fn, opts);\n },\n complete(tags) {\n completeJourney(config.name, tags);\n },\n fail(reason) {\n failJourney(config.name, reason);\n },\n exclude() {\n excludeJourney(config.name);\n },\n setTags(tags) {\n setJourneyTags(config.name, tags);\n },\n };\n}\n"],"names":["moduleRuntime","resolveJourneyEngine","adoptJourneyStepStamp","JourneyStepStamp","ambientStamp","ambientStep","singleInFlightJourneyStep","journey","closed","activeStep","activeJourneyStep","invalidateAmbientStamp","step","resolveStamp","explicit","fromExplicit","undefined","reportBackendRequest","status","durationMs","requestKey","journeyStep","stepName","fn","opts","setJourneyTags","name","tags","failJourney","reason","getOpenJourney","completeJourney","excludeJourney","defineJourney","config","start","startJourney","mountStep","Promise","resolve","complete","fail","exclude","setTags"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/api.ts"],"sourcesContent":["import { moduleRuntime, resolveJourneyEngine } from './runtime';\nimport { adoptJourneyStepStamp, JourneyStepStamp } from './step-tag';\nimport type {\n JourneyDef,\n JourneyHandle,\n JourneyStepOptions,\n JourneyStepTarget,\n SerializedJourneyState,\n StepHandle,\n StepRecord,\n TagValue,\n} from './types';\n\nlet ambientStamp: JourneyStepStamp | null = null;\nlet ambientStep: StepRecord | null = null;\n\n/**\n * Unique in-flight step as a stamp-ready {@link JourneyStepStamp}, or null when\n * auto-attribute is disabled, or when 0 or 2+ steps are in flight app-wide.\n * Ambient stamps never carry `score` or `ignore`. Untagged traffic is attributed\n * to that lone step even if unrelated — prefer `step.stamp()` when the page has\n * background instrumented requests. Disable via\n * `configureJourney({ autoAttributeRequests: false })`.\n */\nexport function singleInFlightJourneyStep(): JourneyStepStamp | null {\n if (ambientStep?.journey.closed) {\n ambientStep = null;\n ambientStamp = null;\n }\n const activeStep = moduleRuntime.activeJourneyStep();\n if (!activeStep) {\n ambientStamp = null;\n ambientStep = null;\n return null;\n }\n if (ambientStep === activeStep && ambientStamp) {\n return ambientStamp;\n }\n ambientStep = activeStep;\n ambientStamp = new JourneyStepStamp(activeStep);\n return ambientStamp;\n}\n\n/** @internal Clear cached ambient stamp when runtime state changes. */\nexport function invalidateAmbientStamp(step?: StepRecord): void {\n if (!step || step === ambientStep) {\n ambientStamp = null;\n ambientStep = null;\n }\n}\n\n/**\n * Prefer an explicit `step.stamp()` value; else the ambient in-flight stamp.\n * Same-realm stamps are returned as-is (identity + score + ignore). Branded\n * foreign copies are adopted into a local stamp. Raw StepRecords are not stamps.\n */\nexport function resolveStamp(explicit?: unknown): JourneyStepStamp | undefined {\n const fromExplicit = adoptJourneyStepStamp(explicit);\n if (fromExplicit) {\n return fromExplicit;\n }\n return singleInFlightJourneyStep() ?? undefined;\n}\n\n/**\n * Record a finished backend request against a captured step.\n * 5xx / network / slow (over threshold) mark Bad; 4xx is not counted. Fail-fast on breach.\n * @internal Prefer {@link onHttpComplete} from adapters.\n */\nexport function reportBackendRequest(\n step: StepRecord | undefined,\n status: number | undefined,\n durationMs: number,\n requestKey: string\n): void {\n if (!step?.journey) {\n return;\n }\n resolveJourneyEngine(step.journey).reportBackendRequest(step, status, durationMs, requestKey);\n}\n\n/**\n * Run one step of a named journey. Runs untraced (noop handle) when no matching journey is open.\n * `journey` may be a name, null, an ordered candidate list, a def, or a handle.\n * A def or handle auto-starts when that journey is not already open; a bare name does not.\n * Prefer `defineJourney(...).step` when you own the journey config.\n */\nexport async function journeyStep<T>(\n journey: JourneyStepTarget,\n stepName: string,\n fn: (step: StepHandle) => T | Promise<T>,\n opts?: JourneyStepOptions\n): Promise<T> {\n return moduleRuntime.journeyStep(journey, stepName, fn, opts);\n}\n\n/** Merge custom tags onto an open journey. No-op if not open. Prefer `handle.setTags`. */\nexport function setJourneyTags(name: string | null, tags: Record<string, TagValue>): void {\n moduleRuntime.setJourneyTags(name, tags);\n}\n\n/** Mark a named journey Bad for a custom reason (fail-fast). Prefer `handle.fail`. */\nexport function failJourney(name: string, reason: string): void {\n const journey = moduleRuntime.getOpenJourney(name);\n if (journey) {\n moduleRuntime.failJourney(journey, reason);\n }\n}\n\n/** Successful end. Outcome stays Bad if a breach already occurred. No-op when name is null. Prefer `handle.complete`. */\nexport function completeJourney(name: string | null, tags?: Record<string, TagValue>): void {\n moduleRuntime.completeJourney(name, tags);\n}\n\n/** User left before finishing. Stays Bad if a breach already occurred (breach-anchored). Prefer `handle.exclude`. */\nexport function excludeJourney(name: string): void {\n const journey = moduleRuntime.getOpenJourney(name);\n if (journey) {\n moduleRuntime.excludeJourney(journey);\n }\n}\n\n/** Turn a journey config into a handle with bound lifecycle methods. Preferred public API. */\nexport function defineJourney(config: JourneyDef): JourneyHandle {\n return {\n config,\n start(tags) {\n moduleRuntime.startJourney(config);\n if (tags) {\n moduleRuntime.setJourneyTags(config.name, tags);\n }\n },\n step(stepName, fn, opts) {\n if (!moduleRuntime.getOpenJourney(config.name)) {\n moduleRuntime.startJourney(config);\n }\n return journeyStep(config.name, stepName, fn, opts);\n },\n async mountStep(stepName, fn, opts) {\n // Defer so a parent <JourneyScope> opens first (child effects run before parent).\n await Promise.resolve();\n if (!moduleRuntime.getOpenJourney(config.name)) {\n moduleRuntime.startJourney(config);\n }\n return journeyStep(config.name, stepName, fn, opts);\n },\n complete(tags) {\n completeJourney(config.name, tags);\n },\n fail(reason) {\n failJourney(config.name, reason);\n },\n exclude() {\n excludeJourney(config.name);\n },\n setTags(tags) {\n setJourneyTags(config.name, tags);\n },\n };\n}\n\n/**\n * Snapshot an open journey for cross-page transfer (e.g. into a cookie). Does\n * NOT close the journey. Returns `null` when no journey is open under `name`.\n */\nexport function serializeJourneyState(name: string): SerializedJourneyState | null {\n return moduleRuntime.serializeJourneyState(name);\n}\n\n/**\n * Rehydrate a serialized journey onto this runtime. Returns `true` when the\n * journey is now open; `false` when it exhausted its budget in transit (a\n * `bad` `journey-timeout` event is emitted) or when a journey under the\n * same name is already open.\n */\nexport function restoreJourney(serialized: SerializedJourneyState, config: JourneyDef): boolean {\n return moduleRuntime.restoreJourney(serialized, config) !== null;\n}\n"],"names":["moduleRuntime","resolveJourneyEngine","adoptJourneyStepStamp","JourneyStepStamp","ambientStamp","ambientStep","singleInFlightJourneyStep","journey","closed","activeStep","activeJourneyStep","invalidateAmbientStamp","step","resolveStamp","explicit","fromExplicit","undefined","reportBackendRequest","status","durationMs","requestKey","journeyStep","stepName","fn","opts","setJourneyTags","name","tags","failJourney","reason","getOpenJourney","completeJourney","excludeJourney","defineJourney","config","start","startJourney","mountStep","Promise","resolve","complete","fail","exclude","setTags","serializeJourneyState","restoreJourney","serialized"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /** Core barrel — public free helpers, handles, and types. Engine lives in `./runtime`. */
2
- export { completeJourney, defineJourney, excludeJourney, failJourney, journeyStep, reportBackendRequest, resolveStamp, setJourneyTags, singleInFlightJourneyStep, } from './api';
2
+ export { completeJourney, defineJourney, excludeJourney, failJourney, journeyStep, reportBackendRequest, resolveStamp, restoreJourney, serializeJourneyState, setJourneyTags, singleInFlightJourneyStep, } from './api';
3
3
  export { resetJourney, } from './runtime';
4
- export type { JourneyDef, JourneyEvent, JourneyHandle, JourneyNameLike, JourneySink, JourneyStepEvent, JourneyStepOptions, JourneyStepTarget, StepHandle, TagValue, } from './types';
4
+ export type { JourneyDef, JourneyEvent, JourneyHandle, JourneyNameLike, JourneySink, JourneyStepEvent, JourneyStepOptions, JourneyStepTarget, SerializedJourneyState, StepHandle, TagValue, } from './types';
5
5
  export { JourneyStepStamp } from './step-tag';
6
6
  export type { JourneyHttpPolicyContext, JourneyHttpScore, JourneyHttpScoreContext, JourneyRequestPolicy, JourneyStampOptions, RequestPolicyConfig, } from './request-policy';
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,OAAO,EACH,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,yBAAyB,GAC5B,MAAM,OAAO,CAAC;AACf,OAAO,EAEH,YAAY,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,UAAU,EACV,QAAQ,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EACR,wBAAwB,EACxB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,OAAO,EACH,eAAe,EACf,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,cAAc,EACd,yBAAyB,GAC5B,MAAM,OAAO,CAAC;AACf,OAAO,EAEH,YAAY,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EACR,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,EACtB,UAAU,EACV,QAAQ,GACX,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EACR,wBAAwB,EACxB,gBAAgB,EAChB,uBAAuB,EACvB,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,GACtB,MAAM,kBAAkB,CAAC"}
@@ -1,4 +1,4 @@
1
- /** Core barrel — public free helpers, handles, and types. Engine lives in `./runtime`. */ export { completeJourney, defineJourney, excludeJourney, failJourney, journeyStep, reportBackendRequest, resolveStamp, setJourneyTags, singleInFlightJourneyStep } from './api';
1
+ /** Core barrel — public free helpers, handles, and types. Engine lives in `./runtime`. */ export { completeJourney, defineJourney, excludeJourney, failJourney, journeyStep, reportBackendRequest, resolveStamp, restoreJourney, serializeJourneyState, setJourneyTags, singleInFlightJourneyStep } from './api';
2
2
  export { // @internal Test helper — not a supported consumer API.
3
3
  resetJourney } from './runtime';
4
4
  export { JourneyStepStamp } from './step-tag';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["/** Core barrel — public free helpers, handles, and types. Engine lives in `./runtime`. */\n\nexport {\n completeJourney,\n defineJourney,\n excludeJourney,\n failJourney,\n journeyStep,\n reportBackendRequest,\n resolveStamp,\n setJourneyTags,\n singleInFlightJourneyStep,\n} from './api';\nexport {\n // @internal Test helper — not a supported consumer API.\n resetJourney,\n} from './runtime';\nexport type {\n JourneyDef,\n JourneyEvent,\n JourneyHandle,\n JourneyNameLike,\n JourneySink,\n JourneyStepEvent,\n JourneyStepOptions,\n JourneyStepTarget,\n StepHandle,\n TagValue,\n} from './types';\nexport { JourneyStepStamp } from './step-tag';\nexport type {\n JourneyHttpPolicyContext,\n JourneyHttpScore,\n JourneyHttpScoreContext,\n JourneyRequestPolicy,\n JourneyStampOptions,\n RequestPolicyConfig,\n} from './request-policy';\n"],"names":["completeJourney","defineJourney","excludeJourney","failJourney","journeyStep","reportBackendRequest","resolveStamp","setJourneyTags","singleInFlightJourneyStep","resetJourney","JourneyStepStamp"],"mappings":"AAAA,wFAAwF,GAExF,SACIA,eAAe,EACfC,aAAa,EACbC,cAAc,EACdC,WAAW,EACXC,WAAW,EACXC,oBAAoB,EACpBC,YAAY,EACZC,cAAc,EACdC,yBAAyB,QACtB,QAAQ;AACf,SACI,wDAAwD;AACxDC,YAAY,QACT,YAAY;AAanB,SAASC,gBAAgB,QAAQ,aAAa"}
1
+ {"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["/** Core barrel — public free helpers, handles, and types. Engine lives in `./runtime`. */\n\nexport {\n completeJourney,\n defineJourney,\n excludeJourney,\n failJourney,\n journeyStep,\n reportBackendRequest,\n resolveStamp,\n restoreJourney,\n serializeJourneyState,\n setJourneyTags,\n singleInFlightJourneyStep,\n} from './api';\nexport {\n // @internal Test helper — not a supported consumer API.\n resetJourney,\n} from './runtime';\nexport type {\n JourneyDef,\n JourneyEvent,\n JourneyHandle,\n JourneyNameLike,\n JourneySink,\n JourneyStepEvent,\n JourneyStepOptions,\n JourneyStepTarget,\n SerializedJourneyState,\n StepHandle,\n TagValue,\n} from './types';\nexport { JourneyStepStamp } from './step-tag';\nexport type {\n JourneyHttpPolicyContext,\n JourneyHttpScore,\n JourneyHttpScoreContext,\n JourneyRequestPolicy,\n JourneyStampOptions,\n RequestPolicyConfig,\n} from './request-policy';\n"],"names":["completeJourney","defineJourney","excludeJourney","failJourney","journeyStep","reportBackendRequest","resolveStamp","restoreJourney","serializeJourneyState","setJourneyTags","singleInFlightJourneyStep","resetJourney","JourneyStepStamp"],"mappings":"AAAA,wFAAwF,GAExF,SACIA,eAAe,EACfC,aAAa,EACbC,cAAc,EACdC,WAAW,EACXC,WAAW,EACXC,oBAAoB,EACpBC,YAAY,EACZC,cAAc,EACdC,qBAAqB,EACrBC,cAAc,EACdC,yBAAyB,QACtB,QAAQ;AACf,SACI,wDAAwD;AACxDC,YAAY,QACT,YAAY;AAcnB,SAASC,gBAAgB,QAAQ,aAAa"}
@@ -0,0 +1,19 @@
1
+ import { type JourneyRuntime } from './runtime';
2
+ import { type JourneyDef, type JourneyState, type SerializedJourneyState } from './types';
3
+ /**
4
+ * @internal Project an open {@link JourneyState} into a plain, JSON-safe
5
+ * {@link SerializedJourneyState} that can ride a cookie across page navigations.
6
+ * The step projection mirrors `finish()`; `startedAt` (a `performance.now()`
7
+ * monotonic stamp) is bridged to a wall-clock epoch so it survives the page
8
+ * load where `performance.now()` resets.
9
+ */
10
+ export declare function projectJourneyState(journey: JourneyState): SerializedJourneyState;
11
+ /**
12
+ * @internal Rehydrate a {@link SerializedJourneyState} into a live
13
+ * {@link JourneyState} bound to the supplied runtime. `startedAt` is rebased
14
+ * from the wall-clock epoch back to a `performance.now()` monotonic stamp,
15
+ * `StepRecord[]` is rebuilt with re-linked circular references, and the
16
+ * `JOURNEY_ENGINE` hook is re-bound so HTTP attribution works on the new page.
17
+ */
18
+ export declare function deserializeJourneyState(serialized: SerializedJourneyState, config: JourneyDef, api: JourneyRuntime, defaultJourneyIdleMs: number): JourneyState;
19
+ //# sourceMappingURL=persist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../../src/core/persist.ts"],"names":[],"mappings":"AASA,OAAO,EAAuC,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAEH,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAE9B,MAAM,SAAS,CAAC;AAEjB;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,sBAAsB,CA0BjF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,sBAAsB,EAClC,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,cAAc,EACnB,oBAAoB,EAAE,MAAM,GAC7B,YAAY,CAiEd"}
@@ -0,0 +1,111 @@
1
+ import { clampMaxSteps, finiteSlowRequestMs, finiteTimeoutMs, MAX_ATTRIBUTE_KEYS, MAX_TAG_KEYS, resolveJourneyTimeoutMs } from './limits';
2
+ import { assignRecord, emptyRecord } from './sanitize';
3
+ import { bindJourneyEngine, freezeJourneyDef } from './runtime';
4
+ import { JOURNEY_ENGINE } from './types';
5
+ /**
6
+ * @internal Project an open {@link JourneyState} into a plain, JSON-safe
7
+ * {@link SerializedJourneyState} that can ride a cookie across page navigations.
8
+ * The step projection mirrors `finish()`; `startedAt` (a `performance.now()`
9
+ * monotonic stamp) is bridged to a wall-clock epoch so it survives the page
10
+ * load where `performance.now()` resets.
11
+ */ export function projectJourneyState(journey) {
12
+ const steps = journey.steps.map((s)=>({
13
+ name: s.name,
14
+ startMs: Math.round(s.startedAt - journey.startedAt),
15
+ durationMs: s.durationMs || Math.round(globalThis.performance.now() - s.startedAt),
16
+ outcome: s.outcome,
17
+ ...s.reason ? {
18
+ reason: s.reason
19
+ } : {},
20
+ ...s.httpStatus !== undefined ? {
21
+ httpStatus: s.httpStatus
22
+ } : {},
23
+ // Attributes are raw here — final emission sanitization happens in finish().
24
+ ...Object.keys(s.attributes).length ? {
25
+ attributes: {
26
+ ...s.attributes
27
+ }
28
+ } : {}
29
+ }));
30
+ const startedAtEpoch = Date.now() - (globalThis.performance.now() - journey.startedAt);
31
+ // Coerce any non-null st_journey_id tag to a string so a numeric/boolean id survives the round-trip.
32
+ const stJourneyId = journey.tags.st_journey_id != null ? String(journey.tags.st_journey_id) : '';
33
+ return {
34
+ stJourneyId,
35
+ startedAtEpoch,
36
+ // Open journeys are never 'excluded' — that verdict is only set inside finish().
37
+ verdict: journey.verdict === 'bad' ? 'bad' : 'good',
38
+ reason: journey.reason,
39
+ steps,
40
+ tags: {
41
+ ...journey.tags
42
+ }
43
+ };
44
+ }
45
+ /**
46
+ * @internal Rehydrate a {@link SerializedJourneyState} into a live
47
+ * {@link JourneyState} bound to the supplied runtime. `startedAt` is rebased
48
+ * from the wall-clock epoch back to a `performance.now()` monotonic stamp,
49
+ * `StepRecord[]` is rebuilt with re-linked circular references, and the
50
+ * `JOURNEY_ENGINE` hook is re-bound so HTTP attribution works on the new page.
51
+ */ export function deserializeJourneyState(serialized, config, api, defaultJourneyIdleMs) {
52
+ const tags = emptyRecord();
53
+ // Caller config tags win; serialized tags fill the rest (incl. st_journey_id).
54
+ assignRecord(tags, serialized.tags, MAX_TAG_KEYS);
55
+ assignRecord(tags, config.tags, MAX_TAG_KEYS);
56
+ if (serialized.stJourneyId && tags.st_journey_id === undefined) {
57
+ tags.st_journey_id = serialized.stJourneyId;
58
+ }
59
+ const snapshot = freezeJourneyDef(config, tags);
60
+ const timeout = resolveJourneyTimeoutMs(snapshot.timeoutMs, defaultJourneyIdleMs);
61
+ const startedAt = globalThis.performance.now() - (Date.now() - serialized.startedAtEpoch);
62
+ const journey = {
63
+ config: snapshot,
64
+ name: snapshot.name,
65
+ team: snapshot.team,
66
+ group: snapshot.group,
67
+ service: snapshot.service,
68
+ verdict: serialized.verdict === 'bad' ? 'bad' : 'good',
69
+ startedAt,
70
+ timeoutMs: timeout.ms,
71
+ timeoutExplicit: timeout.explicit,
72
+ stepTimeoutMs: snapshot.stepTimeoutMs !== undefined ? finiteTimeoutMs(snapshot.stepTimeoutMs) : undefined,
73
+ reason: serialized.reason,
74
+ steps: [],
75
+ expected: snapshot.expected ? [
76
+ ...snapshot.expected
77
+ ] : null,
78
+ tags,
79
+ slowRequestMs: finiteSlowRequestMs(snapshot.slowRequestMs),
80
+ endpoints: snapshot.endpoints,
81
+ timer: null,
82
+ closed: false,
83
+ maxSteps: snapshot.maxSteps !== undefined ? clampMaxSteps(snapshot.maxSteps) : undefined
84
+ };
85
+ // Rebuild StepRecord[] — re-link the circular `step.journey` reference and rebase `startedAt` from the offset.
86
+ for (const s of serialized.steps){
87
+ const step = {
88
+ name: s.name,
89
+ startedAt: journey.startedAt + s.startMs,
90
+ durationMs: s.durationMs,
91
+ outcome: s.outcome,
92
+ attributes: emptyRecord(),
93
+ journey
94
+ };
95
+ if (s.reason !== undefined) {
96
+ step.reason = s.reason;
97
+ }
98
+ if (s.httpStatus !== undefined) {
99
+ step.httpStatus = s.httpStatus;
100
+ }
101
+ if (s.attributes) {
102
+ assignRecord(step.attributes, s.attributes, MAX_ATTRIBUTE_KEYS);
103
+ }
104
+ journey.steps.push(step);
105
+ }
106
+ // Re-bind the engine so HTTP attribution / fail-fast works on this page.
107
+ journey[JOURNEY_ENGINE] = bindJourneyEngine(api, journey, api.shouldIgnoreRequest);
108
+ return journey;
109
+ }
110
+
111
+ //# sourceMappingURL=persist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/persist.ts"],"sourcesContent":["import {\n clampMaxSteps,\n finiteSlowRequestMs,\n finiteTimeoutMs,\n MAX_ATTRIBUTE_KEYS,\n MAX_TAG_KEYS,\n resolveJourneyTimeoutMs,\n} from './limits';\nimport { assignRecord, emptyRecord } from './sanitize';\nimport { bindJourneyEngine, freezeJourneyDef, type JourneyRuntime } from './runtime';\nimport {\n JOURNEY_ENGINE,\n type JourneyDef,\n type JourneyState,\n type SerializedJourneyState,\n type StepRecord,\n} from './types';\n\n/**\n * @internal Project an open {@link JourneyState} into a plain, JSON-safe\n * {@link SerializedJourneyState} that can ride a cookie across page navigations.\n * The step projection mirrors `finish()`; `startedAt` (a `performance.now()`\n * monotonic stamp) is bridged to a wall-clock epoch so it survives the page\n * load where `performance.now()` resets.\n */\nexport function projectJourneyState(journey: JourneyState): SerializedJourneyState {\n const steps = journey.steps.map(s => ({\n name: s.name,\n startMs: Math.round(s.startedAt - journey.startedAt),\n durationMs: s.durationMs || Math.round(globalThis.performance.now() - s.startedAt),\n outcome: s.outcome,\n ...(s.reason ? { reason: s.reason } : {}),\n ...(s.httpStatus !== undefined ? { httpStatus: s.httpStatus } : {}),\n // Attributes are raw here — final emission sanitization happens in finish().\n ...(Object.keys(s.attributes).length ? { attributes: { ...s.attributes } } : {}),\n }));\n\n const startedAtEpoch = Date.now() - (globalThis.performance.now() - journey.startedAt);\n // Coerce any non-null st_journey_id tag to a string so a numeric/boolean id survives the round-trip.\n const stJourneyId =\n journey.tags.st_journey_id != null ? String(journey.tags.st_journey_id) : '';\n\n return {\n stJourneyId,\n startedAtEpoch,\n // Open journeys are never 'excluded' — that verdict is only set inside finish().\n verdict: journey.verdict === 'bad' ? 'bad' : 'good',\n reason: journey.reason,\n steps,\n tags: { ...journey.tags },\n };\n}\n\n/**\n * @internal Rehydrate a {@link SerializedJourneyState} into a live\n * {@link JourneyState} bound to the supplied runtime. `startedAt` is rebased\n * from the wall-clock epoch back to a `performance.now()` monotonic stamp,\n * `StepRecord[]` is rebuilt with re-linked circular references, and the\n * `JOURNEY_ENGINE` hook is re-bound so HTTP attribution works on the new page.\n */\nexport function deserializeJourneyState(\n serialized: SerializedJourneyState,\n config: JourneyDef,\n api: JourneyRuntime,\n defaultJourneyIdleMs: number\n): JourneyState {\n const tags = emptyRecord();\n // Caller config tags win; serialized tags fill the rest (incl. st_journey_id).\n assignRecord(tags, serialized.tags, MAX_TAG_KEYS);\n assignRecord(tags, config.tags, MAX_TAG_KEYS);\n if (serialized.stJourneyId && tags.st_journey_id === undefined) {\n tags.st_journey_id = serialized.stJourneyId;\n }\n\n const snapshot = freezeJourneyDef(config, tags);\n const timeout = resolveJourneyTimeoutMs(snapshot.timeoutMs, defaultJourneyIdleMs);\n\n const startedAt = globalThis.performance.now() - (Date.now() - serialized.startedAtEpoch);\n\n const journey: JourneyState = {\n config: snapshot,\n name: snapshot.name,\n team: snapshot.team,\n group: snapshot.group,\n service: snapshot.service,\n verdict: serialized.verdict === 'bad' ? 'bad' : 'good',\n startedAt,\n timeoutMs: timeout.ms,\n timeoutExplicit: timeout.explicit,\n stepTimeoutMs:\n snapshot.stepTimeoutMs !== undefined\n ? finiteTimeoutMs(snapshot.stepTimeoutMs)\n : undefined,\n reason: serialized.reason,\n steps: [],\n expected: snapshot.expected ? [...snapshot.expected] : null,\n tags,\n slowRequestMs: finiteSlowRequestMs(snapshot.slowRequestMs),\n endpoints: snapshot.endpoints,\n timer: null,\n closed: false,\n maxSteps: snapshot.maxSteps !== undefined ? clampMaxSteps(snapshot.maxSteps) : undefined,\n };\n\n // Rebuild StepRecord[] — re-link the circular `step.journey` reference and rebase `startedAt` from the offset.\n for (const s of serialized.steps) {\n const step: StepRecord = {\n name: s.name,\n startedAt: journey.startedAt + s.startMs,\n durationMs: s.durationMs,\n outcome: s.outcome,\n attributes: emptyRecord(),\n journey,\n };\n if (s.reason !== undefined) {\n step.reason = s.reason;\n }\n if (s.httpStatus !== undefined) {\n step.httpStatus = s.httpStatus;\n }\n if (s.attributes) {\n assignRecord(step.attributes, s.attributes, MAX_ATTRIBUTE_KEYS);\n }\n journey.steps.push(step);\n }\n\n // Re-bind the engine so HTTP attribution / fail-fast works on this page.\n journey[JOURNEY_ENGINE] = bindJourneyEngine(api, journey, api.shouldIgnoreRequest);\n\n return journey;\n}\n"],"names":["clampMaxSteps","finiteSlowRequestMs","finiteTimeoutMs","MAX_ATTRIBUTE_KEYS","MAX_TAG_KEYS","resolveJourneyTimeoutMs","assignRecord","emptyRecord","bindJourneyEngine","freezeJourneyDef","JOURNEY_ENGINE","projectJourneyState","journey","steps","map","s","name","startMs","Math","round","startedAt","durationMs","globalThis","performance","now","outcome","reason","httpStatus","undefined","Object","keys","attributes","length","startedAtEpoch","Date","stJourneyId","tags","st_journey_id","String","verdict","deserializeJourneyState","serialized","config","api","defaultJourneyIdleMs","snapshot","timeout","timeoutMs","team","group","service","ms","timeoutExplicit","explicit","stepTimeoutMs","expected","slowRequestMs","endpoints","timer","closed","maxSteps","step","push","shouldIgnoreRequest"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type SlowRequestConfig } from './endpoint-policy';
2
2
  import type { RequestPolicyConfig } from './request-policy';
3
- import { type JourneyDef, type JourneyEngine, type JourneyEvent, type JourneySink, type JourneyState, type JourneyStepOptions, type JourneyStepTarget, type Outcome, type StepHandle, type StepRecord, type TagValue } from './types';
3
+ import { type JourneyDef, type JourneyEngine, type JourneyEvent, type JourneySink, type JourneyState, type JourneyStepOptions, type JourneyStepTarget, type Outcome, type SerializedJourneyState, type StepHandle, type StepRecord, type TagValue } from './types';
4
4
  /** @internal Private — not part of the public package API. */
5
5
  export interface JourneyRuntimeOptions {
6
6
  /**
@@ -49,6 +49,8 @@ export interface JourneyRuntimeDebugSnapshot {
49
49
  autoAttributeRequests: boolean;
50
50
  };
51
51
  }
52
+ /** @internal Freeze a caller-supplied journey def + tags snapshot. */
53
+ export declare function freezeJourneyDef(config: JourneyDef, tags: Record<string, TagValue>): JourneyDef;
52
54
  /**
53
55
  * @internal Private — not part of the public package API.
54
56
  * Isolated journey engine (open journeys, ambient steps, sinks, request thresholds).
@@ -89,6 +91,17 @@ export interface JourneyRuntime {
89
91
  completeJourneyState(journey: JourneyState, tags?: Record<string, TagValue>): void;
90
92
  excludeJourney(journey: JourneyState): void;
91
93
  updateOpenJourney(config: JourneyDef): void;
94
+ /**
95
+ * @internal Snapshot an open journey for cross-page transfer. Does NOT
96
+ * close the journey. Returns `null` when no journey is open under `name`.
97
+ */
98
+ serializeJourneyState(name: string): SerializedJourneyState | null;
99
+ /**
100
+ * @internal Rehydrate a serialized journey onto this runtime. Returns
101
+ * `null` (after emitting a `bad` `journey-timeout` event) when the journey
102
+ * already exhausted its budget in transit.
103
+ */
104
+ restoreJourney(serialized: SerializedJourneyState, config: JourneyDef): JourneyState | null;
92
105
  activeJourneyStep(): StepRecord | null;
93
106
  journeyStep<T>(journey: JourneyStepTarget, stepName: string, fn: (step: StepHandle) => T | Promise<T>, opts?: JourneyStepOptions): Promise<T>;
94
107
  journeyMountStep<T>(journey: JourneyStepTarget, stepName: string, fn: (step: StepHandle) => T | Promise<T>, opts?: JourneyStepOptions): Promise<T>;
@@ -98,6 +111,8 @@ export interface JourneyRuntime {
98
111
  /** Close open journeys, clear ambient steps, restore default timeouts/sinks. */
99
112
  reset(options?: JourneyRuntimeOptions): void;
100
113
  }
114
+ /** @internal Bind the fail/exclude/report hooks for a journey's creating engine. */
115
+ export declare function bindJourneyEngine(api: JourneyRuntime, journey: JourneyState, shouldIgnoreRequest: (target: JourneyState, key: string) => boolean): JourneyEngine;
101
116
  /**
102
117
  * @internal Private — not part of the public package API.
103
118
  * Build an isolated engine. Rarely needed — apps use the default via free helpers.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/core/runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/core/runtime.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  import { getAutoAttributeRequests as getSharedAutoAttributeRequests, getHttpAbortedRequestsPolicy as getSharedHttpAbortedRequestsPolicy, getHttpClientErrorRequestsPolicy as getSharedHttpClientErrorRequestsPolicy, getSharedSlowRequests, isJourneyDebugEnabled } from '../global';
2
2
  import { isCanceledError } from './abort-error';
3
3
  import { resolveEndpointPolicy, sortEndpointsByLongestMatch } from './endpoint-policy';
4
+ import { deserializeJourneyState, projectJourneyState } from './persist';
4
5
  import { clampMaxSteps, DEFAULT_MAX_STEPS, DEFAULT_JOURNEY_IDLE_MS, finiteSlowRequestMs, finiteTimeoutMs, MAX_ATTRIBUTED_REQUEST_KEYS, MAX_TAG_KEYS, resolveJourneyTimeoutMs } from './limits';
5
6
  import { assignRecord, emptyRecord, sanitizeJourneyEvent, setSafeAttribute } from './sanitize';
6
7
  import { JourneyStepStamp, resolveStampOpts } from './step-tag';
@@ -23,7 +24,7 @@ function toName(target) {
23
24
  }
24
25
  return 'config' in target ? target.config.name : target.name;
25
26
  }
26
- function freezeJourneyDef(config, tags) {
27
+ /** @internal Freeze a caller-supplied journey def + tags snapshot. */ export function freezeJourneyDef(config, tags) {
27
28
  const endpoints = sortEndpointsByLongestMatch(config.endpoints);
28
29
  return Object.freeze({
29
30
  ...config,
@@ -42,7 +43,7 @@ function freezeJourneyDef(config, tags) {
42
43
  })
43
44
  });
44
45
  }
45
- function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
46
+ /** @internal Bind the fail/exclude/report hooks for a journey's creating engine. */ export function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
46
47
  return {
47
48
  failJourney (reason) {
48
49
  api.failJourney(journey, reason);
@@ -281,35 +282,35 @@ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
281
282
  getSlowRequests () {
282
283
  return effectiveSlowRequests();
283
284
  },
284
- setSlowRequests (next1) {
285
+ setSlowRequests (next) {
285
286
  slowRequests = {
286
- ...next1,
287
- endpoints: sortEndpointsByLongestMatch(next1.endpoints)
287
+ ...next,
288
+ endpoints: sortEndpointsByLongestMatch(next.endpoints)
288
289
  };
289
290
  },
290
291
  getMaxSteps () {
291
292
  return maxSteps;
292
293
  },
293
- setMaxSteps (next1) {
294
- maxSteps = clampMaxSteps(next1);
294
+ setMaxSteps (next) {
295
+ maxSteps = clampMaxSteps(next);
295
296
  },
296
297
  getDefaultJourneyIdleMs () {
297
298
  return defaultJourneyIdleMs;
298
299
  },
299
- setDefaultJourneyIdleMs (next1) {
300
- defaultJourneyIdleMs = finiteTimeoutMs(next1);
300
+ setDefaultJourneyIdleMs (next) {
301
+ defaultJourneyIdleMs = finiteTimeoutMs(next);
301
302
  },
302
- setSinks (next1) {
303
+ setSinks (next) {
303
304
  sinks = [
304
- ...next1
305
+ ...next
305
306
  ];
306
307
  },
307
- trySetConfiguredSinks (next1) {
308
+ trySetConfiguredSinks (next) {
308
309
  if (sinksConfigured) {
309
310
  return false;
310
311
  }
311
312
  sinks = [
312
- ...next1
313
+ ...next
313
314
  ];
314
315
  sinksConfigured = true;
315
316
  return true;
@@ -318,10 +319,10 @@ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
318
319
  sinks.push(sink);
319
320
  },
320
321
  emit,
321
- setPolicyOverlay (next1) {
322
+ setPolicyOverlay (next) {
322
323
  overlay = {
323
324
  ...overlay,
324
- ...next1
325
+ ...next
325
326
  };
326
327
  },
327
328
  getAutoAttributeRequests () {
@@ -507,6 +508,40 @@ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
507
508
  }
508
509
  armCountdown(journey, remainingMs);
509
510
  },
511
+ serializeJourneyState (name) {
512
+ const journey = journeys.get(name);
513
+ if (!journey || journey.closed) {
514
+ return null;
515
+ }
516
+ return projectJourneyState(journey);
517
+ },
518
+ restoreJourney (serialized, config) {
519
+ // Refuse double-registration: leave an existing journey under this name in place.
520
+ if (journeys.has(config.name)) {
521
+ return null;
522
+ }
523
+ const journey = deserializeJourneyState(serialized, config, api, defaultJourneyIdleMs);
524
+ if (journey.timeoutMs > 0) {
525
+ const elapsedMs = globalThis.performance.now() - journey.startedAt;
526
+ if (elapsedMs >= journey.timeoutMs) {
527
+ // journey not yet in journeys Map — finish() handles unregistered journeys gracefully.
528
+ if (journey.timeoutExplicit) {
529
+ finish(journey, 'bad', 'journey-timeout');
530
+ } else {
531
+ finish(journey, journey.verdict === 'bad' ? 'bad' : 'excluded', 'journey-idle-timeout');
532
+ }
533
+ return null;
534
+ }
535
+ journeys.set(config.name, journey);
536
+ const remainingMs = journey.timeoutMs - elapsedMs;
537
+ if (remainingMs > 0) {
538
+ armCountdown(journey, remainingMs);
539
+ }
540
+ } else {
541
+ journeys.set(config.name, journey);
542
+ }
543
+ return journey;
544
+ },
510
545
  activeJourneyStep () {
511
546
  var _inFlight_values_next_value;
512
547
  if (!api.getAutoAttributeRequests()) {
@@ -617,7 +652,7 @@ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
617
652
  }
618
653
  api.failJourney(journey, category);
619
654
  },
620
- reset (next1 = {}) {
655
+ reset (next = {}) {
621
656
  var _next_sinks, _ref, _ref1, _next_defaultJourneyIdleMs;
622
657
  var _next_slowRequests, _next_slowRequests1;
623
658
  for (const journey of [
@@ -631,14 +666,14 @@ function bindJourneyEngine(api, journey, shouldIgnoreRequest) {
631
666
  overlay = {};
632
667
  sinksConfigured = false;
633
668
  sinks = [
634
- ...(_next_sinks = next1.sinks) !== null && _next_sinks !== void 0 ? _next_sinks : []
669
+ ...(_next_sinks = next.sinks) !== null && _next_sinks !== void 0 ? _next_sinks : []
635
670
  ];
636
671
  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)
672
+ defaultMs: (_ref = (_next_slowRequests = next.slowRequests) === null || _next_slowRequests === void 0 ? void 0 : _next_slowRequests.defaultMs) !== null && _ref !== void 0 ? _ref : DEFAULT_SLOW_REQUESTS.defaultMs,
673
+ endpoints: sortEndpointsByLongestMatch((_ref1 = (_next_slowRequests1 = next.slowRequests) === null || _next_slowRequests1 === void 0 ? void 0 : _next_slowRequests1.endpoints) !== null && _ref1 !== void 0 ? _ref1 : DEFAULT_SLOW_REQUESTS.endpoints)
639
674
  };
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);
675
+ maxSteps = next.maxSteps !== undefined ? clampMaxSteps(next.maxSteps) : DEFAULT_MAX_STEPS;
676
+ defaultJourneyIdleMs = finiteTimeoutMs((_next_defaultJourneyIdleMs = next.defaultJourneyIdleMs) !== null && _next_defaultJourneyIdleMs !== void 0 ? _next_defaultJourneyIdleMs : DEFAULT_JOURNEY_IDLE_MS);
642
677
  }
643
678
  };
644
679
  return api;