@btravstack/outbox 0.19.0 → 0.20.0
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/index.cjs +13 -18
- package/dist/index.d.cts +4 -3
- package/dist/index.d.mts +4 -3
- package/dist/index.mjs +13 -18
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -99,24 +99,18 @@ const startRelay = (store, publisher, observers, clock, { tenants, pollMs }) =>
|
|
|
99
99
|
}))))).isOk() ? swept : "failed";
|
|
100
100
|
};
|
|
101
101
|
const backoff = (failures) => Math.min(pollMs * 2 ** failures, Math.max(pollMs, MAX_BACKOFF_MS));
|
|
102
|
-
const running = (async () => {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
due: clock.now(),
|
|
106
|
-
failures: 0
|
|
107
|
-
}));
|
|
102
|
+
const running = Promise.all(tenants.map(async (tenantId) => {
|
|
103
|
+
let due = clock.now();
|
|
104
|
+
let failures = 0;
|
|
108
105
|
while (!signal.aborted) {
|
|
109
|
-
|
|
110
|
-
if (signal.aborted) break;
|
|
111
|
-
if (tenant.due > clock.now()) continue;
|
|
112
|
-
const swept = await sweep(tenant.tenantId);
|
|
113
|
-
tenant.failures = swept === "failed" ? tenant.failures + 1 : 0;
|
|
114
|
-
tenant.due = clock.now() + (swept === "full" ? 0 : backoff(tenant.failures));
|
|
115
|
-
}
|
|
116
|
-
const wait = Math.min(...schedule.map(({ due }) => due)) - clock.now();
|
|
106
|
+
const wait = due - clock.now();
|
|
117
107
|
if (wait > 0) await clock.sleep(wait, signal);
|
|
108
|
+
if (signal.aborted) break;
|
|
109
|
+
const swept = await sweep(tenantId);
|
|
110
|
+
failures = swept === "failed" ? failures + 1 : 0;
|
|
111
|
+
due = clock.now() + (swept === "full" ? 0 : backoff(failures));
|
|
118
112
|
}
|
|
119
|
-
})
|
|
113
|
+
}));
|
|
120
114
|
return { stop: () => (0, unthrown.fromSafePromise)((async () => {
|
|
121
115
|
stopping.abort();
|
|
122
116
|
await running;
|
|
@@ -142,9 +136,10 @@ const startRelay = (store, publisher, observers, clock, { tenants, pollMs }) =>
|
|
|
142
136
|
*
|
|
143
137
|
* **A refused publish stops the tenant's batch** and backs that tenant off,
|
|
144
138
|
* doubling from the poll interval to 30 seconds, so a later fact never
|
|
145
|
-
* overtakes an earlier one
|
|
146
|
-
*
|
|
147
|
-
*
|
|
139
|
+
* overtakes an earlier one. Each tenant has its own loop, so a pending claim
|
|
140
|
+
* or publish holds only that tenant. A message the publisher refuses forever
|
|
141
|
+
* therefore holds its tenant's outbox — which is what the health check is for:
|
|
142
|
+
* it reports a tenant whose oldest pending message is older than `maxLagMs`.
|
|
148
143
|
*
|
|
149
144
|
* Started as the graph builds, before the runtime accepts anything, and
|
|
150
145
|
* stopped when the application scope closes, after the runtime has drained.
|
package/dist/index.d.cts
CHANGED
|
@@ -49,9 +49,10 @@ type OutboxOptions = {
|
|
|
49
49
|
*
|
|
50
50
|
* **A refused publish stops the tenant's batch** and backs that tenant off,
|
|
51
51
|
* doubling from the poll interval to 30 seconds, so a later fact never
|
|
52
|
-
* overtakes an earlier one
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* overtakes an earlier one. Each tenant has its own loop, so a pending claim
|
|
53
|
+
* or publish holds only that tenant. A message the publisher refuses forever
|
|
54
|
+
* therefore holds its tenant's outbox — which is what the health check is for:
|
|
55
|
+
* it reports a tenant whose oldest pending message is older than `maxLagMs`.
|
|
55
56
|
*
|
|
56
57
|
* Started as the graph builds, before the runtime accepts anything, and
|
|
57
58
|
* stopped when the application scope closes, after the runtime has drained.
|
package/dist/index.d.mts
CHANGED
|
@@ -49,9 +49,10 @@ type OutboxOptions = {
|
|
|
49
49
|
*
|
|
50
50
|
* **A refused publish stops the tenant's batch** and backs that tenant off,
|
|
51
51
|
* doubling from the poll interval to 30 seconds, so a later fact never
|
|
52
|
-
* overtakes an earlier one
|
|
53
|
-
*
|
|
54
|
-
*
|
|
52
|
+
* overtakes an earlier one. Each tenant has its own loop, so a pending claim
|
|
53
|
+
* or publish holds only that tenant. A message the publisher refuses forever
|
|
54
|
+
* therefore holds its tenant's outbox — which is what the health check is for:
|
|
55
|
+
* it reports a tenant whose oldest pending message is older than `maxLagMs`.
|
|
55
56
|
*
|
|
56
57
|
* Started as the graph builds, before the runtime accepts anything, and
|
|
57
58
|
* stopped when the application scope closes, after the runtime has drained.
|
package/dist/index.mjs
CHANGED
|
@@ -98,24 +98,18 @@ const startRelay = (store, publisher, observers, clock, { tenants, pollMs }) =>
|
|
|
98
98
|
}))))).isOk() ? swept : "failed";
|
|
99
99
|
};
|
|
100
100
|
const backoff = (failures) => Math.min(pollMs * 2 ** failures, Math.max(pollMs, MAX_BACKOFF_MS));
|
|
101
|
-
const running = (async () => {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
due: clock.now(),
|
|
105
|
-
failures: 0
|
|
106
|
-
}));
|
|
101
|
+
const running = Promise.all(tenants.map(async (tenantId) => {
|
|
102
|
+
let due = clock.now();
|
|
103
|
+
let failures = 0;
|
|
107
104
|
while (!signal.aborted) {
|
|
108
|
-
|
|
109
|
-
if (signal.aborted) break;
|
|
110
|
-
if (tenant.due > clock.now()) continue;
|
|
111
|
-
const swept = await sweep(tenant.tenantId);
|
|
112
|
-
tenant.failures = swept === "failed" ? tenant.failures + 1 : 0;
|
|
113
|
-
tenant.due = clock.now() + (swept === "full" ? 0 : backoff(tenant.failures));
|
|
114
|
-
}
|
|
115
|
-
const wait = Math.min(...schedule.map(({ due }) => due)) - clock.now();
|
|
105
|
+
const wait = due - clock.now();
|
|
116
106
|
if (wait > 0) await clock.sleep(wait, signal);
|
|
107
|
+
if (signal.aborted) break;
|
|
108
|
+
const swept = await sweep(tenantId);
|
|
109
|
+
failures = swept === "failed" ? failures + 1 : 0;
|
|
110
|
+
due = clock.now() + (swept === "full" ? 0 : backoff(failures));
|
|
117
111
|
}
|
|
118
|
-
})
|
|
112
|
+
}));
|
|
119
113
|
return { stop: () => fromSafePromise((async () => {
|
|
120
114
|
stopping.abort();
|
|
121
115
|
await running;
|
|
@@ -141,9 +135,10 @@ const startRelay = (store, publisher, observers, clock, { tenants, pollMs }) =>
|
|
|
141
135
|
*
|
|
142
136
|
* **A refused publish stops the tenant's batch** and backs that tenant off,
|
|
143
137
|
* doubling from the poll interval to 30 seconds, so a later fact never
|
|
144
|
-
* overtakes an earlier one
|
|
145
|
-
*
|
|
146
|
-
*
|
|
138
|
+
* overtakes an earlier one. Each tenant has its own loop, so a pending claim
|
|
139
|
+
* or publish holds only that tenant. A message the publisher refuses forever
|
|
140
|
+
* therefore holds its tenant's outbox — which is what the health check is for:
|
|
141
|
+
* it reports a tenant whose oldest pending message is older than `maxLagMs`.
|
|
147
142
|
*
|
|
148
143
|
* Started as the graph builds, before the runtime accepts anything, and
|
|
149
144
|
* stopped when the application scope closes, after the runtime has drained.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/outbox",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "The transactional outbox relay for @btravstack/core: a poll loop that publishes committed facts in outbox order, a per-tenant claim so replicas take turns rather than race for the same rows, and a Prisma 8 store",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency-injection",
|
|
@@ -53,10 +53,10 @@
|
|
|
53
53
|
"./package.json": "./package.json"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@btravstack/config": "0.
|
|
57
|
-
"@btravstack/core": "0.
|
|
58
|
-
"@btravstack/di": "0.
|
|
59
|
-
"@btravstack/testing": "0.
|
|
56
|
+
"@btravstack/config": "0.20.0",
|
|
57
|
+
"@btravstack/core": "0.20.0",
|
|
58
|
+
"@btravstack/di": "0.20.0",
|
|
59
|
+
"@btravstack/testing": "0.20.0",
|
|
60
60
|
"@btravstack/tsconfig": "0.4.0",
|
|
61
61
|
"@types/node": "26.6.4",
|
|
62
62
|
"@unthrown/vitest": "5.12.0",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"vitest": "5.0.3"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@btravstack/config": "^0.
|
|
71
|
-
"@btravstack/core": "^0.
|
|
72
|
-
"@btravstack/di": "^0.
|
|
70
|
+
"@btravstack/config": "^0.20.0",
|
|
71
|
+
"@btravstack/core": "^0.20.0",
|
|
72
|
+
"@btravstack/di": "^0.20.0",
|
|
73
73
|
"@prisma/orm-postgres": "^8.0.0-rc.11",
|
|
74
74
|
"unthrown": "^5.0.0"
|
|
75
75
|
},
|