@offscript/sdk 0.1.7 → 0.1.8
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/adapters/nuxt.cjs +3 -3
- package/dist/adapters/nuxt.js +2 -2
- package/dist/adapters/vanilla.cjs +5 -5
- package/dist/adapters/vanilla.js +3 -3
- package/dist/adapters/vue.cjs +3 -3
- package/dist/adapters/vue.js +2 -2
- package/dist/{chunk-4EPIPNDL.js → chunk-AQG5MIW5.js} +3 -3
- package/dist/{chunk-4EPIPNDL.js.map → chunk-AQG5MIW5.js.map} +1 -1
- package/dist/{chunk-7FCA5EJI.cjs → chunk-E53R6UOC.cjs} +95 -33
- package/dist/chunk-E53R6UOC.cjs.map +1 -0
- package/dist/{chunk-ZB5N4KJE.js → chunk-IOIVKJTV.js} +3 -3
- package/dist/{chunk-ZB5N4KJE.js.map → chunk-IOIVKJTV.js.map} +1 -1
- package/dist/{chunk-LUTOFXSV.js → chunk-W27UMAEC.js} +90 -28
- package/dist/chunk-W27UMAEC.js.map +1 -0
- package/dist/{chunk-OXGIMYKL.cjs → chunk-YIKWNN5R.cjs} +4 -4
- package/dist/{chunk-OXGIMYKL.cjs.map → chunk-YIKWNN5R.cjs.map} +1 -1
- package/dist/{chunk-M7CHVDW6.cjs → chunk-ZB2LSKD2.cjs} +3 -3
- package/dist/{chunk-M7CHVDW6.cjs.map → chunk-ZB2LSKD2.cjs.map} +1 -1
- package/dist/core/OffscriptSDK.d.ts +16 -2
- package/dist/index.cjs +20 -20
- package/dist/index.js +3 -3
- package/dist/playwright.cjs +13 -13
- package/dist/playwright.js +1 -1
- package/dist/recorders/RRWebRecorder.d.ts +10 -0
- package/dist/types/events.d.ts +1 -1
- package/package.json +1 -1
- package/dist/chunk-7FCA5EJI.cjs.map +0 -1
- package/dist/chunk-LUTOFXSV.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Offscript } from './chunk-
|
|
1
|
+
import { Offscript } from './chunk-W27UMAEC.js';
|
|
2
2
|
|
|
3
3
|
// src/adapters/vanilla.ts
|
|
4
4
|
async function createOffscript(config) {
|
|
@@ -13,5 +13,5 @@ async function startOffscript(config) {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export { createOffscript, startOffscript };
|
|
16
|
-
//# sourceMappingURL=chunk-
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-IOIVKJTV.js.map
|
|
17
|
+
//# sourceMappingURL=chunk-IOIVKJTV.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/vanilla.ts"],"names":[],"mappings":";;;AAIA,eAAsB,gBAAgB,MAAA,EAA6C;AACjF,EAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAChC,EAAA,MAAM,IAAI,IAAA,EAAK;AACf,EAAA,OAAO,GAAA;AACT;AAEA,eAAsB,eAAe,MAAA,EAA6C;AAChF,EAAA,MAAM,GAAA,GAAM,MAAM,eAAA,CAAgB,MAAM,CAAA;AACxC,EAAA,MAAM,IAAI,cAAA,EAAe;AACzB,EAAA,OAAO,GAAA;AACT","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/adapters/vanilla.ts"],"names":[],"mappings":";;;AAIA,eAAsB,gBAAgB,MAAA,EAA6C;AACjF,EAAA,MAAM,GAAA,GAAM,IAAI,SAAA,CAAU,MAAM,CAAA;AAChC,EAAA,MAAM,IAAI,IAAA,EAAK;AACf,EAAA,OAAO,GAAA;AACT;AAEA,eAAsB,eAAe,MAAA,EAA6C;AAChF,EAAA,MAAM,GAAA,GAAM,MAAM,eAAA,CAAgB,MAAM,CAAA;AACxC,EAAA,MAAM,IAAI,cAAA,EAAe;AACzB,EAAA,OAAO,GAAA;AACT","file":"chunk-IOIVKJTV.js","sourcesContent":["import { Offscript } from \"../core/OffscriptSDK\";\nimport type { OffscriptConfig } from \"../types/config\";\n\n/** Atalho para aplicações JS tradicionais, Blade e MPA: inicializa a captura local. */\nexport async function createOffscript(config: OffscriptConfig): Promise<Offscript> {\n const sdk = new Offscript(config);\n await sdk.init();\n return sdk;\n}\n\nexport async function startOffscript(config: OffscriptConfig): Promise<Offscript> {\n const sdk = await createOffscript(config);\n await sdk.startRecording();\n return sdk;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildPlaywrightContract, SDK_VERSION, SelectorGenerator, ACTION_SCHEMA_VERSION } from './chunk-
|
|
1
|
+
import { buildPlaywrightContract, SDK_VERSION, SelectorGenerator, ACTION_SCHEMA_VERSION } from './chunk-AQG5MIW5.js';
|
|
2
2
|
|
|
3
3
|
// src/types/config.ts
|
|
4
4
|
var DEFAULT_RECORDING = {
|
|
@@ -1253,6 +1253,8 @@ var IframeRecorder = class {
|
|
|
1253
1253
|
var PRIORITY = { 2: "critical", 4: "critical", 5: "critical", 0: "normal", 1: "normal", 3: "normal", 6: "normal" };
|
|
1254
1254
|
var URL_ATTRS = ["src", "href", "action", "poster", "data-src", "data", "formaction", "srcset", "cite", "rr_src"];
|
|
1255
1255
|
var LOW_SOURCES = /* @__PURE__ */ new Set([1, 6, 12, 3]);
|
|
1256
|
+
var SNAPSHOT_DEBOUNCE_MS = 200;
|
|
1257
|
+
var SNAPSHOT_SETTLE_TIMEOUT_MS = 5e3;
|
|
1256
1258
|
var RRWebRecorder = class {
|
|
1257
1259
|
constructor(sink) {
|
|
1258
1260
|
this.sink = sink;
|
|
@@ -1261,6 +1263,7 @@ var RRWebRecorder = class {
|
|
|
1261
1263
|
this.stopped = true;
|
|
1262
1264
|
this.needsSnapshot = false;
|
|
1263
1265
|
this.snapshotsTaken = 0;
|
|
1266
|
+
this.settling = false;
|
|
1264
1267
|
}
|
|
1265
1268
|
async start() {
|
|
1266
1269
|
this.stopped = false;
|
|
@@ -1292,6 +1295,64 @@ var RRWebRecorder = class {
|
|
|
1292
1295
|
// erros internos do rrweb não propagam
|
|
1293
1296
|
};
|
|
1294
1297
|
this.stopFn = mod.record(options) ?? void 0;
|
|
1298
|
+
this.scheduleSnapshot();
|
|
1299
|
+
}
|
|
1300
|
+
/** Captura o DOM depois do ciclo de renderização atual (Vue, React, etc.). */
|
|
1301
|
+
scheduleSnapshot() {
|
|
1302
|
+
this.cancelScheduledSnapshot();
|
|
1303
|
+
if (typeof window === "undefined") return;
|
|
1304
|
+
this.settling = true;
|
|
1305
|
+
if (typeof MutationObserver !== "undefined" && document.documentElement) {
|
|
1306
|
+
this.settleObserver = new MutationObserver(() => this.notifySnapshotActivity());
|
|
1307
|
+
this.settleObserver.observe(document.documentElement, {
|
|
1308
|
+
attributes: true,
|
|
1309
|
+
characterData: true,
|
|
1310
|
+
childList: true,
|
|
1311
|
+
subtree: true
|
|
1312
|
+
});
|
|
1313
|
+
}
|
|
1314
|
+
this.settleTimeout = window.setTimeout(() => this.captureSettledSnapshot(), SNAPSHOT_SETTLE_TIMEOUT_MS);
|
|
1315
|
+
}
|
|
1316
|
+
notifySnapshotActivity() {
|
|
1317
|
+
if (!this.settling || typeof window === "undefined") return;
|
|
1318
|
+
if (this.scheduledSnapshotTimer !== void 0) window.clearTimeout(this.scheduledSnapshotTimer);
|
|
1319
|
+
this.scheduledSnapshotTimer = window.setTimeout(() => this.captureSettledSnapshot(), SNAPSHOT_DEBOUNCE_MS);
|
|
1320
|
+
}
|
|
1321
|
+
captureSettledSnapshot() {
|
|
1322
|
+
if (!this.settling || typeof window === "undefined") return;
|
|
1323
|
+
this.settling = false;
|
|
1324
|
+
this.cancelScheduledSnapshot();
|
|
1325
|
+
const capture = () => {
|
|
1326
|
+
if (!this.stopped && !this.paused) this.takeFullSnapshot();
|
|
1327
|
+
};
|
|
1328
|
+
if (typeof window.requestAnimationFrame !== "function") {
|
|
1329
|
+
capture();
|
|
1330
|
+
return;
|
|
1331
|
+
}
|
|
1332
|
+
this.scheduledSnapshotFrame = window.requestAnimationFrame(() => {
|
|
1333
|
+
this.scheduledSnapshotFrame = window.requestAnimationFrame(() => {
|
|
1334
|
+
this.scheduledSnapshotFrame = void 0;
|
|
1335
|
+
capture();
|
|
1336
|
+
});
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
cancelScheduledSnapshot() {
|
|
1340
|
+
if (typeof window === "undefined") return;
|
|
1341
|
+
this.settling = false;
|
|
1342
|
+
if (this.scheduledSnapshotFrame !== void 0) {
|
|
1343
|
+
window.cancelAnimationFrame(this.scheduledSnapshotFrame);
|
|
1344
|
+
this.scheduledSnapshotFrame = void 0;
|
|
1345
|
+
}
|
|
1346
|
+
if (this.scheduledSnapshotTimer !== void 0) {
|
|
1347
|
+
window.clearTimeout(this.scheduledSnapshotTimer);
|
|
1348
|
+
this.scheduledSnapshotTimer = void 0;
|
|
1349
|
+
}
|
|
1350
|
+
if (this.settleTimeout !== void 0) {
|
|
1351
|
+
window.clearTimeout(this.settleTimeout);
|
|
1352
|
+
this.settleTimeout = void 0;
|
|
1353
|
+
}
|
|
1354
|
+
this.settleObserver?.disconnect();
|
|
1355
|
+
this.settleObserver = void 0;
|
|
1295
1356
|
}
|
|
1296
1357
|
onEvent(event) {
|
|
1297
1358
|
if (this.paused) return;
|
|
@@ -1299,8 +1360,11 @@ var RRWebRecorder = class {
|
|
|
1299
1360
|
this.sanitizeEvent(event);
|
|
1300
1361
|
let priority = PRIORITY[event.type] ?? "normal";
|
|
1301
1362
|
if (event.type === 3 && LOW_SOURCES.has(event.data?.source)) priority = "low";
|
|
1302
|
-
if (event.type === 2) this.snapshotsTaken++;
|
|
1303
1363
|
const emitted = this.sink.emit("rrweb", event, { priority, at: event.timestamp });
|
|
1364
|
+
if (event.type === 2) {
|
|
1365
|
+
this.needsSnapshot = !emitted;
|
|
1366
|
+
if (emitted) this.snapshotsTaken++;
|
|
1367
|
+
}
|
|
1304
1368
|
if (!emitted && event.type === 3) this.needsSnapshot = true;
|
|
1305
1369
|
});
|
|
1306
1370
|
}
|
|
@@ -1333,13 +1397,15 @@ var RRWebRecorder = class {
|
|
|
1333
1397
|
/** Chamado pelo núcleo quando há folga novamente após descartes. */
|
|
1334
1398
|
recoverIfNeeded() {
|
|
1335
1399
|
if (this.needsSnapshot && !this.paused) {
|
|
1336
|
-
this.needsSnapshot = false;
|
|
1337
1400
|
this.takeFullSnapshot();
|
|
1338
1401
|
}
|
|
1339
1402
|
}
|
|
1340
1403
|
takeFullSnapshot() {
|
|
1341
1404
|
if (this.stopped) return;
|
|
1342
|
-
guard(this.sink, this.name, () =>
|
|
1405
|
+
guard(this.sink, this.name, () => {
|
|
1406
|
+
if (!this.mod?.record) return;
|
|
1407
|
+
this.mod.record.takeFullSnapshot(true);
|
|
1408
|
+
});
|
|
1343
1409
|
}
|
|
1344
1410
|
addCustomEvent(tag, payload) {
|
|
1345
1411
|
if (this.stopped) return;
|
|
@@ -1350,6 +1416,7 @@ var RRWebRecorder = class {
|
|
|
1350
1416
|
}
|
|
1351
1417
|
pause() {
|
|
1352
1418
|
this.paused = true;
|
|
1419
|
+
this.cancelScheduledSnapshot();
|
|
1353
1420
|
}
|
|
1354
1421
|
/** Ao retomar, as mutações perdidas durante a pausa exigem um snapshot completo. */
|
|
1355
1422
|
resume() {
|
|
@@ -1357,7 +1424,9 @@ var RRWebRecorder = class {
|
|
|
1357
1424
|
this.takeFullSnapshot();
|
|
1358
1425
|
}
|
|
1359
1426
|
stop() {
|
|
1427
|
+
if (!this.stopped && !this.paused) this.takeFullSnapshot();
|
|
1360
1428
|
this.stopped = true;
|
|
1429
|
+
this.cancelScheduledSnapshot();
|
|
1361
1430
|
safe(() => this.stopFn?.());
|
|
1362
1431
|
this.stopFn = void 0;
|
|
1363
1432
|
}
|
|
@@ -2213,7 +2282,7 @@ var SUCCESS_TEMPLATE = `
|
|
|
2213
2282
|
var TOKEN_STORAGE_KEY = "offscript-session-token";
|
|
2214
2283
|
var DRAFT_STORAGE_KEY = "offscript-draft-key";
|
|
2215
2284
|
var COMPLETED_TOKEN_STORAGE_KEY = "offscript-completed-token";
|
|
2216
|
-
var
|
|
2285
|
+
var NAVIGATION_SETTLE_WINDOW_MS = 5e3;
|
|
2217
2286
|
function tokenFingerprint(token) {
|
|
2218
2287
|
let first = 2166136261;
|
|
2219
2288
|
let second = 2654435769;
|
|
@@ -2240,6 +2309,7 @@ var Offscript = class {
|
|
|
2240
2309
|
this.pageId = uid("page_");
|
|
2241
2310
|
this.submitted = false;
|
|
2242
2311
|
this.launchTokenChanged = false;
|
|
2312
|
+
this.snapshotAfterNavigationUntil = 0;
|
|
2243
2313
|
this.config = resolveConfig(config);
|
|
2244
2314
|
this.sanitizer = new DataSanitizer(this.config.privacy);
|
|
2245
2315
|
}
|
|
@@ -2255,11 +2325,19 @@ var Offscript = class {
|
|
|
2255
2325
|
this.initPromise ?? (this.initPromise = this.initialize());
|
|
2256
2326
|
await this.initPromise;
|
|
2257
2327
|
if (this.restorePromise) await this.restorePromise;
|
|
2258
|
-
|
|
2328
|
+
this.exposeRunnerBridge();
|
|
2329
|
+
if (this.config.controls && this.launchToken && !this.controls && !window.__offscriptRunner?.enabled) {
|
|
2259
2330
|
this.controls = new RecordingControls(this);
|
|
2260
2331
|
this.controls.mount();
|
|
2261
2332
|
}
|
|
2262
2333
|
}
|
|
2334
|
+
exposeRunnerBridge() {
|
|
2335
|
+
const bridge = window.__offscriptRunner;
|
|
2336
|
+
if (!bridge?.enabled || !bridge.endpoint) return;
|
|
2337
|
+
bridge.startRecording = () => this.startRecording();
|
|
2338
|
+
bridge.complete = () => this.complete({ endpoint: bridge.endpoint });
|
|
2339
|
+
bridge.ready = true;
|
|
2340
|
+
}
|
|
2263
2341
|
async initialize() {
|
|
2264
2342
|
this.resolveLaunchToken();
|
|
2265
2343
|
if (this.launchToken && !this.config.persistenceKey) {
|
|
@@ -2315,27 +2393,8 @@ var Offscript = class {
|
|
|
2315
2393
|
async initializeDraft() {
|
|
2316
2394
|
if (!this.config.persistenceKey) return;
|
|
2317
2395
|
this.store = await RecordingStore.open(this.config.persistenceKey);
|
|
2318
|
-
|
|
2319
|
-
if (this.launchTokenChanged || startsNewSegment) await this.store.clear();
|
|
2396
|
+
if (this.launchTokenChanged) await this.store.clear();
|
|
2320
2397
|
await this.restoreDraft();
|
|
2321
|
-
if (startsNewSegment) await this.startFreshRecording();
|
|
2322
|
-
}
|
|
2323
|
-
async consumeRecordingSegmentMarker() {
|
|
2324
|
-
const url = new URL(window.location.href);
|
|
2325
|
-
const marker = url.searchParams.get(RECORDING_SEGMENT_START_QUERY);
|
|
2326
|
-
if (!marker) return false;
|
|
2327
|
-
url.searchParams.delete(RECORDING_SEGMENT_START_QUERY);
|
|
2328
|
-
window.history.replaceState(window.history.state, "", url.href);
|
|
2329
|
-
if (!this.launchToken || !globalThis.crypto?.subtle) return false;
|
|
2330
|
-
let fingerprint;
|
|
2331
|
-
try {
|
|
2332
|
-
const tokenBytes = new TextEncoder().encode(this.launchToken);
|
|
2333
|
-
const digest = await globalThis.crypto.subtle.digest("SHA-256", tokenBytes);
|
|
2334
|
-
fingerprint = Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2335
|
-
} catch {
|
|
2336
|
-
return false;
|
|
2337
|
-
}
|
|
2338
|
-
return marker === fingerprint;
|
|
2339
2398
|
}
|
|
2340
2399
|
async restoreDraft() {
|
|
2341
2400
|
const saved = await this.store.load();
|
|
@@ -2549,6 +2608,7 @@ var Offscript = class {
|
|
|
2549
2608
|
this.rrweb?.recoverIfNeeded();
|
|
2550
2609
|
const sequence = ++this.sequence;
|
|
2551
2610
|
const timestamp = opts.at ?? Date.now();
|
|
2611
|
+
if (kind === "http" && timestamp <= this.snapshotAfterNavigationUntil) this.rrweb?.notifySnapshotActivity();
|
|
2552
2612
|
const id = `${this.pageId}:${sequence}`;
|
|
2553
2613
|
let payload = data;
|
|
2554
2614
|
if (kind === "action") {
|
|
@@ -2615,6 +2675,8 @@ var Offscript = class {
|
|
|
2615
2675
|
this.actions?.recordNavigation(from, to, kind);
|
|
2616
2676
|
this.emitLifecycle("navigation", { from: this.sanitizer.sanitizeUrl(from), to: this.sanitizer.sanitizeUrl(to), kind }, "critical");
|
|
2617
2677
|
this.context?.record("navigation");
|
|
2678
|
+
this.snapshotAfterNavigationUntil = Date.now() + NAVIGATION_SETTLE_WINDOW_MS;
|
|
2679
|
+
this.rrweb?.scheduleSnapshot();
|
|
2618
2680
|
}
|
|
2619
2681
|
}));
|
|
2620
2682
|
this.lifecycle.install();
|
|
@@ -2675,5 +2737,5 @@ var Offscript = class {
|
|
|
2675
2737
|
Offscript.version = SDK_VERSION;
|
|
2676
2738
|
|
|
2677
2739
|
export { ConfigError, DEFAULT_PRIVACY, DEFAULT_RECORDING, DataSanitizer, InvalidStateError, Offscript, OffscriptError };
|
|
2678
|
-
//# sourceMappingURL=chunk-
|
|
2679
|
-
//# sourceMappingURL=chunk-
|
|
2740
|
+
//# sourceMappingURL=chunk-W27UMAEC.js.map
|
|
2741
|
+
//# sourceMappingURL=chunk-W27UMAEC.js.map
|