@nlozgachev/pipelined 0.12.0 → 0.14.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 (213) hide show
  1. package/LICENCE +28 -0
  2. package/README.md +1 -1
  3. package/{types/src/Types/NonEmptyList.d.ts → dist/NonEmptyList-BlGFjor5.d.mts} +4 -3
  4. package/dist/NonEmptyList-BlGFjor5.d.ts +30 -0
  5. package/dist/Task-Bd3gXPRQ.d.mts +677 -0
  6. package/dist/Task-BjAkkD6t.d.ts +677 -0
  7. package/dist/chunk-4TXC322E.mjs +136 -0
  8. package/dist/chunk-BYWKZLHM.mjs +10 -0
  9. package/dist/chunk-DBIC62UV.mjs +6 -0
  10. package/dist/chunk-FAZN3IWZ.mjs +554 -0
  11. package/dist/chunk-QPTGO5AS.mjs +150 -0
  12. package/dist/chunk-UV2HMF2A.mjs +514 -0
  13. package/dist/composition.d.mts +495 -0
  14. package/dist/composition.d.ts +495 -0
  15. package/dist/composition.js +188 -0
  16. package/dist/composition.mjs +58 -0
  17. package/dist/core.d.mts +2170 -0
  18. package/dist/core.d.ts +2170 -0
  19. package/dist/core.js +698 -0
  20. package/dist/core.mjs +42 -0
  21. package/dist/index.d.mts +6 -0
  22. package/dist/index.d.ts +6 -0
  23. package/dist/index.js +1421 -0
  24. package/dist/index.mjs +120 -0
  25. package/dist/types.d.mts +54 -0
  26. package/{types/src/Types/Brand.d.ts → dist/types.d.ts} +6 -4
  27. package/dist/types.js +41 -0
  28. package/dist/types.mjs +10 -0
  29. package/dist/utils.d.mts +1285 -0
  30. package/dist/utils.d.ts +1285 -0
  31. package/dist/utils.js +722 -0
  32. package/dist/utils.mjs +18 -0
  33. package/package.json +64 -69
  34. package/esm/mod.js +0 -3
  35. package/esm/package.json +0 -3
  36. package/esm/src/Composition/compose.js +0 -3
  37. package/esm/src/Composition/converge.js +0 -3
  38. package/esm/src/Composition/curry.js +0 -42
  39. package/esm/src/Composition/flip.js +0 -20
  40. package/esm/src/Composition/flow.js +0 -8
  41. package/esm/src/Composition/fn.js +0 -85
  42. package/esm/src/Composition/index.js +0 -13
  43. package/esm/src/Composition/juxt.js +0 -3
  44. package/esm/src/Composition/memoize.js +0 -66
  45. package/esm/src/Composition/not.js +0 -25
  46. package/esm/src/Composition/on.js +0 -12
  47. package/esm/src/Composition/pipe.js +0 -3
  48. package/esm/src/Composition/tap.js +0 -33
  49. package/esm/src/Composition/uncurry.js +0 -32
  50. package/esm/src/Core/Deferred.js +0 -30
  51. package/esm/src/Core/InternalTypes.js +0 -1
  52. package/esm/src/Core/Lens.js +0 -98
  53. package/esm/src/Core/Logged.js +0 -111
  54. package/esm/src/Core/Option.js +0 -191
  55. package/esm/src/Core/Optional.js +0 -160
  56. package/esm/src/Core/Predicate.js +0 -133
  57. package/esm/src/Core/Reader.js +0 -134
  58. package/esm/src/Core/Refinement.js +0 -115
  59. package/esm/src/Core/RemoteData.js +0 -211
  60. package/esm/src/Core/Result.js +0 -170
  61. package/esm/src/Core/State.js +0 -181
  62. package/esm/src/Core/Task.js +0 -223
  63. package/esm/src/Core/TaskOption.js +0 -106
  64. package/esm/src/Core/TaskResult.js +0 -127
  65. package/esm/src/Core/TaskValidation.js +0 -128
  66. package/esm/src/Core/These.js +0 -245
  67. package/esm/src/Core/Tuple.js +0 -112
  68. package/esm/src/Core/Validation.js +0 -212
  69. package/esm/src/Core/index.js +0 -18
  70. package/esm/src/Types/Brand.js +0 -28
  71. package/esm/src/Types/NonEmptyList.js +0 -14
  72. package/esm/src/Types/index.js +0 -2
  73. package/esm/src/Utils/Arr.js +0 -570
  74. package/esm/src/Utils/Dict.js +0 -421
  75. package/esm/src/Utils/Num.js +0 -124
  76. package/esm/src/Utils/Rec.js +0 -241
  77. package/esm/src/Utils/Str.js +0 -134
  78. package/esm/src/Utils/Uniq.js +0 -265
  79. package/esm/src/Utils/index.js +0 -6
  80. package/script/mod.js +0 -19
  81. package/script/package.json +0 -3
  82. package/script/src/Composition/compose.js +0 -6
  83. package/script/src/Composition/converge.js +0 -6
  84. package/script/src/Composition/curry.js +0 -48
  85. package/script/src/Composition/flip.js +0 -24
  86. package/script/src/Composition/flow.js +0 -11
  87. package/script/src/Composition/fn.js +0 -98
  88. package/script/src/Composition/index.js +0 -29
  89. package/script/src/Composition/juxt.js +0 -6
  90. package/script/src/Composition/memoize.js +0 -71
  91. package/script/src/Composition/not.js +0 -29
  92. package/script/src/Composition/on.js +0 -16
  93. package/script/src/Composition/pipe.js +0 -6
  94. package/script/src/Composition/tap.js +0 -37
  95. package/script/src/Composition/uncurry.js +0 -38
  96. package/script/src/Core/Deferred.js +0 -33
  97. package/script/src/Core/InternalTypes.js +0 -2
  98. package/script/src/Core/Lens.js +0 -101
  99. package/script/src/Core/Logged.js +0 -114
  100. package/script/src/Core/Option.js +0 -194
  101. package/script/src/Core/Optional.js +0 -163
  102. package/script/src/Core/Predicate.js +0 -136
  103. package/script/src/Core/Reader.js +0 -137
  104. package/script/src/Core/Refinement.js +0 -118
  105. package/script/src/Core/RemoteData.js +0 -214
  106. package/script/src/Core/Result.js +0 -173
  107. package/script/src/Core/State.js +0 -184
  108. package/script/src/Core/Task.js +0 -226
  109. package/script/src/Core/TaskOption.js +0 -109
  110. package/script/src/Core/TaskResult.js +0 -130
  111. package/script/src/Core/TaskValidation.js +0 -131
  112. package/script/src/Core/These.js +0 -248
  113. package/script/src/Core/Tuple.js +0 -115
  114. package/script/src/Core/Validation.js +0 -215
  115. package/script/src/Core/index.js +0 -34
  116. package/script/src/Types/Brand.js +0 -31
  117. package/script/src/Types/NonEmptyList.js +0 -18
  118. package/script/src/Types/index.js +0 -18
  119. package/script/src/Utils/Arr.js +0 -573
  120. package/script/src/Utils/Dict.js +0 -424
  121. package/script/src/Utils/Num.js +0 -127
  122. package/script/src/Utils/Rec.js +0 -244
  123. package/script/src/Utils/Str.js +0 -137
  124. package/script/src/Utils/Uniq.js +0 -268
  125. package/script/src/Utils/index.js +0 -22
  126. package/types/mod.d.ts +0 -4
  127. package/types/mod.d.ts.map +0 -1
  128. package/types/src/Composition/compose.d.ts +0 -33
  129. package/types/src/Composition/compose.d.ts.map +0 -1
  130. package/types/src/Composition/converge.d.ts +0 -21
  131. package/types/src/Composition/converge.d.ts.map +0 -1
  132. package/types/src/Composition/curry.d.ts +0 -43
  133. package/types/src/Composition/curry.d.ts.map +0 -1
  134. package/types/src/Composition/flip.d.ts +0 -21
  135. package/types/src/Composition/flip.d.ts.map +0 -1
  136. package/types/src/Composition/flow.d.ts +0 -56
  137. package/types/src/Composition/flow.d.ts.map +0 -1
  138. package/types/src/Composition/fn.d.ts +0 -76
  139. package/types/src/Composition/fn.d.ts.map +0 -1
  140. package/types/src/Composition/index.d.ts +0 -14
  141. package/types/src/Composition/index.d.ts.map +0 -1
  142. package/types/src/Composition/juxt.d.ts +0 -18
  143. package/types/src/Composition/juxt.d.ts.map +0 -1
  144. package/types/src/Composition/memoize.d.ts +0 -46
  145. package/types/src/Composition/memoize.d.ts.map +0 -1
  146. package/types/src/Composition/not.d.ts +0 -26
  147. package/types/src/Composition/not.d.ts.map +0 -1
  148. package/types/src/Composition/on.d.ts +0 -13
  149. package/types/src/Composition/on.d.ts.map +0 -1
  150. package/types/src/Composition/pipe.d.ts +0 -56
  151. package/types/src/Composition/pipe.d.ts.map +0 -1
  152. package/types/src/Composition/tap.d.ts +0 -31
  153. package/types/src/Composition/tap.d.ts.map +0 -1
  154. package/types/src/Composition/uncurry.d.ts +0 -54
  155. package/types/src/Composition/uncurry.d.ts.map +0 -1
  156. package/types/src/Core/Deferred.d.ts +0 -49
  157. package/types/src/Core/Deferred.d.ts.map +0 -1
  158. package/types/src/Core/InternalTypes.d.ts +0 -23
  159. package/types/src/Core/InternalTypes.d.ts.map +0 -1
  160. package/types/src/Core/Lens.d.ts +0 -118
  161. package/types/src/Core/Lens.d.ts.map +0 -1
  162. package/types/src/Core/Logged.d.ts +0 -126
  163. package/types/src/Core/Logged.d.ts.map +0 -1
  164. package/types/src/Core/Option.d.ts +0 -209
  165. package/types/src/Core/Option.d.ts.map +0 -1
  166. package/types/src/Core/Optional.d.ts +0 -158
  167. package/types/src/Core/Optional.d.ts.map +0 -1
  168. package/types/src/Core/Predicate.d.ts +0 -161
  169. package/types/src/Core/Predicate.d.ts.map +0 -1
  170. package/types/src/Core/Reader.d.ts +0 -156
  171. package/types/src/Core/Reader.d.ts.map +0 -1
  172. package/types/src/Core/Refinement.d.ts +0 -138
  173. package/types/src/Core/Refinement.d.ts.map +0 -1
  174. package/types/src/Core/RemoteData.d.ts +0 -197
  175. package/types/src/Core/RemoteData.d.ts.map +0 -1
  176. package/types/src/Core/Result.d.ts +0 -182
  177. package/types/src/Core/Result.d.ts.map +0 -1
  178. package/types/src/Core/State.d.ts +0 -192
  179. package/types/src/Core/State.d.ts.map +0 -1
  180. package/types/src/Core/Task.d.ts +0 -219
  181. package/types/src/Core/Task.d.ts.map +0 -1
  182. package/types/src/Core/TaskOption.d.ts +0 -121
  183. package/types/src/Core/TaskOption.d.ts.map +0 -1
  184. package/types/src/Core/TaskResult.d.ts +0 -119
  185. package/types/src/Core/TaskResult.d.ts.map +0 -1
  186. package/types/src/Core/TaskValidation.d.ts +0 -144
  187. package/types/src/Core/TaskValidation.d.ts.map +0 -1
  188. package/types/src/Core/These.d.ts +0 -225
  189. package/types/src/Core/These.d.ts.map +0 -1
  190. package/types/src/Core/Tuple.d.ts +0 -129
  191. package/types/src/Core/Tuple.d.ts.map +0 -1
  192. package/types/src/Core/Validation.d.ts +0 -203
  193. package/types/src/Core/Validation.d.ts.map +0 -1
  194. package/types/src/Core/index.d.ts +0 -19
  195. package/types/src/Core/index.d.ts.map +0 -1
  196. package/types/src/Types/Brand.d.ts.map +0 -1
  197. package/types/src/Types/NonEmptyList.d.ts.map +0 -1
  198. package/types/src/Types/index.d.ts +0 -3
  199. package/types/src/Types/index.d.ts.map +0 -1
  200. package/types/src/Utils/Arr.d.ts +0 -403
  201. package/types/src/Utils/Arr.d.ts.map +0 -1
  202. package/types/src/Utils/Dict.d.ts +0 -310
  203. package/types/src/Utils/Dict.d.ts.map +0 -1
  204. package/types/src/Utils/Num.d.ts +0 -110
  205. package/types/src/Utils/Num.d.ts.map +0 -1
  206. package/types/src/Utils/Rec.d.ts +0 -159
  207. package/types/src/Utils/Rec.d.ts.map +0 -1
  208. package/types/src/Utils/Str.d.ts +0 -128
  209. package/types/src/Utils/Str.d.ts.map +0 -1
  210. package/types/src/Utils/Uniq.d.ts +0 -179
  211. package/types/src/Utils/Uniq.d.ts.map +0 -1
  212. package/types/src/Utils/index.d.ts +0 -7
  213. package/types/src/Utils/index.d.ts.map +0 -1
