@updog/data-editor 0.1.85 → 0.1.86

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.
@@ -1,6 +1,6 @@
1
1
  import { detect as e } from "chardet";
2
2
  //#region src/core/encoding/cleanCell.ts
3
- var t = /[\u200B-\u200D\uFEFF\u2060]/g, n = /[\u00A0\u202F]/g, r = (e) => e.replace(t, "").replace(n, " ").normalize("NFC").trim(), i = (e) => e.length >= 4 && e[0] === 255 && e[1] === 254 && e[2] === 0 && e[3] === 0 ? {
3
+ var t = /[\u200B-\u200F\uFEFF\u2060]/g, n = /[\u00A0\u202F]/g, r = (e) => e.replace(t, "").replace(n, " ").normalize("NFC").trim(), i = (e) => e.length >= 4 && e[0] === 255 && e[1] === 254 && e[2] === 0 && e[3] === 0 ? {
4
4
  encoding: "utf-32le",
5
5
  bomLength: 4
6
6
  } : e.length >= 3 && e[0] === 239 && e[1] === 187 && e[2] === 191 ? {
package/index.d.ts CHANGED
@@ -575,6 +575,58 @@ declare var export_default = {
575
575
 
576
576
  type PluralSuffixes = "_zero" | "_one" | "_two" | "_few" | "_many" | "_other";
577
577
 
578
+ /**
579
+ * Strips plural suffixes from a key to get the base form.
580
+ * e.g. "createRows_one" → "createRows", "createRows_other" → "createRows"
581
+ */
582
+ type StripPluralSuffix<K extends string> =
583
+ K extends `${infer Base}${PluralSuffixes}` ? Base : K;
584
+
585
+ /**
586
+ * Recursively derives dot-separated keys from a nested object type.
587
+ * - Plural keys (e.g. `createRows_one`, `createRows_other`) are collapsed to their base (`createRows`).
588
+ * - `Record<string, string>` leaf nodes (like `calendar.months`) are treated as terminal.
589
+ */
590
+ type NestedKeyOf<T, Prefix extends string = ""> =
591
+ T extends Record<string, unknown>
592
+ ? string extends keyof T
593
+ ? Prefix extends ""
594
+ ? never
595
+ : Prefix
596
+ : {
597
+ [K in keyof T & string]: T[K] extends Record<string, unknown>
598
+ ? string extends keyof T[K]
599
+ ?
600
+ | (Prefix extends ""
601
+ ? StripPluralSuffix<K>
602
+ : `${Prefix}.${StripPluralSuffix<K>}`)
603
+ | NestedKeyOf<
604
+ T[K],
605
+ Prefix extends ""
606
+ ? StripPluralSuffix<K>
607
+ : `${Prefix}.${StripPluralSuffix<K>}`
608
+ >
609
+ : NestedKeyOf<
610
+ T[K],
611
+ Prefix extends ""
612
+ ? StripPluralSuffix<K>
613
+ : `${Prefix}.${StripPluralSuffix<K>}`
614
+ >
615
+ : Prefix extends ""
616
+ ? StripPluralSuffix<K>
617
+ : `${Prefix}.${StripPluralSuffix<K>}`;
618
+ }[keyof T & string]
619
+ : never;
620
+
621
+ /** Union of all valid translation keys derived from the English locale. */
622
+ type TranslationKeys = NestedKeyOf<typeof export_default>;
623
+
624
+ /** Typed translation function. Accepts typed keys with autocomplete, and dynamic strings as fallback. */
625
+ type TFunction = (
626
+ key: TranslationKeys | (string & {}),
627
+ options?: Record<string, unknown>,
628
+ ) => string;
629
+
578
630
  /** Makes all properties optional recursively. */
579
631
  type DeepPartial<T> = {
580
632
  [P in keyof T]?: T[P] extends Record<string, unknown>
@@ -806,8 +858,21 @@ type DataEditorColumn = {
806
858
  /** Format the display value without changing stored data. E.g. add `$` prefix. */
807
859
  formatter?: (value: string) => string;
808
860
  /**
809
- * Transform a value before it enters the store. Runs when rows are uploaded
810
- * to the data editor.
861
+ * Transform a value on its way into the store. Runs on every value arriving
862
+ * from outside the editor, so `loadData`, a file import, a remote source, a
863
+ * custom format, and a paste of text from another app all call it. A value
864
+ * moving inside the grid is left alone, so a manual edit, a fill, a paste of
865
+ * cells copied from the grid itself, undo, and redo never call it.
866
+ *
867
+ * The value arrives in the shape the cell is stored in. Numbers and dates
868
+ * canonicalize first, and a `select` value resolves through value matching
869
+ * first, so the transformer sees the option the user confirmed. On a
870
+ * `multiselect` column it runs once per token, the way `formatter` already
871
+ * reads that column. A token it empties leaves the list, and two tokens it
872
+ * makes equal collapse into one.
873
+ *
874
+ * It runs before validation, so a transformer that moves a value outside
875
+ * `editor.options` makes its own column fail a `oneOf` rule.
811
876
  */
812
877
  transformer?: (value: unknown) => unknown;
813
878
  /** How the cell is edited. Defaults to text input. */
@@ -1140,6 +1205,54 @@ declare class ErrorHandler {
1140
1205
  handleError(error: UpdogError): void;
1141
1206
  }
1142
1207
 
1208
+ /**
1209
+ * The parts of a column every cell type reads. Both `DataEditorColumn` and
1210
+ * `NormalizedColumn` satisfy it, so core and the UI pass the column they hold.
1211
+ */
1212
+ type TypedColumn = Pick<DataEditorColumn, "id" | "editor" | "formatter">;
1213
+ type ColumnFormat = {
1214
+ readonly typeId: string;
1215
+ readonly candidateId: string;
1216
+ };
1217
+
1218
+ type FormatScope = string;
1219
+ type FormatField = {
1220
+ key: string;
1221
+ column: TypedColumn;
1222
+ };
1223
+ type AmbiguousColumn = {
1224
+ field: string;
1225
+ applied: ColumnFormat;
1226
+ candidates: readonly ColumnFormat[];
1227
+ samples: readonly string[];
1228
+ };
1229
+ type FormatBatch = {
1230
+ reader(key: string): (value: unknown) => unknown;
1231
+ ambiguous: readonly AmbiguousColumn[];
1232
+ };
1233
+ /**
1234
+ * The one door every reading of raw text goes through. The verdict lives on
1235
+ * the pair of scope and column, so a column is never read by its neighbour's
1236
+ * verdict and a neighbouring source starts its own vote.
1237
+ *
1238
+ * The locale fallback needs no branch of its own: a tie falls to the first
1239
+ * candidate in declared order, and the lists are ordered so the reader's own
1240
+ * locale sits first among its peers.
1241
+ */
1242
+ declare class FormatGate {
1243
+ private deps;
1244
+ private memory;
1245
+ constructor(deps: {
1246
+ columns: () => readonly TypedColumn[];
1247
+ i18n: () => {
1248
+ locale: string;
1249
+ t: TFunction;
1250
+ } | null;
1251
+ });
1252
+ prepare(scope: FormatScope, rows: readonly Record<string, unknown>[], fields?: readonly FormatField[]): FormatBatch;
1253
+ forget(scope?: FormatScope): void;
1254
+ }
1255
+
1143
1256
  type FormulaCellContext = {
1144
1257
  value: unknown;
1145
1258
  field: string;
@@ -1848,6 +1961,8 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
1848
1961
  readonly formulaRegistry: FormulaRegistry;
1849
1962
  private _isLoading;
1850
1963
  private sourceManager;
1964
+ /** The format verdict of every source and column pair that has one. */
1965
+ readonly formats: FormatGate;
1851
1966
  readonly sourceLifecycle: SourceLifecycle<TRow>;
1852
1967
  private dirtyTracker;
1853
1968
  private filterEngine;
@@ -1887,10 +2002,15 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
1887
2002
  private filterRowReader;
1888
2003
  private bulkMutationHost;
1889
2004
  private orchestrator;
2005
+ private i18n;
1890
2006
  constructor(errorHandler?: ErrorHandler);
1891
2007
  getRowId(index: number): TRowId | undefined;
1892
2008
  getLocalRowCount(): number;
1893
2009
  setValidator(validator: IValidator<TRow>): void;
2010
+ setI18n(i18n: {
2011
+ t: TFunction;
2012
+ locale: string;
2013
+ }): void;
1894
2014
  isColumnLocked(field: string): boolean;
1895
2015
  isColumnPreLocked(field: string): boolean;
1896
2016
  lockColumn(field: string, mode?: ColumnLockMode): void;
@@ -2006,9 +2126,50 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
2006
2126
  * has already normalised through buildImportRow — never transforms twice.
2007
2127
  */
2008
2128
  appendClientRows(sourceId: DataSourceId, newRows: TRow[]): TRowId[];
2129
+ private formatContext;
2130
+ /**
2131
+ * A column nothing separated is a signal to whoever integrated the SDK, so
2132
+ * it goes out in English through `onError` rather than to the person at the
2133
+ * screen. The wizard could ask which shape instead; the seam is here and
2134
+ * the dialog is out of scope (spec section 10).
2135
+ */
2136
+ private reportAmbiguity;
2137
+ /**
2138
+ * The column's reader with no verdict behind it. A formula result is one
2139
+ * value, so there is nothing to vote on; the reader is here to give the
2140
+ * column's storage shape, which for a number means digits rather than an
2141
+ * exponent or a JS number.
2142
+ */
2143
+ private fieldReader;
2144
+ /**
2145
+ * The column's own reader over values an assistant produced. There is no
2146
+ * column of file text to vote on here, so the reader runs without a verdict,
2147
+ * the same way a formula result is read: it gives the value the shape its
2148
+ * column stores rather than a JS number or an exponent. A value that reads
2149
+ * back onto what the cell already holds leaves the delta, so an untouched
2150
+ * cell stays untouched.
2151
+ */
2152
+ private readChatDeltas;
2009
2153
  private normalizeClientRows;
2010
2154
  appendRows(sourceId: DataSourceId, newRows: TRow[], rowIdMap?: Map<number, TRowId>): TRowId[];
2011
- seedInitialChanges(assignedRowIds: TRowId[], currentRows: TRow[], changes: InitialRowChange<TRow>[]): void;
2155
+ /**
2156
+ * The declared transformers, resolved once so a per-row loop never rescans
2157
+ * the column list.
2158
+ */
2159
+ private collectTransformers;
2160
+ /**
2161
+ * Runs the column transformers over a partial row the client states as a
2162
+ * baseline, so it is compared against the stored row in the same shape the
2163
+ * stored row was written in.
2164
+ */
2165
+ private transformClientValues;
2166
+ /**
2167
+ * Reads a stated original the way the row itself was read, then transforms
2168
+ * it. The verdict is already in the gate's memory from the append that put
2169
+ * these rows in, so an empty batch reuses it rather than voting again.
2170
+ */
2171
+ private normalizeClientValues;
2172
+ seedInitialChanges(sourceId: DataSourceId, assignedRowIds: TRowId[], currentRows: TRow[], changes: InitialRowChange<TRow>[]): void;
2012
2173
  upsertRows(sourceId: DataSourceId, newRows: TRow[], options?: UpsertOptions): UpsertResult<TRow>;
2013
2174
  private getAnchorMap;
2014
2175
  private clearAnchorMapCache;