Skip to content
// EFFECT DAYS 2026

EventLogMessage unstable

Defines protocol messages for event-log remote clients and servers.

This module is the shared boundary between EventLogRemote clients and event-log servers. It defines store ids, protocol errors, the hello/authenticate session handshake, remote calls for writes and changes, and message formats for encrypted or plaintext journal entries.

35 exports Since v4.0.0 Source

Middleware

RPC middleware that authenticates event-log requests and provides the client Identity to authenticated handlers.

Signature

declare class EventLogAuthentication extends Shape<"effect/eventlog/EventLogMessage/EventLogAuthentication", RpcMiddleware<Identity, EventLogProtocolError, never>, this> & {
readonly "~effect/rpc/RpcMiddleware": {
readonly clientError: never;
readonly error: typeof EventLogProtocolError;
readonly provides: Identity;
readonly requires: never;
};
} {
constructor(_: never);
}

Models

StoreId

type unstable
Since v4.0.0

Branded string identifying a logical event-log store.

Signature

type StoreId = string & Brand<StoreIdTypeId>

Protocols

Since v4.0.0

Schema for an authentication request containing the client public key, Ed25519 signing public key, signature over the session challenge payload, and algorithm name.

Signature

declare class Authenticate extends {
readonly algorithm: "Ed25519";
readonly publicKey: string;
readonly signature: Uint8Array<ArrayBuffer>;
readonly signingPublicKey: Uint8Array<ArrayBuffer>;
} {
constructor(...args: [props: {
readonly algorithm: "Ed25519";
readonly publicKey: string;
readonly signature: Uint8Array<ArrayBuffer>;
readonly signingPublicKey: Uint8Array<ArrayBuffer>;
}, options?: MakeOptions]);
}
Since v4.0.0

RPC used to authenticate a remote event-log session after HelloRpc.

Signature

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

ChangesRpc

unstable
Since v4.0.0

RPC used to stream remote event-log changes for a public key and store id starting at a sequence number.

Details

Responses are encoded as either SingleMessage values or ChunkedMessage parts. Entries written on this connection are acknowledged, not echoed.

Signature

