@newtalaria/browser 0.1.15 → 0.1.16

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.
@@ -8,7 +8,12 @@ export type Teardown = () => void;
8
8
  export declare function installVisibilityResumeHook(onResume: () => void): Teardown;
9
9
  export interface NetworkMeta {
10
10
  method: string;
11
+ /** Sanitized request URL (origin + pathname; query stripped by default). */
11
12
  url: string;
13
+ hostname?: string;
14
+ pathname?: string;
15
+ /** Only when `includeNetworkUrlQuery` is enabled. */
16
+ search?: string;
12
17
  status?: number;
13
18
  durationMs?: number;
14
19
  ok?: boolean;
@@ -37,6 +42,11 @@ export interface NetworkHookOptions {
37
42
  captureFailedRequests?: boolean;
38
43
  /** Promote CORS/offline/DNS fetch failures (default `true`). */
39
44
  captureNetworkErrors?: boolean;
45
+ /**
46
+ * Keep URL query strings in network telemetry (after sensitive-key redaction).
47
+ * Default `false` — GA/ads URLs often carry cid/sid/dl identifiers.
48
+ */
49
+ includeNetworkUrlQuery?: boolean;
40
50
  failedRequestStatusCodes?: FailedRequestStatusCode[];
41
51
  failedRequestIgnoreUrls?: string[];
42
52
  /** SDK base URL — requests under this host + /events|/replays are never promoted. */
@@ -66,6 +76,8 @@ export declare function shouldPromoteNetworkError(meta: NetworkMeta, opts: {
66
76
  talariaBaseUrl?: string;
67
77
  }): boolean;
68
78
  export declare function enrichNetworkMeta(meta: NetworkMeta): NetworkMeta;
79
+ /** Apply privacy sanitization to a raw request URL for network meta. */
80
+ export declare function networkUrlParts(rawUrl: string, includeQuery: boolean): Pick<NetworkMeta, 'url' | 'hostname' | 'pathname' | 'search'>;
69
81
  /** Capture fetch / XHR metadata (no bodies, no auth headers); optionally promote failures. */
70
82
  export declare function installNetworkHook(options?: NetworkHookOptions): Teardown;
71
83
  //# sourceMappingURL=hooks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/replay/hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAG3D,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAElC;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,QAAQ,CA4B1E;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACnE;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,gEAAgE;IAChE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,wBAAwB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACrD,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAwCD,2EAA2E;AAC3E,wBAAgB,kBAAkB,IAAI,QAAQ,CA8B7C;AAcD,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,uBAAuB,EAAE,GAC/B,OAAO,CAUT;AAED,+DAA+D;AAC/D,wBAAgB,4BAA4B,CAC1C,uBAAuB,EAAE,MAAM,EAAE,EACjC,cAAc,CAAC,EAAE,MAAM,GACtB,MAAM,EAAE,CASV;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAM/E;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE;IACJ,qBAAqB,EAAE,OAAO,CAAC;IAC/B,wBAAwB,EAAE,uBAAuB,EAAE,CAAC;IACpD,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,IAAI,IAAI,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAc1C;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,WAAW,EACjB,IAAI,EAAE;IACJ,oBAAoB,EAAE,OAAO,CAAC;IAC9B,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,GACA,OAAO,CAYT;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAqBhE;AAED,8FAA8F;AAC9F,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,kBAAuB,GAAG,QAAQ,CAwH7E"}
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/replay/hooks.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,21 @@
1
- /** Redact sensitive query params from a URL for network breadcrumbs. */
1
+ /** Redact sensitive query params from a URL (keeps other query keys). */
2
2
  export declare function redactUrl(raw: string): string;
3
+ export interface SanitizedNetworkUrl {
4
+ /** Safe URL for telemetry: origin + pathname (no query/hash by default). */
5
+ url: string;
6
+ hostname: string;
7
+ pathname: string;
8
+ /** Present only when query capture is opted in (after sensitive-key redaction). */
9
+ search?: string;
10
+ }
11
+ /**
12
+ * Sanitize a request URL for network breadcrumbs / failure events.
13
+ * Default: drop query string and fragment (GA/ads URLs carry session ids).
14
+ * Opt-in `includeQuery` keeps search after `redactUrl` filtering.
15
+ */
16
+ export declare function sanitizeNetworkUrl(raw: string, opts?: {
17
+ includeQuery?: boolean;
18
+ baseHref?: string;
19
+ }): SanitizedNetworkUrl;
3
20
  export declare function defaultBlockSelector(extra?: string): string;
4
21
  //# sourceMappingURL=privacy.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/replay/privacy.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAU3D"}
1
+ {"version":3,"file":"privacy.d.ts","sourceRoot":"","sources":["../../src/replay/privacy.ts"],"names":[],"mappings":"AAEA,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY7C;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,mBAAmB,CAsCrB;AAED,wBAAgB,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAU3D"}
@@ -1,4 +1,4 @@
1
1
  /** Bumped with package.json version for event metadata. */
2
2
  export declare const SDK_NAME = "@newtalaria/browser";
3
- export declare const SDK_VERSION = "0.1.15";
3
+ export declare const SDK_VERSION = "0.1.16";
4
4
  //# sourceMappingURL=sdk_meta.d.ts.map
@@ -228,7 +228,7 @@
228
228
 
229
229
  // src/sdk_meta.ts
230
230
  var SDK_NAME = "@newtalaria/browser";
231
- var SDK_VERSION = "0.1.15";
231
+ var SDK_VERSION = "0.1.16";
232
232
 
233
233
  // src/transport/serverpod.ts
234
234
  var ServerpodTransport = class {
@@ -13452,6 +13452,40 @@
13452
13452
  return raw.replace(SENSITIVE_QUERY, (_m, name) => `${name}=[Filtered]`);
13453
13453
  }
13454
13454
  }
13455
+ function sanitizeNetworkUrl(raw, opts) {
13456
+ const baseHref = opts?.baseHref ?? (typeof location !== "undefined" ? location.href : void 0);
13457
+ try {
13458
+ const parsed = new URL(raw, baseHref);
13459
+ const hostname = parsed.hostname;
13460
+ const pathname = parsed.pathname || "/";
13461
+ const originPath = `${parsed.origin}${pathname}`;
13462
+ if (!opts?.includeQuery) {
13463
+ return { url: originPath, hostname, pathname };
13464
+ }
13465
+ const redacted = new URL(redactUrl(parsed.toString()));
13466
+ const search = redacted.search || void 0;
13467
+ return {
13468
+ url: search ? `${originPath}${search}` : originPath,
13469
+ hostname,
13470
+ pathname,
13471
+ ...search ? { search } : {}
13472
+ };
13473
+ } catch {
13474
+ const stripped = (raw.split(/[?#]/)[0] ?? raw).trim() || raw;
13475
+ if (!opts?.includeQuery) {
13476
+ return { url: stripped, hostname: "", pathname: stripped };
13477
+ }
13478
+ const redacted = redactUrl(raw);
13479
+ const qIndex = redacted.indexOf("?");
13480
+ const search = qIndex >= 0 ? redacted.slice(qIndex) : void 0;
13481
+ return {
13482
+ url: redacted.split("#")[0] || redacted,
13483
+ hostname: "",
13484
+ pathname: stripped,
13485
+ ...search ? { search } : {}
13486
+ };
13487
+ }
13488
+ }
13455
13489
  function defaultBlockSelector(extra) {
13456
13490
  const parts = [
13457
13491
  "[data-talaria-mask]",
@@ -13627,7 +13661,6 @@
13627
13661
  try {
13628
13662
  record.addCustomEvent("talaria-network", {
13629
13663
  ...meta,
13630
- url: redactUrl(meta.url),
13631
13664
  timestamp: Date.now()
13632
13665
  });
13633
13666
  } catch {
@@ -13699,6 +13732,15 @@
13699
13732
  }
13700
13733
  return meta;
13701
13734
  }
13735
+ function networkUrlParts(rawUrl, includeQuery) {
13736
+ const parts = sanitizeNetworkUrl(rawUrl, { includeQuery });
13737
+ return {
13738
+ url: parts.url,
13739
+ hostname: parts.hostname,
13740
+ pathname: parts.pathname,
13741
+ ...parts.search ? { search: parts.search } : {}
13742
+ };
13743
+ }
13702
13744
  function installNetworkHook(options = {}) {
13703
13745
  const originalFetch = typeof fetch === "function" ? fetch.bind(globalThis) : null;
13704
13746
  const XHR = typeof XMLHttpRequest !== "undefined" ? XMLHttpRequest : null;
@@ -13711,8 +13753,13 @@
13711
13753
  failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
13712
13754
  talariaBaseUrl: options.talariaBaseUrl
13713
13755
  };
13756
+ const includeQuery = options.includeNetworkUrlQuery ?? false;
13714
13757
  const handleMeta = (meta) => {
13715
- const enriched = enrichNetworkMeta(meta);
13758
+ const { rawUrl, ...rest } = meta;
13759
+ const enriched = enrichNetworkMeta({
13760
+ ...rest,
13761
+ ...networkUrlParts(rawUrl, includeQuery)
13762
+ });
13716
13763
  try {
13717
13764
  emitNetwork(enriched);
13718
13765
  options.onNetwork?.(enriched);
@@ -13728,12 +13775,13 @@
13728
13775
  globalThis.fetch = async (input2, init) => {
13729
13776
  const started = Date.now();
13730
13777
  const method = (init?.method ?? (input2 instanceof Request ? input2.method : "GET")).toUpperCase();
13731
- const url = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.toString() : input2.url;
13778
+ const rawUrl = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.toString() : input2.url;
13732
13779
  try {
13733
13780
  const response = await originalFetch(input2, init);
13734
13781
  handleMeta({
13735
13782
  method,
13736
- url,
13783
+ rawUrl,
13784
+ url: rawUrl,
13737
13785
  status: response.status,
13738
13786
  durationMs: Date.now() - started,
13739
13787
  ok: response.ok
@@ -13743,7 +13791,8 @@
13743
13791
  const described = describeUnknownError(error);
13744
13792
  handleMeta({
13745
13793
  method,
13746
- url,
13794
+ rawUrl,
13795
+ url: rawUrl,
13747
13796
  durationMs: Date.now() - started,
13748
13797
  ok: false,
13749
13798
  errorName: described.errorName,
@@ -13766,9 +13815,11 @@
13766
13815
  const onDone = () => {
13767
13816
  const status = this.status;
13768
13817
  const networkFail = status === 0;
13818
+ const rawUrl = this.__talariaUrl ?? "";
13769
13819
  handleMeta({
13770
13820
  method: this.__talariaMethod ?? "GET",
13771
- url: this.__talariaUrl ?? "",
13821
+ rawUrl,
13822
+ url: rawUrl,
13772
13823
  status,
13773
13824
  durationMs: Date.now() - (this.__talariaStarted ?? Date.now()),
13774
13825
  ok: status >= 200 && status < 400,
@@ -13791,8 +13842,23 @@
13791
13842
  }
13792
13843
 
13793
13844
  // src/client.ts
13845
+ function networkFailureExtra(failure) {
13846
+ return {
13847
+ method: failure.method || "GET",
13848
+ url: failure.url || "(unknown url)",
13849
+ ...failure.hostname ? { hostname: failure.hostname } : {},
13850
+ ...failure.pathname ? { pathname: failure.pathname } : {},
13851
+ ...failure.search ? { search: failure.search } : {},
13852
+ ...typeof failure.status === "number" ? { status: failure.status } : {},
13853
+ durationMs: failure.durationMs,
13854
+ ok: failure.ok ?? false,
13855
+ failureKind: failure.failureKind ?? "network",
13856
+ aborted: failure.aborted ?? false,
13857
+ ...failure.errorName ? { errorName: failure.errorName } : {},
13858
+ ...failure.errorMessage ? { errorMessage: failure.errorMessage } : {}
13859
+ };
13860
+ }
13794
13861
  function mergeNetworkFailureContext(context, failure) {
13795
- const url = redactUrl(failure.url || "(unknown url)");
13796
13862
  return {
13797
13863
  ...context,
13798
13864
  tags: {
@@ -13803,16 +13869,7 @@
13803
13869
  },
13804
13870
  extra: {
13805
13871
  ...context?.extra ?? {},
13806
- network: {
13807
- method: failure.method,
13808
- url,
13809
- durationMs: failure.durationMs,
13810
- ok: false,
13811
- failureKind: "network",
13812
- errorName: failure.errorName,
13813
- errorMessage: failure.errorMessage,
13814
- aborted: failure.aborted ?? false
13815
- }
13872
+ network: networkFailureExtra(failure)
13816
13873
  }
13817
13874
  };
13818
13875
  }
@@ -13843,6 +13900,7 @@
13843
13900
  disableDefaultIntegrations: options.disableDefaultIntegrations ?? false,
13844
13901
  captureFailedRequests: options.captureFailedRequests ?? true,
13845
13902
  captureNetworkErrors: options.captureNetworkErrors ?? true,
13903
+ includeNetworkUrlQuery: options.includeNetworkUrlQuery ?? false,
13846
13904
  failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
13847
13905
  failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? []
13848
13906
  };
@@ -13971,6 +14029,7 @@
13971
14029
  installNetworkHook({
13972
14030
  captureFailedRequests: this.options.captureFailedRequests,
13973
14031
  captureNetworkErrors: this.options.captureNetworkErrors,
14032
+ includeNetworkUrlQuery: this.options.includeNetworkUrlQuery,
13974
14033
  failedRequestStatusCodes: this.options.failedRequestStatusCodes,
13975
14034
  failedRequestIgnoreUrls: this.options.failedRequestIgnoreUrls,
13976
14035
  talariaBaseUrl: this.options.baseUrl,
@@ -13982,7 +14041,7 @@
13982
14041
  onFailedRequest: (meta) => {
13983
14042
  const status = meta.status;
13984
14043
  const method = meta.method || "GET";
13985
- const url = redactUrl(meta.url || "(unknown url)");
14044
+ const url = meta.url || "(unknown url)";
13986
14045
  void this.captureMessage(
13987
14046
  `HTTP ${status}: ${method} ${url}`,
13988
14047
  status >= 500 ? "error" : "warning",
@@ -13993,10 +14052,11 @@
13993
14052
  "network.failure_kind": "http"
13994
14053
  },
13995
14054
  extra: {
13996
- url,
13997
- durationMs: meta.durationMs,
13998
- ok: meta.ok,
13999
- failureKind: "http"
14055
+ ...networkFailureExtra({
14056
+ ...meta,
14057
+ failureKind: "http",
14058
+ aborted: false
14059
+ })
14000
14060
  }
14001
14061
  }
14002
14062
  );
@@ -14004,7 +14064,7 @@
14004
14064
  onNetworkError: (meta) => {
14005
14065
  this.rememberNetworkFailure(meta, { promoted: true });
14006
14066
  const method = meta.method || "GET";
14007
- const url = redactUrl(meta.url || "(unknown url)");
14067
+ const url = meta.url || "(unknown url)";
14008
14068
  const errLabel = meta.errorName && meta.errorMessage ? `${meta.errorName}: ${meta.errorMessage}` : meta.errorMessage || meta.errorName || "Failed to fetch";
14009
14069
  void this.captureMessage(
14010
14070
  `Network error: ${method} ${url} \u2014 ${errLabel}`,
@@ -14015,15 +14075,11 @@
14015
14075
  "network.failure_kind": "network",
14016
14076
  ...meta.errorName ? { "network.error_name": meta.errorName } : {}
14017
14077
  },
14018
- extra: {
14019
- url,
14020
- durationMs: meta.durationMs,
14021
- ok: false,
14078
+ extra: networkFailureExtra({
14079
+ ...meta,
14022
14080
  failureKind: "network",
14023
- errorName: meta.errorName,
14024
- errorMessage: meta.errorMessage,
14025
14081
  aborted: false
14026
- }
14082
+ })
14027
14083
  }
14028
14084
  );
14029
14085
  }
@@ -14202,6 +14258,7 @@
14202
14258
  throw new Error("@newtalaria/browser: call Talaria.init() first");
14203
14259
  }
14204
14260
  if (this.ingestDisabled) return;
14261
+ const occurredAt = /* @__PURE__ */ new Date();
14205
14262
  const isErrorLike = args.level === "error" || args.level === "fatal";
14206
14263
  let errorClipOutcome = null;
14207
14264
  let attemptedErrorClip = false;
@@ -14259,6 +14316,7 @@
14259
14316
  errorClipOutcome = { status: "failed", reason: "buffer_empty" };
14260
14317
  }
14261
14318
  }
14319
+ const queuedMs = Math.max(0, Date.now() - occurredAt.getTime());
14262
14320
  const tags = applyReplayCaptureTags(
14263
14321
  {
14264
14322
  ...this.browserContext ? browserContextTags(this.browserContext) : {},
@@ -14280,7 +14338,12 @@
14280
14338
  userAgent: this.browserContext.userAgent
14281
14339
  }
14282
14340
  } : {},
14283
- sdk: { name: SDK_NAME, version: SDK_VERSION },
14341
+ sdk: {
14342
+ name: SDK_NAME,
14343
+ version: SDK_VERSION,
14344
+ // Time spent in capture() before ingest (mostly replay flush).
14345
+ ...queuedMs >= 50 ? { queuedMs } : {}
14346
+ },
14284
14347
  ...args.context?.extra
14285
14348
  },
14286
14349
  errorClipOutcome
@@ -14300,7 +14363,7 @@
14300
14363
  url: typeof location !== "undefined" ? location.href : void 0,
14301
14364
  tags: Object.keys(tags).length ? tags : void 0,
14302
14365
  extraJson: extra ? JSON.stringify(extra) : void 0,
14303
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
14366
+ timestamp: occurredAt.toISOString(),
14304
14367
  keepalive: args.keepalive
14305
14368
  });
14306
14369
  if (replayId && replayId === this.linkableReplayId) {