fp-pack 0.5.0 → 0.7.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.
Files changed (82) hide show
  1. package/README.md +17 -15
  2. package/dist/fp-pack.umd.js +1 -1
  3. package/dist/fp-pack.umd.js.map +1 -1
  4. package/dist/implement/async/pipeAsync.d.ts +11 -0
  5. package/dist/implement/async/pipeAsync.d.ts.map +1 -1
  6. package/dist/implement/async/pipeAsync.mjs.map +1 -1
  7. package/dist/implement/async/pipeAsyncSideEffect.d.ts +11 -0
  8. package/dist/implement/async/pipeAsyncSideEffect.d.ts.map +1 -1
  9. package/dist/implement/async/pipeAsyncSideEffect.mjs.map +1 -1
  10. package/dist/implement/composition/compose.d.ts +25 -9
  11. package/dist/implement/composition/compose.d.ts.map +1 -1
  12. package/dist/implement/composition/compose.mjs.map +1 -1
  13. package/dist/implement/composition/compose.type-test.d.ts +35 -0
  14. package/dist/implement/composition/compose.type-test.d.ts.map +1 -0
  15. package/dist/implement/composition/compose.util.type-test.d.ts +31 -0
  16. package/dist/implement/composition/compose.util.type-test.d.ts.map +1 -0
  17. package/dist/implement/composition/curry.d.ts +5 -5
  18. package/dist/implement/composition/curry.d.ts.map +1 -1
  19. package/dist/implement/composition/curry.mjs.map +1 -1
  20. package/dist/implement/composition/index.d.ts +4 -0
  21. package/dist/implement/composition/index.d.ts.map +1 -1
  22. package/dist/implement/composition/pipe.d.ts +3 -0
  23. package/dist/implement/composition/pipe.d.ts.map +1 -1
  24. package/dist/implement/composition/pipe.mjs.map +1 -1
  25. package/dist/implement/composition/pipe.type-test.d.ts +117 -1
  26. package/dist/implement/composition/pipe.type-test.d.ts.map +1 -1
  27. package/dist/implement/composition/pipe.util.type-test.d.ts +75 -0
  28. package/dist/implement/composition/pipe.util.type-test.d.ts.map +1 -0
  29. package/dist/implement/composition/sideEffect.d.ts +1 -1
  30. package/dist/implement/composition/sideEffect.d.ts.map +1 -1
  31. package/dist/implement/composition/sideEffect.mjs.map +1 -1
  32. package/dist/implement/composition/tap0.d.ts +6 -0
  33. package/dist/implement/composition/tap0.d.ts.map +1 -0
  34. package/dist/implement/composition/tap0.mjs +9 -0
  35. package/dist/implement/composition/tap0.mjs.map +1 -0
  36. package/dist/implement/object/assocPath.d.ts +2 -1
  37. package/dist/implement/object/assocPath.d.ts.map +1 -1
  38. package/dist/implement/object/assocPath.mjs.map +1 -1
  39. package/dist/implement/object/dissocPath.d.ts +2 -1
  40. package/dist/implement/object/dissocPath.d.ts.map +1 -1
  41. package/dist/implement/object/dissocPath.mjs.map +1 -1
  42. package/dist/implement/object/index.d.ts +1 -0
  43. package/dist/implement/object/index.d.ts.map +1 -1
  44. package/dist/implement/object/path.d.ts +4 -2
  45. package/dist/implement/object/path.d.ts.map +1 -1
  46. package/dist/implement/object/path.mjs.map +1 -1
  47. package/dist/implement/object/pathKey.d.ts +2 -0
  48. package/dist/implement/object/pathKey.d.ts.map +1 -0
  49. package/dist/implement/object/pathOr.d.ts +5 -3
  50. package/dist/implement/object/pathOr.d.ts.map +1 -1
  51. package/dist/implement/object/pathOr.mjs.map +1 -1
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.mjs +230 -228
  55. package/dist/index.mjs.map +1 -1
  56. package/dist/skills/fp-pack/SKILL.md +19 -16
  57. package/dist/skills/fp-pack.md +19 -16
  58. package/dist/stream/index.d.ts +1 -0
  59. package/dist/stream/index.d.ts.map +1 -1
  60. package/package.json +1 -1
  61. package/src/implement/async/pipeAsync.ts +71 -0
  62. package/src/implement/async/pipeAsyncSideEffect.ts +74 -0
  63. package/src/implement/composition/compose.test.ts +14 -0
  64. package/src/implement/composition/compose.ts +133 -21
  65. package/src/implement/composition/compose.type-test.ts +109 -0
  66. package/src/implement/composition/compose.util.type-test.ts +128 -0
  67. package/src/implement/composition/curry.ts +5 -5
  68. package/src/implement/composition/index.ts +4 -0
  69. package/src/implement/composition/pipe.ts +4 -0
  70. package/src/implement/composition/pipe.type-test.ts +269 -1
  71. package/src/implement/composition/pipe.util.type-test.ts +256 -0
  72. package/src/implement/composition/sideEffect.ts +1 -1
  73. package/src/implement/composition/tap0.test.ts +16 -0
  74. package/src/implement/composition/tap0.ts +10 -0
  75. package/src/implement/object/assocPath.ts +2 -2
  76. package/src/implement/object/dissocPath.ts +2 -2
  77. package/src/implement/object/index.ts +1 -0
  78. package/src/implement/object/path.ts +5 -3
  79. package/src/implement/object/pathKey.ts +1 -0
  80. package/src/implement/object/pathOr.ts +6 -4
  81. package/src/index.ts +3 -0
  82. package/src/stream/index.ts +1 -0
@@ -1,4 +1,4 @@
1
- import SideEffect from './sideEffect';
1
+ import SideEffect, { runPipeResult } from './sideEffect';
2
2
  import from from './from';
3
3
  import pipe from './pipe';
