@beignet/core 0.0.1 → 0.0.3
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/CHANGELOG.md +27 -0
- package/README.md +202 -8
- package/dist/application/index.d.ts +93 -9
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +11 -11
- package/dist/application/index.js.map +1 -1
- package/dist/client/client.d.ts +73 -12
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +37 -12
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts +69 -8
- package/dist/client/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +84 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +36 -0
- package/dist/config/index.js.map +1 -1
- package/dist/contracts/contract-builder.d.ts +49 -22
- package/dist/contracts/contract-builder.d.ts.map +1 -1
- package/dist/contracts/contract-builder.js +48 -21
- package/dist/contracts/contract-builder.js.map +1 -1
- package/dist/contracts/contract-group.d.ts +35 -19
- package/dist/contracts/contract-group.d.ts.map +1 -1
- package/dist/contracts/contract-group.js +35 -19
- package/dist/contracts/contract-group.js.map +1 -1
- package/dist/contracts/contract-like.d.ts +4 -4
- package/dist/contracts/contract-like.d.ts.map +1 -1
- package/dist/contracts/contract-like.js +2 -1
- package/dist/contracts/contract-like.js.map +1 -1
- package/dist/contracts/index.d.ts +28 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +12 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/openapi-meta.d.ts +8 -8
- package/dist/contracts/openapi-meta.d.ts.map +1 -1
- package/dist/contracts/path-template.d.ts +27 -0
- package/dist/contracts/path-template.d.ts.map +1 -1
- package/dist/contracts/path-template.js +6 -0
- package/dist/contracts/path-template.js.map +1 -1
- package/dist/contracts/types.d.ts +104 -10
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/contracts/types.js +15 -0
- package/dist/contracts/types.js.map +1 -1
- package/dist/contracts/utils.d.ts +6 -0
- package/dist/contracts/utils.d.ts.map +1 -1
- package/dist/contracts/utils.js +6 -0
- package/dist/contracts/utils.js.map +1 -1
- package/dist/domain/entity.d.ts +22 -11
- package/dist/domain/entity.d.ts.map +1 -1
- package/dist/domain/entity.js +5 -1
- package/dist/domain/entity.js.map +1 -1
- package/dist/domain/events.d.ts +5 -2
- package/dist/domain/events.d.ts.map +1 -1
- package/dist/domain/events.js +4 -1
- package/dist/domain/events.js.map +1 -1
- package/dist/domain/value-object.d.ts +19 -9
- package/dist/domain/value-object.d.ts.map +1 -1
- package/dist/domain/value-object.js +5 -1
- package/dist/domain/value-object.js.map +1 -1
- package/dist/errors/catalog.d.ts +40 -16
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/catalog.js +18 -7
- package/dist/errors/catalog.js.map +1 -1
- package/dist/errors/response.d.ts +16 -4
- package/dist/errors/response.d.ts.map +1 -1
- package/dist/errors/response.js +3 -3
- package/dist/errors/response.js.map +1 -1
- package/dist/errors/validation.d.ts +10 -1
- package/dist/errors/validation.d.ts.map +1 -1
- package/dist/errors/validation.js +3 -0
- package/dist/errors/validation.js.map +1 -1
- package/dist/events/index.d.ts +133 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +30 -0
- package/dist/events/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +355 -0
- package/dist/idempotency/index.d.ts.map +1 -0
- package/dist/idempotency/index.js +360 -0
- package/dist/idempotency/index.js.map +1 -0
- package/dist/jobs/index.d.ts +248 -4
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +183 -1
- package/dist/jobs/index.js.map +1 -1
- package/dist/mail/index.d.ts +149 -0
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +30 -0
- package/dist/mail/index.js.map +1 -1
- package/dist/notifications/index.d.ts +369 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +310 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/openapi/index.d.ts +132 -16
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/index.js.map +1 -1
- package/dist/outbox/index.d.ts +474 -0
- package/dist/outbox/index.d.ts.map +1 -0
- package/dist/outbox/index.js +538 -0
- package/dist/outbox/index.js.map +1 -0
- package/dist/pagination/index.d.ts +166 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +96 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/ports/audit.d.ts +271 -0
- package/dist/ports/audit.d.ts.map +1 -1
- package/dist/ports/audit.js +128 -0
- package/dist/ports/audit.js.map +1 -1
- package/dist/ports/auth.d.ts +70 -0
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/auth.js +30 -0
- package/dist/ports/auth.js.map +1 -1
- package/dist/ports/cache.d.ts +41 -0
- package/dist/ports/cache.d.ts.map +1 -1
- package/dist/ports/cache.js +10 -0
- package/dist/ports/cache.js.map +1 -1
- package/dist/ports/clock.d.ts +38 -0
- package/dist/ports/clock.d.ts.map +1 -1
- package/dist/ports/clock.js +20 -0
- package/dist/ports/clock.js.map +1 -1
- package/dist/ports/id-generator.d.ts +37 -0
- package/dist/ports/id-generator.d.ts.map +1 -1
- package/dist/ports/id-generator.js +22 -0
- package/dist/ports/id-generator.js.map +1 -1
- package/dist/ports/index.d.ts +83 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +41 -5
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/logger.d.ts +56 -0
- package/dist/ports/logger.d.ts.map +1 -1
- package/dist/ports/logger.js +17 -0
- package/dist/ports/logger.js.map +1 -1
- package/dist/ports/policy.d.ts +132 -0
- package/dist/ports/policy.d.ts.map +1 -1
- package/dist/ports/policy.js +45 -0
- package/dist/ports/policy.js.map +1 -1
- package/dist/ports/rate-limit.d.ts +25 -0
- package/dist/ports/rate-limit.d.ts.map +1 -1
- package/dist/ports/rate-limit.js +10 -0
- package/dist/ports/rate-limit.js.map +1 -1
- package/dist/ports/redaction.d.ts +101 -0
- package/dist/ports/redaction.d.ts.map +1 -1
- package/dist/ports/redaction.js +59 -0
- package/dist/ports/redaction.js.map +1 -1
- package/dist/ports/storage.d.ts +100 -0
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/ports/storage.js +10 -0
- package/dist/ports/storage.js.map +1 -1
- package/dist/ports/testing.d.ts +47 -0
- package/dist/ports/testing.d.ts.map +1 -1
- package/dist/ports/testing.js +23 -0
- package/dist/ports/testing.js.map +1 -1
- package/dist/ports/unit-of-work.d.ts +60 -3
- package/dist/ports/unit-of-work.d.ts.map +1 -1
- package/dist/ports/unit-of-work.js +11 -2
- package/dist/ports/unit-of-work.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +205 -1
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js +14 -0
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/provider.d.ts +14 -1
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +246 -0
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +27 -0
- package/dist/schedules/index.js.map +1 -1
- package/dist/server/health.d.ts +14 -5
- package/dist/server/health.d.ts.map +1 -1
- package/dist/server/health.js +5 -2
- package/dist/server/health.js.map +1 -1
- package/dist/server/hooks/auth.d.ts +68 -26
- package/dist/server/hooks/auth.d.ts.map +1 -1
- package/dist/server/hooks/auth.js +44 -55
- package/dist/server/hooks/auth.js.map +1 -1
- package/dist/server/hooks/cors.d.ts +27 -0
- package/dist/server/hooks/cors.d.ts.map +1 -1
- package/dist/server/hooks/cors.js +12 -0
- package/dist/server/hooks/cors.js.map +1 -1
- package/dist/server/hooks/errors.d.ts +15 -6
- package/dist/server/hooks/errors.d.ts.map +1 -1
- package/dist/server/hooks/errors.js.map +1 -1
- package/dist/server/hooks/index.d.ts +4 -1
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +3 -0
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/logging.d.ts +36 -0
- package/dist/server/hooks/logging.d.ts.map +1 -1
- package/dist/server/hooks/logging.js +6 -0
- package/dist/server/hooks/logging.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +33 -0
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +11 -0
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/http.d.ts +222 -0
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +20 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.d.ts +19 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +7 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/openapi.d.ts +5 -3
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/openapi.js +4 -2
- package/dist/server/openapi.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts +9 -0
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +9 -0
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/server.d.ts +159 -19
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +72 -31
- package/dist/server/server.js.map +1 -1
- package/dist/testing/index.d.ts +171 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +127 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/uploads/client.d.ts +278 -0
- package/dist/uploads/client.d.ts.map +1 -0
- package/dist/uploads/client.js +428 -0
- package/dist/uploads/client.js.map +1 -0
- package/dist/uploads/index.d.ts +361 -0
- package/dist/uploads/index.d.ts.map +1 -0
- package/dist/uploads/index.js +543 -0
- package/dist/uploads/index.js.map +1 -0
- package/package.json +31 -2
- package/src/application/index.ts +85 -22
- package/src/client/client.ts +73 -12
- package/src/client/index.ts +12 -0
- package/src/client/types.ts +70 -9
- package/src/config/index.ts +86 -0
- package/src/contracts/contract-builder.ts +49 -22
- package/src/contracts/contract-group.ts +35 -19
- package/src/contracts/contract-like.ts +4 -4
- package/src/contracts/index.ts +28 -1
- package/src/contracts/openapi-meta.ts +8 -8
- package/src/contracts/path-template.ts +27 -0
- package/src/contracts/types.ts +111 -10
- package/src/contracts/utils.ts +6 -0
- package/src/domain/entity.ts +22 -11
- package/src/domain/events.ts +5 -2
- package/src/domain/value-object.ts +19 -9
- package/src/errors/catalog.ts +40 -16
- package/src/errors/response.ts +16 -4
- package/src/errors/validation.ts +10 -1
- package/src/events/index.ts +134 -0
- package/src/idempotency/index.ts +767 -0
- package/src/jobs/index.ts +437 -5
- package/src/mail/index.ts +149 -0
- package/src/notifications/index.ts +771 -0
- package/src/openapi/index.ts +133 -16
- package/src/outbox/index.ts +1104 -0
- package/src/pagination/index.ts +278 -0
- package/src/ports/audit.ts +271 -0
- package/src/ports/auth.ts +70 -0
- package/src/ports/cache.ts +41 -0
- package/src/ports/clock.ts +38 -0
- package/src/ports/id-generator.ts +37 -0
- package/src/ports/index.ts +106 -11
- package/src/ports/logger.ts +56 -0
- package/src/ports/policy.ts +133 -0
- package/src/ports/rate-limit.ts +25 -0
- package/src/ports/redaction.ts +101 -0
- package/src/ports/storage.ts +100 -0
- package/src/ports/testing.ts +47 -0
- package/src/ports/unit-of-work.ts +60 -3
- package/src/providers/instrumentation.ts +211 -1
- package/src/providers/provider.ts +14 -1
- package/src/schedules/index.ts +247 -0
- package/src/server/health.ts +14 -5
- package/src/server/hooks/auth.ts +105 -120
- package/src/server/hooks/cors.ts +27 -0
- package/src/server/hooks/errors.ts +15 -6
- package/src/server/hooks/index.ts +4 -5
- package/src/server/hooks/logging.ts +36 -0
- package/src/server/hooks/rate-limit.ts +33 -0
- package/src/server/http.ts +249 -1
- package/src/server/index.ts +19 -1
- package/src/server/openapi.ts +5 -3
- package/src/server/providers/loadProviderConfig.ts +9 -0
- package/src/server/server.ts +296 -30
- package/src/testing/index.ts +348 -0
- package/src/uploads/client.ts +861 -0
- package/src/uploads/index.ts +1067 -0
|
@@ -0,0 +1,538 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @beignet/core/outbox
|
|
3
|
+
*
|
|
4
|
+
* Durable outbox primitives for transactionally recording events and jobs that
|
|
5
|
+
* should be delivered after the owning database transaction commits.
|
|
6
|
+
*/
|
|
7
|
+
import { parseEventPayload, } from "../events";
|
|
8
|
+
import { getJobRetryDelayMs, getJobRetryMaxAttempts, parseJobPayload, shouldRetryJob, } from "../jobs";
|
|
9
|
+
import { createProviderInstrumentation, } from "../providers";
|
|
10
|
+
/**
|
|
11
|
+
* Default lease duration for claimed outbox messages.
|
|
12
|
+
*/
|
|
13
|
+
export const DEFAULT_OUTBOX_LEASE_MS = 30_000;
|
|
14
|
+
/**
|
|
15
|
+
* Default maximum delivery attempts before a message is dead-lettered.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_OUTBOX_MAX_ATTEMPTS = 3;
|
|
18
|
+
/**
|
|
19
|
+
* Error thrown when an outbox payload is not JSON serializable.
|
|
20
|
+
*/
|
|
21
|
+
export class OutboxSerializationError extends Error {
|
|
22
|
+
constructor(message) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "OutboxSerializationError";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Error thrown when an outbox message cannot be resolved through the registry.
|
|
29
|
+
*/
|
|
30
|
+
export class OutboxRegistryError extends Error {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "OutboxRegistryError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Error thrown when a claimed message cannot be updated with the supplied token.
|
|
38
|
+
*/
|
|
39
|
+
export class OutboxClaimError extends Error {
|
|
40
|
+
/**
|
|
41
|
+
* Message ID involved in the claim error.
|
|
42
|
+
*/
|
|
43
|
+
id;
|
|
44
|
+
constructor(args) {
|
|
45
|
+
super(args.message);
|
|
46
|
+
this.name = "OutboxClaimError";
|
|
47
|
+
this.id = args.id;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function assertNonEmptyString(name, value) {
|
|
51
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
52
|
+
throw new Error(`${name} must be a non-empty string`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function assertPositiveInteger(name, value) {
|
|
56
|
+
if (!Number.isInteger(value) || value <= 0) {
|
|
57
|
+
throw new Error(`${name} must be a positive integer`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function cloneDate(value) {
|
|
61
|
+
return new Date(value.getTime());
|
|
62
|
+
}
|
|
63
|
+
function createId() {
|
|
64
|
+
if (!globalThis.crypto?.randomUUID) {
|
|
65
|
+
throw new Error("crypto.randomUUID is required to create outbox IDs.");
|
|
66
|
+
}
|
|
67
|
+
return globalThis.crypto.randomUUID();
|
|
68
|
+
}
|
|
69
|
+
function assertJsonValue(value, path = [], seen = new WeakSet()) {
|
|
70
|
+
const label = path.length > 0 ? path.join(".") : "payload";
|
|
71
|
+
if (value === null)
|
|
72
|
+
return null;
|
|
73
|
+
if (typeof value === "string" ||
|
|
74
|
+
typeof value === "boolean" ||
|
|
75
|
+
typeof value === "number") {
|
|
76
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
77
|
+
throw new OutboxSerializationError(`Outbox ${label} must be a finite number.`);
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
if (seen.has(value)) {
|
|
83
|
+
throw new OutboxSerializationError(`Outbox ${label} must be JSON serializable. Circular references are not supported.`);
|
|
84
|
+
}
|
|
85
|
+
seen.add(value);
|
|
86
|
+
try {
|
|
87
|
+
return value.map((item, index) => assertJsonValue(item, [...path, String(index)], seen));
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
seen.delete(value);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (typeof value === "object") {
|
|
94
|
+
if (value instanceof Date) {
|
|
95
|
+
throw new OutboxSerializationError(`Outbox ${label} must be JSON serializable. Convert Date values to strings before enqueueing.`);
|
|
96
|
+
}
|
|
97
|
+
if (seen.has(value)) {
|
|
98
|
+
throw new OutboxSerializationError(`Outbox ${label} must be JSON serializable. Circular references are not supported.`);
|
|
99
|
+
}
|
|
100
|
+
seen.add(value);
|
|
101
|
+
try {
|
|
102
|
+
const record = value;
|
|
103
|
+
const output = {};
|
|
104
|
+
for (const key of Object.keys(record)) {
|
|
105
|
+
const child = record[key];
|
|
106
|
+
if (child === undefined) {
|
|
107
|
+
throw new OutboxSerializationError(`Outbox ${[...path, key].join(".")} cannot be undefined.`);
|
|
108
|
+
}
|
|
109
|
+
output[key] = assertJsonValue(child, [...path, key], seen);
|
|
110
|
+
}
|
|
111
|
+
return output;
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
seen.delete(value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
throw new OutboxSerializationError(`Outbox ${label} must be JSON serializable. Received ${typeof value}.`);
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Convert an unknown value to an outbox-safe JSON value.
|
|
121
|
+
*
|
|
122
|
+
* Dates, undefined values, functions, non-finite numbers, symbols, and circular
|
|
123
|
+
* references are rejected so durable adapters can store the payload safely.
|
|
124
|
+
*/
|
|
125
|
+
export function toOutboxJsonValue(value) {
|
|
126
|
+
const jsonValue = assertJsonValue(value);
|
|
127
|
+
return JSON.parse(JSON.stringify(jsonValue));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Serialize an unknown delivery error into outbox error metadata.
|
|
131
|
+
*/
|
|
132
|
+
export function serializeOutboxError(error) {
|
|
133
|
+
if (error instanceof Error) {
|
|
134
|
+
return {
|
|
135
|
+
name: error.name,
|
|
136
|
+
message: error.message,
|
|
137
|
+
stack: error.stack,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (typeof error === "string") {
|
|
141
|
+
return { message: error };
|
|
142
|
+
}
|
|
143
|
+
return { message: "Unknown outbox delivery error" };
|
|
144
|
+
}
|
|
145
|
+
function copyMessage(message) {
|
|
146
|
+
return {
|
|
147
|
+
...message,
|
|
148
|
+
availableAt: cloneDate(message.availableAt),
|
|
149
|
+
claimedAt: message.claimedAt ? cloneDate(message.claimedAt) : null,
|
|
150
|
+
lockedUntil: message.lockedUntil ? cloneDate(message.lockedUntil) : null,
|
|
151
|
+
deliveredAt: message.deliveredAt ? cloneDate(message.deliveredAt) : null,
|
|
152
|
+
createdAt: cloneDate(message.createdAt),
|
|
153
|
+
updatedAt: cloneDate(message.updatedAt),
|
|
154
|
+
lastError: message.lastError ? { ...message.lastError } : null,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function toClaimedMessage(message) {
|
|
158
|
+
if (message.status !== "claimed" ||
|
|
159
|
+
!message.claimToken ||
|
|
160
|
+
!message.claimedAt ||
|
|
161
|
+
!message.lockedUntil) {
|
|
162
|
+
throw new OutboxClaimError({
|
|
163
|
+
id: message.id,
|
|
164
|
+
message: `Outbox message "${message.id}" is not claimed.`,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
...copyMessage(message),
|
|
169
|
+
status: "claimed",
|
|
170
|
+
claimToken: message.claimToken,
|
|
171
|
+
claimedAt: cloneDate(message.claimedAt),
|
|
172
|
+
lockedUntil: cloneDate(message.lockedUntil),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Create a validated pending outbox message.
|
|
177
|
+
*/
|
|
178
|
+
export function createOutboxMessage(input, options = {}) {
|
|
179
|
+
assertNonEmptyString("kind", input.kind);
|
|
180
|
+
assertNonEmptyString("name", input.name);
|
|
181
|
+
if (input.id !== undefined)
|
|
182
|
+
assertNonEmptyString("id", input.id);
|
|
183
|
+
if (input.maxAttempts !== undefined) {
|
|
184
|
+
assertPositiveInteger("maxAttempts", input.maxAttempts);
|
|
185
|
+
}
|
|
186
|
+
const now = options.now ?? new Date();
|
|
187
|
+
return {
|
|
188
|
+
id: options.id ?? input.id ?? createId(),
|
|
189
|
+
kind: input.kind,
|
|
190
|
+
name: input.name,
|
|
191
|
+
payload: toOutboxJsonValue(input.payload),
|
|
192
|
+
status: "pending",
|
|
193
|
+
attempts: 0,
|
|
194
|
+
maxAttempts: input.maxAttempts ?? DEFAULT_OUTBOX_MAX_ATTEMPTS,
|
|
195
|
+
availableAt: input.availableAt
|
|
196
|
+
? cloneDate(input.availableAt)
|
|
197
|
+
: cloneDate(now),
|
|
198
|
+
claimedAt: null,
|
|
199
|
+
lockedUntil: null,
|
|
200
|
+
claimToken: null,
|
|
201
|
+
deliveredAt: null,
|
|
202
|
+
lastError: null,
|
|
203
|
+
createdAt: cloneDate(now),
|
|
204
|
+
updatedAt: cloneDate(now),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function isEligible(message, now) {
|
|
208
|
+
if (message.status === "pending") {
|
|
209
|
+
return message.availableAt.getTime() <= now.getTime();
|
|
210
|
+
}
|
|
211
|
+
return (message.status === "claimed" &&
|
|
212
|
+
message.lockedUntil !== null &&
|
|
213
|
+
message.lockedUntil.getTime() <= now.getTime());
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Create an in-memory outbox for tests and local examples.
|
|
217
|
+
*
|
|
218
|
+
* The memory outbox is process-local and not durable.
|
|
219
|
+
*/
|
|
220
|
+
export function createMemoryOutbox() {
|
|
221
|
+
const messages = new Map();
|
|
222
|
+
function getClaimedOrThrow(id, claimToken) {
|
|
223
|
+
const message = messages.get(id);
|
|
224
|
+
if (!message) {
|
|
225
|
+
throw new OutboxClaimError({
|
|
226
|
+
id,
|
|
227
|
+
message: `Outbox message "${id}" does not exist.`,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
if (message.status !== "claimed" || message.claimToken !== claimToken) {
|
|
231
|
+
throw new OutboxClaimError({
|
|
232
|
+
id,
|
|
233
|
+
message: `Outbox message "${id}" is not claimed by this worker.`,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return message;
|
|
237
|
+
}
|
|
238
|
+
return {
|
|
239
|
+
get messages() {
|
|
240
|
+
return [...messages.values()].map(copyMessage);
|
|
241
|
+
},
|
|
242
|
+
async enqueue(input) {
|
|
243
|
+
const message = createOutboxMessage(input);
|
|
244
|
+
if (messages.has(message.id)) {
|
|
245
|
+
throw new Error(`Outbox message "${message.id}" already exists.`);
|
|
246
|
+
}
|
|
247
|
+
messages.set(message.id, message);
|
|
248
|
+
return copyMessage(message);
|
|
249
|
+
},
|
|
250
|
+
async claimBatch(options) {
|
|
251
|
+
assertPositiveInteger("limit", options.limit);
|
|
252
|
+
const now = options.now ?? new Date();
|
|
253
|
+
const leaseMs = options.leaseMs ?? DEFAULT_OUTBOX_LEASE_MS;
|
|
254
|
+
assertPositiveInteger("leaseMs", leaseMs);
|
|
255
|
+
const lockedUntil = new Date(now.getTime() + leaseMs);
|
|
256
|
+
const claimed = [];
|
|
257
|
+
const eligible = [...messages.values()]
|
|
258
|
+
.filter((message) => isEligible(message, now))
|
|
259
|
+
.sort((a, b) => {
|
|
260
|
+
const available = a.availableAt.getTime() - b.availableAt.getTime();
|
|
261
|
+
if (available !== 0)
|
|
262
|
+
return available;
|
|
263
|
+
return a.createdAt.getTime() - b.createdAt.getTime();
|
|
264
|
+
})
|
|
265
|
+
.slice(0, options.limit);
|
|
266
|
+
for (const message of eligible) {
|
|
267
|
+
message.status = "claimed";
|
|
268
|
+
message.attempts += 1;
|
|
269
|
+
message.claimToken = createId();
|
|
270
|
+
message.claimedAt = cloneDate(now);
|
|
271
|
+
message.lockedUntil = cloneDate(lockedUntil);
|
|
272
|
+
message.updatedAt = cloneDate(now);
|
|
273
|
+
claimed.push(toClaimedMessage(message));
|
|
274
|
+
}
|
|
275
|
+
return claimed;
|
|
276
|
+
},
|
|
277
|
+
async markDelivered(input) {
|
|
278
|
+
assertNonEmptyString("id", input.id);
|
|
279
|
+
assertNonEmptyString("claimToken", input.claimToken);
|
|
280
|
+
const message = getClaimedOrThrow(input.id, input.claimToken);
|
|
281
|
+
const now = input.now ?? new Date();
|
|
282
|
+
message.status = "delivered";
|
|
283
|
+
message.deliveredAt = cloneDate(now);
|
|
284
|
+
message.claimToken = null;
|
|
285
|
+
message.claimedAt = null;
|
|
286
|
+
message.lockedUntil = null;
|
|
287
|
+
message.updatedAt = cloneDate(now);
|
|
288
|
+
},
|
|
289
|
+
async markFailed(input) {
|
|
290
|
+
assertNonEmptyString("id", input.id);
|
|
291
|
+
assertNonEmptyString("claimToken", input.claimToken);
|
|
292
|
+
const message = getClaimedOrThrow(input.id, input.claimToken);
|
|
293
|
+
const now = input.now ?? new Date();
|
|
294
|
+
message.status = input.deadLetter ? "deadLettered" : "pending";
|
|
295
|
+
message.lastError = serializeOutboxError(input.error);
|
|
296
|
+
message.availableAt = input.retryAt
|
|
297
|
+
? cloneDate(input.retryAt)
|
|
298
|
+
: cloneDate(now);
|
|
299
|
+
message.claimToken = null;
|
|
300
|
+
message.claimedAt = null;
|
|
301
|
+
message.lockedUntil = null;
|
|
302
|
+
message.updatedAt = cloneDate(now);
|
|
303
|
+
},
|
|
304
|
+
clear() {
|
|
305
|
+
messages.clear();
|
|
306
|
+
},
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function mapDefinitions(kind, defs) {
|
|
310
|
+
const map = new Map();
|
|
311
|
+
for (const def of defs) {
|
|
312
|
+
if (map.has(def.name)) {
|
|
313
|
+
throw new OutboxRegistryError(`Duplicate ${kind} definition "${def.name}" in outbox registry.`);
|
|
314
|
+
}
|
|
315
|
+
map.set(def.name, def);
|
|
316
|
+
}
|
|
317
|
+
return map;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Define the events and jobs that an outbox drain worker can deliver.
|
|
321
|
+
*
|
|
322
|
+
* Duplicate names throw because message delivery resolves by name.
|
|
323
|
+
*/
|
|
324
|
+
export function defineOutboxRegistry(input) {
|
|
325
|
+
return {
|
|
326
|
+
events: mapDefinitions("event", input.events ?? []),
|
|
327
|
+
jobs: mapDefinitions("job", input.jobs ?? []),
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Validate an event payload and enqueue it as an outbox message.
|
|
332
|
+
*/
|
|
333
|
+
export async function enqueueEvent(outbox, event, payload, options = {}) {
|
|
334
|
+
const parsed = await parseEventPayload(event, payload);
|
|
335
|
+
return outbox.enqueue({
|
|
336
|
+
id: options.id,
|
|
337
|
+
kind: "event",
|
|
338
|
+
name: event.name,
|
|
339
|
+
payload: toOutboxJsonValue(parsed),
|
|
340
|
+
availableAt: options.availableAt,
|
|
341
|
+
maxAttempts: options.maxAttempts,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Validate a job payload and enqueue it as an outbox message.
|
|
346
|
+
*/
|
|
347
|
+
export async function enqueueJob(outbox, job, payload, options = {}) {
|
|
348
|
+
const parsed = await parseJobPayload(job, payload);
|
|
349
|
+
return outbox.enqueue({
|
|
350
|
+
id: options.id,
|
|
351
|
+
kind: "job",
|
|
352
|
+
name: job.name,
|
|
353
|
+
payload: toOutboxJsonValue(parsed),
|
|
354
|
+
availableAt: options.availableAt,
|
|
355
|
+
maxAttempts: options.maxAttempts ?? getJobRetryMaxAttempts(job.retry),
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Create a domain event recorder that writes events to the outbox.
|
|
360
|
+
*/
|
|
361
|
+
export function createOutboxEventRecorder(outbox, options = {}) {
|
|
362
|
+
return {
|
|
363
|
+
async record(event, payload) {
|
|
364
|
+
await enqueueEvent(outbox, event, payload, options);
|
|
365
|
+
},
|
|
366
|
+
entries() {
|
|
367
|
+
return [];
|
|
368
|
+
},
|
|
369
|
+
clear() { },
|
|
370
|
+
async flush() { },
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Create a job dispatcher that writes jobs to the outbox.
|
|
375
|
+
*/
|
|
376
|
+
export function createOutboxJobDispatcher(outbox, options = {}) {
|
|
377
|
+
return {
|
|
378
|
+
async dispatch(job, payload) {
|
|
379
|
+
await enqueueJob(outbox, job, payload, options);
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
function resolveRetryDelayMs(options, message, error, now) {
|
|
384
|
+
if (typeof options.retryDelayMs === "function") {
|
|
385
|
+
const delay = options.retryDelayMs({ message, error, now });
|
|
386
|
+
assertPositiveInteger("retryDelayMs", delay);
|
|
387
|
+
return delay;
|
|
388
|
+
}
|
|
389
|
+
if (options.retryDelayMs !== undefined) {
|
|
390
|
+
assertPositiveInteger("retryDelayMs", options.retryDelayMs);
|
|
391
|
+
return options.retryDelayMs;
|
|
392
|
+
}
|
|
393
|
+
if (message.kind === "job") {
|
|
394
|
+
const job = options.registry.jobs.get(message.name);
|
|
395
|
+
if (job?.retry) {
|
|
396
|
+
return getJobRetryDelayMs(job.retry, {
|
|
397
|
+
attempt: message.attempts,
|
|
398
|
+
error,
|
|
399
|
+
jobName: message.name,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return Math.min(60_000, 1000 * 2 ** Math.max(0, message.attempts - 1));
|
|
404
|
+
}
|
|
405
|
+
function shouldRetryOutboxMessage(options, message, error) {
|
|
406
|
+
if (message.kind !== "job") {
|
|
407
|
+
return message.attempts < message.maxAttempts;
|
|
408
|
+
}
|
|
409
|
+
const job = options.registry.jobs.get(message.name);
|
|
410
|
+
return shouldRetryJob(job?.retry, {
|
|
411
|
+
attempt: message.attempts,
|
|
412
|
+
error,
|
|
413
|
+
jobName: message.name,
|
|
414
|
+
maxAttempts: message.maxAttempts,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
async function deliverOutboxMessage(options, message) {
|
|
418
|
+
if (message.kind === "event") {
|
|
419
|
+
if (!options.eventBus) {
|
|
420
|
+
throw new OutboxRegistryError(`Cannot deliver event "${message.name}" without an event bus.`);
|
|
421
|
+
}
|
|
422
|
+
const event = options.registry.events.get(message.name);
|
|
423
|
+
if (!event) {
|
|
424
|
+
throw new OutboxRegistryError(`Outbox registry does not include event "${message.name}".`);
|
|
425
|
+
}
|
|
426
|
+
const payload = await parseEventPayload(event, message.payload);
|
|
427
|
+
await options.eventBus.publish(event, payload);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
if (!options.jobs) {
|
|
431
|
+
throw new OutboxRegistryError(`Cannot deliver job "${message.name}" without a job dispatcher.`);
|
|
432
|
+
}
|
|
433
|
+
const job = options.registry.jobs.get(message.name);
|
|
434
|
+
if (!job) {
|
|
435
|
+
throw new OutboxRegistryError(`Outbox registry does not include job "${message.name}".`);
|
|
436
|
+
}
|
|
437
|
+
const payload = await parseJobPayload(job, message.payload);
|
|
438
|
+
await options.jobs.dispatch(job, payload);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Claim and deliver one batch of outbox messages.
|
|
442
|
+
*
|
|
443
|
+
* This does not loop forever; production workers should call it on their own
|
|
444
|
+
* polling cadence. Event and job messages require matching registry entries.
|
|
445
|
+
* Failed messages are retried with backoff until `maxAttempts`, then
|
|
446
|
+
* dead-lettered.
|
|
447
|
+
*/
|
|
448
|
+
export async function drainOutbox(options) {
|
|
449
|
+
const batchSize = options.batchSize ?? 100;
|
|
450
|
+
assertPositiveInteger("batchSize", batchSize);
|
|
451
|
+
const instrumentation = createProviderInstrumentation(options.instrumentation, {
|
|
452
|
+
providerName: "outbox",
|
|
453
|
+
watcher: "jobs",
|
|
454
|
+
});
|
|
455
|
+
const now = options.now ?? new Date();
|
|
456
|
+
const messages = await options.outbox.claimBatch({
|
|
457
|
+
limit: batchSize,
|
|
458
|
+
now,
|
|
459
|
+
leaseMs: options.leaseMs,
|
|
460
|
+
});
|
|
461
|
+
const result = {
|
|
462
|
+
claimed: messages.length,
|
|
463
|
+
delivered: 0,
|
|
464
|
+
retried: 0,
|
|
465
|
+
deadLettered: 0,
|
|
466
|
+
};
|
|
467
|
+
for (const message of messages) {
|
|
468
|
+
try {
|
|
469
|
+
await deliverOutboxMessage(options, message);
|
|
470
|
+
await options.outbox.markDelivered({
|
|
471
|
+
id: message.id,
|
|
472
|
+
claimToken: message.claimToken,
|
|
473
|
+
now,
|
|
474
|
+
});
|
|
475
|
+
result.delivered += 1;
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
try {
|
|
479
|
+
await options.onError?.(error, message);
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
// Preserve the delivery failure path so the message is retried or
|
|
483
|
+
// dead-lettered even if the observer fails.
|
|
484
|
+
}
|
|
485
|
+
const shouldRetry = shouldRetryOutboxMessage(options, message, error);
|
|
486
|
+
const deadLetter = !shouldRetry;
|
|
487
|
+
const retryDelayMs = deadLetter
|
|
488
|
+
? 0
|
|
489
|
+
: resolveRetryDelayMs(options, message, error, now);
|
|
490
|
+
await options.outbox.markFailed({
|
|
491
|
+
id: message.id,
|
|
492
|
+
claimToken: message.claimToken,
|
|
493
|
+
error,
|
|
494
|
+
deadLetter,
|
|
495
|
+
now,
|
|
496
|
+
retryAt: deadLetter
|
|
497
|
+
? undefined
|
|
498
|
+
: new Date(now.getTime() + retryDelayMs),
|
|
499
|
+
});
|
|
500
|
+
if (deadLetter) {
|
|
501
|
+
if (message.kind === "job") {
|
|
502
|
+
instrumentation.record({
|
|
503
|
+
type: "job",
|
|
504
|
+
jobName: message.name,
|
|
505
|
+
status: "deadLettered",
|
|
506
|
+
details: {
|
|
507
|
+
attempt: message.attempts,
|
|
508
|
+
maxAttempts: message.maxAttempts,
|
|
509
|
+
messageId: message.id,
|
|
510
|
+
error: serializeOutboxError(error),
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
result.deadLettered += 1;
|
|
515
|
+
}
|
|
516
|
+
else {
|
|
517
|
+
if (message.kind === "job") {
|
|
518
|
+
instrumentation.record({
|
|
519
|
+
type: "job",
|
|
520
|
+
jobName: message.name,
|
|
521
|
+
status: "retryScheduled",
|
|
522
|
+
details: {
|
|
523
|
+
attempt: message.attempts,
|
|
524
|
+
maxAttempts: message.maxAttempts,
|
|
525
|
+
messageId: message.id,
|
|
526
|
+
retryDelayMs,
|
|
527
|
+
retryAt: new Date(now.getTime() + retryDelayMs).toISOString(),
|
|
528
|
+
error: serializeOutboxError(error),
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
}
|
|
532
|
+
result.retried += 1;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return result;
|
|
537
|
+
}
|
|
538
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/outbox/index.ts"],"names":[],"mappings":"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"}
|