runtry 0.8.1 → 0.9.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 +66 -124
- package/dist/error/core.d.ts +12 -33
- package/dist/error/core.d.ts.map +1 -1
- package/dist/error/core.js +10 -34
- package/dist/error/core.js.map +1 -1
- package/dist/error/normalize.d.ts.map +1 -1
- package/dist/error/normalize.js +3 -0
- package/dist/error/normalize.js.map +1 -1
- package/dist/error/types.d.ts +1 -1
- package/dist/error/types.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/runner/run.d.ts.map +1 -1
- package/dist/runner/run.js +72 -12
- package/dist/runner/run.js.map +1 -1
- package/dist/runner/runAll.d.ts +16 -0
- package/dist/runner/runAll.d.ts.map +1 -1
- package/dist/runner/runAll.js +4 -0
- package/dist/runner/runAll.js.map +1 -1
- package/dist/runner/runAllOrThrow.d.ts +5 -0
- package/dist/runner/runAllOrThrow.d.ts.map +1 -1
- package/dist/runner/runAllOrThrow.js +2 -0
- package/dist/runner/runAllOrThrow.js.map +1 -1
- package/dist/runner/runner.d.ts +6 -0
- package/dist/runner/runner.d.ts.map +1 -1
- package/dist/runner/runner.js +74 -1
- package/dist/runner/runner.js.map +1 -1
- package/dist/types.d.ts +117 -41
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +26 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +3 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +36 -6
- package/dist/utils.js.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Run async functions and return a typed `Result` **instead of throwing**.
|
|
|
4
4
|
|
|
5
5
|
- ✅ No repetitive `try/catch` in UI code
|
|
6
6
|
- ✅ Typed success/error handling
|
|
7
|
-
- ✅ Pluggable error normalization (
|
|
7
|
+
- ✅ Pluggable error normalization (rules)
|
|
8
8
|
- ✅ **Automatic Retries** with backoff & jitter
|
|
9
9
|
- ✅ **Concurrency control** with `runAll`
|
|
10
10
|
|
|
@@ -35,176 +35,118 @@ const result = await run(async () => {
|
|
|
35
35
|
if (result.ok) {
|
|
36
36
|
console.log("data:", result.data);
|
|
37
37
|
} else {
|
|
38
|
-
console.
|
|
38
|
+
console.log("error:", result.error.code); // "UNKNOWN" | "ABORTED" | ...
|
|
39
39
|
}
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## `createRunner()` (Recommended)
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
Define your error rules once and reuse them. Types are inferred automatically!
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
import
|
|
49
|
+
import { createRunner, rules, errorRule } from "runtry";
|
|
50
|
+
import { ZodError } from "zod";
|
|
51
|
+
import { AxiosError } from "axios";
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
):
|
|
53
|
+
const runner = createRunner({
|
|
54
|
+
rules: [
|
|
55
|
+
// Core rules (optional)
|
|
56
|
+
rules.abort(), // code: "ABORTED"
|
|
57
|
+
rules.timeout(), // code: "TIMEOUT"
|
|
58
|
+
|
|
59
|
+
// Custom rules (type inferred!)
|
|
60
|
+
errorRule.instance(ZodError).toError((e) => ({
|
|
61
|
+
code: "VALIDATION_ERROR", // Literal type "VALIDATION_ERROR"
|
|
62
|
+
message: "Validation failed",
|
|
63
|
+
meta: { issues: e.issues },
|
|
64
|
+
})),
|
|
65
|
+
|
|
66
|
+
errorRule.instance(AxiosError).toError((e) => ({
|
|
67
|
+
code: "HTTP_ERROR",
|
|
68
|
+
message: e.message,
|
|
69
|
+
status: e.response?.status,
|
|
70
|
+
})),
|
|
71
|
+
],
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Now use it everywhere
|
|
75
|
+
const result = await runner.run(fetchUser);
|
|
76
|
+
|
|
77
|
+
if (!result.ok) {
|
|
78
|
+
// ⭐️ Strict typing based on your rules!
|
|
79
|
+
// error.code is "ABORTED" | "TIMEOUT" | "VALIDATION_ERROR" | "HTTP_ERROR" | "UNKNOWN"
|
|
80
|
+
|
|
81
|
+
if (result.error.code === "VALIDATION_ERROR") {
|
|
82
|
+
console.log(result.error.meta.issues); // Typed!
|
|
83
|
+
}
|
|
84
|
+
}
|
|
55
85
|
```
|
|
56
86
|
|
|
57
|
-
|
|
87
|
+
---
|
|
58
88
|
|
|
59
|
-
|
|
60
|
-
- `onError`: Callback for final failure.
|
|
61
|
-
- `onSuccess`: Callback for success.
|
|
62
|
-
- `onFinally`: Callback after completion (success or fail).
|
|
63
|
-
- `ignoreAbort`: Don't trigger onError for Abort/Cancellation (default: true).
|
|
89
|
+
## API
|
|
64
90
|
|
|
65
|
-
|
|
91
|
+
### `run(fn, options?)`
|
|
66
92
|
|
|
67
|
-
|
|
93
|
+
Executes a single async function.
|
|
68
94
|
|
|
69
95
|
```ts
|
|
70
|
-
await run(
|
|
96
|
+
await runner.run(fn, {
|
|
71
97
|
retries: 3,
|
|
72
|
-
retryDelay: (attempt
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
retryDelay: (attempt) => attempt * 1000,
|
|
99
|
+
onError: (err) => toast.error(err.message),
|
|
100
|
+
onSuccess: (data) => console.log(data),
|
|
75
101
|
});
|
|
76
102
|
```
|
|
77
103
|
|
|
78
|
-
---
|
|
79
|
-
|
|
80
104
|
### `runAll(tasks, options?)`
|
|
81
105
|
|
|
82
|
-
Executes multiple tasks with
|
|
106
|
+
Executes multiple tasks with concurrency control.
|
|
83
107
|
|
|
84
108
|
```ts
|
|
85
|
-
import { runAll } from "runtry";
|
|
86
|
-
|
|
87
109
|
const tasks = [
|
|
88
110
|
() => fetch("/api/1"),
|
|
89
111
|
() => fetch("/api/2"),
|
|
90
112
|
() => fetch("/api/3"),
|
|
91
113
|
];
|
|
92
114
|
|
|
93
|
-
// Run max 2 at a time
|
|
94
|
-
const results = await
|
|
115
|
+
// Run max 2 at a time, stop if any fails
|
|
116
|
+
const results = await runner.all(tasks, {
|
|
95
117
|
concurrency: 2,
|
|
96
|
-
|
|
97
|
-
retries: 2, // Inherits all run() options including retries!
|
|
98
|
-
});
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Normalizing errors (matchers)
|
|
104
|
-
|
|
105
|
-
`runtry` can normalize unknown thrown values (`unknown`) into a consistent `AppError` shape.
|
|
106
|
-
|
|
107
|
-
### 1) Create matchers (adapters)
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import {
|
|
111
|
-
createNormalizer,
|
|
112
|
-
abortMatcher,
|
|
113
|
-
matchInstance,
|
|
114
|
-
defaultFallback,
|
|
115
|
-
} from "runtry";
|
|
116
|
-
import type { AppError } from "runtry";
|
|
117
|
-
import { HttpError } from "./http-error"; // your app error class
|
|
118
|
-
|
|
119
|
-
type MyMeta = { url?: string; body?: unknown };
|
|
120
|
-
|
|
121
|
-
const httpMatcher = matchInstance(HttpError, (e) => ({
|
|
122
|
-
code: "HTTP",
|
|
123
|
-
message: e.message,
|
|
124
|
-
status: e.status,
|
|
125
|
-
meta: { url: e.url, body: e.body } as MyMeta,
|
|
126
|
-
cause: e,
|
|
127
|
-
}));
|
|
128
|
-
|
|
129
|
-
const toError = createNormalizer<AppError<MyMeta>>(
|
|
130
|
-
[abortMatcher, httpMatcher],
|
|
131
|
-
(e) => defaultFallback(e) as AppError<MyMeta>
|
|
132
|
-
);
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### 2) Use the normalizer in `run`
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { run } from "runtry";
|
|
139
|
-
|
|
140
|
-
const res = await run(getDocuments, {
|
|
141
|
-
toError,
|
|
142
|
-
onError: (e) => console.log(e.status, e.message),
|
|
118
|
+
mode: "fail-fast", // or "settle" (default)
|
|
143
119
|
});
|
|
144
120
|
```
|
|
145
121
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
## `createRunner()` (configure once, reuse everywhere)
|
|
122
|
+
### `runAllOrThrow(tasks, options?)`
|
|
149
123
|
|
|
150
|
-
|
|
124
|
+
Like `Promise.all` but with concurrency control and retries. Throws the first error (normalized).
|
|
151
125
|
|
|
152
126
|
```ts
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
import { HttpError } from "./http-error";
|
|
160
|
-
|
|
161
|
-
const runner = createRunner({
|
|
162
|
-
matchers: [
|
|
163
|
-
abortMatcher,
|
|
164
|
-
matchInstance(HttpError, (e) => ({
|
|
165
|
-
code: "HTTP",
|
|
166
|
-
message: e.message,
|
|
167
|
-
status: e.status,
|
|
168
|
-
meta: { url: e.url, body: e.body },
|
|
169
|
-
cause: e,
|
|
170
|
-
})),
|
|
171
|
-
],
|
|
172
|
-
fallback: defaultFallback,
|
|
173
|
-
ignoreAbort: true, // default
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const result = await client.run(getDocuments, {
|
|
177
|
-
onError: (e) => console.log(e.code, e.message),
|
|
178
|
-
});
|
|
127
|
+
try {
|
|
128
|
+
const data = await runner.allOrThrow(tasks, { concurrency: 5 });
|
|
129
|
+
} catch (err) {
|
|
130
|
+
// err is your typed AppError
|
|
131
|
+
console.error(err.code);
|
|
132
|
+
}
|
|
179
133
|
```
|
|
180
134
|
|
|
181
135
|
---
|
|
182
136
|
|
|
183
|
-
## React
|
|
137
|
+
## React Example
|
|
184
138
|
|
|
185
139
|
```ts
|
|
186
|
-
import { createRunner, abortMatcher, defaultFallback } from "runtry";
|
|
187
|
-
|
|
188
|
-
const runner = createRunner({
|
|
189
|
-
matchers: [abortMatcher],
|
|
190
|
-
fallback: defaultFallback,
|
|
191
|
-
});
|
|
192
|
-
|
|
193
140
|
useEffect(() => {
|
|
194
141
|
let cancelled = false;
|
|
195
|
-
setIsLoading(true);
|
|
196
142
|
|
|
197
|
-
|
|
198
|
-
onSuccess: (
|
|
199
|
-
if (cancelled)
|
|
200
|
-
setUploadedFiles(docs.map(mapper));
|
|
201
|
-
},
|
|
202
|
-
onError: (e) => {
|
|
203
|
-
if (e.code === "ABORTED") return;
|
|
204
|
-
toast.error(e.message);
|
|
143
|
+
runner.run(fetchData, {
|
|
144
|
+
onSuccess: (data) => {
|
|
145
|
+
if (!cancelled) setData(data);
|
|
205
146
|
},
|
|
206
|
-
|
|
207
|
-
if (
|
|
147
|
+
onError: (err) => {
|
|
148
|
+
if (err.code === "ABORTED") return;
|
|
149
|
+
toast.error(err.message);
|
|
208
150
|
},
|
|
209
151
|
});
|
|
210
152
|
|
package/dist/error/core.d.ts
CHANGED
|
@@ -1,41 +1,20 @@
|
|
|
1
1
|
import type { AppError, Rule } from "./types";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare const
|
|
6
|
-
/**
|
|
7
|
-
* Timeout errors (AbortSignal.timeout, libs, etc)
|
|
8
|
-
*/
|
|
9
|
-
export declare const timeout: () => Rule<AppError<"TIMEOUT">>;
|
|
10
|
-
/**
|
|
11
|
-
* HTTP-like errors (status / statusCode)
|
|
12
|
-
*/
|
|
13
|
-
export declare const httpStatus: () => Rule<AppError<"HTTP">>;
|
|
14
|
-
/**
|
|
15
|
-
* AggregateError (Promise.any, etc)
|
|
16
|
-
*/
|
|
17
|
-
export declare const aggregate: () => Rule<AppError<"UNKNOWN", {
|
|
2
|
+
export declare const abort: Rule<AppError<"ABORTED">>;
|
|
3
|
+
export declare const timeout: Rule<AppError<"TIMEOUT">>;
|
|
4
|
+
export declare const httpStatus: Rule<AppError<"HTTP">>;
|
|
5
|
+
export declare const aggregate: Rule<AppError<"UNKNOWN", {
|
|
18
6
|
errors: unknown[];
|
|
19
7
|
}>>;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
*/
|
|
23
|
-
export declare const string: () => Rule<AppError<"UNKNOWN">>;
|
|
24
|
-
/**
|
|
25
|
-
* Message-like objects (final fallback)
|
|
26
|
-
*/
|
|
27
|
-
export declare const message: () => Rule<AppError<"UNKNOWN">>;
|
|
28
|
-
/**
|
|
29
|
-
* Namespace export
|
|
30
|
-
*/
|
|
8
|
+
export declare const string: Rule<AppError<"UNKNOWN">>;
|
|
9
|
+
export declare const message: Rule<AppError<"UNKNOWN">>;
|
|
31
10
|
export declare const rules: {
|
|
32
|
-
abort:
|
|
33
|
-
timeout:
|
|
34
|
-
httpStatus:
|
|
35
|
-
aggregate:
|
|
11
|
+
abort: Rule<AppError<"ABORTED">>;
|
|
12
|
+
timeout: Rule<AppError<"TIMEOUT">>;
|
|
13
|
+
httpStatus: Rule<AppError<"HTTP">>;
|
|
14
|
+
aggregate: Rule<AppError<"UNKNOWN", {
|
|
36
15
|
errors: unknown[];
|
|
37
16
|
}>>;
|
|
38
|
-
string:
|
|
39
|
-
message:
|
|
17
|
+
string: Rule<AppError<"UNKNOWN">>;
|
|
18
|
+
message: Rule<AppError<"UNKNOWN">>;
|
|
40
19
|
};
|
|
41
20
|
//# sourceMappingURL=core.d.ts.map
|
package/dist/error/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/error/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/error/core.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAY3C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAY7C,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAa7C,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;IAAE,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAAC,CAYtE,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAK5C,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAU7C,CAAC;AAEF,eAAO,MAAM,KAAK;;;;;gBAjCyC,OAAO,EAAE;;;;CAwC1B,CAAC"}
|
package/dist/error/core.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export const abort = () => (err) => {
|
|
1
|
+
import { createRunner } from "../runner/runner";
|
|
2
|
+
import { errorRule } from "./builder";
|
|
3
|
+
export const abort = (err) => {
|
|
5
4
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
6
5
|
return { code: "ABORTED", message: "Request cancelled", cause: err };
|
|
7
6
|
}
|
|
@@ -14,10 +13,7 @@ export const abort = () => (err) => {
|
|
|
14
13
|
}
|
|
15
14
|
return null;
|
|
16
15
|
};
|
|
17
|
-
|
|
18
|
-
* Timeout errors (AbortSignal.timeout, libs, etc)
|
|
19
|
-
*/
|
|
20
|
-
export const timeout = () => (err) => {
|
|
16
|
+
export const timeout = (err) => {
|
|
21
17
|
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
22
18
|
return { code: "TIMEOUT", message: "Request timed out", cause: err };
|
|
23
19
|
}
|
|
@@ -30,10 +26,7 @@ export const timeout = () => (err) => {
|
|
|
30
26
|
}
|
|
31
27
|
return null;
|
|
32
28
|
};
|
|
33
|
-
|
|
34
|
-
* HTTP-like errors (status / statusCode)
|
|
35
|
-
*/
|
|
36
|
-
export const httpStatus = () => (err) => {
|
|
29
|
+
export const httpStatus = (err) => {
|
|
37
30
|
if (typeof err === "object" && err !== null) {
|
|
38
31
|
const status = err.status ?? err.statusCode;
|
|
39
32
|
if (typeof status === "number") {
|
|
@@ -47,12 +40,8 @@ export const httpStatus = () => (err) => {
|
|
|
47
40
|
}
|
|
48
41
|
return null;
|
|
49
42
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*/
|
|
53
|
-
export const aggregate = () => (err) => {
|
|
54
|
-
if (typeof AggregateError !== "undefined" &&
|
|
55
|
-
err instanceof AggregateError) {
|
|
43
|
+
export const aggregate = (err) => {
|
|
44
|
+
if (typeof AggregateError !== "undefined" && err instanceof AggregateError) {
|
|
56
45
|
return {
|
|
57
46
|
code: "UNKNOWN",
|
|
58
47
|
message: err.message || "Multiple errors occurred",
|
|
@@ -62,34 +51,21 @@ export const aggregate = () => (err) => {
|
|
|
62
51
|
}
|
|
63
52
|
return null;
|
|
64
53
|
};
|
|
65
|
-
|
|
66
|
-
* String thrown errors
|
|
67
|
-
*/
|
|
68
|
-
export const string = () => (err) => {
|
|
54
|
+
export const string = (err) => {
|
|
69
55
|
if (typeof err === "string") {
|
|
70
56
|
return { code: "UNKNOWN", message: err, cause: err };
|
|
71
57
|
}
|
|
72
58
|
return null;
|
|
73
59
|
};
|
|
74
|
-
|
|
75
|
-
* Message-like objects (final fallback)
|
|
76
|
-
*/
|
|
77
|
-
export const message = () => (err) => {
|
|
60
|
+
export const message = (err) => {
|
|
78
61
|
if (typeof err === "object" &&
|
|
79
62
|
err !== null &&
|
|
80
63
|
"message" in err &&
|
|
81
64
|
typeof err.message === "string") {
|
|
82
|
-
return {
|
|
83
|
-
code: "UNKNOWN",
|
|
84
|
-
message: err.message,
|
|
85
|
-
cause: err,
|
|
86
|
-
};
|
|
65
|
+
return { code: "UNKNOWN", message: err.message, cause: err };
|
|
87
66
|
}
|
|
88
67
|
return null;
|
|
89
68
|
};
|
|
90
|
-
/**
|
|
91
|
-
* Namespace export
|
|
92
|
-
*/
|
|
93
69
|
export const rules = {
|
|
94
70
|
abort,
|
|
95
71
|
timeout,
|
package/dist/error/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/error/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/error/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/error/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,EACjD,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAChB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,IAErB,KAAK,OAAO,KAAG,CAAC,CAOzB;AAGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAQtD;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/error/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAE9C,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,QAAQ,EACjD,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAChB,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,IAErB,KAAK,OAAO,KAAG,CAAC,CAOzB;AAGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAQtD;AAGD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CASjD"}
|
package/dist/error/normalize.js
CHANGED
|
@@ -24,6 +24,9 @@ export function toAppError(err) {
|
|
|
24
24
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
25
25
|
return { code: "ABORTED", message: "Request cancelled", cause: err };
|
|
26
26
|
}
|
|
27
|
+
if (err instanceof DOMException && err.name === "TimeoutError") {
|
|
28
|
+
return { code: "TIMEOUT", message: "Request timed out", cause: err };
|
|
29
|
+
}
|
|
27
30
|
return defaultFallback(err);
|
|
28
31
|
}
|
|
29
32
|
//# sourceMappingURL=normalize.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/error/normalize.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAC9B,KAAgB,EAChB,QAA6B;IAE7B,OAAO,CAAC,GAAY,EAAK,EAAE;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACnB,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;QACtB,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,sBAAsB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC1E,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,iDAAiD;IACjD,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC"}
|
|
1
|
+
{"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../src/error/normalize.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAC9B,KAAgB,EAChB,QAA6B;IAE7B,OAAO,CAAC,GAAY,EAAK,EAAE;QACzB,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;YACtB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACnB,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;QACtB,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC,CAAC;AACJ,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,mEAAmE;QACnE,gEAAgE;QAChE,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,sBAAsB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AAC1E,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,iDAAiD;IACjD,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QAC7D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC;AAC9B,CAAC"}
|
package/dist/error/types.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export type AppError<Code extends string = AppErrorCode | (string & {}), Meta =
|
|
|
17
17
|
};
|
|
18
18
|
type NonNull<T> = T extends null ? never : T;
|
|
19
19
|
type RuleReturn<R> = R extends (err: unknown) => infer Out ? NonNull<Out> : never;
|
|
20
|
-
export type InferErrorFromRules<TRules extends readonly Rule<any>[]> = TRules extends readonly [] ? AppError : RuleReturn<TRules[number]>;
|
|
20
|
+
export type InferErrorFromRules<TRules extends readonly Rule<any>[]> = TRules extends readonly [] ? AppError : RuleReturn<TRules[number]> | AppError<"UNKNOWN">;
|
|
21
21
|
export type Rule<E extends AppError = AppError> = (err: unknown) => E | null;
|
|
22
22
|
export {};
|
|
23
23
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/error/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,MAAM,GACN,SAAS,CAAC;AAEd;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAClB,IAAI,SAAS,MAAM,GAAG,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAClD,IAAI,GAAG,OAAO,IACZ;IACF,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;AAC7C,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,GACtD,OAAO,CAAC,GAAG,CAAC,GACZ,KAAK,CAAC;AACV,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,IACjE,MAAM,SAAS,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/error/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,SAAS,GACT,YAAY,GACZ,MAAM,GACN,SAAS,CAAC;AAEd;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAClB,IAAI,SAAS,MAAM,GAAG,YAAY,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,EAClD,IAAI,GAAG,OAAO,IACZ;IACF,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;AAC7C,KAAK,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,GAAG,GACtD,OAAO,CAAC,GAAG,CAAC,GACZ,KAAK,CAAC;AACV,MAAM,MAAM,mBAAmB,CAAC,MAAM,SAAS,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,IACjE,MAAM,SAAS,SAAS,EAAE,GACtB,QAAQ,GACR,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;AACvD,MAAM,MAAM,IAAI,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { run } from "./runner/run";
|
|
2
2
|
export { runAll } from "./runner/runAll";
|
|
3
|
-
export type { RunAllOptions } from "./runner/runAll";
|
|
3
|
+
export type { RunAllOptions, SuccessResult, ErrorResult } from "./runner/runAll";
|
|
4
|
+
export { isSuccess } from "./runner/runAll";
|
|
4
5
|
export type { RunOptions, RunResult, RetryOptions } from "./types";
|
|
6
|
+
export type { BackoffStrategy, CircuitBreakerOptions, Metrics, RetryContext, } from "./types";
|
|
5
7
|
export type { AppError, AppErrorCode } from "./error/types";
|
|
6
8
|
export { toAppError, defaultFallback, createNormalizer, } from "./error/normalize";
|
|
7
9
|
export { rules } from "./error/core";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnE,YAAY,EACV,eAAe,EACf,qBAAqB,EACrB,OAAO,EACP,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { run } from "./runner/run";
|
|
2
2
|
export { runAll } from "./runner/runAll";
|
|
3
|
+
export { isSuccess } from "./runner/runAll";
|
|
3
4
|
export { toAppError, defaultFallback, createNormalizer, } from "./error/normalize";
|
|
4
5
|
export { rules } from "./error/core";
|
|
5
6
|
export { errorRule } from "./error/builder";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAU5C,OAAO,EACL,UAAU,EACV,eAAe,EACf,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/runner/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/runner/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/runner/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAItD;;;;;;;;GAQG;AACH,wBAAsB,GAAG,CAAC,CAAC,EAAE,CAAC,SAAS,QAAQ,GAAG,QAAQ,EACxD,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAM,GAC7B,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CA8I1B"}
|
package/dist/runner/run.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toAppError as defaultToAppError } from "../error/normalize";
|
|
2
|
+
import { validateOptions } from "../types";
|
|
2
3
|
import { applyJitter, resolveRetryDelay, sleep } from "../utils";
|
|
3
4
|
/**
|
|
4
5
|
* Executes an async operation and returns a Result instead of throwing.
|
|
@@ -10,37 +11,88 @@ import { applyJitter, resolveRetryDelay, sleep } from "../utils";
|
|
|
10
11
|
* React effects, and any async context.
|
|
11
12
|
*/
|
|
12
13
|
export async function run(fn, options = {}) {
|
|
13
|
-
const { toError = defaultToAppError, mapError, onError, onSuccess, onFinally, ignoreAbort = true, retries = 0, retryDelay, shouldRetry = () => true, jitter = { ratio: 0.5, mode: "full" }, } = options;
|
|
14
|
+
const { toError = defaultToAppError, mapError, onError, onSuccess, onFinally, ignoreAbort = true, retries = 0, retryDelay, shouldRetry = () => true, jitter = { ratio: 0.5, mode: "full" }, backoffStrategy, maxDelay, timeout, signal, onRetry, logger, cleanup, onAbort, } = options;
|
|
14
15
|
const defaultBaseDelay = retries > 0 ? 300 : 0;
|
|
16
|
+
validateOptions(options);
|
|
17
|
+
if (signal?.aborted) {
|
|
18
|
+
try {
|
|
19
|
+
onAbort?.(signal);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
const err = toError(new DOMException("Aborted", "AbortError"));
|
|
23
|
+
const mapped = mapError ? mapError(err) : err;
|
|
24
|
+
if (!ignoreAbort) {
|
|
25
|
+
onError?.(mapped);
|
|
26
|
+
}
|
|
27
|
+
onFinally?.();
|
|
28
|
+
return { ok: false, data: null, error: mapped, metrics: { totalAttempts: 0, totalRetries: 0, totalDuration: 0, lastError: mapped } };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const startedAt = Date.now();
|
|
15
32
|
let attempt = 0;
|
|
33
|
+
let lastError;
|
|
16
34
|
while (true) {
|
|
17
35
|
try {
|
|
18
|
-
const
|
|
36
|
+
const timeoutPromise = timeout && timeout > 0
|
|
37
|
+
? new Promise((_, reject) => setTimeout(() => reject(new DOMException("Timeout", "TimeoutError")), timeout))
|
|
38
|
+
: null;
|
|
39
|
+
const data = await (timeoutPromise ? Promise.race([fn(), timeoutPromise]) : fn());
|
|
19
40
|
onSuccess?.(data);
|
|
20
41
|
onFinally?.();
|
|
21
|
-
|
|
42
|
+
const totalDuration = Date.now() - startedAt;
|
|
43
|
+
const metrics = {
|
|
44
|
+
totalAttempts: attempt + 1,
|
|
45
|
+
totalRetries: attempt,
|
|
46
|
+
totalDuration,
|
|
47
|
+
lastError,
|
|
48
|
+
};
|
|
49
|
+
logger?.debug?.("run:success", { attempts: metrics.totalAttempts, duration: metrics.totalDuration });
|
|
50
|
+
return { ok: true, data, error: null, metrics };
|
|
22
51
|
}
|
|
23
52
|
catch (e) {
|
|
24
53
|
let err = toError(e);
|
|
25
54
|
if (mapError)
|
|
26
55
|
err = mapError(err);
|
|
27
|
-
const isAborted = err
|
|
56
|
+
const isAborted = err?.code === "ABORTED" ||
|
|
57
|
+
(e instanceof DOMException && e.name === "AbortError") ||
|
|
58
|
+
signal?.aborted;
|
|
28
59
|
if (isAborted) {
|
|
29
|
-
|
|
30
|
-
|
|
60
|
+
try {
|
|
61
|
+
if (signal)
|
|
62
|
+
onAbort?.(signal);
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
if (!ignoreAbort) {
|
|
66
|
+
onError?.(err);
|
|
67
|
+
}
|
|
68
|
+
onFinally?.();
|
|
69
|
+
const totalDuration = Date.now() - startedAt;
|
|
70
|
+
const metrics = {
|
|
71
|
+
totalAttempts: attempt,
|
|
72
|
+
totalRetries: attempt,
|
|
73
|
+
totalDuration,
|
|
74
|
+
lastError: err,
|
|
75
|
+
};
|
|
76
|
+
logger?.debug?.("run:aborted", { attempt, duration: metrics.totalDuration });
|
|
77
|
+
return { ok: false, data: null, error: err, metrics };
|
|
31
78
|
}
|
|
32
|
-
onFinally?.();
|
|
33
|
-
return { ok: false, data: null, error: err };
|
|
34
|
-
// If not ignoring abort, we fall through to onError and return
|
|
35
79
|
}
|
|
80
|
+
lastError = err;
|
|
36
81
|
const nextAttempt = attempt + 1;
|
|
37
|
-
const
|
|
82
|
+
const context = {
|
|
83
|
+
totalAttempts: nextAttempt,
|
|
84
|
+
elapsedTime: Date.now() - startedAt,
|
|
85
|
+
};
|
|
86
|
+
const decision = await Promise.resolve(shouldRetry(nextAttempt, err, context));
|
|
87
|
+
const canRetry = attempt < retries && decision;
|
|
38
88
|
if (canRetry) {
|
|
39
89
|
attempt = nextAttempt;
|
|
40
|
-
let delay = resolveRetryDelay(retryDelay, attempt, err, defaultBaseDelay);
|
|
90
|
+
let delay = resolveRetryDelay(retryDelay, attempt, err, defaultBaseDelay, backoffStrategy, maxDelay);
|
|
41
91
|
if (!Number.isFinite(delay) || delay < 0)
|
|
42
92
|
delay = 0;
|
|
43
93
|
delay = applyJitter(delay, jitter);
|
|
94
|
+
onRetry?.(attempt, err, delay);
|
|
95
|
+
logger?.debug?.("run:retry", { attempt, delay });
|
|
44
96
|
if (delay > 0)
|
|
45
97
|
await sleep(delay);
|
|
46
98
|
continue;
|
|
@@ -48,7 +100,15 @@ export async function run(fn, options = {}) {
|
|
|
48
100
|
// Final failure or aborted
|
|
49
101
|
onError?.(err);
|
|
50
102
|
onFinally?.();
|
|
51
|
-
|
|
103
|
+
const totalDuration = Date.now() - startedAt;
|
|
104
|
+
const metrics = {
|
|
105
|
+
totalAttempts: attempt + 1,
|
|
106
|
+
totalRetries: attempt,
|
|
107
|
+
totalDuration,
|
|
108
|
+
lastError: err,
|
|
109
|
+
};
|
|
110
|
+
logger?.error?.("run:error", err);
|
|
111
|
+
return { ok: false, data: null, error: err, metrics };
|
|
52
112
|
}
|
|
53
113
|
}
|
|
54
114
|
}
|
package/dist/runner/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runner/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAErE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjE;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,EAAoB,EACpB,UAA4B,EAAE;IAE9B,MAAM,EACJ,OAAO,GAAG,iBAAmD,EAC7D,QAAQ,EACR,OAAO,EACP,SAAS,EACT,SAAS,EACT,WAAW,GAAG,IAAI,EAClB,OAAO,GAAG,CAAC,EACX,UAAU,EACV,WAAW,GAAG,GAAG,EAAE,CAAC,IAAI,EACxB,MAAM,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/runner/run.ts"],"names":[],"mappings":"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"}
|