559 lines
12 KiB
TypeScript
559 lines
12 KiB
TypeScript
/**
|
|
* Defines the experimental wire schema used by the Effect devtools protocol.
|
|
*
|
|
* The module contains the serialized message shapes exchanged between devtools
|
|
* clients and servers: span snapshots, span events, metric snapshots,
|
|
* heartbeats, and request/response unions. Use these schemas at protocol
|
|
* boundaries to encode, decode, or validate custom transports that need to
|
|
* interoperate with the built-in unstable devtools client and server.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
import * as Exit from "../../Exit.ts"
|
|
import { identity } from "../../Function.ts"
|
|
import type * as Option from "../../Option.ts"
|
|
import * as Schema from "../../Schema.ts"
|
|
import * as SchemaTransformation from "../../SchemaTransformation.ts"
|
|
|
|
/**
|
|
* Schema for a span status representing a span that has started but not yet
|
|
* ended.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const SpanStatusStarted = Schema.Struct({
|
|
_tag: Schema.tag("Started"),
|
|
startTime: Schema.BigInt
|
|
})
|
|
|
|
/**
|
|
* Type of a span status representing a span that has started but not yet ended.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type SpanStatusStarted = Schema.Schema.Type<typeof SpanStatusStarted>
|
|
|
|
/**
|
|
* Schema for a span status representing an ended span, including start time,
|
|
* end time, and encoded exit status. Encoding drops success values with
|
|
* `Exit.asVoid`.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const SpanStatusEnded = Schema.Struct({
|
|
_tag: Schema.tag("Ended"),
|
|
startTime: Schema.BigInt,
|
|
endTime: Schema.BigInt,
|
|
exit: Schema.Exit(Schema.Void, Schema.Defect({ includeStack: true }), Schema.Defect({ includeStack: true })).pipe(
|
|
Schema.decodeTo(
|
|
Schema.Exit(Schema.Unknown, Schema.Unknown, Schema.Unknown),
|
|
SchemaTransformation.transform({
|
|
decode: identity,
|
|
encode: Exit.asVoid
|
|
})
|
|
)
|
|
)
|
|
})
|
|
|
|
/**
|
|
* Type of a span status representing an ended span with start time, end time,
|
|
* and exit status.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type SpanStatusEnded = Schema.Schema.Type<typeof SpanStatusEnded>
|
|
|
|
/**
|
|
* Schema for devtools span status, either started or ended.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const SpanStatus = Schema.Union([SpanStatusStarted, SpanStatusEnded])
|
|
|
|
/**
|
|
* Type of a devtools span status, either started or ended.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type SpanStatus = Schema.Schema.Type<typeof SpanStatus>
|
|
|
|
/**
|
|
* Serialized parent span context for a span created outside the current
|
|
* devtools span tree.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export interface ExternalSpan {
|
|
readonly _tag: "ExternalSpan"
|
|
readonly spanId: string
|
|
readonly traceId: string
|
|
readonly sampled: boolean
|
|
}
|
|
|
|
/**
|
|
* Schema for an external parent span context containing span id, trace id, and
|
|
* sampling flag.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const ExternalSpan: Schema.Codec<ExternalSpan> = Schema.Struct({
|
|
_tag: Schema.tag("ExternalSpan"),
|
|
spanId: Schema.String,
|
|
traceId: Schema.String,
|
|
sampled: Schema.Boolean
|
|
})
|
|
|
|
/**
|
|
* Telemetry payload for an Effect span sent to devtools, including identity,
|
|
* attributes, status, sampling flag, and optional parent span.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export interface Span {
|
|
readonly _tag: "Span"
|
|
readonly spanId: string
|
|
readonly traceId: string
|
|
readonly name: string
|
|
readonly sampled: boolean
|
|
readonly attributes: ReadonlyMap<string, unknown>
|
|
readonly status: SpanStatus
|
|
readonly parent: Option.Option<ParentSpan>
|
|
}
|
|
|
|
/**
|
|
* Schema for an Effect span telemetry payload sent to devtools.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Span: Schema.Codec<Span> = Schema.Struct({
|
|
_tag: Schema.tag("Span"),
|
|
spanId: Schema.String,
|
|
traceId: Schema.String,
|
|
name: Schema.String,
|
|
sampled: Schema.Boolean,
|
|
attributes: Schema.ReadonlyMap(Schema.String, Schema.Any),
|
|
status: SpanStatus,
|
|
parent: Schema.Option(Schema.suspend(() => ParentSpan))
|
|
})
|
|
|
|
/**
|
|
* Schema for a named event emitted by a span, including trace id, span id,
|
|
* start time, and optional attributes.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const SpanEvent = Schema.Struct({
|
|
_tag: Schema.tag("SpanEvent"),
|
|
traceId: Schema.String,
|
|
spanId: Schema.String,
|
|
name: Schema.String,
|
|
startTime: Schema.BigInt,
|
|
attributes: Schema.UndefinedOr(Schema.Record(Schema.String, Schema.Any))
|
|
})
|
|
|
|
/**
|
|
* Type of a named event emitted by a span and sent to devtools.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type SpanEvent = Schema.Schema.Type<typeof SpanEvent>
|
|
|
|
/**
|
|
* Type of a span parent, represented either by a devtools `Span` payload or an
|
|
* `ExternalSpan` context.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type ParentSpan = Span | ExternalSpan
|
|
|
|
/**
|
|
* Schema for a span parent, either a full devtools `Span` payload or an
|
|
* `ExternalSpan` context.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const ParentSpan = Schema.Union([Span, ExternalSpan])
|
|
|
|
/**
|
|
* Schema for the devtools heartbeat request sent by the client.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Ping = Schema.Struct({
|
|
_tag: Schema.tag("Ping")
|
|
})
|
|
|
|
/**
|
|
* Type of the devtools heartbeat request sent by the client.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Ping = Schema.Schema.Type<typeof Ping>
|
|
|
|
/**
|
|
* Schema for the devtools heartbeat response.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Pong = Schema.Struct({
|
|
_tag: Schema.tag("Pong")
|
|
})
|
|
|
|
/**
|
|
* Type of the devtools heartbeat response.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Pong = Schema.Schema.Type<typeof Pong>
|
|
|
|
/**
|
|
* Schema for a devtools request asking the client to send a metrics snapshot.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const MetricsRequest = Schema.Struct({
|
|
_tag: Schema.tag("MetricsRequest")
|
|
})
|
|
|
|
/**
|
|
* Type of a devtools request asking the client to send a metrics snapshot.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type MetricsRequest = Schema.Schema.Type<typeof MetricsRequest>
|
|
|
|
/**
|
|
* Schema for a metric label key/value pair in a devtools metrics snapshot.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const MetricLabel = Schema.Struct({
|
|
key: Schema.String,
|
|
value: Schema.String
|
|
})
|
|
|
|
/**
|
|
* Type of a metric label key/value pair in a devtools metrics snapshot.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type MetricLabel = Schema.Schema.Type<typeof MetricLabel>
|
|
|
|
const metric = <Type extends string, State extends Schema.Constraint>(type: Type, state: State) =>
|
|
Schema.Struct({
|
|
id: Schema.String,
|
|
type: Schema.tag(type),
|
|
description: Schema.UndefinedOr(Schema.String),
|
|
attributes: Schema.UndefinedOr(Schema.Record(Schema.String, Schema.String)),
|
|
state
|
|
})
|
|
|
|
/**
|
|
* Schema for a counter metric snapshot, including the count and whether updates
|
|
* are incremental.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Counter = metric(
|
|
"Counter",
|
|
Schema.Struct({
|
|
count: Schema.Union([Schema.Number, Schema.BigInt]),
|
|
incremental: Schema.Boolean
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Type of a devtools counter metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The state contains the current count and whether the counter reports
|
|
* incremental updates.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Counter = Schema.Schema.Type<typeof Counter>
|
|
|
|
/**
|
|
* Schema for a devtools frequency metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The metric state records occurrence counts by string key.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Frequency = metric(
|
|
"Frequency",
|
|
Schema.Struct({
|
|
occurrences: Schema.ReadonlyMap(Schema.String, Schema.Number)
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Type of a devtools frequency metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The state maps observed string values to occurrence counts.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Frequency = Schema.Schema.Type<typeof Frequency>
|
|
|
|
/**
|
|
* Schema for a devtools gauge metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The metric state contains the current numeric or bigint value.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Gauge = metric(
|
|
"Gauge",
|
|
Schema.Struct({
|
|
value: Schema.Union([Schema.Number, Schema.BigInt])
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Type of a devtools gauge metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The state contains the current numeric or bigint value.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Gauge = Schema.Schema.Type<typeof Gauge>
|
|
|
|
/**
|
|
* Schema for a devtools histogram metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The metric state includes bucket counts plus the total count, minimum,
|
|
* maximum, and sum.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Histogram = metric(
|
|
"Histogram",
|
|
Schema.Struct({
|
|
buckets: Schema.Array(Schema.Tuple([Schema.Number, Schema.Number])),
|
|
count: Schema.Number,
|
|
min: Schema.Number,
|
|
max: Schema.Number,
|
|
sum: Schema.Number
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Type of a devtools histogram metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The state includes bucket counts plus the total count, minimum, maximum, and
|
|
* sum.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Histogram = Schema.Schema.Type<typeof Histogram>
|
|
|
|
/**
|
|
* Schema for a devtools summary metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The metric state contains quantile values plus the total count, minimum,
|
|
* maximum, and sum.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Summary = metric(
|
|
"Summary",
|
|
Schema.Struct({
|
|
quantiles: Schema.Array(Schema.Tuple([Schema.Number, Schema.UndefinedOr(Schema.Number)])),
|
|
count: Schema.Number,
|
|
min: Schema.Number,
|
|
max: Schema.Number,
|
|
sum: Schema.Number
|
|
})
|
|
)
|
|
|
|
/**
|
|
* Type of a devtools summary metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The state contains quantile values plus the total count, minimum, maximum,
|
|
* and sum.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Summary = Schema.Schema.Type<typeof Summary>
|
|
|
|
/**
|
|
* Schema for any devtools metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* Accepted metric kinds are counters, frequencies, gauges, histograms, and
|
|
* summaries.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Metric = Schema.Union([Counter, Frequency, Gauge, Histogram, Summary])
|
|
|
|
/**
|
|
* Type of any devtools metric snapshot.
|
|
*
|
|
* **Details**
|
|
*
|
|
* The union covers counters, frequencies, gauges, histograms, and summaries.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Metric = Schema.Schema.Type<typeof Metric>
|
|
|
|
/**
|
|
* Schema for a devtools protocol message containing the current metric
|
|
* snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const MetricsSnapshot = Schema.Struct({
|
|
_tag: Schema.tag("MetricsSnapshot"),
|
|
metrics: Schema.Array(Metric)
|
|
})
|
|
|
|
/**
|
|
* Type of a devtools protocol message containing the current metric snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type MetricsSnapshot = Schema.Schema.Type<typeof MetricsSnapshot>
|
|
|
|
/**
|
|
* Schema for devtools protocol requests accepted by the server.
|
|
*
|
|
* **Details**
|
|
*
|
|
* Requests include heartbeat pings, spans, span events, and metric snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Request = Schema.Union([Ping, Span, SpanEvent, MetricsSnapshot])
|
|
|
|
/**
|
|
* Type of devtools protocol requests accepted by the server.
|
|
*
|
|
* **Details**
|
|
*
|
|
* Requests include heartbeat pings, spans, span events, and metric snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Request = Schema.Schema.Type<typeof Request>
|
|
|
|
/**
|
|
* Namespace containing helper types for devtools protocol requests.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
export declare namespace Request {
|
|
/**
|
|
* Devtools request messages excluding heartbeat pings.
|
|
*
|
|
* **Details**
|
|
*
|
|
* `DevToolsServer` handles `Ping` internally and exposes only these requests
|
|
* to client handlers.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
export type WithoutPing = Exclude<Request, { readonly _tag: "Ping" }>
|
|
}
|
|
|
|
/**
|
|
* Schema for devtools protocol responses sent by the server.
|
|
*
|
|
* **Details**
|
|
*
|
|
* Responses include heartbeat pongs and requests for metric snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export const Response = Schema.Union([Pong, MetricsRequest])
|
|
|
|
/**
|
|
* Type of devtools protocol responses sent by the server.
|
|
*
|
|
* **Details**
|
|
*
|
|
* Responses include heartbeat pongs and requests for metric snapshots.
|
|
*
|
|
* @category schemas
|
|
* @since 4.0.0
|
|
*/
|
|
export type Response = Schema.Schema.Type<typeof Response>
|
|
|
|
/**
|
|
* Namespace containing helper types for devtools protocol responses.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
export declare namespace Response {
|
|
/**
|
|
* Devtools response messages excluding heartbeat pongs.
|
|
*
|
|
* **Details**
|
|
*
|
|
* `DevToolsServer` sends `Pong` internally and accepts only these responses
|
|
* from client handlers.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
export type WithoutPong = Exclude<Response, { readonly _tag: "Pong" }>
|
|
}
|