@zdavison/matador 2.0.7 → 2.0.9
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/package.json +3 -2
- package/src/hooks/safe-hooks.ts +0 -16
- package/src/hooks/types.ts +0 -7
- package/src/index.ts +1 -0
- package/src/types/event.ts +8 -14
- package/src/types/index.ts +3 -2
- package/dist/checkpoint/context.d.ts +0 -59
- package/dist/checkpoint/context.d.ts.map +0 -1
- package/dist/checkpoint/context.js +0 -140
- package/dist/checkpoint/context.test.d.ts +0 -2
- package/dist/checkpoint/context.test.d.ts.map +0 -1
- package/dist/checkpoint/context.test.js +0 -424
- package/dist/checkpoint/index.d.ts +0 -7
- package/dist/checkpoint/index.d.ts.map +0 -1
- package/dist/checkpoint/index.js +0 -6
- package/dist/checkpoint/stores/memory.d.ts +0 -29
- package/dist/checkpoint/stores/memory.d.ts.map +0 -1
- package/dist/checkpoint/stores/memory.js +0 -39
- package/dist/checkpoint/stores/noop.d.ts +0 -14
- package/dist/checkpoint/stores/noop.d.ts.map +0 -1
- package/dist/checkpoint/stores/noop.js +0 -18
- package/dist/checkpoint/stores/stores.test.d.ts +0 -2
- package/dist/checkpoint/stores/stores.test.d.ts.map +0 -1
- package/dist/checkpoint/stores/stores.test.js +0 -146
- package/dist/checkpoint/types.d.ts +0 -119
- package/dist/checkpoint/types.d.ts.map +0 -1
- package/dist/checkpoint/types.js +0 -1
- package/dist/codec/codec.d.ts +0 -29
- package/dist/codec/codec.d.ts.map +0 -1
- package/dist/codec/codec.js +0 -15
- package/dist/codec/header-aware-codec.d.ts +0 -36
- package/dist/codec/header-aware-codec.d.ts.map +0 -1
- package/dist/codec/header-aware-codec.js +0 -1
- package/dist/codec/index.d.ts +0 -6
- package/dist/codec/index.d.ts.map +0 -1
- package/dist/codec/index.js +0 -3
- package/dist/codec/json-codec.d.ts +0 -13
- package/dist/codec/json-codec.d.ts.map +0 -1
- package/dist/codec/json-codec.js +0 -64
- package/dist/codec/rabbitmq-codec.d.ts +0 -28
- package/dist/codec/rabbitmq-codec.d.ts.map +0 -1
- package/dist/codec/rabbitmq-codec.js +0 -242
- package/dist/codec/rabbitmq-codec.test.d.ts +0 -2
- package/dist/codec/rabbitmq-codec.test.d.ts.map +0 -1
- package/dist/codec/rabbitmq-codec.test.js +0 -433
- package/dist/core/fanout.d.ts +0 -59
- package/dist/core/fanout.d.ts.map +0 -1
- package/dist/core/fanout.js +0 -121
- package/dist/core/fanout.test.d.ts +0 -2
- package/dist/core/fanout.test.d.ts.map +0 -1
- package/dist/core/fanout.test.js +0 -1054
- package/dist/core/index.d.ts +0 -7
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -3
- package/dist/core/matador.d.ts +0 -133
- package/dist/core/matador.d.ts.map +0 -1
- package/dist/core/matador.js +0 -228
- package/dist/core/matador.test.d.ts +0 -2
- package/dist/core/matador.test.d.ts.map +0 -1
- package/dist/core/matador.test.js +0 -446
- package/dist/core/shutdown.d.ts +0 -78
- package/dist/core/shutdown.d.ts.map +0 -1
- package/dist/core/shutdown.js +0 -111
- package/dist/core/shutdown.test.d.ts +0 -2
- package/dist/core/shutdown.test.d.ts.map +0 -1
- package/dist/core/shutdown.test.js +0 -524
- package/dist/errors/checkpoint-errors.d.ts +0 -30
- package/dist/errors/checkpoint-errors.d.ts.map +0 -1
- package/dist/errors/checkpoint-errors.js +0 -49
- package/dist/errors/has-description.d.ts +0 -18
- package/dist/errors/has-description.d.ts.map +0 -1
- package/dist/errors/has-description.js +0 -9
- package/dist/errors/index.d.ts +0 -6
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -22
- package/dist/errors/matador-errors.d.ts +0 -183
- package/dist/errors/matador-errors.d.ts.map +0 -1
- package/dist/errors/matador-errors.js +0 -376
- package/dist/errors/retry-errors.d.ts +0 -102
- package/dist/errors/retry-errors.d.ts.map +0 -1
- package/dist/errors/retry-errors.js +0 -155
- package/dist/errors/retry-errors.test.d.ts +0 -2
- package/dist/errors/retry-errors.test.d.ts.map +0 -1
- package/dist/errors/retry-errors.test.js +0 -136
- package/dist/hooks/index.d.ts +0 -4
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -2
- package/dist/hooks/safe-hooks.d.ts +0 -33
- package/dist/hooks/safe-hooks.d.ts.map +0 -1
- package/dist/hooks/safe-hooks.js +0 -132
- package/dist/hooks/types.d.ts +0 -176
- package/dist/hooks/types.d.ts.map +0 -1
- package/dist/hooks/types.js +0 -9
- package/dist/index.cjs +0 -3242
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -23
- package/dist/index.d.ts +0 -23
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -31
- package/dist/index.js.map +0 -1
- package/dist/pipeline/index.d.ts +0 -3
- package/dist/pipeline/index.d.ts.map +0 -1
- package/dist/pipeline/index.js +0 -1
- package/dist/pipeline/pipeline.d.ts +0 -63
- package/dist/pipeline/pipeline.d.ts.map +0 -1
- package/dist/pipeline/pipeline.js +0 -273
- package/dist/pipeline/pipeline.test.d.ts +0 -2
- package/dist/pipeline/pipeline.test.d.ts.map +0 -1
- package/dist/pipeline/pipeline.test.js +0 -1112
- package/dist/retry/index.d.ts +0 -4
- package/dist/retry/index.d.ts.map +0 -1
- package/dist/retry/index.js +0 -1
- package/dist/retry/policy.d.ts +0 -43
- package/dist/retry/policy.d.ts.map +0 -1
- package/dist/retry/policy.js +0 -1
- package/dist/retry/standard-policy.d.ts +0 -44
- package/dist/retry/standard-policy.d.ts.map +0 -1
- package/dist/retry/standard-policy.js +0 -102
- package/dist/retry/standard-policy.test.d.ts +0 -2
- package/dist/retry/standard-policy.test.d.ts.map +0 -1
- package/dist/retry/standard-policy.test.js +0 -196
- package/dist/schema/index.d.ts +0 -4
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/index.js +0 -2
- package/dist/schema/registry.d.ts +0 -63
- package/dist/schema/registry.d.ts.map +0 -1
- package/dist/schema/registry.js +0 -174
- package/dist/schema/registry.test.d.ts +0 -2
- package/dist/schema/registry.test.d.ts.map +0 -1
- package/dist/schema/registry.test.js +0 -278
- package/dist/schema/types.d.ts +0 -158
- package/dist/schema/types.d.ts.map +0 -1
- package/dist/schema/types.js +0 -74
- package/dist/schema/types.test.d.ts +0 -2
- package/dist/schema/types.test.d.ts.map +0 -1
- package/dist/schema/types.test.js +0 -242
- package/dist/topology/builder.d.ts +0 -80
- package/dist/topology/builder.d.ts.map +0 -1
- package/dist/topology/builder.js +0 -165
- package/dist/topology/builder.test.d.ts +0 -2
- package/dist/topology/builder.test.d.ts.map +0 -1
- package/dist/topology/builder.test.js +0 -360
- package/dist/topology/index.d.ts +0 -5
- package/dist/topology/index.d.ts.map +0 -1
- package/dist/topology/index.js +0 -2
- package/dist/topology/types.d.ts +0 -128
- package/dist/topology/types.d.ts.map +0 -1
- package/dist/topology/types.js +0 -28
- package/dist/transport/capabilities.d.ts +0 -66
- package/dist/transport/capabilities.d.ts.map +0 -1
- package/dist/transport/capabilities.js +0 -18
- package/dist/transport/connection-manager.d.ts +0 -95
- package/dist/transport/connection-manager.d.ts.map +0 -1
- package/dist/transport/connection-manager.js +0 -144
- package/dist/transport/index.d.ts +0 -11
- package/dist/transport/index.d.ts.map +0 -1
- package/dist/transport/index.js +0 -5
- package/dist/transport/local/local-transport.d.ts +0 -62
- package/dist/transport/local/local-transport.d.ts.map +0 -1
- package/dist/transport/local/local-transport.js +0 -241
- package/dist/transport/local/local-transport.test.d.ts +0 -2
- package/dist/transport/local/local-transport.test.d.ts.map +0 -1
- package/dist/transport/local/local-transport.test.js +0 -192
- package/dist/transport/multi/multi-transport.d.ts +0 -94
- package/dist/transport/multi/multi-transport.d.ts.map +0 -1
- package/dist/transport/multi/multi-transport.js +0 -184
- package/dist/transport/multi/multi-transport.test.d.ts +0 -2
- package/dist/transport/multi/multi-transport.test.d.ts.map +0 -1
- package/dist/transport/multi/multi-transport.test.js +0 -236
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts +0 -83
- package/dist/transport/rabbitmq/rabbitmq-transport.d.ts.map +0 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.js +0 -541
- package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts +0 -2
- package/dist/transport/rabbitmq/rabbitmq-transport.test.d.ts.map +0 -1
- package/dist/transport/rabbitmq/rabbitmq-transport.test.js +0 -100
- package/dist/transport/transport.d.ts +0 -152
- package/dist/transport/transport.d.ts.map +0 -1
- package/dist/transport/transport.js +0 -1
- package/dist/types/common.d.ts +0 -41
- package/dist/types/common.d.ts.map +0 -1
- package/dist/types/common.js +0 -12
- package/dist/types/dispatcher.d.ts +0 -14
- package/dist/types/dispatcher.d.ts.map +0 -1
- package/dist/types/dispatcher.js +0 -1
- package/dist/types/envelope.d.ts +0 -131
- package/dist/types/envelope.d.ts.map +0 -1
- package/dist/types/envelope.js +0 -99
- package/dist/types/event.d.ts +0 -96
- package/dist/types/event.d.ts.map +0 -1
- package/dist/types/event.js +0 -26
- package/dist/types/event.test.d.ts +0 -2
- package/dist/types/event.test.d.ts.map +0 -1
- package/dist/types/event.test.js +0 -130
- package/dist/types/index.d.ts +0 -10
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -4
- package/dist/types/subscriber.d.ts +0 -227
- package/dist/types/subscriber.d.ts.map +0 -1
- package/dist/types/subscriber.js +0 -97
- package/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zdavison/matador",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.9",
|
|
4
4
|
"description": "A batteries-included event system.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"send-test-event": "bun ./cli.ts ./examples/config.ts ./examples/event.ts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"amqplib": "^0.10.4"
|
|
37
|
+
"amqplib": "^0.10.4",
|
|
38
|
+
"type-fest": "^5.3.1"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"@testcontainers/rabbitmq": "^10.16.0",
|
package/src/hooks/safe-hooks.ts
CHANGED
|
@@ -116,22 +116,6 @@ export class SafeHooks {
|
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async getQueueConcurrency(queueName: string): Promise<number | undefined> {
|
|
120
|
-
if (!this.hooks.getQueueConcurrency) {
|
|
121
|
-
return undefined;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
return await this.hooks.getQueueConcurrency(queueName);
|
|
126
|
-
} catch (error) {
|
|
127
|
-
this.logger.warn(
|
|
128
|
-
'[Matador] 🟡 Hook getQueueConcurrency threw an error',
|
|
129
|
-
error,
|
|
130
|
-
);
|
|
131
|
-
return undefined;
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
119
|
async getRetryDelay(
|
|
136
120
|
envelope: Envelope,
|
|
137
121
|
attemptNumber: number,
|
package/src/hooks/types.ts
CHANGED
|
@@ -176,13 +176,6 @@ export interface MatadorHooks {
|
|
|
176
176
|
| Record<string, unknown>
|
|
177
177
|
| Promise<Record<string, unknown>>;
|
|
178
178
|
|
|
179
|
-
/**
|
|
180
|
-
* Dynamic queue concurrency lookup.
|
|
181
|
-
*/
|
|
182
|
-
getQueueConcurrency?(
|
|
183
|
-
queueName: string,
|
|
184
|
-
): number | undefined | Promise<number | undefined>;
|
|
185
|
-
|
|
186
179
|
/**
|
|
187
180
|
* Dynamic retry delay lookup.
|
|
188
181
|
*/
|
package/src/index.ts
CHANGED
package/src/types/event.ts
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
|
+
import type { Jsonifiable } from 'type-fest';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Unique event routing key type alias.
|
|
3
5
|
*/
|
|
4
6
|
export type EventKey = string;
|
|
5
7
|
|
|
6
|
-
/**
|
|
7
|
-
* JSON-serializable primitive types.
|
|
8
|
-
*/
|
|
9
|
-
export type JsonPrimitive = string | number | boolean | null;
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* JSON-serializable value (recursive type for objects and arrays).
|
|
13
|
-
*/
|
|
14
|
-
export type JsonValue =
|
|
15
|
-
| JsonPrimitive
|
|
16
|
-
| JsonValue[]
|
|
17
|
-
| { [key: string]: JsonValue };
|
|
18
|
-
|
|
19
8
|
/**
|
|
20
9
|
* JSON-serializable record type for metadata.
|
|
10
|
+
* Uses type-fest's Jsonifiable which accepts:
|
|
11
|
+
* - Primitives (string, number, boolean, null)
|
|
12
|
+
* - Arrays of Jsonifiable values
|
|
13
|
+
* - Objects with Jsonifiable values
|
|
14
|
+
* - Objects with a toJSON() method
|
|
21
15
|
*/
|
|
22
|
-
export type JsonRecord = Record<string,
|
|
16
|
+
export type JsonRecord = Record<string, Jsonifiable>;
|
|
23
17
|
|
|
24
18
|
/**
|
|
25
19
|
* Static properties required on Event classes for schema registration.
|
package/src/types/index.ts
CHANGED
|
@@ -24,12 +24,13 @@ export type {
|
|
|
24
24
|
EventKey,
|
|
25
25
|
EventOptions,
|
|
26
26
|
EventStatic,
|
|
27
|
-
JsonPrimitive,
|
|
28
27
|
JsonRecord,
|
|
29
|
-
JsonValue,
|
|
30
28
|
} from './event.js';
|
|
31
29
|
export { MatadorEvent } from './event.js';
|
|
32
30
|
|
|
31
|
+
// Re-export Jsonifiable from type-fest for convenience
|
|
32
|
+
export type { Jsonifiable } from 'type-fest';
|
|
33
|
+
|
|
33
34
|
export type {
|
|
34
35
|
AnySubscriber,
|
|
35
36
|
BaseSubscriberOptions,
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Envelope, SubscriberDefinition } from '../types/index.js';
|
|
2
|
-
import type { Checkpoint, CheckpointHitContext, CheckpointMissContext, CheckpointStore, JsonSerializable, SubscriberContext } from './types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Hooks for observability during context operations.
|
|
5
|
-
*/
|
|
6
|
-
export interface ResumableContextHooks {
|
|
7
|
-
onCheckpointHit?(context: CheckpointHitContext): void | Promise<void>;
|
|
8
|
-
onCheckpointMiss?(context: CheckpointMissContext): void | Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Configuration for creating a ResumableContext.
|
|
12
|
-
*/
|
|
13
|
-
export interface ResumableContextConfig {
|
|
14
|
-
readonly store: CheckpointStore;
|
|
15
|
-
readonly envelope: Envelope;
|
|
16
|
-
readonly subscriber: SubscriberDefinition;
|
|
17
|
-
readonly existingCheckpoint?: Checkpoint | undefined;
|
|
18
|
-
readonly hooks?: ResumableContextHooks | undefined;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Implementation of SubscriberContext that provides io() caching.
|
|
22
|
-
*
|
|
23
|
-
* On first execution, io() calls execute their lambdas and cache results.
|
|
24
|
-
* On retry (when existingCheckpoint is provided), cached results are returned
|
|
25
|
-
* without re-executing the lambda.
|
|
26
|
-
*/
|
|
27
|
-
export declare class ResumableContext implements SubscriberContext {
|
|
28
|
-
private checkpoint;
|
|
29
|
-
private readonly usedKeys;
|
|
30
|
-
private readonly store;
|
|
31
|
-
private readonly envelope;
|
|
32
|
-
private readonly subscriber;
|
|
33
|
-
private readonly hooks;
|
|
34
|
-
constructor(config: ResumableContextConfig);
|
|
35
|
-
get attempt(): number;
|
|
36
|
-
get isRetry(): boolean;
|
|
37
|
-
io<T extends JsonSerializable>(key: string, fn: () => Promise<T> | T): Promise<T>;
|
|
38
|
-
all<T extends readonly [
|
|
39
|
-
string,
|
|
40
|
-
() => Promise<JsonSerializable> | JsonSerializable
|
|
41
|
-
][]>(ops: T): Promise<{
|
|
42
|
-
[K in keyof T]: T[K] extends [string, () => Promise<infer R> | infer R] ? R : never;
|
|
43
|
-
}>;
|
|
44
|
-
/**
|
|
45
|
-
* Clears the checkpoint from storage.
|
|
46
|
-
* Called after successful completion or dead-letter.
|
|
47
|
-
*/
|
|
48
|
-
clear(): Promise<void>;
|
|
49
|
-
/**
|
|
50
|
-
* Gets the current checkpoint state.
|
|
51
|
-
* Useful for debugging and testing.
|
|
52
|
-
*/
|
|
53
|
-
getCheckpoint(): Checkpoint;
|
|
54
|
-
/**
|
|
55
|
-
* Gets the number of cached steps.
|
|
56
|
-
*/
|
|
57
|
-
get cachedStepCount(): number;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/checkpoint/context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,KAAK,EACV,UAAU,EACV,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,gBAAgB,CAAC,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IACrD,QAAQ,CAAC,KAAK,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;CACpD;AAED;;;;;;GAMG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAkB;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAW;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuB;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE9C,MAAM,EAAE,sBAAsB;IAa1C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,EAAE,CAAC,CAAC,SAAS,gBAAgB,EACjC,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC;IA0CP,GAAG,CACP,CAAC,SAAS,SAAS;QACjB,MAAM;QACN,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB;KACnD,EAAE,EAEH,GAAG,EAAE,CAAC,GACL,OAAO,CAAC;SACR,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,GACnE,CAAC,GACD,KAAK;KACV,CAAC;IAoEF;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B;;;OAGG;IACH,aAAa,IAAI,UAAU;IAI3B;;OAEG;IACH,IAAI,eAAe,IAAI,MAAM,CAE5B;CACF"}
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { DuplicateIoKeyError } from '../errors/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Implementation of SubscriberContext that provides io() caching.
|
|
4
|
-
*
|
|
5
|
-
* On first execution, io() calls execute their lambdas and cache results.
|
|
6
|
-
* On retry (when existingCheckpoint is provided), cached results are returned
|
|
7
|
-
* without re-executing the lambda.
|
|
8
|
-
*/
|
|
9
|
-
export class ResumableContext {
|
|
10
|
-
checkpoint;
|
|
11
|
-
usedKeys = new Set();
|
|
12
|
-
store;
|
|
13
|
-
envelope;
|
|
14
|
-
subscriber;
|
|
15
|
-
hooks;
|
|
16
|
-
constructor(config) {
|
|
17
|
-
this.store = config.store;
|
|
18
|
-
this.envelope = config.envelope;
|
|
19
|
-
this.subscriber = config.subscriber;
|
|
20
|
-
this.hooks = config.hooks;
|
|
21
|
-
this.checkpoint = config.existingCheckpoint ?? {
|
|
22
|
-
envelopeId: config.envelope.id,
|
|
23
|
-
subscriberName: config.subscriber.name,
|
|
24
|
-
completedSteps: {},
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
get attempt() {
|
|
28
|
-
return this.envelope.docket.attempts;
|
|
29
|
-
}
|
|
30
|
-
get isRetry() {
|
|
31
|
-
return this.attempt > 1;
|
|
32
|
-
}
|
|
33
|
-
async io(key, fn) {
|
|
34
|
-
// Validate key uniqueness within this execution
|
|
35
|
-
if (this.usedKeys.has(key)) {
|
|
36
|
-
throw new DuplicateIoKeyError(key, this.subscriber.name);
|
|
37
|
-
}
|
|
38
|
-
this.usedKeys.add(key);
|
|
39
|
-
// Check cache first
|
|
40
|
-
if (key in this.checkpoint.completedSteps) {
|
|
41
|
-
await this.hooks?.onCheckpointHit?.({
|
|
42
|
-
envelope: this.envelope,
|
|
43
|
-
subscriber: this.subscriber,
|
|
44
|
-
stepKey: key,
|
|
45
|
-
});
|
|
46
|
-
return this.checkpoint.completedSteps[key];
|
|
47
|
-
}
|
|
48
|
-
// Notify cache miss
|
|
49
|
-
await this.hooks?.onCheckpointMiss?.({
|
|
50
|
-
envelope: this.envelope,
|
|
51
|
-
subscriber: this.subscriber,
|
|
52
|
-
stepKey: key,
|
|
53
|
-
});
|
|
54
|
-
// Execute the function - errors propagate, no caching on failure
|
|
55
|
-
const result = await fn();
|
|
56
|
-
// Cache the result
|
|
57
|
-
this.checkpoint = {
|
|
58
|
-
...this.checkpoint,
|
|
59
|
-
completedSteps: {
|
|
60
|
-
...this.checkpoint.completedSteps,
|
|
61
|
-
[key]: result,
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
// Persist checkpoint immediately (incremental persistence)
|
|
65
|
-
await this.store.set(this.envelope.id, this.checkpoint);
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
async all(ops) {
|
|
69
|
-
// First, check for duplicates within this all() call
|
|
70
|
-
const keysInThisCall = new Set();
|
|
71
|
-
for (const [key] of ops) {
|
|
72
|
-
if (keysInThisCall.has(key)) {
|
|
73
|
-
throw new DuplicateIoKeyError(key, this.subscriber.name);
|
|
74
|
-
}
|
|
75
|
-
keysInThisCall.add(key);
|
|
76
|
-
}
|
|
77
|
-
// Then validate against previously used keys
|
|
78
|
-
for (const [key] of ops) {
|
|
79
|
-
if (this.usedKeys.has(key)) {
|
|
80
|
-
throw new DuplicateIoKeyError(key, this.subscriber.name);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Mark all keys as used
|
|
84
|
-
for (const [key] of ops) {
|
|
85
|
-
this.usedKeys.add(key);
|
|
86
|
-
}
|
|
87
|
-
// Execute all operations in parallel
|
|
88
|
-
const results = await Promise.all(ops.map(async ([key, fn]) => {
|
|
89
|
-
// Check cache first
|
|
90
|
-
if (key in this.checkpoint.completedSteps) {
|
|
91
|
-
await this.hooks?.onCheckpointHit?.({
|
|
92
|
-
envelope: this.envelope,
|
|
93
|
-
subscriber: this.subscriber,
|
|
94
|
-
stepKey: key,
|
|
95
|
-
});
|
|
96
|
-
return this.checkpoint.completedSteps[key];
|
|
97
|
-
}
|
|
98
|
-
// Notify cache miss
|
|
99
|
-
await this.hooks?.onCheckpointMiss?.({
|
|
100
|
-
envelope: this.envelope,
|
|
101
|
-
subscriber: this.subscriber,
|
|
102
|
-
stepKey: key,
|
|
103
|
-
});
|
|
104
|
-
// Execute - errors propagate
|
|
105
|
-
const result = await fn();
|
|
106
|
-
// Cache individually (in local state, will persist after Promise.all)
|
|
107
|
-
this.checkpoint = {
|
|
108
|
-
...this.checkpoint,
|
|
109
|
-
completedSteps: {
|
|
110
|
-
...this.checkpoint.completedSteps,
|
|
111
|
-
[key]: result,
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
return result;
|
|
115
|
-
}));
|
|
116
|
-
// Persist after all parallel operations complete
|
|
117
|
-
await this.store.set(this.envelope.id, this.checkpoint);
|
|
118
|
-
return results;
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Clears the checkpoint from storage.
|
|
122
|
-
* Called after successful completion or dead-letter.
|
|
123
|
-
*/
|
|
124
|
-
async clear() {
|
|
125
|
-
await this.store.delete(this.envelope.id);
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Gets the current checkpoint state.
|
|
129
|
-
* Useful for debugging and testing.
|
|
130
|
-
*/
|
|
131
|
-
getCheckpoint() {
|
|
132
|
-
return this.checkpoint;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Gets the number of cached steps.
|
|
136
|
-
*/
|
|
137
|
-
get cachedStepCount() {
|
|
138
|
-
return Object.keys(this.checkpoint.completedSteps).length;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.test.d.ts","sourceRoot":"","sources":["../../src/checkpoint/context.test.ts"],"names":[],"mappings":""}
|