@interfere/react 12.0.5 → 12.1.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.
- package/README.md +103 -0
- package/dist/actionable-DOmVf_ib.mjs +1 -0
- package/dist/activity-D18VXGTn.mjs +1 -0
- package/dist/{activity-BfYxFVcK.d.mts → activity-Duhfgvxt.d.mts} +1 -1
- package/dist/{api-DEVCOKkJ.d.mts → api-CMPV9rgU.d.mts} +1 -1
- package/dist/api-DXmjUMZE.mjs +1 -0
- package/dist/api.mjs +1 -1
- package/dist/bot-YLSbnCeg.mjs +1 -0
- package/dist/buffer-BRn_kSm-.mjs +1 -0
- package/dist/capture-BV2RlsYg.mjs +1 -0
- package/dist/capture-boundary-Cz0jO-y5.mjs +1 -0
- package/dist/chunking-Dvs3f50A.d.mts +39 -0
- package/dist/chunking-qZffPbyY.mjs +2 -0
- package/dist/compressor-host-BAz6860r.d.mts +9 -0
- package/dist/compressor-host-CrKngamF.mjs +1 -0
- package/dist/config-Bm8myQlS.mjs +1 -0
- package/dist/config-CBqqY1AV.d.mts +29 -0
- package/dist/config-DapTbKhs.mjs +1 -0
- package/dist/{config-Rm-ct4K1.d.mts → config-Dyc09HCZ.d.mts} +2 -1
- package/dist/consent-COUmLJLD.mjs +1 -0
- package/dist/console-patch-WNKoLE7U.mjs +1 -0
- package/dist/delivery-DehIJWRh.mjs +1 -0
- package/dist/device-6T3DYkLD.mjs +1 -0
- package/dist/device-DRK7hhLi.mjs +1 -0
- package/dist/device-metadata-Ffi__vup.mjs +1 -0
- package/dist/{dist-ByNfzdQp.mjs → dist-Bcb677YG.mjs} +2 -2
- package/dist/environment-CoEXhF1a.mjs +1 -0
- package/dist/environment-_LKcAXKG.d.mts +9 -0
- package/dist/error-boundary.d.mts +1 -1
- package/dist/error-boundary.mjs +1 -1
- package/dist/errors-BDmCWb5z.mjs +1 -0
- package/dist/event-capabilities-Dd0Hoaq2.mjs +1 -0
- package/dist/exporter-DjvOtWYJ.mjs +1 -0
- package/dist/exporter-logs-DS2AXWnV.mjs +1 -0
- package/dist/exporter-metrics-DZYqUo6_.mjs +1 -0
- package/dist/geo-D2wa9bGs.mjs +2 -0
- package/dist/global-DYq1Z4_H.mjs +1 -0
- package/dist/http-span-route-t2gig-KI.mjs +1 -0
- package/dist/hydration-BIp2cKhz.mjs +1 -0
- package/dist/index-DBsXraeJ.d.mts +4 -0
- package/dist/initial-navigation-YeK6UUHX.mjs +1 -0
- package/dist/{instrumentations-Bgm2EazU.d.mts → instrumentations-BuccMAMj.d.mts} +8 -1
- package/dist/instrumentations-CY8NcP_M.mjs +1 -0
- package/dist/internal/{activity.d.mts → activity/activity.d.mts} +1 -1
- package/dist/internal/activity/activity.mjs +1 -0
- package/dist/internal/browser-context.mjs +1 -1
- package/dist/internal/capture-boundary.d.mts +1 -1
- package/dist/internal/capture-boundary.mjs +1 -1
- package/dist/internal/capture.d.mts +1 -1
- package/dist/internal/capture.mjs +1 -1
- package/dist/internal/config.d.mts +2 -28
- package/dist/internal/config.mjs +1 -1
- package/dist/internal/consent.mjs +1 -1
- package/dist/internal/console-patch.mjs +1 -1
- package/dist/internal/device-metadata.d.mts +41 -0
- package/dist/internal/device-metadata.mjs +1 -0
- package/dist/internal/dom/actionable.d.mts +4 -13
- package/dist/internal/dom/actionable.mjs +1 -1
- package/dist/internal/dom/privacy.d.mts +2 -0
- package/dist/internal/dom/privacy.mjs +1 -0
- package/dist/internal/environment.d.mts +2 -0
- package/dist/internal/environment.mjs +1 -0
- package/dist/internal/event-capabilities.d.mts +3 -0
- package/dist/internal/event-capabilities.mjs +1 -0
- package/dist/internal/hydration.mjs +1 -1
- package/dist/internal/kernel-registry.d.mts +1 -1
- package/dist/internal/kernel-registry.mjs +1 -1
- package/dist/internal/kernel.d.mts +5 -3
- package/dist/internal/kernel.mjs +1 -1
- package/dist/internal/otel/exporter-logs.mjs +1 -1
- package/dist/internal/otel/exporter-metrics.mjs +1 -1
- package/dist/internal/otel/exporter.mjs +1 -1
- package/dist/internal/otel/http-span-route.mjs +1 -1
- package/dist/internal/otel/index.d.mts +3 -3
- package/dist/internal/otel/index.mjs +1 -1
- package/dist/internal/otel/initial-navigation.d.mts +1 -0
- package/dist/internal/otel/initial-navigation.mjs +1 -1
- package/dist/internal/otel/instrumentations.d.mts +1 -1
- package/dist/internal/otel/instrumentations.mjs +1 -1
- package/dist/internal/otel/navigation.mjs +1 -1
- package/dist/internal/otel/normalize-path.mjs +1 -1
- package/dist/internal/otel/page-scope-context-manager.mjs +1 -1
- package/dist/internal/otel/propagation.mjs +1 -1
- package/dist/internal/otel/provider.d.mts +1 -1
- package/dist/internal/otel/provider.mjs +1 -1
- package/dist/internal/otel/url-attrs.mjs +1 -1
- package/dist/internal/otel/web-vitals.mjs +1 -1
- package/dist/internal/{page-lifecycle.d.mts → page-lifecycle/page-lifecycle.d.mts} +1 -1
- package/dist/internal/page-lifecycle/page-lifecycle.mjs +1 -0
- package/dist/internal/plugins/plugin-runtime.d.mts +2 -0
- package/dist/internal/plugins/plugin-runtime.mjs +1 -0
- package/dist/internal/react-context.d.mts +1 -1
- package/dist/internal/react-context.mjs +1 -1
- package/dist/internal/server-digest.mjs +1 -1
- package/dist/internal/third-party-hosts.mjs +1 -1
- package/dist/internal/version.mjs +1 -1
- package/dist/internal/wrapper-singleton.d.mts +1 -1
- package/dist/internal/wrapper-singleton.mjs +1 -1
- package/dist/kernel-BD57JxiH.mjs +1 -0
- package/dist/kernel-registry-6f-3VCIy.mjs +1 -0
- package/dist/loader-BGwWwN2n.mjs +1 -0
- package/dist/log-D6Ht--tv.mjs +1 -0
- package/dist/navigation-DwkvuhFR.mjs +1 -0
- package/dist/normalize-path-BChqP8pA.mjs +1 -0
- package/dist/page-events-config-CiJvdAaJ.d.mts +12 -0
- package/dist/{internal/page-lifecycle.mjs → page-lifecycle-BhSFqjlK.mjs} +1 -1
- package/dist/page-scope-context-manager-DhArvVJ_.mjs +1 -0
- package/dist/plugin-runtime-CnFVGbJw.mjs +1 -0
- package/dist/plugins/device.d.mts +1 -1
- package/dist/plugins/device.mjs +1 -1
- package/dist/plugins/errors.d.mts +1 -1
- package/dist/plugins/errors.mjs +1 -1
- package/dist/plugins/lib/loader.d.mts +1 -1
- package/dist/plugins/lib/loader.mjs +1 -1
- package/dist/plugins/lib/types.d.mts +1 -1
- package/dist/plugins/logs.d.mts +1 -1
- package/dist/plugins/logs.mjs +1 -1
- package/dist/plugins/page-events-config.d.mts +2 -0
- package/dist/plugins/page-events-config.mjs +1 -0
- package/dist/plugins/page-events.d.mts +1 -1
- package/dist/plugins/rage-clicks.d.mts +1 -1
- package/dist/plugins/rage-clicks.mjs +1 -1
- package/dist/plugins/replay/buffer.d.mts +1 -1
- package/dist/plugins/replay/buffer.mjs +1 -1
- package/dist/plugins/replay/chunking.d.mts +2 -38
- package/dist/plugins/replay/chunking.mjs +1 -2
- package/dist/plugins/replay/compressor-host.d.mts +2 -8
- package/dist/plugins/replay/compressor-host.mjs +1 -1
- package/dist/plugins/replay/config.d.mts +1 -1
- package/dist/plugins/replay/config.mjs +1 -1
- package/dist/plugins/replay/delivery.d.mts +4 -4
- package/dist/plugins/replay/delivery.mjs +1 -1
- package/dist/plugins/replay/index.d.mts +1 -1
- package/dist/plugins/replay/index.mjs +1 -1
- package/dist/plugins/replay/recorder.d.mts +1 -1
- package/dist/plugins/replay/recorder.mjs +1 -1
- package/dist/plugins/replay/redact-urls.d.mts +6 -0
- package/dist/plugins/replay/redact-urls.mjs +1 -0
- package/dist/plugins/replay/sequence.mjs +1 -1
- package/dist/plugins/replay/upload.d.mts +1 -1
- package/dist/plugins/replay/upload.mjs +1 -1
- package/dist/privacy-CPKosXDP.d.mts +31 -0
- package/dist/privacy-CRuL0X8r.mjs +1 -0
- package/dist/propagation-DVcqCu_E.mjs +1 -0
- package/dist/{provider-DWgb6tn9.d.mts → provider-C68KiG80.d.mts} +55 -39
- package/dist/provider-NuAexTzU.mjs +1 -0
- package/dist/{provider-2LrbA-ld.d.mts → provider-VZtcX6ZS.d.mts} +4 -1
- package/dist/provider.d.mts +4 -3
- package/dist/provider.mjs +1 -1
- package/dist/react-context-c1uTUJfB.mjs +1 -0
- package/dist/react-error-handler.d.mts +1 -1
- package/dist/react-error-handler.mjs +1 -1
- package/dist/recorder-CM6Ae_0S.mjs +1 -0
- package/dist/redact-urls-CwFod9d4.mjs +1 -0
- package/dist/sequence-B4dYChb0.mjs +1 -0
- package/dist/server-digest-CzGdvjW1.mjs +1 -0
- package/dist/session-C30CtCVv.mjs +1 -0
- package/dist/session-retry-DJHvfDaO.mjs +1 -0
- package/dist/stringify-DvuHsAT4.mjs +1 -0
- package/dist/third-party-hosts-BoJNL3xG.mjs +1 -0
- package/dist/tracking/api.d.mts +1 -1
- package/dist/tracking/api.mjs +1 -1
- package/dist/tracking/device.mjs +1 -1
- package/dist/tracking/geo.mjs +1 -2
- package/dist/tracking/registration.fixture.d.mts +119 -109
- package/dist/tracking/registration.fixture.mjs +148 -26
- package/dist/tracking/session-retry.mjs +1 -1
- package/dist/tracking/session.mjs +1 -1
- package/dist/upload-BPaD3YcA.mjs +1 -0
- package/dist/url-attrs-BdcyE2n6.mjs +1 -0
- package/dist/util/bot.d.mts +1 -0
- package/dist/util/bot.mjs +1 -1
- package/dist/util/global.mjs +1 -1
- package/dist/util/log.mjs +1 -1
- package/dist/util/stringify.mjs +1 -1
- package/dist/{version-CsfyuVoF.mjs → version-BuN6IItu.mjs} +1 -1
- package/dist/web-vitals-CxXDUgpl.mjs +1 -0
- package/package.json +6 -6
- package/dist/index-DvFfO2V9.d.mts +0 -4
- package/dist/internal/activity.mjs +0 -1
- package/dist/internal/plugin-runtime.d.mts +0 -2
- package/dist/internal/plugin-runtime.mjs +0 -1
package/README.md
CHANGED
|
@@ -57,6 +57,8 @@ function App() {
|
|
|
57
57
|
}
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
`InterfereProvider` captures render errors by default and rethrows them so your host error boundary keeps control of the fallback. Set `captureRenderErrors={false}` to disable this capture. The deprecated `errorBoundary` prop remains supported; `captureRenderErrors` takes precedence when both are set.
|
|
61
|
+
|
|
60
62
|
## Features
|
|
61
63
|
|
|
62
64
|
- **Error tracking** — automatic capture of uncaught errors and unhandled rejections
|
|
@@ -91,6 +93,107 @@ With the SDK's default browser propagator, instrumented fetch and XHR requests c
|
|
|
91
93
|
|
|
92
94
|
Explicitly denying analytics consent stops session baggage propagation while retaining trace propagation. `tracing: false` disables SDK instrumentation. Existing application-owned propagators are not replaced.
|
|
93
95
|
|
|
96
|
+
## Privacy
|
|
97
|
+
|
|
98
|
+
Pass `privacy` to your framework's browser `init()` to mark elements whose content the SDK never records. The same selectors apply to session replay and to click, submit and rage-click records, from the first capture:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const options: KernelOptions = {
|
|
102
|
+
privacy: {
|
|
103
|
+
blockSelector: "[data-sensitive]",
|
|
104
|
+
maskTextSelector: "[data-mask-text]",
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
The `interfere-block` and `interfere-mask` classes always apply. A selector matches the target element or any ancestor. The selectors apply even when replay is disabled.
|
|
110
|
+
|
|
111
|
+
`replay.blockSelector` and `replay.maskTextSelector` on the provider apply to replay only.
|
|
112
|
+
|
|
113
|
+
### Interaction records
|
|
114
|
+
|
|
115
|
+
Click, submit and rage-click records keep what the person did and which control they used, but never what a private element shows or holds. A click on a private account-number field records that the "Account number" field was clicked, not the number. Field values are never recorded.
|
|
116
|
+
|
|
117
|
+
| Target | Recorded |
|
|
118
|
+
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
119
|
+
| Blocked (`interfere-block`, `blockSelector`) | Event type, timing, tag name and field label. `ui.target.privacy` is `blocked`. |
|
|
120
|
+
| Masked (`interfere-mask`, `maskTextSelector`) | Event type, timing, tag name, `role` and field label. `ui.target.privacy` is `masked`. |
|
|
121
|
+
| Public | Tag, `id`, `name`, `role`, `aria-label`, field label and up to 120 characters of text. Text inside blocked or masked descendants is skipped. |
|
|
122
|
+
|
|
123
|
+
The field label (`ui.target.label`) comes from developer-authored sources only:
|
|
124
|
+
|
|
125
|
+
1. A `data-interfere-label` attribute on the target or an ancestor, such as `<div data-sensitive data-interfere-label="Security code">`. Use this when the visible label sits inside the private region.
|
|
126
|
+
2. Otherwise, the text of the field's `<label>` elements and `aria-labelledby` targets, when those labels are not themselves blocked or masked.
|
|
127
|
+
|
|
128
|
+
A private element's own `aria-label`, `placeholder`, `title`, text and value are never recorded, because applications often put the current value there. Form fields (`input`, `select`, `textarea`) never contribute text, even when public.
|
|
129
|
+
|
|
130
|
+
For blocked and masked targets the SDK also replaces OpenTelemetry's id-based `target_xpath` with a positional path. Target URLs (`href`) are never recorded. An invalid selector blocks every interaction target and logs a warning.
|
|
131
|
+
|
|
132
|
+
To keep navigation, document-load and resource timing without click and submit spans, pass `pageEvents: { interactions: false }`. `pageEvents: false` still turns off all page events, and `rageClick: false` turns off rage clicks. Denying analytics consent stops page events and rage clicks.
|
|
133
|
+
|
|
134
|
+
## URL redaction
|
|
135
|
+
|
|
136
|
+
The SDK redacts URLs before they leave the browser. Parameter names stay, redacted values become `REDACTED`, and credentials in a URL (`https://user:pass@host`) always become `REDACTED:REDACTED`. Configure query and fragment redaction with `privacy.urls`:
|
|
137
|
+
|
|
138
|
+
| `privacy.urls` | Query values redacted | Fragment |
|
|
139
|
+
| --------------------- | --------------------------------------------- | -------- |
|
|
140
|
+
| Omitted (default) | Built-in sensitive names only | Kept |
|
|
141
|
+
| `{ deny: ["email"] }` | Built-in sensitive names and the listed names | Kept |
|
|
142
|
+
| `{ allow: ["page"] }` | Every name except the listed names | Kept |
|
|
143
|
+
| `true` | Every name | Removed |
|
|
144
|
+
| `false` | None | Kept |
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
const options: KernelOptions = {
|
|
148
|
+
privacy: { urls: { allow: ["page", "sort"], fragment: true } },
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
`fragment: true` removes fragments, including hash-router paths. The built-in sensitive names follow the OpenTelemetry URL conventions and common credential names: `AWSAccessKeyId`, `sig`, `code` and `key`, plus any name that contains `token`, `secret`, `password`, `passwd`, `auth`, `credential`, `session`, `signature`, `api_key` or `apikey`. Names match case-insensitively after URL decoding. A name in `deny` is always redacted; a name in `allow` keeps its value, even when it is a built-in sensitive name.
|
|
153
|
+
|
|
154
|
+
A parameter without `=` (such as `?eyJhbGci…`) is redacted whole when its name is redacted, because a bare value can be a token. The SDK splits each value at the first `?` and `#` without parsing it, so relative paths and malformed values follow the same rule. A query inside a hash route belongs to the fragment and is kept with it. Requests, routing and trace propagation still use the original URL. Path segments are not redacted, so a token in a path such as `/share/abc123` is still recorded.
|
|
155
|
+
|
|
156
|
+
| Record | Covered |
|
|
157
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
|
|
158
|
+
| `url.full`, `url.path`, `url.original`, `http.url`, `http.target`, `http.referrer` and `referer` header attributes on SDK spans and span events, and span names such as `GET /a?id=1` | Yes |
|
|
159
|
+
| `url.query` and `url.fragment` attributes | Values redacted; fragment removed with `fragment: true` |
|
|
160
|
+
| Navigation logs, including the initial page load | Yes |
|
|
161
|
+
| Absolute URLs in exception messages, the cause chain and the span status, including SDK messages for failed requests, resource loads and CSP violations | Yes |
|
|
162
|
+
| Session replay page URLs and `href`, `src`, `srcset`, `action`, `formaction`, `poster`, `cite` and `data` attributes | Yes |
|
|
163
|
+
| Spans on your own OpenTelemetry provider, URLs in stack frames, relative paths in exception messages, inlined CSS in replay and console logs | No |
|
|
164
|
+
|
|
165
|
+
Replay plays images and links back from their recorded URLs, so a redacted signed URL (for example `?X-Amz-Signature=REDACTED`) no longer loads in the player.
|
|
166
|
+
|
|
167
|
+
The SDK redacts each span while it ends, so `onEnd` in `tracing.spanProcessors` and the Interfere exporter receive redacted values. `onStart` still sees the URL the instrumentation set at span creation. The browser provider is private to the SDK, so other OpenTelemetry exporters on the page are unaffected.
|
|
168
|
+
|
|
169
|
+
## Browser span processors
|
|
170
|
+
|
|
171
|
+
Framework browser `init()` options accept `tracing.spanProcessors`, an array of standard OpenTelemetry `SpanProcessor` instances. For example, these options remove an application attribute before export:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import type { KernelOptions } from "@interfere/react/internal/kernel";
|
|
175
|
+
import type { SpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
176
|
+
|
|
177
|
+
const dropTenant: SpanProcessor = {
|
|
178
|
+
onStart() {},
|
|
179
|
+
onEnd(span) {
|
|
180
|
+
delete span.attributes["app.tenant_name"];
|
|
181
|
+
},
|
|
182
|
+
async forceFlush() {},
|
|
183
|
+
async shutdown() {},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const options: KernelOptions = {
|
|
187
|
+
tracing: { spanProcessors: [dropTenant] },
|
|
188
|
+
};
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Pass `options` to your framework's browser `init()`. Processors are additive. Built-in session and device enrichment runs first, followed by your processors in array order, internal wrapper processors, and the Interfere batch exporter. Default instrumentation and export remain enabled.
|
|
192
|
+
|
|
193
|
+
Finish attribute mutations synchronously in `onEnd`, before it returns. OpenTelemetry does not await asynchronous work in `onStart` or `onEnd`. Ended spans cannot be changed through `setAttribute`; edit `span.attributes` as above. Use `privacy.urls` for query values and fragments.
|
|
194
|
+
|
|
195
|
+
The SDK calls each processor's `forceFlush` during flush and `shutdown` during disposal. Use a fresh processor instance for each SDK initialization and do not share it with another provider. `tracing: false` skips tracing setup, including custom processors.
|
|
196
|
+
|
|
94
197
|
## Documentation
|
|
95
198
|
|
|
96
199
|
Visit [interfere.com/docs](https://interfere.com/docs) for the full documentation.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as publicText,n as fieldLabel,r as privacyLevel}from"./privacy-CRuL0X8r.mjs";const ACTIONABLE_TAGS=new Set([`a`,`button`,`input`,`select`,`textarea`,`summary`,`label`]),ACTIONABLE_ROLES=new Set([`button`,`link`,`menuitem`,`tab`,`checkbox`,`radio`,`switch`]);function isActionable(el){if(ACTIONABLE_TAGS.has(el.tagName.toLowerCase()))return!0;let role=el.getAttribute(`role`);return role&&ACTIONABLE_ROLES.has(role)?!0:(el instanceof HTMLElement||el instanceof SVGElement)&&Object.hasOwn(el.dataset,`trackClick`)}function closestActionable(target){if(!(target instanceof Element))return null;let el=target;for(;el;){if(isActionable(el))return el;el=el.parentElement}return null}function describeActionable(el,policy){let desc={tag:el.tagName.toLowerCase()},label=fieldLabel(el,policy);label&&(desc.label=label);let level=privacyLevel(el,policy);if(level===`blocked`)return desc.privacy=level,desc;let role=el.getAttribute(`role`);if(role&&(desc.role=role),level===`masked`)return desc.privacy=level,desc;el.id&&(desc.id=el.id);let name=el.getAttribute(`name`);name&&(desc.name=name);let ariaLabel=el.getAttribute(`aria-label`);ariaLabel&&(desc.ariaLabel=ariaLabel);let text=publicText(el,policy);return text&&(desc.text=text),desc}export{describeActionable as n,isActionable as r,closestActionable as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{n as onPageShown}from"./page-lifecycle-BhSFqjlK.mjs";const log=createLogger(`activity`),IDLE_AFTER_MS=3e5,EXPIRE_AFTER_MS=9e5,MAX_AGE_MS=864e5,CHECK_INTERVAL_MS=3e4,KEEPALIVE_THROTTLE_MS=1e3,ACTIVITY_EVENTS=[`pointerdown`,`keydown`,`scroll`,`touchstart`,`mousemove`];function monotonicNow(){return typeof performance>`u`?Date.now():performance.now()}function subscribe(set,handler){return set.add(handler),(()=>{set.delete(handler)})}function fire(handlers,arg){for(let handler of handlers)try{handler(arg)}catch(error){log.warn(`activity handler threw: %s`,error instanceof Error?error.constructor.name:`UnknownError`)}}var ActivityMonitor=class{session=null;paused=!1;lastActivityMs=0;keepaliveUntilMs=0;checkTimer=null;unsubscribeShown=null;pauseHandlers=new Set;resumeHandlers=new Set;onPause(handler){return subscribe(this.pauseHandlers,handler)}onResume(handler){return subscribe(this.resumeHandlers,handler)}start(session){if(this.checkTimer===null&&typeof globalThis.addEventListener==`function`){this.session=session,this.paused=!1,this.lastActivityMs=monotonicNow(),this.keepaliveUntilMs=0;for(let type of ACTIVITY_EVENTS)globalThis.addEventListener(type,this.onInput,{capture:!0,passive:!0});this.unsubscribeShown=onPageShown(this.onInput),this.checkTimer=setInterval(this.poll,CHECK_INTERVAL_MS)}}stop(){if(this.checkTimer!==null){clearInterval(this.checkTimer),this.checkTimer=null;for(let type of ACTIVITY_EVENTS)globalThis.removeEventListener(type,this.onInput,!0);this.unsubscribeShown?.(),this.unsubscribeShown=null,this.session=null,this.paused=!1,this.lastActivityMs=0,this.keepaliveUntilMs=0}}idleMs(){return monotonicNow()-this.lastActivityMs}isOverMaxAge(){let startedAt=this.session?.startedAt()??0;return startedAt>0&&Date.now()-startedAt>=864e5}poll=()=>{this.paused||(this.isOverMaxAge()||this.idleMs()>=3e5)&&(this.paused=!0,log.debug(`session paused`),fire(this.pauseHandlers,void 0))};onInput=()=>{let now=monotonicNow();if(this.isOverMaxAge()||now-this.lastActivityMs>=9e5){this.resume(now,`rotated`);return}if(this.paused){this.resume(now,`idle`);return}now<this.keepaliveUntilMs||(this.touch(now),this.session?.markActivity())};resume(now,reason){reason===`rotated`&&(log.debug(`resume after expiry → new session`),this.session?.reset()),this.paused=!1,this.touch(now),this.session?.markActivity(),fire(this.resumeHandlers,reason)}touch(now){this.lastActivityMs=now,this.keepaliveUntilMs=now+KEEPALIVE_THROTTLE_MS}};export{KEEPALIVE_THROTTLE_MS as a,IDLE_AFTER_MS as i,CHECK_INTERVAL_MS as n,MAX_AGE_MS as o,EXPIRE_AFTER_MS as r,ActivityMonitor as t};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as SessionResumeReason } from "./activity-
|
|
1
|
+
import { c as SessionResumeReason } from "./activity-Duhfgvxt.mjs";
|
|
2
2
|
import { t as DeviceManager } from "./device-vFtWy12y.mjs";
|
|
3
3
|
import { t as GeoDetector } from "./geo-PDfIZY4L.mjs";
|
|
4
4
|
import { InterfereClient } from "@interfere/javascript";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as ActivityMonitor}from"./activity-D18VXGTn.mjs";import{t as DeviceManager}from"./device-DRK7hhLi.mjs";import{t as GeoDetector}from"./geo-D2wa9bGs.mjs";import{t as SessionManager}from"./session-C30CtCVv.mjs";import{t as SessionRetry}from"./session-retry-DJHvfDaO.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{InterfereClient,InterfereError}from"@interfere/javascript";const log=createLogger(`tracking`);function syncKey(sessionId,deviceId,fpHash){return`${sessionId}|${deviceId??``}|${fpHash??``}`}var SessionTracker=class{client;device;geo;mgr=null;activity=new ActivityMonitor;currentIdentity=null;identifiedSessionId=null;lastSyncedKey=null;inflightSyncKey=null;syncAttemptMs=0;generation=0;syncRetry=new SessionRetry;syncRetryKey=null;identityStarted=!1;constructor(opts){this.client=new InterfereClient({...opts.target,maxRetries:0,timeoutInSeconds:10,fetch:Object.assign(async(input,init)=>(opts.fetcher??globalThis.fetch)(input,{...init,credentials:`omit`,keepalive:!0}),opts.fetcher??globalThis.fetch)}),this.device=opts.device??new DeviceManager,this.geo=opts.geo??new GeoDetector}start(){this.mgr=new SessionManager(id=>{this.onRotate(id)}),this.activity.start({markActivity:()=>{this.markActivity()},reset:()=>{this.rotateSession()},startedAt:()=>this.getSessionStartedAt()})}startDeviceIdentity(){this.identityStarted||(this.invalidateSync(),this.identityStarted=!0,this.device.init(),this.geo.detect(),this.backfillIdentity())}discardDeviceIdentity(){this.invalidateSync(),this.identityStarted=!1,this.device.clear(),this.geo.clear()}async backfillIdentity(){let gen=this.generation;if(await Promise.resolve(),gen!==this.generation||!this.identityStarted)return;let initialSessionId=this.mgr?.getSessionId()??null,initialFpHash=this.device.getFpHash();initialSessionId&&await this.syncSession(initialSessionId,this.device.getDeviceId(),initialFpHash);let fpHash=await this.device.whenFingerprintReady(),sessionId=this.mgr?.getSessionId()??null;gen===this.generation&&this.identityStarted&&sessionId&&fpHash!==initialFpHash&&this.syncSession(sessionId,this.device.getDeviceId(),fpHash)}onSessionPause(handler){return this.activity.onPause(handler)}onSessionResume(handler){return this.activity.onResume(handler)}sessionId(){let id=this.mgr?.getSessionId()??null;return id&&this.ensureSynced(id),id}windowId(){return this.mgr?.getWindowId()??null}markActivity(){this.mgr?.markActivity()}getSessionStartedAt(){return this.mgr?.getSessionStartedAt()??0}getDeviceId(){return this.device.getDeviceId()}getFpHash(){return this.device.getFpHash()}getIdentity(){return this.currentIdentity}async identify(params){if(!this.mgr)return;let sessionId=this.mgr.getSessionId();if(this.identifiedSessionId===sessionId){log.debug(`skipped, already identified for session %s`,sessionId);return}this.currentIdentity=params,this.identifiedSessionId=sessionId;let gen=this.generation,[fpHash,country]=await Promise.all([this.device.whenFingerprintReady(),this.geo.detect()]),deviceId=this.device.getDeviceId();if(gen!==this.generation){this.identifiedSessionId=null;return}log.info(`POST session %s → identify`,sessionId),this.postIdentify(sessionId,omitUndefined({deviceId,fpHash,sessionId,...params,country:country||void 0}))}async postIdentify(sessionId,body){try{await this.client.sessions.identifySession(body)}catch{this.identifiedSessionId=null,log.warn(`identify failed for session %s`,sessionId)}}clearIdentity(){this.currentIdentity=null,this.identifiedSessionId=null}reset(){this.invalidateSync(),this.clearIdentity(),this.identityStarted&&this.device.reset(),this.mgr?.reset()}rotateSession(){this.mgr?.reset()}dispose(){this.activity.stop(),this.invalidateSync(),this.clearIdentity(),this.mgr=null}invalidateSync(){this.generation+=1,this.syncRetry.reset(),this.syncRetryKey=null,this.lastSyncedKey=null,this.inflightSyncKey=null,this.syncAttemptMs=0}currentSyncKey(){let sessionId=this.mgr?.sessionId;return sessionId?syncKey(sessionId,this.device.getDeviceId(),this.device.getFpHash()):null}ensureSynced(sessionId){let deviceId=this.device.getDeviceId(),fpHash=this.device.getFpHash(),key=syncKey(sessionId,deviceId,fpHash);this.lastSyncedKey!==key&&this.inflightSyncKey!==key&&(Date.now()-this.syncAttemptMs<5e3||this.syncSession(sessionId,deviceId,fpHash))}async syncSession(sessionId,deviceId,fpHash){let key=syncKey(sessionId,deviceId,fpHash);if(this.lastSyncedKey===key||this.inflightSyncKey===key)return;this.syncRetryKey!==key&&(this.syncRetry.reset(),this.syncRetryKey=key),this.syncRetry.cancel();let{generation}=this;this.inflightSyncKey=key,this.syncAttemptMs=Date.now();try{await this.client.sessions.createSession({sessionId,deviceId,fpHash}),generation===this.generation&&key===this.currentSyncKey()&&(this.lastSyncedKey=key,this.syncRetry.reset())}catch(error){log.warn(`session sync failed`),error instanceof InterfereError&&generation===this.generation&&key===this.currentSyncKey()&&this.syncRetry.schedule(error,()=>{let current=this.mgr?.sessionId;generation===this.generation&¤t&&this.ensureSynced(current)})}finally{generation===this.generation&&this.inflightSyncKey===key&&(this.inflightSyncKey=null)}}async onRotate(sessionId){this.syncAttemptMs=Date.now();let gen=this.generation;try{await Promise.resolve();let fpHash=this.device.getFpHash(),deviceId=this.device.getDeviceId();if(gen!==this.generation)return;log.debug(`POST session %s (device=%s fp=%s)`,sessionId,deviceId??`pending`,fpHash??`none`),this.syncSession(sessionId,deviceId,fpHash)}catch{}}};export{SessionTracker as t};
|
package/dist/api.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{activeKernel}from"./
|
|
1
|
+
import{t as activeKernel}from"./kernel-registry-6f-3VCIy.mjs";import{MECHANISM_TYPE,toError,toException}from"@interfere/types/sdk/errors";import{SpanStatusCode,trace}from"@opentelemetry/api";const TRACER_NAME=`@interfere/react`;function tracer(){return activeKernel()?.getTracer(TRACER_NAME)??trace.getTracer(TRACER_NAME)}function isPromise(value){return value!==null&&(typeof value==`object`||typeof value==`function`)&&`then`in value&&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),error=>{let e=toError(error);throw s.recordException(e),s.setStatus({code:SpanStatusCode.ERROR,message:e.message}),s.end(),error}):(s.end(),result)}catch(error){let e=toError(error);throw s.recordException(e),s.setStatus({code:SpanStatusCode.ERROR,message:e.message}),s.end(),error}})}function capture(error){activeKernel()?.recordException(toException(error),{mechanism:{handled:!0,type:MECHANISM_TYPE.manual.capture}})}export{capture,span};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isBot}from"@ua-parser-js/pro-enterprise/bot-detection";const AUTOMATION_UA_RE=/headless|electron|puppeteer|playwright/iu;function isBotUserAgent(){return typeof navigator>`u`?!1:classifyBrowserAutomation(navigator)}function classifyBrowserAutomation(browser){return browser.webdriver||AUTOMATION_UA_RE.test(browser.userAgent)?!0:isBot(browser.userAgent)}export{isBotUserAgent as n,classifyBrowserAutomation as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as utf8ByteLength,t as classifyReplayEvent}from"./chunking-qZffPbyY.mjs";function createReplayBuffer(opts){let entries=[],totalBytes=0;return{drain(){let drained=entries;return entries=[],totalBytes=0,drained},push(event){let json=JSON.stringify(event),bytes=utf8ByteLength(json),{isActivity,isFullSnapshot}=classifyReplayEvent(event);entries.push({json,ts:Date.now(),bytes,isActivity,isFullSnapshot}),totalBytes+=bytes,totalBytes>=opts.softLimitBytes&&opts.onSoftLimit()}}}export{createReplayBuffer as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as isHydrationError}from"./hydration-BIp2cKhz.mjs";import{parseReactComponentStack}from"@interfere/types/sdk/errors";import{omitUndefined}from"@interfere/helpers/omit-undefined";function captureReactError(kernel,error,componentStack,mechanism){if(!kernel)return;let hydration=isHydrationError(error);kernel.recordException(error,omitUndefined({mechanism:hydration?{...mechanism,synthetic:!1}:mechanism,subtype:hydration?`hydration`:void 0,appendFrames:componentStack?parseReactComponentStack(componentStack):void 0,errorDigest:error.digest||void 0}))}export{captureReactError as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as captureReactError}from"./capture-BV2RlsYg.mjs";import{t as InterfereContext}from"./react-context-c1uTUJfB.mjs";import{t as hasServerDigest}from"./server-digest-CzGdvjW1.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 hasServerDigest(this.state.error)||captureReactError(this.context?.kernel??null,this.state.error,null,{handled:!1,type:MECHANISM_TYPE.react.captureBoundary}),this.state.error;return this.props.children}};export{CaptureBoundary as t};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/plugins/replay/chunking.d.ts
|
|
2
|
+
interface BufferedReplayEvent {
|
|
3
|
+
bytes: number;
|
|
4
|
+
isActivity: boolean;
|
|
5
|
+
isFullSnapshot: boolean;
|
|
6
|
+
json: string;
|
|
7
|
+
ts: number;
|
|
8
|
+
}
|
|
9
|
+
interface ReplayChunkPayload {
|
|
10
|
+
activityCount: number;
|
|
11
|
+
bodyJson: string;
|
|
12
|
+
eventCount: number;
|
|
13
|
+
firstTs: number | null;
|
|
14
|
+
hasFullSnapshot: boolean;
|
|
15
|
+
lastTs: number | null;
|
|
16
|
+
}
|
|
17
|
+
interface SplitReplayEventsResult {
|
|
18
|
+
chunks: BufferedReplayEvent[][];
|
|
19
|
+
droppedEventBytes: number[];
|
|
20
|
+
}
|
|
21
|
+
declare function classifyReplayEvent(event: unknown): {
|
|
22
|
+
isActivity: boolean;
|
|
23
|
+
isFullSnapshot: boolean;
|
|
24
|
+
};
|
|
25
|
+
declare function toReplayChunkPayload(group: BufferedReplayEvent[]): {
|
|
26
|
+
activityCount: number;
|
|
27
|
+
bodyJson: string;
|
|
28
|
+
eventCount: number;
|
|
29
|
+
firstTs: number | null;
|
|
30
|
+
hasFullSnapshot: boolean;
|
|
31
|
+
lastTs: number | null;
|
|
32
|
+
};
|
|
33
|
+
declare function splitReplayEvents(buffered: BufferedReplayEvent[]): {
|
|
34
|
+
chunks: BufferedReplayEvent[][];
|
|
35
|
+
droppedEventBytes: number[];
|
|
36
|
+
};
|
|
37
|
+
declare function utf8ByteLength(value: string): number;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { splitReplayEvents as a, classifyReplayEvent as i, ReplayChunkPayload as n, toReplayChunkPayload as o, SplitReplayEventsResult as r, utf8ByteLength as s, BufferedReplayEvent as t };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{EventType,IncrementalSource}from"@rrweb/types";const textEncoder=new TextEncoder,ACTIVITY_SOURCES=new Set([IncrementalSource.MouseMove,IncrementalSource.MouseInteraction,IncrementalSource.Scroll,IncrementalSource.Input,IncrementalSource.TouchMove,IncrementalSource.Drag,IncrementalSource.Selection]);function classifyReplayEvent(event){if(typeof event!=`object`||!event||!(`type`in event)||typeof event.type!=`number`)return{isActivity:!1,isFullSnapshot:!1};if(event.type===EventType.FullSnapshot)return{isActivity:!1,isFullSnapshot:!0};if(event.type===EventType.IncrementalSnapshot&&`data`in event&&event.data!==null&&typeof event.data==`object`&&`source`in event.data){let{source}=event.data;if(typeof source==`number`&&ACTIVITY_SOURCES.has(source))return{isActivity:!0,isFullSnapshot:!1}}return{isActivity:!1,isFullSnapshot:!1}}function countActivityEvents(group){let count=0;for(let entry of group)entry.isActivity&&(count+=1);return count}function toReplayChunkPayload(group){let parts=[],hasFullSnapshot=!1;for(let entry of group)parts.push(entry.json),entry.isFullSnapshot&&(hasFullSnapshot=!0);let firstTs=group[0]?.ts??null;return{activityCount:countActivityEvents(group),bodyJson:parts.length>0?`${parts.join(`
|
|
2
|
+
`)}\n`:``,eventCount:group.length,firstTs,hasFullSnapshot,lastTs:group.at(-1)?.ts??null}}function splitReplayEvents(buffered){let chunks=[],droppedEventBytes=[],current=[],currentBytes=0;for(let entry of buffered){let singleEventBodyBytes=entry.bytes+1;if(singleEventBodyBytes>8388608){droppedEventBytes.push(singleEventBodyBytes);continue}current.length>0&¤tBytes+singleEventBodyBytes>6291456&&(chunks.push(current),current=[],currentBytes=0),currentBytes+=singleEventBodyBytes,current.push(entry)}return current.length>0&&chunks.push(current),{chunks,droppedEventBytes}}function utf8ByteLength(value){return textEncoder.encode(value).length}export{utf8ByteLength as i,splitReplayEvents as n,toReplayChunkPayload as r,classifyReplayEvent as t};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/plugins/replay/compressor-host.d.ts
|
|
2
|
+
/** `gzip` is `null` when compression is unavailable — callers must POST the chunk uncompressed. */
|
|
3
|
+
interface Compressor {
|
|
4
|
+
readonly dispose: () => void;
|
|
5
|
+
readonly gzip: ((bytes: Uint8Array) => Promise<Uint8Array<ArrayBuffer>>) | null;
|
|
6
|
+
}
|
|
7
|
+
declare function createCompressor(): Compressor;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { createCompressor as n, Compressor as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";const log=createLogger(`replay/compressor`),FAIL_OPEN={dispose:()=>void 0,gzip:null},gzip=async bytes=>{let cs=new CompressionStream(`gzip`),compressed=new Response(cs.readable).arrayBuffer(),writer=cs.writable.getWriter();return await writer.write(new Uint8Array(bytes)),await writer.close(),new Uint8Array(await compressed)};function createCompressor(){return typeof CompressionStream>`u`?(log.warn(`CompressionStream unavailable; replay chunks will POST uncompressed`),FAIL_OPEN):{dispose:()=>void 0,gzip}}export{createCompressor as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{n as getStringGlobal,r as setGlobal,t as getGlobal}from"./global-DYq1Z4_H.mjs";import{API_URL}from"@interfere/constants/api";import{API_URL_GLOBAL,FORCE_ENABLE_GLOBAL,INGEST_URL_GLOBAL,PUBLIC_KEY_GLOBAL}from"@interfere/types/sdk/injected-globals";function resolvePublicKey(){let injected=getStringGlobal(PUBLIC_KEY_GLOBAL);if(injected)return injected;if(typeof process<`u`)return process.env.INTERFERE_PUBLIC_KEY??void 0}function isForceEnableActive(){return!!getGlobal(FORCE_ENABLE_GLOBAL)}function resolveApiHost(explicit){return explicit??getStringGlobal(API_URL_GLOBAL)}function resolveIngestHost(explicit){return explicit??getStringGlobal(INGEST_URL_GLOBAL)}function setIngestHost(host){setGlobal(INGEST_URL_GLOBAL,host)}function normalizeOrigin(host){try{return new URL(host).origin}catch{return API_URL}}function resolveTargets(apiHost,ingestHost){let publicKey=resolvePublicKey(),headers={};isForceEnableActive()&&(headers[`x-interfere-force-enable`]=`1`);let configHost=resolveApiHost(apiHost),configBaseUrl=configHost?normalizeOrigin(configHost):API_URL,resolvedIngestHost=resolveIngestHost(ingestHost),ingestBaseUrl=resolvedIngestHost?normalizeOrigin(resolvedIngestHost):configBaseUrl,options={headers,publicKeyHeader:publicKey?{apiKey:publicKey}:void 0,timeoutInSeconds:10,maxRetries:0};return{config:{...options,baseUrl:configBaseUrl},ingest:{...options,baseUrl:ingestBaseUrl}}}export{resolveTargets as n,setIngestHost as r,isForceEnableActive as t};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/internal/config.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Force enable is the explicit opt-in for telemetry outside production. It
|
|
4
|
+
* also overrides the bot gate, so a browser under test can start a kernel.
|
|
5
|
+
*/
|
|
6
|
+
declare function isForceEnableActive(): boolean;
|
|
7
|
+
declare function setIngestHost(host: string): void;
|
|
8
|
+
declare function resolveTargets(apiHost?: string, ingestHost?: string): {
|
|
9
|
+
config: {
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
publicKeyHeader: {
|
|
12
|
+
apiKey: string;
|
|
13
|
+
} | undefined;
|
|
14
|
+
timeoutInSeconds: number;
|
|
15
|
+
maxRetries: number;
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
};
|
|
18
|
+
ingest: {
|
|
19
|
+
headers: Record<string, string>;
|
|
20
|
+
publicKeyHeader: {
|
|
21
|
+
apiKey: string;
|
|
22
|
+
} | undefined;
|
|
23
|
+
timeoutInSeconds: number;
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
baseUrl: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { resolveTargets as n, setIngestHost as r, isForceEnableActive as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{omitUndefined}from"@interfere/helpers/omit-undefined";const INTERFERE_MASK_TEXT_CLASS=`interfere-mask`,INTERFERE_BLOCK_CLASS=`interfere-block`,INTERFERE_IGNORE_CLASS=`interfere-ignore`;function joinSelectors(...selectors){return selectors.filter(Boolean).join(`, `)||void 0}function toRecordOptions(config,privacy){return omitUndefined({...config,blockClass:INTERFERE_BLOCK_CLASS,blockSelector:joinSelectors(privacy?.blockSelector,config.blockSelector),ignoreClass:INTERFERE_IGNORE_CLASS,maskTextClass:INTERFERE_MASK_TEXT_CLASS,maskTextSelector:joinSelectors(privacy?.maskSelector,config.maskTextSelector)})}export{toRecordOptions as i,INTERFERE_IGNORE_CLASS as n,INTERFERE_MASK_TEXT_CLASS as r,INTERFERE_BLOCK_CLASS as t};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { i as PrivacyPolicy } from "./privacy-CPKosXDP.mjs";
|
|
1
2
|
import { SetRequired } from "@interfere/helpers/set-required";
|
|
2
3
|
import { recordOptions } from "rrweb";
|
|
3
4
|
//#region src/plugins/replay/config.d.ts
|
|
@@ -7,6 +8,6 @@ declare const INTERFERE_IGNORE_CLASS = "interfere-ignore";
|
|
|
7
8
|
type ReplayConfig = Pick<recordOptions<unknown>, "blockClass" | "blockSelector" | "ignoreClass" | "ignoreSelector" | "maskAllInputs" | "maskInputFn" | "maskInputOptions" | "maskTextClass" | "maskTextFn" | "maskTextSelector" | "recordCanvas">;
|
|
8
9
|
type ReplayOption = boolean | ReplayConfig;
|
|
9
10
|
type ReplayRecordOptions = SetRequired<ReplayConfig, "maskTextClass" | "blockClass" | "ignoreClass">;
|
|
10
|
-
declare function toRecordOptions(config: ReplayConfig): ReplayRecordOptions;
|
|
11
|
+
declare function toRecordOptions(config: ReplayConfig, privacy?: PrivacyPolicy): ReplayRecordOptions;
|
|
11
12
|
//#endregion
|
|
12
13
|
export { ReplayOption as a, ReplayConfig as i, INTERFERE_IGNORE_CLASS as n, ReplayRecordOptions as o, INTERFERE_MASK_TEXT_CLASS as r, toRecordOptions as s, INTERFERE_BLOCK_CLASS as t };
|
|
@@ -0,0 +1 @@
|
|
|
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===!0||consent===!1?{analytics:consent,replay:consent}:{...DEFAULT_CONSENT,...consent}}function hasConsentChanged(current,next){for(let category of GATEABLE_CATEGORIES)if(current?.[category]!==next?.[category])return!0;return!1}export{resolveGrantedConsent as a,isConsentAllowed as i,getPluginConsentCategory as n,shouldCaptureEvent as o,hasConsentChanged as r,DEFAULT_CONSENT as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const CONSOLE_LEVELS=[`debug`,`log`,`info`,`warn`,`error`],handlers=new Set,originals=new Map;let installed=!1;function install(){if(installed)return;installed=!0;let target=globalThis.console;for(let level of CONSOLE_LEVELS){let orig=target[level];typeof orig==`function`&&(originals.set(level,orig),target[level]=(...args)=>{orig.apply(globalThis.console,args);for(let handler of handlers)handler(level,args)})}}function uninstall(){if(!installed)return;installed=!1;let target=globalThis.console;for(let level of CONSOLE_LEVELS){let orig=originals.get(level);orig&&(target[level]=orig,originals.delete(level))}}function onConsoleCall(handler){return install(),handlers.add(handler),(()=>{handlers.delete(handler),handlers.size===0&&uninstall()})}function resetConsolePatchForTests(){handlers.clear(),uninstall()}export{onConsoleCall as n,resetConsolePatchForTests as r,CONSOLE_LEVELS as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";import{t as uploadReplayChunk}from"./upload-BPaD3YcA.mjs";import{trace}from"@opentelemetry/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";const log=createLogger(`replay`),textEncoder=new TextEncoder;async function prepareBody(compressor,rawBytes){if(!compressor.gzip)return{body:rawBytes,encoding:null};try{return{body:await compressor.gzip(rawBytes),encoding:`gzip`}}catch(error){return log.warn(`gzip failed for chunk; sending uncompressed: %o`,error),{body:rawBytes,encoding:null}}}function encodeReplayMeta(chunk,payload){return btoa(JSON.stringify({activityCount:payload.activityCount,eventCount:payload.eventCount,firstTs:payload.firstTs,hasFullSnapshot:payload.hasFullSnapshot,lastTs:payload.lastTs,segmentId:chunk.segmentId,windowId:chunk.windowId}))}async function deliverChunk({ctx,chunk,target,compressor,payload,skipCompression}){let sessionId=ctx.getSessionId();if(!sessionId)return`ok`;let rawBytes=textEncoder.encode(payload.bodyJson),uncompressedBytes=rawBytes.byteLength,prepared=skipCompression?{body:rawBytes,encoding:null}:await prepareBody(compressor,rawBytes),headers={"x-replay-meta":encodeReplayMeta(chunk,payload)};prepared.encoding===`gzip`&&(headers[`content-encoding`]=`gzip`);let response;try{let upload=await uploadReplayChunk(target,sessionId,prepared.body,headers);if(!upload.ok)return await upload.body?.cancel(),upload.status>=400&&upload.status<500?`fatal`:`retryable`;response=await upload.json()}catch(error){return log.warn(`replay chunk upload failed: %o`,error),`retryable`}let objectKey=typeof response==`object`&&response&&`objectKey`in response&&typeof response.objectKey==`string`?response.objectKey:null,attributes=omitUndefined({"replay.chunk.size_bytes":uncompressedBytes,"replay.chunk.event_count":payload.eventCount,"replay.chunk.uri":objectKey||void 0,"replay.chunk.compressed_bytes":prepared.encoding===`gzip`?prepared.body.byteLength:void 0,"replay.chunk.first_event_ts":payload.firstTs??void 0,"replay.chunk.last_event_ts":payload.lastTs??void 0});return trace.getTracer(`@interfere/react/replay`).startSpan(`replay.chunk`,{attributes}).end(),`ok`}export{deliverChunk as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const devicePlugin={name:`device`,setup(ctx){return ctx.startDeviceInfoCapture()??void 0}};export{devicePlugin as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as createLogger}from"./log-D6Ht--tv.mjs";const log=createLogger(`device`),LS_KEY=`interfere:device_id`,COOKIE_NAME=`interfere_did`;async function whenIdle(){let{promise,resolve}=Promise.withResolvers();return typeof globalThis.requestIdleCallback==`function`?globalThis.requestIdleCallback(()=>{resolve(void 0)},{timeout:5e3}):setTimeout(()=>{resolve(void 0)},0),promise}const defaultFingerprintProvider=async()=>{await whenIdle();try{let result=await(await(await import(`@fingerprintjs/fingerprintjs`)).load()).get();return result.visitorId?result.visitorId:(log.error(`Fingerprinting returned an empty visitor id; visitor identity will be cookie-only`),null)}catch(error){return log.error(`fingerprint init failed; visitor identity will be cookie-only`,error),null}};function tryLocalStorage(){try{let s=globalThis.localStorage,key=`__interfere_device_probe__`;return s.setItem(key,`1`),s.removeItem(key),s}catch{return null}}function getCookie(name){if(typeof document>`u`)return null;let match=document.cookie.split(`; `).find(c=>c.startsWith(`${name}=`));return match?decodeURIComponent(match.split(`=`)[1]??``):null}function setCookie(name,value,maxAgeSeconds){typeof document>`u`||(document.cookie=`${name}=${encodeURIComponent(value)};path=/;max-age=${maxAgeSeconds};SameSite=Lax`)}function persistCookie(name,value){setCookie(name,value,3456e4)}function deleteCookie(name){setCookie(name,``,0)}function generateId(){return crypto.randomUUID()}var DeviceManager=class{deviceId=null;fpHash=null;fpPending=null;epoch=0;fingerprintProvider;constructor(fingerprintProvider){this.fingerprintProvider=fingerprintProvider??defaultFingerprintProvider}init(){if(this.deviceId)return;let ls=tryLocalStorage(),fromLs=ls?.getItem(LS_KEY)??null,fromCookie=getCookie(COOKIE_NAME);this.deviceId=fromLs??fromCookie??generateId(),!fromLs&&ls&&ls.setItem(LS_KEY,this.deviceId),fromCookie||persistCookie(COOKIE_NAME,this.deviceId),fromLs&&!fromCookie&&persistCookie(COOKIE_NAME,this.deviceId),fromCookie&&!fromLs&&ls&&ls.setItem(LS_KEY,this.deviceId),log.debug(`device %s (ls=%s cookie=%s)`,this.deviceId,!!fromLs,!!fromCookie),this.startFingerprint()}startFingerprint(){if(this.fpHash||this.fpPending)return;let{epoch}=this;this.fpPending=(async()=>{let hash=await this.fingerprintProvider();return epoch===this.epoch?(this.fpHash=hash,hash&&log.debug(`fpHash %s`,hash),hash):null})()}getDeviceId(){return this.deviceId}getFpHash(){return this.fpHash}async whenFingerprintReady(){return this.fpHash?this.fpHash:this.fpPending??Promise.resolve(null)}reset(){return this.deviceId=generateId(),tryLocalStorage()?.setItem(LS_KEY,this.deviceId),persistCookie(COOKIE_NAME,this.deviceId),log.debug(`device %s (reset)`,this.deviceId),this.deviceId}clear(){this.epoch+=1,this.deviceId=null,this.fpHash=null,this.fpPending=null,tryLocalStorage()?.removeItem(LS_KEY),deleteCookie(COOKIE_NAME),log.debug(`device identity cleared`)}};export{whenIdle as n,DeviceManager as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isFrozenUA}from"@ua-parser-js/pro-enterprise/helpers";const NOT_A_BRAND_REGEX=/not.a.brand/iu;function deviceMetadata(parsed,hints,userAgent){if(parsed==null)return null;let fullVersion=hints.fullVersionList?.find(b=>!NOT_A_BRAND_REGEX.test(b.brand))?.version,metadata={...parsed,browser:{...parsed.browser},cpu:{...parsed.cpu},frozenUa:isFrozenUA(userAgent),os:{...parsed.os}};return fullVersion&&(metadata.browser.fullVersion=fullVersion),hints.bitness&&(metadata.cpu.bitness=hints.bitness),hints.platformVersion&&(metadata.os.versionFull=hints.platformVersion),metadata}export{deviceMetadata as t};
|
|
@@ -9,9 +9,9 @@ var chars=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,int
|
|
|
9
9
|
`);i!==-1;i=str.indexOf(`
|
|
10
10
|
`,i+1))this.nextLine();this.generatedCodeColumn+=str.length-lastNewline-1}};const warned={insertLeft:!1,insertRight:!1,storeName:!1};function expandReplacement(replacement,matched,position,str,captures,namedCaptures){if(!replacement.includes(`$`))return replacement;let result=``,index=0;for(;index<replacement.length;){let dollar=replacement.indexOf(`$`,index);if(dollar===-1){result+=replacement.slice(index);break}result+=replacement.slice(index,dollar);let char=replacement[dollar+1],expansion=`$`,consumed=1;if(char===`$`)consumed=2;else if(char===`&`)expansion=matched,consumed=2;else if(char==="`")expansion=str.slice(0,position),consumed=2;else if(char===`'`)expansion=str.slice(position+matched.length),consumed=2;else if(char===`<`&&namedCaptures!==void 0){let close=replacement.indexOf(`>`,dollar+2);close!==-1&&(expansion=namedCaptures[replacement.slice(dollar+2,close)]??``,consumed=close+1-dollar)}else if(char>=`0`&&char<=`9`){let second=replacement[dollar+2],double=second>=`0`&&second<=`9`?Number(char+second):NaN,single=Number(char);double>=1&&double<=captures.length?(expansion=captures[double-1]??``,consumed=3):single>=1&&single<=captures.length&&(expansion=captures[single-1]??``,consumed=2)}result+=expansion,index=dollar+consumed}return result}var MagicString=class MagicString{constructor(string,options={}){let chunk=new Chunk(0,string.length,string);Object.defineProperties(this,{original:{writable:!0,value:string},outro:{writable:!0,value:``},intro:{writable:!0,value:``},firstChunk:{writable:!0,value:chunk},lastChunk:{writable:!0,value:chunk},lastSearchedChunk:{writable:!0,value:chunk},byStart:{writable:!0,value:new Map([[0,chunk]])},byEnd:{writable:!0,value:new Map([[string.length,chunk]])},filename:{writable:!0,value:options.filename},indentExclusionRanges:{writable:!0,value:options.indentExclusionRanges},sourcemapLocations:{writable:!0,value:new BitSet},storedNames:{writable:!0,value:{}},indentStr:{writable:!0,value:void 0},ignoreList:{writable:!0,value:options.ignoreList},offset:{writable:!0,value:options.offset||0},hasMovedChunks:{writable:!0,value:!1}})}addSourcemapLocation(char){this.sourcemapLocations.add(char)}append(content){if(typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);return this.outro+=content,this}appendLeft(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byEnd.get(index);return chunk?chunk.appendLeft(content):this.intro+=content,this}appendRight(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byStart.get(index);return chunk?chunk.appendRight(content):this.outro+=content,this}clone(){let cloned=new MagicString(this.original,{filename:this.filename,ignoreList:this.ignoreList,offset:this.offset}),originalChunk=this.firstChunk,clonedChunk=cloned.firstChunk=cloned.lastSearchedChunk=originalChunk.clone();for(;originalChunk;){cloned.byStart.set(clonedChunk.start,clonedChunk),cloned.byEnd.set(clonedChunk.end,clonedChunk);let nextOriginalChunk=originalChunk.next,nextClonedChunk=nextOriginalChunk&&nextOriginalChunk.clone();nextClonedChunk&&(clonedChunk.next=nextClonedChunk,nextClonedChunk.previous=clonedChunk,clonedChunk=nextClonedChunk),originalChunk=nextOriginalChunk}return cloned.lastChunk=clonedChunk,this.indentExclusionRanges&&(cloned.indentExclusionRanges=this.indentExclusionRanges.slice()),cloned.sourcemapLocations=new BitSet(this.sourcemapLocations),cloned.storedNames={...this.storedNames},cloned.intro=this.intro,cloned.outro=this.outro,cloned.hasMovedChunks=this.hasMovedChunks,cloned}generateDecodedMap(options){options||={};let mappings=new Mappings(options.hires),names=this._generateMappings(mappings);return{...this._mapProperties(options,names),mappings:mappings.raw,rangeMappings:mappings.rawRangeMappings}}generateMap(options){options||={};let encoder=new MappingsEncoder,mappings=new Mappings(options.hires,encoder),names=this._generateMappings(mappings);return new SourceMap({...this._mapProperties(options,names),mappings:encoder.finish(mappings.rawSegments),rangeMappings:mappings.rawRangeMappings})}_generateMappings(mappings){let names=Object.keys(this.storedNames),locate=getLocator(this.original);return this.intro&&mappings.advance(this.intro),this.firstChunk.eachNext(chunk=>{let loc=locate(chunk.start);chunk.intro.length&&mappings.advance(chunk.intro),chunk.edited?mappings.addEdit(0,chunk.content,loc,chunk.storeName?names.indexOf(chunk.original):-1):mappings.addUneditedChunk(0,chunk,this.original,loc,this.sourcemapLocations),chunk.outro.length&&mappings.advance(chunk.outro)}),this.outro&&mappings.advance(this.outro),names}_mapProperties(options,names){return{file:options.file?options.file.split(/[/\\]/).pop():void 0,sources:[options.source?getRelativePath(options.file||``,options.source):options.file||``],sourcesContent:options.includeContent?[this.original]:void 0,names,x_google_ignoreList:this.ignoreList?[0]:void 0}}_ensureindentStr(){this.indentStr===void 0&&(this.indentStr=guessIndent(this.original))}_getRawIndentString(){return this._ensureindentStr(),this.indentStr}getIndentString(){return this._ensureindentStr(),this.indentStr===null?` `:this.indentStr}indent(indentStr,options){let pattern=/^[^\r\n]/gm;if(isObject(indentStr)&&(options=indentStr,indentStr=void 0),indentStr===void 0&&(this._ensureindentStr(),indentStr=this.indentStr||` `),indentStr===``)return this;let resolvedIndentStr=indentStr;options||={};let isExcluded={};options.exclude&&(typeof options.exclude[0]==`number`?[options.exclude]:options.exclude).forEach(exclusion=>{for(let i=exclusion[0];i<exclusion[1];i+=1)isExcluded[i]=!0});let shouldIndentNextCharacter=options.indentStart!==!1,indentPiece=str=>{if(str===``)return str;let indented=str.replace(pattern,(match,offset)=>offset>0||shouldIndentNextCharacter?`${resolvedIndentStr}${match}`:match);return shouldIndentNextCharacter=str[str.length-1]===`
|
|
11
11
|
`,indented};this.intro=indentPiece(this.intro);let charIndex=0,chunk=this.firstChunk,indentAt=index=>{shouldIndentNextCharacter=!1,index===chunk.start?chunk.appendRight(resolvedIndentStr):(this._splitChunk(chunk,index),chunk=chunk.next,chunk.prependRight(resolvedIndentStr))};for(;chunk;){let end=chunk.end;if(isExcluded[chunk.start]||(chunk.intro=indentPiece(chunk.intro)),chunk.edited)isExcluded[charIndex]||(chunk.content=indentPiece(chunk.content));else if(options.exclude)for(charIndex=chunk.start;charIndex<end;){if(!isExcluded[charIndex]){let char=this.original.charCodeAt(charIndex);char===10?shouldIndentNextCharacter=!0:char!==13&&shouldIndentNextCharacter&&indentAt(charIndex)}charIndex+=1}else for(charIndex=chunk.start;charIndex<end;){if(!shouldIndentNextCharacter){let nextLine=this.original.indexOf(`
|
|
12
|
-
`,charIndex);if(nextLine===-1||nextLine>=end)break;shouldIndentNextCharacter=!0,charIndex=nextLine+1;continue}let char=this.original.charCodeAt(charIndex);if(char===10||char===13){charIndex+=1;continue}indentAt(charIndex),charIndex+=1}isExcluded[chunk.end-1]||(chunk.outro=indentPiece(chunk.outro)),charIndex=chunk.end,chunk=chunk.next}return this.outro=indentPiece(this.outro),this}insert(){throw new MagicStringError(`insert() is deprecated, use appendLeft() or prependRight()`)}insertLeft(index,content){return warned.insertLeft||=(console.warn(`magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead`),!0),this.appendLeft(index,content)}insertRight(index,content){return warned.insertRight||=(console.warn(`magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead`),!0),this.prependRight(index,content)}move(start,end,index,affinity=`right`){if(start+=this.offset,end+=this.offset,index+=this.offset,start===end)return this;if(index>=start&&index<=end)throw new MagicStringError(`cannot move a selection inside itself`);this._split(start),this._split(end),this._split(index);let first=this.byStart.get(start),last=this.byEnd.get(end);if(this.hasMovedChunks){let cursor=first;for(;cursor!==last;)if(cursor=cursor.next,!cursor||cursor.start<start||cursor.end>end)throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`)}let oldLeft=first.previous,oldRight=last.next,newLeft,newRight;if(affinity===`left`){if(newLeft=this.byEnd.get(index)??null,newLeft){if(newLeft.next===first)return this;newRight=newLeft.next}else{if(first===this.firstChunk)return this;newRight=this.firstChunk}}else if(newRight=this.byStart.get(index)??null,newRight){if(newRight.previous===last)return this;newLeft=newRight.previous}else{if(last===this.lastChunk)return this;newLeft=this.lastChunk}return oldLeft&&(oldLeft.next=oldRight),oldRight&&(oldRight.previous=oldLeft),newLeft&&(newLeft.next=first),newRight&&(newRight.previous=last),first.previous||(this.firstChunk=last.next),last.next||(this.lastChunk=first.previous,this.lastChunk.next=null),first.previous=newLeft,last.next=newRight||null,newLeft||(this.firstChunk=first),newRight||(this.lastChunk=last),this.hasMovedChunks=!0,this}overwrite(start,end,content,options){let optionObject=typeof options==`object`&&options?options:{};return this.update(start,end,content,{...optionObject,overwrite:!optionObject.contentOnly})}update(start,end,content,options){if(start+=this.offset,end+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);if(this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start<0)throw new MagicStringError(`start ${start} is out of bounds`);if(end>this.original.length)throw new MagicStringError(`end ${end} is out of bounds`);if(start===end)throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end),options===!0&&(warned.storeName||=(console.warn(`The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string`),!0),options={storeName:!0});let optionObject=typeof options==`object`&&options?options:{},storeName=optionObject.storeName||!1,overwrite=optionObject.overwrite||!1;if(storeName){let original=this.original.slice(start,end);Object.defineProperty(this.storedNames,original,{writable:!0,value:!0,enumerable:!0})}let first=this.byStart.get(start),last=this.byEnd.get(end);if(first){let chunk=first;for(;chunk!==last;){if(chunk.next!==this.byStart.get(chunk.end))throw new MagicStringError(`cannot overwrite across a split point`);chunk=chunk.next,chunk.edit(``,!1)}first.edit(content,storeName,!overwrite)}else{let newChunk=new Chunk(start,end,``).edit(content,storeName);last.next=newChunk,newChunk.previous=last}return this}prepend(content){if(typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);return this.intro=content+this.intro,this}prependLeft(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byEnd.get(index);return chunk?chunk.prependLeft(content):this.intro=content+this.intro,this}prependRight(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byStart.get(index);return chunk?chunk.prependRight(content):this.outro=content+this.outro,this}remove(start,end){if(start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start===end)return this;if(start<0||end>this.original.length)throw new MagicStringError(`range ${start}–${end} is out of bounds`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end);let chunk=this.byStart.get(start);for(;chunk;)chunk.start>start&&(chunk.intro=``),chunk.end<end&&(chunk.outro=``),chunk.edit(``,!1,!0),chunk=end>chunk.end?this.byStart.get(chunk.end):null;return this}reset(start,end){if(start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start===end)return this;if(start<0||end>this.original.length)throw new MagicStringError(`range ${start}–${end} is out of bounds`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end);let chunk=this.byStart.get(start);for(;chunk;)chunk.reset(),chunk=end>chunk.end?this.byStart.get(chunk.end):null;return this}lastChar(){if(this.outro.length)return this.outro[this.outro.length-1];let chunk=this.lastChunk;for(;chunk;){if(chunk.outro.length)return chunk.outro[chunk.outro.length-1];if(chunk.content.length)return chunk.content[chunk.content.length-1];if(chunk.intro.length)return chunk.intro[chunk.intro.length-1];chunk=chunk.previous}return this.intro.length?this.intro[this.intro.length-1]:``}lastLine(){let lineIndex=this.outro.lastIndexOf(`
|
|
12
|
+
`,charIndex);if(nextLine===-1||nextLine>=end)break;shouldIndentNextCharacter=!0,charIndex=nextLine+1;continue}let char=this.original.charCodeAt(charIndex);if(char===10||char===13){charIndex+=1;continue}indentAt(charIndex),charIndex+=1}isExcluded[chunk.end-1]||(chunk.outro=indentPiece(chunk.outro)),charIndex=chunk.end,chunk=chunk.next}return this.outro=indentPiece(this.outro),this}insert(){throw new MagicStringError(`insert() is deprecated, use appendLeft() or prependRight()`)}insertLeft(index,content){return warned.insertLeft||=(console.warn(`magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead`),!0),this.appendLeft(index,content)}insertRight(index,content){return warned.insertRight||=(console.warn(`magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead`),!0),this.prependRight(index,content)}move(start,end,index,affinity=`right`){if(start+=this.offset,end+=this.offset,index+=this.offset,start===end)return this;if(index>=start&&index<=end)throw new MagicStringError(`cannot move a selection inside itself`);this._split(start),this._split(end),this._split(index);let first=this.byStart.get(start),last=this.byEnd.get(end);if(this.hasMovedChunks){let cursor=first;for(;cursor!==last;)if(cursor=cursor.next,!cursor||cursor.start<start||cursor.end>end)throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`)}let oldLeft=first.previous,oldRight=last.next,newLeft,newRight;if(affinity===`left`){if(newLeft=this.byEnd.get(index)??null,newLeft){if(newLeft.next===first)return this;newRight=newLeft.next}else{if(first===this.firstChunk)return this;newRight=this.firstChunk}}else if(newRight=this.byStart.get(index)??null,newRight){if(newRight.previous===last)return this;newLeft=newRight.previous}else{if(last===this.lastChunk)return this;newLeft=this.lastChunk}return oldLeft&&(oldLeft.next=oldRight),oldRight&&(oldRight.previous=oldLeft),newLeft&&(newLeft.next=first),newRight&&(newRight.previous=last),first.previous||(this.firstChunk=last.next),last.next||(this.lastChunk=first.previous,this.lastChunk.next=null),first.previous=newLeft,last.next=newRight||null,newLeft||(this.firstChunk=first),newRight||(this.lastChunk=last),this.hasMovedChunks=!0,this}overwrite(start,end,content,options){let optionObject=typeof options==`object`&&options?options:{};return this.update(start,end,content,{...optionObject,overwrite:!optionObject.contentOnly})}update(start,end,content,options){if(start+=this.offset,end+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);if(this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start<0)throw new MagicStringError(`start ${start} is out of bounds`);if(end>this.original.length)throw new MagicStringError(`end ${end} is out of bounds`);if(start===end)throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end),options===!0&&(warned.storeName||=(console.warn(`The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string`),!0),options={storeName:!0});let optionObject=typeof options==`object`&&options?options:{},storeName=optionObject.storeName||!1,overwrite=optionObject.overwrite||!1;if(storeName){let original=this.original.slice(start,end);Object.defineProperty(this.storedNames,original,{writable:!0,value:!0,enumerable:!0})}let first=this.byStart.get(start),last=this.byEnd.get(end);if(first){let chunk=first;for(;chunk!==last;){if(chunk.next!==this.byStart.get(chunk.end))throw new MagicStringError(`cannot overwrite across a split point`);chunk=chunk.next,chunk.edit(``,!1,!overwrite)}first.edit(content,storeName,!overwrite)}else{let newChunk=new Chunk(start,end,``).edit(content,storeName);last.next=newChunk,newChunk.previous=last}return this}prepend(content){if(typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);return this.intro=content+this.intro,this}prependLeft(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byEnd.get(index);return chunk?chunk.prependLeft(content):this.intro=content+this.intro,this}prependRight(index,content){if(index+=this.offset,typeof content!=`string`)throw new MagicStringError(`content must be a string, got ${typeof content}`);this._split(index);let chunk=this.byStart.get(index);return chunk?chunk.prependRight(content):this.outro=content+this.outro,this}remove(start,end){if(start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start===end)return this;if(start<0||end>this.original.length)throw new MagicStringError(`range ${start}–${end} is out of bounds`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end);let chunk=this.byStart.get(start);for(;chunk;)chunk.start>start&&(chunk.intro=``),chunk.end<end&&(chunk.outro=``),chunk.edit(``,!1,!0),chunk=end>chunk.end?this.byStart.get(chunk.end):null;return this}reset(start,end){if(start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length))),start===end)return this;if(start<0||end>this.original.length)throw new MagicStringError(`range ${start}–${end} is out of bounds`);if(start>end)throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);this._split(start),this._split(end);let chunk=this.byStart.get(start);for(;chunk;)chunk.reset(),chunk=end>chunk.end?this.byStart.get(chunk.end):null;return this}lastChar(){if(this.outro.length)return this.outro[this.outro.length-1];let chunk=this.lastChunk;for(;chunk;){if(chunk.outro.length)return chunk.outro[chunk.outro.length-1];if(chunk.content.length)return chunk.content[chunk.content.length-1];if(chunk.intro.length)return chunk.intro[chunk.intro.length-1];chunk=chunk.previous}return this.intro.length?this.intro[this.intro.length-1]:``}lastLine(){let lineIndex=this.outro.lastIndexOf(`
|
|
13
13
|
`);if(lineIndex!==-1)return this.outro.substr(lineIndex+1);let lineStr=this.outro,chunk=this.lastChunk;for(;chunk;){if(chunk.outro.length>0){if(lineIndex=chunk.outro.lastIndexOf(`
|
|
14
14
|
`),lineIndex!==-1)return chunk.outro.substr(lineIndex+1)+lineStr;lineStr=chunk.outro+lineStr}if(chunk.content.length>0){if(lineIndex=chunk.content.lastIndexOf(`
|
|
15
15
|
`),lineIndex!==-1)return chunk.content.substr(lineIndex+1)+lineStr;lineStr=chunk.content+lineStr}if(chunk.intro.length>0){if(lineIndex=chunk.intro.lastIndexOf(`
|
|
16
16
|
`),lineIndex!==-1)return chunk.intro.substr(lineIndex+1)+lineStr;lineStr=chunk.intro+lineStr}chunk=chunk.previous}return lineIndex=this.intro.lastIndexOf(`
|
|
17
|
-
`),lineIndex===-1?this.intro+lineStr:this.intro.substr(lineIndex+1)+lineStr}slice(start=0,end=this.original.length-this.offset){start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length)));let result=``,chunk=this.firstChunk;for(;chunk&&(chunk.start>start||chunk.end<=start);){if(chunk.start<end&&chunk.end>=end||end===0&&chunk.start===0)return result;chunk=chunk.next}if(chunk&&chunk.edited&&chunk.start!==start)throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);let startChunk=chunk;for(;chunk&&(end!==0||chunk.start!==0);){chunk.intro&&(startChunk!==chunk||chunk.start===start)&&(result+=chunk.intro);let containsEnd=chunk.start<end&&chunk.end>=end;if(containsEnd&&chunk.edited&&chunk.end!==end)throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);let sliceStart=startChunk===chunk?start-chunk.start:0,sliceEnd=containsEnd?chunk.content.length+end-chunk.end:chunk.content.length;if(result+=chunk.content.slice(sliceStart,sliceEnd),chunk.outro&&(!containsEnd||chunk.end===end)&&(result+=chunk.outro),containsEnd)break;chunk=chunk.next}return result}snip(start,end){let clone=this.clone();return clone.remove(0,start),clone.remove(end,clone.original.length),clone}_split(index){if(this.byStart.get(index)||this.byEnd.get(index))return;let chunk=this.lastSearchedChunk,previousChunk=chunk,searchForward=index>chunk.end;for(;chunk;){if(chunk.contains(index))return this._splitChunk(chunk,index);if(chunk=searchForward?this.byStart.get(chunk.end):this.byEnd.get(chunk.start),chunk===previousChunk)return;previousChunk=chunk}}_splitChunk(chunk,index){if(chunk.edited&&chunk.content.length){let loc=getLocator(this.original)(index);throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`)}let newChunk=chunk.split(index);return this.byEnd.set(index,chunk),this.byStart.set(index,newChunk),this.byEnd.set(newChunk.end,newChunk),chunk===this.lastChunk&&(this.lastChunk=newChunk),this.lastSearchedChunk=chunk,!0}toString(){let str=this.intro,chunk=this.firstChunk;for(;chunk;)str+=chunk.toString(),chunk=chunk.next;return str+this.outro}isEmpty(){if(this.intro.length&&this.intro.trim())return!1;let chunk=this.firstChunk;for(;chunk;){if(chunk.intro.length&&chunk.intro.trim()||chunk.content.length&&chunk.content.trim()||chunk.outro.length&&chunk.outro.trim())return!1;chunk=chunk.next}return!(this.outro.length&&this.outro.trim())}length(){let chunk=this.firstChunk,length=0;for(;chunk;)length+=chunk.intro.length+chunk.content.length+chunk.outro.length,chunk=chunk.next;return length}trimLines(){return this.trim(`[\\r\\n]`)}trim(charType){return this.trimStart(charType).trimEnd(charType)}trimEndAborted(charType){let rx=RegExp(`${charType||`\\s`}+$`);if(this.outro=this.outro.replace(rx,``),this.outro.length)return!0;let chunk=this.lastChunk;do{let end=chunk.end,aborted=chunk.trimEnd(rx);if(chunk.end!==end&&(this.lastChunk===chunk&&(this.lastChunk=chunk.next),this.byEnd.set(chunk.end,chunk),this.byStart.set(chunk.next.start,chunk.next),this.byEnd.set(chunk.next.end,chunk.next)),aborted)return!0;chunk=chunk.previous}while(chunk);return this.intro=this.intro.replace(rx,``),this.intro.length>0}trimEnd(charType){return this.trimEndAborted(charType),this}trimStartAborted(charType){let rx=RegExp(`^${charType||`\\s`}+`);if(this.intro=this.intro.replace(rx,``),this.intro.length)return!0;let chunk=this.firstChunk;do{let end=chunk.end,aborted=chunk.trimStart(rx);if(chunk.end!==end&&(chunk===this.lastChunk&&(this.lastChunk=chunk.next),this.byEnd.set(chunk.end,chunk),this.byStart.set(chunk.next.start,chunk.next),this.byEnd.set(chunk.next.end,chunk.next)),aborted)return!0;chunk=chunk.next}while(chunk);return this.outro=this.outro.replace(rx,``),this.outro.length>0}trimStart(charType){return this.trimStartAborted(charType),this}hasChanged(){if(this.intro||this.outro)return!0;let outputIndex=0,chunk=this.firstChunk;for(;chunk;){if(chunk.intro||chunk.outro)return!0;if(!chunk.edited&&chunk.start===outputIndex)outputIndex=chunk.end;else{if(!this.original.startsWith(chunk.content,outputIndex))return!0;outputIndex+=chunk.content.length}chunk=chunk.next}return outputIndex!==this.original.length}_hasRemovedContent(start,end){let chunk=this.byStart.get(start);if(!chunk){chunk=this.lastSearchedChunk;let searchForward=start>=chunk.end;for(;chunk&&!chunk.contains(start);)chunk=searchForward?this.byStart.get(chunk.end):this.byEnd.get(chunk.start);chunk&&(this.lastSearchedChunk=chunk)}for(;chunk&&chunk.start<end;){if(chunk.content===``)return!0;chunk=this.byStart.get(chunk.end)}return!1}_replaceRegexp(searchValue,replacement){function getReplacement(match,str){return typeof replacement==`string`?expandReplacement(replacement,match[0],match.index,str,match.slice(1),match.groups):match.groups===void 0?replacement(match[0],...match.slice(1),match.index,str):replacement(match[0],...match.slice(1),match.index,str,match.groups)}let replaceMatch=match=>{if(match.index==null||this._hasRemovedContent(match.index,match.index+match[0].length))return!1;let replacement=getReplacement(match,this.original);return replacement===match[0]||(match[0].length===0?this.appendRight(match.index,replacement):this.overwrite(match.index,match.index+match[0].length,replacement)),!0};if(searchValue.global){searchValue.lastIndex=0;for(let match of this.original.matchAll(searchValue))replaceMatch(match)}else{let match=this.original.match(searchValue);if(match&&!replaceMatch(match)){let global=new RegExp(searchValue.source,`${searchValue.flags}g`);for(let next of this.original.matchAll(global))if(replaceMatch(next))break}}return this}_replaceString(string,replacement){let{original}=this,index=original.indexOf(string);for(;index!==-1;){if(this._hasRemovedContent(index,index+string.length)){index=original.indexOf(string,index+string.length);continue}replacement=typeof replacement==`function`?replacement(string,index,original):expandReplacement(replacement,string,index,original,[],void 0),string!==replacement&&(string.length===0?this.appendRight(index,replacement):this.overwrite(index,index+string.length,replacement));break}return this}replace(searchValue,replacement){return typeof searchValue==`string`?this._replaceString(searchValue,replacement):this._replaceRegexp(searchValue,replacement)}_replaceAllString(string,replacement){let{original}=this,stringLength=string.length;if(stringLength===0){for(let index=0;index<=original.length;index+=1){if(this._hasRemovedContent(index,index))continue;let _replacement=typeof replacement==`function`?replacement(``,index,original):expandReplacement(replacement,``,index,original,[],void 0);_replacement!==``&&this.appendRight(index,_replacement)}return this}for(let index=original.indexOf(string);index!==-1;index=original.indexOf(string,index+stringLength)){if(this._hasRemovedContent(index,index+stringLength))continue;let previous=original.slice(index,index+stringLength),_replacement=typeof replacement==`function`?replacement(previous,index,original):expandReplacement(replacement,previous,index,original,[],void 0);previous!==_replacement&&this.overwrite(index,index+stringLength,_replacement)}return this}replaceAll(searchValue,replacement){if(typeof searchValue==`string`)return this._replaceAllString(searchValue,replacement);if(!searchValue.global)throw new MagicStringError(`replaceAll() requires a global RegExp`);return this._replaceRegexp(searchValue,replacement)}};export{MagicString,MagicString as default};
|
|
17
|
+
`),lineIndex===-1?this.intro+lineStr:this.intro.substr(lineIndex+1)+lineStr}slice(start=0,end=this.original.length-this.offset){start+=this.offset,end+=this.offset,this.original.length!==0&&(start<0&&(start=Math.max(0,start+this.original.length)),end<0&&(end=Math.max(0,end+this.original.length)));let result=``,chunk=this.firstChunk;for(;chunk&&(chunk.start>start||chunk.end<=start);){if(chunk.start<end&&chunk.end>=end||end===0&&chunk.start===0)return result;chunk=chunk.next}if(chunk&&chunk.edited&&chunk.start!==start)throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);let startChunk=chunk;for(;chunk&&(end!==0||chunk.start!==0);){chunk.intro&&(startChunk!==chunk||chunk.start===start)&&(result+=chunk.intro);let containsEnd=chunk.start<end&&chunk.end>=end;if(containsEnd&&chunk.edited&&chunk.end!==end)throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);let sliceStart=startChunk===chunk?start-chunk.start:0,sliceEnd=containsEnd?chunk.content.length+end-chunk.end:chunk.content.length;if(result+=chunk.content.slice(sliceStart,sliceEnd),chunk.outro&&(!containsEnd||chunk.end===end)&&(result+=chunk.outro),containsEnd)break;chunk=chunk.next}return result}snip(start,end){let clone=this.clone();return clone.remove(0,start),clone.remove(end,clone.original.length),clone}_split(index){if(this.byStart.get(index)||this.byEnd.get(index))return;let chunk=this.lastSearchedChunk,previousChunk=chunk,searchForward=index>chunk.end;for(;chunk;){if(chunk.contains(index))return this._splitChunk(chunk,index);if(chunk=searchForward?this.byStart.get(chunk.end):this.byEnd.get(chunk.start),chunk===previousChunk)return;previousChunk=chunk}}_splitChunk(chunk,index){if(chunk.edited&&chunk.content.length){let loc=getLocator(this.original)(index);throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`)}let newChunk=chunk.split(index);return this.byEnd.set(index,chunk),this.byStart.set(index,newChunk),this.byEnd.set(newChunk.end,newChunk),chunk===this.lastChunk&&(this.lastChunk=newChunk),this.lastSearchedChunk=chunk,!0}toString(){let str=this.intro,chunk=this.firstChunk;for(;chunk;)str+=chunk.toString(),chunk=chunk.next;return str+this.outro}isEmpty(){if(this.intro.length&&this.intro.trim())return!1;let chunk=this.firstChunk;for(;chunk;){if(chunk.intro.length&&chunk.intro.trim()||chunk.content.length&&chunk.content.trim()||chunk.outro.length&&chunk.outro.trim())return!1;chunk=chunk.next}return!(this.outro.length&&this.outro.trim())}length(){let chunk=this.firstChunk,length=0;for(;chunk;)length+=chunk.intro.length+chunk.content.length+chunk.outro.length,chunk=chunk.next;return length}trimLines(){return this.trim(`[\\r\\n]`)}trim(charType){return this.trimStart(charType).trimEnd(charType)}trimEndAborted(charType){let rx=RegExp(`${charType||`\\s`}+$`);if(this.outro=this.outro.replace(rx,``),this.outro.length)return!0;let chunk=this.lastChunk;do{let end=chunk.end,aborted=chunk.trimEnd(rx);if(chunk.end!==end&&(this.lastChunk===chunk&&(this.lastChunk=chunk.next),this.byEnd.set(chunk.end,chunk),this.byStart.set(chunk.next.start,chunk.next),this.byEnd.set(chunk.next.end,chunk.next)),aborted)return!0;chunk=chunk.previous}while(chunk);return this.intro=this.intro.replace(rx,``),this.intro.length>0}trimEnd(charType){return this.trimEndAborted(charType),this}trimStartAborted(charType){let rx=RegExp(`^${charType||`\\s`}+`);if(this.intro=this.intro.replace(rx,``),this.intro.length)return!0;let chunk=this.firstChunk;do{let end=chunk.end,aborted=chunk.trimStart(rx);if(chunk.end!==end&&(chunk===this.lastChunk&&(this.lastChunk=chunk.next),this.byEnd.set(chunk.end,chunk),this.byStart.set(chunk.next.start,chunk.next),this.byEnd.set(chunk.next.end,chunk.next)),aborted)return!0;chunk=chunk.next}while(chunk);return this.outro=this.outro.replace(rx,``),this.outro.length>0}trimStart(charType){return this.trimStartAborted(charType),this}hasChanged(){if(this.intro||this.outro)return!0;let outputIndex=0,chunk=this.firstChunk;for(;chunk;){if(chunk.intro||chunk.outro)return!0;if(!chunk.edited&&chunk.start===outputIndex)outputIndex=chunk.end;else{if(!this.original.startsWith(chunk.content,outputIndex))return!0;outputIndex+=chunk.content.length}chunk=chunk.next}return outputIndex!==this.original.length}_hasRemovedContent(start,end){let chunk=this.byStart.get(start);if(!chunk){chunk=this.lastSearchedChunk;let searchForward=start>=chunk.end;for(;chunk&&!chunk.contains(start);)chunk=searchForward?this.byStart.get(chunk.end):this.byEnd.get(chunk.start);chunk&&(this.lastSearchedChunk=chunk)}for(;chunk&&chunk.start<end;){if(chunk.content===``)return!0;chunk=this.byStart.get(chunk.end)}return!1}_replaceRegexp(searchValue,replacement){function getReplacement(match,str){return typeof replacement==`string`?expandReplacement(replacement,match[0],match.index,str,match.slice(1),match.groups):match.groups===void 0?replacement(match[0],...match.slice(1),match.index,str):replacement(match[0],...match.slice(1),match.index,str,match.groups)}let replaceMatch=match=>{if(match.index==null||this._hasRemovedContent(match.index,match.index+match[0].length))return!1;let replacement=getReplacement(match,this.original);return replacement===match[0]||(match[0].length===0?this.appendRight(match.index-this.offset,replacement):this.overwrite(match.index-this.offset,match.index+match[0].length-this.offset,replacement)),!0};if(searchValue.global){searchValue.lastIndex=0;for(let match of this.original.matchAll(searchValue))replaceMatch(match)}else{let match=this.original.match(searchValue);if(match&&!replaceMatch(match)){let global=new RegExp(searchValue.source,`${searchValue.flags}g`);for(let next of this.original.matchAll(global))if(replaceMatch(next))break}}return this}_replaceString(string,replacement){let{original}=this,index=original.indexOf(string);for(;index!==-1;){if(this._hasRemovedContent(index,index+string.length)){index=original.indexOf(string,index+string.length);continue}replacement=typeof replacement==`function`?replacement(string,index,original):expandReplacement(replacement,string,index,original,[],void 0),string!==replacement&&(string.length===0?this.appendRight(index-this.offset,replacement):this.overwrite(index-this.offset,index+string.length-this.offset,replacement));break}return this}replace(searchValue,replacement){return typeof searchValue==`string`?this._replaceString(searchValue,replacement):this._replaceRegexp(searchValue,replacement)}_replaceAllString(string,replacement){let{original}=this,stringLength=string.length;if(stringLength===0){for(let index=0;index<=original.length;index+=1){if(this._hasRemovedContent(index,index))continue;let _replacement=typeof replacement==`function`?replacement(``,index,original):expandReplacement(replacement,``,index,original,[],void 0);_replacement!==``&&this.appendRight(index-this.offset,_replacement)}return this}for(let index=original.indexOf(string);index!==-1;index=original.indexOf(string,index+stringLength)){if(this._hasRemovedContent(index,index+stringLength))continue;let previous=original.slice(index,index+stringLength),_replacement=typeof replacement==`function`?replacement(previous,index,original):expandReplacement(replacement,previous,index,original,[],void 0);previous!==_replacement&&this.overwrite(index-this.offset,index+stringLength-this.offset,_replacement)}return this}replaceAll(searchValue,replacement){if(typeof searchValue==`string`)return this._replaceAllString(searchValue,replacement);if(!searchValue.global)throw new MagicStringError(`replaceAll() requires a global RegExp`);return this._replaceRegexp(searchValue,replacement)}};export{MagicString,MagicString as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as getGlobal}from"./global-DYq1Z4_H.mjs";import{FORCE_ENABLE_GLOBAL}from"@interfere/types/sdk/injected-globals";function isEnvironmentEnabled(environment,forceEnabled){return!environment||environment.NODE_ENV===`production`||environment.NODE_ENV===void 0||forceEnabled||!!environment.INTERFERE_FORCE_ENABLE}function isEnabledByEnvironment(){let environment=typeof process>`u`?void 0:process.env;return!environment||environment.NODE_ENV===`production`||environment.NODE_ENV===void 0||isEnvironmentEnabled({NODE_ENV:environment.NODE_ENV,INTERFERE_FORCE_ENABLE:environment.INTERFERE_FORCE_ENABLE},!!getGlobal(FORCE_ENABLE_GLOBAL))}export{isEnvironmentEnabled as n,isEnabledByEnvironment as t};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/internal/environment.d.ts
|
|
2
|
+
interface RuntimeEnvironment {
|
|
3
|
+
NODE_ENV?: string | undefined;
|
|
4
|
+
INTERFERE_FORCE_ENABLE?: string | undefined;
|
|
5
|
+
}
|
|
6
|
+
declare function isEnvironmentEnabled(environment: RuntimeEnvironment | null | undefined, forceEnabled: boolean): boolean;
|
|
7
|
+
declare function isEnabledByEnvironment(): boolean;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { isEnvironmentEnabled as n, isEnabledByEnvironment as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as InterfereContextValue, i as InterfereContext } from "./provider-
|
|
1
|
+
import { a as InterfereContextValue, i as InterfereContext } from "./provider-C68KiG80.mjs";
|
|
2
2
|
import { Component, ContextType, ErrorInfo, ReactNode } from "react";
|
|
3
3
|
//#region src/error-boundary.d.ts
|
|
4
4
|
export interface ErrorBoundaryProps {
|
package/dist/error-boundary.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{captureReactError}from"./
|
|
1
|
+
"use client";import{t as captureReactError}from"./capture-BV2RlsYg.mjs";import{t as InterfereContext}from"./react-context-c1uTUJfB.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,{handled:!0,type:MECHANISM_TYPE.react.errorBoundary}),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};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as hasServerDigest}from"./server-digest-CzGdvjW1.mjs";import{n as onConsoleCall}from"./console-patch-WNKoLE7U.mjs";import{t as hasEventListenerPair}from"./event-capabilities-Dd0Hoaq2.mjs";import{t as THIRD_PARTY_IGNORE}from"./third-party-hosts-BoJNL3xG.mjs";import{MECHANISM_TYPE,isNonErrorException,toException}from"@interfere/types/sdk/errors";import{omitUndefined}from"@interfere/helpers/omit-undefined";function capture(ctx,opts){ctx.recordException(opts.error,omitUndefined({mechanism:opts.mechanism,fallbackFrames:opts.fallbackFrame&&!isNonErrorException(opts.error)?[opts.fallbackFrame]:void 0}))}function findErrorArg(args){return args.find(arg=>arg instanceof Error)??null}function resourceError(target){return target instanceof HTMLImageElement||target instanceof HTMLScriptElement?target.src?{tag:target.localName,url:target.src}:null:target instanceof HTMLLinkElement&&target.href?{tag:target.localName,url:target.href}:null}function isIgnoredResourceUrl(url){return THIRD_PARTY_IGNORE.some(pattern=>pattern.test(url))}function createResourceGate(){let seen=new Set,windowStart=0,windowCount=0;return(url=>{if(seen.has(url))return!1;let now=Date.now();return now-windowStart>6e4&&(windowStart=now,windowCount=0),windowCount>=20?!1:(seen.size>=100&&seen.clear(),seen.add(url),windowCount+=1,!0)})}function createRepeatGate(){let counts=new Map,windowStart=0;return(key=>{let now=Date.now();now-windowStart>6e4&&(windowStart=now,counts.clear());let count=counts.get(key)??0;return count>=5?!1:(counts.size>=100&&counts.clear(),counts.set(key,count+1),!0)})}const errorsPlugin={name:`errors`,setup(ctx){let originalOnError=globalThis.onerror,originalStackTraceLimit=Error.stackTraceLimit;Error.stackTraceLimit<50&&(Error.stackTraceLimit=50);let repeatGate=createRepeatGate();globalThis.onerror=(msg,source,line,col,error)=>{if(error instanceof Error&&!hasServerDigest(error)&&repeatGate(`${typeof msg==`string`?msg:msg.type}|${String(source)}|${String(line)}|${String(col)}`)){let fallbackFrame=typeof source==`string`?omitUndefined({file:source,id:`fallback-0`,line:typeof line==`number`?line:void 0,column:typeof col==`number`?col:void 0}):null;capture(ctx,omitUndefined({error,mechanism:{handled:!1,type:MECHANISM_TYPE.browser.onerror},fallbackFrame:fallbackFrame??void 0}))}return typeof originalOnError==`function`&&originalOnError.call(globalThis,msg,source,line,col,error)};let onUnhandledRejection=event=>{hasServerDigest(event.reason)||capture(ctx,{error:toException(event.reason),mechanism:omitUndefined({handled:!1,type:MECHANISM_TYPE.browser.onunhandledrejection,synthetic:event.reason instanceof Error?void 0:!0})})},cspReportsByDisposition={enforce:new Set,report:new Set},onSecurityPolicyViolation=event=>{let seenCspReports=cspReportsByDisposition[event.disposition],key=`${event.violatedDirective}|${event.blockedURI}`;seenCspReports.has(key)||seenCspReports.size>=5||(seenCspReports.add(key),capture(ctx,{error:{kind:`non-error`,serialized:{blockedURI:event.blockedURI,columnNumber:event.columnNumber,disposition:event.disposition,lineNumber:event.lineNumber,sourceFile:event.sourceFile,violatedDirective:event.violatedDirective},type:`SecurityPolicyViolation`,value:event.disposition===`report`?`CSP ${event.violatedDirective} reported ${event.blockedURI||`inline`} (report-only)`:`CSP ${event.violatedDirective} blocked ${event.blockedURI||`inline`}`},mechanism:{handled:event.disposition===`report`,type:MECHANISM_TYPE.browser.securityPolicyViolation}}))},resourceGate=createResourceGate(),onResourceError=event=>{let resource=resourceError(event.target);resource&&!isIgnoredResourceUrl(resource.url)&&resourceGate(resource.url)&&capture(ctx,{error:{kind:`non-error`,serialized:{url:resource.url},type:`ResourceLoadError`,value:`Failed to load ${resource.tag}: ${resource.url}`},mechanism:{handled:!1,type:MECHANISM_TYPE.browser.resourceError}})},supportsEventTarget=hasEventListenerPair(globalThis.addEventListener,globalThis.removeEventListener);supportsEventTarget&&(globalThis.addEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.addEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.addEventListener(`error`,onResourceError,!0));let unsubscribeConsole=onConsoleCall((level,args)=>{if(level!==`error`)return;let error=findErrorArg(args);error&&!hasServerDigest(error)&&capture(ctx,{error,mechanism:{handled:!0,type:MECHANISM_TYPE.browser.consoleError}})});return()=>{Error.stackTraceLimit=originalStackTraceLimit,globalThis.onerror=originalOnError,supportsEventTarget&&(globalThis.removeEventListener(`unhandledrejection`,onUnhandledRejection),globalThis.removeEventListener(`securitypolicyviolation`,onSecurityPolicyViolation),globalThis.removeEventListener(`error`,onResourceError,!0)),unsubscribeConsole()}}};export{errorsPlugin as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function hasEventListenerPair(add,remove){return typeof add==`function`&&typeof remove==`function`}export{hasEventListenerPair as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as PRODUCER_VERSION}from"./version-BuN6IItu.mjs";import{t as IngestLogExporter}from"./exporter-logs-DS2AXWnV.mjs";import{t as IngestMetricExporter}from"./exporter-metrics-DZYqUo6_.mjs";import{toError}from"@interfere/types/sdk/errors";import{InterfereClient,InterfereError}from"@interfere/javascript";import{ExportResultCode}from"@opentelemetry/core";import{JsonTraceSerializer}from"@opentelemetry/otlp-transformer";import{z}from"zod";const INGEST_IGNORE_RE=/\/drain\/v1\/(?:traces|logs|metrics)(?:\?|$)/u;let ingestHalted=!1,consecutiveAuthRejections=0;function resetIngestHalt(){ingestHalted=!1,consecutiveAuthRejections=0}function isIngestHalted(){return ingestHalted}const textEncoder=new TextEncoder;let keepaliveBodyBytes=0;function detectUnacceptableExport(error){if(ingestHalted||error.statusCode!==422&&error.statusCode!==401)return;let body=error.body;if(typeof body==`object`&&body&&`code`in body){if(error.statusCode===422&&body.code===`RELEASE_NOT_FOUND`){ingestHalted=!0,console.warn(`[interfere] the ingest endpoint does not recognize this build's release. Telemetry export is disabled for this page load. Check that source-map upload and finalization succeeded and that build and runtime use the same surface key.`);return}if(error.statusCode===401&&body.code===`AUTH_PK_INVALID`){if(consecutiveAuthRejections+=1,consecutiveAuthRejections<3)return;ingestHalted=!0,console.warn(`[interfere] the ingest endpoint rejected this page's public key ${consecutiveAuthRejections} times in a row — telemetry export is disabled for this page load. Check that INTERFERE_PUBLIC_KEY matches an active surface.`)}}}function makeSender(input,signal){let client=new InterfereClient({...input.clientOptions,maxRetries:0,fetch:Object.assign(async(url,init)=>{let body=init?.body,bytes=typeof body==`string`?textEncoder.encode(body).byteLength:0,keepalive=keepaliveBodyBytes+bytes<=6e4;keepalive&&(keepaliveBodyBytes+=bytes);try{return await globalThis.fetch(url,{...init,credentials:`omit`,keepalive})}finally{keepalive&&(keepaliveBodyBytes-=bytes)}},globalThis.fetch)});return((payload,resultCallback)=>{if(!payload||payload.byteLength===0){resultCallback({code:ExportResultCode.SUCCESS});return}if(ingestHalted){resultCallback({code:ExportResultCode.FAILED,error:Error(`ingest halted: the ingest endpoint rejected this build's release`)});return}(async()=>{try{let body=z.record(z.string(),z.unknown()).parse(JSON.parse(new TextDecoder().decode(payload)));await client.drain.otlpExport({signal,body},{headers:{"x-interfere-producer-version":PRODUCER_VERSION}}),consecutiveAuthRejections=0,resultCallback({code:ExportResultCode.SUCCESS})}catch(error){error instanceof InterfereError&&detectUnacceptableExport(error),resultCallback({code:ExportResultCode.FAILED,error:toError(error)})}})()})}var IngestTraceExporter=class{send;constructor(send){this.send=send}export(spans,resultCallback){if(spans.length===0){resultCallback({code:ExportResultCode.SUCCESS});return}this.send(JsonTraceSerializer.serializeRequest(spans),resultCallback)}async shutdown(){return Promise.resolve()}async forceFlush(){return Promise.resolve()}};function createTraceExporter(input){return new IngestTraceExporter(makeSender(input,`traces`))}function createMetricExporter(input,gatedResourceAttributes){return new IngestMetricExporter(makeSender(input,`metrics`),gatedResourceAttributes)}function createLogExporter(input){return new IngestLogExporter(makeSender(input,`logs`))}export{isIngestHalted as a,createTraceExporter as i,createLogExporter as n,resetIngestHalt as o,createMetricExporter as r,INGEST_IGNORE_RE as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ExportResultCode}from"@opentelemetry/core";import{JsonLogsSerializer}from"@opentelemetry/otlp-transformer";var IngestLogExporter=class{send;constructor(send){this.send=send}export(logs,resultCallback){if(logs.length===0){resultCallback({code:ExportResultCode.SUCCESS});return}this.send(JsonLogsSerializer.serializeRequest(logs),resultCallback)}async shutdown(){return Promise.resolve()}async forceFlush(){return Promise.resolve()}};export{IngestLogExporter as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{JsonMetricsSerializer}from"@opentelemetry/otlp-transformer";import{resourceFromAttributes}from"@opentelemetry/resources";import{AggregationTemporality}from"@opentelemetry/sdk-metrics";var IngestMetricExporter=class{gatedResourceAttributes;send;constructor(send,gatedResourceAttributes){this.send=send,this.gatedResourceAttributes=gatedResourceAttributes??null}export(metrics,resultCallback){let gated=this.gatedResourceAttributes,payload=gated?.isEnabled()===!0?{...metrics,resource:metrics.resource.merge(resourceFromAttributes(gated.attributes))}:metrics;this.send(JsonMetricsSerializer.serializeRequest(payload),resultCallback)}selectAggregationTemporality(){return AggregationTemporality.DELTA}async forceFlush(){return Promise.resolve()}async shutdown(){return Promise.resolve()}};export{IngestMetricExporter as t};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{cloudflareTraceSchema}from"@interfere/types/sdk/geo";function parseTrace(text){let result={};for(let line of text.split(`
|
|
2
|
+
`)){let idx=line.indexOf(`=`);idx>0&&(result[line.slice(0,idx)]=line.slice(idx+1))}return result}var GeoDetector=class{cached=null;pending=null;failed=!1;epoch=0;fetcher;constructor(fetcher){this.fetcher=fetcher??globalThis.fetch.bind(globalThis)}async detect(){return this.cached?this.cached:this.failed?null:(this.pending??=this.resolveCountryCode(),this.pending)}async resolveCountryCode(){let{epoch}=this,code=await this.fetchCountryCode();return epoch===this.epoch?(this.cached=code,code||(this.failed=!0),this.pending=null,code):null}getCountry(){return this.cached}clear(){this.epoch+=1,this.cached=null,this.failed=!1,this.pending=null}async fetchCountryCode(){try{let res=await this.fetcher(`https://cloudflare.com/cdn-cgi/trace`,{signal:AbortSignal.timeout(3e3)});if(!res.ok)return null;let raw=parseTrace(await res.text()),trace=cloudflareTraceSchema.safeParse(raw);return trace.success?trace.data.loc.toUpperCase():null}catch{return null}}};export{GeoDetector as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function getGlobal(key){return Reflect.get(globalThis,key)}function getStringGlobal(key){let value=getGlobal(key);return typeof value==`string`?value:void 0}function setGlobal(key,value){Reflect.set(globalThis,key,value)}export{getStringGlobal as n,setGlobal as r,getGlobal as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as normalizePath}from"./normalize-path-BChqP8pA.mjs";import{t as ATTR_HTTP_ROUTE}from"./url-attrs-BdcyE2n6.mjs";function stampHttpSpanRoute(span,method,pathname,resolveRoute){let template=resolveRoute?.(pathname),route=template??normalizePath(pathname);span.setAttribute(ATTR_HTTP_ROUTE,route),span.setAttribute(`interfere.route.source`,template?`template`:`normalized`),span.updateName(`${method} ${route}`)}export{stampHttpSpanRoute as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const HYDRATION_CODE=/(?:Minified React error #|react\.dev\/errors\/)(?:418|423|425)/u,HYDRATION_TEXT=/hydration failed|error while hydrating|hydrated but|text content does not match|server[- ]rendered html|did(?:n't| not) match the client/iu;function isHydrationError(error){if(!(error instanceof Error))return!1;let{message}=error;return HYDRATION_CODE.test(message)||HYDRATION_TEXT.test(message)}export{isHydrationError as t};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function recordInitialNavigation(input){let url=input.getLocationHref?input.getLocationHref():globalThis.location?.href;if(!url)return;let sessionId=input.getSessionId();if(!sessionId)return;let key=`${sessionId}:${input.getWindowId()??``}:${url}`;input.seen.has(key)||(input.seen.add(key),input.loggerProvider.getLogger(`@opentelemetry/instrumentation-browser-navigation`).emit({attributes:{"browser.navigation.type":`pageload`,"url.full":input.redactUrl?input.redactUrl(url):url},severityNumber:0}))}export{recordInitialNavigation as t};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import { i as PrivacyPolicy } from "./privacy-CPKosXDP.mjs";
|
|
1
2
|
import { Span } from "@opentelemetry/api";
|
|
2
3
|
import { FetchCustomAttributeFunction } from "@opentelemetry/instrumentation-fetch";
|
|
3
|
-
import { LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
4
4
|
import { WebTracerProvider } from "@opentelemetry/sdk-trace-web";
|
|
5
|
+
import { LoggerProvider } from "@opentelemetry/sdk-logs";
|
|
5
6
|
//#region src/internal/otel/instrumentations.d.ts
|
|
6
7
|
type FetchError = Exclude<Parameters<FetchCustomAttributeFunction>[2], Response>;
|
|
7
8
|
type FetchSpanRequest = Request | RequestInfo | RequestInit | URL;
|
|
@@ -52,6 +53,10 @@ interface InstrumentationsInput {
|
|
|
52
53
|
* `THIRD_PARTY_IGNORE` defaults and the customer's `ignoreUrls`.
|
|
53
54
|
*/
|
|
54
55
|
ignoreUrls: (string | RegExp)[];
|
|
56
|
+
/** Interaction privacy policy. Defaults to the built-in privacy classes. */
|
|
57
|
+
privacyPolicy?: PrivacyPolicy;
|
|
58
|
+
/** Whether click and submit spans are captured while page events are enabled. Defaults to `true`. */
|
|
59
|
+
isInteractionCaptureEnabled?: () => boolean;
|
|
55
60
|
loggerProvider?: LoggerProvider;
|
|
56
61
|
/**
|
|
57
62
|
* Customer-supplied URL patterns the fetch + XHR instrumentations
|
|
@@ -59,6 +64,8 @@ interface InstrumentationsInput {
|
|
|
59
64
|
* always propagate.
|
|
60
65
|
*/
|
|
61
66
|
propagateContextUrls?: (string | RegExp)[];
|
|
67
|
+
/** Redacts URLs in navigation logs. Defaults to leaving them unchanged. */
|
|
68
|
+
redactUrl?: (url: string) => string;
|
|
62
69
|
/**
|
|
63
70
|
* Pathname → low-cardinality route template (e.g. `/blog/[slug]`).
|
|
64
71
|
* Drives span renaming + `url.path` / `http.route` attrs across
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as DEFAULT_PRIVACY_POLICY}from"./privacy-CRuL0X8r.mjs";import{t as THIRD_PARTY_IGNORE}from"./third-party-hosts-BoJNL3xG.mjs";import{n as describeActionable,r as isActionable}from"./actionable-DOmVf_ib.mjs";import{i as stampUrlAttrs,n as ATTR_URL_FULL,r as ATTR_URL_PATH}from"./url-attrs-BdcyE2n6.mjs";import{t as stampHttpSpanRoute}from"./http-span-route-t2gig-KI.mjs";import{MECHANISM_TYPE}from"@interfere/types/sdk/errors";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{registerInstrumentations}from"@opentelemetry/instrumentation";import{BrowserNavigationInstrumentation,defaultSanitizeUrl}from"@opentelemetry/instrumentation-browser-navigation";import{DocumentLoadInstrumentation}from"@opentelemetry/instrumentation-document-load";import{FetchInstrumentation}from"@opentelemetry/instrumentation-fetch";import{LongTaskInstrumentation}from"@opentelemetry/instrumentation-long-task";import{UserInteractionInstrumentation}from"@opentelemetry/instrumentation-user-interaction";import{XMLHttpRequestInstrumentation}from"@opentelemetry/instrumentation-xml-http-request";import{getElementXPath}from"@opentelemetry/sdk-trace-web";const DEFAULT_FAILURE_RANGES=[[400,599]];function resolveFailureRanges(opt){if(opt===!1)return null;if(opt===void 0||opt===!0)return DEFAULT_FAILURE_RANGES;let codes=opt.statusCodes;return codes&&codes.length>0?codes:DEFAULT_FAILURE_RANGES}function createFailureGate(){let seen=new Set,windowStart=0,windowCount=0;return(key=>{if(seen.has(key))return!1;let now=Date.now();return now-windowStart>6e4&&(windowStart=now,windowCount=0),windowCount>=20?!1:(seen.size>=100&&seen.clear(),seen.add(key),windowCount+=1,!0)})}function failureKey(method,discriminator,url){let path;try{path=new URL(url).pathname}catch{path=url}return`${method} ${discriminator} ${path}`}function statusMatches(status,ranges){for(let range of ranges)if(typeof range==`number`){if(status===range)return!0}else if(status>=range[0]&&status<=range[1])return!0;return!1}function recordHttpFailure(span,status,method,url,mechanism){span.addEvent(`exception`,{"exception.message":`HTTP ${status} ${method} ${url}`,"exception.type":`HttpResponseError`,"interfere.exception.handled":!1,"interfere.exception.kind":`error`,"interfere.exception.mechanism":mechanism})}function maybeCaptureFetchFailure(span,result,failureRanges,method,url,gate){if(!failureRanges)return;let status=result?.status;typeof status!=`number`||status<=0||!statusMatches(status,failureRanges)||(!gate||gate(failureKey(method,status,url)))&&recordHttpFailure(span,status,method,url,MECHANISM_TYPE.browser.fetchFailedResponse)}const NETWORK_TIMEOUT_RE=/timeout|timed out/iu,NETWORK_ABORT_RE=/abort/iu;function classifyNetworkError(message){return NETWORK_TIMEOUT_RE.test(message)?`timeout`:NETWORK_ABORT_RE.test(message)?`abort`:`network`}function recordNetworkFailure(span,kind,method,url,mechanism){span.addEvent(`exception`,{"exception.message":`Network ${kind} ${method} ${url}`,"exception.type":`NetworkError`,"interfere.exception.handled":!1,"interfere.exception.kind":`error`,"interfere.exception.mechanism":mechanism,"interfere.exception.subtype":kind})}function maybeCaptureNetworkFailure(span,result,failureRanges,method,url,gate){if(!failureRanges)return;let{message}=result;if(typeof message!=`string`||message.length===0)return;let kind=classifyNetworkError(message);(!gate||gate(failureKey(method,kind,url)))&&recordNetworkFailure(span,kind,method,url,MECHANISM_TYPE.browser.fetchNetworkError)}function applyFetchSpanAttrs(span,request,result,failureRanges,isTrackedUrl,resolveRoute,gate){let url=resolveFetchUrl(span,request,result);if(!url)return;let parsed;try{parsed=new URL(url)}catch{return}span.setAttribute(ATTR_URL_PATH,parsed.pathname);let tracked=isTrackedUrl(url),method=resolveFetchMethod(request);tracked&&(stampHttpSpanRoute(span,method,parsed.pathname,resolveRoute),result instanceof Response?maybeCaptureFetchFailure(span,result,failureRanges,method,url,gate):maybeCaptureNetworkFailure(span,result,failureRanges,method,url,gate))}function applyXhrSpanAttrs(span,xhr,failureRanges,isTrackedUrl,gate,resolveRoute){let url=xhr.responseURL||spanUrlFull(span);if(!(url&&isTrackedUrl(url)))return;let parsed;try{parsed=new URL(url)}catch{return}let method=isReadableSpan(span)?String(span.attributes[`http.request.method`]??span.attributes[`http.method`]??`XHR`):`XHR`;if(span.setAttribute(ATTR_URL_PATH,parsed.pathname),stampHttpSpanRoute(span,method,parsed.pathname,resolveRoute),!failureRanges)return;let{status}=xhr;if(typeof status==`number`){if(status===0){(!gate||gate(failureKey(`XHR`,`network`,url)))&&recordNetworkFailure(span,`network`,`XHR`,url,MECHANISM_TYPE.browser.xhrNetworkError);return}statusMatches(status,failureRanges)&&(!gate||gate(failureKey(`XHR`,status,url)))&&recordHttpFailure(span,status,`XHR`,url,MECHANISM_TYPE.browser.xhrFailedResponse)}}function resolveFetchUrl(span,request,result){return responseUrl(result)??requestUrl(request)??spanUrlFull(span)}function isReadableSpan(span){return`attributes`in span}function spanUrlFull(span){if(!isReadableSpan(span))return null;let url=span.attributes[`url.full`]??span.attributes[`http.url`];return typeof url==`string`?url:null}function responseUrl(result){return result instanceof Response&&result.url?result.url:null}function requestUrl(request){return typeof request==`string`?request:readStringProp(request,`url`)??readStringProp(request,`href`)}function resolveFetchMethod(request){return readStringProp(request,`method`)??`GET`}function readStringProp(value,key){if(!(typeof value==`object`&&value&&key in value))return null;let prop=Reflect.get(value,key);return typeof prop==`string`?prop:null}const testOnlyApplyFetchSpanAttrs=applyFetchSpanAttrs,testOnlyApplyXhrSpanAttrs=applyXhrSpanAttrs,testOnlyResolveFailureRanges=resolveFailureRanges,testOnlyCreateFailureGate=createFailureGate,testOnlyClassifyNetworkError=classifyNetworkError,NEVER_MATCH=/^$/u,ESCAPE_RE=/[.*+?^${}()|[\]\\]/gu;function sameOriginPattern(){if(typeof window>`u`)return NEVER_MATCH;let{protocol,host}=globalThis.location;return RegExp(`^${protocol}//${host.replace(ESCAPE_RE,String.raw`\$&`)}`,`u`)}function stampInteractionAttrs(eventType,element,span,policy){let desc=describeActionable(element,policy);span.setAttribute(`ui.event_type`,eventType),span.setAttribute(`ui.target.tag`,desc.tag),desc.privacy&&(span.setAttribute(`ui.target.privacy`,desc.privacy),span.setAttribute(`target_xpath`,getElementXPath(element,!1))),desc.label&&span.setAttribute(`ui.target.label`,desc.label),desc.id&&span.setAttribute(`ui.target.id`,desc.id),desc.name&&span.setAttribute(`ui.target.name`,desc.name),desc.role&&span.setAttribute(`ui.target.role`,desc.role),desc.ariaLabel&&span.setAttribute(`ui.target.aria_label`,desc.ariaLabel),desc.text&&span.setAttribute(`ui.target.text`,desc.text)}const PREFETCH_HEADER_NAMES=[`next-router-prefetch`,`next-router-segment-prefetch`];function isPrefetchRequest(request){let headers;try{headers=typeof Request<`u`&&request instanceof Request?request.headers:new Headers(request.headers)}catch{return!1}return PREFETCH_HEADER_NAMES.some(name=>headers.has(name))||headers.get(`purpose`)===`prefetch`||headers.get(`sec-purpose`)?.includes(`prefetch`)===!0}function escapeRegExp(value){return value.replaceAll(/[.*+?^${}()|[\]\\]/gu,String.raw`\$&`)}function apiHostToMatcher(host){return RegExp(`^https?://${escapeRegExp(host)}(:\\d+)?([/?#]|$)`,`u`)}function registerBundledInstrumentations(input){let{tracerProvider,loggerProvider,ignoreUrls,apiHosts=[],propagateContextUrls=[],privacyPolicy=DEFAULT_PRIVACY_POLICY,isInteractionCaptureEnabled=()=>!0,redactUrl=url=>url}=input,{resolveRoute}=input,origin=sameOriginPattern(),propagateMatchers=[...apiHosts.map(host=>apiHostToMatcher(host)),...propagateContextUrls],fetchIgnore=[...ignoreUrls,...THIRD_PARTY_IGNORE],failureRanges=resolveFailureRanges(input.captureFailedRequests),failureGate=createFailureGate();function isTrackedUrl(url){return origin.test(url)||propagateMatchers.some(re=>re instanceof RegExp?re.test(url):url.includes(re))}let pageEventsEnabled=!1,coreInstrumentations=[new FetchInstrumentation({applyCustomAttributesOnSpan:(span,request,result)=>{applyFetchSpanAttrs(span,request,result,failureRanges,isTrackedUrl,resolveRoute,failureGate)},ignoreUrls:fetchIgnore,measureRequestSize:!0,propagateTraceHeaderCorsUrls:[origin,...propagateMatchers],requestHook:(span,request)=>{isPrefetchRequest(request)&&span.setAttribute(`http.request.prefetch`,!0)}}),new XMLHttpRequestInstrumentation({applyCustomAttributesOnSpan:(span,xhr)=>{applyXhrSpanAttrs(span,xhr,failureRanges,isTrackedUrl,failureGate,resolveRoute)},ignoreUrls:fetchIgnore,propagateTraceHeaderCorsUrls:[origin,...propagateMatchers]}),new LongTaskInstrumentation({observerCallback:(span,info)=>{stampUrlAttrs(span,resolveRoute);let containerType=info.longtaskEntry.attribution[0]?.containerType;containerType&&span.setAttribute(`longtask.container_type`,containerType)}}),new UserInteractionInstrumentation({eventNames:[`click`,`submit`],shouldPreventSpanCreation:(eventType,element,span)=>!(pageEventsEnabled&&isInteractionCaptureEnabled())||eventType===`click`&&!isActionable(element)||(stampInteractionAttrs(eventType,element,span,privacyPolicy),stampUrlAttrs(span,resolveRoute),!1)})],pageEventsInstrumentations=[new DocumentLoadInstrumentation({applyCustomAttributesOnSpan:{resourceFetch:(span,entry)=>{let name=entry?.name;if(typeof name!=`string`)return;let url;try{url=new URL(name)}catch{return}let isCrossOrigin=typeof window<`u`&&url.origin!==globalThis.location.origin;span.updateName(isCrossOrigin?`resource: ${url.host}${url.pathname}`:`resource: ${url.pathname}`),span.setAttribute(ATTR_URL_FULL,name),span.setAttribute(ATTR_URL_PATH,url.pathname),span.setAttribute(`server.address`,url.host)}},enabled:!1}),new BrowserNavigationInstrumentation({enabled:!1,sanitizeUrl:url=>redactUrl(defaultSanitizeUrl(url))})],unregisterCore=registerInstrumentations(omitUndefined({tracerProvider,loggerProvider,instrumentations:coreInstrumentations})),unregisterPageEvents=null,setPageEventsEnabled=enabled=>{if(pageEventsEnabled=enabled,enabled){unregisterPageEvents??=registerInstrumentations(omitUndefined({tracerProvider,loggerProvider,instrumentations:pageEventsInstrumentations}));return}unregisterPageEvents?.(),unregisterPageEvents=null};return{dispose:()=>{setPageEventsEnabled(!1),unregisterCore()},setPageEventsEnabled}}export{testOnlyCreateFailureGate as a,testOnlyClassifyNetworkError as i,testOnlyApplyFetchSpanAttrs as n,testOnlyResolveFailureRanges as o,testOnlyApplyXhrSpanAttrs as r,registerBundledInstrumentations as t};
|