@@ -1,134 +0,0 @@
1
- export var Reader;
2
- (function (Reader) {
3
- /**
4
- * Lifts a pure value into a Reader. The environment is ignored.
5
- *
6
- * @example
7
- * ```ts
8
- * const always42: Reader<Config, number> = Reader.resolve(42);
9
- * always42(anyConfig); // 42
10
- * ```
11
- */
12
- Reader.resolve = (value) => (_env) => value;
13
- /**
14
- * Returns the full environment as the result.
15
- * The fundamental way to access the environment in a pipeline.
16
- *
17
- * @example
18
- * ```ts
19
- * pipe(
20
- * Reader.ask<Config>(),
21
- * Reader.map(config => config.baseUrl)
22
- * )(appConfig); // "https://api.example.com"
23
- * ```
24
- */
25
- Reader.ask = () => (env) => env;
26
- /**
27
- * Projects a value from the environment using a selector function.
28
- * Equivalent to `pipe(Reader.ask(), Reader.map(f))` but more direct.
29
- *
30
- * @example
31
- * ```ts
32
- * const getBaseUrl: Reader<Config, string> = Reader.asks(c => c.baseUrl);
33
- * getBaseUrl(appConfig); // "https://api.example.com"
34
- * ```
35
- */
36
- Reader.asks = (f) => (env) => f(env);
37
- /**
38
- * Transforms the value produced by a Reader.
39
- *
40
- * @example
41
- * ```ts
42
- * pipe(
43
- * Reader.asks((c: Config) => c.baseUrl),
44
- * Reader.map(url => url.toUpperCase())
45
- * )(appConfig); // "HTTPS://API.EXAMPLE.COM"
46
- * ```
47
- */
48
- Reader.map = (f) => (data) => (env) => f(data(env));
49
- /**
50
- * Sequences two Readers. Both see the same environment.
51
- * The output of the first is passed to `f`, which returns the next Reader.
52
- *
53
- * @example
54
- * ```ts
55
- * const buildUrl = (path: string): Reader<Config, string> =>
56
- * Reader.asks(c => `${c.baseUrl}${path}`);
57
- *
58
- * const addAuth = (url: string): Reader<Config, string> =>
59
- * Reader.asks(c => `${url}?key=${c.apiKey}`);
60
- *
61
- * pipe(
62
- * buildUrl("/items"),
63
- * Reader.chain(addAuth)
64
- * )(appConfig); // "https://api.example.com/items?key=secret"
65
- * ```
66
- */
67
- Reader.chain = (f) => (data) => (env) => f(data(env))(env);
68
- /**
69
- * Applies a function wrapped in a Reader to a value wrapped in a Reader.
70
- * Both Readers see the same environment.
71
- *
72
- * @example
73
- * ```ts
74
- * const add = (a: number) => (b: number) => a + b;
75
- * pipe(
76
- * Reader.resolve<Config, typeof add>(add),
77
- * Reader.ap(Reader.asks(c => c.timeout)),
78
- * Reader.ap(Reader.resolve(5))
79
- * )(appConfig);
80
- * ```
81
- */
82
- Reader.ap = (arg) => (data) => (env) => data(env)(arg(env));
83
- /**
84
- * Executes a side effect on the produced value without changing the Reader.
85
- * Useful for logging or debugging inside a pipeline.
86
- *
87
- * @example
88
- * ```ts
89
- * pipe(
90
- * buildUrl("/users"),
91
- * Reader.tap(url => console.log("Requesting:", url)),
92
- * Reader.chain(addAuth)
93
- * )(appConfig);
94
- * ```
95
- */
96
- Reader.tap = (f) => (data) => (env) => {
97
- const a = data(env);
98
- f(a);
99
- return a;
100
- };
101
- /**
102
- * Adapts a Reader to work with a different (typically wider) environment
103
- * by transforming the environment before passing it to the Reader.
104
- * This lets you compose Readers that expect different environments.
105
- *
106
- * @example
107
- * ```ts
108
- * type AppEnv = { db: DbPool; config: Config; logger: Logger };
109
- *
110
- * // buildUrl only needs Config
111
- * const buildUrl: Reader<Config, string> = Reader.asks(c => c.baseUrl);
112
- *
113
- * // Zoom in from AppEnv to Config
114
- * const buildUrlFromApp: Reader<AppEnv, string> =
115
- * pipe(buildUrl, Reader.local((env: AppEnv) => env.config));
116
- *
117
- * buildUrlFromApp(appEnv); // works with the full AppEnv
118
- * ```
119
- */
120
- Reader.local = (f) => (data) => (env) => data(f(env));
121
- /**
122
- * Runs a Reader by supplying the environment. Use this at the edge of your
123
- * program where the environment is available.
124
- *
125
- * @example
126
- * ```ts
127
- * pipe(
128
- * buildEndpoint("/users"),
129
- * Reader.run(appConfig)
130
- * ); // "https://api.example.com/users?key=secret"
131
- * ```
132
- */
133
- Reader.run = (env) => (data) => data(env);
134
- })(Reader || (Reader = {}));
@@ -1,115 +0,0 @@
1
- import { Option } from "./Option.js";
2
- import { Result } from "./Result.js";
3
- export var Refinement;
4
- (function (Refinement) {
5
- /**
6
- * Creates a `Refinement<A, B>` from a plain boolean predicate.
7
- *
8
- * This is an unsafe cast — the caller is responsible for ensuring that the
9
- * predicate truly characterises values of type `B`. Use this only when
10
- * bootstrapping a new refinement; prefer `compose`, `and`, or `or` to build
11
- * derived refinements from existing ones.
12
- *
13
- * @example
14
- * ```ts
15
- * type PositiveNumber = number & { readonly _tag: "PositiveNumber" };
16
- *
17
- * const isPositive: Refinement<number, PositiveNumber> =
18
- * Refinement.make(n => n > 0);
19
- * ```
20
- */
21
- Refinement.make = (f) => f;
22
- /**
23
- * Chains two refinements: if `ab` narrows `A` to `B` and `bc` narrows `B` to `C`,
24
- * the result narrows `A` directly to `C`.
25
- *
26
- * Data-last — the first refinement `ab` is the data being piped.
27
- *
28
- * @example
29
- * ```ts
30
- * type NonEmptyString = string & { readonly _tag: "NonEmpty" };
31
- * type TrimmedString = NonEmptyString & { readonly _tag: "Trimmed" };
32
- *
33
- * const isNonEmpty: Refinement<string, NonEmptyString> =
34
- * Refinement.make(s => s.length > 0);
35
- * const isTrimmed: Refinement<NonEmptyString, TrimmedString> =
36
- * Refinement.make(s => s === s.trim());
37
- *
38
- * const isNonEmptyTrimmed: Refinement<string, TrimmedString> = pipe(
39
- * isNonEmpty,
40
- * Refinement.compose(isTrimmed)
41
- * );
42
- * ```
43
- */
44
- Refinement.compose = (bc) => (ab) => (a) => ab(a) && bc(a);
45
- /**
46
- * Intersects two refinements: the result narrows `A` to `B & C`, passing only
47
- * when both refinements hold simultaneously.
48
- *
49
- * Data-last — the first refinement is the data being piped.
50
- *
51
- * @example
52
- * ```ts
53
- * const isString: Refinement<unknown, string> = Refinement.make(x => typeof x === "string");
54
- * const isNonEmpty: Refinement<unknown, { length: number }> =
55
- * Refinement.make(x => (x as any).length > 0);
56
- *
57
- * const isNonEmptyString = pipe(isString, Refinement.and(isNonEmpty));
58
- * isNonEmptyString("hi"); // true
59
- * isNonEmptyString(""); // false
60
- * ```
61
- */
62
- Refinement.and = (second) => (first) => (a) => first(a) && second(a);
63
- /**
64
- * Unions two refinements: the result narrows `A` to `B | C`, passing when either
65
- * refinement holds.
66
- *
67
- * Data-last — the first refinement is the data being piped.
68
- *
69
- * @example
70
- * ```ts
71
- * const isString: Refinement<unknown, string> = Refinement.make(x => typeof x === "string");
72
- * const isNumber: Refinement<unknown, number> = Refinement.make(x => typeof x === "number");
73
- *
74
- * const isStringOrNumber = pipe(isString, Refinement.or(isNumber));
75
- * isStringOrNumber("hi"); // true
76
- * isStringOrNumber(42); // true
77
- * isStringOrNumber(true); // false
78
- * ```
79
- */
80
- Refinement.or = (second) => (first) => (a) => first(a) || second(a);
81
- /**
82
- * Converts a `Refinement<A, B>` into a function `(a: A) => Option<B>`.
83
- *
84
- * Returns `Some(a)` when the refinement holds, `None` otherwise. Useful for
85
- * integrating runtime validation into an `Option`-based pipeline.
86
- *
87
- * @example
88
- * ```ts
89
- * type PositiveNumber = number & { readonly _tag: "Positive" };
90
- * const isPositive: Refinement<number, PositiveNumber> =
91
- * Refinement.make(n => n > 0);
92
- *
93
- * pipe(-1, Refinement.toFilter(isPositive)); // None
94
- * pipe(42, Refinement.toFilter(isPositive)); // Some(42)
95
- * ```
96
- */
97
- Refinement.toFilter = (r) => (a) => r(a) ? Option.some(a) : Option.none();
98
- /**
99
- * Converts a `Refinement<A, B>` into a function `(a: A) => Result<E, B>`.
100
- *
101
- * Returns `Ok(a)` when the refinement holds, `Err(onFail(a))` otherwise. Use
102
- * this to surface validation failures as typed errors inside a `Result` pipeline.
103
- *
104
- * @example
105
- * ```ts
106
- * type NonEmptyString = string & { readonly _tag: "NonEmpty" };
107
- * const isNonEmpty: Refinement<string, NonEmptyString> =
108
- * Refinement.make(s => s.length > 0);
109
- *
110
- * pipe("", Refinement.toResult(isNonEmpty, () => "must not be empty")); // Err(...)
111
- * pipe("hi", Refinement.toResult(isNonEmpty, () => "must not be empty")); // Ok("hi")
112
- * ```
113
- */
114
- Refinement.toResult = (r, onFail) => (a) => r(a) ? Result.ok(a) : Result.err(onFail(a));
115
- })(Refinement || (Refinement = {}));
@@ -1,211 +0,0 @@
1
- import { Option } from "./Option.js";
2
- import { Result } from "./Result.js";
3
- const _notAsked = { kind: "NotAsked" };
4
- const _loading = { kind: "Loading" };
5
- export var RemoteData;
6
- (function (RemoteData) {
7
- /**
8
- * Creates a NotAsked RemoteData.
9
- */
10
- RemoteData.notAsked = () => _notAsked;
11
- /**
12
- * Creates a Loading RemoteData.
13
- */
14
- RemoteData.loading = () => _loading;
15
- /**
16
- * Creates a Failure RemoteData with the given error.
17
- */
18
- RemoteData.failure = (error) => ({
19
- kind: "Failure",
20
- error,
21
- });
22
- /**
23
- * Creates a Success RemoteData with the given value.
24
- */
25
- RemoteData.success = (value) => ({
26
- kind: "Success",
27
- value,
28
- });
29
- /**
30
- * Type guard that checks if a RemoteData is NotAsked.
31
- */
32
- RemoteData.isNotAsked = (data) => data.kind === "NotAsked";
33
- /**
34
- * Type guard that checks if a RemoteData is Loading.
35
- */
36
- RemoteData.isLoading = (data) => data.kind === "Loading";
37
- /**
38
- * Type guard that checks if a RemoteData is Failure.
39
- */
40
- RemoteData.isFailure = (data) => data.kind === "Failure";
41
- /**
42
- * Type guard that checks if a RemoteData is Success.
43
- */
44
- RemoteData.isSuccess = (data) => data.kind === "Success";
45
- /**
46
- * Transforms the success value inside a RemoteData.
47
- *
48
- * @example
49
- * ```ts
50
- * pipe(RemoteData.success(5), RemoteData.map(n => n * 2)); // Success(10)
51
- * pipe(RemoteData.loading(), RemoteData.map(n => n * 2)); // Loading
52
- * ```
53
- */
54
- RemoteData.map = (f) => (data) => RemoteData.isSuccess(data) ? RemoteData.success(f(data.value)) : data;
55
- /**
56
- * Transforms the error value inside a RemoteData.
57
- *
58
- * @example
59
- * ```ts
60
- * pipe(RemoteData.failure("oops"), RemoteData.mapError(e => e.toUpperCase())); // Failure("OOPS")
61
- * ```
62
- */
63
- RemoteData.mapError = (f) => (data) => RemoteData.isFailure(data) ? RemoteData.failure(f(data.error)) : data;
64
- /**
65
- * Chains RemoteData computations. If the input is Success, passes the value to f.
66
- * Otherwise, propagates the current state.
67
- *
68
- * @example
69
- * ```ts
70
- * pipe(
71
- * RemoteData.success(5),
72
- * RemoteData.chain(n => n > 0 ? RemoteData.success(n) : RemoteData.failure("negative"))
73
- * );
74
- * ```
75
- */
76
- RemoteData.chain = (f) => (data) => RemoteData.isSuccess(data) ? f(data.value) : data;
77
- /**
78
- * Applies a function wrapped in a RemoteData to a value wrapped in a RemoteData.
79
- *
80
- * @example
81
- * ```ts
82
- * const add = (a: number) => (b: number) => a + b;
83
- * pipe(
84
- * RemoteData.success(add),
85
- * RemoteData.ap(RemoteData.success(5)),
86
- * RemoteData.ap(RemoteData.success(3))
87
- * ); // Success(8)
88
- * ```
89
- */
90
- RemoteData.ap = (arg) => (data) => {
91
- if (RemoteData.isSuccess(data) && RemoteData.isSuccess(arg)) {
92
- return RemoteData.success(data.value(arg.value));
93
- }
94
- if (RemoteData.isFailure(data))
95
- return data;
96
- if (RemoteData.isFailure(arg))
97
- return arg;
98
- if (RemoteData.isLoading(data) || RemoteData.isLoading(arg))
99
- return RemoteData.loading();
100
- return RemoteData.notAsked();
101
- };
102
- /**
103
- * Extracts the value from a RemoteData by providing handlers for all four cases.
104
- *
105
- * @example
106
- * ```ts
107
- * pipe(
108
- * userData,
109
- * RemoteData.fold(
110
- * () => "Not asked",
111
- * () => "Loading...",
112
- * e => `Error: ${e}`,
113
- * value => `Got: ${value}`
114
- * )
115
- * );
116
- * ```
117
- */
118
- RemoteData.fold = (onNotAsked, onLoading, onFailure, onSuccess) => (data) => {
119
- switch (data.kind) {
120
- case "NotAsked":
121
- return onNotAsked();
122
- case "Loading":
123
- return onLoading();
124
- case "Failure":
125
- return onFailure(data.error);
126
- case "Success":
127
- return onSuccess(data.value);
128
- }
129
- };
130
- /**
131
- * Pattern matches on a RemoteData, returning the result of the matching case.
132
- *
133
- * @example
134
- * ```ts
135
- * pipe(
136
- * userData,
137
- * RemoteData.match({
138
- * notAsked: () => "Click to load",
139
- * loading: () => "Loading...",
140
- * failure: e => `Error: ${e}`,
141
- * success: user => `Hello, ${user.name}!`
142
- * })
143
- * );
144
- * ```
145
- */
146
- RemoteData.match = (cases) => (data) => {
147
- switch (data.kind) {
148
- case "NotAsked":
149
- return cases.notAsked();
150
- case "Loading":
151
- return cases.loading();
152
- case "Failure":
153
- return cases.failure(data.error);
154
- case "Success":
155
- return cases.success(data.value);
156
- }
157
- };
158
- /**
159
- * Returns the success value or a default value if the RemoteData is not Success.
160
- * The default can be a different type, widening the result to `A | B`.
161
- *
162
- * @example
163
- * ```ts
164
- * pipe(RemoteData.success(5), RemoteData.getOrElse(() => 0)); // 5
165
- * pipe(RemoteData.loading(), RemoteData.getOrElse(() => 0)); // 0
166
- * pipe(RemoteData.loading<string, number>(), RemoteData.getOrElse(() => null)); // null — typed as number | null
167
- * ```
168
- */
169
- RemoteData.getOrElse = (defaultValue) => (data) => RemoteData.isSuccess(data) ? data.value : defaultValue();
170
- /**
171
- * Executes a side effect on the success value without changing the RemoteData.
172
- *
173
- * @example
174
- * ```ts
175
- * pipe(
176
- * RemoteData.success(5),
177
- * RemoteData.tap(n => console.log("Value:", n)),
178
- * RemoteData.map(n => n * 2)
179
- * );
180
- * ```
181
- */
182
- RemoteData.tap = (f) => (data) => {
183
- if (RemoteData.isSuccess(data))
184
- f(data.value);
185
- return data;
186
- };
187
- /**
188
- * Recovers from a Failure state by providing a fallback RemoteData.
189
- * The fallback can produce a different success type, widening the result to `RemoteData<E, A | B>`.
190
- */
191
- RemoteData.recover = (fallback) => (data) => RemoteData.isFailure(data) ? fallback(data.error) : data;
192
- /**
193
- * Converts a RemoteData to an Option.
194
- * Success becomes Some, all other states become None.
195
- */
196
- RemoteData.toOption = (data) => RemoteData.isSuccess(data) ? Option.some(data.value) : Option.none();
197
- /**
198
- * Converts a RemoteData to a Result.
199
- * Success becomes Ok, Failure becomes Err.
200
- * NotAsked and Loading become Err with the provided fallback error.
201
- *
202
- * @example
203
- * ```ts
204
- * pipe(
205
- * RemoteData.success(42),
206
- * RemoteData.toResult(() => "not loaded")
207
- * ); // Ok(42)
208
- * ```
209
- */
210
- RemoteData.toResult = (onNotReady) => (data) => RemoteData.isSuccess(data) ? Result.ok(data.value) : Result.err(RemoteData.isFailure(data) ? data.error : onNotReady());
211
- })(RemoteData || (RemoteData = {}));
@@ -1,170 +0,0 @@
1
- import { Option } from "./Option.js";
2
- export var Result;
3
- (function (Result) {
4
- /**
5
- * Creates a successful Result with the given value.
6
- */
7
- Result.ok = (value) => ({ kind: "Ok", value });
8
- /**
9
- * Creates a failed Result with the given error.
10
- */
11
- Result.err = (error) => ({ kind: "Error", error });
12
- /**
13
- * Type guard that checks if an Result is Ok.
14
- */
15
- Result.isOk = (data) => data.kind === "Ok";
16
- /**
17
- * Type guard that checks if an Result is Err.
18
- */
19
- Result.isErr = (data) => data.kind === "Error";
20
- /**
21
- * Creates an Result from a function that may throw.
22
- * Catches any errors and transforms them using the onError function.
23
- *
24
- * @example
25
- * ```ts
26
- * const parseJson = (s: string): Result<string, unknown> =>
27
- * Result.tryCatch(
28
- * () => JSON.parse(s),
29
- * (e) => `Parse error: ${e}`
30
- * );
31
- * ```
32
- */
33
- Result.tryCatch = (f, onError) => {
34
- try {
35
- return Result.ok(f());
36
- }
37
- catch (e) {
38
- return Result.err(onError(e));
39
- }
40
- };
41
- /**
42
- * Transforms the success value inside an Result.
43
- *
44
- * @example
45
- * ```ts
46
- * pipe(Result.ok(5), Result.map(n => n * 2)); // Ok(10)
47
- * pipe(Result.err("error"), Result.map(n => n * 2)); // Err("error")
48
- * ```
49
- */
50
- Result.map = (f) => (data) => Result.isOk(data) ? Result.ok(f(data.value)) : data;
51
- /**
52
- * Transforms the error value inside an Result.
53
- *
54
- * @example
55
- * ```ts
56
- * pipe(Result.err("oops"), Result.mapError(e => e.toUpperCase())); // Err("OOPS")
57
- * ```
58
- */
59
- Result.mapError = (f) => (data) => Result.isErr(data) ? Result.err(f(data.error)) : data;
60
- /**
61
- * Chains Result computations. If the first is Ok, passes the value to f.
62
- * If the first is Err, propagates the error.
63
- *
64
- * @example
65
- * ```ts
66
- * const validatePositive = (n: number): Result<string, number> =>
67
- * n > 0 ? Result.ok(n) : Result.err("Must be positive");
68
- *
69
- * pipe(Result.ok(5), Result.chain(validatePositive)); // Ok(5)
70
- * pipe(Result.ok(-1), Result.chain(validatePositive)); // Err("Must be positive")
71
- * ```
72
- */
73
- Result.chain = (f) => (data) => Result.isOk(data) ? f(data.value) : data;
74
- /**
75
- * Extracts the value from an Result by providing handlers for both cases.
76
- *
77
- * @example
78
- * ```ts
79
- * pipe(
80
- * Result.ok(5),
81
- * Result.fold(
82
- * e => `Error: ${e}`,
83
- * n => `Value: ${n}`
84
- * )
85
- * ); // "Value: 5"
86
- * ```
87
- */
88
- Result.fold = (onErr, onOk) => (data) => Result.isOk(data) ? onOk(data.value) : onErr(data.error);
89
- /**
90
- * Pattern matches on a Result, returning the result of the matching case.
91
- *
92
- * @example
93
- * ```ts
94
- * pipe(
95
- * result,
96
- * Result.match({
97
- * ok: value => `Got ${value}`,
98
- * err: error => `Failed: ${error}`
99
- * })
100
- * );
101
- * ```
102
- */
103
- Result.match = (cases) => (data) => Result.isOk(data) ? cases.ok(data.value) : cases.err(data.error);
104
- /**
105
- * Returns the success value or a default value if the Result is an error.
106
- * The default is a thunk `() => B` — evaluated only when the Result is Err.
107
- * The default can be a different type, widening the result to `A | B`.
108
- *
109
- * @example
110
- * ```ts
111
- * pipe(Result.ok(5), Result.getOrElse(() => 0)); // 5
112
- * pipe(Result.err("error"), Result.getOrElse(() => 0)); // 0
113
- * pipe(Result.err("error"), Result.getOrElse(() => null)); // null — typed as number | null
114
- * ```
115
- */
116
- Result.getOrElse = (defaultValue) => (data) => Result.isOk(data) ? data.value : defaultValue();
117
- /**
118
- * Executes a side effect on the success value without changing the Result.
119
- * Useful for logging or debugging.
120
- *
121
- * @example
122
- * ```ts
123
- * pipe(
124
- * Result.ok(5),
125
- * Result.tap(n => console.log("Value:", n)),
126
- * Result.map(n => n * 2)
127
- * );
128
- * ```
129
- */
130
- Result.tap = (f) => (data) => {
131
- if (Result.isOk(data))
132
- f(data.value);
133
- return data;
134
- };
135
- /**
136
- * Recovers from an error by providing a fallback Result.
137
- * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
138
- */
139
- Result.recover = (fallback) => (data) => Result.isOk(data) ? data : fallback(data.error);
140
- /**
141
- * Recovers from an error unless it matches the blocked error.
142
- * The fallback can produce a different success type, widening the result to `Result<E, A | B>`.
143
- */
144
- Result.recoverUnless = (blockedErr, fallback) => (data) => Result.isErr(data) && data.error !== blockedErr ? fallback() : data;
145
- /**
146
- * Converts a Result to an Option.
147
- * Ok becomes Some, Err becomes None (the error is discarded).
148
- *
149
- * @example
150
- * ```ts
151
- * Result.toOption(Result.ok(42)); // Some(42)
152
- * Result.toOption(Result.err("oops")); // None
153
- * ```
154
- */
155
- Result.toOption = (data) => Result.isOk(data) ? Option.some(data.value) : Option.none();
156
- /**
157
- * Applies a function wrapped in an Result to a value wrapped in an Result.
158
- *
159
- * @example
160
- * ```ts
161
- * const add = (a: number) => (b: number) => a + b;
162
- * pipe(
163
- * Result.ok(add),
164
- * Result.ap(Result.ok(5)),
165
- * Result.ap(Result.ok(3))
166
- * ); // Ok(8)
167
- * ```
168
- */
169
- Result.ap = (arg) => (data) => Result.isOk(data) && Result.isOk(arg) ? Result.ok(data.value(arg.value)) : Result.isErr(data) ? data : arg;
170
- })(Result || (Result = {}));