@cqrs-ddd/pipeline-deadletter 0.5.1 → 0.6.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/dead-letter.behavior.d.ts +2 -10
- package/dist/dead-letter.behavior.d.ts.map +1 -1
- package/dist/dead-letter.behavior.js +10 -27
- package/dist/dead-letter.behavior.js.map +1 -1
- package/dist/dead-letter.redriver.d.ts +23 -2
- package/dist/dead-letter.redriver.d.ts.map +1 -1
- package/dist/dead-letter.redriver.js +21 -4
- package/dist/dead-letter.redriver.js.map +1 -1
- package/dist/errors/dead-letter-redrive.error.d.ts +3 -2
- package/dist/errors/dead-letter-redrive.error.d.ts.map +1 -1
- package/dist/errors/dead-letter-redrive.error.js +3 -2
- package/dist/errors/dead-letter-redrive.error.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interfaces/dead-letter-transport.interface.d.ts +13 -1
- package/dist/interfaces/dead-letter-transport.interface.d.ts.map +1 -1
- package/dist/transports/postgres.transport.d.ts +6 -9
- package/dist/transports/postgres.transport.d.ts.map +1 -1
- package/dist/transports/postgres.transport.js +34 -21
- package/dist/transports/postgres.transport.js.map +1 -1
- package/package.json +6 -6
|
@@ -2,18 +2,10 @@ import { type IPipelineBehavior, type IPipelineBehaviorContract, type IPipelineC
|
|
|
2
2
|
import type { DeadLetterBehaviorOptions } from './interfaces/dead-letter-options.interface.js';
|
|
3
3
|
import type { DeadLetterTransport } from './interfaces/dead-letter-transport.interface.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* The `context.items` entry to `true` or `false` recording whether
|
|
6
6
|
* delivery to the dead-letter transport succeeded.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* ```ts
|
|
10
|
-
* const delivered = context.items.get(DEAD_LETTER_ITEM) === true;
|
|
11
|
-
* ```
|
|
12
|
-
*/
|
|
13
|
-
export declare const DEAD_LETTER_ITEM: unique symbol;
|
|
14
|
-
/**
|
|
15
|
-
* Typed token for {@link DEAD_LETTER_ITEM}: the dead-letter delivery outcome. Reads and writes the same
|
|
16
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
8
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
17
9
|
*/
|
|
18
10
|
export declare const DEAD_LETTER_ITEM_TOKEN: PipelineItemToken<boolean>;
|
|
19
11
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter.behavior.d.ts","sourceRoot":"","sources":["../src/dead-letter.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,0BAA0B,EAG1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,iDAAiD,CAAC;AASzD
|
|
1
|
+
{"version":3,"file":"dead-letter.behavior.d.ts","sourceRoot":"","sources":["../src/dead-letter.behavior.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,0BAA0B,EAG1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,iDAAiD,CAAC;AASzD;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,EAAE,iBAAiB,CAAC,OAAO,CACb,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IA0BxD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAzB5B,MAAM,CAAC,QAAQ,CAAC,CAAC,0BAA0B,CAAC,EAAE,yBAAyB,CAmBrE;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA4B;IAErD,YACmB,SAAS,EAAE,mBAAmB,EAC/C,QAAQ,CAAC,EAAE,yBAAyB,EACpC,MAAM,CAAC,EAAE,cAAc,EAUxB;IAEK,MAAM,CACV,OAAO,EAAE,gBAAgB,EACzB,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,OAAO,CAAC,CA6BlB;IAED,uFAAuF;YACzE,mBAAmB;IAajC,oFAAoF;YACtE,OAAO;IAyBrB,yEAAyE;IACzE,OAAO,CAAC,aAAa;IAiBrB,gEAAgE;IAChE,OAAO,CAAC,cAAc;CA0BvB"}
|
|
@@ -9,20 +9,12 @@ import { currentRedriveId } from './helpers/redrive-scope.js';
|
|
|
9
9
|
*/
|
|
10
10
|
const DEFAULT_CAPTURE_KINDS = ['event'];
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* The `context.items` entry to `true` or `false` recording whether
|
|
13
13
|
* delivery to the dead-letter transport succeeded.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* ```ts
|
|
17
|
-
* const delivered = context.items.get(DEAD_LETTER_ITEM) === true;
|
|
18
|
-
* ```
|
|
19
|
-
*/
|
|
20
|
-
export const DEAD_LETTER_ITEM = Symbol('DEAD_LETTER_ITEM');
|
|
21
|
-
/**
|
|
22
|
-
* Typed token for {@link DEAD_LETTER_ITEM}: the dead-letter delivery outcome. Reads and writes the same
|
|
23
|
-
* `context.items` entry through `getPipelineItem` / `requirePipelineItem`.
|
|
15
|
+
* Read it with `getPipelineItem` or `requirePipelineItem`.
|
|
24
16
|
*/
|
|
25
|
-
export const DEAD_LETTER_ITEM_TOKEN = createPipelineItem('DEAD_LETTER_ITEM'
|
|
17
|
+
export const DEAD_LETTER_ITEM_TOKEN = createPipelineItem('DEAD_LETTER_ITEM');
|
|
26
18
|
/**
|
|
27
19
|
* Pipeline behavior that forwards **failed** requests to a dead-letter sink.
|
|
28
20
|
*
|
|
@@ -131,8 +123,8 @@ export class DeadLetterBehavior {
|
|
|
131
123
|
return false;
|
|
132
124
|
}
|
|
133
125
|
const { ignoreErrors } = options;
|
|
134
|
-
|
|
135
|
-
|
|
126
|
+
const isFilter = typeof ignoreErrors === 'function' || Array.isArray(ignoreErrors);
|
|
127
|
+
return !isFilter || !matchesIgnoredError(ignoreErrors, error, context);
|
|
136
128
|
}
|
|
137
129
|
/** Merges per-handler options over the constructor defaults. */
|
|
138
130
|
resolveOptions(context) {
|
|
@@ -143,20 +135,11 @@ export class DeadLetterBehavior {
|
|
|
143
135
|
...this.defaults,
|
|
144
136
|
...handlerOptions,
|
|
145
137
|
};
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
...handlerOptions.ignoreErrors,
|
|
152
|
-
];
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const defaultFilter = this.defaults.ignoreErrors;
|
|
156
|
-
const handlerFilter = handlerOptions.ignoreErrors;
|
|
157
|
-
merged.ignoreErrors = (err, ctx) => matchesIgnoredError(defaultFilter, err, ctx) ||
|
|
158
|
-
matchesIgnoredError(handlerFilter, err, ctx);
|
|
159
|
-
}
|
|
138
|
+
const defaultFilter = this.defaults.ignoreErrors;
|
|
139
|
+
const handlerFilter = handlerOptions.ignoreErrors;
|
|
140
|
+
if (defaultFilter && handlerFilter) {
|
|
141
|
+
merged.ignoreErrors = (error, ctx) => matchesIgnoredError(defaultFilter, error, ctx) ||
|
|
142
|
+
matchesIgnoredError(handlerFilter, error, ctx);
|
|
160
143
|
}
|
|
161
144
|
if (this.defaults.redactKeys && handlerOptions.redactKeys) {
|
|
162
145
|
merged.redactKeys = Array.from(new Set([...this.defaults.redactKeys, ...handlerOptions.redactKeys]));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter.behavior.js","sourceRoot":"","sources":["../src/dead-letter.behavior.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,kBAAkB,EAKlB,0BAA0B,EAK1B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAO9D;;;;GAIG;AACH,MAAM,qBAAqB,GAAqC,CAAC,OAAO,CAAC,CAAC;AAE1E
|
|
1
|
+
{"version":3,"file":"dead-letter.behavior.js","sourceRoot":"","sources":["../src/dead-letter.behavior.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import type { Constructor } from '@cqrs-ddd/pipeline';
|
|
1
|
+
import type { Constructor, PipelineLogger } from '@cqrs-ddd/pipeline';
|
|
2
2
|
import type { DeadLetterRecord, DeadLetterRequestKind, DeadLetterStore } from './interfaces/dead-letter-transport.interface.js';
|
|
3
3
|
/**
|
|
4
4
|
* Sends a rebuilt request back for handling. It must settle only when the
|
|
5
5
|
* handling has finished, and reject when it failed.
|
|
6
6
|
*
|
|
7
|
+
* It runs in the context of the caller of `redrive`, not in the context of the
|
|
8
|
+
* failed request. When the handling reads the tenant, restore
|
|
9
|
+
* `record.tenantId` here before the handling starts.
|
|
10
|
+
*
|
|
7
11
|
* For an event, run only the handler that failed (`record.handlerName`):
|
|
8
12
|
* publishing the event again would also rerun the handlers that succeeded.
|
|
9
13
|
*/
|
|
@@ -24,6 +28,18 @@ export interface DeadLetterRedriverOptions {
|
|
|
24
28
|
* the redacted values.
|
|
25
29
|
*/
|
|
26
30
|
rebuild?: (record: DeadLetterRecord, requestType: Constructor) => unknown;
|
|
31
|
+
/**
|
|
32
|
+
* How long one redrive holds its record, in milliseconds. Default five
|
|
33
|
+
* minutes. A second redrive of the record is refused during this time. Set
|
|
34
|
+
* it longer than the slowest handling: after it, the record of a process
|
|
35
|
+
* that stopped during the handling can be redriven again.
|
|
36
|
+
*/
|
|
37
|
+
leaseMs?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Receives the store error when a failed attempt cannot be recorded; the
|
|
40
|
+
* handling error is still the one `redrive` throws. Default `console`.
|
|
41
|
+
*/
|
|
42
|
+
logger?: PipelineLogger;
|
|
27
43
|
}
|
|
28
44
|
/** Outcome of a successful {@link DeadLetterRedriver.redrive}. */
|
|
29
45
|
export interface DeadLetterRedriveResult {
|
|
@@ -33,7 +49,8 @@ export interface DeadLetterRedriveResult {
|
|
|
33
49
|
}
|
|
34
50
|
/**
|
|
35
51
|
* Redrives dead letters kept by a {@link DeadLetterStore}: rebuilds the
|
|
36
|
-
* request,
|
|
52
|
+
* request, claims the record so that no second redrive runs it at the same
|
|
53
|
+
* time, dispatches it, then marks the record resolved — or, when the
|
|
37
54
|
* handling fails again, counts the attempt, keeps its error, and rethrows it.
|
|
38
55
|
* During a redrive, `DeadLetterBehavior` neither captures the failure again
|
|
39
56
|
* nor swallows it.
|
|
@@ -63,8 +80,12 @@ export declare class DeadLetterRedriver {
|
|
|
63
80
|
*
|
|
64
81
|
* @throws DeadLetterRedriveError when it cannot be redriven; nothing is dispatched.
|
|
65
82
|
* @throws The handling error when the redrive fails; the attempt is counted.
|
|
83
|
+
* When the store cannot count it, the logger gets the store error and the
|
|
84
|
+
* claim holds until `leaseMs` ends.
|
|
66
85
|
*/
|
|
67
86
|
redrive(id: string): Promise<DeadLetterRedriveResult>;
|
|
87
|
+
/** Counts the failed attempt; a store failure here must not replace `error`. */
|
|
88
|
+
private recordFailure;
|
|
68
89
|
/**
|
|
69
90
|
* The request class and the dispatch that redrive `record`.
|
|
70
91
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter.redriver.d.ts","sourceRoot":"","sources":["../src/dead-letter.redriver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"dead-letter.redriver.d.ts","sourceRoot":"","sources":["../src/dead-letter.redriver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGtE,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,eAAe,EAChB,MAAM,iDAAiD,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAC/B,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,gBAAgB,KACrB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;AAEhC,6CAA6C;AAC7C,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACrE;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC;IAC1E;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAID,kEAAkE;AAClE,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,kBAAkB;IAI3B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD,YACmB,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,yBAAyB,EAGpD;IAED;;;;;;;OAOG;IACG,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CA+B1D;IAED,gFAAgF;YAClE,aAAa;IAc3B;;;;OAIG;IACH,OAAO,CAAC,QAAQ;IA8BhB,wDAAwD;IACxD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEjC;CACF"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
2
|
import { DeadLetterRedriveError } from './errors/dead-letter-redrive.error.js';
|
|
3
3
|
import { runAsRedrive } from './helpers/redrive-scope.js';
|
|
4
|
+
const DEFAULT_LEASE_MS = 5 * 60_000;
|
|
4
5
|
/**
|
|
5
6
|
* Redrives dead letters kept by a {@link DeadLetterStore}: rebuilds the
|
|
6
|
-
* request,
|
|
7
|
+
* request, claims the record so that no second redrive runs it at the same
|
|
8
|
+
* time, dispatches it, then marks the record resolved — or, when the
|
|
7
9
|
* handling fails again, counts the attempt, keeps its error, and rethrows it.
|
|
8
10
|
* During a redrive, `DeadLetterBehavior` neither captures the failure again
|
|
9
11
|
* nor swallows it.
|
|
@@ -37,6 +39,8 @@ export class DeadLetterRedriver {
|
|
|
37
39
|
*
|
|
38
40
|
* @throws DeadLetterRedriveError when it cannot be redriven; nothing is dispatched.
|
|
39
41
|
* @throws The handling error when the redrive fails; the attempt is counted.
|
|
42
|
+
* When the store cannot count it, the logger gets the store error and the
|
|
43
|
+
* claim holds until `leaseMs` ends.
|
|
40
44
|
*/
|
|
41
45
|
async redrive(id) {
|
|
42
46
|
const record = await this.store.get(id);
|
|
@@ -46,19 +50,32 @@ export class DeadLetterRedriver {
|
|
|
46
50
|
const request = this.options.rebuild
|
|
47
51
|
? this.options.rebuild(record, requestType)
|
|
48
52
|
: Object.assign(Object.create(requestType.prototype), record.payload);
|
|
53
|
+
const leaseMs = this.options.leaseMs ?? DEFAULT_LEASE_MS;
|
|
54
|
+
if (!(await this.store.claim(id, leaseMs))) {
|
|
55
|
+
throw new DeadLetterRedriveError(id, 'another redrive holds it, or it is resolved');
|
|
56
|
+
}
|
|
49
57
|
let response;
|
|
50
58
|
try {
|
|
51
59
|
response = await runAsRedrive(id, () => dispatch(request, record));
|
|
52
60
|
}
|
|
53
61
|
catch (error) {
|
|
62
|
+
await this.recordFailure(id, error);
|
|
63
|
+
throw error;
|
|
64
|
+
}
|
|
65
|
+
await this.store.markResolved(id);
|
|
66
|
+
return { id, response };
|
|
67
|
+
}
|
|
68
|
+
/** Counts the failed attempt; a store failure here must not replace `error`. */
|
|
69
|
+
async recordFailure(id, error) {
|
|
70
|
+
try {
|
|
54
71
|
await this.store.recordAttempt(id, {
|
|
55
72
|
name: error instanceof Error ? error.name : 'unknown',
|
|
56
73
|
message: error instanceof Error ? error.message : String(error),
|
|
57
74
|
});
|
|
58
|
-
throw error;
|
|
59
75
|
}
|
|
60
|
-
|
|
61
|
-
|
|
76
|
+
catch (storeError) {
|
|
77
|
+
(this.options.logger ?? console).error(`Failed to record the redrive attempt of dead letter ${id}`, storeError);
|
|
78
|
+
}
|
|
62
79
|
}
|
|
63
80
|
/**
|
|
64
81
|
* The request class and the dispatch that redrive `record`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter.redriver.js","sourceRoot":"","sources":["../src/dead-letter.redriver.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAGtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"dead-letter.redriver.js","sourceRoot":"","sources":["../src/dead-letter.redriver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Raised by `DeadLetterRedriver` when a dead letter cannot be redriven: it does
|
|
3
|
-
* not exist, is already resolved,
|
|
4
|
-
* dispatcher, or its payload was redacted and no
|
|
3
|
+
* not exist, is already resolved, is held by another redrive, has no
|
|
4
|
+
* registered request type or dispatcher, or its payload was redacted and no
|
|
5
|
+
* `rebuild` is configured.
|
|
5
6
|
* Nothing is dispatched and the record is unchanged.
|
|
6
7
|
*/
|
|
7
8
|
export declare class DeadLetterRedriveError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter-redrive.error.d.ts","sourceRoot":"","sources":["../../src/errors/dead-letter-redrive.error.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"dead-letter-redrive.error.d.ts","sourceRoot":"","sources":["../../src/errors/dead-letter-redrive.error.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;aAI7B,YAAY,EAAE,MAAM;aACpB,MAAM,EAAE,MAAM;IAJhC,SAAkB,IAAI,4BAA4B;IAElD,YACkB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EAG/B;CACF"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
2
|
/**
|
|
3
3
|
* Raised by `DeadLetterRedriver` when a dead letter cannot be redriven: it does
|
|
4
|
-
* not exist, is already resolved,
|
|
5
|
-
* dispatcher, or its payload was redacted and no
|
|
4
|
+
* not exist, is already resolved, is held by another redrive, has no
|
|
5
|
+
* registered request type or dispatcher, or its payload was redacted and no
|
|
6
|
+
* `rebuild` is configured.
|
|
6
7
|
* Nothing is dispatched and the record is unchanged.
|
|
7
8
|
*/
|
|
8
9
|
export class DeadLetterRedriveError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter-redrive.error.js","sourceRoot":"","sources":["../../src/errors/dead-letter-redrive.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE
|
|
1
|
+
{"version":3,"file":"dead-letter-redrive.error.js","sourceRoot":"","sources":["../../src/errors/dead-letter-redrive.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;GAMG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAI7B,YAAY;IACZ,MAAM;IAJN,IAAI,GAAG,wBAAwB,CAAC;IAElD,YACkB,YAAoB,EACpB,MAAc;QAE9B,KAAK,CAAC,8BAA8B,YAAY,KAAK,MAAM,EAAE,CAAC,CAAC;4BAH/C,YAAY;sBACZ,MAAM;IAGxB,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { DEFAULT_REDACT_KEYS, REDACTED, redactValue, } from '@cqrs-ddd/safe-stringify';
|
|
2
|
-
export {
|
|
2
|
+
export { DEAD_LETTER_ITEM_TOKEN, DeadLetterBehavior, } from './dead-letter.behavior.js';
|
|
3
3
|
export { type DeadLetterDispatch, type DeadLetterRedriveResult, DeadLetterRedriver, type DeadLetterRedriverOptions, } from './dead-letter.redriver.js';
|
|
4
4
|
export { DeadLetterRedriveError } from './errors/dead-letter-redrive.error.js';
|
|
5
5
|
export { buildDeadLetterAttributes } from './helpers/build-attributes.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EACL,KAAK,uBAAuB,EAC5B,UAAU,GACX,MAAM,iCAAiC,CAAC;AACzC,YAAY,EACV,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,+CAA+C,CAAC;AACvD,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,EACf,mBAAmB,GACpB,MAAM,iDAAiD,CAAC;AACzD,OAAO,EACL,yBAAyB,EACzB,KAAK,gCAAgC,EACrC,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,EACxB,2BAA2B,EAC3B,KAAK,kCAAkC,EACvC,KAAK,qBAAqB,GAC3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,KAAK,0BAA0B,EAC/B,2BAA2B,EAC3B,KAAK,kCAAkC,GACxC,MAAM,oCAAoC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
2
|
export { DEFAULT_REDACT_KEYS, REDACTED, redactValue, } from '@cqrs-ddd/safe-stringify';
|
|
3
|
-
export {
|
|
3
|
+
export { DEAD_LETTER_ITEM_TOKEN, DeadLetterBehavior, } from './dead-letter.behavior.js';
|
|
4
4
|
export { DeadLetterRedriver, } from './dead-letter.redriver.js';
|
|
5
5
|
export { DeadLetterRedriveError } from './errors/dead-letter-redrive.error.js';
|
|
6
6
|
export { buildDeadLetterAttributes } from './helpers/build-attributes.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,WAAW,GACZ,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,kBAAkB,GAEnB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAEL,UAAU,GACX,MAAM,iCAAiC,CAAC;AAczC,OAAO,EACL,yBAAyB,GAG1B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,EACxB,2BAA2B,GAG5B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAEL,2BAA2B,GAE5B,MAAM,oCAAoC,CAAC"}
|
|
@@ -82,6 +82,8 @@ export interface DeadLetterTransport {
|
|
|
82
82
|
export interface DeadLetterListFilter {
|
|
83
83
|
status?: DeadLetterStatus;
|
|
84
84
|
requestName?: string;
|
|
85
|
+
/** Only the records captured in this tenant. Absent: the records of every tenant. */
|
|
86
|
+
tenantId?: string;
|
|
85
87
|
/** Most records to return, oldest first. Default `100`. */
|
|
86
88
|
limit?: number;
|
|
87
89
|
}
|
|
@@ -95,7 +97,17 @@ export interface DeadLetterStore extends DeadLetterTransport {
|
|
|
95
97
|
get(id: string): Promise<DeadLetterRecord | undefined>;
|
|
96
98
|
/** Records matching the filter, oldest first. */
|
|
97
99
|
list(filter?: DeadLetterListFilter): Promise<DeadLetterRecord[]>;
|
|
98
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Takes the open record for one redrive, in one atomic step, so that two
|
|
102
|
+
* redrives of one record cannot both dispatch it. The claim ends with
|
|
103
|
+
* {@link recordAttempt} or {@link markResolved}, or after `leaseMs`, which
|
|
104
|
+
* frees the record of a process that stopped during the handling.
|
|
105
|
+
*
|
|
106
|
+
* @param leaseMs - How long the claim holds, in milliseconds.
|
|
107
|
+
* @returns `false` when the record is absent, resolved or claimed.
|
|
108
|
+
*/
|
|
109
|
+
claim(id: string, leaseMs: number): Promise<boolean>;
|
|
110
|
+
/** Counts one failed redrive attempt, keeps its error and ends the claim. */
|
|
99
111
|
recordAttempt(id: string, error: DeadLetterError): Promise<void>;
|
|
100
112
|
/** Closes the record. */
|
|
101
113
|
markResolved(id: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dead-letter-transport.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/dead-letter-transport.interface.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9E,kCAAkC;AAClC,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnD,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,WAAW,EAAE,qBAAqB,CAAC;IACnC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,EAAE,eAAe,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAgB,SAAQ,mBAAmB;IAC1D,+CAA+C;IAC/C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACvD,iDAAiD;IACjD,IAAI,CAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACjE,
|
|
1
|
+
{"version":3,"file":"dead-letter-transport.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/dead-letter-transport.interface.ts"],"names":[],"mappings":"AAEA,mDAAmD;AACnD,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;AAE9E,kCAAkC;AAClC,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,CAAC;AAEnD,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IACX,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,WAAW,EAAE,qBAAqB,CAAC;IACnC,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,EAAE,eAAe,CAAC;IACvB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,MAAM,EAAE,gBAAgB,CAAC;IACzB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;OAOG;IACH,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,+CAA+C;AAC/C,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAgB,SAAQ,mBAAmB;IAC1D,+CAA+C;IAC/C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IACvD,iDAAiD;IACjD,IAAI,CAAC,MAAM,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IACjE;;;;;;;;OAQG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACrD,6EAA6E;IAC7E,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,yBAAyB;IACzB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC"}
|
|
@@ -1,12 +1,6 @@
|
|
|
1
|
+
import { type PostgresQueryableLike } from '@cqrs-ddd/pipeline';
|
|
1
2
|
import type { DeadLetterError, DeadLetterListFilter, DeadLetterRecord, DeadLetterStore } from '../interfaces/dead-letter-transport.interface.js';
|
|
2
|
-
|
|
3
|
-
* Minimal structural shape of a `pg` `Pool` / `Client`. Declared locally so this
|
|
4
|
-
* package does not hard-depend on `pg` — a real `Pool` or `Client` satisfies it.
|
|
5
|
-
* Add it in your app: `pnpm add pg`.
|
|
6
|
-
*/
|
|
7
|
-
export interface PostgresQueryableLike {
|
|
8
|
-
query(text: string, values?: unknown[]): Promise<unknown>;
|
|
9
|
-
}
|
|
3
|
+
export type { PostgresQueryableLike };
|
|
10
4
|
/** Options for {@link PostgresDeadLetterTransport}. */
|
|
11
5
|
export interface PostgresDeadLetterTransportOptions {
|
|
12
6
|
/**
|
|
@@ -16,7 +10,9 @@ export interface PostgresDeadLetterTransportOptions {
|
|
|
16
10
|
table?: string;
|
|
17
11
|
}
|
|
18
12
|
/**
|
|
19
|
-
* SQL to create the dead-letter table. Run
|
|
13
|
+
* SQL to create the dead-letter table. Run it in a migration. It is safe to
|
|
14
|
+
* run again: it also adds the `claimed_until` and `tenant_id` columns to a
|
|
15
|
+
* table that does not have them.
|
|
20
16
|
*
|
|
21
17
|
* @param table - Table name (validated). Default `'dead_letters'`.
|
|
22
18
|
*/
|
|
@@ -44,6 +40,7 @@ export declare class PostgresDeadLetterTransport implements DeadLetterStore {
|
|
|
44
40
|
send(record: DeadLetterRecord): Promise<void>;
|
|
45
41
|
get(id: string): Promise<DeadLetterRecord | undefined>;
|
|
46
42
|
list(filter?: DeadLetterListFilter): Promise<DeadLetterRecord[]>;
|
|
43
|
+
claim(id: string, leaseMs: number): Promise<boolean>;
|
|
47
44
|
recordAttempt(id: string, error: DeadLetterError): Promise<void>;
|
|
48
45
|
markResolved(id: string): Promise<void>;
|
|
49
46
|
private rows;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.transport.d.ts","sourceRoot":"","sources":["../../src/transports/postgres.transport.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgres.transport.d.ts","sourceRoot":"","sources":["../../src/transports/postgres.transport.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EAChB,MAAM,kDAAkD,CAAC;AAE1D,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,uDAAuD;AACvD,MAAM,WAAW,kCAAkC;IACjD;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,SAAiB,GAAG,MAAM,CAsBvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,2BAA4B,YAAW,eAAe;IAI/D,OAAO,CAAC,QAAQ,CAAC,EAAE;IAHrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B,YACmB,EAAE,EAAE,qBAAqB,EAC1C,OAAO,GAAE,kCAAuC,EAGjD;IAEK,IAAI,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBlD;IAEK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAK3D;IAEK,IAAI,CAAC,MAAM,GAAE,oBAAyB,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAezE;IAEK,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAUzD;IAEK,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAKrE;IAEK,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK5C;YAEa,IAAI;CASnB"}
|
|
@@ -1,21 +1,15 @@
|
|
|
1
1
|
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
2
|
-
import { toPostgresJson } from '@cqrs-ddd/pipeline';
|
|
3
|
-
|
|
4
|
-
const SAFE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$/;
|
|
5
|
-
function assertSafeTable(table) {
|
|
6
|
-
if (!SAFE_IDENTIFIER.test(table)) {
|
|
7
|
-
throw new Error(`Invalid dead-letter table name "${table}". ` +
|
|
8
|
-
'Use an unquoted identifier like "dead_letters" or "schema.dead_letters".');
|
|
9
|
-
}
|
|
10
|
-
return table;
|
|
11
|
-
}
|
|
2
|
+
import { assertSafeTable, toPostgresJson, } from '@cqrs-ddd/pipeline';
|
|
3
|
+
const safeTable = (table) => assertSafeTable(table, 'dead-letter', 'dead_letters');
|
|
12
4
|
/**
|
|
13
|
-
* SQL to create the dead-letter table. Run
|
|
5
|
+
* SQL to create the dead-letter table. Run it in a migration. It is safe to
|
|
6
|
+
* run again: it also adds the `claimed_until` and `tenant_id` columns to a
|
|
7
|
+
* table that does not have them.
|
|
14
8
|
*
|
|
15
9
|
* @param table - Table name (validated). Default `'dead_letters'`.
|
|
16
10
|
*/
|
|
17
11
|
export function createDeadLetterTableSql(table = 'dead_letters') {
|
|
18
|
-
const name =
|
|
12
|
+
const name = safeTable(table);
|
|
19
13
|
return `CREATE TABLE IF NOT EXISTS ${name} (
|
|
20
14
|
id UUID PRIMARY KEY,
|
|
21
15
|
correlation_id TEXT NOT NULL,
|
|
@@ -30,8 +24,12 @@ export function createDeadLetterTableSql(table = 'dead_letters') {
|
|
|
30
24
|
status TEXT NOT NULL DEFAULT 'open',
|
|
31
25
|
payload_redacted BOOLEAN NOT NULL DEFAULT false,
|
|
32
26
|
last_error JSONB,
|
|
33
|
-
resolved_at TIMESTAMPTZ
|
|
34
|
-
|
|
27
|
+
resolved_at TIMESTAMPTZ,
|
|
28
|
+
claimed_until TIMESTAMPTZ,
|
|
29
|
+
tenant_id TEXT
|
|
30
|
+
);
|
|
31
|
+
ALTER TABLE ${name} ADD COLUMN IF NOT EXISTS claimed_until TIMESTAMPTZ;
|
|
32
|
+
ALTER TABLE ${name} ADD COLUMN IF NOT EXISTS tenant_id TEXT;`;
|
|
35
33
|
}
|
|
36
34
|
/**
|
|
37
35
|
* {@link DeadLetterStore} backed by **Postgres** (`pg`): inserts each dead
|
|
@@ -54,13 +52,13 @@ export class PostgresDeadLetterTransport {
|
|
|
54
52
|
table;
|
|
55
53
|
constructor(db, options = {}) {
|
|
56
54
|
this.db = db;
|
|
57
|
-
this.table =
|
|
55
|
+
this.table = safeTable(options.table ?? 'dead_letters');
|
|
58
56
|
}
|
|
59
57
|
async send(record) {
|
|
60
58
|
await this.db.query(`INSERT INTO ${this.table}
|
|
61
59
|
(id, correlation_id, request_kind, request_name, handler_name, payload,
|
|
62
|
-
error, metadata, failed_at, attempts, status, payload_redacted)
|
|
63
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, [
|
|
60
|
+
error, metadata, failed_at, attempts, status, payload_redacted, tenant_id)
|
|
61
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13)`, [
|
|
64
62
|
record.id,
|
|
65
63
|
record.correlationId,
|
|
66
64
|
record.requestKind,
|
|
@@ -73,6 +71,7 @@ export class PostgresDeadLetterTransport {
|
|
|
73
71
|
record.attempts,
|
|
74
72
|
record.status,
|
|
75
73
|
record.payloadRedacted,
|
|
74
|
+
record.tenantId ?? null,
|
|
76
75
|
]);
|
|
77
76
|
}
|
|
78
77
|
async get(id) {
|
|
@@ -85,14 +84,28 @@ export class PostgresDeadLetterTransport {
|
|
|
85
84
|
return this.rows(`SELECT * FROM ${this.table}
|
|
86
85
|
WHERE ($1::text IS NULL OR status = $1)
|
|
87
86
|
AND ($2::text IS NULL OR request_name = $2)
|
|
87
|
+
AND ($4::text IS NULL OR tenant_id = $4)
|
|
88
88
|
ORDER BY id
|
|
89
|
-
LIMIT $3`, [
|
|
89
|
+
LIMIT $3`, [
|
|
90
|
+
filter.status ?? null,
|
|
91
|
+
filter.requestName ?? null,
|
|
92
|
+
filter.limit ?? 100,
|
|
93
|
+
filter.tenantId ?? null,
|
|
94
|
+
]);
|
|
95
|
+
}
|
|
96
|
+
async claim(id, leaseMs) {
|
|
97
|
+
const result = (await this.db.query(`UPDATE ${this.table}
|
|
98
|
+
SET claimed_until = now() + $2 * interval '1 millisecond'
|
|
99
|
+
WHERE id = $1 AND status = 'open'
|
|
100
|
+
AND (claimed_until IS NULL OR claimed_until <= now())
|
|
101
|
+
RETURNING id`, [id, leaseMs]));
|
|
102
|
+
return result.rows?.length === 1;
|
|
90
103
|
}
|
|
91
104
|
async recordAttempt(id, error) {
|
|
92
|
-
await this.db.query(`UPDATE ${this.table} SET attempts = attempts + 1, last_error = $2 WHERE id = $1`, [id, json(error)]);
|
|
105
|
+
await this.db.query(`UPDATE ${this.table} SET attempts = attempts + 1, last_error = $2, claimed_until = NULL WHERE id = $1`, [id, json(error)]);
|
|
93
106
|
}
|
|
94
107
|
async markResolved(id) {
|
|
95
|
-
await this.db.query(`UPDATE ${this.table} SET status = 'resolved', resolved_at = now() WHERE id = $1`, [id]);
|
|
108
|
+
await this.db.query(`UPDATE ${this.table} SET status = 'resolved', resolved_at = now(), claimed_until = NULL WHERE id = $1`, [id]);
|
|
96
109
|
}
|
|
97
110
|
async rows(sql, values) {
|
|
98
111
|
const result = (await this.db.query(sql, values));
|
|
@@ -103,7 +116,7 @@ function json(value) {
|
|
|
103
116
|
return toPostgresJson(JSON.stringify(value));
|
|
104
117
|
}
|
|
105
118
|
function toRecord(row) {
|
|
106
|
-
const tenantId = row.metadata?.tenantId;
|
|
119
|
+
const tenantId = row.tenant_id ?? row.metadata?.tenantId;
|
|
107
120
|
return {
|
|
108
121
|
id: row.id,
|
|
109
122
|
correlationId: row.correlation_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.transport.js","sourceRoot":"","sources":["../../src/transports/postgres.transport.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,
|
|
1
|
+
{"version":3,"file":"postgres.transport.js","sourceRoot":"","sources":["../../src/transports/postgres.transport.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cqrs-ddd/pipeline-deadletter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Dead letters for @cqrs-ddd/pipeline: captures failed commands and events with their context to a queue or table, and redrives them",
|
|
5
5
|
"author": "Aristotelis",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@cqrs-ddd/pipeline": "^0.
|
|
51
|
+
"@cqrs-ddd/pipeline": "^0.6.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
|
+
"@cqrs-ddd/pipeline": "0.6.0",
|
|
54
55
|
"@vitest/coverage-v8": "^5.0.5",
|
|
55
|
-
"vitest": "^5.0.5"
|
|
56
|
-
"@cqrs-ddd/pipeline": "0.5.1"
|
|
56
|
+
"vitest": "^5.0.5"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@cqrs-ddd/safe-stringify": "^0.
|
|
60
|
-
"@cqrs-ddd/uuidv7": "^0.
|
|
59
|
+
"@cqrs-ddd/safe-stringify": "^0.6.0",
|
|
60
|
+
"@cqrs-ddd/uuidv7": "^0.6.0"
|
|
61
61
|
},
|
|
62
62
|
"scripts": {
|
|
63
63
|
"build": "tsc -p tsconfig.build.json",
|