(node: AnyNode, options?: VerifyConnectionOptions): Effect.Effect<
void,
NodeUnreachable | UnaddressedNode
>
(node: AnyNode, options: VerifyConnectionDeepOptions): Effect.Effect<
void,
ClientVerifyError
>Verify a node is reachable, eagerly — a fail-fast startup check for a remote Node.
Default: one bounded transport probe (tier 1) against the endpoint connect would
dial (selectEndpoint, or every endpoint with { all: true }). Fails
NodeUnreachable if nothing answers.
With { deep: true }, escalates after transport OK: dials the auto-served NodeStatus
over that endpoint. Transport up but RPC silent → ProtocolUnanswered; optional
resource key → ServiceNotServed / ServiceNotReady; optional
contractHash → ContractMismatch (F4).
yield* Hyperlink.verifyConnection(Droplet); // tier 1
yield* Hyperlink.verifyConnection(Droplet, { timeout: "1 second" });
yield* Hyperlink.verifyConnection(Droplet, { deep: true }); // + NodeStatus RPC
yield* Hyperlink.verifyConnection(Droplet, {
deep: true,
resource: Emails.groupId,
contractHash: Hyperlink.contractHash(Emails),
});
yield* Hyperlink.verifyConnection(Droplet, { all: true }); // every endpointComplements connect: connect prevents mis-wiring the client transport;
verifyConnection catches a peer that isn't there (or, with deep, isn't speaking RPC /
isn't serving the resource you need / has a stale contract).
export function function verifyConnection(node: AnyNode, options?: VerifyConnectionOptions): Effect.Effect<void, NodeUnreachable | UnaddressedNode> (+1 overload)Verify a node is reachable, eagerly — a fail-fast startup check for a remote
Node
.
Default: one bounded transport probe (tier 1) against the endpoint
connect
would
dial (selectEndpoint, or every endpoint with { all: true }). Fails
NodeUnreachable
if nothing answers.
With { deep: true }, escalates after transport OK: dials the auto-served
NodeStatus
over that endpoint. Transport up but RPC silent →
ProtocolUnanswered
; optional
resource key →
ServiceNotServed
/
ServiceNotReady
; optional
contractHash →
ContractMismatch
(F4).
yield* Hyperlink.verifyConnection(Droplet); // tier 1
yield* Hyperlink.verifyConnection(Droplet, { timeout: "1 second" });
yield* Hyperlink.verifyConnection(Droplet, { deep: true }); // + NodeStatus RPC
yield* Hyperlink.verifyConnection(Droplet, {
deep: true,
resource: Emails.groupId,
contractHash: Hyperlink.contractHash(Emails),
});
yield* Hyperlink.verifyConnection(Droplet, { all: true }); // every endpoint
Complements
connect
: connect prevents mis-wiring the client transport;
verifyConnection catches a peer that isn't there (or, with deep, isn't speaking RPC /
isn't serving the resource you need / has a stale contract).
verifyConnection(
node: AnyNodenode: import AnyNodeAnyNode,
options: VerifyConnectionOptionsoptions?: type VerifyConnectionOptions = {
readonly timeout?: Duration.Input
readonly url?: string
readonly path?: string
readonly all?: boolean
}
Options for the cheap (tier-1)
verifyConnection
probe.
VerifyConnectionOptions,
): 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<void, import NodeUnreachableNodeUnreachable | import UnaddressedNodeUnaddressedNode>;
export function function verifyConnection(node: AnyNode, options: VerifyConnectionDeepOptions): Effect.Effect<void, ClientVerifyError> (+1 overload)Verify a node is reachable, eagerly — a fail-fast startup check for a remote
Node
.
Default: one bounded transport probe (tier 1) against the endpoint
connect
would
dial (selectEndpoint, or every endpoint with { all: true }). Fails
NodeUnreachable
if nothing answers.
With { deep: true }, escalates after transport OK: dials the auto-served
NodeStatus
over that endpoint. Transport up but RPC silent →
ProtocolUnanswered
; optional
resource key →
ServiceNotServed
/
ServiceNotReady
; optional
contractHash →
ContractMismatch
(F4).
yield* Hyperlink.verifyConnection(Droplet); // tier 1
yield* Hyperlink.verifyConnection(Droplet, { timeout: "1 second" });
yield* Hyperlink.verifyConnection(Droplet, { deep: true }); // + NodeStatus RPC
yield* Hyperlink.verifyConnection(Droplet, {
deep: true,
resource: Emails.groupId,
contractHash: Hyperlink.contractHash(Emails),
});
yield* Hyperlink.verifyConnection(Droplet, { all: true }); // every endpoint
Complements
connect
: connect prevents mis-wiring the client transport;
verifyConnection catches a peer that isn't there (or, with deep, isn't speaking RPC /
isn't serving the resource you need / has a stale contract).
verifyConnection(
node: AnyNodenode: import AnyNodeAnyNode,
options: VerifyConnectionDeepOptionsoptions: type VerifyConnectionDeepOptions =
VerifyConnectionOptions & {
readonly deep: true
readonly resource?: string
readonly contractHash?: string
}
Options for deep (tier-2/3/4)
verifyConnection
— RPC + optional resource / F4 hash.
VerifyConnectionDeepOptions,
): 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<void, type ClientVerifyError = anyErrors default-on / deep client verify may surface on addressed client Layers.
ClientVerifyError>;
export function function verifyConnection(node: AnyNode, options?: VerifyConnectionOptions): Effect.Effect<void, NodeUnreachable | UnaddressedNode> (+1 overload)Verify a node is reachable, eagerly — a fail-fast startup check for a remote
Node
.
Default: one bounded transport probe (tier 1) against the endpoint
connect
would
dial (selectEndpoint, or every endpoint with { all: true }). Fails
NodeUnreachable
if nothing answers.
With { deep: true }, escalates after transport OK: dials the auto-served
NodeStatus
over that endpoint. Transport up but RPC silent →
ProtocolUnanswered
; optional
resource key →
ServiceNotServed
/
ServiceNotReady
; optional
contractHash →
ContractMismatch
(F4).
yield* Hyperlink.verifyConnection(Droplet); // tier 1
yield* Hyperlink.verifyConnection(Droplet, { timeout: "1 second" });
yield* Hyperlink.verifyConnection(Droplet, { deep: true }); // + NodeStatus RPC
yield* Hyperlink.verifyConnection(Droplet, {
deep: true,
resource: Emails.groupId,
contractHash: Hyperlink.contractHash(Emails),
});
yield* Hyperlink.verifyConnection(Droplet, { all: true }); // every endpoint
Complements
connect
: connect prevents mis-wiring the client transport;
verifyConnection catches a peer that isn't there (or, with deep, isn't speaking RPC /
isn't serving the resource you need / has a stale contract).
verifyConnection(
node: AnyNodenode: import AnyNodeAnyNode,
options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options?: type VerifyConnectionOptions = {
readonly timeout?: Duration.Input
readonly url?: string
readonly path?: string
readonly all?: boolean
}
Options for the cheap (tier-1)
verifyConnection
probe.
VerifyConnectionOptions & {
readonly deep?: boolean | undefineddeep?: boolean;
readonly resource?: string | undefinedresource?: string;
readonly contractHash?: string | undefinedcontractHash?: 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<void, type ClientVerifyError = anyErrors default-on / deep client verify may surface on addressed client Layers.
ClientVerifyError> {
const const endpoints: anyendpoints = const verifyEndpointsOf: (
node: AnyNode,
options?: {
readonly url?: string
readonly path?: string
readonly all?: boolean
}
) =>
| ReadonlyArray<VerifyEndpoint>
| UnaddressedNode
Endpoints
verifyConnection
probes. Overrides (url/path) win as a single synthetic
endpoint; { all: true } walks every declared transport; otherwise the same
selectEndpoint
pick
connect
would dial.
verifyEndpointsOf(node: AnyNodenode, options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options);
if (const endpoints: anyendpoints instanceof import UnaddressedNodeUnaddressedNode) {
return import EffectEffect.const fail: <any>(
error: any
) => Effect.Effect<never, any, never>
Creates an Effect that represents a recoverable error.
When to use
Use to explicitly signal a recoverable error in an Effect.
Details
The error keeps propagating unless it is handled. You can handle tagged
errors with functions like
catchTag
or
catchTags
.
Example (Creating a failed effect)
import { Data, Effect } from "effect"
class OperationFailedError extends Data.TaggedError("OperationFailedError")<{}> {}
// ┌─── Effect<never, OperationFailedError, never>
// ▼
const failure = Effect.fail(
new OperationFailedError()
)
fail(const endpoints: anyendpoints);
}
const const timeout: Duration.Inputtimeout = options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options?.timeout?: Duration.Input | undefinedtimeout ?? "3 seconds";
const const deep: booleandeep = options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options?.deep?: boolean | undefineddeep === true;
const const resource: string | undefinedresource = options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options?.resource?: string | undefinedresource;
const const expectedHash: string | undefinedexpectedHash = options: VerifyConnectionOptions & {
readonly deep?: boolean
readonly resource?: string
readonly contractHash?: string
}
options?.contractHash?: string | undefinedcontractHash;
return import EffectEffect.const forEach: <void, any, never, any, true>(self: any, f: (a: any, i: number) => Effect.Effect<void, any, never>, options?: {
readonly concurrency?: Concurrency | undefined;
readonly discard?: true | undefined;
} | undefined) => Effect.Effect<void, any, never> (+1 overload)
Executes an effectful operation for each element in an Iterable.
When to use
Use to traverse an iterable with an effectful function while preserving
element order in the collected results.
Details
The forEach function applies a provided operation to each element in the
iterable, producing a new effect that returns an array of results.
If any effect fails, the iteration stops immediately (short-circuiting), and
the error is propagated.
Concurrency:
The concurrency option controls how many operations are performed
concurrently. By default, the operations are performed sequentially.
Discarding Results:
If the discard option is set to true, the intermediate results are not
collected, and the final result of the operation is void.
Example (Mapping over an iterable with effects)
import { Console, Effect } from "effect"
const result = Effect.forEach(
[1, 2, 3, 4, 5],
(n, index) =>
Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2))
)
Effect.runPromise(result).then(console.log)
// Output:
// Currently at index 0
// Currently at index 1
// Currently at index 2
// Currently at index 3
// Currently at index 4
// [ 2, 4, 6, 8, 10 ]
Example (Running effects without collecting results)
import { Console, Effect } from "effect"
// Apply effects but discard the results
const result = Effect.forEach(
[1, 2, 3, 4, 5],
(n, index) =>
Console.log(`Currently at index ${index}`).pipe(Effect.as(n * 2)),
{ discard: true }
)
Effect.runPromise(result).then(console.log)
// Output:
// Currently at index 0
// Currently at index 1
// Currently at index 2
// Currently at index 3
// Currently at index 4
// undefined
forEach(
const endpoints: anyendpoints,
(ep: anyep) =>
import EffectEffect.const gen: <Effect.Effect<void, any, never>, void>(f: () => Generator<Effect.Effect<void, any, never>, void, never>) => Effect.Effect<void, any, never> (+1 overload)Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like
synchronous code, while still handling asynchronous tasks, errors, and complex
control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Example (Sequencing effects with generators)
import { Data, Effect } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function*() {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})
gen(function* () {
yield* const probeEndpointReachable: (
nodeKey: string,
ep: VerifyEndpoint,
timeout: Duration.Input
) => Effect.Effect<
void,
NodeUnreachable | UnaddressedNode
>
Tier-1 transport reachability for one endpoint.
probeEndpointReachable(node: AnyNodenode.key, ep: anyep, const timeout: Duration.Inputtimeout);
if (const deep: booleandeep) {
yield* const probeEndpointDeep: (
nodeKey: string,
ep: VerifyEndpoint,
timeout: Duration.Input,
resource: string | undefined,
expectedHash: string | undefined
) => Effect.Effect<
void,
| ProtocolUnanswered
| ServiceNotServed
| ServiceNotReady
| ContractMismatch
| UnaddressedNode
>
Tier-2/3/4: after transport is up, dial
NodeStatus
over the endpoint's protocol. Failures
classify as
ProtocolUnanswered
; optional resource checks served-key / readiness;
optional contractHash compares the F4 wire fingerprint.
Dynamic-imports the status tag so Hyperlink ⇄ nodeStatusHyperlink stays acyclic.
probeEndpointDeep(node: AnyNodenode.key, ep: anyep, const timeout: Duration.Inputtimeout, const resource: string | undefinedresource, const expectedHash: string | undefinedexpectedHash);
}
}),
{ discard?: true | undefineddiscard: true },
);
}