<Impl, const S extends Spec, Out = Impl>(
impl: Impl,
spec: S,
transform: (
effect: Effect.Effect<unknown, never, never>
) => Effect.Effect<unknown, never, never>
): OutThe generic impl-transform primitive — the Hyperlink counterpart to Store.mapEffects. Walk impl
per its spec (flattenSpec keys aligned onto the impl via flattenImpl) and pass each
Effect method's returned Effect through transform, then re-nest (nestService). A
stream: true leaf — a Hyperlink.stream member (a Stream impl) or a ref field
(a Subscribable impl) — is left untouched, as is a LocalMethod leaf.
transform is applied uniformly; whether it changes types is expressed through the result:
- Type-preserving transforms (
withSpan/retry) leave the type unchanged —Outdefaults toImpl. - Type-changing transforms (stripping
R, like provideContext) supply an explicitOutcomputed per method by a mapped type (e.g. ProvidedContext).
export const const mapEffects: <
Impl,
S extends Spec,
Out = Impl
>(
impl: Impl,
spec: S,
transform: (
effect: Effect.Effect<unknown, never, never>
) => Effect.Effect<unknown, never, never>
) => Out
The generic impl-transform primitive — the Hyperlink counterpart to Store.mapEffects. Walk impl
per its spec (
flattenSpec
keys aligned onto the impl via
flattenImpl
) and pass each
Effect method's returned
Effect
through transform, then re-nest (
nestService
). A
stream: true leaf — a
Hyperlink.stream
member (a
Stream
impl) or a
ref
field
(a
Subscribable
impl) — is left untouched, as is a
LocalMethod
leaf.
transform is applied uniformly; whether it changes types is expressed through the result:
- Type-preserving transforms (
withSpan / retry) leave the type unchanged — Out defaults to
Impl.
- Type-changing transforms (stripping
R, like
provideContext
) supply an explicit Out
computed per method by a mapped type (e.g.
ProvidedContext
).
mapEffects = <function (type parameter) Impl in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutImpl, const function (type parameter) S in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutS extends Spec, function (type parameter) Out in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutOut = function (type parameter) Impl in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutImpl>(
impl: Implimpl: function (type parameter) Impl in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutImpl,
spec: const S extends Specspec: function (type parameter) S in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutS,
transform: (
effect: Effect.Effect<unknown, never, never>
) => Effect.Effect<unknown, never, never>
transform: (
effect: Effect.Effect<unknown, never, never>(parameter) effect: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
effect: import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<unknown, never, never>,
) => import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<unknown, never, never>,
): function (type parameter) Out in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutOut => {
const const flatSpec: FlatSpecflatSpec = const flattenSpec: (
spec: Spec,
prefix?: string
) => FlatSpec
Flatten a nested spec to a flat path-keyed record (identity for a flat spec).
flattenSpec(spec: const S extends Specspec);
// Tree-walk/rebuild idiom (as in `flattenImpl` at every wire call site): the impl is a type-erased
// record here, walked by the spec's flat paths.
const const flatImpl: Record<string, unknown>flatImpl = const flattenImpl: (
impl: Record<string, unknown>,
flatSpec: FlatSpec
) => Record<string, unknown>
flattenImpl(impl: Implimpl as type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string, unknown>, const flatSpec: FlatSpecflatSpec);
const const mapped: Record<string, unknown>mapped: type Record<K extends keyof any, T> = {
[P in K]: T
}
Construct a type with a set of properties K of type T
Record<string, unknown> = {};
for (const [const path: stringpath, const member: unknownmember] of var Object: ObjectConstructorProvides functionality common to all JavaScript objects.
Object.ObjectConstructor.entries<unknown>(o: {
[s: string]: unknown;
} | ArrayLike<unknown>): [string, unknown][] (+1 overload)
Returns an array of key/values of the enumerable own properties of an object
entries(const flatImpl: Record<string, unknown>flatImpl)) {
const const leaf: AnyMethod | AnyLocalMethodleaf = const flatSpec: FlatSpecflatSpec[const path: stringpath];
// Leave streams (and `ref` → Subscribable, which is `stream: true`) and local members untouched;
// map only the Effect methods.
if (
const leaf: AnyMethod | AnyLocalMethodleaf === var undefinedundefined ||
const isLocalMethod: (
m: AnyMethod | AnyLocalMethod | Spec
) => m is AnyLocalMethod
Runtime guard: is a spec entry a
LocalMethod
(vs a wire
Method
)?
isLocalMethod(const leaf: AnyMethod | AnyLocalMethodleaf) ||
(import PredicatePredicate.const hasProperty: <"stream">(self: unknown, property: "stream") => self is { [K in "stream"]: unknown; } (+1 overload)Checks whether a value has a given property key.
When to use
Use when you need a Predicate guard for property access on unknown
values with a simple structural object check.
Details
Uses the in operator and isObjectKeyword. This does not check property
value types.
Example (Guarding object properties)
import { Predicate } from "effect"
const hasName = Predicate.hasProperty("name")
const data: unknown = { name: "Ada" }
if (hasName(data)) {
console.log(data.name)
}
hasProperty(const leaf: AnyMethodconst leaf: {
kind: MethodKind;
payload: P;
success: Su;
error: E;
stream: Str;
annotations: Ann;
annotate: <A extends MethodAnnotations>(annotations: A) => Method<P, Su, E, Str, Ann & A, Client>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
leaf, "stream") && const leaf: AnyMethodconst leaf: {
kind: MethodKind;
payload: P;
success: Su;
error: E;
stream: Str;
annotations: Ann;
annotate: <A extends MethodAnnotations>(annotations: A) => Method<P, Su, E, Str, Ann & A, Client>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
leaf.Method<Struct<Fields extends Struct.Fields>.Fields | Top | undefined, Top, Top, boolean, MethodAnnotations, never>.stream: booleanA streaming read (Stream member) when true; a one-shot Effect otherwise.
stream === true)
) {
const mapped: Record<string, unknown>mapped[const path: stringpath] = const member: unknownmember;
} else {
const mapped: Record<string, unknown>mapped[const path: stringpath] = const mapEffectMember: (
member: unknown,
transform: (
effect: Effect.Effect<unknown, never, never>
) => Effect.Effect<unknown, never, never>
) => unknown
Wrap a type-erased impl member so its returned
Effect
passes through transform. A member that
is a function (...args) => Effect → (...args) => transform(fn(...args)); a bare Effect
member → transform(member) directly. Only ever handed an Effect method's impl member — the
mapEffects
walk skips stream: true leaves (streams and
ref
→
Subscribable
members) before it reaches here.
mapEffectMember(const member: unknownmember, transform: (
effect: Effect.Effect<unknown, never, never>
) => Effect.Effect<unknown, never, never>
transform);
}
}
const const built: Record<string, unknown>built = const nestService: (
flat: Record<string, unknown>
) => Record<string, unknown>
Nest a flat path-keyed service back into the tree. Identity (same reference) when there's no nesting
— so value fields' in-place setters keep updating the returned object.
nestService(const mapped: Record<string, unknown>mapped);
// Same structural-rebuild idiom as `Store.mapEffects`: the reassembled object is asserted once here
// (as `Out` — the caller-supplied per-method result, or `Impl`).
return const built: Record<string, unknown>built as function (type parameter) Out in <Impl, const S extends Spec, Out = Impl>(impl: Impl, spec: S, transform: (effect: Effect.Effect<unknown, never, never>) => Effect.Effect<unknown, never, never>): OutOut;
};