@atscript/ui-table 0.1.141 → 0.1.142

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 CHANGED
@@ -46,6 +46,19 @@ function filledFilterCount(filters) {
46
46
  for (const path in filters) if (filters[path].some(isFilled)) count++;
47
47
  return count;
48
48
  }
49
+ /**
50
+ * `filters` without the fields that have no filled condition — the shape
51
+ * table state holds (a field with nothing filled has no entry). Returns
52
+ * `filters` itself when every field has one; never mutates it.
53
+ *
54
+ * @since 0.1.142
55
+ */
56
+ function compactFieldFilters(filters) {
57
+ if (filledFilterCount(filters) === Object.keys(filters).length) return filters;
58
+ const out = {};
59
+ for (const path in filters) if (filters[path].some(isFilled)) out[path] = filters[path];
60
+ return out;
61
+ }
49
62
  /** Summarize a field's conditions into a human-readable token label. */
50
63
  function filterTokenLabel(path, conditions, columnLabel) {
51
64
  const filled = conditions.filter(isFilled);
@@ -1228,6 +1241,45 @@ function prunePresetSnapshot(snapshot, known) {
1228
1241
  };
1229
1242
  }
1230
1243
  /**
1244
+ * Spell a snapshot the way table state holds it, so it compares equal to a
1245
+ * capture of the state it produces:
1246
+ *
1247
+ * - `columns.columnWidths` — an entry equal to its column's default width, or
1248
+ * on a path with no default (not a column), goes; an emptied map is
1249
+ * omitted. Capture writes overrides only.
1250
+ * - `filterOps` — a field with no filled condition goes
1251
+ * (`compactFieldFilters`). Table state never holds one.
1252
+ *
1253
+ * `defaultWidths` maps each column path to its default width — the `d` of
1254
+ * its `ColumnWidthsMap` entry. Other aspects pass through. Returns `snapshot`
1255
+ * itself when nothing changes; the input is never mutated.
1256
+ *
1257
+ * @since 0.1.142
1258
+ */
1259
+ function canonicalPresetSnapshot(snapshot, defaultWidths) {
1260
+ let out = snapshot;
1261
+ const columns = snapshot.columns;
1262
+ if (columns?.columnWidths) {
1263
+ const entries = Object.entries(columns.columnWidths);
1264
+ const [kept] = partition(entries, ([p, w]) => {
1265
+ const d = defaultWidths[p];
1266
+ return d !== void 0 && d !== w;
1267
+ });
1268
+ if (kept.length !== entries.length || kept.length === 0) out = {
1269
+ ...out,
1270
+ columns: columnsAspect(columns.columnNames, Object.fromEntries(kept))
1271
+ };
1272
+ }
1273
+ if (snapshot.filterOps) {
1274
+ const filterOps = compactFieldFilters(snapshot.filterOps);
1275
+ if (filterOps !== snapshot.filterOps) out = {
1276
+ ...out,
1277
+ filterOps
1278
+ };
1279
+ }
1280
+ return out;
1281
+ }
1282
+ /**
1231
1283
  * Split residual filter conditions, in one pass, into the ones that name
1232
1284
  * only `known` fields and the ones that do not. A condition naming any
1233
1285
  * unknown field is dropped WHOLE — never pruned inside an `$or` (that would
@@ -2595,12 +2647,14 @@ exports.appConfId = appConfId;
2595
2647
  exports.arraysEqual = arraysEqual;
2596
2648
  exports.blockStartFor = blockStartFor;
2597
2649
  exports.buildTableQuery = buildTableQuery;
2650
+ exports.canonicalPresetSnapshot = canonicalPresetSnapshot;
2598
2651
  exports.cellAsString = cellAsString;
2599
2652
  exports.clampTopIndex = clampTopIndex;
2600
2653
  exports.collectExportRows = collectExportRows;
2601
2654
  exports.columnDefaultCondition = columnDefaultCondition;
2602
2655
  exports.columnFilterConditions = columnFilterConditions;
2603
2656
  exports.columnFilterType = columnFilterType;
2657
+ exports.compactFieldFilters = compactFieldFilters;
2604
2658
  exports.computeDefaultColumnWidth = computeDefaultColumnWidth;
2605
2659
  exports.conditionLabel = conditionLabel;
2606
2660
  exports.conditionsForType = conditionsForType;
package/dist/index.d.cts CHANGED
@@ -31,6 +31,14 @@ declare function isSimpleEq(condition: FilterCondition): boolean;
31
31
  declare function conditionLabel(type: FilterConditionType): string;
32
32
  /** Count of fields that have at least one filled condition. */
