@beesolve/analytics-processor 0.3.0 → 0.5.0

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.
Files changed (75) hide show
  1. package/DOCS.md +23 -3
  2. package/dist/cdk.js +46 -0
  3. package/dist/dailyRollup/dailyRollup.mjs.map +2 -2
  4. package/dist/hourly/hourly.mjs +3 -3
  5. package/dist/hourly/hourly.mjs.map +3 -3
  6. package/dist/index.d.ts +273 -11
  7. package/dist/index.js +579 -67
  8. package/dist/monthlyRollup/monthlyRollup.mjs.map +2 -2
  9. package/dist/sitemap/bowser-UJEXXM6S.mjs +2 -0
  10. package/dist/sitemap/bowser-UJEXXM6S.mjs.map +7 -0
  11. package/dist/sitemap/chunk-3UGRDNDZ.mjs +6 -0
  12. package/dist/sitemap/chunk-3UGRDNDZ.mjs.map +7 -0
  13. package/dist/sitemap/chunk-BH7ZEBAB.mjs +2 -0
  14. package/dist/sitemap/chunk-BH7ZEBAB.mjs.map +7 -0
  15. package/dist/sitemap/chunk-CFZ5JWD3.mjs +2 -0
  16. package/dist/sitemap/chunk-CFZ5JWD3.mjs.map +7 -0
  17. package/dist/sitemap/chunk-KRS5YV2Z.mjs +2 -0
  18. package/dist/sitemap/chunk-KRS5YV2Z.mjs.map +7 -0
  19. package/dist/sitemap/chunk-LB33VBGK.mjs +2 -0
  20. package/dist/sitemap/chunk-LB33VBGK.mjs.map +7 -0
  21. package/dist/sitemap/chunk-OC3UN3OS.mjs +2 -0
  22. package/dist/sitemap/chunk-OC3UN3OS.mjs.map +7 -0
  23. package/dist/sitemap/chunk-PD2XGJQD.mjs +10 -0
  24. package/dist/sitemap/chunk-PD2XGJQD.mjs.map +7 -0
  25. package/dist/sitemap/chunk-QPD5NJHJ.mjs +2 -0
  26. package/dist/sitemap/chunk-QPD5NJHJ.mjs.map +7 -0
  27. package/dist/sitemap/chunk-REMPUQ6B.mjs +19 -0
  28. package/dist/sitemap/chunk-REMPUQ6B.mjs.map +7 -0
  29. package/dist/sitemap/chunk-SNCZ4GCT.mjs +2 -0
  30. package/dist/sitemap/chunk-SNCZ4GCT.mjs.map +7 -0
  31. package/dist/sitemap/chunk-TZ6TJSKE.mjs +10 -0
  32. package/dist/sitemap/chunk-TZ6TJSKE.mjs.map +7 -0
  33. package/dist/sitemap/chunk-YMGL4RSC.mjs +2 -0
  34. package/dist/sitemap/chunk-YMGL4RSC.mjs.map +7 -0
  35. package/dist/sitemap/chunk-YY2HYMK3.mjs +4 -0
  36. package/dist/sitemap/chunk-YY2HYMK3.mjs.map +7 -0
  37. package/dist/sitemap/client-WGCJRHWA.mjs +2 -0
  38. package/dist/sitemap/client-WGCJRHWA.mjs.map +7 -0
  39. package/dist/sitemap/dist-es-3FAKVHIH.mjs +2 -0
  40. package/dist/sitemap/dist-es-3FAKVHIH.mjs.map +7 -0
  41. package/dist/sitemap/dist-es-A36NQ5CO.mjs +2 -0
  42. package/dist/sitemap/dist-es-A36NQ5CO.mjs.map +7 -0
  43. package/dist/sitemap/dist-es-F7GXZJIC.mjs +3 -0
  44. package/dist/sitemap/dist-es-F7GXZJIC.mjs.map +7 -0
  45. package/dist/sitemap/dist-es-GRXF7RTK.mjs +2 -0
  46. package/dist/sitemap/dist-es-GRXF7RTK.mjs.map +7 -0
  47. package/dist/sitemap/dist-es-OKUHAI6O.mjs +2 -0
  48. package/dist/sitemap/dist-es-OKUHAI6O.mjs.map +7 -0
  49. package/dist/sitemap/dist-es-P7BXOYHO.mjs +2 -0
  50. package/dist/sitemap/dist-es-P7BXOYHO.mjs.map +7 -0
  51. package/dist/sitemap/dist-es-SQ53M5JX.mjs +7 -0
  52. package/dist/sitemap/dist-es-SQ53M5JX.mjs.map +7 -0
  53. package/dist/sitemap/dist-es-TCGA3UGX.mjs +2 -0
  54. package/dist/sitemap/dist-es-TCGA3UGX.mjs.map +7 -0
  55. package/dist/sitemap/dist-es-UXKF5GQY.mjs +3 -0
  56. package/dist/sitemap/dist-es-UXKF5GQY.mjs.map +7 -0
  57. package/dist/sitemap/dist-es-YJ4PQZC7.mjs +2 -0
  58. package/dist/sitemap/dist-es-YJ4PQZC7.mjs.map +7 -0
  59. package/dist/sitemap/event-streams-6V3Q6GHC.mjs +2 -0
  60. package/dist/sitemap/event-streams-6V3Q6GHC.mjs.map +7 -0
  61. package/dist/sitemap/loadCognitoIdentity-RIENBHOX.mjs +2 -0
  62. package/dist/sitemap/loadCognitoIdentity-RIENBHOX.mjs.map +7 -0
  63. package/dist/sitemap/loadSso-DTQ4R4CV.mjs +2 -0
  64. package/dist/sitemap/loadSso-DTQ4R4CV.mjs.map +7 -0
  65. package/dist/sitemap/loadSts-GZDTRQPT.mjs +2 -0
  66. package/dist/sitemap/loadSts-GZDTRQPT.mjs.map +7 -0
  67. package/dist/sitemap/signin-6D536OAO.mjs +2 -0
  68. package/dist/sitemap/signin-6D536OAO.mjs.map +7 -0
  69. package/dist/sitemap/sitemap.mjs +3 -0
  70. package/dist/sitemap/sitemap.mjs.map +7 -0
  71. package/dist/sitemap/sso-oidc-T5CK3NX3.mjs +2 -0
  72. package/dist/sitemap/sso-oidc-T5CK3NX3.mjs.map +7 -0
  73. package/dist/sitemap/sts-62ECLMPL.mjs +2 -0
  74. package/dist/sitemap/sts-62ECLMPL.mjs.map +7 -0
  75. package/package.json +2 -1
