@goodie-ts/resilience 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/README.md CHANGED
@@ -42,16 +42,9 @@ class PaymentService {
42
42
  - `TimeoutError` — thrown when `@Timeout` duration is exceeded
43
43
  - `CircuitOpenError` — thrown when the circuit breaker is OPEN and rejecting calls
44
44
 
45
- ## Vite Plugin Setup
45
+ ## Setup
46
46
 
47
- ```typescript
48
- import { diPlugin } from '@goodie-ts/vite-plugin';
49
- import { createResiliencePlugin } from '@goodie-ts/resilience';
50
-
51
- export default defineConfig({
52
- plugins: [diPlugin({ plugins: [createResiliencePlugin()] })],
53
- });
54
- ```
47
+ No plugin configuration needed — `@goodie-ts/resilience` ships pre-scanned beans and AOP config in `beans.json`. The transformer auto-discovers them at build time.
55
48
 
56
49
  ## License
57
50
 
@@ -0,0 +1,99 @@
1
+ {
2
+ "version": 1,
3
+ "package": "@goodie-ts/resilience",
4
+ "beans": [
5
+ {
6
+ "tokenRef": {
7
+ "kind": "class",
8
+ "className": "CircuitBreakerInterceptor",
9
+ "importPath": "@goodie-ts/resilience"
10
+ },
11
+ "scope": "singleton",
12
+ "eager": false,
13
+ "name": null,
14
+ "constructorDeps": [],
15
+ "fieldDeps": [],
16
+ "factoryKind": "constructor",
17
+ "providesSource": null,
18
+ "baseTokenRefs": null,
19
+ "metadata": {},
20
+ "sourceLocation": {
21
+ "filePath": "@goodie-ts/resilience",
22
+ "line": 39,
23
+ "column": 1
24
+ }
25
+ },
26
+ {
27
+ "tokenRef": {
28
+ "kind": "class",
29
+ "className": "RetryInterceptor",
30
+ "importPath": "@goodie-ts/resilience"
31
+ },
32
+ "scope": "singleton",
33
+ "eager": false,
34
+ "name": null,
35
+ "constructorDeps": [],
36
+ "fieldDeps": [],
37
+ "factoryKind": "constructor",
38
+ "providesSource": null,
39
+ "baseTokenRefs": null,
40
+ "metadata": {},
41
+ "sourceLocation": {
42
+ "filePath": "@goodie-ts/resilience",
43
+ "line": 31,
44
+ "column": 1
45
+ }
46
+ },
47
+ {
48
+ "tokenRef": {
49
+ "kind": "class",
50
+ "className": "TimeoutInterceptor",
51
+ "importPath": "@goodie-ts/resilience"
52
+ },
53
+ "scope": "singleton",
54
+ "eager": false,
55
+ "name": null,
56
+ "constructorDeps": [],
57
+ "fieldDeps": [],
58
+ "factoryKind": "constructor",
59
+ "providesSource": null,
60
+ "baseTokenRefs": null,
61
+ "metadata": {},
62
+ "sourceLocation": {
63
+ "filePath": "@goodie-ts/resilience",
64
+ "line": 24,
65
+ "column": 1
66
+ }
67
+ }
68
+ ],
69
+ "aop": {
70
+ "CircuitBreaker": {
71
+ "interceptor": "CircuitBreakerInterceptor",
72
+ "order": -20,
73
+ "defaults": {
74
+ "failureThreshold": 5,
75
+ "resetTimeout": 30000,
76
+ "halfOpenAttempts": 1
77
+ }
78
+ },
79
+ "Retryable": {
80
+ "interceptor": "RetryInterceptor",
81
+ "order": -10,
82
+ "defaults": {
83
+ "maxAttempts": 3,
84
+ "delay": 1000,
85
+ "multiplier": 1
86
+ }
87
+ },
88
+ "Timeout": {
89
+ "interceptor": "TimeoutInterceptor",
90
+ "order": -30,
91
+ "argMapping": [
92
+ "duration"
93
+ ],
94
+ "defaults": {
95
+ "duration": 5000
96
+ }
97
+ }
98
+ }
99
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"circuit-breaker-interceptor.d.ts","sourceRoot":"","sources":["../src/circuit-breaker-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE3E,KAAK,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAoBpD,yEAAyE;AACzE,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,SAAS,EAAE,MAAM;CAI9B;AAED;;;;;;GAMG;AACH,qBAAa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAE5D,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAyD1C,gEAAgE;IAChE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY;IAKpE,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,SAAS;CAclB"}
1
+ {"version":3,"file":"circuit-breaker-interceptor.d.ts","sourceRoot":"","sources":["../src/circuit-breaker-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAG3E,KAAK,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAoBpD,yEAAyE;AACzE,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,SAAS,EAAE,MAAM;CAI9B;AAED;;;;;;GAMG;AACH,qBACa,yBAA0B,YAAW,iBAAiB;IACjE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAE5D,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAyD1C,gEAAgE;IAChE,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,YAAY;IAKpE,OAAO,CAAC,kBAAkB;IAkB1B,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,SAAS;CAclB"}
@@ -1,3 +1,38 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Singleton } from '@goodie-ts/decorators';
1
36
  /** Error thrown when the circuit breaker is open and rejecting calls. */
2
37
  export class CircuitOpenError extends Error {
3
38
  constructor(methodKey) {
@@ -12,107 +47,123 @@ export class CircuitOpenError extends Error {
12
47
  *
13
48
  * Each decorated method gets its own circuit, keyed by `className:methodName`.
14
49
  */
15
- export class CircuitBreakerInterceptor {
16
- circuits = new Map();
17
- intercept(ctx) {
18
- const meta = ctx.metadata;
19
- if (!meta)
20
- return ctx.proceed();
21
- const key = `${ctx.className}:${ctx.methodName}`;
22
- const circuit = this.getOrCreateCircuit(key, meta);
23
- if (circuit.state === 'OPEN') {
24
- const elapsed = Date.now() - circuit.lastFailureTime;
25
- if (elapsed >= circuit.resetTimeout) {
26
- circuit.state = 'HALF_OPEN';
27
- circuit.successCount = 0;
50
+ let CircuitBreakerInterceptor = (() => {
51
+ let _classDecorators = [Singleton()];
52
+ let _classDescriptor;
53
+ let _classExtraInitializers = [];
54
+ let _classThis;
55
+ var CircuitBreakerInterceptor = class {
56
+ static { _classThis = this; }
57
+ static {
58
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
59
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
60
+ CircuitBreakerInterceptor = _classThis = _classDescriptor.value;
61
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
62
+ __runInitializers(_classThis, _classExtraInitializers);
63
+ }
64
+ circuits = new Map();
65
+ intercept(ctx) {
66
+ const meta = ctx.metadata;
67
+ if (!meta)
68
+ return ctx.proceed();
69
+ const key = `${ctx.className}:${ctx.methodName}`;
70
+ const circuit = this.getOrCreateCircuit(key, meta);
71
+ if (circuit.state === 'OPEN') {
72
+ const elapsed = Date.now() - circuit.lastFailureTime;
73
+ if (elapsed >= circuit.resetTimeout) {
74
+ circuit.state = 'HALF_OPEN';
75
+ circuit.successCount = 0;
76
+ }
77
+ else {
78
+ throw new CircuitOpenError(key);
79
+ }
28
80
  }
29
- else {
81
+ // Only allow one probe at a time during HALF_OPEN. Concurrent calls are
82
+ // rejected immediately so a burst of requests doesn't overwhelm a
83
+ // recovering backend.
84
+ if (circuit.state === 'HALF_OPEN' && circuit.halfOpenProbeInFlight) {
30
85
  throw new CircuitOpenError(key);
31
86
  }
32
- }
33
- // Only allow one probe at a time during HALF_OPEN. Concurrent calls are
34
- // rejected immediately so a burst of requests doesn't overwhelm a
35
- // recovering backend.
36
- if (circuit.state === 'HALF_OPEN' && circuit.halfOpenProbeInFlight) {
37
- throw new CircuitOpenError(key);
38
- }
39
- const isProbe = circuit.state === 'HALF_OPEN';
40
- if (isProbe) {
41
- circuit.halfOpenProbeInFlight = true;
42
- }
43
- try {
44
- const result = ctx.proceed();
45
- if (result instanceof Promise) {
46
- return result.then((value) => {
47
- if (isProbe)
48
- circuit.halfOpenProbeInFlight = false;
49
- this.onSuccess(circuit);
50
- return value;
51
- }, (error) => {
52
- if (isProbe)
53
- circuit.halfOpenProbeInFlight = false;
54
- this.onFailure(circuit);
55
- throw error;
56
- });
87
+ const isProbe = circuit.state === 'HALF_OPEN';
88
+ if (isProbe) {
89
+ circuit.halfOpenProbeInFlight = true;
90
+ }
91
+ try {
92
+ const result = ctx.proceed();
93
+ if (result instanceof Promise) {
94
+ return result.then((value) => {
95
+ if (isProbe)
96
+ circuit.halfOpenProbeInFlight = false;
97
+ this.onSuccess(circuit);
98
+ return value;
99
+ }, (error) => {
100
+ if (isProbe)
101
+ circuit.halfOpenProbeInFlight = false;
102
+ this.onFailure(circuit);
103
+ throw error;
104
+ });
105
+ }
106
+ if (isProbe)
107
+ circuit.halfOpenProbeInFlight = false;
108
+ this.onSuccess(circuit);
109
+ return result;
110
+ }
111
+ catch (error) {
112
+ if (isProbe)
113
+ circuit.halfOpenProbeInFlight = false;
114
+ this.onFailure(circuit);
115
+ throw error;
57
116
  }
58
- if (isProbe)
59
- circuit.halfOpenProbeInFlight = false;
60
- this.onSuccess(circuit);
61
- return result;
62
117
  }
63
- catch (error) {
64
- if (isProbe)
65
- circuit.halfOpenProbeInFlight = false;
66
- this.onFailure(circuit);
67
- throw error;
118
+ /** Visible for testing — get the current state of a circuit. */
119
+ getCircuitState(className, methodName) {
120
+ const key = `${className}:${methodName}`;
121
+ return this.circuits.get(key)?.state ?? 'CLOSED';
68
122
  }
69
- }
70
- /** Visible for testing — get the current state of a circuit. */
71
- getCircuitState(className, methodName) {
72
- const key = `${className}:${methodName}`;
73
- return this.circuits.get(key)?.state ?? 'CLOSED';
74
- }
75
- getOrCreateCircuit(key, meta) {
76
- let circuit = this.circuits.get(key);
77
- if (!circuit) {
78
- circuit = {
79
- state: 'CLOSED',
80
- failureCount: 0,
81
- successCount: 0,
82
- lastFailureTime: 0,
83
- failureThreshold: meta.failureThreshold,
84
- resetTimeout: meta.resetTimeout,
85
- halfOpenAttempts: meta.halfOpenAttempts,
86
- halfOpenProbeInFlight: false,
87
- };
88
- this.circuits.set(key, circuit);
123
+ getOrCreateCircuit(key, meta) {
124
+ let circuit = this.circuits.get(key);
125
+ if (!circuit) {
126
+ circuit = {
127
+ state: 'CLOSED',
128
+ failureCount: 0,
129
+ successCount: 0,
130
+ lastFailureTime: 0,
131
+ failureThreshold: meta.failureThreshold,
132
+ resetTimeout: meta.resetTimeout,
133
+ halfOpenAttempts: meta.halfOpenAttempts,
134
+ halfOpenProbeInFlight: false,
135
+ };
136
+ this.circuits.set(key, circuit);
137
+ }
138
+ return circuit;
89
139
  }
90
- return circuit;
91
- }
92
- onSuccess(circuit) {
93
- if (circuit.state === 'HALF_OPEN') {
94
- circuit.successCount++;
95
- if (circuit.successCount >= circuit.halfOpenAttempts) {
96
- circuit.state = 'CLOSED';
140
+ onSuccess(circuit) {
141
+ if (circuit.state === 'HALF_OPEN') {
142
+ circuit.successCount++;
143
+ if (circuit.successCount >= circuit.halfOpenAttempts) {
144
+ circuit.state = 'CLOSED';
145
+ circuit.failureCount = 0;
146
+ circuit.successCount = 0;
147
+ }
148
+ }
149
+ else if (circuit.state === 'CLOSED') {
97
150
  circuit.failureCount = 0;
98
- circuit.successCount = 0;
99
151
  }
100
152
  }
101
- else if (circuit.state === 'CLOSED') {
102
- circuit.failureCount = 0;
103
- }
104
- }
105
- onFailure(circuit) {
106
- circuit.failureCount++;
107
- circuit.lastFailureTime = Date.now();
108
- if (circuit.state === 'HALF_OPEN') {
109
- circuit.state = 'OPEN';
110
- circuit.successCount = 0;
111
- }
112
- else if (circuit.state === 'CLOSED' &&
113
- circuit.failureCount >= circuit.failureThreshold) {
114
- circuit.state = 'OPEN';
153
+ onFailure(circuit) {
154
+ circuit.failureCount++;
155
+ circuit.lastFailureTime = Date.now();
156
+ if (circuit.state === 'HALF_OPEN') {
157
+ circuit.state = 'OPEN';
158
+ circuit.successCount = 0;
159
+ }
160
+ else if (circuit.state === 'CLOSED' &&
161
+ circuit.failureCount >= circuit.failureThreshold) {
162
+ circuit.state = 'OPEN';
163
+ }
115
164
  }
116
- }
117
- }
165
+ };
166
+ return CircuitBreakerInterceptor = _classThis;
167
+ })();
168
+ export { CircuitBreakerInterceptor };
118
169
  //# sourceMappingURL=circuit-breaker-interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"circuit-breaker-interceptor.js","sourceRoot":"","sources":["../src/circuit-breaker-interceptor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"circuit-breaker-interceptor.js","sourceRoot":"","sources":["../src/circuit-breaker-interceptor.ts"],"names":[],"mappings":"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"}
@@ -6,13 +6,11 @@ export interface CircuitBreakerOptions {
6
6
  /** Number of successes in HALF_OPEN needed to close the circuit (default: 1). */
7
7
  halfOpenAttempts?: number;
8
8
  }
9
- type MethodDecorator_Stage3 = (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
10
9
  /**
11
10
  * Mark a method for circuit breaker protection.
12
11
  *
13
- * At compile time, the resilience transformer plugin reads this decorator
12
+ * At compile time, the AOP scanner reads the type parameter
14
13
  * and wires the `CircuitBreakerInterceptor` via AOP.
15
14
  */
16
- export declare function CircuitBreaker(_opts?: CircuitBreakerOptions): MethodDecorator_Stage3;
17
- export {};
15
+ export declare const CircuitBreaker: (opts?: CircuitBreakerOptions | undefined) => (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
18
16
  //# sourceMappingURL=circuit-breaker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/decorators/circuit-breaker.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,KAAK,sBAAsB,GAAG,CAC5B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,EACnC,OAAO,EAAE,2BAA2B,KACjC,IAAI,CAAC;AAEV;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,KAAK,CAAC,EAAE,qBAAqB,GAC5B,sBAAsB,CAIxB"}
1
+ {"version":3,"file":"circuit-breaker.d.ts","sourceRoot":"","sources":["../../src/decorators/circuit-breaker.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iFAAiF;IACjF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,0DAMV,GAAG,sEADhB,CAAC"}
@@ -1,12 +1,9 @@
1
+ import { createAopDecorator } from '@goodie-ts/aop';
1
2
  /**
2
3
  * Mark a method for circuit breaker protection.
3
4
  *
4
- * At compile time, the resilience transformer plugin reads this decorator
5
+ * At compile time, the AOP scanner reads the type parameter
5
6
  * and wires the `CircuitBreakerInterceptor` via AOP.
6
7
  */
7
- export function CircuitBreaker(_opts) {
8
- return (_target, _context) => {
9
- // No-op: read at compile time by the resilience transformer plugin
10
- };
11
- }
8
+ export const CircuitBreaker = createAopDecorator();
12
9
  //# sourceMappingURL=circuit-breaker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/decorators/circuit-breaker.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,KAA6B;IAE7B,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,mEAAmE;IACrE,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../../src/decorators/circuit-breaker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAYpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,EAK5C,CAAC"}
@@ -6,13 +6,11 @@ export interface RetryOptions {
6
6
  /** Multiplier for exponential backoff (default: 1 — no backoff). */
7
7
  multiplier?: number;
8
8
  }
9
- type MethodDecorator_Stage3 = (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
10
9
  /**
11
10
  * Mark a method for automatic retry on failure.
12
11
  *
13
- * At compile time, the resilience transformer plugin reads this decorator
12
+ * At compile time, the AOP scanner reads the type parameter
14
13
  * and wires the `RetryInterceptor` via AOP. No runtime metadata is stored.
15
14
  */
16
- export declare function Retryable(_opts?: RetryOptions): MethodDecorator_Stage3;
17
- export {};
15
+ export declare const Retryable: (opts?: RetryOptions | undefined) => (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
18
16
  //# sourceMappingURL=retryable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retryable.d.ts","sourceRoot":"","sources":["../../src/decorators/retryable.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,sBAAsB,GAAG,CAC5B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,EACnC,OAAO,EAAE,2BAA2B,KACjC,IAAI,CAAC;AAEV;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,YAAY,GAAG,sBAAsB,CAItE"}
1
+ {"version":3,"file":"retryable.d.ts","sourceRoot":"","sources":["../../src/decorators/retryable.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,SAAS,iDAMkG,GAAG,sEADvH,CAAC"}
@@ -1,12 +1,9 @@
1
+ import { createAopDecorator } from '@goodie-ts/aop';
1
2
  /**
2
3
  * Mark a method for automatic retry on failure.
3
4
  *
4
- * At compile time, the resilience transformer plugin reads this decorator
5
+ * At compile time, the AOP scanner reads the type parameter
5
6
  * and wires the `RetryInterceptor` via AOP. No runtime metadata is stored.
6
7
  */
7
- export function Retryable(_opts) {
8
- return (_target, _context) => {
9
- // No-op: read at compile time by the resilience transformer plugin
10
- };
11
- }
8
+ export const Retryable = createAopDecorator();
12
9
  //# sourceMappingURL=retryable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retryable.js","sourceRoot":"","sources":["../../src/decorators/retryable.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAoB;IAC5C,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,mEAAmE;IACrE,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"retryable.js","sourceRoot":"","sources":["../../src/decorators/retryable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAYpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,kBAAkB,EAKvC,CAAC"}
@@ -1,12 +1,10 @@
1
- type MethodDecorator_Stage3 = (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
2
1
  /**
3
2
  * Mark a method for automatic timeout.
4
3
  *
5
- * At compile time, the resilience transformer plugin reads this decorator
4
+ * At compile time, the AOP scanner reads the type parameter
6
5
  * and wires the `TimeoutInterceptor` via AOP.
7
6
  *
8
7
  * @param duration - Timeout duration in milliseconds.
9
8
  */
10
- export declare function Timeout(_duration: number): MethodDecorator_Stage3;
11
- export {};
9
+ export declare const Timeout: (duration: number) => (target: (...args: never) => unknown, context: ClassMethodDecoratorContext) => void;
12
10
  //# sourceMappingURL=timeout.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../src/decorators/timeout.ts"],"names":[],"mappings":"AAAA,KAAK,sBAAsB,GAAG,CAC5B,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,EACnC,OAAO,EAAE,2BAA2B,KACjC,IAAI,CAAC;AAEV;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB,CAIjE"}
1
+ {"version":3,"file":"timeout.d.ts","sourceRoot":"","sources":["../../src/decorators/timeout.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,eAAO,MAAM,OAAO,kCAOkX,GAAG,sEADrY,CAAC"}
@@ -1,14 +1,11 @@
1
+ import { createAopDecorator } from '@goodie-ts/aop';
1
2
  /**
2
3
  * Mark a method for automatic timeout.
3
4
  *
4
- * At compile time, the resilience transformer plugin reads this decorator
5
+ * At compile time, the AOP scanner reads the type parameter
5
6
  * and wires the `TimeoutInterceptor` via AOP.
6
7
  *
7
8
  * @param duration - Timeout duration in milliseconds.
8
9
  */
9
- export function Timeout(_duration) {
10
- return (_target, _context) => {
11
- // No-op: read at compile time by the resilience transformer plugin
12
- };
13
- }
10
+ export const Timeout = createAopDecorator();
14
11
  //# sourceMappingURL=timeout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeout.js","sourceRoot":"","sources":["../../src/decorators/timeout.ts"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,SAAiB;IACvC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC3B,mEAAmE;IACrE,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"timeout.js","sourceRoot":"","sources":["../../src/decorators/timeout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,kBAAkB,EAMrC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,7 +2,6 @@ export { CircuitBreakerInterceptor, CircuitOpenError, } from './circuit-breaker-
2
2
  export { CircuitBreaker } from './decorators/circuit-breaker.js';
3
3
  export { Retryable } from './decorators/retryable.js';
4
4
  export { Timeout } from './decorators/timeout.js';
5
- export { createResiliencePlugin } from './resilience-transformer-plugin.js';
6
5
  export { RetryInterceptor } from './retry-interceptor.js';
7
6
  export { TimeoutError, TimeoutInterceptor } from './timeout-interceptor.js';
8
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -2,7 +2,6 @@ export { CircuitBreakerInterceptor, CircuitOpenError, } from './circuit-breaker-
2
2
  export { CircuitBreaker } from './decorators/circuit-breaker.js';
3
3
  export { Retryable } from './decorators/retryable.js';
4
4
  export { Timeout } from './decorators/timeout.js';
5
- export { createResiliencePlugin } from './resilience-transformer-plugin.js';
6
5
  export { RetryInterceptor } from './retry-interceptor.js';
7
6
  export { TimeoutError, TimeoutInterceptor } from './timeout-interceptor.js';
8
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"retry-interceptor.d.ts","sourceRoot":"","sources":["../src/retry-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAS3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,gBAAiB,YAAW,iBAAiB;IACxD,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAQ1C,OAAO,CAAC,OAAO;IAoBf,OAAO,CAAC,WAAW;CA+BpB"}
1
+ {"version":3,"file":"retry-interceptor.d.ts","sourceRoot":"","sources":["../src/retry-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAU3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,gBAAiB,YAAW,iBAAiB;IACxD,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAQ1C,OAAO,CAAC,OAAO;IAoBf,OAAO,CAAC,WAAW;CA+BpB"}
@@ -1,3 +1,38 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Singleton } from '@goodie-ts/decorators';
1
36
  /**
2
37
  * AOP interceptor that retries failed method calls with configurable
3
38
  * backoff strategy (exponential backoff with random jitter).
@@ -18,51 +53,67 @@
18
53
  * failure. Callers should always `await` the return value of `@Retryable`
19
54
  * methods.
20
55
  */
21
- export class RetryInterceptor {
22
- intercept(ctx) {
23
- const meta = ctx.metadata;
24
- if (!meta)
25
- return ctx.proceed();
26
- const result = this.tryCall(ctx, meta, 1);
27
- return result;
28
- }
29
- tryCall(ctx, meta, attempt) {
30
- try {
31
- const result = ctx.proceed();
32
- if (result instanceof Promise) {
33
- return result.catch((error) => this.handleError(ctx, meta, attempt, error));
34
- }
35
- return result;
56
+ let RetryInterceptor = (() => {
57
+ let _classDecorators = [Singleton()];
58
+ let _classDescriptor;
59
+ let _classExtraInitializers = [];
60
+ let _classThis;
61
+ var RetryInterceptor = class {
62
+ static { _classThis = this; }
63
+ static {
64
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
65
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
66
+ RetryInterceptor = _classThis = _classDescriptor.value;
67
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
68
+ __runInitializers(_classThis, _classExtraInitializers);
36
69
  }
37
- catch (error) {
38
- return this.handleError(ctx, meta, attempt, error);
70
+ intercept(ctx) {
71
+ const meta = ctx.metadata;
72
+ if (!meta)
73
+ return ctx.proceed();
74
+ const result = this.tryCall(ctx, meta, 1);
75
+ return result;
39
76
  }
40
- }
41
- handleError(ctx, meta, attempt, error) {
42
- if (attempt >= meta.maxAttempts) {
43
- throw error;
77
+ tryCall(ctx, meta, attempt) {
78
+ try {
79
+ const result = ctx.proceed();
80
+ if (result instanceof Promise) {
81
+ return result.catch((error) => this.handleError(ctx, meta, attempt, error));
82
+ }
83
+ return result;
84
+ }
85
+ catch (error) {
86
+ return this.handleError(ctx, meta, attempt, error);
87
+ }
44
88
  }
45
- // Exponential backoff with random jitter (50–100% of computed delay)
46
- // to prevent thundering herd when many callers retry simultaneously.
47
- const baseDelay = meta.delay * meta.multiplier ** (attempt - 1);
48
- const delayMs = baseDelay * (0.5 + Math.random() * 0.5);
49
- // For async methods, use setTimeout-based delay
50
- return new Promise((resolve, reject) => {
51
- setTimeout(() => {
52
- try {
53
- const result = this.tryCall(ctx, meta, attempt + 1);
54
- if (result instanceof Promise) {
55
- result.then(resolve, reject);
89
+ handleError(ctx, meta, attempt, error) {
90
+ if (attempt >= meta.maxAttempts) {
91
+ throw error;
92
+ }
93
+ // Exponential backoff with random jitter (50–100% of computed delay)
94
+ // to prevent thundering herd when many callers retry simultaneously.
95
+ const baseDelay = meta.delay * meta.multiplier ** (attempt - 1);
96
+ const delayMs = baseDelay * (0.5 + Math.random() * 0.5);
97
+ // For async methods, use setTimeout-based delay
98
+ return new Promise((resolve, reject) => {
99
+ setTimeout(() => {
100
+ try {
101
+ const result = this.tryCall(ctx, meta, attempt + 1);
102
+ if (result instanceof Promise) {
103
+ result.then(resolve, reject);
104
+ }
105
+ else {
106
+ resolve(result);
107
+ }
56
108
  }
57
- else {
58
- resolve(result);
109
+ catch (retryError) {
110
+ reject(retryError);
59
111
  }
60
- }
61
- catch (retryError) {
62
- reject(retryError);
63
- }
64
- }, delayMs);
65
- });
66
- }
67
- }
112
+ }, delayMs);
113
+ });
114
+ }
115
+ };
116
+ return RetryInterceptor = _classThis;
117
+ })();
118
+ export { RetryInterceptor };
68
119
  //# sourceMappingURL=retry-interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry-interceptor.js","sourceRoot":"","sources":["../src/retry-interceptor.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,gBAAgB;IAC3B,SAAS,CAAC,GAAsB;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAqC,CAAC;QACvD,IAAI,CAAC,IAAI;YAAE,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;QAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,OAAO,CACb,GAAsB,EACtB,IAAmB,EACnB,OAAe;QAEf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;YAE7B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAC5C,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAEO,WAAW,CACjB,GAAsB,EACtB,IAAmB,EACnB,OAAe,EACf,KAAc;QAEd,IAAI,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAChC,MAAM,KAAK,CAAC;QACd,CAAC;QAED,qEAAqE;QACrE,qEAAqE;QACrE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;QAExD,gDAAgD;QAChD,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC9C,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;oBACpD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;wBAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAC/B,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,MAAM,CAAC,UAAU,CAAC,CAAC;gBACrB,CAAC;YACH,CAAC,EAAE,OAAO,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"retry-interceptor.js","sourceRoot":"","sources":["../src/retry-interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASlD;;;;;;;;;;;;;;;;;;;GAmBG;IAEU,gBAAgB;4BAD5B,SAAS,EAAE;;;;;;;;YACZ,6KA4DC;;;YA5DY,uDAAgB;;QAC3B,SAAS,CAAC,GAAsB;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAqC,CAAC;YACvD,IAAI,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;YAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1C,OAAO,MAAM,CAAC;QAChB,CAAC;QAEO,OAAO,CACb,GAAsB,EACtB,IAAmB,EACnB,OAAe;YAEf,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;gBAE7B,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;oBAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAC5C,CAAC;gBACJ,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QAEO,WAAW,CACjB,GAAsB,EACtB,IAAmB,EACnB,OAAe,EACf,KAAc;YAEd,IAAI,OAAO,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAChC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,qEAAqE;YACrE,qEAAqE;YACrE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,SAAS,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;YAExD,gDAAgD;YAChD,OAAO,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBAC9C,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;wBACpD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;4BAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;wBAC/B,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,MAAM,CAAC,CAAC;wBAClB,CAAC;oBACH,CAAC;oBAAC,OAAO,UAAU,EAAE,CAAC;wBACpB,MAAM,CAAC,UAAU,CAAC,CAAC;oBACrB,CAAC;gBACH,CAAC,EAAE,OAAO,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;;;;SA3DU,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"timeout-interceptor.d.ts","sourceRoot":"","sources":["../src/timeout-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAO3E,2DAA2D;AAC3D,qBAAa,YAAa,SAAQ,KAAK;gBACzB,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAIhD;AAED;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;CAuB3C"}
1
+ {"version":3,"file":"timeout-interceptor.d.ts","sourceRoot":"","sources":["../src/timeout-interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAQ3E,2DAA2D;AAC3D,qBAAa,YAAa,SAAQ,KAAK;gBACzB,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAIhD;AAED;;;;;;GAMG;AACH,qBACa,kBAAmB,YAAW,iBAAiB;IAC1D,SAAS,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;CAuB3C"}
@@ -1,3 +1,38 @@
1
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
2
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
3
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
4
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
5
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
6
+ var _, done = false;
7
+ for (var i = decorators.length - 1; i >= 0; i--) {
8
+ var context = {};
9
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
10
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
11
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
12
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
13
+ if (kind === "accessor") {
14
+ if (result === void 0) continue;
15
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
16
+ if (_ = accept(result.get)) descriptor.get = _;
17
+ if (_ = accept(result.set)) descriptor.set = _;
18
+ if (_ = accept(result.init)) initializers.unshift(_);
19
+ }
20
+ else if (_ = accept(result)) {
21
+ if (kind === "field") initializers.unshift(_);
22
+ else descriptor[key] = _;
23
+ }
24
+ }
25
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
26
+ done = true;
27
+ };
28
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ import { Singleton } from '@goodie-ts/decorators';
1
36
  /** Error thrown when a method call exceeds its timeout. */
2
37
  export class TimeoutError extends Error {
3
38
  constructor(methodKey, duration) {
@@ -12,22 +47,38 @@ export class TimeoutError extends Error {
12
47
  * For sync methods, the timeout cannot be enforced (sync code blocks the
13
48
  * event loop), so the result is returned as-is.
14
49
  */
15
- export class TimeoutInterceptor {
16
- intercept(ctx) {
17
- const meta = ctx.metadata;
18
- if (!meta)
19
- return ctx.proceed();
20
- const key = `${ctx.className}:${ctx.methodName}`;
21
- const result = ctx.proceed();
22
- // Timeout only applies to async methods (sync methods can't be interrupted)
23
- if (result instanceof Promise) {
24
- let timeoutId;
25
- const timeoutPromise = new Promise((_, reject) => {
26
- timeoutId = setTimeout(() => reject(new TimeoutError(key, meta.duration)), meta.duration);
27
- });
28
- return Promise.race([result, timeoutPromise]).finally(() => clearTimeout(timeoutId));
50
+ let TimeoutInterceptor = (() => {
51
+ let _classDecorators = [Singleton()];
52
+ let _classDescriptor;
53
+ let _classExtraInitializers = [];
54
+ let _classThis;
55
+ var TimeoutInterceptor = class {
56
+ static { _classThis = this; }
57
+ static {
58
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
59
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
60
+ TimeoutInterceptor = _classThis = _classDescriptor.value;
61
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
62
+ __runInitializers(_classThis, _classExtraInitializers);
29
63
  }
30
- return result;
31
- }
32
- }
64
+ intercept(ctx) {
65
+ const meta = ctx.metadata;
66
+ if (!meta)
67
+ return ctx.proceed();
68
+ const key = `${ctx.className}:${ctx.methodName}`;
69
+ const result = ctx.proceed();
70
+ // Timeout only applies to async methods (sync methods can't be interrupted)
71
+ if (result instanceof Promise) {
72
+ let timeoutId;
73
+ const timeoutPromise = new Promise((_, reject) => {
74
+ timeoutId = setTimeout(() => reject(new TimeoutError(key, meta.duration)), meta.duration);
75
+ });
76
+ return Promise.race([result, timeoutPromise]).finally(() => clearTimeout(timeoutId));
77
+ }
78
+ return result;
79
+ }
80
+ };
81
+ return TimeoutInterceptor = _classThis;
82
+ })();
83
+ export { TimeoutInterceptor };
33
84
  //# sourceMappingURL=timeout-interceptor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"timeout-interceptor.js","sourceRoot":"","sources":["../src/timeout-interceptor.ts"],"names":[],"mappings":"AAOA,2DAA2D;AAC3D,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,SAAiB,EAAE,QAAgB;QAC7C,KAAK,CAAC,UAAU,SAAS,oBAAoB,QAAQ,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IAC7B,SAAS,CAAC,GAAsB;QAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAuC,CAAC;QACzD,IAAI,CAAC,IAAI;YAAE,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;QAEhC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QACjD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;QAE7B,4EAA4E;QAC5E,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC9B,IAAI,SAAwC,CAAC;YAC7C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;gBACtD,SAAS,GAAG,UAAU,CACpB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAClD,IAAI,CAAC,QAAQ,CACd,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CACzD,YAAY,CAAC,SAAS,CAAC,CACxB,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
1
+ {"version":3,"file":"timeout-interceptor.js","sourceRoot":"","sources":["../src/timeout-interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOlD,2DAA2D;AAC3D,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC,YAAY,SAAiB,EAAE,QAAgB;QAC7C,KAAK,CAAC,UAAU,SAAS,oBAAoB,QAAQ,IAAI,CAAC,CAAC;QAC3D,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED;;;;;;GAMG;IAEU,kBAAkB;4BAD9B,SAAS,EAAE;;;;;;;;YACZ,6KAwBC;;;YAxBY,uDAAkB;;QAC7B,SAAS,CAAC,GAAsB;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAuC,CAAC;YACzD,IAAI,CAAC,IAAI;gBAAE,OAAO,GAAG,CAAC,OAAO,EAAE,CAAC;YAEhC,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;YACjD,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC;YAE7B,4EAA4E;YAC5E,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,IAAI,SAAwC,CAAC;gBAC7C,MAAM,cAAc,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;oBACtD,SAAS,GAAG,UAAU,CACpB,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,EAClD,IAAI,CAAC,QAAQ,CACd,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CACzD,YAAY,CAAC,SAAS,CAAC,CACxB,CAAC;YACJ,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;;;;SAvBU,kBAAkB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodie-ts/resilience",
3
- "version": "0.5.1",
3
+ "version": "0.6.0",
4
4
  "description": "Resilience patterns for goodie-ts — @Retryable, @CircuitBreaker, @Timeout decorators",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,6 +12,9 @@
12
12
  "publishConfig": {
13
13
  "access": "public"
14
14
  },
15
+ "goodie": {
16
+ "beans": "dist/beans.json"
17
+ },
15
18
  "main": "dist/index.js",
16
19
  "types": "dist/index.d.ts",
17
20
  "exports": {
@@ -21,21 +24,20 @@
21
24
  }
22
25
  },
23
26
  "dependencies": {
24
- "@goodie-ts/aop": "0.5.1"
25
- },
26
- "peerDependencies": {
27
- "@goodie-ts/transformer": "0.5.1"
27
+ "@goodie-ts/aop": "^0.6.0",
28
+ "@goodie-ts/decorators": "^0.5.2"
28
29
  },
29
30
  "devDependencies": {
30
31
  "@types/node": "^22.0.0",
31
32
  "ts-morph": "^24.0.0",
32
- "@goodie-ts/transformer": "0.5.1"
33
+ "@goodie-ts/cli": "0.6.0",
34
+ "@goodie-ts/transformer": "0.6.0"
33
35
  },
34
36
  "files": [
35
37
  "dist"
36
38
  ],
37
39
  "scripts": {
38
- "build": "tsc",
40
+ "build": "tsc && goodie generate --mode library",
39
41
  "clean": "rm -rf dist *.tsbuildinfo"
40
42
  }
41
43
  }
@@ -1,9 +0,0 @@
1
- import type { TransformerPlugin } from '@goodie-ts/transformer';
2
- /**
3
- * Create the resilience transformer plugin.
4
- *
5
- * Scans @Retryable, @CircuitBreaker, and @Timeout decorators on methods
6
- * and wires the appropriate interceptors as AOP dependencies at compile time.
7
- */
8
- export declare function createResiliencePlugin(): TransformerPlugin;
9
- //# sourceMappingURL=resilience-transformer-plugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resilience-transformer-plugin.d.ts","sourceRoot":"","sources":["../src/resilience-transformer-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AA4BhC;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,iBAAiB,CAiJ1D"}
@@ -1,211 +0,0 @@
1
- const DECORATOR_MAP = {
2
- Retryable: 'retry',
3
- CircuitBreaker: 'circuitBreaker',
4
- Timeout: 'timeout',
5
- };
6
- /** Order values — outermost (lowest) runs first: Timeout → CircuitBreaker → Retry */
7
- const ORDER_MAP = {
8
- timeout: -30, // Outermost — enforces deadline
9
- circuitBreaker: -20, // Middle — rejects if circuit open
10
- retry: -10, // Innermost — retries close to the method
11
- };
12
- const INTERCEPTOR_CLASS_MAP = {
13
- retry: 'RetryInterceptor',
14
- circuitBreaker: 'CircuitBreakerInterceptor',
15
- timeout: 'TimeoutInterceptor',
16
- };
17
- /**
18
- * Create the resilience transformer plugin.
19
- *
20
- * Scans @Retryable, @CircuitBreaker, and @Timeout decorators on methods
21
- * and wires the appropriate interceptors as AOP dependencies at compile time.
22
- */
23
- export function createResiliencePlugin() {
24
- const classResilienceInfo = new Map();
25
- return {
26
- name: 'resilience',
27
- beforeScan() {
28
- classResilienceInfo.clear();
29
- },
30
- visitMethod(ctx) {
31
- const decorators = ctx.methodDeclaration.getDecorators();
32
- for (const decorator of decorators) {
33
- const decoratorName = decorator.getName();
34
- const kind = DECORATOR_MAP[decoratorName];
35
- if (!kind)
36
- continue;
37
- const args = decorator.getArguments();
38
- const metadata = parseMetadata(kind, args);
39
- const key = `${ctx.filePath}:${ctx.className}`;
40
- const existing = classResilienceInfo.get(key) ?? [];
41
- existing.push({
42
- methodName: ctx.methodName,
43
- kind,
44
- metadata,
45
- });
46
- classResilienceInfo.set(key, existing);
47
- }
48
- },
49
- afterResolve(beans) {
50
- const usedInterceptors = new Set();
51
- for (const bean of beans) {
52
- const className = bean.tokenRef.kind === 'class' ? bean.tokenRef.className : undefined;
53
- if (!className)
54
- continue;
55
- const key = `${bean.tokenRef.importPath}:${className}`;
56
- const infos = classResilienceInfo.get(key);
57
- if (!infos || infos.length === 0)
58
- continue;
59
- const existing = (bean.metadata.interceptedMethods ?? []);
60
- for (const info of infos) {
61
- const interceptorClassName = INTERCEPTOR_CLASS_MAP[info.kind];
62
- usedInterceptors.add(interceptorClassName);
63
- const methodEntry = existing.find((m) => m.methodName === info.methodName);
64
- const interceptorRef = {
65
- className: interceptorClassName,
66
- importPath: '@goodie-ts/resilience',
67
- adviceType: 'around',
68
- order: ORDER_MAP[info.kind],
69
- metadata: info.metadata,
70
- };
71
- if (methodEntry) {
72
- methodEntry.interceptors.push(interceptorRef);
73
- }
74
- else {
75
- existing.push({
76
- methodName: info.methodName,
77
- interceptors: [interceptorRef],
78
- });
79
- }
80
- }
81
- bean.metadata.interceptedMethods = existing;
82
- }
83
- if (usedInterceptors.size === 0)
84
- return beans;
85
- // Add synthetic beans for each used interceptor
86
- const syntheticBeans = [];
87
- for (const interceptorClassName of usedInterceptors) {
88
- syntheticBeans.push({
89
- tokenRef: {
90
- kind: 'class',
91
- className: interceptorClassName,
92
- importPath: '@goodie-ts/resilience',
93
- },
94
- scope: 'singleton',
95
- eager: false,
96
- name: undefined,
97
- constructorDeps: [],
98
- fieldDeps: [],
99
- factoryKind: 'constructor',
100
- providesSource: undefined,
101
- metadata: {},
102
- sourceLocation: {
103
- filePath: '@goodie-ts/resilience',
104
- line: 0,
105
- column: 0,
106
- },
107
- });
108
- }
109
- return [...beans, ...syntheticBeans];
110
- },
111
- codegen(beans) {
112
- const usedClasses = new Set();
113
- for (const bean of beans) {
114
- const methods = bean.metadata.interceptedMethods;
115
- if (!methods)
116
- continue;
117
- for (const m of methods) {
118
- for (const i of m.interceptors) {
119
- if (i.importPath === '@goodie-ts/resilience') {
120
- usedClasses.add(i.className);
121
- }
122
- }
123
- }
124
- }
125
- if (usedClasses.size === 0)
126
- return {};
127
- const classNames = [...usedClasses].sort().join(', ');
128
- return {
129
- imports: [
130
- `import { ${classNames} } from '@goodie-ts/resilience'`,
131
- "import { buildInterceptorChain } from '@goodie-ts/aop'",
132
- ],
133
- };
134
- },
135
- };
136
- }
137
- /** Strip TypeScript numeric separators: 1_000 → 1000 */
138
- function stripSeparators(s) {
139
- return s.replace(/_/g, '');
140
- }
141
- /**
142
- * Parse decorator arguments into metadata.
143
- *
144
- * **Limitation:** Only literal numeric values are supported. Const references
145
- * or computed expressions (e.g. `maxAttempts: MAX_RETRIES`) will fall back to
146
- * defaults silently. This matches the compile-time AST text parsing approach
147
- * used by all goodie-ts transformer plugins.
148
- */
149
- function parseMetadata(kind, args) {
150
- switch (kind) {
151
- case 'retry': {
152
- const defaults = { maxAttempts: 3, delay: 1000, multiplier: 1 };
153
- if (args.length === 0)
154
- return defaults;
155
- const text = args[0].getText();
156
- const maxMatch = text.match(/maxAttempts\s*:\s*(\d[\d_]*)/);
157
- const delayMatch = text.match(/delay\s*:\s*(\d[\d_]*)/);
158
- const multMatch = text.match(/multiplier\s*:\s*([\d_]+(?:\.[\d_]+)?)/);
159
- return {
160
- maxAttempts: maxMatch
161
- ? Number.parseInt(stripSeparators(maxMatch[1]), 10)
162
- : defaults.maxAttempts,
163
- delay: delayMatch
164
- ? Number.parseInt(stripSeparators(delayMatch[1]), 10)
165
- : defaults.delay,
166
- multiplier: multMatch
167
- ? Number.parseFloat(stripSeparators(multMatch[1]))
168
- : defaults.multiplier,
169
- };
170
- }
171
- case 'circuitBreaker': {
172
- const defaults = {
173
- failureThreshold: 5,
174
- resetTimeout: 30000,
175
- halfOpenAttempts: 1,
176
- };
177
- if (args.length === 0)
178
- return defaults;
179
- const text = args[0].getText();
180
- const threshMatch = text.match(/failureThreshold\s*:\s*(\d[\d_]*)/);
181
- const resetMatch = text.match(/resetTimeout\s*:\s*(\d[\d_]*)/);
182
- const halfMatch = text.match(/halfOpenAttempts\s*:\s*(\d[\d_]*)/);
183
- return {
184
- failureThreshold: threshMatch
185
- ? Number.parseInt(stripSeparators(threshMatch[1]), 10)
186
- : defaults.failureThreshold,
187
- resetTimeout: resetMatch
188
- ? Number.parseInt(stripSeparators(resetMatch[1]), 10)
189
- : defaults.resetTimeout,
190
- halfOpenAttempts: halfMatch
191
- ? Number.parseInt(stripSeparators(halfMatch[1]), 10)
192
- : defaults.halfOpenAttempts,
193
- };
194
- }
195
- case 'timeout': {
196
- if (args.length === 0)
197
- return { duration: 5000 };
198
- const text = stripSeparators(args[0].getText());
199
- const num = Number.parseInt(text, 10);
200
- if (Number.isNaN(num)) {
201
- if (text.includes('{')) {
202
- console.warn(`[resilience] @Timeout received an object literal argument (${text}). ` +
203
- 'Only numeric durations are supported — falling back to 5000ms.');
204
- }
205
- return { duration: 5000 };
206
- }
207
- return { duration: num };
208
- }
209
- }
210
- }
211
- //# sourceMappingURL=resilience-transformer-plugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"resilience-transformer-plugin.js","sourceRoot":"","sources":["../src/resilience-transformer-plugin.ts"],"names":[],"mappings":"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"}