33
33
  declare function filledFilterCount(filters: FieldFilters): number;
34
+ /**
35
+ * `filters` without the fields that have no filled condition — the shape
36
+ * table state holds (a field with nothing filled has no entry). Returns
37
+ * `filters` itself when every field has one; never mutates it.
38
+ *
39
+ * @since 0.1.142
40
+ */
41
+ declare function compactFieldFilters(filters: FieldFilters): FieldFilters;
34
42
  /** Summarize a field's conditions into a human-readable token label. */
35
43
  declare function filterTokenLabel(path: string, conditions: FilterCondition[], columnLabel?: string): string;
36
44
  //#endregion
@@ -615,6 +623,23 @@ declare function prunePresetSnapshot(snapshot: PresetSnapshot, known: KnownField
615
623
  snapshot: PresetSnapshot;
616
624
  dropped: DroppedFields | null;
617
625
  };
626
+ /**
627
+ * Spell a snapshot the way table state holds it, so it compares equal to a
628
+ * capture of the state it produces:
629
+ *
630
+ * - `columns.columnWidths` — an entry equal to its column's default width, or
631
+ * on a path with no default (not a column), goes; an emptied map is
632
+ * omitted. Capture writes overrides only.
633
+ * - `filterOps` — a field with no filled condition goes
634
+ * (`compactFieldFilters`). Table state never holds one.
635
+ *
636
+ * `defaultWidths` maps each column path to its default width — the `d` of
637
+ * its `ColumnWidthsMap` entry. Other aspects pass through. Returns `snapshot`
638
+ * itself when nothing changes; the input is never mutated.
639
+ *
640
+ * @since 0.1.142
641
+ */
642
+ declare function canonicalPresetSnapshot(snapshot: PresetSnapshot, defaultWidths: Readonly<Record<string, string>>): PresetSnapshot;
618
643
  /**
619
644
  * Split residual filter conditions, in one pass, into the ones that name
620
645
  * only `known` fields and the ones that do not. A condition naming any
@@ -1697,4 +1722,4 @@ declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], s
1697
1722
  //#region src/utils/dev.d.ts
1698
1723
  declare const DEV: boolean;
1699
1724
  //#endregion
1700
- 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, type DroppedFields, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, type KnownFields, 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 UnknownFilter, 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
1725
+ 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, type DroppedFields, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, type KnownFields, 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 UnknownFilter, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, canonicalPresetSnapshot, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, compactFieldFilters, 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, 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
@@ -31,6 +31,14 @@ declare function isSimpleEq(condition: FilterCondition): boolean;
31
31
  declare function conditionLabel(type: FilterConditionType): string;
32
32
  /** Count of fields that have at least one filled condition. */
33
33
  declare function filledFilterCount(filters: FieldFilters): number;
34
+ /**
35
+ * `filters` without the fields that have no filled condition — the shape
36
+ * table state holds (a field with nothing filled has no entry). Returns
37
+ * `filters` itself when every field has one; never mutates it.
38
+ *
39
+ * @since 0.1.142
40
+ */
41
+ declare function compactFieldFilters(filters: FieldFilters): FieldFilters;
34
42
  /** Summarize a field's conditions into a human-readable token label. */
35
43
  declare function filterTokenLabel(path: string, conditions: FilterCondition[], columnLabel?: string): string;
36
44
  //#endregion
