@nunofyobiz/effect-extras 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +38 -3
  2. package/dist/ArrayX.d.ts +381 -0
  3. package/dist/ArrayX.d.ts.map +1 -0
  4. package/dist/ArrayX.js +493 -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/InclusiveOr.d.ts +1123 -0
  27. package/dist/InclusiveOr.d.ts.map +1 -0
  28. package/dist/InclusiveOr.js +1074 -0
  29. package/dist/InclusiveOr.js.map +1 -0
  30. package/dist/MapX.d.ts +32 -0
  31. package/dist/MapX.d.ts.map +1 -0
  32. package/dist/MapX.js +49 -0
  33. package/dist/MapX.js.map +1 -0
  34. package/dist/NonNullableX.d.ts +174 -0
  35. package/dist/NonNullableX.d.ts.map +1 -0
  36. package/dist/NonNullableX.js +217 -0
  37. package/dist/NonNullableX.js.map +1 -0
  38. package/dist/NumberX.d.ts +178 -0
  39. package/dist/NumberX.d.ts.map +1 -0
  40. package/dist/NumberX.js +214 -0
  41. package/dist/NumberX.js.map +1 -0
  42. package/dist/OptionX.d.ts +187 -0
  43. package/dist/OptionX.d.ts.map +1 -0
  44. package/dist/OptionX.js +201 -0
  45. package/dist/OptionX.js.map +1 -0
  46. package/dist/OrderX.d.ts +32 -0
  47. package/dist/OrderX.d.ts.map +1 -0
  48. package/dist/OrderX.js +32 -0
  49. package/dist/OrderX.js.map +1 -0
  50. package/dist/PredicateX.d.ts +108 -0
  51. package/dist/PredicateX.d.ts.map +1 -0
  52. package/dist/PredicateX.js +111 -0
  53. package/dist/PredicateX.js.map +1 -0
  54. package/dist/PromiseX.d.ts +32 -0
  55. package/dist/PromiseX.d.ts.map +1 -0
  56. package/dist/PromiseX.js +32 -0
  57. package/dist/PromiseX.js.map +1 -0
  58. package/dist/RecordX.d.ts +450 -0
  59. package/dist/RecordX.d.ts.map +1 -0
  60. package/dist/RecordX.js +487 -0
  61. package/dist/RecordX.js.map +1 -0
  62. package/dist/ResultX.d.ts +50 -0
  63. package/dist/ResultX.d.ts.map +1 -0
  64. package/dist/ResultX.js +50 -0
  65. package/dist/ResultX.js.map +1 -0
  66. package/dist/SchemaX.d.ts +249 -0
  67. package/dist/SchemaX.d.ts.map +1 -0
  68. package/dist/SchemaX.js +243 -0
  69. package/dist/SchemaX.js.map +1 -0
  70. package/dist/SetX.d.ts +121 -0
  71. package/dist/SetX.d.ts.map +1 -0
  72. package/dist/SetX.js +137 -0
  73. package/dist/SetX.js.map +1 -0
  74. package/dist/StringX.d.ts +131 -0
  75. package/dist/StringX.d.ts.map +1 -0
  76. package/dist/StringX.js +149 -0
  77. package/dist/StringX.js.map +1 -0
  78. package/dist/StructX.d.ts +219 -0
  79. package/dist/StructX.d.ts.map +1 -0
  80. package/dist/StructX.js +173 -0
  81. package/dist/StructX.js.map +1 -0
  82. package/dist/WarnResult.d.ts +1191 -0
  83. package/dist/WarnResult.d.ts.map +1 -0
  84. package/dist/WarnResult.js +991 -0
  85. package/dist/WarnResult.js.map +1 -0
  86. package/dist/index.d.ts +23 -3772
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +22 -1011
  89. package/dist/index.js.map +1 -1
  90. package/package.json +18 -5
  91. package/src/{ArrayX/ArrayX.ts → ArrayX.ts} +6 -88
  92. package/src/{DurationX/DurationX.ts → DurationX.ts} +1 -1
  93. package/src/InclusiveOr.ts +1255 -0
  94. package/src/{NonNullableX/NonNullableX.ts → NonNullableX.ts} +5 -0
  95. package/src/{OptionX/OptionX.ts → OptionX.ts} +8 -2
  96. package/src/{PredicateX/PredicateX.ts → PredicateX.ts} +41 -0
  97. package/src/{RecordX/RecordX.ts → RecordX.ts} +184 -2
  98. package/src/StringX.ts +210 -0
  99. package/src/{WarnResult/WarnResult.ts → WarnResult.ts} +297 -227
  100. package/src/index.ts +22 -20
  101. package/src/ArrayX/index.ts +0 -1
  102. package/src/BigIntX/index.ts +0 -1
  103. package/src/BooleanX/index.ts +0 -1
  104. package/src/DurationX/index.ts +0 -1
  105. package/src/EffectX/index.ts +0 -1
  106. package/src/FormDataX/index.ts +0 -1
  107. package/src/MapX/index.ts +0 -1
  108. package/src/NonNullableX/index.ts +0 -2
  109. package/src/NumberX/index.ts +0 -1
  110. package/src/OptionX/index.ts +0 -1
  111. package/src/OrderX/index.ts +0 -1
  112. package/src/PredicateX/index.ts +0 -1
  113. package/src/PromiseX/index.ts +0 -1
  114. package/src/RecordX/index.ts +0 -1
  115. package/src/ResultX/index.ts +0 -1
  116. package/src/SchemaX/index.ts +0 -1
  117. package/src/SetX/index.ts +0 -1
  118. package/src/StringX/StringX.ts +0 -97
  119. package/src/StringX/index.ts +0 -1
  120. package/src/StructX/index.ts +0 -1
  121. package/src/WarnResult/index.ts +0 -1
  122. /package/src/{BigIntX/BigIntX.ts → BigIntX.ts} +0 -0
  123. /package/src/{BooleanX/BooleanX.ts → BooleanX.ts} +0 -0
  124. /package/src/{EffectX/EffectX.ts → EffectX.ts} +0 -0
  125. /package/src/{FormDataX/FormDataX.ts → FormDataX.ts} +0 -0
  126. /package/src/{MapX/MapX.ts → MapX.ts} +0 -0
  127. /package/src/{NumberX/NumberX.ts → NumberX.ts} +0 -0
  128. /package/src/{OrderX/OrderX.ts → OrderX.ts} +0 -0
  129. /package/src/{PromiseX/PromiseX.ts → PromiseX.ts} +0 -0
  130. /package/src/{ResultX/ResultX.ts → ResultX.ts} +0 -0
  131. /package/src/{SchemaX/SchemaX.ts → SchemaX.ts} +0 -0
  132. /package/src/{SetX/SetX.ts → SetX.ts} +0 -0
  133. /package/src/{StructX/StructX.ts → StructX.ts} +0 -0
