Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

EventLog unstable

Runtime for writing typed events to an event journal.

EventLog combines event groups, handlers, a journal, local identity, optional remote replicas, and reactivity hooks. Writers send typed payloads through a client; the matching handler runs first, and the journal entry is committed only after the handler succeeds. This module also contains the layers and helpers needed to assemble that runtime.

25 exports Since v4.0.0 Source

Compaction

Since v4.0.0

Registers a compaction handler for an event group.

Details

During remote replay, matching entries are decoded, grouped by primary key, and passed to the compaction effect, which may write replacement entries.

Signature

declare function groupCompaction<Events extends Any, R>(group: EventGroup<Events>, effect: (options: {
readonly entries: readonly Array<Entry>;
readonly events: readonly Array<TaggedPayload<Events>>;
readonly primaryKey: string;
readonly write: <Tag extends string>(tag: Tag, payload: Type<PayloadSchema<Extract<Events, {
readonly tag: Tag;
}>>>) => Effect<void, never, PayloadSchemaWithTag<Events, Tag>["EncodingServices"]>;
}) => Effect<void, never, R>): Layer<never, never, Registry | R | PayloadSchema<Events>["DecodingServices"]>

Constructors

Since v4.0.0

Decodes a base64url identity string produced by encodeIdentityString.

Gotchas

Invalid input throws a schema decoding error.

Signature

declare function decodeIdentityString(value: string): {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
}
Since v4.0.0

Encodes an event-log identity as a base64url string containing the public key and private key bytes.

Signature

declare function encodeIdentityString(identity: {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
}): string

makeClient

unstable
Since v4.0.0

Creates a typed client function for writing events defined by an EventLogSchema.

Details

The returned function delegates to the EventLog service and preserves each event's success and error types.

Signature

declare function makeClient<Groups extends Any>(schema: EventLogSchema<Groups>): Effect<<Tag extends string>(event: Tag, payload: Type<PayloadSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>) => Effect<Type<SuccessSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>, EventJournalError | Type<ErrorSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>>, never, EventLog>
Since v4.0.0

Generates a new event-log identity using the configured EventLogEncryption service.

Signature

declare const makeIdentity: Effect.Effect<Identity["Service"], never, EventLogEncryption.EventLogEncryption>

Guards

Since v4.0.0

Returns true when a value carries the EventLogSchema marker.

Signature

declare function isEventLogSchema(u: unknown): u is EventLogSchema<Any>

Handlers

group

unstable
Since v4.0.0

Creates a layer that registers handlers for every event in an event group.

Details

The callback receives a Handlers builder; its return type is checked so every event in the group is handled.

Signature

declare function group<Events extends Any, Return>(group: EventGroup<Events>, f: (handlers: Handlers<never, Events>) => ValidateReturn<Return>): Layer<ToService<Events>, Error<Return>, Registry | Exclude<Services<Return>, Scope | Identity>>

Handlers

interface unstable
Since v4.0.0

Builder for the handlers associated with an EventGroup.

Details

The Events type parameter tracks the event tags that still need handlers, and each call to handle records a handler while accumulating any required services.

Signature

interface Handlers<R, Events extends Event.Any = never> extends Pipeable {
readonly "~effect/eventlog/EventLog/Handlers": {
_Events: Covariant<Events>;
};
readonly context: Context<R>;
readonly group: AnyWithProps;
readonly handlers: Record.ReadonlyRecord<string, Handlers.Item<R>>;
handle<Tag extends string, R1>(name: Tag, handler: (options: {
readonly conflicts: readonly Array<{
readonly entry: Entry;
readonly payload: Type<PayloadSchema<Extract<Events, {
readonly tag: Tag;
}>>>;
}>;
readonly entry: Entry;
readonly payload: Type<PayloadSchema<Extract<Events, {
readonly tag: Tag;
}>>>;
readonly storeId: StoreId;
}) => Effect<Type<SuccessSchema<Extract<Events, {
readonly tag: Tag;
}>>>, Type<ErrorSchema<Extract<Events, {
readonly tag: Tag;
}>>>, R1>): Handlers<R | R1, Exclude<Events, {
readonly tag: Tag;
}>>;
}
Since v4.0.0

