(service: string | { readonly key: string }): Effect.Effect<
ReadonlyArray<DirectoryEntry>,
never,
Directory
>List directory rows that advertise a HyperService (Tag or wire key).
Sugar over Directory.nodesServing — wire stays NodesServingRequest.
const rows = yield* Lookup.nodesServing(Jobs)
// or Lookup.nodesServing("fleet/Jobs")export const const nodesServing: (
service: string | { readonly key: string }
) => Effect.Effect<
ReadonlyArray<DirectoryEntry>,
never,
Directory
>
List directory rows that advertise a HyperService (Tag or wire key).
Sugar over
Directory
.nodesServing — wire stays
NodesServingRequest
.
const rows = yield* Lookup.nodesServing(Jobs)
// or Lookup.nodesServing("fleet/Jobs")
nodesServing = (
service: | string
| {
readonly key: string
}
service: string | { readonly key: stringkey: string },
): 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<interface ReadonlyArray<T>ReadonlyArray<class DirectoryEntryclass DirectoryEntry {
kind: 'Http' | 'WebSocket' | 'IpcSocket';
serves: ReadonlyArray<string>;
nodeKey: string;
url: string | undefined;
path: string | undefined;
}
Directory row — dial target plus HyperService keys this node serves (listen catalog).
DirectoryEntry>, never, class Directoryclass Directory {
key: Identifier;
Service: {
advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumbent' | 'reject' | 'inherit' | undefined }…;
unregister: (payload: { nodeKey: string; kind?: 'Http' | 'WebSocket' | 'IpcSocket' | undefined; url?: string | undefined; path?: string | undefined }) => Effect.Effect<boolean, never, never>;
nodesServing: (payload: { serviceKey: string }) => Effect.Effect<ReadonlyArray<DirectoryEntry>, never, never>;
};
}
Lookup node directory — advertise / unregister / list by served HyperService key.
Directory> =>
import EffectEffect.const flatMap: {
<A, B, E1, R1>(
f: (a: A) => Effect<B, E1, R1>
): <E, R>(
self: Effect<A, E, R>
) => Effect<B, E1 | E, R1 | R>
<A, E, R, B, E1, R1>(
self: Effect<A, E, R>,
f: (a: A) => Effect<B, E1, R1>
): Effect<B, E | E1, R | R1>
}
Chains effects to produce new Effect instances, useful for combining
operations that depend on previous results.
When to use
Use when you need to chain multiple effects, ensuring that each
step produces a new Effect while flattening any nested effects that may
occur.
Details
flatMap lets you sequence effects so that the result of one effect can be
used in the next step. It is similar to flatMap used with arrays but works
specifically with Effect instances, allowing you to avoid deeply nested
effect structures.
Since effects are immutable, flatMap always returns a new effect instead of
changing the original one.
Example (Choosing flatMap syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)
const transformation = (n: number) => Effect.succeed(n + 1)
const flatMappedWithPipe = pipe(myEffect, Effect.flatMap(transformation))
const flatMappedWithDataFirst = Effect.flatMap(myEffect, transformation)
const flatMappedWithMethod = myEffect.pipe(Effect.flatMap(transformation))
Example (Sequencing dependent effects)
import { Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amount
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Chaining the fetch and discount application using `flatMap`
const finalAmount = pipe(
fetchTransactionAmount,
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output: 95
flatMap(class Directoryclass Directory {
key: Identifier;
Service: {
advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumbent' | 'reject' | 'inherit' | undefined }…;
unregister: (payload: { nodeKey: string; kind?: 'Http' | 'WebSocket' | 'IpcSocket' | undefined; url?: string | undefined; path?: string | undefined }) => Effect.Effect<boolean, never, never>;
nodesServing: (payload: { serviceKey: string }) => Effect.Effect<ReadonlyArray<DirectoryEntry>, never, never>;
};
description: string | undefined;
of: (this: void, self: { readonly advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumb…;
context: (self: { readonly advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumbent' | 'reje…;
use: (f: (service: { readonly advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumbent' …;
useSync: (f: (service: { readonly advertise: (payload: { kind: 'Http' | 'WebSocket' | 'IpcSocket'; serves: ReadonlyArray<string>; nodeKey: string; url?: string | undefined; path?: string | undefined; onConflict?: 'livenessReplace' | 'askIncumbent' …;
Identifier: Identifier;
stack: string | undefined;
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;
}
Lookup node directory — advertise / unregister / list by served HyperService key.
Directory, (svc: {
readonly advertise: (payload: {
kind: "Http" | "WebSocket" | "IpcSocket";
serves: readonly string[];
nodeKey: string;
url?: string | undefined;
path?: string | undefined;
onConflict?: "livenessReplace" | "askIncumbent" | "reject" | "inherit" | undefined;
}) => Effect.Effect<DirectoryEntry, IncumbentAlive, never>;
readonly unregister: (payload: {
nodeKey: string;
kind?: "Http" | "WebSocket" | "IpcSocket" | undefined;
url?: string | undefined;
path?: string | undefined;
}) => Effect.Effect<boolean, never, never>;
readonly nodesServing: (payload: {
...;
}) => Effect.Effect<...>;
}
svc) =>
svc: {
readonly advertise: (payload: {
kind: "Http" | "WebSocket" | "IpcSocket";
serves: readonly string[];
nodeKey: string;
url?: string | undefined;
path?: string | undefined;
onConflict?: "livenessReplace" | "askIncumbent" | "reject" | "inherit" | undefined;
}) => Effect.Effect<DirectoryEntry, IncumbentAlive, never>;
readonly unregister: (payload: {
nodeKey: string;
kind?: "Http" | "WebSocket" | "IpcSocket" | undefined;
url?: string | undefined;
path?: string | undefined;
}) => Effect.Effect<boolean, never, never>;
readonly nodesServing: (payload: {
...;
}) => Effect.Effect<...>;
}
svc.nodesServing: (payload: {
serviceKey: string
}) => Effect.Effect<
readonly DirectoryEntry[],
never,
never
>
nodesServing(
new constructor NodesServingRequest(props: Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlyMakeIn<{
readonly serviceKey: Schema.String;
}>, options?: Schema.MakeOptions | undefined): NodesServingRequest
constructor NodesServingRequest(props: Schema.Struct<Fields extends Schema.Struct.Fields>.ReadonlyMakeIn<{
readonly serviceKey: Schema.String;
}>, options?: Schema.MakeOptions | undefined): {
Type: Self;
Encoded: S["Encoded"];
DecodingServices: S["DecodingServices"];
EncodingServices: S["EncodingServices"];
Iso: S["Iso"];
identifier: string;
fields: S["fields"];
mapFields: (f: (fields: { readonly serviceKey: Schema.String }) => To, options?: { readonly unsafePreserveChecks?: boolean | undefined } | undefined) => Schema.Struct<{ [K in keyof Readonly<To>]: Readonly<To>[K]; }>;
extend: (identifier: string) => { (fields: NewFields, annotations?: Schema.Annotations.Declaration<Extended, readonly [Schema.Struct<{ [K in keyof { [K in keyof ('serviceKey' & keyof NewFields extends never ? { readonly serviceKey: Schema.String; …;
Rebuild: Rebuild;
ast: Ast;
annotate: (annotations: Schema.Annotations.Bottom<NodesServingRequest, readonly [Schema.Struct<{ readonly serviceKey: Schema.String }>]>) => Schema.decodeTo<Schema.declareConstructor<NodesServingRequest, Schema.Struct.ReadonlySide<{ readonly service…;
annotateKey: (annotations: Schema.Annotations.Key<NodesServingRequest>) => Schema.decodeTo<Schema.declareConstructor<NodesServingRequest, Schema.Struct.ReadonlySide<{ readonly serviceKey: Schema.String }, 'Encoded'>, readonly [Schema.Struct<{ readonly …;
check: (checks_0: Check<NodesServingRequest>, ...checks: Array<Check<NodesServingRequest>>) => Schema.decodeTo<Schema.declareConstructor<NodesServingRequest, Schema.Struct.ReadonlySide<{ readonly serviceKey: Schema.String }, 'Encoded'>, readonly …;
rebuild: (ast: Declaration) => Schema.decodeTo<Schema.declareConstructor<NodesServingRequest, Schema.Struct.ReadonlySide<{ readonly serviceKey: Schema.String }, 'Encoded'>, readonly [Schema.Struct<{ readonly serviceKey: Schema.String }>], Schema.St…;
make: (input: Struct.ReadonlyMakeIn<{ readonly serviceKey: String }>, options?: MakeOptions) => NodesServingRequest;
makeOption: (input: Struct.ReadonlyMakeIn<{ readonly serviceKey: String }>, options?: MakeOptions) => Option_.Option<NodesServingRequest>;
makeEffect: (input: Struct.ReadonlyMakeIn<{ readonly serviceKey: String }>, options?: MakeOptions) => Effect.Effect<NodesServingRequest, SchemaError, never>;
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; <…;
}
List nodes that advertised a given HyperService key in serves.
NodesServingRequest({ serviceKey: stringserviceKey: const serviceKeyOf: (
service:
| string
| {
readonly key: string
}
) => string
Tag or wire key → serviceKey string.
serviceKeyOf(service: | string
| {
readonly key: string
}
service) }),
),
);