Skip to content

Releases: Effect-TS/effect

[email protected]

14 Feb 18:37
c827931
Compare
Choose a tag to compare

Patch Changes

[email protected]

14 Feb 01:52
a585aa5
Compare
Choose a tag to compare

Minor Changes

  • #4280 8baef83 Thanks @tim-smart! - add Promise based apis to Fiber{Handle,Set,Map} modules

  • #4280 655bfe2 Thanks @gcanti! - Add Effect.transposeOption, closes #3142.

    Converts an Option of an Effect into an Effect of an Option.

    Details

    This function transforms an Option<Effect<A, E, R>> into an
    Effect<Option<A>, E, R>. If the Option is None, the resulting Effect
    will immediately succeed with a None value. If the Option is Some, the
    inner Effect will be executed, and its result wrapped in a Some.

    Example

    import { Effect, Option } from "effect"
    
    //      ┌─── Option<Effect<number, never, never>>
    //      ▼
    const maybe = Option.some(Effect.succeed(42))
    
    //      ┌─── Effect<Option<number>, never, never>
    //      ▼
    const result = Effect.transposeOption(maybe)
    
    console.log(Effect.runSync(result))
    // Output: { _id: 'Option', _tag: 'Some', value: 42 }
  • #4280 d90cbc2 Thanks @indietyp! - Add Effect.whenLogLevel, which conditionally executes an effect if the specified log level is enabled

  • #4280 75632bd Thanks @tim-smart! - add RcMap.touch, for reseting the idle timeout for an item

  • #4280 c874a2e Thanks @LaureRC! - Add HashMap.some

  • #4280 bf865e5 Thanks @tim-smart! - allow accessing args in Effect.fn pipe

  • #4280 f98b2b7 Thanks @tim-smart! - add RcMap.invalidate api, for removing a resource from an RcMap

  • #4280 de8ce92 Thanks @mikearnaldi! - Add Layer.updateService mirroring Effect.updateService

  • #4280 db426a5 Thanks @KhraksMamtsov! - Differ implements Pipeable

  • #4280 6862444 Thanks @thewilkybarkid! - Make it easy to convert a DateTime.Zoned to a DateTime.Utc

  • #4280 5fc8a90 Thanks @gcanti! - Add missing Either.void constructor.

  • #4280 546a492 Thanks @vinassefranche! - Add HashMap.toValues and HashSet.toValues getters

  • #4280 65c4796 Thanks @tim-smart! - add {FiberHandle,FiberSet,FiberMap}.awaitEmpty apis

  • #4280 9760fdc Thanks @gcanti! - Schema: Add standardSchemaV1 API to Generate a Standard Schema v1.

    Example

    import { Schema } from "effect"
    
    const schema = Schema.Struct({
      name: Schema.String
    })
    
    //      ┌─── StandardSchemaV1<{ readonly name: string; }>
    //      ▼
    const standardSchema = Schema.standardSchemaV1(schema)
  • #4280 5b471e7 Thanks @fubhy! - Added Duration.formatIso and Duration.fromIso for formatting and parsing ISO8601 durations.

  • #4280 4f810cc Thanks @tim-smart! - add Effect.filterEffect* apis

    Effect.filterEffectOrElse

    Filters an effect with an effectful predicate, falling back to an alternative
    effect if the predicate fails.

    import { Effect, pipe } from "effect"
    
    // Define a user interface
    interface User {
      readonly name: string
    }
    
    // Simulate an asynchronous authentication function
    declare const auth: () => Promise<User | null>
    
    const program = pipe(
      Effect.promise(() => auth()),
      // Use filterEffectOrElse with an effectful predicate
      Effect.filterEffectOrElse({
        predicate: (user) => Effect.succeed(user !== null),
        orElse: (user) => Effect.fail(new Error(`Unauthorized user: ${user}`))
      })
    )

    Effect.filterEffectOrFail

    Filters an effect with an effectful predicate, failing with a custom error if the predicate fails.

    import { Effect, pipe } from "effect"
    
    // Define a user interface
    interface User {
      readonly name: string
    }
    
    // Simulate an asynchronous authentication function
    declare const auth: () => Promise<User | null>
    
    const program = pipe(
      Effect.promise(() => auth()),
      // Use filterEffectOrFail with an effectful predicate
      Effect.filterEffectOrFail({
        predicate: (user) => Effect.succeed(user !== null),
        orFailWith: (user) => Effect.fail(new Error(`Unauthorized user: ${user}`))
      })
    )

