@pythia-software/query-table-react 0.9.9 → 1.0.1

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/README.md CHANGED
@@ -53,8 +53,9 @@ the complete selection, including IDs outside the displayed page.
53
53
  `table.selection.retain(ids)` atomically intersects the current selection with
54
54
  an iterable. Both operations reset the Shift-click range anchor.
55
55
 
56
- Without `transport.fetchDistinctValues`, `table.filterValues(field, search)`
57
- uses `clientRows` for autocomplete. For `textarray` fields it suggests individual
56
+ With a transport, `table.filterValues(field, search, signal?)` sends a v3
57
+ `distinct` request (core's `fetchDistinctValuesV3`) for server-filterable fields;
58
+ aborting the signal cancels it. Without one it uses `clientRows` for autocomplete. For `textarray` fields it suggests individual
58
59
  array elements, deduplicated and matched case-insensitively by substring. Local
59
60
  suggestions are capped at 50 values, with `hasMore` indicating additional matches.
60
61
 
@@ -108,11 +109,11 @@ api.setDefinition(previous => ({ query: { ...previous.query, offset: 0 }, hostSt
108
109
  `hostState` is `{ version, params: Record<string, string[]> }`. It rides in
109
110
  `QueryState.hostState`, so history, saves, `encodeQuery` links and durable
110
111
  `@…` snapshots carry it with the query, within the existing size budgets.
111
- Every request the table sends carries the `hostState` it runs with
112
- (`ServerQuery`, `ServerQueryV2`, `QueryRequestV3`, `MetricQuery`,
113
- `AggregationRequest` and distinct-value requests), so the host's transport
114
- never sees one definition's table query with another's host state; the Go
115
- request types accept and expose it without interpreting it.
112
+ Every `QueryRequestV3` the table sends carries the `hostState` it runs with,
113
+ including filter suggestions, row lookups and field statistics (opt-in with
114
+ `remoteFieldStats: true`, since each reduces the whole dataset), so the host's
115
+ transport never sees one definition's table query with another's host state;
116
+ the Go request types accept and expose it without interpreting it.
116
117
 
117
118
  - One `setDefinition` is one history entry and one execution. Edits through
118
119
  `setQuery` keep the current host state unless they set one.
@@ -160,7 +161,7 @@ for transport and schema examples.
160
161
 
161
162
  ## Shared computed column definitions
162
163
 
163
- Pass a stable `computedColumnStore` (for example, `httpComputedColumnStore("/api/computed-columns")` from core) to `useQueryTable`. `api.computed` exposes the catalogue, compile/preview, save with revision checking, and reload operations. Queries store only `@computed/<id>` SELECT references. Local evaluation uses browser workers. With `fetchRowsV2` and an authoritative `computedExecution` envelope, computed SELECT and global sorting run on the server and values attach through validated stable-row-ID sidecars. Without a store, definitions are in memory for the mounted hook. See the repository’s `docs/computed-columns.md` for the complete integration contract and PostgreSQL adapter.
164
+ Pass a stable `computedColumnStore` (for example, `httpComputedColumnStore("/api/computed-columns")` from core) to `useQueryTable`. `api.computed` exposes the catalogue, compile/preview, save with revision checking, and reload operations. Queries store only `@computed/<id>` SELECT references. Local evaluation uses browser workers. With an authoritative `computedExecution` envelope, computed SELECT and global sorting run on the v3 server and values arrive inline in the rows, validated against the requested revisions. Without a store, definitions are in memory for the mounted hook. See the repository’s `docs/computed-columns.md` for the complete integration contract and PostgreSQL adapter.
164
165
 
165
166
  ### Canonical keys and unavailable filters
166
167
 
@@ -183,7 +184,7 @@ and reject them through `validateQuery` so users can repair the selected tags.
183
184
 
184
185
  ## Metric execution and drafts
185
186
 
186
- `api.aggregations.preview(clauses, signal)` evaluates a draft without modifying the query. `replace(clauses, expected?)` commits the entire dashboard as one undoable change and can reject a stale editor baseline. Presentation-only changes reuse computation. Advanced remote execution uses `fetchMetrics` plus explicit v2 `metricCapabilities`; v1 transports continue to support representable simple metrics. All-matching scope requires the complete client dataset or a server metric service. Shown-row fallback uses committed inputs and reports missing dependencies.
187
+ `api.aggregations.preview(clauses, signal)` evaluates a draft without modifying the query. `replace(clauses, expected?)` commits the entire dashboard as one undoable change and can reject a stale editor baseline. Presentation-only changes reuse computation. With a transport, every metric batch is one v3 request (`rows: false`); a clause using a population control the server's `queryCapabilities` does not advertise fails on its own. All-matching scope requires the complete client dataset or a transport. Without a transport, shown-row metrics use the committed page and report missing dependencies.
187
188
 
188
189
  See [the metrics integration guide](../../docs/metrics.md) for scopes, cancellation, worker-isolated regex, capability negotiation, computed revisions, and snapshot requirements.
189
190
 
@@ -194,14 +195,11 @@ while `clientRows` continues through local filtering, sorting, and paging.
194
195
  selection. Computed grouping choices in `api.computed.catalogue` use the metric
195
196
  transport and handshake, including definition revisions; row selection,
196
197
  filtering, sorting, and value access keep their row capabilities.
197
- Use `metricRowsReady(query)` to confirm that the external row window
198
- matches the current query and origin before local shown-row evaluation or
199
- previews. Remote `allMatching` metrics run while that gate is false.
200
-
201
- A V2 transport must explicitly advertise `metricCapabilities.shownRows: true`
202
- to execute supported shown-row clauses remotely. False or omitted uses the
203
- committed page, provided its inputs are loaded. See the
204
- [migration example](../../docs/metrics.md#independent-remote-metrics).
198
+ A metric transport executes every clause, shown-row ones included, on the
199
+ server. Use `metricRowsReady(query)` to confirm that a local row window matches
200
+ the current query and origin before local shown-row evaluation or previews
201
+ (tables without a metric transport). See the
202
+ [example](../../docs/metrics.md#independent-remote-metrics).
205
203
 
206
204
  Standalone `useAggregations` calls with a complete client dataset derive the
207
205
  shown page when readiness options are omitted. An explicit `rowsReady: false`
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FieldSchema, WhereClause, QueryState, GroupedRow, GroupingModel, GroupingView, GroupKey, SummaryOp, RepresentativeRow, SummaryColumn, SelectColumn, PropertyViewState, SavedPropertyView, PropertyViewStorage, QueryLink, QuerySnapshot, ScopedJsonInspectionState, AttentionRegistry, ItemPropertyMode, ItemPageOptions, ItemDetailMode, ItemDetailsState, RelationshipAdapter, RowId, FormulaNode, FormulaValue, FormulaResult, ComputedColumn, FieldDef, ComputedColumnDraft, FormulaPlan, ColumnPreview, SavedQuery, StorageAdapter, AggOp, AggregationClause, AggregationResult, HostQueryState, DistinctValuesResult, FieldStats, OrderByClause, Transport, ComputedExecution, ComputedColumnStore, QueryLinkOptions, ObjectReference, ResolvedObjectReference } from '@pythia-software/query-table-core';
1
+ import { FieldSchema, WhereClause, QueryState, GroupedRow, GroupingModel, GroupingView, GroupKey, SummaryOp, RepresentativeRow, SummaryColumn, SelectColumn, PropertyViewState, SavedPropertyView, PropertyViewStorage, QueryLink, QuerySnapshot, ScopedJsonInspectionState, AttentionRegistry, ItemPropertyMode, ItemPageOptions, ItemDetailMode, ItemDetailsState, RelationshipAdapter, RowId, FormulaNode, FormulaValue, FormulaResult, ComputedColumn, FieldDef, ComputedColumnDraft, FormulaPlan, ColumnPreview, SavedQuery, StorageAdapter, AggOp, AggregationClause, AggregationResult, QueryError, HostQueryState, DistinctValuesResult, FieldStats, OrderByClause, Transport, ComputedExecution, ComputedColumnStore, QueryLinkOptions, ObjectReference, ResolvedObjectReference } from '@pythia-software/query-table-core';
2
2
 
3
3
  /** Filter controls for either the result query or grouping's source query. */
4
4
  type QueryFilterApi<Row> = Pick<QueryTableApi<Row>, "query" | "setQuery" | "loading" | "addFilter" | "updateFilter" | "removeFilter" | "clearFilters" | "updatePredicate" | "removePredicate" | "negatePredicate" | "reorderFilters" | "mergeFilters" | "filterValues" | "fieldStats">;
@@ -114,7 +114,7 @@ interface ItemDetailsOptions<Row> {
114
114
  storage?: PropertyViewStorage;
115
115
  objectType?: string;
116
116
  relationships?: RelationshipAdapter;
117
- /** Defaults to complete clientRows or Transport.fetchRow, then the current projected row. */
117
+ /** Defaults to complete clientRows or a v3 identity lookup, then the current projected row. */
118
118
  loadRow?: (id: RowId, signal: AbortSignal) => Promise<ItemDetailRecord<Row> | null>;
119
119
  }
120
120
  interface ItemDetailsApi<Row> {
@@ -216,7 +216,7 @@ interface SelectApi<Row> {
216
216
  hide: (field: string) => void;
217
217
  /** Reorder via drag-drop: move `field` to `toIndex` in the visible order. */
218
218
  move: (field: string, toIndex: number) => void;
219
- /** Set a column's pixel width. */
219
+ /** Set a column's pixel width. Other columns keep any live `fit`. */
220
220
  setWidth: (field: string, width: number) => void;
221
221
  /** Reset to the schema's default columns (clears query.select). */
222
222
  reset: () => void;
@@ -327,6 +327,11 @@ interface UseQueryTableOptions<Row> {
327
327
  links?: QueryLinkOptions;
328
328
  /** Enable schema-driven click popovers, item modals and row expansion. */
329
329
  itemDetails?: boolean | ItemDetailsOptions<Row>;
330
+ /** Ask the transport for field statistics (distinct count, min, max) when
331
+ * the column picker or a metric filter editor opens. Each request reduces
332
+ * the whole dataset, so it is off by default; complete clientRows always
333
+ * provide them. */
334
+ remoteFieldStats?: boolean;
330
335
  /** Debounce (ms) between a query change and the fetch it triggers. Default 200. */
331
336
  debounceMs?: number;
332
337
  /** Injected clock for deterministic saved-query timestamps. Default Date.now. */
@@ -368,7 +373,8 @@ interface AggregationsApi {
368
373
  /** Server (or client-mirror) results, one entry per clause; null when none. */
369
374
  results: AggregationResult | null;
370
375
  loading: boolean;
371
- error: Error | null;
376
+ /** A QueryError (with a code from docs/errors.md) for server and client refusals. */
377
+ error: QueryError | Error | null;
372
378
  /** Append a metric. Defaults to "count all rows"; pass a partial to override.
373
379
  * Returns the generated id. */
374
380
  add: (partial?: Partial<Omit<AggregationClause, "id">>) => string;
@@ -424,14 +430,15 @@ interface QueryExecutionReceipt {
424
430
  /** "none" when the query has no metrics. A metric error fails the receipt. */
425
431
  metrics: "none" | "running" | "succeeded" | "failed";
426
432
  /** The row or metric error behind a failure. */
427
- error: Error | null;
433
+ /** A QueryError (with a code from docs/errors.md) for server and client refusals. */
434
+ error: QueryError | Error | null;
428
435
  }
429
436
  interface QueryTableApi<Row> {
430
437
  /** Dependent source fetches can use ready without parsing display errors. */
431
438
  restoration: {
432
439
  status: "resolving" | "ready" | "error";
433
440
  ready: boolean;
434
- error: Error | null;
441
+ error: QueryError | Error | null;
435
442
  };
436
443
  /** Execution of the current query, separate from restoration. Null while
437
444
  * restoring, after a restoration error and while the table is inactive, so
@@ -472,11 +479,13 @@ interface QueryTableApi<Row> {
472
479
  rows: Row[];
473
480
  total: number | null;
474
481
  loading: boolean;
475
- error: Error | null;
482
+ /** A QueryError (with a code from docs/errors.md) for server and client refusals. */
483
+ error: QueryError | Error | null;
476
484
  refresh: () => void;
477
485
  autoRefresh: AutoRefreshApi;
478
- /** Refresh one legacy row, or schedule a full V2 page refresh so computed
479
- * values and page membership remain coherent. Track V2 completion via loading/error. */
486
+ /** Refresh one row in place through a v3 identity lookup. A grouped page or
487
+ * one with computed columns or sorts refreshes as a whole instead, so computed
488
+ * values and page membership remain coherent; track that through loading/error. */
480
489
  refreshRow: (id: RowId) => Promise<void>;
481
490
  aggregations: AggregationsApi;
482
491
  /** Append a predicate as its own AND term. */
@@ -502,8 +511,9 @@ interface QueryTableApi<Row> {
502
511
  mergeFilters: (sourceIndex: number, targetIndex: number) => void;
503
512
  /** Reset the complete query state back to schema defaults. */
504
513
  resetAll: () => void;
505
- /** Keystroke-driven filter-value autocomplete (Transport.fetchDistinctValues). */
506
- filterValues: (field: string, search: string) => Promise<DistinctValuesResult>;
514
+ /** Keystroke-driven filter-value autocomplete (a v3 `distinct` request, or
515
+ * the complete clientRows). Aborting the signal cancels the request. */
516
+ filterValues: (field: string, search: string, signal?: AbortSignal) => Promise<DistinctValuesResult>;
507
517
  /** Dataset-wide field statistics for catalogue and picker affordances. */
508
518
  fieldStats: (fields: string[], signal?: AbortSignal) => Promise<Record<string, FieldStats>>;
509
519
  toggleSort: (field: string, additive?: boolean) => void;
@@ -524,6 +534,7 @@ interface QueryTableApi<Row> {
524
534
  declare function useQueryTable<Row>(opts: UseQueryTableOptions<Row>): QueryTableApi<Row>;
525
535
 
526
536
  interface MetricExecutionContext<Row> {
537
+ /** Remote execution; defaults to executeV3Metrics over `transport`. */
527
538
  executeV3?: (query: QueryState, signal?: AbortSignal) => Promise<AggregationResult>;
528
539
  queryContextKey?: string;
529
540
  schema: FieldSchema<Row>;
@@ -546,7 +557,7 @@ interface MetricExecutionContext<Row> {
546
557
  interface AggregationsApiState {
547
558
  results: AggregationResult | null;
548
559
  loading: boolean;
549
- error: Error | null;
560
+ error: QueryError | Error | null;
550
561
  preview: (clauses: AggregationClause[], signal?: AbortSignal) => Promise<AggregationResult>;
551
562
  }
552
563
  /** Fetch state is keyed by computation and scope, never card presentation. */