@gscdump/engine 1.4.2 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { DataSource, StorageEngine } from "../storage.mjs";
2
2
  import { SearchType } from "gscdump/query";
3
- import { Row, TableName } from "@gscdump/contracts";
3
+ import { Row, TableName, TenantCtx } from "@gscdump/contracts";
4
4
  interface NodeHarnessOptions {
5
5
  dataDir: string;
6
6
  /** Tenant user id. Defaults to `'local'` for single-user CLI installs. */
@@ -18,6 +18,7 @@ interface NodeHarness {
18
18
  dataDir: string;
19
19
  userId: string;
20
20
  siteIdFor: (siteUrl: string) => string;
21
+ withSitemapMutation: <T>(ctx: TenantCtx, mutate: () => Promise<T>) => Promise<T>;
21
22
  runRawSql: (opts: {
22
23
  sql: string;
23
24
  siteUrl: string;
@@ -11,9 +11,10 @@ function createNodeHarness(opts) {
11
11
  const handle = createNodeDuckDBHandle();
12
12
  const factory = { getDuckDB: async () => handle };
13
13
  const dataSource = createFilesystemDataSource({ rootDir: dataDir });
14
+ const manifestStore = createFilesystemManifestStore({ path: path.join(dataDir, manifestFilename) });
14
15
  const engine = createStorageEngine({
15
16
  dataSource,
16
- manifestStore: createFilesystemManifestStore({ path: path.join(dataDir, manifestFilename) }),
17
+ manifestStore,
17
18
  codec: createDuckDBCodec(factory),
18
19
  executor: createDuckDBExecutor(factory)
19
20
  });
@@ -41,6 +42,16 @@ function createNodeHarness(opts) {
41
42
  dataDir,
42
43
  userId,
43
44
  siteIdFor: encodeSiteId,
45
+ withSitemapMutation(ctx, mutate) {
46
+ if (ctx.userId !== userId) throw new Error(`Sitemap mutation user scope mismatch: expected ${userId}, got ${ctx.userId}`);
47
+ if (!ctx.siteId) throw new Error("Sitemap mutation requires a site id");
48
+ return manifestStore.withLock({
49
+ userId,
50
+ siteId: ctx.siteId,
51
+ table: "pages",
52
+ partition: "__sitemap_entities__"
53
+ }, mutate);
54
+ },
44
55
  runRawSql
45
56
  };
46
57
  }
@@ -79,7 +79,7 @@ declare const pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
79
79
  generated: undefined;
80
80
  }>;
81
81
  };
82
- dialect: 'pg';
82
+ dialect: "pg";
83
83
  }>;
84
84
  declare const queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
85
85
  name: "queries";
@@ -161,7 +161,7 @@ declare const queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
161
161
  generated: undefined;
162
162
  }>;
163
163
  };
164
- dialect: 'pg';
164
+ dialect: "pg";
165
165
  }>;
166
166
  declare const countries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
167
167
  name: "countries";
@@ -243,7 +243,7 @@ declare const countries: import("drizzle-orm/pg-core/table").PgTableWithColumns<
243
243
  generated: undefined;
244
244
  }>;
245
245
  };
246
- dialect: 'pg';
246
+ dialect: "pg";
247
247
  }>;
248
248
  declare const page_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
249
249
  name: "page_queries";
@@ -340,7 +340,7 @@ declare const page_queries: import("drizzle-orm/pg-core/table").PgTableWithColum
340
340
  generated: undefined;
341
341
  }>;
342
342
  };
343
- dialect: 'pg';
343
+ dialect: "pg";
344
344
  }>;
