@flareapp/core 2.11.0 → 2.12.1

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/dist/index.cjs CHANGED
@@ -26,17 +26,17 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  }) : target, mod));
27
27
 
28
28
  //#endregion
29
- const require_urlAttributes = require('./urlAttributes-Cinqzwjy.cjs');
29
+ const require_urlAttributes = require('./urlAttributes-CAhKmW6d.cjs');
30
30
  let error_stack_parser = require("error-stack-parser");
31
31
  error_stack_parser = __toESM(error_stack_parser);
32
32
 
33
33
  //#region src/framework.ts
34
34
  /**
35
- * Framework names the Flare backend recognises. Wire format, so the values never change: they ship as
36
- * `flare.framework.name` and (lowercased) as `context.custom.framework`.
35
+ * Framework names the Flare backend recognizes. Wire format: these values never change, since they
36
+ * ship as `flare.framework.name` and (lowercased) as `context.custom.framework`.
37
37
  *
38
- * `Js` and `Node` are the base SDKs' fallback claim, overwritten when a framework package tags its
39
- * own name. `NodeElectron` is an Electron main process; its renderers report their own.
38
+ * `Js` and `Node` are fallback claims from the base SDKs, overwritten when a framework package sets
39
+ * its own name. `NodeElectron` is the Electron main process; renderers report their own name.
40
40
  */