@@ -615,6 +623,23 @@ declare function prunePresetSnapshot(snapshot: PresetSnapshot, known: KnownField
615
623
  snapshot: PresetSnapshot;
616
624
  dropped: DroppedFields | null;
617
625
  };
626
+ /**
627
+ * Spell a snapshot the way table state holds it, so it compares equal to a
628
+ * capture of the state it produces:
629
+ *
630
+ * - `columns.columnWidths` — an entry equal to its column's default width, or
631
+ * on a path with no default (not a column), goes; an emptied map is
632
+ * omitted. Capture writes overrides only.
633
+ * - `filterOps` — a field with no filled condition goes
634
+ * (`compactFieldFilters`). Table state never holds one.
635
+ *
636
+ * `defaultWidths` maps each column path to its default width — the `d` of
637
+ * its `ColumnWidthsMap` entry. Other aspects pass through. Returns `snapshot`
638
+ * itself when nothing changes; the input is never mutated.
639
+ *
640
+ * @since 0.1.142
641
+ */
642
+ declare function canonicalPresetSnapshot(snapshot: PresetSnapshot, defaultWidths: Readonly<Record<string, string>>): PresetSnapshot;
618
643
  /**
619
644
  * Split residual filter conditions, in one pass, into the ones that name
620
645
  * only `known` fields and the ones that do not. A condition naming any
@@ -1697,4 +1722,4 @@ declare function sortRowsLocally<T extends Record<string, unknown>>(rows: T[], s
1697
1722
  //#region src/utils/dev.d.ts
1698
1723
  declare const DEV: boolean;
1699
1724
  //#endregion
1700
- 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, type DroppedFields, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, type KnownFields, 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 UnknownFilter, 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
1725
+ 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, type DroppedFields, ExportAbortError, type ExportPage, type ExportPageFetcher, type ExportScalar, type FetchPlan, type FetchPlanMode, type FieldFilters, type FilterCondition, type FilterConditionType, type FilterableColumn, type KnownFields, 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 UnknownFilter, type UnsupportedFilter, type UnsupportedFilterReason, type UrlQueryDefaults, type UrlQueryParseOptions, type UrlQueryStateLike, type UrlQueryStateSnapshot, type UrlQuerySync, type UserConfData, appConfId, arraysEqual, blockStartFor, buildTableQuery, canonicalPresetSnapshot, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, compactFieldFilters, 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, 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
@@ -45,6 +45,19 @@ function filledFilterCount(filters) {
45
45
  for (const path in filters) if (filters[path].some(isFilled)) count++;
46
46
  return count;
47
47
  }
48
+ /**
49
+ * `filters` without the fields that have no filled condition — the shape
50
+ * table state holds (a field with nothing filled has no entry). Returns
51
+ * `filters` itself when every field has one; never mutates it.
52
+ *
53
+ * @since 0.1.142
54
+ */
55
+ function compactFieldFilters(filters) {
56
+ if (filledFilterCount(filters) === Object.keys(filters).length) return filters;
57
+ const out = {};
58
+ for (const path in filters) if (filters[path].some(isFilled)) out[path] = filters[path];
59
+ return out;
60
+ }
48
61
  /** Summarize a field's conditions into a human-readable token label. */
49
62
  function filterTokenLabel(path, conditions, columnLabel) {
50
63
  const filled = conditions.filter(isFilled);
@@ -1227,6 +1240,45 @@ function prunePresetSnapshot(snapshot, known) {
1227
1240
  };
1228
1241
  }
