ppipe 2.6.5 → 3.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/LICENSE +13 -13
- package/README.md +273 -329
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/pipe.d.ts +3 -0
- package/dist/pipe.d.ts.map +1 -0
- package/dist/pipe.js +211 -0
- package/dist/pipe.js.map +1 -0
- package/dist/placeholder.d.ts +4 -0
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/placeholder.js +26 -0
- package/dist/placeholder.js.map +1 -0
- package/dist/types.d.ts +46 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/package.json +65 -38
- package/.eslintrc.js +0 -223
- package/.github/CONTRIBUTING.md +0 -13
- package/.github/ISSUE_TEMPLATE.md +0 -17
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -30
- package/.travis.yml +0 -4
- package/CODE_OF_CONDUCT.md +0 -46
- package/logo/logo_s.png +0 -0
- package/prettier.config.js +0 -8
- package/src/getPropertyByPath.js +0 -35
- package/src/index.js +0 -159
- package/src/lib/isFunction.js +0 -1
- package/src/lib/isPromise.js +0 -3
- package/test/examples.js +0 -175
- package/test/test.js +0 -603
package/LICENSE
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
Copyright 2020 Yavuz Ege Özcan
|
|
2
|
-
|
|
3
|
-
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
4
|
-
with or without fee is hereby granted, provided that the above copyright notice
|
|
5
|
-
and this permission notice appear in all copies.
|
|
6
|
-
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9
|
-
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
|
10
|
-
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
11
|
-
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
12
|
-
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
13
|
-
SOFTWARE.
|
|
1
|
+
Copyright 2020 Yavuz Ege Özcan
|
|
2
|
+
|
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose
|
|
4
|
+
with or without fee is hereby granted, provided that the above copyright notice
|
|
5
|
+
and this permission notice appear in all copies.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
8
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
9
|
+
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
|
|
10
|
+
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
11
|
+
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
12
|
+
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
13
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,329 +1,273 @@
|
|
|
1
|
-
# [](https://github.com/egeozcan/ppipe)
|
|
2
|
-
|
|
3
|
-
[](https://travis-ci.org/egeozcan/ppipe)
|
|
4
|
-
[](https://coveralls.io/github/egeozcan/ppipe?branch=master)
|
|
5
|
-
[](https://www.npmjs.com/package/ppipe)
|
|
6
|
-
[](https://www.npmjs.com/package/ppipe)
|
|
7
|
-
[](https://github.com/egeozcan/ppipe/blob/master/LICENSE)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
.pipe(
|
|
75
|
-
.
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
function
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
async function
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.pipe(
|
|
96
|
-
.pipe(
|
|
97
|
-
.
|
|
98
|
-
.
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
.
|
|
127
|
-
.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
.
|
|
137
|
-
.
|
|
138
|
-
.
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
ppipe(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
###
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
You can also call `.extend` on the extended ppipes. It will create a new ppipe
|
|
275
|
-
with the new and existing extensions merged.
|
|
276
|
-
|
|
277
|
-
## Testing
|
|
278
|
-
|
|
279
|
-
All the functionality is tested, with 100% coverage. This is also integrated in the build process.
|
|
280
|
-
|
|
281
|
-
To run the tests yourself, clone the repository, install the dev dependencies, and run the npm test command.
|
|
282
|
-
|
|
283
|
-
`npm install`
|
|
284
|
-
|
|
285
|
-
`npm test`
|
|
286
|
-
|
|
287
|
-
## Contributing
|
|
288
|
-
|
|
289
|
-
See
|
|
290
|
-
[CONTRIBUTING](https://github.com/egeozcan/ppipe/blob/master/.github/CONTRIBUTING.md).
|
|
291
|
-
|
|
292
|
-
## Changelog
|
|
293
|
-
|
|
294
|
-
* v2.5.0 - placeholder can be the only argument to the .pipe, for just extracting a property or path
|
|
295
|
-
* v2.4.0 - allow deep property extraction via the placeholder
|
|
296
|
-
(\_.deeply.nested.prop) (test: should be able to extract array members)
|
|
297
|
-
* v2.3.0 - now supports expanding the placeholder (...\_) (test: should support
|
|
298
|
-
expanding the array result)
|
|
299
|
-
|
|
300
|
-
## Caveats
|
|
301
|
-
|
|
302
|
-
* This library was not written with performance in mind. So, it makes next to no
|
|
303
|
-
sense to use it in, say, a tight loop. Use in a web-server should be fine as
|
|
304
|
-
long as you don't have tight response-time requirements. General rule of
|
|
305
|
-
thumb: Test it before putting it into prod. There are a lot of tests written
|
|
306
|
-
for ppipe but none of them measure performance. I may improve the performance
|
|
307
|
-
in the future (some low-hanging fruits) but I'd rather avoid making any
|
|
308
|
-
guarantees. Well, there is one good news:
|
|
309
|
-
[Chrome team is working on performance improvements to the Proxy](https://v8project.blogspot.de/2017/10/optimizing-proxies.html)
|
|
310
|
-
which will very positively affect ppipe performance.
|
|
311
|
-
|
|
312
|
-
* It uses ES6 Proxies to do its magic. Proxies are not back-portable. 1.x.x
|
|
313
|
-
versions of ppipe didn't use proxies. So you can try using an older version
|
|
314
|
-
with a transpiler if evergreen sounds alien to you.
|
|
315
|
-
[Here](https://github.com/egeozcan/ppipe/blob/1888e9269be90f549d5c00002f7e800598c6d539/index.js)
|
|
316
|
-
is an older stable version without value extracting and context change
|
|
317
|
-
support.
|
|
318
|
-
|
|
319
|
-
* ppipe is not typed. No type definition exists for TypeScript nor Flow. I
|
|
320
|
-
actually love TypeScript and would support it but the lack of variadic generic
|
|
321
|
-
type parameters make it next to impossible to provide type definitions for
|
|
322
|
-
ppipe. More can be read
|
|
323
|
-
[here](https://github.com/Microsoft/TypeScript/issues/5453). Also, ppipe is as
|
|
324
|
-
dynamic as it gets, giving the ability to access virtual properties/methods
|
|
325
|
-
which may belong to the provided context, the processed value or any of the
|
|
326
|
-
possible extensions.
|
|
327
|
-
[TypeScripts Type System is Turing Complete](https://github.com/Microsoft/TypeScript/issues/14833),
|
|
328
|
-
so, maybe there is a way to type all of this but I really need help about
|
|
329
|
-
that.
|
|
1
|
+
# [](https://github.com/egeozcan/ppipe)
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/egeozcan/ppipe)
|
|
4
|
+
[](https://coveralls.io/github/egeozcan/ppipe?branch=master)
|
|
5
|
+
[](https://www.npmjs.com/package/ppipe)
|
|
6
|
+
[](https://www.npmjs.com/package/ppipe)
|
|
7
|
+
[](https://github.com/egeozcan/ppipe/blob/master/LICENSE)
|
|
8
|
+
|
|
9
|
+
**Strictly-typed pipes for values through functions**, an alternative to using the
|
|
10
|
+
[proposed pipe operator](https://github.com/tc39/proposal-pipeline-operator) ( |> ) for ES.
|
|
11
|
+
|
|
12
|
+
Version 3.0 is a complete TypeScript rewrite with **maximum type safety** - no `any` in the public API, full IDE autocomplete support, and correct type inference throughout the chain.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install ppipe
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import ppipe, { _ } from 'ppipe';
|
|
24
|
+
|
|
25
|
+
const add = (x: number, y: number) => x + y;
|
|
26
|
+
const square = (x: number) => x * x;
|
|
27
|
+
const divide = (x: number, y: number) => x / y;
|
|
28
|
+
const double = (x: number) => x * 2;
|
|
29
|
+
|
|
30
|
+
// Basic piping
|
|
31
|
+
const result = ppipe(1)
|
|
32
|
+
.pipe(add, _, 1) // 2
|
|
33
|
+
.pipe(double) // 4
|
|
34
|
+
.pipe(square) // 16
|
|
35
|
+
.pipe(divide, _, 8) // 2
|
|
36
|
+
.pipe(add, _, 1) // 3
|
|
37
|
+
.value;
|
|
38
|
+
|
|
39
|
+
console.log(result); // 3
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
### Basic Piping
|
|
45
|
+
|
|
46
|
+
Chain functions together, passing the result of each to the next:
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
ppipe('hello')
|
|
50
|
+
.pipe(s => s.toUpperCase())
|
|
51
|
+
.pipe(s => s + '!')
|
|
52
|
+
.value; // 'HELLO!'
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Placeholder Positioning
|
|
56
|
+
|
|
57
|
+
Use `_` to control where the piped value is inserted:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const _ = ppipe._;
|
|
61
|
+
|
|
62
|
+
// Value inserted at placeholder position
|
|
63
|
+
ppipe(10)
|
|
64
|
+
.pipe(divide, _, 2) // divide(10, 2) = 5
|
|
65
|
+
.value;
|
|
66
|
+
|
|
67
|
+
// Without placeholder, value is appended at the end
|
|
68
|
+
ppipe(10)
|
|
69
|
+
.pipe(divide, 100) // divide(100, 10) = 10
|
|
70
|
+
.value;
|
|
71
|
+
|
|
72
|
+
// Multiple placeholders insert the same value multiple times
|
|
73
|
+
ppipe(5)
|
|
74
|
+
.pipe((a, b) => a + b, _, _) // 5 + 5 = 10
|
|
75
|
+
.value;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Async/Promise Support
|
|
79
|
+
|
|
80
|
+
Promises are automatically handled - the chain waits for resolution and passes the unwrapped value to the next function:
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
async function fetchUser(id: number) {
|
|
84
|
+
const response = await fetch(`/api/users/${id}`);
|
|
85
|
+
return response.json();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const userName = await ppipe(1)
|
|
89
|
+
.pipe(fetchUser)
|
|
90
|
+
.pipe(user => user.name)
|
|
91
|
+
.pipe(name => name.toUpperCase());
|
|
92
|
+
|
|
93
|
+
// Or use .then()/.catch()
|
|
94
|
+
ppipe(1)
|
|
95
|
+
.pipe(fetchUser)
|
|
96
|
+
.pipe(user => user.name)
|
|
97
|
+
.then(name => console.log(name))
|
|
98
|
+
.catch(err => console.error(err));
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Value Extraction
|
|
102
|
+
|
|
103
|
+
Get the current value with `.value` (or `.val`):
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
// Sync value
|
|
107
|
+
const num = ppipe(5).pipe(x => x * 2).value; // 10
|
|
108
|
+
|
|
109
|
+
// Async value (returns Promise)
|
|
110
|
+
const asyncNum = await ppipe(Promise.resolve(5)).pipe(x => x * 2).value;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Typed Extensions
|
|
114
|
+
|
|
115
|
+
Create reusable pipe extensions with full type inference:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const mathPipe = ppipe.extend({
|
|
119
|
+
double: (x: number) => x * 2,
|
|
120
|
+
square: (x: number) => x * x,
|
|
121
|
+
add: (x: number, y: number) => x + y,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const result = mathPipe(5)
|
|
125
|
+
.double() // 10 - return type inferred as number
|
|
126
|
+
.square() // 100
|
|
127
|
+
.add(5) // 105
|
|
128
|
+
.value;
|
|
129
|
+
|
|
130
|
+
// Extensions can be chained
|
|
131
|
+
const extendedPipe = mathPipe.extend({
|
|
132
|
+
stringify: (x: number) => String(x),
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const str = extendedPipe(5)
|
|
136
|
+
.double()
|
|
137
|
+
.stringify() // '10' - return type inferred as string
|
|
138
|
+
.value;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## API Reference
|
|
142
|
+
|
|
143
|
+
### `ppipe(value)`
|
|
144
|
+
|
|
145
|
+
Creates a new pipe with the given initial value.
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const pipe = ppipe(initialValue);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### `.pipe(fn, ...args)`
|
|
152
|
+
|
|
153
|
+
Pipes the current value through a function. The value is inserted at the placeholder position, or appended at the end if no placeholder is used.
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
pipe.pipe(fn) // fn(value)
|
|
157
|
+
pipe.pipe(fn, _, arg2) // fn(value, arg2)
|
|
158
|
+
pipe.pipe(fn, arg1) // fn(arg1, value)
|
|
159
|
+
pipe.pipe(fn, arg1, _) // fn(arg1, value)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### `.value` / `.val`
|
|
163
|
+
|
|
164
|
+
Gets the current value from the chain. Returns a Promise if any function in the chain was async.
|
|
165
|
+
|
|
166
|
+
### `.then(onFulfilled?, onRejected?)`
|
|
167
|
+
|
|
168
|
+
Standard Promise `then` interface. Always available for consistent async handling.
|
|
169
|
+
|
|
170
|
+
### `.catch(onRejected?)`
|
|
171
|
+
|
|
172
|
+
Standard Promise `catch` interface. Always available for consistent async handling.
|
|
173
|
+
|
|
174
|
+
### `ppipe._`
|
|
175
|
+
|
|
176
|
+
The placeholder symbol for argument positioning.
|
|
177
|
+
|
|
178
|
+
### `ppipe.extend(extensions)`
|
|
179
|
+
|
|
180
|
+
Creates a new ppipe factory with additional methods:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
const extended = ppipe.extend({
|
|
184
|
+
methodName: (value, ...args) => result,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Extension functions receive the piped value as their first argument.
|
|
189
|
+
|
|
190
|
+
## Migration from v2.x
|
|
191
|
+
|
|
192
|
+
Version 3.0 is a TypeScript rewrite that prioritizes type safety. Some dynamic features that couldn't be strictly typed have been removed:
|
|
193
|
+
|
|
194
|
+
### Removed Features
|
|
195
|
+
|
|
196
|
+
| Feature | v2.x | v3.x Alternative |
|
|
197
|
+
|---------|------|------------------|
|
|
198
|
+
| Deep property access | `_.a.b.c` | `.pipe(x => x.a.b.c)` |
|
|
199
|
+
| Array spreading | `..._` | `.pipe(arr => fn(...arr))` |
|
|
200
|
+
| Direct method access | `.map(fn)` | `.pipe(arr => arr.map(fn))` |
|
|
201
|
+
| Context binding | `.with(ctx)` | `.pipe(fn.bind(ctx))` |
|
|
202
|
+
| Callable syntax | `ppipe(val)(fn)` | `ppipe(val).pipe(fn)` |
|
|
203
|
+
|
|
204
|
+
### Why These Changes?
|
|
205
|
+
|
|
206
|
+
These features relied on Proxy magic that returned `any` types, breaking TypeScript's ability to infer types correctly. The v3.x API ensures:
|
|
207
|
+
|
|
208
|
+
- Full IDE autocomplete support
|
|
209
|
+
- Correct type inference throughout the chain
|
|
210
|
+
- No `any` types in the public API
|
|
211
|
+
- Compile-time error detection
|
|
212
|
+
|
|
213
|
+
## Type Safety
|
|
214
|
+
|
|
215
|
+
ppipe v3.x provides complete type inference:
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// Types are inferred correctly through the chain
|
|
219
|
+
const result = ppipe(5)
|
|
220
|
+
.pipe(x => x * 2) // Pipe<number>
|
|
221
|
+
.pipe(x => x.toString()) // Pipe<string>
|
|
222
|
+
.pipe(x => x.length) // Pipe<number>
|
|
223
|
+
.value; // number
|
|
224
|
+
|
|
225
|
+
// Async types are tracked
|
|
226
|
+
const asyncResult = ppipe(Promise.resolve(5))
|
|
227
|
+
.pipe(x => x * 2) // Pipe<number, async=true>
|
|
228
|
+
.value; // Promise<number>
|
|
229
|
+
|
|
230
|
+
// Extension return types are inferred
|
|
231
|
+
const myPipe = ppipe.extend({
|
|
232
|
+
toArray: <T>(x: T) => [x],
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
myPipe(5).toArray().value; // number[]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Testing
|
|
239
|
+
|
|
240
|
+
100% test coverage is maintained. To run tests:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
npm install
|
|
244
|
+
npm test
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Contributing
|
|
248
|
+
|
|
249
|
+
See [CONTRIBUTING](https://github.com/egeozcan/ppipe/blob/master/.github/CONTRIBUTING.md).
|
|
250
|
+
|
|
251
|
+
## Changelog
|
|
252
|
+
|
|
253
|
+
### v3.0.0
|
|
254
|
+
|
|
255
|
+
- Complete TypeScript rewrite with strict typing
|
|
256
|
+
- Full IDE autocomplete and type inference support
|
|
257
|
+
- Removed features that couldn't be strictly typed (see Migration section)
|
|
258
|
+
- 100% test coverage on source files
|
|
259
|
+
- Strict ESLint rules disable all TypeScript escape hatches:
|
|
260
|
+
- No `any` types
|
|
261
|
+
- No type assertions (`as`)
|
|
262
|
+
- No ts-ignore/ts-expect-error comments
|
|
263
|
+
- No non-null assertions (`!`)
|
|
264
|
+
- Discriminated union state management for type-safe async/sync/error handling
|
|
265
|
+
- Updated all dependencies to latest versions
|
|
266
|
+
|
|
267
|
+
### v2.x
|
|
268
|
+
|
|
269
|
+
See [v2.x README](https://github.com/egeozcan/ppipe/tree/v2.6.5) for previous features.
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
ISC
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PipeFactory } from "./types.js";
|
|
2
|
+
import { _ } from "./placeholder.js";
|
|
3
|
+
export type { Extensions, Pipe, PipeFactory, PipeWithExtensions, PlaceholderType } from "./types.js";
|
|
4
|
+
export { isPlaceholder } from "./placeholder.js";
|
|
5
|
+
declare const ppipe: PipeFactory<{}>;
|
|
6
|
+
export { _ };
|
|
7
|
+
export default ppipe;
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,WAAW,EAA+B,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AAIrC,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACrG,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AA+BjD,QAAA,MAAM,KAAK,iBAAkB,CAAC;AAG9B,OAAO,EAAE,CAAC,EAAE,CAAC;AAGb,eAAe,KAAK,CAAC"}
|