@nunofyobiz/effect-extras 2.0.0 → 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/README.md +38 -3
- package/dist/ArrayX.d.ts +381 -0
- package/dist/ArrayX.d.ts.map +1 -0
- package/dist/ArrayX.js +493 -0
- package/dist/ArrayX.js.map +1 -0
- package/dist/BigIntX.d.ts +24 -0
- package/dist/BigIntX.d.ts.map +1 -0
- package/dist/BigIntX.js +30 -0
- package/dist/BigIntX.js.map +1 -0
- package/dist/BooleanX.d.ts +25 -0
- package/dist/BooleanX.d.ts.map +1 -0
- package/dist/BooleanX.js +25 -0
- package/dist/BooleanX.js.map +1 -0
- package/dist/DurationX.d.ts +73 -0
- package/dist/DurationX.d.ts.map +1 -0
- package/dist/DurationX.js +91 -0
- package/dist/DurationX.js.map +1 -0
- package/dist/EffectX.d.ts +120 -0
- package/dist/EffectX.d.ts.map +1 -0
- package/dist/EffectX.js +140 -0
- package/dist/EffectX.js.map +1 -0
- package/dist/FormDataX.d.ts +49 -0
- package/dist/FormDataX.d.ts.map +1 -0
- package/dist/FormDataX.js +42 -0
- package/dist/FormDataX.js.map +1 -0
- package/dist/InclusiveOr.d.ts +1123 -0
- package/dist/InclusiveOr.d.ts.map +1 -0
- package/dist/InclusiveOr.js +1074 -0
- package/dist/InclusiveOr.js.map +1 -0
- package/dist/MapX.d.ts +32 -0
- package/dist/MapX.d.ts.map +1 -0
- package/dist/MapX.js +49 -0
- package/dist/MapX.js.map +1 -0
- package/dist/NonNullableX.d.ts +174 -0
- package/dist/NonNullableX.d.ts.map +1 -0
- package/dist/NonNullableX.js +217 -0
- package/dist/NonNullableX.js.map +1 -0
- package/dist/NumberX.d.ts +178 -0
- package/dist/NumberX.d.ts.map +1 -0
- package/dist/NumberX.js +214 -0
- package/dist/NumberX.js.map +1 -0
- package/dist/OptionX.d.ts +187 -0
- package/dist/OptionX.d.ts.map +1 -0
- package/dist/OptionX.js +201 -0
- package/dist/OptionX.js.map +1 -0
- package/dist/OrderX.d.ts +32 -0
- package/dist/OrderX.d.ts.map +1 -0
- package/dist/OrderX.js +32 -0
- package/dist/OrderX.js.map +1 -0
- package/dist/PredicateX.d.ts +108 -0
- package/dist/PredicateX.d.ts.map +1 -0
- package/dist/PredicateX.js +111 -0
- package/dist/PredicateX.js.map +1 -0
- package/dist/PromiseX.d.ts +32 -0
- package/dist/PromiseX.d.ts.map +1 -0
- package/dist/PromiseX.js +32 -0
- package/dist/PromiseX.js.map +1 -0
- package/dist/RecordX.d.ts +450 -0
- package/dist/RecordX.d.ts.map +1 -0
- package/dist/RecordX.js +487 -0
- package/dist/RecordX.js.map +1 -0
- package/dist/ResultX.d.ts +50 -0
- package/dist/ResultX.d.ts.map +1 -0
- package/dist/ResultX.js +50 -0
- package/dist/ResultX.js.map +1 -0
- package/dist/SchemaX.d.ts +249 -0
- package/dist/SchemaX.d.ts.map +1 -0
- package/dist/SchemaX.js +243 -0
- package/dist/SchemaX.js.map +1 -0
- package/dist/SetX.d.ts +121 -0
- package/dist/SetX.d.ts.map +1 -0
- package/dist/SetX.js +137 -0
- package/dist/SetX.js.map +1 -0
- package/dist/StringX.d.ts +131 -0
- package/dist/StringX.d.ts.map +1 -0
- package/dist/StringX.js +149 -0
- package/dist/StringX.js.map +1 -0
- package/dist/StructX.d.ts +219 -0
- package/dist/StructX.d.ts.map +1 -0
- package/dist/StructX.js +173 -0
- package/dist/StructX.js.map +1 -0
- package/dist/WarnResult.d.ts +1191 -0
- package/dist/WarnResult.d.ts.map +1 -0
- package/dist/WarnResult.js +991 -0
- package/dist/WarnResult.js.map +1 -0
- package/dist/index.d.ts +23 -3772
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -1011
- package/dist/index.js.map +1 -1
- package/package.json +18 -5
- package/src/{ArrayX/ArrayX.ts → ArrayX.ts} +6 -88
- package/src/{DurationX/DurationX.ts → DurationX.ts} +1 -1
- package/src/InclusiveOr.ts +1255 -0
- package/src/{NonNullableX/NonNullableX.ts → NonNullableX.ts} +5 -0
- package/src/{OptionX/OptionX.ts → OptionX.ts} +8 -2
- package/src/{PredicateX/PredicateX.ts → PredicateX.ts} +41 -0
- package/src/{RecordX/RecordX.ts → RecordX.ts} +184 -2
- package/src/StringX.ts +210 -0
- package/src/{WarnResult/WarnResult.ts → WarnResult.ts} +297 -227
- package/src/index.ts +22 -20
- package/src/ArrayX/index.ts +0 -1
- package/src/BigIntX/index.ts +0 -1
- package/src/BooleanX/index.ts +0 -1
- package/src/DurationX/index.ts +0 -1
- package/src/EffectX/index.ts +0 -1
- package/src/FormDataX/index.ts +0 -1
- package/src/MapX/index.ts +0 -1
- package/src/NonNullableX/index.ts +0 -2
- package/src/NumberX/index.ts +0 -1
- package/src/OptionX/index.ts +0 -1
- package/src/OrderX/index.ts +0 -1
- package/src/PredicateX/index.ts +0 -1
- package/src/PromiseX/index.ts +0 -1
- package/src/RecordX/index.ts +0 -1
- package/src/ResultX/index.ts +0 -1
- package/src/SchemaX/index.ts +0 -1
- package/src/SetX/index.ts +0 -1
- package/src/StringX/StringX.ts +0 -97
- package/src/StringX/index.ts +0 -1
- package/src/StructX/index.ts +0 -1
- package/src/WarnResult/index.ts +0 -1
- /package/src/{BigIntX/BigIntX.ts → BigIntX.ts} +0 -0
- /package/src/{BooleanX/BooleanX.ts → BooleanX.ts} +0 -0
- /package/src/{EffectX/EffectX.ts → EffectX.ts} +0 -0
- /package/src/{FormDataX/FormDataX.ts → FormDataX.ts} +0 -0
- /package/src/{MapX/MapX.ts → MapX.ts} +0 -0
- /package/src/{NumberX/NumberX.ts → NumberX.ts} +0 -0
- /package/src/{OrderX/OrderX.ts → OrderX.ts} +0 -0
- /package/src/{PromiseX/PromiseX.ts → PromiseX.ts} +0 -0
- /package/src/{ResultX/ResultX.ts → ResultX.ts} +0 -0
- /package/src/{SchemaX/SchemaX.ts → SchemaX.ts} +0 -0
- /package/src/{SetX/SetX.ts → SetX.ts} +0 -0
- /package/src/{StructX/StructX.ts → StructX.ts} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,3772 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
* })
|
|
25
|
-
*
|
|
26
|
-
* assert.deepStrictEqual(both._tag, "SuccessWithWarnings")
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* @category models
|
|
30
|
-
* @since 0.0.0
|
|
31
|
-
*/
|
|
32
|
-
type WarnResult<W, A> = Data.TaggedEnum<{
|
|
33
|
-
WarningsOnly: {
|
|
34
|
-
readonly warnings: W;
|
|
35
|
-
};
|
|
36
|
-
SuccessOnly: {
|
|
37
|
-
readonly success: A;
|
|
38
|
-
};
|
|
39
|
-
SuccessWithWarnings: {
|
|
40
|
-
readonly warnings: W;
|
|
41
|
-
readonly success: A;
|
|
42
|
-
};
|
|
43
|
-
}>;
|
|
44
|
-
/**
|
|
45
|
-
* The `WarningsOnly` member of `WarnResult` — a result that carries only
|
|
46
|
-
* `warnings` and no `success` value.
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```ts
|
|
50
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
51
|
-
*
|
|
52
|
-
* const value: WarnResult.WarningsOnly<string> = WarnResult.WarningsOnly({
|
|
53
|
-
* warnings: "skipped 2 rows"
|
|
54
|
-
* })
|
|
55
|
-
*
|
|
56
|
-
* assert.deepStrictEqual(value.warnings, "skipped 2 rows")
|
|
57
|
-
* ```
|
|
58
|
-
*
|
|
59
|
-
* @category models
|
|
60
|
-
* @since 0.0.0
|
|
61
|
-
*/
|
|
62
|
-
type WarningsOnly<W> = WarnResult<W, never> & {
|
|
63
|
-
_tag: "WarningsOnly";
|
|
64
|
-
};
|
|
65
|
-
/**
|
|
66
|
-
* Constructs a `WarningsOnly` — a `WarnResult` that carries only `warnings`.
|
|
67
|
-
*
|
|
68
|
-
* @example
|
|
69
|
-
* ```ts
|
|
70
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
71
|
-
*
|
|
72
|
-
* const value = WarnResult.WarningsOnly({ warnings: "skipped 2 rows" })
|
|
73
|
-
*
|
|
74
|
-
* assert.deepStrictEqual(value._tag, "WarningsOnly")
|
|
75
|
-
* assert.deepStrictEqual(value.warnings, "skipped 2 rows")
|
|
76
|
-
* ```
|
|
77
|
-
*
|
|
78
|
-
* @category constructors
|
|
79
|
-
* @since 0.0.0
|
|
80
|
-
*/
|
|
81
|
-
declare const WarningsOnly: <A, B>(args: {
|
|
82
|
-
readonly warnings: A;
|
|
83
|
-
}) => {
|
|
84
|
-
readonly _tag: "WarningsOnly";
|
|
85
|
-
readonly warnings: A;
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* The `SuccessOnly` member of `WarnResult` — a result that carries only a
|
|
89
|
-
* `success` value and no `warnings`.
|
|
90
|
-
*
|
|
91
|
-
* @example
|
|
92
|
-
* ```ts
|
|
93
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
94
|
-
*
|
|
95
|
-
* const value: WarnResult.SuccessOnly<number> = WarnResult.SuccessOnly({
|
|
96
|
-
* success: 1
|
|
97
|
-
* })
|
|
98
|
-
*
|
|
99
|
-
* assert.deepStrictEqual(value.success, 1)
|
|
100
|
-
* ```
|
|
101
|
-
*
|
|
102
|
-
* @category models
|
|
103
|
-
* @since 0.0.0
|
|
104
|
-
*/
|
|
105
|
-
type SuccessOnly<A> = WarnResult<never, A> & {
|
|
106
|
-
_tag: "SuccessOnly";
|
|
107
|
-
};
|
|
108
|
-
/**
|
|
109
|
-
* Constructs a `SuccessOnly` — a `WarnResult` that carries only a `success` value.
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```ts
|
|
113
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
114
|
-
*
|
|
115
|
-
* const value = WarnResult.SuccessOnly({ success: 1 })
|
|
116
|
-
*
|
|
117
|
-
* assert.deepStrictEqual(value._tag, "SuccessOnly")
|
|
118
|
-
* assert.deepStrictEqual(value.success, 1)
|
|
119
|
-
* ```
|
|
120
|
-
*
|
|
121
|
-
* @category constructors
|
|
122
|
-
* @since 0.0.0
|
|
123
|
-
*/
|
|
124
|
-
declare const SuccessOnly: <A, B>(args: {
|
|
125
|
-
readonly success: B;
|
|
126
|
-
}) => {
|
|
127
|
-
readonly _tag: "SuccessOnly";
|
|
128
|
-
readonly success: B;
|
|
129
|
-
};
|
|
130
|
-
/**
|
|
131
|
-
* The `SuccessWithWarnings` member of `WarnResult` — a result that carries both a
|
|
132
|
-
* `success` value and `warnings`.
|
|
133
|
-
*
|
|
134
|
-
* @example
|
|
135
|
-
* ```ts
|
|
136
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
137
|
-
*
|
|
138
|
-
* const value: WarnResult.SuccessWithWarnings<string, number> =
|
|
139
|
-
* WarnResult.SuccessWithWarnings({
|
|
140
|
-
* warnings: "rounded down",
|
|
141
|
-
* success: 1
|
|
142
|
-
* })
|
|
143
|
-
*
|
|
144
|
-
* assert.deepStrictEqual(value, {
|
|
145
|
-
* _tag: "SuccessWithWarnings",
|
|
146
|
-
* warnings: "rounded down",
|
|
147
|
-
* success: 1
|
|
148
|
-
* })
|
|
149
|
-
* ```
|
|
150
|
-
*
|
|
151
|
-
* @category models
|
|
152
|
-
* @since 0.0.0
|
|
153
|
-
*/
|
|
154
|
-
type SuccessWithWarnings<W, A> = WarnResult<W, A> & {
|
|
155
|
-
_tag: "SuccessWithWarnings";
|
|
156
|
-
};
|
|
157
|
-
/**
|
|
158
|
-
* Constructs a `SuccessWithWarnings` — a `WarnResult` that carries both a
|
|
159
|
-
* `success` value and `warnings`.
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* ```ts
|
|
163
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
164
|
-
*
|
|
165
|
-
* const value = WarnResult.SuccessWithWarnings({
|
|
166
|
-
* warnings: "rounded down",
|
|
167
|
-
* success: 1
|
|
168
|
-
* })
|
|
169
|
-
*
|
|
170
|
-
* assert.deepStrictEqual(value._tag, "SuccessWithWarnings")
|
|
171
|
-
* assert.deepStrictEqual(value.warnings, "rounded down")
|
|
172
|
-
* assert.deepStrictEqual(value.success, 1)
|
|
173
|
-
* ```
|
|
174
|
-
*
|
|
175
|
-
* @category constructors
|
|
176
|
-
* @since 0.0.0
|
|
177
|
-
*/
|
|
178
|
-
declare const SuccessWithWarnings: <A, B>(args: {
|
|
179
|
-
readonly warnings: A;
|
|
180
|
-
readonly success: B;
|
|
181
|
-
}) => {
|
|
182
|
-
readonly _tag: "SuccessWithWarnings";
|
|
183
|
-
readonly warnings: A;
|
|
184
|
-
readonly success: B;
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
187
|
-
* Builds per-tag refinements for `WarnResult`. `is("WarningsOnly")` is a type
|
|
188
|
-
* guard that narrows a `WarnResult` to its `WarningsOnly` member, and likewise for
|
|
189
|
-
* `"SuccessOnly"` and `"SuccessWithWarnings"`.
|
|
190
|
-
*
|
|
191
|
-
* @example
|
|
192
|
-
* ```ts
|
|
193
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
194
|
-
*
|
|
195
|
-
* assert.deepStrictEqual(
|
|
196
|
-
* WarnResult.is("WarningsOnly")(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
197
|
-
* true
|
|
198
|
-
* )
|
|
199
|
-
* assert.deepStrictEqual(
|
|
200
|
-
* WarnResult.is("WarningsOnly")(WarnResult.SuccessOnly({ success: 1 })),
|
|
201
|
-
* false
|
|
202
|
-
* )
|
|
203
|
-
* ```
|
|
204
|
-
*
|
|
205
|
-
* @category guards
|
|
206
|
-
* @since 0.0.0
|
|
207
|
-
*/
|
|
208
|
-
declare const is: <Tag extends "WarningsOnly" | "SuccessOnly" | "SuccessWithWarnings">(tag: Tag) => {
|
|
209
|
-
<T extends {
|
|
210
|
-
readonly _tag: "WarningsOnly";
|
|
211
|
-
readonly warnings: any;
|
|
212
|
-
} | {
|
|
213
|
-
readonly _tag: "SuccessOnly";
|
|
214
|
-
readonly success: any;
|
|
215
|
-
} | {
|
|
216
|
-
readonly _tag: "SuccessWithWarnings";
|
|
217
|
-
readonly warnings: any;
|
|
218
|
-
readonly success: any;
|
|
219
|
-
}>(u: T): u is T & {
|
|
220
|
-
readonly _tag: Tag;
|
|
221
|
-
};
|
|
222
|
-
(u: unknown): u is Extract<{
|
|
223
|
-
readonly _tag: "WarningsOnly";
|
|
224
|
-
readonly warnings: unknown;
|
|
225
|
-
}, {
|
|
226
|
-
readonly _tag: Tag;
|
|
227
|
-
}> | Extract<{
|
|
228
|
-
readonly _tag: "SuccessOnly";
|
|
229
|
-
readonly success: unknown;
|
|
230
|
-
}, {
|
|
231
|
-
readonly _tag: Tag;
|
|
232
|
-
}> | Extract<{
|
|
233
|
-
readonly _tag: "SuccessWithWarnings";
|
|
234
|
-
readonly warnings: unknown;
|
|
235
|
-
readonly success: unknown;
|
|
236
|
-
}, {
|
|
237
|
-
readonly _tag: Tag;
|
|
238
|
-
}>;
|
|
239
|
-
};
|
|
240
|
-
/**
|
|
241
|
-
* Folds a `WarnResult` over its three tags. Provide a handler for `WarningsOnly`,
|
|
242
|
-
* `SuccessOnly`, and `SuccessWithWarnings` and `match` returns a function from a
|
|
243
|
-
* `WarnResult` to the handlers' common result type.
|
|
244
|
-
*
|
|
245
|
-
* @example
|
|
246
|
-
* ```ts
|
|
247
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
248
|
-
*
|
|
249
|
-
* const describe = WarnResult.match({
|
|
250
|
-
* WarningsOnly: ({ warnings }) => `warnings ${warnings}`,
|
|
251
|
-
* SuccessOnly: ({ success }) => `success ${success}`,
|
|
252
|
-
* SuccessWithWarnings: ({ warnings, success }) => `both ${warnings}/${success}`
|
|
253
|
-
* })
|
|
254
|
-
*
|
|
255
|
-
* assert.deepStrictEqual(
|
|
256
|
-
* describe(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
257
|
-
* "both w/1"
|
|
258
|
-
* )
|
|
259
|
-
* ```
|
|
260
|
-
*
|
|
261
|
-
* @category pattern matching
|
|
262
|
-
* @since 0.0.0
|
|
263
|
-
*/
|
|
264
|
-
declare const match$1: {
|
|
265
|
-
<A, B, C, D, Cases extends {
|
|
266
|
-
readonly WarningsOnly: (args: {
|
|
267
|
-
readonly _tag: "WarningsOnly";
|
|
268
|
-
readonly warnings: A;
|
|
269
|
-
}) => any;
|
|
270
|
-
readonly SuccessOnly: (args: {
|
|
271
|
-
readonly _tag: "SuccessOnly";
|
|
272
|
-
readonly success: B;
|
|
273
|
-
}) => any;
|
|
274
|
-
readonly SuccessWithWarnings: (args: {
|
|
275
|
-
readonly _tag: "SuccessWithWarnings";
|
|
276
|
-
readonly warnings: A;
|
|
277
|
-
readonly success: B;
|
|
278
|
-
}) => any;
|
|
279
|
-
}>(cases: Cases): (self: {
|
|
280
|
-
readonly _tag: "WarningsOnly";
|
|
281
|
-
readonly warnings: A;
|
|
282
|
-
} | {
|
|
283
|
-
readonly _tag: "SuccessOnly";
|
|
284
|
-
readonly success: B;
|
|
285
|
-
} | {
|
|
286
|
-
readonly _tag: "SuccessWithWarnings";
|
|
287
|
-
readonly warnings: A;
|
|
288
|
-
readonly success: B;
|
|
289
|
-
}) => effect_Unify.Unify<ReturnType<Cases["WarningsOnly" | "SuccessOnly" | "SuccessWithWarnings"]>>;
|
|
290
|
-
<A, B, C, D, Cases extends {
|
|
291
|
-
readonly WarningsOnly: (args: {
|
|
292
|
-
readonly _tag: "WarningsOnly";
|
|
293
|
-
readonly warnings: A;
|
|
294
|
-
}) => any;
|
|
295
|
-
readonly SuccessOnly: (args: {
|
|
296
|
-
readonly _tag: "SuccessOnly";
|
|
297
|
-
readonly success: B;
|
|
298
|
-
}) => any;
|
|
299
|
-
readonly SuccessWithWarnings: (args: {
|
|
300
|
-
readonly _tag: "SuccessWithWarnings";
|
|
301
|
-
readonly warnings: A;
|
|
302
|
-
readonly success: B;
|
|
303
|
-
}) => any;
|
|
304
|
-
}>(self: {
|
|
305
|
-
readonly _tag: "WarningsOnly";
|
|
306
|
-
readonly warnings: A;
|
|
307
|
-
} | {
|
|
308
|
-
readonly _tag: "SuccessOnly";
|
|
309
|
-
readonly success: B;
|
|
310
|
-
} | {
|
|
311
|
-
readonly _tag: "SuccessWithWarnings";
|
|
312
|
-
readonly warnings: A;
|
|
313
|
-
readonly success: B;
|
|
314
|
-
}, cases: Cases): effect_Unify.Unify<ReturnType<Cases["WarningsOnly" | "SuccessOnly" | "SuccessWithWarnings"]>>;
|
|
315
|
-
};
|
|
316
|
-
/**
|
|
317
|
-
* Any `WarnResult` that is guaranteed to carry `warnings` — either `WarningsOnly`
|
|
318
|
-
* or `SuccessWithWarnings`.
|
|
319
|
-
*
|
|
320
|
-
* @example
|
|
321
|
-
* ```ts
|
|
322
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
323
|
-
*
|
|
324
|
-
* const value: WarnResult.WithWarnings<string, number> = WarnResult.WarningsOnly({
|
|
325
|
-
* warnings: "skipped 2 rows"
|
|
326
|
-
* })
|
|
327
|
-
*
|
|
328
|
-
* assert.deepStrictEqual(value.warnings, "skipped 2 rows")
|
|
329
|
-
* ```
|
|
330
|
-
*
|
|
331
|
-
* @category models
|
|
332
|
-
* @since 0.0.0
|
|
333
|
-
*/
|
|
334
|
-
type WithWarnings<W, A> = WarningsOnly<W> | SuccessWithWarnings<W, A>;
|
|
335
|
-
/**
|
|
336
|
-
* Builds a `WarnResult` known to carry `warnings`, choosing `SuccessWithWarnings`
|
|
337
|
-
* when a `success` value is present and `WarningsOnly` otherwise.
|
|
338
|
-
*
|
|
339
|
-
* Use it when the `warnings` are mandatory and the `success` value is an optional
|
|
340
|
-
* companion: pass an absent (`null`/`undefined`) `success` to get a
|
|
341
|
-
* `WarningsOnly`, or a present one to get a `SuccessWithWarnings`. The return type
|
|
342
|
-
* `WithWarnings<W, A>` reflects that `warnings` are always present.
|
|
343
|
-
*
|
|
344
|
-
* @example
|
|
345
|
-
* ```ts
|
|
346
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
347
|
-
*
|
|
348
|
-
* assert.deepStrictEqual(
|
|
349
|
-
* WarnResult.WithWarnings({ warnings: "w", success: 1 }),
|
|
350
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
|
|
351
|
-
* )
|
|
352
|
-
*
|
|
353
|
-
* assert.deepStrictEqual(
|
|
354
|
-
* WarnResult.WithWarnings({ warnings: "w" }),
|
|
355
|
-
* WarnResult.WarningsOnly({ warnings: "w" })
|
|
356
|
-
* )
|
|
357
|
-
* ```
|
|
358
|
-
*
|
|
359
|
-
* @category constructors
|
|
360
|
-
* @since 0.0.0
|
|
361
|
-
*/
|
|
362
|
-
declare const WithWarnings: <W, A>({ warnings, success, }: {
|
|
363
|
-
warnings: W;
|
|
364
|
-
success?: A | undefined;
|
|
365
|
-
}) => WithWarnings<W, A>;
|
|
366
|
-
/**
|
|
367
|
-
* Any `WarnResult` that is guaranteed to carry a `success` value — either
|
|
368
|
-
* `SuccessOnly` or `SuccessWithWarnings`.
|
|
369
|
-
*
|
|
370
|
-
* @example
|
|
371
|
-
* ```ts
|
|
372
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
373
|
-
*
|
|
374
|
-
* const value: WarnResult.WithSuccess<string, number> = WarnResult.SuccessOnly({
|
|
375
|
-
* success: 1
|
|
376
|
-
* })
|
|
377
|
-
*
|
|
378
|
-
* assert.deepStrictEqual(value.success, 1)
|
|
379
|
-
* ```
|
|
380
|
-
*
|
|
381
|
-
* @category models
|
|
382
|
-
* @since 0.0.0
|
|
383
|
-
*/
|
|
384
|
-
type WithSuccess<W, A> = SuccessOnly<A> | SuccessWithWarnings<W, A>;
|
|
385
|
-
/**
|
|
386
|
-
* Builds a `WarnResult` known to carry a `success` value, choosing
|
|
387
|
-
* `SuccessWithWarnings` when `warnings` are present and `SuccessOnly` otherwise.
|
|
388
|
-
*
|
|
389
|
-
* The mirror of `WithWarnings`: the `success` value is mandatory and the
|
|
390
|
-
* `warnings` are an optional companion. Pass absent (`null`/`undefined`)
|
|
391
|
-
* `warnings` to get a `SuccessOnly`, or present ones to get a
|
|
392
|
-
* `SuccessWithWarnings`. The return type `WithSuccess<W, A>` reflects that a
|
|
393
|
-
* `success` value is always present.
|
|
394
|
-
*
|
|
395
|
-
* @example
|
|
396
|
-
* ```ts
|
|
397
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
398
|
-
*
|
|
399
|
-
* assert.deepStrictEqual(
|
|
400
|
-
* WarnResult.WithSuccess({ warnings: "w", success: 1 }),
|
|
401
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
|
|
402
|
-
* )
|
|
403
|
-
*
|
|
404
|
-
* assert.deepStrictEqual(
|
|
405
|
-
* WarnResult.WithSuccess({ success: 1 }),
|
|
406
|
-
* WarnResult.SuccessOnly({ success: 1 })
|
|
407
|
-
* )
|
|
408
|
-
* ```
|
|
409
|
-
*
|
|
410
|
-
* @category constructors
|
|
411
|
-
* @since 0.0.0
|
|
412
|
-
*/
|
|
413
|
-
declare const WithSuccess: <W, A>({ warnings, success, }: {
|
|
414
|
-
warnings?: W | undefined;
|
|
415
|
-
success: A;
|
|
416
|
-
}) => WithSuccess<W, A>;
|
|
417
|
-
/**
|
|
418
|
-
* Builds a `WarnResult` from a pair of possibly-nullish inputs, wrapping the
|
|
419
|
-
* result in an `Option` so the all-absent case is expressible.
|
|
420
|
-
*
|
|
421
|
-
* Returns `Option.some(SuccessWithWarnings)` when both are present,
|
|
422
|
-
* `Option.some(WarningsOnly)` or `Option.some(SuccessOnly)` when exactly one is
|
|
423
|
-
* present, and `Option.none()` when both are nullish. Use it as the total entry
|
|
424
|
-
* point for turning an optional success value and optional warnings into a
|
|
425
|
-
* `WarnResult`.
|
|
426
|
-
*
|
|
427
|
-
* @example
|
|
428
|
-
* ```ts
|
|
429
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
430
|
-
* import { Option } from "effect"
|
|
431
|
-
*
|
|
432
|
-
* assert.deepStrictEqual(
|
|
433
|
-
* WarnResult.optionFromNullables({ warnings: "w", success: 1 }),
|
|
434
|
-
* Option.some(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
|
|
435
|
-
* )
|
|
436
|
-
*
|
|
437
|
-
* assert.deepStrictEqual(
|
|
438
|
-
* WarnResult.optionFromNullables({ warnings: "w", success: null }),
|
|
439
|
-
* Option.some(WarnResult.WarningsOnly({ warnings: "w" }))
|
|
440
|
-
* )
|
|
441
|
-
*
|
|
442
|
-
* assert.deepStrictEqual(
|
|
443
|
-
* WarnResult.optionFromNullables({ warnings: null, success: undefined }),
|
|
444
|
-
* Option.none()
|
|
445
|
-
* )
|
|
446
|
-
* ```
|
|
447
|
-
*
|
|
448
|
-
* @category constructors
|
|
449
|
-
* @since 0.0.0
|
|
450
|
-
*/
|
|
451
|
-
declare const optionFromNullables: <W, A>({ warnings, success, }: {
|
|
452
|
-
warnings?: W | null | undefined;
|
|
453
|
-
success?: A | null | undefined;
|
|
454
|
-
}) => Option.Option<WarnResult<W, A>>;
|
|
455
|
-
/**
|
|
456
|
-
* Builds a `WarnResult` from a pair of possibly-nullish inputs, falling back to
|
|
457
|
-
* the `orElse` thunk when both are absent.
|
|
458
|
-
*
|
|
459
|
-
* The non-optional companion to `optionFromNullables`: it unwraps the same logic
|
|
460
|
-
* but resolves the all-absent case with `orElse` instead of an `Option`. The
|
|
461
|
-
* default `orElse` throws, so omit it only when at least one side is guaranteed
|
|
462
|
-
* present.
|
|
463
|
-
*
|
|
464
|
-
* @example
|
|
465
|
-
* ```ts
|
|
466
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
467
|
-
*
|
|
468
|
-
* assert.deepStrictEqual(
|
|
469
|
-
* WarnResult.fromNullables({ warnings: "w", success: 1 }),
|
|
470
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
|
|
471
|
-
* )
|
|
472
|
-
*
|
|
473
|
-
* // Both absent — fall back via orElse instead of throwing
|
|
474
|
-
* assert.deepStrictEqual(
|
|
475
|
-
* WarnResult.fromNullables({
|
|
476
|
-
* warnings: null,
|
|
477
|
-
* success: null,
|
|
478
|
-
* orElse: () => WarnResult.WarningsOnly({ warnings: "none" })
|
|
479
|
-
* }),
|
|
480
|
-
* WarnResult.WarningsOnly({ warnings: "none" })
|
|
481
|
-
* )
|
|
482
|
-
* ```
|
|
483
|
-
*
|
|
484
|
-
* @category constructors
|
|
485
|
-
* @since 0.0.0
|
|
486
|
-
*/
|
|
487
|
-
declare const fromNullables: <W, A>({ warnings, success, orElse, }: {
|
|
488
|
-
warnings?: W | null | undefined;
|
|
489
|
-
success?: A | null | undefined;
|
|
490
|
-
orElse?: () => WarnResult<W, A>;
|
|
491
|
-
}) => WarnResult<W, A>;
|
|
492
|
-
/**
|
|
493
|
-
* Folds a `WarnResult` from the warnings' perspective, collapsing the three tags
|
|
494
|
-
* into two handlers.
|
|
495
|
-
*
|
|
496
|
-
* Both `WarningsOnly` and `SuccessWithWarnings` carry `warnings`, so they route to
|
|
497
|
-
* the `Warnings` handler; only `SuccessOnly` lacks `warnings` and routes to
|
|
498
|
-
* `SuccessOnly`. Use it when you care about the `warnings` and treat the
|
|
499
|
-
* success-only case as the exception.
|
|
500
|
-
*
|
|
501
|
-
* @example
|
|
502
|
-
* ```ts
|
|
503
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
504
|
-
*
|
|
505
|
-
* const onWarnings = WarnResult.matchWarnings({
|
|
506
|
-
* Warnings: (warnings: string) => `warnings ${warnings}`,
|
|
507
|
-
* SuccessOnly: (success: number) => `success ${success}`
|
|
508
|
-
* })
|
|
509
|
-
*
|
|
510
|
-
* assert.deepStrictEqual(
|
|
511
|
-
* onWarnings(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
512
|
-
* "warnings w"
|
|
513
|
-
* )
|
|
514
|
-
* assert.deepStrictEqual(
|
|
515
|
-
* onWarnings(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
516
|
-
* "warnings w"
|
|
517
|
-
* )
|
|
518
|
-
* assert.deepStrictEqual(
|
|
519
|
-
* onWarnings(WarnResult.SuccessOnly({ success: 1 })),
|
|
520
|
-
* "success 1"
|
|
521
|
-
* )
|
|
522
|
-
* ```
|
|
523
|
-
*
|
|
524
|
-
* @category pattern matching
|
|
525
|
-
* @since 0.0.0
|
|
526
|
-
*/
|
|
527
|
-
declare const matchWarnings: <W, A, Z>({ Warnings, SuccessOnly, }: {
|
|
528
|
-
Warnings: (warnings: W) => Z;
|
|
529
|
-
SuccessOnly: (success: A) => Z;
|
|
530
|
-
}) => (warnResult: WarnResult<W, A>) => Z;
|
|
531
|
-
/**
|
|
532
|
-
* Folds a `WarnResult` from the success value's perspective, collapsing the three
|
|
533
|
-
* tags into two handlers.
|
|
534
|
-
*
|
|
535
|
-
* The mirror of `matchWarnings`: both `SuccessOnly` and `SuccessWithWarnings`
|
|
536
|
-
* carry a `success` value, so they route to the `Success` handler; only
|
|
537
|
-
* `WarningsOnly` lacks a `success` value and routes to `WarningsOnly`. Use it when
|
|
538
|
-
* you care about the `success` value and treat the warnings-only case as the
|
|
539
|
-
* exception.
|
|
540
|
-
*
|
|
541
|
-
* @example
|
|
542
|
-
* ```ts
|
|
543
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
544
|
-
*
|
|
545
|
-
* const onSuccess = WarnResult.matchSuccess({
|
|
546
|
-
* WarningsOnly: (warnings: string) => `warnings ${warnings}`,
|
|
547
|
-
* Success: (success: number) => `success ${success}`
|
|
548
|
-
* })
|
|
549
|
-
*
|
|
550
|
-
* assert.deepStrictEqual(
|
|
551
|
-
* onSuccess(WarnResult.SuccessOnly({ success: 1 })),
|
|
552
|
-
* "success 1"
|
|
553
|
-
* )
|
|
554
|
-
* assert.deepStrictEqual(
|
|
555
|
-
* onSuccess(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
556
|
-
* "success 1"
|
|
557
|
-
* )
|
|
558
|
-
* assert.deepStrictEqual(
|
|
559
|
-
* onSuccess(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
560
|
-
* "warnings w"
|
|
561
|
-
* )
|
|
562
|
-
* ```
|
|
563
|
-
*
|
|
564
|
-
* @category pattern matching
|
|
565
|
-
* @since 0.0.0
|
|
566
|
-
*/
|
|
567
|
-
declare const matchSuccess: <W, A, Z>({ WarningsOnly, Success, }: {
|
|
568
|
-
WarningsOnly: (warnings: W) => Z;
|
|
569
|
-
Success: (success: A) => Z;
|
|
570
|
-
}) => (warnResult: WarnResult<W, A>) => Z;
|
|
571
|
-
/**
|
|
572
|
-
* Completes a `WarnResult` into a guaranteed `SuccessWithWarnings` by filling
|
|
573
|
-
* whichever side is missing from the matching `orElse` thunk.
|
|
574
|
-
*
|
|
575
|
-
* A `SuccessWithWarnings` passes through unchanged; a `WarningsOnly` gains a
|
|
576
|
-
* `success` value from `orElseSuccess`; a `SuccessOnly` gains `warnings` from
|
|
577
|
-
* `orElseWarnings`. Use it to normalise a partial `WarnResult` into the
|
|
578
|
-
* both-present shape before reading both sides.
|
|
579
|
-
*
|
|
580
|
-
* @example
|
|
581
|
-
* ```ts
|
|
582
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
583
|
-
*
|
|
584
|
-
* const fill = WarnResult.orElse({
|
|
585
|
-
* orElseWarnings: () => "no warnings",
|
|
586
|
-
* orElseSuccess: () => 0
|
|
587
|
-
* })
|
|
588
|
-
*
|
|
589
|
-
* assert.deepStrictEqual(
|
|
590
|
-
* fill(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
591
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 0 })
|
|
592
|
-
* )
|
|
593
|
-
* assert.deepStrictEqual(
|
|
594
|
-
* fill(WarnResult.SuccessOnly({ success: 1 })),
|
|
595
|
-
* WarnResult.SuccessWithWarnings({ warnings: "no warnings", success: 1 })
|
|
596
|
-
* )
|
|
597
|
-
* ```
|
|
598
|
-
*
|
|
599
|
-
* @category getters
|
|
600
|
-
* @since 0.0.0
|
|
601
|
-
*/
|
|
602
|
-
declare const orElse: <W2, A2>({ orElseWarnings, orElseSuccess, }: {
|
|
603
|
-
orElseWarnings: () => W2;
|
|
604
|
-
orElseSuccess: () => A2;
|
|
605
|
-
}) => (<W, A>(warnResult: WarnResult<W, A>) => SuccessWithWarnings<W | W2, A | A2>);
|
|
606
|
-
/**
|
|
607
|
-
* Completes a `WarnResult` into a `SuccessWithWarnings` whose missing side is
|
|
608
|
-
* filled with `undefined`.
|
|
609
|
-
*
|
|
610
|
-
* A specialisation of `orElse` that supplies `undefined` for whichever side is
|
|
611
|
-
* absent, so the result always exposes both `warnings` and `success` keys (each
|
|
612
|
-
* possibly `undefined`). Use it when you want to destructure both sides without
|
|
613
|
-
* branching on the tag.
|
|
614
|
-
*
|
|
615
|
-
* @example
|
|
616
|
-
* ```ts
|
|
617
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
618
|
-
*
|
|
619
|
-
* assert.deepStrictEqual(
|
|
620
|
-
* WarnResult.orUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
621
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: undefined })
|
|
622
|
-
* )
|
|
623
|
-
* assert.deepStrictEqual(
|
|
624
|
-
* WarnResult.orUndefined(WarnResult.SuccessOnly({ success: 1 })),
|
|
625
|
-
* WarnResult.SuccessWithWarnings({ warnings: undefined, success: 1 })
|
|
626
|
-
* )
|
|
627
|
-
* ```
|
|
628
|
-
*
|
|
629
|
-
* @category getters
|
|
630
|
-
* @since 0.0.0
|
|
631
|
-
*/
|
|
632
|
-
declare const orUndefined: <W, A>(warnResult: {
|
|
633
|
-
readonly _tag: "WarningsOnly";
|
|
634
|
-
readonly warnings: W;
|
|
635
|
-
} | {
|
|
636
|
-
readonly _tag: "SuccessOnly";
|
|
637
|
-
readonly success: A;
|
|
638
|
-
} | {
|
|
639
|
-
readonly _tag: "SuccessWithWarnings";
|
|
640
|
-
readonly warnings: W;
|
|
641
|
-
readonly success: A;
|
|
642
|
-
}) => {
|
|
643
|
-
readonly _tag: "SuccessWithWarnings";
|
|
644
|
-
readonly warnings: W | undefined;
|
|
645
|
-
readonly success: A | undefined;
|
|
646
|
-
} & {
|
|
647
|
-
_tag: "SuccessWithWarnings";
|
|
648
|
-
};
|
|
649
|
-
/**
|
|
650
|
-
* Extracts the `warnings` of a `WarnResult`, falling back to `orElseReturn` when
|
|
651
|
-
* no `warnings` are present.
|
|
652
|
-
*
|
|
653
|
-
* `WarningsOnly` and `SuccessWithWarnings` return their `warnings`; `SuccessOnly`
|
|
654
|
-
* returns the result of `orElseReturn`. Use it to read the warnings with a default
|
|
655
|
-
* in one step.
|
|
656
|
-
*
|
|
657
|
-
* @example
|
|
658
|
-
* ```ts
|
|
659
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
660
|
-
*
|
|
661
|
-
* const warningsOrNone = WarnResult.warningsOrElse(() => "no warnings")
|
|
662
|
-
*
|
|
663
|
-
* assert.deepStrictEqual(
|
|
664
|
-
* warningsOrNone(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
665
|
-
* "w"
|
|
666
|
-
* )
|
|
667
|
-
* assert.deepStrictEqual(
|
|
668
|
-
* warningsOrNone(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
669
|
-
* "w"
|
|
670
|
-
* )
|
|
671
|
-
* assert.deepStrictEqual(
|
|
672
|
-
* warningsOrNone(WarnResult.SuccessOnly({ success: 1 })),
|
|
673
|
-
* "no warnings"
|
|
674
|
-
* )
|
|
675
|
-
* ```
|
|
676
|
-
*
|
|
677
|
-
* @category getters
|
|
678
|
-
* @since 0.0.0
|
|
679
|
-
*/
|
|
680
|
-
declare const warningsOrElse: <Z>(orElseReturn: () => Z) => <W, A>(warnResult: WarnResult<W, A>) => W | Z;
|
|
681
|
-
/**
|
|
682
|
-
* Extracts the `warnings` of a `WarnResult`, returning `undefined` when no
|
|
683
|
-
* `warnings` are present.
|
|
684
|
-
*
|
|
685
|
-
* A specialisation of `warningsOrElse` whose fallback is `undefined`:
|
|
686
|
-
* `WarningsOnly` and `SuccessWithWarnings` yield their `warnings`, while
|
|
687
|
-
* `SuccessOnly` yields `undefined`.
|
|
688
|
-
*
|
|
689
|
-
* @example
|
|
690
|
-
* ```ts
|
|
691
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
692
|
-
*
|
|
693
|
-
* assert.deepStrictEqual(
|
|
694
|
-
* WarnResult.warningsOrUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
695
|
-
* "w"
|
|
696
|
-
* )
|
|
697
|
-
* assert.deepStrictEqual(
|
|
698
|
-
* WarnResult.warningsOrUndefined(WarnResult.SuccessOnly({ success: 1 })),
|
|
699
|
-
* undefined
|
|
700
|
-
* )
|
|
701
|
-
* ```
|
|
702
|
-
*
|
|
703
|
-
* @category getters
|
|
704
|
-
* @since 0.0.0
|
|
705
|
-
*/
|
|
706
|
-
declare const warningsOrUndefined: <W, A>(warnResult: {
|
|
707
|
-
readonly _tag: "WarningsOnly";
|
|
708
|
-
readonly warnings: W;
|
|
709
|
-
} | {
|
|
710
|
-
readonly _tag: "SuccessOnly";
|
|
711
|
-
readonly success: A;
|
|
712
|
-
} | {
|
|
713
|
-
readonly _tag: "SuccessWithWarnings";
|
|
714
|
-
readonly warnings: W;
|
|
715
|
-
readonly success: A;
|
|
716
|
-
}) => W | undefined;
|
|
717
|
-
/**
|
|
718
|
-
* Extracts the `success` value of a `WarnResult`, falling back to `orElseReturn`
|
|
719
|
-
* when no `success` value is present.
|
|
720
|
-
*
|
|
721
|
-
* The mirror of `warningsOrElse`: `SuccessOnly` and `SuccessWithWarnings` return
|
|
722
|
-
* their `success` value; `WarningsOnly` returns the result of `orElseReturn`.
|
|
723
|
-
*
|
|
724
|
-
* @example
|
|
725
|
-
* ```ts
|
|
726
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
727
|
-
*
|
|
728
|
-
* const successOrZero = WarnResult.successOrElse(() => 0)
|
|
729
|
-
*
|
|
730
|
-
* assert.deepStrictEqual(
|
|
731
|
-
* successOrZero(WarnResult.SuccessOnly({ success: 1 })),
|
|
732
|
-
* 1
|
|
733
|
-
* )
|
|
734
|
-
* assert.deepStrictEqual(
|
|
735
|
-
* successOrZero(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
736
|
-
* 0
|
|
737
|
-
* )
|
|
738
|
-
* ```
|
|
739
|
-
*
|
|
740
|
-
* @category getters
|
|
741
|
-
* @since 0.0.0
|
|
742
|
-
*/
|
|
743
|
-
declare const successOrElse: <Z>(orElseReturn: () => Z) => <W, A>(warnResult: WarnResult<W, A>) => A | Z;
|
|
744
|
-
/**
|
|
745
|
-
* Extracts the `success` value of a `WarnResult`, returning `undefined` when no
|
|
746
|
-
* `success` value is present.
|
|
747
|
-
*
|
|
748
|
-
* A specialisation of `successOrElse` whose fallback is `undefined`: `SuccessOnly`
|
|
749
|
-
* and `SuccessWithWarnings` yield their `success` value, while `WarningsOnly`
|
|
750
|
-
* yields `undefined`.
|
|
751
|
-
*
|
|
752
|
-
* @example
|
|
753
|
-
* ```ts
|
|
754
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
755
|
-
*
|
|
756
|
-
* assert.deepStrictEqual(
|
|
757
|
-
* WarnResult.successOrUndefined(WarnResult.SuccessOnly({ success: 1 })),
|
|
758
|
-
* 1
|
|
759
|
-
* )
|
|
760
|
-
* assert.deepStrictEqual(
|
|
761
|
-
* WarnResult.successOrUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
762
|
-
* undefined
|
|
763
|
-
* )
|
|
764
|
-
* ```
|
|
765
|
-
*
|
|
766
|
-
* @category getters
|
|
767
|
-
* @since 0.0.0
|
|
768
|
-
*/
|
|
769
|
-
declare const successOrUndefined: <W, A>(warnResult: {
|
|
770
|
-
readonly _tag: "WarningsOnly";
|
|
771
|
-
readonly warnings: W;
|
|
772
|
-
} | {
|
|
773
|
-
readonly _tag: "SuccessOnly";
|
|
774
|
-
readonly success: A;
|
|
775
|
-
} | {
|
|
776
|
-
readonly _tag: "SuccessWithWarnings";
|
|
777
|
-
readonly warnings: W;
|
|
778
|
-
readonly success: A;
|
|
779
|
-
}) => A | undefined;
|
|
780
|
-
/**
|
|
781
|
-
* Extracts the `success` value of a `WarnResult` as an `Option`.
|
|
782
|
-
*
|
|
783
|
-
* `SuccessOnly` and `SuccessWithWarnings` yield `Option.some(success)`;
|
|
784
|
-
* `WarningsOnly` yields `Option.none()`. Use it when you want to chain the success
|
|
785
|
-
* value through `Option` combinators rather than fall back to a default eagerly.
|
|
786
|
-
*
|
|
787
|
-
* @example
|
|
788
|
-
* ```ts
|
|
789
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
790
|
-
* import { Option } from "effect"
|
|
791
|
-
*
|
|
792
|
-
* assert.deepStrictEqual(
|
|
793
|
-
* WarnResult.successOption(WarnResult.SuccessOnly({ success: 1 })),
|
|
794
|
-
* Option.some(1)
|
|
795
|
-
* )
|
|
796
|
-
* assert.deepStrictEqual(
|
|
797
|
-
* WarnResult.successOption(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
798
|
-
* Option.none()
|
|
799
|
-
* )
|
|
800
|
-
* ```
|
|
801
|
-
*
|
|
802
|
-
* @category getters
|
|
803
|
-
* @since 0.0.0
|
|
804
|
-
*/
|
|
805
|
-
declare const successOption: <W, A>(warnResult: WarnResult<W, A>) => Option.Option<A>;
|
|
806
|
-
/**
|
|
807
|
-
* Extracts the `warnings` of a `WarnResult` as an `Option`.
|
|
808
|
-
*
|
|
809
|
-
* The mirror of `successOption`: `WarningsOnly` and `SuccessWithWarnings` yield
|
|
810
|
-
* `Option.some(warnings)`, while `SuccessOnly` yields `Option.none()`.
|
|
811
|
-
*
|
|
812
|
-
* @example
|
|
813
|
-
* ```ts
|
|
814
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
815
|
-
* import { Option } from "effect"
|
|
816
|
-
*
|
|
817
|
-
* assert.deepStrictEqual(
|
|
818
|
-
* WarnResult.warningsOption(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
819
|
-
* Option.some("w")
|
|
820
|
-
* )
|
|
821
|
-
* assert.deepStrictEqual(
|
|
822
|
-
* WarnResult.warningsOption(WarnResult.SuccessOnly({ success: 1 })),
|
|
823
|
-
* Option.none()
|
|
824
|
-
* )
|
|
825
|
-
* ```
|
|
826
|
-
*
|
|
827
|
-
* @category getters
|
|
828
|
-
* @since 0.0.0
|
|
829
|
-
*/
|
|
830
|
-
declare const warningsOption: <W, A>(warnResult: WarnResult<W, A>) => Option.Option<W>;
|
|
831
|
-
/**
|
|
832
|
-
* Transforms both sides of a `WarnResult`, applying `mapWarnings` to any
|
|
833
|
-
* `warnings` and `mapSuccess` to any `success` value.
|
|
834
|
-
*
|
|
835
|
-
* Each constructor is rebuilt with its mapped contents, so `WarningsOnly` maps
|
|
836
|
-
* only the warnings, `SuccessOnly` only the success value, and
|
|
837
|
-
* `SuccessWithWarnings` both. The tag is preserved. Use it as the bifunctor map
|
|
838
|
-
* over `WarnResult`.
|
|
839
|
-
*
|
|
840
|
-
* @example
|
|
841
|
-
* ```ts
|
|
842
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
843
|
-
*
|
|
844
|
-
* const both = WarnResult.mapBoth({
|
|
845
|
-
* mapWarnings: (warnings: string) => warnings.toUpperCase(),
|
|
846
|
-
* mapSuccess: (success: number) => success + 1
|
|
847
|
-
* })
|
|
848
|
-
*
|
|
849
|
-
* assert.deepStrictEqual(
|
|
850
|
-
* both(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
851
|
-
* WarnResult.SuccessWithWarnings({ warnings: "W", success: 2 })
|
|
852
|
-
* )
|
|
853
|
-
* assert.deepStrictEqual(
|
|
854
|
-
* both(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
855
|
-
* WarnResult.WarningsOnly({ warnings: "W" })
|
|
856
|
-
* )
|
|
857
|
-
* ```
|
|
858
|
-
*
|
|
859
|
-
* @category mapping
|
|
860
|
-
* @since 0.0.0
|
|
861
|
-
*/
|
|
862
|
-
declare const mapBoth: <W1, A1, W2, A2>({ mapWarnings, mapSuccess, }: {
|
|
863
|
-
mapWarnings: (warnings: W1) => W2;
|
|
864
|
-
mapSuccess: (success: A1) => A2;
|
|
865
|
-
}) => ((warnResult: WarnResult<W1, A1>) => WarnResult<W2, A2>);
|
|
866
|
-
/**
|
|
867
|
-
* Effectful `mapBoth`: transforms each present side through an `Effect`,
|
|
868
|
-
* reassembling the results into a `WarnResult` inside an `Effect`.
|
|
869
|
-
*
|
|
870
|
-
* For `SuccessWithWarnings` both effects run via `Effect.all` and their results
|
|
871
|
-
* are combined; `WarningsOnly`/`SuccessOnly` run only the relevant effect. Errors
|
|
872
|
-
* and requirements from both mappers are unioned into the result type. Use it when
|
|
873
|
-
* mapping a `WarnResult`'s sides requires effects (validation, IO).
|
|
874
|
-
*
|
|
875
|
-
* @example
|
|
876
|
-
* ```ts
|
|
877
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
878
|
-
* import { Effect } from "effect"
|
|
879
|
-
*
|
|
880
|
-
* const both = WarnResult.mapBothEffect({
|
|
881
|
-
* mapWarnings: (warnings: string) => Effect.succeed(warnings.toUpperCase()),
|
|
882
|
-
* mapSuccess: (success: number) => Effect.succeed(success + 1)
|
|
883
|
-
* })
|
|
884
|
-
*
|
|
885
|
-
* assert.deepStrictEqual(
|
|
886
|
-
* Effect.runSync(
|
|
887
|
-
* both(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
|
|
888
|
-
* ),
|
|
889
|
-
* WarnResult.SuccessWithWarnings({ warnings: "W", success: 2 })
|
|
890
|
-
* )
|
|
891
|
-
* ```
|
|
892
|
-
*
|
|
893
|
-
* @category sequencing
|
|
894
|
-
* @since 0.0.0
|
|
895
|
-
*/
|
|
896
|
-
declare const mapBothEffect: <W1, A1, W2, A2, EW, EA, RW, RA>({ mapWarnings, mapSuccess, }: {
|
|
897
|
-
mapWarnings: (warnings: W1) => Effect.Effect<W2, EW, RW>;
|
|
898
|
-
mapSuccess: (success: A1) => Effect.Effect<A2, EA, RA>;
|
|
899
|
-
}) => ((warnResult: WarnResult<W1, A1>) => Effect.Effect<WarnResult<W2, A2>, EW | EA, RW | RA>);
|
|
900
|
-
/**
|
|
901
|
-
* Transforms the `warnings` of a `WarnResult`, leaving any `success` value
|
|
902
|
-
* untouched.
|
|
903
|
-
*
|
|
904
|
-
* A specialisation of `mapBoth` with the success mapper set to `identity`:
|
|
905
|
-
* `WarningsOnly` and `SuccessWithWarnings` have their `warnings` mapped, while
|
|
906
|
-
* `SuccessOnly` passes through unchanged.
|
|
907
|
-
*
|
|
908
|
-
* @example
|
|
909
|
-
* ```ts
|
|
910
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
911
|
-
*
|
|
912
|
-
* const shout = WarnResult.mapWarnings((warnings: string) =>
|
|
913
|
-
* warnings.toUpperCase()
|
|
914
|
-
* )
|
|
915
|
-
*
|
|
916
|
-
* assert.deepStrictEqual(
|
|
917
|
-
* shout(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
918
|
-
* WarnResult.SuccessWithWarnings({ warnings: "W", success: 1 })
|
|
919
|
-
* )
|
|
920
|
-
* assert.deepStrictEqual(
|
|
921
|
-
* shout(WarnResult.SuccessOnly({ success: 1 })),
|
|
922
|
-
* WarnResult.SuccessOnly({ success: 1 })
|
|
923
|
-
* )
|
|
924
|
-
* ```
|
|
925
|
-
*
|
|
926
|
-
* @category mapping
|
|
927
|
-
* @since 0.0.0
|
|
928
|
-
*/
|
|
929
|
-
declare const mapWarnings: <W1, W2>(mapWarnings: (warnings: W1) => W2) => (<A>(warnResult: WarnResult<W1, A>) => WarnResult<W2, A>);
|
|
930
|
-
/**
|
|
931
|
-
* Chains the `warnings` of a `WarnResult` into a new `WarnResult`, flattening the
|
|
932
|
-
* result.
|
|
933
|
-
*
|
|
934
|
-
* Whenever `warnings` are present (`WarningsOnly` or `SuccessWithWarnings`) they
|
|
935
|
-
* are passed to `mapWarnings`, whose returned `WarnResult` replaces the original;
|
|
936
|
-
* `SuccessOnly` passes through unchanged. Use it to sequence warnings-driven
|
|
937
|
-
* computations that themselves produce a `WarnResult`.
|
|
938
|
-
*
|
|
939
|
-
* @example
|
|
940
|
-
* ```ts
|
|
941
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
942
|
-
*
|
|
943
|
-
* const chain = WarnResult.flatMapWarnings((warnings: string) =>
|
|
944
|
-
* warnings.length > 0
|
|
945
|
-
* ? WarnResult.WarningsOnly({ warnings: warnings.toUpperCase() })
|
|
946
|
-
* : WarnResult.SuccessOnly({ success: 0 })
|
|
947
|
-
* )
|
|
948
|
-
*
|
|
949
|
-
* assert.deepStrictEqual(
|
|
950
|
-
* chain(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
951
|
-
* WarnResult.WarningsOnly({ warnings: "W" })
|
|
952
|
-
* )
|
|
953
|
-
* assert.deepStrictEqual(
|
|
954
|
-
* chain(WarnResult.SuccessOnly({ success: 1 })),
|
|
955
|
-
* WarnResult.SuccessOnly({ success: 1 })
|
|
956
|
-
* )
|
|
957
|
-
* ```
|
|
958
|
-
*
|
|
959
|
-
* @category sequencing
|
|
960
|
-
* @since 0.0.0
|
|
961
|
-
*/
|
|
962
|
-
declare const flatMapWarnings: <W1, W2, A2>(mapWarnings: (warnings: W1) => WarnResult<W2, A2>) => (<A1>(warnResult: WarnResult<W1, A1>) => WarnResult<W2, A1 | A2>);
|
|
963
|
-
/**
|
|
964
|
-
* Effectful `mapWarnings`: transforms the `warnings` of a `WarnResult` through an
|
|
965
|
-
* `Effect`, leaving any `success` value untouched.
|
|
966
|
-
*
|
|
967
|
-
* A specialisation of `mapBothEffect` with the success mapper set to
|
|
968
|
-
* `Effect.succeed`: the `warnings` (when present) are mapped effectfully and the
|
|
969
|
-
* `success` value is carried through unchanged.
|
|
970
|
-
*
|
|
971
|
-
* @example
|
|
972
|
-
* ```ts
|
|
973
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
974
|
-
* import { Effect } from "effect"
|
|
975
|
-
*
|
|
976
|
-
* const shout = WarnResult.mapWarningsEffect((warnings: string) =>
|
|
977
|
-
* Effect.succeed(warnings.toUpperCase())
|
|
978
|
-
* )
|
|
979
|
-
*
|
|
980
|
-
* assert.deepStrictEqual(
|
|
981
|
-
* Effect.runSync(
|
|
982
|
-
* shout(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
|
|
983
|
-
* ),
|
|
984
|
-
* WarnResult.SuccessWithWarnings({ warnings: "W", success: 1 })
|
|
985
|
-
* )
|
|
986
|
-
* ```
|
|
987
|
-
*
|
|
988
|
-
* @category sequencing
|
|
989
|
-
* @since 0.0.0
|
|
990
|
-
*/
|
|
991
|
-
declare const mapWarningsEffect: <W1, W2, EW, RW>(mapWarnings: (warnings: W1) => Effect.Effect<W2, EW, RW>) => (<A>(warnResult: WarnResult<W1, A>) => Effect.Effect<WarnResult<W2, A>, EW, RW>);
|
|
992
|
-
/**
|
|
993
|
-
* Effectful `flatMapWarnings`: chains the `warnings` of a `WarnResult` into an
|
|
994
|
-
* `Effect` that yields a new `WarnResult`, flattening the result.
|
|
995
|
-
*
|
|
996
|
-
* When `warnings` are present they are passed to `mapWarnings`, whose effectful
|
|
997
|
-
* `WarnResult` replaces the original; `SuccessOnly` is lifted unchanged via
|
|
998
|
-
* `Effect.succeed`. Use it to sequence warnings-driven effectful computations that
|
|
999
|
-
* produce a `WarnResult`.
|
|
1000
|
-
*
|
|
1001
|
-
* @example
|
|
1002
|
-
* ```ts
|
|
1003
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
1004
|
-
* import { Effect } from "effect"
|
|
1005
|
-
*
|
|
1006
|
-
* const chain = WarnResult.flatMapWarningsEffect((warnings: string) =>
|
|
1007
|
-
* Effect.succeed(WarnResult.WarningsOnly({ warnings: warnings.toUpperCase() }))
|
|
1008
|
-
* )
|
|
1009
|
-
*
|
|
1010
|
-
* assert.deepStrictEqual(
|
|
1011
|
-
* Effect.runSync(chain(WarnResult.WarningsOnly({ warnings: "w" }))),
|
|
1012
|
-
* WarnResult.WarningsOnly({ warnings: "W" })
|
|
1013
|
-
* )
|
|
1014
|
-
* assert.deepStrictEqual(
|
|
1015
|
-
* Effect.runSync(chain(WarnResult.SuccessOnly({ success: 1 }))),
|
|
1016
|
-
* WarnResult.SuccessOnly({ success: 1 })
|
|
1017
|
-
* )
|
|
1018
|
-
* ```
|
|
1019
|
-
*
|
|
1020
|
-
* @category sequencing
|
|
1021
|
-
* @since 0.0.0
|
|
1022
|
-
*/
|
|
1023
|
-
declare const flatMapWarningsEffect: <W1, W2, A2, EW, RW>(mapWarnings: (warnings: W1) => Effect.Effect<WarnResult<W2, A2>, EW, RW>) => (<A1>(warnResult: WarnResult<W1, A1>) => Effect.Effect<WarnResult<W2, A1 | A2>, EW, RW>);
|
|
1024
|
-
/**
|
|
1025
|
-
* Transforms the `success` value of a `WarnResult`, leaving any `warnings`
|
|
1026
|
-
* untouched.
|
|
1027
|
-
*
|
|
1028
|
-
* The mirror of `mapWarnings`: `SuccessOnly` and `SuccessWithWarnings` have their
|
|
1029
|
-
* `success` value mapped, while `WarningsOnly` passes through unchanged.
|
|
1030
|
-
*
|
|
1031
|
-
* @example
|
|
1032
|
-
* ```ts
|
|
1033
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
1034
|
-
*
|
|
1035
|
-
* const inc = WarnResult.mapSuccess((success: number) => success + 1)
|
|
1036
|
-
*
|
|
1037
|
-
* assert.deepStrictEqual(
|
|
1038
|
-
* inc(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
|
|
1039
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 2 })
|
|
1040
|
-
* )
|
|
1041
|
-
* assert.deepStrictEqual(
|
|
1042
|
-
* inc(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
1043
|
-
* WarnResult.WarningsOnly({ warnings: "w" })
|
|
1044
|
-
* )
|
|
1045
|
-
* ```
|
|
1046
|
-
*
|
|
1047
|
-
* @category mapping
|
|
1048
|
-
* @since 0.0.0
|
|
1049
|
-
*/
|
|
1050
|
-
declare const mapSuccess: <A1, A2>(mapSuccess: (success: A1) => A2) => (<W>(warnResult: WarnResult<W, A1>) => WarnResult<W, A2>);
|
|
1051
|
-
/**
|
|
1052
|
-
* Chains the `success` value of a `WarnResult` into a new `WarnResult`, flattening
|
|
1053
|
-
* the result.
|
|
1054
|
-
*
|
|
1055
|
-
* The mirror of `flatMapWarnings`: whenever a `success` value is present
|
|
1056
|
-
* (`SuccessOnly` or `SuccessWithWarnings`) it is passed to `mapSuccess`, whose
|
|
1057
|
-
* returned `WarnResult` replaces the original; `WarningsOnly` passes through
|
|
1058
|
-
* unchanged.
|
|
1059
|
-
*
|
|
1060
|
-
* @example
|
|
1061
|
-
* ```ts
|
|
1062
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
1063
|
-
*
|
|
1064
|
-
* const chain = WarnResult.flatMapSuccess((success: number) =>
|
|
1065
|
-
* WarnResult.SuccessOnly({ success: success + 1 })
|
|
1066
|
-
* )
|
|
1067
|
-
*
|
|
1068
|
-
* assert.deepStrictEqual(
|
|
1069
|
-
* chain(WarnResult.SuccessOnly({ success: 1 })),
|
|
1070
|
-
* WarnResult.SuccessOnly({ success: 2 })
|
|
1071
|
-
* )
|
|
1072
|
-
* assert.deepStrictEqual(
|
|
1073
|
-
* chain(WarnResult.WarningsOnly({ warnings: "w" })),
|
|
1074
|
-
* WarnResult.WarningsOnly({ warnings: "w" })
|
|
1075
|
-
* )
|
|
1076
|
-
* ```
|
|
1077
|
-
*
|
|
1078
|
-
* @category sequencing
|
|
1079
|
-
* @since 0.0.0
|
|
1080
|
-
*/
|
|
1081
|
-
declare const flatMapSuccess: <W2, A1, A2>(mapSuccess: (success: A1) => WarnResult<W2, A2>) => (<W1>(warnResult: WarnResult<W1, A1>) => WarnResult<W1 | W2, A2>);
|
|
1082
|
-
/**
|
|
1083
|
-
* Effectful `mapSuccess`: transforms the `success` value of a `WarnResult` through
|
|
1084
|
-
* an `Effect`, leaving any `warnings` untouched.
|
|
1085
|
-
*
|
|
1086
|
-
* The mirror of `mapWarningsEffect`: the `success` value (when present) is mapped
|
|
1087
|
-
* effectfully and the `warnings` are carried through unchanged via
|
|
1088
|
-
* `Effect.succeed`.
|
|
1089
|
-
*
|
|
1090
|
-
* @example
|
|
1091
|
-
* ```ts
|
|
1092
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
1093
|
-
* import { Effect } from "effect"
|
|
1094
|
-
*
|
|
1095
|
-
* const inc = WarnResult.mapSuccessEffect((success: number) =>
|
|
1096
|
-
* Effect.succeed(success + 1)
|
|
1097
|
-
* )
|
|
1098
|
-
*
|
|
1099
|
-
* assert.deepStrictEqual(
|
|
1100
|
-
* Effect.runSync(
|
|
1101
|
-
* inc(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
|
|
1102
|
-
* ),
|
|
1103
|
-
* WarnResult.SuccessWithWarnings({ warnings: "w", success: 2 })
|
|
1104
|
-
* )
|
|
1105
|
-
* ```
|
|
1106
|
-
*
|
|
1107
|
-
* @category sequencing
|
|
1108
|
-
* @since 0.0.0
|
|
1109
|
-
*/
|
|
1110
|
-
declare const mapSuccessEffect: <A1, A2, EA, RA>(mapSuccess: (success: A1) => Effect.Effect<A2, EA, RA>) => (<W>(warnResult: WarnResult<W, A1>) => Effect.Effect<WarnResult<W, A2>, EA, RA>);
|
|
1111
|
-
/**
|
|
1112
|
-
* Effectful `flatMapSuccess`: chains the `success` value of a `WarnResult` into an
|
|
1113
|
-
* `Effect` that yields a new `WarnResult`, flattening the result.
|
|
1114
|
-
*
|
|
1115
|
-
* The mirror of `flatMapWarningsEffect`: when a `success` value is present it is
|
|
1116
|
-
* passed to `mapSuccess`, whose effectful `WarnResult` replaces the original;
|
|
1117
|
-
* `WarningsOnly` is lifted unchanged via `Effect.succeed`.
|
|
1118
|
-
*
|
|
1119
|
-
* @example
|
|
1120
|
-
* ```ts
|
|
1121
|
-
* import { WarnResult } from "@nunofyobiz/effect-extras"
|
|
1122
|
-
* import { Effect } from "effect"
|
|
1123
|
-
*
|
|
1124
|
-
* const chain = WarnResult.flatMapSuccessEffect((success: number) =>
|
|
1125
|
-
* Effect.succeed(WarnResult.SuccessOnly({ success: success + 1 }))
|
|
1126
|
-
* )
|
|
1127
|
-
*
|
|
1128
|
-
* assert.deepStrictEqual(
|
|
1129
|
-
* Effect.runSync(chain(WarnResult.SuccessOnly({ success: 1 }))),
|
|
1130
|
-
* WarnResult.SuccessOnly({ success: 2 })
|
|
1131
|
-
* )
|
|
1132
|
-
* assert.deepStrictEqual(
|
|
1133
|
-
* Effect.runSync(chain(WarnResult.WarningsOnly({ warnings: "w" }))),
|
|
1134
|
-
* WarnResult.WarningsOnly({ warnings: "w" })
|
|
1135
|
-
* )
|
|
1136
|
-
* ```
|
|
1137
|
-
*
|
|
1138
|
-
* @category sequencing
|
|
1139
|
-
* @since 0.0.0
|
|
1140
|
-
*/
|
|
1141
|
-
declare const flatMapSuccessEffect: <W2, A1, A2, EA, RA>(mapSuccess: (success: A1) => Effect.Effect<WarnResult<W2, A2>, EA, RA>) => (<W1>(warnResult: WarnResult<W1, A1>) => Effect.Effect<WarnResult<W1 | W2, A2>, EA, RA>);
|
|
1142
|
-
|
|
1143
|
-
declare const WarnResult$1_SuccessOnly: typeof SuccessOnly;
|
|
1144
|
-
declare const WarnResult$1_SuccessWithWarnings: typeof SuccessWithWarnings;
|
|
1145
|
-
type WarnResult$1_WarnResult<W, A> = WarnResult<W, A>;
|
|
1146
|
-
declare const WarnResult$1_WarningsOnly: typeof WarningsOnly;
|
|
1147
|
-
declare const WarnResult$1_WithSuccess: typeof WithSuccess;
|
|
1148
|
-
declare const WarnResult$1_WithWarnings: typeof WithWarnings;
|
|
1149
|
-
declare const WarnResult$1_flatMapSuccess: typeof flatMapSuccess;
|
|
1150
|
-
declare const WarnResult$1_flatMapSuccessEffect: typeof flatMapSuccessEffect;
|
|
1151
|
-
declare const WarnResult$1_flatMapWarnings: typeof flatMapWarnings;
|
|
1152
|
-
declare const WarnResult$1_flatMapWarningsEffect: typeof flatMapWarningsEffect;
|
|
1153
|
-
declare const WarnResult$1_fromNullables: typeof fromNullables;
|
|
1154
|
-
declare const WarnResult$1_is: typeof is;
|
|
1155
|
-
declare const WarnResult$1_mapBoth: typeof mapBoth;
|
|
1156
|
-
declare const WarnResult$1_mapBothEffect: typeof mapBothEffect;
|
|
1157
|
-
declare const WarnResult$1_mapSuccess: typeof mapSuccess;
|
|
1158
|
-
declare const WarnResult$1_mapSuccessEffect: typeof mapSuccessEffect;
|
|
1159
|
-
declare const WarnResult$1_mapWarnings: typeof mapWarnings;
|
|
1160
|
-
declare const WarnResult$1_mapWarningsEffect: typeof mapWarningsEffect;
|
|
1161
|
-
declare const WarnResult$1_matchSuccess: typeof matchSuccess;
|
|
1162
|
-
declare const WarnResult$1_matchWarnings: typeof matchWarnings;
|
|
1163
|
-
declare const WarnResult$1_optionFromNullables: typeof optionFromNullables;
|
|
1164
|
-
declare const WarnResult$1_orElse: typeof orElse;
|
|
1165
|
-
declare const WarnResult$1_orUndefined: typeof orUndefined;
|
|
1166
|
-
declare const WarnResult$1_successOption: typeof successOption;
|
|
1167
|
-
declare const WarnResult$1_successOrElse: typeof successOrElse;
|
|
1168
|
-
declare const WarnResult$1_successOrUndefined: typeof successOrUndefined;
|
|
1169
|
-
declare const WarnResult$1_warningsOption: typeof warningsOption;
|
|
1170
|
-
declare const WarnResult$1_warningsOrElse: typeof warningsOrElse;
|
|
1171
|
-
declare const WarnResult$1_warningsOrUndefined: typeof warningsOrUndefined;
|
|
1172
|
-
declare namespace WarnResult$1 {
|
|
1173
|
-
export { WarnResult$1_SuccessOnly as SuccessOnly, WarnResult$1_SuccessWithWarnings as SuccessWithWarnings, type WarnResult$1_WarnResult as WarnResult, WarnResult$1_WarningsOnly as WarningsOnly, WarnResult$1_WithSuccess as WithSuccess, WarnResult$1_WithWarnings as WithWarnings, WarnResult$1_flatMapSuccess as flatMapSuccess, WarnResult$1_flatMapSuccessEffect as flatMapSuccessEffect, WarnResult$1_flatMapWarnings as flatMapWarnings, WarnResult$1_flatMapWarningsEffect as flatMapWarningsEffect, WarnResult$1_fromNullables as fromNullables, WarnResult$1_is as is, WarnResult$1_mapBoth as mapBoth, WarnResult$1_mapBothEffect as mapBothEffect, WarnResult$1_mapSuccess as mapSuccess, WarnResult$1_mapSuccessEffect as mapSuccessEffect, WarnResult$1_mapWarnings as mapWarnings, WarnResult$1_mapWarningsEffect as mapWarningsEffect, match$1 as match, WarnResult$1_matchSuccess as matchSuccess, WarnResult$1_matchWarnings as matchWarnings, WarnResult$1_optionFromNullables as optionFromNullables, WarnResult$1_orElse as orElse, WarnResult$1_orUndefined as orUndefined, WarnResult$1_successOption as successOption, WarnResult$1_successOrElse as successOrElse, WarnResult$1_successOrUndefined as successOrUndefined, WarnResult$1_warningsOption as warningsOption, WarnResult$1_warningsOrElse as warningsOrElse, WarnResult$1_warningsOrUndefined as warningsOrUndefined };
|
|
1174
|
-
}
|
|
1175
|
-
|
|
1176
|
-
/**
|
|
1177
|
-
* Generic, framework-agnostic extensions to Effect's `Array` module.
|
|
1178
|
-
*
|
|
1179
|
-
* @since 0.0.0
|
|
1180
|
-
*/
|
|
1181
|
-
|
|
1182
|
-
/**
|
|
1183
|
-
* Returns a shallow copy of `array` between `start` (inclusive) and `end`
|
|
1184
|
-
* (exclusive), as a pipeable, dual-form alias for `Array.prototype.slice`.
|
|
1185
|
-
*
|
|
1186
|
-
* `Array.prototype.slice` is already non-mutating (it returns a shallow copy),
|
|
1187
|
-
* but it isn't pipeable. This helper makes it composable inside `pipe(...)`
|
|
1188
|
-
* chains alongside the rest of the codebase's Effect-style utilities.
|
|
1189
|
-
*
|
|
1190
|
-
* @example
|
|
1191
|
-
* ```ts
|
|
1192
|
-
* import { pipe } from "effect"
|
|
1193
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1194
|
-
*
|
|
1195
|
-
* // data-first
|
|
1196
|
-
* assert.deepStrictEqual(ArrayX.slice([1, 2, 3, 4], 1, 3), [2, 3])
|
|
1197
|
-
*
|
|
1198
|
-
* // data-last (pipeable)
|
|
1199
|
-
* assert.deepStrictEqual(pipe([1, 2, 3, 4], ArrayX.slice(1, 3)), [2, 3])
|
|
1200
|
-
* ```
|
|
1201
|
-
*
|
|
1202
|
-
* @category getters
|
|
1203
|
-
* @since 0.0.0
|
|
1204
|
-
*/
|
|
1205
|
-
declare const slice: (<A>(start: number, end: number) => (array: readonly A[]) => A[]) & (<A>(array: readonly A[], start: number, end: number) => A[]);
|
|
1206
|
-
/**
|
|
1207
|
-
* Zips two arrays into one, calling `f` with a `WarnResult` for each index so
|
|
1208
|
-
* that length mismatches are handled explicitly rather than truncated.
|
|
1209
|
-
*
|
|
1210
|
-
* Unlike `Array.zipWith` (which stops at the shorter array), this walks to the
|
|
1211
|
-
* length of the *longer* array. The first array's element fills the `warnings`
|
|
1212
|
-
* side and the second array's element fills the `success` side, so at each index
|
|
1213
|
-
* `f` receives a `WarnResult.WarnResult<A, B>`: `SuccessWithWarnings` when both
|
|
1214
|
-
* arrays have an element, `WarningsOnly` when only the first does, and
|
|
1215
|
-
* `SuccessOnly` when only the second does. Use it when the "extra" tail of either
|
|
1216
|
-
* array still carries meaning.
|
|
1217
|
-
*
|
|
1218
|
-
* @example
|
|
1219
|
-
* ```ts
|
|
1220
|
-
* import { ArrayX, WarnResult } from "@nunofyobiz/effect-extras"
|
|
1221
|
-
*
|
|
1222
|
-
* const describe = WarnResult.match({
|
|
1223
|
-
* WarningsOnly: ({ warnings }) => `warnings ${warnings}`,
|
|
1224
|
-
* SuccessOnly: ({ success }) => `success ${success}`,
|
|
1225
|
-
* SuccessWithWarnings: ({ warnings, success }) => `both ${warnings}/${success}`,
|
|
1226
|
-
* })
|
|
1227
|
-
*
|
|
1228
|
-
* assert.deepStrictEqual(ArrayX.zipWithWarnings([1, 2, 3], [10, 20], describe), [
|
|
1229
|
-
* "both 1/10",
|
|
1230
|
-
* "both 2/20",
|
|
1231
|
-
* "warnings 3",
|
|
1232
|
-
* ])
|
|
1233
|
-
* ```
|
|
1234
|
-
*
|
|
1235
|
-
* @category combinators
|
|
1236
|
-
* @since 0.0.0
|
|
1237
|
-
*/
|
|
1238
|
-
declare const zipWithWarnings: (<A, B, C>(f: (ab: WarnResult<A, B>) => C) => (array1: readonly A[], array2: readonly B[]) => C[]) & (<A, B, C>(array1: readonly A[], array2: readonly B[], f: (ab: WarnResult<A, B>) => C) => C[]);
|
|
1239
|
-
/**
|
|
1240
|
-
* Inserts or moves a unique item in an array at a specified position.
|
|
1241
|
-
*
|
|
1242
|
-
* **Assumption**: Items should be unique in the array based on standard equality.
|
|
1243
|
-
*
|
|
1244
|
-
* **Happy case**: If the item doesn't exist in the array and the destination reference item is found:
|
|
1245
|
-
* The new item is inserted before the destination reference item
|
|
1246
|
-
*
|
|
1247
|
-
* **Item not found in array**:
|
|
1248
|
-
* - If destination reference item is found: The new item is inserted before the destination reference item
|
|
1249
|
-
* - If destination reference item is not found: The new item is inserted at the end of the array
|
|
1250
|
-
*
|
|
1251
|
-
* **Item found but duplicated**:
|
|
1252
|
-
* - If destination reference item is found: All existing copies are removed, then a single copy is inserted before the destination reference item
|
|
1253
|
-
* - If destination reference item is not found: All existing copies are removed, then a single copy is inserted at the end of the array
|
|
1254
|
-
*
|
|
1255
|
-
* @param array - The input array to modify
|
|
1256
|
-
* @param config - Configuration object containing:
|
|
1257
|
-
* - `item`: The item to insert or update (must be a string or number)
|
|
1258
|
-
* - `insertToBeLeftOf`: The item to position the new/updated item before,
|
|
1259
|
-
* or null to insert at the end
|
|
1260
|
-
*
|
|
1261
|
-
* @returns A new array with the item inserted or moved to the specified position
|
|
1262
|
-
*
|
|
1263
|
-
* @example
|
|
1264
|
-
* ```ts
|
|
1265
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1266
|
-
*
|
|
1267
|
-
* // Move an existing item to sit just before "c"
|
|
1268
|
-
* assert.deepStrictEqual(
|
|
1269
|
-
* ArrayX.insertUniq(["a", "b", "c", "d"], { item: "a", insertToBeLeftOf: "c" }),
|
|
1270
|
-
* ["b", "a", "c", "d"],
|
|
1271
|
-
* )
|
|
1272
|
-
*
|
|
1273
|
-
* // Insert a brand-new item; unknown destination falls through to the end
|
|
1274
|
-
* assert.deepStrictEqual(
|
|
1275
|
-
* ArrayX.insertUniq(["a", "b"], { item: "new", insertToBeLeftOf: null }),
|
|
1276
|
-
* ["a", "b", "new"],
|
|
1277
|
-
* )
|
|
1278
|
-
* ```
|
|
1279
|
-
*
|
|
1280
|
-
* @category combinators
|
|
1281
|
-
* @since 0.0.0
|
|
1282
|
-
*/
|
|
1283
|
-
declare const insertUniq: (<A extends string | number>(config: {
|
|
1284
|
-
item: A;
|
|
1285
|
-
insertToBeLeftOf: A | null;
|
|
1286
|
-
}) => (array: readonly A[] | A[]) => A[]) & (<A extends string | number>(array: readonly A[] | A[], config: {
|
|
1287
|
-
item: A;
|
|
1288
|
-
insertToBeLeftOf: A | null;
|
|
1289
|
-
}) => A[]);
|
|
1290
|
-
/**
|
|
1291
|
-
* Maps over `array` while threading an accumulator, iterating from right to
|
|
1292
|
-
* left instead of left to right.
|
|
1293
|
-
*
|
|
1294
|
-
* Identical to `Array.mapAccum`, except the traversal order is reversed: `f` is
|
|
1295
|
-
* called on the last element first, and the resulting array is returned in the
|
|
1296
|
-
* original (left-to-right) order. Use it when each element's mapped value
|
|
1297
|
-
* depends on state accumulated from the elements that follow it.
|
|
1298
|
-
*
|
|
1299
|
-
* @example
|
|
1300
|
-
* ```ts
|
|
1301
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1302
|
-
*
|
|
1303
|
-
* // Running suffix-sum: each slot holds the sum of itself and everything after it
|
|
1304
|
-
* assert.deepStrictEqual(
|
|
1305
|
-
* ArrayX.mapRightAccum([1, 2, 3], 0, (total, n) => [total + n, total + n]),
|
|
1306
|
-
* [6, [6, 5, 3]],
|
|
1307
|
-
* )
|
|
1308
|
-
* ```
|
|
1309
|
-
*
|
|
1310
|
-
* @category folding
|
|
1311
|
-
* @since 0.0.0
|
|
1312
|
-
*/
|
|
1313
|
-
declare const mapRightAccum: (<A, B, C>(initialAccumulator: C, f: (accumulator: C, a: A, index: number) => [C, B]) => (array: A[]) => [C, B[]]) & (<A, B, C>(array: A[], initialAccumulator: C, f: (accumulator: C, a: A, index: number) => [C, B]) => [C, B[]]);
|
|
1314
|
-
/**
|
|
1315
|
-
* Returns the maximum element of `array` according to `order`, wrapped in an
|
|
1316
|
-
* `Option` so that empty arrays are handled safely.
|
|
1317
|
-
*
|
|
1318
|
-
* Effect's `Array.max` throws on an empty array; this returns `Option.none()`
|
|
1319
|
-
* instead, and `Option.some(max)` otherwise. Reach for it whenever the input
|
|
1320
|
-
* array might be empty.
|
|
1321
|
-
*
|
|
1322
|
-
* @example
|
|
1323
|
-
* ```ts
|
|
1324
|
-
* import { Option, Order, pipe } from "effect"
|
|
1325
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1326
|
-
*
|
|
1327
|
-
* assert.deepStrictEqual(
|
|
1328
|
-
* pipe([3, 7, 2], ArrayX.maxOption(Order.Number)),
|
|
1329
|
-
* Option.some(7),
|
|
1330
|
-
* )
|
|
1331
|
-
* assert.deepStrictEqual(
|
|
1332
|
-
* pipe([], ArrayX.maxOption(Order.Number)),
|
|
1333
|
-
* Option.none(),
|
|
1334
|
-
* )
|
|
1335
|
-
* ```
|
|
1336
|
-
*
|
|
1337
|
-
* @category getters
|
|
1338
|
-
* @since 0.0.0
|
|
1339
|
-
*/
|
|
1340
|
-
declare const maxOption: (<A>(order: Order.Order<A>) => (array: A[]) => Option.Option<A>) & (<A>(array: A[], order: Order.Order<A>) => Option.Option<A>);
|
|
1341
|
-
/**
|
|
1342
|
-
* Returns the smallest element of `array` (per `order`) that matches
|
|
1343
|
-
* `predicate`, narrowed to the refined type `B`, or `Option.none()` if none
|
|
1344
|
-
* match.
|
|
1345
|
-
*
|
|
1346
|
-
* Combines a refinement filter with `Array.min`: only elements satisfying
|
|
1347
|
-
* `predicate` are considered, and the minimum of those (by `order`) is
|
|
1348
|
-
* returned. The refinement narrows the element type, so the resulting `Option`
|
|
1349
|
-
* carries the more specific `B`.
|
|
1350
|
-
*
|
|
1351
|
-
* @example
|
|
1352
|
-
* ```ts
|
|
1353
|
-
* import { Option, Order, pipe } from "effect"
|
|
1354
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1355
|
-
*
|
|
1356
|
-
* const isEven = (n: number): n is number => n % 2 === 0
|
|
1357
|
-
*
|
|
1358
|
-
* assert.deepStrictEqual(
|
|
1359
|
-
* pipe([3, 4, 1, 2, 5], ArrayX.takeFirstWhere(isEven, Order.Number)),
|
|
1360
|
-
* Option.some(2),
|
|
1361
|
-
* )
|
|
1362
|
-
* assert.deepStrictEqual(
|
|
1363
|
-
* pipe([1, 3, 5], ArrayX.takeFirstWhere(isEven, Order.Number)),
|
|
1364
|
-
* Option.none(),
|
|
1365
|
-
* )
|
|
1366
|
-
* ```
|
|
1367
|
-
*
|
|
1368
|
-
* @category getters
|
|
1369
|
-
* @since 0.0.0
|
|
1370
|
-
*/
|
|
1371
|
-
declare const takeFirstWhere$1: (<A, B extends A>(predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => (array: A[]) => Option.Option<B>) & (<A, B extends A>(array: A[], predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => Option.Option<B>);
|
|
1372
|
-
/**
|
|
1373
|
-
* Returns the largest element of `array` (per `order`) that matches
|
|
1374
|
-
* `predicate`, narrowed to the refined type `B`, or `Option.none()` if none
|
|
1375
|
-
* match.
|
|
1376
|
-
*
|
|
1377
|
-
* The mirror of {@link takeFirstWhere}: only elements satisfying `predicate`
|
|
1378
|
-
* are considered, and the maximum of those (by `order`) is returned. The
|
|
1379
|
-
* refinement narrows the element type, so the resulting `Option` carries the
|
|
1380
|
-
* more specific `B`.
|
|
1381
|
-
*
|
|
1382
|
-
* @example
|
|
1383
|
-
* ```ts
|
|
1384
|
-
* import { Option, Order, pipe } from "effect"
|
|
1385
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1386
|
-
*
|
|
1387
|
-
* const isEven = (n: number): n is number => n % 2 === 0
|
|
1388
|
-
*
|
|
1389
|
-
* assert.deepStrictEqual(
|
|
1390
|
-
* pipe([3, 4, 1, 2, 5], ArrayX.takeLastWhere(isEven, Order.Number)),
|
|
1391
|
-
* Option.some(4),
|
|
1392
|
-
* )
|
|
1393
|
-
* assert.deepStrictEqual(
|
|
1394
|
-
* pipe([1, 3, 5], ArrayX.takeLastWhere(isEven, Order.Number)),
|
|
1395
|
-
* Option.none(),
|
|
1396
|
-
* )
|
|
1397
|
-
* ```
|
|
1398
|
-
*
|
|
1399
|
-
* @category getters
|
|
1400
|
-
* @since 0.0.0
|
|
1401
|
-
*/
|
|
1402
|
-
declare const takeLastWhere$1: (<A, B extends A>(predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => (array: A[]) => Option.Option<B>) & (<A, B extends A>(array: A[], predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => Option.Option<B>);
|
|
1403
|
-
/**
|
|
1404
|
-
* Groups `items` into a partial record keyed by the category each item maps to
|
|
1405
|
-
* via `categorize`.
|
|
1406
|
-
*
|
|
1407
|
-
* Each item is appended to the array under its category, preserving input
|
|
1408
|
-
* order. The result is `Partial<Record<C, A[]>>` because not every possible
|
|
1409
|
-
* category `C` is guaranteed to appear — only categories that received at least
|
|
1410
|
-
* one item are present.
|
|
1411
|
-
*
|
|
1412
|
-
* @example
|
|
1413
|
-
* ```ts
|
|
1414
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1415
|
-
*
|
|
1416
|
-
* const parity = (n: number) => (n % 2 === 0 ? "even" : "odd")
|
|
1417
|
-
*
|
|
1418
|
-
* assert.deepStrictEqual(ArrayX.categorize([1, 2, 3, 4], parity), {
|
|
1419
|
-
* odd: [1, 3],
|
|
1420
|
-
* even: [2, 4],
|
|
1421
|
-
* })
|
|
1422
|
-
* ```
|
|
1423
|
-
*
|
|
1424
|
-
* @category folding
|
|
1425
|
-
* @since 0.0.0
|
|
1426
|
-
*/
|
|
1427
|
-
declare const categorize: <A, C extends string>(items: Iterable<A>, categorize: (a: A) => C) => Partial<Record<C, A[]>>;
|
|
1428
|
-
/**
|
|
1429
|
-
* Removes all `null` and `undefined` elements from `array`, narrowing the
|
|
1430
|
-
* element type to `NonNullable<A>`.
|
|
1431
|
-
*
|
|
1432
|
-
* Falsy-but-present values such as `0` and `""` are kept — only nullish values
|
|
1433
|
-
* are dropped. Use it to clean up an array of optionals into a dense array of
|
|
1434
|
-
* known-present values.
|
|
1435
|
-
*
|
|
1436
|
-
* @example
|
|
1437
|
-
* ```ts
|
|
1438
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1439
|
-
*
|
|
1440
|
-
* assert.deepStrictEqual(
|
|
1441
|
-
* ArrayX.compactNullable([1, null, 2, undefined, 0, ""]),
|
|
1442
|
-
* [1, 2, 0, ""],
|
|
1443
|
-
* )
|
|
1444
|
-
* ```
|
|
1445
|
-
*
|
|
1446
|
-
* @category filtering
|
|
1447
|
-
* @since 0.0.0
|
|
1448
|
-
*/
|
|
1449
|
-
declare const compactNullable: <A>(array: A[]) => NonNullable<A>[];
|
|
1450
|
-
/**
|
|
1451
|
-
* Drops the leading elements of `array` until `predicate` first holds, keeping
|
|
1452
|
-
* everything from the first match onward.
|
|
1453
|
-
*
|
|
1454
|
-
* The first matching element and all subsequent elements are retained
|
|
1455
|
-
* regardless of whether they match — only the prefix *before* the first match
|
|
1456
|
-
* is trimmed. If nothing matches, returns an empty array.
|
|
1457
|
-
*
|
|
1458
|
-
* @example
|
|
1459
|
-
* ```ts
|
|
1460
|
-
* import { Predicate } from "effect"
|
|
1461
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1462
|
-
*
|
|
1463
|
-
* // Trims the leading strings, then keeps everything (including the trailing "b")
|
|
1464
|
-
* assert.deepStrictEqual(
|
|
1465
|
-
* ArrayX.filterHead(["a", 1, 2, "b"], Predicate.isNumber),
|
|
1466
|
-
* [1, 2, "b"],
|
|
1467
|
-
* )
|
|
1468
|
-
* ```
|
|
1469
|
-
*
|
|
1470
|
-
* @category filtering
|
|
1471
|
-
* @since 0.0.0
|
|
1472
|
-
*/
|
|
1473
|
-
declare const filterHead: (<A>(predicate: Predicate.Predicate<A>) => (array: A[]) => A[]) & (<A>(array: A[], predicate: Predicate.Predicate<A>) => A[]);
|
|
1474
|
-
/**
|
|
1475
|
-
* Drops the trailing elements of `array` after `predicate` last holds, keeping
|
|
1476
|
-
* everything up to and including the last match.
|
|
1477
|
-
*
|
|
1478
|
-
* The mirror of {@link filterHead}: the last matching element and all preceding
|
|
1479
|
-
* elements are retained regardless of whether they match — only the suffix
|
|
1480
|
-
* *after* the last match is trimmed. If nothing matches, returns an empty
|
|
1481
|
-
* array.
|
|
1482
|
-
*
|
|
1483
|
-
* @example
|
|
1484
|
-
* ```ts
|
|
1485
|
-
* import { Predicate } from "effect"
|
|
1486
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1487
|
-
*
|
|
1488
|
-
* // Keeps the leading "a" and trims the trailing strings after the last number
|
|
1489
|
-
* assert.deepStrictEqual(
|
|
1490
|
-
* ArrayX.filterTail(["a", 1, 2, "b"], Predicate.isNumber),
|
|
1491
|
-
* ["a", 1, 2],
|
|
1492
|
-
* )
|
|
1493
|
-
* ```
|
|
1494
|
-
*
|
|
1495
|
-
* @category filtering
|
|
1496
|
-
* @since 0.0.0
|
|
1497
|
-
*/
|
|
1498
|
-
declare const filterTail: (<A>(predicate: Predicate.Predicate<A>) => (array: A[]) => A[]) & (<A>(array: A[], predicate: Predicate.Predicate<A>) => A[]);
|
|
1499
|
-
/**
|
|
1500
|
-
* Maps `f` over `array` and drops every result that is `null` or `undefined`,
|
|
1501
|
-
* narrowing the element type to `NonNullable<B>`.
|
|
1502
|
-
*
|
|
1503
|
-
* A nullable-friendly `Array.filterMap`: where `filterMap` expects `f` to
|
|
1504
|
-
* return an `Option`, this accepts a function returning `B | null` (or
|
|
1505
|
-
* `undefined`) and treats nullish results as "skip this element". Falsy-but-
|
|
1506
|
-
* present values such as `0` and `""` are kept.
|
|
1507
|
-
*
|
|
1508
|
-
* @example
|
|
1509
|
-
* ```ts
|
|
1510
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1511
|
-
*
|
|
1512
|
-
* // Keep only the even numbers, mapped to their halves
|
|
1513
|
-
* assert.deepStrictEqual(
|
|
1514
|
-
* ArrayX.filterMapNullable([1, 2, 3, 4], (n) => (n % 2 === 0 ? n / 2 : null)),
|
|
1515
|
-
* [1, 2],
|
|
1516
|
-
* )
|
|
1517
|
-
* ```
|
|
1518
|
-
*
|
|
1519
|
-
* @category filtering
|
|
1520
|
-
* @since 0.0.0
|
|
1521
|
-
*/
|
|
1522
|
-
declare const filterMapNullable: (<A, B>(f: (a: A) => B | null) => (array: A[]) => NonNullable<B>[]) & (<A, B>(array: A[], f: (a: A) => B | null) => NonNullable<B>[]);
|
|
1523
|
-
/**
|
|
1524
|
-
* Finds the first element of a 2-dimensional array (row-major order) matching
|
|
1525
|
-
* `predicate`, returning it alongside its row and column indices.
|
|
1526
|
-
*
|
|
1527
|
-
* Scans rows top-to-bottom and, within each row, left-to-right. On a match
|
|
1528
|
-
* returns `Option.some([value, rowIndex, columnIndex])`; if no element matches
|
|
1529
|
-
* (or the grid is empty), returns `Option.none()`.
|
|
1530
|
-
*
|
|
1531
|
-
* @example
|
|
1532
|
-
* ```ts
|
|
1533
|
-
* import { Option } from "effect"
|
|
1534
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1535
|
-
*
|
|
1536
|
-
* const grid = [
|
|
1537
|
-
* ["A", "B", "C"],
|
|
1538
|
-
* ["D", "E", "F"],
|
|
1539
|
-
* ]
|
|
1540
|
-
*
|
|
1541
|
-
* assert.deepStrictEqual(
|
|
1542
|
-
* ArrayX.findFirstWithIndex2d(grid, (cell) => cell === "E"),
|
|
1543
|
-
* Option.some(["E", 1, 1]),
|
|
1544
|
-
* )
|
|
1545
|
-
* ```
|
|
1546
|
-
*
|
|
1547
|
-
* @category getters
|
|
1548
|
-
* @since 0.0.0
|
|
1549
|
-
*/
|
|
1550
|
-
declare const findFirstWithIndex2d: (<A>(predicate: Predicate.Predicate<A>) => (array: A[][]) => Option.Option<[A, number, number]>) & (<A>(array: A[][], predicate: Predicate.Predicate<A>) => Option.Option<[A, number, number]>);
|
|
1551
|
-
/**
|
|
1552
|
-
* Splits `array` into runs of consecutive elements that share the same group
|
|
1553
|
-
* value, where the group is derived by `chunk` and compared with the provided
|
|
1554
|
-
* `Equivalence`.
|
|
1555
|
-
*
|
|
1556
|
-
* Only *adjacent* elements are grouped: a new run starts every time the group
|
|
1557
|
-
* value changes from the previous element. Each entry in the result carries the
|
|
1558
|
-
* `group` value and the non-empty array of `values` that produced it, preserving
|
|
1559
|
-
* input order. An empty input yields an empty array. Use it for run-length-style
|
|
1560
|
-
* segmentation; reach for `Array.groupBy` instead when you want all elements
|
|
1561
|
-
* with the same key collapsed regardless of position.
|
|
1562
|
-
*
|
|
1563
|
-
* @example
|
|
1564
|
-
* ```ts
|
|
1565
|
-
* import { Equivalence } from "effect"
|
|
1566
|
-
* import { ArrayX } from "@nunofyobiz/effect-extras"
|
|
1567
|
-
*
|
|
1568
|
-
* // Group adjacent numbers by parity
|
|
1569
|
-
* assert.deepStrictEqual(
|
|
1570
|
-
* ArrayX.chunkBy([2, 4, 1, 3, 6], (n) => n % 2 === 0, Equivalence.Boolean),
|
|
1571
|
-
* [
|
|
1572
|
-
* { group: true, values: [2, 4] },
|
|
1573
|
-
* { group: false, values: [1, 3] },
|
|
1574
|
-
* { group: true, values: [6] },
|
|
1575
|
-
* ],
|
|
1576
|
-
* )
|
|
1577
|
-
* ```
|
|
1578
|
-
*
|
|
1579
|
-
* @category folding
|
|
1580
|
-
* @since 0.0.0
|
|
1581
|
-
*/
|
|
1582
|
-
declare const chunkBy: (<A, B>(chunk: (a: A) => B, GroupEquivalence: Equivalence.Equivalence<B>) => (array: A[]) => {
|
|
1583
|
-
group: B;
|
|
1584
|
-
values: Array.NonEmptyArray<A>;
|
|
1585
|
-
}[]) & (<A, B>(array: A[], chunk: (a: A) => B, GroupEquivalence: Equivalence.Equivalence<B>) => {
|
|
1586
|
-
group: B;
|
|
1587
|
-
values: Array.NonEmptyArray<A>;
|
|
1588
|
-
}[]);
|
|
1589
|
-
|
|
1590
|
-
declare const ArrayX_categorize: typeof categorize;
|
|
1591
|
-
declare const ArrayX_chunkBy: typeof chunkBy;
|
|
1592
|
-
declare const ArrayX_compactNullable: typeof compactNullable;
|
|
1593
|
-
declare const ArrayX_filterHead: typeof filterHead;
|
|
1594
|
-
declare const ArrayX_filterMapNullable: typeof filterMapNullable;
|
|
1595
|
-
declare const ArrayX_filterTail: typeof filterTail;
|
|
1596
|
-
declare const ArrayX_findFirstWithIndex2d: typeof findFirstWithIndex2d;
|
|
1597
|
-
declare const ArrayX_insertUniq: typeof insertUniq;
|
|
1598
|
-
declare const ArrayX_mapRightAccum: typeof mapRightAccum;
|
|
1599
|
-
declare const ArrayX_maxOption: typeof maxOption;
|
|
1600
|
-
declare const ArrayX_slice: typeof slice;
|
|
1601
|
-
declare const ArrayX_zipWithWarnings: typeof zipWithWarnings;
|
|
1602
|
-
declare namespace ArrayX {
|
|
1603
|
-
export { ArrayX_categorize as categorize, ArrayX_chunkBy as chunkBy, ArrayX_compactNullable as compactNullable, ArrayX_filterHead as filterHead, ArrayX_filterMapNullable as filterMapNullable, ArrayX_filterTail as filterTail, ArrayX_findFirstWithIndex2d as findFirstWithIndex2d, ArrayX_insertUniq as insertUniq, ArrayX_mapRightAccum as mapRightAccum, ArrayX_maxOption as maxOption, ArrayX_slice as slice, takeFirstWhere$1 as takeFirstWhere, takeLastWhere$1 as takeLastWhere, ArrayX_zipWithWarnings as zipWithWarnings };
|
|
1604
|
-
}
|
|
1605
|
-
|
|
1606
|
-
/**
|
|
1607
|
-
* Converts a `bigint` to a `number`, throwing when the value cannot be
|
|
1608
|
-
* represented exactly.
|
|
1609
|
-
*
|
|
1610
|
-
* Delegates to Effect's `BigInt.toNumber`, which returns `None` once the
|
|
1611
|
-
* `bigint` falls outside the safe integer range (`Number.MAX_SAFE_INTEGER`).
|
|
1612
|
-
* This unwraps that `Option`, throwing instead of silently losing precision —
|
|
1613
|
-
* use it only when the value is known to fit.
|
|
1614
|
-
*
|
|
1615
|
-
* @example
|
|
1616
|
-
* ```ts
|
|
1617
|
-
* import { BigIntX } from "@nunofyobiz/effect-extras"
|
|
1618
|
-
*
|
|
1619
|
-
* assert.deepStrictEqual(BigIntX.toNumberOrThrow(42n), 42)
|
|
1620
|
-
*
|
|
1621
|
-
* // throws when outside the safe integer range
|
|
1622
|
-
* assert.throws(() => BigIntX.toNumberOrThrow(9007199254740993n))
|
|
1623
|
-
* ```
|
|
1624
|
-
*
|
|
1625
|
-
* @category unsafe
|
|
1626
|
-
* @since 0.0.0
|
|
1627
|
-
*/
|
|
1628
|
-
declare const toNumberOrThrow: (value: bigint) => number;
|
|
1629
|
-
|
|
1630
|
-
declare const BigIntX_toNumberOrThrow: typeof toNumberOrThrow;
|
|
1631
|
-
declare namespace BigIntX {
|
|
1632
|
-
export { BigIntX_toNumberOrThrow as toNumberOrThrow };
|
|
1633
|
-
}
|
|
1634
|
-
|
|
1635
|
-
/**
|
|
1636
|
-
* Generic, framework-agnostic extensions to Effect's `Boolean` module.
|
|
1637
|
-
*
|
|
1638
|
-
* @since 0.0.0
|
|
1639
|
-
*/
|
|
1640
|
-
/**
|
|
1641
|
-
* Converts a `boolean` to its binary digit: `1` for `true`, `0` for `false`.
|
|
1642
|
-
*
|
|
1643
|
-
* Useful when a numeric flag is required — summing booleans to count how many
|
|
1644
|
-
* predicates hold, or feeding a bit into bitwise math or an external API that
|
|
1645
|
-
* expects `0`/`1` rather than `false`/`true`.
|
|
1646
|
-
*
|
|
1647
|
-
* @example
|
|
1648
|
-
* ```ts
|
|
1649
|
-
* import { BooleanX } from "@nunofyobiz/effect-extras"
|
|
1650
|
-
*
|
|
1651
|
-
* assert.deepStrictEqual(BooleanX.toBinary(true), 1)
|
|
1652
|
-
* assert.deepStrictEqual(BooleanX.toBinary(false), 0)
|
|
1653
|
-
* ```
|
|
1654
|
-
*
|
|
1655
|
-
* @category conversions
|
|
1656
|
-
* @since 0.0.0
|
|
1657
|
-
*/
|
|
1658
|
-
declare const toBinary: (value: boolean) => 0 | 1;
|
|
1659
|
-
|
|
1660
|
-
declare const BooleanX_toBinary: typeof toBinary;
|
|
1661
|
-
declare namespace BooleanX {
|
|
1662
|
-
export { BooleanX_toBinary as toBinary };
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
/**
|
|
1666
|
-
* Generic, framework-agnostic extensions to Effect's `Duration` module.
|
|
1667
|
-
*
|
|
1668
|
-
* @since 0.0.0
|
|
1669
|
-
*/
|
|
1670
|
-
|
|
1671
|
-
/**
|
|
1672
|
-
* Computes the elapsed `Duration` from `that` to `self`, clamped at zero.
|
|
1673
|
-
*
|
|
1674
|
-
* Represents the time that has passed since the reference instant `that`. When
|
|
1675
|
-
* `that` lies in the future relative to `self`, the elapsed time is `zero`
|
|
1676
|
-
* rather than a negative duration.
|
|
1677
|
-
*
|
|
1678
|
-
* @example
|
|
1679
|
-
* ```ts
|
|
1680
|
-
* import { DateTime, Duration, pipe } from "effect"
|
|
1681
|
-
* import { DurationX } from "@nunofyobiz/effect-extras"
|
|
1682
|
-
*
|
|
1683
|
-
* const earlier = DateTime.makeUnsafe(1000)
|
|
1684
|
-
* const later = DateTime.makeUnsafe(4000)
|
|
1685
|
-
*
|
|
1686
|
-
* // data-first
|
|
1687
|
-
* assert.deepStrictEqual(DurationX.diff(later, earlier), Duration.seconds(3))
|
|
1688
|
-
*
|
|
1689
|
-
* // future reference clamps to zero
|
|
1690
|
-
* assert.deepStrictEqual(DurationX.diff(earlier, later), Duration.zero)
|
|
1691
|
-
*
|
|
1692
|
-
* // data-last (piped)
|
|
1693
|
-
* assert.deepStrictEqual(
|
|
1694
|
-
* pipe(later, DurationX.diff(earlier)),
|
|
1695
|
-
* Duration.seconds(3),
|
|
1696
|
-
* )
|
|
1697
|
-
* ```
|
|
1698
|
-
*
|
|
1699
|
-
* @category combinators
|
|
1700
|
-
* @since 0.0.0
|
|
1701
|
-
*/
|
|
1702
|
-
declare const diff: ((that: DateTime.DateTime) => (self: DateTime.DateTime) => Duration.Duration) & ((self: DateTime.DateTime, that: DateTime.DateTime) => Duration.Duration);
|
|
1703
|
-
/**
|
|
1704
|
-
* Transforms a `Duration` by converting it to a numeric `unit`, applying `map`,
|
|
1705
|
-
* then converting back.
|
|
1706
|
-
*
|
|
1707
|
-
* Lets you operate on a duration in whatever unit is convenient — round it to
|
|
1708
|
-
* whole minutes, halve its seconds, floor its days — without juggling
|
|
1709
|
-
* conversions by hand. The `map` callback receives the duration expressed as a
|
|
1710
|
-
* `number` of `unit`s and returns the new count.
|
|
1711
|
-
*
|
|
1712
|
-
* @example
|
|
1713
|
-
* ```ts
|
|
1714
|
-
* import { Duration, Number, pipe } from "effect"
|
|
1715
|
-
* import { DurationX } from "@nunofyobiz/effect-extras"
|
|
1716
|
-
*
|
|
1717
|
-
* // data-first: halve a 4-second duration
|
|
1718
|
-
* assert.deepStrictEqual(
|
|
1719
|
-
* DurationX.mapAsUnit(Duration.seconds(4), "second", Number.divideUnsafe(2)),
|
|
1720
|
-
* Duration.seconds(2),
|
|
1721
|
-
* )
|
|
1722
|
-
*
|
|
1723
|
-
* // data-last (piped)
|
|
1724
|
-
* assert.deepStrictEqual(
|
|
1725
|
-
* pipe(
|
|
1726
|
-
* Duration.minutes(10),
|
|
1727
|
-
* DurationX.mapAsUnit("minute", (minutes) => minutes + 5),
|
|
1728
|
-
* ),
|
|
1729
|
-
* Duration.minutes(15),
|
|
1730
|
-
* )
|
|
1731
|
-
* ```
|
|
1732
|
-
*
|
|
1733
|
-
* @category combinators
|
|
1734
|
-
* @since 0.0.0
|
|
1735
|
-
*/
|
|
1736
|
-
declare const mapAsUnit: ((unit: Duration.Unit, map: (numberOfUnits: number) => number) => (duration: Duration.Duration) => Duration.Duration) & ((duration: Duration.Duration, unit: Duration.Unit, map: (numberOfUnits: number) => number) => Duration.Duration);
|
|
1737
|
-
|
|
1738
|
-
declare const DurationX_diff: typeof diff;
|
|
1739
|
-
declare const DurationX_mapAsUnit: typeof mapAsUnit;
|
|
1740
|
-
declare namespace DurationX {
|
|
1741
|
-
export { DurationX_diff as diff, DurationX_mapAsUnit as mapAsUnit };
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
/**
|
|
1745
|
-
* Generic, framework-agnostic extensions to Effect's `Effect` module.
|
|
1746
|
-
*
|
|
1747
|
-
* @since 0.0.0
|
|
1748
|
-
*/
|
|
1749
|
-
|
|
1750
|
-
/**
|
|
1751
|
-
* Flattens an `Effect` that succeeds with an `Option` into an `Effect` that
|
|
1752
|
-
* fails with `onNone()` when the `Option` is `None`.
|
|
1753
|
-
*
|
|
1754
|
-
* When the wrapped `Option` is `Some(value)` the effect succeeds with `value`;
|
|
1755
|
-
* when it is `None` the effect fails with the error produced by the `onNone`
|
|
1756
|
-
* thunk. An existing failure of the source effect is preserved untouched, so the
|
|
1757
|
-
* result's error channel is the union of the original error and the `None`
|
|
1758
|
-
* error.
|
|
1759
|
-
*
|
|
1760
|
-
* @example
|
|
1761
|
-
* ```ts
|
|
1762
|
-
* import { Effect, Option, Result } from "effect"
|
|
1763
|
-
* import { EffectX } from "@nunofyobiz/effect-extras"
|
|
1764
|
-
*
|
|
1765
|
-
* const some = EffectX.flattenOption(
|
|
1766
|
-
* Effect.succeed(Option.some(1)),
|
|
1767
|
-
* () => "missing",
|
|
1768
|
-
* )
|
|
1769
|
-
* assert.deepStrictEqual(Effect.runSync(Effect.result(some)), Result.succeed(1))
|
|
1770
|
-
*
|
|
1771
|
-
* const none = EffectX.flattenOption(
|
|
1772
|
-
* Effect.succeed(Option.none<number>()),
|
|
1773
|
-
* () => "missing",
|
|
1774
|
-
* )
|
|
1775
|
-
* assert.deepStrictEqual(
|
|
1776
|
-
* Effect.runSync(Effect.result(none)),
|
|
1777
|
-
* Result.fail("missing"),
|
|
1778
|
-
* )
|
|
1779
|
-
* ```
|
|
1780
|
-
*
|
|
1781
|
-
* @category sequencing
|
|
1782
|
-
* @since 0.0.0
|
|
1783
|
-
*/
|
|
1784
|
-
declare const flattenOption: (<A, E1, E2, R>(onNone: () => E2) => (effect: Effect.Effect<Option.Option<A>, E1, R>) => Effect.Effect<A, E1 | E2, R>) & (<A, E1, E2, R>(effect: Effect.Effect<Option.Option<A>, E1, R>, onNone: () => E2) => Effect.Effect<A, E1 | E2, R>);
|
|
1785
|
-
/**
|
|
1786
|
-
* Converts an `Option` to an `Effect`, mapping the `None` case to a caller-chosen
|
|
1787
|
-
* error via the `onNone` thunk.
|
|
1788
|
-
*
|
|
1789
|
-
* Equivalent to `Effect.mapError(Effect.fromOption(option), onNone)`: it bridges
|
|
1790
|
-
* the `NoSuchElementError` that `Effect.fromOption` produces to the caller's own
|
|
1791
|
-
* error type, so callers never have to handle `NoSuchElementError`. This fills
|
|
1792
|
-
* the v4 gap where `Effect.mapError` no longer accepts an `Option` directly —
|
|
1793
|
-
* instead of
|
|
1794
|
-
* `pipe(option, Effect.fromOption, Effect.mapError(() => new MyError()))`, write
|
|
1795
|
-
* `pipe(option, EffectX.fromOptionOrElse(() => new MyError()))`. The `onNone`
|
|
1796
|
-
* thunk runs only when the `Option` is `None`.
|
|
1797
|
-
*
|
|
1798
|
-
* @example
|
|
1799
|
-
* ```ts
|
|
1800
|
-
* import { Effect, Option, Result, pipe } from "effect"
|
|
1801
|
-
* import { EffectX } from "@nunofyobiz/effect-extras"
|
|
1802
|
-
*
|
|
1803
|
-
* // data-first
|
|
1804
|
-
* const some = EffectX.fromOptionOrElse(Option.some(42), () => "missing")
|
|
1805
|
-
* assert.deepStrictEqual(Effect.runSync(Effect.result(some)), Result.succeed(42))
|
|
1806
|
-
*
|
|
1807
|
-
* // data-last (piped) — None maps to the chosen error
|
|
1808
|
-
* const none = pipe(
|
|
1809
|
-
* Option.none<number>(),
|
|
1810
|
-
* EffectX.fromOptionOrElse(() => "missing"),
|
|
1811
|
-
* )
|
|
1812
|
-
* assert.deepStrictEqual(
|
|
1813
|
-
* Effect.runSync(Effect.result(none)),
|
|
1814
|
-
* Result.fail("missing"),
|
|
1815
|
-
* )
|
|
1816
|
-
* ```
|
|
1817
|
-
*
|
|
1818
|
-
* @category conversions
|
|
1819
|
-
* @since 0.0.0
|
|
1820
|
-
*/
|
|
1821
|
-
declare const fromOptionOrElse: {
|
|
1822
|
-
<E>(onNone: () => E): <A>(option: Option.Option<A>) => Effect.Effect<A, E>;
|
|
1823
|
-
<A, E>(option: Option.Option<A>, onNone: () => E): Effect.Effect<A, E>;
|
|
1824
|
-
};
|
|
1825
|
-
/**
|
|
1826
|
-
* Repeatedly calls a synchronous `try` thunk until its result satisfies the
|
|
1827
|
-
* `until` refinement, sleeping `sleepDuration` between attempts and failing with
|
|
1828
|
-
* a `TimeoutError` once `maxDuration` elapses.
|
|
1829
|
-
*
|
|
1830
|
-
* The thunk is evaluated immediately; if its first result already passes the
|
|
1831
|
-
* refinement the effect succeeds without any delay. Otherwise it polls on the
|
|
1832
|
-
* `sleepDuration` interval (defaulting to 200ms — the threshold below which a
|
|
1833
|
-
* delay reads as "instant" to a user) until either the predicate holds (the
|
|
1834
|
-
* effect succeeds with the narrowed `B` value) or `maxDuration` is exceeded (the
|
|
1835
|
-
* effect fails with a `Cause.TimeoutError`). Use it to await an external,
|
|
1836
|
-
* non-effectful condition such as a flag flipped by a callback.
|
|
1837
|
-
*
|
|
1838
|
-
* @example
|
|
1839
|
-
* ```ts
|
|
1840
|
-
* import { Duration, Effect } from "effect"
|
|
1841
|
-
* import { EffectX } from "@nunofyobiz/effect-extras"
|
|
1842
|
-
*
|
|
1843
|
-
* // First attempt already matches, so it resolves immediately.
|
|
1844
|
-
* const effect = EffectX.tryUntil({
|
|
1845
|
-
* try: () => 1,
|
|
1846
|
-
* until: (value: number): value is number => value === 1,
|
|
1847
|
-
* sleepDuration: Duration.millis(100),
|
|
1848
|
-
* maxDuration: Duration.seconds(1),
|
|
1849
|
-
* })
|
|
1850
|
-
*
|
|
1851
|
-
* assert.deepStrictEqual(Effect.runSync(effect), 1)
|
|
1852
|
-
* ```
|
|
1853
|
-
*
|
|
1854
|
-
* @category sequencing
|
|
1855
|
-
* @since 0.0.0
|
|
1856
|
-
*/
|
|
1857
|
-
declare const tryUntil: <A, B extends A>({ try: doTry, until: isDone, sleepDuration, maxDuration, }: {
|
|
1858
|
-
try: () => A;
|
|
1859
|
-
until: Predicate.Refinement<A, B>;
|
|
1860
|
-
sleepDuration?: Duration.Duration;
|
|
1861
|
-
maxDuration: Duration.Duration;
|
|
1862
|
-
}) => Effect.Effect<B, Cause.TimeoutError, never>;
|
|
1863
|
-
|
|
1864
|
-
declare const EffectX_flattenOption: typeof flattenOption;
|
|
1865
|
-
declare const EffectX_fromOptionOrElse: typeof fromOptionOrElse;
|
|
1866
|
-
declare const EffectX_tryUntil: typeof tryUntil;
|
|
1867
|
-
declare namespace EffectX {
|
|
1868
|
-
export { EffectX_flattenOption as flattenOption, EffectX_fromOptionOrElse as fromOptionOrElse, EffectX_tryUntil as tryUntil };
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
|
-
/**
|
|
1872
|
-
* Helpers for decoding `FormData` with Effect `Schema`.
|
|
1873
|
-
*
|
|
1874
|
-
* @since 0.0.0
|
|
1875
|
-
*/
|
|
1876
|
-
|
|
1877
|
-
/**
|
|
1878
|
-
* Decodes a `FormData` into a typed value using a `Schema`, throwing on
|
|
1879
|
-
* validation failure.
|
|
1880
|
-
*
|
|
1881
|
-
* Built on v4's native `Schema.fromFormData`, which first parses the `FormData`
|
|
1882
|
-
* entries into a nested tree record (bracket-path notation is supported) and then
|
|
1883
|
-
* decodes that tree with the provided inner schema. For schemas with non-string
|
|
1884
|
-
* fields (for example `Schema.Int`), wrap the inner schema in
|
|
1885
|
-
* `Schema.toCodecStringTree(schema, { keepDeclarations: true })` so the
|
|
1886
|
-
* string → number/boolean coercion happens. Usable only with schemas that have
|
|
1887
|
-
* no decoding services — this is enforced at the type level via
|
|
1888
|
-
* `S["DecodingServices"] = never` — and it throws synchronously when the input
|
|
1889
|
-
* fails validation.
|
|
1890
|
-
*
|
|
1891
|
-
* @example
|
|
1892
|
-
* ```ts
|
|
1893
|
-
* import { Schema } from "effect"
|
|
1894
|
-
* import { FormDataX } from "@nunofyobiz/effect-extras"
|
|
1895
|
-
*
|
|
1896
|
-
* const formData = new FormData()
|
|
1897
|
-
* formData.append("name", "John")
|
|
1898
|
-
* formData.append("age", "30")
|
|
1899
|
-
*
|
|
1900
|
-
* const result = FormDataX.decodeSync(
|
|
1901
|
-
* formData,
|
|
1902
|
-
* Schema.Struct({ name: Schema.String, age: Schema.NumberFromString }),
|
|
1903
|
-
* )
|
|
1904
|
-
*
|
|
1905
|
-
* assert.deepStrictEqual(result, { name: "John", age: 30 })
|
|
1906
|
-
* ```
|
|
1907
|
-
*
|
|
1908
|
-
* @category conversions
|
|
1909
|
-
* @since 0.0.0
|
|
1910
|
-
*/
|
|
1911
|
-
declare const decodeSync: {
|
|
1912
|
-
<S extends Schema.Top & {
|
|
1913
|
-
readonly DecodingServices: never;
|
|
1914
|
-
}>(formData: FormData, schema: S): S["Type"];
|
|
1915
|
-
<S extends Schema.Top & {
|
|
1916
|
-
readonly DecodingServices: never;
|
|
1917
|
-
}>(schema: S): (formData: FormData) => S["Type"];
|
|
1918
|
-
};
|
|
1919
|
-
|
|
1920
|
-
declare const FormDataX_decodeSync: typeof decodeSync;
|
|
1921
|
-
declare namespace FormDataX {
|
|
1922
|
-
export { FormDataX_decodeSync as decodeSync };
|
|
1923
|
-
}
|
|
1924
|
-
|
|
1925
|
-
/**
|
|
1926
|
-
* Like `Map.prototype.get`, but when the key is absent it stores the computed
|
|
1927
|
-
* fallback at that key and returns it. Mutates the input map in place.
|
|
1928
|
-
*
|
|
1929
|
-
* Use it for memoization-style caches where a miss should both populate the map
|
|
1930
|
-
* and yield the value in one step. Throws if the resolved value is nullish (only
|
|
1931
|
-
* possible when `fallbackIfNotFound` returns `null`/`undefined` for a value type
|
|
1932
|
-
* that admits them — treated as a programmer error). Supports both data-first and
|
|
1933
|
-
* data-last (pipeable) call styles.
|
|
1934
|
-
*
|
|
1935
|
-
* @example
|
|
1936
|
-
* ```ts
|
|
1937
|
-
* import { MapX } from "@nunofyobiz/effect-extras"
|
|
1938
|
-
* import { pipe } from "effect"
|
|
1939
|
-
*
|
|
1940
|
-
* // Miss: stores the fallback and returns it (data-first)
|
|
1941
|
-
* const map = new Map<string, number>()
|
|
1942
|
-
* assert.deepStrictEqual(MapX.getOrElseSetGet(map, "a", () => 1), 1)
|
|
1943
|
-
* assert.deepStrictEqual(map.get("a"), 1)
|
|
1944
|
-
*
|
|
1945
|
-
* // Hit: returns the existing value, fallback is ignored (data-last)
|
|
1946
|
-
* assert.deepStrictEqual(
|
|
1947
|
-
* pipe(map, MapX.getOrElseSetGet("a", () => 99)),
|
|
1948
|
-
* 1
|
|
1949
|
-
* )
|
|
1950
|
-
* ```
|
|
1951
|
-
*
|
|
1952
|
-
* @category combinators
|
|
1953
|
-
* @since 0.0.0
|
|
1954
|
-
*/
|
|
1955
|
-
declare const getOrElseSetGet: (<K, V>(key: K, fallbackIfNotFound: () => V) => (map: Map<K, V>) => V) & (<K, V>(map: Map<K, V>, key: K, fallbackIfNotFound: () => V) => V);
|
|
1956
|
-
|
|
1957
|
-
declare const MapX_getOrElseSetGet: typeof getOrElseSetGet;
|
|
1958
|
-
declare namespace MapX {
|
|
1959
|
-
export { MapX_getOrElseSetGet as getOrElseSetGet };
|
|
1960
|
-
}
|
|
1961
|
-
|
|
1962
|
-
/**
|
|
1963
|
-
* Helpers for working with non-nullable values.
|
|
1964
|
-
*
|
|
1965
|
-
* @since 0.0.0
|
|
1966
|
-
*/
|
|
1967
|
-
|
|
1968
|
-
/**
|
|
1969
|
-
* Returns `value` narrowed to `NonNullable<A>`, throwing an `Error` if it is
|
|
1970
|
-
* `null` or `undefined`.
|
|
1971
|
-
*
|
|
1972
|
-
* Use it at trusted boundaries where a value is known to be present but typed as
|
|
1973
|
-
* nullable, turning a silent `undefined` into a loud failure. An optional
|
|
1974
|
-
* `variableName` is woven into the thrown message to aid debugging. This is the
|
|
1975
|
-
* function re-exported as `nn` from the module barrel, a terse shorthand handy
|
|
1976
|
-
* inside string interpolations.
|
|
1977
|
-
*
|
|
1978
|
-
* @example
|
|
1979
|
-
* ```ts
|
|
1980
|
-
* import { NonNullableX } from "@nunofyobiz/effect-extras"
|
|
1981
|
-
*
|
|
1982
|
-
* assert.deepStrictEqual(NonNullableX.fromNullableOrThrow("value"), "value")
|
|
1983
|
-
*
|
|
1984
|
-
* assert.throws(
|
|
1985
|
-
* () => NonNullableX.fromNullableOrThrow(null, "varName"),
|
|
1986
|
-
* /Value is nullable: null \(variable name: varName\)/
|
|
1987
|
-
* )
|
|
1988
|
-
* ```
|
|
1989
|
-
*
|
|
1990
|
-
* @category unsafe
|
|
1991
|
-
* @since 0.0.0
|
|
1992
|
-
*/
|
|
1993
|
-
declare const fromNullableOrThrow: <A>(value: A, variableName?: string) => NonNullable<A>;
|
|
1994
|
-
/**
|
|
1995
|
-
* Branches on whether `value` is nullish, passing the value narrowed to
|
|
1996
|
-
* `NonNullable<A>` to the `whenNotNullable` handler.
|
|
1997
|
-
*
|
|
1998
|
-
* A nullable-aware sibling of `Match.value`: it folds a present-or-absent value
|
|
1999
|
-
* into a single `B` without an `if`/`else` or a manual `!= null` check. Note that
|
|
2000
|
-
* falsy-but-present values (`""`, `0`, `false`) take the `whenNotNullable`
|
|
2001
|
-
* branch — only `null` and `undefined` are treated as absent. Supports both
|
|
2002
|
-
* data-first and data-last (pipeable) call styles.
|
|
2003
|
-
*
|
|
2004
|
-
* @example
|
|
2005
|
-
* ```ts
|
|
2006
|
-
* import { NonNullableX } from "@nunofyobiz/effect-extras"
|
|
2007
|
-
* import { pipe } from "effect"
|
|
2008
|
-
*
|
|
2009
|
-
* // Data-first — present value flows through narrowed
|
|
2010
|
-
* assert.deepStrictEqual(
|
|
2011
|
-
* NonNullableX.match("value", {
|
|
2012
|
-
* whenNullable: () => "nullable",
|
|
2013
|
-
* whenNotNullable: (value) => value
|
|
2014
|
-
* }),
|
|
2015
|
-
* "value"
|
|
2016
|
-
* )
|
|
2017
|
-
*
|
|
2018
|
-
* // Data-last — null takes the whenNullable branch
|
|
2019
|
-
* assert.deepStrictEqual(
|
|
2020
|
-
* pipe(
|
|
2021
|
-
* null,
|
|
2022
|
-
* NonNullableX.match({
|
|
2023
|
-
* whenNullable: () => "nullable",
|
|
2024
|
-
* whenNotNullable: (value) => value
|
|
2025
|
-
* })
|
|
2026
|
-
* ),
|
|
2027
|
-
* "nullable"
|
|
2028
|
-
* )
|
|
2029
|
-
* ```
|
|
2030
|
-
*
|
|
2031
|
-
* @category pattern matching
|
|
2032
|
-
* @since 0.0.0
|
|
2033
|
-
*/
|
|
2034
|
-
declare const match: (<A, B>(handlers: {
|
|
2035
|
-
whenNullable: () => B;
|
|
2036
|
-
whenNotNullable: (value: NonNullable<A>) => B;
|
|
2037
|
-
}) => (value: A) => B) & (<A, B>(value: A, handlers: {
|
|
2038
|
-
whenNullable: () => B;
|
|
2039
|
-
whenNotNullable: (value: NonNullable<A>) => B;
|
|
2040
|
-
}) => B);
|
|
2041
|
-
/**
|
|
2042
|
-
* Applies `map` to `a` only when it is non-nullish, passing nullish inputs
|
|
2043
|
-
* through unchanged.
|
|
2044
|
-
*
|
|
2045
|
-
* This is the nullable-preserving map: a present value is transformed to `B`,
|
|
2046
|
-
* while `null` stays `null` and `undefined` stays `undefined`, so nullability is
|
|
2047
|
-
* carried through the transformation. Supports both data-first and data-last
|
|
2048
|
-
* (pipeable) call styles.
|
|
2049
|
-
*
|
|
2050
|
-
* @example
|
|
2051
|
-
* ```ts
|
|
2052
|
-
* import { NonNullableX } from "@nunofyobiz/effect-extras"
|
|
2053
|
-
* import { pipe } from "effect"
|
|
2054
|
-
*
|
|
2055
|
-
* // Data-first — present value is transformed
|
|
2056
|
-
* assert.deepStrictEqual(NonNullableX.map(1, (v: number) => v + 1), 2)
|
|
2057
|
-
*
|
|
2058
|
-
* // Data-last — nullish passes through unchanged
|
|
2059
|
-
* const value: number | null = null
|
|
2060
|
-
* assert.deepStrictEqual(
|
|
2061
|
-
* pipe(
|
|
2062
|
-
* value,
|
|
2063
|
-
* NonNullableX.map<number | null, number>((v) => v + 1)
|
|
2064
|
-
* ),
|
|
2065
|
-
* null
|
|
2066
|
-
* )
|
|
2067
|
-
* ```
|
|
2068
|
-
*
|
|
2069
|
-
* @category mapping
|
|
2070
|
-
* @since 0.0.0
|
|
2071
|
-
*/
|
|
2072
|
-
declare const map: (<A, B>(map: (a: NonNullable<A>) => B) => (a: A) => B | (null & A) | (undefined & A)) & (<A, B>(a: A, map: (a: NonNullable<A>) => B) => B | (null & A) | (undefined & A));
|
|
2073
|
-
/**
|
|
2074
|
-
* Lifts a total function `(a: A) => B` into one that tolerates nullish input,
|
|
2075
|
-
* applying it to present values and passing `null`/`undefined` through unchanged.
|
|
2076
|
-
*
|
|
2077
|
-
* Where `map` operates on a value, `lift` transforms the function itself,
|
|
2078
|
-
* yielding a reusable `(a: A | null | undefined) => B | null | undefined` you can
|
|
2079
|
-
* drop into a `pipe`. Use it to adapt a plain transform to a nullable pipeline
|
|
2080
|
-
* without wrapping each call site.
|
|
2081
|
-
*
|
|
2082
|
-
* @example
|
|
2083
|
-
* ```ts
|
|
2084
|
-
* import { NonNullableX } from "@nunofyobiz/effect-extras"
|
|
2085
|
-
* import { Number, pipe } from "effect"
|
|
2086
|
-
*
|
|
2087
|
-
* const addOne = NonNullableX.lift(Number.sum(1))
|
|
2088
|
-
*
|
|
2089
|
-
* assert.deepStrictEqual(pipe(1, addOne), 2)
|
|
2090
|
-
* assert.deepStrictEqual(pipe(null, addOne), null)
|
|
2091
|
-
* assert.deepStrictEqual(pipe(undefined, addOne), undefined)
|
|
2092
|
-
* ```
|
|
2093
|
-
*
|
|
2094
|
-
* @category mapping
|
|
2095
|
-
* @since 0.0.0
|
|
2096
|
-
*/
|
|
2097
|
-
declare const lift: <A, B>(map: (a: A) => B) => (a: A | null | undefined) => B | null | undefined;
|
|
2098
|
-
/**
|
|
2099
|
-
* Extends an `Order.Order<A>` to an `Order.Order<A | null>`, deciding where
|
|
2100
|
-
* `null` sorts relative to present values via the `behavior` argument.
|
|
2101
|
-
*
|
|
2102
|
-
* Pass `"value-null"` to push `null`s to the end and `"null-value"` to pull them
|
|
2103
|
-
* to the front; two present values fall back to the wrapped order. Use it to sort
|
|
2104
|
-
* collections that mix real values with gaps without a bespoke comparator.
|
|
2105
|
-
* Supports both data-first and data-last (pipeable) call styles.
|
|
2106
|
-
*
|
|
2107
|
-
* @example
|
|
2108
|
-
* ```ts
|
|
2109
|
-
* import { NonNullableX } from "@nunofyobiz/effect-extras"
|
|
2110
|
-
* import { Array, Order, pipe } from "effect"
|
|
2111
|
-
*
|
|
2112
|
-
* // "value-null" — nulls sorted last
|
|
2113
|
-
* assert.deepStrictEqual(
|
|
2114
|
-
* pipe(
|
|
2115
|
-
* [null, 1, 3, null, 2],
|
|
2116
|
-
* Array.sort(NonNullableX.nullableOrder(Order.Number, "value-null"))
|
|
2117
|
-
* ),
|
|
2118
|
-
* [1, 2, 3, null, null]
|
|
2119
|
-
* )
|
|
2120
|
-
*
|
|
2121
|
-
* // "null-value" — nulls sorted first (data-last)
|
|
2122
|
-
* assert.deepStrictEqual(
|
|
2123
|
-
* pipe(
|
|
2124
|
-
* [null, 1, 3, null, 2],
|
|
2125
|
-
* Array.sort(pipe(Order.Number, NonNullableX.nullableOrder("null-value")))
|
|
2126
|
-
* ),
|
|
2127
|
-
* [null, null, 1, 2, 3]
|
|
2128
|
-
* )
|
|
2129
|
-
* ```
|
|
2130
|
-
*
|
|
2131
|
-
* @category ordering
|
|
2132
|
-
* @since 0.0.0
|
|
2133
|
-
*/
|
|
2134
|
-
declare const nullableOrder: ((behavior: "value-null" | "null-value") => <A>(order: Order.Order<A>) => Order.Order<A | null>) & (<A>(order: Order.Order<A>, behavior: "value-null" | "null-value") => Order.Order<A | null>);
|
|
2135
|
-
|
|
2136
|
-
declare const NonNullableX_fromNullableOrThrow: typeof fromNullableOrThrow;
|
|
2137
|
-
declare const NonNullableX_lift: typeof lift;
|
|
2138
|
-
declare const NonNullableX_map: typeof map;
|
|
2139
|
-
declare const NonNullableX_match: typeof match;
|
|
2140
|
-
declare const NonNullableX_nullableOrder: typeof nullableOrder;
|
|
2141
|
-
declare namespace NonNullableX {
|
|
2142
|
-
export { NonNullableX_fromNullableOrThrow as fromNullableOrThrow, NonNullableX_lift as lift, NonNullableX_map as map, NonNullableX_match as match, NonNullableX_nullableOrder as nullableOrder };
|
|
2143
|
-
}
|
|
2144
|
-
|
|
2145
|
-
/**
|
|
2146
|
-
* Generic, framework-agnostic extensions to Effect's `Number` module.
|
|
2147
|
-
*
|
|
2148
|
-
* @since 0.0.0
|
|
2149
|
-
*/
|
|
2150
|
-
|
|
2151
|
-
/**
|
|
2152
|
-
* Computes the logarithm of `number` in the given `base`, throwing when the
|
|
2153
|
-
* inputs fall outside the domain of `log`.
|
|
2154
|
-
*
|
|
2155
|
-
* Throws when `number <= 0`, when `base` is `<= 0` or `1`, or when `number` and
|
|
2156
|
-
* `base` sit on opposite sides of `1` (a fractional base with `number >= 1`, or
|
|
2157
|
-
* a base `>= 1` with `number < 1`) — cases where the real logarithm is
|
|
2158
|
-
* undefined or non-finite. Reach for it only when the inputs are already known
|
|
2159
|
-
* to be valid.
|
|
2160
|
-
*
|
|
2161
|
-
* @example
|
|
2162
|
-
* ```ts
|
|
2163
|
-
* import { pipe } from "effect"
|
|
2164
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2165
|
-
*
|
|
2166
|
-
* // data-first
|
|
2167
|
-
* assert.deepStrictEqual(NumberX.unsafeLogBase(8, 2), 3)
|
|
2168
|
-
* assert.deepStrictEqual(NumberX.unsafeLogBase(100, 10), 2)
|
|
2169
|
-
*
|
|
2170
|
-
* // data-last (piped)
|
|
2171
|
-
* assert.deepStrictEqual(pipe(8, NumberX.unsafeLogBase(2)), 3)
|
|
2172
|
-
*
|
|
2173
|
-
* // throws outside the domain of log
|
|
2174
|
-
* assert.throws(() => NumberX.unsafeLogBase(0, 2))
|
|
2175
|
-
* ```
|
|
2176
|
-
*
|
|
2177
|
-
* @category unsafe
|
|
2178
|
-
* @since 0.0.0
|
|
2179
|
-
*/
|
|
2180
|
-
declare const unsafeLogBase: ((base: number) => (number: number) => number) & ((number: number, base: number) => number);
|
|
2181
|
-
/**
|
|
2182
|
-
* Expresses `numerator` as a percentage of `total`, throwing on division by
|
|
2183
|
-
* zero.
|
|
2184
|
-
*
|
|
2185
|
-
* Returns `(numerator / total) * 100`. When `total` is `0` the percentage is
|
|
2186
|
-
* undefined, so this throws rather than returning `Infinity` or `NaN` — use it
|
|
2187
|
-
* only when `total` is known to be non-zero.
|
|
2188
|
-
*
|
|
2189
|
-
* @example
|
|
2190
|
-
* ```ts
|
|
2191
|
-
* import { pipe } from "effect"
|
|
2192
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2193
|
-
*
|
|
2194
|
-
* // data-first
|
|
2195
|
-
* assert.deepStrictEqual(NumberX.unsafeToPercentOf(1, 2), 50)
|
|
2196
|
-
* assert.deepStrictEqual(NumberX.unsafeToPercentOf(2, 1), 200)
|
|
2197
|
-
*
|
|
2198
|
-
* // data-last (piped)
|
|
2199
|
-
* assert.deepStrictEqual(pipe(1, NumberX.unsafeToPercentOf(2)), 50)
|
|
2200
|
-
*
|
|
2201
|
-
* // throws on division by zero
|
|
2202
|
-
* assert.throws(() => NumberX.unsafeToPercentOf(1, 0))
|
|
2203
|
-
* ```
|
|
2204
|
-
*
|
|
2205
|
-
* @category unsafe
|
|
2206
|
-
* @since 0.0.0
|
|
2207
|
-
*/
|
|
2208
|
-
declare const unsafeToPercentOf: ((total: number) => (numerator: number) => number) & ((numerator: number, total: number) => number);
|
|
2209
|
-
/**
|
|
2210
|
-
* Formats `number` with a fixed number of decimal places, returning a `string`.
|
|
2211
|
-
*
|
|
2212
|
-
* A pipeable wrapper around `Number.prototype.toFixed` — the result is rounded
|
|
2213
|
-
* (not truncated) to `numberDigits` decimals and always carries exactly that
|
|
2214
|
-
* many digits after the point.
|
|
2215
|
-
*
|
|
2216
|
-
* @example
|
|
2217
|
-
* ```ts
|
|
2218
|
-
* import { pipe } from "effect"
|
|
2219
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2220
|
-
*
|
|
2221
|
-
* // data-first
|
|
2222
|
-
* assert.deepStrictEqual(NumberX.toFixed(3.236242, 2), "3.24")
|
|
2223
|
-
*
|
|
2224
|
-
* // data-last (piped)
|
|
2225
|
-
* assert.deepStrictEqual(pipe(3.236242, NumberX.toFixed(0)), "3")
|
|
2226
|
-
* ```
|
|
2227
|
-
*
|
|
2228
|
-
* @category conversions
|
|
2229
|
-
* @since 0.0.0
|
|
2230
|
-
*/
|
|
2231
|
-
declare const toFixed: ((numberDigits: number) => (number: number) => string) & ((number: number, numberDigits: number) => string);
|
|
2232
|
-
/**
|
|
2233
|
-
* Rounds `number` to a fixed number of decimal places, returning a `number`.
|
|
2234
|
-
*
|
|
2235
|
-
* Unlike {@link toFixed}, the result stays a `number` (no trailing zeroes) — it
|
|
2236
|
-
* formats via `toFixed` then parses back, which sidesteps the usual
|
|
2237
|
-
* floating-point rounding artifacts. See
|
|
2238
|
-
* https://stackoverflow.com/a/29494612/22875620.
|
|
2239
|
-
*
|
|
2240
|
-
* @example
|
|
2241
|
-
* ```ts
|
|
2242
|
-
* import { pipe } from "effect"
|
|
2243
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2244
|
-
*
|
|
2245
|
-
* // data-first
|
|
2246
|
-
* assert.deepStrictEqual(NumberX.roundToDigits(3.236242, 2), 3.24)
|
|
2247
|
-
*
|
|
2248
|
-
* // data-last (piped)
|
|
2249
|
-
* assert.deepStrictEqual(pipe(3.736242, NumberX.roundToDigits(0)), 4)
|
|
2250
|
-
* ```
|
|
2251
|
-
*
|
|
2252
|
-
* @category mapping
|
|
2253
|
-
* @since 0.0.0
|
|
2254
|
-
*/
|
|
2255
|
-
declare const roundToDigits: ((numberDigits: number) => (number: number) => number) & ((number: number, numberDigits: number) => number);
|
|
2256
|
-
/**
|
|
2257
|
-
* Renders `number` as a `string`, left-padded with zeroes to at least
|
|
2258
|
-
* `numberDigits` characters.
|
|
2259
|
-
*
|
|
2260
|
-
* If the number's string representation is already as long as (or longer than)
|
|
2261
|
-
* `numberDigits`, it is returned unchanged.
|
|
2262
|
-
*
|
|
2263
|
-
* @example
|
|
2264
|
-
* ```ts
|
|
2265
|
-
* import { pipe } from "effect"
|
|
2266
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2267
|
-
*
|
|
2268
|
-
* // data-first
|
|
2269
|
-
* assert.deepStrictEqual(NumberX.padLeftZeroes(1, 3), "001")
|
|
2270
|
-
*
|
|
2271
|
-
* // longer than the target width is returned unchanged
|
|
2272
|
-
* assert.deepStrictEqual(NumberX.padLeftZeroes(1000, 3), "1000")
|
|
2273
|
-
*
|
|
2274
|
-
* // data-last (piped)
|
|
2275
|
-
* assert.deepStrictEqual(pipe(10, NumberX.padLeftZeroes(3)), "010")
|
|
2276
|
-
* ```
|
|
2277
|
-
*
|
|
2278
|
-
* @category conversions
|
|
2279
|
-
* @since 0.0.0
|
|
2280
|
-
*/
|
|
2281
|
-
declare const padLeftZeroes: ((numberDigits: number) => (number: number) => string) & ((number: number, numberDigits: number) => string);
|
|
2282
|
-
/**
|
|
2283
|
-
* Converts a `0`-indexed value to its `1`-indexed rank by adding `1`.
|
|
2284
|
-
*
|
|
2285
|
-
* Handy for presentation where humans count from one (e.g. the element at
|
|
2286
|
-
* index `0` is shown as "item 1").
|
|
2287
|
-
*
|
|
2288
|
-
* @example
|
|
2289
|
-
* ```ts
|
|
2290
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2291
|
-
*
|
|
2292
|
-
* assert.deepStrictEqual(NumberX.indexToRank(0), 1)
|
|
2293
|
-
* assert.deepStrictEqual(NumberX.indexToRank(4), 5)
|
|
2294
|
-
* ```
|
|
2295
|
-
*
|
|
2296
|
-
* @category mapping
|
|
2297
|
-
* @since 0.0.0
|
|
2298
|
-
*/
|
|
2299
|
-
declare const indexToRank: (index: number) => number;
|
|
2300
|
-
/**
|
|
2301
|
-
* Converts a `0`-indexed column number into its bijective base-26 spreadsheet
|
|
2302
|
-
* label (`A`, `B`, …, `Z`, `AA`, `AB`, …).
|
|
2303
|
-
*
|
|
2304
|
-
* Returns `None` for a negative `index`; every non-negative index maps to a
|
|
2305
|
-
* `Some` label. Indexing is `0`-based here, so `0` is `"A"` and `25` is `"Z"`,
|
|
2306
|
-
* unlike the `1`-based numbering shown in most spreadsheet references.
|
|
2307
|
-
*
|
|
2308
|
-
* @example
|
|
2309
|
-
* ```ts
|
|
2310
|
-
* import { Option } from "effect"
|
|
2311
|
-
* import { NumberX } from "@nunofyobiz/effect-extras"
|
|
2312
|
-
*
|
|
2313
|
-
* assert.deepStrictEqual(NumberX.indexToExcel(0), Option.some("A"))
|
|
2314
|
-
* assert.deepStrictEqual(NumberX.indexToExcel(26), Option.some("AA"))
|
|
2315
|
-
* assert.deepStrictEqual(NumberX.indexToExcel(-1), Option.none())
|
|
2316
|
-
* ```
|
|
2317
|
-
*
|
|
2318
|
-
* @category conversions
|
|
2319
|
-
* @since 0.0.0
|
|
2320
|
-
*/
|
|
2321
|
-
declare const indexToExcel: (index: number) => Option.Option<string>;
|
|
2322
|
-
|
|
2323
|
-
declare const NumberX_indexToExcel: typeof indexToExcel;
|
|
2324
|
-
declare const NumberX_indexToRank: typeof indexToRank;
|
|
2325
|
-
declare const NumberX_padLeftZeroes: typeof padLeftZeroes;
|
|
2326
|
-
declare const NumberX_roundToDigits: typeof roundToDigits;
|
|
2327
|
-
declare const NumberX_toFixed: typeof toFixed;
|
|
2328
|
-
declare const NumberX_unsafeLogBase: typeof unsafeLogBase;
|
|
2329
|
-
declare const NumberX_unsafeToPercentOf: typeof unsafeToPercentOf;
|
|
2330
|
-
declare namespace NumberX {
|
|
2331
|
-
export { NumberX_indexToExcel as indexToExcel, NumberX_indexToRank as indexToRank, NumberX_padLeftZeroes as padLeftZeroes, NumberX_roundToDigits as roundToDigits, NumberX_toFixed as toFixed, NumberX_unsafeLogBase as unsafeLogBase, NumberX_unsafeToPercentOf as unsafeToPercentOf };
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
/**
|
|
2335
|
-
* Generic, framework-agnostic extensions to Effect's `Option` module.
|
|
2336
|
-
*
|
|
2337
|
-
* @since 0.0.0
|
|
2338
|
-
*/
|
|
2339
|
-
|
|
2340
|
-
/**
|
|
2341
|
-
* Combines two `Option`s into an `Option` of a tuple, succeeding only when both
|
|
2342
|
-
* are `Some`.
|
|
2343
|
-
*
|
|
2344
|
-
* Returns `Some([a, b])` when both inputs are `Some`, and `None` if either is
|
|
2345
|
-
* `None`. Useful when an operation needs two optional values present at once.
|
|
2346
|
-
*
|
|
2347
|
-
* @example
|
|
2348
|
-
* ```ts
|
|
2349
|
-
* import { Option } from "effect"
|
|
2350
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2351
|
-
*
|
|
2352
|
-
* // Both Some — succeeds with the pair
|
|
2353
|
-
* assert.deepStrictEqual(
|
|
2354
|
-
* OptionX.tupleOf(Option.some(1), Option.some("a")),
|
|
2355
|
-
* Option.some([1, "a"]),
|
|
2356
|
-
* )
|
|
2357
|
-
*
|
|
2358
|
-
* // Either None collapses to None
|
|
2359
|
-
* assert.deepStrictEqual(
|
|
2360
|
-
* OptionX.tupleOf(Option.some(1), Option.none()),
|
|
2361
|
-
* Option.none(),
|
|
2362
|
-
* )
|
|
2363
|
-
* ```
|
|
2364
|
-
*
|
|
2365
|
-
* @category combinators
|
|
2366
|
-
* @since 0.0.0
|
|
2367
|
-
*/
|
|
2368
|
-
declare const tupleOf: (<A>(a: Option.Option<A>) => <B>(b: Option.Option<B>) => Option.Option<[A, B]>) & (<A, B>(a: Option.Option<A>, b: Option.Option<B>) => Option.Option<[A, B]>);
|
|
2369
|
-
/**
|
|
2370
|
-
* Runs a side effect with the value of an `Option` when it is `Some`, doing
|
|
2371
|
-
* nothing when it is `None`.
|
|
2372
|
-
*
|
|
2373
|
-
* A shorthand for the "if Some, do something" branch of `Option.match` where the
|
|
2374
|
-
* `None` case is a no-op. The callback's return value is ignored — `ifSome`
|
|
2375
|
-
* always returns `void`.
|
|
2376
|
-
*
|
|
2377
|
-
* @example
|
|
2378
|
-
* ```ts
|
|
2379
|
-
* import { Option } from "effect"
|
|
2380
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2381
|
-
*
|
|
2382
|
-
* const log: Array<number> = []
|
|
2383
|
-
* OptionX.ifSome(Option.some(1), (value) => log.push(value))
|
|
2384
|
-
* OptionX.ifSome(Option.none<number>(), (value) => log.push(value))
|
|
2385
|
-
*
|
|
2386
|
-
* assert.deepStrictEqual(log, [1])
|
|
2387
|
-
* ```
|
|
2388
|
-
*
|
|
2389
|
-
* @category sequencing
|
|
2390
|
-
* @since 0.0.0
|
|
2391
|
-
*/
|
|
2392
|
-
declare const ifSome: (<A>(ifSome: (value: A) => void) => (self: Option.Option<A>) => void) & (<A>(self: Option.Option<A>, ifSome: (value: A) => void) => void);
|
|
2393
|
-
/**
|
|
2394
|
-
* Runs a side effect with the value of an `Option` when it is `Some`, then
|
|
2395
|
-
* returns the `Option` unchanged.
|
|
2396
|
-
*
|
|
2397
|
-
* The pass-through counterpart of {@link ifSome}: it taps into a `Some` value
|
|
2398
|
-
* (for logging, metrics, debugging) without breaking a `pipe` chain, since it
|
|
2399
|
-
* returns the original `Option`. For `None` it is a no-op.
|
|
2400
|
-
*
|
|
2401
|
-
* @example
|
|
2402
|
-
* ```ts
|
|
2403
|
-
* import { Option, pipe } from "effect"
|
|
2404
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2405
|
-
*
|
|
2406
|
-
* const log: Array<number> = []
|
|
2407
|
-
* const result = pipe(
|
|
2408
|
-
* Option.some(1),
|
|
2409
|
-
* OptionX.inspectSome((value) => log.push(value)),
|
|
2410
|
-
* Option.map((value) => value + 1),
|
|
2411
|
-
* )
|
|
2412
|
-
*
|
|
2413
|
-
* assert.deepStrictEqual(result, Option.some(2))
|
|
2414
|
-
* assert.deepStrictEqual(log, [1])
|
|
2415
|
-
* ```
|
|
2416
|
-
*
|
|
2417
|
-
* @category sequencing
|
|
2418
|
-
* @since 0.0.0
|
|
2419
|
-
*/
|
|
2420
|
-
declare const inspectSome: (<A>(function_: (value: A) => void) => (self: Option.Option<A>) => Option.Option<A>) & (<A>(self: Option.Option<A>, function_: (value: A) => void) => Option.Option<A>);
|
|
2421
|
-
/**
|
|
2422
|
-
* Normalizes a possibly-nullish `Option` into a plain `Option`, mapping `null`
|
|
2423
|
-
* and `undefined` to `None`.
|
|
2424
|
-
*
|
|
2425
|
-
* Handy at boundaries where an `Option` value might itself arrive as `null` or
|
|
2426
|
-
* `undefined` (for example an optional field that holds an `Option`): the result
|
|
2427
|
-
* is always a well-formed `Option`, never `null`/`undefined`.
|
|
2428
|
-
*
|
|
2429
|
-
* @example
|
|
2430
|
-
* ```ts
|
|
2431
|
-
* import { Option } from "effect"
|
|
2432
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2433
|
-
*
|
|
2434
|
-
* assert.deepStrictEqual(OptionX.fromNullableOption(Option.some(1)), Option.some(1))
|
|
2435
|
-
* assert.deepStrictEqual(OptionX.fromNullableOption(null), Option.none())
|
|
2436
|
-
* assert.deepStrictEqual(OptionX.fromNullableOption(undefined), Option.none())
|
|
2437
|
-
* ```
|
|
2438
|
-
*
|
|
2439
|
-
* @category constructors
|
|
2440
|
-
* @since 0.0.0
|
|
2441
|
-
*/
|
|
2442
|
-
declare const fromNullableOption: <A>(nullableOption: Option.Option<A> | null | undefined) => Option.Option<A>;
|
|
2443
|
-
/**
|
|
2444
|
-
* Maps the value of an `Option` when it is `Some`, returning `null` when it is
|
|
2445
|
-
* `None`.
|
|
2446
|
-
*
|
|
2447
|
-
* A shorthand for `pipe(self, Option.map(map), Option.getOrNull)`. The `null`
|
|
2448
|
-
* fallback makes it especially convenient in JSX/React, where rendering `null`
|
|
2449
|
-
* skips output — `mapSomeOrNull(value, (v) => render(v))` replaces a more verbose
|
|
2450
|
-
* `Option.match` with `onNone: () => null`.
|
|
2451
|
-
*
|
|
2452
|
-
* @example
|
|
2453
|
-
* ```ts
|
|
2454
|
-
* import { Option, pipe } from "effect"
|
|
2455
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2456
|
-
*
|
|
2457
|
-
* // data-first
|
|
2458
|
-
* assert.deepStrictEqual(OptionX.mapSomeOrNull(Option.some(1), (v) => v + 1), 2)
|
|
2459
|
-
*
|
|
2460
|
-
* // None maps to null
|
|
2461
|
-
* assert.deepStrictEqual(
|
|
2462
|
-
* OptionX.mapSomeOrNull(Option.none<number>(), (v) => v + 1),
|
|
2463
|
-
* null,
|
|
2464
|
-
* )
|
|
2465
|
-
*
|
|
2466
|
-
* // data-last (piped)
|
|
2467
|
-
* assert.deepStrictEqual(
|
|
2468
|
-
* pipe(Option.some(1), OptionX.mapSomeOrNull((v) => v + 1)),
|
|
2469
|
-
* 2,
|
|
2470
|
-
* )
|
|
2471
|
-
* ```
|
|
2472
|
-
*
|
|
2473
|
-
* @category mapping
|
|
2474
|
-
* @since 0.0.0
|
|
2475
|
-
*/
|
|
2476
|
-
declare const mapSomeOrNull: (<A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | null) & (<A, B>(self: Option.Option<A>, map: (a: A) => B) => B | null);
|
|
2477
|
-
/**
|
|
2478
|
-
* Maps the value of an `Option` when it is `Some`, returning `undefined` when it
|
|
2479
|
-
* is `None`.
|
|
2480
|
-
*
|
|
2481
|
-
* The `undefined`-returning counterpart of {@link mapSomeOrNull}: a shorthand for
|
|
2482
|
-
* `pipe(self, Option.map(map), Option.getOrUndefined)`. Reach for it when the
|
|
2483
|
-
* consuming API expects `undefined` rather than `null` for "absent" (for example
|
|
2484
|
-
* an optional prop or a value spread into an object).
|
|
2485
|
-
*
|
|
2486
|
-
* @example
|
|
2487
|
-
* ```ts
|
|
2488
|
-
* import { Option, pipe } from "effect"
|
|
2489
|
-
* import { OptionX } from "@nunofyobiz/effect-extras"
|
|
2490
|
-
*
|
|
2491
|
-
* // data-first
|
|
2492
|
-
* assert.deepStrictEqual(
|
|
2493
|
-
* OptionX.mapSomeOrUndefined(Option.some(1), (v) => v + 1),
|
|
2494
|
-
* 2,
|
|
2495
|
-
* )
|
|
2496
|
-
*
|
|
2497
|
-
* // None maps to undefined
|
|
2498
|
-
* assert.deepStrictEqual(
|
|
2499
|
-
* OptionX.mapSomeOrUndefined(Option.none<number>(), (v) => v + 1),
|
|
2500
|
-
* undefined,
|
|
2501
|
-
* )
|
|
2502
|
-
*
|
|
2503
|
-
* // data-last (piped)
|
|
2504
|
-
* assert.deepStrictEqual(
|
|
2505
|
-
* pipe(Option.some(1), OptionX.mapSomeOrUndefined((v) => v + 1)),
|
|
2506
|
-
* 2,
|
|
2507
|
-
* )
|
|
2508
|
-
* ```
|
|
2509
|
-
*
|
|
2510
|
-
* @category mapping
|
|
2511
|
-
* @since 0.0.0
|
|
2512
|
-
*/
|
|
2513
|
-
declare const mapSomeOrUndefined: (<A, B>(map: (a: A) => B) => (self: Option.Option<A>) => B | undefined) & (<A, B>(self: Option.Option<A>, map: (a: A) => B) => B | undefined);
|
|
2514
|
-
|
|
2515
|
-
declare const OptionX_fromNullableOption: typeof fromNullableOption;
|
|
2516
|
-
declare const OptionX_ifSome: typeof ifSome;
|
|
2517
|
-
declare const OptionX_inspectSome: typeof inspectSome;
|
|
2518
|
-
declare const OptionX_mapSomeOrNull: typeof mapSomeOrNull;
|
|
2519
|
-
declare const OptionX_mapSomeOrUndefined: typeof mapSomeOrUndefined;
|
|
2520
|
-
declare const OptionX_tupleOf: typeof tupleOf;
|
|
2521
|
-
declare namespace OptionX {
|
|
2522
|
-
export { OptionX_fromNullableOption as fromNullableOption, OptionX_ifSome as ifSome, OptionX_inspectSome as inspectSome, OptionX_mapSomeOrNull as mapSomeOrNull, OptionX_mapSomeOrUndefined as mapSomeOrUndefined, OptionX_tupleOf as tupleOf };
|
|
2523
|
-
}
|
|
2524
|
-
|
|
2525
|
-
/**
|
|
2526
|
-
* Generic, framework-agnostic extensions to Effect's `Order` module.
|
|
2527
|
-
*
|
|
2528
|
-
* @since 0.0.0
|
|
2529
|
-
*/
|
|
2530
|
-
|
|
2531
|
-
/**
|
|
2532
|
-
* Builds an `Order.Order` for an enum-like set of values from an explicit rank
|
|
2533
|
-
* table, sorting each value by its assigned numeric rank.
|
|
2534
|
-
*
|
|
2535
|
-
* Use it when a union of string (or other `PropertyKey`) literals has a natural
|
|
2536
|
-
* priority that isn't its alphabetical order — pass a record mapping every
|
|
2537
|
-
* member to a rank and the resulting order sorts ascending by that rank.
|
|
2538
|
-
*
|
|
2539
|
-
* @example
|
|
2540
|
-
* ```ts
|
|
2541
|
-
* import { OrderX } from "@nunofyobiz/effect-extras"
|
|
2542
|
-
* import { Array } from "effect"
|
|
2543
|
-
*
|
|
2544
|
-
* const byAge = OrderX.rankedEnum({ child: 0, parent: 1, grandparent: 2 })
|
|
2545
|
-
*
|
|
2546
|
-
* assert.deepStrictEqual(
|
|
2547
|
-
* Array.sort(["parent", "grandparent", "child"], byAge),
|
|
2548
|
-
* ["child", "parent", "grandparent"]
|
|
2549
|
-
* )
|
|
2550
|
-
* ```
|
|
2551
|
-
*
|
|
2552
|
-
* @category ordering
|
|
2553
|
-
* @since 0.0.0
|
|
2554
|
-
*/
|
|
2555
|
-
declare const rankedEnum: <const A extends PropertyKey>(ranks: Record<A, number>) => Order.Order<A>;
|
|
2556
|
-
|
|
2557
|
-
declare const OrderX_rankedEnum: typeof rankedEnum;
|
|
2558
|
-
declare namespace OrderX {
|
|
2559
|
-
export { OrderX_rankedEnum as rankedEnum };
|
|
2560
|
-
}
|
|
2561
|
-
|
|
2562
|
-
/**
|
|
2563
|
-
* Generic, framework-agnostic extensions to Effect's `Predicate` module.
|
|
2564
|
-
*
|
|
2565
|
-
* @since 0.0.0
|
|
2566
|
-
*/
|
|
2567
|
-
|
|
2568
|
-
/**
|
|
2569
|
-
* Runs a refinement against `value` and branches on the result, passing the
|
|
2570
|
-
* narrowed value to the `whenTrue` handler.
|
|
2571
|
-
*
|
|
2572
|
-
* It pairs a `Predicate.Refinement<A, B>` with two continuations so the success
|
|
2573
|
-
* branch receives `value` already narrowed to `B`, replacing an `if`/`else` that
|
|
2574
|
-
* would otherwise re-check or cast. Supports both data-first and data-last
|
|
2575
|
-
* (pipeable) call styles.
|
|
2576
|
-
*
|
|
2577
|
-
* @example
|
|
2578
|
-
* ```ts
|
|
2579
|
-
* import { PredicateX } from "@nunofyobiz/effect-extras"
|
|
2580
|
-
* import { Predicate, pipe } from "effect"
|
|
2581
|
-
*
|
|
2582
|
-
* // Data-first
|
|
2583
|
-
* assert.deepStrictEqual(
|
|
2584
|
-
* PredicateX.matchRefine("hello", Predicate.isString, {
|
|
2585
|
-
* whenTrue: (value) => `String: ${value}`,
|
|
2586
|
-
* whenFalse: () => "Not a string"
|
|
2587
|
-
* }),
|
|
2588
|
-
* "String: hello"
|
|
2589
|
-
* )
|
|
2590
|
-
*
|
|
2591
|
-
* // Data-last (pipeable)
|
|
2592
|
-
* assert.deepStrictEqual(
|
|
2593
|
-
* pipe(
|
|
2594
|
-
* 42,
|
|
2595
|
-
* PredicateX.matchRefine(Predicate.isString, {
|
|
2596
|
-
* whenTrue: (value) => `String: ${value}`,
|
|
2597
|
-
* whenFalse: () => "Not a string"
|
|
2598
|
-
* })
|
|
2599
|
-
* ),
|
|
2600
|
-
* "Not a string"
|
|
2601
|
-
* )
|
|
2602
|
-
* ```
|
|
2603
|
-
*
|
|
2604
|
-
* @category pattern matching
|
|
2605
|
-
* @since 0.0.0
|
|
2606
|
-
*/
|
|
2607
|
-
declare const matchRefine: (<A, B extends A, C>(predicate: Predicate.Refinement<A, B>, handlers: {
|
|
2608
|
-
whenFalse: () => C;
|
|
2609
|
-
whenTrue: (value: B) => C;
|
|
2610
|
-
}) => (value: A) => C) & (<A, B extends A, C>(value: A, predicate: Predicate.Refinement<A, B>, handlers: {
|
|
2611
|
-
whenFalse: () => C;
|
|
2612
|
-
whenTrue: (value: B) => C;
|
|
2613
|
-
}) => C);
|
|
2614
|
-
/**
|
|
2615
|
-
* Refines an `unknown` value to a non-empty `string`, returning `true` only when
|
|
2616
|
-
* the value is present, is a `string`, and has at least one character.
|
|
2617
|
-
*
|
|
2618
|
-
* This is the compound guard the repo's conventions call for: it folds
|
|
2619
|
-
* `Predicate.isNotNullish`, `Predicate.isString`, and `String.isNonEmpty` into a
|
|
2620
|
-
* single reusable refinement so call sites get `value is string` narrowing
|
|
2621
|
-
* without restating the three checks.
|
|
2622
|
-
*
|
|
2623
|
-
* @example
|
|
2624
|
-
* ```ts
|
|
2625
|
-
* import { PredicateX } from "@nunofyobiz/effect-extras"
|
|
2626
|
-
*
|
|
2627
|
-
* assert.deepStrictEqual(PredicateX.isNonEmptyString("hello"), true)
|
|
2628
|
-
* assert.deepStrictEqual(PredicateX.isNonEmptyString(""), false)
|
|
2629
|
-
* assert.deepStrictEqual(PredicateX.isNonEmptyString(null), false)
|
|
2630
|
-
* assert.deepStrictEqual(PredicateX.isNonEmptyString(123), false)
|
|
2631
|
-
* ```
|
|
2632
|
-
*
|
|
2633
|
-
* @category refinements
|
|
2634
|
-
* @since 0.0.0
|
|
2635
|
-
*/
|
|
2636
|
-
declare function isNonEmptyString(value: unknown): value is string;
|
|
2637
|
-
|
|
2638
|
-
declare const PredicateX_isNonEmptyString: typeof isNonEmptyString;
|
|
2639
|
-
declare const PredicateX_matchRefine: typeof matchRefine;
|
|
2640
|
-
declare namespace PredicateX {
|
|
2641
|
-
export { PredicateX_isNonEmptyString as isNonEmptyString, PredicateX_matchRefine as matchRefine };
|
|
2642
|
-
}
|
|
2643
|
-
|
|
2644
|
-
/**
|
|
2645
|
-
* Helpers for working with native `Promise`s.
|
|
2646
|
-
*
|
|
2647
|
-
* @since 0.0.0
|
|
2648
|
-
*/
|
|
2649
|
-
/**
|
|
2650
|
-
* Discards the resolved value of a `Promise`, returning a `Promise<void>` that
|
|
2651
|
-
* resolves once the original settles.
|
|
2652
|
-
*
|
|
2653
|
-
* Useful when you await a promise only for its side effect and want the result
|
|
2654
|
-
* type to reflect that nothing meaningful is produced — for example when an API
|
|
2655
|
-
* expects a `Promise<void>` or when narrowing a value-bearing promise to keep
|
|
2656
|
-
* call sites from accidentally depending on the resolved value. A rejection of
|
|
2657
|
-
* the original promise still propagates.
|
|
2658
|
-
*
|
|
2659
|
-
* @example
|
|
2660
|
-
* ```ts
|
|
2661
|
-
* import { PromiseX } from "@nunofyobiz/effect-extras"
|
|
2662
|
-
*
|
|
2663
|
-
* const run = async (): Promise<void> => {
|
|
2664
|
-
* const result = await PromiseX.asVoid(Promise.resolve(42))
|
|
2665
|
-
* assert.deepStrictEqual(result, undefined)
|
|
2666
|
-
* }
|
|
2667
|
-
*
|
|
2668
|
-
* void run()
|
|
2669
|
-
* ```
|
|
2670
|
-
*
|
|
2671
|
-
* @category conversions
|
|
2672
|
-
* @since 0.0.0
|
|
2673
|
-
*/
|
|
2674
|
-
declare const asVoid: <T>(promise: Promise<T>) => Promise<void>;
|
|
2675
|
-
|
|
2676
|
-
declare const PromiseX_asVoid: typeof asVoid;
|
|
2677
|
-
declare namespace PromiseX {
|
|
2678
|
-
export { PromiseX_asVoid as asVoid };
|
|
2679
|
-
}
|
|
2680
|
-
|
|
2681
|
-
/**
|
|
2682
|
-
* Generic, framework-agnostic extensions to Effect's `Record` module.
|
|
2683
|
-
*
|
|
2684
|
-
* @since 0.0.0
|
|
2685
|
-
*/
|
|
2686
|
-
|
|
2687
|
-
/**
|
|
2688
|
-
* Returns `true` when `record` has at least one entry, narrowing it to a
|
|
2689
|
-
* known-non-empty `Record`.
|
|
2690
|
-
*
|
|
2691
|
-
* The negation of `Record.isEmptyRecord`, packaged as a type guard so it reads
|
|
2692
|
-
* naturally at call sites that want to branch on "this record has something in
|
|
2693
|
-
* it" without a manual `!Record.isEmptyRecord(...)`.
|
|
2694
|
-
*
|
|
2695
|
-
* @example
|
|
2696
|
-
* ```ts
|
|
2697
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2698
|
-
*
|
|
2699
|
-
* assert.deepStrictEqual(RecordX.isNonEmptyRecord({ a: 1 }), true)
|
|
2700
|
-
* assert.deepStrictEqual(RecordX.isNonEmptyRecord({}), false)
|
|
2701
|
-
* ```
|
|
2702
|
-
*
|
|
2703
|
-
* @category guards
|
|
2704
|
-
* @since 0.0.0
|
|
2705
|
-
*/
|
|
2706
|
-
declare const isNonEmptyRecord: <K extends PropertyKey, V>(record: Record<K, V>) => record is Record<K, V>;
|
|
2707
|
-
/**
|
|
2708
|
-
* Modifies the value at `key` in `self` with `f`, leaving the record unchanged
|
|
2709
|
-
* if the key doesn't exist.
|
|
2710
|
-
*
|
|
2711
|
-
* v4's `Record.modify` returns `Option<Record>` — `None` when the key is
|
|
2712
|
-
* absent. This helper picks the "do nothing if absent" semantics that v3's
|
|
2713
|
-
* `Record.modify` had implicitly, and that most call sites assume. The modifier
|
|
2714
|
-
* is never invoked when the key is missing.
|
|
2715
|
-
*
|
|
2716
|
-
* @example
|
|
2717
|
-
* ```ts
|
|
2718
|
-
* import { pipe } from "effect"
|
|
2719
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2720
|
-
*
|
|
2721
|
-
* // data-first
|
|
2722
|
-
* assert.deepStrictEqual(
|
|
2723
|
-
* RecordX.modifyIfExists({ a: 1, b: 2 }, "b", (n) => n * 10),
|
|
2724
|
-
* { a: 1, b: 20 },
|
|
2725
|
-
* )
|
|
2726
|
-
*
|
|
2727
|
-
* // a missing key leaves the record untouched
|
|
2728
|
-
* const counts: Record<string, number> = { a: 1, b: 2 }
|
|
2729
|
-
* assert.deepStrictEqual(
|
|
2730
|
-
* RecordX.modifyIfExists(counts, "missing", (n) => n + 1),
|
|
2731
|
-
* { a: 1, b: 2 },
|
|
2732
|
-
* )
|
|
2733
|
-
*
|
|
2734
|
-
* // data-last (pipeable)
|
|
2735
|
-
* assert.deepStrictEqual(
|
|
2736
|
-
* pipe({ a: 1, b: 2 }, RecordX.modifyIfExists("a", (n) => n * 10)),
|
|
2737
|
-
* { a: 10, b: 2 },
|
|
2738
|
-
* )
|
|
2739
|
-
* ```
|
|
2740
|
-
*
|
|
2741
|
-
* @category mapping
|
|
2742
|
-
* @since 0.0.0
|
|
2743
|
-
*/
|
|
2744
|
-
declare const modifyIfExists: {
|
|
2745
|
-
<K extends string, A>(key: NoInfer<K>, f: (a: A) => A): (self: Record<K, A>) => Record<K, A>;
|
|
2746
|
-
<K extends string, A>(self: Record<K, A>, key: NoInfer<K>, f: (a: A) => A): Record<K, A>;
|
|
2747
|
-
};
|
|
2748
|
-
/**
|
|
2749
|
-
* Returns the smallest value of `record` (per `order`) that matches
|
|
2750
|
-
* `predicate`, narrowed to the refined type `B`, or `Option.none()` if none
|
|
2751
|
-
* match.
|
|
2752
|
-
*
|
|
2753
|
-
* The `Record` counterpart of `ArrayX.takeFirstWhere`: it considers only the
|
|
2754
|
-
* record's values, keeps those satisfying `predicate`, and returns the minimum
|
|
2755
|
-
* of them by `order`. Keys are ignored entirely.
|
|
2756
|
-
*
|
|
2757
|
-
* @example
|
|
2758
|
-
* ```ts
|
|
2759
|
-
* import { Option, Order, pipe } from "effect"
|
|
2760
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2761
|
-
*
|
|
2762
|
-
* const isEven = (n: number): n is number => n % 2 === 0
|
|
2763
|
-
*
|
|
2764
|
-
* // data-first
|
|
2765
|
-
* assert.deepStrictEqual(
|
|
2766
|
-
* RecordX.takeFirstWhere({ a: 3, b: 4, c: 2 }, isEven, Order.Number),
|
|
2767
|
-
* Option.some(2),
|
|
2768
|
-
* )
|
|
2769
|
-
*
|
|
2770
|
-
* // data-last (pipeable); no even values yields None
|
|
2771
|
-
* assert.deepStrictEqual(
|
|
2772
|
-
* pipe({ a: 1, b: 3 }, RecordX.takeFirstWhere(isEven, Order.Number)),
|
|
2773
|
-
* Option.none(),
|
|
2774
|
-
* )
|
|
2775
|
-
* ```
|
|
2776
|
-
*
|
|
2777
|
-
* @category getters
|
|
2778
|
-
* @since 0.0.0
|
|
2779
|
-
*/
|
|
2780
|
-
declare const takeFirstWhere: (<K extends PropertyKey, A, B extends A>(predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => (record: Record<K, A>) => Option.Option<B>) & (<K extends PropertyKey, A, B extends A>(record: Record<K, A>, predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => Option.Option<B>);
|
|
2781
|
-
/**
|
|
2782
|
-
* Returns the largest value of `record` (per `order`) that matches `predicate`,
|
|
2783
|
-
* narrowed to the refined type `B`, or `Option.none()` if none match.
|
|
2784
|
-
*
|
|
2785
|
-
* The mirror of {@link takeFirstWhere}: it considers only the record's values,
|
|
2786
|
-
* keeps those satisfying `predicate`, and returns the maximum of them by
|
|
2787
|
-
* `order`. Keys are ignored entirely.
|
|
2788
|
-
*
|
|
2789
|
-
* @example
|
|
2790
|
-
* ```ts
|
|
2791
|
-
* import { Option, Order, pipe } from "effect"
|
|
2792
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2793
|
-
*
|
|
2794
|
-
* const isEven = (n: number): n is number => n % 2 === 0
|
|
2795
|
-
*
|
|
2796
|
-
* // data-first
|
|
2797
|
-
* assert.deepStrictEqual(
|
|
2798
|
-
* RecordX.takeLastWhere({ a: 3, b: 4, c: 2 }, isEven, Order.Number),
|
|
2799
|
-
* Option.some(4),
|
|
2800
|
-
* )
|
|
2801
|
-
*
|
|
2802
|
-
* // data-last (pipeable); no even values yields None
|
|
2803
|
-
* assert.deepStrictEqual(
|
|
2804
|
-
* pipe({ a: 1, b: 3 }, RecordX.takeLastWhere(isEven, Order.Number)),
|
|
2805
|
-
* Option.none(),
|
|
2806
|
-
* )
|
|
2807
|
-
* ```
|
|
2808
|
-
*
|
|
2809
|
-
* @category getters
|
|
2810
|
-
* @since 0.0.0
|
|
2811
|
-
*/
|
|
2812
|
-
declare const takeLastWhere: (<K extends PropertyKey, A, B extends A>(predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => (record: Record<K, A>) => Option.Option<B>) & (<K extends PropertyKey, A, B extends A>(record: Record<K, A>, predicate: Predicate.Refinement<A, B>, order: Order.Order<B>) => Option.Option<B>);
|
|
2813
|
-
/**
|
|
2814
|
-
* Returns the largest value of `record` according to `order`, wrapped in an
|
|
2815
|
-
* `Option` so empty records are handled safely.
|
|
2816
|
-
*
|
|
2817
|
-
* Sorts the record's values by `order` and takes the last one, yielding
|
|
2818
|
-
* `Option.none()` when the record is empty and `Option.some(max)` otherwise.
|
|
2819
|
-
* Keys are ignored — only values participate in the ordering.
|
|
2820
|
-
*
|
|
2821
|
-
* @example
|
|
2822
|
-
* ```ts
|
|
2823
|
-
* import { Option, Order, pipe } from "effect"
|
|
2824
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2825
|
-
*
|
|
2826
|
-
* // data-first
|
|
2827
|
-
* assert.deepStrictEqual(
|
|
2828
|
-
* RecordX.takeLast({ a: 3, b: 5, c: 1 }, Order.Number),
|
|
2829
|
-
* Option.some(5),
|
|
2830
|
-
* )
|
|
2831
|
-
*
|
|
2832
|
-
* // data-last (pipeable); empty record yields None
|
|
2833
|
-
* assert.deepStrictEqual(
|
|
2834
|
-
* pipe({}, RecordX.takeLast(Order.Number)),
|
|
2835
|
-
* Option.none(),
|
|
2836
|
-
* )
|
|
2837
|
-
* ```
|
|
2838
|
-
*
|
|
2839
|
-
* @category getters
|
|
2840
|
-
* @since 0.0.0
|
|
2841
|
-
*/
|
|
2842
|
-
declare const takeLast: (<K extends PropertyKey, A>(order: Order.Order<A>) => (record: Record<K, A>) => Option.Option<A>) & (<K extends PropertyKey, A>(record: Record<K, A>, order: Order.Order<A>) => Option.Option<A>);
|
|
2843
|
-
/**
|
|
2844
|
-
* Re-types the keys of a `Record` to a different key type `K2` without touching
|
|
2845
|
-
* the runtime value.
|
|
2846
|
-
*
|
|
2847
|
-
* A purely type-level reinterpretation: the record is returned as-is, but the
|
|
2848
|
-
* compiler now treats its keys as `K2` instead of the inferred `K1`. Use it at a
|
|
2849
|
-
* boundary where you know the keys conform to a narrower branded or literal key
|
|
2850
|
-
* type that TypeScript can't infer from the value alone. It performs no
|
|
2851
|
-
* validation — the caller is responsible for the keys actually matching `K2`.
|
|
2852
|
-
*
|
|
2853
|
-
* @example
|
|
2854
|
-
* ```ts
|
|
2855
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2856
|
-
*
|
|
2857
|
-
* type UserId = string & { readonly _brand: "UserId" }
|
|
2858
|
-
*
|
|
2859
|
-
* const byId: Record<string, number> = { u1: 10, u2: 20 }
|
|
2860
|
-
* const branded = RecordX.keysAs<UserId>()(byId)
|
|
2861
|
-
*
|
|
2862
|
-
* // Same runtime value, keys now seen as `UserId`
|
|
2863
|
-
* assert.deepStrictEqual(branded, { u1: 10, u2: 20 })
|
|
2864
|
-
* ```
|
|
2865
|
-
*
|
|
2866
|
-
* @category conversions
|
|
2867
|
-
* @since 0.0.0
|
|
2868
|
-
*/
|
|
2869
|
-
declare const keysAs: <K2 extends PropertyKey>() => <K1 extends PropertyKey, V>(record: Record<K1, V>) => Record<K2, V>;
|
|
2870
|
-
/**
|
|
2871
|
-
* Returns the value at `key` in `record`, throwing an `Error` if the key is
|
|
2872
|
-
* absent.
|
|
2873
|
-
*
|
|
2874
|
-
* The unsafe, get-or-explode counterpart to `Record.get` (which returns an
|
|
2875
|
-
* `Option`). The thrown error names the missing key and lists the record's
|
|
2876
|
-
* existing keys to aid debugging. Reach for {@link getOrThrowWith} when you need
|
|
2877
|
-
* a custom error; prefer `Record.get` whenever absence is a real possibility.
|
|
2878
|
-
*
|
|
2879
|
-
* @example
|
|
2880
|
-
* ```ts
|
|
2881
|
-
* import { pipe } from "effect"
|
|
2882
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2883
|
-
*
|
|
2884
|
-
* const record: Record<string, number> = { a: 1, b: 2 }
|
|
2885
|
-
*
|
|
2886
|
-
* // data-first
|
|
2887
|
-
* assert.deepStrictEqual(RecordX.getOrThrow(record, "a"), 1)
|
|
2888
|
-
*
|
|
2889
|
-
* // data-last (pipeable)
|
|
2890
|
-
* assert.deepStrictEqual(pipe(record, RecordX.getOrThrow("b")), 2)
|
|
2891
|
-
*
|
|
2892
|
-
* // missing key throws
|
|
2893
|
-
* assert.throws(() => RecordX.getOrThrow(record, "missing"))
|
|
2894
|
-
* ```
|
|
2895
|
-
*
|
|
2896
|
-
* @category unsafe
|
|
2897
|
-
* @since 0.0.0
|
|
2898
|
-
*/
|
|
2899
|
-
declare const getOrThrow: (<K extends string | symbol>(key: K) => <V>(record: Record<K, V>) => V) & (<K extends string | symbol, V>(record: Record<K, V>, key: K) => V);
|
|
2900
|
-
/**
|
|
2901
|
-
* Returns the value at `key` in `record`, throwing the result of `onNone(key)`
|
|
2902
|
-
* if the key is absent.
|
|
2903
|
-
*
|
|
2904
|
-
* Like {@link getOrThrow}, but lets the caller supply the thrown value (an
|
|
2905
|
-
* `Error`, a string, or any custom failure) computed from the missing key. Use
|
|
2906
|
-
* it when the default "key not found" message isn't descriptive enough for the
|
|
2907
|
-
* call site.
|
|
2908
|
-
*
|
|
2909
|
-
* @example
|
|
2910
|
-
* ```ts
|
|
2911
|
-
* import { pipe } from "effect"
|
|
2912
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2913
|
-
*
|
|
2914
|
-
* const record: Record<string, number> = { a: 1 }
|
|
2915
|
-
* const onNone = (key: string) => new Error(`no ${key}`)
|
|
2916
|
-
*
|
|
2917
|
-
* // data-first
|
|
2918
|
-
* assert.deepStrictEqual(RecordX.getOrThrowWith(record, "a", onNone), 1)
|
|
2919
|
-
*
|
|
2920
|
-
* // data-last (pipeable)
|
|
2921
|
-
* assert.deepStrictEqual(pipe(record, RecordX.getOrThrowWith("a", onNone)), 1)
|
|
2922
|
-
*
|
|
2923
|
-
* // missing key throws the custom error
|
|
2924
|
-
* assert.throws(() => RecordX.getOrThrowWith(record, "missing", onNone))
|
|
2925
|
-
* ```
|
|
2926
|
-
*
|
|
2927
|
-
* @category unsafe
|
|
2928
|
-
* @since 0.0.0
|
|
2929
|
-
*/
|
|
2930
|
-
declare const getOrThrowWith: (<K extends string | symbol>(key: K, onNone: (key: K) => unknown) => <V>(record: Record<K, V>) => V) & (<K extends string | symbol, V>(record: Record<K, V>, key: K, onNone: (key: K) => unknown) => V);
|
|
2931
|
-
/**
|
|
2932
|
-
* Inserts or updates the value at `key`, deriving the new value from the current
|
|
2933
|
-
* one via `upsert`.
|
|
2934
|
-
*
|
|
2935
|
-
* The `upsert` function receives an `Option` of the existing value —
|
|
2936
|
-
* `Option.some(value)` when the key is present, `Option.none()` when it's
|
|
2937
|
-
* absent — and returns the value to store. This unifies "insert if missing" and
|
|
2938
|
-
* "update if present" into a single pass, with `Option.match` as the natural way
|
|
2939
|
-
* to handle both cases.
|
|
2940
|
-
*
|
|
2941
|
-
* @example
|
|
2942
|
-
* ```ts
|
|
2943
|
-
* import { Option, pipe } from "effect"
|
|
2944
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2945
|
-
*
|
|
2946
|
-
* const bump = Option.match({
|
|
2947
|
-
* onNone: () => 1,
|
|
2948
|
-
* onSome: (n: number) => n + 1,
|
|
2949
|
-
* })
|
|
2950
|
-
*
|
|
2951
|
-
* // data-first: updates an existing entry
|
|
2952
|
-
* assert.deepStrictEqual(RecordX.upsert({ a: 1 }, "a", bump), { a: 2 })
|
|
2953
|
-
*
|
|
2954
|
-
* // data-last (pipeable): inserts a missing entry
|
|
2955
|
-
* const counts: Record<string, number> = { a: 1 }
|
|
2956
|
-
* assert.deepStrictEqual(pipe(counts, RecordX.upsert("b", bump)), {
|
|
2957
|
-
* a: 1,
|
|
2958
|
-
* b: 1,
|
|
2959
|
-
* })
|
|
2960
|
-
* ```
|
|
2961
|
-
*
|
|
2962
|
-
* @category mapping
|
|
2963
|
-
* @since 0.0.0
|
|
2964
|
-
*/
|
|
2965
|
-
declare const upsert: (<K extends string | symbol, V>(key: K, upsert: (existingValue: Option.Option<V>) => V) => (record: Record<K, V>) => Record<K, V>) & (<K extends string | symbol, V>(record: Record<K, V>, key: K, upsert: (existingValue: Option.Option<V>) => V) => Record<K, V>);
|
|
2966
|
-
/**
|
|
2967
|
-
* Indexes an iterable of values into a `Record`, keying each value by the result
|
|
2968
|
-
* of `identify`.
|
|
2969
|
-
*
|
|
2970
|
-
* Builds a lookup table from a collection: every value is stored under the key
|
|
2971
|
-
* `identify(value)`. When two values produce the same key the later one wins, so
|
|
2972
|
-
* the result holds the last value seen per key. Useful for turning a list of
|
|
2973
|
-
* records into a by-id map.
|
|
2974
|
-
*
|
|
2975
|
-
* @example
|
|
2976
|
-
* ```ts
|
|
2977
|
-
* import { pipe } from "effect"
|
|
2978
|
-
* import { RecordX } from "@nunofyobiz/effect-extras"
|
|
2979
|
-
*
|
|
2980
|
-
* const items = [
|
|
2981
|
-
* { id: "a", n: 1 },
|
|
2982
|
-
* { id: "b", n: 2 },
|
|
2983
|
-
* { id: "a", n: 3 }, // wins over the earlier "a"
|
|
2984
|
-
* ]
|
|
2985
|
-
*
|
|
2986
|
-
* // data-first
|
|
2987
|
-
* assert.deepStrictEqual(
|
|
2988
|
-
* RecordX.collectBy(items, (item) => item.id),
|
|
2989
|
-
* { a: { id: "a", n: 3 }, b: { id: "b", n: 2 } },
|
|
2990
|
-
* )
|
|
2991
|
-
*
|
|
2992
|
-
* // data-last (pipeable)
|
|
2993
|
-
* assert.deepStrictEqual(
|
|
2994
|
-
* pipe(items, RecordX.collectBy((item) => item.id)),
|
|
2995
|
-
* { a: { id: "a", n: 3 }, b: { id: "b", n: 2 } },
|
|
2996
|
-
* )
|
|
2997
|
-
* ```
|
|
2998
|
-
*
|
|
2999
|
-
* @category constructors
|
|
3000
|
-
* @since 0.0.0
|
|
3001
|
-
*/
|
|
3002
|
-
declare const collectBy: (<K extends string | symbol, V>(identify: (v: V) => K) => (values: Iterable<V>) => Record<K, V>) & (<K extends string | symbol, V>(values: Iterable<V>, identify: (v: V) => K) => Record<K, V>);
|
|
3003
|
-
|
|
3004
|
-
declare const RecordX_collectBy: typeof collectBy;
|
|
3005
|
-
declare const RecordX_getOrThrow: typeof getOrThrow;
|
|
3006
|
-
declare const RecordX_getOrThrowWith: typeof getOrThrowWith;
|
|
3007
|
-
declare const RecordX_isNonEmptyRecord: typeof isNonEmptyRecord;
|
|
3008
|
-
declare const RecordX_keysAs: typeof keysAs;
|
|
3009
|
-
declare const RecordX_modifyIfExists: typeof modifyIfExists;
|
|
3010
|
-
declare const RecordX_takeFirstWhere: typeof takeFirstWhere;
|
|
3011
|
-
declare const RecordX_takeLast: typeof takeLast;
|
|
3012
|
-
declare const RecordX_takeLastWhere: typeof takeLastWhere;
|
|
3013
|
-
declare const RecordX_upsert: typeof upsert;
|
|
3014
|
-
declare namespace RecordX {
|
|
3015
|
-
export { RecordX_collectBy as collectBy, RecordX_getOrThrow as getOrThrow, RecordX_getOrThrowWith as getOrThrowWith, RecordX_isNonEmptyRecord as isNonEmptyRecord, RecordX_keysAs as keysAs, RecordX_modifyIfExists as modifyIfExists, RecordX_takeFirstWhere as takeFirstWhere, RecordX_takeLast as takeLast, RecordX_takeLastWhere as takeLastWhere, RecordX_upsert as upsert };
|
|
3016
|
-
}
|
|
3017
|
-
|
|
3018
|
-
/**
|
|
3019
|
-
* Generic, framework-agnostic extensions to Effect's `Result` module.
|
|
3020
|
-
*
|
|
3021
|
-
* @since 0.0.0
|
|
3022
|
-
*/
|
|
3023
|
-
|
|
3024
|
-
/**
|
|
3025
|
-
* Lifts an `Option` into a `Result` with a `void` failure: `Some(value)` becomes
|
|
3026
|
-
* `Result.succeed(value)` and `None` becomes `Result.failVoid`.
|
|
3027
|
-
*
|
|
3028
|
-
* Useful in v4 where `Array.filterMap` and `Record.filterMap` expect
|
|
3029
|
-
* `Result`-returning predicates (a `Success` keeps the value, a `Failure` drops
|
|
3030
|
-
* it); in v3 those APIs accepted `Option`-returning predicates directly:
|
|
3031
|
-
*
|
|
3032
|
-
* ```ts
|
|
3033
|
-
* import { Array } from "effect"
|
|
3034
|
-
* import { ResultX } from "@nunofyobiz/effect-extras"
|
|
3035
|
-
*
|
|
3036
|
-
* declare const items: ReadonlyArray<number>
|
|
3037
|
-
* declare const maybeTransform: (item: number) => import("effect").Option.Option<string>
|
|
3038
|
-
*
|
|
3039
|
-
* // v3: Array.filterMap(items, (item) => maybeTransform(item))
|
|
3040
|
-
* // v4:
|
|
3041
|
-
* Array.filterMap(items, (item) => ResultX.fromOption(maybeTransform(item)))
|
|
3042
|
-
* ```
|
|
3043
|
-
*
|
|
3044
|
-
* Effect ships `Result.fromOption(option, onNone)` which requires a non-`void`
|
|
3045
|
-
* failure value; this helper specializes to the common "drop the item, no error
|
|
3046
|
-
* needed" case used by `filterMap`.
|
|
3047
|
-
*
|
|
3048
|
-
* @example
|
|
3049
|
-
* ```ts
|
|
3050
|
-
* import { Option, Result } from "effect"
|
|
3051
|
-
* import { ResultX } from "@nunofyobiz/effect-extras"
|
|
3052
|
-
*
|
|
3053
|
-
* assert.deepStrictEqual(
|
|
3054
|
-
* ResultX.fromOption(Option.some(1)),
|
|
3055
|
-
* Result.succeed(1),
|
|
3056
|
-
* )
|
|
3057
|
-
* assert.deepStrictEqual(
|
|
3058
|
-
* ResultX.fromOption(Option.none<number>()),
|
|
3059
|
-
* Result.failVoid,
|
|
3060
|
-
* )
|
|
3061
|
-
* ```
|
|
3062
|
-
*
|
|
3063
|
-
* @category conversions
|
|
3064
|
-
* @since 0.0.0
|
|
3065
|
-
*/
|
|
3066
|
-
declare const fromOption: <A>(option: Option.Option<A>) => Result.Result<A, void>;
|
|
3067
|
-
|
|
3068
|
-
declare const ResultX_fromOption: typeof fromOption;
|
|
3069
|
-
declare namespace ResultX {
|
|
3070
|
-
export { ResultX_fromOption as fromOption };
|
|
3071
|
-
}
|
|
3072
|
-
|
|
3073
|
-
/**
|
|
3074
|
-
* Generic, framework-agnostic extensions to Effect's `Schema` module.
|
|
3075
|
-
*
|
|
3076
|
-
* @since 0.0.0
|
|
3077
|
-
*/
|
|
3078
|
-
|
|
3079
|
-
/**
|
|
3080
|
-
* A `Schema` for a non-empty string that is trimmed on both decode and encode.
|
|
3081
|
-
*
|
|
3082
|
-
* Leading and trailing whitespace is stripped, and the resulting value must be
|
|
3083
|
-
* non-empty — so a whitespace-only input (e.g. `" "`) fails the
|
|
3084
|
-
* `NonEmptyString` refinement after trimming. Use it wherever user-supplied text
|
|
3085
|
-
* should be normalized and guaranteed to carry content.
|
|
3086
|
-
*
|
|
3087
|
-
* @example
|
|
3088
|
-
* ```ts
|
|
3089
|
-
* import { Effect, Schema } from "effect"
|
|
3090
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3091
|
-
*
|
|
3092
|
-
* const decoded = Effect.runSync(
|
|
3093
|
-
* Schema.decodeEffect(SchemaX.TrimmedNonEmptyString)(" hello "),
|
|
3094
|
-
* )
|
|
3095
|
-
* assert.deepStrictEqual(decoded, "hello")
|
|
3096
|
-
* ```
|
|
3097
|
-
*
|
|
3098
|
-
* @category constructors
|
|
3099
|
-
* @since 0.0.0
|
|
3100
|
-
*/
|
|
3101
|
-
declare const TrimmedNonEmptyString: Schema.decodeTo<Schema.toType<Schema.NonEmptyString>, Schema.NonEmptyString, never, never>;
|
|
3102
|
-
/**
|
|
3103
|
-
* A `Schema` for a URL-safe file path built on top of {@link
|
|
3104
|
-
* TrimmedNonEmptyString}.
|
|
3105
|
-
*
|
|
3106
|
-
* On decode the path is `decodeURIComponent`-ed (percent-escapes are expanded);
|
|
3107
|
-
* on encode it is `encodeURIComponent`-ed back into its URL-safe form. The
|
|
3108
|
-
* underlying value is also trimmed and required to be non-empty. Use it at the
|
|
3109
|
-
* boundary between stored/transmitted encoded paths and the decoded paths your
|
|
3110
|
-
* code works with.
|
|
3111
|
-
*
|
|
3112
|
-
* @example
|
|
3113
|
-
* ```ts
|
|
3114
|
-
* import { Effect, Schema } from "effect"
|
|
3115
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3116
|
-
*
|
|
3117
|
-
* // Decoding expands percent-escapes
|
|
3118
|
-
* const decoded = Effect.runSync(
|
|
3119
|
-
* Schema.decodeEffect(SchemaX.URLSafeFilePath)("a%2Fb.txt"),
|
|
3120
|
-
* )
|
|
3121
|
-
* assert.deepStrictEqual(decoded, "a/b.txt")
|
|
3122
|
-
*
|
|
3123
|
-
* // Encoding produces the URL-safe form
|
|
3124
|
-
* const encoded = Effect.runSync(
|
|
3125
|
-
* Schema.encodeEffect(SchemaX.URLSafeFilePath)("a/b.txt"),
|
|
3126
|
-
* )
|
|
3127
|
-
* assert.deepStrictEqual(encoded, "a%2Fb.txt")
|
|
3128
|
-
* ```
|
|
3129
|
-
*
|
|
3130
|
-
* @category constructors
|
|
3131
|
-
* @since 0.0.0
|
|
3132
|
-
*/
|
|
3133
|
-
declare const URLSafeFilePath: Schema.decodeTo<Schema.toType<Schema.decodeTo<Schema.toType<Schema.NonEmptyString>, Schema.NonEmptyString, never, never>>, Schema.decodeTo<Schema.toType<Schema.NonEmptyString>, Schema.NonEmptyString, never, never>, never, never>;
|
|
3134
|
-
/**
|
|
3135
|
-
* Transforms a `bigint` `Schema` so its value is clamped to be non-negative,
|
|
3136
|
-
* mapping any value below `0n` up to `0n` on both decode and encode.
|
|
3137
|
-
*
|
|
3138
|
-
* Unlike a refinement that *rejects* negative input, this *coerces* it: a
|
|
3139
|
-
* negative `bigint` decodes to `0n` rather than failing. Apply it to a `bigint`
|
|
3140
|
-
* schema whenever negative magnitudes are meaningless and should be floored at
|
|
3141
|
-
* zero rather than treated as errors.
|
|
3142
|
-
*
|
|
3143
|
-
* @example
|
|
3144
|
-
* ```ts
|
|
3145
|
-
* import { Effect, Schema } from "effect"
|
|
3146
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3147
|
-
*
|
|
3148
|
-
* const NonNegative = SchemaX.nonNegativeBigInt(Schema.BigInt)
|
|
3149
|
-
*
|
|
3150
|
-
* // Negative values are clamped up to 0n
|
|
3151
|
-
* assert.deepStrictEqual(
|
|
3152
|
-
* Effect.runSync(Schema.decodeEffect(NonNegative)(-5n)),
|
|
3153
|
-
* 0n,
|
|
3154
|
-
* )
|
|
3155
|
-
*
|
|
3156
|
-
* // Non-negative values pass through unchanged
|
|
3157
|
-
* assert.deepStrictEqual(
|
|
3158
|
-
* Effect.runSync(Schema.decodeEffect(NonNegative)(7n)),
|
|
3159
|
-
* 7n,
|
|
3160
|
-
* )
|
|
3161
|
-
* ```
|
|
3162
|
-
*
|
|
3163
|
-
* @category combinators
|
|
3164
|
-
* @since 0.0.0
|
|
3165
|
-
*/
|
|
3166
|
-
declare const nonNegativeBigInt: <S extends Schema.Schema<bigint>>(schema: S) => Schema.decodeTo<Schema.toType<S>, S, never, never>;
|
|
3167
|
-
/**
|
|
3168
|
-
* Extracts the "constructor input" type of a `Schema` — what `.make({...})`
|
|
3169
|
-
* accepts.
|
|
3170
|
-
*
|
|
3171
|
-
* Differs from `S["Type"]` (the decoded type) in that fields carrying
|
|
3172
|
-
* constructor defaults (e.g. an `Overrideable` timestamp) are *optional* in
|
|
3173
|
-
* `MakeIn` but *required* in `Type`. Use it in signatures that accept a value to
|
|
3174
|
-
* construct, so callers can pass a plain object literal without supplying the
|
|
3175
|
-
* defaulted, override-branded fields.
|
|
3176
|
-
*
|
|
3177
|
-
* @example
|
|
3178
|
-
* ```ts
|
|
3179
|
-
* import { Schema } from "effect"
|
|
3180
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3181
|
-
*
|
|
3182
|
-
* const Person = Schema.Struct({ name: Schema.String, age: Schema.Number })
|
|
3183
|
-
*
|
|
3184
|
-
* const input: SchemaX.MakeIn<typeof Person> = { name: "Ada", age: 36 }
|
|
3185
|
-
*
|
|
3186
|
-
* assert.deepStrictEqual(input, { name: "Ada", age: 36 })
|
|
3187
|
-
* ```
|
|
3188
|
-
*
|
|
3189
|
-
* @category models
|
|
3190
|
-
* @since 0.0.0
|
|
3191
|
-
*/
|
|
3192
|
-
type MakeIn<S extends {
|
|
3193
|
-
readonly "~type.make.in": unknown;
|
|
3194
|
-
}> = S["~type.make.in"];
|
|
3195
|
-
/**
|
|
3196
|
-
* Returns a new `Schema.Struct` containing only the named `keys` of `schema`.
|
|
3197
|
-
*
|
|
3198
|
-
* Restores the v3 ergonomics of `mySchema.pick("a", "b")` — v4 removed the
|
|
3199
|
-
* `.pick(...)` method from `Schema.Struct` instances, so this rebuilds it on top
|
|
3200
|
-
* of v4's `mapFields` primitive. Each picked field keeps its original schema,
|
|
3201
|
-
* including any refinements.
|
|
3202
|
-
*
|
|
3203
|
-
* @example
|
|
3204
|
-
* ```ts
|
|
3205
|
-
* import { Effect, Schema } from "effect"
|
|
3206
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3207
|
-
*
|
|
3208
|
-
* const Source = Schema.Struct({
|
|
3209
|
-
* a: Schema.Number,
|
|
3210
|
-
* b: Schema.String,
|
|
3211
|
-
* c: Schema.Boolean,
|
|
3212
|
-
* })
|
|
3213
|
-
*
|
|
3214
|
-
* const Picked = SchemaX.pick(Source, "a", "b")
|
|
3215
|
-
*
|
|
3216
|
-
* const decoded = Effect.runSync(
|
|
3217
|
-
* Schema.decodeEffect(Picked)({ a: 1, b: "hi" }),
|
|
3218
|
-
* )
|
|
3219
|
-
* assert.deepStrictEqual(decoded, { a: 1, b: "hi" })
|
|
3220
|
-
* ```
|
|
3221
|
-
*
|
|
3222
|
-
* @category combinators
|
|
3223
|
-
* @since 0.0.0
|
|
3224
|
-
*/
|
|
3225
|
-
declare const pick: <const Fields extends Schema.Struct.Fields, const Keys extends readonly (keyof Fields & string)[]>(schema: Schema.Struct<Fields>, ...keys: Keys) => Schema.Struct<Pick<Fields, Keys[number]>>;
|
|
3226
|
-
/**
|
|
3227
|
-
* Returns a new `Schema.Struct` with the named `keys` of `schema` removed.
|
|
3228
|
-
*
|
|
3229
|
-
* The complement of {@link pick}, restoring the v3 ergonomics of
|
|
3230
|
-
* `mySchema.omit("a")` that v4 dropped from `Schema.Struct` instances. Every
|
|
3231
|
-
* surviving field keeps its original schema, including any refinements.
|
|
3232
|
-
*
|
|
3233
|
-
* @example
|
|
3234
|
-
* ```ts
|
|
3235
|
-
* import { Effect, Schema } from "effect"
|
|
3236
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3237
|
-
*
|
|
3238
|
-
* const Source = Schema.Struct({
|
|
3239
|
-
* a: Schema.Number,
|
|
3240
|
-
* b: Schema.String,
|
|
3241
|
-
* c: Schema.Boolean,
|
|
3242
|
-
* })
|
|
3243
|
-
*
|
|
3244
|
-
* const Omitted = SchemaX.omit(Source, "c")
|
|
3245
|
-
*
|
|
3246
|
-
* const decoded = Effect.runSync(
|
|
3247
|
-
* Schema.decodeEffect(Omitted)({ a: 1, b: "hi" }),
|
|
3248
|
-
* )
|
|
3249
|
-
* assert.deepStrictEqual(decoded, { a: 1, b: "hi" })
|
|
3250
|
-
* ```
|
|
3251
|
-
*
|
|
3252
|
-
* @category combinators
|
|
3253
|
-
* @since 0.0.0
|
|
3254
|
-
*/
|
|
3255
|
-
declare const omit: <const Fields extends Schema.Struct.Fields, const Keys extends readonly (keyof Fields & string)[]>(schema: Schema.Struct<Fields>, ...keys: Keys) => Schema.Struct<Omit<Fields, Keys[number]>>;
|
|
3256
|
-
/**
|
|
3257
|
-
* Returns a new `Schema.Struct` in which every field of `schema` is made
|
|
3258
|
-
* optional.
|
|
3259
|
-
*
|
|
3260
|
-
* Restores the v3 `Schema.partial(mySchema)` behaviour that v4 removed, by
|
|
3261
|
-
* wrapping each field in `Schema.optional`. A decoded value may therefore omit
|
|
3262
|
-
* any field; fields that *are* present still have to satisfy their original
|
|
3263
|
-
* schema, refinements included.
|
|
3264
|
-
*
|
|
3265
|
-
* @example
|
|
3266
|
-
* ```ts
|
|
3267
|
-
* import { Effect, Schema } from "effect"
|
|
3268
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3269
|
-
*
|
|
3270
|
-
* const Source = Schema.Struct({ a: Schema.Number, b: Schema.String })
|
|
3271
|
-
* const Partial = SchemaX.partial(Source)
|
|
3272
|
-
*
|
|
3273
|
-
* // All fields may be absent
|
|
3274
|
-
* assert.deepStrictEqual(Effect.runSync(Schema.decodeEffect(Partial)({})), {})
|
|
3275
|
-
*
|
|
3276
|
-
* // A present subset still decodes
|
|
3277
|
-
* assert.deepStrictEqual(
|
|
3278
|
-
* Effect.runSync(Schema.decodeEffect(Partial)({ a: 1 })),
|
|
3279
|
-
* { a: 1 },
|
|
3280
|
-
* )
|
|
3281
|
-
* ```
|
|
3282
|
-
*
|
|
3283
|
-
* @category combinators
|
|
3284
|
-
* @since 0.0.0
|
|
3285
|
-
*/
|
|
3286
|
-
declare const partial: <Fields extends Schema.Struct.Fields>(schema: Schema.Struct<Fields>) => Schema.Struct<{ [K in keyof Fields]: Schema.optional<Fields[K]>; }>;
|
|
3287
|
-
/**
|
|
3288
|
-
* Returns a new `Schema.Struct` containing only the named `keys` of `schema`,
|
|
3289
|
-
* with every picked field made optional.
|
|
3290
|
-
*
|
|
3291
|
-
* Equivalent to `partial(pick(schema, ...keys))`, but reads more directly for
|
|
3292
|
-
* the common "partial update over a subset of fields" pattern: select the
|
|
3293
|
-
* mutable fields of an entity, then allow any of them to be omitted in the
|
|
3294
|
-
* update payload. Composes {@link pick} and {@link partial} in one call.
|
|
3295
|
-
*
|
|
3296
|
-
* @example
|
|
3297
|
-
* ```ts
|
|
3298
|
-
* import { Effect, Schema } from "effect"
|
|
3299
|
-
* import { SchemaX } from "@nunofyobiz/effect-extras"
|
|
3300
|
-
*
|
|
3301
|
-
* const Source = Schema.Struct({
|
|
3302
|
-
* a: Schema.Number,
|
|
3303
|
-
* b: Schema.String,
|
|
3304
|
-
* c: Schema.Boolean,
|
|
3305
|
-
* })
|
|
3306
|
-
*
|
|
3307
|
-
* const Update = SchemaX.pickPartial(Source, "a", "b")
|
|
3308
|
-
*
|
|
3309
|
-
* // Only picked fields are known, and each may be omitted
|
|
3310
|
-
* assert.deepStrictEqual(Effect.runSync(Schema.decodeEffect(Update)({})), {})
|
|
3311
|
-
* assert.deepStrictEqual(
|
|
3312
|
-
* Effect.runSync(Schema.decodeEffect(Update)({ a: 1 })),
|
|
3313
|
-
* { a: 1 },
|
|
3314
|
-
* )
|
|
3315
|
-
* ```
|
|
3316
|
-
*
|
|
3317
|
-
* @category combinators
|
|
3318
|
-
* @since 0.0.0
|
|
3319
|
-
*/
|
|
3320
|
-
declare const pickPartial: <const Fields extends Schema.Struct.Fields, const Keys extends readonly (keyof Fields & string)[]>(schema: Schema.Struct<Fields>, ...keys: Keys) => Schema.Struct<{ [K in Keys[number]]: Schema.optional<Fields[K]>; }>;
|
|
3321
|
-
|
|
3322
|
-
type SchemaX_MakeIn<S extends {
|
|
3323
|
-
readonly "~type.make.in": unknown;
|
|
3324
|
-
}> = MakeIn<S>;
|
|
3325
|
-
declare const SchemaX_TrimmedNonEmptyString: typeof TrimmedNonEmptyString;
|
|
3326
|
-
declare const SchemaX_URLSafeFilePath: typeof URLSafeFilePath;
|
|
3327
|
-
declare const SchemaX_nonNegativeBigInt: typeof nonNegativeBigInt;
|
|
3328
|
-
declare const SchemaX_omit: typeof omit;
|
|
3329
|
-
declare const SchemaX_partial: typeof partial;
|
|
3330
|
-
declare const SchemaX_pick: typeof pick;
|
|
3331
|
-
declare const SchemaX_pickPartial: typeof pickPartial;
|
|
3332
|
-
declare namespace SchemaX {
|
|
3333
|
-
export { type SchemaX_MakeIn as MakeIn, SchemaX_TrimmedNonEmptyString as TrimmedNonEmptyString, SchemaX_URLSafeFilePath as URLSafeFilePath, SchemaX_nonNegativeBigInt as nonNegativeBigInt, SchemaX_omit as omit, SchemaX_partial as partial, SchemaX_pick as pick, SchemaX_pickPartial as pickPartial };
|
|
3334
|
-
}
|
|
3335
|
-
|
|
3336
|
-
/**
|
|
3337
|
-
* Runs a mutating function against a copy of `set`, leaving the original
|
|
3338
|
-
* untouched, and returns the mutated copy.
|
|
3339
|
-
*
|
|
3340
|
-
* Use it to reuse imperative `Set` mutation code (`.add`, `.delete`) without
|
|
3341
|
-
* sacrificing immutability: the callback may freely mutate the set it receives
|
|
3342
|
-
* because it operates on a fresh clone. Supports both data-first and data-last
|
|
3343
|
-
* (pipeable) call styles.
|
|
3344
|
-
*
|
|
3345
|
-
* @example
|
|
3346
|
-
* ```ts
|
|
3347
|
-
* import { SetX } from "@nunofyobiz/effect-extras"
|
|
3348
|
-
* import { pipe } from "effect"
|
|
3349
|
-
*
|
|
3350
|
-
* const original = new Set(["a", "b"])
|
|
3351
|
-
*
|
|
3352
|
-
* const result = pipe(
|
|
3353
|
-
* original,
|
|
3354
|
-
* SetX.safelyMutate((set) => {
|
|
3355
|
-
* set.delete("a")
|
|
3356
|
-
* return set.add("c")
|
|
3357
|
-
* })
|
|
3358
|
-
* )
|
|
3359
|
-
*
|
|
3360
|
-
* assert.deepStrictEqual(result, new Set(["b", "c"]))
|
|
3361
|
-
* // The original is left intact
|
|
3362
|
-
* assert.deepStrictEqual(original, new Set(["a", "b"]))
|
|
3363
|
-
* ```
|
|
3364
|
-
*
|
|
3365
|
-
* @category combinators
|
|
3366
|
-
* @since 0.0.0
|
|
3367
|
-
*/
|
|
3368
|
-
declare const safelyMutate: (<A>(mutate: (set: Set<A>) => Set<A>) => (set: Set<A>) => Set<A>) & (<A>(set: Set<A>, mutate: (set: Set<A>) => Set<A>) => Set<A>);
|
|
3369
|
-
/**
|
|
3370
|
-
* Returns a new `Set` with `value` added, leaving the input set unchanged.
|
|
3371
|
-
*
|
|
3372
|
-
* When `value` is already present the input set is returned as-is (no copy),
|
|
3373
|
-
* making repeated adds of existing members allocation-free. Supports both
|
|
3374
|
-
* data-first and data-last (pipeable) call styles.
|
|
3375
|
-
*
|
|
3376
|
-
* @example
|
|
3377
|
-
* ```ts
|
|
3378
|
-
* import { SetX } from "@nunofyobiz/effect-extras"
|
|
3379
|
-
* import { pipe } from "effect"
|
|
3380
|
-
*
|
|
3381
|
-
* // Data-first — adds a new element into a fresh set
|
|
3382
|
-
* assert.deepStrictEqual(
|
|
3383
|
-
* SetX.add(new Set(["a", "b"]), "c"),
|
|
3384
|
-
* new Set(["a", "b", "c"])
|
|
3385
|
-
* )
|
|
3386
|
-
*
|
|
3387
|
-
* // Data-last — existing element leaves the set unchanged
|
|
3388
|
-
* assert.deepStrictEqual(
|
|
3389
|
-
* pipe(new Set(["a", "b"]), SetX.add("b")),
|
|
3390
|
-
* new Set(["a", "b"])
|
|
3391
|
-
* )
|
|
3392
|
-
* ```
|
|
3393
|
-
*
|
|
3394
|
-
* @category combinators
|
|
3395
|
-
* @since 0.0.0
|
|
3396
|
-
*/
|
|
3397
|
-
declare const add: (<A>(value: A) => (set: Set<A>) => Set<A>) & (<A>(set: Set<A>, value: A) => Set<A>);
|
|
3398
|
-
/**
|
|
3399
|
-
* Returns a new `Set` with `value` removed, leaving the input set unchanged.
|
|
3400
|
-
*
|
|
3401
|
-
* When `value` is absent the input set is returned as-is (no copy). Supports both
|
|
3402
|
-
* data-first and data-last (pipeable) call styles.
|
|
3403
|
-
*
|
|
3404
|
-
* @example
|
|
3405
|
-
* ```ts
|
|
3406
|
-
* import { SetX } from "@nunofyobiz/effect-extras"
|
|
3407
|
-
* import { pipe } from "effect"
|
|
3408
|
-
*
|
|
3409
|
-
* // Data-first — removes an existing element into a fresh set
|
|
3410
|
-
* assert.deepStrictEqual(
|
|
3411
|
-
* SetX.remove(new Set(["a", "b", "c"]), "c"),
|
|
3412
|
-
* new Set(["a", "b"])
|
|
3413
|
-
* )
|
|
3414
|
-
*
|
|
3415
|
-
* // Data-last — absent element leaves the set unchanged
|
|
3416
|
-
* assert.deepStrictEqual(
|
|
3417
|
-
* pipe(new Set(["a", "b"]), SetX.remove("z")),
|
|
3418
|
-
* new Set(["a", "b"])
|
|
3419
|
-
* )
|
|
3420
|
-
* ```
|
|
3421
|
-
*
|
|
3422
|
-
* @category combinators
|
|
3423
|
-
* @since 0.0.0
|
|
3424
|
-
*/
|
|
3425
|
-
declare const remove: (<A>(value: A) => (set: Set<A>) => Set<A>) & (<A>(set: Set<A>, value: A) => Set<A>);
|
|
3426
|
-
/**
|
|
3427
|
-
* Returns a new `Set` with `value` added if it was absent or removed if it was
|
|
3428
|
-
* present, leaving the input set unchanged.
|
|
3429
|
-
*
|
|
3430
|
-
* Use it for membership toggles (selection state, feature flags by key) where a
|
|
3431
|
-
* value's presence should flip on each call. Supports both data-first and
|
|
3432
|
-
* data-last (pipeable) call styles.
|
|
3433
|
-
*
|
|
3434
|
-
* @example
|
|
3435
|
-
* ```ts
|
|
3436
|
-
* import { SetX } from "@nunofyobiz/effect-extras"
|
|
3437
|
-
* import { pipe } from "effect"
|
|
3438
|
-
*
|
|
3439
|
-
* // Data-first — absent value gets added
|
|
3440
|
-
* assert.deepStrictEqual(
|
|
3441
|
-
* SetX.toggle(new Set(["a", "b"]), "c"),
|
|
3442
|
-
* new Set(["a", "b", "c"])
|
|
3443
|
-
* )
|
|
3444
|
-
*
|
|
3445
|
-
* // Data-last — present value gets removed
|
|
3446
|
-
* assert.deepStrictEqual(
|
|
3447
|
-
* pipe(new Set(["a", "b", "c"]), SetX.toggle("b")),
|
|
3448
|
-
* new Set(["a", "c"])
|
|
3449
|
-
* )
|
|
3450
|
-
* ```
|
|
3451
|
-
*
|
|
3452
|
-
* @category combinators
|
|
3453
|
-
* @since 0.0.0
|
|
3454
|
-
*/
|
|
3455
|
-
declare const toggle: (<A>(value: A) => (set: Set<A>) => Set<A>) & (<A>(set: Set<A>, value: A) => Set<A>);
|
|
3456
|
-
|
|
3457
|
-
declare const SetX_add: typeof add;
|
|
3458
|
-
declare const SetX_remove: typeof remove;
|
|
3459
|
-
declare const SetX_safelyMutate: typeof safelyMutate;
|
|
3460
|
-
declare const SetX_toggle: typeof toggle;
|
|
3461
|
-
declare namespace SetX {
|
|
3462
|
-
export { SetX_add as add, SetX_remove as remove, SetX_safelyMutate as safelyMutate, SetX_toggle as toggle };
|
|
3463
|
-
}
|
|
3464
|
-
|
|
3465
|
-
/**
|
|
3466
|
-
* Prepends `start` to `string_`.
|
|
3467
|
-
*
|
|
3468
|
-
* v4's `String` module has no native `prepend` (only `concat`), so this fills
|
|
3469
|
-
* the gap as a pipeable helper.
|
|
3470
|
-
*
|
|
3471
|
-
* @example
|
|
3472
|
-
* ```ts
|
|
3473
|
-
* import { pipe } from "effect"
|
|
3474
|
-
* import { StringX } from "@nunofyobiz/effect-extras"
|
|
3475
|
-
*
|
|
3476
|
-
* // data-first
|
|
3477
|
-
* assert.deepStrictEqual(StringX.prepend("world", "hello "), "hello world")
|
|
3478
|
-
*
|
|
3479
|
-
* // data-last (piped)
|
|
3480
|
-
* assert.deepStrictEqual(pipe("world", StringX.prepend("hello ")), "hello world")
|
|
3481
|
-
* ```
|
|
3482
|
-
*
|
|
3483
|
-
* @category combinators
|
|
3484
|
-
* @since 0.0.0
|
|
3485
|
-
*/
|
|
3486
|
-
declare const prepend: ((start: string) => (string_: string) => string) & ((string_: string, start: string) => string);
|
|
3487
|
-
/**
|
|
3488
|
-
* Wraps `string_` between `start` and `end`.
|
|
3489
|
-
*
|
|
3490
|
-
* No v4 native equivalent — handy for quoting, bracketing, or fencing a value.
|
|
3491
|
-
*
|
|
3492
|
-
* @example
|
|
3493
|
-
* ```ts
|
|
3494
|
-
* import { pipe } from "effect"
|
|
3495
|
-
* import { StringX } from "@nunofyobiz/effect-extras"
|
|
3496
|
-
*
|
|
3497
|
-
* // data-first
|
|
3498
|
-
* assert.deepStrictEqual(StringX.surround("value", "[", "]"), "[value]")
|
|
3499
|
-
*
|
|
3500
|
-
* // data-last (piped)
|
|
3501
|
-
* assert.deepStrictEqual(pipe("value", StringX.surround("(", ")")), "(value)")
|
|
3502
|
-
* ```
|
|
3503
|
-
*
|
|
3504
|
-
* @category combinators
|
|
3505
|
-
* @since 0.0.0
|
|
3506
|
-
*/
|
|
3507
|
-
declare const surround: ((start: string, end: string) => (string_: string) => string) & ((string_: string, start: string, end: string) => string);
|
|
3508
|
-
/**
|
|
3509
|
-
* Prepends `start` to `string_` unless `string_` already starts with it.
|
|
3510
|
-
*
|
|
3511
|
-
* Idempotent: applying it to an already-prefixed string is a no-op, so
|
|
3512
|
-
* `ensurePrepend("foofoo", "foo")` stays `"foofoo"` rather than gaining a
|
|
3513
|
-
* second `"foo"`.
|
|
3514
|
-
*
|
|
3515
|
-
* @example
|
|
3516
|
-
* ```ts
|
|
3517
|
-
* import { pipe } from "effect"
|
|
3518
|
-
* import { StringX } from "@nunofyobiz/effect-extras"
|
|
3519
|
-
*
|
|
3520
|
-
* // data-first — adds the prefix when missing
|
|
3521
|
-
* assert.deepStrictEqual(StringX.ensurePrepend("bar", "foo"), "foobar")
|
|
3522
|
-
*
|
|
3523
|
-
* // idempotent — already prefixed, returned unchanged
|
|
3524
|
-
* assert.deepStrictEqual(StringX.ensurePrepend("foobar", "foo"), "foobar")
|
|
3525
|
-
*
|
|
3526
|
-
* // data-last (piped)
|
|
3527
|
-
* assert.deepStrictEqual(pipe("bar", StringX.ensurePrepend("foo")), "foobar")
|
|
3528
|
-
* ```
|
|
3529
|
-
*
|
|
3530
|
-
* @category combinators
|
|
3531
|
-
* @since 0.0.0
|
|
3532
|
-
*/
|
|
3533
|
-
declare const ensurePrepend: ((start: string) => (string_: string) => string) & ((string_: string, start: string) => string);
|
|
3534
|
-
|
|
3535
|
-
declare const StringX_ensurePrepend: typeof ensurePrepend;
|
|
3536
|
-
declare const StringX_prepend: typeof prepend;
|
|
3537
|
-
declare const StringX_surround: typeof surround;
|
|
3538
|
-
declare namespace StringX {
|
|
3539
|
-
export { StringX_ensurePrepend as ensurePrepend, StringX_prepend as prepend, StringX_surround as surround };
|
|
3540
|
-
}
|
|
3541
|
-
|
|
3542
|
-
/**
|
|
3543
|
-
* Generic, framework-agnostic extensions to Effect's `Struct` module.
|
|
3544
|
-
*
|
|
3545
|
-
* @since 0.0.0
|
|
3546
|
-
*/
|
|
3547
|
-
|
|
3548
|
-
/**
|
|
3549
|
-
* Describes the shape of a per-field transformation over an object `O`: a record
|
|
3550
|
-
* `T` whose values are functions taking the corresponding field of `O`.
|
|
3551
|
-
*
|
|
3552
|
-
* Used to type the "evolve" pattern, where each provided key maps to a function
|
|
3553
|
-
* that receives that field's current value. Copied from Effect's internal
|
|
3554
|
-
* `Struct.evolve()` type, which is not exported — it would be better to use
|
|
3555
|
-
* theirs directly if it ever becomes public.
|
|
3556
|
-
*
|
|
3557
|
-
* @example
|
|
3558
|
-
* ```ts
|
|
3559
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3560
|
-
*
|
|
3561
|
-
* type Transform = StructX.PartialTransform<
|
|
3562
|
-
* { a: number; b: string },
|
|
3563
|
-
* { a: (n: number) => boolean }
|
|
3564
|
-
* >
|
|
3565
|
-
*
|
|
3566
|
-
* const evolve: Transform = { a: (n) => n > 0 }
|
|
3567
|
-
*
|
|
3568
|
-
* assert.deepStrictEqual(evolve.a(1), true)
|
|
3569
|
-
* ```
|
|
3570
|
-
*
|
|
3571
|
-
* @category models
|
|
3572
|
-
* @since 0.0.0
|
|
3573
|
-
*/
|
|
3574
|
-
type PartialTransform<O, T> = {
|
|
3575
|
-
[K in keyof T]: T[K] extends (a: O[K & keyof O]) => unknown ? T[K] : (a: O[K & keyof O]) => unknown;
|
|
3576
|
-
};
|
|
3577
|
-
/**
|
|
3578
|
-
* Builds a singleton record `{ [name]: value }` when `value` is defined, or an
|
|
3579
|
-
* empty object `{}` when it is `undefined` — meant to be spread into an object
|
|
3580
|
-
* literal.
|
|
3581
|
-
*
|
|
3582
|
-
* This is the canonical fix for `exactOptionalPropertyTypes: true` (which this
|
|
3583
|
-
* repo enables for Effect Schema). Under that flag, spreading
|
|
3584
|
-
* `{ key: maybeUndefined }` into an object whose key is `key?: T` is a type
|
|
3585
|
-
* error: the property must be *absent*, not present-but-`undefined`. Spreading
|
|
3586
|
-
* `...defined("key", maybeUndefined)` instead conditionally omits the property
|
|
3587
|
-
* altogether. Note that `null` and other falsy-but-defined values (`0`, `""`,
|
|
3588
|
-
* `false`) are kept — only `undefined` is dropped.
|
|
3589
|
-
*
|
|
3590
|
-
* @example
|
|
3591
|
-
* ```ts
|
|
3592
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3593
|
-
*
|
|
3594
|
-
* // Defined value → singleton record
|
|
3595
|
-
* assert.deepStrictEqual(StructX.defined("name", "Ada"), { name: "Ada" })
|
|
3596
|
-
*
|
|
3597
|
-
* // undefined → property omitted entirely
|
|
3598
|
-
* assert.deepStrictEqual(StructX.defined("name", undefined), {})
|
|
3599
|
-
*
|
|
3600
|
-
* // Falsy-but-defined values are kept
|
|
3601
|
-
* assert.deepStrictEqual(StructX.defined("name", 0), { name: 0 })
|
|
3602
|
-
*
|
|
3603
|
-
* // Typical use: spread to conditionally include an optional field
|
|
3604
|
-
* const maybeAge: number | undefined = undefined
|
|
3605
|
-
* assert.deepStrictEqual({ id: 1, ...StructX.defined("age", maybeAge) }, {
|
|
3606
|
-
* id: 1,
|
|
3607
|
-
* })
|
|
3608
|
-
* ```
|
|
3609
|
-
*
|
|
3610
|
-
* @category constructors
|
|
3611
|
-
* @since 0.0.0
|
|
3612
|
-
*/
|
|
3613
|
-
declare const defined: <const K extends string, V>(name: K, value: V | undefined) => Partial<Record<K, Exclude<V, undefined>>>;
|
|
3614
|
-
/**
|
|
3615
|
-
* Removes every property whose value is `undefined` from `record`, narrowing
|
|
3616
|
-
* each remaining property type to exclude `undefined`.
|
|
3617
|
-
*
|
|
3618
|
-
* The bulk counterpart of {@link defined}: instead of building one optional
|
|
3619
|
-
* field, it filters a whole object. Very useful for update/patch actions where
|
|
3620
|
-
* `undefined` means "leave this field unchanged" while every other value —
|
|
3621
|
-
* including `null`, `0`, `""`, `false`, and `Option.none()` — means "set the
|
|
3622
|
-
* field to exactly this".
|
|
3623
|
-
*
|
|
3624
|
-
* @example
|
|
3625
|
-
* ```ts
|
|
3626
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3627
|
-
*
|
|
3628
|
-
* // Drops `b` (undefined) but keeps every other value, including null/0/false
|
|
3629
|
-
* assert.deepStrictEqual(
|
|
3630
|
-
* StructX.filterDefined({ a: "x", b: undefined, c: 0, d: null, e: false }),
|
|
3631
|
-
* { a: "x", c: 0, d: null, e: false },
|
|
3632
|
-
* )
|
|
3633
|
-
* ```
|
|
3634
|
-
*
|
|
3635
|
-
* @category filtering
|
|
3636
|
-
* @since 0.0.0
|
|
3637
|
-
*/
|
|
3638
|
-
declare const filterDefined: <R extends Record<string, unknown>>(record: R) => Partial<{ [P in keyof R]: Exclude<R[P], undefined>; }>;
|
|
3639
|
-
/**
|
|
3640
|
-
* Builds a singleton record `{ [name]: value }` when `value` is `Some`, or an
|
|
3641
|
-
* empty object `{}` when it is `None` — meant to be spread into an object
|
|
3642
|
-
* literal.
|
|
3643
|
-
*
|
|
3644
|
-
* The `Option`-valued sibling of {@link defined}: where `defined` keys off
|
|
3645
|
-
* `undefined`, this keys off `Option` presence. Spread `...some("key", opt)` to
|
|
3646
|
-
* conditionally include a field only when the `Option` carries a value, which
|
|
3647
|
-
* stays correct under `exactOptionalPropertyTypes: true`.
|
|
3648
|
-
*
|
|
3649
|
-
* @example
|
|
3650
|
-
* ```ts
|
|
3651
|
-
* import { Option } from "effect"
|
|
3652
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3653
|
-
*
|
|
3654
|
-
* // Some → singleton record
|
|
3655
|
-
* assert.deepStrictEqual(StructX.some("name", Option.some("Ada")), {
|
|
3656
|
-
* name: "Ada",
|
|
3657
|
-
* })
|
|
3658
|
-
*
|
|
3659
|
-
* // None → property omitted entirely
|
|
3660
|
-
* assert.deepStrictEqual(StructX.some("name", Option.none()), {})
|
|
3661
|
-
* ```
|
|
3662
|
-
*
|
|
3663
|
-
* @category constructors
|
|
3664
|
-
* @since 0.0.0
|
|
3665
|
-
*/
|
|
3666
|
-
declare const some: <const K extends string, V>(name: K, value: Option.Option<V>) => Partial<Record<K, V>>;
|
|
3667
|
-
/**
|
|
3668
|
-
* Looks up `key` in a record of `Option` values and returns a singleton record
|
|
3669
|
-
* when the value is `Some`, or `{}` when the key is absent or its value is
|
|
3670
|
-
* `None`.
|
|
3671
|
-
*
|
|
3672
|
-
* Combines `Record.get` + `Option.flatten` + a singleton builder in one call —
|
|
3673
|
-
* ideal for spreading an optional field out of a lookup table into an object
|
|
3674
|
-
* literal under `exactOptionalPropertyTypes: true`. By default the output key
|
|
3675
|
-
* matches the lookup key; pass `renameKeyTo` to emit the value under a different
|
|
3676
|
-
* name.
|
|
3677
|
-
*
|
|
3678
|
-
* @example
|
|
3679
|
-
* ```ts
|
|
3680
|
-
* import { Option } from "effect"
|
|
3681
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3682
|
-
*
|
|
3683
|
-
* const lookup = {
|
|
3684
|
-
* a: Option.some(100),
|
|
3685
|
-
* b: Option.none<number>(),
|
|
3686
|
-
* }
|
|
3687
|
-
*
|
|
3688
|
-
* // Some → singleton record under the same key
|
|
3689
|
-
* assert.deepStrictEqual(StructX.pickSome(lookup, "a"), { a: 100 })
|
|
3690
|
-
*
|
|
3691
|
-
* // None → property omitted entirely
|
|
3692
|
-
* assert.deepStrictEqual(StructX.pickSome(lookup, "b"), {})
|
|
3693
|
-
*
|
|
3694
|
-
* // Rename the output key
|
|
3695
|
-
* assert.deepStrictEqual(StructX.pickSome(lookup, "a", "count"), { count: 100 })
|
|
3696
|
-
* ```
|
|
3697
|
-
*
|
|
3698
|
-
* @category constructors
|
|
3699
|
-
* @since 0.0.0
|
|
3700
|
-
*/
|
|
3701
|
-
declare function pickSome<const K extends string, V>(record: Record<K, Option.Option<V>>, key: K): Partial<Record<K, V>>;
|
|
3702
|
-
declare function pickSome<const K1 extends string, V, const K2 extends string>(record: Record<K1, Option.Option<V>>, key: K1, renameKeyTo: K2): Partial<Record<K2, V>>;
|
|
3703
|
-
/**
|
|
3704
|
-
* Builds a singleton record `{ [name]: value }` when `value` is truthy, or an
|
|
3705
|
-
* empty object `{}` otherwise — meant to be spread into an object literal.
|
|
3706
|
-
*
|
|
3707
|
-
* Stricter than {@link defined}: it drops not just `undefined` but every falsy
|
|
3708
|
-
* value (`null`, `false`, `0`, `""`, `NaN`), and narrows the value type
|
|
3709
|
-
* accordingly. Use it to spread a field only when it carries a meaningful,
|
|
3710
|
-
* non-falsy value.
|
|
3711
|
-
*
|
|
3712
|
-
* @example
|
|
3713
|
-
* ```ts
|
|
3714
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3715
|
-
*
|
|
3716
|
-
* // Truthy value → singleton record
|
|
3717
|
-
* assert.deepStrictEqual(StructX.truthy("name", "Ada"), { name: "Ada" })
|
|
3718
|
-
*
|
|
3719
|
-
* // Falsy values → property omitted entirely
|
|
3720
|
-
* assert.deepStrictEqual(StructX.truthy("name", ""), {})
|
|
3721
|
-
* assert.deepStrictEqual(StructX.truthy("name", 0), {})
|
|
3722
|
-
* assert.deepStrictEqual(StructX.truthy("name", false), {})
|
|
3723
|
-
* ```
|
|
3724
|
-
*
|
|
3725
|
-
* @category constructors
|
|
3726
|
-
* @since 0.0.0
|
|
3727
|
-
*/
|
|
3728
|
-
declare const truthy: <const K extends string, V>(name: K, value: V) => Partial<Record<K, Exclude<NonNullable<V>, false | 0 | "">>>;
|
|
3729
|
-
/**
|
|
3730
|
-
* Returns `true` when `object` has `key` set to a non-nullish value, narrowing
|
|
3731
|
-
* that property to `NonNullable` on the type level.
|
|
3732
|
-
*
|
|
3733
|
-
* A type guard combining `hasProperty` with a nullish check: after a successful
|
|
3734
|
-
* test, TypeScript treats `object[key]` as present and free of `null` /
|
|
3735
|
-
* `undefined`. Handy as a predicate passed to `Array.filter` to keep only the
|
|
3736
|
-
* elements whose `key` is populated.
|
|
3737
|
-
*
|
|
3738
|
-
* @example
|
|
3739
|
-
* ```ts
|
|
3740
|
-
* import { pipe } from "effect"
|
|
3741
|
-
* import { StructX } from "@nunofyobiz/effect-extras"
|
|
3742
|
-
*
|
|
3743
|
-
* // data-first
|
|
3744
|
-
* assert.deepStrictEqual(
|
|
3745
|
-
* StructX.hasNotNullableProperty({ id: "1" }, "id"),
|
|
3746
|
-
* true,
|
|
3747
|
-
* )
|
|
3748
|
-
*
|
|
3749
|
-
* // data-last (pipeable); a null value fails the guard
|
|
3750
|
-
* assert.deepStrictEqual(
|
|
3751
|
-
* pipe({ id: null }, StructX.hasNotNullableProperty("id")),
|
|
3752
|
-
* false,
|
|
3753
|
-
* )
|
|
3754
|
-
* ```
|
|
3755
|
-
*
|
|
3756
|
-
* @category refinements
|
|
3757
|
-
* @since 0.0.0
|
|
3758
|
-
*/
|
|
3759
|
-
declare const hasNotNullableProperty: (<T, K extends keyof T>(key: K) => (object: T) => object is T & Record<K, NonNullable<T[K]>>) & (<T, K extends keyof T>(object: T, key: K) => object is T & Record<K, NonNullable<T[K]>>);
|
|
3760
|
-
|
|
3761
|
-
type StructX_PartialTransform<O, T> = PartialTransform<O, T>;
|
|
3762
|
-
declare const StructX_defined: typeof defined;
|
|
3763
|
-
declare const StructX_filterDefined: typeof filterDefined;
|
|
3764
|
-
declare const StructX_hasNotNullableProperty: typeof hasNotNullableProperty;
|
|
3765
|
-
declare const StructX_pickSome: typeof pickSome;
|
|
3766
|
-
declare const StructX_some: typeof some;
|
|
3767
|
-
declare const StructX_truthy: typeof truthy;
|
|
3768
|
-
declare namespace StructX {
|
|
3769
|
-
export { type StructX_PartialTransform as PartialTransform, StructX_defined as defined, StructX_filterDefined as filterDefined, StructX_hasNotNullableProperty as hasNotNullableProperty, StructX_pickSome as pickSome, StructX_some as some, StructX_truthy as truthy };
|
|
3770
|
-
}
|
|
3771
|
-
|
|
3772
|
-
export { ArrayX, BigIntX, BooleanX, DurationX, EffectX, FormDataX, MapX, NonNullableX, NumberX, OptionX, OrderX, PredicateX, PromiseX, RecordX, ResultX, SchemaX, SetX, StringX, StructX, WarnResult$1 as WarnResult, fromNullableOrThrow as nn };
|
|
1
|
+
export * as ArrayX from "./ArrayX.js";
|
|
2
|
+
export * as BigIntX from "./BigIntX.js";
|
|
3
|
+
export * as BooleanX from "./BooleanX.js";
|
|
4
|
+
export * as DurationX from "./DurationX.js";
|
|
5
|
+
export * as EffectX from "./EffectX.js";
|
|
6
|
+
export * as FormDataX from "./FormDataX.js";
|
|
7
|
+
export * as InclusiveOr from "./InclusiveOr.js";
|
|
8
|
+
export * as MapX from "./MapX.js";
|
|
9
|
+
export * as NonNullableX from "./NonNullableX.js";
|
|
10
|
+
export { fromNullableOrThrow as nn } from "./NonNullableX.js";
|
|
11
|
+
export * as NumberX from "./NumberX.js";
|
|
12
|
+
export * as OptionX from "./OptionX.js";
|
|
13
|
+
export * as OrderX from "./OrderX.js";
|
|
14
|
+
export * as PredicateX from "./PredicateX.js";
|
|
15
|
+
export * as PromiseX from "./PromiseX.js";
|
|
16
|
+
export * as RecordX from "./RecordX.js";
|
|
17
|
+
export * as ResultX from "./ResultX.js";
|
|
18
|
+
export * as SchemaX from "./SchemaX.js";
|
|
19
|
+
export * as SetX from "./SetX.js";
|
|
20
|
+
export * as StringX from "./StringX.js";
|
|
21
|
+
export * as StructX from "./StructX.js";
|
|
22
|
+
export * as WarnResult from "./WarnResult.js";
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|