effect 4.0.0-beta.21 → 4.0.0-beta.23

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 (89) hide show
  1. package/dist/Array.d.ts +8 -9
  2. package/dist/Array.d.ts.map +1 -1
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Chunk.d.ts +4 -4
  5. package/dist/Chunk.d.ts.map +1 -1
  6. package/dist/Chunk.js.map +1 -1
  7. package/dist/Duration.d.ts +1 -1
  8. package/dist/Duration.d.ts.map +1 -1
  9. package/dist/Duration.js +1 -1
  10. package/dist/Duration.js.map +1 -1
  11. package/dist/Effect.d.ts +2 -2
  12. package/dist/Effect.d.ts.map +1 -1
  13. package/dist/Effect.js.map +1 -1
  14. package/dist/Filter.d.ts +4 -4
  15. package/dist/Filter.d.ts.map +1 -1
  16. package/dist/Filter.js.map +1 -1
  17. package/dist/HashMap.d.ts +3 -3
  18. package/dist/HashMap.d.ts.map +1 -1
  19. package/dist/HashMap.js.map +1 -1
  20. package/dist/Iterable.d.ts +4 -5
  21. package/dist/Iterable.d.ts.map +1 -1
  22. package/dist/Iterable.js.map +1 -1
  23. package/dist/Record.d.ts +4 -5
  24. package/dist/Record.d.ts.map +1 -1
  25. package/dist/Record.js.map +1 -1
  26. package/dist/Runtime.d.ts.map +1 -1
  27. package/dist/Runtime.js +7 -1
  28. package/dist/Runtime.js.map +1 -1
  29. package/dist/SchemaAST.d.ts.map +1 -1
  30. package/dist/SchemaAST.js +4 -0
  31. package/dist/SchemaAST.js.map +1 -1
  32. package/dist/Stream.d.ts +7 -1
  33. package/dist/Stream.d.ts.map +1 -1
  34. package/dist/Stream.js +5 -1
  35. package/dist/Stream.js.map +1 -1
  36. package/dist/Trie.d.ts +3 -3
  37. package/dist/Trie.d.ts.map +1 -1
  38. package/dist/Trie.js.map +1 -1
  39. package/dist/TxHashMap.d.ts +3 -3
  40. package/dist/TxHashMap.d.ts.map +1 -1
  41. package/dist/TxHashMap.js.map +1 -1
  42. package/dist/internal/effect.js +10 -38
  43. package/dist/internal/effect.js.map +1 -1
  44. package/dist/internal/hashMap.js.map +1 -1
  45. package/dist/internal/schema/representation.js +39 -102
  46. package/dist/internal/schema/representation.js.map +1 -1
  47. package/dist/internal/trie.js.map +1 -1
  48. package/dist/unstable/ai/Chat.d.ts +2 -2
  49. package/dist/unstable/ai/Chat.d.ts.map +1 -1
  50. package/dist/unstable/ai/Chat.js +35 -42
  51. package/dist/unstable/ai/Chat.js.map +1 -1
  52. package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
  53. package/dist/unstable/ai/LanguageModel.js.map +1 -1
  54. package/dist/unstable/ai/Tool.d.ts +1 -1
  55. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  56. package/dist/unstable/httpapi/HttpApiClient.d.ts +55 -0
  57. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  58. package/dist/unstable/httpapi/HttpApiClient.js +37 -0
  59. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  60. package/dist/unstable/httpapi/OpenApi.js +1 -1
  61. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  62. package/dist/unstable/schema/VariantSchema.d.ts +2 -2
  63. package/dist/unstable/schema/VariantSchema.d.ts.map +1 -1
  64. package/dist/unstable/schema/VariantSchema.js +3 -3
  65. package/dist/unstable/schema/VariantSchema.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/Array.ts +15 -13
  68. package/src/Chunk.ts +6 -6
  69. package/src/Duration.ts +2 -2
  70. package/src/Effect.ts +4 -2
  71. package/src/Filter.ts +4 -5
  72. package/src/HashMap.ts +3 -3
  73. package/src/Iterable.ts +6 -7
  74. package/src/Record.ts +6 -7
  75. package/src/Runtime.ts +7 -1
  76. package/src/SchemaAST.ts +5 -0
  77. package/src/Stream.ts +12 -3
  78. package/src/Trie.ts +3 -3
  79. package/src/TxHashMap.ts +4 -4
  80. package/src/internal/effect.ts +27 -53
  81. package/src/internal/hashMap.ts +3 -4
  82. package/src/internal/schema/representation.ts +36 -90
  83. package/src/internal/trie.ts +3 -4
  84. package/src/unstable/ai/Chat.ts +36 -51
  85. package/src/unstable/ai/LanguageModel.ts +0 -1
  86. package/src/unstable/ai/Tool.ts +1 -1
  87. package/src/unstable/httpapi/HttpApiClient.ts +82 -1
  88. package/src/unstable/httpapi/OpenApi.ts +1 -1
  89. package/src/unstable/schema/VariantSchema.ts +3 -3