41
41
  const FrameworkName = {
42
42
  Js: "js",
@@ -52,7 +52,7 @@ const FrameworkName = {
52
52
  //#endregion
53
53
  //#region src/spanTypes.ts
54
54
  /**
55
- * Span types the Flare backend recognises. Wire format, so the values never change: they ship as the
55
+ * Span types the Flare backend recognizes. Wire format, so the values never change: they ship as the
56
56
  * `flare.span_type` attribute and the backend groups performance data by them.
57
57
  *
58
58
  * These are the browser client's set. They live in core because core's `SpanOptions.spanType` needs
@@ -66,6 +66,10 @@ const BrowserSpanType = {
66
66
  Component: "browser_component",
67
67
  WebVital: "browser_web_vital"
68
68
  };
69
+ /**
70
+ * Span event types on an error report. Kept apart from `BrowserSpanType`: these are points in time,
71
+ * not spans with a duration. That is also why a route change is not called `browser_navigation`.
72
+ */
69
73
  const BrowserSpanEventType = {
70
74
  Click: "browser_click",
71
75
  Input: "browser_input",
@@ -84,7 +88,6 @@ const SpanStatusCode = {
84
88
  //#endregion
85
89
  //#region src/util/utf8Bytes.ts
86
90
  const textEncoder = new TextEncoder();
87
- /** UTF-8 byte length of `value`. */
88
91
  function utf8Bytes(value) {
89
92
  return textEncoder.encode(value).length;
90
93
  }
@@ -98,8 +101,7 @@ var Api = class {
98
101
  pendingKeepaliveRequests = 0;
99
102
  /**
100
103
  * How many keepalive bytes are still available. Logs and traces share one browser allowance and both
101
- * flush on page hide, so whichever goes second has to pack against what is left rather than assume the
102
- * whole budget, or it exceeds the gate in send() and silently degrades to a cancellable fetch.
104
+ * flush on page hide, so whichever goes second must pack against what is left, not the whole budget.
103
105
  */
104
106
  keepaliveBudgetRemaining() {
105
107
  if (this.pendingKeepaliveRequests >= MAX_PENDING_KEEPALIVE_REQUESTS) return 0;
@@ -199,11 +201,6 @@ function recordBreadcrumb(scopeProvider, config, type, attributes, startTimeUnix
199
201
 
200
202
  //#endregion
201
203
  //#region src/telemetry/TelemetryBuffer.ts
202
- /**
203
- * The batching machine behind both telemetry signals: hold records, ship them when a size, weight or time
204
- * trigger fires, and shed the oldest when nothing can drain. One instance owns one signal; what that signal
205
- * is comes entirely from the policy.
206
- */
207
204
  var TelemetryBuffer = class {
208
205
  entries = [];
209
206
  bufferedBytes = 0;
@@ -313,11 +310,6 @@ var TelemetryBuffer = class {
313
310
  if (dropped) this.bufferedBytes -= dropped.bytes;
314
311
  }
315
312
  }
316
- /**
317
- * Newest-wins. An over-budget record is skipped, not a stop signal, so a smaller older record behind a fat
318
- * one still ships. Runs on visibilitychange:hidden, which fires on plain backgrounding too, so the tail this
319
- * leaves behind is retained and re-armed rather than dropped (see flush).
320
- */
321
313
  packForKeepalive(config, resource) {
322
314
  const fixedBytes = this.policy.emptyEnvelopeBytes(resource);
323
315
  const budget = Math.min(config.keepaliveMaxBytes, this.policy.keepaliveBudget?.(config) ?? config.keepaliveMaxBytes);
@@ -346,11 +338,6 @@ var TelemetryBuffer = class {
346
338
 
347
339
  //#endregion
348
340
  //#region src/telemetry/resourceIdentity.ts
349
- /**
350
- * Builds the attributes that go on every logs or traces envelope: the caller's own attributes in `base`, with
351
- * our SDK, service and framework identity on top. Our keys win, so a user value cannot overwrite something
352
- * like `telemetry.sdk.name`.
353
- */
354
341
  function buildResourceIdentity(base, config, sdk, framework) {
355
342
  const identity = {
356
343
  "telemetry.sdk.language": "javascript",
@@ -371,18 +358,6 @@ function buildResourceIdentity(base, config, sdk, framework) {
371
358
 
372
359
  //#endregion
373
360
  //#region src/logging/otel.ts
374
- /**
375
- * Converts one attribute value into the OpenTelemetry `AnyValue` shape. Strings, numbers and booleans become
376
- * leaves, arrays and objects are walked recursively. Anything OpenTelemetry cannot carry (null, undefined,
377
- * NaN, functions) returns null and the caller drops that key.
378
- *
379
- * A value that contains itself becomes the string `[Circular]`. `inPath` only holds the parents of the value
380
- * being converted right now, so the same object used twice side by side is converted twice instead of being
381
- * wrongly called circular.
382
- *
383
- * The walk also stops at a maximum depth and a maximum number of nodes, see traversalBudget.ts. Pass `budget`
384
- * to let several calls share one allowance, otherwise every call gets its own.
385
- */
386
361
  function valueToOpenTelemetry(value, inPath = /* @__PURE__ */ new WeakSet(), budget = require_urlAttributes.createTraversalBudget()) {
387
362
  return convert(value, inPath, 0, budget);
388
363
  }
@@ -467,17 +442,9 @@ function buildLogsEnvelope(records, resourceAttributes, scopeName, scopeVersion)
467
442
  }]
468
443
  }] };
469
444
  }
470
- /**
471
- * How many UTF-8 bytes one record adds to an envelope. We measure the real toOtelLogRecord output instead of
472
- * reusing the cached BufferedLog estimate, because keepaliveMaxBytes is a hard browser limit and an estimate
473
- * is not good enough.
474
- *
475
- * Uses flatJsonStringify to match Api.logs, which sends the envelope through the same encoder.
476
- */
477
445
  function otelLogRecordBytes(record) {
478
446
  return utf8Bytes(require_urlAttributes.flatJsonStringify(toOtelLogRecord(record)));
479
447
  }
480
- /** UTF-8 bytes of an empty envelope: the fixed overhead every batch has, before any records are added. */
481
448
  function emptyLogsEnvelopeBytes(resourceAttributes, scopeName, scopeVersion) {
482
449
  return utf8Bytes(require_urlAttributes.flatJsonStringify(buildLogsEnvelope([], resourceAttributes, scopeName, scopeVersion)));
483
450
  }
@@ -637,7 +604,6 @@ function partitionAttributes(attributes) {
637
604
 
638
605
  //#endregion
639
606
  //#region src/Scope.ts
640
- /** `USER_IDENTITY_KEYS` derives from this, so adding a field here can never leave the clear pass stale. */
641
607
  const USER_FIELD_KEYS = {
642
608
  id: "user.id",
643
609
  email: "user.email",
@@ -817,11 +783,9 @@ function isApplicationFrame(fileName) {
817
783
  //#endregion
818
784
  //#region src/stacktrace/NullFileReader.ts
819
785
  /**
820
- * No-op `FileReader` returning `null` for every URL. Default for `Flare`'s `fileReader` param so `new Flare()` builds
821
- * reports without picking an environment; stack frames just omit source snippets. Consumer packages inject the real
822
- * ones: `@flareapp/js` a fetch-based reader, `@flareapp/node` a disk reader. The `read(url) -> Promise<string | null>`
823
- * interface lets the stack-trace builder treat all three the same (render on text, skip on null), so core needs no
824
- * environment checks.
786
+ * No-op `FileReader` returning `null` for every URL. Default for `Flare`'s `fileReader` param, so
787
+ * `new Flare()` builds reports without picking an environment; stack frames just omit source snippets.
788
+ * `@flareapp/js` and `@flareapp/node` inject a real fetch- or disk-based reader instead.
825
789
  */
826
790
  var NullFileReader = class {
827
791
  read(_url) {
@@ -1007,28 +971,15 @@ function buildTracesEnvelope(spans, resourceAttributes, scopeName, scopeVersion)
1007
971
  }]
1008
972
  }] };
1009
973
  }
1010
- /**
1011
- * How many UTF-8 bytes one span adds to an envelope. We measure the real toOtelSpan output instead of reusing
1012
- * the cached BufferedSpan estimate, because keepaliveMaxBytes is a hard browser limit and an estimate is not
1013
- * good enough.
1014
- *
1015
- * We use flatJsonStringify instead of JSON.stringify because a span keeps values the caller still owns, like
1016
- * status.message, and those can turn unserializable after the span ended. This runs from a visibilitychange
1017
- * listener with no try/catch around it, so a throw here loses the flush. flatJsonStringify handles the usual
1018
- * suspects (circular references, BigInt, a getter that throws on a plain object) but is not bulletproof: a
1019
- * class instance with a throwing getter goes through untouched and can still throw.
1020
- */
1021
974
  function otelSpanBytes(span) {
1022
975
  return utf8Bytes(require_urlAttributes.flatJsonStringify(toOtelSpan(span)));
1023
976
  }
1024
- /** UTF-8 bytes of an empty envelope: the fixed overhead every batch has, before any spans are added. */
1025
977
  function emptyTracesEnvelopeBytes(resourceAttributes, scopeName, scopeVersion) {
1026
978
  return utf8Bytes(JSON.stringify(buildTracesEnvelope([], resourceAttributes, scopeName, scopeVersion)));
1027
979
  }
1028
980
 
1029
981
  //#endregion
1030
982
  //#region src/tracing/SpanBuffer.ts
1031
- /** The span half of the shared telemetry buffer: names the config keys, the envelope and the ingest call. */
1032
983
  var SpanBuffer = class {
1033
984
  inner;
1034
985
  constructor(deps) {
@@ -1113,11 +1064,9 @@ function parseTraceparent(header) {
1113
1064
  function isPromiseLike(value) {
1114
1065
  return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
1115
1066
  }
1116
- /** `SpanOptions.parent` is a structurally overlapping union; `isRecording` is what tells a real Span apart. */
1117
1067
  function isSpan(parent) {
1118
1068
  return "isRecording" in parent;
1119
1069
  }
1120
- /** A SpanImpl carries the epoch it was created under; a hand-stitched `{traceId, spanId}` parent does not. */
1121
1070
  function hasEpoch(parent) {
1122
1071
  return "epoch" in parent && typeof parent.epoch === "number";
1123
1072
  }
@@ -1126,16 +1075,6 @@ function defaultNowNano() {
1126
1075
  const ms = performanceApi && typeof performanceApi.now === "function" && typeof performanceApi.timeOrigin === "number" ? performanceApi.timeOrigin + performanceApi.now() : Date.now();
1127
1076
  return Math.round(ms * 1e6);
1128
1077
  }
1129
- /**
1130
- * Both trace maps cap their size the same way: insertion order is LRU, so the first key is the one to drop.
1131
- * Only evicts when `key` is not already in the map. A set() that overwrites an existing key does not grow the
1132
- * map, so it must not evict an unrelated entry to make room for it.
1133
- */
1134
- function evictLruIfNew(map, key, cap) {
1135
- if (map.has(key) || map.size < cap) return;
1136
- const lru = map.keys().next().value;
1137
- if (lru !== void 0) map.delete(lru);
1138
- }
1139
1078
  const MAX_CLOSED_TRACES = 100;
1140
1079
  /** Bounded backstop for the live TraceState map: an app that never ends spans must not grow it forever. */
1141
1080
  const DEFAULT_MAX_LIVE_TRACES = 1e3;
@@ -1174,10 +1113,9 @@ var Tracer = class {
1174
1113
  this.holder.setActiveRoot?.(span);
1175
1114
  }
1176
1115
  /**
1177
- * Take one span against `traceId`'s cap up front, for a caller that publishes a span id before the
1178
- * span exists (the component profilers do; their descendants record first). False means the trace is
1179
- * full and the caller should stay transparent instead of handing out an id the cap will refuse.
1180
- * Consumed by the matching `startSpan({ claimed: true })`.
1116
+ * Claims a span slot before the span exists, for a caller that publishes a span id early (the
1117
+ * component profilers do; their descendants record first). Returns false when the trace is full.
1118
+ * Paired with `startSpan({ claimed: true })`.
1181
1119
  */
1182
1120
  claimSpanSlot(traceId) {
1183
1121
  const config = this.deps.getConfig();
@@ -1216,7 +1154,7 @@ var Tracer = class {
1216
1154
  this.pendingContinuation = parseTraceparent(header);
1217
1155
  }
1218
1156
  /**
1219
- * Runs `fn` with the span active, so spans started inside auto-parent to it, then ends it.
1157
+ * Runs `fn` with the span active, so spans started inside it auto-parent to it, then ends the span.
1220
1158
  * Records an error status first if `fn` throws or its returned promise rejects.
1221
1159
  */
1222
1160
  withSpan(name, fn, opts = {}) {
@@ -1246,8 +1184,10 @@ var Tracer = class {
1246
1184
  }
1247
1185
  });
1248
1186
  }
1249
- /** Starts a span the caller must end. Unlike `withSpan`, it does not become the active span,
1250
- * so spans started after it do not auto-parent to it. */
1187
+ /**
1188
+ * Starts a span the caller must end. Unlike `withSpan`, it does not become the active span, so spans
1189
+ * started after it do not auto-parent to it.
1190
+ */
1251
1191
  startSpan(name, opts = {}) {
1252
1192
  const config = this.deps.getConfig();
1253
1193
  const spanId$1 = opts.spanId ?? spanId();
@@ -1277,7 +1217,6 @@ var Tracer = class {
1277
1217
  this.emitSpanEvent("start", span);
1278
1218
  return span;
1279
1219
  }
1280
- /** A real Span handle that records nothing, so callers never have to branch on whether tracing is on. */
1281
1220
  startInertSpan(name, spanId, opts, config) {
1282
1221
  const span = this.makeSpan({
1283
1222
  traceId: traceId(),
@@ -1352,7 +1291,7 @@ var Tracer = class {
1352
1291
  return this.createState(traceId, localRootSpanId, fallbackRecording());
1353
1292
  }
1354
1293
  createState(traceId, localRootSpanId, recording) {
1355
- evictLruIfNew(this.traceStates, traceId, this.maxLiveTraces);
1294
+ require_urlAttributes.evictLruIfNew(this.traceStates, traceId, this.maxLiveTraces);
1356
1295
  const state = {
1357
1296
  traceId,
1358
1297
  recording,
@@ -1384,9 +1323,8 @@ var Tracer = class {
1384
1323
  if (opts.attributes) for (const [key, value] of Object.entries(opts.attributes)) span.setAttribute(key, value);
1385
1324
  return span;
1386
1325
  }
1387
- /** Bounded, LRU by insertion order, like traceStates. Holds primitives only, never a span. */
1388
1326
  rememberClosed(state) {
1389
- evictLruIfNew(this.closedTraces, state.traceId, MAX_CLOSED_TRACES);
1327
+ require_urlAttributes.evictLruIfNew(this.closedTraces, state.traceId, MAX_CLOSED_TRACES);
1390
1328
  this.closedTraces.set(state.traceId, {
1391
1329
  localRootSpanId: state.localRootSpanId,
1392
1330
  recording: state.recording,
@@ -1439,8 +1377,6 @@ var Tracer = class {
1439
1377
 
1440
1378
  //#endregion
1441
1379
  //#region src/Flare.ts
1442
- /** Scope attributes a span never inherits. Derived from `USER_IDENTITY_KEYS` so a future user field is
1443
- * excluded automatically, without anyone needing to remember to list it here. See `getScopeAttributes`. */
1444
1380
  const SPAN_SCOPE_EXCLUDED_KEYS = USER_IDENTITY_KEYS.filter((key) => key !== USER_FIELD_KEYS.id);
1445
1381
  const DEFAULT_SDK_NAME = "@flareapp/core";
1446
1382
  var Flare = class {
@@ -1525,14 +1461,6 @@ var Flare = class {
1525
1461
  activeSpanHolder
1526
1462
  });
1527
1463
  }
1528
- /**
1529
- * Register an in-flight report so `flush()` can wait for it. Every entry point wraps its whole async
1530
- * pipeline, from beforeEvaluate through api.report, so flush() waits on all of it.
1531
- *
1532
- * What goes in the Set is a shadow promise that mirrors `p`'s timing but cannot reject, so a failed
1533
- * report never surfaces as an unhandled rejection warning. `p` itself is returned untouched, so the
1534
- * caller still observes real success or failure.
1535
- */
1536
1464
  track(p) {
1537
1465
  const tracked = p.then(() => void 0, () => void 0);
1538
1466
  this.inflight.add(tracked);
@@ -1540,12 +1468,11 @@ var Flare = class {
1540
1468
  return p;
1541
1469
  }
1542
1470
  /**
1543
- * Wait until every in-flight report settles or `timeoutMs` elapses. Always resolves, never rejects.
1544
- * Written for `@flareapp/node`'s fatal handler, which awaits the fatal report itself then flushes to
1545
- * drain any other concurrent reports before `process.exit`.
1471
+ * Waits until every in-flight report settles, or `timeoutMs` elapses. Always resolves, never rejects.
1472
+ * Used by `@flareapp/node`'s fatal handler to drain other reports before `process.exit`.
1546
1473
  *
1547
- * Snapshotting the Set bounds the wait: reports started after this line are not awaited, so a handler
1548
- * that keeps emitting during shutdown cannot block the process forever. Call flush again for those.
1474
+ * Only reports already in flight are awaited, so a handler still emitting during shutdown cannot block
1475
+ * forever. Call flush again to catch those.
1549
1476
  */
1550
1477
  flush(timeoutMs = 2e3) {
1551
1478
  this._logger.flush();
@@ -1692,10 +1619,6 @@ var Flare = class {
1692
1619
  this.framework = framework;
1693
1620
  return this;
1694
1621
  }
1695
- /**
1696
- * True when a report must not be captured: consent withdrawn, or dropped by sampling. Consent is
1697
- * checked first, so a blocked report never runs the sampler or assembles a report (no cookie read).
1698
- */
1699
1622
  shouldSkipCapture() {
1700
1623
  if (this._config.hasConsent === false) return true;
1701
1624
  return this._config.sampleRate < 1 && Math.random() >= this._config.sampleRate;
@@ -1820,15 +1743,6 @@ var Flare = class {
1820
1743
  record: this.assembleAttributes(collectorRecord, userAttributes, false)
1821
1744
  };
1822
1745
  }
1823
- /**
1824
- * Local roots only, snapshotted by the Tracer at span START so a long-lived root does not drift into
1825
- * the next page's scope. Children get none, and no span ever runs the DOM collector.
1826
- *
1827
- * Everything assembled is inherited except user identity (excluding the opaque `user.id`): a root span
1828
- * goes out for every page view, so email, full name, IP and `user.attributes` would turn normal
1829
- * browsing into PII traffic. The rest — `context.custom`, `addContextGroup` bags — stays in, because
1830
- * the trace viewer renders any span attribute whose key does not start with `flare.`.
1831
- */
1832
1746
  getScopeAttributes() {
1833
1747
  const scoped = { ...this.assembleAttributes({}, {}, false) };
1834
1748
  for (const key of SPAN_SCOPE_EXCLUDED_KEYS) delete scoped[key];
@@ -1961,6 +1875,7 @@ exports.createStackTrace = createStackTrace;
1961
1875
  exports.defaultNowNano = defaultNowNano;
1962
1876
  exports.describeRejectionReason = require_urlAttributes.describeRejectionReason;
1963
1877
  exports.deviceInfoToAttributes = deviceInfoToAttributes;
1878
+ exports.evictLruIfNew = require_urlAttributes.evictLruIfNew;
1964
1879
  exports.extractCode = require_urlAttributes.extractCode;
1965
1880
  exports.flatJsonStringify = require_urlAttributes.flatJsonStringify;
1966
1881
  exports.getCodeSnippet = getCodeSnippet;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as TracesEnvelope, A as Attributes, B as MessageLevel, C as convertToError, D as assert, E as assertKey, F as EntryPointType, G as SamplingContext, H as OtelSpan, I as Framework, J as SpanEvent, K as SdkInfo, L as Glow, M as BufferedSpan, N as Config, O as AnyValue, P as EntryPointHandler, Q as StackFrame, R as KeyValue, S as createIdentityTagger, U as OverriddenGrouping, V as OtelLogRecord, W as Report, X as SpanStatus, Y as SpanOptions, Z as SpanStatusCode, at as FrameworkName, b as extractCode, c as RejectionReporter, d as DEFAULT_URL_DENYLIST, et as TracesSampler, f as redactObjectValues, g as now, h as safeDecode, it as SpanTypeName, j as BufferedLog, k as AttributeValue, l as describeRejectionReason, m as resolveDenylist, n as urlAttributes, nt as BrowserSpanEventType, o as SafeCloneOptions, p as redactUrlQuery, q as Span, r as toCustomContext, rt as BrowserSpanType, s as safeClone, tt as User, u as routeRejection, v as glowsToEvents, x as SdkTaggable, y as flatJsonStringify, z as LogsEnvelope } from "./urlAttributes-D0zqStcw.cjs";
1
+ import { $ as StackFrame, A as AttributeValue, B as LogsEnvelope, C as createIdentityTagger, D as assertKey, F as EntryPointHandler, G as Report, H as OtelLogRecord, I as EntryPointType, J as Span, K as SamplingContext, L as Framework, M as BufferedLog, N as BufferedSpan, O as assert, P as Config, Q as SpanStatusCode, R as Glow, S as SdkTaggable, U as OtelSpan, V as MessageLevel, W as OverriddenGrouping, X as SpanOptions, Y as SpanEvent, Z as SpanStatus, at as SpanTypeName, b as extractCode, c as RejectionReporter, d as DEFAULT_URL_DENYLIST, et as TracesEnvelope, f as redactObjectValues, g as now, h as safeDecode, it as BrowserSpanType, j as Attributes, k as AnyValue, l as describeRejectionReason, m as resolveDenylist, n as urlAttributes, nt as User, o as SafeCloneOptions, ot as FrameworkName, p as redactUrlQuery, q as SdkInfo, r as toCustomContext, rt as BrowserSpanEventType, s as safeClone, tt as TracesSampler, u as routeRejection, v as glowsToEvents, w as convertToError, x as evictLruIfNew, y as flatJsonStringify, z as KeyValue } from "./urlAttributes-CU2Yr37w.cjs";
2
2
 
3
3
  //#region src/api/Api.d.ts
4
4
  declare class Api {
@@ -6,8 +6,7 @@ declare class Api {
6
6
  private pendingKeepaliveRequests;
7
7
  /**
8
8
  * How many keepalive bytes are still available. Logs and traces share one browser allowance and both
9
- * flush on page hide, so whichever goes second has to pack against what is left rather than assume the
10
- * whole budget, or it exceeds the gate in send() and silently degrades to a cancellable fetch.
9
+ * flush on page hide, so whichever goes second must pack against what is left, not the whole budget.
11
10
  */
12
11
  keepaliveBudgetRemaining(): number;
13
12
  report(report: Report, url: string, key: string | null, reportBrowserExtensionErrors: boolean, debug?: boolean): Promise<void>;
@@ -127,14 +126,13 @@ declare function readLinesFromFile(fileText: string, lineNumber: number, columnN
127
126
  interface ActiveSpanHolder {
128
127
  getActive(): Span | undefined;
129
128
  /**
130
- * Run `fn` with `span` active, restoring the prior active span afterward. A callback (not a bare setter) so a Node
131
- * holder can back it with AsyncLocalStorage.run(...) to preserve async-scoped context.
129
+ * Runs `fn` with `span` active, then restores the previous active span. Takes a callback, not a
130
+ * setter, so a Node holder can implement it with `AsyncLocalStorage.run(...)`.
132
131
  */
133
132
  withActive<T>(span: Span, fn: () => T): T;
134
133
  /**
135
- * Persistent "active root" that getActive() falls back to when no withActive scope is on the stack. Used by
136
- * long-lived pageload/navigation roots so child spans (e.g. fetches) auto-parent to them. Optional; a holder that
137
- * omits it simply has no active-root support.
134
+ * Fallback span that getActive() returns when no withActive scope is active. Long-lived
135
+ * pageload/navigation roots use it so child spans auto-parent to them. Optional.
138
136
  */
139
137
  setActiveRoot?(span: Span | undefined): void;
140
138
  }
@@ -187,10 +185,9 @@ declare class Tracer {
187
185
  getActiveSpan(): Span | undefined;
188
186
  setActiveRoot(span?: Span): void;
189
187
  /**
190
- * Take one span against `traceId`'s cap up front, for a caller that publishes a span id before the
191
- * span exists (the component profilers do; their descendants record first). False means the trace is
192
- * full and the caller should stay transparent instead of handing out an id the cap will refuse.
193
- * Consumed by the matching `startSpan({ claimed: true })`.
188
+ * Claims a span slot before the span exists, for a caller that publishes a span id early (the
189
+ * component profilers do; their descendants record first). Returns false when the trace is full.
190
+ * Paired with `startSpan({ claimed: true })`.
194
191
  */
195
192
  claimSpanSlot(traceId: string): boolean;
196
193
  addSpanListener(fn: SpanLifecycleListener): () => void;
@@ -201,20 +198,20 @@ declare class Tracer {
201
198
  clear(): void;
202
199
  continueFromTraceparent(header: string): void;
203
200
  /**
204
- * Runs `fn` with the span active, so spans started inside auto-parent to it, then ends it.
201
+ * Runs `fn` with the span active, so spans started inside it auto-parent to it, then ends the span.
205
202
  * Records an error status first if `fn` throws or its returned promise rejects.
206
203
  */
207
204
  withSpan<T>(name: string, fn: (span: Span) => T, opts?: SpanOptions): T;
208
- /** Starts a span the caller must end. Unlike `withSpan`, it does not become the active span,
209
- * so spans started after it do not auto-parent to it. */
205
+ /**
206
+ * Starts a span the caller must end. Unlike `withSpan`, it does not become the active span, so spans
207
+ * started after it do not auto-parent to it.
208
+ */
210
209
  startSpan(name: string, opts?: SpanOptions): Span;
211
- /** A real Span handle that records nothing, so callers never have to branch on whether tracing is on. */
212
210
  private startInertSpan;
213
211
  private resolveTrace;
214
212
  private getOrSeedState;
215
213
  private createState;
216
214
  private makeSpan;
217
- /** Bounded, LRU by insertion order, like traceStates. Holds primitives only, never a span. */
218
215
  private rememberClosed;
219
216
  private onSpanEnd;
220
217
  }
@@ -246,22 +243,13 @@ declare class Flare {
246
243
  * default; a platform can back it with AsyncLocalStorage instead.
247
244
  */
248
245
  constructor(api?: Api, contextCollector?: ContextCollector, fileReader?: FileReader, scopeProvider?: ScopeProvider, scheduler?: FlushScheduler, activeSpanHolder?: ActiveSpanHolder);
249
- /**
250
- * Register an in-flight report so `flush()` can wait for it. Every entry point wraps its whole async
251
- * pipeline, from beforeEvaluate through api.report, so flush() waits on all of it.
252
- *
253
- * What goes in the Set is a shadow promise that mirrors `p`'s timing but cannot reject, so a failed
254
- * report never surfaces as an unhandled rejection warning. `p` itself is returned untouched, so the
255
- * caller still observes real success or failure.
256
- */
257
246
  private track;
258
247
  /**
259
- * Wait until every in-flight report settles or `timeoutMs` elapses. Always resolves, never rejects.
260
- * Written for `@flareapp/node`'s fatal handler, which awaits the fatal report itself then flushes to
261
- * drain any other concurrent reports before `process.exit`.
248
+ * Waits until every in-flight report settles, or `timeoutMs` elapses. Always resolves, never rejects.
249
+ * Used by `@flareapp/node`'s fatal handler to drain other reports before `process.exit`.
262
250
  *
263
- * Snapshotting the Set bounds the wait: reports started after this line are not awaited, so a handler
264
- * that keeps emitting during shutdown cannot block the process forever. Call flush again for those.
251
+ * Only reports already in flight are awaited, so a handler still emitting during shutdown cannot block
252
+ * forever. Call flush again to catch those.
265
253
  */
266
254
  flush(timeoutMs?: number): Promise<void>;
267
255
  get config(): Readonly<Config>;
@@ -298,10 +286,6 @@ declare class Flare {
298
286
  setEntryPoint(handler: EntryPointHandler): this;
299
287
  setSdkInfo(info: SdkInfo): this;
300
288
  setFramework(framework: Framework): this;
301
- /**
302
- * True when a report must not be captured: consent withdrawn, or dropped by sampling. Consent is
303
- * checked first, so a blocked report never runs the sampler or assembles a report (no cookie read).
304
- */
305
289
  private shouldSkipCapture;
306
290
  report(error: Error, attributes?: Attributes): Promise<void>;
307
291
  private reportInternal;
@@ -314,15 +298,6 @@ declare class Flare {
314
298
  private buildBaseAttributes;
315
299
  private assembleAttributes;
316
300
  private buildLogAttributes;
317
- /**
318
- * Local roots only, snapshotted by the Tracer at span START so a long-lived root does not drift into
319
- * the next page's scope. Children get none, and no span ever runs the DOM collector.
320
- *
321
- * Everything assembled is inherited except user identity (excluding the opaque `user.id`): a root span
322
- * goes out for every page view, so email, full name, IP and `user.attributes` would turn normal
323
- * browsing into PII traffic. The rest — `context.custom`, `addContextGroup` bags — stays in, because
324
- * the trace viewer renders any span attribute whose key does not start with `flare.`.
325
- */
326
301
  private getScopeAttributes;
327
302
  private spanResourceAttributes;
328
303
  private buildReport;
@@ -350,11 +325,9 @@ declare function spanId(): string;
350
325
  //#endregion
351
326
  //#region src/stacktrace/NullFileReader.d.ts
352
327
  /**
353
- * No-op `FileReader` returning `null` for every URL. Default for `Flare`'s `fileReader` param so `new Flare()` builds
354
- * reports without picking an environment; stack frames just omit source snippets. Consumer packages inject the real
355
- * ones: `@flareapp/js` a fetch-based reader, `@flareapp/node` a disk reader. The `read(url) -> Promise<string | null>`
356
- * interface lets the stack-trace builder treat all three the same (render on text, skip on null), so core needs no
357
- * environment checks.
328
+ * No-op `FileReader` returning `null` for every URL. Default for `Flare`'s `fileReader` param, so
329
+ * `new Flare()` builds reports without picking an environment; stack frames just omit source snippets.
330
+ * `@flareapp/js` and `@flareapp/node` inject a real fetch- or disk-based reader instead.
358
331
  */
359
332
  declare class NullFileReader implements FileReader {
360
333
  read(_url: string): Promise<string | null>;
@@ -422,4 +395,4 @@ declare function buildDeviceContextGroup(info: DeviceInfo): Record<string, Attri
422
395
  //#region src/stacktrace/createStackTrace.d.ts
423
396
  declare function createStackTrace(error: Error, debug: boolean, fileReader: FileReader): Promise<Array<StackFrame>>;
424
397
  //#endregion
425
- export { type ActiveSpanHolder, type AnyValue, Api, type AttributeValue, type Attributes, BrowserSpanEventType, BrowserSpanType, type BufferedLog, type BufferedSpan, type Config, type ContextCollector, DEFAULT_MAX_LIVE_TRACES, DEFAULT_URL_DENYLIST, type DeviceInfo, type DeviceInfoProvider, type EffectiveConnectionType, type EntryPointHandler, type EntryPointType, type FileReader, Flare, type FlushFn, type FlushScheduler, type Framework, FrameworkName, GlobalScopeProvider, type Glow, InMemoryActiveSpanHolder, type KeyValue, Logger, type LoggerDeps, type LogsEnvelope, MAX_BREADCRUMB_URL_LENGTH, type MessageLevel, NoopFlushScheduler, NullDeviceInfoProvider, NullFileReader, type OtelLogRecord, type OtelSpan, type OverriddenGrouping, type RejectionReporter, type Report, type SafeCloneOptions, type SamplingContext, Scope, type ScopeProvider, type SdkInfo, type SdkTaggable, type Span, type SpanEvent, type SpanLifecycleEvent, type SpanLifecycleListener, type SpanOptions, type SpanPhase, type SpanStatus, SpanStatusCode, type SpanTypeName, type StackFrame, Tracer, type TracerDeps, type TracesEnvelope, type TracesSampler, USER_IDENTITY_KEYS, type User, assert, assertKey, breadcrumbUrl, buildDeviceContextGroup, buildTraceparent, buildTracesEnvelope, convertToError, createIdentityTagger, createStackTrace, defaultNowNano, describeRejectionReason, deviceInfoToAttributes, extractCode, flatJsonStringify, getCodeSnippet, glowsToEvents, now, parseTraceparent, readLinesFromFile, recordBreadcrumb, redactObjectValues, redactUrlQuery, resolveDenylist, routeRejection, safeClone, safeDecode, spanId, toCustomContext, urlAttributes, userIdentityAttributes };
398
+ export { type ActiveSpanHolder, type AnyValue, Api, type AttributeValue, type Attributes, BrowserSpanEventType, BrowserSpanType, type BufferedLog, type BufferedSpan, type Config, type ContextCollector, DEFAULT_MAX_LIVE_TRACES, DEFAULT_URL_DENYLIST, type DeviceInfo, type DeviceInfoProvider, type EffectiveConnectionType, type EntryPointHandler, type EntryPointType, type FileReader, Flare, type FlushFn, type FlushScheduler, type Framework, FrameworkName, GlobalScopeProvider, type Glow, InMemoryActiveSpanHolder, type KeyValue, Logger, type LoggerDeps, type LogsEnvelope, MAX_BREADCRUMB_URL_LENGTH, type MessageLevel, NoopFlushScheduler, NullDeviceInfoProvider, NullFileReader, type OtelLogRecord, type OtelSpan, type OverriddenGrouping, type RejectionReporter, type Report, type SafeCloneOptions, type SamplingContext, Scope, type ScopeProvider, type SdkInfo, type SdkTaggable, type Span, type SpanEvent, type SpanLifecycleEvent, type SpanLifecycleListener, type SpanOptions, type SpanPhase, type SpanStatus, SpanStatusCode, type SpanTypeName, type StackFrame, Tracer, type TracerDeps, type TracesEnvelope, type TracesSampler, USER_IDENTITY_KEYS, type User, assert, assertKey, breadcrumbUrl, buildDeviceContextGroup, buildTraceparent, buildTracesEnvelope, convertToError, createIdentityTagger, createStackTrace, defaultNowNano, describeRejectionReason, deviceInfoToAttributes, evictLruIfNew, extractCode, flatJsonStringify, getCodeSnippet, glowsToEvents, now, parseTraceparent, readLinesFromFile, recordBreadcrumb, redactObjectValues, redactUrlQuery, resolveDenylist, routeRejection, safeClone, safeDecode, spanId, toCustomContext, urlAttributes, userIdentityAttributes };