@updog/data-editor 0.1.41 → 0.1.43
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/index.css +1 -1
- package/index.d.ts +480 -475
- package/index.js +2910 -2828
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -443,9 +443,6 @@ declare var export_default = {
|
|
|
443
443
|
primaryKey: "Primary key",
|
|
444
444
|
},
|
|
445
445
|
uploadFile: {
|
|
446
|
-
title: "Upload file",
|
|
447
|
-
text: "Upload a CSV, TSV, Excel, JSON or XML file to import data",
|
|
448
|
-
textDynamic: "Upload a {{formats}} file to import data",
|
|
449
446
|
parseError: "Failed to parse file",
|
|
450
447
|
clickToUpload: "Click to upload",
|
|
451
448
|
orDragAndDrop: "or drag and drop",
|
|
@@ -462,8 +459,6 @@ declare var export_default = {
|
|
|
462
459
|
fetchError: "Failed to load data",
|
|
463
460
|
},
|
|
464
461
|
matchColumns: {
|
|
465
|
-
title: "Match columns",
|
|
466
|
-
text: "Map imported columns to existing columns",
|
|
467
462
|
banner: "Some columns could not be automatically matched",
|
|
468
463
|
importedColumns: "Imported columns",
|
|
469
464
|
matchedCount: "{{matched}}/{{total}} matched",
|
|
@@ -484,25 +479,26 @@ declare var export_default = {
|
|
|
484
479
|
"Unmatched columns won't be imported. Match this column to keep the data. You can transform columns after importing.",
|
|
485
480
|
},
|
|
486
481
|
sheetSelection: {
|
|
487
|
-
title: "Select sheet",
|
|
488
|
-
text: "This file contains multiple sheets. Choose which sheet to import.",
|
|
489
482
|
rowCount: "{{count}} rows",
|
|
490
483
|
emptySheet: "Empty sheet",
|
|
491
484
|
},
|
|
492
485
|
matchValues: {
|
|
493
|
-
title: "Match values",
|
|
494
|
-
text: "Review how imported values map to your column options. Adjust any mappings that need a different match.",
|
|
495
486
|
importedValues: "Imported values",
|
|
496
487
|
matchedCount: "{{matched}}/{{total}} matched",
|
|
497
488
|
targetValue: "Target value",
|
|
498
489
|
selectValuePlaceholder: "Select value",
|
|
499
490
|
showMatched: "Show matched",
|
|
500
491
|
allMatched: "All values are matched",
|
|
501
|
-
unmatchedWarning:
|
|
492
|
+
unmatchedWarning:
|
|
493
|
+
"Unmatched values won't be imported. Match this value to keep the data. You can edit values after importing.",
|
|
494
|
+
createOption: "Create option",
|
|
495
|
+
createOptionTitle: "Create option",
|
|
496
|
+
createOptionNameLabel: "Option name",
|
|
497
|
+
createOptionNamePlaceholder: "Enter option name",
|
|
498
|
+
createOptionNameTaken: "This option already exists",
|
|
499
|
+
createOptionSubmit: "Create",
|
|
502
500
|
},
|
|
503
501
|
primaryKey: {
|
|
504
|
-
title: "Select primary key",
|
|
505
|
-
text: "Choose the column that uniquely identifies each row",
|
|
506
502
|
none: "No primary key",
|
|
507
503
|
noneHint:
|
|
508
504
|
"All rows will be appended as new entries without deduplication.",
|
|
@@ -720,6 +716,11 @@ type SelectEditorCell = {
|
|
|
720
716
|
type: "select";
|
|
721
717
|
/** The list of options shown in the dropdown. Each string is both the stored value and the display label. */
|
|
722
718
|
options: string[];
|
|
719
|
+
/**
|
|
720
|
+
* Let users add options via "Create option" (matching step + grid); never
|
|
721
|
+
* created implicitly. Defaults to true; false for a strict closed enum.
|
|
722
|
+
*/
|
|
723
|
+
enableCustomValue?: boolean;
|
|
723
724
|
};
|
|
724
725
|
/** Number input cell with locale-aware formatting. */
|
|
725
726
|
type NumberEditorCell = {
|
|
@@ -1246,78 +1247,6 @@ declare class ChunkedProcessor<T> {
|
|
|
1246
1247
|
cancel(): void;
|
|
1247
1248
|
}
|
|
1248
1249
|
|
|
1249
|
-
type RegisterSourceOptions = {
|
|
1250
|
-
name: string;
|
|
1251
|
-
id?: DataSourceId;
|
|
1252
|
-
isDeletable?: boolean;
|
|
1253
|
-
isInitialData?: boolean;
|
|
1254
|
-
};
|
|
1255
|
-
type MergeEntry<TRow> = {
|
|
1256
|
-
row: TRow;
|
|
1257
|
-
sourceId: DataSourceId;
|
|
1258
|
-
isNew: boolean;
|
|
1259
|
-
isEdited: boolean;
|
|
1260
|
-
};
|
|
1261
|
-
type RemovalPlan<TRow> = {
|
|
1262
|
-
rowsToDelete: Set<TRowId>;
|
|
1263
|
-
rowsToRestore: Array<{
|
|
1264
|
-
rowId: TRowId;
|
|
1265
|
-
row: TRow;
|
|
1266
|
-
originalSourceId: DataSourceId;
|
|
1267
|
-
isNew: boolean;
|
|
1268
|
-
isEdited: boolean;
|
|
1269
|
-
}>;
|
|
1270
|
-
};
|
|
1271
|
-
type ExtendedRemovalPlan<TRow> = RemovalPlan<TRow> & {
|
|
1272
|
-
sourceId: DataSourceId;
|
|
1273
|
-
repairedEntries: Array<{
|
|
1274
|
-
sourceId: DataSourceId;
|
|
1275
|
-
rowId: TRowId;
|
|
1276
|
-
before: MergeEntry<TRow>;
|
|
1277
|
-
after: MergeEntry<TRow> | null;
|
|
1278
|
-
}>;
|
|
1279
|
-
};
|
|
1280
|
-
declare class SourceManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1281
|
-
private readonly _defaultSourceId;
|
|
1282
|
-
private readonly overrides;
|
|
1283
|
-
private readonly sources;
|
|
1284
|
-
private readonly mergedRows;
|
|
1285
|
-
getSourceId(rowId: TRowId): DataSourceId;
|
|
1286
|
-
setSourceId(rowId: TRowId, sourceId: DataSourceId): void;
|
|
1287
|
-
deleteSourceId(rowId: TRowId): void;
|
|
1288
|
-
getOverrides(): ReadonlyMap<TRowId, DataSourceId>;
|
|
1289
|
-
register(options: RegisterSourceOptions): DataSourceId;
|
|
1290
|
-
/**
|
|
1291
|
-
* Re-insert a source using a full captured state, preserving
|
|
1292
|
-
* isVisible, isLoading, rowCount, etc. Used by SourceLifecycle.restore.
|
|
1293
|
-
* If the source already exists, overwrites its state.
|
|
1294
|
-
*/
|
|
1295
|
-
restoreState(state: DataSourceState): void;
|
|
1296
|
-
has(sourceId: DataSourceId): boolean;
|
|
1297
|
-
get(sourceId: DataSourceId): DataSourceState | undefined;
|
|
1298
|
-
delete(sourceId: DataSourceId): void;
|
|
1299
|
-
setLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1300
|
-
finalizeAllSources(): void;
|
|
1301
|
-
values(): IterableIterator<DataSourceState>;
|
|
1302
|
-
getHiddenSourceIds(): Set<DataSourceId>;
|
|
1303
|
-
saveMergeSnapshot(sourceId: DataSourceId, rowId: TRowId, existingRow: TRow, previousSourceId: DataSourceId, isNew: boolean, isEdited: boolean): void;
|
|
1304
|
-
/**
|
|
1305
|
-
* Public so commands can re-install merge entries during undo of a remove.
|
|
1306
|
-
*/
|
|
1307
|
-
restoreMergeEntry(sourceId: DataSourceId, rowId: TRowId, entry: MergeEntry<TRow>): void;
|
|
1308
|
-
/**
|
|
1309
|
-
* Pure — computes the full removal plan without mutating any state.
|
|
1310
|
-
* Callers run applyRemovalPlan(plan) to commit.
|
|
1311
|
-
*/
|
|
1312
|
-
planRemoval(sourceId: DataSourceId): ExtendedRemovalPlan<TRow> | null;
|
|
1313
|
-
/**
|
|
1314
|
-
* Mutates internal state per plan produced by planRemoval.
|
|
1315
|
-
*/
|
|
1316
|
-
applyRemovalPlan(plan: ExtendedRemovalPlan<TRow>): void;
|
|
1317
|
-
clear(): void;
|
|
1318
|
-
private getUniqueName;
|
|
1319
|
-
}
|
|
1320
|
-
|
|
1321
1250
|
/**
|
|
1322
1251
|
* Internal contract: the surface a Scale client exposes to the SDK's data
|
|
1323
1252
|
* layer. Implemented by `ScaleClient`. Not part of the public SDK API —
|
|
@@ -1340,185 +1269,143 @@ type ScaleClientApi<TRow extends DataEditorRow = DataEditorRow, TFilters = Recor
|
|
|
1340
1269
|
scrollSensitivity?: number;
|
|
1341
1270
|
};
|
|
1342
1271
|
|
|
1343
|
-
type ServerDataManagerDeps<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1344
|
-
clear(): void;
|
|
1345
|
-
setLoading(isLoading: boolean): void;
|
|
1346
|
-
registerSource(options: RegisterSourceOptions): DataSourceId;
|
|
1347
|
-
setSourceLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1348
|
-
getLocalRowCount(): number;
|
|
1349
|
-
replaceServerRows(sourceId: DataSourceId, rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1350
|
-
appendServerRows(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1351
|
-
prependServerRows(rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1352
|
-
applyServerRowMeta(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1353
|
-
};
|
|
1354
|
-
type FetchDirection = "forward" | "backward" | "jump";
|
|
1355
|
-
declare class ServerDataManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1356
|
-
private _offset;
|
|
1357
|
-
private _totalCount;
|
|
1358
|
-
private _isFetching;
|
|
1359
|
-
private readonly _pageSize;
|
|
1360
|
-
private readonly _maxBufferRows;
|
|
1361
|
-
private _filters;
|
|
1362
|
-
private _sources;
|
|
1363
|
-
private _sort;
|
|
1364
|
-
private _filterOptions;
|
|
1365
|
-
private _filterOptionsFetched;
|
|
1366
|
-
private _abortController;
|
|
1367
|
-
private _syncAbort;
|
|
1368
|
-
private _lastVisibleStart;
|
|
1369
|
-
private _debouncedFetch;
|
|
1370
|
-
private readonly _config;
|
|
1371
|
-
private readonly _dataStoreRef;
|
|
1372
|
-
private readonly _sourceLabel;
|
|
1373
|
-
private _onChanged;
|
|
1374
|
-
constructor(config: ScaleClientApi<TRow>, dataStoreRef: ServerDataManagerDeps<TRow>, sourceLabel: string);
|
|
1375
|
-
get offset(): number;
|
|
1376
|
-
get totalCount(): number | null;
|
|
1377
|
-
get isFetching(): boolean;
|
|
1378
|
-
get pageSize(): number;
|
|
1379
|
-
get maxBufferRows(): number;
|
|
1380
|
-
setOnChanged(callback: () => void): void;
|
|
1381
|
-
setOffset(offset: number): void;
|
|
1382
|
-
setTotalCount(count: number): void;
|
|
1383
|
-
private setFetching;
|
|
1384
|
-
getExcess(currentCount: number, newCount: number): number;
|
|
1385
|
-
shouldFetch(visibleStart: number, visibleEnd: number, loadedCount: number): FetchDirection | null;
|
|
1386
|
-
/**
|
|
1387
|
-
* Full reload — abort in-flight, clear store, fetch first page.
|
|
1388
|
-
* Called on initial load, search/filter/sort changes, and resetFilters.
|
|
1389
|
-
*/
|
|
1390
|
-
reload(): void;
|
|
1391
|
-
/**
|
|
1392
|
-
* Scroll-driven pagination with velocity-based debouncing.
|
|
1393
|
-
* Called from CanvasGrid on every scroll event.
|
|
1394
|
-
*/
|
|
1395
|
-
handleScroll(visibleStart: number, visibleEnd: number): void;
|
|
1396
|
-
/**
|
|
1397
|
-
* Fetch a single page based on scroll position and current window state.
|
|
1398
|
-
*/
|
|
1399
|
-
private fetchPage;
|
|
1400
|
-
/**
|
|
1401
|
-
* Re-query the current viewport and replace row data, metadata, and counts.
|
|
1402
|
-
* Called after successful edits and find-and-replace mutations.
|
|
1403
|
-
* Each call aborts the previous in-flight sync.
|
|
1404
|
-
*/
|
|
1405
|
-
syncCurrentView(): void;
|
|
1406
|
-
/**
|
|
1407
|
-
* Merge filter keys into server filter state and reload.
|
|
1408
|
-
* Called by DataStore.setFilters() in server mode and by filter components.
|
|
1409
|
-
*/
|
|
1410
|
-
setFilters(filters: Partial<Filters>): void;
|
|
1411
|
-
/**
|
|
1412
|
-
* Set sort state and reload.
|
|
1413
|
-
*/
|
|
1414
|
-
setSort(sort: SortState): void;
|
|
1415
|
-
/**
|
|
1416
|
-
* Restrict query to visible sources and reload.
|
|
1417
|
-
* Pass `undefined` to include all sources.
|
|
1418
|
-
*/
|
|
1419
|
-
setSources(sources: string[] | undefined): void;
|
|
1420
|
-
/**
|
|
1421
|
-
* Clear all filters and sort, then reload.
|
|
1422
|
-
*/
|
|
1423
|
-
resetFilters(): void;
|
|
1424
|
-
/**
|
|
1425
|
-
* One-time fetch of filter option dictionaries for sidebar filter controls.
|
|
1426
|
-
*/
|
|
1427
|
-
fetchFilterOptions(): void;
|
|
1428
|
-
getFilterOptions(): FilterOptionsResponse | null;
|
|
1429
|
-
get onEdit(): (params: EditParams, options?: ServerCallOptions) => Promise<EditResponse | void>;
|
|
1430
|
-
get filters(): Record<string, unknown>;
|
|
1431
|
-
get sort(): SortState;
|
|
1432
|
-
get sources(): string[] | undefined;
|
|
1433
|
-
get onSourceRemove(): ((params: SourceRemoveParams) => Promise<void>) | undefined;
|
|
1434
|
-
get onColumnDelete(): ((params: ColumnDeleteParams) => Promise<EditResponse | void>) | undefined;
|
|
1435
|
-
get onColumnEdit(): ((params: ColumnEditParams) => Promise<EditResponse | void>) | undefined;
|
|
1436
|
-
get hasExport(): boolean;
|
|
1437
|
-
private _exportAbortController;
|
|
1438
|
-
export(format: DataEditorFormat, allRows: boolean, rtl: boolean): Promise<void>;
|
|
1439
|
-
clear(): void;
|
|
1440
|
-
destroy(): void;
|
|
1441
|
-
}
|
|
1442
|
-
|
|
1443
1272
|
/**
|
|
1444
|
-
* A
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1273
|
+
* A single operation the LLM wants to apply to rows in the current filtered view.
|
|
1274
|
+
*
|
|
1275
|
+
* - `edit` — `fn` is `(r, ctx) => void`. Mutates `r` in place. Changed fields
|
|
1276
|
+
* become column deltas. Rows with no changes are no-ops.
|
|
1277
|
+
* - `delete` — `fn` is `(r, ctx) => boolean`. Truthy means "flag this row for
|
|
1278
|
+
* deletion". Soft delete via `DeleteRowCommand`.
|
|
1447
1279
|
*/
|
|
1448
|
-
type
|
|
1449
|
-
|
|
1450
|
-
|
|
1280
|
+
type ChatOp = {
|
|
1281
|
+
action: "edit";
|
|
1282
|
+
fn: string;
|
|
1283
|
+
} | {
|
|
1284
|
+
action: "delete";
|
|
1285
|
+
fn: string;
|
|
1451
1286
|
};
|
|
1452
|
-
|
|
1453
1287
|
/**
|
|
1454
|
-
*
|
|
1455
|
-
*
|
|
1456
|
-
* Converts frontend coordinates (TRowId, column index, grid ranges) into
|
|
1457
|
-
* `EditParams` with `Region[]` that the server can interpret.
|
|
1458
|
-
*
|
|
1459
|
-
* Does NOT call `onEdit`. Only builds params.
|
|
1460
|
-
* DataStore calls the builder, then sends the result to the server.
|
|
1288
|
+
* A single chunk in the stream returned from `DataEditorChat.onMessage`.
|
|
1461
1289
|
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
1464
|
-
*
|
|
1465
|
-
*
|
|
1290
|
+
* - `status` — progress message shown while processing (e.g. "Analyzing 500 rows...").
|
|
1291
|
+
* - `message` — chat reply shown to the user.
|
|
1292
|
+
* - `rows` — updated rows to apply to the grid. Matched by `primaryKey`.
|
|
1293
|
+
* - `ops` — array of per-row operations (edits and/or deletes) to apply in order.
|
|
1466
1294
|
*/
|
|
1467
|
-
|
|
1468
|
-
type
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1295
|
+
type ChatResponseChunk<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1296
|
+
type: "status";
|
|
1297
|
+
content: string;
|
|
1298
|
+
} | {
|
|
1299
|
+
type: "message";
|
|
1300
|
+
content: string;
|
|
1301
|
+
} | {
|
|
1302
|
+
type: "rows";
|
|
1303
|
+
content: TRow[];
|
|
1304
|
+
} | {
|
|
1305
|
+
type: "ops";
|
|
1306
|
+
content: ChatOp[];
|
|
1475
1307
|
};
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1308
|
+
/** Status of a row in the chat sample, relative to its origin snapshot. */
|
|
1309
|
+
type ChatRowStatus = "new" | "edited" | "original";
|
|
1310
|
+
/** A sample row handed to the chat callback, with its current status and validation errors. */
|
|
1311
|
+
type ChatRow<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1312
|
+
/** Row data keyed by column ID. */
|
|
1313
|
+
data: TRow;
|
|
1314
|
+
/** Whether the row was newly added, edited, or is unchanged. */
|
|
1315
|
+
status: ChatRowStatus;
|
|
1316
|
+
/** Validation errors keyed by column ID. */
|
|
1317
|
+
errors: Record<string, string[]>;
|
|
1318
|
+
/** The source this row belongs to. */
|
|
1319
|
+
source: string;
|
|
1320
|
+
};
|
|
1321
|
+
/** Aggregated error count across the current view, grouped by field and message. */
|
|
1322
|
+
type ChatErrorSummary = {
|
|
1323
|
+
/** Column ID where the error occurred. */
|
|
1324
|
+
field: string;
|
|
1325
|
+
/** The validation message. */
|
|
1326
|
+
message: string;
|
|
1327
|
+
/** How many rows hit this error. */
|
|
1328
|
+
count: number;
|
|
1329
|
+
/** A few example values that triggered the error. */
|
|
1330
|
+
examples: string[];
|
|
1331
|
+
};
|
|
1332
|
+
/**
|
|
1333
|
+
* Context about the current dataset, passed to `loadSuggestions` and extended
|
|
1334
|
+
* into `ChatContext` for `onMessage`.
|
|
1335
|
+
*/
|
|
1336
|
+
type ChatDataContext<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1337
|
+
/** Full column definitions. */
|
|
1338
|
+
columns: DataEditorColumn[];
|
|
1339
|
+
/** Row identifier field. */
|
|
1340
|
+
primaryKey: keyof TRow;
|
|
1341
|
+
/** Total rows in the dataset. */
|
|
1342
|
+
totalRowCount: number;
|
|
1343
|
+
/** Rows in the current filtered view. */
|
|
1344
|
+
filteredRowCount: number;
|
|
1345
|
+
/** Sample rows, with status and errors. Size controlled by `sampleSize`. */
|
|
1346
|
+
sample: ChatRow<TRow>[];
|
|
1347
|
+
/** Aggregated error counts by field and message. */
|
|
1348
|
+
errorSummary: ChatErrorSummary[];
|
|
1349
|
+
/** Access all rows. Use for full-dataset operations. */
|
|
1350
|
+
getRows: () => ChatRow<TRow>[];
|
|
1351
|
+
};
|
|
1352
|
+
/**
|
|
1353
|
+
* The full context passed to `DataEditorChat.onMessage` when the user sends
|
|
1354
|
+
* a prompt. Includes the prompt itself and all dataset context.
|
|
1355
|
+
*/
|
|
1356
|
+
type ChatContext<TRow extends DataEditorRow = DataEditorRow> = ChatDataContext<TRow> & {
|
|
1357
|
+
/** The user's chat prompt. */
|
|
1358
|
+
message: string;
|
|
1359
|
+
};
|
|
1360
|
+
/**
|
|
1361
|
+
* Bring-your-own-AI chat configuration. When provided via the `chat` prop,
|
|
1362
|
+
* the editor shows a chat panel alongside the grid. You own the AI
|
|
1363
|
+
* integration; the SDK hands you dataset context and renders the streamed
|
|
1364
|
+
* response.
|
|
1365
|
+
*
|
|
1366
|
+
* @example
|
|
1367
|
+
* ```ts
|
|
1368
|
+
* chat={{
|
|
1369
|
+
* sampleSize: 50,
|
|
1370
|
+
* onMessage: async function* (context) {
|
|
1371
|
+
* yield { type: "status", content: "Thinking..." };
|
|
1372
|
+
* const res = await fetch("/api/ai", {
|
|
1373
|
+
* method: "POST",
|
|
1374
|
+
* body: JSON.stringify({
|
|
1375
|
+
* prompt: context.message,
|
|
1376
|
+
* columns: context.columns,
|
|
1377
|
+
* sample: context.sample.map(r => r.data),
|
|
1378
|
+
* errors: context.errorSummary,
|
|
1379
|
+
* }),
|
|
1380
|
+
* }).then(r => r.json());
|
|
1381
|
+
* yield { type: "rows", content: res.updatedRows };
|
|
1382
|
+
* yield { type: "ops", content: res.ops };
|
|
1383
|
+
* yield { type: "message", content: res.reply };
|
|
1384
|
+
* },
|
|
1385
|
+
* }}
|
|
1386
|
+
* ```
|
|
1387
|
+
*/
|
|
1388
|
+
type DataEditorChat<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1515
1389
|
/**
|
|
1516
|
-
*
|
|
1517
|
-
*
|
|
1390
|
+
* How many rows to include in the context sample. The SDK picks a
|
|
1391
|
+
* representative slice including rows with errors. When omitted, the SDK decides.
|
|
1518
1392
|
*/
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1393
|
+
sampleSize?: number;
|
|
1394
|
+
/** Title shown above the suggestion list when the chat is empty. */
|
|
1395
|
+
emptyTitle?: string;
|
|
1396
|
+
/** How many suggestions to request from `loadSuggestions`. */
|
|
1397
|
+
suggestionsCount?: number;
|
|
1398
|
+
/** Optional prompt generator for the empty-state suggestion chips. */
|
|
1399
|
+
loadSuggestions?: (context: ChatDataContext<TRow>) => Promise<string[]>;
|
|
1400
|
+
/**
|
|
1401
|
+
* Called when the user sends a message. Receives full dataset context.
|
|
1402
|
+
* Returns an async iterable of response chunks — the SDK streams them
|
|
1403
|
+
* into the UI.
|
|
1404
|
+
*/
|
|
1405
|
+
onMessage: (context: ChatContext<TRow>) => AsyncIterable<ChatResponseChunk<TRow>>;
|
|
1406
|
+
/** Called when the user cancels a pending request. Use to abort your API call. */
|
|
1407
|
+
onCancel?: () => void;
|
|
1408
|
+
};
|
|
1522
1409
|
|
|
1523
1410
|
/**
|
|
1524
1411
|
* Categories of internal errors surfaced through the `onError` callback.
|
|
@@ -1559,6 +1446,341 @@ declare class ErrorHandler {
|
|
|
1559
1446
|
handleError(error: UpdogError): void;
|
|
1560
1447
|
}
|
|
1561
1448
|
|
|
1449
|
+
type FormulaCellContext = {
|
|
1450
|
+
value: unknown;
|
|
1451
|
+
field: string;
|
|
1452
|
+
rowId: TRowId;
|
|
1453
|
+
getField: (field: string) => unknown;
|
|
1454
|
+
/**
|
|
1455
|
+
* Positional arguments for expression-compiled formulas.
|
|
1456
|
+
* Populated by the expression evaluator when invoking multi-arg function
|
|
1457
|
+
* calls. Single-arg formulas (UPPER, TRIM, etc.) still read from `value`.
|
|
1458
|
+
* Undefined for all non-expression call sites — existing code is unaffected.
|
|
1459
|
+
*/
|
|
1460
|
+
args?: readonly unknown[];
|
|
1461
|
+
};
|
|
1462
|
+
type FormulaParamType = "string" | "number" | "boolean" | "select";
|
|
1463
|
+
type FormulaParam = {
|
|
1464
|
+
name: string;
|
|
1465
|
+
label: string;
|
|
1466
|
+
type: FormulaParamType;
|
|
1467
|
+
required?: boolean;
|
|
1468
|
+
defaultValue?: unknown;
|
|
1469
|
+
options?: Array<{
|
|
1470
|
+
id: string;
|
|
1471
|
+
text: string;
|
|
1472
|
+
}>;
|
|
1473
|
+
};
|
|
1474
|
+
type ColumnInputKind = "single" | "multiple";
|
|
1475
|
+
type ColumnInput = {
|
|
1476
|
+
name: string;
|
|
1477
|
+
label: string;
|
|
1478
|
+
kind: ColumnInputKind;
|
|
1479
|
+
required?: boolean;
|
|
1480
|
+
};
|
|
1481
|
+
type FormulaCategory = "text" | "number" | "logic" | "custom";
|
|
1482
|
+
type FormulaArity = {
|
|
1483
|
+
/** Minimum number of positional arguments. 0 means "callable with no args". */
|
|
1484
|
+
min: number;
|
|
1485
|
+
/** Maximum number of positional arguments. Use Number.POSITIVE_INFINITY for variadic. */
|
|
1486
|
+
max: number;
|
|
1487
|
+
};
|
|
1488
|
+
type FormulaBase = {
|
|
1489
|
+
name: string;
|
|
1490
|
+
label: string;
|
|
1491
|
+
category: FormulaCategory;
|
|
1492
|
+
description?: string;
|
|
1493
|
+
columns?: ColumnInput[];
|
|
1494
|
+
params: FormulaParam[];
|
|
1495
|
+
/**
|
|
1496
|
+
* The call signature of this formula when invoked from the expression
|
|
1497
|
+
* language. Required. For shortcut formulas (UPPER, TRIM, ...) use
|
|
1498
|
+
* { min: 1, max: 1 }. For CLEAR use { min: 0, max: 0 }. For MERGE use
|
|
1499
|
+
* { min: 2, max: Number.POSITIVE_INFINITY }.
|
|
1500
|
+
*/
|
|
1501
|
+
arity: FormulaArity;
|
|
1502
|
+
/** Parameter signature shown in autocomplete, without the function name. e.g. "(text, count)" */
|
|
1503
|
+
syntax?: string;
|
|
1504
|
+
/**
|
|
1505
|
+
* Whether this formula may be invoked from the expression parser.
|
|
1506
|
+
* Defaults to true when omitted. MERGE and SPLIT set this to false
|
|
1507
|
+
* because they have dedicated modals that supply their non-expression
|
|
1508
|
+
* params (column lists, separator, ...).
|
|
1509
|
+
*/
|
|
1510
|
+
expressionCallable?: boolean;
|
|
1511
|
+
};
|
|
1512
|
+
type CellFormula = FormulaBase & {
|
|
1513
|
+
kind: "cell";
|
|
1514
|
+
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => unknown;
|
|
1515
|
+
};
|
|
1516
|
+
type RowFormula = FormulaBase & {
|
|
1517
|
+
kind: "row";
|
|
1518
|
+
targetFields: (params: Record<string, unknown>) => string[];
|
|
1519
|
+
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => Record<string, unknown>;
|
|
1520
|
+
};
|
|
1521
|
+
type FormulaDefinition = CellFormula | RowFormula;
|
|
1522
|
+
|
|
1523
|
+
declare class FormulaRegistry {
|
|
1524
|
+
private readonly formulas;
|
|
1525
|
+
register(formula: FormulaDefinition): void;
|
|
1526
|
+
get(name: string): FormulaDefinition | undefined;
|
|
1527
|
+
getAll(): FormulaDefinition[];
|
|
1528
|
+
getByCategory(category: string): FormulaDefinition[];
|
|
1529
|
+
getExpressionCallable(): FormulaDefinition[];
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
type RegisterSourceOptions = {
|
|
1533
|
+
name: string;
|
|
1534
|
+
id?: DataSourceId;
|
|
1535
|
+
isDeletable?: boolean;
|
|
1536
|
+
isInitialData?: boolean;
|
|
1537
|
+
};
|
|
1538
|
+
type MergeEntry<TRow> = {
|
|
1539
|
+
row: TRow;
|
|
1540
|
+
sourceId: DataSourceId;
|
|
1541
|
+
isNew: boolean;
|
|
1542
|
+
isEdited: boolean;
|
|
1543
|
+
};
|
|
1544
|
+
type RemovalPlan<TRow> = {
|
|
1545
|
+
rowsToDelete: Set<TRowId>;
|
|
1546
|
+
rowsToRestore: Array<{
|
|
1547
|
+
rowId: TRowId;
|
|
1548
|
+
row: TRow;
|
|
1549
|
+
originalSourceId: DataSourceId;
|
|
1550
|
+
isNew: boolean;
|
|
1551
|
+
isEdited: boolean;
|
|
1552
|
+
}>;
|
|
1553
|
+
};
|
|
1554
|
+
type ExtendedRemovalPlan<TRow> = RemovalPlan<TRow> & {
|
|
1555
|
+
sourceId: DataSourceId;
|
|
1556
|
+
repairedEntries: Array<{
|
|
1557
|
+
sourceId: DataSourceId;
|
|
1558
|
+
rowId: TRowId;
|
|
1559
|
+
before: MergeEntry<TRow>;
|
|
1560
|
+
after: MergeEntry<TRow> | null;
|
|
1561
|
+
}>;
|
|
1562
|
+
};
|
|
1563
|
+
declare class SourceManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1564
|
+
private readonly _defaultSourceId;
|
|
1565
|
+
private readonly overrides;
|
|
1566
|
+
private readonly sources;
|
|
1567
|
+
private readonly mergedRows;
|
|
1568
|
+
getSourceId(rowId: TRowId): DataSourceId;
|
|
1569
|
+
setSourceId(rowId: TRowId, sourceId: DataSourceId): void;
|
|
1570
|
+
deleteSourceId(rowId: TRowId): void;
|
|
1571
|
+
getOverrides(): ReadonlyMap<TRowId, DataSourceId>;
|
|
1572
|
+
register(options: RegisterSourceOptions): DataSourceId;
|
|
1573
|
+
/**
|
|
1574
|
+
* Re-insert a source using a full captured state, preserving
|
|
1575
|
+
* isVisible, isLoading, rowCount, etc. Used by SourceLifecycle.restore.
|
|
1576
|
+
* If the source already exists, overwrites its state.
|
|
1577
|
+
*/
|
|
1578
|
+
restoreState(state: DataSourceState): void;
|
|
1579
|
+
has(sourceId: DataSourceId): boolean;
|
|
1580
|
+
get(sourceId: DataSourceId): DataSourceState | undefined;
|
|
1581
|
+
delete(sourceId: DataSourceId): void;
|
|
1582
|
+
setLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1583
|
+
finalizeAllSources(): void;
|
|
1584
|
+
values(): IterableIterator<DataSourceState>;
|
|
1585
|
+
getHiddenSourceIds(): Set<DataSourceId>;
|
|
1586
|
+
saveMergeSnapshot(sourceId: DataSourceId, rowId: TRowId, existingRow: TRow, previousSourceId: DataSourceId, isNew: boolean, isEdited: boolean): void;
|
|
1587
|
+
/**
|
|
1588
|
+
* Public so commands can re-install merge entries during undo of a remove.
|
|
1589
|
+
*/
|
|
1590
|
+
restoreMergeEntry(sourceId: DataSourceId, rowId: TRowId, entry: MergeEntry<TRow>): void;
|
|
1591
|
+
/**
|
|
1592
|
+
* Pure — computes the full removal plan without mutating any state.
|
|
1593
|
+
* Callers run applyRemovalPlan(plan) to commit.
|
|
1594
|
+
*/
|
|
1595
|
+
planRemoval(sourceId: DataSourceId): ExtendedRemovalPlan<TRow> | null;
|
|
1596
|
+
/**
|
|
1597
|
+
* Mutates internal state per plan produced by planRemoval.
|
|
1598
|
+
*/
|
|
1599
|
+
applyRemovalPlan(plan: ExtendedRemovalPlan<TRow>): void;
|
|
1600
|
+
clear(): void;
|
|
1601
|
+
private getUniqueName;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
type ServerDataManagerDeps<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1605
|
+
clear(): void;
|
|
1606
|
+
setLoading(isLoading: boolean): void;
|
|
1607
|
+
registerSource(options: RegisterSourceOptions): DataSourceId;
|
|
1608
|
+
setSourceLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1609
|
+
getLocalRowCount(): number;
|
|
1610
|
+
replaceServerRows(sourceId: DataSourceId, rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1611
|
+
appendServerRows(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1612
|
+
prependServerRows(rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1613
|
+
applyServerRowMeta(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1614
|
+
};
|
|
1615
|
+
type FetchDirection = "forward" | "backward" | "jump";
|
|
1616
|
+
declare class ServerDataManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1617
|
+
private _offset;
|
|
1618
|
+
private _totalCount;
|
|
1619
|
+
private _isFetching;
|
|
1620
|
+
private readonly _pageSize;
|
|
1621
|
+
private readonly _maxBufferRows;
|
|
1622
|
+
private _filters;
|
|
1623
|
+
private _sources;
|
|
1624
|
+
private _sort;
|
|
1625
|
+
private _filterOptions;
|
|
1626
|
+
private _filterOptionsFetched;
|
|
1627
|
+
private _abortController;
|
|
1628
|
+
private _syncAbort;
|
|
1629
|
+
private _lastVisibleStart;
|
|
1630
|
+
private _debouncedFetch;
|
|
1631
|
+
private readonly _config;
|
|
1632
|
+
private readonly _dataStoreRef;
|
|
1633
|
+
private readonly _sourceLabel;
|
|
1634
|
+
private _onChanged;
|
|
1635
|
+
constructor(config: ScaleClientApi<TRow>, dataStoreRef: ServerDataManagerDeps<TRow>, sourceLabel: string);
|
|
1636
|
+
get offset(): number;
|
|
1637
|
+
get totalCount(): number | null;
|
|
1638
|
+
get isFetching(): boolean;
|
|
1639
|
+
get pageSize(): number;
|
|
1640
|
+
get maxBufferRows(): number;
|
|
1641
|
+
setOnChanged(callback: () => void): void;
|
|
1642
|
+
setOffset(offset: number): void;
|
|
1643
|
+
setTotalCount(count: number): void;
|
|
1644
|
+
private setFetching;
|
|
1645
|
+
getExcess(currentCount: number, newCount: number): number;
|
|
1646
|
+
shouldFetch(visibleStart: number, visibleEnd: number, loadedCount: number): FetchDirection | null;
|
|
1647
|
+
/**
|
|
1648
|
+
* Full reload — abort in-flight, clear store, fetch first page.
|
|
1649
|
+
* Called on initial load, search/filter/sort changes, and resetFilters.
|
|
1650
|
+
*/
|
|
1651
|
+
reload(): void;
|
|
1652
|
+
/**
|
|
1653
|
+
* Scroll-driven pagination with velocity-based debouncing.
|
|
1654
|
+
* Called from CanvasGrid on every scroll event.
|
|
1655
|
+
*/
|
|
1656
|
+
handleScroll(visibleStart: number, visibleEnd: number): void;
|
|
1657
|
+
/**
|
|
1658
|
+
* Fetch a single page based on scroll position and current window state.
|
|
1659
|
+
*/
|
|
1660
|
+
private fetchPage;
|
|
1661
|
+
/**
|
|
1662
|
+
* Re-query the current viewport and replace row data, metadata, and counts.
|
|
1663
|
+
* Called after successful edits and find-and-replace mutations.
|
|
1664
|
+
* Each call aborts the previous in-flight sync.
|
|
1665
|
+
*/
|
|
1666
|
+
syncCurrentView(): void;
|
|
1667
|
+
/**
|
|
1668
|
+
* Merge filter keys into server filter state and reload.
|
|
1669
|
+
* Called by DataStore.setFilters() in server mode and by filter components.
|
|
1670
|
+
*/
|
|
1671
|
+
setFilters(filters: Partial<Filters>): void;
|
|
1672
|
+
/**
|
|
1673
|
+
* Set sort state and reload.
|
|
1674
|
+
*/
|
|
1675
|
+
setSort(sort: SortState): void;
|
|
1676
|
+
/**
|
|
1677
|
+
* Restrict query to visible sources and reload.
|
|
1678
|
+
* Pass `undefined` to include all sources.
|
|
1679
|
+
*/
|
|
1680
|
+
setSources(sources: string[] | undefined): void;
|
|
1681
|
+
/**
|
|
1682
|
+
* Clear all filters and sort, then reload.
|
|
1683
|
+
*/
|
|
1684
|
+
resetFilters(): void;
|
|
1685
|
+
/**
|
|
1686
|
+
* One-time fetch of filter option dictionaries for sidebar filter controls.
|
|
1687
|
+
*/
|
|
1688
|
+
fetchFilterOptions(): void;
|
|
1689
|
+
getFilterOptions(): FilterOptionsResponse | null;
|
|
1690
|
+
get onEdit(): (params: EditParams, options?: ServerCallOptions) => Promise<EditResponse | void>;
|
|
1691
|
+
get filters(): Record<string, unknown>;
|
|
1692
|
+
get sort(): SortState;
|
|
1693
|
+
get sources(): string[] | undefined;
|
|
1694
|
+
get onSourceRemove(): ((params: SourceRemoveParams) => Promise<void>) | undefined;
|
|
1695
|
+
get onColumnDelete(): ((params: ColumnDeleteParams) => Promise<EditResponse | void>) | undefined;
|
|
1696
|
+
get onColumnEdit(): ((params: ColumnEditParams) => Promise<EditResponse | void>) | undefined;
|
|
1697
|
+
get hasExport(): boolean;
|
|
1698
|
+
private _exportAbortController;
|
|
1699
|
+
export(format: DataEditorFormat, allRows: boolean, rtl: boolean): Promise<void>;
|
|
1700
|
+
clear(): void;
|
|
1701
|
+
destroy(): void;
|
|
1702
|
+
}
|
|
1703
|
+
|
|
1704
|
+
/**
|
|
1705
|
+
* A post-resolution selection rectangle in stable coordinate space.
|
|
1706
|
+
* Produced by grid-layer resolvers from CellRange[] in grid-index space.
|
|
1707
|
+
* Consumed by DataStore operations and server sync.
|
|
1708
|
+
*/
|
|
1709
|
+
type SelectionRect = {
|
|
1710
|
+
readonly fields: readonly string[];
|
|
1711
|
+
readonly rowIds: readonly TRowId[];
|
|
1712
|
+
};
|
|
1713
|
+
|
|
1714
|
+
/**
|
|
1715
|
+
* ServerEditBuilder — Stateless coordinate translator for server-delegated edits.
|
|
1716
|
+
*
|
|
1717
|
+
* Converts frontend coordinates (TRowId, column index, grid ranges) into
|
|
1718
|
+
* `EditParams` with `Region[]` that the server can interpret.
|
|
1719
|
+
*
|
|
1720
|
+
* Does NOT call `onEdit`. Only builds params.
|
|
1721
|
+
* DataStore calls the builder, then sends the result to the server.
|
|
1722
|
+
*
|
|
1723
|
+
* Responsibilities:
|
|
1724
|
+
* - TRowId → ServerRowId translation via primaryKey
|
|
1725
|
+
* - Grid index → column ID translation via columns array
|
|
1726
|
+
* - Filter/sort context attachment from ServerDataManager
|
|
1727
|
+
*/
|
|
1728
|
+
|
|
1729
|
+
type ServerEditDeps<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1730
|
+
getPrimaryKey: () => string;
|
|
1731
|
+
getRowById: (id: TRowId) => TRow | undefined;
|
|
1732
|
+
getColumnIds: () => string[];
|
|
1733
|
+
getFilters: () => Record<string, unknown>;
|
|
1734
|
+
getSort: () => SortState;
|
|
1735
|
+
getLockedColumns: () => ReadonlyMap<string, ColumnLockMode>;
|
|
1736
|
+
};
|
|
1737
|
+
declare class ServerEditBuilder<TRow extends DataEditorRow = DataEditorRow> {
|
|
1738
|
+
private readonly _deps;
|
|
1739
|
+
constructor(deps: ServerEditDeps<TRow>);
|
|
1740
|
+
resolveServerRowId(rowId: TRowId): ServerRowId | undefined;
|
|
1741
|
+
buildRegion(rowIds: TRowId[], columnIds: string[]): Region;
|
|
1742
|
+
/**
|
|
1743
|
+
* Collapse rowIds × columnIds into minimal Region[].
|
|
1744
|
+
* - All columns → omit column fields (row-only regions).
|
|
1745
|
+
* - Contiguous columns in schema order → single fromColumn/toColumn span.
|
|
1746
|
+
* - Non-contiguous → one region per contiguous column group.
|
|
1747
|
+
* Rows are expressed as fromRow/toRow using first/last of the provided array.
|
|
1748
|
+
*/
|
|
1749
|
+
buildRegions(rowIds: TRowId[], columnIds: string[]): Region[];
|
|
1750
|
+
/**
|
|
1751
|
+
* Collapse columnIds into minimal column-only Region[] (all rows implied).
|
|
1752
|
+
* - All columns → `{ allSelected: true }`.
|
|
1753
|
+
* - Contiguous in schema order → single `{ fromColumn, toColumn }`.
|
|
1754
|
+
* - Non-contiguous → one region per contiguous group.
|
|
1755
|
+
*/
|
|
1756
|
+
buildColumnRegions(columnIds: string[]): Region[];
|
|
1757
|
+
/**
|
|
1758
|
+
* Build minimal Region[] from multiple selection rectangles.
|
|
1759
|
+
* Each rect is collapsed independently, preserving disjoint selections.
|
|
1760
|
+
*/
|
|
1761
|
+
buildRegionsFromRects(rects: SelectionRect[]): Region[];
|
|
1762
|
+
buildAllSelectedRegion(): Region;
|
|
1763
|
+
buildColumnRegion(columnId: string): Region;
|
|
1764
|
+
buildRowRegion(fromRowId: TRowId, toRowId: TRowId): Region;
|
|
1765
|
+
cellEdit(rowId: TRowId, field: string, value: unknown): EditParams;
|
|
1766
|
+
clear(target: Region[]): EditParams;
|
|
1767
|
+
paste(source: Region[], target: Region[], cut?: boolean): EditParams;
|
|
1768
|
+
pasteExternal(target: Region[], values: unknown[][]): EditParams;
|
|
1769
|
+
fill(source: Region[], target: Region[]): EditParams;
|
|
1770
|
+
transform(target: Region[], transform: TransformParams): EditParams;
|
|
1771
|
+
deleteRows(rowRanges: [TRowId, TRowId][]): EditParams;
|
|
1772
|
+
restoreRows(rowRanges: [TRowId, TRowId][]): EditParams;
|
|
1773
|
+
deleteAllRows(): EditParams;
|
|
1774
|
+
restoreAllRows(): EditParams;
|
|
1775
|
+
insertRow(anchorRowId: TRowId | undefined, position: InsertParams["position"], values: unknown[][], columnIds: string[]): EditParams;
|
|
1776
|
+
/**
|
|
1777
|
+
* Returns null when all columns are selected (caller decides representation).
|
|
1778
|
+
* Otherwise returns contiguous column spans as `{ fromColumn, toColumn }` regions.
|
|
1779
|
+
*/
|
|
1780
|
+
private collapseColumns;
|
|
1781
|
+
private viewContext;
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1562
1784
|
/**
|
|
1563
1785
|
* DirtyTracker — Change classification and revert detection for rows.
|
|
1564
1786
|
*
|
|
@@ -1979,89 +2201,6 @@ type FillSpec = {
|
|
|
1979
2201
|
rowIdToFillIndex: ReadonlyMap<TRowId, number>;
|
|
1980
2202
|
};
|
|
1981
2203
|
|
|
1982
|
-
type FormulaCellContext = {
|
|
1983
|
-
value: unknown;
|
|
1984
|
-
field: string;
|
|
1985
|
-
rowId: TRowId;
|
|
1986
|
-
getField: (field: string) => unknown;
|
|
1987
|
-
/**
|
|
1988
|
-
* Positional arguments for expression-compiled formulas.
|
|
1989
|
-
* Populated by the expression evaluator when invoking multi-arg function
|
|
1990
|
-
* calls. Single-arg formulas (UPPER, TRIM, etc.) still read from `value`.
|
|
1991
|
-
* Undefined for all non-expression call sites — existing code is unaffected.
|
|
1992
|
-
*/
|
|
1993
|
-
args?: readonly unknown[];
|
|
1994
|
-
};
|
|
1995
|
-
type FormulaParamType = "string" | "number" | "boolean" | "select";
|
|
1996
|
-
type FormulaParam = {
|
|
1997
|
-
name: string;
|
|
1998
|
-
label: string;
|
|
1999
|
-
type: FormulaParamType;
|
|
2000
|
-
required?: boolean;
|
|
2001
|
-
defaultValue?: unknown;
|
|
2002
|
-
options?: Array<{
|
|
2003
|
-
id: string;
|
|
2004
|
-
text: string;
|
|
2005
|
-
}>;
|
|
2006
|
-
};
|
|
2007
|
-
type ColumnInputKind = "single" | "multiple";
|
|
2008
|
-
type ColumnInput = {
|
|
2009
|
-
name: string;
|
|
2010
|
-
label: string;
|
|
2011
|
-
kind: ColumnInputKind;
|
|
2012
|
-
required?: boolean;
|
|
2013
|
-
};
|
|
2014
|
-
type FormulaCategory = "text" | "number" | "logic" | "custom";
|
|
2015
|
-
type FormulaArity = {
|
|
2016
|
-
/** Minimum number of positional arguments. 0 means "callable with no args". */
|
|
2017
|
-
min: number;
|
|
2018
|
-
/** Maximum number of positional arguments. Use Number.POSITIVE_INFINITY for variadic. */
|
|
2019
|
-
max: number;
|
|
2020
|
-
};
|
|
2021
|
-
type FormulaBase = {
|
|
2022
|
-
name: string;
|
|
2023
|
-
label: string;
|
|
2024
|
-
category: FormulaCategory;
|
|
2025
|
-
description?: string;
|
|
2026
|
-
columns?: ColumnInput[];
|
|
2027
|
-
params: FormulaParam[];
|
|
2028
|
-
/**
|
|
2029
|
-
* The call signature of this formula when invoked from the expression
|
|
2030
|
-
* language. Required. For shortcut formulas (UPPER, TRIM, ...) use
|
|
2031
|
-
* { min: 1, max: 1 }. For CLEAR use { min: 0, max: 0 }. For MERGE use
|
|
2032
|
-
* { min: 2, max: Number.POSITIVE_INFINITY }.
|
|
2033
|
-
*/
|
|
2034
|
-
arity: FormulaArity;
|
|
2035
|
-
/** Parameter signature shown in autocomplete, without the function name. e.g. "(text, count)" */
|
|
2036
|
-
syntax?: string;
|
|
2037
|
-
/**
|
|
2038
|
-
* Whether this formula may be invoked from the expression parser.
|
|
2039
|
-
* Defaults to true when omitted. MERGE and SPLIT set this to false
|
|
2040
|
-
* because they have dedicated modals that supply their non-expression
|
|
2041
|
-
* params (column lists, separator, ...).
|
|
2042
|
-
*/
|
|
2043
|
-
expressionCallable?: boolean;
|
|
2044
|
-
};
|
|
2045
|
-
type CellFormula = FormulaBase & {
|
|
2046
|
-
kind: "cell";
|
|
2047
|
-
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => unknown;
|
|
2048
|
-
};
|
|
2049
|
-
type RowFormula = FormulaBase & {
|
|
2050
|
-
kind: "row";
|
|
2051
|
-
targetFields: (params: Record<string, unknown>) => string[];
|
|
2052
|
-
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => Record<string, unknown>;
|
|
2053
|
-
};
|
|
2054
|
-
type FormulaDefinition = CellFormula | RowFormula;
|
|
2055
|
-
|
|
2056
|
-
declare class FormulaRegistry {
|
|
2057
|
-
private readonly formulas;
|
|
2058
|
-
register(formula: FormulaDefinition): void;
|
|
2059
|
-
get(name: string): FormulaDefinition | undefined;
|
|
2060
|
-
getAll(): FormulaDefinition[];
|
|
2061
|
-
getByCategory(category: string): FormulaDefinition[];
|
|
2062
|
-
getExpressionCallable(): FormulaDefinition[];
|
|
2063
|
-
}
|
|
2064
|
-
|
|
2065
2204
|
/**
|
|
2066
2205
|
* Paste-level delta computations.
|
|
2067
2206
|
*
|
|
@@ -2086,144 +2225,6 @@ type PasteSpec = {
|
|
|
2086
2225
|
isCut: boolean;
|
|
2087
2226
|
};
|
|
2088
2227
|
|
|
2089
|
-
/**
|
|
2090
|
-
* A single operation the LLM wants to apply to rows in the current filtered view.
|
|
2091
|
-
*
|
|
2092
|
-
* - `edit` — `fn` is `(r, ctx) => void`. Mutates `r` in place. Changed fields
|
|
2093
|
-
* become column deltas. Rows with no changes are no-ops.
|
|
2094
|
-
* - `delete` — `fn` is `(r, ctx) => boolean`. Truthy means "flag this row for
|
|
2095
|
-
* deletion". Soft delete via `DeleteRowCommand`.
|
|
2096
|
-
*/
|
|
2097
|
-
type ChatOp = {
|
|
2098
|
-
action: "edit";
|
|
2099
|
-
fn: string;
|
|
2100
|
-
} | {
|
|
2101
|
-
action: "delete";
|
|
2102
|
-
fn: string;
|
|
2103
|
-
};
|
|
2104
|
-
/**
|
|
2105
|
-
* A single chunk in the stream returned from `DataEditorChat.onMessage`.
|
|
2106
|
-
*
|
|
2107
|
-
* - `status` — progress message shown while processing (e.g. "Analyzing 500 rows...").
|
|
2108
|
-
* - `message` — chat reply shown to the user.
|
|
2109
|
-
* - `rows` — updated rows to apply to the grid. Matched by `primaryKey`.
|
|
2110
|
-
* - `ops` — array of per-row operations (edits and/or deletes) to apply in order.
|
|
2111
|
-
*/
|
|
2112
|
-
type ChatResponseChunk<TRow extends DataEditorRow = DataEditorRow> = {
|
|
2113
|
-
type: "status";
|
|
2114
|
-
content: string;
|
|
2115
|
-
} | {
|
|
2116
|
-
type: "message";
|
|
2117
|
-
content: string;
|
|
2118
|
-
} | {
|
|
2119
|
-
type: "rows";
|
|
2120
|
-
content: TRow[];
|
|
2121
|
-
} | {
|
|
2122
|
-
type: "ops";
|
|
2123
|
-
content: ChatOp[];
|
|
2124
|
-
};
|
|
2125
|
-
/** Status of a row in the chat sample, relative to its origin snapshot. */
|
|
2126
|
-
type ChatRowStatus = "new" | "edited" | "original";
|
|
2127
|
-
/** A sample row handed to the chat callback, with its current status and validation errors. */
|
|
2128
|
-
type ChatRow<TRow extends DataEditorRow = DataEditorRow> = {
|
|
2129
|
-
/** Row data keyed by column ID. */
|
|
2130
|
-
data: TRow;
|
|
2131
|
-
/** Whether the row was newly added, edited, or is unchanged. */
|
|
2132
|
-
status: ChatRowStatus;
|
|
2133
|
-
/** Validation errors keyed by column ID. */
|
|
2134
|
-
errors: Record<string, string[]>;
|
|
2135
|
-
/** The source this row belongs to. */
|
|
2136
|
-
source: string;
|
|
2137
|
-
};
|
|
2138
|
-
/** Aggregated error count across the current view, grouped by field and message. */
|
|
2139
|
-
type ChatErrorSummary = {
|
|
2140
|
-
/** Column ID where the error occurred. */
|
|
2141
|
-
field: string;
|
|
2142
|
-
/** The validation message. */
|
|
2143
|
-
message: string;
|
|
2144
|
-
/** How many rows hit this error. */
|
|
2145
|
-
count: number;
|
|
2146
|
-
/** A few example values that triggered the error. */
|
|
2147
|
-
examples: string[];
|
|
2148
|
-
};
|
|
2149
|
-
/**
|
|
2150
|
-
* Context about the current dataset, passed to `loadSuggestions` and extended
|
|
2151
|
-
* into `ChatContext` for `onMessage`.
|
|
2152
|
-
*/
|
|
2153
|
-
type ChatDataContext<TRow extends DataEditorRow = DataEditorRow> = {
|
|
2154
|
-
/** Full column definitions. */
|
|
2155
|
-
columns: DataEditorColumn[];
|
|
2156
|
-
/** Row identifier field. */
|
|
2157
|
-
primaryKey: keyof TRow;
|
|
2158
|
-
/** Total rows in the dataset. */
|
|
2159
|
-
totalRowCount: number;
|
|
2160
|
-
/** Rows in the current filtered view. */
|
|
2161
|
-
filteredRowCount: number;
|
|
2162
|
-
/** Sample rows, with status and errors. Size controlled by `sampleSize`. */
|
|
2163
|
-
sample: ChatRow<TRow>[];
|
|
2164
|
-
/** Aggregated error counts by field and message. */
|
|
2165
|
-
errorSummary: ChatErrorSummary[];
|
|
2166
|
-
/** Access all rows. Use for full-dataset operations. */
|
|
2167
|
-
getRows: () => ChatRow<TRow>[];
|
|
2168
|
-
};
|
|
2169
|
-
/**
|
|
2170
|
-
* The full context passed to `DataEditorChat.onMessage` when the user sends
|
|
2171
|
-
* a prompt. Includes the prompt itself and all dataset context.
|
|
2172
|
-
*/
|
|
2173
|
-
type ChatContext<TRow extends DataEditorRow = DataEditorRow> = ChatDataContext<TRow> & {
|
|
2174
|
-
/** The user's chat prompt. */
|
|
2175
|
-
message: string;
|
|
2176
|
-
};
|
|
2177
|
-
/**
|
|
2178
|
-
* Bring-your-own-AI chat configuration. When provided via the `chat` prop,
|
|
2179
|
-
* the editor shows a chat panel alongside the grid. You own the AI
|
|
2180
|
-
* integration; the SDK hands you dataset context and renders the streamed
|
|
2181
|
-
* response.
|
|
2182
|
-
*
|
|
2183
|
-
* @example
|
|
2184
|
-
* ```ts
|
|
2185
|
-
* chat={{
|
|
2186
|
-
* sampleSize: 50,
|
|
2187
|
-
* onMessage: async function* (context) {
|
|
2188
|
-
* yield { type: "status", content: "Thinking..." };
|
|
2189
|
-
* const res = await fetch("/api/ai", {
|
|
2190
|
-
* method: "POST",
|
|
2191
|
-
* body: JSON.stringify({
|
|
2192
|
-
* prompt: context.message,
|
|
2193
|
-
* columns: context.columns,
|
|
2194
|
-
* sample: context.sample.map(r => r.data),
|
|
2195
|
-
* errors: context.errorSummary,
|
|
2196
|
-
* }),
|
|
2197
|
-
* }).then(r => r.json());
|
|
2198
|
-
* yield { type: "rows", content: res.updatedRows };
|
|
2199
|
-
* yield { type: "ops", content: res.ops };
|
|
2200
|
-
* yield { type: "message", content: res.reply };
|
|
2201
|
-
* },
|
|
2202
|
-
* }}
|
|
2203
|
-
* ```
|
|
2204
|
-
*/
|
|
2205
|
-
type DataEditorChat<TRow extends DataEditorRow = DataEditorRow> = {
|
|
2206
|
-
/**
|
|
2207
|
-
* How many rows to include in the context sample. The SDK picks a
|
|
2208
|
-
* representative slice including rows with errors. When omitted, the SDK decides.
|
|
2209
|
-
*/
|
|
2210
|
-
sampleSize?: number;
|
|
2211
|
-
/** Title shown above the suggestion list when the chat is empty. */
|
|
2212
|
-
emptyTitle?: string;
|
|
2213
|
-
/** How many suggestions to request from `loadSuggestions`. */
|
|
2214
|
-
suggestionsCount?: number;
|
|
2215
|
-
/** Optional prompt generator for the empty-state suggestion chips. */
|
|
2216
|
-
loadSuggestions?: (context: ChatDataContext<TRow>) => Promise<string[]>;
|
|
2217
|
-
/**
|
|
2218
|
-
* Called when the user sends a message. Receives full dataset context.
|
|
2219
|
-
* Returns an async iterable of response chunks — the SDK streams them
|
|
2220
|
-
* into the UI.
|
|
2221
|
-
*/
|
|
2222
|
-
onMessage: (context: ChatContext<TRow>) => AsyncIterable<ChatResponseChunk<TRow>>;
|
|
2223
|
-
/** Called when the user cancels a pending request. Use to abort your API call. */
|
|
2224
|
-
onCancel?: () => void;
|
|
2225
|
-
};
|
|
2226
|
-
|
|
2227
2228
|
type ApplyFormulaOptions = {
|
|
2228
2229
|
/**
|
|
2229
2230
|
* Column IDs to delete AFTER the formula has been applied.
|
|
@@ -2314,11 +2315,15 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
|
|
|
2314
2315
|
private _dynamicColumns;
|
|
2315
2316
|
private _effectiveColumns;
|
|
2316
2317
|
private _lastColumnsInput;
|
|
2318
|
+
private _addedOptions;
|
|
2319
|
+
private withAddedOptions;
|
|
2320
|
+
private rebuildEffectiveColumns;
|
|
2317
2321
|
setSchemaColumns(columns: DataEditorColumn[]): void;
|
|
2318
2322
|
getDynamicColumns(): DataEditorColumn[];
|
|
2319
2323
|
getEffectiveColumns: () => DataEditorColumn[];
|
|
2320
2324
|
setDynamicColumns(fn: (prev: DataEditorColumn[]) => DataEditorColumn[]): void;
|
|
2321
2325
|
addDynamicColumns(columns: DataEditorColumn[]): void;
|
|
2326
|
+
addColumnOptions(columnId: string, values: string[]): void;
|
|
2322
2327
|
setColumns(columns: DataEditorColumn[]): void;
|
|
2323
2328
|
subscribe: (listener: () => void) => (() => void);
|
|
2324
2329
|
getSnapshot: () => DataStoreSnapshot;
|