awaitly 1.35.0 → 2.0.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/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +29 -4
- package/dist/result.d.ts +29 -4
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
- package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -168
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-By77n4Fa.d.ts +0 -15
- package/dist/di-OJfsohf-.d.cts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-4sV7mTqj.d.cts +0 -72
- package/dist/guards-BIX05ALH.d.ts +0 -72
- package/dist/hitl-DFn4Xa_l.d.cts +0 -468
- package/dist/hitl-DU5VpKq7.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-CnvBryQB.d.ts +0 -417
- package/dist/index-DEZEf8Fs.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
- package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-BziYHFkD.d.ts +0 -323
- package/dist/types-C5jLEUqY.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- package/dist/webhook.js.map +0 -1
package/dist/cache.d.ts
DELETED
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
import { Duration } from './duration.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* awaitly/cache
|
|
5
|
-
*
|
|
6
|
-
* Caching utilities for memoization and deduplication.
|
|
7
|
-
* Inspired by Effect.js caching patterns.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* ```typescript
|
|
11
|
-
* import { cached, cachedWithTTL, cachedFunction, once } from 'awaitly/cache';
|
|
12
|
-
*
|
|
13
|
-
* // Compute once, reuse forever
|
|
14
|
-
* const getConfig = cached(() => loadConfig());
|
|
15
|
-
*
|
|
16
|
-
* // Expire after duration
|
|
17
|
-
* const getUser = cachedWithTTL(() => fetchUser(id), { ttl: '5m' });
|
|
18
|
-
*
|
|
19
|
-
* // Memoize by arguments
|
|
20
|
-
* const fetchUserMemo = cachedFunction((id: string) => fetchUser(id));
|
|
21
|
-
*
|
|
22
|
-
* // Execute exactly once (for initialization)
|
|
23
|
-
* const initDb = once(() => connectToDatabase());
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Duration input type - supports Duration objects or string shorthand.
|
|
29
|
-
*/
|
|
30
|
-
type DurationInput = Duration | string;
|
|
31
|
-
/**
|
|
32
|
-
* Cache entry with metadata.
|
|
33
|
-
*/
|
|
34
|
-
interface CacheEntry<T> {
|
|
35
|
-
value: T;
|
|
36
|
-
timestamp: number;
|
|
37
|
-
expiresAt?: number;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Cache options.
|
|
41
|
-
*/
|
|
42
|
-
interface CacheOptions {
|
|
43
|
-
/**
|
|
44
|
-
* Time-to-live for cached values.
|
|
45
|
-
* Accepts Duration or string shorthand like "5m", "1h", "30s".
|
|
46
|
-
*/
|
|
47
|
-
ttl?: DurationInput;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Cached function options.
|
|
51
|
-
*/
|
|
52
|
-
interface CachedFunctionOptions<Args extends unknown[]> {
|
|
53
|
-
/**
|
|
54
|
-
* Custom key generator for arguments.
|
|
55
|
-
* Default: JSON.stringify(args)
|
|
56
|
-
*/
|
|
57
|
-
keyFn?: (...args: Args) => string;
|
|
58
|
-
/**
|
|
59
|
-
* Time-to-live for cached values.
|
|
60
|
-
*/
|
|
61
|
-
ttl?: DurationInput;
|
|
62
|
-
/**
|
|
63
|
-
* Maximum cache size. When exceeded, oldest entries are evicted.
|
|
64
|
-
* @default Infinity
|
|
65
|
-
*/
|
|
66
|
-
maxSize?: number;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Cache statistics.
|
|
70
|
-
*/
|
|
71
|
-
interface CacheStats {
|
|
72
|
-
hits: number;
|
|
73
|
-
misses: number;
|
|
74
|
-
size: number;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Create a cached computation that executes once and reuses the result.
|
|
78
|
-
*
|
|
79
|
-
* The function is called at most once, even with concurrent calls.
|
|
80
|
-
* Subsequent calls return the cached value immediately.
|
|
81
|
-
*
|
|
82
|
-
* @param fn - Function to compute the cached value
|
|
83
|
-
* @returns Function that returns the cached value
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```typescript
|
|
87
|
-
* const getConfig = cached(async () => {
|
|
88
|
-
* console.log('Loading config...');
|
|
89
|
-
* return await loadConfigFromFile();
|
|
90
|
-
* });
|
|
91
|
-
*
|
|
92
|
-
* // First call executes the function
|
|
93
|
-
* const config1 = await getConfig(); // "Loading config..."
|
|
94
|
-
*
|
|
95
|
-
* // Subsequent calls return cached value
|
|
96
|
-
* const config2 = await getConfig(); // No log, instant return
|
|
97
|
-
* const config3 = await getConfig(); // No log, instant return
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
declare function cached<T>(fn: () => T | Promise<T>): () => Promise<T>;
|
|
101
|
-
/**
|
|
102
|
-
* Create a cached computation that expires after a duration.
|
|
103
|
-
*
|
|
104
|
-
* The function is re-executed when the TTL expires.
|
|
105
|
-
* Concurrent calls while computing share the same promise.
|
|
106
|
-
*
|
|
107
|
-
* @param fn - Function to compute the cached value
|
|
108
|
-
* @param options - Cache options including TTL
|
|
109
|
-
* @returns Function that returns the cached value
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```typescript
|
|
113
|
-
* const getUser = cachedWithTTL(
|
|
114
|
-
* async () => await fetchUser(userId),
|
|
115
|
-
* { ttl: '5m' } // Cache for 5 minutes
|
|
116
|
-
* );
|
|
117
|
-
*
|
|
118
|
-
* const user1 = await getUser(); // Fetches from API
|
|
119
|
-
* const user2 = await getUser(); // Returns cached (within 5 min)
|
|
120
|
-
*
|
|
121
|
-
* // After 5 minutes...
|
|
122
|
-
* const user3 = await getUser(); // Fetches again
|
|
123
|
-
* ```
|
|
124
|
-
*/
|
|
125
|
-
declare function cachedWithTTL<T>(fn: () => T | Promise<T>, options: {
|
|
126
|
-
ttl: DurationInput;
|
|
127
|
-
}): () => Promise<T>;
|
|
128
|
-
/**
|
|
129
|
-
* Memoized function interface.
|
|
130
|
-
*/
|
|
131
|
-
interface MemoizedFunction<Args extends unknown[], T> {
|
|
132
|
-
(...args: Args): Promise<T>;
|
|
133
|
-
/** Clear the entire cache */
|
|
134
|
-
clear(): void;
|
|
135
|
-
/** Clear a specific cache entry */
|
|
136
|
-
delete(...args: Args): boolean;
|
|
137
|
-
/** Check if an entry exists */
|
|
138
|
-
has(...args: Args): boolean;
|
|
139
|
-
/** Get cache statistics */
|
|
140
|
-
getStats(): CacheStats;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Create a memoized function that caches results by arguments.
|
|
144
|
-
*
|
|
145
|
-
* Each unique set of arguments produces a cached result.
|
|
146
|
-
* Supports TTL and max size limits.
|
|
147
|
-
*
|
|
148
|
-
* @param fn - Function to memoize
|
|
149
|
-
* @param options - Memoization options
|
|
150
|
-
* @returns Memoized function with cache control methods
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const fetchUserMemo = cachedFunction(
|
|
155
|
-
* async (id: string) => await fetchUser(id),
|
|
156
|
-
* { ttl: '5m', maxSize: 100 }
|
|
157
|
-
* );
|
|
158
|
-
*
|
|
159
|
-
* const user1 = await fetchUserMemo('user-1'); // Fetches
|
|
160
|
-
* const user2 = await fetchUserMemo('user-2'); // Fetches
|
|
161
|
-
* const user1Again = await fetchUserMemo('user-1'); // Cached!
|
|
162
|
-
*
|
|
163
|
-
* // Cache control
|
|
164
|
-
* fetchUserMemo.delete('user-1'); // Remove specific entry
|
|
165
|
-
* fetchUserMemo.clear(); // Clear all
|
|
166
|
-
* console.log(fetchUserMemo.getStats()); // { hits: 1, misses: 2, size: 0 }
|
|
167
|
-
* ```
|
|
168
|
-
*/
|
|
169
|
-
declare function cachedFunction<Args extends unknown[], T>(fn: (...args: Args) => T | Promise<T>, options?: CachedFunctionOptions<Args>): MemoizedFunction<Args, T>;
|
|
170
|
-
/**
|
|
171
|
-
* Once-executed function interface.
|
|
172
|
-
*/
|
|
173
|
-
interface OnceFunction<T> {
|
|
174
|
-
(): Promise<T>;
|
|
175
|
-
/** Check if the function has been called */
|
|
176
|
-
called: boolean;
|
|
177
|
-
/** Check if execution completed successfully */
|
|
178
|
-
completed: boolean;
|
|
179
|
-
/** Check if execution failed */
|
|
180
|
-
failed: boolean;
|
|
181
|
-
/** Reset to allow re-execution */
|
|
182
|
-
reset(): void;
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Create a function that executes exactly once.
|
|
186
|
-
*
|
|
187
|
-
* Useful for initialization code that should only run once.
|
|
188
|
-
* Subsequent calls return the same result or re-throw the same error.
|
|
189
|
-
*
|
|
190
|
-
* @param fn - Function to execute once
|
|
191
|
-
* @returns Function that executes once and returns the result
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```typescript
|
|
195
|
-
* const initDb = once(async () => {
|
|
196
|
-
* console.log('Connecting to database...');
|
|
197
|
-
* const conn = await createConnection();
|
|
198
|
-
* return conn;
|
|
199
|
-
* });
|
|
200
|
-
*
|
|
201
|
-
* // First call executes
|
|
202
|
-
* const db1 = await initDb(); // "Connecting to database..."
|
|
203
|
-
*
|
|
204
|
-
* // Subsequent calls return cached result
|
|
205
|
-
* const db2 = await initDb(); // Instant, same connection
|
|
206
|
-
* const db3 = await initDb(); // Instant, same connection
|
|
207
|
-
*
|
|
208
|
-
* console.log(initDb.called); // true
|
|
209
|
-
* console.log(initDb.completed); // true
|
|
210
|
-
* ```
|
|
211
|
-
*/
|
|
212
|
-
declare function once<T>(fn: () => T | Promise<T>): OnceFunction<T>;
|
|
213
|
-
/**
|
|
214
|
-
* General purpose cache interface.
|
|
215
|
-
*/
|
|
216
|
-
interface Cache<K, V> {
|
|
217
|
-
/** Get a value from the cache */
|
|
218
|
-
get(key: K): V | undefined;
|
|
219
|
-
/** Set a value in the cache */
|
|
220
|
-
set(key: K, value: V, options?: {
|
|
221
|
-
ttl?: DurationInput;
|
|
222
|
-
}): void;
|
|
223
|
-
/** Check if a key exists */
|
|
224
|
-
has(key: K): boolean;
|
|
225
|
-
/** Delete a key from the cache */
|
|
226
|
-
delete(key: K): boolean;
|
|
227
|
-
/** Clear the entire cache */
|
|
228
|
-
clear(): void;
|
|
229
|
-
/** Get the cache size */
|
|
230
|
-
size: number;
|
|
231
|
-
/** Get cache statistics */
|
|
232
|
-
getStats(): CacheStats;
|
|
233
|
-
}
|
|
234
|
-
/**
|
|
235
|
-
* Cache configuration.
|
|
236
|
-
*/
|
|
237
|
-
interface CacheConfig {
|
|
238
|
-
/**
|
|
239
|
-
* Default TTL for all entries.
|
|
240
|
-
*/
|
|
241
|
-
defaultTTL?: DurationInput;
|
|
242
|
-
/**
|
|
243
|
-
* Maximum cache size.
|
|
244
|
-
* @default Infinity
|
|
245
|
-
*/
|
|
246
|
-
maxSize?: number;
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Create a general-purpose cache with TTL and size limits.
|
|
250
|
-
*
|
|
251
|
-
* @param config - Cache configuration
|
|
252
|
-
* @returns A Cache instance
|
|
253
|
-
*
|
|
254
|
-
* @example
|
|
255
|
-
* ```typescript
|
|
256
|
-
* const cache = createCache<string, User>({
|
|
257
|
-
* defaultTTL: '5m',
|
|
258
|
-
* maxSize: 1000,
|
|
259
|
-
* });
|
|
260
|
-
*
|
|
261
|
-
* cache.set('user:1', user);
|
|
262
|
-
* cache.set('user:2', user2, { ttl: '1h' }); // Override TTL
|
|
263
|
-
*
|
|
264
|
-
* const user = cache.get('user:1');
|
|
265
|
-
* ```
|
|
266
|
-
*/
|
|
267
|
-
declare function createCache<K, V>(config?: CacheConfig): Cache<K, V>;
|
|
268
|
-
|
|
269
|
-
export { type Cache, type CacheConfig, type CacheEntry, type CacheOptions, type CacheStats, type CachedFunctionOptions, type DurationInput, type MemoizedFunction, type OnceFunction, cached, cachedFunction, cachedWithTTL, createCache, once };
|
package/dist/cache.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function b(n){return{_tag:"Duration",millis:n}}function A(n){return{_tag:"Duration",millis:n*1e3}}function C(n){return{_tag:"Duration",millis:n*60*1e3}}function w(n){return{_tag:"Duration",millis:n*60*60*1e3}}function P(n){return{_tag:"Duration",millis:n*24*60*60*1e3}}function y(n){let t=n.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let r=parseFloat(t[1]);switch(t[2].toLowerCase()){case"ms":return b(r);case"s":return A(r);case"m":return C(r);case"h":return w(r);case"d":return P(r);default:return}}function h(n){if(typeof n=="string"){let t=y(n);if(!t)throw new Error(`Invalid duration string: ${n}`);return t.millis}return n.millis}function v(n){let t={status:"empty"};return async()=>{if(t.status==="filled")return t.value;if(t.status==="pending")return t.promise;let r=Promise.resolve(n()).then(e=>(t={status:"filled",value:e},e));return t={status:"pending",promise:r},r}}function M(n,t){let r=h(t.ttl),e={status:"empty"};return async()=>{let a=Date.now();if(e.status==="filled"&&a<e.expiresAt)return e.value;if(e.status==="pending")return e.promise;let o=Promise.resolve(n()).then(c=>(e={status:"filled",value:c,expiresAt:Date.now()+r},c));return e={status:"pending",promise:o},o}}function S(n,t={}){let{keyFn:r=(...s)=>JSON.stringify(s),maxSize:e=1/0}=t,a=t.ttl?h(t.ttl):void 0,o=new Map,c=new Map,d=0,i=0;function l(){if(o.size<=e)return;let s=null,u=1/0;for(let[p,f]of o.entries())f.timestamp<u&&(u=f.timestamp,s=p);s&&o.delete(s)}let m=async(...s)=>{let u=r(...s),p=Date.now(),f=o.get(u);if(f)if(f.expiresAt&&p>=f.expiresAt)o.delete(u);else return d++,f.value;let g=c.get(u);if(g)return g;i++;let x=Promise.resolve(n(...s)).then(D=>{let T={value:D,timestamp:Date.now(),expiresAt:a?Date.now()+a:void 0};return o.set(u,T),c.delete(u),l(),D});c.set(u,x);try{return await x}catch(D){throw c.delete(u),D}};return m.clear=()=>{o.clear(),c.clear()},m.delete=(...s)=>{let u=r(...s);return o.delete(u)},m.has=(...s)=>{let u=r(...s),p=o.get(u);return p?p.expiresAt&&Date.now()>=p.expiresAt?(o.delete(u),!1):!0:!1},m.getStats=()=>({hits:d,misses:i,size:o.size}),m}function z(n){let t={status:"idle"},r=async()=>{if(t.status==="done")return t.value;if(t.status==="failed")throw t.error;if(t.status==="running")return t.promise;let e=Promise.resolve(n()).then(a=>(t={status:"done",value:a},a)).catch(a=>{throw t={status:"failed",error:a},a});return t={status:"running",promise:e},e};return Object.defineProperty(r,"called",{get:()=>t.status!=="idle"}),Object.defineProperty(r,"completed",{get:()=>t.status==="done"}),Object.defineProperty(r,"failed",{get:()=>t.status==="failed"}),r.reset=()=>{t={status:"idle"}},r}function O(n={}){let{maxSize:t=1/0}=n,r=n.defaultTTL?h(n.defaultTTL):void 0,e=new Map,a=0,o=0;function c(i){return i.expiresAt!==void 0&&Date.now()>=i.expiresAt}function d(){if(e.size<=t)return;let i=null,l=1/0;for(let[m,s]of e.entries())s.timestamp<l&&(l=s.timestamp,i=m);i!==null&&e.delete(i)}return{get(i){let l=e.get(i);if(!l){o++;return}if(c(l)){e.delete(i),o++;return}return a++,l.value},set(i,l,m){let s=m?.ttl?h(m.ttl):r,u=Date.now();e.set(i,{value:l,timestamp:u,expiresAt:s?u+s:void 0}),d()},has(i){let l=e.get(i);return l?c(l)?(e.delete(i),!1):!0:!1},delete(i){return e.delete(i)},clear(){e.clear()},get size(){return e.size},getStats(){return{hits:a,misses:o,size:e.size}}}}export{v as cached,S as cachedFunction,M as cachedWithTTL,O as createCache,z as once};
|
|
2
|
-
//# sourceMappingURL=cache.js.map
|
package/dist/cache.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/duration.ts","../src/cache.ts"],"sourcesContent":["/**\n * awaitly/duration\n *\n * Type-safe duration handling inspired by Effect's Duration module.\n * Prevents unit confusion (milliseconds vs seconds) with explicit constructors.\n */\n\n// =============================================================================\n// Duration Type\n// =============================================================================\n\n/**\n * A type-safe representation of a time duration.\n * Use the constructor functions (millis, seconds, etc.) to create durations.\n */\nexport interface Duration {\n readonly _tag: \"Duration\";\n readonly millis: number;\n}\n\n// =============================================================================\n// Constructors\n// =============================================================================\n\n/**\n * Create a Duration from milliseconds.\n *\n * @example\n * ```typescript\n * const d = Duration.millis(500)\n * ```\n */\nexport function millis(ms: number): Duration {\n return { _tag: \"Duration\", millis: ms };\n}\n\n/**\n * Create a Duration from seconds.\n *\n * @example\n * ```typescript\n * const d = Duration.seconds(5) // 5000ms\n * ```\n */\nexport function seconds(s: number): Duration {\n return { _tag: \"Duration\", millis: s * 1000 };\n}\n\n/**\n * Create a Duration from minutes.\n *\n * @example\n * ```typescript\n * const d = Duration.minutes(2) // 120000ms\n * ```\n */\nexport function minutes(m: number): Duration {\n return { _tag: \"Duration\", millis: m * 60 * 1000 };\n}\n\n/**\n * Create a Duration from hours.\n *\n * @example\n * ```typescript\n * const d = Duration.hours(1) // 3600000ms\n * ```\n */\nexport function hours(h: number): Duration {\n return { _tag: \"Duration\", millis: h * 60 * 60 * 1000 };\n}\n\n/**\n * Create a Duration from days.\n *\n * @example\n * ```typescript\n * const d = Duration.days(1) // 86400000ms\n * ```\n */\nexport function days(d: number): Duration {\n return { _tag: \"Duration\", millis: d * 24 * 60 * 60 * 1000 };\n}\n\n/**\n * Zero duration.\n */\nexport const zero: Duration = { _tag: \"Duration\", millis: 0 };\n\n/**\n * Infinite duration (represented as Infinity milliseconds).\n */\nexport const infinity: Duration = { _tag: \"Duration\", millis: Infinity };\n\n// =============================================================================\n// Conversions\n// =============================================================================\n\n/**\n * Convert a Duration to milliseconds.\n */\nexport function toMillis(duration: Duration): number {\n return duration.millis;\n}\n\n/**\n * Convert a Duration to seconds.\n */\nexport function toSeconds(duration: Duration): number {\n return duration.millis / 1000;\n}\n\n/**\n * Convert a Duration to minutes.\n */\nexport function toMinutes(duration: Duration): number {\n return duration.millis / (60 * 1000);\n}\n\n/**\n * Convert a Duration to hours.\n */\nexport function toHours(duration: Duration): number {\n return duration.millis / (60 * 60 * 1000);\n}\n\n/**\n * Convert a Duration to days.\n */\nexport function toDays(duration: Duration): number {\n return duration.millis / (24 * 60 * 60 * 1000);\n}\n\n// =============================================================================\n// Operations\n// =============================================================================\n\n/**\n * Add two durations.\n *\n * @example\n * ```typescript\n * const total = Duration.add(Duration.seconds(5), Duration.millis(500))\n * // 5500ms\n * ```\n */\nexport function add(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: a.millis + b.millis };\n}\n\n/**\n * Subtract duration b from duration a.\n * Result is clamped to zero (no negative durations).\n *\n * @example\n * ```typescript\n * const remaining = Duration.subtract(Duration.seconds(5), Duration.seconds(2))\n * // 3000ms\n * ```\n */\nexport function subtract(a: Duration, b: Duration): Duration {\n return { _tag: \"Duration\", millis: Math.max(0, a.millis - b.millis) };\n}\n\n/**\n * Multiply a duration by a factor.\n *\n * @example\n * ```typescript\n * const doubled = Duration.multiply(Duration.seconds(5), 2)\n * // 10000ms\n * ```\n */\nexport function multiply(duration: Duration, factor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis * factor };\n}\n\n/**\n * Divide a duration by a divisor.\n *\n * @example\n * ```typescript\n * const half = Duration.divide(Duration.seconds(10), 2)\n * // 5000ms\n * ```\n */\nexport function divide(duration: Duration, divisor: number): Duration {\n return { _tag: \"Duration\", millis: duration.millis / divisor };\n}\n\n// =============================================================================\n// Comparisons\n// =============================================================================\n\n/**\n * Check if duration a is less than duration b.\n */\nexport function lessThan(a: Duration, b: Duration): boolean {\n return a.millis < b.millis;\n}\n\n/**\n * Check if duration a is less than or equal to duration b.\n */\nexport function lessThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis <= b.millis;\n}\n\n/**\n * Check if duration a is greater than duration b.\n */\nexport function greaterThan(a: Duration, b: Duration): boolean {\n return a.millis > b.millis;\n}\n\n/**\n * Check if duration a is greater than or equal to duration b.\n */\nexport function greaterThanOrEqual(a: Duration, b: Duration): boolean {\n return a.millis >= b.millis;\n}\n\n/**\n * Check if two durations are equal.\n */\nexport function equals(a: Duration, b: Duration): boolean {\n return a.millis === b.millis;\n}\n\n/**\n * Get the minimum of two durations.\n */\nexport function min(a: Duration, b: Duration): Duration {\n return a.millis <= b.millis ? a : b;\n}\n\n/**\n * Get the maximum of two durations.\n */\nexport function max(a: Duration, b: Duration): Duration {\n return a.millis >= b.millis ? a : b;\n}\n\n/**\n * Clamp a duration between a minimum and maximum.\n */\nexport function clamp(duration: Duration, minimum: Duration, maximum: Duration): Duration {\n return min(max(duration, minimum), maximum);\n}\n\n// =============================================================================\n// Predicates\n// =============================================================================\n\n/**\n * Check if a duration is zero.\n */\nexport function isZero(duration: Duration): boolean {\n return duration.millis === 0;\n}\n\n/**\n * Check if a duration is infinite.\n */\nexport function isInfinite(duration: Duration): boolean {\n return duration.millis === Infinity;\n}\n\n/**\n * Check if a duration is finite and positive.\n */\nexport function isFinite(duration: Duration): boolean {\n return Number.isFinite(duration.millis) && duration.millis > 0;\n}\n\n/**\n * Type guard to check if a value is a Duration.\n */\nexport function isDuration(value: unknown): value is Duration {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n value._tag === \"Duration\" &&\n \"millis\" in value &&\n typeof value.millis === \"number\"\n );\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\n/**\n * Format a duration as a human-readable string.\n *\n * @example\n * ```typescript\n * Duration.format(Duration.seconds(90)) // \"1m 30s\"\n * Duration.format(Duration.millis(500)) // \"500ms\"\n * ```\n */\nexport function format(duration: Duration): string {\n const ms = duration.millis;\n\n if (ms === Infinity) return \"∞\";\n if (ms === 0) return \"0ms\";\n\n const days = Math.floor(ms / (24 * 60 * 60 * 1000));\n const hours = Math.floor((ms % (24 * 60 * 60 * 1000)) / (60 * 60 * 1000));\n const minutes = Math.floor((ms % (60 * 60 * 1000)) / (60 * 1000));\n const seconds = Math.floor((ms % (60 * 1000)) / 1000);\n const millis = ms % 1000;\n\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0) parts.push(`${seconds}s`);\n if (millis > 0 && parts.length === 0) parts.push(`${millis}ms`);\n\n return parts.join(\" \") || \"0ms\";\n}\n\n// =============================================================================\n// Parsing\n// =============================================================================\n\n/**\n * Parse a duration from a string like \"100ms\", \"5s\", \"2m\", \"1h\", \"1d\".\n * Returns undefined if parsing fails.\n *\n * @example\n * ```typescript\n * Duration.parse(\"5s\") // Duration.seconds(5)\n * Duration.parse(\"100ms\") // Duration.millis(100)\n * Duration.parse(\"2m\") // Duration.minutes(2)\n * ```\n */\nexport function parse(input: string): Duration | undefined {\n const match = input.trim().match(/^(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d)$/i);\n if (!match) return undefined;\n\n const value = parseFloat(match[1]);\n const unit = match[2].toLowerCase();\n\n switch (unit) {\n case \"ms\":\n return millis(value);\n case \"s\":\n return seconds(value);\n case \"m\":\n return minutes(value);\n case \"h\":\n return hours(value);\n case \"d\":\n return days(value);\n default:\n return undefined;\n }\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Duration namespace with all functions for convenient access.\n *\n * @example\n * ```typescript\n * import { Duration } from \"awaitly\";\n *\n * const timeout = Duration.seconds(30);\n * const delay = Duration.millis(100);\n * const total = Duration.add(timeout, delay);\n *\n * console.log(Duration.format(total)); // \"30s 100ms\"\n * ```\n */\nexport const Duration = {\n // Constructors\n millis,\n seconds,\n minutes,\n hours,\n days,\n zero,\n infinity,\n\n // Conversions\n toMillis,\n toSeconds,\n toMinutes,\n toHours,\n toDays,\n\n // Operations\n add,\n subtract,\n multiply,\n divide,\n\n // Comparisons\n lessThan,\n lessThanOrEqual,\n greaterThan,\n greaterThanOrEqual,\n equals,\n min,\n max,\n clamp,\n\n // Predicates\n isZero,\n isInfinite,\n isFinite,\n isDuration,\n\n // Formatting\n format,\n parse,\n} as const;\n\nexport type { Duration as DurationType };\n","/**\n * awaitly/cache\n *\n * Caching utilities for memoization and deduplication.\n * Inspired by Effect.js caching patterns.\n *\n * @example\n * ```typescript\n * import { cached, cachedWithTTL, cachedFunction, once } from 'awaitly/cache';\n *\n * // Compute once, reuse forever\n * const getConfig = cached(() => loadConfig());\n *\n * // Expire after duration\n * const getUser = cachedWithTTL(() => fetchUser(id), { ttl: '5m' });\n *\n * // Memoize by arguments\n * const fetchUserMemo = cachedFunction((id: string) => fetchUser(id));\n *\n * // Execute exactly once (for initialization)\n * const initDb = once(() => connectToDatabase());\n * ```\n */\n\nimport { Duration, parse as parseDuration } from \"./duration\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Duration input type - supports Duration objects or string shorthand.\n */\nexport type DurationInput = Duration | string;\n\n/**\n * Cache entry with metadata.\n */\nexport interface CacheEntry<T> {\n value: T;\n timestamp: number;\n expiresAt?: number;\n}\n\n/**\n * Cache options.\n */\nexport interface CacheOptions {\n /**\n * Time-to-live for cached values.\n * Accepts Duration or string shorthand like \"5m\", \"1h\", \"30s\".\n */\n ttl?: DurationInput;\n}\n\n/**\n * Cached function options.\n */\nexport interface CachedFunctionOptions<Args extends unknown[]> {\n /**\n * Custom key generator for arguments.\n * Default: JSON.stringify(args)\n */\n keyFn?: (...args: Args) => string;\n\n /**\n * Time-to-live for cached values.\n */\n ttl?: DurationInput;\n\n /**\n * Maximum cache size. When exceeded, oldest entries are evicted.\n * @default Infinity\n */\n maxSize?: number;\n}\n\n/**\n * Cache statistics.\n */\nexport interface CacheStats {\n hits: number;\n misses: number;\n size: number;\n}\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\n/**\n * Convert DurationInput to milliseconds.\n */\nfunction toMs(duration: DurationInput): number {\n if (typeof duration === \"string\") {\n const parsed = parseDuration(duration);\n if (!parsed) {\n throw new Error(`Invalid duration string: ${duration}`);\n }\n return parsed.millis;\n }\n return duration.millis;\n}\n\n// =============================================================================\n// cached() - Compute once, reuse forever\n// =============================================================================\n\n/**\n * State for a cached value.\n */\ntype CachedState<T> =\n | { status: \"empty\" }\n | { status: \"pending\"; promise: Promise<T> }\n | { status: \"filled\"; value: T };\n\n/**\n * Create a cached computation that executes once and reuses the result.\n *\n * The function is called at most once, even with concurrent calls.\n * Subsequent calls return the cached value immediately.\n *\n * @param fn - Function to compute the cached value\n * @returns Function that returns the cached value\n *\n * @example\n * ```typescript\n * const getConfig = cached(async () => {\n * console.log('Loading config...');\n * return await loadConfigFromFile();\n * });\n *\n * // First call executes the function\n * const config1 = await getConfig(); // \"Loading config...\"\n *\n * // Subsequent calls return cached value\n * const config2 = await getConfig(); // No log, instant return\n * const config3 = await getConfig(); // No log, instant return\n * ```\n */\nexport function cached<T>(fn: () => T | Promise<T>): () => Promise<T> {\n let state: CachedState<T> = { status: \"empty\" };\n\n return async () => {\n if (state.status === \"filled\") {\n return state.value;\n }\n\n if (state.status === \"pending\") {\n return state.promise;\n }\n\n // Compute the value\n const promise = Promise.resolve(fn()).then((value) => {\n state = { status: \"filled\", value };\n return value;\n });\n\n state = { status: \"pending\", promise };\n return promise;\n };\n}\n\n// =============================================================================\n// cachedWithTTL() - Expire after duration\n// =============================================================================\n\n/**\n * State for a TTL-cached value.\n */\ntype CachedTTLState<T> =\n | { status: \"empty\" }\n | { status: \"pending\"; promise: Promise<T> }\n | { status: \"filled\"; value: T; expiresAt: number };\n\n/**\n * Create a cached computation that expires after a duration.\n *\n * The function is re-executed when the TTL expires.\n * Concurrent calls while computing share the same promise.\n *\n * @param fn - Function to compute the cached value\n * @param options - Cache options including TTL\n * @returns Function that returns the cached value\n *\n * @example\n * ```typescript\n * const getUser = cachedWithTTL(\n * async () => await fetchUser(userId),\n * { ttl: '5m' } // Cache for 5 minutes\n * );\n *\n * const user1 = await getUser(); // Fetches from API\n * const user2 = await getUser(); // Returns cached (within 5 min)\n *\n * // After 5 minutes...\n * const user3 = await getUser(); // Fetches again\n * ```\n */\nexport function cachedWithTTL<T>(\n fn: () => T | Promise<T>,\n options: { ttl: DurationInput }\n): () => Promise<T> {\n const ttlMs = toMs(options.ttl);\n let state: CachedTTLState<T> = { status: \"empty\" };\n\n return async () => {\n const now = Date.now();\n\n // Check if cached value is still valid\n if (state.status === \"filled\" && now < state.expiresAt) {\n return state.value;\n }\n\n // Check if already computing\n if (state.status === \"pending\") {\n return state.promise;\n }\n\n // Compute the value\n const promise = Promise.resolve(fn()).then((value) => {\n state = {\n status: \"filled\",\n value,\n expiresAt: Date.now() + ttlMs,\n };\n return value;\n });\n\n state = { status: \"pending\", promise };\n return promise;\n };\n}\n\n// =============================================================================\n// cachedFunction() - Memoize by arguments\n// =============================================================================\n\n/**\n * Cache entry for memoized functions.\n */\ninterface MemoEntry<T> {\n value: T;\n timestamp: number;\n expiresAt?: number;\n}\n\n/**\n * Memoized function interface.\n */\nexport interface MemoizedFunction<Args extends unknown[], T> {\n (...args: Args): Promise<T>;\n /** Clear the entire cache */\n clear(): void;\n /** Clear a specific cache entry */\n delete(...args: Args): boolean;\n /** Check if an entry exists */\n has(...args: Args): boolean;\n /** Get cache statistics */\n getStats(): CacheStats;\n}\n\n/**\n * Create a memoized function that caches results by arguments.\n *\n * Each unique set of arguments produces a cached result.\n * Supports TTL and max size limits.\n *\n * @param fn - Function to memoize\n * @param options - Memoization options\n * @returns Memoized function with cache control methods\n *\n * @example\n * ```typescript\n * const fetchUserMemo = cachedFunction(\n * async (id: string) => await fetchUser(id),\n * { ttl: '5m', maxSize: 100 }\n * );\n *\n * const user1 = await fetchUserMemo('user-1'); // Fetches\n * const user2 = await fetchUserMemo('user-2'); // Fetches\n * const user1Again = await fetchUserMemo('user-1'); // Cached!\n *\n * // Cache control\n * fetchUserMemo.delete('user-1'); // Remove specific entry\n * fetchUserMemo.clear(); // Clear all\n * console.log(fetchUserMemo.getStats()); // { hits: 1, misses: 2, size: 0 }\n * ```\n */\nexport function cachedFunction<Args extends unknown[], T>(\n fn: (...args: Args) => T | Promise<T>,\n options: CachedFunctionOptions<Args> = {}\n): MemoizedFunction<Args, T> {\n const {\n keyFn = (...args: Args) => JSON.stringify(args),\n maxSize = Infinity,\n } = options;\n const ttlMs = options.ttl ? toMs(options.ttl) : undefined;\n\n const cache = new Map<string, MemoEntry<T>>();\n const pending = new Map<string, Promise<T>>();\n let hits = 0;\n let misses = 0;\n\n /**\n * Evict oldest entries if over max size.\n */\n function evictOldest(): void {\n if (cache.size <= maxSize) return;\n\n // Find oldest entry\n let oldestKey: string | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of cache.entries()) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n cache.delete(oldestKey);\n }\n }\n\n const memoized = async (...args: Args): Promise<T> => {\n const key = keyFn(...args);\n const now = Date.now();\n\n // Check cache\n const cached = cache.get(key);\n if (cached) {\n // Check if expired\n if (cached.expiresAt && now >= cached.expiresAt) {\n cache.delete(key);\n } else {\n hits++;\n return cached.value;\n }\n }\n\n // Check if already computing\n const pendingPromise = pending.get(key);\n if (pendingPromise) {\n return pendingPromise;\n }\n\n // Compute the value\n misses++;\n const promise = Promise.resolve(fn(...args)).then((value) => {\n const entry: MemoEntry<T> = {\n value,\n timestamp: Date.now(),\n expiresAt: ttlMs ? Date.now() + ttlMs : undefined,\n };\n cache.set(key, entry);\n pending.delete(key);\n evictOldest();\n return value;\n });\n\n pending.set(key, promise);\n\n try {\n return await promise;\n } catch (error) {\n pending.delete(key);\n throw error;\n }\n };\n\n memoized.clear = () => {\n cache.clear();\n pending.clear();\n };\n\n memoized.delete = (...args: Args) => {\n const key = keyFn(...args);\n return cache.delete(key);\n };\n\n memoized.has = (...args: Args) => {\n const key = keyFn(...args);\n const entry = cache.get(key);\n if (!entry) return false;\n if (entry.expiresAt && Date.now() >= entry.expiresAt) {\n cache.delete(key);\n return false;\n }\n return true;\n };\n\n memoized.getStats = () => ({\n hits,\n misses,\n size: cache.size,\n });\n\n return memoized;\n}\n\n// =============================================================================\n// once() - Execute exactly once\n// =============================================================================\n\n/**\n * State for a once-executed function.\n */\ntype OnceState<T> =\n | { status: \"idle\" }\n | { status: \"running\"; promise: Promise<T> }\n | { status: \"done\"; value: T }\n | { status: \"failed\"; error: unknown };\n\n/**\n * Once-executed function interface.\n */\nexport interface OnceFunction<T> {\n (): Promise<T>;\n /** Check if the function has been called */\n called: boolean;\n /** Check if execution completed successfully */\n completed: boolean;\n /** Check if execution failed */\n failed: boolean;\n /** Reset to allow re-execution */\n reset(): void;\n}\n\n/**\n * Create a function that executes exactly once.\n *\n * Useful for initialization code that should only run once.\n * Subsequent calls return the same result or re-throw the same error.\n *\n * @param fn - Function to execute once\n * @returns Function that executes once and returns the result\n *\n * @example\n * ```typescript\n * const initDb = once(async () => {\n * console.log('Connecting to database...');\n * const conn = await createConnection();\n * return conn;\n * });\n *\n * // First call executes\n * const db1 = await initDb(); // \"Connecting to database...\"\n *\n * // Subsequent calls return cached result\n * const db2 = await initDb(); // Instant, same connection\n * const db3 = await initDb(); // Instant, same connection\n *\n * console.log(initDb.called); // true\n * console.log(initDb.completed); // true\n * ```\n */\nexport function once<T>(fn: () => T | Promise<T>): OnceFunction<T> {\n let state: OnceState<T> = { status: \"idle\" };\n\n const onceFn = async (): Promise<T> => {\n if (state.status === \"done\") {\n return state.value;\n }\n\n if (state.status === \"failed\") {\n throw state.error;\n }\n\n if (state.status === \"running\") {\n return state.promise;\n }\n\n // Execute the function\n const promise = Promise.resolve(fn())\n .then((value) => {\n state = { status: \"done\", value };\n return value;\n })\n .catch((error) => {\n state = { status: \"failed\", error };\n throw error;\n });\n\n state = { status: \"running\", promise };\n return promise;\n };\n\n Object.defineProperty(onceFn, \"called\", {\n get: () => state.status !== \"idle\",\n });\n\n Object.defineProperty(onceFn, \"completed\", {\n get: () => state.status === \"done\",\n });\n\n Object.defineProperty(onceFn, \"failed\", {\n get: () => state.status === \"failed\",\n });\n\n onceFn.reset = () => {\n state = { status: \"idle\" };\n };\n\n return onceFn as OnceFunction<T>;\n}\n\n// =============================================================================\n// createCache() - General purpose cache\n// =============================================================================\n\n/**\n * General purpose cache interface.\n */\nexport interface Cache<K, V> {\n /** Get a value from the cache */\n get(key: K): V | undefined;\n /** Set a value in the cache */\n set(key: K, value: V, options?: { ttl?: DurationInput }): void;\n /** Check if a key exists */\n has(key: K): boolean;\n /** Delete a key from the cache */\n delete(key: K): boolean;\n /** Clear the entire cache */\n clear(): void;\n /** Get the cache size */\n size: number;\n /** Get cache statistics */\n getStats(): CacheStats;\n}\n\n/**\n * Cache configuration.\n */\nexport interface CacheConfig {\n /**\n * Default TTL for all entries.\n */\n defaultTTL?: DurationInput;\n\n /**\n * Maximum cache size.\n * @default Infinity\n */\n maxSize?: number;\n}\n\n/**\n * Create a general-purpose cache with TTL and size limits.\n *\n * @param config - Cache configuration\n * @returns A Cache instance\n *\n * @example\n * ```typescript\n * const cache = createCache<string, User>({\n * defaultTTL: '5m',\n * maxSize: 1000,\n * });\n *\n * cache.set('user:1', user);\n * cache.set('user:2', user2, { ttl: '1h' }); // Override TTL\n *\n * const user = cache.get('user:1');\n * ```\n */\nexport function createCache<K, V>(config: CacheConfig = {}): Cache<K, V> {\n const { maxSize = Infinity } = config;\n const defaultTTLMs = config.defaultTTL ? toMs(config.defaultTTL) : undefined;\n\n interface Entry {\n value: V;\n timestamp: number;\n expiresAt?: number;\n }\n\n const store = new Map<K, Entry>();\n let hits = 0;\n let misses = 0;\n\n /**\n * Check if an entry is expired.\n */\n function isExpired(entry: Entry): boolean {\n return entry.expiresAt !== undefined && Date.now() >= entry.expiresAt;\n }\n\n /**\n * Evict oldest entries if over max size.\n */\n function evictOldest(): void {\n if (store.size <= maxSize) return;\n\n let oldestKey: K | null = null;\n let oldestTime = Infinity;\n\n for (const [key, entry] of store.entries()) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey !== null) {\n store.delete(oldestKey);\n }\n }\n\n return {\n get(key: K): V | undefined {\n const entry = store.get(key);\n if (!entry) {\n misses++;\n return undefined;\n }\n if (isExpired(entry)) {\n store.delete(key);\n misses++;\n return undefined;\n }\n hits++;\n return entry.value;\n },\n\n set(key: K, value: V, options?: { ttl?: DurationInput }): void {\n const ttlMs = options?.ttl ? toMs(options.ttl) : defaultTTLMs;\n const now = Date.now();\n\n store.set(key, {\n value,\n timestamp: now,\n expiresAt: ttlMs ? now + ttlMs : undefined,\n });\n\n evictOldest();\n },\n\n has(key: K): boolean {\n const entry = store.get(key);\n if (!entry) return false;\n if (isExpired(entry)) {\n store.delete(key);\n return false;\n }\n return true;\n },\n\n delete(key: K): boolean {\n return store.delete(key);\n },\n\n clear(): void {\n store.clear();\n },\n\n get size(): number {\n return store.size;\n },\n\n getStats(): CacheStats {\n return { hits, misses, size: store.size };\n },\n };\n}\n"],"mappings":"AAgCO,SAASA,EAAOC,EAAsB,CAC3C,MAAO,CAAE,KAAM,WAAY,OAAQA,CAAG,CACxC,CAUO,SAASC,EAAQC,EAAqB,CAC3C,MAAO,CAAE,KAAM,WAAY,OAAQA,EAAI,GAAK,CAC9C,CAUO,SAASC,EAAQC,EAAqB,CAC3C,MAAO,CAAE,KAAM,WAAY,OAAQA,EAAI,GAAK,GAAK,CACnD,CAUO,SAASC,EAAMC,EAAqB,CACzC,MAAO,CAAE,KAAM,WAAY,OAAQA,EAAI,GAAK,GAAK,GAAK,CACxD,CAUO,SAASC,EAAKC,EAAqB,CACxC,MAAO,CAAE,KAAM,WAAY,OAAQA,EAAI,GAAK,GAAK,GAAK,GAAK,CAC7D,CAiQO,SAASC,EAAMC,EAAqC,CACzD,IAAMC,EAAQD,EAAM,KAAK,EAAE,MAAM,mCAAmC,EACpE,GAAI,CAACC,EAAO,OAEZ,IAAMC,EAAQ,WAAWD,EAAM,CAAC,CAAC,EAGjC,OAFaA,EAAM,CAAC,EAAE,YAAY,EAEpB,CACZ,IAAK,KACH,OAAOE,EAAOD,CAAK,EACrB,IAAK,IACH,OAAOE,EAAQF,CAAK,EACtB,IAAK,IACH,OAAOG,EAAQH,CAAK,EACtB,IAAK,IACH,OAAOI,EAAMJ,CAAK,EACpB,IAAK,IACH,OAAOK,EAAKL,CAAK,EACnB,QACE,MACJ,CACF,CC3QA,SAASM,EAAKC,EAAiC,CAC7C,GAAI,OAAOA,GAAa,SAAU,CAChC,IAAMC,EAASC,EAAcF,CAAQ,EACrC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,4BAA4BD,CAAQ,EAAE,EAExD,OAAOC,EAAO,MAChB,CACA,OAAOD,EAAS,MAClB,CAsCO,SAASG,EAAUC,EAA4C,CACpE,IAAIC,EAAwB,CAAE,OAAQ,OAAQ,EAE9C,MAAO,UAAY,CACjB,GAAIA,EAAM,SAAW,SACnB,OAAOA,EAAM,MAGf,GAAIA,EAAM,SAAW,UACnB,OAAOA,EAAM,QAIf,IAAMC,EAAU,QAAQ,QAAQF,EAAG,CAAC,EAAE,KAAMG,IAC1CF,EAAQ,CAAE,OAAQ,SAAU,MAAAE,CAAM,EAC3BA,EACR,EAED,OAAAF,EAAQ,CAAE,OAAQ,UAAW,QAAAC,CAAQ,EAC9BA,CACT,CACF,CAsCO,SAASE,EACdJ,EACAK,EACkB,CAClB,IAAMC,EAAQX,EAAKU,EAAQ,GAAG,EAC1BJ,EAA2B,CAAE,OAAQ,OAAQ,EAEjD,MAAO,UAAY,CACjB,IAAMM,EAAM,KAAK,IAAI,EAGrB,GAAIN,EAAM,SAAW,UAAYM,EAAMN,EAAM,UAC3C,OAAOA,EAAM,MAIf,GAAIA,EAAM,SAAW,UACnB,OAAOA,EAAM,QAIf,IAAMC,EAAU,QAAQ,QAAQF,EAAG,CAAC,EAAE,KAAMG,IAC1CF,EAAQ,CACN,OAAQ,SACR,MAAAE,EACA,UAAW,KAAK,IAAI,EAAIG,CAC1B,EACOH,EACR,EAED,OAAAF,EAAQ,CAAE,OAAQ,UAAW,QAAAC,CAAQ,EAC9BA,CACT,CACF,CAyDO,SAASM,EACdR,EACAK,EAAuC,CAAC,EACb,CAC3B,GAAM,CACJ,MAAAI,EAAQ,IAAIC,IAAe,KAAK,UAAUA,CAAI,EAC9C,QAAAC,EAAU,GACZ,EAAIN,EACEC,EAAQD,EAAQ,IAAMV,EAAKU,EAAQ,GAAG,EAAI,OAE1CO,EAAQ,IAAI,IACZC,EAAU,IAAI,IAChBC,EAAO,EACPC,EAAS,EAKb,SAASC,GAAoB,CAC3B,GAAIJ,EAAM,MAAQD,EAAS,OAG3B,IAAIM,EAA2B,KAC3BC,EAAa,IAEjB,OAAW,CAACC,EAAKC,CAAK,IAAKR,EAAM,QAAQ,EACnCQ,EAAM,UAAYF,IACpBA,EAAaE,EAAM,UACnBH,EAAYE,GAIZF,GACFL,EAAM,OAAOK,CAAS,CAE1B,CAEA,IAAMI,EAAW,SAAUX,IAA2B,CACpD,IAAMS,EAAMV,EAAM,GAAGC,CAAI,EACnBH,EAAM,KAAK,IAAI,EAGfR,EAASa,EAAM,IAAIO,CAAG,EAC5B,GAAIpB,EAEF,GAAIA,EAAO,WAAaQ,GAAOR,EAAO,UACpCa,EAAM,OAAOO,CAAG,MAEhB,QAAAL,IACOf,EAAO,MAKlB,IAAMuB,EAAiBT,EAAQ,IAAIM,CAAG,EACtC,GAAIG,EACF,OAAOA,EAITP,IACA,IAAMb,EAAU,QAAQ,QAAQF,EAAG,GAAGU,CAAI,CAAC,EAAE,KAAMP,GAAU,CAC3D,IAAMiB,EAAsB,CAC1B,MAAAjB,EACA,UAAW,KAAK,IAAI,EACpB,UAAWG,EAAQ,KAAK,IAAI,EAAIA,EAAQ,MAC1C,EACA,OAAAM,EAAM,IAAIO,EAAKC,CAAK,EACpBP,EAAQ,OAAOM,CAAG,EAClBH,EAAY,EACLb,CACT,CAAC,EAEDU,EAAQ,IAAIM,EAAKjB,CAAO,EAExB,GAAI,CACF,OAAO,MAAMA,CACf,OAASqB,EAAO,CACd,MAAAV,EAAQ,OAAOM,CAAG,EACZI,CACR,CACF,EAEA,OAAAF,EAAS,MAAQ,IAAM,CACrBT,EAAM,MAAM,EACZC,EAAQ,MAAM,CAChB,EAEAQ,EAAS,OAAS,IAAIX,IAAe,CACnC,IAAMS,EAAMV,EAAM,GAAGC,CAAI,EACzB,OAAOE,EAAM,OAAOO,CAAG,CACzB,EAEAE,EAAS,IAAM,IAAIX,IAAe,CAChC,IAAMS,EAAMV,EAAM,GAAGC,CAAI,EACnBU,EAAQR,EAAM,IAAIO,CAAG,EAC3B,OAAKC,EACDA,EAAM,WAAa,KAAK,IAAI,GAAKA,EAAM,WACzCR,EAAM,OAAOO,CAAG,EACT,IAEF,GALY,EAMrB,EAEAE,EAAS,SAAW,KAAO,CACzB,KAAAP,EACA,OAAAC,EACA,KAAMH,EAAM,IACd,GAEOS,CACT,CA0DO,SAASG,EAAQxB,EAA2C,CACjE,IAAIC,EAAsB,CAAE,OAAQ,MAAO,EAErCwB,EAAS,SAAwB,CACrC,GAAIxB,EAAM,SAAW,OACnB,OAAOA,EAAM,MAGf,GAAIA,EAAM,SAAW,SACnB,MAAMA,EAAM,MAGd,GAAIA,EAAM,SAAW,UACnB,OAAOA,EAAM,QAIf,IAAMC,EAAU,QAAQ,QAAQF,EAAG,CAAC,EACjC,KAAMG,IACLF,EAAQ,CAAE,OAAQ,OAAQ,MAAAE,CAAM,EACzBA,EACR,EACA,MAAOoB,GAAU,CAChB,MAAAtB,EAAQ,CAAE,OAAQ,SAAU,MAAAsB,CAAM,EAC5BA,CACR,CAAC,EAEH,OAAAtB,EAAQ,CAAE,OAAQ,UAAW,QAAAC,CAAQ,EAC9BA,CACT,EAEA,cAAO,eAAeuB,EAAQ,SAAU,CACtC,IAAK,IAAMxB,EAAM,SAAW,MAC9B,CAAC,EAED,OAAO,eAAewB,EAAQ,YAAa,CACzC,IAAK,IAAMxB,EAAM,SAAW,MAC9B,CAAC,EAED,OAAO,eAAewB,EAAQ,SAAU,CACtC,IAAK,IAAMxB,EAAM,SAAW,QAC9B,CAAC,EAEDwB,EAAO,MAAQ,IAAM,CACnBxB,EAAQ,CAAE,OAAQ,MAAO,CAC3B,EAEOwB,CACT,CA6DO,SAASC,EAAkBC,EAAsB,CAAC,EAAgB,CACvE,GAAM,CAAE,QAAAhB,EAAU,GAAS,EAAIgB,EACzBC,EAAeD,EAAO,WAAahC,EAAKgC,EAAO,UAAU,EAAI,OAQ7DE,EAAQ,IAAI,IACdf,EAAO,EACPC,EAAS,EAKb,SAASe,EAAUV,EAAuB,CACxC,OAAOA,EAAM,YAAc,QAAa,KAAK,IAAI,GAAKA,EAAM,SAC9D,CAKA,SAASJ,GAAoB,CAC3B,GAAIa,EAAM,MAAQlB,EAAS,OAE3B,IAAIM,EAAsB,KACtBC,EAAa,IAEjB,OAAW,CAACC,EAAKC,CAAK,IAAKS,EAAM,QAAQ,EACnCT,EAAM,UAAYF,IACpBA,EAAaE,EAAM,UACnBH,EAAYE,GAIZF,IAAc,MAChBY,EAAM,OAAOZ,CAAS,CAE1B,CAEA,MAAO,CACL,IAAIE,EAAuB,CACzB,IAAMC,EAAQS,EAAM,IAAIV,CAAG,EAC3B,GAAI,CAACC,EAAO,CACVL,IACA,MACF,CACA,GAAIe,EAAUV,CAAK,EAAG,CACpBS,EAAM,OAAOV,CAAG,EAChBJ,IACA,MACF,CACA,OAAAD,IACOM,EAAM,KACf,EAEA,IAAID,EAAQhB,EAAUE,EAAyC,CAC7D,IAAMC,EAAQD,GAAS,IAAMV,EAAKU,EAAQ,GAAG,EAAIuB,EAC3CrB,EAAM,KAAK,IAAI,EAErBsB,EAAM,IAAIV,EAAK,CACb,MAAAhB,EACA,UAAWI,EACX,UAAWD,EAAQC,EAAMD,EAAQ,MACnC,CAAC,EAEDU,EAAY,CACd,EAEA,IAAIG,EAAiB,CACnB,IAAMC,EAAQS,EAAM,IAAIV,CAAG,EAC3B,OAAKC,EACDU,EAAUV,CAAK,GACjBS,EAAM,OAAOV,CAAG,EACT,IAEF,GALY,EAMrB,EAEA,OAAOA,EAAiB,CACtB,OAAOU,EAAM,OAAOV,CAAG,CACzB,EAEA,OAAc,CACZU,EAAM,MAAM,CACd,EAEA,IAAI,MAAe,CACjB,OAAOA,EAAM,IACf,EAEA,UAAuB,CACrB,MAAO,CAAE,KAAAf,EAAM,OAAAC,EAAQ,KAAMc,EAAM,IAAK,CAC1C,CACF,CACF","names":["millis","ms","seconds","s","minutes","m","hours","h","days","d","parse","input","match","value","millis","seconds","minutes","hours","days","toMs","duration","parsed","parse","cached","fn","state","promise","value","cachedWithTTL","options","ttlMs","now","cachedFunction","keyFn","args","maxSize","cache","pending","hits","misses","evictOldest","oldestKey","oldestTime","key","entry","memoized","pendingPromise","error","once","onceFn","createCache","config","defaultTTLMs","store","isExpired"]}
|
package/dist/circuit-breaker.cjs
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
"use strict";var me=Object.defineProperty;var Le=Object.getOwnPropertyDescriptor;var Ve=Object.getOwnPropertyNames;var He=Object.prototype.hasOwnProperty;var $e=(r,e)=>{for(var E in e)me(r,E,{get:e[E],enumerable:!0})},We=(r,e,E,w)=>{if(e&&typeof e=="object"||typeof e=="function")for(let R of Ve(e))!He.call(r,R)&&R!==E&&me(r,R,{get:()=>e[R],enumerable:!(w=Le(e,R))||w.enumerable});return r};var qe=r=>We(me({},"__esModule",{value:!0}),r);var ur={};$e(ur,{CircuitOpenError:()=>ne,circuitBreakerPresets:()=>Ke,createCircuitBreaker:()=>Ne,isCircuitOpenError:()=>Ue});module.exports=qe(ur);var Ye={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function Te(r){return`https://jagreehal.github.io/awaitly/rules/#${r}`}var Er=Object.keys(Ye);var se=class extends Error{_tag};function L(r,e){return class extends se{_tag=r;constructor(E,w){let R=e?.message?e.message(E??{}):r;if(super(R),this.name=r,e?.slug!==void 0){if(!e.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${e.slug}")`);Object.defineProperty(this,"code",{value:e.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:e.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:Te(e.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),E&&typeof E=="object"){let c;if(e?.slug!==void 0){let{_tag:F,name:A,message:D,stack:s,code:N,hint:B,docsUrl:U,...j}=E;c=j}else{let{_tag:F,name:A,message:D,stack:s,...N}=E;c=N}let T=Object.prototype.hasOwnProperty.call(c,"cause"),P=T?c.cause:void 0;T&&delete c.cause;let v=w?.cause!==void 0;if(T&&v)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,c),T&&(this.cause=P),v&&(this.cause=w?.cause)}else w?.cause!==void 0&&(this.cause=w.cause)}}}Object.defineProperty(L,Symbol.hasInstance,{value:r=>r instanceof se});(R=>{function r(c){return c instanceof Error}R.isError=r;function e(c){return c instanceof se}R.isTaggedError=e;function E(c,T){let P=c._tag,v=T[P];return v(c)}R.match=E;function w(c,T,P){let v=c._tag,F=T[v];return F?F(c):P(c)}R.matchPartial=w})(L||={});var ke=class extends L("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:e=>e.operation?`TimeoutError: ${e.operation} timed out after ${e.ms}ms`:`TimeoutError: Operation timed out after ${e.ms}ms`}){},Re=class extends L("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:e=>e.operation?`RetryExhaustedError: ${e.operation} failed after ${e.attempts} attempts`:`RetryExhaustedError: Operation failed after ${e.attempts} attempts`}){},ge=class extends L("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:e=>e.limiterName?`RateLimitError: Rate limit exceeded for ${e.limiterName}${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`}){},xe=class extends L("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:e=>`CircuitBreakerOpenError: Circuit ${e.circuitName} is ${e.state??"OPEN"}${e.retryAfterMs?`, retry after ${Math.ceil(e.retryAfterMs/1e3)}s`:""}`}){},Ce=class extends L("ValidationError",{message:e=>`ValidationError: Invalid ${e.field} - ${e.reason}`}){},he=class extends L("NotFoundError",{message:e=>e.id?`NotFoundError: ${e.resource} with id ${e.id} not found`:`NotFoundError: ${e.resource} not found`}){},be=class extends L("UnauthorizedError",{message:e=>e.reason?`UnauthorizedError: ${e.reason}`:e.action&&e.resource?`UnauthorizedError: Not authorized to ${e.action} ${e.resource}`:"UnauthorizedError: Access denied"}){},Ae=class extends L("NetworkError",{message:e=>e.url?`NetworkError: ${e.reason} (${e.url})`:`NetworkError: ${e.reason}`}){},Se=class extends L("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:e=>`CompensationError: Failed to compensate step ${e.step}`}){},ue=class extends L("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:e=>`UnexpectedError: ${e.cause instanceof Error?e.cause.message:String(e.cause??"unknown")}`}){};function Pe(r){return{ok:!0,value:r}}var ze=r=>typeof r=="object"&&r!==null&&"ok"in r&&typeof r.ok=="boolean"&&(r.ok?"value"in r:"error"in r),Oe=(r,e)=>{let E={},w=new Map;for(let R of Object.keys(r)){let c=r[R];typeof c=="function"&&(E[R]=(...T)=>{let P=(w.get(R)??0)+1;w.set(R,P);let v=P===1?R:`${R}#${P}`;return e(v,async()=>{let F=await c(...T);return ze(F)?F:Pe(F)})})}return E};function Je(r){let e=r.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!e)return;let E=parseFloat(e[1]),w=e[2].toLowerCase();return{_tag:"Duration",millis:E*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[w]??1)}}function Ge(r){return new ue({cause:r})}function W(r){return{ok:!0,value:r}}function K(r,e){let E=e?.cause;return{ok:!1,error:r,...E!==void 0?{cause:E}:{}}}function Xe(r){if(r==null)return"unknown";if(typeof r=="string")return r.trim()||"unknown";if(typeof r=="object"){let e=r;if(typeof e._tag=="string"){let E=e._tag.trim();if(E)return E}if(typeof e.tag=="string"){let E=e.tag.trim();if(E)return E}if(typeof e.code=="string"){let E=e.code.trim();if(E)return E}else if(typeof e.code=="number")return String(e.code);if(r instanceof Error&&r.name){let E=r.name.trim();if(E)return E}}return"unknown"}function Ze(r,e){if(!(!e||!r))return e[r]}function Qe(r){let{intent:e,domain:E,owner:w,tags:R,stateChanges:c,emits:T,calls:P}=r;if(!e&&!E&&!w&&!R?.length&&!c?.length&&!T?.length&&!P?.length)return;let v={};return e&&(v.intent=e),E&&(v.domain=E),w&&(v.owner=w),R?.length&&(v.tags=R),c?.length&&(v.stateChanges=c),T?.length&&(v.emits=T),P?.length&&(v.calls=P),v}function H(r,e,E,w,R){let c=Xe(r),T=Ze(c,e),P={tag:c,origin:E};return T!==void 0&&(P.classification=T),w!==void 0&&(P.attempt=w),R!==void 0&&(P.cumulativeDurationMs=R),P}var te=Symbol.for("step_timeout_marker");function ve(r){return typeof r!="object"||r===null?!1:r.type==="STEP_TIMEOUT"?!0:te in r}function er(r){if(!(typeof r!="object"||r===null)){if(r.type==="STEP_TIMEOUT"){let e=r;return{timeoutMs:e.timeoutMs,stepName:e.stepName,stepKey:e.stepKey,attempt:e.attempt}}if(te in r)return r[te]}}var Ie=Symbol("early-exit");function rr(r,e){return{[Ie]:!0,error:r,meta:e}}function tr(r){return typeof r=="object"&&r!==null&&r[Ie]===!0}var De=Symbol("mapper-exception");function ee(r){return{[De]:!0,thrown:r}}function nr(r){return typeof r=="object"&&r!==null&&r[De]===!0}function fe(r,e){let{backoff:E,initialDelay:w,maxDelay:R,jitter:c}=e,T;switch(E){case"fixed":T=w;break;case"linear":T=w*r;break;case"exponential":T=w*Math.pow(2,r-1);break}if(T=Math.min(T,R),c){let P=T*.25*Math.random();T=T+P}return Math.floor(T)}function we(r){return new Promise(e=>setTimeout(e,r))}var _e=Symbol("timeout"),ie=Symbol("timeout-option");function or(r){return typeof r=="object"&&r!==null&&r[ie]===!0}async function sr(r,e,E,w){let R=new AbortController,c=e.onTimeout??"error",T=()=>typeof c=="function"?c({name:E.name,key:E.key,ms:e.ms}):e.error??{type:"STEP_TIMEOUT",stepName:E.name,stepKey:E.key,timeoutMs:e.ms,attempt:E.attempt},P;w?.aborted&&R.abort(w.reason);let v;w&&!w.aborted&&(v=()=>R.abort(w.reason),w.addEventListener("abort",v,{once:!0}));let F=new Promise((D,s)=>{P=setTimeout(()=>{if(c!=="disconnect"&&R.abort(),c==="option"){s({[ie]:!0,ms:e.ms});return}s({[_e]:!0,error:T()})},e.ms)}),A;e.signal?A=Promise.resolve(r(R.signal)):A=Promise.resolve(r());try{return await Promise.race([A,F])}catch(D){if(typeof D=="object"&&D!==null&&D[ie]===!0)throw{[ie]:!0,ms:e.ms};if(typeof D=="object"&&D!==null&&D[_e]===!0){c==="disconnect"&&A.catch(()=>{});let s=D.error;if(typeof s=="object"&&s!==null&&s.type!=="STEP_TIMEOUT"){let N={timeoutMs:e.ms,stepName:E.name,stepKey:E.key,attempt:E.attempt};te in s?s[te]=N:Object.defineProperty(s,te,{value:N,enumerable:!1,writable:!0,configurable:!1})}throw s}throw D}finally{clearTimeout(P),v&&w&&w.removeEventListener("abort",v)}}var re={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function ye(r,e,E){if(typeof r!="function"){let p=r,V=e;if(typeof V!="function")throw new TypeError("[awaitly] run(deps, fn) requires a callback as the second argument. Example: run({ getUser }, async (s) => s.getUser(id))");return ye(({step:Z})=>V(Oe(p,Z),{step:Z}),E)}let w=r,R=e,{onError:c,onEvent:T,catchUnexpected:P,workflowId:v,workflowName:F,context:A,_workflowSignal:D}=R&&typeof R=="object"?R:{},s=v??crypto.randomUUID(),N=P??Ge,B=[],U=0,j=p=>p??`step_${++U}`,u=p=>{let V=p.context!==void 0||A===void 0?p:{...p,context:A},q=F!==void 0&&V.workflowName===void 0?{...V,workflowName:F}:V;if(q.type==="step_success"){let Z=q.stepId;for(let ae=B.length-1;ae>=0;ae--){let $=B[ae];if($.type==="race"&&!$.winnerId){$.winnerId=Z;break}}}T?.(q,A)},_=rr,X=p=>tr(p),z=(p,V)=>p,Fe=p=>typeof p=="function"?!1:!!(p&&typeof p=="object"&&"ok"in p||p&&typeof p=="object"&&"then"in p&&typeof p.then=="function");try{let V=function(a){let d={};for(let[n,o]of Object.entries(a))if(typeof o=="function")d[n]=o;else if(o&&typeof o=="object"&&"fn"in o)d[n]=o.fn;else throw new TypeError(`step.all: operation "${n}" must be a function or { fn, errors? } object`);return d},q=function(a,d){let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),t=!1;B.push({scopeId:n,type:"parallel"});let i=()=>{if(t)return;t=!0;let l=B.findIndex(m=>m.scopeId===n);l!==-1&&B.splice(l,1),u({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o})};u({type:"scope_start",workflowId:s,scopeId:n,scopeType:"parallel",name:a,ts:Date.now()});try{let l=await d();if(i(),!l.ok)throw c?.(l.error,a,A),_(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw i(),l}})()},Z=function(a,d){let n=Object.keys(a),o=d.name??`Parallel(${n.join(", ")})`,t=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let i=performance.now(),l=!1;B.push({scopeId:t,type:"parallel"});let m=()=>{if(l)return;l=!0;let f=B.findIndex(y=>y.scopeId===t);f!==-1&&B.splice(f,1),u({type:"scope_end",workflowId:s,scopeId:t,ts:Date.now(),durationMs:performance.now()-i})};u({type:"scope_start",workflowId:s,scopeId:t,scopeType:"parallel",name:o,ts:Date.now()});try{let f=await new Promise(g=>{if(n.length===0){g([]);return}let S=!1,I=n.length,x=new Array(n.length);for(let M=0;M<n.length;M++){let C=n[M],b=M;Promise.resolve(a[C]()).catch(h=>K({type:"PROMISE_REJECTED",cause:h},{cause:{type:"PROMISE_REJECTION",reason:h}})).then(h=>{if(!S){if(!h.ok){S=!0,g([{key:C,result:h}]);return}x[b]={key:C,result:h},I--,I===0&&g(x)}})}});m();let y={};for(let{key:g,result:S}of f){if(!S.ok)throw c?.(S.error,g,A),_(S.error,{origin:"result",resultCause:S.cause});y[g]=S.value}return y}catch(f){throw m(),f}})()};var ir=V,cr=q,lr=Z;let p=(a,d,n)=>(async()=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let o=n??{},t=Qe(o),i=a,l=o.key??a,m=o.key??a,{description:f,retry:y,timeout:g}=o,S=j(l),I=T,x=I?performance.now():0,C=Fe(d)?()=>d:d,h={attempts:Math.max(1,y?.attempts??1),backoff:y?.backoff??re.backoff,initialDelay:y?.initialDelay??re.initialDelay,maxDelay:y?.maxDelay??re.maxDelay,jitter:y?.jitter??re.jitter,shouldRetry:y?.shouldRetry??re.shouldRetry,onRetry:y?.onRetry??re.onRetry};T&&u({type:"step_start",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),...t&&{metadata:t}});let Q;for(let O=1;O<=h.attempts;O++){let je=I?performance.now():0;try{let k;if(g?k=await sr(C,g,{name:i,key:l,attempt:O},D):k=await C(),k.ok){let G=performance.now()-x;return u({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:G,...t&&{metadata:t}}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:f,ts:Date.now(),durationMs:G,result:k,...t&&{metadata:t}}),k.value}if(Q=k,O<h.attempts&&h.shouldRetry(k.error,O)){let G=fe(O,h);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:O+1,maxAttempts:h.attempts,delayMs:G,error:k.error,...t&&{metadata:t},diagnostics:H(k.error,o.errorMeta,"result",O,performance.now()-x)}),h.onRetry(k.error,O,G),await we(G);continue}h.attempts>1&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:k.error,...t&&{metadata:t},diagnostics:H(k.error,o.errorMeta,"result",O,performance.now()-x)});break}catch(k){let G=performance.now()-je;if(or(k)){let Y=k.ms;u({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),timeoutMs:Y,attempt:O,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"timeout",O)}),u({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:performance.now()-x,...t&&{metadata:t}}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:f,ts:Date.now(),durationMs:performance.now()-x,result:W(void 0),...t&&{metadata:t}});return}if(X(k))throw u({type:"step_aborted",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:G,...t&&{metadata:t}}),k;if(ve(k)){let Y=er(k),Be=g?.ms??Y?.timeoutMs??0;if(u({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),timeoutMs:Be,attempt:O,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"timeout",O)}),O<h.attempts&&h.shouldRetry(k,O)){let de=fe(O,h);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:O+1,maxAttempts:h.attempts,delayMs:de,error:k,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"timeout",O,performance.now()-x)}),h.onRetry(k,O,de),await we(de);continue}h.attempts>1&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:k,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"timeout",O,performance.now()-x)});let Ee=performance.now()-x;throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:Ee,error:k,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"timeout",O,Ee)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:f,ts:Date.now(),durationMs:Ee,result:K(k,{cause:k}),meta:{origin:"throw",thrown:k},...t&&{metadata:t}}),c?.(k,i,A),_(k,{origin:"throw",thrown:k})}if(O<h.attempts&&h.shouldRetry(k,O)){let Y=fe(O,h);u({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),attempt:O+1,maxAttempts:h.attempts,delayMs:Y,error:k,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"throw",O,performance.now()-x)}),h.onRetry(k,O,Y),await we(Y);continue}h.attempts>1&&!ve(k)&&u({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-x,attempts:O,lastError:k,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"throw",O,performance.now()-x)});let pe=performance.now()-x,oe;try{oe=N(k)}catch(Y){throw ee(Y)}throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:pe,error:oe,...t&&{metadata:t},diagnostics:H(k,o.errorMeta,"throw",O,pe)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:f,ts:Date.now(),durationMs:pe,result:K(oe,{cause:k}),meta:{origin:"throw",thrown:k},...t&&{metadata:t}}),c?.(oe,i,A),_(oe,{origin:"throw",thrown:k})}}let J=Q,ce=performance.now()-x,le=z(J.error,{origin:"result",resultCause:J.cause});throw u({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:i,description:f,ts:Date.now(),durationMs:ce,error:le,...t&&{metadata:t},diagnostics:H(J.error,o.errorMeta,"result",h.attempts,ce)}),m&&u({type:"step_complete",workflowId:s,stepKey:m,name:i,description:f,ts:Date.now(),durationMs:ce,result:J,meta:{origin:"result",resultCause:J.cause},...t&&{metadata:t}}),c?.(le,i,A),_(le,{origin:"result",resultCause:J.cause})})();p.try=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.try() requires an explicit string ID as the first argument. Example: step.try("parse", () => JSON.parse(str), { error: "PARSE_ERROR" })');let o="error"in n?()=>n.error:n.onError;if(n.retry||n.timeout)return p.retry(a,async()=>{try{return W(await d())}catch(f){return K(o(f),{cause:f})}},{attempts:n.retry?.attempts??1,...n.retry??{},key:n.key,timeout:n.timeout});let t=n.key??a,i=a,l=a,m=T;return(async()=>{let f=m?performance.now():0;T&&u({type:"step_start",workflowId:s,stepId:l,stepKey:t,name:i,ts:Date.now()});try{let y=await d(),g=performance.now()-f;return u({type:"step_success",workflowId:s,stepId:l,stepKey:t,name:i,ts:Date.now(),durationMs:g}),t&&u({type:"step_complete",workflowId:s,stepKey:t,name:i,ts:Date.now(),durationMs:g,result:W(y)}),y}catch(y){let g=o(y),S=performance.now()-f,I=z(g,{origin:"throw",thrown:y});throw u({type:"step_error",workflowId:s,stepId:l,stepKey:t,name:i,ts:Date.now(),durationMs:S,error:I}),t&&u({type:"step_complete",workflowId:s,stepKey:t,name:i,ts:Date.now(),durationMs:S,result:K(g,{cause:y}),meta:{origin:"throw",thrown:y}}),c?.(I,i,A),_(I,{origin:"throw",thrown:y})}})()},p.fromResult=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.fromResult() requires an explicit string ID as the first argument. Example: step.fromResult("callProvider", () => callProvider(input), { onError: (e) => ({ type: "FAILED" }) })');let o=n.key??a,t=a,i=a,l="error"in n?()=>n.error:n.onError,m=T;return(async()=>{let f=m?performance.now():0;T&&u({type:"step_start",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now()});let y=await d();if(y.ok){let g=performance.now()-f;return u({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:g}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:g,result:W(y.value)}),y.value}else{let g=l(y.error),S=performance.now()-f,I=z(g,{origin:"result",resultCause:y.error});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:S,error:I}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:S,result:K(g,{cause:y.error}),meta:{origin:"result",resultCause:y.error}}),c?.(I,t,A),_(I,{origin:"result",resultCause:y.error})}})()},p.fromNullable=(a,d,n,o)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.fromNullable() requires an explicit string ID as the first argument. Example: step.fromNullable("getUser", () => db.find(id), () => ({ type: "NOT_FOUND" }))');return p(a,async()=>{let t=await d();return t!=null?W(t):K(n())},o)},p.retry=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.retry() requires an explicit string ID as the first argument. Example: step.retry("fetchData", () => fetchData(), { attempts: 3 })');return p(a,d,{key:n.key??a,retry:{attempts:n.attempts,backoff:n.backoff,initialDelay:n.initialDelay,maxDelay:n.maxDelay,jitter:n.jitter,shouldRetry:n.shouldRetry,onRetry:n.onRetry},timeout:n.timeout})},p.withTimeout=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withTimeout() requires an explicit string ID as the first argument. Example: step.withTimeout("slowOp", () => slowOp(), { ms: 5000 })');return p(a,d,{key:n.key??a,timeout:n})},p.sleep=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let o=typeof d=="string"?Je(d):d;if(!o)throw new Error(`step.sleep: invalid duration '${d}'`);let t=o.millis,i=n?.signal;return p(a,async()=>{if(D?.aborted||i?.aborted){let l=new Error("Sleep aborted");throw l.name="AbortError",l}return new Promise((l,m)=>{let f={timeoutId:void 0},y=()=>{f.timeoutId&&clearTimeout(f.timeoutId);let g=new Error("Sleep aborted");g.name="AbortError",m(g)};D?.addEventListener("abort",y,{once:!0}),i?.addEventListener("abort",y,{once:!0}),f.timeoutId=setTimeout(()=>{D?.removeEventListener("abort",y),i?.removeEventListener("abort",y),l(W(void 0))},t)})},{key:n?.key??a,description:n?.description})},p.all=((...a)=>{if(typeof a[0]!="string")throw new TypeError("step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let d=a[0],n=a[1];if(typeof n=="function")return q(d,n);if(n&&typeof n=="object"&&!Array.isArray(n)){let t=V(n);return Z(t,{name:d})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(a,d)=>{let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),t=!1,i={scopeId:n,type:"race",winnerId:void 0};B.push(i);let l=()=>{if(t)return;t=!0;let m=B.findIndex(f=>f.scopeId===n);m!==-1&&B.splice(m,1),u({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o,winnerId:i.winnerId})};u({type:"scope_start",workflowId:s,scopeId:n,scopeType:"race",name:a,ts:Date.now()});try{let m=await d();if(l(),!m.ok)throw c?.(m.error,a,A),_(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw l(),m}})()},p.if=(a,d,n)=>n(),p.label=p.if,p.branch=async(a,d)=>{let{condition:n,then:o,else:t}=d;if(n())return await o();if(t)return await t()},p.arm=(a,d)=>({fn:a,errors:d}),p.forEach=async(a,d,n)=>{let o=[],t=n.maxIterations,i=0,l="run"in n,m=Symbol.asyncIterator in d?d:(async function*(){yield*d})();for await(let f of m){if(t!==void 0&&i>=t)break;let y;l?y=await n.run(f,i):y=await n.item.handler(f,i,p),o.push(y),i++}return o},p.item=a=>({__forEachItemHandler:!0,handler:a}),p.dep=(a,d)=>d,p.workflow=(a,d,n)=>p(a,d,n),p.map=async(a,d,n,o)=>{let t=o?.concurrency??d.length;return p(a,()=>t>=d.length?Me(d.map((i,l)=>n(i,l))):(async()=>{let i=[];for(let l=0;l<d.length;l+=t){let m=d.slice(l,l+t),f=await Me(m.map((y,g)=>n(y,l+g)));if(!f.ok)return f;i.push(...f.value)}return W(i)})(),{key:o?.key})},p.withFallback=(a,d,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withFallback() requires an explicit string ID as the first argument. Example: step.withFallback("getUser", () => fetchUser(id), { fallback: () => fetchFromCache(id) })');let o=n.key??a,t=a,i=j(o),l=T;return(async()=>{let m=l?performance.now():0;T&&u({type:"step_start",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now()});let f;try{f=await d()}catch(x){if(X(x))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-m}),x;let M;try{M=N(x)}catch(b){throw ee(b)}if(n.on!==void 0&&n.on!==M){let b=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:b,error:M}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:b,result:K(M,{cause:x}),meta:{origin:"throw",thrown:x}}),c?.(M,t,A),_(M,{origin:"throw",thrown:x})}let C;try{C=await n.fallback()}catch(b){if(X(b))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-m}),b;let h;try{h=N(b)}catch(J){throw ee(J)}let Q=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:Q,error:h}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:Q,result:K(h,{cause:b}),meta:{origin:"throw",thrown:b}}),c?.(h,t,A),_(h,{origin:"throw",thrown:b})}if(C.ok){let b=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:b}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:b,result:C,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(M)}}),C.value}else{let b=performance.now()-m,h=z(C.error,{origin:"result",resultCause:C.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:b,error:h}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:b,result:C,meta:{origin:"result",resultCause:C.cause}}),c?.(h,t,A),_(h,{origin:"result",resultCause:C.cause})}}if(f.ok){let x=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:x}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:x,result:f}),f.value}let y=f.error;if(n.on!==void 0&&n.on!==y){let x=performance.now()-m,M=z(y,{origin:"result",resultCause:f.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:x,error:M}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:x,result:f,meta:{origin:"result",resultCause:f.cause}}),c?.(M,t,A),_(M,{origin:"result",resultCause:f.cause})}let g;try{g=await n.fallback()}catch(x){if(X(x))throw u({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-m}),x;let M;try{M=N(x)}catch(b){throw ee(b)}let C=performance.now()-m;throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:C,error:M}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:C,result:K(M,{cause:x}),meta:{origin:"throw",thrown:x}}),c?.(M,t,A),_(M,{origin:"throw",thrown:x})}if(g.ok){let x=performance.now()-m;return u({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:x}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:x,result:g,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(y)}}),g.value}let S=performance.now()-m,I=z(g.error,{origin:"result",resultCause:g.cause});throw u({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:t,ts:Date.now(),durationMs:S,error:I}),o&&u({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:S,result:g,meta:{origin:"result",resultCause:g.cause}}),c?.(I,t,A),_(I,{origin:"result",resultCause:g.cause})})()},p.withResource=(a,d)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.withResource() requires an explicit string ID as the first argument. Example: step.withResource("useDb", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })');let n=a,o=a,t=j(n),i=T;return(async()=>{let l=i?performance.now():0;T&&u({type:"step_start",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now()});let m;try{m=await d.acquire()}catch(C){if(X(C))throw u({type:"step_aborted",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:performance.now()-l}),C;let b;try{b=N(C)}catch(Q){throw ee(Q)}let h=performance.now()-l;throw u({type:"step_error",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:h,error:b}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:h,result:K(b,{cause:C}),meta:{origin:"throw",thrown:C}}),c?.(b,o,A),_(b,{origin:"throw",thrown:C})}if(!m.ok){let C=performance.now()-l,b=z(m.error,{origin:"result",resultCause:m.cause});throw u({type:"step_error",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:C,error:b}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:C,result:m,meta:{origin:"result",resultCause:m.cause}}),c?.(b,o,A),_(b,{origin:"result",resultCause:m.cause})}let f=m.value,y,g,S=!1;try{y=await d.use(f)}catch(C){if(X(C)){try{await d.release(f)}catch(b){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,b)}throw C}g=C,S=!0}try{await d.release(f)}catch(C){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,C)}if(S){let C;try{C=N(g)}catch(h){throw ee(h)}let b=performance.now()-l;throw u({type:"step_error",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:b,error:C}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:b,result:K(C,{cause:g}),meta:{origin:"throw",thrown:g}}),c?.(C,o,A),_(C,{origin:"throw",thrown:g})}let I=y;if(I.ok){let C=performance.now()-l;return u({type:"step_success",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:C}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:C,result:I}),I.value}let x=performance.now()-l,M=z(I.error,{origin:"result",resultCause:I.cause});throw u({type:"step_error",workflowId:s,stepId:t,stepKey:n,name:o,ts:Date.now(),durationMs:x,error:M}),n&&u({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:x,result:I,meta:{origin:"result",resultCause:I.cause}}),c?.(M,o,A),_(M,{origin:"result",resultCause:I.cause})})()};let $=await w({step:p});if(process.env.NODE_ENV!=="production"&&$!==null&&typeof $=="object"&&"ok"in $&&typeof $.ok=="boolean"){let a=$;(a.ok===!0&&"value"in a||a.ok===!1&&"error"in a)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
|
|
2
|
-
|
|
3
|
-
Incorrect: return ok({ data });
|
|
4
|
-
Correct: return { data };
|
|
5
|
-
|
|
6
|
-
See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return W($)}catch(p){if(nr(p))throw p.thrown;if(X(p)){let q=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return K(p.error,{cause:q})}let V=N(p);return c?.(V,"unexpected",A),K(V,{cause:p})}}ye.strict=(r,e)=>ye(r,e);async function Me(r){return r.length===0?W([]):new Promise(e=>{let E=!1,w=r.length,R=new Array(r.length);for(let c=0;c<r.length;c++){let T=c;Promise.resolve(r[T]).catch(P=>K({type:"PROMISE_REJECTED",cause:P},{cause:{type:"PROMISE_REJECTION",reason:P}})).then(P=>{if(!E){if(!P.ok){E=!0,e(P);return}R[T]=P.value,w--,w===0&&e(W(R))}})}})}var ne=class extends Error{type="CIRCUIT_OPEN";circuitName;state;retryAfterMs;constructor(e){super(e.message??`Circuit breaker "${e.circuitName}" is ${e.state}. Retry after ${Math.ceil(e.retryAfterMs/1e3)}s`),this.name="CircuitOpenError",this.circuitName=e.circuitName,this.state=e.state,this.retryAfterMs=e.retryAfterMs}};function Ue(r){return typeof r=="object"&&r!==null&&r.type==="CIRCUIT_OPEN"}var ar={failureThreshold:5,resetTimeout:3e4,windowSize:6e4,halfOpenMax:3};function Ne(r,e){let E={...ar,...e},w="CLOSED",R=[],c=null,T=null,P=0,v=0;function F(){let U=Date.now();R=R.filter(j=>U-j.timestamp<E.windowSize)}function A(U){if(w!==U){let j=w;w=U,U==="HALF_OPEN"&&(v=0),E.onStateChange?.(j,U,r)}}function D(){return w!=="OPEN"||c===null?!1:Date.now()-c>=E.resetTimeout?(A("HALF_OPEN"),!0):!1}function s(){T=Date.now(),P++,w==="HALF_OPEN"&&(v++,v>=E.halfOpenMax&&(A("CLOSED"),R=[]))}function N(U){let j=Date.now();c=j,F(),R.push({timestamp:j,error:U}),(w==="HALF_OPEN"||w==="CLOSED"&&R.length>=E.failureThreshold)&&A("OPEN")}function B(){if(w==="CLOSED")return 0;if(w==="OPEN"){if(D())return 0;let U=Date.now(),j=c?U-c:0;return Math.max(0,E.resetTimeout-j)}return 0}return{async execute(U,j){let u=B();if(u>0)throw new ne({circuitName:r,state:w,retryAfterMs:u});try{let _=await U();return s(),_}catch(_){throw N(_),_}},async executeResult(U,j){let u=B();if(u>0)return K(new ne({circuitName:r,state:w,retryAfterMs:u}));try{let _=await U();return _.ok?s():N(_.error),_}catch(_){throw N(_),_}},getState(){return w==="OPEN"&&D(),w},getStats(){return F(),{state:this.getState(),failureCount:R.length,successCount:P,lastFailureTime:c,lastSuccessTime:T,halfOpenSuccesses:v}},reset(){A("CLOSED"),R=[],v=0},forceOpen(){c=Date.now(),A("OPEN")},recordSuccess(){s()},recordFailure(U){N(U??new Error("Manual failure"))}}}var Ke={critical:{failureThreshold:3,resetTimeout:6e4,windowSize:3e4,halfOpenMax:1},standard:{failureThreshold:5,resetTimeout:3e4,windowSize:6e4,halfOpenMax:3},lenient:{failureThreshold:10,resetTimeout:15e3,windowSize:12e4,halfOpenMax:5}};0&&(module.exports={CircuitOpenError,circuitBreakerPresets,createCircuitBreaker,isCircuitOpenError});
|
|
7
|
-
//# sourceMappingURL=circuit-breaker.cjs.map
|