@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,189 @@
1
+ "use strict";
2
+ /**
3
+ * Structured **console arguments** (spec #122 §C, decision D7) — the shared,
4
+ * runtime-agnostic assembly that turns a `console.*` call's arguments into
5
+ * type-tagged, JSON-safe, size-capped {@link ConsoleArg} values, plus the one-line
6
+ * preview the crumb's `message` carries.
7
+ *
8
+ * Preserving arguments type-tagged rather than flattening them to a string is what
9
+ * lets the Console tab render an object or an Error expandably instead of
10
+ * `[object Object]`. Every cap is applied **at assembly**, so a single console
11
+ * crumb can never bloat a report and an exotic or circular value can never reach
12
+ * the wire unserialized.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MAX_CONSOLE_ARGS_BYTES = exports.MAX_ARG_STRING_LENGTH = exports.MAX_ARG_ITEMS = exports.MAX_ARG_DEPTH = exports.MAX_MESSAGE_LENGTH = void 0;
16
+ exports.capLength = capLength;
17
+ exports.stringifyArg = stringifyArg;
18
+ exports.joinArgs = joinArgs;
19
+ exports.describeErrorValue = describeErrorValue;
20
+ exports.safeCloneValue = safeCloneValue;
21
+ exports.toConsoleArg = toConsoleArg;
22
+ exports.capConsoleArgs = capConsoleArgs;
23
+ const env_1 = require("../env");
24
+ /** Longest crumb message kept; a huge log line is truncated, never dropped. */
25
+ exports.MAX_MESSAGE_LENGTH = 300;
26
+ /**
27
+ * Structured console argument caps (spec #122 §C/§F), all applied **at assembly** so a
28
+ * single console crumb can never bloat a report:
29
+ * - {@link MAX_ARG_DEPTH} bounds how deep a `json` argument is cloned (deeper nodes
30
+ * collapse to an `[Object]`/`[Array]` marker);
31
+ * - {@link MAX_ARG_ITEMS} bounds how many keys/elements are kept at each level;
32
+ * - {@link MAX_ARG_STRING_LENGTH} truncates a single over-long string value;
33
+ * - {@link MAX_CONSOLE_ARGS_BYTES} bounds the serialized size of the whole args array
34
+ * (trailing args are dropped to fit), kept well under ingest's per-entry byte cap.
35
+ */
36
+ exports.MAX_ARG_DEPTH = 4;
37
+ exports.MAX_ARG_ITEMS = 100;
38
+ exports.MAX_ARG_STRING_LENGTH = 1024;
39
+ exports.MAX_CONSOLE_ARGS_BYTES = 4096;
40
+ /** Longest Error `stack` kept on a structured `error` arg, truncated never dropped. */
41
+ const MAX_ERROR_STACK_LENGTH = 2048;
42
+ /** Truncate a string to `max` with an ellipsis marker; keeps the value, never drops it. */
43
+ function capLength(value, max) {
44
+ return value.length > max ? `${value.slice(0, max)}…` : value;
45
+ }
46
+ /** Render one console argument to the flat text of the crumb's preview line. */
47
+ function stringifyArg(arg) {
48
+ if (typeof arg === "string")
49
+ return arg;
50
+ if (arg instanceof Error)
51
+ return `${arg.name}: ${arg.message}`;
52
+ if (arg === null || arg === undefined)
53
+ return String(arg);
54
+ if (typeof arg === "number" || typeof arg === "boolean")
55
+ return String(arg);
56
+ try {
57
+ return JSON.stringify(arg) ?? String(arg);
58
+ }
59
+ catch {
60
+ return "[object]";
61
+ }
62
+ }
63
+ /** The one-line preview a console crumb's `message` carries, length-capped. */
64
+ function joinArgs(args) {
65
+ const text = args.map(stringifyArg).join(" ");
66
+ return text.length > exports.MAX_MESSAGE_LENGTH
67
+ ? `${text.slice(0, exports.MAX_MESSAGE_LENGTH)}…`
68
+ : text;
69
+ }
70
+ /** An Error rendered to a structured, size-capped `{ name, message, stack? }`. */
71
+ function describeErrorValue(error) {
72
+ const out = {
73
+ name: error.name || "Error",
74
+ message: capLength(String(error.message ?? ""), exports.MAX_ARG_STRING_LENGTH),
75
+ };
76
+ if (typeof error.stack === "string" && error.stack.length > 0) {
77
+ out.stack = capLength(error.stack, MAX_ERROR_STACK_LENGTH);
78
+ }
79
+ return out;
80
+ }
81
+ /**
82
+ * Build a JSON-safe, depth-/breadth-/string-capped clone of a value for a `json`
83
+ * console argument. Beyond {@link MAX_ARG_DEPTH} the node collapses to a marker;
84
+ * at each level at most {@link MAX_ARG_ITEMS} keys/elements are kept; strings are
85
+ * truncated to {@link MAX_ARG_STRING_LENGTH}; circular references become
86
+ * `"[Circular]"`; and exotic values (bigint / symbol / function / undefined) are
87
+ * rendered to safe text — so the result is always serializable and bounded.
88
+ */
89
+ function safeCloneValue(value, depth, seen) {
90
+ if (value === null)
91
+ return null;
92
+ const type = typeof value;
93
+ if (type === "string")
94
+ return capLength(value, exports.MAX_ARG_STRING_LENGTH);
95
+ if (type === "number")
96
+ return Number.isFinite(value) ? value : String(value);
97
+ if (type === "boolean")
98
+ return value;
99
+ if (type === "bigint")
100
+ return `${value.toString()}n`;
101
+ if (type === "symbol")
102
+ return value.toString();
103
+ if (type === "function")
104
+ return "[Function]";
105
+ if (type === "undefined")
106
+ return null;
107
+ const obj = value;
108
+ if (value instanceof Error) {
109
+ const { name, message } = describeErrorValue(value);
110
+ return { name, message };
111
+ }
112
+ if (seen.has(obj))
113
+ return "[Circular]";
114
+ if (depth <= 0)
115
+ return Array.isArray(value) ? "[Array]" : "[Object]";
116
+ seen.add(obj);
117
+ try {
118
+ if (Array.isArray(value)) {
119
+ const items = value
120
+ .slice(0, exports.MAX_ARG_ITEMS)
121
+ .map((item) => safeCloneValue(item, depth - 1, seen));
122
+ if (value.length > exports.MAX_ARG_ITEMS) {
123
+ items.push(`… ${value.length - exports.MAX_ARG_ITEMS} more`);
124
+ }
125
+ return items;
126
+ }
127
+ const source = value;
128
+ const keys = Object.keys(source);
129
+ const out = {};
130
+ for (const key of keys.slice(0, exports.MAX_ARG_ITEMS)) {
131
+ const child = source[key];
132
+ // Undefined / function values JSON drops anyway — omit them for a clean clone.
133
+ if (typeof child === "undefined" || typeof child === "function")
134
+ continue;
135
+ out[key] = safeCloneValue(child, depth - 1, seen);
136
+ }
137
+ if (keys.length > exports.MAX_ARG_ITEMS)
138
+ out["…"] = `${keys.length - exports.MAX_ARG_ITEMS} more`;
139
+ return out;
140
+ }
141
+ finally {
142
+ seen.delete(obj);
143
+ }
144
+ }
145
+ /** Classify one console argument into a type-tagged {@link ConsoleArg} (spec #122 §C). */
146
+ function toConsoleArg(value) {
147
+ if (value === null || value === undefined)
148
+ return { t: "null", v: null };
149
+ const type = typeof value;
150
+ if (type === "string") {
151
+ return { t: "string", v: capLength(value, exports.MAX_ARG_STRING_LENGTH) };
152
+ }
153
+ if (type === "number") {
154
+ return Number.isFinite(value)
155
+ ? { t: "number", v: value }
156
+ : { t: "string", v: String(value) };
157
+ }
158
+ if (type === "boolean")
159
+ return { t: "bool", v: value };
160
+ if (type === "bigint")
161
+ return { t: "string", v: `${value.toString()}n` };
162
+ if (type === "symbol")
163
+ return { t: "string", v: value.toString() };
164
+ if (type === "function")
165
+ return { t: "string", v: "[Function]" };
166
+ if (value instanceof Error)
167
+ return { t: "error", v: describeErrorValue(value) };
168
+ return { t: "json", v: safeCloneValue(value, exports.MAX_ARG_DEPTH, new Set()) };
169
+ }
170
+ /**
171
+ * Cap an entry's structured args to {@link MAX_CONSOLE_ARGS_BYTES} (spec #122 §F):
172
+ * drop trailing args until the array fits, keeping the earliest (usually the format
173
+ * string / main message); if even a single arg is over budget, keep one honest
174
+ * placeholder rather than an unbounded value. Per-arg depth/breadth/string caps bound
175
+ * most cases already — this is the whole-entry backstop.
176
+ */
177
+ function capConsoleArgs(args) {
178
+ if ((0, env_1.serializedBytes)(args) <= exports.MAX_CONSOLE_ARGS_BYTES)
179
+ return args;
180
+ let out = args.slice();
181
+ while (out.length > 1 && (0, env_1.serializedBytes)(out) > exports.MAX_CONSOLE_ARGS_BYTES) {
182
+ out = out.slice(0, -1);
183
+ }
184
+ if (out.length === 1 && (0, env_1.serializedBytes)(out) > exports.MAX_CONSOLE_ARGS_BYTES) {
185
+ return [{ t: "string", v: "[trace: console argument omitted (too large)]" }];
186
+ }
187
+ return out;
188
+ }
189
+ //# sourceMappingURL=console-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console-args.js","sourceRoot":"","sources":["../../src/trace/console-args.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AA2BH,8BAEC;AAGD,oCAUC;AAGD,4BAKC;AAGD,gDAaC;AAUD,wCA8CC;AAGD,oCAiBC;AASD,wCAUC;AA/JD,gCAAyC;AAGzC,+EAA+E;AAClE,QAAA,kBAAkB,GAAG,GAAG,CAAC;AAEtC;;;;;;;;;GASG;AACU,QAAA,aAAa,GAAG,CAAC,CAAC;AAClB,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,qBAAqB,GAAG,IAAI,CAAC;AAC7B,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAE3C,uFAAuF;AACvF,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAEpC,2FAA2F;AAC3F,SAAgB,SAAS,CAAC,KAAa,EAAE,GAAW;IAClD,OAAO,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;AAChE,CAAC;AAED,gFAAgF;AAChF,SAAgB,YAAY,CAAC,GAAY;IACvC,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC;IACxC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC;IAC/D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5E,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAgB,QAAQ,CAAC,IAAwB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9C,OAAO,IAAI,CAAC,MAAM,GAAG,0BAAkB;QACrC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,0BAAkB,CAAC,GAAG;QACzC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED,kFAAkF;AAClF,SAAgB,kBAAkB,CAAC,KAAY;IAK7C,MAAM,GAAG,GAAsD;QAC7D,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,OAAO;QAC3B,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,6BAAqB,CAAC;KACvE,CAAC;IACF,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,sBAAsB,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,cAAc,CAC5B,KAAc,EACd,KAAa,EACb,IAAiB;IAEjB,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC;IAC1B,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC,KAAe,EAAE,6BAAqB,CAAC,CAAC;IAChF,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvF,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAI,KAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC;IACjE,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAQ,KAAgB,CAAC,QAAQ,EAAE,CAAC;IAC3D,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC;IAC7C,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,KAAe,CAAC;IAC5B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,YAAY,CAAC;IACvC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;IACrE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACd,IAAI,CAAC;QACH,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,KAAK,GAAG,KAAK;iBAChB,KAAK,CAAC,CAAC,EAAE,qBAAa,CAAC;iBACvB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;YACxD,IAAI,KAAK,CAAC,MAAM,GAAG,qBAAa,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,qBAAa,OAAO,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,KAAgC,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAa,CAAC,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC1B,+EAA+E;YAC/E,IAAI,OAAO,KAAK,KAAK,WAAW,IAAI,OAAO,KAAK,KAAK,UAAU;gBAAE,SAAS;YAC1E,GAAG,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,qBAAa;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,qBAAa,OAAO,CAAC;QAClF,OAAO,GAAG,CAAC;IACb,CAAC;YAAS,CAAC;QACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0FAA0F;AAC1F,SAAgB,YAAY,CAAC,KAAc;IACzC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACzE,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC;IAC1B,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,CAAC,KAAe,EAAE,6BAAqB,CAAC,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAe,CAAC;YACrC,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE;YAC3B,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IACxC,CAAC;IACD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;IACvD,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,GAAI,KAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC;IACrF,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAG,KAAgB,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC/E,IAAI,IAAI,KAAK,UAAU;QAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;IACjE,IAAI,KAAK,YAAY,KAAK;QAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;IAChF,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,cAAc,CAAC,KAAK,EAAE,qBAAa,EAAE,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,cAAc,CAAC,IAAkB;IAC/C,IAAI,IAAA,qBAAe,EAAC,IAAI,CAAC,IAAI,8BAAsB;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,GAAG,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IACvB,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,IAAA,qBAAe,EAAC,GAAG,CAAC,GAAG,8BAAsB,EAAE,CAAC;QACvE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,IAAA,qBAAe,EAAC,GAAG,CAAC,GAAG,8BAAsB,EAAE,CAAC;QACtE,OAAO,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,+CAA+C,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * The **console instrumentation** (spec #122 §C) — the one wrapper both the browser
3
+ * and React Native SDKs install (ADR-0028).
4
+ *
5
+ * It patches the injected `console` object's level methods so each call becomes a
6
+ * crumb before the original runs. The console surface is a parameter, never read
7
+ * off a global here, so the core stays runtime-agnostic and tests pass a plain
8
+ * object. Capture must never throw into the host app: a failure recording a crumb
9
+ * is swallowed and the original `console` method always runs.
10
+ */
11
+ import type { BreadcrumbLevel } from "../breadcrumb";
12
+ import { type BreadcrumbBuffer } from "./buffer";
13
+ /** Detaches an installed instrumentation, restoring the original behaviour. */
14
+ export type Teardown = () => void;
15
+ /**
16
+ * The `console` surface the wrapper patches — injected, never read off a global
17
+ * here.
18
+ *
19
+ * Declared as optional **methods** rather than a `Partial<Record<Level, Fn>>` of
20
+ * function-typed properties, deliberately: method signatures are bivariant in
21
+ * their parameters, so a real DOM `Console` — whose `assert` is overloaded with a
22
+ * leading `condition?: boolean` — satisfies this directly. That is what lets the
23
+ * browser SDK pass `console` with no cast at all.
24
+ */
25
+ export interface ConsoleLike {
26
+ log?(...args: unknown[]): unknown;
27
+ info?(...args: unknown[]): unknown;
28
+ warn?(...args: unknown[]): unknown;
29
+ error?(...args: unknown[]): unknown;
30
+ assert?(...args: unknown[]): unknown;
31
+ debug?(...args: unknown[]): unknown;
32
+ }
33
+ /**
34
+ * Wrap `console` methods so calls at the captured levels become crumbs, returning a
35
+ * teardown that restores every method it replaced.
36
+ *
37
+ * Whether a level pays the source-capture cost is decided **once per level**, not per
38
+ * call: only `warn`/`error`/`assert` construct a `new Error()` to read the call site,
39
+ * so a tight `log` loop stays cheap (ticket #159; see `SOURCE_CAPTURE_LEVELS`).
40
+ * `console.assert` records only when the asserted condition is falsy.
41
+ */
42
+ export declare function instrumentConsole(buffer: BreadcrumbBuffer, consoleObj: ConsoleLike, levels: readonly BreadcrumbLevel[], now: () => number): Teardown;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ /**
3
+ * The **console instrumentation** (spec #122 §C) — the one wrapper both the browser
4
+ * and React Native SDKs install (ADR-0028).
5
+ *
6
+ * It patches the injected `console` object's level methods so each call becomes a
7
+ * crumb before the original runs. The console surface is a parameter, never read
8
+ * off a global here, so the core stays runtime-agnostic and tests pass a plain
9
+ * object. Capture must never throw into the host app: a failure recording a crumb
10
+ * is swallowed and the original `console` method always runs.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.instrumentConsole = instrumentConsole;
14
+ const buffer_1 = require("./buffer");
15
+ const crumbs_1 = require("./crumbs");
16
+ const source_1 = require("./source");
17
+ /**
18
+ * Wrap `console` methods so calls at the captured levels become crumbs, returning a
19
+ * teardown that restores every method it replaced.
20
+ *
21
+ * Whether a level pays the source-capture cost is decided **once per level**, not per
22
+ * call: only `warn`/`error`/`assert` construct a `new Error()` to read the call site,
23
+ * so a tight `log` loop stays cheap (ticket #159; see `SOURCE_CAPTURE_LEVELS`).
24
+ * `console.assert` records only when the asserted condition is falsy.
25
+ */
26
+ function instrumentConsole(buffer, consoleObj, levels, now) {
27
+ const restores = [];
28
+ for (const level of levels) {
29
+ const original = consoleObj[level];
30
+ if (typeof original !== "function")
31
+ continue;
32
+ const withSource = (0, buffer_1.capturesSource)(level);
33
+ const wrapper = (...args) => {
34
+ // Capture the call site before anything else so the wrapper is the top frame —
35
+ // but only for the levels that keep a source (the hot-page budget, ticket #159).
36
+ let source;
37
+ if (withSource) {
38
+ try {
39
+ source = (0, source_1.sourceFromStack)(new Error().stack, source_1.CONSOLE_SOURCE_SKIP_FRAMES);
40
+ }
41
+ catch {
42
+ source = undefined;
43
+ }
44
+ }
45
+ try {
46
+ if (level === "assert") {
47
+ // console.assert records only when the asserted condition is falsy.
48
+ if (!args[0]) {
49
+ buffer.add((0, crumbs_1.consoleCrumb)("assert", args.slice(1), now(), source));
50
+ }
51
+ }
52
+ else {
53
+ buffer.add((0, crumbs_1.consoleCrumb)(level, args, now(), source));
54
+ }
55
+ }
56
+ catch {
57
+ // Capture must never throw into the host app.
58
+ }
59
+ return original.apply(consoleObj, args);
60
+ };
61
+ consoleObj[level] = wrapper;
62
+ restores.push(() => {
63
+ consoleObj[level] = original;
64
+ });
65
+ }
66
+ return () => {
67
+ for (const restore of restores)
68
+ restore();
69
+ };
70
+ }
71
+ //# sourceMappingURL=console.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"console.js","sourceRoot":"","sources":["../../src/trace/console.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAuCH,8CA4CC;AA/ED,qCAAiE;AACjE,qCAAwC;AACxC,qCAAuE;AAwBvE;;;;;;;;GAQG;AACH,SAAgB,iBAAiB,CAC/B,MAAwB,EACxB,UAAuB,EACvB,MAAkC,EAClC,GAAiB;IAEjB,MAAM,QAAQ,GAAe,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,OAAO,QAAQ,KAAK,UAAU;YAAE,SAAS;QAC7C,MAAM,UAAU,GAAG,IAAA,uBAAc,EAAC,KAAK,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,CAAC,GAAG,IAAe,EAAW,EAAE;YAC9C,+EAA+E;YAC/E,iFAAiF;YACjF,IAAI,MAAkC,CAAC;YACvC,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC;oBACH,MAAM,GAAG,IAAA,wBAAe,EAAC,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,mCAA0B,CAAC,CAAC;gBAC1E,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,GAAG,SAAS,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,IAAI,CAAC;gBACH,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACvB,oEAAoE;oBACpE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACb,MAAM,CAAC,GAAG,CAAC,IAAA,qBAAY,EAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;oBACnE,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,IAAA,qBAAY,EAAC,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;YACD,OAAO,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC1C,CAAC,CAAC;QACF,UAAU,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE;YACjB,UAAU,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;QAC/B,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,EAAE;QACV,KAAK,MAAM,OAAO,IAAI,QAAQ;YAAE,OAAO,EAAE,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * The pure **crumb builders** (spec #122 §C/§D/§F) — the shared, runtime-agnostic
3
+ * constructors every capture SDK assembles trace entries with (ADR-0028), so the
4
+ * server and dashboard cannot tell a mobile trace from a web one.
5
+ *
6
+ * Everything private is kept out **at the source**: a network crumb has no field
7
+ * for a request/response body or an arbitrary header, and every URL is scrubbed
8
+ * (query dropped, path PII redacted) and length-capped as the crumb is built. The
9
+ * `beforeSend` choke point (`../scrub`) is the final gate over the whole report.
10
+ *
11
+ * The two DOM-shaped builders — `ui.click` and `ui.input`, which need an `Element`
12
+ * to derive a masked selector from — stay in the browser SDK; every crumb kind a
13
+ * non-browser runtime can also produce lives here.
14
+ */
15
+ import type { Breadcrumb, BreadcrumbLevel, NetworkApi, NetworkOutcome, SourceLocation } from "../breadcrumb";
16
+ /**
17
+ * Longest scrubbed URL kept on a crumb (spec #122 §F): capped at assembly so an
18
+ * over-long URL is truncated, never dropped and never allowed to bloat a report.
19
+ */
20
+ export declare const MAX_URL_LENGTH = 2048;
21
+ /**
22
+ * A `console` crumb from a captured call's level and arguments (spec #122 §C). The
23
+ * `message` is the one-line preview (flattened, truncated); `args` preserves each
24
+ * argument as a structured, type-tagged, size-capped value so the Console tab can
25
+ * render objects/errors expandably; `source` is the best-effort `file:line`, attached
26
+ * only when the stack yielded one. Args are omitted entirely for a no-argument call.
27
+ */
28
+ export declare function consoleCrumb(level: BreadcrumbLevel, args: readonly unknown[], timestamp: number, source?: SourceLocation): Breadcrumb;
29
+ /**
30
+ * A `navigation` crumb; both URLs are scrubbed and length-capped as the crumb is
31
+ * built. In a browser these come from `history`/`hashchange`; on mobile from the
32
+ * host app's `trackScreen` calls (spec 0004 §D), where the values are screen URLs
33
+ * derived from the configured origin.
34
+ */
35
+ export declare function navigationCrumb(from: string, to: string, timestamp: number): Breadcrumb;
36
+ /**
37
+ * Classify an HTTP status into a {@link NetworkOutcome} (spec #122 §D). A missing or
38
+ * `0` status is a `network-error` (a request that never got a response); otherwise
39
+ * the 4xx/5xx classes flag failures and everything else is `ok`. Used both as the
40
+ * fallback outcome and by the thin {@link fetchCrumb} / {@link xhrCrumb} builders.
41
+ */
42
+ export declare function outcomeFromStatus(status: number | undefined): NetworkOutcome;
43
+ /** Parse a `content-length` header into a non-negative byte count, or `undefined`. */
44
+ export declare function parseContentLength(value: string | null | undefined): number | undefined;
45
+ /** The media type from a `content-type` header (the part before any `;` parameters). */
46
+ export declare function contentTypeOf(value: string | null | undefined): string | undefined;
47
+ /** The rich metadata a network crumb records (spec #122 §D) — never a body or header. */
48
+ export interface NetworkCrumbInput {
49
+ readonly api: NetworkApi;
50
+ readonly method: string;
51
+ /** The raw request URL — scrubbed (query dropped, path PII redacted) as the crumb is built. */
52
+ readonly url: string;
53
+ readonly status?: number;
54
+ readonly statusText?: string;
55
+ readonly durationMs?: number;
56
+ readonly reqSize?: number;
57
+ readonly respSize?: number;
58
+ readonly contentType?: string;
59
+ readonly outcome: NetworkOutcome;
60
+ }
61
+ /**
62
+ * A network crumb (`fetch` / `xhr` / `beacon`) with the rich, metadata-only fields
63
+ * the Network tab renders (spec #122 §D, ticket #139): api, method, scrubbed URL,
64
+ * status + statusText, duration, request/response sizes, content type, and a failure
65
+ * outcome. The URL is scrubbed and length-capped at assembly. The shape has **no field
66
+ * for a request/response body or an arbitrary header**, so neither can ever be
67
+ * recorded; only a positive status, and fields that were actually supplied, ride along.
68
+ */
69
+ export declare function networkCrumb(input: NetworkCrumbInput, timestamp: number): Breadcrumb;
70
+ /**
71
+ * A thin `fetch` crumb from method + URL + status (outcome derived from the status).
72
+ * The instrumentation uses {@link networkCrumb} directly to carry the full metadata;
73
+ * this convenience builder seeds a network crumb from a status alone.
74
+ */
75
+ export declare function fetchCrumb(method: string, url: string, status: number | undefined, timestamp: number): Breadcrumb;
76
+ /** A thin `xhr` crumb from method + URL + status (outcome derived from the status). */
77
+ export declare function xhrCrumb(method: string, url: string, status: number | undefined, timestamp: number): Breadcrumb;
78
+ /** Distil any thrown value into the `{ name, message }` an error crumb reads. */
79
+ export declare function describeError(error: unknown): {
80
+ name: string;
81
+ message: string;
82
+ };
83
+ /**
84
+ * An `error` crumb for the failing exception or rejection that ends the trace. When
85
+ * `causedBy` is given (an auto-captured error), it rides on the crumb as the causal
86
+ * pointer to the ids of the entries immediately preceding the throw (spec #122 §F).
87
+ */
88
+ export declare function errorCrumb(error: unknown, timestamp: number, causedBy?: readonly string[]): Breadcrumb;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /**
3
+ * The pure **crumb builders** (spec #122 §C/§D/§F) — the shared, runtime-agnostic
4
+ * constructors every capture SDK assembles trace entries with (ADR-0028), so the
5
+ * server and dashboard cannot tell a mobile trace from a web one.
6
+ *
7
+ * Everything private is kept out **at the source**: a network crumb has no field
8
+ * for a request/response body or an arbitrary header, and every URL is scrubbed
9
+ * (query dropped, path PII redacted) and length-capped as the crumb is built. The
10
+ * `beforeSend` choke point (`../scrub`) is the final gate over the whole report.
11
+ *
12
+ * The two DOM-shaped builders — `ui.click` and `ui.input`, which need an `Element`
13
+ * to derive a masked selector from — stay in the browser SDK; every crumb kind a
14
+ * non-browser runtime can also produce lives here.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MAX_URL_LENGTH = void 0;
18
+ exports.consoleCrumb = consoleCrumb;
19
+ exports.navigationCrumb = navigationCrumb;
20
+ exports.outcomeFromStatus = outcomeFromStatus;
21
+ exports.parseContentLength = parseContentLength;
22
+ exports.contentTypeOf = contentTypeOf;
23
+ exports.networkCrumb = networkCrumb;
24
+ exports.fetchCrumb = fetchCrumb;
25
+ exports.xhrCrumb = xhrCrumb;
26
+ exports.describeError = describeError;
27
+ exports.errorCrumb = errorCrumb;
28
+ const scrub_1 = require("../scrub");
29
+ const console_args_1 = require("./console-args");
30
+ /**
31
+ * Longest scrubbed URL kept on a crumb (spec #122 §F): capped at assembly so an
32
+ * over-long URL is truncated, never dropped and never allowed to bloat a report.
33
+ */
34
+ exports.MAX_URL_LENGTH = 2048;
35
+ /**
36
+ * A `console` crumb from a captured call's level and arguments (spec #122 §C). The
37
+ * `message` is the one-line preview (flattened, truncated); `args` preserves each
38
+ * argument as a structured, type-tagged, size-capped value so the Console tab can
39
+ * render objects/errors expandably; `source` is the best-effort `file:line`, attached
40
+ * only when the stack yielded one. Args are omitted entirely for a no-argument call.
41
+ */
42
+ function consoleCrumb(level, args, timestamp, source) {
43
+ const structured = (0, console_args_1.capConsoleArgs)(args.map(console_args_1.toConsoleArg));
44
+ return {
45
+ category: "console",
46
+ level,
47
+ message: (0, console_args_1.joinArgs)(args),
48
+ timestamp,
49
+ ...(structured.length > 0 ? { args: structured } : {}),
50
+ ...(source ? { source } : {}),
51
+ };
52
+ }
53
+ /**
54
+ * A `navigation` crumb; both URLs are scrubbed and length-capped as the crumb is
55
+ * built. In a browser these come from `history`/`hashchange`; on mobile from the
56
+ * host app's `trackScreen` calls (spec 0004 §D), where the values are screen URLs
57
+ * derived from the configured origin.
58
+ */
59
+ function navigationCrumb(from, to, timestamp) {
60
+ const fromUrl = (0, console_args_1.capLength)((0, scrub_1.scrubUrl)(from), exports.MAX_URL_LENGTH);
61
+ const toUrl = (0, console_args_1.capLength)((0, scrub_1.scrubUrl)(to), exports.MAX_URL_LENGTH);
62
+ return {
63
+ category: "navigation",
64
+ message: `${fromUrl} → ${toUrl}`,
65
+ timestamp,
66
+ data: { from: fromUrl, to: toUrl },
67
+ };
68
+ }
69
+ /**
70
+ * Classify an HTTP status into a {@link NetworkOutcome} (spec #122 §D). A missing or
71
+ * `0` status is a `network-error` (a request that never got a response); otherwise
72
+ * the 4xx/5xx classes flag failures and everything else is `ok`. Used both as the
73
+ * fallback outcome and by the thin {@link fetchCrumb} / {@link xhrCrumb} builders.
74
+ */
75
+ function outcomeFromStatus(status) {
76
+ if (typeof status !== "number" || status <= 0)
77
+ return "network-error";
78
+ if (status >= 500)
79
+ return "http-5xx";
80
+ if (status >= 400)
81
+ return "http-4xx";
82
+ return "ok";
83
+ }
84
+ /** Parse a `content-length` header into a non-negative byte count, or `undefined`. */
85
+ function parseContentLength(value) {
86
+ if (typeof value !== "string")
87
+ return undefined;
88
+ const bytes = Number.parseInt(value, 10);
89
+ return Number.isFinite(bytes) && bytes >= 0 ? bytes : undefined;
90
+ }
91
+ /** The media type from a `content-type` header (the part before any `;` parameters). */
92
+ function contentTypeOf(value) {
93
+ if (typeof value !== "string" || value.length === 0)
94
+ return undefined;
95
+ const media = value.split(";")[0]?.trim();
96
+ return media && media.length > 0 ? media : undefined;
97
+ }
98
+ /**
99
+ * A network crumb (`fetch` / `xhr` / `beacon`) with the rich, metadata-only fields
100
+ * the Network tab renders (spec #122 §D, ticket #139): api, method, scrubbed URL,
101
+ * status + statusText, duration, request/response sizes, content type, and a failure
102
+ * outcome. The URL is scrubbed and length-capped at assembly. The shape has **no field
103
+ * for a request/response body or an arbitrary header**, so neither can ever be
104
+ * recorded; only a positive status, and fields that were actually supplied, ride along.
105
+ */
106
+ function networkCrumb(input, timestamp) {
107
+ const url = (0, console_args_1.capLength)((0, scrub_1.scrubUrl)(input.url), exports.MAX_URL_LENGTH);
108
+ const hasStatus = typeof input.status === "number" && input.status > 0;
109
+ const statusPart = hasStatus ? ` → ${input.status}` : "";
110
+ const outcomePart = input.outcome !== "ok" ? ` (${input.outcome})` : "";
111
+ return {
112
+ category: input.api,
113
+ api: input.api,
114
+ method: input.method,
115
+ url,
116
+ message: `${input.method} ${url}${statusPart}${outcomePart}`,
117
+ timestamp,
118
+ ...(hasStatus ? { status: input.status } : {}),
119
+ ...(input.statusText ? { statusText: input.statusText } : {}),
120
+ ...(typeof input.durationMs === "number" ? { durationMs: input.durationMs } : {}),
121
+ ...(typeof input.reqSize === "number" ? { reqSize: input.reqSize } : {}),
122
+ ...(typeof input.respSize === "number" ? { respSize: input.respSize } : {}),
123
+ ...(input.contentType ? { contentType: input.contentType } : {}),
124
+ outcome: input.outcome,
125
+ };
126
+ }
127
+ /**
128
+ * A thin `fetch` crumb from method + URL + status (outcome derived from the status).
129
+ * The instrumentation uses {@link networkCrumb} directly to carry the full metadata;
130
+ * this convenience builder seeds a network crumb from a status alone.
131
+ */
132
+ function fetchCrumb(method, url, status, timestamp) {
133
+ return networkCrumb({ api: "fetch", method, url, status, outcome: outcomeFromStatus(status) }, timestamp);
134
+ }
135
+ /** A thin `xhr` crumb from method + URL + status (outcome derived from the status). */
136
+ function xhrCrumb(method, url, status, timestamp) {
137
+ return networkCrumb({ api: "xhr", method, url, status, outcome: outcomeFromStatus(status) }, timestamp);
138
+ }
139
+ /** Distil any thrown value into the `{ name, message }` an error crumb reads. */
140
+ function describeError(error) {
141
+ if (error instanceof Error) {
142
+ return { name: error.name || "Error", message: error.message };
143
+ }
144
+ if (typeof error === "string")
145
+ return { name: "Error", message: error };
146
+ return { name: "Error", message: (0, console_args_1.stringifyArg)(error) };
147
+ }
148
+ /**
149
+ * An `error` crumb for the failing exception or rejection that ends the trace. When
150
+ * `causedBy` is given (an auto-captured error), it rides on the crumb as the causal
151
+ * pointer to the ids of the entries immediately preceding the throw (spec #122 §F).
152
+ */
153
+ function errorCrumb(error, timestamp, causedBy) {
154
+ const { name, message } = describeError(error);
155
+ const crumb = {
156
+ category: "error",
157
+ level: "error",
158
+ message: message ? `${name}: ${message}` : name,
159
+ timestamp,
160
+ data: { errorType: name },
161
+ };
162
+ return causedBy && causedBy.length > 0 ? { ...crumb, causedBy } : crumb;
163
+ }
164
+ //# sourceMappingURL=crumbs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crumbs.js","sourceRoot":"","sources":["../../src/trace/crumbs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * The console crumb's **call site** (spec #122 §C) — the best-effort `file:line` a
3
+ * `console.*` call was made from, shared runtime-agnostically (ADR-0028).
4
+ *
5
+ * Frames are tokenized by the core's single stack parser (`stack.ts`), so a stack
6
+ * that yields a fingerprint frame yields a source location too — the browser's V8
7
+ * and Firefox/Safari dialects and React Native's Hermes/JSC ones alike. A query
8
+ * string on the asset URL is dropped, both for parse safety and privacy (it may be
9
+ * a cache-buster, or defensively a token).
10
+ */
11
+ import type { SourceLocation } from "../breadcrumb";
12
+ /**
13
+ * Parse a single **trimmed** stack line into a `{ file, line }` location, or
14
+ * `undefined` when the line names no locatable file:line.
15
+ */
16
+ export declare function parseStackFrame(line: string): SourceLocation | undefined;
17
+ /**
18
+ * The best-effort `file:line` a console call was made from (spec #122 §C). Parses the
19
+ * frames of a stack, skipping `skipFrames` leading (SDK-internal) frames so the source
20
+ * points at the host code that called `console.*`. Returns `undefined` when no frame
21
+ * yields a usable location — the crumb then simply omits `source`.
22
+ */
23
+ export declare function sourceFromStack(stack: string | undefined, skipFrames?: number): SourceLocation | undefined;
24
+ /**
25
+ * Frames between `new Error()` (created inside the console wrapper) and the host
26
+ * caller: just the wrapper frame itself. Skipping it points {@link sourceFromStack}
27
+ * at the app code. The wrapper is called through the console object's property, so
28
+ * it is not a direct-call inlining candidate — keeping this skip count stable.
29
+ */
30
+ export declare const CONSOLE_SOURCE_SKIP_FRAMES = 1;