@oneuptime/react-native-replay 14.0.0 → 14.0.2
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.js
CHANGED
|
@@ -20,7 +20,23 @@ import { AppState } from "react-native";
|
|
|
20
20
|
// src/Contract.ts
|
|
21
21
|
var SESSION_REPLAY_WIRE_VERSION = 1;
|
|
22
22
|
var SESSION_REPLAY_SCHEMA_VERSION = 1;
|
|
23
|
-
var SESSION_REPLAY_CONTENT_TYPE = "application/
|
|
23
|
+
var SESSION_REPLAY_CONTENT_TYPE = "application/octet-stream";
|
|
24
|
+
var SESSION_REPLAY_ENVELOPE_TERMINATOR = " \n";
|
|
25
|
+
var ESCAPED_SEQUENCES = /[%&]|(http)\//gi;
|
|
26
|
+
function escapeSessionReplayJson(json) {
|
|
27
|
+
return json.replace(
|
|
28
|
+
ESCAPED_SEQUENCES,
|
|
29
|
+
(match, http) => {
|
|
30
|
+
if (http !== void 0) {
|
|
31
|
+
return `${http}\\/`;
|
|
32
|
+
}
|
|
33
|
+
return match === "%" ? "\\u0025" : "\\u0026";
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
function encodeSessionReplayEnvelopeLine(envelope) {
|
|
38
|
+
return escapeSessionReplayJson(JSON.stringify(envelope)) + SESSION_REPLAY_ENVELOPE_TERMINATOR;
|
|
39
|
+
}
|
|
24
40
|
var SESSION_REPLAY_APP_IDENTIFIER_HEADER = "x-oneuptime-app-identifier";
|
|
25
41
|
var SESSION_REPLAY_RECORDER_KIND_HEADER = "x-oneuptime-replay-recorder-kind";
|
|
26
42
|
var SESSION_REPLAY_MOBILE_APP_IDENTIFIER_HEADER = "x-oneuptime-mobile-app-identifier";
|
|
@@ -39,10 +55,11 @@ var SESSION_REPLAY_MAX_SESSION_MS = 4 * 60 * 6e4;
|
|
|
39
55
|
var SESSION_REPLAY_MAX_DECOMPRESSED_FRAME_BYTES = 8 * 1024 * 1024;
|
|
40
56
|
var MAX_SESSION_REPLAY_CHUNK_BYTES = 2 * 1024 * 1024;
|
|
41
57
|
var MAX_SESSION_REPLAY_CHUNKS_PER_SESSION = 480;
|
|
58
|
+
var SESSION_REPLAY_MAX_OFFLINE_DELAY_MS = 3 * 24 * 60 * 60 * 1e3;
|
|
42
59
|
var MOBILE_CAPTURE_INTERVAL_MS = 500;
|
|
43
60
|
var MOBILE_RECORDER_KIND = "rn-view-tree";
|
|
44
61
|
var SYNTHETIC_RRWEB_VERSION = "synthetic-1";
|
|
45
|
-
var RECORDER_VERSION = true ? "14.0.
|
|
62
|
+
var RECORDER_VERSION = true ? "14.0.2" : "0.0.0-dev";
|
|
46
63
|
var SESSION_REPLAY_MOBILE_RECORDER_CAPABILITIES = [
|
|
47
64
|
"mobile-view-tree",
|
|
48
65
|
"mobile-touch-events",
|
|
@@ -523,6 +540,57 @@ function normalizeReplayConfig(value) {
|
|
|
523
540
|
}
|
|
524
541
|
return resolved;
|
|
525
542
|
}
|
|
543
|
+
function replayConfigCacheKey(namespace) {
|
|
544
|
+
return `@oneuptime/replay/${namespace}/config`;
|
|
545
|
+
}
|
|
546
|
+
async function saveReplayConfig(storage, namespace, config, nowUnixMs) {
|
|
547
|
+
try {
|
|
548
|
+
if (!config.enabled) {
|
|
549
|
+
await storage.removeItem(replayConfigCacheKey(namespace));
|
|
550
|
+
return;
|
|
551
|
+
}
|
|
552
|
+
const cached = {
|
|
553
|
+
savedAtUnixMs: nowUnixMs,
|
|
554
|
+
config: { ...config, isTargeted: false }
|
|
555
|
+
};
|
|
556
|
+
await storage.setItem(
|
|
557
|
+
replayConfigCacheKey(namespace),
|
|
558
|
+
JSON.stringify(cached)
|
|
559
|
+
);
|
|
560
|
+
} catch {
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
async function forgetReplayConfig(storage, namespace) {
|
|
564
|
+
try {
|
|
565
|
+
await storage.removeItem(replayConfigCacheKey(namespace));
|
|
566
|
+
} catch {
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
async function loadCachedReplayConfig(storage, namespace, nowUnixMs) {
|
|
570
|
+
try {
|
|
571
|
+
const raw = await storage.getItem(
|
|
572
|
+
replayConfigCacheKey(namespace)
|
|
573
|
+
);
|
|
574
|
+
if (!raw) {
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
const cached = JSON.parse(
|
|
578
|
+
raw
|
|
579
|
+
);
|
|
580
|
+
const age = nowUnixMs - Number(cached.savedAtUnixMs);
|
|
581
|
+
if (!Number.isFinite(age) || age < 0 || age > SESSION_REPLAY_MAX_OFFLINE_DELAY_MS || !cached.config || typeof cached.config !== "object") {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
const config = normalizeReplayConfig({
|
|
585
|
+
...cached.config,
|
|
586
|
+
directive: cached.config.enabled === true ? "continue" : "stop",
|
|
587
|
+
isTargeted: false
|
|
588
|
+
});
|
|
589
|
+
return config.enabled ? config : null;
|
|
590
|
+
} catch {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
526
594
|
async function fetchReplayConfig(options, includeUserRef = false, revalidate = false) {
|
|
527
595
|
const controller = typeof AbortController === "undefined" ? null : new AbortController();
|
|
528
596
|
let timeout = null;
|
|
@@ -1052,878 +1120,1415 @@ function getViewport() {
|
|
|
1052
1120
|
return viewport();
|
|
1053
1121
|
}
|
|
1054
1122
|
|
|
1055
|
-
//
|
|
1056
|
-
var
|
|
1057
|
-
var
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1123
|
+
// node_modules/fflate/esm/browser.js
|
|
1124
|
+
var u8 = Uint8Array;
|
|
1125
|
+
var u16 = Uint16Array;
|
|
1126
|
+
var i32 = Int32Array;
|
|
1127
|
+
var fleb = new u8([
|
|
1128
|
+
0,
|
|
1129
|
+
0,
|
|
1130
|
+
0,
|
|
1131
|
+
0,
|
|
1132
|
+
0,
|
|
1133
|
+
0,
|
|
1134
|
+
0,
|
|
1135
|
+
0,
|
|
1136
|
+
1,
|
|
1137
|
+
1,
|
|
1138
|
+
1,
|
|
1139
|
+
1,
|
|
1140
|
+
2,
|
|
1141
|
+
2,
|
|
1142
|
+
2,
|
|
1143
|
+
2,
|
|
1144
|
+
3,
|
|
1145
|
+
3,
|
|
1146
|
+
3,
|
|
1147
|
+
3,
|
|
1148
|
+
4,
|
|
1149
|
+
4,
|
|
1150
|
+
4,
|
|
1151
|
+
4,
|
|
1152
|
+
5,
|
|
1153
|
+
5,
|
|
1154
|
+
5,
|
|
1155
|
+
5,
|
|
1156
|
+
0,
|
|
1157
|
+
/* unused */
|
|
1158
|
+
0,
|
|
1159
|
+
0,
|
|
1160
|
+
/* impossible */
|
|
1161
|
+
0
|
|
1162
|
+
]);
|
|
1163
|
+
var fdeb = new u8([
|
|
1164
|
+
0,
|
|
1165
|
+
0,
|
|
1166
|
+
0,
|
|
1167
|
+
0,
|
|
1168
|
+
1,
|
|
1169
|
+
1,
|
|
1170
|
+
2,
|
|
1171
|
+
2,
|
|
1172
|
+
3,
|
|
1173
|
+
3,
|
|
1174
|
+
4,
|
|
1175
|
+
4,
|
|
1176
|
+
5,
|
|
1177
|
+
5,
|
|
1178
|
+
6,
|
|
1179
|
+
6,
|
|
1180
|
+
7,
|
|
1181
|
+
7,
|
|
1182
|
+
8,
|
|
1183
|
+
8,
|
|
1184
|
+
9,
|
|
1185
|
+
9,
|
|
1186
|
+
10,
|
|
1187
|
+
10,
|
|
1188
|
+
11,
|
|
1189
|
+
11,
|
|
1190
|
+
12,
|
|
1191
|
+
12,
|
|
1192
|
+
13,
|
|
1193
|
+
13,
|
|
1194
|
+
/* unused */
|
|
1195
|
+
0,
|
|
1196
|
+
0
|
|
1197
|
+
]);
|
|
1198
|
+
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
1199
|
+
var freb = function(eb, start) {
|
|
1200
|
+
var b = new u16(31);
|
|
1201
|
+
for (var i2 = 0; i2 < 31; ++i2) {
|
|
1202
|
+
b[i2] = start += 1 << eb[i2 - 1];
|
|
1061
1203
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1204
|
+
var r = new i32(b[30]);
|
|
1205
|
+
for (var i2 = 1; i2 < 30; ++i2) {
|
|
1206
|
+
for (var j = b[i2]; j < b[i2 + 1]; ++j) {
|
|
1207
|
+
r[j] = j - b[i2] << 5 | i2;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
return { b, r };
|
|
1211
|
+
};
|
|
1212
|
+
var _a = freb(fleb, 2);
|
|
1213
|
+
var fl = _a.b;
|
|
1214
|
+
var revfl = _a.r;
|
|
1215
|
+
fl[28] = 258, revfl[258] = 28;
|
|
1216
|
+
var _b = freb(fdeb, 0);
|
|
1217
|
+
var fd = _b.b;
|
|
1218
|
+
var revfd = _b.r;
|
|
1219
|
+
var rev = new u16(32768);
|
|
1220
|
+
for (i = 0; i < 32768; ++i) {
|
|
1221
|
+
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
1222
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
1223
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
1224
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
1067
1225
|
}
|
|
1068
|
-
var
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1226
|
+
var x;
|
|
1227
|
+
var i;
|
|
1228
|
+
var hMap = (function(cd, mb, r) {
|
|
1229
|
+
var s = cd.length;
|
|
1230
|
+
var i2 = 0;
|
|
1231
|
+
var l = new u16(mb);
|
|
1232
|
+
for (; i2 < s; ++i2) {
|
|
1233
|
+
if (cd[i2])
|
|
1234
|
+
++l[cd[i2] - 1];
|
|
1075
1235
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
return this.readUnlocked();
|
|
1080
|
-
}
|
|
1081
|
-
);
|
|
1236
|
+
var le = new u16(mb);
|
|
1237
|
+
for (i2 = 1; i2 < mb; ++i2) {
|
|
1238
|
+
le[i2] = le[i2 - 1] + l[i2 - 1] << 1;
|
|
1082
1239
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1240
|
+
var co;
|
|
1241
|
+
if (r) {
|
|
1242
|
+
co = new u16(1 << mb);
|
|
1243
|
+
var rvb = 15 - mb;
|
|
1244
|
+
for (i2 = 0; i2 < s; ++i2) {
|
|
1245
|
+
if (cd[i2]) {
|
|
1246
|
+
var sv = i2 << 4 | cd[i2];
|
|
1247
|
+
var r_1 = mb - cd[i2];
|
|
1248
|
+
var v = le[cd[i2] - 1]++ << r_1;
|
|
1249
|
+
for (var m = v | (1 << r_1) - 1; v <= m; ++v) {
|
|
1250
|
+
co[rev[v] >> rvb] = sv;
|
|
1251
|
+
}
|
|
1088
1252
|
}
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1253
|
+
}
|
|
1254
|
+
} else {
|
|
1255
|
+
co = new u16(s);
|
|
1256
|
+
for (i2 = 0; i2 < s; ++i2) {
|
|
1257
|
+
if (cd[i2]) {
|
|
1258
|
+
co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
|
|
1093
1259
|
}
|
|
1094
|
-
return parsed.slice().sort(
|
|
1095
|
-
(left, right) => {
|
|
1096
|
-
return left.createdAtUnixMs - right.createdAtUnixMs;
|
|
1097
|
-
}
|
|
1098
|
-
);
|
|
1099
|
-
} catch {
|
|
1100
|
-
await this.removeUnlocked();
|
|
1101
|
-
return [];
|
|
1102
1260
|
}
|
|
1103
1261
|
}
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1262
|
+
return co;
|
|
1263
|
+
});
|
|
1264
|
+
var flt = new u8(288);
|
|
1265
|
+
for (i = 0; i < 144; ++i)
|
|
1266
|
+
flt[i] = 8;
|
|
1267
|
+
var i;
|
|
1268
|
+
for (i = 144; i < 256; ++i)
|
|
1269
|
+
flt[i] = 9;
|
|
1270
|
+
var i;
|
|
1271
|
+
for (i = 256; i < 280; ++i)
|
|
1272
|
+
flt[i] = 7;
|
|
1273
|
+
var i;
|
|
1274
|
+
for (i = 280; i < 288; ++i)
|
|
1275
|
+
flt[i] = 8;
|
|
1276
|
+
var i;
|
|
1277
|
+
var fdt = new u8(32);
|
|
1278
|
+
for (i = 0; i < 32; ++i)
|
|
1279
|
+
fdt[i] = 5;
|
|
1280
|
+
var i;
|
|
1281
|
+
var flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
1282
|
+
var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
|
|
1283
|
+
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
1284
|
+
var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
|
|
1285
|
+
var max = function(a) {
|
|
1286
|
+
var m = a[0];
|
|
1287
|
+
for (var i2 = 1; i2 < a.length; ++i2) {
|
|
1288
|
+
if (a[i2] > m)
|
|
1289
|
+
m = a[i2];
|
|
1290
|
+
}
|
|
1291
|
+
return m;
|
|
1292
|
+
};
|
|
1293
|
+
var bits = function(d, p, m) {
|
|
1294
|
+
var o = p / 8 | 0;
|
|
1295
|
+
return (d[o] | d[o + 1] << 8) >> (p & 7) & m;
|
|
1296
|
+
};
|
|
1297
|
+
var bits16 = function(d, p) {
|
|
1298
|
+
var o = p / 8 | 0;
|
|
1299
|
+
return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
|
|
1300
|
+
};
|
|
1301
|
+
var shft = function(p) {
|
|
1302
|
+
return (p + 7) / 8 | 0;
|
|
1303
|
+
};
|
|
1304
|
+
var slc = function(v, s, e) {
|
|
1305
|
+
if (s == null || s < 0)
|
|
1306
|
+
s = 0;
|
|
1307
|
+
if (e == null || e > v.length)
|
|
1308
|
+
e = v.length;
|
|
1309
|
+
return new u8(v.subarray(s, e));
|
|
1310
|
+
};
|
|
1311
|
+
var ec = [
|
|
1312
|
+
"unexpected EOF",
|
|
1313
|
+
"invalid block type",
|
|
1314
|
+
"invalid length/literal",
|
|
1315
|
+
"invalid distance",
|
|
1316
|
+
"stream finished",
|
|
1317
|
+
"no stream handler",
|
|
1318
|
+
,
|
|
1319
|
+
// determined by compression function
|
|
1320
|
+
"no callback",
|
|
1321
|
+
"invalid UTF-8 data",
|
|
1322
|
+
"extra field too long",
|
|
1323
|
+
"date not in range 1980-2099",
|
|
1324
|
+
"filename too long",
|
|
1325
|
+
"stream finishing",
|
|
1326
|
+
"invalid zip data"
|
|
1327
|
+
// determined by unknown compression method
|
|
1328
|
+
];
|
|
1329
|
+
var err = function(ind, msg, nt) {
|
|
1330
|
+
var e = new Error(msg || ec[ind]);
|
|
1331
|
+
e.code = ind;
|
|
1332
|
+
if (Error.captureStackTrace)
|
|
1333
|
+
Error.captureStackTrace(e, err);
|
|
1334
|
+
if (!nt)
|
|
1335
|
+
throw e;
|
|
1336
|
+
return e;
|
|
1337
|
+
};
|
|
1338
|
+
var inflt = function(dat, st, buf, dict) {
|
|
1339
|
+
var sl = dat.length, dl = dict ? dict.length : 0;
|
|
1340
|
+
if (!sl || st.f && !st.l)
|
|
1341
|
+
return buf || new u8(0);
|
|
1342
|
+
var noBuf = !buf;
|
|
1343
|
+
var resize = noBuf || st.i != 2;
|
|
1344
|
+
var noSt = st.i;
|
|
1345
|
+
if (noBuf)
|
|
1346
|
+
buf = new u8(sl * 3);
|
|
1347
|
+
var cbuf = function(l2) {
|
|
1348
|
+
var bl = buf.length;
|
|
1349
|
+
if (l2 > bl) {
|
|
1350
|
+
var nbuf = new u8(Math.max(bl * 2, l2));
|
|
1351
|
+
nbuf.set(buf);
|
|
1352
|
+
buf = nbuf;
|
|
1353
|
+
}
|
|
1354
|
+
};
|
|
1355
|
+
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;
|
|
1356
|
+
var tbts = sl * 8;
|
|
1357
|
+
do {
|
|
1358
|
+
if (!lm) {
|
|
1359
|
+
final = bits(dat, pos, 1);
|
|
1360
|
+
var type = bits(dat, pos + 1, 3);
|
|
1361
|
+
pos += 3;
|
|
1362
|
+
if (!type) {
|
|
1363
|
+
var s = shft(pos) + 4, l = dat[s - 4] | dat[s - 3] << 8, t = s + l;
|
|
1364
|
+
if (t > sl) {
|
|
1365
|
+
if (noSt)
|
|
1366
|
+
err(0);
|
|
1367
|
+
break;
|
|
1368
|
+
}
|
|
1369
|
+
if (resize)
|
|
1370
|
+
cbuf(bt + l);
|
|
1371
|
+
buf.set(dat.subarray(s, t), bt);
|
|
1372
|
+
st.b = bt += l, st.p = pos = t * 8, st.f = final;
|
|
1373
|
+
continue;
|
|
1374
|
+
} else if (type == 1)
|
|
1375
|
+
lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
|
|
1376
|
+
else if (type == 2) {
|
|
1377
|
+
var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
|
|
1378
|
+
var tl = hLit + bits(dat, pos + 5, 31) + 1;
|
|
1379
|
+
pos += 14;
|
|
1380
|
+
var ldt = new u8(tl);
|
|
1381
|
+
var clt = new u8(19);
|
|
1382
|
+
for (var i2 = 0; i2 < hcLen; ++i2) {
|
|
1383
|
+
clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
|
|
1384
|
+
}
|
|
1385
|
+
pos += hcLen * 3;
|
|
1386
|
+
var clb = max(clt), clbmsk = (1 << clb) - 1;
|
|
1387
|
+
var clm = hMap(clt, clb, 1);
|
|
1388
|
+
for (var i2 = 0; i2 < tl; ) {
|
|
1389
|
+
var r = clm[bits(dat, pos, clbmsk)];
|
|
1390
|
+
pos += r & 15;
|
|
1391
|
+
var s = r >> 4;
|
|
1392
|
+
if (s < 16) {
|
|
1393
|
+
ldt[i2++] = s;
|
|
1394
|
+
} else {
|
|
1395
|
+
var c = 0, n = 0;
|
|
1396
|
+
if (s == 16)
|
|
1397
|
+
n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
|
|
1398
|
+
else if (s == 17)
|
|
1399
|
+
n = 3 + bits(dat, pos, 7), pos += 3;
|
|
1400
|
+
else if (s == 18)
|
|
1401
|
+
n = 11 + bits(dat, pos, 127), pos += 7;
|
|
1402
|
+
while (n--)
|
|
1403
|
+
ldt[i2++] = c;
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
|
|
1407
|
+
lbt = max(lt);
|
|
1408
|
+
dbt = max(dt);
|
|
1409
|
+
lm = hMap(lt, lbt, 1);
|
|
1410
|
+
dm = hMap(dt, dbt, 1);
|
|
1411
|
+
} else
|
|
1412
|
+
err(1);
|
|
1413
|
+
if (pos > tbts) {
|
|
1414
|
+
if (noSt)
|
|
1415
|
+
err(0);
|
|
1416
|
+
break;
|
|
1111
1417
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1418
|
+
}
|
|
1419
|
+
if (resize)
|
|
1420
|
+
cbuf(bt + 131072);
|
|
1421
|
+
var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
|
|
1422
|
+
var lpos = pos;
|
|
1423
|
+
for (; ; lpos = pos) {
|
|
1424
|
+
var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
|
|
1425
|
+
pos += c & 15;
|
|
1426
|
+
if (pos > tbts) {
|
|
1427
|
+
if (noSt)
|
|
1428
|
+
err(0);
|
|
1429
|
+
break;
|
|
1117
1430
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1431
|
+
if (!c)
|
|
1432
|
+
err(2);
|
|
1433
|
+
if (sym < 256)
|
|
1434
|
+
buf[bt++] = sym;
|
|
1435
|
+
else if (sym == 256) {
|
|
1436
|
+
lpos = pos, lm = null;
|
|
1437
|
+
break;
|
|
1438
|
+
} else {
|
|
1439
|
+
var add = sym - 254;
|
|
1440
|
+
if (sym > 264) {
|
|
1441
|
+
var i2 = sym - 257, b = fleb[i2];
|
|
1442
|
+
add = bits(dat, pos, (1 << b) - 1) + fl[i2];
|
|
1443
|
+
pos += b;
|
|
1444
|
+
}
|
|
1445
|
+
var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
|
|
1446
|
+
if (!d)
|
|
1447
|
+
err(3);
|
|
1448
|
+
pos += d & 15;
|
|
1449
|
+
var dt = fd[dsym];
|
|
1450
|
+
if (dsym > 3) {
|
|
1451
|
+
var b = fdeb[dsym];
|
|
1452
|
+
dt += bits16(dat, pos) & (1 << b) - 1, pos += b;
|
|
1453
|
+
}
|
|
1454
|
+
if (pos > tbts) {
|
|
1455
|
+
if (noSt)
|
|
1456
|
+
err(0);
|
|
1138
1457
|
break;
|
|
1139
1458
|
}
|
|
1459
|
+
if (resize)
|
|
1460
|
+
cbuf(bt + 131072);
|
|
1461
|
+
var end = bt + add;
|
|
1462
|
+
if (bt < dt) {
|
|
1463
|
+
var shift = dl - dt, dend = Math.min(dt, end);
|
|
1464
|
+
if (shift + bt < 0)
|
|
1465
|
+
err(3);
|
|
1466
|
+
for (; bt < dend; ++bt)
|
|
1467
|
+
buf[bt] = dict[shift + bt];
|
|
1468
|
+
}
|
|
1469
|
+
for (; bt < end; ++bt)
|
|
1470
|
+
buf[bt] = buf[bt - dt];
|
|
1140
1471
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1472
|
+
}
|
|
1473
|
+
st.l = lm, st.p = lpos, st.b = bt, st.f = final;
|
|
1474
|
+
if (lm)
|
|
1475
|
+
final = 1, st.m = lbt, st.d = dm, st.n = dbt;
|
|
1476
|
+
} while (!final);
|
|
1477
|
+
return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
|
|
1478
|
+
};
|
|
1479
|
+
var wbits = function(d, p, v) {
|
|
1480
|
+
v <<= p & 7;
|
|
1481
|
+
var o = p / 8 | 0;
|
|
1482
|
+
d[o] |= v;
|
|
1483
|
+
d[o + 1] |= v >> 8;
|
|
1484
|
+
};
|
|
1485
|
+
var wbits16 = function(d, p, v) {
|
|
1486
|
+
v <<= p & 7;
|
|
1487
|
+
var o = p / 8 | 0;
|
|
1488
|
+
d[o] |= v;
|
|
1489
|
+
d[o + 1] |= v >> 8;
|
|
1490
|
+
d[o + 2] |= v >> 16;
|
|
1491
|
+
};
|
|
1492
|
+
var hTree = function(d, mb) {
|
|
1493
|
+
var t = [];
|
|
1494
|
+
for (var i2 = 0; i2 < d.length; ++i2) {
|
|
1495
|
+
if (d[i2])
|
|
1496
|
+
t.push({ s: i2, f: d[i2] });
|
|
1144
1497
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
}
|
|
1498
|
+
var s = t.length;
|
|
1499
|
+
var t2 = t.slice();
|
|
1500
|
+
if (!s)
|
|
1501
|
+
return { t: et, l: 0 };
|
|
1502
|
+
if (s == 1) {
|
|
1503
|
+
var v = new u8(t[0].s + 1);
|
|
1504
|
+
v[t[0].s] = 1;
|
|
1505
|
+
return { t: v, l: 1 };
|
|
1149
1506
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1507
|
+
t.sort(function(a, b) {
|
|
1508
|
+
return a.f - b.f;
|
|
1509
|
+
});
|
|
1510
|
+
t.push({ s: -1, f: 25001 });
|
|
1511
|
+
var l = t[0], r = t[1], i0 = 0, i1 = 1, i22 = 2;
|
|
1512
|
+
t[0] = { s: -1, f: l.f + r.f, l, r };
|
|
1513
|
+
while (i1 != s - 1) {
|
|
1514
|
+
l = t[t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1515
|
+
r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1516
|
+
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
1155
1517
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1518
|
+
var maxSym = t2[0].s;
|
|
1519
|
+
for (var i2 = 1; i2 < s; ++i2) {
|
|
1520
|
+
if (t2[i2].s > maxSym)
|
|
1521
|
+
maxSym = t2[i2].s;
|
|
1522
|
+
}
|
|
1523
|
+
var tr = new u16(maxSym + 1);
|
|
1524
|
+
var mbt = ln(t[i1 - 1], tr, 0);
|
|
1525
|
+
if (mbt > mb) {
|
|
1526
|
+
var i2 = 0, dt = 0;
|
|
1527
|
+
var lft = mbt - mb, cst = 1 << lft;
|
|
1528
|
+
t2.sort(function(a, b) {
|
|
1529
|
+
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
1530
|
+
});
|
|
1531
|
+
for (; i2 < s; ++i2) {
|
|
1532
|
+
var i2_1 = t2[i2].s;
|
|
1533
|
+
if (tr[i2_1] > mb) {
|
|
1534
|
+
dt += cst - (1 << mbt - tr[i2_1]);
|
|
1535
|
+
tr[i2_1] = mb;
|
|
1536
|
+
} else
|
|
1537
|
+
break;
|
|
1538
|
+
}
|
|
1539
|
+
dt >>= lft;
|
|
1540
|
+
while (dt > 0) {
|
|
1541
|
+
var i2_2 = t2[i2].s;
|
|
1542
|
+
if (tr[i2_2] < mb)
|
|
1543
|
+
dt -= 1 << mb - tr[i2_2]++ - 1;
|
|
1544
|
+
else
|
|
1545
|
+
++i2;
|
|
1546
|
+
}
|
|
1547
|
+
for (; i2 >= 0 && dt; --i2) {
|
|
1548
|
+
var i2_3 = t2[i2].s;
|
|
1549
|
+
if (tr[i2_3] == mb) {
|
|
1550
|
+
--tr[i2_3];
|
|
1551
|
+
++dt;
|
|
1161
1552
|
}
|
|
1162
|
-
await this.storage.setItem(this.key, JSON.stringify(frames));
|
|
1163
|
-
} catch {
|
|
1164
1553
|
}
|
|
1554
|
+
mbt = mb;
|
|
1165
1555
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1556
|
+
return { t: new u8(tr), l: mbt };
|
|
1557
|
+
};
|
|
1558
|
+
var ln = function(n, l, d) {
|
|
1559
|
+
return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
|
|
1560
|
+
};
|
|
1561
|
+
var lc = function(c) {
|
|
1562
|
+
var s = c.length;
|
|
1563
|
+
while (s && !c[--s])
|
|
1564
|
+
;
|
|
1565
|
+
var cl = new u16(++s);
|
|
1566
|
+
var cli = 0, cln = c[0], cls = 1;
|
|
1567
|
+
var w = function(v) {
|
|
1568
|
+
cl[cli++] = v;
|
|
1569
|
+
};
|
|
1570
|
+
for (var i2 = 1; i2 <= s; ++i2) {
|
|
1571
|
+
if (c[i2] == cln && i2 != s)
|
|
1572
|
+
++cls;
|
|
1573
|
+
else {
|
|
1574
|
+
if (!cln && cls > 2) {
|
|
1575
|
+
for (; cls > 138; cls -= 138)
|
|
1576
|
+
w(32754);
|
|
1577
|
+
if (cls > 2) {
|
|
1578
|
+
w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
|
|
1579
|
+
cls = 0;
|
|
1580
|
+
}
|
|
1581
|
+
} else if (cls > 3) {
|
|
1582
|
+
w(cln), --cls;
|
|
1583
|
+
for (; cls > 6; cls -= 6)
|
|
1584
|
+
w(8304);
|
|
1585
|
+
if (cls > 2)
|
|
1586
|
+
w(cls - 3 << 5 | 8208), cls = 0;
|
|
1174
1587
|
}
|
|
1175
|
-
|
|
1176
|
-
|
|
1588
|
+
while (cls--)
|
|
1589
|
+
w(cln);
|
|
1590
|
+
cls = 1;
|
|
1591
|
+
cln = c[i2];
|
|
1592
|
+
}
|
|
1177
1593
|
}
|
|
1594
|
+
return { c: cl.subarray(0, cli), n: s };
|
|
1178
1595
|
};
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1596
|
+
var clen = function(cf, cl) {
|
|
1597
|
+
var l = 0;
|
|
1598
|
+
for (var i2 = 0; i2 < cl.length; ++i2)
|
|
1599
|
+
l += cf[i2] * cl[i2];
|
|
1600
|
+
return l;
|
|
1601
|
+
};
|
|
1602
|
+
var wfblk = function(out, pos, dat) {
|
|
1603
|
+
var s = dat.length;
|
|
1604
|
+
var o = shft(pos + 2);
|
|
1605
|
+
out[o] = s & 255;
|
|
1606
|
+
out[o + 1] = s >> 8;
|
|
1607
|
+
out[o + 2] = out[o] ^ 255;
|
|
1608
|
+
out[o + 3] = out[o + 1] ^ 255;
|
|
1609
|
+
for (var i2 = 0; i2 < s; ++i2)
|
|
1610
|
+
out[o + i2 + 4] = dat[i2];
|
|
1611
|
+
return (o + 4 + s) * 8;
|
|
1612
|
+
};
|
|
1613
|
+
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
1614
|
+
wbits(out, p++, final);
|
|
1615
|
+
++lf[256];
|
|
1616
|
+
var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
|
|
1617
|
+
var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
|
|
1618
|
+
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
1619
|
+
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
1620
|
+
var lcfreq = new u16(19);
|
|
1621
|
+
for (var i2 = 0; i2 < lclt.length; ++i2)
|
|
1622
|
+
++lcfreq[lclt[i2] & 31];
|
|
1623
|
+
for (var i2 = 0; i2 < lcdt.length; ++i2)
|
|
1624
|
+
++lcfreq[lcdt[i2] & 31];
|
|
1625
|
+
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
1626
|
+
var nlcc = 19;
|
|
1627
|
+
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
1628
|
+
;
|
|
1629
|
+
var flen = bl + 5 << 3;
|
|
1630
|
+
var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
1631
|
+
var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
|
|
1632
|
+
if (bs >= 0 && flen <= ftlen && flen <= dtlen)
|
|
1633
|
+
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
1634
|
+
var lm, ll, dm, dl;
|
|
1635
|
+
wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
|
|
1636
|
+
if (dtlen < ftlen) {
|
|
1637
|
+
lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
|
|
1638
|
+
var llm = hMap(lct, mlcb, 0);
|
|
1639
|
+
wbits(out, p, nlc - 257);
|
|
1640
|
+
wbits(out, p + 5, ndc - 1);
|
|
1641
|
+
wbits(out, p + 10, nlcc - 4);
|
|
1642
|
+
p += 14;
|
|
1643
|
+
for (var i2 = 0; i2 < nlcc; ++i2)
|
|
1644
|
+
wbits(out, p + 3 * i2, lct[clim[i2]]);
|
|
1645
|
+
p += 3 * nlcc;
|
|
1646
|
+
var lcts = [lclt, lcdt];
|
|
1647
|
+
for (var it = 0; it < 2; ++it) {
|
|
1648
|
+
var clct = lcts[it];
|
|
1649
|
+
for (var i2 = 0; i2 < clct.length; ++i2) {
|
|
1650
|
+
var len = clct[i2] & 31;
|
|
1651
|
+
wbits(out, p, llm[len]), p += lct[len];
|
|
1652
|
+
if (len > 15)
|
|
1653
|
+
wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
|
|
1654
|
+
}
|
|
1192
1655
|
}
|
|
1656
|
+
} else {
|
|
1657
|
+
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
1193
1658
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
1208
|
-
return null;
|
|
1209
|
-
}
|
|
1210
|
-
const candidate = parsed;
|
|
1211
|
-
if (!isReplayId(candidate.sessionId) || !Number.isSafeInteger(candidate.sessionStartUnixMs) || !Number.isSafeInteger(candidate.lastActivityUnixMs) || !Number.isSafeInteger(candidate.nextChunkIndex) || (candidate.nextChunkIndex ?? -1) < 0) {
|
|
1212
|
-
return null;
|
|
1659
|
+
for (var i2 = 0; i2 < li; ++i2) {
|
|
1660
|
+
var sym = syms[i2];
|
|
1661
|
+
if (sym > 255) {
|
|
1662
|
+
var len = sym >> 18 & 31;
|
|
1663
|
+
wbits16(out, p, lm[len + 257]), p += ll[len + 257];
|
|
1664
|
+
if (len > 7)
|
|
1665
|
+
wbits(out, p, sym >> 23 & 31), p += fleb[len];
|
|
1666
|
+
var dst = sym & 31;
|
|
1667
|
+
wbits16(out, p, dm[dst]), p += dl[dst];
|
|
1668
|
+
if (dst > 3)
|
|
1669
|
+
wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
|
|
1670
|
+
} else {
|
|
1671
|
+
wbits16(out, p, lm[sym]), p += ll[sym];
|
|
1213
1672
|
}
|
|
1214
|
-
return candidate;
|
|
1215
|
-
} catch {
|
|
1216
|
-
return null;
|
|
1217
1673
|
}
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1674
|
+
wbits16(out, p, lm[256]);
|
|
1675
|
+
return p + ll[256];
|
|
1676
|
+
};
|
|
1677
|
+
var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
|
|
1678
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
1679
|
+
var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
1680
|
+
var s = st.z || dat.length;
|
|
1681
|
+
var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7e3)) + post);
|
|
1682
|
+
var w = o.subarray(pre, o.length - post);
|
|
1683
|
+
var lst = st.l;
|
|
1684
|
+
var pos = (st.r || 0) & 7;
|
|
1685
|
+
if (lvl) {
|
|
1686
|
+
if (pos)
|
|
1687
|
+
w[0] = st.r >> 3;
|
|
1688
|
+
var opt = deo[lvl - 1];
|
|
1689
|
+
var n = opt >> 13, c = opt & 8191;
|
|
1690
|
+
var msk_1 = (1 << plvl) - 1;
|
|
1691
|
+
var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
|
|
1692
|
+
var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
|
|
1693
|
+
var hsh = function(i3) {
|
|
1694
|
+
return (dat[i3] ^ dat[i3 + 1] << bs1_1 ^ dat[i3 + 2] << bs2_1) & msk_1;
|
|
1695
|
+
};
|
|
1696
|
+
var syms = new i32(25e3);
|
|
1697
|
+
var lf = new u16(288), df = new u16(32);
|
|
1698
|
+
var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
1699
|
+
for (; i2 + 2 < s; ++i2) {
|
|
1700
|
+
var hv = hsh(i2);
|
|
1701
|
+
var imod = i2 & 32767, pimod = head[hv];
|
|
1702
|
+
prev[imod] = pimod;
|
|
1703
|
+
head[hv] = imod;
|
|
1704
|
+
if (wi <= i2) {
|
|
1705
|
+
var rem = s - i2;
|
|
1706
|
+
if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
|
|
1707
|
+
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1708
|
+
li = lc_1 = eb = 0, bs = i2;
|
|
1709
|
+
for (var j = 0; j < 286; ++j)
|
|
1710
|
+
lf[j] = 0;
|
|
1711
|
+
for (var j = 0; j < 30; ++j)
|
|
1712
|
+
df[j] = 0;
|
|
1713
|
+
}
|
|
1714
|
+
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
1715
|
+
if (rem > 2 && hv == hsh(i2 - dif)) {
|
|
1716
|
+
var maxn = Math.min(n, rem) - 1;
|
|
1717
|
+
var maxd = Math.min(32767, i2);
|
|
1718
|
+
var ml = Math.min(258, rem);
|
|
1719
|
+
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
1720
|
+
if (dat[i2 + l] == dat[i2 + l - dif]) {
|
|
1721
|
+
var nl = 0;
|
|
1722
|
+
for (; nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
|
|
1723
|
+
;
|
|
1724
|
+
if (nl > l) {
|
|
1725
|
+
l = nl, d = dif;
|
|
1726
|
+
if (nl > maxn)
|
|
1727
|
+
break;
|
|
1728
|
+
var mmd = Math.min(dif, nl - 2);
|
|
1729
|
+
var md = 0;
|
|
1730
|
+
for (var j = 0; j < mmd; ++j) {
|
|
1731
|
+
var ti = i2 - dif + j & 32767;
|
|
1732
|
+
var pti = prev[ti];
|
|
1733
|
+
var cd = ti - pti & 32767;
|
|
1734
|
+
if (cd > md)
|
|
1735
|
+
md = cd, pimod = ti;
|
|
1736
|
+
}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
imod = pimod, pimod = prev[imod];
|
|
1740
|
+
dif += imod - pimod & 32767;
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
if (d) {
|
|
1744
|
+
syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
|
|
1745
|
+
var lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
1746
|
+
eb += fleb[lin] + fdeb[din];
|
|
1747
|
+
++lf[257 + lin];
|
|
1748
|
+
++df[din];
|
|
1749
|
+
wi = i2 + l;
|
|
1750
|
+
++lc_1;
|
|
1751
|
+
} else {
|
|
1752
|
+
syms[li++] = dat[i2];
|
|
1753
|
+
++lf[dat[i2]];
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1249
1756
|
}
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
await this.safeSet(this.visitorKey, visitorId);
|
|
1757
|
+
for (i2 = Math.max(i2, wi); i2 < s; ++i2) {
|
|
1758
|
+
syms[li++] = dat[i2];
|
|
1759
|
+
++lf[dat[i2]];
|
|
1254
1760
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
sessionStartUnixMs: session.sessionStartUnixMs,
|
|
1261
|
-
chunkIndex: session.nextChunkIndex
|
|
1262
|
-
};
|
|
1263
|
-
return { ...this.identity };
|
|
1264
|
-
}
|
|
1265
|
-
async takeChunkIndex(nowUnixMs) {
|
|
1266
|
-
if (!this.identity) {
|
|
1267
|
-
await this.resolve(nowUnixMs);
|
|
1761
|
+
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1762
|
+
if (!lst) {
|
|
1763
|
+
st.r = pos & 7 | w[pos / 8 | 0] << 3;
|
|
1764
|
+
pos -= 7;
|
|
1765
|
+
st.h = head, st.p = prev, st.i = i2, st.w = wi;
|
|
1268
1766
|
}
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
};
|
|
1278
|
-
await this.safeSet(this.sessionKey, JSON.stringify(state));
|
|
1279
|
-
return index;
|
|
1280
|
-
}
|
|
1281
|
-
getNextChunkIndex() {
|
|
1282
|
-
return this.identity?.chunkIndex ?? null;
|
|
1283
|
-
}
|
|
1284
|
-
async rotate(nowUnixMs) {
|
|
1285
|
-
let visitorId = await this.safeGet(this.visitorKey);
|
|
1286
|
-
if (!isReplayId(visitorId)) {
|
|
1287
|
-
visitorId = generateReplayId();
|
|
1288
|
-
await this.safeSet(this.visitorKey, visitorId);
|
|
1767
|
+
} else {
|
|
1768
|
+
for (var i2 = st.w || 0; i2 < s + lst; i2 += 65535) {
|
|
1769
|
+
var e = i2 + 65535;
|
|
1770
|
+
if (e >= s) {
|
|
1771
|
+
w[pos / 8 | 0] = lst;
|
|
1772
|
+
e = s;
|
|
1773
|
+
}
|
|
1774
|
+
pos = wfblk(w, pos + 1, dat.subarray(i2, e));
|
|
1289
1775
|
}
|
|
1290
|
-
|
|
1291
|
-
sessionId: generateReplayId(),
|
|
1292
|
-
sessionStartUnixMs: nowUnixMs,
|
|
1293
|
-
lastActivityUnixMs: nowUnixMs,
|
|
1294
|
-
nextChunkIndex: 0
|
|
1295
|
-
};
|
|
1296
|
-
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
1297
|
-
this.identity = {
|
|
1298
|
-
sessionId: session.sessionId,
|
|
1299
|
-
tabId: generateReplayId(),
|
|
1300
|
-
visitorId,
|
|
1301
|
-
sessionStartUnixMs: nowUnixMs,
|
|
1302
|
-
chunkIndex: 0
|
|
1303
|
-
};
|
|
1304
|
-
return { ...this.identity };
|
|
1776
|
+
st.i = s;
|
|
1305
1777
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1778
|
+
return slc(o, 0, pre + shft(pos) + post);
|
|
1779
|
+
};
|
|
1780
|
+
var crct = /* @__PURE__ */ (function() {
|
|
1781
|
+
var t = new Int32Array(256);
|
|
1782
|
+
for (var i2 = 0; i2 < 256; ++i2) {
|
|
1783
|
+
var c = i2, k = 9;
|
|
1784
|
+
while (--k)
|
|
1785
|
+
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
1786
|
+
t[i2] = c;
|
|
1312
1787
|
}
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1788
|
+
return t;
|
|
1789
|
+
})();
|
|
1790
|
+
var crc = function() {
|
|
1791
|
+
var c = -1;
|
|
1792
|
+
return {
|
|
1793
|
+
p: function(d) {
|
|
1794
|
+
var cr = c;
|
|
1795
|
+
for (var i2 = 0; i2 < d.length; ++i2)
|
|
1796
|
+
cr = crct[cr & 255 ^ d[i2]] ^ cr >>> 8;
|
|
1797
|
+
c = cr;
|
|
1798
|
+
},
|
|
1799
|
+
d: function() {
|
|
1800
|
+
return ~c;
|
|
1318
1801
|
}
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1802
|
+
};
|
|
1803
|
+
};
|
|
1804
|
+
var dopt = function(dat, opt, pre, post, st) {
|
|
1805
|
+
if (!st) {
|
|
1806
|
+
st = { l: 1 };
|
|
1807
|
+
if (opt.dictionary) {
|
|
1808
|
+
var dict = opt.dictionary.subarray(-32768);
|
|
1809
|
+
var newDat = new u8(dict.length + dat.length);
|
|
1810
|
+
newDat.set(dict);
|
|
1811
|
+
newDat.set(dat, dict.length);
|
|
1812
|
+
dat = newDat;
|
|
1813
|
+
st.w = dict.length;
|
|
1324
1814
|
}
|
|
1325
1815
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1816
|
+
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);
|
|
1817
|
+
};
|
|
1818
|
+
var wbytes = function(d, b, v) {
|
|
1819
|
+
for (; v; ++b)
|
|
1820
|
+
d[b] = v, v >>>= 8;
|
|
1821
|
+
};
|
|
1822
|
+
var gzh = function(c, o) {
|
|
1823
|
+
var fn = o.filename;
|
|
1824
|
+
c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3;
|
|
1825
|
+
if (o.mtime != 0)
|
|
1826
|
+
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1e3));
|
|
1827
|
+
if (fn) {
|
|
1828
|
+
c[3] = 8;
|
|
1829
|
+
for (var i2 = 0; i2 <= fn.length; ++i2)
|
|
1830
|
+
c[i2 + 10] = fn.charCodeAt(i2);
|
|
1331
1831
|
}
|
|
1332
1832
|
};
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
var
|
|
1337
|
-
var
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
0
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
0
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
1
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
var
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
5,
|
|
1388
|
-
5,
|
|
1389
|
-
6,
|
|
1390
|
-
6,
|
|
1391
|
-
7,
|
|
1392
|
-
7,
|
|
1393
|
-
8,
|
|
1394
|
-
8,
|
|
1395
|
-
9,
|
|
1396
|
-
9,
|
|
1397
|
-
10,
|
|
1398
|
-
10,
|
|
1399
|
-
11,
|
|
1400
|
-
11,
|
|
1401
|
-
12,
|
|
1402
|
-
12,
|
|
1403
|
-
13,
|
|
1404
|
-
13,
|
|
1405
|
-
/* unused */
|
|
1406
|
-
0,
|
|
1407
|
-
0
|
|
1408
|
-
]);
|
|
1409
|
-
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
1410
|
-
var freb = function(eb, start) {
|
|
1411
|
-
var b = new u16(31);
|
|
1412
|
-
for (var i2 = 0; i2 < 31; ++i2) {
|
|
1413
|
-
b[i2] = start += 1 << eb[i2 - 1];
|
|
1833
|
+
var gzs = function(d) {
|
|
1834
|
+
if (d[0] != 31 || d[1] != 139 || d[2] != 8)
|
|
1835
|
+
err(6, "invalid gzip data");
|
|
1836
|
+
var flg = d[3];
|
|
1837
|
+
var st = 10;
|
|
1838
|
+
if (flg & 4)
|
|
1839
|
+
st += (d[10] | d[11] << 8) + 2;
|
|
1840
|
+
for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
|
|
1841
|
+
;
|
|
1842
|
+
return st + (flg & 2);
|
|
1843
|
+
};
|
|
1844
|
+
var gzl = function(d) {
|
|
1845
|
+
var l = d.length;
|
|
1846
|
+
return (d[l - 4] | d[l - 3] << 8 | d[l - 2] << 16 | d[l - 1] << 24) >>> 0;
|
|
1847
|
+
};
|
|
1848
|
+
var gzhl = function(o) {
|
|
1849
|
+
return 10 + (o.filename ? o.filename.length + 1 : 0);
|
|
1850
|
+
};
|
|
1851
|
+
function gzipSync(data, opts) {
|
|
1852
|
+
if (!opts)
|
|
1853
|
+
opts = {};
|
|
1854
|
+
var c = crc(), l = data.length;
|
|
1855
|
+
c.p(data);
|
|
1856
|
+
var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
1857
|
+
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
1858
|
+
}
|
|
1859
|
+
function gunzipSync(data, opts) {
|
|
1860
|
+
var st = gzs(data);
|
|
1861
|
+
if (st + 8 > data.length)
|
|
1862
|
+
err(6, "invalid gzip data");
|
|
1863
|
+
return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
|
|
1864
|
+
}
|
|
1865
|
+
var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
|
|
1866
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1867
|
+
var tds = 0;
|
|
1868
|
+
try {
|
|
1869
|
+
td.decode(et, { stream: true });
|
|
1870
|
+
tds = 1;
|
|
1871
|
+
} catch (e) {
|
|
1872
|
+
}
|
|
1873
|
+
var dutf8 = function(d) {
|
|
1874
|
+
for (var r = "", i2 = 0; ; ) {
|
|
1875
|
+
var c = d[i2++];
|
|
1876
|
+
var eb = (c > 127) + (c > 223) + (c > 239);
|
|
1877
|
+
if (i2 + eb > d.length)
|
|
1878
|
+
return { s: r, r: slc(d, i2 - 1) };
|
|
1879
|
+
if (!eb)
|
|
1880
|
+
r += String.fromCharCode(c);
|
|
1881
|
+
else if (eb == 3) {
|
|
1882
|
+
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);
|
|
1883
|
+
} else if (eb & 1)
|
|
1884
|
+
r += String.fromCharCode((c & 31) << 6 | d[i2++] & 63);
|
|
1885
|
+
else
|
|
1886
|
+
r += String.fromCharCode((c & 15) << 12 | (d[i2++] & 63) << 6 | d[i2++] & 63);
|
|
1414
1887
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1888
|
+
};
|
|
1889
|
+
function strToU8(str, latin1) {
|
|
1890
|
+
if (latin1) {
|
|
1891
|
+
var ar_1 = new u8(str.length);
|
|
1892
|
+
for (var i2 = 0; i2 < str.length; ++i2)
|
|
1893
|
+
ar_1[i2] = str.charCodeAt(i2);
|
|
1894
|
+
return ar_1;
|
|
1895
|
+
}
|
|
1896
|
+
if (te)
|
|
1897
|
+
return te.encode(str);
|
|
1898
|
+
var l = str.length;
|
|
1899
|
+
var ar = new u8(str.length + (str.length >> 1));
|
|
1900
|
+
var ai = 0;
|
|
1901
|
+
var w = function(v) {
|
|
1902
|
+
ar[ai++] = v;
|
|
1903
|
+
};
|
|
1904
|
+
for (var i2 = 0; i2 < l; ++i2) {
|
|
1905
|
+
if (ai + 5 > ar.length) {
|
|
1906
|
+
var n = new u8(ai + 8 + (l - i2 << 1));
|
|
1907
|
+
n.set(ar);
|
|
1908
|
+
ar = n;
|
|
1419
1909
|
}
|
|
1910
|
+
var c = str.charCodeAt(i2);
|
|
1911
|
+
if (c < 128 || latin1)
|
|
1912
|
+
w(c);
|
|
1913
|
+
else if (c < 2048)
|
|
1914
|
+
w(192 | c >> 6), w(128 | c & 63);
|
|
1915
|
+
else if (c > 55295 && c < 57344)
|
|
1916
|
+
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);
|
|
1917
|
+
else
|
|
1918
|
+
w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1420
1919
|
}
|
|
1421
|
-
return
|
|
1422
|
-
};
|
|
1423
|
-
var _a = freb(fleb, 2);
|
|
1424
|
-
var fl = _a.b;
|
|
1425
|
-
var revfl = _a.r;
|
|
1426
|
-
fl[28] = 258, revfl[258] = 28;
|
|
1427
|
-
var _b = freb(fdeb, 0);
|
|
1428
|
-
var fd = _b.b;
|
|
1429
|
-
var revfd = _b.r;
|
|
1430
|
-
var rev = new u16(32768);
|
|
1431
|
-
for (i = 0; i < 32768; ++i) {
|
|
1432
|
-
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
1433
|
-
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
1434
|
-
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
1435
|
-
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
1920
|
+
return slc(ar, 0, ai);
|
|
1436
1921
|
}
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
var
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1922
|
+
function strFromU8(dat, latin1) {
|
|
1923
|
+
if (latin1) {
|
|
1924
|
+
var r = "";
|
|
1925
|
+
for (var i2 = 0; i2 < dat.length; i2 += 16384)
|
|
1926
|
+
r += String.fromCharCode.apply(null, dat.subarray(i2, i2 + 16384));
|
|
1927
|
+
return r;
|
|
1928
|
+
} else if (td) {
|
|
1929
|
+
return td.decode(dat);
|
|
1930
|
+
} else {
|
|
1931
|
+
var _a2 = dutf8(dat), s = _a2.s, r = _a2.r;
|
|
1932
|
+
if (r.length)
|
|
1933
|
+
err(8);
|
|
1934
|
+
return s;
|
|
1446
1935
|
}
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// src/Base64.ts
|
|
1939
|
+
var ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
1940
|
+
var LOOKUP = (() => {
|
|
1941
|
+
const table = new Int16Array(128).fill(-1);
|
|
1942
|
+
for (let index = 0; index < ALPHABET.length; index += 1) {
|
|
1943
|
+
table[ALPHABET.charCodeAt(index)] = index;
|
|
1944
|
+
}
|
|
1945
|
+
return table;
|
|
1946
|
+
})();
|
|
1947
|
+
function encodeBase64(bytes) {
|
|
1948
|
+
const parts = [];
|
|
1949
|
+
for (let index = 0; index < bytes.length; index += 3) {
|
|
1950
|
+
const first = bytes[index];
|
|
1951
|
+
const second = bytes[index + 1];
|
|
1952
|
+
const third = bytes[index + 2];
|
|
1953
|
+
const triple = first << 16 | (second ?? 0) << 8 | (third ?? 0);
|
|
1954
|
+
parts.push(
|
|
1955
|
+
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))
|
|
1956
|
+
);
|
|
1450
1957
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1958
|
+
return parts.join("");
|
|
1959
|
+
}
|
|
1960
|
+
function decodeBase64(text) {
|
|
1961
|
+
if (typeof text !== "string" || text.length % 4 !== 0) {
|
|
1962
|
+
return null;
|
|
1963
|
+
}
|
|
1964
|
+
const padding = text.endsWith("==") ? 2 : text.endsWith("=") ? 1 : 0;
|
|
1965
|
+
const bytes = new Uint8Array(text.length / 4 * 3 - padding);
|
|
1966
|
+
let buffer = 0;
|
|
1967
|
+
let bits2 = 0;
|
|
1968
|
+
let written = 0;
|
|
1969
|
+
for (let index = 0; index < text.length - padding; index += 1) {
|
|
1970
|
+
const code = text.charCodeAt(index);
|
|
1971
|
+
const value = code < 128 ? LOOKUP[code] : -1;
|
|
1972
|
+
if (value < 0) {
|
|
1973
|
+
return null;
|
|
1464
1974
|
}
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1975
|
+
buffer = (buffer << 6 | value) & 16777215;
|
|
1976
|
+
bits2 += 6;
|
|
1977
|
+
if (bits2 >= 8) {
|
|
1978
|
+
bits2 -= 8;
|
|
1979
|
+
bytes[written] = buffer >> bits2 & 255;
|
|
1980
|
+
written += 1;
|
|
1471
1981
|
}
|
|
1472
1982
|
}
|
|
1473
|
-
return
|
|
1474
|
-
}
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
var
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
for (i = 256; i < 280; ++i)
|
|
1483
|
-
flt[i] = 7;
|
|
1484
|
-
var i;
|
|
1485
|
-
for (i = 280; i < 288; ++i)
|
|
1486
|
-
flt[i] = 8;
|
|
1487
|
-
var i;
|
|
1488
|
-
var fdt = new u8(32);
|
|
1489
|
-
for (i = 0; i < 32; ++i)
|
|
1490
|
-
fdt[i] = 5;
|
|
1491
|
-
var i;
|
|
1492
|
-
var flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
1493
|
-
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
1494
|
-
var shft = function(p) {
|
|
1495
|
-
return (p + 7) / 8 | 0;
|
|
1496
|
-
};
|
|
1497
|
-
var slc = function(v, s, e) {
|
|
1498
|
-
if (s == null || s < 0)
|
|
1499
|
-
s = 0;
|
|
1500
|
-
if (e == null || e > v.length)
|
|
1501
|
-
e = v.length;
|
|
1502
|
-
return new u8(v.subarray(s, e));
|
|
1503
|
-
};
|
|
1504
|
-
var wbits = function(d, p, v) {
|
|
1505
|
-
v <<= p & 7;
|
|
1506
|
-
var o = p / 8 | 0;
|
|
1507
|
-
d[o] |= v;
|
|
1508
|
-
d[o + 1] |= v >> 8;
|
|
1509
|
-
};
|
|
1510
|
-
var wbits16 = function(d, p, v) {
|
|
1511
|
-
v <<= p & 7;
|
|
1512
|
-
var o = p / 8 | 0;
|
|
1513
|
-
d[o] |= v;
|
|
1514
|
-
d[o + 1] |= v >> 8;
|
|
1515
|
-
d[o + 2] |= v >> 16;
|
|
1516
|
-
};
|
|
1517
|
-
var hTree = function(d, mb) {
|
|
1518
|
-
var t = [];
|
|
1519
|
-
for (var i2 = 0; i2 < d.length; ++i2) {
|
|
1520
|
-
if (d[i2])
|
|
1521
|
-
t.push({ s: i2, f: d[i2] });
|
|
1983
|
+
return written === bytes.length ? bytes : null;
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
// src/Outbox.ts
|
|
1987
|
+
var MAX_OUTBOX_ENTRIES = 240;
|
|
1988
|
+
var MAX_OUTBOX_BYTES = 3 * 1024 * 1024;
|
|
1989
|
+
function isEnvelope(value) {
|
|
1990
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1991
|
+
return false;
|
|
1522
1992
|
}
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
if (
|
|
1528
|
-
|
|
1529
|
-
v[t[0].s] = 1;
|
|
1530
|
-
return { t: v, l: 1 };
|
|
1993
|
+
const envelope = value;
|
|
1994
|
+
return typeof envelope.sessionId === "string" && typeof envelope.tabId === "string" && typeof envelope.chunkIndex === "number";
|
|
1995
|
+
}
|
|
1996
|
+
function isEntry(value) {
|
|
1997
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1998
|
+
return false;
|
|
1531
1999
|
}
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
while (i1 != s - 1) {
|
|
1539
|
-
l = t[t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1540
|
-
r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
|
|
1541
|
-
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
2000
|
+
const entry = value;
|
|
2001
|
+
return typeof entry.id === "string" && Number.isSafeInteger(entry.attempts) && typeof entry.createdAtUnixMs === "number" && Number.isFinite(entry.createdAtUnixMs) && Number.isSafeInteger(entry.bytes);
|
|
2002
|
+
}
|
|
2003
|
+
function isLegacyFrame(value) {
|
|
2004
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2005
|
+
return false;
|
|
1542
2006
|
}
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
2007
|
+
const frame = value;
|
|
2008
|
+
return typeof frame.id === "string" && typeof frame.payload === "string" && typeof frame.attempts === "number" && Number.isSafeInteger(frame.attempts) && typeof frame.createdAtUnixMs === "number" && isEnvelope(frame.envelope);
|
|
2009
|
+
}
|
|
2010
|
+
function byOldest(left, right) {
|
|
2011
|
+
return left.createdAtUnixMs - right.createdAtUnixMs;
|
|
2012
|
+
}
|
|
2013
|
+
function frameId(envelope) {
|
|
2014
|
+
return `${envelope.sessionId}:${envelope.tabId}:${envelope.chunkIndex}`;
|
|
2015
|
+
}
|
|
2016
|
+
var ReplayOutbox = class {
|
|
2017
|
+
constructor(storage, namespace, now = Date.now) {
|
|
2018
|
+
__publicField(this, "storage");
|
|
2019
|
+
__publicField(this, "legacyKey");
|
|
2020
|
+
__publicField(this, "indexKey");
|
|
2021
|
+
__publicField(this, "framePrefix");
|
|
2022
|
+
__publicField(this, "now");
|
|
2023
|
+
__publicField(this, "mutationQueue", Promise.resolve());
|
|
2024
|
+
__publicField(this, "migrated", false);
|
|
2025
|
+
this.storage = storage;
|
|
2026
|
+
this.legacyKey = `@oneuptime/replay/${namespace}/outbox`;
|
|
2027
|
+
this.indexKey = `@oneuptime/replay/${namespace}/outbox-v2`;
|
|
2028
|
+
this.framePrefix = `@oneuptime/replay/${namespace}/outbox-v2/`;
|
|
2029
|
+
this.now = now;
|
|
1547
2030
|
}
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
var lft = mbt - mb, cst = 1 << lft;
|
|
1553
|
-
t2.sort(function(a, b) {
|
|
1554
|
-
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
2031
|
+
/* Every queued frame's index entry, oldest first. Reads no payload. */
|
|
2032
|
+
async entries() {
|
|
2033
|
+
return await this.withLock(async () => {
|
|
2034
|
+
return await this.readIndexUnlocked();
|
|
1555
2035
|
});
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
2036
|
+
}
|
|
2037
|
+
/*
|
|
2038
|
+
* One frame, ready to post. Null when it is no longer queued, and
|
|
2039
|
+
* "unreadable" when its value could not be read back - it is removed, so
|
|
2040
|
+
* one damaged frame never blocks the ones behind it.
|
|
2041
|
+
*/
|
|
2042
|
+
async load(id) {
|
|
2043
|
+
return await this.withLock(
|
|
2044
|
+
async () => {
|
|
2045
|
+
const entries = await this.readIndexUnlocked();
|
|
2046
|
+
const entry = entries.find(
|
|
2047
|
+
(candidate) => {
|
|
2048
|
+
return candidate.id === id;
|
|
2049
|
+
}
|
|
2050
|
+
);
|
|
2051
|
+
if (!entry) {
|
|
2052
|
+
return null;
|
|
2053
|
+
}
|
|
2054
|
+
const value = await this.readFrameUnlocked(id);
|
|
2055
|
+
if (!value) {
|
|
2056
|
+
await this.removeEntriesUnlocked(entries, [id]);
|
|
2057
|
+
return "unreadable";
|
|
2058
|
+
}
|
|
2059
|
+
return {
|
|
2060
|
+
id,
|
|
2061
|
+
envelope: value.envelope,
|
|
2062
|
+
compressedPayload: value.bytes,
|
|
2063
|
+
attempts: entry.attempts,
|
|
2064
|
+
createdAtUnixMs: entry.createdAtUnixMs
|
|
2065
|
+
};
|
|
2066
|
+
}
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
/* Every frame with its payload decompressed, oldest first. */
|
|
2070
|
+
async list() {
|
|
2071
|
+
const frames = [];
|
|
2072
|
+
for (const entry of await this.entries()) {
|
|
2073
|
+
const frame = await this.load(
|
|
2074
|
+
entry.id
|
|
2075
|
+
);
|
|
2076
|
+
if (!frame || frame === "unreadable") {
|
|
2077
|
+
continue;
|
|
2078
|
+
}
|
|
2079
|
+
frames.push({
|
|
2080
|
+
id: frame.id,
|
|
2081
|
+
envelope: frame.envelope,
|
|
2082
|
+
payload: strFromU8(gunzipSync(frame.compressedPayload)),
|
|
2083
|
+
attempts: frame.attempts,
|
|
2084
|
+
createdAtUnixMs: frame.createdAtUnixMs
|
|
2085
|
+
});
|
|
1563
2086
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
2087
|
+
return frames;
|
|
2088
|
+
}
|
|
2089
|
+
/*
|
|
2090
|
+
* Queue a frame. Past MAX_OUTBOX_ENTRIES or MAX_OUTBOX_BYTES the OLDEST
|
|
2091
|
+
* frames are evicted - the newest seconds are the ones closest to whatever
|
|
2092
|
+
* went wrong, and a later full snapshot re-anchors the player after a gap -
|
|
2093
|
+
* and counted in `dropped`, as is a frame the device had no room to store.
|
|
2094
|
+
*/
|
|
2095
|
+
async enqueue(frame) {
|
|
2096
|
+
return await this.withLock(async () => {
|
|
2097
|
+
const entries = await this.readIndexUnlocked();
|
|
2098
|
+
if (entries.some((candidate) => {
|
|
2099
|
+
return candidate.id === frame.id;
|
|
2100
|
+
})) {
|
|
2101
|
+
return { dropped: 0 };
|
|
2102
|
+
}
|
|
2103
|
+
const bytes = await this.writeFrameUnlocked(frame);
|
|
2104
|
+
if (bytes === null) {
|
|
2105
|
+
return { dropped: 1 };
|
|
2106
|
+
}
|
|
2107
|
+
entries.push({
|
|
2108
|
+
id: frame.id,
|
|
2109
|
+
attempts: frame.attempts,
|
|
2110
|
+
createdAtUnixMs: frame.createdAtUnixMs,
|
|
2111
|
+
bytes
|
|
2112
|
+
});
|
|
2113
|
+
entries.sort(byOldest);
|
|
2114
|
+
let totalBytes = 0;
|
|
2115
|
+
for (const entry of entries) {
|
|
2116
|
+
totalBytes += entry.bytes;
|
|
2117
|
+
}
|
|
2118
|
+
const evicted = [];
|
|
2119
|
+
while (entries.length > 1 && (entries.length > MAX_OUTBOX_ENTRIES || totalBytes > MAX_OUTBOX_BYTES)) {
|
|
2120
|
+
const oldest = entries.shift();
|
|
2121
|
+
totalBytes -= oldest.bytes;
|
|
2122
|
+
evicted.push(oldest.id);
|
|
2123
|
+
}
|
|
2124
|
+
if (!await this.writeIndexUnlocked(entries)) {
|
|
2125
|
+
await this.safeRemove(this.frameKey(frame.id));
|
|
2126
|
+
return { dropped: 1 };
|
|
2127
|
+
}
|
|
2128
|
+
await Promise.all(
|
|
2129
|
+
evicted.map((id) => {
|
|
2130
|
+
return this.safeRemove(this.frameKey(id));
|
|
2131
|
+
})
|
|
2132
|
+
);
|
|
2133
|
+
return { dropped: evicted.length };
|
|
2134
|
+
});
|
|
2135
|
+
}
|
|
2136
|
+
async remove(id) {
|
|
2137
|
+
await this.withLock(async () => {
|
|
2138
|
+
await this.removeEntriesUnlocked(await this.readIndexUnlocked(), [id]);
|
|
2139
|
+
});
|
|
2140
|
+
}
|
|
2141
|
+
async incrementAttempts(id) {
|
|
2142
|
+
return await this.withLock(async () => {
|
|
2143
|
+
const entries = await this.readIndexUnlocked();
|
|
2144
|
+
let attempts = 0;
|
|
2145
|
+
for (const entry of entries) {
|
|
2146
|
+
if (entry.id === id) {
|
|
2147
|
+
entry.attempts += 1;
|
|
2148
|
+
attempts = entry.attempts;
|
|
2149
|
+
break;
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
await this.writeIndexUnlocked(entries);
|
|
2153
|
+
return attempts;
|
|
2154
|
+
});
|
|
2155
|
+
}
|
|
2156
|
+
/*
|
|
2157
|
+
* Consent withdrawn, or the server refused this recorder for good: every
|
|
2158
|
+
* frame goes, including any a crash left untracked by the index when the
|
|
2159
|
+
* storage can list its keys.
|
|
2160
|
+
*/
|
|
2161
|
+
async clear() {
|
|
2162
|
+
await this.withLock(async () => {
|
|
2163
|
+
const keys = /* @__PURE__ */ new Set([
|
|
2164
|
+
this.legacyKey,
|
|
2165
|
+
this.indexKey
|
|
2166
|
+
]);
|
|
2167
|
+
for (const entry of await this.readRawIndexUnlocked()) {
|
|
2168
|
+
keys.add(this.frameKey(entry.id));
|
|
2169
|
+
}
|
|
2170
|
+
if (typeof this.storage.getAllKeys === "function") {
|
|
2171
|
+
try {
|
|
2172
|
+
for (const key of await this.storage.getAllKeys()) {
|
|
2173
|
+
if (key.startsWith(this.framePrefix)) {
|
|
2174
|
+
keys.add(key);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
} catch {
|
|
2178
|
+
}
|
|
2179
|
+
}
|
|
2180
|
+
this.migrated = true;
|
|
2181
|
+
await Promise.all(
|
|
2182
|
+
Array.from(keys).map((key) => {
|
|
2183
|
+
return this.safeRemove(key);
|
|
2184
|
+
})
|
|
2185
|
+
);
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
frameKey(id) {
|
|
2189
|
+
return `${this.framePrefix}${id}`;
|
|
2190
|
+
}
|
|
2191
|
+
/*
|
|
2192
|
+
* The index, with the legacy layout migrated into it on first use and
|
|
2193
|
+
* anything older than SESSION_REPLAY_MAX_OFFLINE_DELAY_MS pruned: the
|
|
2194
|
+
* server would no longer place it on the recording's real timeline.
|
|
2195
|
+
*/
|
|
2196
|
+
async readIndexUnlocked() {
|
|
2197
|
+
await this.migrateUnlocked();
|
|
2198
|
+
const entries = await this.readRawIndexUnlocked();
|
|
2199
|
+
const oldestKept = this.now() - SESSION_REPLAY_MAX_OFFLINE_DELAY_MS;
|
|
2200
|
+
const expired = entries.filter((entry) => {
|
|
2201
|
+
return entry.createdAtUnixMs < oldestKept;
|
|
2202
|
+
}).map((entry) => {
|
|
2203
|
+
return entry.id;
|
|
2204
|
+
});
|
|
2205
|
+
if (expired.length > 0) {
|
|
2206
|
+
await this.removeEntriesUnlocked(entries, expired);
|
|
1571
2207
|
}
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
2208
|
+
return entries.sort(byOldest);
|
|
2209
|
+
}
|
|
2210
|
+
async readRawIndexUnlocked() {
|
|
2211
|
+
let raw = null;
|
|
2212
|
+
try {
|
|
2213
|
+
raw = await this.storage.getItem(this.indexKey);
|
|
2214
|
+
} catch {
|
|
2215
|
+
raw = null;
|
|
2216
|
+
}
|
|
2217
|
+
if (!raw) {
|
|
2218
|
+
return [];
|
|
2219
|
+
}
|
|
2220
|
+
try {
|
|
2221
|
+
const parsed = JSON.parse(raw);
|
|
2222
|
+
if (Array.isArray(parsed) && parsed.every(isEntry)) {
|
|
2223
|
+
return parsed;
|
|
1577
2224
|
}
|
|
2225
|
+
} catch {
|
|
1578
2226
|
}
|
|
1579
|
-
|
|
2227
|
+
await this.safeRemove(this.indexKey);
|
|
2228
|
+
return [];
|
|
1580
2229
|
}
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
};
|
|
1595
|
-
for (var i2 = 1; i2 <= s; ++i2) {
|
|
1596
|
-
if (c[i2] == cln && i2 != s)
|
|
1597
|
-
++cls;
|
|
1598
|
-
else {
|
|
1599
|
-
if (!cln && cls > 2) {
|
|
1600
|
-
for (; cls > 138; cls -= 138)
|
|
1601
|
-
w(32754);
|
|
1602
|
-
if (cls > 2) {
|
|
1603
|
-
w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
|
|
1604
|
-
cls = 0;
|
|
1605
|
-
}
|
|
1606
|
-
} else if (cls > 3) {
|
|
1607
|
-
w(cln), --cls;
|
|
1608
|
-
for (; cls > 6; cls -= 6)
|
|
1609
|
-
w(8304);
|
|
1610
|
-
if (cls > 2)
|
|
1611
|
-
w(cls - 3 << 5 | 8208), cls = 0;
|
|
2230
|
+
async writeIndexUnlocked(entries) {
|
|
2231
|
+
if (entries.length === 0) {
|
|
2232
|
+
await this.safeRemove(this.indexKey);
|
|
2233
|
+
return true;
|
|
2234
|
+
}
|
|
2235
|
+
return await this.safeSet(this.indexKey, JSON.stringify(entries));
|
|
2236
|
+
}
|
|
2237
|
+
/* Drop entries from the index and their frames from storage. */
|
|
2238
|
+
async removeEntriesUnlocked(entries, ids) {
|
|
2239
|
+
const removing = new Set(ids);
|
|
2240
|
+
const kept = entries.filter(
|
|
2241
|
+
(entry) => {
|
|
2242
|
+
return !removing.has(entry.id);
|
|
1612
2243
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
2244
|
+
);
|
|
2245
|
+
entries.splice(0, entries.length, ...kept);
|
|
2246
|
+
await this.writeIndexUnlocked(entries);
|
|
2247
|
+
await Promise.all(
|
|
2248
|
+
ids.map((id) => {
|
|
2249
|
+
return this.safeRemove(this.frameKey(id));
|
|
2250
|
+
})
|
|
2251
|
+
);
|
|
2252
|
+
}
|
|
2253
|
+
/* Store one frame's value. Its size, or null when it could not be stored. */
|
|
2254
|
+
async writeFrameUnlocked(frame) {
|
|
2255
|
+
let value;
|
|
2256
|
+
try {
|
|
2257
|
+
const stored = {
|
|
2258
|
+
envelope: frame.envelope,
|
|
2259
|
+
gzip: encodeBase64(gzipSync(strToU8(frame.payload)))
|
|
2260
|
+
};
|
|
2261
|
+
value = JSON.stringify(stored);
|
|
2262
|
+
} catch {
|
|
2263
|
+
return null;
|
|
1617
2264
|
}
|
|
2265
|
+
return await this.safeSet(this.frameKey(frame.id), value) ? byteLength(value) : null;
|
|
1618
2266
|
}
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
l += cf[i2] * cl[i2];
|
|
1625
|
-
return l;
|
|
1626
|
-
};
|
|
1627
|
-
var wfblk = function(out, pos, dat) {
|
|
1628
|
-
var s = dat.length;
|
|
1629
|
-
var o = shft(pos + 2);
|
|
1630
|
-
out[o] = s & 255;
|
|
1631
|
-
out[o + 1] = s >> 8;
|
|
1632
|
-
out[o + 2] = out[o] ^ 255;
|
|
1633
|
-
out[o + 3] = out[o + 1] ^ 255;
|
|
1634
|
-
for (var i2 = 0; i2 < s; ++i2)
|
|
1635
|
-
out[o + i2 + 4] = dat[i2];
|
|
1636
|
-
return (o + 4 + s) * 8;
|
|
1637
|
-
};
|
|
1638
|
-
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
1639
|
-
wbits(out, p++, final);
|
|
1640
|
-
++lf[256];
|
|
1641
|
-
var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
|
|
1642
|
-
var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
|
|
1643
|
-
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
1644
|
-
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
1645
|
-
var lcfreq = new u16(19);
|
|
1646
|
-
for (var i2 = 0; i2 < lclt.length; ++i2)
|
|
1647
|
-
++lcfreq[lclt[i2] & 31];
|
|
1648
|
-
for (var i2 = 0; i2 < lcdt.length; ++i2)
|
|
1649
|
-
++lcfreq[lcdt[i2] & 31];
|
|
1650
|
-
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
1651
|
-
var nlcc = 19;
|
|
1652
|
-
for (; nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
1653
|
-
;
|
|
1654
|
-
var flen = bl + 5 << 3;
|
|
1655
|
-
var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
1656
|
-
var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
|
|
1657
|
-
if (bs >= 0 && flen <= ftlen && flen <= dtlen)
|
|
1658
|
-
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
1659
|
-
var lm, ll, dm, dl;
|
|
1660
|
-
wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
|
|
1661
|
-
if (dtlen < ftlen) {
|
|
1662
|
-
lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
|
|
1663
|
-
var llm = hMap(lct, mlcb, 0);
|
|
1664
|
-
wbits(out, p, nlc - 257);
|
|
1665
|
-
wbits(out, p + 5, ndc - 1);
|
|
1666
|
-
wbits(out, p + 10, nlcc - 4);
|
|
1667
|
-
p += 14;
|
|
1668
|
-
for (var i2 = 0; i2 < nlcc; ++i2)
|
|
1669
|
-
wbits(out, p + 3 * i2, lct[clim[i2]]);
|
|
1670
|
-
p += 3 * nlcc;
|
|
1671
|
-
var lcts = [lclt, lcdt];
|
|
1672
|
-
for (var it = 0; it < 2; ++it) {
|
|
1673
|
-
var clct = lcts[it];
|
|
1674
|
-
for (var i2 = 0; i2 < clct.length; ++i2) {
|
|
1675
|
-
var len = clct[i2] & 31;
|
|
1676
|
-
wbits(out, p, llm[len]), p += lct[len];
|
|
1677
|
-
if (len > 15)
|
|
1678
|
-
wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
|
|
2267
|
+
async readFrameUnlocked(id) {
|
|
2268
|
+
try {
|
|
2269
|
+
const raw = await this.storage.getItem(this.frameKey(id));
|
|
2270
|
+
if (!raw) {
|
|
2271
|
+
return null;
|
|
1679
2272
|
}
|
|
2273
|
+
const parsed = JSON.parse(
|
|
2274
|
+
raw
|
|
2275
|
+
);
|
|
2276
|
+
const bytes = typeof parsed.gzip === "string" ? decodeBase64(parsed.gzip) : null;
|
|
2277
|
+
if (!bytes || !isEnvelope(parsed.envelope)) {
|
|
2278
|
+
return null;
|
|
2279
|
+
}
|
|
2280
|
+
return { envelope: parsed.envelope, bytes };
|
|
2281
|
+
} catch {
|
|
2282
|
+
return null;
|
|
1680
2283
|
}
|
|
1681
|
-
} else {
|
|
1682
|
-
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
1683
2284
|
}
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
2285
|
+
/*
|
|
2286
|
+
* Move a queue written by an earlier SDK version (one JSON array under the
|
|
2287
|
+
* legacy key) into this layout, once. A legacy queue too large to read -
|
|
2288
|
+
* the very failure this layout exists to fix - cannot be recovered, only
|
|
2289
|
+
* removed so it stops failing.
|
|
2290
|
+
*/
|
|
2291
|
+
async migrateUnlocked() {
|
|
2292
|
+
if (this.migrated) {
|
|
2293
|
+
return;
|
|
2294
|
+
}
|
|
2295
|
+
this.migrated = true;
|
|
2296
|
+
let raw = null;
|
|
2297
|
+
try {
|
|
2298
|
+
raw = await this.storage.getItem(this.legacyKey);
|
|
2299
|
+
} catch {
|
|
2300
|
+
await this.safeRemove(this.legacyKey);
|
|
2301
|
+
return;
|
|
1697
2302
|
}
|
|
2303
|
+
if (!raw) {
|
|
2304
|
+
return;
|
|
2305
|
+
}
|
|
2306
|
+
let legacy = [];
|
|
2307
|
+
try {
|
|
2308
|
+
const parsed = JSON.parse(raw);
|
|
2309
|
+
if (Array.isArray(parsed)) {
|
|
2310
|
+
legacy = parsed.filter(isLegacyFrame);
|
|
2311
|
+
}
|
|
2312
|
+
} catch {
|
|
2313
|
+
legacy = [];
|
|
2314
|
+
}
|
|
2315
|
+
const entries = await this.readRawIndexUnlocked();
|
|
2316
|
+
for (const frame of legacy) {
|
|
2317
|
+
if (entries.some((entry) => {
|
|
2318
|
+
return entry.id === frame.id;
|
|
2319
|
+
})) {
|
|
2320
|
+
continue;
|
|
2321
|
+
}
|
|
2322
|
+
const bytes = await this.writeFrameUnlocked(frame);
|
|
2323
|
+
if (bytes !== null) {
|
|
2324
|
+
entries.push({
|
|
2325
|
+
id: frame.id,
|
|
2326
|
+
attempts: frame.attempts,
|
|
2327
|
+
createdAtUnixMs: frame.createdAtUnixMs,
|
|
2328
|
+
bytes
|
|
2329
|
+
});
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
await this.writeIndexUnlocked(entries.sort(byOldest));
|
|
2333
|
+
await this.safeRemove(this.legacyKey);
|
|
1698
2334
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
var syms = new i32(25e3);
|
|
1722
|
-
var lf = new u16(288), df = new u16(32);
|
|
1723
|
-
var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
1724
|
-
for (; i2 + 2 < s; ++i2) {
|
|
1725
|
-
var hv = hsh(i2);
|
|
1726
|
-
var imod = i2 & 32767, pimod = head[hv];
|
|
1727
|
-
prev[imod] = pimod;
|
|
1728
|
-
head[hv] = imod;
|
|
1729
|
-
if (wi <= i2) {
|
|
1730
|
-
var rem = s - i2;
|
|
1731
|
-
if ((lc_1 > 7e3 || li > 24576) && (rem > 423 || !lst)) {
|
|
1732
|
-
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
1733
|
-
li = lc_1 = eb = 0, bs = i2;
|
|
1734
|
-
for (var j = 0; j < 286; ++j)
|
|
1735
|
-
lf[j] = 0;
|
|
1736
|
-
for (var j = 0; j < 30; ++j)
|
|
1737
|
-
df[j] = 0;
|
|
1738
|
-
}
|
|
1739
|
-
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
1740
|
-
if (rem > 2 && hv == hsh(i2 - dif)) {
|
|
1741
|
-
var maxn = Math.min(n, rem) - 1;
|
|
1742
|
-
var maxd = Math.min(32767, i2);
|
|
1743
|
-
var ml = Math.min(258, rem);
|
|
1744
|
-
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
1745
|
-
if (dat[i2 + l] == dat[i2 + l - dif]) {
|
|
1746
|
-
var nl = 0;
|
|
1747
|
-
for (; nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
|
|
1748
|
-
;
|
|
1749
|
-
if (nl > l) {
|
|
1750
|
-
l = nl, d = dif;
|
|
1751
|
-
if (nl > maxn)
|
|
1752
|
-
break;
|
|
1753
|
-
var mmd = Math.min(dif, nl - 2);
|
|
1754
|
-
var md = 0;
|
|
1755
|
-
for (var j = 0; j < mmd; ++j) {
|
|
1756
|
-
var ti = i2 - dif + j & 32767;
|
|
1757
|
-
var pti = prev[ti];
|
|
1758
|
-
var cd = ti - pti & 32767;
|
|
1759
|
-
if (cd > md)
|
|
1760
|
-
md = cd, pimod = ti;
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
imod = pimod, pimod = prev[imod];
|
|
1765
|
-
dif += imod - pimod & 32767;
|
|
1766
|
-
}
|
|
1767
|
-
}
|
|
1768
|
-
if (d) {
|
|
1769
|
-
syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
|
|
1770
|
-
var lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
1771
|
-
eb += fleb[lin] + fdeb[din];
|
|
1772
|
-
++lf[257 + lin];
|
|
1773
|
-
++df[din];
|
|
1774
|
-
wi = i2 + l;
|
|
1775
|
-
++lc_1;
|
|
1776
|
-
} else {
|
|
1777
|
-
syms[li++] = dat[i2];
|
|
1778
|
-
++lf[dat[i2]];
|
|
1779
|
-
}
|
|
2335
|
+
async safeSet(key, value) {
|
|
2336
|
+
try {
|
|
2337
|
+
await this.storage.setItem(key, value);
|
|
2338
|
+
return true;
|
|
2339
|
+
} catch {
|
|
2340
|
+
return false;
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
async safeRemove(key) {
|
|
2344
|
+
try {
|
|
2345
|
+
await this.storage.removeItem(key);
|
|
2346
|
+
} catch {
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
async withLock(operation) {
|
|
2350
|
+
const result = this.mutationQueue.then(operation, operation);
|
|
2351
|
+
this.mutationQueue = result.then(
|
|
2352
|
+
() => {
|
|
2353
|
+
return void 0;
|
|
2354
|
+
},
|
|
2355
|
+
() => {
|
|
2356
|
+
return void 0;
|
|
1780
2357
|
}
|
|
2358
|
+
);
|
|
2359
|
+
return await result;
|
|
2360
|
+
}
|
|
2361
|
+
};
|
|
2362
|
+
|
|
2363
|
+
// src/Storage.ts
|
|
2364
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
2365
|
+
var REPLAY_ID_PATTERN = /^[0-9a-f]{32}$/u;
|
|
2366
|
+
var defaultReplayStorage = AsyncStorage;
|
|
2367
|
+
function generateReplayId() {
|
|
2368
|
+
const bytes = new Uint8Array(16);
|
|
2369
|
+
const cryptoRef = globalThis.crypto;
|
|
2370
|
+
if (cryptoRef && typeof cryptoRef.getRandomValues === "function") {
|
|
2371
|
+
cryptoRef.getRandomValues(bytes);
|
|
2372
|
+
} else {
|
|
2373
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
2374
|
+
bytes[index] = Math.floor(Math.random() * 256);
|
|
1781
2375
|
}
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
2376
|
+
}
|
|
2377
|
+
return Array.from(bytes).map((byte) => {
|
|
2378
|
+
return byte.toString(16).padStart(2, "0");
|
|
2379
|
+
}).join("");
|
|
2380
|
+
}
|
|
2381
|
+
function isReplayId(value) {
|
|
2382
|
+
return typeof value === "string" && REPLAY_ID_PATTERN.test(value);
|
|
2383
|
+
}
|
|
2384
|
+
function parseStoredSession(value) {
|
|
2385
|
+
if (!value) {
|
|
2386
|
+
return null;
|
|
2387
|
+
}
|
|
2388
|
+
try {
|
|
2389
|
+
const parsed = JSON.parse(value);
|
|
2390
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
2391
|
+
return null;
|
|
2392
|
+
}
|
|
2393
|
+
const candidate = parsed;
|
|
2394
|
+
if (!isReplayId(candidate.sessionId) || !Number.isSafeInteger(candidate.sessionStartUnixMs) || !Number.isSafeInteger(candidate.lastActivityUnixMs) || !Number.isSafeInteger(candidate.nextChunkIndex) || (candidate.nextChunkIndex ?? -1) < 0) {
|
|
2395
|
+
return null;
|
|
2396
|
+
}
|
|
2397
|
+
return candidate;
|
|
2398
|
+
} catch {
|
|
2399
|
+
return null;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
var ReplaySessionStore = class {
|
|
2403
|
+
constructor(storage, namespace) {
|
|
2404
|
+
__publicField(this, "storage");
|
|
2405
|
+
__publicField(this, "sessionKey");
|
|
2406
|
+
__publicField(this, "visitorKey");
|
|
2407
|
+
__publicField(this, "identity", null);
|
|
2408
|
+
this.storage = storage;
|
|
2409
|
+
this.sessionKey = `@oneuptime/replay/${namespace}/session`;
|
|
2410
|
+
this.visitorKey = `@oneuptime/replay/${namespace}/visitor`;
|
|
2411
|
+
}
|
|
2412
|
+
async resolve(nowUnixMs) {
|
|
2413
|
+
const stored = parseStoredSession(
|
|
2414
|
+
await this.safeGet(this.sessionKey)
|
|
2415
|
+
);
|
|
2416
|
+
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;
|
|
2417
|
+
let session;
|
|
2418
|
+
if (shouldRotate || !stored) {
|
|
2419
|
+
session = {
|
|
2420
|
+
sessionId: generateReplayId(),
|
|
2421
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2422
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2423
|
+
nextChunkIndex: 0
|
|
2424
|
+
};
|
|
2425
|
+
} else {
|
|
2426
|
+
session = {
|
|
2427
|
+
sessionId: stored.sessionId,
|
|
2428
|
+
sessionStartUnixMs: stored.sessionStartUnixMs,
|
|
2429
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2430
|
+
nextChunkIndex: stored.nextChunkIndex
|
|
2431
|
+
};
|
|
1785
2432
|
}
|
|
1786
|
-
|
|
1787
|
-
if (!
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
st.h = head, st.p = prev, st.i = i2, st.w = wi;
|
|
2433
|
+
let visitorId = await this.safeGet(this.visitorKey);
|
|
2434
|
+
if (!isReplayId(visitorId)) {
|
|
2435
|
+
visitorId = generateReplayId();
|
|
2436
|
+
await this.safeSet(this.visitorKey, visitorId);
|
|
1791
2437
|
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
2438
|
+
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
2439
|
+
this.identity = {
|
|
2440
|
+
sessionId: session.sessionId,
|
|
2441
|
+
tabId: generateReplayId(),
|
|
2442
|
+
visitorId,
|
|
2443
|
+
sessionStartUnixMs: session.sessionStartUnixMs,
|
|
2444
|
+
chunkIndex: session.nextChunkIndex
|
|
2445
|
+
};
|
|
2446
|
+
return { ...this.identity };
|
|
2447
|
+
}
|
|
2448
|
+
async takeChunkIndex(nowUnixMs) {
|
|
2449
|
+
if (!this.identity) {
|
|
2450
|
+
await this.resolve(nowUnixMs);
|
|
1800
2451
|
}
|
|
1801
|
-
|
|
2452
|
+
const identity = this.identity;
|
|
2453
|
+
const index = identity.chunkIndex;
|
|
2454
|
+
identity.chunkIndex += 1;
|
|
2455
|
+
const state = {
|
|
2456
|
+
sessionId: identity.sessionId,
|
|
2457
|
+
sessionStartUnixMs: identity.sessionStartUnixMs,
|
|
2458
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2459
|
+
nextChunkIndex: identity.chunkIndex
|
|
2460
|
+
};
|
|
2461
|
+
await this.safeSet(this.sessionKey, JSON.stringify(state));
|
|
2462
|
+
return index;
|
|
1802
2463
|
}
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
var crct = /* @__PURE__ */ (function() {
|
|
1806
|
-
var t = new Int32Array(256);
|
|
1807
|
-
for (var i2 = 0; i2 < 256; ++i2) {
|
|
1808
|
-
var c = i2, k = 9;
|
|
1809
|
-
while (--k)
|
|
1810
|
-
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
1811
|
-
t[i2] = c;
|
|
2464
|
+
getNextChunkIndex() {
|
|
2465
|
+
return this.identity?.chunkIndex ?? null;
|
|
1812
2466
|
}
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
p: function(d) {
|
|
1819
|
-
var cr = c;
|
|
1820
|
-
for (var i2 = 0; i2 < d.length; ++i2)
|
|
1821
|
-
cr = crct[cr & 255 ^ d[i2]] ^ cr >>> 8;
|
|
1822
|
-
c = cr;
|
|
1823
|
-
},
|
|
1824
|
-
d: function() {
|
|
1825
|
-
return ~c;
|
|
1826
|
-
}
|
|
1827
|
-
};
|
|
1828
|
-
};
|
|
1829
|
-
var dopt = function(dat, opt, pre, post, st) {
|
|
1830
|
-
if (!st) {
|
|
1831
|
-
st = { l: 1 };
|
|
1832
|
-
if (opt.dictionary) {
|
|
1833
|
-
var dict = opt.dictionary.subarray(-32768);
|
|
1834
|
-
var newDat = new u8(dict.length + dat.length);
|
|
1835
|
-
newDat.set(dict);
|
|
1836
|
-
newDat.set(dat, dict.length);
|
|
1837
|
-
dat = newDat;
|
|
1838
|
-
st.w = dict.length;
|
|
2467
|
+
async rotate(nowUnixMs) {
|
|
2468
|
+
let visitorId = await this.safeGet(this.visitorKey);
|
|
2469
|
+
if (!isReplayId(visitorId)) {
|
|
2470
|
+
visitorId = generateReplayId();
|
|
2471
|
+
await this.safeSet(this.visitorKey, visitorId);
|
|
1839
2472
|
}
|
|
2473
|
+
const session = {
|
|
2474
|
+
sessionId: generateReplayId(),
|
|
2475
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2476
|
+
lastActivityUnixMs: nowUnixMs,
|
|
2477
|
+
nextChunkIndex: 0
|
|
2478
|
+
};
|
|
2479
|
+
await this.safeSet(this.sessionKey, JSON.stringify(session));
|
|
2480
|
+
this.identity = {
|
|
2481
|
+
sessionId: session.sessionId,
|
|
2482
|
+
tabId: generateReplayId(),
|
|
2483
|
+
visitorId,
|
|
2484
|
+
sessionStartUnixMs: nowUnixMs,
|
|
2485
|
+
chunkIndex: 0
|
|
2486
|
+
};
|
|
2487
|
+
return { ...this.identity };
|
|
1840
2488
|
}
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
var gzh = function(c, o) {
|
|
1848
|
-
var fn = o.filename;
|
|
1849
|
-
c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3;
|
|
1850
|
-
if (o.mtime != 0)
|
|
1851
|
-
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1e3));
|
|
1852
|
-
if (fn) {
|
|
1853
|
-
c[3] = 8;
|
|
1854
|
-
for (var i2 = 0; i2 <= fn.length; ++i2)
|
|
1855
|
-
c[i2 + 10] = fn.charCodeAt(i2);
|
|
2489
|
+
async clear() {
|
|
2490
|
+
this.identity = null;
|
|
2491
|
+
await Promise.all([
|
|
2492
|
+
this.safeRemove(this.sessionKey),
|
|
2493
|
+
this.safeRemove(this.visitorKey)
|
|
2494
|
+
]);
|
|
1856
2495
|
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
opts = {};
|
|
1864
|
-
var c = crc(), l = data.length;
|
|
1865
|
-
c.p(data);
|
|
1866
|
-
var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
1867
|
-
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
1868
|
-
}
|
|
1869
|
-
var te = typeof TextEncoder != "undefined" && /* @__PURE__ */ new TextEncoder();
|
|
1870
|
-
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
|
|
1871
|
-
var tds = 0;
|
|
1872
|
-
try {
|
|
1873
|
-
td.decode(et, { stream: true });
|
|
1874
|
-
tds = 1;
|
|
1875
|
-
} catch (e) {
|
|
1876
|
-
}
|
|
1877
|
-
function strToU8(str, latin1) {
|
|
1878
|
-
if (latin1) {
|
|
1879
|
-
var ar_1 = new u8(str.length);
|
|
1880
|
-
for (var i2 = 0; i2 < str.length; ++i2)
|
|
1881
|
-
ar_1[i2] = str.charCodeAt(i2);
|
|
1882
|
-
return ar_1;
|
|
2496
|
+
async safeGet(key) {
|
|
2497
|
+
try {
|
|
2498
|
+
return await this.storage.getItem(key);
|
|
2499
|
+
} catch {
|
|
2500
|
+
return null;
|
|
2501
|
+
}
|
|
1883
2502
|
}
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
var ai = 0;
|
|
1889
|
-
var w = function(v) {
|
|
1890
|
-
ar[ai++] = v;
|
|
1891
|
-
};
|
|
1892
|
-
for (var i2 = 0; i2 < l; ++i2) {
|
|
1893
|
-
if (ai + 5 > ar.length) {
|
|
1894
|
-
var n = new u8(ai + 8 + (l - i2 << 1));
|
|
1895
|
-
n.set(ar);
|
|
1896
|
-
ar = n;
|
|
2503
|
+
async safeSet(key, value) {
|
|
2504
|
+
try {
|
|
2505
|
+
await this.storage.setItem(key, value);
|
|
2506
|
+
} catch {
|
|
1897
2507
|
}
|
|
1898
|
-
var c = str.charCodeAt(i2);
|
|
1899
|
-
if (c < 128 || latin1)
|
|
1900
|
-
w(c);
|
|
1901
|
-
else if (c < 2048)
|
|
1902
|
-
w(192 | c >> 6), w(128 | c & 63);
|
|
1903
|
-
else if (c > 55295 && c < 57344)
|
|
1904
|
-
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);
|
|
1905
|
-
else
|
|
1906
|
-
w(224 | c >> 12), w(128 | c >> 6 & 63), w(128 | c & 63);
|
|
1907
2508
|
}
|
|
1908
|
-
|
|
1909
|
-
|
|
2509
|
+
async safeRemove(key) {
|
|
2510
|
+
try {
|
|
2511
|
+
await this.storage.removeItem(key);
|
|
2512
|
+
} catch {
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
};
|
|
1910
2516
|
|
|
1911
2517
|
// src/Transport.ts
|
|
1912
2518
|
var MAX_ATTEMPTS_PER_FRAME = 3;
|
|
1913
2519
|
var DEFAULT_RETRY_MS = 15e3;
|
|
1914
2520
|
var MAX_RETRY_MS = 5 * 6e4;
|
|
1915
2521
|
var CHUNK_POST_TIMEOUT_MS = 1e4;
|
|
2522
|
+
var OFFLINE_RETRY_MS = [5e3, 15e3, 3e4, 6e4];
|
|
1916
2523
|
var DIRECTIVE_REASON_PATTERN = /^[A-Za-z0-9_.:-]{1,100}$/u;
|
|
1917
|
-
function
|
|
1918
|
-
const compressed = gzipSync(strToU8(payload));
|
|
2524
|
+
function encodeCompressedReplayFrame(originalEnvelope, compressed) {
|
|
1919
2525
|
const envelope = {
|
|
1920
2526
|
...originalEnvelope,
|
|
1921
2527
|
payloadEncoding: "gzip",
|
|
1922
2528
|
payloadBytes: compressed.byteLength,
|
|
1923
2529
|
clientSendUnixMs: Date.now()
|
|
1924
2530
|
};
|
|
1925
|
-
const prefix = strToU8(
|
|
1926
|
-
`);
|
|
2531
|
+
const prefix = strToU8(encodeSessionReplayEnvelopeLine(envelope));
|
|
1927
2532
|
const body = new Uint8Array(
|
|
1928
2533
|
prefix.byteLength + compressed.byteLength
|
|
1929
2534
|
);
|
|
@@ -1988,9 +2593,47 @@ var ReplayTransport = class {
|
|
|
1988
2593
|
__publicField(this, "retryAfterDrainMs", null);
|
|
1989
2594
|
__publicField(this, "activeAbortController", null);
|
|
1990
2595
|
__publicField(this, "abortCurrentRequest", null);
|
|
2596
|
+
/* Requests in a row that never reached the server. */
|
|
2597
|
+
__publicField(this, "connectivityFailures", 0);
|
|
2598
|
+
/* What the host app's connectivity source last said, if it has one. */
|
|
2599
|
+
__publicField(this, "reportedOffline", false);
|
|
1991
2600
|
this.options = options;
|
|
1992
2601
|
this.fetch = options.startOptions.fetch;
|
|
1993
2602
|
}
|
|
2603
|
+
/*
|
|
2604
|
+
* Offline, as far as uploading goes: the host app's connectivity source
|
|
2605
|
+
* says so, or the last request never reached the server.
|
|
2606
|
+
*/
|
|
2607
|
+
isOffline() {
|
|
2608
|
+
return this.reportedOffline || this.connectivityFailures > 0;
|
|
2609
|
+
}
|
|
2610
|
+
/*
|
|
2611
|
+
* The host app's connectivity source changed (NetInfo, typically). While
|
|
2612
|
+
* it says offline nothing is attempted. Coming back does NOT drain on its
|
|
2613
|
+
* own: whether this recorder may upload right now (consent) is the
|
|
2614
|
+
* recorder's decision, so it calls resume() itself. null means "unknown",
|
|
2615
|
+
* which blocks nothing.
|
|
2616
|
+
*/
|
|
2617
|
+
setConnectivity(isConnected) {
|
|
2618
|
+
this.reportedOffline = isConnected === false;
|
|
2619
|
+
}
|
|
2620
|
+
/*
|
|
2621
|
+
* Drain now rather than on the retry timer: the app came to the
|
|
2622
|
+
* foreground, or the network came back. An offline wait ends; a server
|
|
2623
|
+
* throttle still stands.
|
|
2624
|
+
*/
|
|
2625
|
+
resume() {
|
|
2626
|
+
if (this.stopped || this.reportedOffline) {
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
if (this.connectivityFailures > 0 && this.retryTimer) {
|
|
2630
|
+
clearTimeout(this.retryTimer);
|
|
2631
|
+
this.retryTimer = null;
|
|
2632
|
+
}
|
|
2633
|
+
if (!this.retryTimer) {
|
|
2634
|
+
void this.drain();
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
1994
2637
|
async enqueue(envelope, payload) {
|
|
1995
2638
|
if (this.stopped) {
|
|
1996
2639
|
return;
|
|
@@ -2007,13 +2650,15 @@ var ReplayTransport = class {
|
|
|
2007
2650
|
dropped: mutation.dropped
|
|
2008
2651
|
});
|
|
2009
2652
|
}
|
|
2010
|
-
|
|
2653
|
+
if (!this.retryTimer) {
|
|
2654
|
+
await this.drain();
|
|
2655
|
+
}
|
|
2011
2656
|
}
|
|
2012
2657
|
async restore() {
|
|
2013
2658
|
await this.drain();
|
|
2014
2659
|
}
|
|
2015
2660
|
async drain() {
|
|
2016
|
-
if (this.stopped) {
|
|
2661
|
+
if (this.stopped || this.reportedOffline) {
|
|
2017
2662
|
return;
|
|
2018
2663
|
}
|
|
2019
2664
|
if (this.drainPromise) {
|
|
@@ -2042,11 +2687,19 @@ var ReplayTransport = class {
|
|
|
2042
2687
|
return this.flushFailures;
|
|
2043
2688
|
}
|
|
2044
2689
|
async drainLoop() {
|
|
2045
|
-
const
|
|
2046
|
-
for (const
|
|
2047
|
-
if (this.stopped) {
|
|
2690
|
+
const entries = await this.options.outbox.entries();
|
|
2691
|
+
for (const entry of entries) {
|
|
2692
|
+
if (this.stopped || this.reportedOffline) {
|
|
2048
2693
|
return;
|
|
2049
2694
|
}
|
|
2695
|
+
const frame = await this.options.outbox.load(entry.id);
|
|
2696
|
+
if (frame === "unreadable") {
|
|
2697
|
+
this.options.onDiagnostic("outbox-frame-unreadable");
|
|
2698
|
+
continue;
|
|
2699
|
+
}
|
|
2700
|
+
if (!frame) {
|
|
2701
|
+
continue;
|
|
2702
|
+
}
|
|
2050
2703
|
const outcome = await this.post(frame);
|
|
2051
2704
|
if (outcome === "remove") {
|
|
2052
2705
|
await this.options.outbox.remove(frame.id);
|
|
@@ -2059,10 +2712,13 @@ var ReplayTransport = class {
|
|
|
2059
2712
|
if (outcome === "stop") {
|
|
2060
2713
|
return;
|
|
2061
2714
|
}
|
|
2715
|
+
this.flushFailures += 1;
|
|
2716
|
+
if (outcome === "wait") {
|
|
2717
|
+
return;
|
|
2718
|
+
}
|
|
2062
2719
|
const attempts = await this.options.outbox.incrementAttempts(
|
|
2063
2720
|
frame.id
|
|
2064
2721
|
);
|
|
2065
|
-
this.flushFailures += 1;
|
|
2066
2722
|
if (attempts >= MAX_ATTEMPTS_PER_FRAME) {
|
|
2067
2723
|
await this.options.outbox.remove(frame.id);
|
|
2068
2724
|
this.options.onDiagnostic("chunk-retry-exhausted", {
|
|
@@ -2077,9 +2733,9 @@ var ReplayTransport = class {
|
|
|
2077
2733
|
}
|
|
2078
2734
|
}
|
|
2079
2735
|
async post(frame) {
|
|
2080
|
-
const encoded =
|
|
2736
|
+
const encoded = encodeCompressedReplayFrame(
|
|
2081
2737
|
frame.envelope,
|
|
2082
|
-
frame.
|
|
2738
|
+
frame.compressedPayload
|
|
2083
2739
|
);
|
|
2084
2740
|
if (encoded.body.byteLength > MAX_SESSION_REPLAY_CHUNK_BYTES) {
|
|
2085
2741
|
this.options.onDiagnostic("chunk-too-large", {
|
|
@@ -2138,7 +2794,9 @@ var ReplayTransport = class {
|
|
|
2138
2794
|
chunkIndex: frame.envelope.chunkIndex
|
|
2139
2795
|
}
|
|
2140
2796
|
);
|
|
2141
|
-
|
|
2797
|
+
this.connectivityFailures += 1;
|
|
2798
|
+
this.retryAfterDrainMs = OFFLINE_RETRY_MS[Math.min(this.connectivityFailures, OFFLINE_RETRY_MS.length) - 1];
|
|
2799
|
+
return "wait";
|
|
2142
2800
|
} finally {
|
|
2143
2801
|
if (timeout) {
|
|
2144
2802
|
clearTimeout(timeout);
|
|
@@ -2150,6 +2808,10 @@ var ReplayTransport = class {
|
|
|
2150
2808
|
this.abortCurrentRequest = null;
|
|
2151
2809
|
}
|
|
2152
2810
|
}
|
|
2811
|
+
if (this.connectivityFailures > 0) {
|
|
2812
|
+
this.connectivityFailures = 0;
|
|
2813
|
+
this.options.onDiagnostic("back-online");
|
|
2814
|
+
}
|
|
2153
2815
|
if (said.directive) {
|
|
2154
2816
|
this.options.onDirective(said.directive, said.reason);
|
|
2155
2817
|
}
|
|
@@ -2191,6 +2853,9 @@ var ReplayTransport = class {
|
|
|
2191
2853
|
(said.retryAfterSeconds ?? DEFAULT_RETRY_MS / 1e3) * 1e3
|
|
2192
2854
|
);
|
|
2193
2855
|
this.retryAfterDrainMs = retryMs;
|
|
2856
|
+
if (response.status === 429 || said.directive === "throttle" || said.retryAfterSeconds !== null) {
|
|
2857
|
+
return "wait";
|
|
2858
|
+
}
|
|
2194
2859
|
return "retry";
|
|
2195
2860
|
}
|
|
2196
2861
|
scheduleRetry(delayMs) {
|
|
@@ -2374,6 +3039,21 @@ var MobileReplayRecorder = class {
|
|
|
2374
3039
|
__publicField(this, "captureTimer", null);
|
|
2375
3040
|
__publicField(this, "flushTimer", null);
|
|
2376
3041
|
__publicField(this, "appStateSubscription", null);
|
|
3042
|
+
/*
|
|
3043
|
+
* Offline mode: the host app's connectivity source (start option
|
|
3044
|
+
* `connectivity`), and what it last said, which a transport created later
|
|
3045
|
+
* - after a consent or identity change - starts from.
|
|
3046
|
+
*/
|
|
3047
|
+
__publicField(this, "unsubscribeConnectivity", null);
|
|
3048
|
+
__publicField(this, "lastConnectivity", null);
|
|
3049
|
+
/*
|
|
3050
|
+
* The policy in force is the cached one an offline launch started with,
|
|
3051
|
+
* or the last refresh could not reach the server. Refreshed the moment the
|
|
3052
|
+
* connection is back rather than on the five-minute schedule, so a policy
|
|
3053
|
+
* changed while the device was offline takes effect before its backlog
|
|
3054
|
+
* has finished uploading.
|
|
3055
|
+
*/
|
|
3056
|
+
__publicField(this, "policyStale", false);
|
|
2377
3057
|
__publicField(this, "captureGeneration", null);
|
|
2378
3058
|
__publicField(this, "running", false);
|
|
2379
3059
|
__publicField(this, "foreground", true);
|
|
@@ -2510,11 +3190,32 @@ var MobileReplayRecorder = class {
|
|
|
2510
3190
|
});
|
|
2511
3191
|
return false;
|
|
2512
3192
|
}
|
|
3193
|
+
const namespace = getReplayStorageNamespace(validated);
|
|
2513
3194
|
let config = await fetchReplayConfig(this.options);
|
|
2514
3195
|
if (!this.isCurrentGeneration(generation)) {
|
|
2515
3196
|
return false;
|
|
2516
3197
|
}
|
|
2517
|
-
|
|
3198
|
+
let configFromCache = false;
|
|
3199
|
+
if (isRetryablePolicyFailure(config)) {
|
|
3200
|
+
const cached = await loadCachedReplayConfig(
|
|
3201
|
+
this.storage,
|
|
3202
|
+
namespace,
|
|
3203
|
+
this.now()
|
|
3204
|
+
);
|
|
3205
|
+
if (!this.isCurrentGeneration(generation)) {
|
|
3206
|
+
return false;
|
|
3207
|
+
}
|
|
3208
|
+
if (cached) {
|
|
3209
|
+
this.diagnostic("config-from-cache", {
|
|
3210
|
+
reason: config.disabledReason ?? "not-reported"
|
|
3211
|
+
});
|
|
3212
|
+
config = cached;
|
|
3213
|
+
configFromCache = true;
|
|
3214
|
+
}
|
|
3215
|
+
} else if (this.mayPersistUnder(config)) {
|
|
3216
|
+
await saveReplayConfig(this.storage, namespace, config, this.now());
|
|
3217
|
+
}
|
|
3218
|
+
if (!configFromCache && config.enabled && this.userRef && (config.consentMode === "NotRequired" /* NotRequired */ || this.consentGranted)) {
|
|
2518
3219
|
config = await this.refreshTargetingConfig(config);
|
|
2519
3220
|
if (!this.isCurrentGeneration(generation)) {
|
|
2520
3221
|
return false;
|
|
@@ -2527,8 +3228,8 @@ var MobileReplayRecorder = class {
|
|
|
2527
3228
|
});
|
|
2528
3229
|
return false;
|
|
2529
3230
|
}
|
|
2530
|
-
this.lastPolicyRefreshAtUnixMs = this.now();
|
|
2531
|
-
|
|
3231
|
+
this.lastPolicyRefreshAtUnixMs = configFromCache ? 0 : this.now();
|
|
3232
|
+
this.policyStale = configFromCache;
|
|
2532
3233
|
const sessionStore = new ReplaySessionStore(
|
|
2533
3234
|
this.storage,
|
|
2534
3235
|
namespace
|
|
@@ -2557,8 +3258,9 @@ var MobileReplayRecorder = class {
|
|
|
2557
3258
|
this.disable("not-sampled");
|
|
2558
3259
|
return false;
|
|
2559
3260
|
}
|
|
2560
|
-
this.outbox = new ReplayOutbox(this.storage, namespace);
|
|
3261
|
+
this.outbox = new ReplayOutbox(this.storage, namespace, this.now);
|
|
2561
3262
|
this.transport = this.createTransport(validated, this.outbox);
|
|
3263
|
+
this.subscribeConnectivity(validated);
|
|
2562
3264
|
try {
|
|
2563
3265
|
const nativeMetadata = await this.nativeViewTree.getAppMetadata();
|
|
2564
3266
|
if (!this.isCurrentGeneration(generation)) {
|
|
@@ -2708,6 +3410,7 @@ var MobileReplayRecorder = class {
|
|
|
2708
3410
|
});
|
|
2709
3411
|
await this.outbox?.clear();
|
|
2710
3412
|
await this.sessionStore?.clear();
|
|
3413
|
+
await this.forgetCachedConfig();
|
|
2711
3414
|
this.identity = null;
|
|
2712
3415
|
this.userRef = null;
|
|
2713
3416
|
this.traits = {};
|
|
@@ -3321,6 +4024,9 @@ var MobileReplayRecorder = class {
|
|
|
3321
4024
|
this.startTimers();
|
|
3322
4025
|
this.diagnosticsStatus = this.consentState() === "Unknown" ? "consent-required" : "recording";
|
|
3323
4026
|
await this.captureTick(true);
|
|
4027
|
+
if (this.uploadActive && this.running) {
|
|
4028
|
+
this.transport?.resume();
|
|
4029
|
+
}
|
|
3324
4030
|
}
|
|
3325
4031
|
}
|
|
3326
4032
|
startTimers() {
|
|
@@ -3382,7 +4088,7 @@ var MobileReplayRecorder = class {
|
|
|
3382
4088
|
this.installedGlobalErrorHandler = null;
|
|
3383
4089
|
}
|
|
3384
4090
|
createTransport(startOptions, outbox) {
|
|
3385
|
-
|
|
4091
|
+
const transport = new ReplayTransport({
|
|
3386
4092
|
startOptions,
|
|
3387
4093
|
outbox,
|
|
3388
4094
|
onDirective: (directive, reason) => {
|
|
@@ -3390,8 +4096,15 @@ var MobileReplayRecorder = class {
|
|
|
3390
4096
|
},
|
|
3391
4097
|
onDiagnostic: (code, details) => {
|
|
3392
4098
|
this.diagnostic(code, details);
|
|
4099
|
+
if (code === "back-online") {
|
|
4100
|
+
this.onBackOnline();
|
|
4101
|
+
}
|
|
3393
4102
|
}
|
|
3394
4103
|
});
|
|
4104
|
+
if (this.lastConnectivity !== null) {
|
|
4105
|
+
transport.setConnectivity(this.lastConnectivity);
|
|
4106
|
+
}
|
|
4107
|
+
return transport;
|
|
3395
4108
|
}
|
|
3396
4109
|
onDirective(directive, reason) {
|
|
3397
4110
|
this.diagnostic("server-directive", { directive, reason });
|
|
@@ -3430,8 +4143,76 @@ var MobileReplayRecorder = class {
|
|
|
3430
4143
|
this.clearTimers();
|
|
3431
4144
|
this.appStateSubscription?.remove();
|
|
3432
4145
|
this.appStateSubscription = null;
|
|
4146
|
+
this.stopConnectivity();
|
|
3433
4147
|
this.restoreGlobalErrorHandler();
|
|
3434
4148
|
}
|
|
4149
|
+
/*
|
|
4150
|
+
* Whether this device may be written to under a policy. Nothing is stored
|
|
4151
|
+
* before an explicit consent the policy requires - the cached policy
|
|
4152
|
+
* included, even though it holds no user data - except a removal: a
|
|
4153
|
+
* policy that says replay is off always deletes the cached one.
|
|
4154
|
+
*/
|
|
4155
|
+
/*
|
|
4156
|
+
* The cached policy goes with everything else when consent does: it holds
|
|
4157
|
+
* no user data, but "nothing of the recorder stays on the device" is the
|
|
4158
|
+
* promise, and the next consented policy fetch writes it again.
|
|
4159
|
+
*/
|
|
4160
|
+
async forgetCachedConfig() {
|
|
4161
|
+
if (this.options) {
|
|
4162
|
+
await forgetReplayConfig(
|
|
4163
|
+
this.storage,
|
|
4164
|
+
getReplayStorageNamespace(this.options)
|
|
4165
|
+
);
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
mayPersistUnder(config) {
|
|
4169
|
+
return !config.enabled || config.consentMode === "NotRequired" /* NotRequired */ || this.consentGranted;
|
|
4170
|
+
}
|
|
4171
|
+
subscribeConnectivity(options) {
|
|
4172
|
+
this.stopConnectivity();
|
|
4173
|
+
this.lastConnectivity = null;
|
|
4174
|
+
if (!options.connectivity) {
|
|
4175
|
+
return;
|
|
4176
|
+
}
|
|
4177
|
+
try {
|
|
4178
|
+
const unsubscribe = options.connectivity.subscribe(
|
|
4179
|
+
(isConnected) => {
|
|
4180
|
+
const connected = typeof isConnected === "boolean" ? isConnected : null;
|
|
4181
|
+
if (connected === this.lastConnectivity) {
|
|
4182
|
+
return;
|
|
4183
|
+
}
|
|
4184
|
+
this.lastConnectivity = connected;
|
|
4185
|
+
if (connected !== null) {
|
|
4186
|
+
this.diagnostic(connected ? "network-online" : "network-offline");
|
|
4187
|
+
}
|
|
4188
|
+
this.transport?.setConnectivity(connected);
|
|
4189
|
+
if (connected === true) {
|
|
4190
|
+
this.onBackOnline();
|
|
4191
|
+
if (this.uploadActive && this.running) {
|
|
4192
|
+
this.transport?.resume();
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
}
|
|
4196
|
+
);
|
|
4197
|
+
this.unsubscribeConnectivity = typeof unsubscribe === "function" ? unsubscribe : null;
|
|
4198
|
+
} catch {
|
|
4199
|
+
this.diagnostic("connectivity-subscribe-failed");
|
|
4200
|
+
}
|
|
4201
|
+
}
|
|
4202
|
+
/* The next capture tick refreshes a stale policy (see policyStale). */
|
|
4203
|
+
onBackOnline() {
|
|
4204
|
+
if (this.policyStale) {
|
|
4205
|
+
this.lastPolicyRefreshAtUnixMs = 0;
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
stopConnectivity() {
|
|
4209
|
+
const unsubscribe = this.unsubscribeConnectivity;
|
|
4210
|
+
this.unsubscribeConnectivity = null;
|
|
4211
|
+
try {
|
|
4212
|
+
unsubscribe?.();
|
|
4213
|
+
} catch {
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
3435
4216
|
isCurrentGeneration(generation) {
|
|
3436
4217
|
return generation === this.lifecycleGeneration;
|
|
3437
4218
|
}
|
|
@@ -3662,11 +4443,23 @@ var MobileReplayRecorder = class {
|
|
|
3662
4443
|
}
|
|
3663
4444
|
}
|
|
3664
4445
|
this.lastPolicyRefreshAtUnixMs = nowUnixMs;
|
|
4446
|
+
if (!isRetryablePolicyFailure(freshConfig) && this.mayPersistUnder(freshConfig)) {
|
|
4447
|
+
await saveReplayConfig(
|
|
4448
|
+
this.storage,
|
|
4449
|
+
getReplayStorageNamespace(currentOptions),
|
|
4450
|
+
freshConfig,
|
|
4451
|
+
nowUnixMs
|
|
4452
|
+
);
|
|
4453
|
+
if (!this.running || !this.isCurrentGeneration(generation)) {
|
|
4454
|
+
return false;
|
|
4455
|
+
}
|
|
4456
|
+
}
|
|
3665
4457
|
if (!freshConfig.enabled) {
|
|
3666
4458
|
if (reason !== "consent" && isRetryablePolicyFailure(freshConfig)) {
|
|
3667
4459
|
this.diagnostic("policy-refresh-failed-using-last-config", {
|
|
3668
4460
|
reason
|
|
3669
4461
|
});
|
|
4462
|
+
this.policyStale = true;
|
|
3670
4463
|
return true;
|
|
3671
4464
|
}
|
|
3672
4465
|
this.config = freshConfig;
|
|
@@ -3676,6 +4469,7 @@ var MobileReplayRecorder = class {
|
|
|
3676
4469
|
);
|
|
3677
4470
|
return false;
|
|
3678
4471
|
}
|
|
4472
|
+
this.policyStale = false;
|
|
3679
4473
|
return await this.applyRuntimePolicy(
|
|
3680
4474
|
previousConfig,
|
|
3681
4475
|
freshConfig,
|
|
@@ -3722,6 +4516,7 @@ var MobileReplayRecorder = class {
|
|
|
3722
4516
|
});
|
|
3723
4517
|
await this.outbox?.clear();
|
|
3724
4518
|
await this.sessionStore?.clear();
|
|
4519
|
+
await this.forgetCachedConfig();
|
|
3725
4520
|
if (!this.running || !this.isCurrentGeneration(generation)) {
|
|
3726
4521
|
return false;
|
|
3727
4522
|
}
|