import { SmrtCollection, SmrtObject } from '@happyvertical/smrt-core'; import { DatabaseInterface } from '@happyvertical/sql'; export type ForgeDeliveryStatus = 'pending' | 'leased' | 'retry' | 'completed' | 'dead_letter'; /** * A provider-neutral observation emitted by a forge delivery adapter. * * `version` is a monotonically increasing provider/domain revision for one * `(projection, subjectKey)` pair. Projectors never infer issue semantics from * pull requests; applications choose both the projection and subject identity. */ export interface ForgeObservation { projection: string; subjectKey: string; version: number; value: T; } export interface ForgeProjectionContext { /** Transaction-scoped database. Projection writes must use this handle. */ db: DatabaseInterface; tenantId: string; deliveryId: string; } export interface ForgeProjector { /** * Normalize a provider delivery into a tracker-independent observation. * Return null when the delivery is intentionally ignored. */ observe(delivery: ForgeDelivery): Promise | null>; /** * Apply the observation. The callback and checkpoint/delivery updates share * one database transaction. */ project(observation: ForgeObservation, context: ForgeProjectionContext): Promise; } export type ForgeProjectionAuditEvent = { type: 'delivery.accepted' | 'delivery.duplicate'; tenantId: string; deliveryId: string; provider: string; } | { type: 'delivery.leased' | 'delivery.completed' | 'delivery.retry_scheduled' | 'delivery.dead_lettered' | 'delivery.replayed' | 'observation.stale'; tenantId: string; deliveryId: string; attempt: number; }; export type ForgeProjectionAuditHook = (event: ForgeProjectionAuditEvent) => void | Promise; export declare class ForgeDelivery extends SmrtObject { tenantId: string; provider: string; deliveryId: string; installationKey: string | null; repositoryKey: string | null; eventName: string; payload: Record; status: ForgeDeliveryStatus; attempts: number; maxAttempts: number; receivedAt: Date; nextAttemptAt: Date; leaseOwner: string | null; leaseToken: string | null; leaseExpiresAt: Date | null; lastError: string | null; completedAt: Date | null; replayCount: number; } export declare class ForgeProjectionCheckpoint extends SmrtObject { tenantId: string; projection: string; subjectKey: string; observationVersion: number; deliveryId: string; observedAt: Date; } export interface AcceptForgeDeliveryInput { provider: string; deliveryId: string; installationKey?: string | null; repositoryKey?: string | null; eventName: string; payload: Record; maxAttempts?: number; receivedAt?: Date; } export interface AcceptedForgeDelivery { delivery: ForgeDelivery; accepted: boolean; } export interface ClaimForgeDeliveryOptions { workerId: string; leaseMs: number; now?: Date; } /** * Durable provider delivery inbox. * * All tenant-facing operations require ambient tenant context. `claimReady` * is the sole cross-tenant worker scan and returns the captured tenant so the * runtime can restore it before normalization or projection. */ export declare class ForgeDeliveryCollection extends SmrtCollection { static readonly _itemClass: typeof ForgeDelivery; accept(input: AcceptForgeDeliveryInput, audit?: ForgeProjectionAuditHook): Promise; claimReady(options: ClaimForgeDeliveryOptions, audit?: ForgeProjectionAuditHook): Promise; replay(id: string, audit?: ForgeProjectionAuditHook): Promise; } export interface ForgeProjectionRuntimeOptions { db: DatabaseInterface; workerId: string; leaseMs?: number; retryBaseMs?: number; retryMaxMs?: number; audit?: ForgeProjectionAuditHook; } /** * Claims and projects one delivery at a time. * * The ownership assertion, application projection, monotonic checkpoint and * inbox completion are one transaction. The initial no-op UPDATE takes a row * write lock, preventing an expired lease from being reclaimed while a valid * projection transaction is still in progress. */ export declare class ForgeProjectionRuntime { readonly db: DatabaseInterface; readonly workerId: string; readonly leaseMs: number; readonly retryBaseMs: number; readonly retryMaxMs: number; readonly audit?: ForgeProjectionAuditHook; constructor(options: ForgeProjectionRuntimeOptions); processNext(projector: ForgeProjector, options?: { now?: Date; }): Promise; private commitOwned; private failOwned; } //# sourceMappingURL=forge-projection.d.ts.map