@fixback/sdk-core 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +28 -9
  2. package/{src/annotation.ts → dist/annotation.d.ts} +36 -47
  3. package/dist/anonymous-id.d.ts +23 -0
  4. package/dist/anonymous-id.js +39 -0
  5. package/dist/anonymous-id.js.map +1 -0
  6. package/dist/auto-capture.d.ts +129 -0
  7. package/dist/auto-capture.js +210 -0
  8. package/dist/auto-capture.js.map +1 -0
  9. package/{src/backoff.ts → dist/backoff.d.ts} +17 -52
  10. package/dist/boot.d.ts +148 -0
  11. package/dist/boot.js +113 -0
  12. package/dist/boot.js.map +1 -0
  13. package/dist/breadcrumb.d.ts +133 -0
  14. package/dist/connect.d.ts +110 -0
  15. package/dist/connect.js +147 -0
  16. package/dist/connect.js.map +1 -0
  17. package/dist/env.d.ts +37 -0
  18. package/dist/env.js +83 -0
  19. package/dist/env.js.map +1 -0
  20. package/dist/fingerprint.d.ts +39 -0
  21. package/dist/fingerprint.js +10 -15
  22. package/dist/fingerprint.js.map +1 -1
  23. package/dist/http.d.ts +51 -0
  24. package/dist/http.js +42 -0
  25. package/dist/http.js.map +1 -0
  26. package/dist/index.d.ts +28 -0
  27. package/dist/index.js +115 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/index.mjs +1057 -0
  30. package/dist/index.mjs.map +7 -0
  31. package/dist/options.d.ts +82 -0
  32. package/dist/options.js +22 -0
  33. package/dist/options.js.map +1 -0
  34. package/dist/release.d.ts +19 -0
  35. package/dist/release.js +36 -0
  36. package/dist/release.js.map +1 -0
  37. package/dist/scrub.d.ts +62 -0
  38. package/dist/stack.d.ts +51 -0
  39. package/dist/stack.js +97 -0
  40. package/dist/stack.js.map +1 -0
  41. package/dist/trace/buffer.d.ts +121 -0
  42. package/dist/trace/buffer.js +230 -0
  43. package/dist/trace/buffer.js.map +1 -0
  44. package/dist/trace/console-args.d.ts +60 -0
  45. package/dist/trace/console-args.js +189 -0
  46. package/dist/trace/console-args.js.map +1 -0
  47. package/dist/trace/console.d.ts +42 -0
  48. package/dist/trace/console.js +71 -0
  49. package/dist/trace/console.js.map +1 -0
  50. package/dist/trace/crumbs.d.ts +88 -0
  51. package/dist/trace/crumbs.js +164 -0
  52. package/dist/trace/crumbs.js.map +1 -0
  53. package/dist/trace/source.d.ts +30 -0
  54. package/dist/trace/source.js +59 -0
  55. package/dist/trace/source.js.map +1 -0
  56. package/dist/version.d.ts +13 -0
  57. package/dist/version.js +17 -0
  58. package/dist/version.js.map +1 -0
  59. package/dist/wire.d.ts +101 -0
  60. package/package.json +12 -8
  61. package/src/backoff.test.ts +0 -94
  62. package/src/breadcrumb.ts +0 -169
  63. package/src/fingerprint.test.ts +0 -96
  64. package/src/fingerprint.ts +0 -112
  65. package/src/index.ts +0 -63
  66. package/src/scrub.test.ts +0 -215
  67. package/src/scrub.ts +0 -226
  68. package/src/wire.ts +0 -116
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ /**
3
+ * The **Connect** wire contract (ADR-0032, CONTEXT.md "Connect") — the one copy every
4
+ * capture SDK speaks, kept in the shared core beside the boot contract for the same
5
+ * reason (`@fixback/shared` is server-shaped and private, ticket #47).
6
+ *
7
+ * Connect is the round trip that binds an Account to a site: the SDK opens the
8
+ * platform's connect page ({@link BootAnswer.connectUrl}), the person signs in, the
9
+ * page hands back a **one-time code**, and the SDK exchanges it here for a **Reporter
10
+ * session** — a compact token it stores per origin and forwards on every boot. Keep
11
+ * this in lock-step with the server: `POST /api/connect/exchange` and
12
+ * `POST /api/connect/signout` (`apps/api/src/connect/*`).
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CONNECT_RETURN_PARAM = exports.CONNECT_MESSAGE_SOURCE = void 0;
16
+ exports.connectExchangeEndpoint = connectExchangeEndpoint;
17
+ exports.connectSignOutEndpoint = connectSignOutEndpoint;
18
+ exports.buildConnectUrl = buildConnectUrl;
19
+ exports.reporterSessionStorageKey = reporterSessionStorageKey;
20
+ exports.parseConnectMessage = parseConnectMessage;
21
+ exports.isConnectExchangeResponse = isConnectExchangeResponse;
22
+ exports.exchangeConnectCode = exchangeConnectCode;
23
+ exports.revokeReporterSession = revokeReporterSession;
24
+ const http_1 = require("./http");
25
+ /**
26
+ * The `postMessage` a connect page in a popup sends back to the opener. `source`
27
+ * pins it to Fixback so an unrelated message on the window is ignored; `code` is the
28
+ * one-time Connect code to exchange. Read with {@link parseConnectMessage}.
29
+ */
30
+ exports.CONNECT_MESSAGE_SOURCE = "fixback-connect";
31
+ /**
32
+ * The query parameter a Fixback link — and the connect page's **redirect fallback** —
33
+ * carries the one-time code back on, when a popup could not be used (ADR-0032,
34
+ * "arriving with the `fixback` query parameter"). The SDK detects it on boot, exchanges
35
+ * it, and strips it from the URL.
36
+ */
37
+ exports.CONNECT_RETURN_PARAM = "fixback";
38
+ /** Join an API base URL with the Connect exchange path, tolerating a trailing slash. */
39
+ function connectExchangeEndpoint(apiUrl) {
40
+ return `${apiUrl.replace(/\/+$/, "")}/api/connect/exchange`;
41
+ }
42
+ /** Join an API base URL with the Connect sign-out path, tolerating a trailing slash. */
43
+ function connectSignOutEndpoint(apiUrl) {
44
+ return `${apiUrl.replace(/\/+$/, "")}/api/connect/signout`;
45
+ }
46
+ /**
47
+ * Build the connect-page URL the SDK opens (popup or redirect). `connectUrl` is the
48
+ * base the boot answer carried; `key` identifies the Project and `returnUrl` is where
49
+ * the person is sent back — validated server-side against the Project's allowed
50
+ * origins, so a hostile page cannot redirect the code anywhere else.
51
+ */
52
+ function buildConnectUrl(connectUrl, params) {
53
+ // Built with `encodeURIComponent` rather than `URLSearchParams`/`URL` so the
54
+ // runtime-agnostic core needs no DOM lib (it runs on web, Expo, and Node alike).
55
+ const base = connectUrl.split("#")[0] ?? connectUrl;
56
+ const sep = base.includes("?") ? "&" : "?";
57
+ const query = `key=${encodeURIComponent(params.key)}` +
58
+ `&return=${encodeURIComponent(params.returnUrl)}`;
59
+ return `${base}${sep}${query}`;
60
+ }
61
+ /**
62
+ * The `localStorage` key a browser SDK stores its Reporter session token under,
63
+ * **scoped by publishable key** so two Fixback Projects on one origin keep separate
64
+ * sessions (ADR-0032). The storage binding is per-runtime; the key format is shared.
65
+ */
66
+ function reporterSessionStorageKey(publishableKey) {
67
+ return `fixback.reporterSession.${publishableKey}`;
68
+ }
69
+ /**
70
+ * Narrow an unknown `message.data` to the Connect code it carries, or `null`. Guards
71
+ * `source` so an unrelated `postMessage` — the web is noisy — is ignored.
72
+ */
73
+ function parseConnectMessage(data) {
74
+ if (typeof data !== "object" || data === null)
75
+ return null;
76
+ const v = data;
77
+ if (v.source !== exports.CONNECT_MESSAGE_SOURCE)
78
+ return null;
79
+ return typeof v.code === "string" && v.code.length > 0 ? v.code : null;
80
+ }
81
+ /** Narrow an unknown JSON body to a {@link ConnectExchangeResponse}. */
82
+ function isConnectExchangeResponse(value) {
83
+ if (typeof value !== "object" || value === null)
84
+ return false;
85
+ const v = value;
86
+ if (typeof v.reporterSession !== "string" || v.reporterSession.length === 0) {
87
+ return false;
88
+ }
89
+ const account = v.account;
90
+ return (typeof account === "object" &&
91
+ account !== null &&
92
+ typeof account.name === "string" &&
93
+ typeof account.email === "string");
94
+ }
95
+ /**
96
+ * Exchange a one-time code for a Reporter session. Resolves to the response, or `null`
97
+ * when Fixback was unreachable, the code was refused, or the body was not a valid
98
+ * response — the caller stays anonymous rather than surfacing an error into the host
99
+ * page (ticket #47: "fails quietly").
100
+ */
101
+ async function exchangeConnectCode(apiUrl, request, deps = {}) {
102
+ const doFetch = deps.fetch ?? (0, http_1.resolveFetch)();
103
+ if (!doFetch)
104
+ return null;
105
+ let response;
106
+ try {
107
+ response = await doFetch(connectExchangeEndpoint(apiUrl), {
108
+ method: "POST",
109
+ headers: { "content-type": "application/json" },
110
+ body: JSON.stringify(request),
111
+ });
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ if (!response.ok)
117
+ return null;
118
+ let body;
119
+ try {
120
+ body = await response.json?.();
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ return isConnectExchangeResponse(body) ? body : null;
126
+ }
127
+ /**
128
+ * Revoke a Reporter session server-side ("sign out"). Best-effort: a network failure
129
+ * still lets the SDK clear its stored token locally, and a revoked-anyway token is
130
+ * refused at the next boot regardless.
131
+ */
132
+ async function revokeReporterSession(apiUrl, token, deps = {}) {
133
+ const doFetch = deps.fetch ?? (0, http_1.resolveFetch)();
134
+ if (!doFetch)
135
+ return;
136
+ try {
137
+ await doFetch(connectSignOutEndpoint(apiUrl), {
138
+ method: "POST",
139
+ headers: { "content-type": "application/json" },
140
+ body: JSON.stringify({ reporterSession: token }),
141
+ });
142
+ }
143
+ catch {
144
+ // Best-effort: the local token is cleared by the caller regardless.
145
+ }
146
+ }
147
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The **runtime probes** every capture SDK shares (ADR-0028): a high-res clock and
3
+ * the three byte-measuring helpers, written against `globalThis` alone so one
4
+ * implementation serves the browser, React Native, and Node.
5
+ *
6
+ * Each probe reads its global defensively — `performance`, `TextEncoder`, `Blob`
7
+ * and `ArrayBuffer` are all optional here — and falls back rather than throwing, so
8
+ * a runtime missing one of them degrades to a coarser measurement instead of
9
+ * breaking capture. Nothing in this module reads a body's *content*: a size is
10
+ * taken only when it is trivially known (spec #122 §D).
11
+ */
12
+ /**
13
+ * A high-res monotonic timestamp: `performance.now()` where the runtime offers it
14
+ * (browsers and React Native both do), else `Date.now()`. Used to order trace
15
+ * entries across streams and to measure request durations as a delta.
16
+ */
17
+ export declare function nowMono(): number;
18
+ /**
19
+ * A string's UTF-8 byte length, measured with `TextEncoder` when available and
20
+ * falling back to the UTF-16 code-unit count otherwise. Never throws — the
21
+ * fallback is an approximation, not an error.
22
+ */
23
+ export declare function utf8ByteLength(value: string): number;
24
+ /**
25
+ * The serialized UTF-8 byte length of a value; `Infinity` when it cannot be
26
+ * serialized at all. The cap helpers use it to bound what a single entry may
27
+ * carry, so an unserializable value is treated as over budget rather than shipped.
28
+ */
29
+ export declare function serializedBytes(value: unknown): number;
30
+ /**
31
+ * The trivially-known byte size of a request body (spec #122 §D) — a string's
32
+ * UTF-8 length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`.
33
+ * Anything that would require **reading** the body (a `ReadableStream`, `FormData`,
34
+ * a `Request` with a stream body) returns `undefined` — the "never read the body"
35
+ * line holds.
36
+ */
37
+ export declare function trivialBodySize(body: unknown): number | undefined;
package/dist/env.js ADDED
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * The **runtime probes** every capture SDK shares (ADR-0028): a high-res clock and
4
+ * the three byte-measuring helpers, written against `globalThis` alone so one
5
+ * implementation serves the browser, React Native, and Node.
6
+ *
7
+ * Each probe reads its global defensively — `performance`, `TextEncoder`, `Blob`
8
+ * and `ArrayBuffer` are all optional here — and falls back rather than throwing, so
9
+ * a runtime missing one of them degrades to a coarser measurement instead of
10
+ * breaking capture. Nothing in this module reads a body's *content*: a size is
11
+ * taken only when it is trivially known (spec #122 §D).
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.nowMono = nowMono;
15
+ exports.utf8ByteLength = utf8ByteLength;
16
+ exports.serializedBytes = serializedBytes;
17
+ exports.trivialBodySize = trivialBodySize;
18
+ /**
19
+ * A high-res monotonic timestamp: `performance.now()` where the runtime offers it
20
+ * (browsers and React Native both do), else `Date.now()`. Used to order trace
21
+ * entries across streams and to measure request durations as a delta.
22
+ */
23
+ function nowMono() {
24
+ const perf = globalThis.performance;
25
+ return perf && typeof perf.now === "function" ? perf.now() : Date.now();
26
+ }
27
+ /** The `TextEncoder` constructor, when the runtime provides one. */
28
+ function textEncoder() {
29
+ return globalThis.TextEncoder;
30
+ }
31
+ /**
32
+ * A string's UTF-8 byte length, measured with `TextEncoder` when available and
33
+ * falling back to the UTF-16 code-unit count otherwise. Never throws — the
34
+ * fallback is an approximation, not an error.
35
+ */
36
+ function utf8ByteLength(value) {
37
+ try {
38
+ const Encoder = textEncoder();
39
+ return Encoder ? new Encoder().encode(value).length : value.length;
40
+ }
41
+ catch {
42
+ return value.length;
43
+ }
44
+ }
45
+ /**
46
+ * The serialized UTF-8 byte length of a value; `Infinity` when it cannot be
47
+ * serialized at all. The cap helpers use it to bound what a single entry may
48
+ * carry, so an unserializable value is treated as over budget rather than shipped.
49
+ */
50
+ function serializedBytes(value) {
51
+ try {
52
+ const json = JSON.stringify(value) ?? "";
53
+ return utf8ByteLength(json);
54
+ }
55
+ catch {
56
+ return Number.POSITIVE_INFINITY;
57
+ }
58
+ }
59
+ /**
60
+ * The trivially-known byte size of a request body (spec #122 §D) — a string's
61
+ * UTF-8 length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`.
62
+ * Anything that would require **reading** the body (a `ReadableStream`, `FormData`,
63
+ * a `Request` with a stream body) returns `undefined` — the "never read the body"
64
+ * line holds.
65
+ */
66
+ function trivialBodySize(body) {
67
+ if (typeof body === "string")
68
+ return utf8ByteLength(body);
69
+ // `Blob` is optional here (the core compiles without the DOM lib) and its real
70
+ // constructor takes arguments, so the probe is read through `unknown` and only
71
+ // ever used as an `instanceof` right-hand side.
72
+ const BlobCtor = globalThis.Blob;
73
+ if (BlobCtor && body instanceof BlobCtor)
74
+ return body.size;
75
+ if (typeof ArrayBuffer !== "undefined") {
76
+ if (body instanceof ArrayBuffer)
77
+ return body.byteLength;
78
+ if (ArrayBuffer.isView(body))
79
+ return body.byteLength;
80
+ }
81
+ return undefined;
82
+ }
83
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAOH,0BAGC;AAkBD,wCAOC;AAOD,0CAOC;AASD,0CAgBC;AAxED;;;;GAIG;AACH,SAAgB,OAAO;IACrB,MAAM,IAAI,GAAI,UAAuD,CAAC,WAAW,CAAC;IAClF,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAC1E,CAAC;AAED,oEAAoE;AACpE,SAAS,WAAW;IAGlB,OACE,UAGD,CAAC,WAAW,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1D,+EAA+E;IAC/E,+EAA+E;IAC/E,gDAAgD;IAChD,MAAM,QAAQ,GACZ,UAGD,CAAC,IAAI,CAAC;IACP,IAAI,QAAQ,IAAI,IAAI,YAAY,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC3D,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,IAAI,IAAI,YAAY,WAAW;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACxD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAQ,IAAwB,CAAC,UAAU,CAAC;IAC5E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The cross-surface error **fingerprint** (research `sentry-error-capture-findings.md`
3
+ * §7.2; ADR-0027/0028) — the pure, runtime-agnostic key by which the same logical
4
+ * error groups together, computed the **same way** on every SDK.
5
+ *
6
+ * `computeFingerprint(type, value, stack)` hashes the error type, a normalised
7
+ * message, and a compact top-frames signature. It only has to be stable and
8
+ * well-distributed (the client key is a flood guard; the server does canonical
9
+ * cross-session clustering), so a dependency-free FNV-1a hash is right. The
10
+ * `normalize` shape and the frame limit are **starting points** from research
11
+ * (ticket #92), tunable — never a frozen magic set.
12
+ */
13
+ /**
14
+ * Collapse the volatile parts of an error message so a changing string doesn't
15
+ * split one bug: UUIDs, URLs, `0x…` and long hex runs, and long digit runs are
16
+ * replaced with stable placeholders. Short numbers and stable text are kept so
17
+ * genuinely distinct bugs stay distinct. A small, dependency-free regex set —
18
+ * tunable per ticket #92, never a frozen magic set.
19
+ */
20
+ export declare function normalize(value: string): string;
21
+ /**
22
+ * A dependency-free FNV-1a hash rendered in base-36. It only has to be stable and
23
+ * well-distributed within one session (the client key is a flood guard; the server
24
+ * does canonical cross-session clustering), so a non-cryptographic hash is right.
25
+ */
26
+ export declare function hashString(input: string): string;
27
+ /**
28
+ * Extract a compact, stable signature of the top in-app frames of a stack: up to
29
+ * {@link FINGERPRINT_FRAME_LIMIT} frames as `function@basename:line:col`, origin
30
+ * and cache-busting query stripped so a per-deploy asset hash doesn't matter within
31
+ * a session. Returns `""` when there is no usable stack (message-only fallback).
32
+ */
33
+ export declare function extractTopFrames(stack: string | undefined, limit?: number): string;
34
+ /**
35
+ * The per-session fingerprint (research §7.2):
36
+ * `hash(errorType + "|" + normalize(value) + "|" + topFrames)`. Stack frames
37
+ * dominate when present; otherwise it falls back to type + normalized value.
38
+ */
39
+ export declare function computeFingerprint(type: string, value: string, stack?: string): string;
@@ -16,6 +16,7 @@ exports.normalize = normalize;
16
16
  exports.hashString = hashString;
17
17
  exports.extractTopFrames = extractTopFrames;
18
18
  exports.computeFingerprint = computeFingerprint;
19
+ const stack_1 = require("./stack");
19
20
  const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
20
21
  const URL_RE = /\bhttps?:\/\/[^\s"')]+/gi;
21
22
  const HEX_0X_RE = /\b0x[0-9a-f]+\b/gi;
@@ -60,22 +61,16 @@ function compactLocation(location) {
60
61
  const lastSlash = noQuery.lastIndexOf("/");
61
62
  return lastSlash >= 0 ? noQuery.slice(lastSlash + 1) : noQuery;
62
63
  }
63
- /** Parse one stack line into a compact `function@basename:line:col` frame id. */
64
+ /**
65
+ * Reduce one stack line to a compact `function@basename:line:col` frame id, using
66
+ * the core's single frame tokenizer (`stack.ts`) so the fingerprint sees exactly
67
+ * the frames every other stack reader does.
68
+ */
64
69
  function parseFrame(line) {
65
- // V8: "at fn (loc)" | "at loc"
66
- const v8Named = line.match(/^at\s+(.+?)\s+\((.+)\)$/);
67
- if (v8Named)
68
- return `${v8Named[1] ?? ""}@${compactLocation(v8Named[2] ?? "")}`;
69
- const v8Bare = line.match(/^at\s+(.+)$/);
70
- if (v8Bare)
71
- return `@${compactLocation(v8Bare[1] ?? "")}`;
72
- // Firefox / Safari: "fn@loc" | "@loc"
73
- const at = line.indexOf("@");
74
- if (at >= 0) {
75
- const fn = line.slice(0, at);
76
- return `${fn}@${compactLocation(line.slice(at + 1))}`;
77
- }
78
- return null;
70
+ const tokens = (0, stack_1.parseStackLine)(line);
71
+ if (!tokens)
72
+ return null;
73
+ return `${tokens.fn ?? ""}@${compactLocation(tokens.location)}`;
79
74
  }
80
75
  /**
81
76
  * Extract a compact, stable signature of the top in-app frames of a stack: up to
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The **structural HTTP surface** every Fixback SDK talks to ingest through
3
+ * (ADR-0028) — one description of the `fetch` slice the transports use, shared by
4
+ * the browser, Expo, and Node SDKs.
5
+ *
6
+ * Described structurally rather than against the DOM lib: the core typechecks with
7
+ * `types: []` and no `lib.dom`, React Native is not a browser, and Node's `fetch`
8
+ * is a global with its own types. Every runtime satisfies these shapes at runtime,
9
+ * and tests inject plain fakes through the same seams. Only what the SDKs actually
10
+ * read is described — status, `ok`, one header at a time, and an optional JSON body.
11
+ */
12
+ /**
13
+ * The response slice the transports read: the outcome, the status, the header bag
14
+ * (for `Retry-After` / `content-length`), and — for the endpoints that answer with
15
+ * JSON — the parsed body. `json()` is **optional**: the batched Node transport
16
+ * never reads a body, so a fake need not provide one.
17
+ */
18
+ export interface FetchResponseLike {
19
+ readonly ok: boolean;
20
+ readonly status: number;
21
+ readonly headers?: {
22
+ get(name: string): string | null;
23
+ } | null;
24
+ json?(): Promise<unknown>;
25
+ }
26
+ /** The request init the SDKs send — a method, plain headers, and a body. */
27
+ export interface FetchRequestInit {
28
+ readonly method: string;
29
+ readonly headers?: Record<string, string>;
30
+ /**
31
+ * The request body: a JSON string, or a runtime-specific multipart form (a
32
+ * browser `FormData`, React Native's `FormData`). Deliberately `unknown` — the
33
+ * core never inspects it, it only hands it to the runtime's `fetch`.
34
+ */
35
+ readonly body?: unknown;
36
+ }
37
+ /** A `fetch`-shaped function, injectable for tests. */
38
+ export type FetchLike = (url: string, init: FetchRequestInit) => Promise<FetchResponseLike>;
39
+ /**
40
+ * The runtime's global `fetch` adapted to {@link FetchLike}, or `undefined` when
41
+ * the runtime has none. Bound to `globalThis` so a `this`-less call never throws
42
+ * an "illegal invocation", and adapted through one cast here so no call site has
43
+ * to reconcile the runtime's own `fetch` types with the structural slice.
44
+ */
45
+ export declare function resolveFetch(): FetchLike | undefined;
46
+ /**
47
+ * Read one response header defensively — `null` when the response carries no
48
+ * header bag, the header is absent, or the getter throws (an opaque cross-origin
49
+ * response). A transport must never fail because a header could not be read.
50
+ */
51
+ export declare function safeHeader(response: FetchResponseLike, name: string): string | null;
package/dist/http.js ADDED
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * The **structural HTTP surface** every Fixback SDK talks to ingest through
4
+ * (ADR-0028) — one description of the `fetch` slice the transports use, shared by
5
+ * the browser, Expo, and Node SDKs.
6
+ *
7
+ * Described structurally rather than against the DOM lib: the core typechecks with
8
+ * `types: []` and no `lib.dom`, React Native is not a browser, and Node's `fetch`
9
+ * is a global with its own types. Every runtime satisfies these shapes at runtime,
10
+ * and tests inject plain fakes through the same seams. Only what the SDKs actually
11
+ * read is described — status, `ok`, one header at a time, and an optional JSON body.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.resolveFetch = resolveFetch;
15
+ exports.safeHeader = safeHeader;
16
+ /**
17
+ * The runtime's global `fetch` adapted to {@link FetchLike}, or `undefined` when
18
+ * the runtime has none. Bound to `globalThis` so a `this`-less call never throws
19
+ * an "illegal invocation", and adapted through one cast here so no call site has
20
+ * to reconcile the runtime's own `fetch` types with the structural slice.
21
+ */
22
+ function resolveFetch() {
23
+ const g = globalThis;
24
+ if (typeof g.fetch !== "function")
25
+ return undefined;
26
+ const bound = g.fetch.bind(globalThis);
27
+ return (url, init) => bound(url, init);
28
+ }
29
+ /**
30
+ * Read one response header defensively — `null` when the response carries no
31
+ * header bag, the header is absent, or the getter throws (an opaque cross-origin
32
+ * response). A transport must never fail because a header could not be read.
33
+ */
34
+ function safeHeader(response, name) {
35
+ try {
36
+ return response.headers?.get?.(name) ?? null;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAuCH,oCAOC;AAOD,gCAMC;AA1BD;;;;;GAKG;AACH,SAAgB,YAAY;IAC1B,MAAM,CAAC,GAAG,UAET,CAAC;IACF,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAA+B,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,QAA2B,EAAE,IAAY;IAClE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * `@fixback/sdk-core` — the runtime-agnostic core shared by the Fixback capture
3
+ * SDKs (ADR-0028). Fingerprinting, stack parsing, scrubbing, backoff, the trace
4
+ * buffer and its crumb builders, the automatic-capture state machine, the ingest
5
+ * boot contract, and the shared wire shapes — with no DOM, no Node built-ins, and
6
+ * no rrweb. Every runtime touchpoint is either injected or probed off `globalThis`.
7
+ */
8
+ export { SDK_CORE_VERSION } from "./version";
9
+ export { computeFingerprint, extractTopFrames, hashString, normalize } from "./fingerprint";
10
+ export { extractStructuredFrames, parseFrameLocation, parseStackLine, type StackFrameTokens, } from "./stack";
11
+ export { applyDefaultScrub, type BeforeSend, type BeforeSendOptions, redactPii, runBeforeSend, scrubUrl, } from "./scrub";
12
+ export { AutoReportBackoff, type Clock, DEFAULT_RETRY_AFTER_SECONDS, parseRetryAfter, } from "./backoff";
13
+ export { nowMono, serializedBytes, trivialBodySize, utf8ByteLength } from "./env";
14
+ export { type FetchLike, type FetchRequestInit, type FetchResponseLike, resolveFetch, safeHeader, } from "./http";
15
+ export { type BootAnswer, type BootDeps, bootEndpoint, type BootRequest, type CaptureConfig, compactIdentity, type ConnectedAccount, feedbackEndpoint, type IdentityInputs, isBootAnswer, isFixbackApiRequest, type ProjectGate, type ReporterTier, requestBoot, } from "./boot";
16
+ export { buildConnectUrl, CONNECT_MESSAGE_SOURCE, CONNECT_RETURN_PARAM, type ConnectDeps, type ConnectExchangeRequest, type ConnectExchangeResponse, type ConnectMessage, connectExchangeEndpoint, connectSignOutEndpoint, exchangeConnectCode, isConnectExchangeResponse, parseConnectMessage, type ReporterIdentity, reporterSessionStorageKey, revokeReporterSession, } from "./connect";
17
+ export { ANONYMOUS_ID_STORAGE_KEY, generateAnonymousId } from "./anonymous-id";
18
+ export { normaliseRelease, RELEASE_MAX_LENGTH } from "./release";
19
+ export { type CaptureToggles, type CommonCaptureInitOptions, type CommonInitOptions, DEFAULT_API_URL, } from "./options";
20
+ export { type AutoCaptureCore, type AutoCaptureCoreConfig, type AutoReport, asString, CAUSED_BY_LIMIT, createAutoCapture, DEFAULT_BURST_CAPACITY, DEFAULT_BURST_REFILL_MS, DEFAULT_MAX_DISTINCT_AUTO, type ExtractedError, precedingIds, TokenBucket, type TokenBucketOptions, } from "./auto-capture";
21
+ export { type BeforeBreadcrumb, type BreadcrumbBuffer, type BreadcrumbBufferConfig, capturesSource, createBreadcrumbBuffer, createIdFactory, DEFAULT_CONSOLE_LEVELS, DEFAULT_MAX_AGE_MS, DEFAULT_STREAM_BUDGETS, isPinnedConsoleLevel, normalizeBudget, PINNED_CONSOLE_LEVELS, SOURCE_CAPTURE_LEVELS, streamOf, type TraceStream, trimConsoleStream, } from "./trace/buffer";
22
+ export { capConsoleArgs, capLength, describeErrorValue, joinArgs, MAX_ARG_DEPTH, MAX_ARG_ITEMS, MAX_ARG_STRING_LENGTH, MAX_CONSOLE_ARGS_BYTES, MAX_MESSAGE_LENGTH, safeCloneValue, stringifyArg, toConsoleArg, } from "./trace/console-args";
23
+ export { consoleCrumb, contentTypeOf, describeError, errorCrumb, fetchCrumb, MAX_URL_LENGTH, navigationCrumb, type NetworkCrumbInput, networkCrumb, outcomeFromStatus, parseContentLength, xhrCrumb, } from "./trace/crumbs";
24
+ export { CONSOLE_SOURCE_SKIP_FRAMES, parseStackFrame, sourceFromStack, } from "./trace/source";
25
+ export { type ConsoleLike, instrumentConsole, type Teardown } from "./trace/console";
26
+ export type { CaptureEnvironment, CapturedFrame, FeedbackSource, Platform, ReportContent, } from "./wire";
27
+ export type { Annotation, ArrowMark, BoxMark, DrawTool, ElementRect, Mark, PenMark, Point, Rect, SelectedElement, TextMark, } from "./annotation";
28
+ export type { Breadcrumb, BreadcrumbCategory, BreadcrumbData, BreadcrumbLevel, ConsoleArg, ConsoleArgType, NetworkApi, NetworkOutcome, SourceLocation, } from "./breadcrumb";