@updog/data-editor 0.1.28 → 0.1.29

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.
Files changed (3) hide show
  1. package/index.d.ts +32 -6
  2. package/index.js +17 -3
  3. package/package.json +1 -1
package/index.d.ts CHANGED
@@ -2396,6 +2396,7 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
2396
2396
  */
2397
2397
  insertRowServer(row: TRow, localPosition: number, anchorRowId: TRowId | undefined, insertPosition: 'above' | 'below', columnIds: string[]): Promise<TRowId>;
2398
2398
  appendRows(sourceId: DataSourceId, newRows: TRow[], rowIdMap?: Map<number, TRowId>): TRowId[];
2399
+ seedInitialChanges(assignedRowIds: TRowId[], currentRows: TRow[], changes: InitialRowChange<TRow>[]): void;
2399
2400
  upsertRows(sourceId: DataSourceId, newRows: TRow[], options?: {
2400
2401
  anchorKey?: keyof TRow;
2401
2402
  newRowIds?: TRowId[];
@@ -2662,14 +2663,37 @@ type DataEditorResult<TRow extends DataEditorRow = DataEditorRow> = {
2662
2663
  invalid: number;
2663
2664
  };
2664
2665
  };
2666
+ /**
2667
+ * Describes the change state of a single row within a chunk, used to seed
2668
+ * the editor with a previously saved diff on load.
2669
+ *
2670
+ * The client passes current-state rows via `onChunk` and attaches change
2671
+ * descriptors to mark which rows were edited, added, or deleted in a
2672
+ * previous session. The SDK uses these to seed DirtyTracker so the diff
2673
+ * is visible from the first frame.
2674
+ */
2675
+ type InitialRowChange<TRow extends DataEditorRow = DataEditorRow> = {
2676
+ /** Index of this row within the chunk's rows array. */
2677
+ index: number;
2678
+ /**
2679
+ * Original field values before the user's edits.
2680
+ * Only include fields that differ from the current row.
2681
+ * Presence of this field marks the row as "edited".
2682
+ */
2683
+ originalValues?: Partial<TRow>;
2684
+ /** Marks this row as a new addition (not from backend). */
2685
+ isNew?: boolean;
2686
+ /** Marks this row as pending deletion. */
2687
+ isDeleted?: boolean;
2688
+ };
2665
2689
  /**
2666
2690
  * Options used to tag a chunk passed to `loadData`'s `onChunk` callback.
2667
- * Sources are auto-registered on first encounter. Chunks without options go
2668
- * to "Existing Data".
2691
+ * Sources are auto-registered on first encounter. Chunks without options
2692
+ * (or options without `source`) go to "Existing Data".
2669
2693
  */
2670
- type ChunkSourceOptions = {
2671
- /** Display name for this data source. Required when tagging a source. */
2672
- source: string;
2694
+ type ChunkSourceOptions<TRow extends DataEditorRow = DataEditorRow> = {
2695
+ /** Display name for this data source. When omitted, chunk goes to the default backend source. */
2696
+ source?: string;
2673
2697
  /** Stable identifier. Defaults to the `source` value when omitted. */
2674
2698
  id?: string;
2675
2699
  /** Whether the user can delete this source from the editor. @default false */
@@ -2681,6 +2705,8 @@ type ChunkSourceOptions = {
2681
2705
  * @default false
2682
2706
  */
2683
2707
  done?: boolean;
2708
+ /** Seed change state for specific rows in this chunk. Sparse: only rows that differ from backend. */
2709
+ changes?: InitialRowChange<TRow>[];
2684
2710
  };
2685
2711
  type DataSourceId = string;
2686
2712
  type DataSourceState = {
@@ -3130,4 +3156,4 @@ declare function exportDataEditor<TRow extends DataEditorRow>(params: ExportPara
3130
3156
  declare function DataEditor<TRow extends DataEditorRow = DataEditorRow>(allProps: DataEditorProps<TRow>): react_jsx_runtime.JSX.Element;
3131
3157
 
3132
3158
  export { DataEditor, downloadExampleFile, exportDataEditor };
3133
- export type { CellValidator, ChatContext, ChatErrorSummary, ChatResponseChunk, ChatRow, ChatRowStatus, ChunkSourceOptions, DataEditorChat, DataEditorColumn, DataEditorFormat, DataEditorInlineProps, DataEditorLocalStorage, DataEditorModalProps, DataEditorMode, DataEditorProps, DataEditorResult, DataEditorRow, DataEditorSourceResult, DataEditorTranslations, DataEditorVariant, RemoteSource, ResultRow, UpdogError, UpdogErrorCode, ValidationError, ValueMatchInput, ValueMatchOutput };
3159
+ export type { CellValidator, ChatContext, ChatErrorSummary, ChatResponseChunk, ChatRow, ChatRowStatus, ChunkSourceOptions, DataEditorChat, DataEditorColumn, DataEditorFormat, DataEditorInlineProps, DataEditorLocalStorage, DataEditorModalProps, DataEditorMode, DataEditorProps, DataEditorResult, DataEditorRow, DataEditorSourceResult, DataEditorTranslations, DataEditorVariant, InitialRowChange, RemoteSource, ResultRow, UpdogError, UpdogErrorCode, ValidationError, ValueMatchInput, ValueMatchOutput };
package/index.js CHANGED
@@ -6245,7 +6245,7 @@ function ec(e, t, n) {
6245
6245
  newValues: /* @__PURE__ */ new Map()
6246
6246
  });
6247
6247
  for (let i of n) {
6248
- if (e.isNew(i) || !e.isEdited(i)) continue;
6248
+ if (!e.isEdited(i)) continue;
6249
6249
  let n = e.getRowById(i);
6250
6250
  if (n) for (let a of t) {
6251
6251
  if (!e.isCellDirty(i, a)) continue;
@@ -7675,6 +7675,20 @@ var Lc = /* @__PURE__ */ new Map(), Rc = class {
7675
7675
  }
7676
7676
  return r && (r.rowCount += i), this.valueIndex.bumpVersion(), this.snapshotManager.markCountsDirty(), this.rowStore.invalidateIndex(), this.sourceLifecycle.trackAppend(e, a, t, n !== void 0 && n.size > 0), this.filterEngine.notifyRowsAdded(o), this.filterEngine.updateRowsText(s), this.notify(), a;
7677
7677
  }
7678
+ seedInitialChanges(e, t, n) {
7679
+ for (let r of n) {
7680
+ let n = e[r.index], i = t[r.index];
7681
+ if (r.isNew && (this.dirtyTracker.trackNonBackendRow(n), this.dirtyTracker.markNew(n)), r.originalValues) {
7682
+ let e = {
7683
+ ...i,
7684
+ ...r.originalValues
7685
+ };
7686
+ this.dirtyTracker.snapshotOriginal(n, e), this.dirtyTracker.markEdited(n);
7687
+ }
7688
+ r.isDeleted && this.dirtyTracker.markDeleted(n);
7689
+ }
7690
+ this.filterEngine.markFlagsDirty(), this.filterEngine.flushPendingFlags(), this.snapshotManager.markCountsDirty(), this.notify();
7691
+ }
7678
7692
  upsertRows(e, t, n) {
7679
7693
  let { anchorKey: r, newRowIds: i } = n ?? {};
7680
7694
  r && this.sourceLifecycle.trackPrimaryKey(e, r);
@@ -9792,7 +9806,7 @@ function dl(e, t, n, r) {
9792
9806
  };
9793
9807
  n((n, o) => {
9794
9808
  let c;
9795
- if (o ? (c = o.id ?? o.source, e.hasSource(c) || (e.registerSource({
9809
+ if (o?.source ? (c = o.id ?? o.source, e.hasSource(c) || (e.registerSource({
9796
9810
  name: o.source,
9797
9811
  id: c,
9798
9812
  isDeletable: o.deletable ?? !1,
@@ -9804,7 +9818,7 @@ function dl(e, t, n, r) {
9804
9818
  isInitialData: !0
9805
9819
  }), e.setSourceLoading(Os, !0), !0), c = Os), n.length > 0) {
9806
9820
  let r = e.appendRows(c, n);
9807
- a++, requestIdleCallback(() => {
9821
+ o?.changes?.length && e.seedInitialChanges(r, n, o.changes), a++, requestIdleCallback(() => {
9808
9822
  t.current.validateRows(n, r), a--, s();
9809
9823
  });
9810
9824
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@updog/data-editor",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "Client-side CSV importer and spreadsheet editor SDK for React. Import CSV, Excel, JSON, TSV, and XML, match columns, validate, and edit 1M+ rows entirely in the browser.",
5
5
  "author": "Mikhail Kutateladze <admin@updog.tech>",
6
6
  "homepage": "https://updog.tech",