Builds the effect used to replay entries received from a remote event log.

Details

The returned handler decodes the entry and conflicts with the registered event schema, runs the matching handler with the supplied identity and store id, logs failures, and invalidates configured reactivity keys.

Signature

declare function makeReplayFromRemote(options: {
readonly handlers: ReadonlyMap<string, Item<any>>;
readonly identity: {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
};
readonly logAnnotations: {
readonly effect: string;
readonly service: string;
};
readonly reactivity: Reactivity;
readonly reactivityKeys: Record<string, ReadonlyArray<string>>;
readonly storeId: StoreId;
}): (...args: [{
readonly conflicts: readonly Array<Entry>;
readonly entry: Entry;
}]) => Effect

Layers

layer

unstable
Since v4.0.0

Combines event-group handler layers with the EventLog runtime for a schema.

When to use

Use when you need one layer that installs the shared EventLog runtime for an EventLogSchema and registers an event-group handler layer for typed writes.

Details

The supplied handler layer is provided with layerEventLog. The returned layer provides EventLog | Registry, preserves the handler layer's error type, and still requires its remaining services plus EventJournal and Identity.

Gotchas

The schema argument does not register handlers by itself. Handler registration comes from the supplied layer, and writing an event without a registered handler dies with Event handler not found for: "<tag>".

See

  • schema for creating the schema argument from event groups
  • group for building the handler layer consumed by this layer
  • layerEventLog for installing the runtime and registry without combining a handler layer

Signature

declare function layer<Groups extends Any, E, R>(_schema: EventLogSchema<Groups>, layer: Layer<ToService<Groups>, E, R>): Layer<EventLog | Registry, E, EventJournal | Identity | Exclude<R, EventLog | Registry>>
Since v4.0.0

Provides EventLog and Registry using the configured EventJournal and Identity.

Signature

declare const layerEventLog: Layer.Layer<EventLog | Registry, never, EventJournal | Identity>
Since v4.0.0

Provides an in-memory Registry for event handlers, compactors, remote replicas, and reactivity keys.

Signature

declare const layerRegistry: Layer<Registry, never, never>

Other

Handlers

unstable
Since v4.0.0

Namespace containing helper types for Handlers values and handler-producing layers.

Reactivity

Since v4.0.0

Registers reactivity keys to invalidate when events from a group are written or replayed.

Details

Pass a single key list for all events or a mapping from event tag to key list.

Signature

declare function groupReactivity<Events extends Any>(group: EventGroup<Events>, keys: readonly Array<string> | { [Tag in string]: readonly Array<string> }): Layer<never, never, Registry>

Schemas

EventLogSchema

interface unstable
Since v4.0.0

Schema describing the event groups that can be written through an EventLog.

Signature

interface EventLogSchema<Groups extends EventGroup.Any> {
readonly "~effect/eventlog/EventLog/Schema": "~effect/eventlog/EventLog/Schema";
readonly groups: readonly Array<Groups>;
}
Since v4.0.0

Schema for an event-log identity with a string public key and redacted base64-encoded private key bytes.

Signature

declare const IdentitySchema: Struct<{
readonly privateKey: decodeTo<Redacted<Uint8Array>, Uint8ArrayFromBase64, never, never>;
readonly publicKey: String;
}>

schema

unstable
Since v4.0.0

Creates an EventLogSchema from one or more event groups.

Signature

declare function schema<Groups extends readonly Array<Any>>(...groups: Groups): EventLogSchema<Groups[number]>

Services

Since v4.0.0

Context reference for the store id used by event-log writes and remote replication.

Details

Defaults to the branded store id "default".

Signature

declare class CurrentStoreId extends {} {
constructor(_: never);
}

EventLog

unstable
Since v4.0.0

Service for writing typed event-log events through registered handlers.

Details

write encodes the event payload, runs the matching handler, commits the entry only when the handler succeeds, and exposes access to the underlying journal entries and destroy operation.

Signature

