@tonytang99/integration-core 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/builder.d.ts +70 -1
- package/dist/pipeline/builder.d.ts.map +1 -1
- package/dist/pipeline/builder.js +113 -1
- package/dist/pipeline/builder.js.map +1 -1
- package/dist/pipeline/iterators.d.ts +74 -0
- package/dist/pipeline/iterators.d.ts.map +1 -0
- package/dist/pipeline/iterators.js +244 -0
- package/dist/pipeline/iterators.js.map +1 -0
- package/dist/pipeline/retry.d.ts +57 -0
- package/dist/pipeline/retry.d.ts.map +1 -0
- package/dist/pipeline/retry.js +139 -0
- package/dist/pipeline/retry.js.map +1 -0
- package/dist/types/errors.d.ts +62 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +262 -0
- package/dist/types/errors.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export * from './types/common';
|
|
2
|
+
export * from './types/errors';
|
|
2
3
|
export * from './pipeline/context';
|
|
3
4
|
export * from './pipeline/phase';
|
|
4
5
|
export * from './pipeline/builder';
|
|
5
6
|
export * from './pipeline/executor';
|
|
6
7
|
export * from './pipeline/middleware';
|
|
8
|
+
export * from './pipeline/retry';
|
|
9
|
+
export * from './pipeline/iterators';
|
|
7
10
|
export * from './slots/well-known-slots';
|
|
8
11
|
export * from './registry/phase-registry';
|
|
9
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAG/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,0BAA0B,CAAC;AAGzC,cAAc,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,12 +16,15 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
// Types
|
|
18
18
|
__exportStar(require("./types/common"), exports);
|
|
19
|
+
__exportStar(require("./types/errors"), exports);
|
|
19
20
|
// Pipeline
|
|
20
21
|
__exportStar(require("./pipeline/context"), exports);
|
|
21
22
|
__exportStar(require("./pipeline/phase"), exports);
|
|
22
23
|
__exportStar(require("./pipeline/builder"), exports);
|
|
23
24
|
__exportStar(require("./pipeline/executor"), exports);
|
|
24
25
|
__exportStar(require("./pipeline/middleware"), exports);
|
|
26
|
+
__exportStar(require("./pipeline/retry"), exports);
|
|
27
|
+
__exportStar(require("./pipeline/iterators"), exports);
|
|
25
28
|
// Slots
|
|
26
29
|
__exportStar(require("./slots/well-known-slots"), exports);
|
|
27
30
|
// Registry
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,QAAQ;AACR,iDAA+B;AAE/B,WAAW;AACX,qDAAmC;AACnC,mDAAiC;AACjC,qDAAmC;AACnC,sDAAoC;AACpC,wDAAsC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,QAAQ;AACR,iDAA+B;AAC/B,iDAA+B;AAE/B,WAAW;AACX,qDAAmC;AACnC,mDAAiC;AACjC,qDAAmC;AACnC,sDAAoC;AACpC,wDAAsC;AACtC,mDAAiC;AACjC,uDAAqC;AAErC,QAAQ;AACR,2DAAyC;AAEzC,WAAW;AACX,4DAA0C"}
|
|
@@ -1,14 +1,83 @@
|
|
|
1
1
|
import { Phase } from './phase';
|
|
2
2
|
import { Pipeline, ErrorHandler } from './executor';
|
|
3
|
-
import { ClientConfig } from '../types/common';
|
|
3
|
+
import { SlotKey, ClientConfig, PipelineError } from '../types/common';
|
|
4
|
+
import { PipelineContext } from './context';
|
|
4
5
|
export declare class PipelineBuilder {
|
|
5
6
|
private phases;
|
|
6
7
|
private errorHandlers;
|
|
7
8
|
add(phase: Phase): this;
|
|
8
9
|
addIf(condition: boolean | ((config: ClientConfig) => boolean), phase: Phase): this;
|
|
9
10
|
addAll(...phases: Phase[]): this;
|
|
11
|
+
/**
|
|
12
|
+
* Adds a phase that only executes when the predicate returns true.
|
|
13
|
+
* Unlike addIf which checks config at build time, addWhen evaluates
|
|
14
|
+
* the predicate at runtime against the current pipeline context.
|
|
15
|
+
*/
|
|
16
|
+
addWhen(predicate: (ctx: PipelineContext) => boolean | Promise<boolean>, phase: Phase): this;
|
|
17
|
+
/**
|
|
18
|
+
* Adds a branch that executes different phases based on a condition.
|
|
19
|
+
* @param condition - Predicate evaluated at runtime
|
|
20
|
+
* @param ifTrue - Phase(s) to execute when condition is true
|
|
21
|
+
* @param ifFalse - Optional phase(s) to execute when condition is false
|
|
22
|
+
*/
|
|
23
|
+
addBranch(condition: (ctx: PipelineContext) => boolean | Promise<boolean>, ifTrue: Phase | Phase[], ifFalse?: Phase | Phase[]): this;
|
|
10
24
|
onError(phaseOrCode: string, handler: ErrorHandler): this;
|
|
11
25
|
build(): Pipeline;
|
|
12
26
|
private validate;
|
|
13
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Wraps a phase and checks a condition before executing.
|
|
30
|
+
* Proxies all metadata (name, description, tags) to the inner phase.
|
|
31
|
+
*/
|
|
32
|
+
declare class ConditionalPhase implements Phase {
|
|
33
|
+
private inner;
|
|
34
|
+
private condition;
|
|
35
|
+
constructor(inner: Phase, condition: (config: ClientConfig) => boolean);
|
|
36
|
+
get name(): string;
|
|
37
|
+
get description(): string;
|
|
38
|
+
get requires(): SlotKey[];
|
|
39
|
+
get produces(): SlotKey[];
|
|
40
|
+
get optionalReads(): SlotKey[] | undefined;
|
|
41
|
+
get dependsOn(): string[] | undefined;
|
|
42
|
+
get tags(): string[] | undefined;
|
|
43
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
44
|
+
shouldSkip(ctx: PipelineContext): Promise<boolean>;
|
|
45
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Wraps a phase and checks a context-based predicate before executing.
|
|
49
|
+
* This enables runtime decisions based on data in the pipeline context.
|
|
50
|
+
*/
|
|
51
|
+
declare class ContextConditionalPhase implements Phase {
|
|
52
|
+
private inner;
|
|
53
|
+
private predicate;
|
|
54
|
+
constructor(inner: Phase, predicate: (ctx: PipelineContext) => boolean | Promise<boolean>);
|
|
55
|
+
get name(): string;
|
|
56
|
+
get description(): string;
|
|
57
|
+
get requires(): SlotKey[];
|
|
58
|
+
get produces(): SlotKey[];
|
|
59
|
+
get optionalReads(): SlotKey[] | undefined;
|
|
60
|
+
get dependsOn(): string[] | undefined;
|
|
61
|
+
get tags(): string[] | undefined;
|
|
62
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
63
|
+
shouldSkip(ctx: PipelineContext): Promise<boolean>;
|
|
64
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Implements branching logic - executes different phases based on a condition.
|
|
68
|
+
*/
|
|
69
|
+
declare class BranchPhase implements Phase {
|
|
70
|
+
private condition;
|
|
71
|
+
private trueBranch;
|
|
72
|
+
private falseBranch;
|
|
73
|
+
constructor(condition: (ctx: PipelineContext) => boolean | Promise<boolean>, ifTrue: Phase | Phase[], ifFalse?: Phase | Phase[]);
|
|
74
|
+
get name(): string;
|
|
75
|
+
get description(): string;
|
|
76
|
+
get requires(): SlotKey<unknown>[];
|
|
77
|
+
get produces(): SlotKey<unknown>[];
|
|
78
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
79
|
+
shouldSkip(): Promise<boolean>;
|
|
80
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
export { ConditionalPhase, ContextConditionalPhase, BranchPhase };
|
|
14
83
|
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/pipeline/builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/pipeline/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline/builder.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PipelineBuilder = void 0;
|
|
3
|
+
exports.BranchPhase = exports.ContextConditionalPhase = exports.ConditionalPhase = exports.PipelineBuilder = void 0;
|
|
4
4
|
const executor_1 = require("./executor");
|
|
5
5
|
class PipelineBuilder {
|
|
6
6
|
phases = [];
|
|
@@ -22,6 +22,25 @@ class PipelineBuilder {
|
|
|
22
22
|
this.phases.push(...phases);
|
|
23
23
|
return this;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Adds a phase that only executes when the predicate returns true.
|
|
27
|
+
* Unlike addIf which checks config at build time, addWhen evaluates
|
|
28
|
+
* the predicate at runtime against the current pipeline context.
|
|
29
|
+
*/
|
|
30
|
+
addWhen(predicate, phase) {
|
|
31
|
+
this.phases.push(new ContextConditionalPhase(phase, predicate));
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Adds a branch that executes different phases based on a condition.
|
|
36
|
+
* @param condition - Predicate evaluated at runtime
|
|
37
|
+
* @param ifTrue - Phase(s) to execute when condition is true
|
|
38
|
+
* @param ifFalse - Optional phase(s) to execute when condition is false
|
|
39
|
+
*/
|
|
40
|
+
addBranch(condition, ifTrue, ifFalse) {
|
|
41
|
+
this.phases.push(new BranchPhase(condition, ifTrue, ifFalse));
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
25
44
|
onError(phaseOrCode, handler) {
|
|
26
45
|
this.errorHandlers.set(phaseOrCode, handler);
|
|
27
46
|
return this;
|
|
@@ -95,4 +114,97 @@ class ConditionalPhase {
|
|
|
95
114
|
}
|
|
96
115
|
}
|
|
97
116
|
}
|
|
117
|
+
exports.ConditionalPhase = ConditionalPhase;
|
|
118
|
+
/**
|
|
119
|
+
* Wraps a phase and checks a context-based predicate before executing.
|
|
120
|
+
* This enables runtime decisions based on data in the pipeline context.
|
|
121
|
+
*/
|
|
122
|
+
class ContextConditionalPhase {
|
|
123
|
+
inner;
|
|
124
|
+
predicate;
|
|
125
|
+
constructor(inner, predicate) {
|
|
126
|
+
this.inner = inner;
|
|
127
|
+
this.predicate = predicate;
|
|
128
|
+
}
|
|
129
|
+
get name() { return `conditional:${this.inner.name}`; }
|
|
130
|
+
get description() { return `Conditionally executes: ${this.inner.description}`; }
|
|
131
|
+
get requires() { return this.inner.requires; }
|
|
132
|
+
get produces() { return this.inner.produces; }
|
|
133
|
+
get optionalReads() { return this.inner.optionalReads; }
|
|
134
|
+
get dependsOn() { return this.inner.dependsOn; }
|
|
135
|
+
get tags() { return this.inner.tags; }
|
|
136
|
+
async execute(ctx) {
|
|
137
|
+
const shouldExecute = await this.predicate(ctx);
|
|
138
|
+
if (!shouldExecute) {
|
|
139
|
+
return ctx; // Skip execution, return context unchanged
|
|
140
|
+
}
|
|
141
|
+
return this.inner.execute(ctx);
|
|
142
|
+
}
|
|
143
|
+
async shouldSkip(ctx) {
|
|
144
|
+
const shouldExecute = await this.predicate(ctx);
|
|
145
|
+
if (!shouldExecute)
|
|
146
|
+
return true;
|
|
147
|
+
return this.inner.shouldSkip ? await this.inner.shouldSkip(ctx) : false;
|
|
148
|
+
}
|
|
149
|
+
async rollback(ctx, error) {
|
|
150
|
+
if (this.inner.rollback) {
|
|
151
|
+
await this.inner.rollback(ctx, error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
exports.ContextConditionalPhase = ContextConditionalPhase;
|
|
156
|
+
/**
|
|
157
|
+
* Implements branching logic - executes different phases based on a condition.
|
|
158
|
+
*/
|
|
159
|
+
class BranchPhase {
|
|
160
|
+
condition;
|
|
161
|
+
trueBranch;
|
|
162
|
+
falseBranch;
|
|
163
|
+
constructor(condition, ifTrue, ifFalse) {
|
|
164
|
+
this.condition = condition;
|
|
165
|
+
this.trueBranch = Array.isArray(ifTrue) ? ifTrue : [ifTrue];
|
|
166
|
+
this.falseBranch = ifFalse
|
|
167
|
+
? (Array.isArray(ifFalse) ? ifFalse : [ifFalse])
|
|
168
|
+
: [];
|
|
169
|
+
}
|
|
170
|
+
get name() { return 'branch'; }
|
|
171
|
+
get description() { return 'Conditional branch execution'; }
|
|
172
|
+
get requires() {
|
|
173
|
+
// Combine requires from both branches
|
|
174
|
+
const allReqs = new Set();
|
|
175
|
+
[...this.trueBranch, ...this.falseBranch].forEach(p => {
|
|
176
|
+
p.requires.forEach(r => allReqs.add(r));
|
|
177
|
+
});
|
|
178
|
+
return Array.from(allReqs);
|
|
179
|
+
}
|
|
180
|
+
get produces() {
|
|
181
|
+
// Combine produces from both branches
|
|
182
|
+
const allProds = new Set();
|
|
183
|
+
[...this.trueBranch, ...this.falseBranch].forEach(p => {
|
|
184
|
+
p.produces.forEach(r => allProds.add(r));
|
|
185
|
+
});
|
|
186
|
+
return Array.from(allProds);
|
|
187
|
+
}
|
|
188
|
+
async execute(ctx) {
|
|
189
|
+
const result = await this.condition(ctx);
|
|
190
|
+
const branch = result ? this.trueBranch : this.falseBranch;
|
|
191
|
+
let currentCtx = ctx;
|
|
192
|
+
for (const phase of branch) {
|
|
193
|
+
currentCtx = await phase.execute(currentCtx);
|
|
194
|
+
}
|
|
195
|
+
return currentCtx;
|
|
196
|
+
}
|
|
197
|
+
async shouldSkip() {
|
|
198
|
+
return false; // Branch itself doesn't skip, it chooses a path
|
|
199
|
+
}
|
|
200
|
+
async rollback(ctx, error) {
|
|
201
|
+
// Rollback all phases in both branches that might have executed
|
|
202
|
+
for (const phase of [...this.trueBranch, ...this.falseBranch]) {
|
|
203
|
+
if (phase.rollback) {
|
|
204
|
+
await phase.rollback(ctx, error);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.BranchPhase = BranchPhase;
|
|
98
210
|
//# sourceMappingURL=builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/pipeline/builder.ts"],"names":[],"mappings":";;;AAEA,yCAAoD;AAIpD,MAAa,eAAe;IAClB,MAAM,GAAY,EAAE,CAAC;IACrB,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAExD,GAAG,CAAC,KAAY;QACd,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CACH,SAAwD,EACxD,KAAY;QAEZ,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QAC3D,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,GAAG,MAAe;QACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,CAAC,WAAmB,EAAE,OAAqB;QAChD,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,gCAAgC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;QAED,8DAA8D;QAC9D,+CAA+C;QAC/C,OAAO,IAAI,mBAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACvD,CAAC;IAEO,QAAQ;QACd,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QAEnC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACjC,gCAAgC;gBAChC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAa,CAAC,EAAE,CAAC;oBACjC,+BAA+B;oBAC/B,4EAA4E;oBAC5E,MAAM,CAAC,IAAI,CAAC,UAAU,KAAK,CAAC,IAAI,oBAAoB,GAAG,oCAAoC,CAAC,CAAC;gBAC/F,CAAC;YACH,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAClC,QAAQ,CAAC,GAAG,CAAC,IAAc,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/pipeline/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Phase } from './phase';
|
|
2
|
+
import { PipelineContext } from './context';
|
|
3
|
+
import { SlotKey, PipelineError } from '../types/common';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for MapPhase iteration
|
|
6
|
+
*/
|
|
7
|
+
export interface MapPhaseConfig<TInput, TOutput> {
|
|
8
|
+
/** Slot containing the input array to iterate over */
|
|
9
|
+
inputSlot: SlotKey<TInput[]>;
|
|
10
|
+
/** Slot where results array will be stored */
|
|
11
|
+
outputSlot: SlotKey<TOutput[]>;
|
|
12
|
+
/** Slot for current item during iteration (available to sub-phases) */
|
|
13
|
+
itemSlot: SlotKey<TInput>;
|
|
14
|
+
/** Slot for result of current iteration (set by sub-phases) */
|
|
15
|
+
resultSlot: SlotKey<TOutput>;
|
|
16
|
+
/** Phases to execute for each item */
|
|
17
|
+
phases: Phase[];
|
|
18
|
+
/** Max concurrent executions (default: 1 for sequential) */
|
|
19
|
+
concurrency?: number;
|
|
20
|
+
/** Continue processing remaining items if one fails (default: false) */
|
|
21
|
+
continueOnError?: boolean;
|
|
22
|
+
/** Callback for progress updates */
|
|
23
|
+
onProgress?: (completed: number, total: number, item: TInput) => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Phase that iterates over a collection, executing sub-phases for each item.
|
|
27
|
+
* Similar to AWS Step Functions Map state.
|
|
28
|
+
*/
|
|
29
|
+
export declare class MapPhase<TInput, TOutput> implements Phase {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly description: string;
|
|
32
|
+
private readonly config;
|
|
33
|
+
constructor(name: string, config: MapPhaseConfig<TInput, TOutput>);
|
|
34
|
+
get requires(): SlotKey<unknown>[];
|
|
35
|
+
get produces(): SlotKey<unknown>[];
|
|
36
|
+
get optionalReads(): SlotKey<unknown>[] | undefined;
|
|
37
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
38
|
+
private processItem;
|
|
39
|
+
private toPipelineError;
|
|
40
|
+
private isPipelineError;
|
|
41
|
+
private chunk;
|
|
42
|
+
shouldSkip(ctx: PipelineContext): Promise<boolean>;
|
|
43
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Configuration for ForEachPhase (side-effect iteration without collecting results)
|
|
47
|
+
*/
|
|
48
|
+
export interface ForEachPhaseConfig<TInput> {
|
|
49
|
+
/** Slot containing the input array to iterate over */
|
|
50
|
+
inputSlot: SlotKey<TInput[]>;
|
|
51
|
+
/** Slot for current item during iteration */
|
|
52
|
+
itemSlot: SlotKey<TInput>;
|
|
53
|
+
/** Phases to execute for each item */
|
|
54
|
+
phases: Phase[];
|
|
55
|
+
/** Continue processing remaining items if one fails */
|
|
56
|
+
continueOnError?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Phase that iterates over a collection for side effects (no result collection).
|
|
60
|
+
* Useful for operations like "notify each user" or "delete each file".
|
|
61
|
+
*/
|
|
62
|
+
export declare class ForEachPhase<TInput> implements Phase {
|
|
63
|
+
readonly name: string;
|
|
64
|
+
readonly description: string;
|
|
65
|
+
private readonly config;
|
|
66
|
+
constructor(name: string, config: ForEachPhaseConfig<TInput>);
|
|
67
|
+
get requires(): SlotKey<unknown>[];
|
|
68
|
+
get produces(): SlotKey<unknown>[];
|
|
69
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
70
|
+
private toPipelineError;
|
|
71
|
+
shouldSkip(ctx: PipelineContext): Promise<boolean>;
|
|
72
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=iterators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterators.d.ts","sourceRoot":"","sources":["../../src/pipeline/iterators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ForEachPhase = exports.MapPhase = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Phase that iterates over a collection, executing sub-phases for each item.
|
|
6
|
+
* Similar to AWS Step Functions Map state.
|
|
7
|
+
*/
|
|
8
|
+
class MapPhase {
|
|
9
|
+
name;
|
|
10
|
+
description;
|
|
11
|
+
config;
|
|
12
|
+
constructor(name, config) {
|
|
13
|
+
this.name = `map:${name}`;
|
|
14
|
+
this.description = `Iterates over collection and executes phases for each item`;
|
|
15
|
+
this.config = {
|
|
16
|
+
inputSlot: config.inputSlot,
|
|
17
|
+
outputSlot: config.outputSlot,
|
|
18
|
+
itemSlot: config.itemSlot,
|
|
19
|
+
resultSlot: config.resultSlot,
|
|
20
|
+
phases: config.phases,
|
|
21
|
+
concurrency: config.concurrency ?? 1,
|
|
22
|
+
continueOnError: config.continueOnError ?? false,
|
|
23
|
+
onProgress: config.onProgress,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
get requires() {
|
|
27
|
+
// We require the input slot
|
|
28
|
+
return [this.config.inputSlot];
|
|
29
|
+
}
|
|
30
|
+
get produces() {
|
|
31
|
+
// We produce the output slot
|
|
32
|
+
return [this.config.outputSlot];
|
|
33
|
+
}
|
|
34
|
+
get optionalReads() {
|
|
35
|
+
// Collect optional reads from all sub-phases
|
|
36
|
+
const allOptional = new Set();
|
|
37
|
+
for (const phase of this.config.phases) {
|
|
38
|
+
phase.optionalReads?.forEach(slot => allOptional.add(slot));
|
|
39
|
+
}
|
|
40
|
+
return allOptional.size > 0 ? Array.from(allOptional) : undefined;
|
|
41
|
+
}
|
|
42
|
+
async execute(ctx) {
|
|
43
|
+
const items = ctx.require(this.config.inputSlot);
|
|
44
|
+
if (items.length === 0) {
|
|
45
|
+
return ctx.set(this.config.outputSlot, []);
|
|
46
|
+
}
|
|
47
|
+
const results = [];
|
|
48
|
+
const errors = [];
|
|
49
|
+
if (this.config.concurrency === 1) {
|
|
50
|
+
// Sequential execution
|
|
51
|
+
for (let i = 0; i < items.length; i++) {
|
|
52
|
+
const result = await this.processItem(ctx, items[i], i);
|
|
53
|
+
results.push(result);
|
|
54
|
+
if (!result.success) {
|
|
55
|
+
errors.push(result.error);
|
|
56
|
+
if (!this.config.continueOnError) {
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
this.config.onProgress?.(i + 1, items.length, items[i]);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Parallel execution with concurrency limit
|
|
65
|
+
const batches = this.chunk(items, this.config.concurrency);
|
|
66
|
+
let completedCount = 0;
|
|
67
|
+
for (const batch of batches) {
|
|
68
|
+
const batchPromises = batch.map((item, batchIndex) => {
|
|
69
|
+
const globalIndex = completedCount + batchIndex;
|
|
70
|
+
return this.processItem(ctx, item, globalIndex);
|
|
71
|
+
});
|
|
72
|
+
const batchResults = await Promise.all(batchPromises);
|
|
73
|
+
for (const result of batchResults) {
|
|
74
|
+
results.push(result);
|
|
75
|
+
if (!result.success) {
|
|
76
|
+
errors.push(result.error);
|
|
77
|
+
}
|
|
78
|
+
completedCount++;
|
|
79
|
+
this.config.onProgress?.(completedCount, items.length, items[result.index]);
|
|
80
|
+
}
|
|
81
|
+
// Check if we should stop due to errors
|
|
82
|
+
if (errors.length > 0 && !this.config.continueOnError) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Collect successful results in order
|
|
88
|
+
const successfulResults = results
|
|
89
|
+
.filter(r => r.success)
|
|
90
|
+
.sort((a, b) => a.index - b.index)
|
|
91
|
+
.map(r => r.result);
|
|
92
|
+
// Add any errors to context
|
|
93
|
+
let resultCtx = ctx;
|
|
94
|
+
for (const error of errors) {
|
|
95
|
+
resultCtx = resultCtx.addError(error);
|
|
96
|
+
}
|
|
97
|
+
// If we have errors and didn't continue, throw the first one
|
|
98
|
+
if (errors.length > 0 && !this.config.continueOnError) {
|
|
99
|
+
throw errors[0];
|
|
100
|
+
}
|
|
101
|
+
return resultCtx.set(this.config.outputSlot, successfulResults);
|
|
102
|
+
}
|
|
103
|
+
async processItem(ctx, item, index) {
|
|
104
|
+
try {
|
|
105
|
+
// Create iteration context with current item
|
|
106
|
+
let iterCtx = ctx.set(this.config.itemSlot, item);
|
|
107
|
+
// Execute all phases for this item
|
|
108
|
+
for (const phase of this.config.phases) {
|
|
109
|
+
iterCtx = await phase.execute(iterCtx);
|
|
110
|
+
}
|
|
111
|
+
// Get the result from the result slot
|
|
112
|
+
const result = iterCtx.require(this.config.resultSlot);
|
|
113
|
+
return {
|
|
114
|
+
success: true,
|
|
115
|
+
result,
|
|
116
|
+
index,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
catch (error) {
|
|
120
|
+
return {
|
|
121
|
+
success: false,
|
|
122
|
+
error: this.toPipelineError(error, index),
|
|
123
|
+
index,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
toPipelineError(error, index) {
|
|
128
|
+
if (this.isPipelineError(error)) {
|
|
129
|
+
return {
|
|
130
|
+
...error,
|
|
131
|
+
data: { ...error.data, iterationIndex: index },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const err = error;
|
|
135
|
+
return {
|
|
136
|
+
phase: this.name,
|
|
137
|
+
code: 'ITERATION_ERROR',
|
|
138
|
+
message: `Error processing item at index ${index}: ${err?.message ?? String(error)}`,
|
|
139
|
+
recoverable: false,
|
|
140
|
+
data: { iterationIndex: index },
|
|
141
|
+
stack: err?.stack,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
isPipelineError(error) {
|
|
145
|
+
return (typeof error === 'object' &&
|
|
146
|
+
error !== null &&
|
|
147
|
+
'phase' in error &&
|
|
148
|
+
'code' in error &&
|
|
149
|
+
'message' in error);
|
|
150
|
+
}
|
|
151
|
+
chunk(array, size) {
|
|
152
|
+
const chunks = [];
|
|
153
|
+
for (let i = 0; i < array.length; i += size) {
|
|
154
|
+
chunks.push(array.slice(i, i + size));
|
|
155
|
+
}
|
|
156
|
+
return chunks;
|
|
157
|
+
}
|
|
158
|
+
async shouldSkip(ctx) {
|
|
159
|
+
// Skip if input array is empty
|
|
160
|
+
const items = ctx.get(this.config.inputSlot);
|
|
161
|
+
return !items || items.length === 0;
|
|
162
|
+
}
|
|
163
|
+
async rollback(ctx, error) {
|
|
164
|
+
// Rollback all sub-phases
|
|
165
|
+
for (const phase of this.config.phases) {
|
|
166
|
+
if (phase.rollback) {
|
|
167
|
+
await phase.rollback(ctx, error);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.MapPhase = MapPhase;
|
|
173
|
+
/**
|
|
174
|
+
* Phase that iterates over a collection for side effects (no result collection).
|
|
175
|
+
* Useful for operations like "notify each user" or "delete each file".
|
|
176
|
+
*/
|
|
177
|
+
class ForEachPhase {
|
|
178
|
+
name;
|
|
179
|
+
description;
|
|
180
|
+
config;
|
|
181
|
+
constructor(name, config) {
|
|
182
|
+
this.name = `forEach:${name}`;
|
|
183
|
+
this.description = `Executes phases for each item in collection`;
|
|
184
|
+
this.config = {
|
|
185
|
+
inputSlot: config.inputSlot,
|
|
186
|
+
itemSlot: config.itemSlot,
|
|
187
|
+
phases: config.phases,
|
|
188
|
+
continueOnError: config.continueOnError ?? false,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
get requires() {
|
|
192
|
+
return [this.config.inputSlot];
|
|
193
|
+
}
|
|
194
|
+
get produces() {
|
|
195
|
+
return []; // ForEach doesn't produce output, just side effects
|
|
196
|
+
}
|
|
197
|
+
async execute(ctx) {
|
|
198
|
+
const items = ctx.require(this.config.inputSlot);
|
|
199
|
+
let resultCtx = ctx;
|
|
200
|
+
for (const item of items) {
|
|
201
|
+
try {
|
|
202
|
+
let iterCtx = resultCtx.set(this.config.itemSlot, item);
|
|
203
|
+
for (const phase of this.config.phases) {
|
|
204
|
+
iterCtx = await phase.execute(iterCtx);
|
|
205
|
+
}
|
|
206
|
+
resultCtx = iterCtx;
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
if (!this.config.continueOnError) {
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
// Add error and continue
|
|
213
|
+
const pipelineError = this.toPipelineError(error);
|
|
214
|
+
resultCtx = resultCtx.addError(pipelineError);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return resultCtx;
|
|
218
|
+
}
|
|
219
|
+
toPipelineError(error) {
|
|
220
|
+
if (typeof error === 'object' && error !== null && 'phase' in error) {
|
|
221
|
+
return error;
|
|
222
|
+
}
|
|
223
|
+
const err = error;
|
|
224
|
+
return {
|
|
225
|
+
phase: this.name,
|
|
226
|
+
code: 'ITERATION_ERROR',
|
|
227
|
+
message: err?.message ?? String(error),
|
|
228
|
+
recoverable: false,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
async shouldSkip(ctx) {
|
|
232
|
+
const items = ctx.get(this.config.inputSlot);
|
|
233
|
+
return !items || items.length === 0;
|
|
234
|
+
}
|
|
235
|
+
async rollback(ctx, error) {
|
|
236
|
+
for (const phase of this.config.phases) {
|
|
237
|
+
if (phase.rollback) {
|
|
238
|
+
await phase.rollback(ctx, error);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
exports.ForEachPhase = ForEachPhase;
|
|
244
|
+
//# sourceMappingURL=iterators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"iterators.js","sourceRoot":"","sources":["../../src/pipeline/iterators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Phase } from './phase';
|
|
2
|
+
import { PipelineContext } from './context';
|
|
3
|
+
import { SlotKey, PipelineError } from '../types/common';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for retry behavior
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryPolicy {
|
|
8
|
+
/** Maximum number of retry attempts (not including initial attempt) */
|
|
9
|
+
maxAttempts: number;
|
|
10
|
+
/** Base delay in milliseconds before first retry */
|
|
11
|
+
baseDelayMs: number;
|
|
12
|
+
/** Maximum delay in milliseconds (caps exponential backoff) */
|
|
13
|
+
maxDelayMs: number;
|
|
14
|
+
/** Multiplier for exponential backoff (default: 2) */
|
|
15
|
+
backoffMultiplier?: number;
|
|
16
|
+
/** Error codes that should trigger a retry */
|
|
17
|
+
retryableErrors?: string[];
|
|
18
|
+
/** HTTP status codes that should trigger a retry */
|
|
19
|
+
retryableStatuses?: number[];
|
|
20
|
+
/** Callback invoked before each retry attempt */
|
|
21
|
+
onRetry?: (attempt: number, error: PipelineError, delayMs: number) => void;
|
|
22
|
+
/** Whether to add jitter to delays to prevent thundering herd */
|
|
23
|
+
jitter?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Default retry policy with sensible defaults
|
|
27
|
+
*/
|
|
28
|
+
export declare const DefaultRetryPolicy: RetryPolicy;
|
|
29
|
+
/**
|
|
30
|
+
* Wraps a phase with retry logic
|
|
31
|
+
*/
|
|
32
|
+
export declare function withRetry(phase: Phase, policy?: RetryPolicy): Phase;
|
|
33
|
+
/**
|
|
34
|
+
* Phase wrapper that implements retry logic with exponential backoff
|
|
35
|
+
*/
|
|
36
|
+
declare class RetryPhase implements Phase {
|
|
37
|
+
private inner;
|
|
38
|
+
private readonly policy;
|
|
39
|
+
constructor(inner: Phase, policy: RetryPolicy);
|
|
40
|
+
get name(): string;
|
|
41
|
+
get description(): string;
|
|
42
|
+
get requires(): SlotKey<unknown>[];
|
|
43
|
+
get produces(): SlotKey<unknown>[];
|
|
44
|
+
get optionalReads(): SlotKey[] | undefined;
|
|
45
|
+
get dependsOn(): string[] | undefined;
|
|
46
|
+
get tags(): string[] | undefined;
|
|
47
|
+
execute(ctx: PipelineContext): Promise<PipelineContext>;
|
|
48
|
+
shouldSkip(ctx: PipelineContext): Promise<boolean>;
|
|
49
|
+
rollback(ctx: PipelineContext, error: PipelineError): Promise<void>;
|
|
50
|
+
private shouldRetry;
|
|
51
|
+
private calculateDelay;
|
|
52
|
+
private toPipelineError;
|
|
53
|
+
private isPipelineError;
|
|
54
|
+
private sleep;
|
|
55
|
+
}
|
|
56
|
+
export { RetryPhase };
|
|
57
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/pipeline/retry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,iEAAiE;IACjE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAQhC,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,GAAE,WAAgC,GAAG,KAAK,CAEvF;AAED;;GAEG;AACH,cAAM,UAAW,YAAW,KAAK;IAI7B,OAAO,CAAC,KAAK;IAHf,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAGrC,KAAK,EAAE,KAAK,EACpB,MAAM,EAAE,WAAW;IAcrB,IAAI,IAAI,WAAyC;IACjD,IAAI,WAAW,WAAuD;IACtE,IAAI,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAgC;IAClE,IAAI,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAgC;IAClE,IAAI,aAAa,0BAAuC;IACxD,IAAI,SAAS,yBAAmC;IAChD,IAAI,IAAI,yBAA8B;IAEhC,OAAO,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;IA4BvD,UAAU,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE,OAAO,CAAC,WAAW;IA0BnB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,KAAK;CAGd;AAED,OAAO,EAAE,UAAU,EAAE,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RetryPhase = exports.DefaultRetryPolicy = void 0;
|
|
4
|
+
exports.withRetry = withRetry;
|
|
5
|
+
/**
|
|
6
|
+
* Default retry policy with sensible defaults
|
|
7
|
+
*/
|
|
8
|
+
exports.DefaultRetryPolicy = {
|
|
9
|
+
maxAttempts: 3,
|
|
10
|
+
baseDelayMs: 1000,
|
|
11
|
+
maxDelayMs: 30000,
|
|
12
|
+
backoffMultiplier: 2,
|
|
13
|
+
retryableErrors: ['RATE_LIMITED', 'TIMEOUT', 'CONNECTION_ERROR', 'SERVICE_UNAVAILABLE'],
|
|
14
|
+
retryableStatuses: [408, 429, 500, 502, 503, 504],
|
|
15
|
+
jitter: true,
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Wraps a phase with retry logic
|
|
19
|
+
*/
|
|
20
|
+
function withRetry(phase, policy = exports.DefaultRetryPolicy) {
|
|
21
|
+
return new RetryPhase(phase, policy);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Phase wrapper that implements retry logic with exponential backoff
|
|
25
|
+
*/
|
|
26
|
+
class RetryPhase {
|
|
27
|
+
inner;
|
|
28
|
+
policy;
|
|
29
|
+
constructor(inner, policy) {
|
|
30
|
+
this.inner = inner;
|
|
31
|
+
this.policy = {
|
|
32
|
+
maxAttempts: policy.maxAttempts,
|
|
33
|
+
baseDelayMs: policy.baseDelayMs,
|
|
34
|
+
maxDelayMs: policy.maxDelayMs,
|
|
35
|
+
backoffMultiplier: policy.backoffMultiplier ?? 2,
|
|
36
|
+
retryableErrors: policy.retryableErrors ?? [],
|
|
37
|
+
retryableStatuses: policy.retryableStatuses ?? [],
|
|
38
|
+
onRetry: policy.onRetry ?? (() => { }),
|
|
39
|
+
jitter: policy.jitter ?? true,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
get name() { return `retry:${this.inner.name}`; }
|
|
43
|
+
get description() { return `${this.inner.description} (with retry)`; }
|
|
44
|
+
get requires() { return this.inner.requires; }
|
|
45
|
+
get produces() { return this.inner.produces; }
|
|
46
|
+
get optionalReads() { return this.inner.optionalReads; }
|
|
47
|
+
get dependsOn() { return this.inner.dependsOn; }
|
|
48
|
+
get tags() { return this.inner.tags; }
|
|
49
|
+
async execute(ctx) {
|
|
50
|
+
let lastError;
|
|
51
|
+
let attempt = 0;
|
|
52
|
+
while (attempt <= this.policy.maxAttempts) {
|
|
53
|
+
try {
|
|
54
|
+
return await this.inner.execute(ctx);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
const pipelineError = this.toPipelineError(error);
|
|
58
|
+
lastError = pipelineError;
|
|
59
|
+
if (!this.shouldRetry(pipelineError, attempt)) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
attempt++;
|
|
63
|
+
if (attempt <= this.policy.maxAttempts) {
|
|
64
|
+
const delay = this.calculateDelay(attempt);
|
|
65
|
+
this.policy.onRetry(attempt, pipelineError, delay);
|
|
66
|
+
await this.sleep(delay);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Should not reach here, but throw last error if we do
|
|
71
|
+
throw lastError;
|
|
72
|
+
}
|
|
73
|
+
async shouldSkip(ctx) {
|
|
74
|
+
return this.inner.shouldSkip ? await this.inner.shouldSkip(ctx) : false;
|
|
75
|
+
}
|
|
76
|
+
async rollback(ctx, error) {
|
|
77
|
+
if (this.inner.rollback) {
|
|
78
|
+
await this.inner.rollback(ctx, error);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
shouldRetry(error, currentAttempt) {
|
|
82
|
+
// Don't retry if we've exhausted attempts
|
|
83
|
+
if (currentAttempt >= this.policy.maxAttempts) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// Don't retry non-recoverable errors
|
|
87
|
+
if (!error.recoverable) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
// Check if error code is in retryable list
|
|
91
|
+
if (this.policy.retryableErrors.includes(error.code)) {
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
// Check if HTTP status is in retryable list
|
|
95
|
+
const httpStatus = error.data?.httpStatus ?? 0;
|
|
96
|
+
if (this.policy.retryableStatuses.includes(httpStatus)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
// Default: retry all recoverable errors
|
|
100
|
+
return error.recoverable;
|
|
101
|
+
}
|
|
102
|
+
calculateDelay(attempt) {
|
|
103
|
+
// Exponential backoff: baseDelay * multiplier^(attempt-1)
|
|
104
|
+
let delay = this.policy.baseDelayMs * Math.pow(this.policy.backoffMultiplier, attempt - 1);
|
|
105
|
+
// Cap at max delay
|
|
106
|
+
delay = Math.min(delay, this.policy.maxDelayMs);
|
|
107
|
+
// Add jitter (0-25% of delay)
|
|
108
|
+
if (this.policy.jitter) {
|
|
109
|
+
const jitter = delay * 0.25 * Math.random();
|
|
110
|
+
delay = delay + jitter;
|
|
111
|
+
}
|
|
112
|
+
return Math.floor(delay);
|
|
113
|
+
}
|
|
114
|
+
toPipelineError(error) {
|
|
115
|
+
if (this.isPipelineError(error)) {
|
|
116
|
+
return error;
|
|
117
|
+
}
|
|
118
|
+
const err = error;
|
|
119
|
+
return {
|
|
120
|
+
phase: this.inner.name,
|
|
121
|
+
code: 'UNKNOWN_ERROR',
|
|
122
|
+
message: err?.message ?? String(error),
|
|
123
|
+
recoverable: true,
|
|
124
|
+
stack: err?.stack,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
isPipelineError(error) {
|
|
128
|
+
return (typeof error === 'object' &&
|
|
129
|
+
error !== null &&
|
|
130
|
+
'phase' in error &&
|
|
131
|
+
'code' in error &&
|
|
132
|
+
'message' in error);
|
|
133
|
+
}
|
|
134
|
+
sleep(ms) {
|
|
135
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
exports.RetryPhase = RetryPhase;
|
|
139
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/pipeline/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { PipelineError } from './common';
|
|
2
|
+
/**
|
|
3
|
+
* Categories of errors for classification and handling decisions
|
|
4
|
+
*/
|
|
5
|
+
export declare enum ErrorCategory {
|
|
6
|
+
/** Input validation failures */
|
|
7
|
+
VALIDATION = "VALIDATION",
|
|
8
|
+
/** Network connectivity issues */
|
|
9
|
+
NETWORK = "NETWORK",
|
|
10
|
+
/** Authentication failures (invalid credentials, expired tokens) */
|
|
11
|
+
AUTHENTICATION = "AUTHENTICATION",
|
|
12
|
+
/** Authorization failures (insufficient permissions) */
|
|
13
|
+
AUTHORIZATION = "AUTHORIZATION",
|
|
14
|
+
/** Rate limiting / throttling */
|
|
15
|
+
RATE_LIMIT = "RATE_LIMIT",
|
|
16
|
+
/** Resource not found */
|
|
17
|
+
NOT_FOUND = "NOT_FOUND",
|
|
18
|
+
/** Conflict (e.g., duplicate, optimistic lock failure) */
|
|
19
|
+
CONFLICT = "CONFLICT",
|
|
20
|
+
/** Business logic errors */
|
|
21
|
+
BUSINESS_LOGIC = "BUSINESS_LOGIC",
|
|
22
|
+
/** External service errors (5xx from APIs) */
|
|
23
|
+
SERVICE_ERROR = "SERVICE_ERROR",
|
|
24
|
+
/** Timeout errors */
|
|
25
|
+
TIMEOUT = "TIMEOUT",
|
|
26
|
+
/** Internal system errors */
|
|
27
|
+
SYSTEM = "SYSTEM",
|
|
28
|
+
/** Unknown/unclassified errors */
|
|
29
|
+
UNKNOWN = "UNKNOWN"
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Extended error interface with categorization
|
|
33
|
+
*/
|
|
34
|
+
export interface CategorizedError extends PipelineError {
|
|
35
|
+
/** Error category for handling decisions */
|
|
36
|
+
category: ErrorCategory;
|
|
37
|
+
/** HTTP status code if applicable */
|
|
38
|
+
httpStatus?: number;
|
|
39
|
+
/** Suggested retry delay in milliseconds */
|
|
40
|
+
retryAfterMs?: number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Categorizes an error for handling decisions
|
|
44
|
+
*/
|
|
45
|
+
export declare function categorizeError(error: unknown, phaseName?: string): CategorizedError;
|
|
46
|
+
/**
|
|
47
|
+
* Helper to check if an error category is retryable
|
|
48
|
+
*/
|
|
49
|
+
export declare function isRetryableCategory(category: ErrorCategory): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Helper to create a validation error
|
|
52
|
+
*/
|
|
53
|
+
export declare function validationError(phase: string, message: string, field?: string): CategorizedError;
|
|
54
|
+
/**
|
|
55
|
+
* Helper to create a not found error
|
|
56
|
+
*/
|
|
57
|
+
export declare function notFoundError(phase: string, resource: string, id?: string): CategorizedError;
|
|
58
|
+
/**
|
|
59
|
+
* Helper to create a rate limit error
|
|
60
|
+
*/
|
|
61
|
+
export declare function rateLimitError(phase: string, retryAfterMs?: number): CategorizedError;
|
|
62
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC;;GAEG;AACH,oBAAY,aAAa;IACvB,gCAAgC;IAChC,UAAU,eAAe;IACzB,kCAAkC;IAClC,OAAO,YAAY;IACnB,oEAAoE;IACpE,cAAc,mBAAmB;IACjC,wDAAwD;IACxD,aAAa,kBAAkB;IAC/B,iCAAiC;IACjC,UAAU,eAAe;IACzB,yBAAyB;IACzB,SAAS,cAAc;IACvB,0DAA0D;IAC1D,QAAQ,aAAa;IACrB,4BAA4B;IAC5B,cAAc,mBAAmB;IACjC,8CAA8C;IAC9C,aAAa,kBAAkB;IAC/B,qBAAqB;IACrB,OAAO,YAAY;IACnB,6BAA6B;IAC7B,MAAM,WAAW;IACjB,kCAAkC;IAClC,OAAO,YAAY;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,4CAA4C;IAC5C,QAAQ,EAAE,aAAa,CAAC;IACxB,qCAAqC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA6CD;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,SAAY,GAAG,gBAAgB,CAyDvF;AA4FD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAEpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,gBAAgB,CASlB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,MAAM,GACV,gBAAgB,CAUlB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB,CAUlB"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ErrorCategory = void 0;
|
|
4
|
+
exports.categorizeError = categorizeError;
|
|
5
|
+
exports.isRetryableCategory = isRetryableCategory;
|
|
6
|
+
exports.validationError = validationError;
|
|
7
|
+
exports.notFoundError = notFoundError;
|
|
8
|
+
exports.rateLimitError = rateLimitError;
|
|
9
|
+
/**
|
|
10
|
+
* Categories of errors for classification and handling decisions
|
|
11
|
+
*/
|
|
12
|
+
var ErrorCategory;
|
|
13
|
+
(function (ErrorCategory) {
|
|
14
|
+
/** Input validation failures */
|
|
15
|
+
ErrorCategory["VALIDATION"] = "VALIDATION";
|
|
16
|
+
/** Network connectivity issues */
|
|
17
|
+
ErrorCategory["NETWORK"] = "NETWORK";
|
|
18
|
+
/** Authentication failures (invalid credentials, expired tokens) */
|
|
19
|
+
ErrorCategory["AUTHENTICATION"] = "AUTHENTICATION";
|
|
20
|
+
/** Authorization failures (insufficient permissions) */
|
|
21
|
+
ErrorCategory["AUTHORIZATION"] = "AUTHORIZATION";
|
|
22
|
+
/** Rate limiting / throttling */
|
|
23
|
+
ErrorCategory["RATE_LIMIT"] = "RATE_LIMIT";
|
|
24
|
+
/** Resource not found */
|
|
25
|
+
ErrorCategory["NOT_FOUND"] = "NOT_FOUND";
|
|
26
|
+
/** Conflict (e.g., duplicate, optimistic lock failure) */
|
|
27
|
+
ErrorCategory["CONFLICT"] = "CONFLICT";
|
|
28
|
+
/** Business logic errors */
|
|
29
|
+
ErrorCategory["BUSINESS_LOGIC"] = "BUSINESS_LOGIC";
|
|
30
|
+
/** External service errors (5xx from APIs) */
|
|
31
|
+
ErrorCategory["SERVICE_ERROR"] = "SERVICE_ERROR";
|
|
32
|
+
/** Timeout errors */
|
|
33
|
+
ErrorCategory["TIMEOUT"] = "TIMEOUT";
|
|
34
|
+
/** Internal system errors */
|
|
35
|
+
ErrorCategory["SYSTEM"] = "SYSTEM";
|
|
36
|
+
/** Unknown/unclassified errors */
|
|
37
|
+
ErrorCategory["UNKNOWN"] = "UNKNOWN";
|
|
38
|
+
})(ErrorCategory || (exports.ErrorCategory = ErrorCategory = {}));
|
|
39
|
+
/**
|
|
40
|
+
* Mapping of HTTP status codes to error categories
|
|
41
|
+
*/
|
|
42
|
+
const HTTP_STATUS_CATEGORY_MAP = {
|
|
43
|
+
400: ErrorCategory.VALIDATION,
|
|
44
|
+
401: ErrorCategory.AUTHENTICATION,
|
|
45
|
+
403: ErrorCategory.AUTHORIZATION,
|
|
46
|
+
404: ErrorCategory.NOT_FOUND,
|
|
47
|
+
408: ErrorCategory.TIMEOUT,
|
|
48
|
+
409: ErrorCategory.CONFLICT,
|
|
49
|
+
422: ErrorCategory.VALIDATION,
|
|
50
|
+
429: ErrorCategory.RATE_LIMIT,
|
|
51
|
+
500: ErrorCategory.SERVICE_ERROR,
|
|
52
|
+
502: ErrorCategory.SERVICE_ERROR,
|
|
53
|
+
503: ErrorCategory.SERVICE_ERROR,
|
|
54
|
+
504: ErrorCategory.TIMEOUT,
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Mapping of error codes/patterns to categories
|
|
58
|
+
*/
|
|
59
|
+
const ERROR_CODE_PATTERNS = [
|
|
60
|
+
{ pattern: /^(ECONNREFUSED|ENOTFOUND|ECONNRESET|EPIPE|ETIMEDOUT)$/i, category: ErrorCategory.NETWORK },
|
|
61
|
+
{ pattern: /^(TIMEOUT|TIMED_OUT|REQUEST_TIMEOUT)$/i, category: ErrorCategory.TIMEOUT },
|
|
62
|
+
{ pattern: /^(RATE_LIMIT|THROTTL|TOO_MANY_REQUESTS)$/i, category: ErrorCategory.RATE_LIMIT },
|
|
63
|
+
{ pattern: /^(AUTH|UNAUTHORIZED|UNAUTHENTICATED|TOKEN_EXPIRED|INVALID_TOKEN)$/i, category: ErrorCategory.AUTHENTICATION },
|
|
64
|
+
{ pattern: /^(FORBIDDEN|ACCESS_DENIED|PERMISSION_DENIED)$/i, category: ErrorCategory.AUTHORIZATION },
|
|
65
|
+
{ pattern: /^(NOT_FOUND|RESOURCE_NOT_FOUND|MISSING)$/i, category: ErrorCategory.NOT_FOUND },
|
|
66
|
+
{ pattern: /^(CONFLICT|DUPLICATE|ALREADY_EXISTS|OPTIMISTIC_LOCK)$/i, category: ErrorCategory.CONFLICT },
|
|
67
|
+
{ pattern: /^(VALIDATION|INVALID|REQUIRED|FORMAT)$/i, category: ErrorCategory.VALIDATION },
|
|
68
|
+
{ pattern: /^(INTERNAL|SYSTEM|FATAL)$/i, category: ErrorCategory.SYSTEM },
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* Categories that are generally safe to retry
|
|
72
|
+
*/
|
|
73
|
+
const RETRYABLE_CATEGORIES = new Set([
|
|
74
|
+
ErrorCategory.NETWORK,
|
|
75
|
+
ErrorCategory.TIMEOUT,
|
|
76
|
+
ErrorCategory.RATE_LIMIT,
|
|
77
|
+
ErrorCategory.SERVICE_ERROR,
|
|
78
|
+
]);
|
|
79
|
+
/**
|
|
80
|
+
* Categorizes an error for handling decisions
|
|
81
|
+
*/
|
|
82
|
+
function categorizeError(error, phaseName = 'unknown') {
|
|
83
|
+
// If already categorized, return as-is
|
|
84
|
+
if (isCategorizedError(error)) {
|
|
85
|
+
return error;
|
|
86
|
+
}
|
|
87
|
+
// Start with base pipeline error
|
|
88
|
+
const baseError = toPipelineError(error, phaseName);
|
|
89
|
+
// Try to determine category
|
|
90
|
+
let category = ErrorCategory.UNKNOWN;
|
|
91
|
+
let httpStatus;
|
|
92
|
+
let retryAfterMs;
|
|
93
|
+
// Check for HTTP status in error data
|
|
94
|
+
if (baseError.data?.httpStatus) {
|
|
95
|
+
httpStatus = baseError.data.httpStatus;
|
|
96
|
+
category = HTTP_STATUS_CATEGORY_MAP[httpStatus] ?? ErrorCategory.UNKNOWN;
|
|
97
|
+
// Check for Retry-After header
|
|
98
|
+
if (baseError.data.retryAfter) {
|
|
99
|
+
retryAfterMs = parseRetryAfter(baseError.data.retryAfter);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// If still unknown, try matching error code patterns
|
|
103
|
+
if (category === ErrorCategory.UNKNOWN && baseError.code) {
|
|
104
|
+
for (const { pattern, category: cat } of ERROR_CODE_PATTERNS) {
|
|
105
|
+
if (pattern.test(baseError.code)) {
|
|
106
|
+
category = cat;
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Check error message for common patterns if still unknown
|
|
112
|
+
if (category === ErrorCategory.UNKNOWN) {
|
|
113
|
+
const message = baseError.message.toLowerCase();
|
|
114
|
+
if (message.includes('timeout') || message.includes('timed out')) {
|
|
115
|
+
category = ErrorCategory.TIMEOUT;
|
|
116
|
+
}
|
|
117
|
+
else if (message.includes('network') || message.includes('connection')) {
|
|
118
|
+
category = ErrorCategory.NETWORK;
|
|
119
|
+
}
|
|
120
|
+
else if (message.includes('rate limit') || message.includes('too many')) {
|
|
121
|
+
category = ErrorCategory.RATE_LIMIT;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Determine if error is recoverable based on category
|
|
125
|
+
const recoverable = baseError.recoverable ?? RETRYABLE_CATEGORIES.has(category);
|
|
126
|
+
return {
|
|
127
|
+
...baseError,
|
|
128
|
+
category,
|
|
129
|
+
httpStatus,
|
|
130
|
+
retryAfterMs,
|
|
131
|
+
recoverable,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Converts any error to a PipelineError
|
|
136
|
+
*/
|
|
137
|
+
function toPipelineError(error, phaseName) {
|
|
138
|
+
if (isPipelineError(error)) {
|
|
139
|
+
return error;
|
|
140
|
+
}
|
|
141
|
+
if (error instanceof Error) {
|
|
142
|
+
return {
|
|
143
|
+
phase: phaseName,
|
|
144
|
+
code: error.code ?? 'ERROR',
|
|
145
|
+
message: error.message,
|
|
146
|
+
recoverable: true,
|
|
147
|
+
stack: error.stack,
|
|
148
|
+
data: extractErrorData(error),
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
phase: phaseName,
|
|
153
|
+
code: 'UNKNOWN_ERROR',
|
|
154
|
+
message: String(error),
|
|
155
|
+
recoverable: true,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Extracts useful data from error objects
|
|
160
|
+
*/
|
|
161
|
+
function extractErrorData(error) {
|
|
162
|
+
const data = {};
|
|
163
|
+
const errorAny = error;
|
|
164
|
+
// Common properties from HTTP/API errors
|
|
165
|
+
if (errorAny.status)
|
|
166
|
+
data.httpStatus = errorAny.status;
|
|
167
|
+
if (errorAny.statusCode)
|
|
168
|
+
data.httpStatus = errorAny.statusCode;
|
|
169
|
+
if (errorAny.response?.status)
|
|
170
|
+
data.httpStatus = errorAny.response.status;
|
|
171
|
+
// Retry-After header
|
|
172
|
+
if (errorAny.headers?.['retry-after'])
|
|
173
|
+
data.retryAfter = errorAny.headers['retry-after'];
|
|
174
|
+
if (errorAny.response?.headers?.['retry-after'])
|
|
175
|
+
data.retryAfter = errorAny.response.headers['retry-after'];
|
|
176
|
+
// Request/response details
|
|
177
|
+
if (errorAny.config?.url)
|
|
178
|
+
data.url = errorAny.config.url;
|
|
179
|
+
if (errorAny.config?.method)
|
|
180
|
+
data.method = errorAny.config.method;
|
|
181
|
+
return Object.keys(data).length > 0 ? data : undefined;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Parses Retry-After header value to milliseconds
|
|
185
|
+
*/
|
|
186
|
+
function parseRetryAfter(value) {
|
|
187
|
+
if (typeof value === 'number') {
|
|
188
|
+
return value * 1000; // Assume seconds
|
|
189
|
+
}
|
|
190
|
+
if (typeof value === 'string') {
|
|
191
|
+
// Try as number of seconds
|
|
192
|
+
const seconds = parseInt(value, 10);
|
|
193
|
+
if (!isNaN(seconds)) {
|
|
194
|
+
return seconds * 1000;
|
|
195
|
+
}
|
|
196
|
+
// Try as HTTP date
|
|
197
|
+
const date = new Date(value);
|
|
198
|
+
if (!isNaN(date.getTime())) {
|
|
199
|
+
const delay = date.getTime() - Date.now();
|
|
200
|
+
return delay > 0 ? delay : undefined;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
function isPipelineError(error) {
|
|
206
|
+
return (typeof error === 'object' &&
|
|
207
|
+
error !== null &&
|
|
208
|
+
'phase' in error &&
|
|
209
|
+
'code' in error &&
|
|
210
|
+
'message' in error);
|
|
211
|
+
}
|
|
212
|
+
function isCategorizedError(error) {
|
|
213
|
+
return isPipelineError(error) && 'category' in error;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Helper to check if an error category is retryable
|
|
217
|
+
*/
|
|
218
|
+
function isRetryableCategory(category) {
|
|
219
|
+
return RETRYABLE_CATEGORIES.has(category);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Helper to create a validation error
|
|
223
|
+
*/
|
|
224
|
+
function validationError(phase, message, field) {
|
|
225
|
+
return {
|
|
226
|
+
phase,
|
|
227
|
+
code: 'VALIDATION_ERROR',
|
|
228
|
+
message,
|
|
229
|
+
category: ErrorCategory.VALIDATION,
|
|
230
|
+
recoverable: false,
|
|
231
|
+
data: field ? { field } : undefined,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Helper to create a not found error
|
|
236
|
+
*/
|
|
237
|
+
function notFoundError(phase, resource, id) {
|
|
238
|
+
return {
|
|
239
|
+
phase,
|
|
240
|
+
code: 'NOT_FOUND',
|
|
241
|
+
message: id ? `${resource} with id "${id}" not found` : `${resource} not found`,
|
|
242
|
+
category: ErrorCategory.NOT_FOUND,
|
|
243
|
+
recoverable: false,
|
|
244
|
+
httpStatus: 404,
|
|
245
|
+
data: { resource, id },
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Helper to create a rate limit error
|
|
250
|
+
*/
|
|
251
|
+
function rateLimitError(phase, retryAfterMs) {
|
|
252
|
+
return {
|
|
253
|
+
phase,
|
|
254
|
+
code: 'RATE_LIMITED',
|
|
255
|
+
message: 'Rate limit exceeded',
|
|
256
|
+
category: ErrorCategory.RATE_LIMIT,
|
|
257
|
+
recoverable: true,
|
|
258
|
+
httpStatus: 429,
|
|
259
|
+
retryAfterMs,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"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"}
|