effect 3.12.4 → 3.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Arbitrary.js +72 -14
- package/dist/cjs/Arbitrary.js.map +1 -1
- package/dist/cjs/Array.js +11 -9
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/Cause.js +26 -2
- package/dist/cjs/Cause.js.map +1 -1
- package/dist/cjs/Cron.js +55 -23
- package/dist/cjs/Cron.js.map +1 -1
- package/dist/cjs/Duration.js.map +1 -1
- package/dist/cjs/Effect.js +32 -23
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/FiberHandle.js +8 -8
- package/dist/cjs/FiberMap.js +8 -8
- package/dist/cjs/FiberSet.js +8 -8
- package/dist/cjs/Inspectable.js +0 -4
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/LogLevel.js +30 -2
- package/dist/cjs/LogLevel.js.map +1 -1
- package/dist/cjs/ParseResult.js +38 -18
- package/dist/cjs/ParseResult.js.map +1 -1
- package/dist/cjs/Schema.js +192 -118
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/internal/cause.js.map +1 -1
- package/dist/cjs/internal/core-effect.js +6 -5
- package/dist/cjs/internal/core-effect.js.map +1 -1
- package/dist/cjs/internal/core.js +6 -5
- package/dist/cjs/internal/core.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +12 -3
- package/dist/cjs/internal/dateTime.js.map +1 -1
- package/dist/cjs/internal/effect/circular.js +15 -2
- package/dist/cjs/internal/effect/circular.js.map +1 -1
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/groupBy.js +7 -7
- package/dist/cjs/internal/groupBy.js.map +1 -1
- package/dist/cjs/internal/rateLimiter.js +8 -7
- package/dist/cjs/internal/rateLimiter.js.map +1 -1
- package/dist/cjs/internal/runtime.js +7 -11
- package/dist/cjs/internal/runtime.js.map +1 -1
- package/dist/cjs/internal/stream.js +5 -5
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/dts/Arbitrary.d.ts.map +1 -1
- package/dist/dts/Array.d.ts +62 -16
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/Cause.d.ts +27 -3
- package/dist/dts/Cause.d.ts.map +1 -1
- package/dist/dts/Cron.d.ts +10 -3
- package/dist/dts/Cron.d.ts.map +1 -1
- package/dist/dts/Duration.d.ts +5 -5
- package/dist/dts/Duration.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +31 -22
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/FiberHandle.d.ts +8 -8
- package/dist/dts/FiberMap.d.ts +8 -8
- package/dist/dts/FiberSet.d.ts +8 -8
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/LogLevel.d.ts +90 -6
- package/dist/dts/LogLevel.d.ts.map +1 -1
- package/dist/dts/ParseResult.d.ts +11 -0
- package/dist/dts/ParseResult.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +53 -33
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/internal/core-effect.d.ts.map +1 -1
- package/dist/dts/internal/core.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Arbitrary.js +72 -14
- package/dist/esm/Arbitrary.js.map +1 -1
- package/dist/esm/Array.js +11 -9
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/Cause.js +26 -2
- package/dist/esm/Cause.js.map +1 -1
- package/dist/esm/Cron.js +53 -22
- package/dist/esm/Cron.js.map +1 -1
- package/dist/esm/Duration.js.map +1 -1
- package/dist/esm/Effect.js +32 -23
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/FiberHandle.js +8 -8
- package/dist/esm/FiberMap.js +8 -8
- package/dist/esm/FiberSet.js +8 -8
- package/dist/esm/Inspectable.js +0 -3
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/LogLevel.js +30 -2
- package/dist/esm/LogLevel.js.map +1 -1
- package/dist/esm/ParseResult.js +38 -18
- package/dist/esm/ParseResult.js.map +1 -1
- package/dist/esm/Schema.js +186 -110
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/internal/cause.js.map +1 -1
- package/dist/esm/internal/core-effect.js +6 -5
- package/dist/esm/internal/core-effect.js.map +1 -1
- package/dist/esm/internal/core.js +6 -5
- package/dist/esm/internal/core.js.map +1 -1
- package/dist/esm/internal/dateTime.js +11 -2
- package/dist/esm/internal/dateTime.js.map +1 -1
- package/dist/esm/internal/effect/circular.js +15 -2
- package/dist/esm/internal/effect/circular.js.map +1 -1
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/groupBy.js +7 -7
- package/dist/esm/internal/groupBy.js.map +1 -1
- package/dist/esm/internal/rateLimiter.js +8 -7
- package/dist/esm/internal/rateLimiter.js.map +1 -1
- package/dist/esm/internal/runtime.js +7 -11
- package/dist/esm/internal/runtime.js.map +1 -1
- package/dist/esm/internal/stream.js +5 -5
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/package.json +1 -1
- package/src/Arbitrary.ts +84 -14
- package/src/Array.ts +65 -19
- package/src/Cause.ts +27 -3
- package/src/Cron.ts +30 -27
- package/src/Duration.ts +11 -3
- package/src/Effect.ts +35 -23
- package/src/FiberHandle.ts +8 -8
- package/src/FiberMap.ts +8 -8
- package/src/FiberSet.ts +8 -8
- package/src/Inspectable.ts +0 -1
- package/src/LogLevel.ts +90 -6
- package/src/ParseResult.ts +52 -28
- package/src/Schema.ts +233 -124
- package/src/internal/cause.ts +1 -1
- package/src/internal/core-effect.ts +16 -9
- package/src/internal/core.ts +9 -4
- package/src/internal/dateTime.ts +12 -2
- package/src/internal/effect/circular.ts +19 -17
- package/src/internal/fiberRuntime.ts +2 -1
- package/src/internal/groupBy.ts +35 -39
- package/src/internal/rateLimiter.ts +8 -7
- package/src/internal/runtime.ts +6 -14
- package/src/internal/stream.ts +13 -15
- package/src/internal/version.ts +1 -1
package/package.json
CHANGED
package/src/Arbitrary.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Arr from "./Array.js"
|
|
6
6
|
import * as FastCheck from "./FastCheck.js"
|
|
7
|
+
import { globalValue } from "./GlobalValue.js"
|
|
7
8
|
import * as errors_ from "./internal/schema/errors.js"
|
|
8
9
|
import * as schemaId_ from "./internal/schema/schemaId.js"
|
|
9
10
|
import * as util_ from "./internal/schema/util.js"
|
|
@@ -276,6 +277,11 @@ const makeArrayConfig = (options: {
|
|
|
276
277
|
|
|
277
278
|
type Config = StringConstraints | NumberConstraints | BigIntConstraints | DateConstraints | ArrayConfig
|
|
278
279
|
|
|
280
|
+
const arbitraryMemoMap = globalValue(
|
|
281
|
+
Symbol.for("effect/Arbitrary/arbitraryMemoMap"),
|
|
282
|
+
() => new WeakMap<AST.AST, LazyArbitrary<any>>()
|
|
283
|
+
)
|
|
284
|
+
|
|
279
285
|
const go = (
|
|
280
286
|
ast: AST.AST,
|
|
281
287
|
ctx: ArbitraryGenerationContext,
|
|
@@ -311,6 +317,7 @@ const go = (
|
|
|
311
317
|
const constStringConstraints = makeStringConstraints({})
|
|
312
318
|
const constNumberConstraints = makeNumberConstraints({})
|
|
313
319
|
const constBigIntConstraints = makeBigIntConstraints({})
|
|
320
|
+
const defaultSuspendedArrayConstraints: FastCheck.ArrayConstraints = { maxLength: 2 }
|
|
314
321
|
|
|
315
322
|
/** @internal */
|
|
316
323
|
export const toOp = (
|
|
@@ -439,8 +446,22 @@ export const toOp = (
|
|
|
439
446
|
const value = indexSignatures[i][1](fc)
|
|
440
447
|
output = output.chain((o) => {
|
|
441
448
|
const item = fc.tuple(key, value)
|
|
449
|
+
/*
|
|
450
|
+
|
|
451
|
+
`getSuspendedArray` is used to generate less key/value pairs in
|
|
452
|
+
the context of a recursive schema. Without it, the following schema
|
|
453
|
+
would generate an big amount of values possibly leading to a stack
|
|
454
|
+
overflow:
|
|
455
|
+
|
|
456
|
+
```ts
|
|
457
|
+
type A = { [_: string]: A }
|
|
458
|
+
|
|
459
|
+
const schema = S.Record({ key: S.String, value: S.suspend((): S.Schema<A> => schema) })
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
*/
|
|
442
463
|
const arr = ctx.depthIdentifier !== undefined ?
|
|
443
|
-
getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item) :
|
|
464
|
+
getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item, defaultSuspendedArrayConstraints) :
|
|
444
465
|
fc.array(item)
|
|
445
466
|
return arr.map((tuples) => ({ ...Object.fromEntries(tuples), ...o }))
|
|
446
467
|
})
|
|
@@ -454,16 +475,39 @@ export const toOp = (
|
|
|
454
475
|
return new Succeed((fc) => fc.oneof(...types.map((arb) => arb(fc))))
|
|
455
476
|
}
|
|
456
477
|
case "Suspend": {
|
|
478
|
+
const memo = arbitraryMemoMap.get(ast)
|
|
479
|
+
if (memo) {
|
|
480
|
+
return new Succeed(memo)
|
|
481
|
+
}
|
|
457
482
|
const get = util_.memoizeThunk(() => {
|
|
458
483
|
return go(ast.f(), getSuspendedContext(ctx, ast), path)
|
|
459
484
|
})
|
|
460
|
-
|
|
485
|
+
const out: LazyArbitrary<any> = (fc) => fc.constant(null).chain(() => get()(fc))
|
|
486
|
+
arbitraryMemoMap.set(ast, out)
|
|
487
|
+
return new Succeed(out)
|
|
461
488
|
}
|
|
462
489
|
case "Transformation":
|
|
463
490
|
return toOp(ast.to, ctx, path)
|
|
464
491
|
}
|
|
465
492
|
}
|
|
466
493
|
|
|
494
|
+
function subtractElementsLength(
|
|
495
|
+
constraints: FastCheck.ArrayConstraints,
|
|
496
|
+
elementsLength: number
|
|
497
|
+
): FastCheck.ArrayConstraints {
|
|
498
|
+
if (elementsLength === 0 || (constraints.minLength === undefined && constraints.maxLength === undefined)) {
|
|
499
|
+
return constraints
|
|
500
|
+
}
|
|
501
|
+
const out = { ...constraints }
|
|
502
|
+
if (out.minLength !== undefined) {
|
|
503
|
+
out.minLength = Math.max(out.minLength - elementsLength, 0)
|
|
504
|
+
}
|
|
505
|
+
if (out.maxLength !== undefined) {
|
|
506
|
+
out.maxLength = Math.max(out.maxLength - elementsLength, 0)
|
|
507
|
+
}
|
|
508
|
+
return out
|
|
509
|
+
}
|
|
510
|
+
|
|
467
511
|
const goTupleType = (
|
|
468
512
|
ast: AST.TupleType,
|
|
469
513
|
ctx: ArbitraryGenerationContext,
|
|
@@ -508,9 +552,36 @@ const goTupleType = (
|
|
|
508
552
|
const [head, ...tail] = rest
|
|
509
553
|
const item = head(fc)
|
|
510
554
|
output = output.chain((as) => {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
555
|
+
const len = as.length
|
|
556
|
+
// We must adjust the constraints for the rest element
|
|
557
|
+
// because the elements might have generated some values
|
|
558
|
+
const restArrayConstraints = subtractElementsLength(constraints, len)
|
|
559
|
+
if (restArrayConstraints.maxLength === 0) {
|
|
560
|
+
return fc.constant(as)
|
|
561
|
+
}
|
|
562
|
+
/*
|
|
563
|
+
|
|
564
|
+
`getSuspendedArray` is used to generate less values in
|
|
565
|
+
the context of a recursive schema. Without it, the following schema
|
|
566
|
+
would generate an big amount of values possibly leading to a stack
|
|
567
|
+
overflow:
|
|
568
|
+
|
|
569
|
+
```ts
|
|
570
|
+
type A = ReadonlyArray<A | null>
|
|
571
|
+
|
|
572
|
+
const schema = S.Array(
|
|
573
|
+
S.NullOr(S.suspend((): S.Schema<A> => schema))
|
|
574
|
+
)
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
*/
|
|
578
|
+
const arr = ctx.depthIdentifier !== undefined
|
|
579
|
+
? getSuspendedArray(fc, ctx.depthIdentifier, ctx.maxDepth, item, restArrayConstraints)
|
|
580
|
+
: fc.array(item, restArrayConstraints)
|
|
581
|
+
if (len === 0) {
|
|
582
|
+
return arr
|
|
583
|
+
}
|
|
584
|
+
return arr.map((rest) => [...as, ...rest])
|
|
514
585
|
})
|
|
515
586
|
// ---------------------------------------------
|
|
516
587
|
// handle post rest elements
|
|
@@ -660,20 +731,19 @@ const getSuspendedArray = (
|
|
|
660
731
|
depthIdentifier: string,
|
|
661
732
|
maxDepth: number,
|
|
662
733
|
item: FastCheck.Arbitrary<any>,
|
|
663
|
-
constraints
|
|
734
|
+
constraints: FastCheck.ArrayConstraints
|
|
664
735
|
) => {
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
}
|
|
736
|
+
// In the context of a recursive schema, we don't want a `maxLength` greater than 2.
|
|
737
|
+
// The only exception is when `minLength` is also set, in which case we set
|
|
738
|
+
// `maxLength` to the minimum value, which is `minLength`.
|
|
739
|
+
const maxLengthLimit = Math.max(2, constraints.minLength ?? 0)
|
|
740
|
+
if (constraints.maxLength !== undefined && constraints.maxLength > maxLengthLimit) {
|
|
741
|
+
constraints = { ...constraints, maxLength: maxLengthLimit }
|
|
672
742
|
}
|
|
673
743
|
return fc.oneof(
|
|
674
744
|
{ maxDepth, depthIdentifier },
|
|
675
745
|
fc.constant([]),
|
|
676
|
-
fc.array(item,
|
|
746
|
+
fc.array(item, constraints)
|
|
677
747
|
)
|
|
678
748
|
}
|
|
679
749
|
|
package/src/Array.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @since 2.0.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { Either
|
|
7
|
+
import type { Either } from "./Either.js"
|
|
8
8
|
import * as E from "./Either.js"
|
|
9
9
|
import * as Equal from "./Equal.js"
|
|
10
10
|
import * as Equivalence from "./Equivalence.js"
|
|
@@ -4787,7 +4787,7 @@ export const partitionMap: {
|
|
|
4787
4787
|
* @category filtering
|
|
4788
4788
|
* @since 2.0.0
|
|
4789
4789
|
*/
|
|
4790
|
-
<A, B, C>(f: (a: A, i: number) =>
|
|
4790
|
+
<A, B, C>(f: (a: A, i: number) => Either<C, B>): (self: Iterable<A>) => [left: Array<B>, right: Array<C>]
|
|
4791
4791
|
/**
|
|
4792
4792
|
* Applies a function to each element of the `Iterable`, categorizing the results into two separate arrays.
|
|
4793
4793
|
* This function is particularly useful for operations where each element can result in two possible types,
|
|
@@ -4813,10 +4813,10 @@ export const partitionMap: {
|
|
|
4813
4813
|
* @category filtering
|
|
4814
4814
|
* @since 2.0.0
|
|
4815
4815
|
*/
|
|
4816
|
-
<A, B, C>(self: Iterable<A>, f: (a: A, i: number) =>
|
|
4816
|
+
<A, B, C>(self: Iterable<A>, f: (a: A, i: number) => Either<C, B>): [left: Array<B>, right: Array<C>]
|
|
4817
4817
|
} = dual(
|
|
4818
4818
|
2,
|
|
4819
|
-
<A, B, C>(self: Iterable<A>, f: (a: A, i: number) =>
|
|
4819
|
+
<A, B, C>(self: Iterable<A>, f: (a: A, i: number) => Either<C, B>): [left: Array<B>, right: Array<C>] => {
|
|
4820
4820
|
const left: Array<B> = []
|
|
4821
4821
|
const right: Array<C> = []
|
|
4822
4822
|
const as = fromIterable(self)
|
|
@@ -4869,7 +4869,7 @@ export const getSomes: <T extends Iterable<Option<X>>, X = any>(
|
|
|
4869
4869
|
* @category filtering
|
|
4870
4870
|
* @since 2.0.0
|
|
4871
4871
|
*/
|
|
4872
|
-
export const getLefts = <T extends Iterable<
|
|
4872
|
+
export const getLefts = <T extends Iterable<Either<any, any>>>(self: T): Array<Either.Left<ReadonlyArray.Infer<T>>> => {
|
|
4873
4873
|
const out: Array<any> = []
|
|
4874
4874
|
for (const a of self) {
|
|
4875
4875
|
if (E.isLeft(a)) {
|
|
@@ -4896,9 +4896,9 @@ export const getLefts = <T extends Iterable<array_<any, any>>>(self: T): Array<a
|
|
|
4896
4896
|
* @category filtering
|
|
4897
4897
|
* @since 2.0.0
|
|
4898
4898
|
*/
|
|
4899
|
-
export const getRights = <T extends Iterable<
|
|
4899
|
+
export const getRights = <T extends Iterable<Either<any, any>>>(
|
|
4900
4900
|
self: T
|
|
4901
|
-
): Array<
|
|
4901
|
+
): Array<Either.Right<ReadonlyArray.Infer<T>>> => {
|
|
4902
4902
|
const out: Array<any> = []
|
|
4903
4903
|
for (const a of self) {
|
|
4904
4904
|
if (E.isRight(a)) {
|
|
@@ -4951,6 +4951,17 @@ export const filter: {
|
|
|
4951
4951
|
/**
|
|
4952
4952
|
* Separate elements based on a predicate that also exposes the index of the element.
|
|
4953
4953
|
*
|
|
4954
|
+
* @example
|
|
4955
|
+
* ```ts
|
|
4956
|
+
* import { Array } from "effect"
|
|
4957
|
+
*
|
|
4958
|
+
* const numbers = [1, 2, 3, 4]
|
|
4959
|
+
*
|
|
4960
|
+
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
4961
|
+
*
|
|
4962
|
+
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
4963
|
+
* ```
|
|
4964
|
+
*
|
|
4954
4965
|
* @category filtering
|
|
4955
4966
|
* @since 2.0.0
|
|
4956
4967
|
*/
|
|
@@ -4958,6 +4969,17 @@ export const partition: {
|
|
|
4958
4969
|
/**
|
|
4959
4970
|
* Separate elements based on a predicate that also exposes the index of the element.
|
|
4960
4971
|
*
|
|
4972
|
+
* @example
|
|
4973
|
+
* ```ts
|
|
4974
|
+
* import { Array } from "effect"
|
|
4975
|
+
*
|
|
4976
|
+
* const numbers = [1, 2, 3, 4]
|
|
4977
|
+
*
|
|
4978
|
+
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
4979
|
+
*
|
|
4980
|
+
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
4981
|
+
* ```
|
|
4982
|
+
*
|
|
4961
4983
|
* @category filtering
|
|
4962
4984
|
* @since 2.0.0
|
|
4963
4985
|
*/
|
|
@@ -4967,6 +4989,17 @@ export const partition: {
|
|
|
4967
4989
|
/**
|
|
4968
4990
|
* Separate elements based on a predicate that also exposes the index of the element.
|
|
4969
4991
|
*
|
|
4992
|
+
* @example
|
|
4993
|
+
* ```ts
|
|
4994
|
+
* import { Array } from "effect"
|
|
4995
|
+
*
|
|
4996
|
+
* const numbers = [1, 2, 3, 4]
|
|
4997
|
+
*
|
|
4998
|
+
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
4999
|
+
*
|
|
5000
|
+
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
5001
|
+
* ```
|
|
5002
|
+
*
|
|
4970
5003
|
* @category filtering
|
|
4971
5004
|
* @since 2.0.0
|
|
4972
5005
|
*/
|
|
@@ -4976,6 +5009,17 @@ export const partition: {
|
|
|
4976
5009
|
/**
|
|
4977
5010
|
* Separate elements based on a predicate that also exposes the index of the element.
|
|
4978
5011
|
*
|
|
5012
|
+
* @example
|
|
5013
|
+
* ```ts
|
|
5014
|
+
* import { Array } from "effect"
|
|
5015
|
+
*
|
|
5016
|
+
* const numbers = [1, 2, 3, 4]
|
|
5017
|
+
*
|
|
5018
|
+
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
5019
|
+
*
|
|
5020
|
+
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
5021
|
+
* ```
|
|
5022
|
+
*
|
|
4979
5023
|
* @category filtering
|
|
4980
5024
|
* @since 2.0.0
|
|
4981
5025
|
*/
|
|
@@ -4986,6 +5030,17 @@ export const partition: {
|
|
|
4986
5030
|
/**
|
|
4987
5031
|
* Separate elements based on a predicate that also exposes the index of the element.
|
|
4988
5032
|
*
|
|
5033
|
+
* @example
|
|
5034
|
+
* ```ts
|
|
5035
|
+
* import { Array } from "effect"
|
|
5036
|
+
*
|
|
5037
|
+
* const numbers = [1, 2, 3, 4]
|
|
5038
|
+
*
|
|
5039
|
+
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
5040
|
+
*
|
|
5041
|
+
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
5042
|
+
* ```
|
|
5043
|
+
*
|
|
4989
5044
|
* @category filtering
|
|
4990
5045
|
* @since 2.0.0
|
|
4991
5046
|
*/
|
|
@@ -5010,21 +5065,12 @@ export const partition: {
|
|
|
5010
5065
|
/**
|
|
5011
5066
|
* Separates an `Iterable` into two arrays based on a predicate.
|
|
5012
5067
|
*
|
|
5013
|
-
* @example
|
|
5014
|
-
* ```ts
|
|
5015
|
-
* import { Array } from "effect"
|
|
5016
|
-
*
|
|
5017
|
-
* const numbers = [1, 2, 3, 4]
|
|
5018
|
-
* const result = Array.partition(numbers, n => n % 2 === 0)
|
|
5019
|
-
* assert.deepStrictEqual(result, [[1, 3], [2, 4]])
|
|
5020
|
-
* ```
|
|
5021
|
-
*
|
|
5022
5068
|
* @category filtering
|
|
5023
5069
|
* @since 2.0.0
|
|
5024
5070
|
*/
|
|
5025
|
-
export const separate: <T extends Iterable<
|
|
5071
|
+
export const separate: <T extends Iterable<Either<any, any>>>(
|
|
5026
5072
|
self: T
|
|
5027
|
-
) => [Array<
|
|
5073
|
+
) => [Array<Either.Left<ReadonlyArray.Infer<T>>>, Array<Either.Right<ReadonlyArray.Infer<T>>>] = partitionMap(
|
|
5028
5074
|
identity
|
|
5029
5075
|
)
|
|
5030
5076
|
|
|
@@ -5296,7 +5342,7 @@ export const flatMapNullable: {
|
|
|
5296
5342
|
* @since 2.0.0
|
|
5297
5343
|
*/
|
|
5298
5344
|
export const liftEither = <A extends Array<unknown>, E, B>(
|
|
5299
|
-
f: (...a: A) =>
|
|
5345
|
+
f: (...a: A) => Either<B, E>
|
|
5300
5346
|
) =>
|
|
5301
5347
|
(...a: A): Array<B> => {
|
|
5302
5348
|
const e = f(...a)
|
package/src/Cause.ts
CHANGED
|
@@ -453,7 +453,7 @@ export const sequential: <E, E2>(left: Cause<E>, right: Cause<E2>) => Cause<E |
|
|
|
453
453
|
* @since 2.0.0
|
|
454
454
|
* @category refinements
|
|
455
455
|
*/
|
|
456
|
-
export const isCause: (u: unknown) => u is Cause<
|
|
456
|
+
export const isCause: (u: unknown) => u is Cause<unknown> = internal.isCause
|
|
457
457
|
|
|
458
458
|
/**
|
|
459
459
|
* Returns `true` if the specified `Cause` is an `Empty` type, `false`
|
|
@@ -1089,8 +1089,32 @@ export const isRuntimeException: (u: unknown) => u is RuntimeException = core.is
|
|
|
1089
1089
|
export const TimeoutException: new(message?: string | undefined) => TimeoutException = core.TimeoutException
|
|
1090
1090
|
|
|
1091
1091
|
/**
|
|
1092
|
-
*
|
|
1093
|
-
* from
|
|
1092
|
+
* Creates an instance of `UnknownException`, an error object used to handle
|
|
1093
|
+
* unknown errors such as those from rejected promises.
|
|
1094
|
+
*
|
|
1095
|
+
* **Details**
|
|
1096
|
+
*
|
|
1097
|
+
* This function constructs an `UnknownException` with flexible behavior for
|
|
1098
|
+
* managing the error message and cause.
|
|
1099
|
+
*
|
|
1100
|
+
* The required `error` argument is passed as the `cause` to the global `Error`
|
|
1101
|
+
* constructor, ensuring that the original cause is preserved in the error chain
|
|
1102
|
+
* for debugging purposes. This ensures that the origin stack trace is
|
|
1103
|
+
* preserved.
|
|
1104
|
+
*
|
|
1105
|
+
* The `error` argument is always stored in the `error` property of the
|
|
1106
|
+
* `UnknownException` instance for reference, regardless of its type.
|
|
1107
|
+
*
|
|
1108
|
+
* Additionally, if you provide a `message` argument, it is used as the error
|
|
1109
|
+
* message. If no `message` is provided, the error message defaults to `"An
|
|
1110
|
+
* unknown error occurred"`.
|
|
1111
|
+
*
|
|
1112
|
+
* **When to Use**
|
|
1113
|
+
*
|
|
1114
|
+
* Use this function when you need to handle unexpected or unknown errors in
|
|
1115
|
+
* your application, particularly when the source of the error might not provide
|
|
1116
|
+
* a clear message. This is useful for wrapping generic errors thrown from
|
|
1117
|
+
* promises or external APIs.
|
|
1094
1118
|
*
|
|
1095
1119
|
* @since 2.0.0
|
|
1096
1120
|
* @category errors
|
package/src/Cron.ts
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @since 2.0.0
|
|
3
3
|
*/
|
|
4
4
|
import * as Arr from "./Array.js"
|
|
5
|
+
import * as Data from "./Data.js"
|
|
5
6
|
import type * as DateTime from "./DateTime.js"
|
|
6
7
|
import * as Either from "./Either.js"
|
|
7
8
|
import * as Equal from "./Equal.js"
|
|
@@ -202,25 +203,14 @@ export type ParseErrorTypeId = typeof ParseErrorTypeId
|
|
|
202
203
|
* @since 2.0.0
|
|
203
204
|
* @category models
|
|
204
205
|
*/
|
|
205
|
-
export
|
|
206
|
-
readonly _tag: "ParseError"
|
|
207
|
-
readonly [ParseErrorTypeId]: ParseErrorTypeId
|
|
206
|
+
export class ParseError extends Data.TaggedError("CronParseError")<{
|
|
208
207
|
readonly message: string
|
|
209
208
|
readonly input?: string
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
[ParseErrorTypeId]
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const ParseError = (message: string, input?: string): ParseError => {
|
|
218
|
-
const o: Mutable<ParseError> = Object.create(ParseErrorProto)
|
|
219
|
-
o.message = message
|
|
220
|
-
if (input !== undefined) {
|
|
221
|
-
o.input = input
|
|
222
|
-
}
|
|
223
|
-
return o
|
|
209
|
+
}> {
|
|
210
|
+
/**
|
|
211
|
+
* @since 2.0.0
|
|
212
|
+
*/
|
|
213
|
+
readonly [ParseErrorTypeId] = ParseErrorTypeId
|
|
224
214
|
}
|
|
225
215
|
|
|
226
216
|
/**
|
|
@@ -259,7 +249,12 @@ export const isParseError = (u: unknown): u is ParseError => hasProperty(u, Pars
|
|
|
259
249
|
export const parse = (cron: string, tz?: DateTime.TimeZone | string): Either.Either<Cron, ParseError> => {
|
|
260
250
|
const segments = cron.split(" ").filter(String.isNonEmpty)
|
|
261
251
|
if (segments.length !== 5 && segments.length !== 6) {
|
|
262
|
-
return Either.left(
|
|
252
|
+
return Either.left(
|
|
253
|
+
new ParseError({
|
|
254
|
+
message: `Invalid number of segments in cron expression`,
|
|
255
|
+
input: cron
|
|
256
|
+
})
|
|
257
|
+
)
|
|
263
258
|
}
|
|
264
259
|
|
|
265
260
|
if (segments.length === 5) {
|
|
@@ -269,7 +264,11 @@ export const parse = (cron: string, tz?: DateTime.TimeZone | string): Either.Eit
|
|
|
269
264
|
const [seconds, minutes, hours, days, months, weekdays] = segments
|
|
270
265
|
const zone = tz === undefined || dateTime.isTimeZone(tz) ?
|
|
271
266
|
Either.right(tz) :
|
|
272
|
-
Either.fromOption(dateTime.zoneFromString(tz), () =>
|
|
267
|
+
Either.fromOption(dateTime.zoneFromString(tz), () =>
|
|
268
|
+
new ParseError({
|
|
269
|
+
message: `Invalid time zone in cron expression`,
|
|
270
|
+
input: tz
|
|
271
|
+
}))
|
|
273
272
|
|
|
274
273
|
return Either.all({
|
|
275
274
|
tz: zone,
|
|
@@ -639,13 +638,13 @@ const parseSegment = (
|
|
|
639
638
|
|
|
640
639
|
if (step !== undefined) {
|
|
641
640
|
if (!Number.isInteger(step)) {
|
|
642
|
-
return Either.left(ParseError(`Expected step value to be a positive integer`, input))
|
|
641
|
+
return Either.left(new ParseError({ message: `Expected step value to be a positive integer`, input }))
|
|
643
642
|
}
|
|
644
643
|
if (step < 1) {
|
|
645
|
-
return Either.left(ParseError(`Expected step value to be greater than 0`, input))
|
|
644
|
+
return Either.left(new ParseError({ message: `Expected step value to be greater than 0`, input }))
|
|
646
645
|
}
|
|
647
646
|
if (step > options.max) {
|
|
648
|
-
return Either.left(ParseError(`Expected step value to be less than ${options.max}`, input))
|
|
647
|
+
return Either.left(new ParseError({ message: `Expected step value to be less than ${options.max}`, input }))
|
|
649
648
|
}
|
|
650
649
|
}
|
|
651
650
|
|
|
@@ -656,23 +655,27 @@ const parseSegment = (
|
|
|
656
655
|
} else {
|
|
657
656
|
const [left, right] = splitRange(raw, options.aliases)
|
|
658
657
|
if (!Number.isInteger(left)) {
|
|
659
|
-
return Either.left(ParseError(`Expected a positive integer`, input))
|
|
658
|
+
return Either.left(new ParseError({ message: `Expected a positive integer`, input }))
|
|
660
659
|
}
|
|
661
660
|
if (left < options.min || left > options.max) {
|
|
662
|
-
return Either.left(
|
|
661
|
+
return Either.left(
|
|
662
|
+
new ParseError({ message: `Expected a value between ${options.min} and ${options.max}`, input })
|
|
663
|
+
)
|
|
663
664
|
}
|
|
664
665
|
|
|
665
666
|
if (right === undefined) {
|
|
666
667
|
values.add(left)
|
|
667
668
|
} else {
|
|
668
669
|
if (!Number.isInteger(right)) {
|
|
669
|
-
return Either.left(ParseError(`Expected a positive integer`, input))
|
|
670
|
+
return Either.left(new ParseError({ message: `Expected a positive integer`, input }))
|
|
670
671
|
}
|
|
671
672
|
if (right < options.min || right > options.max) {
|
|
672
|
-
return Either.left(
|
|
673
|
+
return Either.left(
|
|
674
|
+
new ParseError({ message: `Expected a value between ${options.min} and ${options.max}`, input })
|
|
675
|
+
)
|
|
673
676
|
}
|
|
674
677
|
if (left > right) {
|
|
675
|
-
return Either.left(ParseError(`Invalid value range`, input))
|
|
678
|
+
return Either.left(new ParseError({ message: `Invalid value range`, input }))
|
|
676
679
|
}
|
|
677
680
|
|
|
678
681
|
for (let i = left; i <= right; i += step ?? 1) {
|
package/src/Duration.ts
CHANGED
|
@@ -41,9 +41,17 @@ export interface Duration extends Equal.Equal, Pipeable, Inspectable {
|
|
|
41
41
|
* @category models
|
|
42
42
|
*/
|
|
43
43
|
export type DurationValue =
|
|
44
|
-
| {
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
| {
|
|
45
|
+
readonly _tag: "Millis"
|
|
46
|
+
readonly millis: number
|
|
47
|
+
}
|
|
48
|
+
| {
|
|
49
|
+
readonly _tag: "Nanos"
|
|
50
|
+
readonly nanos: bigint
|
|
51
|
+
}
|
|
52
|
+
| {
|
|
53
|
+
readonly _tag: "Infinity"
|
|
54
|
+
}
|
|
47
55
|
|
|
48
56
|
/**
|
|
49
57
|
* @since 2.0.0
|
package/src/Effect.ts
CHANGED
|
@@ -15712,13 +15712,14 @@ export {
|
|
|
15712
15712
|
* original effect succeeds, the success value is wrapped in `Option.some`. If
|
|
15713
15713
|
* the effect fails, the failure is converted to `Option.none`.
|
|
15714
15714
|
*
|
|
15715
|
-
* This is useful for
|
|
15716
|
-
* absence of a value
|
|
15717
|
-
* resulting effect
|
|
15718
|
-
*
|
|
15715
|
+
* This is particularly useful for scenarios where you want to represent the
|
|
15716
|
+
* absence of a value explicitly, without causing the resulting effect to fail.
|
|
15717
|
+
* The resulting effect has an error type of `never`, meaning it cannot fail
|
|
15718
|
+
* directly. However, unrecoverable errors, also referred to as defects, are
|
|
15719
|
+
* not captured and will still result in failure.
|
|
15719
15720
|
*
|
|
15720
15721
|
* @see {@link either} for a version that uses `Either` instead.
|
|
15721
|
-
* @see {@link exit} for a version that
|
|
15722
|
+
* @see {@link exit} for a version that encapsulates both recoverable errors and defects in an `Exit`.
|
|
15722
15723
|
*
|
|
15723
15724
|
* @example
|
|
15724
15725
|
* ```ts
|
|
@@ -15768,18 +15769,24 @@ export const option: <A, E, R>(self: Effect<A, E, R>) => Effect<Option.Option<A>
|
|
|
15768
15769
|
*
|
|
15769
15770
|
* This function converts an effect that may fail into an effect that always
|
|
15770
15771
|
* succeeds, wrapping the outcome in an `Either` type. The result will be
|
|
15771
|
-
* `Either.Left` if the effect fails, containing the error, or
|
|
15772
|
-
* it succeeds, containing the result.
|
|
15772
|
+
* `Either.Left` if the effect fails, containing the recoverable error, or
|
|
15773
|
+
* `Either.Right` if it succeeds, containing the result.
|
|
15773
15774
|
*
|
|
15774
|
-
* Using this function, you can handle errors explicitly without
|
|
15775
|
-
* effect to fail. This
|
|
15776
|
-
* chain effects and
|
|
15775
|
+
* Using this function, you can handle recoverable errors explicitly without
|
|
15776
|
+
* causing the effect to fail. This is particularly useful in scenarios where
|
|
15777
|
+
* you want to chain effects and manage both success and failure in the same
|
|
15778
|
+
* logical flow.
|
|
15777
15779
|
*
|
|
15778
|
-
*
|
|
15779
|
-
*
|
|
15780
|
+
* It's important to note that unrecoverable errors, often referred to as
|
|
15781
|
+
* "defects," are still thrown and not captured within the `Either` type. Only
|
|
15782
|
+
* failures that are explicitly represented as recoverable errors in the effect
|
|
15783
|
+
* are encapsulated.
|
|
15784
|
+
*
|
|
15785
|
+
* The resulting effect cannot fail directly because all recoverable failures
|
|
15786
|
+
* are represented inside the `Either` type.
|
|
15780
15787
|
*
|
|
15781
15788
|
* @see {@link option} for a version that uses `Option` instead.
|
|
15782
|
-
* @see {@link exit} for a version that
|
|
15789
|
+
* @see {@link exit} for a version that encapsulates both recoverable errors and defects in an `Exit`.
|
|
15783
15790
|
*
|
|
15784
15791
|
* @example
|
|
15785
15792
|
* ```ts
|
|
@@ -15831,16 +15838,18 @@ export const either: <A, E, R>(self: Effect<A, E, R>) => Effect<Either.Either<A,
|
|
|
15831
15838
|
* **Details**
|
|
15832
15839
|
*
|
|
15833
15840
|
* This function converts an effect into one that always succeeds, wrapping its
|
|
15834
|
-
* outcome in the `Exit` type. The `Exit` type
|
|
15835
|
-
* success (`Exit.Success`) and failure (`Exit.Failure`) cases
|
|
15841
|
+
* outcome in the `Exit` type. The `Exit` type provides explicit handling of
|
|
15842
|
+
* both success (`Exit.Success`) and failure (`Exit.Failure`) cases, including
|
|
15843
|
+
* defects (unrecoverable errors).
|
|
15836
15844
|
*
|
|
15837
|
-
*
|
|
15838
|
-
*
|
|
15839
|
-
*
|
|
15845
|
+
* Unlike {@link either} or {@link option}, this function also encapsulates
|
|
15846
|
+
* defects, which are typically unrecoverable and would otherwise terminate the
|
|
15847
|
+
* effect. With the `Exit` type, defects are represented in `Exit.Failure`,
|
|
15848
|
+
* allowing for detailed introspection and structured error handling.
|
|
15840
15849
|
*
|
|
15841
|
-
* This
|
|
15842
|
-
*
|
|
15843
|
-
* defects and
|
|
15850
|
+
* This makes the resulting effect robust and incapable of direct failure (its
|
|
15851
|
+
* error type is `never`). It is particularly useful for workflows where all
|
|
15852
|
+
* outcomes, including unexpected defects, must be managed and analyzed.
|
|
15844
15853
|
*
|
|
15845
15854
|
* @see {@link option} for a version that uses `Option` instead.
|
|
15846
15855
|
* @see {@link either} for a version that uses `Either` instead.
|
|
@@ -26848,6 +26857,9 @@ export const Tag: <const Id extends string>(id: Id) => <
|
|
|
26848
26857
|
return makeTagProxy(TagClass as any)
|
|
26849
26858
|
}
|
|
26850
26859
|
|
|
26860
|
+
/** @internal */
|
|
26861
|
+
type MissingSelfGeneric = `Missing \`Self\` generic - use \`class Self extends Effect.Service<Self>()...\``
|
|
26862
|
+
|
|
26851
26863
|
/**
|
|
26852
26864
|
* Simplifies the creation and management of services in Effect by defining both
|
|
26853
26865
|
* a `Tag` and a `Layer`.
|
|
@@ -26892,7 +26904,7 @@ export const Tag: <const Id extends string>(id: Id) => <
|
|
|
26892
26904
|
* @category Context
|
|
26893
26905
|
* @experimental might be up for breaking changes
|
|
26894
26906
|
*/
|
|
26895
|
-
export const Service: <Self>() => {
|
|
26907
|
+
export const Service: <Self = never>() => [Self] extends [never] ? MissingSelfGeneric : {
|
|
26896
26908
|
<
|
|
26897
26909
|
const Key extends string,
|
|
26898
26910
|
const Make extends
|
|
@@ -27065,7 +27077,7 @@ export const Service: <Self>() => {
|
|
|
27065
27077
|
|
|
27066
27078
|
return proxy === true ? makeTagProxy(TagClass) : TagClass
|
|
27067
27079
|
}
|
|
27068
|
-
}
|
|
27080
|
+
} as any
|
|
27069
27081
|
|
|
27070
27082
|
/**
|
|
27071
27083
|
* @since 3.9.0
|
package/src/FiberHandle.ts
CHANGED
|
@@ -90,15 +90,15 @@ const unsafeMake = <A = unknown, E = unknown>(
|
|
|
90
90
|
* ```ts
|
|
91
91
|
* import { Effect, FiberHandle } from "effect"
|
|
92
92
|
*
|
|
93
|
-
* Effect.gen(function*(
|
|
94
|
-
* const handle = yield*
|
|
93
|
+
* Effect.gen(function*() {
|
|
94
|
+
* const handle = yield* FiberHandle.make()
|
|
95
95
|
*
|
|
96
96
|
* // run some effects
|
|
97
|
-
* yield*
|
|
97
|
+
* yield* FiberHandle.run(handle, Effect.never)
|
|
98
98
|
* // this will interrupt the previous fiber
|
|
99
|
-
* yield*
|
|
99
|
+
* yield* FiberHandle.run(handle, Effect.never)
|
|
100
100
|
*
|
|
101
|
-
* yield*
|
|
101
|
+
* yield* Effect.sleep(1000)
|
|
102
102
|
* }).pipe(
|
|
103
103
|
* Effect.scoped // The fiber will be interrupted when the scope is closed
|
|
104
104
|
* )
|
|
@@ -434,9 +434,9 @@ export const run: {
|
|
|
434
434
|
* getAll: Effect.Effect<Array<unknown>>
|
|
435
435
|
* }>("Users")
|
|
436
436
|
*
|
|
437
|
-
* Effect.gen(function*(
|
|
438
|
-
* const handle = yield*
|
|
439
|
-
* const run = yield*
|
|
437
|
+
* Effect.gen(function*() {
|
|
438
|
+
* const handle = yield* FiberHandle.make()
|
|
439
|
+
* const run = yield* FiberHandle.runtime(handle)<Users>()
|
|
440
440
|
*
|
|
441
441
|
* // run an effect and set the fiber in the handle
|
|
442
442
|
* run(Effect.andThen(Users, _ => _.getAll))
|