declare class EventLog extends Shape<"effect/eventlog/EventLog", {
readonly destroy: Effect<void, EventJournalError>;
readonly entries: Effect<readonly Array<Entry>, EventJournalError>;
readonly write: <Groups extends Any, Tag extends string>(options: {
readonly event: Tag;
readonly payload: Type<PayloadSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>;
readonly schema: EventLogSchema<Groups>;
}) => Effect<Type<SuccessSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>, EventJournalError | Type<ErrorSchema<Extract<Events<Groups>, {
readonly tag: Tag;
}>>>>;
}, this> {
constructor(_: never);
}

Identity

unstable
Since v4.0.0

Context service for an event-log identity containing a public key and redacted private key material.

Details

The identity is used by remote replication for authentication and by the encryption service to derive signing and encryption keys.

Signature

declare class Identity extends Shape<"effect/eventlog/EventLog/Identity", {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
}, this> {
constructor(_: never);
}

Registry

unstable
Since v4.0.0

Service that collects event handlers, compaction handlers, remote replicas, and reactivity invalidation keys.

Signature

declare class Registry extends Shape<"effect/eventlog/EventLog/Registry", {
readonly compactors: ReadonlyMap<string, {
readonly effect: (options: {
readonly entries: readonly Array<Entry>;
readonly write: (entry: Entry) => Effect<void>;
}) => Effect<void>;
readonly events: ReadonlySet<string>;
}>;
readonly handleRemote: (handler: (remote: {
readonly changes: (options: {
readonly identity: {
readonly privateKey: Redacted<Uint8Array<...>>;
readonly publicKey: string;
};
readonly startSequence: number;
readonly storeId: StoreId;
}) => Effect<Dequeue<RemoteEntry, EventLogRemoteError>, never, Scope>;
readonly id: RemoteId;
readonly whenAuthenticated: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, EventLogRemoteError | E, Identity | R>;
readonly write: (options: {
readonly entries: readonly Array<Entry>;
readonly identity: {
readonly privateKey: Redacted<Uint8Array<...>>;
readonly publicKey: string;
};
readonly storeId: StoreId;
}) => Effect<void, EventLogRemoteError>;
}) => Effect<void>) => Effect<void>;
readonly handlers: ReadonlyMap<string, Item<any>>;
readonly reactivityKeys: Record<string, ReadonlyArray<string>>;
readonly registerCompaction: (options: {
readonly effect: (options: {
readonly entries: readonly Array<Entry>;
readonly write: (entry: Entry) => Effect<void>;
}) => Effect<void>;
readonly events: readonly Array<string>;
}) => Effect<void, never, Scope>;
readonly registerHandlerUnsafe: (options: {
readonly event: string;
readonly handler: Item<any>;
}) => void;
readonly registerReactivity: (keys: Record<string, ReadonlyArray<string>>) => Effect<void, never, Scope>;
readonly registerRemote: (remote: {
readonly changes: (options: {
readonly identity: {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
};
readonly startSequence: number;
readonly storeId: StoreId;
}) => Effect<Dequeue<RemoteEntry, EventLogRemoteError>, never, Scope>;
readonly id: RemoteId;
readonly whenAuthenticated: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, EventLogRemoteError | E, Identity | R>;
readonly write: (options: {
readonly entries: readonly Array<Entry>;
readonly identity: {
readonly privateKey: Redacted<Uint8Array<ArrayBuffer>>;
readonly publicKey: string;
};
readonly storeId: StoreId;
}) => Effect<void, EventLogRemoteError>;
}) => Effect<void, never, Scope>;
}, this> {
constructor(_: never);
}

Type IDs

Since v4.0.0

Runtime property key used to identify Handlers values.

Signature

declare const HandlersTypeId: "~effect/eventlog/EventLog/Handlers"

HandlersTypeId

type unstable
Since v4.0.0

Type-level identifier used to brand Handlers values.

Signature

type HandlersTypeId = "~effect/eventlog/EventLog/Handlers"
Since v4.0.0

Runtime property key used to identify EventLogSchema values.

Signature

declare const SchemaTypeId: "~effect/eventlog/EventLog/Schema"

SchemaTypeId

type unstable
Since v4.0.0

Type-level identifier used to brand EventLogSchema values.

Signature

type SchemaTypeId = "~effect/eventlog/EventLog/Schema"