<Input, State>(
metric: Metric.Metric<Input, State>,
f: (defect: unknown) => Input
): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>
<State, E>(metric: Metric.Metric<unknown, State>): <A, R>(
self: Effect<A, E, R>
) => Effect<A, E, R>
<A, E, R, Input, State>(
self: Effect<A, E, R>,
metric: Metric.Metric<Input, State>,
f: (defect: unknown) => Input
): Effect<A, E, R>
<A, E, R, State>(
self: Effect<A, E, R>,
metric: Metric.Metric<unknown, State>
): Effect<A, E, R>Updates the provided Metric every time the wrapped Effect fails with an
unexpected error (i.e. a defect).
Details
Also accepts an optional function which can be used to map the defect value
of the Effect into a valid Input for the Metric.
Example (Counting defects)
import { Effect, Metric } from "effect"
const defectCounter = Metric.counter("defects").pipe(
Metric.withConstantInput(1)
)
const program = Effect.die("Critical system failure").pipe(
Effect.trackDefects(defectCounter)
)
Effect.runPromiseExit(program).then(() =>
Effect.runPromise(Metric.value(defectCounter)).then(console.log)
// Output: { count: 1, incremental: false }
)Example (Mapping defects before tracking)
import { Effect, Metric } from "effect"
// Track defect types using frequency metric
const defectTypeFrequency = Metric.frequency("defect_types")
const program = Effect.die(new Error("Null pointer exception")).pipe(
Effect.trackDefects(defectTypeFrequency, (defect: unknown) => {
if (defect instanceof Error) return defect.constructor.name
return typeof defect
})
)
Effect.runPromiseExit(program).then(() =>
Effect.runPromise(Metric.value(defectTypeFrequency)).then(console.log)
// Output: { occurrences: Map(1) { "Error" => 1 } }
)export const const trackDefects: {
<Input, State>(
metric: Metric.Metric<Input, State>,
f: (defect: unknown) => Input
): <A, E, R>(
self: Effect<A, E, R>
) => Effect<A, E, R>
<State, E>(
metric: Metric.Metric<unknown, State>
): <A, R>(
self: Effect<A, E, R>
) => Effect<A, E, R>
<A, E, R, Input, State>(
self: Effect<A, E, R>,
metric: Metric.Metric<Input, State>,
f: (defect: unknown) => Input
): Effect<A, E, R>
<A, E, R, State>(
self: Effect<A, E, R>,
metric: Metric.Metric<unknown, State>
): Effect<A, E, R>
}
Updates the provided Metric every time the wrapped Effect fails with an
unexpected error (i.e. a defect).
Details
Also accepts an optional function which can be used to map the defect value
of the Effect into a valid Input for the Metric.
Example (Counting defects)
import { Effect, Metric } from "effect"
const defectCounter = Metric.counter("defects").pipe(
Metric.withConstantInput(1)
)
const program = Effect.die("Critical system failure").pipe(
Effect.trackDefects(defectCounter)
)
Effect.runPromiseExit(program).then(() =>
Effect.runPromise(Metric.value(defectCounter)).then(console.log)
// Output: { count: 1, incremental: false }
)
Example (Mapping defects before tracking)
import { Effect, Metric } from "effect"
// Track defect types using frequency metric
const defectTypeFrequency = Metric.frequency("defect_types")
const program = Effect.die(new Error("Null pointer exception")).pipe(
Effect.trackDefects(defectTypeFrequency, (defect: unknown) => {
if (defect instanceof Error) return defect.constructor.name
return typeof defect
})
)
Effect.runPromiseExit(program).then(() =>
Effect.runPromise(Metric.value(defectTypeFrequency)).then(console.log)
// Output: { occurrences: Map(1) { "Error" => 1 } }
)
trackDefects: {
<function (type parameter) Input in <Input, State>(metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Input, function (type parameter) State in <Input, State>(metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>State>(
metric: Metric.Metric<Input, State>(parameter) metric: {
Input: Contravariant<Input>;
State: Covariant<State>;
id: string;
type: Metric.Type;
description: string | undefined;
attributes: Metric.AttributeSet | undefined;
valueUnsafe: (context: Context.Context<never>) => State;
updateUnsafe: (input: Input, context: Context.Context<never>) => void;
modifyUnsafe: (input: Input, context: Context.Context<never>) => void;
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; <…;
}
metric: import MetricMetric.interface Metric<in Input, out State>A Metric<Input, State> represents a concurrent metric which accepts update
values of type Input and are aggregated to a value of type State.
Details
For example, a counter metric would have type Metric<number, number>,
representing the fact that the metric can be updated with numbers (the amount
to increment or decrement the counter by), and the state of the counter is a
number.
There are five primitive metric types supported by Effect:
- Counters
- Frequencies
- Gauges
- Histograms
- Summaries
Example (Using multiple metric types)
import { Data, Effect, Metric } from "effect"
class MetricExample extends Data.TaggedError("MetricExample")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter: Metric.Counter<number> = Metric.counter("requests", {
description: "Total requests processed"
})
const memoryGauge: Metric.Gauge<number> = Metric.gauge("memory_usage", {
description: "Current memory usage in MB"
})
const statusFrequency: Metric.Frequency = Metric.frequency("status_codes", {
description: "HTTP status code frequency"
})
// All metrics share the same interface for updates and reads
yield* Metric.update(requestCounter, 1)
yield* Metric.update(memoryGauge, 128)
yield* Metric.update(statusFrequency, "200")
// All metrics can be read with Metric.value
const counterState = yield* Metric.value(requestCounter)
const gaugeState = yield* Metric.value(memoryGauge)
const frequencyState = yield* Metric.value(statusFrequency)
// Metrics have common properties accessible through the interface:
// - id: unique identifier
// - type: metric type ("Counter", "Gauge", "Frequency", etc.)
// - description: optional human-readable description
// - attributes: optional key-value attributes for tagging
return {
counter: {
id: requestCounter.id,
type: requestCounter.type,
state: counterState
},
gauge: { id: memoryGauge.id, type: memoryGauge.type, state: gaugeState },
frequency: {
id: statusFrequency.id,
type: statusFrequency.type,
state: frequencyState
}
}
})
The Metric namespace provides a comprehensive system for collecting, aggregating, and observing
application metrics in Effect applications.
Example (Collecting application metrics)
import { Data, Effect, Metric } from "effect"
class MetricsError extends Data.TaggedError("MetricsError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter = Metric.counter("http_requests_total")
const responseTimeHistogram = Metric.histogram("http_response_time", {
boundaries: Metric.linearBoundaries({ start: 0, width: 10, count: 10 })
})
const activeConnectionsGauge = Metric.gauge("active_connections")
const statusFrequency = Metric.frequency("http_status_codes")
// Update metrics
yield* Metric.update(requestCounter, 1)
yield* Metric.update(responseTimeHistogram, 45.2)
yield* Metric.update(activeConnectionsGauge, 12)
yield* Metric.update(statusFrequency, "200")
// Get metric values
const counterValue = yield* Metric.value(requestCounter)
const histogramValue = yield* Metric.value(responseTimeHistogram)
const gaugeValue = yield* Metric.value(activeConnectionsGauge)
const frequencyValue = yield* Metric.value(statusFrequency)
return {
counter: counterValue,
histogram: histogramValue,
gauge: gaugeValue,
frequency: frequencyValue
}
})
Metric<function (type parameter) Input in <Input, State>(metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Input, function (type parameter) State in <Input, State>(metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>State>,
f: (defect: unknown) => Inputf: (defect: unknowndefect: unknown) => function (type parameter) Input in <Input, State>(metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): <A, E, R>(self: Effect<A, E, R>) => Effect<A, E, R>Input
): <function (type parameter) A in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) E in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>E, function (type parameter) R in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>R>(self: Effect<A, E, R>(parameter) self: {
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;
}
self: 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<function (type parameter) A in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) E in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>E, function (type parameter) R in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>R>) => 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<function (type parameter) A in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) E in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>E, function (type parameter) R in <A, E, R>(self: Effect<A, E, R>): Effect<A, E, R>R>
<function (type parameter) State in <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R>State, function (type parameter) E in <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R>E>(
metric: Metric.Metric<unknown, State>(parameter) metric: {
Input: Contravariant<Input>;
State: Covariant<State>;
id: string;
type: Metric.Type;
description: string | undefined;
attributes: Metric.AttributeSet | undefined;
valueUnsafe: (context: Context.Context<never>) => State;
updateUnsafe: (input: Input, context: Context.Context<never>) => void;
modifyUnsafe: (input: Input, context: Context.Context<never>) => void;
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; <…;
}
metric: import MetricMetric.interface Metric<in Input, out State>A Metric<Input, State> represents a concurrent metric which accepts update
values of type Input and are aggregated to a value of type State.
Details
For example, a counter metric would have type Metric<number, number>,
representing the fact that the metric can be updated with numbers (the amount
to increment or decrement the counter by), and the state of the counter is a
number.
There are five primitive metric types supported by Effect:
- Counters
- Frequencies
- Gauges
- Histograms
- Summaries
Example (Using multiple metric types)
import { Data, Effect, Metric } from "effect"
class MetricExample extends Data.TaggedError("MetricExample")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter: Metric.Counter<number> = Metric.counter("requests", {
description: "Total requests processed"
})
const memoryGauge: Metric.Gauge<number> = Metric.gauge("memory_usage", {
description: "Current memory usage in MB"
})
const statusFrequency: Metric.Frequency = Metric.frequency("status_codes", {
description: "HTTP status code frequency"
})
// All metrics share the same interface for updates and reads
yield* Metric.update(requestCounter, 1)
yield* Metric.update(memoryGauge, 128)
yield* Metric.update(statusFrequency, "200")
// All metrics can be read with Metric.value
const counterState = yield* Metric.value(requestCounter)
const gaugeState = yield* Metric.value(memoryGauge)
const frequencyState = yield* Metric.value(statusFrequency)
// Metrics have common properties accessible through the interface:
// - id: unique identifier
// - type: metric type ("Counter", "Gauge", "Frequency", etc.)
// - description: optional human-readable description
// - attributes: optional key-value attributes for tagging
return {
counter: {
id: requestCounter.id,
type: requestCounter.type,
state: counterState
},
gauge: { id: memoryGauge.id, type: memoryGauge.type, state: gaugeState },
frequency: {
id: statusFrequency.id,
type: statusFrequency.type,
state: frequencyState
}
}
})
The Metric namespace provides a comprehensive system for collecting, aggregating, and observing
application metrics in Effect applications.
Example (Collecting application metrics)
import { Data, Effect, Metric } from "effect"
class MetricsError extends Data.TaggedError("MetricsError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter = Metric.counter("http_requests_total")
const responseTimeHistogram = Metric.histogram("http_response_time", {
boundaries: Metric.linearBoundaries({ start: 0, width: 10, count: 10 })
})
const activeConnectionsGauge = Metric.gauge("active_connections")
const statusFrequency = Metric.frequency("http_status_codes")
// Update metrics
yield* Metric.update(requestCounter, 1)
yield* Metric.update(responseTimeHistogram, 45.2)
yield* Metric.update(activeConnectionsGauge, 12)
yield* Metric.update(statusFrequency, "200")
// Get metric values
const counterValue = yield* Metric.value(requestCounter)
const histogramValue = yield* Metric.value(responseTimeHistogram)
const gaugeValue = yield* Metric.value(activeConnectionsGauge)
const frequencyValue = yield* Metric.value(statusFrequency)
return {
counter: counterValue,
histogram: histogramValue,
gauge: gaugeValue,
frequency: frequencyValue
}
})
Metric<unknown, function (type parameter) State in <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R>State>
): <function (type parameter) A in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) R in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>R>(self: Effect<A, E, R>(parameter) self: {
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;
}
self: 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<function (type parameter) A in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) E in <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R>E, function (type parameter) R in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>R>) => 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<function (type parameter) A in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>A, function (type parameter) E in <State, E>(metric: Metric.Metric<unknown, State>): <A, R>(self: Effect<A, E, R>) => Effect<A, E, R>E, function (type parameter) R in <A, R>(self: Effect<A, E, R>): Effect<A, E, R>R>
<function (type parameter) A in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>A, function (type parameter) E in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>E, function (type parameter) R in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>R, function (type parameter) Input in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>Input, function (type parameter) State in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>State>(
self: Effect<A, E, R>(parameter) self: {
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;
}
self: 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<function (type parameter) A in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>A, function (type parameter) E in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>E, function (type parameter) R in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>R>,
metric: Metric.Metric<Input, State>(parameter) metric: {
Input: Contravariant<Input>;
State: Covariant<State>;
id: string;
type: Metric.Type;
description: string | undefined;
attributes: Metric.AttributeSet | undefined;
valueUnsafe: (context: Context.Context<never>) => State;
updateUnsafe: (input: Input, context: Context.Context<never>) => void;
modifyUnsafe: (input: Input, context: Context.Context<never>) => void;
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; <…;
}
metric: import MetricMetric.interface Metric<in Input, out State>A Metric<Input, State> represents a concurrent metric which accepts update
values of type Input and are aggregated to a value of type State.
Details
For example, a counter metric would have type Metric<number, number>,
representing the fact that the metric can be updated with numbers (the amount
to increment or decrement the counter by), and the state of the counter is a
number.
There are five primitive metric types supported by Effect:
- Counters
- Frequencies
- Gauges
- Histograms
- Summaries
Example (Using multiple metric types)
import { Data, Effect, Metric } from "effect"
class MetricExample extends Data.TaggedError("MetricExample")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter: Metric.Counter<number> = Metric.counter("requests", {
description: "Total requests processed"
})
const memoryGauge: Metric.Gauge<number> = Metric.gauge("memory_usage", {
description: "Current memory usage in MB"
})
const statusFrequency: Metric.Frequency = Metric.frequency("status_codes", {
description: "HTTP status code frequency"
})
// All metrics share the same interface for updates and reads
yield* Metric.update(requestCounter, 1)
yield* Metric.update(memoryGauge, 128)
yield* Metric.update(statusFrequency, "200")
// All metrics can be read with Metric.value
const counterState = yield* Metric.value(requestCounter)
const gaugeState = yield* Metric.value(memoryGauge)
const frequencyState = yield* Metric.value(statusFrequency)
// Metrics have common properties accessible through the interface:
// - id: unique identifier
// - type: metric type ("Counter", "Gauge", "Frequency", etc.)
// - description: optional human-readable description
// - attributes: optional key-value attributes for tagging
return {
counter: {
id: requestCounter.id,
type: requestCounter.type,
state: counterState
},
gauge: { id: memoryGauge.id, type: memoryGauge.type, state: gaugeState },
frequency: {
id: statusFrequency.id,
type: statusFrequency.type,
state: frequencyState
}
}
})
The Metric namespace provides a comprehensive system for collecting, aggregating, and observing
application metrics in Effect applications.
Example (Collecting application metrics)
import { Data, Effect, Metric } from "effect"
class MetricsError extends Data.TaggedError("MetricsError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter = Metric.counter("http_requests_total")
const responseTimeHistogram = Metric.histogram("http_response_time", {
boundaries: Metric.linearBoundaries({ start: 0, width: 10, count: 10 })
})
const activeConnectionsGauge = Metric.gauge("active_connections")
const statusFrequency = Metric.frequency("http_status_codes")
// Update metrics
yield* Metric.update(requestCounter, 1)
yield* Metric.update(responseTimeHistogram, 45.2)
yield* Metric.update(activeConnectionsGauge, 12)
yield* Metric.update(statusFrequency, "200")
// Get metric values
const counterValue = yield* Metric.value(requestCounter)
const histogramValue = yield* Metric.value(responseTimeHistogram)
const gaugeValue = yield* Metric.value(activeConnectionsGauge)
const frequencyValue = yield* Metric.value(statusFrequency)
return {
counter: counterValue,
histogram: histogramValue,
gauge: gaugeValue,
frequency: frequencyValue
}
})
Metric<function (type parameter) Input in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>Input, function (type parameter) State in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>State>,
f: (defect: unknown) => Inputf: (defect: unknowndefect: unknown) => function (type parameter) Input in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>Input
): 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<function (type parameter) A in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>A, function (type parameter) E in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>E, function (type parameter) R in <A, E, R, Input, State>(self: Effect<A, E, R>, metric: Metric.Metric<Input, State>, f: (defect: unknown) => Input): Effect<A, E, R>R>
<function (type parameter) A in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>A, function (type parameter) E in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>E, function (type parameter) R in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>R, function (type parameter) State in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>State>(
self: Effect<A, E, R>(parameter) self: {
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;
}
self: 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<function (type parameter) A in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>A, function (type parameter) E in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>E, function (type parameter) R in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>R>,
metric: Metric.Metric<unknown, State>(parameter) metric: {
Input: Contravariant<Input>;
State: Covariant<State>;
id: string;
type: Metric.Type;
description: string | undefined;
attributes: Metric.AttributeSet | undefined;
valueUnsafe: (context: Context.Context<never>) => State;
updateUnsafe: (input: Input, context: Context.Context<never>) => void;
modifyUnsafe: (input: Input, context: Context.Context<never>) => void;
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; <…;
}
metric: import MetricMetric.interface Metric<in Input, out State>A Metric<Input, State> represents a concurrent metric which accepts update
values of type Input and are aggregated to a value of type State.
Details
For example, a counter metric would have type Metric<number, number>,
representing the fact that the metric can be updated with numbers (the amount
to increment or decrement the counter by), and the state of the counter is a
number.
There are five primitive metric types supported by Effect:
- Counters
- Frequencies
- Gauges
- Histograms
- Summaries
Example (Using multiple metric types)
import { Data, Effect, Metric } from "effect"
class MetricExample extends Data.TaggedError("MetricExample")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter: Metric.Counter<number> = Metric.counter("requests", {
description: "Total requests processed"
})
const memoryGauge: Metric.Gauge<number> = Metric.gauge("memory_usage", {
description: "Current memory usage in MB"
})
const statusFrequency: Metric.Frequency = Metric.frequency("status_codes", {
description: "HTTP status code frequency"
})
// All metrics share the same interface for updates and reads
yield* Metric.update(requestCounter, 1)
yield* Metric.update(memoryGauge, 128)
yield* Metric.update(statusFrequency, "200")
// All metrics can be read with Metric.value
const counterState = yield* Metric.value(requestCounter)
const gaugeState = yield* Metric.value(memoryGauge)
const frequencyState = yield* Metric.value(statusFrequency)
// Metrics have common properties accessible through the interface:
// - id: unique identifier
// - type: metric type ("Counter", "Gauge", "Frequency", etc.)
// - description: optional human-readable description
// - attributes: optional key-value attributes for tagging
return {
counter: {
id: requestCounter.id,
type: requestCounter.type,
state: counterState
},
gauge: { id: memoryGauge.id, type: memoryGauge.type, state: gaugeState },
frequency: {
id: statusFrequency.id,
type: statusFrequency.type,
state: frequencyState
}
}
})
The Metric namespace provides a comprehensive system for collecting, aggregating, and observing
application metrics in Effect applications.
Example (Collecting application metrics)
import { Data, Effect, Metric } from "effect"
class MetricsError extends Data.TaggedError("MetricsError")<{
readonly operation: string
}> {}
const program = Effect.gen(function*() {
// Create different types of metrics
const requestCounter = Metric.counter("http_requests_total")
const responseTimeHistogram = Metric.histogram("http_response_time", {
boundaries: Metric.linearBoundaries({ start: 0, width: 10, count: 10 })
})
const activeConnectionsGauge = Metric.gauge("active_connections")
const statusFrequency = Metric.frequency("http_status_codes")
// Update metrics
yield* Metric.update(requestCounter, 1)
yield* Metric.update(responseTimeHistogram, 45.2)
yield* Metric.update(activeConnectionsGauge, 12)
yield* Metric.update(statusFrequency, "200")
// Get metric values
const counterValue = yield* Metric.value(requestCounter)
const histogramValue = yield* Metric.value(responseTimeHistogram)
const gaugeValue = yield* Metric.value(activeConnectionsGauge)
const frequencyValue = yield* Metric.value(statusFrequency)
return {
counter: counterValue,
histogram: histogramValue,
gauge: gaugeValue,
frequency: frequencyValue
}
})
Metric<unknown, function (type parameter) State in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>State>
): 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<function (type parameter) A in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>A, function (type parameter) E in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>E, function (type parameter) R in <A, E, R, State>(self: Effect<A, E, R>, metric: Metric.Metric<unknown, State>): Effect<A, E, R>R>
} = dual<(...args: Array<any>) => any, (self: any, metric: any, f: any) => Effect<unknown, unknown, unknown>>(isDataFirst: (args: IArguments) => boolean, body: (self: any, metric: any, f: any) => Effect<unknown, unknown, unknown>): ((...args: Array<any>) => any) & ((self: any, metric: any, f: any) => Effect<unknown, unknown, unknown>) (+1 overload)Creates a function that can be called in data-first style or data-last
(pipe-friendly) style.
When to use
Use to expose one implementation through both direct and pipe-friendly
call styles.
Details
Pass either the arity of the uncurried function or a predicate that decides
whether the current call is data-first. Arity is the common case. Use a
predicate when optional arguments make arity ambiguous.
Example (Selecting data-first or data-last style by arity)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(2, (self, that) => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Defining overloads with call signatures)
import { Function, pipe } from "effect"
const sum: {
(that: number): (self: number) => number
(self: number, that: number): number
} = Function.dual(2, (self: number, that: number): number => self + that)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
Example (Selecting data-first or data-last style with a predicate)
import { Function, pipe } from "effect"
const sum = Function.dual<
(that: number) => (self: number) => number,
(self: number, that: number) => number
>(
(args) => args.length === 2,
(self, that) => self + that
)
console.log(sum(2, 3)) // 5
console.log(pipe(2, sum(3))) // 5
dual(
(args: IArgumentsargs) => const isEffect: (
u: unknown
) => u is Effect<any, any, any>
Checks whether a value is an Effect.
Example (Checking whether a value is an Effect)
import { Effect } from "effect"
console.log(Effect.isEffect(Effect.succeed(1))) // true
console.log(Effect.isEffect("hello")) // false
isEffect(args: IArgumentsargs[0]),
(self: anyself, metric: anymetric, f: anyf) =>
const tapDefect: {
<E, B, E2, R2>(
f: (defect: unknown) => Effect<B, E2, R2>
): <A, R>(
self: Effect<A, E, R>
) => Effect<A, E | E2, R | R2>
<A, E, R, B, E2, R2>(
self: Effect<A, E, R>,
f: (defect: unknown) => Effect<B, E2, R2>
): Effect<A, E | E2, R | R2>
}
tapDefect(self: anyself, (defect: unknowndefect) => {
const const input: anyinput = f: anyf === var undefinedundefined ? defect: unknowndefect : internalCall<any>(body: () => any): anyinternalCall(() => f: anyf(defect: unknowndefect))
return import MetricMetric.const update: {
<Input>(input: Input): <State>(
self: Metric<Input, State>
) => Effect<void>
<Input, State>(
self: Metric<Input, State>,
input: Input
): Effect<void>
}
update(metric: anymetric, const input: anyinput)
})
)