@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-UNTKMIUK.js";
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, w3;
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
- w3 = number[i] | number[i - 1] << 8 | number[i - 2] << 16;
149
- this.words[j] |= w3 << off & 67108863;
150
- this.words[j + 1] = w3 >>> 26 - off & 67108863;
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
- w3 = number[i] | number[i + 1] << 8 | number[i + 2] << 16;
160
- this.words[j] |= w3 << off & 67108863;
161
- this.words[j + 1] = w3 >>> 26 - off & 67108863;
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 w3;
196
+ var w2;
197
197
  if (endian === "be") {
198
198
  for (i = number.length - 1; i >= start2; i -= 2) {
199
- w3 = parseHexByte(number, start2, i) << off;
200
- this.words[j] |= w3 & 67108863;
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] |= w3 >>> 26;
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
- w3 = parseHexByte(number, start2, i) << off;
213
- this.words[j] |= w3 & 67108863;
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] |= w3 >>> 26;
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 w3 = this.words[i];
428
- var word = ((w3 << off | carry) & 16777215).toString(16);
429
- carry = w3 >>> 24 - off & 16777215;
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 q2 = this.clone();
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; !q2.isZero(); i++) {
516
- b2 = q2.andln(255);
517
- q2.iushrn(8);
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; !q2.isZero(); i++) {
522
- b2 = q2.andln(255);
523
- q2.iushrn(8);
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(w3) {
534
- return 32 - Math.clz32(w3);
533
+ BN.prototype._countBits = function _countBits(w2) {
534
+ return 32 - Math.clz32(w2);
535
535
  };
536
536
  } else {
537
- BN.prototype._countBits = function _countBits(w3) {
538
- var t = w3;
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(w3) {
560
- if (w3 === 0) return 26;
561
- var t = w3;
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 w3 = this.words[this.length - 1];
586
- var hi = this._countBits(w3);
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 w3 = new Array(num.bitLength());
591
- for (var bit = 0; bit < w3.length; 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
- w3[bit] = (num.words[off] & 1 << wbit) >>> wbit;
594
+ w2[bit] = (num.words[off] & 1 << wbit) >>> wbit;
595
595
  }
596
- return w3;
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 k2 = 1; k2 < len; k2++) {
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(k2, num.length - 1);
875
- for (var j = Math.max(0, k2 - self.length + 1); j <= maxJ; j++) {
876
- var i = k2 - j | 0;
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[k2] = rword | 0;
883
+ out.words[k] = rword | 0;
884
884
  carry = ncarry | 0;
885
885
  }
886
886
  if (carry !== 0) {
887
- out.words[k2] = carry | 0;
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 w22 = (c + lo | 0) + ((mid & 8191) << 13) | 0;
994
- c = (hi + (mid >>> 13) | 0) + (w22 >>> 26) | 0;
995
- w22 &= 67108863;
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] = w22;
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 k2 = 0; k2 < out.length - 1; k2++) {
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(k2, num.length - 1);
1458
- for (var j = Math.max(0, k2 - self.length + 1); j <= maxJ; j++) {
1459
- var i = k2 - j;
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[k2] = rword;
1471
+ out.words[k] = rword;
1472
1472
  carry = ncarry;
1473
1473
  ncarry = hncarry;
1474
1474
  }
1475
1475
  if (carry !== 0) {
1476
- out.words[k2] = carry;
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(x2, y3) {
1501
- this.x = x2;
1502
- this.y = y3;
1500
+ function FFTM(x, y2) {
1501
+ this.x = x;
1502
+ this.y = y2;
1503
1503
  }
1504
- FFTM.prototype.makeRBT = function makeRBT(N2) {
1505
- var t = new Array(N2);
1506
- var l = BN.prototype._countBits(N2) - 1;
1507
- for (var i = 0; i < N2; i++) {
1508
- t[i] = this.revBin(i, l, N2);
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(x2, l, N2) {
1513
- if (x2 === 0 || x2 === N2 - 1) return x2;
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 |= (x2 & 1) << l - i - 1;
1517
- x2 >>= 1;
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, N2) {
1522
- for (var i = 0; i < N2; 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, N2, rbt) {
1528
- this.permute(rbt, rws, iws, rtws, itws, N2);
1529
- for (var s = 1; s < N2; s <<= 1) {
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 < N2; p2 += l) {
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 re2 = rtws[p2 + j];
1538
- var ie2 = itws[p2 + j];
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] = re2 + ro;
1545
- itws[p2 + j] = ie2 + io;
1546
- rtws[p2 + j + s] = re2 - ro;
1547
- itws[p2 + j + s] = ie2 - io;
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, m2) {
1558
- var N2 = Math.max(m2, n) | 1;
1559
- var odd = N2 & 1;
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 (N2 = N2 / 2 | 0; N2; N2 = N2 >>> 1) {
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, N2) {
1567
- if (N2 <= 1) return;
1568
- for (var i = 0; i < N2 / 2; 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[N2 - i - 1];
1571
- rws[N2 - i - 1] = t;
1570
+ rws[i] = rws[N - i - 1];
1571
+ rws[N - i - 1] = t;
1572
1572
  t = iws[i];
1573
- iws[i] = -iws[N2 - i - 1];
1574
- iws[N2 - i - 1] = -t;
1573
+ iws[i] = -iws[N - i - 1];
1574
+ iws[N - i - 1] = -t;
1575
1575
  }
1576
1576
  };
1577
- FFTM.prototype.normalize13b = function normalize13b(ws, N2) {
1577
+ FFTM.prototype.normalize13b = function normalize13b(ws, N) {
1578
1578
  var carry = 0;
1579
- for (var i = 0; i < N2 / 2; i++) {
1580
- var w3 = Math.round(ws[2 * i + 1] / N2) * 8192 + Math.round(ws[2 * i] / N2) + carry;
1581
- ws[i] = w3 & 67108863;
1582
- if (w3 < 67108864) {
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 = w3 / 67108864 | 0;
1585
+ carry = w2 / 67108864 | 0;
1586
1586
  }
1587
1587
  }
1588
1588
  return ws;
1589
1589
  };
1590
- FFTM.prototype.convert13b = function convert13b(ws, len, rws, N2) {
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 < N2; ++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(N2) {
1606
- var ph = new Array(N2);
1607
- for (var i = 0; i < N2; 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(x2, y3, out) {
1613
- var N2 = 2 * this.guessLen13b(x2.length, y3.length);
1614
- var rbt = this.makeRBT(N2);
1615
- var _ = this.stub(N2);
1616
- var rws = new Array(N2);
1617
- var rwst = new Array(N2);
1618
- var iwst = new Array(N2);
1619
- var nrws = new Array(N2);
1620
- var nrwst = new Array(N2);
1621
- var niwst = new Array(N2);
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 = N2;
1624
- this.convert13b(x2.words, x2.length, rws, N2);
1625
- this.convert13b(y3.words, y3.length, nrws, N2);
1626
- this.transform(rws, _, rwst, iwst, N2, rbt);
1627
- this.transform(nrws, _, nrwst, niwst, N2, rbt);
1628
- for (var i = 0; i < N2; 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, N2);
1634
- this.transform(rwst, iwst, rmws, _, N2, rbt);
1635
- this.conjugate(rmws, _, N2);
1636
- this.normalize13b(rmws, N2);
1637
- out.negative = x2.negative ^ y3.negative;
1638
- out.length = x2.length + y3.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 w3 = (this.words[i] | 0) * num;
1660
- var lo = (w3 & 67108863) + (carry & 67108863);
1659
+ var w2 = (this.words[i] | 0) * num;
1660
+ var lo = (w2 & 67108863) + (carry & 67108863);
1661
1661
  carry >>= 26;
1662
- carry += w3 / 67108864 | 0;
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 w3 = toBitArray(num);
1687
- if (w3.length === 0) return new BN(1);
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 < w3.length; i++, res = res.sqr()) {
1690
- if (w3[i] !== 0) break;
1689
+ for (var i = 0; i < w2.length; i++, res = res.sqr()) {
1690
+ if (w2[i] !== 0) break;
1691
1691
  }
1692
- if (++i < w3.length) {
1693
- for (var q2 = res.sqr(); i < w3.length; i++, q2 = q2.sqr()) {
1694
- if (w3[i] === 0) continue;
1695
- res = res.mul(q2);
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 h2;
1736
+ var h3;
1737
1737
  if (hint) {
1738
- h2 = (hint - hint % 26) / 26;
1738
+ h3 = (hint - hint % 26) / 26;
1739
1739
  } else {
1740
- h2 = 0;
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
- h2 -= s;
1747
- h2 = Math.max(0, h2);
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 >= h2); 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 q2 = 1 << r;
1799
+ var q = 1 << r;
1800
1800
  if (this.length <= s) return false;
1801
- var w3 = this.words[s];
1802
- return !!(w3 & q2);
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 w3;
1898
+ var w2;
1899
1899
  var carry = 0;
1900
1900
  for (i = 0; i < num.length; i++) {
1901
- w3 = (this.words[i + shift] | 0) + carry;
1901
+ w2 = (this.words[i + shift] | 0) + carry;
1902
1902
  var right = (num.words[i] | 0) * mul;
1903
- w3 -= right & 67108863;
1904
- carry = (w3 >> 26) - (right / 67108864 | 0);
1905
- this.words[i + shift] = w3 & 67108863;
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
- w3 = (this.words[i + shift] | 0) + carry;
1909
- carry = w3 >> 26;
1910
- this.words[i + shift] = w3 & 67108863;
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
- w3 = -(this.words[i] | 0) + carry;
1917
- carry = w3 >> 26;
1918
- this.words[i] = w3 & 67108863;
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 m2 = a.length - b2.length;
1936
- var q2;
1935
+ var m3 = a.length - b2.length;
1936
+ var q;
1937
1937
  if (mode !== "mod") {
1938
- q2 = new BN(null);
1939
- q2.length = m2 + 1;
1940
- q2.words = new Array(q2.length);
1941
- for (var i = 0; i < q2.length; i++) {
1942
- q2.words[i] = 0;
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, m2);
1945
+ var diff = a.clone()._ishlnsubmul(b2, 1, m3);
1946
1946
  if (diff.negative === 0) {
1947
1947
  a = diff;
1948
- if (q2) {
1949
- q2.words[m2] = 1;
1948
+ if (q) {
1949
+ q.words[m3] = 1;
1950
1950
  }
1951
1951
  }
1952
- for (var j = m2 - 1; j >= 0; 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 (q2) {
1965
- q2.words[j] = qj;
1964
+ if (q) {
1965
+ q.words[j] = qj;
1966
1966
  }
1967
1967
  }
1968
- if (q2) {
1969
- q2.strip();
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: q2 || null,
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 w3 = (this.words[i] | 0) + carry * 67108864;
2089
- this.words[i] = w3 / num | 0;
2090
- carry = w3 % num;
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 x2 = this;
2101
- var y3 = p2.clone();
2102
- if (x2.negative !== 0) {
2103
- x2 = x2.umod(p2);
2100
+ var x = this;
2101
+ var y2 = p2.clone();
2102
+ if (x.negative !== 0) {
2103
+ x = x.umod(p2);
2104
2104
  } else {
2105
- x2 = x2.clone();
2105
+ x = x.clone();
2106
2106
  }
2107
2107
  var A2 = new BN(1);
2108
2108
  var B2 = new BN(0);
2109
- var C = new BN(0);
2109
+ var C2 = new BN(0);
2110
2110
  var D2 = new BN(1);
2111
2111
  var g2 = 0;
2112
- while (x2.isEven() && y3.isEven()) {
2113
- x2.iushrn(1);
2114
- y3.iushrn(1);
2112
+ while (x.isEven() && y2.isEven()) {
2113
+ x.iushrn(1);
2114
+ y2.iushrn(1);
2115
2115
  ++g2;
2116
2116
  }
2117
- var yp = y3.clone();
2118
- var xp = x2.clone();
2119
- while (!x2.isZero()) {
2120
- for (var i = 0, im = 1; (x2.words[0] & im) === 0 && i < 26; ++i, 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
- x2.iushrn(i);
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; (y3.words[0] & jm) === 0 && j < 26; ++j, 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
- y3.iushrn(j);
2134
+ y2.iushrn(j);
2135
2135
  while (j-- > 0) {
2136
- if (C.isOdd() || D2.isOdd()) {
2137
- C.iadd(yp);
2136
+ if (C2.isOdd() || D2.isOdd()) {
2137
+ C2.iadd(yp);
2138
2138
  D2.isub(xp);
2139
2139
  }
2140
- C.iushrn(1);
2140
+ C2.iushrn(1);
2141
2141
  D2.iushrn(1);
2142
2142
  }
2143
2143
  }
2144
- if (x2.cmp(y3) >= 0) {
2145
- x2.isub(y3);
2146
- A2.isub(C);
2144
+ if (x.cmp(y2) >= 0) {
2145
+ x.isub(y2);
2146
+ A2.isub(C2);
2147
2147
  B2.isub(D2);
2148
2148
  } else {
2149
- y3.isub(x2);
2150
- C.isub(A2);
2149
+ y2.isub(x);
2150
+ C2.isub(A2);
2151
2151
  D2.isub(B2);
2152
2152
  }
2153
2153
  }
2154
2154
  return {
2155
- a: C,
2155
+ a: C2,
2156
2156
  b: D2,
2157
- gcd: y3.iushln(g2)
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 q2 = 1 << r;
2259
+ var q = 1 << r;
2260
2260
  if (this.length <= s) {
2261
2261
  this._expand(s + 1);
2262
- this.words[s] |= q2;
2262
+ this.words[s] |= q;
2263
2263
  return this;
2264
2264
  }
2265
- var carry = q2;
2265
+ var carry = q;
2266
2266
  for (var i = s; carry !== 0 && i < this.length; i++) {
2267
- var w3 = this.words[i] | 0;
2268
- w3 += carry;
2269
- carry = w3 >>> 26;
2270
- w3 &= 67108863;
2271
- this.words[i] = w3;
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 w3 = this.words[0] | 0;
2296
- res = w3 === num ? 0 : w3 < num ? -1 : 1;
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 w3 = num.words[i] | 0;
2525
- lo += w3 * 977;
2524
+ var w2 = num.words[i] | 0;
2525
+ lo += w2 * 977;
2526
2526
  num.words[i] = lo & 67108863;
2527
- lo = w3 * 64 + (lo / 67108864 | 0);
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(m2) {
2593
- if (typeof m2 === "string") {
2594
- var prime = BN._prime(m2);
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(m2.gtn(1), "modulus must be greater than 1");
2599
- this.m = m2;
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 q2 = this.m.subn(1);
2682
+ var q = this.m.subn(1);
2683
2683
  var s = 0;
2684
- while (!q2.isZero() && q2.andln(1) === 0) {
2684
+ while (!q.isZero() && q.andln(1) === 0) {
2685
2685
  s++;
2686
- q2.iushrn(1);
2686
+ q.iushrn(1);
2687
2687
  }
2688
- assert(!q2.isZero());
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 z = this.m.bitLength();
2693
- z = new BN(2 * z * z).toRed(this);
2694
- while (this.pow(z, lpow).cmp(nOne) !== 0) {
2695
- z.redIAdd(nOne);
2696
- }
2697
- var c = this.pow(z, q2);
2698
- var r = this.pow(a, q2.addn(1).iushrn(1));
2699
- var t = this.pow(a, q2);
2700
- var m2 = s;
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 < m2);
2707
- var b2 = this.pow(c, new BN(1).iushln(m2 - i - 1));
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
- m2 = i;
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(m2) {
2777
- Red.call(this, m2);
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 u3 = t.isub(c).iushrn(this.shift);
2807
- var res = u3;
2808
- if (u3.cmp(this.m) >= 0) {
2809
- res = u3.isub(this.m);
2810
- } else if (u3.cmpn(0) < 0) {
2811
- res = u3.iadd(this.m);
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 u3 = t.isub(c).iushrn(this.shift);
2820
- var res = u3;
2821
- if (u3.cmp(this.m) >= 0) {
2822
- res = u3.isub(this.m);
2823
- } else if (u3.cmpn(0) < 0) {
2824
- res = u3.iadd(this.m);
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 re2 = /^-----(BEGIN|END) ([^-]+)-----$/;
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(re2);
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(m2, k2) {
5483
- console.warn(m2 + " [" + k2.length + "]: " + k2.toString("base64url"));
5484
- return k2;
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(m2, k2) {
5488
- return k2;
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 m2 = nonce.readUIntBE(nonce.length - 6, 6);
5718
- var x2 = ((m2 ^ counter) & 16777215) + ((m2 / 16777216 ^ counter / 16777216) & 16777215) * 16777216;
5719
- nonce.writeUIntBE(x2, nonce.length - 6, 6);
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 m2 = s * 60;
5997
- var h2 = m2 * 60;
5998
- var d2 = h2 * 24;
5999
- var w3 = d2 * 7;
6000
- var y3 = d2 * 365.25;
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 * y3;
6032
+ return n * y2;
6033
6033
  case "weeks":
6034
6034
  case "week":
6035
6035
  case "w":
6036
- return n * w3;
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 * h2;
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 * m2;
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 >= h2) {
6075
- return Math.round(ms / h2) + "h";
6074
+ if (msAbs >= h3) {
6075
+ return Math.round(ms / h3) + "h";
6076
6076
  }
6077
- if (msAbs >= m2) {
6078
- return Math.round(ms / m2) + "m";
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 >= h2) {
6091
- return plural(ms, msAbs, h2, "hour");
6090
+ if (msAbs >= h3) {
6091
+ return plural(ms, msAbs, h3, "hour");
6092
6092
  }
6093
- if (msAbs >= m2) {
6094
- return plural(ms, msAbs, m2, "minute");
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: (v2) => {
6194
- enableOverride = v2;
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 m2;
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 && (m2 = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m2[1], 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
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(v2) {
6447
+ formatters.j = function(v3) {
6448
6448
  try {
6449
- return JSON.stringify(v2);
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, (_, k2) => {
6563
- return k2.toUpperCase();
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(v2) {
6621
+ formatters.o = function(v3) {
6622
6622
  this.inspectOpts.colors = this.useColors;
6623
- return util.inspect(v2, this.inspectOpts).split("\n").map((str2) => str2.trim()).join(" ");
6623
+ return util.inspect(v3, this.inspectOpts).split("\n").map((str2) => str2.trim()).join(" ");
6624
6624
  };
6625
- formatters.O = function(v2) {
6625
+ formatters.O = function(v3) {
6626
6626
  this.inspectOpts.colors = this.useColors;
6627
- return util.inspect(v2, this.inspectOpts);
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, m2, k2, k22) {
6650
- if (k22 === void 0) k22 = k2;
6651
- var desc = Object.getOwnPropertyDescriptor(m2, k2);
6652
- if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
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 m2[k2];
6654
+ return m3[k];
6655
6655
  } };
6656
6656
  }
6657
- Object.defineProperty(o, k22, desc);
6658
- }) : (function(o, m2, k2, k22) {
6659
- if (k22 === void 0) k22 = k2;
6660
- o[k22] = m2[k2];
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, v2) {
6663
- Object.defineProperty(o, "default", { enumerable: true, value: v2 });
6664
- }) : function(o, v2) {
6665
- o["default"] = v2;
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 k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
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((resolve3, reject) => {
6706
- req2.once("response", resolve3).once("error", reject).end();
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, m2, k2, k22) {
6721
- if (k22 === void 0) k22 = k2;
6722
- var desc = Object.getOwnPropertyDescriptor(m2, k2);
6723
- if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
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 m2[k2];
6725
+ return m3[k];
6726
6726
  } };
6727
6727
  }
6728
- Object.defineProperty(o, k22, desc);
6729
- }) : (function(o, m2, k2, k22) {
6730
- if (k22 === void 0) k22 = k2;
6731
- o[k22] = m2[k2];
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, v2) {
6734
- Object.defineProperty(o, "default", { enumerable: true, value: v2 });
6735
- }) : function(o, v2) {
6736
- o["default"] = v2;
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 k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
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(m2, exports2) {
6748
- for (var p2 in m2) if (p2 !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p2)) __createBinding(exports2, m2, p2);
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(v2) {
6854
+ set defaultPort(v3) {
6855
6855
  if (this[INTERNAL]) {
6856
- this[INTERNAL].defaultPort = v2;
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(v2) {
6862
+ set protocol(v3) {
6863
6863
  if (this[INTERNAL]) {
6864
- this[INTERNAL].protocol = v2;
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((resolve3, reject) => {
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
- resolve3({
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, m2, k2, k22) {
6975
- if (k22 === void 0) k22 = k2;
6976
- var desc = Object.getOwnPropertyDescriptor(m2, k2);
6977
- if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
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 m2[k2];
6979
+ return m3[k];
6980
6980
  } };
6981
6981
  }
6982
- Object.defineProperty(o, k22, desc);
6983
- }) : (function(o, m2, k2, k22) {
6984
- if (k22 === void 0) k22 = k2;
6985
- o[k22] = m2[k2];
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, v2) {
6988
- Object.defineProperty(o, "default", { enumerable: true, value: v2 });
6989
- }) : function(o, v2) {
6990
- o["default"] = v2;
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 k2 in mod) if (k2 !== "default" && Object.prototype.hasOwnProperty.call(mod, k2)) __createBinding(result, mod, k2);
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(resolve3, reject) {
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
- resolve3({
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((k2) => {
9660
- let values = params[k2];
9659
+ Object.keys(params).map((k) => {
9660
+ let values = params[k];
9661
9661
  if (!Array.isArray(values)) values = [values];
9662
- return values.map((v2) => v2 === true ? k2 : `${k2}=${v2}`).join("; ");
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((h2) => `${h2}: ${headers[h2]}`).join("\r\n") + "\r\n\r\n" + message
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 resolve2, sep } from "node:path";
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 = createHash("sha256").update(canonical({
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/media-response.ts
11952
- init_define_MESSENGER_BUILD_INFO();
11953
- var INLINE_MEDIA = /^(?:image\/(?:avif|gif|jpeg|png|webp)|audio\/[a-z0-9.+-]+|video\/[a-z0-9.+-]+)$/;
11954
- function mediaResponsePolicy(mime2) {
11955
- const declared = mime2.toLowerCase().split(";", 1)[0].trim();
11956
- return INLINE_MEDIA.test(declared) ? { mime: declared, disposition: "inline" } : { mime: "application/octet-stream", disposition: "attachment" };
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
- // src/events.ts
11960
- init_define_MESSENGER_BUILD_INFO();
11961
- var nonEmpty2 = (value) => typeof value === "string" && value.length > 0;
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
- if (record.event === "receipt_received") {
11975
- const kind = record.kind;
11976
- const wireIds = record.wire_ids;
11977
- if (!nonEmpty2(record.sender_id) || kind !== "delivered" && kind !== "read" || !Array.isArray(wireIds) || !wireIds.every(nonEmpty2)) {
11978
- return { type: "sync_required", reason: "legacy_event" };
11979
- }
11980
- return {
11981
- type: "receipt_received",
11982
- contact_id: record.sender_id,
11983
- kind,
11984
- wire_ids: [...wireIds],
11985
- // Receipt time is not present in the currently published actor contract.
11986
- // A fixed actor should supply it; observation time is the explicit fallback.
11987
- date: nonEmpty2(record.date) ? record.date : (/* @__PURE__ */ new Date()).toISOString()
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
- if (record.event === "file_received") {
11991
- if (!nonEmpty2(record.sender_id) || !nonEmpty2(record.wire_id) || !nonEmpty2(record.date)) {
11992
- return { type: "sync_required", reason: "legacy_event" };
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
- return {
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
- return { type: "sync_required", reason: "unknown_event" };
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
- var MessengerEventBus = class {
12004
- #subscribers = /* @__PURE__ */ new Set();
12005
- get size() {
12006
- return this.#subscribers.size;
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
- subscribe(limit = 64) {
12009
- if (!Number.isInteger(limit) || limit < 1) throw new Error("subscriber queue limit must be a positive integer");
12010
- const sub = { limit, queue: [], waiting: null, closed: false, overflowed: false };
12011
- this.#subscribers.add(sub);
12012
- return {
12013
- next: () => {
12014
- if (sub.queue.length > 0) {
12015
- const event = sub.queue.shift();
12016
- if (event.type === "sync_required" && event.reason === "overflow") sub.overflowed = false;
12017
- return Promise.resolve(event);
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 (sub.closed) return Promise.resolve(null);
12020
- if (sub.waiting) throw new Error("only one pending next() is allowed per event subscriber");
12021
- return new Promise((resolve3) => {
12022
- sub.waiting = resolve3;
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
- close: () => this.#close(sub)
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
- publish(event) {
12029
- for (const sub of this.#subscribers) {
12030
- if (sub.closed) continue;
12031
- if (sub.waiting) {
12032
- const resolve3 = sub.waiting;
12033
- sub.waiting = null;
12034
- resolve3(event);
12035
- continue;
12036
- }
12037
- if (sub.overflowed) continue;
12038
- if (sub.queue.length >= sub.limit) {
12039
- sub.queue.splice(0, sub.queue.length, { type: "sync_required", reason: "overflow" });
12040
- sub.overflowed = true;
12041
- continue;
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
- sub.queue.push(event);
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
- function toSse(event, identity) {
12060
- if (event.type === "sync_required") {
12061
- return {
12062
- event: event.type,
12063
- data: { v: 1, reason: event.reason, ...identity ? { identity } : {} }
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 createHash2 } from "node:crypto";
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 createHash2("sha256").update(canonical2(input)).digest("base64url");
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-${createHash2("sha256").update(identityCid).digest("hex").slice(0, 24)}.json`);
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 ? "&quot;" : char === 38 ? "&amp;" : char === 39 ? "&apos;" : char === 60 ? "&lt;" : char === 62 ? "&gt;" : "&nbsp;";
20279
20971
  }
20280
- function escapeWithRegex(re2, data) {
20281
- re2.lastIndex = 0;
20282
- if (!re2.test(data))
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 = re2.lastIndex - 1;
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 (re2.test(data));
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 = (m2) => new HttpError(400, m2);
21272
+ var bad = (m3) => new HttpError(400, m3);
20566
21273
  function str(body, key) {
20567
- const v2 = body[key];
20568
- if (typeof v2 !== "string" || v2 === "") throw bad(`${key} must be a non-empty string`);
20569
- return v2;
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 v2 = body[key];
20573
- if (v2 === void 0 || v2 === null) return void 0;
20574
- if (typeof v2 !== "string" || v2 === "") throw bad(`${key}, when present, must be a non-empty string`);
20575
- return v2;
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 v2 = body[key];
20579
- if (v2 === void 0 || v2 === null) return void 0;
20580
- if (typeof v2 !== "boolean") throw bad(`${key}, when present, must be a boolean`);
20581
- return v2;
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((resolve3) => {
20848
- releaseDrain = resolve3;
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 }) => ({ ...publicIdentity(await client.currentIdentity()), humanProfile: readHumanProfile(deps.config.stateDir, deps.identityCid) }),
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((k2) => typeof challenge[k2] === "string" && /^[A-Za-z0-9_-]{43}$/.test(String(challenge[k2]))) || !Number.isFinite(challenge.expiresAt) || Number(challenge.expiresAt) <= Date.now() || Number(challenge.expiresAt) > Date.now() + 16 * 6e4) throw bad("Workspace challenge expired or invalid");
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((resolve3) => setTimeout(resolve3, 100));
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((v2) => typeof v2 === "string" && v2 !== "")) {
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 k2 = keys;
21320
- if (typeof k2.p256dh !== "string" || typeof k2.auth !== "string") {
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: k2.p256dh, auth: k2.auth },
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 [m2, pattern] = key.split(" ");
21400
- if (m2 !== method) continue;
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-W33OG3IH.js
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 O2 = e.openSync(c, e.constants.O_RDONLY | e.constants.O_DIRECTORY | e.constants.O_NOFOLLOW);
22339
+ let O = e.openSync(c, e.constants.O_RDONLY | e.constants.O_DIRECTORY | e.constants.O_NOFOLLOW);
21516
22340
  try {
21517
- e.fsyncSync(O2);
22341
+ e.fsyncSync(O);
21518
22342
  } finally {
21519
- e.closeSync(O2);
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-W33OG3IH.js
21575
- import { homedir as me } from "node:os";
21576
- import { isAbsolute as ye, join as ge, resolve as ne } from "node:path";
21577
- import { randomBytes as V } from "node:crypto";
21578
- import { readFileSync as Ee } from "node:fs";
21579
- import { homedir as ve } from "node:os";
21580
- import { join as M2, resolve as P } from "node:path";
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 U = () => new d("INVALID_OBSERVATION", "Terminal observation must match this external owner instance and contain valid process evidence.");
21590
- function y2(e2) {
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 u2(e2, t) {
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 R2(e2) {
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 F(e2) {
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 N(e2, t) {
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 U();
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 w2 = (e2) => typeof e2 == "string" && e2.length > 0;
21640
- var $3 = (e2) => ({ event: "sync_required", reason: "legacy_or_malformed_event", source_event: e2 });
21641
- function te(e2) {
21642
- if (!w2(e2.event)) return $3("unknown");
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" ? $3("contact_removed") : { event: "contact_removed", identity_cid: e2.identity_cid, cid: e2.cid, by: e2.by };
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 !w2(e2.sender_id) || !w2(e2.sender_name) || !w2(e2.msg_id) || !w2(e2.wire_id) || !w2(e2.date) ? $3("message_received") : { event: "message_received", sender_id: e2.sender_id, sender_name: e2.sender_name, from: w2(e2.from) ? e2.from : e2.sender_name, msg_id: e2.msg_id, wire_id: e2.wire_id, date: e2.date };
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 !w2(e2.sender_id) || t !== "delivered" && t !== "read" || !Array.isArray(n) || n.length === 0 || !n.every(w2) ? $3("receipt_received") : { event: "receipt_received", sender_id: e2.sender_id, kind: t, wire_ids: [...n], date: w2(e2.date) ? e2.date : (/* @__PURE__ */ new Date()).toISOString() };
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 fe = { event: () => {
22478
+ var ve = { event: () => {
21655
22479
  }, notification: () => {
21656
22480
  } };
21657
- var xt = { ...fe };
21658
- function q(e2, t = /* @__PURE__ */ new Set()) {
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) => q(r, t)) : Object.getPrototypeOf(e2) === Object.prototype && Object.values(e2).every((r) => q(r, t));
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 x = class {
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 = y2(t.url), this.sessionMode = t.sessionMode ?? "local", this.sessionMode !== "local" && this.sessionMode !== "external") throw new Error("Invalid sessionMode");
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) === u2(this.base, "/api/v1/releaseLease"), s = [i?.signal, o ? t.requestSignal ? AbortSignal.timeout(5e3) : void 0 : t.requestSignal].filter((a) => a != null);
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(u2(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;
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 F(i) : o = await i.json();
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: m2, details: f } = s;
21708
- throw new d(l, m2, f);
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(u2(this.base, t), { redirect: "error", headers: n ? this.headers() : {} }), i;
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 U();
21758
- N(n, this.leaseToken);
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, m2 = l.command, f = this.commandHandlers.get(m2);
21854
- if (!f) throw new Error("handler not registered");
21855
- let g2 = Object.freeze({ sender_cid: s.from.id, sender_name: s.from.name, request_wire_id: s.wire_id }), E2 = await f(l.arguments, g2);
21856
- if (!q(E2)) throw new Error("handler returned a non-JSON value");
21857
- a = { ok: true, result: E2 };
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(u2(this.base, r + "?since=" + encodeURIComponent(String(n.since ?? "tip")) + i), { redirect: "error", headers: this.headers(), signal: o }), a;
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(u2(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)]) });
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 te(a && typeof a == "object" ? a : {});
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(u2(this.base, `/files/${encodeURIComponent(t)}`), { redirect: "error", headers: this.headers() });
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(u2(this.base, `/files/${encodeURIComponent(t)}`), { redirect: "error", headers: this.headers() });
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(u2(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" } });
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 O = class extends Error {
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 he(e2 = process.env) {
22875
+ function Te(e2 = process.env) {
21985
22876
  if (e2.OURS_CONFIG !== void 0) {
21986
- if (!e2.OURS_CONFIG.trim()) throw new O("OURS_CONFIG must name a client profile");
21987
- return ne(e2.OURS_CONFIG);
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 ge(e2.HOME || me(), ".ours-client", "profile.json");
22880
+ return _e(e2.HOME || Ie(), ".ours-client", "profile.json");
21990
22881
  }
21991
- function we(e2) {
22882
+ function Oe(e2) {
21992
22883
  let t = (o) => {
21993
- throw new O(o);
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 = y2(n.serverUrl);
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" || y2(n.endpoint) !== i) return t("endpoint must equal serverUrl/daemon; remove stale endpoint overrides");
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" || !ye(n.credentialPath) || ne(n.credentialPath) !== n.credentialPath ? t("credentialPath must be an absolute normalized path") : Object.freeze({ serverUrl: r, endpoint: i, expectedInstanceId: n.expectedInstanceId, credentialPath: n.credentialPath });
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 re(e2 = process.env) {
22014
- let t = he(e2), n;
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 O("selected profile is missing, invalid JSON or unsafe; require a 0700 directory and a 0600 regular file");
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 = we(n);
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 O("remove legacy OURS_PORT/STATE_DIR/API_TOKEN/DAEMON_ID/DAEMON_URL/DAEMON_CREDENTIAL_PATH environment selectors");
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 B = class extends p {
22922
+ var W = class extends p {
22032
22923
  constructor(n, r, i = {}) {
22033
- super("DAEMON_UNAVAILABLE", `no ours daemon is running at ${R2(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.`);
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 oe = K.port;
22040
- var J = $2;
22041
- var _e = ".ours";
22042
- var Ie = ["explicit", "environment", "config-file"];
22043
- function Oe(e2 = {}) {
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 ?? ((E2) => Ee(E2, "utf8")), r = e2.homeDir ?? ve(), i = k(t, "OURS_INSTANCE");
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 E2 = P(e2.stateDir), T2 = P(e2.expectStateDir);
22051
- if (E2 !== T2) throw new p("INCOHERENT_SELECTION", `stateDir ${JSON.stringify(E2)} and expectStateDir ${JSON.stringify(T2)} 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.`);
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 = Re(e2.configPath, k(t, "OURS_CONFIG")), s = o ? Se(o.value, n) : {}, a = ie(e2.port, Ae(k(t, "OURS_PORT")), s.port, oe), c = ie(e2.stateDir ?? e2.expectStateDir, k(t, "OURS_STATE_DIR"), s.stateDir, M2(r, _e)), l = { value: P(c.value), source: c.source }, m2 = e2.endpoint !== void 0 ? { value: y2(e2.endpoint), source: "explicit" } : { value: `http://127.0.0.1:${a.value}`, source: a.source }, f = k(t, "OURS_API_TOKEN");
22054
- Te({ endpointSelected: e2.endpoint !== void 0 || a.source !== "default", endpointSource: m2.source, stateDirIntentional: Ie.includes(l.source), stateDirSource: l.source, hasExplicitToken: e2.token !== void 0 && e2.token !== "", hasEnvToken: f !== void 0, requireExplicitSelection: e2.requireExplicitSelection === true, portSource: a.source });
22055
- let g2 = be(e2.token, f, s, l, e2.readTextFile);
22056
- return { baseUrl: m2, port: a, stateDir: l, expectStateDir: e2.expectStateDir !== void 0 ? P(e2.expectStateDir) : l.value, ...g2 ? { token: g2 } : {}, ...o ? { configPath: o } : {} };
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 Te(e2) {
22949
+ function ke(e2) {
22059
22950
  if (e2.requireExplicitSelection) {
22060
- if (e2.endpointSource === "default" && e2.portSource === "default") throw D(`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:${oe}.`);
22061
- if (!e2.stateDirIntentional) throw D("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.");
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 D(`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.`);
22064
- if (e2.hasEnvToken && !e2.stateDirIntentional) throw D("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.");
22065
- if (e2.hasExplicitToken && !e2.stateDirIntentional) throw D("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.");
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 D(e2) {
22958
+ function F(e2) {
22068
22959
  return new p("INCOHERENT_SELECTION", e2);
22069
22960
  }
22070
- function be(e2, t, n, r, i) {
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(M2(r.value, J), false);
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(M2(r.value, J)).trim();
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 Se(e2, t) {
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 k(e2, t) {
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 Ae(e2) {
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 ie(e2, t, n, r) {
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 Re(e2, t) {
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 Ne(e2, t = {}) {
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(u2(e2.baseUrl.value, "/state-dir"), { signal: r.signal, redirect: "error" });
22144
- if (!a.ok) throw new p("INCOHERENT_SELECTION", `${R2(u2(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.`);
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 B(e2.baseUrl.value, e2.expectStateDir, { cause: a });
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" ? P(o.stateDir) : null;
22152
- if (s === null) throw new p("INCOHERENT_SELECTION", `${R2(u2(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.`);
22153
- if (s !== e2.expectStateDir) throw new p("INCOHERENT_SELECTION", `the daemon at ${R2(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.`);
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 G(e2 = {}) {
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 = re({ ...e2.env ?? process.env, ...e2.configPath === void 0 ? {} : { OURS_CONFIG: e2.configPath } });
22158
- return G({ ...e2, endpoint: g2.endpoint, expectedInstanceId: g2.expectedInstanceId, credentialPath: g2.credentialPath, sessionMode: "external", leaseToken: e2.leaseToken ?? V(32).toString("hex"), env: {} });
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, ...m2 } = e2;
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 || m2.token !== void 0)) throw new Error("Credential path requires explicit daemon identity and cannot be combined with a token");
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: E2 } = m2;
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 T2 = y2(g2);
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 _ = [...c ?? ["external-sessions-v1"]];
22178
- if (!_.length || _.some((b2) => typeof b2 != "string" || !b2.trim())) throw new Error("Instance selection requires a nonempty capability list");
22179
- if (i === "external") _.includes("external-sessions-v1") || _.push("external-sessions-v1");
22180
- else if (_.includes("external-sessions-v1")) throw new Error("External capabilities require explicit sessionMode: external; refusing local-mode fallback");
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 b2 = await globalThis.fetch(u2(T2, "/selection"), { signal: s ? AbortSignal.any([s, AbortSignal.timeout(5e3)]) : AbortSignal.timeout(5e3), redirect: "error" }), I2 = await F(b2);
22183
- if (!b2.ok || !I2 || Object.keys(I2).length !== 3 || Object.keys(I2).some((S2) => !["schema", "instanceId", "capabilities"].includes(S2)) || I2.schema !== 1 || I2.instanceId !== a) throw new Error("Daemon instance selection metadata is absent, incompatible or mismatched");
22184
- let j = I2.capabilities;
22185
- if (!Array.isArray(j) || j.some((S2) => typeof S2 != "string") || _.some((S2) => !j.includes(S2))) throw new Error("Daemon does not support the required capabilities; refusing local-mode fallback");
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 H = l === void 0 ? E2 : S(l);
22188
- if (typeof H != "string" || !H.trim()) throw new Error("Instance selection requires an explicit API token after daemon verification");
22189
- return new x({ url: T2, sessionMode: i, requestSignal: s, ...l === void 0 ? { apiToken: H } : { credentialPath: l }, leaseToken: n ?? V(32).toString("hex"), clientPid: r });
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 f = Oe(m2);
22193
- return await Ne(f, { fetch: o }), new x({ url: f.baseUrl.value, leaseToken: n ?? V(32).toString("hex"), clientPid: r, ...f.token?.source === "token-file" && m2.readTextFile === void 0 ? { credentialPath: M2(f.expectStateDir, J) } : { apiToken: f.token?.value }, fetch: o, requestSignal: s });
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) || resolve(stateDir) !== 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 = G) {
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 createHash3, randomUUID as randomUUID2, timingSafeEqual } from "node:crypto";
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 createHash3("sha256").update(publicKey).digest("base64url");
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: randomUUID2(),
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 ?? randomUUID2();
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-${randomUUID2()}`;
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((resolve3) => wss.close(() => resolve3()));
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, resolve2(appDir, "index.html"))).toString("utf8");
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 = resolve2(appDir, "assets");
23527
- const candidate = resolve2(appDir, `.${decodedPathname}`);
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 = resolve2(appDir, "icons");
23536
- const candidate = resolve2(appDir, `.${decodedPathname}`);
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 = resolve2(appDir, pathname.slice(1));
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 = resolve2(appDir, "index.html");
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 === resolve2(appDir, "index.html")) body = Buffer.from(prefixDocument(body.toString("utf8"), base));
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 !== resolve2(appDir, "index.html")) {
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
- resolve2(moduleDir, "../web"),
23792
- resolve2(moduleDir, "../dist/web"),
23793
- resolve2(moduleDir, "web")
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(resolve2(candidate, "index.html")) && existsSync3(resolve2(candidate, "assets"))) ?? resolve2(moduleDir, "__messenger_web_not_built__");
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;