import { DataSource } from "../storage.mjs"; import { Row, TenantCtx } from "@gscdump/contracts"; interface ParsedUrl { loc: string; lastmod?: string; } interface SitemapUrlRecord { feedpath: string; feedpathHash: string; urlHash: string; loc: string; lastmod?: string; firstSeenAt: number; lastSeenAt: number; removedAt?: number; } interface SitemapGenerationFeedManifest { feedpath: string; feedpathHash: string; baseKey: string; eventKey: string | null; membershipHash: string; payloadHash: string; urlCount: number; observedAt: number; } type SitemapLegacyImportEvidence = { _tag: 'none'; } | { _tag: 'metadata_only'; importedAt: number; recordCount: number; source: 'gsc_sitemaps'; }; interface SitemapSiteGenerationManifest { version: 1; generationId: string; observedAt: number; publishedAt: number; completeness: { _tag: 'complete'; }; membershipHistoryAvailableFrom: number | null; legacyImport: SitemapLegacyImportEvidence; previousGenerationId: string | null; previousManifestKey: string | null; eventKeys: string[]; feeds: Record; } interface SitemapStagedFeed { version: 1; generationId: string; observedAt: number; feed: SitemapGenerationFeedManifest; } type StageSitemapGenerationFeedResult = { _tag: 'staged'; generationId: string; feedpath: string; membershipChanged: boolean; payloadChanged: boolean; added: number; removed: number; updated: number; } | { _tag: 'invalid_feed'; reason: 'credentials' | 'empty' | 'invalid_url' | 'unsupported_protocol'; } | { _tag: 'invalid_generation'; reason: 'empty_id' | 'invalid_observed_at'; } | { _tag: 'conflict'; reason: 'stale_generation' | 'generation_reused'; }; interface CompleteSitemapTraversal { _tag: 'complete'; expectedFeedpaths: readonly string[]; } type FinalizeSitemapGenerationResult = { _tag: 'published'; generationId: string; observedAt: number; feedCount: number; } | { _tag: 'unchanged'; generationId: string; observedAt: number; feedCount: number; } | { _tag: 'incomplete'; missingFeedpaths: string[]; invalidFeedpaths: string[]; } | { _tag: 'conflict'; reason: 'stale_generation' | 'generation_reused' | 'publication_changed'; } | { _tag: 'invalid_generation'; reason: 'empty_id' | 'invalid_observed_at'; }; type SitemapGenerationReadResult = { _tag: 'available'; manifest: SitemapSiteGenerationManifest; } | { _tag: 'unavailable'; reason: 'no_generation' | 'generation_not_found'; }; interface IterateSitemapGenerationUrlsOptions { generationId?: string; feedpath?: string; } type IterateSitemapGenerationUrlsResult = { _tag: 'iterator'; generationId: string; observedAt: number; items: AsyncIterable; completeness: { _tag: 'complete'; }; membershipHistoryAvailableFrom: number | null; } | { _tag: 'invalid_request'; reason: 'invalid_feed'; } | { _tag: 'unavailable'; reason: 'no_generation' | 'generation_not_found'; }; interface ListSitemapGenerationUrlsOptions { generationId?: string; feedpath?: string; cursor?: string; limit?: number; } type ListSitemapGenerationUrlsResult = { _tag: 'page'; generationId: string; observedAt: number; items: SitemapUrlRecord[]; nextCursor: string | null; completeness: { _tag: 'complete'; }; membershipHistoryAvailableFrom: number | null; } | { _tag: 'invalid_request'; reason: 'invalid_limit' | 'invalid_cursor' | 'invalid_feed'; } | { _tag: 'unavailable'; reason: 'no_generation' | 'generation_not_found'; }; type SitemapMembershipEvidence = { _tag: 'present'; url: string; feedpath: string; lastmod: string | null; firstSeenAt: number; lastSeenAt: number; } | { _tag: 'absent'; url: string; observedAt: number; } | { _tag: 'unknown'; url: string; reason: 'no_generation' | 'generation_not_found'; }; type QuerySitemapGenerationMembershipResult = { _tag: 'result'; generationId: string; observedAt: number; evidence: SitemapMembershipEvidence[]; completeness: { _tag: 'complete'; }; membershipHistoryAvailableFrom: number | null; } | { _tag: 'unavailable'; reason: 'no_generation' | 'generation_not_found'; }; type RecordSitemapLegacyImportResult = { _tag: 'recorded'; evidence: Extract; } | { _tag: 'existing'; evidence: Extract; } | { _tag: 'invalid'; reason: 'invalid_imported_at' | 'invalid_record_count'; }; interface CompleteSitemapGeneration { _tag: 'complete'; id: string; observedAt: number; } interface SitemapMembershipEvent { feedpath: string; feedpathHash: string; urlHash: string; op: 'added' | 'removed' | 'updated'; loc: string; lastmod?: string; previousLastmod?: string; generationId: string; observedAt: number; sequence: number; projectsState: boolean; } interface DateRange { from?: string; to?: string; } interface SitemapReadStore { loadEvents: (ctx: TenantCtx, dateRange?: DateRange) => AsyncIterable; getSitemapGeneration: (ctx: TenantCtx, generationId?: string) => Promise; iterateSitemapGenerationUrls: (ctx: TenantCtx, opts?: IterateSitemapGenerationUrlsOptions) => Promise; listSitemapGenerationUrls: (ctx: TenantCtx, opts?: ListSitemapGenerationUrlsOptions) => Promise; querySitemapGenerationMembership: (ctx: TenantCtx, opts: { generationId?: string; urls: readonly string[]; }) => Promise; } interface SitemapStore extends SitemapReadStore { stageSitemapGenerationFeed: (ctx: TenantCtx, generation: CompleteSitemapGeneration, feedpath: string, urls: readonly ParsedUrl[]) => Promise; finalizeSitemapGeneration: (ctx: TenantCtx, generation: CompleteSitemapGeneration, traversal: CompleteSitemapTraversal) => Promise; abortSitemapGeneration: (ctx: TenantCtx, generation: CompleteSitemapGeneration) => Promise; recordSitemapLegacyImport: (ctx: TenantCtx, input: { importedAt: number; recordCount: number; }) => Promise; } interface CreateSitemapReadStoreOptions { dataSource: DataSource; } type SitemapMutation = (ctx: TenantCtx, effect: () => Promise) => Promise; interface CreateSitemapStoreOptions extends CreateSitemapReadStoreOptions { withMutation: SitemapMutation; now?: () => number; } export { CompleteSitemapGeneration, CompleteSitemapTraversal, CreateSitemapReadStoreOptions, CreateSitemapStoreOptions, DateRange, FinalizeSitemapGenerationResult, IterateSitemapGenerationUrlsOptions, IterateSitemapGenerationUrlsResult, ListSitemapGenerationUrlsOptions, ListSitemapGenerationUrlsResult, ParsedUrl, QuerySitemapGenerationMembershipResult, RecordSitemapLegacyImportResult, SitemapGenerationFeedManifest, SitemapGenerationReadResult, SitemapLegacyImportEvidence, SitemapMembershipEvent, SitemapMembershipEvidence, SitemapMutation, SitemapReadStore, SitemapSiteGenerationManifest, SitemapStagedFeed, SitemapStore, SitemapUrlRecord, StageSitemapGenerationFeedResult };