package/dist/index.d.ts CHANGED
@@ -7,6 +7,7 @@ declare const dimensions: readonly ["status", "country", "device", "path"];
7
7
  type Dimension = (typeof dimensions)[number];
8
8
  declare const appliedSources: readonly ["v1", "v2"];
9
9
  type AppliedSource = (typeof appliedSources)[number];
10
+ type MarkerGrain = Grain | "sitemap";
10
11
  type TransactWriteItem = NonNullable<TransactWriteCommandInput["TransactItems"]>[number];
11
12
  type PutMembers = NonNullable<TransactWriteItem["Put"]>;
12
13
  interface TransactPutItem {
@@ -28,11 +29,11 @@ declare class AppliedMarkers {
28
29
  readonly reverseIndexName?: string;
29
30
  });
30
31
  readonly isApplied: (props: {
31
- readonly grain: Grain;
32
+ readonly grain: MarkerGrain;
32
33
  readonly periodKey: string;
33
34
  }) => Promise<boolean>;
34
35
  readonly buildMarkerPut: (props: {
35
- readonly grain: Grain;
36
+ readonly grain: MarkerGrain;
36
37
  readonly periodKey: string;
37
38
  readonly source: AppliedSource;
38
39
  readonly ttl?: number;
@@ -142,6 +143,18 @@ interface HourlyAthenaResult {
142
143
  hits: number;
143
144
  }>;
144
145
  }
146
+ /**
147
+ * Start an Athena statement, poll until it succeeds, and return every result
148
+ * row as raw string cells (header row dropped). Shared by the hourly query and
149
+ * the sitemap monthly query so both use one polling/paging implementation.
150
+ */
151
+ declare function startAndFetchRows({ athena, database, workgroup, outputLocation, queryString }: {
152
+ athena: Pick<AthenaClient, "send">;
153
+ database: string;
154
+ workgroup: string;
155
+ outputLocation?: string;
156
+ queryString: string;
157
+ }): Promise<Array<Array<string | undefined>>>;
145
158
  declare function runHourlyAthenaQuery({ athena, database, table, workgroup, outputLocation, source, hourKey, topPaths }: {
146
159
  athena: Pick<AthenaClient, "send">;
147
160
  database: string;
@@ -212,8 +225,13 @@ declare const configSchema: v3.ObjectSchema<{
212
225
  readonly sk: v3.LiteralSchema<"analytics", undefined>;
213
226
  readonly startKey: v3.StringSchema<undefined>;
214
227
  readonly startedAt: v3.StringSchema<undefined>;
228
+ readonly sitemapUrl: v3.OptionalSchema<v3.StringSchema<undefined>, undefined>;
215
229
  }, undefined>;
216
230
  type AnalyticsConfig = v3.InferOutput<typeof configSchema>;
231
+ declare const sitemapConfigSchema: v3.LooseObjectSchema<{
232
+ readonly sitemapUrl: v3.OptionalSchema<v3.StringSchema<undefined>, undefined>;
233
+ }, undefined>;
234
+ type SitemapConfig = v3.InferOutput<typeof sitemapConfigSchema>;
217
235
  declare class Config {
218
236
  private readonly props;
219
237
  constructor(props: {
@@ -221,6 +239,10 @@ declare class Config {
221
239
  readonly tableName: string;
222
240
  });
223
241
  readonly get: () => Promise<AnalyticsConfig | null>;
242
+ readonly getSitemapConfig: () => Promise<SitemapConfig>;
243
+ readonly setSitemapUrl: ({ sitemapUrl }: {
244
+ readonly sitemapUrl: string;
245
+ }) => Promise<void>;
224
246
  /**
225
247
  * Records the earliest ingested hour the first time any data lands, so the UI
226
248
  * can clamp navigation to [startKey, now]. Idempotent: once `startKey` exists
@@ -362,7 +384,25 @@ interface RollupModels {
362
384
  readonly breakdowns: Pick<Breakdowns, "buildUpdates" | "getForPeriod">;
363
385
  readonly markers: Pick<AppliedMarkers, "isApplied" | "buildMarkerPut">;
364
386
  }
387
+ declare function sendTransacted({ dynamo, leading, rest }: {
388
+ dynamo: Pick<DynamoDBDocumentClient5, "send">;
389
+ leading: Array<TransactItem>;
390
+ rest: Array<TransactItem>;
391
+ }): Promise<ProcessHourResult>;
392
+ declare function isMarkerRaceError(error: unknown): boolean;
365
393
  type View = Grain | "year";
394
+ /**
395
+ * How a bucket's value was obtained, so the UI can tell "no traffic" apart from
396
+ * "not calculated yet":
397
+ * - `sealed`: a finalized, rolled-up period read from its stored aggregate. A
398
+ * zero-hit sealed bucket is genuine "no traffic".
399
+ * - `partial`: an in-progress period computed live from the finer grain; the
400
+ * value is real but may still grow.
401
+ * - `pending`: a period past its expected processing time with no stored data
402
+ * and nothing computable yet — awaiting processing.
403
+ */
404
+ declare const bucketStates: readonly ["sealed", "partial", "pending"];
405
+ type BucketState = (typeof bucketStates)[number];
366
406
  interface ResolveModels {
367
407
  readonly totals: Pick<Totals, "queryWindow" | "getOne">;
368
408
  readonly breakdowns: Pick<Breakdowns, "getForPeriod">;
@@ -370,15 +410,21 @@ interface ResolveModels {
370
410
  }
371
411
  /**
372
412
  * Resolves one bucket's totals, computing an in-progress period on the fly from
373
- * the grain below it. A past period whose rollup marker is applied is read
374
- * directly from the stored aggregate ("sealed"); the current period, and any
375
- * past period still missing its marker, is summed from its children — the
376
- * current month folds down through the current day to the hours ingested so far.
413
+ * exactly one grain finer, following only the current edge deeper.
414
+ *
415
+ * A sealed period (strictly past, rollup marker applied) is read from its stored
416
+ * aggregate. Otherwise the period is the sum of its children at the next finer
417
+ * grain, where every already-complete child is taken from its stored aggregate
418
+ * and only the single in-progress child is resolved recursively:
419
+ *
420
+ * - partial day = stored/queried hours `00..currentHour`
421
+ * - partial month = stored days `01..currentDay-1` + the partial current day
422
+ * - partial year = stored months `01..currentMonth-1` + the partial current month
377
423
  *
378
- * Each level reads its children with a single ranged query (never a get per
379
- * child): a day sums its hours via one hourly `queryWindow`; a month sums its
380
- * days, and the one in-progress day among them is resolved from hours. `hour`
381
- * is terminal.
424
+ * So a partial month never fans out to hours for its finished days (it trusts
425
+ * their day aggregate) — only the one current day drills into hours. Each level
426
+ * is one ranged query, keeping the read count bounded (a year touches ~12
427
+ * months + ~31 days + ~24 hours) and the request sub-second.
382
428
  */
383
429
  declare function resolveTotalsLive({ models, grain, periodKey, now }: {
384
430
  readonly models: ResolveModels;
@@ -393,6 +439,222 @@ declare function resolveBreakdownLive({ models, dimension, grain, periodKey, now
393
439
  readonly periodKey: string;
394
440
  readonly now: Date;
395
441
  }): Promise<Array<BreakdownRow>>;
442
+ /**
443
+ * Classifies a bucket as sealed / partial / pending without recomputing its
444
+ * value. A sealed bucket is a finalized rollup (its marker is applied), so a
445
+ * zero-hit sealed bucket is genuine "no traffic". A non-sealed bucket that
446
+ * yielded data is in-progress (`partial`); one with nothing to show is awaiting
447
+ * processing (`pending`).
448
+ */
449
+ declare function classifyBucketState({ models, grain, periodKey, now, hasData }: {
450
+ readonly models: ResolveModels;
451
+ readonly grain: Grain;
452
+ readonly periodKey: string;
453
+ readonly now: Date;
454
+ readonly hasData: boolean;
455
+ }): Promise<BucketState>;
456
+ import { AthenaClient as AthenaClient3 } from "@aws-sdk/client-athena";
457
+ import { DynamoDBDocumentClient as DynamoDBDocumentClient6, TransactWriteCommandInput as TransactWriteCommandInput5 } from "@aws-sdk/lib-dynamodb";
458
+ import * as v5 from "valibot";
459
+ type TransactWriteItem4 = NonNullable<TransactWriteCommandInput5["TransactItems"]>[number];
460
+ type UpdateMembers3 = NonNullable<TransactWriteItem4["Update"]>;
461
+ /**
462
+ * Collapse a single trailing slash on a path so `/blog/` and `/blog` fold
463
+ * together. Root `/` is preserved. Already-unslashed paths are returned as-is.
464
+ */
465
+ declare function canonicalPath(path: string): string;
466
+ /**
467
+ * Parse an absolute sitemap `<loc>` URL and reduce it to a canonical path:
468
+ * origin, query and fragment are stripped and a trailing slash is collapsed.
469
+ * Throws on input the `URL` class cannot parse.
470
+ */
471
+ declare function normalizeSitemapLoc(loc: string): string;
472
+ /**
473
+ * Extract every `<loc>` from a flat `<urlset>` sitemap, XML-unescape and
474
+ * normalize each to a path, and dedupe preserving first-seen order (so a
475
+ * `/blog` and `/blog/` pair collapse to one entry). Throws on a
476
+ * `<sitemapindex>` document, which is not supported.
477
+ */
478
+ declare function parseSitemap(xml: string): Array<string>;
479
+ /**
480
+ * Identifies this crawler's outbound sitemap requests so site operators can
481
+ * distinguish them in their access logs.
482
+ */
483
+ declare const sitemapUserAgent = "@beesolve/analytics-processor sitemap fetcher (+https://github.com/BeeSolve/packages)";
484
+ /**
485
+ * Fetch a sitemap over HTTP and return its normalized, deduped paths. Throws
486
+ * with the response status if the request is not successful.
487
+ */
488
+ declare function fetchSitemapPaths(url: string): Promise<Array<string>>;
489
+ interface SitemapHourCounts {
490
+ readonly path: string;
491
+ readonly hits: number;
492
+ }
493
+ /**
494
+ * Build an Athena statement that counts hits per `path` for a single UTC hour,
495
+ * restricted to the given sitemap paths. The log-side URI is slash-collapsed in
496
+ * SQL via {@link canonicalUriExpr} in both the `WHERE ... IN` and the
497
+ * `GROUP BY`, mirroring {@link canonicalPath}, so `/blog` and the 301 hit on
498
+ * `/blog/` both count against `/blog`. An empty `paths` yields a valid zero-row
499
+ * statement (`WHERE 1 = 0`).
500
+ */
501
+ declare function buildSitemapHourlyQuery({ table, source, hourKey, paths }: {
502
+ table: string;
503
+ source: AppliedSource;
504
+ hourKey: string;
505
+ paths: Array<string>;
506
+ }): string;
507
+ /**
508
+ * Run {@link buildSitemapHourlyQuery} and return one {@link SitemapHourCounts}
509
+ * per path with hits for that hour. Short-circuits to `[]` without calling
510
+ * Athena when `paths` is empty.
511
+ */
512
+ declare function runSitemapHourlyQuery({ athena, database, table, workgroup, outputLocation, source, hourKey, paths }: {
513
+ athena: Pick<AthenaClient3, "send">;
514
+ database: string;
515
+ table: string;
516
+ workgroup: string;
517
+ outputLocation?: string;
518
+ source: AppliedSource;
519
+ hourKey: string;
520
+ paths: Array<string>;
521
+ }): Promise<Array<SitemapHourCounts>>;
522
+ interface SitemapMonthCounts {
523
+ readonly path: string;
524
+ readonly month: string;
525
+ readonly days: Record<string, number>;
526
+ readonly hits: number;
527
+ }
528
+ /**
529
+ * Build an Athena statement that counts hits per `(day-of-month, path)` across
530
+ * a whole `YYYY-MM`, restricted to the given sitemap paths. One scan of the
531
+ * month's partitions replaces 720 single-hour scans, which is why backfill uses
532
+ * this instead of {@link buildSitemapHourlyQuery}. The log-side URI is
533
+ * slash-collapsed in SQL via {@link canonicalUriExpr} in both the `WHERE ... IN`
534
+ * and the `GROUP BY`. An empty `paths` yields a valid zero-row statement.
535
+ */
536
+ declare function buildSitemapMonthlyQuery({ table, source, monthKey, paths }: {
537
+ table: string;
538
+ source: AppliedSource;
539
+ monthKey: string;
540
+ paths: Array<string>;
541
+ }): string;
542
+ /**
543
+ * Run {@link buildSitemapMonthlyQuery} and reshape the rows into one
544
+ * {@link SitemapMonthCounts} per path, with day-of-month zero-padded to `dd`.
545
+ * Short-circuits to `[]` without calling Athena when `paths` is empty.
546
+ */
547
+ declare function runSitemapMonthlyQuery({ athena, database, table, workgroup, outputLocation, source, monthKey, paths }: {
548
+ athena: Pick<AthenaClient3, "send">;
549
+ database: string;
550
+ table: string;
551
+ workgroup: string;
552
+ outputLocation?: string;
553
+ source: AppliedSource;
554
+ monthKey: string;
555
+ paths: Array<string>;
556
+ }): Promise<Array<SitemapMonthCounts>>;
557
+ interface ProcessSitemapModels {
558
+ readonly sitemapUrlStats: Pick<SitemapUrlStats, "buildAdd">;
559
+ readonly markers: Pick<AppliedMarkers, "isApplied" | "buildMarkerPut">;
560
+ }
561
+ interface ProcessSitemapAthena {
562
+ readonly client: Pick<AthenaClient3, "send">;
563
+ readonly database: string;
564
+ readonly table: string;
565
+ readonly workgroup: string;
566
+ readonly outputLocation?: string;
567
+ }
568
+ interface ProcessSitemapOptions {
569
+ readonly markerTtlDays?: number;
570
+ }
571
+ /**
572
+ * Incrementally add a single UTC hour's per-path hits to each sitemap URL's
573
+ * `(path, month)` item, guarded by an applied-marker so the hour is counted at
574
+ * most once. Returns `{ status: "skipped" }` when the hour is already applied,
575
+ * and `{ status: "applied", urls }` otherwise (`urls: 0` when nothing matched).
576
+ */
577
+ declare function processSitemapHour({ hourKey, source, paths, models, athena, options, dynamo }: {
578
+ hourKey: string;
579
+ source: AppliedSource;
580
+ paths: Array<string>;
581
+ models: ProcessSitemapModels;
582
+ athena: ProcessSitemapAthena;
583
+ options?: ProcessSitemapOptions;
584
+ dynamo: Pick<DynamoDBDocumentClient6, "send">;
585
+ }): Promise<{
586
+ status: "applied" | "skipped";
587
+ urls: number;
588
+ }>;
589
+ interface ProcessSitemapMonthModels {
590
+ readonly sitemapUrlStats: Pick<SitemapUrlStats, "overwriteMany">;
591
+ }
592
+ /**
593
+ * Recompute a whole month's per-day hits in a single Athena scan and overwrite
594
+ * each `(path, month)` item with `SET`. This is the backfill path: one scan of
595
+ * the month replaces 720 single-hour scans, and `SET` is idempotent so reruns
596
+ * are safe and no applied-marker is needed. The live hourly cron uses
597
+ * {@link processSitemapHour} (incremental `ADD`) instead, because going forward
598
+ * it only ever has one new hour of data. Returns `{ urls: 0 }` without calling
599
+ * Athena when `paths` is empty.
600
+ */
601
+ declare function processSitemapMonth({ monthKey, source, paths, models, athena }: {
602
+ monthKey: string;
603
+ source: AppliedSource;
604
+ paths: Array<string>;
605
+ models: ProcessSitemapMonthModels;
606
+ athena: ProcessSitemapAthena;
607
+ }): Promise<{
608
+ urls: number;
609
+ }>;
610
+ declare const sitemapUrlStatSchema: v5.LooseObjectSchema<{
611
+ readonly pk: v5.StringSchema<undefined>;
612
+ readonly sk: v5.StringSchema<undefined>;
613
+ readonly path: v5.StringSchema<undefined>;
614
+ readonly month: v5.StringSchema<undefined>;
615
+ readonly hits: v5.NumberSchema<undefined>;
616
+ readonly updatedAt: v5.NumberSchema<undefined>;
617
+ }, undefined>;
618
+ type SitemapUrlStat = v5.InferOutput<typeof sitemapUrlStatSchema>;
619
+ interface SitemapUrlStatRecord {
620
+ readonly pk: string;
621
+ readonly sk: string;
622
+ readonly path: string;
623
+ readonly month: string;
624
+ readonly hits: number;
625
+ readonly updatedAt: number;
626
+ readonly days: Record<string, number>;
627
+ }
628
+ declare class SitemapUrlStats {
629
+ private readonly props;
630
+ constructor(props: {
631
+ readonly dynamo: Pick<DynamoDBDocumentClient6, "send">;
632
+ readonly tableName: string;
633
+ readonly reverseIndexName?: string;
634
+ });
635
+ readonly buildAdd: ({ path, month, dayAttr, hits }: {
636
+ readonly path: string;
637
+ readonly month: string;
638
+ readonly dayAttr: string;
639
+ readonly hits: number;
640
+ }) => TransactItem;
641
+ readonly overwriteMany: (stats: Array<SitemapMonthCounts>) => Promise<void>;
642
+ readonly buildOverwrite: ({ path, month, days, hits }: {
643
+ readonly path: string;
644
+ readonly month: string;
645
+ readonly days: Record<string, number>;
646
+ readonly hits: number;
647
+ }) => UpdateMembers3;
648
+ readonly getForUrl: ({ path, startMonth, endMonth }: {
649
+ readonly path: string;
650
+ readonly startMonth: string;
651
+ readonly endMonth: string;
652
+ }) => Promise<Array<SitemapUrlStatRecord>>;
653
+ readonly getForMonth: ({ month }: {
654
+ readonly month: string;
655
+ }) => Promise<Array<SitemapUrlStatRecord>>;
656
+ private readonly parseOne;
657
+ }
396
658
  declare function yearKey(date: Date): string;
397
659
  declare function monthKey2(date: Date): string;
398
660
  declare function dayKey2(date: Date): string;
@@ -423,4 +685,4 @@ declare function hoursBetween({ from, to }: {
423
685
  from: Date;
424
686
  to: Date;
425
687
  }): Array<string>;
426
- export { AnalyticsConfig, AppliedMarker, AppliedMarkers, AppliedSource, AthenaColumnMap, BreakdownInput, BreakdownItem, BreakdownRow, Breakdowns, Config, DeviceBucket, Dimension, Grain, HourlyAthenaResult, HourlyAthenaTotals, ProcessHourAthena, ProcessHourModels, ProcessHourOptions, ProcessHourResult, ResolveModels, SummedTotals, Totals, TotalsInput, TotalsItem, TransactItem, View, appliedMarkerSchema, appliedSources, applyDailyRollup, applyMonthlyRollup, breakdownSchema, buildHourlyQuery, chunkTransactItems, classifyDevice, columnMaps, configSchema, dayKey2 as dayKey, dimensions, grainForPeriodKey, grains, hourKey2 as hourKey, hourKeyParts, hoursBetween, maxWindowFor, monthKey2 as monthKey, parsePeriodKey, processHour, requiredRecordFields, resolveBreakdownLive, resolveTotalsLive, runHourlyAthenaQuery, shiftAnchor, sumBreakdown, sumTotals, topNWithOther, totalsSchema, windowKeys, yearKey };
688
+ export { AnalyticsConfig, AppliedMarker, AppliedMarkers, AppliedSource, AthenaColumnMap, BreakdownInput, BreakdownItem, BreakdownRow, Breakdowns, BucketState, Config, DeviceBucket, Dimension, Grain, HourlyAthenaResult, HourlyAthenaTotals, MarkerGrain, ProcessHourAthena, ProcessHourModels, ProcessHourOptions, ProcessHourResult, ProcessSitemapAthena, ProcessSitemapModels, ProcessSitemapMonthModels, ProcessSitemapOptions, ResolveModels, SitemapConfig, SitemapHourCounts, SitemapMonthCounts, SitemapUrlStat, SitemapUrlStatRecord, SitemapUrlStats, SummedTotals, Totals, TotalsInput, TotalsItem, TransactItem, View, appliedMarkerSchema, appliedSources, applyDailyRollup, applyMonthlyRollup, breakdownSchema, bucketStates, buildHourlyQuery, buildSitemapHourlyQuery, buildSitemapMonthlyQuery, canonicalPath, chunkTransactItems, classifyBucketState, classifyDevice, columnMaps, configSchema, dayKey2 as dayKey, dimensions, fetchSitemapPaths, grainForPeriodKey, grains, hourKey2 as hourKey, hourKeyParts, hoursBetween, isMarkerRaceError, maxWindowFor, monthKey2 as monthKey, normalizeSitemapLoc, parsePeriodKey, parseSitemap, processHour, processSitemapHour, processSitemapMonth, requiredRecordFields, resolveBreakdownLive, resolveTotalsLive, runHourlyAthenaQuery, runSitemapHourlyQuery, runSitemapMonthlyQuery, sendTransacted, shiftAnchor, sitemapUrlStatSchema, sitemapUserAgent, startAndFetchRows, sumBreakdown, sumTotals, topNWithOther, totalsSchema, windowKeys, yearKey };