@atscript/ui-table 0.1.132 → 0.1.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -197,6 +197,10 @@ declare function derivePresetAspects(content: unknown): PresetAspect[];
197
197
  * Convert in-memory dict-form snapshot to the wire form persisted on the
198
198
  * server. Entries-arrays are sorted by `field` so consumers (server-side
199
199
  * aspect derivation, dirty detection, equality checks) see a stable order.
200
+ *
201
+ * Empty aspects round-trip as empty (since 0.1.133): a saved view with no
202
+ * filters owns `filterOps` and clears them on apply, which is not the same
203
+ * thing as a view that never claimed the aspect.
200
204
  */
201
205
  declare function toWireSnapshot(snapshot: PresetSnapshot): PresetSnapshotWire;
202
206
  declare function fromWireSnapshot(wire: PresetSnapshotWire): PresetSnapshot;
@@ -454,7 +458,7 @@ interface PresetsListResult {
454
458
  * untouched.
455
459
  */
456
460
  capabilities: PresetCapabilities | null | undefined;
457
- /** True when the controller responded 401/403 — UI silently hides. */
461
+ /** True when the controller responded 401/403/404 — UI silently hides. */
458
462
  denied: boolean;
459
463
  }
460
464
  interface PresetsSaveAsOptions {
@@ -466,7 +470,7 @@ interface PresetsSaveResult {
466
470
  /**
467
471
  * Framework-agnostic wrapper over `@atscript/db-client`'s `Client` for the
468
472
  * `AsPresetEntry` table. Handles wire serialisation, list-splitting by
469
- * `type`, capabilities side-channel, and 401/403 → `denied` semantics.
473
+ * `type`, capabilities side-channel, and 401/403/404 → `denied` semantics.
470
474
  *
471
475
  * Stateless: every method is a fresh request. The Vue composable layer
472
476
  * holds reactive state; this class only translates intent → HTTP.
@@ -483,8 +487,8 @@ declare class PresetsClient {
483
487
  * `(app, tableKey)`. By default also fetches `capabilities` in parallel —
484
488
  * pass `{ capabilities: false }` for refresh-after-mutation calls (fav
485
489
  * toggle, default change, save/save-as, public toggle, rename, delete)
486
- * where role-derived capabilities can't have changed. Auth errors
487
- * (401/403) collapse to `denied: true` with empty data so the UI hides
490
+ * where role-derived capabilities can't have changed. Unavailable
491
+ * responses (401/403/404) collapse to `denied: true` with empty data so the UI hides
488
492
  * itself silently.
489
493
  */
490
494
  list(opts?: {
@@ -525,8 +529,19 @@ declare class PresetsHttpError extends Error {
525
529
  readonly status: number;
526
530
  constructor(status: number, message: string);
527
531
  }
528
- /** True for HTTP 401/403 across both `ClientError` and `PresetsHttpError`. */
529
- declare function isAuthError(err: unknown): boolean;
532
+ /**
533
+ * True when the presets/app-prefs surface is simply not available to this
534
+ * client: HTTP 401/403 (not signed in / not permitted) or 404 (the
535
+ * controller is not mounted on this server). All three collapse to
536
+ * `denied: true` — the UI hides itself silently instead of surfacing an
537
+ * error. Covers both `ClientError` and `PresetsHttpError`.
538
+ */
539
+ declare function isUnavailableError(err: unknown): boolean;
540
+ /**
541
+ * @deprecated Renamed to `isUnavailableError` in 0.1.133 — it also covers
542
+ * 404 (feature not mounted), not just auth failures.
543
+ */
544
+ declare const isAuthError: typeof isUnavailableError;
530
545
  //#endregion
531
546
  //#region src/presets/app-prefs-client.d.ts
532
547
  /**
@@ -547,7 +562,7 @@ interface AppPrefsLoadResult {
547
562
  row: AsPresetEntryRow | null;
548
563
  /** Convenience accessor for `row.data` (the typed prefs payload), or `null`. */
549
564
  prefs: AppConfData | null;
550
- /** True when the controller responded 401/403. */
565
+ /** True when the controller responded 401/403/404 (not mounted). */
551
566
  denied: boolean;
552
567
  }
553
568
  /**
@@ -734,6 +749,21 @@ declare function resolveAspectGate(value: boolean | string[] | undefined): Aspec
734
749
  * Returns `""` (no leading `?`) for the default view.
735
750
  */
736
751
  declare function stateToUrlQueryString(state: UrlQueryStateLike, defaults: UrlQueryDefaults): string;
752
+ /**
753
+ * Whether {@link urlQueryStringToState} would consume the query key `key` —
754
+ * i.e. whether the key belongs to the table rather than to the page hosting
755
+ * it. This is the ownership rule the `useTableUrlQuery` router bridge reads
756
+ * and writes by, so both directions agree: a key the parser ignores is never
757
+ * removed, and a key it reads is the table's to remove.
758
+ *
759
+ * Shape-only, and deliberately conservative for bare `field=value` keys: a
760
+ * filter on a column and a host flag are indistinguishable without the table
761
+ * definition, so those are owned only once the bridge has written them
762
+ * itself (or once a `prefix` namespaces them).
763
+ *
764
+ * @since 0.1.133
765
+ */
766
+ declare function urlQueryConsumesKey(key: string): boolean;
737
767
  interface UrlQueryParseOptions {
738
768
  /**
739
769
  * Field paths the table knows about. Conditions on fields outside this set
@@ -1076,4 +1106,188 @@ type ColumnReorderPosition = "before" | "after";
1076
1106
  */
1077
1107
  declare function reorderColumnNames(names: string[], fromPath: string, toPath: string, position: ColumnReorderPosition): string[];
1078
1108
  //#endregion
1079
- export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, DEFAULT_ROW_HEIGHT_PX, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DraftPersistedAspect, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, USER_CONF_PREFIX, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, clampTopIndex, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, hasSecondValue, isAuthError, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortersEqual, stableStringify, stateToUrlQueryString, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb };
1109
+ //#region src/export/csv.d.ts
1110
+ /** A cell value after export-time resolution — always a spreadsheet scalar. */
1111
+ type ExportScalar = string | number | boolean | null;
1112
+ /** Options shared by {@link csvCell} and {@link toCsv}. */
1113
+ interface CsvOptions {
1114
+ /**
1115
+ * Prepend a UTF-8 byte-order mark. Excel needs it to detect UTF-8 in a
1116
+ * `.csv` opened by double-click; most other tools don't care. Default `false`.
1117
+ */
1118
+ bom?: boolean;
1119
+ /**
1120
+ * Prefix a STRING cell starting with `=`, `+`, `-`, `@`, TAB or CR with a
1121
+ * single quote so a spreadsheet treats it as text instead of a formula
1122
+ * (CSV-injection defence). Numbers and booleans are never touched — a
1123
+ * negative number stays numeric. Default `true`; set `false` when the file
1124
+ * is consumed by a parser rather than a spreadsheet.
1125
+ */
1126
+ escapeFormulas?: boolean;
1127
+ /** Field delimiter. Default `","`. */
1128
+ delimiter?: string;
1129
+ }
1130
+ /**
1131
+ * Render one value as an RFC 4180 field: formula-escaped (unless opted out),
1132
+ * then quoted when it contains the delimiter, a quote, CR or LF — with inner
1133
+ * quotes doubled.
1134
+ */
1135
+ declare function csvCell(value: ExportScalar | undefined, opts?: CsvOptions): string;
1136
+ /**
1137
+ * Serialise a header row + data rows to an RFC 4180 CSV string (`\r\n` row
1138
+ * separators, quoted fields where required, optional UTF-8 BOM).
1139
+ *
1140
+ * Pure — no DOM, no framework. See {@link csvCell} for the per-field rules.
1141
+ */
1142
+ declare function toCsv(header: readonly string[], rows: readonly (readonly ExportScalar[])[], opts?: CsvOptions): string;
1143
+ //#endregion
1144
+ //#region src/export/export-paging.d.ts
1145
+ /** Default page size used by the export pager when the caller gives none. */
1146
+ declare const DEFAULT_EXPORT_PAGE_SIZE = 500;
1147
+ /** One page of an export run — the subset of `PageResult` the pager needs. */
1148
+ interface ExportPage {
1149
+ data: Record<string, unknown>[];
1150
+ /** Total row count, when the endpoint reports one. */
1151
+ count?: number;
1152
+ }
1153
+ /** Fetches one page of the export query. Mirrors `client.pages(query, page, size)`. */
1154
+ type ExportPageFetcher = (query: Uniquery, page: number, size: number) => Promise<ExportPage>;
1155
+ /** Rejection raised when an export is cancelled through its `AbortSignal`. */
1156
+ declare class ExportAbortError extends Error {
1157
+ /** Matches the DOM convention so `err.name === "AbortError"` checks work. */
1158
+ readonly name = "AbortError";
1159
+ constructor(message?: string);
1160
+ }
1161
+ interface CollectExportRowsOptions<T = Record<string, unknown>> {
1162
+ /** The query to page through. Pass it through {@link withStableOrder} first. */
1163
+ query: Uniquery;
1164
+ /** Rows per request. Default {@link DEFAULT_EXPORT_PAGE_SIZE}. */
1165
+ pageSize?: number;
1166
+ fetchPage: ExportPageFetcher;
1167
+ /** Aborts between pages; the returned promise rejects with {@link ExportAbortError}. */
1168
+ signal?: AbortSignal;
1169
+ /** Called after every settled page. `total` comes from the first page's `count`. */
1170
+ onProgress?: (done: number, total?: number) => void;
1171
+ /** Hard ceiling on collected rows — the pager stops once it is reached. */
1172
+ maxRows?: number;
1173
+ /**
1174
+ * Project each row as it arrives — the collected array holds the projection,
1175
+ * not the raw row, so a formatted export never keeps both in memory.
1176
+ * Identity by default.
1177
+ */
1178
+ mapRow?: (row: Record<string, unknown>) => T;
1179
+ }
1180
+ /**
1181
+ * Append the primary key(s) to a query's `$sort` as a tiebreaker so paging is
1182
+ * stable: two rows equal on every user sorter keep a deterministic relative
1183
+ * order, and no row is skipped or duplicated across page boundaries.
1184
+ *
1185
+ * Existing sort fields are preserved in order and never replaced — a pk the
1186
+ * user already sorts by is left where it is. Returns the input query when
1187
+ * there is nothing to add.
1188
+ */
1189
+ declare function withStableOrder(query: Uniquery, primaryKeys: readonly string[]): Uniquery;
1190
+ /**
1191
+ * Page through `query` until the endpoint runs out of rows, collecting every
1192
+ * row into one array.
1193
+ *
1194
+ * Stops when a page comes back short (fewer rows than `pageSize`), when the
1195
+ * reported `count` is reached, or when `maxRows` is hit. Checks `signal`
1196
+ * before and after every request so a cancel lands between pages rather than
1197
+ * mid-flight.
1198
+ */
1199
+ declare function collectExportRows<T = Record<string, unknown>>(opts: CollectExportRowsOptions<T>): Promise<{
1200
+ rows: T[];
1201
+ total?: number;
1202
+ }>;
1203
+ //#endregion
1204
+ //#region src/export/export-value.d.ts
1205
+ /**
1206
+ * Turn a raw cell value into the scalar an export carries, using the same
1207
+ * column metadata the cell renderers read:
1208
+ *
1209
+ * - `null` / `undefined` → `null` (an empty CSV field).
1210
+ * - union / enum columns (`column.options`) → the option's **label**, so the
1211
+ * file reads like the screen; an unknown key falls back to the raw value.
1212
+ * - `Date` → ISO 8601 (spreadsheet- and re-import-friendly, unlike a
1213
+ * locale-formatted date).
1214
+ * - arrays → comma-joined scalars; other objects → JSON.
1215
+ * - numbers / booleans pass through untouched so a spreadsheet keeps them
1216
+ * numeric.
1217
+ *
1218
+ * Callers override per column (`formatters`) or globally (`formatCell`) when
1219
+ * they want different text.
1220
+ */
1221
+ declare function resolveExportValue(value: unknown, column?: ColumnDef): ExportScalar;
1222
+ //#endregion
1223
+ //#region src/columns/display-columns.d.ts
1224
+ /**
1225
+ * A client-owned column the app adds on top of the server's `/meta` columns —
1226
+ * a derived value, a count, a link, a widget. It has a label, a width and a
1227
+ * renderer, takes part in column visibility / reordering / presets like any
1228
+ * other column, but never reaches the backend: no `$select`, no server sort,
1229
+ * no filters.
1230
+ *
1231
+ * Since 0.1.134.
1232
+ */
1233
+ interface DisplayColumnDef {
1234
+ /**
1235
+ * Stable key. Becomes the column's `path`, so it is what `cell-<key>` /
1236
+ * `header-<key>` slots, the `columnNames` model and presets refer to. Must
1237
+ * not collide with a real field path.
1238
+ */
1239
+ key: string;
1240
+ /** Header label. Unlike `fixed` chrome columns, a display column is labelled. */
1241
+ label: string;
1242
+ /** Default width (any CSS length), e.g. `"8em"`. */
1243
+ width?: string;
1244
+ /** Initial position among the server columns (lower = earlier). Appended when omitted. */
1245
+ order?: number;
1246
+ /**
1247
+ * `'local'` makes the header offer sorting, applied client-side over the
1248
+ * rows currently loaded (page-local). Anything else — including the default
1249
+ * — leaves the column unsortable, since the server cannot sort it.
1250
+ *
1251
+ * Paged tables only: `<AsWindowTable>` caches rows by absolute index, so
1252
+ * there is no page to re-order and the affordance is not offered there.
1253
+ */
1254
+ sortable?: false | "local";
1255
+ /**
1256
+ * The value `sortable: 'local'` orders by. A display column has no server
1257
+ * field behind it, so without this the sorter reads `row[key]` — which is
1258
+ * `undefined` unless the app happens to carry that key on the row. Ignored
1259
+ * when the column is not sorted locally.
1260
+ */
1261
+ sortValue?: (row: Record<string, unknown>) => unknown;
1262
+ /** Named cell component (`components[name]` on the table context). */
1263
+ component?: string;
1264
+ /** Cell type for the `types[type]` dispatch. Default `"text"`. */
1265
+ type?: string;
1266
+ }
1267
+ /**
1268
+ * Merge client-owned columns into the server's column list, ordered by each
1269
+ * column's `order`. `Array#sort` is stable, so server columns that share an
1270
+ * `order` keep their `/meta` sequence. Returns `base` untouched when there is
1271
+ * nothing to merge.
1272
+ */
1273
+ declare function mergeDisplayColumns(base: ColumnDef[], display: readonly DisplayColumnDef[]): ColumnDef[];
1274
+ //#endregion
1275
+ //#region src/utils/sort-rows.d.ts
1276
+ /**
1277
+ * Coerce a primitive cell value to the text used for comparing and matching
1278
+ * cells — the string compare in {@link sortRowsLocally} and the substring
1279
+ * search of an in-memory table. Objects and functions collapse to `""` so
1280
+ * `'[object Object]'` never drives an ordering or matches a search.
1281
+ */
1282
+ declare function cellAsString(v: unknown): string;
1283
+ /**
1284
+ * Sort rows in memory by `sorters`, numerically when both sides are numbers
1285
+ * and locale-aware otherwise. Returns a NEW array; the input is untouched. A
1286
+ * no-op (returns the input reference) when there is nothing to sort.
1287
+ *
1288
+ * `getValue` reads a sorter's field off a row — pass a dot-path reader for
1289
+ * nested fields; the default is a flat property read.
1290
+ */
1291
+ declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], sorters: readonly SortControl[], getValue?: (row: T, field: string) => unknown): T[];
1292
+ //#endregion
1293
+ export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, type CsvOptions, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DisplayColumnDef, type DraftPersistedAspect, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, USER_CONF_PREFIX, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, hasSecondValue, isAuthError, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveExportValue, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
package/dist/index.d.mts CHANGED
@@ -197,6 +197,10 @@ declare function derivePresetAspects(content: unknown): PresetAspect[];
197
197
  * Convert in-memory dict-form snapshot to the wire form persisted on the
198
198
  * server. Entries-arrays are sorted by `field` so consumers (server-side
199
199
  * aspect derivation, dirty detection, equality checks) see a stable order.
200
+ *
201
+ * Empty aspects round-trip as empty (since 0.1.133): a saved view with no
202
+ * filters owns `filterOps` and clears them on apply, which is not the same
203
+ * thing as a view that never claimed the aspect.
200
204
  */
201
205
  declare function toWireSnapshot(snapshot: PresetSnapshot): PresetSnapshotWire;
202
206
  declare function fromWireSnapshot(wire: PresetSnapshotWire): PresetSnapshot;
@@ -454,7 +458,7 @@ interface PresetsListResult {
454
458
  * untouched.
455
459
  */
456
460
  capabilities: PresetCapabilities | null | undefined;
457
- /** True when the controller responded 401/403 — UI silently hides. */
461
+ /** True when the controller responded 401/403/404 — UI silently hides. */
458
462
  denied: boolean;
459
463
  }
460
464
  interface PresetsSaveAsOptions {
@@ -466,7 +470,7 @@ interface PresetsSaveResult {
466
470
  /**
467
471
  * Framework-agnostic wrapper over `@atscript/db-client`'s `Client` for the
468
472
  * `AsPresetEntry` table. Handles wire serialisation, list-splitting by
469
- * `type`, capabilities side-channel, and 401/403 → `denied` semantics.
473
+ * `type`, capabilities side-channel, and 401/403/404 → `denied` semantics.
470
474
  *
471
475
  * Stateless: every method is a fresh request. The Vue composable layer
472
476
  * holds reactive state; this class only translates intent → HTTP.
@@ -483,8 +487,8 @@ declare class PresetsClient {
483
487
  * `(app, tableKey)`. By default also fetches `capabilities` in parallel —
484
488
  * pass `{ capabilities: false }` for refresh-after-mutation calls (fav
485
489
  * toggle, default change, save/save-as, public toggle, rename, delete)
486
- * where role-derived capabilities can't have changed. Auth errors
487
- * (401/403) collapse to `denied: true` with empty data so the UI hides
490
+ * where role-derived capabilities can't have changed. Unavailable
491
+ * responses (401/403/404) collapse to `denied: true` with empty data so the UI hides
488
492
  * itself silently.
489
493
  */
490
494
  list(opts?: {
@@ -525,8 +529,19 @@ declare class PresetsHttpError extends Error {
525
529
  readonly status: number;
526
530
  constructor(status: number, message: string);
527
531
  }
528
- /** True for HTTP 401/403 across both `ClientError` and `PresetsHttpError`. */
529
- declare function isAuthError(err: unknown): boolean;
532
+ /**
533
+ * True when the presets/app-prefs surface is simply not available to this
534
+ * client: HTTP 401/403 (not signed in / not permitted) or 404 (the
535
+ * controller is not mounted on this server). All three collapse to
536
+ * `denied: true` — the UI hides itself silently instead of surfacing an
537
+ * error. Covers both `ClientError` and `PresetsHttpError`.
538
+ */
539
+ declare function isUnavailableError(err: unknown): boolean;
540
+ /**
541
+ * @deprecated Renamed to `isUnavailableError` in 0.1.133 — it also covers
542
+ * 404 (feature not mounted), not just auth failures.
543
+ */
544
+ declare const isAuthError: typeof isUnavailableError;
530
545
  //#endregion
531
546
  //#region src/presets/app-prefs-client.d.ts
532
547
  /**
@@ -547,7 +562,7 @@ interface AppPrefsLoadResult {
547
562
  row: AsPresetEntryRow | null;
548
563
  /** Convenience accessor for `row.data` (the typed prefs payload), or `null`. */
549
564
  prefs: AppConfData | null;
550
- /** True when the controller responded 401/403. */
565
+ /** True when the controller responded 401/403/404 (not mounted). */
551
566
  denied: boolean;
552
567
  }
553
568
  /**
@@ -734,6 +749,21 @@ declare function resolveAspectGate(value: boolean | string[] | undefined): Aspec
734
749
  * Returns `""` (no leading `?`) for the default view.
735
750
  */
736
751
  declare function stateToUrlQueryString(state: UrlQueryStateLike, defaults: UrlQueryDefaults): string;
752
+ /**
753
+ * Whether {@link urlQueryStringToState} would consume the query key `key` —
754
+ * i.e. whether the key belongs to the table rather than to the page hosting
755
+ * it. This is the ownership rule the `useTableUrlQuery` router bridge reads
756
+ * and writes by, so both directions agree: a key the parser ignores is never
757
+ * removed, and a key it reads is the table's to remove.
758
+ *
759
+ * Shape-only, and deliberately conservative for bare `field=value` keys: a
760
+ * filter on a column and a host flag are indistinguishable without the table
761
+ * definition, so those are owned only once the bridge has written them
762
+ * itself (or once a `prefix` namespaces them).
763
+ *
764
+ * @since 0.1.133
765
+ */
766
+ declare function urlQueryConsumesKey(key: string): boolean;
737
767
  interface UrlQueryParseOptions {
738
768
  /**
739
769
  * Field paths the table knows about. Conditions on fields outside this set
@@ -1076,4 +1106,188 @@ type ColumnReorderPosition = "before" | "after";
1076
1106
  */
1077
1107
  declare function reorderColumnNames(names: string[], fromPath: string, toPath: string, position: ColumnReorderPosition): string[];
1078
1108
  //#endregion
1079
- export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, DEFAULT_ROW_HEIGHT_PX, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DraftPersistedAspect, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, USER_CONF_PREFIX, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, clampTopIndex, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, hasSecondValue, isAuthError, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortersEqual, stableStringify, stateToUrlQueryString, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb };
1109
+ //#region src/export/csv.d.ts
1110
+ /** A cell value after export-time resolution — always a spreadsheet scalar. */
1111
+ type ExportScalar = string | number | boolean | null;
1112
+ /** Options shared by {@link csvCell} and {@link toCsv}. */
1113
+ interface CsvOptions {
1114
+ /**
1115
+ * Prepend a UTF-8 byte-order mark. Excel needs it to detect UTF-8 in a
1116
+ * `.csv` opened by double-click; most other tools don't care. Default `false`.
1117
+ */
1118
+ bom?: boolean;
1119
+ /**
1120
+ * Prefix a STRING cell starting with `=`, `+`, `-`, `@`, TAB or CR with a
1121
+ * single quote so a spreadsheet treats it as text instead of a formula
1122
+ * (CSV-injection defence). Numbers and booleans are never touched — a
1123
+ * negative number stays numeric. Default `true`; set `false` when the file
1124
+ * is consumed by a parser rather than a spreadsheet.
1125
+ */
1126
+ escapeFormulas?: boolean;
1127
+ /** Field delimiter. Default `","`. */
1128
+ delimiter?: string;
1129
+ }
1130
+ /**
1131
+ * Render one value as an RFC 4180 field: formula-escaped (unless opted out),
1132
+ * then quoted when it contains the delimiter, a quote, CR or LF — with inner
1133
+ * quotes doubled.
1134
+ */
1135
+ declare function csvCell(value: ExportScalar | undefined, opts?: CsvOptions): string;
1136
+ /**
1137
+ * Serialise a header row + data rows to an RFC 4180 CSV string (`\r\n` row
1138
+ * separators, quoted fields where required, optional UTF-8 BOM).
1139
+ *
1140
+ * Pure — no DOM, no framework. See {@link csvCell} for the per-field rules.
1141
+ */
1142
+ declare function toCsv(header: readonly string[], rows: readonly (readonly ExportScalar[])[], opts?: CsvOptions): string;
1143
+ //#endregion
1144
+ //#region src/export/export-paging.d.ts
1145
+ /** Default page size used by the export pager when the caller gives none. */
1146
+ declare const DEFAULT_EXPORT_PAGE_SIZE = 500;
1147
+ /** One page of an export run — the subset of `PageResult` the pager needs. */
1148
+ interface ExportPage {
1149
+ data: Record<string, unknown>[];
1150
+ /** Total row count, when the endpoint reports one. */
1151
+ count?: number;
1152
+ }
1153
+ /** Fetches one page of the export query. Mirrors `client.pages(query, page, size)`. */
1154
+ type ExportPageFetcher = (query: Uniquery, page: number, size: number) => Promise<ExportPage>;
1155
+ /** Rejection raised when an export is cancelled through its `AbortSignal`. */
1156
+ declare class ExportAbortError extends Error {
1157
+ /** Matches the DOM convention so `err.name === "AbortError"` checks work. */
1158
+ readonly name = "AbortError";
1159
+ constructor(message?: string);
1160
+ }
1161
+ interface CollectExportRowsOptions<T = Record<string, unknown>> {
1162
+ /** The query to page through. Pass it through {@link withStableOrder} first. */
1163
+ query: Uniquery;
1164
+ /** Rows per request. Default {@link DEFAULT_EXPORT_PAGE_SIZE}. */
1165
+ pageSize?: number;
1166
+ fetchPage: ExportPageFetcher;
1167
+ /** Aborts between pages; the returned promise rejects with {@link ExportAbortError}. */
1168
+ signal?: AbortSignal;
1169
+ /** Called after every settled page. `total` comes from the first page's `count`. */
1170
+ onProgress?: (done: number, total?: number) => void;
1171
+ /** Hard ceiling on collected rows — the pager stops once it is reached. */
1172
+ maxRows?: number;
1173
+ /**
1174
+ * Project each row as it arrives — the collected array holds the projection,
1175
+ * not the raw row, so a formatted export never keeps both in memory.
1176
+ * Identity by default.
1177
+ */
1178
+ mapRow?: (row: Record<string, unknown>) => T;
1179
+ }
1180
+ /**
1181
+ * Append the primary key(s) to a query's `$sort` as a tiebreaker so paging is
1182
+ * stable: two rows equal on every user sorter keep a deterministic relative
1183
+ * order, and no row is skipped or duplicated across page boundaries.
1184
+ *
1185
+ * Existing sort fields are preserved in order and never replaced — a pk the
1186
+ * user already sorts by is left where it is. Returns the input query when
1187
+ * there is nothing to add.
1188
+ */
1189
+ declare function withStableOrder(query: Uniquery, primaryKeys: readonly string[]): Uniquery;
1190
+ /**
1191
+ * Page through `query` until the endpoint runs out of rows, collecting every
1192
+ * row into one array.
1193
+ *
1194
+ * Stops when a page comes back short (fewer rows than `pageSize`), when the
1195
+ * reported `count` is reached, or when `maxRows` is hit. Checks `signal`
1196
+ * before and after every request so a cancel lands between pages rather than
1197
+ * mid-flight.
1198
+ */
1199
+ declare function collectExportRows<T = Record<string, unknown>>(opts: CollectExportRowsOptions<T>): Promise<{
1200
+ rows: T[];
1201
+ total?: number;
1202
+ }>;
1203
+ //#endregion
1204
+ //#region src/export/export-value.d.ts
1205
+ /**
1206
+ * Turn a raw cell value into the scalar an export carries, using the same
1207
+ * column metadata the cell renderers read:
1208
+ *
1209
+ * - `null` / `undefined` → `null` (an empty CSV field).
1210
+ * - union / enum columns (`column.options`) → the option's **label**, so the
1211
+ * file reads like the screen; an unknown key falls back to the raw value.
1212
+ * - `Date` → ISO 8601 (spreadsheet- and re-import-friendly, unlike a
1213
+ * locale-formatted date).
1214
+ * - arrays → comma-joined scalars; other objects → JSON.
1215
+ * - numbers / booleans pass through untouched so a spreadsheet keeps them
1216
+ * numeric.
1217
+ *
1218
+ * Callers override per column (`formatters`) or globally (`formatCell`) when
1219
+ * they want different text.
1220
+ */
1221
+ declare function resolveExportValue(value: unknown, column?: ColumnDef): ExportScalar;
1222
+ //#endregion
1223
+ //#region src/columns/display-columns.d.ts
1224
+ /**
1225
+ * A client-owned column the app adds on top of the server's `/meta` columns —
1226
+ * a derived value, a count, a link, a widget. It has a label, a width and a
1227
+ * renderer, takes part in column visibility / reordering / presets like any
1228
+ * other column, but never reaches the backend: no `$select`, no server sort,
1229
+ * no filters.
1230
+ *
1231
+ * Since 0.1.134.
1232
+ */
1233
+ interface DisplayColumnDef {
1234
+ /**
1235
+ * Stable key. Becomes the column's `path`, so it is what `cell-<key>` /
1236
+ * `header-<key>` slots, the `columnNames` model and presets refer to. Must
1237
+ * not collide with a real field path.
1238
+ */
1239
+ key: string;
1240
+ /** Header label. Unlike `fixed` chrome columns, a display column is labelled. */
1241
+ label: string;
1242
+ /** Default width (any CSS length), e.g. `"8em"`. */
1243
+ width?: string;
1244
+ /** Initial position among the server columns (lower = earlier). Appended when omitted. */
1245
+ order?: number;
1246
+ /**
1247
+ * `'local'` makes the header offer sorting, applied client-side over the
1248
+ * rows currently loaded (page-local). Anything else — including the default
1249
+ * — leaves the column unsortable, since the server cannot sort it.
1250
+ *
1251
+ * Paged tables only: `<AsWindowTable>` caches rows by absolute index, so
1252
+ * there is no page to re-order and the affordance is not offered there.
1253
+ */
1254
+ sortable?: false | "local";
1255
+ /**
1256
+ * The value `sortable: 'local'` orders by. A display column has no server
1257
+ * field behind it, so without this the sorter reads `row[key]` — which is
1258
+ * `undefined` unless the app happens to carry that key on the row. Ignored
1259
+ * when the column is not sorted locally.
1260
+ */
1261
+ sortValue?: (row: Record<string, unknown>) => unknown;
1262
+ /** Named cell component (`components[name]` on the table context). */
1263
+ component?: string;
1264
+ /** Cell type for the `types[type]` dispatch. Default `"text"`. */
1265
+ type?: string;
1266
+ }
1267
+ /**
1268
+ * Merge client-owned columns into the server's column list, ordered by each
1269
+ * column's `order`. `Array#sort` is stable, so server columns that share an
1270
+ * `order` keep their `/meta` sequence. Returns `base` untouched when there is
1271
+ * nothing to merge.
1272
+ */
1273
+ declare function mergeDisplayColumns(base: ColumnDef[], display: readonly DisplayColumnDef[]): ColumnDef[];
1274
+ //#endregion
1275
+ //#region src/utils/sort-rows.d.ts
1276
+ /**
1277
+ * Coerce a primitive cell value to the text used for comparing and matching
1278
+ * cells — the string compare in {@link sortRowsLocally} and the substring
1279
+ * search of an in-memory table. Objects and functions collapse to `""` so
1280
+ * `'[object Object]'` never drives an ordering or matches a search.
1281
+ */
1282
+ declare function cellAsString(v: unknown): string;
1283
+ /**
1284
+ * Sort rows in memory by `sorters`, numerically when both sides are numbers
1285
+ * and locale-aware otherwise. Returns a NEW array; the input is untouched. A
1286
+ * no-op (returns the input reference) when there is nothing to sort.
1287
+ *
1288
+ * `getValue` reads a sorter's field off a row — pass a dot-path reader for
1289
+ * nested fields; the default is a flat property read.
1290
+ */
1291
+ declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], sorters: readonly SortControl[], getValue?: (row: T, field: string) => unknown): T[];
1292
+ //#endregion
1293
+ export { APP_CONF_PREFIX, type AppConfData, AppPrefsClient, type AppPrefsClientConfig, type AppPrefsLoadResult, type AsPresetEntryData, type AsPresetEntryRow, type AsPresetsErrorCode, type AspectGate, type AspectMask, type BuildTableQueryOptions, type ColumnFilterType, type ColumnReorderPosition, type ColumnWidthEntry, type ColumnWidthsMap, type ConfigTab, type CsvOptions, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DisplayColumnDef, type DraftPersistedAspect, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, MAX_DEFAULT_COLUMN_WIDTH_PX, type MergeResult, NULL_OPS, PRESET_ASPECTS, type PageAlignedBlock, type PlanFetchArgs, type PresetAspect, type PresetCapabilities, type PresetColumnWidthEntry, type PresetData, type PresetDraft, type PresetFilterOpEntry, type PresetLimitReachedBody, type PresetSnapshot, type PresetSnapshotWire, type PresetSorterEntry, PresetsClient, type PresetsClientConfig, PresetsHttpError, type PresetsListResult, type PresetsSaveAsOptions, type PresetsSaveResult, type QueryOptions, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, type SelectionMode, type SystemPreset, type SystemPresetInput, type TableStateData, type TableStateMethods, USER_CONF_PREFIX, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, hasSecondValue, isAuthError, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, resolveAspectGate, resolveExportValue, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };