effect 4.0.0-beta.17 → 4.0.0-beta.19

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 (164) hide show
  1. package/dist/Array.d.ts +127 -299
  2. package/dist/Array.d.ts.map +1 -1
  3. package/dist/Array.js +102 -62
  4. package/dist/Array.js.map +1 -1
  5. package/dist/Cache.d.ts.map +1 -1
  6. package/dist/Cache.js +5 -4
  7. package/dist/Cache.js.map +1 -1
  8. package/dist/Channel.d.ts +97 -11
  9. package/dist/Channel.d.ts.map +1 -1
  10. package/dist/Channel.js +72 -29
  11. package/dist/Channel.js.map +1 -1
  12. package/dist/Chunk.d.ts +54 -247
  13. package/dist/Chunk.d.ts.map +1 -1
  14. package/dist/Chunk.js +36 -67
  15. package/dist/Chunk.js.map +1 -1
  16. package/dist/Effect.d.ts +337 -437
  17. package/dist/Effect.d.ts.map +1 -1
  18. package/dist/Effect.js +118 -134
  19. package/dist/Effect.js.map +1 -1
  20. package/dist/Filter.d.ts +0 -33
  21. package/dist/Filter.d.ts.map +1 -1
  22. package/dist/Filter.js +0 -13
  23. package/dist/Filter.js.map +1 -1
  24. package/dist/HashMap.d.ts +15 -14
  25. package/dist/HashMap.d.ts.map +1 -1
  26. package/dist/HashMap.js +4 -4
  27. package/dist/HashMap.js.map +1 -1
  28. package/dist/Iterable.d.ts +40 -39
  29. package/dist/Iterable.d.ts.map +1 -1
  30. package/dist/Iterable.js +94 -22
  31. package/dist/Iterable.js.map +1 -1
  32. package/dist/Option.d.ts +22 -15
  33. package/dist/Option.d.ts.map +1 -1
  34. package/dist/Option.js +14 -7
  35. package/dist/Option.js.map +1 -1
  36. package/dist/Pull.d.ts.map +1 -1
  37. package/dist/Pull.js +1 -1
  38. package/dist/Pull.js.map +1 -1
  39. package/dist/Record.d.ts +24 -120
  40. package/dist/Record.d.ts.map +1 -1
  41. package/dist/Record.js +21 -41
  42. package/dist/Record.js.map +1 -1
  43. package/dist/Sink.d.ts +11 -11
  44. package/dist/Sink.d.ts.map +1 -1
  45. package/dist/Sink.js +53 -6
  46. package/dist/Sink.js.map +1 -1
  47. package/dist/Stream.d.ts +198 -386
  48. package/dist/Stream.d.ts.map +1 -1
  49. package/dist/Stream.js +103 -59
  50. package/dist/Stream.js.map +1 -1
  51. package/dist/Trie.d.ts +18 -17
  52. package/dist/Trie.d.ts.map +1 -1
  53. package/dist/Trie.js +5 -5
  54. package/dist/Trie.js.map +1 -1
  55. package/dist/TxChunk.d.ts +37 -37
  56. package/dist/TxChunk.d.ts.map +1 -1
  57. package/dist/TxChunk.js +3 -3
  58. package/dist/TxChunk.js.map +1 -1
  59. package/dist/TxDeferred.d.ts +328 -0
  60. package/dist/TxDeferred.d.ts.map +1 -0
  61. package/dist/TxDeferred.js +196 -0
  62. package/dist/TxDeferred.js.map +1 -0
  63. package/dist/TxHashMap.d.ts +84 -83
  64. package/dist/TxHashMap.d.ts.map +1 -1
  65. package/dist/TxHashMap.js +24 -24
  66. package/dist/TxHashMap.js.map +1 -1
  67. package/dist/TxHashSet.d.ts +35 -35
  68. package/dist/TxHashSet.d.ts.map +1 -1
  69. package/dist/TxHashSet.js +14 -14
  70. package/dist/TxHashSet.js.map +1 -1
  71. package/dist/TxPriorityQueue.d.ts +609 -0
  72. package/dist/TxPriorityQueue.d.ts.map +1 -0
  73. package/dist/TxPriorityQueue.js +415 -0
  74. package/dist/TxPriorityQueue.js.map +1 -0
  75. package/dist/TxPubSub.d.ts +585 -0
  76. package/dist/TxPubSub.d.ts.map +1 -0
  77. package/dist/TxPubSub.js +521 -0
  78. package/dist/TxPubSub.js.map +1 -0
  79. package/dist/TxQueue.d.ts +32 -32
  80. package/dist/TxQueue.d.ts.map +1 -1
  81. package/dist/TxQueue.js +26 -26
  82. package/dist/TxQueue.js.map +1 -1
  83. package/dist/TxReentrantLock.d.ts +523 -0
  84. package/dist/TxReentrantLock.d.ts.map +1 -0
  85. package/dist/TxReentrantLock.js +504 -0
  86. package/dist/TxReentrantLock.js.map +1 -0
  87. package/dist/TxRef.d.ts +34 -34
  88. package/dist/TxRef.d.ts.map +1 -1
  89. package/dist/TxRef.js +21 -14
  90. package/dist/TxRef.js.map +1 -1
  91. package/dist/TxSemaphore.d.ts +8 -8
  92. package/dist/TxSemaphore.d.ts.map +1 -1
  93. package/dist/TxSemaphore.js +7 -7
  94. package/dist/TxSemaphore.js.map +1 -1
  95. package/dist/TxSubscriptionRef.d.ts +508 -0
  96. package/dist/TxSubscriptionRef.d.ts.map +1 -0
  97. package/dist/TxSubscriptionRef.js +293 -0
  98. package/dist/TxSubscriptionRef.js.map +1 -0
  99. package/dist/index.d.ts +40 -0
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +40 -0
  102. package/dist/index.js.map +1 -1
  103. package/dist/internal/effect.js +99 -42
  104. package/dist/internal/effect.js.map +1 -1
  105. package/dist/internal/hashMap.js +3 -2
  106. package/dist/internal/hashMap.js.map +1 -1
  107. package/dist/internal/trie.js +5 -4
  108. package/dist/internal/trie.js.map +1 -1
  109. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  110. package/dist/unstable/ai/Tool.js +0 -9
  111. package/dist/unstable/ai/Tool.js.map +1 -1
  112. package/dist/unstable/cli/Command.d.ts +1 -1
  113. package/dist/unstable/cli/Command.d.ts.map +1 -1
  114. package/dist/unstable/cli/Command.js +1 -1
  115. package/dist/unstable/cli/Command.js.map +1 -1
  116. package/dist/unstable/cluster/K8sHttpClient.js +4 -4
  117. package/dist/unstable/cluster/K8sHttpClient.js.map +1 -1
  118. package/dist/unstable/cluster/Sharding.js +1 -1
  119. package/dist/unstable/cluster/Sharding.js.map +1 -1
  120. package/dist/unstable/encoding/Sse.js +1 -1
  121. package/dist/unstable/encoding/Sse.js.map +1 -1
  122. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  123. package/dist/unstable/rpc/RpcServer.js +1 -2
  124. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  125. package/dist/unstable/socket/Socket.d.ts.map +1 -1
  126. package/dist/unstable/socket/Socket.js +3 -3
  127. package/dist/unstable/socket/Socket.js.map +1 -1
  128. package/package.json +1 -1
  129. package/src/Array.ts +190 -342
  130. package/src/Cache.ts +6 -5
  131. package/src/Channel.ts +506 -102
  132. package/src/Chunk.ts +81 -268
  133. package/src/Effect.ts +437 -518
  134. package/src/Filter.ts +0 -57
  135. package/src/HashMap.ts +15 -14
  136. package/src/Iterable.ts +105 -50
  137. package/src/Option.ts +30 -20
  138. package/src/Pull.ts +1 -1
  139. package/src/Record.ts +43 -152
  140. package/src/Sink.ts +75 -23
  141. package/src/Stream.ts +442 -502
  142. package/src/Trie.ts +18 -17
  143. package/src/TxChunk.ts +72 -53
  144. package/src/TxDeferred.ts +394 -0
  145. package/src/TxHashMap.ts +332 -285
  146. package/src/TxHashSet.ts +111 -116
  147. package/src/TxPriorityQueue.ts +767 -0
  148. package/src/TxPubSub.ts +789 -0
  149. package/src/TxQueue.ts +241 -251
  150. package/src/TxReentrantLock.ts +753 -0
  151. package/src/TxRef.ts +50 -38
  152. package/src/TxSemaphore.ts +29 -32
  153. package/src/TxSubscriptionRef.ts +639 -0
  154. package/src/index.ts +45 -0
  155. package/src/internal/effect.ts +368 -163
  156. package/src/internal/hashMap.ts +7 -5
  157. package/src/internal/trie.ts +16 -9
  158. package/src/unstable/ai/Tool.ts +0 -9
  159. package/src/unstable/cli/Command.ts +6 -4
  160. package/src/unstable/cluster/K8sHttpClient.ts +4 -4
  161. package/src/unstable/cluster/Sharding.ts +1 -1
  162. package/src/unstable/encoding/Sse.ts +1 -1
  163. package/src/unstable/rpc/RpcServer.ts +1 -7
  164. package/src/unstable/socket/Socket.ts +9 -11
package/src/Option.ts CHANGED
@@ -31,7 +31,7 @@
31
31
  * **Gotchas**
32
32
  *
33
33
  * - `Option.some(null)` is a valid `Some`; use {@link fromNullishOr} to treat `null`/`undefined` as `None`
34
- * - {@link filterMap} is an alias for {@link flatMap}
34
+ * - {@link filterMap} uses a `Filter` callback that returns `Result`
35
35
  * - {@link getOrThrow} throws a generic `Error`; prefer {@link getOrThrowWith} for custom errors
36
36
  * - `None` is a singleton; compare with {@link isNone}, not `===`
37
37
  * - When yielded in `Effect.gen`, a `None` becomes a `NoSuchElementError` defect
@@ -77,6 +77,7 @@ import * as Combiner from "./Combiner.ts"
77
77
  import type { EffectIterator, Yieldable } from "./Effect.ts"
78
78
  import * as Equal from "./Equal.ts"
79
79
  import * as Equivalence from "./Equivalence.ts"
80
+ import type * as Filter from "./Filter.ts"
80
81
  import type { LazyArg } from "./Function.ts"
81
82
  import { constNull, constUndefined, dual, identity } from "./Function.ts"
82
83
  import type { TypeLambda } from "./HKT.ts"
@@ -3441,79 +3442,88 @@ export const partitionMap: {
3441
3442
  return result.isFailure(e) ? [some(e.failure), none()] : [none(), some(e.success)]
3442
3443
  })
3443
3444
 
3444
- // TODO(4.0): remove?
3445
3445
  /**
3446
- * Alias of {@link flatMap}. Applies a function returning `Option` to the value
3447
- * inside a `Some`, flattening the result.
3446
+ * Transforms and filters an `Option` using a `Filter` callback.
3447
+ *
3448
+ * The callback returns a `Result`: `Result.succeed` keeps and transforms the
3449
+ * value, while `Result.fail` discards it.
3448
3450
  *
3449
3451
  * **Example** (Filtering and transforming)
3450
3452
  *
3451
3453
  * ```ts
3452
3454
  * import { Option } from "effect"
3455
+ * import * as Result from "effect/Result"
3453
3456
  *
3454
3457
  * console.log(Option.filterMap(
3455
3458
  * Option.some(2),
3456
- * (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none())
3459
+ * (n) => (n % 2 === 0 ? Result.succeed(`Even: ${n}`) : Result.failVoid)
3457
3460
  * ))
3458
3461
  * // Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }
3459
3462
  * ```
3460
3463
  *
3461
- * @see {@link flatMap} (canonical)
3462
3464
  * @see {@link filter} for predicate-based filtering
3463
3465
  *
3464
3466
  * @category Filtering
3465
3467
  * @since 2.0.0
3466
3468
  */
3467
3469
  export const filterMap: {
3468
- // TODO(4.0): remove?
3469
3470
  /**
3470
- * Alias of {@link flatMap}. Applies a function returning `Option` to the value
3471
- * inside a `Some`, flattening the result.
3471
+ * Transforms and filters an `Option` using a `Filter` callback.
3472
+ *
3473
+ * The callback returns a `Result`: `Result.succeed` keeps and transforms the
3474
+ * value, while `Result.fail` discards it.
3472
3475
  *
3473
3476
  * **Example** (Filtering and transforming)
3474
3477
  *
3475
3478
  * ```ts
3476
3479
  * import { Option } from "effect"
3480
+ * import * as Result from "effect/Result"
3477
3481
  *
3478
3482
  * console.log(Option.filterMap(
3479
3483
  * Option.some(2),
3480
- * (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none())
3484
+ * (n) => (n % 2 === 0 ? Result.succeed(`Even: ${n}`) : Result.failVoid)
3481
3485
  * ))
3482
3486
  * // Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }
3483
3487
  * ```
3484
3488
  *
3485
- * @see {@link flatMap} (canonical)
3486
3489
  * @see {@link filter} for predicate-based filtering
3487
3490
  *
3488
3491
  * @category Filtering
3489
3492
  * @since 2.0.0
3490
3493
  */
3491
- <A, B>(f: (a: A) => Option<B>): (self: Option<A>) => Option<B>
3492
- // TODO(4.0): remove?
3494
+ <A, B, X>(f: Filter.Filter<A, B, X>): (self: Option<A>) => Option<B>
3493
3495
  /**
3494
- * Alias of {@link flatMap}. Applies a function returning `Option` to the value
3495
- * inside a `Some`, flattening the result.
3496
+ * Transforms and filters an `Option` using a `Filter` callback.
3497
+ *
3498
+ * The callback returns a `Result`: `Result.succeed` keeps and transforms the
3499
+ * value, while `Result.fail` discards it.
3496
3500
  *
3497
3501
  * **Example** (Filtering and transforming)
3498
3502
  *
3499
3503
  * ```ts
3500
3504
  * import { Option } from "effect"
3505
+ * import * as Result from "effect/Result"
3501
3506
  *
3502
3507
  * console.log(Option.filterMap(
3503
3508
  * Option.some(2),
3504
- * (n) => (n % 2 === 0 ? Option.some(`Even: ${n}`) : Option.none())
3509
+ * (n) => (n % 2 === 0 ? Result.succeed(`Even: ${n}`) : Result.failVoid)
3505
3510
  * ))
3506
3511
  * // Output: { _id: 'Option', _tag: 'Some', value: 'Even: 2' }
3507
3512
  * ```
3508
3513
  *
3509
- * @see {@link flatMap} (canonical)
3510
3514
  * @see {@link filter} for predicate-based filtering
3511
3515
  *
3512
3516
  * @category Filtering
3513
3517
  * @since 2.0.0
3514
3518
  */
3515
- <A, B>(self: Option<A>, f: (a: A) => Option<B>): Option<B>
3516
- } = flatMap
3519
+ <A, B, X>(self: Option<A>, f: Filter.Filter<A, B, X>): Option<B>
3520
+ } = dual(2, <A, B, X>(self: Option<A>, f: Filter.Filter<A, B, X>): Option<B> => {
3521
+ if (isNone(self)) {
3522
+ return none()
3523
+ }
3524
+ const next = f(self.value)
3525
+ return result.isSuccess(next) ? some(next.success) : none()
3526
+ })
3517
3527
 
3518
3528
  /**
3519
3529
  * Filters an `Option` using a predicate. Returns `None` if the predicate is
@@ -3723,7 +3733,7 @@ export const filter: {
3723
3733
  } = dual(
3724
3734
  2,
3725
3735
  <A>(self: Option<A>, predicate: Predicate<A>): Option<A> =>
3726
- filterMap(self, (b) => (predicate(b) ? option.some(b) : option.none))
3736
+ isNone(self) ? none() : predicate(self.value) ? some(self.value) : none()
3727
3737
  )
3728
3738
 
3729
3739
  /**
package/src/Pull.ts CHANGED
@@ -95,7 +95,7 @@ export const catchDone: {
95
95
  effect: Effect<A, E, R>,
96
96
  f: (leftover: Cause.Done.Extract<E>) => Effect<A2, E2, R2>
97
97
  ): Effect<A | A2, ExcludeDone<E> | E2, R | R2> =>
98
- internalEffect.catchCauseIf(effect, filterDoneLeftover as any, (l: any) => f(l)) as any)
98
+ internalEffect.catchCauseFilter(effect, filterDoneLeftover as any, (l: any) => f(l)) as any)
99
99
 
100
100
  /**
101
101
  * Checks if a Cause contains any done errors.
package/src/Record.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  import type * as Combiner from "./Combiner.ts"
8
8
  import * as Equal from "./Equal.ts"
9
9
  import type { Equivalence } from "./Equivalence.ts"
10
+ import type * as Filter from "./Filter.ts"
10
11
  import { dual, identity } from "./Function.ts"
11
12
  import type { TypeLambda } from "./HKT.ts"
12
13
  import * as Option from "./Option.ts"
@@ -1002,16 +1003,16 @@ export const mapEntries: {
1002
1003
  )
1003
1004
 
1004
1005
  /**
1005
- * Transforms a record into a record by applying the function `f` to each key and value in the original record.
1006
- * If the function returns `Some`, the key-value pair is included in the output record.
1006
+ * Transforms a record by applying the function `f` to each key and value in the original record.
1007
+ * If the function succeeds, the key-value pair is included in the output record.
1007
1008
  *
1008
1009
  * @example
1009
1010
  * ```ts
1010
- * import { Option, Record } from "effect"
1011
+ * import { Record, Result } from "effect"
1011
1012
  * import * as assert from "node:assert"
1012
1013
  *
1013
1014
  * const x = { a: 1, b: 2, c: 3 }
1014
- * const f = (a: number, key: string) => a > 2 ? Option.some(a * 2) : Option.none()
1015
+ * const f = (a: number, key: string) => a > 2 ? Result.succeed(a * 2) : Result.failVoid
1015
1016
  * assert.deepStrictEqual(Record.filterMap(x, f), { c: 6 })
1016
1017
  * ```
1017
1018
  *
@@ -1020,52 +1021,52 @@ export const mapEntries: {
1020
1021
  */