345
345
  /**
346
346
  * Per-`(site, search_type, date)` daily totals + device breakdown.
@@ -573,7 +573,7 @@ declare const dates: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
573
573
  generated: undefined;
574
574
  }>;
575
575
  };
576
- dialect: 'pg';
576
+ dialect: "pg";
577
577
  }>;
578
578
  declare const search_appearance: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
579
579
  name: "search_appearance";
@@ -655,7 +655,7 @@ declare const search_appearance: import("drizzle-orm/pg-core/table").PgTableWith
655
655
  generated: undefined;
656
656
  }>;
657
657
  };
658
- dialect: 'pg';
658
+ dialect: "pg";
659
659
  }>;
660
660
  declare const search_appearance_pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
661
661
  name: "search_appearance_pages";
@@ -752,7 +752,7 @@ declare const search_appearance_pages: import("drizzle-orm/pg-core/table").PgTab
752
752
  generated: undefined;
753
753
  }>;
754
754
  };
755
- dialect: 'pg';
755
+ dialect: "pg";
756
756
  }>;
757
757
  declare const search_appearance_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
758
758
  name: "search_appearance_queries";
@@ -849,7 +849,7 @@ declare const search_appearance_queries: import("drizzle-orm/pg-core/table").PgT
849
849
  generated: undefined;
850
850
  }>;
851
851
  };
852
- dialect: 'pg';
852
+ dialect: "pg";
853
853
  }>;
854
854
  declare const search_appearance_page_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
855
855
  name: "search_appearance_page_queries";
@@ -961,7 +961,7 @@ declare const search_appearance_page_queries: import("drizzle-orm/pg-core/table"
961
961
  generated: undefined;
962
962
  }>;
963
963
  };
964
- dialect: 'pg';
964
+ dialect: "pg";
965
965
  }>;
966
966
  declare const hourly_pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
967
967
  name: "hourly_pages";
@@ -1058,7 +1058,7 @@ declare const hourly_pages: import("drizzle-orm/pg-core/table").PgTableWithColum
1058
1058
  generated: undefined;
1059
1059
  }>;
1060
1060
  };
1061
- dialect: 'pg';
1061
+ dialect: "pg";
1062
1062
  }>;
1063
1063
  declare const drizzleSchema: {
1064
1064
  pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
@@ -1141,7 +1141,7 @@ declare const drizzleSchema: {
1141
1141
  generated: undefined;
1142
1142
  }>;
1143
1143
  };
1144
- dialect: 'pg';
1144
+ dialect: "pg";
1145
1145
  }>;
1146
1146
  queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1147
1147
  name: "queries";
@@ -1223,7 +1223,7 @@ declare const drizzleSchema: {
1223
1223
  generated: undefined;
1224
1224
  }>;
1225
1225
  };
1226
- dialect: 'pg';
1226
+ dialect: "pg";
1227
1227
  }>;
1228
1228
  countries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1229
1229
  name: "countries";
@@ -1305,7 +1305,7 @@ declare const drizzleSchema: {
1305
1305
  generated: undefined;
1306
1306
  }>;
1307
1307
  };
1308
- dialect: 'pg';
1308
+ dialect: "pg";
1309
1309
  }>;
1310
1310
  page_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1311
1311
  name: "page_queries";
@@ -1402,7 +1402,7 @@ declare const drizzleSchema: {
1402
1402
  generated: undefined;
1403
1403
  }>;
1404
1404
  };
1405
- dialect: 'pg';
1405
+ dialect: "pg";
1406
1406
  }>;
1407
1407
  dates: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1408
1408
  name: "dates";
@@ -1619,7 +1619,7 @@ declare const drizzleSchema: {
1619
1619
  generated: undefined;
1620
1620
  }>;
1621
1621
  };
1622
- dialect: 'pg';
1622
+ dialect: "pg";
1623
1623
  }>;
1624
1624
  search_appearance: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1625
1625
  name: "search_appearance";
@@ -1701,7 +1701,7 @@ declare const drizzleSchema: {
1701
1701
  generated: undefined;
1702
1702
  }>;
1703
1703
  };
1704
- dialect: 'pg';
1704
+ dialect: "pg";
1705
1705
  }>;
1706
1706
  search_appearance_pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1707
1707
  name: "search_appearance_pages";
@@ -1798,7 +1798,7 @@ declare const drizzleSchema: {
1798
1798
  generated: undefined;
1799
1799
  }>;
1800
1800
  };
1801
- dialect: 'pg';
1801
+ dialect: "pg";
1802
1802
  }>;
1803
1803
  search_appearance_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1804
1804
  name: "search_appearance_queries";
@@ -1895,7 +1895,7 @@ declare const drizzleSchema: {
1895
1895
  generated: undefined;
1896
1896
  }>;
1897
1897
  };
1898
- dialect: 'pg';
1898
+ dialect: "pg";
1899
1899
  }>;
1900
1900
  search_appearance_page_queries: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
1901
1901
  name: "search_appearance_page_queries";
@@ -2007,7 +2007,7 @@ declare const drizzleSchema: {
2007
2007
  generated: undefined;
2008
2008
  }>;
2009
2009
  };
2010
- dialect: 'pg';
2010
+ dialect: "pg";
2011
2011
  }>;
2012
2012
  hourly_pages: import("drizzle-orm/pg-core/table").PgTableWithColumns<{
2013
2013
  name: "hourly_pages";
@@ -2104,7 +2104,7 @@ declare const drizzleSchema: {
2104
2104
  generated: undefined;
2105
2105
  }>;
2106
2106
  };
2107
- dialect: 'pg';
2107
+ dialect: "pg";
2108
2108
  }>;
2109
2109
  };
2110
2110
  type DrizzleSchema = typeof drizzleSchema;
@@ -1,6 +1,7 @@
1
1
  import { DataSource } from "./storage.mjs";
2
2
  import { ScheduleState } from "./schedule.mjs";
3
- import { emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPrefix } from "./entity-keys.mjs";
3
+ import { SitemapGenerationKey, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, parseSitemapUrlsDeltaKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsEventKey, sitemapUrlsEventSeedKey, sitemapUrlsEventsPrefix, sitemapUrlsGenerationKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPendingGenerationKey, sitemapUrlsPendingGenerationsPrefix, sitemapUrlsPrefix, sitemapUrlsProjectionManifestKey, sitemapUrlsReconcileGenerationKey } from "./entity-keys.mjs";
4
+ import { SITEMAP_PROJECTION_GRACE_MS, SitemapProjectionFeed, SitemapProjectionFiles, SitemapProjectionManifest, decodeSitemapProjectionManifest, emptySitemapProjectionManifest, parseSitemapProjectionManifest, selectSitemapProjectionFiles, withSitemapProjectionFeed } from "./sitemap-projection.mjs";
4
5
  import { QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, buildQueryDimRecords, createQueryDimStore } from "./query-dim.mjs";
5
6
  import { TenantCtx } from "@gscdump/contracts";
6
7
  /**
@@ -284,9 +285,15 @@ interface SnapshotUrlsResult {
284
285
  removed: number;
285
286
  kept: number;
286
287
  contentHash: string;
287
- /** True when contentHash matched prior; the call performed zero writes. */
288
+ /** True when current membership did not change. Initial history seeding may write. */
288
289
  unchanged: boolean;