Patch Changes

  • #4280 cf8b2dd Thanks @KhraksMamtsov! - Trie<out A> type annotations have been aligned. The type parameter was made covariant because the structure is immutable.

[email protected]

14 Feb 00:32
9324b18
Compare
Choose a tag to compare

Patch Changes

  • #4440 4018eae Thanks @gcanti! - Schema: add missing support for tuple annotations in TaggedRequest.

  • #4439 543d36d Thanks @gcanti! - Schedule: fix unsafe tapOutput signature.

    Previously, tapOutput allowed using an output type that wasn't properly inferred, leading to potential runtime errors. Now, TypeScript correctly detects mismatches at compile time, preventing unexpected crashes.

    Before (Unsafe, Causes Runtime Error)

    import { Effect, Schedule, Console } from "effect"
    
    const schedule = Schedule.once.pipe(
      Schedule.as<number | string>(1),
      Schedule.tapOutput((s: string) => Console.log(s.trim())) // ❌ Runtime error
    )
    
    Effect.runPromise(Effect.void.pipe(Effect.schedule(schedule)))
    // throws: TypeError: s.trim is not a function

    After (Safe, Catches Type Error at Compile Time)

    import { Console, Schedule } from "effect"
    
    const schedule = Schedule.once.pipe(
      Schedule.as<number | string>(1),
      // ✅ Type Error: Type 'number' is not assignable to type 'string'
      Schedule.tapOutput((s: string) => Console.log(s.trim()))
    )
  • #4447 f70a65a Thanks @gcanti! - Preserve function length property in Effect.fn / Effect.fnUntraced, closes #4435

    Previously, functions created with Effect.fn and Effect.fnUntraced always had a .length of 0, regardless of their actual number of parameters. This has been fixed so that the length property correctly reflects the expected number of arguments.

    Before

    import { Effect } from "effect"
    
    const fn1 = Effect.fn("fn1")(function* (n: number) {
      return n
    })
    
    console.log(fn1.length)
    // Output: 0 ❌ (incorrect)
    
    const fn2 = Effect.fnUntraced(function* (n: number) {
      return n
    })
    
    console.log(fn2.length)
    // Output: 0 ❌ (incorrect)

    After

    import { Effect } from "effect"
    
    const fn1 = Effect.fn("fn1")(function* (n: number) {
      return n
    })
    
    console.log(fn1.length)
    // Output: 1 ✅ (correct)
    
    const fn2 = Effect.fnUntraced(function* (n: number) {
      return n
    })
    
    console.log(fn2.length)
    // Output: 1 ✅ (correct)
  • #4422 ba409f6 Thanks @mikearnaldi! - Fix Context.Tag inference using explicit generics

  • #4432 3d2e356 Thanks @tim-smart! - use Map for Scope finalizers, to ensure they are always added

@effect/[email protected]

14 Feb 18:38
c827931
Compare
Choose a tag to compare

Patch Changes

@effect/[email protected]

14 Feb 01:53
a585aa5
Compare
Choose a tag to compare

@effect/[email protected]

14 Feb 00:33
9324b18
Compare
Choose a tag to compare

@effect/[email protected]

14 Feb 18:38
c827931
Compare
Choose a tag to compare

Patch Changes

@effect/[email protected]

14 Feb 01:53
a585aa5
Compare
Choose a tag to compare

@effect/[email protected]

14 Feb 00:34
9324b18
Compare
Choose a tag to compare

@effect/[email protected]

14 Feb 18:37
c827931
Compare
Choose a tag to compare

Patch Changes