@pythia-software/query-table-core 0.9.9 → 1.0.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.
package/dist/index.d.ts CHANGED
@@ -89,7 +89,335 @@ type CellDisplay = JsonCellDisplay | ({
89
89
  lines?: number;
90
90
  };
91
91
 
92
+ /** Filter operators. Every value can be NULL, so is_null/is_not_null are valid for every field type. */
93
+ type FilterOp = "=" | "!=" | ">" | ">=" | "<" | "<=" | "contains" | "starts_with" | "ends_with" | "matches_regex" | "not_matches_regex" | "length_gt" | "length_lt" | "length_eq" | "includes" | "is_null" | "is_not_null";
94
+ /** One predicate. `value` is the raw string the UI captured; executors coerce it by the field's declared type. Datetime comparisons also accept signed offsets such as "-1h" relative to `now`. `negated` is a null-exclusive NOT, set only for ops without a complement. */
95
+ interface WireWhereClause {
96
+ field: string;
97
+ op: FilterOp;
98
+ value: string;
99
+ negated?: boolean;
100
+ }
101
+ /** One branch of an OR group that ANDs several literals. Branches do not nest. */
102
+ interface WireWhereConjunction {
103
+ all: WireWhereClause[];
104
+ }
105
+ /** One alternative of an OR group: a literal or a conjunction. */
106
+ type WireWhereBranch = WireWhereClause | WireWhereConjunction;
107
+ /** A disjunction of literals or conjunctions: (a AND b) OR c. */
108
+ interface WireOrGroup {
109
+ any: WireWhereBranch[];
110
+ }
111
+ /** One conjunct of a WHERE: a literal or an OR group. A WHERE is the AND of its terms; every literal counts against the 100-predicate budget. */
112
+ type WireWhereTerm = WireWhereClause | WireOrGroup;
113
+ /** Sort by the first capture group of a regex match (or the whole match); a non-match is NULL. */
114
+ interface RegexExtract {
115
+ regex: string;
116
+ }
117
+ /** One ORDER BY term; array order is sort priority. */
118
+ interface OrderByClause {
119
+ field: string;
120
+ dir: "asc" | "desc";
121
+ /** NULL placement; omitted is last. */
122
+ nulls?: "first" | "last";
123
+ extract?: RegexExtract;
124
+ }
125
+ /** A single aggregate operation; only count needs no measure field. */
126
+ type AggOp = "count" | "count_distinct" | "sum" | "avg" | "min" | "max";
127
+ type MetricScope = "allMatching" | "shownRows";
128
+ /** Calendar grouping of the first group key. Calendar intervals key a bucket by its start instant; hourOfDay (0-23) and dayOfWeek (ISO 1-7) key a slot by number. Whole intervals and occurrences are planned by the client into plain calendar metrics and never cross the wire. */
129
+ interface WireMetricDateGrouping {
130
+ field: string;
131
+ interval: "hour" | "day" | "week" | "month" | "year" | "hourOfDay" | "dayOfWeek";
132
+ /** IANA identifier; omitted is UTC. */
133
+ timeZone?: string;
134
+ /** Add a bucket for every interval of the range. */
135
+ includeEmpty: boolean;
136
+ range: "query" | "observed" | "custom";
137
+ start?: string;
138
+ end?: string;
139
+ }
140
+ /** The only display state on the wire: scatter pairs `expression` with `expressionY`. */
141
+ interface MetricDisplayHint {
142
+ kind: "scatter";
143
+ }
144
+ interface WireMetricSort {
145
+ key: "value" | "y" | "count" | "samples" | `group${number}`;
146
+ dir: "asc" | "desc";
147
+ nulls?: "first" | "last";
148
+ }
149
+ /** A box or histogram over `input` per group instead of a scalar value. */
150
+ interface MetricDistribution {
151
+ kind: "box" | "histogram";
152
+ input: string;
153
+ whiskers?: "minmax" | "tukey";
154
+ bins?: number;
155
+ }
156
+ interface MetricMinCountDistinct {
157
+ min: number;
158
+ distinct: string;
159
+ }
160
+ interface MetricMinCountSum {
161
+ min: number;
162
+ sum: string;
163
+ }
164
+ /** Drop small groups before sorting, groupLimit and Other: a number counts rows; an object counts a field's distinct non-null values or sums a numeric field. Removed groups are reported as hiddenGroups. */
165
+ type MetricMinCount = number | MetricMinCountDistinct | MetricMinCountSum;
166
+ /** One metric as sent: an AggregationClause without its presentation (label, layout, display other than scatter, window, share). */
167
+ interface MetricSpecV3 {
168
+ dateGrouping?: WireMetricDateGrouping;
169
+ display?: MetricDisplayHint;
170
+ /** A formula over aggregates; replaces op/field. */
171
+ expression?: string;
172
+ /** The scatter y expression. */
173
+ expressionY?: string;
174
+ scope?: MetricScope;
175
+ sort?: WireMetricSort[];
176
+ groupLimit?: number;
177
+ distribution?: MetricDistribution;
178
+ /** Echoed by the result entry. */
179
+ id: string;
180
+ op: AggOp;
181
+ /** Measure field; omitted only for count. */
182
+ field?: string;
183
+ groupBy: string[];
184
+ /** The metric's own predicate, ANDed with the table WHERE. */
185
+ where?: WireWhereTerm[];
186
+ minCount?: MetricMinCount;
187
+ }
188
+ /** A grouping key that buckets a datetime field by calendar interval, keyed by the interval's start instant. Weeks start on Monday. */
189
+ interface CalendarGroupKey {
190
+ field: string;
191
+ interval: "hour" | "day" | "week" | "month" | "year";
192
+ /** IANA identifier; omitted is UTC. */
193
+ timeZone?: string;
194
+ }
195
+ /** A field name (group by exact value) or a calendar key. */
196
+ type GroupKey = string | CalendarGroupKey;
197
+ /** One summary column of a grouping stage. Display and link columns are client-only. */
198
+ interface WireSummaryColumn {
199
+ id: string;
200
+ op: "count" | "count_distinct" | "sum" | "avg" | "min" | "max" | "row" | "formula";
201
+ field?: string;
202
+ expression?: string;
203
+ label?: string;
204
+ }
205
+ /** The ordering that picks each group's representative row for ROW summaries. */
206
+ interface WireRepresentativeRow {
207
+ orderBy: OrderByClause[];
208
+ }
209
+ /** One grouping stage over the complete source population; the result stage's where is HAVING. */
210
+ interface WireGroupingDefinition {
211
+ keys: GroupKey[];
212
+ summaries: WireSummaryColumn[];
213
+ representative: WireRepresentativeRow | null;
214
+ }
215
+ /** Query state a host owns and registers with useQueryTable({ hostQuery }), such as a keyword clause it runs itself. It travels with the table query through saves, links, history and resets. params are named lists of strings, like URL search parameters, sorted by name; the host interprets them. Query Table passes it through uninterpreted. Version 0 marks a payload that could not be read and is always rejected on restore. */
216
+ interface HostQueryState {
217
+ version: number;
218
+ params: Record<string, string[]>;
219
+ }
220
+ /** Distinct values of one server-filterable field: a literal, case-insensitive substring match on the value as text (empty matches all), ordered by count desc then value asc. textarray fields contribute each element. */
221
+ interface DistinctRequestV3 {
222
+ field: string;
223
+ search: string;
224
+ limit: number;
225
+ }
226
+ /** The server's query handshake. */
227
+ interface QueryCapabilitiesV3 {
228
+ regexSourceFilters?: boolean;
229
+ regexAggregateExpressions?: boolean;
230
+ /** Executes MetricSpec.where. */
231
+ metricFilters?: boolean;
232
+ /** Executes a numeric minCount and reports hiddenGroups. */
233
+ metricMinCount?: boolean;
234
+ /** Also executes an object minCount. */
235
+ metricMinCountMeasures?: boolean;
236
+ version: 3;
237
+ groupedRows: boolean;
238
+ calendarGrouping: boolean;
239
+ /** Executes the hourOfDay and dayOfWeek intervals. */
240
+ calendarCycles?: boolean;
241
+ /** Executes calendar grouping keys. */
242
+ calendarGroupKeys?: boolean;
243
+ computedSourceFilters: boolean;
244
+ regex: boolean;
245
+ maxRows: number;
246
+ maxGroups: number;
247
+ maxPopulation: number;
248
+ profile: string;
249
+ }
250
+ /** One v3 query: rows, metrics, groups or distinct values. source.where runs before grouping; result selects, filters (HAVING) and pages. */
251
+ interface QueryRequestV3 {
252
+ version: 3;
253
+ profile: string;
254
+ /** Evaluation clock, epoch milliseconds. */
255
+ now: number;
256
+ /** Computed definition id to the revision the client planned with. */
257
+ expectedRevisions: Record<string, string>;
258
+ planToken?: string;
259
+ snapshot?: string;
260
+ source: ServerQuery;
261
+ result: ServerQuery;
262
+ grouping?: WireGroupingDefinition;
263
+ rows: boolean;
264
+ metrics: MetricSpecV3[];
265
+ /** Filter-value suggestions over source.where; requires rows false, no metrics and no grouping. */
266
+ distinct?: DistinctRequestV3;
267
+ /** Host-owned state, passed through uninterpreted: any JSON object. Query Table's TypeScript client sends a HostQueryState ({ version, params }); a host defines what its own clients send. */
268
+ hostState?: HostQueryState;
269
+ }
270
+ /** A metric value or group key: a number for count/sum/avg, the column's value for min/max; null when undefined. Go carries it as any, Swift as JSONValue. */
271
+ type MetricValue = number | string | boolean | null;
272
+ interface MetricBoxSummary {
273
+ n: number;
274
+ min: number;
275
+ q1: number;
276
+ median: number;
277
+ q3: number;
278
+ max: number;
279
+ mean: number;
280
+ /** Lower whisker. */
281
+ low: number;
282
+ /** Upper whisker. */
283
+ high: number;
284
+ outliers: number[];
285
+ outlierCount: number;
286
+ whiskers: "minmax" | "tukey";
287
+ method: "exact-linear";
288
+ }
289
+ interface MetricBoxDistribution {
290
+ kind: "box";
291
+ /** null when the group has no numeric samples. */
292
+ summary: MetricBoxSummary | null;
293
+ }
294
+ /** Bin i is edges[i] <= value < edges[i+1]; the final bin includes its upper edge. */
295
+ interface MetricHistogramDistribution {
296
+ kind: "histogram";
297
+ edges: number[];
298
+ counts: number[];
299
+ n: number;
300
+ }
301
+ type MetricDistributionResult = MetricBoxDistribution | MetricHistogramDistribution;
302
+ /** One group of a metric result. `keys` has one entry per groupBy field ([] for a grand total); a null key is the NULL bucket. */
303
+ interface MetricBucketV3 {
304
+ distribution?: MetricDistributionResult;
305
+ /** Distribution inputs that were NULL. */
306
+ nullCount?: number;
307
+ /** Distribution inputs that were errors. */
308
+ inputErrorCount?: number;
309
+ keys: MetricValue[];
310
+ /** The metric: a number for count/sum/avg, a column value for min/max, null when undefined. Swift reads an omitted value as null, as before. */
311
+ value: MetricValue;
312
+ /** COUNT(*) of rows in the group. */
313
+ count: number;
314
+ error?: string;
315
+ /** The scatter y value. */
316
+ y?: MetricValue;
317
+ yError?: string;
318
+ }
319
+ /** One metric's result, in request order. */
320
+ interface MetricResultV3 {
321
+ id: string;
322
+ buckets: MetricBucketV3[];
323
+ scope?: MetricScope;
324
+ processedRows?: number;
325
+ /** Groups before groupLimit, excluding hidden groups. */
326
+ groupCount?: number;
327
+ coverage?: "exact" | "partial";
328
+ /** The metric could not be computed; siblings are unaffected. */
329
+ error?: string;
330
+ /** The machine-readable code of error; present with it. A newer server may send a code this client does not know. */
331
+ errorCode?: ErrorCode | (string & {});
332
+ /** Groups removed by minCount; present whenever it is set. */
333
+ hiddenGroups?: number;
334
+ /** The exact omitted additive quantity beyond groupLimit, when an executor computes it. */
335
+ other?: MetricBucketV3;
336
+ }
92
337
  type FieldType = "text" | "number" | "enum" | "datetime" | "bool" | "textarray";
338
+ /** What a canonical computed field may do in a view. Hints for client planning, never authorization. */
339
+ interface ComputedFieldCapabilities {
340
+ /** Host-approved canonical predicates; omitted is closed. */
341
+ filter?: boolean;
342
+ type: FieldType;
343
+ select: boolean;
344
+ sort: boolean;
345
+ measure: boolean;
346
+ group: boolean;
347
+ reason?: string;
348
+ }
349
+ /** The execution envelope: profile, token, snapshot, resolved computed revisions and capabilities. A fingerprint is not authorization. */
350
+ interface ComputedExecution {
351
+ profile: string;
352
+ /** Empty without a handshake. Swift reads an omitted token as empty, as before. */
353
+ planToken: string;
354
+ resolvedRevisions: Record<string, string>;
355
+ fields: Record<string, ComputedFieldCapabilities>;
356
+ fingerprint?: string;
357
+ snapshot?: string;
358
+ }
359
+ interface ProjectedFieldV3 {
360
+ name: string;
361
+ type: string;
362
+ }
363
+ /** The result's schema: grouped results use the group identity field. */
364
+ interface ProjectedSchemaV3 {
365
+ name: string;
366
+ idField: string;
367
+ fields: ProjectedFieldV3[];
368
+ }
369
+ interface DistinctResultV3 {
370
+ /** Non-NULL matches as text, at most limit. */
371
+ values: string[];
372
+ hasMore: boolean;
373
+ /** The population has a NULL (textarray: NULL or empty), whatever the search. */
374
+ hasNull: boolean;
375
+ }
376
+ /** The answer to one QueryRequestV3. Row cells are JSON scalars, arrays (textarray) or {"computedError": code}. */
377
+ interface QueryResultV3 {
378
+ sourceTotal: number;
379
+ version: 3;
380
+ now: number;
381
+ rows: (Record<string, unknown>)[];
382
+ total: number;
383
+ schema: ProjectedSchemaV3;
384
+ metrics: MetricResultV3[];
385
+ execution: ComputedExecution;
386
+ /** Present exactly when the request has distinct. */
387
+ distinct?: DistinctResultV3;
388
+ }
389
+ /** One stage (source or result) of a request. It has exactly these keys; view-only state never crosses the wire. */
390
+ interface ServerQuery {
391
+ /** Field names to return. */
392
+ select: string[];
393
+ /** Pushdown predicates (CNF). */
394
+ where: WireWhereTerm[];
395
+ /** Server-sortable terms, remapped through FieldDef.sort.field. */
396
+ orderBy: OrderByClause[];
397
+ limit: number;
398
+ offset: number;
399
+ }
400
+ /** Every machine-readable error code the server or a client can produce. x-codes gives each code's HTTP status (null: never sent by a server), whether a retry can succeed (yes, no, or refresh: after refreshing the handshake or reloading) and its meaning; docs/errors.md is generated from it. Decoders must accept codes they do not know. */
401
+ declare const ERROR_CODES: readonly ["invalid_json", "invalid_request", "method_not_allowed", "forbidden", "not_found", "request_too_large", "conflict", "quota_exceeded", "timeout", "cancelled", "unavailable", "internal", "version", "invalid_query", "profile_mismatch", "definition_changed", "execution_expired", "definition_unavailable", "definition_invalid", "datetime_value", "residual_query", "dataset", "schema", "source_required", "resolver_required", "resolver_scope", "snapshot_transaction_required", "snapshot_validation_required", "plan_token_validation_required", "numeric_domain_required", "unknown_field", "select_required", "filter", "filter_disabled", "sort", "collation_required", "unsupported_regex", "unsupported_literal", "unsupported_type", "invalid_source_value", "numeric_range", "encoding", "identity_required", "duplicate_identity", "scope", "window_required", "syntax", "unsupported_syntax", "unsupported_function", "arity", "type_error", "aggregate_required", "aggregate_context", "aggregate_disabled", "paired_expression_required", "dependency_cycle", "invalid_metric", "duplicate_metric", "metric_sort", "distribution", "date_grouping", "unsupported_date_grouping", "min_count_grouping", "min_count_field", "min_count_distribution", "group_disabled", "grouping", "representative", "resource_limit", "complexity_limit", "dependency_limit", "expansion_limit", "source_limit", "stage_limit", "schema_limit", "capability_unsupported", "unexpanded_series", "invalid", "too_large", "unsupported_version"];
402
+ type ErrorCode = (typeof ERROR_CODES)[number];
403
+ /** One machine-readable error. */
404
+ interface QueryErrorDetail {
405
+ /** A newer server may send a code this client does not know; narrow with isErrorCode. */
406
+ code: ErrorCode | (string & {});
407
+ /** Human-readable; not stable. */
408
+ message: string;
409
+ /** The field the error is about, when there is one. */
410
+ field?: string;
411
+ /** Where in the expression source the problem starts, when a server or client reports it (UTF-16 code units in TypeScript). The Go server does not set it yet. */
412
+ offset?: number;
413
+ /** The metric the error is about, when there is one. */
414
+ metricId?: string;
415
+ }
416
+ /** The JSON body of every non-2xx response from the query, computed-columns and query-snapshots handlers (Content-Type: application/json). */
417
+ interface QueryErrorBody {
418
+ error: QueryErrorDetail;
419
+ }
420
+
93
421
  type Align = "left" | "right" | "center";
94
422
  /** A cell renderer is resolved by name against a `RenderRegistry` (in
95
423
  * @pythia-software/query-table-ui) or supplied inline. The type lives in core so FieldDef can
@@ -125,7 +453,7 @@ interface DerivedField<Row = any, V = unknown> {
125
453
  type FieldSource<Row = any, V = unknown> = BackendField | DerivedField<Row, V>;
126
454
  /** How filter-value candidates are offered. Autocomplete is the DEFAULT for
127
455
  * every field (design feedback): the value input is a combobox backed by
128
- * Transport.fetchDistinctValues, which takes a search string so large domains
456
+ * a v3 `distinct` request, which takes a search string so large domains
129
457
  * refine per keystroke on the backend. `static` is for closed domains you don't
130
458
  * want a round-trip for; `freeform` opts out of suggestions entirely. */
131
459
  type FilterValues = {
@@ -309,16 +637,14 @@ declare function formulaRuntime(ast: FormulaNode, inputs: Record<string, Formula
309
637
  kind: "call";
310
638
  }>) => FormulaResult | undefined): FormulaResult;
