effect-io-ai

Package: effect
Module: Effect

Effect.firstSuccessOf

Runs a sequence of effects and returns the result of the first successful one.

Details

This function allows you to execute a collection of effects in sequence, stopping at the first success. If an effect succeeds, its result is immediately returned, and no further effects in the sequence are executed. However, if all the effects fail, the function will return the error of the last effect.

The execution is sequential, meaning that effects are evaluated one at a time in the order they are provided. This ensures predictable behavior and avoids unnecessary computations.

If the collection of effects is empty, an IllegalArgumentException is thrown, indicating that the operation is invalid without any effects to try.

When to Use

This is particularly useful when you have multiple fallback strategies or alternative sources to obtain a result, such as attempting multiple APIs, retrieving configurations, or accessing resources in a prioritized manner.

Example

import { Effect, Console } from "effect"

interface Config {
  host: string
  port: number
  apiKey: string
}

// Create a configuration object with sample values
const makeConfig = (name: string): Config => ({
  host: `${name}.example.com`,
  port: 8080,
  apiKey: "12345-abcde"
})

// Simulate retrieving configuration from a remote node
const remoteConfig = (name: string): Effect.Effect<Config, Error> =>
  Effect.gen(function* () {
    // Simulate node3 being the only one with available config
    if (name === "node3") {
      yield* Console.log(`Config for ${name} found`)
      return makeConfig(name)
    } else {
      yield* Console.log(`Unavailable config for ${name}`)
      return yield* Effect.fail(new Error(`Config not found for ${name}`))
    }
  })

// Define the master configuration and potential fallback nodes
const masterConfig = remoteConfig("master")
const nodeConfigs = ["node1", "node2", "node3", "node4"].map(remoteConfig)

// Attempt to find a working configuration,
// starting with the master and then falling back to other nodes
const config = Effect.firstSuccessOf([masterConfig, ...nodeConfigs])

// Run the effect to retrieve the configuration
const result = Effect.runSync(config)

console.log(result)
// Output:
// Unavailable config for master
// Unavailable config for node1
// Unavailable config for node2
// Config for node3 found
// { host: 'node3.example.com', port: 8080, apiKey: '12345-abcde' }

Signature

declare const firstSuccessOf: <Eff extends Effect<any, any, any>>(effects: Iterable<Eff>) => Effect<Effect.Success<Eff>, Effect.Error<Eff>, Effect.Context<Eff>>

Source

Since v2.0.0