import { isCurrentCheckpointSchema } from "../state/checkpointHelpers.js";
export default class MaterializeLiveStrategy {
    runtime;
    constructor(runtime) {
        this.runtime = runtime;
    }
    async materialize(opts) {
        const checkpoint = await this.runtime.deps.patches.loadCheckpoint();
        if (checkpoint !== null && checkpoint !== undefined && isCurrentCheckpointSchema(checkpoint.schema)) {
            return await this.fromCheckpoint(checkpoint, opts);
        }
        return await this.fromScratch(opts);
    }
    async fromCheckpoint(checkpoint, opts) {
        const reduction = await this.runtime.reducePatchStream(this.streamPatchesSince(checkpoint), checkpoint.state, opts, checkpoint.provenanceIndex);
        return await this.runtime.buildResult({
            reduced: reduction.reduced,
            summary: reduction.summary,
            degraded: false,
            ceiling: null,
            frontier: null,
        });
    }
    async *streamPatchesSince(checkpoint) {
        if (typeof this.runtime.deps.patches.streamPatchesSince === 'function') {
            yield* this.runtime.deps.patches.streamPatchesSince(checkpoint);
            return;
        }
        for (const entry of await this.runtime.deps.patches.loadPatchesSince(checkpoint)) {
            yield entry;
        }
    }
    async fromScratch(opts) {
        const writers = await this.runtime.deps.patches.discoverWriters();
        if (writers.length === 0) {
            return await this.runtime.emptyResult();
        }
        const reduction = await this.runtime.reducePatchStream(this.streamAllPatches(writers), undefined, opts);
        if (reduction.summary.patchCount === 0) {
            return await this.runtime.emptyResult();
        }
        return await this.runtime.buildResult({
            reduced: reduction.reduced,
            summary: reduction.summary,
            degraded: false,
            ceiling: null,
            frontier: null,
        });
    }
    async *streamAllPatches(writers) {
        for (const writerId of writers) {
            yield* this.runtime.deps.patches.streamWriterPatches(writerId);
        }
    }
}
