@pythia-software/query-table-core 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/README.md +73 -0
- package/dist/index.d.ts +1002 -282
- package/dist/index.js +4202 -914
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/computed.ts","../src/query.ts","../src/schema.ts","../src/ops.ts","../src/agg.ts","../src/setFilter.ts","../src/encode.ts","../src/apply.ts","../src/adapters.ts","../src/formula.ts"],"sourcesContent":["import type { FormulaResult, FormulaValue } from \"./formula\";\n\n/** Reserved field token namespace. Query state stores IDs, never formula source. */\nexport const COMPUTED_PREFIX = \"@computed/\";\nexport const computedFieldName = (id: string): string => COMPUTED_PREFIX + id;\nexport const isComputedField = (name: string): boolean =>\n name.trim().toLowerCase().startsWith(COMPUTED_PREFIX);\nexport interface ComputedColumn {\n id: string;\n label: string;\n expression: { language: \"qt-expr\"; version: 1; source: string };\n /** Optimistic concurrency token issued by the store. */\n revision: string;\n}\nexport type ComputedColumnDraft = Omit<ComputedColumn, \"revision\">;\nexport interface ComputedColumnStore {\n /** Return the complete authorized catalogue for this dataset. */\n list(dataset: string, signal?: AbortSignal): Promise<ComputedColumn[]>;\n /** null creates a new ID; updates must match the current revision. */\n save(\n dataset: string,\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ): Promise<ComputedColumn>;\n /** Optional push invalidation, including changes from other sessions. */\n subscribe?(dataset: string, listener: () => void): () => void;\n}\nexport function validateComputedColumn(input: unknown): ComputedColumn {\n const c = input as ComputedColumn;\n if (\n !c ||\n typeof c.id !== \"string\" ||\n !/^[a-zA-Z0-9_-]{1,128}$/.test(c.id) ||\n typeof c.label !== \"string\" ||\n !c.label.trim() ||\n c.label.length > 200 ||\n typeof c.revision !== \"string\" ||\n !c.revision ||\n c.revision.length > 256 ||\n c.expression?.language !== \"qt-expr\" ||\n c.expression.version !== 1 ||\n typeof c.expression.source !== \"string\" ||\n !c.expression.source.trim() ||\n c.expression.source.length > 10000\n ) {\n throw new Error(\n \"Invalid computed column definition or unsupported formula version.\",\n );\n }\n return {\n id: c.id,\n label: c.label,\n revision: c.revision,\n expression: { ...c.expression },\n };\n}\nexport function memoryComputedColumnStore(\n seed: Record<string, ComputedColumn[]> = {},\n): ComputedColumnStore {\n const data = new Map(\n Object.entries(seed).map(([k, v]) => [\n k,\n new Map(v.map((c) => [c.id, validateComputedColumn(c)])),\n ]),\n );\n // Revisions are opaque: never derive a new token by parsing an existing one.\n // Reserve all seed tokens so even a seed from this namespace cannot recur.\n const seedRevisions = new Set(\n [...data.values()].flatMap((entries) =>\n [...entries.values()].map((c) => c.revision),\n ),\n );\n let revisionSequence = 0n;\n function freshRevision(): string {\n let revision: string;\n do {\n revision = `memory:${++revisionSequence}`;\n } while (seedRevisions.has(revision));\n return revision;\n }\n const listeners = new Map<string, Set<() => void>>();\n return {\n async list(dataset) {\n return [...(data.get(dataset)?.values() ?? [])].map(\n validateComputedColumn,\n );\n },\n async save(dataset, column, expectedRevision) {\n const entries = data.get(dataset) ?? new Map<string, ComputedColumn>();\n const current = entries.get(column.id);\n if ((current?.revision ?? null) !== expectedRevision)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n const next = validateComputedColumn({\n ...column,\n revision: freshRevision(),\n });\n entries.set(next.id, next);\n data.set(dataset, entries);\n listeners.get(dataset)?.forEach((fn) => fn());\n return validateComputedColumn(next);\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\n\n/** REST adapter. The implementing server owns authorization and DB persistence.\n * GET base?dataset=… → ComputedColumn[]\n * PUT base?dataset=… → {column, expectedRevision} → ComputedColumn\n * Return HTTP 409 for a stale revision. No formula evaluation happens there. */\nexport function httpComputedColumnStore(\n base: string,\n fetcher: typeof fetch = fetch,\n): ComputedColumnStore {\n const listeners = new Map<string, Set<() => void>>();\n const url = (dataset: string) =>\n `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(dataset)}`;\n async function read(response: Response): Promise<unknown> {\n if (response.status === 409)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n if (!response.ok)\n throw new Error(\n `Computed column store request failed (${response.status}).`,\n );\n return response.json();\n }\n return {\n async list(dataset, signal) {\n const raw = await read(\n await fetcher(url(dataset), { ...(signal ? { signal } : {}) }),\n );\n if (!Array.isArray(raw))\n throw new Error(\"Invalid computed column catalogue.\");\n return raw.map(validateComputedColumn);\n },\n async save(dataset, column, expectedRevision) {\n const result = validateComputedColumn(\n await read(\n await fetcher(url(dataset), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ column, expectedRevision }),\n }),\n ),\n );\n listeners.get(dataset)?.forEach((fn) => fn());\n return result;\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\nexport interface ComputedCellError {\n computedError: string;\n}\nexport function isComputedCellError(\n value: unknown,\n): value is ComputedCellError {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"computedError\" in value &&\n typeof (value as ComputedCellError).computedError === \"string\"\n );\n}\nexport interface PreviewGroup {\n inputs: FormulaValue[];\n result: FormulaResult;\n count: number;\n}\nexport interface ColumnPreview {\n dependencies: string[];\n groups: PreviewGroup[];\n processed: number;\n total: number;\n nulls: number;\n errors: number;\n}\nexport function groupPreview(\n dependencies: string[],\n inputs: Record<string, FormulaValue>[],\n results: FormulaResult[],\n total: number,\n): ColumnPreview {\n const groups = new Map<string, PreviewGroup>();\n let nulls = 0,\n errors = 0;\n inputs.forEach((row, i) => {\n const values = dependencies.map((name) => row[name] ?? null),\n result = results[i] ?? { value: null, error: \"No result.\" };\n const key = JSON.stringify([values, result.value, result.error ?? null]);\n const group = groups.get(key);\n if (group) group.count++;\n else groups.set(key, { inputs: values, result, count: 1 });\n if (result.error) errors++;\n else if (result.value === null) nulls++;\n });\n return {\n dependencies,\n groups: [...groups.values()].sort((a, b) => b.count - a.count),\n processed: inputs.length,\n total,\n nulls,\n errors,\n };\n}\n","import { isComputedField } from \"./computed\";\n// query.ts — the canonical query state shape.\n//\n// We lean into SQL vocabulary at every layer (per design feedback): a QueryState\n// reads top-to-bottom like the statement it compiles to —\n//\n// SELECT <select> WHERE <where> ORDER BY <orderBy> LIMIT <limit> OFFSET <offset>\n//\n// Both \"what data\" (where/orderBy/limit/offset) and \"how viewed\" (select +\n// per-column width) can be serialized together when a consumer explicitly opts\n// into URL synchronization.\n\n/** All filter operators across both source projects, unioned. Every value can\n * be NULL, so `is_null`/`is_not_null` are valid for every field type. */\nexport type FilterOp =\n // comparison — number / datetime (and =,!= for any scalar)\n | \"=\"\n | \"!=\"\n | \">\"\n | \">=\"\n | \"<\"\n | \"<=\"\n // text matching\n | \"contains\"\n | \"starts_with\"\n | \"ends_with\"\n | \"matches_regex\"\n | \"not_matches_regex\"\n | \"length_gt\"\n | \"length_lt\"\n | \"length_eq\"\n // array (textarray) containment\n | \"includes\"\n // nullity — valid for EVERY type; for arrays, \"empty\" vs \"non-empty\"\n | \"is_null\"\n | \"is_not_null\";\n\n/** A single filter predicate (a \"literal\" in CNF terms). `value` is always the\n * raw string the UI captured; coercion to number/bool/date happens at\n * apply/compile time based on the field's declared type (never on the value's\n * runtime shape). Unused for the nullary ops (`is_null`/`is_not_null`).\n *\n * `negated` wraps the predicate in a logical NOT. It is only ever set for ops\n * that have no complementary operator (`contains`/`starts_with`/`ends_with`/\n * `includes`); ops with a complement negate by flipping the op itself (`>=`→`<`,\n * `=`→`!=`, `is_null`→`is_not_null`, `matches_regex`→`not_matches_regex`) — see\n * `negateClause` in ops.ts. NOT is null-exclusive: a NULL/empty value satisfies\n * neither the predicate nor its negation, matching `not_matches_regex`. */\nexport interface WhereClause {\n field: string; // FieldDef.name\n op: FilterOp;\n value: string;\n negated?: boolean;\n setFilter?: SetFilterMetadata;\n}\n\nexport type SetFilterMode = \"any\" | \"all\" | \"none\" | \"empty\";\n\n/** Presentation-only identity; execution always uses the accompanying predicates. */\nexport interface SetFilterMetadata {\n id: string;\n mode: SetFilterMode;\n values: string[];\n}\n\n/** A disjunction of predicates — the inner OR of conjunctive normal form. Every\n * member is a plain literal; nesting is intentionally not allowed yet (CNF\n * only), but the object shape leaves room to grow. */\nexport interface OrGroup {\n any: WhereClause[];\n setFilter?: SetFilterMetadata;\n}\n\n/** One conjunct of the WHERE clause: either a single predicate or an OR group.\n * `QueryState.where` is the AND of these terms, so the whole WHERE is\n * conjunctive normal form — `(a) AND (b OR c) AND (d)`. A bare literal is\n * equivalent to a one-element OR group; normalization flattens singleton groups\n * back to a literal so equality/encoding stay canonical. */\nexport type WhereTerm = WhereClause | OrGroup;\n\n/** Narrow a term to an OR group. A literal always carries `field`; a group never\n * does and always carries an `any` array. */\nexport function isOrGroup(term: WhereTerm): term is OrGroup {\n return Array.isArray((term as OrGroup).any);\n}\n\n/** The predicate literals a term contributes, in order: the term itself for a\n * literal, or its members for a group. Handy for anything that must visit every\n * predicate regardless of grouping (field allowlisting, SELECT projection). */\nexport function predicatesOf(term: WhereTerm): WhereClause[] {\n return isOrGroup(term) ? term.any : [term];\n}\n\n/** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */\nexport interface OrderByClause {\n field: string; // FieldDef.name (server may sort a different expr via FieldDef.sort.field)\n dir: \"asc\" | \"desc\";\n /** NULL placement. Omitted = \"last\" (the historical default both projects used,\n * preserved so old `?q=` links round-trip identically). */\n nulls?: \"first\" | \"last\";\n /** Sort by the first capture group of a regex match (or by the whole match\n * when the pattern has no capture group). A non-match produces NULL. Regex\n * syntax is interpreted by the executor (JavaScript locally, PostgreSQL on\n * the bundled Go backend), so portable patterns should use their common\n * syntax subset. */\n extract?: { regex: string };\n}\n\n/** One column in the SELECT list, plus the view state that travels with it.\n * Order in `QueryState.select` is the left-to-right display order. */\nexport interface SelectColumn {\n field: string; // FieldDef.name, or @computed/<id> (source lives in ComputedColumnStore)\n /** Pixel width override. Omitted = FieldDef.select.width, else the type default. */\n width?: number;\n}\n\n/** A single aggregate operation. `count` is the only op that needs no measure\n * column (it counts rows); the rest reduce one column's values. The server-side\n * matrix (backends/go aggOpAllowed + the TS AGG_OPS_BY_TYPE) decides which ops a\n * field's type permits. */\nexport type AggOp = \"count\" | \"count_distinct\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\n/** One optional \"metric\" pinned above the table: a single aggregate over a single\n * measure column, optionally broken down by one or more group columns.\n *\n * Scope is deliberately the *whole filtered set* — the same WHERE as the table,\n * but NOT its ORDER BY / LIMIT / OFFSET. It is always evaluated on the server\n * (a real GROUP BY), so it reflects every matching row, not just the visible\n * page. Lives inside QueryState so it round-trips through `?q=`, saved queries,\n * and undo/redo for free — a saved query is a saved dashboard. */\nexport interface AggregationClause {\n /** Stable id; keys the metric panel and survives a `?q=` round-trip. */\n id: string;\n op: AggOp;\n /** Measure column (FieldDef.name). Omit only for `count` (⇒ COUNT(*)). */\n field?: string;\n /** Group-by columns, in axis order. `[]` = a single grand-total value.\n * One ⇒ a list/bar breakdown; two ⇒ an x/y pivot; three+ ⇒ a flat table. */\n groupBy: string[];\n /** Panel header override; defaults to a derived label like \"avg total\". */\n label?: string;\n}\n\nexport interface QueryState {\n /** Ordered SELECT list + per-column widths. Empty = the schema's default columns. */\n select: SelectColumn[];\n /** WHERE in conjunctive normal form: the AND of these terms, each a single\n * predicate or an OR group. A flat list of literals (no groups) is the common\n * case and the legacy shape, decoded unchanged. */\n where: WhereTerm[];\n /** Multi-sort terms in priority order. Empty = the schema's default sort. */\n orderBy: OrderByClause[];\n /** Page size. */\n limit: number;\n /** Page offset (rows). */\n offset: number;\n /** Optional aggregate metrics shown above the table. Omitted/empty = none.\n * Each runs as its own server GROUP BY over the WHERE-filtered set (no paging). */\n aggregations?: AggregationClause[];\n}\n\n/** A row's stable identity, used for selection and per-row refresh. */\nexport type RowId = string | number;\n\n/** The query a fresh table starts from before schema defaults are layered on.\n * Empty `select`/`orderBy`/`where` mean \"defer to the schema\", which also keeps\n * encoded `?q=` tokens short (defaults are omitted). */\nexport const EMPTY_QUERY: QueryState = {\n select: [],\n where: [],\n orderBy: [],\n limit: 100,\n offset: 0,\n};\n\n/** Structural limits applied whenever query state crosses a trust boundary\n * (URL, storage, an imperative setQuery call, or a server projection). Row\n * limits may use the full safe-integer range; consumers and their backends own\n * any smaller operational cap appropriate for their dataset. */\nexport const MAX_QUERY_LIMIT = Number.MAX_SAFE_INTEGER;\nexport const MAX_QUERY_OFFSET = 1_000_000;\nexport const MAX_SELECT_COLUMNS = 200;\nexport const MAX_WHERE_CLAUSES = 100;\nexport const MAX_ORDER_BY_TERMS = 20;\nexport const MAX_AGGREGATIONS = 20;\nexport const MAX_GROUP_BY_FIELDS = 20;\nexport const MAX_QUERY_TOKEN_LENGTH = 2 * 1024 * 1024;\n\nconst MAX_FIELD_NAME_LENGTH = 256;\nconst MAX_FILTER_VALUE_LENGTH = 10_000;\nconst MAX_LABEL_LENGTH = 1_000;\nconst MIN_COLUMN_WIDTH = 24;\nconst MAX_COLUMN_WIDTH = 2_000;\n\nconst FILTER_OPS: ReadonlySet<string> = new Set([\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n \"includes\",\n \"is_null\",\n \"is_not_null\",\n]);\n\nconst AGG_OPS: ReadonlySet<string> = new Set([\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction boundedString(value: unknown, maxLength: number): string | null {\n return typeof value === \"string\" && value.length > 0 && value.length <= maxLength ? value : null;\n}\n\nfunction boundedInteger(value: unknown, fallback: number, min: number, max: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.min(max, Math.round(value)));\n}\n\n/** Validate one raw predicate into a bounded WhereClause, or null if malformed.\n * Shared by top-level literals and the members of an OR group. */\nfunction normalizeWhereClause(item: unknown): WhereClause | null {\n if (!isRecord(item)) return null;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const value = typeof item.value === \"string\" && item.value.length <= MAX_FILTER_VALUE_LENGTH ? item.value : null;\n if (!field || isComputedField(field) || typeof item.op !== \"string\" || !FILTER_OPS.has(item.op) || value == null) {\n return null;\n }\n const clause: WhereClause = { field, op: item.op as FilterOp, value };\n if (item.negated === true) clause.negated = true;\n return clause;\n}\n\n/** Deep-clone one WHERE term (literal or group) so a normalized/fallback state\n * never aliases the caller's arrays. */\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 normalizeSetFilter(item: unknown): SetFilterMetadata | undefined {\n if (!isRecord(item)) return undefined;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id || ![\"any\", \"all\", \"none\", \"empty\"].includes(String(item.mode)) || !Array.isArray(item.values)) return undefined;\n if (item.values.length > MAX_WHERE_CLAUSES || !item.values.every((value) => typeof value === \"string\" && value.length <= MAX_FILTER_VALUE_LENGTH)) return undefined;\n return { id, mode: item.mode as SetFilterMode, values: [...item.values] as string[] };\n}\n\n/** Convert unknown input into a bounded, structurally valid QueryState.\n * Invalid members are dropped; invalid scalar paging values use the supplied\n * fallback. This function is intentionally schema-agnostic—field allowlisting\n * still happens in toServerQuery and in the backend compiler. */\nexport function normalizeQueryState(input: unknown, fallback: QueryState = EMPTY_QUERY): QueryState {\n const raw = isRecord(input) ? input : {};\n\n const select: SelectColumn[] = [];\n if (Array.isArray(raw.select)) {\n for (const item of raw.select.slice(0, MAX_SELECT_COLUMNS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field) continue;\n const column: SelectColumn = { field };\n if (typeof item.width === \"number\" && Number.isFinite(item.width)) {\n column.width = boundedInteger(item.width, MIN_COLUMN_WIDTH, MIN_COLUMN_WIDTH, MAX_COLUMN_WIDTH);\n }\n select.push(column);\n }\n } else {\n select.push(...fallback.select.map((column) => ({ ...column })));\n }\n\n // WHERE is CNF: an array of terms, each a literal or an `{ any: [...] }` OR\n // group. MAX_WHERE_CLAUSES bounds the TOTAL predicate count across all terms\n // (legacy flat lists are all literals, so the cap is unchanged for them).\n // Singleton/empty groups are canonicalized (flattened / dropped).\n const where: WhereTerm[] = [];\n if (Array.isArray(raw.where)) {\n let literalBudget = MAX_WHERE_CLAUSES;\n for (const item of raw.where) {\n if (literalBudget <= 0) break;\n const start = where.length;\n if (isRecord(item) && Array.isArray((item as { any?: unknown }).any)) {\n const members: WhereClause[] = [];\n for (const inner of (item as { any: unknown[] }).any) {\n if (literalBudget <= 0) break;\n const clause = normalizeWhereClause(inner);\n if (clause) {\n members.push(clause);\n literalBudget--;\n }\n }\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n // 0 members → drop the term entirely\n } else {\n const clause = normalizeWhereClause(item);\n if (clause) {\n where.push(clause);\n literalBudget--;\n }\n }\n if (where.length > start && isRecord(item)) {\n const metadata = normalizeSetFilter(item.setFilter);\n if (metadata) where[start]!.setFilter = metadata;\n }\n }\n } else {\n where.push(...fallback.where.map(cloneWhereTerm));\n }\n\n const orderBy: OrderByClause[] = [];\n if (Array.isArray(raw.orderBy)) {\n for (const item of raw.orderBy.slice(0, MAX_ORDER_BY_TERMS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field || isComputedField(field) || (item.dir !== \"asc\" && item.dir !== \"desc\")) continue;\n const term: OrderByClause = { field, dir: item.dir };\n if (item.nulls === \"first\" || item.nulls === \"last\") term.nulls = item.nulls;\n if (\n isRecord(item.extract) &&\n typeof item.extract.regex === \"string\" &&\n item.extract.regex.length <= MAX_FILTER_VALUE_LENGTH\n ) {\n term.extract = { regex: item.extract.regex };\n }\n orderBy.push(term);\n }\n } else {\n orderBy.push(\n ...fallback.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n );\n }\n\n const out: QueryState = {\n select,\n where,\n orderBy,\n limit: boundedInteger(raw.limit, fallback.limit, 1, MAX_QUERY_LIMIT),\n offset: boundedInteger(raw.offset, fallback.offset, 0, MAX_QUERY_OFFSET),\n };\n\n if (Array.isArray(raw.aggregations)) {\n const aggregations: AggregationClause[] = [];\n for (const item of raw.aggregations.slice(0, MAX_AGGREGATIONS)) {\n if (!isRecord(item)) continue;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id || typeof item.op !== \"string\" || !AGG_OPS.has(item.op) || !Array.isArray(item.groupBy)) continue;\n const groupBy = item.groupBy\n .slice(0, MAX_GROUP_BY_FIELDS)\n .map((field) => boundedString(field, MAX_FIELD_NAME_LENGTH))\n .filter((field): field is string => field != null);\n const aggregation: AggregationClause = { id, op: item.op as AggOp, groupBy };\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const label = boundedString(item.label, MAX_LABEL_LENGTH);\n if ((field && isComputedField(field)) || groupBy.some(isComputedField)) continue;\n if (field) aggregation.field = field;\n if (label) aggregation.label = label;\n aggregations.push(aggregation);\n }\n if (aggregations.length > 0) out.aggregations = aggregations;\n } else if (fallback.aggregations?.length) {\n out.aggregations = fallback.aggregations.map((aggregation) => ({ ...aggregation, groupBy: [...aggregation.groupBy] }));\n }\n\n return out;\n}\n\n/** Structural equality on two queries — used to decide whether a `?q=` write or a\n * refetch is actually needed (avoids history spam / redundant fetches). */\nexport function queriesEqual(a: QueryState, b: QueryState): boolean {\n if (a === b) return true;\n if (a.limit !== b.limit || a.offset !== b.offset) return false;\n if (!sameArray(a.where, b.where)) return false;\n if (!sameArray(a.orderBy, b.orderBy)) return false;\n if (!sameArray(a.select, b.select)) return false;\n if (!sameArray(a.aggregations ?? [], b.aggregations ?? [])) return false;\n return true;\n}\n\nfunction sameArray<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n // Members are records of primitives (WHERE terms may nest one `any` array of\n // them) — a structural JSON compare is correct and cheap here.\n if (JSON.stringify(a[i]) !== JSON.stringify(b[i])) return false;\n }\n return true;\n}\n","// schema.ts — the field schema: the contract that binds frontend and backend.\n//\n// A `FieldSchema` is the runtime, frontend-facing projection of a JSON schema\n// document (schema/query-table.schema.json). The same document is projected on\n// the backend into a Go `Schema` of SQL bindings. Codegen keeps the two in sync.\n//\n// `FieldDef` is organized to make two things obvious (per design feedback):\n//\n// 1. WHAT KIND of field it is — the `source` discriminated union. A `backend`\n// field is a column the server returns and can filter/sort; a `derived`\n// field is computed on the client (or render-only) and is never pushed to\n// the server. Each kind uses its own property subset, so you can't, say,\n// mark a client-only column as server-filterable.\n//\n// 2. CONFIG vs CODE. Everything except `source.accessor` and `render` is\n// declarative, serializable config grouped by capability (`filter`, `sort`,\n// `select`). The only code-bearing members are the derived `accessor` and\n// the `render` function — kept apart from the config so the two don't mix.\n\nimport type { AggOp, FilterOp, OrderByClause, SelectColumn } from \"./query\";\n\nexport type FieldType =\n | \"text\"\n | \"number\"\n | \"enum\"\n | \"datetime\"\n | \"bool\"\n | \"textarray\"; // array-of-text; supports `includes`, and null-as-empty semantics\n\nexport type Align = \"left\" | \"right\" | \"center\";\n\n/** A cell renderer is resolved by name against a `RenderRegistry` (in\n * @pythia-software/query-table-ui) or supplied inline. The type lives in core so FieldDef can\n * reference it, but core never imports React — `unknown` stands in for the node\n * and @pythia-software/query-table-ui narrows it to `React.ReactNode`. */\nexport type CellRenderer<Row = any, V = unknown> = (ctx: {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n}) => unknown;\n\n// ---- source: WHAT KIND of field (discriminated union) ---------------------\n\n/** A column the backend returns and can filter/sort. Its SQL expression lives in\n * the JSON schema doc's `bindings` (and the Go Schema), never on the frontend. */\nexport interface BackendField {\n kind: \"backend\";\n /** Dotted path into the API row when it differs from `name` (e.g. \"enqueued_at.Time\"). */\n path?: string;\n /** Computed SQL with no backing column (e.g. is_starred). Documentation hint\n * surfaced to the picker; the actual expression is server-side. */\n synthetic?: boolean;\n}\n\n/** A value computed on the client, or a purely render-driven column. Never\n * pushed to the server; client-side filtering/sorting (if any) reads `accessor`. */\nexport interface DerivedField<Row = any, V = unknown> {\n kind: \"derived\";\n /** Backend inputs required for accessors and computed formulas. */\n dependencies?: string[];\n /** Reusable computed column ID; always select-only. */\n computedId?: string;\n /** Compute the value from the row for client filter/sort. Omit for render-only\n * columns (the renderer reads the whole row from CellContext instead). */\n accessor?: (row: Row) => V;\n}\n\nexport type FieldSource<Row = any, V = unknown> = BackendField | DerivedField<Row, V>;\n\n// ---- capability config (declarative; serializable; shared with backend) ----\n\n/** How filter-value candidates are offered. Autocomplete is the DEFAULT for\n * every field (design feedback): the value input is a combobox backed by\n * Transport.fetchDistinctValues, which takes a search string so large domains\n * refine per keystroke on the backend. `static` is for closed domains you don't\n * want a round-trip for; `freeform` opts out of suggestions entirely. */\nexport type FilterValues =\n | { source: \"autocomplete\" }\n | { source: \"static\"; options: Array<string | { value: string; label: string }> }\n | { source: \"freeform\" };\n\nexport interface FilterConfig {\n /** Opt into the native multi-value editor for textarray fields. */\n editor?: \"set\";\n /** Preserve case when matching textarray values. Default false. */\n arrayCaseSensitive?: boolean;\n /** Whether this field is filterable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Evaluate on the backend (predicate pushdown)? Default: backend ⇒ true.\n * false ⇒ the clause is stripped from the server request and applied locally\n * by applyQuery (the \"serverFilter:false\" derived/JSONB-less columns). */\n pushdown?: boolean;\n /** Override the default operator set for the field's type. */\n ops?: FilterOp[];\n /** Value-suggestion strategy. Default { source: \"autocomplete\" }. */\n values?: FilterValues;\n}\n\nexport interface SortConfig {\n /** Whether this field is sortable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Server field to ORDER BY when it differs from the display field\n * (e.g. a \"★\" column whose server sort key is `is_starred`). */\n field?: string;\n}\n\nexport interface SelectConfig {\n /** Can this appear as a visible column? Default true. false ⇒ filter-only field. */\n enabled?: boolean;\n /** Shown by default when QueryState.select is empty. */\n default?: boolean;\n /** Default column width (px); a per-column override rides in QueryState.select. */\n width?: number;\n align?: Align;\n}\n\nexport interface AggregateConfig {\n /** Can this field be a metric's MEASURE (sum/avg/min/max/count_distinct)?\n * Default: backend ⇒ true, derived ⇒ false. */\n measure?: boolean;\n /** Can this field be a GROUP BY key? Default: enum/text/bool ⇒ true. */\n groupable?: boolean;\n /** Override the default aggregate-op set for the field's type. */\n ops?: AggOp[];\n}\n\n// ---- the field ------------------------------------------------------------\n\nexport interface FieldDef<Row = any, V = unknown> {\n // identity\n name: string; // canonical id; matches the backend binding key + Where/OrderBy `field`\n label: string;\n type: FieldType;\n\n // WHAT KIND of field (value origin + server capability)\n source: FieldSource<Row, V>;\n\n // capabilities (declarative config; omit for sensible per-source defaults)\n filter?: FilterConfig;\n sort?: SortConfig;\n select?: SelectConfig;\n aggregate?: AggregateConfig;\n\n // discovery (picker UX, declarative)\n group?: string; // grouping bucket\n alias?: string; // single alternative search term\n aliases?: string[]; // extra search terms\n\n // presentation (the only code-bearing field): registry key or inline fn\n render?: string | CellRenderer<Row, V>;\n}\n\n/** The frontend's loaded schema for one dataset. */\nexport interface FieldSchema<Row = any> {\n /** Dataset id, also the StorageAdapter namespace for saved queries. */\n name: string;\n /** Field that yields a row's stable id for selection / per-row refresh. */\n idField: string;\n fields: FieldDef<Row>[];\n /** Sort applied when QueryState.orderBy is empty. */\n defaultSort?: OrderByClause[];\n /** Columns shown when QueryState.select is empty. */\n defaultSelect?: SelectColumn[];\n /** Page size for a fresh query. */\n defaultLimit?: number;\n}\n\n// ---- derived capability helpers (the per-source defaults, in one place) ----\n\nexport function isFilterable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return false;\n return f.filter?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isPushdownFilter(f: FieldDef): boolean {\n return isFilterable(f) && (f.filter?.pushdown ?? f.source.kind === \"backend\");\n}\nexport function isSortable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return false;\n return f.sort?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isSelectable(f: FieldDef): boolean {\n return f.select?.enabled ?? true;\n}\nexport function filterValues(f: FieldDef): FilterValues {\n return f.filter?.values ?? { source: \"autocomplete\" };\n}\n\n// ---- schema operations ----------------------------------------------------\n\n/** Index fields by name for O(1) lookup. */\nexport function indexFields<Row>(schema: FieldSchema<Row>): Map<string, FieldDef<Row>> {\n return new Map(schema.fields.map((f) => [f.name, f]));\n}\n\n/** Resolve the ordered, selectable FieldDefs for a query, falling back to schema\n * defaults, then to every `select.default` field. Unknown/duplicate/unselectable\n * names in `select` are dropped. */\nexport function selectedFields<Row>(\n schema: FieldSchema<Row>,\n q: { select: SelectColumn[] },\n): FieldDef<Row>[] {\n const order =\n q.select.length > 0\n ? q.select.map((c) => c.field)\n : (schema.defaultSelect ?? schema.fields.filter((f) => f.select?.default).map((f) => ({ field: f.name }))).map(\n (c) => c.field,\n );\n const seen = new Set<string>();\n const out: FieldDef<Row>[] = [];\n for (const name of order) {\n if (seen.has(name)) continue;\n const f = resolveField(schema, name);\n if (!f || !isSelectable(f)) continue;\n seen.add(name);\n seen.add(f.name);\n out.push(f);\n }\n return out;\n}\n\n/** Resolve a field token to a concrete field by canonical name, case-insensitive\n * name match, or alias match. */\nexport function resolveField<Row>(schema: FieldSchema<Row>, field: string): FieldDef<Row> | undefined {\n const token = field.trim();\n if (!token) return undefined;\n\n const byName = indexFields(schema);\n const byExactName = byName.get(token);\n if (byExactName) return byExactName;\n\n const needle = token.toLowerCase();\n for (const f of schema.fields) {\n if (f.name.toLowerCase() === needle) return f;\n if (aliasMatches(f, needle)) return f;\n }\n return undefined;\n}\n\n/** Return the canonical name for a query token, or undefined when unresolved. */\nexport function resolveFieldName<Row>(schema: FieldSchema<Row>, field: string): string | undefined {\n return resolveField(schema, field)?.name;\n}\n\n/** All configured aliases for a field (deduped, preserving display shape). */\nexport function aliasTermsFor<Row>(field: FieldDef<Row>): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(value);\n };\n\n add(field.alias);\n if (field.aliases) {\n for (const alias of field.aliases) add(alias);\n }\n\n return out;\n}\n\nfunction aliasMatches(field: FieldDef, needle: string): boolean {\n for (const alias of aliasTermsFor(field)) {\n if (alias.toLowerCase() === needle) return true;\n }\n return false;\n}\n\n/** Read a field's value from a row: derived `accessor` if present, else the\n * backend `path` (dotted) / `name`. Returns null when any path segment is missing. */\nexport function readFieldValue<Row, V = unknown>(field: FieldDef<Row, V>, row: Row): V | null {\n if (row == null) return null;\n if (field.source.kind === \"derived\" && field.source.accessor) {\n return field.source.accessor(row);\n }\n const path = (field.source.kind === \"backend\" && field.source.path) || field.name;\n const r = row as Record<string, unknown>;\n if (path in r) return (r[path] ?? null) as V | null;\n let cur: unknown = row;\n for (const part of path.split(\".\")) {\n if (cur == null || typeof cur !== \"object\") return null;\n cur = (cur as Record<string, unknown>)[part];\n }\n return (cur ?? null) as V | null;\n}\n\n/** Parse + validate a raw JSON schema document into a FieldSchema. The doc is the\n * same one the Go backend loads; here we drop backend `bindings` (the frontend\n * never sees SQL) and leave `render` as a string key the consumer maps to a\n * renderer at runtime. Throws with a readable message on a malformed document. */\nexport function loadSchema<Row = any>(doc: unknown): FieldSchema<Row> {\n const d = doc as Record<string, any>;\n if (!d || typeof d !== \"object\") throw new Error(\"schema: document is not an object\");\n if (typeof d.name !== \"string\") throw new Error(\"schema: missing `name`\");\n if (typeof d.idField !== \"string\") throw new Error(\"schema: missing `idField`\");\n if (!Array.isArray(d.fields) || d.fields.length === 0) throw new Error(\"schema: `fields` must be a non-empty array\");\n\n const fields: FieldDef<Row>[] = d.fields.map((raw: any, i: number) => projectField<Row>(raw, i));\n return {\n name: d.name,\n idField: d.idField,\n fields,\n defaultSort: d.defaultSort,\n defaultSelect: d.defaultSelect,\n defaultLimit: d.defaultLimit,\n };\n}\n\nfunction projectField<Row>(raw: any, i: number): FieldDef<Row> {\n if (!raw || typeof raw.name !== \"string\") throw new Error(`schema: field[${i}] missing \\`name\\``);\n if (typeof raw.label !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`label\\``);\n if (typeof raw.type !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`type\\``);\n\n // `source` accepts a string shorthand (\"backend\"|\"derived\") or an object.\n const rs = raw.source ?? (raw.bindings ? \"backend\" : \"derived\");\n let source: FieldSource<Row>;\n if (typeof rs === \"string\") {\n source = rs === \"derived\" ? { kind: \"derived\" } : { kind: \"backend\" };\n } else if (rs.kind === \"derived\") {\n source = { kind: \"derived\" }; // accessor is code → attached at runtime, never from JSON\n } else {\n source = { kind: \"backend\", path: rs.path, synthetic: rs.synthetic };\n }\n\n return {\n name: raw.name,\n label: raw.label,\n type: raw.type,\n source,\n filter: raw.filter,\n sort: raw.sort,\n select: raw.select,\n aggregate: raw.aggregate,\n group: raw.group,\n alias: raw.alias,\n aliases: normalizeAliases(raw.aliases, raw.alias),\n render: raw.render, // string key from JSON; consumer may override with a fn\n };\n}\n\nfunction normalizeAliases(rawAliases: unknown, rawAlias: unknown): string[] {\n const aliases: string[] = [];\n const seen = new Set<string>();\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n aliases.push(value);\n };\n\n add(rawAlias);\n if (Array.isArray(rawAliases)) {\n for (const item of rawAliases) add(item);\n }\n return aliases;\n}\n","// ops.ts — which operators a field type allows, and value coercion.\n//\n// Single source of truth for \"what filters can I build on this field\", shared by\n// the QueryBuilder UI, the CellMenu quick-filters, and client-side applyQuery.\n// The backend (backends/go) enforces the same matrix independently — never trust\n// the client.\n//\n// Every value can be NULL, so `is_null`/`is_not_null` are available on EVERY\n// type, including bool (design feedback).\n\nimport type { FilterOp, FieldType, FieldDef, WhereClause } from \"./index\";\n\nconst NULLITY: FilterOp[] = [\"is_null\", \"is_not_null\"];\n\n/** Operators that are each other's logical complement. Negating one of these is\n * a clean op flip (no NULL surprises the two ops don't already share), so the\n * UI can render `≥ 10`'s negation as `< 10` rather than `NOT (≥ 10)`. Ops absent\n * here (`contains`/`starts_with`/`ends_with`/`includes`) have no single-op\n * complement and negate via the `WhereClause.negated` flag instead. */\nconst COMPLEMENT_OP: Partial<Record<FilterOp, FilterOp>> = {\n \"=\": \"!=\",\n \"!=\": \"=\",\n \">\": \"<=\",\n \"<=\": \">\",\n \">=\": \"<\",\n \"<\": \">=\",\n is_null: \"is_not_null\",\n is_not_null: \"is_null\",\n matches_regex: \"not_matches_regex\",\n not_matches_regex: \"matches_regex\",\n};\n\n/** The logical negation of a predicate. Prefers flipping to the complementary\n * operator (nicer to read, and the server's op allowlist already covers it);\n * falls back to toggling the `negated` flag when the op has no complement, or\n * when the complement is not in `allowedOps` (a field's `filter.ops` override\n * could disable it, and the server would reject a disabled op). `allowedOps`,\n * when given, is the field's effective operator set from `opsForField`. */\nexport function negateClause(clause: WhereClause, allowedOps?: readonly FilterOp[]): WhereClause {\n if (clause.value === \"0\" && !clause.negated) {\n const zeroComplement = clause.op === \"length_gt\" ? \"length_eq\" : clause.op === \"length_eq\" ? \"length_gt\" : null;\n if (zeroComplement && (!allowedOps || allowedOps.includes(zeroComplement))) {\n return { field: clause.field, op: zeroComplement, value: \"0\" };\n }\n }\n const complement = COMPLEMENT_OP[clause.op];\n if (complement && (!allowedOps || allowedOps.includes(complement))) {\n const next: WhereClause = { field: clause.field, op: complement, value: clause.value };\n return next; // a complement fully expresses the negation; drop any stale flag\n }\n const next: WhereClause = { field: clause.field, op: clause.op, value: clause.value };\n if (!clause.negated) next.negated = true;\n return next;\n}\n\n/** Whether a predicate is negative — either an op that reads as a negation\n * (`!=`, `not_matches_regex`, `is_not_null`) or one carrying the `negated`\n * flag. Used to sort candidate filters into the CellMenu's two columns. */\nexport function isNegativePredicate(clause: Pick<WhereClause, \"op\" | \"negated\">): boolean {\n return Boolean(clause.negated) || clause.op === \"!=\" || clause.op === \"not_matches_regex\" || clause.op === \"is_not_null\";\n}\n\n/** A specific operator + negation state, e.g. `{ op: \"<\", negated: false }` or\n * `{ op: \"contains\", negated: true }`. */\nexport interface OpChoice {\n op: FilterOp;\n negated: boolean;\n}\n\n/** A positive operator (\"keep\") and its logical negation (\"exclude\") — the row\n * shape rendered by both the CellMenu quick-filters and the WHERE operator\n * picker, so the two read identically. */\nexport interface OpPair {\n keep: OpChoice;\n exclude: OpChoice;\n}\n\n/** Positive operators surfaced in the \"keep\" column, in display order. Each\n * one's negation lands opposite via `negateClause`, so the pair covers\n * `<`/`<=`/`!=`/`not_matches_regex` without listing them separately. */\nconst POSITIVE_OP_ORDER: FilterOp[] = [\"=\", \">\", \">=\", \"contains\", \"starts_with\", \"ends_with\", \"length_gt\", \"length_lt\", \"length_eq\", \"matches_regex\", \"includes\"];\n\n/** The keep/exclude operator pairs offered for a field: each positive op with\n * its negation opposite, then a nullity row (`is null`/`is not null`) when the\n * field allows it. Derived from the field's effective op set and `negateClause`,\n * so a `filter.ops` override narrows the offered pairs too. */\nexport function opPairsForField(field: Pick<FieldDef, \"type\" | \"filter\">): OpPair[] {\n const ops = opsForField(field);\n const allow = new Set(ops);\n const pairs: OpPair[] = [];\n for (const op of POSITIVE_OP_ORDER) {\n if (!allow.has(op)) continue;\n const neg = negateClause({ field: \"\", op, value: \"\" }, ops);\n pairs.push({ keep: { op, negated: false }, exclude: { op: neg.op, negated: Boolean(neg.negated) } });\n }\n if (allow.has(\"is_null\") || allow.has(\"is_not_null\")) {\n pairs.push({ keep: { op: \"is_null\", negated: false }, exclude: { op: \"is_not_null\", negated: false } });\n }\n return pairs;\n}\n\n/** Default operator set per type. A FieldDef.filter.ops overrides this. */\nexport const OPS_BY_TYPE: Record<FieldType, FilterOp[]> = {\n text: [\n \"=\",\n \"!=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n ...NULLITY,\n ],\n enum: [\"=\", \"!=\", ...NULLITY],\n number: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n datetime: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n bool: [\"=\", \"!=\", ...NULLITY],\n textarray: [\"includes\", ...NULLITY],\n};\n\n/** Operators that take no value (the value input is hidden). */\nexport const NULLARY_OPS: ReadonlySet<FilterOp> = new Set<FilterOp>(NULLITY);\n\n/** Effective operators for a field (its override, else the type default). */\nexport function opsForField(field: Pick<FieldDef, \"type\" | \"filter\">): FilterOp[] {\n return field.filter?.ops ?? OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (server mirror lives\n * in Go opAllowed; keep them in lockstep). */\nexport function opAllowedForType(type: FieldType, op: FilterOp): boolean {\n return OPS_BY_TYPE[type].includes(op);\n}\n\n/** Coerce a raw string value to the type the field expects, for client-side\n * comparison. Throws on invalid input (e.g. a non-numeric value on a number\n * field) so callers can surface it rather than silently mis-filtering. */\nexport function coerceValue(type: FieldType, raw: string): string | number | boolean {\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n if (raw.trim() === \"\" || Number.isNaN(n)) throw new Error(`not a number: ${JSON.stringify(raw)}`);\n return n;\n }\n case \"bool\": {\n const v = raw.toLowerCase();\n if (v === \"true\" || v === \"1\" || v === \"t\") return true;\n if (v === \"false\" || v === \"0\" || v === \"f\") return false;\n throw new Error(`not a bool: ${JSON.stringify(raw)}`);\n }\n case \"datetime\": {\n const ms = Date.parse(raw);\n if (Number.isNaN(ms)) throw new Error(`not a datetime: ${JSON.stringify(raw)}`);\n return ms;\n }\n default:\n return raw;\n }\n}\n","// agg.ts — which aggregate ops a field type allows, and which fields can be a\n// measure or a group-by key. The single source of truth shared by the\n// QueryBuilder's metric editor, the client-side applyAggregations, and (mirrored\n// independently in backends/go) the SQL compiler. Never trust the client: the Go\n// `aggOpAllowed` enforces the same matrix before any GROUP BY is built.\n\nimport type { AggOp } from \"./query\";\nimport type { FieldType, FieldDef } from \"./schema\";\n\n/** Default aggregate ops per field type. A FieldDef.aggregate.ops overrides this.\n * `count`/`count_distinct` work on anything countable; sum/avg are numeric-only;\n * min/max need an ordered domain (numbers, datetimes, and lexical text/enum). */\nexport const AGG_OPS_BY_TYPE: Record<FieldType, AggOp[]> = {\n number: [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"],\n datetime: [\"count\", \"count_distinct\", \"min\", \"max\"],\n enum: [\"count\", \"count_distinct\", \"min\", \"max\"],\n text: [\"count\", \"count_distinct\", \"min\", \"max\"],\n bool: [\"count\", \"count_distinct\"],\n textarray: [\"count\"],\n};\n\n/** Ops that reduce a measure column. `count` is the only op that may omit a\n * field (counting rows), so it's the only one absent here. */\nexport const AGG_OPS_NEEDING_FIELD: ReadonlySet<AggOp> = new Set<AggOp>([\n \"count_distinct\",\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n]);\n\n/** Whether an op requires a measure column. */\nexport function aggOpNeedsField(op: AggOp): boolean {\n return AGG_OPS_NEEDING_FIELD.has(op);\n}\n\n/** Effective aggregate ops for a field (its override, else the type default). */\nexport function aggOpsForField(field: Pick<FieldDef, \"type\" | \"aggregate\">): AggOp[] {\n return field.aggregate?.ops ?? AGG_OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (Go aggOpAllowed is\n * the server mirror; keep them in lockstep). */\nexport function aggOpAllowedForType(type: FieldType, op: AggOp): boolean {\n return AGG_OPS_BY_TYPE[type].includes(op);\n}\n\n/** Can this field be the MEASURE of a metric? Only backend fields (they have SQL\n * to aggregate); derived/render-only columns are never pushed to the server. An\n * explicit `aggregate.measure` wins over the type default. */\nexport function isMeasurable(field: FieldDef): boolean {\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.measure != null) return field.aggregate.measure;\n return aggOpsForField(field).length > 0;\n}\n\n/** Can this field be a GROUP BY key? Backend fields only. Default: low-cardinality\n * types (enum/text/bool); numbers/datetimes need bucketing (out of scope) so they\n * default off, but `aggregate.groupable: true` opts any backend field in. */\nexport function isGroupable(field: FieldDef): boolean {\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.groupable != null) return field.aggregate.groupable;\n return field.type === \"enum\" || field.type === \"text\" || field.type === \"bool\";\n}\n","import { isOrGroup, predicatesOf, type SetFilterMetadata, type SetFilterMode, type WhereTerm } from \"./query\";\n\n/** Compile an explicitly identified editor into existing CNF predicates. */\nexport function createSetFilter(field: string, mode: SetFilterMode, values: string[], id: string): WhereTerm[] {\n const keys = [...new Set(values)];\n if (mode !== \"empty\" && keys.length === 0) return [];\n const includes = keys.map((value) => ({ field, op: \"includes\" as const, value }));\n let terms: WhereTerm[];\n if (mode === \"empty\") terms = [{ field, op: \"is_null\", value: \"\" }];\n else if (mode === \"any\") terms = includes.length === 1 ? includes : [{ any: includes }];\n else if (mode === \"all\") terms = includes;\n else terms = includes.map((clause) => ({ any: [{ field, op: \"is_null\", value: \"\" }, { ...clause, negated: true }] }));\n return terms.map((term) => ({ ...term, setFilter: { id, mode, values: mode === \"empty\" ? [] : [...keys] } }));\n}\n\n/** Remove presentation metadata at transport boundaries, including inner literals. */\nexport function stripSetFilter(term: WhereTerm): WhereTerm {\n const strip = ({ setFilter: _metadata, ...clause }: ReturnType<typeof predicatesOf>[number]) => clause;\n return isOrGroup(term) ? { any: term.any.map(strip) } : strip(term);\n}\n\n/** Only collapse explicitly marked, intact editor output. Never infer from predicates. */\nexport function readSetFilter(where: WhereTerm[], index: number): { field: string; metadata: SetFilterMetadata; count: number } | null {\n const term = where[index];\n const metadata = term?.setFilter;\n if (!term || !metadata || where[index - 1]?.setFilter?.id === metadata.id) return null;\n const field = predicatesOf(term)[0]?.field;\n if (!field) return null;\n const expected = createSetFilter(field, metadata.mode, metadata.values, metadata.id);\n if (expected.length === 0) return null;\n for (let offset = 0; offset < expected.length; offset++) {\n const actual = where[index + offset];\n if (!actual || JSON.stringify(actual.setFilter) !== JSON.stringify(expected[offset]!.setFilter) || JSON.stringify(stripSetFilter(actual)) !== JSON.stringify(stripSetFilter(expected[offset]!))) return null;\n }\n if (where[index + expected.length]?.setFilter?.id === metadata.id) return null;\n return { field, metadata, count: expected.length };\n}\n\n/** Canonicalize consumer-owned value aliases without disconnecting editor metadata. */\nexport function mapSetFilterValues(where: WhereTerm[], canonicalize: (field: string, value: string) => string): WhereTerm[] {\n const result: WhereTerm[] = [];\n for (let index = 0; index < where.length; index++) {\n const set = readSetFilter(where, index);\n if (!set) { result.push(where[index]!); continue; }\n result.push(...createSetFilter(set.field, set.metadata.mode, set.metadata.values.map((value) => canonicalize(set.field, value)), set.metadata.id));\n index += set.count - 1;\n }\n return result;\n}\n","// encode.ts — URL serialization + the server-bound query subset.\n//\n// Two distinct serializations, deliberately kept apart:\n//\n// 1. encodeQuery / decodeQuery — the *whole* QueryState (incl. view state:\n// select columns + widths) ⇄ a base64url `?q=` token. This is what makes\n// reload, back/forward, bookmarks, and \"send a coworker your view\" all work\n// (decisions #4 + #5). Defaults are omitted to keep the token short.\n//\n// 2. toServerQuery — the subset the backend acts on: pushdown\n// WHERE clauses, server-sortable ORDER BY (remapped through sort.field), the\n// page window, and the field names to SELECT (so the backend evaluates the\n// computed/synthetic columns the view needs — requested ∪ always-needed,\n// design decision #2). Per-column widths never leave the client.\n//\n// Back-compat: decodeQuery accepts legacy compact shapes: `o` as a single\n// object (pre-multi-sort) and `c`/`s` as a string[] (pre-width).\n\nimport { EMPTY_QUERY, MAX_QUERY_TOKEN_LENGTH, normalizeQueryState, predicatesOf } from \"./query\";\nimport { stripSetFilter } from \"./setFilter\";\nimport type { QueryState, WhereTerm, OrderByClause, SelectColumn, AggregationClause } from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport { indexFields, isFilterable, isPushdownFilter, isSortable, resolveFieldName, selectedFields } from \"./schema\";\n\n// ---- base64url (browser + node) -------------------------------------------\n\nfunction toBase64Url(json: string): string {\n let b64: string;\n if (typeof Buffer !== \"undefined\") {\n b64 = Buffer.from(json, \"utf8\").toString(\"base64\");\n } else {\n const bytes = new TextEncoder().encode(json);\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n b64 = btoa(bin);\n }\n return b64.replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction fromBase64Url(s: string): string {\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4);\n if (typeof Buffer !== \"undefined\") return Buffer.from(b64, \"base64\").toString(\"utf8\");\n const bin = atob(b64);\n const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n// ---- compact wire form ----------------------------------------------------\n// Keys are short to keep `?q=` small; any field at its default is omitted.\n// s = select (as [field] or [field, width] tuples)\n// w = where, o = orderBy, l = limit, f = offset\n\ninterface CompactQuery {\n s?: Array<[string] | [string, number]> | string[]; // string[] = legacy\n w?: WhereTerm[];\n o?: OrderByClause[] | OrderByClause; // object accepted for legacy decode\n l?: number;\n f?: number;\n g?: AggregationClause[]; // aggregation metrics (omitted when none)\n c?: string[]; // legacy alias for select column names\n}\n\n/** QueryState → base64url token (omitting defaults). All-default query → \"\". */\nexport function encodeQuery(q: QueryState): string {\n q = normalizeQueryState(q);\n const c: CompactQuery = {};\n if (q.select.length)\n c.s = q.select.map((col): [string] | [string, number] => (col.width != null ? [col.field, col.width] : [col.field]));\n if (q.where.length) c.w = q.where;\n if (q.orderBy.length) c.o = q.orderBy;\n c.l = q.limit;\n if (q.offset) c.f = q.offset;\n if (q.aggregations?.length) c.g = q.aggregations;\n if (Object.keys(c).length === 0) return \"\";\n return toBase64Url(JSON.stringify(c));\n}\n\n/** base64url token → QueryState. Tolerant: bad input and legacy shapes both\n * normalize to a valid QueryState (never throws). */\nexport function decodeQuery(token: string): QueryState {\n if (!token) return { ...EMPTY_QUERY };\n if (token.length > MAX_QUERY_TOKEN_LENGTH) return { ...EMPTY_QUERY };\n try {\n const c = JSON.parse(fromBase64Url(token)) as CompactQuery;\n const out = normalizeQueryState({\n select: normalizeSelect(c.s ?? c.c),\n where: Array.isArray(c.w) ? c.w : [],\n orderBy: normalizeOrderBy(c.o),\n limit: c.l,\n offset: c.f,\n aggregations: c.g,\n });\n return out;\n } catch {\n return { ...EMPTY_QUERY };\n }\n}\n\nfunction normalizeSelect(s: CompactQuery[\"s\"] | CompactQuery[\"c\"]): SelectColumn[] {\n if (!Array.isArray(s)) return [];\n return s\n .map((item): SelectColumn | null => {\n if (typeof item === \"string\") return { field: item }; // legacy string[]\n if (Array.isArray(item) && typeof item[0] === \"string\") {\n return typeof item[1] === \"number\" ? { field: item[0], width: item[1] } : { field: item[0] };\n }\n return null;\n })\n .filter((x): x is SelectColumn => x != null);\n}\n\nfunction normalizeOrderBy(o: CompactQuery[\"o\"]): OrderByClause[] {\n if (!o) return [];\n if (Array.isArray(o)) return o;\n return [o]; // legacy single-object form → one-element array\n}\n\n// ---- server-bound subset --------------------------------------------------\n\n/** The backend request derived from a QueryState + its schema. Mirrors the Go\n * `WireQuery`. View-only state (column widths) is intentionally absent. */\nexport interface ServerQuery {\n /** field names to return — visible columns ∪ fields referenced by where/orderBy. */\n select: string[];\n /** only terms whose every predicate is on a pushdown-filterable field. */\n where: WhereTerm[];\n /** only terms on server-sortable fields, with `field` already remapped to the\n * field's server sort key (FieldDef.sort.field) when set. */\n orderBy: OrderByClause[];\n limit: number;\n offset: number;\n}\n\n/** Project a QueryState into the server request, dropping client-only filters,\n * client-only sorts, and remapping sort fields through `sort.field`. */\nexport function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): ServerQuery {\n q = normalizeQueryState(q);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const orderBy: OrderByClause[] = [];\n for (const term of q.orderBy) {\n const field = resolveField(term.field);\n const f = byName.get(field);\n if (!f || !isSortable(f) || f.source.kind !== \"backend\") continue;\n orderBy.push({ ...term, field: f.sort?.field ?? f.name });\n }\n\n // SELECT = the BACKEND columns the response rows must carry: visible backend\n // columns, the id (for selection/refresh), and any backend column a\n // CLIENT-SIDE filter reads. Derived/render-only columns are computed on the\n // client and have no SQL to select; pushdown filters/sorts run in SQL and need\n // not be returned (design decision #2: requested ∪ always-needed).\n const select = new Set<string>(\n selectedFields(schema, q)\n .filter((f) => f.source.kind === \"backend\")\n .map((f) => f.name),\n );\n for (const field of selectedFields(schema, q)) {\n if (field.source.kind === \"derived\") {\n for (const name of field.source.dependencies ?? []) {\n if (byName.get(name)?.source.kind === \"backend\") select.add(name);\n }\n }\n }\n select.add(schema.idField);\n for (const term of q.where) {\n for (const cl of predicatesOf(term)) {\n const field = resolveField(cl.field);\n const f = byName.get(field);\n if (f && isFilterable(f) && !isPushdownFilter(f) && f.source.kind === \"backend\") select.add(field);\n }\n }\n\n return { select: [...select].sort(), where, orderBy, limit: q.limit, offset: q.offset };\n}\n\n/** A term can push down only if EVERY predicate it contains is on a\n * pushdown-filterable field. An OR group is all-or-nothing: dropping one\n * disjunct would change the set the group matches, so a group with any\n * non-pushdown member stays client-side in full. */\nfunction termIsPushdown<Row>(\n term: WhereTerm,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (name: string) => string,\n): boolean {\n return predicatesOf(term).every((cl) => {\n const f = byName.get(resolveField(cl.field));\n return f != null && isPushdownFilter(f);\n });\n}\n\n// ---- aggregation server subset --------------------------------------------\n\n/** The backend request for the metric panel. Scope is the whole filtered set:\n * the SAME pushdown WHERE as the rows query, but NO ORDER BY / LIMIT / OFFSET —\n * metrics describe every matching row, not the visible page. Mirrors the Go\n * AggSpec list. */\nexport interface AggregationRequest {\n where: WhereTerm[];\n aggregations: AggregationClause[];\n}\n\n/** One group's result. `keys` has one entry per AggregationClause.groupBy field,\n * in axis order (`[]` for a grand total); a null key is the NULL/empty bucket. */\nexport interface AggregationBucket {\n keys: (string | null)[];\n /** The metric: a number for count/sum/avg, or the column's value for min/max\n * (which may be a string for text/datetime). null when undefined (e.g. avg of\n * an all-null column). */\n value: number | string | null;\n /** COUNT(*) of rows in the group — always present, even when `value` isn't a\n * count, so the panel can show group sizes / shares. */\n count: number;\n}\n\nexport interface AggregationResultEntry {\n /** Echoes AggregationClause.id. */\n id: string;\n buckets: AggregationBucket[];\n}\n\nexport interface AggregationResult {\n /** One entry per requested aggregation, in request order. */\n metrics: AggregationResultEntry[];\n}\n\n/** Project a QueryState into the metric request: the pushdown WHERE subset (same\n * rule as toServerQuery) plus the aggregations whose measure + group fields are\n * all server-capable backend columns. Aggregations referencing a derived /\n * unknown field are dropped — the server has no SQL for them. */\nexport function toAggregationQuery<Row>(q: QueryState, schema: FieldSchema<Row>): AggregationRequest {\n q = normalizeQueryState(q);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const isBackend = (name: string | undefined): boolean => {\n if (name == null) return true; // omitted measure (count(*)) is fine\n const field = resolveField(name);\n const f = byName.get(field);\n return f != null && f.source.kind === \"backend\";\n };\n\n const aggregations = (q.aggregations ?? []).filter(\n (a) => isBackend(a.field) && a.groupBy.every((g) => isBackend(g)),\n );\n\n return { where, aggregations };\n}\n","// apply.ts — client-side filter + multi-sort + paginate.\n//\n// applyQuery is the client mirror of the backend compiler. Three jobs:\n// 1. The executor for purely client-side datasets (no backend at all).\n// 2. The executor for derived / non-pushdown columns the backend can't filter.\n// 3. Idempotent defense-in-depth over server-filtered fields (re-applying a\n// server-handled clause must not change the result).\n//\n// It must agree with backends/go's Compile on operator semantics:\n// - `contains`/`starts_with`/`ends_with` are case-insensitive\n// - textarray `is_null` = empty-or-missing; `is_not_null` = any element;\n// `includes` = case-insensitive membership\n// - NULLs sort per OrderByClause.nulls (default \"last\")\n// - multi-sort is a stable lexicographic fold over orderBy in priority order\n\nimport { isComputedField } from \"./computed\";\nimport type { AggOp, AggregationClause, QueryState, WhereClause, WhereTerm } from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { AggregationBucket, AggregationResult } from \"./encode\";\nimport { indexFields, readFieldValue, resolveFieldName } from \"./schema\";\nimport { isOrGroup, predicatesOf } from \"./query\";\nimport { coerceValue } from \"./ops\";\n\nexport interface ApplyResult<Row> {\n /** The page slice (after filter + sort + offset/limit). */\n rows: Row[];\n /** Total matching rows *before* pagination — powers \"showing N of M\". */\n total: number;\n}\n\n/** Filter + multi-sort + paginate `rows` per `q`, resolving field types/paths\n * from `schema`. Pure; never mutates `rows`. Clauses/sorts on unknown fields are\n * ignored (the backend already enforced its own allowlist). */\nexport function applyQuery<Row>(rows: Row[], q: QueryState, schema: FieldSchema<Row>): ApplyResult<Row> {\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n // Terms touching a computed column are dropped here (the formula engine\n // evaluates those separately; `byName` has no opinion on them anyway). An OR\n // group is all-or-nothing, so a single computed member drops the whole term.\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field)))\n .map((term) => prepareWhereTerm(term, resolveField));\n const orderBy = q.orderBy\n .filter((term) => !isComputedField(term.field))\n .map((term) => ({ ...term, field: resolveField(term.field) }));\n\n let out = rows.filter((row) => whereTerms.every((term) => matchesTerm(byName, row, term)));\n const total = out.length;\n\n if (orderBy.length) {\n const terms = orderBy\n .map((t) => ({\n field: byName.get(t.field),\n dir: t.dir,\n nullsLast: (t.nulls ?? \"last\") === \"last\",\n extract: compileRegex(t.extract?.regex),\n }))\n .filter(\n (t): t is { field: FieldDef<Row>; dir: \"asc\" | \"desc\"; nullsLast: boolean; extract: RegExp | null | undefined } =>\n t.field != null,\n );\n out = [...out].sort((a, b) => {\n for (const t of terms) {\n const av = extractSortValue(readFieldValue(t.field, a), t.extract);\n const bv = extractSortValue(readFieldValue(t.field, b), t.extract);\n const aNull = av == null;\n const bNull = bv == null;\n if (aNull || bNull) {\n if (aNull && bNull) continue;\n return (aNull ? 1 : -1) * (t.nullsLast ? 1 : -1);\n }\n const cmp = compare(av, bv);\n if (cmp !== 0) return t.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const start = q.offset > 0 ? q.offset : 0;\n const end = q.limit > 0 ? start + q.limit : out.length;\n return { rows: out.slice(start, end), total };\n}\n\n/** Does one row satisfy one clause? Exposed for the CellMenu preview + tests. */\nexport function matchesClause<Row>(row: Row, clause: WhereClause, schema: FieldSchema<Row>): boolean {\n return matchesWith(indexFields(schema), row, prepareWhereClause(clause));\n}\n\n/** Client-side mirror of the backend GROUP BY (the executor for `clientRows`\n * mode / the demo). Scope matches the server contract: the WHERE-filtered set\n * only — ORDER BY / LIMIT / OFFSET are intentionally ignored, so a metric\n * reflects every matching row, not the visible page. Must agree with\n * backends/go's aggregate compile on op semantics. */\nexport function applyAggregations<Row>(rows: Row[], q: QueryState, schema: FieldSchema<Row>): AggregationResult {\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field)))\n .map((term) => prepareWhereTerm(term, resolveField));\n const filtered = rows.filter((row) => whereTerms.every((term) => matchesTerm(byName, row, term)));\n const metrics = (q.aggregations ?? [])\n .filter((a) => !isComputedField(a.field ?? \"\") && !a.groupBy.some(isComputedField))\n .map((agg) => ({\n id: agg.id,\n buckets: computeBuckets(filtered, agg, byName, resolveField),\n }));\n return { metrics };\n}\n\nfunction computeBuckets<Row>(\n rows: Row[],\n agg: AggregationClause,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (field: string) => string,\n): AggregationBucket[] {\n // One slot per groupBy entry, preserving position. An unresolved field stays\n // in the array as `undefined` so every bucket's `keys` has exactly one element\n // per requested group field — the panel renders keys positionally against\n // `clause.groupBy`, so dropping an entry here would shift every later column.\n const groupFields = agg.groupBy.map((n) => byName.get(resolveField(n)));\n const measure = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n\n const groups = new Map<string, { keys: (string | null)[]; rows: Row[] }>();\n for (const row of rows) {\n const keys = groupFields.map((f) => {\n if (!f) return null; // unresolved group field → NULL bucket, never a missing column\n const v = readFieldValue(f, row);\n return v == null || v === \"\" ? null : String(v);\n });\n const k = JSON.stringify(keys);\n let g = groups.get(k);\n if (!g) {\n g = { keys, rows: [] };\n groups.set(k, g);\n }\n g.rows.push(row);\n }\n\n const buckets = [...groups.values()].map((g) => ({\n keys: g.keys,\n count: g.rows.length,\n value: aggValue(agg.op, measure, g.rows),\n }));\n return sortBuckets(buckets);\n}\n\nfunction aggValue<Row>(op: AggOp, measure: FieldDef<Row> | undefined, rows: Row[]): number | string | null {\n if (op === \"count\") {\n if (!measure) return rows.length; // COUNT(*)\n let n = 0;\n for (const r of rows) if (readFieldValue(measure, r) != null) n++; // COUNT(expr) = non-null\n return n;\n }\n if (!measure) return null;\n const values = rows.map((r) => readFieldValue(measure, r)).filter((v) => v != null);\n\n switch (op) {\n case \"count_distinct\":\n return new Set(values.map((v) => String(v))).size;\n case \"sum\":\n case \"avg\": {\n let sum = 0;\n let n = 0;\n for (const v of values) {\n const num = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(num)) {\n sum += num;\n n++;\n }\n }\n if (op === \"avg\") return n ? sum / n : null;\n return n ? sum : null;\n }\n case \"min\":\n case \"max\": {\n let best: unknown;\n for (const v of values) {\n if (best === undefined) {\n best = v;\n continue;\n }\n const cmp = compare(v, best);\n if (op === \"min\" ? cmp < 0 : cmp > 0) best = v;\n }\n return (best as number | string | undefined) ?? null;\n }\n default:\n return null;\n }\n}\n\n/** Stable display order: descending by the metric (or group size when the metric\n * isn't numeric), then by group key. The 2D pivot ignores this; the 1D bar list\n * and the flat N-column table read top-to-bottom from it. */\nfunction sortBuckets(buckets: AggregationBucket[]): AggregationBucket[] {\n return [...buckets].sort((a, b) => {\n const av = typeof a.value === \"number\" ? a.value : a.count;\n const bv = typeof b.value === \"number\" ? b.value : b.count;\n if (av !== bv) return bv - av;\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n}\n\ninterface PreparedWhereClause {\n clause: WhereClause;\n regex: RegExp | null | undefined;\n}\n\ntype PreparedWhereTerm =\n | { kind: \"lit\"; predicate: PreparedWhereClause }\n | { kind: \"or\"; predicates: PreparedWhereClause[] };\n\nfunction prepareWhereClause(clause: WhereClause): PreparedWhereClause {\n const usesRegex = clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\";\n return { clause, regex: usesRegex ? compileRegex(clause.value) : undefined };\n}\n\nfunction prepareWhereTerm(term: WhereTerm, resolveField: (name: string) => string): PreparedWhereTerm {\n if (isOrGroup(term)) {\n return { kind: \"or\", predicates: term.any.map((c) => prepareWhereClause({ ...c, field: resolveField(c.field) })) };\n }\n return { kind: \"lit\", predicate: prepareWhereClause({ ...term, field: resolveField(term.field) }) };\n}\n\n/** A row satisfies the WHERE when every term matches (AND); a term matches when\n * its sole predicate matches, or — for an OR group — when any member does. */\nfunction matchesTerm<Row>(byName: Map<string, FieldDef<Row>>, row: Row, term: PreparedWhereTerm): boolean {\n if (term.kind === \"lit\") return matchesWith(byName, row, term.predicate);\n // Normalization never yields an empty group (0 dropped, 1 flattened), so\n // `some` over a non-empty list is the OR.\n return term.predicates.some((p) => matchesWith(byName, row, p));\n}\n\nfunction matchesWith<Row>(byName: Map<string, FieldDef<Row>>, row: Row, prepared: PreparedWhereClause): boolean {\n const { clause } = prepared;\n const field = byName.get(clause.field);\n if (!field) return true; // unknown field → no client opinion\n const v = readFieldValue(field, row);\n\n // Empty value on a non-equality, value-taking op is a \"no filter\" signal —\n // true for BOTH the predicate and its negation (matches the UI + the Go\n // compiler, which skip such clauses). Nullary ops legitimately use value \"\".\n if (\n clause.value === \"\" &&\n clause.op !== \"=\" &&\n clause.op !== \"!=\" &&\n clause.op !== \"is_null\" &&\n clause.op !== \"is_not_null\"\n ) {\n return true;\n }\n\n if (clause.op === \"length_gt\" || clause.op === \"length_lt\" || clause.op === \"length_eq\") {\n if (!/^(0|[1-9]\\d*)$/.test(clause.value) || !Number.isSafeInteger(Number(clause.value))) return false;\n }\n\n const base = matchesBase(field, v, prepared);\n if (!clause.negated) return base;\n // Null-exclusive NOT: a NULL/empty value satisfies neither the predicate nor\n // its negation (mirrors `not_matches_regex` and the server's trailing\n // `AND <expr> IS NOT NULL`).\n const isNull = Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n return !isNull && !base;\n}\n\n/** The bare predicate result, ignoring `negated` and the empty-value skip\n * (both handled by `matchesWith`). */\nfunction matchesBase<Row>(field: FieldDef<Row>, v: unknown, prepared: PreparedWhereClause): boolean {\n const { clause, regex } = prepared;\n\n // Nullity, with array-aware semantics.\n if (clause.op === \"is_null\") return Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n if (clause.op === \"is_not_null\") return Array.isArray(v) ? v.length > 0 : v != null && v !== \"\";\n\n const arrayText = (value: unknown) => field.filter?.arrayCaseSensitive\n ? String(value) : String(value).toLowerCase();\n\n // `includes` is array membership (ARRAY_HAS): a null/missing array contains\n // nothing. Handle before the array/scalar split so null can't fall through.\n if (clause.op === \"includes\") {\n const arr = Array.isArray(v) ? v : [];\n const needle = arrayText(clause.value);\n return arr.some((x) => arrayText(x) === needle);\n }\n\n if (clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\") {\n if (v == null || Array.isArray(v)) return false;\n if (!regex) return false;\n const matches = regex.test(String(v));\n return clause.op === \"matches_regex\" ? matches : !matches;\n }\n\n if (clause.op === \"length_gt\" || clause.op === \"length_lt\" || clause.op === \"length_eq\") {\n if (typeof v !== \"string\" || !/^(0|[1-9]\\d*)$/.test(clause.value)) return false;\n const limit = Number(clause.value);\n if (!Number.isSafeInteger(limit)) return false;\n const length = Array.from(v).length;\n return clause.op === \"length_gt\" ? length > limit : clause.op === \"length_lt\" ? length < limit : length === limit;\n }\n\n if (Array.isArray(v)) {\n const needle = arrayText(clause.value);\n const hay = v.map(arrayText);\n switch (clause.op) {\n case \"contains\":\n return hay.some((s) => s.includes(needle));\n case \"=\":\n return hay.includes(needle);\n case \"!=\":\n return !hay.includes(needle);\n default:\n return true;\n }\n }\n\n switch (clause.op) {\n case \"=\":\n return String(v ?? \"\") === String(coerceSafe(field, clause.value));\n case \"!=\":\n return String(v ?? \"\") !== String(coerceSafe(field, clause.value));\n case \">\":\n return compare(v, coerceSafe(field, clause.value)) > 0;\n case \">=\":\n return compare(v, coerceSafe(field, clause.value)) >= 0;\n case \"<\":\n return compare(v, coerceSafe(field, clause.value)) < 0;\n case \"<=\":\n return compare(v, coerceSafe(field, clause.value)) <= 0;\n case \"contains\":\n return String(v ?? \"\").toLowerCase().includes(clause.value.toLowerCase());\n case \"starts_with\":\n return String(v ?? \"\").toLowerCase().startsWith(clause.value.toLowerCase());\n case \"ends_with\":\n return String(v ?? \"\").toLowerCase().endsWith(clause.value.toLowerCase());\n default:\n return true;\n }\n}\n\n/** `null` means an invalid pattern; `undefined` means no regex was requested. */\nfunction compileRegex(pattern: string | undefined): RegExp | null | undefined {\n if (pattern === undefined) return undefined;\n try {\n return new RegExp(pattern);\n } catch {\n return null;\n }\n}\n\nfunction extractSortValue(value: unknown, regex: RegExp | null | undefined): unknown {\n if (regex === undefined) return value;\n if (regex === null || value == null) return null;\n const match = regex.exec(String(value));\n if (!match) return null;\n return match.length > 1 ? (match[1] ?? null) : match[0];\n}\n\n/** Coerce per the field type, falling back to the raw string if coercion fails\n * (so a malformed value degrades to a string compare rather than throwing). */\nfunction coerceSafe(field: FieldDef, raw: string): string | number | boolean {\n try {\n return coerceValue(field.type, raw);\n } catch {\n return raw;\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\") return a === b ? 0 : a ? 1 : -1;\n return String(a).localeCompare(String(b));\n}\n","// adapters.ts — the pluggable seams. Everything project-specific is injected\n// here so the package core stays generic.\n//\n// - Transport : how rows + filter-value suggestions are fetched.\n// - StorageAdapter: where saved/last queries live (in-memory by default in\n// the React hook; explicitly durable when callers opt in).\n\nimport { normalizeQueryState } from \"./query\";\nimport type { QueryState, RowId } from \"./query\";\nimport type { ServerQuery, AggregationRequest, AggregationResult } from \"./encode\";\n\n// ---- Transport ------------------------------------------------------------\n\nexport interface FetchRowsResult<Row> {\n rows: Row[];\n /** Total matching rows before pagination (for \"N of M\" + paging bounds). */\n total: number;\n}\n\n/** A keystroke-driven distinct-value lookup. Autocomplete is the DEFAULT value\n * source for every field (design feedback), so this is how the filter combobox\n * finds options. `search` is the user's current input; the backend returns the\n * best matches and whether it truncated (so the UI can prompt \"keep typing\"). */\nexport interface DistinctValuesQuery {\n field: string;\n /** Current substring/prefix the user has typed (empty = top values). */\n search: string;\n /** Max suggestions to return (default chosen by the adapter, ~50). */\n limit?: number;\n}\n\nexport interface DistinctValuesResult {\n values: string[];\n /** true when more matches exist than were returned — refine by typing. */\n hasMore: boolean;\n /** True if the selected field has at least one NULL in the source dataset.\n * False if that field is guaranteed non-null. Omitted when the backend does\n * not compute this metadata. */\n hasNull?: boolean;\n}\n\n/** Per-field metadata for the field picker. */\nexport interface FieldStats {\n distinct?: number;\n min?: string | number;\n max?: string | number;\n}\n\nexport interface Transport<Row = any> {\n /** Run a server query. The only required method — a purely client-side table\n * can omit a Transport entirely and rely on applyQuery over local rows. */\n fetchRows(query: ServerQuery, signal?: AbortSignal): Promise<FetchRowsResult<Row>>;\n\n /** Distinct values for filter autocomplete. Strongly recommended: without it,\n * fields fall back to freeform input. The backend should match `search`\n * server-side (e.g. ILIKE prefix) and cap at `limit` so large domains stay\n * fast and refine per keystroke. */\n fetchDistinctValues?(q: DistinctValuesQuery, signal?: AbortSignal): Promise<DistinctValuesResult>;\n\n /** Run the metric panel's GROUP BY queries (one per requested aggregation),\n * scoped to the WHERE-filtered set with no paging. Optional: without it, the\n * metric panel falls back to applyAggregations over local rows (client mode).\n * Implementations compile each AggSpec with backends/go CompileAggregation,\n * sharing the same WHERE as fetchRows. */\n fetchAggregations?(q: AggregationRequest, signal?: AbortSignal): Promise<AggregationResult>;\n\n /** Re-fetch a single row by id, for in-place updates without a full re-query\n * after a mutation. Optional. */\n fetchRow?(id: RowId, signal?: AbortSignal): Promise<Row | null>;\n\n /** Stats for the field picker. Optional. */\n fetchFieldStats?(fields: string[], signal?: AbortSignal): Promise<Record<string, FieldStats>>;\n}\n\n// ---- Saved queries --------------------------------------------------------\n\nexport interface SavedQuery {\n id: string;\n name: string;\n /** Epoch millis; injected by the caller so core stays deterministic/testable. */\n savedAt: number;\n query: QueryState;\n}\n\n/** Persistence for the \"last\" query (auto-restored) and named saved queries. All\n * methods are namespaced by `key` (the schema/dataset name) so multiple tables\n * on one origin don't collide. Async to allow backend implementations; the\n * browser adapters can still resolve synchronously. */\nexport interface StorageAdapter {\n loadLast(key: string): Promise<QueryState | null>;\n saveLast(key: string, query: QueryState): Promise<void>;\n\n listSaved(key: string): Promise<SavedQuery[]>;\n /** Load the saved query selected as the default view for this key. Optional so\n * existing backend adapters keep working until they add first-class support. */\n loadDefaultSaved?(key: string): Promise<SavedQuery | null>;\n /** Set or clear the saved query used as the default view for this key. */\n setDefaultSaved?(key: string, id: string | null): Promise<void>;\n /** Persist a named query snapshot. Rejects when a saved query with the same\n * name already exists in the key namespace. */\n saveNamed(key: string, name: string, query: QueryState, savedAt: number): Promise<SavedQuery>;\n deleteSaved(key: string, id: string): Promise<void>;\n}\n\nconst LAST_PREFIX = \"query-table:last:\";\nconst SAVED_PREFIX = \"query-table:saved:\";\nconst DEFAULT_PREFIX = \"query-table:default:\";\nconst MAX_SAVED_QUERIES = 100;\nconst MAX_SAVED_NAME_LENGTH = 200;\n\nfunction normalizeSavedQuery(value: unknown): SavedQuery | null {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) return null;\n const raw = value as Record<string, unknown>;\n if (\n typeof raw.id !== \"string\" ||\n !raw.id ||\n raw.id.length > 256 ||\n typeof raw.name !== \"string\" ||\n !raw.name ||\n raw.name.length > MAX_SAVED_NAME_LENGTH ||\n typeof raw.savedAt !== \"number\" ||\n !Number.isFinite(raw.savedAt) ||\n raw.query == null ||\n typeof raw.query !== \"object\"\n ) {\n return null;\n }\n return { id: raw.id, name: raw.name, savedAt: raw.savedAt, query: normalizeQueryState(raw.query) };\n}\n\nfunction normalizeSavedQueries(value: unknown): SavedQuery[] {\n if (!Array.isArray(value)) return [];\n return value\n .slice(0, MAX_SAVED_QUERIES)\n .map(normalizeSavedQuery)\n .filter((item): item is SavedQuery => item != null);\n}\n\n/** In-memory persistence used by default by the React package. It supports the\n * full saved-query UI for the lifetime of a mounted table without writing\n * filter values to durable browser storage. */\nexport function memoryStorageAdapter(): StorageAdapter {\n const last = new Map<string, QueryState>();\n const saved = new Map<string, SavedQuery[]>();\n const defaults = new Map<string, string>();\n\n return {\n async loadLast(key) {\n const query = last.get(key);\n return query ? normalizeQueryState(query) : null;\n },\n async saveLast(key, query) {\n last.set(key, normalizeQueryState(query));\n },\n async listSaved(key) {\n return (saved.get(key) ?? []).map((item) => ({ ...item, query: normalizeQueryState(item.query) }));\n },\n async loadDefaultSaved(key) {\n const id = defaults.get(key);\n return id ? (saved.get(key) ?? []).find((item) => item.id === id) ?? null : null;\n },\n async setDefaultSaved(key, id) {\n if (id == null) {\n defaults.delete(key);\n return;\n }\n if (!(saved.get(key) ?? []).some((item) => item.id === id)) throw new Error(`Saved query \"${id}\" does not exist.`);\n defaults.set(key, id);\n },\n async saveNamed(key, name, query, savedAt) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = saved.get(key) ?? [];\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((item) => item.name === normalizedName)) throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n const item: SavedQuery = {\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n saved.set(key, [...items, item]);\n return item;\n },\n async deleteSaved(key, id) {\n saved.set(key, (saved.get(key) ?? []).filter((item) => item.id !== id));\n if (defaults.get(key) === id) defaults.delete(key);\n },\n };\n}\n\n/** Opt-in StorageAdapter over window.localStorage. Query state includes raw\n * filter values and is stored as cleartext JSON; do not use it for sensitive\n * datasets. Falls back to no persistence when storage is unavailable. */\nexport function localStorageAdapter(): StorageAdapter {\n const ls: Storage | null = (() => {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null; // access can throw in some sandboxes\n }\n })();\n\n const readSaved = (key: string): SavedQuery[] => {\n if (!ls) return [];\n try {\n const raw = ls.getItem(SAVED_PREFIX + key);\n return normalizeSavedQueries(raw ? JSON.parse(raw) : []);\n } catch {\n return [];\n }\n };\n const writeSaved = (key: string, items: SavedQuery[]): void => {\n if (ls) ls.setItem(SAVED_PREFIX + key, JSON.stringify(items));\n };\n const readDefaultId = (key: string): string | null => {\n if (!ls) return null;\n return ls.getItem(DEFAULT_PREFIX + key);\n };\n const writeDefaultId = (key: string, id: string | null): void => {\n if (!ls) return;\n if (id) ls.setItem(DEFAULT_PREFIX + key, id);\n else ls.removeItem(DEFAULT_PREFIX + key);\n };\n\n return {\n async loadLast(key) {\n if (!ls) return null;\n try {\n const raw = ls.getItem(LAST_PREFIX + key);\n return raw ? normalizeQueryState(JSON.parse(raw)) : null;\n } catch {\n return null;\n }\n },\n async saveLast(key, query) {\n if (ls) ls.setItem(LAST_PREFIX + key, JSON.stringify(normalizeQueryState(query)));\n },\n async listSaved(key) {\n return readSaved(key).sort((a, b) => b.savedAt - a.savedAt);\n },\n async loadDefaultSaved(key) {\n const id = readDefaultId(key);\n if (!id) return null;\n const found = readSaved(key).find((q) => q.id === id);\n if (!found) writeDefaultId(key, null);\n return found ?? null;\n },\n async setDefaultSaved(key, id) {\n if (id && !readSaved(key).some((q) => q.id === id)) {\n throw new Error(`Saved query \"${id}\" does not exist.`);\n }\n writeDefaultId(key, id);\n },\n async saveNamed(key, name, query, savedAt) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = readSaved(key);\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((q) => q.name === normalizedName)) {\n throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n }\n const item: SavedQuery = {\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n items.push(item);\n writeSaved(key, items);\n return item;\n },\n async deleteSaved(key, id) {\n writeSaved(\n key,\n readSaved(key).filter((q) => q.id !== id),\n );\n if (readDefaultId(key) === id) writeDefaultId(key, null);\n },\n };\n}\n","import type { FieldType } from \"./schema\";\n\nexport type FormulaType = Exclude<FieldType, \"enum\"> | \"null\";\nexport type FormulaValue = string | number | boolean | string[] | null;\nexport interface FormulaDiagnostic {\n message: string;\n from: number;\n to: number;\n}\nexport type FormulaNode =\n | { kind: \"literal\"; value: FormulaValue; from: number; to: number }\n | {\n kind: \"field\";\n name: string;\n valueType?: FormulaType;\n from: number;\n to: number;\n }\n | {\n kind: \"call\";\n name: string;\n args: FormulaNode[];\n from: number;\n to: number;\n };\nexport interface FormulaPlan {\n ast: FormulaNode;\n dependencies: string[];\n type: FormulaType;\n}\nexport interface RegexInspection {\n input: string;\n start: number;\n end: number;\n groups: (string | null)[];\n}\nexport interface FormulaResult {\n value: FormulaValue;\n error?: string;\n regex?: RegexInspection;\n}\nexport interface FormulaFunction {\n name: string;\n signature: string;\n description: string;\n min: number;\n max: number;\n result: FormulaType | \"branch\";\n args: FormulaType[] | \"any\";\n}\n\nconst f = (\n name: string,\n signature: string,\n description: string,\n min: number,\n max: number,\n result: FormulaFunction[\"result\"],\n args: FormulaFunction[\"args\"],\n): FormulaFunction => ({\n name,\n signature,\n description,\n min,\n max,\n result,\n args,\n});\nexport const FORMULA_FUNCTIONS: FormulaFunction[] = [\n ...[\"LEFT\", \"RIGHT\"].map((n) =>\n f(\n n,\n `${n}(text, count)`,\n \"Take Unicode code points from the end indicated.\",\n 2,\n 2,\n \"text\",\n [\"text\", \"number\"],\n ),\n ),\n f(\n \"SUBSTRING\",\n \"SUBSTRING(text, start, length)\",\n \"One-based start; length is optional.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"number\"],\n ),\n f(\"LENGTH\", \"LENGTH(text)\", \"Count Unicode code points.\", 1, 1, \"number\", [\n \"text\",\n ]),\n ...[\"LOWER\", \"UPPER\", \"TRIM\", \"LTRIM\", \"RTRIM\"].map((n) =>\n f(\n n,\n `${n}(text)`,\n \"Change case or remove surrounding whitespace.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ),\n f(\n \"REPLACE\",\n \"REPLACE(text, search, replacement)\",\n \"Replace all literal occurrences.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"text\"],\n ),\n ...[\"LPAD\", \"RPAD\"].map((n) =>\n f(\n n,\n `${n}(text, length, padding)`,\n \"Pad to a code-point length; default padding is a space.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"text\"],\n ),\n ),\n f(\n \"SPLIT_PART\",\n \"SPLIT_PART(text, separator, index)\",\n \"One-based part; missing part returns null.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"number\"],\n ),\n f(\n \"CONCAT\",\n \"CONCAT(text, ...)\",\n \"Combine text; null propagates.\",\n 1,\n 50,\n \"text\",\n [\"text\"],\n ),\n f(\n \"CONCAT_WS\",\n \"CONCAT_WS(separator, text, ...)\",\n \"Combine text, skipping null arguments.\",\n 2,\n 50,\n \"text\",\n [\"text\"],\n ),\n ...[\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].map((n) =>\n f(\n n,\n `${n}(text, search, ignoreCase)`,\n \"Case-sensitive unless the optional third argument is true.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"bool\"],\n ),\n ),\n f(\n \"REGEX_TEST\",\n \"REGEX_TEST(text, pattern, flags)\",\n \"Test a JavaScript Unicode regex; flags: i, m, s.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"text\"],\n ),\n f(\n \"REGEX_EXTRACT\",\n \"REGEX_EXTRACT(text, pattern, group, flags)\",\n \"Extract a capture (default 0: whole match); no match returns null.\",\n 2,\n 4,\n \"text\",\n [\"text\", \"text\", \"number\", \"text\"],\n ),\n f(\n \"REGEX_REPLACE\",\n \"REGEX_REPLACE(text, pattern, replacement, flags)\",\n \"Replace all matches; supports $1 capture references.\",\n 3,\n 4,\n \"text\",\n [\"text\", \"text\", \"text\", \"text\"],\n ),\n ...[\"ABS\", \"FLOOR\", \"CEIL\", \"TRUNC\", \"SQRT\"].map((n) =>\n f(n, `${n}(number)`, \"Numeric transformation.\", 1, 1, \"number\", [\"number\"]),\n ),\n f(\n \"ROUND\",\n \"ROUND(number, digits)\",\n \"Round to decimal places (default 0, range -15 to 15).\",\n 1,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"POWER\",\n \"POWER(base, exponent)\",\n \"Raise a number to a power.\",\n 2,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"CLAMP\",\n \"CLAMP(number, lower, upper)\",\n \"Constrain a number to an inclusive range.\",\n 3,\n 3,\n \"number\",\n [\"number\"],\n ),\n ...[\"LEAST\", \"GREATEST\"].map((n) =>\n f(\n n,\n `${n}(number, ...)`,\n \"Compare numbers within this row.\",\n 1,\n 50,\n \"number\",\n [\"number\"],\n ),\n ),\n f(\n \"IF\",\n \"IF(condition, then, otherwise)\",\n \"Evaluate only the chosen branch; null condition uses otherwise.\",\n 3,\n 3,\n \"branch\",\n \"any\",\n ),\n f(\n \"IFS\",\n \"IFS(condition, value, ..., fallback)\",\n \"First true condition wins; final fallback is required.\",\n 3,\n 49,\n \"branch\",\n \"any\",\n ),\n f(\n \"SWITCH\",\n \"SWITCH(value, match, result, ..., fallback)\",\n \"Match a value to a result; final fallback is required.\",\n 4,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"COALESCE\",\n \"COALESCE(value, ...)\",\n \"First non-null value, evaluated lazily.\",\n 1,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"NULLIF\",\n \"NULLIF(value, other)\",\n \"Return null if the values are equal.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...[\"IS_NULL\", \"IS_EMPTY\"].map((n) =>\n f(\n n,\n `${n}(value)`,\n \"Test null, or null/empty text/empty array.\",\n 1,\n 1,\n \"bool\",\n \"any\",\n ),\n ),\n f(\n \"IFERROR\",\n \"IFERROR(value, fallback)\",\n \"Use fallback only when evaluating value fails.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...(\n [\n [\"TO_TEXT\", \"text\"],\n [\"TO_NUMBER\", \"number\"],\n [\"TO_BOOLEAN\", \"bool\"],\n [\"TO_DATETIME\", \"datetime\"],\n ] as const\n ).map(([n, t]) =>\n f(\n n,\n `${n}(value)`,\n \"Explicit conversion; invalid input produces a cell error.\",\n 1,\n 1,\n t,\n \"any\",\n ),\n ),\n f(\n \"SPLIT\",\n \"SPLIT(text, separator)\",\n \"Split text into an array.\",\n 2,\n 2,\n \"textarray\",\n [\"text\", \"text\"],\n ),\n f(\"JOIN\", \"JOIN(array, separator)\", \"Join an array of text.\", 2, 2, \"text\", [\n \"textarray\",\n \"text\",\n ]),\n f(\n \"ARRAY_LENGTH\",\n \"ARRAY_LENGTH(array)\",\n \"Count array elements.\",\n 1,\n 1,\n \"number\",\n [\"textarray\"],\n ),\n f(\n \"ARRAY_CONTAINS\",\n \"ARRAY_CONTAINS(array, text)\",\n \"Case-sensitive array membership.\",\n 2,\n 2,\n \"bool\",\n [\"textarray\", \"text\"],\n ),\n f(\n \"ARRAY_GET\",\n \"ARRAY_GET(array, index)\",\n \"One-based element; out of range returns null.\",\n 2,\n 2,\n \"text\",\n [\"textarray\", \"number\"],\n ),\n ...[\"ARRAY_UNIQUE\", \"ARRAY_SORT\"].map((n) =>\n f(\n n,\n `${n}(array)`,\n \"Deduplicate or sort text elements by code-point order.\",\n 1,\n 1,\n \"textarray\",\n [\"textarray\"],\n ),\n ),\n ...[\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\", \"WEEKDAY\"].map((n) =>\n f(\n n,\n `${n}(datetime)`,\n \"UTC date component; weekday is Monday=1 through Sunday=7.\",\n 1,\n 1,\n \"number\",\n [\"datetime\"],\n ),\n ),\n f(\n \"DATE_TRUNC\",\n \"DATE_TRUNC(unit, datetime)\",\n \"UTC truncation: year, month, week (Monday), day, hour, minute, second.\",\n 2,\n 2,\n \"datetime\",\n [\"text\", \"datetime\"],\n ),\n f(\n \"DATE_ADD\",\n \"DATE_ADD(unit, amount, datetime)\",\n \"UTC calendar addition; month/year clamp to the last day.\",\n 3,\n 3,\n \"datetime\",\n [\"text\", \"number\", \"datetime\"],\n ),\n f(\n \"DATE_DIFF\",\n \"DATE_DIFF(unit, start, end)\",\n \"Elapsed whole units: week, day, hour, minute, second, millisecond.\",\n 3,\n 3,\n \"number\",\n [\"text\", \"datetime\", \"datetime\"],\n ),\n f(\n \"FORMAT_DATE\",\n \"FORMAT_DATE(datetime, pattern)\",\n \"UTC tokens: YYYY MM DD HH mm ss; other text is literal.\",\n 2,\n 2,\n \"text\",\n [\"datetime\", \"text\"],\n ),\n];\n\nexport class FormulaError extends Error {\n constructor(\n message: string,\n public from = 0,\n public to = from + 1,\n ) {\n super(message);\n }\n}\ninterface Token {\n text: string;\n kind: \"field\" | \"string\" | \"number\" | \"word\" | \"op\" | \"end\";\n from: number;\n to: number;\n}\nexport function compileFormula(\n source: string,\n fields: readonly { name: string; type: FieldType }[],\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaPlan {\n if (!source.trim() || source.length > 10000)\n throw new FormulaError(\"Formula must contain 1–10,000 characters.\");\n const tokens: Token[] = [];\n let pos = 0;\n while (pos < source.length) {\n if (/\\s/.test(source[pos]!)) {\n pos++;\n continue;\n }\n const from = pos;\n let match: RegExpMatchArray | null;\n if (source[pos] === \"[\") {\n pos++;\n let text = \"\";\n let closed = false;\n while (pos < source.length) {\n if (source[pos] === \"]\") {\n if (source[pos + 1] === \"]\") {\n text += \"]\";\n pos += 2;\n } else {\n pos++;\n closed = true;\n break;\n }\n } else text += source[pos++];\n }\n if (!closed)\n throw new FormulaError(\"Unclosed field reference.\", from, pos);\n tokens.push({ kind: \"field\", text, from, to: pos });\n } else if (source[pos] === '\"') {\n pos++;\n while (pos < source.length && source[pos] !== '\"') {\n if (source[pos] === \"\\\\\") pos++;\n pos++;\n }\n pos++;\n try {\n tokens.push({\n kind: \"string\",\n text: JSON.parse(source.slice(from, pos)),\n from,\n to: pos,\n });\n } catch {\n throw new FormulaError(\"Invalid JSON string literal.\", from, pos);\n }\n } else if (\n (match = source\n .slice(pos)\n .match(/^(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"number\", text: match[0], from, to: pos });\n } else if ((match = source.slice(pos).match(/^[a-zA-Z_][a-zA-Z_0-9]*/))) {\n pos += match[0].length;\n tokens.push({\n kind: \"word\",\n text: match[0].toUpperCase(),\n from,\n to: pos,\n });\n } else if (\n (match = source.slice(pos).match(/^(>=|<=|!=|<>|[=<>+*/%(),-])/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"op\", text: match[0], from, to: pos });\n } else throw new FormulaError(`Unexpected character ${source[pos]}.`, from);\n if (tokens.length > 2000)\n throw new FormulaError(\"Formula is too complex.\", from);\n }\n tokens.push({ kind: \"end\", text: \"\", from: pos, to: pos });\n let i = 0,\n depth = 0;\n const peek = () => tokens[i]!;\n const take = () => tokens[i++]!;\n const expect = (s: string) => {\n if (peek().text !== s)\n throw new FormulaError(`Expected ${s}.`, peek().from, peek().to);\n return take();\n };\n const call = (\n name: string,\n args: FormulaNode[],\n from: number,\n to: number,\n ): FormulaNode => ({ kind: \"call\", name, args, from, to });\n const priority: Record<string, number> = {\n OR: 1,\n AND: 2,\n \"=\": 3,\n \"!=\": 3,\n \"<>\": 3,\n \"<\": 3,\n \">\": 3,\n \"<=\": 3,\n \">=\": 3,\n IN: 3,\n BETWEEN: 3,\n \"+\": 4,\n \"-\": 4,\n \"*\": 5,\n \"/\": 5,\n \"%\": 5,\n };\n function expression(min = 0): FormulaNode {\n if (++depth > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", peek().from);\n const t = take();\n let node: FormulaNode;\n if (t.kind === \"number\") {\n if (!Number.isFinite(Number(t.text)))\n throw new FormulaError(\"Number must be finite.\", t.from, t.to);\n node = { kind: \"literal\", value: Number(t.text), from: t.from, to: t.to };\n } else if (t.kind === \"string\")\n node = { kind: \"literal\", value: t.text, from: t.from, to: t.to };\n else if (t.kind === \"field\")\n node = { kind: \"field\", name: t.text, from: t.from, to: t.to };\n else if ([\"TRUE\", \"FALSE\", \"NULL\"].includes(t.text))\n node = {\n kind: \"literal\",\n value: t.text === \"NULL\" ? null : t.text === \"TRUE\",\n from: t.from,\n to: t.to,\n };\n else if (t.text === \"(\") {\n node = expression();\n expect(\")\");\n } else if ([\"NOT\", \"-\", \"+\"].includes(t.text)) {\n const arg = expression(t.text === \"NOT\" ? 3 : 6);\n node = call(`unary:${t.text}`, [arg], t.from, arg.to);\n } else if (t.kind === \"word\") {\n expect(\"(\");\n const args: FormulaNode[] = [];\n if (peek().text !== \")\") {\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n }\n node = call(t.text, args, t.from, expect(\")\").to);\n } else\n throw new FormulaError(\n \"Expected a value, field, or function.\",\n t.from,\n t.to,\n );\n while (peek().kind !== \"end\" && (priority[peek().text] ?? -1) >= min) {\n const op = take();\n const p = priority[op.text]!;\n if (op.text === \"IN\") {\n expect(\"(\");\n const args = [node];\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n node = call(\"op:IN\", args, node.from, expect(\")\").to);\n } else if (op.text === \"BETWEEN\") {\n const lo = expression(p + 1);\n expect(\"AND\");\n const hi = expression(p + 1);\n node = call(\"op:BETWEEN\", [node, lo, hi], node.from, hi.to);\n } else {\n const right = expression(p + 1);\n node = call(`op:${op.text}`, [node, right], node.from, right.to);\n }\n }\n depth--;\n return node;\n }\n const ast = expression();\n if (peek().kind !== \"end\")\n throw new FormulaError(\"Unexpected token.\", peek().from, peek().to);\n const deps = new Set<string>();\n const byName = new Map(fields.map((v) => [v.name, v.type]));\n const same = (ts: FormulaType[], n: FormulaNode): FormulaType => {\n const real = [...new Set(ts.filter((t) => t !== \"null\"))];\n if (real.length > 1)\n throw new FormulaError(\n \"Values must have compatible types; use an explicit conversion.\",\n n.from,\n n.to,\n );\n return real[0] ?? \"null\";\n };\n function check(n: FormulaNode, level = 0): FormulaType {\n if (level > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", n.from, n.to);\n if (n.kind === \"literal\")\n return n.value === null\n ? \"null\"\n : typeof n.value === \"boolean\"\n ? \"bool\"\n : typeof n.value === \"number\"\n ? \"number\"\n : \"text\";\n if (n.kind === \"field\") {\n const t = byName.get(n.name);\n if (!t) {\n const nested = resolve?.(n.name);\n if (nested) {\n Object.assign(n, nested.ast);\n nested.dependencies.forEach((d) => deps.add(d));\n return nested.type;\n }\n throw new FormulaError(\n `Unknown or unavailable field: ${n.name}`,\n n.from,\n n.to,\n );\n }\n deps.add(n.name);\n n.valueType = t === \"enum\" ? \"text\" : t;\n return n.valueType;\n }\n const ts = n.args.map((a) => check(a, level + 1));\n const need = (index: number, t: FormulaType) => {\n if (ts[index] !== undefined && ts[index] !== \"null\" && ts[index] !== t)\n throw new FormulaError(\n `Expected ${t}, received ${ts[index]}.`,\n n.args[index]!.from,\n n.args[index]!.to,\n );\n };\n if (n.name.startsWith(\"op:\") || n.name.startsWith(\"unary:\")) {\n const op = n.name.split(\":\")[1]!;\n if ([\"AND\", \"OR\", \"NOT\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"bool\"));\n return \"bool\";\n }\n if ([\"+\", \"-\", \"*\", \"/\", \"%\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"number\"));\n return \"number\";\n }\n same(ts, n);\n return \"bool\";\n }\n const spec = FORMULA_FUNCTIONS.find((v) => v.name === n.name);\n if (!spec)\n throw new FormulaError(`Unknown function: ${n.name}`, n.from, n.to);\n if (ts.length < spec.min || ts.length > spec.max)\n throw new FormulaError(`Use ${spec.signature}.`, n.from, n.to);\n if (spec.args !== \"any\") {\n const args = spec.args;\n ts.forEach((_, j) => need(j, args[Math.min(j, args.length - 1)]!));\n }\n if (n.name === \"IF\") {\n need(0, \"bool\");\n return same(ts.slice(1), n);\n }\n if (n.name === \"IFS\") {\n if (ts.length % 2 !== 1)\n throw new FormulaError(\n \"IFS requires condition/value pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n ts.forEach((t, j) => {\n if (j === ts.length - 1 || j % 2 === 1) branches.push(t);\n else need(j, \"bool\");\n });\n return same(branches, n);\n }\n if (n.name === \"SWITCH\") {\n if (ts.length % 2 !== 0)\n throw new FormulaError(\n \"SWITCH requires match/result pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n for (let j = 1; j < ts.length - 1; j += 2) {\n same([ts[0]!, ts[j]!], n);\n branches.push(ts[j + 1]!);\n }\n branches.push(ts[ts.length - 1]!);\n return same(branches, n);\n }\n if (n.name.startsWith(\"REGEX_\")) {\n const pattern = n.args[1];\n const flags = n.args[n.name === \"REGEX_TEST\" ? 2 : 3];\n if (pattern?.kind === \"literal\" && typeof pattern.value === \"string\") {\n if (pattern.value.length > 2000)\n throw new FormulaError(\n \"Regex pattern exceeds 2,000 characters.\",\n pattern.from,\n pattern.to,\n );\n if (\n !flags ||\n (flags.kind === \"literal\" && typeof flags.value === \"string\")\n ) {\n const value = flags?.value ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(String(value)))\n throw new FormulaError(\n \"Regex flags must be unique i, m, or s.\",\n n.from,\n n.to,\n );\n try {\n new RegExp(pattern.value, `${value}u`);\n } catch {\n throw new FormulaError(\n \"Invalid regex pattern.\",\n pattern.from,\n pattern.to,\n );\n }\n }\n }\n }\n if (spec.result === \"branch\") return same(ts, n);\n return spec.result;\n }\n const type = check(ast);\n return { ast, dependencies: [...deps].sort(), type };\n}\n\n/** Self-contained runtime: serialized into the browser worker, never user code. */\nexport function formulaRuntime(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>,\n): FormulaResult {\n const fail = (s: string): never => {\n throw new Error(s);\n };\n const num = (v: FormulaValue): number =>\n typeof v === \"number\" && Number.isFinite(v)\n ? v\n : fail(\"Expected a finite number.\");\n const str = (v: FormulaValue): string =>\n typeof v === \"string\" ? v : fail(\"Expected text.\");\n const arr = (v: FormulaValue): string[] =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\")\n ? v\n : fail(\"Expected a text array.\");\n const integer = (v: FormulaValue, min = 0, max = 100000): number => {\n const n = num(v);\n return Number.isInteger(n) && n >= min && n <= max\n ? n\n : fail(`Expected an integer between ${min} and ${max}.`);\n };\n const equal = (a: FormulaValue, b: FormulaValue) =>\n JSON.stringify(a) === JSON.stringify(b);\n const date = (v: FormulaValue): Date => {\n const s = str(v);\n if (\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n s,\n )\n )\n fail(\"Expected an ISO date or timestamp with timezone.\");\n const d = new Date(s);\n const day = Number(s.slice(8, 10)),\n month = Number(s.slice(5, 7));\n if (\n !Number.isFinite(d.getTime()) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > new Date(Date.UTC(Number(s.slice(0, 4)), month, 0)).getUTCDate()\n )\n fail(\"Invalid date.\");\n return d;\n };\n const bound = (v: FormulaValue): FormulaValue => {\n if (\n v !== null &&\n typeof v !== \"number\" &&\n typeof v !== \"string\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v)\n )\n fail(\"Unsupported input value type.\");\n if (Array.isArray(v) && !v.every((x) => typeof x === \"string\"))\n fail(\"Expected a text array.\");\n if (typeof v === \"number\" && !Number.isFinite(v))\n fail(\"Result is not finite.\");\n if (typeof v === \"string\" && v.length > 100000)\n fail(\"Text result exceeds 100,000 characters.\");\n if (\n Array.isArray(v) &&\n (v.length > 10000 || v.reduce((s, x) => s + x.length, 0) > 100000)\n )\n fail(\"Array result is too large.\");\n return v;\n };\n let inspection: RegexInspection | undefined;\n let budget = 5000;\n function run(n: FormulaNode): FormulaValue {\n if (--budget < 0) fail(\"Formula operation limit exceeded.\");\n if (n.kind === \"literal\") return n.value;\n if (n.kind === \"field\") {\n if (!Object.prototype.hasOwnProperty.call(inputs, n.name)) return null;\n const v = bound(inputs[n.name] ?? null);\n if (v === null) return null;\n if (n.valueType === \"number\") return num(v);\n if (n.valueType === \"bool\" && typeof v !== \"boolean\")\n fail(\"Expected a boolean.\");\n if (n.valueType === \"datetime\") return date(v).toISOString();\n if (n.valueType === \"text\") return str(v);\n if (n.valueType === \"textarray\") return arr(v);\n return v;\n }\n const name = n.name;\n const args = n.args;\n if (name === \"IF\") return run(run(args[0]!) === true ? args[1]! : args[2]!);\n if (name === \"IFS\") {\n for (let j = 0; j < args.length - 1; j += 2)\n if (run(args[j]!) === true) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"SWITCH\") {\n const v = run(args[0]!);\n for (let j = 1; j < args.length - 1; j += 2)\n if (equal(v, run(args[j]!))) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"COALESCE\") {\n for (const arg of args) {\n const v = run(arg);\n if (v !== null) return v;\n }\n return null;\n }\n if (name === \"IFERROR\") {\n try {\n return run(args[0]!);\n } catch {\n return run(args[1]!);\n }\n }\n if (name === \"op:AND\" || name === \"op:OR\") {\n const a = run(args[0]!);\n if (name === \"op:AND\" && a === false) return false;\n if (name === \"op:OR\" && a === true) return true;\n const b = run(args[1]!);\n return name === \"op:AND\"\n ? b === false\n ? false\n : a === null || b === null\n ? null\n : true\n : b === true\n ? true\n : a === null || b === null\n ? null\n : false;\n }\n const vs = args.map(run);\n const a = vs[0] ?? null,\n b = vs[1] ?? null,\n c = vs[2] ?? null;\n if (name === \"IS_NULL\") return a === null;\n if (name === \"IS_EMPTY\")\n return a === null || a === \"\" || (Array.isArray(a) && a.length === 0);\n if (name === \"NULLIF\") return equal(a, b) ? null : a;\n if (name === \"CONCAT_WS\")\n return a === null\n ? null\n : bound(\n vs\n .slice(1)\n .filter((v) => v !== null)\n .map(str)\n .join(str(a)),\n );\n if (name === \"op:IN\") {\n if (a === null) return null;\n if (vs.slice(1).some((v) => v !== null && equal(a, v))) return true;\n return vs.slice(1).includes(null) ? null : false;\n }\n if (vs.some((v) => v === null)) return null;\n let out: FormulaValue;\n switch (name) {\n case \"unary:NOT\":\n out = !a;\n break;\n case \"unary:-\":\n out = -num(a);\n break;\n case \"unary:+\":\n out = num(a);\n break;\n case \"op:+\":\n out = num(a) + num(b);\n break;\n case \"op:-\":\n out = num(a) - num(b);\n break;\n case \"op:*\":\n out = num(a) * num(b);\n break;\n case \"op:/\":\n case \"op:%\":\n if (num(b) === 0) fail(\"Division by zero.\");\n out = name === \"op:/\" ? num(a) / num(b) : num(a) % num(b);\n break;\n case \"op:=\":\n out = equal(a, b);\n break;\n case \"op:!=\":\n case \"op:<>\":\n out = !equal(a, b);\n break;\n case \"op:<\":\n out = a! < b!;\n break;\n case \"op:>\":\n out = a! > b!;\n break;\n case \"op:<=\":\n out = a! <= b!;\n break;\n case \"op:>=\":\n out = a! >= b!;\n break;\n case \"op:BETWEEN\":\n out = a! >= b! && a! <= c!;\n break;\n case \"LEFT\":\n out = Array.from(str(a)).slice(0, integer(b)).join(\"\");\n break;\n case \"RIGHT\": {\n const n = integer(b);\n out = n ? Array.from(str(a)).slice(-n).join(\"\") : \"\";\n break;\n }\n case \"SUBSTRING\": {\n const start = integer(b, 1) - 1;\n out = Array.from(str(a))\n .slice(start, vs.length > 2 ? start + integer(c) : undefined)\n .join(\"\");\n break;\n }\n case \"LENGTH\":\n out = Array.from(str(a)).length;\n break;\n case \"LOWER\":\n out = str(a).toLowerCase();\n break;\n case \"UPPER\":\n out = str(a).toUpperCase();\n break;\n case \"TRIM\":\n out = str(a).trim();\n break;\n case \"LTRIM\":\n out = str(a).trimStart();\n break;\n case \"RTRIM\":\n out = str(a).trimEnd();\n break;\n case \"REPLACE\":\n if (b === \"\") fail(\"Search text must not be empty.\");\n const parts = str(a).split(str(b));\n if (parts.length * str(c).length + str(a).length > 200000)\n fail(\"Replacement result is too large.\");\n out = parts.join(str(c));\n break;\n case \"LPAD\":\n case \"RPAD\": {\n const chars = Array.from(str(a)),\n len = integer(b),\n pad = Array.from(vs.length > 2 ? str(c) : \" \");\n if (!pad.length) fail(\"Padding must not be empty.\");\n const fill = Array.from(\n { length: Math.max(0, len - chars.length) },\n (_, i) => pad[i % pad.length]!,\n ).join(\"\");\n out =\n (name === \"LPAD\" ? fill : \"\") +\n chars.slice(0, len).join(\"\") +\n (name === \"RPAD\" ? fill : \"\");\n break;\n }\n case \"SPLIT_PART\":\n out = str(a).split(str(b))[integer(c, 1) - 1] ?? null;\n break;\n case \"CONCAT\":\n out = vs.map(str).join(\"\");\n break;\n case \"CONTAINS\":\n case \"STARTS_WITH\":\n case \"ENDS_WITH\": {\n const s = c === true ? str(a).toLowerCase() : str(a),\n t = c === true ? str(b).toLowerCase() : str(b);\n out =\n name === \"CONTAINS\"\n ? s.includes(t)\n : name === \"STARTS_WITH\"\n ? s.startsWith(t)\n : s.endsWith(t);\n break;\n }\n case \"REGEX_TEST\":\n case \"REGEX_EXTRACT\":\n case \"REGEX_REPLACE\": {\n const flags = vs[name === \"REGEX_TEST\" ? 2 : 3] ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(str(flags)))\n fail(\"Regex flags must be unique i, m, or s.\");\n if (str(b).length > 2000)\n fail(\"Regex pattern exceeds 2,000 characters.\");\n const re = new RegExp(\n str(b),\n `${flags}u${name === \"REGEX_REPLACE\" ? \"g\" : \"\"}`,\n );\n if (name === \"REGEX_TEST\") out = re.test(str(a));\n else if (name === \"REGEX_REPLACE\") {\n let produced = 0;\n out = str(a).replace(re, (...captures: unknown[]) => {\n const replacement = str(c).replace(\n /\\$(\\$|[0-9]{1,2}|&|`|')/g,\n (_token, key: string) => {\n if (key === \"$\") return \"$\";\n if (key === \"&\") return String(captures[0]);\n if (key === \"`\" || key === \"'\")\n return fail(\n \"Regex replacement supports $$, $&, and numbered captures only.\",\n );\n const extra =\n typeof captures[captures.length - 1] === \"object\" ? 3 : 2;\n const i = Number(key);\n return i > 0 && i < captures.length - extra\n ? String(captures[i] ?? \"\")\n : fail(\"Invalid replacement capture.\");\n },\n );\n produced += replacement.length;\n if (produced > 100000) fail(\"Replacement result is too large.\");\n return replacement;\n });\n } else {\n const match = re.exec(str(a));\n const group = vs.length > 2 ? integer(c, 0, 100) : 0;\n out = match?.[group] ?? null;\n if (match)\n inspection = {\n input: str(a),\n start: match.index,\n end: match.index + match[0].length,\n groups: Array.from(match, (v) => v ?? null),\n };\n }\n break;\n }\n case \"ABS\":\n out = Math.abs(num(a));\n break;\n case \"FLOOR\":\n out = Math.floor(num(a));\n break;\n case \"CEIL\":\n out = Math.ceil(num(a));\n break;\n case \"TRUNC\":\n out = Math.trunc(num(a));\n break;\n case \"SQRT\":\n out = Math.sqrt(num(a));\n break;\n case \"ROUND\": {\n const scale = 10 ** (vs.length > 1 ? integer(b, -15, 15) : 0);\n out = Math.round(num(a) * scale) / scale;\n break;\n }\n case \"POWER\":\n out = Math.pow(num(a), num(b));\n break;\n case \"CLAMP\":\n if (num(b) > num(c)) fail(\"Lower bound exceeds upper bound.\");\n out = Math.max(num(b), Math.min(num(c), num(a)));\n break;\n case \"LEAST\":\n out = Math.min(...vs.map(num));\n break;\n case \"GREATEST\":\n out = Math.max(...vs.map(num));\n break;\n case \"TO_TEXT\":\n out = Array.isArray(a) ? JSON.stringify(a) : String(a);\n break;\n case \"TO_NUMBER\":\n if (\n typeof a !== \"number\" &&\n (typeof a !== \"string\" ||\n !/^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/.test(a.trim()))\n )\n fail(\"Cannot convert to number.\");\n out = Number(a);\n break;\n case \"TO_BOOLEAN\":\n if (a === true || a === false) out = a;\n else if (a === \"true\" || a === 1) out = true;\n else if (a === \"false\" || a === 0) out = false;\n else return fail(\"Cannot convert to boolean.\");\n break;\n case \"TO_DATETIME\":\n out = date(a).toISOString();\n break;\n case \"SPLIT\":\n out = str(a).split(str(b));\n break;\n case \"JOIN\":\n out = arr(a).join(str(b));\n break;\n case \"ARRAY_LENGTH\":\n out = arr(a).length;\n break;\n case \"ARRAY_CONTAINS\":\n out = arr(a).includes(str(b));\n break;\n case \"ARRAY_GET\":\n out = arr(a)[integer(b, 1) - 1] ?? null;\n break;\n case \"ARRAY_UNIQUE\":\n out = [...new Set(arr(a))];\n break;\n case \"ARRAY_SORT\":\n out = [...arr(a)].sort((left, right) => {\n const l = Array.from(left),\n r = Array.from(right);\n for (let i = 0; i < Math.min(l.length, r.length); i++) {\n const delta = l[i]!.codePointAt(0)! - r[i]!.codePointAt(0)!;\n if (delta) return delta;\n }\n return l.length - r.length;\n });\n break;\n case \"YEAR\":\n out = date(a).getUTCFullYear();\n break;\n case \"MONTH\":\n out = date(a).getUTCMonth() + 1;\n break;\n case \"DAY\":\n out = date(a).getUTCDate();\n break;\n case \"HOUR\":\n out = date(a).getUTCHours();\n break;\n case \"WEEKDAY\":\n out = ((date(a).getUTCDay() + 6) % 7) + 1;\n break;\n case \"DATE_TRUNC\": {\n const d = date(b),\n unit = str(a).toLowerCase();\n if (\n ![\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n ].includes(unit)\n )\n fail(\"Unsupported date unit.\");\n d.setUTCMilliseconds(0);\n if (unit !== \"second\") d.setUTCSeconds(0);\n if (![\"second\", \"minute\"].includes(unit)) d.setUTCMinutes(0);\n if ([\"year\", \"month\", \"week\", \"day\"].includes(unit)) d.setUTCHours(0);\n if (unit === \"week\")\n d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7));\n if (unit === \"year\" || unit === \"month\") d.setUTCDate(1);\n if (unit === \"year\") d.setUTCMonth(0);\n out = d.toISOString();\n break;\n }\n case \"DATE_ADD\": {\n const d = date(c),\n unit = str(a).toLowerCase(),\n amount = integer(b, -100000, 100000);\n if (unit === \"year\" || unit === \"month\") {\n const day = d.getUTCDate();\n d.setUTCDate(1);\n d.setUTCMonth(d.getUTCMonth() + amount * (unit === \"year\" ? 12 : 1));\n const last = new Date(d.getTime());\n last.setUTCMonth(last.getUTCMonth() + 1, 0);\n d.setUTCDate(Math.min(day, last.getUTCDate()));\n } else {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[unit];\n if (!ms) fail(\"Unsupported date unit.\");\n d.setTime(d.getTime() + amount * ms!);\n }\n out = d.toISOString();\n break;\n }\n case \"DATE_DIFF\": {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[str(a).toLowerCase()];\n if (!ms) fail(\"Unsupported elapsed date unit.\");\n out = Math.trunc((date(c).getTime() - date(b).getTime()) / ms!);\n break;\n }\n case \"FORMAT_DATE\": {\n const d = date(a),\n pad = (n: number) => String(n).padStart(2, \"0\"),\n parts: Record<string, string> = {\n YYYY: String(d.getUTCFullYear()).padStart(4, \"0\"),\n MM: pad(d.getUTCMonth() + 1),\n DD: pad(d.getUTCDate()),\n HH: pad(d.getUTCHours()),\n mm: pad(d.getUTCMinutes()),\n ss: pad(d.getUTCSeconds()),\n };\n out = str(b).replace(/YYYY|MM|DD|HH|mm|ss/g, (t) => parts[t]!);\n break;\n }\n default:\n return fail(`Unknown operation: ${name}`);\n }\n return bound(out);\n }\n try {\n const value = run(ast);\n return inspection ? { value, regex: inspection } : { value };\n } catch (e) {\n return {\n value: null,\n error: e instanceof Error ? e.message : \"Formula evaluation failed.\",\n };\n }\n}\n"],"mappings":"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","names":["field","f","next","resolveField","f","resolveField","f","item","a","b","n","parts"]}
|
|
1
|
+
{"version":3,"sources":["../src/cellDisplay.ts","../src/properties.ts","../src/schema.ts","../src/itemPage.ts","../src/metricNormalize.ts","../src/query.ts","../src/relativeTime.ts","../src/ops.ts","../src/agg.ts","../src/encode.ts","../src/setFilter.ts","../src/queryLinks.ts","../src/computed.ts","../src/formula.ts","../src/grouping.ts","../src/execution.ts","../src/metricPrecision.ts","../src/metricDistributions.ts","../src/metricDates.ts","../src/metrics.ts","../src/apply.ts","../src/adapters.ts","../src/propertyStorage.ts","../src/source.ts","../src/queryV3.ts"],"sourcesContent":["/** Presentation hints only: field types still determine query/filter semantics. */\nexport interface JsonCellDisplay {\n kind: \"json\";\n /** auto accepts objects, JSON text and repeatedly encoded/escaped JSON text.\n * value keeps a native string literal; json parses text once; escaped unwraps it. */\n encoding?: \"auto\" | \"value\" | \"json\" | \"escaped\";\n /** Maximum string-unwrapping passes, 1–8. Default 4. */\n maxDecodeDepth?: number;\n /** Inline preview length, 20–500 characters. Default 80. */\n previewLength?: number;\n /** Override initially expanded container levels, 0–8.\n * The root starts open. By default, nested containers with up to 3 entries\n * open; larger nested containers collapse. */\n expandDepth?: number;\n}\n\ntype CalendarDisplay = {\n style?: \"human\" | \"iso\" | \"custom\";\n pattern?: string;\n /** UTC by default; an IANA timezone or local may be selected explicitly. */\n timeZone?: string;\n locale?: string;\n};\n\nexport type CellDisplay =\n | JsonCellDisplay\n | ({ kind: \"date\" | \"datetime\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" } & CalendarDisplay)\n | ({ kind: \"time\"; sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\" | \"secondsOfDay\" | \"millisecondsOfDay\" } & CalendarDisplay)\n | { kind: \"duration\"; sourceUnit?: \"milliseconds\" | \"seconds\" | \"minutes\" | \"hours\" | \"days\"; style?: \"human\" | \"long\" | \"clock\" | \"custom\"; pattern?: string; decimals?: number }\n | { kind: \"number\" | \"percent\"; decimals?: number; locale?: string }\n | { kind: \"chip\"; labels?: Record<string, string>; tones?: Record<string, \"neutral\" | \"success\" | \"warning\" | \"danger\"> }\n | { kind: \"text\"; truncate?: boolean };\n\nconst calendarOptions = {\n style: [\"human\", \"iso\", \"custom\"], pattern: \"string\", timeZone: \"string\", locale: \"string\",\n} as const;\nconst numberOptions = { decimals: [0, 20], locale: \"string\" } as const;\nconst calendarUnits = [\"iso\", \"epochSeconds\", \"epochMilliseconds\"];\nconst options: Record<string, Record<string, readonly string[] | readonly number[] | string>> = {\n json: { encoding: [\"auto\", \"value\", \"json\", \"escaped\"], maxDecodeDepth: [1, 8], previewLength: [20, 500], expandDepth: [0, 8] },\n date: { ...calendarOptions, sourceUnit: calendarUnits },\n datetime: { ...calendarOptions, sourceUnit: calendarUnits },\n time: { ...calendarOptions, sourceUnit: [...calendarUnits, \"secondsOfDay\", \"millisecondsOfDay\"] },\n duration: { sourceUnit: [\"milliseconds\", \"seconds\", \"minutes\", \"hours\", \"days\"], style: [\"human\", \"long\", \"clock\", \"custom\"], pattern: \"string\", decimals: [0, 20] },\n number: numberOptions, percent: numberOptions,\n chip: { labels: \"labels\", tones: \"tones\" },\n text: { truncate: \"boolean\" },\n};\n\n/** Validate the serializable contract at schema loading, before rendering cells. */\nexport function parseCellDisplay(raw: unknown, context = \"cell display\"): CellDisplay {\n const fail = (reason: string): never => { throw Error(`${context}: ${reason}`); };\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return fail(\"expected an object\");\n const record = raw as Record<string, unknown>;\n if (typeof record.kind !== \"string\" || !Object.prototype.hasOwnProperty.call(options, record.kind)) return fail(\"unsupported kind\");\n const allowed = options[record.kind]!;\n for (const [key, value] of Object.entries(record)) {\n if (key === \"kind\") continue;\n const rule = Object.prototype.hasOwnProperty.call(allowed, key) ? allowed[key] : undefined;\n if (!rule) return fail(`unsupported option ${key}`);\n if (Array.isArray(rule)) {\n if (typeof rule[0] === \"number\") {\n if (typeof value !== \"number\" || !Number.isInteger(value) || value < Number(rule[0]) || value > Number(rule[1])) return fail(`${key} must be an integer from ${rule[0]} to ${rule[1]}`);\n } else if (!rule.includes(value as never)) return fail(`unsupported ${key}`);\n } else if (rule === \"labels\" || rule === \"tones\") {\n if (!value || typeof value !== \"object\" || Array.isArray(value) || !Object.values(value).every((item) => typeof item === \"string\" && (rule === \"labels\" || [\"neutral\", \"success\", \"warning\", \"danger\"].includes(item)))) return fail(`invalid ${key} map`);\n } else if (typeof value !== rule) return fail(`${key} must be ${rule}`);\n if (key === \"pattern\" && (value as string).length > 160) return fail(\"pattern must be at most 160 characters\");\n }\n return { ...record,\n ...(record.labels ? { labels: { ...record.labels as Record<string, string> } } : {}),\n ...(record.tones ? { tones: { ...record.tones as Record<string, string> } } : {}),\n } as CellDisplay;\n}\n","import type { MetricValueFormat } from \"./metricTypes\";\nimport type { FieldDef, FieldSchema } from \"./schema\";\nimport { readFieldValue } from \"./schema\";\nimport type { RowId } from \"./query\";\nimport { parseCellDisplay, type CellDisplay, type JsonCellDisplay } from \"./cellDisplay\";\n\n/** Formats change presentation only; values retain their original types/units. */\nexport type PropertyFormat =\n | MetricValueFormat\n | { kind: \"text\" | \"code\" | \"boolean\" | \"chips\" }\n | JsonCellDisplay\n | Extract<CellDisplay, { kind: \"chip\" }>\n | {\n kind: \"relative\";\n sourceUnit?: \"iso\" | \"epochSeconds\" | \"epochMilliseconds\";\n }\n | { kind: \"currency\"; currency: string; decimals?: number };\n\nexport interface PropertyFieldConfig {\n enabled?: boolean;\n default?: boolean;\n /** Detail-specific renderer. Table renderers remain unchanged. */\n render?: string;\n format?: PropertyFormat;\n}\n\nexport interface PropertySelection {\n /** Instance identity allows the same field to appear with different formats. */\n id: string;\n field: string;\n label?: string;\n render?: string;\n format?: PropertyFormat;\n}\n\n/** Independent of object identity and collection QueryState. [] shows no fields. */\nexport interface PropertyViewState {\n version: 1;\n properties: PropertySelection[];\n /** Property label column width as a percentage, shared with the saved view. */\n labelWidth?: number;\n}\n\nexport const MAX_PROPERTIES = 200;\nconst string = (value: unknown, max = 256): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= max;\nconst record = (value: unknown): value is Record<string, unknown> =>\n value !== null && typeof value === \"object\" && !Array.isArray(value);\n\nexport function normalizePropertyFormat(\n input: unknown,\n): PropertyFormat | undefined {\n if (!record(input)) return;\n const kind = input.kind;\n if (kind === \"json\" || kind === \"chip\") {\n try { return parseCellDisplay(input) as PropertyFormat; }\n catch { return; }\n }\n if (\n input.decimals !== undefined &&\n !(\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n )\n return;\n if ([\"text\", \"code\", \"boolean\", \"chips\"].includes(String(kind)))\n return { kind } as PropertyFormat;\n if (kind === \"relative\") {\n if (\n input.sourceUnit !== undefined &&\n ![\"iso\", \"epochSeconds\", \"epochMilliseconds\"].includes(\n String(input.sourceUnit),\n )\n )\n return;\n return {\n kind,\n ...(input.sourceUnit ? { sourceUnit: input.sourceUnit } : {}),\n } as PropertyFormat;\n }\n if (kind === \"currency\") {\n if (\n typeof input.currency !== \"string\" ||\n !/^[A-Z]{3}$/.test(input.currency)\n )\n return;\n return {\n kind,\n currency: input.currency,\n ...(typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n ? { decimals: input.decimals }\n : {}),\n };\n }\n if (\n ![\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"].includes(\n String(kind),\n )\n )\n return;\n if (\n input.sourceUnit !== undefined &&\n ![\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n return;\n if (\n input.style !== undefined &&\n ![\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style))\n )\n return;\n if (input.pattern !== undefined && !string(input.pattern, 1000)) return;\n if (input.timeZone !== undefined && !string(input.timeZone)) return;\n const out: Record<string, unknown> = { kind };\n if (\n typeof input.decimals === \"number\" &&\n Number.isInteger(input.decimals) &&\n input.decimals >= 0 &&\n input.decimals <= 20\n )\n out.decimals = input.decimals;\n if (\n [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ].includes(String(input.sourceUnit))\n )\n out.sourceUnit = input.sourceUnit;\n if ([\"human\", \"long\", \"clock\", \"custom\", \"iso\"].includes(String(input.style)))\n out.style = input.style;\n if (string(input.pattern, 1000)) out.pattern = input.pattern;\n if (string(input.timeZone)) out.timeZone = input.timeZone;\n return out as unknown as PropertyFormat;\n}\n\n/** Strict envelope/version checks prevent interpreting future saved views as empty. */\nexport function normalizePropertyView(input: unknown): PropertyViewState {\n if (!record(input) || input.version !== 1 || !Array.isArray(input.properties))\n throw new Error(\n \"Unsupported or invalid property view (expected version 1).\",\n );\n if (input.properties.length > MAX_PROPERTIES)\n throw new Error(`At most ${MAX_PROPERTIES} properties are allowed.`);\n const ids = new Set<string>();\n const properties = input.properties.map((item): PropertySelection => {\n if (\n !record(item) ||\n !string(item.id) ||\n !string(item.field) ||\n ids.has(item.id)\n )\n throw new Error(\"Property fields and unique instance IDs are required.\");\n ids.add(item.id);\n const property: PropertySelection = { id: item.id, field: item.field };\n if (string(item.label, 1000)) property.label = item.label;\n if (string(item.render)) property.render = item.render;\n if (item.format !== undefined) {\n const format = normalizePropertyFormat(item.format);\n if (!format) throw new Error(`Invalid format for property ${item.id}.`);\n property.format = format;\n }\n return property;\n });\n const labelWidth = typeof input.labelWidth === \"number\" && Number.isFinite(input.labelWidth)\n ? Math.max(15, Math.min(75, Math.round(input.labelWidth))) : undefined;\n return { version: 1, properties, ...(labelWidth !== undefined ? { labelWidth } : {}) };\n}\n\nexport function createPropertyView<Row>(\n schema: FieldSchema<Row>,\n names?: string[],\n): PropertyViewState {\n const enabled = schema.fields.filter((f) => f.property?.enabled !== false);\n const hasPropertyDefaults = enabled.some(\n (f) => f.property?.default !== undefined,\n );\n const defaults = hasPropertyDefaults\n ? enabled.filter((f) => f.property?.default).map((f) => f.name)\n : (schema.defaultSelect?.map((column) => column.field) ??\n enabled.filter((f) => f.select?.default).map((f) => f.name));\n const fields =\n names ??\n (hasPropertyDefaults || defaults.length\n ? defaults.filter((name) => enabled.some((field) => field.name === name))\n : enabled.map((f) => f.name));\n return normalizePropertyView({\n version: 1,\n properties: fields.map((field, i) => ({ id: `property-${i}`, field })),\n });\n}\n\nexport interface FieldOrigin {\n table: string;\n column: string;\n}\n/** Backend discovery groups composite key columns in constraint order. */\nexport interface ForeignKey {\n sourceTable: string;\n sourceColumns: string[];\n targetTable: string;\n targetColumns: string[];\n}\nexport interface ObjectTypeDefinition {\n name: string;\n table: string;\n keyFields: string[];\n}\nexport interface FieldRelationship {\n objectType: string;\n /** Target key field -> local catalogue field, including composite keys. */\n key: Record<string, string>;\n}\nexport interface ObjectReference {\n objectType: string;\n key: Record<string, RowId>;\n}\nexport interface ResolvedObjectReference {\n reference: ObjectReference;\n label?: string;\n href?: string;\n}\n/** Hosts resolve a batch through their authorized APIs, and own application routes. */\nexport interface RelationshipAdapter {\n resolve(\n references: ObjectReference[],\n signal?: AbortSignal,\n ): Promise<ResolvedObjectReference[]>;\n}\nexport function objectReferenceKey(reference: ObjectReference): string {\n return JSON.stringify([\n reference.objectType,\n Object.entries(reference.key).sort(([a], [b]) => a.localeCompare(b)),\n ]);\n}\nexport function readObjectReference<Row>(\n field: FieldDef<Row>,\n fields: FieldDef<Row>[],\n row: Row,\n): ObjectReference | null {\n const relationship = field.relationship;\n if (!relationship) return null;\n const key: Record<string, RowId> = Object.create(null);\n for (const [target, local] of Object.entries(relationship.key)) {\n const source = fields.find((f) => f.name === local);\n if (!source) return null;\n const value = readFieldValue(source, row);\n if (\n !(\n (typeof value === \"string\" && value !== \"\") ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n )\n return null;\n key[target] = value as RowId;\n }\n return Object.keys(key).length\n ? { objectType: relationship.objectType, key }\n : null;\n}\n\n/** Only unambiguous, fully mapped constraints become links. Explicit metadata wins. */\nexport function discoverFieldRelationships<Row>(\n fields: FieldDef<Row>[],\n keys: ForeignKey[],\n types: ObjectTypeDefinition[],\n): FieldDef<Row>[] {\n return fields.map((field) => {\n if (field.relationship || !field.origin) return field;\n const candidates: FieldRelationship[] = [];\n for (const fk of keys) {\n if (\n fk.sourceTable !== field.origin.table ||\n !fk.sourceColumns.includes(field.origin.column) ||\n fk.sourceColumns.length === 0 ||\n fk.sourceColumns.length !== fk.targetColumns.length\n )\n continue;\n const targets = types.filter(\n (type) =>\n type.table === fk.targetTable &&\n type.keyFields.length === fk.targetColumns.length &&\n type.keyFields.every((k) => fk.targetColumns.includes(k)),\n );\n if (targets.length !== 1) continue;\n const key: Record<string, string> = Object.create(null);\n let complete = true;\n fk.sourceColumns.forEach((column, i) => {\n const local = fields.filter(\n (f) =>\n f.origin?.table === fk.sourceTable && f.origin.column === column,\n );\n if (local.length !== 1) complete = false;\n else key[fk.targetColumns[i]!] = local[0]!.name;\n });\n if (complete) candidates.push({ objectType: targets[0]!.name, key });\n }\n return candidates.length === 1\n ? { ...field, relationship: candidates[0]! }\n : field;\n });\n}\n","// schema.ts — the field schema: the contract that binds frontend and backend.\n//\n// A `FieldSchema` is the runtime, frontend-facing projection of a JSON schema\n// document (schema/query-table.schema.json). The same document is projected on\n// the backend into a Go `Schema` of SQL bindings. Codegen keeps the two in sync.\n//\n// `FieldDef` is organized to make two things obvious (per design feedback):\n//\n// 1. WHAT KIND of field it is — the `source` discriminated union. A `backend`\n// field is a column the server returns and can filter/sort; a `derived`\n// field is computed on the client (or render-only) and is never pushed to\n// the server. Each kind uses its own property subset, so you can't, say,\n// mark a client-only column as server-filterable.\n//\n// 2. CONFIG vs CODE. Everything except `source.accessor` and `render` is\n// declarative, serializable config grouped by capability (`filter`, `sort`,\n// `select`, `display`). The only code-bearing members are the derived\n// `accessor` and the `render` function — kept apart from the config.\n\nimport type { AggOp, FilterOp, OrderByClause, SelectColumn } from \"./query\";\nimport type { CellDisplay } from \"./cellDisplay\";\nimport { parseCellDisplay } from \"./cellDisplay\";\nimport { normalizePropertyFormat, type PropertyFieldConfig, type FieldOrigin, type FieldRelationship } from \"./properties\";\n\nexport type FieldType =\n | \"text\"\n | \"number\"\n | \"enum\"\n | \"datetime\"\n | \"bool\"\n | \"textarray\"; // array-of-text; supports `includes`, and null-as-empty semantics\n\nexport type Align = \"left\" | \"right\" | \"center\";\n\n/** A cell renderer is resolved by name against a `RenderRegistry` (in\n * @pythia-software/query-table-ui) or supplied inline. The type lives in core so FieldDef can\n * reference it, but core never imports React — `unknown` stands in for the node\n * and @pythia-software/query-table-ui narrows it to `React.ReactNode`. */\nexport type CellRenderer<Row = any, V = unknown> = (ctx: {\n value: V;\n row: Row;\n field: FieldDef<Row, V>;\n}) => unknown;\n\n// ---- source: WHAT KIND of field (discriminated union) ---------------------\n\n/** A column the backend returns and can filter/sort. Its SQL expression lives in\n * the JSON schema doc's `bindings` (and the Go Schema), never on the frontend. */\nexport interface BackendField {\n kind: \"backend\";\n /** Dotted path into the API row when it differs from `name` (e.g. \"enqueued_at.Time\"). */\n path?: string;\n /** Computed SQL with no backing column (e.g. is_starred). Documentation hint\n * surfaced to the picker; the actual expression is server-side. */\n synthetic?: boolean;\n}\n\n/** A value computed on the client, or a purely render-driven column. Never\n * pushed to the server; client-side filtering/sorting (if any) reads `accessor`. */\nexport interface DerivedField<Row = any, V = unknown> {\n kind: \"derived\";\n /** Backend inputs required for accessors and computed formulas. */\n dependencies?: string[];\n /** Reusable computed column ID; always select-only. */\n computedId?: string;\n /** Compute the value from the row for client filter/sort. Omit for render-only\n * columns (the renderer reads the whole row from CellContext instead). */\n accessor?: (row: Row) => V;\n}\n\nexport type FieldSource<Row = any, V = unknown> = BackendField | DerivedField<Row, V>;\n\n// ---- capability config (declarative; serializable; shared with backend) ----\n\n/** How filter-value candidates are offered. Autocomplete is the DEFAULT for\n * every field (design feedback): the value input is a combobox backed by\n * Transport.fetchDistinctValues, which takes a search string so large domains\n * refine per keystroke on the backend. `static` is for closed domains you don't\n * want a round-trip for; `freeform` opts out of suggestions entirely. */\nexport type FilterValues =\n | { source: \"autocomplete\" }\n | { source: \"static\"; options: Array<string | { value: string; label: string }> }\n | { source: \"freeform\" };\n\nexport interface FilterConfig {\n /** Opt into the native multi-value editor for textarray fields. */\n editor?: \"set\";\n /** Preserve case when matching textarray values. Default false. */\n arrayCaseSensitive?: boolean;\n /** Whether this field is filterable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Evaluate on the backend (predicate pushdown)? Default: backend ⇒ true.\n * false ⇒ the clause is stripped from the server request and applied locally\n * by applyQuery (the \"serverFilter:false\" derived/JSONB-less columns). */\n pushdown?: boolean;\n /** Override the default operator set for the field's type. */\n ops?: FilterOp[];\n /** Value-suggestion strategy. Default { source: \"autocomplete\" }. */\n values?: FilterValues;\n}\n\nexport interface SortConfig {\n /** Whether this field is sortable. Default: backend ⇒ true, derived ⇒ false. */\n enabled?: boolean;\n /** Server field to ORDER BY when it differs from the display field\n * (e.g. a \"★\" column whose server sort key is `is_starred`). */\n field?: string;\n}\n\nexport interface SelectConfig {\n /** Can this appear as a visible column? Default true. false ⇒ filter-only field. */\n enabled?: boolean;\n /** Shown by default when QueryState.select is empty. */\n default?: boolean;\n /** Default column width (px); a per-column override rides in QueryState.select. */\n width?: number;\n align?: Align;\n}\n\nexport interface AggregateConfig {\n /** Can this field be a metric's MEASURE (sum/avg/min/max/count_distinct)?\n * Default: backend ⇒ true, derived ⇒ false. */\n measure?: boolean;\n /** Can this field be a GROUP BY key? Default: enum/text/bool ⇒ true. */\n groupable?: boolean;\n /** Override the default aggregate-op set for the field's type. */\n ops?: AggOp[];\n}\n\n// ---- the field ------------------------------------------------------------\n\nexport interface FieldDef<Row = any, V = unknown> {\n // identity\n name: string; // canonical id; matches the backend binding key + Where/OrderBy `field`\n label: string;\n type: FieldType;\n\n // WHAT KIND of field (value origin + server capability)\n source: FieldSource<Row, V>;\n\n // capabilities (declarative config; omit for sensible per-source defaults)\n filter?: FilterConfig;\n sort?: SortConfig;\n select?: SelectConfig;\n aggregate?: AggregateConfig;\n\n // discovery (picker UX, declarative)\n group?: string; // grouping bucket\n alias?: string; // single alternative search term\n aliases?: string[]; // extra search terms\n\n /** Declarative built-in presentation, independent of the query's field type.\n * An explicit render function or registered render key takes precedence. */\n display?: CellDisplay;\n // custom presentation: registry key or inline fn\n render?: string | CellRenderer<Row, V>;\n property?: PropertyFieldConfig;\n /** Structured provenance for relationship discovery; never SQL text. */\n origin?: FieldOrigin;\n relationship?: FieldRelationship;\n}\n\n/** The frontend's loaded schema for one dataset. */\nexport interface FieldSchema<Row = any> {\n /** Dataset id, also the StorageAdapter namespace for saved queries. */\n name: string;\n /** Field that yields a row's stable id for selection / per-row refresh. */\n idField: string;\n fields: FieldDef<Row>[];\n /** Sort applied when QueryState.orderBy is empty. */\n defaultSort?: OrderByClause[];\n /** Columns shown when QueryState.select is empty. */\n defaultSelect?: SelectColumn[];\n /** Page size for a fresh query. */\n defaultLimit?: number;\n}\n\n// ---- derived capability helpers (the per-source defaults, in one place) ----\n\nexport function isFilterable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return false;\n return f.filter?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isPushdownFilter(f: FieldDef): boolean {\n return isFilterable(f) && (f.filter?.pushdown ?? f.source.kind === \"backend\");\n}\nexport function isSortable(f: FieldDef): boolean {\n if (f.source.kind === \"derived\" && f.source.computedId) return f.sort?.enabled === true;\n return f.sort?.enabled ?? f.source.kind === \"backend\";\n}\nexport function isSelectable(f: FieldDef): boolean {\n return f.select?.enabled ?? true;\n}\nexport function filterValues(f: FieldDef): FilterValues {\n return f.filter?.values ?? { source: \"autocomplete\" };\n}\n\n// ---- schema operations ----------------------------------------------------\n\n/** Index fields by name for O(1) lookup. */\nexport function indexFields<Row>(schema: FieldSchema<Row>): Map<string, FieldDef<Row>> {\n return new Map(schema.fields.map((f) => [f.name, f]));\n}\n\n/** Resolve the ordered, selectable FieldDefs for a query, falling back to schema\n * defaults, then to every `select.default` field. Unknown/duplicate/unselectable\n * names in `select` are dropped. */\nexport function selectedFields<Row>(\n schema: FieldSchema<Row>,\n q: { select: SelectColumn[] },\n): FieldDef<Row>[] {\n const order =\n q.select.length > 0\n ? q.select.map((c) => c.field)\n : (schema.defaultSelect ?? schema.fields.filter((f) => f.select?.default).map((f) => ({ field: f.name }))).map(\n (c) => c.field,\n );\n const seen = new Set<string>();\n const out: FieldDef<Row>[] = [];\n for (const name of order) {\n if (seen.has(name)) continue;\n const f = resolveField(schema, name);\n if (!f || !isSelectable(f)) continue;\n seen.add(name);\n seen.add(f.name);\n out.push(f);\n }\n return out;\n}\n\n/** Resolve a field token to a concrete field by canonical name, case-insensitive\n * name match, or alias match. */\nexport function resolveField<Row>(schema: FieldSchema<Row>, field: string): FieldDef<Row> | undefined {\n const token = field.trim();\n if (!token) return undefined;\n\n const byName = indexFields(schema);\n const byExactName = byName.get(token);\n if (byExactName) return byExactName;\n\n const needle = token.toLowerCase();\n for (const f of schema.fields) {\n if (f.name.toLowerCase() === needle) return f;\n if (aliasMatches(f, needle)) return f;\n }\n return undefined;\n}\n\n/** Return the canonical name for a query token, or undefined when unresolved. */\nexport function resolveFieldName<Row>(schema: FieldSchema<Row>, field: string): string | undefined {\n return resolveField(schema, field)?.name;\n}\n\n/** All configured aliases for a field (deduped, preserving display shape). */\nexport function aliasTermsFor<Row>(field: FieldDef<Row>): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n out.push(value);\n };\n\n add(field.alias);\n if (field.aliases) {\n for (const alias of field.aliases) add(alias);\n }\n\n return out;\n}\n\nfunction aliasMatches(field: FieldDef, needle: string): boolean {\n for (const alias of aliasTermsFor(field)) {\n if (alias.toLowerCase() === needle) return true;\n }\n return false;\n}\n\n/** Read a field's value from a row: derived `accessor` if present, else the\n * backend `path` (dotted) / `name`. Returns null when any path segment is missing. */\nexport function readFieldValue<Row, V = unknown>(field: FieldDef<Row, V>, row: Row): V | null {\n if (row == null) return null;\n if (field.source.kind === \"derived\" && field.source.accessor) {\n return field.source.accessor(row);\n }\n const path = (field.source.kind === \"backend\" && field.source.path) || field.name;\n const r = row as Record<string, unknown>;\n if (path in r) return (r[path] ?? null) as V | null;\n let cur: unknown = row;\n for (const part of path.split(\".\")) {\n if (cur == null || typeof cur !== \"object\") return null;\n cur = (cur as Record<string, unknown>)[part];\n }\n return (cur ?? null) as V | null;\n}\n\n/** Parse + validate a raw JSON schema document into a FieldSchema. The doc is the\n * same one the Go backend loads; here we drop backend `bindings` (the frontend\n * never sees SQL) and leave `render` as a string key the consumer maps to a\n * renderer at runtime. Throws with a readable message on a malformed document. */\nexport function loadSchema<Row = any>(doc: unknown): FieldSchema<Row> {\n const d = doc as Record<string, any>;\n if (!d || typeof d !== \"object\") throw new Error(\"schema: document is not an object\");\n if (typeof d.name !== \"string\") throw new Error(\"schema: missing `name`\");\n if (typeof d.idField !== \"string\") throw new Error(\"schema: missing `idField`\");\n if (!Array.isArray(d.fields) || d.fields.length === 0) throw new Error(\"schema: `fields` must be a non-empty array\");\n\n const fields: FieldDef<Row>[] = d.fields.map((raw: any, i: number) => projectField<Row>(raw, i));\n return {\n name: d.name,\n idField: d.idField,\n fields,\n defaultSort: d.defaultSort,\n defaultSelect: d.defaultSelect,\n defaultLimit: d.defaultLimit,\n };\n}\n\nfunction projectField<Row>(raw: any, i: number): FieldDef<Row> {\n if (!raw || typeof raw.name !== \"string\") throw new Error(`schema: field[${i}] missing \\`name\\``);\n if (typeof raw.label !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`label\\``);\n if (typeof raw.type !== \"string\") throw new Error(`schema: field ${raw.name} missing \\`type\\``);\n if (raw.property !== undefined) {\n const property = raw.property;\n if (!property || typeof property !== \"object\" || Array.isArray(property)\n || (property.enabled !== undefined && typeof property.enabled !== \"boolean\")\n || (property.default !== undefined && typeof property.default !== \"boolean\")\n || (property.render !== undefined && (typeof property.render !== \"string\" || !property.render))) {\n throw new Error(`schema: field ${raw.name} has invalid property metadata`);\n }\n if (property.format !== undefined && !normalizePropertyFormat(property.format)) {\n throw new Error(`schema: field ${raw.name} has an invalid property format`);\n }\n }\n if (raw.origin !== undefined && (!raw.origin\n || typeof raw.origin.table !== \"string\" || !raw.origin.table\n || typeof raw.origin.column !== \"string\" || !raw.origin.column)) {\n throw new Error(`schema: field ${raw.name} has an invalid origin`);\n }\n if (raw.relationship !== undefined && (!raw.relationship\n || typeof raw.relationship.objectType !== \"string\" || !raw.relationship.objectType\n || !raw.relationship.key || typeof raw.relationship.key !== \"object\"\n || Array.isArray(raw.relationship.key) || Object.keys(raw.relationship.key).length === 0\n || Object.entries(raw.relationship.key).some(([key, value]) => !key || typeof value !== \"string\" || !value))) {\n throw new Error(`schema: field ${raw.name} has an invalid relationship`);\n }\n\n // `source` accepts a string shorthand (\"backend\"|\"derived\") or an object.\n const rs = raw.source ?? (raw.bindings ? \"backend\" : \"derived\");\n let source: FieldSource<Row>;\n if (typeof rs === \"string\") {\n source = rs === \"derived\" ? { kind: \"derived\" } : { kind: \"backend\" };\n } else if (rs.kind === \"derived\") {\n source = { kind: \"derived\" }; // accessor is code → attached at runtime, never from JSON\n } else {\n source = { kind: \"backend\", path: rs.path, synthetic: rs.synthetic };\n }\n\n return {\n name: raw.name,\n label: raw.label,\n type: raw.type,\n source,\n filter: raw.filter,\n sort: raw.sort,\n select: raw.select,\n aggregate: raw.aggregate,\n group: raw.group,\n alias: raw.alias,\n aliases: normalizeAliases(raw.aliases, raw.alias),\n ...(raw.display === undefined ? {} : { display: parseCellDisplay(raw.display, `schema: field ${raw.name} display`) }),\n render: raw.render, // string key from JSON; consumer may override with a fn\n property: raw.property ? { ...raw.property, format: raw.property.format === undefined ? undefined : normalizePropertyFormat(raw.property.format) } : undefined,\n origin: raw.origin,\n relationship: raw.relationship,\n };\n}\n\nfunction normalizeAliases(rawAliases: unknown, rawAlias: unknown): string[] {\n const aliases: string[] = [];\n const seen = new Set<string>();\n const add = (raw: unknown) => {\n if (typeof raw !== \"string\") return;\n const value = raw.trim();\n if (!value) return;\n const key = value.toLowerCase();\n if (seen.has(key)) return;\n seen.add(key);\n aliases.push(value);\n };\n\n add(rawAlias);\n if (Array.isArray(rawAliases)) {\n for (const item of rawAliases) add(item);\n }\n return aliases;\n}\n","import { readFieldValue, type FieldSchema } from \"./schema\";\nimport type { RowId } from \"./query\";\n\n/** Literal templates only: substitution never evaluates code or nested paths. */\nexport function itemPageFields(template: string): string[] {\n return [...new Set(Array.from(template.matchAll(/\\{field:([^{}]+)\\}/g), match => match[1]!))];\n}\nexport function validateItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>): string | null {\n if (template.length > 8000) return \"Use a URL template of at most 8,000 characters.\";\n if (!template.trim()) return null;\n const remainder = template.replace(/\\{(id|query|field:[^{}]+)\\}/g, \"value\");\n if (/[{}]/.test(remainder)) return \"Use {id}, {query}, or {field:field_name} placeholders.\";\n for (const name of itemPageFields(template)) {\n if (!schema.fields.some(field => field.name === name)) return `Unknown URL field: ${name}.`;\n }\n try {\n if (![\"http:\", \"https:\"].includes(new URL(remainder, \"https://query-table.invalid/\").protocol))\n return \"Use an HTTP, HTTPS, or relative page URL.\";\n } catch { return \"Enter a valid page URL.\"; }\n return null;\n}\nexport function renderItemPageTemplate<Row>(template: string, schema: FieldSchema<Row>, row: Row, id: RowId | null, query: string): string | null {\n if (!template.trim() || validateItemPageTemplate(template, schema)) return null;\n let missing = false;\n const href = template.replace(/\\{(id|query|field:[^{}]+)\\}/g, (_match, token: string) => {\n const value = token === \"id\" ? id : token === \"query\" ? query\n : readFieldValue(schema.fields.find(field => field.name === token.slice(6))!, row);\n if (value == null || ![\"string\", \"number\", \"boolean\"].includes(typeof value)) { missing = true; return \"\"; }\n return encodeURIComponent(String(value));\n });\n // Validate again after substitution: a placeholder cannot introduce a scheme.\n try {\n if (missing || ![\"http:\", \"https:\"].includes(new URL(href, \"https://query-table.invalid/\").protocol)) return null;\n } catch { return null; }\n return href;\n}\n","import type { AggregationClause } from \"./query\";\n/** Whitelist every nested property: URL/storage objects never become executable plans. */\nexport function normalizeMetricOptions(\n raw: Record<string, unknown>,\n): Partial<AggregationClause> {\n const out: Record<string, unknown> = {},\n diagnostics: string[] = [];\n const record = (x: unknown): x is Record<string, unknown> =>\n !!x && typeof x === \"object\" && !Array.isArray(x);\n const copy = (\n input: Record<string, unknown>,\n specs: Record<\n string,\n readonly string[] | \"string\" | \"boolean\" | \"integer\" | \"positiveInteger\" | \"number\"\n >,\n ): Record<string, unknown> => {\n const result: Record<string, unknown> = {};\n for (const [key, spec] of Object.entries(specs)) {\n const v = input[key];\n if (v === undefined) continue;\n if (\n spec === \"string\"\n ? typeof v === \"string\" && v.length <= 10000\n : spec === \"number\"\n ? typeof v === \"number\" && Number.isFinite(v)\n : spec === \"boolean\"\n ? typeof v === \"boolean\"\n : spec === \"integer\" || spec === \"positiveInteger\"\n ? typeof v === \"number\" &&\n Number.isSafeInteger(v) &&\n v >= (spec === \"positiveInteger\" ? 1 : 0) &&\n v <= 1000000\n : typeof v === \"string\" && spec.includes(v)\n )\n result[key] = v;\n else diagnostics.push(`Invalid metric ${key}.`);\n }\n return result;\n };\n Object.assign(\n out,\n copy(raw, {\n expression: \"string\",\n expressionY: \"string\",\n scope: [\"allMatching\", \"shownRows\"],\n groupLimit: \"integer\",\n }),\n );\n if (raw.dateGrouping !== undefined) {\n if (record(raw.dateGrouping)) {\n const d = copy(raw.dateGrouping, {\n field: \"string\",\n interval: [\"hour\", \"day\", \"week\", \"month\", \"year\"],\n timeZone: \"string\",\n includeEmpty: \"boolean\",\n range: [\"query\", \"observed\", \"custom\"],\n start: \"string\",\n end: \"string\",\n });\n if (\n typeof d.field !== \"string\" ||\n !d.field ||\n d.field.length > 256 ||\n !d.interval ||\n typeof d.includeEmpty !== \"boolean\" ||\n !d.range\n )\n diagnostics.push(\"Invalid metric date grouping.\");\n out.dateGrouping = d;\n } else diagnostics.push(\"Invalid metric date grouping.\");\n }\n if (raw.display !== undefined) {\n if (record(raw.display)) {\n if (typeof raw.display.kind !== \"string\")\n diagnostics.push(\"Invalid metric display kind.\");\n const d = copy(raw.display, {\n kind: [\n \"auto\",\n \"value\",\n \"table\",\n \"list\",\n \"bar-horizontal\",\n \"bar-vertical\",\n \"line\",\n \"pie\",\n \"donut\",\n \"scatter\",\n \"box\",\n \"histogram\",\n ],\n valueLabel: \"string\",\n xLabel: \"string\",\n yLabel: \"string\",\n legendPosition: [\"left\", \"right\", \"top\", \"bottom\", \"none\"],\n maxGroups: \"positiveInteger\",\n showOther: \"boolean\",\n boxMean: \"boolean\",\n });\n for (const k of [\"xScale\", \"yScale\"]) {\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], {\n mode: [\"linear\", \"log\"],\n min: \"number\",\n max: \"number\",\n });\n else if (raw.display[k] !== undefined)\n diagnostics.push(`Invalid metric ${k}.`);\n }\n for (const k of [\"format\", \"xFormat\", \"yFormat\"])\n if (record(raw.display[k]))\n d[k] = copy(raw.display[k], {\n kind: [\"number\", \"percent\", \"duration\", \"date\", \"time\", \"datetime\"],\n decimals: \"integer\",\n sourceUnit: [\n \"milliseconds\",\n \"seconds\",\n \"minutes\",\n \"hours\",\n \"days\",\n \"iso\",\n \"epochSeconds\",\n \"epochMilliseconds\",\n \"secondsOfDay\",\n \"millisecondsOfDay\",\n ],\n style: [\"human\", \"long\", \"clock\", \"custom\", \"iso\"],\n pattern: \"string\",\n timeZone: \"string\",\n });\n if (record(raw.display.list))\n d.list = copy(raw.display.list, {\n showBars: \"boolean\",\n useGroupColors: \"boolean\",\n showValues: \"boolean\",\n barPosition: [\"inline\", \"below\"],\n maxLabelLines: \"positiveInteger\",\n });\n if (record(raw.display.pivot))\n d.pivot = copy(raw.display.pivot, {\n swap: \"boolean\",\n rowDir: [\"asc\", \"desc\"],\n columnDir: [\"asc\", \"desc\"],\n });\n out.display = { kind: \"auto\", ...d };\n } else diagnostics.push(\"Invalid metric display.\");\n }\n if (raw.distribution !== undefined) {\n if (record(raw.distribution))\n out.distribution = copy(raw.distribution, {\n kind: [\"box\", \"histogram\"],\n input: \"string\",\n whiskers: [\"minmax\", \"tukey\"],\n bins: \"integer\",\n });\n else diagnostics.push(\"Invalid metric distribution.\");\n }\n if (record(raw.layout)) {\n const l = copy(raw.layout, {\n widthRem: \"integer\",\n heightRem: \"integer\",\n minWidthRem: \"integer\",\n minHeightRem: \"integer\",\n });\n for (const k of [\"widthRem\", \"heightRem\", \"minWidthRem\", \"minHeightRem\"])\n l[k] = Math.max(1, Math.min(1000, Number(l[k] ?? 1)));\n l.widthRem = Math.max(Number(l.widthRem), Number(l.minWidthRem));\n l.heightRem = Math.max(Number(l.heightRem), Number(l.minHeightRem));\n out.layout = l;\n }\n if (raw.sort !== undefined && !Array.isArray(raw.sort))\n diagnostics.push(\"Invalid metric sort.\");\n if (Array.isArray(raw.sort))\n out.sort = raw.sort.slice(0, 20).flatMap((s) => {\n if (\n !record(s) ||\n typeof s.key !== \"string\" ||\n !/^(value|y|count|samples|group(?:0|[1-9][0-9]?))$/.test(s.key) ||\n ![\"asc\", \"desc\"].includes(String(s.dir))\n ) {\n diagnostics.push(\"Invalid metric sort.\");\n return [];\n }\n return [\n copy(s, {\n key: [s.key],\n dir: [\"asc\", \"desc\"],\n nulls: [\"first\", \"last\"],\n }),\n ];\n });\n if (Array.isArray(raw.diagnostics))\n diagnostics.push(\n ...raw.diagnostics\n .filter((s): s is string => typeof s === \"string\" && s.length <= 1000)\n .slice(0, 20),\n );\n if (diagnostics.length) out.diagnostics = [...new Set(diagnostics)];\n return out as Partial<AggregationClause>;\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\nimport type { MetricDisplay, MetricLayout, MetricDistribution, MetricSort, MetricScope, MetricDateGrouping } from \"./metricTypes\";\nimport { normalizeMetricOptions } from \"./metricNormalize\";\nimport type { GroupingState, SummaryColumn, RepresentativeOrder } from \"./grouping\";\n// query.ts — the canonical query state shape.\n//\n// We lean into SQL vocabulary at every layer (per design feedback): a QueryState\n// reads top-to-bottom like the statement it compiles to —\n//\n// SELECT <select> WHERE <where> ORDER BY <orderBy> LIMIT <limit> OFFSET <offset>\n//\n// Both \"what data\" (where/orderBy/limit/offset) and \"how viewed\" (select +\n// per-column width) can be serialized together when a consumer explicitly opts\n// into URL synchronization.\n\n/** All filter operators across both source projects, unioned. Every value can\n * be NULL, so `is_null`/`is_not_null` are valid for every field type. */\nexport type FilterOp =\n // comparison — number / datetime (and =,!= for any scalar)\n | \"=\"\n | \"!=\"\n | \">\"\n | \">=\"\n | \"<\"\n | \"<=\"\n // text matching\n | \"contains\"\n | \"starts_with\"\n | \"ends_with\"\n | \"matches_regex\"\n | \"not_matches_regex\"\n | \"length_gt\"\n | \"length_lt\"\n | \"length_eq\"\n // array (textarray) containment\n | \"includes\"\n // nullity — valid for EVERY type; for arrays, \"empty\" vs \"non-empty\"\n | \"is_null\"\n | \"is_not_null\";\n\n/** A single filter predicate (a \"literal\" in CNF terms). `value` is always the\n * raw string the UI captured; coercion to number/bool/date happens at\n * apply/compile time based on the field's declared type (never on the value's\n * runtime shape). Datetime comparisons also accept signed duration offsets\n * such as \"-1h\" or \"+8d2h10m\", resolved relative to execution time.\n * Unused for the nullary ops (`is_null`/`is_not_null`).\n *\n * `negated` wraps the predicate in a logical NOT. It is only ever set for ops\n * that have no complementary operator (`contains`/`starts_with`/`ends_with`/\n * `includes`); ops with a complement negate by flipping the op itself (`>=`→`<`,\n * `=`→`!=`, `is_null`→`is_not_null`, `matches_regex`→`not_matches_regex`) — see\n * `negateClause` in ops.ts. NOT is null-exclusive: a NULL/empty value satisfies\n * neither the predicate nor its negation, matching `not_matches_regex`. */\nexport interface WhereClause {\n field: string; // FieldDef.name\n op: FilterOp;\n value: string;\n negated?: boolean;\n setFilter?: SetFilterMetadata;\n}\n\nexport type SetFilterMode = \"any\" | \"all\" | \"none\" | \"empty\";\n\n/** Presentation-only identity; execution always uses the accompanying predicates. */\nexport interface SetFilterMetadata {\n id: string;\n mode: SetFilterMode;\n values: string[];\n}\n\n/** A disjunction of predicates — the inner OR of conjunctive normal form. Every\n * member is a plain literal; nesting is intentionally not allowed yet (CNF\n * only), but the object shape leaves room to grow. */\nexport interface OrGroup {\n any: WhereClause[];\n setFilter?: SetFilterMetadata;\n}\n\n/** One conjunct of the WHERE clause: either a single predicate or an OR group.\n * `QueryState.where` is the AND of these terms, so the whole WHERE is\n * conjunctive normal form — `(a) AND (b OR c) AND (d)`. A bare literal is\n * equivalent to a one-element OR group; normalization flattens singleton groups\n * back to a literal so equality/encoding stay canonical. */\nexport type WhereTerm = WhereClause | OrGroup;\n\n/** Narrow a term to an OR group. A literal always carries `field`; a group never\n * does and always carries an `any` array. */\nexport function isOrGroup(term: WhereTerm): term is OrGroup {\n return Array.isArray((term as OrGroup).any);\n}\n\n/** The predicate literals a term contributes, in order: the term itself for a\n * literal, or its members for a group. Handy for anything that must visit every\n * predicate regardless of grouping (field allowlisting, SELECT projection). */\nexport function predicatesOf(term: WhereTerm): WhereClause[] {\n return isOrGroup(term) ? term.any : [term];\n}\n\n/** One ORDER BY term. Array order in `QueryState.orderBy` is the sort priority. */\nexport interface OrderByClause {\n field: string; // FieldDef.name (server may sort a different expr via FieldDef.sort.field)\n dir: \"asc\" | \"desc\";\n /** NULL placement. Omitted = \"last\" (the historical default both projects used,\n * preserved so old `?q=` links round-trip identically). */\n nulls?: \"first\" | \"last\";\n /** Sort by the first capture group of a regex match (or by the whole match\n * when the pattern has no capture group). A non-match produces NULL. Regex\n * syntax is interpreted by the executor (JavaScript locally, PostgreSQL on\n * the bundled Go backend), so portable patterns should use their common\n * syntax subset. */\n extract?: { regex: string };\n}\n\n/** One column in the SELECT list, plus the view state that travels with it.\n * Order in `QueryState.select` is the left-to-right display order. */\nexport interface SelectColumn {\n field: string; // FieldDef.name, or @computed/<id> (source lives in ComputedColumnStore)\n /** Pixel width override. Omitted = FieldDef.select.width, else the type default. */\n width?: number;\n}\n\n/** A single aggregate operation. `count` is the only op that needs no measure\n * column (it counts rows); the rest reduce one column's values. The server-side\n * matrix (backends/go aggOpAllowed + the TS AGG_OPS_BY_TYPE) decides which ops a\n * field's type permits. */\nexport type AggOp = \"count\" | \"count_distinct\" | \"sum\" | \"avg\" | \"min\" | \"max\";\n\n/** One optional \"metric\" pinned above the table: a single aggregate over a single\n * measure column, optionally broken down by one or more group columns.\n *\n * Scope is deliberately the *whole filtered set* — the same WHERE as the table,\n * but NOT its ORDER BY / LIMIT / OFFSET. It is always evaluated on the server\n * (a real GROUP BY), so it reflects every matching row, not just the visible\n * page. Lives inside QueryState so it round-trips through `?q=`, saved queries,\n * and undo/redo for free — a saved query is a saved dashboard. */\nexport interface AggregationClause {\n dateGrouping?: MetricDateGrouping;\n expression?: string;\n expressionY?: string;\n scope?: MetricScope;\n sort?: MetricSort[];\n groupLimit?: number;\n display?: MetricDisplay;\n layout?: MetricLayout;\n distribution?: MetricDistribution;\n diagnostics?: string[];\n /** Preserved source operation when this client does not implement it. */\n unsupportedOp?: string;\n /** Stable id; keys the metric panel and survives a `?q=` round-trip. */\n id: string;\n op: AggOp;\n /** Measure column (FieldDef.name). Omit only for `count` (⇒ COUNT(*)). */\n field?: string;\n /** Group-by columns, in axis order. `[]` = a single grand-total value.\n * One ⇒ a list/bar breakdown; two ⇒ an x/y pivot; three+ ⇒ a flat table. */\n groupBy: string[];\n /** Panel header override; defaults to a derived label like \"avg total\". */\n label?: string;\n}\n\n/** Detail affordances are presentation state, never backend SELECT fields. */\nexport type ItemPropertyMode = \"hover\" | \"modal\" | \"expand\";\nexport type ItemDetailMode = ItemPropertyMode | \"page\";\nexport interface ItemPageOptions {\n /** Empty uses the current page with the item modal and query state. */\n urlTemplate: string;\n target: \"_blank\" | \"_self\";\n}\n/** Reserved presentation column; never sent to a data source. */\nexport const ITEM_DETAILS_COLUMN = \"__qt_item_details__\";\nexport interface ItemDetailsState {\n modes: ItemDetailMode[];\n /** A self-contained view travels with shared links; saved-view IDs are device-local. */\n view?: PropertyViewState;\n /** Independent layouts for each modality. Legacy view is the fallback. */\n views?: Partial<Record<ItemPropertyMode, PropertyViewState>>;\n page?: ItemPageOptions;\n active?: { id: RowId; mode: \"modal\" | \"expand\" };\n}\n\nexport interface QueryState {\n /** Optional row-producing stage. `grouping.source` is the original record\n * query (its WHERE runs first). This query selects/filters/sorts the groups;\n * its `where` therefore represents HAVING. Only one stage is supported. */\n grouping?: GroupingState;\n itemDetails?: ItemDetailsState;\n /** Ordered SELECT list + per-column widths. Empty = the schema's default columns. */\n select: SelectColumn[];\n /** Refit columns to each viewer's table viewport after loading. Manual width\n * changes clear this view preference; omitted/false uses stored widths. */\n fitToScreen?: boolean;\n /** WHERE in conjunctive normal form: the AND of these terms, each a single\n * predicate or an OR group. A flat list of literals (no groups) is the common\n * case and the legacy shape, decoded unchanged. */\n where: WhereTerm[];\n /** Multi-sort terms in priority order. Empty = the schema's default sort. */\n orderBy: OrderByClause[];\n /** Page size. */\n limit: number;\n /** Page offset (rows). */\n offset: number;\n /** Optional aggregate metrics shown above the table. Omitted/empty = none.\n * Each runs as its own server GROUP BY over the WHERE-filtered set (no paging). */\n aggregations?: AggregationClause[];\n}\n\n/** A row's stable identity, used for selection and per-row refresh. */\nexport type RowId = string | number;\n\n/** The query a fresh table starts from before schema defaults are layered on.\n * Empty `select`/`orderBy`/`where` mean \"defer to the schema\", which also keeps\n * encoded `?q=` tokens short (defaults are omitted). */\nexport const EMPTY_QUERY: QueryState = {\n select: [],\n where: [],\n orderBy: [],\n limit: 100,\n offset: 0,\n};\n\n/** Structural limits applied whenever query state crosses a trust boundary\n * (URL, storage, an imperative setQuery call, or a server projection). Row\n * limits may use the full safe-integer range; consumers and their backends own\n * any smaller operational cap appropriate for their dataset. */\nexport const MAX_QUERY_LIMIT = Number.MAX_SAFE_INTEGER;\nexport const MAX_QUERY_OFFSET = 1_000_000;\nexport const MAX_SELECT_COLUMNS = 200;\nexport const MAX_WHERE_CLAUSES = 100;\nexport const MAX_ORDER_BY_TERMS = 20;\nexport const MAX_AGGREGATIONS = 20;\nexport const MAX_GROUP_BY_FIELDS = 20;\nexport const MAX_QUERY_TOKEN_LENGTH = 2 * 1024 * 1024;\n\nconst MAX_FIELD_NAME_LENGTH = 256;\nconst MAX_FILTER_VALUE_LENGTH = 10_000;\nconst MAX_LABEL_LENGTH = 1_000;\nconst MIN_COLUMN_WIDTH = 24;\nconst MAX_COLUMN_WIDTH = 2_000;\n\nconst FILTER_OPS: ReadonlySet<string> = new Set([\n \"=\",\n \"!=\",\n \">\",\n \">=\",\n \"<\",\n \"<=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n \"includes\",\n \"is_null\",\n \"is_not_null\",\n]);\n\nconst AGG_OPS: ReadonlySet<string> = new Set([\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"]);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value != null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction boundedString(value: unknown, maxLength: number): string | null {\n return typeof value === \"string\" && value.length > 0 && value.length <= maxLength ? value : null;\n}\n\nfunction boundedInteger(value: unknown, fallback: number, min: number, max: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value)) return fallback;\n return Math.max(min, Math.min(max, Math.round(value)));\n}\n\n/** Validate one raw predicate into a bounded WhereClause, or null if malformed.\n * Shared by top-level literals and the members of an OR group. */\nfunction normalizeWhereClause(item: unknown): WhereClause | null {\n if (!isRecord(item)) return null;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const value = typeof item.value === \"string\" && item.value.length <= MAX_FILTER_VALUE_LENGTH ? item.value : null;\n if (!field || typeof item.op !== \"string\" || !FILTER_OPS.has(item.op) || value == null) {\n return null;\n }\n const clause: WhereClause = { field, op: item.op as FilterOp, value };\n if (item.negated === true) clause.negated = true;\n return clause;\n}\n\n/** Deep-clone one WHERE term (literal or group) so a normalized/fallback state\n * never aliases the caller's arrays. */\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 normalizeSetFilter(item: unknown): SetFilterMetadata | undefined {\n if (!isRecord(item)) return undefined;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id || ![\"any\", \"all\", \"none\", \"empty\"].includes(String(item.mode)) || !Array.isArray(item.values)) return undefined;\n if (item.values.length > MAX_WHERE_CLAUSES || !item.values.every((value) => typeof value === \"string\" && value.length <= MAX_FILTER_VALUE_LENGTH)) return undefined;\n return { id, mode: item.mode as SetFilterMode, values: [...item.values] as string[] };\n}\n\n/** Convert unknown input into a bounded, structurally valid QueryState.\n * Invalid members are dropped; invalid scalar paging values use the supplied\n * fallback. This function is intentionally schema-agnostic—field allowlisting\n * still happens in toServerQuery and in the backend compiler. */\nexport function normalizeQueryState(input: unknown, fallback: QueryState = EMPTY_QUERY): QueryState {\n const raw = isRecord(input) ? input : {};\n\n const select: SelectColumn[] = [];\n if (Array.isArray(raw.select)) {\n for (const item of raw.select.slice(0, MAX_SELECT_COLUMNS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field) continue;\n const column: SelectColumn = { field };\n if (typeof item.width === \"number\" && Number.isFinite(item.width)) {\n column.width = boundedInteger(item.width, MIN_COLUMN_WIDTH, MIN_COLUMN_WIDTH, MAX_COLUMN_WIDTH);\n }\n select.push(column);\n }\n } else {\n select.push(...fallback.select.map((column) => ({ ...column })));\n }\n\n // WHERE is CNF: an array of terms, each a literal or an `{ any: [...] }` OR\n // group. MAX_WHERE_CLAUSES bounds the TOTAL predicate count across all terms\n // (legacy flat lists are all literals, so the cap is unchanged for them).\n // Singleton/empty groups are canonicalized (flattened / dropped).\n const where: WhereTerm[] = [];\n if (Array.isArray(raw.where)) {\n let literalBudget = MAX_WHERE_CLAUSES;\n for (const item of raw.where) {\n if (literalBudget <= 0) break;\n const start = where.length;\n if (isRecord(item) && Array.isArray((item as { any?: unknown }).any)) {\n const members: WhereClause[] = [];\n for (const inner of (item as { any: unknown[] }).any) {\n if (literalBudget <= 0) break;\n const clause = normalizeWhereClause(inner);\n if (clause) {\n members.push(clause);\n literalBudget--;\n }\n }\n if (members.length === 1) where.push(members[0]!);\n else if (members.length > 1) where.push({ any: members });\n // 0 members → drop the term entirely\n } else {\n const clause = normalizeWhereClause(item);\n if (clause) {\n where.push(clause);\n literalBudget--;\n }\n }\n if (where.length > start && isRecord(item)) {\n const metadata = normalizeSetFilter(item.setFilter);\n if (metadata) where[start]!.setFilter = metadata;\n }\n }\n } else {\n where.push(...fallback.where.map(cloneWhereTerm));\n }\n\n const orderBy: OrderByClause[] = [];\n if (Array.isArray(raw.orderBy)) {\n for (const item of raw.orderBy.slice(0, MAX_ORDER_BY_TERMS)) {\n if (!isRecord(item)) continue;\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n if (!field || (item.dir !== \"asc\" && item.dir !== \"desc\")) continue;\n const term: OrderByClause = { field, dir: item.dir };\n if (item.nulls === \"first\" || item.nulls === \"last\") term.nulls = item.nulls;\n if (\n isRecord(item.extract) &&\n typeof item.extract.regex === \"string\" &&\n item.extract.regex.length <= MAX_FILTER_VALUE_LENGTH\n ) {\n term.extract = { regex: item.extract.regex };\n }\n orderBy.push(term);\n }\n } else {\n orderBy.push(\n ...fallback.orderBy.map((term) => (term.extract ? { ...term, extract: { ...term.extract } } : { ...term })),\n );\n }\n\n const out: QueryState = {\n select,\n where,\n orderBy,\n limit: boundedInteger(raw.limit, fallback.limit, 1, MAX_QUERY_LIMIT),\n offset: boundedInteger(raw.offset, fallback.offset, 0, MAX_QUERY_OFFSET),\n };\n\n if (raw.fitToScreen === true) out.fitToScreen = true;\n\n if (raw.grouping != null) out.grouping = normalizeGroupingState(raw.grouping);\n\n if (Array.isArray(raw.aggregations)) {\n const aggregations: AggregationClause[] = [];\n for (const item of raw.aggregations.slice(0, MAX_AGGREGATIONS)) {\n if (!isRecord(item)) continue;\n const id = boundedString(item.id, MAX_FIELD_NAME_LENGTH);\n if (!id) continue;\n const validOp = typeof item.op === \"string\" && AGG_OPS.has(item.op);\n const rawGroups: unknown[] = Array.isArray(item.groupBy) ? item.groupBy : [];\n const groupBy = rawGroups\n .slice(0, MAX_GROUP_BY_FIELDS)\n .map((field) => boundedString(field, MAX_FIELD_NAME_LENGTH))\n .filter((field): field is string => field != null);\n const aggregation: AggregationClause = { id, op: validOp ? item.op as AggOp : \"count\", groupBy };\n const field = boundedString(item.field, MAX_FIELD_NAME_LENGTH);\n const label = boundedString(item.label, MAX_LABEL_LENGTH);\n if (field) aggregation.field = field;\n if (label) aggregation.label = label;\n Object.assign(aggregation, normalizeMetricOptions(item));\n if (!Array.isArray(item.groupBy) || rawGroups.length > MAX_GROUP_BY_FIELDS || groupBy.length !== rawGroups.length) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric grouping fields or grouping budget exceeded.\"];\n const unsupportedOp = boundedString(item.unsupportedOp ?? (!validOp ? item.op : undefined), MAX_FIELD_NAME_LENGTH);\n if (unsupportedOp) aggregation.unsupportedOp = unsupportedOp;\n if (item.field !== undefined && !field) aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Invalid metric measure field.\"];\n if (!validOp && typeof item.expression !== \"string\") aggregation.diagnostics = [...(aggregation.diagnostics ?? []), \"Unsupported aggregate operation.\"];\n aggregations.push(aggregation);\n }\n if (aggregations.length > 0) out.aggregations = aggregations;\n } else if (fallback.aggregations?.length) {\n out.aggregations = normalizeQueryState({ aggregations: fallback.aggregations }).aggregations!;\n }\n\n if (isRecord(raw.itemDetails) && Array.isArray(raw.itemDetails.modes)) {\n const modes = [...new Set(raw.itemDetails.modes.filter(\n (mode): mode is ItemDetailMode => typeof mode === \"string\" && [\"hover\", \"modal\", \"expand\", \"page\"].includes(mode),\n ))];\n const details: ItemDetailsState = { modes };\n if (isRecord(raw.itemDetails.page) && typeof raw.itemDetails.page.urlTemplate === \"string\"\n && raw.itemDetails.page.urlTemplate.length <= 8000) {\n details.page = { urlTemplate: raw.itemDetails.page.urlTemplate,\n target: raw.itemDetails.page.target === \"_self\" ? \"_self\" : \"_blank\" };\n }\n if (raw.itemDetails.view !== undefined) {\n try { details.view = normalizePropertyView(raw.itemDetails.view); } catch { /* Ignore malformed view snapshots. */ }\n }\n if (isRecord(raw.itemDetails.views)) {\n const views: NonNullable<ItemDetailsState[\"views\"]> = {};\n for (const mode of [\"hover\", \"modal\", \"expand\"] as const) {\n try {\n if (raw.itemDetails.views[mode] !== undefined) views[mode] = normalizePropertyView(raw.itemDetails.views[mode]);\n } catch { /* Ignore malformed modality snapshots. */ }\n }\n if (Object.keys(views).length) details.views = views;\n }\n const active = raw.itemDetails.active;\n if (isRecord(active) && (active.mode === \"modal\" || active.mode === \"expand\") && modes.includes(active.mode)\n && ((typeof active.id === \"string\" && active.id.length > 0 && active.id.length <= 1000)\n || (typeof active.id === \"number\" && Number.isFinite(active.id)))) {\n details.active = { id: active.id as RowId, mode: active.mode };\n }\n out.itemDetails = details;\n }\n\n return out;\n}\n\n/** Retain an invalid stage as a diagnostic rather than silently executing an\n * ungrouped query. Strip nesting before normalizing the source snapshot. */\nfunction normalizeGroupingState(value: unknown): GroupingState {\n const raw = isRecord(value) ? value : {};\n const diagnostics: string[] = [];\n const fail = () => { diagnostics.push(\"Invalid grouping definition.\"); };\n const keys = Array.isArray(raw.keys) ? raw.keys.slice(0, MAX_GROUP_BY_FIELDS).filter((key): key is string => !!boundedString(key, MAX_FIELD_NAME_LENGTH)) : [];\n if (!Array.isArray(raw.keys) || !keys.length || keys.length !== raw.keys.length || new Set(keys).size !== keys.length) fail();\n const summaries: SummaryColumn[] = [];\n if (!Array.isArray(raw.summaries) || raw.summaries.length > 64) fail();\n for (const item of Array.isArray(raw.summaries) ? raw.summaries.slice(0, 64) : []) {\n if (!isRecord(item) || !boundedString(item.id, MAX_FIELD_NAME_LENGTH) || typeof item.op !== \"string\" || (!AGG_OPS.has(item.op) && item.op !== \"row\" && item.op !== \"formula\")) { fail(); continue; }\n const column: SummaryColumn = { id: item.id as string, op: item.op as SummaryColumn[\"op\"] };\n if (item.field !== undefined) {\n if (!boundedString(item.field, MAX_FIELD_NAME_LENGTH)) fail();\n else column.field = item.field as string;\n }\n if (item.op === \"formula\") {\n if (typeof item.expression !== \"string\" || item.expression.length > 10_000) fail();\n else column.expression = item.expression;\n }\n if (item.label !== undefined) {\n if (typeof item.label !== \"string\" || item.label.length > MAX_LABEL_LENGTH) fail();\n else column.label = item.label;\n }\n summaries.push(column);\n }\n let representative: GroupingState[\"representative\"] = null;\n if (raw.representative != null) {\n const ordering = isRecord(raw.representative) ? raw.representative.orderBy : undefined;\n const orderBy: RepresentativeOrder[] = [];\n if (!Array.isArray(ordering) || !ordering.length || ordering.length > 8) fail();\n for (const term of Array.isArray(ordering) ? ordering.slice(0, 8) : []) {\n if (!isRecord(term) || !boundedString(term.field, MAX_FIELD_NAME_LENGTH) || ![\"asc\", \"desc\"].includes(String(term.dir)) || (term.nulls !== undefined && ![\"first\", \"last\"].includes(String(term.nulls)))) { fail(); continue; }\n orderBy.push({ field: term.field as string, dir: term.dir as \"asc\" | \"desc\", nulls: term.nulls === \"first\" ? \"first\" : \"last\" });\n }\n representative = { orderBy };\n }\n if (!isRecord(raw.source) || raw.source.grouping != null) fail();\n const { grouping: _nested, ...source } = isRecord(raw.source) ? raw.source : {};\n if (Array.isArray(raw.diagnostics) && raw.diagnostics.length) fail();\n const normalizedSource = normalizeQueryState(source);\n if (Array.isArray(source.where)) {\n const supplied = source.where.reduce((count: number, term: unknown) => count + (isRecord(term) && Array.isArray(term.any) ? term.any.length : 1), 0);\n if (supplied !== normalizedSource.where.reduce((count, term) => count + predicatesOf(term).length, 0)) fail();\n }\n return { keys, summaries, representative, source: normalizedSource, ...(diagnostics.length ? { diagnostics: [...new Set(diagnostics)] } : {}) };\n}\n\n/** Structural equality on two queries — used to decide whether a `?q=` write or a\n * refetch is actually needed (avoids history spam / redundant fetches). */\nexport function queriesEqual(a: QueryState, b: QueryState): boolean {\n if (a === b) return true;\n if (a.limit !== b.limit || a.offset !== b.offset) return false;\n if ((a.fitToScreen === true) !== (b.fitToScreen === true)) return false;\n if (!sameArray(a.where, b.where)) return false;\n if (!sameArray(a.orderBy, b.orderBy)) return false;\n if (!sameArray(a.select, b.select)) return false;\n if (!sameArray(a.aggregations ?? [], b.aggregations ?? [])) return false;\n if (JSON.stringify(a.itemDetails) !== JSON.stringify(b.itemDetails)) return false;\n if (JSON.stringify(a.grouping) !== JSON.stringify(b.grouping)) return false;\n return true;\n}\n\nfunction sameArray<T>(a: readonly T[], b: readonly T[]): boolean {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n // Members are records of primitives (WHERE terms may nest one `any` array of\n // them) — a structural JSON compare is correct and cheap here.\n if (JSON.stringify(a[i]) !== JSON.stringify(b[i])) return false;\n }\n return true;\n}\n","const UNIT_MS: Record<string, number> = { ms: 1, s: 1000, m: 60000, h: 3600000, d: 86400000, w: 604800000 };\n/** Portable datetime/offset bound in milliseconds (also below MAX_SAFE_INTEGER). */\nexport const MAX_RELATIVE_TIME_MS = 8_640_000_000_000_000;\n\n/** A signed elapsed offset, e.g. -1h or +8d2h10m. The sign applies to the\n * complete sum. Returns null for absolute values or invalid duration syntax.\n * Units are lowercase; amounts are whole integers. No whitespace, calendar\n * arithmetic, locale, or Date.parse heuristics are used. */\nexport function parseRelativeDuration(value: string): number | null {\n const valid = /^[+-](?:[0-9]+(?:ms|s|m|h|d|w))+$/.exec(value);\n if (!valid || valid[0] !== value) return null;\n const body = value.slice(1);\n const components = /([0-9]+)(ms|s|m|h|d|w)/g;\n let total = 0;\n for (const match of body.matchAll(components)) {\n const amount = Number(match[1]);\n const unit = UNIT_MS[match[2]!]!;\n if (!Number.isSafeInteger(amount) || amount > Math.floor((MAX_RELATIVE_TIME_MS - total) / unit)) return null;\n total += amount * unit;\n }\n return value[0] === \"-\" && total !== 0 ? -total : total;\n}\n\n/** Local execution only. The server independently owns its execution clock. */\nexport interface QueryEvaluationOptions { now?: number }\n\nexport function evaluationTime(options: QueryEvaluationOptions): number {\n const now = options.now ?? Date.now();\n if (!Number.isSafeInteger(now) || Math.abs(now) > MAX_RELATIVE_TIME_MS) throw new Error(\"Invalid query evaluation time\");\n return now;\n}\n\nexport function relativeTimestamp(now: number, offsetMs: number): number {\n const result = now + offsetMs;\n if (!Number.isSafeInteger(result) || Math.abs(result) > MAX_RELATIVE_TIME_MS) throw new Error(\"Relative time exceeds datetime limits\");\n return result;\n}\n","// ops.ts — which operators a field type allows, and value coercion.\n//\n// Single source of truth for \"what filters can I build on this field\", shared by\n// the QueryBuilder UI, the CellMenu quick-filters, and client-side applyQuery.\n// The backend (backends/go) enforces the same matrix independently — never trust\n// the client.\n//\n// Every value can be NULL, so `is_null`/`is_not_null` are available on EVERY\n// type, including bool (design feedback).\n\nimport { parseRelativeDuration, relativeTimestamp } from \"./relativeTime\";\nimport type { FilterOp, FieldType, FieldDef, WhereClause } from \"./index\";\n\nconst NULLITY: FilterOp[] = [\"is_null\", \"is_not_null\"];\n\n/** Operators that are each other's logical complement. Negating one of these is\n * a clean op flip (no NULL surprises the two ops don't already share), so the\n * UI can render `≥ 10`'s negation as `< 10` rather than `NOT (≥ 10)`. Ops absent\n * here (`contains`/`starts_with`/`ends_with`/`includes`) have no single-op\n * complement and negate via the `WhereClause.negated` flag instead. */\nconst COMPLEMENT_OP: Partial<Record<FilterOp, FilterOp>> = {\n \"=\": \"!=\",\n \"!=\": \"=\",\n \">\": \"<=\",\n \"<=\": \">\",\n \">=\": \"<\",\n \"<\": \">=\",\n is_null: \"is_not_null\",\n is_not_null: \"is_null\",\n matches_regex: \"not_matches_regex\",\n not_matches_regex: \"matches_regex\",\n};\n\n/** The logical negation of a predicate. Prefers flipping to the complementary\n * operator (nicer to read, and the server's op allowlist already covers it);\n * falls back to toggling the `negated` flag when the op has no complement, or\n * when the complement is not in `allowedOps` (a field's `filter.ops` override\n * could disable it, and the server would reject a disabled op). `allowedOps`,\n * when given, is the field's effective operator set from `opsForField`. */\nexport function negateClause(clause: WhereClause, allowedOps?: readonly FilterOp[]): WhereClause {\n if (clause.value === \"0\" && !clause.negated) {\n const zeroComplement = clause.op === \"length_gt\" ? \"length_eq\" : clause.op === \"length_eq\" ? \"length_gt\" : null;\n if (zeroComplement && (!allowedOps || allowedOps.includes(zeroComplement))) {\n return { field: clause.field, op: zeroComplement, value: \"0\" };\n }\n }\n const complement = COMPLEMENT_OP[clause.op];\n if (complement && (!allowedOps || allowedOps.includes(complement))) {\n const next: WhereClause = { field: clause.field, op: complement, value: clause.value };\n return next; // a complement fully expresses the negation; drop any stale flag\n }\n const next: WhereClause = { field: clause.field, op: clause.op, value: clause.value };\n if (!clause.negated) next.negated = true;\n return next;\n}\n\n/** Whether a predicate is negative — either an op that reads as a negation\n * (`!=`, `not_matches_regex`, `is_not_null`) or one carrying the `negated`\n * flag. Used to sort candidate filters into the CellMenu's two columns. */\nexport function isNegativePredicate(clause: Pick<WhereClause, \"op\" | \"negated\">): boolean {\n return Boolean(clause.negated) || clause.op === \"!=\" || clause.op === \"not_matches_regex\" || clause.op === \"is_not_null\";\n}\n\n/** A specific operator + negation state, e.g. `{ op: \"<\", negated: false }` or\n * `{ op: \"contains\", negated: true }`. */\nexport interface OpChoice {\n op: FilterOp;\n negated: boolean;\n}\n\n/** A positive operator (\"keep\") and its logical negation (\"exclude\") — the row\n * shape rendered by both the CellMenu quick-filters and the WHERE operator\n * picker, so the two read identically. */\nexport interface OpPair {\n keep: OpChoice;\n exclude: OpChoice;\n}\n\n/** Positive operators surfaced in the \"keep\" column, in display order. Each\n * one's negation lands opposite via `negateClause`, so the pair covers\n * `<`/`<=`/`!=`/`not_matches_regex` without listing them separately. */\nconst POSITIVE_OP_ORDER: FilterOp[] = [\"=\", \">\", \">=\", \"contains\", \"starts_with\", \"ends_with\", \"length_gt\", \"length_lt\", \"length_eq\", \"matches_regex\", \"includes\"];\n\n/** The keep/exclude operator pairs offered for a field: each positive op with\n * its negation opposite, then a nullity row (`is null`/`is not null`) when the\n * field allows it. Derived from the field's effective op set and `negateClause`,\n * so a `filter.ops` override narrows the offered pairs too. */\nexport function opPairsForField(field: Pick<FieldDef, \"type\" | \"filter\">): OpPair[] {\n const ops = opsForField(field);\n const allow = new Set(ops);\n const pairs: OpPair[] = [];\n for (const op of POSITIVE_OP_ORDER) {\n if (!allow.has(op)) continue;\n const neg = negateClause({ field: \"\", op, value: \"\" }, ops);\n pairs.push({ keep: { op, negated: false }, exclude: { op: neg.op, negated: Boolean(neg.negated) } });\n }\n if (allow.has(\"is_null\") || allow.has(\"is_not_null\")) {\n pairs.push({ keep: { op: \"is_null\", negated: false }, exclude: { op: \"is_not_null\", negated: false } });\n }\n return pairs;\n}\n\n/** Default operator set per type. A FieldDef.filter.ops overrides this. */\nexport const OPS_BY_TYPE: Record<FieldType, FilterOp[]> = {\n text: [\n \"=\",\n \"!=\",\n \"contains\",\n \"starts_with\",\n \"ends_with\",\n \"matches_regex\",\n \"not_matches_regex\",\n \"length_gt\",\n \"length_lt\",\n \"length_eq\",\n ...NULLITY,\n ],\n enum: [\"=\", \"!=\", ...NULLITY],\n number: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n datetime: [\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\", ...NULLITY],\n bool: [\"=\", \"!=\", ...NULLITY],\n textarray: [\"includes\", ...NULLITY],\n};\n\n/** Operators that take no value (the value input is hidden). */\nexport const NULLARY_OPS: ReadonlySet<FilterOp> = new Set<FilterOp>(NULLITY);\n\n/** Effective operators for a field (its override, else the type default). */\nexport function opsForField(field: Pick<FieldDef, \"type\" | \"filter\">): FilterOp[] {\n return field.filter?.ops ?? OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (server mirror lives\n * in Go opAllowed; keep them in lockstep). */\nexport function opAllowedForType(type: FieldType, op: FilterOp): boolean {\n return OPS_BY_TYPE[type].includes(op);\n}\n\n/** Coerce a raw string value to the type the field expects, for client-side\n * comparison. Throws on invalid input (e.g. a non-numeric value on a number\n * field) so callers can surface it rather than silently mis-filtering. */\nexport function coerceValue(type: FieldType, raw: string, now?: number): string | number | boolean {\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n if (raw.trim() === \"\" || Number.isNaN(n)) throw new Error(`not a number: ${JSON.stringify(raw)}`);\n return n;\n }\n case \"bool\": {\n const v = raw.toLowerCase();\n if (v === \"true\" || v === \"1\" || v === \"t\") return true;\n if (v === \"false\" || v === \"0\" || v === \"f\") return false;\n throw new Error(`not a bool: ${JSON.stringify(raw)}`);\n }\n case \"datetime\": {\n if (raw.startsWith(\"+\") || raw.startsWith(\"-\")) {\n const offset = parseRelativeDuration(raw);\n if (offset === null) throw new Error(`not a signed duration: ${JSON.stringify(raw)}`);\n return relativeTimestamp(now ?? Date.now(), offset);\n }\n const ms = Date.parse(raw);\n if (Number.isNaN(ms)) throw new Error(`not a datetime: ${JSON.stringify(raw)}`);\n return ms;\n }\n default:\n return raw;\n }\n}\n","// agg.ts — which aggregate ops a field type allows, and which fields can be a\n// measure or a group-by key. The single source of truth shared by the\n// QueryBuilder's metric editor, the client-side applyAggregations, and (mirrored\n// independently in backends/go) the SQL compiler. Never trust the client: the Go\n// `aggOpAllowed` enforces the same matrix before any GROUP BY is built.\n\nimport type { AggOp } from \"./query\";\nimport type { FieldType, FieldDef } from \"./schema\";\n\n/** Default aggregate ops per field type. A FieldDef.aggregate.ops overrides this.\n * `count`/`count_distinct` work on anything countable; sum/avg are numeric-only;\n * min/max need an ordered domain (numbers, datetimes, and lexical text/enum). */\nexport const AGG_OPS_BY_TYPE: Record<FieldType, AggOp[]> = {\n number: [\"count\", \"count_distinct\", \"sum\", \"avg\", \"min\", \"max\"],\n datetime: [\"count\", \"count_distinct\", \"min\", \"max\"],\n enum: [\"count\", \"count_distinct\", \"min\", \"max\"],\n text: [\"count\", \"count_distinct\", \"min\", \"max\"],\n bool: [\"count\", \"count_distinct\"],\n textarray: [\"count\"],\n};\n\n/** Ops that reduce a measure column. `count` is the only op that may omit a\n * field (counting rows), so it's the only one absent here. */\nexport const AGG_OPS_NEEDING_FIELD: ReadonlySet<AggOp> = new Set<AggOp>([\n \"count_distinct\",\n \"sum\",\n \"avg\",\n \"min\",\n \"max\",\n]);\n\n/** Whether an op requires a measure column. */\nexport function aggOpNeedsField(op: AggOp): boolean {\n return AGG_OPS_NEEDING_FIELD.has(op);\n}\n\n/** Effective aggregate ops for a field (its override, else the type default). */\nexport function aggOpsForField(field: Pick<FieldDef, \"type\" | \"aggregate\">): AggOp[] {\n return field.aggregate?.ops ?? AGG_OPS_BY_TYPE[field.type];\n}\n\n/** Whether an op is valid for a type per the default matrix (Go aggOpAllowed is\n * the server mirror; keep them in lockstep). */\nexport function aggOpAllowedForType(type: FieldType, op: AggOp): boolean {\n return AGG_OPS_BY_TYPE[type].includes(op);\n}\n\n/** Can this field be the MEASURE of a metric? Only backend fields (they have SQL\n * to aggregate); derived/render-only columns are never pushed to the server. An\n * explicit `aggregate.measure` wins over the type default. */\nexport function isMeasurable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.measure === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.measure != null) return field.aggregate.measure;\n return aggOpsForField(field).length > 0;\n}\n\n/** Can this field be a GROUP BY key? Backend fields only. Default: low-cardinality\n * types (enum/text/bool); numbers/datetimes need bucketing (out of scope) so they\n * default off, but `aggregate.groupable: true` opts any backend field in. */\nexport function isGroupable(field: FieldDef): boolean {\n if (field.source.kind === \"derived\" && field.source.computedId) return field.aggregate?.groupable === true;\n if (field.source.kind !== \"backend\") return false;\n if (field.aggregate?.groupable != null) return field.aggregate.groupable;\n return field.type === \"enum\" || field.type === \"text\" || field.type === \"bool\";\n}\n","import type { MetricKey, MetricValue, MetricScope, MetricDistributionResult, MetricDiagnostic } from \"./metricTypes\";\nimport { deflateSync, Inflate } from \"fflate\";\nimport { createSetFilter, readSetFilter } from \"./setFilter\";\n// encode.ts — URL serialization + the server-bound query subset.\n//\n// Two distinct serializations, deliberately kept apart:\n//\n// 1. encodeQuery / decodeQuery — the *whole* QueryState (incl. view state:\n// select columns + widths) ⇄ a base64url `?q=` token. This is what makes\n// reload, back/forward, bookmarks, and \"send a coworker your view\" all work\n// (decisions #4 + #5). Defaults are omitted to keep the token short.\n//\n// 2. toServerQuery — the subset the backend acts on: pushdown\n// WHERE clauses, server-sortable ORDER BY (remapped through sort.field), the\n// page window, and the field names to SELECT (so the backend evaluates the\n// computed/synthetic columns the view needs — requested ∪ always-needed,\n// design decision #2). Per-column widths never leave the client.\n//\n// Back-compat: decodeQuery accepts legacy compact shapes: `o` as a single\n// object (pre-multi-sort) and `c`/`s` as a string[] (pre-width).\n\nimport { EMPTY_QUERY, MAX_QUERY_TOKEN_LENGTH, normalizeQueryState, predicatesOf } from \"./query\";\nimport { stripSetFilter } from \"./setFilter\";\nimport type { QueryState, WhereTerm, OrderByClause, SelectColumn, AggregationClause, SetFilterMode } from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport { indexFields, isFilterable, isPushdownFilter, isSortable, resolveFieldName, selectedFields } from \"./schema\";\n\n// ---- base64url (browser + node) -------------------------------------------\n\nfunction toBase64Url(json: string): string {\n let b64: string;\n if (typeof Buffer !== \"undefined\") {\n b64 = Buffer.from(json, \"utf8\").toString(\"base64\");\n } else {\n const bytes = new TextEncoder().encode(json);\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n b64 = btoa(bin);\n }\n return b64.replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction fromBase64Url(s: string): string {\n const b64 = s.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((s.length + 3) % 4);\n if (typeof Buffer !== \"undefined\") return Buffer.from(b64, \"base64\").toString(\"utf8\");\n const bin = atob(b64);\n const bytes = Uint8Array.from(bin, (c) => c.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n// ---- compact wire form ----------------------------------------------------\n// Keys are short to keep `?q=` small; any field at its default is omitted.\n// s = select (as [field] or [field, width] tuples)\n// w = where, o = orderBy, l = limit, f = offset\n// fs = fit to the viewer's screen\n\ninterface CompactQuery {\n s?: Array<[string] | [string, number]> | string[]; // string[] = legacy\n w?: WhereTerm[];\n o?: OrderByClause[] | OrderByClause; // object accepted for legacy decode\n l?: number;\n f?: number;\n g?: AggregationClause[]; // aggregation metrics (omitted when none)\n d?: QueryState[\"itemDetails\"];\n c?: string[]; // legacy alias for select column names\n fs?: boolean;\n b?: QueryState[\"grouping\"];\n}\n\n/** Canonical query projected into the URL wire form. */\nfunction compactQuery(q: QueryState): CompactQuery {\n q = normalizeQueryState(q);\n const c: CompactQuery = {};\n if (q.select.length)\n c.s = q.select.map((col): [string] | [string, number] => (col.width != null ? [col.field, col.width] : [col.field]));\n if (q.where.length) c.w = q.where;\n if (q.orderBy.length) c.o = q.orderBy;\n c.l = q.limit;\n if (q.offset) c.f = q.offset;\n if (q.aggregations?.length) c.g = q.aggregations;\n if (q.itemDetails) c.d = q.itemDetails;\n if (q.fitToScreen) c.fs = true;\n if (q.grouping) c.b = q.grouping;\n return c;\n}\n\nexport const MAX_QUERY_STATE_BYTES = 4 * 1024 * 1024;\nexport class QueryDecodeError extends Error {\n constructor(public readonly code: \"invalid\" | \"too_large\" | \"unsupported_version\", message: string) {\n super(message); this.name = \"QueryDecodeError\";\n }\n}\n\n// v2 keeps execution state unchanged, but represents intact set editors once.\n// Equal property layouts share one entry rather than repeating every modality.\nfunction packQuery(c: CompactQuery): Record<string, unknown> {\n const packed: Record<string, unknown> = { ...c };\n if (c.l === EMPTY_QUERY.limit) delete packed.l;\n if (c.w) {\n const terms: unknown[] = [];\n for (let i = 0; i < c.w.length; i++) {\n const set = readSetFilter(c.w, i);\n if (set) {\n terms.push([\"set\", set.field, set.metadata.mode, set.metadata.values, set.metadata.id]);\n i += set.count - 1;\n } else terms.push(c.w[i]);\n }\n packed.w = terms;\n }\n if (c.d?.views) {\n const pool: unknown[] = [];\n const refs: Record<string, number> = {};\n for (const [mode, view] of Object.entries(c.d.views)) {\n let index = pool.findIndex(v => JSON.stringify(v) === JSON.stringify(view));\n if (index < 0) { index = pool.length; pool.push(view); }\n refs[mode] = index;\n }\n packed.d = { ...c.d, views: { pool, refs } };\n }\n return packed;\n}\n\nfunction unpackQuery(c: Record<string, unknown>): CompactQuery {\n if (Array.isArray(c.w)) c.w = c.w.flatMap((term: unknown) => {\n if (!Array.isArray(term)) return [term];\n if (term.length !== 5 || term[0] !== \"set\" || typeof term[1] !== \"string\" ||\n typeof term[2] !== \"string\" || ![\"any\", \"all\", \"none\", \"empty\"].includes(term[2]) || !Array.isArray(term[3]) ||\n term[3].length > 100 || !term[3].every((v: unknown) => typeof v === \"string\" && v.length <= 10000) || typeof term[4] !== \"string\")\n throw new QueryDecodeError(\"invalid\", \"Invalid set filter in query link.\");\n return createSetFilter(term[1], term[2] as SetFilterMode, term[3] as string[], term[4]);\n });\n const details = c.d;\n const views = details && typeof details === \"object\" && \"views\" in details ? details.views : undefined;\n if (details && typeof details === \"object\" && views && typeof views === \"object\" && \"pool\" in views) {\n const pool = views.pool;\n const refs = \"refs\" in views ? views.refs : undefined;\n if (!Array.isArray(pool) || pool.length > 3 || !refs || typeof refs !== \"object\" || Array.isArray(refs))\n throw new QueryDecodeError(\"invalid\", \"Invalid property views in query link.\");\n c.d = { ...details, views: Object.fromEntries(Object.entries(refs).map(([mode, index]) => {\n if (![\"hover\", \"modal\", \"expand\"].includes(mode) || !Number.isInteger(index) || (index as number) < 0 || (index as number) >= pool.length)\n throw new QueryDecodeError(\"invalid\", \"Invalid property view reference.\");\n return [mode, pool[index as number]];\n })) };\n }\n return c as CompactQuery;\n}\n\n/** v2 JSON or raw-DEFLATE UTF-8, whichever produces the shorter URL token. */\nexport function encodeQuery(q: QueryState): string {\n const json = JSON.stringify(packQuery(compactQuery(q)));\n const bytes = new TextEncoder().encode(json);\n if (bytes.length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const plain = \"2j.\" + toBase64Url(json);\n const compressed = \"2d.\" + bytesToBase64(deflateSync(bytes));\n const token = compressed.length < plain.length ? compressed : plain;\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Encoded query state exceeds the storage limit.\");\n return token;\n}\n\nfunction bytesToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") return Buffer.from(bytes).toString(\"base64\").replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n let bin = \"\";\n for (const byte of bytes) bin += String.fromCharCode(byte);\n return btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\");\n}\n\nfunction inflateToken(token: string): string {\n const bin = atob(token.replace(/-/g, \"+\").replace(/_/g, \"/\"));\n const input = Uint8Array.from(bin, c => c.charCodeAt(0));\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n const stream = new Inflate((chunk, final) => {\n size += chunk.length;\n if (size > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Expanded query state exceeds the storage limit.\");\n chunks.push(chunk); complete = final;\n });\n // Small input chunks bound allocations before the expanded-size check.\n for (let i = 0; i < input.length; i += 256) stream.push(input.subarray(i, i + 256), i + 256 >= input.length);\n if (!complete) throw new QueryDecodeError(\"invalid\", \"Incomplete compressed query link.\");\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n}\n\n/** base64url token → QueryState. Tolerant: bad input and legacy shapes both\n * normalize to a valid QueryState (never throws). */\nexport function decodeQuery(token: string): QueryState {\n try { return decodeToken(token, false); } catch { return { ...EMPTY_QUERY }; }\n}\n\n/** Navigation uses this decoder so corrupt links cannot silently run defaults. */\nexport function decodeQueryStrict(token: string): QueryState {\n return decodeToken(token, true);\n}\nfunction decodeToken(token: string, strict: boolean): QueryState {\n if (!token) return { ...EMPTY_QUERY };\n if (token.length > MAX_QUERY_TOKEN_LENGTH) throw new QueryDecodeError(\"too_large\", \"Query link exceeds the storage limit.\");\n try {\n const versioned = token.includes(\".\");\n if (versioned && !token.startsWith(\"2j.\") && !token.startsWith(\"2d.\"))\n throw new QueryDecodeError(\"unsupported_version\", \"Unsupported query link version.\");\n const payload = versioned ? token.slice(3) : token;\n if (!/^[A-Za-z0-9_-]+$/.test(payload) || payload.length % 4 === 1) throw new QueryDecodeError(\"invalid\", \"Invalid query link encoding.\");\n const json = token.startsWith(\"2d.\") ? inflateToken(payload) : fromBase64Url(payload);\n if (new TextEncoder().encode(json).length > MAX_QUERY_STATE_BYTES) throw new QueryDecodeError(\"too_large\", \"Query state exceeds the storage limit.\");\n const raw = JSON.parse(json);\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw) || [\"w\", \"g\"].some(k => raw[k] !== undefined && !Array.isArray(raw[k])))\n throw new QueryDecodeError(\"invalid\", \"Invalid query link state.\");\n const c = versioned ? unpackQuery(raw) : raw as CompactQuery;\n if (strict && c.w) {\n if (c.w.some((term: WhereTerm) => !term || typeof term !== \"object\")) throw new QueryDecodeError(\"invalid\", \"Invalid query predicates.\");\n const count = c.w.reduce((n: number, term: WhereTerm) => n + predicatesOf(term).length, 0);\n const normalized = normalizeQueryState({ where: c.w });\n const normalizedCount = normalized.where.reduce((n, term) => n + predicatesOf(term).length, 0);\n if (count > 100 || count !== normalizedCount || c.w.some((term: WhereTerm) => predicatesOf(term).some(clause =>\n !clause || typeof clause !== \"object\" || (clause.negated !== undefined && typeof clause.negated !== \"boolean\"))))\n throw new QueryDecodeError(\"invalid\", \"Invalid query predicates or predicate budget exceeded.\");\n }\n const out = normalizeQueryState({\n select: normalizeSelect(c.s ?? c.c),\n where: Array.isArray(c.w) ? c.w : [],\n orderBy: normalizeOrderBy(c.o),\n limit: c.l,\n offset: c.f,\n aggregations: c.g,\n itemDetails: c.d,\n fitToScreen: c.fs,\n grouping: c.b,\n });\n if (strict && c.g && out.aggregations?.length !== c.g.length) throw new QueryDecodeError(\"invalid\", \"Invalid query metrics.\");\n return out;\n } catch (error) {\n if (error instanceof QueryDecodeError) throw error;\n throw new QueryDecodeError(\"invalid\", \"Invalid or incomplete query link.\");\n }\n}\n\nfunction normalizeSelect(s: CompactQuery[\"s\"] | CompactQuery[\"c\"]): SelectColumn[] {\n if (!Array.isArray(s)) return [];\n return s\n .map((item): SelectColumn | null => {\n if (typeof item === \"string\") return { field: item }; // legacy string[]\n if (Array.isArray(item) && typeof item[0] === \"string\") {\n return typeof item[1] === \"number\" ? { field: item[0], width: item[1] } : { field: item[0] };\n }\n return null;\n })\n .filter((x): x is SelectColumn => x != null);\n}\n\nfunction normalizeOrderBy(o: CompactQuery[\"o\"]): OrderByClause[] {\n if (!o) return [];\n if (Array.isArray(o)) return o;\n return [o]; // legacy single-object form → one-element array\n}\n\n// ---- server-bound subset --------------------------------------------------\n\n/** The backend request derived from a QueryState + its schema. Mirrors the Go\n * `WireQuery`. View-only state (column widths) is intentionally absent. */\nexport interface ServerQuery {\n /** field names to return — visible columns ∪ fields referenced by where/orderBy. */\n select: string[];\n /** only terms whose every predicate is on a pushdown-filterable field. */\n where: WhereTerm[];\n /** only terms on server-sortable fields, with `field` already remapped to the\n * field's server sort key (FieldDef.sort.field) when set. */\n orderBy: OrderByClause[];\n limit: number;\n offset: number;\n}\n\n/** Project a QueryState into the server request, dropping client-only filters,\n * client-only sorts, and remapping sort fields through `sort.field`. */\nexport function toServerQuery<Row>(q: QueryState, schema: FieldSchema<Row>): ServerQuery {\n if (q.grouping) throw new Error(\"This transport does not support grouped queries. Enable the v3 query executor.\");\n q = normalizeQueryState(q);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const orderBy: OrderByClause[] = [];\n for (const term of q.orderBy) {\n const field = resolveField(term.field);\n const f = byName.get(field);\n if (!f || !isSortable(f) || f.source.kind !== \"backend\") continue;\n orderBy.push({ ...term, field: f.sort?.field ?? f.name });\n }\n\n // SELECT = the BACKEND columns the response rows must carry: visible backend\n // columns, the id (for selection/refresh), and any backend column a\n // CLIENT-SIDE filter reads. Derived/render-only columns are computed on the\n // client and have no SQL to select; pushdown filters/sorts run in SQL and need\n // not be returned (design decision #2: requested ∪ always-needed).\n const select = new Set<string>(\n selectedFields(schema, q)\n .filter((f) => f.source.kind === \"backend\")\n .map((f) => f.name),\n );\n for (const field of selectedFields(schema, q)) {\n if (field.source.kind === \"derived\") {\n for (const name of field.source.dependencies ?? []) {\n if (byName.get(name)?.source.kind === \"backend\") select.add(name);\n }\n }\n }\n select.add(schema.idField);\n for (const term of q.where) {\n for (const cl of predicatesOf(term)) {\n const field = resolveField(cl.field);\n const f = byName.get(field);\n if (f && isFilterable(f) && !isPushdownFilter(f) && f.source.kind === \"backend\") select.add(field);\n }\n }\n\n return { select: [...select].sort(), where, orderBy, limit: q.limit, offset: q.offset };\n}\n\n/** A term can push down only if EVERY predicate it contains is on a\n * pushdown-filterable field. An OR group is all-or-nothing: dropping one\n * disjunct would change the set the group matches, so a group with any\n * non-pushdown member stays client-side in full. */\nfunction termIsPushdown<Row>(\n term: WhereTerm,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (name: string) => string,\n): boolean {\n return predicatesOf(term).every((cl) => {\n const f = byName.get(resolveField(cl.field));\n return f != null && isPushdownFilter(f);\n });\n}\n\n// ---- aggregation server subset --------------------------------------------\n\n/** The backend request for the metric panel. Scope is the whole filtered set:\n * the SAME pushdown WHERE as the rows query, but NO ORDER BY / LIMIT / OFFSET —\n * metrics describe every matching row, not the visible page. Mirrors the Go\n * AggSpec list. */\nexport interface AggregationRequest {\n diagnostics?: MetricDiagnostic[];\n where: WhereTerm[];\n aggregations: AggregationClause[];\n}\n\n/** One group's result. `keys` has one entry per AggregationClause.groupBy field,\n * in axis order (`[]` for a grand total); a null key is the NULL/empty bucket. */\nexport interface AggregationBucket {\n keys: MetricKey[];\n error?: string;\n y?: MetricValue;\n yError?: string;\n components?: {expression:string; value:MetricValue}[];\n nullCount?: number;\n inputErrorCount?: number;\n distribution?: MetricDistributionResult;\n /** The metric: a number for count/sum/avg, or the column's value for min/max\n * (which may be a string for text/datetime). null when undefined (e.g. avg of\n * an all-null column). */\n value: MetricValue;\n /** COUNT(*) of rows in the group — always present, even when `value` isn't a\n * count, so the panel can show group sizes / shares. */\n count: number;\n}\n\nexport interface AggregationResultEntry {\n /** Exact omitted additive quantity; unavailable for ratios/averages/distinct. */\n other?: AggregationBucket;\n error?: string;\n scope?: MetricScope;\n processedRows?: number;\n groupCount?: number;\n coverage?: \"exact\" | \"partial\";\n /** Echoes AggregationClause.id. */\n id: string;\n buckets: AggregationBucket[];\n}\n\nexport interface AggregationResult {\n /** One entry per requested aggregation, in request order. */\n metrics: AggregationResultEntry[];\n}\n\n/** Project a QueryState into the metric request: the pushdown WHERE subset (same\n * rule as toServerQuery) plus the aggregations whose measure + group fields are\n * all server-capable backend columns. Aggregations referencing a derived /\n * unknown field are dropped — the server has no SQL for them. */\nexport function toAggregationQuery<Row>(q: QueryState, schema: FieldSchema<Row>): AggregationRequest {\n if (q.grouping) throw new Error(\"Metrics over grouped rows require grouped-query execution.\");\n const suppliedPredicateCount = q.where.reduce((n,t)=>n+predicatesOf(t).length,0);\n q = normalizeQueryState(q);\n if (q.aggregations?.some(a => a.dateGrouping)) throw new Error(\"Date grouping currently requires local metric execution.\");\n if (q.aggregations?.some(a => a.diagnostics?.length || a.expression !== undefined || a.expressionY !== undefined || a.distribution || a.scope === \"shownRows\" || a.sort?.length || a.groupLimit)) throw new Error(\"Metric definition requires the version 2 metric transport.\");\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n\n const where = q.where.filter((term) => termIsPushdown(term, byName, resolveField)).map(stripSetFilter);\n\n const isBackend = (name: string | undefined): boolean => {\n if (name == null) return true; // omitted measure (count(*)) is fine\n const field = resolveField(name);\n const f = byName.get(field);\n return f != null && f.source.kind === \"backend\";\n };\n\n const aggregations = (q.aggregations ?? []).filter(\n (a) => isBackend(a.field) && a.groupBy.every((g) => isBackend(g)),\n );\n\n const diagnostics: MetricDiagnostic[] = [];\n for (const c of q.aggregations ?? []) if (!aggregations.includes(c)) diagnostics.push({ metricId: c.id, code: \"unsupported_metric\", message: \"Metric requires unavailable backend fields.\", from: 0, to: 1 });\n if (where.length !== q.where.length || suppliedPredicateCount !== q.where.reduce((n,t)=>n+predicatesOf(t).length,0)) diagnostics.push({ code: \"residual_filter\", message: \"All-matching metrics are unavailable with residual client-only filters.\", from: 0, to: 1 });\n return { where, aggregations, ...(diagnostics.length ? { diagnostics } : {}) };\n}\n","import { isOrGroup, predicatesOf, type SetFilterMetadata, type SetFilterMode, type WhereTerm } from \"./query\";\n\n/** Compile an explicitly identified editor into existing CNF predicates. */\nexport function createSetFilter(field: string, mode: SetFilterMode, values: string[], id: string): WhereTerm[] {\n const keys = [...new Set(values)];\n if (mode !== \"empty\" && keys.length === 0) return [];\n const includes = keys.map((value) => ({ field, op: \"includes\" as const, value }));\n let terms: WhereTerm[];\n if (mode === \"empty\") terms = [{ field, op: \"is_null\", value: \"\" }];\n else if (mode === \"any\") terms = includes.length === 1 ? includes : [{ any: includes }];\n else if (mode === \"all\") terms = includes;\n else terms = includes.map((clause) => ({ any: [{ field, op: \"is_null\", value: \"\" }, { ...clause, negated: true }] }));\n return terms.map((term) => ({ ...term, setFilter: { id, mode, values: mode === \"empty\" ? [] : [...keys] } }));\n}\n\n/** Remove presentation metadata at transport boundaries, including inner literals. */\nexport function stripSetFilter(term: WhereTerm): WhereTerm {\n const strip = ({ setFilter: _metadata, ...clause }: ReturnType<typeof predicatesOf>[number]) => clause;\n return isOrGroup(term) ? { any: term.any.map(strip) } : strip(term);\n}\n\n/** Only collapse explicitly marked, intact editor output. Never infer from predicates. */\nexport function readSetFilter(where: WhereTerm[], index: number): { field: string; metadata: SetFilterMetadata; count: number } | null {\n const term = where[index];\n const metadata = term?.setFilter;\n if (!term || !metadata || where[index - 1]?.setFilter?.id === metadata.id) return null;\n const field = predicatesOf(term)[0]?.field;\n if (!field) return null;\n const expected = createSetFilter(field, metadata.mode, metadata.values, metadata.id);\n if (expected.length === 0) return null;\n for (let offset = 0; offset < expected.length; offset++) {\n const actual = where[index + offset];\n if (!actual || JSON.stringify(actual.setFilter) !== JSON.stringify(expected[offset]!.setFilter) || JSON.stringify(stripSetFilter(actual)) !== JSON.stringify(stripSetFilter(expected[offset]!))) return null;\n }\n if (where[index + expected.length]?.setFilter?.id === metadata.id) return null;\n return { field, metadata, count: expected.length };\n}\n\n/** Canonicalize consumer-owned value aliases without disconnecting editor metadata. */\nexport function mapSetFilterValues(where: WhereTerm[], canonicalize: (field: string, value: string) => string): WhereTerm[] {\n const result: WhereTerm[] = [];\n for (let index = 0; index < where.length; index++) {\n const set = readSetFilter(where, index);\n if (!set) { result.push(where[index]!); continue; }\n result.push(...createSetFilter(set.field, set.metadata.mode, set.metadata.values.map((value) => canonicalize(set.field, value)), set.metadata.id));\n index += set.count - 1;\n }\n return result;\n}\n","import { decodeQueryStrict, encodeQuery } from \"./encode\";\nimport { MAX_QUERY_TOKEN_LENGTH, type QueryState } from \"./query\";\n\nexport interface QuerySnapshot {\n version: 1;\n code: string;\n token: string;\n createdAt: number;\n}\n/** The host owns authenticated, durable storage. Save is immutable/idempotent\n * by code: an existing code may never be assigned a different token. */\nexport interface QuerySnapshotStore {\n save(key: string, snapshot: QuerySnapshot, signal?: AbortSignal): Promise<QuerySnapshot>;\n resolve(key: string, code: string, signal?: AbortSignal): Promise<QuerySnapshot | null>;\n}\nexport interface QuerySnapshotCache {\n get(key: string, code: string): QuerySnapshot | null;\n find(key: string, token: string): QuerySnapshot | null;\n put(key: string, snapshot: QuerySnapshot): void;\n isDurable?(key: string, code: string): boolean;\n markDurable?(key: string, code: string): void;\n}\nexport interface QueryLink {\n url: string;\n kind: \"inline\" | \"local\" | \"durable\";\n bytes: number;\n snapshotCode?: string;\n}\nexport interface QueryLinkOptions {\n /** Complete URL budget, including host parameters and fragment. Default 2000. */\n maxUrlBytes?: number;\n cache?: QuerySnapshotCache;\n}\nconst codePattern = /^[A-Za-z0-9_-]{22}$/;\nexport function validateQuerySnapshot(input: unknown): QuerySnapshot {\n const s = input as QuerySnapshot;\n if (!s || s.version !== 1 || !codePattern.test(s.code) || typeof s.token !== \"string\" ||\n s.token.length > MAX_QUERY_TOKEN_LENGTH || !Number.isFinite(s.createdAt)) throw Error(\"Invalid query snapshot.\");\n decodeQueryStrict(s.token);\n return { version: 1, code: s.code, token: s.token, createdAt: s.createdAt };\n}\nfunction newSnapshot(token: string): QuerySnapshot {\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return { version: 1, code: btoa(bin).replace(/=+$/, \"\").replace(/\\+/g, \"-\").replace(/\\//g, \"_\"), token, createdAt: Date.now() };\n}\n\n/** FIFO entries are scoped by dataset. One bounded envelope makes each write\n * atomic; the new entry is protected from eviction and stored before URL use.\n * Browser profiles, origins, and devices do not share these entries. */\nexport function localQuerySnapshotCache(options: {\n storage?: Pick<Storage, \"getItem\" | \"setItem\">;\n storageKey?: string;\n maxEntries?: number;\n maxBytes?: number;\n} = {}): QuerySnapshotCache {\n const storageKey = options.storageKey ?? \"query-table:link-cache:v1\";\n const maxEntries = options.maxEntries ?? 100;\n const maxBytes = options.maxBytes ?? 2 * 1024 * 1024;\n if (!Number.isInteger(maxEntries) || maxEntries < 1 || !Number.isFinite(maxBytes) || maxBytes < 1) throw Error(\"Invalid query link cache limits.\");\n type Entry = { key: string; snapshot: QuerySnapshot; durable?: boolean };\n const storage = () => options.storage ?? globalThis.localStorage;\n function read(): Entry[] {\n const text = storage().getItem(storageKey);\n if (!text) return [];\n let raw: unknown;\n try { raw = JSON.parse(text); } catch { return []; }\n if (!Array.isArray(raw)) return [];\n const entries: Entry[] = raw.filter(e => e && typeof e.key === \"string\" && e.snapshot &&\n e.snapshot.version === 1 && codePattern.test(e.snapshot.code) && typeof e.snapshot.token === \"string\" &&\n e.snapshot.token.length <= MAX_QUERY_TOKEN_LENGTH && Number.isFinite(e.snapshot.createdAt)).slice(-maxEntries);\n // A lowered host limit trims the oldest entries instead of poisoning the\n // cache. The next successful write replaces malformed/outdated envelopes.\n while (entries.length && JSON.stringify(entries).length * 2 > maxBytes) entries.shift();\n return entries;\n }\n return {\n isDurable(key, code) { return read().some(e => e.key === key && e.snapshot.code === code && e.durable); },\n markDurable(key, code) {\n const entries = read(); const entry = entries.find(e => e.key === key && e.snapshot.code === code);\n if (entry) {\n entry.durable = true;\n let text = JSON.stringify(entries);\n while (text.length * 2 > maxBytes && entries.length > 1) {\n entries.splice(entries[0] === entry ? 1 : 0, 1); text = JSON.stringify(entries);\n }\n if (text.length * 2 <= maxBytes) storage().setItem(storageKey, text);\n }\n },\n get(key, code) { return read().find(e => e.key === key && e.snapshot.code === code)?.snapshot ?? null; },\n find(key, token) { return read().find(e => e.key === key && e.snapshot.token === token)?.snapshot ?? null; },\n put(key, snapshot) {\n const entries = read();\n const old = entries.find(e => e.key === key && e.snapshot.code === snapshot.code);\n if (old) {\n if (old.snapshot.token !== snapshot.token) throw Error(\"A query link code cannot be overwritten.\");\n const text = JSON.stringify(entries);\n if (storage().getItem(storageKey) !== text) storage().setItem(storageKey, text);\n return;\n }\n entries.push({ key, snapshot: validateQuerySnapshot(snapshot) });\n while (entries.length > maxEntries) entries.shift();\n let text = JSON.stringify(entries);\n // Web Storage stores UTF-16 strings; charge both bytes of each code unit.\n while (text.length * 2 > maxBytes && entries.length > 1) { entries.shift(); text = JSON.stringify(entries); }\n if (text.length * 2 > maxBytes) throw Error(\"This query is too large for the local link cache.\");\n storage().setItem(storageKey, text); // Throws on quota/access failure; caller keeps the previous URL.\n },\n };\n}\n\nexport function memoryQuerySnapshotCache(): QuerySnapshotCache {\n let text: string | null = null;\n return localQuerySnapshotCache({ storage: { getItem: () => text, setItem: (_key, value) => { text = value; } } });\n}\n\nexport type QuerySnapshotHttpErrorCode = \"quota\" | \"forbidden\" | \"conflict\" | \"unavailable\" | \"storage\" | \"http\";\n\n/** HTTP failures retain structured information for host error formatting. The\n * message is plain text suitable for displaying in the Save/Share UI. */\nexport class QuerySnapshotHttpError extends Error {\n readonly name = \"QuerySnapshotHttpError\";\n constructor(\n readonly status: number,\n readonly code: QuerySnapshotHttpErrorCode,\n message: string,\n readonly detail?: string,\n readonly serverCode?: string,\n ) { super(message); }\n}\n\nasync function snapshotHttpError(response: Response): Promise<QuerySnapshotHttpError> {\n // Error endpoints may return plain text (including Go's http.Error), JSON,\n // HTML proxy pages, or arbitrarily large bodies. Read at most 4 KiB and never\n // turn an infrastructure response or HTML into a browser-facing message.\n let detail: string | undefined;\n let serverCode: string | undefined;\n const type = response.headers.get(\"content-type\")?.split(\";\")[0]?.trim().toLowerCase();\n if (response.body && (type === \"text/plain\" || type === \"application/json\")) {\n const reader = response.body.getReader();\n try {\n const chunks: Uint8Array[] = [];\n let size = 0;\n let complete = false;\n while (size <= 4096) {\n const next = await reader.read();\n if (next.done) { complete = true; break; }\n size += next.value.byteLength;\n if (size <= 4096) chunks.push(next.value);\n }\n if (complete) {\n const bytes = new Uint8Array(size);\n let offset = 0;\n for (const chunk of chunks) { bytes.set(chunk, offset); offset += chunk.length; }\n const text = new TextDecoder().decode(bytes);\n let reason: unknown = text;\n if (type === \"application/json\") {\n const body = JSON.parse(text);\n reason = body?.message ?? body?.error?.message ?? body?.error;\n const code = body?.code ?? body?.error?.code;\n if (typeof code === \"string\" && /^[A-Za-z0-9_.-]{1,64}$/.test(code)) serverCode = code;\n }\n if (typeof reason === \"string\" && !/[<>]/.test(reason)) {\n const safe = reason.replace(/[\\u0000-\\u001f\\u007f]/g, \" \").trim();\n if (safe) detail = safe.slice(0, 512);\n }\n }\n } catch { /* An unreadable error body must not hide the HTTP failure. */ }\n finally {\n try { await reader.cancel(); } catch { /* Already closed or disconnected. */ }\n reader.releaseLock();\n }\n }\n const status = response.status;\n const code: QuerySnapshotHttpErrorCode = status === 507 ? \"quota\" : status === 401 || status === 403 ? \"forbidden\"\n : status === 409 ? \"conflict\" : status === 404 ? \"unavailable\" : status >= 500 ? \"storage\" : \"http\";\n const messages: Record<QuerySnapshotHttpErrorCode, string> = {\n quota: \"Query snapshot storage is full. Ask your host to increase its quota, then retry saving. Existing links still work.\",\n forbidden: \"You do not have permission to save or open this query link. Sign in or ask your host for access.\",\n conflict: \"This query link code already identifies different state. Ask your host to check its snapshot store.\",\n unavailable: \"This query link is unavailable. Check its address or ask its author for a new link.\",\n storage: \"Query snapshot storage is temporarily unavailable. Retry later; your previous saved query is unchanged.\",\n http: `Query snapshot request failed (${status}). Check the request or retry later.`,\n };\n const message = messages[code] + (code !== \"http\" ? ` (HTTP ${status})` : \"\")\n + (detail && (status < 500 || status === 507) ? ` ${detail}` : \"\");\n return new QuerySnapshotHttpError(status, code, message, detail, serverCode);\n}\n\nexport function httpQuerySnapshotStore(base: string, fetcher: typeof fetch = fetch): QuerySnapshotStore {\n const url = (key: string, code: string) => `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(key)}&code=${encodeURIComponent(code)}`;\n async function responseSnapshot(response: Response): Promise<QuerySnapshot> {\n if (!response.ok) throw await snapshotHttpError(response);\n return validateQuerySnapshot(await response.json());\n }\n return {\n async save(key, snapshot, signal) {\n const result = await responseSnapshot(await fetcher(url(key, snapshot.code), {\n method: \"PUT\", headers: { \"Content-Type\": \"application/json\" }, body: JSON.stringify(snapshot), ...(signal ? { signal } : {}),\n }));\n if (result.code !== snapshot.code || result.token !== snapshot.token) throw Error(\"The snapshot store changed this immutable query link.\");\n return result;\n },\n async resolve(key, code, signal) {\n const response = await fetcher(url(key, code), signal ? { signal } : {});\n if (response.status === 404) return null;\n const result = await responseSnapshot(response);\n if (result.code !== code) throw Error(\"The snapshot store returned a different query link.\");\n return result;\n },\n };\n}\n\nexport interface QueryLinkService {\n local(query: QueryState, baseUrl: string, parameter?: string): QueryLink;\n durable(query: QueryState, baseUrl: string, parameter?: string): Promise<QueryLink>;\n snapshot(query: QueryState): Promise<QuerySnapshot | null>;\n resolve(url: string, parameter?: string, signal?: AbortSignal): Promise<QueryState | null>;\n}\n\n/** Local URL synchronization never writes to the server. Only explicit\n * snapshot/durable calls (Save/Share/Bookmark) promote state to the host store. */\nexport function createQueryLinkService(key: string, store?: QuerySnapshotStore, options: QueryLinkOptions = {}): QueryLinkService {\n const budget = options.maxUrlBytes ?? 2000;\n if (!Number.isInteger(budget) || budget < 1) throw Error(\"Invalid query URL budget.\");\n const cache = options.cache ?? localQuerySnapshotCache();\n const promoted = new Map<string, Promise<QuerySnapshot>>();\n const attempts = new Map<string, QuerySnapshot>();\n const known = new Map<string, QuerySnapshot>();\n function remember(snapshot: QuerySnapshot) {\n known.set(snapshot.code, snapshot);\n while (known.size > 100) known.delete(known.keys().next().value!);\n try { cache.put(key, snapshot); cache.markDurable?.(key, snapshot.code); } catch { /* Durable link does not require a cache. */ }\n }\n function link(base: string, parameter: string, value: string, kind: QueryLink[\"kind\"]): QueryLink {\n const url = new URL(base);\n url.searchParams.set(parameter, value);\n const bytes = new TextEncoder().encode(url.toString()).length;\n if (bytes > budget) throw Error(\"The query link exceeds the URL budget, including the page address.\");\n return { url: url.toString(), kind, bytes, ...(kind !== \"inline\" ? { snapshotCode: value.slice(1) } : {}) };\n }\n function cached(token: string): QuerySnapshot | null {\n try { return cache.find(key, token); } catch { return null; }\n }\n async function snapshot(query: QueryState): Promise<QuerySnapshot | null> {\n if (!store) return null;\n const token = encodeQuery(query);\n const existing = promoted.get(token);\n if (existing) return existing;\n const local = attempts.get(token) ?? cached(token) ?? newSnapshot(token);\n attempts.set(token, local);\n while (attempts.size > 100) attempts.delete(attempts.keys().next().value!);\n // Also retain the code after failed/uncertain writes, so retries are idempotent.\n try { cache.put(key, local); } catch { /* A durable store works without browser storage. */ }\n const pending = store.save(key, local).then(result => {\n const valid = validateQuerySnapshot(result);\n if (valid.code !== local.code || valid.token !== token) throw Error(\"The snapshot store changed this immutable query link.\");\n remember(valid);\n return valid;\n });\n promoted.set(token, pending);\n while (promoted.size > 100) promoted.delete(promoted.keys().next().value!);\n try { return await pending; } catch (error) { promoted.delete(token); throw error; }\n }\n return {\n local(query, baseUrl, parameter = \"q\") {\n const token = encodeQuery(query);\n const current = new URL(baseUrl).searchParams.get(parameter);\n if (current?.startsWith(\"@\") && known.get(current.slice(1))?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n if (current?.startsWith(\"@\")) {\n try {\n const code = current.slice(1);\n if (cache.isDurable?.(key, code) && cache.get(key, code)?.token === token)\n return link(baseUrl, parameter, current, \"durable\");\n } catch { /* Try ordinary inline/local materialization next. */ }\n }\n const url = new URL(baseUrl); url.searchParams.set(parameter, token);\n if (new TextEncoder().encode(url.toString()).length <= budget) return link(baseUrl, parameter, token, \"inline\");\n const local = cached(token) ?? newSnapshot(token);\n const result = link(baseUrl, parameter, \"@\" + local.code, \"local\");\n cache.put(key, local);\n return result;\n },\n async durable(query, baseUrl, parameter = \"q\") {\n const saved = await snapshot(query);\n if (saved) return link(baseUrl, parameter, \"@\" + saved.code, \"durable\");\n const token = encodeQuery(query);\n // Small inline links are portable without a server; never share a local-only code.\n return link(baseUrl, parameter, token, \"inline\");\n },\n snapshot,\n async resolve(baseUrl, parameter = \"q\", signal) {\n const values = new URL(baseUrl).searchParams.getAll(parameter);\n if (!values.length || (values.length === 1 && values[0] === \"\")) return null;\n if (values.length !== 1) throw Error(\"Invalid or conflicting query link parameters.\");\n const value = values[0]!;\n if (!value.startsWith(\"@\")) return decodeQueryStrict(value);\n const code = value.slice(1);\n if (!codePattern.test(code)) throw Error(\"Invalid query link code.\");\n let local: QuerySnapshot | null = null;\n try { local = cache.get(key, code); if (local) local = validateQuerySnapshot(local); } catch { local = null; }\n const result = local ?? (store ? await store.resolve(key, code, signal) : null);\n if (!result) throw Error(\"This query link is unavailable. Its local cache entry may have expired; use a saved or shared link for permanent access.\");\n const valid = validateQuerySnapshot(result);\n if (valid.code !== code) throw Error(\"Invalid query snapshot code.\");\n if (!local) remember(valid);\n else { try { if (cache.isDurable?.(key, code)) remember(valid); } catch { /* Cache metadata is optional. */ } }\n return decodeQueryStrict(valid.token);\n },\n };\n}\n","import type { FormulaResult, FormulaValue } from \"./formula\";\n\n/** Reserved field token namespace. Query state stores IDs, never formula source. */\nexport const COMPUTED_PREFIX = \"@computed/\";\nexport const computedFieldName = (id: string): string => COMPUTED_PREFIX + id;\nexport const isComputedField = (name: string): boolean =>\n name.trim().toLowerCase().startsWith(COMPUTED_PREFIX);\nexport interface ComputedColumn {\n id: string;\n label: string;\n expression: { language: \"qt-expr\"; version: 1; source: string };\n /** Optimistic concurrency token issued by the store. */\n revision: string;\n}\nexport type ComputedColumnDraft = Omit<ComputedColumn, \"revision\">;\nexport interface ComputedColumnStore {\n /** Return the complete authorized catalogue for this dataset. */\n list(dataset: string, signal?: AbortSignal): Promise<ComputedColumn[]>;\n /** null creates a new ID; updates must match the current revision. */\n save(\n dataset: string,\n column: ComputedColumnDraft,\n expectedRevision: string | null,\n ): Promise<ComputedColumn>;\n /** Optional push invalidation, including changes from other sessions. */\n subscribe?(dataset: string, listener: () => void): () => void;\n}\nexport function validateComputedColumn(input: unknown): ComputedColumn {\n const c = input as ComputedColumn;\n if (\n !c ||\n typeof c.id !== \"string\" ||\n !/^[a-zA-Z0-9_-]{1,128}$/.test(c.id) ||\n typeof c.label !== \"string\" ||\n !c.label.trim() ||\n c.label.length > 200 ||\n typeof c.revision !== \"string\" ||\n !c.revision ||\n c.revision.length > 256 ||\n c.expression?.language !== \"qt-expr\" ||\n c.expression.version !== 1 ||\n typeof c.expression.source !== \"string\" ||\n !c.expression.source.trim() ||\n c.expression.source.length > 10000\n ) {\n throw new Error(\n \"Invalid computed column definition or unsupported formula version.\",\n );\n }\n return {\n id: c.id,\n label: c.label,\n revision: c.revision,\n expression: { ...c.expression },\n };\n}\nexport function memoryComputedColumnStore(\n seed: Record<string, ComputedColumn[]> = {},\n): ComputedColumnStore {\n const data = new Map(\n Object.entries(seed).map(([k, v]) => [\n k,\n new Map(v.map((c) => [c.id, validateComputedColumn(c)])),\n ]),\n );\n // Revisions are opaque: never derive a new token by parsing an existing one.\n // Reserve all seed tokens so even a seed from this namespace cannot recur.\n const seedRevisions = new Set(\n [...data.values()].flatMap((entries) =>\n [...entries.values()].map((c) => c.revision),\n ),\n );\n let revisionSequence = 0n;\n function freshRevision(): string {\n let revision: string;\n do {\n revision = `memory:${++revisionSequence}`;\n } while (seedRevisions.has(revision));\n return revision;\n }\n const listeners = new Map<string, Set<() => void>>();\n return {\n async list(dataset) {\n return [...(data.get(dataset)?.values() ?? [])].map(\n validateComputedColumn,\n );\n },\n async save(dataset, column, expectedRevision) {\n const entries = data.get(dataset) ?? new Map<string, ComputedColumn>();\n const current = entries.get(column.id);\n if ((current?.revision ?? null) !== expectedRevision)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n const next = validateComputedColumn({\n ...column,\n revision: freshRevision(),\n });\n entries.set(next.id, next);\n data.set(dataset, entries);\n listeners.get(dataset)?.forEach((fn) => fn());\n return validateComputedColumn(next);\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\n\n/** REST adapter. The implementing server owns authorization and DB persistence.\n * GET base?dataset=… → ComputedColumn[]\n * PUT base?dataset=… → {column, expectedRevision} → ComputedColumn\n * Return HTTP 409 for a stale revision. No formula evaluation happens there. */\nexport function httpComputedColumnStore(\n base: string,\n fetcher: typeof fetch = fetch,\n): ComputedColumnStore {\n const listeners = new Map<string, Set<() => void>>();\n const url = (dataset: string) =>\n `${base}${base.includes(\"?\") ? \"&\" : \"?\"}dataset=${encodeURIComponent(dataset)}`;\n async function read(response: Response): Promise<unknown> {\n if (response.status === 409)\n throw new Error(\n \"This definition changed. Reload it before saving again.\",\n );\n if (!response.ok)\n throw new Error(\n `Computed column store request failed (${response.status}).`,\n );\n return response.json();\n }\n return {\n async list(dataset, signal) {\n const raw = await read(\n await fetcher(url(dataset), { ...(signal ? { signal } : {}) }),\n );\n if (!Array.isArray(raw))\n throw new Error(\"Invalid computed column catalogue.\");\n return raw.map(validateComputedColumn);\n },\n async save(dataset, column, expectedRevision) {\n const result = validateComputedColumn(\n await read(\n await fetcher(url(dataset), {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ column, expectedRevision }),\n }),\n ),\n );\n listeners.get(dataset)?.forEach((fn) => fn());\n return result;\n },\n subscribe(dataset, listener) {\n const set = listeners.get(dataset) ?? new Set();\n set.add(listener);\n listeners.set(dataset, set);\n return () => {\n set.delete(listener);\n };\n },\n };\n}\nexport interface ComputedCellError {\n computedError: string;\n}\nexport function isComputedCellError(\n value: unknown,\n): value is ComputedCellError {\n return (\n value !== null &&\n typeof value === \"object\" &&\n \"computedError\" in value &&\n typeof (value as ComputedCellError).computedError === \"string\"\n );\n}\nexport interface PreviewGroup {\n inputs: FormulaValue[];\n result: FormulaResult;\n count: number;\n}\nexport interface ColumnPreview {\n dependencies: string[];\n groups: PreviewGroup[];\n processed: number;\n total: number;\n nulls: number;\n errors: number;\n}\nexport function groupPreview(\n dependencies: string[],\n inputs: Record<string, FormulaValue>[],\n results: FormulaResult[],\n total: number,\n): ColumnPreview {\n const groups = new Map<string, PreviewGroup>();\n let nulls = 0,\n errors = 0;\n inputs.forEach((row, i) => {\n const values = dependencies.map((name) => row[name] ?? null),\n result = results[i] ?? { value: null, error: \"No result.\" };\n const key = JSON.stringify([values, result.value, result.error ?? null]);\n const group = groups.get(key);\n if (group) group.count++;\n else groups.set(key, { inputs: values, result, count: 1 });\n if (result.error) errors++;\n else if (result.value === null) nulls++;\n });\n return {\n dependencies,\n groups: [...groups.values()].sort((a, b) => b.count - a.count),\n processed: inputs.length,\n total,\n nulls,\n errors,\n };\n}\n\n/** Server-issued capabilities are hints for client planning, never authorization. */\nexport interface ComputedFieldCapabilities {\n\n /** Host-approved canonical predicates; omitted retains the closed default. */\n filter?: boolean;\n type: import('./schema').FieldType;\n select: boolean;\n sort: boolean;\n measure: boolean;\n group: boolean;\n reason?: string;\n}\nexport interface ComputedExecution {\n profile: string;\n planToken: string;\n resolvedRevisions: Record<string,string>;\n fields: Record<string,ComputedFieldCapabilities>;\n fingerprint?: string;\n snapshot?: string;\n}\nexport type RowComputedValues = Record<string,{value: import('./metricTypes').MetricValue; error?: {code:string}}>;\n","import type { FieldType } from \"./schema\";\n\nexport type FormulaType = Exclude<FieldType, \"enum\"> | \"null\";\nexport type FormulaValue = string | number | boolean | string[] | null;\nexport interface FormulaDiagnostic {\n message: string;\n from: number;\n to: number;\n}\nexport type FormulaNode =\n | { kind: \"literal\"; value: FormulaValue; from: number; to: number }\n | {\n kind: \"field\";\n name: string;\n valueType?: FormulaType;\n from: number;\n to: number;\n }\n | {\n kind: \"call\";\n name: string;\n args: FormulaNode[];\n from: number;\n to: number;\n };\nexport interface FormulaPlan {\n ast: FormulaNode;\n dependencies: string[];\n type: FormulaType;\n}\nexport interface RegexInspection {\n input: string;\n start: number;\n end: number;\n groups: (string | null)[];\n}\nexport interface FormulaResult {\n value: FormulaValue;\n error?: string;\n regex?: RegexInspection;\n}\nexport interface FormulaFunction {\n name: string;\n signature: string;\n description: string;\n min: number;\n max: number;\n result: FormulaType | \"branch\";\n args: FormulaType[] | \"any\";\n}\n\nconst f = (\n name: string,\n signature: string,\n description: string,\n min: number,\n max: number,\n result: FormulaFunction[\"result\"],\n args: FormulaFunction[\"args\"],\n): FormulaFunction => ({\n name,\n signature,\n description,\n min,\n max,\n result,\n args,\n});\nexport const FORMULA_FUNCTIONS: FormulaFunction[] = [\n ...[\"LEFT\", \"RIGHT\"].map((n) =>\n f(\n n,\n `${n}(text, count)`,\n \"Take Unicode code points from the end indicated.\",\n 2,\n 2,\n \"text\",\n [\"text\", \"number\"],\n ),\n ),\n f(\n \"SUBSTRING\",\n \"SUBSTRING(text, start, length)\",\n \"One-based start; length is optional.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"number\"],\n ),\n f(\"LENGTH\", \"LENGTH(text)\", \"Count Unicode code points.\", 1, 1, \"number\", [\n \"text\",\n ]),\n ...[\"LOWER\", \"UPPER\", \"TRIM\", \"LTRIM\", \"RTRIM\"].map((n) =>\n f(\n n,\n `${n}(text)`,\n \"Change case or remove surrounding whitespace.\",\n 1,\n 1,\n \"text\",\n [\"text\"],\n ),\n ),\n f(\n \"REPLACE\",\n \"REPLACE(text, search, replacement)\",\n \"Replace all literal occurrences.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"text\"],\n ),\n ...[\"LPAD\", \"RPAD\"].map((n) =>\n f(\n n,\n `${n}(text, length, padding)`,\n \"Pad to a code-point length; default padding is a space.\",\n 2,\n 3,\n \"text\",\n [\"text\", \"number\", \"text\"],\n ),\n ),\n f(\n \"SPLIT_PART\",\n \"SPLIT_PART(text, separator, index)\",\n \"One-based part; missing part returns null.\",\n 3,\n 3,\n \"text\",\n [\"text\", \"text\", \"number\"],\n ),\n f(\n \"CONCAT\",\n \"CONCAT(text, ...)\",\n \"Combine text; null propagates.\",\n 1,\n 50,\n \"text\",\n [\"text\"],\n ),\n f(\n \"CONCAT_WS\",\n \"CONCAT_WS(separator, text, ...)\",\n \"Combine text, skipping null arguments.\",\n 2,\n 50,\n \"text\",\n [\"text\"],\n ),\n ...[\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].map((n) =>\n f(\n n,\n `${n}(text, search, ignoreCase)`,\n \"Case-sensitive unless the optional third argument is true.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"bool\"],\n ),\n ),\n f(\n \"REGEX_TEST\",\n \"REGEX_TEST(text, pattern, flags)\",\n \"Test a JavaScript Unicode regex; flags: i, m, s.\",\n 2,\n 3,\n \"bool\",\n [\"text\", \"text\", \"text\"],\n ),\n f(\n \"REGEX_EXTRACT\",\n \"REGEX_EXTRACT(text, pattern, group, flags)\",\n \"Extract a capture (default 0: whole match); no match returns null.\",\n 2,\n 4,\n \"text\",\n [\"text\", \"text\", \"number\", \"text\"],\n ),\n f(\n \"REGEX_REPLACE\",\n \"REGEX_REPLACE(text, pattern, replacement, flags)\",\n \"Replace all matches; supports $1 capture references.\",\n 3,\n 4,\n \"text\",\n [\"text\", \"text\", \"text\", \"text\"],\n ),\n ...[\"ABS\", \"FLOOR\", \"CEIL\", \"TRUNC\", \"SQRT\"].map((n) =>\n f(n, `${n}(number)`, \"Numeric transformation.\", 1, 1, \"number\", [\"number\"]),\n ),\n f(\n \"ROUND\",\n \"ROUND(number, digits)\",\n \"Round to decimal places (default 0, range -15 to 15).\",\n 1,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"POWER\",\n \"POWER(base, exponent)\",\n \"Raise a number to a power.\",\n 2,\n 2,\n \"number\",\n [\"number\"],\n ),\n f(\n \"CLAMP\",\n \"CLAMP(number, lower, upper)\",\n \"Constrain a number to an inclusive range.\",\n 3,\n 3,\n \"number\",\n [\"number\"],\n ),\n ...[\"LEAST\", \"GREATEST\"].map((n) =>\n f(\n n,\n `${n}(number, ...)`,\n \"Compare numbers within this row.\",\n 1,\n 50,\n \"number\",\n [\"number\"],\n ),\n ),\n f(\n \"IF\",\n \"IF(condition, then, otherwise)\",\n \"Evaluate only the chosen branch; null condition uses otherwise.\",\n 3,\n 3,\n \"branch\",\n \"any\",\n ),\n f(\n \"IFS\",\n \"IFS(condition, value, ..., fallback)\",\n \"First true condition wins; final fallback is required.\",\n 3,\n 49,\n \"branch\",\n \"any\",\n ),\n f(\n \"SWITCH\",\n \"SWITCH(value, match, result, ..., fallback)\",\n \"Match a value to a result; final fallback is required.\",\n 4,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"COALESCE\",\n \"COALESCE(value, ...)\",\n \"First non-null value, evaluated lazily.\",\n 1,\n 50,\n \"branch\",\n \"any\",\n ),\n f(\n \"NULLIF\",\n \"NULLIF(value, other)\",\n \"Return null if the values are equal.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...[\"IS_NULL\", \"IS_EMPTY\"].map((n) =>\n f(\n n,\n `${n}(value)`,\n \"Test null, or null/empty text/empty array.\",\n 1,\n 1,\n \"bool\",\n \"any\",\n ),\n ),\n f(\n \"IFERROR\",\n \"IFERROR(value, fallback)\",\n \"Use fallback only when evaluating value fails.\",\n 2,\n 2,\n \"branch\",\n \"any\",\n ),\n ...(\n [\n [\"TO_TEXT\", \"text\"],\n [\"TO_NUMBER\", \"number\"],\n [\"TO_BOOLEAN\", \"bool\"],\n [\"TO_DATETIME\", \"datetime\"],\n ] as const\n ).map(([n, t]) =>\n f(\n n,\n `${n}(value)`,\n \"Explicit conversion; invalid input produces a cell error.\",\n 1,\n 1,\n t,\n \"any\",\n ),\n ),\n f(\n \"SPLIT\",\n \"SPLIT(text, separator)\",\n \"Split text into an array.\",\n 2,\n 2,\n \"textarray\",\n [\"text\", \"text\"],\n ),\n f(\"JOIN\", \"JOIN(array, separator)\", \"Join an array of text.\", 2, 2, \"text\", [\n \"textarray\",\n \"text\",\n ]),\n f(\n \"ARRAY_LENGTH\",\n \"ARRAY_LENGTH(array)\",\n \"Count array elements.\",\n 1,\n 1,\n \"number\",\n [\"textarray\"],\n ),\n f(\n \"ARRAY_CONTAINS\",\n \"ARRAY_CONTAINS(array, text)\",\n \"Case-sensitive array membership.\",\n 2,\n 2,\n \"bool\",\n [\"textarray\", \"text\"],\n ),\n f(\n \"ARRAY_GET\",\n \"ARRAY_GET(array, index)\",\n \"One-based element; out of range returns null.\",\n 2,\n 2,\n \"text\",\n [\"textarray\", \"number\"],\n ),\n ...[\"ARRAY_UNIQUE\", \"ARRAY_SORT\"].map((n) =>\n f(\n n,\n `${n}(array)`,\n \"Deduplicate or sort text elements by code-point order.\",\n 1,\n 1,\n \"textarray\",\n [\"textarray\"],\n ),\n ),\n ...[\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\", \"WEEKDAY\"].map((n) =>\n f(\n n,\n `${n}(datetime)`,\n \"UTC date component; weekday is Monday=1 through Sunday=7.\",\n 1,\n 1,\n \"number\",\n [\"datetime\"],\n ),\n ),\n f(\n \"DATE_TRUNC\",\n \"DATE_TRUNC(unit, datetime)\",\n \"UTC truncation: year, month, week (Monday), day, hour, minute, second.\",\n 2,\n 2,\n \"datetime\",\n [\"text\", \"datetime\"],\n ),\n f(\n \"DATE_ADD\",\n \"DATE_ADD(unit, amount, datetime)\",\n \"UTC calendar addition; month/year clamp to the last day.\",\n 3,\n 3,\n \"datetime\",\n [\"text\", \"number\", \"datetime\"],\n ),\n f(\n \"DATE_DIFF\",\n \"DATE_DIFF(unit, start, end)\",\n \"Elapsed whole units: week, day, hour, minute, second, millisecond.\",\n 3,\n 3,\n \"number\",\n [\"text\", \"datetime\", \"datetime\"],\n ),\n f(\n \"FORMAT_DATE\",\n \"FORMAT_DATE(datetime, pattern)\",\n \"UTC tokens: YYYY MM DD HH mm ss; other text is literal.\",\n 2,\n 2,\n \"text\",\n [\"datetime\", \"text\"],\n ),\n];\n\nexport class FormulaError extends Error {\n constructor(\n message: string,\n public from = 0,\n public to = from + 1,\n ) {\n super(message);\n }\n}\ninterface Token {\n text: string;\n kind: \"field\" | \"string\" | \"number\" | \"word\" | \"op\" | \"end\";\n from: number;\n to: number;\n}\nexport function compileFormula(\n source: string,\n fields: readonly { name: string; type: FieldType }[],\n resolve?: (name: string) => FormulaPlan | undefined,\n extension?: (node: FormulaNode, check: (node: FormulaNode) => FormulaType) => FormulaType | undefined,\n): FormulaPlan {\n if (!source.trim() || source.length > 10000)\n throw new FormulaError(\"Formula must contain 1–10,000 characters.\");\n const tokens: Token[] = [];\n let pos = 0;\n while (pos < source.length) {\n if (/\\s/.test(source[pos]!)) {\n pos++;\n continue;\n }\n const from = pos;\n let match: RegExpMatchArray | null;\n if (source[pos] === \"[\") {\n pos++;\n let text = \"\";\n let closed = false;\n while (pos < source.length) {\n if (source[pos] === \"]\") {\n if (source[pos + 1] === \"]\") {\n text += \"]\";\n pos += 2;\n } else {\n pos++;\n closed = true;\n break;\n }\n } else text += source[pos++];\n }\n if (!closed)\n throw new FormulaError(\"Unclosed field reference.\", from, pos);\n tokens.push({ kind: \"field\", text, from, to: pos });\n } else if (source[pos] === '\"') {\n pos++;\n while (pos < source.length && source[pos] !== '\"') {\n if (source[pos] === \"\\\\\") pos++;\n pos++;\n }\n pos++;\n try {\n tokens.push({\n kind: \"string\",\n text: JSON.parse(source.slice(from, pos)),\n from,\n to: pos,\n });\n } catch {\n throw new FormulaError(\"Invalid JSON string literal.\", from, pos);\n }\n } else if (\n (match = source\n .slice(pos)\n .match(/^(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"number\", text: match[0], from, to: pos });\n } else if ((match = source.slice(pos).match(/^[a-zA-Z_][a-zA-Z_0-9]*/))) {\n pos += match[0].length;\n tokens.push({\n kind: \"word\",\n text: match[0].toUpperCase(),\n from,\n to: pos,\n });\n } else if (\n (match = source.slice(pos).match(/^(>=|<=|!=|<>|[=<>+*/%(),-])/))\n ) {\n pos += match[0].length;\n tokens.push({ kind: \"op\", text: match[0], from, to: pos });\n } else throw new FormulaError(`Unexpected character ${source[pos]}.`, from);\n if (tokens.length > 2000)\n throw new FormulaError(\"Formula is too complex.\", from);\n }\n tokens.push({ kind: \"end\", text: \"\", from: pos, to: pos });\n let i = 0,\n depth = 0;\n const peek = () => tokens[i]!;\n const take = () => tokens[i++]!;\n const expect = (s: string) => {\n if (peek().text !== s)\n throw new FormulaError(`Expected ${s}.`, peek().from, peek().to);\n return take();\n };\n const call = (\n name: string,\n args: FormulaNode[],\n from: number,\n to: number,\n ): FormulaNode => ({ kind: \"call\", name, args, from, to });\n const priority: Record<string, number> = {\n OR: 1,\n AND: 2,\n \"=\": 3,\n \"!=\": 3,\n \"<>\": 3,\n \"<\": 3,\n \">\": 3,\n \"<=\": 3,\n \">=\": 3,\n IN: 3,\n BETWEEN: 3,\n \"+\": 4,\n \"-\": 4,\n \"*\": 5,\n \"/\": 5,\n \"%\": 5,\n };\n function expression(min = 0): FormulaNode {\n if (++depth > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", peek().from);\n const t = take();\n let node: FormulaNode;\n if (t.kind === \"number\") {\n if (!Number.isFinite(Number(t.text)))\n throw new FormulaError(\"Number must be finite.\", t.from, t.to);\n node = { kind: \"literal\", value: Number(t.text), from: t.from, to: t.to };\n } else if (t.kind === \"string\")\n node = { kind: \"literal\", value: t.text, from: t.from, to: t.to };\n else if (t.kind === \"field\")\n node = { kind: \"field\", name: t.text, from: t.from, to: t.to };\n else if ([\"TRUE\", \"FALSE\", \"NULL\"].includes(t.text))\n node = {\n kind: \"literal\",\n value: t.text === \"NULL\" ? null : t.text === \"TRUE\",\n from: t.from,\n to: t.to,\n };\n else if (t.text === \"(\") {\n node = expression();\n expect(\")\");\n } else if ([\"NOT\", \"-\", \"+\"].includes(t.text)) {\n const arg = expression(t.text === \"NOT\" ? 3 : 6);\n node = call(`unary:${t.text}`, [arg], t.from, arg.to);\n } else if (t.kind === \"word\") {\n expect(\"(\");\n const args: FormulaNode[] = [];\n if (peek().text !== \")\") {\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n }\n node = call(t.text, args, t.from, expect(\")\").to);\n } else\n throw new FormulaError(\n \"Expected a value, field, or function.\",\n t.from,\n t.to,\n );\n while (peek().kind !== \"end\" && (priority[peek().text] ?? -1) >= min) {\n const op = take();\n const p = priority[op.text]!;\n if (op.text === \"IN\") {\n expect(\"(\");\n const args = [node];\n do {\n args.push(expression());\n if (peek().text !== \",\") break;\n take();\n } while (true);\n node = call(\"op:IN\", args, node.from, expect(\")\").to);\n } else if (op.text === \"BETWEEN\") {\n const lo = expression(p + 1);\n expect(\"AND\");\n const hi = expression(p + 1);\n node = call(\"op:BETWEEN\", [node, lo, hi], node.from, hi.to);\n } else {\n const right = expression(p + 1);\n node = call(`op:${op.text}`, [node, right], node.from, right.to);\n }\n }\n depth--;\n return node;\n }\n const ast = expression();\n if (peek().kind !== \"end\")\n throw new FormulaError(\"Unexpected token.\", peek().from, peek().to);\n const deps = new Set<string>();\n const byName = new Map(fields.map((v) => [v.name, v.type]));\n const same = (ts: FormulaType[], n: FormulaNode): FormulaType => {\n const real = [...new Set(ts.filter((t) => t !== \"null\"))];\n if (real.length > 1)\n throw new FormulaError(\n \"Values must have compatible types; use an explicit conversion.\",\n n.from,\n n.to,\n );\n return real[0] ?? \"null\";\n };\n function check(n: FormulaNode, level = 0): FormulaType {\n if (level > 50)\n throw new FormulaError(\"Maximum nesting depth is 50.\", n.from, n.to);\n if (n.kind === \"literal\")\n return n.value === null\n ? \"null\"\n : typeof n.value === \"boolean\"\n ? \"bool\"\n : typeof n.value === \"number\"\n ? \"number\"\n : \"text\";\n if (n.kind === \"field\") {\n const t = byName.get(n.name);\n if (!t) {\n const nested = resolve?.(n.name);\n if (nested) {\n Object.assign(n, nested.ast);\n nested.dependencies.forEach((d) => deps.add(d));\n return nested.type;\n }\n throw new FormulaError(\n `Unknown or unavailable field: ${n.name}`,\n n.from,\n n.to,\n );\n }\n deps.add(n.name);\n n.valueType = t === \"enum\" ? \"text\" : t;\n return n.valueType;\n }\n const extended = extension?.(n, (arg) => check(arg, level + 1));\n if (extended !== undefined) return extended;\n const ts = n.args.map((a) => check(a, level + 1));\n const need = (index: number, t: FormulaType) => {\n if (ts[index] !== undefined && ts[index] !== \"null\" && ts[index] !== t)\n throw new FormulaError(\n `Expected ${t}, received ${ts[index]}.`,\n n.args[index]!.from,\n n.args[index]!.to,\n );\n };\n if (n.name.startsWith(\"op:\") || n.name.startsWith(\"unary:\")) {\n const op = n.name.split(\":\")[1]!;\n if ([\"AND\", \"OR\", \"NOT\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"bool\"));\n return \"bool\";\n }\n if ([\"+\", \"-\", \"*\", \"/\", \"%\"].includes(op)) {\n ts.forEach((_, j) => need(j, \"number\"));\n return \"number\";\n }\n same(ts, n);\n return \"bool\";\n }\n const spec = FORMULA_FUNCTIONS.find((v) => v.name === n.name);\n if (!spec)\n throw new FormulaError(`Unknown function: ${n.name}`, n.from, n.to);\n if (ts.length < spec.min || ts.length > spec.max)\n throw new FormulaError(`Use ${spec.signature}.`, n.from, n.to);\n if (spec.args !== \"any\") {\n const args = spec.args;\n ts.forEach((_, j) => need(j, args[Math.min(j, args.length - 1)]!));\n }\n if (n.name === \"IF\") {\n need(0, \"bool\");\n return same(ts.slice(1), n);\n }\n if (n.name === \"IFS\") {\n if (ts.length % 2 !== 1)\n throw new FormulaError(\n \"IFS requires condition/value pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n ts.forEach((t, j) => {\n if (j === ts.length - 1 || j % 2 === 1) branches.push(t);\n else need(j, \"bool\");\n });\n return same(branches, n);\n }\n if (n.name === \"SWITCH\") {\n if (ts.length % 2 !== 0)\n throw new FormulaError(\n \"SWITCH requires match/result pairs and a fallback.\",\n n.from,\n n.to,\n );\n const branches: FormulaType[] = [];\n for (let j = 1; j < ts.length - 1; j += 2) {\n same([ts[0]!, ts[j]!], n);\n branches.push(ts[j + 1]!);\n }\n branches.push(ts[ts.length - 1]!);\n return same(branches, n);\n }\n if (n.name.startsWith(\"REGEX_\")) {\n const pattern = n.args[1];\n const flags = n.args[n.name === \"REGEX_TEST\" ? 2 : 3];\n if (pattern?.kind === \"literal\" && typeof pattern.value === \"string\") {\n if (pattern.value.length > 2000)\n throw new FormulaError(\n \"Regex pattern exceeds 2,000 characters.\",\n pattern.from,\n pattern.to,\n );\n if (\n !flags ||\n (flags.kind === \"literal\" && typeof flags.value === \"string\")\n ) {\n const value = flags?.value ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(String(value)))\n throw new FormulaError(\n \"Regex flags must be unique i, m, or s.\",\n n.from,\n n.to,\n );\n try {\n new RegExp(pattern.value, `${value}u`);\n } catch {\n throw new FormulaError(\n \"Invalid regex pattern.\",\n pattern.from,\n pattern.to,\n );\n }\n }\n }\n }\n if (spec.result === \"branch\") return same(ts, n);\n return spec.result;\n }\n const type = check(ast);\n return { ast, dependencies: [...deps].sort(), type };\n}\n\n/** Self-contained runtime: serialized into the browser worker, never user code. */\nexport function formulaRuntime(\n ast: FormulaNode,\n inputs: Record<string, FormulaValue>,\n extension?: (node: Extract<FormulaNode, { kind: \"call\" }>) => FormulaResult | undefined,\n): FormulaResult {\n const fail = (s: string): never => {\n throw new Error(s);\n };\n const num = (v: FormulaValue): number =>\n typeof v === \"number\" && Number.isFinite(v)\n ? v\n : fail(\"Expected a finite number.\");\n const str = (v: FormulaValue): string =>\n typeof v === \"string\" ? v : fail(\"Expected text.\");\n const arr = (v: FormulaValue): string[] =>\n Array.isArray(v) && v.every((x) => typeof x === \"string\")\n ? v\n : fail(\"Expected a text array.\");\n const integer = (v: FormulaValue, min = 0, max = 100000): number => {\n const n = num(v);\n return Number.isInteger(n) && n >= min && n <= max\n ? n\n : fail(`Expected an integer between ${min} and ${max}.`);\n };\n const equal = (a: FormulaValue, b: FormulaValue) =>\n JSON.stringify(a) === JSON.stringify(b);\n const date = (v: FormulaValue): Date => {\n const s = str(v);\n if (\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n s,\n )\n )\n fail(\"Expected an ISO date or timestamp with timezone.\");\n const d = new Date(s);\n const day = Number(s.slice(8, 10)),\n month = Number(s.slice(5, 7));\n if (\n !Number.isFinite(d.getTime()) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > new Date(Date.UTC(Number(s.slice(0, 4)), month, 0)).getUTCDate()\n )\n fail(\"Invalid date.\");\n return d;\n };\n const bound = (v: FormulaValue): FormulaValue => {\n if (\n v !== null &&\n typeof v !== \"number\" &&\n typeof v !== \"string\" &&\n typeof v !== \"boolean\" &&\n !Array.isArray(v)\n )\n fail(\"Unsupported input value type.\");\n if (Array.isArray(v) && !v.every((x) => typeof x === \"string\"))\n fail(\"Expected a text array.\");\n if (typeof v === \"number\" && !Number.isFinite(v))\n fail(\"Result is not finite.\");\n if (typeof v === \"string\" && v.length > 100000)\n fail(\"Text result exceeds 100,000 characters.\");\n if (\n Array.isArray(v) &&\n (v.length > 10000 || v.reduce((s, x) => s + x.length, 0) > 100000)\n )\n fail(\"Array result is too large.\");\n return v;\n };\n let inspection: RegexInspection | undefined;\n let budget = 5000;\n function run(n: FormulaNode): FormulaValue {\n if (--budget < 0) fail(\"Formula operation limit exceeded.\");\n if (n.kind === \"literal\") return n.value;\n if (n.kind === \"field\") {\n if (!Object.prototype.hasOwnProperty.call(inputs, n.name)) return null;\n const v = bound(inputs[n.name] ?? null);\n if (v === null) return null;\n if (n.valueType === \"number\") return num(v);\n if (n.valueType === \"bool\" && typeof v !== \"boolean\")\n fail(\"Expected a boolean.\");\n if (n.valueType === \"datetime\") return date(v).toISOString();\n if (n.valueType === \"text\") return str(v);\n if (n.valueType === \"textarray\") return arr(v);\n return v;\n }\n const extended = extension?.(n);\n if (extended) {\n if (extended.error) fail(extended.error);\n return bound(extended.value);\n }\n const name = n.name;\n const args = n.args;\n if (name === \"IF\") return run(run(args[0]!) === true ? args[1]! : args[2]!);\n if (name === \"IFS\") {\n for (let j = 0; j < args.length - 1; j += 2)\n if (run(args[j]!) === true) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"SWITCH\") {\n const v = run(args[0]!);\n for (let j = 1; j < args.length - 1; j += 2)\n if (equal(v, run(args[j]!))) return run(args[j + 1]!);\n return run(args[args.length - 1]!);\n }\n if (name === \"COALESCE\") {\n for (const arg of args) {\n const v = run(arg);\n if (v !== null) return v;\n }\n return null;\n }\n if (name === \"IFERROR\") {\n try {\n return run(args[0]!);\n } catch {\n return run(args[1]!);\n }\n }\n if (name === \"op:AND\" || name === \"op:OR\") {\n const a = run(args[0]!);\n if (name === \"op:AND\" && a === false) return false;\n if (name === \"op:OR\" && a === true) return true;\n const b = run(args[1]!);\n return name === \"op:AND\"\n ? b === false\n ? false\n : a === null || b === null\n ? null\n : true\n : b === true\n ? true\n : a === null || b === null\n ? null\n : false;\n }\n const vs = args.map(run);\n const a = vs[0] ?? null,\n b = vs[1] ?? null,\n c = vs[2] ?? null;\n if (name === \"IS_NULL\") return a === null;\n if (name === \"IS_EMPTY\")\n return a === null || a === \"\" || (Array.isArray(a) && a.length === 0);\n if (name === \"NULLIF\") return equal(a, b) ? null : a;\n if (name === \"CONCAT_WS\")\n return a === null\n ? null\n : bound(\n vs\n .slice(1)\n .filter((v) => v !== null)\n .map(str)\n .join(str(a)),\n );\n if (name === \"op:IN\") {\n if (a === null) return null;\n if (vs.slice(1).some((v) => v !== null && equal(a, v))) return true;\n return vs.slice(1).includes(null) ? null : false;\n }\n if (vs.some((v) => v === null)) return null;\n let out: FormulaValue;\n switch (name) {\n case \"unary:NOT\":\n out = !a;\n break;\n case \"unary:-\":\n out = -num(a);\n break;\n case \"unary:+\":\n out = num(a);\n break;\n case \"op:+\":\n out = num(a) + num(b);\n break;\n case \"op:-\":\n out = num(a) - num(b);\n break;\n case \"op:*\":\n out = num(a) * num(b);\n break;\n case \"op:/\":\n case \"op:%\":\n if (num(b) === 0) fail(\"Division by zero.\");\n out = name === \"op:/\" ? num(a) / num(b) : num(a) % num(b);\n break;\n case \"op:=\":\n out = equal(a, b);\n break;\n case \"op:!=\":\n case \"op:<>\":\n out = !equal(a, b);\n break;\n case \"op:<\":\n out = a! < b!;\n break;\n case \"op:>\":\n out = a! > b!;\n break;\n case \"op:<=\":\n out = a! <= b!;\n break;\n case \"op:>=\":\n out = a! >= b!;\n break;\n case \"op:BETWEEN\":\n out = a! >= b! && a! <= c!;\n break;\n case \"LEFT\":\n out = Array.from(str(a)).slice(0, integer(b)).join(\"\");\n break;\n case \"RIGHT\": {\n const n = integer(b);\n out = n ? Array.from(str(a)).slice(-n).join(\"\") : \"\";\n break;\n }\n case \"SUBSTRING\": {\n const start = integer(b, 1) - 1;\n out = Array.from(str(a))\n .slice(start, vs.length > 2 ? start + integer(c) : undefined)\n .join(\"\");\n break;\n }\n case \"LENGTH\":\n out = Array.from(str(a)).length;\n break;\n case \"LOWER\":\n out = str(a).toLowerCase();\n break;\n case \"UPPER\":\n out = str(a).toUpperCase();\n break;\n case \"TRIM\":\n out = str(a).trim();\n break;\n case \"LTRIM\":\n out = str(a).trimStart();\n break;\n case \"RTRIM\":\n out = str(a).trimEnd();\n break;\n case \"REPLACE\":\n if (b === \"\") fail(\"Search text must not be empty.\");\n const parts = str(a).split(str(b));\n if (parts.length * str(c).length + str(a).length > 200000)\n fail(\"Replacement result is too large.\");\n out = parts.join(str(c));\n break;\n case \"LPAD\":\n case \"RPAD\": {\n const chars = Array.from(str(a)),\n len = integer(b),\n pad = Array.from(vs.length > 2 ? str(c) : \" \");\n if (!pad.length) fail(\"Padding must not be empty.\");\n const fill = Array.from(\n { length: Math.max(0, len - chars.length) },\n (_, i) => pad[i % pad.length]!,\n ).join(\"\");\n out =\n (name === \"LPAD\" ? fill : \"\") +\n chars.slice(0, len).join(\"\") +\n (name === \"RPAD\" ? fill : \"\");\n break;\n }\n case \"SPLIT_PART\":\n out = str(a).split(str(b))[integer(c, 1) - 1] ?? null;\n break;\n case \"CONCAT\":\n out = vs.map(str).join(\"\");\n break;\n case \"CONTAINS\":\n case \"STARTS_WITH\":\n case \"ENDS_WITH\": {\n const s = c === true ? str(a).toLowerCase() : str(a),\n t = c === true ? str(b).toLowerCase() : str(b);\n out =\n name === \"CONTAINS\"\n ? s.includes(t)\n : name === \"STARTS_WITH\"\n ? s.startsWith(t)\n : s.endsWith(t);\n break;\n }\n case \"REGEX_TEST\":\n case \"REGEX_EXTRACT\":\n case \"REGEX_REPLACE\": {\n const flags = vs[name === \"REGEX_TEST\" ? 2 : 3] ?? \"\";\n if (!/^(?!.*(.).*\\1)[ims]*$/.test(str(flags)))\n fail(\"Regex flags must be unique i, m, or s.\");\n if (str(b).length > 2000)\n fail(\"Regex pattern exceeds 2,000 characters.\");\n const re = new RegExp(\n str(b),\n `${flags}u${name === \"REGEX_REPLACE\" ? \"g\" : \"\"}`,\n );\n if (name === \"REGEX_TEST\") out = re.test(str(a));\n else if (name === \"REGEX_REPLACE\") {\n let produced = 0;\n out = str(a).replace(re, (...captures: unknown[]) => {\n const replacement = str(c).replace(\n /\\$(\\$|[0-9]{1,2}|&|`|')/g,\n (_token, key: string) => {\n if (key === \"$\") return \"$\";\n if (key === \"&\") return String(captures[0]);\n if (key === \"`\" || key === \"'\")\n return fail(\n \"Regex replacement supports $$, $&, and numbered captures only.\",\n );\n const extra =\n typeof captures[captures.length - 1] === \"object\" ? 3 : 2;\n const i = Number(key);\n return i > 0 && i < captures.length - extra\n ? String(captures[i] ?? \"\")\n : fail(\"Invalid replacement capture.\");\n },\n );\n produced += replacement.length;\n if (produced > 100000) fail(\"Replacement result is too large.\");\n return replacement;\n });\n } else {\n const match = re.exec(str(a));\n const group = vs.length > 2 ? integer(c, 0, 100) : 0;\n out = match?.[group] ?? null;\n if (match)\n inspection = {\n input: str(a),\n start: match.index,\n end: match.index + match[0].length,\n groups: Array.from(match, (v) => v ?? null),\n };\n }\n break;\n }\n case \"ABS\":\n out = Math.abs(num(a));\n break;\n case \"FLOOR\":\n out = Math.floor(num(a));\n break;\n case \"CEIL\":\n out = Math.ceil(num(a));\n break;\n case \"TRUNC\":\n out = Math.trunc(num(a));\n break;\n case \"SQRT\":\n out = Math.sqrt(num(a));\n break;\n case \"ROUND\": {\n const scale = 10 ** (vs.length > 1 ? integer(b, -15, 15) : 0);\n out = Math.round(num(a) * scale) / scale;\n break;\n }\n case \"POWER\":\n out = Math.pow(num(a), num(b));\n break;\n case \"CLAMP\":\n if (num(b) > num(c)) fail(\"Lower bound exceeds upper bound.\");\n out = Math.max(num(b), Math.min(num(c), num(a)));\n break;\n case \"LEAST\":\n out = Math.min(...vs.map(num));\n break;\n case \"GREATEST\":\n out = Math.max(...vs.map(num));\n break;\n case \"TO_TEXT\":\n out = Array.isArray(a) ? JSON.stringify(a) : String(a);\n break;\n case \"TO_NUMBER\":\n if (\n typeof a !== \"number\" &&\n (typeof a !== \"string\" ||\n !/^[-+]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?$/.test(a.trim()))\n )\n fail(\"Cannot convert to number.\");\n out = Number(a);\n break;\n case \"TO_BOOLEAN\":\n if (a === true || a === false) out = a;\n else if (a === \"true\" || a === 1) out = true;\n else if (a === \"false\" || a === 0) out = false;\n else return fail(\"Cannot convert to boolean.\");\n break;\n case \"TO_DATETIME\":\n out = date(a).toISOString();\n break;\n case \"SPLIT\":\n out = str(a).split(str(b));\n break;\n case \"JOIN\":\n out = arr(a).join(str(b));\n break;\n case \"ARRAY_LENGTH\":\n out = arr(a).length;\n break;\n case \"ARRAY_CONTAINS\":\n out = arr(a).includes(str(b));\n break;\n case \"ARRAY_GET\":\n out = arr(a)[integer(b, 1) - 1] ?? null;\n break;\n case \"ARRAY_UNIQUE\":\n out = [...new Set(arr(a))];\n break;\n case \"ARRAY_SORT\":\n out = [...arr(a)].sort((left, right) => {\n const l = Array.from(left),\n r = Array.from(right);\n for (let i = 0; i < Math.min(l.length, r.length); i++) {\n const delta = l[i]!.codePointAt(0)! - r[i]!.codePointAt(0)!;\n if (delta) return delta;\n }\n return l.length - r.length;\n });\n break;\n case \"YEAR\":\n out = date(a).getUTCFullYear();\n break;\n case \"MONTH\":\n out = date(a).getUTCMonth() + 1;\n break;\n case \"DAY\":\n out = date(a).getUTCDate();\n break;\n case \"HOUR\":\n out = date(a).getUTCHours();\n break;\n case \"WEEKDAY\":\n out = ((date(a).getUTCDay() + 6) % 7) + 1;\n break;\n case \"DATE_TRUNC\": {\n const d = date(b),\n unit = str(a).toLowerCase();\n if (\n ![\n \"year\",\n \"month\",\n \"week\",\n \"day\",\n \"hour\",\n \"minute\",\n \"second\",\n ].includes(unit)\n )\n fail(\"Unsupported date unit.\");\n d.setUTCMilliseconds(0);\n if (unit !== \"second\") d.setUTCSeconds(0);\n if (![\"second\", \"minute\"].includes(unit)) d.setUTCMinutes(0);\n if ([\"year\", \"month\", \"week\", \"day\"].includes(unit)) d.setUTCHours(0);\n if (unit === \"week\")\n d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 6) % 7));\n if (unit === \"year\" || unit === \"month\") d.setUTCDate(1);\n if (unit === \"year\") d.setUTCMonth(0);\n out = d.toISOString();\n break;\n }\n case \"DATE_ADD\": {\n const d = date(c),\n unit = str(a).toLowerCase(),\n amount = integer(b, -100000, 100000);\n if (unit === \"year\" || unit === \"month\") {\n const day = d.getUTCDate();\n d.setUTCDate(1);\n d.setUTCMonth(d.getUTCMonth() + amount * (unit === \"year\" ? 12 : 1));\n const last = new Date(d.getTime());\n last.setUTCMonth(last.getUTCMonth() + 1, 0);\n d.setUTCDate(Math.min(day, last.getUTCDate()));\n } else {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[unit];\n if (!ms) fail(\"Unsupported date unit.\");\n d.setTime(d.getTime() + amount * ms!);\n }\n out = d.toISOString();\n break;\n }\n case \"DATE_DIFF\": {\n const units: Record<string, number> = {\n week: 604800000,\n day: 86400000,\n hour: 3600000,\n minute: 60000,\n second: 1000,\n millisecond: 1,\n };\n const ms = units[str(a).toLowerCase()];\n if (!ms) fail(\"Unsupported elapsed date unit.\");\n out = Math.trunc((date(c).getTime() - date(b).getTime()) / ms!);\n break;\n }\n case \"FORMAT_DATE\": {\n const d = date(a),\n pad = (n: number) => String(n).padStart(2, \"0\"),\n parts: Record<string, string> = {\n YYYY: String(d.getUTCFullYear()).padStart(4, \"0\"),\n MM: pad(d.getUTCMonth() + 1),\n DD: pad(d.getUTCDate()),\n HH: pad(d.getUTCHours()),\n mm: pad(d.getUTCMinutes()),\n ss: pad(d.getUTCSeconds()),\n };\n out = str(b).replace(/YYYY|MM|DD|HH|mm|ss/g, (t) => parts[t]!);\n break;\n }\n default:\n return fail(`Unknown operation: ${name}`);\n }\n return bound(out);\n }\n try {\n const value = run(ast);\n return inspection ? { value, regex: inspection } : { value };\n } catch (e) {\n return {\n value: null,\n error: e instanceof Error ? e.message : \"Formula evaluation failed.\",\n };\n }\n}\n","import { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n compileMetric,\n metricAggregatePlans,\n reduceMetricValues,\n evaluateMetricReductions,\n metricPlans,\n hasRegex,\n selectMetricShownRows,\n} from \"./metrics\";\nimport { formulaRuntime, type FormulaNode, type FormulaValue } from \"./formula\";\nimport { isComputedField } from \"./computed\";\nimport { type QueryEvaluationOptions } from \"./relativeTime\";\nimport type { MetricPlan } from \"./metrics\";\nimport {\n isSortable,\n isSelectable,\n readFieldValue,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n MAX_GROUP_BY_FIELDS,\n normalizeQueryState,\n predicatesOf,\n type AggOp,\n type QueryState,\n} from \"./query\";\n\nexport type GroupedRow = Record<string, unknown>;\ntype Row = GroupedRow;\nexport type SummaryOp = AggOp | \"row\" | \"formula\";\nexport interface RepresentativeOrder {\n field: string;\n dir: \"asc\" | \"desc\";\n nulls: \"first\" | \"last\";\n}\nexport interface RepresentativeRow {\n orderBy: RepresentativeOrder[];\n}\nexport interface SummaryColumn {\n id: string;\n op: SummaryOp;\n field?: string;\n expression?: string;\n label?: string;\n}\nexport interface GroupingView {\n version: 2;\n mode: \"rows\" | \"groups\";\n keys: string[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n input: QueryState;\n result: QueryState;\n}\n\n/** One grouping stage over the complete source population. QueryState.where is\n * HAVING in this mode; source.where is the pre-group WHERE. The source snapshot\n * also restores the record layout, paging, metrics and item details on exit. */\nexport interface GroupingDefinition {\n keys: string[];\n summaries: SummaryColumn[];\n representative: RepresentativeRow | null;\n diagnostics?: string[];\n}\nexport interface GroupingState extends GroupingDefinition {\n source: QueryState;\n}\nexport const GROUP_ID_FIELD = \"__qt_group_id__\";\nexport const MAX_REPRESENTATIVE_SORTS = 8;\nexport const MAX_SUMMARY_COLUMNS = 64;\nexport const MAX_RESULT_GROUPS = 10000;\nexport function withoutGrouping(query: QueryState): QueryState {\n const { grouping: _grouping, ...result } = query;\n return result;\n}\nexport const OP_LABEL: Record<SummaryOp, string> = {\n count: \"COUNT\",\n count_distinct: \"DISTINCT\",\n sum: \"SUM\",\n avg: \"AVG\",\n min: \"MIN\",\n max: \"MAX\",\n row: \"ROW\",\n formula: \"ƒx\",\n};\n\n/** Bind aggregation helpers to this instance's source catalogue. */\nexport function createGroupingModel<InputRow>(\n inputSchema: FieldSchema<InputRow>,\n) {\n const sourceField = (name: string) =>\n inputSchema.fields.find((f) => f.name === name);\n const groupableFields = inputSchema.fields.filter(\n (field) => isGroupable(field) && isSelectable(field),\n );\n const summaryFields = inputSchema.fields.filter(\n (f) => f.type !== \"textarray\" && isSelectable(f),\n );\n const representativeFields = inputSchema.fields.filter(\n (field) => isSortable(field) && field.type !== \"textarray\",\n );\n\n function representativeLabel(rule: RepresentativeRow): string {\n return rule.orderBy\n .map(\n (term) =>\n `${sourceField(term.field)?.label ?? term.field} ${term.dir === \"asc\" ? \"↑\" : \"↓\"}${term.nulls === \"first\" ? \" (empty first)\" : \"\"}`,\n )\n .join(\", \");\n }\n\n function allowedOps(field?: string): SummaryOp[] {\n if (!field) return [\"count\"];\n const f = sourceField(field);\n return f && isSelectable(f)\n ? [...(isMeasurable(f) ? aggOpsForField(f) : []), \"row\"]\n : [];\n }\n function summaryExpression(column: SummaryColumn): string {\n if (column.op === \"formula\") return column.expression ?? \"\";\n const field = column.field ? `[${column.field.replace(/\\]/g, \"]]\")}]` : \"\";\n return `${column.op === \"row\" ? \"COUNT\" : column.op.toUpperCase()}(${field})`;\n }\n function summaryProblem(column: SummaryColumn): string | null {\n if (column.op !== \"formula\") return null;\n try {\n const plan = compileMetric(summaryExpression(column), inputSchema);\n if (plan.dependencies.some((name) => !isSelectable(sourceField(name)!)))\n throw new Error(\"Aggregate fields must be selectable.\");\n if (hasRegex(plan))\n throw new Error(\n \"Regex aggregate formulas require isolated execution and are not supported in grouped columns.\",\n );\n return null;\n } catch (error) {\n return error instanceof Error ? error.message : String(error);\n }\n }\n function summaryLabel(column: SummaryColumn): string {\n if (column.op === \"formula\")\n return column.label?.trim() || \"Custom aggregate\";\n if (!column.field) return \"Row count\";\n const label = sourceField(column.field)?.label ?? column.field;\n const prefix: Record<SummaryOp, string> = {\n count: \"Count of\",\n count_distinct: \"Distinct\",\n sum: \"Total\",\n avg: \"Average\",\n min: \"Min\",\n max: \"Max\",\n row: \"Representative ·\",\n formula: \"\",\n };\n return `${prefix[column.op]} ${label}`;\n }\n\n function resultSchema(\n keys: string[],\n summaries: SummaryColumn[],\n ): FieldSchema<Row> {\n const fields: FieldDef<Row>[] = [\n {\n name: GROUP_ID_FIELD,\n label: \"Group identity\",\n type: \"text\",\n source: { kind: \"backend\" },\n select: { enabled: false },\n filter: { enabled: false },\n sort: { enabled: false },\n aggregate: { measure: false, groupable: false },\n },\n ...keys.flatMap((key): FieldDef<Row>[] => {\n const field = sourceField(key);\n // Draft/saved views may contain fields removed by the host. Leave\n // them in query state for repair; validate() still rejects execution.\n if (!field) return [];\n return [{\n name: key,\n label: field.label,\n type: field.type,\n source: { kind: \"backend\" },\n ...(field.select ? { select: { ...field.select } } : {}),\n ...(field.filter ? { filter: { ...field.filter } } : {}),\n ...(field.aggregate ? { aggregate: { ...field.aggregate } } : {}),\n ...(field.sort?.enabled !== undefined\n ? { sort: { enabled: field.sort.enabled } }\n : {}),\n ...(typeof field.render === \"string\" ? { render: field.render } : {}),\n ...(field.display ? { display: field.display } : {}),\n group: \"Group keys\",\n }];\n }),\n ];\n for (const column of summaries) {\n if (column.op === \"formula\") {\n let type: FieldDef<Row>[\"type\"] = \"number\";\n try {\n const compiled = compileMetric(\n summaryExpression(column),\n inputSchema,\n );\n type = compiled.type === \"null\" ? \"number\" : compiled.type;\n } catch {\n /* Invalid drafts show diagnostics in the editor. */\n }\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type,\n source: { kind: \"backend\" },\n group: \"Aggregates\",\n select: { align: type === \"number\" ? \"right\" : \"left\" },\n });\n continue;\n }\n const input = column.field ? sourceField(column.field) : undefined;\n const counting = column.op === \"count\" || column.op === \"count_distinct\";\n const numeric = counting || column.op === \"sum\" || column.op === \"avg\";\n const example = column.op === \"row\";\n fields.push({\n name: column.id,\n label: summaryLabel(column),\n type: numeric ? \"number\" : (input?.type ?? \"number\"),\n source: { kind: \"backend\" },\n select: {\n align: numeric || input?.type === \"number\" ? \"right\" : \"left\",\n },\n group: example ? \"Representative row\" : \"Summaries\",\n ...(!numeric && input?.aggregate?.groupable !== undefined\n ? { aggregate: { groupable: input.aggregate.groupable } }\n : {}),\n ...(typeof input?.render === \"string\" && !counting\n ? { render: input.render }\n : {}),\n ...(input?.display && !counting ? { display: input.display } : {}),\n });\n }\n return {\n name: `${inputSchema.name}:groups`,\n idField: GROUP_ID_FIELD,\n fields,\n defaultSelect: keys.filter(key => sourceField(key)).map((field) => ({ field })),\n defaultLimit: 25,\n };\n }\n\n // Typed tuples distinguish NULL, empty string, booleans and numbers. Key field\n // names are part of identity; key order and row arrival order are not.\n function keyValue(value: unknown): FormulaValue {\n if (value == null) return null;\n if (value instanceof Date) return value.toISOString();\n if (\n typeof value === \"string\" ||\n typeof value === \"boolean\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n )\n return value;\n throw new Error(\"Group keys must be finite scalar values.\");\n }\n function groupId(\n row: InputRow,\n keys: string[],\n schema: FieldSchema<InputRow>,\n ): string {\n const tuple = [...keys]\n .sort()\n .map((key) => [\n key,\n keyValue(\n readFieldValue(schema.fields.find((f) => f.name === key)!, row),\n ),\n ]);\n // Bound source strings before JSON escaping can multiply their allocation.\n if (\n tuple.some(\n ([key, value]) => String(key).length + String(value).length > 10000,\n )\n )\n throw new Error(\"Grouping key length budget exceeded.\");\n const id = JSON.stringify(tuple);\n if (id.length > 65536)\n throw new Error(\"Grouping key length budget exceeded.\");\n return id;\n }\n function compare(a: unknown, b: unknown): number {\n if (a === b) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n return a < b ? -1 : 1;\n }\n function representative(\n rows: InputRow[],\n rule: RepresentativeRow,\n schema: FieldSchema<InputRow>,\n ): InputRow {\n const identityField = schema.fields.find(\n (field) => field.name === schema.idField,\n );\n const identities = new Set<string | number>();\n for (const row of rows) {\n const id = identityField\n ? readFieldValue(identityField, row)\n : (row as Record<string, unknown>)[schema.idField];\n if (\n !(\n typeof id === \"string\" ||\n (typeof id === \"number\" && Number.isFinite(id))\n ) ||\n identities.has(id)\n )\n throw new Error(\n \"Representative rows require unique string or finite numeric source IDs.\",\n );\n identities.add(id);\n }\n // The same stable identity tie-break is used for every projection. Explicit\n // ordering by ID takes precedence; no arrival-order fallback is needed.\n const order = rule.orderBy.some((term) => term.field === schema.idField)\n ? rule.orderBy\n : [\n ...rule.orderBy,\n { field: schema.idField, dir: \"desc\", nulls: \"last\" } as const,\n ];\n const terms = order.map((term) => ({\n ...term,\n def: schema.fields.find((field) => field.name === term.field)!,\n }));\n return rows.reduce((best, row) => {\n for (const term of terms) {\n const value = (record: InputRow) => {\n const raw = term.def\n ? readFieldValue(term.def, record)\n : (record as Record<string, unknown>)[schema.idField];\n if (raw == null || term.def?.type !== \"datetime\") return raw;\n const instant = Date.parse(String(raw));\n return Number.isFinite(instant) ? instant : null;\n };\n const a = value(row),\n b = value(best);\n if (a == null || b == null) {\n if (a == null && b == null) continue;\n return (a == null) === (term.nulls === \"first\") ? row : best;\n }\n const rank = compare(a, b);\n if (rank !== 0)\n return (term.dir === \"asc\" ? rank < 0 : rank > 0) ? row : best;\n }\n return best;\n });\n }\n function groupRows(\n rows: InputRow[],\n schema: FieldSchema<InputRow>,\n keys: string[],\n summaries: SummaryColumn[],\n rule: RepresentativeRow | null = null,\n ): Row[] {\n if (!rule && summaries.some((column) => column.op === \"row\"))\n throw new Error(\n \"Configure representative-row ordering before selecting row values.\",\n );\n if (keys.length === 0) return [];\n if (keys.length > MAX_GROUP_BY_FIELDS || summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Grouping definition exceeds column limits.\");\n if (rows.length > 1_000_000)\n throw new Error(\"Grouping row budget exceeded.\");\n let bytes = rows.length * 16;\n let operations = 0;\n const groups = new Map<string, InputRow[]>();\n for (const row of rows) {\n const id = groupId(row, keys, schema);\n const bucket = groups.get(id);\n if (bucket) bucket.push(row);\n else {\n if (groups.size >= MAX_RESULT_GROUPS)\n throw new Error(\n `Grouping exceeds ${MAX_RESULT_GROUPS.toLocaleString()} groups.`,\n );\n bytes += id.length * 2 + 256;\n if (bytes > 16_000_000)\n throw new Error(\"Grouping retained-memory budget exceeded.\");\n groups.set(id, [row]);\n }\n }\n const formulas = new Map<string, { plan?: MetricPlan; error?: string }>(\n summaries\n .filter((c) => c.op !== \"row\")\n .map((column) => {\n try {\n const problem = summaryProblem(column);\n if (problem) throw new Error(problem);\n return [\n column.id,\n { plan: compileMetric(summaryExpression(column), schema) },\n ] as const;\n } catch (error) {\n return [\n column.id,\n { error: error instanceof Error ? error.message : String(error) },\n ] as const;\n }\n }),\n );\n const nodeCost = (node: FormulaNode): number =>\n 1 +\n (node.kind === \"call\"\n ? node.args.reduce((cost, child) => cost + nodeCost(child), 0)\n : 0);\n const costs = new Map(\n [...formulas].map(([id, compiled]) => [\n id,\n compiled.plan?.aggregates.map(nodeCost) ?? [],\n ]),\n );\n return [...groups].map(([id, members]) => {\n const output: Row = Object.assign(Object.create(null), {\n [GROUP_ID_FIELD]: id,\n });\n for (const key of keys)\n output[key] = readFieldValue(\n schema.fields.find((f) => f.name === key)!,\n members[0]!,\n );\n const chosen =\n rule && summaries.some((column) => column.op === \"row\")\n ? representative(members, rule, schema)\n : null;\n for (const column of summaries) {\n if (column.op !== \"row\") {\n const compiled = formulas.get(column.id)!;\n if (!compiled.plan) {\n output[column.id] = { computedError: compiled.error };\n continue;\n }\n const plan = compiled.plan;\n const rowPlans = metricAggregatePlans(plan);\n const reductions = plan.aggregates.map((node, i) =>\n reduceMetricValues(\n node,\n members.map((row) => {\n if ((operations += costs.get(column.id)?.[i] ?? 1) > 10_000_000)\n throw new Error(\"Grouping operation budget exceeded.\");\n const rowPlan = rowPlans[i];\n if (!rowPlan) return { value: 1 };\n const values = Object.fromEntries(\n rowPlan.dependencies.map((name) => {\n const value = readFieldValue(\n schema.fields.find((f) => f.name === name)!,\n row,\n );\n return [\n name,\n (value instanceof Date\n ? value.toISOString()\n : (value ?? null)) as FormulaValue,\n ];\n }),\n );\n return formulaRuntime(rowPlan.ast, values);\n }),\n ),\n );\n const result = evaluateMetricReductions(plan, reductions);\n output[column.id] = result.error\n ? { computedError: result.error }\n : result.value;\n continue;\n }\n const field = schema.fields.find((f) => f.name === column.field);\n if (column.op === \"row\") {\n output[column.id] =\n field && chosen ? readFieldValue(field, chosen) : null;\n continue;\n }\n }\n return output;\n });\n }\n function filteredInput(\n rows: InputRow[],\n query: QueryState,\n schema: FieldSchema<InputRow>,\n options: QueryEvaluationOptions = {},\n ): InputRow[] {\n // GROUP BY operates on all matching source records, never on a displayed page.\n return selectMetricShownRows(\n rows,\n {\n ...withoutGrouping(query),\n aggregations: [],\n orderBy: [],\n offset: 0,\n limit: Math.max(1, rows.length),\n },\n { ...schema, defaultSort: [] },\n options,\n );\n }\n\n /** Reconcile only consumers of row values when the shared selection changes.\n * Aggregate outputs and metrics over them keep their meaning. */\n function reconcileRepresentative(\n query: QueryState,\n summaries: SummaryColumn[],\n schema: FieldSchema<Row>,\n remove: boolean,\n ): QueryState {\n const affected = new Set(\n summaries.filter((s) => s.op === \"row\").map((s) => s.id),\n );\n if (!affected.size) return query;\n // Computed columns can depend on representative fields transitively.\n let grew = true;\n while (grew) {\n grew = false;\n for (const f of schema.fields) {\n if (\n !affected.has(f.name) &&\n f.source.kind === \"derived\" &&\n f.source.dependencies?.some((name) => affected.has(name))\n ) {\n affected.add(f.name);\n grew = true;\n }\n }\n }\n return {\n ...query,\n offset: 0,\n select: remove\n ? query.select.filter((c) => !affected.has(c.field))\n : query.select,\n where: query.where.filter(\n (term) => !predicatesOf(term).some((p) => affected.has(p.field)),\n ),\n orderBy: query.orderBy.filter((term) => !affected.has(term.field)),\n aggregations: (query.aggregations ?? []).filter((metric) => {\n if (metric.groupBy.some((name) => affected.has(name))) return false;\n try {\n return !metricPlans(metric, schema).some((plan) =>\n plan.dependencies.some((name) => affected.has(name)),\n );\n } catch {\n // A broken expression cannot be proven independent of the changed values.\n return false;\n }\n }),\n };\n }\n\n function validate(definition: GroupingDefinition): void {\n if (definition.diagnostics?.length)\n throw new Error(definition.diagnostics.join(\" \"));\n if (\n !definition.keys.length ||\n definition.keys.length > MAX_GROUP_BY_FIELDS ||\n new Set(definition.keys).size !== definition.keys.length ||\n definition.keys.some(\n (key) =>\n key === GROUP_ID_FIELD ||\n !groupableFields.some((f) => f.name === key),\n )\n )\n throw new Error(\"Choose valid group keys from the source schema.\");\n if (definition.summaries.length > MAX_SUMMARY_COLUMNS)\n throw new Error(\"Too many aggregate columns.\");\n const ids = new Set([\n GROUP_ID_FIELD,\n ...inputSchema.fields.map((field) => field.name),\n ]);\n for (const column of definition.summaries) {\n if (\n !column.id ||\n column.id.length > 256 ||\n ids.has(column.id) ||\n isComputedField(column.id) ||\n [\"__proto__\", \"constructor\", \"prototype\"].includes(column.id)\n )\n throw new Error(\n \"Aggregate column IDs must be unique and distinct from source fields.\",\n );\n ids.add(column.id);\n if (column.op === \"formula\") {\n const error = summaryProblem(column);\n if (error) throw new Error(error);\n } else if (\n !allowedOps(column.field).includes(column.op) ||\n (column.op === \"row\" && (!column.field || !definition.representative))\n )\n throw new Error(\"Invalid aggregate or representative column.\");\n }\n const rule = definition.representative;\n if (\n rule &&\n (!rule.orderBy.length ||\n rule.orderBy.length > MAX_REPRESENTATIVE_SORTS ||\n new Set(rule.orderBy.map((t) => t.field)).size !==\n rule.orderBy.length ||\n rule.orderBy.some(\n (t) =>\n !representativeFields.some((f) => f.name === t.field) ||\n ![\"asc\", \"desc\"].includes(t.dir) ||\n ![\"first\", \"last\"].includes(t.nulls),\n ))\n )\n throw new Error(\"Choose valid representative-row ordering.\");\n }\n\n return {\n inputSchema,\n sourceField,\n groupableFields,\n summaryFields,\n representativeFields,\n representativeLabel,\n allowedOps,\n summaryExpression,\n summaryProblem,\n summaryLabel,\n resultSchema,\n groupRows,\n filteredInput,\n reconcileRepresentative,\n validate,\n };\n}\nexport type GroupingModel<Row> = ReturnType<typeof createGroupingModel<Row>>;\n\n/** Evaluate the WHERE and grouping stages once; callers apply HAVING and paging\n * with the resulting schema and withoutGrouping(query). Never accepts a page\n * fetched by a transport as a complete source dataset. */\nexport function prepareGrouping<Row>(\n rows: Row[],\n schema: FieldSchema<Row>,\n grouping: GroupingState,\n options: QueryEvaluationOptions = {},\n) {\n const model = createGroupingModel(schema);\n if (grouping.source.grouping)\n throw new Error(\"Only one grouping stage is supported.\");\n model.validate(grouping);\n const inputs = model.filteredInput(rows, grouping.source, schema, options);\n return {\n inputs,\n rows: model.groupRows(\n inputs,\n schema,\n grouping.keys,\n grouping.summaries,\n grouping.representative,\n ),\n schema: model.resultSchema(grouping.keys, grouping.summaries),\n };\n}\n","import {\n predicatesOf,\n normalizeQueryState,\n type QueryState,\n type RowId,\n} from \"./query\";\nimport { toServerQuery, type ServerQuery } from \"./encode\";\nimport {\n isComputedField,\n type ComputedExecution,\n type RowComputedValues,\n} from \"./computed\";\nimport { selectedFields, type FieldSchema } from \"./schema\";\nimport type { MetricDiagnostic } from \"./metricTypes\";\n/** Versioned row projection keeps server-computed payload separate from host row fields. */\nexport interface ServerQueryV2 extends ServerQuery {\n version: 2;\n profile: string;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n /** Host must enforce this binding against the row response. */\n snapshot?: string;\n diagnostics: MetricDiagnostic[];\n}\nexport interface FetchRowsResultV2<Row> {\n version: 2;\n rows: Row[];\n total: number;\n computed: { id: RowId; values: RowComputedValues }[];\n execution: ComputedExecution;\n}\n/** Project with a previously resolved server capability envelope. This does not\n * authorize definitions or upload their source; the backend revalidates revisions. */\nexport function toServerQueryV2<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution: ComputedExecution,\n): ServerQueryV2 {\n const normalized = normalizeQueryState(q),\n legacy = toServerQuery(normalized, schema);\n const diagnostics: MetricDiagnostic[] = [];\n const expectedRevisions = Object.create(null) as Record<string, string>;\n const requireField = (\n name: string,\n operation: \"select\" | \"sort\",\n ): boolean => {\n const cap = execution.fields[name];\n const revision =\n execution.resolvedRevisions[name] ??\n execution.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (!cap?.[operation] || !revision) {\n diagnostics.push({\n code: \"unsupported_computed\",\n message: `Computed field ${name} is unavailable for ${operation}.`,\n from: 0,\n to: 1,\n });\n return false;\n }\n return true;\n };\n for (const [key, value] of Object.entries(execution.resolvedRevisions)) {\n if (\n key.length > 256 ||\n typeof value !== \"string\" ||\n !value ||\n value.length > 256\n )\n throw Error(\"Invalid computed revision envelope.\");\n expectedRevisions[key] = value;\n }\n const select = [...legacy.select];\n for (const c of normalized.select.length\n ? normalized.select\n : selectedFields(schema, normalized).map((f) => ({ field: f.name })))\n if (\n isComputedField(c.field) &&\n execution.fields[c.field]?.select &&\n requireField(c.field, \"select\")\n )\n select.push(c.field);\n // Retain unsupported clauses in state; gate execution using the server envelope.\n const orderBy: ServerQuery[\"orderBy\"] = [];\n for (const term of normalized.orderBy.length\n ? normalized.orderBy\n : (schema.defaultSort ?? [])) {\n if (isComputedField(term.field)) {\n if (requireField(term.field, \"sort\")) {\n if ((term.dir !== \"asc\" && term.dir !== \"desc\") || term.extract) {\n diagnostics.push({\n code: \"unsupported_computed_sort\",\n message: \"Invalid computed sort or extraction.\",\n from: 0,\n to: 1,\n });\n continue;\n }\n orderBy.push({\n field: term.field,\n dir: term.dir,\n ...(term.nulls === \"first\" || term.nulls === \"last\"\n ? { nulls: term.nulls }\n : {}),\n });\n }\n } else {\n const projected = toServerQuery(\n { ...normalized, orderBy: [term] },\n schema,\n ).orderBy;\n if (!projected.length)\n diagnostics.push({\n code: \"unsupported_sort\",\n message: `Unavailable server sort: ${term.field}.`,\n from: 0,\n to: 1,\n });\n orderBy.push(...projected);\n }\n }\n // The host appends its configured tie-break terms and stable identity. An\n // identity term here would take precedence over the host's ordering.\n if (\n legacy.where.length !== normalized.where.length ||\n q.where.reduce((n, t) => n + predicatesOf(t).length, 0) !==\n normalized.where.reduce((n, t) => n + predicatesOf(t).length, 0)\n )\n diagnostics.push({\n code: \"residual_filter\",\n message:\n \"Global execution is unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n });\n return {\n ...legacy,\n select: [...new Set(select)].sort(),\n orderBy,\n version: 2,\n profile: execution.profile,\n expectedRevisions,\n ...(execution.planToken ? { planToken: execution.planToken } : {}),\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n diagnostics,\n };\n}\n","import type { FormulaResult } from \"./formula\";\n\n/** Display arithmetic uses doubles, but an integer outside the safe range is\n * never accepted as an exact metric sample or result. This is not decimal math. */\nexport function assertMetricNumber(value: number): void {\n if (\n !Number.isFinite(value) ||\n (Number.isInteger(value) && !Number.isSafeInteger(value))\n ) {\n throw Error(\"Aggregate exceeds finite safe numeric precision.\");\n }\n}\n\nexport function checkedMetricResult(result: FormulaResult): FormulaResult {\n if (result.error || typeof result.value !== \"number\") return result;\n try {\n assertMetricNumber(result.value);\n return result;\n } catch (e) {\n return { value: null, error: (e as Error).message };\n }\n}\n","import { assertMetricNumber } from \"./metricPrecision\";\n// Exact bounded reductions over the complete scoped population.\nexport function percentile(sorted: number[], p: number): number | null {\n if (!Number.isFinite(p) || p < 0 || p > 1)\n throw Error(\"Percentile must be between zero and one.\");\n if (\n sorted.some((v, i) => !Number.isFinite(v) || (i > 0 && v < sorted[i - 1]!))\n )\n throw Error(\"Percentile inputs must be sorted finite numbers.\");\n sorted.forEach(assertMetricNumber);\n if (!sorted.length) return null;\n const position = (sorted.length - 1) * p,\n lower = Math.floor(position),\n fraction = position - lower;\n const a = sorted[lower]!,\n b = sorted[Math.min(lower + 1, sorted.length - 1)]!;\n // Floating underflow/roundoff cannot move an interpolated percentile outside its two samples.\n const raw = (1 - fraction) * a + fraction * b;\n assertMetricNumber(raw);\n const value = Math.min(b, Math.max(a, raw));\n return value;\n}\nexport function boxSummary(\n values: number[],\n whiskers: \"minmax\" | \"tukey\" = \"minmax\",\n) {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Distribution inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n const sorted = [...values].sort((a, b) => a - b),\n n = sorted.length;\n if (!n) return null;\n const min = sorted[0]!,\n max = sorted[n - 1]!,\n q1 = percentile(sorted, 0.25)!,\n median = percentile(sorted, 0.5)!,\n q3 = percentile(sorted, 0.75)!;\n const lowFence = q1 - 1.5 * (q3 - q1),\n highFence = q3 + 1.5 * (q3 - q1);\n const low = whiskers === \"tukey\" ? sorted.find((v) => v >= lowFence)! : min;\n const high =\n whiskers === \"tukey\"\n ? [...sorted].reverse().find((v) => v <= highFence)!\n : max;\n const outside =\n whiskers === \"tukey\" ? sorted.filter((v) => v < low || v > high) : [];\n // Bound the response while retaining both tails. Report the total separately.\n const outliers =\n outside.length <= 20\n ? outside\n : [...outside.slice(0, 10), ...outside.slice(-10)];\n const rawMean = sorted.reduce((sum, value) => sum + value / n, 0);\n // Check the numeric boundary before correcting insignificant range drift.\n assertMetricNumber(rawMean);\n const mean = Math.min(max, Math.max(min, rawMean));\n [min, q1, median, q3, max, mean, low, high].forEach(assertMetricNumber);\n return {\n n,\n min,\n q1,\n median,\n q3,\n max,\n mean,\n low,\n high,\n outliers,\n outlierCount: outside.length,\n whiskers,\n method: \"exact-linear\" as const,\n };\n}\nexport function histogramEdges(values: number[], bins: number): number[] {\n if (!Number.isInteger(bins) || bins < 2 || bins > 30)\n throw Error(\"Choose 2–30 histogram bins.\");\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n values.forEach(assertMetricNumber);\n if (!values.length) return [];\n let min = Infinity,\n max = -Infinity;\n for (const value of values) {\n min = Math.min(min, value);\n max = Math.max(max, value);\n }\n if (min === max) return [min, max]; // one point interval, not artificial spread\n if (!Number.isFinite(max - min))\n throw Error(\"Histogram range exceeds finite numeric precision.\");\n const edges = Array.from(\n { length: bins + 1 },\n (_, i) => min + (max - min) * (i / bins),\n );\n edges[0] = min;\n edges[bins] = max;\n edges.forEach(assertMetricNumber);\n if (edges.some((value, i) => i > 0 && value <= edges[i - 1]!))\n throw Error(\n \"Histogram bins are finer than numeric precision. Reduce the bin count.\",\n );\n return edges;\n}\nexport function histogramCounts(values: number[], edges: number[]): number[] {\n if (values.some((v) => !Number.isFinite(v)))\n throw Error(\"Histogram inputs must be finite numbers.\");\n if (!edges.length) {\n if (values.length) throw Error(\"Histogram values require edges.\");\n return [];\n }\n if (\n edges.length < 2 ||\n edges.some(\n (v, i) =>\n !Number.isFinite(v) ||\n (i > 0 &&\n (v < edges[i - 1]! || (v === edges[i - 1]! && edges.length !== 2))),\n )\n )\n throw Error(\"Histogram edges must be ordered finite boundaries.\");\n values.forEach(assertMetricNumber);\n edges.forEach(assertMetricNumber);\n const counts = Array<number>(edges.length - 1).fill(0);\n for (const value of values) {\n if (value < edges[0]! || value > edges[edges.length - 1]!)\n throw Error(\"Value falls outside shared histogram edges.\");\n // Lower inclusive, upper exclusive; the last bin also includes the maximum.\n let bin = 0;\n while (bin < counts.length - 1 && value >= edges[bin + 1]!) bin++;\n counts[bin] = counts[bin]! + 1;\n }\n return counts;\n}\n","import { coerceValue } from \"./ops\";\nimport { isOrGroup, type QueryState } from \"./query\";\nimport type { MetricDateGrouping, MetricValue } from \"./metricTypes\";\nimport { Temporal } from \"temporal-polyfill\";\n\nexport const METRIC_DATE_INTERVALS = [\n \"hour\",\n \"day\",\n \"week\",\n \"month\",\n \"year\",\n] as const;\n\n/** Strict calendar input; timestamps require an explicit offset. */\nexport function metricDateTime(value: MetricValue, timeZone = \"UTC\"): number {\n if (\n typeof value !== \"string\" ||\n !/^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?(?:Z|[+-]\\d{2}:\\d{2}))?$/.test(\n value,\n )\n )\n throw Error(\n \"Date grouping requires ISO dates or timestamps with a timezone.\",\n );\n const time = Date.parse(value),\n month = Number(value.slice(5, 7)),\n day = Number(value.slice(8, 10));\n const calendar = new Date(0);\n calendar.setUTCFullYear(Number(value.slice(0, 4)), month, 0);\n if (\n !Number.isFinite(time) ||\n month < 1 ||\n month > 12 ||\n day < 1 ||\n day > calendar.getUTCDate()\n )\n throw Error(\"Invalid date grouping value.\");\n return value.length === 10 && timeZone !== \"UTC\"\n ? Temporal.PlainDate.from(value).toZonedDateTime(timeZone).epochMilliseconds\n : time;\n}\n\n/** Find an offset change inside one bucket window. The polyfill's \"previous\"\n * transition lookup caps future searches to about three years from today. */\nfunction metricOffsetTransition(\n start: number,\n end: number,\n timeZone: string,\n): number | undefined {\n if (end <= start) return undefined;\n const offset = (time: number) =>\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone)\n .offsetNanoseconds;\n const before = offset(start);\n if (before === offset(end)) return undefined;\n // IANA transitions are separated by more than this hour-sized window.\n while (end - start > 1) {\n const middle = Math.floor((start + end) / 2);\n if (offset(middle) === before) start = middle;\n else end = middle;\n }\n return end;\n}\n\nexport function metricDateFloor(\n time: number,\n interval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const floor =\n time - zoned.minute * 60000 - zoned.second * 1000 - zoned.millisecond;\n // An offset change can start a partial hour (e.g. Lord Howe's 30-minute\n // DST shift). Split there rather than mapping into the previous offset.\n return metricOffsetTransition(floor, time, timeZone) ?? floor;\n }\n let date = zoned.toPlainDate();\n if (interval === \"week\") date = date.subtract({ days: date.dayOfWeek - 1 });\n if (interval === \"month\" || interval === \"year\")\n date = date.with({ day: 1 });\n if (interval === \"year\") date = date.with({ month: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n date.setUTCMinutes(0, 0, 0);\n if (interval !== \"hour\") date.setUTCHours(0);\n if (interval === \"week\")\n date.setUTCDate(date.getUTCDate() - ((date.getUTCDay() + 6) % 7));\n if (interval === \"month\" || interval === \"year\") date.setUTCDate(1);\n if (interval === \"year\") date.setUTCMonth(0);\n return date.getTime();\n}\n\nexport function metricDateNext(\n time: number,\n interval: MetricDateGrouping[\"interval\"],\n timeZone = \"UTC\",\n): number {\n if (timeZone !== \"UTC\") {\n const zoned =\n Temporal.Instant.fromEpochMilliseconds(time).toZonedDateTimeISO(timeZone);\n if (interval === \"hour\") {\n const target = zoned\n .toPlainDateTime()\n .with({\n minute: 0,\n second: 0,\n millisecond: 0,\n microsecond: 0,\n nanosecond: 0,\n })\n .add({ hours: 1 });\n let next = target.toZonedDateTime(timeZone).epochMilliseconds;\n if (next <= time)\n next = target.toZonedDateTime(timeZone, {\n disambiguation: \"later\",\n }).epochMilliseconds;\n return metricOffsetTransition(time, next, timeZone) ?? next;\n }\n let date = zoned.toPlainDate();\n if (interval === \"month\") date = date.with({ day: 1 }).add({ months: 1 });\n else if (interval === \"year\")\n date = date.with({ month: 1, day: 1 }).add({ years: 1 });\n else if (interval === \"week\")\n date = date.subtract({ days: date.dayOfWeek - 1 }).add({ weeks: 1 });\n else date = date.add({ days: 1 });\n return date.toZonedDateTime(timeZone).epochMilliseconds;\n }\n const date = new Date(time);\n if (interval === \"hour\") date.setUTCHours(date.getUTCHours() + 1);\n else if (interval === \"month\") date.setUTCMonth(date.getUTCMonth() + 1);\n else if (interval === \"year\") date.setUTCFullYear(date.getUTCFullYear() + 1);\n else date.setUTCDate(date.getUTCDate() + (interval === \"week\" ? 7 : 1));\n return date.getTime();\n}\n\n/** A date-only Through value includes the whole local day, even for hourly groups. */\nfunction customEndTime(value: string, timeZone = \"UTC\"): number {\n const time = metricDateTime(value, timeZone);\n return value.length === 10 ? metricDateNext(time, \"day\", timeZone) - 1 : time;\n}\n\nexport function validateDateGrouping(config: MetricDateGrouping): void {\n if (\n typeof config.field !== \"string\" ||\n !config.field ||\n config.field.length > 256 ||\n !METRIC_DATE_INTERVALS.includes(config.interval) ||\n typeof config.includeEmpty !== \"boolean\" ||\n ![\"query\", \"observed\", \"custom\"].includes(config.range)\n )\n throw Error(\"Invalid date grouping definition.\");\n if (config.timeZone !== undefined) {\n if (\n typeof config.timeZone !== \"string\" ||\n !config.timeZone ||\n config.timeZone.length > 80 ||\n /^[+-]/.test(config.timeZone)\n )\n throw Error(\n \"Use a valid IANA grouping timezone, such as America/Denver or UTC.\",\n );\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: config.timeZone });\n } catch {\n throw Error(\n \"Use a valid IANA grouping timezone, such as America/Denver or UTC.\",\n );\n }\n }\n if (config.includeEmpty && config.range === \"custom\") {\n const start = metricDateTime(config.start ?? \"\", config.timeZone),\n end = customEndTime(config.end ?? \"\", config.timeZone);\n if (end < start)\n throw Error(\"The end date must be on or after the start date.\");\n }\n}\n\n/** Only conjunctive bounds prove a domain; OR alternatives are not bounds. */\nexport function metricDateRange(\n config: MetricDateGrouping,\n query: QueryState,\n observed: readonly number[],\n now: number,\n canonical: (field: string) => string,\n): [number, number] | undefined {\n let min = Infinity,\n max = -Infinity;\n for (const time of observed) {\n min = Math.min(min, time);\n max = Math.max(max, time);\n }\n if (config.range === \"observed\")\n return observed.length ? [min, max] : undefined;\n if (config.range === \"custom\") {\n const start = metricDateFloor(\n metricDateTime(config.start ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n const end = metricDateFloor(\n customEndTime(config.end ?? \"\", config.timeZone),\n config.interval,\n config.timeZone,\n );\n if (observed.length && (start > min || end < max))\n throw Error(\n \"Custom date bounds must include all observed buckets. Narrow the query filters to exclude data.\",\n );\n return [start, end];\n }\n let start = -Infinity,\n end = Infinity;\n for (const term of query.where) {\n if (\n isOrGroup(term) ||\n term.negated ||\n canonical(term.field) !== canonical(config.field)\n )\n continue;\n if (![\"=\", \">\", \">=\", \"<\", \"<=\"].includes(term.op)) continue;\n const time = Number(coerceValue(\"datetime\", term.value, now));\n if (term.op === \">\" || term.op === \">=\" || term.op === \"=\")\n start = Math.max(start, time + (term.op === \">\" ? 1 : 0));\n if (term.op === \"<\" || term.op === \"<=\" || term.op === \"=\")\n end = Math.min(end, time - (term.op === \"<\" ? 1 : 0));\n }\n if (!Number.isFinite(start) || !Number.isFinite(end))\n throw Error(\n \"Include empty dates needs a bounded date filter. Choose observed dates or a custom range.\",\n );\n if (end < start) return undefined;\n return [\n metricDateFloor(start, config.interval, config.timeZone),\n metricDateFloor(end, config.interval, config.timeZone),\n ];\n}\n","import type { ComputedExecution } from \"./computed\";\nimport { isComputedField } from \"./computed\";\nimport {\n compileFormula,\n formulaRuntime,\n FormulaError,\n type FormulaNode,\n type FormulaPlan,\n type FormulaType,\n type FormulaValue,\n type FormulaDiagnostic,\n type FormulaResult,\n type FormulaFunction,\n} from \"./formula\";\nimport { aggOpsForField, isGroupable, isMeasurable } from \"./agg\";\nimport {\n indexFields,\n readFieldValue,\n resolveFieldName,\n type FieldDef,\n type FieldSchema,\n} from \"./schema\";\nimport {\n normalizeQueryState,\n predicatesOf,\n type AggregationClause,\n type AggOp,\n type QueryState,\n} from \"./query\";\nimport { applyQuery } from \"./apply\";\nimport { prepareGrouping, withoutGrouping, type GroupedRow } from \"./grouping\";\nimport { computedInputAllowed } from \"./apply\";\nimport { toServerQueryV2 } from \"./execution\";\nimport {\n toServerQuery,\n type AggregationResult,\n type AggregationBucket,\n} from \"./encode\";\nimport type { MetricQuery, MetricValue, MetricSort } from \"./metricTypes\";\nimport {\n boxSummary,\n histogramEdges,\n histogramCounts,\n} from \"./metricDistributions\";\nimport { assertMetricNumber, checkedMetricResult } from \"./metricPrecision\";\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport {\n metricDateTime,\n metricDateFloor,\n metricDateNext,\n metricDateRange,\n validateDateGrouping,\n} from \"./metricDates\";\nconst aggregates = new Set([\n \"COUNT\",\n \"COUNT_DISTINCT\",\n \"SUM\",\n \"AVG\",\n \"MIN\",\n \"MAX\",\n \"MEDIAN\",\n]);\n/** Functions available only in aggregate expressions, separate from row formulas. */\nexport const METRIC_FUNCTIONS: FormulaFunction[] = [\n [\"COUNT\", \"Count rows, or non-empty values.\"],\n [\"COUNT_DISTINCT\", \"Count distinct non-empty values.\"],\n [\"SUM\", \"Total numeric values in each group.\"],\n [\"AVG\", \"Average numeric values in each group.\"],\n [\"MIN\", \"Smallest non-empty value in each group.\"],\n [\"MAX\", \"Largest non-empty value in each group.\"],\n [\n \"MEDIAN\",\n \"Middle numeric value; averages the middle pair. Ignores empty values.\",\n ],\n].map(([name, description]) => ({\n name: name!,\n description: description!,\n signature: `${name}(row expression${name === \"COUNT\" ? \"?\" : \"\"})`,\n min: name === \"COUNT\" ? 0 : 1,\n max: 1,\n result: name === \"MIN\" || name === \"MAX\" ? \"branch\" : \"number\",\n args: [\"SUM\", \"AVG\", \"MEDIAN\"].includes(name!) ? [\"number\"] : \"any\",\n}));\nexport interface MetricPlan extends FormulaPlan {\n aggregates: Extract<FormulaNode, { kind: \"call\" }>[];\n aggregateTypes: FormulaType[];\n}\nexport function compileMetric(\n expression: string,\n schema: FieldSchema | readonly FieldDef[],\n resolve?: (name: string) => FormulaPlan | undefined,\n): MetricPlan {\n const fields: readonly FieldDef[] = Array.isArray(schema)\n ? schema\n : (schema as FieldSchema).fields;\n const nodes: MetricPlan[\"aggregates\"] = [];\n const aggregateTypes: FormulaType[] = [];\n let inAggregate = false;\n const plan = compileFormula(\n expression,\n resolve\n ? fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : fields,\n resolve,\n (node, check) => {\n if (node.kind !== \"call\" || !aggregates.has(node.name)) return undefined;\n if (inAggregate)\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n node.from,\n node.to,\n );\n if (\n node.args.length > 1 ||\n (node.name !== \"COUNT\" && node.args.length !== 1)\n )\n throw new FormulaError(\n `${node.name} requires ${node.name === \"COUNT\" ? \"zero or one argument\" : \"one argument\"}.`,\n node.from,\n node.to,\n );\n inAggregate = true;\n let type: FormulaType;\n try {\n type = node.args[0] ? check(node.args[0]) : \"number\";\n } finally {\n inAggregate = false;\n }\n const visit = (n: FormulaNode) => {\n if (n.kind === \"field\") {\n const field = fields.find((f) => f.name === n.name);\n if (!field)\n throw new FormulaError(\n `Unresolved dependency ${n.name}.`,\n n.from,\n n.to,\n );\n // MEDIAN is formula-only, so it is absent from the default AggOp\n // list. Explicit field restrictions still apply to every reduction.\n if (\n !isMeasurable(field) ||\n ((field.aggregate?.ops !== undefined ||\n (node.args[0] === n && node.name !== \"MEDIAN\")) &&\n !aggOpsForField(field).includes(node.name.toLowerCase() as AggOp))\n )\n throw new FormulaError(\n `Field ${n.name} does not allow ${node.name}.`,\n n.from,\n n.to,\n );\n } else if (n.kind === \"call\") {\n if (aggregates.has(n.name))\n throw new FormulaError(\n \"Nested aggregates are not allowed.\",\n n.from,\n n.to,\n );\n n.args.forEach(visit);\n }\n };\n node.args.forEach(visit);\n if (\n [\"SUM\", \"AVG\", \"MEDIAN\"].includes(node.name) &&\n ![\"number\", \"null\"].includes(type)\n )\n throw new FormulaError(\n `${node.name} requires numeric input.`,\n node.from,\n node.to,\n );\n if (\n [\"MIN\", \"MAX\", \"COUNT_DISTINCT\"].includes(node.name) &&\n (type === \"textarray\" ||\n (type === \"bool\" && node.name !== \"COUNT_DISTINCT\"))\n )\n throw new FormulaError(\n `Unsupported ${node.name} input type.`,\n node.from,\n node.to,\n );\n nodes.push(node);\n aggregateTypes.push(type);\n return [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\", \"AVG\", \"MEDIAN\"].includes(\n node.name,\n )\n ? \"number\"\n : type;\n },\n );\n const groupCheck = (node: FormulaNode) => {\n if (node.kind === \"field\")\n throw new FormulaError(\n \"Row fields must be inside an aggregate.\",\n node.from,\n node.to,\n );\n if (node.kind === \"call\" && !aggregates.has(node.name)) {\n if (node.name.startsWith(\"REGEX_\"))\n throw new FormulaError(\n \"Regex is supported only inside aggregate row expressions.\",\n node.from,\n node.to,\n );\n node.args.forEach(groupCheck);\n }\n };\n groupCheck(plan.ast);\n if (!nodes.length)\n throw new FormulaError(\"A metric must contain an aggregate.\");\n if (plan.type === \"textarray\")\n throw new FormulaError(\"Metrics must return scalar values.\");\n return { ...plan, aggregates: nodes, aggregateTypes };\n}\n/** Row plans for worker evaluation. Null denotes COUNT(), which requires only row count. */\nexport function metricAggregatePlans(plan: MetricPlan): (FormulaPlan | null)[] {\n return plan.aggregates.map((node) => {\n if (!node.args[0]) return null;\n const dependencies = new Set<string>();\n const visit = (n: FormulaNode): void => {\n if (n.kind === \"field\") dependencies.add(n.name);\n else if (n.kind === \"call\") n.args.forEach(visit);\n };\n visit(node.args[0]);\n // Aggregate argument type is retained by the compiler in aggregateTypes.\n return {\n ast: node.args[0],\n dependencies: [...dependencies].sort(),\n type: plan.aggregateTypes[plan.aggregates.indexOf(node)]!,\n };\n });\n}\n/** Reduce exact per-row worker results; errors are not silently treated as NULL. */\nexport interface MetricReductionOptions {\n /** Retained distinct entries, independently bounded from row count. */\n maxDistinctValues?: number;\n /** Conservative UTF-16 payload plus per-entry storage estimate. */\n maxDistinctBytes?: number;\n}\nfunction distinctAccumulator(options: MetricReductionOptions) {\n const values = new Set<string | number | boolean>();\n let bytes = 0;\n const cardinality = options.maxDistinctValues ?? 100000;\n const byteLimit = options.maxDistinctBytes ?? 16000000;\n if (\n !Number.isSafeInteger(cardinality) ||\n cardinality < 0 ||\n !Number.isSafeInteger(byteLimit) ||\n byteLimit < 0\n )\n throw Error(\"Invalid distinct budget.\");\n return {\n add(value: FormulaValue) {\n const v = scalar(value);\n if (typeof v === \"number\") assertMetricNumber(v);\n if (v === null || values.has(v)) return;\n const size = 64 + (typeof v === \"string\" ? v.length * 2 : 8);\n if (values.size >= cardinality || size > byteLimit - bytes)\n throw Error(\"Metric distinct retained-memory budget exceeded.\");\n values.add(v);\n bytes += size;\n },\n result: () => ({ value: values.size }),\n };\n}\nexport function reduceMetricValues(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: readonly FormulaResult[],\n options: MetricReductionOptions = {},\n): FormulaResult {\n return reduceResults(node, results, options);\n}\nfunction reduceResults(\n node: Extract<FormulaNode, { kind: \"call\" }>,\n results: Iterable<FormulaResult>,\n options: MetricReductionOptions,\n): FormulaResult {\n try {\n if (!aggregates.has(node.name)) throw Error(\"Expected an aggregate node.\");\n const distinct =\n node.name === \"COUNT_DISTINCT\" ? distinctAccumulator(options) : undefined;\n const values: FormulaValue[] = [];\n let count = 0,\n nonnull = 0,\n error: string | undefined;\n for (const r of results) {\n count++;\n if (r.error) {\n error ??= r.error;\n continue;\n }\n if (r.value === null) continue;\n if (node.name !== \"COUNT\" && !distinct && typeof r.value === \"number\")\n assertMetricNumber(r.value);\n nonnull++;\n if (distinct) distinct.add(r.value);\n else if (node.name !== \"COUNT\") values.push(r.value);\n }\n if (error) return { value: null, error };\n if (distinct) return distinct.result();\n if (node.name === \"COUNT\")\n return { value: node.args.length ? nonnull : count };\n if (!values.length) return { value: null };\n if (node.name === \"MEDIAN\") {\n const sorted = values\n .map((value) => {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw Error(\"Expected a finite number.\");\n return value;\n })\n .sort((a, b) => a - b);\n const mid = Math.floor(sorted.length / 2);\n const value =\n sorted.length % 2\n ? sorted[mid]!\n : sorted[mid - 1]! / 2 + sorted[mid]! / 2;\n assertMetricNumber(value);\n return { value };\n }\n if (node.name === \"SUM\" || node.name === \"AVG\") {\n let sum = 0;\n for (const v of values) {\n if (typeof v !== \"number\" || !Number.isFinite(v))\n throw Error(\"Expected a finite number.\");\n sum += v / (node.name === \"AVG\" ? values.length : 1);\n assertMetricNumber(sum);\n }\n return { value: sum };\n }\n return {\n value: values.reduce((a, b) =>\n compareMetricValues(scalar(a), scalar(b)) *\n (node.name === \"MIN\" ? 1 : -1) <=\n 0\n ? a\n : b,\n ),\n };\n } catch (e) {\n return { value: null, error: e instanceof Error ? e.message : String(e) };\n }\n}\n/** Evaluate the group AST lazily from reductions indexed like plan.aggregates.\n * A dead IF/COALESCE branch does not observe a failed aggregate in that branch. */\nexport function evaluateMetricReductions(\n plan: MetricPlan,\n reductions: readonly FormulaResult[],\n): FormulaResult {\n const key = (n: FormulaNode) =>\n `${n.from}:${n.to}:${n.kind === \"call\" ? n.name : n.kind}`;\n const byNode = new Map(\n plan.aggregates.map((n, i) => [key(n), reductions[i]]),\n );\n return checkedMetricResult(\n formulaRuntime(plan.ast, {}, (node) =>\n byNode.has(key(node))\n ? checkedMetricResult(\n byNode.get(key(node)) ?? {\n value: null,\n error: \"Missing aggregate reduction.\",\n },\n )\n : undefined,\n ),\n );\n}\nexport function metricExpression(clause: AggregationClause): string {\n return (\n clause.expression ??\n `${clause.op.toUpperCase()}(${clause.field ? `[${clause.field.replace(/]/g, \"]]\")}]` : \"\"})`\n );\n}\nexport function hasRegex(plan: FormulaPlan): boolean {\n const visit = (n: FormulaNode): boolean =>\n n.kind === \"call\" && (n.name.startsWith(\"REGEX_\") || n.args.some(visit));\n return visit(plan.ast);\n}\nfunction distributionActive(c: AggregationClause): boolean {\n return (\n !!c.distribution &&\n (!c.display || c.display.kind === \"box\" || c.display.kind === \"histogram\")\n );\n}\nexport function metricPlans(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaPlan[] {\n if (distributionActive(c)) {\n const p = compileFormula(\n c.distribution!.input,\n resolve\n ? schema.fields.filter(\n (f) => f.source.kind !== \"derived\" || !f.source.computedId,\n )\n : schema.fields,\n resolve,\n );\n if (p.type !== \"number\" && p.type !== \"null\")\n throw new FormulaError(\"Distribution input must be numeric.\");\n if (![\"box\", \"histogram\"].includes(c.distribution!.kind))\n throw new FormulaError(\"Invalid distribution kind.\");\n if (\n c.distribution!.kind === \"histogram\" &&\n (!Number.isInteger(c.distribution!.bins ?? 10) ||\n (c.distribution!.bins ?? 10) < 2 ||\n (c.distribution!.bins ?? 10) > 30)\n )\n throw new FormulaError(\"Choose 2–30 histogram bins.\");\n for (const name of p.dependencies) {\n const field = schema.fields.find((f) => f.name === name)!;\n if (!isMeasurable(field))\n throw new FormulaError(`Field ${name} cannot be a distribution input.`);\n }\n if (c.scope !== \"shownRows\" && hasRegex(p))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return [p];\n }\n const out = [\n compileMetric(\n metricExpression(\n c.expression === undefined && c.field\n ? { ...c, field: resolveFieldName(schema, c.field) ?? c.field }\n : c,\n ),\n schema,\n resolve,\n ),\n ];\n if (c.display?.kind === \"scatter\") {\n out.push(compileMetric(c.expressionY ?? \"\", schema, resolve));\n if (out.some((p) => p.type !== \"number\" && p.type !== \"null\"))\n throw new FormulaError(\"Scatter expressions must be numeric.\");\n }\n if (c.scope !== \"shownRows\" && out.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return out;\n}\nexport function validateMetric(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): FormulaDiagnostic[] {\n try {\n if (c.diagnostics?.length) throw new FormulaError(c.diagnostics.join(\" \"));\n if (c.groupBy.length > 20)\n throw new FormulaError(\"At most 20 grouping fields are allowed.\");\n for (const key of c.groupBy) {\n const f = schema.fields.find(\n (f) => f.name === (resolveFieldName(schema, key) ?? key),\n );\n if (!f || !isGroupable(f))\n throw new FormulaError(`Field ${key} cannot group metrics.`);\n }\n if (c.dateGrouping) {\n validateDateGrouping(c.dateGrouping);\n const field =\n resolveFieldName(schema, c.dateGrouping.field) ?? c.dateGrouping.field;\n if (\n field !==\n (resolveFieldName(schema, c.groupBy[0] ?? \"\") ?? c.groupBy[0]) ||\n schema.fields.find((f) => f.name === field)?.type !== \"datetime\"\n )\n throw new FormulaError(\n \"Date grouping must use the first grouping field, with a datetime type.\",\n );\n if (distributionActive(c))\n throw new FormulaError(\n \"Date grouping currently supports scalar metrics, not distributions.\",\n );\n }\n if (\n c.groupLimit !== undefined &&\n (!Number.isInteger(c.groupLimit) ||\n c.groupLimit < 1 ||\n c.groupLimit > 10000)\n )\n throw new FormulaError(\"Group limit must be 1–10,000.\");\n for (const s of c.sort ?? []) {\n if (s.key === \"y\" && c.display?.kind !== \"scatter\")\n throw new FormulaError(\"Y sorting requires a scatter metric.\");\n if (s.key === \"samples\" && !distributionActive(c))\n throw new FormulaError(\n \"Sample sorting requires a distribution metric.\",\n );\n if (\n s.key.startsWith(\"group\") &&\n Number(s.key.slice(5)) >= c.groupBy.length\n )\n throw new FormulaError(\"Sort refers to an unavailable grouping key.\");\n }\n const compiled = metricPlans(c, schema, resolve);\n if (c.scope !== \"shownRows\" && compiled.some(hasRegex))\n throw new FormulaError(\"Regex is unavailable for all-matching metrics.\");\n return [];\n } catch (e) {\n return [\n {\n message: e instanceof Error ? e.message : String(e),\n from: e instanceof FormulaError ? e.from : 0,\n to: e instanceof FormulaError ? e.to : 1,\n },\n ];\n }\n}\nexport function metricDependencies(\n c: AggregationClause,\n schema: FieldSchema,\n resolve?: (name: string) => FormulaPlan | undefined,\n): string[] {\n return [\n ...new Set([\n ...c.groupBy.map((name) => resolveFieldName(schema, name) ?? name),\n ...metricPlans(c, schema, resolve).flatMap((p) => p.dependencies),\n ]),\n ].sort();\n}\nexport function metricComputationKey(\n clauses: readonly AggregationClause[],\n): string {\n return JSON.stringify(\n clauses\n .map((c) => ({\n id: c.id,\n diagnostics: c.diagnostics,\n unsupportedOp: c.unsupportedOp,\n expression: distributionActive(c) ? undefined : metricExpression(c),\n expressionY: c.display?.kind === \"scatter\" ? c.expressionY : undefined,\n scope: c.scope ?? \"allMatching\",\n groupBy: c.groupBy,\n dateGrouping: c.dateGrouping,\n sort: c.sort,\n groupLimit: c.groupLimit,\n distribution: distributionActive(c) ? c.distribution : undefined,\n }))\n .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)),\n );\n}\nexport function toMetricQuery<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n execution?: ComputedExecution,\n): MetricQuery {\n const originalSchema = schema;\n const fields = new Map(schema.fields.map((f) => [f.name, f]));\n // A local computed field never establishes remote authority.\n for (const [name, prior] of fields)\n if (isComputedField(name))\n fields.set(name, {\n ...prior,\n aggregate: { measure: false, groupable: false },\n });\n for (const [name, cap] of Object.entries(execution?.fields ?? {}))\n if (isComputedField(name)) {\n const prior = fields.get(name);\n fields.set(name, {\n ...prior,\n name,\n label: prior?.label ?? name,\n type: cap.type,\n source: { kind: \"backend\" },\n filter: { enabled: false },\n sort: { enabled: cap.sort },\n aggregate: {\n ...prior?.aggregate,\n measure: cap.measure,\n groupable: cap.group,\n },\n });\n }\n schema = { ...schema, fields: [...fields.values()] };\n const raw = q;\n q = normalizeQueryState(q);\n const server = toServerQuery(q, schema);\n const metrics = (q.aggregations ?? []).map((c) => {\n const {\n label,\n layout,\n display,\n distribution,\n expression,\n expressionY,\n dateGrouping,\n ...rest\n } = c;\n return {\n ...rest,\n ...(!distributionActive(c) && expression !== undefined\n ? { expression }\n : {}),\n ...(display?.kind === \"scatter\"\n ? {\n display: { kind: \"scatter\" as const },\n ...(expressionY !== undefined ? { expressionY } : {}),\n }\n : {}),\n ...(distributionActive(c) && distribution ? { distribution } : {}),\n };\n });\n const diagnostics = (q.aggregations ?? []).flatMap((c) =>\n validateMetric(c, schema).map((d) => ({\n ...d,\n metricId: c.id,\n code: \"invalid_metric\",\n })),\n );\n for (const c of q.aggregations ?? [])\n if (c.dateGrouping)\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_date_grouping\",\n from: 0,\n to: 1,\n message: \"Date grouping currently requires local metric execution.\",\n });\n try {\n assertMetricQueryState(raw, originalSchema);\n } catch (e) {\n diagnostics.push({\n message: String(e),\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"invalid_query\",\n });\n }\n const ids = new Set<string>();\n for (const c of q.aggregations ?? []) {\n if (ids.has(c.id))\n diagnostics.push({\n message: \"Duplicate metric ID.\",\n from: 0,\n to: 1,\n metricId: c.id,\n code: \"duplicate_metric\",\n });\n ids.add(c.id);\n }\n if (\n server.where.length !== q.where.length ||\n queryStateKey(raw.where) !== queryStateKey(q.where)\n )\n diagnostics.push({\n message: \"Metrics unavailable with residual client-only filters.\",\n from: 0,\n to: 1,\n metricId: \"\",\n code: \"residual_filter\",\n });\n for (const c of q.aggregations ?? []) {\n try {\n for (const name of metricDependencies(c, schema))\n if (isComputedField(name)) {\n const revision =\n execution?.resolvedRevisions[name] ??\n execution?.resolvedRevisions[name.slice(\"@computed/\".length)];\n if (\n typeof revision !== \"string\" ||\n !revision ||\n revision.length > 256\n )\n diagnostics.push({\n metricId: c.id,\n code: \"definition_revision\",\n message: `Missing expected revision for ${name}.`,\n from: 0,\n to: 1,\n });\n if (!execution?.fields[name])\n diagnostics.push({\n metricId: c.id,\n code: \"unsupported_computed\",\n message: `Missing server capability for ${name}.`,\n from: 0,\n to: 1,\n });\n }\n } catch {\n /* compilation diagnostic already included */\n }\n }\n // Row and metric page membership share effective defaults and v2 gates.\n const rowProjection = toServerQueryV2(\n { ...q, select: [{ field: schema.idField }] },\n originalSchema,\n execution ?? {\n profile: \"\",\n planToken: \"\",\n fields: {},\n resolvedRevisions: {},\n },\n );\n if (q.aggregations?.some((c) => c.scope === \"shownRows\"))\n diagnostics.push(\n ...rowProjection.diagnostics.map((d) => ({\n ...d,\n metricId: \"\",\n code: d.code ?? \"residual_order\",\n })),\n );\n return {\n version: 2,\n where: server.where,\n orderBy: rowProjection.orderBy,\n limit: q.limit,\n offset: q.offset,\n metrics,\n diagnostics,\n ...(execution\n ? {\n profile: execution.profile,\n expectedRevisions: { ...execution.resolvedRevisions },\n planToken: execution.planToken,\n ...(execution.snapshot !== undefined\n ? { snapshot: execution.snapshot }\n : {}),\n }\n : {}),\n };\n}\nfunction queryStateKey(value: unknown): string | undefined {\n return JSON.stringify(value, (_key, item: unknown) =>\n item && typeof item === \"object\" && !Array.isArray(item)\n ? Object.fromEntries(\n Object.entries(item).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0)),\n )\n : item,\n );\n}\n/** Reject normalization losses before claiming an exact population. */\nfunction assertMetricQueryState<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n): void {\n const normalized = normalizeQueryState(q);\n if ((q.aggregations?.length ?? 0) !== (normalized.aggregations?.length ?? 0))\n throw Error(\"Malformed metric definitions cannot be dropped.\");\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n const normalizedOrder = normalizeQueryState({ ...q, orderBy }).orderBy;\n if (\n queryStateKey(q.where) !== queryStateKey(normalized.where) ||\n queryStateKey(orderBy) !== queryStateKey(normalizedOrder) ||\n q.limit !== normalized.limit ||\n q.offset !== normalized.offset\n )\n throw Error(\"Malformed metric query state cannot be executed exactly.\");\n}\n/** Safe pre-worker page selection. A supplied committed page needs no query execution.\n * Query regex is never executed here; all-matching regex filtering is unsupported. */\nexport function selectMetricShownRows<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): Row[] {\n if (options.signal?.aborted) throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if (options.shownRows) return options.shownRows;\n const orderBy = q.orderBy.length ? q.orderBy : (schema.defaultSort ?? []);\n assertMetricPopulation(q, schema, orderBy);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n if ((options.maxOperations ?? 10000000) <= 0)\n throw Error(\"Metric operation budget exceeded.\");\n return applyQuery(\n rows,\n // Local tables use a stable sort: ties retain input order. An extra ID\n // sort here would choose a different page than the one the table shows.\n { ...q, orderBy },\n schema,\n options,\n ).rows;\n}\nfunction assertMetricPopulation<Row>(\n q: QueryState,\n schema: FieldSchema<Row>,\n orderBy: QueryState[\"orderBy\"],\n): void {\n const fields = indexFields(schema);\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n ) ||\n orderBy.some((s) => s.extract !== undefined)\n )\n throw Error(\n \"Query regex requires isolated execution; unavailable for metric population selection.\",\n );\n if (\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) =>\n isComputedField(p.field) && !computedInputAllowed(schema, p.field, \"filter\") ||\n !fields.has(resolveFieldName(schema, p.field) ?? p.field),\n ),\n )\n )\n throw Error(\"Metric filter references an unavailable field.\");\n if (\n orderBy.some(\n (s) =>\n isComputedField(s.field) && !computedInputAllowed(schema, s.field, \"sort\") ||\n !fields.has(resolveFieldName(schema, s.field) ?? s.field),\n )\n )\n throw Error(\"Shown-row ordering requires an authoritative committed page.\");\n}\nexport interface MetricEvaluationOptions<Row = unknown>\n extends QueryEvaluationOptions,\n MetricReductionOptions {\n resolveComputed?: (name: string) => FormulaPlan | undefined;\n /** Called only for regex row ASTs, using cached results from a terminable worker. */\n evaluateInput?: (\n node: FormulaNode,\n row: Row,\n plan: FormulaPlan,\n ) => FormulaResult;\n /** Exact committed page supplied by the host after filters/order/window. */\n /** Escaped tuple length bound, in UTF-16 code units (default 65,536). */\n maxGroupKeyLength?: number;\n /** Retained group keys, map/bucket overhead and row references, plus key scratch space (default 16 MB). */\n maxGroupBytes?: number;\n shownRows?: Row[];\n maxRows?: number;\n maxGroups?: number;\n /** Per-metric operation budget (default 10,000,000, allowing simple paired\n * aggregates across the default one-million-row population limit). */\n maxOperations?: number;\n /** @deprecated Regex requires cached evaluateInput; this flag grants no execution permission. */ allowRegex?: boolean;\n signal?: AbortSignal;\n}\nconst scalar = (v: unknown): MetricValue => {\n if (v instanceof Date) return v.toISOString();\n if (v == null) return null;\n if (\n typeof v === \"string\" ||\n typeof v === \"boolean\" ||\n (typeof v === \"number\" && Number.isFinite(v))\n )\n return v;\n throw Error(\"Metric keys and values must be finite scalars.\");\n};\n/** JSON string length without allocating escaped text; scan only bounded input. */\nfunction groupStringLength(value: string, limit: number): number {\n let length = value.length + 2;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n for (let i = 0; i < value.length; i++) {\n const code = value.charCodeAt(i);\n if (\n code === 34 ||\n code === 92 ||\n code === 8 ||\n code === 9 ||\n code === 10 ||\n code === 12 ||\n code === 13\n )\n length++;\n else if (code < 32) length += 5;\n else if (\n code >= 0xd800 &&\n code <= 0xdbff &&\n i + 1 < value.length &&\n value.charCodeAt(i + 1) >= 0xdc00 &&\n value.charCodeAt(i + 1) <= 0xdfff\n )\n i++;\n else if (code >= 0xd800 && code <= 0xdfff) length += 5;\n if (length > limit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n return length;\n}\n/** Typed lexicographic ordering with null placement independent of direction. */\nexport function compareMetricValues(a: MetricValue, b: MetricValue): number {\n if (a === b) return 0;\n if (a === null) return 1;\n if (b === null) return -1;\n if (typeof a !== typeof b) return typeof a < typeof b ? -1 : 1;\n if (typeof a === \"string\" && typeof b === \"string\") {\n const ac = Array.from(a),\n bc = Array.from(b);\n for (let i = 0; i < Math.min(ac.length, bc.length); i++) {\n const diff = ac[i]!.codePointAt(0)! - bc[i]!.codePointAt(0)!;\n if (diff) return Math.sign(diff);\n }\n return Math.sign(ac.length - bc.length);\n }\n return a < b ? -1 : 1;\n}\nexport function evaluateMetrics<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) {\n try {\n if (options.signal?.aborted) throw new Error(\"Metric evaluation cancelled.\");\n if (rows.length > (options.maxRows ?? 1_000_000)) throw new Error(\"Metric row budget exceeded.\");\n const now = evaluationTime(options);\n const prepared = prepareGrouping(rows, schema, q.grouping, { now });\n return evaluateMetrics(prepared.rows, withoutGrouping(q), prepared.schema, {\n ...options, now,\n } as unknown as MetricEvaluationOptions<GroupedRow>);\n } catch (error) {\n return { metrics: (q.aggregations ?? []).map(metric => ({ id: metric.id, buckets: [], error: error instanceof Error ? error.message : String(error) })) };\n }\n }\n const now = evaluationTime(options),\n fields = indexFields(schema);\n let matching: Row[] | undefined;\n let shown: Row[] | undefined;\n return {\n metrics: (q.aggregations ?? []).map((c) => {\n let budget = options.maxOperations ?? 10000000;\n const tick = () => {\n if (--budget < 0) throw Error(\"Metric operation budget exceeded.\");\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n };\n try {\n if (options.signal?.aborted)\n throw Error(\"Metric evaluation cancelled.\");\n assertMetricQueryState(q, schema);\n if ((q.aggregations?.length ?? 0) > 20)\n throw Error(\"At most 20 metrics are allowed.\");\n const diagnostics = validateMetric(c, schema, options.resolveComputed);\n if (diagnostics.length)\n throw Error(diagnostics.map((d) => d.message).join(\" \"));\n const ps = metricPlans(c, schema, options.resolveComputed);\n if (ps.some(hasRegex) && !options.evaluateInput)\n throw Error(\n \"Regex metrics require an isolated worker with a watchdog.\",\n );\n let inputRows: Row[];\n if (c.scope === \"shownRows\")\n inputRows = shown ??= selectMetricShownRows(rows, q, schema, options);\n else {\n if (!matching) {\n assertMetricPopulation(q, schema, []);\n if (rows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n matching = applyQuery(\n rows,\n { ...q, orderBy: [], offset: 0, limit: Number.MAX_SAFE_INTEGER },\n schema,\n { now },\n ).rows;\n }\n inputRows = matching;\n }\n if (inputRows.length > (options.maxRows ?? 1000000))\n throw Error(\"Metric row budget exceeded.\");\n const groups = new Map<string, { keys: MetricValue[]; rows: Row[] }>();\n const keyLimit = options.maxGroupKeyLength ?? 65536,\n byteLimit = options.maxGroupBytes ?? 16000000;\n if (\n ![keyLimit, byteLimit].every((v) => Number.isSafeInteger(v) && v >= 0)\n )\n throw Error(\"Invalid grouping budget.\");\n let groupBytes = 0;\n const reserve = (bytes: number) => {\n if (bytes > byteLimit - groupBytes)\n throw Error(\"Metric grouping retained-memory budget exceeded.\");\n };\n if (!c.groupBy.length) {\n if (keyLimit < 2)\n throw Error(\"Metric grouping key length budget exceeded.\");\n reserve(256);\n groupBytes = 256;\n groups.set(\"[]\", { keys: [], rows: [] });\n }\n // Retain only the most recent calendar interval. Dense timestamp rows\n // share its boundaries and ISO key without repeating timezone work.\n // The half-open interval also separates repeated/partial DST hours;\n // out-of-order rows outside it always recompute the correct bucket.\n let dateStart = Infinity,\n dateEnd = -Infinity,\n dateKey = \"\";\n let dateInput: MetricValue | undefined,\n dateTime = NaN;\n for (const row of inputRows) {\n tick();\n if (!c.groupBy.length) {\n reserve(16);\n groupBytes += 16;\n groups.get(\"[]\")!.rows.push(row);\n continue;\n }\n const keys = c.groupBy.map((k) =>\n scalar(\n readFieldValue(\n fields.get(resolveFieldName(schema, k) ?? k)!,\n row,\n ),\n ),\n );\n if (c.dateGrouping && keys[0] !== null) {\n const config = c.dateGrouping;\n // Repeated date-only values would otherwise resolve local midnight\n // through Temporal for every row as well.\n if (keys[0] !== dateInput) {\n dateTime = metricDateTime(keys[0]!, config.timeZone);\n dateInput = keys[0];\n }\n if (dateTime < dateStart || dateTime >= dateEnd) {\n dateStart = metricDateFloor(\n dateTime,\n config.interval,\n config.timeZone,\n );\n dateEnd = metricDateNext(\n dateStart,\n config.interval,\n config.timeZone,\n );\n dateKey = new Date(dateStart).toISOString();\n }\n keys[0] = dateKey;\n }\n // Measure escaping without allocating a serialized key. Check BEFORE\n // stringify: shared source strings must not amplify into unbounded map keys. Charge source payload again\n // per group, even if shared, plus tuple slots, buckets and map overhead.\n let keyLength = 1,\n payloadBytes = 0;\n for (const value of keys) {\n keyLength +=\n 1 +\n (typeof value === \"string\"\n ? groupStringLength(value, keyLimit - keyLength - 1)\n : value === null\n ? 4\n : typeof value === \"boolean\"\n ? value\n ? 4\n : 5\n : String(value).length);\n payloadBytes += typeof value === \"string\" ? 2 * value.length : 8;\n if (keyLength > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n }\n const retainedBytes =\n 256 + 16 * keys.length + payloadBytes + 2 * keyLength;\n // Reserve a candidate group plus serialization scratch, even for a\n // duplicate; this deliberately conservative check needs no large key.\n reserve(retainedBytes + 2 * keyLength + 16);\n const key = JSON.stringify(keys);\n let g = groups.get(key);\n if (!g) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n g = { keys, rows: [] };\n groups.set(key, g);\n groupBytes += retainedBytes;\n }\n groupBytes += 16;\n g.rows.push(row);\n }\n if (c.dateGrouping?.includeEmpty) {\n const config = c.dateGrouping;\n const observed: number[] = [];\n const series = new Map<string, MetricValue[]>();\n for (const group of groups.values())\n if (group.keys[0] !== null) {\n tick();\n reserve(8);\n groupBytes += 8;\n observed.push(metricDateTime(group.keys[0]!));\n const tuple = group.keys.slice(1);\n const key = JSON.stringify(tuple);\n if (!series.has(key)) {\n const bytes = 128 + 16 * tuple.length + 2 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n series.set(key, tuple);\n }\n }\n if (c.groupBy.length === 1 && !series.size) {\n reserve(132);\n groupBytes += 132;\n series.set(\"[]\", []);\n }\n const range = metricDateRange(\n config,\n q,\n observed,\n now,\n (name) => resolveFieldName(schema, name) ?? name,\n );\n if (range)\n for (let time = range[0]; time <= range[1]; ) {\n tick();\n for (const tuple of series.values()) {\n tick();\n const keys: MetricValue[] = [\n new Date(time).toISOString(),\n ...tuple,\n ];\n const key = JSON.stringify(keys);\n if (key.length > keyLimit)\n throw Error(\"Metric grouping key length budget exceeded.\");\n if (!groups.has(key)) {\n if (groups.size >= (options.maxGroups ?? 10000))\n throw Error(\"Metric group budget exceeded.\");\n const bytes = 256 + 16 * keys.length + 4 * key.length;\n reserve(bytes);\n groupBytes += bytes;\n groups.set(key, { keys, rows: [] });\n }\n }\n const next = metricDateNext(\n time,\n config.interval,\n config.timeZone,\n );\n if (!Number.isFinite(next) || next <= time)\n throw Error(\"Date grouping exceeds calendar limits.\");\n time = next;\n }\n }\n const inputs = (\n row: Row,\n p: FormulaPlan,\n ): Record<string, FormulaValue> =>\n Object.fromEntries(\n p.dependencies.map((name) => [\n name,\n (() => {\n const value = readFieldValue(fields.get(name)!, row);\n return value instanceof Date\n ? value.toISOString()\n : (value ?? null);\n })(),\n ]),\n ) as Record<string, FormulaValue>;\n const nodeCosts = new Map<FormulaNode, number>();\n const cost = (n: FormulaNode): number => {\n const known = nodeCosts.get(n);\n if (known !== undefined) return known;\n const value =\n 1 +\n (n.kind === \"call\" ? n.args.reduce((s, a) => s + cost(a), 0) : 0);\n nodeCosts.set(n, value);\n return value;\n };\n const rowEval = (node: FormulaNode, row: Row, p: FormulaPlan) => {\n budget -= cost(node);\n tick();\n // A direct aggregate input needs only its own binding, even when the\n // composed metric reaches many other fields. Keep runtime validation.\n if (node.kind === \"field\") {\n const value = readFieldValue(fields.get(node.name)!, row);\n return formulaRuntime(node, {\n [node.name]:\n value instanceof Date\n ? value.toISOString()\n : ((value ?? null) as FormulaValue),\n });\n }\n return options.evaluateInput && hasRegex({ ...p, ast: node })\n ? options.evaluateInput(node, row, p)\n : formulaRuntime(node, inputs(row, p));\n };\n const reduce = (\n p: FormulaPlan,\n rs: Row[],\n inputErrors: Set<number>,\n ): FormulaResult => {\n const cache = new Map<FormulaNode, FormulaResult>();\n return checkedMetricResult(\n formulaRuntime(p.ast, {}, (node) => {\n if (!aggregates.has(node.name)) return undefined;\n if (cache.has(node)) return cache.get(node)!;\n let result: FormulaResult;\n try {\n function* results(): Generator<FormulaResult> {\n for (let i = 0; i < rs.length; i++) {\n tick();\n const v = node.args[0]\n ? rowEval(node.args[0], rs[i]!, p)\n : { value: 1 };\n if (v.error) inputErrors.add(i);\n yield v;\n }\n }\n result = reduceResults(node, results(), options);\n } catch (e) {\n result = {\n value: null,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n cache.set(node, result);\n return result;\n }),\n );\n };\n const populations = new Map<AggregationBucket, number[]>();\n let buckets: AggregationBucket[] = [...groups.values()].map((g) => {\n const bucket: AggregationBucket = {\n keys: g.keys,\n count: g.rows.length,\n value: null,\n };\n if (distributionActive(c)) {\n const values: number[] = [];\n bucket.nullCount = 0;\n bucket.inputErrorCount = 0;\n for (const row of g.rows) {\n const r = checkedMetricResult(rowEval(ps[0]!.ast, row, ps[0]!));\n if (r.error) {\n bucket.inputErrorCount++;\n bucket.error = r.error;\n } else if (r.value === null) bucket.nullCount++;\n else values.push(Number(r.value));\n }\n populations.set(bucket, values);\n } else {\n if (c.dateGrouping && !g.rows.length) {\n const empty = (p: FormulaPlan) =>\n p.ast.kind === \"call\" &&\n [\"COUNT\", \"COUNT_DISTINCT\", \"SUM\"].includes(p.ast.name)\n ? 0\n : null;\n bucket.value = empty(ps[0]!);\n if (ps[1]) bucket.y = empty(ps[1]);\n return bucket;\n }\n const inputErrors = new Set<number>();\n const x = reduce(ps[0]!, g.rows, inputErrors);\n bucket.value = scalar(x.value);\n if (x.error) bucket.error = x.error;\n if (ps[1]) {\n const y = reduce(ps[1], g.rows, inputErrors);\n bucket.y = scalar(y.value);\n if (y.error) bucket.yError = y.error;\n }\n if (inputErrors.size) bucket.inputErrorCount = inputErrors.size;\n }\n return bucket;\n });\n if (distributionActive(c)) {\n const d = c.distribution!;\n if (d.kind === \"histogram\" && buckets.some((b) => b.error))\n throw Error(\n \"Histogram input errors prevent an exact shared extent.\",\n );\n const all: number[] = [];\n for (const values of populations.values())\n for (const v of values) all.push(v);\n const edges =\n d.kind === \"histogram\" ? histogramEdges(all, d.bins ?? 10) : [];\n for (const b of buckets) {\n const vs = populations.get(b)!;\n if (b.error) continue;\n if (d.kind === \"box\") {\n const summary = boxSummary(vs, d.whiskers);\n b.distribution = { kind: \"box\", summary };\n b.value = summary?.median ?? null;\n } else {\n b.distribution = {\n kind: \"histogram\",\n edges: [...edges],\n counts: histogramCounts(vs, edges),\n n: vs.length,\n };\n b.value = vs.length;\n }\n }\n }\n const ordering: MetricSort[] = c.sort?.length\n ? c.sort\n : c.dateGrouping\n ? [{ key: \"group0\", dir: \"asc\", nulls: \"last\" }]\n : [{ key: \"value\", dir: \"desc\", nulls: \"last\" }];\n const target = (b: AggregationBucket, s: MetricSort): MetricValue =>\n s.key === \"samples\"\n ? b.count - (b.nullCount ?? 0) - (b.inputErrorCount ?? 0)\n : s.key.startsWith(\"group\")\n ? (b.keys[Number(s.key.slice(5))] ?? null)\n : s.key === \"count\"\n ? b.count\n : s.key === \"y\"\n ? (b.y ?? null)\n : b.value;\n buckets.sort((a, b) => {\n if (!!(a.error || a.yError) !== !!(b.error || b.yError))\n return a.error || a.yError ? 1 : -1;\n for (const s of ordering) {\n const av = target(a, s),\n bv = target(b, s);\n const cmp =\n av === null || bv === null\n ? av === bv\n ? 0\n : (av === null ? 1 : -1) * (s.nulls === \"first\" ? -1 : 1)\n : compareMetricValues(av, bv) * (s.dir === \"asc\" ? 1 : -1);\n if (cmp) return cmp;\n }\n for (let i = 0; i < a.keys.length; i++) {\n const cmp = compareMetricValues(a.keys[i]!, b.keys[i]!);\n if (cmp) return cmp;\n }\n return 0;\n });\n tick();\n const groupCount = buckets.length;\n let other: AggregationBucket | undefined;\n if (c.groupLimit && buckets.length > c.groupLimit) {\n const omitted = buckets.slice(c.groupLimit),\n ast = ps[0]!.ast;\n if (\n !distributionActive(c) &&\n ast.kind === \"call\" &&\n [\"SUM\", \"COUNT\"].includes(ast.name) &&\n omitted.every(\n (b) =>\n !b.error &&\n (typeof b.value === \"number\" ||\n (ast.name === \"SUM\" && b.value === null)),\n )\n ) {\n const value = omitted.reduce((s, b) => s + Number(b.value), 0);\n if (\n Number.isFinite(value) &&\n (!Number.isInteger(value) || Number.isSafeInteger(value))\n )\n other = {\n keys: [],\n value,\n count: omitted.reduce((s, b) => s + b.count, 0),\n };\n }\n buckets = buckets.slice(0, c.groupLimit);\n }\n return {\n id: c.id,\n buckets,\n scope: c.scope ?? \"allMatching\",\n processedRows: inputRows.length,\n groupCount,\n coverage: \"exact\" as const,\n ...(other ? { other } : {}),\n };\n } catch (e) {\n return {\n id: c.id,\n buckets: [],\n error: e instanceof Error ? e.message : String(e),\n };\n }\n }),\n };\n}\n","import { aggOpsForField, isMeasurable } from \"./agg\";\nimport type { MetricKey } from \"./metricTypes\";\nimport { evaluateMetrics, type MetricEvaluationOptions } from \"./metrics\";\n// apply.ts — client-side filter + multi-sort + paginate.\n//\n// applyQuery is the client mirror of the backend compiler. Three jobs:\n// 1. The executor for purely client-side datasets (no backend at all).\n// 2. The executor for derived / non-pushdown columns the backend can't filter.\n// 3. Idempotent defense-in-depth over server-filtered fields (re-applying a\n// server-handled clause must not change the result).\n//\n// It must agree with backends/go's Compile on operator semantics:\n// - `contains`/`starts_with`/`ends_with` are case-insensitive\n// - textarray `is_null` = empty-or-missing; `is_not_null` = any element;\n// `includes` = case-insensitive membership\n// - NULLs sort per OrderByClause.nulls (default \"last\")\n// - multi-sort is a stable lexicographic fold over orderBy in priority order\n\nimport { evaluationTime, type QueryEvaluationOptions } from \"./relativeTime\";\nimport { isComputedField } from \"./computed\";\nimport type {\n AggOp,\n AggregationClause,\n QueryState,\n WhereClause,\n WhereTerm,\n} from \"./query\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport type { AggregationBucket, AggregationResult } from \"./encode\";\nimport { indexFields, readFieldValue, resolveFieldName } from \"./schema\";\nimport { isOrGroup, predicatesOf, normalizeQueryState } from \"./query\";\nimport { coerceValue } from \"./ops\";\nimport { prepareGrouping, withoutGrouping } from \"./grouping\";\n\nexport interface ApplyResult<Row> {\n /** The page slice (after filter + sort + offset/limit). */\n rows: Row[];\n /** Total matching rows *before* pagination — powers \"showing N of M\". */\n total: number;\n}\n\n/** Filter + multi-sort + paginate `rows` per `q`, resolving field types/paths\n * from `schema`. Never mutates `rows`. Relative predicates use options.now or\n * one captured Date.now(). Clauses/sorts on unknown fields are\n * ignored (the backend already enforced its own allowlist). */\nexport function applyQuery<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): ApplyResult<Row> {\n const now = evaluationTime(options);\n if (q.grouping) {\n const grouped = prepareGrouping(rows, schema, q.grouping, { now });\n // Grouped results are projections described by grouped.schema; they do not\n // retain source-row accessors or identities.\n return applyQuery(grouped.rows, withoutGrouping(q), grouped.schema, { now }) as ApplyResult<Row>;\n }\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n // Terms touching a computed column are dropped here (the formula engine\n // evaluates those separately; `byName` has no opinion on them anyway). An OR\n // group is all-or-nothing, so a single computed member drops the whole term.\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field) && !computedInputAllowed(schema, c.field, \"filter\")))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const orderBy = q.orderBy\n .filter((term) => !isComputedField(term.field) || computedInputAllowed(schema, term.field, \"sort\"))\n .map((term) => ({ ...term, field: resolveField(term.field) }));\n\n let out = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const total = out.length;\n\n if (orderBy.length) {\n const terms = orderBy\n .map((t) => ({\n field: byName.get(t.field),\n dir: t.dir,\n nullsLast: (t.nulls ?? \"last\") === \"last\",\n extract: compileRegex(t.extract?.regex),\n }))\n .filter(\n (\n t,\n ): t is {\n field: FieldDef<Row>;\n dir: \"asc\" | \"desc\";\n nullsLast: boolean;\n extract: RegExp | null | undefined;\n } => t.field != null,\n );\n out = [...out].sort((a, b) => {\n for (const t of terms) {\n const av = extractSortValue(readFieldValue(t.field, a), t.extract);\n const bv = extractSortValue(readFieldValue(t.field, b), t.extract);\n const aNull = av == null;\n const bNull = bv == null;\n if (aNull || bNull) {\n if (aNull && bNull) continue;\n return (aNull ? 1 : -1) * (t.nullsLast ? 1 : -1);\n }\n const cmp = compare(av, bv);\n if (cmp !== 0) return t.dir === \"asc\" ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const start = q.offset > 0 ? q.offset : 0;\n const end = q.limit > 0 ? start + q.limit : out.length;\n return { rows: out.slice(start, end), total };\n}\n\n/** Explicit host bindings or approved evaluated accessors can participate in\n * local source stages. Ordinary unapproved computed controls stay disabled. */\nexport function computedInputAllowed(schema: FieldSchema, name: string, operation: \"filter\" | \"sort\"): boolean {\n const field = schema.fields.find(field => field.name === name);\n return !!field && (field.source.kind === \"backend\" && field[operation]?.enabled !== false || field[operation]?.enabled === true);\n}\n\n/** Does one row satisfy one clause? Exposed for the CellMenu preview + tests. */\nexport function matchesClause<Row>(\n row: Row,\n clause: WhereClause,\n schema: FieldSchema<Row>,\n options: QueryEvaluationOptions = {},\n): boolean {\n const field = resolveFieldName(schema, clause.field) ?? clause.field;\n const byName = indexFields(schema);\n const prepared = prepareWhereClause(\n { ...clause, field },\n evaluationTime(options),\n );\n prepareDatetimePredicates([{ kind: \"lit\", predicate: prepared }], byName);\n return matchesWith(byName, row, prepared);\n}\n\n/** Client-side mirror of the backend GROUP BY (the executor for `clientRows`\n * mode / the demo). Scope matches the server contract: the WHERE-filtered set\n * only — ORDER BY / LIMIT / OFFSET are intentionally ignored, so a metric\n * reflects every matching row, not the visible page. Must agree with\n * backends/go's aggregate compile on op semantics. */\nexport function applyAggregations<Row>(\n rows: Row[],\n q: QueryState,\n schema: FieldSchema<Row>,\n options: MetricEvaluationOptions<Row> = {},\n): AggregationResult {\n if (q.grouping) return evaluateMetrics(rows, q, schema, options);\n if (\n options.signal?.aborted ||\n q.where.some((t) =>\n predicatesOf(t).some(\n (p) => p.op === \"matches_regex\" || p.op === \"not_matches_regex\",\n ),\n )\n )\n return evaluateMetrics(rows, q, schema, options);\n const advanced = (q.aggregations ?? []).filter(\n (a) =>\n a.dateGrouping ||\n a.diagnostics?.length ||\n a.expression !== undefined ||\n a.expressionY !== undefined ||\n a.scope !== undefined ||\n a.distribution ||\n a.sort ||\n a.groupLimit !== undefined,\n );\n if (advanced.length) {\n // Partitioning must not hide invalid IDs/shapes or the query-wide card cap.\n if (\n (q.aggregations?.length ?? 0) > 20 ||\n normalizeQueryState(q).aggregations?.length !== q.aggregations?.length\n )\n return evaluateMetrics(rows, q, schema, options);\n const legacy = (q.aggregations ?? []).filter((a) => !advanced.includes(a));\n const results = [\n ...evaluateMetrics(\n rows,\n { ...q, aggregations: advanced },\n schema,\n options,\n ).metrics,\n ...(legacy.length\n ? applyAggregations(\n rows,\n { ...q, aggregations: legacy },\n schema,\n options,\n ).metrics\n : []),\n ];\n const byId = new Map(results.map((result) => [result.id, result]));\n return {\n metrics: (q.aggregations ?? []).flatMap((a) => byId.get(a.id) ?? []),\n };\n }\n const now = evaluationTime(options);\n const byName = indexFields(schema);\n const resolveField = (name: string) => resolveFieldName(schema, name) ?? name;\n const whereTerms = q.where\n .filter((term) => !predicatesOf(term).some((c) => isComputedField(c.field)))\n .map((term) => prepareWhereTerm(term, resolveField, now));\n prepareDatetimePredicates(whereTerms, byName);\n const filtered = rows.filter((row) =>\n whereTerms.every((term) => matchesTerm(byName, row, term)),\n );\n const metrics = (q.aggregations ?? [])\n .filter(\n (a) =>\n !isComputedField(a.field ?? \"\") && !a.groupBy.some(isComputedField),\n )\n .map((agg) => {\n const field = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n if (\n field &&\n (!isMeasurable(field) || !aggOpsForField(field).includes(agg.op))\n )\n return {\n id: agg.id,\n buckets: [],\n error: `Field ${field.name} does not allow ${agg.op}.`,\n };\n return {\n id: agg.id,\n buckets: computeBuckets(filtered, agg, byName, resolveField),\n };\n });\n return { metrics };\n}\n\nfunction computeBuckets<Row>(\n rows: Row[],\n agg: AggregationClause,\n byName: Map<string, FieldDef<Row>>,\n resolveField: (field: string) => string,\n): AggregationBucket[] {\n // One slot per groupBy entry, preserving position. An unresolved field stays\n // in the array as `undefined` so every bucket's `keys` has exactly one element\n // per requested group field — the panel renders keys positionally against\n // `clause.groupBy`, so dropping an entry here would shift every later column.\n const groupFields = agg.groupBy.map((n) => byName.get(resolveField(n)));\n const measure = agg.field ? byName.get(resolveField(agg.field)) : undefined;\n\n const groups = new Map<string, { keys: MetricKey[]; rows: Row[] }>();\n if (!agg.groupBy.length) groups.set(\"[]\", { keys: [], rows: [] });\n for (const row of rows) {\n const keys = groupFields.map((f) => {\n if (!f) return null; // unresolved group field → NULL bucket, never a missing column\n const v = readFieldValue(f, row);\n return v == null || v === \"\"\n ? null\n : typeof v === \"number\" ||\n typeof v === \"boolean\" ||\n typeof v === \"string\"\n ? v\n : String(v);\n });\n const k = JSON.stringify(keys);\n let g = groups.get(k);\n if (!g) {\n g = { keys, rows: [] };\n groups.set(k, g);\n }\n g.rows.push(row);\n }\n\n const buckets = [...groups.values()].map((g) => ({\n keys: g.keys,\n count: g.rows.length,\n value: aggValue(agg.op, measure, g.rows),\n }));\n return sortBuckets(buckets);\n}\n\nfunction aggValue<Row>(\n op: AggOp,\n measure: FieldDef<Row> | undefined,\n rows: Row[],\n): number | string | null {\n if (op === \"count\") {\n if (!measure) return rows.length; // COUNT(*)\n let n = 0;\n for (const r of rows) if (readFieldValue(measure, r) != null) n++; // COUNT(expr) = non-null\n return n;\n }\n if (!measure) return null;\n const values = rows\n .map((r) => readFieldValue(measure, r))\n .filter((v) => v != null);\n\n switch (op) {\n case \"count_distinct\":\n return new Set(values.map((v) => String(v))).size;\n case \"sum\":\n case \"avg\": {\n let sum = 0;\n let n = 0;\n for (const v of values) {\n const num = typeof v === \"number\" ? v : Number(v);\n if (Number.isFinite(num)) {\n sum += num;\n n++;\n }\n }\n if (op === \"avg\") return n ? sum / n : null;\n return n ? sum : null;\n }\n case \"min\":\n case \"max\": {\n let best: unknown;\n for (const v of values) {\n if (best === undefined) {\n best = v;\n continue;\n }\n const cmp = compare(v, best);\n if (op === \"min\" ? cmp < 0 : cmp > 0) best = v;\n }\n return (best as number | string | undefined) ?? null;\n }\n default:\n return null;\n }\n}\n\n/** Stable display order: descending by the metric (or group size when the metric\n * isn't numeric), then by group key. The 2D pivot ignores this; the 1D bar list\n * and the flat N-column table read top-to-bottom from it. */\nfunction sortBuckets(buckets: AggregationBucket[]): AggregationBucket[] {\n return [...buckets].sort((a, b) => {\n const av = typeof a.value === \"number\" ? a.value : a.count;\n const bv = typeof b.value === \"number\" ? b.value : b.count;\n if (av !== bv) return bv - av;\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n}\n\ninterface PreparedWhereClause {\n clause: WhereClause;\n now: number;\n datetime?: number;\n regex: RegExp | null | undefined;\n}\n\ntype PreparedWhereTerm =\n | { kind: \"lit\"; predicate: PreparedWhereClause }\n | { kind: \"or\"; predicates: PreparedWhereClause[] };\n\nfunction prepareWhereClause(\n clause: WhereClause,\n now: number,\n): PreparedWhereClause {\n const usesRegex =\n clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\";\n return {\n clause,\n now,\n regex: usesRegex ? compileRegex(clause.value) : undefined,\n };\n}\n\nfunction prepareWhereTerm(\n term: WhereTerm,\n resolveField: (name: string) => string,\n now: number,\n): PreparedWhereTerm {\n if (isOrGroup(term)) {\n return {\n kind: \"or\",\n predicates: term.any.map((c) =>\n prepareWhereClause({ ...c, field: resolveField(c.field) }, now),\n ),\n };\n }\n return {\n kind: \"lit\",\n predicate: prepareWhereClause(\n { ...term, field: resolveField(term.field) },\n now,\n ),\n };\n}\n\nfunction prepareDatetimePredicates<Row>(\n terms: PreparedWhereTerm[],\n fields: Map<string, FieldDef<Row>>,\n): void {\n for (const term of terms)\n for (const p of term.kind === \"lit\" ? [term.predicate] : term.predicates) {\n const field = fields.get(p.clause.field);\n if (\n field?.type !== \"datetime\" ||\n p.clause.value === \"\" ||\n p.clause.op === \"is_null\" ||\n p.clause.op === \"is_not_null\"\n )\n continue;\n p.datetime = coerceValue(\"datetime\", p.clause.value, p.now) as number;\n }\n}\n\n/** A row satisfies the WHERE when every term matches (AND); a term matches when\n * its sole predicate matches, or — for an OR group — when any member does. */\nfunction matchesTerm<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n term: PreparedWhereTerm,\n): boolean {\n if (term.kind === \"lit\") return matchesWith(byName, row, term.predicate);\n // Normalization never yields an empty group (0 dropped, 1 flattened), so\n // `some` over a non-empty list is the OR.\n return term.predicates.some((p) => matchesWith(byName, row, p));\n}\n\nfunction matchesWith<Row>(\n byName: Map<string, FieldDef<Row>>,\n row: Row,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause } = prepared;\n const field = byName.get(clause.field);\n if (!field) return true; // unknown field → no client opinion\n const v = readFieldValue(field, row);\n\n // Empty value on a non-equality, value-taking op is a \"no filter\" signal —\n // true for BOTH the predicate and its negation (matches the UI + the Go\n // compiler, which skip such clauses). Nullary ops legitimately use value \"\".\n if (\n clause.value === \"\" &&\n clause.op !== \"=\" &&\n clause.op !== \"!=\" &&\n clause.op !== \"is_null\" &&\n clause.op !== \"is_not_null\"\n ) {\n return true;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (\n !/^(0|[1-9]\\d*)$/.test(clause.value) ||\n !Number.isSafeInteger(Number(clause.value))\n )\n return false;\n }\n\n let base: boolean;\n if (prepared.datetime !== undefined) {\n const timestamp =\n v instanceof Date\n ? v.getTime()\n : typeof v === \"number\"\n ? v\n : typeof v === \"string\"\n ? Date.parse(v)\n : NaN;\n if (v === \"\" || !Number.isFinite(timestamp)) return false;\n base = matchesDatetime(timestamp, prepared.datetime, clause.op);\n } else {\n base = matchesBase(field, v, prepared);\n }\n if (!clause.negated) return base;\n // Null-exclusive NOT: a NULL/empty value satisfies neither the predicate nor\n // its negation (mirrors `not_matches_regex` and the server's trailing\n // `AND <expr> IS NOT NULL`).\n const isNull = Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n return !isNull && !base;\n}\n\nfunction matchesDatetime(\n timestamp: number,\n rhs: number,\n op: WhereClause[\"op\"],\n): boolean {\n switch (op) {\n case \"=\":\n return timestamp === rhs;\n case \"!=\":\n return timestamp !== rhs;\n case \">\":\n return timestamp > rhs;\n case \">=\":\n return timestamp >= rhs;\n case \"<\":\n return timestamp < rhs;\n case \"<=\":\n return timestamp <= rhs;\n default:\n return false;\n }\n}\n\n/** The bare predicate result, ignoring `negated` and the empty-value skip\n * (both handled by `matchesWith`). */\nfunction matchesBase<Row>(\n field: FieldDef<Row>,\n v: unknown,\n prepared: PreparedWhereClause,\n): boolean {\n const { clause, regex } = prepared;\n\n // Nullity, with array-aware semantics.\n if (clause.op === \"is_null\")\n return Array.isArray(v) ? v.length === 0 : v == null || v === \"\";\n if (clause.op === \"is_not_null\")\n return Array.isArray(v) ? v.length > 0 : v != null && v !== \"\";\n\n const arrayText = (value: unknown) =>\n field.filter?.arrayCaseSensitive\n ? String(value)\n : String(value).toLowerCase();\n\n // `includes` is array membership (ARRAY_HAS): a null/missing array contains\n // nothing. Handle before the array/scalar split so null can't fall through.\n if (clause.op === \"includes\") {\n const arr = Array.isArray(v) ? v : [];\n const needle = arrayText(clause.value);\n return arr.some((x) => arrayText(x) === needle);\n }\n\n if (clause.op === \"matches_regex\" || clause.op === \"not_matches_regex\") {\n if (v == null || Array.isArray(v)) return false;\n if (!regex) return false;\n const matches = regex.test(String(v));\n return clause.op === \"matches_regex\" ? matches : !matches;\n }\n\n if (\n clause.op === \"length_gt\" ||\n clause.op === \"length_lt\" ||\n clause.op === \"length_eq\"\n ) {\n if (typeof v !== \"string\" || !/^(0|[1-9]\\d*)$/.test(clause.value))\n return false;\n const limit = Number(clause.value);\n if (!Number.isSafeInteger(limit)) return false;\n const length = Array.from(v).length;\n return clause.op === \"length_gt\"\n ? length > limit\n : clause.op === \"length_lt\"\n ? length < limit\n : length === limit;\n }\n\n if (Array.isArray(v)) {\n const needle = arrayText(clause.value);\n const hay = v.map(arrayText);\n switch (clause.op) {\n case \"contains\":\n return hay.some((s) => s.includes(needle));\n case \"=\":\n return hay.includes(needle);\n case \"!=\":\n return !hay.includes(needle);\n default:\n return true;\n }\n }\n\n switch (clause.op) {\n case \"=\":\n return String(v ?? \"\") === String(coerceSafe(field, clause.value));\n case \"!=\":\n return String(v ?? \"\") !== String(coerceSafe(field, clause.value));\n case \">\":\n return compare(v, coerceSafe(field, clause.value)) > 0;\n case \">=\":\n return compare(v, coerceSafe(field, clause.value)) >= 0;\n case \"<\":\n return compare(v, coerceSafe(field, clause.value)) < 0;\n case \"<=\":\n return compare(v, coerceSafe(field, clause.value)) <= 0;\n case \"contains\":\n return String(v ?? \"\")\n .toLowerCase()\n .includes(clause.value.toLowerCase());\n case \"starts_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .startsWith(clause.value.toLowerCase());\n case \"ends_with\":\n return String(v ?? \"\")\n .toLowerCase()\n .endsWith(clause.value.toLowerCase());\n default:\n return true;\n }\n}\n\n/** `null` means an invalid pattern; `undefined` means no regex was requested. */\nfunction compileRegex(pattern: string | undefined): RegExp | null | undefined {\n if (pattern === undefined) return undefined;\n try {\n return new RegExp(pattern);\n } catch {\n return null;\n }\n}\n\nfunction extractSortValue(\n value: unknown,\n regex: RegExp | null | undefined,\n): unknown {\n if (regex === undefined) return value;\n if (regex === null || value == null) return null;\n const match = regex.exec(String(value));\n if (!match) return null;\n return match.length > 1 ? (match[1] ?? null) : match[0];\n}\n\n/** Coerce per the field type, falling back to the raw string if coercion fails\n * (so a malformed value degrades to a string compare rather than throwing). */\nfunction coerceSafe(field: FieldDef, raw: string): string | number | boolean {\n try {\n return coerceValue(field.type, raw);\n } catch {\n return raw;\n }\n}\n\nfunction compare(a: unknown, b: unknown): number {\n if (a == null && b == null) return 0;\n if (a == null) return -1;\n if (b == null) return 1;\n if (typeof a === \"number\" && typeof b === \"number\") return a - b;\n if (typeof a === \"boolean\" && typeof b === \"boolean\")\n return a === b ? 0 : a ? 1 : -1;\n return String(a).localeCompare(String(b));\n}\n","import type { ServerQueryV2, FetchRowsResultV2 } from \"./execution\";\nimport type { QueryCapabilitiesV3, QueryRequestV3, QueryResultV3 } from \"./queryV3\";\nimport type { MetricQuery, MetricCapabilities } from \"./metricTypes\";\n// adapters.ts — the pluggable seams. Everything project-specific is injected\n// here so the package core stays generic.\n//\n// - Transport : how rows + filter-value suggestions are fetched.\n// - StorageAdapter: where saved/last queries live (in-memory by default in\n// the React hook; explicitly durable when callers opt in).\n\nimport { normalizeQueryState } from \"./query\";\nimport type { QueryState, RowId } from \"./query\";\nimport type { QuerySnapshotStore } from \"./queryLinks\";\nimport type { ServerQuery, AggregationRequest, AggregationResult } from \"./encode\";\n\n// ---- Transport ------------------------------------------------------------\n\nexport interface FetchRowsResult<Row> {\n rows: Row[];\n /** Total matching rows before pagination (for \"N of M\" + paging bounds). */\n total: number;\n}\n\n/** A keystroke-driven distinct-value lookup. Autocomplete is the DEFAULT value\n * source for every field (design feedback), so this is how the filter combobox\n * finds options. `search` is the user's current input; the backend returns the\n * best matches and whether it truncated (so the UI can prompt \"keep typing\"). */\nexport interface DistinctValuesQuery {\n field: string;\n /** Current substring/prefix the user has typed (empty = top values). */\n search: string;\n /** Max suggestions to return (default chosen by the adapter, ~50). */\n limit?: number;\n}\n\nexport interface DistinctValuesResult {\n values: string[];\n /** true when more matches exist than were returned — refine by typing. */\n hasMore: boolean;\n /** True if the selected field has at least one NULL in the source dataset.\n * False if that field is guaranteed non-null. Omitted when the backend does\n * not compute this metadata. */\n hasNull?: boolean;\n}\n\n/** Per-field metadata for the field picker. */\nexport interface FieldStats {\n distinct?: number;\n min?: string | number;\n max?: string | number;\n}\n\nexport interface Transport<Row = any> {\n queryCapabilities?: QueryCapabilitiesV3;\n fetchQueryV3?(query: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;\n fetchRowsV2?(query: ServerQueryV2, signal?: AbortSignal): Promise<FetchRowsResultV2<Row>>;\n metricCapabilities?: MetricCapabilities;\n fetchMetrics?(query: MetricQuery, signal?: AbortSignal): Promise<AggregationResult>;\n /** Run a server query. The only required method — a purely client-side table\n * can omit a Transport entirely and rely on applyQuery over local rows. */\n fetchRows(query: ServerQuery, signal?: AbortSignal): Promise<FetchRowsResult<Row>>;\n\n /** Distinct values for filter autocomplete. Strongly recommended: without it,\n * fields fall back to freeform input. The backend should match `search`\n * server-side (e.g. ILIKE prefix) and cap at `limit` so large domains stay\n * fast and refine per keystroke. */\n fetchDistinctValues?(q: DistinctValuesQuery, signal?: AbortSignal): Promise<DistinctValuesResult>;\n\n /** Run the metric panel's GROUP BY queries (one per requested aggregation),\n * scoped to the WHERE-filtered set with no paging. Optional: without it, the\n * metric panel falls back to applyAggregations over local rows (client mode).\n * Implementations compile each AggSpec with backends/go CompileAggregation,\n * sharing the same WHERE as fetchRows. */\n fetchAggregations?(q: AggregationRequest, signal?: AbortSignal): Promise<AggregationResult>;\n\n /** Re-fetch a single row by id, for in-place updates without a full re-query\n * after a mutation. Optional. */\n fetchRow?(id: RowId, signal?: AbortSignal): Promise<Row | null>;\n\n /** Stats for the field picker. Optional. */\n fetchFieldStats?(fields: string[], signal?: AbortSignal): Promise<Record<string, FieldStats>>;\n}\n\n// ---- Saved queries --------------------------------------------------------\n\nexport interface SavedQuery {\n snapshotCode?: string;\n id: string;\n name: string;\n /** Epoch millis; injected by the caller so core stays deterministic/testable. */\n savedAt: number;\n query: QueryState;\n}\n\n/** Persistence for the \"last\" query (auto-restored) and named saved queries. All\n * methods are namespaced by `key` (the schema/dataset name) so multiple tables\n * on one origin don't collide. Async to allow backend implementations; the\n * browser adapters can still resolve synchronously. */\nexport interface StorageAdapter {\n /** Optional authenticated server store. Ordinary URL sync never calls it. */\n snapshots?: QuerySnapshotStore;\n loadLast(key: string): Promise<QueryState | null>;\n saveLast(key: string, query: QueryState): Promise<void>;\n\n listSaved(key: string): Promise<SavedQuery[]>;\n /** Load the saved query selected as the default view for this key. Optional so\n * existing backend adapters keep working until they add first-class support. */\n loadDefaultSaved?(key: string): Promise<SavedQuery | null>;\n /** Set or clear the saved query used as the default view for this key. */\n setDefaultSaved?(key: string, id: string | null): Promise<void>;\n /** Persist a named query snapshot. Rejects when a saved query with the same\n * name already exists in the key namespace. */\n saveNamed(key: string, name: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n /** Atomically replace a named query's state, preserving its id, name and default\n * selection. On rejection the original entry must remain unchanged. */\n updateNamed?(key: string, id: string, query: QueryState, savedAt: number, snapshotCode?: string): Promise<SavedQuery>;\n deleteSaved(key: string, id: string): Promise<void>;\n}\n\nconst LAST_PREFIX = \"query-table:last:\";\nconst SAVED_PREFIX = \"query-table:saved:\";\nconst DEFAULT_PREFIX = \"query-table:default:\";\nconst MAX_SAVED_QUERIES = 100;\nconst MAX_SAVED_NAME_LENGTH = 200;\n\nfunction normalizeSavedQuery(value: unknown): SavedQuery | null {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) return null;\n const raw = value as Record<string, unknown>;\n if (\n typeof raw.id !== \"string\" ||\n !raw.id ||\n raw.id.length > 256 ||\n typeof raw.name !== \"string\" ||\n !raw.name ||\n raw.name.length > MAX_SAVED_NAME_LENGTH ||\n typeof raw.savedAt !== \"number\" ||\n !Number.isFinite(raw.savedAt) ||\n raw.query == null ||\n typeof raw.query !== \"object\"\n ) {\n return null;\n }\n return { id: raw.id, name: raw.name, savedAt: raw.savedAt, query: normalizeQueryState(raw.query),\n ...(typeof raw.snapshotCode === \"string\" ? { snapshotCode: raw.snapshotCode } : {}) };\n}\n\nfunction normalizeSavedQueries(value: unknown): SavedQuery[] {\n if (!Array.isArray(value)) return [];\n return value\n .slice(0, MAX_SAVED_QUERIES)\n .map(normalizeSavedQuery)\n .filter((item): item is SavedQuery => item != null);\n}\n\n/** In-memory persistence used by default by the React package. It supports the\n * full saved-query UI for the lifetime of a mounted table without writing\n * filter values to durable browser storage. */\nexport function memoryStorageAdapter(): StorageAdapter {\n const last = new Map<string, QueryState>();\n const saved = new Map<string, SavedQuery[]>();\n const defaults = new Map<string, string>();\n\n return {\n async loadLast(key) {\n const query = last.get(key);\n return query ? normalizeQueryState(query) : null;\n },\n async saveLast(key, query) {\n last.set(key, normalizeQueryState(query));\n },\n async listSaved(key) {\n return (saved.get(key) ?? []).map((item) => ({ ...item, query: normalizeQueryState(item.query) }));\n },\n async loadDefaultSaved(key) {\n const id = defaults.get(key);\n return id ? (saved.get(key) ?? []).find((item) => item.id === id) ?? null : null;\n },\n async setDefaultSaved(key, id) {\n if (id == null) {\n defaults.delete(key);\n return;\n }\n if (!(saved.get(key) ?? []).some((item) => item.id === id)) throw new Error(`Saved query \"${id}\" does not exist.`);\n defaults.set(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = saved.get(key) ?? [];\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((item) => item.name === normalizedName)) throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n saved.set(key, [...items, item]);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = saved.get(key) ?? [];\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n saved.set(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n saved.set(key, (saved.get(key) ?? []).filter((item) => item.id !== id));\n if (defaults.get(key) === id) defaults.delete(key);\n },\n };\n}\n\n/** Opt-in StorageAdapter over window.localStorage. Query state includes raw\n * filter values and is stored as cleartext JSON; do not use it for sensitive\n * datasets. Falls back to no persistence when storage is unavailable. */\nexport function localStorageAdapter(): StorageAdapter {\n const ls: Storage | null = (() => {\n try {\n return typeof localStorage !== \"undefined\" ? localStorage : null;\n } catch {\n return null; // access can throw in some sandboxes\n }\n })();\n\n const readSaved = (key: string): SavedQuery[] => {\n if (!ls) return [];\n try {\n const raw = ls.getItem(SAVED_PREFIX + key);\n return normalizeSavedQueries(raw ? JSON.parse(raw) : []);\n } catch {\n return [];\n }\n };\n const writeSaved = (key: string, items: SavedQuery[]): void => {\n if (ls) ls.setItem(SAVED_PREFIX + key, JSON.stringify(items));\n };\n const readDefaultId = (key: string): string | null => {\n if (!ls) return null;\n return ls.getItem(DEFAULT_PREFIX + key);\n };\n const writeDefaultId = (key: string, id: string | null): void => {\n if (!ls) return;\n if (id) ls.setItem(DEFAULT_PREFIX + key, id);\n else ls.removeItem(DEFAULT_PREFIX + key);\n };\n\n return {\n async loadLast(key) {\n if (!ls) return null;\n try {\n const raw = ls.getItem(LAST_PREFIX + key);\n return raw ? normalizeQueryState(JSON.parse(raw)) : null;\n } catch {\n return null;\n }\n },\n async saveLast(key, query) {\n if (ls) ls.setItem(LAST_PREFIX + key, JSON.stringify(normalizeQueryState(query)));\n },\n async listSaved(key) {\n return readSaved(key).sort((a, b) => b.savedAt - a.savedAt);\n },\n async loadDefaultSaved(key) {\n const id = readDefaultId(key);\n if (!id) return null;\n const found = readSaved(key).find((q) => q.id === id);\n if (!found) writeDefaultId(key, null);\n return found ?? null;\n },\n async setDefaultSaved(key, id) {\n if (id && !readSaved(key).some((q) => q.id === id)) {\n throw new Error(`Saved query \"${id}\" does not exist.`);\n }\n writeDefaultId(key, id);\n },\n async saveNamed(key, name, query, savedAt, snapshotCode) {\n const normalizedName = name.trim();\n if (!normalizedName || normalizedName.length > MAX_SAVED_NAME_LENGTH) {\n throw new Error(`Saved query name must be between 1 and ${MAX_SAVED_NAME_LENGTH} characters.`);\n }\n const items = readSaved(key);\n if (items.length >= MAX_SAVED_QUERIES) throw new Error(`At most ${MAX_SAVED_QUERIES} saved queries are allowed.`);\n if (items.some((q) => q.name === normalizedName)) {\n throw new Error(`Saved query \"${normalizedName}\" already exists.`);\n }\n const item: SavedQuery = {\n ...(snapshotCode ? { snapshotCode } : {}),\n id: `${savedAt}-${Math.round((savedAt * 9301 + 49297) % 233280)}`,\n name: normalizedName,\n savedAt,\n query: normalizeQueryState(query),\n };\n items.push(item);\n writeSaved(key, items);\n return item;\n },\n async updateNamed(key, id, query, savedAt, snapshotCode) {\n const items = readSaved(key);\n const original = items.find((item) => item.id === id);\n if (!original) throw new Error(`Saved query \"${id}\" does not exist.`);\n const item: SavedQuery = {\n id, name: original.name, savedAt,\n query: normalizeQueryState(query),\n ...(snapshotCode ? { snapshotCode } : {}),\n };\n writeSaved(key, items.map((entry) => entry.id === id ? item : entry));\n return item;\n },\n async deleteSaved(key, id) {\n writeSaved(\n key,\n readSaved(key).filter((q) => q.id !== id),\n );\n if (readDefaultId(key) === id) writeDefaultId(key, null);\n },\n };\n}\n","import { normalizePropertyView, type PropertyViewState } from \"./properties\";\n\nexport interface SavedPropertyView {\n id: string;\n name: string;\n savedAt: number;\n view: PropertyViewState;\n}\nexport interface PropertyViewStorage {\n loadLast(objectType: string): Promise<PropertyViewState | null>;\n saveLast(objectType: string, view: PropertyViewState): Promise<void>;\n listSaved(objectType: string): Promise<SavedPropertyView[]>;\n saveNamed(\n objectType: string,\n name: string,\n view: PropertyViewState,\n savedAt: number,\n ): Promise<SavedPropertyView>;\n deleteSaved(objectType: string, id: string): Promise<void>;\n loadDefaultSaved(objectType: string): Promise<SavedPropertyView | null>;\n setDefaultSaved(objectType: string, id: string | null): Promise<void>;\n}\ninterface StoredViews {\n last: PropertyViewState | null;\n saved: SavedPropertyView[];\n defaultId: string | null;\n}\nconst empty = (): StoredViews => ({ last: null, saved: [], defaultId: null });\nconst clone = (saved: SavedPropertyView): SavedPropertyView => ({\n ...saved,\n view: normalizePropertyView(saved.view),\n});\n\n/** The JSON-backed factory also supports application-owned synchronous preferences. */\nexport function jsonPropertyViewStorage(\n read: (key: string) => string | null,\n write: (key: string, value: string) => void,\n): PropertyViewStorage {\n const keyFor = (type: string) => `query-table:properties:${type}`;\n function load(type: string): StoredViews {\n const value = read(keyFor(type));\n if (value === null) return empty();\n const raw = JSON.parse(value) as StoredViews;\n if (\n !raw ||\n !Array.isArray(raw.saved) ||\n raw.saved.length > 100 ||\n !(raw.defaultId === null || typeof raw.defaultId === \"string\")\n )\n throw new Error(\"Invalid saved property views.\");\n const saved = raw.saved.map((item) => {\n if (\n !item ||\n typeof item.id !== \"string\" ||\n !item.id ||\n typeof item.name !== \"string\" ||\n !item.name.trim() ||\n item.name.length > 200 ||\n !Number.isFinite(item.savedAt)\n )\n throw new Error(\"Invalid saved property view.\");\n return clone(item);\n });\n return {\n last: raw.last === null ? null : normalizePropertyView(raw.last),\n saved,\n defaultId: raw.defaultId,\n };\n }\n const store = (type: string, value: StoredViews) =>\n write(keyFor(type), JSON.stringify(value));\n return {\n async loadLast(type) {\n return load(type).last;\n },\n async saveLast(type, view) {\n const data = load(type);\n data.last = normalizePropertyView(view);\n store(type, data);\n },\n async listSaved(type) {\n return load(type).saved;\n },\n async saveNamed(type, name, view, savedAt) {\n name = name.trim();\n if (!name || name.length > 200 || !Number.isFinite(savedAt))\n throw new Error(\n \"A view name (1–200 characters) and valid save time are required.\",\n );\n const data = load(type);\n if (data.saved.some((v) => v.name === name))\n throw new Error(`A property view named “${name}” already exists.`);\n if (data.saved.length >= 100)\n throw new Error(\"At most 100 saved property views are allowed.\");\n let suffix = 0;\n while (data.saved.some((v) => v.id === `${savedAt}-${suffix}`)) suffix++;\n const saved = {\n id: `${savedAt}-${suffix}`,\n name,\n savedAt,\n view: normalizePropertyView(view),\n };\n data.saved.push(saved);\n store(type, data);\n return clone(saved);\n },\n async deleteSaved(type, id) {\n const data = load(type);\n data.saved = data.saved.filter((v) => v.id !== id);\n if (data.defaultId === id) data.defaultId = null;\n store(type, data);\n },\n async loadDefaultSaved(type) {\n const data = load(type);\n return data.saved.find((v) => v.id === data.defaultId) ?? null;\n },\n async setDefaultSaved(type, id) {\n const data = load(type);\n if (id !== null && !data.saved.some((v) => v.id === id))\n throw new Error(\"Unknown property view.\");\n data.defaultId = id;\n store(type, data);\n },\n };\n}\nexport function memoryPropertyViewStorage(): PropertyViewStorage {\n const values = new Map<string, string>();\n return jsonPropertyViewStorage(\n (key) => values.get(key) ?? null,\n (key, value) => {\n values.set(key, value);\n },\n );\n}\n/** Durable browser persistence is explicitly opt-in, independently of table storage. */\nexport function localPropertyViewStorage(): PropertyViewStorage {\n return jsonPropertyViewStorage(\n (key) => localStorage.getItem(key),\n (key, value) => localStorage.setItem(key, value),\n );\n}\n","import { predicatesOf, ITEM_DETAILS_COLUMN, type QueryState } from \"./query\";\nimport { metricDependencies, compileMetric } from \"./metrics\";\nimport { createGroupingModel } from \"./grouping\";\nimport type { FieldSchema } from \"./schema\";\nimport type { FormulaPlan } from \"./formula\";\n\nexport interface SourceDependencies {\n fields: string[];\n baseFields: string[];\n identity: string;\n paths: Record<string, string>;\n}\n/** Source inputs are distinct from result/HAVING aliases. Includes hidden ROW\n * inputs and transitive computed/derived dependencies, even when not selected. */\nexport function sourceDependencies<Row>(query: QueryState, schema: FieldSchema<Row>, resolveComputed?: (name: string) => FormulaPlan | undefined): SourceDependencies {\n const fields = new Set<string>([schema.idField]);\n const addSort = (name: string) => {\n fields.add(name);\n const sortField = schema.fields.find(field => field.name === name)?.sort?.field;\n if (sortField) fields.add(sortField);\n };\n const source = query.grouping?.source ?? query;\n for (const term of source.where) for (const predicate of predicatesOf(term)) fields.add(predicate.field);\n if (query.grouping) {\n const model = createGroupingModel(schema);\n model.validate(query.grouping);\n for (const key of query.grouping.keys) fields.add(key);\n for (const summary of query.grouping.summaries) {\n if (summary.op === \"row\") fields.add(summary.field!);\n else for (const dependency of compileMetric(model.summaryExpression(summary), schema, resolveComputed).dependencies) fields.add(dependency);\n }\n for (const term of query.grouping.representative?.orderBy ?? []) addSort(term.field);\n } else {\n for (const column of source.select) if (column.field !== ITEM_DETAILS_COLUMN) fields.add(column.field);\n for (const term of source.orderBy) addSort(term.field);\n for (const metric of source.aggregations ?? []) for (const dependency of metricDependencies(metric, schema, resolveComputed)) fields.add(dependency);\n }\n const base = new Set<string>();\n const visiting = new Set<string>();\n const visit = (name: string) => {\n if (visiting.has(name)) throw Error(\"Source dependency cycle.\");\n const field = schema.fields.find(field => field.name === name);\n if (!field && name === schema.idField) { base.add(name); return; }\n const dependencies = field?.source.kind === \"derived\" ? field.source.dependencies : resolveComputed?.(name)?.dependencies;\n if (!field && !dependencies) throw Error(`Unavailable source dependency: ${name}.`);\n if (dependencies?.length) {\n visiting.add(name);\n for (const dependency of dependencies) visit(dependency);\n visiting.delete(name);\n } else base.add(name);\n };\n for (const name of fields) visit(name);\n const paths = Object.fromEntries([...base].map(name => {\n const field = schema.fields.find(field => field.name === name);\n return [name, field?.source.kind === \"backend\" ? field.source.path ?? name : name];\n }));\n return { fields: [...fields].sort(), baseFields: [...base].sort(), identity: schema.idField, paths };\n}\n","import { createGroupingModel, withoutGrouping, type GroupingDefinition } from \"./grouping\";\nimport { normalizeQueryState, predicatesOf, type QueryState, type AggregationClause } from \"./query\";\nimport { toServerQuery, type ServerQuery, type AggregationResult } from \"./encode\";\nimport { validateMetric, toMetricQuery } from \"./metrics\";\nimport type { ComputedExecution } from \"./computed\";\nimport type { FieldSchema, FieldDef } from \"./schema\";\nimport { evaluationTime } from \"./relativeTime\";\n\nexport interface QueryCapabilitiesV3 {\n version: 3;\n groupedRows: boolean;\n calendarGrouping: boolean;\n computedSourceFilters: boolean;\n regex: boolean;\n regexSourceFilters?: boolean;\n regexAggregateExpressions?: boolean;\n maxRows: number;\n maxGroups: number;\n maxPopulation: number;\n profile: string;\n}\nexport interface QueryRequestV3 {\n version: 3;\n profile: string;\n now: number;\n expectedRevisions: Record<string, string>;\n planToken?: string;\n snapshot?: string;\n source: ServerQuery;\n result: ServerQuery;\n grouping?: GroupingDefinition;\n rows: boolean;\n metrics: AggregationClause[];\n diagnostics: string[];\n}\nexport interface QueryResultV3 {\n version: 3;\n now: number;\n sourceTotal: number;\n rows: Record<string, unknown>[];\n total: number;\n schema: { name: string; idField: string; fields: { name: string; type: string }[] };\n metrics: AggregationResult[\"metrics\"];\n execution: ComputedExecution;\n}\n/** The handshake supplies authority, including capabilities for computed keys\n * absent from the base schema. Labels may be supplied by the editable catalogue. */\nexport function sourceExecutionSchema<Row>(schema: FieldSchema<Row>, execution?: ComputedExecution, catalogue: readonly { id: string; label: string; revision: string }[] = []): FieldSchema<Row> {\n const fields = new Map(schema.fields.map(field => [field.name, field]));\n for (const [name, capability] of Object.entries(execution?.fields ?? {})) {\n const definition = catalogue.find(definition => name === `@computed/${definition.id}`);\n const revision = execution?.resolvedRevisions[name] ?? execution?.resolvedRevisions[name.slice(10)];\n const current = !!revision && (!definition || definition.revision === revision);\n fields.set(name, { ...fields.get(name), name, label: definition?.label ?? fields.get(name)?.label ?? name,\n type: capability.type, source: { kind: \"backend\" },\n select: { enabled: current && capability.select }, filter: { enabled: current && capability.filter === true },\n sort: { enabled: current && capability.sort }, aggregate: { measure: current && capability.measure, groupable: current && capability.group } } as FieldDef<Row>);\n }\n return { ...schema, fields: [...fields.values()] };\n}\nexport function toQueryRequestV3<Row>(query: QueryState, baseSchema: FieldSchema<Row>, capabilities: QueryCapabilitiesV3,\n execution?: ComputedExecution, options: { now?: number; rows?: boolean } = {}): QueryRequestV3 {\n const now = evaluationTime(options), q = normalizeQueryState(query);\n const sourceSchema = sourceExecutionSchema(baseSchema, execution);\n const source = q.grouping?.source ?? withoutGrouping(q);\n const diagnostics: string[] = [];\n if ((query.aggregations?.length ?? 0) !== (q.aggregations?.length ?? 0)) diagnostics.push(\"The query exceeds its metric budget or contains malformed metric state.\");\n if (capabilities.version !== 3 || execution && execution.profile !== capabilities.profile) diagnostics.push(\"The negotiated query profile is unavailable.\");\n let resultSchema = sourceSchema as FieldSchema<any>;\n if (q.grouping) {\n if (!capabilities.groupedRows) diagnostics.push(\"This server does not support grouped rows.\");\n try { const model = createGroupingModel(sourceSchema); model.validate(q.grouping); resultSchema = model.resultSchema(q.grouping.keys, q.grouping.summaries); }\n catch (error) { diagnostics.push(error instanceof Error ? error.message : String(error)); }\n }\n const sourceRequest = toServerQuery(withoutGrouping(source), sourceSchema);\n for (const term of source.where) for (const predicate of predicatesOf(term)) if ([\"matches_regex\", \"not_matches_regex\"].includes(predicate.op) && !capabilities.regexSourceFilters)\n diagnostics.push(\"This server profile does not support isolated regex source filtering.\");\n const result = toServerQuery(withoutGrouping(q), resultSchema);\n if (sourceRequest.where.length !== source.where.length || result.where.length !== q.where.length) diagnostics.push(\"The query contains unsupported source or result predicates.\");\n if (result.orderBy.length !== q.orderBy.length) diagnostics.push(\"The query contains unsupported result ordering.\");\n if (q.grouping) for (const term of q.grouping.source.where) for (const predicate of predicatesOf(term))\n if (predicate.field.startsWith(\"@computed/\") && !capabilities.computedSourceFilters) diagnostics.push(\"This server does not support computed source predicates.\");\n const metrics = toMetricQuery(withoutGrouping(q), resultSchema, execution).metrics.map(metric => {\n const dateGrouping = q.aggregations?.find(clause => clause.id === metric.id)?.dateGrouping;\n return dateGrouping ? { ...metric, dateGrouping } : metric;\n });\n for (const metric of metrics) {\n diagnostics.push(...validateMetric(metric, resultSchema).map(issue => issue.message));\n if (metric.dateGrouping && !capabilities.calendarGrouping) diagnostics.push(\"This server does not support calendar grouping.\");\n }\n const revisions: Record<string, string> = Object.create(null);\n for (const [id, revision] of Object.entries(execution?.resolvedRevisions ?? {})) {\n if (!revision || id.length > 256 || revision.length > 256) diagnostics.push(\"Invalid computed revision envelope.\");\n else revisions[id.startsWith(\"@computed/\") ? id.slice(10) : id] = revision;\n }\n return { version: 3, profile: capabilities.profile, now, expectedRevisions: revisions,\n ...(execution?.planToken ? { planToken: execution.planToken } : {}), ...(execution?.snapshot !== undefined ? { snapshot: execution.snapshot } : {}),\n source: sourceRequest, result, ...(q.grouping ? { grouping: { keys: q.grouping.keys, summaries: q.grouping.summaries, representative: q.grouping.representative,\n ...(q.grouping.diagnostics ? { diagnostics: q.grouping.diagnostics } : {}) } } : {}), rows: options.rows !== false, metrics, diagnostics: [...new Set(diagnostics)] };\n}\nexport function validateQueryResultV3(result: QueryResultV3, request: QueryRequestV3, schema: FieldSchema): void {\n if (!result || result.version !== 3 || result.now !== request.now || !Number.isSafeInteger(result.total) || result.total < 0 ||\n !Number.isSafeInteger(result.sourceTotal) || result.sourceTotal < 0 || !Array.isArray(result.rows) || !Array.isArray(result.metrics) ||\n result.execution?.profile !== request.profile || (result.execution.planToken ?? \"\") !== (request.planToken ?? \"\") ||\n (result.execution.snapshot ?? \"\") !== (request.snapshot ?? \"\") || result.schema?.idField !== schema.idField)\n throw Error(\"Invalid or mismatched query execution response.\");\n const expected = new Map(schema.fields.map(field => [field.name, field.type]));\n if (!Array.isArray(result.schema.fields) || result.schema.fields.some(field => expected.get(field.name) !== field.type) ||\n request.rows && request.result.select.some(name => !result.schema.fields.some(field => field.name === name))) throw Error(\"The server returned a different projected schema.\");\n for (const [id, revision] of Object.entries(request.expectedRevisions)) if (result.execution.resolvedRevisions[id] !== revision)\n throw Error(\"Computed definitions changed. Refresh the server execution handshake.\");\n const seen = new Set<unknown>();\n for (const row of result.rows) { const id = row[schema.idField]; if (typeof id !== \"string\" && typeof id !== \"number\" || seen.has(id)) throw Error(\"The server returned invalid or duplicate group identities.\"); seen.add(id); }\n}\n"],"mappings":"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","names":["record","f","f","record","field","options","next","resolveField","f","options","text","code","snapshot","a","b","n","parts","f","compare","record","options","f","date","start","end","f","options","value","now","empty","options","resolveField","field","f","item","field","definition","options"]}
|