stitchkit 0.112.1 → 0.112.2

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
@@ -15,6 +15,12 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.112.2] - 2026-10-25
19
+
20
+ ### Added
21
+
22
+ - `stitchkit/tracking` — `resolveTrackedClick` and `createTrackingClient` accept `hrefPolicy: 'full'` to retain internal and outbound click query parameters and fragments before consumer `decorate` redaction. The default `path-only` policy, navigation classification, labels and listener cleanup stay unchanged; URL credentials remain excluded.
23
+
18
24
  ## [0.112.1] - 2026-10-25
19
25
 
20
26
  ### Fixed
@@ -204,17 +204,18 @@ function sendUnloadBeacon(url, body, sender = typeof navigator === "undefined" ?
204
204
  function label(target) {
205
205
  return (target?.textContent ?? "").trim().slice(0, 100) || undefined;
206
206
  }
207
- function sanitizedHref(value, origin) {
207
+ function trackedHref(value, origin, policy) {
208
208
  if (!value)
209
209
  return;
210
210
  try {
211
211
  const url = new URL(value, origin);
212
- return url.origin === origin ? url.pathname : `${url.origin}${url.pathname}`;
212
+ const path = `${url.pathname}${policy === "full" ? url.search + url.hash : ""}`;
213
+ return url.origin === origin ? path : `${url.origin}${path}`;
213
214
  } catch {
214
215
  return;
215
216
  }
216
217
  }
217
- function resolveTrackedClick(target, { origin, attributes = {}, isAction = () => true }) {
218
+ function resolveTrackedClick(target, { origin, attributes = {}, isAction = () => true, hrefPolicy }) {
218
219
  if (!target)
219
220
  return null;
220
221
  const trackAttribute = attributes.track ?? "data-track";
@@ -247,12 +248,15 @@ function resolveTrackedClick(target, { origin, attributes = {}, isAction = () =>
247
248
  result.click = {
248
249
  element,
249
250
  elementText: label(tracked),
250
- href: sanitizedHref(href, origin)
251
+ href: trackedHref(href, origin, hrefPolicy)
251
252
  };
252
253
  }
253
254
  }
254
255
  if (outbound && href) {
255
- result.outbound = { href: sanitizedHref(href, origin) ?? href, label: label(anchor) };
256
+ result.outbound = {
257
+ href: trackedHref(href, origin, hrefPolicy) ?? href,
258
+ label: label(anchor)
259
+ };
256
260
  }
257
261
  return result.interaction || result.click || result.outbound ? result : null;
258
262
  }
@@ -299,7 +303,8 @@ function wireTrackingListeners(deps) {
299
303
  const click = resolveTrackedClick(target, {
300
304
  origin: host.page().origin,
301
305
  attributes: deps.clickAttributes,
302
- isAction: deps.isAction
306
+ isAction: deps.isAction,
307
+ hrefPolicy: deps.hrefPolicy
303
308
  });
304
309
  if (!click)
305
310
  return;
@@ -789,6 +794,7 @@ function createTrackingClient(config) {
789
794
  });
790
795
  },
791
796
  clickAttributes: config.clickAttributes,
797
+ hrefPolicy: config.hrefPolicy,
792
798
  isAction: config.isAction
793
799
  });
