effect 3.2.9 → 3.3.1

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 (154) hide show
  1. package/Redacted/package.json +6 -0
  2. package/dist/cjs/Chunk.js +16 -6
  3. package/dist/cjs/Chunk.js.map +1 -1
  4. package/dist/cjs/Config.js +9 -1
  5. package/dist/cjs/Config.js.map +1 -1
  6. package/dist/cjs/Either.js +3 -2
  7. package/dist/cjs/Either.js.map +1 -1
  8. package/dist/cjs/Iterable.js +15 -2
  9. package/dist/cjs/Iterable.js.map +1 -1
  10. package/dist/cjs/Layer.js +11 -1
  11. package/dist/cjs/Layer.js.map +1 -1
  12. package/dist/cjs/Option.js +8 -2
  13. package/dist/cjs/Option.js.map +1 -1
  14. package/dist/cjs/Pool.js +26 -0
  15. package/dist/cjs/Pool.js.map +1 -1
  16. package/dist/cjs/Predicate.js +92 -2
  17. package/dist/cjs/Predicate.js.map +1 -1
  18. package/dist/cjs/Redacted.js +114 -0
  19. package/dist/cjs/Redacted.js.map +1 -0
  20. package/dist/cjs/STM.js.map +1 -1
  21. package/dist/cjs/Secret.js +7 -0
  22. package/dist/cjs/Secret.js.map +1 -1
  23. package/dist/cjs/Stream.js +32 -1
  24. package/dist/cjs/Stream.js.map +1 -1
  25. package/dist/cjs/Struct.js.map +1 -1
  26. package/dist/cjs/Tuple.js +15 -1
  27. package/dist/cjs/Tuple.js.map +1 -1
  28. package/dist/cjs/Utils.js.map +1 -1
  29. package/dist/cjs/index.js +4 -2
  30. package/dist/cjs/index.js.map +1 -1
  31. package/dist/cjs/internal/config.js +9 -2
  32. package/dist/cjs/internal/config.js.map +1 -1
  33. package/dist/cjs/internal/layer.js +14 -2
  34. package/dist/cjs/internal/layer.js.map +1 -1
  35. package/dist/cjs/internal/pool.js +206 -235
  36. package/dist/cjs/internal/pool.js.map +1 -1
  37. package/dist/cjs/internal/redacted.js +87 -0
  38. package/dist/cjs/internal/redacted.js.map +1 -0
  39. package/dist/cjs/internal/secret.js +40 -23
  40. package/dist/cjs/internal/secret.js.map +1 -1
  41. package/dist/cjs/internal/stm/stm.js +2 -1
  42. package/dist/cjs/internal/stm/stm.js.map +1 -1
  43. package/dist/cjs/internal/stream.js +15 -7
  44. package/dist/cjs/internal/stream.js.map +1 -1
  45. package/dist/cjs/internal/version.js +1 -1
  46. package/dist/dts/Chunk.d.ts +11 -1
  47. package/dist/dts/Chunk.d.ts.map +1 -1
  48. package/dist/dts/Config.d.ts +10 -1
  49. package/dist/dts/Config.d.ts.map +1 -1
  50. package/dist/dts/Either.d.ts.map +1 -1
  51. package/dist/dts/Iterable.d.ts +7 -0
  52. package/dist/dts/Iterable.d.ts.map +1 -1
  53. package/dist/dts/Layer.d.ts +20 -0
  54. package/dist/dts/Layer.d.ts.map +1 -1
  55. package/dist/dts/Option.d.ts.map +1 -1
  56. package/dist/dts/Pool.d.ts +31 -0
  57. package/dist/dts/Pool.d.ts.map +1 -1
  58. package/dist/dts/Predicate.d.ts +99 -2
  59. package/dist/dts/Predicate.d.ts.map +1 -1
  60. package/dist/dts/Redacted.d.ts +122 -0
  61. package/dist/dts/Redacted.d.ts.map +1 -0
  62. package/dist/dts/STM.d.ts +4 -1
  63. package/dist/dts/STM.d.ts.map +1 -1
  64. package/dist/dts/Secret.d.ts +14 -1
  65. package/dist/dts/Secret.d.ts.map +1 -1
  66. package/dist/dts/Stream.d.ts +61 -4
  67. package/dist/dts/Stream.d.ts.map +1 -1
  68. package/dist/dts/Struct.d.ts +7 -7
  69. package/dist/dts/Struct.d.ts.map +1 -1
  70. package/dist/dts/Tuple.d.ts +51 -0
  71. package/dist/dts/Tuple.d.ts.map +1 -1
  72. package/dist/dts/Types.d.ts +46 -0
  73. package/dist/dts/Types.d.ts.map +1 -1
  74. package/dist/dts/Utils.d.ts +6 -5
  75. package/dist/dts/Utils.d.ts.map +1 -1
  76. package/dist/dts/index.d.ts +10 -0
  77. package/dist/dts/index.d.ts.map +1 -1
  78. package/dist/dts/internal/layer.d.ts +15 -1
  79. package/dist/dts/internal/layer.d.ts.map +1 -1
  80. package/dist/dts/internal/redacted.d.ts +2 -0
  81. package/dist/dts/internal/redacted.d.ts.map +1 -0
  82. package/dist/dts/internal/stm/stm.d.ts.map +1 -1
  83. package/dist/dts/internal/stream.d.ts +1 -0
  84. package/dist/dts/internal/stream.d.ts.map +1 -1
  85. package/dist/esm/Chunk.js +16 -5
  86. package/dist/esm/Chunk.js.map +1 -1
  87. package/dist/esm/Config.js +8 -0
  88. package/dist/esm/Config.js.map +1 -1
  89. package/dist/esm/Either.js +3 -2
  90. package/dist/esm/Either.js.map +1 -1
  91. package/dist/esm/Iterable.js +12 -0
  92. package/dist/esm/Iterable.js.map +1 -1
  93. package/dist/esm/Layer.js +10 -0
  94. package/dist/esm/Layer.js.map +1 -1
  95. package/dist/esm/Option.js +8 -2
  96. package/dist/esm/Option.js.map +1 -1
  97. package/dist/esm/Pool.js +26 -0
  98. package/dist/esm/Pool.js.map +1 -1
  99. package/dist/esm/Predicate.js +91 -1
  100. package/dist/esm/Predicate.js.map +1 -1
  101. package/dist/esm/Redacted.js +82 -0
  102. package/dist/esm/Redacted.js.map +1 -0
  103. package/dist/esm/STM.js.map +1 -1
  104. package/dist/esm/Secret.js +7 -0
  105. package/dist/esm/Secret.js.map +1 -1
  106. package/dist/esm/Stream.js +31 -0
  107. package/dist/esm/Stream.js.map +1 -1
  108. package/dist/esm/Struct.js.map +1 -1
  109. package/dist/esm/Tuple.js +51 -0
  110. package/dist/esm/Tuple.js.map +1 -1
  111. package/dist/esm/Utils.js.map +1 -1
  112. package/dist/esm/index.js +10 -0
  113. package/dist/esm/index.js.map +1 -1
  114. package/dist/esm/internal/config.js +7 -1
  115. package/dist/esm/internal/config.js.map +1 -1
  116. package/dist/esm/internal/layer.js +12 -0
  117. package/dist/esm/internal/layer.js.map +1 -1
  118. package/dist/esm/internal/pool.js +205 -235
  119. package/dist/esm/internal/pool.js.map +1 -1
  120. package/dist/esm/internal/redacted.js +52 -0
  121. package/dist/esm/internal/redacted.js.map +1 -0
  122. package/dist/esm/internal/secret.js +39 -22
  123. package/dist/esm/internal/secret.js.map +1 -1
  124. package/dist/esm/internal/stm/stm.js +2 -1
  125. package/dist/esm/internal/stm/stm.js.map +1 -1
  126. package/dist/esm/internal/stream.js +13 -4
  127. package/dist/esm/internal/stream.js.map +1 -1
  128. package/dist/esm/internal/version.js +1 -1
  129. package/package.json +9 -1
  130. package/src/Chunk.ts +17 -5
  131. package/src/Config.ts +11 -1
  132. package/src/Either.ts +6 -4
  133. package/src/Iterable.ts +13 -0
  134. package/src/Layer.ts +22 -0
  135. package/src/Option.ts +8 -2
  136. package/src/Pool.ts +39 -6
  137. package/src/Predicate.ts +102 -3
  138. package/src/Redacted.ts +133 -0
  139. package/src/STM.ts +7 -2
  140. package/src/Secret.ts +14 -1
  141. package/src/Stream.ts +67 -7
  142. package/src/Struct.ts +8 -13
  143. package/src/Tuple.ts +53 -0
  144. package/src/Types.ts +48 -0
  145. package/src/Utils.ts +9 -6
  146. package/src/index.ts +11 -0
  147. package/src/internal/config.ts +13 -2
  148. package/src/internal/layer.ts +63 -0
  149. package/src/internal/pool.ts +320 -447
  150. package/src/internal/redacted.ts +69 -0
  151. package/src/internal/secret.ts +39 -28
  152. package/src/internal/stm/stm.ts +4 -1
  153. package/src/internal/stream.ts +111 -50
  154. package/src/internal/version.ts +1 -1
