@scalebun/web 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/SDKBootstrapper.d.ts.map +1 -1
- package/dist/bootstrap/SDKBootstrapper.js +37 -1
- package/dist/bootstrap/SDKBootstrapper.js.map +1 -1
- package/dist/browser.d.ts +2 -2
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +6 -3
- package/dist/browser.js.map +1 -1
- package/dist/config/schema.d.ts +3 -3
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +25 -6
- package/dist/config/schema.js.map +1 -1
- package/dist/core/pageContext.js +17 -1
- package/dist/core/pageContext.js.map +1 -1
- package/dist/core/prune.d.ts +28 -4
- package/dist/core/prune.d.ts.map +1 -1
- package/dist/core/prune.js +92 -11
- package/dist/core/prune.js.map +1 -1
- package/dist/features/bugreport/BugReportFeature.d.ts +3 -2
- package/dist/features/bugreport/BugReportFeature.d.ts.map +1 -1
- package/dist/features/bugreport/BugReportFeature.js +2 -1
- package/dist/features/bugreport/BugReportFeature.js.map +1 -1
- package/dist/features/bugreport/collect.d.ts +13 -1
- package/dist/features/bugreport/collect.d.ts.map +1 -1
- package/dist/features/bugreport/collect.js +4 -1
- package/dist/features/bugreport/collect.js.map +1 -1
- package/dist/features/bugreport/widget.d.ts +21 -2
- package/dist/features/bugreport/widget.d.ts.map +1 -1
- package/dist/features/bugreport/widget.js +37 -4
- package/dist/features/bugreport/widget.js.map +1 -1
- package/dist/features/coach/overlay.d.ts.map +1 -1
- package/dist/features/coach/overlay.js +26 -5
- package/dist/features/coach/overlay.js.map +1 -1
- package/dist/features/engage/EngageFeature.d.ts +7 -1
- package/dist/features/engage/EngageFeature.d.ts.map +1 -1
- package/dist/features/engage/EngageFeature.js +32 -10
- package/dist/features/engage/EngageFeature.js.map +1 -1
- package/dist/features/engage/normalize.d.ts.map +1 -1
- package/dist/features/engage/normalize.js +7 -0
- package/dist/features/engage/normalize.js.map +1 -1
- package/dist/features/engage/runtime.d.ts +11 -0
- package/dist/features/engage/runtime.d.ts.map +1 -1
- package/dist/features/engage/runtime.js +25 -10
- package/dist/features/engage/runtime.js.map +1 -1
- package/dist/features/engage/throttle.d.ts +16 -6
- package/dist/features/engage/throttle.d.ts.map +1 -1
- package/dist/features/engage/throttle.js +96 -6
- package/dist/features/engage/throttle.js.map +1 -1
- package/dist/features/engage/types.d.ts +6 -0
- package/dist/features/engage/types.d.ts.map +1 -1
- package/dist/features/engage/types.js.map +1 -1
- package/dist/features/inapp/InApp2Feature.d.ts.map +1 -1
- package/dist/features/inapp/InApp2Feature.js +1 -0
- package/dist/features/inapp/InApp2Feature.js.map +1 -1
- package/dist/features/inapp/blocks/heavy/steps.d.ts.map +1 -1
- package/dist/features/inapp/blocks/heavy/steps.js +9 -1
- package/dist/features/inapp/blocks/heavy/steps.js.map +1 -1
- package/dist/features/inapp/blocks/styles.d.ts +1 -1
- package/dist/features/inapp/blocks/styles.d.ts.map +1 -1
- package/dist/features/inapp/blocks/styles.js +30 -3
- package/dist/features/inapp/blocks/styles.js.map +1 -1
- package/dist/features/inapp/center/panel.d.ts +1 -1
- package/dist/features/inapp/center/panel.d.ts.map +1 -1
- package/dist/features/inapp/center/panel.js +40 -6
- package/dist/features/inapp/center/panel.js.map +1 -1
- package/dist/features/inapp/core/engine.d.ts +2 -0
- package/dist/features/inapp/core/engine.d.ts.map +1 -1
- package/dist/features/inapp/core/engine.js +1 -1
- package/dist/features/inapp/core/engine.js.map +1 -1
- package/dist/features/inapp/core/host.d.ts.map +1 -1
- package/dist/features/inapp/core/host.js +5 -1
- package/dist/features/inapp/core/host.js.map +1 -1
- package/dist/features/inapp/core/targeting.d.ts +29 -2
- package/dist/features/inapp/core/targeting.d.ts.map +1 -1
- package/dist/features/inapp/core/targeting.js +78 -4
- package/dist/features/inapp/core/targeting.js.map +1 -1
- package/dist/features/inapp/inappContract.web.d.ts.map +1 -1
- package/dist/features/inapp/inappContract.web.js +12 -1
- package/dist/features/inapp/inappContract.web.js.map +1 -1
- package/dist/features/inapp/surfaces/coachmark.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/coachmark.js +5 -2
- package/dist/features/inapp/surfaces/coachmark.js.map +1 -1
- package/dist/features/inapp/surfaces/hotspot.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/hotspot.js +5 -2
- package/dist/features/inapp/surfaces/hotspot.js.map +1 -1
- package/dist/features/inapp/surfaces/inline.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/inline.js +7 -1
- package/dist/features/inapp/surfaces/inline.js.map +1 -1
- package/dist/features/inapp/surfaces/popover.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/popover.js +5 -2
- package/dist/features/inapp/surfaces/popover.js.map +1 -1
- package/dist/features/inapp/surfaces/styles.d.ts +1 -1
- package/dist/features/inapp/surfaces/styles.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/styles.js +60 -11
- package/dist/features/inapp/surfaces/styles.js.map +1 -1
- package/dist/features/inapp/surfaces/toolbar.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/toolbar.js +5 -2
- package/dist/features/inapp/surfaces/toolbar.js.map +1 -1
- package/dist/features/inapp/surfaces/tour.d.ts.map +1 -1
- package/dist/features/inapp/surfaces/tour.js +5 -2
- package/dist/features/inapp/surfaces/tour.js.map +1 -1
- package/dist/features/inapp/types.d.ts +2 -0
- package/dist/features/inapp/types.d.ts.map +1 -1
- package/dist/features/journey/InteractionTracker.d.ts.map +1 -1
- package/dist/features/journey/InteractionTracker.js +145 -0
- package/dist/features/journey/InteractionTracker.js.map +1 -1
- package/dist/features/journey/positionContext.d.ts +34 -0
- package/dist/features/journey/positionContext.d.ts.map +1 -0
- package/dist/features/journey/positionContext.js +43 -0
- package/dist/features/journey/positionContext.js.map +1 -0
- package/dist/features/manifest.d.ts +21 -0
- package/dist/features/manifest.d.ts.map +1 -1
- package/dist/features/manifest.js +27 -10
- package/dist/features/manifest.js.map +1 -1
- package/dist/features/replay/ReplayFeature.d.ts +20 -0
- package/dist/features/replay/ReplayFeature.d.ts.map +1 -1
- package/dist/features/replay/ReplayFeature.js +155 -5
- package/dist/features/replay/ReplayFeature.js.map +1 -1
- package/dist/features/replay/lifecycle/recorder.d.ts +21 -1
- package/dist/features/replay/lifecycle/recorder.d.ts.map +1 -1
- package/dist/features/replay/lifecycle/recorder.js +20 -4
- package/dist/features/replay/lifecycle/recorder.js.map +1 -1
- package/dist/features/scroll/index.d.ts +2 -0
- package/dist/features/scroll/index.d.ts.map +1 -1
- package/dist/features/scroll/index.js +6 -2
- package/dist/features/scroll/index.js.map +1 -1
- package/dist/features/session/sessionStore.d.ts +17 -1
- package/dist/features/session/sessionStore.d.ts.map +1 -1
- package/dist/features/session/sessionStore.js +17 -1
- package/dist/features/session/sessionStore.js.map +1 -1
- package/dist/pipeline/pipeline.d.ts +82 -0
- package/dist/pipeline/pipeline.d.ts.map +1 -1
- package/dist/pipeline/pipeline.js +307 -14
- package/dist/pipeline/pipeline.js.map +1 -1
- package/dist/public/ScaleBunFacade.d.ts +31 -0
- package/dist/public/ScaleBunFacade.d.ts.map +1 -1
- package/dist/public/ScaleBunFacade.js +52 -10
- package/dist/public/ScaleBunFacade.js.map +1 -1
- package/dist/scalebun.min.js +147 -65
- package/dist/scalebun.min.js.map +4 -4
- package/dist/transport/httpClient.d.ts +56 -2
- package/dist/transport/httpClient.d.ts.map +1 -1
- package/dist/transport/httpClient.js +81 -5
- package/dist/transport/httpClient.js.map +1 -1
- package/package.json +10 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SDKBootstrapper.d.ts","sourceRoot":"","sources":["../../src/bootstrap/SDKBootstrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,yBAAyB,CAAC;AAElF,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAwJ,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AACnM,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASpD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUhE;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,mGAAmG;IACnG,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6BAA6B;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAED,qBAAa,eAAe;IAC1B;;;;;OAKG;WACU,SAAS,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"SDKBootstrapper.d.ts","sourceRoot":"","sources":["../../src/bootstrap/SDKBootstrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,yBAAyB,CAAC;AAElF,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAwJ,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AACnM,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASpD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUhE;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,cAAc,CAAC;IACvB,OAAO,EAAE,cAAc,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,UAAU,CAAC;IACtB,QAAQ,EAAE,eAAe,CAAC;IAC1B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAClC,mGAAmG;IACnG,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,6BAA6B;IAC7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;CACvC;AAED,qBAAa,eAAe;IAC1B;;;;;OAKG;WACU,SAAS,CAAC,KAAK,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC;CA8PlG"}
|
|
@@ -9,7 +9,7 @@ import { SessionManager } from '../features/session/sessionManager.js';
|
|
|
9
9
|
import { HttpClient } from '../transport/httpClient.js';
|
|
10
10
|
import { Pipeline } from '../pipeline/pipeline.js';
|
|
11
11
|
import { FeatureRegistry } from './FeatureRegistry.js';
|
|
12
|
-
import { FEATURES, featureRequirements } from '../features/manifest.js';
|
|
12
|
+
import { FEATURES, OPTIONAL_FEATURES, featureRequirements } from '../features/manifest.js';
|
|
13
13
|
import { can } from '../core/index.js';
|
|
14
14
|
// 0-cost-closed: map an item kind → the SDK-suppressible entitlement that gates it (or '' if
|
|
15
15
|
// ungated). When the org has CLOSED one of these features (admin dashboard → /config entitlements),
|
|
@@ -139,6 +139,41 @@ export class SDKBootstrapper {
|
|
|
139
139
|
}
|
|
140
140
|
};
|
|
141
141
|
registerFeatures();
|
|
142
|
+
/**
|
|
143
|
+
* P5a — register the OFF-BY-DEFAULT features, which are lazy-imported.
|
|
144
|
+
*
|
|
145
|
+
* Only reached for a name the host explicitly enabled: all five default to `false`, so the common
|
|
146
|
+
* page never issues any of these imports and never pays for them. That is the whole point — their
|
|
147
|
+
* shells used to sit in the eager core on every page load whether or not the site used them
|
|
148
|
+
* (measured: 1,383 B gzipped).
|
|
149
|
+
*
|
|
150
|
+
* Awaited inside `activate()` BEFORE `setupAll`, so an enabled feature is registered and set up in
|
|
151
|
+
* exactly the same order an eager one would be, and the setup-before-`pipeline.start` contract that
|
|
152
|
+
* F-VIT depends on is untouched.
|
|
153
|
+
*
|
|
154
|
+
* `Promise.all`, not sequential: two opted-in features are independent, and serialising their
|
|
155
|
+
* imports would put a second round trip in front of session start for no reason.
|
|
156
|
+
*
|
|
157
|
+
* A failed import must not stop the others or abort activation — a feature that cannot load is a
|
|
158
|
+
* missing feature, not a broken SDK. `FeatureRegistry.setupAll` already reports per-feature setup
|
|
159
|
+
* failures; this reports the earlier, rarer case where the chunk itself never arrives.
|
|
160
|
+
*/
|
|
161
|
+
const registerOptional = async () => {
|
|
162
|
+
await Promise.all(Object.entries(OPTIONAL_FEATURES).map(async ([name, load]) => {
|
|
163
|
+
if (enabled[name] !== true)
|
|
164
|
+
return;
|
|
165
|
+
if (!featureRequirements(name).every((cap) => can(cap)))
|
|
166
|
+
return;
|
|
167
|
+
if (registry.get(name))
|
|
168
|
+
return; // idempotent, like registerFeatures()
|
|
169
|
+
try {
|
|
170
|
+
registry.add(await load());
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
log(`[scalebun] optional feature "${name}" failed to load:`, err);
|
|
174
|
+
}
|
|
175
|
+
}));
|
|
176
|
+
};
|
|
142
177
|
// Consent-mode (F-CNS): when consent is required and not yet granted, DEFER activation — no
|
|
143
178
|
// feature setup (no observers installed) and no pipeline start (no session opened, no flush).
|
|
144
179
|
// Capture begins only on the first grant. Default (not required) → activate immediately.
|
|
@@ -149,6 +184,7 @@ export class SDKBootstrapper {
|
|
|
149
184
|
return;
|
|
150
185
|
activated = true;
|
|
151
186
|
registerFeatures(); // re-register after a prior deny teardownAll() cleared the registry
|
|
187
|
+
await registerOptional(); // P5a — opted-in lazy features, before setup so ordering is unchanged
|
|
152
188
|
// Order matters: setupAll BEFORE pipeline.start (F-VIT relies on it — see its header).
|
|
153
189
|
await registry.setupAll(ctx);
|
|
154
190
|
// Edge-lite: skip the session-lane pipeline (no startSession fetch, no flush timer, no DOM
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SDKBootstrapper.js","sourceRoot":"","sources":["../../src/bootstrap/SDKBootstrapper.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,aAAa,EAAuB,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,EAAE,gBAAgB,EAAsB,MAAM,SAAS,CAAC;AACnM,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"SDKBootstrapper.js","sourceRoot":"","sources":["../../src/bootstrap/SDKBootstrapper.ts"],"names":[],"mappings":"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"}
|
package/dist/browser.d.ts
CHANGED
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
* var s=d.createElement('script');s.async=true;
|
|
20
20
|
* s.src='https://cdn.jsdelivr.net/npm/@scalebun/web@1/dist/scalebun.min.js';
|
|
21
21
|
* d.head.appendChild(s);}(window,document);
|
|
22
|
-
* ScaleBun.init({clientKey:'…'
|
|
22
|
+
* ScaleBun.init({clientKey:'…'});
|
|
23
23
|
* </script>
|
|
24
24
|
* On load we replace the stub, replay `ScaleBun.q` in order — no race, no lost calls.
|
|
25
25
|
*
|
|
26
26
|
* 2. DECLARATIVE TAG (CSP-clean, zero inline JS) — config via data-* on the tag itself:
|
|
27
|
-
* <script async src="…/scalebun.min.js" data-client-key="…"
|
|
27
|
+
* <script async src="…/scalebun.min.js" data-client-key="…"></script>
|
|
28
28
|
* We read the loading script's dataset and auto-init.
|
|
29
29
|
*/
|
|
30
30
|
import { ScaleBun } from './public/ScaleBunFacade.js';
|
package/dist/browser.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,iFAAiF;AACjF,UAAU,YAAY;IACpB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;CAChC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,QAAQ,CAAC,EAAE,OAAO,QAAQ,GAAG,YAAY,CAAC;KAC3C;CACF;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,QAAQ,GAAG,YAAY,CAAA;CAAE,EAClD,aAAa,EAAE;IAAE,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,GAC/C,IAAI,
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,iFAAiF;AACjF,UAAU,YAAY;IACpB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;CAChC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,QAAQ,CAAC,EAAE,OAAO,QAAQ,GAAG,YAAY,CAAC;KAC3C;CACF;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,QAAQ,GAAG,YAAY,CAAA;CAAE,EAClD,aAAa,EAAE;IAAE,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,GAAG,IAAI,GAC/C,IAAI,CAqCN;AAaD,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/browser.js
CHANGED
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
* var s=d.createElement('script');s.async=true;
|
|
20
20
|
* s.src='https://cdn.jsdelivr.net/npm/@scalebun/web@1/dist/scalebun.min.js';
|
|
21
21
|
* d.head.appendChild(s);}(window,document);
|
|
22
|
-
* ScaleBun.init({clientKey:'…'
|
|
22
|
+
* ScaleBun.init({clientKey:'…'});
|
|
23
23
|
* </script>
|
|
24
24
|
* On load we replace the stub, replay `ScaleBun.q` in order — no race, no lost calls.
|
|
25
25
|
*
|
|
26
26
|
* 2. DECLARATIVE TAG (CSP-clean, zero inline JS) — config via data-* on the tag itself:
|
|
27
|
-
* <script async src="…/scalebun.min.js" data-client-key="…"
|
|
27
|
+
* <script async src="…/scalebun.min.js" data-client-key="…"></script>
|
|
28
28
|
* We read the loading script's dataset and auto-init.
|
|
29
29
|
*/
|
|
30
30
|
import { ScaleBun } from './public/ScaleBunFacade.js';
|
|
@@ -59,7 +59,10 @@ export function installBrowserGlobal(win, currentScript) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
// (2) Declarative auto-init (skipped if init already came through the queue). Only clientKey is
|
|
62
|
-
// required
|
|
62
|
+
// required. `data-api-base-url` is forwarded VERBATIM — the lock lives in resolveConfig, the one
|
|
63
|
+
// enforcement point: a remote value is discarded there in favour of the cloud endpoint, while a
|
|
64
|
+
// loopback value is honoured for local development. Duplicating the lock here would just hide
|
|
65
|
+
// the loopback path from script-tag installs without adding any protection.
|
|
63
66
|
const ds = currentScript?.dataset;
|
|
64
67
|
if (!queuedInit && ds?.clientKey) {
|
|
65
68
|
const cfg = { clientKey: ds.clientKey };
|
package/dist/browser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAelC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAkD,EAClD,aAAgD;IAEhD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAoC,CAAC;IAC1D,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAExB,2EAA2E;IAC3E,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;YAC7B,IAAI,MAAM,KAAK,MAAM;gBAAE,UAAU,GAAG,IAAI,CAAC;YACzC,MAAM,EAAE,GAAI,QAA+C,CAAC,MAAM,CAAC,CAAC;YACpE,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,sFAAsF;gBACtF,mFAAmF;gBACnF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,IAAI,CAAC;oBACF,EAAmC,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC;oBACP,gEAAgE;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,gGAAgG;IAChG,
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAelC;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAkD,EAClD,aAAgD;IAEhD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAoC,CAAC;IAC1D,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAExB,2EAA2E;IAC3E,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1C,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;YAC7B,IAAI,MAAM,KAAK,MAAM;gBAAE,UAAU,GAAG,IAAI,CAAC;YACzC,MAAM,EAAE,GAAI,QAA+C,CAAC,MAAM,CAAC,CAAC;YACpE,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC7B,sFAAsF;gBACtF,mFAAmF;gBACnF,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC1D,IAAI,CAAC;oBACF,EAAmC,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC7D,CAAC;gBAAC,MAAM,CAAC;oBACP,gEAAgE;gBAClE,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,gGAAgG;IAChG,iGAAiG;IACjG,gGAAgG;IAChG,8FAA8F;IAC9F,4EAA4E;IAC5E,MAAM,EAAE,GAAG,aAAa,EAAE,OAAO,CAAC;IAClC,IAAI,CAAC,UAAU,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC;QACjC,MAAM,GAAG,GAAe,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC;QACpD,IAAI,EAAE,CAAC,UAAU;YAAE,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC;QAClD,IAAI,EAAE,CAAC,WAAW;YAAE,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,CAAC;QACrD,IAAI,EAAE,CAAC,WAAW,IAAI,IAAI;YAAE,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,KAAK,OAAO,CAAC;QACzE,KAAK,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;IAClC,MAAM,aAAa,GAAG,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;IACtF,+FAA+F;IAC/F,mGAAmG;IACnG,QAAQ,CAAE,aAA2C,EAAE,KAAK,CAAC,CAAC;IAC9D,oBAAoB,CAClB,MAAkE,EAClE,aAAkD,CACnD,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,QAAQ,IAAI,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
package/dist/config/schema.d.ts
CHANGED
|
@@ -72,11 +72,11 @@ export interface ResolvedConfig {
|
|
|
72
72
|
captureNetworkBodies: boolean;
|
|
73
73
|
denylist: string[];
|
|
74
74
|
maskSelectors: string[];
|
|
75
|
-
/** Mask all replay text. Default
|
|
76
|
-
*
|
|
75
|
+
/** Mask all replay text. Default TRUE (privacy-first — PII protected out of the box); set
|
|
76
|
+
* false to capture visible text. Form input values have their own flag (maskInputs). */
|
|
77
77
|
maskReplayText: boolean;
|
|
78
78
|
/** Mask form input values in replay. Defaults to FOLLOW maskReplayText (one flag governs text +
|
|
79
|
-
* inputs). Set explicitly to decouple. Passwords
|
|
79
|
+
* inputs, so masked by default). Set explicitly to decouple. Passwords always blanked. */
|
|
80
80
|
maskInputs: boolean;
|
|
81
81
|
/** Honor GPC / Do-Not-Track by not recording replay for opted-out users. Default false. */
|
|
82
82
|
respectDnt: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;iCAC6B;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;oGACgG;IAChG,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,2FAA2F;IAC3F,YAAY,EAAE,OAAO,CAAC;IACtB;uGACmG;IACnG,eAAe,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,+FAA+F;IAC/F,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,mGAAmG;IACnG,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,2GAA2G;IAC3G,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC/C,yFAAyF;IACzF,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC3C,uFAAuF;IACvF,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACnC,wFAAwF;IACxF,WAAW,EAAE,OAAO,CAAC;IACrB,qGAAqG;IACrG,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mGAAmG;IACnG,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,OAAO,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,2FAA2F;IAC3F,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACzC;kGAC8F;IAC9F,UAAU,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC7C,OAAO,EAAE;QACP,oBAAoB,EAAE,OAAO,CAAC;QAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;iCAC6B;IAC7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;oGACgG;IAChG,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,2FAA2F;IAC3F,YAAY,EAAE,OAAO,CAAC;IACtB;uGACmG;IACnG,eAAe,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,+FAA+F;IAC/F,MAAM,EAAE,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACrC,mGAAmG;IACnG,OAAO,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACvC,2GAA2G;IAC3G,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAC/C,yFAAyF;IACzF,SAAS,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;IAC3C,uFAAuF;IACvF,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACnC,wFAAwF;IACxF,WAAW,EAAE,OAAO,CAAC;IACrB,qGAAqG;IACrG,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mGAAmG;IACnG,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,OAAO,CAAC;QACnB,WAAW,EAAE,OAAO,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;QACf,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,2FAA2F;IAC3F,QAAQ,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACzC;kGAC8F;IAC9F,UAAU,EAAE,kBAAkB,CAAC,YAAY,CAAC,CAAC;IAC7C,OAAO,EAAE;QACP,oBAAoB,EAAE,OAAO,CAAC;QAC9B,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB;iGACyF;QACzF,cAAc,EAAE,OAAO,CAAC;QACxB;mGAC2F;QAC3F,UAAU,EAAE,OAAO,CAAC;QACpB,2FAA2F;QAC3F,UAAU,EAAE,OAAO,CAAC;QACpB;;8DAEsD;QACtD,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IACF,OAAO,EAAE;QACP,yEAAyE;QACzE,QAAQ,EAAE,OAAO,CAAC;QAClB,mEAAmE;QACnE,OAAO,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;KAC3C,CAAC;IACF,SAAS,EAAE;QACT,0CAA0C;QAC1C,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,EAAE,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAC;QACpE,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7D;AAcD,wBAAgB,aAAa,CAAC,GAAG,EAAE,kBAAkB,GAAG,cAAc,CAkGrE"}
|
package/dist/config/schema.js
CHANGED
|
@@ -17,9 +17,19 @@ const DEFAULT_DENYLIST = [
|
|
|
17
17
|
export function resolveConfig(cfg) {
|
|
18
18
|
if (!cfg || !cfg.clientKey)
|
|
19
19
|
throw new Error('[scalebun] clientKey is required');
|
|
20
|
-
// apiBaseUrl is
|
|
21
|
-
//
|
|
22
|
-
|
|
20
|
+
// apiBaseUrl is LOCKED to the ScaleBun cloud endpoint — a REMOTE value passed in
|
|
21
|
+
// `cfg.apiBaseUrl` is deliberately ignored so integrators cannot repoint the SDK.
|
|
22
|
+
// The single exception is LOOPBACK (localhost / 127.0.0.1; IPv6 [::1] deliberately
|
|
23
|
+
// omitted — the core size gate is byte-tight and no test or dev flow uses it):
|
|
24
|
+
// local mock servers are how the SDK's own integration tests and local development
|
|
25
|
+
// drive the full egress path, and a loopback target cannot repoint anyone's
|
|
26
|
+
// production data anywhere. To target a different real backend, change
|
|
27
|
+
// DEFAULT_API_BASE_URL at build time (keep it slash-free: it is used verbatim; a
|
|
28
|
+
// supplied loopback URL gets its trailing slash trimmed).
|
|
29
|
+
const supplied = cfg.apiBaseUrl?.replace(/\/$/, '');
|
|
30
|
+
const apiBaseUrl = supplied && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?([/?#]|$)/.test(supplied)
|
|
31
|
+
? supplied
|
|
32
|
+
: DEFAULT_API_BASE_URL;
|
|
23
33
|
return {
|
|
24
34
|
clientKey: cfg.clientKey,
|
|
25
35
|
apiBaseUrl,
|
|
@@ -69,10 +79,13 @@ export function resolveConfig(cfg) {
|
|
|
69
79
|
captureNetworkBodies: cfg.privacy?.captureNetworkBodies ?? false,
|
|
70
80
|
denylist: [...DEFAULT_DENYLIST, ...(cfg.privacy?.denylist ?? [])].map((s) => s.toLowerCase()),
|
|
71
81
|
maskSelectors: cfg.privacy?.maskSelectors ?? [],
|
|
72
|
-
|
|
82
|
+
// Privacy-first default: replay text is MASKED unless the integrator explicitly opts out
|
|
83
|
+
// (maskReplayText: false). Protects PII in replays out of the box.
|
|
84
|
+
maskReplayText: cfg.privacy?.maskReplayText ?? true,
|
|
73
85
|
// Input masking FOLLOWS maskReplayText by default — one flag governs everything (text + inputs).
|
|
74
|
-
// Can be set explicitly to decouple. Passwords are ALWAYS blanked regardless.
|
|
75
|
-
|
|
86
|
+
// Can be set explicitly to decouple. Passwords are ALWAYS blanked regardless. Defaults to
|
|
87
|
+
// masked (true) in line with the privacy-first maskReplayText default above.
|
|
88
|
+
maskInputs: cfg.privacy?.maskInputs ?? cfg.privacy?.maskReplayText ?? true,
|
|
76
89
|
respectDnt: cfg.privacy?.respectDnt ?? false,
|
|
77
90
|
// Deliberately does NOT follow maskReplayText the way maskInputs does. Replay text and an event
|
|
78
91
|
// label are different exposures: replay is a recording someone opens deliberately, whereas the
|
|
@@ -81,6 +94,12 @@ export function resolveConfig(cfg) {
|
|
|
81
94
|
maskEventText: cfg.privacy?.maskEventText ?? false,
|
|
82
95
|
},
|
|
83
96
|
consent: {
|
|
97
|
+
// Consent mode is OPT-IN (requireConsent: true), not the default. A required-by-default
|
|
98
|
+
// gate silently stops ALL capture (sessions, replay, analytics) for every existing
|
|
99
|
+
// integrator the moment they upgrade, until they discover setConsent(true) — dashboards go
|
|
100
|
+
// dark with no error anywhere. The "default activates immediately — no regression" test
|
|
101
|
+
// pins this contract. Privacy-first defaults live in masking (maskReplayText/maskInputs
|
|
102
|
+
// default true), which protects PII without turning capture off.
|
|
84
103
|
required: cfg.requireConsent ?? false,
|
|
85
104
|
initial: cfg.initialConsent ?? 'unknown',
|
|
86
105
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAwGnD,mFAAmF;AACnF,MAAM,gBAAgB,GAAG;IACvB,eAAe;IACf,QAAQ;IACR,YAAY;IACZ,WAAW;IACX,cAAc;IACd,UAAU;IACV,OAAO;IACP,QAAQ;CACT,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAChF,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/config/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/core/pageContext.js
CHANGED
|
@@ -44,7 +44,23 @@ export function buildContext() {
|
|
|
44
44
|
function parseUserAgent(ua) {
|
|
45
45
|
const browser = {};
|
|
46
46
|
const os = {};
|
|
47
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Chromium FORKS FIRST, in their own pass.
|
|
49
|
+
*
|
|
50
|
+
* Alternation only decides between branches at the SAME position — `exec` returns the leftmost
|
|
51
|
+
* match in the string. Edge and Opera both append their token AFTER Chrome's:
|
|
52
|
+
*
|
|
53
|
+
* … Chrome/120.0.0.0 Safari/537.36 Edg/120.0.2210.91
|
|
54
|
+
*
|
|
55
|
+
* so a single `(Edg|OPR|Chrome|…)` pattern matched `Chrome/` every time and the Edg→Edge mapping
|
|
56
|
+
* below was unreachable dead code. Every Edge and Opera visitor was recorded as Chrome. Two passes
|
|
57
|
+
* is the fix: ask for a fork, fall back to the base engines.
|
|
58
|
+
*
|
|
59
|
+
* Brave still reports Chrome, and that is correct — it ships a byte-identical UA deliberately.
|
|
60
|
+
* The backend's deviceLabel and the dashboard's security page already test `Edg/` separately,
|
|
61
|
+
* which is why login sessions named Edge correctly while SDK-captured sessions did not.
|
|
62
|
+
*/
|
|
63
|
+
const b = /(Edg|OPR)\/([\d.]+)/.exec(ua) ?? /(Chrome|Firefox|Safari)\/([\d.]+)/.exec(ua);
|
|
48
64
|
if (b && b[1]) {
|
|
49
65
|
browser.name = { Edg: 'Edge', OPR: 'Opera' }[b[1]] ?? b[1];
|
|
50
66
|
browser.version = b[2]?.split('.')[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pageContext.js","sourceRoot":"","sources":["../../src/core/pageContext.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,CAAC,MAAM,QAAQ,GAAG,eAAe,CAAC;AACxC,MAAM,CAAC,MAAM,WAAW,GAAW,OAAO,oBAAoB,KAAK,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC;AAEhH,MAAM,UAAU,WAAW;IACzB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;AAC7F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,EAAE,GAAG,OAAO,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IAC3C,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,OAAO,EAAE,OAAO,CAAC,IAAI;QACrB,cAAc,EAAE,OAAO,CAAC,OAAO;QAC/B,EAAE,EAAE,EAAE,CAAC,IAAI;QACX,SAAS,EAAE,EAAE,CAAC,OAAO;KACtB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAsB;IAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;AAClG,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,GAAG,GAAgB,EAAE,CAAC;IAC5B,IAAI,CAAC;QACH,IAAI,OAAO,SAAS,KAAK,WAAW;YAAE,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC;QACtE,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAC;QAChE,IAAI,OAAO,QAAQ,KAAK,WAAW;YAAE,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC7D,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,GAAG,CAAC,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,WAAW,EAAE,CAAC;QAC3G,MAAM,IAAI,GAAI,SAAoE,EAAE,UAAU,CAAC;QAC/F,IAAI,IAAI,EAAE,aAAa;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,mFAAmF;AACnF,SAAS,cAAc,CAAC,EAAU;IAIhC,MAAM,OAAO,GAAwC,EAAE,CAAC;IACxD,MAAM,EAAE,GAAwC,EAAE,CAAC;IAEnD,MAAM,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"pageContext.js","sourceRoot":"","sources":["../../src/core/pageContext.ts"],"names":[],"mappings":"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"}
|
package/dist/core/prune.d.ts
CHANGED
|
@@ -1,7 +1,31 @@
|
|
|
1
|
+
/** The persisted-buffer budget. Exported so producers can size their own buffers against the budget
|
|
2
|
+
* their data has to survive, instead of guessing — see `MAX_BUFFER_BYTES` in the replay recorder,
|
|
3
|
+
* which was 3MB against this 2MB and so could never be persisted whole. */
|
|
4
|
+
export declare const PERSIST_MAX_BYTES = 2000000;
|
|
1
5
|
/** Keep only items younger than the max age (by getTime). Items with no timestamp are kept. */
|
|
2
6
|
export declare function freshOnly<T>(items: T[], getTime: (it: T) => number | undefined, nowMs: number): T[];
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Trim a queue to the persisted-byte budget.
|
|
9
|
+
*
|
|
10
|
+
* Sheds the OLDEST heavy (replay-frame) items until it fits, so what survives is the most recent
|
|
11
|
+
* replay plus every light item. Light telemetry is never traded for a frame: events, perf and
|
|
12
|
+
* network entries are two orders of magnitude smaller, so dropping them to keep a keyframe is a
|
|
13
|
+
* bad exchange in both directions.
|
|
14
|
+
*
|
|
15
|
+
* WHY THIS IS NOT `filter(not heavy)`:
|
|
16
|
+
* it used to be. One byte over budget removed EVERY frame in a single pass — keyframe included —
|
|
17
|
+
* while events/perf/network sailed through. That is precisely the failure signature measured on a
|
|
18
|
+
* live app: 44 of 164 sessions arrived complete in every other lane with not one frame stored
|
|
19
|
+
* (`npm run replay:diagnose`, the `missing` state). Its keyframes average 109 kB and reach 1.17 MB,
|
|
20
|
+
* and `persistQueue()` runs on every pagehide AND every failed flush, so a single transient 500
|
|
21
|
+
* mid-session was enough to discard a whole session's replay.
|
|
22
|
+
*
|
|
23
|
+
* `isBase` marks a keyframe. A delta whose keyframe was shed reconstructs nothing, so it goes too —
|
|
24
|
+
* storing it would only convert a `missing` session into an `orphaned` one, which is no better and
|
|
25
|
+
* costs bytes to find out.
|
|
26
|
+
*
|
|
27
|
+
* Always returns a fresh array (a synchronous snapshot) so the async IDB write can't capture a
|
|
28
|
+
* reference that a concurrent flush() splices out from under it (pagehide save-vs-flush race).
|
|
29
|
+
*/
|
|
30
|
+
export declare function capBytes<T>(items: T[], isHeavy?: (it: T) => boolean, isBase?: (it: T) => boolean): T[];
|
|
7
31
|
//# sourceMappingURL=prune.d.ts.map
|
package/dist/core/prune.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/core/prune.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"prune.d.ts","sourceRoot":"","sources":["../../src/core/prune.ts"],"names":[],"mappings":"AAWA;;4EAE4E;AAC5E,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAO3C,+FAA+F;AAC/F,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,EAAE,CAKnG;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,OAAO,GAAG,CAAC,EAAE,CAuDtG"}
|
package/dist/core/prune.js
CHANGED
|
@@ -8,8 +8,14 @@
|
|
|
8
8
|
* oldest) so a few large frames can't blow the IndexedDB quota.
|
|
9
9
|
*/
|
|
10
10
|
const MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24h
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
/** The persisted-buffer budget. Exported so producers can size their own buffers against the budget
|
|
12
|
+
* their data has to survive, instead of guessing — see `MAX_BUFFER_BYTES` in the replay recorder,
|
|
13
|
+
* which was 3MB against this 2MB and so could never be persisted whole. */
|
|
14
|
+
export const PERSIST_MAX_BYTES = 2000000; // ~2MB — well under typical IndexedDB quotas
|
|
15
|
+
/** Per-item cost, +1 for the separating comma. Summed once instead of re-stringifying the whole
|
|
16
|
+
* array per drop: the old shed loop was O(n) full stringifies, which on a 1000-item queue holding
|
|
17
|
+
* MB-scale keyframes is real main-thread time — spent on `pagehide`, of all moments. */
|
|
18
|
+
const itemSize = (it) => JSON.stringify(it).length + 1;
|
|
13
19
|
/** Keep only items younger than the max age (by getTime). Items with no timestamp are kept. */
|
|
14
20
|
export function freshOnly(items, getTime, nowMs) {
|
|
15
21
|
return items.filter((it) => {
|
|
@@ -17,15 +23,90 @@ export function freshOnly(items, getTime, nowMs) {
|
|
|
17
23
|
return t == null || nowMs - t <= MAX_AGE_MS;
|
|
18
24
|
});
|
|
19
25
|
}
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Trim a queue to the persisted-byte budget.
|
|
28
|
+
*
|
|
29
|
+
* Sheds the OLDEST heavy (replay-frame) items until it fits, so what survives is the most recent
|
|
30
|
+
* replay plus every light item. Light telemetry is never traded for a frame: events, perf and
|
|
31
|
+
* network entries are two orders of magnitude smaller, so dropping them to keep a keyframe is a
|
|
32
|
+
* bad exchange in both directions.
|
|
33
|
+
*
|
|
34
|
+
* WHY THIS IS NOT `filter(not heavy)`:
|
|
35
|
+
* it used to be. One byte over budget removed EVERY frame in a single pass — keyframe included —
|
|
36
|
+
* while events/perf/network sailed through. That is precisely the failure signature measured on a
|
|
37
|
+
* live app: 44 of 164 sessions arrived complete in every other lane with not one frame stored
|
|
38
|
+
* (`npm run replay:diagnose`, the `missing` state). Its keyframes average 109 kB and reach 1.17 MB,
|
|
39
|
+
* and `persistQueue()` runs on every pagehide AND every failed flush, so a single transient 500
|
|
40
|
+
* mid-session was enough to discard a whole session's replay.
|
|
41
|
+
*
|
|
42
|
+
* `isBase` marks a keyframe. A delta whose keyframe was shed reconstructs nothing, so it goes too —
|
|
43
|
+
* storing it would only convert a `missing` session into an `orphaned` one, which is no better and
|
|
44
|
+
* costs bytes to find out.
|
|
45
|
+
*
|
|
46
|
+
* Always returns a fresh array (a synchronous snapshot) so the async IDB write can't capture a
|
|
47
|
+
* reference that a concurrent flush() splices out from under it (pagehide save-vs-flush race).
|
|
48
|
+
*/
|
|
49
|
+
export function capBytes(items, isHeavy, isBase) {
|
|
50
|
+
const rows = items.map((it) => ({ it, n: itemSize(it), gone: false }));
|
|
51
|
+
let total = rows.reduce((a, r) => a + r.n, 0);
|
|
52
|
+
if (total <= PERSIST_MAX_BYTES)
|
|
25
53
|
return items.slice();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
54
|
+
// Oldest-first over whatever `pick` selects, stopping the moment the budget is met.
|
|
55
|
+
const shed = (pick) => {
|
|
56
|
+
for (const r of rows) {
|
|
57
|
+
if (total <= PERSIST_MAX_BYTES)
|
|
58
|
+
return;
|
|
59
|
+
if (r.gone || !pick(r.it))
|
|
60
|
+
continue;
|
|
61
|
+
r.gone = true;
|
|
62
|
+
total -= r.n;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Pass 1 — frames, oldest first, BUT never the last surviving keyframe.
|
|
67
|
+
*
|
|
68
|
+
* Oldest-first alone is right whenever two segments exist: dropping the older base (and, via pass 3,
|
|
69
|
+
* its orphaned deltas) leaves a recent replay that still has motion, which beats keeping two static
|
|
70
|
+
* snapshots. That policy is preserved exactly.
|
|
71
|
+
*
|
|
72
|
+
* It breaks on the SINGLE-segment case. Early in a session there is one keyframe with deltas behind
|
|
73
|
+
* it; oldest-first sheds the base first, pass 3 then correctly drops the orphaned deltas, and the
|
|
74
|
+
* whole replay is gone — where shedding the deltas would have left a playable single-frame replay.
|
|
75
|
+
* That is the early/short session that dominates the `missing` bucket, and `persistQueue()` runs on
|
|
76
|
+
* every pagehide and every failed flush, so a visitor simply leaving is enough to reach it.
|
|
77
|
+
*
|
|
78
|
+
* The guard is "more than one keyframe left", not "is this the first": after the older bases have
|
|
79
|
+
* gone the survivor becomes protected in turn, so the rule needs no lookahead and cannot strand a
|
|
80
|
+
* session with deltas and no base.
|
|
81
|
+
*/
|
|
82
|
+
if (isHeavy && isBase) {
|
|
83
|
+
let basesLeft = rows.reduce((n, r) => n + (isBase(r.it) ? 1 : 0), 0);
|
|
84
|
+
for (const r of rows) {
|
|
85
|
+
if (total <= PERSIST_MAX_BYTES)
|
|
86
|
+
break;
|
|
87
|
+
if (r.gone || !isHeavy(r.it))
|
|
88
|
+
continue;
|
|
89
|
+
const isTheBase = isBase(r.it);
|
|
90
|
+
if (isTheBase && basesLeft <= 1)
|
|
91
|
+
continue; // the last thing that makes any of this playable
|
|
92
|
+
r.gone = true;
|
|
93
|
+
total -= r.n;
|
|
94
|
+
if (isTheBase)
|
|
95
|
+
basesLeft--;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (isHeavy) {
|
|
99
|
+
shed(isHeavy); // no base predicate — nothing to protect, old behaviour
|
|
100
|
+
}
|
|
101
|
+
// Pass 2 — light items alone still over budget, or a lone keyframe that cannot fit on its own. This
|
|
102
|
+
// is the genuine last resort and may take the protected base with it; at that point there is no
|
|
103
|
+
// playable replay to save either way.
|
|
104
|
+
shed(() => true);
|
|
105
|
+
const kept = rows.filter((r) => !r.gone).map((r) => r.it);
|
|
106
|
+
if (!isHeavy || !isBase)
|
|
107
|
+
return kept;
|
|
108
|
+
// Pass 3 — drop deltas left with no keyframe ahead of them.
|
|
109
|
+
let based = false;
|
|
110
|
+
return kept.filter((it) => (!isHeavy(it) ? true : isBase(it) ? ((based = true), true) : based));
|
|
30
111
|
}
|
|
31
112
|
//# sourceMappingURL=prune.js.map
|
package/dist/core/prune.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/core/prune.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"prune.js","sourceRoot":"","sources":["../../src/core/prune.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,15 +6,16 @@
|
|
|
6
6
|
* The actual HTTP submit is orchestrated by the facade (which holds session + transport + registry).
|
|
7
7
|
*/
|
|
8
8
|
import type { IFeature, FeatureContext } from '@scalebun/sdk-contracts';
|
|
9
|
-
import type { WidgetPosition } from './widget.js';
|
|
9
|
+
import type { SubmitResult, WidgetPosition } from './widget.js';
|
|
10
10
|
export interface LauncherOptions {
|
|
11
11
|
position: WidgetPosition;
|
|
12
12
|
label: string;
|
|
13
13
|
}
|
|
14
|
+
/** Resolves to the report id, or to `{ id, reason }` naming which branch of the submit path failed. */
|
|
14
15
|
type SubmitFn = (input: {
|
|
15
16
|
message: string;
|
|
16
17
|
email?: string;
|
|
17
|
-
}) => Promise<
|
|
18
|
+
}) => Promise<SubmitResult>;
|
|
18
19
|
export declare class BugReportFeature implements IFeature {
|
|
19
20
|
readonly name = "bugReport";
|
|
20
21
|
private ctx;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BugReportFeature.d.ts","sourceRoot":"","sources":["../../../src/features/bugreport/BugReportFeature.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"BugReportFeature.d.ts","sourceRoot":"","sources":["../../../src/features/bugreport/BugReportFeature.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAgB,cAAc,EAAE,MAAM,UAAU,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uGAAuG;AACvG,KAAK,QAAQ,GAAG,CAAC,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAEtF,qBAAa,gBAAiB,YAAW,QAAQ;IAC/C,QAAQ,CAAC,IAAI,eAAe;IAC5B,OAAO,CAAC,GAAG,CAA+B;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,QAAQ,CAAS;IAEzB,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,KAAK,CAAC,GAAG,EAAE,cAAc,GAAG,IAAI;IAKhC,8FAA8F;IAC9F,YAAY,IAAI,IAAI;IAIpB,6FAA6F;IAC7F,SAAS,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI;IAI7B,+FAA+F;IACzF,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzD,QAAQ,IAAI,IAAI;CAMjB"}
|
|
@@ -35,7 +35,8 @@ export class BugReportFeature {
|
|
|
35
35
|
this.widget = createBugReportWidget({
|
|
36
36
|
position: opts.position,
|
|
37
37
|
label: opts.label,
|
|
38
|
-
|
|
38
|
+
// No submitFn means the facade never finished wiring — that is 'init', not a send failure.
|
|
39
|
+
onSubmit: (input) => this.submitFn ? this.submitFn(input) : Promise.resolve({ e: 'init' }),
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
42
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BugReportFeature.js","sourceRoot":"","sources":["../../../src/features/bugreport/BugReportFeature.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BugReportFeature.js","sourceRoot":"","sources":["../../../src/features/bugreport/BugReportFeature.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,gBAAgB;IAA7B;QACW,SAAI,GAAG,WAAW,CAAC;QACpB,QAAG,GAA0B,IAAI,CAAC;QAClC,WAAM,GAAG,KAAK,CAAC;QACf,aAAQ,GAAoB,IAAI,CAAC;QACjC,WAAM,GAAwB,IAAI,CAAC;QACnC,aAAQ,GAAG,KAAK,CAAC,CAAC,yEAAyE;IAiDrG,CAAC;IA/CC,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,GAAmB;QACvB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,8FAA8F;IAC9F,YAAY;QACV,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,6FAA6F;IAC7F,SAAS,CAAC,EAAY;QACpB,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACrB,CAAC;IAED,+FAA+F;IAC/F,KAAK,CAAC,aAAa,CAAC,IAAqB;QACvC,0FAA0F;QAC1F,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,WAAW;YAAE,OAAO;QAC5E,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,EAAE,qBAAqB,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;YAC3D,IAAI,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,+BAA+B;YACxD,IAAI,CAAC,MAAM,GAAG,qBAAqB,CAAC;gBAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,2FAA2F;gBAC3F,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAClB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAe,EAAE,CAAC;aACjF,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;QAC5E,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;CACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ReplayCoord } from '../../core/replayCoord.js';
|
|
1
2
|
export interface BugReportInput {
|
|
2
3
|
/** Required free-text from the reporter. */
|
|
3
4
|
message: string;
|
|
@@ -14,8 +15,19 @@ export interface BugReportPayload {
|
|
|
14
15
|
url?: string;
|
|
15
16
|
/** Recent console breadcrumbs (already scrubbed log items) for quick triage; full set is in-session. */
|
|
16
17
|
console?: unknown[];
|
|
18
|
+
/** Last replay frame known when the reporter pressed Send. Absent means no exact frame was captured. */
|
|
19
|
+
replaySeq?: number;
|
|
20
|
+
/** The keyframe segment containing `replaySeq`, when the recorder has one. */
|
|
21
|
+
replaySegmentId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Client wall-clock time when the report was created. Kept as `timestamp` for wire compatibility;
|
|
24
|
+
* the ingestion API persists it as `reportedAt`, distinct from server-side `createdAt`.
|
|
25
|
+
*/
|
|
17
26
|
timestamp: number;
|
|
18
27
|
}
|
|
28
|
+
export interface BugReportReplayContext {
|
|
29
|
+
replayCoord?: ReplayCoord;
|
|
30
|
+
}
|
|
19
31
|
/** Build the POST body. `message` is scrubbed for obvious PII; `recentConsole` is capped. */
|
|
20
|
-
export declare function buildBugReportPayload(input: BugReportInput, recentConsole?: readonly unknown[]): BugReportPayload;
|
|
32
|
+
export declare function buildBugReportPayload(input: BugReportInput, recentConsole?: readonly unknown[], replay?: BugReportReplayContext): BugReportPayload;
|
|
21
33
|
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../src/features/bugreport/collect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../../src/features/bugreport/collect.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,wGAAwG;IACxG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAUD,6FAA6F;AAC7F,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,cAAc,EACrB,aAAa,GAAE,SAAS,OAAO,EAAO,EACtC,MAAM,GAAE,sBAA2B,GAClC,gBAAgB,CAalB"}
|
|
@@ -13,7 +13,8 @@ function currentUrl() {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
/** Build the POST body. `message` is scrubbed for obvious PII; `recentConsole` is capped. */
|
|
16
|
-
export function buildBugReportPayload(input, recentConsole = []) {
|
|
16
|
+
export function buildBugReportPayload(input, recentConsole = [], replay = {}) {
|
|
17
|
+
const coord = replay.replayCoord;
|
|
17
18
|
return {
|
|
18
19
|
clientReportId: `bug_${uuid()}`,
|
|
19
20
|
...(input.title ? { title: scrubText(input.title) } : {}),
|
|
@@ -21,6 +22,8 @@ export function buildBugReportPayload(input, recentConsole = []) {
|
|
|
21
22
|
...(input.email ? { email: input.email } : {}),
|
|
22
23
|
url: currentUrl(),
|
|
23
24
|
...(recentConsole.length ? { console: recentConsole.slice(-20) } : {}),
|
|
25
|
+
...(typeof coord?.seq === 'number' ? { replaySeq: coord.seq } : {}),
|
|
26
|
+
...(coord?.segmentId ? { replaySegmentId: coord.segmentId } : {}),
|
|
24
27
|
timestamp: now(),
|
|
25
28
|
};
|
|
26
29
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/features/bugreport/collect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../../src/features/bugreport/collect.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmClD,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,OAAO,OAAO,QAAQ,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,6FAA6F;AAC7F,MAAM,UAAU,qBAAqB,CACnC,KAAqB,EACrB,gBAAoC,EAAE,EACtC,SAAiC,EAAE;IAEnC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;IACjC,OAAO;QACL,cAAc,EAAE,OAAO,IAAI,EAAE,EAAE;QAC/B,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9C,GAAG,EAAE,UAAU,EAAE;QACjB,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,GAAG,CAAC,OAAO,KAAK,EAAE,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,SAAS,EAAE,GAAG,EAAE;KACjB,CAAC;AACJ,CAAC"}
|