@abraca/resend 2.16.0 → 2.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abracadabra-resend.cjs +60 -24
- package/dist/abracadabra-resend.cjs.map +1 -1
- package/dist/abracadabra-resend.esm.js +60 -24
- package/dist/abracadabra-resend.esm.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/package.json +3 -3
- package/src/outbox-watcher.ts +96 -12
- package/src/server.ts +35 -19
|
@@ -511,11 +511,15 @@ function readEntry(treeMap, id) {
|
|
|
511
511
|
var OutboxWatcher = class {
|
|
512
512
|
constructor(opts) {
|
|
513
513
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
514
|
-
this.handled = /* @__PURE__ */ new Set();
|
|
515
514
|
this.observer = null;
|
|
516
515
|
this.treeMap = null;
|
|
517
516
|
this.rootDoc = null;
|
|
518
517
|
this.txHandler = null;
|
|
518
|
+
this.subdocsHandler = null;
|
|
519
|
+
this.updateHandler = null;
|
|
520
|
+
this.reconnectedHandler = null;
|
|
521
|
+
this.reconnectProvider = null;
|
|
522
|
+
this.subdocHandlers = /* @__PURE__ */ new Map();
|
|
519
523
|
this.server = opts.server;
|
|
520
524
|
this.sender = opts.sender;
|
|
521
525
|
this.bootstrap = opts.bootstrap;
|
|
@@ -548,23 +552,57 @@ var OutboxWatcher = class {
|
|
|
548
552
|
rootDoc.on("afterTransaction", onTx);
|
|
549
553
|
this.txHandler = onTx;
|
|
550
554
|
const onSubdocs = (changes) => {
|
|
551
|
-
console.error(`[abracadabra-resend] subdocs: added=${changes.added.size} loaded=${changes.loaded.size}`);
|
|
552
|
-
for (const sub of
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
555
|
+
console.error(`[abracadabra-resend] subdocs: added=${changes.added.size} loaded=${changes.loaded.size} removed=${changes.removed.size}`);
|
|
556
|
+
for (const sub of changes.removed) {
|
|
557
|
+
const handler = this.subdocHandlers.get(sub);
|
|
558
|
+
if (handler) {
|
|
559
|
+
sub.off("afterTransaction", handler);
|
|
560
|
+
this.subdocHandlers.delete(sub);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
for (const sub of [...changes.added, ...changes.loaded]) {
|
|
564
|
+
if (this.subdocHandlers.has(sub)) continue;
|
|
565
|
+
const handler = (tx) => {
|
|
566
|
+
console.error(`[abracadabra-resend] subdoc afterTransaction (guid=${sub.guid}, local=${tx.local})`);
|
|
567
|
+
this.scan("subdoc");
|
|
568
|
+
};
|
|
569
|
+
sub.on("afterTransaction", handler);
|
|
570
|
+
this.subdocHandlers.set(sub, handler);
|
|
571
|
+
}
|
|
556
572
|
};
|
|
557
573
|
rootDoc.on("subdocs", onSubdocs);
|
|
558
|
-
|
|
574
|
+
this.subdocsHandler = onSubdocs;
|
|
575
|
+
const onUpdate = (_update, origin) => {
|
|
559
576
|
console.error(`[abracadabra-resend] root update applied (origin=${String(origin)})`);
|
|
560
577
|
this.scan("update");
|
|
561
|
-
}
|
|
578
|
+
};
|
|
579
|
+
rootDoc.on("update", onUpdate);
|
|
580
|
+
this.updateHandler = onUpdate;
|
|
581
|
+
const provider = this.server.rootProvider;
|
|
582
|
+
if (provider && typeof provider.on === "function") {
|
|
583
|
+
const onReconnected = () => {
|
|
584
|
+
console.error("[abracadabra-resend] provider reconnected — re-scanning");
|
|
585
|
+
this.scan("reconnected");
|
|
586
|
+
};
|
|
587
|
+
provider.on("reconnected", onReconnected);
|
|
588
|
+
this.reconnectedHandler = onReconnected;
|
|
589
|
+
this.reconnectProvider = provider;
|
|
590
|
+
}
|
|
562
591
|
console.error(`[abracadabra-resend] Outbox watcher attached (ready column ${this.bootstrap.columns.Ready})`);
|
|
563
592
|
}
|
|
564
593
|
stop() {
|
|
565
594
|
if (this.rootDoc && this.txHandler) this.rootDoc.off("afterTransaction", this.txHandler);
|
|
595
|
+
if (this.rootDoc && this.subdocsHandler) this.rootDoc.off("subdocs", this.subdocsHandler);
|
|
596
|
+
if (this.rootDoc && this.updateHandler) this.rootDoc.off("update", this.updateHandler);
|
|
597
|
+
for (const [sub, handler] of this.subdocHandlers) sub.off("afterTransaction", handler);
|
|
598
|
+
this.subdocHandlers.clear();
|
|
566
599
|
if (this.treeMap && this.observer) this.treeMap.unobserveDeep(this.observer);
|
|
600
|
+
if (this.reconnectProvider && this.reconnectedHandler) this.reconnectProvider.off("reconnected", this.reconnectedHandler);
|
|
567
601
|
this.txHandler = null;
|
|
602
|
+
this.subdocsHandler = null;
|
|
603
|
+
this.updateHandler = null;
|
|
604
|
+
this.reconnectedHandler = null;
|
|
605
|
+
this.reconnectProvider = null;
|
|
568
606
|
this.rootDoc = null;
|
|
569
607
|
this.observer = null;
|
|
570
608
|
this.treeMap = null;
|
|
@@ -591,9 +629,8 @@ var OutboxWatcher = class {
|
|
|
591
629
|
});
|
|
592
630
|
if (e.parentId !== readyColId) return;
|
|
593
631
|
inReadyCount++;
|
|
594
|
-
if (this.inFlight.has(id)
|
|
632
|
+
if (this.inFlight.has(id)) return;
|
|
595
633
|
if (typeof e.meta.resendId === "string" && e.meta.resendId.length > 0) {
|
|
596
|
-
this.handled.add(id);
|
|
597
634
|
this.moveTo(id, this.bootstrap.columns.Sent);
|
|
598
635
|
return;
|
|
599
636
|
}
|
|
@@ -613,7 +650,6 @@ var OutboxWatcher = class {
|
|
|
613
650
|
const payload = await renderEmail(this.server, id, this.defaultFrom);
|
|
614
651
|
console.error(`[abracadabra-resend] sending "${payload.subject}" → ${payload.to.join(", ")} (doc=${id})`);
|
|
615
652
|
const { id: resendId } = await this.sender.send(payload, { "X-Abra-Doc-Id": id });
|
|
616
|
-
this.handled.add(id);
|
|
617
653
|
this.patchMeta(id, {
|
|
618
654
|
resendId,
|
|
619
655
|
sentAt: Date.now(),
|
|
@@ -622,7 +658,6 @@ var OutboxWatcher = class {
|
|
|
622
658
|
this.moveTo(id, this.bootstrap.columns.Sent);
|
|
623
659
|
console.error(`[abracadabra-resend] sent "${payload.subject}" (resend=${resendId}, doc=${id})`);
|
|
624
660
|
} catch (err) {
|
|
625
|
-
this.handled.add(id);
|
|
626
661
|
const message = err instanceof RenderError ? err.message : err?.message ? String(err.message) : String(err);
|
|
627
662
|
console.error(`[abracadabra-resend] send failed for "${label}" (${id}): ${message}`);
|
|
628
663
|
this.patchMeta(id, {
|
|
@@ -1336,6 +1371,7 @@ var AbracadabraResendServer = class {
|
|
|
1336
1371
|
this._connection = null;
|
|
1337
1372
|
this.childCache = /* @__PURE__ */ new Map();
|
|
1338
1373
|
this.evictionTimer = null;
|
|
1374
|
+
this.heartbeatTimer = null;
|
|
1339
1375
|
this._userId = null;
|
|
1340
1376
|
this._signFn = null;
|
|
1341
1377
|
this._reconnecting = null;
|
|
@@ -1403,6 +1439,9 @@ var AbracadabraResendServer = class {
|
|
|
1403
1439
|
await this._connectToSpace(targetId);
|
|
1404
1440
|
console.error("[abracadabra-resend] Space doc synced");
|
|
1405
1441
|
this.evictionTimer = setInterval(() => this.evictIdle(), 6e4);
|
|
1442
|
+
this.heartbeatTimer = setInterval(() => {
|
|
1443
|
+
this.ensureConnected();
|
|
1444
|
+
}, 3e4);
|
|
1406
1445
|
}
|
|
1407
1446
|
async _connectToSpace(docId) {
|
|
1408
1447
|
if (!this.client.isTokenValid() && this._signFn && this._userId) {
|
|
@@ -1456,20 +1495,13 @@ var AbracadabraResendServer = class {
|
|
|
1456
1495
|
await waitForSync(conn.provider, 6e3);
|
|
1457
1496
|
} catch {}
|
|
1458
1497
|
if (this._wsConnected(conn.provider)) return;
|
|
1459
|
-
console.error("[abracadabra-resend]
|
|
1460
|
-
|
|
1498
|
+
console.error("[abracadabra-resend] Socket dead — forcing reconnect on the same doc…");
|
|
1499
|
+
conn.provider.reconnect();
|
|
1461
1500
|
try {
|
|
1462
|
-
conn.provider
|
|
1463
|
-
|
|
1464
|
-
for (const [, cached] of this.childCache) try {
|
|
1465
|
-
cached.provider.destroy();
|
|
1466
|
-
} catch {}
|
|
1467
|
-
this.childCache.clear();
|
|
1468
|
-
try {
|
|
1469
|
-
await this._connectToSpace(docId);
|
|
1470
|
-
console.error("[abracadabra-resend] Space provider rebuilt + synced");
|
|
1501
|
+
await waitForSync(conn.provider, 1e4);
|
|
1502
|
+
console.error("[abracadabra-resend] Reconnected + re-synced");
|
|
1471
1503
|
} catch (e) {
|
|
1472
|
-
console.error("[abracadabra-resend]
|
|
1504
|
+
console.error("[abracadabra-resend] Reconnect did not re-sync in time:", e);
|
|
1473
1505
|
}
|
|
1474
1506
|
} finally {
|
|
1475
1507
|
this._reconnecting = null;
|
|
@@ -1517,6 +1549,10 @@ var AbracadabraResendServer = class {
|
|
|
1517
1549
|
clearInterval(this.evictionTimer);
|
|
1518
1550
|
this.evictionTimer = null;
|
|
1519
1551
|
}
|
|
1552
|
+
if (this.heartbeatTimer) {
|
|
1553
|
+
clearInterval(this.heartbeatTimer);
|
|
1554
|
+
this.heartbeatTimer = null;
|
|
1555
|
+
}
|
|
1520
1556
|
for (const [, cached] of this.childCache) try {
|
|
1521
1557
|
cached.provider.destroy();
|
|
1522
1558
|
} catch {}
|