@@ -0,0 +1,991 @@
1
+ /**
2
+ * The `WarnResult` data type — a result that may carry a success value and/or
3
+ * warnings, where both sides are optional but never both absent.
4
+ *
5
+ * @since 0.0.0
6
+ */
7
+ import { Data, Effect, Option, pipe } from "effect";
8
+ import { dual } from "effect/Function";
9
+ import * as InclusiveOr from "./InclusiveOr.js";
10
+ const taggedEnum = /*#__PURE__*/Data.taggedEnum();
11
+ /**
12
+ * Constructs a `WarningsOnly` — a `WarnResult` that carries only `warnings`.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
17
+ *
18
+ * const value = WarnResult.WarningsOnly({ warnings: "skipped 2 rows" })
19
+ *
20
+ * assert.deepStrictEqual(value._tag, "WarningsOnly")
21
+ * assert.deepStrictEqual(value.warnings, "skipped 2 rows")
22
+ * ```
23
+ *
24
+ * @category constructors
25
+ * @since 0.0.0
26
+ */
27
+ export const WarningsOnly = taggedEnum.WarningsOnly;
28
+ /**
29
+ * Constructs a `SuccessOnly` — a `WarnResult` that carries only a `success` value.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
34
+ *
35
+ * const value = WarnResult.SuccessOnly({ success: 1 })
36
+ *
37
+ * assert.deepStrictEqual(value._tag, "SuccessOnly")
38
+ * assert.deepStrictEqual(value.success, 1)
39
+ * ```
40
+ *
41
+ * @category constructors
42
+ * @since 0.0.0
43
+ */
44
+ export const SuccessOnly = taggedEnum.SuccessOnly;
45
+ /**
46
+ * Constructs a `SuccessWithWarnings` — a `WarnResult` that carries both a
47
+ * `success` value and `warnings`.
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
52
+ *
53
+ * const value = WarnResult.SuccessWithWarnings({
54
+ * warnings: "rounded down",
55
+ * success: 1
56
+ * })
57
+ *
58
+ * assert.deepStrictEqual(value._tag, "SuccessWithWarnings")
59
+ * assert.deepStrictEqual(value.warnings, "rounded down")
60
+ * assert.deepStrictEqual(value.success, 1)
61
+ * ```
62
+ *
63
+ * @category constructors
64
+ * @since 0.0.0
65
+ */
66
+ export const SuccessWithWarnings = taggedEnum.SuccessWithWarnings;
67
+ /**
68
+ * Builds per-tag refinements for `WarnResult`. `is("WarningsOnly")` is a type
69
+ * guard that narrows a `WarnResult` to its `WarningsOnly` member, and likewise for
70
+ * `"SuccessOnly"` and `"SuccessWithWarnings"`.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
75
+ *
76
+ * assert.deepStrictEqual(
77
+ * WarnResult.is("WarningsOnly")(WarnResult.WarningsOnly({ warnings: "w" })),
78
+ * true
79
+ * )
80
+ * assert.deepStrictEqual(
81
+ * WarnResult.is("WarningsOnly")(WarnResult.SuccessOnly({ success: 1 })),
82
+ * false
83
+ * )
84
+ * ```
85
+ *
86
+ * @category guards
87
+ * @since 0.0.0
88
+ */
89
+ export const is = taggedEnum.$is;
90
+ /**
91
+ * Folds a `WarnResult` over its three tags. Provide a handler for `WarningsOnly`,
92
+ * `SuccessOnly`, and `SuccessWithWarnings` and `match` returns a function from a
93
+ * `WarnResult` to the handlers' common result type.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
98
+ *
99
+ * const describe = WarnResult.match({
100
+ * WarningsOnly: ({ warnings }) => `warnings ${warnings}`,
101
+ * SuccessOnly: ({ success }) => `success ${success}`,
102
+ * SuccessWithWarnings: ({ warnings, success }) => `both ${warnings}/${success}`
103
+ * })
104
+ *
105
+ * assert.deepStrictEqual(
106
+ * describe(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
107
+ * "both w/1"
108
+ * )
109
+ * ```
110
+ *
111
+ * @category pattern matching
112
+ * @since 0.0.0
113
+ */
114
+ export const match = taggedEnum.$match;
115
+ /**
116
+ * Relabels a `WarnResult` as the equivalent terminology-free `InclusiveOr`,
117
+ * mapping `warnings` to `left` and `success` to `right`. The inverse of
118
+ * `fromInclusiveOr`.
119
+ *
120
+ * `WarnResult` is the use-case-driven (`warnings`/`success`) face of the generic
121
+ * `InclusiveOr` (`left`/`right`); every derived `WarnResult` operation is just this
122
+ * relabeling around the corresponding `InclusiveOr` operation, so all the logic
123
+ * lives in `InclusiveOr` and is never duplicated here.
124
+ */
125
+ const toInclusiveOr = warnResult => match(warnResult, {
126
+ WarningsOnly: ({
127
+ warnings
128
+ }) => InclusiveOr.LeftOnly({
129
+ left: warnings
130
+ }),
131
+ SuccessOnly: ({
132
+ success
133
+ }) => InclusiveOr.RightOnly({
134
+ right: success
135
+ }),
136
+ SuccessWithWarnings: ({
137
+ warnings,
138
+ success
139
+ }) => InclusiveOr.LeftAndRight({
140
+ left: warnings,
141
+ right: success
142
+ })
143
+ });
144
+ function fromInclusiveOr(io) {
145
+ return InclusiveOr.match(io, {
146
+ LeftOnly: ({
147
+ left
148
+ }) => WarningsOnly({
149
+ warnings: left
150
+ }),
151
+ RightOnly: ({
152
+ right
153
+ }) => SuccessOnly({
154
+ success: right
155
+ }),
156
+ LeftAndRight: ({
157
+ left,
158
+ right
159
+ }) => SuccessWithWarnings({
160
+ warnings: left,
161
+ success: right
162
+ })
163
+ });
164
+ }
165
+ /**
166
+ * Builds a `WarnResult` known to carry `warnings`, choosing `SuccessWithWarnings`
167
+ * when a `success` value is present and `WarningsOnly` otherwise.
168
+ *
169
+ * Use it when the `warnings` are mandatory and the `success` value is an optional
170
+ * companion: pass an absent (`null`/`undefined`) `success` to get a
171
+ * `WarningsOnly`, or a present one to get a `SuccessWithWarnings`. The return type
172
+ * `WithWarnings<A, W>` reflects that `warnings` are always present.
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
177
+ *
178
+ * assert.deepStrictEqual(
179
+ * WarnResult.WithWarnings({ warnings: "w", success: 1 }),
180
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
181
+ * )
182
+ *
183
+ * assert.deepStrictEqual(
184
+ * WarnResult.WithWarnings({ warnings: "w" }),
185
+ * WarnResult.WarningsOnly({ warnings: "w" })
186
+ * )
187
+ * ```
188
+ *
189
+ * @category constructors
190
+ * @since 0.0.0
191
+ */
192
+ export const WithWarnings = ({
193
+ warnings,
194
+ success
195
+ }) => fromInclusiveOr(InclusiveOr.WithLeft({
196
+ left: warnings,
197
+ right: success
198
+ }));
199
+ /**
200
+ * Builds a `WarnResult` known to carry a `success` value, choosing
201
+ * `SuccessWithWarnings` when `warnings` are present and `SuccessOnly` otherwise.
202
+ *
203
+ * The mirror of `WithWarnings`: the `success` value is mandatory and the
204
+ * `warnings` are an optional companion. Pass absent (`null`/`undefined`)
205
+ * `warnings` to get a `SuccessOnly`, or present ones to get a
206
+ * `SuccessWithWarnings`. The return type `WithSuccess<A, W>` reflects that a
207
+ * `success` value is always present.
208
+ *
209
+ * @example
210
+ * ```ts
211
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
212
+ *
213
+ * assert.deepStrictEqual(
214
+ * WarnResult.WithSuccess({ warnings: "w", success: 1 }),
215
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
216
+ * )
217
+ *
218
+ * assert.deepStrictEqual(
219
+ * WarnResult.WithSuccess({ success: 1 }),
220
+ * WarnResult.SuccessOnly({ success: 1 })
221
+ * )
222
+ * ```
223
+ *
224
+ * @category constructors
225
+ * @since 0.0.0
226
+ */
227
+ export const WithSuccess = ({
228
+ warnings,
229
+ success
230
+ }) => fromInclusiveOr(InclusiveOr.WithRight({
231
+ left: warnings,
232
+ right: success
233
+ }));
234
+ /**
235
+ * Builds a `WarnResult` from a pair of possibly-nullish inputs, wrapping the
236
+ * result in an `Option` so the all-absent case is expressible.
237
+ *
238
+ * Returns `Option.some(SuccessWithWarnings)` when both are present,
239
+ * `Option.some(WarningsOnly)` or `Option.some(SuccessOnly)` when exactly one is
240
+ * present, and `Option.none()` when both are nullish. Use it as the total entry
241
+ * point for turning an optional success value and optional warnings into a
242
+ * `WarnResult`.
243
+ *
244
+ * @example
245
+ * ```ts
246
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
247
+ * import { Option } from "effect"
248
+ *
249
+ * assert.deepStrictEqual(
250
+ * WarnResult.optionFromNullables({ warnings: "w", success: 1 }),
251
+ * Option.some(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
252
+ * )
253
+ *
254
+ * assert.deepStrictEqual(
255
+ * WarnResult.optionFromNullables({ warnings: "w", success: null }),
256
+ * Option.some(WarnResult.WarningsOnly({ warnings: "w" }))
257
+ * )
258
+ *
259
+ * assert.deepStrictEqual(
260
+ * WarnResult.optionFromNullables({ warnings: null, success: undefined }),
261
+ * Option.none()
262
+ * )
263
+ * ```
264
+ *
265
+ * @category constructors
266
+ * @since 0.0.0
267
+ */
268
+ export const optionFromNullables = ({
269
+ warnings,
270
+ success
271
+ }) => Option.map(InclusiveOr.optionFromNullables({
272
+ left: warnings,
273
+ right: success
274
+ }), io => fromInclusiveOr(io));
275
+ /**
276
+ * Builds a `WarnResult` from a pair of possibly-nullish inputs, falling back to
277
+ * the `orElse` thunk when both are absent.
278
+ *
279
+ * The non-optional companion to `optionFromNullables`: it unwraps the same logic
280
+ * but resolves the all-absent case with `orElse` instead of an `Option`. The
281
+ * default `orElse` throws, so omit it only when at least one side is guaranteed
282
+ * present.
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
287
+ *
288
+ * assert.deepStrictEqual(
289
+ * WarnResult.fromNullables({ warnings: "w", success: 1 }),
290
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })
291
+ * )
292
+ *
293
+ * // Both absent — fall back via orElse instead of throwing
294
+ * assert.deepStrictEqual(
295
+ * WarnResult.fromNullables({
296
+ * warnings: null,
297
+ * success: null,
298
+ * orElse: () => WarnResult.WarningsOnly({ warnings: "none" })
299
+ * }),
300
+ * WarnResult.WarningsOnly({ warnings: "none" })
301
+ * )
302
+ * ```
303
+ *
304
+ * @category constructors
305
+ * @since 0.0.0
306
+ */
307
+ export const fromNullables = ({
308
+ warnings,
309
+ success,
310
+ orElse = () => {
311
+ throw new Error("Both warnings and success are nullish");
312
+ }
313
+ }) => pipe(optionFromNullables({
314
+ warnings,
315
+ success
316
+ }), Option.getOrElse(orElse));
317
+ /**
318
+ * Folds a `WarnResult` from the warnings' perspective, collapsing the three tags
319
+ * into two handlers.
320
+ *
321
+ * Both `WarningsOnly` and `SuccessWithWarnings` carry `warnings`, so they route to
322
+ * the `Warnings` handler; only `SuccessOnly` lacks `warnings` and routes to
323
+ * `SuccessOnly`. Use it when you care about the `warnings` and treat the
324
+ * success-only case as the exception.
325
+ *
326
+ * @example
327
+ * ```ts
328
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
329
+ *
330
+ * const onWarnings = WarnResult.matchWarnings({
331
+ * Warnings: (warnings: string) => `warnings ${warnings}`,
332
+ * SuccessOnly: (success: number) => `success ${success}`
333
+ * })
334
+ *
335
+ * assert.deepStrictEqual(
336
+ * onWarnings(WarnResult.WarningsOnly({ warnings: "w" })),
337
+ * "warnings w"
338
+ * )
339
+ * assert.deepStrictEqual(
340
+ * onWarnings(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
341
+ * "warnings w"
342
+ * )
343
+ * assert.deepStrictEqual(
344
+ * onWarnings(WarnResult.SuccessOnly({ success: 1 })),
345
+ * "success 1"
346
+ * )
347
+ * ```
348
+ *
349
+ * @category pattern matching
350
+ * @since 0.0.0
351
+ */
352
+ export const matchWarnings = ({
353
+ Warnings,
354
+ SuccessOnly
355
+ }) => warnResult => InclusiveOr.matchLeft({
356
+ Left: Warnings,
357
+ RightOnly: SuccessOnly
358
+ })(toInclusiveOr(warnResult));
359
+ /**
360
+ * Folds a `WarnResult` from the success value's perspective, collapsing the three
361
+ * tags into two handlers.
362
+ *
363
+ * The mirror of `matchWarnings`: both `SuccessOnly` and `SuccessWithWarnings`
364
+ * carry a `success` value, so they route to the `Success` handler; only
365
+ * `WarningsOnly` lacks a `success` value and routes to `WarningsOnly`. Use it when
366
+ * you care about the `success` value and treat the warnings-only case as the
367
+ * exception.
368
+ *
369
+ * @example
370
+ * ```ts
371
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
372
+ *
373
+ * const onSuccess = WarnResult.matchSuccess({
374
+ * WarningsOnly: (warnings: string) => `warnings ${warnings}`,
375
+ * Success: (success: number) => `success ${success}`
376
+ * })
377
+ *
378
+ * assert.deepStrictEqual(
379
+ * onSuccess(WarnResult.SuccessOnly({ success: 1 })),
380
+ * "success 1"
381
+ * )
382
+ * assert.deepStrictEqual(
383
+ * onSuccess(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
384
+ * "success 1"
385
+ * )
386
+ * assert.deepStrictEqual(
387
+ * onSuccess(WarnResult.WarningsOnly({ warnings: "w" })),
388
+ * "warnings w"
389
+ * )
390
+ * ```
391
+ *
392
+ * @category pattern matching
393
+ * @since 0.0.0
394
+ */
395
+ export const matchSuccess = ({
396
+ WarningsOnly,
397
+ Success
398
+ }) => warnResult => InclusiveOr.matchRight({
399
+ LeftOnly: WarningsOnly,
400
+ Right: Success
401
+ })(toInclusiveOr(warnResult));
402
+ /**
403
+ * Completes a `WarnResult` into a guaranteed `SuccessWithWarnings` by filling
404
+ * whichever side is missing from the matching `orElse` thunk.
405
+ *
406
+ * A `SuccessWithWarnings` passes through unchanged; a `WarningsOnly` gains a
407
+ * `success` value from `orElseSuccess`; a `SuccessOnly` gains `warnings` from
408
+ * `orElseWarnings`. Use it to normalise a partial `WarnResult` into the
409
+ * both-present shape before reading both sides.
410
+ *
411
+ * @example
412
+ * ```ts
413
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
414
+ *
415
+ * const fill = WarnResult.orElse({
416
+ * orElseWarnings: () => "no warnings",
417
+ * orElseSuccess: () => 0
418
+ * })
419
+ *
420
+ * assert.deepStrictEqual(
421
+ * fill(WarnResult.WarningsOnly({ warnings: "w" })),
422
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 0 })
423
+ * )
424
+ * assert.deepStrictEqual(
425
+ * fill(WarnResult.SuccessOnly({ success: 1 })),
426
+ * WarnResult.SuccessWithWarnings({ warnings: "no warnings", success: 1 })
427
+ * )
428
+ * ```
429
+ *
430
+ * @category getters
431
+ * @since 0.0.0
432
+ */
433
+ export const orElse = ({
434
+ orElseWarnings,
435
+ orElseSuccess
436
+ }) => warnResult => fromInclusiveOr(InclusiveOr.orElse({
437
+ orElseLeft: orElseWarnings,
438
+ orElseRight: orElseSuccess
439
+ })(toInclusiveOr(warnResult)));
440
+ /**
441
+ * Completes a `WarnResult` into a `SuccessWithWarnings` whose missing side is
442
+ * filled with `undefined`.
443
+ *
444
+ * A specialisation of `orElse` that supplies `undefined` for whichever side is
445
+ * absent, so the result always exposes both `warnings` and `success` keys (each
446
+ * possibly `undefined`). Use it when you want to destructure both sides without
447
+ * branching on the tag.
448
+ *
449
+ * @example
450
+ * ```ts
451
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
452
+ *
453
+ * assert.deepStrictEqual(
454
+ * WarnResult.orUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
455
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: undefined })
456
+ * )
457
+ * assert.deepStrictEqual(
458
+ * WarnResult.orUndefined(WarnResult.SuccessOnly({ success: 1 })),
459
+ * WarnResult.SuccessWithWarnings({ warnings: undefined, success: 1 })
460
+ * )
461
+ * ```
462
+ *
463
+ * @category getters
464
+ * @since 0.0.0
465
+ */
466
+ export const orUndefined = /*#__PURE__*/orElse({
467
+ orElseWarnings: () => undefined,
468
+ orElseSuccess: () => undefined
469
+ });
470
+ /**
471
+ * Extracts the `warnings` of a `WarnResult`, falling back to `orElseReturn` when
472
+ * no `warnings` are present.
473
+ *
474
+ * `WarningsOnly` and `SuccessWithWarnings` return their `warnings`; `SuccessOnly`
475
+ * returns the result of `orElseReturn`. Use it to read the warnings with a default
476
+ * in one step.
477
+ *
478
+ * @example
479
+ * ```ts
480
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
481
+ *
482
+ * const warningsOrNone = WarnResult.warningsOrElse(() => "no warnings")
483
+ *
484
+ * assert.deepStrictEqual(
485
+ * warningsOrNone(WarnResult.WarningsOnly({ warnings: "w" })),
486
+ * "w"
487
+ * )
488
+ * assert.deepStrictEqual(
489
+ * warningsOrNone(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
490
+ * "w"
491
+ * )
492
+ * assert.deepStrictEqual(
493
+ * warningsOrNone(WarnResult.SuccessOnly({ success: 1 })),
494
+ * "no warnings"
495
+ * )
496
+ * ```
497
+ *
498
+ * @category getters
499
+ * @since 0.0.0
500
+ */
501
+ export const warningsOrElse = orElseReturn => warnResult => InclusiveOr.leftOrElse(orElseReturn)(toInclusiveOr(warnResult));
502
+ /**
503
+ * Extracts the `warnings` of a `WarnResult`, returning `undefined` when no
504
+ * `warnings` are present.
505
+ *
506
+ * A specialisation of `warningsOrElse` whose fallback is `undefined`:
507
+ * `WarningsOnly` and `SuccessWithWarnings` yield their `warnings`, while
508
+ * `SuccessOnly` yields `undefined`.
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
513
+ *
514
+ * assert.deepStrictEqual(
515
+ * WarnResult.warningsOrUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
516
+ * "w"
517
+ * )
518
+ * assert.deepStrictEqual(
519
+ * WarnResult.warningsOrUndefined(WarnResult.SuccessOnly({ success: 1 })),
520
+ * undefined
521
+ * )
522
+ * ```
523
+ *
524
+ * @category getters
525
+ * @since 0.0.0
526
+ */
527
+ export const warningsOrUndefined = /*#__PURE__*/warningsOrElse(() => undefined);
528
+ /**
529
+ * Extracts the `success` value of a `WarnResult`, falling back to `orElseReturn`
530
+ * when no `success` value is present.
531
+ *
532
+ * The mirror of `warningsOrElse`: `SuccessOnly` and `SuccessWithWarnings` return
533
+ * their `success` value; `WarningsOnly` returns the result of `orElseReturn`.
534
+ *
535
+ * @example
536
+ * ```ts
537
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
538
+ *
539
+ * const successOrZero = WarnResult.successOrElse(() => 0)
540
+ *
541
+ * assert.deepStrictEqual(
542
+ * successOrZero(WarnResult.SuccessOnly({ success: 1 })),
543
+ * 1
544
+ * )
545
+ * assert.deepStrictEqual(
546
+ * successOrZero(WarnResult.WarningsOnly({ warnings: "w" })),
547
+ * 0
548
+ * )
549
+ * ```
550
+ *
551
+ * @category getters
552
+ * @since 0.0.0
553
+ */
554
+ export const successOrElse = orElseReturn => warnResult => InclusiveOr.rightOrElse(orElseReturn)(toInclusiveOr(warnResult));
555
+ /**
556
+ * Extracts the `success` value of a `WarnResult`, returning `undefined` when no
557
+ * `success` value is present.
558
+ *
559
+ * A specialisation of `successOrElse` whose fallback is `undefined`: `SuccessOnly`
560
+ * and `SuccessWithWarnings` yield their `success` value, while `WarningsOnly`
561
+ * yields `undefined`.
562
+ *
563
+ * @example
564
+ * ```ts
565
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
566
+ *
567
+ * assert.deepStrictEqual(
568
+ * WarnResult.successOrUndefined(WarnResult.SuccessOnly({ success: 1 })),
569
+ * 1
570
+ * )
571
+ * assert.deepStrictEqual(
572
+ * WarnResult.successOrUndefined(WarnResult.WarningsOnly({ warnings: "w" })),
573
+ * undefined
574
+ * )
575
+ * ```
576
+ *
577
+ * @category getters
578
+ * @since 0.0.0
579
+ */
580
+ export const successOrUndefined = /*#__PURE__*/successOrElse(() => undefined);
581
+ /**
582
+ * Extracts the `success` value of a `WarnResult` as an `Option`.
583
+ *
584
+ * `SuccessOnly` and `SuccessWithWarnings` yield `Option.some(success)`;
585
+ * `WarningsOnly` yields `Option.none()`. Use it when you want to chain the success
586
+ * value through `Option` combinators rather than fall back to a default eagerly.
587
+ *
588
+ * @example
589
+ * ```ts
590
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
591
+ * import { Option } from "effect"
592
+ *
593
+ * assert.deepStrictEqual(
594
+ * WarnResult.successOption(WarnResult.SuccessOnly({ success: 1 })),
595
+ * Option.some(1)
596
+ * )
597
+ * assert.deepStrictEqual(
598
+ * WarnResult.successOption(WarnResult.WarningsOnly({ warnings: "w" })),
599
+ * Option.none()
600
+ * )
601
+ * ```
602
+ *
603
+ * @category getters
604
+ * @since 0.0.0
605
+ */
606
+ export const successOption = warnResult => InclusiveOr.rightOption(toInclusiveOr(warnResult));
607
+ /**
608
+ * Extracts the `warnings` of a `WarnResult` as an `Option`.
609
+ *
610
+ * The mirror of `successOption`: `WarningsOnly` and `SuccessWithWarnings` yield
611
+ * `Option.some(warnings)`, while `SuccessOnly` yields `Option.none()`.
612
+ *
613
+ * @example
614
+ * ```ts
615
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
616
+ * import { Option } from "effect"
617
+ *
618
+ * assert.deepStrictEqual(
619
+ * WarnResult.warningsOption(WarnResult.WarningsOnly({ warnings: "w" })),
620
+ * Option.some("w")
621
+ * )
622
+ * assert.deepStrictEqual(
623
+ * WarnResult.warningsOption(WarnResult.SuccessOnly({ success: 1 })),
624
+ * Option.none()
625
+ * )
626
+ * ```
627
+ *
628
+ * @category getters
629
+ * @since 0.0.0
630
+ */
631
+ export const warningsOption = warnResult => InclusiveOr.leftOption(toInclusiveOr(warnResult));
632
+ /**
633
+ * Transforms both sides of a `WarnResult`, applying `mapWarnings` to any
634
+ * `warnings` and `mapSuccess` to any `success` value.
635
+ *
636
+ * Each constructor is rebuilt with its mapped contents, so `WarningsOnly` maps
637
+ * only the warnings, `SuccessOnly` only the success value, and
638
+ * `SuccessWithWarnings` both. The tag is preserved. Use it as the bifunctor map
639
+ * over `WarnResult`.
640
+ *
641
+ * @example
642
+ * ```ts
643
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
644
+ *
645
+ * const both = WarnResult.mapBoth({
646
+ * mapWarnings: (warnings: string) => warnings.toUpperCase(),
647
+ * mapSuccess: (success: number) => success + 1
648
+ * })
649
+ *
650
+ * assert.deepStrictEqual(
651
+ * both(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
652
+ * WarnResult.SuccessWithWarnings({ warnings: "W", success: 2 })
653
+ * )
654
+ * assert.deepStrictEqual(
655
+ * both(WarnResult.WarningsOnly({ warnings: "w" })),
656
+ * WarnResult.WarningsOnly({ warnings: "W" })
657
+ * )
658
+ * ```
659
+ *
660
+ * @category mapping
661
+ * @since 0.0.0
662
+ */
663
+ export const mapBoth = ({
664
+ mapWarnings,
665
+ mapSuccess
666
+ }) => warnResult => fromInclusiveOr(InclusiveOr.mapBoth({
667
+ mapLeft: mapWarnings,
668
+ mapRight: mapSuccess
669
+ })(toInclusiveOr(warnResult)));
670
+ /**
671
+ * Effectful `mapBoth`: transforms each present side through an `Effect`,
672
+ * reassembling the results into a `WarnResult` inside an `Effect`.
673
+ *
674
+ * For `SuccessWithWarnings` both effects run via `Effect.all` and their results
675
+ * are combined; `WarningsOnly`/`SuccessOnly` run only the relevant effect. Errors
676
+ * and requirements from both mappers are unioned into the result type. Use it when
677
+ * mapping a `WarnResult`'s sides requires effects (validation, IO).
678
+ *
679
+ * @example
680
+ * ```ts
681
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
682
+ * import { Effect } from "effect"
683
+ *
684
+ * const both = WarnResult.mapBothEffect({
685
+ * mapWarnings: (warnings: string) => Effect.succeed(warnings.toUpperCase()),
686
+ * mapSuccess: (success: number) => Effect.succeed(success + 1)
687
+ * })
688
+ *
689
+ * assert.deepStrictEqual(
690
+ * Effect.runSync(
691
+ * both(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
692
+ * ),
693
+ * WarnResult.SuccessWithWarnings({ warnings: "W", success: 2 })
694
+ * )
695
+ * ```
696
+ *
697
+ * @category sequencing
698
+ * @since 0.0.0
699
+ */
700
+ export const mapBothEffect = ({
701
+ mapWarnings,
702
+ mapSuccess
703
+ }) => warnResult => pipe(toInclusiveOr(warnResult), InclusiveOr.mapBothEffect({
704
+ mapLeft: mapWarnings,
705
+ mapRight: mapSuccess
706
+ }), Effect.map(io => fromInclusiveOr(io)));
707
+ /**
708
+ * Transforms the `warnings` of a `WarnResult`, leaving any `success` value
709
+ * untouched.
710
+ *
711
+ * A specialisation of `mapBoth` with the success mapper set to `identity`:
712
+ * `WarningsOnly` and `SuccessWithWarnings` have their `warnings` mapped, while
713
+ * `SuccessOnly` passes through unchanged.
714
+ *
715
+ * @example
716
+ * ```ts
717
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
718
+ *
719
+ * const shout = WarnResult.mapWarnings((warnings: string) =>
720
+ * warnings.toUpperCase()
721
+ * )
722
+ *
723
+ * assert.deepStrictEqual(
724
+ * shout(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
725
+ * WarnResult.SuccessWithWarnings({ warnings: "W", success: 1 })
726
+ * )
727
+ * assert.deepStrictEqual(
728
+ * shout(WarnResult.SuccessOnly({ success: 1 })),
729
+ * WarnResult.SuccessOnly({ success: 1 })
730
+ * )
731
+ * ```
732
+ *
733
+ * @category mapping
734
+ * @since 0.0.0
735
+ */
736
+ export const mapWarnings = mapWarnings => warnResult => fromInclusiveOr(InclusiveOr.mapLeft(mapWarnings)(toInclusiveOr(warnResult)));
737
+ /**
738
+ * Chains the `warnings` of a `WarnResult` into a new `WarnResult`, flattening the
739
+ * result.
740
+ *
741
+ * Whenever `warnings` are present (`WarningsOnly` or `SuccessWithWarnings`) they
742
+ * are passed to `mapWarnings`, whose returned `WarnResult` replaces the original;
743
+ * `SuccessOnly` passes through unchanged. Use it to sequence warnings-driven
744
+ * computations that themselves produce a `WarnResult`.
745
+ *
746
+ * @example
747
+ * ```ts
748
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
749
+ *
750
+ * const chain = WarnResult.flatMapWarnings((warnings: string) =>
751
+ * warnings.length > 0
752
+ * ? WarnResult.WarningsOnly({ warnings: warnings.toUpperCase() })
753
+ * : WarnResult.SuccessOnly({ success: 0 })
754
+ * )
755
+ *
756
+ * assert.deepStrictEqual(
757
+ * chain(WarnResult.WarningsOnly({ warnings: "w" })),
758
+ * WarnResult.WarningsOnly({ warnings: "W" })
759
+ * )
760
+ * assert.deepStrictEqual(
761
+ * chain(WarnResult.SuccessOnly({ success: 1 })),
762
+ * WarnResult.SuccessOnly({ success: 1 })
763
+ * )
764
+ * ```
765
+ *
766
+ * @category sequencing
767
+ * @since 0.0.0
768
+ */
769
+ export const flatMapWarnings = mapWarnings => warnResult => fromInclusiveOr(InclusiveOr.flatMapLeft(warnings => toInclusiveOr(mapWarnings(warnings)))(toInclusiveOr(warnResult)));
770
+ /**
771
+ * Effectful `mapWarnings`: transforms the `warnings` of a `WarnResult` through an
772
+ * `Effect`, leaving any `success` value untouched.
773
+ *
774
+ * A specialisation of `mapBothEffect` with the success mapper set to
775
+ * `Effect.succeed`: the `warnings` (when present) are mapped effectfully and the
776
+ * `success` value is carried through unchanged.
777
+ *
778
+ * @example
779
+ * ```ts
780
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
781
+ * import { Effect } from "effect"
782
+ *
783
+ * const shout = WarnResult.mapWarningsEffect((warnings: string) =>
784
+ * Effect.succeed(warnings.toUpperCase())
785
+ * )
786
+ *
787
+ * assert.deepStrictEqual(
788
+ * Effect.runSync(
789
+ * shout(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
790
+ * ),
791
+ * WarnResult.SuccessWithWarnings({ warnings: "W", success: 1 })
792
+ * )
793
+ * ```
794
+ *
795
+ * @category sequencing
796
+ * @since 0.0.0
797
+ */
798
+ export const mapWarningsEffect = mapWarnings => warnResult => pipe(toInclusiveOr(warnResult), InclusiveOr.mapLeftEffect(mapWarnings), Effect.map(io => fromInclusiveOr(io)));
799
+ /**
800
+ * Effectful `flatMapWarnings`: chains the `warnings` of a `WarnResult` into an
801
+ * `Effect` that yields a new `WarnResult`, flattening the result.
802
+ *
803
+ * When `warnings` are present they are passed to `mapWarnings`, whose effectful
804
+ * `WarnResult` replaces the original; `SuccessOnly` is lifted unchanged via
805
+ * `Effect.succeed`. Use it to sequence warnings-driven effectful computations that
806
+ * produce a `WarnResult`.
807
+ *
808
+ * @example
809
+ * ```ts
810
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
811
+ * import { Effect } from "effect"
812
+ *
813
+ * const chain = WarnResult.flatMapWarningsEffect((warnings: string) =>
814
+ * Effect.succeed(WarnResult.WarningsOnly({ warnings: warnings.toUpperCase() }))
815
+ * )
816
+ *
817
+ * assert.deepStrictEqual(
818
+ * Effect.runSync(chain(WarnResult.WarningsOnly({ warnings: "w" }))),
819
+ * WarnResult.WarningsOnly({ warnings: "W" })
820
+ * )
821
+ * assert.deepStrictEqual(
822
+ * Effect.runSync(chain(WarnResult.SuccessOnly({ success: 1 }))),
823
+ * WarnResult.SuccessOnly({ success: 1 })
824
+ * )
825
+ * ```
826
+ *
827
+ * @category sequencing
828
+ * @since 0.0.0
829
+ */
830
+ export const flatMapWarningsEffect = mapWarnings => warnResult => pipe(toInclusiveOr(warnResult), InclusiveOr.flatMapLeftEffect(warnings => Effect.map(mapWarnings(warnings), toInclusiveOr)), Effect.map(io => fromInclusiveOr(io)));
831
+ /**
832
+ * Transforms the `success` value of a `WarnResult`, leaving any `warnings`
833
+ * untouched.
834
+ *
835
+ * The mirror of `mapWarnings`: `SuccessOnly` and `SuccessWithWarnings` have their
836
+ * `success` value mapped, while `WarningsOnly` passes through unchanged.
837
+ *
838
+ * @example
839
+ * ```ts
840
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
841
+ *
842
+ * const inc = WarnResult.mapSuccess((success: number) => success + 1)
843
+ *
844
+ * assert.deepStrictEqual(
845
+ * inc(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 })),
846
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 2 })
847
+ * )
848
+ * assert.deepStrictEqual(
849
+ * inc(WarnResult.WarningsOnly({ warnings: "w" })),
850
+ * WarnResult.WarningsOnly({ warnings: "w" })
851
+ * )
852
+ * ```
853
+ *
854
+ * @category mapping
855
+ * @since 0.0.0
856
+ */
857
+ export const mapSuccess = mapSuccess => warnResult => fromInclusiveOr(InclusiveOr.mapRight(mapSuccess)(toInclusiveOr(warnResult)));
858
+ /**
859
+ * Chains the `success` value of a `WarnResult` into a new `WarnResult`, flattening
860
+ * the result.
861
+ *
862
+ * The mirror of `flatMapWarnings`: whenever a `success` value is present
863
+ * (`SuccessOnly` or `SuccessWithWarnings`) it is passed to `mapSuccess`, whose
864
+ * returned `WarnResult` replaces the original; `WarningsOnly` passes through
865
+ * unchanged.
866
+ *
867
+ * @example
868
+ * ```ts
869
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
870
+ *
871
+ * const chain = WarnResult.flatMapSuccess((success: number) =>
872
+ * WarnResult.SuccessOnly({ success: success + 1 })
873
+ * )
874
+ *
875
+ * assert.deepStrictEqual(
876
+ * chain(WarnResult.SuccessOnly({ success: 1 })),
877
+ * WarnResult.SuccessOnly({ success: 2 })
878
+ * )
879
+ * assert.deepStrictEqual(
880
+ * chain(WarnResult.WarningsOnly({ warnings: "w" })),
881
+ * WarnResult.WarningsOnly({ warnings: "w" })
882
+ * )
883
+ * ```
884
+ *
885
+ * @category sequencing
886
+ * @since 0.0.0
887
+ */
888
+ export const flatMapSuccess = mapSuccess => warnResult => fromInclusiveOr(InclusiveOr.flatMapRight(success => toInclusiveOr(mapSuccess(success)))(toInclusiveOr(warnResult)));
889
+ /**
890
+ * Effectful `mapSuccess`: transforms the `success` value of a `WarnResult` through
891
+ * an `Effect`, leaving any `warnings` untouched.
892
+ *
893
+ * The mirror of `mapWarningsEffect`: the `success` value (when present) is mapped
894
+ * effectfully and the `warnings` are carried through unchanged via
895
+ * `Effect.succeed`.
896
+ *
897
+ * @example
898
+ * ```ts
899
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
900
+ * import { Effect } from "effect"
901
+ *
902
+ * const inc = WarnResult.mapSuccessEffect((success: number) =>
903
+ * Effect.succeed(success + 1)
904
+ * )
905
+ *
906
+ * assert.deepStrictEqual(
907
+ * Effect.runSync(
908
+ * inc(WarnResult.SuccessWithWarnings({ warnings: "w", success: 1 }))
909
+ * ),
910
+ * WarnResult.SuccessWithWarnings({ warnings: "w", success: 2 })
911
+ * )
912
+ * ```
913
+ *
914
+ * @category sequencing
915
+ * @since 0.0.0
916
+ */
917
+ export const mapSuccessEffect = mapSuccess => warnResult => pipe(toInclusiveOr(warnResult), InclusiveOr.mapRightEffect(mapSuccess), Effect.map(io => fromInclusiveOr(io)));
918
+ /**
919
+ * Effectful `flatMapSuccess`: chains the `success` value of a `WarnResult` into an
920
+ * `Effect` that yields a new `WarnResult`, flattening the result.
921
+ *
922
+ * The mirror of `flatMapWarningsEffect`: when a `success` value is present it is
923
+ * passed to `mapSuccess`, whose effectful `WarnResult` replaces the original;
924
+ * `WarningsOnly` is lifted unchanged via `Effect.succeed`.
925
+ *
926
+ * @example
927
+ * ```ts
928
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
929
+ * import { Effect } from "effect"
930
+ *
931
+ * const chain = WarnResult.flatMapSuccessEffect((success: number) =>
932
+ * Effect.succeed(WarnResult.SuccessOnly({ success: success + 1 }))
933
+ * )
934
+ *
935
+ * assert.deepStrictEqual(
936
+ * Effect.runSync(chain(WarnResult.SuccessOnly({ success: 1 }))),
937
+ * WarnResult.SuccessOnly({ success: 2 })
938
+ * )
939
+ * assert.deepStrictEqual(
940
+ * Effect.runSync(chain(WarnResult.WarningsOnly({ warnings: "w" }))),
941
+ * WarnResult.WarningsOnly({ warnings: "w" })
942
+ * )
943
+ * ```
944
+ *
945
+ * @category sequencing
946
+ * @since 0.0.0
947
+ */
948
+ export const flatMapSuccessEffect = mapSuccess => warnResult => pipe(toInclusiveOr(warnResult), InclusiveOr.flatMapRightEffect(success => Effect.map(mapSuccess(success), toInclusiveOr)), Effect.map(io => fromInclusiveOr(io)));
949
+ /**
950
+ * Zips two arrays into one, calling `f` with a `WarnResult` for each index so
951
+ * that length mismatches are handled explicitly rather than truncated.
952
+ *
953
+ * Unlike `Array.zipWith` (which stops at the shorter array), this walks to the
954
+ * length of the *longer* array. The first array's element fills the `warnings`
955
+ * side and the second array's element fills the `success` side, so at each index
956
+ * `f` receives a `WarnResult.WarnResult<B, A>`: `SuccessWithWarnings` when both
957
+ * arrays have an element, `WarningsOnly` when only the first does, and
958
+ * `SuccessOnly` when only the second does. Use it when the "extra" tail of either
959
+ * array still carries meaning.
960
+ *
961
+ * @example
962
+ * ```ts
963
+ * import { WarnResult } from "@nunofyobiz/effect-extras"
964
+ * import { pipe } from "effect"
965
+ *
966
+ * const describe = WarnResult.match({
967
+ * WarningsOnly: ({ warnings }) => `warnings ${warnings}`,
968
+ * SuccessOnly: ({ success }) => `success ${success}`,
969
+ * SuccessWithWarnings: ({ warnings, success }) => `both ${warnings}/${success}`
970
+ * })
971
+ *
972
+ * // data-first
973
+ * assert.deepStrictEqual(WarnResult.zip([1, 2, 3], [10, 20], describe), [
974
+ * "both 1/10",
975
+ * "both 2/20",
976
+ * "warnings 3"
977
+ * ])
978
+ *
979
+ * // data-last (pipeable)
980
+ * assert.deepStrictEqual(pipe([1, 2, 3], WarnResult.zip([10, 20], describe)), [
981
+ * "both 1/10",
982
+ * "both 2/20",
983
+ * "warnings 3"
984
+ * ])
985
+ * ```
986
+ *
987
+ * @category combinators
988
+ * @since 0.0.0
989
+ */
990
+ export const zip = /*#__PURE__*/dual(3, (array1, array2, f) => InclusiveOr.zip(array1, array2, io => f(fromInclusiveOr(io))));
991
+ //# sourceMappingURL=WarnResult.js.map