@corbado/observe 1.12.1 → 1.14.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @corbado/observe
2
2
 
3
+ ## 1.14.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8f563e2: New tracker plugin `eventTime(stamp)` for `initCore`: every tracked event is dated by the integration's clock, `stamp(explicitTimestamp)`, instead of `explicitTimestamp ?? Date.now()`, also for SDK methods that take no timestamp (`flowStarted`, `flowFinished`, decisions, an operation's `subflow_started`). For integrations that replay host signals late (e.g. from a host-side event buffer). A clock that throws or returns a non-finite number falls back to the SDK's own dating; telemetry and low events keep their capture time. `init()` / `CorbadoTracker` are unchanged.
8
+
9
+ ## 1.13.0
10
+
11
+ ### Minor Changes
12
+
13
+ - e0c70aa: New tracker plugin `fixedSourcePath(policy)` for `initCore`: the batch source path (`meta.trackingSourcePath`) comes from the integration's policy (e.g. `pageSourcePath(PAGES)` of `@corbado/autocapture`) instead of the server-driven `sourcePathQuery` config, so it can be declared in the integration's collection manifest. A failing policy sends the fully masked path. `init()` / `CorbadoTracker` are unchanged.
14
+
3
15
  ## 1.12.1
4
16
 
5
17
  ### Patch Changes
@@ -11,6 +11,8 @@ export * from "./plugins/cookie-storage.mjs";
11
11
  export * from "./plugins/cross-origin-session.mjs";
12
12
  export * from "./plugins/raw-errors.mjs";
13
13
  export * from "./plugins/probes.mjs";
14
+ export * from "./plugins/fixed-source-path.mjs";
15
+ export * from "./plugins/event-time.mjs";
14
16
  export * from "./probe-lane.mjs";
15
17
  export * from "./transport.mjs";
16
18
  export * from "./queue.mjs";
@@ -0,0 +1,18 @@
1
+ // src/plugins/event-time.ts
2
+ function eventTime(stamp) {
3
+ if (typeof stamp !== "function") return {};
4
+ return {
5
+ // Guarded here, not in the tracker: the core only pays for the hook call.
6
+ eventTime: (explicitTimestamp) => {
7
+ try {
8
+ const stamped = stamp(explicitTimestamp);
9
+ return typeof stamped === "number" && Number.isFinite(stamped) ? stamped : void 0;
10
+ } catch {
11
+ return void 0;
12
+ }
13
+ }
14
+ };
15
+ }
16
+ export {
17
+ eventTime
18
+ };
@@ -0,0 +1,47 @@
1
+ // src/plugins/fixed-source-path.ts
2
+ import { readLocationPath } from "../readers/page.mjs";
3
+ var MAX_SOURCE_PATH = 2048;
4
+ function maskedSourcePath(path) {
5
+ const segments = String(path ?? "").split("/").filter((segment) => segment !== "");
6
+ return segments.length === 0 ? "/" : "/" + segments.map(() => "*").join("/");
7
+ }
8
+ function fixedSourcePath(policy) {
9
+ if (typeof policy !== "function") return {};
10
+ return {
11
+ sourcePath: () => {
12
+ const { path, search } = readLocationPath({
13
+ key: "page:location.fixed-source-path",
14
+ title: "Page path and declared parameters",
15
+ accessNote: "location.pathname and location.search, reduced by the integration's declared page templates and parameters (trackingSourcePath); everything else is masked",
16
+ group: "Page",
17
+ origin: "observe-external",
18
+ fields: [
19
+ {
20
+ path: "url.path",
21
+ label: "Page path (declared parts only)",
22
+ category: "technical",
23
+ exposure: "partial",
24
+ transform: { note: "declared page templates and path parameters; other segments become '*'" }
25
+ },
26
+ {
27
+ path: "url.query",
28
+ label: "Page address parameters (declared ones only)",
29
+ category: "technical",
30
+ exposure: "redacted",
31
+ transform: { note: "declared parameters as their declared reduction; other values become '*'" }
32
+ }
33
+ ]
34
+ });
35
+ try {
36
+ const out = policy(path, search);
37
+ return typeof out === "string" ? out.slice(0, MAX_SOURCE_PATH) : maskedSourcePath(path);
38
+ } catch {
39
+ return maskedSourcePath(path);
40
+ }
41
+ }
42
+ };
43
+ }
44
+ export {
45
+ fixedSourcePath,
46
+ maskedSourcePath
47
+ };
@@ -21,6 +21,9 @@ function readSourcePath(_meta, mode, allow) {
21
21
  const search = applySourcePathQuery(window.location.search, mode, allow);
22
22
  return `${window.location.pathname}${search}`;
23
23
  }
