@atscript/ui-table 0.1.139 → 0.1.140
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.cjs +220 -48
- package/dist/index.d.cts +142 -11
- package/dist/index.d.mts +142 -11
- package/dist/index.mjs +216 -50
- package/package.json +8 -8
package/dist/index.d.mts
CHANGED
|
@@ -175,6 +175,67 @@ interface UnsupportedFilter {
|
|
|
175
175
|
/** Field paths the sub-expression references, in order of appearance. */
|
|
176
176
|
fields: string[];
|
|
177
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Field paths a Uniquery filter expression references, deduped, in order of
|
|
180
|
+
* appearance (logical operators are walked, operator keys skipped).
|
|
181
|
+
*
|
|
182
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
183
|
+
*/
|
|
184
|
+
declare function filterExprFields(expr: unknown): string[];
|
|
185
|
+
/** Options for {@link decomposeUniqueryFilter}. @since 0.1.140 */
|
|
186
|
+
interface DecomposeUniqueryFilterOptions {
|
|
187
|
+
/**
|
|
188
|
+
* Field paths the table knows. Pieces on fields outside it are ignored
|
|
189
|
+
* silently; a piece mixing known and unknown fields is reported, never
|
|
190
|
+
* carried. Omit to accept every field.
|
|
191
|
+
*/
|
|
192
|
+
knownFields?: Iterable<string>;
|
|
193
|
+
/**
|
|
194
|
+
* Keep left-out pieces whose fields are all known as `residual` instead of
|
|
195
|
+
* reporting them. Default `false` — the 0.1.139 split. See
|
|
196
|
+
* [Custom filter conditions](https://ui.atscript.dev/tables/filtering#custom-filter-conditions).
|
|
197
|
+
*/
|
|
198
|
+
carry?: boolean;
|
|
199
|
+
}
|
|
200
|
+
/** Result of {@link decomposeUniqueryFilter}. @since 0.1.140 */
|
|
201
|
+
interface DecomposedUniqueryFilter {
|
|
202
|
+
/** The part field filters express exactly. */
|
|
203
|
+
filters: FieldFilters;
|
|
204
|
+
/** Carried pieces — AND-ed conditions, deduped, canonical order. `[]` unless `carry` is on. */
|
|
205
|
+
residual: FilterExpr[];
|
|
206
|
+
/** Pieces left out and lost — the result is broader by exactly these. */
|
|
207
|
+
unsupported: UnsupportedFilter[];
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Split a Uniquery `FilterExpr` into what the table's field-filter model
|
|
211
|
+
* holds exactly (`filters`), what it cannot hold but carries as residual
|
|
212
|
+
* conditions (`residual`, with `carry`), and what it leaves out
|
|
213
|
+
* (`unsupported`). Nothing is approximated: `filters AND residual` selects
|
|
214
|
+
* `expr` minus the `unsupported` pieces and pieces on fields outside
|
|
215
|
+
* `knownFields`.
|
|
216
|
+
*
|
|
217
|
+
* Never throws, never warns — the caller decides how to report.
|
|
218
|
+
*
|
|
219
|
+
* @since 0.1.140
|
|
220
|
+
*/
|
|
221
|
+
declare function decomposeUniqueryFilter(expr: FilterExpr | undefined, opts?: DecomposeUniqueryFilterOptions): DecomposedUniqueryFilter;
|
|
222
|
+
/**
|
|
223
|
+
* Canonical identity of a filter expression — its `@uniqu/url` spelling.
|
|
224
|
+
* Two expressions with the same key select the same rows.
|
|
225
|
+
*
|
|
226
|
+
* @since 0.1.140
|
|
227
|
+
*/
|
|
228
|
+
declare function filterExprKey(expr: FilterExpr): string;
|
|
229
|
+
/**
|
|
230
|
+
* A residual-condition list with empty expressions and duplicates (by
|
|
231
|
+
* {@link filterExprKey}) dropped, sorted by key. Sorted, not first-appearance:
|
|
232
|
+
* the URL parser moves \`$not\`-wrapped clauses (how \`mergeFilters\` spells
|
|
233
|
+
* a repeated same-field clause) ahead of plain ones, so appearance order would
|
|
234
|
+
* flip on every round trip.
|
|
235
|
+
*
|
|
236
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
237
|
+
*/
|
|
238
|
+
declare function normalizeResidualFilters(exprs: readonly FilterExpr[]): FilterExpr[];
|
|
178
239
|
/**
|
|
179
240
|
* Convert a Uniquery `FilterExpr` back into the UI's `FieldFilters` shape.
|
|
180
241
|
*
|
|
@@ -189,7 +250,8 @@ interface UnsupportedFilter {
|
|
|
189
250
|
* - Anything else (see {@link UnsupportedFilterReason}) is left out. Leaving
|
|
190
251
|
* an AND-ed piece out only ever widens the match, so the result selects a
|
|
191
252
|
* superset of `expr`. Each left-out piece goes to `onUnsupportedFilter`, or
|
|
192
|
-
* to a dev-mode `console.warn` when no handler is given.
|
|
253
|
+
* to a dev-mode `console.warn` when no handler is given. To keep those
|
|
254
|
+
* pieces instead, use {@link decomposeUniqueryFilter} with `carry`.
|
|
193
255
|
*
|
|
194
256
|
* Conditions on fields outside `knownFields` (when provided) are ignored
|
|
195
257
|
* silently: they are not this table's (a host page flag, a stale column). A
|
|
@@ -199,6 +261,20 @@ interface UnsupportedFilter {
|
|
|
199
261
|
*/
|
|
200
262
|
declare function uniqueryFilterToFieldFilters(expr: FilterExpr | undefined, knownFields?: Iterable<string> | Set<string>, onUnsupportedFilter?: (issue: UnsupportedFilter) => void): FieldFilters;
|
|
201
263
|
//#endregion
|
|
264
|
+
//#region src/filters/format-filter-expr.d.ts
|
|
265
|
+
/**
|
|
266
|
+
* Human-readable rendering of a Uniquery filter expression, worded like the
|
|
267
|
+
* filter-field chips: `(Status equals shipped and Total greater than 500) or
|
|
268
|
+
* (Status equals pending and Total less or equal 50)`. `and` binds tighter
|
|
269
|
+
* than `or`; groups are parenthesized only where needed. Operators without a
|
|
270
|
+
* wording fall back to their `@uniqu/url` spelling.
|
|
271
|
+
*
|
|
272
|
+
* @param labelOf — display label for a field path (e.g. the column label);
|
|
273
|
+
* the path itself when omitted or when it returns `undefined`.
|
|
274
|
+
* @since 0.1.140
|
|
275
|
+
*/
|
|
276
|
+
declare function formatFilterExpr(expr: FilterExpr, labelOf?: (path: string) => string | undefined): string;
|
|
277
|
+
//#endregion
|
|
202
278
|
//#region src/filters/date-shortcuts.d.ts
|
|
203
279
|
/** A date shortcut produces a label and a [start, end] ISO date range. */
|
|
204
280
|
interface DateShortcut {
|
|
@@ -694,6 +770,12 @@ interface BuildTableQueryOptions {
|
|
|
694
770
|
ignoreSorters?: boolean;
|
|
695
771
|
/** User-configured field filters. */
|
|
696
772
|
filters: FieldFilters;
|
|
773
|
+
/**
|
|
774
|
+
* Residual filter conditions — AND-ed conjuncts the field-filter model
|
|
775
|
+
* cannot hold (a cross-field `$or`, a second range on one field, …). AND'd
|
|
776
|
+
* after `filters`. Since 0.1.140.
|
|
777
|
+
*/
|
|
778
|
+
residualFilters?: FilterExpr[];
|
|
697
779
|
/** Always-applied Uniquery filter (AND'd with user filters). */
|
|
698
780
|
forceFilters?: FilterExpr;
|
|
699
781
|
/** Full-text search term. */
|
|
@@ -712,7 +794,8 @@ interface BuildTableQueryOptions {
|
|
|
712
794
|
* Build a Uniquery object from table UI state.
|
|
713
795
|
*
|
|
714
796
|
* Pure function — no framework dependencies.
|
|
715
|
-
* Combines user filters
|
|
797
|
+
* Combines user filters (field filters, then residual conditions) with force
|
|
798
|
+
* filters, merges sorters,
|
|
716
799
|
* projects visible columns, and applies pagination.
|
|
717
800
|
*/
|
|
718
801
|
declare function buildTableQuery(opts: BuildTableQueryOptions): Uniquery;
|
|
@@ -728,8 +811,9 @@ declare function mergeSorters(forceSorters: SortControl[], userSorters: SortCont
|
|
|
728
811
|
//#endregion
|
|
729
812
|
//#region src/query/merge-filters.d.ts
|
|
730
813
|
/**
|
|
731
|
-
* AND-merge
|
|
732
|
-
* `@uniqu/url`'s `mergeConjunction` parser collapse.
|
|
814
|
+
* AND-merge filter expressions (`undefined` ones skipped), producing a wire
|
|
815
|
+
* shape that survives `@uniqu/url`'s `mergeConjunction` parser collapse.
|
|
816
|
+
* Variadic since 0.1.140.
|
|
733
817
|
*
|
|
734
818
|
* The collapse problem: when two `$and` siblings target the same field
|
|
735
819
|
* with the same op (e.g. `{status: 'cancelled'}` AND `{status: 'shipped'}`),
|
|
@@ -742,12 +826,17 @@ declare function mergeSorters(forceSorters: SortControl[], userSorters: SortCont
|
|
|
742
826
|
* and `!!p ≡ p` is a semantic identity, so the server evaluator sees the
|
|
743
827
|
* same AND. Non-colliding merges produce the canonical `$and` shape.
|
|
744
828
|
*/
|
|
745
|
-
declare function mergeFilters(
|
|
829
|
+
declare function mergeFilters(...exprs: (FilterExpr | undefined)[]): FilterExpr | undefined;
|
|
746
830
|
//#endregion
|
|
747
831
|
//#region src/query/url-query.d.ts
|
|
748
832
|
/** State subset that round-trips through the URL bridge. */
|
|
749
833
|
interface UrlQueryStateLike {
|
|
750
834
|
filters: FieldFilters;
|
|
835
|
+
/**
|
|
836
|
+
* Residual filter conditions, AND-ed after `filters`. Only the ones the
|
|
837
|
+
* filter gate owns are written (see {@link residualGateOwns}). Since 0.1.140.
|
|
838
|
+
*/
|
|
839
|
+
residualFilters?: FilterExpr[];
|
|
751
840
|
sorters: SortControl[];
|
|
752
841
|
/** 1-based page number. `1` is the default and is omitted from the URL. */
|
|
753
842
|
page?: number;
|
|
@@ -788,11 +877,17 @@ interface UrlQueryStateSnapshot {
|
|
|
788
877
|
*/
|
|
789
878
|
snapshot?: true;
|
|
790
879
|
/**
|
|
791
|
-
* Pieces of the URL's filter that
|
|
792
|
-
* cannot express them — see `uniqueryFilterToFieldFilters`.
|
|
793
|
-
* the
|
|
880
|
+
* Pieces of the URL's filter that are left out because field filters
|
|
881
|
+
* cannot express them — see `uniqueryFilterToFieldFilters`. Since 0.1.140
|
|
882
|
+
* only the pieces NOT carried in `residual`. Omitted when none. Since 0.1.139.
|
|
794
883
|
*/
|
|
795
884
|
unsupported?: UnsupportedFilter[];
|
|
885
|
+
/**
|
|
886
|
+
* Filter pieces field filters cannot express, carried as residual
|
|
887
|
+
* conditions (see `decomposeUniqueryFilter`). Omitted when there are none
|
|
888
|
+
* or `sync.residual` is `false`. Since 0.1.140.
|
|
889
|
+
*/
|
|
890
|
+
residual?: FilterExpr[];
|
|
796
891
|
/**
|
|
797
892
|
* Raw record offset from `$skip` (omitted when no `$skip` in URL). The
|
|
798
893
|
* decoder does NOT compute a page index — that requires `itemsPerPage`,
|
|
@@ -836,6 +931,15 @@ interface UrlQuerySync {
|
|
|
836
931
|
* Since 0.1.139.
|
|
837
932
|
*/
|
|
838
933
|
snapshot?: boolean;
|
|
934
|
+
/**
|
|
935
|
+
* Whether filter pieces the field-filter model cannot hold travel as
|
|
936
|
+
* residual conditions. Default `true`: the encoder writes
|
|
937
|
+
* `UrlQueryStateLike.residualFilters` and the decoder returns them as
|
|
938
|
+
* `residual`. `false`: neither — the 0.1.139 behaviour, where such
|
|
939
|
+
* pieces are left out and reported. Inert when `filters` is off.
|
|
940
|
+
* Since 0.1.140.
|
|
941
|
+
*/
|
|
942
|
+
residual?: boolean;
|
|
839
943
|
}
|
|
840
944
|
interface UrlQueryDefaults {
|
|
841
945
|
/** Consumer's `:limit` prop. Used to omit `$limit` from the URL when state matches it. */
|
|
@@ -872,6 +976,14 @@ declare function resolveAspectGate(value: boolean | string[] | undefined): Aspec
|
|
|
872
976
|
* @since 0.1.137
|
|
873
977
|
*/
|
|
874
978
|
declare function gateOwns(gate: AspectGate, path: string): boolean;
|
|
979
|
+
/**
|
|
980
|
+
* Does a URL under `gate` own the residual condition `expr`? Only when it
|
|
981
|
+
* owns every field the condition references — a condition that touches a
|
|
982
|
+
* private field stays private as a whole.
|
|
983
|
+
*
|
|
984
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
985
|
+
*/
|
|
986
|
+
declare function residualGateOwns(gate: AspectGate, expr: FilterExpr): boolean;
|
|
875
987
|
/**
|
|
876
988
|
* Serialize the table state subset into a URL query string.
|
|
877
989
|
*
|
|
@@ -917,7 +1029,9 @@ interface UrlQueryParseOptions {
|
|
|
917
1029
|
* - unknown fields (not in `knownFields`) → silently dropped
|
|
918
1030
|
* - filter pieces field filters cannot express (cross-field OR, unknown
|
|
919
1031
|
* operator, …) → left out of `filters` and listed in `unsupported`, never
|
|
920
|
-
* approximated (the parser does not warn — the caller decides)
|
|
1032
|
+
* approximated (the parser does not warn — the caller decides). Unless
|
|
1033
|
+
* `sync.residual` is `false`, those whose fields are all known come back
|
|
1034
|
+
* in `residual` instead
|
|
921
1035
|
* - unknown controls (e.g. `$weird=42`) → silently ignored
|
|
922
1036
|
* - malformed query → `{ filters: {}, sorters: [], searchTerm: "" }`
|
|
923
1037
|
*
|
|
@@ -1012,6 +1126,13 @@ interface TableStateData {
|
|
|
1012
1126
|
filterFields: string[];
|
|
1013
1127
|
/** Active field filters. */
|
|
1014
1128
|
filters: FieldFilters;
|
|
1129
|
+
/**
|
|
1130
|
+
* Residual filter conditions — AND-ed Uniquery conjuncts the field-filter
|
|
1131
|
+
* model cannot hold (a cross-field `$or`, a second range on one field, …),
|
|
1132
|
+
* applied after `filters`. Restored from URLs, shown as "custom filter"
|
|
1133
|
+
* chips. Since 0.1.140.
|
|
1134
|
+
*/
|
|
1135
|
+
residualFilters: FilterExpr[];
|
|
1015
1136
|
/** Active sorters. */
|
|
1016
1137
|
sorters: SortControl[];
|
|
1017
1138
|
/**
|
|
@@ -1132,8 +1253,18 @@ interface TableStateMethods {
|
|
|
1132
1253
|
loadingAt(absIdx: number): boolean;
|
|
1133
1254
|
/** Returns the last error attached to the block covering `absIdx`, or null. */
|
|
1134
1255
|
errorAt(absIdx: number): Error | null;
|
|
1135
|
-
/**
|
|
1256
|
+
/**
|
|
1257
|
+
* Clear all applied filters — field filters and residual conditions. Does
|
|
1258
|
+
* not touch `filterFields`.
|
|
1259
|
+
*/
|
|
1136
1260
|
resetFilters(): void;
|
|
1261
|
+
/**
|
|
1262
|
+
* Replace the residual filter conditions (AND-ed Uniquery conjuncts).
|
|
1263
|
+
* Empty expressions and duplicates are dropped. Since 0.1.140.
|
|
1264
|
+
*/
|
|
1265
|
+
setResidualFilters(exprs: FilterExpr[]): void;
|
|
1266
|
+
/** Remove the residual condition at `index`. Since 0.1.140. */
|
|
1267
|
+
removeResidualFilter(index: number): void;
|
|
1137
1268
|
/** Open the config dialog (optionally to a specific tab). */
|
|
1138
1269
|
showConfigDialog(tab?: ConfigTab): void;
|
|
1139
1270
|
/** Append a field to the displayed filter fields (deduped). */
|
|
@@ -1430,4 +1561,4 @@ declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], s
|
|
|
1430
1561
|
//#region src/utils/dev.d.ts
|
|
1431
1562
|
declare const DEV: boolean;
|
|
1432
1563
|
//#endregion
|
|
1433
|
-
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, DEV, 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, type FilterableColumn, 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, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseColumnFilterInput, 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 };
|
|
1564
|
+
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, DEV, DRAFT_PERSISTED_ASPECTS, type DateShortcut, type DecomposeUniqueryFilterOptions, type DecomposedUniqueryFilter, type DisplayColumnDef, type DraftPersistedAspect, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, 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, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, decomposeUniqueryFilter, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterExprFields, filterExprKey, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, formatFilterExpr, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, normalizeResidualFilters, pageAlignedBlocksFor, parseColumnFilterInput, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, 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.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { isLogicalKey } from "@uniqu/core";
|
|
1
|
+
import { isLogicalKey, walkFilter } from "@uniqu/core";
|
|
2
|
+
import { buildUrl } from "@uniqu/url/builder";
|
|
2
3
|
import { ClientError } from "@atscript/db-client";
|
|
3
4
|
import { getDefaultClientFactory, str } from "@atscript/ui";
|
|
4
|
-
import { buildUrl } from "@uniqu/url/builder";
|
|
5
5
|
import { parseUrl } from "@uniqu/url";
|
|
6
6
|
//#region src/filters/filter-conditions.ts
|
|
7
7
|
/** Conditions that operate purely on nullability — value is ignored. */
|
|
@@ -508,8 +508,16 @@ const RANGE_OPS = {
|
|
|
508
508
|
$lt: "lt",
|
|
509
509
|
$lte: "lte"
|
|
510
510
|
};
|
|
511
|
-
/**
|
|
512
|
-
|
|
511
|
+
/**
|
|
512
|
+
* Field paths a Uniquery filter expression references, deduped, in order of
|
|
513
|
+
* appearance (logical operators are walked, operator keys skipped).
|
|
514
|
+
*
|
|
515
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
516
|
+
*/
|
|
517
|
+
function filterExprFields(expr) {
|
|
518
|
+
return fieldsOf(expr, []);
|
|
519
|
+
}
|
|
520
|
+
function fieldsOf(expr, out) {
|
|
513
521
|
if (Array.isArray(expr)) {
|
|
514
522
|
for (const child of expr) fieldsOf(child, out);
|
|
515
523
|
return out;
|
|
@@ -520,7 +528,7 @@ function fieldsOf(expr, out = []) {
|
|
|
520
528
|
return out;
|
|
521
529
|
}
|
|
522
530
|
function unsupported(reason, expr) {
|
|
523
|
-
const fields = fieldsOf(expr);
|
|
531
|
+
const fields = fieldsOf(expr, []);
|
|
524
532
|
return {
|
|
525
533
|
reason: fields.length > 1 ? "cross-field" : reason,
|
|
526
534
|
expr,
|
|
@@ -698,6 +706,7 @@ function invert(cond) {
|
|
|
698
706
|
* anything else would invert into an OR of ANDs, which the model cannot hold.
|
|
699
707
|
*/
|
|
700
708
|
function collectNot(child, out) {
|
|
709
|
+
if (isPlainObject(child) && Object.keys(child).length === 1 && "$not" in child) return collect(child.$not, out);
|
|
701
710
|
const expr = { $not: child };
|
|
702
711
|
const b = classifyBranch(child);
|
|
703
712
|
if (b && !("reason" in b) && (b.terms.length === 1 || b.terms.every(isNegative))) {
|
|
@@ -741,30 +750,26 @@ function warnUnsupported(issue) {
|
|
|
741
750
|
console.warn(`[ui-table] Filter left out (${issue.reason}): ${JSON.stringify(issue.expr)}. Field filters cannot express it, so the result is broader than the source filter.`);
|
|
742
751
|
}
|
|
743
752
|
/**
|
|
744
|
-
*
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
*
|
|
753
|
+
* Split a Uniquery `FilterExpr` into what the table's field-filter model
|
|
754
|
+
* holds exactly (`filters`), what it cannot hold but carries as residual
|
|
755
|
+
* conditions (`residual`, with `carry`), and what it leaves out
|
|
756
|
+
* (`unsupported`). Nothing is approximated: `filters AND residual` selects
|
|
757
|
+
* `expr` minus the `unsupported` pieces and pieces on fields outside
|
|
758
|
+
* `knownFields`.
|
|
749
759
|
*
|
|
750
|
-
*
|
|
751
|
-
* - A same-field `$or` becomes that field's OR'd conditions.
|
|
752
|
-
* - A `$not` that inverts equality / emptiness becomes the inverse conditions.
|
|
753
|
-
* - Fields next to `$and` / `$or` / `$not` in one object are all kept.
|
|
754
|
-
* - Anything else (see {@link UnsupportedFilterReason}) is left out. Leaving
|
|
755
|
-
* an AND-ed piece out only ever widens the match, so the result selects a
|
|
756
|
-
* superset of `expr`. Each left-out piece goes to `onUnsupportedFilter`, or
|
|
757
|
-
* to a dev-mode `console.warn` when no handler is given.
|
|
758
|
-
*
|
|
759
|
-
* Conditions on fields outside `knownFields` (when provided) are ignored
|
|
760
|
-
* silently: they are not this table's (a host page flag, a stale column). A
|
|
761
|
-
* piece that mixes known and unknown fields is reported.
|
|
760
|
+
* Never throws, never warns — the caller decides how to report.
|
|
762
761
|
*
|
|
763
|
-
*
|
|
762
|
+
* @since 0.1.140
|
|
764
763
|
*/
|
|
765
|
-
function
|
|
766
|
-
const
|
|
767
|
-
|
|
764
|
+
function decomposeUniqueryFilter(expr, opts = {}) {
|
|
765
|
+
const filters = {};
|
|
766
|
+
const result = {
|
|
767
|
+
filters,
|
|
768
|
+
residual: [],
|
|
769
|
+
unsupported: []
|
|
770
|
+
};
|
|
771
|
+
if (!expr) return result;
|
|
772
|
+
const knownFields = opts.knownFields;
|
|
768
773
|
const known = knownFields == null ? null : knownFields instanceof Set ? knownFields : new Set(knownFields);
|
|
769
774
|
const isKnown = (field) => known === null || known.has(field);
|
|
770
775
|
const out = {
|
|
@@ -784,19 +789,158 @@ function uniqueryFilterToFieldFilters(expr, knownFields, onUnsupportedFilter = w
|
|
|
784
789
|
const positives = /* @__PURE__ */ new Map();
|
|
785
790
|
for (const term of out.terms) {
|
|
786
791
|
if (!isKnown(term.field)) continue;
|
|
787
|
-
const list =
|
|
788
|
-
|
|
789
|
-
if (isNegative(term) || !kept) {
|
|
790
|
-
if (!isNegative(term)) positives.set(term.field, term.conds);
|
|
792
|
+
const list = filters[term.field] ??= [];
|
|
793
|
+
if (isNegative(term)) {
|
|
791
794
|
list.push(...term.conds);
|
|
792
|
-
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
const groups = positives.get(term.field);
|
|
798
|
+
if (!groups) {
|
|
799
|
+
positives.set(term.field, [term]);
|
|
800
|
+
list.push(...term.conds);
|
|
801
|
+
} else if (!groups.some((g) => sameConds(g.conds, term.conds))) groups.push(term);
|
|
802
|
+
}
|
|
803
|
+
const carried = [];
|
|
804
|
+
for (const [field, groups] of positives) {
|
|
805
|
+
if (groups.length < 2) continue;
|
|
806
|
+
const leftOut = opts.carry ? groups : groups.slice(1);
|
|
807
|
+
if (opts.carry) {
|
|
808
|
+
const kept = new Set(groups[0].conds);
|
|
809
|
+
const rest = filters[field].filter((c) => !kept.has(c));
|
|
810
|
+
if (rest.length > 0) filters[field] = rest;
|
|
811
|
+
else delete filters[field];
|
|
812
|
+
}
|
|
813
|
+
for (const term of leftOut) out.issues.push({
|
|
793
814
|
reason: "conjunction",
|
|
794
815
|
expr: term.expr,
|
|
795
|
-
fields: [
|
|
816
|
+
fields: [field]
|
|
796
817
|
});
|
|
797
818
|
}
|
|
798
|
-
for (const issue of out.issues)
|
|
799
|
-
|
|
819
|
+
for (const issue of out.issues) {
|
|
820
|
+
const fields = issue.fields;
|
|
821
|
+
if (fields.length > 0 && !fields.some(isKnown)) continue;
|
|
822
|
+
if (opts.carry && fields.length > 0 && fields.every(isKnown)) carried.push(issue.expr);
|
|
823
|
+
else result.unsupported.push(issue);
|
|
824
|
+
}
|
|
825
|
+
result.residual = normalizeResidualFilters(carried);
|
|
826
|
+
return result;
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Canonical identity of a filter expression — its `@uniqu/url` spelling.
|
|
830
|
+
* Two expressions with the same key select the same rows.
|
|
831
|
+
*
|
|
832
|
+
* @since 0.1.140
|
|
833
|
+
*/
|
|
834
|
+
function filterExprKey(expr) {
|
|
835
|
+
try {
|
|
836
|
+
return buildUrl({ filter: expr });
|
|
837
|
+
} catch {
|
|
838
|
+
return JSON.stringify(expr) ?? "";
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* A residual-condition list with empty expressions and duplicates (by
|
|
843
|
+
* {@link filterExprKey}) dropped, sorted by key. Sorted, not first-appearance:
|
|
844
|
+
* the URL parser moves \`$not\`-wrapped clauses (how \`mergeFilters\` spells
|
|
845
|
+
* a repeated same-field clause) ahead of plain ones, so appearance order would
|
|
846
|
+
* flip on every round trip.
|
|
847
|
+
*
|
|
848
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
849
|
+
*/
|
|
850
|
+
function normalizeResidualFilters(exprs) {
|
|
851
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
852
|
+
for (const expr of exprs) {
|
|
853
|
+
if (!isPlainObject(expr)) continue;
|
|
854
|
+
const key = filterExprKey(expr);
|
|
855
|
+
if (key && !byKey.has(key)) byKey.set(key, expr);
|
|
856
|
+
}
|
|
857
|
+
return [...byKey.keys()].toSorted().map((key) => byKey.get(key));
|
|
858
|
+
}
|
|
859
|
+
/**
|
|
860
|
+
* Convert a Uniquery `FilterExpr` back into the UI's `FieldFilters` shape.
|
|
861
|
+
*
|
|
862
|
+
* Inverse of `filtersToUniqueryFilter`, and exact for everything that encoder
|
|
863
|
+
* produces. For any other input, each AND-ed piece is either converted exactly
|
|
864
|
+
* or left out whole and reported — never approximated:
|
|
865
|
+
*
|
|
866
|
+
* - `$in` becomes equality conditions on the field, `$nin` inequality ones.
|
|
867
|
+
* - A same-field `$or` becomes that field's OR'd conditions.
|
|
868
|
+
* - A `$not` that inverts equality / emptiness becomes the inverse conditions.
|
|
869
|
+
* - Fields next to `$and` / `$or` / `$not` in one object are all kept.
|
|
870
|
+
* - Anything else (see {@link UnsupportedFilterReason}) is left out. Leaving
|
|
871
|
+
* an AND-ed piece out only ever widens the match, so the result selects a
|
|
872
|
+
* superset of `expr`. Each left-out piece goes to `onUnsupportedFilter`, or
|
|
873
|
+
* to a dev-mode `console.warn` when no handler is given. To keep those
|
|
874
|
+
* pieces instead, use {@link decomposeUniqueryFilter} with `carry`.
|
|
875
|
+
*
|
|
876
|
+
* Conditions on fields outside `knownFields` (when provided) are ignored
|
|
877
|
+
* silently: they are not this table's (a host page flag, a stale column). A
|
|
878
|
+
* piece that mixes known and unknown fields is reported.
|
|
879
|
+
*
|
|
880
|
+
* Returns `{}` for an empty/missing expression. Never throws.
|
|
881
|
+
*/
|
|
882
|
+
function uniqueryFilterToFieldFilters(expr, knownFields, onUnsupportedFilter = warnUnsupported) {
|
|
883
|
+
const { filters, unsupported } = decomposeUniqueryFilter(expr, { knownFields });
|
|
884
|
+
for (const issue of unsupported) onUnsupportedFilter(issue);
|
|
885
|
+
return filters;
|
|
886
|
+
}
|
|
887
|
+
//#endregion
|
|
888
|
+
//#region src/filters/format-filter-expr.ts
|
|
889
|
+
function show(v) {
|
|
890
|
+
if (v instanceof Date) return v.toISOString();
|
|
891
|
+
if (typeof v === "object" && v !== null) return JSON.stringify(v) ?? "";
|
|
892
|
+
return String(v);
|
|
893
|
+
}
|
|
894
|
+
/** One comparison, worded like the filter chips (the decoder's operator table). */
|
|
895
|
+
function leaf(label, op, value) {
|
|
896
|
+
if (op === "$eq" && value instanceof RegExp) op = "$regex";
|
|
897
|
+
if ((op === "$in" || op === "$nin") && Array.isArray(value)) return `${label} ${op === "$in" ? "is one of" : "is none of"} ${value.map(show).join(", ")}`;
|
|
898
|
+
const conds = decodeOperator(op, value);
|
|
899
|
+
if (conds?.length === 1) return filterTokenLabel(label, conds, label);
|
|
900
|
+
return buildUrl({ filter: { [label]: { [op]: value } } }) || `${label}${op}`;
|
|
901
|
+
}
|
|
902
|
+
function join(children, kind) {
|
|
903
|
+
const parts = children.filter((c) => c.s);
|
|
904
|
+
if (parts.length === 0) return {
|
|
905
|
+
s: "",
|
|
906
|
+
kind: "leaf"
|
|
907
|
+
};
|
|
908
|
+
if (parts.length === 1) return parts[0];
|
|
909
|
+
const wrap = kind === "and" ? "or" : "and";
|
|
910
|
+
return {
|
|
911
|
+
s: parts.map((c) => c.kind === wrap ? `(${c.s})` : c.s).join(` ${kind} `),
|
|
912
|
+
kind
|
|
913
|
+
};
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Human-readable rendering of a Uniquery filter expression, worded like the
|
|
917
|
+
* filter-field chips: `(Status equals shipped and Total greater than 500) or
|
|
918
|
+
* (Status equals pending and Total less or equal 50)`. `and` binds tighter
|
|
919
|
+
* than `or`; groups are parenthesized only where needed. Operators without a
|
|
920
|
+
* wording fall back to their `@uniqu/url` spelling.
|
|
921
|
+
*
|
|
922
|
+
* @param labelOf — display label for a field path (e.g. the column label);
|
|
923
|
+
* the path itself when omitted or when it returns `undefined`.
|
|
924
|
+
* @since 0.1.140
|
|
925
|
+
*/
|
|
926
|
+
function formatFilterExpr(expr, labelOf) {
|
|
927
|
+
const visitor = {
|
|
928
|
+
comparison: (field, op, value) => ({
|
|
929
|
+
s: leaf(labelOf?.(field) ?? field, op, value),
|
|
930
|
+
kind: "leaf"
|
|
931
|
+
}),
|
|
932
|
+
and: (children) => join(children, "and"),
|
|
933
|
+
or: (children) => join(children, "or"),
|
|
934
|
+
not: (child) => ({
|
|
935
|
+
s: child.s ? `not (${child.s})` : "",
|
|
936
|
+
kind: "leaf"
|
|
937
|
+
})
|
|
938
|
+
};
|
|
939
|
+
try {
|
|
940
|
+
return walkFilter(expr, visitor)?.s ?? "";
|
|
941
|
+
} catch {
|
|
942
|
+
return JSON.stringify(expr) ?? "";
|
|
943
|
+
}
|
|
800
944
|
}
|
|
801
945
|
//#endregion
|
|
802
946
|
//#region src/filters/date-shortcuts.ts
|
|
@@ -1393,8 +1537,9 @@ function mergeSorters(forceSorters, userSorters) {
|
|
|
1393
1537
|
//#endregion
|
|
1394
1538
|
//#region src/query/merge-filters.ts
|
|
1395
1539
|
/**
|
|
1396
|
-
* AND-merge
|
|
1397
|
-
* `@uniqu/url`'s `mergeConjunction` parser collapse.
|
|
1540
|
+
* AND-merge filter expressions (`undefined` ones skipped), producing a wire
|
|
1541
|
+
* shape that survives `@uniqu/url`'s `mergeConjunction` parser collapse.
|
|
1542
|
+
* Variadic since 0.1.140.
|
|
1398
1543
|
*
|
|
1399
1544
|
* The collapse problem: when two `$and` siblings target the same field
|
|
1400
1545
|
* with the same op (e.g. `{status: 'cancelled'}` AND `{status: 'shipped'}`),
|
|
@@ -1407,10 +1552,10 @@ function mergeSorters(forceSorters, userSorters) {
|
|
|
1407
1552
|
* and `!!p ≡ p` is a semantic identity, so the server evaluator sees the
|
|
1408
1553
|
* same AND. Non-colliding merges produce the canonical `$and` shape.
|
|
1409
1554
|
*/
|
|
1410
|
-
function mergeFilters(
|
|
1411
|
-
|
|
1412
|
-
if (
|
|
1413
|
-
return makeParserSafeAnd(
|
|
1555
|
+
function mergeFilters(...exprs) {
|
|
1556
|
+
const list = exprs.filter((e) => !!e);
|
|
1557
|
+
if (list.length <= 1) return list[0];
|
|
1558
|
+
return makeParserSafeAnd(list);
|
|
1414
1559
|
}
|
|
1415
1560
|
/** Op-set for a field value: primitives are `$eq`, op-bags expose their keys. */
|
|
1416
1561
|
function getOpsForFieldValue(value) {
|
|
@@ -1478,12 +1623,12 @@ function makeParserSafeAnd(children) {
|
|
|
1478
1623
|
* Build a Uniquery object from table UI state.
|
|
1479
1624
|
*
|
|
1480
1625
|
* Pure function — no framework dependencies.
|
|
1481
|
-
* Combines user filters
|
|
1626
|
+
* Combines user filters (field filters, then residual conditions) with force
|
|
1627
|
+
* filters, merges sorters,
|
|
1482
1628
|
* projects visible columns, and applies pagination.
|
|
1483
1629
|
*/
|
|
1484
1630
|
function buildTableQuery(opts) {
|
|
1485
|
-
const
|
|
1486
|
-
const filter = mergeFilters(opts.forceFilters, userFilter);
|
|
1631
|
+
const filter = mergeFilters(opts.forceFilters, filtersToUniqueryFilter(opts.filters), ...opts.residualFilters ?? []);
|
|
1487
1632
|
const userSorters = opts.ignoreSorters ? [] : opts.sorters;
|
|
1488
1633
|
const sorters = opts.forceSorters?.length ? mergeSorters(opts.forceSorters, userSorters) : userSorters;
|
|
1489
1634
|
const $sort = {};
|
|
@@ -1543,6 +1688,17 @@ function gateOwns(gate, path) {
|
|
|
1543
1688
|
if (gate === "none") return false;
|
|
1544
1689
|
return gate.has(path);
|
|
1545
1690
|
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Does a URL under `gate` own the residual condition `expr`? Only when it
|
|
1693
|
+
* owns every field the condition references — a condition that touches a
|
|
1694
|
+
* private field stays private as a whole.
|
|
1695
|
+
*
|
|
1696
|
+
* @internal Exported for `@atscript/vue-table`.
|
|
1697
|
+
*/
|
|
1698
|
+
function residualGateOwns(gate, expr) {
|
|
1699
|
+
const fields = filterExprFields(expr);
|
|
1700
|
+
return fields.length > 0 && fields.every((path) => gateOwns(gate, path));
|
|
1701
|
+
}
|
|
1546
1702
|
function pickFilterPaths(filters, gate) {
|
|
1547
1703
|
const out = {};
|
|
1548
1704
|
for (const path in filters) if (gateOwns(gate, path)) out[path] = filters[path];
|
|
@@ -1569,6 +1725,7 @@ function stateToUrlQueryString(state, defaults) {
|
|
|
1569
1725
|
visibleColumnPaths: [],
|
|
1570
1726
|
sorters: sortersGate === "all" ? state.sorters : state.sorters.filter((s) => gateOwns(sortersGate, s.field)),
|
|
1571
1727
|
filters,
|
|
1728
|
+
residualFilters: defaults.sync?.residual === false || !state.residualFilters?.length ? void 0 : state.residualFilters.filter((expr) => residualGateOwns(filtersGate, expr)),
|
|
1572
1729
|
search: searchOff ? void 0 : state.searchTerm || void 0
|
|
1573
1730
|
});
|
|
1574
1731
|
if (!searchOff && state.searchTerm && state.ignoreSorters !== void 0 && state.ignoreSorters !== (defaults.defaultIgnoreSorters ?? false)) query.controls.$relevance = state.ignoreSorters ? 1 : 0;
|
|
@@ -1591,8 +1748,11 @@ const CONSUMED_CONTROLS = new Set([
|
|
|
1591
1748
|
"$skip",
|
|
1592
1749
|
URL_SNAPSHOT_KEY
|
|
1593
1750
|
]);
|
|
1594
|
-
/**
|
|
1595
|
-
|
|
1751
|
+
/**
|
|
1752
|
+
* Characters that can only appear in a uniqu filter key, never in a page flag:
|
|
1753
|
+
* comparison operators, `^` (OR), `( )` (groups) and `{ }` (`$in` lists).
|
|
1754
|
+
*/
|
|
1755
|
+
const FILTER_OPERATOR_CHAR = /[<>!~()^{}]/;
|
|
1596
1756
|
/**
|
|
1597
1757
|
* Whether {@link urlQueryStringToState} would consume the query key `key` —
|
|
1598
1758
|
* i.e. whether the key belongs to the table rather than to the page hosting
|
|
@@ -1619,7 +1779,9 @@ function urlQueryConsumesKey(key) {
|
|
|
1619
1779
|
* - unknown fields (not in `knownFields`) → silently dropped
|
|
1620
1780
|
* - filter pieces field filters cannot express (cross-field OR, unknown
|
|
1621
1781
|
* operator, …) → left out of `filters` and listed in `unsupported`, never
|
|
1622
|
-
* approximated (the parser does not warn — the caller decides)
|
|
1782
|
+
* approximated (the parser does not warn — the caller decides). Unless
|
|
1783
|
+
* `sync.residual` is `false`, those whose fields are all known come back
|
|
1784
|
+
* in `residual` instead
|
|
1623
1785
|
* - unknown controls (e.g. `$weird=42`) → silently ignored
|
|
1624
1786
|
* - malformed query → `{ filters: {}, sorters: [], searchTerm: "" }`
|
|
1625
1787
|
*
|
|
@@ -1654,8 +1816,11 @@ function urlQueryStringToState(urlString, opts = {}) {
|
|
|
1654
1816
|
filterKnown = /* @__PURE__ */ new Set();
|
|
1655
1817
|
for (const path of filtersGate) if (knownSet.has(path)) filterKnown.add(path);
|
|
1656
1818
|
} else filterKnown = filtersGate;
|
|
1657
|
-
const
|
|
1658
|
-
|
|
1819
|
+
const decomposed = filtersGate === "none" ? null : decomposeUniqueryFilter(parsed.filter, {
|
|
1820
|
+
knownFields: filterKnown,
|
|
1821
|
+
carry: opts.sync?.residual !== false
|
|
1822
|
+
});
|
|
1823
|
+
const filters = decomposed?.filters ?? {};
|
|
1659
1824
|
const sorters = [];
|
|
1660
1825
|
if (sortersGate !== "none") {
|
|
1661
1826
|
const $sort = parsed.controls?.$sort;
|
|
@@ -1679,7 +1844,8 @@ function urlQueryStringToState(urlString, opts = {}) {
|
|
|
1679
1844
|
sorters,
|
|
1680
1845
|
searchTerm: !searchOff && typeof $search === "string" ? $search : ""
|
|
1681
1846
|
};
|
|
1682
|
-
if (unsupported.length
|
|
1847
|
+
if (decomposed?.unsupported.length) out.unsupported = decomposed.unsupported;
|
|
1848
|
+
if (decomposed?.residual.length) out.residual = decomposed.residual;
|
|
1683
1849
|
if (opts.sync?.snapshot !== false && parsed.controls && "$snapshot" in parsed.controls) out.snapshot = true;
|
|
1684
1850
|
if (!searchOff) {
|
|
1685
1851
|
const $relevance = parsed.controls?.$relevance;
|
|
@@ -2231,4 +2397,4 @@ function sortRowsLocally(rows, sorters, getValue = (row, field) => row[field]) {
|
|
|
2231
2397
|
});
|
|
2232
2398
|
}
|
|
2233
2399
|
//#endregion
|
|
2234
|
-
export { APP_CONF_PREFIX, AppPrefsClient, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DEV, DRAFT_PERSISTED_ASPECTS, ExportAbortError, MAX_DEFAULT_COLUMN_WIDTH_PX, NULL_OPS, PRESET_ASPECTS, PresetsClient, PresetsHttpError, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, pageAlignedBlocksFor, parseColumnFilterInput, 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 };
|
|
2400
|
+
export { APP_CONF_PREFIX, AppPrefsClient, DEFAULT_EXPORT_PAGE_SIZE, DEFAULT_ROW_HEIGHT_PX, DEV, DRAFT_PERSISTED_ASPECTS, ExportAbortError, MAX_DEFAULT_COLUMN_WIDTH_PX, NULL_OPS, PRESET_ASPECTS, PresetsClient, PresetsHttpError, RESERVED_ID_PREFIXES, STANDARD_PRESET_ID, SYSTEM_PRESET_PREFIX, URL_SNAPSHOT_KEY, USER_CONF_PREFIX, appConfId, arraysEqual, blockStartFor, buildTableQuery, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, computeDefaultColumnWidth, conditionLabel, conditionsForType, csvCell, dateShortcuts, debounce, decomposeUniqueryFilter, defaultCondition, derivePresetAspects, deserializeDraft, draftMatchesPreset, escapeRegex, filledFilterCount, filterExprFields, filterExprKey, filterTokenLabel, filtersToUniqueryFilter, formatFilterCondition, formatFilterExpr, fromWireSnapshot, gateOwns, hasSecondValue, isAuthError, isColumnFilterable, isDirtyAgainst, isEmptyDraft, isFilled, isSimpleEq, isSystemPresetId, isUnavailableError, mergeDisplayColumns, mergeFilters, mergeSorters, normaliseSystemPresetId, normalizeResidualFilters, pageAlignedBlocksFor, parseColumnFilterInput, parseFilterInput, planFetch, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
|