@pythia-software/query-table-react 0.4.2 → 0.6.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/README.md CHANGED
@@ -25,6 +25,11 @@ the complete selection, including IDs outside the displayed page.
25
25
  `table.selection.retain(ids)` atomically intersects the current selection with
26
26
  an iterable. Both operations reset the Shift-click range anchor.
27
27
 
28
+ Without `transport.fetchDistinctValues`, `table.filterValues(field, search)`
29
+ uses `clientRows` for autocomplete. For `textarray` fields it suggests individual
30
+ array elements, deduplicated and matched case-insensitively by substring. Local
31
+ suggestions are capped at 50 values, with `hasMore` indicating additional matches.
32
+
28
33
  ## Privacy defaults
29
34
 
30
35
  URL synchronization and durable browser storage are disabled by default. Set
@@ -39,7 +44,7 @@ for transport and schema examples.
39
44
 
40
45
  ## Shared computed column definitions
41
46
 
42
- 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; formula evaluation stays in browser workers. 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.
47
+ 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.
43
48
 
44
49
  ### Canonical keys and unavailable filters
45
50
 
@@ -54,3 +59,14 @@ Pass a stable `computedColumnStore` (for example, `httpComputedColumnStore("/api
54
59
  Memoize these callbacks and change their identity when external validation metadata
55
60
  changes. Return immutable query values from the canonicalizer. No callback is required
56
61
  for ordinary tables; the existing execution behavior remains the default.
62
+
63
+ For native set editors, use core's `mapSetFilterValues(query.where, (field, key) =>
64
+ canonicalKey)` inside `canonicalizeQuery` to update aliases in both the existing
65
+ predicates and their editor identity. Leave unrecognized/deleted keys unchanged
66
+ and reject them through `validateQuery` so users can repair the selected tags.
67
+
68
+ ## Metric execution and drafts
69
+
70
+ `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.
71
+
72
+ See [the metrics integration guide](../../docs/metrics.md) for scopes, cancellation, worker-isolated regex, capability negotiation, computed revisions, and snapshot requirements.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { FormulaNode, FormulaValue, FormulaResult, ComputedColumn, FieldDef, ComputedColumnDraft, FormulaPlan, ColumnPreview, RowId, SelectColumn, QueryState, FieldSchema, SavedQuery, StorageAdapter, AggOp, AggregationClause, AggregationResult, WhereClause, DistinctValuesResult, FieldStats, OrderByClause, Transport, ComputedColumnStore } from '@pythia-software/query-table-core';
1
+ import { FormulaNode, FormulaValue, FormulaResult, ComputedColumn, FieldDef, ComputedColumnDraft, FormulaPlan, ColumnPreview, RowId, SelectColumn, QueryState, FieldSchema, SavedQuery, StorageAdapter, AggOp, AggregationClause, AggregationResult, WhereClause, DistinctValuesResult, FieldStats, OrderByClause, Transport, ComputedColumnStore, ComputedExecution } from '@pythia-software/query-table-core';
2
2
 
3
3
  type FormulaWorkerFactory = () => Worker;
4
4
  /** Host applications with a restrictive CSP can supply their own worker factory. */
@@ -17,6 +17,20 @@ interface ComputedColumnsApi<Row> {
17
17
  preview: (source: string, count: number, signal?: AbortSignal, editingId?: string, includeInputs?: boolean) => Promise<ColumnPreview>;
18
18
  }
19
19
 
20
+ interface RequestActivityEntry {
21
+ id: number;
22
+ kind: string;
23
+ startedAt: number;
24
+ status: "pending" | "success" | "error" | "aborted";
25
+ durationMs?: number;
26
+ error?: string;
27
+ }
28
+ interface RequestActivityApi {
29
+ /** Newest first; bounded to the latest 100 calls. Query values and results are never retained. */
30
+ entries: readonly RequestActivityEntry[];
31
+ clear: () => void;
32
+ }
33
+
20
34
  interface SelectionApi {
21
35
  selected: Set<RowId>;
22
36
  isSelected: (id: RowId) => boolean;
@@ -65,12 +79,14 @@ interface ColumnDragApi {
65
79
  overIndex: number | null;
66
80
  /** True while a column drag is in progress. */
67
81
  active: boolean;
68
- /** Begin dragging `field`, initially previewed at `index` (its own slot). */
69
- start: (field: string, index: number) => void;
70
- /** Update the previewed insertion index (no-op if unchanged). */
71
- over: (index: number) => void;
82
+ /** Changes only for confirmed drops, so surfaces can persist auxiliary positions. */
83
+ dropRevision?: number;
84
+ /** Begin dragging `field` at `index`. Supply the surface order for cross-surface mapping. */
85
+ start: (field: string, index: number, order?: string[]) => void;
86
+ /** Update the insertion slot and optional surface order (no-op if unchanged). */
87
+ over: (index: number, order?: string[]) => void;
72
88
  /** End the drag (on drop or cancel). */
73
- end: () => void;
89
+ end: (committed?: boolean) => void;
74
90
  /** The live order to render while dragging: `source` moved to `overIndex`.
75
91
  * Returns `order` unchanged when idle, or when `source` isn't in `order`. */
76
92
  preview: (order: string[]) => string[];
@@ -112,6 +128,8 @@ interface UseQueryTableOptions<Row> {
112
128
  storage?: StorageAdapter;
113
129
  /** Shared reusable definitions, independent of saved-query storage. */
114
130
  computedColumnStore?: ComputedColumnStore;
131
+ /** Authoritative host handshake for versioned server SELECT, sorts, and metrics. */
132
+ computedExecution?: ComputedExecution;
115
133
  /** Override the worker factory when CSP disallows blob workers. */
116
134
  formulaWorkerFactory?: FormulaWorkerFactory;
117
135
  /** Seed query, normalized and resource-bounded before use. When omitted the
@@ -150,12 +168,12 @@ interface AutoRefreshApi {
150
168
  /** A patch for one metric. `field`/`label` accept an explicit `undefined` to
151
169
  * CLEAR them (e.g. switching to an op whose measure no longer applies); an
152
170
  * absent key leaves the existing value untouched. */
153
- interface AggregationPatch {
171
+ type AggregationPatch = {
154
172
  op?: AggOp;
155
- field?: string | undefined;
156
173
  groupBy?: string[];
157
- label?: string | undefined;
158
- }
174
+ } & {
175
+ [K in keyof Omit<AggregationClause, "id" | "op" | "groupBy">]?: AggregationClause[K] | undefined;
176
+ };
159
177
  interface AggregationsApi {
160
178
  /** The metric specs currently in the query. */
161
179
  clauses: AggregationClause[];
@@ -175,6 +193,14 @@ interface AggregationsApi {
175
193
  remove: (id: string) => void;
176
194
  /** Remove all metrics. */
177
195
  clear: () => void;
196
+ /** Evaluate a draft without modifying the query. */
197
+ preview?: (clauses: AggregationClause[], signal?: AbortSignal) => Promise<AggregationResult>;
198
+ /** Commit the complete draft as one undoable change. */
199
+ replace?: (clauses: AggregationClause[], expected?: AggregationClause[]) => void;
200
+ /** Validate a clause, including reusable computed dependencies. */
201
+ compile?: (clause: AggregationClause) => unknown;
202
+ /** Invalidation token for page, refresh, schema, and definition changes. */
203
+ contextKey?: string;
178
204
  }
179
205
  interface QueryTableApi<Row> {
180
206
  query: QueryState;
@@ -189,12 +215,15 @@ interface QueryTableApi<Row> {
189
215
  undo: () => void;
190
216
  /** Move forward through local, unsaved query history. */
191
217
  redo: () => void;
218
+ requestActivity: RequestActivityApi;
192
219
  rows: Row[];
193
220
  total: number | null;
194
221
  loading: boolean;
195
222
  error: Error | null;
196
223
  refresh: () => void;
197
224
  autoRefresh: AutoRefreshApi;
225
+ /** Refresh one legacy row, or schedule a full V2 page refresh so computed
226
+ * values and page membership remain coherent. Track V2 completion via loading/error. */
198
227
  refreshRow: (id: RowId) => Promise<void>;
199
228
  aggregations: AggregationsApi;
200
229
  /** Append a predicate as its own AND term. */
@@ -240,11 +269,27 @@ interface QueryTableApi<Row> {
240
269
  }
241
270
  declare function useQueryTable<Row>(opts: UseQueryTableOptions<Row>): QueryTableApi<Row>;
242
271
 
272
+ interface MetricExecutionContext<Row> {
273
+ schema: FieldSchema<Row>;
274
+ transport?: Transport<Row> | undefined;
275
+ clientRows?: Row[] | undefined;
276
+ shownRows?: Row[] | undefined;
277
+ rowsReady?: boolean | undefined;
278
+ rowsError?: Error | null | undefined;
279
+ shownFields?: readonly string[] | undefined;
280
+ resolveComputed?: ((name: string) => FormulaPlan | undefined) | undefined;
281
+ workerFactory?: FormulaWorkerFactory | undefined;
282
+ revisions?: Record<string, string> | undefined;
283
+ execution?: ComputedExecution;
284
+ }
285
+
243
286
  interface AggregationsApiState {
244
287
  results: AggregationResult | null;
245
288
  loading: boolean;
246
289
  error: Error | null;
290
+ preview: (clauses: AggregationClause[], signal?: AbortSignal) => Promise<AggregationResult>;
247
291
  }
248
- declare function useAggregations<Row>(query: QueryState, schema: FieldSchema<Row>, transport: Transport<Row> | undefined, clientRows: Row[] | undefined, debounceMs: number, nonce: number, validateQuery?: (query: QueryState) => void): AggregationsApiState;
292
+ /** Fetch state is keyed by computation and scope, never card presentation. */
293
+ declare function useAggregations<Row>(query: QueryState, schema: FieldSchema<Row>, transport: Transport<Row> | undefined, clientRows: Row[] | undefined, debounceMs: number, nonce: number, validateQuery?: (q: QueryState) => void, options?: Omit<MetricExecutionContext<Row>, "schema" | "transport" | "clientRows">): AggregationsApiState;
249
294
 
250
- export { type AggregationPatch, type AggregationsApi, type AggregationsApiState, type AutoRefreshApi, type AutoRefreshConfig, type AutoRefreshStatus, type ColumnDragApi, type ComputedColumnsApi, type FormulaWorkerFactory, type QueryTableApi, type SavedQueriesApi, type SelectApi, type SelectionApi, type UseQueryTableOptions, createFormulaWorker, evaluateFormulaRows, useAggregations, useColumnDrag, useQueryTable, useSavedQueries, useSelect, useSelection };
295
+ export { type AggregationPatch, type AggregationsApi, type AggregationsApiState, type AutoRefreshApi, type AutoRefreshConfig, type AutoRefreshStatus, type ColumnDragApi, type ComputedColumnsApi, type FormulaWorkerFactory, type QueryTableApi, type RequestActivityApi, type RequestActivityEntry, type SavedQueriesApi, type SelectApi, type SelectionApi, type UseQueryTableOptions, createFormulaWorker, evaluateFormulaRows, useAggregations, useColumnDrag, useQueryTable, useSavedQueries, useSelect, useSelection };