@pythia-software/query-table-core 0.9.6 → 0.9.7

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.
package/dist/index.d.ts CHANGED
@@ -130,6 +130,10 @@ interface SelectConfig {
130
130
  default?: boolean;
131
131
  /** Default column width (px); a per-column override rides in QueryState.select. */
132
132
  width?: number;
133
+ /** Narrowest usable width (px) when fitting columns to the screen, such as
134
+ * the room a host renderer's buttons need. Measured native controls are
135
+ * always kept whole; this adds room they cannot measure. */
136
+ minWidth?: number;
133
137
  align?: Align;
134
138
  }
135
139
  interface AggregateConfig {
@@ -268,19 +272,44 @@ declare function formulaRuntime(ast: FormulaNode, inputs: Record<string, Formula
268
272
  type MetricValue = number | string | boolean | null;
269
273
  type MetricKey = MetricValue;
270
274
  type MetricScope = "allMatching" | "shownRows";
275
+ /** Calendar intervals: each bucket is one interval on the timeline, keyed by
276
+ * its start as an ISO instant. */
277
+ type MetricCalendarInterval = "hour" | "day" | "week" | "month" | "year";
278
+ /** Cyclic intervals: each bucket is one slot of a repeating cycle, keyed by a
279
+ * number. `hourOfDay` is the local hour, 0–23; `dayOfWeek` the ISO weekday,
280
+ * 1 (Monday) to 7 (Sunday). */
281
+ type MetricCycleInterval = "hourOfDay" | "dayOfWeek";
282
+ /** Summarise each cyclic slot over its occurrences: every whole day or hour
283
+ * the slot covers inside the query's time bounds. */
284
+ interface MetricDateOccurrence {
285
+ /** One occurrence: "day" (dayOfWeek only) or "hour". */
286
+ interval: "hour" | "day";
287
+ /** Count occurrences without rows: 0 for direct COUNT, COUNT_DISTINCT and
288
+ * SUM metrics, no value for other expressions. false leaves them out. */
289
+ includeEmpty: boolean;
290
+ }
271
291
  /** Calendar grouping, currently executed over complete local populations. */
272
292
  interface MetricDateGrouping {
273
293
  field: string;
274
- interval: "hour" | "day" | "week" | "month" | "year";
294
+ interval: MetricCalendarInterval | MetricCycleInterval;
275
295
  /** IANA timezone identifier; omitted settings retain UTC behavior. */
276
296
  timeZone?: string;
297
+ /** Add a bucket for every interval of the range, or for every slot of a
298
+ * cyclic interval. */
277
299
  includeEmpty: boolean;
300
+ /** The calendar range empty intervals fill; for a cyclic interval, the range
301
+ * whose empty occurrences count. */
278
302
  range: "query" | "observed" | "custom";
279
303
  start?: string;
280
304
  end?: string;
281
305
  /** "exclude" leaves out intervals the query's bounds cut, and intervals that
282
- * have not ended by the evaluation time; omitted includes them. */
306
+ * have not ended by the evaluation time; omitted includes them. A cyclic
307
+ * interval's intervals are its hours or days. */
283
308
  partialIntervals?: "include" | "exclude";
309
+ /** Cyclic intervals only: each slot's value is the mean of its
310
+ * per-occurrence values, and a box distribution summarises them. Only whole
311
+ * occurrences count. Computed from a calendar metric by planMetricSeries. */
312
+ occurrence?: MetricDateOccurrence;
284
313
  }
285
314
  /** A trailing window over a calendar metric's intervals. */
286
315
  interface MetricWindow {
@@ -298,6 +327,19 @@ interface MetricWindow {
298
327
  /** Divide each bucket by the total of all groups ("total") or of its first
299
328
  * grouping key ("group0"), such as one calendar interval. */
300
329
  type MetricShare = "total" | "group0";
330
+ /** A per-group minimum measured over something other than rows: the distinct
331
+ * non-null values of one field (like COUNT_DISTINCT), or the sum of one
332
+ * numeric field (like SUM; nulls add nothing). Exactly one of `distinct` and
333
+ * `sum` is set. A group whose measure is an error is kept. */
334
+ type MetricMinCountOf = {
335
+ min: number;
336
+ distinct: string;
337
+ sum?: never;
338
+ } | {
339
+ min: number;
340
+ sum: string;
341
+ distinct?: never;
342
+ };
301
343
  interface MetricValueFormat {
302
344
  kind: "number" | "percent" | "duration" | "date" | "time" | "datetime";
303
345
  decimals?: number;
@@ -396,6 +438,8 @@ interface MetricDiagnostic extends FormulaDiagnostic {
396
438
  }
397
439
  /** Host must enforce snapshot against the row response; this token alone does not pin data. */
398
440
  interface MetricQuery {
441
+ /** The table's host-owned state when `hostQuery` is configured. */
442
+ hostState?: HostQueryState;
399
443
  snapshot?: string;
400
444
  profile?: string;
401
445
  expectedRevisions?: Record<string, string>;
@@ -418,6 +462,8 @@ interface MetricCapabilities {
418
462
  filters?: boolean;
419
463
  /** Executes AggregationClause.minCount and reports hiddenGroups. */
420
464
  minCount?: boolean;
465
+ /** Also executes an object minCount: distinct values or a sum per group. */
466
+ minCountMeasures?: boolean;
421
467
  maxGroups?: number;
422
468
  profile?: string;
423
469
  }
@@ -501,6 +547,33 @@ declare function readObjectReference<Row>(field: FieldDef<Row>, fields: FieldDef
501
547
  /** Only unambiguous, fully mapped constraints become links. Explicit metadata wins. */
502
548
  declare function discoverFieldRelationships<Row>(fields: FieldDef<Row>[], keys: ForeignKey[], types: ObjectTypeDefinition[]): FieldDef<Row>[];
503
549
 
550
+ /** Calendar intervals a grouping key can bucket a datetime field by. */
551
+ declare const GROUP_KEY_INTERVALS: readonly MetricCalendarInterval[];
552
+ /** A grouping key that buckets a datetime field by calendar interval: one
553
+ * group per interval, keyed by the interval's start as an ISO instant. The
554
+ * result column is named after the field. Intervals follow the metric
555
+ * calendar (`dateGrouping`), including daylight-saving changes; weeks start
556
+ * on Monday. */
557
+ interface CalendarGroupKey {
558
+ field: string;
559
+ interval: MetricCalendarInterval;
560
+ /** IANA timezone identifier; omitted means UTC. */
561
+ timeZone?: string;
562
+ }
563
+ /** A field name (group by its exact value) or a calendar key. */
564
+ type GroupKey = string | CalendarGroupKey;
565
+ declare function isCalendarGroupKey(key: GroupKey): key is CalendarGroupKey;
566
+ /** The source field a key reads; also the name of its result column. */
567
+ declare function groupKeyField(key: GroupKey): string;
568
+ /** Result column names, in key order. */
569
+ declare function groupKeyFields(keys: readonly GroupKey[]): string[];
570
+ /** The calendar key on `field`, if that key buckets by interval. */
571
+ declare function calendarGroupKey(keys: readonly GroupKey[], field: string): CalendarGroupKey | undefined;
572
+ /** `=` (or `is_null`) per key, in key order, or null when any key cannot be
573
+ * matched exactly (textarray, unknown or unfilterable fields, unparseable
574
+ * datetimes). A calendar key adds `>= start` and `< end` for its interval. */
575
+ declare function groupKeyTerms(keys: readonly GroupKey[], group: Record<string, unknown>, schema: FieldSchema): WhereClause[] | null;
576
+
504
577
  type QueryFacet = "filters" | "columns" | "order" | "grouping" | "metrics" | "limit";
505
578
  interface QueryPatch {
506
579
  /** Host identity for the patch; not interpreted. */
@@ -629,7 +702,10 @@ declare function isGroupLinkField(field: Pick<FieldDef, "render"> | undefined):
629
702
  interface GroupingView {
630
703
  version: 2;
631
704
  mode: "rows" | "groups";
705
+ /** Result key columns: the field each key reads, in key order. */
632
706
  keys: string[];
707
+ /** The keys as defined, including calendar intervals; absent means `keys`. */
708
+ groupKeys?: GroupKey[];
633
709
  summaries: SummaryColumn[];
634
710
  representative: RepresentativeRow | null;
635
711
  input: QueryState;
@@ -639,7 +715,10 @@ interface GroupingView {
639
715
  * HAVING in this mode; source.where is the pre-group WHERE. The source snapshot
640
716
  * also restores the record layout, paging, metrics and item details on exit. */
641
717
  interface GroupingDefinition {
642
- keys: string[];
718
+ /** Field names, or calendar keys (`{ field, interval, timeZone }`) that
719
+ * group a datetime field by interval. Each field appears once; its result
720
+ * column is named after the field. */
721
+ keys: GroupKey[];
643
722
  summaries: SummaryColumn[];
644
723
  representative: RepresentativeRow | null;
645
724
  diagnostics?: string[];
@@ -653,14 +732,14 @@ declare const MAX_SUMMARY_COLUMNS = 64;
653
732
  declare const MAX_RESULT_GROUPS = 10000;
654
733
  declare function withoutGrouping(query: QueryState): QueryState;
655
734
  /** Leave the grouping stage: the source snapshot restores the record WHERE,
656
- * layout, ordering, paging, metrics and item details. Ungrouped queries are
657
- * returned unchanged. */
735
+ * layout, ordering, paging, metrics and item details, and keeps the host
736
+ * state of the grouped query. Ungrouped queries are returned unchanged. */
658
737
  declare function exitGrouping(query: QueryState): QueryState;
659
738
  /** The grouping-key transition behind the grouping controls. Empty keys exit
660
739
  * the stage; an ungrouped query becomes the source of a new stage that shows
661
740
  * only its keys; a grouped query swaps keys, dropping result columns, HAVING
662
741
  * terms and sorts on removed keys and clearing group metrics. */
663
- declare function withGroupingKeys(query: QueryState, keys: string[]): QueryState;
742
+ declare function withGroupingKeys(query: QueryState, keys: GroupKey[]): QueryState;
664
743
  declare const OP_LABEL: Record<SummaryOp, string>;
665
744
  /** Bind aggregation helpers to this instance's source catalogue. */
666
745
  declare function createGroupingModel<InputRow>(inputSchema: FieldSchema<InputRow>): {
@@ -674,10 +753,10 @@ declare function createGroupingModel<InputRow>(inputSchema: FieldSchema<InputRow
674
753
  summaryExpression: (column: SummaryColumn) => string;
675
754
  summaryProblem: (column: SummaryColumn) => string | null;
676
755
  summaryLabel: (column: SummaryColumn) => string;
677
- linkProblem: (column: SummaryColumn, keys: string[], summaries: SummaryColumn[]) => string | null;
756
+ linkProblem: (column: SummaryColumn, keys: GroupKey[], summaries: SummaryColumn[]) => string | null;
678
757
  linkDiagnostics: (definition: Pick<GroupingDefinition, "keys" | "summaries">) => string[];
679
- resultSchema: (keys: string[], summaries: SummaryColumn[]) => FieldSchema<Row>;
680
- groupRows: (rows: InputRow[], schema: FieldSchema<InputRow>, keys: string[], summaries: SummaryColumn[], rule?: RepresentativeRow | null) => Row[];
758
+ resultSchema: (keys: GroupKey[], summaries: SummaryColumn[]) => FieldSchema<Row>;
759
+ groupRows: (rows: InputRow[], schema: FieldSchema<InputRow>, keys: GroupKey[], summaries: SummaryColumn[], rule?: RepresentativeRow | null) => Row[];
681
760
  filteredInput: (rows: InputRow[], query: QueryState, schema: FieldSchema<InputRow>, options?: QueryEvaluationOptions) => InputRow[];
682
761
  reconcileRepresentative: (query: QueryState, summaries: SummaryColumn[], schema: FieldSchema<Row>, remove: boolean) => QueryState;
683
762
  validate: (definition: GroupingDefinition) => void;
@@ -723,25 +802,59 @@ interface SetFilterMetadata {
723
802
  values: string[];
724
803
  }
725
804
  /** A disjunction of predicates — the inner OR of conjunctive normal form. Every
726
- * member is a plain literal; nesting is intentionally not allowed yet (CNF
727
- * only), but the object shape leaves room to grow. */
805
+ * member is a plain literal. See `OrOfAndsGroup` for an OR whose members may
806
+ * themselves be conjunctions. */
728
807
  interface OrGroup {
729
808
  any: WhereClause[];
730
809
  setFilter?: SetFilterMetadata;
731
810
  }
732
- /** One conjunct of the WHERE clause: either a single predicate or an OR group.
733
- * `QueryState.where` is the AND of these terms, so the whole WHERE is
734
- * conjunctive normal form — `(a) AND (b OR c) AND (d)`. A bare literal is
735
- * equivalent to a one-element OR group; normalization flattens singleton groups
736
- * back to a literal so equality/encoding stay canonical. */
737
- type WhereTerm = WhereClause | OrGroup;
738
- /** Narrow a term to an OR group. A literal always carries `field`; a group never
739
- * does and always carries an `any` array. */
811
+ /** One branch of an `OrOfAndsGroup` that ANDs several literals. Members are
812
+ * always plain literals: nesting stops at `any` → `all` → clause. */
813
+ interface WhereConjunction {
814
+ all: WhereClause[];
815
+ }
816
+ /** One alternative of an `OrOfAndsGroup`: a literal or a conjunction. */
817
+ type WhereBranch = WhereClause | WhereConjunction;
818
+ /** A disjunction of conjunctions — `(a AND b) OR (c AND d)` — written
819
+ * `{ any: [{ all: [a, b] }, { all: [c, d] }] }`. A branch may also be a bare
820
+ * literal. It selects the union of its branches' rows, such as a legend
821
+ * selection of several (provider, model) pairs, without the exponential
822
+ * AND-of-ORs rewrite. Normalization keeps the shape canonical: a one-literal
823
+ * conjunction becomes that literal, a group whose branches are all literals is
824
+ * an `OrGroup`, and a single conjunction becomes top-level literals. Every
825
+ * literal counts against `MAX_WHERE_CLAUSES`, which therefore also bounds the
826
+ * number of branches. Each literal keeps its own null-exclusive negation; the
827
+ * group itself is never negated. */
828
+ interface OrOfAndsGroup {
829
+ any: WhereBranch[];
830
+ setFilter?: SetFilterMetadata;
831
+ }
832
+ /** One conjunct of the WHERE clause: a single predicate, an OR group, or an OR
833
+ * of conjunctions. `QueryState.where` is the AND of these terms —
834
+ * `(a) AND (b OR c) AND ((d AND e) OR f)`. A bare literal is equivalent to a
835
+ * one-element OR group; normalization flattens singleton groups back to a
836
+ * literal so equality/encoding stay canonical. */
837
+ type WhereTerm = WhereClause | OrGroup | OrOfAndsGroup;
838
+ /** Narrow a branch to a conjunction. */
839
+ declare function isWhereConjunction(branch: WhereBranch): branch is WhereConjunction;
840
+ /** Narrow a term to a plain OR group (every member a literal). A literal
841
+ * always carries `field`; a group never does and always carries an `any`
842
+ * array. An `OrOfAndsGroup` is not an `OrGroup`. */
740
843
  declare function isOrGroup(term: WhereTerm): term is OrGroup;
741
- /** The predicate literals a term contributes, in order: the term itself for a
742
- * literal, or its members for a group. Handy for anything that must visit every
743
- * predicate regardless of grouping (field allowlisting, SELECT projection). */
844
+ /** Narrow a term to an OR group with at least one conjunction branch. */
845
+ declare function isOrOfAndsGroup(term: WhereTerm): term is OrOfAndsGroup;
846
+ /** Narrow a term to either kind of group (anything carrying `any`). */
847
+ declare function isWhereGroup(term: WhereTerm): term is OrGroup | OrOfAndsGroup;
848
+ /** The predicate literals a term references, in order: the term itself for a
849
+ * literal, a group's members, and the members of each conjunction branch.
850
+ * Handy for anything that must visit every predicate regardless of grouping
851
+ * (field allowlisting, SELECT projection, budgets); it does not preserve
852
+ * meaning — use `branchesOf` to evaluate a term. */
744
853
  declare function predicatesOf(term: WhereTerm): WhereClause[];
854
+ /** A term as a disjunction of conjunctions: it matches when every literal of
855
+ * some branch matches. A literal is `[[literal]]`, an OR group one
856
+ * single-literal branch per member. */
857
+ declare function branchesOf(term: WhereTerm): WhereClause[][];
745
858
  /** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */
746
859
  interface OrderByClause {
747
860
  field: string;
@@ -810,10 +923,12 @@ interface AggregationClause {
810
923
  * mode it refers to grouped-result fields. Shown-row metrics apply it inside
811
924
  * the shown page. */
812
925
  where?: WhereTerm[];
813
- /** Drop groups with fewer than this many rows (counted after `where`) before
814
- * sorting, `groupLimit` and Other. Requires at least one grouping field;
815
- * integer 1–1,000,000. Removed groups are reported as `hiddenGroups`. */
816
- minCount?: number;
926
+ /** Drop small groups before sorting, `groupLimit` and Other. A number counts
927
+ * rows (after `where`); `{ min, distinct: field }` counts a field's distinct
928
+ * non-null values and `{ min, sum: field }` sums a numeric field, ignoring
929
+ * nulls. Requires at least one grouping field; `min` is an integer
930
+ * 1–1,000,000. Removed groups are reported as `hiddenGroups`. */
931
+ minCount?: number | MetricMinCountOf;
817
932
  /** A trailing window or running value over the calendar intervals of
818
933
  * `dateGrouping`. Computed from ordinary metrics, so every engine supports it. */
819
934
  window?: MetricWindow;
@@ -842,7 +957,29 @@ interface ItemDetailsState {
842
957
  mode: "modal" | "expand";
843
958
  };
844
959
  }
960
+ /**
961
+ * Query state a host owns and registers with `useQueryTable({ hostQuery })`,
962
+ * such as a keyword clause it runs itself. It travels with the table query
963
+ * through saves, links, history and resets as one definition. `params` are
964
+ * named lists of strings, like URL search parameters; the host's own
965
+ * `normalize` interprets them. Version 0 marks a payload that could not be
966
+ * read, and is always rejected on restore.
967
+ */
968
+ interface HostQueryState {
969
+ version: number;
970
+ params: Record<string, string[]>;
971
+ }
972
+ declare const MAX_HOST_QUERY_PARAMS = 64;
973
+ declare const MAX_HOST_QUERY_VALUES = 64;
974
+ declare const MAX_HOST_QUERY_VALUE_LENGTH = 4000;
975
+ declare const MAX_HOST_QUERY_STATE_BYTES: number;
976
+ /** Validates host state and returns its canonical form (parameters sorted by
977
+ * name, values in order). Throws on a malformed or oversized payload. */
978
+ declare function parseHostQueryState(input: unknown): HostQueryState;
845
979
  interface QueryState {
980
+ /** Host-owned state registered through `useQueryTable({ hostQuery })`.
981
+ * Only the top-level query carries it; a grouping source never does. */
982
+ hostState?: HostQueryState;
846
983
  /** Optional row-producing stage. `grouping.source` is the original record
847
984
  * query (its WHERE runs first). This query selects/filters/sorts the groups;
848
985
  * its `where` therefore represents HAVING. Only one stage is supported. */
@@ -988,6 +1125,9 @@ interface ServerQuery {
988
1125
  orderBy: OrderByClause[];
989
1126
  limit: number;
990
1127
  offset: number;
1128
+ /** The table's host-owned state when `hostQuery` is configured; hosts run
1129
+ * their own clauses from it. Query Table does not interpret it. */
1130
+ hostState?: HostQueryState;
991
1131
  }
992
1132
  /** Project a QueryState into the server request, dropping client-only filters,
993
1133
  * client-only sorts, and remapping sort fields through `sort.field`. */
@@ -997,6 +1137,8 @@ declare function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): Se
997
1137
  * metrics describe every matching row, not the visible page. Mirrors the Go
998
1138
  * AggSpec list. */
999
1139
  interface AggregationRequest {
1140
+ /** The table's host-owned state when `hostQuery` is configured. */
1141
+ hostState?: HostQueryState;
1000
1142
  diagnostics?: MetricDiagnostic[];
1001
1143
  where: WhereTerm[];
1002
1144
  aggregations: AggregationClause[];
@@ -1022,6 +1164,9 @@ interface AggregationBucket {
1022
1164
  /** Calendar intervals combined into a windowed point (`AggregationClause.window`);
1023
1165
  * fewer than its periods where the window starts before the first interval. */
1024
1166
  intervals?: number;
1167
+ /** Occurrences summarised by a cyclic slot (`dateGrouping.occurrence`):
1168
+ * those with a value, the samples of its mean and box. */
1169
+ occurrences?: number;
1025
1170
  /** The metric: a number for count/sum/avg, or the column's value for min/max
1026
1171
  * (which may be a string for text/datetime). null when undefined (e.g. avg of
1027
1172
  * an all-null column). */
@@ -1219,12 +1364,46 @@ declare function reduceMetricValues(node: Extract<FormulaNode, {
1219
1364
  declare function evaluateMetricReductions(plan: MetricPlan, reductions: readonly FormulaResult[]): FormulaResult;
1220
1365
  declare function metricExpression(clause: AggregationClause): string;
1221
1366
  declare function hasRegex(plan: FormulaPlan): boolean;
1367
+ /** A box over a cyclic slot's per-occurrence values: its input is the
1368
+ * metric itself, evaluated once per occurrence. */
1369
+ declare function occurrenceDistribution(c: AggregationClause): boolean;
1222
1370
  declare function metricPlans(c: AggregationClause, schema: FieldSchema, resolve?: (name: string) => FormulaPlan | undefined): FormulaPlan[];
1223
1371
  declare function validateMetric(c: AggregationClause, schema: FieldSchema, resolve?: (name: string) => FormulaPlan | undefined): FormulaDiagnostic[];
1372
+ /** The threshold of `AggregationClause.minCount` in either form. */
1373
+ declare function metricMinCount(c: {
1374
+ minCount?: AggregationClause["minCount"] | undefined;
1375
+ }): number | undefined;
1376
+ /** What an object `minCount` measures: the aggregate whose value per group
1377
+ * must reach `min`. Undefined when `minCount` counts rows. */
1378
+ declare function metricMinCountMeasure(c: {
1379
+ minCount?: AggregationClause["minCount"] | undefined;
1380
+ }): {
1381
+ op: "count_distinct" | "sum";
1382
+ field: string;
1383
+ } | undefined;
1384
+ /** A minimum in words: "3 rows", "5 distinct Conversation values" or
1385
+ * "10 total Calls". `label` names a field (default: its name). */
1386
+ declare function metricMinCountText(c: {
1387
+ minCount?: AggregationClause["minCount"] | undefined;
1388
+ }, label?: (field: string) => string): string | undefined;
1389
+ /** The aggregate plan of an object `minCount`, such as SUM([calls]). */
1390
+ declare function metricMinCountPlan(c: {
1391
+ minCount?: AggregationClause["minCount"] | undefined;
1392
+ }, schema: FieldSchema, resolve?: (name: string) => FormulaPlan | undefined): MetricPlan | undefined;
1393
+ /** Whether a group survives `minCount`. Calendar fill-ins (no rows) always do.
1394
+ * Otherwise the row count, or for an object `minCount` the group's measure
1395
+ * (null counts as 0), must reach `min`. A measure that is an error keeps its
1396
+ * group, so the error stays visible. */
1397
+ declare function metricMinCountKeeps(min: number, count: number, measure?: {
1398
+ value: unknown;
1399
+ error?: string | undefined;
1400
+ }): boolean;
1224
1401
  /** Executor support for population controls, from either capability handshake. */
1225
1402
  interface MetricPopulationSupport {
1226
1403
  filters?: boolean | undefined;
1227
1404
  minCount?: boolean | undefined;
1405
+ /** A `minCount` object: distinct values or a sum of a field. */
1406
+ minCountMeasures?: boolean | undefined;
1228
1407
  }
1229
1408
  /** A clause the executor cannot run exactly gets its own error; it is never
1230
1409
  * sent with `where`/`minCount` silently dropped. */
@@ -1308,6 +1487,11 @@ interface QueryCapabilitiesV3 {
1308
1487
  version: 3;
1309
1488
  groupedRows: boolean;
1310
1489
  calendarGrouping: boolean;
1490
+ /** Executes the cyclic `hourOfDay` and `dayOfWeek` date intervals. */
1491
+ calendarCycles?: boolean;
1492
+ /** Executes calendar grouping keys (`{ field, interval, timeZone }`) in a
1493
+ * grouping stage. Requests using them are refused otherwise. */
1494
+ calendarGroupKeys?: boolean;
1311
1495
  computedSourceFilters: boolean;
1312
1496
  regex: boolean;
1313
1497
  regexSourceFilters?: boolean;
@@ -1316,12 +1500,16 @@ interface QueryCapabilitiesV3 {
1316
1500
  metricFilters?: boolean;
1317
1501
  /** Executes AggregationClause.minCount and reports hiddenGroups. */
1318
1502
  metricMinCount?: boolean;
1503
+ /** Also executes an object minCount: distinct values or a sum per group. */
1504
+ metricMinCountMeasures?: boolean;
1319
1505
  maxRows: number;
1320
1506
  maxGroups: number;
1321
1507
  maxPopulation: number;
1322
1508
  profile: string;
1323
1509
  }
1324
1510
  interface QueryRequestV3 {
1511
+ /** The table's host-owned state when `hostQuery` is configured. */
1512
+ hostState?: HostQueryState;
1325
1513
  version: 3;
1326
1514
  profile: string;
1327
1515
  now: number;
@@ -1380,6 +1568,8 @@ interface DistinctValuesQuery {
1380
1568
  search: string;
1381
1569
  /** Max suggestions to return (default chosen by the adapter, ~50). */
1382
1570
  limit?: number;
1571
+ /** The table's host-owned state when `hostQuery` is configured. */
1572
+ hostState?: HostQueryState;
1383
1573
  }
1384
1574
  interface DistinctValuesResult {
1385
1575
  values: string[];
@@ -1438,6 +1628,10 @@ interface SavedQuery {
1438
1628
  interface StorageAdapter {
1439
1629
  /** Optional authenticated server store. Ordinary URL sync never calls it. */
1440
1630
  snapshots?: QuerySnapshotStore;
1631
+ /** True when last-used and named queries keep `QueryState.hostState`
1632
+ * exactly. A table with `hostQuery` refuses to save through an adapter
1633
+ * without it rather than store a table-only query. */
1634
+ storesHostState?: boolean;
1441
1635
  loadLast(key: string): Promise<QueryState | null>;
1442
1636
  saveLast(key: string, query: QueryState): Promise<void>;
1443
1637
  listSaved(key: string): Promise<SavedQuery[]>;
@@ -1506,13 +1700,27 @@ declare function boxSummary(values: number[], whiskers?: "minmax" | "tukey"): {
1506
1700
  declare function histogramEdges(values: number[], bins: number): number[];
1507
1701
  declare function histogramCounts(values: number[], edges: number[]): number[];
1508
1702
 
1509
- declare const METRIC_DATE_INTERVALS: readonly ["hour", "day", "week", "month", "year"];
1703
+ declare const METRIC_DATE_INTERVALS: readonly ["hour", "day", "week", "month", "year", "hourOfDay", "dayOfWeek"];
1704
+ declare const METRIC_CYCLE_INTERVALS: readonly ["hourOfDay", "dayOfWeek"];
1705
+ /** Whether an interval is cyclic: keyed by slot number, not by date. */
1706
+ declare function isMetricCycle(interval: string | undefined): interval is MetricCycleInterval;
1707
+ /** Every slot of a cyclic interval, in order: 0–23 or 1–7 (ISO, Monday 1). */
1708
+ declare function metricCycleSlots(interval: MetricCycleInterval): number[];
1709
+ /** The calendar interval one occurrence of a slot spans: its hour or day.
1710
+ * Calendar intervals are their own unit. */
1711
+ declare function metricCalendarUnit(interval: MetricDateGrouping["interval"]): Exclude<MetricDateGrouping["interval"], MetricCycleInterval>;
1712
+ /** The slot an instant occupies in `timeZone`: its local wall-clock hour
1713
+ * (0–23), or its local ISO weekday (1 = Monday … 7 = Sunday). */
1714
+ declare function metricCycleSlot(time: number, interval: MetricCycleInterval, timeZone?: string): number;
1510
1715
  /** Strict calendar input; timestamps require an explicit offset. */
1511
1716
  declare function metricDateTime(value: MetricValue, timeZone?: string): number;
1512
- declare function metricDateFloor(time: number, interval: MetricDateGrouping["interval"], timeZone?: string): number;
1513
- declare function metricDateNext(time: number, interval: MetricDateGrouping["interval"], timeZone?: string): number;
1717
+ declare function metricDateFloor(time: number, cycleOrInterval: MetricDateGrouping["interval"], timeZone?: string): number;
1718
+ declare function metricDateNext(time: number, cycleOrInterval: MetricDateGrouping["interval"], timeZone?: string): number;
1514
1719
  /** A date-only Through value includes the whole local day, even for hourly groups. */
1515
1720
  declare function metricCustomEndTime(value: string, timeZone?: string): number;
1721
+ /** An IANA timezone identifier this runtime knows, such as America/Denver or
1722
+ * UTC. Fixed offsets ("+02:00") are refused: they do not follow DST. */
1723
+ declare function isGroupingTimeZone(value: unknown): value is string;
1516
1724
  declare function validateDateGrouping(config: MetricDateGrouping): void;
1517
1725
  /** Only conjunctive bounds prove a domain; OR alternatives are not bounds. */
1518
1726
  declare function metricDateRange(config: MetricDateGrouping, query: QueryState, observed: readonly number[], now: number, canonical: (field: string) => string): [number, number] | undefined;
@@ -1522,8 +1730,15 @@ declare const MAX_METRIC_WINDOW_PERIODS = 1000;
1522
1730
  declare function hasMetricSeries(c: AggregationClause): boolean;
1523
1731
  /** Throws when a clause's window or share cannot be computed exactly. */
1524
1732
  declare function validateMetricSeries(c: AggregationClause, plan: FormulaPlan): void;
1733
+ /** The conjunctive bounds on a date-grouped clause's field, from the query's
1734
+ * and the metric's own filters: [lower, upper), infinite where absent. */
1735
+ declare function metricDateBounds(c: AggregationClause, query: QueryState, schema: FieldSchema, now: number): {
1736
+ lower: number;
1737
+ upper: number;
1738
+ };
1525
1739
  /** The whole intervals inside the conjunctive bounds on the date field (the
1526
- * query's and the metric's own), ending by `now`: [start, end). */
1740
+ * query's and the metric's own), ending by `now`: [start, end). A cyclic
1741
+ * interval's intervals are its hours or days. */
1527
1742
  declare function wholeIntervalSpan(c: AggregationClause, query: QueryState, schema: FieldSchema, now: number): {
1528
1743
  start?: number;
1529
1744
  end: number;
@@ -1552,9 +1767,13 @@ interface MetricSeriesPlan {
1552
1767
  * of every group. With a window, both are windowed first.
1553
1768
  * - **Whole intervals.** `partialIntervals: "exclude"` narrows the metric to
1554
1769
  * the intervals the query bounds and `now` leave whole.
1770
+ * - **Occurrences.** A cyclic slot with `dateGrouping.occurrence` runs the
1771
+ * metric per whole occurrence (one calendar hour or day), then summarises
1772
+ * each slot: the mean of its occurrence values, or a box over them.
1555
1773
  *
1556
- * `sort`, `groupLimit` and `minCount` (counting a window's rows) apply to the
1557
- * combined buckets. Windowed and share results have no Other remainder. */
1774
+ * `sort`, `groupLimit` and `minCount` (counting a window's rows, or summing a
1775
+ * field over the window) apply to the combined buckets. Windowed and share
1776
+ * results have no Other remainder. */
1558
1777
  declare function planMetricSeries(query: QueryState, schema: FieldSchema, options?: MetricSeriesOptions): MetricSeriesPlan | undefined;
1559
1778
 
1560
1779
  interface SavedPropertyView {
@@ -1596,6 +1815,12 @@ declare function sourceDependencies<Row>(query: QueryState, schema: FieldSchema<
1596
1815
  * - A date-grouped key becomes `>= start` and `< next`, using the clause's
1597
1816
  * interval and timezone. A windowed point starts at its window's first
1598
1817
  * interval, or has no lower bound for a running value.
1818
+ * - An hour-of-day or day-of-week slot selects its occurrences inside the
1819
+ * date field's bounds (whole ones with `occurrence` or whole intervals):
1820
+ * `>= first`, `< last end` and, for each gap between occurrences, an OR
1821
+ * group `< gap start` or `>= gap end`. Without a lower and an upper bound on
1822
+ * the date field, or when the filter would exceed the query's predicate
1823
+ * budget (about 48 occurrences), the result is null.
1599
1824
  * - A histogram bin (`bucket.bin`) adds `>= min` and `< max` (`<= max` for
1600
1825
  * the final bin) on the distribution input, which must be a field reference.
1601
1826
  * Box cohorts are their group keys.
@@ -1613,7 +1838,8 @@ declare function inspectBucketQuery(query: QueryState, bucket: AggregationBucket
1613
1838
  *
1614
1839
  * Starts from the grouping source, as leaving the grouping stage does, so its
1615
1840
  * WHERE, columns, order and item details are kept. Each key adds `=` (or
1616
- * `is_null` for a null key) and the offset resets. */
1841
+ * `is_null` for a null key), a calendar key `>= start` and `< end` of its
1842
+ * interval, and the offset resets. */
1617
1843
  declare function groupSourceQuery(query: QueryState, group: GroupedRow, schema: FieldSchema): QueryState | null;
1618
1844
 
1619
1845
  /** Host routes for query-kind links, keyed by `LinkSpec.to.target`. Each
@@ -1640,4 +1866,4 @@ declare function groupLinkQuery(query: QueryState, value: GroupLinkValue): Query
1640
1866
  * routes and unresolvable values return `href: null` with a `problem`. */
1641
1867
  declare function resolveGroupLink(query: QueryState, value: GroupLinkValue, targets?: LinkTargets): ResolvedGroupLink;
1642
1868
 
1643
- export { AGG_OPS_BY_TYPE, AGG_OPS_NEEDING_FIELD, type AggOp, type AggregateConfig, type AggregationBucket, type AggregationClause, type AggregationRequest, type AggregationResult, type AggregationResultEntry, type Align, type ApplyPatchOptions, type ApplyResult, type BackendField, COMPUTED_PREFIX, type CellDisplay, type CellRenderer, type ColumnPreview, type ComputedCellError, type ComputedColumn, type ComputedColumnDraft, type ComputedColumnStore, type ComputedExecution, type ComputedFieldCapabilities, type DerivedField, type DistinctValuesQuery, type DistinctValuesResult, EMPTY_QUERY, FORMULA_FUNCTIONS, type FetchRowsResult, type FetchRowsResultV2, type FieldDef, type FieldOrigin, type FieldRelationship, type FieldSchema, type FieldSource, type FieldStats, type FieldType, type FilterConfig, type FilterOp, type FilterValues, type ForeignKey, type FormulaDiagnostic, FormulaError, type FormulaFunction, type FormulaNode, type FormulaPlan, type FormulaResult, type FormulaType, type FormulaValue, GROUP_ID_FIELD, GROUP_LINK_RENDER, type GroupLinkValue, type GroupedRow, type GroupingDefinition, type GroupingModel, type GroupingState, type GroupingView, ITEM_DETAILS_COLUMN, type ItemDetailMode, type ItemDetailsState, type ItemPageOptions, type ItemPropertyMode, type JsonCellDisplay, type LinkDestination, type LinkSpec, type LinkTargets, MAX_AGGREGATIONS, MAX_GROUP_BY_FIELDS, MAX_METRIC_WINDOW_PERIODS, MAX_ORDER_BY_TERMS, MAX_PROPERTIES, MAX_QUERY_LIMIT, MAX_QUERY_OFFSET, MAX_QUERY_STATE_BYTES, MAX_QUERY_TOKEN_LENGTH, MAX_RELATIVE_TIME_MS, MAX_REPRESENTATIVE_SORTS, MAX_RESULT_GROUPS, MAX_SELECT_COLUMNS, MAX_SUMMARY_COLUMNS, MAX_WHERE_CLAUSES, METRIC_DATE_INTERVALS, METRIC_FUNCTIONS, type MetricAxisScale, type MetricBoxSummary, type MetricCapabilities, type MetricDateGrouping, type MetricDiagnostic, type MetricDisplay, type MetricDistribution, type MetricDistributionResult, type MetricEvaluationOptions, type MetricHistogramBin, type MetricKey, type MetricLayout, type MetricPlan, type MetricPopulationSupport, type MetricQuery, type MetricReductionOptions, type MetricScope, type MetricSeriesOptions, type MetricSeriesPlan, type MetricShare, type MetricSort, type MetricValue, type MetricValueFormat, type MetricWindow, NULLARY_OPS, OPS_BY_TYPE, OP_LABEL, type ObjectReference, type ObjectTypeDefinition, type OpChoice, type OpPair, type OrGroup, type OrderByClause, type PreviewGroup, type PropertyFieldConfig, type PropertyFormat, type PropertySelection, type PropertyViewState, type PropertyViewStorage, type QueryCapabilitiesV3, QueryDecodeError, type QueryEvaluationOptions, type QueryFacet, type QueryLink, type QueryLinkOptions, type QueryLinkService, type QueryPatch, type QueryPatchMatch, type QueryRequestV3, type QueryResultV3, type QuerySnapshot, type QuerySnapshotCache, QuerySnapshotHttpError, type QuerySnapshotHttpErrorCode, type QuerySnapshotStore, type QueryState, type RegexInspection, type RelationshipAdapter, type RepresentativeOrder, type RepresentativeRow, type ResolvedGroupLink, type ResolvedObjectReference, type RowComputedValues, type RowId, type SavedPropertyView, type SavedQuery, type SelectColumn, type SelectConfig, type ServerQuery, type ServerQueryV2, type SetFilterMetadata, type SetFilterMode, type SetFilterTarget, type SortConfig, type SourceDependencies, type StorageAdapter, type SummaryColumn, type SummaryOp, type Transport, type WhereClause, type WhereTerm, aggOpAllowedForType, aggOpNeedsField, aggOpsForField, applyAggregations, applyPatch, applyQuery, boxSummary, coerceValue, compareMetricValues, compileFormula, compileMetric, computedFieldName, createGroupingModel, createPropertyView, createQueryLinkService, createSetFilter, decodeQuery, decodeQueryStrict, discoverFieldRelationships, encodeQuery, evaluateMetricReductions, evaluateMetrics, exitGrouping, filterValues, formulaRuntime, groupLinkQuery, groupPreview, groupSourceQuery, hasMetricSeries, hasRegex, histogramCounts, histogramEdges, httpComputedColumnStore, httpQuerySnapshotStore, indexFields, inspectBucketQuery, isComputedCellError, isComputedField, isFilterable, isGroupLinkField, isGroupLinkValue, isGroupable, isMeasurable, isNegativePredicate, isOrGroup, isPushdownFilter, isSelectable, isSortable, itemPageFields, jsonPropertyViewStorage, loadSchema, localPropertyViewStorage, localQuerySnapshotCache, localStorageAdapter, mapSetFilterValues, matchPatch, matchesClause, memoryComputedColumnStore, memoryPropertyViewStorage, memoryQuerySnapshotCache, memoryStorageAdapter, metricAggregatePlans, metricComputationKey, metricCustomEndTime, metricDateFloor, metricDateNext, metricDateRange, metricDateTime, metricDependencies, metricExpression, metricPlans, metricPopulationError, negateClause, normalizePropertyFormat, normalizePropertyView, normalizeQueryState, objectReferenceKey, opAllowedForType, opPairsForField, opsForField, parseRelativeDuration, percentile, planMetricSeries, predicatesOf, prepareGrouping, queriesEqual, readFieldValue, readObjectReference, readSetFilter, reduceMetricValues, removePatch, renderItemPageTemplate, resolveFieldName, resolveGroupLink, selectMetricShownRows, selectedFields, setFilterModes, setFilterTarget, sortMetricBuckets, sourceDependencies, sourceExecutionSchema, stripSetFilter, toAggregationQuery, toMetricQuery, toQueryRequestV3, toServerQuery, toServerQueryV2, validateComputedColumn, validateDateGrouping, validateItemPageTemplate, validateMetric, validateMetricSeries, validateQueryResultV3, validateQuerySnapshot, wholeIntervalSpan, withGroupingKeys, withoutGrouping, withoutLinkSummaries };
1869
+ export { AGG_OPS_BY_TYPE, AGG_OPS_NEEDING_FIELD, type AggOp, type AggregateConfig, type AggregationBucket, type AggregationClause, type AggregationRequest, type AggregationResult, type AggregationResultEntry, type Align, type ApplyPatchOptions, type ApplyResult, type BackendField, COMPUTED_PREFIX, type CalendarGroupKey, type CellDisplay, type CellRenderer, type ColumnPreview, type ComputedCellError, type ComputedColumn, type ComputedColumnDraft, type ComputedColumnStore, type ComputedExecution, type ComputedFieldCapabilities, type DerivedField, type DistinctValuesQuery, type DistinctValuesResult, EMPTY_QUERY, FORMULA_FUNCTIONS, type FetchRowsResult, type FetchRowsResultV2, type FieldDef, type FieldOrigin, type FieldRelationship, type FieldSchema, type FieldSource, type FieldStats, type FieldType, type FilterConfig, type FilterOp, type FilterValues, type ForeignKey, type FormulaDiagnostic, FormulaError, type FormulaFunction, type FormulaNode, type FormulaPlan, type FormulaResult, type FormulaType, type FormulaValue, GROUP_ID_FIELD, GROUP_KEY_INTERVALS, GROUP_LINK_RENDER, type GroupKey, type GroupLinkValue, type GroupedRow, type GroupingDefinition, type GroupingModel, type GroupingState, type GroupingView, type HostQueryState, ITEM_DETAILS_COLUMN, type ItemDetailMode, type ItemDetailsState, type ItemPageOptions, type ItemPropertyMode, type JsonCellDisplay, type LinkDestination, type LinkSpec, type LinkTargets, MAX_AGGREGATIONS, MAX_GROUP_BY_FIELDS, MAX_HOST_QUERY_PARAMS, MAX_HOST_QUERY_STATE_BYTES, MAX_HOST_QUERY_VALUES, MAX_HOST_QUERY_VALUE_LENGTH, MAX_METRIC_WINDOW_PERIODS, MAX_ORDER_BY_TERMS, MAX_PROPERTIES, MAX_QUERY_LIMIT, MAX_QUERY_OFFSET, MAX_QUERY_STATE_BYTES, MAX_QUERY_TOKEN_LENGTH, MAX_RELATIVE_TIME_MS, MAX_REPRESENTATIVE_SORTS, MAX_RESULT_GROUPS, MAX_SELECT_COLUMNS, MAX_SUMMARY_COLUMNS, MAX_WHERE_CLAUSES, METRIC_CYCLE_INTERVALS, METRIC_DATE_INTERVALS, METRIC_FUNCTIONS, type MetricAxisScale, type MetricBoxSummary, type MetricCalendarInterval, type MetricCapabilities, type MetricCycleInterval, type MetricDateGrouping, type MetricDateOccurrence, type MetricDiagnostic, type MetricDisplay, type MetricDistribution, type MetricDistributionResult, type MetricEvaluationOptions, type MetricHistogramBin, type MetricKey, type MetricLayout, type MetricMinCountOf, type MetricPlan, type MetricPopulationSupport, type MetricQuery, type MetricReductionOptions, type MetricScope, type MetricSeriesOptions, type MetricSeriesPlan, type MetricShare, type MetricSort, type MetricValue, type MetricValueFormat, type MetricWindow, NULLARY_OPS, OPS_BY_TYPE, OP_LABEL, type ObjectReference, type ObjectTypeDefinition, type OpChoice, type OpPair, type OrGroup, type OrOfAndsGroup, type OrderByClause, type PreviewGroup, type PropertyFieldConfig, type PropertyFormat, type PropertySelection, type PropertyViewState, type PropertyViewStorage, type QueryCapabilitiesV3, QueryDecodeError, type QueryEvaluationOptions, type QueryFacet, type QueryLink, type QueryLinkOptions, type QueryLinkService, type QueryPatch, type QueryPatchMatch, type QueryRequestV3, type QueryResultV3, type QuerySnapshot, type QuerySnapshotCache, QuerySnapshotHttpError, type QuerySnapshotHttpErrorCode, type QuerySnapshotStore, type QueryState, type RegexInspection, type RelationshipAdapter, type RepresentativeOrder, type RepresentativeRow, type ResolvedGroupLink, type ResolvedObjectReference, type RowComputedValues, type RowId, type SavedPropertyView, type SavedQuery, type SelectColumn, type SelectConfig, type ServerQuery, type ServerQueryV2, type SetFilterMetadata, type SetFilterMode, type SetFilterTarget, type SortConfig, type SourceDependencies, type StorageAdapter, type SummaryColumn, type SummaryOp, type Transport, type WhereBranch, type WhereClause, type WhereConjunction, type WhereTerm, aggOpAllowedForType, aggOpNeedsField, aggOpsForField, applyAggregations, applyPatch, applyQuery, boxSummary, branchesOf, calendarGroupKey, coerceValue, compareMetricValues, compileFormula, compileMetric, computedFieldName, createGroupingModel, createPropertyView, createQueryLinkService, createSetFilter, decodeQuery, decodeQueryStrict, discoverFieldRelationships, encodeQuery, evaluateMetricReductions, evaluateMetrics, exitGrouping, filterValues, formulaRuntime, groupKeyField, groupKeyFields, groupKeyTerms, groupLinkQuery, groupPreview, groupSourceQuery, hasMetricSeries, hasRegex, histogramCounts, histogramEdges, httpComputedColumnStore, httpQuerySnapshotStore, indexFields, inspectBucketQuery, isCalendarGroupKey, isComputedCellError, isComputedField, isFilterable, isGroupLinkField, isGroupLinkValue, isGroupable, isGroupingTimeZone, isMeasurable, isMetricCycle, isNegativePredicate, isOrGroup, isOrOfAndsGroup, isPushdownFilter, isSelectable, isSortable, isWhereConjunction, isWhereGroup, itemPageFields, jsonPropertyViewStorage, loadSchema, localPropertyViewStorage, localQuerySnapshotCache, localStorageAdapter, mapSetFilterValues, matchPatch, matchesClause, memoryComputedColumnStore, memoryPropertyViewStorage, memoryQuerySnapshotCache, memoryStorageAdapter, metricAggregatePlans, metricCalendarUnit, metricComputationKey, metricCustomEndTime, metricCycleSlot, metricCycleSlots, metricDateBounds, metricDateFloor, metricDateNext, metricDateRange, metricDateTime, metricDependencies, metricExpression, metricMinCount, metricMinCountKeeps, metricMinCountMeasure, metricMinCountPlan, metricMinCountText, metricPlans, metricPopulationError, negateClause, normalizePropertyFormat, normalizePropertyView, normalizeQueryState, objectReferenceKey, occurrenceDistribution, opAllowedForType, opPairsForField, opsForField, parseHostQueryState, parseRelativeDuration, percentile, planMetricSeries, predicatesOf, prepareGrouping, queriesEqual, readFieldValue, readObjectReference, readSetFilter, reduceMetricValues, removePatch, renderItemPageTemplate, resolveFieldName, resolveGroupLink, selectMetricShownRows, selectedFields, setFilterModes, setFilterTarget, sortMetricBuckets, sourceDependencies, sourceExecutionSchema, stripSetFilter, toAggregationQuery, toMetricQuery, toQueryRequestV3, toServerQuery, toServerQueryV2, validateComputedColumn, validateDateGrouping, validateItemPageTemplate, validateMetric, validateMetricSeries, validateQueryResultV3, validateQuerySnapshot, wholeIntervalSpan, withGroupingKeys, withoutGrouping, withoutLinkSummaries };