@interfere/react 10.0.0 → 10.0.1-canary.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 (121) hide show
  1. package/dist/api.d.mts.map +1 -1
  2. package/dist/api.mjs +1 -68
  3. package/dist/api.mjs.map +1 -1
  4. package/dist/error-boundary.d.mts +1 -2
  5. package/dist/error-boundary.d.mts.map +1 -1
  6. package/dist/error-boundary.mjs +1 -42
  7. package/dist/error-boundary.mjs.map +1 -1
  8. package/dist/internal/browser-context.d.mts.map +1 -1
  9. package/dist/internal/browser-context.mjs +1 -59
  10. package/dist/internal/browser-context.mjs.map +1 -1
  11. package/dist/internal/capture-boundary.d.mts +1 -2
  12. package/dist/internal/capture-boundary.d.mts.map +1 -1
  13. package/dist/internal/capture-boundary.mjs +1 -48
  14. package/dist/internal/capture-boundary.mjs.map +1 -1
  15. package/dist/internal/capture.mjs +1 -27
  16. package/dist/internal/capture.mjs.map +1 -1
  17. package/dist/internal/config.d.mts +3 -1
  18. package/dist/internal/config.d.mts.map +1 -1
  19. package/dist/internal/config.mjs +1 -33
  20. package/dist/internal/config.mjs.map +1 -1
  21. package/dist/internal/consent.d.mts.map +1 -1
  22. package/dist/internal/consent.mjs +1 -27
  23. package/dist/internal/consent.mjs.map +1 -1
  24. package/dist/internal/console-patch.d.mts.map +1 -1
  25. package/dist/internal/console-patch.mjs +1 -62
  26. package/dist/internal/console-patch.mjs.map +1 -1
  27. package/dist/internal/dom/actionable.d.mts.map +1 -1
  28. package/dist/internal/dom/actionable.mjs +1 -62
  29. package/dist/internal/dom/actionable.mjs.map +1 -1
  30. package/dist/internal/kernel-registry.d.mts.map +1 -1
  31. package/dist/internal/kernel-registry.mjs +1 -31
  32. package/dist/internal/kernel-registry.mjs.map +1 -1
  33. package/dist/internal/kernel.d.mts.map +1 -1
  34. package/dist/internal/kernel.mjs +1 -322
  35. package/dist/internal/kernel.mjs.map +1 -1
  36. package/dist/internal/otel/exporter.d.mts +4 -12
  37. package/dist/internal/otel/exporter.d.mts.map +1 -1
  38. package/dist/internal/otel/exporter.mjs +1 -212
  39. package/dist/internal/otel/exporter.mjs.map +1 -1
  40. package/dist/internal/otel/index.mjs +1 -6
  41. package/dist/internal/otel/instrumentations.d.mts.map +1 -1
  42. package/dist/internal/otel/instrumentations.mjs +1 -150
  43. package/dist/internal/otel/instrumentations.mjs.map +1 -1
  44. package/dist/internal/otel/page-scope-context-manager.d.mts.map +1 -1
  45. package/dist/internal/otel/page-scope-context-manager.mjs +1 -36
  46. package/dist/internal/otel/page-scope-context-manager.mjs.map +1 -1
  47. package/dist/internal/otel/propagation.d.mts.map +1 -1
  48. package/dist/internal/otel/propagation.mjs +1 -40
  49. package/dist/internal/otel/propagation.mjs.map +1 -1
  50. package/dist/internal/otel/provider.d.mts +1 -2
  51. package/dist/internal/otel/provider.d.mts.map +1 -1
  52. package/dist/internal/otel/provider.mjs +1 -151
  53. package/dist/internal/otel/provider.mjs.map +1 -1
  54. package/dist/internal/otel/web-vitals.d.mts.map +1 -1
  55. package/dist/internal/otel/web-vitals.mjs +1 -162
  56. package/dist/internal/otel/web-vitals.mjs.map +1 -1
  57. package/dist/internal/page-lifecycle.d.mts.map +1 -1
  58. package/dist/internal/page-lifecycle.mjs +1 -33
  59. package/dist/internal/page-lifecycle.mjs.map +1 -1
  60. package/dist/internal/plugin-runtime.mjs +1 -101
  61. package/dist/internal/plugin-runtime.mjs.map +1 -1
  62. package/dist/internal/react-context.d.mts +1 -2
  63. package/dist/internal/react-context.d.mts.map +1 -1
  64. package/dist/internal/react-context.mjs +1 -34
  65. package/dist/internal/react-context.mjs.map +1 -1
  66. package/dist/internal/sw.d.mts.map +1 -1
  67. package/dist/internal/sw.mjs +1 -37
  68. package/dist/internal/sw.mjs.map +1 -1
  69. package/dist/internal/version.mjs +1 -7
  70. package/dist/internal/version.mjs.map +1 -1
  71. package/dist/internal/wrapper-singleton.d.mts.map +1 -1
  72. package/dist/internal/wrapper-singleton.mjs +1 -73
  73. package/dist/internal/wrapper-singleton.mjs.map +1 -1
  74. package/dist/package.mjs +1 -5
  75. package/dist/plugins/errors.d.mts.map +1 -1
  76. package/dist/plugins/errors.mjs +1 -84
  77. package/dist/plugins/errors.mjs.map +1 -1
  78. package/dist/plugins/lib/loader.mjs +1 -34
  79. package/dist/plugins/lib/loader.mjs.map +1 -1
  80. package/dist/plugins/lib/types.d.mts.map +1 -1
  81. package/dist/plugins/lib/types.mjs +1 -1
  82. package/dist/plugins/logs.d.mts.map +1 -1
  83. package/dist/plugins/logs.mjs +1 -53
  84. package/dist/plugins/logs.mjs.map +1 -1
  85. package/dist/plugins/rage-clicks.d.mts.map +1 -1
  86. package/dist/plugins/rage-clicks.mjs +1 -55
  87. package/dist/plugins/rage-clicks.mjs.map +1 -1
  88. package/dist/plugins/replay.d.mts.map +1 -1
  89. package/dist/plugins/replay.mjs +1 -101
  90. package/dist/plugins/replay.mjs.map +1 -1
  91. package/dist/provider.d.mts.map +1 -1
  92. package/dist/provider.mjs +1 -31
  93. package/dist/provider.mjs.map +1 -1
  94. package/dist/react-error-handler.d.mts.map +1 -1
  95. package/dist/react-error-handler.mjs +1 -62
  96. package/dist/react-error-handler.mjs.map +1 -1
  97. package/dist/tracking/api.d.mts.map +1 -1
  98. package/dist/tracking/api.mjs +1 -152
  99. package/dist/tracking/api.mjs.map +1 -1
  100. package/dist/tracking/device.d.mts.map +1 -1
  101. package/dist/tracking/device.mjs +1 -104
  102. package/dist/tracking/device.mjs.map +1 -1
  103. package/dist/tracking/geo.d.mts.map +1 -1
  104. package/dist/tracking/geo.mjs +2 -48
  105. package/dist/tracking/geo.mjs.map +1 -1
  106. package/dist/tracking/session.d.mts.map +1 -1
  107. package/dist/tracking/session.mjs +1 -75
  108. package/dist/tracking/session.mjs.map +1 -1
  109. package/dist/util/bot.d.mts.map +1 -1
  110. package/dist/util/bot.mjs +1 -14
  111. package/dist/util/bot.mjs.map +1 -1
  112. package/dist/util/global.d.mts.map +1 -1
  113. package/dist/util/global.mjs +1 -12
  114. package/dist/util/global.mjs.map +1 -1
  115. package/dist/util/log.d.mts.map +1 -1
  116. package/dist/util/log.mjs +1 -44
  117. package/dist/util/log.mjs.map +1 -1
  118. package/dist/util/stringify.d.mts.map +1 -1
  119. package/dist/util/stringify.mjs +1 -16
  120. package/dist/util/stringify.mjs.map +1 -1
  121. package/package.json +34 -33
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.mts","names":[],"sources":["../src/api.ts"],"mappings":";;;;;AAuCA;;;;;;;;iBAAgB,IAAA,GAAA,CACd,IAAA,UACA,EAAA,GAAK,IAAA,EAAM,IAAA,KAAS,CAAA,EACpB,OAAA,GAAU,WAAA,GACT,CAAA;;;;;;;;;iBAuCa,OAAA,CAAQ,KAAA"}
1
+ {"version":3,"file":"api.d.mts","names":[],"sources":["../src/api.ts"],"mappings":";;;;;AAuCA;;;;;;;;iBAAgB,IAAA,GAAA,CACd,IAAA,UACA,EAAA,GAAK,IAAA,EAAM,IAAA,KAAS,CAAA,EACpB,OAAA,GAAU,WAAA,GACT,CAAA;;;;;;;;;iBAuCa,OAAA,CAAQ,KAAc"}
package/dist/api.mjs CHANGED
@@ -1,68 +1 @@
1
- import { activeKernel } from "./internal/kernel-registry.mjs";
2
- import { MECHANISM_TYPE, toError, toException } from "@interfere/types/sdk/errors";
3
- import { SpanStatusCode, trace } from "@opentelemetry/api";
4
- //#region src/api.ts
5
- const TRACER_NAME = "@interfere/react";
6
- function tracer() {
7
- return trace.getTracer(TRACER_NAME);
8
- }
9
- function isPromise(value) {
10
- return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
11
- }
12
- /**
13
- * Wraps `fn` in an OTel span. The span becomes the active context for the
14
- * duration of the call (sync) or the awaited promise (async). Errors thrown
15
- * by `fn` are recorded on the span before re-throwing — caller still owns
16
- * the error.
17
- *
18
- * Works pre-init: `trace.getTracer()` returns a no-op tracer that still
19
- * runs `fn` and propagates its return value, so call sites don't need
20
- * defensive checks.
21
- */
22
- function span(name, fn, options) {
23
- return tracer().startActiveSpan(name, options ?? {}, (s) => {
24
- try {
25
- const result = fn(s);
26
- if (isPromise(result)) return result.then((value) => {
27
- s.end();
28
- return value;
29
- }, (err) => {
30
- const e = toError(err);
31
- s.recordException(e);
32
- s.setStatus({
33
- code: SpanStatusCode.ERROR,
34
- message: e.message
35
- });
36
- s.end();
37
- throw err;
38
- });
39
- s.end();
40
- return result;
41
- } catch (err) {
42
- const e = toError(err);
43
- s.recordException(e);
44
- s.setStatus({
45
- code: SpanStatusCode.ERROR,
46
- message: e.message
47
- });
48
- s.end();
49
- throw err;
50
- }
51
- });
52
- }
53
- /**
54
- * Captures an error. Records on the active OTel span (when present) AND on
55
- * the legacy envelope path. Accepts any thrown value; non-Error inputs that
56
- * carry structure (objects without a recoverable nested Error) are preserved
57
- * via `toException` so the original shape survives to the wire.
58
- *
59
- * Safe to call before init — drops silently if no kernel is registered.
60
- */
61
- function capture(error) {
62
- activeKernel()?.recordException(toException(error), { mechanism: {
63
- type: MECHANISM_TYPE.manual.capture,
64
- handled: true
65
- } });
66
- }
67
- //#endregion
68
- export { capture, span };
1
+ import{activeKernel}from"./internal/kernel-registry.mjs";import{MECHANISM_TYPE,toError,toException}from"@interfere/types/sdk/errors";import{SpanStatusCode,trace}from"@opentelemetry/api";function tracer(){return trace.getTracer(`@interfere/react`)}function isPromise(value){return!!value&&(typeof value==`object`||typeof value==`function`)&&typeof value.then==`function`}function span(name,fn,options){return tracer().startActiveSpan(name,options??{},s=>{try{let result=fn(s);return isPromise(result)?result.then(value=>(s.end(),value),err=>{let e=toError(err);throw s.recordException(e),s.setStatus({code:SpanStatusCode.ERROR,message:e.message}),s.end(),err}):(s.end(),result)}catch(err){let e=toError(err);throw s.recordException(e),s.setStatus({code:SpanStatusCode.ERROR,message:e.message}),s.end(),err}})}function capture(error){activeKernel()?.recordException(toException(error),{mechanism:{type:MECHANISM_TYPE.manual.capture,handled:!0}})}export{capture,span};
package/dist/api.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"api.mjs","names":[],"sources":["../src/api.ts"],"sourcesContent":["import {\n MECHANISM_TYPE,\n toError,\n toException,\n} from \"@interfere/types/sdk/errors\";\n\nimport {\n type Span,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from \"@opentelemetry/api\";\n\nimport { activeKernel } from \"./internal/kernel-registry.js\";\n\nconst TRACER_NAME = \"@interfere/react\";\n\nfunction tracer() {\n return trace.getTracer(TRACER_NAME);\n}\n\nfunction isPromise<T>(value: unknown): value is Promise<T> {\n return (\n !!value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Wraps `fn` in an OTel span. The span becomes the active context for the\n * duration of the call (sync) or the awaited promise (async). Errors thrown\n * by `fn` are recorded on the span before re-throwing — caller still owns\n * the error.\n *\n * Works pre-init: `trace.getTracer()` returns a no-op tracer that still\n * runs `fn` and propagates its return value, so call sites don't need\n * defensive checks.\n */\nexport function span<T>(\n name: string,\n fn: (span: Span) => T,\n options?: SpanOptions\n): T {\n return tracer().startActiveSpan(name, options ?? {}, (s): T => {\n try {\n const result = fn(s);\n if (isPromise<T>(result)) {\n return result.then(\n (value) => {\n s.end();\n return value;\n },\n (err: unknown) => {\n const e = toError(err);\n s.recordException(e);\n s.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n s.end();\n throw err;\n }\n ) as T;\n }\n s.end();\n return result;\n } catch (err) {\n const e = toError(err);\n s.recordException(e);\n s.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n s.end();\n throw err;\n }\n });\n}\n\n/**\n * Captures an error. Records on the active OTel span (when present) AND on\n * the legacy envelope path. Accepts any thrown value; non-Error inputs that\n * carry structure (objects without a recoverable nested Error) are preserved\n * via `toException` so the original shape survives to the wire.\n *\n * Safe to call before init — drops silently if no kernel is registered.\n */\nexport function capture(error: unknown): void {\n activeKernel()?.recordException(toException(error), {\n mechanism: { type: MECHANISM_TYPE.manual.capture, handled: true },\n });\n}\n"],"mappings":";;;;AAeA,MAAM,cAAc;AAEpB,SAAS,SAAS;CAChB,OAAO,MAAM,UAAU,YAAY;;AAGrC,SAAS,UAAa,OAAqC;CACzD,OACE,CAAC,CAAC,UACD,OAAO,UAAU,YAAY,OAAO,UAAU,eAC/C,OAAQ,MAA6B,SAAS;;;;;;;;;;;;AAclD,SAAgB,KACd,MACA,IACA,SACG;CACH,OAAO,QAAQ,CAAC,gBAAgB,MAAM,WAAW,EAAE,GAAG,MAAS;EAC7D,IAAI;GACF,MAAM,SAAS,GAAG,EAAE;GACpB,IAAI,UAAa,OAAO,EACtB,OAAO,OAAO,MACX,UAAU;IACT,EAAE,KAAK;IACP,OAAO;OAER,QAAiB;IAChB,MAAM,IAAI,QAAQ,IAAI;IACtB,EAAE,gBAAgB,EAAE;IACpB,EAAE,UAAU;KAAE,MAAM,eAAe;KAAO,SAAS,EAAE;KAAS,CAAC;IAC/D,EAAE,KAAK;IACP,MAAM;KAET;GAEH,EAAE,KAAK;GACP,OAAO;WACA,KAAK;GACZ,MAAM,IAAI,QAAQ,IAAI;GACtB,EAAE,gBAAgB,EAAE;GACpB,EAAE,UAAU;IAAE,MAAM,eAAe;IAAO,SAAS,EAAE;IAAS,CAAC;GAC/D,EAAE,KAAK;GACP,MAAM;;GAER;;;;;;;;;;AAWJ,SAAgB,QAAQ,OAAsB;CAC5C,cAAc,EAAE,gBAAgB,YAAY,MAAM,EAAE,EAClD,WAAW;EAAE,MAAM,eAAe,OAAO;EAAS,SAAS;EAAM,EAClE,CAAC"}
1
+ {"version":3,"file":"api.mjs","names":[],"sources":["../src/api.ts"],"sourcesContent":["import {\n MECHANISM_TYPE,\n toError,\n toException,\n} from \"@interfere/types/sdk/errors\";\n\nimport {\n type Span,\n type SpanOptions,\n SpanStatusCode,\n trace,\n} from \"@opentelemetry/api\";\n\nimport { activeKernel } from \"./internal/kernel-registry.js\";\n\nconst TRACER_NAME = \"@interfere/react\";\n\nfunction tracer() {\n return trace.getTracer(TRACER_NAME);\n}\n\nfunction isPromise<T>(value: unknown): value is Promise<T> {\n return (\n !!value &&\n (typeof value === \"object\" || typeof value === \"function\") &&\n typeof (value as { then?: unknown }).then === \"function\"\n );\n}\n\n/**\n * Wraps `fn` in an OTel span. The span becomes the active context for the\n * duration of the call (sync) or the awaited promise (async). Errors thrown\n * by `fn` are recorded on the span before re-throwing — caller still owns\n * the error.\n *\n * Works pre-init: `trace.getTracer()` returns a no-op tracer that still\n * runs `fn` and propagates its return value, so call sites don't need\n * defensive checks.\n */\nexport function span<T>(\n name: string,\n fn: (span: Span) => T,\n options?: SpanOptions\n): T {\n return tracer().startActiveSpan(name, options ?? {}, (s): T => {\n try {\n const result = fn(s);\n if (isPromise<T>(result)) {\n return result.then(\n (value) => {\n s.end();\n return value;\n },\n (err: unknown) => {\n const e = toError(err);\n s.recordException(e);\n s.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n s.end();\n throw err;\n }\n ) as T;\n }\n s.end();\n return result;\n } catch (err) {\n const e = toError(err);\n s.recordException(e);\n s.setStatus({ code: SpanStatusCode.ERROR, message: e.message });\n s.end();\n throw err;\n }\n });\n}\n\n/**\n * Captures an error. Records on the active OTel span (when present) AND on\n * the legacy envelope path. Accepts any thrown value; non-Error inputs that\n * carry structure (objects without a recoverable nested Error) are preserved\n * via `toException` so the original shape survives to the wire.\n *\n * Safe to call before init — drops silently if no kernel is registered.\n */\nexport function capture(error: unknown): void {\n activeKernel()?.recordException(toException(error), {\n mechanism: { type: MECHANISM_TYPE.manual.capture, handled: true },\n });\n}\n"],"mappings":"0LAiBA,SAAS,QAAS,CAChB,OAAO,MAAM,UAAU,kBAAW,CACpC,CAEA,SAAS,UAAa,MAAqC,CACzD,MACE,CAAC,CAAC,QACD,OAAO,OAAU,UAAY,OAAO,OAAU,aAC/C,OAAQ,MAA6B,MAAS,UAElD,CAYA,SAAgB,KACd,KACA,GACA,QACG,CACH,OAAO,OAAO,EAAE,gBAAgB,KAAM,SAAW,CAAC,EAAI,GAAS,CAC7D,GAAI,CACF,IAAM,OAAS,GAAG,CAAC,EAiBnB,OAhBI,UAAa,MAAM,EACd,OAAO,KACX,QACC,EAAE,IAAI,EACC,OAER,KAAiB,CAChB,IAAM,EAAI,QAAQ,GAAG,EAIrB,MAHA,EAAE,gBAAgB,CAAC,EACnB,EAAE,UAAU,CAAE,KAAM,eAAe,MAAO,QAAS,EAAE,OAAQ,CAAC,EAC9D,EAAE,IAAI,EACA,GACR,CACF,GAEF,EAAE,IAAI,EACC,OACT,OAAS,IAAK,CACZ,IAAM,EAAI,QAAQ,GAAG,EAIrB,MAHA,EAAE,gBAAgB,CAAC,EACnB,EAAE,UAAU,CAAE,KAAM,eAAe,MAAO,QAAS,EAAE,OAAQ,CAAC,EAC9D,EAAE,IAAI,EACA,GACR,CACF,CAAC,CACH,CAUA,SAAgB,QAAQ,MAAsB,CAC5C,aAAa,GAAG,gBAAgB,YAAY,KAAK,EAAG,CAClD,UAAW,CAAE,KAAM,eAAe,OAAO,QAAS,QAAS,EAAK,CAClE,CAAC,CACH"}
@@ -1,5 +1,4 @@
1
1
  import { InterfereContext, InterfereContextValue } from "./internal/react-context.mjs";