4
4
  import pipeSideEffect from './pipeSideEffect';
@@ -25,6 +25,21 @@ export const purePipe = pipe(
25
25
  type PurePipeExpected = (input: number) => string;
26
26
  export type PipePureIsStrict = Expect<Equal<typeof purePipe, PurePipeExpected>>;
27
27
 
28
+ export const purePipeZero = pipe(() => 3, (value: number) => value + 1);
29
+
30
+ type PurePipeZeroExpected = () => number;
31
+ export type PipePureZeroIsStrict = Expect<Equal<typeof purePipeZero, PurePipeZeroExpected>>;
32
+
33
+ export const purePipeZeroValue = purePipeZero();
34
+
35
+ type PurePipeZeroValueExpected = number;
36
+ export type PipePureZeroValueIsStrict = Expect<Equal<typeof purePipeZeroValue, PurePipeZeroValueExpected>>;
37
+
38
+ export const purePipeValue = purePipe(1);
39
+
40
+ type PurePipeValueExpected = string;
41
+ export type PipePureValueIsStrict = Expect<Equal<typeof purePipeValue, PurePipeValueExpected>>;
42
+
28
43
  export const purePipeSix = pipe(
29
44
  (value: number) => value + 1,
30
45
  (value) => value * 2,
@@ -71,6 +86,23 @@ export const pipeFromTenValue = pipeFromTen('input');
71
86
  type PipeFromTenValueExpected = string;
72
87
  export type PipeFromTenValueIsStrict = Expect<Equal<typeof pipeFromTenValue, PipeFromTenValueExpected>>;
73
88
 
89
+ export const pipeFromTenValueNoInput = pipeFromTen();
90
+
91
+ type PipeFromTenValueNoInputExpected = string;
92
+ export type PipeFromTenValueNoInputIsStrict = Expect<
93
+ Equal<typeof pipeFromTenValueNoInput, PipeFromTenValueNoInputExpected>
94
+ >;
95
+
96
+ export const pipeFromNoInput = pipe(from(1));
97
+
98
+ type PipeFromNoInputExpected = (input?: unknown) => number;
99
+ export type PipeFromNoInputIsStrict = Expect<Equal<typeof pipeFromNoInput, PipeFromNoInputExpected>>;
100
+
101
+ export const pipeFromNoInputValue = pipeFromNoInput();
102
+
103
+ type PipeFromNoInputValueExpected = number;
104
+ export type PipeFromNoInputValueIsStrict = Expect<Equal<typeof pipeFromNoInputValue, PipeFromNoInputValueExpected>>;
105
+
74
106
  export const pipeWithSideEffectInput = pipeSideEffect(
75
107
  (value: number) => value + 1,
76
108
  (value) => value * 2,
@@ -82,6 +114,25 @@ export const pipeWithSideEffectValue = pipeWithSideEffectInput(sideEffectInput);
82
114
  type PipeExpected = (input: number | SideEffect<any>) => string | SideEffect<any>;
83
115
  export type PipeAcceptsSideEffectInput = Expect<Equal<typeof pipeWithSideEffectInput, PipeExpected>>;
84
116
 
117
+ export const pipeSideEffectZero = pipeSideEffect(() => 1, (value: number) => value + 1);
118
+
119
+ type PipeSideEffectZeroExpected = () => number | SideEffect<any>;
120
+ export type PipeSideEffectZeroIsStrict = Expect<Equal<typeof pipeSideEffectZero, PipeSideEffectZeroExpected>>;
121
+
122
+ export const pipeSideEffectZeroValue = pipeSideEffectZero();
123
+
124
+ type PipeSideEffectZeroValueExpected = number | SideEffect<any>;
125
+ export type PipeSideEffectZeroValueIsStrict = Expect<
126
+ Equal<typeof pipeSideEffectZeroValue, PipeSideEffectZeroValueExpected>
127
+ >;
128
+
129
+ export const pipeWithSideEffectValueInput = pipeWithSideEffectInput(1);
130
+
131
+ type PipeWithSideEffectValueInputExpected = string | SideEffect<any>;
132
+ export type PipeSideEffectValueInputIsStrict = Expect<
133
+ Equal<typeof pipeWithSideEffectValueInput, PipeWithSideEffectValueInputExpected>
134
+ >;
135
+
85
136
  export const pipeSideEffectSix = pipeSideEffect(
86
137
  (value: number) => value + 1,
87
138
  (value) => value * 2,
@@ -137,6 +188,20 @@ export type PipeSideEffectFromTenValueNoInputIsStrict = Expect<
137
188
  Equal<typeof pipeSideEffectFromTenValueNoInput, PipeSideEffectFromTenValueNoInputExpected>
138
189
  >;
139
190
 
191
+ export const pipeSideEffectFromNoInput = pipeSideEffect(from(1));
192
+
193
+ type PipeSideEffectFromNoInputExpected = (input?: unknown) => number | SideEffect<any>;
194
+ export type PipeSideEffectFromNoInputIsStrict = Expect<
195
+ Equal<typeof pipeSideEffectFromNoInput, PipeSideEffectFromNoInputExpected>
196
+ >;
197
+
198
+ export const pipeSideEffectFromNoInputValue = pipeSideEffectFromNoInput();
199
+
200
+ type PipeSideEffectFromNoInputValueExpected = number | SideEffect<any>;
201
+ export type PipeSideEffectFromNoInputValueIsStrict = Expect<
202
+ Equal<typeof pipeSideEffectFromNoInputValue, PipeSideEffectFromNoInputValueExpected>
203
+ >;
204
+
140
205
  export const purePipeAsync = pipeAsync(
141
206
  (value: number) => value + 1,
142
207
  async (value) => value * 2,
@@ -146,6 +211,23 @@ export const purePipeAsync = pipeAsync(
146
211
  type PurePipeAsyncExpected = (input: number) => Promise<string>;
147
212
  export type PipeAsyncPureIsStrict = Expect<Equal<typeof purePipeAsync, PurePipeAsyncExpected>>;
148
213
 
214
+ export const purePipeAsyncZero = pipeAsync(() => 1, async (value: number) => value + 1);
215
+
216
+ type PurePipeAsyncZeroExpected = () => Promise<number>;
217
+ export type PipeAsyncPureZeroIsStrict = Expect<Equal<typeof purePipeAsyncZero, PurePipeAsyncZeroExpected>>;
218
+
219
+ export const purePipeAsyncZeroValue = purePipeAsyncZero();
220
+
221
+ type PurePipeAsyncZeroValueExpected = Promise<number>;
222
+ export type PipeAsyncPureZeroValueIsStrict = Expect<
223
+ Equal<typeof purePipeAsyncZeroValue, PurePipeAsyncZeroValueExpected>
224
+ >;
225
+
226
+ export const purePipeAsyncValue = purePipeAsync(1);
227
+
228
+ type PurePipeAsyncValueExpected = Promise<string>;
229
+ export type PipeAsyncPureValueIsStrict = Expect<Equal<typeof purePipeAsyncValue, PurePipeAsyncValueExpected>>;
230
+
149
231
  export const purePipeAsyncSix = pipeAsync(
150
232
  (value: number) => value + 1,
151
233
  async (value) => value * 2,
@@ -201,6 +283,18 @@ export type PipeAsyncFromTenValueNoInputIsStrict = Expect<
201
283
  Equal<typeof pipeAsyncFromTenValueNoInput, PipeAsyncFromTenValueNoInputExpected>
202
284
  >;
203
285
 
286
+ export const pipeAsyncFromNoInput = pipeAsync(from(1));
287
+
288
+ type PipeAsyncFromNoInputExpected = (input?: unknown) => Promise<number>;
289
+ export type PipeAsyncFromNoInputIsStrict = Expect<Equal<typeof pipeAsyncFromNoInput, PipeAsyncFromNoInputExpected>>;
290
+
291
+ export const pipeAsyncFromNoInputValue = pipeAsyncFromNoInput();
292
+
293
+ type PipeAsyncFromNoInputValueExpected = Promise<number>;
294
+ export type PipeAsyncFromNoInputValueIsStrict = Expect<
295
+ Equal<typeof pipeAsyncFromNoInputValue, PipeAsyncFromNoInputValueExpected>
296
+ >;
297
+
204
298
  export const pipeAsyncWithSideEffectInput = pipeAsyncSideEffect(
205
299
  (value: number) => value + 1,
206
300
  async (value) => value * 2,
@@ -214,6 +308,27 @@ export type PipeAsyncAcceptsSideEffectInput = Expect<
214
308
  Equal<typeof pipeAsyncWithSideEffectInput, PipeAsyncExpected>
215
309
  >;
216
310
 
311
+ export const pipeAsyncSideEffectZero = pipeAsyncSideEffect(() => 1, async (value: number) => value + 1);
312
+
313
+ type PipeAsyncSideEffectZeroExpected = () => Promise<number | SideEffect<any>>;
314
+ export type PipeAsyncSideEffectZeroIsStrict = Expect<
315
+ Equal<typeof pipeAsyncSideEffectZero, PipeAsyncSideEffectZeroExpected>
316
+ >;
317
+
318
+ export const pipeAsyncSideEffectZeroValue = pipeAsyncSideEffectZero();
319
+
320
+ type PipeAsyncSideEffectZeroValueExpected = Promise<number | SideEffect<any>>;
321
+ export type PipeAsyncSideEffectZeroValueIsStrict = Expect<
322
+ Equal<typeof pipeAsyncSideEffectZeroValue, PipeAsyncSideEffectZeroValueExpected>
323
+ >;
324
+
325
+ export const pipeAsyncWithSideEffectValueInput = pipeAsyncWithSideEffectInput(1);
326
+
327
+ type PipeAsyncWithSideEffectValueInputExpected = Promise<string | SideEffect<any>>;
328
+ export type PipeAsyncSideEffectValueInputIsStrict = Expect<
329
+ Equal<typeof pipeAsyncWithSideEffectValueInput, PipeAsyncWithSideEffectValueInputExpected>
330
+ >;
331
+
217
332
  export const pipeAsyncSideEffectSix = pipeAsyncSideEffect(
218
333
  (value: number) => value + 1,
219
334
  async (value) => value * 2,
@@ -273,6 +388,20 @@ export type PipeAsyncSideEffectFromTenValueNoInputIsStrict = Expect<
273
388
  Equal<typeof pipeAsyncSideEffectFromTenValueNoInput, PipeAsyncSideEffectFromTenValueNoInputExpected>
274
389
  >;
275
390
 
391
+ export const pipeAsyncSideEffectFromNoInput = pipeAsyncSideEffect(from(1));
392
+
393
+ type PipeAsyncSideEffectFromNoInputExpected = (input?: unknown) => Promise<number | SideEffect<any>>;
394
+ export type PipeAsyncSideEffectFromNoInputIsStrict = Expect<
395
+ Equal<typeof pipeAsyncSideEffectFromNoInput, PipeAsyncSideEffectFromNoInputExpected>
396
+ >;
397
+
398
+ export const pipeAsyncSideEffectFromNoInputValue = pipeAsyncSideEffectFromNoInput();
399
+
400
+ type PipeAsyncSideEffectFromNoInputValueExpected = Promise<number | SideEffect<any>>;
401
+ export type PipeAsyncSideEffectFromNoInputValueIsStrict = Expect<
402
+ Equal<typeof pipeAsyncSideEffectFromNoInputValue, PipeAsyncSideEffectFromNoInputValueExpected>
403
+ >;
404
+
276
405
  export const strictPipeSideEffect = pipeSideEffectStrict(
277
406
  (value: number) => value + 1,
278
407
  (value) => (value > 1 ? value : SideEffect.of(() => 'LOW' as const)),
@@ -281,6 +410,11 @@ export const strictPipeSideEffect = pipeSideEffectStrict(
281
410
 
282
411
  export const strictPipeSideEffectResult = strictPipeSideEffect(1);
283
412
 
413
+ type StrictPipeSideEffectResultExpected = number | SideEffect<'LOW' | 0>;
414
+ export type PipeSideEffectStrictResultIsStrict = Expect<
415
+ Equal<typeof strictPipeSideEffectResult, StrictPipeSideEffectResultExpected>
416
+ >;
417
+
284
418
  type StrictSideEffectEffects = EffectUnion<typeof strictPipeSideEffectResult>;
285
419
  type StrictSideEffectEffectsExpected = 'LOW' | 0;
286
420
  export type PipeSideEffectStrictEffects = Expect<Equal<StrictSideEffectEffects, StrictSideEffectEffectsExpected>>;
@@ -289,8 +423,39 @@ type StrictSideEffectValue = ValueUnion<typeof strictPipeSideEffectResult>;
289
423
  type StrictSideEffectValueExpected = number;
290
424
  export type PipeSideEffectStrictValue = Expect<Equal<StrictSideEffectValue, StrictSideEffectValueExpected>>;
291
425
 
426
+ export const strictPipeSideEffectRunResult = runPipeResult(strictPipeSideEffectResult);
427
+
428
+ type StrictPipeSideEffectRunExpected =
429
+ | ValueUnion<typeof strictPipeSideEffectResult>
430
+ | EffectUnion<typeof strictPipeSideEffectResult>;
431
+ export type PipeSideEffectStrictRunPipeResultIsStrict = Expect<
432
+ Equal<typeof strictPipeSideEffectRunResult, StrictPipeSideEffectRunExpected>
433
+ >;
434
+
435
+ export const strictPipeSideEffectZero = pipeSideEffectStrict(
436
+ () => 1,
437
+ (value: number) => (value > 0 ? value : SideEffect.of(() => 'LOW' as const))
438
+ );
439
+
440
+ type StrictPipeSideEffectZeroExpected = () => number | SideEffect<'LOW'>;
441
+ export type PipeSideEffectStrictZeroIsStrict = Expect<
442
+ Equal<typeof strictPipeSideEffectZero, StrictPipeSideEffectZeroExpected>
443
+ >;
444
+
445
+ export const strictPipeSideEffectZeroValue = strictPipeSideEffectZero();
446
+
447
+ type StrictPipeSideEffectZeroValueExpected = number | SideEffect<'LOW'>;
448
+ export type PipeSideEffectStrictZeroValueIsStrict = Expect<
449
+ Equal<typeof strictPipeSideEffectZeroValue, StrictPipeSideEffectZeroValueExpected>
450
+ >;
451
+
292
452
  export const strictPipeSideEffectInput = strictPipeSideEffect(SideEffect.of(() => 'INPUT' as const));
293
453
 
454
+ type StrictPipeSideEffectInputExpected = number | SideEffect<'LOW' | 0 | 'INPUT'>;
455
+ export type PipeSideEffectStrictInputIsStrict = Expect<
456
+ Equal<typeof strictPipeSideEffectInput, StrictPipeSideEffectInputExpected>
457
+ >;
458
+
294
459
  type StrictSideEffectInputEffects = EffectUnion<typeof strictPipeSideEffectInput>;
295
460
  type StrictSideEffectInputEffectsExpected = 'LOW' | 0 | 'INPUT';
296
461
  export type PipeSideEffectStrictInputEffects = Expect<
@@ -354,6 +519,11 @@ export const strictPipeSideEffectFromTen = pipeSideEffectStrict(
354
519
 
355
520
  export const strictPipeSideEffectFromTenResult = strictPipeSideEffectFromTen('input');
356
521
 
522
+ type StrictSideEffectFromTenResultExpected = number | SideEffect<'LOW' | 'MID' | 0>;
523
+ export type PipeSideEffectStrictFromTenResultIsStrict = Expect<
524
+ Equal<typeof strictPipeSideEffectFromTenResult, StrictSideEffectFromTenResultExpected>
525
+ >;
526
+
357
527
  type StrictFromTenEffects = EffectUnion<typeof strictPipeSideEffectFromTenResult>;
358
528
  type StrictFromTenEffectsExpected = 'LOW' | 'MID' | 0;
359
529
  export type PipeSideEffectStrictFromTenEffects = Expect<
@@ -366,6 +536,11 @@ export type PipeSideEffectStrictFromTenValue = Expect<Equal<StrictFromTenValue,
366
536
 
367
537
  export const strictPipeSideEffectFromTenResultNoInput = strictPipeSideEffectFromTen();
368
538
 
539
+ type StrictSideEffectFromTenNoInputExpected = number | SideEffect<'LOW' | 'MID' | 0>;
540
+ export type PipeSideEffectStrictFromTenNoInputIsStrict = Expect<
541
+ Equal<typeof strictPipeSideEffectFromTenResultNoInput, StrictSideEffectFromTenNoInputExpected>
542
+ >;
543
+
369
544
  type StrictFromTenNoInputEffects = EffectUnion<typeof strictPipeSideEffectFromTenResultNoInput>;
370
545
  type StrictFromTenNoInputEffectsExpected = 'LOW' | 'MID' | 0;
371
546
  export type PipeSideEffectStrictFromTenNoInputEffects = Expect<
@@ -378,6 +553,23 @@ export type PipeSideEffectStrictFromTenNoInputValue = Expect<
378
553
  Equal<StrictFromTenNoInputValue, StrictFromTenNoInputValueExpected>
379
554
  >;
380
555
 
556
+ export const strictPipeSideEffectFromNoInput = pipeSideEffectStrict(from(1));
557
+
558
+ type StrictPipeSideEffectFromNoInputExpected = {
559
+ (input?: unknown): number | SideEffect<never>;
560
+ <EIn>(input?: unknown | SideEffect<EIn>): number | SideEffect<EIn>;
561
+ };
562
+ export type PipeSideEffectStrictFromNoInputIsStrict = Expect<
563
+ Equal<typeof strictPipeSideEffectFromNoInput, StrictPipeSideEffectFromNoInputExpected>
564
+ >;
565
+
566
+ export const strictPipeSideEffectFromNoInputValue = strictPipeSideEffectFromNoInput();
567
+
568
+ type StrictPipeSideEffectFromNoInputValueExpected = number | SideEffect<never>;
569
+ export type PipeSideEffectStrictFromNoInputValueIsStrict = Expect<
570
+ Equal<typeof strictPipeSideEffectFromNoInputValue, StrictPipeSideEffectFromNoInputValueExpected>
571
+ >;
572
+
381
573
  export const strictPipeAsyncSideEffect = pipeAsyncSideEffectStrict(
382
574
  (value: number) => value + 1,
383
575
  async (value) => (value > 1 ? value : SideEffect.of(() => 'LOW' as const)),
@@ -386,6 +578,11 @@ export const strictPipeAsyncSideEffect = pipeAsyncSideEffectStrict(
386
578
 
387
579
  export const strictPipeAsyncSideEffectResult = strictPipeAsyncSideEffect(1);
388
580
 
581
+ type StrictPipeAsyncSideEffectResultExpected = Promise<number | SideEffect<'LOW' | 0>>;
582
+ export type PipeAsyncSideEffectStrictResultIsStrict = Expect<
583
+ Equal<typeof strictPipeAsyncSideEffectResult, StrictPipeAsyncSideEffectResultExpected>
584
+ >;
585
+
389
586
  type StrictPipeAsyncResolved = Awaited<typeof strictPipeAsyncSideEffectResult>;
390
587
  type StrictPipeAsyncEffects = EffectUnion<StrictPipeAsyncResolved>;
391
588
  type StrictPipeAsyncEffectsExpected = 'LOW' | 0;
@@ -399,6 +596,23 @@ export type PipeAsyncSideEffectStrictValue = Expect<
399
596
  Equal<StrictPipeAsyncValue, StrictPipeAsyncValueExpected>
400
597
  >;
401
598
 
599
+ export const strictPipeAsyncSideEffectZero = pipeAsyncSideEffectStrict(
600
+ () => 1,
601
+ async (value: number) => (value > 0 ? value : SideEffect.of(() => 'LOW' as const))
602
+ );
603
+
604
+ type StrictPipeAsyncSideEffectZeroExpected = () => Promise<number | SideEffect<'LOW'>>;
605
+ export type PipeAsyncSideEffectStrictZeroIsStrict = Expect<
606
+ Equal<typeof strictPipeAsyncSideEffectZero, StrictPipeAsyncSideEffectZeroExpected>
607
+ >;
608
+
609
+ export const strictPipeAsyncSideEffectZeroValue = strictPipeAsyncSideEffectZero();
610
+
611
+ type StrictPipeAsyncSideEffectZeroValueExpected = Promise<number | SideEffect<'LOW'>>;
612
+ export type PipeAsyncSideEffectStrictZeroValueIsStrict = Expect<
613
+ Equal<typeof strictPipeAsyncSideEffectZeroValue, StrictPipeAsyncSideEffectZeroValueExpected>
614
+ >;
615
+
402
616
  export const strictPipeAsyncSideEffectSix = pipeAsyncSideEffectStrict(
403
617
  (value: number) => value + 1,
404
618
  async (value) => (value > 2 ? value : SideEffect.of(() => 'LOW' as const)),
@@ -466,6 +680,11 @@ export const strictPipeAsyncSideEffectFromTen = pipeAsyncSideEffectStrict(
466
680
 
467
681
  export const strictPipeAsyncSideEffectFromTenResult = strictPipeAsyncSideEffectFromTen('input');
468
682
 
683
+ type StrictAsyncFromTenResultExpected = Promise<number | SideEffect<'LOW' | 'MID' | 0>>;
684
+ export type PipeAsyncSideEffectStrictFromTenResultIsStrict = Expect<
685
+ Equal<typeof strictPipeAsyncSideEffectFromTenResult, StrictAsyncFromTenResultExpected>
686
+ >;
687
+
469
688
  type StrictAsyncFromTenResolved = Awaited<typeof strictPipeAsyncSideEffectFromTenResult>;
470
689
  type StrictAsyncFromTenEffects = EffectUnion<StrictAsyncFromTenResolved>;
471
690
  type StrictAsyncFromTenEffectsExpected = 'LOW' | 'MID' | 0;
@@ -481,6 +700,11 @@ export type PipeAsyncSideEffectStrictFromTenValue = Expect<
481
700
 
482
701
  export const strictPipeAsyncSideEffectFromTenResultNoInput = strictPipeAsyncSideEffectFromTen();
483
702
 
703
+ type StrictAsyncFromTenNoInputResultExpected = Promise<number | SideEffect<'LOW' | 'MID' | 0>>;
704
+ export type PipeAsyncSideEffectStrictFromTenNoInputIsStrict = Expect<
705
+ Equal<typeof strictPipeAsyncSideEffectFromTenResultNoInput, StrictAsyncFromTenNoInputResultExpected>
706
+ >;
707
+
484
708
  type StrictAsyncFromTenNoInputResolved = Awaited<typeof strictPipeAsyncSideEffectFromTenResultNoInput>;
485
709
  type StrictAsyncFromTenNoInputEffects = EffectUnion<StrictAsyncFromTenNoInputResolved>;
486
710
  type StrictAsyncFromTenNoInputEffectsExpected = 'LOW' | 'MID' | 0;
@@ -493,3 +717,47 @@ type StrictAsyncFromTenNoInputValueExpected = number;
493
717
  export type PipeAsyncSideEffectStrictFromTenNoInputValue = Expect<
494
718
  Equal<StrictAsyncFromTenNoInputValue, StrictAsyncFromTenNoInputValueExpected>
495
719
  >;
720
+
721
+ export const strictPipeAsyncSideEffectFromNoInput = pipeAsyncSideEffectStrict(from(1));
722
+
723
+ type StrictAsyncSideEffectFromNoInputExpected = {
724
+ (input?: unknown): Promise<number | SideEffect<never>>;
725
+ <EIn>(input?: unknown | SideEffect<EIn>): Promise<number | SideEffect<EIn>>;
726
+ };
727
+ export type PipeAsyncSideEffectStrictFromNoInputIsStrict = Expect<
728
+ Equal<typeof strictPipeAsyncSideEffectFromNoInput, StrictAsyncSideEffectFromNoInputExpected>
729
+ >;
730
+
731
+ export const strictPipeAsyncSideEffectFromNoInputValue = strictPipeAsyncSideEffectFromNoInput();
732
+
733
+ type StrictAsyncSideEffectFromNoInputValueExpected = Promise<number | SideEffect<never>>;
734
+ export type PipeAsyncSideEffectStrictFromNoInputValueIsStrict = Expect<
735
+ Equal<typeof strictPipeAsyncSideEffectFromNoInputValue, StrictAsyncSideEffectFromNoInputValueExpected>
736
+ >;
737
+
738
+ // Negative cases: input required when not using from/zero-arity.
739
+ // @ts-expect-error input required for unary pipe
740
+ purePipe();
741
+ // @ts-expect-error input required for unary pipeSideEffect
742
+ pipeWithSideEffectInput();
743
+ // @ts-expect-error input required for unary pipeSideEffectStrict
744
+ strictPipeSideEffect();
745
+ // @ts-expect-error input required for unary pipeAsync
746
+ purePipeAsync();
747
+ // @ts-expect-error input required for unary pipeAsyncSideEffect
748
+ pipeAsyncWithSideEffectInput();
749
+ // @ts-expect-error input required for unary pipeAsyncSideEffectStrict
750
+ strictPipeAsyncSideEffect();
751
+
752
+ // @ts-expect-error input required for direct pipe call
753
+ pipe((value: number) => value + 1)();
754
+ // @ts-expect-error input required for direct pipeSideEffect call
755
+ pipeSideEffect((value: number) => value + 1)();
756
+ // @ts-expect-error input required for direct pipeSideEffectStrict call
757
+ pipeSideEffectStrict((value: number) => value + 1)();
758
+ // @ts-expect-error input required for direct pipeAsync call
759
+ pipeAsync((value: number) => value + 1)();
760
+ // @ts-expect-error input required for direct pipeAsyncSideEffect call
761
+ pipeAsyncSideEffect((value: number) => value + 1)();
762
+ // @ts-expect-error input required for direct pipeAsyncSideEffectStrict call
763
+ pipeAsyncSideEffectStrict((value: number) => value + 1)();
@@ -0,0 +1,256 @@
1
+ import SideEffect from './sideEffect';
2
+ import pipe from './pipe';
3
+ import pipeSideEffect from './pipeSideEffect';
4
+ import pipeSideEffectStrict from './pipeSideEffectStrict';
5
+ import tap from './tap';
6
+ import pipeAsync from '../async/pipeAsync';
7
+ import pipeAsyncSideEffect from '../async/pipeAsyncSideEffect';
8
+ import pipeAsyncSideEffectStrict from '../async/pipeAsyncSideEffectStrict';
9
+ import filter from '../array/filter';
10
+ import flattenDeep from '../array/flattenDeep';
11
+ import map from '../array/map';
12
+ import sum from '../math/sum';
13
+ import gt from '../equality/gt';
14
+ import isEmpty from '../equality/isEmpty';
15
+ import when from '../control/when';
16
+ import ifElse from '../control/ifElse';
17
+ import log from '../debug/log';
18
+ import prop from '../object/prop';
19
+ import mergeAll from '../object/mergeAll';
20
+ import getOrElse from '../nullable/getOrElse';
21
+ import mapMaybe from '../nullable/mapMaybe';
22
+ import join from '../string/join';
23
+ import trim from '../string/trim';
24
+ import toUpper from '../string/toUpper';
25
+ import streamFilter from '../../stream/filter';
26
+ import streamMap from '../../stream/map';
27
+ import streamRange from '../../stream/range';
28
+ import streamReduce from '../../stream/reduce';
29
+ import streamToArray from '../../stream/toArray';
30
+
31
+ type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends B ? 1 : 2)
32
+ ? true
33
+ : false;
34
+ type Expect<T extends true> = T;
35
+
36
+ type User = {
37
+ name?: string;
38
+ };
39
+
40
+ type TagOwner = {
41
+ tags?: Array<string | null>;
42
+ };
43
+
44
+ type Config = {
45
+ value?: number;
46
+ };
47
+
48
+ const getName = prop('name') as (user: User) => string | undefined;
49
+ const getTags = prop('tags') as (owner: TagOwner) => Array<string | null> | undefined;
50
+ const mergeConfig = mergeAll as (configs: Config[]) => Config;
51
+ const getValue = prop('value') as (config: Config) => number | undefined;
52
+ const streamMapNumber = streamMap((value: number) => value + 1) as (iterable: Iterable<number>) => IterableIterator<
53
+ number
54
+ >;
55
+ const streamFilterNumber = streamFilter((value: number) => value > 1) as (
56
+ iterable: Iterable<number>
57
+ ) => IterableIterator<number>;
58
+ const streamReduceNumber = streamReduce((acc: number, value: number) => acc + value, 0) as (
59
+ iterable: Iterable<number>
60
+ ) => number;
61
+ const streamMapAsyncNumber = streamMap(async (value: number) => value + 1) as (
62
+ iterable: Iterable<number>
63
+ ) => IterableIterator<Promise<number>>;
64
+
65
+ export const pipeArrayControlString = pipe(
66
+ flattenDeep<number>,
67
+ filter(gt(1)),
68
+ map((value: number) => value * 2),
69
+ sum,
70
+ when(gt(10), (value) => value + 1),
71
+ (value) => `${value}`,
72
+ trim,
73
+ toUpper,
74
+ log('total')
75
+ );
76
+
77
+ type PipeArrayControlStringExpected = (input: any[]) => string;
78
+ export type PipeArrayControlStringIsStrict = Expect<
79
+ Equal<typeof pipeArrayControlString, PipeArrayControlStringExpected>
80
+ >;
81
+
82
+ export const pipeObjectNullableControl = pipe(
83
+ getName,
84
+ getOrElse(''),
85
+ ifElse(
86
+ (value: string) => value.length > 0,
87
+ toUpper,
88
+ () => 'UNKNOWN'
89
+ ),
90
+ tap((value: string) => value.length)
91
+ );
92
+
93
+ type PipeObjectNullableControlExpected = (input: User) => string;
94
+ export type PipeObjectNullableControlIsStrict = Expect<
95
+ Equal<typeof pipeObjectNullableControl, PipeObjectNullableControlExpected>
96
+ >;
97
+
98
+ export const pipeSideEffectTags = pipeSideEffect(
99
+ getTags,
100
+ getOrElse<Array<string | null>>([]),
101
+ mapMaybe((tag) => (tag ? tag.trim() : null)),
102
+ map((tag) => tag.toUpperCase()),
103
+ join('|'),
104
+ (value) => (isEmpty(value) ? SideEffect.of(() => 'EMPTY' as const) : value)
105
+ );
106
+
107
+ type PipeSideEffectTagsExpected = (input: TagOwner | SideEffect<any>) => string | SideEffect<any>;
108
+ export type PipeSideEffectTagsIsStrict = Expect<Equal<typeof pipeSideEffectTags, PipeSideEffectTagsExpected>>;
109
+
110
+ export const pipeSideEffectStrictConfig = pipeSideEffectStrict(
111
+ mergeConfig,
112
+ getValue,
113
+ getOrElse(0),
114
+ when(gt(0), (value) => value + 1),
115
+ (value) => (value > 0 ? value : SideEffect.of(() => 'NO_VALUE' as const)),
116
+ (value) => value + 1
117
+ );
118
+
119
+ export const pipeSideEffectStrictConfigValue = pipeSideEffectStrictConfig([{ value: 1 }]);
120
+
121
+ type PipeSideEffectStrictConfigValueExpected = number | SideEffect<'NO_VALUE'>;
122
+ export type PipeSideEffectStrictConfigValueIsStrict = Expect<
123
+ Equal<typeof pipeSideEffectStrictConfigValue, PipeSideEffectStrictConfigValueExpected>
124
+ >;
125
+
126
+ export const pipeSideEffectStrictConfigInput = pipeSideEffectStrictConfig(SideEffect.of(() => 'INPUT' as const));
127
+
128
+ type PipeSideEffectStrictConfigInputExpected = number | SideEffect<'NO_VALUE' | 'INPUT'>;
129
+ export type PipeSideEffectStrictConfigInputIsStrict = Expect<
130
+ Equal<typeof pipeSideEffectStrictConfigInput, PipeSideEffectStrictConfigInputExpected>
131
+ >;
132
+
133
+ export const pipeAsyncUserLabel = pipeAsync(
134
+ getName,
135
+ getOrElse(''),
136
+ async (value) => value.trim(),
137
+ ifElse(
138
+ (value: string) => value.length > 0,
139
+ toUpper,
140
+ () => 'UNKNOWN'
141
+ ),
142
+ log('label')
143
+ );
144
+
145
+ type PipeAsyncUserLabelExpected = (input: User) => Promise<string>;
146
+ export type PipeAsyncUserLabelIsStrict = Expect<Equal<typeof pipeAsyncUserLabel, PipeAsyncUserLabelExpected>>;
147
+
148
+ export const pipeAsyncSideEffectTags = pipeAsyncSideEffect(
149
+ getTags,
150
+ getOrElse<Array<string | null>>([]),
151
+ mapMaybe((tag) => (tag ? tag.trim() : null)),
152
+ async (tags) => tags.map((tag) => tag.toUpperCase()),
153
+ join('|'),
154
+ (value) => (isEmpty(value) ? SideEffect.of(() => 'EMPTY' as const) : value)
155
+ );
156
+
157
+ type PipeAsyncSideEffectTagsExpected = (input: TagOwner | SideEffect<any>) => Promise<string | SideEffect<any>>;
158
+ export type PipeAsyncSideEffectTagsIsStrict = Expect<
159
+ Equal<typeof pipeAsyncSideEffectTags, PipeAsyncSideEffectTagsExpected>
160
+ >;
161
+
162
+ export const pipeAsyncSideEffectStrictConfig = pipeAsyncSideEffectStrict(
163
+ mergeConfig,
164
+ getValue,
165
+ getOrElse(0),
166
+ async (value) => value + 1,
167
+ (value) => (value > 0 ? value : SideEffect.of(() => 'NO_VALUE' as const)),
168
+ async (value) => value + 1
169
+ );
170
+
171
+ export const pipeAsyncSideEffectStrictConfigValue = pipeAsyncSideEffectStrictConfig([{ value: 1 }]);
172
+
173
+ type PipeAsyncSideEffectStrictConfigValueExpected = Promise<number | SideEffect<'NO_VALUE'>>;
174
+ export type PipeAsyncSideEffectStrictConfigValueIsStrict = Expect<
175
+ Equal<typeof pipeAsyncSideEffectStrictConfigValue, PipeAsyncSideEffectStrictConfigValueExpected>
176
+ >;
177
+
178
+ export const pipeAsyncSideEffectStrictConfigInput = pipeAsyncSideEffectStrictConfig(
179
+ SideEffect.of(() => 'INPUT' as const)
180
+ );
181
+
182
+ type PipeAsyncSideEffectStrictConfigInputExpected = Promise<number | SideEffect<'NO_VALUE' | 'INPUT'>>;
183
+ export type PipeAsyncSideEffectStrictConfigInputIsStrict = Expect<
184
+ Equal<typeof pipeAsyncSideEffectStrictConfigInput, PipeAsyncSideEffectStrictConfigInputExpected>
185
+ >;
186
+
187
+ export const pipeStreamSync = pipe(
188
+ (end: number) => streamRange(0, end),
189
+ streamMapNumber,
190
+ streamFilterNumber,
191
+ streamReduceNumber
192
+ );
193
+
194
+ type PipeStreamSyncExpected = (input: number) => number;
195
+ export type PipeStreamSyncIsStrict = Expect<Equal<typeof pipeStreamSync, PipeStreamSyncExpected>>;
196
+
197
+ export const pipeSideEffectStream = pipeSideEffect(
198
+ (end: number) => streamRange(0, end),
199
+ streamMapNumber,
200
+ streamFilterNumber,
201
+ streamReduceNumber,
202
+ (value) => (value > 0 ? value : SideEffect.of(() => 'EMPTY' as const))
203
+ );
204
+
205
+ type PipeSideEffectStreamExpected = (input: number | SideEffect<any>) => number | SideEffect<any>;
206
+ export type PipeSideEffectStreamIsStrict = Expect<Equal<typeof pipeSideEffectStream, PipeSideEffectStreamExpected>>;
207
+
208
+ export const pipeSideEffectStrictStream = pipeSideEffectStrict(
209
+ (end: number) => streamRange(0, end),
210
+ streamMapNumber,
211
+ streamFilterNumber,
212
+ streamReduceNumber,
213
+ (value) => (value > 0 ? value : SideEffect.of(() => 'EMPTY' as const))
214
+ );
215
+
216
+ export const pipeSideEffectStrictStreamValue = pipeSideEffectStrictStream(3);
217
+
218
+ type PipeSideEffectStrictStreamValueExpected = number | SideEffect<'EMPTY'>;
219
+ export type PipeSideEffectStrictStreamValueIsStrict = Expect<
220
+ Equal<typeof pipeSideEffectStrictStreamValue, PipeSideEffectStrictStreamValueExpected>
221
+ >;
222
+
223
+ export const pipeAsyncStream = pipeAsync(
224
+ (end: number) => streamRange(0, end),
225
+ streamMapAsyncNumber,
226
+ streamToArray
227
+ );
228
+
229
+ type PipeAsyncStreamExpected = (input: number) => Promise<number[]>;
230
+ export type PipeAsyncStreamIsStrict = Expect<Equal<typeof pipeAsyncStream, PipeAsyncStreamExpected>>;
231
+
232
+ export const pipeAsyncSideEffectStream = pipeAsyncSideEffect(
233
+ (end: number) => streamRange(0, end),
234
+ streamMapAsyncNumber,
235
+ streamToArray,
236
+ (value) => (value.length > 0 ? value : SideEffect.of(() => 'EMPTY' as const))
237
+ );
238
+
239
+ type PipeAsyncSideEffectStreamExpected = (input: number | SideEffect<any>) => Promise<number[] | SideEffect<any>>;
240
+ export type PipeAsyncSideEffectStreamIsStrict = Expect<
241
+ Equal<typeof pipeAsyncSideEffectStream, PipeAsyncSideEffectStreamExpected>
242
+ >;
243
+
244
+ export const pipeAsyncSideEffectStrictStream = pipeAsyncSideEffectStrict(
245
+ (end: number) => streamRange(0, end),
246
+ streamMapAsyncNumber,
247
+ streamToArray,
248
+ (value) => (value.length > 0 ? value : SideEffect.of(() => 'EMPTY' as const))
249
+ );
250
+
251
+ export const pipeAsyncSideEffectStrictStreamValue = pipeAsyncSideEffectStrictStream(3);
252
+
253
+ type PipeAsyncSideEffectStrictStreamValueExpected = Promise<number[] | SideEffect<'EMPTY'>>;
254
+ export type PipeAsyncSideEffectStrictStreamValueIsStrict = Expect<
255
+ Equal<typeof pipeAsyncSideEffectStrictStreamValue, PipeAsyncSideEffectStrictStreamValueExpected>
256
+ >;
@@ -15,7 +15,7 @@ export class SideEffect<T = unknown> {
15
15
  }
16
16
  }
17
17
 
18
- type MatchHandlers<T, RValue, REffect> = {
18
+ export type MatchHandlers<T, RValue, REffect> = {
19
19
  value: (value: T) => RValue;
20
20
  effect: (sideEffect: SideEffect) => REffect;
21
21
  };
@@ -0,0 +1,16 @@
1
+ import { vi, describe, it, expect } from 'vitest';
2
+ import tap0 from './tap0';
3
+
4
+ describe('tap0', () => {
5
+ it('runs the side effect without input', () => {
6
+ const spy = vi.fn();
7
+ tap0(spy)();
8
+
9
+ expect(spy).toHaveBeenCalledTimes(1);
10
+ });
11
+
12
+ it('returns undefined', () => {
13
+ const result = tap0(() => {})();
14
+ expect(result).toBeUndefined();
15
+ });
16
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * tap0 - 입력 없이 side-effect 실행
3
+ */
4
+ function tap0(fn: () => void): () => void {
5
+ return () => {
6
+ fn();
7
+ };
8
+ }
9
+
10
+ export default tap0;