package/src/Iterable.ts CHANGED
@@ -32,7 +32,6 @@
32
32
 
33
33
  import type { NonEmptyArray } from "./Array.ts"
34
34
  import * as Equal from "./Equal.ts"
35
- import type * as Filter from "./Filter.ts"
36
35
  import { dual } from "./Function.ts"
37
36
  import type { Option } from "./Option.ts"
38
37
  import * as O from "./Option.ts"
@@ -3205,7 +3204,7 @@ export const filterMap: {
3205
3204
  * @category filtering
3206
3205
  * @since 2.0.0
3207
3206
  */
3208
- <A, B, X>(f: Filter.Filter<A, B, X, [i: number]>): (self: Iterable<A>) => Iterable<B>
3207
+ <A, B, X>(f: (input: A, i: number) => Result<B, X>): (self: Iterable<A>) => Iterable<B>
3209
3208
  /**
3210
3209
  * Transforms elements of an iterable using a function that returns a `Result`, keeping only successful values.
3211
3210
  *
@@ -3251,10 +3250,10 @@ export const filterMap: {
3251
3250
  * @category filtering
3252
3251
  * @since 2.0.0
3253
3252
  */
3254
- <A, B, X>(self: Iterable<A>, f: Filter.Filter<A, B, X, [i: number]>): Iterable<B>
3253
+ <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Iterable<B>
3255
3254
  } = dual(
3256
3255
  2,
3257
- <A, B, X>(self: Iterable<A>, f: Filter.Filter<A, B, X, [i: number]>): Iterable<B> => ({
3256
+ <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Iterable<B> => ({
3258
3257
  [Symbol.iterator]() {
3259
3258
  const iterator = self[Symbol.iterator]()
3260
3259
  let i = 0
@@ -3348,7 +3347,7 @@ export const filterMapWhile: {
3348
3347
  * @category filtering
3349
3348
  * @since 2.0.0
3350
3349
  */
3351
- <A, B, X>(f: Filter.Filter<A, B, X, [i: number]>): (self: Iterable<A>) => Iterable<B>
3350
+ <A, B, X>(f: (input: A, i: number) => Result<B, X>): (self: Iterable<A>) => Iterable<B>
3352
3351
  /**
3353
3352
  * Transforms all elements of the `Iterable` for as long as the specified function succeeds.
3354
3353
  *
@@ -3385,8 +3384,8 @@ export const filterMapWhile: {
3385
3384
  * @category filtering
3386
3385
  * @since 2.0.0
3387
3386
  */
3388
- <A, B, X>(self: Iterable<A>, f: Filter.Filter<A, B, X, [i: number]>): Iterable<B>
3389
- } = dual(2, <A, B, X>(self: Iterable<A>, f: Filter.Filter<A, B, X, [i: number]>) => ({
3387
+ <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Iterable<B>
3388
+ } = dual(2, <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>) => ({
3390
3389
  [Symbol.iterator]() {
3391
3390
  const iterator = self[Symbol.iterator]()
3392
3391
  let i = 0
package/src/Record.ts CHANGED
@@ -7,7 +7,6 @@
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"
11
10
  import { dual, identity } from "./Function.ts"
12
11
  import type { TypeLambda } from "./HKT.ts"
13
12
  import * as Option from "./Option.ts"
@@ -1037,7 +1036,7 @@ export const filterMap: {
1037
1036
  * @category filtering
1038
1037
  * @since 2.0.0
1039
1038
  */
1040
- <K extends string, A, B, X>(f: Filter.Filter<A, B, X, [key: K]>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>
1039
+ <K extends string, A, B, X>(f: (input: A, key: K) => Result<B, X>): (self: ReadonlyRecord<K, A>) => Record<ReadonlyRecord.NonLiteralKey<K>, B>
1041
1040
  /**
1042
1041
  * Transforms a record by applying the function `f` to each key and value in the original record.
1043
1042
  * If the function succeeds, the key-value pair is included in the output record.
@@ -1055,12 +1054,12 @@ export const filterMap: {
1055
1054
  * @category filtering
1056
1055
  * @since 2.0.0
1057
1056
  */
1058
- <K extends string, A, B, X>(self: ReadonlyRecord<K, A>, f: Filter.Filter<A, B, X, [key: K]>): Record<ReadonlyRecord.NonLiteralKey<K>, B>
1057
+ <K extends string, A, B, X>(self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<B, X>): Record<ReadonlyRecord.NonLiteralKey<K>, B>
1059
1058
  } = dual(
1060
1059
  2,
1061
1060
  <K extends string, A, B, X>(
1062
1061
  self: ReadonlyRecord<K, A>,
1063
- f: Filter.Filter<A, B, X, [key: K]>
1062
+ f: (input: A, key: K) => Result<B, X>
1064
1063
  ): Record<ReadonlyRecord.NonLiteralKey<K>, B> => {
1065
1064
  const out: Record<string, B> = empty()
1066
1065
  for (const key of keys(self)) {
@@ -1304,7 +1303,7 @@ export const partition: {
1304
1303
  * @category filtering
1305
1304
  * @since 2.0.0
1306
1305
  */
1307
- <K extends string, A, B, C>(f: Filter.Filter<A, C, B, [key: K]>): (
1306
+ <K extends string, A, B, C>(f: (input: A, key: K) => Result<C, B>): (
1308
1307
  self: ReadonlyRecord<K, A>
1309
1308
  ) => [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]
1310
1309
  /**
@@ -1323,12 +1322,12 @@ export const partition: {
1323
1322
  * @category filtering
1324
1323
  * @since 2.0.0
1325
1324
  */
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>]
1325
+ <K extends string, A, B, C>(self: ReadonlyRecord<K, A>, f: (input: A, key: K) => Result<C, B>): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>]
1327
1326
  } = dual(
1328
1327
  2,
1329
1328
  <K extends string, A, B, C>(
1330
1329
  self: ReadonlyRecord<K, A>,
1331
- f: Filter.Filter<A, C, B, [key: K]>
1330
+ f: (input: A, key: K) => Result<C, B>
1332
1331
  ): [left: Record<ReadonlyRecord.NonLiteralKey<K>, B>, right: Record<ReadonlyRecord.NonLiteralKey<K>, C>] => {
1333
1332
  const left: Record<string, B> = empty()
1334
1333
  const right: Record<string, C> = empty()
package/src/Runtime.ts CHANGED
@@ -29,7 +29,7 @@
29
29
  import * as Cause from "effect/Cause"
30
30
  import * as Effect from "effect/Effect"
31
31
  import * as Exit from "effect/Exit"
32
- import { dual } from "effect/Function"
32
+ import { constVoid, dual } from "effect/Function"
33
33
  import type * as Fiber from "./Fiber.ts"
34
34
 
35
35
  /**
@@ -212,6 +212,12 @@ export const makeRunMain = (
212
212
  return Effect.logError(cause)
213
213
  })
214
214
  )
215
+ try {
216
+ const keepAlive = globalThis.setInterval(constVoid, 2_147_483_647)
217
+ fiber.addObserver(() => {
218
+ clearInterval(keepAlive)
219
+ })
220
+ } catch {}
215
221
  const teardown = options?.teardown ?? defaultTeardown
216
222
  return f({ fiber, teardown })
217
223
  })
package/src/SchemaAST.ts CHANGED
@@ -2640,6 +2640,11 @@ export function replaceContext<A extends AST>(ast: A, context: Context | undefin
2640
2640
  })
2641
2641
  }
2642
2642
 
2643
+ /** @internal */
2644
+ export function getLastEncoding(ast: AST): AST {
2645
+ return ast.encoding ? getLastEncoding(ast.encoding[ast.encoding.length - 1].to) : ast
2646
+ }
2647
+
2643
2648
  /** @internal */
2644
2649
  export function annotate<A extends AST>(ast: A, annotations: Schema.Annotations.Annotations): A {
2645
2650
  if (ast.checks) {
package/src/Stream.ts CHANGED
@@ -963,6 +963,10 @@ export const fromIteratorSucceed = <A>(iterator: IterableIterator<A>, maxChunkSi
963
963
  /**
964
964
  * Creates a new `Stream` from an iterable collection of values.
965
965
  *
966
+ * **Options**
967
+ *
968
+ * - `chunkSize`: Maximum number of values emitted per chunk.
969
+ *
966
970
  * @example
967
971
  * ```ts
968
972
  * import { Console, Effect, Stream } from "effect"
@@ -982,10 +986,15 @@ export const fromIteratorSucceed = <A>(iterator: IterableIterator<A>, maxChunkSi
982
986
  * @since 2.0.0
983
987
  * @category Constructors
984
988
  */
985
- export const fromIterable = <A>(iterable: Iterable<A>): Stream<A> =>
986
- Array.isArray(iterable)
989
+ export const fromIterable = <A>(
990
+ iterable: Iterable<A>,
991
+ options?: {
992
+ readonly chunkSize?: number | undefined
993
+ }
994
+ ): Stream<A> =>
995
+ Array.isArray(iterable) && options?.chunkSize === undefined
987
996
  ? fromArray(iterable)
988
- : fromChannel(Channel.fromIterableArray(iterable))
997
+ : fromChannel(Channel.fromIterableArray(iterable, options?.chunkSize))
989
998
 
990
999
  /**
991
1000
  * Creates a stream from an effect producing an iterable of values.
package/src/Trie.ts CHANGED
@@ -16,11 +16,11 @@
16
16
  * @since 2.0.0
17
17
  */
18
18
  import type { Equal } from "./Equal.ts"
19
- import type * as Filter from "./Filter.ts"
20
19
  import type { Inspectable } from "./Inspectable.ts"
21
20
  import * as TR from "./internal/trie.ts"
22
21
  import type { Option } from "./Option.ts"
23
22
  import type { Pipeable } from "./Pipeable.ts"
23
+ import type { Result } from "./Result.ts"
24
24
  import type { Covariant, NoInfer } from "./Types.ts"
25
25
 
26
26
  const TypeId = TR.TrieTypeId
@@ -1585,7 +1585,7 @@ export const filterMap: {
1585
1585
  * @since 2.0.0
1586
1586
  * @category filtering
1587
1587
  */
1588
- <A, B, X>(f: Filter.Filter<A, B, X, [key: string]>): (self: Trie<A>) => Trie<B>
1588
+ <A, B, X>(f: (input: A, key: string) => Result<B, X>): (self: Trie<A>) => Trie<B>
1589
1589
  /**
1590
1590
  * Maps over the entries of the `Trie` using the specified filter and keeps
1591
1591
  * only successful results.
@@ -1634,7 +1634,7 @@ export const filterMap: {
1634
1634
  * @since 2.0.0
1635
1635
  * @category filtering
1636
1636
  */
1637
- <A, B, X>(self: Trie<A>, f: Filter.Filter<A, B, X, [key: string]>): Trie<B>
1637
+ <A, B, X>(self: Trie<A>, f: (input: A, key: string) => Result<B, X>): Trie<B>
1638
1638
  } = TR.filterMap
1639
1639
 
1640
1640
  /**
package/src/TxHashMap.ts CHANGED
@@ -3,7 +3,6 @@
3
3
  */
4
4
 
5
5
  import * as Effect from "./Effect.ts"
6
- import type * as Filter from "./Filter.ts"
7
6
  import { format } from "./Formatter.ts"
8
7
  import { dual } from "./Function.ts"
9
8
  import * as HashMap from "./HashMap.ts"
@@ -12,6 +11,7 @@ import { NodeInspectSymbol, toJson } from "./Inspectable.ts"
12
11
  import * as Option from "./Option.ts"
13
12
  import type { Pipeable } from "./Pipeable.ts"
14
13
  import { pipeArguments } from "./Pipeable.ts"
14
+ import type { Result } from "./Result.ts"
15
15
  import * as TxRef from "./TxRef.ts"
16
16
 
17
17
  const TypeId = "~effect/transactions/TxHashMap"
@@ -2835,7 +2835,7 @@ export const filterMap: {
2835
2835
  * @since 2.0.0
2836
2836
  * @category combinators
2837
2837
  */
2838
- <V, K, A, X>(f: Filter.Filter<V, A, X, [key: K]>): (self: TxHashMap<K, V>) => Effect.Effect<TxHashMap<K, A>, never, Effect.Transaction>
2838
+ <V, K, A, X>(f: (input: V, key: K) => Result<A, X>): (self: TxHashMap<K, V>) => Effect.Effect<TxHashMap<K, A>, never, Effect.Transaction>
2839
2839
  /**
2840
2840
  * Combines filtering and mapping in a single operation. Applies a filter to each
2841
2841
  * entry, keeping only successful results and transforming them.
@@ -2893,12 +2893,12 @@ export const filterMap: {
2893
2893
  * @since 2.0.0
2894
2894
  * @category combinators
2895
2895
  */
2896
- <K, V, A, X>(self: TxHashMap<K, V>, f: Filter.Filter<V, A, X, [key: K]>): Effect.Effect<TxHashMap<K, A>, never, Effect.Transaction>
2896
+ <K, V, A, X>(self: TxHashMap<K, V>, f: (input: V, key: K) => Result<A, X>): Effect.Effect<TxHashMap<K, A>, never, Effect.Transaction>
2897
2897
  } = dual(
2898
2898
  2,
2899
2899
  <K, V, A, X>(
2900
2900
  self: TxHashMap<K, V>,
2901
- f: Filter.Filter<V, A, X, [key: K]>
2901
+ f: (input: V, key: K) => Result<A, X>
2902
2902
  ): Effect.Effect<TxHashMap<K, A>, never, Effect.Transaction> =>
2903
2903
  Effect.gen(function*() {
2904
2904
  const currentMap = yield* TxRef.get(self.ref)
@@ -493,40 +493,6 @@ const fiberIdStore = { id: 0 }
493
493
  /** @internal */
494
494
  export const getCurrentFiber = (): Fiber.Fiber<any, any> | undefined => (globalThis as any)[currentFiberTypeId]
495
495
 
496
- const keepAlive = (() => {
497
- let isAvailable: boolean | undefined
498
- const start = () => {
499
- if (isAvailable === true) return setInterval(constVoid, 2_147_483_647)
500
- else if (isAvailable === false) return undefined
501
-
502
- try {
503
- const running = setInterval(constVoid, 2_147_483_647)
504
- isAvailable = true
505
- return running
506
- } catch {
507
- isAvailable = false
508
- return undefined
509
- }
510
- }
511
- let count = 0
512
- let running: ReturnType<typeof globalThis.setInterval> | undefined = undefined
513
- return ({
514
- increment() {
515
- count++
516
- if (running === undefined) {
517
- running = start()
518
- }
519
- },
520
- decrement() {
521
- count--
522
- if (count === 0 && running !== undefined) {
523
- clearInterval(running)
524
- running = undefined
525
- }
526
- }
527
- })
528
- })()
529
-
530
496
  /** @internal */
531
497
  export class FiberImpl<A = any, E = any> implements Fiber.Fiber<A, E> {
532
498
  constructor(
@@ -1056,10 +1022,8 @@ const callbackOptions: <A, E = never, R = never>(
1056
1022
  }, controller?.signal)
1057
1023
  if (yielded !== false) return yielded
1058
1024
  yielded = true
1059
- keepAlive.increment()
1060
1025
  fiber._yielded = () => {
1061
1026
  resumed = true
1062
- keepAlive.decrement()
1063
1027
  }
1064
1028
  if (controller === undefined && onCancel === undefined) {
1065
1029
  return Yield
@@ -1133,7 +1097,7 @@ export const fnUntraced: Effect.fn.Untraced = (
1133
1097
  body: Function,
1134
1098
  ...pipeables: Array<any>
1135
1099
  ) => {
1136
- return pipeables.length === 0
1100
+ const fn = pipeables.length === 0
1137
1101
  ? function(this: any) {
1138
1102
  return suspend(() => fromIteratorUnsafe(body.apply(this, arguments)))
1139
1103
  }
@@ -1144,8 +1108,15 @@ export const fnUntraced: Effect.fn.Untraced = (
1144
1108
  }
1145
1109
  return effect
1146
1110
  }
1111
+ return defineFunctionLength(body.length, fn)
1147
1112
  }
1148
1113
 
1114
+ const defineFunctionLength = <F extends Function>(length: number, fn: F): F =>
1115
+ Object.defineProperty(fn, "length", {
1116
+ value: length,
1117
+ configurable: true
1118
+ })
1119
+
1149
1120
  const fnStackCleaner = makeStackCleaner(2)
1150
1121
 
1151
1122
  /** @internal */
@@ -1186,7 +1157,7 @@ const makeFn = (
1186
1157
  ? bodyOrOptions
1187
1158
  : (pipeables.pop()!).bind(bodyOrOptions.self)
1188
1159
 
1189
- return function(this: any, ...args: Array<any>) {
1160
+ return defineFunctionLength(body.length, function(this: any, ...args: Array<any>) {
1190
1161
  let result = suspend(() => {
1191
1162
  const iter = body.apply(this, arguments)
1192
1163
  return isEffect(iter) ? iter : fromIteratorUnsafe(iter)
@@ -1216,7 +1187,7 @@ const makeFn = (
1216
1187
  }
1217
1188
  })
1218
1189
  )
1219
- }
1190
+ })
1220
1191
  }
1221
1192
 
1222
1193
  /** @internal */
@@ -1224,17 +1195,20 @@ export const fnUntracedEager: Effect.fn.Untraced = (
1224
1195
  body: Function,
1225
1196
  ...pipeables: Array<any>
1226
1197
  ) =>
1227
- pipeables.length === 0
1228
- ? function(this: any) {
1229
- return fromIteratorEagerUnsafe(() => body.apply(this, arguments))
1230
- }
1231
- : function(this: any) {
1232
- let effect = fromIteratorEagerUnsafe(() => body.apply(this, arguments))
1233
- for (const pipeable of pipeables) {
1234
- effect = pipeable(effect)
1198
+ defineFunctionLength(
1199
+ body.length,
1200
+ pipeables.length === 0
1201
+ ? function(this: any) {
1202
+ return fromIteratorEagerUnsafe(() => body.apply(this, arguments))
1235
1203
  }
1236
- return effect
1237
- }
1204
+ : function(this: any) {
1205
+ let effect = fromIteratorEagerUnsafe(() => body.apply(this, arguments))
1206
+ for (const pipeable of pipeables) {
1207
+ effect = pipeable(effect)
1208
+ }
1209
+ return effect
1210
+ }
1211
+ )
1238
1212
 
1239
1213
  const fromIteratorEagerUnsafe = (
1240
1214
  evaluate: () => Iterator<Effect.Yieldable<any, any, any, any>>
@@ -4334,17 +4308,17 @@ const findFirstLoop = <A, E, R>(
4334
4308
  /** @internal */
4335
4309
  export const findFirstFilter: {
4336
4310
  <A, B, X, E, R>(
4337
- filter: Filter.FilterEffect<NoInfer<A>, B, X, E, R, [i: number]>
4311
+ filter: (input: NoInfer<A>, i: number) => Effect.Effect<Result.Result<B, X>, E, R>
4338
4312
  ): (elements: Iterable<A>) => Effect.Effect<Option.Option<B>, E, R>
4339
4313
  <A, B, X, E, R>(
4340
4314
  elements: Iterable<A>,
4341
- filter: Filter.FilterEffect<NoInfer<A>, B, X, E, R, [i: number]>
4315
+ filter: (input: NoInfer<A>, i: number) => Effect.Effect<Result.Result<B, X>, E, R>
4342
4316
  ): Effect.Effect<Option.Option<B>, E, R>
4343
4317
  } = dual(
4344
4318
  (args) => isIterable(args[0]) && !isEffect(args[0]),
4345
4319
  <A, B, X, E, R>(
4346
4320
  elements: Iterable<A>,
4347
- filter: Filter.FilterEffect<A, B, X, E, R, [i: number]>
4321
+ filter: (input: A, i: number) => Effect.Effect<Result.Result<B, X>, E, R>
4348
4322
  ): Effect.Effect<Option.Option<B>, E, R> =>
4349
4323
  suspend(() => {
4350
4324
  const iterator = elements[Symbol.iterator]()
@@ -4359,7 +4333,7 @@ export const findFirstFilter: {
4359
4333
  const findFirstFilterLoop = <A, B, X, E, R>(
4360
4334
  iterator: Iterator<A>,
4361
4335
  index: number,
4362
- filter: Filter.FilterEffect<A, B, X, E, R, [i: number]>,
4336
+ filter: (input: A, i: number) => Effect.Effect<Result.Result<B, X>, E, R>,
4363
4337
  value: A
4364
4338
  ): Effect.Effect<Option.Option<B>, E, R> =>
4365
4339
  flatMap(filter(value, index), (result) => {
@@ -3,7 +3,6 @@
3
3
  */
4
4
 
5
5
  import * as Equal_ from "../Equal.ts"
6
- import type * as Filter from "../Filter.ts"
7
6
  import { format } from "../Formatter.ts"
8
7
  import { dual, pipe } from "../Function.ts"
9
8
  import * as Hash from "../Hash.ts"
@@ -1257,9 +1256,9 @@ export const compact = <K, A>(self: HashMap<K, Option.Option<A>>): HashMap<K, A>
1257
1256
 
1258
1257
  /** @internal */
1259
1258
  export const filterMap = dual<
1260
- <A, K, B, X>(f: Filter.Filter<A, B, X, [key: K]>) => (self: HashMap<K, A>) => HashMap<K, B>,
1261
- <K, A, B, X>(self: HashMap<K, A>, f: Filter.Filter<A, B, X, [key: K]>) => HashMap<K, B>
1262
- >(2, <K, A, B, X>(self: HashMap<K, A>, f: Filter.Filter<A, B, X, [key: K]>): HashMap<K, B> => {
1259
+ <A, K, B, X>(f: (input: A, key: K) => Result.Result<B, X>) => (self: HashMap<K, A>) => HashMap<K, B>,
1260
+ <K, A, B, X>(self: HashMap<K, A>, f: (input: A, key: K) => Result.Result<B, X>) => HashMap<K, B>
1261
+ >(2, <K, A, B, X>(self: HashMap<K, A>, f: (input: A, key: K) => Result.Result<B, X>): HashMap<K, B> => {
1263
1262
  let result = empty<K, B>()
1264
1263
  for (const [key, value] of self) {
1265
1264
  const mapped = f(value, key)
@@ -24,80 +24,13 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
24
24
 
25
25
  const referenceMap = new Map<AST.AST, string>()
26
26
  const uniqueReferences = new Set<string>()
27
- const usedReferences = new Set<string>()
27
+ const visiting = new Set<AST.AST>()
28
28
 
29
29
  const schemas = Arr.map(asts, (ast) => recur(ast))
30
30
 
31
31
  return {
32
- representations: Arr.map(schemas, compact),
33
- references: Rec.map(Rec.filter(references, (_, k) => !isCompactable(k)), compact)
34
- }
35
-
36
- function isCompactable($ref: string): boolean {
37
- return !usedReferences.has($ref)
38
- }
39
-
40
- function compact(s: SchemaRepresentation.Representation): SchemaRepresentation.Representation {
41
- switch (s._tag) {
42
- default:
43
- return s
44
- case "Declaration":
45
- return {
46
- ...s,
47
- typeParameters: s.typeParameters.map(compact),
48
- encodedSchema: compact(s.encodedSchema)
49
- }
50
- case "Reference": {
51
- if (isCompactable(s.$ref)) {
52
- return compact(references[s.$ref])
53
- }
54
- return s
55
- }
56
- case "Suspend":
57
- return { ...s, thunk: compact(s.thunk) }
58
- case "String":
59
- return {
60
- ...s,
61
- ...(s.contentSchema ? { contentSchema: compact(s.contentSchema) } : undefined)
62
- }
63
- case "TemplateLiteral":
64
- return { ...s, parts: s.parts.map(compact) }
65
- case "Arrays":
66
- return {
67
- ...s,
68
- elements: s.elements.map((e) => ({ ...e, type: compact(e.type) })),
69
- rest: s.rest.map(compact)
70
- }
71
- case "Objects":
72
- return {
73
- ...s,
74
- checks: s.checks.map(compactCheck),
75
- propertySignatures: s.propertySignatures.map((ps) => ({ ...ps, type: compact(ps.type) })),
76
- indexSignatures: s.indexSignatures.map((is) => ({
77
- ...is,
78
- parameter: compact(is.parameter),
79
- type: compact(is.type)
80
- }))
81
- }
82
- case "Union":
83
- return { ...s, types: s.types.map(compact) }
84
- }
85
- }
86
-
87
- function compactCheck<M extends SchemaRepresentation.Meta>(
88
- check: SchemaRepresentation.Check<M>
89
- ): SchemaRepresentation.Check<M> {
90
- switch (check._tag) {
91
- case "Filter":
92
- return {
93
- ...check,
94
- meta: check.meta._tag === "isPropertyNames"
95
- ? { _tag: "isPropertyNames", propertyNames: compact(check.meta.propertyNames) } as M
96
- : check.meta
97
- }
98
- case "FilterGroup":
99
- return { ...check, checks: Arr.map(check.checks, compactCheck) }
100
- }
32
+ representations: schemas,
33
+ references
101
34
  }
102
35
 
103
36
  function gen(prefix: string = "_"): string {
@@ -115,32 +48,45 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
115
48
  function recur(ast: AST.AST, prefix?: string): SchemaRepresentation.Representation {
116
49
  const found = referenceMap.get(ast)
117
50
  if (found !== undefined) {
118
- usedReferences.add(found)
119
51
  return { _tag: "Reference", $ref: found }
120
52
  }
121
53
 
122
- const last = getLastEncoding(ast)
123
-
124
- if (ast === last) {
125
- const reference = ast._tag === "Declaration"
126
- ? gen(ast._tag)
127
- : gen(InternalAnnotations.resolveIdentifier(ast) ?? prefix ?? `${ast._tag}_`)
54
+ const last = AST.getLastEncoding(ast)
55
+ const identifier = InternalAnnotations.resolveIdentifier(ast) ?? prefix
128
56
 
129
- const encodedSchemaPrefix = ast._tag === "Declaration"
130
- ? InternalAnnotations.resolveIdentifier(ast) ?? prefix
131
- : prefix
57
+ if (ast !== last) {
58
+ return recur(last, identifier)
59
+ }
132
60
 
61
+ // Has identifier → always create reference
62
+ if (identifier !== undefined) {
63
+ const reference = gen(identifier)
133
64
  referenceMap.set(ast, reference)
134
- const out = on(ast, encodedSchemaPrefix)
65
+ const out = on(ast)
135
66
  references[reference] = out
136
67
  return { _tag: "Reference", $ref: reference }
137
- } else {
138
- return recur(last, InternalAnnotations.resolveIdentifier(ast) ?? prefix)
139
68
  }
140
- }
141
69
 
142
- function getLastEncoding(ast: AST.AST): AST.AST {
143
- return ast.encoding ? ast.encoding[ast.encoding.length - 1].to : ast
70
+ // Recursion detected create reference
71
+ if (visiting.has(ast)) {
72
+ const reference = gen(`${ast._tag}_`)
73
+ referenceMap.set(ast, reference)
74
+ return { _tag: "Reference", $ref: reference }
75
+ }
76
+
77
+ // Normal case → inline
78
+ visiting.add(ast)
79
+ const out = on(ast)
80
+ visiting.delete(ast)
81
+
82
+ // A descendant triggered reference creation (recursion)
83
+ const ref = referenceMap.get(ast)
84
+ if (ref !== undefined) {
85
+ references[ref] = out
86
+ return { _tag: "Reference", $ref: ref }
87
+ }
88
+
89
+ return out
144
90
  }
145
91
 
146
92
  function getEncodedSchema(last: AST.Declaration): AST.AST {
@@ -153,12 +99,12 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
153
99
  return AST.null
154
100
  }
155
101
 
156
- function on(last: AST.AST, encodedSchemaPrefix?: string): SchemaRepresentation.Representation {
102
+ function on(last: AST.AST): SchemaRepresentation.Representation {
157
103
  const annotations = fromASTAnnotations(last.annotations)
158
104
  switch (last._tag) {
159
105
  case "Declaration": {
160
106
  // this must be executed before transforming the type parameters
161
- const encodedSchema = recur(getEncodedSchema(last), encodedSchemaPrefix)
107
+ const encodedSchema = recur(getEncodedSchema(last))
162
108
  return {
163
109
  _tag: "Declaration",
164
110
  typeParameters: last.typeParameters.map((ast) => recur(ast)),
@@ -228,7 +174,7 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
228
174
  return {
229
175
  _tag: last._tag,
230
176
  elements: last.elements.map((e) => {
231
- const last = getLastEncoding(e)
177
+ const last = AST.getLastEncoding(e)
232
178
  return {
233
179
  isOptional: AST.isOptional(last),
234
180
  type: recur(e),
@@ -243,7 +189,7 @@ export function fromASTs(asts: readonly [AST.AST, ...Array<AST.AST>]): SchemaRep
243
189
  return {
244
190
  _tag: last._tag,
245
191
  propertySignatures: last.propertySignatures.map((ps) => {
246
- const last = getLastEncoding(ps.type)
192
+ const last = AST.getLastEncoding(ps.type)
247
193
  return {
248
194
  name: ps.name,
249
195
  type: recur(ps.type),
@@ -1,5 +1,4 @@
1
1
  import * as Equal from "../Equal.ts"
2
- import type * as Filter from "../Filter.ts"
3
2
  import { format } from "../Formatter.ts"
4
3
  import { dual, pipe } from "../Function.ts"
5
4
  import * as Hash from "../Hash.ts"
@@ -312,10 +311,10 @@ export const filter: {
312
311
  /** @internal */
313
312
  export const filterMap = dual<
314
313
  <A, B, X>(
315
- f: Filter.Filter<A, B, X, [key: string]>
314
+ f: (input: A, key: string) => Result.Result<B, X>
316
315
  ) => (self: TR.Trie<A>) => TR.Trie<B>,
317
- <A, B, X>(self: TR.Trie<A>, f: Filter.Filter<A, B, X, [key: string]>) => TR.Trie<B>
318
- >(2, <A, B, X>(self: TR.Trie<A>, f: Filter.Filter<A, B, X, [key: string]>): TR.Trie<B> =>
316
+ <A, B, X>(self: TR.Trie<A>, f: (input: A, key: string) => Result.Result<B, X>) => TR.Trie<B>
317
+ >(2, <A, B, X>(self: TR.Trie<A>, f: (input: A, key: string) => Result.Result<B, X>): TR.Trie<B> =>
319
318
  reduce(
320
319
  self,
321
320
  empty<B>(),