@@ -1,4 +1,4 @@
1
- let moduleVersion = "3.2.9";
1
+ let moduleVersion = "3.3.1";
2
2
  export const getCurrentVersion = () => moduleVersion;
3
3
  export const setCurrentVersion = version => {
4
4
  moduleVersion = version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "effect",
3
- "version": "3.2.9",
3
+ "version": "3.3.1",
4
4
  "description": "The missing standard library for TypeScript, for writing production-grade software.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -482,6 +482,11 @@
482
482
  "import": "./dist/esm/RedBlackTree.js",
483
483
  "default": "./dist/cjs/RedBlackTree.js"
484
484
  },
485
+ "./Redacted": {
486
+ "types": "./dist/dts/Redacted.d.ts",
487
+ "import": "./dist/esm/Redacted.js",
488
+ "default": "./dist/cjs/Redacted.js"
489
+ },
485
490
  "./Ref": {
486
491
  "types": "./dist/dts/Ref.d.ts",
487
492
  "import": "./dist/esm/Ref.js",
@@ -1081,6 +1086,9 @@
1081
1086
  "RedBlackTree": [
1082
1087
  "./dist/dts/RedBlackTree.d.ts"
1083
1088
  ],
1089
+ "Redacted": [
1090
+ "./dist/dts/Redacted.d.ts"
1091
+ ],
1084
1092
  "Ref": [
1085
1093
  "./dist/dts/Ref.d.ts"
1086
1094
  ],
package/src/Chunk.ts CHANGED
@@ -316,11 +316,7 @@ export const toReadonlyArray = <A>(self: Chunk<A>): ReadonlyArray<A> => {
316
316
  }
317
317
  }