289
290
  }
291
+ interface CompleteSitemapGeneration {
292
+ _tag: 'complete';
293
+ id: string;
294
+ /** Unix epoch milliseconds. */
295
+ observedAt: number;
296
+ }
290
297
  interface ReconcileResult {
291
298
  /** Feedpaths that were absent from the live set and had their live URLs pruned. */
292
299
  feedpathsPruned: number;
@@ -307,12 +314,12 @@ interface CompactUrlsOptions {
307
314
  maxFeedpaths?: number;
308
315
  }
309
316
  interface CompactUrlsResult {
310
- /** Feedpaths whose deltas were folded and deleted by this call. */
317
+ /** Feedpaths whose active deltas were folded and retired by this call. */
311
318
  compactedFeedpaths: number;
312
319
  /**
313
320
  * Feedpaths that still hold outstanding deltas. Call `compactUrls` again to
314
- * continue no cursor is needed, because a compacted feedpath's deltas are
315
- * deleted, so the next call simply doesn't see it.
321
+ * continue. No cursor is needed because the projection watermark excludes a
322
+ * compacted feedpath's grace-retained deltas from the next call.
316
323
  */
317
324
  remainingFeedpaths: number;
318
325
  }
@@ -325,6 +332,21 @@ interface DeltaEntry {
325
332
  lastmod?: string;
326
333
  at: number;
327
334
  }
335
+ interface SitemapMembershipEvent {
336
+ feedpath: string;
337
+ feedpathHash: string;
338
+ urlHash: string;
339
+ op: 'added' | 'removed';
340
+ loc: string;
341
+ lastmod?: string;
342
+ generationId: string;
343
+ /** Unix epoch milliseconds. */
344
+ observedAt: number;
345
+ /** Stable ordering within one generation. */
346
+ sequence: number;
347
+ /** Whether this row also mutates the disposable current-state projection. */
348
+ projectsState: boolean;
349
+ }
328
350
  interface DateRange {
329
351
  /** YYYY-MM-DD inclusive. */
330
352
  from?: string;
@@ -334,27 +356,29 @@ interface DateRange {
334
356
  interface LoadUrlsOptions {
335
357
  includeRemoved?: boolean;
336
358
  }
337
- interface SitemapStore {
338
- /**
339
- * Persist a snapshot run. Updates the index + writes one immutable
340
- * history doc per record under `history/<feedpathHash>__<capturedAtMs>.json`.
341
- */
342
- writeSnapshot: (ctx: TenantCtx, records: readonly SitemapRecord[]) => Promise<void>;
359
+ interface SitemapReadStore {
343
360
  /** Load the full site index (latest record per feedpath). */
344
361
  loadIndex: (ctx: TenantCtx) => Promise<SitemapIndex>;
345
362
  /** Fetch the latest snapshot for a feedpath, or undefined. */
346
363
  getLatest: (ctx: TenantCtx, path: string) => Promise<SitemapRecord | undefined>;
347
- /**
348
- * Diff incoming URLs against the prior `urls/index.parquet` partition for
349
- * `feedpath`; on change, writes a single delta parquet under
350
- * `urls/deltas/YYYY-MM-DD__{feedpathHash}.parquet`. Skipped (0 PUTs) when
351
- * `contentHash` matches prior.
352
- */
353
- snapshotUrls: (ctx: TenantCtx, feedpath: string, urls: readonly ParsedUrl[]) => Promise<SnapshotUrlsResult>;
354
364
  /** Stream live (and optionally removed) URL rows for a feedpath. */
355
365
  loadUrls: (ctx: TenantCtx, feedpath: string, opts?: LoadUrlsOptions) => AsyncIterable<SitemapUrlRecord>;
356
366
  /** Stream all delta entries within `[from, to]` (YYYY-MM-DD inclusive). */
357
367
  loadDeltas: (ctx: TenantCtx, dateRange?: DateRange) => AsyncIterable<DeltaEntry>;
368
+ /** Stream immutable membership events within `[from, to]`. */
369
+ loadEvents: (ctx: TenantCtx, dateRange?: DateRange) => AsyncIterable<SitemapMembershipEvent>;
370
+ }
371
+ interface SitemapStore extends SitemapReadStore {
372
+ /**
373
+ * Persist a snapshot run. Updates the index + writes one immutable
374
+ * history doc per record under `history/<feedpathHash>__<capturedAtMs>.json`.
375
+ */
376
+ writeSnapshot: (ctx: TenantCtx, records: readonly SitemapRecord[]) => Promise<void>;
377
+ /**
378
+ * Diff a complete sitemap generation against current state. The immutable
379
+ * membership event lands before its disposable state delta.
380
+ */
381
+ snapshotUrls: (ctx: TenantCtx, generation: CompleteSitemapGeneration, feedpath: string, urls: readonly ParsedUrl[]) => Promise<SnapshotUrlsResult>;
358
382
  /**
359
383
  * Fold accumulated deltas into the prior index, one feedpath at a time:
360
384
  * rewrites each touched feedpath's `by-feed/<hash>/index.parquet` and deletes
@@ -362,9 +386,9 @@ interface SitemapStore {
362
386
  * regardless of total site URL count.
363
387
  *
364
388
  * Optionally bounded in TIME too (`opts.deadlineMs` / `opts.maxFeedpaths`).
365
- * A bounded call is safe to stop mid-way: each feedpath's deltas are deleted
366
- * as soon as its index is rewritten, so the remainder is simply what the next
367
- * call finds. Callers drive this from `remainingFeedpaths`, not a cursor.
389
+ * A bounded call is safe to stop mid-way: each rewritten feedpath advances
390
+ * the projection watermark, so the remainder is simply what the next call
391
+ * finds. Callers drive this from `remainingFeedpaths`, not a cursor.
368
392
  */
369
393
  compactUrls: (ctx: TenantCtx, opts?: CompactUrlsOptions) => Promise<CompactUrlsResult>;
370
394
  /**
@@ -373,22 +397,26 @@ interface SitemapStore {
373
397
  * prune URLs *inside* a feedpath that was re-observed; a whole feed dropped
374
398
  * from the sitemap list (no `snapshotUrls` call) leaves its URLs frozen-live
375
399
  * forever. This is the sidecar mirror of the D1 generation sweep: it rewrites
376
- * each dropped feedpath's `by-feed/<hash>/index.parquet` with `removedAt` set
377
- * and deletes its outstanding deltas (write-new-base + delete-deltas,
378
- * ADR-0002). Bounded per feedpath, so memory stays flat regardless of site
379
- * size. Live feedpaths are never touched.
400
+ * each dropped feedpath's `by-feed/<hash>/index.parquet` with `removedAt` set,
401
+ * advances its projection watermark, and grace-retires outstanding deltas.
402
+ * Bounded per feedpath, so memory stays flat regardless of site size. Live
403
+ * feedpaths are never touched.
380
404
  */
381
- reconcile: (ctx: TenantCtx, opts: {
405
+ reconcile: (ctx: TenantCtx, generation: CompleteSitemapGeneration, opts: {
382
406
  liveFeedpaths: readonly string[];
383
- at?: number;
384
407
  }) => Promise<ReconcileResult>;
385
408
  }
386
- interface CreateSitemapStoreOptions {
409
+ interface CreateSitemapReadStoreOptions {
387
410
  dataSource: DataSource;
388
411
  /** Override the feedpath hash (test seam). */
389
412
  hash?: (path: string) => string;
413
+ }
414
+ type SitemapMutation = <T>(ctx: TenantCtx, fn: () => Promise<T>) => Promise<T>;
415
+ interface CreateSitemapStoreOptions extends CreateSitemapReadStoreOptions {
416
+ withMutation: SitemapMutation;
390
417
  now?: () => number;
391
418
  }
419
+ declare function createSitemapReadStore(opts: CreateSitemapReadStoreOptions): SitemapReadStore;
392
420
  declare function createSitemapStore(opts: CreateSitemapStoreOptions): SitemapStore;
393
421
  interface IndexingMetadataRecord {
394
422
  url: string;
@@ -432,4 +460,4 @@ interface CreateEmptyTypesStoreOptions {
432
460
  now?: () => number;
433
461
  }
434
462
  declare function createEmptyTypesStore(opts: CreateEmptyTypesStoreOptions): EmptyTypesStore;
435
- export { CompactUrlsOptions, CompactUrlsResult, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SitemapHistoryDoc, SitemapIndex, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapStore, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, queryDimMetaKey, queryDimParquetKey, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPrefix };
463
+ export { CompactUrlsOptions, CompactUrlsResult, CompleteSitemapGeneration, CreateEmptyTypesStoreOptions, CreateIndexingMetadataStoreOptions, CreateInspectionStoreOptions, CreateSitemapReadStoreOptions, CreateSitemapStoreOptions, DateRange, DeltaEntry, EmptyTypesDoc, EmptyTypesStore, INSPECTION_HISTORY_MAX_BYTES, IndexingMetadataIndex, IndexingMetadataRecord, IndexingMetadataStore, InspectionEventRow, InspectionHistoryShard, InspectionIndex, InspectionParquetRow, InspectionRecord, InspectionStore, LoadUrlsOptions, ParsedUrl, QueryDimDeps, QueryDimMeta, QueryDimRecord, QueryDimStore, ReconcileResult, SITEMAP_PROJECTION_GRACE_MS, SitemapGenerationKey, SitemapHistoryDoc, SitemapIndex, SitemapMembershipEvent, SitemapMutation, SitemapProjectionFeed, SitemapProjectionFiles, SitemapProjectionManifest, SitemapReadStore, SitemapRecord, SitemapStore, SitemapUrlRecord, SnapshotUrlsResult, buildQueryDimRecords, createEmptyTypesStore, createIndexingMetadataStore, createInspectionStore, createQueryDimStore, createSitemapReadStore, createSitemapStore, decodeSitemapProjectionManifest, emptySitemapProjectionManifest, emptyTypesKey, hashSortedUrlList, hashUrl, hashUrlList, indexingMetadataIndexKey, inspectionBaseKey, inspectionEventKey, inspectionEventsPrefix, inspectionHistoryPrefix, inspectionHistoryShardKey, inspectionIndexKey, inspectionParquetKey, parseSitemapProjectionManifest, parseSitemapUrlsDeltaKey, queryDimMetaKey, queryDimParquetKey, selectSitemapProjectionFiles, sitemapHistoryKey, sitemapIndexKey, sitemapUrlsDeltaKey, sitemapUrlsEventKey, sitemapUrlsEventSeedKey, sitemapUrlsEventsPrefix, sitemapUrlsGenerationKey, sitemapUrlsIndexKey, sitemapUrlsIndexPrefix, sitemapUrlsPendingGenerationKey, sitemapUrlsPendingGenerationsPrefix, sitemapUrlsPrefix, sitemapUrlsProjectionManifestKey, sitemapUrlsReconcileGenerationKey, withSitemapProjectionFeed };