/** * Full sync provider over the Google Sheets REST API. * * Implements every provider capability the sync runtime needs with ONE * provider instance (one transport, separate read and write request-start * limiters, one telemetry sink): the outbound effect worker (fast append, applyEffects, * postcondition recovery), projection provisioning, values-only table reads, * row-anchor assignment, and full metadata snapshots. The service-account * bootstrap mode uses this provider exclusively and needs no Apps Script. * * Delivery semantics are ported from the Apps Script operations: bulk * preflight with fail-closed validation, receipt replay/idempotency, * visible/candidate/repair compare-and-set guards, full-row deletion guards, * one atomic `spreadsheets.batchUpdate` per target+receipt batch, * response-loss recovery through receipt-backed postcondition reads, * exact-match provisioning, and snapshot wire shapes that are byte-compatible * with the Apps Script observation source. The provider never exposes * credential material or raw Google SDK responses; telemetry carries only * operation names, counts, durations, and stable codes. * * Request pacing is per transport call: every `getSpreadsheet` (preflight * enumeration, preflight data, observation reads, post-reads, table reads, * provisioning reads) and every `batchUpdate` acquires a request-start limiter * and emits one redacted telemetry event. Reads serialize only against reads; * writes only against writes, so a read and a write can start concurrently * (an idempotent get + a committed batchUpdate are safe to overlap) while * same-class bursts can never outpace the interval. Admission is bounded * SEPARATELY by an independent maximum admission wait * (`requestStartMaxWaitMs`, default 5,000 ms — not derived from the * interval): a request whose PREDICTED WAIT for a slot exceeds that bound * is refused before any SDK call with the stable delivery-uncertain * `google_sheets_api_request_start_refused` error, so an arbitrarily long * limiter queue can never make a request wait past its effect lease — the * durable worker requeues instead. */ import type { ApplySyncEffectsRequest, ApplySyncEffectsResult, EnsureSyncRowAnchorsRequest, EnsureSyncRowAnchorsResult, FastAppendRowsRequest, FastAppendRowsResult, ReadSyncEffectPostconditionsRequest, ReadSyncRowChecksRequest, ReadSyncSnapshotRequest, ReadSyncTableRowsRequest, PreparedApplyEffects, SyncEffectPostcondition, SyncEffectPostconditionResult, SyncEffectWorkerProvider, SyncObservedSnapshot, SyncRowChecksResult, SyncSheetsObservationBatchProvider, SyncSheetsObservationProvider, SyncSheetsRowChecksReader, SyncSheetsSnapshot, SyncSheetsTableReader, SyncProjectionEffect, SyncTableRowsResult } from "../../../contracts/sheets/syncSheets.js"; import type { RegisteredSyncProjectionDefinition, SyncSheetsProvisioner, SyncSheetsProvisionRoute } from "../../../contracts/sheets/sheetsProvisioning.js"; export type { GoogleSheetsApiRequestEvent, GoogleSheetsApiProviderOptions, } from "../../../contracts/sheets/googleSheetsApi.js"; import type { GoogleSheetsApiProviderOptions } from "../../../contracts/sheets/googleSheetsApi.js"; /** Full construction options (bootstrap supplies spreadsheet and routes). */ export interface GoogleSheetsApiSyncProviderOptions extends GoogleSheetsApiProviderOptions { readonly spreadsheetId: string; readonly definitions: readonly RegisteredSyncProjectionDefinition[]; } /** * Full sync provider over the Sheets REST API: outbound effects, provisioning, * table reads, anchors, and snapshots behind the shared provider contracts. * * All reads share ONE request-start timeline (a read QoS scheduler with * weighted polling/preflight fairness) and all writes share ONE write * request-start limiter, so reads serialize only against reads and writes * only against writes (an idempotent read and a committed write may start * concurrently); the worker-level append throttle stays enabled on * top in service mode via the bootstrap's bulk worker options. Provisioning * runs at startup before the worker, and observation anchors are the only * metadata mutations outside effect batches. * * The class is a thin facade: every method body lives in an operation module * under `operations/` and receives the immutable wiring from `this.deps`. */ export declare class GoogleSheetsApiSyncProvider implements SyncEffectWorkerProvider, SyncSheetsObservationProvider, SyncSheetsObservationBatchProvider, SyncSheetsTableReader, SyncSheetsRowChecksReader, SyncSheetsProvisioner { private readonly spreadsheetId; private readonly definitions; private readonly transport; private readonly transportTimeoutMs; private readonly readTimeoutMs; private readonly maxBatchBytes; private readonly readScheduler; private readonly writeLimiter; private readonly readBudget; private readonly writeBudget; private readonly quotaGovernor; /** Single quota/backoff marker object shared by governors and outcome checks. */ private readonly timingDefaults; /** Bounded admission: independent max request-start wait (default 5,000 * ms), separate from the pacing interval. */ private readonly maxRequestStartWaitMs; private readonly now; private readonly onRequest; /** Per-identity pacing pool (2+ credentials only); undefined single-slot. */ private readonly credentialPacing; private readonly deps; constructor(options: GoogleSheetsApiSyncProviderOptions); /** Exposes the configured outbound timeout (used by lease-headroom checks). */ get timeoutMs(): number; /** Appends rows through one idempotent, atomic target+receipt batch. */ fastAppendRows(request: FastAppendRowsRequest): Promise; /** Applies regular update/delete/create effects through one atomic batch. */ applyEffects(request: ApplySyncEffectsRequest): Promise; /** Read+plan stage of one apply request; never mutates the sheet. */ preflightApplyEffects(request: ApplySyncEffectsRequest): Promise; /** Write+verify stage that consumes preflight prepared state. */ applyPreparedEffects(prepared: PreparedApplyEffects): Promise; /** Classifies one response-loss effect through a fresh target+receipt read. */ readEffectPostcondition(effect: SyncProjectionEffect): Promise; /** Classifies a recovery batch with one shared target+receipt read. */ readEffectPostconditions(request: ReadSyncEffectPostconditionsRequest): Promise; /** * Creates missing tabs and their header rows, or verifies existing tabs, * in ONE atomic batchUpdate. An existing tab with no content anywhere in * its used grid gets its headers initialized; an existing tab with content * must match the registered headers exactly (order, duplicates, width), * otherwise provisioning fails closed BEFORE any mutation. The operation * is idempotent: a retry after a lost response re-enumerates, sees the * exact headers, and succeeds without rewriting anything. */ provisionRegistry(registrations: readonly SyncSheetsProvisionRoute[]): Promise<{ readonly registrations: readonly Omit[]; readonly createdSheets: readonly string[]; readonly initializedHeaders: readonly string[]; }>; /** Reads one registered table's literal values with one REST read. */ readRows(request: ReadSyncTableRowsRequest): Promise; /** * Reads several registered tables through ONE `spreadsheets.get` call. * Results are returned in request order; a missing tab, header drift, or * malformed payload fails closed before any result is produced. */ readRowsBatch(requests: readonly ReadSyncTableRowsRequest[]): Promise; /** * Reads ONLY the identity + anchor + row-check column bands of several * User_Input tabs through ONE narrow `spreadsheets.get` (the check-column * polling gate). Lock-free like every value read; a tab without the provisioned * check header answers `checks_unavailable` so polling falls back to the * historical whole-table observation (mixed mode). */ readRowChecksBatch(requests: readonly ReadSyncRowChecksRequest[]): Promise; /** * Ensures every nonblank row of one registered tab carries a * developer-metadata anchor, writing all planned anchors in ONE atomic * batchUpdate. Rows with more than one anchor fail closed; duplicate * anchors across rows are reported as evidence. No re-read is performed. */ ensureRowAnchors(request: EnsureSyncRowAnchorsRequest): Promise; /** Reads one full snapshot without any mutation (lock-free). */ readSnapshot(request: ReadSyncSnapshotRequest): Promise; /** Combines anchor assignment and one snapshot read under one request. */ observeSnapshot(request: ReadSyncSnapshotRequest): Promise; /** * Observes several projections with ONE grid read, ONE anchor write (when * any anchor is missing), and ONE re-read (when anchors were written), so * the committed anchors are reflected in every snapshot. The coordinator * already holds every involved mutation lane before this call. */ observeSnapshots(requests: readonly ReadSyncSnapshotRequest[]): Promise; } //# sourceMappingURL=GoogleSheetsApiSyncProvider.d.ts.map