311
639
 
312
- type MetricValue = number | string | boolean | null;
313
640
  type MetricKey = MetricValue;
314
- type MetricScope = "allMatching" | "shownRows";
315
641
  /** Calendar intervals: each bucket is one interval on the timeline, keyed by
316
642
  * its start as an ISO instant. */
317
- type MetricCalendarInterval = "hour" | "day" | "week" | "month" | "year";
643
+ type MetricCalendarInterval = CalendarGroupKey["interval"];
318
644
  /** Cyclic intervals: each bucket is one slot of a repeating cycle, keyed by a
319
645
  * number. `hourOfDay` is the local hour, 0–23; `dayOfWeek` the ISO weekday,
320
646
  * 1 (Monday) to 7 (Sunday). */
321
- type MetricCycleInterval = "hourOfDay" | "dayOfWeek";
647
+ type MetricCycleInterval = Exclude<WireMetricDateGrouping["interval"], MetricCalendarInterval>;
322
648
  /** Summarise each cyclic slot over its occurrences: every whole day or hour
323
649
  * the slot covers inside the query's time bounds. */
324
650
  interface MetricDateOccurrence {
@@ -328,20 +654,11 @@ interface MetricDateOccurrence {
328
654
  * SUM metrics, no value for other expressions. false leaves them out. */
329
655
  includeEmpty: boolean;
330
656
  }
331
- /** Calendar grouping, currently executed over complete local populations. */
332
- interface MetricDateGrouping {
333
- field: string;
657
+ /** Calendar grouping, currently executed over complete local populations.
658
+ * The wire subset is WireMetricDateGrouping; whole intervals and occurrences
659
+ * are planned on the client. */
660
+ interface MetricDateGrouping extends WireMetricDateGrouping {
334
661
  interval: MetricCalendarInterval | MetricCycleInterval;
335
- /** IANA timezone identifier; omitted settings retain UTC behavior. */
336
- timeZone?: string;
337
- /** Add a bucket for every interval of the range, or for every slot of a
338
- * cyclic interval. */
339
- includeEmpty: boolean;
340
- /** The calendar range empty intervals fill; for a cyclic interval, the range
341
- * whose empty occurrences count. */
342
- range: "query" | "observed" | "custom";
343
- start?: string;
344
- end?: string;
345
662
  /** "exclude" leaves out intervals the query's bounds cut, and intervals that
346
663
  * have not ended by the evaluation time; omitted includes them. A cyclic
347
664
  * interval's intervals are its hours or days. */
@@ -371,15 +688,11 @@ type MetricShare = "total" | "group0";
371
688
  * non-null values of one field (like COUNT_DISTINCT), or the sum of one
372
689
  * numeric field (like SUM; nulls add nothing). Exactly one of `distinct` and
373
690
  * `sum` is set. A group whose measure is an error is kept. */
374
- type MetricMinCountOf = {
375
- min: number;
376
- distinct: string;
691
+ type MetricMinCountOf = (MetricMinCountDistinct & {
377
692
  sum?: never;
378
- } | {
379
- min: number;
380
- sum: string;
693
+ }) | (MetricMinCountSum & {
381
694
  distinct?: never;
382
- };
695
+ });
383
696
  interface MetricValueFormat {
384
697
  kind: "number" | "percent" | "duration" | "date" | "time" | "datetime";
385
698
  decimals?: number;
@@ -431,82 +744,17 @@ interface MetricLayout {
431
744
  minWidthRem: number;
432
745
  minHeightRem: number;
433
746
  }
434
- interface MetricDistribution {
435
- kind: "box" | "histogram";
436
- input: string;
437
- whiskers?: "minmax" | "tukey";
438
- bins?: number;
439
- }
440
- interface MetricSort {
441
- key: "value" | "y" | "count" | "samples" | `group${number}`;
442
- dir: "asc" | "desc";
443
- nulls?: "first" | "last";
444
- }
445
- interface MetricBoxSummary {
446
- n: number;
447
- min: number;
448
- q1: number;
449
- median: number;
450
- q3: number;
451
- max: number;
452
- mean: number;
453
- low: number;
454
- high: number;
455
- outliers: number[];
456
- outlierCount: number;
457
- whiskers: "minmax" | "tukey";
458
- method: "exact-linear";
459
- }
747
+ type MetricSort = WireMetricSort;
460
748
  /** One histogram bin: `min <= value < max`, or `<= max` for the final bin. */
461
749
  interface MetricHistogramBin {
462
750
  min: number;
463
751
  max: number;
464
752
  inclusiveMax: boolean;
465
753
  }
466
- type MetricDistributionResult = {
467
- kind: "box";
468
- summary: MetricBoxSummary | null;
469
- } | {
470
- kind: "histogram";
471
- edges: number[];
472
- counts: number[];
473
- n: number;
474
- };
475
754
  interface MetricDiagnostic extends FormulaDiagnostic {
476
755
  metricId?: string;
477
756
  code?: string;
478
757
  }
479
- /** Host must enforce snapshot against the row response; this token alone does not pin data. */
480
- interface MetricQuery {
481
- /** The table's host-owned state when `hostQuery` is configured. */
482
- hostState?: HostQueryState;
483
- snapshot?: string;
484
- profile?: string;
485
- expectedRevisions?: Record<string, string>;
486
- planToken?: string;
487
- version: 2;
488
- where: WhereTerm[];
489
- orderBy: OrderByClause[];
490
- limit: number;
491
- offset: number;
492
- metrics: AggregationClause[];
493
- diagnostics: MetricDiagnostic[];
494
- }
495
- interface MetricCapabilities {
496
- version: 2;
497
- expressions?: boolean;
498
- shownRows?: boolean;
499
- distributions?: boolean;
500
- computedFields?: boolean;
501
- /** Executes AggregationClause.where. Clauses using it are refused otherwise. */
502
- filters?: boolean;
503
- /** Executes AggregationClause.minCount and reports hiddenGroups. */
504
- minCount?: boolean;
505
- /** Also executes an object minCount: distinct values or a sum per group. */
506
- minCountMeasures?: boolean;
507
- maxGroups?: number;
508
- profile?: string;
509
- }
510
758
 
511
759
  /** Formats change presentation only; values retain their original types/units. */
512
760
  type PropertyFormat = MetricValueFormat | {
@@ -591,19 +839,7 @@ declare function discoverFieldRelationships<Row>(fields: FieldDef<Row>[], keys:
591
839
 
592
840
  /** Calendar intervals a grouping key can bucket a datetime field by. */
593
841
  declare const GROUP_KEY_INTERVALS: readonly MetricCalendarInterval[];
594
- /** A grouping key that buckets a datetime field by calendar interval: one
595
- * group per interval, keyed by the interval's start as an ISO instant. The
596
- * result column is named after the field. Intervals follow the metric
597
- * calendar (`dateGrouping`), including daylight-saving changes; weeks start
598
- * on Monday. */
599
- interface CalendarGroupKey {
600
- field: string;
601
- interval: MetricCalendarInterval;
602
- /** IANA timezone identifier; omitted means UTC. */
603
- timeZone?: string;
604
- }
605
- /** A field name (group by its exact value) or a calendar key. */
606
- type GroupKey = string | CalendarGroupKey;
842
+
607
843
  declare function isCalendarGroupKey(key: GroupKey): key is CalendarGroupKey;
608
844
  /** The source field a key reads; also the name of its result column. */
609
845
  declare function groupKeyField(key: GroupKey): string;
@@ -636,7 +872,7 @@ interface ApplyPatchOptions {
636
872
  replacing?: QueryPatch;
637
873
  }
638
874
  /** Compare a query with a patch. Both are normalized first; column widths,
639
- * `fitToScreen`, labels, metric display/layout and metric IDs are ignored.
875
+ * `fit`, labels, metric display/layout and metric IDs are ignored.
640
876
  *
641
877
  * - `active`: every owned facet matches.
642
878
  * - `modified`: some owned facet differs, but the patch is still recognizable:
@@ -813,9 +1049,6 @@ declare function prepareGrouping<Row>(rows: Row[], schema: FieldSchema<Row>, gro
813
1049
  schema: FieldSchema<GroupedRow>;
814
1050
  };
815
1051
 
816
- /** All filter operators across both source projects, unioned. Every value can
817
- * be NULL, so `is_null`/`is_not_null` are valid for every field type. */
818
- type FilterOp = "=" | "!=" | ">" | ">=" | "<" | "<=" | "contains" | "starts_with" | "ends_with" | "matches_regex" | "not_matches_regex" | "length_gt" | "length_lt" | "length_eq" | "includes" | "is_null" | "is_not_null";
819
1052
  /** A single filter predicate (a "literal" in CNF terms). `value` is always the
820
1053
  * raw string the UI captured; coercion to number/bool/date happens at
821
1054
  * apply/compile time based on the field's declared type (never on the value's
@@ -829,11 +1062,8 @@ type FilterOp = "=" | "!=" | ">" | ">=" | "<" | "<=" | "contains" | "starts_with
829
1062
  * `=`→`!=`, `is_null`→`is_not_null`, `matches_regex`→`not_matches_regex`) — see
830
1063
  * `negateClause` in ops.ts. NOT is null-exclusive: a NULL/empty value satisfies
831
1064
  * neither the predicate nor its negation, matching `not_matches_regex`. */
832
- interface WhereClause {
833
- field: string;
834
- op: FilterOp;
835
- value: string;
836
- negated?: boolean;
1065
+ interface WhereClause extends WireWhereClause {
1066
+ /** Presentation only; stripped before a request is sent. */
837
1067
  setFilter?: SetFilterMetadata;
838
1068
  }
839
1069
  type SetFilterMode = "any" | "all" | "none" | "empty";
@@ -897,22 +1127,6 @@ declare function predicatesOf(term: WhereTerm): WhereClause[];
897
1127
  * some branch matches. A literal is `[[literal]]`, an OR group one
898
1128
  * single-literal branch per member. */
899
1129
  declare function branchesOf(term: WhereTerm): WhereClause[][];
900
- /** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */
901
- interface OrderByClause {
902
- field: string;
903
- dir: "asc" | "desc";
904
- /** NULL placement. Omitted = "last" (the historical default both projects used,
905
- * preserved so old `?q=` links round-trip identically). */
906
- nulls?: "first" | "last";
907
- /** Sort by the first capture group of a regex match (or by the whole match
908
- * when the pattern has no capture group). A non-match produces NULL. Regex
909
- * syntax is interpreted by the executor (JavaScript locally, PostgreSQL on
910
- * the bundled Go backend), so portable patterns should use their common
911
- * syntax subset. */
912
- extract?: {
913
- regex: string;
914
- };
915
- }
916
1130
  /** One column in the SELECT list, plus the view state that travels with it.
917
1131
  * Order in `QueryState.select` is the left-to-right display order. */
918
1132
  interface SelectColumn {
@@ -924,11 +1138,6 @@ interface SelectColumn {
924
1138
  * and `display`; other surfaces (details, menus, metrics) keep the field's. */
925
1139
  display?: CellDisplay;
926
1140
  }
927
- /** A single aggregate operation. `count` is the only op that needs no measure
928
- * column (it counts rows); the rest reduce one column's values. The server-side
929
- * matrix (backends/go aggOpAllowed + the TS AGG_OPS_BY_TYPE) decides which ops a
930
- * field's type permits. */
931
- type AggOp = "count" | "count_distinct" | "sum" | "avg" | "min" | "max";
932
1141
  /** One optional "metric" pinned above the table: a single aggregate over a single
933
1142
  * measure column, optionally broken down by one or more group columns.
934
1143
  *
@@ -1001,18 +1210,6 @@ interface ItemDetailsState {
1001
1210
  /** Record-specific JSON presentation; independent of property instance/layout IDs. */
1002
1211
  jsonInspections?: ScopedJsonInspectionState[];
1003
1212
  }
1004
- /**
1005
- * Query state a host owns and registers with `useQueryTable({ hostQuery })`,
1006
- * such as a keyword clause it runs itself. It travels with the table query
1007
- * through saves, links, history and resets as one definition. `params` are
1008
- * named lists of strings, like URL search parameters; the host's own
1009
- * `normalize` interprets them. Version 0 marks a payload that could not be
1010
- * read, and is always rejected on restore.
1011
- */
1012
- interface HostQueryState {
1013
- version: number;
1014
- params: Record<string, string[]>;
1015
- }
1016
1213
  declare const MAX_HOST_QUERY_PARAMS = 64;
1017
1214
  declare const MAX_HOST_QUERY_VALUES = 64;
1018
1215
  declare const MAX_HOST_QUERY_VALUE_LENGTH = 4000;
@@ -1020,6 +1217,8 @@ declare const MAX_HOST_QUERY_STATE_BYTES: number;
1020
1217
  /** Validates host state and returns its canonical form (parameters sorted by
1021
1218
  * name, values in order). Throws on a malformed or oversized payload. */
1022
1219
  declare function parseHostQueryState(input: unknown): HostQueryState;
1220
+ /** Live column sizing mode; see `QueryState.fit`. */
1221
+ type FitMode = "content" | "screen";
1023
1222
  interface QueryState {
1024
1223
  /** Host-owned state registered through `useQueryTable({ hostQuery })`.
1025
1224
  * Only the top-level query carries it; a grouping source never does. */
@@ -1031,9 +1230,13 @@ interface QueryState {
1031
1230
  itemDetails?: ItemDetailsState;
1032
1231
  /** Ordered SELECT list + per-column widths. Empty = the schema's default columns. */
1033
1232
  select: SelectColumn[];
1034
- /** Refit columns to each viewer's table viewport after loading. Manual width
1035
- * changes clear this view preference; omitted/false uses stored widths. */
1036
- fitToScreen?: boolean;
1233
+ /** Live sizing for columns without an explicit `width`, refit after every
1234
+ * change to what the table shows and kept out of the query:
1235
+ * - `"content"`: each column fits its widest drawn value.
1236
+ * - `"screen"`: the columns fill each viewer's table viewport.
1237
+ * Omitted: stored or default widths. A legacy `fitToScreen: true` (whose
1238
+ * stored widths were never shown) normalizes to `"screen"` without widths. */
1239
+ fit?: FitMode;
1037
1240
  /** WHERE in conjunctive normal form: the AND of these terms, each a single
1038
1241
  * predicate or an OR group. A flat list of literals (no groups) is the common
1039
1242
  * case and the legacy shape, decoded unchanged. */
@@ -1145,10 +1348,55 @@ declare function isMeasurable(field: FieldDef): boolean;
1145
1348
  * default off, but `aggregate.groupable: true` opts any backend field in. */
1146
1349
  declare function isGroupable(field: FieldDef): boolean;
1147
1350
 
1351
+ /** Whether `value` is a code this build knows. Servers may send newer codes;
1352
+ * QueryError keeps them as strings. */
1353
+ declare const isErrorCode: (value: unknown) => value is ErrorCode;
1354
+ interface QueryErrorOptions {
1355
+ field?: string;
1356
+ offset?: number;
1357
+ metricId?: string;
1358
+ /** The HTTP status, for errors read from a response. */
1359
+ status?: number;
1360
+ /** The capability flag a client-side refusal needs. */
1361
+ capability?: keyof QueryCapabilitiesV3;
1362
+ cause?: unknown;
1363
+ }
1364
+ /** An error with a stable code, from the server (QueryErrorBody) or from a
1365
+ * client-side refusal before any request is sent. Messages are for people;
1366
+ * match on `code`. */
1367
+ declare class QueryError extends Error {
1368
+ /** An ErrorCode, or a newer code this build does not know (narrow with
1369
+ * isErrorCode before an exhaustive switch). */
1370
+ readonly code: ErrorCode | (string & {});
1371
+ readonly field?: string;
1372
+ readonly offset?: number;
1373
+ readonly metricId?: string;
1374
+ readonly status?: number;
1375
+ readonly capability?: keyof QueryCapabilitiesV3;
1376
+ constructor(code: ErrorCode | (string & {}), message: string, options?: QueryErrorOptions);
1377
+ /** The QueryErrorDetail wire shape of this error. */
1378
+ toJSON(): QueryErrorDetail;
1379
+ }
1380
+ declare const isQueryError: (error: unknown) => error is QueryError;
1381
+ /** The code a bare HTTP status implies, for bodies that are not a
1382
+ * QueryErrorBody (a proxy's error page, say). */
1383
+ declare function errorCodeForStatus(status: number): ErrorCode;
1384
+ /** Reads a QueryErrorBody, or null when `body` is not one. */
1385
+ declare function parseQueryErrorBody(body: unknown): QueryErrorDetail | null;
1386
+ /** A QueryError from a QueryErrorBody (or a code and message). */
1387
+ declare function queryErrorFromBody(body: unknown, status?: number): QueryError | null;
1388
+ /** The QueryError of a failed fetch response: its QueryErrorBody when it has
1389
+ * one, otherwise a code from the status and a short message. Consumes the body. */
1390
+ declare function queryErrorFromResponse(response: Response): Promise<QueryError>;
1391
+ /** A failed metric entry. A QueryError keeps its code; any other failure of
1392
+ * a local engine is `fallback`. */
1393
+ declare function failedMetric(id: string, error: unknown, fallback: ErrorCode): AggregationResultEntry;
1394
+
1148
1395
  declare const MAX_QUERY_STATE_BYTES: number;
1149
- declare class QueryDecodeError extends Error {
1150
- readonly code: "invalid" | "too_large" | "unsupported_version";
1151
- constructor(code: "invalid" | "too_large" | "unsupported_version", message: string);
1396
+ /** A query link or saved state that cannot be decoded; a QueryError with a query-link code. */
1397
+ declare class QueryDecodeError extends QueryError {
1398
+ readonly code: Extract<ErrorCode, "invalid" | "too_large" | "unsupported_version">;
1399
+ constructor(code: Extract<ErrorCode, "invalid" | "too_large" | "unsupported_version">, message: string);
1152
1400
  }
1153
1401
  /** v2 JSON or raw-DEFLATE UTF-8, whichever produces the shorter URL token. */
1154
1402
  declare function encodeQuery(q: QueryState): string;
@@ -1157,50 +1405,17 @@ declare function encodeQuery(q: QueryState): string;
1157
1405
  declare function decodeQuery(token: string): QueryState;
1158
1406
  /** Navigation uses this decoder so corrupt links cannot silently run defaults. */
1159
1407
  declare function decodeQueryStrict(token: string): QueryState;
1160
- /** The backend request derived from a QueryState + its schema. Mirrors the Go
1161
- * `WireQuery`. View-only state (column widths) is intentionally absent. */
1162
- interface ServerQuery {
1163
- /** field names to return — visible columns ∪ fields referenced by where/orderBy. */
1164
- select: string[];
1165
- /** only terms whose every predicate is on a pushdown-filterable field. */
1166
- where: WhereTerm[];
1167
- /** only terms on server-sortable fields, with `field` already remapped to the
1168
- * field's server sort key (FieldDef.sort.field) when set. */
1169
- orderBy: OrderByClause[];
1170
- limit: number;
1171
- offset: number;
1172
- /** The table's host-owned state when `hostQuery` is configured; hosts run
1173
- * their own clauses from it. Query Table does not interpret it. */
1174
- hostState?: HostQueryState;
1175
- }
1408
+
1176
1409
  /** Project a QueryState into the server request, dropping client-only filters,
1177
1410
  * client-only sorts, and remapping sort fields through `sort.field`. */
1178
1411
  declare function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): ServerQuery;
1179
- /** The backend request for the metric panel. Scope is the whole filtered set:
1180
- * the SAME pushdown WHERE as the rows query, but NO ORDER BY / LIMIT / OFFSET —
1181
- * metrics describe every matching row, not the visible page. Mirrors the Go
1182
- * AggSpec list. */
1183
- interface AggregationRequest {
1184
- /** The table's host-owned state when `hostQuery` is configured. */
1185
- hostState?: HostQueryState;
1186
- diagnostics?: MetricDiagnostic[];
1187
- where: WhereTerm[];
1188
- aggregations: AggregationClause[];
1189
- }
1190
- /** One group's result. `keys` has one entry per AggregationClause.groupBy field,
1191
- * in axis order (`[]` for a grand total); a null key is the NULL/empty bucket. */
1192
- interface AggregationBucket {
1193
- keys: MetricKey[];
1194
- error?: string;
1195
- y?: MetricValue;
1196
- yError?: string;
1412
+ /** One group's result: the wire bucket (`MetricBucketV3`) plus state the
1413
+ * client derives after a transport returns. */
1414
+ interface AggregationBucket extends MetricBucketV3 {
1197
1415
  components?: {
1198
1416
  expression: string;
1199
1417
  value: MetricValue;
1200
1418
  }[];
1201
- nullCount?: number;
1202
- inputErrorCount?: number;
1203
- distribution?: MetricDistributionResult;
1204
1419
  /** Client-side only: set by the metric UI when one histogram bin of this
1205
1420
  * cohort is inspected (`count`/`value` are then the bin's count). Never part
1206
1421
  * of a transport result. */
@@ -1211,38 +1426,15 @@ interface AggregationBucket {
1211
1426
  /** Occurrences summarised by a cyclic slot (`dateGrouping.occurrence`):
1212
1427
  * those with a value, the samples of its mean and box. */
1213
1428
  occurrences?: number;
1214
- /** The metric: a number for count/sum/avg, or the column's value for min/max
1215
- * (which may be a string for text/datetime). null when undefined (e.g. avg of
1216
- * an all-null column). */
1217
- value: MetricValue;
1218
- /** COUNT(*) of rows in the group — always present, even when `value` isn't a
1219
- * count, so the panel can show group sizes / shares. */
1220
- count: number;
1221
1429
  }
1222
- interface AggregationResultEntry {
1223
- /** Exact omitted additive quantity; unavailable for ratios/averages/distinct. */
1430
+ interface AggregationResultEntry extends MetricResultV3 {
1224
1431
  other?: AggregationBucket;
1225
- error?: string;
1226
- scope?: MetricScope;
1227
- processedRows?: number;
1228
- groupCount?: number;
1229
- coverage?: "exact" | "partial";
1230
- /** Groups removed by AggregationClause.minCount (present whenever it is set).
1231
- * They are not part of `groupCount`, `buckets` or `other`. */
1232
- hiddenGroups?: number;
1233
- /** Echoes AggregationClause.id. */
1234
- id: string;
1235
1432
  buckets: AggregationBucket[];
1236
1433
  }
1237
1434
  interface AggregationResult {
1238
1435
  /** One entry per requested aggregation, in request order. */
1239
1436
  metrics: AggregationResultEntry[];
1240
1437
  }
1241
- /** Project a QueryState into the metric request: the pushdown WHERE subset (same
1242
- * rule as toServerQuery) plus the aggregations whose measure + group fields are
1243
- * all server-capable backend columns. Aggregations referencing a derived /
1244
- * unknown field are dropped — the server has no SQL for them. */
1245
- declare function toAggregationQuery<Row>(q: QueryState, schema: FieldSchema<Row>): AggregationRequest;
1246
1438
 
1247
1439
  interface QuerySnapshot {
1248
1440
  version: 1;
@@ -1356,25 +1548,7 @@ interface ColumnPreview {
1356
1548
  errors: number;
1357
1549
  }
1358
1550
  declare function groupPreview(dependencies: string[], inputs: Record<string, FormulaValue>[], results: FormulaResult[], total: number): ColumnPreview;
1359
- /** Server-issued capabilities are hints for client planning, never authorization. */
1360
- interface ComputedFieldCapabilities {
1361
- /** Host-approved canonical predicates; omitted retains the closed default. */
1362
- filter?: boolean;
1363
- type: FieldType;
1364
- select: boolean;
1365
- sort: boolean;
1366
- measure: boolean;
1367
- group: boolean;
1368
- reason?: string;
1369
- }
1370
- interface ComputedExecution {
1371
- profile: string;
1372
- planToken: string;
1373
- resolvedRevisions: Record<string, string>;
1374
- fields: Record<string, ComputedFieldCapabilities>;
1375
- fingerprint?: string;
1376
- snapshot?: string;
1377
- }
1551
+
1378
1552
  type RowComputedValues = Record<string, {
1379
1553
  value: MetricValue;
1380
1554
  error?: {
@@ -1454,7 +1628,6 @@ interface MetricPopulationSupport {
1454
1628
  declare function metricPopulationError(clause: Pick<AggregationClause, "where" | "minCount">, support: MetricPopulationSupport): string | undefined;
1455
1629
  declare function metricDependencies(c: AggregationClause, schema: FieldSchema, resolve?: (name: string) => FormulaPlan | undefined): string[];
1456
1630
  declare function metricComputationKey(clauses: readonly AggregationClause[]): string;
1457
- declare function toMetricQuery<Row>(q: QueryState, schema: FieldSchema<Row>, execution?: ComputedExecution): MetricQuery;
1458
1631
  /** Safe pre-worker page selection. A supplied committed page needs no query execution.
1459
1632
  * Query regex is never executed here; all-matching regex filtering is unsupported. */
1460
1633
  declare function selectMetricShownRows<Row>(rows: Row[], q: QueryState, schema: FieldSchema<Row>, options?: MetricEvaluationOptions<Row>): Row[];
@@ -1503,87 +1676,8 @@ declare function matchesClause<Row>(row: Row, clause: WhereClause, schema: Field
1503
1676
  * backends/go's aggregate compile on op semantics. */
1504
1677
  declare function applyAggregations<Row>(rows: Row[], q: QueryState, schema: FieldSchema<Row>, options?: MetricEvaluationOptions<Row>): AggregationResult;
1505
1678
 
1506
- /** Versioned row projection keeps server-computed payload separate from host row fields. */
1507
- interface ServerQueryV2 extends ServerQuery {
1508
- version: 2;
1509
- profile: string;
1510
- expectedRevisions: Record<string, string>;
1511
- planToken?: string;
1512
- /** Host must enforce this binding against the row response. */
1513
- snapshot?: string;
1514
- diagnostics: MetricDiagnostic[];
1515
- }
1516
- interface FetchRowsResultV2<Row> {
1517
- version: 2;
1518
- rows: Row[];
1519
- total: number;
1520
- computed: {
1521
- id: RowId;
1522
- values: RowComputedValues;
1523
- }[];
1524
- execution: ComputedExecution;
1525
- }
1526
- /** Project with a previously resolved server capability envelope. This does not
1527
- * authorize definitions or upload their source; the backend revalidates revisions. */
1528
- declare function toServerQueryV2<Row>(q: QueryState, schema: FieldSchema<Row>, execution: ComputedExecution): ServerQueryV2;
1529
-
1530
- interface QueryCapabilitiesV3 {
1531
- version: 3;
1532
- groupedRows: boolean;
1533
- calendarGrouping: boolean;
1534
- /** Executes the cyclic `hourOfDay` and `dayOfWeek` date intervals. */
1535
- calendarCycles?: boolean;
1536
- /** Executes calendar grouping keys (`{ field, interval, timeZone }`) in a
1537
- * grouping stage. Requests using them are refused otherwise. */
1538
- calendarGroupKeys?: boolean;
1539
- computedSourceFilters: boolean;
1540
- regex: boolean;
1541
- regexSourceFilters?: boolean;
1542
- regexAggregateExpressions?: boolean;
1543
- /** Executes AggregationClause.where; clauses using it are refused otherwise. */
1544
- metricFilters?: boolean;
1545
- /** Executes AggregationClause.minCount and reports hiddenGroups. */
1546
- metricMinCount?: boolean;
1547
- /** Also executes an object minCount: distinct values or a sum per group. */
1548
- metricMinCountMeasures?: boolean;
1549
- maxRows: number;
1550
- maxGroups: number;
1551
- maxPopulation: number;
1552
- profile: string;
1553
- }
1554
- interface QueryRequestV3 {
1555
- /** The table's host-owned state when `hostQuery` is configured. */
1556
- hostState?: HostQueryState;
1557
- version: 3;
1558
- profile: string;
1559
- now: number;
1560
- expectedRevisions: Record<string, string>;
1561
- planToken?: string;
1562
- snapshot?: string;
1563
- source: ServerQuery;
1564
- result: ServerQuery;
1565
- grouping?: GroupingDefinition;
1566
- rows: boolean;
1567
- metrics: AggregationClause[];
1568
- diagnostics: string[];
1569
- }
1570
- interface QueryResultV3 {
1571
- version: 3;
1572
- now: number;
1573
- sourceTotal: number;
1574
- rows: Record<string, unknown>[];
1575
- total: number;
1576
- schema: {
1577
- name: string;
1578
- idField: string;
1579
- fields: {
1580
- name: string;
1581
- type: string;
1582
- }[];
1583
- };
1584
- metrics: AggregationResult["metrics"];
1585
- execution: ComputedExecution;
1586
- }
1679
+ declare const MAX_DISTINCT_LIMIT = 500;
1680
+ declare const MAX_DISTINCT_SEARCH_LENGTH = 2000;
1587
1681
  /** The handshake supplies authority, including capabilities for computed keys
1588
1682
  * absent from the base schema. Labels may be supplied by the editable catalogue. */
1589
1683
  declare function sourceExecutionSchema<Row>(schema: FieldSchema<Row>, execution?: ComputedExecution, catalogue?: readonly {
@@ -1591,37 +1685,62 @@ declare function sourceExecutionSchema<Row>(schema: FieldSchema<Row>, execution?
1591
1685
  label: string;
1592
1686
  revision: string;
1593
1687
  }[]): FieldSchema<Row>;
1688
+ /** The v3 request for a query. Throws a QueryError, before anything is sent,
1689
+ * when the query needs a capability the server does not advertise or would
1690
+ * leave a filter or sort on the client (see docs/errors.md). */
1594
1691
  declare function toQueryRequestV3<Row>(query: QueryState, baseSchema: FieldSchema<Row>, capabilities: QueryCapabilitiesV3, execution?: ComputedExecution, options?: {
1595
1692
  now?: number;
1596
1693
  rows?: boolean;
1597
1694
  }): QueryRequestV3;
1598
1695
  declare function validateQueryResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): void;
1599
-
1600
- interface FetchRowsResult<Row> {
1601
- rows: Row[];
1602
- /** Total matching rows before pagination (for "N of M" + paging bounds). */
1603
- total: number;
1604
- }
1605
- /** A keystroke-driven distinct-value lookup. Autocomplete is the DEFAULT value
1606
- * source for every field (design feedback), so this is how the filter combobox
1607
- * finds options. `search` is the user's current input; the backend returns the
1608
- * best matches and whether it truncated (so the UI can prompt "keep typing"). */
1609
- interface DistinctValuesQuery {
1610
- field: string;
1611
- /** Current substring/prefix the user has typed (empty = top values). */
1612
- search: string;
1613
- /** Max suggestions to return (default chosen by the adapter, ~50). */
1614
- limit?: number;
1615
- /** The table's host-owned state when `hostQuery` is configured. */
1696
+ interface AuxiliaryRequestOptions {
1697
+ /** Evaluation clock; defaults to Date.now(). */
1698
+ now?: number;
1699
+ /** The computed execution handshake, when the table has one. */
1700
+ execution?: ComputedExecution;
1616
1701
  hostState?: HostQueryState;
1617
1702
  }
1703
+ /** Filter autocomplete: distinct values of `field` over `where` (default: the
1704
+ * whole source). */
1705
+ declare function toDistinctRequestV3(field: string, search: string, capabilities: QueryCapabilitiesV3, options?: AuxiliaryRequestOptions & {
1706
+ limit?: number;
1707
+ where?: WhereTerm[];
1708
+ }): QueryRequestV3;
1709
+ declare function readDistinctResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): DistinctResultV3;
1710
+ declare function fetchDistinctValuesV3(transport: Transport, schema: FieldSchema, field: string, search: string, options?: AuxiliaryRequestOptions & {
1711
+ limit?: number;
1712
+ where?: WhereTerm[];
1713
+ }, signal?: AbortSignal): Promise<DistinctResultV3>;
1714
+ /** The backend fields a single-row lookup returns by default: every
1715
+ * selectable backend field, and the identity. */
1716
+ declare function rowLookupFields(schema: FieldSchema): string[];
1717
+ /** One row by identity (a refresh after a mutation, or an item lookup). It
1718
+ * asks for two rows, within the server's row budget; the total reports a
1719
+ * duplicate identity either way. */
1720
+ declare function toRowRequestV3(schema: FieldSchema, id: RowId, capabilities: QueryCapabilitiesV3, options?: AuxiliaryRequestOptions & {
1721
+ select?: string[];
1722
+ }): QueryRequestV3;
1723
+ /** The matching row, or null when none matches. Two matches are an error. */
1724
+ declare function readRowResultV3<Row = Record<string, unknown>>(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): Row | null;
1725
+ declare function fetchRowV3<Row = Record<string, unknown>>(transport: Transport, schema: FieldSchema, id: RowId, options?: AuxiliaryRequestOptions & {
1726
+ select?: string[];
1727
+ }, signal?: AbortSignal): Promise<Row | null>;
1728
+ /** Field-picker statistics as ungrouped metrics: `<field>:distinct`, and
1729
+ * `<field>:min`/`<field>:max` where the field allows them. Fields without a
1730
+ * measurable backend source are left out. */
1731
+ declare function toFieldStatsRequestV3(schema: FieldSchema, fields: string[], capabilities: QueryCapabilitiesV3, options?: AuxiliaryRequestOptions): QueryRequestV3;
1732
+ declare function readFieldStatsResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): Record<string, FieldStats>;
1733
+ /** Requests run in batches of at most MAX_AGGREGATIONS metrics. */
1734
+ declare function fetchFieldStatsV3(transport: Transport, schema: FieldSchema, fields: string[], options?: AuxiliaryRequestOptions, signal?: AbortSignal): Promise<Record<string, FieldStats>>;
1735
+
1736
+ /** Filter-value suggestions: the best matches for a search and whether more
1737
+ * exist (so the UI can prompt "keep typing"). */
1618
1738
  interface DistinctValuesResult {
1619
1739
  values: string[];
1620
1740
  /** true when more matches exist than were returned — refine by typing. */
1621
1741
  hasMore: boolean;
1622
1742
  /** True if the selected field has at least one NULL in the source dataset.
1623
- * False if that field is guaranteed non-null. Omitted when the backend does
1624
- * not compute this metadata. */
1743
+ * False if that field is guaranteed non-null. Omitted when unknown. */
1625
1744
  hasNull?: boolean;
1626
1745
  }
1627
1746
  /** Per-field metadata for the field picker. */
@@ -1630,32 +1749,13 @@ interface FieldStats {
1630
1749
  min?: string | number;
1631
1750
  max?: string | number;
1632
1751
  }
1752
+ /** Remote execution. Every row page, metric batch, grouped view, filter
1753
+ * suggestion, row lookup and field statistic is one v3 request. Omit the
1754
+ * transport to run `clientRows` locally. */
1633
1755
  interface Transport<Row = any> {
1634
- queryCapabilities?: QueryCapabilitiesV3;
1635
- fetchQueryV3?(query: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;
1636
- fetchRowsV2?(query: ServerQueryV2, signal?: AbortSignal): Promise<FetchRowsResultV2<Row>>;
1637
- metricCapabilities?: MetricCapabilities;
1638
- fetchMetrics?(query: MetricQuery, signal?: AbortSignal): Promise<AggregationResult>;
1639
- /** Legacy row execution. A remote table needs this, fetchRowsV2 with a
1640
- * computedExecution handshake, or fetchQueryV3 with queryCapabilities.
1641
- * Modern hosts may omit the legacy endpoint, including for draft previews. */
1642
- fetchRows?(query: ServerQuery, signal?: AbortSignal): Promise<FetchRowsResult<Row>>;
1643
- /** Distinct values for filter autocomplete. Strongly recommended: without it,
1644
- * fields fall back to freeform input. The backend should match `search`
1645
- * server-side (e.g. ILIKE prefix) and cap at `limit` so large domains stay
1646
- * fast and refine per keystroke. */
1647
- fetchDistinctValues?(q: DistinctValuesQuery, signal?: AbortSignal): Promise<DistinctValuesResult>;
1648
- /** Run the metric panel's GROUP BY queries (one per requested aggregation),
1649
- * scoped to the WHERE-filtered set with no paging. Optional: without it, the
1650
- * metric panel falls back to applyAggregations over local rows (client mode).
1651
- * Implementations compile each AggSpec with backends/go CompileAggregation,
1652
- * sharing the same WHERE as fetchRows. */
1653
- fetchAggregations?(q: AggregationRequest, signal?: AbortSignal): Promise<AggregationResult>;
1654
- /** Re-fetch a single row by id, for in-place updates without a full re-query
1655
- * after a mutation. Optional. */
1656
- fetchRow?(id: RowId, signal?: AbortSignal): Promise<Row | null>;
1657
- /** Stats for the field picker. Optional. */
1658
- fetchFieldStats?(fields: string[], signal?: AbortSignal): Promise<Record<string, FieldStats>>;
1756
+ /** The server's negotiated v3 capabilities and profile. */
1757
+ queryCapabilities: QueryCapabilitiesV3;
1758
+ fetchQueryV3(query: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;
1659
1759
  }
1660
1760
  interface SavedQuery {
1661
1761
  snapshotCode?: string;
@@ -1943,4 +2043,4 @@ declare function attentionTargetKey(target: AttentionTarget): string;
1943
2043
  /** Framework-independent registration and cancellation; adapters own materialization. */
1944
2044
  declare function createAttentionRegistry(): AttentionRegistry;
1945
2045
 
1946
- 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 AttentionProvider, type AttentionRegistry, type AttentionResult, type AttentionTarget, 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 JsonInspectionScope, type JsonInspectionState, type JsonMatchIdentity, 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_JSON_INSPECTIONS, MAX_JSON_PATHS, 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 ScopedJsonInspectionState, 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, attentionTargetKey, boxSummary, branchesOf, calendarGroupKey, coerceValue, compareMetricValues, compileFormula, compileMetric, computedFieldName, createAttentionRegistry, 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, isJsonBucketId, isJsonPath, isMeasurable, isMetricCycle, isNegativePredicate, isOrGroup, isOrOfAndsGroup, isPropertyFieldLoaded, isPushdownFilter, isSelectable, isSortable, isWhereConjunction, isWhereGroup, itemPageFields, jsonInspectionScopeKey, 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, parseJsonInspectionState, parseJsonInspections, 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 };
2046
+ export { AGG_OPS_BY_TYPE, AGG_OPS_NEEDING_FIELD, type AggOp, type AggregateConfig, type AggregationBucket, type AggregationClause, type AggregationResult, type AggregationResultEntry, type Align, type ApplyPatchOptions, type ApplyResult, type AttentionProvider, type AttentionRegistry, type AttentionResult, type AttentionTarget, type AuxiliaryRequestOptions, 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 DistinctRequestV3, type DistinctResultV3, type DistinctValuesResult, EMPTY_QUERY, ERROR_CODES, type ErrorCode, FORMULA_FUNCTIONS, type FieldDef, type FieldOrigin, type FieldRelationship, type FieldSchema, type FieldSource, type FieldStats, type FieldType, type FilterConfig, type FilterOp, type FilterValues, type FitMode, 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 JsonInspectionScope, type JsonInspectionState, type JsonMatchIdentity, type LinkDestination, type LinkSpec, type LinkTargets, MAX_AGGREGATIONS, MAX_DISTINCT_LIMIT, MAX_DISTINCT_SEARCH_LENGTH, MAX_GROUP_BY_FIELDS, MAX_HOST_QUERY_PARAMS, MAX_HOST_QUERY_STATE_BYTES, MAX_HOST_QUERY_VALUES, MAX_HOST_QUERY_VALUE_LENGTH, MAX_JSON_INSPECTIONS, MAX_JSON_PATHS, 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 MetricBoxDistribution, type MetricBoxSummary, type MetricBucketV3, type MetricCalendarInterval, type MetricCycleInterval, type MetricDateGrouping, type MetricDateOccurrence, type MetricDiagnostic, type MetricDisplay, type MetricDisplayHint, type MetricDistribution, type MetricDistributionResult, type MetricEvaluationOptions, type MetricHistogramBin, type MetricHistogramDistribution, type MetricKey, type MetricLayout, type MetricMinCount, type MetricMinCountDistinct, type MetricMinCountOf, type MetricMinCountSum, type MetricPlan, type MetricPopulationSupport, type MetricReductionOptions, type MetricResultV3, type MetricScope, type MetricSeriesOptions, type MetricSeriesPlan, type MetricShare, type MetricSort, type MetricSpecV3, 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 ProjectedFieldV3, type ProjectedSchemaV3, type PropertyFieldConfig, type PropertyFormat, type PropertySelection, type PropertyViewState, type PropertyViewStorage, type QueryCapabilitiesV3, QueryDecodeError, QueryError, type QueryErrorBody, type QueryErrorDetail, type QueryErrorOptions, 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 RegexExtract, type RegexInspection, type RelationshipAdapter, type RepresentativeOrder, type RepresentativeRow, type ResolvedGroupLink, type ResolvedObjectReference, type RowComputedValues, type RowId, type SavedPropertyView, type SavedQuery, type ScopedJsonInspectionState, type SelectColumn, type SelectConfig, type ServerQuery, 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, type WireGroupingDefinition, type WireMetricDateGrouping, type WireMetricSort, type WireOrGroup, type WireRepresentativeRow, type WireSummaryColumn, type WireWhereBranch, type WireWhereClause, type WireWhereConjunction, type WireWhereTerm, aggOpAllowedForType, aggOpNeedsField, aggOpsForField, applyAggregations, applyPatch, applyQuery, attentionTargetKey, boxSummary, branchesOf, calendarGroupKey, coerceValue, compareMetricValues, compileFormula, compileMetric, computedFieldName, createAttentionRegistry, createGroupingModel, createPropertyView, createQueryLinkService, createSetFilter, decodeQuery, decodeQueryStrict, discoverFieldRelationships, encodeQuery, errorCodeForStatus, evaluateMetricReductions, evaluateMetrics, exitGrouping, failedMetric, fetchDistinctValuesV3, fetchFieldStatsV3, fetchRowV3, filterValues, formulaRuntime, groupKeyField, groupKeyFields, groupKeyTerms, groupLinkQuery, groupPreview, groupSourceQuery, hasMetricSeries, hasRegex, histogramCounts, histogramEdges, httpComputedColumnStore, httpQuerySnapshotStore, indexFields, inspectBucketQuery, isCalendarGroupKey, isComputedCellError, isComputedField, isErrorCode, isFilterable, isGroupLinkField, isGroupLinkValue, isGroupable, isGroupingTimeZone, isJsonBucketId, isJsonPath, isMeasurable, isMetricCycle, isNegativePredicate, isOrGroup, isOrOfAndsGroup, isPropertyFieldLoaded, isPushdownFilter, isQueryError, isSelectable, isSortable, isWhereConjunction, isWhereGroup, itemPageFields, jsonInspectionScopeKey, 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, parseJsonInspectionState, parseJsonInspections, parseQueryErrorBody, parseRelativeDuration, percentile, planMetricSeries, predicatesOf, prepareGrouping, queriesEqual, queryErrorFromBody, queryErrorFromResponse, readDistinctResultV3, readFieldStatsResultV3, readFieldValue, readObjectReference, readRowResultV3, readSetFilter, reduceMetricValues, removePatch, renderItemPageTemplate, resolveFieldName, resolveGroupLink, rowLookupFields, selectMetricShownRows, selectedFields, setFilterModes, setFilterTarget, sortMetricBuckets, sourceDependencies, sourceExecutionSchema, stripSetFilter, toDistinctRequestV3, toFieldStatsRequestV3, toQueryRequestV3, toRowRequestV3, toServerQuery, validateComputedColumn, validateDateGrouping, validateItemPageTemplate, validateMetric, validateMetricSeries, validateQueryResultV3, validateQuerySnapshot, wholeIntervalSpan, withGroupingKeys, withoutGrouping, withoutLinkSummaries };