effect 4.0.0-rc.113 → 4.0.0-rc.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Effect.d.ts +268 -7
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +33 -2
- package/dist/Effect.js.map +1 -1
- package/dist/Effectable.d.ts +1 -2
- package/dist/Effectable.d.ts.map +1 -1
- package/dist/Effectable.js.map +1 -1
- package/dist/FileSystem.d.ts +3 -4
- package/dist/FileSystem.d.ts.map +1 -1
- package/dist/FileSystem.js.map +1 -1
- package/dist/Match.d.ts +1 -14
- package/dist/Match.d.ts.map +1 -1
- package/dist/Schema.d.ts +4 -4
- package/dist/Schema.d.ts.map +1 -1
- package/dist/SchemaAST.d.ts.map +1 -1
- package/dist/SchemaAST.js +43 -23
- package/dist/SchemaAST.js.map +1 -1
- package/dist/SchemaParser.d.ts.map +1 -1
- package/dist/SchemaParser.js +3 -2
- package/dist/SchemaParser.js.map +1 -1
- package/dist/SchemaRepresentation.d.ts +39 -24
- package/dist/SchemaRepresentation.d.ts.map +1 -1
- package/dist/SchemaRepresentation.js +37 -23
- package/dist/SchemaRepresentation.js.map +1 -1
- package/dist/internal/arbitrary/schema.js.map +1 -1
- package/dist/internal/effect.js +16 -8
- package/dist/internal/effect.js.map +1 -1
- package/dist/internal/schema/fromJsonSchemaDocument.js +221 -230
- package/dist/internal/schema/fromJsonSchemaDocument.js.map +1 -1
- package/dist/internal/schema/make.js +8 -3
- package/dist/internal/schema/make.js.map +1 -1
- package/dist/internal/schema/toCodeDocument.js +4 -4
- package/dist/internal/schema/toCodeDocument.js.map +1 -1
- package/dist/internal/schema/toEquivalence.js +2 -2
- package/dist/internal/schema/toEquivalence.js.map +1 -1
- package/dist/internal/schema/toFormatter.js +2 -2
- package/dist/internal/schema/toFormatter.js.map +1 -1
- package/dist/unstable/cli/Prompt.d.ts +6 -2
- package/dist/unstable/cli/Prompt.d.ts.map +1 -1
- package/dist/unstable/cli/Prompt.js +8 -7
- package/dist/unstable/cli/Prompt.js.map +1 -1
- package/dist/unstable/cli/internal/command.d.ts +1 -6
- package/dist/unstable/cli/internal/command.d.ts.map +1 -1
- package/dist/unstable/cli/internal/command.js +2 -0
- package/dist/unstable/cli/internal/command.js.map +1 -1
- package/dist/unstable/http/HttpEffect.d.ts.map +1 -1
- package/dist/unstable/http/HttpEffect.js +6 -2
- package/dist/unstable/http/HttpEffect.js.map +1 -1
- package/dist/unstable/http/HttpServerResponse.d.ts +13 -2
- package/dist/unstable/http/HttpServerResponse.d.ts.map +1 -1
- package/dist/unstable/http/HttpServerResponse.js +19 -5
- package/dist/unstable/http/HttpServerResponse.js.map +1 -1
- package/dist/unstable/persistence/Persistence.d.ts.map +1 -1
- package/dist/unstable/persistence/Persistence.js +2 -10
- package/dist/unstable/persistence/Persistence.js.map +1 -1
- package/package.json +2 -2
- package/src/Effect.ts +271 -7
- package/src/Effectable.ts +2 -2
- package/src/FileSystem.ts +3 -4
- package/src/Match.ts +1 -1
- package/src/Schema.ts +4 -7
- package/src/SchemaAST.ts +48 -25
- package/src/SchemaParser.ts +3 -2
- package/src/SchemaRepresentation.ts +39 -24
- package/src/internal/arbitrary/schema.ts +16 -16
- package/src/internal/effect.ts +34 -11
- package/src/internal/schema/fromJsonSchemaDocument.ts +294 -268
- package/src/internal/schema/make.ts +9 -4
- package/src/internal/schema/toCodeDocument.ts +4 -4
- package/src/internal/schema/toEquivalence.ts +2 -2
- package/src/internal/schema/toFormatter.ts +2 -2
- package/src/unstable/cli/Prompt.ts +22 -11
- package/src/unstable/cli/internal/command.ts +2 -0
- package/src/unstable/http/HttpEffect.ts +5 -2
- package/src/unstable/http/HttpServerResponse.ts +21 -5
- package/src/unstable/persistence/Persistence.ts +6 -16
package/src/Effect.ts
CHANGED
|
@@ -13941,8 +13941,8 @@ export const onExitFilter: {
|
|
|
13941
13941
|
export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>> = internal.cached
|
|
13942
13942
|
|
|
13943
13943
|
/**
|
|
13944
|
-
* Returns an effect that caches its result for a
|
|
13945
|
-
* known as "timeToLive" (TTL).
|
|
13944
|
+
* Returns an effect that caches its result for a fixed duration or a duration
|
|
13945
|
+
* computed from its `Exit`, known as "timeToLive" (TTL).
|
|
13946
13946
|
*
|
|
13947
13947
|
* **When to use**
|
|
13948
13948
|
*
|
|
@@ -13961,6 +13961,17 @@ export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
|
13961
13961
|
* After the specified duration has passed, the cache expires, and the effect
|
|
13962
13962
|
* will be recomputed upon the next evaluation.
|
|
13963
13963
|
*
|
|
13964
|
+
* `timeToLive` accepts a `Duration.Input` or a function from `Exit<A, E>` to
|
|
13965
|
+
* `Duration.Input`. The function runs once after each fresh computation,
|
|
13966
|
+
* including failures, so successes and failures can have different TTLs. It
|
|
13967
|
+
* does not run when the cache is created or when a cached result is reused.
|
|
13968
|
+
* The callback also receives interruption exits, which are cached for the
|
|
13969
|
+
* returned duration.
|
|
13970
|
+
*
|
|
13971
|
+
* The TTL starts when the computation completes. Concurrent callers share the
|
|
13972
|
+
* pending computation. A zero TTL expires immediately, and an infinite TTL
|
|
13973
|
+
* keeps the result indefinitely.
|
|
13974
|
+
*
|
|
13964
13975
|
* **Example** (Memoizing an effect with TTL)
|
|
13965
13976
|
*
|
|
13966
13977
|
* ```ts import.meta.vitest
|
|
@@ -13985,6 +13996,26 @@ export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
|
13985
13996
|
* output // => ["expensive task...", "result 1", "result 1", "result 1"]
|
|
13986
13997
|
* ```
|
|
13987
13998
|
*
|
|
13999
|
+
* **Example** (Caching successes while retrying failures)
|
|
14000
|
+
*
|
|
14001
|
+
* ```ts import.meta.vitest
|
|
14002
|
+
* import { Effect, Exit } from "effect"
|
|
14003
|
+
*
|
|
14004
|
+
* let attempts = 0
|
|
14005
|
+
* const task = Effect.suspend(() =>
|
|
14006
|
+
* ++attempts === 1 ? Effect.fail("temporary failure") : Effect.succeed(42)
|
|
14007
|
+
* )
|
|
14008
|
+
* const program = Effect.gen(function*() {
|
|
14009
|
+
* const cached = yield* task.pipe(
|
|
14010
|
+
* Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? "1 hour" : 0)
|
|
14011
|
+
* )
|
|
14012
|
+
* yield* Effect.exit(cached)
|
|
14013
|
+
* return yield* cached
|
|
14014
|
+
* })
|
|
14015
|
+
*
|
|
14016
|
+
* Effect.runSync(program) // => 42
|
|
14017
|
+
* ```
|
|
14018
|
+
*
|
|
13988
14019
|
* @see {@link cached} for a similar function that caches the result
|
|
13989
14020
|
* indefinitely.
|
|
13990
14021
|
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
|
@@ -13994,8 +14025,8 @@ export const cached: <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
|
13994
14025
|
*/
|
|
13995
14026
|
export const cachedWithTTL: {
|
|
13996
14027
|
/**
|
|
13997
|
-
* Returns an effect that caches its result for a
|
|
13998
|
-
* known as "timeToLive" (TTL).
|
|
14028
|
+
* Returns an effect that caches its result for a fixed duration or a duration
|
|
14029
|
+
* computed from its `Exit`, known as "timeToLive" (TTL).
|
|
13999
14030
|
*
|
|
14000
14031
|
* **When to use**
|
|
14001
14032
|
*
|
|
@@ -14014,6 +14045,17 @@ export const cachedWithTTL: {
|
|
|
14014
14045
|
* After the specified duration has passed, the cache expires, and the effect
|
|
14015
14046
|
* will be recomputed upon the next evaluation.
|
|
14016
14047
|
*
|
|
14048
|
+
* `timeToLive` accepts a `Duration.Input` or a function from `Exit<A, E>` to
|
|
14049
|
+
* `Duration.Input`. The function runs once after each fresh computation,
|
|
14050
|
+
* including failures, so successes and failures can have different TTLs. It
|
|
14051
|
+
* does not run when the cache is created or when a cached result is reused.
|
|
14052
|
+
* The callback also receives interruption exits, which are cached for the
|
|
14053
|
+
* returned duration.
|
|
14054
|
+
*
|
|
14055
|
+
* The TTL starts when the computation completes. Concurrent callers share the
|
|
14056
|
+
* pending computation. A zero TTL expires immediately, and an infinite TTL
|
|
14057
|
+
* keeps the result indefinitely.
|
|
14058
|
+
*
|
|
14017
14059
|
* **Example** (Memoizing an effect with TTL)
|
|
14018
14060
|
*
|
|
14019
14061
|
* ```ts import.meta.vitest
|
|
@@ -14038,6 +14080,110 @@ export const cachedWithTTL: {
|
|
|
14038
14080
|
* output // => ["expensive task...", "result 1", "result 1", "result 1"]
|
|
14039
14081
|
* ```
|
|
14040
14082
|
*
|
|
14083
|
+
* **Example** (Caching successes while retrying failures)
|
|
14084
|
+
*
|
|
14085
|
+
* ```ts import.meta.vitest
|
|
14086
|
+
* import { Effect, Exit } from "effect"
|
|
14087
|
+
*
|
|
14088
|
+
* let attempts = 0
|
|
14089
|
+
* const task = Effect.suspend(() =>
|
|
14090
|
+
* ++attempts === 1 ? Effect.fail("temporary failure") : Effect.succeed(42)
|
|
14091
|
+
* )
|
|
14092
|
+
* const program = Effect.gen(function*() {
|
|
14093
|
+
* const cached = yield* task.pipe(
|
|
14094
|
+
* Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? "1 hour" : 0)
|
|
14095
|
+
* )
|
|
14096
|
+
* yield* Effect.exit(cached)
|
|
14097
|
+
* return yield* cached
|
|
14098
|
+
* })
|
|
14099
|
+
*
|
|
14100
|
+
* Effect.runSync(program) // => 42
|
|
14101
|
+
* ```
|
|
14102
|
+
*
|
|
14103
|
+
* @see {@link cached} for a similar function that caches the result
|
|
14104
|
+
* indefinitely.
|
|
14105
|
+
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
|
14106
|
+
* additional effect for manually invalidating the cached value.
|
|
14107
|
+
* @category caching
|
|
14108
|
+
* @since 2.0.0
|
|
14109
|
+
*/
|
|
14110
|
+
<A, E>(timeToLive: (exit: Exit.Exit<A, E>) => Duration.Input): <R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
14111
|
+
/**
|
|
14112
|
+
* Returns an effect that caches its result for a fixed duration or a duration
|
|
14113
|
+
* computed from its `Exit`, known as "timeToLive" (TTL).
|
|
14114
|
+
*
|
|
14115
|
+
* **When to use**
|
|
14116
|
+
*
|
|
14117
|
+
* Use when you need a costly effect result to be reused for a bounded duration
|
|
14118
|
+
* before being recomputed.
|
|
14119
|
+
*
|
|
14120
|
+
* **Details**
|
|
14121
|
+
*
|
|
14122
|
+
* This function is used to cache the result of an effect for a specified amount
|
|
14123
|
+
* of time. This means that the first time the effect is evaluated, its result
|
|
14124
|
+
* is computed and stored.
|
|
14125
|
+
*
|
|
14126
|
+
* If the effect is evaluated again within the specified `timeToLive`, the
|
|
14127
|
+
* cached result will be used, avoiding recomputation.
|
|
14128
|
+
*
|
|
14129
|
+
* After the specified duration has passed, the cache expires, and the effect
|
|
14130
|
+
* will be recomputed upon the next evaluation.
|
|
14131
|
+
*
|
|
14132
|
+
* `timeToLive` accepts a `Duration.Input` or a function from `Exit<A, E>` to
|
|
14133
|
+
* `Duration.Input`. The function runs once after each fresh computation,
|
|
14134
|
+
* including failures, so successes and failures can have different TTLs. It
|
|
14135
|
+
* does not run when the cache is created or when a cached result is reused.
|
|
14136
|
+
* The callback also receives interruption exits, which are cached for the
|
|
14137
|
+
* returned duration.
|
|
14138
|
+
*
|
|
14139
|
+
* The TTL starts when the computation completes. Concurrent callers share the
|
|
14140
|
+
* pending computation. A zero TTL expires immediately, and an infinite TTL
|
|
14141
|
+
* keeps the result indefinitely.
|
|
14142
|
+
*
|
|
14143
|
+
* **Example** (Memoizing an effect with TTL)
|
|
14144
|
+
*
|
|
14145
|
+
* ```ts import.meta.vitest
|
|
14146
|
+
* import { Effect } from "effect"
|
|
14147
|
+
* const output: Array<unknown> = []
|
|
14148
|
+
* const record = (value: unknown) => Effect.sync(() => { output.push(value) })
|
|
14149
|
+
*
|
|
14150
|
+
* let i = 1
|
|
14151
|
+
* const expensiveTask = Effect.sync(() => {
|
|
14152
|
+
* void output.push("expensive task...")
|
|
14153
|
+
* return `result ${i++}`
|
|
14154
|
+
* })
|
|
14155
|
+
*
|
|
14156
|
+
* const program = Effect.gen(function*() {
|
|
14157
|
+
* const cached = yield* Effect.cachedWithTTL(expensiveTask, "1 hour")
|
|
14158
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14159
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14160
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14161
|
+
* })
|
|
14162
|
+
*
|
|
14163
|
+
* Effect.runSync(program)
|
|
14164
|
+
* output // => ["expensive task...", "result 1", "result 1", "result 1"]
|
|
14165
|
+
* ```
|
|
14166
|
+
*
|
|
14167
|
+
* **Example** (Caching successes while retrying failures)
|
|
14168
|
+
*
|
|
14169
|
+
* ```ts import.meta.vitest
|
|
14170
|
+
* import { Effect, Exit } from "effect"
|
|
14171
|
+
*
|
|
14172
|
+
* let attempts = 0
|
|
14173
|
+
* const task = Effect.suspend(() =>
|
|
14174
|
+
* ++attempts === 1 ? Effect.fail("temporary failure") : Effect.succeed(42)
|
|
14175
|
+
* )
|
|
14176
|
+
* const program = Effect.gen(function*() {
|
|
14177
|
+
* const cached = yield* task.pipe(
|
|
14178
|
+
* Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? "1 hour" : 0)
|
|
14179
|
+
* )
|
|
14180
|
+
* yield* Effect.exit(cached)
|
|
14181
|
+
* return yield* cached
|
|
14182
|
+
* })
|
|
14183
|
+
*
|
|
14184
|
+
* Effect.runSync(program) // => 42
|
|
14185
|
+
* ```
|
|
14186
|
+
*
|
|
14041
14187
|
* @see {@link cached} for a similar function that caches the result
|
|
14042
14188
|
* indefinitely.
|
|
14043
14189
|
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
|
@@ -14047,8 +14193,92 @@ export const cachedWithTTL: {
|
|
|
14047
14193
|
*/
|
|
14048
14194
|
(timeToLive: Duration.Input): <A, E, R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
14049
14195
|
/**
|
|
14050
|
-
* Returns an effect that caches its result for a
|
|
14051
|
-
* known as "timeToLive" (TTL).
|
|
14196
|
+
* Returns an effect that caches its result for a fixed duration or a duration
|
|
14197
|
+
* computed from its `Exit`, known as "timeToLive" (TTL).
|
|
14198
|
+
*
|
|
14199
|
+
* **When to use**
|
|
14200
|
+
*
|
|
14201
|
+
* Use when you need a costly effect result to be reused for a bounded duration
|
|
14202
|
+
* before being recomputed.
|
|
14203
|
+
*
|
|
14204
|
+
* **Details**
|
|
14205
|
+
*
|
|
14206
|
+
* This function is used to cache the result of an effect for a specified amount
|
|
14207
|
+
* of time. This means that the first time the effect is evaluated, its result
|
|
14208
|
+
* is computed and stored.
|
|
14209
|
+
*
|
|
14210
|
+
* If the effect is evaluated again within the specified `timeToLive`, the
|
|
14211
|
+
* cached result will be used, avoiding recomputation.
|
|
14212
|
+
*
|
|
14213
|
+
* After the specified duration has passed, the cache expires, and the effect
|
|
14214
|
+
* will be recomputed upon the next evaluation.
|
|
14215
|
+
*
|
|
14216
|
+
* `timeToLive` accepts a `Duration.Input` or a function from `Exit<A, E>` to
|
|
14217
|
+
* `Duration.Input`. The function runs once after each fresh computation,
|
|
14218
|
+
* including failures, so successes and failures can have different TTLs. It
|
|
14219
|
+
* does not run when the cache is created or when a cached result is reused.
|
|
14220
|
+
* The callback also receives interruption exits, which are cached for the
|
|
14221
|
+
* returned duration.
|
|
14222
|
+
*
|
|
14223
|
+
* The TTL starts when the computation completes. Concurrent callers share the
|
|
14224
|
+
* pending computation. A zero TTL expires immediately, and an infinite TTL
|
|
14225
|
+
* keeps the result indefinitely.
|
|
14226
|
+
*
|
|
14227
|
+
* **Example** (Memoizing an effect with TTL)
|
|
14228
|
+
*
|
|
14229
|
+
* ```ts import.meta.vitest
|
|
14230
|
+
* import { Effect } from "effect"
|
|
14231
|
+
* const output: Array<unknown> = []
|
|
14232
|
+
* const record = (value: unknown) => Effect.sync(() => { output.push(value) })
|
|
14233
|
+
*
|
|
14234
|
+
* let i = 1
|
|
14235
|
+
* const expensiveTask = Effect.sync(() => {
|
|
14236
|
+
* void output.push("expensive task...")
|
|
14237
|
+
* return `result ${i++}`
|
|
14238
|
+
* })
|
|
14239
|
+
*
|
|
14240
|
+
* const program = Effect.gen(function*() {
|
|
14241
|
+
* const cached = yield* Effect.cachedWithTTL(expensiveTask, "1 hour")
|
|
14242
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14243
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14244
|
+
* yield* cached.pipe(Effect.andThen(record))
|
|
14245
|
+
* })
|
|
14246
|
+
*
|
|
14247
|
+
* Effect.runSync(program)
|
|
14248
|
+
* output // => ["expensive task...", "result 1", "result 1", "result 1"]
|
|
14249
|
+
* ```
|
|
14250
|
+
*
|
|
14251
|
+
* **Example** (Caching successes while retrying failures)
|
|
14252
|
+
*
|
|
14253
|
+
* ```ts import.meta.vitest
|
|
14254
|
+
* import { Effect, Exit } from "effect"
|
|
14255
|
+
*
|
|
14256
|
+
* let attempts = 0
|
|
14257
|
+
* const task = Effect.suspend(() =>
|
|
14258
|
+
* ++attempts === 1 ? Effect.fail("temporary failure") : Effect.succeed(42)
|
|
14259
|
+
* )
|
|
14260
|
+
* const program = Effect.gen(function*() {
|
|
14261
|
+
* const cached = yield* task.pipe(
|
|
14262
|
+
* Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? "1 hour" : 0)
|
|
14263
|
+
* )
|
|
14264
|
+
* yield* Effect.exit(cached)
|
|
14265
|
+
* return yield* cached
|
|
14266
|
+
* })
|
|
14267
|
+
*
|
|
14268
|
+
* Effect.runSync(program) // => 42
|
|
14269
|
+
* ```
|
|
14270
|
+
*
|
|
14271
|
+
* @see {@link cached} for a similar function that caches the result
|
|
14272
|
+
* indefinitely.
|
|
14273
|
+
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
|
14274
|
+
* additional effect for manually invalidating the cached value.
|
|
14275
|
+
* @category caching
|
|
14276
|
+
* @since 2.0.0
|
|
14277
|
+
*/
|
|
14278
|
+
<A, E>(timeToLive: Duration.Input | ((exit: Exit.Exit<A, E>) => Duration.Input)): <R>(self: Effect<A, E, R>) => Effect<Effect<A, E, R>>
|
|
14279
|
+
/**
|
|
14280
|
+
* Returns an effect that caches its result for a fixed duration or a duration
|
|
14281
|
+
* computed from its `Exit`, known as "timeToLive" (TTL).
|
|
14052
14282
|
*
|
|
14053
14283
|
* **When to use**
|
|
14054
14284
|
*
|
|
@@ -14067,6 +14297,17 @@ export const cachedWithTTL: {
|
|
|
14067
14297
|
* After the specified duration has passed, the cache expires, and the effect
|
|
14068
14298
|
* will be recomputed upon the next evaluation.
|
|
14069
14299
|
*
|
|
14300
|
+
* `timeToLive` accepts a `Duration.Input` or a function from `Exit<A, E>` to
|
|
14301
|
+
* `Duration.Input`. The function runs once after each fresh computation,
|
|
14302
|
+
* including failures, so successes and failures can have different TTLs. It
|
|
14303
|
+
* does not run when the cache is created or when a cached result is reused.
|
|
14304
|
+
* The callback also receives interruption exits, which are cached for the
|
|
14305
|
+
* returned duration.
|
|
14306
|
+
*
|
|
14307
|
+
* The TTL starts when the computation completes. Concurrent callers share the
|
|
14308
|
+
* pending computation. A zero TTL expires immediately, and an infinite TTL
|
|
14309
|
+
* keeps the result indefinitely.
|
|
14310
|
+
*
|
|
14070
14311
|
* **Example** (Memoizing an effect with TTL)
|
|
14071
14312
|
*
|
|
14072
14313
|
* ```ts import.meta.vitest
|
|
@@ -14091,6 +14332,26 @@ export const cachedWithTTL: {
|
|
|
14091
14332
|
* output // => ["expensive task...", "result 1", "result 1", "result 1"]
|
|
14092
14333
|
* ```
|
|
14093
14334
|
*
|
|
14335
|
+
* **Example** (Caching successes while retrying failures)
|
|
14336
|
+
*
|
|
14337
|
+
* ```ts import.meta.vitest
|
|
14338
|
+
* import { Effect, Exit } from "effect"
|
|
14339
|
+
*
|
|
14340
|
+
* let attempts = 0
|
|
14341
|
+
* const task = Effect.suspend(() =>
|
|
14342
|
+
* ++attempts === 1 ? Effect.fail("temporary failure") : Effect.succeed(42)
|
|
14343
|
+
* )
|
|
14344
|
+
* const program = Effect.gen(function*() {
|
|
14345
|
+
* const cached = yield* task.pipe(
|
|
14346
|
+
* Effect.cachedWithTTL((exit) => Exit.isSuccess(exit) ? "1 hour" : 0)
|
|
14347
|
+
* )
|
|
14348
|
+
* yield* Effect.exit(cached)
|
|
14349
|
+
* return yield* cached
|
|
14350
|
+
* })
|
|
14351
|
+
*
|
|
14352
|
+
* Effect.runSync(program) // => 42
|
|
14353
|
+
* ```
|
|
14354
|
+
*
|
|
14094
14355
|
* @see {@link cached} for a similar function that caches the result
|
|
14095
14356
|
* indefinitely.
|
|
14096
14357
|
* @see {@link cachedInvalidateWithTTL} for a similar function that includes an
|
|
@@ -14098,7 +14359,10 @@ export const cachedWithTTL: {
|
|
|
14098
14359
|
* @category caching
|
|
14099
14360
|
* @since 2.0.0
|
|
14100
14361
|
*/
|
|
14101
|
-
<A, E, R>(
|
|
14362
|
+
<A, E, R>(
|
|
14363
|
+
self: Effect<A, E, R>,
|
|
14364
|
+
timeToLive: Duration.Input | ((exit: Exit.Exit<A, E>) => Duration.Input)
|
|
14365
|
+
): Effect<Effect<A, E, R>>
|
|
14102
14366
|
} = internal.cachedWithTTL
|
|
14103
14367
|
|
|
14104
14368
|
/**
|
package/src/Effectable.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import type * as Effect from "./Effect.ts"
|
|
10
10
|
import type * as Fiber from "./Fiber.ts"
|
|
11
|
-
import {
|
|
11
|
+
import { evaluate, makePrimitiveProto } from "./internal/core.ts"
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Create a low-level `Effect` prototype.
|
|
@@ -78,7 +78,7 @@ type AsEffectReturn<Self> = Self extends {
|
|
|
78
78
|
|
|
79
79
|
declare abstract class MixinBase extends Class<any, any, any> {
|
|
80
80
|
constructor(...args: ReadonlyArray<any>)
|
|
81
|
-
override readonly [
|
|
81
|
+
override readonly [Effect.TypeId]: AsEffectReturn<this>[Effect.TypeId]
|
|
82
82
|
override [Symbol.iterator](): Effect.EffectIterator<AsEffectReturn<this>>
|
|
83
83
|
}
|
|
84
84
|
|
package/src/FileSystem.ts
CHANGED
|
@@ -906,10 +906,9 @@ export declare namespace File {
|
|
|
906
906
|
* permissions, and size information. This structure is returned by file
|
|
907
907
|
* stat operations.
|
|
908
908
|
*
|
|
909
|
-
* Node and Bun preserve `size` and `blksize` exactly.
|
|
910
|
-
*
|
|
911
|
-
*
|
|
912
|
-
* can therefore prevent stat and HTTP file serving even for small files.
|
|
909
|
+
* Node and Bun preserve `size` and `blksize` exactly. Optional `number`
|
|
910
|
+
* metadata is `Option.none()` when absent or outside the safe integer range.
|
|
911
|
+
* Unsafe `dev` or `mode` values fail the stat operation with `BadArgument`.
|
|
913
912
|
*
|
|
914
913
|
* **Example** (Inspecting file information)
|
|
915
914
|
*
|
package/src/Match.ts
CHANGED
|
@@ -22,7 +22,7 @@ const TypeId = internal.TypeId
|
|
|
22
22
|
|
|
23
23
|
// The conditional must stay deferred until P is inferred. Replacing it with an
|
|
24
24
|
// intersection loses contextual typing for nested generic calls (microsoft/TypeScript#52864).
|
|
25
|
-
type Contextual<P, Fallback> =
|
|
25
|
+
type Contextual<P, Fallback> = [P] extends [never] ? Fallback : P
|
|
26
26
|
|
|
27
27
|
type TagHandlers<D extends string, R, Ret> = {
|
|
28
28
|
readonly [Tag in Types.Tags<D, R> & string]: (_: Extract<R, Record<D, Tag>>) => Ret
|
package/src/Schema.ts
CHANGED
|
@@ -15512,9 +15512,6 @@ export function resolveAnnotations<S extends Constraint>(
|
|
|
15512
15512
|
export function resolveAnnotationsKey<S extends Constraint>(schema: S): Annotations.Key<S["Type"]> | undefined {
|
|
15513
15513
|
return schema.ast.context?.annotations
|
|
15514
15514
|
}
|
|
15515
|
-
/** @internal */
|
|
15516
|
-
type AnnotationSchemaConstraint = Constraint
|
|
15517
|
-
|
|
15518
15515
|
/**
|
|
15519
15516
|
* The `Annotations` namespace groups all annotation interfaces used to attach
|
|
15520
15517
|
* metadata to schemas. Annotations control documentation, validation messages,
|
|
@@ -15833,7 +15830,7 @@ export declare namespace Annotations {
|
|
|
15833
15830
|
*
|
|
15834
15831
|
* @since 4.0.0
|
|
15835
15832
|
*/
|
|
15836
|
-
readonly arbitraryConstraint?: ToArbitrary.
|
|
15833
|
+
readonly arbitraryConstraint?: ToArbitrary.FilterConstraint<any> | undefined
|
|
15837
15834
|
/**
|
|
15838
15835
|
* Marks the filter as *structural*, meaning it applies to the shape or
|
|
15839
15836
|
* structure of the container (e.g., array length, object keys) rather than
|
|
@@ -15899,7 +15896,7 @@ export declare namespace Annotations {
|
|
|
15899
15896
|
* @category models
|
|
15900
15897
|
* @since 4.0.0
|
|
15901
15898
|
*/
|
|
15902
|
-
interface
|
|
15899
|
+
interface FilterConstraint<T = unknown> extends GenerationConstraint<T> {
|
|
15903
15900
|
readonly order?: Order.Order<T> | undefined
|
|
15904
15901
|
}
|
|
15905
15902
|
/**
|
|
@@ -15908,7 +15905,7 @@ export declare namespace Annotations {
|
|
|
15908
15905
|
* @category models
|
|
15909
15906
|
* @since 4.0.0
|
|
15910
15907
|
*/
|
|
15911
|
-
interface DeclarationInput<T, Parameters extends ReadonlyArray<
|
|
15908
|
+
interface DeclarationInput<T, Parameters extends ReadonlyArray<Constraint>> {
|
|
15912
15909
|
readonly typeParameters: TypeParameters.Type<Parameters>
|
|
15913
15910
|
readonly constraint: GenerationConstraint<T> | undefined
|
|
15914
15911
|
}
|
|
@@ -15918,7 +15915,7 @@ export declare namespace Annotations {
|
|
|
15918
15915
|
* @category models
|
|
15919
15916
|
* @since 4.0.0
|
|
15920
15917
|
*/
|
|
15921
|
-
interface Declaration<T, Parameters extends ReadonlyArray<
|
|
15918
|
+
interface Declaration<T, Parameters extends ReadonlyArray<Constraint>> {
|
|
15922
15919
|
(input: DeclarationInput<T, Parameters>): SchemaAST.Link
|
|
15923
15920
|
}
|
|
15924
15921
|
}
|
package/src/SchemaAST.ts
CHANGED
|
@@ -1377,10 +1377,18 @@ type TemplateLiteralPart =
|
|
|
1377
1377
|
| TemplateLiteral
|
|
1378
1378
|
| Union<TemplateLiteralPart>
|
|
1379
1379
|
|
|
1380
|
-
function
|
|
1380
|
+
function formatTemplateLiteralPath(path: string | number): string {
|
|
1381
|
+
return typeof path === "number" ? `parts[${path}]` : path
|
|
1382
|
+
}
|
|
1383
|
+
|
|
1384
|
+
function isTemplateLiteralPart(
|
|
1385
|
+
ast: AST,
|
|
1386
|
+
path: string | number,
|
|
1387
|
+
validated: Set<AST>
|
|
1388
|
+
): ast is TemplateLiteralPart {
|
|
1381
1389
|
if (validated.has(ast)) return true
|
|
1382
1390
|
if (ast.encoding) {
|
|
1383
|
-
throw new Error(`TemplateLiteral parts cannot have an encoding at ${path}`)
|
|
1391
|
+
throw new Error(`TemplateLiteral parts cannot have an encoding at ${formatTemplateLiteralPath(path)}`)
|
|
1384
1392
|
}
|
|
1385
1393
|
let valid: boolean
|
|
1386
1394
|
switch (ast._tag) {
|
|
@@ -1392,14 +1400,18 @@ function isTemplateLiteralPart(ast: AST, path: string, validated: WeakSet<AST>):
|
|
|
1392
1400
|
case "Literal":
|
|
1393
1401
|
valid = !ast.checks
|
|
1394
1402
|
break
|
|
1395
|
-
case "TemplateLiteral":
|
|
1403
|
+
case "TemplateLiteral": {
|
|
1404
|
+
const currentPath = formatTemplateLiteralPath(path)
|
|
1396
1405
|
valid = !ast.checks &&
|
|
1397
|
-
ast.parts.every((part, index) => isTemplateLiteralPart(part, `${
|
|
1406
|
+
ast.parts.every((part, index) => isTemplateLiteralPart(part, `${currentPath}.parts[${index}]`, validated))
|
|
1398
1407
|
break
|
|
1399
|
-
|
|
1408
|
+
}
|
|
1409
|
+
case "Union": {
|
|
1410
|
+
const currentPath = formatTemplateLiteralPath(path)
|
|
1400
1411
|
valid = !ast.checks &&
|
|
1401
|
-
ast.types.every((part, index) => isTemplateLiteralPart(part, `${
|
|
1412
|
+
ast.types.every((part, index) => isTemplateLiteralPart(part, `${currentPath}.types[${index}]`, validated))
|
|
1402
1413
|
break
|
|
1414
|
+
}
|
|
1403
1415
|
default:
|
|
1404
1416
|
return false
|
|
1405
1417
|
}
|
|
@@ -1477,10 +1489,10 @@ export const TemplateLiteral: new(
|
|
|
1477
1489
|
super(annotations, checks, encoding, context)
|
|
1478
1490
|
const encodedParts: Array<TemplateLiteralPart> = []
|
|
1479
1491
|
const literals: Array<string | undefined> = []
|
|
1480
|
-
const validated = new
|
|
1492
|
+
const validated = new Set<AST>()
|
|
1481
1493
|
for (let index = 0; index < parts.length; index++) {
|
|
1482
1494
|
const part = parts[index]
|
|
1483
|
-
if (!isTemplateLiteralPart(part,
|
|
1495
|
+
if (!isTemplateLiteralPart(part, index, validated)) {
|
|
1484
1496
|
throw new Error(`Invalid TemplateLiteral part ${part._tag}`)
|
|
1485
1497
|
}
|
|
1486
1498
|
encodedParts.push(part)
|
|
@@ -2573,8 +2585,23 @@ function isIndexSignatureParameterSide(ast: AST): ast is IndexSignatureParameter
|
|
|
2573
2585
|
}
|
|
2574
2586
|
}
|
|
2575
2587
|
|
|
2588
|
+
function isIndexSignatureParameterEncodedSide(ast: AST): boolean {
|
|
2589
|
+
const encoded = getLastEncoding(ast)
|
|
2590
|
+
switch (encoded._tag) {
|
|
2591
|
+
case "String":
|
|
2592
|
+
case "Number":
|
|
2593
|
+
case "Symbol":
|
|
2594
|
+
case "TemplateLiteral":
|
|
2595
|
+
return true
|
|
2596
|
+
case "Union":
|
|
2597
|
+
return encoded.types.every(isIndexSignatureParameterEncodedSide)
|
|
2598
|
+
default:
|
|
2599
|
+
return false
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2576
2603
|
function isIndexSignatureParameter(ast: AST): ast is IndexSignatureParameter {
|
|
2577
|
-
return isIndexSignatureParameterSide(ast) &&
|
|
2604
|
+
return isIndexSignatureParameterSide(ast) && isIndexSignatureParameterEncodedSide(ast)
|
|
2578
2605
|
}
|
|
2579
2606
|
|
|
2580
2607
|
/**
|
|
@@ -2727,7 +2754,16 @@ export const Objects: new(
|
|
|
2727
2754
|
this.encodingChecks = encodingChecks
|
|
2728
2755
|
|
|
2729
2756
|
// Duplicate property signatures
|
|
2730
|
-
const
|
|
2757
|
+
const seen = new Set<PropertyKey>()
|
|
2758
|
+
const duplicates: Array<PropertyKey> = []
|
|
2759
|
+
for (const propertySignature of propertySignatures) {
|
|
2760
|
+
const name = propertySignature.name
|
|
2761
|
+
if (seen.has(name)) {
|
|
2762
|
+
duplicates.push(name)
|
|
2763
|
+
} else {
|
|
2764
|
+
seen.add(name)
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2731
2767
|
if (duplicates.length > 0) {
|
|
2732
2768
|
throw new Error(`Duplicate identifiers: ${JSON.stringify(duplicates)}. ts(2300)`)
|
|
2733
2769
|
}
|
|
@@ -3780,20 +3816,6 @@ function formatIsOptional(isOptional: boolean | undefined): string {
|
|
|
3780
3816
|
return isOptional ? "?" : ""
|
|
3781
3817
|
}
|
|
3782
3818
|
|
|
3783
|
-
/** @internal */
|
|
3784
|
-
export function memoizeThunk<A>(f: () => A): () => A {
|
|
3785
|
-
let done = false
|
|
3786
|
-
let a: A
|
|
3787
|
-
return () => {
|
|
3788
|
-
if (done) {
|
|
3789
|
-
return a
|
|
3790
|
-
}
|
|
3791
|
-
a = f()
|
|
3792
|
-
done = true
|
|
3793
|
-
return a
|
|
3794
|
-
}
|
|
3795
|
-
}
|
|
3796
|
-
|
|
3797
3819
|
/**
|
|
3798
3820
|
* AST node for lazy/recursive schemas.
|
|
3799
3821
|
*
|
|
@@ -3866,7 +3888,8 @@ export const Suspend: new(
|
|
|
3866
3888
|
throw new Error("Cannot add checks to Suspend")
|
|
3867
3889
|
}
|
|
3868
3890
|
super(annotations, undefined, encoding, context)
|
|
3869
|
-
|
|
3891
|
+
let ast: AST
|
|
3892
|
+
this.thunk = () => ast ??= thunk()
|
|
3870
3893
|
}
|
|
3871
3894
|
/** @internal */
|
|
3872
3895
|
getParser(compile: SchemaParser.Compiler): SchemaParser.Parser {
|
package/src/SchemaParser.ts
CHANGED
|
@@ -41,9 +41,10 @@ import * as SchemaIssue from "./SchemaIssue.ts"
|
|
|
41
41
|
* @since 4.0.0
|
|
42
42
|
*/
|
|
43
43
|
export function makeEffect<S extends Schema.Constraint>(schema: S) {
|
|
44
|
-
const
|
|
44
|
+
const ast = schema.ast
|
|
45
|
+
let parser: ReturnType<typeof runWithCompiler<S["Type"], never>>
|
|
45
46
|
return (input: S["~type.make.in"], options?: Schema.MakeOptions): Effect.Effect<S["Type"], SchemaIssue.Issue> => {
|
|
46
|
-
return parser(
|
|
47
|
+
return (parser ??= runWithCompiler<S["Type"], never>(constructorCompiler, SchemaAST.toType(ast)))(
|
|
47
48
|
input,
|
|
48
49
|
options?.disableChecks
|
|
49
50
|
? options?.parseOptions ? { ...options.parseOptions, disableChecks: true } : { disableChecks: true }
|