1021
1022
  export const filterMap: {
1022
1023
  /**
1023
- * Transforms a record into a record by applying the function `f` to each key and value in the original record.
1024
- * If the function returns `Some`, the key-value pair is included in the output record.
1024
+ * Transforms a record by applying the function `f` to each key and value in the original record.
1025
+ * If the function succeeds, the key-value pair is included in the output record.
1025
1026
  *
1026
1027
  * @example
1027
1028
  * ```ts
1028
- * import { Option, Record } from "effect"
1029
+ * import { Record, Result } from "effect"
1029
1030
  * import * as assert from "node:assert"
1030
1031
  *
1031
1032
  * const x = { a: 1, b: 2, c: 3 }
1032
- * const f = (a: number, key: string) => a > 2 ? Option.some(a * 2) : Option.none()
1033
+ * const f = (a: number, key: string) => a > 2 ? Result.succeed(a * 2) : Result.failVoid
1033
1034
  * assert.deepStrictEqual(Record.filterMap(x, f), { c: 6 })
1034
1035
  * ```
1035
1036
  *
1036
1037
  * @category filtering
1037
1038
  * @since 2.0.0
1038
1039
  */
1039
- <K extends string, A, B>(f: (a: A, key: K) => Option.Option<B>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>
1040
+ <K extends string, A, B, X>(f: Filter.Filter<A, B, X, [key: K]>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>
1040
1041
  /**
1041
- * Transforms a record into a record by applying the function `f` to each key and value in the original record.
1042
- * If the function returns `Some`, the key-value pair is included in the output record.
1042
+ * Transforms a record by applying the function `f` to each key and value in the original record.
1043
+ * If the function succeeds, the key-value pair is included in the output record.
1043
1044
  *
1044
1045
  * @example
1045
1046
  * ```ts
1046
- * import { Option, Record } from "effect"
1047
+ * import { Record, Result } from "effect"
1047
1048
  * import * as assert from "node:assert"
1048
1049
  *
1049
1050
  * const x = { a: 1, b: 2, c: 3 }
1050
- * const f = (a: number, key: string) => a > 2 ? Option.some(a * 2) : Option.none()
1051
+ * const f = (a: number, key: string) => a > 2 ? Result.succeed(a * 2) : Result.failVoid
1051
1052
  * assert.deepStrictEqual(Record.filterMap(x, f), { c: 6 })
1052
1053
  * ```
1053
1054
  *
1054
1055
  * @category filtering
1055
1056
  * @since 2.0.0
1056
1057
  */
1057
- <K extends string, A, B>(self: ReadonlyRecord<K, A>, f: (a: A, key: K) => Option.Option<B>): Record<ReadonlyRecord.NonLiteralKey<K>, B>
1058
+ <K extends string, A, B, X>(self: ReadonlyRecord<K, A>, f: Filter.Filter<A, B, X, [key: K]>): Record<ReadonlyRecord.NonLiteralKey<K>, B>
1058
1059
  } = dual(
1059
1060
  2,
1060
- <K extends string, A, B>(
1061
+ <K extends string, A, B, X>(
1061
1062
  self: ReadonlyRecord<K, A>,
1062
- f: (a: A, key: K) => Option.Option<B>
1063
+ f: Filter.Filter<A, B, X, [key: K]>
1063
1064
  ): Record<ReadonlyRecord.NonLiteralKey<K>, B> => {
1064
1065
  const out: Record<string, B> = empty()
1065
1066
  for (const key of keys(self)) {
1066
- const o = f(self[key], key)
1067
- if (Option.isSome(o)) {
1068
- out[key] = o.value
1067
+ const result = f(self[key], key)
1068
+ if (R.isSuccess(result)) {
1069
+ out[key] = result.success
1069
1070
  }
1070
1071
  }
1071
1072
  return out
@@ -1187,9 +1188,18 @@ export const filter: {
1187
1188
  */
1188
1189
  export const getSomes: <K extends string, A>(
1189
1190
  self: ReadonlyRecord<K, Option.Option<A>>
1190
- ) => Record<ReadonlyRecord.NonLiteralKey<K>, A> = filterMap(
1191
- identity
1192
- )
1191
+ ) => Record<ReadonlyRecord.NonLiteralKey<K>, A> = <K extends string, A>(
1192
+ self: ReadonlyRecord<K, Option.Option<A>>
1193
+ ): Record<ReadonlyRecord.NonLiteralKey<K>, A> => {
1194
+ const out: Record<string, A> = empty()
1195
+ for (const key of keys(self)) {
1196
+ const option = self[key]
1197
+ if (Option.isSome(option)) {
1198
+ out[key] = option.value
1199
+ }
1200
+ }
1201
+ return out
1202
+ }
1193
1203
 
1194
1204
  /**
1195
1205
  * Given a record with `Result` values, returns a new record containing only the `Err` values, preserving the original keys.
@@ -1262,7 +1272,7 @@ export const getSuccesses = <K extends string, A, E>(
1262
1272
  }
1263
1273
 
1264
1274
  /**
1265
- * Partitions the elements of a record into two groups: those that match a predicate, and those that don't.
1275
+ * Partitions the elements of a record into two groups: those that match a filter, and those that don't.
1266
1276
  *
1267
1277
  * @example
1268
1278
  * ```ts
@@ -1271,15 +1281,15 @@ export const getSuccesses = <K extends string, A, E>(
1271
1281
  *
1272
1282
  * const x = { a: 1, b: 2, c: 3 }
1273
1283
  * const f = (n: number) => (n % 2 === 0 ? Result.succeed(n) : Result.fail(n))
1274
- * assert.deepStrictEqual(Record.partitionMap(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1284
+ * assert.deepStrictEqual(Record.partition(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1275
1285
  * ```
1276
1286
  *
1277
1287
  * @category filtering
1278
1288
  * @since 2.0.0
1279
1289
  */
1280
- export const partitionMap: {
1290
+ export const partition: {
1281
1291
  /**
1282
- * Partitions the elements of a record into two groups: those that match a predicate, and those that don't.
1292
+ * Partitions the elements of a record into two groups: those that match a filter, and those that don't.
1283
1293
  *
1284
1294
  * @example
1285
1295
  * ```ts
@@ -1288,17 +1298,17 @@ export const partitionMap: {
1288
1298
  *
1289
1299
  * const x = { a: 1, b: 2, c: 3 }
1290
1300
  * const f = (n: number) => (n % 2 === 0 ? Result.succeed(n) : Result.fail(n))
1291
- * assert.deepStrictEqual(Record.partitionMap(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1301
+ * assert.deepStrictEqual(Record.partition(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1292
1302
  * ```
1293
1303
  *
1294
1304
  * @category filtering
1295
1305
  * @since 2.0.0
1296
1306
  */
1297
- <K extends string, A, B, C>(f: (a: A, key: K) => Result<C, B>): (
1307
+ <K extends string, A, B, C>(f: Filter.Filter<A, C, B, [key: K]>): (
1298
1308
  self: ReadonlyRecord<K, A>
1299
1309
  ) => [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]
1300
1310
  /**
1301
- * Partitions the elements of a record into two groups: those that match a predicate, and those that don't.
1311
+ * Partitions the elements of a record into two groups: those that match a filter, and those that don't.
1302
1312
  *
1303
1313
  * @example
1304
1314
  * ```ts
@@ -1307,18 +1317,18 @@ export const partitionMap: {
1307
1317
  *
1308
1318
  * const x = { a: 1, b: 2, c: 3 }
1309
1319
  * const f = (n: number) => (n % 2 === 0 ? Result.succeed(n) : Result.fail(n))
1310
- * assert.deepStrictEqual(Record.partitionMap(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1320
+ * assert.deepStrictEqual(Record.partition(x, f), [{ a: 1, c: 3 }, { b: 2 }])
1311
1321
  * ```
1312
1322
  *
1313
1323
  * @category filtering
1314
1324
  * @since 2.0.0
1315
1325
  */
1316
- <K extends string, A, B, C>(self: ReadonlyRecord<K, A>, f: (a: A, key: K) => Result<C, B>): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]
1326
+ <K extends string, A, B, C>(self: ReadonlyRecord<K, A>, f: Filter.Filter<A, C, B, [key: K]>): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]
1317
1327
  } = dual(
1318
1328
  2,
1319
1329
  <K extends string, A, B, C>(
1320
1330
  self: ReadonlyRecord<K, A>,
1321
- f: (a: A, key: K) => Result<C, B>
1331
+ f: Filter.Filter<A, C, B, [key: K]>
1322
1332
  ): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>] => {
1323
1333
  const left: Record<string, B> = empty()
1324
1334
  const right: Record<string, C> = empty()
@@ -1354,126 +1364,7 @@ export const partitionMap: {
1354
1364
  */
1355
1365
  export const separate: <K extends string, A, B>(
1356
1366
  self: ReadonlyRecord<K, Result<B, A>>
1357
- ) => [Record<ReadonlyRecord.NonLiteralKey<K>, A>, Record<ReadonlyRecord.NonLiteralKey<K>, B>] = partitionMap(identity)
1358
-
1359
- /**
1360
- * Partitions a record into two separate records based on the result of a predicate function.
1361
- *
1362
- * @example
1363
- * ```ts
1364
- * import { Record } from "effect"
1365
- * import * as assert from "node:assert"
1366
- *
1367
- * assert.deepStrictEqual(
1368
- * Record.partition({ a: 1, b: 3 }, (n) => n > 2),
1369
- * [{ a: 1 }, { b: 3 }]
1370
- * )
1371
- * ```
1372
- *
1373
- * @category filtering
1374
- * @since 2.0.0
1375
- */
1376
- export const partition: {
1377
- /**
1378
- * Partitions a record into two separate records based on the result of a predicate function.
1379
- *
1380
- * @example
1381
- * ```ts
1382
- * import { Record } from "effect"
1383
- * import * as assert from "node:assert"
1384
- *
1385
- * assert.deepStrictEqual(
1386
- * Record.partition({ a: 1, b: 3 }, (n) => n > 2),
1387
- * [{ a: 1 }, { b: 3 }]
1388
- * )
1389
- * ```
1390
- *
1391
- * @category filtering
1392
- * @since 2.0.0
1393
- */
1394
- <K extends string, A, B extends A>(refinement: (a: NoInfer<A>, key: K) => a is B): (
1395
- self: ReadonlyRecord<K, A>
1396
- ) => [
1397
- excluded: Record<ReadonlyRecord.NonLiteralKey<K>, Exclude<A, B>>,
1398
- satisfying: Record<ReadonlyRecord.NonLiteralKey<K>, B>
1399
- ]
1400
- /**
1401
- * Partitions a record into two separate records based on the result of a predicate function.
1402
- *
1403
- * @example
1404
- * ```ts
1405
- * import { Record } from "effect"
1406
- * import * as assert from "node:assert"
1407
- *
1408
- * assert.deepStrictEqual(
1409
- * Record.partition({ a: 1, b: 3 }, (n) => n > 2),
1410
- * [{ a: 1 }, { b: 3 }]
1411
- * )
1412
- * ```
1413
- *
1414
- * @category filtering
1415
- * @since 2.0.0
1416
- */
1417
- <K extends string, A>(predicate: (a: NoInfer<A>, key: K) => boolean): (
1418
- self: ReadonlyRecord<K, A>
1419
- ) => [excluded: Record<ReadonlyRecord.NonLiteralKey<K>, A>, satisfying: Record<ReadonlyRecord.NonLiteralKey<K>, A>]
1420
- /**
1421
- * Partitions a record into two separate records based on the result of a predicate function.
1422
- *
1423
- * @example
1424
- * ```ts
1425
- * import { Record } from "effect"
1426
- * import * as assert from "node:assert"
1427
- *
1428
- * assert.deepStrictEqual(
1429
- * Record.partition({ a: 1, b: 3 }, (n) => n > 2),
1430
- * [{ a: 1 }, { b: 3 }]
1431
- * )
1432
- * ```
1433
- *
1434
- * @category filtering
1435
- * @since 2.0.0
1436
- */
1437
- <K extends string, A, B extends A>(self: ReadonlyRecord<K, A>, refinement: (a: A, key: K) => a is B): [
1438
- excluded: Record<ReadonlyRecord.NonLiteralKey<K>, Exclude<A, B>>,
1439
- satisfying: Record<ReadonlyRecord.NonLiteralKey<K>, B>
1440
- ]
1441
- /**
1442
- * Partitions a record into two separate records based on the result of a predicate function.
1443
- *
1444
- * @example
1445
- * ```ts
1446
- * import { Record } from "effect"
1447
- * import * as assert from "node:assert"
1448
- *
1449
- * assert.deepStrictEqual(
1450
- * Record.partition({ a: 1, b: 3 }, (n) => n > 2),
1451
- * [{ a: 1 }, { b: 3 }]
1452
- * )
1453
- * ```
1454
- *
1455
- * @category filtering
1456
- * @since 2.0.0
1457
- */
1458
- <K extends string, A>(self: ReadonlyRecord<K, A>, predicate: (a: A, key: K) => boolean): [excluded: Record<ReadonlyRecord.NonLiteralKey<K>, A>, satisfying: Record<ReadonlyRecord.NonLiteralKey<K>, A>]
1459
- } = dual(
1460
- 2,
1461
- <K extends string, A>(
1462
- self: ReadonlyRecord<K, A>,
1463
- predicate: (a: A, key: K) => boolean
1464
- ): [excluded: Record<ReadonlyRecord.NonLiteralKey<K>, A>, satisfying: Record<ReadonlyRecord.NonLiteralKey<K>, A>] => {
1465
- const left: Record<string, A> = empty()
1466
- const right: Record<string, A> = empty()
1467
- for (const key of keys(self)) {
1468
- if (predicate(self[key], key)) {
1469
- right[key] = self[key]
1470
- } else {
1471
- left[key] = self[key]
1472
- }
1473
- }
1474
- return [left, right]
1475
- }
1476
- )
1367
+ ) => [Record<ReadonlyRecord.NonLiteralKey<K>, A>, Record<ReadonlyRecord.NonLiteralKey<K>, B>] = partition(identity)
1477
1368
 
1478
1369
  /**
1479
1370
  * Retrieve the keys of a given record as an array.
package/src/Sink.ts CHANGED
@@ -9,7 +9,7 @@ import * as Clock from "./Clock.ts"
9
9
  import * as Duration from "./Duration.ts"
10
10
  import * as Effect from "./Effect.ts"
11
11
  import * as Exit from "./Exit.ts"
12
- import * as Filter from "./Filter.ts"
12
+ import type * as Filter from "./Filter.ts"
13
13
  import type { LazyArg } from "./Function.ts"
14
14
  import { constant, constFalse, constTrue, constVoid, dual, identity, pipe } from "./Function.ts"
15
15
  import * as internalStream from "./internal/stream.ts"
@@ -1454,18 +1454,40 @@ export const takeWhile: {
1454
1454
  * @category constructors
1455
1455
  */
1456
1456
  <In>(predicate: Predicate<In>): Sink<Array<In>, In, In>
1457
- /**
1458
- * @since 4.0.0
1459
- * @category constructors
1460
- */
1461
- <In, Out, X>(filter: Filter.Filter<In, Out, X>): Sink<Array<Out>, In, In>
1462
- } = <In>(filter: Filter.Filter<In, any, any> | Predicate<In>): Sink<Array<any>, In, In> =>
1457
+ } = <In>(predicate: Predicate<In>): Sink<Array<In>, In, In> =>
1463
1458
  fromTransform((upstream) => {
1464
- const out = Arr.empty<any>()
1459
+ const out = Arr.empty<In>()
1465
1460
  return upstream.pipe(
1466
1461
  Effect.flatMap((arr) => {
1467
1462
  for (let i = 0; i < arr.length; i++) {
1468
- const result = Filter.apply(filter as any, arr[i])
1463
+ if (!predicate(arr[i])) {
1464
+ const leftover: Arr.NonEmptyReadonlyArray<In> | undefined = (i + 1) < arr.length
1465
+ ? arr.slice(i + 1) as any
1466
+ : undefined
1467
+ return Cause.done([out, leftover] as const)
1468
+ }
1469
+ out.push(arr[i])
1470
+ }
1471
+ return Effect.void
1472
+ }),
1473
+ Effect.forever({ disableYield: true }),
1474
+ Pull.catchDone((end) => Effect.succeed<End<Array<In>, In>>(end ?? [out]))
1475
+ )
1476
+ })
1477
+
1478
+ /**
1479
+ * @since 4.0.0
1480
+ * @category constructors
1481
+ */
1482
+ export const takeWhileFilter = <In, Out, X>(
1483
+ filter: Filter.Filter<In, Out, X>
1484
+ ): Sink<Array<Out>, In, In> =>
1485
+ fromTransform((upstream) => {
1486
+ const out = Arr.empty<Out>()
1487
+ return upstream.pipe(
1488
+ Effect.flatMap((arr) => {
1489
+ for (let i = 0; i < arr.length; i++) {
1490
+ const result = filter(arr[i])
1469
1491
  if (Result.isFailure(result)) {
1470
1492
  const leftover: Arr.NonEmptyReadonlyArray<In> | undefined = (i + 1) < arr.length
1471
1493
  ? arr.slice(i + 1) as any
@@ -1477,7 +1499,7 @@ export const takeWhile: {
1477
1499
  return Effect.void
1478
1500
  }),
1479
1501
  Effect.forever({ disableYield: true }),
1480
- Pull.catchDone((end) => Effect.succeed<End<Array<any>, In>>(end ?? [out]))
1502
+ Pull.catchDone((end) => Effect.succeed<End<Array<Out>, In>>(end ?? [out]))
1481
1503
  )
1482
1504
  })
1483
1505
 
@@ -1491,27 +1513,57 @@ export const takeWhileEffect: {
1491
1513
  * @category constructors
1492
1514
  */
1493
1515
  <In, E, R>(predicate: (input: In) => Effect.Effect<boolean, E, R>): Sink<Array<In>, In, In, E, R>
1494
- /**
1495
- * @since 4.0.0
1496
- * @category constructors
1497
- */
1498
- <In, Out, X, E, R>(filter: Filter.FilterEffect<In, Out, X, E, R>): Sink<Array<Out>, In, In, E, R>
1499
- } = <In, Out, X, E, R>(
1500
- filter: Filter.FilterEffect<In, Out, X, E, R> | ((input: In) => Effect.Effect<boolean, E, R>)
1516
+ } = <In, E, R>(
1517
+ predicate: (input: In) => Effect.Effect<boolean, E, R>
1518
+ ): Sink<Array<In>, In, In, E, R> =>
1519
+ fromTransform((upstream) => {
1520
+ const out = Arr.empty<In>()
1521
+ let leftover: Arr.NonEmptyReadonlyArray<In> | undefined = undefined
1522
+ return upstream.pipe(
1523
+ Effect.flatMap((arr) => {
1524
+ let i = 0
1525
+ return Effect.whileLoop({
1526
+ while: () => i < arr.length,
1527
+ body: constant(Effect.flatMap(
1528
+ Effect.suspend(() => {
1529
+ const input = arr[i++]
1530
+ return Effect.map(predicate(input), (passes) => [input, passes] as const)
1531
+ }),
1532
+ ([input, passes]) => {
1533
+ if (!passes) {
1534
+ if (i < arr.length) {
1535
+ leftover = arr.slice(i) as any
1536
+ }
1537
+ return Cause.done()
1538
+ }
1539
+ out.push(input)
1540
+ return Effect.void
1541
+ }
1542
+ )),
1543
+ step: constVoid
1544
+ })
1545
+ }),
1546
+ Effect.forever({ disableYield: true }),
1547
+ Pull.catchDone(() => Effect.succeed([out, leftover] as const))
1548
+ )
1549
+ })
1550
+
1551
+ /**
1552
+ * @since 4.0.0
1553
+ * @category constructors
1554
+ */
1555
+ export const takeWhileFilterEffect = <In, Out, X, E, R>(
1556
+ filter: Filter.FilterEffect<In, Out, X, E, R>
1501
1557
  ): Sink<Array<Out>, In, In, E, R> =>
1502
1558
  fromTransform((upstream) => {
1503
- const f: Filter.FilterEffect<In, any, any, E, R> = (input: In) =>
1504
- Effect.map((filter as any)(input), (b: any) =>
1505
- typeof b === "boolean" ? (b ? Result.succeed(input) : Result.fail(undefined)) : b)
1506
1559
  const out = Arr.empty<Out>()
1507
1560
  let leftover: Arr.NonEmptyReadonlyArray<In> | undefined = undefined
1508
1561
  return upstream.pipe(
1509
1562
  Effect.flatMap((arr) => {
1510
1563
  let i = 0
1511
1564
  return Effect.whileLoop({
1512
- while: () =>
1513
- i < arr.length,
1514
- body: constant(Effect.flatMap(Effect.suspend(() => f(arr[i++])), (result) => {
1565
+ while: () => i < arr.length,
1566
+ body: constant(Effect.flatMap(Effect.suspend(() => filter(arr[i++])), (result) => {
1515
1567
  if (Result.isFailure(result)) {
1516
1568
  if (i < arr.length) {
1517
1569
  leftover = arr.slice(i) as any