(
root: unknown,
options?: { readonly preserveEmptyStrings?: boolean | undefined }
): ConfigProviderCreates a ConfigProvider backed by an in-memory JavaScript value
(typically a parsed JSON object).
When to use
Use when you need deterministic config from an in-memory JavaScript value, such as in tests, embedded config, or parsed JSON.
Details
Path traversal follows standard JS rules: string segments index into object
keys, numeric segments index into arrays. Returns undefined for any path
that cannot be resolved. Never fails with SourceError.
Primitive values (number, boolean, bigint) are stringified via
String(...).
Literal empty strings are treated as missing values when loaded as values by
default. Pass { preserveEmptyStrings: true } to keep empty strings as
explicit values.
Gotchas
Object keys and array lengths reflect the original input shape. A leaf value
of "" is treated as missing when that leaf is loaded, but the parent
container still reports its original keys or length.
Example (Providing config from a plain object)
import { Config, ConfigProvider, Effect } from "effect"
const provider = ConfigProvider.fromUnknown({
database: {
host: "localhost",
port: 5432
}
})
const host = Config.string("host").parse(
provider.pipe(ConfigProvider.nested("database"))
)
// Effect.runSync(host) // "localhost"export function function fromUnknown(
root: unknown,
options?: {
readonly preserveEmptyStrings?:
| boolean
| undefined
}
): ConfigProvider
Creates a ConfigProvider backed by an in-memory JavaScript value
(typically a parsed JSON object).
When to use
Use when you need deterministic config from an in-memory JavaScript value,
such as in tests, embedded config, or parsed JSON.
Details
Path traversal follows standard JS rules: string segments index into object
keys, numeric segments index into arrays. Returns undefined for any path
that cannot be resolved. Never fails with SourceError.
Primitive values (number, boolean, bigint) are stringified via
String(...).
Literal empty strings are treated as missing values when loaded as values by
default. Pass { preserveEmptyStrings: true } to keep empty strings as
explicit values.
Gotchas
Object keys and array lengths reflect the original input shape. A leaf value
of "" is treated as missing when that leaf is loaded, but the parent
container still reports its original keys or length.
Example (Providing config from a plain object)
import { Config, ConfigProvider, Effect } from "effect"
const provider = ConfigProvider.fromUnknown({
database: {
host: "localhost",
port: 5432
}
})
const host = Config.string("host").parse(
provider.pipe(ConfigProvider.nested("database"))
)
// Effect.runSync(host) // "localhost"
fromUnknown(root: unknownroot: unknown, options: | {
readonly preserveEmptyStrings?:
| boolean
| undefined
}
| undefined
options?: {
readonly preserveEmptyStrings?: boolean | undefinedpreserveEmptyStrings?: boolean | undefined
}): ConfigProvider {
const const preserveEmptyStrings: booleanpreserveEmptyStrings = options: | {
readonly preserveEmptyStrings?:
| boolean
| undefined
}
| undefined
options?.preserveEmptyStrings?: boolean | undefinedpreserveEmptyStrings === true
return function make(
get: (
path: Path
) => Effect.Effect<
Node | undefined,
SourceError
>
): ConfigProvider
Creates a ConfigProvider from a raw lookup function.
When to use
Use when implementing a provider backed by a custom store, such as a
database, remote API, or in-memory map.
Details
The get callback receives a Path and must return
Effect<Node | undefined, SourceError>. Return undefined when the path
does not exist; fail with SourceError only for actual I/O errors.
Example (Creating a simple in-memory provider)
import { ConfigProvider, Effect } from "effect"
const data: Record<string, string> = {
host: "localhost",
port: "5432"
}
const provider = ConfigProvider.make((path) => {
const key = path.join(".")
const value = data[key]
return Effect.succeed(
value !== undefined ? ConfigProvider.makeValue(value) : undefined
)
})
make((path: Path(parameter) path: {
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<string | number>;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) =>…;
some: (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: ReadonlyArray<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: ReadonlyArray<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, th…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: ReadonlyArray<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: s…;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: ReadonlyArray<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: s…;
find: { (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => unknown, t…;
findIndex: (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknow…;
findLastIndex: (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
path) => import EffectEffect.const succeed: <A>(value: A) => Effect<A>Creates an Effect that always succeeds with a given value.
When to use
Use when an effect should complete successfully with a specific value without any errors
or external dependencies.
Example (Creating a successful effect)
import { Effect } from "effect"
// Creating an effect that represents a successful scenario
//
// ┌─── Effect<number, never, never>
// ▼
const success = Effect.succeed(42)
succeed(function nodeAtJson(
root: unknown,
path: Path,
preserveEmptyStrings: boolean
): Node | undefined
nodeAtJson(root: unknownroot, path: Path(parameter) path: {
length: number;
toString: () => string;
toLocaleString: { (): string; (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string };
concat: { (...items: Array<ConcatArray<string | number>>): Array<string | number>; (...items: Array<string | number | ConcatArray<string | number>>): Array<string | number> };
join: (separator?: string) => string;
slice: (start?: number, end?: number) => Array<string | number>;
indexOf: (searchElement: string | number, fromIndex?: number) => number;
lastIndexOf: (searchElement: string | number, fromIndex?: number) => number;
every: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): this is readonly S[]; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) =>…;
some: (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, thisArg?: any) => boolean;
forEach: (callbackfn: (value: string | number, index: number, array: ReadonlyArray<string | number>) => void, thisArg?: any) => void;
map: (callbackfn: (value: string | number, index: number, array: ReadonlyArray<string | number>) => U, thisArg?: any) => Array<U>;
filter: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): Array<S>; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, th…;
reduce: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: ReadonlyArray<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: s…;
reduceRight: { (callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: ReadonlyArray<string | number>) => string | number): string | number; (callbackfn: (previousValue: string | number, currentValue: s…;
find: { (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => unknown, t…;
findIndex: (predicate: (value: string | number, index: number, obj: ReadonlyArray<string | number>) => unknown, thisArg?: any) => number;
entries: () => ArrayIterator<[number, string | number]>;
keys: () => ArrayIterator<number>;
values: () => ArrayIterator<string | number>;
includes: (searchElement: string | number, fromIndex?: number) => boolean;
flatMap: (callback: (this: This, value: string | number, index: number, array: Array<string | number>) => U | ReadonlyArray<U>, thisArg?: This | undefined) => Array<U>;
flat: (this: A, depth?: D | undefined) => Array<FlatArray<A, D>>;
at: (index: number) => string | number | undefined;
findLast: { (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => value is S, thisArg?: any): S | undefined; (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknow…;
findLastIndex: (predicate: (value: string | number, index: number, array: ReadonlyArray<string | number>) => unknown, thisArg?: any) => number;
toReversed: () => Array<string | number>;
toSorted: (compareFn?: ((a: string | number, b: string | number) => number) | undefined) => Array<string | number>;
toSpliced: { (start: number, deleteCount: number, ...items: Array<string | number>): Array<string | number>; (start: number, deleteCount?: number): Array<string | number> };
with: (index: number, value: string | number) => Array<string | number>;
}
path, const preserveEmptyStrings: booleanpreserveEmptyStrings)))
}