Skip to content

Documentation / @etherfold/core / StreamWriter

Class: StreamWriter<ABI> ​

Defined in: packages/core/src/stream/writer.ts:172

THE ONE WRITER OF ONE STREAM: it answers where the next range must start, and it appends what comes back.

It implements LogIngestion, so it is addressable on the wire exactly as a receiver was -- a stream is ONE address ({source, config}) and this is what that address now resolves to. What it does NOT carry is a generation: a stream address has no single fold behind it any more, which is the whole point, so the field is absent rather than filled in with whichever fold happened to be first.

Type Parameters ​

ABI ​

ABI extends Abi

Implements ​

Constructors ​

Constructor ​

new StreamWriter<ABI>(source, options): StreamWriter<ABI>

Defined in: packages/core/src/stream/writer.ts:193

Parameters ​

source ​

IndexingSource<ABI>

options ​

StreamWriterOptions<ABI>

Returns ​

StreamWriter<ABI>

Properties ​

context ​

readonly context: WireContext

Defined in: packages/core/src/stream/writer.ts:178

The {source, config} a sender must assert to be talking to this writer.

Implementation of ​

LogIngestion.context


defaultFromBlock ​

readonly defaultFromBlock: number

Defined in: packages/core/src/stream/writer.ts:174

The earliest block this source can have anything to say about.


streamConfig ​

readonly streamConfig: UsedStreamConfig

Defined in: packages/core/src/stream/writer.ts:176

The resolved stream config, which is what config in the context hashes.


streamDigest ​

readonly streamDigest: string

Defined in: packages/core/src/stream/writer.ts:180

WHICH stream this writes, as everything that stores its emissions keys them.

Implementation of ​

LogIngestion.streamDigest

Methods ​

expectedFromBlock() ​

expectedFromBlock(): Promise<number>

Defined in: packages/core/src/stream/writer.ts:228

Where the next batch must start -- read from the STREAM and from no fold.

It is NOT lastToBlock + 1: it reaches back to latestBlock - finality so the unconfirmed window is re-delivered every round, which is the only way a reorg is ever detected. That rule is getFromBlock's and is shared with every other thing that resumes; what moved is WHOSE three numbers it is applied to.

This is the line the whole change turns on. Answered from a fold's cursor, a restarted deployment with an empty-state successor asks for history the stream already holds and stores it a second time; answered from the stream, there is nothing about any fold that could drag it backwards.

Reading this WRITES NOTHING. A receiver's read used to register a generation and could clear a foreign cursor; a stream has no fold to reconcile.

Returns ​

Promise<number>

Implementation of ​

LogIngestion.expectedFromBlock


receive() ​

receive(batch): Promise<IngestionResult<ABI>>

Defined in: packages/core/src/stream/writer.ts:247

Append one batch to the stream, or refuse it having appended nothing.

The order is the same one StreamBuilder.receive established and it is still load-bearing: identity first (a batch for another source must never be told to resume from a block number that means nothing to it), then the envelope, then the cursor -- which is generateStreamToAppend's own check, so the engine and not a second opinion beside it.

The APPEND is not best-effort and nothing catches it: a state that advanced past events the stream never received is a HOLE, so a batch that could not be stored is not delivered to anybody. The failure propagates, no fold sees it, the stream's position does not move, and the next cycle re-derives exactly this delta.

Parameters ​

batch ​

WireBatch<ABI>

Returns ​

Promise<IngestionResult<ABI>>

Implementation of ​

LogIngestion.receive