EventLog
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.
Compaction
groupCompaction
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
decodeIdentityString
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;
};encodeIdentityString
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
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
>;makeIdentity
Generates a new event-log identity using the configured EventLogEncryption service.
Signature
declare const makeIdentity: Effect.Effect<
Identity["Service"],
never,
EventLogEncryption.EventLogEncryption
>;Guards
isEventLogSchema
Returns true when a value carries the EventLogSchema marker.
Signature
declare function isEventLogSchema(u: unknown): u is EventLogSchema<Any>;Handlers
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>>;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;
}>>;
}makeReplayFromRemote
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: {
readonly invalidate: (keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>) => Effect<void>;
readonly invalidateUnsafe: (keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>) => void;
readonly mutation: <A, E, R>(keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>, effect: Effect<A, E, R>) => Effect<A, E, R>;
readonly query: <A, E, R>(keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>, effect: Effect<A, E, R>) => Effect<Dequeue<A, E>, never, Scope | R>;
readonly registerUnsafe: (keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>, handler: () => void) => () => void;
readonly stream: <A, E, R>(keys: readonly Array<unknown> | ReadonlyRecord<string, readonly Array<unknown>>, effect: Effect<A, E, R>) => Stream<A, E, Exclude<R, Scope>>;
readonly withBatch: <A, E, R>(effect: Effect<A, E, R>) => Effect<A, E, R>;
};
readonly reactivityKeys: Record<string, ReadonlyArray<string>>;
readonly storeId: StoreId;
}): (...args: [{
readonly conflicts: readonly Array<Entry>;
readonly entry: Entry;
}]) => EffectLayers
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
schemafor creating the schema argument from event groupsgroupfor building the handler layer consumed by this layerlayerEventLogfor 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>>;layerEventLog
Provides EventLog and Registry using the configured EventJournal and Identity.
Signature
declare const layerEventLog: Layer.Layer<EventLog | Registry, never, EventJournal | Identity>;layerRegistry
Provides an in-memory Registry for event handlers, compactors, remote replicas, and reactivity keys.
Signature
declare const layerRegistry: Layer<Registry, never, never>;Other
Reactivity
groupReactivity
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
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>;
}IdentitySchema
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;
}>;Creates an EventLogSchema from one or more event groups.
Signature
declare function schema<Groups extends readonly Array<Any>>(...groups: Groups): EventLogSchema<Groups[number]>Services
CurrentStoreId
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);
}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);
}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);
}Service that collects event handlers, compaction handlers, remote replicas, and reactivity invalidation keys.
Signature
declare class Registry extends Shape<"effect/unstable/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
HandlersTypeId
Runtime property key used to identify Handlers values.
Signature
declare const HandlersTypeId: "~effect/eventlog/EventLog/Handlers";HandlersTypeId type
Type-level identifier used to brand Handlers values.
Signature
type HandlersTypeId = "~effect/eventlog/EventLog/Handlers";SchemaTypeId
Runtime property key used to identify EventLogSchema values.
Signature
declare const SchemaTypeId: "~effect/eventlog/EventLog/Schema";SchemaTypeId type
Type-level identifier used to brand EventLogSchema values.
Signature
type SchemaTypeId = "~effect/eventlog/EventLog/Schema";
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.