24
+ function readLocationPath(_meta) {
25
+ return { path: window.location.pathname, search: window.location.search };
26
+ }
24
27
  function readCookieScope(_meta) {
25
28
  return { hostname: window.location.hostname, https: window.location.protocol === "https:" };
26
29
  }
@@ -29,6 +32,7 @@ export {
29
32
  readCookieScope,
30
33
  readDocumentComplete,
31
34
  readDocumentHidden,
35
+ readLocationPath,
32
36
  readPageUrl,
33
37
  readSourcePath
34
38
  };
@@ -132,6 +132,8 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
132
132
  this.eachPlugin(installed, (plugin) => {
133
133
  if (plugin.session) this.bridge = plugin.session(this) || this.bridge;
134
134
  if (plugin.rawErrors) this.rawErrors = plugin.rawErrors;
135
+ if (typeof plugin.sourcePath === "function") this.fixedSourcePath = plugin.sourcePath;
136
+ if (plugin.eventTime) this.eventClock = plugin.eventTime;
135
137
  });
136
138
  if (options.fixedDataConfig?.crossOriginSession && !this.bridge) {
137
139
  this.logger.warn("fixedDataConfig.crossOriginSession is ignored without the crossOriginSession() plugin");
@@ -270,6 +272,10 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
270
272
  bridge;
271
273
  /** Raw-error serializer of a plugin; undefined = operation step errors drop `rawError`. */
272
274
  rawErrors;
275
+ /** Fixed source path of a plugin; undefined = the server-driven `sourcePathQuery` policy. */
276
+ fixedSourcePath;
277
+ /** Event clock of a plugin (never throws); undefined or an undefined result = `explicitTimestamp ?? Date.now()`. */
278
+ eventClock;
273
279
  /** @internal Shared passive page observation and per-operation context registration. */
274
280
  getWindowObserver() {
275
281
  return this.windowObserver ??= new SharedWindowObserver(
@@ -719,6 +725,14 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
719
725
  if (typeof window === "undefined") {
720
726
  return void 0;
721
727
  }
728
+ if (this.fixedSourcePath) {
729
+ try {
730
+ const path = this.fixedSourcePath();
731
+ return typeof path === "string" ? path : void 0;
732
+ } catch {
733
+ return void 0;
734
+ }
735
+ }
722
736
  return readSourcePath(
723
737
  {
724
738
  key: "page:location.source-path",
@@ -880,7 +894,7 @@ var CorbadoTrackerCore = class _CorbadoTrackerCore {
880
894
  if (name === AuthEventName.FlowFinished || name === AuthEventName.FlowAutoFinished || name === AuthEventName.FlowReset) {
881
895
  this.windowObserver?.flushInputs();
882
896
  }
883
- const timestamp = explicitTimestamp ?? Date.now();
897
+ const timestamp = this.eventClock?.(explicitTimestamp) ?? explicitTimestamp ?? Date.now();
884
898
  const capturedId = capture?.id ?? uuidv7();
885
899
  const capturedSessionId = capture?.sessionId ?? this.sessionId;
886
900
  const nextSeq = this.nextSeq();
@@ -1,6 +1,6 @@
1
1
  // src/version.ts
2
2
  var SDK_NAME = "@corbado/observe";
3
- var SDK_VERSION = true ? "1.12.1" : "0.0.0-dev";
3
+ var SDK_VERSION = true ? "1.14.0" : "0.0.0-dev";
4
4
  export {
5
5
  SDK_NAME,
6
6
  SDK_VERSION