794
800
  return () => {
@@ -24,6 +24,8 @@ export interface ResolveTrackedClickOptions {
24
24
  attributes?: TrackedClickAttributes;
25
25
  /** Whether an action name is one the application knows. Default: any. */
26
26
  isAction?: (action: string) => boolean;
27
+ /** Click URLs omit query/fragment by default. `full` retains both for consumer redaction. */
28
+ hrefPolicy?: 'path-only' | 'full';
27
29
  }
28
30
  export interface TrackedClick {
29
31
  interaction?: {
@@ -42,5 +44,5 @@ export interface TrackedClick {
42
44
  /** The click navigates away — send its facts on the unload path. */
43
45
  leavesPage: boolean;
44
46
  }
45
- export declare function resolveTrackedClick(target: ClickTarget | null, { origin, attributes, isAction }: ResolveTrackedClickOptions): TrackedClick | null;
47
+ export declare function resolveTrackedClick(target: ClickTarget | null, { origin, attributes, isAction, hrefPolicy }: ResolveTrackedClickOptions): TrackedClick | null;
46
48
  //# sourceMappingURL=clicks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"clicks.d.ts","sourceRoot":"","sources":["../../src/tracking/clicks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAC9C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;CACrB;AAgBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,EAAE,MAAM,EAAE,UAAe,EAAE,QAAqB,EAAE,EAAE,0BAA0B,GAC7E,YAAY,GAAG,IAAI,CA0CrB"}
1
+ {"version":3,"file":"clicks.d.ts","sourceRoot":"","sources":["../../src/tracking/clicks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4EAA4E;AAC5E,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;IAC9C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,6FAA6F;IAC7F,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACjE,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,oEAAoE;IACpE,UAAU,EAAE,OAAO,CAAC;CACrB;AAqBD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,EAAE,MAAM,EAAE,UAAe,EAAE,QAAqB,EAAE,UAAU,EAAE,EAAE,0BAA0B,GACzF,YAAY,GAAG,IAAI,CA6CrB"}
@@ -25,6 +25,7 @@ export interface TrackingListenerDeps<TType extends string> {
25
25
  releaseLease(): void;
26
26
  readonly clickAttributes: Parameters<typeof resolveTrackedClick>[1]['attributes'];
27
27
  readonly isAction: Parameters<typeof resolveTrackedClick>[1]['isAction'];
28
+ readonly hrefPolicy: Parameters<typeof resolveTrackedClick>[1]['hrefPolicy'];
28
29
  }
29
30
  export declare function wireTrackingListeners<TType extends string>(deps: TrackingListenerDeps<TType>): Array<() => void>;
30
31
  //# sourceMappingURL=client-listeners.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client-listeners.d.ts","sourceRoot":"","sources":["../../src/tracking/client-listeners.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,MAAM;IACxD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC1D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACxC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,IAAI,CAAC;IACrB,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAClF,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;CAC1E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,MAAM,EACxD,IAAI,EAAE,oBAAoB,CAAC,KAAK,CAAC,GAChC,KAAK,CAAC,MAAM,IAAI,CAAC,CAsEnB"}
1
+ {"version":3,"file":"client-listeners.d.ts","sourceRoot":"","sources":["../../src/tracking/client-listeners.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,WAAW,oBAAoB,CAAC,KAAK,SAAS,MAAM;IACxD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC1D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC;IACnC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;IACxC,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/B,WAAW,IAAI,MAAM,CAAC;IACtB,YAAY,IAAI,IAAI,CAAC;IACrB,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAClF,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACzE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;CAC9E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,SAAS,MAAM,EACxD,IAAI,EAAE,oBAAoB,CAAC,KAAK,CAAC,GAChC,KAAK,CAAC,MAAM,IAAI,CAAC,CAuEnB"}
@@ -12,7 +12,7 @@
12
12
  * session. → ADR 0166.
13
13
  */
14
14
  import type { ReferrerRule, ResolvedAttribution } from './attribution.js';
15
- import type { TrackedClickAttributes } from './clicks.js';
15
+ import type { ResolveTrackedClickOptions, TrackedClickAttributes } from './clicks.js';
16
16
  import type { TrackingHost } from './host.js';
17
17
  import type { TrackingOutbox } from './outbox.js';
18
18
  import type { TrackEventsRequest, TrackEventsResponse, TrackingEventEnvelope, VisitBootstrapResponse, VisitEntryContext } from './schemas.js';
@@ -88,6 +88,8 @@ export interface TrackingClientConfig<TMetadata extends object, TEvent extends T
88
88
  isAction?: (action: string) => boolean;
89
89
  referrerMap?: readonly ReferrerRule[];
90
90
  clickAttributes?: TrackedClickAttributes;
91
+ /** Click URL retention before `decorate`. Default `path-only`; `full` includes query/fragment. */
92
+ hrefPolicy?: ResolveTrackedClickOptions['hrefPolicy'];
91
93
  scrollMilestones?: readonly number[];
92
94
  /** Heartbeat and flush period. Default 30 s. */
93
95
  heartbeatMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/tracking/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/tracking/client.ts"],"names":[],"mappings":"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"}
package/llms/tracking.txt CHANGED
@@ -100,6 +100,24 @@ createTrackingClient<BrowserEvents, TrackingEventEnvelope<keyof BrowserEvents> &
100
100
  })
101
101
  ```
102
102
 
103
+ ### Click URL retention
104
+
105
+ `resolveTrackedClick(target, { origin, hrefPolicy: 'full' })` and
106
+ `createTrackingClient({ …, hrefPolicy: 'full' })` retain the clicked URL's pathname,
107
+ query and fragment. Internal URLs are relative (`/item?offer=one#details`);
108
+ outbound URLs include their origin (`https://other.example/item?offer=one#details`).
109
+ URL credentials are excluded. Omitting the option, or selecting `path-only`,
110
+ keeps the default that omits query and fragment. Navigation classification,
111
+ labels and subscriptions are independent of this policy.
112
+
113
+ Full URLs may contain sensitive values. Supply your application's password and
114
+ secret redactor through `decorate` before enabling `full`: it receives the retained
115
+ `event.metadata.href` and must return the redacted metadata. The returned event is
116
+ what the outbox, synchronous unload and normal delivery receive. The framework
117
+ has no application-specific password policy. This option controls click and
118
+ outbound-click metadata; it does not change attribution, page tracking or interaction
119
+ metadata. Use the same redactor on your other ingestion paths.
120
+
103
121
  A `bootstrap` operation that needs extra fields of its own (a locale, a RUM
104
122
  flag) is not the factory's: build the `entry` schema with
105
123
  `createTrackingSchemas(…).entry.extend({ … })` and declare that endpoint yourself.
@@ -234,7 +252,7 @@ application's — it owns the router and the session. The server half is
234
252
  | Export | Kind | Summary |
235
253
  |--------|------|---------|
236
254
  | `createTrackingClient` | function | the client: visit lease and renewal, pending queue, synchronous identity from reserved sequences, outbox and flush lease, delivery, the string-body page-leave beacon plus a queued copy, visible time, scroll milestones, declarative clicks, heartbeats |
237
- | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `referrerMap`, `clickAttributes`, `scrollMilestones`, `batchSize`, periods and limits |
255
+ | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `referrerMap`, `clickAttributes`, `hrefPolicy` (`path-only` by default; `full` retains click query/fragment before `decorate`), `scrollMilestones`, `batchSize`, periods and limits |
238
256
  | `TrackFn` / `EventsWithMetadata` / `EventsWithoutMetadata` | _type_ | `track(type)` / `track(type, metadata)` typed by the application's metadata map, and the two halves of that map |
239
257
  | `BuiltinTrackingEventTypes` / `CONVENTIONAL_TRACKING_EVENT_TYPES` | _type_ / const | the application's names for the events the client emits itself; the conventional `PAGE_VIEW` … `INTERACTION` set |
240
258
  | `browserTrackingHost` / `TrackingHost` / `TrackingPageContext` | function / _type_ | everything the client takes from a browser tab behind one interface — page context, visibility, scroll depth, events, intervals, clocks, storage — so a test or a non-tab host can supply its own |
@@ -258,6 +276,6 @@ application's — it owns the router and the session. The server half is
258
276
  | `createOncePerPage` / `OncePerPage` | function / _type_ | one fact per key per page within a window — the guard a twice-mounted component cannot keep itself |
259
277
  | `resolveAttribution` / `ResolveAttributionInput` / `ResolvedAttribution` / `AttributionStorage` / `ReferrerRule` | function / _type_ | first-touch once, current-touch on every new UTM; the referrer → source/medium map is the application's, there is no built-in list |
260
278
  | `parseUtmFromSearch` / `parseReferrer` | function | the two parsers `resolveAttribution` is built from |
261
- | `resolveTrackedClick` / `ResolveTrackedClickOptions` / `TrackedClick` / `TrackedClickAttributes` / `ClickTarget` | function / _type_ | `data-track` → click, `data-track-action` → interaction, a link to another origin → outbound; attribute names configurable; `leavesPage` says which path to send on |
279
+ | `resolveTrackedClick` / `ResolveTrackedClickOptions` / `TrackedClick` / `TrackedClickAttributes` / `ClickTarget` | function / _type_ | `data-track` → click, `data-track-action` → interaction, a link to another origin → outbound; attribute names configurable; `hrefPolicy: 'full'` retains query/fragment (default `path-only` omits them), URL credentials excluded; `leavesPage` says which path to send on |
262
280
 
263
281
  ---
package/llms-full.txt CHANGED
@@ -511,6 +511,24 @@ createTrackingClient<BrowserEvents, TrackingEventEnvelope<keyof BrowserEvents> &
511
511
  })
512
512
  ```
513
513
 
514
+ ### Click URL retention
515
+
516
+ `resolveTrackedClick(target, { origin, hrefPolicy: 'full' })` and
517
+ `createTrackingClient({ …, hrefPolicy: 'full' })` retain the clicked URL's pathname,
518
+ query and fragment. Internal URLs are relative (`/item?offer=one#details`);
519
+ outbound URLs include their origin (`https://other.example/item?offer=one#details`).
520
+ URL credentials are excluded. Omitting the option, or selecting `path-only`,
521
+ keeps the default that omits query and fragment. Navigation classification,
522
+ labels and subscriptions are independent of this policy.
523
+
524
+ Full URLs may contain sensitive values. Supply your application's password and
525
+ secret redactor through `decorate` before enabling `full`: it receives the retained
526
+ `event.metadata.href` and must return the redacted metadata. The returned event is
527
+ what the outbox, synchronous unload and normal delivery receive. The framework
528
+ has no application-specific password policy. This option controls click and
529
+ outbound-click metadata; it does not change attribution, page tracking or interaction
530
+ metadata. Use the same redactor on your other ingestion paths.
531
+
514
532
  A `bootstrap` operation that needs extra fields of its own (a locale, a RUM
515
533
  flag) is not the factory's: build the `entry` schema with
516
534
  `createTrackingSchemas(…).entry.extend({ … })` and declare that endpoint yourself.
@@ -23280,7 +23298,7 @@ application's — it owns the router and the session. The server half is
23280
23298
  | Export | Kind | Summary |
23281
23299
  |--------|------|---------|
23282
23300
  | `createTrackingClient` | function | the client: visit lease and renewal, pending queue, synchronous identity from reserved sequences, outbox and flush lease, delivery, the string-body page-leave beacon plus a queued copy, visible time, scroll milestones, declarative clicks, heartbeats |
23283
- | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `referrerMap`, `clickAttributes`, `scrollMilestones`, `batchSize`, periods and limits |
23301
+ | `TrackingClient` / `TrackingClientConfig` | _type_ | `track` / `onNavigate` / `start` / `visitId` / `browserStreamId` / `attribution`, and the host, `buildId`, `builtin` names, `bootstrap`, `deliver`, optional `decorate` (your `eventExtras` on every minted event), `unload` / `unloadUrl`, `outbox`, `onUnauthorized`, `onVisit`, `onFailure`, `isAction`, `referrerMap`, `clickAttributes`, `hrefPolicy` (`path-only` by default; `full` retains click query/fragment before `decorate`), `scrollMilestones`, `batchSize`, periods and limits |
23284
23302
  | `TrackFn` / `EventsWithMetadata` / `EventsWithoutMetadata` | _type_ | `track(type)` / `track(type, metadata)` typed by the application's metadata map, and the two halves of that map |
23285
23303
  | `BuiltinTrackingEventTypes` / `CONVENTIONAL_TRACKING_EVENT_TYPES` | _type_ / const | the application's names for the events the client emits itself; the conventional `PAGE_VIEW` … `INTERACTION` set |
23286
23304
  | `browserTrackingHost` / `TrackingHost` / `TrackingPageContext` | function / _type_ | everything the client takes from a browser tab behind one interface — page context, visibility, scroll depth, events, intervals, clocks, storage — so a test or a non-tab host can supply its own |
@@ -23304,7 +23322,7 @@ application's — it owns the router and the session. The server half is
23304
23322
  | `createOncePerPage` / `OncePerPage` | function / _type_ | one fact per key per page within a window — the guard a twice-mounted component cannot keep itself |
23305
23323
  | `resolveAttribution` / `ResolveAttributionInput` / `ResolvedAttribution` / `AttributionStorage` / `ReferrerRule` | function / _type_ | first-touch once, current-touch on every new UTM; the referrer → source/medium map is the application's, there is no built-in list |
23306
23324
  | `parseUtmFromSearch` / `parseReferrer` | function | the two parsers `resolveAttribution` is built from |
23307
- | `resolveTrackedClick` / `ResolveTrackedClickOptions` / `TrackedClick` / `TrackedClickAttributes` / `ClickTarget` | function / _type_ | `data-track` → click, `data-track-action` → interaction, a link to another origin → outbound; attribute names configurable; `leavesPage` says which path to send on |
23325
+ | `resolveTrackedClick` / `ResolveTrackedClickOptions` / `TrackedClick` / `TrackedClickAttributes` / `ClickTarget` | function / _type_ | `data-track` → click, `data-track-action` → interaction, a link to another origin → outbound; attribute names configurable; `hrefPolicy: 'full'` retains query/fragment (default `path-only` omits them), URL credentials excluded; `leavesPage` says which path to send on |
23308
23326
 
23309
23327
  ---
23310
23328
 
package/llms.txt CHANGED
@@ -45,7 +45,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
45
45
  - **stitchkit/telegram**: [llms/telegram.txt](llms/telegram.txt) 36.6 KB
46
46
  - **stitchkit/telegram/html**: [llms/telegram-html.txt](llms/telegram-html.txt) 2.7 KB
47
47
  - **stitchkit/telegram/screens**: [llms/telegram-screens.txt](llms/telegram-screens.txt) 21.2 KB
48
- - **stitchkit/tracking**: [llms/tracking.txt](llms/tracking.txt) 16.8 KB
48
+ - **stitchkit/tracking**: [llms/tracking.txt](llms/tracking.txt) 18.1 KB
49
49
  - **stitchkit/release**: [llms/release.txt](llms/release.txt) 8.9 KB
50
50
  - **stitchkit/tracking/server**: [llms/tracking-server.txt](llms/tracking-server.txt) 2.5 KB
51
51
  - **stitchkit/geo**: [llms/geo.txt](llms/geo.txt) 4.1 KB
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.112.1",
3
+ "version": "0.112.2",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",