@ours.network/messenger-server 1.0.31-nightly.20 → 1.0.31-nightly.21
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.
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
publicEngineError,
|
|
11
11
|
publicInternalError,
|
|
12
12
|
reportFailure
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-BB74SVTG.js";
|
|
14
14
|
|
|
15
15
|
// node_modules/bn.js/lib/bn.js
|
|
16
16
|
var require_bn = __commonJS({
|
|
@@ -141,13 +141,13 @@ var require_bn = __commonJS({
|
|
|
141
141
|
for (var i = 0; i < this.length; i++) {
|
|
142
142
|
this.words[i] = 0;
|
|
143
143
|
}
|
|
144
|
-
var j,
|
|
144
|
+
var j, w2;
|
|
145
145
|
var off = 0;
|
|
146
146
|
if (endian === "be") {
|
|
147
147
|
for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
|
|
148
|
-
|
|
149
|
-
this.words[j] |=
|
|
150
|
-
this.words[j + 1] =
|
|
148
|
+
w2 = number[i] | number[i - 1] << 8 | number[i - 2] << 16;
|
|
149
|
+
this.words[j] |= w2 << off & 67108863;
|
|
150
|
+
this.words[j + 1] = w2 >>> 26 - off & 67108863;
|
|
151
151
|
off += 24;
|
|
152
152
|
if (off >= 26) {
|
|
153
153
|
off -= 26;
|
|
@@ -156,9 +156,9 @@ var require_bn = __commonJS({
|
|
|
156
156
|
}
|
|
157
157
|
} else if (endian === "le") {
|
|
158
158
|
for (i = 0, j = 0; i < number.length; i += 3) {
|
|
159
|
-
|
|
160
|
-
this.words[j] |=
|
|
161
|
-
this.words[j + 1] =
|
|
159
|
+
w2 = number[i] | number[i + 1] << 8 | number[i + 2] << 16;
|
|
160
|
+
this.words[j] |= w2 << off & 67108863;
|
|
161
|
+
this.words[j + 1] = w2 >>> 26 - off & 67108863;
|
|
162
162
|
off += 24;
|
|
163
163
|
if (off >= 26) {
|
|
164
164
|
off -= 26;
|
|
@@ -193,15 +193,15 @@ var require_bn = __commonJS({
|
|
|
193
193
|
}
|
|
194
194
|
var off = 0;
|
|
195
195
|
var j = 0;
|
|
196
|
-
var
|
|
196
|
+
var w2;
|
|
197
197
|
if (endian === "be") {
|
|
198
198
|
for (i = number.length - 1; i >= start2; i -= 2) {
|
|
199
|
-
|
|
200
|
-
this.words[j] |=
|
|
199
|
+
w2 = parseHexByte(number, start2, i) << off;
|
|
200
|
+
this.words[j] |= w2 & 67108863;
|
|
201
201
|
if (off >= 18) {
|
|
202
202
|
off -= 18;
|
|
203
203
|
j += 1;
|
|
204
|
-
this.words[j] |=
|
|
204
|
+
this.words[j] |= w2 >>> 26;
|
|
205
205
|
} else {
|
|
206
206
|
off += 8;
|
|
207
207
|
}
|
|
@@ -209,12 +209,12 @@ var require_bn = __commonJS({
|
|
|
209
209
|
} else {
|
|
210
210
|
var parseLength = number.length - start2;
|
|
211
211
|
for (i = parseLength % 2 === 0 ? start2 + 1 : start2; i < number.length; i += 2) {
|
|
212
|
-
|
|
213
|
-
this.words[j] |=
|
|
212
|
+
w2 = parseHexByte(number, start2, i) << off;
|
|
213
|
+
this.words[j] |= w2 & 67108863;
|
|
214
214
|
if (off >= 18) {
|
|
215
215
|
off -= 18;
|
|
216
216
|
j += 1;
|
|
217
|
-
this.words[j] |=
|
|
217
|
+
this.words[j] |= w2 >>> 26;
|
|
218
218
|
} else {
|
|
219
219
|
off += 8;
|
|
220
220
|
}
|
|
@@ -424,9 +424,9 @@ var require_bn = __commonJS({
|
|
|
424
424
|
var off = 0;
|
|
425
425
|
var carry = 0;
|
|
426
426
|
for (var i = 0; i < this.length; i++) {
|
|
427
|
-
var
|
|
428
|
-
var word = ((
|
|
429
|
-
carry =
|
|
427
|
+
var w2 = this.words[i];
|
|
428
|
+
var word = ((w2 << off | carry) & 16777215).toString(16);
|
|
429
|
+
carry = w2 >>> 24 - off & 16777215;
|
|
430
430
|
off += 2;
|
|
431
431
|
if (off >= 26) {
|
|
432
432
|
off -= 26;
|
|
@@ -507,20 +507,20 @@ var require_bn = __commonJS({
|
|
|
507
507
|
var littleEndian = endian === "le";
|
|
508
508
|
var res = new ArrayType(reqLength);
|
|
509
509
|
var b2, i;
|
|
510
|
-
var
|
|
510
|
+
var q = this.clone();
|
|
511
511
|
if (!littleEndian) {
|
|
512
512
|
for (i = 0; i < reqLength - byteLength; i++) {
|
|
513
513
|
res[i] = 0;
|
|
514
514
|
}
|
|
515
|
-
for (i = 0; !
|
|
516
|
-
b2 =
|
|
517
|
-
|
|
515
|
+
for (i = 0; !q.isZero(); i++) {
|
|
516
|
+
b2 = q.andln(255);
|
|
517
|
+
q.iushrn(8);
|
|
518
518
|
res[reqLength - i - 1] = b2;
|
|
519
519
|
}
|
|
520
520
|
} else {
|
|
521
|
-
for (i = 0; !
|
|
522
|
-
b2 =
|
|
523
|
-
|
|
521
|
+
for (i = 0; !q.isZero(); i++) {
|
|
522
|
+
b2 = q.andln(255);
|
|
523
|
+
q.iushrn(8);
|
|
524
524
|
res[i] = b2;
|
|
525
525
|
}
|
|
526
526
|
for (; i < reqLength; i++) {
|
|
@@ -530,12 +530,12 @@ var require_bn = __commonJS({
|
|
|
530
530
|
return res;
|
|
531
531
|
};
|
|
532
532
|
if (Math.clz32) {
|
|
533
|
-
BN.prototype._countBits = function _countBits(
|
|
534
|
-
return 32 - Math.clz32(
|
|
533
|
+
BN.prototype._countBits = function _countBits(w2) {
|
|
534
|
+
return 32 - Math.clz32(w2);
|
|
535
535
|
};
|
|
536
536
|
} else {
|
|
537
|
-
BN.prototype._countBits = function _countBits(
|
|
538
|
-
var t =
|
|
537
|
+
BN.prototype._countBits = function _countBits(w2) {
|
|
538
|
+
var t = w2;
|
|
539
539
|
var r = 0;
|
|
540
540
|
if (t >= 4096) {
|
|
541
541
|
r += 13;
|
|
@@ -556,9 +556,9 @@ var require_bn = __commonJS({
|
|
|
556
556
|
return r + t;
|
|
557
557
|
};
|
|
558
558
|
}
|
|
559
|
-
BN.prototype._zeroBits = function _zeroBits(
|
|
560
|
-
if (
|
|
561
|
-
var t =
|
|
559
|
+
BN.prototype._zeroBits = function _zeroBits(w2) {
|
|
560
|
+
if (w2 === 0) return 26;
|
|
561
|
+
var t = w2;
|
|
562
562
|
var r = 0;
|
|
563
563
|
if ((t & 8191) === 0) {
|
|
564
564
|
r += 13;
|
|
@@ -582,18 +582,18 @@ var require_bn = __commonJS({
|
|
|
582
582
|
return r;
|
|
583
583
|
};
|
|
584
584
|
BN.prototype.bitLength = function bitLength() {
|
|
585
|
-
var
|
|
586
|
-
var hi = this._countBits(
|
|
585
|
+
var w2 = this.words[this.length - 1];
|
|
586
|
+
var hi = this._countBits(w2);
|
|
587
587
|
return (this.length - 1) * 26 + hi;
|
|
588
588
|
};
|
|
589
589
|
function toBitArray(num) {
|
|
590
|
-
var
|
|
591
|
-
for (var bit = 0; bit <
|
|
590
|
+
var w2 = new Array(num.bitLength());
|
|
591
|
+
for (var bit = 0; bit < w2.length; bit++) {
|
|
592
592
|
var off = bit / 26 | 0;
|
|
593
593
|
var wbit = bit % 26;
|
|
594
|
-
|
|
594
|
+
w2[bit] = (num.words[off] & 1 << wbit) >>> wbit;
|
|
595
595
|
}
|
|
596
|
-
return
|
|
596
|
+
return w2;
|
|
597
597
|
}
|
|
598
598
|
BN.prototype.zeroBits = function zeroBits() {
|
|
599
599
|
if (this.isZero()) return 0;
|
|
@@ -868,23 +868,23 @@ var require_bn = __commonJS({
|
|
|
868
868
|
var lo = r & 67108863;
|
|
869
869
|
var carry = r / 67108864 | 0;
|
|
870
870
|
out.words[0] = lo;
|
|
871
|
-
for (var
|
|
871
|
+
for (var k = 1; k < len; k++) {
|
|
872
872
|
var ncarry = carry >>> 26;
|
|
873
873
|
var rword = carry & 67108863;
|
|
874
|
-
var maxJ = Math.min(
|
|
875
|
-
for (var j = Math.max(0,
|
|
876
|
-
var i =
|
|
874
|
+
var maxJ = Math.min(k, num.length - 1);
|
|
875
|
+
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
876
|
+
var i = k - j | 0;
|
|
877
877
|
a = self.words[i] | 0;
|
|
878
878
|
b2 = num.words[j] | 0;
|
|
879
879
|
r = a * b2 + rword;
|
|
880
880
|
ncarry += r / 67108864 | 0;
|
|
881
881
|
rword = r & 67108863;
|
|
882
882
|
}
|
|
883
|
-
out.words[
|
|
883
|
+
out.words[k] = rword | 0;
|
|
884
884
|
carry = ncarry | 0;
|
|
885
885
|
}
|
|
886
886
|
if (carry !== 0) {
|
|
887
|
-
out.words[
|
|
887
|
+
out.words[k] = carry | 0;
|
|
888
888
|
} else {
|
|
889
889
|
out.length--;
|
|
890
890
|
}
|
|
@@ -990,9 +990,9 @@ var require_bn = __commonJS({
|
|
|
990
990
|
mid = mid + Math.imul(al0, bh2) | 0;
|
|
991
991
|
mid = mid + Math.imul(ah0, bl2) | 0;
|
|
992
992
|
hi = hi + Math.imul(ah0, bh2) | 0;
|
|
993
|
-
var
|
|
994
|
-
c = (hi + (mid >>> 13) | 0) + (
|
|
995
|
-
|
|
993
|
+
var w2 = (c + lo | 0) + ((mid & 8191) << 13) | 0;
|
|
994
|
+
c = (hi + (mid >>> 13) | 0) + (w2 >>> 26) | 0;
|
|
995
|
+
w2 &= 67108863;
|
|
996
996
|
lo = Math.imul(al3, bl0);
|
|
997
997
|
mid = Math.imul(al3, bh0);
|
|
998
998
|
mid = mid + Math.imul(ah3, bl0) | 0;
|
|
@@ -1419,7 +1419,7 @@ var require_bn = __commonJS({
|
|
|
1419
1419
|
w18 &= 67108863;
|
|
1420
1420
|
o[0] = w0;
|
|
1421
1421
|
o[1] = w1;
|
|
1422
|
-
o[2] =
|
|
1422
|
+
o[2] = w2;
|
|
1423
1423
|
o[3] = w3;
|
|
1424
1424
|
o[4] = w4;
|
|
1425
1425
|
o[5] = w5;
|
|
@@ -1450,13 +1450,13 @@ var require_bn = __commonJS({
|
|
|
1450
1450
|
out.length = self.length + num.length;
|
|
1451
1451
|
var carry = 0;
|
|
1452
1452
|
var hncarry = 0;
|
|
1453
|
-
for (var
|
|
1453
|
+
for (var k = 0; k < out.length - 1; k++) {
|
|
1454
1454
|
var ncarry = hncarry;
|
|
1455
1455
|
hncarry = 0;
|
|
1456
1456
|
var rword = carry & 67108863;
|
|
1457
|
-
var maxJ = Math.min(
|
|
1458
|
-
for (var j = Math.max(0,
|
|
1459
|
-
var i =
|
|
1457
|
+
var maxJ = Math.min(k, num.length - 1);
|
|
1458
|
+
for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
|
|
1459
|
+
var i = k - j;
|
|
1460
1460
|
var a = self.words[i] | 0;
|
|
1461
1461
|
var b2 = num.words[j] | 0;
|
|
1462
1462
|
var r = a * b2;
|
|
@@ -1468,12 +1468,12 @@ var require_bn = __commonJS({
|
|
|
1468
1468
|
hncarry += ncarry >>> 26;
|
|
1469
1469
|
ncarry &= 67108863;
|
|
1470
1470
|
}
|
|
1471
|
-
out.words[
|
|
1471
|
+
out.words[k] = rword;
|
|
1472
1472
|
carry = ncarry;
|
|
1473
1473
|
ncarry = hncarry;
|
|
1474
1474
|
}
|
|
1475
1475
|
if (carry !== 0) {
|
|
1476
|
-
out.words[
|
|
1476
|
+
out.words[k] = carry;
|
|
1477
1477
|
} else {
|
|
1478
1478
|
out.length--;
|
|
1479
1479
|
}
|
|
@@ -1497,54 +1497,54 @@ var require_bn = __commonJS({
|
|
|
1497
1497
|
}
|
|
1498
1498
|
return res;
|
|
1499
1499
|
};
|
|
1500
|
-
function FFTM(
|
|
1501
|
-
this.x =
|
|
1502
|
-
this.y =
|
|
1500
|
+
function FFTM(x, y2) {
|
|
1501
|
+
this.x = x;
|
|
1502
|
+
this.y = y2;
|
|
1503
1503
|
}
|
|
1504
|
-
FFTM.prototype.makeRBT = function makeRBT(
|
|
1505
|
-
var t = new Array(
|
|
1506
|
-
var l = BN.prototype._countBits(
|
|
1507
|
-
for (var i = 0; i <
|
|
1508
|
-
t[i] = this.revBin(i, l,
|
|
1504
|
+
FFTM.prototype.makeRBT = function makeRBT(N) {
|
|
1505
|
+
var t = new Array(N);
|
|
1506
|
+
var l = BN.prototype._countBits(N) - 1;
|
|
1507
|
+
for (var i = 0; i < N; i++) {
|
|
1508
|
+
t[i] = this.revBin(i, l, N);
|
|
1509
1509
|
}
|
|
1510
1510
|
return t;
|
|
1511
1511
|
};
|
|
1512
|
-
FFTM.prototype.revBin = function revBin(
|
|
1513
|
-
if (
|
|
1512
|
+
FFTM.prototype.revBin = function revBin(x, l, N) {
|
|
1513
|
+
if (x === 0 || x === N - 1) return x;
|
|
1514
1514
|
var rb = 0;
|
|
1515
1515
|
for (var i = 0; i < l; i++) {
|
|
1516
|
-
rb |= (
|
|
1517
|
-
|
|
1516
|
+
rb |= (x & 1) << l - i - 1;
|
|
1517
|
+
x >>= 1;
|
|
1518
1518
|
}
|
|
1519
1519
|
return rb;
|
|
1520
1520
|
};
|
|
1521
|
-
FFTM.prototype.permute = function permute(rbt, rws, iws, rtws, itws,
|
|
1522
|
-
for (var i = 0; i <
|
|
1521
|
+
FFTM.prototype.permute = function permute(rbt, rws, iws, rtws, itws, N) {
|
|
1522
|
+
for (var i = 0; i < N; i++) {
|
|
1523
1523
|
rtws[i] = rws[rbt[i]];
|
|
1524
1524
|
itws[i] = iws[rbt[i]];
|
|
1525
1525
|
}
|
|
1526
1526
|
};
|
|
1527
|
-
FFTM.prototype.transform = function transform(rws, iws, rtws, itws,
|
|
1528
|
-
this.permute(rbt, rws, iws, rtws, itws,
|
|
1529
|
-
for (var s = 1; s <
|
|
1527
|
+
FFTM.prototype.transform = function transform(rws, iws, rtws, itws, N, rbt) {
|
|
1528
|
+
this.permute(rbt, rws, iws, rtws, itws, N);
|
|
1529
|
+
for (var s = 1; s < N; s <<= 1) {
|
|
1530
1530
|
var l = s << 1;
|
|
1531
1531
|
var rtwdf = Math.cos(2 * Math.PI / l);
|
|
1532
1532
|
var itwdf = Math.sin(2 * Math.PI / l);
|
|
1533
|
-
for (var p2 = 0; p2 <
|
|
1533
|
+
for (var p2 = 0; p2 < N; p2 += l) {
|
|
1534
1534
|
var rtwdf_ = rtwdf;
|
|
1535
1535
|
var itwdf_ = itwdf;
|
|
1536
1536
|
for (var j = 0; j < s; j++) {
|
|
1537
|
-
var
|
|
1538
|
-
var
|
|
1537
|
+
var re = rtws[p2 + j];
|
|
1538
|
+
var ie = itws[p2 + j];
|
|
1539
1539
|
var ro = rtws[p2 + j + s];
|
|
1540
1540
|
var io = itws[p2 + j + s];
|
|
1541
1541
|
var rx = rtwdf_ * ro - itwdf_ * io;
|
|
1542
1542
|
io = rtwdf_ * io + itwdf_ * ro;
|
|
1543
1543
|
ro = rx;
|
|
1544
|
-
rtws[p2 + j] =
|
|
1545
|
-
itws[p2 + j] =
|
|
1546
|
-
rtws[p2 + j + s] =
|
|
1547
|
-
itws[p2 + j + s] =
|
|
1544
|
+
rtws[p2 + j] = re + ro;
|
|
1545
|
+
itws[p2 + j] = ie + io;
|
|
1546
|
+
rtws[p2 + j + s] = re - ro;
|
|
1547
|
+
itws[p2 + j + s] = ie - io;
|
|
1548
1548
|
if (j !== l) {
|
|
1549
1549
|
rx = rtwdf * rtwdf_ - itwdf * itwdf_;
|
|
1550
1550
|
itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
|
|
@@ -1554,40 +1554,40 @@ var require_bn = __commonJS({
|
|
|
1554
1554
|
}
|
|
1555
1555
|
}
|
|
1556
1556
|
};
|
|
1557
|
-
FFTM.prototype.guessLen13b = function guessLen13b(n,
|
|
1558
|
-
var
|
|
1559
|
-
var odd =
|
|
1557
|
+
FFTM.prototype.guessLen13b = function guessLen13b(n, m3) {
|
|
1558
|
+
var N = Math.max(m3, n) | 1;
|
|
1559
|
+
var odd = N & 1;
|
|
1560
1560
|
var i = 0;
|
|
1561
|
-
for (
|
|
1561
|
+
for (N = N / 2 | 0; N; N = N >>> 1) {
|
|
1562
1562
|
i++;
|
|
1563
1563
|
}
|
|
1564
1564
|
return 1 << i + 1 + odd;
|
|
1565
1565
|
};
|
|
1566
|
-
FFTM.prototype.conjugate = function conjugate(rws, iws,
|
|
1567
|
-
if (
|
|
1568
|
-
for (var i = 0; i <
|
|
1566
|
+
FFTM.prototype.conjugate = function conjugate(rws, iws, N) {
|
|
1567
|
+
if (N <= 1) return;
|
|
1568
|
+
for (var i = 0; i < N / 2; i++) {
|
|
1569
1569
|
var t = rws[i];
|
|
1570
|
-
rws[i] = rws[
|
|
1571
|
-
rws[
|
|
1570
|
+
rws[i] = rws[N - i - 1];
|
|
1571
|
+
rws[N - i - 1] = t;
|
|
1572
1572
|
t = iws[i];
|
|
1573
|
-
iws[i] = -iws[
|
|
1574
|
-
iws[
|
|
1573
|
+
iws[i] = -iws[N - i - 1];
|
|
1574
|
+
iws[N - i - 1] = -t;
|
|
1575
1575
|
}
|
|
1576
1576
|
};
|
|
1577
|
-
FFTM.prototype.normalize13b = function normalize13b(ws,
|
|
1577
|
+
FFTM.prototype.normalize13b = function normalize13b(ws, N) {
|
|
1578
1578
|
var carry = 0;
|
|
1579
|
-
for (var i = 0; i <
|
|
1580
|
-
var
|
|
1581
|
-
ws[i] =
|
|
1582
|
-
if (
|
|
1579
|
+
for (var i = 0; i < N / 2; i++) {
|
|
1580
|
+
var w2 = Math.round(ws[2 * i + 1] / N) * 8192 + Math.round(ws[2 * i] / N) + carry;
|
|
1581
|
+
ws[i] = w2 & 67108863;
|
|
1582
|
+
if (w2 < 67108864) {
|
|
1583
1583
|
carry = 0;
|
|
1584
1584
|
} else {
|
|
1585
|
-
carry =
|
|
1585
|
+
carry = w2 / 67108864 | 0;
|
|
1586
1586
|
}
|
|
1587
1587
|
}
|
|
1588
1588
|
return ws;
|
|
1589
1589
|
};
|
|
1590
|
-
FFTM.prototype.convert13b = function convert13b(ws, len, rws,
|
|
1590
|
+
FFTM.prototype.convert13b = function convert13b(ws, len, rws, N) {
|
|
1591
1591
|
var carry = 0;
|
|
1592
1592
|
for (var i = 0; i < len; i++) {
|
|
1593
1593
|
carry = carry + (ws[i] | 0);
|
|
@@ -1596,46 +1596,46 @@ var require_bn = __commonJS({
|
|
|
1596
1596
|
rws[2 * i + 1] = carry & 8191;
|
|
1597
1597
|
carry = carry >>> 13;
|
|
1598
1598
|
}
|
|
1599
|
-
for (i = 2 * len; i <
|
|
1599
|
+
for (i = 2 * len; i < N; ++i) {
|
|
1600
1600
|
rws[i] = 0;
|
|
1601
1601
|
}
|
|
1602
1602
|
assert(carry === 0);
|
|
1603
1603
|
assert((carry & ~8191) === 0);
|
|
1604
1604
|
};
|
|
1605
|
-
FFTM.prototype.stub = function stub(
|
|
1606
|
-
var ph = new Array(
|
|
1607
|
-
for (var i = 0; i <
|
|
1605
|
+
FFTM.prototype.stub = function stub(N) {
|
|
1606
|
+
var ph = new Array(N);
|
|
1607
|
+
for (var i = 0; i < N; i++) {
|
|
1608
1608
|
ph[i] = 0;
|
|
1609
1609
|
}
|
|
1610
1610
|
return ph;
|
|
1611
1611
|
};
|
|
1612
|
-
FFTM.prototype.mulp = function mulp(
|
|
1613
|
-
var
|
|
1614
|
-
var rbt = this.makeRBT(
|
|
1615
|
-
var _ = this.stub(
|
|
1616
|
-
var rws = new Array(
|
|
1617
|
-
var rwst = new Array(
|
|
1618
|
-
var iwst = new Array(
|
|
1619
|
-
var nrws = new Array(
|
|
1620
|
-
var nrwst = new Array(
|
|
1621
|
-
var niwst = new Array(
|
|
1612
|
+
FFTM.prototype.mulp = function mulp(x, y2, out) {
|
|
1613
|
+
var N = 2 * this.guessLen13b(x.length, y2.length);
|
|
1614
|
+
var rbt = this.makeRBT(N);
|
|
1615
|
+
var _ = this.stub(N);
|
|
1616
|
+
var rws = new Array(N);
|
|
1617
|
+
var rwst = new Array(N);
|
|
1618
|
+
var iwst = new Array(N);
|
|
1619
|
+
var nrws = new Array(N);
|
|
1620
|
+
var nrwst = new Array(N);
|
|
1621
|
+
var niwst = new Array(N);
|
|
1622
1622
|
var rmws = out.words;
|
|
1623
|
-
rmws.length =
|
|
1624
|
-
this.convert13b(
|
|
1625
|
-
this.convert13b(
|
|
1626
|
-
this.transform(rws, _, rwst, iwst,
|
|
1627
|
-
this.transform(nrws, _, nrwst, niwst,
|
|
1628
|
-
for (var i = 0; i <
|
|
1623
|
+
rmws.length = N;
|
|
1624
|
+
this.convert13b(x.words, x.length, rws, N);
|
|
1625
|
+
this.convert13b(y2.words, y2.length, nrws, N);
|
|
1626
|
+
this.transform(rws, _, rwst, iwst, N, rbt);
|
|
1627
|
+
this.transform(nrws, _, nrwst, niwst, N, rbt);
|
|
1628
|
+
for (var i = 0; i < N; i++) {
|
|
1629
1629
|
var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
|
|
1630
1630
|
iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
|
|
1631
1631
|
rwst[i] = rx;
|
|
1632
1632
|
}
|
|
1633
|
-
this.conjugate(rwst, iwst,
|
|
1634
|
-
this.transform(rwst, iwst, rmws, _,
|
|
1635
|
-
this.conjugate(rmws, _,
|
|
1636
|
-
this.normalize13b(rmws,
|
|
1637
|
-
out.negative =
|
|
1638
|
-
out.length =
|
|
1633
|
+
this.conjugate(rwst, iwst, N);
|
|
1634
|
+
this.transform(rwst, iwst, rmws, _, N, rbt);
|
|
1635
|
+
this.conjugate(rmws, _, N);
|
|
1636
|
+
this.normalize13b(rmws, N);
|
|
1637
|
+
out.negative = x.negative ^ y2.negative;
|
|
1638
|
+
out.length = x.length + y2.length;
|
|
1639
1639
|
return out.strip();
|
|
1640
1640
|
};
|
|
1641
1641
|
BN.prototype.mul = function mul(num) {
|
|
@@ -1656,10 +1656,10 @@ var require_bn = __commonJS({
|
|
|
1656
1656
|
assert(num < 67108864);
|
|
1657
1657
|
var carry = 0;
|
|
1658
1658
|
for (var i = 0; i < this.length; i++) {
|
|
1659
|
-
var
|
|
1660
|
-
var lo = (
|
|
1659
|
+
var w2 = (this.words[i] | 0) * num;
|
|
1660
|
+
var lo = (w2 & 67108863) + (carry & 67108863);
|
|
1661
1661
|
carry >>= 26;
|
|
1662
|
-
carry +=
|
|
1662
|
+
carry += w2 / 67108864 | 0;
|
|
1663
1663
|
carry += lo >>> 26;
|
|
1664
1664
|
this.words[i] = lo & 67108863;
|
|
1665
1665
|
}
|
|
@@ -1683,16 +1683,16 @@ var require_bn = __commonJS({
|
|
|
1683
1683
|
return this.imul(this.clone());
|
|
1684
1684
|
};
|
|
1685
1685
|
BN.prototype.pow = function pow(num) {
|
|
1686
|
-
var
|
|
1687
|
-
if (
|
|
1686
|
+
var w2 = toBitArray(num);
|
|
1687
|
+
if (w2.length === 0) return new BN(1);
|
|
1688
1688
|
var res = this;
|
|
1689
|
-
for (var i = 0; i <
|
|
1690
|
-
if (
|
|
1689
|
+
for (var i = 0; i < w2.length; i++, res = res.sqr()) {
|
|
1690
|
+
if (w2[i] !== 0) break;
|
|
1691
1691
|
}
|
|
1692
|
-
if (++i <
|
|
1693
|
-
for (var
|
|
1694
|
-
if (
|
|
1695
|
-
res = res.mul(
|
|
1692
|
+
if (++i < w2.length) {
|
|
1693
|
+
for (var q = res.sqr(); i < w2.length; i++, q = q.sqr()) {
|
|
1694
|
+
if (w2[i] === 0) continue;
|
|
1695
|
+
res = res.mul(q);
|
|
1696
1696
|
}
|
|
1697
1697
|
}
|
|
1698
1698
|
return res;
|
|
@@ -1733,18 +1733,18 @@ var require_bn = __commonJS({
|
|
|
1733
1733
|
};
|
|
1734
1734
|
BN.prototype.iushrn = function iushrn(bits, hint, extended) {
|
|
1735
1735
|
assert(typeof bits === "number" && bits >= 0);
|
|
1736
|
-
var
|
|
1736
|
+
var h3;
|
|
1737
1737
|
if (hint) {
|
|
1738
|
-
|
|
1738
|
+
h3 = (hint - hint % 26) / 26;
|
|
1739
1739
|
} else {
|
|
1740
|
-
|
|
1740
|
+
h3 = 0;
|
|
1741
1741
|
}
|
|
1742
1742
|
var r = bits % 26;
|
|
1743
1743
|
var s = Math.min((bits - r) / 26, this.length);
|
|
1744
1744
|
var mask = 67108863 ^ 67108863 >>> r << r;
|
|
1745
1745
|
var maskedWords = extended;
|
|
1746
|
-
|
|
1747
|
-
|
|
1746
|
+
h3 -= s;
|
|
1747
|
+
h3 = Math.max(0, h3);
|
|
1748
1748
|
if (maskedWords) {
|
|
1749
1749
|
for (var i = 0; i < s; i++) {
|
|
1750
1750
|
maskedWords.words[i] = this.words[i];
|
|
@@ -1762,7 +1762,7 @@ var require_bn = __commonJS({
|
|
|
1762
1762
|
this.length = 1;
|
|
1763
1763
|
}
|
|
1764
1764
|
var carry = 0;
|
|
1765
|
-
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >=
|
|
1765
|
+
for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h3); i--) {
|
|
1766
1766
|
var word = this.words[i] | 0;
|
|
1767
1767
|
this.words[i] = carry << 26 - r | word >>> r;
|
|
1768
1768
|
carry = word & mask;
|
|
@@ -1796,10 +1796,10 @@ var require_bn = __commonJS({
|
|
|
1796
1796
|
assert(typeof bit === "number" && bit >= 0);
|
|
1797
1797
|
var r = bit % 26;
|
|
1798
1798
|
var s = (bit - r) / 26;
|
|
1799
|
-
var
|
|
1799
|
+
var q = 1 << r;
|
|
1800
1800
|
if (this.length <= s) return false;
|
|
1801
|
-
var
|
|
1802
|
-
return !!(
|
|
1801
|
+
var w2 = this.words[s];
|
|
1802
|
+
return !!(w2 & q);
|
|
1803
1803
|
};
|
|
1804
1804
|
BN.prototype.imaskn = function imaskn(bits) {
|
|
1805
1805
|
assert(typeof bits === "number" && bits >= 0);
|
|
@@ -1895,27 +1895,27 @@ var require_bn = __commonJS({
|
|
|
1895
1895
|
var len = num.length + shift;
|
|
1896
1896
|
var i;
|
|
1897
1897
|
this._expand(len);
|
|
1898
|
-
var
|
|
1898
|
+
var w2;
|
|
1899
1899
|
var carry = 0;
|
|
1900
1900
|
for (i = 0; i < num.length; i++) {
|
|
1901
|
-
|
|
1901
|
+
w2 = (this.words[i + shift] | 0) + carry;
|
|
1902
1902
|
var right = (num.words[i] | 0) * mul;
|
|
1903
|
-
|
|
1904
|
-
carry = (
|
|
1905
|
-
this.words[i + shift] =
|
|
1903
|
+
w2 -= right & 67108863;
|
|
1904
|
+
carry = (w2 >> 26) - (right / 67108864 | 0);
|
|
1905
|
+
this.words[i + shift] = w2 & 67108863;
|
|
1906
1906
|
}
|
|
1907
1907
|
for (; i < this.length - shift; i++) {
|
|
1908
|
-
|
|
1909
|
-
carry =
|
|
1910
|
-
this.words[i + shift] =
|
|
1908
|
+
w2 = (this.words[i + shift] | 0) + carry;
|
|
1909
|
+
carry = w2 >> 26;
|
|
1910
|
+
this.words[i + shift] = w2 & 67108863;
|
|
1911
1911
|
}
|
|
1912
1912
|
if (carry === 0) return this.strip();
|
|
1913
1913
|
assert(carry === -1);
|
|
1914
1914
|
carry = 0;
|
|
1915
1915
|
for (i = 0; i < this.length; i++) {
|
|
1916
|
-
|
|
1917
|
-
carry =
|
|
1918
|
-
this.words[i] =
|
|
1916
|
+
w2 = -(this.words[i] | 0) + carry;
|
|
1917
|
+
carry = w2 >> 26;
|
|
1918
|
+
this.words[i] = w2 & 67108863;
|
|
1919
1919
|
}
|
|
1920
1920
|
this.negative = 1;
|
|
1921
1921
|
return this.strip();
|
|
@@ -1932,24 +1932,24 @@ var require_bn = __commonJS({
|
|
|
1932
1932
|
a.iushln(shift);
|
|
1933
1933
|
bhi = b2.words[b2.length - 1] | 0;
|
|
1934
1934
|
}
|
|
1935
|
-
var
|
|
1936
|
-
var
|
|
1935
|
+
var m3 = a.length - b2.length;
|
|
1936
|
+
var q;
|
|
1937
1937
|
if (mode !== "mod") {
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
for (var i = 0; i <
|
|
1942
|
-
|
|
1938
|
+
q = new BN(null);
|
|
1939
|
+
q.length = m3 + 1;
|
|
1940
|
+
q.words = new Array(q.length);
|
|
1941
|
+
for (var i = 0; i < q.length; i++) {
|
|
1942
|
+
q.words[i] = 0;
|
|
1943
1943
|
}
|
|
1944
1944
|
}
|
|
1945
|
-
var diff = a.clone()._ishlnsubmul(b2, 1,
|
|
1945
|
+
var diff = a.clone()._ishlnsubmul(b2, 1, m3);
|
|
1946
1946
|
if (diff.negative === 0) {
|
|
1947
1947
|
a = diff;
|
|
1948
|
-
if (
|
|
1949
|
-
|
|
1948
|
+
if (q) {
|
|
1949
|
+
q.words[m3] = 1;
|
|
1950
1950
|
}
|
|
1951
1951
|
}
|
|
1952
|
-
for (var j =
|
|
1952
|
+
for (var j = m3 - 1; j >= 0; j--) {
|
|
1953
1953
|
var qj = (a.words[b2.length + j] | 0) * 67108864 + (a.words[b2.length + j - 1] | 0);
|
|
1954
1954
|
qj = Math.min(qj / bhi | 0, 67108863);
|
|
1955
1955
|
a._ishlnsubmul(b2, qj, j);
|
|
@@ -1961,19 +1961,19 @@ var require_bn = __commonJS({
|
|
|
1961
1961
|
a.negative ^= 1;
|
|
1962
1962
|
}
|
|
1963
1963
|
}
|
|
1964
|
-
if (
|
|
1965
|
-
|
|
1964
|
+
if (q) {
|
|
1965
|
+
q.words[j] = qj;
|
|
1966
1966
|
}
|
|
1967
1967
|
}
|
|
1968
|
-
if (
|
|
1969
|
-
|
|
1968
|
+
if (q) {
|
|
1969
|
+
q.strip();
|
|
1970
1970
|
}
|
|
1971
1971
|
a.strip();
|
|
1972
1972
|
if (mode !== "div" && shift !== 0) {
|
|
1973
1973
|
a.iushrn(shift);
|
|
1974
1974
|
}
|
|
1975
1975
|
return {
|
|
1976
|
-
div:
|
|
1976
|
+
div: q || null,
|
|
1977
1977
|
mod: a
|
|
1978
1978
|
};
|
|
1979
1979
|
};
|
|
@@ -2085,9 +2085,9 @@ var require_bn = __commonJS({
|
|
|
2085
2085
|
assert(num <= 67108863);
|
|
2086
2086
|
var carry = 0;
|
|
2087
2087
|
for (var i = this.length - 1; i >= 0; i--) {
|
|
2088
|
-
var
|
|
2089
|
-
this.words[i] =
|
|
2090
|
-
carry =
|
|
2088
|
+
var w2 = (this.words[i] | 0) + carry * 67108864;
|
|
2089
|
+
this.words[i] = w2 / num | 0;
|
|
2090
|
+
carry = w2 % num;
|
|
2091
2091
|
}
|
|
2092
2092
|
return this.strip();
|
|
2093
2093
|
};
|
|
@@ -2097,29 +2097,29 @@ var require_bn = __commonJS({
|
|
|
2097
2097
|
BN.prototype.egcd = function egcd(p2) {
|
|
2098
2098
|
assert(p2.negative === 0);
|
|
2099
2099
|
assert(!p2.isZero());
|
|
2100
|
-
var
|
|
2101
|
-
var
|
|
2102
|
-
if (
|
|
2103
|
-
|
|
2100
|
+
var x = this;
|
|
2101
|
+
var y2 = p2.clone();
|
|
2102
|
+
if (x.negative !== 0) {
|
|
2103
|
+
x = x.umod(p2);
|
|
2104
2104
|
} else {
|
|
2105
|
-
|
|
2105
|
+
x = x.clone();
|
|
2106
2106
|
}
|
|
2107
2107
|
var A2 = new BN(1);
|
|
2108
2108
|
var B2 = new BN(0);
|
|
2109
|
-
var
|
|
2109
|
+
var C2 = new BN(0);
|
|
2110
2110
|
var D2 = new BN(1);
|
|
2111
2111
|
var g2 = 0;
|
|
2112
|
-
while (
|
|
2113
|
-
|
|
2114
|
-
|
|
2112
|
+
while (x.isEven() && y2.isEven()) {
|
|
2113
|
+
x.iushrn(1);
|
|
2114
|
+
y2.iushrn(1);
|
|
2115
2115
|
++g2;
|
|
2116
2116
|
}
|
|
2117
|
-
var yp =
|
|
2118
|
-
var xp =
|
|
2119
|
-
while (!
|
|
2120
|
-
for (var i = 0, im = 1; (
|
|
2117
|
+
var yp = y2.clone();
|
|
2118
|
+
var xp = x.clone();
|
|
2119
|
+
while (!x.isZero()) {
|
|
2120
|
+
for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1) ;
|
|
2121
2121
|
if (i > 0) {
|
|
2122
|
-
|
|
2122
|
+
x.iushrn(i);
|
|
2123
2123
|
while (i-- > 0) {
|
|
2124
2124
|
if (A2.isOdd() || B2.isOdd()) {
|
|
2125
2125
|
A2.iadd(yp);
|
|
@@ -2129,32 +2129,32 @@ var require_bn = __commonJS({
|
|
|
2129
2129
|
B2.iushrn(1);
|
|
2130
2130
|
}
|
|
2131
2131
|
}
|
|
2132
|
-
for (var j = 0, jm = 1; (
|
|
2132
|
+
for (var j = 0, jm = 1; (y2.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1) ;
|
|
2133
2133
|
if (j > 0) {
|
|
2134
|
-
|
|
2134
|
+
y2.iushrn(j);
|
|
2135
2135
|
while (j-- > 0) {
|
|
2136
|
-
if (
|
|
2137
|
-
|
|
2136
|
+
if (C2.isOdd() || D2.isOdd()) {
|
|
2137
|
+
C2.iadd(yp);
|
|
2138
2138
|
D2.isub(xp);
|
|
2139
2139
|
}
|
|
2140
|
-
|
|
2140
|
+
C2.iushrn(1);
|
|
2141
2141
|
D2.iushrn(1);
|
|
2142
2142
|
}
|
|
2143
2143
|
}
|
|
2144
|
-
if (
|
|
2145
|
-
|
|
2146
|
-
A2.isub(
|
|
2144
|
+
if (x.cmp(y2) >= 0) {
|
|
2145
|
+
x.isub(y2);
|
|
2146
|
+
A2.isub(C2);
|
|
2147
2147
|
B2.isub(D2);
|
|
2148
2148
|
} else {
|
|
2149
|
-
|
|
2150
|
-
|
|
2149
|
+
y2.isub(x);
|
|
2150
|
+
C2.isub(A2);
|
|
2151
2151
|
D2.isub(B2);
|
|
2152
2152
|
}
|
|
2153
2153
|
}
|
|
2154
2154
|
return {
|
|
2155
|
-
a:
|
|
2155
|
+
a: C2,
|
|
2156
2156
|
b: D2,
|
|
2157
|
-
gcd:
|
|
2157
|
+
gcd: y2.iushln(g2)
|
|
2158
2158
|
};
|
|
2159
2159
|
};
|
|
2160
2160
|
BN.prototype._invmp = function _invmp(p2) {
|
|
@@ -2256,19 +2256,19 @@ var require_bn = __commonJS({
|
|
|
2256
2256
|
assert(typeof bit === "number");
|
|
2257
2257
|
var r = bit % 26;
|
|
2258
2258
|
var s = (bit - r) / 26;
|
|
2259
|
-
var
|
|
2259
|
+
var q = 1 << r;
|
|
2260
2260
|
if (this.length <= s) {
|
|
2261
2261
|
this._expand(s + 1);
|
|
2262
|
-
this.words[s] |=
|
|
2262
|
+
this.words[s] |= q;
|
|
2263
2263
|
return this;
|
|
2264
2264
|
}
|
|
2265
|
-
var carry =
|
|
2265
|
+
var carry = q;
|
|
2266
2266
|
for (var i = s; carry !== 0 && i < this.length; i++) {
|
|
2267
|
-
var
|
|
2268
|
-
|
|
2269
|
-
carry =
|
|
2270
|
-
|
|
2271
|
-
this.words[i] =
|
|
2267
|
+
var w2 = this.words[i] | 0;
|
|
2268
|
+
w2 += carry;
|
|
2269
|
+
carry = w2 >>> 26;
|
|
2270
|
+
w2 &= 67108863;
|
|
2271
|
+
this.words[i] = w2;
|
|
2272
2272
|
}
|
|
2273
2273
|
if (carry !== 0) {
|
|
2274
2274
|
this.words[i] = carry;
|
|
@@ -2292,8 +2292,8 @@ var require_bn = __commonJS({
|
|
|
2292
2292
|
num = -num;
|
|
2293
2293
|
}
|
|
2294
2294
|
assert(num <= 67108863, "Number is too big");
|
|
2295
|
-
var
|
|
2296
|
-
res =
|
|
2295
|
+
var w2 = this.words[0] | 0;
|
|
2296
|
+
res = w2 === num ? 0 : w2 < num ? -1 : 1;
|
|
2297
2297
|
}
|
|
2298
2298
|
if (this.negative !== 0) return -res | 0;
|
|
2299
2299
|
return res;
|
|
@@ -2521,10 +2521,10 @@ var require_bn = __commonJS({
|
|
|
2521
2521
|
num.length += 2;
|
|
2522
2522
|
var lo = 0;
|
|
2523
2523
|
for (var i = 0; i < num.length; i++) {
|
|
2524
|
-
var
|
|
2525
|
-
lo +=
|
|
2524
|
+
var w2 = num.words[i] | 0;
|
|
2525
|
+
lo += w2 * 977;
|
|
2526
2526
|
num.words[i] = lo & 67108863;
|
|
2527
|
-
lo =
|
|
2527
|
+
lo = w2 * 64 + (lo / 67108864 | 0);
|
|
2528
2528
|
}
|
|
2529
2529
|
if (num.words[num.length - 1] === 0) {
|
|
2530
2530
|
num.length--;
|
|
@@ -2589,14 +2589,14 @@ var require_bn = __commonJS({
|
|
|
2589
2589
|
primes[name] = prime2;
|
|
2590
2590
|
return prime2;
|
|
2591
2591
|
};
|
|
2592
|
-
function Red(
|
|
2593
|
-
if (typeof
|
|
2594
|
-
var prime = BN._prime(
|
|
2592
|
+
function Red(m3) {
|
|
2593
|
+
if (typeof m3 === "string") {
|
|
2594
|
+
var prime = BN._prime(m3);
|
|
2595
2595
|
this.m = prime.p;
|
|
2596
2596
|
this.prime = prime;
|
|
2597
2597
|
} else {
|
|
2598
|
-
assert(
|
|
2599
|
-
this.m =
|
|
2598
|
+
assert(m3.gtn(1), "modulus must be greater than 1");
|
|
2599
|
+
this.m = m3;
|
|
2600
2600
|
this.prime = null;
|
|
2601
2601
|
}
|
|
2602
2602
|
}
|
|
@@ -2679,36 +2679,36 @@ var require_bn = __commonJS({
|
|
|
2679
2679
|
var pow = this.m.add(new BN(1)).iushrn(2);
|
|
2680
2680
|
return this.pow(a, pow);
|
|
2681
2681
|
}
|
|
2682
|
-
var
|
|
2682
|
+
var q = this.m.subn(1);
|
|
2683
2683
|
var s = 0;
|
|
2684
|
-
while (!
|
|
2684
|
+
while (!q.isZero() && q.andln(1) === 0) {
|
|
2685
2685
|
s++;
|
|
2686
|
-
|
|
2686
|
+
q.iushrn(1);
|
|
2687
2687
|
}
|
|
2688
|
-
assert(!
|
|
2688
|
+
assert(!q.isZero());
|
|
2689
2689
|
var one = new BN(1).toRed(this);
|
|
2690
2690
|
var nOne = one.redNeg();
|
|
2691
2691
|
var lpow = this.m.subn(1).iushrn(1);
|
|
2692
|
-
var
|
|
2693
|
-
|
|
2694
|
-
while (this.pow(
|
|
2695
|
-
|
|
2696
|
-
}
|
|
2697
|
-
var c = this.pow(
|
|
2698
|
-
var r = this.pow(a,
|
|
2699
|
-
var t = this.pow(a,
|
|
2700
|
-
var
|
|
2692
|
+
var z2 = this.m.bitLength();
|
|
2693
|
+
z2 = new BN(2 * z2 * z2).toRed(this);
|
|
2694
|
+
while (this.pow(z2, lpow).cmp(nOne) !== 0) {
|
|
2695
|
+
z2.redIAdd(nOne);
|
|
2696
|
+
}
|
|
2697
|
+
var c = this.pow(z2, q);
|
|
2698
|
+
var r = this.pow(a, q.addn(1).iushrn(1));
|
|
2699
|
+
var t = this.pow(a, q);
|
|
2700
|
+
var m3 = s;
|
|
2701
2701
|
while (t.cmp(one) !== 0) {
|
|
2702
2702
|
var tmp = t;
|
|
2703
2703
|
for (var i = 0; tmp.cmp(one) !== 0; i++) {
|
|
2704
2704
|
tmp = tmp.redSqr();
|
|
2705
2705
|
}
|
|
2706
|
-
assert(i <
|
|
2707
|
-
var b2 = this.pow(c, new BN(1).iushln(
|
|
2706
|
+
assert(i < m3);
|
|
2707
|
+
var b2 = this.pow(c, new BN(1).iushln(m3 - i - 1));
|
|
2708
2708
|
r = r.redMul(b2);
|
|
2709
2709
|
c = b2.redSqr();
|
|
2710
2710
|
t = t.redMul(c);
|
|
2711
|
-
|
|
2711
|
+
m3 = i;
|
|
2712
2712
|
}
|
|
2713
2713
|
return r;
|
|
2714
2714
|
};
|
|
@@ -2773,8 +2773,8 @@ var require_bn = __commonJS({
|
|
|
2773
2773
|
BN.mont = function mont(num) {
|
|
2774
2774
|
return new Mont(num);
|
|
2775
2775
|
};
|
|
2776
|
-
function Mont(
|
|
2777
|
-
Red.call(this,
|
|
2776
|
+
function Mont(m3) {
|
|
2777
|
+
Red.call(this, m3);
|
|
2778
2778
|
this.shift = this.m.bitLength();
|
|
2779
2779
|
if (this.shift % 26 !== 0) {
|
|
2780
2780
|
this.shift += 26 - this.shift % 26;
|
|
@@ -2803,12 +2803,12 @@ var require_bn = __commonJS({
|
|
|
2803
2803
|
}
|
|
2804
2804
|
var t = a.imul(b2);
|
|
2805
2805
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
2806
|
-
var
|
|
2807
|
-
var res =
|
|
2808
|
-
if (
|
|
2809
|
-
res =
|
|
2810
|
-
} else if (
|
|
2811
|
-
res =
|
|
2806
|
+
var u2 = t.isub(c).iushrn(this.shift);
|
|
2807
|
+
var res = u2;
|
|
2808
|
+
if (u2.cmp(this.m) >= 0) {
|
|
2809
|
+
res = u2.isub(this.m);
|
|
2810
|
+
} else if (u2.cmpn(0) < 0) {
|
|
2811
|
+
res = u2.iadd(this.m);
|
|
2812
2812
|
}
|
|
2813
2813
|
return res._forceRed(this);
|
|
2814
2814
|
};
|
|
@@ -2816,12 +2816,12 @@ var require_bn = __commonJS({
|
|
|
2816
2816
|
if (a.isZero() || b2.isZero()) return new BN(0)._forceRed(this);
|
|
2817
2817
|
var t = a.mul(b2);
|
|
2818
2818
|
var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
|
|
2819
|
-
var
|
|
2820
|
-
var res =
|
|
2821
|
-
if (
|
|
2822
|
-
res =
|
|
2823
|
-
} else if (
|
|
2824
|
-
res =
|
|
2819
|
+
var u2 = t.isub(c).iushrn(this.shift);
|
|
2820
|
+
var res = u2;
|
|
2821
|
+
if (u2.cmp(this.m) >= 0) {
|
|
2822
|
+
res = u2.isub(this.m);
|
|
2823
|
+
} else if (u2.cmpn(0) < 0) {
|
|
2824
|
+
res = u2.iadd(this.m);
|
|
2825
2825
|
}
|
|
2826
2826
|
return res._forceRed(this);
|
|
2827
2827
|
};
|
|
@@ -4337,11 +4337,11 @@ var require_pem2 = __commonJS({
|
|
|
4337
4337
|
PEMDecoder.prototype.decode = function decode(data, options) {
|
|
4338
4338
|
const lines = data.toString().split(/[\r\n]+/g);
|
|
4339
4339
|
const label = options.label.toUpperCase();
|
|
4340
|
-
const
|
|
4340
|
+
const re = /^-----(BEGIN|END) ([^-]+)-----$/;
|
|
4341
4341
|
let start2 = -1;
|
|
4342
4342
|
let end = -1;
|
|
4343
4343
|
for (let i = 0; i < lines.length; i++) {
|
|
4344
|
-
const match2 = lines[i].match(
|
|
4344
|
+
const match2 = lines[i].match(re);
|
|
4345
4345
|
if (match2 === null)
|
|
4346
4346
|
continue;
|
|
4347
4347
|
if (match2[2] !== label)
|
|
@@ -5479,13 +5479,13 @@ var require_ece = __commonJS({
|
|
|
5479
5479
|
var MODE_DECRYPT = "decrypt";
|
|
5480
5480
|
var keylog;
|
|
5481
5481
|
if (process.env.ECE_KEYLOG === "1") {
|
|
5482
|
-
keylog = function(
|
|
5483
|
-
console.warn(
|
|
5484
|
-
return
|
|
5482
|
+
keylog = function(m3, k) {
|
|
5483
|
+
console.warn(m3 + " [" + k.length + "]: " + k.toString("base64url"));
|
|
5484
|
+
return k;
|
|
5485
5485
|
};
|
|
5486
5486
|
} else {
|
|
5487
|
-
keylog = function(
|
|
5488
|
-
return
|
|
5487
|
+
keylog = function(m3, k) {
|
|
5488
|
+
return k;
|
|
5489
5489
|
};
|
|
5490
5490
|
}
|
|
5491
5491
|
function decode(b2) {
|
|
@@ -5714,9 +5714,9 @@ var require_ece = __commonJS({
|
|
|
5714
5714
|
}
|
|
5715
5715
|
function generateNonce(base, counter) {
|
|
5716
5716
|
var nonce = Buffer.from(base);
|
|
5717
|
-
var
|
|
5718
|
-
var
|
|
5719
|
-
nonce.writeUIntBE(
|
|
5717
|
+
var m3 = nonce.readUIntBE(nonce.length - 6, 6);
|
|
5718
|
+
var x = ((m3 ^ counter) & 16777215) + ((m3 / 16777216 ^ counter / 16777216) & 16777215) * 16777216;
|
|
5719
|
+
nonce.writeUIntBE(x, nonce.length - 6, 6);
|
|
5720
5720
|
keylog("nonce" + counter, nonce);
|
|
5721
5721
|
return nonce;
|
|
5722
5722
|
}
|
|
@@ -5993,11 +5993,11 @@ var require_ms = __commonJS({
|
|
|
5993
5993
|
"node_modules/ms/index.js"(exports, module) {
|
|
5994
5994
|
init_define_MESSENGER_BUILD_INFO();
|
|
5995
5995
|
var s = 1e3;
|
|
5996
|
-
var
|
|
5997
|
-
var
|
|
5998
|
-
var d2 =
|
|
5999
|
-
var
|
|
6000
|
-
var
|
|
5996
|
+
var m3 = s * 60;
|
|
5997
|
+
var h3 = m3 * 60;
|
|
5998
|
+
var d2 = h3 * 24;
|
|
5999
|
+
var w2 = d2 * 7;
|
|
6000
|
+
var y2 = d2 * 365.25;
|
|
6001
6001
|
module.exports = function(val, options) {
|
|
6002
6002
|
options = options || {};
|
|
6003
6003
|
var type = typeof val;
|
|
@@ -6029,11 +6029,11 @@ var require_ms = __commonJS({
|
|
|
6029
6029
|
case "yrs":
|
|
6030
6030
|
case "yr":
|
|
6031
6031
|
case "y":
|
|
6032
|
-
return n *
|
|
6032
|
+
return n * y2;
|
|
6033
6033
|
case "weeks":
|
|
6034
6034
|
case "week":
|
|
6035
6035
|
case "w":
|
|
6036
|
-
return n *
|
|
6036
|
+
return n * w2;
|
|
6037
6037
|
case "days":
|
|
6038
6038
|
case "day":
|
|
6039
6039
|
case "d":
|
|
@@ -6043,13 +6043,13 @@ var require_ms = __commonJS({
|
|
|
6043
6043
|
case "hrs":
|
|
6044
6044
|
case "hr":
|
|
6045
6045
|
case "h":
|
|
6046
|
-
return n *
|
|
6046
|
+
return n * h3;
|
|
6047
6047
|
case "minutes":
|
|
6048
6048
|
case "minute":
|
|
6049
6049
|
case "mins":
|
|
6050
6050
|
case "min":
|
|
6051
6051
|
case "m":
|
|
6052
|
-
return n *
|
|
6052
|
+
return n * m3;
|
|
6053
6053
|
case "seconds":
|
|
6054
6054
|
case "second":
|
|
6055
6055
|
case "secs":
|
|
@@ -6071,11 +6071,11 @@ var require_ms = __commonJS({
|
|
|
6071
6071
|
if (msAbs >= d2) {
|
|
6072
6072
|
return Math.round(ms / d2) + "d";
|
|
6073
6073
|
}
|
|
6074
|
-
if (msAbs >=
|
|
6075
|
-
return Math.round(ms /
|
|
6074
|
+
if (msAbs >= h3) {
|
|
6075
|
+
return Math.round(ms / h3) + "h";
|
|
6076
6076
|
}
|
|
6077
|
-
if (msAbs >=
|
|
6078
|
-
return Math.round(ms /
|
|
6077
|
+
if (msAbs >= m3) {
|
|
6078
|
+
return Math.round(ms / m3) + "m";
|
|
6079
6079
|
}
|
|
6080
6080
|
if (msAbs >= s) {
|
|
6081
6081
|
return Math.round(ms / s) + "s";
|
|
@@ -6087,11 +6087,11 @@ var require_ms = __commonJS({
|
|
|
6087
6087
|
if (msAbs >= d2) {
|
|
6088
6088
|
return plural(ms, msAbs, d2, "day");
|
|
6089
6089
|
}
|
|
6090
|
-
if (msAbs >=
|
|
6091
|
-
return plural(ms, msAbs,
|
|
6090
|
+
if (msAbs >= h3) {
|
|
6091
|
+
return plural(ms, msAbs, h3, "hour");
|
|
6092
6092
|
}
|
|
6093
|
-
if (msAbs >=
|
|
6094
|
-
return plural(ms, msAbs,
|
|
6093
|
+
if (msAbs >= m3) {
|
|
6094
|
+
return plural(ms, msAbs, m3, "minute");
|
|
6095
6095
|
}
|
|
6096
6096
|
if (msAbs >= s) {
|
|
6097
6097
|
return plural(ms, msAbs, s, "second");
|
|
@@ -6190,8 +6190,8 @@ var require_common = __commonJS({
|
|
|
6190
6190
|
}
|
|
6191
6191
|
return enabledCache;
|
|
6192
6192
|
},
|
|
6193
|
-
set: (
|
|
6194
|
-
enableOverride =
|
|
6193
|
+
set: (v3) => {
|
|
6194
|
+
enableOverride = v3;
|
|
6195
6195
|
}
|
|
6196
6196
|
});
|
|
6197
6197
|
if (typeof createDebug.init === "function") {
|
|
@@ -6386,11 +6386,11 @@ var require_browser = __commonJS({
|
|
|
6386
6386
|
if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
|
6387
6387
|
return false;
|
|
6388
6388
|
}
|
|
6389
|
-
let
|
|
6389
|
+
let m3;
|
|
6390
6390
|
return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
|
|
6391
6391
|
typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
|
|
6392
6392
|
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
|
6393
|
-
typeof navigator !== "undefined" && navigator.userAgent && (
|
|
6393
|
+
typeof navigator !== "undefined" && navigator.userAgent && (m3 = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m3[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
|
|
6394
6394
|
typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
|
|
6395
6395
|
}
|
|
6396
6396
|
function formatArgs(args) {
|
|
@@ -6444,9 +6444,9 @@ var require_browser = __commonJS({
|
|
|
6444
6444
|
}
|
|
6445
6445
|
module.exports = require_common()(exports);
|
|
6446
6446
|
var { formatters } = module.exports;
|
|
6447
|
-
formatters.j = function(
|
|
6447
|
+
formatters.j = function(v3) {
|
|
6448
6448
|
try {
|
|
6449
|
-
return JSON.stringify(
|
|
6449
|
+
return JSON.stringify(v3);
|
|
6450
6450
|
} catch (error) {
|
|
6451
6451
|
return "[UnexpectedJSONParseError]: " + error.message;
|
|
6452
6452
|
}
|
|
@@ -6559,8 +6559,8 @@ var require_node2 = __commonJS({
|
|
|
6559
6559
|
exports.inspectOpts = Object.keys(process.env).filter((key) => {
|
|
6560
6560
|
return /^debug_/i.test(key);
|
|
6561
6561
|
}).reduce((obj, key) => {
|
|
6562
|
-
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_,
|
|
6563
|
-
return
|
|
6562
|
+
const prop = key.substring(6).toLowerCase().replace(/_([a-z])/g, (_, k) => {
|
|
6563
|
+
return k.toUpperCase();
|
|
6564
6564
|
});
|
|
6565
6565
|
let val = process.env[key];
|
|
6566
6566
|
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
|
@@ -6618,13 +6618,13 @@ var require_node2 = __commonJS({
|
|
|
6618
6618
|
}
|
|
6619
6619
|
module.exports = require_common()(exports);
|
|
6620
6620
|
var { formatters } = module.exports;
|
|
6621
|
-
formatters.o = function(
|
|
6621
|
+
formatters.o = function(v3) {
|
|
6622
6622
|
this.inspectOpts.colors = this.useColors;
|
|
6623
|
-
return util.inspect(
|
|
6623
|
+
return util.inspect(v3, this.inspectOpts).split("\n").map((str2) => str2.trim()).join(" ");
|
|
6624
6624
|
};
|
|
6625
|
-
formatters.O = function(
|
|
6625
|
+
formatters.O = function(v3) {
|
|
6626
6626
|
this.inspectOpts.colors = this.useColors;
|
|
6627
|
-
return util.inspect(
|
|
6627
|
+
return util.inspect(v3, this.inspectOpts);
|
|
6628
6628
|
};
|
|
6629
6629
|
}
|
|
6630
6630
|
});
|
|
@@ -6646,29 +6646,29 @@ var require_helpers = __commonJS({
|
|
|
6646
6646
|
"node_modules/agent-base/dist/helpers.js"(exports) {
|
|
6647
6647
|
"use strict";
|
|
6648
6648
|
init_define_MESSENGER_BUILD_INFO();
|
|
6649
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o,
|
|
6650
|
-
if (
|
|
6651
|
-
var desc = Object.getOwnPropertyDescriptor(
|
|
6652
|
-
if (!desc || ("get" in desc ? !
|
|
6649
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m3, k, k2) {
|
|
6650
|
+
if (k2 === void 0) k2 = k;
|
|
6651
|
+
var desc = Object.getOwnPropertyDescriptor(m3, k);
|
|
6652
|
+
if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
|
|
6653
6653
|
desc = { enumerable: true, get: function() {
|
|
6654
|
-
return
|
|
6654
|
+
return m3[k];
|
|
6655
6655
|
} };
|
|
6656
6656
|
}
|
|
6657
|
-
Object.defineProperty(o,
|
|
6658
|
-
}) : (function(o,
|
|
6659
|
-
if (
|
|
6660
|
-
o[
|
|
6657
|
+
Object.defineProperty(o, k2, desc);
|
|
6658
|
+
}) : (function(o, m3, k, k2) {
|
|
6659
|
+
if (k2 === void 0) k2 = k;
|
|
6660
|
+
o[k2] = m3[k];
|
|
6661
6661
|
}));
|
|
6662
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o,
|
|
6663
|
-
Object.defineProperty(o, "default", { enumerable: true, value:
|
|
6664
|
-
}) : function(o,
|
|
6665
|
-
o["default"] =
|
|
6662
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v3) {
|
|
6663
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v3 });
|
|
6664
|
+
}) : function(o, v3) {
|
|
6665
|
+
o["default"] = v3;
|
|
6666
6666
|
});
|
|
6667
6667
|
var __importStar = exports && exports.__importStar || function(mod) {
|
|
6668
6668
|
if (mod && mod.__esModule) return mod;
|
|
6669
6669
|
var result = {};
|
|
6670
6670
|
if (mod != null) {
|
|
6671
|
-
for (var
|
|
6671
|
+
for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
6672
6672
|
}
|
|
6673
6673
|
__setModuleDefault(result, mod);
|
|
6674
6674
|
return result;
|
|
@@ -6702,8 +6702,8 @@ var require_helpers = __commonJS({
|
|
|
6702
6702
|
function req(url, opts = {}) {
|
|
6703
6703
|
const href = typeof url === "string" ? url : url.href;
|
|
6704
6704
|
const req2 = (href.startsWith("https:") ? https : http).request(url, opts);
|
|
6705
|
-
const promise = new Promise((
|
|
6706
|
-
req2.once("response",
|
|
6705
|
+
const promise = new Promise((resolve4, reject) => {
|
|
6706
|
+
req2.once("response", resolve4).once("error", reject).end();
|
|
6707
6707
|
});
|
|
6708
6708
|
req2.then = promise.then.bind(promise);
|
|
6709
6709
|
return req2;
|
|
@@ -6717,35 +6717,35 @@ var require_dist = __commonJS({
|
|
|
6717
6717
|
"node_modules/agent-base/dist/index.js"(exports) {
|
|
6718
6718
|
"use strict";
|
|
6719
6719
|
init_define_MESSENGER_BUILD_INFO();
|
|
6720
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o,
|
|
6721
|
-
if (
|
|
6722
|
-
var desc = Object.getOwnPropertyDescriptor(
|
|
6723
|
-
if (!desc || ("get" in desc ? !
|
|
6720
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m3, k, k2) {
|
|
6721
|
+
if (k2 === void 0) k2 = k;
|
|
6722
|
+
var desc = Object.getOwnPropertyDescriptor(m3, k);
|
|
6723
|
+
if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
|
|
6724
6724
|
desc = { enumerable: true, get: function() {
|
|
6725
|
-
return
|
|
6725
|
+
return m3[k];
|
|
6726
6726
|
} };
|
|
6727
6727
|
}
|
|
6728
|
-
Object.defineProperty(o,
|
|
6729
|
-
}) : (function(o,
|
|
6730
|
-
if (
|
|
6731
|
-
o[
|
|
6728
|
+
Object.defineProperty(o, k2, desc);
|
|
6729
|
+
}) : (function(o, m3, k, k2) {
|
|
6730
|
+
if (k2 === void 0) k2 = k;
|
|
6731
|
+
o[k2] = m3[k];
|
|
6732
6732
|
}));
|
|
6733
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o,
|
|
6734
|
-
Object.defineProperty(o, "default", { enumerable: true, value:
|
|
6735
|
-
}) : function(o,
|
|
6736
|
-
o["default"] =
|
|
6733
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v3) {
|
|
6734
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v3 });
|
|
6735
|
+
}) : function(o, v3) {
|
|
6736
|
+
o["default"] = v3;
|
|
6737
6737
|
});
|
|
6738
6738
|
var __importStar = exports && exports.__importStar || function(mod) {
|
|
6739
6739
|
if (mod && mod.__esModule) return mod;
|
|
6740
6740
|
var result = {};
|
|
6741
6741
|
if (mod != null) {
|
|
6742
|
-
for (var
|
|
6742
|
+
for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
6743
6743
|
}
|
|
6744
6744
|
__setModuleDefault(result, mod);
|
|
6745
6745
|
return result;
|
|
6746
6746
|
};
|
|
6747
|
-
var __exportStar = exports && exports.__exportStar || function(
|
|
6748
|
-
for (var p2 in
|
|
6747
|
+
var __exportStar = exports && exports.__exportStar || function(m3, exports2) {
|
|
6748
|
+
for (var p2 in m3) if (p2 !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p2)) __createBinding(exports2, m3, p2);
|
|
6749
6749
|
};
|
|
6750
6750
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6751
6751
|
exports.Agent = void 0;
|
|
@@ -6851,17 +6851,17 @@ var require_dist = __commonJS({
|
|
|
6851
6851
|
get defaultPort() {
|
|
6852
6852
|
return this[INTERNAL].defaultPort ?? (this.protocol === "https:" ? 443 : 80);
|
|
6853
6853
|
}
|
|
6854
|
-
set defaultPort(
|
|
6854
|
+
set defaultPort(v3) {
|
|
6855
6855
|
if (this[INTERNAL]) {
|
|
6856
|
-
this[INTERNAL].defaultPort =
|
|
6856
|
+
this[INTERNAL].defaultPort = v3;
|
|
6857
6857
|
}
|
|
6858
6858
|
}
|
|
6859
6859
|
get protocol() {
|
|
6860
6860
|
return this[INTERNAL].protocol ?? (this.isSecureEndpoint() ? "https:" : "http:");
|
|
6861
6861
|
}
|
|
6862
|
-
set protocol(
|
|
6862
|
+
set protocol(v3) {
|
|
6863
6863
|
if (this[INTERNAL]) {
|
|
6864
|
-
this[INTERNAL].protocol =
|
|
6864
|
+
this[INTERNAL].protocol = v3;
|
|
6865
6865
|
}
|
|
6866
6866
|
}
|
|
6867
6867
|
};
|
|
@@ -6882,7 +6882,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
6882
6882
|
var debug_1 = __importDefault(require_src());
|
|
6883
6883
|
var debug = (0, debug_1.default)("https-proxy-agent:parse-proxy-response");
|
|
6884
6884
|
function parseProxyResponse(socket) {
|
|
6885
|
-
return new Promise((
|
|
6885
|
+
return new Promise((resolve4, reject) => {
|
|
6886
6886
|
let buffersLength = 0;
|
|
6887
6887
|
const buffers = [];
|
|
6888
6888
|
function read() {
|
|
@@ -6948,7 +6948,7 @@ var require_parse_proxy_response = __commonJS({
|
|
|
6948
6948
|
}
|
|
6949
6949
|
debug("got proxy server response: %o %o", firstLine, headers);
|
|
6950
6950
|
cleanup();
|
|
6951
|
-
|
|
6951
|
+
resolve4({
|
|
6952
6952
|
connect: {
|
|
6953
6953
|
statusCode,
|
|
6954
6954
|
statusText,
|
|
@@ -6971,29 +6971,29 @@ var require_dist2 = __commonJS({
|
|
|
6971
6971
|
"node_modules/https-proxy-agent/dist/index.js"(exports) {
|
|
6972
6972
|
"use strict";
|
|
6973
6973
|
init_define_MESSENGER_BUILD_INFO();
|
|
6974
|
-
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o,
|
|
6975
|
-
if (
|
|
6976
|
-
var desc = Object.getOwnPropertyDescriptor(
|
|
6977
|
-
if (!desc || ("get" in desc ? !
|
|
6974
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? (function(o, m3, k, k2) {
|
|
6975
|
+
if (k2 === void 0) k2 = k;
|
|
6976
|
+
var desc = Object.getOwnPropertyDescriptor(m3, k);
|
|
6977
|
+
if (!desc || ("get" in desc ? !m3.__esModule : desc.writable || desc.configurable)) {
|
|
6978
6978
|
desc = { enumerable: true, get: function() {
|
|
6979
|
-
return
|
|
6979
|
+
return m3[k];
|
|
6980
6980
|
} };
|
|
6981
6981
|
}
|
|
6982
|
-
Object.defineProperty(o,
|
|
6983
|
-
}) : (function(o,
|
|
6984
|
-
if (
|
|
6985
|
-
o[
|
|
6982
|
+
Object.defineProperty(o, k2, desc);
|
|
6983
|
+
}) : (function(o, m3, k, k2) {
|
|
6984
|
+
if (k2 === void 0) k2 = k;
|
|
6985
|
+
o[k2] = m3[k];
|
|
6986
6986
|
}));
|
|
6987
|
-
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o,
|
|
6988
|
-
Object.defineProperty(o, "default", { enumerable: true, value:
|
|
6989
|
-
}) : function(o,
|
|
6990
|
-
o["default"] =
|
|
6987
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? (function(o, v3) {
|
|
6988
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v3 });
|
|
6989
|
+
}) : function(o, v3) {
|
|
6990
|
+
o["default"] = v3;
|
|
6991
6991
|
});
|
|
6992
6992
|
var __importStar = exports && exports.__importStar || function(mod) {
|
|
6993
6993
|
if (mod && mod.__esModule) return mod;
|
|
6994
6994
|
var result = {};
|
|
6995
6995
|
if (mod != null) {
|
|
6996
|
-
for (var
|
|
6996
|
+
for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
6997
6997
|
}
|
|
6998
6998
|
__setModuleDefault(result, mod);
|
|
6999
6999
|
return result;
|
|
@@ -7346,7 +7346,7 @@ var require_web_push_lib = __commonJS({
|
|
|
7346
7346
|
} catch (err) {
|
|
7347
7347
|
return Promise.reject(err);
|
|
7348
7348
|
}
|
|
7349
|
-
return new Promise(function(
|
|
7349
|
+
return new Promise(function(resolve4, reject) {
|
|
7350
7350
|
const httpsOptions = {};
|
|
7351
7351
|
const urlParts = url.parse(requestDetails.endpoint);
|
|
7352
7352
|
httpsOptions.hostname = urlParts.hostname;
|
|
@@ -7379,7 +7379,7 @@ var require_web_push_lib = __commonJS({
|
|
|
7379
7379
|
requestDetails.endpoint
|
|
7380
7380
|
));
|
|
7381
7381
|
} else {
|
|
7382
|
-
|
|
7382
|
+
resolve4({
|
|
7383
7383
|
statusCode: pushResponse.statusCode,
|
|
7384
7384
|
body: responseText,
|
|
7385
7385
|
headers: pushResponse.headers
|
|
@@ -9656,10 +9656,10 @@ var require_extension = __commonJS({
|
|
|
9656
9656
|
if (!Array.isArray(configurations)) configurations = [configurations];
|
|
9657
9657
|
return configurations.map((params) => {
|
|
9658
9658
|
return [extension2].concat(
|
|
9659
|
-
Object.keys(params).map((
|
|
9660
|
-
let values = params[
|
|
9659
|
+
Object.keys(params).map((k) => {
|
|
9660
|
+
let values = params[k];
|
|
9661
9661
|
if (!Array.isArray(values)) values = [values];
|
|
9662
|
-
return values.map((
|
|
9662
|
+
return values.map((v3) => v3 === true ? k : `${k}=${v3}`).join("; ");
|
|
9663
9663
|
})
|
|
9664
9664
|
).join("; ");
|
|
9665
9665
|
}).join(", ");
|
|
@@ -11111,7 +11111,7 @@ var require_websocket_server = __commonJS({
|
|
|
11111
11111
|
socket.once("finish", socket.destroy);
|
|
11112
11112
|
socket.end(
|
|
11113
11113
|
`HTTP/1.1 ${code} ${http.STATUS_CODES[code]}\r
|
|
11114
|
-
` + Object.keys(headers).map((
|
|
11114
|
+
` + Object.keys(headers).map((h3) => `${h3}: ${headers[h3]}`).join("\r\n") + "\r\n\r\n" + message
|
|
11115
11115
|
);
|
|
11116
11116
|
}
|
|
11117
11117
|
function abortHandshakeOrEmitwsClientError(server, req, socket, code, message, headers) {
|
|
@@ -11751,18 +11751,48 @@ var MessengerNotificationProducer = class {
|
|
|
11751
11751
|
import { existsSync as existsSync3 } from "node:fs";
|
|
11752
11752
|
import { readFile, realpath, stat } from "node:fs/promises";
|
|
11753
11753
|
import { createServer } from "node:http";
|
|
11754
|
-
import { dirname as dirname5, extname, isAbsolute as isAbsolute2, relative, resolve as
|
|
11754
|
+
import { dirname as dirname5, extname, isAbsolute as isAbsolute2, relative, resolve as resolve3, sep } from "node:path";
|
|
11755
11755
|
import { fileURLToPath } from "node:url";
|
|
11756
11756
|
import { Worker } from "node:worker_threads";
|
|
11757
11757
|
|
|
11758
11758
|
// src/api.ts
|
|
11759
11759
|
init_define_MESSENGER_BUILD_INFO();
|
|
11760
11760
|
|
|
11761
|
+
// src/resource-connections.ts
|
|
11762
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
11763
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
11764
|
+
|
|
11761
11765
|
// src/workspace-profile.ts
|
|
11762
11766
|
init_define_MESSENGER_BUILD_INFO();
|
|
11763
11767
|
import { existsSync as existsSync2, lstatSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11764
|
-
import { join as join2 } from "node:path";
|
|
11768
|
+
import { join as join2, resolve } from "node:path";
|
|
11765
11769
|
import { randomUUID } from "node:crypto";
|
|
11770
|
+
var profileObservers = /* @__PURE__ */ new Map();
|
|
11771
|
+
function profileKey(dir, cid) {
|
|
11772
|
+
return resolve(path(dir, cid));
|
|
11773
|
+
}
|
|
11774
|
+
function subscribeHumanProfile(dir, cid, onCommitted, signal) {
|
|
11775
|
+
if (signal.aborted) return () => {
|
|
11776
|
+
};
|
|
11777
|
+
const key = profileKey(dir, cid), observers = profileObservers.get(key) ?? /* @__PURE__ */ new Set();
|
|
11778
|
+
profileObservers.set(key, observers);
|
|
11779
|
+
observers.add(onCommitted);
|
|
11780
|
+
const dispose = () => {
|
|
11781
|
+
observers.delete(onCommitted);
|
|
11782
|
+
if (!observers.size) profileObservers.delete(key);
|
|
11783
|
+
signal.removeEventListener("abort", dispose);
|
|
11784
|
+
};
|
|
11785
|
+
signal.addEventListener("abort", dispose, { once: true });
|
|
11786
|
+
return dispose;
|
|
11787
|
+
}
|
|
11788
|
+
function publishHumanProfile(dir, cid) {
|
|
11789
|
+
for (const observer of [...profileObservers.get(profileKey(dir, cid)) ?? []]) {
|
|
11790
|
+
try {
|
|
11791
|
+
observer();
|
|
11792
|
+
} catch {
|
|
11793
|
+
}
|
|
11794
|
+
}
|
|
11795
|
+
}
|
|
11766
11796
|
function workspaceProfile(value) {
|
|
11767
11797
|
const optional = (field) => field == null || field === "" ? null : profileName(field);
|
|
11768
11798
|
return { fullName: optional(value.fullName), name: optional(value.name), surname: optional(value.surname) };
|
|
@@ -11797,15 +11827,311 @@ function writeHumanProfile(dir, cid, value) {
|
|
|
11797
11827
|
const temporary = file + "." + randomUUID();
|
|
11798
11828
|
writeFileSync2(temporary, JSON.stringify(row) + "\n", { mode: 384, flag: "wx" });
|
|
11799
11829
|
renameSync2(temporary, file);
|
|
11830
|
+
publishHumanProfile(dir, cid);
|
|
11800
11831
|
return row;
|
|
11801
11832
|
}
|
|
11802
11833
|
|
|
11834
|
+
// src/watch.ts
|
|
11835
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
11836
|
+
import { createHash } from "node:crypto";
|
|
11837
|
+
|
|
11838
|
+
// src/events.ts
|
|
11839
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
11840
|
+
var nonEmpty2 = (value) => typeof value === "string" && value.length > 0;
|
|
11841
|
+
function normalizeNotification(record) {
|
|
11842
|
+
if (record.event === "message_received") {
|
|
11843
|
+
if (!nonEmpty2(record.sender_id) || !nonEmpty2(record.wire_id) || !nonEmpty2(record.date)) {
|
|
11844
|
+
return { type: "sync_required", reason: "legacy_event" };
|
|
11845
|
+
}
|
|
11846
|
+
return {
|
|
11847
|
+
type: "message_received",
|
|
11848
|
+
contact_id: record.sender_id,
|
|
11849
|
+
wire_id: record.wire_id,
|
|
11850
|
+
date: record.date
|
|
11851
|
+
};
|
|
11852
|
+
}
|
|
11853
|
+
if (record.event === "receipt_received") {
|
|
11854
|
+
const kind = record.kind;
|
|
11855
|
+
const wireIds = record.wire_ids;
|
|
11856
|
+
if (!nonEmpty2(record.sender_id) || kind !== "delivered" && kind !== "read" || !Array.isArray(wireIds) || !wireIds.every(nonEmpty2)) {
|
|
11857
|
+
return { type: "sync_required", reason: "legacy_event" };
|
|
11858
|
+
}
|
|
11859
|
+
return {
|
|
11860
|
+
type: "receipt_received",
|
|
11861
|
+
contact_id: record.sender_id,
|
|
11862
|
+
kind,
|
|
11863
|
+
wire_ids: [...wireIds],
|
|
11864
|
+
// Receipt time is not present in the currently published actor contract.
|
|
11865
|
+
// A fixed actor should supply it; observation time is the explicit fallback.
|
|
11866
|
+
date: nonEmpty2(record.date) ? record.date : (/* @__PURE__ */ new Date()).toISOString()
|
|
11867
|
+
};
|
|
11868
|
+
}
|
|
11869
|
+
if (record.event === "file_received") {
|
|
11870
|
+
if (!nonEmpty2(record.sender_id) || !nonEmpty2(record.wire_id) || !nonEmpty2(record.date)) {
|
|
11871
|
+
return { type: "sync_required", reason: "legacy_event" };
|
|
11872
|
+
}
|
|
11873
|
+
return {
|
|
11874
|
+
type: "file_received",
|
|
11875
|
+
contact_id: record.sender_id,
|
|
11876
|
+
wire_id: record.wire_id,
|
|
11877
|
+
date: record.date
|
|
11878
|
+
};
|
|
11879
|
+
}
|
|
11880
|
+
return { type: "sync_required", reason: "unknown_event" };
|
|
11881
|
+
}
|
|
11882
|
+
var MessengerEventBus = class {
|
|
11883
|
+
#subscribers = /* @__PURE__ */ new Set();
|
|
11884
|
+
get size() {
|
|
11885
|
+
return this.#subscribers.size;
|
|
11886
|
+
}
|
|
11887
|
+
subscribe(limit = 64) {
|
|
11888
|
+
if (!Number.isInteger(limit) || limit < 1) throw new Error("subscriber queue limit must be a positive integer");
|
|
11889
|
+
const sub = { limit, queue: [], waiting: null, closed: false, overflowed: false };
|
|
11890
|
+
this.#subscribers.add(sub);
|
|
11891
|
+
return {
|
|
11892
|
+
next: () => {
|
|
11893
|
+
if (sub.queue.length > 0) {
|
|
11894
|
+
const event = sub.queue.shift();
|
|
11895
|
+
if (event.type === "sync_required" && event.reason === "overflow") sub.overflowed = false;
|
|
11896
|
+
return Promise.resolve(event);
|
|
11897
|
+
}
|
|
11898
|
+
if (sub.closed) return Promise.resolve(null);
|
|
11899
|
+
if (sub.waiting) throw new Error("only one pending next() is allowed per event subscriber");
|
|
11900
|
+
return new Promise((resolve4) => {
|
|
11901
|
+
sub.waiting = resolve4;
|
|
11902
|
+
});
|
|
11903
|
+
},
|
|
11904
|
+
close: () => this.#close(sub)
|
|
11905
|
+
};
|
|
11906
|
+
}
|
|
11907
|
+
publish(event) {
|
|
11908
|
+
for (const sub of this.#subscribers) {
|
|
11909
|
+
if (sub.closed) continue;
|
|
11910
|
+
if (sub.waiting) {
|
|
11911
|
+
const resolve4 = sub.waiting;
|
|
11912
|
+
sub.waiting = null;
|
|
11913
|
+
resolve4(event);
|
|
11914
|
+
continue;
|
|
11915
|
+
}
|
|
11916
|
+
if (sub.overflowed) continue;
|
|
11917
|
+
if (sub.queue.length >= sub.limit) {
|
|
11918
|
+
sub.queue.splice(0, sub.queue.length, { type: "sync_required", reason: "overflow" });
|
|
11919
|
+
sub.overflowed = true;
|
|
11920
|
+
continue;
|
|
11921
|
+
}
|
|
11922
|
+
sub.queue.push(event);
|
|
11923
|
+
}
|
|
11924
|
+
}
|
|
11925
|
+
close() {
|
|
11926
|
+
for (const sub of [...this.#subscribers]) this.#close(sub);
|
|
11927
|
+
}
|
|
11928
|
+
#close(sub) {
|
|
11929
|
+
if (sub.closed) return;
|
|
11930
|
+
sub.closed = true;
|
|
11931
|
+
sub.queue.length = 0;
|
|
11932
|
+
this.#subscribers.delete(sub);
|
|
11933
|
+
const resolve4 = sub.waiting;
|
|
11934
|
+
sub.waiting = null;
|
|
11935
|
+
resolve4?.(null);
|
|
11936
|
+
}
|
|
11937
|
+
};
|
|
11938
|
+
function toSse(event, identity) {
|
|
11939
|
+
if (event.type === "sync_required") {
|
|
11940
|
+
return {
|
|
11941
|
+
event: event.type,
|
|
11942
|
+
data: { v: 1, reason: event.reason, ...identity ? { identity } : {} }
|
|
11943
|
+
};
|
|
11944
|
+
}
|
|
11945
|
+
const { type, ...metadata } = event;
|
|
11946
|
+
return { event: type, data: { v: 1, ...metadata } };
|
|
11947
|
+
}
|
|
11948
|
+
|
|
11949
|
+
// src/watch.ts
|
|
11950
|
+
function pageDigest(events) {
|
|
11951
|
+
return createHash("sha256").update(JSON.stringify(events)).digest("base64url");
|
|
11952
|
+
}
|
|
11953
|
+
function applyNotificationPage(page, push, delivery, events, stats, log2) {
|
|
11954
|
+
if (!Number.isSafeInteger(page.cursor) || page.cursor < 0 || !Array.isArray(page.events)) {
|
|
11955
|
+
throw new Error("daemon notification page is malformed");
|
|
11956
|
+
}
|
|
11957
|
+
const fromCursor = push.notificationCursor;
|
|
11958
|
+
if (fromCursor === null) {
|
|
11959
|
+
if (page.events.length > 0) throw new Error("daemon notification tip page unexpectedly contained events");
|
|
11960
|
+
push.commitNotificationCursor(page.cursor);
|
|
11961
|
+
stats.cursorCommits++;
|
|
11962
|
+
return true;
|
|
11963
|
+
}
|
|
11964
|
+
let progress = push.notificationPageProgress;
|
|
11965
|
+
if (progress) {
|
|
11966
|
+
const prefix = page.events.slice(0, progress.eventCount);
|
|
11967
|
+
if (progress.fromCursor !== fromCursor || page.cursor < progress.cursor || page.events.length < progress.eventCount || pageDigest(prefix) !== progress.digest) {
|
|
11968
|
+
throw new Error("daemon notification page changed while a checkpoint was in progress");
|
|
11969
|
+
}
|
|
11970
|
+
} else {
|
|
11971
|
+
progress = push.beginNotificationPage({
|
|
11972
|
+
fromCursor,
|
|
11973
|
+
cursor: page.cursor,
|
|
11974
|
+
eventCount: page.events.length,
|
|
11975
|
+
digest: pageDigest(page.events)
|
|
11976
|
+
});
|
|
11977
|
+
}
|
|
11978
|
+
for (let index = progress.nextIndex; index < progress.eventCount; index++) {
|
|
11979
|
+
const record = page.events[index];
|
|
11980
|
+
const admission = delivery.admit(record, index + 1);
|
|
11981
|
+
if (admission.status === "saturated") {
|
|
11982
|
+
push.checkpointNotificationPage();
|
|
11983
|
+
stats.saturationEvents++;
|
|
11984
|
+
log2.warn(`event=push_cursor_blocked status=saturated source_cursor=${page.cursor}`);
|
|
11985
|
+
return false;
|
|
11986
|
+
}
|
|
11987
|
+
stats.events++;
|
|
11988
|
+
events.publish(normalizeNotification(record));
|
|
11989
|
+
if (!admission.checkpointed) push.advanceNotificationPage(index + 1);
|
|
11990
|
+
}
|
|
11991
|
+
push.commitNotificationPage();
|
|
11992
|
+
stats.cursorCommits++;
|
|
11993
|
+
return true;
|
|
11994
|
+
}
|
|
11995
|
+
function abortableWait(ms, signal) {
|
|
11996
|
+
if (signal.aborted) return Promise.resolve();
|
|
11997
|
+
return new Promise((resolve4) => {
|
|
11998
|
+
const timer = setTimeout(done, ms);
|
|
11999
|
+
function done() {
|
|
12000
|
+
clearTimeout(timer);
|
|
12001
|
+
signal.removeEventListener("abort", done);
|
|
12002
|
+
resolve4();
|
|
12003
|
+
}
|
|
12004
|
+
signal.addEventListener("abort", done, { once: true });
|
|
12005
|
+
});
|
|
12006
|
+
}
|
|
12007
|
+
function startWatcher(client, identity, push, log2, events, options) {
|
|
12008
|
+
const controller = new AbortController();
|
|
12009
|
+
const stats = { pushes: 0, events: 0, reconnects: 0, cursorCommits: 0, saturationEvents: 0 };
|
|
12010
|
+
let backoffMs = 500;
|
|
12011
|
+
let reconnecting = false;
|
|
12012
|
+
const wait = options.wait ?? abortableWait;
|
|
12013
|
+
const probe = options.probe ?? (() => client.version());
|
|
12014
|
+
const loop = (async () => {
|
|
12015
|
+
while (!controller.signal.aborted) {
|
|
12016
|
+
try {
|
|
12017
|
+
if (reconnecting) {
|
|
12018
|
+
await probe();
|
|
12019
|
+
if (controller.signal.aborted) break;
|
|
12020
|
+
events.publish({ type: "sync_required", reason: "daemon_reconnected" });
|
|
12021
|
+
reconnecting = false;
|
|
12022
|
+
}
|
|
12023
|
+
const since = push.notificationCursor ?? "tip";
|
|
12024
|
+
const page = await options.readPage(identity, since, controller.signal);
|
|
12025
|
+
if (controller.signal.aborted) break;
|
|
12026
|
+
const committed = applyNotificationPage(page, push, options.delivery, events, stats, log2);
|
|
12027
|
+
if (!committed) {
|
|
12028
|
+
await wait(backoffMs, controller.signal);
|
|
12029
|
+
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
12030
|
+
continue;
|
|
12031
|
+
}
|
|
12032
|
+
backoffMs = 500;
|
|
12033
|
+
} catch (e2) {
|
|
12034
|
+
if (controller.signal.aborted) break;
|
|
12035
|
+
stats.reconnects++;
|
|
12036
|
+
reconnecting = true;
|
|
12037
|
+
events.publish({ type: "sync_required", reason: "daemon_unavailable" });
|
|
12038
|
+
reportFailure(log2.warn, `watch stream; reconnecting in ${backoffMs}ms`, e2);
|
|
12039
|
+
await wait(backoffMs, controller.signal);
|
|
12040
|
+
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
12041
|
+
}
|
|
12042
|
+
}
|
|
12043
|
+
})();
|
|
12044
|
+
return {
|
|
12045
|
+
stats,
|
|
12046
|
+
async stop() {
|
|
12047
|
+
controller.abort();
|
|
12048
|
+
await loop;
|
|
12049
|
+
}
|
|
12050
|
+
};
|
|
12051
|
+
}
|
|
12052
|
+
function startResourceObserver(client, identity, callbacks) {
|
|
12053
|
+
const controller = new AbortController();
|
|
12054
|
+
let healthy = false;
|
|
12055
|
+
let failed = false;
|
|
12056
|
+
let lastCoverage = 0;
|
|
12057
|
+
let generation;
|
|
12058
|
+
let readyResolve;
|
|
12059
|
+
let readyReject;
|
|
12060
|
+
let readySettled = false;
|
|
12061
|
+
const ready = new Promise((resolve4, reject) => {
|
|
12062
|
+
readyResolve = resolve4;
|
|
12063
|
+
readyReject = reject;
|
|
12064
|
+
});
|
|
12065
|
+
void ready.catch(() => {
|
|
12066
|
+
});
|
|
12067
|
+
const fail = (error) => {
|
|
12068
|
+
if (failed) return;
|
|
12069
|
+
failed = true;
|
|
12070
|
+
healthy = false;
|
|
12071
|
+
if (!readySettled) {
|
|
12072
|
+
readySettled = true;
|
|
12073
|
+
readyReject(error);
|
|
12074
|
+
}
|
|
12075
|
+
if (!controller.signal.aborted) callbacks.failed(error);
|
|
12076
|
+
};
|
|
12077
|
+
const loop = (async () => {
|
|
12078
|
+
try {
|
|
12079
|
+
for await (const frame of client.resourceEvents(identity, { signal: controller.signal })) {
|
|
12080
|
+
if (controller.signal.aborted) break;
|
|
12081
|
+
if (frame.kind === "resync" || generation !== void 0 && generation !== frame.producerGeneration) {
|
|
12082
|
+
throw new Error("resource source continuity lost");
|
|
12083
|
+
}
|
|
12084
|
+
lastCoverage = Date.now();
|
|
12085
|
+
if (frame.kind === "ready") {
|
|
12086
|
+
generation = frame.producerGeneration;
|
|
12087
|
+
healthy = true;
|
|
12088
|
+
if (!readySettled) {
|
|
12089
|
+
readySettled = true;
|
|
12090
|
+
readyResolve();
|
|
12091
|
+
}
|
|
12092
|
+
}
|
|
12093
|
+
callbacks.committed(frame);
|
|
12094
|
+
}
|
|
12095
|
+
if (!controller.signal.aborted) fail(new Error("resource source ended"));
|
|
12096
|
+
} catch (error) {
|
|
12097
|
+
fail(error instanceof Error ? error : new Error("resource source failed"));
|
|
12098
|
+
} finally {
|
|
12099
|
+
healthy = false;
|
|
12100
|
+
}
|
|
12101
|
+
})();
|
|
12102
|
+
return {
|
|
12103
|
+
ready,
|
|
12104
|
+
get healthy() {
|
|
12105
|
+
if (healthy && Date.now() - lastCoverage >= 6e3) {
|
|
12106
|
+
fail(new Error("resource source coverage expired"));
|
|
12107
|
+
controller.abort();
|
|
12108
|
+
}
|
|
12109
|
+
return healthy;
|
|
12110
|
+
},
|
|
12111
|
+
get generation() {
|
|
12112
|
+
return generation;
|
|
12113
|
+
},
|
|
12114
|
+
async stop() {
|
|
12115
|
+
healthy = false;
|
|
12116
|
+
controller.abort();
|
|
12117
|
+
if (!readySettled) {
|
|
12118
|
+
readySettled = true;
|
|
12119
|
+
readyReject(new Error("resource source aborted"));
|
|
12120
|
+
}
|
|
12121
|
+
await loop;
|
|
12122
|
+
}
|
|
12123
|
+
};
|
|
12124
|
+
}
|
|
12125
|
+
|
|
12126
|
+
// src/resource-views.ts
|
|
12127
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
12128
|
+
|
|
11803
12129
|
// src/conversation.ts
|
|
11804
12130
|
init_define_MESSENGER_BUILD_INFO();
|
|
11805
12131
|
|
|
11806
12132
|
// src/typed-commands.ts
|
|
11807
12133
|
init_define_MESSENGER_BUILD_INFO();
|
|
11808
|
-
import { createHash } from "node:crypto";
|
|
12134
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
11809
12135
|
var MAX_COMMANDS = 64;
|
|
11810
12136
|
var MAX_COMMAND_NAME_LENGTH = 128;
|
|
11811
12137
|
var MAX_COMMAND_DESCRIPTION_LENGTH = 2048;
|
|
@@ -11865,7 +12191,7 @@ function projectCatalog(recipientCid, commands) {
|
|
|
11865
12191
|
input_schema: command.input_schema
|
|
11866
12192
|
};
|
|
11867
12193
|
});
|
|
11868
|
-
const fingerprint2 =
|
|
12194
|
+
const fingerprint2 = createHash2("sha256").update(canonical({
|
|
11869
12195
|
recipient_cid: recipientCid,
|
|
11870
12196
|
commands: projected
|
|
11871
12197
|
})).digest("base64url");
|
|
@@ -11948,128 +12274,494 @@ function projectHistoryPage(contact, history, summary, opts = {}) {
|
|
|
11948
12274
|
};
|
|
11949
12275
|
}
|
|
11950
12276
|
|
|
11951
|
-
// src/
|
|
11952
|
-
|
|
11953
|
-
|
|
11954
|
-
|
|
11955
|
-
const
|
|
11956
|
-
|
|
11957
|
-
}
|
|
12277
|
+
// src/resource-views.ts
|
|
12278
|
+
async function abortableProjection(read, signal) {
|
|
12279
|
+
signal.throwIfAborted();
|
|
12280
|
+
let onAbort;
|
|
12281
|
+
const aborted = new Promise((_, reject) => {
|
|
12282
|
+
onAbort = () => reject(signal.reason ?? new Error("resource projection aborted"));
|
|
12283
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
12284
|
+
});
|
|
12285
|
+
try {
|
|
12286
|
+
return await Promise.race([read, aborted]);
|
|
12287
|
+
} finally {
|
|
12288
|
+
signal.removeEventListener("abort", onAbort);
|
|
12289
|
+
}
|
|
12290
|
+
}
|
|
12291
|
+
async function captureResourceProjection(client, identity, project, signal, localRevision = () => 0) {
|
|
12292
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
12293
|
+
signal.throwIfAborted();
|
|
12294
|
+
const local = localRevision();
|
|
12295
|
+
const before = await abortableProjection(client.resourcePosition(identity, { signal }), signal);
|
|
12296
|
+
signal.throwIfAborted();
|
|
12297
|
+
const payload = await abortableProjection(project(), signal);
|
|
12298
|
+
signal.throwIfAborted();
|
|
12299
|
+
const after = await abortableProjection(client.resourcePosition(identity, { signal }), signal);
|
|
12300
|
+
signal.throwIfAborted();
|
|
12301
|
+
if (before.producerGeneration === after.producerGeneration && before.position === after.position && local === localRevision()) return { source: after, payload };
|
|
12302
|
+
}
|
|
12303
|
+
throw new Error("resource projection unstable");
|
|
12304
|
+
}
|
|
12305
|
+
var RESOURCE_FRAME_BYTES = 512 * 1024;
|
|
12306
|
+
var RESOURCE_PENDING_BYTES = 8 * 1024 * 1024;
|
|
12307
|
+
var RESOURCE_ASSEMBLY_BYTES = 16 * 1024 * 1024;
|
|
12308
|
+
var CHUNK_BYTES = 256 * 1024;
|
|
12309
|
+
function* resourceFrames(envelope) {
|
|
12310
|
+
const bytes = Buffer.from(JSON.stringify(envelope));
|
|
12311
|
+
if (bytes.length > RESOURCE_ASSEMBLY_BYTES) throw new Error("resource assembly limit exceeded");
|
|
12312
|
+
const ordinary = { event: "resource", data: envelope };
|
|
12313
|
+
if (Buffer.byteLength(`event: resource
|
|
12314
|
+
data: ${bytes.toString("utf8")}
|
|
11958
12315
|
|
|
11959
|
-
|
|
11960
|
-
|
|
11961
|
-
|
|
11962
|
-
function normalizeNotification(record) {
|
|
11963
|
-
if (record.event === "message_received") {
|
|
11964
|
-
if (!nonEmpty2(record.sender_id) || !nonEmpty2(record.wire_id) || !nonEmpty2(record.date)) {
|
|
11965
|
-
return { type: "sync_required", reason: "legacy_event" };
|
|
11966
|
-
}
|
|
11967
|
-
return {
|
|
11968
|
-
type: "message_received",
|
|
11969
|
-
contact_id: record.sender_id,
|
|
11970
|
-
wire_id: record.wire_id,
|
|
11971
|
-
date: record.date
|
|
11972
|
-
};
|
|
12316
|
+
`) <= RESOURCE_FRAME_BYTES) {
|
|
12317
|
+
yield ordinary;
|
|
12318
|
+
return;
|
|
11973
12319
|
}
|
|
11974
|
-
|
|
11975
|
-
|
|
11976
|
-
|
|
11977
|
-
|
|
11978
|
-
|
|
11979
|
-
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
12320
|
+
const id = `${envelope.viewId}:${envelope.subscriptionEpoch}:${envelope.sequence}`;
|
|
12321
|
+
const binding = {
|
|
12322
|
+
protocolVersion: 1,
|
|
12323
|
+
id,
|
|
12324
|
+
producerGeneration: envelope.producerGeneration,
|
|
12325
|
+
viewId: envelope.viewId,
|
|
12326
|
+
subscriptionEpoch: envelope.subscriptionEpoch,
|
|
12327
|
+
revision: envelope.revision,
|
|
12328
|
+
sequence: envelope.sequence
|
|
12329
|
+
};
|
|
12330
|
+
yield { event: "resource-chunk", data: { ...binding, type: "start", totalBytes: bytes.length, parts: Math.ceil(bytes.length / CHUNK_BYTES) } };
|
|
12331
|
+
for (let offset = 0, index = 0; offset < bytes.length; offset += CHUNK_BYTES, index++) {
|
|
12332
|
+
yield { event: "resource-chunk", data: { ...binding, type: "chunk", index, data: bytes.subarray(offset, offset + CHUNK_BYTES).toString("base64") } };
|
|
12333
|
+
}
|
|
12334
|
+
yield { event: "resource-chunk", data: { ...binding, type: "commit", totalBytes: bytes.length } };
|
|
12335
|
+
}
|
|
12336
|
+
function canonicalResourceDescriptor(value) {
|
|
12337
|
+
const invalid = () => {
|
|
12338
|
+
throw new Error("invalid resource descriptor");
|
|
12339
|
+
};
|
|
12340
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return invalid();
|
|
12341
|
+
const row = value;
|
|
12342
|
+
if (Object.keys(row).some((key) => !["viewId", "resource", "entityId", "window"].includes(key)) || typeof row.viewId !== "string" || !/^[A-Za-z0-9_-]{1,128}$/.test(row.viewId) || !["contacts", "identity", "messages", "files", "commands"].includes(String(row.resource))) return invalid();
|
|
12343
|
+
const resource = row.resource;
|
|
12344
|
+
const scoped = ["messages", "files", "commands"].includes(resource);
|
|
12345
|
+
if (scoped ? typeof row.entityId !== "string" || !row.entityId : row.entityId !== void 0) return invalid();
|
|
12346
|
+
if (resource !== "messages" && row.window !== void 0) return invalid();
|
|
12347
|
+
let window2;
|
|
12348
|
+
if (resource === "messages") {
|
|
12349
|
+
const raw = row.window ?? { limit: 50, retainedPages: 1 };
|
|
12350
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return invalid();
|
|
12351
|
+
const w2 = raw;
|
|
12352
|
+
if (Object.keys(w2).some((key) => !["limit", "retainedPages", "oldestSequence"].includes(key)) || !Number.isInteger(w2.limit) || w2.limit < 1 || w2.limit > 200 || !Number.isSafeInteger(w2.retainedPages) || w2.retainedPages < 1 || w2.oldestSequence !== void 0 && (!Number.isSafeInteger(w2.oldestSequence) || w2.oldestSequence < 1)) return invalid();
|
|
12353
|
+
window2 = {
|
|
12354
|
+
limit: w2.limit,
|
|
12355
|
+
retainedPages: w2.retainedPages,
|
|
12356
|
+
...w2.oldestSequence === void 0 ? {} : { oldestSequence: w2.oldestSequence }
|
|
11988
12357
|
};
|
|
11989
12358
|
}
|
|
11990
|
-
|
|
11991
|
-
|
|
11992
|
-
|
|
12359
|
+
return { viewId: row.viewId, resource, ...scoped ? { entityId: row.entityId } : {}, ...window2 ? { window: window2 } : {} };
|
|
12360
|
+
}
|
|
12361
|
+
async function projectMessageWindow(client, contact, announcedContact, window2, signal) {
|
|
12362
|
+
let before;
|
|
12363
|
+
const rows = [];
|
|
12364
|
+
let next = null;
|
|
12365
|
+
let totalBytes = 0;
|
|
12366
|
+
for (let pageIndex = 0; ; pageIndex++) {
|
|
12367
|
+
signal.throwIfAborted();
|
|
12368
|
+
const page = await client.listHistory({ peer_cid: contact, before_seq: before, limit: window2.limit });
|
|
12369
|
+
signal.throwIfAborted();
|
|
12370
|
+
if (page.next_cursor !== null && (!Number.isSafeInteger(page.next_cursor) || before !== void 0 && page.next_cursor >= before)) throw new Error("invalid history continuation");
|
|
12371
|
+
const selected = window2.oldestSequence === void 0 ? page.items : page.items.filter((row) => row.seq >= window2.oldestSequence);
|
|
12372
|
+
totalBytes += Buffer.byteLength(JSON.stringify(projectHistoryPage(
|
|
12373
|
+
contact,
|
|
12374
|
+
{ items: selected, next_cursor: null },
|
|
12375
|
+
{ total: 0, unread: 0 },
|
|
12376
|
+
{ announcedContact }
|
|
12377
|
+
).messages));
|
|
12378
|
+
if (totalBytes > RESOURCE_ASSEMBLY_BYTES) throw new Error("resource assembly limit exceeded");
|
|
12379
|
+
rows.push(...selected);
|
|
12380
|
+
next = page.next_cursor;
|
|
12381
|
+
const crossedLowerBound = window2.oldestSequence !== void 0 && page.items.some((row) => row.seq <= window2.oldestSequence);
|
|
12382
|
+
if (next === null || crossedLowerBound || window2.oldestSequence === void 0 && pageIndex + 1 >= window2.retainedPages) {
|
|
12383
|
+
if (selected.length !== page.items.length) next = selected.at(-1)?.seq ?? window2.oldestSequence;
|
|
12384
|
+
break;
|
|
11993
12385
|
}
|
|
11994
|
-
|
|
11995
|
-
type: "file_received",
|
|
11996
|
-
contact_id: record.sender_id,
|
|
11997
|
-
wire_id: record.wire_id,
|
|
11998
|
-
date: record.date
|
|
11999
|
-
};
|
|
12386
|
+
before = next;
|
|
12000
12387
|
}
|
|
12001
|
-
|
|
12388
|
+
const ids = new Set(rows.map((row) => row.wire_id));
|
|
12389
|
+
if (ids.has("") || ids.size !== rows.length) throw new Error("message view lacks stable IDs");
|
|
12390
|
+
const summary = await client.getHistorySummary({ peer_cid: contact });
|
|
12391
|
+
signal.throwIfAborted();
|
|
12392
|
+
return {
|
|
12393
|
+
...projectHistoryPage(contact, { items: rows, next_cursor: next }, summary, { announcedContact }),
|
|
12394
|
+
oldestSequence: rows.at(-1)?.seq ?? window2.oldestSequence ?? null
|
|
12395
|
+
};
|
|
12002
12396
|
}
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12397
|
+
async function messageProjectionDelta(client, previous, current, signal) {
|
|
12398
|
+
const old = new Map(previous.messages.map((item) => [item.wire_id, item]));
|
|
12399
|
+
const ids = new Set(current.messages.map((item) => item.wire_id));
|
|
12400
|
+
if (ids.has("") || ids.size !== current.messages.length) throw new Error("message view lacks stable IDs");
|
|
12401
|
+
const deletes = [];
|
|
12402
|
+
for (const id of old.keys()) {
|
|
12403
|
+
signal.throwIfAborted();
|
|
12404
|
+
if (!ids.has(id) && await client.getHistoryItem({ wire_id: id }) === null) deletes.push(id);
|
|
12405
|
+
}
|
|
12406
|
+
signal.throwIfAborted();
|
|
12407
|
+
const { messages, ...metadata } = current;
|
|
12408
|
+
return {
|
|
12409
|
+
type: "message-delta",
|
|
12410
|
+
upserts: messages.filter((item) => JSON.stringify(old.get(item.wire_id)) !== JSON.stringify(item)).map((item) => ({ id: item.wire_id, item })),
|
|
12411
|
+
deletes,
|
|
12412
|
+
window: { ...metadata, orderedIds: messages.map((item) => item.wire_id) }
|
|
12413
|
+
};
|
|
12414
|
+
}
|
|
12415
|
+
|
|
12416
|
+
// src/resource-connections.ts
|
|
12417
|
+
var ResourceOutput = class {
|
|
12418
|
+
constructor(response, signal, failed) {
|
|
12419
|
+
this.response = response;
|
|
12420
|
+
this.signal = signal;
|
|
12421
|
+
this.failed = failed;
|
|
12422
|
+
if (signal.aborted) this.close();
|
|
12423
|
+
else {
|
|
12424
|
+
signal.addEventListener("abort", this.#abort, { once: true });
|
|
12425
|
+
response.once("close", this.#abort);
|
|
12426
|
+
}
|
|
12427
|
+
}
|
|
12428
|
+
#pending = [];
|
|
12429
|
+
#pendingBytes = 0;
|
|
12430
|
+
#active;
|
|
12431
|
+
#closed = false;
|
|
12432
|
+
#releaseDrain;
|
|
12433
|
+
#abort = () => this.close();
|
|
12434
|
+
send(envelope) {
|
|
12435
|
+
if (this.#closed) return Promise.reject(new Error("resource output closed"));
|
|
12436
|
+
const bytes = Buffer.byteLength(JSON.stringify(envelope));
|
|
12437
|
+
if (bytes > RESOURCE_ASSEMBLY_BYTES) return this.#fail(new Error("resource assembly limit exceeded"));
|
|
12438
|
+
if (this.#active && this.#pendingBytes + bytes > RESOURCE_PENDING_BYTES) {
|
|
12439
|
+
return this.#fail(new Error("resource pending limit exceeded"));
|
|
12440
|
+
}
|
|
12441
|
+
return new Promise((resolve4, reject) => {
|
|
12442
|
+
const item = { envelope, bytes, resolve: resolve4, reject };
|
|
12443
|
+
if (!this.#active) {
|
|
12444
|
+
this.#active = item;
|
|
12445
|
+
void this.#pump();
|
|
12446
|
+
} else {
|
|
12447
|
+
this.#pending.push(item);
|
|
12448
|
+
this.#pendingBytes += bytes;
|
|
12449
|
+
}
|
|
12450
|
+
});
|
|
12007
12451
|
}
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12017
|
-
|
|
12452
|
+
#fail(error) {
|
|
12453
|
+
this.close(error);
|
|
12454
|
+
this.failed(error);
|
|
12455
|
+
return Promise.reject(error);
|
|
12456
|
+
}
|
|
12457
|
+
close(error = new Error("resource output closed")) {
|
|
12458
|
+
if (this.#closed) return;
|
|
12459
|
+
this.#closed = true;
|
|
12460
|
+
this.signal.removeEventListener("abort", this.#abort);
|
|
12461
|
+
this.response.removeListener("close", this.#abort);
|
|
12462
|
+
this.#releaseDrain?.();
|
|
12463
|
+
this.#active?.reject(error);
|
|
12464
|
+
for (const item of this.#pending.splice(0)) item.reject(error);
|
|
12465
|
+
this.#pendingBytes = 0;
|
|
12466
|
+
if (!this.response.destroyed && !this.response.writableEnded) this.response.end();
|
|
12467
|
+
}
|
|
12468
|
+
async #pump() {
|
|
12469
|
+
try {
|
|
12470
|
+
while (this.#active && !this.#closed) {
|
|
12471
|
+
const item = this.#active;
|
|
12472
|
+
for (const frame of resourceFrames(item.envelope)) {
|
|
12473
|
+
if (this.#closed) break;
|
|
12474
|
+
const writable = this.response.write(`event: ${frame.event}
|
|
12475
|
+
data: ${JSON.stringify(frame.data)}
|
|
12476
|
+
|
|
12477
|
+
`);
|
|
12478
|
+
if (!writable) await this.#drain();
|
|
12018
12479
|
}
|
|
12019
|
-
if (
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12480
|
+
if (this.#closed) break;
|
|
12481
|
+
item.resolve();
|
|
12482
|
+
this.#active = this.#pending.shift();
|
|
12483
|
+
if (this.#active) this.#pendingBytes -= this.#active.bytes;
|
|
12484
|
+
}
|
|
12485
|
+
} catch (error) {
|
|
12486
|
+
const failure = error instanceof Error ? error : new Error("resource output failed");
|
|
12487
|
+
this.close(failure);
|
|
12488
|
+
this.failed(failure);
|
|
12489
|
+
}
|
|
12490
|
+
}
|
|
12491
|
+
#drain() {
|
|
12492
|
+
if (this.#closed) return Promise.resolve();
|
|
12493
|
+
return new Promise((resolve4) => {
|
|
12494
|
+
const release = () => {
|
|
12495
|
+
this.response.removeListener("drain", release);
|
|
12496
|
+
this.#releaseDrain = void 0;
|
|
12497
|
+
resolve4();
|
|
12498
|
+
};
|
|
12499
|
+
this.#releaseDrain = release;
|
|
12500
|
+
this.response.once("drain", release);
|
|
12501
|
+
});
|
|
12502
|
+
}
|
|
12503
|
+
};
|
|
12504
|
+
var ResourceBindingError = class extends Error {
|
|
12505
|
+
constructor(status, message) {
|
|
12506
|
+
super(message);
|
|
12507
|
+
this.status = status;
|
|
12508
|
+
}
|
|
12509
|
+
};
|
|
12510
|
+
var ResourceConnections = class {
|
|
12511
|
+
constructor(deps) {
|
|
12512
|
+
this.deps = deps;
|
|
12513
|
+
}
|
|
12514
|
+
#connections = /* @__PURE__ */ new Map();
|
|
12515
|
+
producerGeneration = randomUUID2();
|
|
12516
|
+
open(response) {
|
|
12517
|
+
const id = randomUUID2(), controller = new AbortController();
|
|
12518
|
+
let resolveClosed;
|
|
12519
|
+
const closed = new Promise((resolve4) => {
|
|
12520
|
+
resolveClosed = resolve4;
|
|
12521
|
+
});
|
|
12522
|
+
let connection;
|
|
12523
|
+
const close = () => {
|
|
12524
|
+
if (controller.signal.aborted) return;
|
|
12525
|
+
controller.abort();
|
|
12526
|
+
this.#connections.delete(id);
|
|
12527
|
+
if (connection) {
|
|
12528
|
+
for (const view of connection.views.values()) this.#retire(view);
|
|
12529
|
+
connection.views.clear();
|
|
12530
|
+
connection.output.close();
|
|
12531
|
+
void connection.observer.stop().catch(() => {
|
|
12023
12532
|
});
|
|
12533
|
+
}
|
|
12534
|
+
response.removeListener("close", close);
|
|
12535
|
+
resolveClosed();
|
|
12536
|
+
};
|
|
12537
|
+
const output = new ResourceOutput(response, controller.signal, close);
|
|
12538
|
+
const observer = startResourceObserver(this.deps.client, this.deps.identity, {
|
|
12539
|
+
committed: (frame) => {
|
|
12540
|
+
if (!connection || controller.signal.aborted) return;
|
|
12541
|
+
for (const view of connection.views.values()) {
|
|
12542
|
+
if (frame.kind === "coverage") {
|
|
12543
|
+
if (view.covered && !view.failed) void this.#emit(connection, view, "coverage", { source: view.covered }).catch(close);
|
|
12544
|
+
} else if (!view.covered || frame.position > view.covered.position) this.#schedule(connection, view);
|
|
12545
|
+
}
|
|
12024
12546
|
},
|
|
12025
|
-
|
|
12547
|
+
failed: (error) => {
|
|
12548
|
+
if (!connection || controller.signal.aborted) return;
|
|
12549
|
+
const reason = "status" in error && (error.status === 401 || error.status === 403) ? "auth_required" : "status" in error && error.status === 404 ? "unsupported" : "upstream_unavailable";
|
|
12550
|
+
const writes = [...connection.views.values()].map((view) => {
|
|
12551
|
+
view.failed = true;
|
|
12552
|
+
view.rejectInitial(error);
|
|
12553
|
+
view.controller.abort();
|
|
12554
|
+
return this.#emit(connection, view, "health", { healthy: false, reason });
|
|
12555
|
+
});
|
|
12556
|
+
if (!writes.length) {
|
|
12557
|
+
response.write(`event: resource-service-health
|
|
12558
|
+
data: ${JSON.stringify({
|
|
12559
|
+
protocolVersion: 1,
|
|
12560
|
+
connectionId: id,
|
|
12561
|
+
producerGeneration: this.producerGeneration,
|
|
12562
|
+
healthy: false,
|
|
12563
|
+
reason
|
|
12564
|
+
})}
|
|
12565
|
+
|
|
12566
|
+
`);
|
|
12567
|
+
close();
|
|
12568
|
+
} else void Promise.allSettled(writes).then(close);
|
|
12569
|
+
}
|
|
12570
|
+
});
|
|
12571
|
+
connection = { id, controller, output, views: /* @__PURE__ */ new Map(), epochs: /* @__PURE__ */ new Map(), observer, localRevision: 0, projectionTail: Promise.resolve(), close };
|
|
12572
|
+
this.#connections.set(id, connection);
|
|
12573
|
+
response.once("close", close);
|
|
12574
|
+
subscribeHumanProfile(this.deps.stateDir, this.deps.identityCid, () => {
|
|
12575
|
+
if (!connection || controller.signal.aborted) return;
|
|
12576
|
+
connection.localRevision++;
|
|
12577
|
+
for (const view of connection.views.values()) if (view.descriptor.resource === "identity") this.#schedule(connection, view);
|
|
12578
|
+
}, controller.signal);
|
|
12579
|
+
response.write(`event: resource-connection
|
|
12580
|
+
data: ${JSON.stringify({
|
|
12581
|
+
protocolVersion: 1,
|
|
12582
|
+
connectionId: id,
|
|
12583
|
+
producerGeneration: this.producerGeneration,
|
|
12584
|
+
identityCid: this.deps.identityCid,
|
|
12585
|
+
baselineRequired: true,
|
|
12586
|
+
continuity: "reset"
|
|
12587
|
+
})}
|
|
12588
|
+
|
|
12589
|
+
`);
|
|
12590
|
+
return { connectionId: id, close, closed };
|
|
12591
|
+
}
|
|
12592
|
+
async register(connectionId, viewId, epoch, input, signal) {
|
|
12593
|
+
const connection = this.#get(connectionId);
|
|
12594
|
+
let descriptor;
|
|
12595
|
+
try {
|
|
12596
|
+
descriptor = canonicalResourceDescriptor(input);
|
|
12597
|
+
} catch {
|
|
12598
|
+
throw new ResourceBindingError(400, "invalid resource descriptor");
|
|
12599
|
+
}
|
|
12600
|
+
if (descriptor.viewId !== viewId || !Number.isSafeInteger(epoch) || epoch < 1) throw new ResourceBindingError(400, "invalid subscription epoch");
|
|
12601
|
+
const priorEpoch = connection.epochs.get(viewId);
|
|
12602
|
+
if (priorEpoch !== void 0 && epoch <= priorEpoch) throw new ResourceBindingError(409, "obsolete subscription epoch");
|
|
12603
|
+
if (!connection.epochs.has(viewId) && connection.epochs.size >= 256) throw new ResourceBindingError(503, "resource epoch capacity exceeded");
|
|
12604
|
+
const lifetime = signal ? AbortSignal.any([signal, connection.controller.signal]) : connection.controller.signal;
|
|
12605
|
+
await abortableProjection(connection.observer.ready, lifetime);
|
|
12606
|
+
lifetime.throwIfAborted();
|
|
12607
|
+
if (connection.controller.signal.aborted || !connection.observer.healthy) throw new ResourceBindingError(503, "resource source unavailable");
|
|
12608
|
+
const current = connection.views.get(viewId);
|
|
12609
|
+
if ((connection.epochs.get(viewId) ?? 0) >= epoch) throw new ResourceBindingError(409, "obsolete subscription epoch");
|
|
12610
|
+
if (!connection.epochs.has(viewId) && connection.epochs.size >= 256) throw new ResourceBindingError(503, "resource epoch capacity exceeded");
|
|
12611
|
+
if (current) this.#retire(current);
|
|
12612
|
+
let resolveInitial, rejectInitial;
|
|
12613
|
+
const initial = new Promise((resolve4, reject) => {
|
|
12614
|
+
resolveInitial = resolve4;
|
|
12615
|
+
rejectInitial = reject;
|
|
12616
|
+
});
|
|
12617
|
+
void initial.catch(() => {
|
|
12618
|
+
});
|
|
12619
|
+
const view = {
|
|
12620
|
+
descriptor,
|
|
12621
|
+
epoch,
|
|
12622
|
+
baselineId: randomUUID2(),
|
|
12623
|
+
controller: new AbortController(),
|
|
12624
|
+
revision: 0,
|
|
12625
|
+
sequence: 0,
|
|
12626
|
+
dirty: false,
|
|
12627
|
+
running: false,
|
|
12628
|
+
failed: false,
|
|
12629
|
+
initial,
|
|
12630
|
+
resolveInitial,
|
|
12631
|
+
rejectInitial,
|
|
12632
|
+
localRevision: -1
|
|
12026
12633
|
};
|
|
12634
|
+
connection.views.set(viewId, view);
|
|
12635
|
+
connection.epochs.set(viewId, epoch);
|
|
12636
|
+
this.#schedule(connection, view);
|
|
12637
|
+
return { subscriptionEpoch: epoch, baselineId: view.baselineId };
|
|
12638
|
+
}
|
|
12639
|
+
remove(connectionId, viewId, epoch) {
|
|
12640
|
+
if (typeof viewId !== "string" || !/^[A-Za-z0-9_-]{1,128}$/.test(viewId) || !Number.isSafeInteger(epoch) || epoch < 1) throw new ResourceBindingError(400, "invalid subscription epoch");
|
|
12641
|
+
const connection = this.#connections.get(connectionId);
|
|
12642
|
+
if (!connection) return;
|
|
12643
|
+
if (!connection.epochs.has(viewId) && connection.epochs.size >= 256) throw new ResourceBindingError(503, "resource epoch capacity exceeded");
|
|
12644
|
+
connection.epochs.set(viewId, Math.max(connection.epochs.get(viewId) ?? 0, epoch));
|
|
12645
|
+
const view = connection.views.get(viewId);
|
|
12646
|
+
if (view && epoch >= view.epoch) {
|
|
12647
|
+
this.#retire(view);
|
|
12648
|
+
connection.views.delete(viewId);
|
|
12649
|
+
}
|
|
12650
|
+
}
|
|
12651
|
+
async bound(connectionId, viewId, epoch, baselineId) {
|
|
12652
|
+
const connection = this.#get(connectionId), view = connection.views.get(viewId);
|
|
12653
|
+
if (!view || view.epoch !== epoch || view.baselineId !== baselineId) throw new ResourceBindingError(409, "resource binding mismatch");
|
|
12654
|
+
const baseline = await view.initial;
|
|
12655
|
+
if (!this.#current(connection, view) || view.failed || !connection.observer.healthy) throw new ResourceBindingError(409, "resource binding retired");
|
|
12656
|
+
return baseline;
|
|
12657
|
+
}
|
|
12658
|
+
#get(id) {
|
|
12659
|
+
const connection = this.#connections.get(id);
|
|
12660
|
+
if (!connection) throw new ResourceBindingError(409, "unknown resource connection");
|
|
12661
|
+
return connection;
|
|
12662
|
+
}
|
|
12663
|
+
#current(connection, view) {
|
|
12664
|
+
return !connection.controller.signal.aborted && !view.controller.signal.aborted && connection.views.get(view.descriptor.viewId) === view;
|
|
12665
|
+
}
|
|
12666
|
+
#retire(view) {
|
|
12667
|
+
view.controller.abort();
|
|
12668
|
+
view.rejectInitial(new ResourceBindingError(409, "resource binding retired"));
|
|
12669
|
+
}
|
|
12670
|
+
#emit(connection, view, kind, payload) {
|
|
12671
|
+
return connection.output.send({
|
|
12672
|
+
protocolVersion: 1,
|
|
12673
|
+
producerGeneration: this.producerGeneration,
|
|
12674
|
+
viewId: view.descriptor.viewId,
|
|
12675
|
+
subscriptionEpoch: view.epoch,
|
|
12676
|
+
sequence: ++view.sequence,
|
|
12677
|
+
revision: view.revision,
|
|
12678
|
+
baselineId: view.baselineId,
|
|
12679
|
+
kind,
|
|
12680
|
+
payload
|
|
12681
|
+
});
|
|
12027
12682
|
}
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
if (
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12683
|
+
#schedule(connection, view) {
|
|
12684
|
+
if (!this.#current(connection, view) || view.failed) return;
|
|
12685
|
+
view.dirty = true;
|
|
12686
|
+
if (view.running) return;
|
|
12687
|
+
view.running = true;
|
|
12688
|
+
const task = connection.projectionTail.then(() => this.#refresh(connection, view));
|
|
12689
|
+
connection.projectionTail = task.catch(() => {
|
|
12690
|
+
});
|
|
12691
|
+
void task.finally(() => {
|
|
12692
|
+
view.running = false;
|
|
12693
|
+
if (view.dirty) this.#schedule(connection, view);
|
|
12694
|
+
}).catch(connection.close);
|
|
12695
|
+
}
|
|
12696
|
+
async #refresh(connection, view) {
|
|
12697
|
+
try {
|
|
12698
|
+
if (view.dirty && this.#current(connection, view)) {
|
|
12699
|
+
view.dirty = false;
|
|
12700
|
+
const localRevision = connection.localRevision;
|
|
12701
|
+
const captured = await captureResourceProjection(this.deps.client, this.deps.identity, async () => {
|
|
12702
|
+
const payload = await this.deps.project(view.descriptor, view.controller.signal);
|
|
12703
|
+
const delta = view.descriptor.resource === "messages" && view.payload !== void 0 ? await messageProjectionDelta(
|
|
12704
|
+
this.deps.client,
|
|
12705
|
+
view.payload,
|
|
12706
|
+
payload,
|
|
12707
|
+
view.controller.signal
|
|
12708
|
+
) : void 0;
|
|
12709
|
+
return { payload, delta };
|
|
12710
|
+
}, view.controller.signal, () => connection.localRevision);
|
|
12711
|
+
if (!this.#current(connection, view)) return;
|
|
12712
|
+
if (!connection.observer.healthy || captured.source.producerGeneration !== connection.observer.generation) {
|
|
12713
|
+
throw new Error("resource source continuity lost");
|
|
12714
|
+
}
|
|
12715
|
+
const first = view.payload === void 0;
|
|
12716
|
+
const changed = first || JSON.stringify(captured.payload.payload) !== JSON.stringify(view.payload);
|
|
12717
|
+
view.covered = captured.source;
|
|
12718
|
+
view.localRevision = localRevision;
|
|
12719
|
+
if (changed) {
|
|
12720
|
+
view.revision++;
|
|
12721
|
+
if (first || view.descriptor.resource !== "messages") {
|
|
12722
|
+
await this.#emit(connection, view, "snapshot", captured.payload.payload);
|
|
12723
|
+
} else {
|
|
12724
|
+
await this.#emit(connection, view, "upsert", captured.payload.delta);
|
|
12725
|
+
}
|
|
12726
|
+
if (!this.#current(connection, view)) return;
|
|
12727
|
+
view.payload = captured.payload.payload;
|
|
12728
|
+
}
|
|
12729
|
+
if (first) {
|
|
12730
|
+
await this.#emit(connection, view, "ready", { baselineId: view.baselineId, source: captured.source });
|
|
12731
|
+
if (!this.#current(connection, view)) return;
|
|
12732
|
+
view.resolveInitial({
|
|
12733
|
+
payload: view.payload,
|
|
12734
|
+
source: captured.source,
|
|
12735
|
+
producerGeneration: this.producerGeneration,
|
|
12736
|
+
revision: view.revision,
|
|
12737
|
+
baselineId: view.baselineId,
|
|
12738
|
+
descriptor: view.descriptor
|
|
12739
|
+
});
|
|
12740
|
+
} else {
|
|
12741
|
+
await this.#emit(connection, view, "coverage", { source: captured.source });
|
|
12742
|
+
}
|
|
12042
12743
|
}
|
|
12043
|
-
|
|
12744
|
+
} catch (error) {
|
|
12745
|
+
if (!this.#current(connection, view)) return;
|
|
12746
|
+
view.failed = true;
|
|
12747
|
+
const failure = error instanceof Error ? error : new Error("resource projection failed");
|
|
12748
|
+
view.rejectInitial(failure);
|
|
12749
|
+
await this.#emit(connection, view, "resync", { reason: /limit/.test(failure.message) ? "capacity" : "projection_unavailable" }).catch(connection.close);
|
|
12044
12750
|
}
|
|
12045
12751
|
}
|
|
12046
|
-
close() {
|
|
12047
|
-
for (const sub of [...this.#subscribers]) this.#close(sub);
|
|
12048
|
-
}
|
|
12049
|
-
#close(sub) {
|
|
12050
|
-
if (sub.closed) return;
|
|
12051
|
-
sub.closed = true;
|
|
12052
|
-
sub.queue.length = 0;
|
|
12053
|
-
this.#subscribers.delete(sub);
|
|
12054
|
-
const resolve3 = sub.waiting;
|
|
12055
|
-
sub.waiting = null;
|
|
12056
|
-
resolve3?.(null);
|
|
12057
|
-
}
|
|
12058
12752
|
};
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12065
|
-
}
|
|
12066
|
-
const { type, ...metadata } = event;
|
|
12067
|
-
return { event: type, data: { v: 1, ...metadata } };
|
|
12753
|
+
|
|
12754
|
+
// src/media-response.ts
|
|
12755
|
+
init_define_MESSENGER_BUILD_INFO();
|
|
12756
|
+
var INLINE_MEDIA = /^(?:image\/(?:avif|gif|jpeg|png|webp)|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+)$/;
|
|
12757
|
+
function mediaResponsePolicy(mime2) {
|
|
12758
|
+
const declared = mime2.toLowerCase().split(";", 1)[0].trim();
|
|
12759
|
+
return INLINE_MEDIA.test(declared) ? { mime: declared, disposition: "inline" } : { mime: "application/octet-stream", disposition: "attachment" };
|
|
12068
12760
|
}
|
|
12069
12761
|
|
|
12070
12762
|
// src/command-invocations.ts
|
|
12071
12763
|
init_define_MESSENGER_BUILD_INFO();
|
|
12072
|
-
import { createHash as
|
|
12764
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
12073
12765
|
import { chmodSync, mkdirSync as mkdirSync3, readFileSync as readFileSync3, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
12074
12766
|
import { dirname as dirname2, join as join3 } from "node:path";
|
|
12075
12767
|
var MAX_INVOCATIONS = 4096;
|
|
@@ -12083,7 +12775,7 @@ function canonical2(value) {
|
|
|
12083
12775
|
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonical2(value[key])}`).join(",")}}`;
|
|
12084
12776
|
}
|
|
12085
12777
|
function invocationFingerprint(input) {
|
|
12086
|
-
return
|
|
12778
|
+
return createHash3("sha256").update(canonical2(input)).digest("base64url");
|
|
12087
12779
|
}
|
|
12088
12780
|
function validRecord(value) {
|
|
12089
12781
|
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
@@ -12098,7 +12790,7 @@ var CommandInvocationStore = class _CommandInvocationStore {
|
|
|
12098
12790
|
}
|
|
12099
12791
|
static open(stateDir, identityCid, capacity = MAX_INVOCATIONS) {
|
|
12100
12792
|
if (!Number.isInteger(capacity) || capacity < 1) throw new Error("invocation capacity must be a positive integer");
|
|
12101
|
-
const file = join3(stateDir, `typed-commands-${
|
|
12793
|
+
const file = join3(stateDir, `typed-commands-${createHash3("sha256").update(identityCid).digest("hex").slice(0, 24)}.json`);
|
|
12102
12794
|
let state = { version: 1, records: {} };
|
|
12103
12795
|
try {
|
|
12104
12796
|
const parsed = JSON.parse(readFileSync3(file, "utf8"));
|
|
@@ -20277,20 +20969,20 @@ init_define_MESSENGER_BUILD_INFO();
|
|
|
20277
20969
|
function getEscape(char) {
|
|
20278
20970
|
return char === 34 ? """ : char === 38 ? "&" : char === 39 ? "'" : char === 60 ? "<" : char === 62 ? ">" : " ";
|
|
20279
20971
|
}
|
|
20280
|
-
function escapeWithRegex(
|
|
20281
|
-
|
|
20282
|
-
if (!
|
|
20972
|
+
function escapeWithRegex(re, data) {
|
|
20973
|
+
re.lastIndex = 0;
|
|
20974
|
+
if (!re.test(data))
|
|
20283
20975
|
return data;
|
|
20284
20976
|
let out = "";
|
|
20285
20977
|
let last = 0;
|
|
20286
20978
|
do {
|
|
20287
|
-
const index =
|
|
20979
|
+
const index = re.lastIndex - 1;
|
|
20288
20980
|
if (last !== index)
|
|
20289
20981
|
out += data.substring(last, index);
|
|
20290
20982
|
const char = data.charCodeAt(index);
|
|
20291
20983
|
out += getEscape(char);
|
|
20292
20984
|
last = index + 1;
|
|
20293
|
-
} while (
|
|
20985
|
+
} while (re.test(data));
|
|
20294
20986
|
return out + data.substring(last);
|
|
20295
20987
|
}
|
|
20296
20988
|
var attributeEscapeRegex = /["&\u{A0}]/gu;
|
|
@@ -20546,6 +21238,21 @@ var HTML_PREVIEW_RESPONSE_CSP = `${HTML_PREVIEW_CSP}; sandbox; frame-ancestors '
|
|
|
20546
21238
|
var MAX_HTTP_BODY_BYTES = 32 * 1024 * 1024;
|
|
20547
21239
|
var MAX_INLINE_FILE_BYTES = 20 * 1024 * 1024;
|
|
20548
21240
|
var MAX_PUSH_BODY_BYTES = 16 * 1024;
|
|
21241
|
+
var resourceConnections = /* @__PURE__ */ new WeakMap();
|
|
21242
|
+
function resourceService(deps) {
|
|
21243
|
+
let service = resourceConnections.get(deps);
|
|
21244
|
+
if (!service) {
|
|
21245
|
+
service = new ResourceConnections({
|
|
21246
|
+
client: deps.runtime.client,
|
|
21247
|
+
identity: deps.config.identity,
|
|
21248
|
+
identityCid: deps.identityCid,
|
|
21249
|
+
stateDir: deps.config.stateDir,
|
|
21250
|
+
project: (descriptor, signal) => projectResourceView(deps, descriptor, signal)
|
|
21251
|
+
});
|
|
21252
|
+
resourceConnections.set(deps, service);
|
|
21253
|
+
}
|
|
21254
|
+
return service;
|
|
21255
|
+
}
|
|
20549
21256
|
var invocationStores = /* @__PURE__ */ new WeakMap();
|
|
20550
21257
|
function invocationStore(deps) {
|
|
20551
21258
|
if (deps.commandInvocations) return deps.commandInvocations;
|
|
@@ -20562,23 +21269,23 @@ var HttpError = class extends Error {
|
|
|
20562
21269
|
this.status = status;
|
|
20563
21270
|
}
|
|
20564
21271
|
};
|
|
20565
|
-
var bad = (
|
|
21272
|
+
var bad = (m3) => new HttpError(400, m3);
|
|
20566
21273
|
function str(body, key) {
|
|
20567
|
-
const
|
|
20568
|
-
if (typeof
|
|
20569
|
-
return
|
|
21274
|
+
const v3 = body[key];
|
|
21275
|
+
if (typeof v3 !== "string" || v3 === "") throw bad(`${key} must be a non-empty string`);
|
|
21276
|
+
return v3;
|
|
20570
21277
|
}
|
|
20571
21278
|
function optStr(body, key) {
|
|
20572
|
-
const
|
|
20573
|
-
if (
|
|
20574
|
-
if (typeof
|
|
20575
|
-
return
|
|
21279
|
+
const v3 = body[key];
|
|
21280
|
+
if (v3 === void 0 || v3 === null) return void 0;
|
|
21281
|
+
if (typeof v3 !== "string" || v3 === "") throw bad(`${key}, when present, must be a non-empty string`);
|
|
21282
|
+
return v3;
|
|
20576
21283
|
}
|
|
20577
21284
|
function optBool(body, key) {
|
|
20578
|
-
const
|
|
20579
|
-
if (
|
|
20580
|
-
if (typeof
|
|
20581
|
-
return
|
|
21285
|
+
const v3 = body[key];
|
|
21286
|
+
if (v3 === void 0 || v3 === null) return void 0;
|
|
21287
|
+
if (typeof v3 !== "boolean") throw bad(`${key}, when present, must be a boolean`);
|
|
21288
|
+
return v3;
|
|
20582
21289
|
}
|
|
20583
21290
|
function filename(body) {
|
|
20584
21291
|
const value = str(body, "filename").normalize("NFC");
|
|
@@ -20772,11 +21479,19 @@ function beforeSequence(raw) {
|
|
|
20772
21479
|
}
|
|
20773
21480
|
return value;
|
|
20774
21481
|
}
|
|
20775
|
-
async function listAllFiles(client, peerCid) {
|
|
21482
|
+
async function listAllFiles(client, peerCid, signal, identity) {
|
|
20776
21483
|
const files = [];
|
|
21484
|
+
let bytes = 0;
|
|
20777
21485
|
let before;
|
|
20778
21486
|
for (; ; ) {
|
|
21487
|
+
signal?.throwIfAborted();
|
|
20779
21488
|
const page = await client.listFiles({ peer_cid: peerCid, before_seq: before, limit: 200 });
|
|
21489
|
+
signal?.throwIfAborted();
|
|
21490
|
+
if (signal) {
|
|
21491
|
+
bytes += Buffer.byteLength(JSON.stringify(page.items.map((row) => publicMediaRecord(row, identity, 1))));
|
|
21492
|
+
if (bytes > RESOURCE_ASSEMBLY_BYTES) throw new Error("resource assembly limit exceeded");
|
|
21493
|
+
if (page.next_cursor !== null && (!page.items.length || !Number.isSafeInteger(page.next_cursor) || before !== void 0 && page.next_cursor >= before)) throw new Error("invalid file continuation");
|
|
21494
|
+
}
|
|
20780
21495
|
files.push(...page.items);
|
|
20781
21496
|
if (page.next_cursor === null) return files;
|
|
20782
21497
|
before = page.next_cursor;
|
|
@@ -20844,8 +21559,8 @@ async function serveEvents(req, res, deps) {
|
|
|
20844
21559
|
};
|
|
20845
21560
|
const waitForDrain = () => {
|
|
20846
21561
|
if (drainWait) return drainWait;
|
|
20847
|
-
drainWait = new Promise((
|
|
20848
|
-
releaseDrain =
|
|
21562
|
+
drainWait = new Promise((resolve4) => {
|
|
21563
|
+
releaseDrain = resolve4;
|
|
20849
21564
|
});
|
|
20850
21565
|
res.once("drain", onDrain);
|
|
20851
21566
|
return drainWait;
|
|
@@ -20887,12 +21602,118 @@ async function serveEvents(req, res, deps) {
|
|
|
20887
21602
|
if (!res.destroyed && !res.writableEnded) res.end();
|
|
20888
21603
|
}
|
|
20889
21604
|
}
|
|
21605
|
+
async function projectIdentityResource(client, deps) {
|
|
21606
|
+
return { ...publicIdentity(await client.currentIdentity()), humanProfile: readHumanProfile(deps.config.stateDir, deps.identityCid) };
|
|
21607
|
+
}
|
|
21608
|
+
async function projectCommandResource(client, deps, params) {
|
|
21609
|
+
if (deps.config.typedCommands === false) throw new HttpError(404, "Typed commands are disabled");
|
|
21610
|
+
const peer = await resolveContact(client, params.contact);
|
|
21611
|
+
return projectCatalog(peer.cid, await client.listContactCommands({ contact: peer.cid }));
|
|
21612
|
+
}
|
|
21613
|
+
async function projectFilesResource(client, deps, params, signal) {
|
|
21614
|
+
const peer = await resolveContact(client, params.contact);
|
|
21615
|
+
const files = (await listAllFiles(client, peer.cid, signal, { cid: deps.identityCid, name: deps.config.identity })).reverse();
|
|
21616
|
+
const versions = /* @__PURE__ */ new Map();
|
|
21617
|
+
return {
|
|
21618
|
+
contact: params.contact,
|
|
21619
|
+
files: files.map((row) => {
|
|
21620
|
+
const logicalName = row.filename.normalize("NFC").toLocaleLowerCase("en-US");
|
|
21621
|
+
const version = (versions.get(logicalName) ?? 0) + 1;
|
|
21622
|
+
versions.set(logicalName, version);
|
|
21623
|
+
return publicMediaRecord(row, {
|
|
21624
|
+
cid: deps.identityCid,
|
|
21625
|
+
name: deps.config.identity
|
|
21626
|
+
}, version);
|
|
21627
|
+
})
|
|
21628
|
+
};
|
|
21629
|
+
}
|
|
21630
|
+
async function projectResourceView(deps, input, signal) {
|
|
21631
|
+
const descriptor = canonicalResourceDescriptor(input), client = deps.runtime.client;
|
|
21632
|
+
signal.throwIfAborted();
|
|
21633
|
+
switch (descriptor.resource) {
|
|
21634
|
+
case "contacts":
|
|
21635
|
+
return presentContacts(await client.listContacts());
|
|
21636
|
+
case "identity":
|
|
21637
|
+
return projectIdentityResource(client, deps);
|
|
21638
|
+
case "files":
|
|
21639
|
+
return projectFilesResource(client, deps, { contact: descriptor.entityId }, signal);
|
|
21640
|
+
case "commands":
|
|
21641
|
+
return projectCommandResource(client, deps, { contact: descriptor.entityId });
|
|
21642
|
+
case "messages": {
|
|
21643
|
+
const peer = await resolveContact(client, descriptor.entityId);
|
|
21644
|
+
const page = await projectMessageWindow(client, peer.cid, peer.announcedName, descriptor.window, signal);
|
|
21645
|
+
return { ...page, contact: descriptor.entityId };
|
|
21646
|
+
}
|
|
21647
|
+
}
|
|
21648
|
+
}
|
|
20890
21649
|
var ROUTES = {
|
|
20891
21650
|
// ---- live metadata invalidations (canonical state remains REST/MUFL) ------
|
|
20892
|
-
"GET /api/events": async ({ req, res, deps }) => {
|
|
21651
|
+
"GET /api/events": async ({ req, res, deps, query }) => {
|
|
21652
|
+
if (query.get("resources") === "1") {
|
|
21653
|
+
res.writeHead(200, {
|
|
21654
|
+
"content-type": "text/event-stream",
|
|
21655
|
+
"cache-control": "no-cache, no-transform",
|
|
21656
|
+
connection: "keep-alive",
|
|
21657
|
+
"x-accel-buffering": "no"
|
|
21658
|
+
});
|
|
21659
|
+
res.flushHeaders?.();
|
|
21660
|
+
const connection = resourceService(deps).open(res);
|
|
21661
|
+
const close = () => connection.close();
|
|
21662
|
+
req.once("close", close);
|
|
21663
|
+
try {
|
|
21664
|
+
await connection.closed;
|
|
21665
|
+
} finally {
|
|
21666
|
+
req.removeListener("close", close);
|
|
21667
|
+
connection.close();
|
|
21668
|
+
}
|
|
21669
|
+
return void 0;
|
|
21670
|
+
}
|
|
20893
21671
|
await serveEvents(req, res, deps);
|
|
20894
21672
|
return void 0;
|
|
20895
21673
|
},
|
|
21674
|
+
"POST /api/resource-subscriptions": async ({ req, res, deps, body }) => {
|
|
21675
|
+
const connectionId = str(body, "connectionId"), viewId = str(body, "viewId");
|
|
21676
|
+
const epoch = body.subscriptionEpoch;
|
|
21677
|
+
if (deps.config.typedCommands === false && body.descriptor?.resource === "commands") {
|
|
21678
|
+
throw new HttpError(404, "Typed commands are disabled");
|
|
21679
|
+
}
|
|
21680
|
+
const controller = new AbortController();
|
|
21681
|
+
let installed = false;
|
|
21682
|
+
const cleanup = () => {
|
|
21683
|
+
req.removeListener("aborted", abort);
|
|
21684
|
+
res.removeListener("close", responseClosed);
|
|
21685
|
+
res.removeListener("finish", cleanup);
|
|
21686
|
+
};
|
|
21687
|
+
const abort = () => {
|
|
21688
|
+
controller.abort();
|
|
21689
|
+
if (installed) resourceService(deps).remove(connectionId, viewId, epoch);
|
|
21690
|
+
cleanup();
|
|
21691
|
+
};
|
|
21692
|
+
req.once("aborted", abort);
|
|
21693
|
+
const responseClosed = () => {
|
|
21694
|
+
if (!res.writableFinished) abort();
|
|
21695
|
+
};
|
|
21696
|
+
res.once("close", responseClosed);
|
|
21697
|
+
res.once("finish", cleanup);
|
|
21698
|
+
try {
|
|
21699
|
+
const registered = await resourceService(deps).register(connectionId, viewId, epoch, body.descriptor, controller.signal);
|
|
21700
|
+
installed = true;
|
|
21701
|
+
if (req.aborted || res.destroyed) {
|
|
21702
|
+
abort();
|
|
21703
|
+
return void 0;
|
|
21704
|
+
}
|
|
21705
|
+
return registered;
|
|
21706
|
+
} catch (error) {
|
|
21707
|
+
if (controller.signal.aborted) return void 0;
|
|
21708
|
+
throw error;
|
|
21709
|
+
} finally {
|
|
21710
|
+
if (controller.signal.aborted || res.writableFinished || res.destroyed) cleanup();
|
|
21711
|
+
}
|
|
21712
|
+
},
|
|
21713
|
+
"DELETE /api/resource-subscriptions": async ({ deps, body }) => {
|
|
21714
|
+
resourceService(deps).remove(str(body, "connectionId"), str(body, "viewId"), body.subscriptionEpoch);
|
|
21715
|
+
return { removed: true };
|
|
21716
|
+
},
|
|
20896
21717
|
// ---- messaging -----------------------------------------------------------
|
|
20897
21718
|
"POST /api/messages/send": async ({ client, body }) => {
|
|
20898
21719
|
const reply = replyReference(body);
|
|
@@ -20909,11 +21730,7 @@ var ROUTES = {
|
|
|
20909
21730
|
}
|
|
20910
21731
|
return { wire_id: wireId, delivery: "tracked" };
|
|
20911
21732
|
},
|
|
20912
|
-
"GET /api/contacts/:contact/commands": async ({ client, deps, params }) =>
|
|
20913
|
-
if (deps.config.typedCommands === false) throw new HttpError(404, "Typed commands are disabled");
|
|
20914
|
-
const peer = await resolveContact(client, params.contact);
|
|
20915
|
-
return projectCatalog(peer.cid, await client.listContactCommands({ contact: peer.cid }));
|
|
20916
|
-
},
|
|
21733
|
+
"GET /api/contacts/:contact/commands": async ({ client, deps, params }) => projectCommandResource(client, deps, params),
|
|
20917
21734
|
"POST /api/commands/send": async ({ client, deps, body }) => {
|
|
20918
21735
|
if (deps.config.typedCommands === false) throw new HttpError(404, "Typed commands are disabled");
|
|
20919
21736
|
const peer = await resolveContact(client, str(body, "contact"));
|
|
@@ -21106,7 +21923,7 @@ var ROUTES = {
|
|
|
21106
21923
|
// ---- identity / profile --------------------------------------------------
|
|
21107
21924
|
// The old browser surface called the read half `getProfileName`; the name is a
|
|
21108
21925
|
// field on this result.
|
|
21109
|
-
"GET /api/identity": async ({ client, deps }) => (
|
|
21926
|
+
"GET /api/identity": async ({ client, deps }) => projectIdentityResource(client, deps),
|
|
21110
21927
|
"POST /api/identity/profile": async ({ client, deps, body }) => {
|
|
21111
21928
|
if (!humanIdentity(await client.currentIdentity())) throw bad("Human profile requires the Human root or a permanent identity under it");
|
|
21112
21929
|
let profile;
|
|
@@ -21157,7 +21974,7 @@ var ROUTES = {
|
|
|
21157
21974
|
const serverCid = str(body, "serverCid").toUpperCase();
|
|
21158
21975
|
if (!/^[A-F0-9]{64}$/.test(serverCid) || !/^[A-Za-z0-9_-]{43}$/.test(str(body, "hostWorkspaceId"))) throw bad("Invalid workspace proof");
|
|
21159
21976
|
const challenge = body.challenge;
|
|
21160
|
-
if (!challenge || !["nonce", "workspaceId", "accountId"].every((
|
|
21977
|
+
if (!challenge || !["nonce", "workspaceId", "accountId"].every((k) => typeof challenge[k] === "string" && /^[A-Za-z0-9_-]{43}$/.test(String(challenge[k]))) || !Number.isFinite(challenge.expiresAt) || Number(challenge.expiresAt) <= Date.now() || Number(challenge.expiresAt) > Date.now() + 16 * 6e4) throw bad("Workspace challenge expired or invalid");
|
|
21161
21978
|
const preserveProfile = optBool(body, "preserveProfile") === true;
|
|
21162
21979
|
let humanProfile;
|
|
21163
21980
|
if (!preserveProfile) try {
|
|
@@ -21176,7 +21993,7 @@ var ROUTES = {
|
|
|
21176
21993
|
const contactDeadline = Date.now() + 1e4;
|
|
21177
21994
|
while (!(await client.listContacts()).contacts.some((contact) => contact.container_id.toUpperCase() === serverCid)) {
|
|
21178
21995
|
if (Date.now() >= contactDeadline) throw bad("Enrollment contact is not ready; obtain a fresh setup payload before retrying");
|
|
21179
|
-
await new Promise((
|
|
21996
|
+
await new Promise((resolve4) => setTimeout(resolve4, 100));
|
|
21180
21997
|
}
|
|
21181
21998
|
const argumentsValue = { type: "ours.app.bind-workspace.v1", accountId: String(challenge.accountId), workspaceId: String(challenge.workspaceId), nonce: String(challenge.nonce), hostWorkspaceId: String(body.hostWorkspaceId) };
|
|
21182
21999
|
const outcome = await client.sendCommand({ contact: serverCid, command: "bind-workspace", arguments: argumentsValue });
|
|
@@ -21197,27 +22014,11 @@ var ROUTES = {
|
|
|
21197
22014
|
},
|
|
21198
22015
|
// ---- files ---------------------------------------------------------------
|
|
21199
22016
|
"GET /api/files/incoming": async ({ client }) => client.listIncomingFiles(),
|
|
21200
|
-
"GET /api/conversations/:contact/files": async ({ client, deps, params }) =>
|
|
21201
|
-
const peer = await resolveContact(client, params.contact);
|
|
21202
|
-
const files = (await listAllFiles(client, peer.cid)).reverse();
|
|
21203
|
-
const versions = /* @__PURE__ */ new Map();
|
|
21204
|
-
return {
|
|
21205
|
-
contact: params.contact,
|
|
21206
|
-
files: files.map((row) => {
|
|
21207
|
-
const logicalName = row.filename.normalize("NFC").toLocaleLowerCase("en-US");
|
|
21208
|
-
const version = (versions.get(logicalName) ?? 0) + 1;
|
|
21209
|
-
versions.set(logicalName, version);
|
|
21210
|
-
return publicMediaRecord(row, {
|
|
21211
|
-
cid: deps.identityCid,
|
|
21212
|
-
name: deps.config.identity
|
|
21213
|
-
}, version);
|
|
21214
|
-
})
|
|
21215
|
-
};
|
|
21216
|
-
},
|
|
22017
|
+
"GET /api/conversations/:contact/files": async ({ client, deps, params }) => projectFilesResource(client, deps, params),
|
|
21217
22018
|
"POST /api/files/fetch": async ({ client, body }) => {
|
|
21218
22019
|
const ids = body.wire_ids;
|
|
21219
22020
|
if (ids === void 0 || ids === null) throw bad("wire_ids is required for browser file retrieval");
|
|
21220
|
-
if (!Array.isArray(ids) || !ids.every((
|
|
22021
|
+
if (!Array.isArray(ids) || !ids.every((v3) => typeof v3 === "string" && v3 !== "")) {
|
|
21221
22022
|
throw bad("wire_ids, when present, must be an array of non-empty strings");
|
|
21222
22023
|
}
|
|
21223
22024
|
const requested = ids;
|
|
@@ -21316,15 +22117,15 @@ var ROUTES = {
|
|
|
21316
22117
|
if (keys === null || typeof keys !== "object" || Array.isArray(keys)) {
|
|
21317
22118
|
throw bad("keys must be an object with p256dh and auth");
|
|
21318
22119
|
}
|
|
21319
|
-
const
|
|
21320
|
-
if (typeof
|
|
22120
|
+
const k = keys;
|
|
22121
|
+
if (typeof k.p256dh !== "string" || typeof k.auth !== "string") {
|
|
21321
22122
|
throw bad("keys.p256dh and keys.auth must be strings");
|
|
21322
22123
|
}
|
|
21323
22124
|
let saved;
|
|
21324
22125
|
try {
|
|
21325
22126
|
saved = deps.push.ensure({
|
|
21326
22127
|
endpoint: str(body, "endpoint"),
|
|
21327
|
-
keys: { p256dh:
|
|
22128
|
+
keys: { p256dh: k.p256dh, auth: k.auth },
|
|
21328
22129
|
label: optStr(body, "label"),
|
|
21329
22130
|
preview: body.preview === void 0 ? void 0 : str(body, "preview"),
|
|
21330
22131
|
bindingId: optStr(body, "binding_id")
|
|
@@ -21396,8 +22197,8 @@ var ROUTES = {
|
|
|
21396
22197
|
function match(method, pathname) {
|
|
21397
22198
|
const parts = pathname.split("/").filter(Boolean);
|
|
21398
22199
|
for (const key of Object.keys(ROUTES)) {
|
|
21399
|
-
const [
|
|
21400
|
-
if (
|
|
22200
|
+
const [m3, pattern] = key.split(" ");
|
|
22201
|
+
if (m3 !== method) continue;
|
|
21401
22202
|
const pp = pattern.split("/").filter(Boolean);
|
|
21402
22203
|
if (pp.length !== parts.length) continue;
|
|
21403
22204
|
const params = {};
|
|
@@ -21428,6 +22229,27 @@ async function serveApi(req, res, deps) {
|
|
|
21428
22229
|
req,
|
|
21429
22230
|
url.pathname.startsWith("/api/push/") ? MAX_PUSH_BODY_BYTES : MAX_HTTP_BODY_BYTES
|
|
21430
22231
|
);
|
|
22232
|
+
const resourceHeaderNames = ["x-resource-connection", "x-resource-view", "x-resource-epoch", "x-resource-baseline"];
|
|
22233
|
+
const resourceHeaders = resourceHeaderNames.map((name) => rawHeaderValues(req, name));
|
|
22234
|
+
if (resourceHeaders.some((values) => values.length > 0)) {
|
|
22235
|
+
if (method !== "GET" || resourceHeaders.some((values) => values.length !== 1)) throw new ResourceBindingError(409, "incomplete resource binding");
|
|
22236
|
+
const [connectionId, viewId, epoch, baselineId] = resourceHeaders.map((values) => values[0]);
|
|
22237
|
+
const baseline = await resourceService(deps).bound(connectionId, viewId, Number(epoch), baselineId);
|
|
22238
|
+
const descriptor = baseline.descriptor;
|
|
22239
|
+
const route = descriptor.resource === "contacts" ? "GET /api/contacts" : descriptor.resource === "identity" ? "GET /api/identity" : descriptor.resource === "commands" ? "GET /api/contacts/:contact/commands" : descriptor.resource === "files" ? "GET /api/conversations/:contact/files" : "GET /api/conversations/:contact/page";
|
|
22240
|
+
const allowedQuery = descriptor.resource === "messages" && [...url.searchParams.keys()].every((key) => key === "limit") && (!url.searchParams.has("limit") || url.searchParams.getAll("limit").length === 1 && Number(url.searchParams.get("limit")) === descriptor.window.limit);
|
|
22241
|
+
if (hit.key !== route || descriptor.entityId !== void 0 && descriptor.entityId !== hit.params.contact || url.searchParams.size > 0 && !allowedQuery) throw new ResourceBindingError(409, "resource read descriptor mismatch");
|
|
22242
|
+
res.setHeader("X-Resource-Connection", connectionId);
|
|
22243
|
+
res.setHeader("X-Resource-View", viewId);
|
|
22244
|
+
res.setHeader("X-Resource-Epoch", epoch);
|
|
22245
|
+
res.setHeader("X-Resource-Baseline", baselineId);
|
|
22246
|
+
res.setHeader("X-Resource-Producer", baseline.producerGeneration);
|
|
22247
|
+
res.setHeader("X-Resource-Revision", String(baseline.revision));
|
|
22248
|
+
res.setHeader("X-Resource-Source-Generation", baseline.source.producerGeneration);
|
|
22249
|
+
res.setHeader("X-Resource-Source-Position", String(baseline.source.position));
|
|
22250
|
+
sendJson(res, 200, baseline.payload);
|
|
22251
|
+
return;
|
|
22252
|
+
}
|
|
21431
22253
|
const out = await ROUTES[hit.key]({
|
|
21432
22254
|
deps,
|
|
21433
22255
|
client: deps.runtime.client,
|
|
@@ -21442,6 +22264,8 @@ async function serveApi(req, res, deps) {
|
|
|
21442
22264
|
} catch (e2) {
|
|
21443
22265
|
if (isOursError(e2)) {
|
|
21444
22266
|
sendJson(res, 400, { error: publicEngineError(e2.code) });
|
|
22267
|
+
} else if (e2 instanceof ResourceBindingError) {
|
|
22268
|
+
sendJson(res, e2.status, { error: { code: "RESOURCE_BINDING", message: e2.message } });
|
|
21445
22269
|
} else if (e2 instanceof HttpError) {
|
|
21446
22270
|
const code = e2.status === 403 ? "FORBIDDEN" : e2.status === 415 ? "UNSUPPORTED_MEDIA_TYPE" : e2.status === 413 ? "PAYLOAD_TOO_LARGE" : e2.status === 429 ? "RATE_LIMITED" : "BAD_REQUEST";
|
|
21447
22271
|
sendJson(res, e2.status, { error: { code, message: e2.message } });
|
|
@@ -21463,7 +22287,7 @@ import { randomBytes as randomBytes2 } from "node:crypto";
|
|
|
21463
22287
|
// node_modules/@ours.network/sdk/dist/index.js
|
|
21464
22288
|
init_define_MESSENGER_BUILD_INFO();
|
|
21465
22289
|
|
|
21466
|
-
// node_modules/@ours.network/sdk/dist/chunk-
|
|
22290
|
+
// node_modules/@ours.network/sdk/dist/chunk-AKRQMPU6.js
|
|
21467
22291
|
init_define_MESSENGER_BUILD_INFO();
|
|
21468
22292
|
|
|
21469
22293
|
// node_modules/@ours.network/sdk/dist/chunk-4VLQOZT7.js
|
|
@@ -21512,11 +22336,11 @@ function m(t, o = 65536, s = false) {
|
|
|
21512
22336
|
if (s) {
|
|
21513
22337
|
e.fsyncSync(r);
|
|
21514
22338
|
for (let c = y(t); ; c = y(c)) {
|
|
21515
|
-
let
|
|
22339
|
+
let O = e.openSync(c, e.constants.O_RDONLY | e.constants.O_DIRECTORY | e.constants.O_NOFOLLOW);
|
|
21516
22340
|
try {
|
|
21517
|
-
e.fsyncSync(
|
|
22341
|
+
e.fsyncSync(O);
|
|
21518
22342
|
} finally {
|
|
21519
|
-
e.closeSync(
|
|
22343
|
+
e.closeSync(O);
|
|
21520
22344
|
}
|
|
21521
22345
|
if (c === y(c)) break;
|
|
21522
22346
|
}
|
|
@@ -21571,13 +22395,13 @@ var I = 100 * 1024 * 1024;
|
|
|
21571
22395
|
var K = { brokerUrl: "wss://broker1.ours.network", port: 3050, stateDir: E(T(), ".ours"), gcIntervalMs: 36e5, historyMaxBytes: I, apiVisibility: "owner", apiAuthMode: "legacy" };
|
|
21572
22396
|
var $2 = "daemon-token";
|
|
21573
22397
|
|
|
21574
|
-
// node_modules/@ours.network/sdk/dist/chunk-
|
|
21575
|
-
import { homedir as
|
|
21576
|
-
import { isAbsolute as
|
|
21577
|
-
import { randomBytes as
|
|
21578
|
-
import { readFileSync as
|
|
21579
|
-
import { homedir as
|
|
21580
|
-
import { join as
|
|
22398
|
+
// node_modules/@ours.network/sdk/dist/chunk-AKRQMPU6.js
|
|
22399
|
+
import { homedir as Ie } from "node:os";
|
|
22400
|
+
import { isAbsolute as be, join as _e, resolve as ce } from "node:path";
|
|
22401
|
+
import { randomBytes as z } from "node:crypto";
|
|
22402
|
+
import { readFileSync as Se } from "node:fs";
|
|
22403
|
+
import { homedir as Ae } from "node:os";
|
|
22404
|
+
import { join as G, resolve as M2 } from "node:path";
|
|
21581
22405
|
var d = class extends Error {
|
|
21582
22406
|
constructor(n, r, i) {
|
|
21583
22407
|
super(r);
|
|
@@ -21586,8 +22410,8 @@ var d = class extends Error {
|
|
|
21586
22410
|
this.name = "OursError";
|
|
21587
22411
|
}
|
|
21588
22412
|
};
|
|
21589
|
-
var
|
|
21590
|
-
function
|
|
22413
|
+
var B = () => new d("INVALID_OBSERVATION", "Terminal observation must match this external owner instance and contain valid process evidence.");
|
|
22414
|
+
function h2(e2) {
|
|
21591
22415
|
if (typeof e2 != "string" || /[\s\\#]/.test(e2) || !/^https?:\/\//i.test(e2)) throw new Error("Daemon endpoint must be an HTTP or HTTPS URL without credentials or fragment");
|
|
21592
22416
|
let t;
|
|
21593
22417
|
try {
|
|
@@ -21598,7 +22422,7 @@ function y2(e2) {
|
|
|
21598
22422
|
if (t.username || t.password || t.hash) throw new Error("Daemon endpoint cannot contain credentials or fragment");
|
|
21599
22423
|
return t.origin + t.pathname.replace(/\/+$/, "") + t.search;
|
|
21600
22424
|
}
|
|
21601
|
-
function
|
|
22425
|
+
function m2(e2, t) {
|
|
21602
22426
|
if (!t.startsWith("/") || t.startsWith("//") || t.includes("#")) throw new Error("Invalid daemon route");
|
|
21603
22427
|
let n = new URL(e2), r = new URL(t, "http://daemon.invalid");
|
|
21604
22428
|
if (n.pathname = n.pathname.replace(/\/+$/, "") + r.pathname, r.search) {
|
|
@@ -21607,7 +22431,7 @@ function u2(e2, t) {
|
|
|
21607
22431
|
}
|
|
21608
22432
|
return n.href;
|
|
21609
22433
|
}
|
|
21610
|
-
function
|
|
22434
|
+
function D(e2) {
|
|
21611
22435
|
try {
|
|
21612
22436
|
let t = new URL(e2);
|
|
21613
22437
|
return t.origin + t.pathname;
|
|
@@ -21615,7 +22439,7 @@ function R2(e2) {
|
|
|
21615
22439
|
return "<invalid daemon endpoint>";
|
|
21616
22440
|
}
|
|
21617
22441
|
}
|
|
21618
|
-
async function
|
|
22442
|
+
async function P(e2) {
|
|
21619
22443
|
let t = e2.body?.getReader();
|
|
21620
22444
|
if (!t) throw new Error("Missing daemon response");
|
|
21621
22445
|
let n = [], r = 0;
|
|
@@ -21632,38 +22456,38 @@ async function F(e2) {
|
|
|
21632
22456
|
});
|
|
21633
22457
|
}
|
|
21634
22458
|
}
|
|
21635
|
-
function
|
|
22459
|
+
function C(e2, t) {
|
|
21636
22460
|
let n = (o) => o !== null && typeof o == "object" && !Array.isArray(o), r = (o, s) => Object.keys(o).length === s.length && Object.keys(o).every((a) => s.includes(a)), i = (o) => typeof o == "string" && o.trim().length > 0 && o.length <= 1024;
|
|
21637
|
-
if (!n(e2) || !r(e2, ["ownerInstanceId", "reason", "observedAt", "process"]) || !t || e2.ownerInstanceId !== t || e2.reason !== "process-exit" && e2.reason !== "session-end" || !Number.isSafeInteger(e2.observedAt) || Number(e2.observedAt) < 0 || !n(e2.process) || !r(e2.process, ["pid", "bootId", "startId", "domain"]) || !Number.isSafeInteger(e2.process.pid) || Number(e2.process.pid) < 1 || !i(e2.process.bootId) || !i(e2.process.startId) || !i(e2.process.domain)) throw
|
|
22461
|
+
if (!n(e2) || !r(e2, ["ownerInstanceId", "reason", "observedAt", "process"]) || !t || e2.ownerInstanceId !== t || e2.reason !== "process-exit" && e2.reason !== "session-end" || !Number.isSafeInteger(e2.observedAt) || Number(e2.observedAt) < 0 || !n(e2.process) || !r(e2.process, ["pid", "bootId", "startId", "domain"]) || !Number.isSafeInteger(e2.process.pid) || Number(e2.process.pid) < 1 || !i(e2.process.bootId) || !i(e2.process.startId) || !i(e2.process.domain)) throw B();
|
|
21638
22462
|
}
|
|
21639
|
-
var
|
|
21640
|
-
var
|
|
21641
|
-
function
|
|
21642
|
-
if (!
|
|
22463
|
+
var v2 = (e2) => typeof e2 == "string" && e2.length > 0;
|
|
22464
|
+
var V = (e2) => ({ event: "sync_required", reason: "legacy_or_malformed_event", source_event: e2 });
|
|
22465
|
+
function ae(e2) {
|
|
22466
|
+
if (!v2(e2.event)) return V("unknown");
|
|
21643
22467
|
if (e2.event === "contact_removed") {
|
|
21644
22468
|
let t = /^[0-9A-F]{64}$/;
|
|
21645
|
-
return typeof e2.cid != "string" || !t.test(e2.cid) || typeof e2.identity_cid != "string" || !t.test(e2.identity_cid) || e2.by !== "local" && e2.by !== "peer" ?
|
|
22469
|
+
return typeof e2.cid != "string" || !t.test(e2.cid) || typeof e2.identity_cid != "string" || !t.test(e2.identity_cid) || e2.by !== "local" && e2.by !== "peer" ? V("contact_removed") : { event: "contact_removed", identity_cid: e2.identity_cid, cid: e2.cid, by: e2.by };
|
|
21646
22470
|
}
|
|
21647
|
-
if (e2.event === "message_received") return !
|
|
22471
|
+
if (e2.event === "message_received") return !v2(e2.sender_id) || !v2(e2.sender_name) || !v2(e2.msg_id) || !v2(e2.wire_id) || !v2(e2.date) ? V("message_received") : { event: "message_received", sender_id: e2.sender_id, sender_name: e2.sender_name, from: v2(e2.from) ? e2.from : e2.sender_name, msg_id: e2.msg_id, wire_id: e2.wire_id, date: e2.date };
|
|
21648
22472
|
if (e2.event === "receipt_received") {
|
|
21649
22473
|
let t = e2.kind, n = e2.wire_ids;
|
|
21650
|
-
return !
|
|
22474
|
+
return !v2(e2.sender_id) || t !== "delivered" && t !== "read" || !Array.isArray(n) || n.length === 0 || !n.every(v2) ? V("receipt_received") : { event: "receipt_received", sender_id: e2.sender_id, kind: t, wire_ids: [...n], date: v2(e2.date) ? e2.date : (/* @__PURE__ */ new Date()).toISOString() };
|
|
21651
22475
|
}
|
|
21652
22476
|
return e2;
|
|
21653
22477
|
}
|
|
21654
|
-
var
|
|
22478
|
+
var ve = { event: () => {
|
|
21655
22479
|
}, notification: () => {
|
|
21656
22480
|
} };
|
|
21657
|
-
var
|
|
21658
|
-
function
|
|
22481
|
+
var Ft = { ...ve };
|
|
22482
|
+
function K2(e2, t = /* @__PURE__ */ new Set()) {
|
|
21659
22483
|
if (e2 === null || typeof e2 == "string" || typeof e2 == "boolean") return true;
|
|
21660
22484
|
if (typeof e2 == "number") return Number.isFinite(e2);
|
|
21661
22485
|
if (typeof e2 != "object" || t.has(e2)) return false;
|
|
21662
22486
|
t.add(e2);
|
|
21663
|
-
let n = Array.isArray(e2) ? e2.every((r) =>
|
|
22487
|
+
let n = Array.isArray(e2) ? e2.every((r) => K2(r, t)) : Object.getPrototypeOf(e2) === Object.prototype && Object.values(e2).every((r) => K2(r, t));
|
|
21664
22488
|
return t.delete(e2), n;
|
|
21665
22489
|
}
|
|
21666
|
-
var
|
|
22490
|
+
var U = class {
|
|
21667
22491
|
base;
|
|
21668
22492
|
leaseToken;
|
|
21669
22493
|
sessionMode;
|
|
@@ -21679,12 +22503,12 @@ var x = class {
|
|
|
21679
22503
|
if (t.credentialPath !== void 0 && t.apiToken !== void 0) throw new Error("Credential path cannot be combined with an explicit API token");
|
|
21680
22504
|
if ("serverCertificate" in t && t.serverCertificate !== void 0) throw new Error("Custom serverCertificate is not supported; HTTPS uses Node certificate trust, including NODE_EXTRA_CA_CERTS");
|
|
21681
22505
|
if (new URL(t.url).protocol !== "http:" && new URL(t.url).protocol !== "https:") throw new Error("Client requires an HTTP or HTTPS daemon endpoint");
|
|
21682
|
-
if (this.base =
|
|
22506
|
+
if (this.base = h2(t.url), this.sessionMode = t.sessionMode ?? "local", this.sessionMode !== "local" && this.sessionMode !== "external") throw new Error("Invalid sessionMode");
|
|
21683
22507
|
if (this.sessionMode === "external" && !t.leaseToken) throw new Error("External ownership requires a stable caller-supplied leaseToken");
|
|
21684
22508
|
this.leaseToken = t.leaseToken, this.clientPid = t.clientPid ?? process.pid, this.explicitApiToken = t.apiToken, this.credentialPath = t.credentialPath;
|
|
21685
22509
|
let n = t.fetch ?? globalThis.fetch;
|
|
21686
22510
|
this.fetchImpl = (r, i) => {
|
|
21687
|
-
let o = String(r) ===
|
|
22511
|
+
let o = String(r) === m2(this.base, "/api/v1/releaseLease"), s = [i?.signal, o ? t.requestSignal ? AbortSignal.timeout(5e3) : void 0 : t.requestSignal].filter((a) => a != null);
|
|
21688
22512
|
return n(r, { ...i, ...s.length ? { signal: AbortSignal.any(s) } : {} });
|
|
21689
22513
|
};
|
|
21690
22514
|
}
|
|
@@ -21695,17 +22519,17 @@ var x = class {
|
|
|
21695
22519
|
return { "x-ours-session-mode": this.sessionMode, "x-ours-lease-token": this.leaseToken, "x-ours-client-pid": String(this.clientPid), ...n ? { "x-ours-api-token": n } : {}, ...t };
|
|
21696
22520
|
}
|
|
21697
22521
|
async post(t, n, r = false) {
|
|
21698
|
-
let i = await this.fetchImpl(
|
|
22522
|
+
let i = await this.fetchImpl(m2(this.base, `/api/v1/${t}`), { redirect: "error", method: "POST", headers: this.headers({ "content-type": "application/json" }), body: JSON.stringify(n ?? {}), ...r ? { signal: AbortSignal.timeout(5e3) } : {} }), o;
|
|
21699
22523
|
try {
|
|
21700
|
-
r ? o = await
|
|
22524
|
+
r ? o = await P(i) : o = await i.json();
|
|
21701
22525
|
} catch {
|
|
21702
22526
|
throw new Error(`${t}: the daemon returned a non-JSON response (HTTP ${i.status})`);
|
|
21703
22527
|
}
|
|
21704
22528
|
if (o && typeof o == "object" && !Array.isArray(o) && "error" in o) {
|
|
21705
22529
|
let s = o.error, a = s !== null && typeof s == "object" && "code" in s && "message" in s;
|
|
21706
22530
|
if (i.status === 400 && a) {
|
|
21707
|
-
let { code: l, message:
|
|
21708
|
-
throw new d(l,
|
|
22531
|
+
let { code: l, message: f, details: u2 } = s;
|
|
22532
|
+
throw new d(l, f, u2);
|
|
21709
22533
|
}
|
|
21710
22534
|
let c = a ? s.message : String(s);
|
|
21711
22535
|
throw new Error(`${t}: ${c} (HTTP ${i.status})`);
|
|
@@ -21714,7 +22538,7 @@ var x = class {
|
|
|
21714
22538
|
return o;
|
|
21715
22539
|
}
|
|
21716
22540
|
async get(t, n) {
|
|
21717
|
-
let r = await this.fetchImpl(
|
|
22541
|
+
let r = await this.fetchImpl(m2(this.base, t), { redirect: "error", headers: n ? this.headers() : {} }), i;
|
|
21718
22542
|
try {
|
|
21719
22543
|
i = await r.json();
|
|
21720
22544
|
} catch {
|
|
@@ -21724,6 +22548,61 @@ var x = class {
|
|
|
21724
22548
|
if (!r.ok) throw new Error(`GET ${t}: the daemon returned HTTP ${r.status} with no error field`);
|
|
21725
22549
|
return i;
|
|
21726
22550
|
}
|
|
22551
|
+
async resourcePosition(t, n) {
|
|
22552
|
+
let r = await this.fetchImpl(m2(this.base, `/identities/${encodeURIComponent(t)}/resource-events?position=1`), { redirect: "error", headers: this.headers(), signal: n.signal });
|
|
22553
|
+
if (!r.ok) throw new L(r.status);
|
|
22554
|
+
let i = await P(r);
|
|
22555
|
+
return de(i), i;
|
|
22556
|
+
}
|
|
22557
|
+
async *resourceEvents(t, n) {
|
|
22558
|
+
if (n.expectedGeneration === void 0 != (n.after === void 0) || n.after !== void 0 && (!Number.isSafeInteger(n.after) || n.after < 0)) throw new Error("expectedGeneration and a nonnegative safe after position are required together");
|
|
22559
|
+
let r = new AbortController(), i = AbortSignal.any([n.signal, r.signal]), o, s = 0, a = (f) => {
|
|
22560
|
+
s = Date.now() + f, clearTimeout(o), o = setTimeout(() => r.abort(new Error("Resource source coverage deadline expired")), f), o.unref?.();
|
|
22561
|
+
}, c = () => {
|
|
22562
|
+
if (i.aborted) throw i.reason;
|
|
22563
|
+
if (Date.now() >= s) throw new Error("Resource source coverage deadline expired");
|
|
22564
|
+
}, l;
|
|
22565
|
+
try {
|
|
22566
|
+
a(1e4);
|
|
22567
|
+
let f = new URLSearchParams();
|
|
22568
|
+
n.after !== void 0 && (f.set("after", String(n.after)), f.set("expectedGeneration", n.expectedGeneration));
|
|
22569
|
+
let u2 = await this.fetchImpl(m2(this.base, `/identities/${encodeURIComponent(t)}/resource-events?${f}`), { redirect: "error", headers: this.headers({ accept: "text/event-stream" }), signal: i });
|
|
22570
|
+
if (i.aborted) throw u2.body?.cancel(), i.reason;
|
|
22571
|
+
if (!u2.ok) throw new L(u2.status);
|
|
22572
|
+
if (!u2.body || !u2.headers.get("content-type")?.startsWith("text/event-stream")) throw new Error("Invalid resource stream response");
|
|
22573
|
+
l = u2.body.getReader();
|
|
22574
|
+
let g2 = new TextDecoder("utf-8", { fatal: true }), y2 = "", I2 = 0, b2 = false, S2, T2 = -1;
|
|
22575
|
+
for (; ; ) {
|
|
22576
|
+
let { value: _, done: x } = await l.read();
|
|
22577
|
+
if (c(), x) throw new Error("Resource stream ended before disposal");
|
|
22578
|
+
if (I2 += _.byteLength, I2 > 8 * 1024 * 1024) throw new Error("Resource live input exceeds limit");
|
|
22579
|
+
for (y2 += g2.decode(_, { stream: true }); ; ) {
|
|
22580
|
+
c();
|
|
22581
|
+
let w2 = /\r?\n\r?\n/.exec(y2);
|
|
22582
|
+
if (!w2) break;
|
|
22583
|
+
let H = y2.slice(0, w2.index);
|
|
22584
|
+
if (y2 = y2.slice(w2.index + w2[0].length), I2 -= Buffer.byteLength(H) + Buffer.byteLength(w2[0]), Buffer.byteLength(H) > 512 * 1024) throw new Error("Resource frame exceeds limit");
|
|
22585
|
+
let re = H.split(/\r?\n/).filter((N) => N.startsWith("data:")).map((N) => N.slice(5).trimStart()).join(`
|
|
22586
|
+
`);
|
|
22587
|
+
if (!re) continue;
|
|
22588
|
+
let A2 = JSON.parse(re);
|
|
22589
|
+
if (c(), H.split(/\r?\n/).some((N) => N === "event: auth_required")) throw new L(401);
|
|
22590
|
+
de(A2);
|
|
22591
|
+
let J = A2.kind;
|
|
22592
|
+
if (!["ready", "committed", "coverage", "resync"].includes(J)) throw new Error("Invalid resource frame kind");
|
|
22593
|
+
if (S2 !== void 0 && (A2.producerGeneration !== S2 || A2.position < T2)) throw new Error("Resource stream continuity changed");
|
|
22594
|
+
if (S2 = A2.producerGeneration, T2 = A2.position, J === "ready") b2 = true, a(6e3);
|
|
22595
|
+
else if (b2) a(6e3);
|
|
22596
|
+
else if (J !== "resync") throw new Error("Resource mutation before ready");
|
|
22597
|
+
yield A2, c();
|
|
22598
|
+
}
|
|
22599
|
+
if (Buffer.byteLength(y2) > 512 * 1024) throw new Error("Resource frame exceeds limit");
|
|
22600
|
+
}
|
|
22601
|
+
} finally {
|
|
22602
|
+
clearTimeout(o), r.abort(), await l?.cancel().catch(() => {
|
|
22603
|
+
}), l?.releaseLock();
|
|
22604
|
+
}
|
|
22605
|
+
}
|
|
21727
22606
|
createIdentity(t) {
|
|
21728
22607
|
return this.post("createIdentity", t);
|
|
21729
22608
|
}
|
|
@@ -21754,8 +22633,8 @@ var x = class {
|
|
|
21754
22633
|
async releaseLease(t = {}) {
|
|
21755
22634
|
let n = t?.observation;
|
|
21756
22635
|
if (n !== void 0) {
|
|
21757
|
-
if (this.sessionMode !== "external") throw
|
|
21758
|
-
|
|
22636
|
+
if (this.sessionMode !== "external") throw B();
|
|
22637
|
+
C(n, this.leaseToken);
|
|
21759
22638
|
}
|
|
21760
22639
|
let r = await this.post("releaseLease", t, n !== void 0);
|
|
21761
22640
|
if (n !== void 0) {
|
|
@@ -21850,11 +22729,11 @@ var x = class {
|
|
|
21850
22729
|
try {
|
|
21851
22730
|
let c = JSON.parse(s.body);
|
|
21852
22731
|
if (!c || typeof c != "object" || Array.isArray(c) || Object.keys(c).length !== 2 || typeof c.command != "string" || !("arguments" in c)) throw new Error("invalid command payload");
|
|
21853
|
-
let l = c,
|
|
21854
|
-
if (!
|
|
21855
|
-
let g2 = Object.freeze({ sender_cid: s.from.id, sender_name: s.from.name, request_wire_id: s.wire_id }),
|
|
21856
|
-
if (!
|
|
21857
|
-
a = { ok: true, result:
|
|
22732
|
+
let l = c, f = l.command, u2 = this.commandHandlers.get(f);
|
|
22733
|
+
if (!u2) throw new Error("handler not registered");
|
|
22734
|
+
let g2 = Object.freeze({ sender_cid: s.from.id, sender_name: s.from.name, request_wire_id: s.wire_id }), y2 = await u2(l.arguments, g2);
|
|
22735
|
+
if (!K2(y2)) throw new Error("handler returned a non-JSON value");
|
|
22736
|
+
a = { ok: true, result: y2 };
|
|
21858
22737
|
} catch {
|
|
21859
22738
|
}
|
|
21860
22739
|
await this.post("sendCommandResult", { contact: s.from.id, reply_to_wire_id: s.wire_id, outcome: a });
|
|
@@ -21901,7 +22780,7 @@ var x = class {
|
|
|
21901
22780
|
return this.get("/history-storage", true);
|
|
21902
22781
|
}
|
|
21903
22782
|
async readNotificationPage(t, n = {}) {
|
|
21904
|
-
let r = "/identities/" + encodeURIComponent(t) + "/notifications", i = n.kinds?.length ? "&kinds=" + encodeURIComponent(n.kinds.join(",")) : "", o = n.requestTimeoutMs === void 0 ? n.signal : AbortSignal.any([...n.signal ? [n.signal] : [], AbortSignal.timeout(n.requestTimeoutMs)]), s = await this.fetchImpl(
|
|
22783
|
+
let r = "/identities/" + encodeURIComponent(t) + "/notifications", i = n.kinds?.length ? "&kinds=" + encodeURIComponent(n.kinds.join(",")) : "", o = n.requestTimeoutMs === void 0 ? n.signal : AbortSignal.any([...n.signal ? [n.signal] : [], AbortSignal.timeout(n.requestTimeoutMs)]), s = await this.fetchImpl(m2(this.base, r + "?since=" + encodeURIComponent(String(n.since ?? "tip")) + i), { redirect: "error", headers: this.headers(), signal: o }), a;
|
|
21905
22784
|
try {
|
|
21906
22785
|
a = await s.json();
|
|
21907
22786
|
} catch {
|
|
@@ -21918,7 +22797,7 @@ var x = class {
|
|
|
21918
22797
|
for (; !n.signal?.aborted; ) {
|
|
21919
22798
|
let s;
|
|
21920
22799
|
try {
|
|
21921
|
-
let a = await this.fetchImpl(
|
|
22800
|
+
let a = await this.fetchImpl(m2(this.base, `${i}?since=${r}${o}`), { redirect: "error", headers: this.headers(), signal: n.requestTimeoutMs === void 0 ? n.signal : AbortSignal.any([...n.signal ? [n.signal] : [], AbortSignal.timeout(n.requestTimeoutMs)]) });
|
|
21922
22801
|
try {
|
|
21923
22802
|
s = await a.json();
|
|
21924
22803
|
} catch {
|
|
@@ -21930,11 +22809,11 @@ var x = class {
|
|
|
21930
22809
|
}
|
|
21931
22810
|
if ("error" in s) throw new Error(`watchNotifications(${t}): ${s.error}`);
|
|
21932
22811
|
r = s.cursor;
|
|
21933
|
-
for (let a of s.events) yield
|
|
22812
|
+
for (let a of s.events) yield ae(a && typeof a == "object" ? a : {});
|
|
21934
22813
|
}
|
|
21935
22814
|
}
|
|
21936
22815
|
async fetchFile(t) {
|
|
21937
|
-
let n = await this.fetchImpl(
|
|
22816
|
+
let n = await this.fetchImpl(m2(this.base, `/files/${encodeURIComponent(t)}`), { redirect: "error", headers: this.headers() });
|
|
21938
22817
|
if (!n.ok) {
|
|
21939
22818
|
let r = `HTTP ${n.status}`;
|
|
21940
22819
|
try {
|
|
@@ -21947,7 +22826,7 @@ var x = class {
|
|
|
21947
22826
|
return new Uint8Array(await n.arrayBuffer());
|
|
21948
22827
|
}
|
|
21949
22828
|
async openFile(t) {
|
|
21950
|
-
let n = await this.fetchImpl(
|
|
22829
|
+
let n = await this.fetchImpl(m2(this.base, `/files/${encodeURIComponent(t)}`), { redirect: "error", headers: this.headers() });
|
|
21951
22830
|
if (!n.ok) {
|
|
21952
22831
|
let r = `HTTP ${n.status}`;
|
|
21953
22832
|
try {
|
|
@@ -21963,7 +22842,7 @@ var x = class {
|
|
|
21963
22842
|
async uploadFile(t, n) {
|
|
21964
22843
|
let r = t instanceof Uint8Array ? t.byteLength : n.size;
|
|
21965
22844
|
if (r === void 0) throw new Error("uploadFile: `size` is required when the body is a stream (the route needs Content-Length)");
|
|
21966
|
-
let i = await this.fetchImpl(
|
|
22845
|
+
let i = await this.fetchImpl(m2(this.base, "/files/upload"), { redirect: "error", method: "POST", headers: { ...this.headers(), "x-ours-filename": encodeURIComponent(n.filename), "Content-Type": n.mime || "application/octet-stream", "Content-Length": String(r) }, body: t, ...t instanceof Uint8Array ? {} : { duplex: "half" } });
|
|
21967
22846
|
if (!i.ok) {
|
|
21968
22847
|
let o = `HTTP ${i.status}`;
|
|
21969
22848
|
try {
|
|
@@ -21976,21 +22855,33 @@ var x = class {
|
|
|
21976
22855
|
return await i.json();
|
|
21977
22856
|
}
|
|
21978
22857
|
};
|
|
21979
|
-
var
|
|
22858
|
+
var L = class extends Error {
|
|
22859
|
+
constructor(n) {
|
|
22860
|
+
super(`Resource stream HTTP ${n}${n === 401 ? ": unauthorized" : ""}`);
|
|
22861
|
+
this.status = n;
|
|
22862
|
+
this.name = "ResourceStreamError";
|
|
22863
|
+
}
|
|
22864
|
+
};
|
|
22865
|
+
function de(e2) {
|
|
22866
|
+
if (!e2 || typeof e2 != "object") throw new Error("Invalid resource source position");
|
|
22867
|
+
let t = e2;
|
|
22868
|
+
if (t.protocolVersion !== 1 || typeof t.producerGeneration != "string" || !t.producerGeneration || !Number.isSafeInteger(t.position) || t.position < 0) throw new Error("Invalid resource source position");
|
|
22869
|
+
}
|
|
22870
|
+
var R2 = class extends Error {
|
|
21980
22871
|
constructor(t) {
|
|
21981
22872
|
super(`Invalid gateway client profile: ${t}. Configure ~/.ours-client/profile.json with ours-install client; no local service fallback is permitted.`), this.name = "ClientProfileError";
|
|
21982
22873
|
}
|
|
21983
22874
|
};
|
|
21984
|
-
function
|
|
22875
|
+
function Te(e2 = process.env) {
|
|
21985
22876
|
if (e2.OURS_CONFIG !== void 0) {
|
|
21986
|
-
if (!e2.OURS_CONFIG.trim()) throw new
|
|
21987
|
-
return
|
|
22877
|
+
if (!e2.OURS_CONFIG.trim()) throw new R2("OURS_CONFIG must name a client profile");
|
|
22878
|
+
return ce(e2.OURS_CONFIG);
|
|
21988
22879
|
}
|
|
21989
|
-
return
|
|
22880
|
+
return _e(e2.HOME || Ie(), ".ours-client", "profile.json");
|
|
21990
22881
|
}
|
|
21991
|
-
function
|
|
22882
|
+
function Oe(e2) {
|
|
21992
22883
|
let t = (o) => {
|
|
21993
|
-
throw new
|
|
22884
|
+
throw new R2(o);
|
|
21994
22885
|
};
|
|
21995
22886
|
if (!e2 || typeof e2 != "object" || Array.isArray(e2)) return t("expected a JSON object");
|
|
21996
22887
|
let n = e2;
|
|
@@ -21998,27 +22889,27 @@ function we(e2) {
|
|
|
21998
22889
|
if (typeof n.serverUrl != "string" || !n.serverUrl || /[\s\\?#]/.test(n.serverUrl)) return t("serverUrl must be an HTTP or HTTPS gateway base URL without credentials, query or fragment");
|
|
21999
22890
|
let r;
|
|
22000
22891
|
try {
|
|
22001
|
-
r =
|
|
22892
|
+
r = h2(n.serverUrl);
|
|
22002
22893
|
} catch {
|
|
22003
22894
|
return t("serverUrl must be a safe HTTP or HTTPS gateway base URL");
|
|
22004
22895
|
}
|
|
22005
22896
|
let i = r + "/daemon";
|
|
22006
22897
|
if (n.endpoint !== void 0) try {
|
|
22007
|
-
if (typeof n.endpoint != "string" ||
|
|
22898
|
+
if (typeof n.endpoint != "string" || h2(n.endpoint) !== i) return t("endpoint must equal serverUrl/daemon; remove stale endpoint overrides");
|
|
22008
22899
|
} catch {
|
|
22009
22900
|
return t("endpoint must equal serverUrl/daemon");
|
|
22010
22901
|
}
|
|
22011
|
-
return typeof n.expectedInstanceId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(n.expectedInstanceId) ? t("expectedInstanceId must be a lowercase UUID") : typeof n.credentialPath != "string" || !
|
|
22902
|
+
return typeof n.expectedInstanceId != "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(n.expectedInstanceId) ? t("expectedInstanceId must be a lowercase UUID") : typeof n.credentialPath != "string" || !be(n.credentialPath) || ce(n.credentialPath) !== n.credentialPath ? t("credentialPath must be an absolute normalized path") : Object.freeze({ serverUrl: r, endpoint: i, expectedInstanceId: n.expectedInstanceId, credentialPath: n.credentialPath });
|
|
22012
22903
|
}
|
|
22013
|
-
function
|
|
22014
|
-
let t =
|
|
22904
|
+
function le(e2 = process.env) {
|
|
22905
|
+
let t = Te(e2), n;
|
|
22015
22906
|
try {
|
|
22016
22907
|
n = JSON.parse(m(t).toString("utf8"));
|
|
22017
22908
|
} catch {
|
|
22018
|
-
throw new
|
|
22909
|
+
throw new R2("selected profile is missing, invalid JSON or unsafe; require a 0700 directory and a 0600 regular file");
|
|
22019
22910
|
}
|
|
22020
|
-
let r =
|
|
22021
|
-
if (["OURS_PORT", "OURS_STATE_DIR", "OURS_API_TOKEN", "OURS_DAEMON_ID", "OURS_DAEMON_URL", "OURS_DAEMON_CREDENTIAL_PATH"].some((o) => e2[o]?.trim())) throw new
|
|
22911
|
+
let r = Oe(n);
|
|
22912
|
+
if (["OURS_PORT", "OURS_STATE_DIR", "OURS_API_TOKEN", "OURS_DAEMON_ID", "OURS_DAEMON_URL", "OURS_DAEMON_CREDENTIAL_PATH"].some((o) => e2[o]?.trim())) throw new R2("remove legacy OURS_PORT/STATE_DIR/API_TOKEN/DAEMON_ID/DAEMON_URL/DAEMON_CREDENTIAL_PATH environment selectors");
|
|
22022
22913
|
return Object.freeze({ ...r, configPath: t });
|
|
22023
22914
|
}
|
|
22024
22915
|
var p = class extends Error {
|
|
@@ -22028,61 +22919,61 @@ var p = class extends Error {
|
|
|
22028
22919
|
this.name = "DaemonSelectionError";
|
|
22029
22920
|
}
|
|
22030
22921
|
};
|
|
22031
|
-
var
|
|
22922
|
+
var W = class extends p {
|
|
22032
22923
|
constructor(n, r, i = {}) {
|
|
22033
|
-
super("DAEMON_UNAVAILABLE", `no ours daemon is running at ${
|
|
22924
|
+
super("DAEMON_UNAVAILABLE", `no ours daemon is running at ${D(n)} for state directory ${JSON.stringify(r)}. Install the daemon with \`npm install --global @ours.network/daemon\`, then start the shared daemon with \`ours-daemon start\` or install/start its per-user service through \`ours-daemon install-service\`. SDK applications attach to the shared daemon and do not start an embedded daemon.`);
|
|
22034
22925
|
this.endpoint = n;
|
|
22035
22926
|
this.stateDir = r;
|
|
22036
22927
|
this.name = "DaemonUnavailableError", i.cause !== void 0 && (this.cause = i.cause);
|
|
22037
22928
|
}
|
|
22038
22929
|
};
|
|
22039
|
-
var
|
|
22040
|
-
var
|
|
22041
|
-
var
|
|
22042
|
-
var
|
|
22043
|
-
function
|
|
22930
|
+
var pe = K.port;
|
|
22931
|
+
var Y = $2;
|
|
22932
|
+
var Re = ".ours";
|
|
22933
|
+
var xe = ["explicit", "environment", "config-file"];
|
|
22934
|
+
function Ne(e2 = {}) {
|
|
22044
22935
|
let t = e2.env ?? process.env;
|
|
22045
22936
|
if (t.OURS_TLS_CERT !== void 0 || t.OURS_TLS_KEY !== void 0) throw new p("INCOHERENT_SELECTION", "Daemon TLS is not supported in V1; remove OURS_TLS_CERT/OURS_TLS_KEY and explicitly configure HTTP");
|
|
22046
22937
|
if (e2.endpoint !== void 0 && new URL(e2.endpoint).protocol !== "http:" && new URL(e2.endpoint).protocol !== "https:") throw new p("INCOHERENT_SELECTION", "Client requires an HTTP or HTTPS daemon endpoint");
|
|
22047
|
-
let n = e2.readTextFile ?? ((
|
|
22938
|
+
let n = e2.readTextFile ?? ((y2) => Se(y2, "utf8")), r = e2.homeDir ?? Ae(), i = $3(t, "OURS_INSTANCE");
|
|
22048
22939
|
if (i !== void 0) throw new p("INCOHERENT_SELECTION", `OURS_INSTANCE=${JSON.stringify(i)} is set, but named daemon instances are not implemented. Select the daemon with an explicit endpoint/port option or with OURS_PORT, and unset OURS_INSTANCE.`);
|
|
22049
22940
|
if (e2.stateDir !== void 0 && e2.expectStateDir !== void 0) {
|
|
22050
|
-
let
|
|
22051
|
-
if (
|
|
22941
|
+
let y2 = M2(e2.stateDir), I2 = M2(e2.expectStateDir);
|
|
22942
|
+
if (y2 !== I2) throw new p("INCOHERENT_SELECTION", `stateDir ${JSON.stringify(y2)} and expectStateDir ${JSON.stringify(I2)} name different directories. The state directory decides which token is read; the expected one decides which daemon that token may be sent to. Reconcile them, or pass only one.`);
|
|
22052
22943
|
}
|
|
22053
|
-
let o =
|
|
22054
|
-
|
|
22055
|
-
let g2 =
|
|
22056
|
-
return { baseUrl:
|
|
22944
|
+
let o = Le(e2.configPath, $3(t, "OURS_CONFIG")), s = o ? Pe(o.value, n) : {}, a = ue(e2.port, Ce($3(t, "OURS_PORT")), s.port, pe), c = ue(e2.stateDir ?? e2.expectStateDir, $3(t, "OURS_STATE_DIR"), s.stateDir, G(r, Re)), l = { value: M2(c.value), source: c.source }, f = e2.endpoint !== void 0 ? { value: h2(e2.endpoint), source: "explicit" } : { value: `http://127.0.0.1:${a.value}`, source: a.source }, u2 = $3(t, "OURS_API_TOKEN");
|
|
22945
|
+
ke({ endpointSelected: e2.endpoint !== void 0 || a.source !== "default", endpointSource: f.source, stateDirIntentional: xe.includes(l.source), stateDirSource: l.source, hasExplicitToken: e2.token !== void 0 && e2.token !== "", hasEnvToken: u2 !== void 0, requireExplicitSelection: e2.requireExplicitSelection === true, portSource: a.source });
|
|
22946
|
+
let g2 = De(e2.token, u2, s, l, e2.readTextFile);
|
|
22947
|
+
return { baseUrl: f, port: a, stateDir: l, expectStateDir: e2.expectStateDir !== void 0 ? M2(e2.expectStateDir) : l.value, ...g2 ? { token: g2 } : {}, ...o ? { configPath: o } : {} };
|
|
22057
22948
|
}
|
|
22058
|
-
function
|
|
22949
|
+
function ke(e2) {
|
|
22059
22950
|
if (e2.requireExplicitSelection) {
|
|
22060
|
-
if (e2.endpointSource === "default" && e2.portSource === "default") throw
|
|
22061
|
-
if (!e2.stateDirIntentional) throw
|
|
22951
|
+
if (e2.endpointSource === "default" && e2.portSource === "default") throw F(`requireExplicitSelection is set, but no daemon was selected. Pass endpoint/port, set OURS_PORT, or point OURS_CONFIG at a config file. Refusing the built-in default 127.0.0.1:${pe}.`);
|
|
22952
|
+
if (!e2.stateDirIntentional) throw F("requireExplicitSelection is set, but the state directory is the built-in default. Every auth-affecting field must be chosen deliberately: pass stateDir or expectStateDir, set OURS_STATE_DIR, or name a config file. Refusing before reading any token or opening any socket.");
|
|
22062
22953
|
}
|
|
22063
|
-
if (e2.endpointSelected && !e2.stateDirIntentional) throw
|
|
22064
|
-
if (e2.hasEnvToken && !e2.stateDirIntentional) throw
|
|
22065
|
-
if (e2.hasExplicitToken && !e2.stateDirIntentional) throw
|
|
22954
|
+
if (e2.endpointSelected && !e2.stateDirIntentional) throw F(`the endpoint was selected (source: ${e2.endpointSource}) but the state directory is the built-in default. A daemon's API token belongs to one state directory, so reading the default token and sending it to a separately chosen endpoint would disclose a credential to it. Select the state directory too: stateDir, expectStateDir, OURS_STATE_DIR, or one config file. An explicit token alone is not enough \u2014 without an expected state directory there is nothing to assert the endpoint against before the token is sent.`);
|
|
22955
|
+
if (e2.hasEnvToken && !e2.stateDirIntentional) throw F("OURS_API_TOKEN is set, but the state directory is the built-in default. An environment token is process-wide and authenticates to every daemon it is offered to, so it requires an explicitly expected state directory: pass stateDir or expectStateDir, or set OURS_STATE_DIR.");
|
|
22956
|
+
if (e2.hasExplicitToken && !e2.stateDirIntentional) throw F("an explicit token was given, but the state directory is the built-in default, so there would be nothing to assert the daemon against before the token is sent. Pass expectStateDir (or stateDir) naming the state directory that token belongs to.");
|
|
22066
22957
|
}
|
|
22067
|
-
function
|
|
22958
|
+
function F(e2) {
|
|
22068
22959
|
return new p("INCOHERENT_SELECTION", e2);
|
|
22069
22960
|
}
|
|
22070
|
-
function
|
|
22961
|
+
function De(e2, t, n, r, i) {
|
|
22071
22962
|
if (e2 !== void 0 && e2 !== "") return { value: e2, source: "explicit" };
|
|
22072
22963
|
if (t !== void 0) return { value: t, source: "environment" };
|
|
22073
22964
|
let o = n.apiToken?.trim();
|
|
22074
22965
|
if (o) return { value: o, source: "config-file" };
|
|
22075
22966
|
if (i === void 0) {
|
|
22076
|
-
let s = w(
|
|
22967
|
+
let s = w(G(r.value, Y), false);
|
|
22077
22968
|
return s ? { value: s.token, source: "token-file" } : void 0;
|
|
22078
22969
|
}
|
|
22079
22970
|
try {
|
|
22080
|
-
let s = i(
|
|
22971
|
+
let s = i(G(r.value, Y)).trim();
|
|
22081
22972
|
if (s) return { value: s, source: "token-file" };
|
|
22082
22973
|
} catch {
|
|
22083
22974
|
}
|
|
22084
22975
|
}
|
|
22085
|
-
function
|
|
22976
|
+
function Pe(e2, t) {
|
|
22086
22977
|
let n;
|
|
22087
22978
|
try {
|
|
22088
22979
|
n = t(e2);
|
|
@@ -22118,86 +23009,86 @@ function Se(e2, t) {
|
|
|
22118
23009
|
}
|
|
22119
23010
|
return o;
|
|
22120
23011
|
}
|
|
22121
|
-
function
|
|
23012
|
+
function $3(e2, t) {
|
|
22122
23013
|
let n = e2[t];
|
|
22123
23014
|
if (n === void 0) return;
|
|
22124
23015
|
let r = n.trim();
|
|
22125
23016
|
return r === "" ? void 0 : r;
|
|
22126
23017
|
}
|
|
22127
|
-
function
|
|
23018
|
+
function Ce(e2) {
|
|
22128
23019
|
if (e2 === void 0) return;
|
|
22129
23020
|
let t = Number.parseInt(e2, 10);
|
|
22130
23021
|
if (!Number.isInteger(t) || t < 1 || t > 65535) throw new p("INCOHERENT_SELECTION", `OURS_PORT=${JSON.stringify(e2)} is not a TCP port between 1 and 65535.`);
|
|
22131
23022
|
return t;
|
|
22132
23023
|
}
|
|
22133
|
-
function
|
|
23024
|
+
function ue(e2, t, n, r) {
|
|
22134
23025
|
return e2 !== void 0 ? { value: e2, source: "explicit" } : t !== void 0 ? { value: t, source: "environment" } : n !== void 0 ? { value: n, source: "config-file" } : { value: r, source: "default" };
|
|
22135
23026
|
}
|
|
22136
|
-
function
|
|
23027
|
+
function Le(e2, t) {
|
|
22137
23028
|
if (e2 !== void 0) return { value: e2, source: "explicit" };
|
|
22138
23029
|
if (t !== void 0) return { value: t, source: "environment" };
|
|
22139
23030
|
}
|
|
22140
|
-
async function
|
|
23031
|
+
async function Ue(e2, t = {}) {
|
|
22141
23032
|
let n = t.fetch ?? globalThis.fetch, r = new AbortController(), i = setTimeout(() => r.abort(), t.timeoutMs ?? 5e3), o;
|
|
22142
23033
|
try {
|
|
22143
|
-
let a = await n(
|
|
22144
|
-
if (!a.ok) throw new p("INCOHERENT_SELECTION", `${
|
|
23034
|
+
let a = await n(m2(e2.baseUrl.value, "/state-dir"), { signal: r.signal, redirect: "error" });
|
|
23035
|
+
if (!a.ok) throw new p("INCOHERENT_SELECTION", `${D(m2(e2.baseUrl.value, "/state-dir"))} answered HTTP ${a.status}, so the daemon at that address could not be identified. Refusing to send a credential to it.`);
|
|
22145
23036
|
o = await a.json();
|
|
22146
23037
|
} catch (a) {
|
|
22147
|
-
throw a instanceof p ? a : new
|
|
23038
|
+
throw a instanceof p ? a : new W(e2.baseUrl.value, e2.expectStateDir, { cause: a });
|
|
22148
23039
|
} finally {
|
|
22149
23040
|
clearTimeout(i);
|
|
22150
23041
|
}
|
|
22151
|
-
let s = typeof o.stateDir == "string" ?
|
|
22152
|
-
if (s === null) throw new p("INCOHERENT_SELECTION", `${
|
|
22153
|
-
if (s !== e2.expectStateDir) throw new p("INCOHERENT_SELECTION", `the daemon at ${
|
|
23042
|
+
let s = typeof o.stateDir == "string" ? M2(o.stateDir) : null;
|
|
23043
|
+
if (s === null) throw new p("INCOHERENT_SELECTION", `${D(m2(e2.baseUrl.value, "/state-dir"))} did not report a state directory, so this is not an ours daemon or not one this client understands. Refusing to send a credential to it.`);
|
|
23044
|
+
if (s !== e2.expectStateDir) throw new p("INCOHERENT_SELECTION", `the daemon at ${D(e2.baseUrl.value)} owns state directory ${JSON.stringify(s)}, but this selection expects ${JSON.stringify(e2.expectStateDir)}. The token belongs to the expected directory, so it is NOT being sent. Point the endpoint and the state directory at the same daemon.`);
|
|
22154
23045
|
}
|
|
22155
|
-
async function
|
|
23046
|
+
async function X(e2 = {}) {
|
|
22156
23047
|
if (e2.endpoint === void 0 && e2.port === void 0 && e2.stateDir === void 0 && e2.expectStateDir === void 0) {
|
|
22157
|
-
let g2 =
|
|
22158
|
-
return
|
|
23048
|
+
let g2 = le({ ...e2.env ?? process.env, ...e2.configPath === void 0 ? {} : { OURS_CONFIG: e2.configPath } });
|
|
23049
|
+
return X({ ...e2, endpoint: g2.endpoint, expectedInstanceId: g2.expectedInstanceId, credentialPath: g2.credentialPath, sessionMode: "external", leaseToken: e2.leaseToken ?? z(32).toString("hex"), env: {} });
|
|
22159
23050
|
}
|
|
22160
23051
|
if ("serverCertificate" in e2 && e2.serverCertificate !== void 0) throw new Error("Custom serverCertificate is not supported; HTTPS uses Node certificate trust, including NODE_EXTRA_CA_CERTS");
|
|
22161
23052
|
let t = e2.env ?? process.env;
|
|
22162
23053
|
if (t.OURS_TLS_CERT !== void 0 || t.OURS_TLS_KEY !== void 0) throw new Error("Daemon TLS is not supported in V1; remove OURS_TLS_CERT/OURS_TLS_KEY and explicitly configure HTTP");
|
|
22163
|
-
let { leaseToken: n, clientPid: r, sessionMode: i = "local", fetch: o, requestSignal: s, expectedInstanceId: a, requiredCapabilities: c, credentialPath: l, ...
|
|
23054
|
+
let { leaseToken: n, clientPid: r, sessionMode: i = "local", fetch: o, requestSignal: s, expectedInstanceId: a, requiredCapabilities: c, credentialPath: l, ...f } = e2;
|
|
22164
23055
|
if (i !== "local" && i !== "external") throw new Error("Invalid sessionMode");
|
|
22165
23056
|
if (i === "external") {
|
|
22166
23057
|
if (a === void 0) throw new Error("External ownership requires explicit daemon identity");
|
|
22167
23058
|
if (typeof n != "string" || !n.trim()) throw new Error("External ownership requires a stable caller-supplied leaseToken");
|
|
22168
23059
|
}
|
|
22169
|
-
if (l !== void 0 && (a === void 0 ||
|
|
23060
|
+
if (l !== void 0 && (a === void 0 || f.token !== void 0)) throw new Error("Credential path requires explicit daemon identity and cannot be combined with a token");
|
|
22170
23061
|
if (a !== void 0) {
|
|
22171
|
-
let { endpoint: g2, token:
|
|
23062
|
+
let { endpoint: g2, token: y2 } = f;
|
|
22172
23063
|
if (!g2) throw new Error("Instance selection requires an explicit endpoint");
|
|
22173
23064
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(a)) throw new Error("Expected daemon instance must be a lowercase UUID");
|
|
22174
23065
|
if (o !== void 0) throw new Error("Instance selection cannot use an injected fetch");
|
|
22175
|
-
let
|
|
23066
|
+
let I2 = h2(g2);
|
|
22176
23067
|
if (c !== void 0 && !Array.isArray(c)) throw new Error("Instance selection requires a nonempty capability list");
|
|
22177
|
-
let
|
|
22178
|
-
if (!
|
|
22179
|
-
if (i === "external")
|
|
22180
|
-
else if (
|
|
23068
|
+
let b2 = [...c ?? ["external-sessions-v1"]];
|
|
23069
|
+
if (!b2.length || b2.some((T2) => typeof T2 != "string" || !T2.trim())) throw new Error("Instance selection requires a nonempty capability list");
|
|
23070
|
+
if (i === "external") b2.includes("external-sessions-v1") || b2.push("external-sessions-v1");
|
|
23071
|
+
else if (b2.includes("external-sessions-v1")) throw new Error("External capabilities require explicit sessionMode: external; refusing local-mode fallback");
|
|
22181
23072
|
{
|
|
22182
|
-
let
|
|
22183
|
-
if (!
|
|
22184
|
-
let
|
|
22185
|
-
if (!Array.isArray(
|
|
23073
|
+
let T2 = await globalThis.fetch(m2(I2, "/selection"), { signal: s ? AbortSignal.any([s, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3), redirect: "error" }), _ = await P(T2);
|
|
23074
|
+
if (!T2.ok || !_ || Object.keys(_).length !== 3 || Object.keys(_).some((w2) => !["schema", "instanceId", "capabilities"].includes(w2)) || _.schema !== 1 || _.instanceId !== a) throw new Error("Daemon instance selection metadata is absent, incompatible or mismatched");
|
|
23075
|
+
let x = _.capabilities;
|
|
23076
|
+
if (!Array.isArray(x) || x.some((w2) => typeof w2 != "string") || b2.some((w2) => !x.includes(w2))) throw new Error("Daemon does not support the required capabilities; refusing local-mode fallback");
|
|
22186
23077
|
}
|
|
22187
|
-
let
|
|
22188
|
-
if (typeof
|
|
22189
|
-
return new
|
|
23078
|
+
let S2 = l === void 0 ? y2 : S(l);
|
|
23079
|
+
if (typeof S2 != "string" || !S2.trim()) throw new Error("Instance selection requires an explicit API token after daemon verification");
|
|
23080
|
+
return new U({ url: I2, sessionMode: i, requestSignal: s, ...l === void 0 ? { apiToken: S2 } : { credentialPath: l }, leaseToken: n ?? z(32).toString("hex"), clientPid: r });
|
|
22190
23081
|
}
|
|
22191
23082
|
if (c !== void 0) throw new Error("Capability selection requires an expected daemon instance");
|
|
22192
|
-
let
|
|
22193
|
-
return await
|
|
23083
|
+
let u2 = Ne(f);
|
|
23084
|
+
return await Ue(u2, { fetch: o }), new U({ url: u2.baseUrl.value, leaseToken: n ?? z(32).toString("hex"), clientPid: r, ...u2.token?.source === "token-file" && f.readTextFile === void 0 ? { credentialPath: G(u2.expectStateDir, Y) } : { apiToken: u2.token?.value }, fetch: o, requestSignal: s });
|
|
22194
23085
|
}
|
|
22195
23086
|
|
|
22196
23087
|
// src/owner-session.ts
|
|
22197
23088
|
init_define_MESSENGER_BUILD_INFO();
|
|
22198
23089
|
import { randomBytes } from "node:crypto";
|
|
22199
23090
|
import * as fs from "node:fs";
|
|
22200
|
-
import { isAbsolute, join as join4, resolve, dirname as dirname3 } from "node:path";
|
|
23091
|
+
import { isAbsolute, join as join4, resolve as resolve2, dirname as dirname3 } from "node:path";
|
|
22201
23092
|
import { spawnSync } from "node:child_process";
|
|
22202
23093
|
function stateExists(path2) {
|
|
22203
23094
|
try {
|
|
@@ -22224,7 +23115,7 @@ var OwnerSession = class _OwnerSession {
|
|
|
22224
23115
|
if (saved) throw new ConfigurationError("Saved messenger ownership requires its qualified V1 activation and original selection");
|
|
22225
23116
|
return void 0;
|
|
22226
23117
|
}
|
|
22227
|
-
if (!stateDir || !isAbsolute(stateDir) ||
|
|
23118
|
+
if (!stateDir || !isAbsolute(stateDir) || resolve2(stateDir) !== stateDir) {
|
|
22228
23119
|
throw new ConfigurationError("Messenger ownership requires an absolute private state directory");
|
|
22229
23120
|
}
|
|
22230
23121
|
const capability = spawnSync("flock", ["--version"], { stdio: "ignore", timeout: 5e3 });
|
|
@@ -22414,7 +23305,7 @@ function daemonNotificationReader(client) {
|
|
|
22414
23305
|
function hasCode(error, code) {
|
|
22415
23306
|
return error instanceof Error && "code" in error && error.code === code;
|
|
22416
23307
|
}
|
|
22417
|
-
async function startRuntime(cfg, buildInfo, attach =
|
|
23308
|
+
async function startRuntime(cfg, buildInfo, attach = X) {
|
|
22418
23309
|
const endpoint = process.env.OURS_DAEMON_URL?.trim();
|
|
22419
23310
|
const expectedInstanceId = process.env.OURS_DAEMON_ID?.trim();
|
|
22420
23311
|
const credentialPath = process.env.OURS_DAEMON_CREDENTIAL_PATH?.trim();
|
|
@@ -22491,7 +23382,7 @@ async function bindIdentity(runtime, cfg) {
|
|
|
22491
23382
|
// src/push.ts
|
|
22492
23383
|
init_define_MESSENGER_BUILD_INFO();
|
|
22493
23384
|
var import_web_push = __toESM(require_src2(), 1);
|
|
22494
|
-
import { createHash as
|
|
23385
|
+
import { createHash as createHash4, randomUUID as randomUUID3, timingSafeEqual } from "node:crypto";
|
|
22495
23386
|
import { chmodSync as chmodSync2, lstatSync as lstatSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync5, renameSync as renameSync5, writeFileSync as writeFileSync6 } from "node:fs";
|
|
22496
23387
|
import { dirname as dirname4, join as join5 } from "node:path";
|
|
22497
23388
|
var MAX_BINDINGS = 32;
|
|
@@ -22518,7 +23409,7 @@ function nonEmpty3(value, max = Number.MAX_SAFE_INTEGER) {
|
|
|
22518
23409
|
return typeof value === "string" && value.length > 0 && value.length <= max;
|
|
22519
23410
|
}
|
|
22520
23411
|
function fingerprint(publicKey) {
|
|
22521
|
-
return
|
|
23412
|
+
return createHash4("sha256").update(publicKey).digest("base64url");
|
|
22522
23413
|
}
|
|
22523
23414
|
function base64urlBytes(value, length, field) {
|
|
22524
23415
|
if (!nonEmpty3(value, 256) || !/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
@@ -22775,7 +23666,7 @@ var PushStore = class _PushStore {
|
|
|
22775
23666
|
[identityCid]: {
|
|
22776
23667
|
...newIdentityState(),
|
|
22777
23668
|
bindings: (parsed?.subscriptions ?? []).map((row) => ({
|
|
22778
|
-
bindingId:
|
|
23669
|
+
bindingId: randomUUID3(),
|
|
22779
23670
|
endpoint: row.endpoint,
|
|
22780
23671
|
keys: row.keys,
|
|
22781
23672
|
createdAt: row.createdAt,
|
|
@@ -22847,7 +23738,7 @@ var PushStore = class _PushStore {
|
|
|
22847
23738
|
const preview = input.preview === void 0 ? previous?.preview ?? "full" : previewMode(input.preview);
|
|
22848
23739
|
if (!previous && owner.bindings.length >= MAX_BINDINGS) throw new Error(`push subscription limit is ${MAX_BINDINGS}`);
|
|
22849
23740
|
const createdAt = previous?.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
22850
|
-
const bindingId = previous?.bindingId ??
|
|
23741
|
+
const bindingId = previous?.bindingId ?? randomUUID3();
|
|
22851
23742
|
const record = {
|
|
22852
23743
|
bindingId,
|
|
22853
23744
|
endpoint,
|
|
@@ -23157,7 +24048,7 @@ var PushStore = class _PushStore {
|
|
|
23157
24048
|
}
|
|
23158
24049
|
/** Compatibility for tests/old callers; durable production delivery uses jobs. */
|
|
23159
24050
|
async send(event) {
|
|
23160
|
-
const wire = `compat-${
|
|
24051
|
+
const wire = `compat-${randomUUID3()}`;
|
|
23161
24052
|
this.enqueueJob({ wireId: wire, kind: event.kind, contactId: event.contact_id });
|
|
23162
24053
|
const id = `${this.identityCid}:${wire}:${event.kind}`;
|
|
23163
24054
|
this.claimJob(id);
|
|
@@ -23166,112 +24057,6 @@ var PushStore = class _PushStore {
|
|
|
23166
24057
|
}
|
|
23167
24058
|
};
|
|
23168
24059
|
|
|
23169
|
-
// src/watch.ts
|
|
23170
|
-
init_define_MESSENGER_BUILD_INFO();
|
|
23171
|
-
import { createHash as createHash4 } from "node:crypto";
|
|
23172
|
-
function pageDigest(events) {
|
|
23173
|
-
return createHash4("sha256").update(JSON.stringify(events)).digest("base64url");
|
|
23174
|
-
}
|
|
23175
|
-
function applyNotificationPage(page, push, delivery, events, stats, log2) {
|
|
23176
|
-
if (!Number.isSafeInteger(page.cursor) || page.cursor < 0 || !Array.isArray(page.events)) {
|
|
23177
|
-
throw new Error("daemon notification page is malformed");
|
|
23178
|
-
}
|
|
23179
|
-
const fromCursor = push.notificationCursor;
|
|
23180
|
-
if (fromCursor === null) {
|
|
23181
|
-
if (page.events.length > 0) throw new Error("daemon notification tip page unexpectedly contained events");
|
|
23182
|
-
push.commitNotificationCursor(page.cursor);
|
|
23183
|
-
stats.cursorCommits++;
|
|
23184
|
-
return true;
|
|
23185
|
-
}
|
|
23186
|
-
let progress = push.notificationPageProgress;
|
|
23187
|
-
if (progress) {
|
|
23188
|
-
const prefix = page.events.slice(0, progress.eventCount);
|
|
23189
|
-
if (progress.fromCursor !== fromCursor || page.cursor < progress.cursor || page.events.length < progress.eventCount || pageDigest(prefix) !== progress.digest) {
|
|
23190
|
-
throw new Error("daemon notification page changed while a checkpoint was in progress");
|
|
23191
|
-
}
|
|
23192
|
-
} else {
|
|
23193
|
-
progress = push.beginNotificationPage({
|
|
23194
|
-
fromCursor,
|
|
23195
|
-
cursor: page.cursor,
|
|
23196
|
-
eventCount: page.events.length,
|
|
23197
|
-
digest: pageDigest(page.events)
|
|
23198
|
-
});
|
|
23199
|
-
}
|
|
23200
|
-
for (let index = progress.nextIndex; index < progress.eventCount; index++) {
|
|
23201
|
-
const record = page.events[index];
|
|
23202
|
-
const admission = delivery.admit(record, index + 1);
|
|
23203
|
-
if (admission.status === "saturated") {
|
|
23204
|
-
push.checkpointNotificationPage();
|
|
23205
|
-
stats.saturationEvents++;
|
|
23206
|
-
log2.warn(`event=push_cursor_blocked status=saturated source_cursor=${page.cursor}`);
|
|
23207
|
-
return false;
|
|
23208
|
-
}
|
|
23209
|
-
stats.events++;
|
|
23210
|
-
events.publish(normalizeNotification(record));
|
|
23211
|
-
if (!admission.checkpointed) push.advanceNotificationPage(index + 1);
|
|
23212
|
-
}
|
|
23213
|
-
push.commitNotificationPage();
|
|
23214
|
-
stats.cursorCommits++;
|
|
23215
|
-
return true;
|
|
23216
|
-
}
|
|
23217
|
-
function abortableWait(ms, signal) {
|
|
23218
|
-
if (signal.aborted) return Promise.resolve();
|
|
23219
|
-
return new Promise((resolve3) => {
|
|
23220
|
-
const timer = setTimeout(done, ms);
|
|
23221
|
-
function done() {
|
|
23222
|
-
clearTimeout(timer);
|
|
23223
|
-
signal.removeEventListener("abort", done);
|
|
23224
|
-
resolve3();
|
|
23225
|
-
}
|
|
23226
|
-
signal.addEventListener("abort", done, { once: true });
|
|
23227
|
-
});
|
|
23228
|
-
}
|
|
23229
|
-
function startWatcher(client, identity, push, log2, events, options) {
|
|
23230
|
-
const controller = new AbortController();
|
|
23231
|
-
const stats = { pushes: 0, events: 0, reconnects: 0, cursorCommits: 0, saturationEvents: 0 };
|
|
23232
|
-
let backoffMs = 500;
|
|
23233
|
-
let reconnecting = false;
|
|
23234
|
-
const wait = options.wait ?? abortableWait;
|
|
23235
|
-
const probe = options.probe ?? (() => client.version());
|
|
23236
|
-
const loop = (async () => {
|
|
23237
|
-
while (!controller.signal.aborted) {
|
|
23238
|
-
try {
|
|
23239
|
-
if (reconnecting) {
|
|
23240
|
-
await probe();
|
|
23241
|
-
if (controller.signal.aborted) break;
|
|
23242
|
-
events.publish({ type: "sync_required", reason: "daemon_reconnected" });
|
|
23243
|
-
reconnecting = false;
|
|
23244
|
-
}
|
|
23245
|
-
const since = push.notificationCursor ?? "tip";
|
|
23246
|
-
const page = await options.readPage(identity, since, controller.signal);
|
|
23247
|
-
if (controller.signal.aborted) break;
|
|
23248
|
-
const committed = applyNotificationPage(page, push, options.delivery, events, stats, log2);
|
|
23249
|
-
if (!committed) {
|
|
23250
|
-
await wait(backoffMs, controller.signal);
|
|
23251
|
-
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
23252
|
-
continue;
|
|
23253
|
-
}
|
|
23254
|
-
backoffMs = 500;
|
|
23255
|
-
} catch (e2) {
|
|
23256
|
-
if (controller.signal.aborted) break;
|
|
23257
|
-
stats.reconnects++;
|
|
23258
|
-
reconnecting = true;
|
|
23259
|
-
events.publish({ type: "sync_required", reason: "daemon_unavailable" });
|
|
23260
|
-
reportFailure(log2.warn, `watch stream; reconnecting in ${backoffMs}ms`, e2);
|
|
23261
|
-
await wait(backoffMs, controller.signal);
|
|
23262
|
-
backoffMs = Math.min(backoffMs * 2, 3e4);
|
|
23263
|
-
}
|
|
23264
|
-
}
|
|
23265
|
-
})();
|
|
23266
|
-
return {
|
|
23267
|
-
stats,
|
|
23268
|
-
async stop() {
|
|
23269
|
-
controller.abort();
|
|
23270
|
-
await loop;
|
|
23271
|
-
}
|
|
23272
|
-
};
|
|
23273
|
-
}
|
|
23274
|
-
|
|
23275
24060
|
// src/presence.ts
|
|
23276
24061
|
init_define_MESSENGER_BUILD_INFO();
|
|
23277
24062
|
|
|
@@ -23433,7 +24218,7 @@ function attachPresenceServer(server, registry, options) {
|
|
|
23433
24218
|
clearInterval(pinger);
|
|
23434
24219
|
server.removeListener("upgrade", upgrade);
|
|
23435
24220
|
for (const socket of wss.clients) socket.terminate();
|
|
23436
|
-
await new Promise((
|
|
24221
|
+
await new Promise((resolve4) => wss.close(() => resolve4()));
|
|
23437
24222
|
}
|
|
23438
24223
|
};
|
|
23439
24224
|
}
|
|
@@ -23480,7 +24265,7 @@ async function redirectStaleEntryAsset(req, res, appDir, pathname, basePath = "/
|
|
|
23480
24265
|
const staleEntry = /^\/assets\/index-[A-Za-z0-9_-]+\.(js|css)$/.exec(pathname);
|
|
23481
24266
|
if (!staleEntry) return false;
|
|
23482
24267
|
try {
|
|
23483
|
-
const index = (await readContainedFile(appDir,
|
|
24268
|
+
const index = (await readContainedFile(appDir, resolve3(appDir, "index.html"))).toString("utf8");
|
|
23484
24269
|
const extension2 = staleEntry[1];
|
|
23485
24270
|
const currentEntry = new RegExp(
|
|
23486
24271
|
`(?:src|href)=["'](\\.?\\/assets\\/index-[A-Za-z0-9_-]+\\.${extension2})["']`
|
|
@@ -23523,8 +24308,8 @@ async function serveApp(req, res, appDir, basePath = "/") {
|
|
|
23523
24308
|
let assetRoot = appDir;
|
|
23524
24309
|
let cacheControl = "no-cache";
|
|
23525
24310
|
if (pathname.startsWith("/assets/")) {
|
|
23526
|
-
assetRoot =
|
|
23527
|
-
const candidate =
|
|
24311
|
+
assetRoot = resolve3(appDir, "assets");
|
|
24312
|
+
const candidate = resolve3(appDir, `.${decodedPathname}`);
|
|
23528
24313
|
if (candidate !== assetRoot && !candidate.startsWith(`${assetRoot}${sep}`)) {
|
|
23529
24314
|
appNotFound(res);
|
|
23530
24315
|
return;
|
|
@@ -23532,25 +24317,25 @@ async function serveApp(req, res, appDir, basePath = "/") {
|
|
|
23532
24317
|
asset = candidate;
|
|
23533
24318
|
cacheControl = "public, max-age=31536000, immutable";
|
|
23534
24319
|
} else if (pathname.startsWith("/icons/")) {
|
|
23535
|
-
assetRoot =
|
|
23536
|
-
const candidate =
|
|
24320
|
+
assetRoot = resolve3(appDir, "icons");
|
|
24321
|
+
const candidate = resolve3(appDir, `.${decodedPathname}`);
|
|
23537
24322
|
if (candidate === assetRoot || !candidate.startsWith(`${assetRoot}${sep}`)) {
|
|
23538
24323
|
appNotFound(res);
|
|
23539
24324
|
return;
|
|
23540
24325
|
}
|
|
23541
24326
|
asset = candidate;
|
|
23542
24327
|
} else if (pathname === "/manifest.webmanifest" || pathname === "/version.json" || pathname === "/sw.js" || pathname === "/icon.svg" || pathname === "/maskable-icon.svg") {
|
|
23543
|
-
asset =
|
|
24328
|
+
asset = resolve3(appDir, pathname.slice(1));
|
|
23544
24329
|
} else if (/\.[a-z0-9]+$/i.test(pathname)) {
|
|
23545
24330
|
appNotFound(res);
|
|
23546
24331
|
return;
|
|
23547
24332
|
} else {
|
|
23548
|
-
asset =
|
|
24333
|
+
asset = resolve3(appDir, "index.html");
|
|
23549
24334
|
}
|
|
23550
24335
|
try {
|
|
23551
24336
|
let body = await readContainedFile(assetRoot, asset);
|
|
23552
24337
|
const base = normalizeBasePath(basePath);
|
|
23553
|
-
if (asset ===
|
|
24338
|
+
if (asset === resolve3(appDir, "index.html")) body = Buffer.from(prefixDocument(body.toString("utf8"), base));
|
|
23554
24339
|
if (pathname === "/manifest.webmanifest" && base !== "/") {
|
|
23555
24340
|
const manifest = JSON.parse(body.toString("utf8"));
|
|
23556
24341
|
for (const key of ["id", "start_url", "scope"]) if (typeof manifest[key] === "string") manifest[key] = base + manifest[key].replace(/^\//, "");
|
|
@@ -23561,7 +24346,7 @@ async function serveApp(req, res, appDir, basePath = "/") {
|
|
|
23561
24346
|
res.writeHead(200, appHeaders(type, cacheControl, body.length));
|
|
23562
24347
|
res.end(req.method === "HEAD" ? void 0 : body);
|
|
23563
24348
|
} catch (error) {
|
|
23564
|
-
if (asset !==
|
|
24349
|
+
if (asset !== resolve3(appDir, "index.html")) {
|
|
23565
24350
|
if (await redirectStaleEntryAsset(req, res, appDir, decodedPathname, basePath)) return;
|
|
23566
24351
|
appNotFound(res);
|
|
23567
24352
|
return;
|
|
@@ -23788,11 +24573,11 @@ async function start(cfg, buildInfo, dependencies = DEFAULT_START_DEPENDENCIES)
|
|
|
23788
24573
|
};
|
|
23789
24574
|
const moduleDir = dirname5(fileURLToPath(import.meta.url));
|
|
23790
24575
|
const appCandidates = [
|
|
23791
|
-
|
|
23792
|
-
|
|
23793
|
-
|
|
24576
|
+
resolve3(moduleDir, "../web"),
|
|
24577
|
+
resolve3(moduleDir, "../dist/web"),
|
|
24578
|
+
resolve3(moduleDir, "web")
|
|
23794
24579
|
];
|
|
23795
|
-
const appDir = process.env.OURS_MESSENGER_WEB_DIR ?? appCandidates.find((candidate) => existsSync3(
|
|
24580
|
+
const appDir = process.env.OURS_MESSENGER_WEB_DIR ?? appCandidates.find((candidate) => existsSync3(resolve3(candidate, "index.html")) && existsSync3(resolve3(candidate, "assets"))) ?? resolve3(moduleDir, "__messenger_web_not_built__");
|
|
23796
24581
|
http = createServer((req, res) => {
|
|
23797
24582
|
const pathname = new URL(req.url ?? "/", "http://localhost").pathname;
|
|
23798
24583
|
let serving;
|