318
318
 
319
- /**
320
- * @since 2.0.0
321
- * @category elements
322
- */
323
- export const reverse = <A>(self: Chunk<A>): Chunk<A> => {
319
+ const reverseChunk = <A>(self: Chunk<A>): Chunk<A> => {
324
320
  switch (self.backing._tag) {
325
321
  case "IEmpty":
326
322
  case "ISingleton":
@@ -336,6 +332,22 @@ export const reverse = <A>(self: Chunk<A>): Chunk<A> => {
336
332
  }
337
333
  }
338
334
 
335
+ /**
336
+ * Reverses the order of elements in a `Chunk`.
337
+ * Importantly, if the input chunk is a `NonEmptyChunk`, the reversed chunk will also be a `NonEmptyChunk`.
338
+ *
339
+ * @example
340
+ * import { Chunk } from "effect"
341
+ *
342
+ * const numbers = Chunk.make(1, 2, 3)
343
+ * const reversedNumbers = Chunk.reverse(numbers)
344
+ * assert.deepStrictEqual(reversedNumbers, Chunk.make(3, 2, 1))
345
+ *
346
+ * @since 2.0.0
347
+ * @category elements
348
+ */
349
+ export const reverse: <S extends Chunk<any>>(self: S) => Chunk.With<S, Chunk.Infer<S>> = reverseChunk as any
350
+
339
351
  /**
340
352
  * This function provides a safe way to read a value at a particular index from a `Chunk`.
341
353
  *
package/src/Config.ts CHANGED
@@ -13,6 +13,7 @@ import * as internal from "./internal/config.js"
13
13
  import type * as LogLevel from "./LogLevel.js"
14
14
  import type * as Option from "./Option.js"
15
15
  import type { Predicate, Refinement } from "./Predicate.js"
16
+ import type * as Redacted from "./Redacted.js"
16
17
  import type * as Secret from "./Secret.js"
17
18
  import type * as Types from "./Types.js"
18
19
 
@@ -109,7 +110,7 @@ export const all: <const Arg extends Iterable<Config<any>> | Record<string, Conf
109
110
  * @since 2.0.0
110
111
  * @category constructors
111
112
  */
112
- export const array: <A>(config: Config<A>, name?: string) => Config<ReadonlyArray<A>> = internal.array
113
+ export const array: <A>(config: Config<A>, name?: string) => Config<Array<A>> = internal.array
113
114
 
114
115
  /**
115
116
  * Constructs a config for a boolean value.
@@ -330,9 +331,18 @@ export const repeat: <A>(self: Config<A>) => Config<Array<A>> = internal.repeat
330
331
  *
331
332
  * @since 2.0.0
332
333
  * @category constructors
334
+ * @deprecated
333
335
  */
334
336
  export const secret: (name?: string) => Config<Secret.Secret> = internal.secret
335
337
 
338
+ /**
339
+ * Constructs a config for a redacted value.
340
+ *
341
+ * @since 2.0.0
342
+ * @category constructors
343
+ */
344
+ export const redacted: (name?: string) => Config<Redacted.Redacted> = internal.redacted
345
+
336
346
  /**
337
347
  * Constructs a config for a sequence of values.
338
348
  *
package/src/Either.ts CHANGED
@@ -290,10 +290,9 @@ export const getEquivalence = <R, L>({ left, right }: {
290
290
  left: Equivalence.Equivalence<L>
291
291
  }): Equivalence.Equivalence<Either<R, L>> =>
292
292
  Equivalence.make((x, y) =>
293
- x === y ||
294
- (isLeft(x) ?
293
+ isLeft(x) ?
295
294
  isLeft(y) && left(x.left, y.left) :
296
- isRight(y) && right(x.right, y.right))
295
+ isRight(y) && right(x.right, y.right)
297
296
  )
298
297
 
299
298
  /**
@@ -700,7 +699,10 @@ const adapter = Gen.adapter<EitherTypeLambda>()
700
699
  * @category generators
701
700
  * @since 2.0.0
702
701
  */
703
- export const gen: Gen.Gen<EitherTypeLambda, Gen.Adapter<EitherTypeLambda>> = (f) => {
702
+ export const gen: Gen.Gen<EitherTypeLambda, Gen.Adapter<EitherTypeLambda>> = (...args) => {
703
+ const f = (args.length === 1)
704
+ ? args[0]
705
+ : args[1].bind(args[0])
704
706
  const iterator = f(adapter)
705
707
  let state: IteratorYieldResult<any> | IteratorReturnResult<any> = iterator.next()
706
708
  if (state.done) {
package/src/Iterable.ts CHANGED
@@ -265,6 +265,19 @@ export const head = <A>(self: Iterable<A>): Option<A> => {
265
265
  return result.done ? O.none() : O.some(result.value)
266
266
  }
267
267
 
268
+ /**
269
+ * Get the first element of a `Iterable`, or throw an error if the `Iterable` is empty.
270
+ *
271
+ * @category getters
272
+ * @since 3.3.0
273
+ */
274
+ export const unsafeHead = <A>(self: Iterable<A>): A => {
275
+ const iterator = self[Symbol.iterator]()
276
+ const result = iterator.next()
277
+ if (result.done) throw new Error("unsafeHead: empty iterable")
278
+ return result.value
279
+ }
280
+
268
281
  /**
269
282
  * Keep only a max number of elements from the start of an `Iterable`, creating a new `Iterable`.
270
283
  *
package/src/Layer.ts CHANGED
@@ -139,6 +139,28 @@ export const isLayer: (u: unknown) => u is Layer<unknown, unknown, unknown> = in
139
139
  */
140
140
  export const isFresh: <RIn, E, ROut>(self: Layer<ROut, E, RIn>) => boolean = internal.isFresh
141
141
 
142
+ /**
143
+ * @since 3.3.0
144
+ * @category tracing
145
+ */
146
+ export const annotateLogs: {
147
+ (key: string, value: unknown): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R>
148
+ (values: Record<string, unknown>): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R>
149
+ <A, E, R>(self: Layer<A, E, R>, key: string, value: unknown): Layer<A, E, R>
150
+ <A, E, R>(self: Layer<A, E, R>, values: Record<string, unknown>): Layer<A, E, R>
151
+ } = internal.annotateLogs
152
+
153
+ /**
154
+ * @since 3.3.0
155
+ * @category tracing
156
+ */
157
+ export const annotateSpans: {
158
+ (key: string, value: unknown): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R>
159
+ (values: Record<string, unknown>): <A, E, R>(self: Layer<A, E, R>) => Layer<A, E, R>
160
+ <A, E, R>(self: Layer<A, E, R>, key: string, value: unknown): Layer<A, E, R>
161
+ <A, E, R>(self: Layer<A, E, R>, values: Record<string, unknown>): Layer<A, E, R>
162
+ } = internal.annotateSpans
163
+
142
164
  /**
143
165
  * Builds a layer into a scoped value.
144
166
  *
package/src/Option.ts CHANGED
@@ -1057,7 +1057,7 @@ export const filter: {
1057
1057
  * @since 2.0.0
1058
1058
  */
1059
1059
  export const getEquivalence = <A>(isEquivalent: Equivalence.Equivalence<A>): Equivalence.Equivalence<Option<A>> =>
1060
- Equivalence.make((x, y) => x === y || (isNone(x) ? isNone(y) : isNone(y) ? false : isEquivalent(x.value, y.value)))
1060
+ Equivalence.make((x, y) => isNone(x) ? isNone(y) : isNone(y) ? false : isEquivalent(x.value, y.value))
1061
1061
 
1062
1062
  /**
1063
1063
  * The `Order` instance allows `Option` values to be compared with
@@ -1345,7 +1345,13 @@ const adapter = Gen.adapter<OptionTypeLambda>()
1345
1345
  * @category generators
1346
1346
  * @since 2.0.0
1347
1347
  */
1348
- export const gen: Gen.Gen<OptionTypeLambda, Gen.Adapter<OptionTypeLambda>> = (f) => {
1348
+ export const gen: Gen.Gen<OptionTypeLambda, Gen.Adapter<OptionTypeLambda>> = (...args) => {
1349
+ let f: any
1350
+ if (args.length === 1) {
1351
+ f = args[0]
1352
+ } else {
1353
+ f = args[1].bind(args[0])
1354
+ }
1349
1355
  const iterator = f(adapter)
1350
1356
  let state: IteratorYieldResult<any> | IteratorReturnResult<any> = iterator.next()
1351
1357
  if (state.done) {
package/src/Pool.ts CHANGED
@@ -74,6 +74,16 @@ export const isPool: (u: unknown) => u is Pool<unknown, unknown> = internal.isPo
74
74
  * because the `Scope` is closed, the individual items allocated by the pool
75
75
  * will be released in some unspecified order.
76
76
  *
77
+ * By setting the `concurrency` parameter, you can control the level of concurrent
78
+ * access per pool item. By default, the number of permits is set to `1`.
79
+ *
80
+ * `targetUtilization` determines when to create new pool items. It is a value
81
+ * between 0 and 1, where 1 means only create new pool items when all the existing
82
+ * items are fully utilized.
83
+ *
84
+ * A `targetUtilization` of 0.5 will create new pool items when the existing items are
85
+ * 50% utilized.
86
+ *
77
87
  * @since 2.0.0
78
88
  * @category constructors
79
89
  */
@@ -81,6 +91,8 @@ export const make: <A, E, R>(
81
91
  options: {
82
92
  readonly acquire: Effect.Effect<A, E, R>
83
93
  readonly size: number
94
+ readonly concurrency?: number | undefined
95
+ readonly targetUtilization?: number | undefined
84
96
  }
85
97
  ) => Effect.Effect<Pool<A, E>, never, Scope.Scope | R> = internal.make
86
98
 
@@ -92,6 +104,22 @@ export const make: <A, E, R>(
92
104
  * used, the individual items allocated by the pool will be released in some
93
105
  * unspecified order.
94
106
  *
107
+ * By setting the `concurrency` parameter, you can control the level of concurrent
108
+ * access per pool item. By default, the number of permits is set to `1`.
109
+ *
110
+ * `targetUtilization` determines when to create new pool items. It is a value
111
+ * between 0 and 1, where 1 means only create new pool items when all the existing
112
+ * items are fully utilized.
113
+ *
114
+ * A `targetUtilization` of 0.5 will create new pool items when the existing items are
115
+ * 50% utilized.
116
+ *
117
+ * The `timeToLiveStrategy` determines how items are invalidated. If set to
118
+ * "creation", then items are invalidated based on their creation time. If set
119
+ * to "usage", then items are invalidated based on pool usage.
120
+ *
121
+ * By default, the `timeToLiveStrategy` is set to "usage".
122
+ *
95
123
  * ```ts
96
124
  * import { createConnection } from "mysql2";
97
125
  * import { Duration, Effect, Pool } from "effect"
@@ -115,12 +143,17 @@ export const make: <A, E, R>(
115
143
  * @since 2.0.0
116
144
  * @category constructors
117
145
  */
118
- export const makeWithTTL: <A, E, R>(options: {
119
- readonly acquire: Effect.Effect<A, E, R>
120
- readonly min: number
121
- readonly max: number
122
- readonly timeToLive: Duration.DurationInput
123
- }) => Effect.Effect<Pool<A, E>, never, Scope.Scope | R> = internal.makeWithTTL
146
+ export const makeWithTTL: <A, E, R>(
147
+ options: {
148
+ readonly acquire: Effect.Effect<A, E, R>
149
+ readonly min: number
150
+ readonly max: number
151
+ readonly concurrency?: number | undefined
152
+ readonly targetUtilization?: number | undefined
153
+ readonly timeToLive: Duration.DurationInput
154
+ readonly timeToLiveStrategy?: "creation" | "usage" | undefined
155
+ }
156
+ ) => Effect.Effect<Pool<A, E>, never, Scope.Scope | R> = internal.makeWithTTL
124
157
 
125
158
  /**
126
159
  * Retrieves an item from the pool in a scoped effect. Note that if
package/src/Predicate.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  */
4
4
  import { dual, isFunction as isFunction_ } from "./Function.js"
5
5
  import type { TypeLambda } from "./HKT.js"
6
+ import type { TupleOf, TupleOfAtLeast } from "./Types.js"
6
7
 
7
8
  /**
8
9
  * @category models
@@ -52,6 +53,64 @@ export const mapInput: {
52
53
  <A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B>
53
54
  } = dual(2, <A, B>(self: Predicate<A>, f: (b: B) => A): Predicate<B> => (b) => self(f(b)))
54
55
 
56
+ /**
57
+ * Determine if an `Array` is a tuple with exactly `N` elements, narrowing down the type to `TupleOf`.
58
+ *
59
+ * An `Array` is considered to be a `TupleOf` if its length is exactly `N`.
60
+ *
61
+ * @param self - The `Array` to check.
62
+ * @param n - The exact number of elements that the `Array` should have to be considered a `TupleOf`.
63
+ *
64
+ * @example
65
+ * import { isTupleOf } from "effect/Predicate"
66
+ *
67
+ * assert.deepStrictEqual(isTupleOf([1, 2, 3], 3), true);
68
+ * assert.deepStrictEqual(isTupleOf([1, 2, 3], 2), false);
69
+ * assert.deepStrictEqual(isTupleOf([1, 2, 3], 4), false);
70
+ *
71
+ * const arr: number[] = [1, 2, 3];
72
+ * if (isTupleOf(arr, 3)) {
73
+ * console.log(arr);
74
+ * // ^? [number, number, number]
75
+ * }
76
+ *
77
+ * @category guards
78
+ * @since 3.3.0
79
+ */
80
+ export const isTupleOf: {
81
+ <N extends number>(n: N): <T>(self: ReadonlyArray<T>) => self is TupleOf<N, T>
82
+ <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOf<N, T>
83
+ } = dual(2, <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOf<N, T> => self.length === n)
84
+
85
+ /**
86
+ * Determine if an `Array` is a tuple with at least `N` elements, narrowing down the type to `TupleOfAtLeast`.
87
+ *
88
+ * An `Array` is considered to be a `TupleOfAtLeast` if its length is at least `N`.
89
+ *
90
+ * @param self - The `Array` to check.
91
+ * @param n - The minimum number of elements that the `Array` should have to be considered a `TupleOfAtLeast`.
92
+ *
93
+ * @example
94
+ * import { isTupleOfAtLeast } from "effect/Predicate"
95
+ *
96
+ * assert.deepStrictEqual(isTupleOfAtLeast([1, 2, 3], 3), true);
97
+ * assert.deepStrictEqual(isTupleOfAtLeast([1, 2, 3], 2), true);
98
+ * assert.deepStrictEqual(isTupleOfAtLeast([1, 2, 3], 4), false);
99
+ *
100
+ * const arr: number[] = [1, 2, 3, 4];
101
+ * if (isTupleOfAtLeast(arr, 3)) {
102
+ * console.log(arr);
103
+ * // ^? [number, number, number, ...number[]]
104
+ * }
105
+ *
106
+ * @category guards
107
+ * @since 3.3.0
108
+ */
109
+ export const isTupleOfAtLeast: {
110
+ <N extends number>(n: N): <T>(self: ReadonlyArray<T>) => self is TupleOfAtLeast<N, T>
111
+ <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOfAtLeast<N, T>
112
+ } = dual(2, <T, N extends number>(self: ReadonlyArray<T>, n: N): self is TupleOfAtLeast<N, T> => self.length >= n)
113
+
55
114
  /**
56
115
  * Tests if a value is `truthy`.
57
116
  *
@@ -740,15 +799,55 @@ export const eqv: {
740
799
  } = dual(2, <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) === that(a))
741
800
 
742
801
  /**
802
+ * Represents the logical implication combinator for predicates. In formal
803
+ * logic, the implication operator `->` denotes that if the first proposition
804
+ * (antecedent) is true, then the second proposition (consequent) must also be
805
+ * true. In simpler terms, `p implies q` can be interpreted as "if p then q". If
806
+ * the first predicate holds, then the second predicate must hold
807
+ * for the given context.
808
+ *
809
+ * In practical terms within TypeScript, `p implies q` is equivalent to `!p || (p && q)`.
810
+ *
811
+ * Note that if the antecedent is `false`, the result is `true` by default
812
+ * because the outcome of the consequent cannot be determined.
813
+ *
814
+ * This function is useful in situations where you need to enforce rules or
815
+ * constraints that are contingent on certain conditions.
816
+ * It proves especially helpful in defining property tests.
817
+ *
818
+ * The example below illustrates the transitive property of order using the
819
+ * `implies` function. In simple terms, if `a <= b` and `b <= c`, then `a <= c`
820
+ * must be true.
821
+ *
822
+ * @example
823
+ * import { Predicate } from "effect"
824
+ *
825
+ * type Triple = {
826
+ * readonly a: number
827
+ * readonly b: number
828
+ * readonly c: number
829
+ * }
830
+ *
831
+ * const transitivity = Predicate.implies(
832
+ * // antecedent
833
+ * (input: Triple) => input.a <= input.b && input.b <= input.c,
834
+ * // consequent
835
+ * (input: Triple) => input.a <= input.c
836
+ * )
837
+ *
838
+ * assert.equal(transitivity({ a: 1, b: 2, c: 3 }), true)
839
+ * // antecedent is `false`, so the result is `true`
840
+ * assert.equal(transitivity({ a: 1, b: 0, c: 0 }), true)
841
+ *
743
842
  * @category combinators
744
843
  * @since 2.0.0
745
844
  */
746
845
  export const implies: {
747
- <A>(that: Predicate<A>): (self: Predicate<A>) => Predicate<A>
748
- <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A>
846
+ <A>(consequent: Predicate<A>): (antecedent: Predicate<A>) => Predicate<A>
847
+ <A>(antecedent: Predicate<A>, consequent: Predicate<A>): Predicate<A>
749
848
  } = dual(
750
849
  2,
751
- <A>(self: Predicate<A>, that: Predicate<A>): Predicate<A> => (a) => self(a) ? that(a) : true
850
+ <A>(antecedent: Predicate<A>, consequent: Predicate<A>): Predicate<A> => (a) => antecedent(a) ? consequent(a) : true
752
851
  )
753
852
 
754
853
  /**
@@ -0,0 +1,133 @@
1
+ /**
2
+ * The Redacted module provides functionality for handling sensitive information
3
+ * securely within your application. By using the `Redacted` data type, you can
4
+ * ensure that sensitive values are not accidentally exposed in logs or error
5
+ * messages.
6
+ *
7
+ * @since 3.3.0
8
+ */
9
+ import type * as Equal from "./Equal.js"
10
+ import * as Equivalence from "./Equivalence.js"
11
+ import * as redacted_ from "./internal/redacted.js"
12
+ import type { Pipeable } from "./Pipeable.js"
13
+ import type { Covariant } from "./Types.js"
14
+
15
+ /**
16
+ * @since 3.3.0
17
+ * @category symbols
18
+ */
19
+ export const RedactedTypeId: unique symbol = redacted_.RedactedTypeId
20
+
21
+ /**
22
+ * @since 3.3.0
23
+ * @category symbols
24
+ */
25
+ export type RedactedTypeId = typeof RedactedTypeId
26
+
27
+ /**
28
+ * @since 3.3.0
29
+ * @category models
30
+ */
31
+ export interface Redacted<out A = string> extends Redacted.Variance<A>, Equal.Equal, Pipeable {
32
+ }
33
+
34
+ /**
35
+ * @since 3.3.0
36
+ */
37
+ export declare namespace Redacted {
38
+ /**
39
+ * @since 3.3.0
40
+ * @category models
41
+ */
42
+ export interface Variance<out A> {
43
+ readonly [RedactedTypeId]: {
44
+ readonly _A: Covariant<A>
45
+ }
46
+ }
47
+
48
+ /**
49
+ * @since 3.3.0
50
+ * @category type-level
51
+ */
52
+ export type Value<T extends Redacted<any>> = [T] extends [Redacted<infer _A>] ? _A : never
53
+ }
54
+
55
+ /**
56
+ * @since 3.3.0
57
+ * @category refinements
58
+ */
59
+ export const isRedacted: (u: unknown) => u is Redacted<unknown> = redacted_.isRedacted
60
+
61
+ /**
62
+ * This function creates a `Redacted<A>` instance from a given value `A`,
63
+ * securely hiding its content.
64
+ *
65
+ * @example
66
+ * import { Redacted } from "effect"
67
+ *
68
+ * const API_KEY = Redacted.make("1234567890")
69
+ *
70
+ * @since 3.3.0
71
+ * @category constructors
72
+ */
73
+ export const make: <A>(value: A) => Redacted<A> = redacted_.make
74
+
75
+ /**
76
+ * Retrieves the original value from a `Redacted` instance. Use this function
77
+ * with caution, as it exposes the sensitive data.
78
+ *
79
+ * @example
80
+ * import { Redacted } from "effect"
81
+ *
82
+ * const API_KEY = Redacted.make("1234567890")
83
+ *
84
+ * assert.equal(Redacted.value(API_KEY), "1234567890")
85
+ *
86
+ * @since 3.3.0
87
+ * @category getters
88
+ */
89
+ export const value: <A>(self: Redacted<A>) => A = redacted_.value
90
+
91
+ /**
92
+ * Erases the underlying value of a `Redacted` instance, rendering it unusable.
93
+ * This function is intended to ensure that sensitive data does not remain in
94
+ * memory longer than necessary.
95
+ *
96
+ * @example
97
+ * import { Redacted } from "effect"
98
+ *
99
+ * const API_KEY = Redacted.make("1234567890")
100
+ *
101
+ * assert.equal(Redacted.value(API_KEY), "1234567890")
102
+ *
103
+ * Redacted.unsafeWipe(API_KEY)
104
+ *
105
+ * assert.throws(() => Redacted.value(API_KEY), new Error("Unable to get redacted value"))
106
+ *
107
+ * @since 3.3.0
108
+ * @category unsafe
109
+ */
110
+ export const unsafeWipe: <A>(self: Redacted<A>) => boolean = redacted_.unsafeWipe
111
+
112
+ /**
113
+ * Generates an equivalence relation for `Redacted<A>` values based on an
114
+ * equivalence relation for the underlying values `A`. This function is useful
115
+ * for comparing `Redacted` instances without exposing their contents.
116
+ *
117
+ * @example
118
+ * import { Redacted, Equivalence } from "effect"
119
+ *
120
+ * const API_KEY1 = Redacted.make("1234567890")
121
+ * const API_KEY2 = Redacted.make("1-34567890")
122
+ * const API_KEY3 = Redacted.make("1234567890")
123
+ *
124
+ * const equivalence = Redacted.getEquivalence(Equivalence.string)
125
+ *
126
+ * assert.equal(equivalence(API_KEY1, API_KEY2), false)
127
+ * assert.equal(equivalence(API_KEY1, API_KEY3), true)
128
+ *
129
+ * @category equivalence
130
+ * @since 3.3.0
131
+ */
132
+ export const getEquivalence = <A>(isEquivalent: Equivalence.Equivalence<A>): Equivalence.Equivalence<Redacted<A>> =>
133
+ Equivalence.make((x, y) => isEquivalent(value(x), value(y)))
package/src/STM.ts CHANGED
@@ -1065,8 +1065,13 @@ export interface Adapter {
1065
1065
  * @since 2.0.0
1066
1066
  * @category constructors
1067
1067
  */
1068
- export const gen: <Eff extends YieldWrap<STM<any, any, any>>, AEff>(
1069
- f: (resume: Adapter) => Generator<Eff, AEff, never>
1068
+ export const gen: <Self, Eff extends YieldWrap<STM<any, any, any>>, AEff>(
1069
+ ...args:
1070
+ | [
1071
+ self: Self,
1072
+ body: (this: Self, resume: Adapter) => Generator<Eff, AEff, never>
1073
+ ]
1074
+ | [body: (resume: Adapter) => Generator<Eff, AEff, never>]
1070
1075
  ) => STM<
1071
1076
  AEff,
1072
1077
  [Eff] extends [never] ? never : [Eff] extends [YieldWrap<STM<infer _A, infer E, infer _R>>] ? E : never,
package/src/Secret.ts CHANGED
@@ -1,37 +1,44 @@
1
1
  /**
2
2
  * @since 2.0.0
3
+ * @deprecated
3
4
  */
4
5
  import type * as Equal from "./Equal.js"
5
6
  import * as InternalSecret from "./internal/secret.js"
7
+ import type * as Redacted from "./Redacted.js"
6
8
 
7
9
  /**
8
10
  * @since 2.0.0
9
11
  * @category symbols
12
+ * @deprecated
10
13
  */
11
14
  export const SecretTypeId: unique symbol = InternalSecret.SecretTypeId
12
15
 
13
16
  /**
14
17
  * @since 2.0.0
15
18
  * @category symbols
19
+ * @deprecated
16
20
  */
17
21
  export type SecretTypeId = typeof SecretTypeId
18
22
 
19
23
  /**
20
24
  * @since 2.0.0
21
25
  * @category models
26
+ * @deprecated
22
27
  */
23
- export interface Secret extends Secret.Proto, Equal.Equal {
28
+ export interface Secret extends Redacted.Redacted, Secret.Proto, Equal.Equal {
24
29
  /** @internal */
25
30
  readonly raw: Array<number>
26
31
  }
27
32
 
28
33
  /**
29
34
  * @since 2.0.0
35
+ * @deprecated
30
36
  */
31
37
  export declare namespace Secret {
32
38
  /**
33
39
  * @since 2.0.0
34
40
  * @category models
41
+ * @deprecated
35
42
  */
36
43
  export interface Proto {
37
44
  readonly [SecretTypeId]: SecretTypeId
@@ -41,35 +48,41 @@ export declare namespace Secret {
41
48
  /**
42
49
  * @since 2.0.0
43
50
  * @category refinements
51
+ * @deprecated
44
52
  */
45
53
  export const isSecret: (u: unknown) => u is Secret = InternalSecret.isSecret
46
54
 
47
55
  /**
48
56
  * @since 2.0.0
49
57
  * @category constructors
58
+ * @deprecated
50
59
  */
51
60
  export const make: (bytes: Array<number>) => Secret = InternalSecret.make
52
61
 
53
62
  /**
54
63
  * @since 2.0.0
55
64
  * @category constructors
65
+ * @deprecated
56
66
  */
57
67
  export const fromIterable: (iterable: Iterable<string>) => Secret = InternalSecret.fromIterable
58
68
 
59
69
  /**
60
70
  * @since 2.0.0
61
71
  * @category constructors
72
+ * @deprecated
62
73
  */
63
74
  export const fromString: (text: string) => Secret = InternalSecret.fromString
64
75
 
65
76
  /**
66
77
  * @since 2.0.0
67
78
  * @category getters
79
+ * @deprecated
68
80
  */
69
81
  export const value: (self: Secret) => string = InternalSecret.value
70
82
 
71
83
  /**
72
84
  * @since 2.0.0
73
85
  * @category unsafe
86
+ * @deprecated
74
87
  */
75
88
  export const unsafeWipe: (self: Secret) => void = InternalSecret.unsafeWipe