Documentation / @etherfold/core / GenerationRebuild
Class: GenerationRebuild<ABI, ProcessResultType> ​
Defined in: packages/core/src/generation/rebuild.ts:452
THE BOUNDED REBUILD OF ONE GENERATION: the chain-free, chunked counterpart of IndexerGeneration.followMore.
That one is a single unbounded advance driven by an engine that owns a provider; this one is a slice at a time, over a stream read through a port, on a runtime that has no chain at all. The RULES are shared and not restated: where a fold resumes is getFromBlock, what a stored stream becomes is generateStreamFromReplay, and what the raw rows decode to is LogEventFetcher.reparse.
It holds no position between calls, on purpose. Everything it needs is read at the top of more() from the processor's persisted cursor, so a fresh object graph -- a new process, a new isolate, a new container over the same database -- resumes exactly where the last committed chunk left off. A field remembering the last chunk would be the one thing a kill between two chunks could lose.
Type Parameters ​
ABI ​
ABI extends Abi
ProcessResultType ​
ProcessResultType = unknown
Constructors ​
Constructor ​
new GenerationRebuild<
ABI,ProcessResultType>(processor,source,options):GenerationRebuild<ABI,ProcessResultType>
Defined in: packages/core/src/generation/rebuild.ts:468
Parameters ​
processor ​
EventProcessor<ABI, ProcessResultType>
source ​
IndexingSource<ABI>
options ​
Returns ​
GenerationRebuild<ABI, ProcessResultType>
Properties ​
defaultFromBlock ​
readonlydefaultFromBlock:number
Defined in: packages/core/src/generation/rebuild.ts:454
The earliest block this source can have anything to say about.
stream ​
readonlystream:string
Defined in: packages/core/src/generation/rebuild.ts:456
WHICH stream is folded, and the key every read of it carries.
Accessors ​
generation ​
Get Signature ​
get generation():
GenerationId
Defined in: packages/core/src/generation/rebuild.ts:489
WHICH generation this rebuilds: the stream above, plus the fold over it.
Returns ​
Methods ​
follow() ​
follow(
delta):Promise<{applied:boolean;replayed:number; }>
Defined in: packages/core/src/generation/rebuild.ts:688
TAKE THE DELTA THE STREAM'S WRITER JUST APPENDED, if this fold is level with it.
The live half of the same one advance. Under ADR-0087 the DEPLOYMENT fetches a stream and appends to it, and every generation over that stream READS what was appended -- so a fold sitting exactly where the append begins folds it there and then, instead of paying a round trip to read back rows it was just handed.
It is the SAME code path as more() below the read: the same checkpoint, the same reparse, the same generateStreamFromReplay, the same delivery cut. Only the source of the chunk differs -- the port, or the writer -- which is what keeps "a generation is a stream plus a fold over it" one implementation rather than two that agree on the day they were written.
Declining is the ordinary answer and never an error ​
A fold that is BEHIND the stream cannot apply a delta beginning above where it resumes: doing so would leave the blocks between as a HOLE in its own state. generateStreamFromReplay already refuses exactly that (UnexpectedFromBlockError), and the refusal is caught HERE and reported as declined rather than thrown, because it is not a fault: a successor mid-catch-up is behind BY DESIGN, and its bounded rebuild is what carries it. A fold that is AHEAD -- a delta it has already applied, re-offered -- resumes above it and declines for the same reason.
Nothing here is a hand-over of the write duty. The append already happened, positioned from the stream, before this fold was consulted; what a fold does or does not take changes nothing about what is stored.
Parameters ​
delta ​
eventStream ​
LogEvent<ABI>[]
lastSync ​
LastSync<ABI>
Returns ​
Promise<{ applied: boolean; replayed: number; }>
more() ​
more(
options?):Promise<RebuildReport>
Defined in: packages/core/src/generation/rebuild.ts:519
ONE CHUNK: resume from the durable checkpoint, replay a bounded slice, and report.
The order is the whole of the resumability guarantee. The checkpoint is READ first, from the store, so nothing in this process decides where to resume. The slice is then applied through process, which writes the state and the cursor describing it in ONE transaction (ADR-0027), so the call either advanced both or neither. Nothing is written here afterwards: there is no second durable value that a crash could leave disagreeing with the state.
Nothing is CLEARED on any branch, unlike the load path, and for the reason readOnlyStream gives: this generation owns neither the stream it reads nor the cursor of whatever else wrote into a namespace it can see. An absent or unreadable stream costs one idle call and the next one asks again.
Parameters ​
options? ​
maxEmissions? ​
number
Returns ​
Promise<RebuildReport>