@nunofyobiz/effect-extras 1.0.0 → 2.1.0

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