2
- import * as _$react from "react";
3
2
  import { Component, ContextType, ErrorInfo, ReactNode } from "react";
4
3
 
5
4
  //#region src/error-boundary.d.ts
@@ -20,7 +19,7 @@ interface ErrorBoundaryState {
20
19
  * Class component required — React has no hook-based error boundary API.
21
20
  */
22
21
  declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
23
- static contextType: _$react.Context<InterfereContextValue | null>;
22
+ static contextType: import("react").Context<InterfereContextValue | null>;
24
23
  context: ContextType<typeof InterfereContext>;
25
24
  state: ErrorBoundaryState;
26
25
  static getDerivedStateFromError(error: Error): ErrorBoundaryState;
@@ -1 +1 @@
1
- {"version":3,"file":"error-boundary.d.mts","names":[],"sources":["../src/error-boundary.tsx"],"mappings":";;;;;UAciB,kBAAA;EACf,QAAA,EAAU,SAAA;EACV,QAAA,GAAW,SAAA,KAAc,KAAA,EAAO,KAAA,EAAO,KAAA,iBAAsB,SAAA;EAC7D,OAAA,IAAW,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,SAAA;AAAA;AAAA,UAGvB,kBAAA;EACR,KAAA,EAAO,KAAA;AAAA;;;;;;;;;cAWI,aAAA,SAAsB,SAAA,CACjC,kBAAA,EACA,kBAAA;EAAA,OAEgB,WAAA,EAAW,OAAA,CAAA,OAAA,CAFT,qBAAA;EAGV,OAAA,EAAS,WAAA,QAAmB,gBAAA;EAE3B,KAAA,EAAO,kBAAA;EAAA,OAET,wBAAA,CAAyB,KAAA,EAAO,KAAA,GAAQ,kBAAA;EAItC,iBAAA,CACP,KAAA,EAAO,KAAA;IAAU,MAAA;EAAA,GACjB,IAAA,EAAM,SAAA;EAAA,iBAeS,KAAA;EAIR,MAAA,CAAA,GAAM,SAAA;AAAA"}
1
+ {"version":3,"file":"error-boundary.d.mts","names":[],"sources":["../src/error-boundary.tsx"],"mappings":";;;;UAciB,kBAAA;EACf,QAAA,EAAU,SAAA;EACV,QAAA,GAAW,SAAA,KAAc,KAAA,EAAO,KAAA,EAAO,KAAA,iBAAsB,SAAA;EAC7D,OAAA,IAAW,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,SAAA;AAAA;AAAA,UAGvB,kBAAA;EACR,KAAA,EAAO,KAAK;AAAA;;;;;;;;;cAWD,aAAA,SAAsB,SAAA,CACjC,kBAAA,EACA,kBAAA;EAAA,OAEgB,WAAA,kBAAW,OAAA,CAFT,qBAAA;EAGV,OAAA,EAAS,WAAA,QAAmB,gBAAA;EAE3B,KAAA,EAAO,kBAAA;EAAA,OAET,wBAAA,CAAyB,KAAA,EAAO,KAAA,GAAQ,kBAAA;EAItC,iBAAA,CACP,KAAA,EAAO,KAAA;IAAU,MAAA;EAAA,GACjB,IAAA,EAAM,SAAA;EAAA,iBAeS,KAAA;EAIR,MAAA,CAAA,GAAM,SAAA;AAAA"}
@@ -1,42 +1 @@
1
- "use client";
2
- import { captureReactError } from "./internal/capture.mjs";
3
- import { InterfereContext } from "./internal/react-context.mjs";
4
- import { MECHANISM_TYPE } from "@interfere/types/sdk/errors";
5
- import { Component } from "react";
6
- //#region src/error-boundary.tsx
7
- /**
8
- * Catches render-phase React errors, reports them to the SDK, and renders a
9
- * fallback. Reads the kernel from `InterfereContext`; mounting outside the
10
- * provider is supported — capture is silently skipped, fallback + `onError`
11
- * still fire.
12
- *
13
- * Class component required — React has no hook-based error boundary API.
14
- */
15
- var ErrorBoundary = class extends Component {
16
- static contextType = InterfereContext;
17
- state = { error: null };
18
- static getDerivedStateFromError(error) {
19
- return { error };
20
- }
21
- componentDidCatch(error, info) {
22
- captureReactError(this.context?.kernel ?? null, error, info.componentStack, {
23
- type: MECHANISM_TYPE.react.errorBoundary,
24
- handled: true
25
- });
26
- this.props.onError?.(error, info);
27
- }
28
- reset = () => {
29
- this.setState({ error: null });
30
- };
31
- render() {
32
- const { error } = this.state;
33
- if (error) {
34
- const { fallback } = this.props;
35
- if (typeof fallback === "function") return fallback(error, this.reset);
36
- return fallback ?? null;
37
- }
38
- return this.props.children;
39
- }
40
- };
41
- //#endregion
42
- export { ErrorBoundary };
1
+ "use client";import{captureReactError}from"./internal/capture.mjs";import{InterfereContext}from"./internal/react-context.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";import{Component}from"react";var ErrorBoundary=class extends Component{static contextType=InterfereContext;state={error:null};static getDerivedStateFromError(error){return{error}}componentDidCatch(error,info){captureReactError(this.context?.kernel??null,error,info.componentStack,{type:MECHANISM_TYPE.react.errorBoundary,handled:!0}),this.props.onError?.(error,info)}reset=()=>{this.setState({error:null})};render(){let{error}=this.state;if(error){let{fallback}=this.props;return typeof fallback==`function`?fallback(error,this.reset):fallback??null}return this.props.children}};export{ErrorBoundary};
@@ -1 +1 @@
1
- {"version":3,"file":"error-boundary.mjs","names":[],"sources":["../src/error-boundary.tsx"],"sourcesContent":["\"use client\";\n\nimport { MECHANISM_TYPE } from \"@interfere/types/sdk/errors\";\n\nimport {\n Component,\n type ContextType,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\n\nimport { captureReactError } from \"./internal/capture.js\";\nimport { InterfereContext } from \"./internal/react-context.js\";\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n error: Error | null;\n}\n\n/**\n * Catches render-phase React errors, reports them to the SDK, and renders a\n * fallback. Reads the kernel from `InterfereContext`; mounting outside the\n * provider is supported — capture is silently skipped, fallback + `onError`\n * still fire.\n *\n * Class component required — React has no hook-based error boundary API.\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static override contextType = InterfereContext;\n declare context: ContextType<typeof InterfereContext>;\n\n override state: ErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { error };\n }\n\n override componentDidCatch(\n error: Error & { digest?: string },\n info: ErrorInfo\n ) {\n captureReactError(\n this.context?.kernel ?? null,\n error,\n info.componentStack,\n {\n type: MECHANISM_TYPE.react.errorBoundary,\n handled: true,\n }\n );\n\n this.props.onError?.(error, info);\n }\n\n private readonly reset = () => {\n this.setState({ error: null });\n };\n\n override render() {\n const { error } = this.state;\n\n if (error) {\n const { fallback } = this.props;\n if (typeof fallback === \"function\") {\n return fallback(error, this.reset);\n }\n return fallback ?? null;\n }\n\n return this.props.children;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAgCA,IAAa,gBAAb,cAAmC,UAGjC;CACA,OAAgB,cAAc;CAG9B,QAAqC,EAAE,OAAO,MAAM;CAEpD,OAAO,yBAAyB,OAAkC;EAChE,OAAO,EAAE,OAAO;;CAGlB,kBACE,OACA,MACA;EACA,kBACE,KAAK,SAAS,UAAU,MACxB,OACA,KAAK,gBACL;GACE,MAAM,eAAe,MAAM;GAC3B,SAAS;GACV,CACF;EAED,KAAK,MAAM,UAAU,OAAO,KAAK;;CAGnC,cAA+B;EAC7B,KAAK,SAAS,EAAE,OAAO,MAAM,CAAC;;CAGhC,SAAkB;EAChB,MAAM,EAAE,UAAU,KAAK;EAEvB,IAAI,OAAO;GACT,MAAM,EAAE,aAAa,KAAK;GAC1B,IAAI,OAAO,aAAa,YACtB,OAAO,SAAS,OAAO,KAAK,MAAM;GAEpC,OAAO,YAAY;;EAGrB,OAAO,KAAK,MAAM"}
1
+ {"version":3,"file":"error-boundary.mjs","names":[],"sources":["../src/error-boundary.tsx"],"sourcesContent":["\"use client\";\n\nimport { MECHANISM_TYPE } from \"@interfere/types/sdk/errors\";\n\nimport {\n Component,\n type ContextType,\n type ErrorInfo,\n type ReactNode,\n} from \"react\";\n\nimport { captureReactError } from \"./internal/capture.js\";\nimport { InterfereContext } from \"./internal/react-context.js\";\n\nexport interface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode | ((error: Error, reset: () => void) => ReactNode);\n onError?: (error: Error, info: ErrorInfo) => void;\n}\n\ninterface ErrorBoundaryState {\n error: Error | null;\n}\n\n/**\n * Catches render-phase React errors, reports them to the SDK, and renders a\n * fallback. Reads the kernel from `InterfereContext`; mounting outside the\n * provider is supported — capture is silently skipped, fallback + `onError`\n * still fire.\n *\n * Class component required — React has no hook-based error boundary API.\n */\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n static override contextType = InterfereContext;\n declare context: ContextType<typeof InterfereContext>;\n\n override state: ErrorBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { error };\n }\n\n override componentDidCatch(\n error: Error & { digest?: string },\n info: ErrorInfo\n ) {\n captureReactError(\n this.context?.kernel ?? null,\n error,\n info.componentStack,\n {\n type: MECHANISM_TYPE.react.errorBoundary,\n handled: true,\n }\n );\n\n this.props.onError?.(error, info);\n }\n\n private readonly reset = () => {\n this.setState({ error: null });\n };\n\n override render() {\n const { error } = this.state;\n\n if (error) {\n const { fallback } = this.props;\n if (typeof fallback === \"function\") {\n return fallback(error, this.reset);\n }\n return fallback ?? null;\n }\n\n return this.props.children;\n }\n}\n"],"mappings":"mNAgCA,IAAa,cAAb,cAAmC,SAGjC,CACA,OAAgB,YAAc,iBAG9B,MAAqC,CAAE,MAAO,IAAK,EAEnD,OAAO,yBAAyB,MAAkC,CAChE,MAAO,CAAE,KAAM,CACjB,CAEA,kBACE,MACA,KACA,CACA,kBACE,KAAK,SAAS,QAAU,KACxB,MACA,KAAK,eACL,CACE,KAAM,eAAe,MAAM,cAC3B,QAAS,EACX,CACF,EAEA,KAAK,MAAM,UAAU,MAAO,IAAI,CAClC,CAEA,UAA+B,CAC7B,KAAK,SAAS,CAAE,MAAO,IAAK,CAAC,CAC/B,EAEA,QAAkB,CAChB,GAAM,CAAE,OAAU,KAAK,MAEvB,GAAI,MAAO,CACT,GAAM,CAAE,UAAa,KAAK,MAI1B,OAHI,OAAO,UAAa,WACf,SAAS,MAAO,KAAK,KAAK,EAE5B,UAAY,IACrB,CAEA,OAAO,KAAK,MAAM,QACpB,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser-context.d.mts","names":[],"sources":["../../src/internal/browser-context.ts"],"mappings":";;;iBA0GsB,cAAA,CAAA,GAAkB,OAAA,CAAQ,cAAA"}
1
+ {"version":3,"file":"browser-context.d.mts","names":[],"sources":["../../src/internal/browser-context.ts"],"mappings":";;;iBA0GsB,cAAA,CAAA,GAAkB,OAAO,CAAC,cAAA"}
@@ -1,59 +1 @@
1
- import { UAParser } from "@ua-parser-js/pro-enterprise";
2
- import { InApps } from "@ua-parser-js/pro-enterprise/extensions";
3
- import { isFrozenUA } from "@ua-parser-js/pro-enterprise/helpers";
4
- //#region src/internal/browser-context.ts
5
- const NOT_A_BRAND_REGEX = /not.a.brand/i;
6
- const HIGH_ENTROPY_HINTS = [
7
- "bitness",
8
- "platformVersion",
9
- "fullVersionList"
10
- ];
11
- async function getDeviceMetadata() {
12
- if (typeof navigator === "undefined") return null;
13
- const uaData = navigator.userAgentData;
14
- const [parsed, hints] = await Promise.all([UAParser(navigator.userAgent, InApps).withClientHints(), uaData?.getHighEntropyValues ? uaData.getHighEntropyValues(HIGH_ENTROPY_HINTS).catch(() => ({})) : Promise.resolve({})]);
15
- if (!parsed) return null;
16
- const fullVersion = hints.fullVersionList?.find((b) => !NOT_A_BRAND_REGEX.test(b.brand))?.version;
17
- return {
18
- ...parsed,
19
- browser: {
20
- ...parsed.browser,
21
- ...fullVersion ? { fullVersion } : {}
22
- },
23
- cpu: {
24
- ...parsed.cpu,
25
- ...hints.bitness ? { bitness: hints.bitness } : {}
26
- },
27
- os: {
28
- ...parsed.os,
29
- ...hints.platformVersion ? { versionFull: hints.platformVersion } : {}
30
- },
31
- frozenUa: isFrozenUA(navigator.userAgent)
32
- };
33
- }
34
- function getBrowserMetadata() {
35
- if ([
36
- typeof navigator,
37
- typeof screen,
38
- typeof globalThis
39
- ].some((x) => x === "undefined")) return null;
40
- const { language } = navigator;
41
- return {
42
- language,
43
- timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
44
- display: { screen: {
45
- height: screen.availHeight,
46
- width: screen.availWidth,
47
- orientation: screen.orientation?.type
48
- } }
49
- };
50
- }
51
- async function collectContext() {
52
- return {
53
- runtime: "browser",
54
- browser: getBrowserMetadata(),
55
- device: await getDeviceMetadata()
56
- };
57
- }
58
- //#endregion
59
- export { collectContext };
1
+ import{UAParser}from"@ua-parser-js/pro-enterprise";import{InApps}from"@ua-parser-js/pro-enterprise/extensions";import{isFrozenUA}from"@ua-parser-js/pro-enterprise/helpers";const NOT_A_BRAND_REGEX=/not.a.brand/i,HIGH_ENTROPY_HINTS=[`bitness`,`platformVersion`,`fullVersionList`];async function getDeviceMetadata(){if(typeof navigator>`u`)return null;let uaData=navigator.userAgentData,[parsed,hints]=await Promise.all([UAParser(navigator.userAgent,InApps).withClientHints(),uaData?.getHighEntropyValues?uaData.getHighEntropyValues(HIGH_ENTROPY_HINTS).catch(()=>({})):Promise.resolve({})]);if(!parsed)return null;let fullVersion=hints.fullVersionList?.find(b=>!NOT_A_BRAND_REGEX.test(b.brand))?.version;return{...parsed,browser:{...parsed.browser,...fullVersion?{fullVersion}:{}},cpu:{...parsed.cpu,...hints.bitness?{bitness:hints.bitness}:{}},os:{...parsed.os,...hints.platformVersion?{versionFull:hints.platformVersion}:{}},frozenUa:isFrozenUA(navigator.userAgent)}}function getBrowserMetadata(){if([typeof navigator,typeof screen,typeof globalThis].some(x=>x===`undefined`))return null;let{language}=navigator;return{language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,display:{screen:{height:screen.availHeight,width:screen.availWidth,orientation:screen.orientation?.type}}}}async function collectContext(){return{runtime:`browser`,browser:getBrowserMetadata(),device:await getDeviceMetadata()}}export{collectContext};
@@ -1 +1 @@
1
- {"version":3,"file":"browser-context.mjs","names":[],"sources":["../../src/internal/browser-context.ts"],"sourcesContent":["import type {\n BrowserContext,\n BrowserMetadata,\n DeviceMetadata,\n} from \"@interfere/types/sdk/plugins/context/browser\";\n\nimport { UAParser } from \"@ua-parser-js/pro-enterprise\";\nimport { InApps } from \"@ua-parser-js/pro-enterprise/extensions\";\nimport { isFrozenUA } from \"@ua-parser-js/pro-enterprise/helpers\";\n\ninterface NavigatorUABrand {\n brand: string;\n version: string;\n}\n\ninterface NavigatorUAData {\n brands?: NavigatorUABrand[];\n getHighEntropyValues?: (hints: string[]) => Promise<HighEntropyValues>;\n}\n\ninterface HighEntropyValues {\n bitness?: string;\n fullVersionList?: NavigatorUABrand[];\n platformVersion?: string;\n}\n\nconst NOT_A_BRAND_REGEX = /not.a.brand/i;\nconst HIGH_ENTROPY_HINTS = [\"bitness\", \"platformVersion\", \"fullVersionList\"];\n\nasync function getDeviceMetadata(): Promise<DeviceMetadata | null> {\n if (typeof navigator === \"undefined\") {\n return null;\n }\n\n const uaData = (navigator as Navigator & { userAgentData?: NavigatorUAData })\n .userAgentData;\n\n // `withClientHints()` resolves with UA-only data on non-Chromium and never\n // rejects. We separately request the raw high-entropy values so we can\n // surface `bitness`, the unrounded `platformVersion`, and the full\n // browser version — fields the parser folds into existing slots and\n // therefore loses precision on. `getHighEntropyValues` can reject with\n // `NotAllowedError` (Permissions Policy / Privacy Budget); swallow it.\n // The `InApps` extension is merged into the default regex map (see\n // `extend(defaultRegexes, extensions)` in ua-parser-js), so we still get\n // normal browser/OS detection plus tagging for in-app browsers (Slack,\n // Teams, Discord, VS Code, etc.) — those land as `browser.type: \"inapp\"`.\n const [parsed, hints] = await Promise.all([\n UAParser(navigator.userAgent, InApps).withClientHints(),\n uaData?.getHighEntropyValues\n ? uaData\n .getHighEntropyValues(HIGH_ENTROPY_HINTS)\n .catch((): HighEntropyValues => ({}))\n : Promise.resolve<HighEntropyValues>({}),\n ]);\n\n if (!parsed) {\n return null;\n }\n\n const fullVersion = hints.fullVersionList?.find(\n (b) => !NOT_A_BRAND_REGEX.test(b.brand)\n )?.version;\n\n return {\n ...parsed,\n browser: {\n ...parsed.browser,\n ...(fullVersion ? { fullVersion } : {}),\n },\n cpu: {\n ...parsed.cpu,\n ...(hints.bitness ? { bitness: hints.bitness } : {}),\n },\n os: {\n ...parsed.os,\n ...(hints.platformVersion ? { versionFull: hints.platformVersion } : {}),\n },\n frozenUa: isFrozenUA(navigator.userAgent),\n };\n}\n\nfunction getBrowserMetadata(): BrowserMetadata | null {\n if (\n [typeof navigator, typeof screen, typeof globalThis].some(\n (x) => x === \"undefined\"\n )\n ) {\n return null;\n }\n\n const { language } = navigator;\n\n return {\n language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n display: {\n screen: {\n height: screen.availHeight,\n width: screen.availWidth,\n orientation: screen.orientation?.type,\n },\n },\n };\n}\n\nexport async function collectContext(): Promise<BrowserContext> {\n return {\n runtime: \"browser\",\n browser: getBrowserMetadata(),\n device: await getDeviceMetadata(),\n };\n}\n"],"mappings":";;;;AA0BA,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;CAAC;CAAW;CAAmB;CAAkB;AAE5E,eAAe,oBAAoD;CACjE,IAAI,OAAO,cAAc,aACvB,OAAO;CAGT,MAAM,SAAU,UACb;CAYH,MAAM,CAAC,QAAQ,SAAS,MAAM,QAAQ,IAAI,CACxC,SAAS,UAAU,WAAW,OAAO,CAAC,iBAAiB,EACvD,QAAQ,uBACJ,OACG,qBAAqB,mBAAmB,CACxC,aAAgC,EAAE,EAAE,GACvC,QAAQ,QAA2B,EAAE,CAAC,CAC3C,CAAC;CAEF,IAAI,CAAC,QACH,OAAO;CAGT,MAAM,cAAc,MAAM,iBAAiB,MACxC,MAAM,CAAC,kBAAkB,KAAK,EAAE,MAAM,CACxC,EAAE;CAEH,OAAO;EACL,GAAG;EACH,SAAS;GACP,GAAG,OAAO;GACV,GAAI,cAAc,EAAE,aAAa,GAAG,EAAE;GACvC;EACD,KAAK;GACH,GAAG,OAAO;GACV,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,SAAS,GAAG,EAAE;GACpD;EACD,IAAI;GACF,GAAG,OAAO;GACV,GAAI,MAAM,kBAAkB,EAAE,aAAa,MAAM,iBAAiB,GAAG,EAAE;GACxE;EACD,UAAU,WAAW,UAAU,UAAU;EAC1C;;AAGH,SAAS,qBAA6C;CACpD,IACE;EAAC,OAAO;EAAW,OAAO;EAAQ,OAAO;EAAW,CAAC,MAClD,MAAM,MAAM,YACd,EAED,OAAO;CAGT,MAAM,EAAE,aAAa;CAErB,OAAO;EACL;EACA,UAAU,KAAK,gBAAgB,CAAC,iBAAiB,CAAC;EAClD,SAAS,EACP,QAAQ;GACN,QAAQ,OAAO;GACf,OAAO,OAAO;GACd,aAAa,OAAO,aAAa;GAClC,EACF;EACF;;AAGH,eAAsB,iBAA0C;CAC9D,OAAO;EACL,SAAS;EACT,SAAS,oBAAoB;EAC7B,QAAQ,MAAM,mBAAmB;EAClC"}
1
+ {"version":3,"file":"browser-context.mjs","names":[],"sources":["../../src/internal/browser-context.ts"],"sourcesContent":["import type {\n BrowserContext,\n BrowserMetadata,\n DeviceMetadata,\n} from \"@interfere/types/sdk/plugins/context/browser\";\n\nimport { UAParser } from \"@ua-parser-js/pro-enterprise\";\nimport { InApps } from \"@ua-parser-js/pro-enterprise/extensions\";\nimport { isFrozenUA } from \"@ua-parser-js/pro-enterprise/helpers\";\n\ninterface NavigatorUABrand {\n brand: string;\n version: string;\n}\n\ninterface NavigatorUAData {\n brands?: NavigatorUABrand[];\n getHighEntropyValues?: (hints: string[]) => Promise<HighEntropyValues>;\n}\n\ninterface HighEntropyValues {\n bitness?: string;\n fullVersionList?: NavigatorUABrand[];\n platformVersion?: string;\n}\n\nconst NOT_A_BRAND_REGEX = /not.a.brand/i;\nconst HIGH_ENTROPY_HINTS = [\"bitness\", \"platformVersion\", \"fullVersionList\"];\n\nasync function getDeviceMetadata(): Promise<DeviceMetadata | null> {\n if (typeof navigator === \"undefined\") {\n return null;\n }\n\n const uaData = (navigator as Navigator & { userAgentData?: NavigatorUAData })\n .userAgentData;\n\n // `withClientHints()` resolves with UA-only data on non-Chromium and never\n // rejects. We separately request the raw high-entropy values so we can\n // surface `bitness`, the unrounded `platformVersion`, and the full\n // browser version — fields the parser folds into existing slots and\n // therefore loses precision on. `getHighEntropyValues` can reject with\n // `NotAllowedError` (Permissions Policy / Privacy Budget); swallow it.\n // The `InApps` extension is merged into the default regex map (see\n // `extend(defaultRegexes, extensions)` in ua-parser-js), so we still get\n // normal browser/OS detection plus tagging for in-app browsers (Slack,\n // Teams, Discord, VS Code, etc.) — those land as `browser.type: \"inapp\"`.\n const [parsed, hints] = await Promise.all([\n UAParser(navigator.userAgent, InApps).withClientHints(),\n uaData?.getHighEntropyValues\n ? uaData\n .getHighEntropyValues(HIGH_ENTROPY_HINTS)\n .catch((): HighEntropyValues => ({}))\n : Promise.resolve<HighEntropyValues>({}),\n ]);\n\n if (!parsed) {\n return null;\n }\n\n const fullVersion = hints.fullVersionList?.find(\n (b) => !NOT_A_BRAND_REGEX.test(b.brand)\n )?.version;\n\n return {\n ...parsed,\n browser: {\n ...parsed.browser,\n ...(fullVersion ? { fullVersion } : {}),\n },\n cpu: {\n ...parsed.cpu,\n ...(hints.bitness ? { bitness: hints.bitness } : {}),\n },\n os: {\n ...parsed.os,\n ...(hints.platformVersion ? { versionFull: hints.platformVersion } : {}),\n },\n frozenUa: isFrozenUA(navigator.userAgent),\n };\n}\n\nfunction getBrowserMetadata(): BrowserMetadata | null {\n if (\n [typeof navigator, typeof screen, typeof globalThis].some(\n (x) => x === \"undefined\"\n )\n ) {\n return null;\n }\n\n const { language } = navigator;\n\n return {\n language,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n display: {\n screen: {\n height: screen.availHeight,\n width: screen.availWidth,\n orientation: screen.orientation?.type,\n },\n },\n };\n}\n\nexport async function collectContext(): Promise<BrowserContext> {\n return {\n runtime: \"browser\",\n browser: getBrowserMetadata(),\n device: await getDeviceMetadata(),\n };\n}\n"],"mappings":"4KA0BA,MAAM,kBAAoB,eACpB,mBAAqB,CAAC,UAAW,kBAAmB,iBAAiB,EAE3E,eAAe,mBAAoD,CACjE,GAAI,OAAO,UAAc,IACvB,OAAO,KAGT,IAAM,OAAU,UACb,cAYG,CAAC,OAAQ,OAAS,MAAM,QAAQ,IAAI,CACxC,SAAS,UAAU,UAAW,MAAM,EAAE,gBAAgB,EACtD,QAAQ,qBACJ,OACG,qBAAqB,kBAAkB,EACvC,WAAgC,CAAC,EAAE,EACtC,QAAQ,QAA2B,CAAC,CAAC,CAC3C,CAAC,EAED,GAAI,CAAC,OACH,OAAO,KAGT,IAAM,YAAc,MAAM,iBAAiB,KACxC,GAAM,CAAC,kBAAkB,KAAK,EAAE,KAAK,CACxC,GAAG,QAEH,MAAO,CACL,GAAG,OACH,QAAS,CACP,GAAG,OAAO,QACV,GAAI,YAAc,CAAE,WAAY,EAAI,CAAC,CACvC,EACA,IAAK,CACH,GAAG,OAAO,IACV,GAAI,MAAM,QAAU,CAAE,QAAS,MAAM,OAAQ,EAAI,CAAC,CACpD,EACA,GAAI,CACF,GAAG,OAAO,GACV,GAAI,MAAM,gBAAkB,CAAE,YAAa,MAAM,eAAgB,EAAI,CAAC,CACxE,EACA,SAAU,WAAW,UAAU,SAAS,CAC1C,CACF,CAEA,SAAS,oBAA6C,CACpD,GACE,CAAC,OAAO,UAAW,OAAO,OAAQ,OAAO,UAAU,EAAE,KAClD,GAAM,IAAM,WACf,EAEA,OAAO,KAGT,GAAM,CAAE,UAAa,UAErB,MAAO,CACL,SACA,SAAU,KAAK,eAAe,EAAE,gBAAgB,EAAE,SAClD,QAAS,CACP,OAAQ,CACN,OAAQ,OAAO,YACf,MAAO,OAAO,WACd,YAAa,OAAO,aAAa,IACnC,CACF,CACF,CACF,CAEA,eAAsB,gBAA0C,CAC9D,MAAO,CACL,QAAS,UACT,QAAS,mBAAmB,EAC5B,OAAQ,MAAM,kBAAkB,CAClC,CACF"}
@@ -1,5 +1,4 @@
1
1
  import { InterfereContext, InterfereContextValue } from "./react-context.mjs";
2
- import * as _$react from "react";
3
2
  import { Component, ContextType, ReactNode } from "react";
4
3
 
5
4
  //#region src/internal/capture-boundary.d.ts
@@ -33,7 +32,7 @@ interface CaptureBoundaryState {
33
32
  * captured the error but did not render a fallback — propagation continues.
34
33
  */
35
34
  declare class CaptureBoundary extends Component<CaptureBoundaryProps, CaptureBoundaryState> {
36
- static contextType: _$react.Context<InterfereContextValue | null>;
35
+ static contextType: import("react").Context<InterfereContextValue | null>;
37
36
  context: ContextType<typeof InterfereContext>;
38
37
  state: CaptureBoundaryState;
39
38
  static getDerivedStateFromError(error: Error): CaptureBoundaryState;
@@ -1 +1 @@
1
- {"version":3,"file":"capture-boundary.d.mts","names":[],"sources":["../../src/internal/capture-boundary.tsx"],"mappings":";;;;;UASU,oBAAA;EACR,QAAA,EAAU,SAAA;AAAA;AAAA,UAGF,oBAAA;EACR,KAAA,EAAO,KAAA;AAAA;;;AAJY;;;;;AA8BrB;;;;;;;;;;;;;;;;cAAa,eAAA,SAAwB,SAAA,CACnC,oBAAA,EACA,oBAAA;EAAA,OAEgB,WAAA,EAAW,OAAA,CAAA,OAAA,CAFP,qBAAA;EAGZ,OAAA,EAAS,WAAA,QAAmB,gBAAA;EAE3B,KAAA,EAAO,oBAAA;EAAA,OAET,wBAAA,CAAyB,KAAA,EAAO,KAAA,GAAQ,oBAAA;EAItC,MAAA,CAAA,GAAU,SAAA;AAAA"}
1
+ {"version":3,"file":"capture-boundary.d.mts","names":[],"sources":["../../src/internal/capture-boundary.tsx"],"mappings":";;;;UASU,oBAAA;EACR,QAAA,EAAU,SAAS;AAAA;AAAA,UAGX,oBAAA;EACR,KAAA,EAAO,KAAK;AAAA;AAJO;AAAA;;;;AAIP;AA0Bd;;;;;;;;;;;;;;;;;AA9BqB,cA8BR,eAAA,SAAwB,SAAA,CACnC,oBAAA,EACA,oBAAA;EAAA,OAEgB,WAAA,kBAAW,OAAA,CAFP,qBAAA;EAGZ,OAAA,EAAS,WAAA,QAAmB,gBAAA;EAE3B,KAAA,EAAO,oBAAA;EAAA,OAET,wBAAA,CAAyB,KAAA,EAAO,KAAA,GAAQ,oBAAA;EAItC,MAAA,CAAA,GAAU,SAAA;AAAA"}
@@ -1,48 +1 @@
1
- "use client";
2
- import { captureReactError } from "./capture.mjs";
3
- import { InterfereContext } from "./react-context.mjs";
4
- import { MECHANISM_TYPE } from "@interfere/types/sdk/errors";
5
- import { Component } from "react";
6
- //#region src/internal/capture-boundary.tsx
7
- /**
8
- * Internal boundary used by `<InterfereProvider>` to capture render-phase
9
- * React errors without changing the app's UX.
10
- *
11
- * Unlike the public `ErrorBoundary`, this boundary always re-throws the
12
- * captured error in its `render()` so upstream boundaries — the customer's
13
- * own `ErrorBoundary`, Next.js's `error.tsx` / `global-error.tsx`, or React's
14
- * default unmount — keep control of what the user sees. The net effect:
15
- * zero visual change, full capture coverage for any render-phase error in
16
- * the subtree.
17
- *
18
- * Capture happens inside `getDerivedStateFromError` rather than
19
- * `componentDidCatch` because `componentDidCatch` does not fire on a boundary
20
- * that re-throws in render — React considers such a boundary to have failed
21
- * and skips its commit-phase lifecycle. The trade-off: we don't get
22
- * `errorInfo.componentStack` in this capture. Callers who want the component
23
- * tree should use the public `ErrorBoundary` (which renders a fallback and
24
- * therefore receives `componentDidCatch`), or pass
25
- * {@link reactErrorHandler} to `createRoot()`.
26
- *
27
- * `mechanism.handled` is `false` because from Interfere's perspective we
28
- * captured the error but did not render a fallback — propagation continues.
29
- */
30
- var CaptureBoundary = class extends Component {
31
- static contextType = InterfereContext;
32
- state = { error: null };
33
- static getDerivedStateFromError(error) {
34
- return { error };
35
- }
36
- render() {
37
- if (this.state.error) {
38
- captureReactError(this.context?.kernel ?? null, this.state.error, null, {
39
- type: MECHANISM_TYPE.react.captureBoundary,
40
- handled: false
41
- });
42
- throw this.state.error;
43
- }
44
- return this.props.children;
45
- }
46
- };
47
- //#endregion
48
- export { CaptureBoundary };
1
+ "use client";import{captureReactError}from"./capture.mjs";import{InterfereContext}from"./react-context.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";import{Component}from"react";var CaptureBoundary=class extends Component{static contextType=InterfereContext;state={error:null};static getDerivedStateFromError(error){return{error}}render(){if(this.state.error)throw captureReactError(this.context?.kernel??null,this.state.error,null,{type:MECHANISM_TYPE.react.captureBoundary,handled:!1}),this.state.error;return this.props.children}};export{CaptureBoundary};
@@ -1 +1 @@
1
- {"version":3,"file":"capture-boundary.mjs","names":[],"sources":["../../src/internal/capture-boundary.tsx"],"sourcesContent":["\"use client\";\n\nimport { MECHANISM_TYPE } from \"@interfere/types/sdk/errors\";\n\nimport { Component, type ContextType, type ReactNode } from \"react\";\n\nimport { captureReactError } from \"./capture.js\";\nimport { InterfereContext } from \"./react-context.js\";\n\ninterface CaptureBoundaryProps {\n children: ReactNode;\n}\n\ninterface CaptureBoundaryState {\n error: Error | null;\n}\n\n/**\n * Internal boundary used by `<InterfereProvider>` to capture render-phase\n * React errors without changing the app's UX.\n *\n * Unlike the public `ErrorBoundary`, this boundary always re-throws the\n * captured error in its `render()` so upstream boundaries — the customer's\n * own `ErrorBoundary`, Next.js's `error.tsx` / `global-error.tsx`, or React's\n * default unmount — keep control of what the user sees. The net effect:\n * zero visual change, full capture coverage for any render-phase error in\n * the subtree.\n *\n * Capture happens inside `getDerivedStateFromError` rather than\n * `componentDidCatch` because `componentDidCatch` does not fire on a boundary\n * that re-throws in render — React considers such a boundary to have failed\n * and skips its commit-phase lifecycle. The trade-off: we don't get\n * `errorInfo.componentStack` in this capture. Callers who want the component\n * tree should use the public `ErrorBoundary` (which renders a fallback and\n * therefore receives `componentDidCatch`), or pass\n * {@link reactErrorHandler} to `createRoot()`.\n *\n * `mechanism.handled` is `false` because from Interfere's perspective we\n * captured the error but did not render a fallback — propagation continues.\n */\nexport class CaptureBoundary extends Component<\n CaptureBoundaryProps,\n CaptureBoundaryState\n> {\n static override contextType = InterfereContext;\n declare context: ContextType<typeof InterfereContext>;\n\n override state: CaptureBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): CaptureBoundaryState {\n return { error };\n }\n\n override render(): ReactNode {\n if (this.state.error) {\n // Capture before re-throwing. `componentDidCatch` never fires when\n // render throws (React treats the boundary itself as failed), so the\n // capture has to happen here. `captureReactError` dedupes on the\n // error instance, so the multiple-render case in concurrent React\n // doesn't cause duplicate captures.\n captureReactError(this.context?.kernel ?? null, this.state.error, null, {\n type: MECHANISM_TYPE.react.captureBoundary,\n handled: false,\n });\n throw this.state.error;\n }\n return this.props.children;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,IAAa,kBAAb,cAAqC,UAGnC;CACA,OAAgB,cAAc;CAG9B,QAAuC,EAAE,OAAO,MAAM;CAEtD,OAAO,yBAAyB,OAAoC;EAClE,OAAO,EAAE,OAAO;;CAGlB,SAA6B;EAC3B,IAAI,KAAK,MAAM,OAAO;GAMpB,kBAAkB,KAAK,SAAS,UAAU,MAAM,KAAK,MAAM,OAAO,MAAM;IACtE,MAAM,eAAe,MAAM;IAC3B,SAAS;IACV,CAAC;GACF,MAAM,KAAK,MAAM;;EAEnB,OAAO,KAAK,MAAM"}
1
+ {"version":3,"file":"capture-boundary.mjs","names":[],"sources":["../../src/internal/capture-boundary.tsx"],"sourcesContent":["\"use client\";\n\nimport { MECHANISM_TYPE } from \"@interfere/types/sdk/errors\";\n\nimport { Component, type ContextType, type ReactNode } from \"react\";\n\nimport { captureReactError } from \"./capture.js\";\nimport { InterfereContext } from \"./react-context.js\";\n\ninterface CaptureBoundaryProps {\n children: ReactNode;\n}\n\ninterface CaptureBoundaryState {\n error: Error | null;\n}\n\n/**\n * Internal boundary used by `<InterfereProvider>` to capture render-phase\n * React errors without changing the app's UX.\n *\n * Unlike the public `ErrorBoundary`, this boundary always re-throws the\n * captured error in its `render()` so upstream boundaries — the customer's\n * own `ErrorBoundary`, Next.js's `error.tsx` / `global-error.tsx`, or React's\n * default unmount — keep control of what the user sees. The net effect:\n * zero visual change, full capture coverage for any render-phase error in\n * the subtree.\n *\n * Capture happens inside `getDerivedStateFromError` rather than\n * `componentDidCatch` because `componentDidCatch` does not fire on a boundary\n * that re-throws in render — React considers such a boundary to have failed\n * and skips its commit-phase lifecycle. The trade-off: we don't get\n * `errorInfo.componentStack` in this capture. Callers who want the component\n * tree should use the public `ErrorBoundary` (which renders a fallback and\n * therefore receives `componentDidCatch`), or pass\n * {@link reactErrorHandler} to `createRoot()`.\n *\n * `mechanism.handled` is `false` because from Interfere's perspective we\n * captured the error but did not render a fallback — propagation continues.\n */\nexport class CaptureBoundary extends Component<\n CaptureBoundaryProps,\n CaptureBoundaryState\n> {\n static override contextType = InterfereContext;\n declare context: ContextType<typeof InterfereContext>;\n\n override state: CaptureBoundaryState = { error: null };\n\n static getDerivedStateFromError(error: Error): CaptureBoundaryState {\n return { error };\n }\n\n override render(): ReactNode {\n if (this.state.error) {\n // Capture before re-throwing. `componentDidCatch` never fires when\n // render throws (React treats the boundary itself as failed), so the\n // capture has to happen here. `captureReactError` dedupes on the\n // error instance, so the multiple-render case in concurrent React\n // doesn't cause duplicate captures.\n captureReactError(this.context?.kernel ?? null, this.state.error, null, {\n type: MECHANISM_TYPE.react.captureBoundary,\n handled: false,\n });\n throw this.state.error;\n }\n return this.props.children;\n }\n}\n"],"mappings":"iMAwCA,IAAa,gBAAb,cAAqC,SAGnC,CACA,OAAgB,YAAc,iBAG9B,MAAuC,CAAE,MAAO,IAAK,EAErD,OAAO,yBAAyB,MAAoC,CAClE,MAAO,CAAE,KAAM,CACjB,CAEA,QAA6B,CAC3B,GAAI,KAAK,MAAM,MAUb,MAJA,kBAAkB,KAAK,SAAS,QAAU,KAAM,KAAK,MAAM,MAAO,KAAM,CACtE,KAAM,eAAe,MAAM,gBAC3B,QAAS,EACX,CAAC,EACK,KAAK,MAAM,MAEnB,OAAO,KAAK,MAAM,QACpB,CACF"}
@@ -1,27 +1 @@
1
- import { parseReactComponentStack } from "@interfere/types/sdk/errors";
2
- //#region src/internal/capture.ts
3
- /**
4
- * Routes a React error through `kernel.recordException()`, attaching the
5
- * component stack reported by React as additional frames. Dedup of the
6
- * same `Error` instance caught by both the boundary and `window.onerror`
7
- * happens inside `recordException`.
8
- *
9
- * `error.digest` is React's identifier for an RSC server-side throw that
10
- * was sanitised and rebuilt on the client — promote it so enrichment can
11
- * fingerprint the redacted client capture into the same problem as the
12
- * unredacted server capture.
13
- *
14
- * Accepts a nullable kernel — error boundaries can mount outside the
15
- * `<InterfereProvider>` tree, in which case we silently skip capture and
16
- * let the host render its fallback / call its `onError` callback.
17
- */
18
- function captureReactError(kernel, error, componentStack, mechanism) {
19
- if (!kernel) return;
20
- kernel.recordException(error, {
21
- mechanism,
22
- ...componentStack ? { appendFrames: parseReactComponentStack(componentStack) } : {},
23
- ...error.digest ? { errorDigest: error.digest } : {}
24
- });
25
- }
26
- //#endregion
27
- export { captureReactError };
1
+ import{parseReactComponentStack}from"@interfere/types/sdk/errors";function captureReactError(kernel,error,componentStack,mechanism){kernel&&kernel.recordException(error,{mechanism,...componentStack?{appendFrames:parseReactComponentStack(componentStack)}:{},...error.digest?{errorDigest:error.digest}:{}})}export{captureReactError};
@@ -1 +1 @@
1
- {"version":3,"file":"capture.mjs","names":[],"sources":["../../src/internal/capture.ts"],"sourcesContent":["import { parseReactComponentStack } from \"@interfere/types/sdk/errors\";\nimport type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nimport type { Kernel } from \"./kernel.js\";\n\n/**\n * Routes a React error through `kernel.recordException()`, attaching the\n * component stack reported by React as additional frames. Dedup of the\n * same `Error` instance caught by both the boundary and `window.onerror`\n * happens inside `recordException`.\n *\n * `error.digest` is React's identifier for an RSC server-side throw that\n * was sanitised and rebuilt on the client — promote it so enrichment can\n * fingerprint the redacted client capture into the same problem as the\n * unredacted server capture.\n *\n * Accepts a nullable kernel — error boundaries can mount outside the\n * `<InterfereProvider>` tree, in which case we silently skip capture and\n * let the host render its fallback / call its `onError` callback.\n */\nexport function captureReactError(\n kernel: Kernel | null,\n error: Error & { digest?: string },\n componentStack: string | null | undefined,\n mechanism: ErrorMechanism\n): void {\n if (!kernel) {\n return;\n }\n kernel.recordException(error, {\n mechanism,\n ...(componentStack\n ? { appendFrames: parseReactComponentStack(componentStack) }\n : {}),\n ...(error.digest ? { errorDigest: error.digest } : {}),\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAoBA,SAAgB,kBACd,QACA,OACA,gBACA,WACM;CACN,IAAI,CAAC,QACH;CAEF,OAAO,gBAAgB,OAAO;EAC5B;EACA,GAAI,iBACA,EAAE,cAAc,yBAAyB,eAAe,EAAE,GAC1D,EAAE;EACN,GAAI,MAAM,SAAS,EAAE,aAAa,MAAM,QAAQ,GAAG,EAAE;EACtD,CAAC"}
1
+ {"version":3,"file":"capture.mjs","names":[],"sources":["../../src/internal/capture.ts"],"sourcesContent":["import { parseReactComponentStack } from \"@interfere/types/sdk/errors\";\nimport type { ErrorMechanism } from \"@interfere/types/sdk/plugins/payload/errors\";\n\nimport type { Kernel } from \"./kernel.js\";\n\n/**\n * Routes a React error through `kernel.recordException()`, attaching the\n * component stack reported by React as additional frames. Dedup of the\n * same `Error` instance caught by both the boundary and `window.onerror`\n * happens inside `recordException`.\n *\n * `error.digest` is React's identifier for an RSC server-side throw that\n * was sanitised and rebuilt on the client — promote it so enrichment can\n * fingerprint the redacted client capture into the same problem as the\n * unredacted server capture.\n *\n * Accepts a nullable kernel — error boundaries can mount outside the\n * `<InterfereProvider>` tree, in which case we silently skip capture and\n * let the host render its fallback / call its `onError` callback.\n */\nexport function captureReactError(\n kernel: Kernel | null,\n error: Error & { digest?: string },\n componentStack: string | null | undefined,\n mechanism: ErrorMechanism\n): void {\n if (!kernel) {\n return;\n }\n kernel.recordException(error, {\n mechanism,\n ...(componentStack\n ? { appendFrames: parseReactComponentStack(componentStack) }\n : {}),\n ...(error.digest ? { errorDigest: error.digest } : {}),\n });\n}\n"],"mappings":"kEAoBA,SAAgB,kBACd,OACA,MACA,eACA,UACM,CACD,QAGL,OAAO,gBAAgB,MAAO,CAC5B,UACA,GAAI,eACA,CAAE,aAAc,yBAAyB,cAAc,CAAE,EACzD,CAAC,EACL,GAAI,MAAM,OAAS,CAAE,YAAa,MAAM,MAAO,EAAI,CAAC,CACtD,CAAC,CACH"}
@@ -6,6 +6,8 @@ interface IngestTarget {
6
6
  interface AuthHeaders {
7
7
  headers: Headers;
8
8
  }
9
+ declare function withQueryParam(url: string, key: string, value: string): string;
10
+ declare function appendPathBeforeQuery(url: string, path: string): string;
9
11
  declare function resolveTargets(): {
10
12
  /**
11
13
  * Base URL for OTLP exports — the trace/metric exporters append the
@@ -23,4 +25,4 @@ declare function resolveTargets(): {
23
25
  session: IngestTarget;
24
26
  };
25
27
  //#endregion
26
- export { AuthHeaders, IngestTarget, resolveTargets };
28
+ export { AuthHeaders, IngestTarget, appendPathBeforeQuery, resolveTargets, withQueryParam };
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/internal/config.ts"],"mappings":";UAKiB,YAAA;EACf,OAAA,EAAS,OAAA;EACT,GAAA;AAAA;AAAA,UAGe,WAAA;EACf,OAAA,EAAS,OAAA;AAAA;AAAA,iBAsBK,cAAA,CAAA;EA1BX;;AAGL;;;EA6BE,gBAAA;EACA,MAAA,EAAQ,YAAA;EAPM;;;;;EAad,MAAA,EAAQ,WAAA;EACR,OAAA,EAAS,YAAA;AAAA"}
1
+ {"version":3,"file":"config.d.mts","names":[],"sources":["../../src/internal/config.ts"],"mappings":";UAUiB,YAAA;EACf,OAAA,EAAS,OAAO;EAChB,GAAA;AAAA;AAAA,UAGe,WAAA;EACf,OAAA,EAAS,OAAO;AAAA;AAAA,iBA0CF,cAAA,CACd,GAAA,UACA,GAAA,UACA,KAAA;AAAA,iBAWc,qBAAA,CAAsB,GAAA,UAAa,IAAY;AAAA,iBAO/C,cAAA,CAAA;EAhEC;;;;AACC;EAqEhB,gBAAA;EACA,MAAA,EAAQ,YAAA;;;;;;EAMR,MAAA,EAAQ,WAAA;EACR,OAAA,EAAS,YAAA;AAAA"}
@@ -1,33 +1 @@
1
- import { getGlobal } from "../util/global.mjs";
2
- import { API_PATHS, API_URL } from "@interfere/constants/api";
3
- import { resolveRoutePrefix } from "@interfere/constants/route-prefix";
4
- //#region src/internal/config.ts
5
- function resolvePublicKey() {
6
- const injected = getGlobal("__INTERFERE_PUBLIC_KEY__");
7
- if (injected) return injected;
8
- if (typeof process !== "undefined") return process.env["INTERFERE_PUBLIC_KEY"] ?? void 0;
9
- }
10
- function isForceEnableActive() {
11
- return !!getGlobal("__INTERFERE_FORCE_ENABLE__");
12
- }
13
- function resolveTargets() {
14
- const publicKey = resolvePublicKey();
15
- const headers = new Headers({ "content-type": "application/json" });
16
- if (publicKey) headers.set("x-interfere-pub-token", publicKey);
17
- if (isForceEnableActive()) headers.set("x-interfere-force-enable", "1");
18
- const baseUrl = publicKey ? API_URL : resolveRoutePrefix();
19
- return {
20
- collectorBaseUrl: baseUrl,
21
- config: {
22
- url: `${baseUrl}${API_PATHS.CONFIG}`,
23
- headers
24
- },
25
- ingest: { headers },
26
- session: {
27
- url: `${baseUrl}${API_PATHS.SESSION}`,
28
- headers
29
- }
30
- };
31
- }
32
- //#endregion
33
- export { resolveTargets };
1
+ import{getGlobal}from"../util/global.mjs";import{API_PATHS,API_URL}from"@interfere/constants/api";import{resolveRoutePrefix}from"@interfere/constants/route-prefix";const TRAILING_SLASH_RE=/\/$/,RELATIVE_URL_BASE=`https://interfere.local`;function resolvePublicKey(){let injected=getGlobal(`__INTERFERE_PUBLIC_KEY__`);if(injected)return injected;if(typeof process<`u`)return process.env.INTERFERE_PUBLIC_KEY??void 0}function resolveApiUrlOverride(){let injected=getGlobal(`__INTERFERE_API_URL__`);if(injected)return injected}function isForceEnableActive(){return!!getGlobal(`__INTERFERE_FORCE_ENABLE__`)}function isProxyModeActive(){return!!getGlobal(`__INTERFERE_PROXY_MODE__`)}function serializeUrl(input,url){return input.startsWith(`/`)?`${url.pathname}${url.search}`:url.toString()}function withQueryParam(url,key,value){let next=new URL(url,RELATIVE_URL_BASE);return next.searchParams.set(key,value),serializeUrl(url,next)}function appendPublicKey(url,publicKey){return publicKey?withQueryParam(url,`pk`,publicKey):url}function appendPathBeforeQuery(url,path){let next=new URL(url,RELATIVE_URL_BASE),suffix=path.startsWith(`/`)?path:`/${path}`;return next.pathname=`${next.pathname.replace(TRAILING_SLASH_RE,``)}${suffix}`,serializeUrl(url,next)}function resolveTargets(){let publicKey=resolvePublicKey(),headers=new Headers({"content-type":`application/json`});isForceEnableActive()&&headers.set(`x-interfere-force-enable`,`1`);let baseUrl=publicKey&&!isProxyModeActive()?resolveApiUrlOverride()??API_URL:resolveRoutePrefix();return{collectorBaseUrl:appendPublicKey(baseUrl,publicKey),config:{url:appendPublicKey(`${baseUrl}${API_PATHS.CONFIG}`,publicKey),headers},ingest:{headers},session:{url:appendPublicKey(`${baseUrl}${API_PATHS.SESSION}`,publicKey),headers}}}export{appendPathBeforeQuery,resolveTargets,withQueryParam};
@@ -1 +1 @@
1
- {"version":3,"file":"config.mjs","names":[],"sources":["../../src/internal/config.ts"],"sourcesContent":["import { API_PATHS, API_URL } from \"@interfere/constants/api\";\nimport { resolveRoutePrefix } from \"@interfere/constants/route-prefix\";\n\nimport { getGlobal } from \"../util/global.js\";\n\nexport interface IngestTarget {\n headers: Headers;\n url: string;\n}\n\nexport interface AuthHeaders {\n headers: Headers;\n}\n\nfunction resolvePublicKey(): string | undefined {\n // Vite plugin injects the key onto globalThis at build time\n const injected = getGlobal<string>(\"__INTERFERE_PUBLIC_KEY__\");\n if (injected) {\n return injected;\n }\n\n // Node / webpack / Next.js: read from process.env\n if (typeof process !== \"undefined\") {\n return process.env[\"INTERFERE_PUBLIC_KEY\"] ?? undefined;\n }\n\n return;\n}\n\nfunction isForceEnableActive(): boolean {\n return !!getGlobal<boolean>(\"__INTERFERE_FORCE_ENABLE__\");\n}\n\nexport function resolveTargets(): {\n /**\n * Base URL for OTLP exports — the trace/metric exporters append the\n * sink path themselves. Avoids the kernel having to regex-strip\n * `/v2/sink` off the configured URL to derive a base.\n */\n collectorBaseUrl: string;\n config: IngestTarget;\n /**\n * Identity headers shared across every collector-bound request\n * (OTLP exporters, replay upload, session sync). One source of\n * truth for auth + force-enable.\n */\n ingest: AuthHeaders;\n session: IngestTarget;\n} {\n const publicKey = resolvePublicKey();\n const headers = new Headers({ \"content-type\": \"application/json\" });\n if (publicKey) {\n headers.set(\"x-interfere-pub-token\", publicKey);\n }\n // Single chokepoint: every collector request (OTLP exporters, replay\n // upload, session, config) reuses these headers, so the force-enable\n // flag travels everywhere a customer event might. Production\n // collectors drop on this header (ENG-1356).\n if (isForceEnableActive()) {\n headers.set(\"x-interfere-force-enable\", \"1\");\n }\n\n const baseUrl = publicKey ? API_URL : resolveRoutePrefix();\n\n return {\n collectorBaseUrl: baseUrl,\n config: {\n url: `${baseUrl}${API_PATHS.CONFIG}`,\n headers,\n },\n ingest: { headers },\n session: {\n url: `${baseUrl}${API_PATHS.SESSION}`,\n headers,\n },\n };\n}\n"],"mappings":";;;;AAcA,SAAS,mBAAuC;CAE9C,MAAM,WAAW,UAAkB,2BAA2B;CAC9D,IAAI,UACF,OAAO;CAIT,IAAI,OAAO,YAAY,aACrB,OAAO,QAAQ,IAAI,2BAA2B,KAAA;;AAMlD,SAAS,sBAA+B;CACtC,OAAO,CAAC,CAAC,UAAmB,6BAA6B;;AAG3D,SAAgB,iBAed;CACA,MAAM,YAAY,kBAAkB;CACpC,MAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,oBAAoB,CAAC;CACnE,IAAI,WACF,QAAQ,IAAI,yBAAyB,UAAU;CAMjD,IAAI,qBAAqB,EACvB,QAAQ,IAAI,4BAA4B,IAAI;CAG9C,MAAM,UAAU,YAAY,UAAU,oBAAoB;CAE1D,OAAO;EACL,kBAAkB;EAClB,QAAQ;GACN,KAAK,GAAG,UAAU,UAAU;GAC5B;GACD;EACD,QAAQ,EAAE,SAAS;EACnB,SAAS;GACP,KAAK,GAAG,UAAU,UAAU;GAC5B;GACD;EACF"}
1
+ {"version":3,"file":"config.mjs","names":[],"sources":["../../src/internal/config.ts"],"sourcesContent":["import { API_PATHS, API_URL } from \"@interfere/constants/api\";\nimport { resolveRoutePrefix } from \"@interfere/constants/route-prefix\";\n\nimport { getGlobal } from \"../util/global.js\";\n\nconst PUBLIC_KEY_QUERY = \"pk\";\nconst PROXY_MODE_GLOBAL = \"__INTERFERE_PROXY_MODE__\";\nconst TRAILING_SLASH_RE = /\\/$/;\nconst RELATIVE_URL_BASE = \"https://interfere.local\";\n\nexport interface IngestTarget {\n headers: Headers;\n url: string;\n}\n\nexport interface AuthHeaders {\n headers: Headers;\n}\n\nfunction resolvePublicKey(): string | undefined {\n // Vite plugin injects the key onto globalThis at build time\n const injected = getGlobal<string>(\"__INTERFERE_PUBLIC_KEY__\");\n if (injected) {\n return injected;\n }\n\n // Node / webpack / Next.js: read from process.env\n if (typeof process !== \"undefined\") {\n return process.env[\"INTERFERE_PUBLIC_KEY\"] ?? undefined;\n }\n\n return;\n}\n\nfunction resolveApiUrlOverride(): string | undefined {\n const injected = getGlobal<string>(\"__INTERFERE_API_URL__\");\n if (injected) {\n return injected;\n }\n\n return;\n}\n\nfunction isForceEnableActive(): boolean {\n return !!getGlobal<boolean>(\"__INTERFERE_FORCE_ENABLE__\");\n}\n\nfunction isProxyModeActive(): boolean {\n return !!getGlobal<boolean>(PROXY_MODE_GLOBAL);\n}\n\nfunction serializeUrl(input: string, url: URL): string {\n if (input.startsWith(\"/\")) {\n return `${url.pathname}${url.search}`;\n }\n return url.toString();\n}\n\nexport function withQueryParam(\n url: string,\n key: string,\n value: string\n): string {\n const next = new URL(url, RELATIVE_URL_BASE);\n next.searchParams.set(key, value);\n return serializeUrl(url, next);\n}\n\nfunction appendPublicKey(url: string, publicKey: string | undefined): string {\n return publicKey ? withQueryParam(url, PUBLIC_KEY_QUERY, publicKey) : url;\n}\n\nexport function appendPathBeforeQuery(url: string, path: string): string {\n const next = new URL(url, RELATIVE_URL_BASE);\n const suffix = path.startsWith(\"/\") ? path : `/${path}`;\n next.pathname = `${next.pathname.replace(TRAILING_SLASH_RE, \"\")}${suffix}`;\n return serializeUrl(url, next);\n}\n\nexport function resolveTargets(): {\n /**\n * Base URL for OTLP exports — the trace/metric exporters append the\n * sink path themselves. Avoids the kernel having to regex-strip\n * `/v2/sink` off the configured URL to derive a base.\n */\n collectorBaseUrl: string;\n config: IngestTarget;\n /**\n * Identity headers shared across every collector-bound request\n * (OTLP exporters, replay upload, session sync). One source of\n * truth for auth + force-enable.\n */\n ingest: AuthHeaders;\n session: IngestTarget;\n} {\n const publicKey = resolvePublicKey();\n const headers = new Headers({ \"content-type\": \"application/json\" });\n // Single chokepoint: every collector request (OTLP exporters, replay\n // upload, session, config) reuses these headers, so the force-enable\n // flag travels everywhere a customer event might. Production\n // collectors drop on this header (ENG-1356).\n if (isForceEnableActive()) {\n headers.set(\"x-interfere-force-enable\", \"1\");\n }\n\n const baseUrl =\n publicKey && !isProxyModeActive()\n ? (resolveApiUrlOverride() ?? API_URL)\n : resolveRoutePrefix();\n const authenticatedBaseUrl = appendPublicKey(baseUrl, publicKey);\n\n return {\n collectorBaseUrl: authenticatedBaseUrl,\n config: {\n url: appendPublicKey(`${baseUrl}${API_PATHS.CONFIG}`, publicKey),\n headers,\n },\n ingest: { headers },\n session: {\n url: appendPublicKey(`${baseUrl}${API_PATHS.SESSION}`, publicKey),\n headers,\n },\n };\n}\n"],"mappings":"oKAKA,MAEM,kBAAoB,MACpB,kBAAoB,0BAW1B,SAAS,kBAAuC,CAE9C,IAAM,SAAW,UAAkB,0BAA0B,EAC7D,GAAI,SACF,OAAO,SAIT,GAAI,OAAO,QAAY,IACrB,OAAO,QAAQ,IAAI,sBAA2B,IAAA,EAIlD,CAEA,SAAS,uBAA4C,CACnD,IAAM,SAAW,UAAkB,uBAAuB,EAC1D,GAAI,SACF,OAAO,QAIX,CAEA,SAAS,qBAA+B,CACtC,MAAO,CAAC,CAAC,UAAmB,4BAA4B,CAC1D,CAEA,SAAS,mBAA6B,CACpC,MAAO,CAAC,CAAC,UAAmB,0BAAiB,CAC/C,CAEA,SAAS,aAAa,MAAe,IAAkB,CAIrD,OAHI,MAAM,WAAW,GAAG,EACf,GAAG,IAAI,WAAW,IAAI,SAExB,IAAI,SAAS,CACtB,CAEA,SAAgB,eACd,IACA,IACA,MACQ,CACR,IAAM,KAAO,IAAI,IAAI,IAAK,iBAAiB,EAE3C,OADA,KAAK,aAAa,IAAI,IAAK,KAAK,EACzB,aAAa,IAAK,IAAI,CAC/B,CAEA,SAAS,gBAAgB,IAAa,UAAuC,CAC3E,OAAO,UAAY,eAAe,IAAK,KAAkB,SAAS,EAAI,GACxE,CAEA,SAAgB,sBAAsB,IAAa,KAAsB,CACvE,IAAM,KAAO,IAAI,IAAI,IAAK,iBAAiB,EACrC,OAAS,KAAK,WAAW,GAAG,EAAI,KAAO,IAAI,OAEjD,MADA,MAAK,SAAW,GAAG,KAAK,SAAS,QAAQ,kBAAmB,EAAE,IAAI,SAC3D,aAAa,IAAK,IAAI,CAC/B,CAEA,SAAgB,gBAed,CACA,IAAM,UAAY,iBAAiB,EAC7B,QAAU,IAAI,QAAQ,CAAE,eAAgB,kBAAmB,CAAC,EAK9D,oBAAoB,GACtB,QAAQ,IAAI,2BAA4B,GAAG,EAG7C,IAAM,QACJ,WAAa,CAAC,kBAAkB,EAC3B,sBAAsB,GAAK,QAC5B,mBAAmB,EAGzB,MAAO,CACL,iBAH2B,gBAAgB,QAAS,SAGf,EACrC,OAAQ,CACN,IAAK,gBAAgB,GAAG,UAAU,UAAU,SAAU,SAAS,EAC/D,OACF,EACA,OAAQ,CAAE,OAAQ,EAClB,QAAS,CACP,IAAK,gBAAgB,GAAG,UAAU,UAAU,UAAW,SAAS,EAChE,OACF,CACF,CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"consent.d.mts","names":[],"sources":["../../src/internal/consent.ts"],"mappings":";;;;cASa,eAAA;EAAA,SAGoB,SAAA;EAAA,SAAA,MAAA;AAAA;AAAA,iBAcjB,wBAAA,CAAyB,GAAA,EAAK,SAAA,GAAY,eAAA;AAAA,iBAI1C,gBAAA,CACd,QAAA,EAAU,eAAA,EACV,YAAA,EAAc,YAAA;AAAA,iBASA,kBAAA,CACd,IAAA,EAAM,SAAA,EACN,YAAA,EAAc,YAAA;AAAA,iBAKA,qBAAA,CAAsB,OAAA,GAAU,YAAA,GAAe,YAAA;AAAA,iBAI/C,iBAAA,CACd,OAAA,EAAS,YAAA,SACT,IAAA,EAAM,YAAA"}
1
+ {"version":3,"file":"consent.d.mts","names":[],"sources":["../../src/internal/consent.ts"],"mappings":";;;;cASa,eAAA;EAAA,SAGoB,SAAA;EAAA,SAAA,MAAA;AAAA;AAAA,iBAcjB,wBAAA,CAAyB,GAAA,EAAK,SAAA,GAAY,eAAe;AAAA,iBAIzD,gBAAA,CACd,QAAA,EAAU,eAAA,EACV,YAAA,EAAc,YAAY;AAAA,iBASZ,kBAAA,CACd,IAAA,EAAM,SAAA,EACN,YAAA,EAAc,YAAY;AAAA,iBAKZ,qBAAA,CAAsB,OAAA,GAAU,YAAA,GAAe,YAAY;AAAA,iBAI3D,iBAAA,CACd,OAAA,EAAS,YAAA,SACT,IAAA,EAAM,YAAY"}
@@ -1,27 +1 @@
1
- import { PLUGIN_MANIFEST } from "@interfere/types/sdk/plugins/manifest";
2
- //#region src/internal/consent.ts
3
- const DEFAULT_CONSENT = {
4
- analytics: true,
5
- replay: true
6
- };
7
- const PLUGIN_CONSENT_BY_KEY = Object.fromEntries(PLUGIN_MANIFEST.map((plugin) => [plugin.name, plugin.consentCategory]));
8
- const EVENT_CONSENT_BY_TYPE = Object.fromEntries(PLUGIN_MANIFEST.flatMap((plugin) => plugin.events.map((event) => [event.name, plugin.consentCategory])));
9
- const GATEABLE_CATEGORIES = Object.keys(DEFAULT_CONSENT);
10
- function getPluginConsentCategory(key) {
11
- return PLUGIN_CONSENT_BY_KEY[key];
12
- }
13
- function isConsentAllowed(category, consentState) {
14
- return category === "necessary" || consentState === null || consentState[category] === true;
15
- }
16
- function shouldCaptureEvent(type, consentState) {
17
- return isConsentAllowed(EVENT_CONSENT_BY_TYPE[type], consentState);
18
- }
19
- function resolveGrantedConsent(consent) {
20
- return consent ?? { ...DEFAULT_CONSENT };
21
- }
22
- function hasConsentChanged(current, next) {
23
- for (const category of GATEABLE_CATEGORIES) if (current?.[category] !== next?.[category]) return true;
24
- return false;
25
- }
26
- //#endregion
27
- export { DEFAULT_CONSENT, getPluginConsentCategory, hasConsentChanged, isConsentAllowed, resolveGrantedConsent, shouldCaptureEvent };
1
+ import{PLUGIN_MANIFEST}from"@interfere/types/sdk/plugins/manifest";const DEFAULT_CONSENT={analytics:!0,replay:!0},PLUGIN_CONSENT_BY_KEY=Object.fromEntries(PLUGIN_MANIFEST.map(plugin=>[plugin.name,plugin.consentCategory])),EVENT_CONSENT_BY_TYPE=Object.fromEntries(PLUGIN_MANIFEST.flatMap(plugin=>plugin.events.map(event=>[event.name,plugin.consentCategory]))),GATEABLE_CATEGORIES=Object.keys(DEFAULT_CONSENT);function getPluginConsentCategory(key){return PLUGIN_CONSENT_BY_KEY[key]}function isConsentAllowed(category,consentState){return category===`necessary`||consentState===null||consentState[category]===!0}function shouldCaptureEvent(type,consentState){return isConsentAllowed(EVENT_CONSENT_BY_TYPE[type],consentState)}function resolveGrantedConsent(consent){return consent??{...DEFAULT_CONSENT}}function hasConsentChanged(current,next){for(let category of GATEABLE_CATEGORIES)if(current?.[category]!==next?.[category])return!0;return!1}export{DEFAULT_CONSENT,getPluginConsentCategory,hasConsentChanged,isConsentAllowed,resolveGrantedConsent,shouldCaptureEvent};
@@ -1 +1 @@
1
- {"version":3,"file":"consent.mjs","names":[],"sources":["../../src/internal/consent.ts"],"sourcesContent":["import type { EventType } from \"@interfere/types/sdk/envelope\";\nimport {\n type ConsentCategory,\n type ConsentState,\n type GateableCategory,\n PLUGIN_MANIFEST,\n type PluginKey,\n} from \"@interfere/types/sdk/plugins/manifest\";\n\nexport const DEFAULT_CONSENT = {\n analytics: true,\n replay: true,\n} as const satisfies ConsentState;\n\nconst PLUGIN_CONSENT_BY_KEY = Object.fromEntries(\n PLUGIN_MANIFEST.map((plugin) => [plugin.name, plugin.consentCategory])\n) as Record<PluginKey, ConsentCategory>;\n\nconst EVENT_CONSENT_BY_TYPE = Object.fromEntries(\n PLUGIN_MANIFEST.flatMap((plugin) =>\n plugin.events.map((event) => [event.name, plugin.consentCategory] as const)\n )\n) as Record<EventType, ConsentCategory>;\n\nconst GATEABLE_CATEGORIES = Object.keys(DEFAULT_CONSENT) as GateableCategory[];\n\nexport function getPluginConsentCategory(key: PluginKey): ConsentCategory {\n return PLUGIN_CONSENT_BY_KEY[key];\n}\n\nexport function isConsentAllowed(\n category: ConsentCategory,\n consentState: ConsentState | null\n): boolean {\n return (\n category === \"necessary\" ||\n consentState === null ||\n consentState[category] === true\n );\n}\n\nexport function shouldCaptureEvent(\n type: EventType,\n consentState: ConsentState | null\n): boolean {\n return isConsentAllowed(EVENT_CONSENT_BY_TYPE[type], consentState);\n}\n\nexport function resolveGrantedConsent(consent?: ConsentState): ConsentState {\n return consent ?? { ...DEFAULT_CONSENT };\n}\n\nexport function hasConsentChanged(\n current: ConsentState | null,\n next: ConsentState | null\n): boolean {\n for (const category of GATEABLE_CATEGORIES) {\n if (current?.[category] !== next?.[category]) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":";;AASA,MAAa,kBAAkB;CAC7B,WAAW;CACX,QAAQ;CACT;AAED,MAAM,wBAAwB,OAAO,YACnC,gBAAgB,KAAK,WAAW,CAAC,OAAO,MAAM,OAAO,gBAAgB,CAAC,CACvE;AAED,MAAM,wBAAwB,OAAO,YACnC,gBAAgB,SAAS,WACvB,OAAO,OAAO,KAAK,UAAU,CAAC,MAAM,MAAM,OAAO,gBAAgB,CAAU,CAC5E,CACF;AAED,MAAM,sBAAsB,OAAO,KAAK,gBAAgB;AAExD,SAAgB,yBAAyB,KAAiC;CACxE,OAAO,sBAAsB;;AAG/B,SAAgB,iBACd,UACA,cACS;CACT,OACE,aAAa,eACb,iBAAiB,QACjB,aAAa,cAAc;;AAI/B,SAAgB,mBACd,MACA,cACS;CACT,OAAO,iBAAiB,sBAAsB,OAAO,aAAa;;AAGpE,SAAgB,sBAAsB,SAAsC;CAC1E,OAAO,WAAW,EAAE,GAAG,iBAAiB;;AAG1C,SAAgB,kBACd,SACA,MACS;CACT,KAAK,MAAM,YAAY,qBACrB,IAAI,UAAU,cAAc,OAAO,WACjC,OAAO;CAGX,OAAO"}
1
+ {"version":3,"file":"consent.mjs","names":[],"sources":["../../src/internal/consent.ts"],"sourcesContent":["import type { EventType } from \"@interfere/types/sdk/envelope\";\nimport {\n type ConsentCategory,\n type ConsentState,\n type GateableCategory,\n PLUGIN_MANIFEST,\n type PluginKey,\n} from \"@interfere/types/sdk/plugins/manifest\";\n\nexport const DEFAULT_CONSENT = {\n analytics: true,\n replay: true,\n} as const satisfies ConsentState;\n\nconst PLUGIN_CONSENT_BY_KEY = Object.fromEntries(\n PLUGIN_MANIFEST.map((plugin) => [plugin.name, plugin.consentCategory])\n) as Record<PluginKey, ConsentCategory>;\n\nconst EVENT_CONSENT_BY_TYPE = Object.fromEntries(\n PLUGIN_MANIFEST.flatMap((plugin) =>\n plugin.events.map((event) => [event.name, plugin.consentCategory] as const)\n )\n) as Record<EventType, ConsentCategory>;\n\nconst GATEABLE_CATEGORIES = Object.keys(DEFAULT_CONSENT) as GateableCategory[];\n\nexport function getPluginConsentCategory(key: PluginKey): ConsentCategory {\n return PLUGIN_CONSENT_BY_KEY[key];\n}\n\nexport function isConsentAllowed(\n category: ConsentCategory,\n consentState: ConsentState | null\n): boolean {\n return (\n category === \"necessary\" ||\n consentState === null ||\n consentState[category] === true\n );\n}\n\nexport function shouldCaptureEvent(\n type: EventType,\n consentState: ConsentState | null\n): boolean {\n return isConsentAllowed(EVENT_CONSENT_BY_TYPE[type], consentState);\n}\n\nexport function resolveGrantedConsent(consent?: ConsentState): ConsentState {\n return consent ?? { ...DEFAULT_CONSENT };\n}\n\nexport function hasConsentChanged(\n current: ConsentState | null,\n next: ConsentState | null\n): boolean {\n for (const category of GATEABLE_CATEGORIES) {\n if (current?.[category] !== next?.[category]) {\n return true;\n }\n }\n return false;\n}\n"],"mappings":"mEASA,MAAa,gBAAkB,CAC7B,UAAW,GACX,OAAQ,EACV,EAEM,sBAAwB,OAAO,YACnC,gBAAgB,IAAK,QAAW,CAAC,OAAO,KAAM,OAAO,eAAe,CAAC,CACvE,EAEM,sBAAwB,OAAO,YACnC,gBAAgB,QAAS,QACvB,OAAO,OAAO,IAAK,OAAU,CAAC,MAAM,KAAM,OAAO,eAAe,CAAU,CAC5E,CACF,EAEM,oBAAsB,OAAO,KAAK,eAAe,EAEvD,SAAgB,yBAAyB,IAAiC,CACxE,OAAO,sBAAsB,IAC/B,CAEA,SAAgB,iBACd,SACA,aACS,CACT,OACE,WAAa,aACb,eAAiB,MACjB,aAAa,YAAc,EAE/B,CAEA,SAAgB,mBACd,KACA,aACS,CACT,OAAO,iBAAiB,sBAAsB,MAAO,YAAY,CACnE,CAEA,SAAgB,sBAAsB,QAAsC,CAC1E,OAAO,SAAW,CAAE,GAAG,eAAgB,CACzC,CAEA,SAAgB,kBACd,QACA,KACS,CACT,IAAK,IAAM,YAAY,oBACrB,GAAI,UAAU,YAAc,OAAO,UACjC,MAAO,GAGX,MAAO,EACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"console-patch.d.mts","names":[],"sources":["../../src/internal/console-patch.ts"],"mappings":";;AAUA;;;;;AAQA;;;;cARa,cAAA;AAAA,KAQD,YAAA,WAAuB,cAAA;AAAA,KAEvB,cAAA,IAAkB,KAAA,EAAO,YAAA,EAAc,IAAA;AAAA,iBAiDnC,aAAA,CAAc,OAAA,EAAS,cAAA;;iBAYvB,0BAAA,CAAA"}
1
+ {"version":3,"file":"console-patch.d.mts","names":[],"sources":["../../src/internal/console-patch.ts"],"mappings":";;AAUA;;;;AAMU;AAEV;;;;cARa,cAAA;AAAA,KAQD,YAAA,WAAuB,cAAc;AAAA,KAErC,cAAA,IAAkB,KAAA,EAAO,YAAY,EAAE,IAAA;AAAA,iBAiDnC,aAAA,CAAc,OAAuB,EAAd,cAAc;;iBAYrC,0BAAA,CAAA"}