@jesscss/awaitable-pipe 2.0.0-alpha.1 → 2.0.0-alpha.11
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 +23 -8
- package/lib/index.cjs +217 -0
- package/lib/index.js +209 -4
- package/lib/utils.d.ts +2 -1
- package/package.json +12 -12
- package/lib/helpers.js +0 -111
- package/lib/helpers.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/pipe.js +0 -126
- package/lib/pipe.js.map +0 -1
- package/lib/utils.js +0 -47
- package/lib/utils.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
# awaitable-pipe
|
|
1
|
+
# @jesscss/awaitable-pipe
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A tiny, strongly-typed pipe that stays synchronous until a step returns a Promise — with one optional error handler.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It’s a small utility from the [Jess](https://github.com/jesscss/jess) project,
|
|
6
|
+
where hot paths call functions that are usually — but not always —
|
|
7
|
+
synchronous. It’s zero-dependency and usable on its own: it stays sync when
|
|
8
|
+
everything is sync, and turns into a Promise only when something is async. No
|
|
9
|
+
wrappers, no ceremony.
|
|
6
10
|
|
|
7
11
|
- **Stays sync when it can**: all-sync pipelines return a plain value
|
|
8
12
|
- **Goes async when it must**: any async input/step returns a Promise
|
|
@@ -12,12 +16,12 @@ A tiny, zero-dependency pipe with friendly types that “just works”: it stays
|
|
|
12
16
|
|
|
13
17
|
## Install
|
|
14
18
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
# or
|
|
18
|
-
npm i @jesscss/awaitable-pipe
|
|
19
|
+
```sh
|
|
20
|
+
npm install @jesscss/awaitable-pipe
|
|
19
21
|
```
|
|
20
22
|
|
|
23
|
+
Published to npm under both the `latest` and `alpha` dist-tags.
|
|
24
|
+
|
|
21
25
|
## Quick Start
|
|
22
26
|
|
|
23
27
|
```ts
|
|
@@ -181,5 +185,16 @@ const sum = await serialReduce(items, 0, async (acc, n, i) => {
|
|
|
181
185
|
// sum === 6
|
|
182
186
|
```
|
|
183
187
|
|
|
188
|
+
## Status
|
|
189
|
+
|
|
190
|
+
Alpha, as part of the Jess monorepo. Please
|
|
191
|
+
[report issues](https://github.com/jesscss/jess/issues).
|
|
192
|
+
|
|
193
|
+
## Links
|
|
194
|
+
|
|
195
|
+
- Repository: <https://github.com/jesscss/jess>
|
|
196
|
+
- Documentation: <https://jesscss.github.io/> (currently pre-alpha content)
|
|
197
|
+
|
|
184
198
|
## License
|
|
185
|
-
|
|
199
|
+
|
|
200
|
+
[MIT](https://github.com/jesscss/jess/blob/dev/LICENSE)
|
package/lib/index.cjs
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/utils.ts
|
|
3
|
+
function isThenable(x) {
|
|
4
|
+
return !!x && (typeof x === "object" || typeof x === "function") && "then" in x && typeof x.then === "function";
|
|
5
|
+
}
|
|
6
|
+
function isPromise(x) {
|
|
7
|
+
return !!x && typeof x === "object" && "then" in x && typeof x.then === "function" && "catch" in x && typeof x.catch === "function";
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Serial forEach over an array where the step may return a Promise.
|
|
11
|
+
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
12
|
+
*/
|
|
13
|
+
function serialForEach(items, step) {
|
|
14
|
+
for (let i = 0; i < items.length; i++) {
|
|
15
|
+
const out = step(items[i], i);
|
|
16
|
+
if (isThenable(out)) return (async () => {
|
|
17
|
+
await out;
|
|
18
|
+
for (let j = i + 1; j < items.length; j++) await step(items[j], j);
|
|
19
|
+
})();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Serial reduce over an array where the step may return a Promise.
|
|
24
|
+
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
25
|
+
*/
|
|
26
|
+
function serialReduce(items, seed, step) {
|
|
27
|
+
let acc = seed;
|
|
28
|
+
for (let i = 0; i < items.length; i++) {
|
|
29
|
+
const out = step(acc, items[i], i);
|
|
30
|
+
if (isThenable(out)) return (async () => {
|
|
31
|
+
acc = await out;
|
|
32
|
+
for (let j = i + 1; j < items.length; j++) acc = await step(acc, items[j], j);
|
|
33
|
+
return acc;
|
|
34
|
+
})();
|
|
35
|
+
acc = out;
|
|
36
|
+
}
|
|
37
|
+
return acc;
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/pipe.ts
|
|
41
|
+
function isAnyFn(value) {
|
|
42
|
+
return typeof value === "function";
|
|
43
|
+
}
|
|
44
|
+
function runAsync(v, fns, startIndex) {
|
|
45
|
+
let p = Promise.resolve(v);
|
|
46
|
+
for (let i = startIndex; i < fns.length; i++) {
|
|
47
|
+
const fn = fns[i];
|
|
48
|
+
p = p.then((val) => fn(val));
|
|
49
|
+
}
|
|
50
|
+
return p;
|
|
51
|
+
}
|
|
52
|
+
function pipe(...args) {
|
|
53
|
+
let input;
|
|
54
|
+
let fns;
|
|
55
|
+
if (args.length === 0) return;
|
|
56
|
+
const first = args[0];
|
|
57
|
+
const second = args[1];
|
|
58
|
+
const rest = args.slice(1);
|
|
59
|
+
if (isAnyFn(first) && isAnyFn(second)) {
|
|
60
|
+
input = void 0;
|
|
61
|
+
fns = args.filter(isAnyFn);
|
|
62
|
+
} else if (args.length > 1) {
|
|
63
|
+
input = isAnyFn(first) ? first(void 0) : first;
|
|
64
|
+
fns = rest.filter(isAnyFn);
|
|
65
|
+
} else {
|
|
66
|
+
input = void 0;
|
|
67
|
+
if (!isAnyFn(first)) return first;
|
|
68
|
+
fns = [first];
|
|
69
|
+
}
|
|
70
|
+
if (isThenable(input)) return runAsync(input, fns, 0);
|
|
71
|
+
for (let i = 0; i < fns.length; i++) {
|
|
72
|
+
const fn = fns[i];
|
|
73
|
+
const out = fn(input);
|
|
74
|
+
if (isThenable(out)) return runAsync(out, fns, i + 1);
|
|
75
|
+
input = out;
|
|
76
|
+
}
|
|
77
|
+
return input;
|
|
78
|
+
}
|
|
79
|
+
function isFallbackFactory(fallback) {
|
|
80
|
+
return typeof fallback === "function";
|
|
81
|
+
}
|
|
82
|
+
function resolveFallback(fb) {
|
|
83
|
+
return isFallbackFactory(fb) ? fb() : fb;
|
|
84
|
+
}
|
|
85
|
+
function runAsyncSafe(v, fns, startIndex, opts) {
|
|
86
|
+
const { onError, fallback } = opts;
|
|
87
|
+
const callOnError = (e) => {
|
|
88
|
+
try {
|
|
89
|
+
onError?.(e);
|
|
90
|
+
} catch {}
|
|
91
|
+
};
|
|
92
|
+
let p = Promise.resolve(v);
|
|
93
|
+
for (let i = startIndex; i < fns.length; i++) {
|
|
94
|
+
const fn = fns[i];
|
|
95
|
+
p = p.then((val) => {
|
|
96
|
+
try {
|
|
97
|
+
return fn(val);
|
|
98
|
+
} catch (e) {
|
|
99
|
+
callOnError(e);
|
|
100
|
+
return resolveFallback(fallback);
|
|
101
|
+
}
|
|
102
|
+
}, (e) => {
|
|
103
|
+
callOnError(e);
|
|
104
|
+
return resolveFallback(fallback);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return p.catch((e) => {
|
|
108
|
+
callOnError(e);
|
|
109
|
+
return resolveFallback(fallback);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function safePipe(...args) {
|
|
113
|
+
let input;
|
|
114
|
+
let options;
|
|
115
|
+
let fns;
|
|
116
|
+
if (args.length === 0) return;
|
|
117
|
+
const first = args[0];
|
|
118
|
+
const second = args[1];
|
|
119
|
+
const looksLikeOptions = (x) => !!x && typeof x === "object" && !Array.isArray(x);
|
|
120
|
+
if (args.length === 1 && !!first && typeof first === "object") return;
|
|
121
|
+
const bothFns = isAnyFn(first) && isAnyFn(second);
|
|
122
|
+
if (looksLikeOptions(first) || bothFns) {
|
|
123
|
+
input = void 0;
|
|
124
|
+
options = looksLikeOptions(first) ? first : {};
|
|
125
|
+
fns = (looksLikeOptions(first) ? args.slice(1) : args).filter(isAnyFn);
|
|
126
|
+
} else throw new TypeError("safePipe requires steps-only or options-first with steps");
|
|
127
|
+
input = void 0;
|
|
128
|
+
for (let i = 0; i < fns.length; i++) {
|
|
129
|
+
const fn = fns[i];
|
|
130
|
+
try {
|
|
131
|
+
const out = fn(input);
|
|
132
|
+
if (isThenable(out)) return runAsyncSafe(out, fns, i + 1, options);
|
|
133
|
+
input = out;
|
|
134
|
+
} catch (e) {
|
|
135
|
+
try {
|
|
136
|
+
options?.onError?.(e);
|
|
137
|
+
} catch {}
|
|
138
|
+
return resolveFallback(options?.fallback);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return input;
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/helpers.ts
|
|
145
|
+
function isStepFallbackFactory(fallback) {
|
|
146
|
+
return typeof fallback === "function";
|
|
147
|
+
}
|
|
148
|
+
function resolveStepFallback(fallback, error, input) {
|
|
149
|
+
return isStepFallbackFactory(fallback) ? fallback(error, input) : fallback;
|
|
150
|
+
}
|
|
151
|
+
function isNoArgFunction(fn) {
|
|
152
|
+
return fn.length === 0;
|
|
153
|
+
}
|
|
154
|
+
function tryStep(fn, options = {}) {
|
|
155
|
+
if (isNoArgFunction(fn)) {
|
|
156
|
+
const noInputFn = fn;
|
|
157
|
+
const resultFn = (input) => {
|
|
158
|
+
try {
|
|
159
|
+
const out = noInputFn();
|
|
160
|
+
if (isThenable(out)) return out.catch((e) => {
|
|
161
|
+
try {
|
|
162
|
+
options.onError?.(e, input);
|
|
163
|
+
} catch (_onErrorThrown) {}
|
|
164
|
+
if (options.rethrow === true) return Promise.reject(e);
|
|
165
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
166
|
+
});
|
|
167
|
+
return out;
|
|
168
|
+
} catch (e) {
|
|
169
|
+
try {
|
|
170
|
+
options.onError?.(e, input);
|
|
171
|
+
} catch (_onErrorThrown) {}
|
|
172
|
+
if (options.rethrow === true) throw e;
|
|
173
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
return resultFn;
|
|
177
|
+
}
|
|
178
|
+
return (input) => {
|
|
179
|
+
try {
|
|
180
|
+
const out = fn(input);
|
|
181
|
+
if (isThenable(out)) return out.catch((e) => {
|
|
182
|
+
try {
|
|
183
|
+
options.onError?.(e, input);
|
|
184
|
+
} catch (_onErrorThrown) {}
|
|
185
|
+
if (options.rethrow === true) return Promise.reject(e);
|
|
186
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
187
|
+
});
|
|
188
|
+
return out;
|
|
189
|
+
} catch (e) {
|
|
190
|
+
try {
|
|
191
|
+
options.onError?.(e, input);
|
|
192
|
+
} catch (_onErrorThrown) {}
|
|
193
|
+
if (options.rethrow === true) throw e;
|
|
194
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function guard(predicate, errorFactory = (_v) => /* @__PURE__ */ new Error("ensure failed")) {
|
|
199
|
+
return (value) => {
|
|
200
|
+
const ok = predicate(value);
|
|
201
|
+
if (isThenable(ok)) return ok.then((passed) => {
|
|
202
|
+
if (!passed) throw errorFactory(value);
|
|
203
|
+
return value;
|
|
204
|
+
});
|
|
205
|
+
if (!ok) throw errorFactory(value);
|
|
206
|
+
return value;
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
//#endregion
|
|
210
|
+
exports.guard = guard;
|
|
211
|
+
exports.isPromise = isPromise;
|
|
212
|
+
exports.isThenable = isThenable;
|
|
213
|
+
exports.pipe = pipe;
|
|
214
|
+
exports.safePipe = safePipe;
|
|
215
|
+
exports.serialForEach = serialForEach;
|
|
216
|
+
exports.serialReduce = serialReduce;
|
|
217
|
+
exports.tryStep = tryStep;
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,209 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
//#region src/utils.ts
|
|
2
|
+
function isThenable(x) {
|
|
3
|
+
return !!x && (typeof x === "object" || typeof x === "function") && "then" in x && typeof x.then === "function";
|
|
4
|
+
}
|
|
5
|
+
function isPromise(x) {
|
|
6
|
+
return !!x && typeof x === "object" && "then" in x && typeof x.then === "function" && "catch" in x && typeof x.catch === "function";
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Serial forEach over an array where the step may return a Promise.
|
|
10
|
+
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
11
|
+
*/
|
|
12
|
+
function serialForEach(items, step) {
|
|
13
|
+
for (let i = 0; i < items.length; i++) {
|
|
14
|
+
const out = step(items[i], i);
|
|
15
|
+
if (isThenable(out)) return (async () => {
|
|
16
|
+
await out;
|
|
17
|
+
for (let j = i + 1; j < items.length; j++) await step(items[j], j);
|
|
18
|
+
})();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Serial reduce over an array where the step may return a Promise.
|
|
23
|
+
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
24
|
+
*/
|
|
25
|
+
function serialReduce(items, seed, step) {
|
|
26
|
+
let acc = seed;
|
|
27
|
+
for (let i = 0; i < items.length; i++) {
|
|
28
|
+
const out = step(acc, items[i], i);
|
|
29
|
+
if (isThenable(out)) return (async () => {
|
|
30
|
+
acc = await out;
|
|
31
|
+
for (let j = i + 1; j < items.length; j++) acc = await step(acc, items[j], j);
|
|
32
|
+
return acc;
|
|
33
|
+
})();
|
|
34
|
+
acc = out;
|
|
35
|
+
}
|
|
36
|
+
return acc;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/pipe.ts
|
|
40
|
+
function isAnyFn(value) {
|
|
41
|
+
return typeof value === "function";
|
|
42
|
+
}
|
|
43
|
+
function runAsync(v, fns, startIndex) {
|
|
44
|
+
let p = Promise.resolve(v);
|
|
45
|
+
for (let i = startIndex; i < fns.length; i++) {
|
|
46
|
+
const fn = fns[i];
|
|
47
|
+
p = p.then((val) => fn(val));
|
|
48
|
+
}
|
|
49
|
+
return p;
|
|
50
|
+
}
|
|
51
|
+
function pipe(...args) {
|
|
52
|
+
let input;
|
|
53
|
+
let fns;
|
|
54
|
+
if (args.length === 0) return;
|
|
55
|
+
const first = args[0];
|
|
56
|
+
const second = args[1];
|
|
57
|
+
const rest = args.slice(1);
|
|
58
|
+
if (isAnyFn(first) && isAnyFn(second)) {
|
|
59
|
+
input = void 0;
|
|
60
|
+
fns = args.filter(isAnyFn);
|
|
61
|
+
} else if (args.length > 1) {
|
|
62
|
+
input = isAnyFn(first) ? first(void 0) : first;
|
|
63
|
+
fns = rest.filter(isAnyFn);
|
|
64
|
+
} else {
|
|
65
|
+
input = void 0;
|
|
66
|
+
if (!isAnyFn(first)) return first;
|
|
67
|
+
fns = [first];
|
|
68
|
+
}
|
|
69
|
+
if (isThenable(input)) return runAsync(input, fns, 0);
|
|
70
|
+
for (let i = 0; i < fns.length; i++) {
|
|
71
|
+
const fn = fns[i];
|
|
72
|
+
const out = fn(input);
|
|
73
|
+
if (isThenable(out)) return runAsync(out, fns, i + 1);
|
|
74
|
+
input = out;
|
|
75
|
+
}
|
|
76
|
+
return input;
|
|
77
|
+
}
|
|
78
|
+
function isFallbackFactory(fallback) {
|
|
79
|
+
return typeof fallback === "function";
|
|
80
|
+
}
|
|
81
|
+
function resolveFallback(fb) {
|
|
82
|
+
return isFallbackFactory(fb) ? fb() : fb;
|
|
83
|
+
}
|
|
84
|
+
function runAsyncSafe(v, fns, startIndex, opts) {
|
|
85
|
+
const { onError, fallback } = opts;
|
|
86
|
+
const callOnError = (e) => {
|
|
87
|
+
try {
|
|
88
|
+
onError?.(e);
|
|
89
|
+
} catch {}
|
|
90
|
+
};
|
|
91
|
+
let p = Promise.resolve(v);
|
|
92
|
+
for (let i = startIndex; i < fns.length; i++) {
|
|
93
|
+
const fn = fns[i];
|
|
94
|
+
p = p.then((val) => {
|
|
95
|
+
try {
|
|
96
|
+
return fn(val);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
callOnError(e);
|
|
99
|
+
return resolveFallback(fallback);
|
|
100
|
+
}
|
|
101
|
+
}, (e) => {
|
|
102
|
+
callOnError(e);
|
|
103
|
+
return resolveFallback(fallback);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return p.catch((e) => {
|
|
107
|
+
callOnError(e);
|
|
108
|
+
return resolveFallback(fallback);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function safePipe(...args) {
|
|
112
|
+
let input;
|
|
113
|
+
let options;
|
|
114
|
+
let fns;
|
|
115
|
+
if (args.length === 0) return;
|
|
116
|
+
const first = args[0];
|
|
117
|
+
const second = args[1];
|
|
118
|
+
const looksLikeOptions = (x) => !!x && typeof x === "object" && !Array.isArray(x);
|
|
119
|
+
if (args.length === 1 && !!first && typeof first === "object") return;
|
|
120
|
+
const bothFns = isAnyFn(first) && isAnyFn(second);
|
|
121
|
+
if (looksLikeOptions(first) || bothFns) {
|
|
122
|
+
input = void 0;
|
|
123
|
+
options = looksLikeOptions(first) ? first : {};
|
|
124
|
+
fns = (looksLikeOptions(first) ? args.slice(1) : args).filter(isAnyFn);
|
|
125
|
+
} else throw new TypeError("safePipe requires steps-only or options-first with steps");
|
|
126
|
+
input = void 0;
|
|
127
|
+
for (let i = 0; i < fns.length; i++) {
|
|
128
|
+
const fn = fns[i];
|
|
129
|
+
try {
|
|
130
|
+
const out = fn(input);
|
|
131
|
+
if (isThenable(out)) return runAsyncSafe(out, fns, i + 1, options);
|
|
132
|
+
input = out;
|
|
133
|
+
} catch (e) {
|
|
134
|
+
try {
|
|
135
|
+
options?.onError?.(e);
|
|
136
|
+
} catch {}
|
|
137
|
+
return resolveFallback(options?.fallback);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return input;
|
|
141
|
+
}
|
|
142
|
+
//#endregion
|
|
143
|
+
//#region src/helpers.ts
|
|
144
|
+
function isStepFallbackFactory(fallback) {
|
|
145
|
+
return typeof fallback === "function";
|
|
146
|
+
}
|
|
147
|
+
function resolveStepFallback(fallback, error, input) {
|
|
148
|
+
return isStepFallbackFactory(fallback) ? fallback(error, input) : fallback;
|
|
149
|
+
}
|
|
150
|
+
function isNoArgFunction(fn) {
|
|
151
|
+
return fn.length === 0;
|
|
152
|
+
}
|
|
153
|
+
function tryStep(fn, options = {}) {
|
|
154
|
+
if (isNoArgFunction(fn)) {
|
|
155
|
+
const noInputFn = fn;
|
|
156
|
+
const resultFn = (input) => {
|
|
157
|
+
try {
|
|
158
|
+
const out = noInputFn();
|
|
159
|
+
if (isThenable(out)) return out.catch((e) => {
|
|
160
|
+
try {
|
|
161
|
+
options.onError?.(e, input);
|
|
162
|
+
} catch (_onErrorThrown) {}
|
|
163
|
+
if (options.rethrow === true) return Promise.reject(e);
|
|
164
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
165
|
+
});
|
|
166
|
+
return out;
|
|
167
|
+
} catch (e) {
|
|
168
|
+
try {
|
|
169
|
+
options.onError?.(e, input);
|
|
170
|
+
} catch (_onErrorThrown) {}
|
|
171
|
+
if (options.rethrow === true) throw e;
|
|
172
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
return resultFn;
|
|
176
|
+
}
|
|
177
|
+
return (input) => {
|
|
178
|
+
try {
|
|
179
|
+
const out = fn(input);
|
|
180
|
+
if (isThenable(out)) return out.catch((e) => {
|
|
181
|
+
try {
|
|
182
|
+
options.onError?.(e, input);
|
|
183
|
+
} catch (_onErrorThrown) {}
|
|
184
|
+
if (options.rethrow === true) return Promise.reject(e);
|
|
185
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
186
|
+
});
|
|
187
|
+
return out;
|
|
188
|
+
} catch (e) {
|
|
189
|
+
try {
|
|
190
|
+
options.onError?.(e, input);
|
|
191
|
+
} catch (_onErrorThrown) {}
|
|
192
|
+
if (options.rethrow === true) throw e;
|
|
193
|
+
return resolveStepFallback(options.fallback, e, input);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
function guard(predicate, errorFactory = (_v) => /* @__PURE__ */ new Error("ensure failed")) {
|
|
198
|
+
return (value) => {
|
|
199
|
+
const ok = predicate(value);
|
|
200
|
+
if (isThenable(ok)) return ok.then((passed) => {
|
|
201
|
+
if (!passed) throw errorFactory(value);
|
|
202
|
+
return value;
|
|
203
|
+
});
|
|
204
|
+
if (!ok) throw errorFactory(value);
|
|
205
|
+
return value;
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
//#endregion
|
|
209
|
+
export { guard, isPromise, isThenable, pipe, safePipe, serialForEach, serialReduce, tryStep };
|
package/lib/utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export type MaybePromise<T> = T | Promise<T>;
|
|
2
|
-
export declare function isThenable(x:
|
|
2
|
+
export declare function isThenable<T = unknown>(x: T | Promise<T>): x is Promise<T>;
|
|
3
|
+
export declare function isThenable<T = unknown>(x: unknown): x is Promise<T>;
|
|
3
4
|
export declare function isPromise<T = unknown>(x: unknown): x is Promise<T>;
|
|
4
5
|
/**
|
|
5
6
|
* Serial forEach over an array where the step may return a Promise.
|
package/package.json
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jesscss/awaitable-pipe",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.11",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
6
|
+
},
|
|
4
7
|
"description": "A tiny, strongly-typed pipe that stays sync when possible and becomes a Promise when needed. With an optional single-point error handler.",
|
|
5
8
|
"type": "module",
|
|
6
|
-
"main": "lib/index.
|
|
9
|
+
"main": "lib/index.cjs",
|
|
7
10
|
"types": "lib/index.d.ts",
|
|
8
11
|
"exports": {
|
|
9
12
|
".": {
|
|
10
|
-
"import": "./lib/index.js",
|
|
11
13
|
"types": "./lib/index.d.ts",
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"./*": {
|
|
15
|
-
"types": "./lib/*.d.ts",
|
|
16
|
-
"import": "./lib/*.js",
|
|
17
|
-
"source": "./src/*.ts"
|
|
14
|
+
"import": "./lib/index.js",
|
|
15
|
+
"require": "./lib/index.cjs"
|
|
18
16
|
},
|
|
19
17
|
"./package.json": "./package.json"
|
|
20
18
|
},
|
|
@@ -44,11 +42,13 @@
|
|
|
44
42
|
"devDependencies": {
|
|
45
43
|
"typescript": "~5.8.2"
|
|
46
44
|
},
|
|
45
|
+
"module": "lib/index.js",
|
|
47
46
|
"scripts": {
|
|
48
|
-
"build": "
|
|
49
|
-
"dev": "
|
|
47
|
+
"build": "pnpm compile",
|
|
48
|
+
"dev": "tsdown --tsconfig tsconfig.build.json --watch",
|
|
50
49
|
"test": "vitest run",
|
|
51
50
|
"test:types": "tsc -p tsconfig.json --noEmit",
|
|
52
|
-
"test:watch": "vitest"
|
|
51
|
+
"test:watch": "vitest",
|
|
52
|
+
"compile": "tsdown --tsconfig tsconfig.build.json --no-dts && tsc -p tsconfig.build.json --emitDeclarationOnly --noCheck"
|
|
53
53
|
}
|
|
54
54
|
}
|
package/lib/helpers.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { isThenable } from './utils.js';
|
|
2
|
-
export { serialForEach, serialReduce } from './utils.js';
|
|
3
|
-
// Type guard to help TypeScript narrow no-arg functions
|
|
4
|
-
function isNoArgFunction(fn) {
|
|
5
|
-
return fn.length === 0;
|
|
6
|
-
}
|
|
7
|
-
export function tryStep(fn, options = {}) {
|
|
8
|
-
// Check if fn takes no arguments (for first step)
|
|
9
|
-
if (isNoArgFunction(fn)) {
|
|
10
|
-
const noInputFn = fn; // Type guard narrows this to () => MaybePromise<R>
|
|
11
|
-
// Even though the function takes no args, the wrapper should accept input for pipe chaining
|
|
12
|
-
// and pass it to fallback/onError
|
|
13
|
-
const resultFn = (input) => {
|
|
14
|
-
try {
|
|
15
|
-
const out = noInputFn();
|
|
16
|
-
if (isThenable(out)) {
|
|
17
|
-
return out.catch((e) => {
|
|
18
|
-
try {
|
|
19
|
-
options.onError?.(e, input);
|
|
20
|
-
}
|
|
21
|
-
catch (onErrorThrown) {
|
|
22
|
-
// Swallow onError errors and continue to fallback
|
|
23
|
-
}
|
|
24
|
-
if (options.rethrow === true) {
|
|
25
|
-
return Promise.reject(e);
|
|
26
|
-
}
|
|
27
|
-
const fb = options.fallback;
|
|
28
|
-
return typeof fb === 'function' ? fb(e, input) : fb;
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
return out;
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
try {
|
|
35
|
-
options.onError?.(e, input);
|
|
36
|
-
}
|
|
37
|
-
catch (onErrorThrown) {
|
|
38
|
-
// Swallow onError errors and continue to fallback
|
|
39
|
-
}
|
|
40
|
-
if (options.rethrow === true) {
|
|
41
|
-
throw e;
|
|
42
|
-
}
|
|
43
|
-
const fb = options.fallback;
|
|
44
|
-
return typeof fb === 'function' ? fb(e, input) : fb;
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
// Cast to match overload return types
|
|
48
|
-
// Overloads say () => MaybePromise<R>, but implementation accepts optional input for fallback/onError
|
|
49
|
-
// At runtime, JavaScript allows calling () => A with an argument, so this works
|
|
50
|
-
// TypeScript sees () => MaybePromise<R> to match pipe's first overload
|
|
51
|
-
if (options.rethrow === true) {
|
|
52
|
-
// Type assertion: TypeScript sees () => MaybePromise<R>, runtime accepts optional input
|
|
53
|
-
return resultFn;
|
|
54
|
-
}
|
|
55
|
-
return resultFn;
|
|
56
|
-
}
|
|
57
|
-
// Original implementation for functions that take input
|
|
58
|
-
const inputFn = fn;
|
|
59
|
-
return (input) => {
|
|
60
|
-
try {
|
|
61
|
-
const out = fn(input);
|
|
62
|
-
if (isThenable(out)) {
|
|
63
|
-
return out.catch((e) => {
|
|
64
|
-
try {
|
|
65
|
-
options.onError?.(e, input);
|
|
66
|
-
}
|
|
67
|
-
catch (onErrorThrown) {
|
|
68
|
-
// Swallow onError errors and continue to fallback
|
|
69
|
-
}
|
|
70
|
-
if (options.rethrow === true) {
|
|
71
|
-
return Promise.reject(e);
|
|
72
|
-
}
|
|
73
|
-
const fb = options.fallback;
|
|
74
|
-
return typeof fb === 'function' ? fb(e, input) : fb;
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
catch (e) {
|
|
80
|
-
try {
|
|
81
|
-
options.onError?.(e, input);
|
|
82
|
-
}
|
|
83
|
-
catch (onErrorThrown) {
|
|
84
|
-
// Swallow onError errors and continue to fallback
|
|
85
|
-
}
|
|
86
|
-
if (options.rethrow === true) {
|
|
87
|
-
throw e;
|
|
88
|
-
}
|
|
89
|
-
const fb = options.fallback;
|
|
90
|
-
return typeof fb === 'function' ? fb(e, input) : fb;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
export function guard(predicate, errorFactory = (v) => new Error('ensure failed')) {
|
|
95
|
-
return (value) => {
|
|
96
|
-
const ok = predicate(value);
|
|
97
|
-
if (isThenable(ok)) {
|
|
98
|
-
return ok.then(passed => {
|
|
99
|
-
if (!passed) {
|
|
100
|
-
throw errorFactory(value);
|
|
101
|
-
}
|
|
102
|
-
return value;
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
if (!ok) {
|
|
106
|
-
throw errorFactory(value);
|
|
107
|
-
}
|
|
108
|
-
return value;
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
//# sourceMappingURL=helpers.js.map
|
package/lib/helpers.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
package/lib/pipe.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { isThenable } from './utils.js';
|
|
2
|
-
function runAsync(v, fns, startIndex) {
|
|
3
|
-
let p = Promise.resolve(v);
|
|
4
|
-
for (let i = startIndex; i < fns.length; i++) {
|
|
5
|
-
const fn = fns[i];
|
|
6
|
-
p = p.then(val => fn(val));
|
|
7
|
-
}
|
|
8
|
-
return p;
|
|
9
|
-
}
|
|
10
|
-
// Note: Intentionally omitting generic varargs overloads to improve contextual typing
|
|
11
|
-
export function pipe(...args) {
|
|
12
|
-
let input;
|
|
13
|
-
let fns;
|
|
14
|
-
if (args.length === 0)
|
|
15
|
-
return undefined;
|
|
16
|
-
const first = args[0];
|
|
17
|
-
const second = args[1];
|
|
18
|
-
const rest = args.slice(1);
|
|
19
|
-
// Disambiguation:
|
|
20
|
-
// - If first and second are both functions → treat as steps-only (no explicit input)
|
|
21
|
-
// - Else if more than one arg → treat first as input (value | Promise | thunk)
|
|
22
|
-
// - Else single function → steps-only
|
|
23
|
-
const stepsOnly = typeof first === 'function' && typeof second === 'function';
|
|
24
|
-
if (stepsOnly) {
|
|
25
|
-
input = undefined;
|
|
26
|
-
fns = args;
|
|
27
|
-
}
|
|
28
|
-
else if (args.length > 1) {
|
|
29
|
-
input = typeof first === 'function' ? first() : first;
|
|
30
|
-
fns = rest;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
input = undefined;
|
|
34
|
-
fns = [first];
|
|
35
|
-
}
|
|
36
|
-
if (isThenable(input)) {
|
|
37
|
-
return runAsync(input, fns, 0);
|
|
38
|
-
}
|
|
39
|
-
for (let i = 0; i < fns.length; i++) {
|
|
40
|
-
const fn = fns[i];
|
|
41
|
-
const out = fn(input);
|
|
42
|
-
if (isThenable(out)) {
|
|
43
|
-
return runAsync(out, fns, i + 1);
|
|
44
|
-
}
|
|
45
|
-
input = out;
|
|
46
|
-
}
|
|
47
|
-
return input;
|
|
48
|
-
}
|
|
49
|
-
function resolveFallback(fb) {
|
|
50
|
-
return typeof fb === 'function' ? fb() : fb;
|
|
51
|
-
}
|
|
52
|
-
function runAsyncSafe(v, fns, startIndex, opts) {
|
|
53
|
-
const { onError, fallback } = opts;
|
|
54
|
-
const callOnError = (e) => {
|
|
55
|
-
try {
|
|
56
|
-
onError?.(e);
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
// Swallow errors from onError to keep guarantees: never throw
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
let p = Promise.resolve(v);
|
|
63
|
-
for (let i = startIndex; i < fns.length; i++) {
|
|
64
|
-
const fn = fns[i];
|
|
65
|
-
p = p.then(val => {
|
|
66
|
-
try {
|
|
67
|
-
return fn(val);
|
|
68
|
-
}
|
|
69
|
-
catch (e) {
|
|
70
|
-
callOnError(e);
|
|
71
|
-
return resolveFallback(fallback);
|
|
72
|
-
}
|
|
73
|
-
}, e => {
|
|
74
|
-
callOnError(e);
|
|
75
|
-
return resolveFallback(fallback);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
return p.catch(e => {
|
|
79
|
-
callOnError(e);
|
|
80
|
-
return resolveFallback(fallback);
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
export function safePipe(...args) {
|
|
84
|
-
let input;
|
|
85
|
-
let options;
|
|
86
|
-
let fns;
|
|
87
|
-
if (args.length === 0)
|
|
88
|
-
return undefined;
|
|
89
|
-
const first = args[0];
|
|
90
|
-
const second = args[1];
|
|
91
|
-
const looksLikeOptions = (x) => !!x && typeof x === 'object' && !Array.isArray(x);
|
|
92
|
-
// Special-case: options-first with no steps should return undefined
|
|
93
|
-
if (args.length === 1 && !!first && typeof first === 'object') {
|
|
94
|
-
return undefined;
|
|
95
|
-
}
|
|
96
|
-
const bothFns = typeof first === 'function' && typeof second === 'function';
|
|
97
|
-
if (looksLikeOptions(first) || bothFns) {
|
|
98
|
-
// options-first or steps-only (no explicit input)
|
|
99
|
-
input = undefined;
|
|
100
|
-
options = looksLikeOptions(first) ? first : {};
|
|
101
|
-
fns = (looksLikeOptions(first) ? args.slice(1) : args);
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
throw new TypeError('safePipe requires steps-only or options-first with steps');
|
|
105
|
-
}
|
|
106
|
-
input = undefined;
|
|
107
|
-
for (let i = 0; i < fns.length; i++) {
|
|
108
|
-
const fn = fns[i];
|
|
109
|
-
try {
|
|
110
|
-
const out = fn(input);
|
|
111
|
-
if (isThenable(out)) {
|
|
112
|
-
return runAsyncSafe(out, fns, i + 1, options);
|
|
113
|
-
}
|
|
114
|
-
input = out;
|
|
115
|
-
}
|
|
116
|
-
catch (e) {
|
|
117
|
-
try {
|
|
118
|
-
options?.onError?.(e);
|
|
119
|
-
}
|
|
120
|
-
catch { }
|
|
121
|
-
return resolveFallback(options?.fallback);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return input;
|
|
125
|
-
}
|
|
126
|
-
//# sourceMappingURL=pipe.js.map
|
package/lib/pipe.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pipe.js","sourceRoot":"","sources":["../src/pipe.ts"],"names":[],"mappings":"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"}
|
package/lib/utils.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
export function isThenable(x) {
|
|
2
|
-
return !!x && (typeof x === 'object' || typeof x === 'function') && typeof x.then === 'function';
|
|
3
|
-
}
|
|
4
|
-
export function isPromise(x) {
|
|
5
|
-
return !!x && typeof x === 'object' && typeof x.then === 'function' && typeof x.catch === 'function';
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Serial forEach over an array where the step may return a Promise.
|
|
9
|
-
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
10
|
-
*/
|
|
11
|
-
export function serialForEach(items, step) {
|
|
12
|
-
for (let i = 0; i < items.length; i++) {
|
|
13
|
-
const out = step(items[i], i);
|
|
14
|
-
if (isThenable(out)) {
|
|
15
|
-
return (async () => {
|
|
16
|
-
await out;
|
|
17
|
-
for (let j = i + 1; j < items.length; j++) {
|
|
18
|
-
await step(items[j], j);
|
|
19
|
-
}
|
|
20
|
-
return undefined;
|
|
21
|
-
})();
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return undefined;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Serial reduce over an array where the step may return a Promise.
|
|
28
|
-
* Runs synchronously until an async step is encountered, then switches to async for the remainder.
|
|
29
|
-
*/
|
|
30
|
-
export function serialReduce(items, seed, step) {
|
|
31
|
-
let acc = seed;
|
|
32
|
-
for (let i = 0; i < items.length; i++) {
|
|
33
|
-
const out = step(acc, items[i], i);
|
|
34
|
-
if (isThenable(out)) {
|
|
35
|
-
return (async () => {
|
|
36
|
-
acc = await out;
|
|
37
|
-
for (let j = i + 1; j < items.length; j++) {
|
|
38
|
-
acc = await step(acc, items[j], j);
|
|
39
|
-
}
|
|
40
|
-
return acc;
|
|
41
|
-
})();
|
|
42
|
-
}
|
|
43
|
-
acc = out;
|
|
44
|
-
}
|
|
45
|
-
return acc;
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=utils.js.map
|
package/lib/utils.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,UAAU,CAAC,IAAI,OAAQ,CAAS,CAAC,IAAI,KAAK,UAAU,CAAC;AAC5G,CAAC;AAED,MAAM,UAAU,SAAS,CAAc,CAAU;IAC/C,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAQ,CAAS,CAAC,IAAI,KAAK,UAAU,IAAI,OAAQ,CAAS,CAAC,KAAK,KAAK,UAAU,CAAC;AACzH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAI,KAAmB,EAAE,IAAgE;IACpH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC;QAC/B,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,IAAI,EAAE;gBACjB,MAAM,GAAG,CAAC;gBACV,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1C,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC;gBAC3B,CAAC;gBACD,OAAO,SAAS,CAAC;YACnB,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAO,KAAmB,EAAE,IAAO,EAAE,IAAyD;IACxH,IAAI,GAAG,GAAG,IAAI,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC;QACpC,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,OAAO,CAAC,KAAK,IAAI,EAAE;gBACjB,GAAG,GAAG,MAAM,GAAQ,CAAC;gBACrB,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1C,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,CAAC,CAAM,CAAC;gBAC3C,CAAC;gBACD,OAAO,GAAG,CAAC;YACb,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QACD,GAAG,GAAG,GAAQ,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|