@oneuptime/react-native-replay 14.0.1 → 14.0.3
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 +51 -0
- package/dist/index.cjs +1593 -798
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +1593 -798
- package/dist/index.js.map +4 -4
- package/dist/types/Base64.d.ts +3 -0
- package/dist/types/Base64.d.ts.map +1 -0
- package/dist/types/Config.d.ts +26 -0
- package/dist/types/Config.d.ts.map +1 -1
- package/dist/types/Contract.d.ts +5 -0
- package/dist/types/Contract.d.ts.map +1 -1
- package/dist/types/MobileReplayRecorder.d.ts +8 -0
- package/dist/types/MobileReplayRecorder.d.ts.map +1 -1
- package/dist/types/Outbox.d.ts +33 -5
- package/dist/types/Outbox.d.ts.map +1 -1
- package/dist/types/Storage.d.ts +1 -0
- package/dist/types/Storage.d.ts.map +1 -1
- package/dist/types/Transport.d.ts +7 -0
- package/dist/types/Transport.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -59,7 +59,23 @@ var import_react_native2 = require("react-native");
|
|
|
59
59
|
// src/Contract.ts
|
|
60
60
|
var SESSION_REPLAY_WIRE_VERSION = 1;
|
|
61
61
|
var SESSION_REPLAY_SCHEMA_VERSION = 1;
|
|
62
|
-
var SESSION_REPLAY_CONTENT_TYPE = "application/
|
|
62
|
+
var SESSION_REPLAY_CONTENT_TYPE = "application/octet-stream";
|
|
63
|
+
var SESSION_REPLAY_ENVELOPE_TERMINATOR = " \n";
|
|
64
|
+
var ESCAPED_SEQUENCES = /[%&]|(http)\//gi;
|
|
65
|
+
function escapeSessionReplayJson(json) {
|
|
66
|
+
return json.replace(
|
|
67
|
+
ESCAPED_SEQUENCES,
|
|
68
|
+
(match, http) => {
|
|
69
|
+
if (http !== void 0) {
|
|
70
|
+
return `${http}\\/`;
|
|
71
|
+
}
|
|
72
|
+
return match === "%" ? "\\u0025" : "\\u0026";
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
function encodeSessionReplayEnvelopeLine(envelope) {
|
|
77
|
+
return escapeSessionReplayJson(JSON.stringify(envelope)) + SESSION_REPLAY_ENVELOPE_TERMINATOR;
|
|
78
|
+
}
|
|
63
79
|
var SESSION_REPLAY_APP_IDENTIFIER_HEADER = "x-oneuptime-app-identifier";
|
|
64
80
|
var SESSION_REPLAY_RECORDER_KIND_HEADER = "x-oneuptime-replay-recorder-kind";
|
|
65
81
|
var SESSION_REPLAY_MOBILE_APP_IDENTIFIER_HEADER = "x-oneuptime-mobile-app-identifier";
|
|
@@ -78,10 +94,11 @@ var SESSION_REPLAY_MAX_SESSION_MS = 4 * 60 * 6e4;
|
|
|
78
94
|
var SESSION_REPLAY_MAX_DECOMPRESSED_FRAME_BYTES = 8 * 1024 * 1024;
|
|
79
95
|
var MAX_SESSION_REPLAY_CHUNK_BYTES = 2 * 1024 * 1024;
|
|
80
96
|
var MAX_SESSION_REPLAY_CHUNKS_PER_SESSION = 480;
|
|
97
|
+
var SESSION_REPLAY_MAX_OFFLINE_DELAY_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
81
98
|
var MOBILE_CAPTURE_INTERVAL_MS = 500;
|
|
82
99
|
var MOBILE_RECORDER_KIND = "rn-view-tree";
|
|
83
100
|
var SYNTHETIC_RRWEB_VERSION = "synthetic-1";
|
|
84
|
-
var RECORDER_VERSION = true ? "14.0.
|
|
101
|
+
var RECORDER_VERSION = true ? "14.0.3" : "0.0.0-dev";
|
|
85
102
|
var SESSION_REPLAY_MOBILE_RECORDER_CAPABILITIES = [
|
|
86
103
|
"mobile-view-tree",
|
|
87
104
|
"mobile-touch-events",
|
|
@@ -562,6 +579,57 @@ function normalizeReplayConfig(value) {
|
|
|
562
579
|
}
|
|
563
580
|
return resolved;
|
|
564
581
|
}
|
|
582
|
+
function replayConfigCacheKey(namespace) {
|
|
583
|
+
return `@oneuptime/replay/${namespace}/config`;
|
|
584
|
+
}
|
|
585
|
+
async function saveReplayConfig(storage, namespace, config, nowUnixMs) {
|
|
586
|
+
try {
|
|
587
|
+
if (!config.enabled) {
|
|
588
|
+
await storage.removeItem(replayConfigCacheKey(namespace));
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
const cached = {
|
|
592
|
+
savedAtUnixMs: nowUnixMs,
|
|
593
|
+
config: { ...config, isTargeted: false }
|
|
594
|
+
};
|
|
595
|
+
await storage.setItem(
|
|
596
|
+
replayConfigCacheKey(namespace),
|
|
597
|
+
JSON.stringify(cached)
|
|
598
|
+
);
|
|
599
|
+
} catch {
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
async function forgetReplayConfig(storage, namespace) {
|
|
603
|
+
try {
|
|
604
|
+
await storage.removeItem(replayConfigCacheKey(namespace));
|
|
605
|
+
} catch {
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
async function loadCachedReplayConfig(storage, namespace, nowUnixMs) {
|
|
609
|
+
try {
|
|
610
|
+
const raw = await storage.getItem(
|
|
611
|
+
replayConfigCacheKey(namespace)
|
|
612
|
+
);
|
|
613
|
+
if (!raw) {
|
|
614
|
+
return null;
|
|
615
|
+
}
|
|
616
|
+
const cached = JSON.parse(
|
|
617
|
+
raw
|
|
618
|
+
);
|
|
619
|
+
const age = nowUnixMs - Number(cached.savedAtUnixMs);
|
|
620
|
+
if (!Number.isFinite(age) || age < 0 || age > SESSION_REPLAY_MAX_OFFLINE_DELAY_MS || !cached.config || typeof cached.config !== "object") {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
const config = normalizeReplayConfig({
|
|
624
|
+
...cached.config,
|
|
625
|
+
directive: cached.config.enabled === true ? "continue" : "stop",
|
|
626
|
+
isTargeted: false
|
|
627
|
+
});
|
|
628
|
+
return config.enabled ? config : null;
|
|
629
|
+
} catch {
|
|
630
|
+
return null;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
565
633
|
async function fetchReplayConfig(options, includeUserRef = false, revalidate = false) {
|
|
566
634
|
const controller = typeof AbortController === "undefined" ? null : new AbortController();
|
|
567
635
|
let timeout = null;
|
|
@@ -1091,878 +1159,1415 @@ function getViewport() {
|
|
|
1091
1159
|
return viewport();
|
|
1092
1160
|
}
|
|
1093
1161
|
|
|
1094
|
-
//
|
|
1095
|
-
var
|
|
1096
|
-
var
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1162
|
+
// node_modules/fflate/esm/browser.js
|
|
1163
|
+
var u8 = Uint8Array;
|
|
1164
|
+
var u16 = Uint16Array;
|
|
1165
|
+
var i32 = Int32Array;
|
|
1166
|
+
var fleb = new u8([
|
|
1167
|
+
0,
|
|
1168
|
+
0,
|
|
1169
|
+
0,
|
|
1170
|
+
0,
|
|
1171
|
+
0,
|
|
1172
|
+
0,
|
|
1173
|
+
0,
|
|
1174
|
+
0,
|
|
1175
|
+
1,
|
|
1176
|
+
1,
|
|
1177
|
+
1,
|
|
1178
|
+
1,
|
|
1179
|
+
2,
|
|
1180
|
+
2,
|
|
1181
|
+
2,
|
|
1182
|
+
2,
|
|
1183
|
+
3,
|
|
1184
|
+
3,
|
|
1185
|
+
3,
|
|
1186
|
+
3,
|
|
1187
|
+
4,
|
|
1188
|
+
4,
|
|
1189
|
+
4,
|
|
1190
|
+
4,
|
|
1191
|
+
5,
|
|
1192
|
+
5,
|
|
1193
|
+
5,
|
|
1194
|
+
5,
|
|
1195
|
+
0,
|
|
1196
|
+
/* unused */
|
|
1197
|
+
0,
|
|
1198
|
+
0,
|
|
1199
|
+
/* impossible */
|
|
1200
|
+
0
|
|
1201
|
+
]);
|
|
1202
|
+
var fdeb = new u8([
|
|
1203
|
+
0,
|
|
1204
|
+
0,
|
|
1205
|
+
0,
|
|
1206
|
+
0,
|
|
1207
|
+
1,
|
|
1208
|
+
1,
|
|
1209
|
+
2,
|
|
1210
|
+
2,
|
|
1211
|
+
3,
|
|
1212
|
+
3,
|
|
1213
|
+
4,
|
|
1214
|
+
4,
|
|
1215
|
+
5,
|
|
1216
|
+
5,
|
|
1217
|
+
6,
|
|
1218
|
+
6,
|
|
1219
|
+
7,
|
|
1220
|
+
7,
|
|
1221
|
+
8,
|
|
1222
|
+
8,
|
|
1223
|
+
9,
|
|
1224
|
+
9,
|
|
1225
|
+
10,
|
|
1226
|
+
10,
|
|
1227
|
+
11,
|
|
1228
|
+
11,
|
|
1229
|
+
12,
|
|
1230
|
+
12,
|
|
1231
|
+
13,
|
|
1232
|
+
13,
|
|
1233
|
+
/* unused */
|
|
1234
|
+
0,
|
|
1235
|
+
0
|
|
1236
|
+
]);
|
|
1237
|
+
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
1238
|
+
var freb = function(eb, start) {
|
|
1239
|
+
var b = new u16(31);
|
|
1240
|
+
for (var i2 = 0; i2 < 31; ++i2) {
|
|
1241
|
+
b[i2] = start += 1 << eb[i2 - 1];
|
|
1100
1242
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1243
|
+
var r = new i32(b[30]);
|
|
1244
|
+
for (var i2 = 1; i2 < 30; ++i2) {
|
|
1245
|
+
for (var j = b[i2]; j < b[i2 + 1]; ++j) {
|
|
1246
|
+
r[j] = j - b[i2] << 5 | i2;
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
return { b, r };
|
|
1250
|
+
};
|
|
1251
|
+
var _a = freb(fleb, 2);
|
|
1252
|
+
var fl = _a.b;
|
|
1253
|
+
var revfl = _a.r;
|
|
1254
|
+
fl[28] = 258, revfl[258] = 28;
|
|
1255
|
+
var _b = freb(fdeb, 0);
|
|
1256
|
+
var fd = _b.b;
|
|
1257
|
+
var revfd = _b.r;
|
|
1258
|
+
var rev = new u16(32768);
|
|
1259
|
+
for (i = 0; i < 32768; ++i) {
|
|
1260
|
+
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
1261
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
1262
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
1263
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
1106
1264
|
}
|
|
1107
|
-
var
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1265
|
+
var x;
|
|
1266
|
+
var i;
|
|
1267
|
+
var hMap = (function(cd, mb, r) {
|
|
1268
|
+
var s = cd.length;
|
|
1269
|
+
var i2 = 0;
|
|
1270
|
+
var l = new u16(mb);
|
|
1271
|
+
for (; i2 < s; ++i2) {
|
|
1272
|
+
if (cd[i2])
|
|
1273
|
+
++l[cd[i2] - 1];
|
|
1114
1274
|
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
return this.readUnlocked();
|
|
1119
|
-
}
|
|
1120
|
-
);
|
|
1275
|
+
var le = new u16(mb);
|
|
1276
|
+
for (i2 = 1; i2 < mb; ++i2) {
|
|
1277
|
+
le[i2] = le[i2 - 1] + l[i2 - 1] << 1;
|
|
1121
1278
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1279
|
+
var co;
|
|
1280
|
+
if (r) {
|
|
1281
|
+
co = new u16(1 << mb);
|
|
1282
|
+
var rvb = 15 - mb;
|
|
1283
|
+
for (i2 = 0; i2 < s; ++i2) {
|
|
1284
|
+
if (cd[i2]) {
|
|
1285
|
+
var sv = i2 << 4 | cd[i2];
|
|
1286
|
+
var r_1 = mb - cd[i2];
|
|
1287
|
+
var v = le[cd[i2] - 1]++ << r_1;
|
|
1288
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
|
|
1289
|
+
co[rev[v] >> rvb] = sv;
|
|
1290
|
+
}
|
|
1127
1291
|
}
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1292
|
+
}
|
|
1293
|
+
} else {
|
|
1294
|
+
co = new u16(s);
|
|
1295
|
+
for (i2 = 0; i2 < s; ++i2) {
|
|
1296
|
+
if (cd[i2]) {
|
|
1297
|
+
co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
|
|
1132
1298
|
}
|
|
1133
|
-
return parsed.slice().sort(
|
|
1134
|
-
(left, right) => {
|
|
1135
|
-
return left.createdAtUnixMs - right.createdAtUnixMs;
|
|
1136
|
-
}
|
|
1137
|
-
);
|
|
1138
|
-
} catch {
|
|
1139
|
-
await this.removeUnlocked();
|
|
1140
|
-
return [];
|
|
1141
1299
|
}
|
|
1142
1300
|
}
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1301
|
+
return co;
|
|
1302
|
+
});
|
|
1303
|
+
var flt = new u8(288);
|
|
1304
|
+
for (i = 0; i < 144; ++i)
|
|
1305
|
+
flt[i] = 8;
|
|
1306
|
+
var i;
|
|
1307
|
+
for (i = 144; i < 256; ++i)
|
|
1308
|
+
flt[i] = 9;
|
|
1309
|
+
var i;
|
|
1310
|
+
for (i = 256; i < 280; ++i)
|
|
1311
|
+
flt[i] = 7;
|
|
1312
|
+
var i;
|
|
1313
|
+
for (i = 280; i < 288; ++i)
|
|
1314
|
+
flt[i] = 8;
|
|
1315
|
+
var i;
|
|
1316
|
+
var fdt = new u8(32);
|
|
1317
|
+
for (i = 0; i < 32; ++i)
|
|
1318
|
+
fdt[i] = 5;
|
|
1319
|
+
var i;
|
|
1320
|
+
var flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
1321
|
+
var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
1322
|
+
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
1323
|
+
var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
1324
|
+
var max = function(a) {
|
|
1325
|
+
var m = a[0];
|
|
1326
|
+
for (var i2 = 1; i2 < a.length; ++i2) {
|
|
1327
|
+
if (a[i2] > m)
|
|
1328
|
+
m = a[i2];
|
|
1329
|
+
}
|
|
1330
|
+
return m;
|
|
1331
|
+
};
|
|
1332
|
+
var bits = function(d, p, m) {
|
|
1333
|
+
var o = p / 8 | 0;
|
|
1334
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
1335
|
+
};
|
|
1336
|
+
var bits16 = function(d, p) {
|
|
1337
|
+
var o = p / 8 | 0;
|
|
1338
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
1339
|
+
};
|
|
1340
|
+
var shft = function(p) {
|
|
1341
|
+
return (p + 7) / 8 | 0;
|
|
1342
|
+
};
|
|
1343
|
+
var slc = function(v, s, e) {
|
|
1344
|
+
if (s == null || s < 0)
|
|
1345
|
+
s = 0;
|
|
1346
|
+
if (e == null || e > v.length)
|
|
1347
|
+
e = v.length;
|
|
1348
|
+
return new u8(v.subarray(s, e));
|
|
1349
|
+
};
|
|
1350
|
+
var ec = [
|
|
1351
|
+
"unexpected EOF",
|
|
1352
|
+
"invalid block type",
|
|
1353
|
+
"invalid length/literal",
|
|
1354
|
+
"invalid distance",
|
|
1355
|
+
"stream finished",
|
|
1356
|
+
"no stream handler",
|
|
1357
|
+
,
|
|
1358
|
+
// determined by compression function
|
|
1359
|
+
"no callback",
|
|
1360
|
+
"invalid UTF-8 data",
|
|
1361
|
+
"extra field too long",
|
|
1362
|
+
"date not in range 1980-2099",
|
|
1363
|
+
"filename too long",
|
|
1364
|
+
"stream finishing",
|
|
1365
|
+
"invalid zip data"
|
|
1366
|
+
// determined by unknown compression method
|
|
1367
|
+
];
|
|
1368
|
+
var err = function(ind, msg, nt) {
|
|
1369
|
+
var e = new Error(msg || ec[ind]);
|
|
1370
|
+
e.code = ind;
|
|
1371
|
+
if (Error.captureStackTrace)
|
|
1372
|
+
Error.captureStackTrace(e, err);
|
|
1373
|
+
if (!nt)
|
|
1374
|
+
throw e;
|
|
1375
|
+
return e;
|
|
1376
|
+
};
|
|
1377
|
+
var inflt = function(dat, st, buf, dict) {
|
|
1378
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
1379
|
+
if (!sl || st.f && !st.l)
|
|
1380
|
+
return buf || new u8(0);
|
|
1381
|
+
var noBuf = !buf;
|
|
1382
|
+
var resize = noBuf || st.i != 2;
|
|
1383
|
+
var noSt = st.i;
|
|
1384
|
+
if (noBuf)
|
|
1385
|
+
buf = new u8(sl * 3);
|
|
1386
|
+
var cbuf = function(l2) {
|
|
1387
|
+
var bl = buf.length;
|
|
1388
|
+
if (l2 > bl) {
|
|
1389
|
+
var nbuf = new u8(Math.max(bl * 2, l2));
|
|
1390
|
+
nbuf.set(buf);
|
|
1391
|
+
buf = nbuf;
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
1394
|
+
var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
|
|
1395
|
+
var tbts = sl * 8;
|
|
1396
|
+
do {
|
|
1397
|
+
if (!lm) {
|
|
1398
|
+
final = bits(dat, pos, 1);
|
|
1399
|
+
var type = bits(dat, pos + 1, 3);
|
|
1400
|
+
pos += 3;
|
|
1401
|
+
if (!type) {
|
|
1402
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
1403
|
+
if (t > sl) {
|
|
1404
|
+
if (noSt)
|
|
1405
|
+
err(0);
|
|
1406
|
+
break;
|
|
1407
|
+
}
|
|
1408
|
+
if (resize)
|
|
1409
|
+
cbuf(bt + l);
|
|
1410
|
+
buf.set(dat.subarray(s, t), bt);
|
|
1411
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
1412
|
+
continue;
|
|
1413
|
+
} else if (type == 1)
|
|
1414
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
1415
|
+
else if (type == 2) {
|
|
1416
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
1417
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
1418
|
+
pos += 14;
|
|
1419
|
+
var ldt = new u8(tl);
|
|
1420
|
+
var clt = new u8(19);
|
|
1421
|
+
for (var i2 = 0; i2 < hcLen; ++i2) {
|
|
1422
|
+
clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
|
|
1423
|
+
}
|
|
1424
|
+
pos += hcLen * 3;
|
|
1425
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
1426
|
+
var clm = hMap(clt, clb, 1);
|
|
1427
|
+
for (var i2 = 0; i2 < tl; ) {
|
|
1428
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
1429
|
+
pos += r & 15;
|
|
1430
|
+
var s = r >> 4;
|
|
1431
|
+
if (s < 16) {
|
|
1432
|
+
ldt[i2++] = s;
|
|
1433
|
+
} else {
|
|
1434
|
+
var c = 0, n = 0;
|
|
1435
|
+
if (s == 16)
|
|
1436
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
|
|
1437
|
+
else if (s == 17)
|
|
1438
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
1439
|
+
else if (s == 18)
|
|
1440
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
1441
|
+
while (n--)
|
|
1442
|
+
ldt[i2++] = c;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
1446
|
+
lbt = max(lt);
|
|
1447
|
+
dbt = max(dt);
|
|
1448
|
+
lm = hMap(lt, lbt, 1);
|
|
1449
|
+
dm = hMap(dt, dbt, 1);
|
|
1450
|
+
} else
|
|
1451
|
+
err(1);
|
|
1452
|
+
if (pos > tbts) {
|
|
1453
|
+
if (noSt)
|
|
1454
|
+
err(0);
|
|
1455
|
+
break;
|
|
1150
1456
|
}
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1457
|
+
}
|
|
1458
|
+
if (resize)
|
|
1459
|
+
cbuf(bt + 131072);
|
|
1460
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
1461
|
+
var lpos = pos;
|
|
1462
|
+
for (; ; lpos = pos) {
|
|
1463
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
1464
|
+
pos += c & 15;
|
|
1465
|
+
if (pos > tbts) {
|
|
1466
|
+
if (noSt)
|
|
1467
|
+
err(0);
|
|
1468
|
+
break;
|
|
1156
1469
|
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1470
|
+
if (!c)
|
|
1471
|
+
err(2);
|
|
1472
|
+
if (sym < 256)
|
|
1473
|
+
buf[bt++] = sym;
|
|
1474
|
+
else if (sym == 256) {
|
|
1475
|
+
lpos = pos, lm = null;
|
|
1476
|
+
break;
|
|
1477
|
+
} else {
|
|
1478
|
+
var add = sym - 254;
|
|
1479
|
+
if (sym > 264) {
|
|
1480
|
+
var i2 = sym - 257, b = fleb[i2];
|
|
1481
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i2];
|
|
1482
|
+
pos += b;
|
|
1483
|
+
}
|
|
1484
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
1485
|
+
if (!d)
|
|
1486
|
+
err(3);
|
|
1487
|
+
pos += d & 15;
|
|
1488
|
+
var dt = fd[dsym];
|
|
1489
|
+
if (dsym > 3) {
|
|
1490
|
+
var b = fdeb[dsym];
|
|
1491
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
1492
|
+
}
|
|
1493
|
+
if (pos > tbts) {
|
|
1494
|
+
if (noSt)
|
|
1495
|
+
err(0);
|
|
1177
1496
|
break;
|
|
1178
1497
|
}
|
|
1498
|
+
if (resize)
|
|
1499
|
+
cbuf(bt + 131072);
|
|
1500
|
+
var end = bt + add;
|
|
1501
|
+
if (bt < dt) {
|
|
1502
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
1503
|
+
if (shift + bt < 0)
|
|
1504
|
+
err(3);
|
|
1505
|
+
for (; bt < dend; ++bt)
|
|
1506
|
+
buf[bt] = dict[shift + bt];
|
|
1507
|
+
}
|
|
1508
|
+
for (; bt < end; ++bt)
|
|
1509
|
+
buf[bt] = buf[bt - dt];
|
|
1179
1510
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1511
|
+
}
|
|
1512
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
1513
|
+
if (lm)
|
|
1514
|
+
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
1515
|
+
} while (!final);
|
|
1516
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
1517
|
+
};
|
|
1518
|
+
var wbits = function(d, p, v) {
|
|
1519
|
+
v <<= p & 7;
|
|
1520
|
+
var o = p / 8 | 0;
|
|
1521
|
+
d[o] |= v;
|
|
1522
|
+
d[o + 1] |= v >> 8;
|
|
1523
|
+
};
|
|
1524
|
+
var wbits16 = function(d, p, v) {
|
|
1525
|
+
v <<= p & 7;
|
|
1526
|
+
var o = p / 8 | 0;
|
|
1527
|
+
d[o] |= v;
|
|
1528
|
+
d[o + 1] |= v >> 8;
|
|
1529
|
+
d[o + 2] |= v >> 16;
|
|
1530
|
+
};
|
|
1531
|
+
var hTree = function(d, mb) {
|
|
1532
|
+
var t = [];
|
|
1533
|
+
for (var i2 = 0; i2 < d.length; ++i2) {
|
|
1534
|
+
if (d[i2])
|
|
1535
|
+
t.push({ s: i2, f: d[i2] });
|
|
1183
1536
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
}
|
|
1537
|
+
var s = t.length;
|
|
1538
|
+
var t2 = t.slice();
|
|
1539
|
+
if (!s)
|
|
1540
|
+
return { t: et, l: 0 };
|
|
1541
|
+
if (s == 1) {
|
|
1542
|
+
var v = new u8(t[0].s + 1);
|
|
1543
|
+
v[t[0].s] = 1;
|
|
1544
|
+
return { t: v, l: 1 };
|
|
1188
1545
|
}
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1546
|
+
t.sort(function(a, b) {
|
|
1547
|
+
return a.f - b.f;
|
|
1548
|
+
});
|
|
1549
|
+
t.push({ s: -1, f: 25001 });
|
|
1550
|
+
var l = t[0], r = t[1], i0 = 0, i1 = 1, i22 = 2;
|
|
1551
|
+
t[0] = { s: -1, f: l.f + r.f, l, r };
|
|
1552
|
+
while (i1 != s - 1) {
|
|
1553
|
+
l = t[t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1554
|
+
r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1555
|
+
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
1194
1556
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1557
|
+
var maxSym = t2[0].s;
|
|
1558
|
+
for (var i2 = 1; i2 < s; ++i2) {
|
|
1559
|
+
if (t2[i2].s > maxSym)
|
|
1560
|
+
maxSym = t2[i2].s;
|
|
1561
|
+
}
|
|
1562
|
+
var tr = new u16(maxSym + 1);
|
|
1563
|
+
var mbt = ln(t[i1 - 1], tr, 0);
|
|
1564
|
+
if (mbt > mb) {
|
|
1565
|
+
var i2 = 0, dt = 0;
|
|
1566
|
+
var lft = mbt - mb, cst = 1 << lft;
|
|
1567
|
+
t2.sort(function(a, b) {
|
|
1568
|
+
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
1569
|
+
});
|
|
1570
|
+
for (; i2 < s; ++i2) {
|
|
1571
|
+
var i2_1 = t2[i2].s;
|
|
1572
|
+
if (tr[i2_1] > mb) {
|
|
1573
|
+
dt += cst - (1 << mbt - tr[i2_1]);
|
|
1574
|
+
tr[i2_1] = mb;
|
|
1575
|
+
} else
|
|
1576
|
+
break;
|
|
1577
|
+
}
|
|
1578
|
+
dt >>= lft;
|
|
1579
|
+
while (dt > 0) {
|
|
1580
|
+
var i2_2 = t2[i2].s;
|
|
1581
|
+
if (tr[i2_2] < mb)
|
|
1582
|
+
dt -= 1 << mb - tr[i2_2]++ - 1;
|
|
1583
|
+
else
|
|
1584
|
+
++i2;
|
|
1585
|
+
}
|
|
1586
|
+
for (; i2 >= 0 && dt; --i2) {
|
|
1587
|
+
var i2_3 = t2[i2].s;
|
|
1588
|
+
if (tr[i2_3] == mb) {
|
|
1589
|
+
--tr[i2_3];
|
|
1590
|
+
++dt;
|
|
1200
1591
|
}
|
|
1201
|
-
await this.storage.setItem(this.key, JSON.stringify(frames));
|
|
1202
|
-
} catch {
|
|
1203
1592
|
}
|
|
1593
|
+
mbt = mb;
|
|
1204
1594
|
}
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1595
|
+
return { t: new u8(tr), l: mbt };
|
|
1596
|
+
};
|
|
1597
|
+
var ln = function(n, l, d) {
|
|
1598
|
+
return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
|
|
1599
|
+
};
|
|
1600
|
+
var lc = function(c) {
|
|
1601
|
+
var s = c.length;
|
|
1602
|
+
while (s && !c[--s])
|
|
1603
|
+
;
|
|
1604
|
+
var cl = new u16(++s);
|
|
1605
|
+
var cli = 0, cln = c[0], cls = 1;
|
|
1606
|
+
var w = function(v) {
|
|
1607
|
+
cl[cli++] = v;
|
|
1608
|
+
};
|
|
1609
|
+
for (var i2 = 1; i2 <= s; ++i2) {
|
|
1610
|
+
if (c[i2] == cln && i2 != s)
|
|
1611
|
+
++cls;
|
|
1612
|
+
else {
|
|
1613
|
+
if (!cln && cls > 2) {
|
|
1614
|
+
for (; cls > 138; cls -= 138)
|
|
1615
|
+
w(32754);
|
|
1616
|
+
if (cls > 2) {
|
|
1617
|
+
w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
|
|
1618
|
+
cls = 0;
|
|
1619
|
+
}
|
|
1620
|
+
} else if (cls > 3) {
|
|
1621
|
+
w(cln), --cls;
|
|
1622
|
+
for (; cls > 6; cls -= 6)
|
|
1623
|
+
w(8304);
|
|
1624
|
+
if (cls > 2)
|
|
1625
|
+
w(cls - 3 << 5 | 8208), cls = 0;
|
|
1213
1626
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1627
|
+
while (cls--)
|
|
1628
|
+
w(cln);
|
|
1629
|
+
cls = 1;
|
|
1630
|
+
cln = c[i2];
|
|
1631
|
+
}
|
|
1216
1632
|
}
|
|
1633
|
+
return { c: cl.subarray(0, cli), n: s };
|
|
1217
1634
|
};
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
var
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1635
|
+
var clen = function(cf, cl) {
|
|
1636
|
+
var l = 0;
|
|
1637
|
+
for (var i2 = 0; i2 < cl.length; ++i2)
|
|
1638
|
+
l += cf[i2] * cl[i2];
|
|
1639
|
+
return l;
|
|
1640
|
+
};
|
|
1641
|
+
var wfblk = function(out, pos, dat) {
|
|
1642
|
+
var s = dat.length;
|
|
1643
|
+
var o = shft(pos + 2);
|
|
1644
|
+
out[o] = s & 255;
|
|
1645
|
+
out[o + 1] = s >> 8;
|
|
1646
|
+
out[o + 2] = out[o] ^ 255;
|
|
1647
|
+
out[o + 3] = out[o + 1] ^ 255;
|
|
1648
|
+
for (var i2 = 0; i2 < s; ++i2)
|
|
1649
|
+
out[o + i2 + 4] = dat[i2];
|
|
1650
|
+
return (o + 4 + s) * 8;
|
|
1651
|
+
};
|
|
1652
|
+
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
1653
|
+
wbits(out, p++, final);
|
|
1654
|
+
++lf[256];
|
|
1655
|
+
var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
|
|
1656
|
+
var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
|
|
1657
|
+
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
1658
|
+
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
1659
|
+
var lcfreq = new u16(19);
|
|
1660
|
+
for (var i2 = 0; i2 < lclt.length; ++i2)
|
|
1661
|
+
++lcfreq[lclt[i2] & 31];
|
|
1662
|
+
for (var i2 = 0; i2 < lcdt.length; ++i2)
|
|
1663
|
+
++lcfreq[lcdt[i2] & 31];
|
|
1664
|
+
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
1665
|
+
var nlcc = 19;
|
|
1666
|
+
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
1667
|
+
;
|
|
1668
|
+
var flen = bl + 5 << 3;
|
|
1669
|
+
var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
1670
|
+
var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
|
|
1671
|
+
if (bs >= 0 && flen <= ftlen && flen <= dtlen)
|
|
1672
|
+
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
1673
|
+
var lm, ll, dm, dl;
|
|
1674
|
+
wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
|
|
1675
|
+
if (dtlen < ftlen) {
|
|
1676
|
+
lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
|
|
1677
|
+
var llm = hMap(lct, mlcb, 0);
|
|
1678
|
+
wbits(out, p, nlc - 257);
|
|
1679
|
+
wbits(out, p + 5, ndc - 1);
|
|
1680
|
+
wbits(out, p + 10, nlcc - 4);
|
|
1681
|
+
p += 14;
|
|
1682
|
+
for (var i2 = 0; i2 < nlcc; ++i2)
|
|
1683
|
+
wbits(out, p + 3 * i2, lct[clim[i2]]);
|
|
1684
|
+
p += 3 * nlcc;
|
|
1685
|
+
var lcts = [lclt, lcdt];
|
|
1686
|
+
for (var it = 0; it < 2; ++it) {
|
|
1687
|
+
var clct = lcts[it];
|
|
1688
|
+
for (var i2 = 0; i2 < clct.length; ++i2) {
|
|
1689
|
+
var len = clct[i2] & 31;
|
|
1690
|
+
wbits(out, p, llm[len]), p += lct[len];
|
|
1691
|
+
if (len > 15)
|
|
1692
|
+
wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
|
|
1693
|
+
}
|
|
1231
1694
|
}
|
|
1695
|
+
} else {
|
|
1696
|
+
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
1232
1697
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1247
|
-
return null;
|
|
1248
|
-
}
|
|
1249
|
-
const candidate = parsed;
|
|
1250
|
-
if (!isReplayId(candidate.sessionId) || !Number.isSafeInteger(candidate.sessionStartUnixMs) || !Number.isSafeInteger(candidate.lastActivityUnixMs) || !Number.isSafeInteger(candidate.nextChunkIndex) || (candidate.nextChunkIndex ?? -1) < 0) {
|
|
1251
|
-
return null;
|
|
1698
|
+
for (var i2 = 0; i2 < li; ++i2) {
|
|
1699
|
+
var sym = syms[i2];
|
|
1700
|
+
if (sym > 255) {
|
|
1701
|
+
var len = sym >> 18 & 31;
|
|
1702
|
+
wbits16(out, p, lm[len + 257]), p += ll[len + 257];
|
|
1703
|
+
if (len > 7)
|
|
1704
|
+
wbits(out, p, sym >> 23 & 31), p += fleb[len];
|
|
1705
|
+
var dst = sym & 31;
|
|
1706
|
+
wbits16(out, p, dm[dst]), p += dl[dst];
|
|
1707
|
+
if (dst > 3)
|
|
1708
|
+
wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
|
|
1709
|
+
} else {
|
|
1710
|
+
wbits16(out, p, lm[sym]), p += ll[sym];
|
|
1252
1711
|
}
|
|
1253
|
-
return candidate;
|
|
1254
|
-
} catch {
|
|
1255
|
-
return null;
|
|
1256
1712
|
}
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1713
|
+
wbits16(out, p, lm[256]);
|
|
1714
|
+
return p + ll[256];
|
|
1715
|
+
};
|
|
1716
|
+
var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
|
|
1717
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
1718
|
+
var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
1719
|
+
var s = st.z || dat.length;
|
|
1720
|
+
var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7e3)) + post);
|
|
1721
|
+
var w = o.subarray(pre, o.length - post);
|
|
1722
|
+
var lst = st.l;
|
|
1723
|
+
var pos = (st.r || 0) & 7;
|
|
1724
|
+
if (lvl) {
|
|
1725
|
+
if (pos)
|
|
1726
|
+
w[0] = st.r >> 3;
|
|
1727
|
+
var opt = deo[lvl - 1];
|
|
1728
|
+
var n = opt >> 13, c = opt & 8191;
|
|
1729
|
+
var msk_1 = (1 << plvl) - 1;
|
|
1730
|
+
var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
|
|
1731
|
+
var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
|
|
1732
|
+
var hsh = function(i3) {
|
|
1733
|
+
return (dat[i3] ^ dat[i3 + 1] << bs1_1 ^ dat[i3 + 2] << bs2_1) & msk_1;
|
|
1734
|
+
};
|
|
1735
|
+
var syms = new i32(25e3);
|
|
1736
|
+
var lf = new u16(288), df = new u16(32);
|
|
1737
|
+
var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
1738
|
+
for (; i2 + 2 < s; ++i2) {
|
|
1739
|
+
var hv = hsh(i2);
|
|
1740
|
+
var imod = i2 & 32767, pimod = head[hv];
|
|
1741
|
+
prev[imod] = pimod;
|
|
1742
|
+
head[hv] = imod;
|
|
1743
|
+
if (wi <= i2) {
|
|
1744
|
+
var rem = s - i2;
|
|
1745
|
+
if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
|
|
1746
|
+
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1747
|
+
li = lc_1 = eb = 0, bs = i2;
|
|
1748
|
+
for (var j = 0; j < 286; ++j)
|
|
1749
|
+
lf[j] = 0;
|
|
1750
|
+
for (var j = 0; j < 30; ++j)
|
|
1751
|
+
df[j] = 0;
|
|
1752
|
+
}
|
|
1753
|
+
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
1754
|
+
if (rem > 2 && hv == hsh(i2 - dif)) {
|
|
1755
|
+
var maxn = Math.min(n, rem) - 1;
|
|
1756
|
+
var maxd = Math.min(32767, i2);
|
|
1757
|
+
var ml = Math.min(258, rem);
|
|
1758
|
+
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
1759
|
+
if (dat[i2 + l] == dat[i2 + l - dif]) {
|
|
1760
|
+
var nl = 0;
|
|
1761
|
+
for (; nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
|
|
1762
|
+
;
|
|
1763
|
+
if (nl > l) {
|
|
1764
|
+
l = nl, d = dif;
|
|
1765
|
+
if (nl > maxn)
|
|
1766
|
+
break;
|
|
1767
|
+
var mmd = Math.min(dif, nl - 2);
|
|
1768
|
+
var md = 0;
|
|
1769
|
+
for (var j = 0; j < mmd; ++j) {
|
|
1770
|
+
var ti = i2 - dif + j & 32767;
|
|
1771
|
+
var pti = prev[ti];
|
|
1772
|
+
var cd = ti - pti & 32767;
|
|
1773
|
+
if (cd > md)
|
|
1774
|
+
md = cd, pimod = ti;
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
imod = pimod, pimod = prev[imod];
|
|
1779
|
+
dif += imod - pimod & 32767;
|
|
1780
|
+
}
|
|
1781
|
+
}
|
|
1782
|
+
if (d) {
|
|
1783
|
+
syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
|
|
1784
|
+
var lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
1785
|
+
eb += fleb[lin] + fdeb[din];
|
|
1786
|
+
++lf[257 + lin];
|
|
1787
|
+
++df[din];
|
|
1788
|
+
wi = i2 + l;
|
|
1789
|
+
++lc_1;
|
|
1790
|
+
} else {
|
|
1791
|
+
syms[li++] = dat[i2];
|
|
1792
|
+
++lf[dat[i2]];
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1288
1795
|
}
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
await this.safeSet(this.visitorKey, visitorId);
|
|
1796
|
+
for (i2 = Math.max(i2, wi); i2 < s; ++i2) {
|
|
1797
|
+
syms[li++] = dat[i2];
|
|
1798
|
+
++lf[dat[i2]];
|
|
1293
1799
|
}
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
sessionStartUnixMs: session.sessionStartUnixMs,
|
|
1300
|
-
chunkIndex: session.nextChunkIndex
|
|
1301
|
-
};
|
|
1302
|
-
return { ...this.identity };
|
|
1303
|
-
}
|
|
1304
|
-
async takeChunkIndex(nowUnixMs) {
|
|
1305
|
-
if (!this.identity) {
|
|
1306
|
-
await this.resolve(nowUnixMs);
|
|
1800
|
+
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1801
|
+
if (!lst) {
|
|
1802
|
+
st.r = pos & 7 | w[pos / 8 | 0] << 3;
|
|
1803
|
+
pos -= 7;
|
|
1804
|
+
st.h = head, st.p = prev, st.i = i2, st.w = wi;
|
|
1307
1805
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
};
|
|
1317
|
-
await this.safeSet(this.sessionKey, JSON.stringify(state));
|
|
1318
|
-
return index;
|
|
1319
|
-
}
|
|
1320
|
-
getNextChunkIndex() {
|
|
1321
|
-
return this.identity?.chunkIndex ?? null;
|
|
1322
|
-
}
|
|
1323
|
-
async rotate(nowUnixMs) {
|
|
1324
|
-
let visitorId = await this.safeGet(this.visitorKey);
|
|
1325
|
-
if (!isReplayId(visitorId)) {
|
|
1326
|
-
visitorId = generateReplayId();
|
|
1327
|
-
await this.safeSet(this.visitorKey, visitorId);
|
|
1806
|
+
} else {
|
|
1807
|
+
for (var i2 = st.w || 0; i2 < s + lst; i2 += 65535) {
|
|
1808
|
+
var e = i2 + 65535;
|
|
1809
|
+
if (e >= s) {
|
|
1810
|
+
w[pos / 8 | 0] = lst;
|
|
1811
|
+
e = s;
|
|
1812
|
+
}
|
|
1813
|
+
pos = wfblk(w, pos + 1, dat.subarray(i2, e));
|
|
1328
1814
|
}
|
|
1329
|
-
|
|
1330
|
-
sessionId: generateReplayId(),
|
|
1331
|
-
sessionStartUnixMs: nowUnixMs,
|
|
1332
|
-
lastActivityUnixMs: nowUnixMs,
|
|
1333
|
-
nextChunkIndex: 0
|
|
1334
|
-
};
|
|
1335
|
-
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
1336
|
-
this.identity = {
|
|
1337
|
-
sessionId: session.sessionId,
|
|
1338
|
-
tabId: generateReplayId(),
|
|
1339
|
-
visitorId,
|
|
1340
|
-
sessionStartUnixMs: nowUnixMs,
|
|
1341
|
-
chunkIndex: 0
|
|
1342
|
-
};
|
|
1343
|
-
return { ...this.identity };
|
|
1815
|
+
st.i = s;
|
|
1344
1816
|
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1817
|
+
return slc(o, 0, pre + shft(pos) + post);
|
|
1818
|
+
};
|
|
1819
|
+
var crct = /* @__PURE__ */ (function() {
|
|
1820
|
+
var t = new Int32Array(256);
|
|
1821
|
+
for (var i2 = 0; i2 < 256; ++i2) {
|
|
1822
|
+
var c = i2, k = 9;
|
|
1823
|
+
while (--k)
|
|
1824
|
+
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
1825
|
+
t[i2] = c;
|
|
1351
1826
|
}
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1827
|
+
return t;
|
|
1828
|
+
})();
|
|
1829
|
+
var crc = function() {
|
|
1830
|
+
var c = -1;
|
|
1831
|
+
return {
|
|
1832
|
+
p: function(d) {
|
|
1833
|
+
var cr = c;
|
|
1834
|
+
for (var i2 = 0; i2 < d.length; ++i2)
|
|
1835
|
+
cr = crct[cr & 255 ^ d[i2]] ^ cr >>> 8;
|
|
1836
|
+
c = cr;
|
|
1837
|
+
},
|
|
1838
|
+
d: function() {
|
|
1839
|
+
return ~c;
|
|
1357
1840
|
}
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1841
|
+
};
|
|
1842
|
+
};
|
|
1843
|
+
var dopt = function(dat, opt, pre, post, st) {
|
|
1844
|
+
if (!st) {
|
|
1845
|
+
st = { l: 1 };
|
|
1846
|
+
if (opt.dictionary) {
|
|
1847
|
+
var dict = opt.dictionary.subarray(-32768);
|
|
1848
|
+
var newDat = new u8(dict.length + dat.length);
|
|
1849
|
+
newDat.set(dict);
|
|
1850
|
+
newDat.set(dat, dict.length);
|
|
1851
|
+
dat = newDat;
|
|
1852
|
+
st.w = dict.length;
|
|
1363
1853
|
}
|
|
1364
1854
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1855
|
+
return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
|
|
1856
|
+
};
|
|
1857
|
+
var wbytes = function(d, b, v) {
|
|
1858
|
+
for (; v; ++b)
|
|
1859
|
+
d[b] = v, v >>>= 8;
|
|
1860
|
+
};
|
|
1861
|
+
var gzh = function(c, o) {
|
|
1862
|
+
var fn = o.filename;
|
|
1863
|
+
c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3;
|
|
1864
|
+
if (o.mtime != 0)
|
|
1865
|
+
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1e3));
|
|
1866
|
+
if (fn) {
|
|
1867
|
+
c[3] = 8;
|
|
1868
|
+
for (var i2 = 0; i2 <= fn.length; ++i2)
|
|
1869
|
+
c[i2 + 10] = fn.charCodeAt(i2);
|
|
1370
1870
|
}
|
|
1371
1871
|
};
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
var
|
|
1376
|
-
var
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
0
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
0
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
1
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
var
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
5,
|
|
1427
|
-
5,
|
|
1428
|
-
6,
|
|
1429
|
-
6,
|
|
1430
|
-
7,
|
|
1431
|
-
7,
|
|
1432
|
-
8,
|
|
1433
|
-
8,
|
|
1434
|
-
9,
|
|
1435
|
-
9,
|
|
1436
|
-
10,
|
|
1437
|
-
10,
|
|
1438
|
-
11,
|
|
1439
|
-
11,
|
|
1440
|
-
12,
|
|
1441
|
-
12,
|
|
1442
|
-
13,
|
|
1443
|
-
13,
|
|
1444
|
-
/* unused */
|
|
1445
|
-
0,
|
|
1446
|
-
0
|
|
1447
|
-
]);
|
|
1448
|
-
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
1449
|
-
var freb = function(eb, start) {
|
|
1450
|
-
var b = new u16(31);
|
|
1451
|
-
for (var i2 = 0; i2 < 31; ++i2) {
|
|
1452
|
-
b[i2] = start += 1 << eb[i2 - 1];
|
|
1872
|
+
var gzs = function(d) {
|
|
1873
|
+
if (d[0] != 31 || d[1] != 139 || d[2] != 8)
|
|
1874
|
+
err(6, "invalid gzip data");
|
|
1875
|
+
var flg = d[3];
|
|
1876
|
+
var st = 10;
|
|
1877
|
+
if (flg & 4)
|
|
1878
|
+
st += (d[10] | d[11] << 8) + 2;
|
|
1879
|
+
for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
|
|
1880
|
+
;
|
|
1881
|
+
return st + (flg & 2);
|
|
1882
|
+
};
|
|
1883
|
+
var gzl = function(d) {
|
|
1884
|
+
var l = d.length;
|
|
1885
|
+
return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
|
|
1886
|
+
};
|
|
1887
|
+
var gzhl = function(o) {
|
|
1888
|
+
return 10 + (o.filename ? o.filename.length + 1 : 0);
|
|
1889
|
+
};
|
|
1890
|
+
function gzipSync(data, opts) {
|
|
1891
|
+
if (!opts)
|
|
1892
|
+
opts = {};
|
|
1893
|
+
var c = crc(), l = data.length;
|
|
1894
|
+
c.p(data);
|
|
1895
|
+
var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
1896
|
+
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
1897
|
+
}
|
|
1898
|
+
function gunzipSync(data, opts) {
|
|
1899
|
+
var st = gzs(data);
|
|
1900
|
+
if (st + 8 > data.length)
|
|
1901
|
+
err(6, "invalid gzip data");
|
|
1902
|
+
return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
|
|
1903
|
+
}
|
|
1904
|
+
var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
|
|
1905
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1906
|
+
var tds = 0;
|
|
1907
|
+
try {
|
|
1908
|
+
td.decode(et, { stream: true });
|
|
1909
|
+
tds = 1;
|
|
1910
|
+
} catch (e) {
|
|
1911
|
+
}
|
|
1912
|
+
var dutf8 = function(d) {
|
|
1913
|
+
for (var r = "", i2 = 0; ; ) {
|
|
1914
|
+
var c = d[i2++];
|
|
1915
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
1916
|
+
if (i2 + eb > d.length)
|
|
1917
|
+
return { s: r, r: slc(d, i2 - 1) };
|
|
1918
|
+
if (!eb)
|
|
1919
|
+
r += String.fromCharCode(c);
|
|
1920
|
+
else if (eb == 3) {
|
|
1921
|
+
c = ((c & 15) << 18 | (d[i2++] & 63) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63) - 65536, r += String.fromCharCode(55296 | c >> 10, 56320 | c & 1023);
|
|
1922
|
+
} else if (eb & 1)
|
|
1923
|
+
r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);
|
|
1924
|
+
else
|
|
1925
|
+
r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);
|
|
1453
1926
|
}
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1927
|
+
};
|
|
1928
|
+
function strToU8(str, latin1) {
|
|
1929
|
+
if (latin1) {
|
|
1930
|
+
var ar_1 = new u8(str.length);
|
|
1931
|
+
for (var i2 = 0; i2 < str.length; ++i2)
|
|
1932
|
+
ar_1[i2] = str.charCodeAt(i2);
|
|
1933
|
+
return ar_1;
|
|
1934
|
+
}
|
|
1935
|
+
if (te)
|
|
1936
|
+
return te.encode(str);
|
|
1937
|
+
var l = str.length;
|
|
1938
|
+
var ar = new u8(str.length + (str.length >> 1));
|
|
1939
|
+
var ai = 0;
|
|
1940
|
+
var w = function(v) {
|
|
1941
|
+
ar[ai++] = v;
|
|
1942
|
+
};
|
|
1943
|
+
for (var i2 = 0; i2 < l; ++i2) {
|
|
1944
|
+
if (ai + 5 > ar.length) {
|
|
1945
|
+
var n = new u8(ai + 8 + (l - i2 << 1));
|
|
1946
|
+
n.set(ar);
|
|
1947
|
+
ar = n;
|
|
1458
1948
|
}
|
|
1949
|
+
var c = str.charCodeAt(i2);
|
|
1950
|
+
if (c < 128 || latin1)
|
|
1951
|
+
w(c);
|
|
1952
|
+
else if (c < 2048)
|
|
1953
|
+
w(192 | c >> 6), w(128 | c & 63);
|
|
1954
|
+
else if (c > 55295 && c < 57344)
|
|
1955
|
+
c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i2) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1956
|
+
else
|
|
1957
|
+
w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1459
1958
|
}
|
|
1460
|
-
return
|
|
1461
|
-
};
|
|
1462
|
-
var _a = freb(fleb, 2);
|
|
1463
|
-
var fl = _a.b;
|
|
1464
|
-
var revfl = _a.r;
|
|
1465
|
-
fl[28] = 258, revfl[258] = 28;
|
|
1466
|
-
var _b = freb(fdeb, 0);
|
|
1467
|
-
var fd = _b.b;
|
|
1468
|
-
var revfd = _b.r;
|
|
1469
|
-
var rev = new u16(32768);
|
|
1470
|
-
for (i = 0; i < 32768; ++i) {
|
|
1471
|
-
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
1472
|
-
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
1473
|
-
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
1474
|
-
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
1959
|
+
return slc(ar, 0, ai);
|
|
1475
1960
|
}
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
var
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1961
|
+
function strFromU8(dat, latin1) {
|
|
1962
|
+
if (latin1) {
|
|
1963
|
+
var r = "";
|
|
1964
|
+
for (var i2 = 0; i2 < dat.length; i2 += 16384)
|
|
1965
|
+
r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));
|
|
1966
|
+
return r;
|
|
1967
|
+
} else if (td) {
|
|
1968
|
+
return td.decode(dat);
|
|
1969
|
+
} else {
|
|
1970
|
+
var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;
|
|
1971
|
+
if (r.length)
|
|
1972
|
+
err(8);
|
|
1973
|
+
return s;
|
|
1485
1974
|
}
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
// src/Base64.ts
|
|
1978
|
+
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1979
|
+
var LOOKUP = (() => {
|
|
1980
|
+
const table = new Int16Array(128).fill(-1);
|
|
1981
|
+
for (let index = 0; index < ALPHABET.length; index += 1) {
|
|
1982
|
+
table[ALPHABET.charCodeAt(index)] = index;
|
|
1983
|
+
}
|
|
1984
|
+
return table;
|
|
1985
|
+
})();
|
|
1986
|
+
function encodeBase64(bytes) {
|
|
1987
|
+
const parts = [];
|
|
1988
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
1989
|
+
const first = bytes[index];
|
|
1990
|
+
const second = bytes[index + 1];
|
|
1991
|
+
const third = bytes[index + 2];
|
|
1992
|
+
const triple = first << 16 | (second ?? 0) << 8 | (third ?? 0);
|
|
1993
|
+
parts.push(
|
|
1994
|
+
ALPHABET.charAt(triple >> 18 & 63) + ALPHABET.charAt(triple >> 12 & 63) + (second === void 0 ? "=" : ALPHABET.charAt(triple >> 6 & 63)) + (third === void 0 ? "=" : ALPHABET.charAt(triple & 63))
|
|
1995
|
+
);
|
|
1489
1996
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1997
|
+
return parts.join("");
|
|
1998
|
+
}
|
|
1999
|
+
function decodeBase64(text) {
|
|
2000
|
+
if (typeof text !== "string" || text.length % 4 !== 0) {
|
|
2001
|
+
return null;
|
|
2002
|
+
}
|
|
2003
|
+
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
2004
|
+
const bytes = new Uint8Array(text.length / 4 * 3 - padding);
|
|
2005
|
+
let buffer = 0;
|
|
2006
|
+
let bits2 = 0;
|
|
2007
|
+
let written = 0;
|
|
2008
|
+
for (let index = 0; index < text.length - padding; index += 1) {
|
|
2009
|
+
const code = text.charCodeAt(index);
|
|
2010
|
+
const value = code < 128 ? LOOKUP[code] : -1;
|
|
2011
|
+
if (value < 0) {
|
|
2012
|
+
return null;
|
|
1503
2013
|
}
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
2014
|
+
buffer = (buffer << 6 | value) & 16777215;
|
|
2015
|
+
bits2 += 6;
|
|
2016
|
+
if (bits2 >= 8) {
|
|
2017
|
+
bits2 -= 8;
|
|
2018
|
+
bytes[written] = buffer >> bits2 & 255;
|
|
2019
|
+
written += 1;
|
|
1510
2020
|
}
|
|
1511
2021
|
}
|
|
1512
|
-
return
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
var
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
for (i = 256; i < 280; ++i)
|
|
1522
|
-
flt[i] = 7;
|
|
1523
|
-
var i;
|
|
1524
|
-
for (i = 280; i < 288; ++i)
|
|
1525
|
-
flt[i] = 8;
|
|
1526
|
-
var i;
|
|
1527
|
-
var fdt = new u8(32);
|
|
1528
|
-
for (i = 0; i < 32; ++i)
|
|
1529
|
-
fdt[i] = 5;
|
|
1530
|
-
var i;
|
|
1531
|
-
var flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
1532
|
-
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
1533
|
-
var shft = function(p) {
|
|
1534
|
-
return (p + 7) / 8 | 0;
|
|
1535
|
-
};
|
|
1536
|
-
var slc = function(v, s, e) {
|
|
1537
|
-
if (s == null || s < 0)
|
|
1538
|
-
s = 0;
|
|
1539
|
-
if (e == null || e > v.length)
|
|
1540
|
-
e = v.length;
|
|
1541
|
-
return new u8(v.subarray(s, e));
|
|
1542
|
-
};
|
|
1543
|
-
var wbits = function(d, p, v) {
|
|
1544
|
-
v <<= p & 7;
|
|
1545
|
-
var o = p / 8 | 0;
|
|
1546
|
-
d[o] |= v;
|
|
1547
|
-
d[o + 1] |= v >> 8;
|
|
1548
|
-
};
|
|
1549
|
-
var wbits16 = function(d, p, v) {
|
|
1550
|
-
v <<= p & 7;
|
|
1551
|
-
var o = p / 8 | 0;
|
|
1552
|
-
d[o] |= v;
|
|
1553
|
-
d[o + 1] |= v >> 8;
|
|
1554
|
-
d[o + 2] |= v >> 16;
|
|
1555
|
-
};
|
|
1556
|
-
var hTree = function(d, mb) {
|
|
1557
|
-
var t = [];
|
|
1558
|
-
for (var i2 = 0; i2 < d.length; ++i2) {
|
|
1559
|
-
if (d[i2])
|
|
1560
|
-
t.push({ s: i2, f: d[i2] });
|
|
2022
|
+
return written === bytes.length ? bytes : null;
|
|
2023
|
+
}
|
|
2024
|
+
|
|
2025
|
+
// src/Outbox.ts
|
|
2026
|
+
var MAX_OUTBOX_ENTRIES = 240;
|
|
2027
|
+
var MAX_OUTBOX_BYTES = 3 * 1024 * 1024;
|
|
2028
|
+
function isEnvelope(value) {
|
|
2029
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2030
|
+
return false;
|
|
1561
2031
|
}
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
if (
|
|
1567
|
-
|
|
1568
|
-
v[t[0].s] = 1;
|
|
1569
|
-
return { t: v, l: 1 };
|
|
2032
|
+
const envelope = value;
|
|
2033
|
+
return typeof envelope.sessionId === "string" && typeof envelope.tabId === "string" && typeof envelope.chunkIndex === "number";
|
|
2034
|
+
}
|
|
2035
|
+
function isEntry(value) {
|
|
2036
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2037
|
+
return false;
|
|
1570
2038
|
}
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
while (i1 != s - 1) {
|
|
1578
|
-
l = t[t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1579
|
-
r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1580
|
-
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
2039
|
+
const entry = value;
|
|
2040
|
+
return typeof entry.id === "string" && Number.isSafeInteger(entry.attempts) && typeof entry.createdAtUnixMs === "number" && Number.isFinite(entry.createdAtUnixMs) && Number.isSafeInteger(entry.bytes);
|
|
2041
|
+
}
|
|
2042
|
+
function isLegacyFrame(value) {
|
|
2043
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2044
|
+
return false;
|
|
1581
2045
|
}
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
2046
|
+
const frame = value;
|
|
2047
|
+
return typeof frame.id === "string" && typeof frame.payload === "string" && typeof frame.attempts === "number" && Number.isSafeInteger(frame.attempts) && typeof frame.createdAtUnixMs === "number" && isEnvelope(frame.envelope);
|
|
2048
|
+
}
|
|
2049
|
+
function byOldest(left, right) {
|
|
2050
|
+
return left.createdAtUnixMs - right.createdAtUnixMs;
|
|
2051
|
+
}
|
|
2052
|
+
function frameId(envelope) {
|
|
2053
|
+
return `${envelope.sessionId}:${envelope.tabId}:${envelope.chunkIndex}`;
|
|
2054
|
+
}
|
|
2055
|
+
var ReplayOutbox = class {
|
|
2056
|
+
constructor(storage, namespace, now = Date.now) {
|
|
2057
|
+
__publicField(this, "storage");
|
|
2058
|
+
__publicField(this, "legacyKey");
|
|
2059
|
+
__publicField(this, "indexKey");
|
|
2060
|
+
__publicField(this, "framePrefix");
|
|
2061
|
+
__publicField(this, "now");
|
|
2062
|
+
__publicField(this, "mutationQueue", Promise.resolve());
|
|
2063
|
+
__publicField(this, "migrated", false);
|
|
2064
|
+
this.storage = storage;
|
|
2065
|
+
this.legacyKey = `@oneuptime/replay/${namespace}/outbox`;
|
|
2066
|
+
this.indexKey = `@oneuptime/replay/${namespace}/outbox-v2`;
|
|
2067
|
+
this.framePrefix = `@oneuptime/replay/${namespace}/outbox-v2/`;
|
|
2068
|
+
this.now = now;
|
|
1586
2069
|
}
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
var lft = mbt - mb, cst = 1 << lft;
|
|
1592
|
-
t2.sort(function(a, b) {
|
|
1593
|
-
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
2070
|
+
/* Every queued frame's index entry, oldest first. Reads no payload. */
|
|
2071
|
+
async entries() {
|
|
2072
|
+
return await this.withLock(async () => {
|
|
2073
|
+
return await this.readIndexUnlocked();
|
|
1594
2074
|
});
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
2075
|
+
}
|
|
2076
|
+
/*
|
|
2077
|
+
* One frame, ready to post. Null when it is no longer queued, and
|
|
2078
|
+
* "unreadable" when its value could not be read back - it is removed, so
|
|
2079
|
+
* one damaged frame never blocks the ones behind it.
|
|
2080
|
+
*/
|
|
2081
|
+
async load(id) {
|
|
2082
|
+
return await this.withLock(
|
|
2083
|
+
async () => {
|
|
2084
|
+
const entries = await this.readIndexUnlocked();
|
|
2085
|
+
const entry = entries.find(
|
|
2086
|
+
(candidate) => {
|
|
2087
|
+
return candidate.id === id;
|
|
2088
|
+
}
|
|
2089
|
+
);
|
|
2090
|
+
if (!entry) {
|
|
2091
|
+
return null;
|
|
2092
|
+
}
|
|
2093
|
+
const value = await this.readFrameUnlocked(id);
|
|
2094
|
+
if (!value) {
|
|
2095
|
+
await this.removeEntriesUnlocked(entries, [id]);
|
|
2096
|
+
return "unreadable";
|
|
2097
|
+
}
|
|
2098
|
+
return {
|
|
2099
|
+
id,
|
|
2100
|
+
envelope: value.envelope,
|
|
2101
|
+
compressedPayload: value.bytes,
|
|
2102
|
+
attempts: entry.attempts,
|
|
2103
|
+
createdAtUnixMs: entry.createdAtUnixMs
|
|
2104
|
+
};
|
|
2105
|
+
}
|
|
2106
|
+
);
|
|
2107
|
+
}
|
|
2108
|
+
/* Every frame with its payload decompressed, oldest first. */
|
|
2109
|
+
async list() {
|
|
2110
|
+
const frames = [];
|
|
2111
|
+
for (const entry of await this.entries()) {
|
|
2112
|
+
const frame = await this.load(
|
|
2113
|
+
entry.id
|
|
2114
|
+
);
|
|
2115
|
+
if (!frame || frame === "unreadable") {
|
|
2116
|
+
continue;
|
|
2117
|
+
}
|
|
2118
|
+
frames.push({
|
|
2119
|
+
id: frame.id,
|
|
2120
|
+
envelope: frame.envelope,
|
|
2121
|
+
payload: strFromU8(gunzipSync(frame.compressedPayload)),
|
|
2122
|
+
attempts: frame.attempts,
|
|
2123
|
+
createdAtUnixMs: frame.createdAtUnixMs
|
|
2124
|
+
});
|
|
1602
2125
|
}
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
2126
|
+
return frames;
|
|
2127
|
+
}
|
|
2128
|
+
/*
|
|
2129
|
+
* Queue a frame. Past MAX_OUTBOX_ENTRIES or MAX_OUTBOX_BYTES the OLDEST
|
|
2130
|
+
* frames are evicted - the newest seconds are the ones closest to whatever
|
|
2131
|
+
* went wrong, and a later full snapshot re-anchors the player after a gap -
|
|
2132
|
+
* and counted in `dropped`, as is a frame the device had no room to store.
|
|
2133
|
+
*/
|
|
2134
|
+
async enqueue(frame) {
|
|
2135
|
+
return await this.withLock(async () => {
|
|
2136
|
+
const entries = await this.readIndexUnlocked();
|
|
2137
|
+
if (entries.some((candidate) => {
|
|
2138
|
+
return candidate.id === frame.id;
|
|
2139
|
+
})) {
|
|
2140
|
+
return { dropped: 0 };
|
|
2141
|
+
}
|
|
2142
|
+
const bytes = await this.writeFrameUnlocked(frame);
|
|
2143
|
+
if (bytes === null) {
|
|
2144
|
+
return { dropped: 1 };
|
|
2145
|
+
}
|
|
2146
|
+
entries.push({
|
|
2147
|
+
id: frame.id,
|
|
2148
|
+
attempts: frame.attempts,
|
|
2149
|
+
createdAtUnixMs: frame.createdAtUnixMs,
|
|
2150
|
+
bytes
|
|
2151
|
+
});
|
|
2152
|
+
entries.sort(byOldest);
|
|
2153
|
+
let totalBytes = 0;
|
|
2154
|
+
for (const entry of entries) {
|
|
2155
|
+
totalBytes += entry.bytes;
|
|
2156
|
+
}
|
|
2157
|
+
const evicted = [];
|
|
2158
|
+
while (entries.length > 1 && (entries.length > MAX_OUTBOX_ENTRIES || totalBytes > MAX_OUTBOX_BYTES)) {
|
|
2159
|
+
const oldest = entries.shift();
|
|
2160
|
+
totalBytes -= oldest.bytes;
|
|
2161
|
+
evicted.push(oldest.id);
|
|
2162
|
+
}
|
|
2163
|
+
if (!await this.writeIndexUnlocked(entries)) {
|
|
2164
|
+
await this.safeRemove(this.frameKey(frame.id));
|
|
2165
|
+
return { dropped: 1 };
|
|
2166
|
+
}
|
|
2167
|
+
await Promise.all(
|
|
2168
|
+
evicted.map((id) => {
|
|
2169
|
+
return this.safeRemove(this.frameKey(id));
|
|
2170
|
+
})
|
|
2171
|
+
);
|
|
2172
|
+
return { dropped: evicted.length };
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
async remove(id) {
|
|
2176
|
+
await this.withLock(async () => {
|
|
2177
|
+
await this.removeEntriesUnlocked(await this.readIndexUnlocked(), [id]);
|
|
2178
|
+
});
|
|
2179
|
+
}
|
|
2180
|
+
async incrementAttempts(id) {
|
|
2181
|
+
return await this.withLock(async () => {
|
|
2182
|
+
const entries = await this.readIndexUnlocked();
|
|
2183
|
+
let attempts = 0;
|
|
2184
|
+
for (const entry of entries) {
|
|
2185
|
+
if (entry.id === id) {
|
|
2186
|
+
entry.attempts += 1;
|
|
2187
|
+
attempts = entry.attempts;
|
|
2188
|
+
break;
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2191
|
+
await this.writeIndexUnlocked(entries);
|
|
2192
|
+
return attempts;
|
|
2193
|
+
});
|
|
2194
|
+
}
|
|
2195
|
+
/*
|
|
2196
|
+
* Consent withdrawn, or the server refused this recorder for good: every
|
|
2197
|
+
* frame goes, including any a crash left untracked by the index when the
|
|
2198
|
+
* storage can list its keys.
|
|
2199
|
+
*/
|
|
2200
|
+
async clear() {
|
|
2201
|
+
await this.withLock(async () => {
|
|
2202
|
+
const keys = /* @__PURE__ */ new Set([
|
|
2203
|
+
this.legacyKey,
|
|
2204
|
+
this.indexKey
|
|
2205
|
+
]);
|
|
2206
|
+
for (const entry of await this.readRawIndexUnlocked()) {
|
|
2207
|
+
keys.add(this.frameKey(entry.id));
|
|
2208
|
+
}
|
|
2209
|
+
if (typeof this.storage.getAllKeys === "function") {
|
|
2210
|
+
try {
|
|
2211
|
+
for (const key of await this.storage.getAllKeys()) {
|
|
2212
|
+
if (key.startsWith(this.framePrefix)) {
|
|
2213
|
+
keys.add(key);
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
} catch {
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
this.migrated = true;
|
|
2220
|
+
await Promise.all(
|
|
2221
|
+
Array.from(keys).map((key) => {
|
|
2222
|
+
return this.safeRemove(key);
|
|
2223
|
+
})
|
|
2224
|
+
);
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
frameKey(id) {
|
|
2228
|
+
return `${this.framePrefix}${id}`;
|
|
2229
|
+
}
|
|
2230
|
+
/*
|
|
2231
|
+
* The index, with the legacy layout migrated into it on first use and
|
|
2232
|
+
* anything older than SESSION_REPLAY_MAX_OFFLINE_DELAY_MS pruned: the
|
|
2233
|
+
* server would no longer place it on the recording's real timeline.
|
|
2234
|
+
*/
|
|
2235
|
+
async readIndexUnlocked() {
|
|
2236
|
+
await this.migrateUnlocked();
|
|
2237
|
+
const entries = await this.readRawIndexUnlocked();
|
|
2238
|
+
const oldestKept = this.now() - SESSION_REPLAY_MAX_OFFLINE_DELAY_MS;
|
|
2239
|
+
const expired = entries.filter((entry) => {
|
|
2240
|
+
return entry.createdAtUnixMs < oldestKept;
|
|
2241
|
+
}).map((entry) => {
|
|
2242
|
+
return entry.id;
|
|
2243
|
+
});
|
|
2244
|
+
if (expired.length > 0) {
|
|
2245
|
+
await this.removeEntriesUnlocked(entries, expired);
|
|
1610
2246
|
}
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
2247
|
+
return entries.sort(byOldest);
|
|
2248
|
+
}
|
|
2249
|
+
async readRawIndexUnlocked() {
|
|
2250
|
+
let raw = null;
|
|
2251
|
+
try {
|
|
2252
|
+
raw = await this.storage.getItem(this.indexKey);
|
|
2253
|
+
} catch {
|
|
2254
|
+
raw = null;
|
|
2255
|
+
}
|
|
2256
|
+
if (!raw) {
|
|
2257
|
+
return [];
|
|
2258
|
+
}
|
|
2259
|
+
try {
|
|
2260
|
+
const parsed = JSON.parse(raw);
|
|
2261
|
+
if (Array.isArray(parsed) && parsed.every(isEntry)) {
|
|
2262
|
+
return parsed;
|
|
1616
2263
|
}
|
|
2264
|
+
} catch {
|
|
1617
2265
|
}
|
|
1618
|
-
|
|
2266
|
+
await this.safeRemove(this.indexKey);
|
|
2267
|
+
return [];
|
|
1619
2268
|
}
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
};
|
|
1634
|
-
for (var i2 = 1; i2 <= s; ++i2) {
|
|
1635
|
-
if (c[i2] == cln && i2 != s)
|
|
1636
|
-
++cls;
|
|
1637
|
-
else {
|
|
1638
|
-
if (!cln && cls > 2) {
|
|
1639
|
-
for (; cls > 138; cls -= 138)
|
|
1640
|
-
w(32754);
|
|
1641
|
-
if (cls > 2) {
|
|
1642
|
-
w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
|
|
1643
|
-
cls = 0;
|
|
1644
|
-
}
|
|
1645
|
-
} else if (cls > 3) {
|
|
1646
|
-
w(cln), --cls;
|
|
1647
|
-
for (; cls > 6; cls -= 6)
|
|
1648
|
-
w(8304);
|
|
1649
|
-
if (cls > 2)
|
|
1650
|
-
w(cls - 3 << 5 | 8208), cls = 0;
|
|
2269
|
+
async writeIndexUnlocked(entries) {
|
|
2270
|
+
if (entries.length === 0) {
|
|
2271
|
+
await this.safeRemove(this.indexKey);
|
|
2272
|
+
return true;
|
|
2273
|
+
}
|
|
2274
|
+
return await this.safeSet(this.indexKey, JSON.stringify(entries));
|
|
2275
|
+
}
|
|
2276
|
+
/* Drop entries from the index and their frames from storage. */
|
|
2277
|
+
async removeEntriesUnlocked(entries, ids) {
|
|
2278
|
+
const removing = new Set(ids);
|
|
2279
|
+
const kept = entries.filter(
|
|
2280
|
+
(entry) => {
|
|
2281
|
+
return !removing.has(entry.id);
|
|
1651
2282
|
}
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
2283
|
+
);
|
|
2284
|
+
entries.splice(0, entries.length, ...kept);
|
|
2285
|
+
await this.writeIndexUnlocked(entries);
|
|
2286
|
+
await Promise.all(
|
|
2287
|
+
ids.map((id) => {
|
|
2288
|
+
return this.safeRemove(this.frameKey(id));
|
|
2289
|
+
})
|
|
2290
|
+
);
|
|
2291
|
+
}
|
|
2292
|
+
/* Store one frame's value. Its size, or null when it could not be stored. */
|
|
2293
|
+
async writeFrameUnlocked(frame) {
|
|
2294
|
+
let value;
|
|
2295
|
+
try {
|
|
2296
|
+
const stored = {
|
|
2297
|
+
envelope: frame.envelope,
|
|
2298
|
+
gzip: encodeBase64(gzipSync(strToU8(frame.payload)))
|
|
2299
|
+
};
|
|
2300
|
+
value = JSON.stringify(stored);
|
|
2301
|
+
} catch {
|
|
2302
|
+
return null;
|
|
1656
2303
|
}
|
|
2304
|
+
return await this.safeSet(this.frameKey(frame.id), value) ? byteLength(value) : null;
|
|
1657
2305
|
}
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
l += cf[i2] * cl[i2];
|
|
1664
|
-
return l;
|
|
1665
|
-
};
|
|
1666
|
-
var wfblk = function(out, pos, dat) {
|
|
1667
|
-
var s = dat.length;
|
|
1668
|
-
var o = shft(pos + 2);
|
|
1669
|
-
out[o] = s & 255;
|
|
1670
|
-
out[o + 1] = s >> 8;
|
|
1671
|
-
out[o + 2] = out[o] ^ 255;
|
|
1672
|
-
out[o + 3] = out[o + 1] ^ 255;
|
|
1673
|
-
for (var i2 = 0; i2 < s; ++i2)
|
|
1674
|
-
out[o + i2 + 4] = dat[i2];
|
|
1675
|
-
return (o + 4 + s) * 8;
|
|
1676
|
-
};
|
|
1677
|
-
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
1678
|
-
wbits(out, p++, final);
|
|
1679
|
-
++lf[256];
|
|
1680
|
-
var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
|
|
1681
|
-
var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
|
|
1682
|
-
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
1683
|
-
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
1684
|
-
var lcfreq = new u16(19);
|
|
1685
|
-
for (var i2 = 0; i2 < lclt.length; ++i2)
|
|
1686
|
-
++lcfreq[lclt[i2] & 31];
|
|
1687
|
-
for (var i2 = 0; i2 < lcdt.length; ++i2)
|
|
1688
|
-
++lcfreq[lcdt[i2] & 31];
|
|
1689
|
-
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
1690
|
-
var nlcc = 19;
|
|
1691
|
-
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
1692
|
-
;
|
|
1693
|
-
var flen = bl + 5 << 3;
|
|
1694
|
-
var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
1695
|
-
var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
|
|
1696
|
-
if (bs >= 0 && flen <= ftlen && flen <= dtlen)
|
|
1697
|
-
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
1698
|
-
var lm, ll, dm, dl;
|
|
1699
|
-
wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
|
|
1700
|
-
if (dtlen < ftlen) {
|
|
1701
|
-
lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
|
|
1702
|
-
var llm = hMap(lct, mlcb, 0);
|
|
1703
|
-
wbits(out, p, nlc - 257);
|
|
1704
|
-
wbits(out, p + 5, ndc - 1);
|
|
1705
|
-
wbits(out, p + 10, nlcc - 4);
|
|
1706
|
-
p += 14;
|
|
1707
|
-
for (var i2 = 0; i2 < nlcc; ++i2)
|
|
1708
|
-
wbits(out, p + 3 * i2, lct[clim[i2]]);
|
|
1709
|
-
p += 3 * nlcc;
|
|
1710
|
-
var lcts = [lclt, lcdt];
|
|
1711
|
-
for (var it = 0; it < 2; ++it) {
|
|
1712
|
-
var clct = lcts[it];
|
|
1713
|
-
for (var i2 = 0; i2 < clct.length; ++i2) {
|
|
1714
|
-
var len = clct[i2] & 31;
|
|
1715
|
-
wbits(out, p, llm[len]), p += lct[len];
|
|
1716
|
-
if (len > 15)
|
|
1717
|
-
wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
|
|
2306
|
+
async readFrameUnlocked(id) {
|
|
2307
|
+
try {
|
|
2308
|
+
const raw = await this.storage.getItem(this.frameKey(id));
|
|
2309
|
+
if (!raw) {
|
|
2310
|
+
return null;
|
|
1718
2311
|
}
|
|
2312
|
+
const parsed = JSON.parse(
|
|
2313
|
+
raw
|
|
2314
|
+
);
|
|
2315
|
+
const bytes = typeof parsed.gzip === "string" ? decodeBase64(parsed.gzip) : null;
|
|
2316
|
+
if (!bytes || !isEnvelope(parsed.envelope)) {
|
|
2317
|
+
return null;
|
|
2318
|
+
}
|
|
2319
|
+
return { envelope: parsed.envelope, bytes };
|
|
2320
|
+
} catch {
|
|
2321
|
+
return null;
|
|
1719
2322
|
}
|
|
1720
|
-
} else {
|
|
1721
|
-
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
1722
2323
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
2324
|
+
/*
|
|
2325
|
+
* Move a queue written by an earlier SDK version (one JSON array under the
|
|
2326
|
+
* legacy key) into this layout, once. A legacy queue too large to read -
|
|
2327
|
+
* the very failure this layout exists to fix - cannot be recovered, only
|
|
2328
|
+
* removed so it stops failing.
|
|
2329
|
+
*/
|
|
2330
|
+
async migrateUnlocked() {
|
|
2331
|
+
if (this.migrated) {
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
this.migrated = true;
|
|
2335
|
+
let raw = null;
|
|
2336
|
+
try {
|
|
2337
|
+
raw = await this.storage.getItem(this.legacyKey);
|
|
2338
|
+
} catch {
|
|
2339
|
+
await this.safeRemove(this.legacyKey);
|
|
2340
|
+
return;
|
|
1736
2341
|
}
|
|
2342
|
+
if (!raw) {
|
|
2343
|
+
return;
|
|
2344
|
+
}
|
|
2345
|
+
let legacy = [];
|
|
2346
|
+
try {
|
|
2347
|
+
const parsed = JSON.parse(raw);
|
|
2348
|
+
if (Array.isArray(parsed)) {
|
|
2349
|
+
legacy = parsed.filter(isLegacyFrame);
|
|
2350
|
+
}
|
|
2351
|
+
} catch {
|
|
2352
|
+
legacy = [];
|
|
2353
|
+
}
|
|
2354
|
+
const entries = await this.readRawIndexUnlocked();
|
|
2355
|
+
for (const frame of legacy) {
|
|
2356
|
+
if (entries.some((entry) => {
|
|
2357
|
+
return entry.id === frame.id;
|
|
2358
|
+
})) {
|
|
2359
|
+
continue;
|
|
2360
|
+
}
|
|
2361
|
+
const bytes = await this.writeFrameUnlocked(frame);
|
|
2362
|
+
if (bytes !== null) {
|
|
2363
|
+
entries.push({
|
|
2364
|
+
id: frame.id,
|
|
2365
|
+
attempts: frame.attempts,
|
|
2366
|
+
createdAtUnixMs: frame.createdAtUnixMs,
|
|
2367
|
+
bytes
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
await this.writeIndexUnlocked(entries.sort(byOldest));
|
|
2372
|
+
await this.safeRemove(this.legacyKey);
|
|
1737
2373
|
}
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
var syms = new i32(25e3);
|
|
1761
|
-
var lf = new u16(288), df = new u16(32);
|
|
1762
|
-
var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
1763
|
-
for (; i2 + 2 < s; ++i2) {
|
|
1764
|
-
var hv = hsh(i2);
|
|
1765
|
-
var imod = i2 & 32767, pimod = head[hv];
|
|
1766
|
-
prev[imod] = pimod;
|
|
1767
|
-
head[hv] = imod;
|
|
1768
|
-
if (wi <= i2) {
|
|
1769
|
-
var rem = s - i2;
|
|
1770
|
-
if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
|
|
1771
|
-
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1772
|
-
li = lc_1 = eb = 0, bs = i2;
|
|
1773
|
-
for (var j = 0; j < 286; ++j)
|
|
1774
|
-
lf[j] = 0;
|
|
1775
|
-
for (var j = 0; j < 30; ++j)
|
|
1776
|
-
df[j] = 0;
|
|
1777
|
-
}
|
|
1778
|
-
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
1779
|
-
if (rem > 2 && hv == hsh(i2 - dif)) {
|
|
1780
|
-
var maxn = Math.min(n, rem) - 1;
|
|
1781
|
-
var maxd = Math.min(32767, i2);
|
|
1782
|
-
var ml = Math.min(258, rem);
|
|
1783
|
-
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
1784
|
-
if (dat[i2 + l] == dat[i2 + l - dif]) {
|
|
1785
|
-
var nl = 0;
|
|
1786
|
-
for (; nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
|
|
1787
|
-
;
|
|
1788
|
-
if (nl > l) {
|
|
1789
|
-
l = nl, d = dif;
|
|
1790
|
-
if (nl > maxn)
|
|
1791
|
-
break;
|
|
1792
|
-
var mmd = Math.min(dif, nl - 2);
|
|
1793
|
-
var md = 0;
|
|
1794
|
-
for (var j = 0; j < mmd; ++j) {
|
|
1795
|
-
var ti = i2 - dif + j & 32767;
|
|
1796
|
-
var pti = prev[ti];
|
|
1797
|
-
var cd = ti - pti & 32767;
|
|
1798
|
-
if (cd > md)
|
|
1799
|
-
md = cd, pimod = ti;
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
imod = pimod, pimod = prev[imod];
|
|
1804
|
-
dif += imod - pimod & 32767;
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
if (d) {
|
|
1808
|
-
syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
|
|
1809
|
-
var lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
1810
|
-
eb += fleb[lin] + fdeb[din];
|
|
1811
|
-
++lf[257 + lin];
|
|
1812
|
-
++df[din];
|
|
1813
|
-
wi = i2 + l;
|
|
1814
|
-
++lc_1;
|
|
1815
|
-
} else {
|
|
1816
|
-
syms[li++] = dat[i2];
|
|
1817
|
-
++lf[dat[i2]];
|
|
1818
|
-
}
|
|
2374
|
+
async safeSet(key, value) {
|
|
2375
|
+
try {
|
|
2376
|
+
await this.storage.setItem(key, value);
|
|
2377
|
+
return true;
|
|
2378
|
+
} catch {
|
|
2379
|
+
return false;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
async safeRemove(key) {
|
|
2383
|
+
try {
|
|
2384
|
+
await this.storage.removeItem(key);
|
|
2385
|
+
} catch {
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2388
|
+
async withLock(operation) {
|
|
2389
|
+
const result = this.mutationQueue.then(operation, operation);
|
|
2390
|
+
this.mutationQueue = result.then(
|
|
2391
|
+
() => {
|
|
2392
|
+
return void 0;
|
|
2393
|
+
},
|
|
2394
|
+
() => {
|
|
2395
|
+
return void 0;
|
|
1819
2396
|
}
|
|
2397
|
+
);
|
|
2398
|
+
return await result;
|
|
2399
|
+
}
|
|
2400
|
+
};
|
|
2401
|
+
|
|
2402
|
+
// src/Storage.ts
|
|
2403
|
+
var import_async_storage = __toESM(require("@react-native-async-storage/async-storage"));
|
|
2404
|
+
var REPLAY_ID_PATTERN = /^[0-9a-f]{32}$/u;
|
|
2405
|
+
var defaultReplayStorage = import_async_storage.default;
|
|
2406
|
+
function generateReplayId() {
|
|
2407
|
+
const bytes = new Uint8Array(16);
|
|
2408
|
+
const cryptoRef = globalThis.crypto;
|
|
2409
|
+
if (cryptoRef && typeof cryptoRef.getRandomValues === "function") {
|
|
2410
|
+
cryptoRef.getRandomValues(bytes);
|
|
2411
|
+
} else {
|
|
2412
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
2413
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
1820
2414
|
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
2415
|
+
}
|
|
2416
|
+
return Array.from(bytes).map((byte) => {
|
|
2417
|
+
return byte.toString(16).padStart(2, "0");
|
|
2418
|
+
}).join("");
|
|
2419
|
+
}
|
|
2420
|
+
function isReplayId(value) {
|
|
2421
|
+
return typeof value === "string" && REPLAY_ID_PATTERN.test(value);
|
|
2422
|
+
}
|
|
2423
|
+
function parseStoredSession(value) {
|
|
2424
|
+
if (!value) {
|
|
2425
|
+
return null;
|
|
2426
|
+
}
|
|
2427
|
+
try {
|
|
2428
|
+
const parsed = JSON.parse(value);
|
|
2429
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2430
|
+
return null;
|
|
2431
|
+
}
|
|
2432
|
+
const candidate = parsed;
|
|
2433
|
+
if (!isReplayId(candidate.sessionId) || !Number.isSafeInteger(candidate.sessionStartUnixMs) || !Number.isSafeInteger(candidate.lastActivityUnixMs) || !Number.isSafeInteger(candidate.nextChunkIndex) || (candidate.nextChunkIndex ?? -1) < 0) {
|
|
2434
|
+
return null;
|
|
2435
|
+
}
|
|
2436
|
+
return candidate;
|
|
2437
|
+
} catch {
|
|
2438
|
+
return null;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
var ReplaySessionStore = class {
|
|
2442
|
+
constructor(storage, namespace) {
|
|
2443
|
+
__publicField(this, "storage");
|
|
2444
|
+
__publicField(this, "sessionKey");
|
|
2445
|
+
__publicField(this, "visitorKey");
|
|
2446
|
+
__publicField(this, "identity", null);
|
|
2447
|
+
this.storage = storage;
|
|
2448
|
+
this.sessionKey = `@oneuptime/replay/${namespace}/session`;
|
|
2449
|
+
this.visitorKey = `@oneuptime/replay/${namespace}/visitor`;
|
|
2450
|
+
}
|
|
2451
|
+
async resolve(nowUnixMs) {
|
|
2452
|
+
const stored = parseStoredSession(
|
|
2453
|
+
await this.safeGet(this.sessionKey)
|
|
2454
|
+
);
|
|
2455
|
+
const shouldRotate = !stored || stored.nextChunkIndex >= MAX_SESSION_REPLAY_CHUNKS_PER_SESSION || nowUnixMs - stored.lastActivityUnixMs >= SESSION_REPLAY_IDLE_ROLLOVER_MS || nowUnixMs - stored.sessionStartUnixMs >= SESSION_REPLAY_MAX_SESSION_MS;
|
|
2456
|
+
let session;
|
|
2457
|
+
if (shouldRotate || !stored) {
|
|
2458
|
+
session = {
|
|
2459
|
+
sessionId: generateReplayId(),
|
|
2460
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2461
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2462
|
+
nextChunkIndex: 0
|
|
2463
|
+
};
|
|
2464
|
+
} else {
|
|
2465
|
+
session = {
|
|
2466
|
+
sessionId: stored.sessionId,
|
|
2467
|
+
sessionStartUnixMs: stored.sessionStartUnixMs,
|
|
2468
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2469
|
+
nextChunkIndex: stored.nextChunkIndex
|
|
2470
|
+
};
|
|
1824
2471
|
}
|
|
1825
|
-
|
|
1826
|
-
if (!
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
st.h = head, st.p = prev, st.i = i2, st.w = wi;
|
|
2472
|
+
let visitorId = await this.safeGet(this.visitorKey);
|
|
2473
|
+
if (!isReplayId(visitorId)) {
|
|
2474
|
+
visitorId = generateReplayId();
|
|
2475
|
+
await this.safeSet(this.visitorKey, visitorId);
|
|
1830
2476
|
}
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
2477
|
+
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
2478
|
+
this.identity = {
|
|
2479
|
+
sessionId: session.sessionId,
|
|
2480
|
+
tabId: generateReplayId(),
|
|
2481
|
+
visitorId,
|
|
2482
|
+
sessionStartUnixMs: session.sessionStartUnixMs,
|
|
2483
|
+
chunkIndex: session.nextChunkIndex
|
|
2484
|
+
};
|
|
2485
|
+
return { ...this.identity };
|
|
2486
|
+
}
|
|
2487
|
+
async takeChunkIndex(nowUnixMs) {
|
|
2488
|
+
if (!this.identity) {
|
|
2489
|
+
await this.resolve(nowUnixMs);
|
|
1839
2490
|
}
|
|
1840
|
-
|
|
2491
|
+
const identity = this.identity;
|
|
2492
|
+
const index = identity.chunkIndex;
|
|
2493
|
+
identity.chunkIndex += 1;
|
|
2494
|
+
const state = {
|
|
2495
|
+
sessionId: identity.sessionId,
|
|
2496
|
+
sessionStartUnixMs: identity.sessionStartUnixMs,
|
|
2497
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2498
|
+
nextChunkIndex: identity.chunkIndex
|
|
2499
|
+
};
|
|
2500
|
+
await this.safeSet(this.sessionKey, JSON.stringify(state));
|
|
2501
|
+
return index;
|
|
1841
2502
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
var crct = /* @__PURE__ */ (function() {
|
|
1845
|
-
var t = new Int32Array(256);
|
|
1846
|
-
for (var i2 = 0; i2 < 256; ++i2) {
|
|
1847
|
-
var c = i2, k = 9;
|
|
1848
|
-
while (--k)
|
|
1849
|
-
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
1850
|
-
t[i2] = c;
|
|
2503
|
+
getNextChunkIndex() {
|
|
2504
|
+
return this.identity?.chunkIndex ?? null;
|
|
1851
2505
|
}
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
p: function(d) {
|
|
1858
|
-
var cr = c;
|
|
1859
|
-
for (var i2 = 0; i2 < d.length; ++i2)
|
|
1860
|
-
cr = crct[cr & 255 ^ d[i2]] ^ cr >>> 8;
|
|
1861
|
-
c = cr;
|
|
1862
|
-
},
|
|
1863
|
-
d: function() {
|
|
1864
|
-
return ~c;
|
|
1865
|
-
}
|
|
1866
|
-
};
|
|
1867
|
-
};
|
|
1868
|
-
var dopt = function(dat, opt, pre, post, st) {
|
|
1869
|
-
if (!st) {
|
|
1870
|
-
st = { l: 1 };
|
|
1871
|
-
if (opt.dictionary) {
|
|
1872
|
-
var dict = opt.dictionary.subarray(-32768);
|
|
1873
|
-
var newDat = new u8(dict.length + dat.length);
|
|
1874
|
-
newDat.set(dict);
|
|
1875
|
-
newDat.set(dat, dict.length);
|
|
1876
|
-
dat = newDat;
|
|
1877
|
-
st.w = dict.length;
|
|
2506
|
+
async rotate(nowUnixMs) {
|
|
2507
|
+
let visitorId = await this.safeGet(this.visitorKey);
|
|
2508
|
+
if (!isReplayId(visitorId)) {
|
|
2509
|
+
visitorId = generateReplayId();
|
|
2510
|
+
await this.safeSet(this.visitorKey, visitorId);
|
|
1878
2511
|
}
|
|
2512
|
+
const session = {
|
|
2513
|
+
sessionId: generateReplayId(),
|
|
2514
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2515
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2516
|
+
nextChunkIndex: 0
|
|
2517
|
+
};
|
|
2518
|
+
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
2519
|
+
this.identity = {
|
|
2520
|
+
sessionId: session.sessionId,
|
|
2521
|
+
tabId: generateReplayId(),
|
|
2522
|
+
visitorId,
|
|
2523
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2524
|
+
chunkIndex: 0
|
|
2525
|
+
};
|
|
2526
|
+
return { ...this.identity };
|
|
1879
2527
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
var gzh = function(c, o) {
|
|
1887
|
-
var fn = o.filename;
|
|
1888
|
-
c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3;
|
|
1889
|
-
if (o.mtime != 0)
|
|
1890
|
-
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1e3));
|
|
1891
|
-
if (fn) {
|
|
1892
|
-
c[3] = 8;
|
|
1893
|
-
for (var i2 = 0; i2 <= fn.length; ++i2)
|
|
1894
|
-
c[i2 + 10] = fn.charCodeAt(i2);
|
|
2528
|
+
async clear() {
|
|
2529
|
+
this.identity = null;
|
|
2530
|
+
await Promise.all([
|
|
2531
|
+
this.safeRemove(this.sessionKey),
|
|
2532
|
+
this.safeRemove(this.visitorKey)
|
|
2533
|
+
]);
|
|
1895
2534
|
}
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
}
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
opts = {};
|
|
1903
|
-
var c = crc(), l = data.length;
|
|
1904
|
-
c.p(data);
|
|
1905
|
-
var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
1906
|
-
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
1907
|
-
}
|
|
1908
|
-
var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
|
|
1909
|
-
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1910
|
-
var tds = 0;
|
|
1911
|
-
try {
|
|
1912
|
-
td.decode(et, { stream: true });
|
|
1913
|
-
tds = 1;
|
|
1914
|
-
} catch (e) {
|
|
1915
|
-
}
|
|
1916
|
-
function strToU8(str, latin1) {
|
|
1917
|
-
if (latin1) {
|
|
1918
|
-
var ar_1 = new u8(str.length);
|
|
1919
|
-
for (var i2 = 0; i2 < str.length; ++i2)
|
|
1920
|
-
ar_1[i2] = str.charCodeAt(i2);
|
|
1921
|
-
return ar_1;
|
|
2535
|
+
async safeGet(key) {
|
|
2536
|
+
try {
|
|
2537
|
+
return await this.storage.getItem(key);
|
|
2538
|
+
} catch {
|
|
2539
|
+
return null;
|
|
2540
|
+
}
|
|
1922
2541
|
}
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
var ai = 0;
|
|
1928
|
-
var w = function(v) {
|
|
1929
|
-
ar[ai++] = v;
|
|
1930
|
-
};
|
|
1931
|
-
for (var i2 = 0; i2 < l; ++i2) {
|
|
1932
|
-
if (ai + 5 > ar.length) {
|
|
1933
|
-
var n = new u8(ai + 8 + (l - i2 << 1));
|
|
1934
|
-
n.set(ar);
|
|
1935
|
-
ar = n;
|
|
2542
|
+
async safeSet(key, value) {
|
|
2543
|
+
try {
|
|
2544
|
+
await this.storage.setItem(key, value);
|
|
2545
|
+
} catch {
|
|
1936
2546
|
}
|
|
1937
|
-
var c = str.charCodeAt(i2);
|
|
1938
|
-
if (c < 128 || latin1)
|
|
1939
|
-
w(c);
|
|
1940
|
-
else if (c < 2048)
|
|
1941
|
-
w(192 | c >> 6), w(128 | c & 63);
|
|
1942
|
-
else if (c > 55295 && c < 57344)
|
|
1943
|
-
c = 65536 + (c & 1023 << 10) | str.charCodeAt(++i2) & 1023, w(240 | c >> 18), w(128 | c >> 12 & 63), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1944
|
-
else
|
|
1945
|
-
w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1946
2547
|
}
|
|
1947
|
-
|
|
1948
|
-
|
|
2548
|
+
async safeRemove(key) {
|
|
2549
|
+
try {
|
|
2550
|
+
await this.storage.removeItem(key);
|
|
2551
|
+
} catch {
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
1949
2555
|
|
|
1950
2556
|
// src/Transport.ts
|
|
1951
2557
|
var MAX_ATTEMPTS_PER_FRAME = 3;
|
|
1952
2558
|
var DEFAULT_RETRY_MS = 15e3;
|
|
1953
2559
|
var MAX_RETRY_MS = 5 * 6e4;
|
|
1954
2560
|
var CHUNK_POST_TIMEOUT_MS = 1e4;
|
|
2561
|
+
var OFFLINE_RETRY_MS = [5e3, 15e3, 3e4, 6e4];
|
|
1955
2562
|
var DIRECTIVE_REASON_PATTERN = /^[A-Za-z0-9_.:-]{1,100}$/u;
|
|
1956
|
-
function
|
|
1957
|
-
const compressed = gzipSync(strToU8(payload));
|
|
2563
|
+
function encodeCompressedReplayFrame(originalEnvelope, compressed) {
|
|
1958
2564
|
const envelope = {
|
|
1959
2565
|
...originalEnvelope,
|
|
1960
2566
|
payloadEncoding: "gzip",
|
|
1961
2567
|
payloadBytes: compressed.byteLength,
|
|
1962
2568
|
clientSendUnixMs: Date.now()
|
|
1963
2569
|
};
|
|
1964
|
-
const prefix = strToU8(
|
|
1965
|
-
`);
|
|
2570
|
+
const prefix = strToU8(encodeSessionReplayEnvelopeLine(envelope));
|
|
1966
2571
|
const body = new Uint8Array(
|
|
1967
2572
|
prefix.byteLength + compressed.byteLength
|
|
1968
2573
|
);
|
|
@@ -2027,9 +2632,47 @@ var ReplayTransport = class {
|
|
|
2027
2632
|
__publicField(this, "retryAfterDrainMs", null);
|
|
2028
2633
|
__publicField(this, "activeAbortController", null);
|
|
2029
2634
|
__publicField(this, "abortCurrentRequest", null);
|
|
2635
|
+
/* Requests in a row that never reached the server. */
|
|
2636
|
+
__publicField(this, "connectivityFailures", 0);
|
|
2637
|
+
/* What the host app's connectivity source last said, if it has one. */
|
|
2638
|
+
__publicField(this, "reportedOffline", false);
|
|
2030
2639
|
this.options = options;
|
|
2031
2640
|
this.fetch = options.startOptions.fetch;
|
|
2032
2641
|
}
|
|
2642
|
+
/*
|
|
2643
|
+
* Offline, as far as uploading goes: the host app's connectivity source
|
|
2644
|
+
* says so, or the last request never reached the server.
|
|
2645
|
+
*/
|
|
2646
|
+
isOffline() {
|
|
2647
|
+
return this.reportedOffline || this.connectivityFailures > 0;
|
|
2648
|
+
}
|
|
2649
|
+
/*
|
|
2650
|
+
* The host app's connectivity source changed (NetInfo, typically). While
|
|
2651
|
+
* it says offline nothing is attempted. Coming back does NOT drain on its
|
|
2652
|
+
* own: whether this recorder may upload right now (consent) is the
|
|
2653
|
+
* recorder's decision, so it calls resume() itself. null means "unknown",
|
|
2654
|
+
* which blocks nothing.
|
|
2655
|
+
*/
|
|
2656
|
+
setConnectivity(isConnected) {
|
|
2657
|
+
this.reportedOffline = isConnected === false;
|
|
2658
|
+
}
|
|
2659
|
+
/*
|
|
2660
|
+
* Drain now rather than on the retry timer: the app came to the
|
|
2661
|
+
* foreground, or the network came back. An offline wait ends; a server
|
|
2662
|
+
* throttle still stands.
|
|
2663
|
+
*/
|
|
2664
|
+
resume() {
|
|
2665
|
+
if (this.stopped || this.reportedOffline) {
|
|
2666
|
+
return;
|
|
2667
|
+
}
|
|
2668
|
+
if (this.connectivityFailures > 0 && this.retryTimer) {
|
|
2669
|
+
clearTimeout(this.retryTimer);
|
|
2670
|
+
this.retryTimer = null;
|
|
2671
|
+
}
|
|
2672
|
+
if (!this.retryTimer) {
|
|
2673
|
+
void this.drain();
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2033
2676
|
async enqueue(envelope, payload) {
|
|
2034
2677
|
if (this.stopped) {
|
|
2035
2678
|
return;
|
|
@@ -2046,13 +2689,15 @@ var ReplayTransport = class {
|
|
|
2046
2689
|
dropped: mutation.dropped
|
|
2047
2690
|
});
|
|
2048
2691
|
}
|
|
2049
|
-
|
|
2692
|
+
if (!this.retryTimer) {
|
|
2693
|
+
await this.drain();
|
|
2694
|
+
}
|
|
2050
2695
|
}
|
|
2051
2696
|
async restore() {
|
|
2052
2697
|
await this.drain();
|
|
2053
2698
|
}
|
|
2054
2699
|
async drain() {
|
|
2055
|
-
if (this.stopped) {
|
|
2700
|
+
if (this.stopped || this.reportedOffline) {
|
|
2056
2701
|
return;
|
|
2057
2702
|
}
|
|
2058
2703
|
if (this.drainPromise) {
|
|
@@ -2081,11 +2726,19 @@ var ReplayTransport = class {
|
|
|
2081
2726
|
return this.flushFailures;
|
|
2082
2727
|
}
|
|
2083
2728
|
async drainLoop() {
|
|
2084
|
-
const
|
|
2085
|
-
for (const
|
|
2086
|
-
if (this.stopped) {
|
|
2729
|
+
const entries = await this.options.outbox.entries();
|
|
2730
|
+
for (const entry of entries) {
|
|
2731
|
+
if (this.stopped || this.reportedOffline) {
|
|
2087
2732
|
return;
|
|
2088
2733
|
}
|
|
2734
|
+
const frame = await this.options.outbox.load(entry.id);
|
|
2735
|
+
if (frame === "unreadable") {
|
|
2736
|
+
this.options.onDiagnostic("outbox-frame-unreadable");
|
|
2737
|
+
continue;
|
|
2738
|
+
}
|
|
2739
|
+
if (!frame) {
|
|
2740
|
+
continue;
|
|
2741
|
+
}
|
|
2089
2742
|
const outcome = await this.post(frame);
|
|
2090
2743
|
if (outcome === "remove") {
|
|
2091
2744
|
await this.options.outbox.remove(frame.id);
|
|
@@ -2098,10 +2751,13 @@ var ReplayTransport = class {
|
|
|
2098
2751
|
if (outcome === "stop") {
|
|
2099
2752
|
return;
|
|
2100
2753
|
}
|
|
2754
|
+
this.flushFailures += 1;
|
|
2755
|
+
if (outcome === "wait") {
|
|
2756
|
+
return;
|
|
2757
|
+
}
|
|
2101
2758
|
const attempts = await this.options.outbox.incrementAttempts(
|
|
2102
2759
|
frame.id
|
|
2103
2760
|
);
|
|
2104
|
-
this.flushFailures += 1;
|
|
2105
2761
|
if (attempts >= MAX_ATTEMPTS_PER_FRAME) {
|
|
2106
2762
|
await this.options.outbox.remove(frame.id);
|
|
2107
2763
|
this.options.onDiagnostic("chunk-retry-exhausted", {
|
|
@@ -2116,9 +2772,9 @@ var ReplayTransport = class {
|
|
|
2116
2772
|
}
|
|
2117
2773
|
}
|
|
2118
2774
|
async post(frame) {
|
|
2119
|
-
const encoded =
|
|
2775
|
+
const encoded = encodeCompressedReplayFrame(
|
|
2120
2776
|
frame.envelope,
|
|
2121
|
-
frame.
|
|
2777
|
+
frame.compressedPayload
|
|
2122
2778
|
);
|
|
2123
2779
|
if (encoded.body.byteLength > MAX_SESSION_REPLAY_CHUNK_BYTES) {
|
|
2124
2780
|
this.options.onDiagnostic("chunk-too-large", {
|
|
@@ -2177,7 +2833,9 @@ var ReplayTransport = class {
|
|
|
2177
2833
|
chunkIndex: frame.envelope.chunkIndex
|
|
2178
2834
|
}
|
|
2179
2835
|
);
|
|
2180
|
-
|
|
2836
|
+
this.connectivityFailures += 1;
|
|
2837
|
+
this.retryAfterDrainMs = OFFLINE_RETRY_MS[Math.min(this.connectivityFailures, OFFLINE_RETRY_MS.length) - 1];
|
|
2838
|
+
return "wait";
|
|
2181
2839
|
} finally {
|
|
2182
2840
|
if (timeout) {
|
|
2183
2841
|
clearTimeout(timeout);
|
|
@@ -2189,6 +2847,10 @@ var ReplayTransport = class {
|
|
|
2189
2847
|
this.abortCurrentRequest = null;
|
|
2190
2848
|
}
|
|
2191
2849
|
}
|
|
2850
|
+
if (this.connectivityFailures > 0) {
|
|
2851
|
+
this.connectivityFailures = 0;
|
|
2852
|
+
this.options.onDiagnostic("back-online");
|
|
2853
|
+
}
|
|
2192
2854
|
if (said.directive) {
|
|
2193
2855
|
this.options.onDirective(said.directive, said.reason);
|
|
2194
2856
|
}
|
|
@@ -2230,6 +2892,9 @@ var ReplayTransport = class {
|
|
|
2230
2892
|
(said.retryAfterSeconds ?? DEFAULT_RETRY_MS / 1e3) * 1e3
|
|
2231
2893
|
);
|
|
2232
2894
|
this.retryAfterDrainMs = retryMs;
|
|
2895
|
+
if (response.status === 429 || said.directive === "throttle" || said.retryAfterSeconds !== null) {
|
|
2896
|
+
return "wait";
|
|
2897
|
+
}
|
|
2233
2898
|
return "retry";
|
|
2234
2899
|
}
|
|
2235
2900
|
scheduleRetry(delayMs) {
|
|
@@ -2413,6 +3078,21 @@ var MobileReplayRecorder = class {
|
|
|
2413
3078
|
__publicField(this, "captureTimer", null);
|
|
2414
3079
|
__publicField(this, "flushTimer", null);
|
|
2415
3080
|
__publicField(this, "appStateSubscription", null);
|
|
3081
|
+
/*
|
|
3082
|
+
* Offline mode: the host app's connectivity source (start option
|
|
3083
|
+
* `connectivity`), and what it last said, which a transport created later
|
|
3084
|
+
* - after a consent or identity change - starts from.
|
|
3085
|
+
*/
|
|
3086
|
+
__publicField(this, "unsubscribeConnectivity", null);
|
|
3087
|
+
__publicField(this, "lastConnectivity", null);
|
|
3088
|
+
/*
|
|
3089
|
+
* The policy in force is the cached one an offline launch started with,
|
|
3090
|
+
* or the last refresh could not reach the server. Refreshed the moment the
|
|
3091
|
+
* connection is back rather than on the five-minute schedule, so a policy
|
|
3092
|
+
* changed while the device was offline takes effect before its backlog
|
|
3093
|
+
* has finished uploading.
|
|
3094
|
+
*/
|
|
3095
|
+
__publicField(this, "policyStale", false);
|
|
2416
3096
|
__publicField(this, "captureGeneration", null);
|
|
2417
3097
|
__publicField(this, "running", false);
|
|
2418
3098
|
__publicField(this, "foreground", true);
|
|
@@ -2549,11 +3229,32 @@ var MobileReplayRecorder = class {
|
|
|
2549
3229
|
});
|
|
2550
3230
|
return false;
|
|
2551
3231
|
}
|
|
3232
|
+
const namespace = getReplayStorageNamespace(validated);
|
|
2552
3233
|
let config = await fetchReplayConfig(this.options);
|
|
2553
3234
|
if (!this.isCurrentGeneration(generation)) {
|
|
2554
3235
|
return false;
|
|
2555
3236
|
}
|
|
2556
|
-
|
|
3237
|
+
let configFromCache = false;
|
|
3238
|
+
if (isRetryablePolicyFailure(config)) {
|
|
3239
|
+
const cached = await loadCachedReplayConfig(
|
|
3240
|
+
this.storage,
|
|
3241
|
+
namespace,
|
|
3242
|
+
this.now()
|
|
3243
|
+
);
|
|
3244
|
+
if (!this.isCurrentGeneration(generation)) {
|
|
3245
|
+
return false;
|
|
3246
|
+
}
|
|
3247
|
+
if (cached) {
|
|
3248
|
+
this.diagnostic("config-from-cache", {
|
|
3249
|
+
reason: config.disabledReason ?? "not-reported"
|
|
3250
|
+
});
|
|
3251
|
+
config = cached;
|
|
3252
|
+
configFromCache = true;
|
|
3253
|
+
}
|
|
3254
|
+
} else if (this.mayPersistUnder(config)) {
|
|
3255
|
+
await saveReplayConfig(this.storage, namespace, config, this.now());
|
|
3256
|
+
}
|
|
3257
|
+
if (!configFromCache && config.enabled && this.userRef && (config.consentMode === "NotRequired" /* NotRequired */ || this.consentGranted)) {
|
|
2557
3258
|
config = await this.refreshTargetingConfig(config);
|
|
2558
3259
|
if (!this.isCurrentGeneration(generation)) {
|
|
2559
3260
|
return false;
|
|
@@ -2566,8 +3267,8 @@ var MobileReplayRecorder = class {
|
|
|
2566
3267
|
});
|
|
2567
3268
|
return false;
|
|
2568
3269
|
}
|
|
2569
|
-
this.lastPolicyRefreshAtUnixMs = this.now();
|
|
2570
|
-
|
|
3270
|
+
this.lastPolicyRefreshAtUnixMs = configFromCache ? 0 : this.now();
|
|
3271
|
+
this.policyStale = configFromCache;
|
|
2571
3272
|
const sessionStore = new ReplaySessionStore(
|
|
2572
3273
|
this.storage,
|
|
2573
3274
|
namespace
|
|
@@ -2596,8 +3297,9 @@ var MobileReplayRecorder = class {
|
|
|
2596
3297
|
this.disable("not-sampled");
|
|
2597
3298
|
return false;
|
|
2598
3299
|
}
|
|
2599
|
-
this.outbox = new ReplayOutbox(this.storage, namespace);
|
|
3300
|
+
this.outbox = new ReplayOutbox(this.storage, namespace, this.now);
|
|
2600
3301
|
this.transport = this.createTransport(validated, this.outbox);
|
|
3302
|
+
this.subscribeConnectivity(validated);
|
|
2601
3303
|
try {
|
|
2602
3304
|
const nativeMetadata = await this.nativeViewTree.getAppMetadata();
|
|
2603
3305
|
if (!this.isCurrentGeneration(generation)) {
|
|
@@ -2747,6 +3449,7 @@ var MobileReplayRecorder = class {
|
|
|
2747
3449
|
});
|
|
2748
3450
|
await this.outbox?.clear();
|
|
2749
3451
|
await this.sessionStore?.clear();
|
|
3452
|
+
await this.forgetCachedConfig();
|
|
2750
3453
|
this.identity = null;
|
|
2751
3454
|
this.userRef = null;
|
|
2752
3455
|
this.traits = {};
|
|
@@ -3360,6 +4063,9 @@ var MobileReplayRecorder = class {
|
|
|
3360
4063
|
this.startTimers();
|
|
3361
4064
|
this.diagnosticsStatus = this.consentState() === "Unknown" ? "consent-required" : "recording";
|
|
3362
4065
|
await this.captureTick(true);
|
|
4066
|
+
if (this.uploadActive && this.running) {
|
|
4067
|
+
this.transport?.resume();
|
|
4068
|
+
}
|
|
3363
4069
|
}
|
|
3364
4070
|
}
|
|
3365
4071
|
startTimers() {
|
|
@@ -3421,7 +4127,7 @@ var MobileReplayRecorder = class {
|
|
|
3421
4127
|
this.installedGlobalErrorHandler = null;
|
|
3422
4128
|
}
|
|
3423
4129
|
createTransport(startOptions, outbox) {
|
|
3424
|
-
|
|
4130
|
+
const transport = new ReplayTransport({
|
|
3425
4131
|
startOptions,
|
|
3426
4132
|
outbox,
|
|
3427
4133
|
onDirective: (directive, reason) => {
|
|
@@ -3429,8 +4135,15 @@ var MobileReplayRecorder = class {
|
|
|
3429
4135
|
},
|
|
3430
4136
|
onDiagnostic: (code, details) => {
|
|
3431
4137
|
this.diagnostic(code, details);
|
|
4138
|
+
if (code === "back-online") {
|
|
4139
|
+
this.onBackOnline();
|
|
4140
|
+
}
|
|
3432
4141
|
}
|
|
3433
4142
|
});
|
|
4143
|
+
if (this.lastConnectivity !== null) {
|
|
4144
|
+
transport.setConnectivity(this.lastConnectivity);
|
|
4145
|
+
}
|
|
4146
|
+
return transport;
|
|
3434
4147
|
}
|
|
3435
4148
|
onDirective(directive, reason) {
|
|
3436
4149
|
this.diagnostic("server-directive", { directive, reason });
|
|
@@ -3469,8 +4182,76 @@ var MobileReplayRecorder = class {
|
|
|
3469
4182
|
this.clearTimers();
|
|
3470
4183
|
this.appStateSubscription?.remove();
|
|
3471
4184
|
this.appStateSubscription = null;
|
|
4185
|
+
this.stopConnectivity();
|
|
3472
4186
|
this.restoreGlobalErrorHandler();
|
|
3473
4187
|
}
|
|
4188
|
+
/*
|
|
4189
|
+
* Whether this device may be written to under a policy. Nothing is stored
|
|
4190
|
+
* before an explicit consent the policy requires - the cached policy
|
|
4191
|
+
* included, even though it holds no user data - except a removal: a
|
|
4192
|
+
* policy that says replay is off always deletes the cached one.
|
|
4193
|
+
*/
|
|
4194
|
+
/*
|
|
4195
|
+
* The cached policy goes with everything else when consent does: it holds
|
|
4196
|
+
* no user data, but "nothing of the recorder stays on the device" is the
|
|
4197
|
+
* promise, and the next consented policy fetch writes it again.
|
|
4198
|
+
*/
|
|
4199
|
+
async forgetCachedConfig() {
|
|
4200
|
+
if (this.options) {
|
|
4201
|
+
await forgetReplayConfig(
|
|
4202
|
+
this.storage,
|
|
4203
|
+
getReplayStorageNamespace(this.options)
|
|
4204
|
+
);
|
|
4205
|
+
}
|
|
4206
|
+
}
|
|
4207
|
+
mayPersistUnder(config) {
|
|
4208
|
+
return !config.enabled || config.consentMode === "NotRequired" /* NotRequired */ || this.consentGranted;
|
|
4209
|
+
}
|
|
4210
|
+
subscribeConnectivity(options) {
|
|
4211
|
+
this.stopConnectivity();
|
|
4212
|
+
this.lastConnectivity = null;
|
|
4213
|
+
if (!options.connectivity) {
|
|
4214
|
+
return;
|
|
4215
|
+
}
|
|
4216
|
+
try {
|
|
4217
|
+
const unsubscribe = options.connectivity.subscribe(
|
|
4218
|
+
(isConnected) => {
|
|
4219
|
+
const connected = typeof isConnected === "boolean" ? isConnected : null;
|
|
4220
|
+
if (connected === this.lastConnectivity) {
|
|
4221
|
+
return;
|
|
4222
|
+
}
|
|
4223
|
+
this.lastConnectivity = connected;
|
|
4224
|
+
if (connected !== null) {
|
|
4225
|
+
this.diagnostic(connected ? "network-online" : "network-offline");
|
|
4226
|
+
}
|
|
4227
|
+
this.transport?.setConnectivity(connected);
|
|
4228
|
+
if (connected === true) {
|
|
4229
|
+
this.onBackOnline();
|
|
4230
|
+
if (this.uploadActive && this.running) {
|
|
4231
|
+
this.transport?.resume();
|
|
4232
|
+
}
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
);
|
|
4236
|
+
this.unsubscribeConnectivity = typeof unsubscribe === "function" ? unsubscribe : null;
|
|
4237
|
+
} catch {
|
|
4238
|
+
this.diagnostic("connectivity-subscribe-failed");
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
/* The next capture tick refreshes a stale policy (see policyStale). */
|
|
4242
|
+
onBackOnline() {
|
|
4243
|
+
if (this.policyStale) {
|
|
4244
|
+
this.lastPolicyRefreshAtUnixMs = 0;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
stopConnectivity() {
|
|
4248
|
+
const unsubscribe = this.unsubscribeConnectivity;
|
|
4249
|
+
this.unsubscribeConnectivity = null;
|
|
4250
|
+
try {
|
|
4251
|
+
unsubscribe?.();
|
|
4252
|
+
} catch {
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
3474
4255
|
isCurrentGeneration(generation) {
|
|
3475
4256
|
return generation === this.lifecycleGeneration;
|
|
3476
4257
|
}
|
|
@@ -3701,11 +4482,23 @@ var MobileReplayRecorder = class {
|
|
|
3701
4482
|
}
|
|
3702
4483
|
}
|
|
3703
4484
|
this.lastPolicyRefreshAtUnixMs = nowUnixMs;
|
|
4485
|
+
if (!isRetryablePolicyFailure(freshConfig) && this.mayPersistUnder(freshConfig)) {
|
|
4486
|
+
await saveReplayConfig(
|
|
4487
|
+
this.storage,
|
|
4488
|
+
getReplayStorageNamespace(currentOptions),
|
|
4489
|
+
freshConfig,
|
|
4490
|
+
nowUnixMs
|
|
4491
|
+
);
|
|
4492
|
+
if (!this.running || !this.isCurrentGeneration(generation)) {
|
|
4493
|
+
return false;
|
|
4494
|
+
}
|
|
4495
|
+
}
|
|
3704
4496
|
if (!freshConfig.enabled) {
|
|
3705
4497
|
if (reason !== "consent" && isRetryablePolicyFailure(freshConfig)) {
|
|
3706
4498
|
this.diagnostic("policy-refresh-failed-using-last-config", {
|
|
3707
4499
|
reason
|
|
3708
4500
|
});
|
|
4501
|
+
this.policyStale = true;
|
|
3709
4502
|
return true;
|
|
3710
4503
|
}
|
|
3711
4504
|
this.config = freshConfig;
|
|
@@ -3715,6 +4508,7 @@ var MobileReplayRecorder = class {
|
|
|
3715
4508
|
);
|
|
3716
4509
|
return false;
|
|
3717
4510
|
}
|
|
4511
|
+
this.policyStale = false;
|
|
3718
4512
|
return await this.applyRuntimePolicy(
|
|
3719
4513
|
previousConfig,
|
|
3720
4514
|
freshConfig,
|
|
@@ -3761,6 +4555,7 @@ var MobileReplayRecorder = class {
|
|
|
3761
4555
|
});
|
|
3762
4556
|
await this.outbox?.clear();
|
|
3763
4557
|
await this.sessionStore?.clear();
|
|
4558
|
+
await this.forgetCachedConfig();
|
|
3764
4559
|
if (!this.running || !this.isCurrentGeneration(generation)) {
|
|
3765
4560
|
return false;
|
|
3766
4561
|
}
|