@pythia-software/query-table-react 0.5.0 → 0.7.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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/useComputedColumns.ts","../src/formulaWorker.ts","../src/useQueryTable.ts","../src/useAggregations.ts","../src/useSelection.ts","../src/useSelect.ts","../src/useColumnDrag.ts","../src/useSavedQueries.ts"],"sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n applyQuery,\n compileFormula,\n computedFieldName,\n groupPreview,\n isComputedField,\n memoryComputedColumnStore,\n readFieldValue,\n toServerQuery,\n validateComputedColumn,\n isSelectable,\n type ColumnPreview,\n type ComputedColumn,\n type ComputedColumnDraft,\n type ComputedColumnStore,\n type FieldDef,\n type FieldSchema,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface ComputedColumnsApi<Row> {\n definitions: ComputedColumn[];\n catalogue: FieldDef<Row>[];\n loading: boolean;\n error: string | null;\n reload: () => Promise<void>;\n save: (\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ) => Promise<ComputedColumn>;\n compile: (source: string, editingId?: string) => FormulaPlan;\n /** Sample the first N matching rows in current sort order, independent of table paging. */\n preview: (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs?: boolean,\n ) => Promise<ColumnPreview>;\n}\ninterface Options<Row> {\n schema: FieldSchema<Row>;\n query: QueryState;\n rows: Row[];\n store?: ComputedColumnStore;\n transport?: Transport<Row>;\n clientRows?: Row[];\n workerFactory?: FormulaWorkerFactory;\n}\nexport function useComputedColumns<Row>(options: Options<Row>): {\n api: ComputedColumnsApi<Row>;\n displaySchema: FieldSchema<Row>;\n} {\n const { schema, query, rows, transport, clientRows, workerFactory } = options;\n const store = useMemo(\n () => options.store ?? memoryComputedColumnStore(),\n [options.store],\n );\n const [catalogue, setCatalogue] = useState<{\n dataset: string;\n store: ComputedColumnStore;\n items: ComputedColumn[];\n } | null>(null);\n const definitions = useMemo(\n () =>\n catalogue?.dataset === schema.name && catalogue.store === store\n ? catalogue.items\n : [],\n [catalogue, schema.name, store],\n );\n const [loading, setLoading] = useState(false),\n [error, setError] = useState<string | null>(null);\n const catalogueRequest = useRef<AbortController | null>(null);\n const reload = useCallback(async () => {\n catalogueRequest.current?.abort();\n const ac = new AbortController();\n catalogueRequest.current = ac;\n setLoading(true);\n setError(null);\n try {\n const items = await store.list(schema.name, ac.signal);\n if (ac.signal.aborted) return;\n const valid = items\n .map(validateComputedColumn)\n .sort((a, b) => a.id.localeCompare(b.id));\n if (new Set(valid.map((c) => c.id)).size !== valid.length)\n throw new Error(\"Duplicate computed column IDs.\");\n setCatalogue((previous) =>\n previous?.dataset === schema.name &&\n previous.store === store &&\n JSON.stringify(previous.items) === JSON.stringify(valid)\n ? previous\n : { dataset: schema.name, store, items: valid },\n );\n } catch (e) {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!ac.signal.aborted) setLoading(false);\n }\n }, [store, schema.name]);\n useEffect(() => {\n void reload();\n return () => catalogueRequest.current?.abort();\n }, [reload]);\n useEffect(\n () =>\n store.subscribe?.(schema.name, () => {\n void reload();\n }),\n [store, schema.name, reload],\n );\n useEffect(() => {\n const focus = () => {\n void reload();\n };\n window.addEventListener(\"focus\", focus);\n return () => window.removeEventListener(\"focus\", focus);\n }, [reload]);\n const inputFields = useMemo(\n () =>\n schema.fields\n .filter(isSelectable)\n .filter(\n (f) =>\n f.source.kind === \"backend\" ||\n (f.source.accessor && f.source.dependencies),\n ),\n [schema],\n );\n const compile = useCallback(\n (source: string, editingId?: string): FormulaPlan => {\n const stack = new Set<string>(editingId ? [editingId] : []);\n let expanded = 0;\n const resolve = (name: string): FormulaPlan | undefined => {\n if (!isComputedField(name)) return undefined;\n const id = name.slice(\"@computed/\".length),\n def = definitions.find((d) => d.id === id);\n if (!def) throw new Error(`Computed column unavailable: ${id}`);\n if (stack.has(id))\n throw new Error(`Circular computed-column reference: ${def.label}`);\n if (stack.size >= 20 || ++expanded > 100)\n throw new Error(\"Computed dependency graph is too large.\");\n stack.add(id);\n try {\n return compileFormula(def.expression.source, inputFields, resolve);\n } finally {\n stack.delete(id);\n }\n };\n return compileFormula(source, inputFields, resolve);\n },\n [inputFields, definitions],\n );\n const plans = useMemo(\n () =>\n new Map<string, { plan?: FormulaPlan; error?: string }>(\n definitions.map((def) => {\n try {\n return [\n def.id,\n { plan: compile(def.expression.source, def.id) },\n ] as const;\n } catch (e) {\n return [\n def.id,\n { error: e instanceof Error ? e.message : String(e) },\n ] as const;\n }\n }),\n ),\n [definitions, compile],\n );\n const backendDependencies = useCallback(\n (plan: FormulaPlan) =>\n [\n ...new Set(\n plan.dependencies.flatMap((name) => {\n const f = inputFields.find((f) => f.name === name);\n return f?.source.kind === \"backend\"\n ? [name]\n : (f?.source.dependencies ?? []);\n }),\n ),\n ]\n .filter((name) =>\n schema.fields.some(\n (f) => f.name === name && f.source.kind === \"backend\",\n ),\n )\n .sort(),\n [schema, inputFields],\n );\n const inputsFor = useCallback(\n (plan: FormulaPlan, batch: Row[]) => {\n let size = 0;\n return batch.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = inputFields.find((f) => f.name === name)!;\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date ? raw.toISOString() : (raw as FormulaValue);\n }\n size += JSON.stringify(values).length;\n if (size > 16000000)\n throw new Error(\n \"Input sample exceeds 16 MB. Reduce the rows to process.\",\n );\n return values;\n });\n },\n [inputFields],\n );\n const activeSelect = query.select.length\n ? query.select\n : (schema.defaultSelect ?? []);\n const activeIds = activeSelect\n .filter((c) => isComputedField(c.field))\n .map((c) => c.field.slice(\"@computed/\".length))\n .sort()\n .join(\",\");\n const [evaluated, setEvaluated] = useState<{\n rows: Row[];\n plans: typeof plans;\n values: Map<string, FormulaResult[]>;\n } | null>(null);\n useEffect(() => {\n const ac = new AbortController();\n const values = new Map<string, FormulaResult[]>();\n void (async () => {\n for (const id of activeIds.split(\",\").filter(Boolean)) {\n const entry = plans.get(id);\n if (!entry?.plan) continue;\n try {\n values.set(\n id,\n await evaluateFormulaRows(\n entry.plan.ast,\n inputsFor(entry.plan, rows),\n ac.signal,\n workerFactory,\n ),\n );\n } catch (e) {\n if (ac.signal.aborted) return;\n values.set(\n id,\n rows.map(() => ({\n value: null,\n error: e instanceof Error ? e.message : String(e),\n })),\n );\n }\n }\n if (!ac.signal.aborted) setEvaluated({ rows, plans, values });\n })();\n return () => ac.abort();\n }, [activeIds, rows, plans, inputsFor, workerFactory]);\n const displaySchema = useMemo<FieldSchema<Row>>(() => {\n const indices = new Map(rows.map((row, i) => [row, i]));\n const fields: FieldDef<Row>[] = definitions.map((def) => {\n const entry = plans.get(def.id);\n return {\n name: computedFieldName(def.id),\n label: def.label,\n type:\n entry?.plan?.type === \"null\" ? \"text\" : (entry?.plan?.type ?? \"text\"),\n group: \"Computed columns\",\n source: {\n kind: \"derived\",\n computedId: def.id,\n dependencies: entry?.plan ? backendDependencies(entry.plan) : [],\n accessor: (row: Row) => {\n if (entry?.error) return { computedError: entry.error };\n const result =\n evaluated?.rows === rows && evaluated.plans === plans\n ? evaluated.values.get(def.id)?.[indices.get(row) ?? -1]\n : undefined;\n return result?.error\n ? { computedError: result.error }\n : result\n ? result.value\n : { computedError: \"Calculating…\" };\n },\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n };\n });\n for (const col of activeSelect)\n if (\n isComputedField(col.field) &&\n !fields.some((f) => f.name === col.field)\n )\n fields.push({\n name: col.field,\n label: col.field.slice(10),\n type: \"text\",\n source: {\n kind: \"derived\",\n computedId: col.field.slice(10),\n accessor: () => ({\n computedError: loading\n ? \"Loading definition…\"\n : \"Definition unavailable. Reload the catalogue or contact its owner.\",\n }),\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n });\n return { ...schema, fields: [...schema.fields, ...fields] };\n }, [\n schema,\n definitions,\n plans,\n backendDependencies,\n evaluated,\n rows,\n query.select,\n schema.defaultSelect,\n loading,\n ]);\n const save = useCallback(\n async (column: ComputedColumnDraft, expectedRevision: string | null) => {\n compile(column.expression.source, column.id);\n const saved = validateComputedColumn(\n await store.save(schema.name, column, expectedRevision),\n );\n setCatalogue((prev) => ({\n dataset: schema.name,\n store,\n items: [\n ...(prev?.dataset === schema.name && prev.store === store\n ? prev.items.filter((d) => d.id !== saved.id)\n : []),\n saved,\n ],\n }));\n return saved;\n },\n [compile, store, schema.name],\n );\n const preview = useCallback(\n async (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs = true,\n ): Promise<ColumnPreview> => {\n if (!Number.isInteger(count) || count < 1 || count > 10000)\n throw new Error(\"Choose between 1 and 10,000 rows.\");\n const plan = compile(source, editingId);\n let batch: Row[] = [],\n total = 0;\n if (transport) {\n const request = toServerQuery(\n {\n ...query,\n select: [\n ...new Set([schema.idField, ...backendDependencies(plan)]),\n ].map((field) => ({ field })),\n limit: Math.min(count, 500),\n offset: 0,\n },\n schema,\n );\n while (batch.length < count) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const res = await transport.fetchRows(\n {\n ...request,\n offset: batch.length,\n limit: Math.min(500, count - batch.length),\n },\n signal,\n );\n total = res.total;\n batch.push(...res.rows.slice(0, count - batch.length));\n if (!res.rows.length || batch.length >= total) break;\n }\n } else {\n const result = applyQuery(\n clientRows ?? [],\n { ...query, limit: count, offset: 0 },\n schema,\n );\n batch = result.rows;\n total = result.total;\n }\n const inputs = inputsFor(plan, batch),\n results = await evaluateFormulaRows(\n plan.ast,\n inputs,\n signal,\n workerFactory,\n );\n return groupPreview(\n includeInputs ? plan.dependencies : [],\n inputs,\n results,\n total,\n );\n },\n [\n compile,\n transport,\n query,\n schema,\n backendDependencies,\n clientRows,\n inputsFor,\n workerFactory,\n ],\n );\n return {\n displaySchema,\n api: {\n definitions,\n catalogue: displaySchema.fields,\n loading,\n error,\n reload,\n save,\n compile,\n preview,\n },\n };\n}\n","import {\n formulaRuntime,\n type FormulaNode,\n type FormulaResult,\n type FormulaValue,\n} from \"@pythia-software/query-table-core\";\n\nexport type FormulaWorkerFactory = () => Worker;\n/** Host applications with a restrictive CSP can supply their own worker factory. */\nexport const createFormulaWorker: FormulaWorkerFactory = () => {\n const code = `const evaluate = ${formulaRuntime.toString()}; self.onmessage = e => { const { ast, inputs } = e.data; self.postMessage(inputs.map(row => evaluate(ast, row))); };`;\n const url = URL.createObjectURL(\n new Blob([code], { type: \"text/javascript\" }),\n );\n try {\n return new Worker(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n};\nexport function evaluateFormulaRows(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>[],\n signal?: AbortSignal,\n factory: FormulaWorkerFactory = createFormulaWorker,\n): Promise<FormulaResult[]> {\n if (signal?.aborted)\n return Promise.reject(new DOMException(\"Aborted\", \"AbortError\"));\n if (!inputs.length) return Promise.resolve([]);\n return new Promise((resolve, reject) => {\n let worker: Worker;\n try {\n worker = factory();\n } catch (e) {\n reject(\n new Error(\n `Formula worker unavailable: ${e instanceof Error ? e.message : String(e)}`,\n ),\n );\n return;\n }\n let timer: ReturnType<typeof setTimeout>;\n const started = Date.now();\n let offset = 0;\n const results: FormulaResult[] = [];\n const cleanup = () => {\n clearTimeout(timer);\n worker.terminate();\n signal?.removeEventListener(\"abort\", abort);\n };\n const abort = () => {\n cleanup();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n const send = () => {\n if (Date.now() - started > 30000) {\n cleanup();\n reject(\n new Error(\n \"Formula exceeded the 30-second processing budget. Reduce the row count or simplify the formula.\",\n ),\n );\n return;\n }\n timer = setTimeout(() => {\n cleanup();\n reject(\n new Error(\n \"Formula timed out. Check the regex or reduce the row count.\",\n ),\n );\n }, 2000);\n try {\n worker.postMessage({ ast, inputs: inputs.slice(offset, offset + 200) });\n } catch (e) {\n cleanup();\n reject(e);\n }\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n worker.onerror = () => {\n cleanup();\n reject(new Error(\"Formula worker failed.\"));\n };\n worker.onmessage = (event: MessageEvent<FormulaResult[]>) => {\n clearTimeout(timer);\n results.push(...event.data);\n offset += event.data.length;\n if (offset >= inputs.length) {\n cleanup();\n resolve(results);\n } else send();\n };\n send();\n });\n}\n","// useQueryTable — the one hook that owns everything.\n//\n// The headless brain of the table: it holds the QueryState, keeps it in sync\n// with the URL (`?q=`) and the StorageAdapter, orchestrates fetches through the\n// Transport (debounced + abortable), and exposes intent-level mutators so a UI\n// never hand-edits QueryState. @pythia-software/query-table-ui is a thin layer over this; you\n// can also build an entirely custom table on it.\n\nimport { useComputedColumns, type ComputedColumnsApi } from \"./useComputedColumns\";\nimport type { FormulaWorkerFactory } from \"./formulaWorker\";\nimport type { ComputedColumnStore } from \"@pythia-software/query-table-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EMPTY_QUERY,\n applyQuery,\n decodeQuery,\n encodeQuery,\n memoryStorageAdapter,\n normalizeQueryState,\n readFieldValue,\n selectedFields,\n toServerQuery,\n queriesEqual,\n isOrGroup,\n predicatesOf,\n negateClause,\n opsForField,\n} from \"@pythia-software/query-table-core\";\n\nconst AUTOCOMPLETE_LIMIT = 50;\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nimport type {\n QueryState,\n WhereClause,\n WhereTerm,\n OrderByClause,\n AggOp,\n AggregationClause,\n AggregationResult,\n RowId,\n FieldDef,\n FieldSchema,\n Transport,\n StorageAdapter,\n DistinctValuesResult,\n FieldStats,\n} from \"@pythia-software/query-table-core\";\nimport { useAggregations } from \"./useAggregations\";\nimport { useSelection, type SelectionApi } from \"./useSelection\";\nimport { useSelect, type SelectApi } from \"./useSelect\";\nimport { useColumnDrag, type ColumnDragApi } from \"./useColumnDrag\";\nimport { useSavedQueries, type SavedQueriesApi } from \"./useSavedQueries\";\n\nexport interface UseQueryTableOptions<Row> {\n /** Normalize external aliases without storing presentation in query state. Must be pure and not throw. */\n canonicalizeQuery?: (query: QueryState) => QueryState;\n /** Reject an entire query before rows or metrics execute. Errors retain editable query state. */\n validateQuery?: (query: QueryState) => void;\n\n schema: FieldSchema<Row>;\n /** Data access. Omit for a purely client-side table driven by `clientRows`. */\n transport?: Transport<Row>;\n /** All rows, for client-side mode (applyQuery runs locally over these). */\n clientRows?: Row[];\n /** Saved/last-query persistence. Defaults to a non-durable in-memory adapter.\n * Pass localStorageAdapter() explicitly only when filter values are safe to\n * retain as cleartext JSON on the device. */\n storage?: StorageAdapter;\n /** Shared reusable definitions, independent of saved-query storage. */\n computedColumnStore?: ComputedColumnStore;\n /** Override the worker factory when CSP disallows blob workers. */\n formulaWorkerFactory?: FormulaWorkerFactory;\n /** Seed query, normalized and resource-bounded before use. When omitted the\n * hook resolves: opted-in URL → storage.loadLast → schema defaults. */\n initialQuery?: QueryState;\n /** Mirror QueryState to `?q=` via history.replaceState. Default false because\n * base64url is encoding, not encryption: filters will appear in browser\n * history, referrers, logs, analytics, and screenshots when enabled. */\n syncUrl?: boolean;\n /** Debounce (ms) between a query change and the fetch it triggers. Default 200. */\n debounceMs?: number;\n /** Injected clock for deterministic saved-query timestamps. Default Date.now. */\n now?: () => number;\n /** Side-effect to run on every refresh — both manual `api.refresh()` and each\n * auto-refresh tick. Fires *in addition to* the internal `setNonce` re-query,\n * so manual and auto stay identical. Use it in client mode (no transport) to\n * bridge a UI refresh to your own server fetch without monkey-patching the\n * returned `api`. Always read through a ref, so supplying it never tears down\n * and recreates the auto-refresh interval. */\n onRefresh?: () => void;\n}\n\nexport interface AutoRefreshConfig {\n frequencyMs: number;\n turnOffAfterMs: number;\n}\n\nexport interface AutoRefreshStatus extends AutoRefreshConfig {\n startedAt: number;\n stopsAt: number;\n pollCount: number;\n}\n\nexport interface AutoRefreshApi {\n status: AutoRefreshStatus | null;\n start: (config: AutoRefreshConfig) => void;\n stop: () => void;\n}\n\n/** A patch for one metric. `field`/`label` accept an explicit `undefined` to\n * CLEAR them (e.g. switching to an op whose measure no longer applies); an\n * absent key leaves the existing value untouched. */\nexport interface AggregationPatch {\n op?: AggOp;\n field?: string | undefined;\n groupBy?: string[];\n label?: string | undefined;\n}\n\nexport interface AggregationsApi {\n /** The metric specs currently in the query. */\n clauses: AggregationClause[];\n /** Server (or client-mirror) results, one entry per clause; null when none. */\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n /** Append a metric. Defaults to \"count all rows\"; pass a partial to override.\n * Returns the generated id. */\n add: (partial?: Partial<Omit<AggregationClause, \"id\">>) => string;\n /** Patch a metric by id. */\n update: (id: string, patch: AggregationPatch) => void;\n /** Reorder: move the metric `id` to `toIndex` (an index in the list with the\n * metric removed, so a drag preview's slot maps straight to the result). */\n move: (id: string, toIndex: number) => void;\n /** Remove a metric by id. */\n remove: (id: string) => void;\n /** Remove all metrics. */\n clear: () => void;\n}\n\nexport interface QueryTableApi<Row> {\n // state\n query: QueryState;\n /** Schema defaults used for reset controls. */\n defaults: QueryState;\n setQuery: (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n /** Can move back to a previously applied local query state. */\n canUndo: boolean;\n /** Can move forward to a previously undone local query state. */\n canRedo: boolean;\n /** Move backward through local, unsaved query history. */\n undo: () => void;\n /** Move forward through local, unsaved query history. */\n redo: () => void;\n\n // data\n rows: Row[];\n total: number | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n autoRefresh: AutoRefreshApi;\n refreshRow: (id: RowId) => Promise<void>;\n\n // aggregation metrics (the dashboard panel above the table)\n aggregations: AggregationsApi;\n\n // filters — WHERE is CNF: `query.where` is an array of terms (a literal or an\n // OR group), ANDed together. The top-level intents address a whole term by\n // index; the predicate-level intents address one literal within a term.\n /** Append a predicate as its own AND term. */\n addFilter: (clause: WhereClause) => void;\n /** Replace the whole term at `index` with a single predicate. */\n updateFilter: (index: number, clause: WhereClause) => void;\n /** Remove the whole term at `index`. */\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n /** Replace one predicate inside a term (predIndex 0 for a literal term). */\n updatePredicate: (termIndex: number, predIndex: number, clause: WhereClause) => void;\n /** Remove one predicate; a group of one flattens to a literal, an emptied term drops. */\n removePredicate: (termIndex: number, predIndex: number) => void;\n /** Logically invert one predicate (flips the op, else toggles its NOT flag). */\n negatePredicate: (termIndex: number, predIndex: number) => void;\n /** Move the term at `fromIndex` to `toIndex` (an index in the list with the\n * dragged term removed, so a drag preview's slot maps straight to the result). */\n reorderFilters: (fromIndex: number, toIndex: number) => void;\n /** OR-merge the term at `sourceIndex` into the term at `targetIndex`: the\n * target becomes (or stays) an OR group holding both terms' predicates, and\n * the source term is removed. This is the drag-onto-another-filter gesture. */\n mergeFilters: (sourceIndex: number, targetIndex: number) => void;\n /** Reset the complete query state back to schema defaults. */\n resetAll: () => void;\n /** Keystroke-driven filter-value autocomplete (Transport.fetchDistinctValues). */\n filterValues: (field: string, search: string) => Promise<DistinctValuesResult>;\n /** Dataset-wide field statistics for catalogue and picker affordances. */\n fieldStats: (\n fields: string[],\n signal?: AbortSignal,\n ) => Promise<Record<string, FieldStats>>;\n\n // sorting (multi-sort): click header sets/cycles primary; shift-click appends.\n toggleSort: (field: string, additive?: boolean) => void;\n setSort: (orderBy: OrderByClause[]) => void;\n\n // select + pagination + selection + saved\n select: SelectApi<Row>;\n computed: ComputedColumnsApi<Row>;\n setLimit: (limit: number) => void;\n setOffset: (offset: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n selection: SelectionApi;\n saved: SavedQueriesApi;\n /** Shared, transient column-reorder drag state (table headers + select chips). */\n columnDrag: ColumnDragApi;\n\n // resolved view\n visibleFields: FieldDef<Row>[];\n rowId: (row: Row) => RowId | null;\n}\n\nfunction defaultsFor<Row>(schema: FieldSchema<Row>): QueryState {\n return normalizeQueryState({\n select: schema.defaultSelect ?? [],\n where: [],\n orderBy: schema.defaultSort ?? [],\n limit: schema.defaultLimit ?? EMPTY_QUERY.limit,\n offset: 0,\n });\n}\n\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy = isOrGroup(term) ? { ...term, any: term.any.map((c) => ({ ...c })) } : { ...term };\n if (term.setFilter) copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction cloneQueryState(q: QueryState): QueryState {\n const clone: QueryState = {\n select: q.select.map((column) => ({ ...column })),\n where: q.where.map(cloneWhereTerm),\n orderBy: q.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n limit: q.limit,\n offset: q.offset,\n };\n if (q.aggregations) clone.aggregations = q.aggregations.map((a) => ({ ...a, groupBy: [...a.groupBy] }));\n return clone;\n}\n\n/** Apply a patch to a metric, building a fresh clause so optional `field`/`label`\n * can be dropped (passing them as `undefined` clears; omitting the key keeps the\n * current value) without ever materializing an `undefined`-valued property. */\nfunction mergeAggregation(a: AggregationClause, patch: AggregationPatch): AggregationClause {\n const next: AggregationClause = {\n id: a.id,\n op: patch.op ?? a.op,\n groupBy: patch.groupBy ?? a.groupBy,\n };\n const field = \"field\" in patch ? patch.field : a.field;\n if (field) next.field = field;\n const label = \"label\" in patch ? patch.label : a.label;\n if (label) next.label = label;\n return next;\n}\n\nfunction isNullLike(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.length === 0);\n}\n\nfunction asDistinctValue(value: unknown): string | null {\n if (isNullLike(value)) return null;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n return null;\n}\n\nfunction fieldHasNullInRows<Row>(field: FieldDef<Row>, rows: Row[]): boolean {\n for (const row of rows) {\n if (isNullLike(readFieldValue(field, row))) return true;\n }\n return false;\n}\n\nfunction distinctValuesFromRows<Row>(field: FieldDef<Row>, rows: Row[], search: string): { values: string[]; hasMore: boolean } {\n const target = search.trim().toLowerCase();\n const values: string[] = [];\n const seen = new Set<string>();\n let hasMore = false;\n\n for (const row of rows) {\n const raw = asDistinctValue(readFieldValue(field, row));\n if (raw == null || seen.has(raw)) continue;\n if (target && !raw.toLowerCase().includes(target)) continue;\n\n if (values.length < AUTOCOMPLETE_LIMIT) {\n seen.add(raw);\n values.push(raw);\n continue;\n }\n\n hasMore = true;\n break;\n }\n\n return { values: values.sort((a, b) => a.localeCompare(b)), hasMore };\n}\n\nfunction resolveInitial<Row>(opts: UseQueryTableOptions<Row>): { q: QueryState; fromUrl: boolean } {\n const defaults = defaultsFor(opts.schema);\n if (opts.initialQuery) return { q: normalizeQueryState(opts.initialQuery, defaults), fromUrl: false };\n if (opts.syncUrl === true && typeof window !== \"undefined\") {\n const token = new URLSearchParams(window.location.search).get(\"q\");\n if (token) return { q: normalizeQueryState(decodeQuery(token), defaults), fromUrl: true };\n }\n return { q: defaults, fromUrl: false };\n}\n\nexport function useQueryTable<Row>(opts: UseQueryTableOptions<Row>): QueryTableApi<Row> {\n const { schema, transport, clientRows, initialQuery, syncUrl = false, debounceMs = 200 } = opts;\n const storage = useMemo(() => opts.storage ?? memoryStorageAdapter(), [opts.storage]);\n const now = opts.now ?? Date.now;\n const nowRef = useRef(now);\n const onRefreshRef = useRef(opts.onRefresh);\n const defaults = useMemo(() => defaultsFor(schema), [schema]);\n const byName = useMemo(() => new Map(schema.fields.map((f) => [f.name, f])), [schema]);\n\n const initRef = useRef(resolveInitial(opts));\n const aggIdRef = useRef(0);\n const [storedQuery, setQueryState] = useState<QueryState>(initRef.current.q);\n const query = useMemo(() => opts.canonicalizeQuery?.(storedQuery) ?? storedQuery, [storedQuery, opts.canonicalizeQuery]);\n const undoStack = useRef<QueryState[]>([cloneQueryState(initRef.current.q)]);\n const redoStack = useRef<QueryState[]>([]);\n const [rows, setRows] = useState<Row[]>([]);\n const [total, setTotal] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [nonce, setNonce] = useState(0);\n const [autoRefreshStatus, setAutoRefreshStatus] = useState<AutoRefreshStatus | null>(null);\n\n useEffect(() => {\n nowRef.current = now;\n }, [now]);\n\n useEffect(() => {\n onRefreshRef.current = opts.onRefresh;\n }, [opts.onRefresh]);\n\n const setQuery = useCallback<QueryTableApi<Row>[\"setQuery\"]>((next) => {\n setQueryState((prev) => {\n const candidate = typeof next === \"function\" ? (next as (p: QueryState) => QueryState)(prev) : next;\n const nextQuery = normalizeQueryState(candidate, defaults);\n if (queriesEqual(prev, nextQuery)) return prev;\n undoStack.current.push(cloneQueryState(prev));\n redoStack.current = [];\n return cloneQueryState(nextQuery);\n });\n }, [defaults]);\n\n // Restore the default saved query (preferred) or last query on mount when\n // nothing explicit seeded the view.\n useEffect(() => {\n if (initRef.current.fromUrl || initialQuery) return;\n let cancelled = false;\n void (async () => {\n const defaultSaved = await storage.loadDefaultSaved?.(schema.name);\n const restored = defaultSaved?.query ?? (await storage.loadLast(schema.name));\n if (!cancelled && restored) {\n const normalized = normalizeQueryState(restored, defaults);\n undoStack.current = [cloneQueryState(normalized)];\n redoStack.current = [];\n setQueryState(normalized);\n }\n })();\n return () => {\n cancelled = true;\n };\n // mount-only\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const { api: computed, displaySchema } = useComputedColumns({\n schema, query, rows,\n ...(opts.computedColumnStore ? {store:opts.computedColumnStore} : {}),\n ...(opts.formulaWorkerFactory ? {workerFactory:opts.formulaWorkerFactory} : {}),\n ...(transport ? {transport} : {}), ...(clientRows ? {clientRows} : {}),\n });\n\n // Fetch (debounced + abortable). Transport mode, or client-side applyQuery.\n const queryKey = useMemo(() => encodeQuery(query), [query]);\n const serverRowQuery = useMemo(() => toServerQuery(query, displaySchema), [queryKey, displaySchema]);\n // Keep presentation-only query changes out of the expensive row pipeline.\n // Widths do not leave the client at all, and SELECT does not affect client-side\n // filtering/sorting/paging. The full queryKey still drives URL + persistence.\n const rowQueryKey = useMemo(\n () => transport\n ? `server:${JSON.stringify(serverRowQuery)}`\n : `client:${JSON.stringify([query.where, query.orderBy, query.limit, query.offset])}`,\n [transport, serverRowQuery, query.where, query.orderBy, query.limit, query.offset],\n );\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n opts.validateQuery?.(query);\n if (transport) {\n const res = await transport.fetchRows(serverRowQuery, ac.signal);\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n }\n } else {\n const res = applyQuery(clientRows ?? [], query, schema);\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n }\n }\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) { setError(e as Error); setRows([]); setTotal(null); }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // rowQueryKey captures only row-affecting query state; clientRows/nonce\n // force refetch. Presentation changes still sync/persist via queryKey below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [rowQueryKey, transport, clientRows, schema, debounceMs, nonce, opts.validateQuery]);\n\n // URL sync.\n useEffect(() => {\n if (!syncUrl || typeof window === \"undefined\") return;\n const url = new URL(window.location.href);\n const token = encodeQuery(query);\n if (token) url.searchParams.set(\"q\", token);\n else url.searchParams.delete(\"q\");\n window.history.replaceState(null, \"\", url.toString());\n }, [queryKey, syncUrl, query]);\n\n // Persist last query (debounced).\n useEffect(() => {\n const t = setTimeout(() => void storage.saveLast(schema.name, query), 400);\n return () => clearTimeout(t);\n }, [queryKey, storage, schema.name, query]);\n\n // Resolved id accessor.\n const idField = useMemo(() => schema.fields.find((f) => f.name === schema.idField), [schema]);\n const rowId = useCallback(\n (row: Row): RowId | null => (idField ? (readFieldValue(idField, row) as RowId | null) : null),\n [idField],\n );\n\n // Sub-APIs.\n const displayedIds = useMemo(() => rows.map(rowId).filter((id): id is RowId => id != null), [rows, rowId]);\n const selection = useSelection(displayedIds);\n const select = useSelect(query, setQuery, displaySchema);\n const columnDrag = useColumnDrag();\n const saved = useSavedQueries(\n schema.name,\n query,\n (q) => setQuery(q),\n storage,\n now,\n );\n const aggState = useAggregations(query, schema, transport, clientRows, debounceMs, nonce, opts.validateQuery);\n\n const canUndo = undoStack.current.length > 0;\n const canRedo = redoStack.current.length > 0;\n\n const undo = useCallback(() => {\n setQueryState((prev) => {\n const previous = undoStack.current.pop();\n if (!previous) return prev;\n redoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(previous);\n });\n }, []);\n\n const redo = useCallback(() => {\n setQueryState((prev) => {\n const next = redoStack.current.pop();\n if (!next) return prev;\n undoStack.current.push(cloneQueryState(prev));\n return cloneQueryState(next);\n });\n }, []);\n\n // ---- intent helpers (keep offset/url/storage coherent) ----\n const patch = useCallback((p: Partial<QueryState>) => setQuery((prev) => ({ ...prev, ...p })), [setQuery]);\n\n const addFilter = useCallback((clause: WhereClause) => setQuery((q) => ({ ...q, offset: 0, where: [...q.where, clause] })), [setQuery]);\n const updateFilter = useCallback(\n (index: number, clause: WhereClause) =>\n setQuery((q) => ({ ...q, offset: 0, where: q.where.map((t, i) => (i === index ? clause : t)) })),\n [setQuery],\n );\n const removeFilter = useCallback(\n (index: number) => setQuery((q) => ({ ...q, offset: 0, where: q.where.filter((_, i) => i !== index) })),\n [setQuery],\n );\n const clearFilters = useCallback(() => setQuery((q) => ({ ...q, offset: 0, where: [] })), [setQuery]);\n\n const updatePredicate = useCallback<QueryTableApi<Row>[\"updatePredicate\"]>(\n (termIndex, predIndex, clause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term)) return { any: term.any.map((c, j) => (j === predIndex ? clause : c)) };\n return clause;\n }),\n })),\n [setQuery],\n );\n const removePredicate = useCallback<QueryTableApi<Row>[\"removePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => {\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i !== termIndex) {\n where.push(term);\n return;\n }\n if (isOrGroup(term)) {\n const members = term.any.filter((_, j) => j !== predIndex);\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n return; // 0 members → drop the term\n }\n // literal term → removing its predicate drops the whole term\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const negateOne = useCallback(\n (clause: WhereClause): WhereClause => {\n const field = byName.get(clause.field);\n return negateClause(clause, field ? opsForField(field) : undefined);\n },\n [byName],\n );\n const negatePredicate = useCallback<QueryTableApi<Row>[\"negatePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term)) return { any: term.any.map((c, j) => (j === predIndex ? negateOne(c) : c)) };\n return negateOne(term);\n }),\n })),\n [setQuery, negateOne],\n );\n const reorderFilters = useCallback<QueryTableApi<Row>[\"reorderFilters\"]>(\n (fromIndex, toIndex) =>\n setQuery((q) => {\n if (fromIndex < 0 || fromIndex >= q.where.length) return q;\n const where = [...q.where];\n const [moved] = where.splice(fromIndex, 1);\n where.splice(Math.max(0, Math.min(toIndex, where.length)), 0, moved!);\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const mergeFilters = useCallback<QueryTableApi<Row>[\"mergeFilters\"]>(\n (sourceIndex, targetIndex) =>\n setQuery((q) => {\n if (sourceIndex === targetIndex) return q;\n const source = q.where[sourceIndex];\n const target = q.where[targetIndex];\n if (!source || !target) return q;\n const merged: WhereTerm = { any: [...predicatesOf(target), ...predicatesOf(source)] };\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i === sourceIndex) return; // remove the dragged term\n where.push(i === targetIndex ? merged : term);\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const resetAll = useCallback(() => setQuery(() => cloneQueryState(defaults)), [setQuery, defaults]);\n\n // ---- aggregation metric mutators (don't touch paging — scope is the whole set) ----\n const addAggregation = useCallback<AggregationsApi[\"add\"]>(\n (partial) => {\n const id = `a${nowRef.current()}-${aggIdRef.current++}`;\n const clause: AggregationClause = { id, op: \"count\", groupBy: [], ...partial };\n setQuery((q) => ({ ...q, aggregations: [...(q.aggregations ?? []), clause] }));\n return id;\n },\n [setQuery],\n );\n const updateAggregation = useCallback<AggregationsApi[\"update\"]>(\n (id, patch) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).map((a) => (a.id === id ? mergeAggregation(a, patch) : a)),\n })),\n [setQuery],\n );\n const moveAggregation = useCallback<AggregationsApi[\"move\"]>(\n (id, toIndex) =>\n setQuery((q) => {\n const current = q.aggregations ?? [];\n const from = current.findIndex((a) => a.id === id);\n if (from === -1) return q;\n const next = [...current];\n const [item] = next.splice(from, 1);\n next.splice(Math.max(0, Math.min(toIndex, next.length)), 0, item!);\n return { ...q, aggregations: next };\n }),\n [setQuery],\n );\n const removeAggregation = useCallback<AggregationsApi[\"remove\"]>(\n (id) => setQuery((q) => ({ ...q, aggregations: (q.aggregations ?? []).filter((a) => a.id !== id) })),\n [setQuery],\n );\n const clearAggregations = useCallback<AggregationsApi[\"clear\"]>(\n () => setQuery((q) => ({ ...q, aggregations: [] })),\n [setQuery],\n );\n\n const setSort = useCallback((orderBy: OrderByClause[]) => setQuery((q) => ({ ...q, offset: 0, orderBy })), [setQuery]);\n const toggleSort = useCallback(\n (field: string, additive = false) =>\n setQuery((q) => ({ ...q, offset: 0, orderBy: nextOrderBy(q.orderBy, field, additive) })),\n [setQuery],\n );\n\n const setLimit = useCallback((limit: number) => patch({ limit, offset: 0 }), [patch]);\n const setOffset = useCallback((offset: number) => patch({ offset }), [patch]);\n const nextPage = useCallback(() => setQuery((q) => ({ ...q, offset: q.offset + q.limit })), [setQuery]);\n const prevPage = useCallback(() => setQuery((q) => ({ ...q, offset: Math.max(0, q.offset - q.limit) })), [setQuery]);\n\n const filterValues = useCallback(\n async (field: string, search: string): Promise<DistinctValuesResult> => {\n if (!transport?.fetchDistinctValues) {\n const f = byName.get(field);\n if (!f || !clientRows) return { values: [], hasMore: false };\n\n const fieldHasNull = fieldHasNullInRows(f, clientRows);\n const matches = distinctValuesFromRows(f, clientRows, search);\n\n return {\n values: matches.values,\n hasMore: matches.hasMore,\n hasNull: fieldHasNull,\n };\n }\n return transport.fetchDistinctValues({ field, search });\n },\n [transport, byName, clientRows],\n );\n\n const fieldStats = useCallback<QueryTableApi<Row>[\"fieldStats\"]>(\n async (fields, signal) => {\n const requested = [...new Set(fields)];\n if (transport?.fetchFieldStats) {\n const backendFields = requested.filter(\n (name) => byName.get(name)?.source.kind === \"backend\",\n );\n return backendFields.length\n ? transport.fetchFieldStats(backendFields, signal)\n : {};\n }\n if (!clientRows) return {};\n\n const result: Record<string, FieldStats> = {};\n for (const name of requested) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const field = byName.get(name);\n if (!field) continue;\n const distinct = new Set<string>();\n for (const row of clientRows) {\n const value = readFieldValue(field, row);\n if (value !== null) distinct.add(JSON.stringify(value));\n }\n result[name] = { distinct: distinct.size };\n }\n return result;\n },\n [transport, byName, clientRows],\n );\n\n // Single refresh seam: re-runs the internal query (setNonce) and fires the\n // consumer's onRefresh, if any. Both the manual `api.refresh()` and every\n // auto-refresh tick go through here, so they stay observably identical. Read\n // onRefresh through a ref to keep this callback (and the interval that depends\n // on it) stable across renders.\n const refresh = useCallback(() => {\n setNonce((n) => n + 1);\n onRefreshRef.current?.();\n }, []);\n const stopAutoRefresh = useCallback(() => setAutoRefreshStatus(null), []);\n const startAutoRefresh = useCallback(\n ({ frequencyMs, turnOffAfterMs }: AutoRefreshConfig) => {\n const pollCount = frequencyMs > 0 && turnOffAfterMs > 0 ? Math.floor(turnOffAfterMs / frequencyMs) : 0;\n if (pollCount < 1 || pollCount > MAX_AUTO_REFRESH_POLLS) {\n throw new Error(\"Auto-refresh must schedule between 1 and 1000 polls.\");\n }\n\n const startedAt = nowRef.current();\n refresh();\n setAutoRefreshStatus({\n frequencyMs,\n turnOffAfterMs,\n startedAt,\n stopsAt: startedAt + turnOffAfterMs,\n pollCount: 1,\n });\n },\n [refresh],\n );\n\n const autoRefreshFrequencyMs = autoRefreshStatus?.frequencyMs ?? null;\n const autoRefreshStopsAt = autoRefreshStatus?.stopsAt ?? null;\n\n useEffect(() => {\n if (autoRefreshFrequencyMs == null || autoRefreshStopsAt == null) return;\n\n const tick = () => {\n if (nowRef.current() >= autoRefreshStopsAt) {\n setAutoRefreshStatus((current) => (current?.stopsAt === autoRefreshStopsAt ? null : current));\n return;\n }\n\n refresh();\n setAutoRefreshStatus((current) => {\n if (!current) return current;\n if (current.stopsAt !== autoRefreshStopsAt) return current;\n return { ...current, pollCount: current.pollCount + 1 };\n });\n };\n\n const interval = setInterval(tick, autoRefreshFrequencyMs);\n const timeout = setTimeout(\n () => setAutoRefreshStatus((current) => (current?.stopsAt === autoRefreshStopsAt ? null : current)),\n Math.max(0, autoRefreshStopsAt - nowRef.current()),\n );\n\n return () => {\n clearInterval(interval);\n clearTimeout(timeout);\n };\n }, [autoRefreshFrequencyMs, autoRefreshStopsAt, refresh]);\n\n const autoRefresh = useMemo<AutoRefreshApi>(\n () => ({\n status: autoRefreshStatus,\n start: startAutoRefresh,\n stop: stopAutoRefresh,\n }),\n [autoRefreshStatus, startAutoRefresh, stopAutoRefresh],\n );\n\n const refreshRow = useCallback(\n async (id: RowId) => {\n if (!transport?.fetchRow) return;\n const updated = await transport.fetchRow(id);\n setRows((prev) => prev.map((r) => (rowId(r) === id ? updated ?? r : r)));\n },\n [transport, rowId],\n );\n\n const visibleFields = useMemo(() => selectedFields(displaySchema, query), [displaySchema, query]);\n\n const aggregations = useMemo<AggregationsApi>(\n () => ({\n clauses: query.aggregations ?? [],\n results: aggState.results,\n loading: aggState.loading,\n error: aggState.error,\n add: addAggregation,\n update: updateAggregation,\n move: moveAggregation,\n remove: removeAggregation,\n clear: clearAggregations,\n }),\n [\n query.aggregations,\n aggState.results,\n aggState.loading,\n aggState.error,\n addAggregation,\n updateAggregation,\n moveAggregation,\n removeAggregation,\n clearAggregations,\n ],\n );\n\n return {\n query,\n defaults,\n setQuery,\n rows,\n total,\n loading,\n error,\n canUndo,\n canRedo,\n undo,\n redo,\n refresh,\n autoRefresh,\n refreshRow,\n aggregations,\n addFilter,\n updateFilter,\n removeFilter,\n clearFilters,\n updatePredicate,\n removePredicate,\n negatePredicate,\n reorderFilters,\n mergeFilters,\n resetAll,\n filterValues,\n fieldStats,\n toggleSort,\n setSort,\n select,\n computed,\n setLimit,\n setOffset,\n nextPage,\n prevPage,\n selection,\n saved,\n columnDrag,\n visibleFields,\n rowId,\n };\n}\n\n/** Multi-sort header click logic.\n * - plain click on the sole sorted column → flip its direction\n * - plain click on another column → make it the only sort (desc)\n * - shift-click a new column → append it (desc) as a secondary term\n * - shift-click an existing term → cycle desc → asc → remove */\nfunction nextOrderBy(existing: OrderByClause[], field: string, additive: boolean): OrderByClause[] {\n const i = existing.findIndex((s) => s.field === field);\n if (!additive) {\n if (i === 0 && existing.length === 1) {\n const flipped: \"asc\" | \"desc\" = existing[0]!.dir === \"desc\" ? \"asc\" : \"desc\";\n return [{ ...existing[0]!, dir: flipped }];\n }\n return [{ field, dir: \"desc\" }];\n }\n if (i === -1) return [...existing, { field, dir: \"desc\" }];\n const cur = existing[i]!;\n if (cur.dir === \"desc\") {\n const next = [...existing];\n next[i] = { ...cur, dir: \"asc\" };\n return next;\n }\n return existing.filter((_, k) => k !== i); // asc → remove\n}\n","// useAggregations — the metric panel's data side.\n//\n// Runs the optional GROUP BY queries that back the metrics shown above the table.\n// Kept separate from the rows fetch so the panel loads/refreshes independently:\n// metrics depend ONLY on the WHERE filter + the aggregation specs (scope is the\n// whole filtered set — never the page window), so paging or re-sorting the table\n// does not re-issue them. Debounced + abortable, mirroring the rows fetch.\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { applyAggregations, toAggregationQuery } from \"@pythia-software/query-table-core\";\nimport type { AggregationResult, FieldSchema, QueryState, Transport } from \"@pythia-software/query-table-core\";\n\nexport interface AggregationsApiState {\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n}\n\nconst EMPTY_RESULT: AggregationResult = { metrics: [] };\n\nexport function useAggregations<Row>(\n query: QueryState,\n schema: FieldSchema<Row>,\n transport: Transport<Row> | undefined,\n clientRows: Row[] | undefined,\n debounceMs: number,\n nonce: number,\n validateQuery?: (query: QueryState) => void,\n): AggregationsApiState {\n const [results, setResults] = useState<AggregationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n // Metrics depend only on WHERE + the agg specs. Keying on just those avoids\n // refetching when the user pages or re-sorts the table.\n const key = useMemo(\n () => JSON.stringify({ where: query.where, aggregations: query.aggregations ?? [] }),\n [query.where, query.aggregations],\n );\n const hasAggregations = (query.aggregations?.length ?? 0) > 0;\n\n useEffect(() => {\n if (!hasAggregations) {\n setResults(null);\n setError(null);\n setLoading(false);\n return;\n }\n\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n validateQuery?.(query);\n let res: AggregationResult;\n if (transport?.fetchAggregations) {\n res = await transport.fetchAggregations(toAggregationQuery(query, schema), ac.signal);\n } else if (clientRows) {\n res = applyAggregations(clientRows, query, schema);\n } else {\n res = EMPTY_RESULT;\n }\n if (!cancelled) setResults(res);\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) { setError(e as Error); setResults(null); }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // `key` captures the relevant query subset; clientRows/nonce force a refetch.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key, hasAggregations, transport, clientRows, schema, debounceMs, nonce, validateQuery]);\n\n return { results, loading, error };\n}\n","// useSelection — row selection for paged and re-sortable datasets.\n//\n// - Shift-click range select, anchored by ROW ID (not index) so a\n// range survives re-sort / re-filter / paging. Index anchors break the moment\n// the data reorders; id anchors don't.\n// - Indeterminate header checkbox + select-all-on-page.\n\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\n\nexport interface SelectionApi {\n selected: Set<RowId>;\n isSelected: (id: RowId) => boolean;\n /** Toggle one row. With `shiftKey`, extend from the last-toggled anchor to `id`\n * across the *currently displayed* order (falls back to a plain toggle if the\n * anchor row is no longer present). */\n toggle: (id: RowId, shiftKey?: boolean) => void;\n /** Select / clear every row currently on the page. */\n setPage: (ids: RowId[], selected: boolean) => void;\n /** Atomically replace the complete selection with arbitrary stable row ids. */\n replace: (ids: Iterable<RowId>) => void;\n /** Atomically retain only selected ids that are also present in `ids`. */\n retain: (ids: Iterable<RowId>) => void;\n /** Header checkbox tri-state for the current page. */\n pageState: (pageIds: RowId[]) => \"none\" | \"some\" | \"all\";\n clear: () => void;\n count: number;\n}\n\n/** `displayedIds` is the page's id list in display order; the hook uses it to\n * resolve shift-ranges and header tri-state against what the user sees. */\nexport function useSelection(displayedIds: RowId[]): SelectionApi {\n const [selected, setSelected] = useState<Set<RowId>>(() => new Set());\n const anchor = useRef<RowId | null>(null);\n\n const toggle = useCallback(\n (id: RowId, shiftKey = false) => {\n setSelected((prev) => {\n const next = new Set(prev);\n const a = anchor.current;\n if (shiftKey && a != null) {\n const i = displayedIds.indexOf(a);\n const j = displayedIds.indexOf(id);\n if (i !== -1 && j !== -1) {\n const [lo, hi] = i <= j ? [i, j] : [j, i];\n const span = displayedIds.slice(lo, hi + 1);\n const allChecked = span.every((rowId) => prev.has(rowId));\n for (const rowId of span) {\n if (allChecked) next.delete(rowId);\n else next.add(rowId);\n }\n anchor.current = id;\n return next;\n }\n }\n if (next.has(id)) next.delete(id);\n else next.add(id);\n anchor.current = id;\n return next;\n });\n },\n [displayedIds],\n );\n\n const setPage = useCallback((ids: RowId[], select: boolean) => {\n setSelected((prev) => {\n const next = new Set(prev);\n for (const id of ids) {\n if (select) next.add(id);\n else next.delete(id);\n }\n return next;\n });\n }, []);\n\n const replace = useCallback((ids: Iterable<RowId>) => {\n const next = new Set(ids);\n anchor.current = null;\n setSelected(next);\n }, []);\n\n const retain = useCallback((ids: Iterable<RowId>) => {\n const allowed = new Set(ids);\n anchor.current = null;\n setSelected((prev) => {\n const next = new Set<RowId>();\n for (const id of prev) if (allowed.has(id)) next.add(id);\n return next;\n });\n }, []);\n\n const pageState = useCallback(\n (pageIds: RowId[]): \"none\" | \"some\" | \"all\" => {\n if (pageIds.length === 0) return \"none\";\n let n = 0;\n for (const id of pageIds) if (selected.has(id)) n++;\n return n === 0 ? \"none\" : n === pageIds.length ? \"all\" : \"some\";\n },\n [selected],\n );\n\n const clear = useCallback(() => {\n anchor.current = null;\n setSelected(new Set());\n }, []);\n\n return useMemo<SelectionApi>(\n () => ({\n selected,\n isSelected: (id) => selected.has(id),\n toggle,\n setPage,\n replace,\n retain,\n pageState,\n clear,\n count: selected.size,\n }),\n [selected, toggle, setPage, replace, retain, pageState, clear],\n );\n}\n","// useSelect — the SELECT list: visible columns, their order, and their widths,\n// all persisted INTO the query (decision #5, so one URL renders identically\n// anywhere). This API mutates QueryState.select; it holds no state of its own.\n// Width changes should be debounced by the caller before they hit the query to\n// avoid flooding history during a drag (useQueryTable does this).\n\nimport { useCallback, useMemo } from \"react\";\nimport type { QueryState, SelectColumn, FieldDef, FieldSchema } from \"@pythia-software/query-table-core\";\nimport { selectedFields } from \"@pythia-software/query-table-core\";\n\nexport interface SelectApi<Row> {\n /** Ordered visible columns (resolved: schema defaults when query.select is empty). */\n visible: SelectColumn[];\n /** The corresponding FieldDefs, same order. */\n fields: FieldDef<Row>[];\n /** Selectable fields not currently shown (for the \"add column\" picker). */\n hidden: FieldDef<Row>[];\n\n show: (field: string) => void;\n hide: (field: string) => void;\n /** Reorder via drag-drop: move `field` to `toIndex` in the visible order. */\n move: (field: string, toIndex: number) => void;\n /** Set a column's pixel width. */\n setWidth: (field: string, width: number) => void;\n /** Reset to the schema's default columns (clears query.select). */\n reset: () => void;\n}\n\ntype SetQuery = (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n\nexport function useSelect<Row>(query: QueryState, setQuery: SetQuery, schema: FieldSchema<Row>): SelectApi<Row> {\n const fields = useMemo(() => selectedFields(schema, query), [schema, query]);\n\n // The materialized SelectColumn[] (resolve defaults so the UI always has a\n // concrete, reorderable list even before the user customizes it).\n const visible = useMemo<SelectColumn[]>(() => fields.map((f) => columnFor(query.select, f.name)), [fields, query.select]);\n\n const hidden = useMemo<FieldDef<Row>[]>(() => {\n const shown = new Set(fields.map((f) => f.name));\n return schema.fields.filter((f) => !shown.has(f.name) && (f.select?.enabled ?? true));\n }, [schema, fields]);\n\n const writeSelect = useCallback(\n (mutate: (cols: SelectColumn[]) => SelectColumn[]) => {\n setQuery((prev) => {\n // Materialize current (resolved) columns the first time we diverge from defaults.\n const current = prev.select.length ? prev.select : visible;\n return { ...prev, select: mutate([...current]) };\n });\n },\n [setQuery, visible],\n );\n\n const show = useCallback((field: string) => writeSelect((c) => (c.some((x) => x.field === field) ? c : [...c, { field }])), [writeSelect]);\n const hide = useCallback((field: string) => writeSelect((c) => c.filter((x) => x.field !== field)), [writeSelect]);\n const move = useCallback(\n (field: string, toIndex: number) =>\n writeSelect((c) => {\n const from = c.findIndex((x) => x.field === field);\n if (from === -1) return c;\n const [item] = c.splice(from, 1);\n c.splice(Math.max(0, Math.min(toIndex, c.length)), 0, item!);\n return c;\n }),\n [writeSelect],\n );\n const setWidth = useCallback(\n (field: string, width: number) =>\n writeSelect((c) => c.map((x) => (x.field === field ? { ...x, width: Math.round(width) } : x))),\n [writeSelect],\n );\n const reset = useCallback(() => setQuery((prev) => ({ ...prev, select: [] })), [setQuery]);\n\n return { visible, fields, hidden, show, hide, move, setWidth, reset };\n}\n\nfunction columnFor(select: SelectColumn[], name: string): SelectColumn {\n const found = select.find((c) => c.field === name);\n return found ?? { field: name };\n}\n","// useColumnDrag — transient, SHARED state for a column-reorder drag. One instance\n// is owned by useQueryTable and read by BOTH the table headers and the\n// QueryBuilder select chips, so a drag started in either surface live-previews\n// (and dims) the same column in the other. It holds no query state; the reorder\n// is committed to QueryState.select by whichever surface handles the drop.\n\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface ColumnDragApi {\n /** Field name currently being dragged, or null when idle. */\n source: string | null;\n /** Insertion index within the order with `source` removed (0..n; n = append). */\n overIndex: number | null;\n /** True while a column drag is in progress. */\n active: boolean;\n /** Begin dragging `field`, initially previewed at `index` (its own slot). */\n start: (field: string, index: number) => void;\n /** Update the previewed insertion index (no-op if unchanged). */\n over: (index: number) => void;\n /** End the drag (on drop or cancel). */\n end: () => void;\n /** The live order to render while dragging: `source` moved to `overIndex`.\n * Returns `order` unchanged when idle, or when `source` isn't in `order`. */\n preview: (order: string[]) => string[];\n}\n\ninterface DragState {\n source: string;\n overIndex: number;\n}\n\nexport function useColumnDrag(): ColumnDragApi {\n const [state, setState] = useState<DragState | null>(null);\n\n const start = useCallback((field: string, index: number) => setState({ source: field, overIndex: index }), []);\n const over = useCallback(\n (index: number) =>\n // Keep the SAME object reference when unchanged so React can bail out of the\n // re-render — onDragOver fires continuously while the cursor moves.\n setState((s) => (s && s.overIndex !== index ? { source: s.source, overIndex: index } : s)),\n [],\n );\n const end = useCallback(() => setState(null), []);\n\n const preview = useCallback(\n (order: string[]): string[] => {\n if (!state) return order;\n const without = order.filter((n) => n !== state.source);\n if (without.length === order.length) return order; // source not part of this list\n const at = Math.max(0, Math.min(state.overIndex, without.length));\n return [...without.slice(0, at), state.source, ...without.slice(at)];\n },\n [state],\n );\n\n return useMemo(\n () => ({\n source: state?.source ?? null,\n overIndex: state?.overIndex ?? null,\n active: state != null,\n start,\n over,\n end,\n preview,\n }),\n [state, start, over, end, preview],\n );\n}\n","// useSavedQueries — named query snapshots over a StorageAdapter.\n//\n// \"Last query\" auto-restore and named saves both flow through the injected\n// StorageAdapter (in-memory by default, explicitly durable when the caller\n// provides one). Loading a saved query pushes its QueryState into the controller.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { QueryState, SavedQuery, StorageAdapter } from \"@pythia-software/query-table-core\";\n\nexport interface SavedQueriesApi {\n items: SavedQuery[];\n loading: boolean;\n /** Saved query id used as the default view when no query is specified. */\n defaultId: string | null;\n /** Persist the current query under a name. Rejects on duplicate names. */\n save: (name: string) => Promise<SavedQuery>;\n /** Load a saved query into the live controller. */\n load: (id: string) => void;\n /** Mark a saved query as the default view. No-op when storage lacks support. */\n setDefault: (id: string) => Promise<void>;\n /** Clear the saved-query default view. */\n clearDefault: () => Promise<void>;\n remove: (id: string) => Promise<void>;\n}\n\nexport function useSavedQueries(\n key: string,\n currentQuery: QueryState,\n applyQueryState: (q: QueryState) => void,\n storage: StorageAdapter,\n /** Injected clock so saves are deterministic/testable. */\n now: () => number,\n): SavedQueriesApi {\n const [items, setItems] = useState<SavedQuery[]>([]);\n const [defaultId, setDefaultId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n\n const refresh = useCallback(async () => {\n setLoading(true);\n try {\n const [savedItems, defaultSaved] = await Promise.all([\n storage.listSaved(key),\n storage.loadDefaultSaved?.(key) ?? Promise.resolve(null),\n ]);\n setItems(savedItems);\n setDefaultId(defaultSaved?.id ?? null);\n } finally {\n setLoading(false);\n }\n }, [storage, key]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const save = useCallback(\n async (name: string) => {\n const saved = await storage.saveNamed(key, name, currentQuery, now());\n await refresh();\n return saved;\n },\n [storage, key, currentQuery, now, refresh],\n );\n\n const load = useCallback(\n (id: string) => {\n const found = items.find((q) => q.id === id);\n if (found) applyQueryState(found.query);\n },\n [items, applyQueryState],\n );\n\n const setDefault = useCallback(\n async (id: string) => {\n await storage.setDefaultSaved?.(key, id);\n await refresh();\n },\n [storage, key, refresh],\n );\n\n const clearDefault = useCallback(async () => {\n await storage.setDefaultSaved?.(key, null);\n await refresh();\n }, [storage, key, refresh]);\n\n const remove = useCallback(\n async (id: string) => {\n if (id === defaultId) await storage.setDefaultSaved?.(key, null);\n await storage.deleteSaved(key, id);\n await refresh();\n },\n [storage, key, defaultId, refresh],\n );\n\n return { items, loading, defaultId, save, load, setDefault, clearDefault, remove };\n}\n"],"mappings":"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","names":["f","useCallback","useEffect","useMemo","useRef","useState","applyQuery","readFieldValue","selectedFields","toServerQuery","useEffect","useMemo","useState","useCallback","useMemo","useRef","useState","useCallback","useMemo","useCallback","useMemo","useState","useCallback","useEffect","useState","readFieldValue","useMemo","useRef","useState","useEffect","useCallback","toServerQuery","applyQuery","patch","selectedFields"]}
1
+ {"version":3,"sources":["../src/useQueryFilters.ts","../src/useGrouping.ts","../src/useQueryTable.ts","../src/useItemDetails.ts","../src/usePropertyView.ts","../src/computedExecution.ts","../src/useComputedColumns.ts","../src/formulaWorker.ts","../src/useRequestActivity.ts","../src/useAggregations.ts","../src/metricExecution.ts","../src/useSelection.ts","../src/useSelect.ts","../src/useColumnDrag.ts","../src/useSavedQueries.ts","../src/useQueryLinks.ts","../src/useObjectReferences.ts"],"sourcesContent":["import { useCallback, useMemo } from \"react\";\nimport {\n isOrGroup,\n predicatesOf,\n negateClause,\n opsForField,\n type FieldSchema,\n type WhereClause,\n type WhereTerm,\n} from \"@pythia-software/query-table-core\";\nimport type { QueryTableApi } from \"./useQueryTable\";\n\n/** Filter controls for either the result query or grouping's source query. */\nexport type QueryFilterApi<Row> = Pick<\n QueryTableApi<Row>,\n | \"query\"\n | \"setQuery\"\n | \"loading\"\n | \"addFilter\"\n | \"updateFilter\"\n | \"removeFilter\"\n | \"clearFilters\"\n | \"updatePredicate\"\n | \"removePredicate\"\n | \"negatePredicate\"\n | \"reorderFilters\"\n | \"mergeFilters\"\n | \"filterValues\"\n | \"fieldStats\"\n>;\n\n/** Bind filter intents to a query stage, including the source WHERE of grouping. */\nexport function useQueryFilters<Row>(\n schema: FieldSchema<Row>,\n setQuery: QueryTableApi<Row>[\"setQuery\"],\n) {\n const byName = useMemo(\n () => new Map(schema.fields.map((field) => [field.name, field])),\n [schema],\n );\n const addFilter = useCallback(\n (clause: WhereClause) =>\n setQuery((q) => ({ ...q, offset: 0, where: [...q.where, clause] })),\n [setQuery],\n );\n const updateFilter = useCallback(\n (index: number, clause: WhereClause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((t, i) => (i === index ? clause : t)),\n })),\n [setQuery],\n );\n const removeFilter = useCallback(\n (index: number) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.filter((_, i) => i !== index),\n })),\n [setQuery],\n );\n const clearFilters = useCallback(\n () => setQuery((q) => ({ ...q, offset: 0, where: [] })),\n [setQuery],\n );\n\n const updatePredicate = useCallback<QueryTableApi<Row>[\"updatePredicate\"]>(\n (termIndex, predIndex, clause) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term))\n return {\n any: term.any.map((c, j) => (j === predIndex ? clause : c)),\n };\n return clause;\n }),\n })),\n [setQuery],\n );\n const removePredicate = useCallback<QueryTableApi<Row>[\"removePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => {\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i !== termIndex) {\n where.push(term);\n return;\n }\n if (isOrGroup(term)) {\n const members = term.any.filter((_, j) => j !== predIndex);\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n return; // 0 members → drop the term\n }\n // literal term → removing its predicate drops the whole term\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const negateOne = useCallback(\n (clause: WhereClause): WhereClause => {\n const field = byName.get(clause.field);\n return negateClause(clause, field ? opsForField(field) : undefined);\n },\n [byName],\n );\n const negatePredicate = useCallback<QueryTableApi<Row>[\"negatePredicate\"]>(\n (termIndex, predIndex) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n where: q.where.map((term, i) => {\n if (i !== termIndex) return term;\n if (isOrGroup(term))\n return {\n any: term.any.map((c, j) => (j === predIndex ? negateOne(c) : c)),\n };\n return negateOne(term);\n }),\n })),\n [setQuery, negateOne],\n );\n const reorderFilters = useCallback<QueryTableApi<Row>[\"reorderFilters\"]>(\n (fromIndex, toIndex) =>\n setQuery((q) => {\n if (fromIndex < 0 || fromIndex >= q.where.length) return q;\n const where = [...q.where];\n const [moved] = where.splice(fromIndex, 1);\n where.splice(Math.max(0, Math.min(toIndex, where.length)), 0, moved!);\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n const mergeFilters = useCallback<QueryTableApi<Row>[\"mergeFilters\"]>(\n (sourceIndex, targetIndex) =>\n setQuery((q) => {\n if (sourceIndex === targetIndex) return q;\n const source = q.where[sourceIndex];\n const target = q.where[targetIndex];\n if (!source || !target) return q;\n const merged: WhereTerm = {\n any: [...predicatesOf(target), ...predicatesOf(source)],\n };\n const where: WhereTerm[] = [];\n q.where.forEach((term, i) => {\n if (i === sourceIndex) return; // remove the dragged term\n where.push(i === targetIndex ? merged : term);\n });\n return { ...q, offset: 0, where };\n }),\n [setQuery],\n );\n return {\n addFilter,\n updateFilter,\n removeFilter,\n clearFilters,\n updatePredicate,\n removePredicate,\n negatePredicate,\n reorderFilters,\n mergeFilters,\n };\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport {\n MAX_SUMMARY_COLUMNS,\n normalizeQueryState,\n predicatesOf,\n withoutGrouping,\n type FieldSchema,\n type GroupedRow,\n type GroupingModel,\n type GroupingState,\n queriesEqual,\n type GroupingView,\n type QueryState,\n type RepresentativeRow,\n type SelectColumn,\n type SummaryColumn,\n type SummaryOp,\n} from \"@pythia-software/query-table-core\";\nimport type { QueryFilterApi } from \"./useQueryFilters\";\nimport type { QueryTableApi } from \"./useQueryTable\";\n\n/** Source-stage controls. Rows/columns/metrics remain on the active result API. */\nexport type GroupingSourceApi<Row> = QueryFilterApi<Row> &\n Pick<QueryTableApi<Row>, \"itemDetails\" | \"rowId\"> & {\n schema: FieldSchema<Row>;\n };\n\nexport interface GroupingApi<Row> {\n inputsReady?: boolean;\n preview?: (query: QueryState, signal?: AbortSignal) => Promise<{ rows: GroupedRow[]; sourceTotal: number; total: number }>;\n supported: boolean;\n model: GroupingModel<Row>;\n api: QueryTableApi<Row>;\n source: GroupingSourceApi<Row>;\n grouped: QueryTableApi<Row>;\n schema: FieldSchema<Row>;\n view: GroupingView;\n inputs: Row[];\n notice: string;\n setNotice: (notice: string) => void;\n changeKeys: (keys: string[]) => void;\n addSummary: (op: SummaryOp, field?: string) => void;\n changeSummary: (id: string, op: SummaryOp) => void;\n changeRepresentative: (rule: RepresentativeRow | null) => void;\n representativeImpact: () => string;\n applyColumns: (summaries: SummaryColumn[], columns: SelectColumn[]) => void;\n}\n\n/** Structural edits are one normal QueryState transaction: persistence,\n * sharing, undo and redo all retain the original source query and result view. */\nexport function useGroupingController<Row>(\n api: QueryTableApi<Row>,\n source: GroupingSourceApi<Row>,\n model: GroupingModel<Row>,\n inputs: Row[],\n supported: boolean,\n viewRevision: number,\n execution: Pick<GroupingApi<Row>, \"inputsReady\" | \"preview\"> = {},\n): GroupingApi<Row> {\n const [notice, setNotice] = useState(\"\");\n useEffect(() => setNotice(\"\"), [viewRevision]);\n const previous = useRef<{ query: QueryState; revision: number } | null>(null);\n const stage = api.query.grouping;\n const view: GroupingView = {\n version: 2,\n mode: stage ? \"groups\" : \"rows\",\n keys: stage?.keys ?? [],\n summaries: stage?.summaries ?? [],\n representative: stage?.representative ?? null,\n input: source.query,\n result: withoutGrouping(api.query),\n };\n const outputSchema = {\n ...api.schema!,\n fields: api.computed.catalogue,\n } as unknown as FieldSchema<GroupedRow>;\n function changeKeys(keys: string[]) {\n if (keys.length && !supported) return;\n const cached =\n previous.current?.revision === viewRevision\n ? previous.current.query\n : null;\n const canRestore = (current: QueryState) =>\n !current.grouping && cached?.grouping &&\n queriesEqual(cached.grouping.source, current) &&\n JSON.stringify(cached.grouping.keys) === JSON.stringify(keys);\n // Reject at the intent boundary, where callers can display the error.\n // Throwing inside a state updater instead fails React's next render.\n if (keys.length)\n model.validate(canRestore(api.query) ? cached!.grouping! : {\n ...(stage ?? { summaries: [], representative: null }),\n keys,\n });\n if (!keys.length && stage)\n previous.current = { query: api.query, revision: viewRevision };\n api.setQuery((current) => {\n const before = current.grouping;\n if (!keys.length) return before ? before.source : current;\n if (!before) {\n // Restore a previous grouped layout only for the same explicit keys.\n if (cached?.grouping && canRestore(current))\n return {\n ...cached,\n grouping: { ...cached.grouping, source: current },\n };\n const grouping: GroupingState = {\n keys,\n summaries: [],\n representative: null,\n source: current,\n };\n return {\n select: keys.map((field) => ({ field })),\n where: [],\n orderBy: [],\n limit: current.limit,\n offset: 0,\n grouping,\n };\n }\n const grouping = { ...before, keys };\n const removed = new Set(before.keys.filter((key) => !keys.includes(key)));\n // An empty SELECT shows the existing keys by default. Materialize them\n // before adding keys so introducing an explicit SELECT keeps those columns.\n const columns = current.select.length\n ? current.select\n : before.keys.map((field) => ({ field }));\n return {\n ...current,\n grouping,\n offset: 0,\n aggregations: [],\n select: [\n ...keys\n .filter((key) => !before.keys.includes(key))\n .map((field) => ({ field })),\n ...columns.filter((c) => !removed.has(c.field)),\n ],\n where: current.where.filter(\n (term) => !predicatesOf(term).some((p) => removed.has(p.field)),\n ),\n orderBy: current.orderBy.filter((term) => !removed.has(term.field)),\n };\n });\n setNotice(\n stage && api.query.aggregations?.length && keys.length\n ? \"Grouping changed. Group metrics cleared; Undo restores them.\"\n : \"\",\n );\n api.selection.clear();\n }\n function applyColumns(summaries: SummaryColumn[], columns: SelectColumn[]) {\n if (!stage) {\n api.setQuery((q) => ({ ...q, select: columns }));\n return;\n }\n model.validate({ ...stage, summaries });\n const changed = new Set(\n stage.summaries\n .filter((before) => {\n const after = summaries.find((column) => column.id === before.id);\n return (\n !after ||\n before.op !== after.op ||\n before.field !== after.field ||\n before.expression !== after.expression\n );\n })\n .map((column) => column.id),\n );\n api.setQuery((q) =>\n q.grouping\n ? {\n ...q,\n grouping: { ...q.grouping, summaries },\n select: columns,\n ...(changed.size\n ? {\n offset: 0,\n aggregations: [],\n where: q.where.filter(\n (term) =>\n !predicatesOf(term).some((p) => changed.has(p.field)),\n ),\n orderBy: q.orderBy.filter((term) => !changed.has(term.field)),\n }\n : {}),\n }\n : q,\n );\n setNotice(\n changed.size &&\n (api.query.where.some((term) =>\n predicatesOf(term).some((p) => changed.has(p.field)),\n ) ||\n api.query.orderBy.some((term) => changed.has(term.field)) ||\n api.query.aggregations?.length)\n ? \"Columns updated. Affected filters, sorts, and metrics cleared; Undo restores them.\"\n : \"\",\n );\n }\n function addSummary(op: SummaryOp, field?: string) {\n if (!stage || (op === \"row\" && !stage.representative)) return;\n const existing = stage.summaries.find(\n (column) => column.op === op && column.field === field,\n );\n if (!existing && stage.summaries.length >= MAX_SUMMARY_COLUMNS) {\n setNotice(\n `A grouped view supports up to ${MAX_SUMMARY_COLUMNS} aggregate columns.`,\n );\n return;\n }\n const column = existing ?? {\n id: `summary_${crypto.randomUUID().replace(/-/g, \"\")}`,\n op,\n ...(field ? { field } : {}),\n };\n applyColumns(\n existing ? stage.summaries : [...stage.summaries, column],\n api.select.visible.some((c) => c.field === column.id)\n ? api.select.visible\n : [...api.select.visible, { field: column.id }],\n );\n }\n function changeSummary(id: string, op: SummaryOp) {\n if (!stage) return;\n applyColumns(\n stage.summaries.map((column) =>\n column.id === id ? { ...column, op } : column,\n ),\n api.select.visible,\n );\n }\n function representativeImpact() {\n if (!stage) return \"\";\n const before = api.query;\n const after = model.reconcileRepresentative(\n before,\n stage.summaries,\n outputSchema,\n false,\n );\n return [\n before.where.length !== after.where.length ? \"row-value filters\" : \"\",\n before.orderBy.length !== after.orderBy.length ? \"row-value sorts\" : \"\",\n (before.aggregations?.length ?? 0) !== (after.aggregations?.length ?? 0)\n ? \"dependent metrics\"\n : \"\",\n ]\n .filter(Boolean)\n .join(\", \");\n }\n function changeRepresentative(representative: RepresentativeRow | null) {\n if (\n !stage ||\n JSON.stringify(stage.representative) === JSON.stringify(representative)\n )\n return;\n const summaries = representative\n ? stage.summaries\n : stage.summaries.filter((column) => column.op !== \"row\");\n model.validate({ ...stage, summaries, representative });\n const impact = representativeImpact();\n api.setQuery((q) =>\n q.grouping\n ? normalizeQueryState({\n ...model.reconcileRepresentative(\n q,\n stage.summaries,\n outputSchema,\n !representative,\n ),\n grouping: { ...q.grouping, summaries, representative },\n })\n : q,\n );\n setNotice(\n impact\n ? `Representative row changed. Cleared ${impact}; Undo restores them.`\n : \"\",\n );\n }\n return {\n ...execution,\n supported,\n model,\n api,\n source,\n grouped: api,\n schema: api.schema!,\n view,\n inputs,\n notice,\n setNotice,\n changeKeys,\n addSummary,\n changeSummary,\n applyColumns,\n changeRepresentative,\n representativeImpact,\n };\n}\n","import { useQueryFilters } from \"./useQueryFilters\";\nimport { useGroupingController, type GroupingApi, type GroupingSourceApi } from \"./useGrouping\";\nimport { createGroupingModel, prepareGrouping, withoutGrouping,\n sourceExecutionSchema, toQueryRequestV3, validateQueryResultV3 } from \"@pythia-software/query-table-core\";\nimport { ITEM_DETAILS_COLUMN, itemPageFields } from \"@pythia-software/query-table-core\";\nimport { useItemDetails, initialDetailModes, type ItemDetailsApi, type ItemDetailsOptions } from \"./useItemDetails\";\n// useQueryTable — the one hook that owns everything.\n//\n// The headless brain of the table: it holds the QueryState, keeps it in sync\n// with the URL (`?q=`) and the StorageAdapter, orchestrates fetches through the\n// Transport (debounced + abortable), and exposes intent-level mutators so a UI\n// never hand-edits QueryState. @pythia-software/query-table-ui is a thin layer over this; you\n// can also build an entirely custom table on it.\n\nimport {\n executionRevision,\n validateComputedResponse,\n} from \"./computedExecution\";\nimport {\n useComputedColumns,\n type ComputedColumnsApi,\n} from \"./useComputedColumns\";\nimport type { FormulaWorkerFactory } from \"./formulaWorker\";\nimport type {\n ComputedColumnStore,\n ComputedExecution,\n RowComputedValues,\n} from \"@pythia-software/query-table-core\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n EMPTY_QUERY,\n applyQuery,\n memoryStorageAdapter,\n normalizeQueryState,\n readFieldValue,\n selectedFields,\n toServerQuery,\n queriesEqual,\n isOrGroup,\n predicatesOf,\n negateClause,\n opsForField,\n metricPlans,\n validateMetric,\n metricDependencies,\n isComputedField,\n computedFieldName,\n toServerQueryV2,\n} from \"@pythia-software/query-table-core\";\n\nconst AUTOCOMPLETE_LIMIT = 50;\nconst MAX_AUTO_REFRESH_POLLS = 1000;\nimport type {\n QueryState,\n WhereClause,\n WhereTerm,\n OrderByClause,\n AggOp,\n AggregationClause,\n AggregationResult,\n RowId,\n FieldDef,\n FieldSchema,\n Transport,\n StorageAdapter,\n DistinctValuesResult,\n FieldStats,\n} from \"@pythia-software/query-table-core\";\nimport {\n useRequestActivity,\n type RequestActivityApi,\n} from \"./useRequestActivity\";\nimport { useAggregations } from \"./useAggregations\";\nimport { useSelection, type SelectionApi } from \"./useSelection\";\nimport { useSelect, type SelectApi } from \"./useSelect\";\nimport { useColumnDrag, type ColumnDragApi } from \"./useColumnDrag\";\nimport { useSavedQueries, type SavedQueriesApi } from \"./useSavedQueries\";\nimport { useQueryLinks, type QueryLinksApi } from \"./useQueryLinks\";\nimport { createQueryLinkService, type QueryLinkOptions } from \"@pythia-software/query-table-core\";\n\nexport interface UseQueryTableOptions<Row> {\n\n /** Pause execution and URL synchronization while a mounted host view is hidden. */\n active?: boolean;\n /** Capture evaluation time for grouped executions and remote query requests. */\n evaluationNow?: () => number;\n /** Normalize external aliases without storing presentation in query state. Must be pure and not throw. */\n canonicalizeQuery?: (query: QueryState) => QueryState;\n /** Reject an entire query before rows or metrics execute. Errors retain editable query state. */\n validateQuery?: (query: QueryState) => void;\n\n /** Disable row-producing grouping for this instance. Enabled for complete client datasets by default. */\n grouping?: boolean;\n schema: FieldSchema<Row>;\n /** Data access. Omit for a purely client-side table driven by `clientRows`. */\n transport?: Transport<Row>;\n /** Dataset already available in memory. Remote grouping/aggregation belongs\n * on the server; do not download a population to supply this option. */\n clientRows?: Row[];\n /** Saved/last-query persistence. Defaults to a non-durable in-memory adapter.\n * Pass localStorageAdapter() explicitly only when filter values are safe to\n * retain as cleartext JSON on the device. */\n storage?: StorageAdapter;\n /** Shared reusable definitions, independent of saved-query storage. */\n computedColumnStore?: ComputedColumnStore;\n /** Authoritative host handshake for versioned server SELECT, sorts, and metrics. */\n computedExecution?: ComputedExecution;\n /** Override the worker factory when CSP disallows blob workers. */\n formulaWorkerFactory?: FormulaWorkerFactory;\n /** Seed query, normalized and resource-bounded before use. When omitted the\n * hook resolves: opted-in URL → storage.loadLast → schema defaults. */\n initialQuery?: QueryState;\n /** Mirror QueryState to `?q=` via history.replaceState. Default false because\n * base64url is encoding, not encryption: filters will appear in browser\n * history, referrers, logs, analytics, and screenshots when enabled. */\n syncUrl?: boolean;\n /** Collection URL parameter, independent of item views. Takes precedence\n * over the legacy itemDetails.queryParameter; otherwise defaults to q. */\n queryParameter?: string;\n /** URL budget and browser-local FIFO cache; remote snapshots come from storage.snapshots. */\n links?: QueryLinkOptions;\n /** Enable schema-driven click popovers, item modals and row expansion. */\n itemDetails?: boolean | ItemDetailsOptions<Row>;\n /** Debounce (ms) between a query change and the fetch it triggers. Default 200. */\n debounceMs?: number;\n /** Injected clock for deterministic saved-query timestamps. Default Date.now. */\n now?: () => number;\n /** Side-effect to run on every refresh — both manual `api.refresh()` and each\n * auto-refresh tick. Fires *in addition to* the internal `setNonce` re-query,\n * so manual and auto stay identical. Use it in client mode (no transport) to\n * bridge a UI refresh to your own server fetch without monkey-patching the\n * returned `api`. Always read through a ref, so supplying it never tears down\n * and recreates the auto-refresh interval. */\n onRefresh?: () => void;\n}\n\nexport interface AutoRefreshConfig {\n frequencyMs: number;\n turnOffAfterMs: number;\n}\n\nexport interface AutoRefreshStatus extends AutoRefreshConfig {\n startedAt: number;\n stopsAt: number;\n pollCount: number;\n}\n\nexport interface AutoRefreshApi {\n status: AutoRefreshStatus | null;\n start: (config: AutoRefreshConfig) => void;\n stop: () => void;\n}\n\n/** A patch for one metric. `field`/`label` accept an explicit `undefined` to\n * CLEAR them (e.g. switching to an op whose measure no longer applies); an\n * absent key leaves the existing value untouched. */\nexport type AggregationPatch = { op?: AggOp; groupBy?: string[] } & {\n [K in keyof Omit<AggregationClause, \"id\" | \"op\" | \"groupBy\">]?:\n AggregationClause[K] | undefined;\n};\n\nexport interface AggregationsApi {\n /** The metric specs currently in the query. */\n clauses: AggregationClause[];\n /** Server (or client-mirror) results, one entry per clause; null when none. */\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n /** Append a metric. Defaults to \"count all rows\"; pass a partial to override.\n * Returns the generated id. */\n add: (partial?: Partial<Omit<AggregationClause, \"id\">>) => string;\n /** Patch a metric by id. */\n update: (id: string, patch: AggregationPatch) => void;\n /** Reorder: move the metric `id` to `toIndex` (an index in the list with the\n * metric removed, so a drag preview's slot maps straight to the result). */\n move: (id: string, toIndex: number) => void;\n /** Remove a metric by id. */\n remove: (id: string) => void;\n /** Remove all metrics. */\n clear: () => void;\n /** Evaluate a draft without modifying the query. */\n preview?: (\n clauses: AggregationClause[],\n signal?: AbortSignal,\n ) => Promise<AggregationResult>;\n /** Commit the complete draft as one undoable change. */\n replace?: (\n clauses: AggregationClause[],\n expected?: AggregationClause[],\n ) => void;\n /** Validate a clause, including reusable computed dependencies. */\n compile?: (clause: AggregationClause) => unknown;\n /** Invalidation token for page, refresh, schema, and definition changes. */\n contextKey?: string;\n}\n\nexport interface QueryTableApi<Row> {\n /** Dependent source fetches can use ready without parsing display errors. */\n restoration: { status: \"resolving\" | \"ready\" | \"error\"; ready: boolean; error: Error | null };\n /** Call after a host pushState/router update, with an absolute URL or a location\n * relative to window.location.href. Supersedes prior resolution;\n * abort or an intervening query edit prevents stale publication. */\n restoreLocation: (location: string | URL, signal?: AbortSignal) => Promise<void>;\n /** Row-producing GROUP BY controls and source stage, when supported. */\n grouping?: GroupingApi<Row>;\n /** Current result schema; changes when entering or leaving grouping. */\n schema?: FieldSchema<Row>;\n links: QueryLinksApi;\n /** Built-in item details, enabled by the instance creator. */\n itemDetails?: ItemDetailsApi<Row>;\n // state\n query: QueryState;\n /** Schema defaults used for reset controls. */\n defaults: QueryState;\n setQuery: (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n /** Can move back to a previously applied local query state. */\n canUndo: boolean;\n /** Can move forward to a previously undone local query state. */\n canRedo: boolean;\n /** Move backward through local, unsaved query history. Empty history leaves\n * incoming link restoration and errors unchanged. */\n undo: () => void;\n /** Move forward through local, unsaved query history. Empty history leaves\n * incoming link restoration and errors unchanged. */\n redo: () => void;\n\n requestActivity: RequestActivityApi;\n\n // data\n rows: Row[];\n total: number | null;\n loading: boolean;\n error: Error | null;\n refresh: () => void;\n autoRefresh: AutoRefreshApi;\n /** Refresh one legacy row, or schedule a full V2 page refresh so computed\n * values and page membership remain coherent. Track V2 completion via loading/error. */\n refreshRow: (id: RowId) => Promise<void>;\n\n // aggregation metrics (the dashboard panel above the table)\n aggregations: AggregationsApi;\n\n // filters — WHERE is CNF: `query.where` is an array of terms (a literal or an\n // OR group), ANDed together. The top-level intents address a whole term by\n // index; the predicate-level intents address one literal within a term.\n /** Append a predicate as its own AND term. */\n addFilter: (clause: WhereClause) => void;\n /** Replace the whole term at `index` with a single predicate. */\n updateFilter: (index: number, clause: WhereClause) => void;\n /** Remove the whole term at `index`. */\n removeFilter: (index: number) => void;\n clearFilters: () => void;\n /** Replace one predicate inside a term (predIndex 0 for a literal term). */\n updatePredicate: (\n termIndex: number,\n predIndex: number,\n clause: WhereClause,\n ) => void;\n /** Remove one predicate; a group of one flattens to a literal, an emptied term drops. */\n removePredicate: (termIndex: number, predIndex: number) => void;\n /** Logically invert one predicate (flips the op, else toggles its NOT flag). */\n negatePredicate: (termIndex: number, predIndex: number) => void;\n /** Move the term at `fromIndex` to `toIndex` (an index in the list with the\n * dragged term removed, so a drag preview's slot maps straight to the result). */\n reorderFilters: (fromIndex: number, toIndex: number) => void;\n /** OR-merge the term at `sourceIndex` into the term at `targetIndex`: the\n * target becomes (or stays) an OR group holding both terms' predicates, and\n * the source term is removed. This is the drag-onto-another-filter gesture. */\n mergeFilters: (sourceIndex: number, targetIndex: number) => void;\n /** Reset the complete query state back to schema defaults. */\n resetAll: () => void;\n /** Keystroke-driven filter-value autocomplete (Transport.fetchDistinctValues). */\n filterValues: (\n field: string,\n search: string,\n ) => Promise<DistinctValuesResult>;\n /** Dataset-wide field statistics for catalogue and picker affordances. */\n fieldStats: (\n fields: string[],\n signal?: AbortSignal,\n ) => Promise<Record<string, FieldStats>>;\n\n // sorting (multi-sort): click header sets/cycles primary; shift-click appends.\n toggleSort: (field: string, additive?: boolean) => void;\n setSort: (orderBy: OrderByClause[]) => void;\n\n // select + pagination + selection + saved\n select: SelectApi<Row>;\n computed: ComputedColumnsApi<Row>;\n setLimit: (limit: number) => void;\n setOffset: (offset: number) => void;\n nextPage: () => void;\n prevPage: () => void;\n selection: SelectionApi;\n saved: SavedQueriesApi;\n /** Shared, transient column-reorder drag state (table headers + select chips). */\n columnDrag: ColumnDragApi;\n\n // resolved view\n visibleFields: FieldDef<Row>[];\n rowId: (row: Row) => RowId | null;\n}\n\nfunction detailColumnSchema<Row>(schema: FieldSchema<Row>, enabled: boolean): FieldSchema<Row> {\n if (!enabled) return schema;\n return { ...schema,\n defaultSelect: [...(schema.defaultSelect ?? selectedFields(schema, { select: [] }).map(field => ({ field: field.name }))), { field: ITEM_DETAILS_COLUMN }],\n fields: [...schema.fields, { name: ITEM_DETAILS_COLUMN, label: \"Detail\", type: \"text\",\n source: { kind: \"derived\", accessor: () => null }, select: { default: true, width: 112 },\n filter: { enabled: false }, sort: { enabled: false }, aggregate: { measure: false, groupable: false },\n property: { enabled: false },\n }],\n };\n}\nfunction defaultsFor<Row>(schema: FieldSchema<Row>, details = false): QueryState {\n schema = detailColumnSchema(schema, details);\n return normalizeQueryState({\n select: schema.defaultSelect ?? [],\n where: [],\n orderBy: schema.defaultSort ?? [],\n limit: schema.defaultLimit ?? EMPTY_QUERY.limit,\n offset: 0,\n });\n}\n\nfunction cloneWhereTerm(term: WhereTerm): WhereTerm {\n const copy = isOrGroup(term)\n ? { ...term, any: term.any.map((c) => ({ ...c })) }\n : { ...term };\n if (term.setFilter)\n copy.setFilter = { ...term.setFilter, values: [...term.setFilter.values] };\n return copy;\n}\n\nfunction cloneQueryState(q: QueryState): QueryState {\n const clone: QueryState = {\n select: q.select.map((column) => ({ ...column })),\n where: q.where.map(cloneWhereTerm),\n orderBy: q.orderBy.map((term) =>\n term.extract ? { ...term, extract: { ...term.extract } } : { ...term },\n ),\n limit: q.limit,\n offset: q.offset,\n };\n if (q.fitToScreen) clone.fitToScreen = true;\n if (q.aggregations)\n clone.aggregations = JSON.parse(\n JSON.stringify(q.aggregations),\n ) as AggregationClause[];\n if (q.grouping) clone.grouping = normalizeQueryState(q).grouping!;\n if (q.itemDetails) clone.itemDetails = JSON.parse(JSON.stringify(q.itemDetails)) as NonNullable<QueryState[\"itemDetails\"]>;\n return clone;\n}\n\n/** Apply a patch to a metric, building a fresh clause so optional `field`/`label`\n * can be dropped (passing them as `undefined` clears; omitting the key keeps the\n * current value) without ever materializing an `undefined`-valued property. */\nfunction mergeAggregation(\n a: AggregationClause,\n patch: AggregationPatch,\n): AggregationClause {\n const next = { ...a, ...patch } as AggregationClause;\n for (const key of Object.keys(next) as Array<keyof AggregationClause>) {\n if (next[key] === undefined) delete next[key];\n }\n return next;\n}\n\nfunction isNullLike(value: unknown): boolean {\n return value == null || (Array.isArray(value) && value.length === 0);\n}\n\nfunction asDistinctValue(value: unknown): string | null {\n if (isNullLike(value)) return null;\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return String(value);\n }\n return null;\n}\n\nfunction fieldHasNullInRows<Row>(field: FieldDef<Row>, rows: Row[]): boolean {\n for (const row of rows) {\n if (isNullLike(readFieldValue(field, row))) return true;\n }\n return false;\n}\n\nfunction distinctValuesFromRows<Row>(\n field: FieldDef<Row>,\n rows: Row[],\n search: string,\n): { values: string[]; hasMore: boolean } {\n const target = search.trim().toLowerCase();\n const values: string[] = [];\n const seen = new Set<string>();\n let hasMore = false;\n\n rowsLoop: for (const row of rows) {\n const value = readFieldValue(field, row);\n const candidates =\n field.type === \"textarray\" && Array.isArray(value) ? value : [value];\n for (const candidate of candidates) {\n const raw = asDistinctValue(candidate);\n if (raw == null || seen.has(raw)) continue;\n if (target && !raw.toLowerCase().includes(target)) continue;\n\n if (values.length < AUTOCOMPLETE_LIMIT) {\n seen.add(raw);\n values.push(raw);\n continue;\n }\n\n hasMore = true;\n break rowsLoop;\n }\n }\n\n return { values: values.sort((a, b) => a.localeCompare(b)), hasMore };\n}\n\nfunction hasQueryLink(url: string, parameter: string): boolean {\n const values = new URL(url).searchParams.getAll(parameter);\n return values.length > 1 || (values.length === 1 && values[0] !== \"\");\n}\n\nfunction queryParameter<Row>(opts: UseQueryTableOptions<Row>): string {\n return opts.queryParameter ?? (typeof opts.itemDetails === \"object\" ? opts.itemDetails.queryParameter : undefined) ?? \"q\";\n}\n\nfunction resolveInitial<Row>(opts: UseQueryTableOptions<Row>): {\n q: QueryState;\n fromUrl: boolean;\n} {\n const defaults = defaultsFor(opts.schema, Boolean(opts.itemDetails));\n if (opts.initialQuery)\n return {\n q: normalizeQueryState(opts.initialQuery, defaults),\n fromUrl: false,\n };\n if (opts.syncUrl === true && opts.active !== false && typeof window !== \"undefined\") {\n const parameter = queryParameter(opts);\n if (hasQueryLink(window.location.href, parameter))\n return {\n q: defaults,\n fromUrl: true,\n };\n }\n return { q: defaults, fromUrl: false };\n}\n\nexport function useQueryTable<Row>(\n opts: UseQueryTableOptions<Row>,\n): QueryTableApi<Row> {\n const {\n schema: sourceSchema,\n transport: sourceTransport,\n clientRows: providedRows,\n initialQuery,\n debounceMs = 200,\n } = opts;\n const active = opts.active !== false;\n const urlSyncEnabled = opts.syncUrl === true;\n const syncUrl = urlSyncEnabled && active;\n const { transport: metadataTransport, activity: requestActivity } =\n useRequestActivity(sourceTransport);\n const transport = metadataTransport;\n const storage = useMemo(\n () => opts.storage ?? memoryStorageAdapter(),\n [opts.storage],\n );\n const parameter = queryParameter(opts);\n const linkService = useMemo(() => createQueryLinkService(sourceSchema.name, storage.snapshots, opts.links),\n [sourceSchema.name, storage.snapshots, opts.links?.cache, opts.links?.maxUrlBytes]);\n const now = opts.now ?? Date.now;\n const nowRef = useRef(now);\n const onRefreshRef = useRef(opts.onRefresh);\n const defaults = useMemo(() => defaultsFor(sourceSchema, Boolean(opts.itemDetails)), [sourceSchema, Boolean(opts.itemDetails)]);\n\n const initRef = useRef(resolveInitial(opts));\n const [restoration, setRestoration] = useState<{ loading: boolean; error: Error | null }>({ loading: initRef.current.fromUrl, error: null });\n const [storageReady, setStorageReady] = useState(Boolean(initialQuery));\n const restorationCurrent = useRef({ storageReady, restoration, active });\n restorationCurrent.current = { storageReady, restoration, active };\n const manualQueryEpoch = useRef(0);\n const restoreController = useRef<AbortController | null>(null);\n const restoreHandler = useRef<((location: string, signal?: AbortSignal) => Promise<void>) | null>(null);\n const initialRestore = useRef<(() => Promise<void>) | null>(null);\n const initialRestorationStarted = useRef(false);\n const restoreLocation = useCallback((location: string | URL, signal?: AbortSignal) => {\n if (!restoreHandler.current) return Promise.reject(Error(\"Query controller is not mounted.\"));\n return restoreHandler.current(String(location), signal);\n }, []);\n const aggIdRef = useRef(0);\n // A null baseline follows current host defaults. Explicit views keep their\n // snapshot, scoped to the source so reset cannot restore another table.\n const savedBaseline = useRef<{ source: string; query: QueryState } | null>(\n initRef.current.q.grouping\n ? { source: sourceSchema.name, query: cloneQueryState(initRef.current.q) }\n : null,\n );\n const viewRevision = useRef(0);\n const [queryHistory, setQueryHistory] = useState<{ query: QueryState; past: QueryState[]; future: QueryState[] }>(\n () => ({ query: initRef.current.q, past: [], future: [] }),\n );\n // Keep history current even when React batches several edits or\n // undo/redo calls. History updates stay pure and cancellation stays outside\n // React state updaters, which may run more than once.\n const queryHistoryRef = useRef(queryHistory);\n const updateQueryHistory = useCallback((update: (history: typeof queryHistory) => typeof queryHistory) => {\n const previous = queryHistoryRef.current;\n const next = update(previous);\n if (next === previous) return;\n queryHistoryRef.current = next;\n setQueryHistory(next);\n }, []);\n const storedQuery = queryHistory.query;\n const [nonce, setNonce] = useState(0);\n const query = useMemo(\n () => opts.canonicalizeQuery?.(storedQuery) ?? storedQuery,\n [storedQuery, opts.canonicalizeQuery],\n );\n const sourceCatalogue = useMemo(() => sourceExecutionSchema(sourceSchema, opts.computedExecution), [sourceSchema, opts.computedExecution]);\n const sourceRows = providedRows;\n const groupingModel = useMemo(() => createGroupingModel(sourceCatalogue), [sourceCatalogue]);\n const remoteGrouping = !!transport?.fetchQueryV3 && transport.queryCapabilities?.version === 3 && transport.queryCapabilities.groupedRows;\n const groupingSupported = ((!transport && sourceRows !== undefined) || remoteGrouping) && opts.grouping !== false;\n const groupKey = JSON.stringify(query.grouping ?? null);\n // Capture the grouped evaluation clock with its population. Debounced rows,\n // metric previews and committed metrics must use the same relative bounds.\n // Ordinary V3 requests capture their clock when each execution begins.\n const groupingNow = useMemo(() => query.grouping ? (opts.evaluationNow ?? Date.now)() : undefined,\n [sourceRows, sourceSchema, groupingSupported, groupKey, nonce, opts.evaluationNow]);\n const prepared = useMemo(() => {\n if (!query.grouping) return null;\n try {\n if (!groupingSupported) throw new Error(\"Grouped queries require a server with grouped-query support or a dataset already in memory.\");\n if (remoteGrouping) { groupingModel.validate(query.grouping); return { inputs: [] as Row[], rows: [], error: null }; }\n return { ...prepareGrouping(sourceRows!, sourceCatalogue, query.grouping, { now: groupingNow! }), error: null };\n } catch (error) {\n return { inputs: [] as Row[], rows: [], error: error as Error };\n }\n }, [sourceRows, sourceCatalogue, groupingModel, groupingSupported, groupKey, nonce, groupingNow, remoteGrouping]);\n // Result fields depend on the projection, not the current population. Keep\n // their identity across refresh/WHERE changes so committed rows stay visible\n // during debounce, while real shape changes still invalidate them below.\n const projectionKey = JSON.stringify(query.grouping\n ? [query.grouping.keys, query.grouping.summaries] : null);\n const schema = useMemo(() => (query.grouping\n ? groupingModel.resultSchema(query.grouping.keys, query.grouping.summaries)\n : sourceSchema) as FieldSchema<Row>, [sourceSchema, groupingModel, projectionKey]);\n const clientRows = (prepared?.rows ?? sourceRows) as Row[] | undefined;\n const executionQuery = useMemo(() => withoutGrouping(query), [query]);\n const byName = useMemo(() => new Map(schema.fields.map(field => [field.name, field])), [schema]);\n const detailsEnabled = Boolean(opts.itemDetails) && !query.grouping;\n // Normalization clones grouping even for presentation edits. Only a change\n // in its content should invalidate row and metric execution.\n const validateExecution = useCallback((q: QueryState) => {\n if (prepared?.error) throw prepared.error;\n // Previews carry draft metrics in q. Reattach the source stage without\n // replacing those drafts with the currently committed dashboard.\n opts.validateQuery?.(query.grouping ? { ...q, grouping: query.grouping } : q);\n }, [prepared?.error, opts.validateQuery, groupKey]);\n const [committedRows, setRows] = useState<Row[]>([]);\n const [serverComputed, setServerComputed] = useState<\n Map<RowId, RowComputedValues>\n >(new Map());\n const [committedFields, setCommittedFields] = useState<string[]>([]);\n const [serverExecution, setServerExecution] = useState<\n ComputedExecution | undefined\n >();\n const [total, setTotal] = useState<number | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [committedPage, setCommittedPage] = useState<string | null>(null);\n const [committedSource, setCommittedSource] = useState<{\n schema: FieldSchema<Row>;\n transport: Transport<Row> | undefined;\n clientRows: Row[] | undefined;\n } | null>(null);\n // A schema transition changes row shape and identity. Never render records\n // from the previous result shape while the next page is being prepared.\n const rows = useMemo(() => committedSource?.schema === schema ? committedRows : [], [committedSource?.schema, schema, committedRows]);\n const [autoRefreshStatus, setAutoRefreshStatus] =\n useState<AutoRefreshStatus | null>(null);\n\n useEffect(() => {\n nowRef.current = now;\n }, [now]);\n\n useEffect(() => {\n onRefreshRef.current = opts.onRefresh;\n }, [opts.onRefresh]);\n\n const setQuery = useCallback<QueryTableApi<Row>[\"setQuery\"]>(\n (next) => {\n manualQueryEpoch.current++;\n initialRestorationStarted.current = true;\n restoreController.current?.abort();\n setStorageReady(true);\n setRestoration(previous => !previous.loading && !previous.error ? previous : { loading: false, error: null });\n updateQueryHistory((history) => {\n const prev = history.query;\n const candidate =\n typeof next === \"function\"\n ? (next as (p: QueryState) => QueryState)(prev)\n : next;\n const nextQuery = normalizeQueryState(candidate, defaults);\n if (queriesEqual(prev, nextQuery)) return history;\n return { query: cloneQueryState(nextQuery), past: [...history.past, cloneQueryState(prev)], future: [] };\n });\n },\n [defaults, updateQueryHistory],\n );\n\n const sourceQuery = query.grouping?.source ?? query;\n const setSourceQuery = useCallback<QueryTableApi<Row>[\"setQuery\"]>((next) => {\n setQuery(current => {\n const previous = current.grouping?.source ?? current;\n const source = withoutGrouping(typeof next === \"function\" ? next(previous) : next);\n return current.grouping ? { ...current, offset: 0, grouping: { ...current.grouping, source } } : source;\n });\n }, [setQuery]);\n const sourceFilters = useQueryFilters(sourceCatalogue, setSourceQuery);\n\n // Track only this table's URL parameter, including duplicates. Host routes,\n // anchors and unrelated history.state changes do not restore table state.\n const observedQueryUrl = useRef<string | null>(null);\n const recordQueryUrl = useCallback((url: string) => {\n observedQueryUrl.current = JSON.stringify(new URL(url).searchParams.getAll(parameter));\n }, [parameter]);\n const links = useQueryLinks(query, linkService, syncUrl, storageReady && !restoration.loading && !restoration.error,\n parameter, opts.links?.maxUrlBytes ?? 2000, recordQueryUrl);\n const restoreSources = useRef({ storage, linkService, defaults, initialQuery });\n restoreSources.current = { storage, linkService, defaults, initialQuery };\n\n // Resolve URL references before rows, metrics, persistence, or address-bar writes.\n useEffect(() => {\n let cancelled = false;\n let controller = new AbortController();\n let generation = 0;\n initialRestorationStarted.current = Boolean(restoreSources.current.initialQuery);\n async function restore(navigation = false, location = typeof window !== \"undefined\" ? window.location.href : \"\", signal?: AbortSignal) {\n initialRestorationStarted.current = true;\n const { storage, linkService, defaults } = restoreSources.current;\n const run = ++generation;\n const epoch = manualQueryEpoch.current;\n controller.abort(); controller = new AbortController();\n restoreController.current = controller;\n const currentController = controller;\n const abort = () => currentController.abort();\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) currentController.abort();\n setStorageReady(false);\n const explicitLink = !!location && (navigation || urlSyncEnabled) && hasQueryLink(location, parameter);\n setRestoration({ loading: true, error: null });\n try {\n if (currentController.signal.aborted) throw new DOMException(\"Query restoration cancelled.\", \"AbortError\");\n const fromUrl = location && (navigation || urlSyncEnabled) ? await linkService.resolve(location, parameter, currentController.signal) : null;\n const defaultSaved = fromUrl ? null : await storage.loadDefaultSaved?.(sourceSchema.name);\n const restored = fromUrl ?? defaultSaved?.query ?? (navigation ? defaults : await storage.loadLast(sourceSchema.name));\n if (currentController.signal.aborted) throw new DOMException(\"Query restoration cancelled.\", \"AbortError\");\n if (!cancelled && run === generation && epoch === manualQueryEpoch.current) {\n if (restored) {\n const normalized = normalizeQueryState(restored, defaults);\n savedBaseline.current = defaultSaved || fromUrl?.grouping\n ? { source: sourceSchema.name, query: cloneQueryState(normalized) }\n : null;\n viewRevision.current++;\n updateQueryHistory(() => ({ query: normalized, past: [], future: [] }));\n }\n setStorageReady(true);\n setRestoration(previous => !previous.loading && !previous.error ? previous : { loading: false, error: null });\n }\n } catch (e) {\n if (!cancelled && run === generation && epoch === manualQueryEpoch.current) {\n if (explicitLink || navigation && currentController.signal.aborted) {\n setRestoration({ loading: false, error: e instanceof Error ? e : Error(String(e)) });\n } else {\n // Last/default saved queries are optional restoration sources.\n // A failed host read should still leave a usable default table.\n updateQueryHistory(() => ({ query: defaults, past: [], future: [] }));\n setRestoration({ loading: false, error: null });\n }\n setStorageReady(true);\n }\n if (navigation && !cancelled && run === generation && epoch === manualQueryEpoch.current) throw e;\n } finally {\n signal?.removeEventListener(\"abort\", abort);\n }\n }\n restoreHandler.current = async (location, signal) => {\n location = new URL(location, typeof window !== \"undefined\" ? window.location.href : undefined).href;\n const key = JSON.stringify(new URL(location).searchParams.getAll(parameter));\n const current = restorationCurrent.current;\n if (key === observedQueryUrl.current && current.storageReady && !current.restoration.loading && !current.restoration.error) return;\n recordQueryUrl(location);\n await restore(true, location, signal);\n };\n initialRestore.current = () => restore();\n if (typeof window !== \"undefined\") recordQueryUrl(window.location.href);\n const navigate = () => {\n if (!restorationCurrent.current.active) return;\n const key = JSON.stringify(new URL(window.location.href).searchParams.getAll(parameter));\n if (key === observedQueryUrl.current) return;\n observedQueryUrl.current = key;\n void restore(true).catch(() => { /* Restoration state owns the display error. */ });\n };\n if (urlSyncEnabled && typeof window !== \"undefined\") window.addEventListener(\"popstate\", navigate);\n return () => {\n cancelled = true; controller.abort();\n restoreHandler.current = null;\n initialRestore.current = null;\n if (urlSyncEnabled && typeof window !== \"undefined\") window.removeEventListener(\"popstate\", navigate);\n };\n }, [sourceSchema.name, urlSyncEnabled, parameter, recordQueryUrl, updateQueryHistory]);\n // Activation pauses a mounted controller; it only initiates restoration if\n // this dataset has never started, preserving edits and history on tab switches.\n useEffect(() => {\n if (active && !initialRestorationStarted.current) void initialRestore.current?.();\n }, [active, sourceSchema.name, urlSyncEnabled, parameter, recordQueryUrl]);\n\n const { api: computed, displaySchema } = useComputedColumns({\n schema,\n query: executionQuery,\n rows,\n serverComputed,\n ...(serverExecution ? { serverExecution } : {}),\n ...(opts.computedExecution ? { execution: opts.computedExecution } : {}),\n ...(opts.computedColumnStore ? { store: opts.computedColumnStore } : {}),\n ...(opts.formulaWorkerFactory\n ? { workerFactory: opts.formulaWorkerFactory }\n : {}),\n ...(transport ? { transport } : {}),\n ...(clientRows ? { clientRows } : {}),\n });\n\n const resolveComputed = useCallback(\n (name: string) =>\n isComputedField(name)\n ? computed.compile(`[${name.replace(/]/g, \"]] \".trim())}]`)\n : undefined,\n [computed.compile],\n );\n const metricCompile = useCallback(\n (clause: AggregationClause) => {\n const diagnostics = validateMetric(\n clause,\n displaySchema,\n resolveComputed,\n );\n if (diagnostics.length)\n throw new Error(diagnostics.map((d) => d.message).join(\" \"));\n return metricPlans(clause, displaySchema, resolveComputed);\n },\n [displaySchema, resolveComputed],\n );\n const computedRevisions = useMemo(\n () =>\n Object.fromEntries(computed.definitions.map((d) => [d.id, d.revision])),\n [computed.definitions],\n );\n const definitionKey = JSON.stringify(computedRevisions);\n\n // Fetch (debounced + abortable). Transport mode, or client-side applyQuery.\n const queryKey = useMemo(() => JSON.stringify(query), [query]);\n const serverRowQuery = useMemo(() => {\n const execution = opts.computedExecution;\n const detailConfig = typeof opts.itemDetails === \"object\" ? opts.itemDetails : undefined;\n const page = query.itemDetails?.page ?? detailConfig?.page;\n const pageEnabled = Boolean(opts.itemDetails) && (query.itemDetails?.modes ?? initialDetailModes(detailConfig)).includes(\"page\")\n && (!detailConfig?.modes || detailConfig.modes.includes(\"page\"));\n const pageFields = pageEnabled ? itemPageFields(page?.urlTemplate ?? \"\") : [];\n // Page templates can use fields outside the visible projection. Ask the\n // transport for those dependencies through its usual SELECT planning.\n const requestQuery = pageFields.length ? { ...executionQuery, select: [...(query.select.length ? query.select : defaults.select),\n ...pageFields.filter(name => displaySchema.fields.some(field => field.name === name)).map(field => ({ field }))] } : executionQuery;\n const v2Request =\n execution && transport?.fetchRowsV2\n ? toServerQueryV2(requestQuery, displaySchema, execution)\n : undefined;\n const request = v2Request ?? toServerQuery(requestQuery, displaySchema);\n if (v2Request)\n for (const definition of computed.definitions) {\n if (\n (execution?.fields[computedFieldName(definition.id)]?.select ||\n v2Request.orderBy.some(\n (term) => term.field === computedFieldName(definition.id),\n )) &&\n executionRevision(execution, definition.id) !== undefined &&\n executionRevision(execution, definition.id) !== definition.revision\n )\n v2Request.diagnostics.push({\n from: 0,\n to: 1,\n code: \"definition_changed\",\n message:\n \"Computed definitions changed. Refresh the server execution handshake.\",\n });\n }\n // A shown-row metric may refer to columns outside the visible projection.\n for (const clause of query.aggregations ?? [])\n if (clause.scope === \"shownRows\") {\n try {\n for (const name of metricDependencies(\n clause,\n schema,\n resolveComputed,\n )) {\n const field = schema.fields.find((f) => f.name === name);\n if (field?.source.kind === \"backend\") request.select.push(name);\n else\n for (const dep of field?.source.kind === \"derived\"\n ? (field.source.dependencies ?? [])\n : [])\n request.select.push(dep);\n }\n } catch {\n /* Invalid metric stays editable and fails metric validation. */\n }\n }\n request.select = [...new Set(request.select)].sort();\n return request;\n }, [\n queryKey,\n displaySchema,\n transport,\n computedRevisions,\n schema,\n resolveComputed,\n opts.computedExecution,\n opts.itemDetails,\n defaults,\n ]);\n // Keep presentation-only query changes out of the expensive row pipeline.\n // Widths do not leave the client at all, and SELECT does not affect client-side\n // filtering/sorting/paging. The full queryKey still drives URL + persistence.\n const rowQueryKey = useMemo(\n () =>\n transport\n ? `server:${JSON.stringify(serverRowQuery)}:${transport.fetchQueryV3 ? JSON.stringify([groupKey, groupingNow,\n query.select.map(column => column.field), query.where, query.orderBy, query.limit, query.offset]) : \"\"}`\n : `client:${JSON.stringify([query.where, query.orderBy, query.limit, query.offset])}`,\n [\n transport,\n serverRowQuery,\n groupKey,\n groupingNow,\n query.select,\n query.where,\n query.orderBy,\n query.limit,\n query.offset,\n ],\n );\n const executionKey = JSON.stringify(opts.computedExecution ?? null);\n const pageContext = `${schema.name}:${rowQueryKey}:${nonce}:${executionKey}`;\n useEffect(() => {\n if (!active || !storageReady || restoration.loading || restoration.error) {\n setRows(previous => previous.length ? [] : previous); setTotal(null); setCommittedPage(null); setLoading(false);\n return;\n }\n const ac = new AbortController();\n let cancelled = false;\n const run = async () => {\n setLoading(true);\n setError(null);\n try {\n validateExecution(query);\n if (transport) {\n if (transport.fetchQueryV3 && transport.queryCapabilities?.version === 3 &&\n (query.grouping || query.select.some(column => isComputedField(column.field)) || query.orderBy.some(term => isComputedField(term.field)) ||\n query.where.some(term => (\"any\" in term ? term.any : [term]).some(predicate => isComputedField(predicate.field))))) {\n const request = toQueryRequestV3({ ...query, aggregations: [], select: [...query.select.filter(column => isComputedField(column.field)),\n ...serverRowQuery.select.map(field => ({ field }))] }, sourceSchema,\n transport.queryCapabilities, opts.computedExecution, { now: groupingNow ?? (opts.evaluationNow ?? Date.now)() });\n if (request.diagnostics.length) throw Error(request.diagnostics.join(\" \"));\n const result = await transport.fetchQueryV3(request, ac.signal);\n validateQueryResultV3(result, request, query.grouping ? schema : sourceCatalogue);\n if (!cancelled) {\n setCommittedFields(request.result.select); setServerExecution(result.execution);\n setServerComputed(new Map(result.rows.map(row => [row[schema.idField] as RowId,\n Object.fromEntries(Object.entries(row).filter(([name]) => isComputedField(name)).map(([name, value]) =>\n [name.slice(10), value && typeof value === \"object\" && \"computedError\" in value\n ? { value: null, error: { code: String(value.computedError) } } : { value: value as import(\"@pythia-software/query-table-core\").MetricValue }]))])));\n setRows(result.rows as Row[]); setTotal(result.total); setCommittedPage(pageContext);\n setCommittedSource({ schema, transport, clientRows });\n }\n return;\n }\n const useV2 = \"version\" in serverRowQuery && transport.fetchRowsV2;\n if (\n \"diagnostics\" in serverRowQuery &&\n Array.isArray(serverRowQuery.diagnostics) &&\n serverRowQuery.diagnostics.length\n )\n throw Error(\n serverRowQuery.diagnostics.map((d) => d.message).join(\" \"),\n );\n if (!useV2 && query.orderBy.some((s) => isComputedField(s.field)))\n throw Error(\n \"Global computed sorting requires a server execution handshake and fetchRowsV2.\",\n );\n const res = useV2\n ? await transport.fetchRowsV2!(\n serverRowQuery as ReturnType<typeof toServerQueryV2<Row>>,\n ac.signal,\n )\n : await transport.fetchRows(serverRowQuery, ac.signal);\n if (useV2)\n validateComputedResponse(\n serverRowQuery as ReturnType<typeof toServerQueryV2<Row>>,\n res as import(\"@pythia-software/query-table-core\").FetchRowsResultV2<Row>,\n schema,\n );\n if (!cancelled) {\n setCommittedFields(serverRowQuery.select);\n setServerExecution(\n useV2\n ? (\n res as import(\"@pythia-software/query-table-core\").FetchRowsResultV2<Row>\n ).execution\n : undefined,\n );\n if (\"computed\" in res && Array.isArray(res.computed))\n setServerComputed(\n new Map(res.computed.map((c) => [c.id, c.values])),\n );\n else setServerComputed(new Map());\n setRows(res.rows);\n setTotal(res.total);\n setCommittedPage(pageContext);\n setCommittedSource({ schema, transport, clientRows });\n }\n } else {\n const res = applyQuery(clientRows ?? [], executionQuery, schema,\n groupingNow !== undefined ? { now: groupingNow } : {});\n if (!cancelled) {\n setRows(res.rows);\n setTotal(res.total);\n setCommittedPage(pageContext);\n setCommittedSource({ schema, transport, clientRows });\n }\n }\n } catch (e) {\n if (!cancelled && !ac.signal.aborted) {\n setError(e as Error);\n setRows([]);\n setTotal(null);\n setCommittedPage(null);\n }\n } finally {\n if (!cancelled) setLoading(false);\n }\n };\n const t = setTimeout(run, debounceMs);\n return () => {\n cancelled = true;\n clearTimeout(t);\n ac.abort();\n };\n // rowQueryKey captures only row-affecting query state; clientRows/nonce\n // force refetch. Presentation changes still sync/persist via queryKey below.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n rowQueryKey,\n transport,\n clientRows,\n schema,\n debounceMs,\n nonce,\n validateExecution,\n executionKey,\n groupingNow,\n restoration,\n active,\n storageReady,\n ]);\n\n // Persist last query (debounced).\n useEffect(() => {\n if (!storageReady || restoration.loading || restoration.error) return;\n const t = setTimeout(() => void storage.saveLast(sourceSchema.name, query), 400);\n return () => clearTimeout(t);\n }, [queryKey, storage, sourceSchema.name, query, restoration, storageReady]);\n\n // Resolved id accessor.\n const idField = useMemo(\n () => schema.fields.find((f) => f.name === schema.idField),\n [schema],\n );\n const rowId = useCallback(\n (row: Row): RowId | null =>\n (() => {\n const value = idField ? readFieldValue(idField, row) : (row as Record<string, unknown> | null)?.[schema.idField];\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value)) ? value : null;\n })(),\n [idField, schema.idField],\n );\n\n // Sub-APIs.\n const displayedIds = useMemo(\n () => rows.map(rowId).filter((id): id is RowId => id != null),\n [rows, rowId],\n );\n const selection = useSelection(displayedIds);\n const identityScope = JSON.stringify([sourceSchema.name, query.grouping?.keys ?? null]);\n useEffect(() => { selection.clear(); }, [identityScope, selection.clear]);\n const columnSchema = useMemo(() => detailColumnSchema(displaySchema, detailsEnabled), [displaySchema, detailsEnabled]);\n const resultDefaults = useMemo(() => query.grouping ? defaultsFor(schema) : defaults, [Boolean(query.grouping), schema, defaults]);\n const select = useSelect(query, setQuery, columnSchema);\n const columnDrag = useColumnDrag();\n const savedQueries = useSavedQueries(\n sourceSchema.name,\n query,\n (q) => {\n const normalized = normalizeQueryState(q, defaults);\n savedBaseline.current = { source: sourceSchema.name, query: cloneQueryState(normalized) };\n viewRevision.current++;\n setQuery(normalized);\n },\n storage,\n now,\n links.snapshot,\n );\n const saved: SavedQueriesApi = { ...savedQueries, save: async name => {\n const item = await savedQueries.save(name);\n savedBaseline.current = { source: sourceSchema.name, query: cloneQueryState(normalizeQueryState(item.query, defaults)) };\n viewRevision.current++;\n return item;\n } };\n const pageReady =\n committedPage === pageContext &&\n committedSource?.schema === schema &&\n committedSource?.transport === transport &&\n committedSource?.clientRows === clientRows &&\n !error;\n const dataToken = useRef(0);\n const dataVersion = useMemo(\n () => ++dataToken.current,\n [schema, transport, clientRows, nonce, definitionKey, executionKey],\n );\n const executeV3Metrics = useCallback(async (metricQuery: QueryState, signal?: AbortSignal) => {\n if (!transport?.fetchQueryV3 || transport.queryCapabilities?.version !== 3) throw Error(\"The v3 query executor is unavailable.\");\n const request = toQueryRequestV3(query.grouping ? { ...metricQuery, grouping: query.grouping } : metricQuery,\n sourceSchema, transport.queryCapabilities, opts.computedExecution, { now: groupingNow ?? (opts.evaluationNow ?? Date.now)(), rows: false });\n if (request.diagnostics.length) throw Error(request.diagnostics.join(\" \"));\n const result = await transport.fetchQueryV3(request, signal);\n validateQueryResultV3(result, request, query.grouping ? schema : sourceCatalogue);\n return { metrics: result.metrics };\n }, [transport, sourceSchema, sourceCatalogue, schema, opts.computedExecution, groupKey, groupingNow, opts.evaluationNow]);\n const previewGrouping = useCallback(async (draft: QueryState, signal?: AbortSignal) => {\n if (!active || !storageReady || restoration.loading || restoration.error) throw Error(\"Wait for query restoration before previewing groups.\");\n if (!transport?.fetchQueryV3 || !transport.queryCapabilities?.groupedRows || !draft.grouping) throw Error(\"The server group preview is unavailable.\");\n const request = toQueryRequestV3({ ...draft, aggregations: [] }, sourceSchema, transport.queryCapabilities,\n opts.computedExecution, { now: groupingNow ?? (opts.evaluationNow ?? Date.now)() });\n if (request.diagnostics.length) throw Error(request.diagnostics.join(\" \"));\n const result = await transport.fetchQueryV3(request, signal);\n validateQueryResultV3(result, request, groupingModel.resultSchema(draft.grouping.keys, draft.grouping.summaries));\n return { rows: result.rows, total: result.total, sourceTotal: result.sourceTotal };\n }, [transport, sourceSchema, opts.computedExecution, groupingModel, groupingNow, opts.evaluationNow, active, storageReady, restoration.loading, restoration.error]);\n const aggState = useAggregations(\n executionQuery,\n schema,\n transport,\n clientRows,\n debounceMs,\n nonce,\n validateExecution,\n {\n ...(transport?.fetchQueryV3 && transport.queryCapabilities?.version === 3 &&\n (query.grouping || query.aggregations?.some(metric => metric.dateGrouping) ||\n query.where.some(term => (\"any\" in term ? term.any : [term]).some(predicate => isComputedField(predicate.field))))\n ? { executeV3: executeV3Metrics, queryContextKey: groupKey } : {}),\n ...(groupingNow !== undefined ? { now: groupingNow, strictLocalMetrics: true } : {}),\n shownRows: rows,\n rowsReady: pageReady,\n rowsError: error,\n ...(transport ? { shownFields: committedFields } : {}),\n resolveComputed,\n revisions: computedRevisions,\n ...(opts.computedExecution\n ? {\n execution:\n pageReady && serverExecution\n ? serverExecution\n : opts.computedExecution,\n }\n : {}),\n ...(opts.formulaWorkerFactory\n ? { workerFactory: opts.formulaWorkerFactory }\n : {}),\n },\n active && storageReady && !restoration.loading && !restoration.error,\n );\n const queryRef = useRef(query);\n queryRef.current = query;\n const replaceAggregations = useCallback(\n (clauses: AggregationClause[], expected?: AggregationClause[]) => {\n if (\n expected &&\n JSON.stringify(queryRef.current.aggregations ?? []) !==\n JSON.stringify(expected)\n )\n throw new Error(\n \"Metrics changed while editing. Reopen the editor to use the latest configuration.\",\n );\n for (const clause of clauses) metricCompile(clause);\n setQuery((q) => ({\n ...q,\n aggregations: JSON.parse(\n JSON.stringify(clauses),\n ) as AggregationClause[],\n }));\n },\n [setQuery, metricCompile],\n );\n\n const canUndo = queryHistory.past.length > 0;\n const canRedo = queryHistory.future.length > 0;\n\n const undo = useCallback(() => {\n if (!queryHistoryRef.current.past.length) return;\n manualQueryEpoch.current++;\n restoreController.current?.abort();\n setStorageReady(true);\n setRestoration({ loading: false, error: null });\n updateQueryHistory((history) => {\n const previous = history.past[history.past.length - 1];\n if (!previous) return history;\n return { query: cloneQueryState(previous), past: history.past.slice(0, -1), future: [...history.future, cloneQueryState(history.query)] };\n });\n }, [updateQueryHistory]);\n\n const redo = useCallback(() => {\n if (!queryHistoryRef.current.future.length) return;\n manualQueryEpoch.current++;\n restoreController.current?.abort();\n setStorageReady(true);\n setRestoration({ loading: false, error: null });\n updateQueryHistory((history) => {\n const next = history.future[history.future.length - 1];\n if (!next) return history;\n return { query: cloneQueryState(next), past: [...history.past, cloneQueryState(history.query)], future: history.future.slice(0, -1) };\n });\n }, [updateQueryHistory]);\n\n // ---- intent helpers (keep offset/url/storage coherent) ----\n const patch = useCallback(\n (p: Partial<QueryState>) => setQuery((prev) => ({ ...prev, ...p })),\n [setQuery],\n );\n\n const { addFilter, updateFilter, removeFilter, clearFilters, updatePredicate, removePredicate, negatePredicate, reorderFilters, mergeFilters } = useQueryFilters(schema, setQuery);\n\n const resetAll = useCallback(\n () => {\n const baseline = savedBaseline.current;\n viewRevision.current++;\n setQuery(cloneQueryState(baseline?.source === sourceSchema.name ? baseline.query : defaults));\n },\n [setQuery, defaults, sourceSchema.name],\n );\n\n // ---- aggregation metric mutators (don't touch paging — scope is the whole set) ----\n const addAggregation = useCallback<AggregationsApi[\"add\"]>(\n (partial) => {\n const id = `a${nowRef.current()}-${aggIdRef.current++}`;\n const clause: AggregationClause = {\n id,\n op: \"count\",\n groupBy: [],\n ...partial,\n };\n setQuery((q) => ({\n ...q,\n aggregations: [...(q.aggregations ?? []), clause],\n }));\n return id;\n },\n [setQuery],\n );\n const updateAggregation = useCallback<AggregationsApi[\"update\"]>(\n (id, patch) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).map((a) =>\n a.id === id ? mergeAggregation(a, patch) : a,\n ),\n })),\n [setQuery],\n );\n const moveAggregation = useCallback<AggregationsApi[\"move\"]>(\n (id, toIndex) =>\n setQuery((q) => {\n const current = q.aggregations ?? [];\n const from = current.findIndex((a) => a.id === id);\n if (from === -1) return q;\n const next = [...current];\n const [item] = next.splice(from, 1);\n next.splice(Math.max(0, Math.min(toIndex, next.length)), 0, item!);\n return { ...q, aggregations: next };\n }),\n [setQuery],\n );\n const removeAggregation = useCallback<AggregationsApi[\"remove\"]>(\n (id) =>\n setQuery((q) => ({\n ...q,\n aggregations: (q.aggregations ?? []).filter((a) => a.id !== id),\n })),\n [setQuery],\n );\n const clearAggregations = useCallback<AggregationsApi[\"clear\"]>(\n () => setQuery((q) => ({ ...q, aggregations: [] })),\n [setQuery],\n );\n\n const setSort = useCallback(\n (orderBy: OrderByClause[]) =>\n setQuery((q) => ({ ...q, offset: 0, orderBy })),\n [setQuery],\n );\n const toggleSort = useCallback(\n (field: string, additive = false) =>\n setQuery((q) => ({\n ...q,\n offset: 0,\n orderBy: nextOrderBy(q.orderBy, field, additive),\n })),\n [setQuery],\n );\n\n const setLimit = useCallback(\n (limit: number) => patch({ limit, offset: 0 }),\n [patch],\n );\n const setOffset = useCallback((offset: number) => patch({ offset }), [patch]);\n const nextPage = useCallback(\n () => setQuery((q) => ({ ...q, offset: q.offset + q.limit })),\n [setQuery],\n );\n const prevPage = useCallback(\n () => setQuery((q) => ({ ...q, offset: Math.max(0, q.offset - q.limit) })),\n [setQuery],\n );\n\n const filterValues = useCallback(\n async (field: string, search: string): Promise<DistinctValuesResult> => {\n if (!metadataTransport?.fetchDistinctValues || query.grouping && !query.grouping.keys.includes(field)) {\n const f = byName.get(field);\n if (!f || !clientRows) return { values: [], hasMore: false };\n\n const fieldHasNull = fieldHasNullInRows(f, clientRows);\n const matches = distinctValuesFromRows(f, clientRows, search);\n\n return {\n values: matches.values,\n hasMore: matches.hasMore,\n hasNull: fieldHasNull,\n };\n }\n return metadataTransport.fetchDistinctValues({ field, search });\n },\n [metadataTransport, byName, clientRows, groupKey],\n );\n\n const fieldStats = useCallback<QueryTableApi<Row>[\"fieldStats\"]>(\n async (fields, signal) => {\n const requested = [...new Set(fields)];\n if (metadataTransport?.fetchFieldStats && !query.grouping) {\n const backendFields = requested.filter(\n (name) => byName.get(name)?.source.kind === \"backend\",\n );\n return backendFields.length\n ? metadataTransport.fetchFieldStats(backendFields, signal)\n : {};\n }\n if (!clientRows) return {};\n\n const result: Record<string, FieldStats> = {};\n for (const name of requested) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const field = byName.get(name);\n if (!field) continue;\n const distinct = new Set<string>();\n for (const row of clientRows) {\n const value = readFieldValue(field, row);\n if (value !== null) distinct.add(JSON.stringify(value));\n }\n result[name] = { distinct: distinct.size };\n }\n return result;\n },\n [metadataTransport, byName, clientRows, groupKey],\n );\n\n // Single refresh seam: re-runs the internal query (setNonce) and fires the\n // consumer's onRefresh, if any. Both the manual `api.refresh()` and every\n // auto-refresh tick go through here, so they stay observably identical. Read\n // onRefresh through a ref to keep this callback (and the interval that depends\n // on it) stable across renders.\n const refresh = useCallback(() => {\n setNonce((n) => n + 1);\n onRefreshRef.current?.();\n }, []);\n const stopAutoRefresh = useCallback(() => setAutoRefreshStatus(null), []);\n const startAutoRefresh = useCallback(\n ({ frequencyMs, turnOffAfterMs }: AutoRefreshConfig) => {\n const pollCount =\n frequencyMs > 0 && turnOffAfterMs > 0\n ? Math.floor(turnOffAfterMs / frequencyMs)\n : 0;\n if (pollCount < 1 || pollCount > MAX_AUTO_REFRESH_POLLS) {\n throw new Error(\"Auto-refresh must schedule between 1 and 1000 polls.\");\n }\n\n const startedAt = nowRef.current();\n refresh();\n setAutoRefreshStatus({\n frequencyMs,\n turnOffAfterMs,\n startedAt,\n stopsAt: startedAt + turnOffAfterMs,\n pollCount: 1,\n });\n },\n [refresh],\n );\n\n const autoRefreshFrequencyMs = autoRefreshStatus?.frequencyMs ?? null;\n const autoRefreshStopsAt = autoRefreshStatus?.stopsAt ?? null;\n\n useEffect(() => {\n if (autoRefreshFrequencyMs == null || autoRefreshStopsAt == null) return;\n\n const tick = () => {\n if (nowRef.current() >= autoRefreshStopsAt) {\n setAutoRefreshStatus((current) =>\n current?.stopsAt === autoRefreshStopsAt ? null : current,\n );\n return;\n }\n\n refresh();\n setAutoRefreshStatus((current) => {\n if (!current) return current;\n if (current.stopsAt !== autoRefreshStopsAt) return current;\n return { ...current, pollCount: current.pollCount + 1 };\n });\n };\n\n const interval = setInterval(tick, autoRefreshFrequencyMs);\n const timeout = setTimeout(\n () =>\n setAutoRefreshStatus((current) =>\n current?.stopsAt === autoRefreshStopsAt ? null : current,\n ),\n Math.max(0, autoRefreshStopsAt - nowRef.current()),\n );\n\n return () => {\n clearInterval(interval);\n clearTimeout(timeout);\n };\n }, [autoRefreshFrequencyMs, autoRefreshStopsAt, refresh]);\n\n const autoRefresh = useMemo<AutoRefreshApi>(\n () => ({\n status: autoRefreshStatus,\n start: startAutoRefresh,\n stop: stopAutoRefresh,\n }),\n [autoRefreshStatus, startAutoRefresh, stopAutoRefresh],\n );\n\n const refreshRow = useCallback(\n async (id: RowId) => {\n if (opts.computedExecution && transport?.fetchRowsV2) {\n // Base rows and computed sidecars belong to one committed page. A\n // single-row fetch cannot replace either independently, and changes\n // to a computed sort may also change page membership.\n refresh();\n return;\n }\n if (!transport?.fetchRow) return;\n const updated = await transport.fetchRow(id);\n setRows((prev) =>\n prev.map((r) => (rowId(r) === id ? (updated ?? r) : r)),\n );\n },\n [transport, rowId, opts.computedExecution, refresh],\n );\n\n const visibleFields = useMemo(\n () => selectedFields(columnSchema, query),\n [columnSchema, query],\n );\n\n const aggregations = useMemo<AggregationsApi>(\n () => ({\n clauses: query.aggregations ?? [],\n results: aggState.results,\n loading: aggState.loading,\n error: aggState.error,\n add: addAggregation,\n update: updateAggregation,\n move: moveAggregation,\n remove: removeAggregation,\n clear: clearAggregations,\n preview: aggState.preview,\n replace: replaceAggregations,\n compile: metricCompile,\n contextKey: `${dataVersion}:${pageContext}:${pageReady}:${JSON.stringify(query.where)}`,\n }),\n [\n query.aggregations,\n aggState.results,\n aggState.loading,\n aggState.error,\n addAggregation,\n updateAggregation,\n moveAggregation,\n removeAggregation,\n clearAggregations,\n aggState.preview,\n replaceAggregations,\n metricCompile,\n pageContext,\n pageReady,\n dataVersion,\n query.where,\n ],\n );\n\n const sourceRowId = useCallback((row: Row): RowId | null => {\n const field = sourceSchema.fields.find(f => f.name === sourceSchema.idField);\n const value = field ? readFieldValue(field, row) : (row as Record<string, unknown>)[sourceSchema.idField];\n return typeof value === \"string\" || (typeof value === \"number\" && Number.isFinite(value)) ? value : null;\n }, [sourceSchema]);\n\n const itemDetails = useItemDetails({\n schema: query.grouping ? sourceSchema : displaySchema,\n query: sourceQuery, setQuery: setSourceQuery, options: opts.itemDetails,\n rows: query.grouping ? sourceRows ?? [] : rows, clientRows: sourceRows,\n rowId: sourceRowId, transport: metadataTransport, refreshKey: nonce, links, queryParameter: parameter,\n queryReady: storageReady && !restoration.loading && !restoration.error,\n });\n\n const api: QueryTableApi<Row> = {\n restoration: { status: restoration.error ? \"error\" : !storageReady || restoration.loading ? \"resolving\" : \"ready\",\n ready: active && storageReady && !restoration.loading && !restoration.error, error: restoration.error },\n restoreLocation,\n links,\n schema: columnSchema,\n ...(itemDetails && detailsEnabled ? { itemDetails } : {}),\n query,\n defaults: resultDefaults,\n setQuery,\n rows,\n total,\n loading: loading || restoration.loading,\n error: restoration.error ?? error,\n requestActivity,\n canUndo,\n canRedo,\n undo,\n redo,\n refresh,\n autoRefresh,\n refreshRow,\n aggregations,\n addFilter,\n updateFilter,\n removeFilter,\n clearFilters,\n updatePredicate,\n removePredicate,\n negatePredicate,\n reorderFilters,\n mergeFilters,\n resetAll,\n filterValues,\n fieldStats,\n toggleSort,\n setSort,\n select,\n computed,\n setLimit,\n setOffset,\n nextPage,\n prevPage,\n selection,\n saved,\n columnDrag,\n visibleFields,\n rowId,\n };\n const sourceApi: GroupingSourceApi<Row> = {\n ...sourceFilters, loading, rowId: sourceRowId, query: sourceQuery, setQuery: setSourceQuery,\n ...(itemDetails ? { itemDetails } : {}),\n schema: sourceCatalogue,\n filterValues: async (name, search) => {\n if (metadataTransport?.fetchDistinctValues) return metadataTransport.fetchDistinctValues({ field: name, search });\n const field = groupingModel.sourceField(name);\n return field && sourceRows ? { ...distinctValuesFromRows(field, sourceRows, search), hasNull: fieldHasNullInRows(field, sourceRows) } : { values: [], hasMore: false };\n },\n fieldStats: async (names, signal) => {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const requested = [...new Set(names)];\n if (metadataTransport?.fetchFieldStats) {\n const backendFields = requested.filter(\n name => sourceCatalogue.fields.find(field => field.name === name)?.source.kind === \"backend\",\n );\n return backendFields.length ? metadataTransport.fetchFieldStats(backendFields, signal) : {};\n }\n return Object.fromEntries(requested.flatMap(name => {\n const field = groupingModel.sourceField(name);\n return field && sourceRows ? [[name, { distinct: new Set(sourceRows.map(row => JSON.stringify(readFieldValue(field, row)))).size }]] : [];\n }));\n },\n };\n const grouping = useGroupingController(api, sourceApi, groupingModel, prepared?.inputs ?? sourceRows ?? [], groupingSupported, viewRevision.current,\n { inputsReady: !remoteGrouping, ...(remoteGrouping ? { preview: previewGrouping } : {}) });\n return {\n ...api,\n ...(groupingSupported || query.grouping ? { grouping } : {}),\n select: { ...select, hide: field => query.grouping?.keys.includes(field)\n ? grouping.changeKeys(query.grouping.keys.filter(key => key !== field)) : select.hide(field) },\n };\n}\n\n/** Multi-sort header click logic.\n * - plain click on the sole sorted column → flip its direction\n * - plain click on another column → make it the only sort (desc)\n * - shift-click a new column → append it (desc) as a secondary term\n * - shift-click an existing term → cycle desc → asc → remove */\nfunction nextOrderBy(\n existing: OrderByClause[],\n field: string,\n additive: boolean,\n): OrderByClause[] {\n const i = existing.findIndex((s) => s.field === field);\n if (!additive) {\n if (i === 0 && existing.length === 1) {\n const flipped: \"asc\" | \"desc\" =\n existing[0]!.dir === \"desc\" ? \"asc\" : \"desc\";\n return [{ ...existing[0]!, dir: flipped }];\n }\n return [{ field, dir: \"desc\" }];\n }\n if (i === -1) return [...existing, { field, dir: \"desc\" }];\n const cur = existing[i]!;\n if (cur.dir === \"desc\") {\n const next = [...existing];\n next[i] = { ...cur, dir: \"asc\" };\n return next;\n }\n return existing.filter((_, k) => k !== i); // asc → remove\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n FieldSchema, ItemDetailMode, ItemPropertyMode, ItemPageOptions, ItemDetailsState, PropertyViewStorage,\n QueryState, RelationshipAdapter, RowId, Transport, PropertyViewState,\n} from \"@pythia-software/query-table-core\";\nimport { usePropertyView, type PropertyViewApi } from \"./usePropertyView\";\nimport type { QueryLinksApi } from \"./useQueryLinks\";\n\nexport interface ItemDetailRecord<Row> {\n row: Row;\n /** Omit for complete records. Supply for a projection to distinguish missing values from NULL. */\n loadedFields?: readonly string[];\n}\nexport interface ItemDetailsOptions<Row> {\n /** Detail catalogue; defaults to the table catalogue. Useful for non-column properties. */\n schema?: FieldSchema<Row>;\n /** Legacy collection URL parameter. useQueryTable.queryParameter takes precedence. */\n queryParameter?: string;\n /** Creator-approved modalities; users can enable/disable these in Select columns. Defaults to all. */\n modes?: ItemDetailMode[];\n /** Initially selected buttons. Defaults to Modal (or the first allowed mode). */\n defaultModes?: ItemDetailMode[];\n /** Creator's initial Page link settings; users can override in the column editor. */\n page?: ItemPageOptions;\n storage?: PropertyViewStorage;\n objectType?: string;\n relationships?: RelationshipAdapter;\n /** Defaults to complete clientRows or Transport.fetchRow, then the current projected row. */\n loadRow?: (id: RowId, signal: AbortSignal) => Promise<ItemDetailRecord<Row> | null>;\n}\nexport interface ItemDetailsApi<Row> {\n links?: QueryLinksApi;\n schema: FieldSchema<Row>;\n /** Collection catalogue used to resolve Page template fields. */\n pageSchema: FieldSchema<Row>;\n queryParameter: string;\n /** Modal controller, retained for standalone cards. */\n properties: PropertyViewApi;\n propertiesByMode: Record<ItemPropertyMode, PropertyViewApi>;\n page: ItemPageOptions;\n availableModes: ItemDetailMode[];\n modes: ItemDetailMode[];\n active: ItemDetailsState[\"active\"] | null;\n record: ItemDetailRecord<Row> | null;\n loading: boolean;\n error: Error | null;\n relationships?: RelationshipAdapter;\n setModes(modes: ItemDetailMode[]): void;\n open(id: RowId, mode: \"modal\" | \"expand\"): void;\n close(): void;\n retry(): void;\n loadRow(id: RowId, signal: AbortSignal): Promise<ItemDetailRecord<Row> | null>;\n}\nconst ALL_MODES: ItemDetailMode[] = [\"hover\", \"modal\", \"expand\", \"page\"];\nexport function initialDetailModes<Row>(config: ItemDetailsOptions<Row> | undefined): ItemDetailMode[] {\n const available = ALL_MODES.filter(mode => !config?.modes || config.modes.includes(mode));\n return config?.defaultModes ? available.filter(mode => config.defaultModes!.includes(mode))\n : available.includes(\"modal\") ? [\"modal\"] : available.slice(0, 1);\n}\n\n/** Synchronize a single modality without overwriting its siblings. */\nfunction useDetailProperties<Row>(mode: ItemPropertyMode, schema: FieldSchema<Row>, config: ItemDetailsOptions<Row> | undefined,\n query: QueryState, setQuery: (next: QueryState | ((previous: QueryState) => QueryState)) => void, enabled: boolean): PropertyViewApi {\n const snapshot = query.itemDetails?.views?.[mode] ?? query.itemDetails?.view;\n const seed = useRef(snapshot);\n const properties = usePropertyView({ schema,\n ...(config?.storage ? { storage: config.storage } : {}),\n key: `${config?.objectType ?? schema.name}:${mode}`,\n ...(seed.current ? { initialView: seed.current } : {}),\n });\n const queryViewKey = JSON.stringify(snapshot);\n const localViewKey = JSON.stringify(properties.view);\n const previousView = useRef({ query: queryViewKey, local: localViewKey });\n const baselineView = useRef(properties.view);\n const baselineReady = useRef(false);\n const pendingView = useRef<{ query: string | undefined; local: string } | null>(null);\n useEffect(() => {\n if (!enabled) return;\n if (!properties.loading && !baselineReady.current) {\n baselineView.current = properties.view;\n baselineReady.current = true;\n }\n const previous = previousView.current;\n previousView.current = { query: queryViewKey, local: localViewKey };\n if (queryViewKey !== previous.query) {\n const next = snapshot ?? baselineView.current;\n const target = JSON.stringify(next);\n pendingView.current = target !== localViewKey ? { query: queryViewKey, local: target } : null;\n if (target !== localViewKey) properties.setView(next);\n } else if (pendingView.current && pendingView.current.query === queryViewKey) {\n if (pendingView.current.local === localViewKey) pendingView.current = null;\n } else if (!properties.loading && localViewKey !== queryViewKey && (queryViewKey !== undefined || localViewKey !== previous.local)) {\n setQuery((current) => ({ ...current, itemDetails: {\n modes: current.itemDetails?.modes ?? initialDetailModes(config),\n ...current.itemDetails,\n views: { ...current.itemDetails?.views, [mode]: properties.view },\n } }));\n }\n }, [enabled, queryViewKey, localViewKey, properties.loading, properties.setView, setQuery]);\n return properties;\n}\n\n/** Independent, type-level property controllers for each detail modality. */\nexport function useItemDetails<Row>({\n schema, query, setQuery, options, rows, clientRows, rowId, transport, refreshKey, links, queryReady = true, queryParameter,\n}: {\n schema: FieldSchema<Row>;\n query: QueryState;\n setQuery: (next: QueryState | ((previous: QueryState) => QueryState)) => void;\n options: boolean | ItemDetailsOptions<Row> | undefined;\n rows: Row[];\n clientRows: Row[] | undefined;\n rowId: (row: Row) => RowId | null;\n transport: Transport<Row> | undefined;\n refreshKey: number;\n links?: QueryLinksApi;\n queryParameter?: string;\n /** Hold property-view synchronization while the collection query is restoring. */\n queryReady?: boolean;\n}): ItemDetailsApi<Row> | undefined {\n const enabled = Boolean(options);\n const config = typeof options === \"object\" ? options : undefined;\n const detailSchema = config?.schema ?? schema;\n const availableModes = ALL_MODES.filter((mode) => !config?.modes || config.modes.includes(mode));\n const modes = availableModes.filter((mode) => (query.itemDetails?.modes ?? initialDetailModes(config)).includes(mode));\n const page = query.itemDetails?.page ?? config?.page ?? { urlTemplate: \"\", target: \"_blank\" as const };\n const requested = query.itemDetails?.active;\n const sharedModal = requested?.mode === \"modal\" && query.itemDetails?.modes.includes(\"modal\")\n && (availableModes.includes(\"hover\") || (availableModes.includes(\"page\") && !page.urlTemplate.trim()));\n const active = requested && (modes.includes(requested.mode) || sharedModal) ? requested : null;\n // Property storage can hydrate independently, but must not apply its view to\n // a placeholder query and thereby cancel a pending URL/saved-query restore.\n const syncProperties = enabled && queryReady;\n const modalProperties = useDetailProperties(\"modal\", detailSchema, config, query, setQuery, syncProperties);\n const hoverProperties = useDetailProperties(\"hover\", detailSchema, config, query, setQuery, syncProperties);\n const expandProperties = useDetailProperties(\"expand\", detailSchema, config, query, setQuery, syncProperties);\n const propertiesByMode = { modal: modalProperties, hover: hoverProperties, expand: expandProperties };\n const views: Record<ItemPropertyMode, PropertyViewState> = {\n modal: modalProperties.view, hover: hoverProperties.view, expand: expandProperties.view,\n };\n\n const customLoad = config?.loadRow;\n const customLoadRef = useRef(customLoad);\n customLoadRef.current = customLoad;\n // Inline host callbacks should not restart a request on every controller\n // render. Data-source/type changes and explicit refresh/retry still reload.\n const hasCustomLoad = Boolean(customLoad);\n const sourceType = config?.objectType ?? detailSchema.name;\n const fallbackRows = !customLoad && !clientRows && !transport?.fetchRow ? rows : undefined;\n const loadRow = useCallback(async (id: RowId, signal: AbortSignal): Promise<ItemDetailRecord<Row> | null> => {\n if (customLoadRef.current) return customLoadRef.current(id, signal);\n if (clientRows) {\n const row = clientRows.find((row) => rowId(row) === id);\n return row ? { row } : null;\n }\n if (transport?.fetchRow) {\n const row = await transport.fetchRow(id, signal);\n return row ? { row } : null;\n }\n const row = rows.find((row) => rowId(row) === id);\n return row ? { row, loadedFields: Object.keys(row as object) } : null;\n }, [hasCustomLoad, sourceType, clientRows, transport?.fetchRow, fallbackRows, rowId]);\n const [retryKey, setRetryKey] = useState(0);\n const [result, setResult] = useState<{\n source: typeof loadRow | undefined; epoch: string; id: RowId | undefined; record: ItemDetailRecord<Row> | null; loading: boolean; error: Error | null;\n }>({ source: undefined, epoch: \"\", id: undefined, record: null, loading: false, error: null });\n const activeId = enabled ? active?.id : undefined;\n const epoch = `${refreshKey}:${retryKey}`;\n const currentResult = result.id === activeId && result.source === loadRow && result.epoch === epoch;\n useEffect(() => {\n const controller = new AbortController();\n if (activeId === undefined) {\n setResult((previous) => previous.id === undefined && !previous.loading && !previous.error && !previous.record ? previous : { source: undefined, epoch: \"\", id: undefined, record: null, loading: false, error: null });\n return;\n }\n setResult({ source: loadRow, epoch, id: activeId, record: null, loading: true, error: null });\n void Promise.resolve().then(() => loadRow(activeId, controller.signal)).then((record) => {\n if (!controller.signal.aborted) setResult({ source: loadRow, epoch, id: activeId, record, loading: false, error: null });\n }).catch((error) => {\n if (!controller.signal.aborted) setResult({ source: loadRow, epoch, id: activeId, record: null, loading: false,\n error: error instanceof Error ? error : new Error(String(error)) });\n });\n return () => controller.abort();\n }, [activeId, loadRow, refreshKey, retryKey]);\n if (!enabled) return;\n return {\n ...(links ? { links } : {}),\n schema: detailSchema, queryParameter: queryParameter ?? config?.queryParameter ?? \"q\", properties: modalProperties, propertiesByMode, availableModes, modes, active,\n page, pageSchema: schema,\n record: currentResult ? result.record : null,\n loading: activeId !== undefined && (!currentResult || result.loading),\n error: currentResult ? result.error : null,\n ...(config?.relationships ? { relationships: config.relationships } : {}),\n loadRow,\n retry: () => setRetryKey((value) => value + 1),\n setModes(next) {\n setQuery((current) => {\n const allowed = availableModes.filter((mode) => next.includes(mode));\n const state: ItemDetailsState = { ...current.itemDetails, modes: allowed, views };\n if (state.active && !allowed.includes(state.active.mode)) delete state.active;\n return { ...current, itemDetails: state };\n });\n },\n open(id, mode) {\n if (!modes.includes(mode)) return;\n setQuery((current) => ({ ...current, itemDetails: {\n ...current.itemDetails, modes: current.itemDetails?.modes ?? modes,\n views, active: { id, mode },\n } }));\n },\n close() {\n setQuery((current) => {\n if (!current.itemDetails?.active) return current;\n const { active: _active, ...state } = current.itemDetails;\n return { ...current, itemDetails: state };\n });\n },\n };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n createPropertyView,\n memoryPropertyViewStorage,\n normalizePropertyView,\n type FieldSchema,\n type PropertyViewState,\n type PropertyViewStorage,\n type SavedPropertyView,\n} from \"@pythia-software/query-table-core\";\n\nexport interface UsePropertyViewOptions<Row> {\n schema: FieldSchema<Row>;\n /** Object type, never object ID. Defaults to schema.name. */\n key?: string;\n storage?: PropertyViewStorage;\n initialView?: PropertyViewState;\n}\nexport interface PropertyViewApi {\n view: PropertyViewState;\n loading: boolean;\n error: Error | null;\n saved: SavedPropertyView[];\n defaultId: string | null;\n setView(view: PropertyViewState): void;\n reset(): void;\n undo(): void;\n redo(): void;\n canUndo: boolean;\n canRedo: boolean;\n load(id: string): void;\n save(name: string): Promise<SavedPropertyView>;\n remove(id: string): Promise<void>;\n setDefault(id: string | null): Promise<void>;\n}\nconst asError = (error: unknown) =>\n error instanceof Error ? error : new Error(String(error));\n\n/** Owns presentation only. Changing the inspected row never resets this controller. */\nexport function usePropertyView<Row>(\n options: UsePropertyViewOptions<Row>,\n): PropertyViewApi {\n const [memory] = useState(memoryPropertyViewStorage);\n const storage = options.storage ?? memory;\n const key = options.key ?? options.schema.name;\n const schemaDefault = useMemo(() => createPropertyView(options.schema), [options.schema]);\n const fallback = useMemo(\n () =>\n options.initialView\n ? normalizePropertyView(options.initialView)\n : schemaDefault,\n [options.initialView, schemaDefault],\n );\n const defaults = useRef(schemaDefault);\n defaults.current = schemaDefault;\n const initial = useRef(options.initialView);\n initial.current = options.initialView;\n const [state, setState] = useState({\n key,\n storage,\n history: [fallback],\n index: 0,\n loading: true,\n error: null as Error | null,\n saved: [] as SavedPropertyView[],\n defaultId: null as string | null,\n });\n const generation = useRef(0);\n const edits = useRef(0);\n const saveQueue = useRef(Promise.resolve());\n const current = state.key === key && state.storage === storage;\n const view = current ? state.history[state.index]! : fallback;\n\n useEffect(() => {\n const token = ++generation.current;\n const editToken = edits.current;\n setState({\n key,\n storage,\n history: [defaults.current],\n index: 0,\n loading: true,\n error: null,\n saved: [],\n defaultId: null,\n });\n void Promise.resolve()\n .then(() =>\n Promise.all([\n storage.loadLast(key),\n storage.listSaved(key),\n storage.loadDefaultSaved(key),\n ]),\n )\n .then(([last, saved, defaultView]) => {\n if (generation.current !== token) return;\n const restored = normalizePropertyView(\n initial.current ?? last ?? defaultView?.view ?? defaults.current,\n );\n const items = saved.map((item) => ({\n ...item,\n view: normalizePropertyView(item.view),\n }));\n setState((previous) => ({\n ...previous,\n ...(edits.current === editToken\n ? { history: [restored], index: 0 }\n : {}),\n saved: items,\n defaultId: defaultView?.id ?? null,\n loading: false,\n }));\n })\n .catch((error) => {\n if (generation.current === token)\n setState((previous) => ({\n ...previous,\n loading: false,\n error: asError(error),\n }));\n });\n return () => {\n generation.current++;\n };\n }, [key, storage]);\n\n useEffect(() => {\n if (!current || state.loading || state.error) return;\n const token = generation.current;\n const snapshot = normalizePropertyView(view);\n // Serial writes prevent a slower old save from replacing a newer view.\n saveQueue.current = saveQueue.current\n .then(() => storage.saveLast(key, snapshot))\n .catch((error) => {\n if (generation.current === token)\n setState((previous) => ({ ...previous, error: asError(error) }));\n });\n }, [view, current, state.loading, state.error, key, storage]);\n\n const setView = useCallback(\n (next: PropertyViewState) => {\n const normalized = normalizePropertyView(next);\n edits.current++;\n setState((previous) => {\n const history =\n previous.key === key && previous.storage === storage\n ? previous.history.slice(0, previous.index + 1)\n : [defaults.current];\n if (\n JSON.stringify(history[history.length - 1]) ===\n JSON.stringify(normalized)\n )\n return { ...previous, error: null };\n const nextHistory = [...history, normalized].slice(-50);\n return {\n ...previous,\n key,\n storage,\n history: nextHistory,\n index: nextHistory.length - 1,\n error: null,\n };\n });\n },\n [key, storage],\n );\n const refresh = useCallback(\n async (token: number) => {\n const [saved, defaultView] = await Promise.all([\n storage.listSaved(key),\n storage.loadDefaultSaved(key),\n ]);\n if (generation.current === token)\n setState((previous) => ({\n ...previous,\n saved: saved.map((item) => ({\n ...item,\n view: normalizePropertyView(item.view),\n })),\n defaultId: defaultView?.id ?? null,\n error: null,\n }));\n },\n [key, storage],\n );\n return {\n view,\n loading: !current || state.loading,\n error: current ? state.error : null,\n saved: current ? state.saved : [],\n defaultId: current ? state.defaultId : null,\n setView,\n reset: () => setView(defaults.current),\n canUndo: current && state.index > 0,\n canRedo: current && state.index < state.history.length - 1,\n undo() {\n edits.current++;\n setState((previous) => ({\n ...previous,\n index: Math.max(0, previous.index - 1),\n error: null,\n }));\n },\n redo() {\n edits.current++;\n setState((previous) => ({\n ...previous,\n index: Math.min(previous.history.length - 1, previous.index + 1),\n error: null,\n }));\n },\n load(id) {\n const found = state.saved.find((item) => item.id === id);\n if (found && current) setView(found.view);\n },\n async save(name) {\n const token = generation.current;\n const saved = await storage.saveNamed(key, name, view, Date.now());\n await refresh(token);\n return saved;\n },\n async remove(id) {\n const token = generation.current;\n await storage.deleteSaved(key, id);\n await refresh(token);\n },\n async setDefault(id) {\n const token = generation.current;\n await storage.setDefaultSaved(key, id);\n await refresh(token);\n },\n };\n}\n","import {\n isComputedField,\n readFieldValue,\n type ComputedExecution,\n type FetchRowsResultV2,\n type FieldSchema,\n type ServerQueryV2,\n} from \"@pythia-software/query-table-core\";\nexport function executionRevision(\n execution: ComputedExecution | undefined,\n id: string,\n): string | undefined {\n return (\n execution?.resolvedRevisions[id] ??\n execution?.resolvedRevisions[`@computed/${id}`]\n );\n}\n/** Reject mismatched sidecars before they can be attached to committed row identities. */\nexport function validateComputedResponse<Row>(\n request: ServerQueryV2,\n result: FetchRowsResultV2<Row>,\n schema: FieldSchema<Row>,\n): void {\n const execution = result.execution;\n if (\n result.version !== 2 ||\n !execution ||\n execution.profile !== request.profile ||\n (request.planToken && execution.planToken !== request.planToken) ||\n (request.snapshot !== undefined && execution.snapshot !== request.snapshot)\n )\n throw Error(\n \"Server computed execution identity changed. Refresh the handshake.\",\n );\n // The backend validates the full transitive envelope. Browser response checks\n // concern only fields actually executed for this row request; a catalogue can\n // also contain revisions for browser-only definitions.\n const executed = new Set([\n ...request.select.filter(isComputedField),\n ...request.orderBy.map((term) => term.field).filter(isComputedField),\n ]);\n for (const [name, revision] of Object.entries(request.expectedRevisions)) {\n const id = name.replace(/^@computed\\//, \"\");\n if (!executed.has(`@computed/${id}`)) continue;\n if (executionRevision(execution, id) !== revision)\n throw Error(\n \"Server computed definition revision changed. Refresh the handshake.\",\n );\n }\n const idField = schema.fields.find((f) => f.name === schema.idField);\n if (!idField)\n throw Error(\"Stable row identity is required for computed values.\");\n const ids = new Set(result.rows.map((row) => readFieldValue(idField, row)));\n if (ids.has(null) || ids.has(undefined) || ids.size !== result.rows.length)\n throw Error(\n \"Computed response contains missing or duplicate row identities.\",\n );\n const sidecars = new Map(\n result.computed.map((item) => [item.id, item.values]),\n );\n if (\n sidecars.size !== result.computed.length ||\n [...sidecars.keys()].some((id) => !ids.has(id))\n )\n throw Error(\"Computed sidecars do not match returned row identities.\");\n for (const field of request.select.filter(isComputedField)) {\n const id = field.slice(\"@computed/\".length);\n for (const rowId of ids) {\n const value = sidecars.get(rowId as string | number)?.[id];\n if (\n !value ||\n (value.value !== null &&\n ![\"string\", \"number\", \"boolean\"].includes(typeof value.value)) ||\n (typeof value.value === \"number\" && !Number.isFinite(value.value))\n )\n throw Error(`Missing or invalid server computed result: ${field}.`);\n }\n }\n}\n","import { executionRevision } from \"./computedExecution\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n applyQuery,\n compileFormula,\n computedFieldName,\n groupPreview,\n isComputedField,\n memoryComputedColumnStore,\n readFieldValue,\n toServerQuery,\n validateComputedColumn,\n isSelectable,\n hasRegex,\n type ColumnPreview,\n type ComputedColumn,\n type ComputedExecution,\n type RowComputedValues,\n type RowId,\n type ComputedColumnDraft,\n type ComputedColumnStore,\n type FieldDef,\n type FieldSchema,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface ComputedColumnsApi<Row> {\n definitions: ComputedColumn[];\n catalogue: FieldDef<Row>[];\n loading: boolean;\n error: string | null;\n reload: () => Promise<void>;\n save: (\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ) => Promise<ComputedColumn>;\n compile: (source: string, editingId?: string) => FormulaPlan;\n /** Sample the first N matching rows in current sort order, independent of table paging. */\n preview: (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs?: boolean,\n ) => Promise<ColumnPreview>;\n}\ninterface Options<Row> {\n schema: FieldSchema<Row>;\n query: QueryState;\n rows: Row[];\n store?: ComputedColumnStore;\n transport?: Transport<Row>;\n clientRows?: Row[];\n workerFactory?: FormulaWorkerFactory;\n execution?: ComputedExecution;\n serverComputed?: Map<RowId, RowComputedValues>;\n serverExecution?: ComputedExecution;\n}\nexport function useComputedColumns<Row>(options: Options<Row>): {\n api: ComputedColumnsApi<Row>;\n displaySchema: FieldSchema<Row>;\n} {\n const { schema, query, rows, transport, clientRows, workerFactory } = options;\n const store = useMemo(\n () => options.store ?? memoryComputedColumnStore(),\n [options.store],\n );\n const [catalogue, setCatalogue] = useState<{\n dataset: string;\n store: ComputedColumnStore;\n items: ComputedColumn[];\n } | null>(null);\n const definitions = useMemo(\n () =>\n catalogue?.dataset === schema.name && catalogue.store === store\n ? catalogue.items\n : [],\n [catalogue, schema.name, store],\n );\n const [loading, setLoading] = useState(false),\n [error, setError] = useState<string | null>(null);\n const catalogueRequest = useRef<AbortController | null>(null);\n const reload = useCallback(async () => {\n catalogueRequest.current?.abort();\n const ac = new AbortController();\n catalogueRequest.current = ac;\n setLoading(true);\n setError(null);\n try {\n const items = await store.list(schema.name, ac.signal);\n if (ac.signal.aborted) return;\n const valid = items\n .map(validateComputedColumn)\n .sort((a, b) => a.id.localeCompare(b.id));\n if (new Set(valid.map((c) => c.id)).size !== valid.length)\n throw new Error(\"Duplicate computed column IDs.\");\n setCatalogue((previous) =>\n previous?.dataset === schema.name &&\n previous.store === store &&\n JSON.stringify(previous.items) === JSON.stringify(valid)\n ? previous\n : { dataset: schema.name, store, items: valid },\n );\n } catch (e) {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!ac.signal.aborted) setLoading(false);\n }\n }, [store, schema.name]);\n useEffect(() => {\n void reload();\n return () => catalogueRequest.current?.abort();\n }, [reload]);\n useEffect(\n () =>\n store.subscribe?.(schema.name, () => {\n void reload();\n }),\n [store, schema.name, reload],\n );\n useEffect(() => {\n const focus = () => {\n void reload();\n };\n window.addEventListener(\"focus\", focus);\n return () => window.removeEventListener(\"focus\", focus);\n }, [reload]);\n const inputFields = useMemo(\n () =>\n schema.fields\n .filter(isSelectable)\n .filter(\n (f) =>\n f.source.kind === \"backend\" ||\n (f.source.accessor && f.source.dependencies),\n ),\n [schema],\n );\n const compile = useCallback(\n (source: string, editingId?: string): FormulaPlan => {\n const stack = new Set<string>(editingId ? [editingId] : []);\n let expanded = 0;\n const resolve = (name: string): FormulaPlan | undefined => {\n if (!isComputedField(name)) return undefined;\n const id = name.slice(\"@computed/\".length),\n def = definitions.find((d) => d.id === id);\n if (!def) throw new Error(`Computed column unavailable: ${id}`);\n if (stack.has(id))\n throw new Error(`Circular computed-column reference: ${def.label}`);\n if (stack.size >= 20 || ++expanded > 100)\n throw new Error(\"Computed dependency graph is too large.\");\n stack.add(id);\n try {\n return compileFormula(def.expression.source, inputFields, resolve);\n } finally {\n stack.delete(id);\n }\n };\n return compileFormula(source, inputFields, resolve);\n },\n [inputFields, definitions],\n );\n const plans = useMemo(\n () =>\n new Map<string, { plan?: FormulaPlan; error?: string }>(\n definitions.map((def) => {\n try {\n return [\n def.id,\n { plan: compile(def.expression.source, def.id) },\n ] as const;\n } catch (e) {\n return [\n def.id,\n { error: e instanceof Error ? e.message : String(e) },\n ] as const;\n }\n }),\n ),\n [definitions, compile],\n );\n const backendDependencies = useCallback(\n (plan: FormulaPlan) =>\n [\n ...new Set(\n plan.dependencies.flatMap((name) => {\n const f = inputFields.find((f) => f.name === name);\n return f?.source.kind === \"backend\"\n ? [name]\n : (f?.source.dependencies ?? []);\n }),\n ),\n ]\n .filter((name) =>\n schema.fields.some(\n (f) => f.name === name && f.source.kind === \"backend\",\n ),\n )\n .sort(),\n [schema, inputFields],\n );\n const inputsFor = useCallback(\n (plan: FormulaPlan, batch: Row[]) => {\n let size = 0;\n return batch.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = inputFields.find((f) => f.name === name)!;\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date ? raw.toISOString() : (raw as FormulaValue);\n }\n size += JSON.stringify(values).length;\n if (size > 16000000)\n throw new Error(\n \"Input sample exceeds 16 MB. Reduce the rows to process.\",\n );\n return values;\n });\n },\n [inputFields],\n );\n const activeSelect = query.select.length\n ? query.select\n : (schema.defaultSelect ?? []);\n const activeIds = activeSelect\n .filter((c) => isComputedField(c.field))\n .map((c) => c.field.slice(\"@computed/\".length))\n .sort()\n .join(\",\");\n const [evaluated, setEvaluated] = useState<{\n rows: Row[];\n plans: typeof plans;\n values: Map<string, FormulaResult[]>;\n } | null>(null);\n useEffect(() => {\n const ac = new AbortController();\n const values = new Map<string, FormulaResult[]>();\n void (async () => {\n for (const id of activeIds.split(\",\").filter(Boolean)) {\n if (\n options.execution?.fields[computedFieldName(id)]?.select &&\n (transport?.fetchRowsV2 || transport?.fetchQueryV3)\n )\n continue;\n const entry = plans.get(id);\n if (!entry?.plan) continue;\n try {\n values.set(\n id,\n await evaluateFormulaRows(\n entry.plan.ast,\n inputsFor(entry.plan, rows),\n ac.signal,\n workerFactory,\n ),\n );\n } catch (e) {\n if (ac.signal.aborted) return;\n values.set(\n id,\n rows.map(() => ({\n value: null,\n error: e instanceof Error ? e.message : String(e),\n })),\n );\n }\n }\n if (!ac.signal.aborted) setEvaluated({ rows, plans, values });\n })();\n return () => ac.abort();\n }, [\n activeIds,\n rows,\n plans,\n inputsFor,\n workerFactory,\n options.execution,\n transport,\n ]);\n const displaySchema = useMemo<FieldSchema<Row>>(() => {\n const indices = new Map(rows.map((row, i) => [row, i]));\n const fields: FieldDef<Row>[] = definitions.map((def) => {\n const entry = plans.get(def.id);\n return {\n name: computedFieldName(def.id),\n label: def.label,\n type:\n entry?.plan?.type === \"null\" ? \"text\" : (entry?.plan?.type ?? \"text\"),\n group: \"Computed columns\",\n source: {\n kind: \"derived\",\n computedId: def.id,\n dependencies: entry?.plan ? backendDependencies(entry.plan) : [],\n accessor: (row: Row) => {\n if (entry?.error) return { computedError: entry.error };\n if (\n options.execution?.fields[computedFieldName(def.id)]?.select &&\n (transport?.fetchRowsV2 || transport?.fetchQueryV3)\n ) {\n if (\n options.serverExecution?.profile !==\n options.execution.profile ||\n options.serverExecution?.planToken !==\n options.execution.planToken ||\n options.serverExecution?.snapshot !==\n options.execution.snapshot ||\n executionRevision(options.execution, def.id) !== def.revision ||\n executionRevision(options.serverExecution, def.id) !==\n def.revision\n )\n return {\n computedError:\n \"Definition changed or values are pending. Refresh the server handshake.\",\n };\n const idField = schema.fields.find(\n (f) => f.name === schema.idField,\n );\n const id = idField\n ? (readFieldValue(idField, row) as RowId)\n : null;\n const server =\n id === null\n ? undefined\n : options.serverComputed?.get(id)?.[def.id];\n return server\n ? server.error\n ? { computedError: server.error.code }\n : server.value\n : { computedError: \"Server computed result unavailable.\" };\n }\n const result =\n evaluated?.rows === rows && evaluated.plans === plans\n ? evaluated.values.get(def.id)?.[indices.get(row) ?? -1]\n : undefined;\n return result?.error\n ? { computedError: result.error }\n : result\n ? result.value\n : { computedError: \"Calculating…\" };\n },\n },\n filter: { enabled: options.execution?.fields[computedFieldName(def.id)]?.filter === true &&\n executionRevision(options.execution, def.id) === def.revision && !!entry?.plan && !hasRegex(entry.plan) },\n sort: {\n enabled:\n !!(transport?.fetchRowsV2 || transport?.fetchQueryV3) &&\n !!options.execution?.fields[computedFieldName(def.id)]?.sort &&\n executionRevision(options.execution, def.id) === def.revision &&\n !!entry?.plan &&\n !hasRegex(entry.plan),\n },\n aggregate: {\n measure: !!entry?.plan,\n groupable:\n (!!transport?.fetchMetrics && transport.metricCapabilities?.version === 2 || !!transport?.fetchQueryV3) &&\n !!options.execution?.fields[computedFieldName(def.id)]?.group &&\n executionRevision(options.execution, def.id) === def.revision &&\n !!entry?.plan &&\n !hasRegex(entry.plan),\n },\n };\n });\n for (const col of activeSelect)\n if (\n isComputedField(col.field) &&\n !fields.some((f) => f.name === col.field)\n )\n fields.push({\n name: col.field,\n label: col.field.slice(10),\n type: \"text\",\n source: {\n kind: \"derived\",\n computedId: col.field.slice(10),\n accessor: () => ({\n computedError: loading\n ? \"Loading definition…\"\n : \"Definition unavailable. Reload the catalogue or contact its owner.\",\n }),\n },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n });\n return { ...schema, fields: [...schema.fields, ...fields] };\n }, [\n schema,\n definitions,\n plans,\n backendDependencies,\n evaluated,\n rows,\n query.select,\n schema.defaultSelect,\n loading,\n transport,\n options.execution,\n options.serverComputed,\n options.serverExecution,\n ]);\n const save = useCallback(\n async (column: ComputedColumnDraft, expectedRevision: string | null) => {\n compile(column.expression.source, column.id);\n const saved = validateComputedColumn(\n await store.save(schema.name, column, expectedRevision),\n );\n setCatalogue((prev) => ({\n dataset: schema.name,\n store,\n items: [\n ...(prev?.dataset === schema.name && prev.store === store\n ? prev.items.filter((d) => d.id !== saved.id)\n : []),\n saved,\n ],\n }));\n return saved;\n },\n [compile, store, schema.name],\n );\n const preview = useCallback(\n async (\n source: string,\n count: number,\n signal?: AbortSignal,\n editingId?: string,\n includeInputs = true,\n ): Promise<ColumnPreview> => {\n if (!Number.isInteger(count) || count < 1 || count > 10000)\n throw new Error(\"Choose between 1 and 10,000 rows.\");\n const plan = compile(source, editingId);\n let batch: Row[] = [],\n total = 0;\n if (transport) {\n const request = toServerQuery(\n {\n ...query,\n select: [\n ...new Set([schema.idField, ...backendDependencies(plan)]),\n ].map((field) => ({ field })),\n limit: Math.min(count, 500),\n offset: 0,\n },\n schema,\n );\n while (batch.length < count) {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n const res = await transport.fetchRows(\n {\n ...request,\n offset: batch.length,\n limit: Math.min(500, count - batch.length),\n },\n signal,\n );\n total = res.total;\n batch.push(...res.rows.slice(0, count - batch.length));\n if (!res.rows.length || batch.length >= total) break;\n }\n } else {\n const result = applyQuery(\n clientRows ?? [],\n { ...query, limit: count, offset: 0 },\n schema,\n );\n batch = result.rows;\n total = result.total;\n }\n const inputs = inputsFor(plan, batch),\n results = await evaluateFormulaRows(\n plan.ast,\n inputs,\n signal,\n workerFactory,\n );\n return groupPreview(\n includeInputs ? plan.dependencies : [],\n inputs,\n results,\n total,\n );\n },\n [\n compile,\n transport,\n query,\n schema,\n backendDependencies,\n clientRows,\n inputsFor,\n workerFactory,\n ],\n );\n return {\n displaySchema,\n api: {\n definitions,\n catalogue: displaySchema.fields,\n loading,\n error,\n reload,\n save,\n compile,\n preview,\n },\n };\n}\n","import {\n formulaRuntime,\n type FormulaNode,\n type FormulaResult,\n type FormulaValue,\n} from \"@pythia-software/query-table-core\";\n\nexport type FormulaWorkerFactory = () => Worker;\n/** Host applications with a restrictive CSP can supply their own worker factory. */\nexport const createFormulaWorker: FormulaWorkerFactory = () => {\n const code = `const evaluate = ${formulaRuntime.toString()}; self.onmessage = e => { const { ast, inputs } = e.data; self.postMessage(inputs.map(row => evaluate(ast, row))); };`;\n const url = URL.createObjectURL(\n new Blob([code], { type: \"text/javascript\" }),\n );\n try {\n return new Worker(url);\n } finally {\n URL.revokeObjectURL(url);\n }\n};\nexport function evaluateFormulaRows(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>[],\n signal?: AbortSignal,\n factory: FormulaWorkerFactory = createFormulaWorker,\n): Promise<FormulaResult[]> {\n if (signal?.aborted)\n return Promise.reject(new DOMException(\"Aborted\", \"AbortError\"));\n if (!inputs.length) return Promise.resolve([]);\n return new Promise((resolve, reject) => {\n let worker: Worker;\n try {\n worker = factory();\n } catch (e) {\n reject(\n new Error(\n `Formula worker unavailable: ${e instanceof Error ? e.message : String(e)}`,\n ),\n );\n return;\n }\n let timer: ReturnType<typeof setTimeout>;\n const started = Date.now();\n let offset = 0;\n const results: FormulaResult[] = [];\n const cleanup = () => {\n clearTimeout(timer);\n worker.terminate();\n signal?.removeEventListener(\"abort\", abort);\n };\n const abort = () => {\n cleanup();\n reject(new DOMException(\"Aborted\", \"AbortError\"));\n };\n const send = () => {\n if (Date.now() - started > 30000) {\n cleanup();\n reject(\n new Error(\n \"Formula exceeded the 30-second processing budget. Reduce the row count or simplify the formula.\",\n ),\n );\n return;\n }\n timer = setTimeout(() => {\n cleanup();\n reject(\n new Error(\n \"Formula timed out. Check the regex or reduce the row count.\",\n ),\n );\n }, 2000);\n try {\n worker.postMessage({ ast, inputs: inputs.slice(offset, offset + 200) });\n } catch (e) {\n cleanup();\n reject(e);\n }\n };\n signal?.addEventListener(\"abort\", abort, { once: true });\n worker.onerror = () => {\n cleanup();\n reject(new Error(\"Formula worker failed.\"));\n };\n worker.onmessage = (event: MessageEvent<FormulaResult[]>) => {\n clearTimeout(timer);\n results.push(...event.data);\n offset += event.data.length;\n if (offset >= inputs.length) {\n cleanup();\n resolve(results);\n } else send();\n };\n send();\n });\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type { Transport } from \"@pythia-software/query-table-core\";\n\nexport interface RequestActivityEntry {\n id: number;\n kind: string;\n startedAt: number;\n status: \"pending\" | \"success\" | \"error\" | \"aborted\";\n durationMs?: number;\n error?: string;\n}\nexport interface RequestActivityApi {\n /** Newest first; bounded to the latest 100 calls. Query values and results are never retained. */\n entries: readonly RequestActivityEntry[];\n clear: () => void;\n}\nconst methods = new Set([\n \"fetchRows\",\n \"fetchRowsV2\",\n \"fetchQueryV3\",\n \"fetchMetrics\",\n \"fetchAggregations\",\n \"fetchRow\",\n \"fetchDistinctValues\",\n \"fetchFieldStats\",\n]);\n\n/** Observe the transport boundary without changing receiver, arguments or errors. */\nexport function observeTransport<Row>(\n transport: Transport<Row>,\n publish: (entry: RequestActivityEntry) => void,\n nextId: () => number,\n): Transport<Row> {\n const wrappers = new Map<PropertyKey, unknown>();\n return new Proxy(Object.create(transport) as Transport<Row>, {\n get(_target, key) {\n const method = Reflect.get(transport, key, transport);\n if (!methods.has(String(key)) || typeof method !== \"function\")\n return method;\n if (!wrappers.has(key))\n wrappers.set(key, async (...args: unknown[]) => {\n const signal = args[1] as AbortSignal | undefined;\n const start = performance.now();\n const entry: RequestActivityEntry = {\n id: nextId(),\n kind: String(key).replace(/^fetch/, \"\"),\n startedAt: Date.now(),\n status: \"pending\",\n };\n publish(entry);\n let done = false;\n const finish = (\n status: RequestActivityEntry[\"status\"],\n error?: unknown,\n ) => {\n if (done) return;\n done = true;\n publish({\n ...entry,\n status,\n durationMs: Math.max(0, performance.now() - start),\n ...(error !== undefined\n ? {\n error:\n error instanceof Error ? error.message : String(error),\n }\n : {}),\n });\n };\n const abort = () => finish(\"aborted\");\n signal?.addEventListener(\"abort\", abort, { once: true });\n if (signal?.aborted) abort();\n try {\n const result = await method.apply(transport, args);\n finish(signal?.aborted ? \"aborted\" : \"success\");\n return result;\n } catch (error) {\n finish(\n signal?.aborted ||\n (error instanceof Error && error.name === \"AbortError\")\n ? \"aborted\"\n : \"error\",\n error,\n );\n throw error;\n } finally {\n signal?.removeEventListener(\"abort\", abort);\n }\n });\n return wrappers.get(key);\n },\n });\n}\n\nexport function useRequestActivity<Row>(source: Transport<Row> | undefined) {\n const [entries, setEntries] = useState<RequestActivityEntry[]>([]);\n const sequence = useRef(0),\n mounted = useRef(true);\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n };\n }, []);\n const publish = useCallback((entry: RequestActivityEntry) => {\n if (mounted.current)\n setEntries((previous) =>\n [entry, ...previous.filter((e) => e.id !== entry.id)]\n .sort((a, b) => b.id - a.id)\n .slice(0, 100),\n );\n }, []);\n const transport = useMemo(\n () =>\n source\n ? observeTransport(source, publish, () => ++sequence.current)\n : undefined,\n [source, publish],\n );\n const clear = useCallback(\n () =>\n setEntries((previous) => previous.filter((e) => e.status === \"pending\")),\n [],\n );\n const activity: RequestActivityApi = useMemo(\n () => ({ entries, clear }),\n [entries, clear],\n );\n return { transport, activity };\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n metricComputationKey,\n metricPlans,\n hasRegex,\n type AggregationClause,\n type AggregationResult,\n type FieldSchema,\n type QueryState,\n type Transport,\n} from \"@pythia-software/query-table-core\";\nimport { executeMetrics, type MetricExecutionContext } from \"./metricExecution\";\n\nexport interface AggregationsApiState {\n results: AggregationResult | null;\n loading: boolean;\n error: Error | null;\n preview: (\n clauses: AggregationClause[],\n signal?: AbortSignal,\n ) => Promise<AggregationResult>;\n}\n/** Fetch state is keyed by computation and scope, never card presentation. */\nexport function useAggregations<Row>(\n query: QueryState,\n schema: FieldSchema<Row>,\n transport: Transport<Row> | undefined,\n clientRows: Row[] | undefined,\n debounceMs: number,\n nonce: number,\n validateQuery?: (q: QueryState) => void,\n options: Omit<\n MetricExecutionContext<Row>,\n \"schema\" | \"transport\" | \"clientRows\"\n > = {},\n enabled = true,\n): AggregationsApiState {\n const [results, setResults] = useState<AggregationResult | null>(null);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const latest = useRef({\n query,\n schema,\n transport,\n clientRows,\n options,\n validateQuery,\n enabled,\n });\n latest.current = {\n query,\n schema,\n transport,\n clientRows,\n options,\n validateQuery,\n enabled,\n };\n const preview = useCallback(\n async (clauses: AggregationClause[], signal?: AbortSignal) => {\n const current = latest.current;\n if (!current.enabled) throw Error(\"Resolve the query link before previewing metrics.\");\n const draft = { ...current.query, aggregations: clauses };\n current.validateQuery?.(draft);\n return executeMetrics(\n draft,\n {\n schema: current.schema,\n transport: current.transport,\n clientRows: current.clientRows,\n ...current.options,\n },\n signal,\n );\n },\n [],\n );\n const shown = (query.aggregations ?? []).some((c) => c.scope === \"shownRows\");\n // A v2 server scopes shownRows from the query window and snapshot itself.\n // Only client/legacy/regex evaluation depends on the downloaded row page.\n const localPage =\n !options.executeV3 && shown &&\n (!transport?.fetchMetrics ||\n transport.metricCapabilities?.version !== 2 ||\n (query.aggregations ?? []).some((clause) => {\n if (clause.scope !== \"shownRows\") return false;\n try {\n return metricPlans(clause, schema, options.resolveComputed).some(\n hasRegex,\n );\n } catch {\n return true;\n } // Validation reports invalid inputs through fetch state.\n }));\n const key = useMemo(\n () =>\n JSON.stringify([\n query.where,\n metricComputationKey(query.aggregations ?? []),\n shown ? [query.orderBy, query.limit, query.offset] : null,\n ]),\n [\n query.where,\n query.aggregations,\n query.orderBy,\n query.limit,\n query.offset,\n shown,\n ],\n );\n const dependencyKey = JSON.stringify([\n options.revisions ?? {},\n options.execution ?? null,\n options.now,\n options.strictLocalMetrics,\n options.queryContextKey,\n ]);\n useEffect(() => {\n if (!enabled || !latest.current.query.aggregations?.length) {\n setResults(null);\n setLoading(false);\n setError(null);\n return;\n }\n const ac = new AbortController();\n setLoading(true);\n setResults(null);\n // Automatic shown-page evaluation waits for the committed page. Explicit\n // previews still report missing inputs rather than using stale rows.\n if (localPage && transport && !options.rowsReady) {\n try {\n latest.current.validateQuery?.(latest.current.query);\n setError(options.rowsError ?? null);\n if (options.rowsError) setLoading(false);\n } catch (e) {\n setError(e instanceof Error ? e : Error(String(e)));\n setLoading(false);\n }\n return;\n }\n const timer = setTimeout(() => {\n setError(null);\n try {\n latest.current.validateQuery?.(latest.current.query);\n } catch (e) {\n setError(e instanceof Error ? e : Error(String(e)));\n setLoading(false);\n return;\n }\n void preview(latest.current.query.aggregations ?? [], ac.signal)\n .then((result) => {\n if (!ac.signal.aborted) setResults(result);\n })\n .catch((e) => {\n if (!ac.signal.aborted)\n setError(e instanceof Error ? e : Error(String(e)));\n })\n .finally(() => {\n if (!ac.signal.aborted) setLoading(false);\n });\n }, debounceMs);\n return () => {\n ac.abort();\n clearTimeout(timer);\n };\n }, [\n key,\n schema,\n transport,\n clientRows,\n debounceMs,\n nonce,\n validateQuery,\n enabled,\n dependencyKey,\n localPage,\n localPage ? options.shownRows : undefined,\n localPage ? options.rowsReady : undefined,\n localPage ? options.rowsError : undefined,\n preview,\n ]);\n return { results, loading, error, preview };\n}\n","import {\n applyAggregations,\n normalizeQueryState,\n evaluateMetrics,\n metricPlans,\n hasRegex,\n toAggregationQuery,\n toMetricQuery,\n validateMetric,\n selectMetricShownRows,\n readFieldValue,\n resolveFieldName,\n isComputedField,\n type AggregationClause,\n type AggregationResult,\n type FieldSchema,\n type FormulaNode,\n type FormulaPlan,\n type FormulaResult,\n type FormulaValue,\n type QueryState,\n type Transport,\n type ComputedExecution,\n} from \"@pythia-software/query-table-core\";\nimport {\n evaluateFormulaRows,\n type FormulaWorkerFactory,\n} from \"./formulaWorker\";\n\nexport interface MetricExecutionContext<Row> {\n executeV3?: (query: QueryState, signal?: AbortSignal) => Promise<AggregationResult>;\n queryContextKey?: string;\n schema: FieldSchema<Row>;\n /** One clock shared by source grouping, HAVING, rows and local metrics. */\n now?: number;\n /** Group projections use typed semantics even for shorthand metric clauses. */\n strictLocalMetrics?: boolean;\n transport?: Transport<Row> | undefined;\n clientRows?: Row[] | undefined;\n shownRows?: Row[] | undefined;\n rowsReady?: boolean | undefined;\n rowsError?: Error | null | undefined;\n shownFields?: readonly string[] | undefined;\n resolveComputed?: ((name: string) => FormulaPlan | undefined) | undefined;\n workerFactory?: FormulaWorkerFactory | undefined;\n revisions?: Record<string, string> | undefined;\n execution?: ComputedExecution;\n}\nconst abort = (signal?: AbortSignal) => {\n if (signal?.aborted) throw new DOMException(\"Aborted\", \"AbortError\");\n};\n\n/** Local regex inputs run in terminable workers; reduction uses only cached values. */\nasync function localMetrics<Row>(\n rows: Row[],\n query: QueryState,\n context: MetricExecutionContext<Row>,\n signal?: AbortSignal,\n): Promise<AggregationResult> {\n // Keep legacy aggregates on their permissive compatibility path. Advanced\n // metrics still use the typed formula engine and isolated regex workers.\n const originalClauses = query.aggregations ?? [];\n const advanced = (query.aggregations ?? []).filter(\n (c) =>\n context.strictLocalMetrics ||\n c.dateGrouping ||\n isComputedField(c.field ?? \"\") ||\n c.groupBy.some(isComputedField) ||\n c.diagnostics?.length ||\n c.expression !== undefined ||\n c.expressionY !== undefined ||\n c.scope !== undefined ||\n c.distribution ||\n c.sort ||\n c.groupLimit !== undefined,\n );\n if (\n advanced.length &&\n (originalClauses.length > 20 ||\n normalizeQueryState(query).aggregations?.length !==\n originalClauses.length)\n )\n return evaluateMetrics(rows, query, context.schema, {\n ...(context.now !== undefined ? { now: context.now } : {}),\n ...(signal ? { signal } : {}),\n ...(context.resolveComputed\n ? { resolveComputed: context.resolveComputed }\n : {}),\n });\n const legacy = (query.aggregations ?? []).filter(\n (c) => !advanced.includes(c),\n );\n const compatible = applyAggregations(\n rows,\n { ...query, aggregations: legacy },\n context.schema,\n {\n ...(context.now !== undefined ? { now: context.now } : {}),\n ...(signal ? { signal } : {}),\n },\n );\n if (!advanced.length) return compatible;\n query = { ...query, aggregations: advanced };\n const options = {\n ...(context.now !== undefined ? { now: context.now } : {}),\n ...(context.resolveComputed\n ? { resolveComputed: context.resolveComputed }\n : {}),\n ...(signal ? { signal } : {}),\n };\n for (const clause of query.aggregations ?? []) {\n const diagnostics = validateMetric(\n clause,\n context.schema,\n context.resolveComputed,\n );\n if (diagnostics.length)\n throw Error(diagnostics.map((d) => d.message).join(\" \"));\n }\n const requiresPage = (query.aggregations ?? []).some(\n (clause) => clause.scope === \"shownRows\",\n );\n const page = requiresPage\n ? selectMetricShownRows(rows, query, context.schema, {\n ...options,\n ...(context.rowsReady && context.shownRows\n ? { shownRows: context.shownRows }\n : {}),\n })\n : [];\n const caches = new Map<string, Map<Row, FormulaResult>>();\n for (const clause of query.aggregations ?? []) {\n for (const plan of metricPlans(\n clause,\n context.schema,\n context.resolveComputed,\n )) {\n if (!hasRegex(plan)) continue;\n const nodes =\n \"aggregates\" in plan\n ? (\n plan as FormulaPlan & {\n aggregates: Array<{ args: FormulaNode[] }>;\n }\n ).aggregates.flatMap((a) => a.args)\n : [plan.ast];\n for (const node of nodes) {\n if (!hasRegex({ ...plan, ast: node })) continue;\n const key = JSON.stringify(node);\n if (caches.has(key)) continue;\n let bytes = 0;\n const inputs = page.map((row) => {\n const values: Record<string, FormulaValue> = Object.create(null);\n for (const name of plan.dependencies) {\n const field = context.schema.fields.find((f) => f.name === name);\n if (!field) throw Error(`Unavailable metric input: ${name}`);\n const raw = readFieldValue(field, row);\n values[name] =\n raw instanceof Date\n ? raw.toISOString()\n : ((raw ?? null) as FormulaValue);\n }\n bytes += JSON.stringify(values).length;\n if (bytes > 16000000)\n throw Error(\n \"Metric worker input exceeds 16 MB. Reduce the shown rows.\",\n );\n return values;\n });\n const values = await evaluateFormulaRows(\n node,\n inputs,\n signal,\n context.workerFactory,\n );\n caches.set(\n key,\n new Map(page.map((row, i) => [row, values[i]!] as const)),\n );\n }\n }\n }\n abort(signal);\n const typed = evaluateMetrics(rows, query, context.schema, {\n ...options,\n shownRows: page,\n ...(caches.size\n ? {\n evaluateInput: (node: FormulaNode, row: Row, plan: FormulaPlan) => {\n const cached = caches.get(JSON.stringify(node));\n if (cached)\n return (\n cached.get(row) ?? {\n value: null,\n error: \"Metric worker result missing.\",\n }\n );\n // Core calls the override only for regex inputs.\n throw Error(\"Metric regex input was not evaluated in a worker.\");\n },\n }\n : {}),\n });\n const byId = new Map(\n [...compatible.metrics, ...typed.metrics].map((m) => [m.id, m]),\n );\n return { metrics: originalClauses.flatMap((c) => byId.get(c.id) ?? []) };\n}\n\nexport async function executeMetrics<Row>(\n query: QueryState,\n context: MetricExecutionContext<Row>,\n signal?: AbortSignal,\n): Promise<AggregationResult> {\n abort(signal);\n const clauses = query.aggregations ?? [];\n if (!clauses.length) return { metrics: [] };\n if (context.executeV3) return context.executeV3(query, signal);\n const supportsV2 =\n !!context.transport?.fetchMetrics &&\n context.transport.metricCapabilities?.version === 2;\n if (\n context.clientRows &&\n !supportsV2 &&\n !context.transport?.fetchAggregations\n )\n return localMetrics(context.clientRows, query, context, signal);\n const needsWorker = (c: AggregationClause) =>\n metricPlans(c, context.schema, context.resolveComputed).some(hasRegex);\n const shown = clauses.filter(\n (c) =>\n c.scope === \"shownRows\" &&\n (!supportsV2 || needsWorker(c) || !!c.dateGrouping),\n );\n const matching = clauses.filter(\n (c) =>\n c.scope !== \"shownRows\" ||\n (supportsV2 && !needsWorker(c) && !c.dateGrouping),\n );\n const results: AggregationResult[\"metrics\"] = [];\n if (shown.length) {\n if (!context.rowsReady || !context.shownRows)\n throw Error(\n \"Wait for the current table page before previewing shown-row metrics.\",\n );\n // Only committed inputs can claim \"shown rows\". Never hydrate them from a\n // newer response with the same IDs; that would mix data snapshots.\n const names = new Set(\n shown.flatMap((clause) => [\n ...clause.groupBy,\n ...metricPlans(clause, context.schema, context.resolveComputed).flatMap(\n (p) => p.dependencies,\n ),\n ]),\n );\n for (const name of names) {\n const canonical = resolveFieldName(context.schema, name) ?? name;\n const field = context.schema.fields.find((f) => f.name === canonical);\n const dependencies =\n field?.source.kind === \"derived\"\n ? (field.source.dependencies ?? [])\n : [canonical];\n const loaded = context.shownFields\n ? dependencies.every((dep) => context.shownFields!.includes(dep))\n : field &&\n context.shownRows.every(\n (row) =>\n field.source.kind === \"derived\" ||\n loadedPath(\n row,\n field.source.kind === \"backend\"\n ? (field.source.path ?? field.name)\n : field.name,\n ),\n );\n if (!field || !loaded)\n throw Error(\n `Shown-page input ${name} is not loaded. Add it to the selected columns and refresh, or use a snapshot-capable metric transport.`,\n );\n }\n // Committed shown rows supply the population; original filters still define\n // the calendar domain for completing empty dates.\n const pageQuery = {\n ...query,\n orderBy: [],\n limit: Math.max(1, context.shownRows.length),\n offset: 0,\n aggregations: shown,\n };\n results.push(\n ...(await localMetrics(context.shownRows, pageQuery, context, signal))\n .metrics,\n );\n }\n if (matching.length) {\n if (matching.some((c) => c.dateGrouping))\n throw Error(\n \"This server does not support calendar grouping. Enable the v3 query executor.\",\n );\n const transport = context.transport;\n const scoped = { ...query, aggregations: matching };\n if (\n transport?.fetchMetrics &&\n transport.metricCapabilities?.version === 2\n ) {\n const request = toMetricQuery(scoped, context.schema, context.execution);\n if (request.diagnostics.length)\n throw Error(request.diagnostics.map((d) => d.message).join(\" \"));\n if (\n matching.some((c) => c.scope === \"shownRows\") &&\n !transport.metricCapabilities.shownRows\n )\n throw Error(\"This server does not support shown-row metrics.\");\n if (\n request.profile &&\n transport.metricCapabilities.profile &&\n request.profile !== transport.metricCapabilities.profile\n )\n throw Error(\n \"Metric transport and computed execution profiles do not match. Refresh the handshake.\",\n );\n const remoteFields = new Map(\n context.schema.fields.map((field) => [field.name, field]),\n );\n for (const [name, capability] of Object.entries(\n context.execution?.fields ?? {},\n ))\n if (isComputedField(name))\n remoteFields.set(name, {\n name,\n label: name,\n type: capability.type,\n source: { kind: \"backend\" },\n });\n const remoteSchema = {\n ...context.schema,\n fields: [...remoteFields.values()],\n };\n if (\n matching.some((clause) =>\n [\n ...clause.groupBy,\n ...metricPlans(clause, remoteSchema).flatMap(\n (plan) => plan.dependencies,\n ),\n ].some(isComputedField),\n ) &&\n !transport.metricCapabilities.computedFields\n )\n throw Error(\"This metric server does not support computed fields.\");\n if (\n request.metrics.some(\n (c) =>\n !c.distribution &&\n (c.expression !== undefined || c.expressionY !== undefined),\n ) &&\n !transport.metricCapabilities.expressions\n )\n throw Error(\n \"This server does not support composed metric expressions.\",\n );\n if (\n matching.some(\n (c) =>\n c.distribution &&\n (!c.display || [\"box\", \"histogram\"].includes(c.display.kind)),\n ) &&\n !transport.metricCapabilities.distributions\n )\n throw Error(\"This server does not support distributions.\");\n results.push(...(await transport.fetchMetrics(request, signal)).metrics);\n } else if (transport?.fetchAggregations) {\n const request = toAggregationQuery(scoped, context.schema);\n if (request.diagnostics?.length)\n throw Error(request.diagnostics.map((d) => d.message).join(\" \"));\n results.push(\n ...(await transport.fetchAggregations(request, signal)).metrics,\n );\n } else\n throw Error(\n \"Remote all-matching metrics require a metric-capable server transport.\",\n );\n }\n abort(signal);\n const byId = new Map(results.map((r) => [r.id, r]));\n return {\n metrics: clauses.map(\n (c) =>\n byId.get(c.id) ?? {\n id: c.id,\n buckets: [],\n error: \"Server omitted this metric.\",\n },\n ),\n };\n}\n\nfunction loadedPath(row: unknown, path: string): boolean {\n if (!row || typeof row !== \"object\") return false;\n if (path in row) return true;\n let value: unknown = row;\n for (const part of path.split(\".\")) {\n if (value === null) return true;\n if (!value || typeof value !== \"object\" || !(part in value)) return false;\n value = (value as Record<string, unknown>)[part];\n }\n return true;\n}\n","// useSelection — row selection for paged and re-sortable datasets.\n//\n// - Editable Shift-click ranges with a fixed row-ID anchor and a snapshot of\n// the selection before the range, so earlier selections survive resizing.\n// - Display-order changes commit the selection and reset the active range.\n// - Indeterminate header checkbox + select-all-on-page.\n\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport type { RowId } from \"@pythia-software/query-table-core\";\n\nexport interface SelectionApi {\n selected: Set<RowId>;\n isSelected: (id: RowId) => boolean;\n /** Toggle one row and start an editable range. With `shiftKey`, resize that\n * range in the current page's order, checking or unchecking according to the\n * anchor's toggle. `additive` + Shift adds a span to the current selection.\n * Missing anchors or changed display order fall back to a plain toggle. */\n toggle: (id: RowId, shiftKey?: boolean, additive?: boolean) => void;\n /** Select / clear every row currently on the page. */\n setPage: (ids: RowId[], selected: boolean) => void;\n /** Atomically replace the complete selection with arbitrary stable row ids. */\n replace: (ids: Iterable<RowId>) => void;\n /** Atomically retain only selected ids that are also present in `ids`. */\n retain: (ids: Iterable<RowId>) => void;\n /** Header checkbox tri-state for the current page. */\n pageState: (pageIds: RowId[]) => \"none\" | \"some\" | \"all\";\n clear: () => void;\n count: number;\n}\n\ninterface SelectionRange {\n anchor: RowId;\n baseline: Set<RowId>;\n selecting: boolean;\n displayedIds: RowId[];\n}\n\ninterface SelectionState {\n selected: Set<RowId>;\n range: SelectionRange | null;\n}\n\nfunction sameOrder(left: RowId[], right: RowId[]): boolean {\n return left.length === right.length && left.every((id, index) => id === right[index]);\n}\n\n/** `displayedIds` is the page's id list in display order; the hook uses it to\n * resolve shift-ranges and header tri-state against what the user sees. */\nexport function useSelection(displayedIds: RowId[]): SelectionApi {\n const [{ selected }, setState] = useState<SelectionState>(() => ({\n selected: new Set(),\n range: null,\n }));\n\n useEffect(() => {\n setState((prev) => prev.range && !sameOrder(prev.range.displayedIds, displayedIds)\n ? { selected: prev.selected, range: null }\n : prev);\n }, [displayedIds]);\n\n const toggle = useCallback(\n (id: RowId, shiftKey = false, additive = false) => {\n setState((prev) => {\n const range = prev.range;\n if (shiftKey && range && sameOrder(range.displayedIds, displayedIds)) {\n const i = displayedIds.indexOf(range.anchor);\n const j = displayedIds.indexOf(id);\n if (i !== -1 && j !== -1) {\n const [lo, hi] = i <= j ? [i, j] : [j, i];\n // Additive gestures commit the current range before adding another\n // span. Ordinary Shift gestures always rebuild from its baseline.\n const activeRange = additive\n ? { ...range, baseline: prev.selected, selecting: true }\n : range;\n const next = new Set(activeRange.baseline);\n for (const rowId of displayedIds.slice(lo, hi + 1)) {\n if (activeRange.selecting) next.add(rowId);\n else next.delete(rowId);\n }\n return { selected: next, range: activeRange };\n }\n }\n const next = new Set(prev.selected);\n const selecting = !next.has(id);\n if (selecting) next.add(id);\n else next.delete(id);\n return {\n selected: next,\n range: { anchor: id, baseline: prev.selected, selecting, displayedIds: [...displayedIds] },\n };\n });\n },\n [displayedIds],\n );\n\n const setPage = useCallback((ids: RowId[], select: boolean) => {\n setState((prev) => {\n const next = new Set(prev.selected);\n for (const id of ids) {\n if (select) next.add(id);\n else next.delete(id);\n }\n return { selected: next, range: null };\n });\n }, []);\n\n const replace = useCallback((ids: Iterable<RowId>) => {\n const next = new Set(ids);\n setState({ selected: next, range: null });\n }, []);\n\n const retain = useCallback((ids: Iterable<RowId>) => {\n const allowed = new Set(ids);\n setState((prev) => {\n const next = new Set<RowId>();\n for (const id of prev.selected) if (allowed.has(id)) next.add(id);\n return { selected: next, range: null };\n });\n }, []);\n\n const pageState = useCallback(\n (pageIds: RowId[]): \"none\" | \"some\" | \"all\" => {\n if (pageIds.length === 0) return \"none\";\n let n = 0;\n for (const id of pageIds) if (selected.has(id)) n++;\n return n === 0 ? \"none\" : n === pageIds.length ? \"all\" : \"some\";\n },\n [selected],\n );\n\n const clear = useCallback(() => {\n setState({ selected: new Set(), range: null });\n }, []);\n\n return useMemo<SelectionApi>(\n () => ({\n selected,\n isSelected: (id) => selected.has(id),\n toggle,\n setPage,\n replace,\n retain,\n pageState,\n clear,\n count: selected.size,\n }),\n [selected, toggle, setPage, replace, retain, pageState, clear],\n );\n}\n","// useSelect — the SELECT list: visible columns, their order, and their widths,\n// all persisted INTO the query (decision #5, so one URL renders identically\n// anywhere). This API mutates QueryState.select; it holds no state of its own.\n// Width changes should be debounced by the caller before they hit the query to\n// avoid flooding history during a drag (useQueryTable does this).\n\nimport { useCallback, useMemo } from \"react\";\nimport type { QueryState, SelectColumn, FieldDef, FieldSchema } from \"@pythia-software/query-table-core\";\nimport { selectedFields } from \"@pythia-software/query-table-core\";\n\nexport interface SelectApi<Row> {\n /** Ordered visible columns (resolved: schema defaults when query.select is empty). */\n visible: SelectColumn[];\n /** The corresponding FieldDefs, same order. */\n fields: FieldDef<Row>[];\n /** Selectable fields not currently shown (for the \"add column\" picker). */\n hidden: FieldDef<Row>[];\n\n show: (field: string) => void;\n hide: (field: string) => void;\n /** Reorder via drag-drop: move `field` to `toIndex` in the visible order. */\n move: (field: string, toIndex: number) => void;\n /** Set a column's pixel width. */\n setWidth: (field: string, width: number) => void;\n /** Reset to the schema's default columns (clears query.select). */\n reset: () => void;\n}\n\ntype SetQuery = (next: QueryState | ((prev: QueryState) => QueryState)) => void;\n\nexport function useSelect<Row>(query: QueryState, setQuery: SetQuery, schema: FieldSchema<Row>): SelectApi<Row> {\n const fields = useMemo(() => selectedFields(schema, query), [schema, query]);\n\n // The materialized SelectColumn[] (resolve defaults so the UI always has a\n // concrete, reorderable list even before the user customizes it).\n const visible = useMemo<SelectColumn[]>(() => fields.map((f) => columnFor(query.select, f.name)), [fields, query.select]);\n\n const hidden = useMemo<FieldDef<Row>[]>(() => {\n const shown = new Set(fields.map((f) => f.name));\n return schema.fields.filter((f) => !shown.has(f.name) && (f.select?.enabled ?? true));\n }, [schema, fields]);\n\n const writeSelect = useCallback(\n (mutate: (cols: SelectColumn[]) => SelectColumn[], clearFitToScreen = false) => {\n setQuery((prev) => {\n // Materialize current (resolved) columns the first time we diverge from defaults.\n const current = prev.select.length ? prev.select : visible;\n const next = { ...prev, select: mutate([...current]) };\n if (clearFitToScreen) delete next.fitToScreen;\n return next;\n });\n },\n [setQuery, visible],\n );\n\n const show = useCallback((field: string) => writeSelect((c) => (c.some((x) => x.field === field) ? c : [...c, { field }])), [writeSelect]);\n const hide = useCallback((field: string) => writeSelect((c) => c.filter((x) => x.field !== field)), [writeSelect]);\n const move = useCallback(\n (field: string, toIndex: number) =>\n writeSelect((c) => {\n const from = c.findIndex((x) => x.field === field);\n if (from === -1) return c;\n const [item] = c.splice(from, 1);\n c.splice(Math.max(0, Math.min(toIndex, c.length)), 0, item!);\n return c;\n }),\n [writeSelect],\n );\n const setWidth = useCallback(\n (field: string, width: number) =>\n writeSelect((c) => c.map((x) => (x.field === field ? { ...x, width: Math.round(width) } : x)), true),\n [writeSelect],\n );\n const reset = useCallback(() => setQuery((prev) => ({ ...prev, select: [] })), [setQuery]);\n\n return { visible, fields, hidden, show, hide, move, setWidth, reset };\n}\n\nfunction columnFor(select: SelectColumn[], name: string): SelectColumn {\n const found = select.find((c) => c.field === name);\n return found ?? { field: name };\n}\n","// useColumnDrag — transient, SHARED state for a column-reorder drag. One instance\n// is owned by useQueryTable and read by BOTH the table headers and the\n// QueryBuilder select chips, so a drag started in either surface live-previews\n// (and dims) the same column in the other. It holds no query state; the reorder\n// is committed to QueryState.select by whichever surface handles the drop.\n\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface ColumnDragApi {\n /** Field name currently being dragged, or null when idle. */\n source: string | null;\n /** Insertion index within the order with `source` removed (0..n; n = append). */\n overIndex: number | null;\n /** True while a column drag is in progress. */\n active: boolean;\n /** Changes only for confirmed drops, so surfaces can persist auxiliary positions. */\n dropRevision?: number;\n /** Begin dragging `field` at `index`. Supply the surface order for cross-surface mapping. */\n start: (field: string, index: number, order?: string[]) => void;\n /** Update the insertion slot and optional surface order (no-op if unchanged). */\n over: (index: number, order?: string[]) => void;\n /** End the drag (on drop or cancel). */\n end: (committed?: boolean) => void;\n /** The live order to render while dragging: `source` moved to `overIndex`.\n * Returns `order` unchanged when idle, or when `source` isn't in `order`. */\n preview: (order: string[]) => string[];\n}\n\ninterface DragState {\n source: string;\n overIndex: number;\n order: string[] | undefined;\n moved: boolean;\n}\n\nexport function useColumnDrag(): ColumnDragApi {\n const [state, setState] = useState<DragState | null>(null);\n const [dropRevision, setDropRevision] = useState(0);\n\n const start = useCallback(\n (field: string, index: number, order?: string[]) =>\n setState({\n source: field,\n overIndex: index,\n order: order?.slice(),\n moved: false,\n }),\n [],\n );\n const over = useCallback(\n (index: number, order?: string[]) =>\n // Keep the SAME object reference when unchanged so React can bail out of the\n // re-render — onDragOver fires continuously while the cursor moves.\n setState((s) => {\n if (!s) return s;\n if (\n s.moved &&\n s.overIndex === index &&\n ((!order && !s.order) ||\n (order &&\n s.order &&\n order.length === s.order.length &&\n order.every((name, i) => name === s.order![i])))\n )\n return s;\n return {\n source: s.source,\n overIndex: index,\n order: order?.slice(),\n moved: true,\n };\n }),\n [],\n );\n const end = useCallback((committed = false) => {\n if (committed) setDropRevision((revision) => revision + 1);\n setState(null);\n }, []);\n\n const preview = useCallback(\n (order: string[]): string[] => {\n if (!state || (state.order && !state.moved)) return order;\n const without = order.filter((n) => n !== state.source);\n if (without.length === order.length) return order; // source not part of this list\n let at = Math.max(0, Math.min(state.overIndex, without.length));\n if (state.order) {\n // Surfaces can contain different auxiliary columns (e.g. selection).\n // Resolve the slot against shared neighboring fields, not raw indices.\n const reference = state.order.filter((name) => name !== state.source);\n const slot = Math.max(0, Math.min(state.overIndex, reference.length));\n const following = reference\n .slice(slot)\n .find((name) => without.includes(name));\n const preceding = reference\n .slice(0, slot)\n .reverse()\n .find((name) => without.includes(name));\n if (following != null) at = without.indexOf(following);\n else if (preceding != null) at = without.indexOf(preceding) + 1;\n }\n return [...without.slice(0, at), state.source, ...without.slice(at)];\n },\n [state],\n );\n\n return useMemo(\n () => ({\n source: state?.source ?? null,\n overIndex: state?.overIndex ?? null,\n active: state != null,\n dropRevision,\n start,\n over,\n end,\n preview,\n }),\n [state, dropRevision, start, over, end, preview],\n );\n}\n","// useSavedQueries — named query snapshots over a StorageAdapter.\n//\n// \"Last query\" auto-restore and named saves both flow through the injected\n// StorageAdapter (in-memory by default, explicitly durable when the caller\n// provides one). Loading a saved query pushes its QueryState into the controller.\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type { QueryState, SavedQuery, StorageAdapter, QuerySnapshot } from \"@pythia-software/query-table-core\";\n\nexport interface SavedQueriesApi {\n items: SavedQuery[];\n loading: boolean;\n /** Saved query id used as the default view when no query is specified. */\n defaultId: string | null;\n /** Persist the current query under a name. Rejects on duplicate names. */\n save: (name: string) => Promise<SavedQuery>;\n /** Whether the storage adapter supports atomic updates. */\n canUpdate: boolean;\n /** Replace a saved query with the current state, retaining its id and default. */\n update: (id: string) => Promise<SavedQuery>;\n /** Load a saved query into the live controller. */\n load: (id: string) => void;\n /** Mark a saved query as the default view. No-op when storage lacks support. */\n setDefault: (id: string) => Promise<void>;\n /** Clear the saved-query default view. */\n clearDefault: () => Promise<void>;\n remove: (id: string) => Promise<void>;\n}\n\nexport function useSavedQueries(\n key: string,\n currentQuery: QueryState,\n applyQueryState: (q: QueryState) => void,\n storage: StorageAdapter,\n /** Injected clock so saves are deterministic/testable. */\n now: () => number,\n snapshot?: (query: QueryState) => Promise<QuerySnapshot | null>,\n): SavedQueriesApi {\n const [items, setItems] = useState<SavedQuery[]>([]);\n const [defaultId, setDefaultId] = useState<string | null>(null);\n const [loading, setLoading] = useState(true);\n const storageRef = useRef(storage);\n storageRef.current = storage;\n\n const refresh = useCallback(async () => {\n const storage = storageRef.current;\n setLoading(true);\n try {\n const [savedItems, defaultSaved] = await Promise.allSettled([\n storage.listSaved(key),\n storage.loadDefaultSaved?.(key) ?? Promise.resolve(null),\n ]);\n // Optional catalogue reads must not block the table or turn a committed\n // save into a reported failure. Keep the last successful data on failure.\n if (savedItems.status === \"fulfilled\") setItems(savedItems.value);\n if (defaultSaved.status === \"fulfilled\") setDefaultId(defaultSaved.value?.id ?? null);\n } finally {\n setLoading(false);\n }\n }, [key]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const save = useCallback(\n async (name: string) => {\n name = name.trim();\n if (!name || name.length > 200) throw Error(\"Saved query name must be between 1 and 200 characters.\");\n const immutable = await snapshot?.(currentQuery);\n const saved = await storage.saveNamed(key, name, currentQuery, now(), immutable?.code);\n await refresh();\n return saved;\n },\n [storage, key, currentQuery, now, refresh, snapshot],\n );\n\n const load = useCallback(\n (id: string) => {\n const found = items.find((q) => q.id === id);\n if (found) applyQueryState(found.query);\n },\n [items, applyQueryState],\n );\n\n const update = useCallback(\n async (id: string) => {\n if (!storage.updateNamed) throw Error(\"This storage adapter does not support saved-query updates.\");\n const immutable = await snapshot?.(currentQuery);\n const saved = await storage.updateNamed(key, id, currentQuery, now(), immutable?.code);\n await refresh();\n return saved;\n },\n [storage, key, currentQuery, now, refresh, snapshot],\n );\n\n const setDefault = useCallback(\n async (id: string) => {\n await storage.setDefaultSaved?.(key, id);\n await refresh();\n },\n [storage, key, refresh],\n );\n\n const clearDefault = useCallback(async () => {\n await storage.setDefaultSaved?.(key, null);\n await refresh();\n }, [storage, key, refresh]);\n\n const remove = useCallback(\n async (id: string) => {\n if (id === defaultId) await storage.setDefaultSaved?.(key, null);\n await storage.deleteSaved(key, id);\n await refresh();\n },\n [storage, key, defaultId, refresh],\n );\n\n return { items, loading, defaultId, save, canUpdate: Boolean(storage.updateNamed), update, load, setDefault, clearDefault, remove };\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { encodeQuery, type QueryLink, type QueryLinkService, type QueryState, type QuerySnapshot } from \"@pythia-software/query-table-core\";\n\nexport interface QueryLinksApi {\n maxUrlBytes: number;\n kind: QueryLink[\"kind\"] | null;\n busy: boolean;\n error: Error | null;\n /** Explicit Share/Bookmark: server snapshot if configured, otherwise a fitting inline link. */\n create(query?: QueryState, options?: { baseUrl?: string; parameter?: string }): Promise<QueryLink>;\n /** Synchronous local-only URL for navigation, never a server write. */\n local(query: QueryState, baseUrl?: string, parameter?: string): QueryLink;\n /** Save uses the same immutable snapshot and promotion path as Share. */\n snapshot(query: QueryState): Promise<QuerySnapshot | null>;\n}\n\nexport function useQueryLinks(query: QueryState, service: QueryLinkService, syncUrl: boolean, ready: boolean, parameter: string, maxUrlBytes: number,\n onUrlChange: (url: string) => void): QueryLinksApi {\n const latest = useRef(query); latest.current = query;\n const [kind, setKind] = useState<QueryLink[\"kind\"] | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const mounted = useRef(true);\n const operations = useRef(0);\n useEffect(() => { mounted.current = true; return () => { mounted.current = false; }; }, []);\n const queryKey = JSON.stringify(query);\n useEffect(() => {\n if (!syncUrl || !ready || typeof window === \"undefined\") return;\n try {\n // Preserve an already-promoted link until the query actually changes.\n const result = service.local(query, window.location.href, parameter);\n window.history.replaceState(window.history.state, \"\", result.url);\n onUrlChange(result.url);\n setKind(result.kind); setError(null);\n } catch (e) { setError(e instanceof Error ? e : Error(String(e))); }\n }, [queryKey, syncUrl, ready, service, parameter, onUrlChange]);\n\n const snapshot = useCallback(async (q: QueryState) => {\n const captured = encodeQuery(q);\n const base = typeof window !== \"undefined\" ? window.location.href : undefined;\n operations.current++; setBusy(true); setError(null);\n try {\n if (!ready) throw Error(\"Resolve or reset the query link before saving it.\");\n const saved = await service.snapshot(q);\n if (saved && base && mounted.current && syncUrl && ready && window.location.href === base && encodeQuery(latest.current) === captured) {\n const url = new URL(base); url.searchParams.set(parameter, \"@\" + saved.code);\n const result = service.local(q, url.toString(), parameter);\n window.history.replaceState(window.history.state, \"\", result.url); onUrlChange(result.url); setKind(\"durable\");\n }\n return saved;\n }\n catch (e) { if (mounted.current) setError(e instanceof Error ? e : Error(String(e))); throw e; }\n finally { operations.current--; if (mounted.current) setBusy(operations.current > 0); }\n }, [service, syncUrl, ready, parameter, onUrlChange]);\n const create = useCallback(async (q = latest.current, options: { baseUrl?: string; parameter?: string } = {}) => {\n const baseUrl = options.baseUrl ?? window.location.href;\n const param = options.parameter ?? parameter;\n const captured = encodeQuery(q);\n operations.current++; setBusy(true); setError(null);\n try {\n if (!ready) throw Error(\"Resolve or reset the query link before sharing it.\");\n const result = await service.durable(q, baseUrl, param);\n if (mounted.current && syncUrl && ready && param === parameter &&\n window.location.href === baseUrl && encodeQuery(latest.current) === captured) {\n window.history.replaceState(window.history.state, \"\", result.url);\n onUrlChange(result.url);\n setKind(result.kind);\n }\n return result;\n } catch (e) { if (mounted.current) setError(e instanceof Error ? e : Error(String(e))); throw e; }\n finally { operations.current--; if (mounted.current) setBusy(operations.current > 0); }\n }, [service, syncUrl, ready, parameter, onUrlChange]);\n const local = useCallback((q: QueryState, base = window.location.href, param = parameter) => service.local(q, base, param), [service, parameter]);\n return { maxUrlBytes, kind, busy, error, create, local, snapshot };\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport {\n objectReferenceKey,\n type ObjectReference,\n type RelationshipAdapter,\n type ResolvedObjectReference,\n} from \"@pythia-software/query-table-core\";\n\n/** One cancellable batch per displayed reference set; rejects unrelated results. */\nexport function useObjectReferences(\n references: ObjectReference[],\n adapter?: RelationshipAdapter,\n) {\n const fingerprint = JSON.stringify(references.map(objectReferenceKey).sort());\n const batch = useMemo(\n () => [\n ...new Map(\n references.map((reference) => [\n objectReferenceKey(reference),\n reference,\n ]),\n ).values(),\n ],\n [fingerprint],\n );\n const [state, setState] = useState({\n fingerprint: \"\",\n adapter: undefined as RelationshipAdapter | undefined,\n values: new Map<string, ResolvedObjectReference>(),\n error: null as Error | null,\n });\n useEffect(() => {\n const controller = new AbortController();\n if (!adapter || batch.length === 0) return;\n const allowed = new Set(batch.map(objectReferenceKey));\n void Promise.resolve()\n .then(() => adapter.resolve(batch, controller.signal))\n .then((results) => {\n if (controller.signal.aborted) return;\n const values = new Map<string, ResolvedObjectReference>();\n for (const result of results) {\n const key = objectReferenceKey(result.reference);\n if (allowed.has(key)) values.set(key, result);\n }\n setState({ fingerprint, adapter, values, error: null });\n })\n .catch((error) => {\n if (!controller.signal.aborted)\n setState({\n fingerprint,\n adapter,\n values: new Map(),\n error: error instanceof Error ? error : new Error(String(error)),\n });\n });\n return () => controller.abort();\n }, [batch, adapter]);\n const current =\n state.fingerprint === fingerprint && state.adapter === adapter;\n return {\n values: current ? state.values : new Map<string, ResolvedObjectReference>(),\n error: current ? state.error : null,\n };\n}\n"],"mappings":"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","names":["predicatesOf","grouping","column","withoutGrouping","useCallback","useEffect","useRef","useState","useCallback","useEffect","useMemo","useRef","useState","useRef","useEffect","queryParameter","useCallback","row","useState","useCallback","useEffect","useMemo","useRef","useState","isComputedField","readFieldValue","abort","useMemo","useState","useRef","useCallback","useEffect","isComputedField","f","readFieldValue","useCallback","useEffect","useMemo","useRef","useState","applyQuery","normalizeQueryState","readFieldValue","selectedFields","toServerQuery","queriesEqual","isOrGroup","metricPlans","validateMetric","isComputedField","computedFieldName","useCallback","useEffect","useMemo","useRef","useState","abort","useCallback","useEffect","useMemo","useRef","useState","metricPlans","hasRegex","normalizeQueryState","hasRegex","readFieldValue","isComputedField","isComputedField","normalizeQueryState","hasRegex","values","readFieldValue","useState","useRef","useCallback","metricPlans","hasRegex","useMemo","useEffect","useCallback","useEffect","useMemo","useState","next","useCallback","useMemo","useCallback","useMemo","useState","useCallback","useEffect","useRef","useState","storage","useCallback","useEffect","useRef","useState","selectedFields","normalizeQueryState","isOrGroup","readFieldValue","useMemo","useRef","useState","useCallback","error","withoutGrouping","useEffect","queriesEqual","storage","linkService","defaults","abort","isComputedField","validateMetric","metricPlans","toServerQuery","computedFieldName","applyQuery","patch","useEffect","useMemo","useState"]}