declare class ChangesRpc extends {} {
constructor(_: never);
static decodeEncrypted: (input: Uint8Array<ArrayBuffer>, options?: ParseOptions) => Effect<readonly [{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
readonly sequence: number;
}, {
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
readonly sequence: number;
}], SchemaError, never>;
static decodeUnencrypted: (input: Uint8Array<ArrayBuffer>, options?: ParseOptions) => Effect<readonly [RemoteEntry, RemoteEntry], SchemaError, never>;
static encodeEncrypted: (input: readonly [{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
readonly sequence: number;
}, {
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
readonly sequence: number;
}], options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static encodeUnencrypted: (input: readonly [RemoteEntry, RemoteEntry], options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static EncryptedFromSchemaBinary: toCodec<NonEmptyArray<Struct<{
readonly encryptedBatch: Transferable<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
readonly entryIds: NonEmptyArray<brand<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, "effect/eventlog/EventJournal/EntryId">>;
readonly iv: Transferable<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
readonly sequence: Natural;
}>>>;
static UnencryptedFromSchemaBinary: toCodec<NonEmptyArray<typeof RemoteEntry>>;
}
Since v4.0.0

Represents one part of a large encoded event-log payload.

When to use

Use to divide data into chunks and join to reassemble all chunks with the same id once every part has arrived.

Signature

declare class ChunkedMessage extends {
readonly _tag: "Chunked";
readonly data: Uint8Array<ArrayBuffer>;
readonly id: number;
readonly part: readonly [number, number];
} {
constructor(...args: [props: {
readonly _tag?: "Chunked";
readonly data: Uint8Array<ArrayBuffer>;
readonly id: number;
readonly part: readonly [number, number];
}, options?: MakeOptions]);
static chunkSize: number;
static initialJoinState(): Map<number, {
bytes: number;
count: number;
readonly parts: Array<Uint8Array<ArrayBufferLike>>;
}>;
static join(map: Map<number, {
bytes: number;
count: number;
readonly parts: Array<Uint8Array<ArrayBufferLike>>;
}>, part: ChunkedMessage): Uint8Array<ArrayBuffer> | undefined;
static split(id: number, data: Uint8Array): readonly [ChunkedMessage, ChunkedMessage];
}
Since v4.0.0

RPC that releases an open compaction stage. A late abort is a no-op.

Signature

declare class CompactionAbortRpc extends {} {
constructor(_: never);
}
Since v4.0.0

Schema for the result of opening a compaction stage.

Details

Started pins the stage to the active generation and to the last input sequence. Busy means another stage is open on the store. NotWanted means the store doesn't need compacting.

Signature

declare const CompactionBeginResult: Union<readonly [TaggedStruct<"Started", {
readonly stageId: String;
}>, TaggedStruct<"Busy", {}>, TaggedStruct<"NotWanted", {}>]>
Since v4.0.0

The result of opening a compaction stage.

Signature

type CompactionBeginResult = typeof CompactionBeginResult.Type
Since v4.0.0

RPC that opens a compaction stage.

Signature

declare class CompactionBeginRpc extends {} {
constructor(_: never);
}
Since v4.0.0

RPC that commits a compaction stage.

Details

Answers Superseded when the stage's pinned generation is no longer active. Fails with InvalidRequest, aborting the stage, when the segments are incomplete or the kept ids are not a non-empty, repeat-free subsequence of the pinned input. Fails with NotFound when the stage expired, was aborted or committed, or is unknown, so a retried commit fails too.

Signature

declare class CompactionCommitRpc extends {} {
constructor(_: never);
}
Since v4.0.0

RPC that streams the encrypted input batches at the given input sequences.

Details

batches holds the input sequence of each batch to fetch. Batches are framed and encoded as in ChangesRpc. It fails with a NotFound error once the stage or its pin is gone.

Signature

declare class CompactionFetchRpc extends {} {
constructor(_: never);
}
Since v4.0.0

Schema for the header of one compaction input batch.

Details

An entry's input sequence is the batch sequence plus its position in entryIds.

Signature

declare const CompactionInputHeader: Struct<{
readonly entryIds: NonEmptyArray<brand<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, "effect/eventlog/EventJournal/EntryId">>;
readonly sequence: Natural;
}>
Since v4.0.0

The header of one compaction input batch.

Signature

type CompactionInputHeader = typeof CompactionInputHeader.Type
Since v4.0.0

RPC that streams a stage's input batch headers in input order.

Details

The input is the pinned snapshot, then the originals up to the stage's through. Headers are framed as SingleMessage values or ChunkedMessage parts, as in ChangesRpc. It fails with a NotFound error once the stage or its pin is gone.

Signature

declare class CompactionInputRpc extends {} {
constructor(_: never);
static decodeHeaders: (input: Uint8Array<ArrayBuffer>, options?: ParseOptions) => Effect<readonly [{
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly sequence: number;
}, {
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly sequence: number;
}], SchemaError, never>;
static encodeHeaders: (input: readonly [{
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly sequence: number;
}, {
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly sequence: number;
}], options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static HeadersFromSchemaBinary: toCodec<NonEmptyArray<Struct<{
readonly entryIds: NonEmptyArray<brand<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, "effect/eventlog/EventJournal/EntryId">>;
readonly sequence: Natural;
}>>>;
}
Since v4.0.0

RPC that uploads one piece of a compaction snapshot segment.

Details

A segment is an encoded non-empty array of encrypted batches, indexed by chunk.id, and is split into pieces when larger than ChunkedMessage.chunkSize. Re-uploading a stored segment is acknowledged without storing it again. A segment that fails validation aborts the stage with an InvalidRequest error.

Signature

declare class CompactionPartRpc extends {} {
constructor(_: never);
static decodeSegment: (input: Uint8Array<ArrayBuffer>, options?: ParseOptions) => Effect<readonly [{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}, {
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}], SchemaError, never>;
static encodeSegment: (input: readonly [{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}, {
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}], options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static SegmentFromSchemaBinary: toCodec<NonEmptyArray<Struct<{
readonly encryptedBatch: Transferable<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
readonly entryIds: NonEmptyArray<brand<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, "effect/eventlog/EventJournal/EntryId">>;
readonly iv: Transferable<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>>;
}>>>;
}
Since v4.0.0

Schema for the outcome of a compaction run reported at commit.

Details

Snapshot activates the segmentCount uploaded segments. NoOp reports a run that dropped nothing.

Signature

declare const CompactionResult: Union<readonly [TaggedStruct<"Snapshot", {
readonly segmentCount: Natural;
}>, TaggedStruct<"NoOp", {}>]>

CompactionResult

type unstable
Since v4.0.0

The outcome of a compaction run reported at commit.

Signature

type CompactionResult = typeof CompactionResult.Type
Since v4.0.0

The compaction state of a store, as reported to clients.

Details

wanted is true when the server would open a compaction stage. head is the highest stored sequence.

Signature

declare class CompactionStatus extends {
readonly head: number;
readonly wanted: boolean;
} {
constructor(...args: [props: {
readonly head: number;
readonly wanted: boolean;
}, options?: MakeOptions]);
}
Since v4.0.0

RPC that reports a store's compaction state.

Signature

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

RPC group for encrypted remote compaction.

Details

Served by the encrypted server alongside EventLogRemoteRpcs. Clients call it only when HelloResponse.compaction is set.

Signature

declare class EventLogCompactionRpcs extends {} {
constructor(_: never);
}
Since v4.0.0

Error returned by event-log remote RPCs.

Details

It records the request tag, optional identity and store information, a protocol error code, and a human-readable message.

Signature

declare class EventLogProtocolError extends {
readonly _tag: "EventLogProtocolError";
readonly code: "NotFound" | "Forbidden" | "InvalidRequest" | "Unauthorized" | "InternalServerError";
readonly message: string;
readonly publicKey?: string;
readonly requestTag: string;
readonly storeId?: string & Brand<"effect/eventlog/EventLog/StoreId">;
} & YieldableError<this> {
constructor(...args: [props: {
readonly _tag?: "EventLogProtocolError";
readonly code: "NotFound" | "Forbidden" | "InvalidRequest" | "Unauthorized" | "InternalServerError";
readonly message: string;
readonly publicKey?: string;
readonly requestTag: string;
readonly storeId?: string & Brand<"effect/eventlog/EventLog/StoreId">;
}, options?: MakeOptions]);
static is(u: unknown): u is EventLogProtocolError;
}
Since v4.0.0

RPC group containing the event-log remote handshake, authentication, write, and changes endpoints.

Signature

declare class EventLogRemoteRpcs extends {} {
constructor(_: never);
}
Since v4.0.0

Response sent by the remote server during the authentication handshake.

Details

Contains the remote id, a challenge for the client to sign, and the lowest assigned sequence (default 0) for initializing acknowledgement cursors. compaction is true when the server serves EventLogCompactionRpcs.

Signature

declare class HelloResponse extends {
readonly challenge: Uint8Array<ArrayBuffer>;
readonly compaction?: true;
readonly firstSequence?: number;
readonly remoteId: Uint8Array<ArrayBufferLike> & Brand<"effect/eventlog/EventJournal/RemoteId">;
} {
constructor(...args: [props: {
readonly challenge: Uint8Array<ArrayBuffer>;
readonly compaction?: true;
readonly firstSequence?: number;
readonly remoteId: Uint8Array<ArrayBufferLike> & Brand<"effect/eventlog/EventJournal/RemoteId">;
}, options?: MakeOptions]);
}

HelloRpc

unstable
Since v4.0.0

RPC used to start an event-log remote session and receive a HelloResponse.

Signature

declare class HelloRpc extends {} {
constructor(_: never);
}
Since v4.0.0

Represents an entire encoded event-log payload in one transport frame.

Signature

declare class SingleMessage extends {
readonly _tag: "Single";
readonly data: Uint8Array<ArrayBuffer>;
} {
constructor(...args: [props: {
readonly _tag?: "Single";
readonly data: Uint8Array<ArrayBuffer>;
}, options?: MakeOptions]);
}

WriteAck

unstable
Since v4.0.6

Schema for a written entry's id and a sequence at which the server stores it. Entries the server already held keep their stored sequence. When a write stores an entry again, as part of a partly known batch, it is acknowledged at its new position.

Signature

declare const WriteAck: Struct<{
readonly entryId: brand<instanceOf<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>, "effect/eventlog/EventJournal/EntryId">;
readonly sequence: Natural;
}>

WriteAck

type unstable
Since v4.0.6

Acknowledgement of one written entry.

Signature

type WriteAck = typeof WriteAck.Type
Since v4.0.0

RPC used to send one chunk of a large encoded write payload.

Details

The completing chunk returns acknowledgements in request order; earlier chunks return an empty array.

Signature

declare class WriteChunkedRpc extends {} {
constructor(_: never);
}
Since v4.0.0

Schema for encrypted event-log write payloads sent to a remote store.

Details

It includes the client public key, target store id, and the entries encrypted as batches.

Signature

declare class WriteEntries extends {
readonly batches: readonly Array<{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}>;
readonly publicKey: string;
readonly storeId: string & Brand<"effect/eventlog/EventLog/StoreId">;
} {
constructor(...args: [props: {
readonly batches: readonly Array<{
readonly encryptedBatch: Uint8Array<ArrayBuffer>;
readonly entryIds: readonly [Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">, Uint8Array<ArrayBuffer> & Brand<"effect/eventlog/EventJournal/EntryId">];
readonly iv: Uint8Array<ArrayBuffer>;
}>;
readonly publicKey: string;
readonly storeId: string & Brand<"effect/eventlog/EventLog/StoreId">;
}, options?: MakeOptions]);
static decode: (input: Uint8Array<ArrayBuffer>, options?: ParseOptions) => Effect<WriteEntries, SchemaError, never>;
static encode: (input: WriteEntries, options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static FromSchemaBinary: toCodec<typeof WriteEntries>;
encoded: Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
}

Schema for plaintext event-log write payloads sent to a remote store.

Signature

declare class WriteEntriesUnencrypted extends {
readonly entries: readonly Array<Entry>;
readonly publicKey: string;
readonly storeId: string & Brand<"effect/eventlog/EventLog/StoreId">;
} {
constructor(...args: [props: {
readonly entries: readonly Array<Entry>;
readonly publicKey: string;
readonly storeId: string & Brand<"effect/eventlog/EventLog/StoreId">;
}, options?: MakeOptions]);
static encode: (input: WriteEntriesUnencrypted, options?: ParseOptions) => Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static FromSchemaBinary: toCodec<typeof WriteEntriesUnencrypted>;
encoded: Effect<Uint8Array<ArrayBuffer>, SchemaError, never>;
static decode(data: Uint8Array<ArrayBuffer>, options?: ParseOptions): Effect<WriteEntriesUnencrypted, SchemaError>;
}
Since v4.0.0

RPC used to send an encoded write payload that fits in one message.

Details

The response acknowledges every written entry, in request order.

Signature

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

Schemas

StoreId

unstable
Since v4.0.0

Schema for branded event-log store ids.

Signature

declare const StoreId: brand<String, "effect/eventlog/EventLog/StoreId">

Type IDs

Since v4.0.0

Runtime brand identifier for event-log store ids.

Signature

declare const StoreIdTypeId: "effect/eventlog/EventLog/StoreId"

StoreIdTypeId

type unstable
Since v4.0.0

Type-level identifier used to brand event-log store ids.

Signature

type StoreIdTypeId = "effect/eventlog/EventLog/StoreId"