/** * Stores Effect services in typed maps. * * A `Context` holds service implementations under `Context.Service` or * `Context.Reference` keys, and its type records which keys are present. * Effects use contexts as their environment, so services can be provided once * instead of passed through every function call. This module includes helpers * for creating keys, building contexts, adding and reading services, merging * contexts, and selecting or removing services. * * @stability stable * @since 4.0.0 */ import type { Effect, EffectIterator } from "./Effect.ts"; import * as Equal from "./Equal.ts"; import { type LazyArg } from "./Function.ts"; import type { Inspectable } from "./Inspectable.ts"; import * as Option from "./Option.ts"; import type { Pipeable } from "./Pipeable.ts"; import type * as Types from "./Types.ts"; /** * String literal type used as the runtime type identifier for `Context` * service keys. * * @stability stable * @category type IDs * @since 4.0.0 */ export type ServiceTypeId = "~effect/Context/Service"; /** * Runtime type identifier attached to `Context` service keys and used by * `isKey` to recognize them. * * @stability stable * @category type IDs * @since 4.0.0 */ export declare const ServiceTypeId: ServiceTypeId; /** * Typed identifier for a service stored in a `Context`. * * **When to use** * * Use as the typed handle for storing, retrieving, and requiring a specific * service in a `Context`. * * **Details** * * `Identifier` tracks the requirement in Effect types, while `Shape` is the * service implementation retrieved by the key. A key is also an Effect value, * so yielding it inside `Effect.gen` retrieves the service from the current * fiber context. * * @see {@link Service} for creating required service keys * @see {@link Reference} for creating service keys with default values * * @stability stable * @category models * @since 4.0.0 */ export interface Key extends Effect { readonly [ServiceTypeId]: ServiceTypeId; readonly Service: Shape; readonly Identifier: Identifier; readonly key: string; } /** * Context key with helper methods for working with a service. * * **Details** * * `context` creates a one-service `Context`, `use` and `useSync` retrieve the * service from the current Effect context before applying a function, and `of` * is a type-level helper for service values. * * **Example** (Defining a service key) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Define an identifier for a database service * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * // The key can be used to store and retrieve services * const context = Context.make(Database, { query: (sql) => `Result: ${sql}` }) * Context.get(context, Database).query("SELECT 1") // => "Result: SELECT 1" * ``` * * @stability stable * @category services * @since 4.0.0 */ export interface Service extends Key { of(this: void, self: Shape): Shape; context(self: Shape): Context; use(f: (service: Shape) => Effect): Effect; useSync(f: (service: Shape) => A): Effect; } /** * Class-style service key produced by `Context.Service()("Id")`. * * **When to use** * * Use when declaring a service as a class so the class value can serve as the * `Context` key. * * **Details** * * The class itself is the `Context` key, and its string `key` identifies the * service at runtime. * * @see {@link Service} for creating function-style keys or class-style service keys * * @stability stable * @category services * @since 4.0.0 */ export interface ServiceClass extends Service { new (_: never): ServiceClass.Shape; readonly key: Identifier; } /** * Namespace containing helper types for class-style `Context.Service` * declarations. * * @stability stable * @since 4.0.0 */ export declare namespace ServiceClass { /** * Runtime and type-level metadata carried by a class-style service key, * including its service type identifier, string key, and service shape. * * @category services * @since 4.0.0 */ interface Shape { readonly [ServiceTypeId]: typeof ServiceTypeId; readonly key: Identifier; readonly Service: Service; } } /** * Creates a `Context` service key. * * **When to use** * * Use when you need to define a context service key for a dependency that must * be provided by the surrounding context. * * **Details** * * Call `Context.Service("Key")` for a function-style key, or use the two-stage * form `Context.Service()("Key")` for class-style service * declarations. The returned key can be yielded as an Effect and passed to * `Context.make`, `Context.add`, and the Context getter functions. * * **Gotchas** * * The string key is the runtime identity of the service. Reusing the same key * string for unrelated services makes them occupy the same slot in a * `Context`. * * **Example** (Creating service keys) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a simple service * const Database = Context.Service<{ * query: (sql: string) => string * }>("Database") * * // Create a service class * class Config extends Context.Service()("Config") {} * * // Use the services to create contexts * const db = Context.make(Database, { * query: (sql) => `Result: ${sql}` * }) * const config = Context.make(Config, { port: 8080 }) * Context.get(db, Database).query("SELECT 1") // => "Result: SELECT 1" * Context.get(config, Config).port // => 8080 * ``` * * @see {@link Reference} for service keys with default values * * @stability stable * @category services * @since 4.0.0 */ export declare const Service: { /** * Creates a `Context` service key. * * **When to use** * * Use when you need to define a context service key for a dependency that must * be provided by the surrounding context. * * **Details** * * Call `Context.Service("Key")` for a function-style key, or use the two-stage * form `Context.Service()("Key")` for class-style service * declarations. The returned key can be yielded as an Effect and passed to * `Context.make`, `Context.add`, and the Context getter functions. * * **Gotchas** * * The string key is the runtime identity of the service. Reusing the same key * string for unrelated services makes them occupy the same slot in a * `Context`. * * **Example** (Creating service keys) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a simple service * const Database = Context.Service<{ * query: (sql: string) => string * }>("Database") * * // Create a service class * class Config extends Context.Service()("Config") {} * * // Use the services to create contexts * const db = Context.make(Database, { * query: (sql) => `Result: ${sql}` * }) * const config = Context.make(Config, { port: 8080 }) * Context.get(db, Database).query("SELECT 1") // => "Result: SELECT 1" * Context.get(config, Config).port // => 8080 * ``` * * @see {@link Reference} for service keys with default values * * @stability stable * @category services * @since 4.0.0 */ (key: string, options?: {} | undefined): Service; /** * Creates a `Context` service key. * * **When to use** * * Use when you need to define a context service key for a dependency that must * be provided by the surrounding context. * * **Details** * * Call `Context.Service("Key")` for a function-style key, or use the two-stage * form `Context.Service()("Key")` for class-style service * declarations. The returned key can be yielded as an Effect and passed to * `Context.make`, `Context.add`, and the Context getter functions. * * **Gotchas** * * The string key is the runtime identity of the service. Reusing the same key * string for unrelated services makes them occupy the same slot in a * `Context`. * * **Example** (Creating service keys) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a simple service * const Database = Context.Service<{ * query: (sql: string) => string * }>("Database") * * // Create a service class * class Config extends Context.Service()("Config") {} * * // Use the services to create contexts * const db = Context.make(Database, { * query: (sql) => `Result: ${sql}` * }) * const config = Context.make(Config, { port: 8080 }) * Context.get(db, Database).query("SELECT 1") // => "Result: SELECT 1" * Context.get(config, Config).port // => 8080 * ``` * * @see {@link Reference} for service keys with default values * * @stability stable * @category services * @since 4.0.0 */ (): = never>(id: Identifier, options?: { readonly make?: ((...args: Args) => Effect) | Effect | undefined; } | undefined) => ServiceClass & ([Types.unassigned] extends [R] ? unknown : { readonly make: [Args] extends [never] ? Effect : (...args: Args) => Effect; }); /** * Creates a `Context` service key. * * **When to use** * * Use when you need to define a context service key for a dependency that must * be provided by the surrounding context. * * **Details** * * Call `Context.Service("Key")` for a function-style key, or use the two-stage * form `Context.Service()("Key")` for class-style service * declarations. The returned key can be yielded as an Effect and passed to * `Context.make`, `Context.add`, and the Context getter functions. * * **Gotchas** * * The string key is the runtime identity of the service. Reusing the same key * string for unrelated services makes them occupy the same slot in a * `Context`. * * **Example** (Creating service keys) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a simple service * const Database = Context.Service<{ * query: (sql: string) => string * }>("Database") * * // Create a service class * class Config extends Context.Service()("Config") {} * * // Use the services to create contexts * const db = Context.make(Database, { * query: (sql) => `Result: ${sql}` * }) * const config = Context.make(Config, { port: 8080 }) * Context.get(db, Database).query("SELECT 1") // => "Result: SELECT 1" * Context.get(config, Config).port // => 8080 * ``` * * @see {@link Reference} for service keys with default values * * @stability stable * @category services * @since 4.0.0 */ (): | ((...args: any) => Effect)>(id: Identifier, options: { readonly make: Make; }) => ServiceClass | ((...args: infer _Args) => Effect) ? _A : never> & { readonly make: Make; }; }; declare const ReferenceTypeId: "~effect/Context/Reference"; /** * Service key with a lazily computed default value. * * **Details** * * When a `Reference` is requested from a `Context` that does not contain an * override, Context getters that resolve references return the cached default * value instead of failing. * * **Example** (Defining a reference with a default value) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Define a reference with a default value * const messages: Array = [] * const LoggerRef: Context.Reference<{ log: (msg: string) => void }> = * Context.Reference("Logger", { * defaultValue: () => ({ log: (msg) => { messages.push(msg) } }) * }) * * // The reference can be used without explicit provision * const context = Context.empty() * const logger = Context.get(context, LoggerRef) // Uses default value * logger.log("default logger") * messages // => ["default logger"] * ``` * * @stability stable * @category services * @since 3.11.0 */ export interface Reference extends Service { readonly [ReferenceTypeId]: typeof ReferenceTypeId; readonly defaultValue: () => Shape; [Symbol.iterator](): EffectIterator>; new (_: never): {}; } /** * Namespace containing utility types for `Context` service keys. * * **Example** (Extracting service types) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Database = Context.Service<{ * query: (sql: string) => string * }>("Database") * * // Extract service type from a key * type DatabaseService = Context.Service.Shape * * // Extract identifier type from a key * type DatabaseId = Context.Service.Identifier * * Database.key // => "Database" * ``` * * @stability stable * @since 2.0.0 */ export declare namespace Service { /** * Type that matches any `Context` service key regardless of its identifier or * service shape. * * **Example** (Typing any service key) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Any represents any possible service type * const services: Array = [ * Context.Service<{ log: (msg: string) => void }>("Logger"), * Context.Service<{ query: (sql: string) => string }>("Database") * ] * services.map((service) => service.key) // => ["Logger", "Database"] * ``` * * @category utility types * @since 4.0.0 */ type Any = Key | Key; /** * Extracts the service implementation type stored behind a `Context` service * key. * * **Example** (Extracting a service shape) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * // Extract the service shape from the service * type DatabaseService = Context.Service.Shape * // DatabaseService is { query: (sql: string) => string } * Database.key // => "Database" * ``` * * @category utility types * @since 4.0.0 */ type Shape = T extends Key ? S : never; /** * Extracts the identifier, or requirement type, associated with a `Context` * service key. * * **Example** (Extracting a service identifier) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * // Extract the identifier type from a key * type DatabaseId = Context.Service.Identifier * // DatabaseId is the identifier type * Database.key // => "Database" * ``` * * @category utility types * @since 2.0.0 */ type Identifier = T extends Key ? I : never; } declare const TypeId: "~effect/Context"; /** * Immutable collection of service implementations used for dependency * injection in Effect programs. * * **Details** * * The type parameter tracks the service identifiers available in the context. * At runtime, services are stored by each key's string `key`. * * **Example** (Creating a context with multiple services) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a context with multiple services * const Logger = Context.Service<{ log: (msg: string) => void }>("Logger") * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * const context = Context.make(Logger, { log: (_msg: string) => {} }) * .pipe(Context.add(Database, { query: (sql) => `Result: ${sql}` })) * Context.get(context, Database).query("SELECT 1") // => "Result: SELECT 1" * ``` * * @stability stable * @category models * @since 2.0.0 */ export interface Context extends Equal.Equal, Pipeable, Inspectable { readonly [TypeId]: { readonly _Services: Types.Contravariant; }; readonly mapUnsafe: ReadonlyMap; } /** * Creates a `Context` from an existing service map. * * **When to use** * * Use when constructing a low-level `Context` from a trusted map whose lifecycle * you control. * * **Gotchas** * * The provided map is retained without copying and must not be mutated after * construction. Prefer `empty`, `make`, `add`, or `merge` for normal Context * construction. * * **Example** (Creating a context from a map) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a context from a Map (unsafe) * const map = new Map([ * ["Logger", { log: (_msg: string) => {} }] * ]) * * const context = Context.makeUnsafe(map) * context.mapUnsafe.size // => 1 * ``` * * @stability stable * @category constructors * @since 4.0.0 */ export declare const makeUnsafe: (mapUnsafe: ReadonlyMap) => Context; /** * Checks whether the provided argument is a `Context`. * * **When to use** * * Use to narrow an unknown value before passing it to APIs that require a * `Context`. * * **Details** * * This checks the runtime `Context` marker and does not inspect which services * the context contains. * * **Gotchas** * * This guard only proves that the value is a `Context`; it does not prove that * any specific service is present. * * **Example** (Checking for contexts) * * ```ts import.meta.vitest * import { Context } from "effect" * Context.isContext(Context.empty()) // => true * ``` * * @see {@link isKey} for checking service keys * @see {@link isReference} for checking references with defaults * * @stability stable * @category guards * @since 2.0.0 */ export declare const isContext: (u: unknown) => u is Context; /** * Checks whether the provided argument is a `Key`. * * **Example** (Checking for keys) * * ```ts import.meta.vitest * import { Context } from "effect" * Context.isKey(Context.Service("Service")) // => true * ``` * * @stability stable * @category guards * @since 4.0.0 */ export declare const isKey: (u: unknown) => u is Key; /** * Checks whether the provided argument is a `Reference`. * * **Example** (Checking for references) * * ```ts import.meta.vitest * import { Context } from "effect" * * const LoggerRef = Context.Reference("Logger", { * defaultValue: () => ({ log: (_msg: string) => {} }) * }) * * Context.isReference(LoggerRef) // => true * Context.isReference(Context.Service("Key")) // => false * ``` * * @stability stable * @category guards * @since 3.11.0 */ export declare const isReference: (u: Key) => u is Reference; /** * Returns an empty `Context`. * * **Example** (Creating an empty context) * * ```ts import.meta.vitest * import { Context } from "effect" * Context.empty().mapUnsafe.size // => 0 * ``` * * @stability stable * @category constructors * @since 2.0.0 */ export declare const empty: () => Context; /** * Creates a new `Context` with a single service associated to the key. * * **Example** (Creating a context with one service) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.get(context, Port).PORT // => 8080 * ``` * * @stability stable * @category constructors * @since 2.0.0 */ export declare const make: (key: Key, service: Types.NoInfer) => Context; /** * Adds a service to a given `Context`. * * **When to use** * * Use when you need to store a known service value in a `Context`. * * **Details** * * If the context already contains the same service key, the new service * replaces the previous one. * * **Example** (Adding a service to a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const someContext = Context.make(Port, { PORT: 8080 }) * * const context = pipe( * someContext, * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link addOrOmit} for adding or removing a service from an `Option` * * @stability stable * @category combining * @since 2.0.0 */ export declare const add: { /** * Adds a service to a given `Context`. * * **When to use** * * Use when you need to store a known service value in a `Context`. * * **Details** * * If the context already contains the same service key, the new service * replaces the previous one. * * **Example** (Adding a service to a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const someContext = Context.make(Port, { PORT: 8080 }) * * const context = pipe( * someContext, * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link addOrOmit} for adding or removing a service from an `Option` * * @stability stable * @category combining * @since 2.0.0 */ (key: Key, service: Types.NoInfer): (self: Context) => Context; /** * Adds a service to a given `Context`. * * **When to use** * * Use when you need to store a known service value in a `Context`. * * **Details** * * If the context already contains the same service key, the new service * replaces the previous one. * * **Example** (Adding a service to a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const someContext = Context.make(Port, { PORT: 8080 }) * * const context = pipe( * someContext, * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link addOrOmit} for adding or removing a service from an `Option` * * @stability stable * @category combining * @since 2.0.0 */ (self: Context, key: Key, service: Types.NoInfer): Context; }; /** * Adds a service by key to a given `Context` using a string key. * * @stability stable * @category combining * @since 4.0.0 */ export declare const addUnsafe: (self: Context, key: string, service: Types.NoInfer) => Context; /** * Adds or removes a service depending on an `Option`. * * **When to use** * * Use when you need to add or omit a `Context` service based on an `Option`. * * **Details** * * When `service` is `Option.some`, the value is stored for the key. When it is * `Option.none`, the key is removed from the returned `Context`. * * **Example** (Adding optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * * const withPort = Context.empty().pipe( * Context.addOrOmit(Port, Option.some({ PORT: 8080 })) * ) * * const withoutPort = withPort.pipe( * Context.addOrOmit(Port, Option.none()) * ) * Context.getOption(withPort, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(withoutPort, Port) // => Option.none() * ``` * * @see {@link add} for always storing a service value * * @stability stable * @category combining * @since 4.0.0 */ export declare const addOrOmit: { /** * Adds or removes a service depending on an `Option`. * * **When to use** * * Use when you need to add or omit a `Context` service based on an `Option`. * * **Details** * * When `service` is `Option.some`, the value is stored for the key. When it is * `Option.none`, the key is removed from the returned `Context`. * * **Example** (Adding optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * * const withPort = Context.empty().pipe( * Context.addOrOmit(Port, Option.some({ PORT: 8080 })) * ) * * const withoutPort = withPort.pipe( * Context.addOrOmit(Port, Option.none()) * ) * Context.getOption(withPort, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(withoutPort, Port) // => Option.none() * ``` * * @see {@link add} for always storing a service value * * @stability stable * @category combining * @since 4.0.0 */ (key: Key, service: Option.Option>): (self: Context) => Context>; /** * Adds or removes a service depending on an `Option`. * * **When to use** * * Use when you need to add or omit a `Context` service based on an `Option`. * * **Details** * * When `service` is `Option.some`, the value is stored for the key. When it is * `Option.none`, the key is removed from the returned `Context`. * * **Example** (Adding optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * * const withPort = Context.empty().pipe( * Context.addOrOmit(Port, Option.some({ PORT: 8080 })) * ) * * const withoutPort = withPort.pipe( * Context.addOrOmit(Port, Option.none()) * ) * Context.getOption(withPort, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(withoutPort, Port) // => Option.none() * ``` * * @see {@link add} for always storing a service value * * @stability stable * @category combining * @since 4.0.0 */ (self: Context, key: Key, service: Option.Option>): Context>; }; /** * Gets the service for a key, or evaluates the fallback when a non-reference * key is absent. * * **When to use** * * Use when you need a fallback for a missing `Context.Service` key while still * resolving `Context.Reference` defaults. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned instead of the fallback. * * **Gotchas** * * The fallback is not evaluated for missing `Context.Reference` keys because * references resolve to their default value. * * **Example** (Falling back for missing services) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Logger = Context.Service<{ log: (msg: string) => void }>("Logger") * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * const context = Context.make(Logger, { log: (_msg: string) => {} }) * * const logger = Context.getOrElse(context, Logger, () => ({ log: () => {} })) * const database = Context.getOrElse( * context, * Database, * () => ({ query: () => "fallback" }) * ) * * logger === Context.get(context, Logger) // => true * database.query("SELECT 1") // => "fallback" * ``` * * @see {@link getOption} for returning `Option.none` when a non-reference key is missing * * @stability stable * @category getters * @since 3.7.0 */ export declare const getOrElse: { /** * Gets the service for a key, or evaluates the fallback when a non-reference * key is absent. * * **When to use** * * Use when you need a fallback for a missing `Context.Service` key while still * resolving `Context.Reference` defaults. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned instead of the fallback. * * **Gotchas** * * The fallback is not evaluated for missing `Context.Reference` keys because * references resolve to their default value. * * **Example** (Falling back for missing services) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Logger = Context.Service<{ log: (msg: string) => void }>("Logger") * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * const context = Context.make(Logger, { log: (_msg: string) => {} }) * * const logger = Context.getOrElse(context, Logger, () => ({ log: () => {} })) * const database = Context.getOrElse( * context, * Database, * () => ({ query: () => "fallback" }) * ) * * logger === Context.get(context, Logger) // => true * database.query("SELECT 1") // => "fallback" * ``` * * @see {@link getOption} for returning `Option.none` when a non-reference key is missing * * @stability stable * @category getters * @since 3.7.0 */ (key: Key, orElse: LazyArg): (self: Context) => S | B; /** * Gets the service for a key, or evaluates the fallback when a non-reference * key is absent. * * **When to use** * * Use when you need a fallback for a missing `Context.Service` key while still * resolving `Context.Reference` defaults. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned instead of the fallback. * * **Gotchas** * * The fallback is not evaluated for missing `Context.Reference` keys because * references resolve to their default value. * * **Example** (Falling back for missing services) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Logger = Context.Service<{ log: (msg: string) => void }>("Logger") * const Database = Context.Service<{ query: (sql: string) => string }>( * "Database" * ) * * const context = Context.make(Logger, { log: (_msg: string) => {} }) * * const logger = Context.getOrElse(context, Logger, () => ({ log: () => {} })) * const database = Context.getOrElse( * context, * Database, * () => ({ query: () => "fallback" }) * ) * * logger === Context.get(context, Logger) // => true * database.query("SELECT 1") // => "fallback" * ``` * * @see {@link getOption} for returning `Option.none` when a non-reference key is missing * * @stability stable * @category getters * @since 3.7.0 */ (self: Context, key: Key, orElse: LazyArg): S | B; }; /** * Returns the service currently stored for a key, or `undefined` when the key * is absent. * * **When to use** * * Use when you need to read the service stored for a key without resolving * `Context.Reference` defaults. * * **Gotchas** * * This is a raw lookup and does not resolve default values for * `Context.Reference` keys. * * @see {@link getOption} for a reference-aware optional lookup * * @stability stable * @category getters * @since 4.0.0 */ export declare const getOrUndefined: { /** * Returns the service currently stored for a key, or `undefined` when the key * is absent. * * **When to use** * * Use when you need to read the service stored for a key without resolving * `Context.Reference` defaults. * * **Gotchas** * * This is a raw lookup and does not resolve default values for * `Context.Reference` keys. * * @see {@link getOption} for a reference-aware optional lookup * * @stability stable * @category getters * @since 4.0.0 */ (key: Key): (self: Context) => S | undefined; /** * Returns the service currently stored for a key, or `undefined` when the key * is absent. * * **When to use** * * Use when you need to read the service stored for a key without resolving * `Context.Reference` defaults. * * **Gotchas** * * This is a raw lookup and does not resolve default values for * `Context.Reference` keys. * * @see {@link getOption} for a reference-aware optional lookup * * @stability stable * @category getters * @since 4.0.0 */ (self: Context, key: Key): S | undefined; }; /** * Gets the service for a key, throwing if an absent non-reference key cannot be * resolved. * * **When to use** * * Use when you need to read a service from a context whose type does not prove * the service is present. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned. For absent non-reference keys, * this function throws a runtime error. * * **Example** (Getting services unsafely) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getUnsafe(context, Port).PORT // => 8080 * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link get} for type-checked service access * @see {@link getOption} for optional service access * * @stability stable * @category unsafe * @since 4.0.0 */ export declare const getUnsafe: { /** * Gets the service for a key, throwing if an absent non-reference key cannot be * resolved. * * **When to use** * * Use when you need to read a service from a context whose type does not prove * the service is present. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned. For absent non-reference keys, * this function throws a runtime error. * * **Example** (Getting services unsafely) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getUnsafe(context, Port).PORT // => 8080 * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link get} for type-checked service access * @see {@link getOption} for optional service access * * @stability stable * @category unsafe * @since 4.0.0 */ (service: Key): (self: Context) => S; /** * Gets the service for a key, throwing if an absent non-reference key cannot be * resolved. * * **When to use** * * Use when you need to read a service from a context whose type does not prove * the service is present. * * **Details** * * If the key is a `Context.Reference` and no override is stored in the * context, its cached default value is returned. For absent non-reference keys, * this function throws a runtime error. * * **Example** (Getting services unsafely) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getUnsafe(context, Port).PORT // => 8080 * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link get} for type-checked service access * @see {@link getOption} for optional service access * * @stability stable * @category unsafe * @since 4.0.0 */ (self: Context, services: Key): S; }; /** * Gets a service from the context that corresponds to the given key. * * **When to use** * * Use when you need type-checked access to a service already included in the * context type. * * **Example** (Getting a service from a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * Context.get(context, Timeout).TIMEOUT // => 5000 * ``` * * @see {@link getOption} for optional service access * @see {@link getOrElse} for fallback values * * @stability stable * @category getters * @since 2.0.0 */ export declare const get: { /** * Gets a service from the context that corresponds to the given key. * * **When to use** * * Use when you need type-checked access to a service already included in the * context type. * * **Example** (Getting a service from a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * Context.get(context, Timeout).TIMEOUT // => 5000 * ``` * * @see {@link getOption} for optional service access * @see {@link getOrElse} for fallback values * * @stability stable * @category getters * @since 2.0.0 */ (service: Key): (self: Context) => S; /** * Gets a service from the context that corresponds to the given key. * * **When to use** * * Use when you need type-checked access to a service already included in the * context type. * * **Example** (Getting a service from a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * Context.get(context, Timeout).TIMEOUT // => 5000 * ``` * * @see {@link getOption} for optional service access * @see {@link getOrElse} for fallback values * * @stability stable * @category getters * @since 2.0.0 */ (service: Key): (self: Context) => S; /** * Gets a service from the context that corresponds to the given key. * * **When to use** * * Use when you need type-checked access to a service already included in the * context type. * * **Example** (Getting a service from a context) * * ```ts import.meta.vitest * import { Context, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * Context.get(context, Timeout).TIMEOUT // => 5000 * ``` * * @see {@link getOption} for optional service access * @see {@link getOrElse} for fallback values * * @stability stable * @category getters * @since 2.0.0 */ (self: Context, service: Key): S; }; /** * Gets the service for a key safely wrapped in an `Option`. * * **When to use** * * Use when you need to read a `Context` service as an `Option` so absence is * represented as data. * * **Details** * * Returns `Option.some` when the service is stored in the context. If the key * is a `Context.Reference` and no override is stored, returns `Option.some` of * the cached default value. Missing non-reference keys return `Option.none`. * * **Example** (Getting optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getOption(context, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link getOrElse} for returning a fallback value directly * * @stability stable * @category getters * @since 2.0.0 */ export declare const getOption: { /** * Gets the service for a key safely wrapped in an `Option`. * * **When to use** * * Use when you need to read a `Context` service as an `Option` so absence is * represented as data. * * **Details** * * Returns `Option.some` when the service is stored in the context. If the key * is a `Context.Reference` and no override is stored, returns `Option.some` of * the cached default value. Missing non-reference keys return `Option.none`. * * **Example** (Getting optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getOption(context, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link getOrElse} for returning a fallback value directly * * @stability stable * @category getters * @since 2.0.0 */ (service: Key): (self: Context) => Option.Option; /** * Gets the service for a key safely wrapped in an `Option`. * * **When to use** * * Use when you need to read a `Context` service as an `Option` so absence is * represented as data. * * **Details** * * Returns `Option.some` when the service is stored in the context. If the key * is a `Context.Reference` and no override is stored, returns `Option.some` of * the cached default value. Missing non-reference keys return `Option.none`. * * **Example** (Getting optional services) * * ```ts import.meta.vitest * import { Context, Option } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const context = Context.make(Port, { PORT: 8080 }) * * Context.getOption(context, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link getOrElse} for returning a fallback value directly * * @stability stable * @category getters * @since 2.0.0 */ (self: Context, service: Key): Option.Option; }; /** * Merges two `Context`s into one. * * **When to use** * * Use when you need to combine two contexts. * * **Details** * * When both contexts contain the same service key, the service from `that` * overrides the service from `self`. * * **Example** (Merging two contexts) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const firstContext = Context.make(Port, { PORT: 8080 }) * const secondContext = Context.make(Timeout, { TIMEOUT: 5000 }) * * const context = Context.merge(firstContext, secondContext) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link mergeAll} for merging more than two contexts at once * * @stability stable * @category combining * @since 2.0.0 */ export declare const merge: { /** * Merges two `Context`s into one. * * **When to use** * * Use when you need to combine two contexts. * * **Details** * * When both contexts contain the same service key, the service from `that` * overrides the service from `self`. * * **Example** (Merging two contexts) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const firstContext = Context.make(Port, { PORT: 8080 }) * const secondContext = Context.make(Timeout, { TIMEOUT: 5000 }) * * const context = Context.merge(firstContext, secondContext) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link mergeAll} for merging more than two contexts at once * * @stability stable * @category combining * @since 2.0.0 */ (that: Context): (self: Context) => Context; /** * Merges two `Context`s into one. * * **When to use** * * Use when you need to combine two contexts. * * **Details** * * When both contexts contain the same service key, the service from `that` * overrides the service from `self`. * * **Example** (Merging two contexts) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const firstContext = Context.make(Port, { PORT: 8080 }) * const secondContext = Context.make(Timeout, { TIMEOUT: 5000 }) * * const context = Context.merge(firstContext, secondContext) * * const values = [Context.get(context, Port).PORT, Context.get(context, Timeout).TIMEOUT] * values // => [8080, 5000] * ``` * * @see {@link mergeAll} for merging more than two contexts at once * * @stability stable * @category combining * @since 2.0.0 */ (self: Context, that: Context): Context; }; /** * Merges any number of `Context`s into one. * * **When to use** * * Use when you need to combine a variadic list of contexts. * * **Details** * * When multiple contexts contain the same service key, the service from the * last context with that key is kept. * * **Example** (Merging multiple contexts) * * ```ts import.meta.vitest * import { Context } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * const Host = Context.Service<{ HOST: string }>("Host") * * const firstContext = Context.make(Port, { PORT: 8080 }) * const secondContext = Context.make(Timeout, { TIMEOUT: 5000 }) * const thirdContext = Context.make(Host, { HOST: "localhost" }) * * const context = Context.mergeAll( * firstContext, * secondContext, * thirdContext * ) * * context.mapUnsafe.size // => 3 * ``` * * @see {@link merge} for merging two contexts * * @stability stable * @category combining * @since 3.12.0 */ export declare const mergeAll: >(...ctxs: [...{ [K in keyof T]: Context; }]) => Context; /** * Returns a new `Context` that contains only the specified services. * * **When to use** * * Use when you want to keep an allowlist of services in a `Context`. * * **Example** (Picking services from a context) * * ```ts import.meta.vitest * import { Context, Option, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const someContext = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * const context = pipe(someContext, Context.pick(Port)) * * Context.getOption(context, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link omit} for removing selected services * * @stability stable * @category filtering * @since 2.0.0 */ export declare const pick: >>(...services: S) => (self: Context) => Context>; /** * Returns a new `Context` with the specified service keys removed. * * **When to use** * * Use when you want to remove a denylist of services from a `Context`. * * **Example** (Omitting services from a context) * * ```ts import.meta.vitest * import { Context, Option, pipe } from "effect" * * const Port = Context.Service<{ PORT: number }>("Port") * const Timeout = Context.Service<{ TIMEOUT: number }>("Timeout") * * const someContext = pipe( * Context.make(Port, { PORT: 8080 }), * Context.add(Timeout, { TIMEOUT: 5000 }) * ) * * const context = pipe(someContext, Context.omit(Timeout)) * * Context.getOption(context, Port) // => Option.some({ PORT: 8080 }) * Context.getOption(context, Timeout) // => Option.none() * ``` * * @see {@link pick} for keeping selected services * * @stability stable * @category filtering * @since 2.0.0 */ export declare const omit: >>(...keys: S) => (self: Context) => Context>>; /** * Creates a context key with a default value. * * **When to use** * * Use when you need to define a context key with a lazily computed default * value. * * **Details** * * `Context.Reference` allows you to create a key that can hold a value. You * can provide a default value for the service, which will automatically be used * when the context is accessed, or override it with a custom implementation * when needed. The default value is computed lazily and cached on the * reference. * * **Example** (Creating references with default values) * * ```ts import.meta.vitest * import { Context } from "effect" * * // Create a reference with a default value * const messages: Array = [] * const LoggerRef = Context.Reference("Logger", { * defaultValue: () => ({ log: (msg: string) => messages.push(`Default: ${msg}`) }) * }) * * // The reference provides the default value when accessed from an empty context * const context = Context.empty() * const logger = Context.get(context, LoggerRef) * * // You can also override the default value * const customContext = Context.make(LoggerRef, { * log: (msg: string) => messages.push(`Custom: ${msg}`) * }) * const customLogger = Context.get(customContext, LoggerRef) * logger.log("default") * customLogger.log("message") * messages // => ["Default: default", "Custom: message"] * ``` * * @see {@link Service} for required services without default values * * @stability stable * @category services * @since 3.11.0 */ export declare const Reference: (key: string, options: { readonly defaultValue: () => Service; }) => Reference; export {}; //# sourceMappingURL=Context.d.ts.map