@newtalaria/browser 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -35,6 +35,9 @@ Talaria.init({
35
35
  // until the 5-minute max duration (Sentry-like, more expensive).
36
36
  replaysErrorAfterMs: 15_000,
37
37
  maskAllInputs: true, // default
38
+ // Embed same-origin CSS into the snapshot (needed for auth-gated UIs like CMS).
39
+ // Default false — player re-fetches public stylesheet hrefs instead.
40
+ // inlineStylesheet: true,
38
41
  });
39
42
 
40
43
  try {
@@ -52,6 +55,27 @@ await Talaria.close();
52
55
 
53
56
  `Talaria.init` also installs `window.onerror` / `unhandledrejection` handlers unless you pass `disableDefaultIntegrations: true`.
54
57
 
58
+ Optional init `tags` are merged into every captured event (per-call tags win on key conflict).
59
+
60
+ ## Script tag (IIFE)
61
+
62
+ For hosts without a bundler (e.g. Silverstripe `Requirements`):
63
+
64
+ ```html
65
+ <script src="/path/to/talaria.browser.iife.js"></script>
66
+ <script>
67
+ Talaria.init({
68
+ dsn: 'https://api.example.com',
69
+ apiKey: 'tal_live_…',
70
+ environment: 'production',
71
+ replaysSessionSampleRate: 0,
72
+ replaysOnErrorSampleRate: 0,
73
+ });
74
+ </script>
75
+ ```
76
+
77
+ Build output: `dist/talaria.browser.iife.js` (also produced by `npm run build` / `npm run build:iife`).
78
+
55
79
  ## Recommended sampling (cost)
56
80
 
57
81
  You pay for **uploaded + retained** bytes, not for local buffering. Prefer error clips in production; keep full-session sampling low.
@@ -127,6 +151,32 @@ Custom rrweb events:
127
151
 
128
152
  Privacy defaults: `maskAllInputs: true`, password fields masked, `[data-talaria-mask]` blocked.
129
153
 
154
+ ### Auth-gated CSS (CMS / admin)
155
+
156
+ By default `inlineStylesheet` is `false`: linked stylesheets stay as `href`s and are re-fetched when you watch the replay. That works for **public** CSS, but fails for login-protected admin CSS (player has no session cookies).
157
+
158
+ Set `inlineStylesheet: true` so same-origin stylesheet rules are embedded while the user is logged in. Cross-origin sheets without CORS still cannot be inlined (browser `cssRules` restriction).
159
+
160
+ ### Failed HTTP requests → events
161
+
162
+ By default, completed `fetch` / XHR responses with status **500–599** are also sent as Talaria events (message like `HTTP 500: GET /api/...`). Replay still gets `talaria-network` breadcrumbs for all requests.
163
+
164
+ ```ts
165
+ Talaria.init({
166
+ dsn: 'https://api.example.com',
167
+ apiKey: 'tal_live_…',
168
+ environment: 'production',
169
+ // Default true
170
+ captureFailedRequests: true,
171
+ // Default [[500, 599]]. CMS admin often wants 4xx too:
172
+ failedRequestStatusCodes: [[400, 599]],
173
+ // Extra URL substrings to skip (Talaria /events and /replays are always skipped)
174
+ failedRequestIgnoreUrls: ['/health'],
175
+ });
176
+ ```
177
+
178
+ Transport errors (network down, no status) are not promoted as HTTP events; uncaught exceptions from failed fetches still go through normal `error` / `unhandledrejection` handlers when the app rethrows.
179
+
130
180
  ## Public API
131
181
 
132
182
  | API | Description |
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAoCpB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAuEpC,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAAuB;IACrC,yEAAyE;IACzE,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,uBAAuB,CAAK;IACpC,0EAA0E;IAC1E,OAAO,CAAC,iBAAiB,CAAuB;IAChD,4EAA4E;IAC5E,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAgEvC,WAAW,IAAI,MAAM,GAAG,IAAI;IAKtB,gBAAgB,CACpB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAcV,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,aAAsB,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IASV,KAAK,CAAC,IAAI,CAAC,EAAE;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD5B,OAAO,CAAC,YAAY;YAwBN,OAAO;IA4ErB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,qBAAqB;YAOf,qBAAqB;IAsBnC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAO3B,8EAA8E;YAChE,YAAY;YAgBZ,eAAe;IAW7B,oFAAoF;IACpF,OAAO,CAAC,iBAAiB;IAiBzB,+EAA+E;IAC/E,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAYjC,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,aAAa;YAKP,aAAa;YAkBb,qBAAqB;IA8HnC,OAAO,CAAC,kBAAkB;IAQ1B;;;OAGG;YACW,iBAAiB;YA2BjB,cAAc;CAuB7B"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EAEd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAoCpB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AA4EpC,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,MAAM,CAAuB;IACrC,yEAAyE;IACzE,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,uBAAuB,CAAK;IACpC,0EAA0E;IAC1E,OAAO,CAAC,iBAAiB,CAAuB;IAChD,4EAA4E;IAC5E,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAkB;IACnC;;;OAGG;IACH,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,IAAI,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IA6FvC,WAAW,IAAI,MAAM,GAAG,IAAI;IAKtB,gBAAgB,CACpB,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IAcV,cAAc,CAClB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,aAAsB,EAC7B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;IASV,KAAK,CAAC,IAAI,CAAC,EAAE;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,MAAM,CAAC,EAAE,OAAO,CAAC;KAClB,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmD5B,OAAO,CAAC,YAAY;YAwBN,OAAO;IA+ErB,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,uBAAuB;IAK/B,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,uBAAuB;IAiB/B,OAAO,CAAC,qBAAqB;YAOf,qBAAqB;IAsBnC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAmB5B,OAAO,CAAC,mBAAmB;IAO3B,8EAA8E;YAChE,YAAY;YAgBZ,eAAe;IAW7B,oFAAoF;IACpF,OAAO,CAAC,iBAAiB;IAiBzB,+EAA+E;IAC/E,OAAO,CAAC,oBAAoB;IAI5B;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAYjC,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,aAAa;YAKP,aAAa;YAkBb,qBAAqB;IA8HnC,OAAO,CAAC,kBAAkB;IAQ1B;;;OAGG;YACW,iBAAiB;YA2BjB,cAAc;CAuB7B"}
package/dist/iife.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=iife.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"iife.d.ts","sourceRoot":"","sources":["../src/iife.ts"],"names":[],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -32,6 +32,6 @@ export declare const Talaria: {
32
32
  export { TalariaClient } from './client.js';
33
33
  export { computeErrorClipDeadlineMs, fitCompressedPrefix, isErrorClipBudgetExhausted, planOversizedRetry, } from './replay/fit_segment.js';
34
34
  export { MAX_SEGMENTS_ERROR_CLIP, MAX_ERROR_CLIP_COMPRESSED_BYTES, TARGET_COMPRESSED_SEGMENT_BYTES, MAX_COMPRESSED_SEGMENT_BYTES, } from './replay/segment_buffer.js';
35
- export type { CaptureContext, Environment, SeverityLevel, TalariaInitOptions, } from './types.js';
35
+ export type { CaptureContext, Environment, FailedRequestStatusCode, SeverityLevel, TalariaInitOptions, } from './types.js';
36
36
  export default Talaria;
37
37
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO;kBACJ,kBAAkB,GAAG,IAAI;4BAIf,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;4BAK9D,MAAM,UACP,aAAa,YACX,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;mBAID,MAAM,GAAG,IAAI;aAInB,OAAO,CAAC,IAAI,CAAC;aAIb,OAAO,CAAC,IAAI,CAAC;CAGvB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,cAAc,EACd,WAAW,EACX,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EACb,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAIpB;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,OAAO;kBACJ,kBAAkB,GAAG,IAAI;4BAIf,OAAO,YAAY,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;4BAK9D,MAAM,UACP,aAAa,YACX,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC;mBAID,MAAM,GAAG,IAAI;aAInB,OAAO,CAAC,IAAI,CAAC;aAIb,OAAO,CAAC,IAAI,CAAC;CAGvB,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,+BAA+B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EACV,cAAc,EACd,WAAW,EACX,uBAAuB,EACvB,aAAa,EACb,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,eAAe,OAAO,CAAC"}
package/dist/index.js CHANGED
@@ -13142,7 +13142,7 @@ function startRecorder(options) {
13142
13142
  blockSelector: defaultBlockSelector(options.blockSelector),
13143
13143
  recordCanvas: false,
13144
13144
  collectFonts: false,
13145
- inlineStylesheet: false,
13145
+ inlineStylesheet: options.inlineStylesheet,
13146
13146
  // Shrink DOM snapshots on heavy sites (docs / marketing).
13147
13147
  slimDOMOptions: "all",
13148
13148
  sampling: {
@@ -13214,11 +13214,52 @@ function emitNetwork(meta) {
13214
13214
  } catch {
13215
13215
  }
13216
13216
  }
13217
- function installNetworkHook() {
13217
+ function statusMatches(status, codes) {
13218
+ for (const entry of codes) {
13219
+ if (typeof entry === "number") {
13220
+ if (status === entry) return true;
13221
+ } else if (Array.isArray(entry) && entry.length >= 2) {
13222
+ const [min, max] = entry;
13223
+ if (status >= min && status <= max) return true;
13224
+ }
13225
+ }
13226
+ return false;
13227
+ }
13228
+ function shouldPromoteFailedRequest(meta, opts) {
13229
+ if (!opts.captureFailedRequests) return false;
13230
+ if (typeof meta.status !== "number" || Number.isNaN(meta.status)) return false;
13231
+ if (!statusMatches(meta.status, opts.failedRequestStatusCodes)) return false;
13232
+ const url = meta.url || "";
13233
+ const ignore = [...opts.failedRequestIgnoreUrls];
13234
+ const base = (opts.talariaBaseUrl ?? "").replace(/\/+$/, "");
13235
+ if (base) {
13236
+ ignore.push(`${base}/events/`, `${base}/replays/`);
13237
+ }
13238
+ ignore.push("/events/ingest", "/events/ingestBatch", "/replays/");
13239
+ const lower = url.toLowerCase();
13240
+ for (const part of ignore) {
13241
+ if (part && lower.includes(part.toLowerCase())) return false;
13242
+ }
13243
+ return true;
13244
+ }
13245
+ function installNetworkHook(options = {}) {
13218
13246
  const originalFetch = typeof fetch === "function" ? fetch.bind(globalThis) : null;
13219
13247
  const XHR = typeof XMLHttpRequest !== "undefined" ? XMLHttpRequest : null;
13220
13248
  const originalOpen = XHR?.prototype.open;
13221
13249
  const originalSend = XHR?.prototype.send;
13250
+ const matchOpts = {
13251
+ captureFailedRequests: options.captureFailedRequests ?? true,
13252
+ failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
13253
+ failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? [],
13254
+ talariaBaseUrl: options.talariaBaseUrl
13255
+ };
13256
+ const handleMeta = (meta) => {
13257
+ emitNetwork(meta);
13258
+ options.onNetwork?.(meta);
13259
+ if (shouldPromoteFailedRequest(meta, matchOpts)) {
13260
+ options.onFailedRequest?.(meta);
13261
+ }
13262
+ };
13222
13263
  if (originalFetch) {
13223
13264
  globalThis.fetch = async (input2, init) => {
13224
13265
  const started = Date.now();
@@ -13226,7 +13267,7 @@ function installNetworkHook() {
13226
13267
  const url = typeof input2 === "string" ? input2 : input2 instanceof URL ? input2.toString() : input2.url;
13227
13268
  try {
13228
13269
  const response = await originalFetch(input2, init);
13229
- emitNetwork({
13270
+ handleMeta({
13230
13271
  method,
13231
13272
  url,
13232
13273
  status: response.status,
@@ -13235,7 +13276,7 @@ function installNetworkHook() {
13235
13276
  });
13236
13277
  return response;
13237
13278
  } catch (error) {
13238
- emitNetwork({
13279
+ handleMeta({
13239
13280
  method,
13240
13281
  url,
13241
13282
  durationMs: Date.now() - started,
@@ -13254,7 +13295,7 @@ function installNetworkHook() {
13254
13295
  XHR.prototype.send = function(body) {
13255
13296
  this.__talariaStarted = Date.now();
13256
13297
  const onDone = () => {
13257
- emitNetwork({
13298
+ handleMeta({
13258
13299
  method: this.__talariaMethod ?? "GET",
13259
13300
  url: this.__talariaUrl ?? "",
13260
13301
  status: this.status,
@@ -13294,9 +13335,14 @@ function resolveOptions(options) {
13294
13335
  replaysOnErrorSampleRate: clamp01(options.replaysOnErrorSampleRate ?? 1),
13295
13336
  replaysErrorAfterMs: normalizeErrorAfterMs(options.replaysErrorAfterMs),
13296
13337
  maskAllInputs: options.maskAllInputs ?? true,
13338
+ inlineStylesheet: options.inlineStylesheet ?? false,
13297
13339
  blockSelector: options.blockSelector ?? "",
13298
13340
  userId: options.userId,
13299
- disableDefaultIntegrations: options.disableDefaultIntegrations ?? false
13341
+ tags: options.tags,
13342
+ disableDefaultIntegrations: options.disableDefaultIntegrations ?? false,
13343
+ captureFailedRequests: options.captureFailedRequests ?? true,
13344
+ failedRequestStatusCodes: options.failedRequestStatusCodes ?? [[500, 599]],
13345
+ failedRequestIgnoreUrls: options.failedRequestIgnoreUrls ?? []
13300
13346
  };
13301
13347
  }
13302
13348
  function clamp01(n2) {
@@ -13380,10 +13426,39 @@ var TalariaClient = class {
13380
13426
  this.uploadEnabled = this.sessionSampled;
13381
13427
  this.recorder = startRecorder({
13382
13428
  maskAllInputs: this.options.maskAllInputs,
13429
+ inlineStylesheet: this.options.inlineStylesheet,
13383
13430
  blockSelector: this.options.blockSelector,
13384
13431
  onEvent: (event) => this.onRrwebEvent(event)
13385
13432
  });
13386
- this.teardowns.push(installConsoleHook(), installNetworkHook());
13433
+ this.teardowns.push(
13434
+ installConsoleHook(),
13435
+ installNetworkHook({
13436
+ captureFailedRequests: this.options.captureFailedRequests,
13437
+ failedRequestStatusCodes: this.options.failedRequestStatusCodes,
13438
+ failedRequestIgnoreUrls: this.options.failedRequestIgnoreUrls,
13439
+ talariaBaseUrl: this.options.baseUrl,
13440
+ onFailedRequest: (meta) => {
13441
+ const status = meta.status;
13442
+ const method = meta.method || "GET";
13443
+ const url = meta.url || "(unknown url)";
13444
+ void this.captureMessage(
13445
+ `HTTP ${status}: ${method} ${url}`,
13446
+ status >= 500 ? "error" : "warning",
13447
+ {
13448
+ tags: {
13449
+ "http.status_code": String(status),
13450
+ "http.method": method
13451
+ },
13452
+ extra: {
13453
+ url,
13454
+ durationMs: meta.durationMs,
13455
+ ok: meta.ok
13456
+ }
13457
+ }
13458
+ );
13459
+ }
13460
+ })
13461
+ );
13387
13462
  if (!this.options.disableDefaultIntegrations) {
13388
13463
  this.installGlobalHandlers();
13389
13464
  }
@@ -13551,7 +13626,10 @@ var TalariaClient = class {
13551
13626
  throw error;
13552
13627
  }
13553
13628
  }
13554
- const tags = { ...args.context?.tags ?? {} };
13629
+ const tags = {
13630
+ ...this.options.tags ?? {},
13631
+ ...args.context?.tags ?? {}
13632
+ };
13555
13633
  const extra = args.context?.extra;
13556
13634
  const replayId = this.uploadEnabled && this.segmentIndex > 0 ? this.replayId : this.linkableReplayId;
13557
13635
  try {