1229
1242
  /**
1243
+ * Spell a snapshot the way table state holds it, so it compares equal to a
1244
+ * capture of the state it produces:
1245
+ *
1246
+ * - `columns.columnWidths` — an entry equal to its column's default width, or
1247
+ * on a path with no default (not a column), goes; an emptied map is
1248
+ * omitted. Capture writes overrides only.
1249
+ * - `filterOps` — a field with no filled condition goes
1250
+ * (`compactFieldFilters`). Table state never holds one.
1251
+ *
1252
+ * `defaultWidths` maps each column path to its default width — the `d` of
1253
+ * its `ColumnWidthsMap` entry. Other aspects pass through. Returns `snapshot`
1254
+ * itself when nothing changes; the input is never mutated.
1255
+ *
1256
+ * @since 0.1.142
1257
+ */
1258
+ function canonicalPresetSnapshot(snapshot, defaultWidths) {
1259
+ let out = snapshot;
1260
+ const columns = snapshot.columns;
1261
+ if (columns?.columnWidths) {
1262
+ const entries = Object.entries(columns.columnWidths);
1263
+ const [kept] = partition(entries, ([p, w]) => {
1264
+ const d = defaultWidths[p];
1265
+ return d !== void 0 && d !== w;
1266
+ });
1267
+ if (kept.length !== entries.length || kept.length === 0) out = {
1268
+ ...out,
1269
+ columns: columnsAspect(columns.columnNames, Object.fromEntries(kept))
1270
+ };
1271
+ }
1272
+ if (snapshot.filterOps) {
1273
+ const filterOps = compactFieldFilters(snapshot.filterOps);
1274
+ if (filterOps !== snapshot.filterOps) out = {
1275
+ ...out,
1276
+ filterOps
1277
+ };
1278
+ }
1279
+ return out;
1280
+ }
1281
+ /**
1230
1282
  * Split residual filter conditions, in one pass, into the ones that name
1231
1283
  * only `known` fields and the ones that do not. A condition naming any
1232
1284
  * unknown field is dropped WHOLE — never pruned inside an `$or` (that would
@@ -2573,4 +2625,4 @@ function sortRowsLocally(rows, sorters, getValue = (row, field) => row[field]) {
2573
2625
  });
2574
2626
  }
2575
2627
  //#endregion
2576
- 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
2628
+ 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, canonicalPresetSnapshot, cellAsString, clampTopIndex, collectExportRows, columnDefaultCondition, columnFilterConditions, columnFilterType, compactFieldFilters, 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, prunePresetSnapshot, pruneResidualFilters, reconcileColumnWidthDefaults, reorderColumnNames, residualGateOwns, resolveAspectGate, resolveExportValue, resolveSystemPresets, restoreDroppedEntries, rowsToPks, sameColumnSet, serializeDraft, setsEqual, sortRowsLocally, sortersEqual, stableStringify, stateToUrlQueryString, toCsv, toWireSnapshot, togglePk, trimSelection, unescapeRegex, uniqueryFilterToFieldFilters, urlQueryConsumesKey, urlQueryStringToState, userConfId, walkBackwardAbsorb, walkForwardAbsorb, withStableOrder };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/ui-table",
3
- "version": "0.1.141",
3
+ "version": "0.1.142",
4
4
  "description": "Framework-agnostic filter model, filter-to-Uniquery conversion, and preset serialization for atscript tables",
5
5
  "keywords": [
6
6
  "atscript",
@@ -42,18 +42,18 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "@atscript/ui": "0.1.141"
45
+ "@atscript/ui": "0.1.142"
46
46
  },
47
47
  "devDependencies": {
48
- "@atscript/db-client": "^0.1.133",
49
- "@uniqu/core": "^0.1.10",
50
- "@uniqu/url": "^0.1.10",
48
+ "@atscript/db-client": "^0.1.136",
49
+ "@uniqu/core": "^0.1.11",
50
+ "@uniqu/url": "^0.1.11",
51
51
  "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.14"
52
52
  },
53
53
  "peerDependencies": {
54
- "@atscript/db-client": "^0.1.133",
55
- "@uniqu/core": "^0.1.10",
56
- "@uniqu/url": "^0.1.10"
54
+ "@atscript/db-client": "^0.1.136",
55
+ "@uniqu/core": "^0.1.11",
56
+ "@uniqu/url": "^0.1.11"
57
57
  },
58
58
  "scripts": {
59
59
  "build": "vp pack",