import { SearchType, TenantCtx as TenantCtx$1 } from "./storage.mjs"; import { GscApiRow, RowAccumulatorOptions } from "./ingest.mjs"; import { Grain, Row, TableName } from "@gscdump/contracts"; interface IngestAccumulatorEngine { writeDay: (scope: TenantCtx$1 & { table: TableName; date: string; searchType?: SearchType; }, rows: Row[]) => Promise; /** * Routed when the accumulator's `ctx.grain === 'hour'`. Same scope shape as * `writeDay`; `date` is the PT calendar day, rows carry `hour` + `date`. * Optional so hosts that never opt into hourly need not implement it. */ writeHour?: (scope: TenantCtx$1 & { table: TableName; date: string; searchType?: SearchType; }, rows: Row[]) => Promise; setSyncState: (scope: TenantCtx$1 & { table: TableName; date: string; searchType?: SearchType; }, state: 'done' | 'failed', info?: { error?: string; }) => Promise; } interface IngestAccumulatorCtx { userId: string | number; siteId: string; searchType?: SearchType; /** * Temporal granularity for this accumulator. `'day'` (default) routes * flushed buckets to `engine.writeDay`. `'hour'` routes to * `engine.writeHour` and requires the engine implementation to be set. */ grain?: Grain; } interface IngestAccumulatorHooks { /** * Called once per (table, date) when the job must abandon in-memory rows * (overflow or `hasMore` continuation). Host queues a forced re-sync from * the source. Return true iff a recovery job was actually queued. */ onRecover: (table: TableName, date: string) => Promise; /** * Called when an engine.writeDay fails or recovery itself errors. Host * logs to its error sink (e.g. `r2_write_errors` D1 table). */ onWriteError: (info: { table: TableName | null; date: string | null; error: unknown; }) => Promise; /** * Called after a successful writeDay for a (table, date). Host typically * busts the manifest cache here so the next read sees the new parquet. */ onWritten?: (info: { table: TableName; date: string; rowCount: number; }) => void | Promise; /** * Called once at end of `finalize`, only when at least one (table, date) * actually landed. Host queues rollup rebuild + compaction. */ onJobComplete?: (info: { flushed: number; rowsWritten: number; }) => Promise; } interface FinalizeOptions { /** * The GSC `hasMore` flag for the whole job. When true, in-memory buckets * only reflect this job's slice; we re-queue forced single-day re-syncs * via `onRecover` so R2 stays authoritative. */ hasMore: boolean; } interface FinalizeResult { flushed: number; recovered: number; failed: number; rowsWritten: number; } interface IngestAccumulator { push: (table: TableName, rows: readonly GscApiRow[]) => boolean; finalize: (opts: FinalizeOptions) => Promise; } interface CreateIngestAccumulatorOptions extends RowAccumulatorOptions { engine: IngestAccumulatorEngine; ctx: IngestAccumulatorCtx; hooks: IngestAccumulatorHooks; } declare function createIngestAccumulator(opts: CreateIngestAccumulatorOptions): IngestAccumulator; export { CreateIngestAccumulatorOptions, FinalizeOptions, FinalizeResult, IngestAccumulator, IngestAccumulatorCtx, IngestAccumulatorEngine, IngestAccumulatorHooks, createIngestAccumulator };