@updog/data-editor 0.1.41 → 0.1.42
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.d.ts +480 -464
- package/index.js +3038 -2880
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -498,7 +498,14 @@ declare var export_default = {
|
|
|
498
498
|
selectValuePlaceholder: "Select value",
|
|
499
499
|
showMatched: "Show matched",
|
|
500
500
|
allMatched: "All values are matched",
|
|
501
|
-
unmatchedWarning:
|
|
501
|
+
unmatchedWarning:
|
|
502
|
+
"Unmatched values won't be imported. Match this value to keep the data. You can edit values after importing.",
|
|
503
|
+
createOption: "Create option",
|
|
504
|
+
createOptionTitle: "Create option",
|
|
505
|
+
createOptionNameLabel: "Option name",
|
|
506
|
+
createOptionNamePlaceholder: "Enter option name",
|
|
507
|
+
createOptionNameTaken: "This option already exists",
|
|
508
|
+
createOptionSubmit: "Create",
|
|
502
509
|
},
|
|
503
510
|
primaryKey: {
|
|
504
511
|
title: "Select primary key",
|
|
@@ -720,6 +727,11 @@ type SelectEditorCell = {
|
|
|
720
727
|
type: "select";
|
|
721
728
|
/** The list of options shown in the dropdown. Each string is both the stored value and the display label. */
|
|
722
729
|
options: string[];
|
|
730
|
+
/**
|
|
731
|
+
* Let users add options via "Create option" (matching step + grid); never
|
|
732
|
+
* created implicitly. Defaults to true; false for a strict closed enum.
|
|
733
|
+
*/
|
|
734
|
+
enableCustomValue?: boolean;
|
|
723
735
|
};
|
|
724
736
|
/** Number input cell with locale-aware formatting. */
|
|
725
737
|
type NumberEditorCell = {
|
|
@@ -1246,78 +1258,6 @@ declare class ChunkedProcessor<T> {
|
|
|
1246
1258
|
cancel(): void;
|
|
1247
1259
|
}
|
|
1248
1260
|
|
|
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
1261
|
/**
|
|
1322
1262
|
* Internal contract: the surface a Scale client exposes to the SDK's data
|
|
1323
1263
|
* layer. Implemented by `ScaleClient`. Not part of the public SDK API —
|
|
@@ -1340,185 +1280,143 @@ type ScaleClientApi<TRow extends DataEditorRow = DataEditorRow, TFilters = Recor
|
|
|
1340
1280
|
scrollSensitivity?: number;
|
|
1341
1281
|
};
|
|
1342
1282
|
|
|
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
1283
|
/**
|
|
1444
|
-
* A
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1284
|
+
* A single operation the LLM wants to apply to rows in the current filtered view.
|
|
1285
|
+
*
|
|
1286
|
+
* - `edit` — `fn` is `(r, ctx) => void`. Mutates `r` in place. Changed fields
|
|
1287
|
+
* become column deltas. Rows with no changes are no-ops.
|
|
1288
|
+
* - `delete` — `fn` is `(r, ctx) => boolean`. Truthy means "flag this row for
|
|
1289
|
+
* deletion". Soft delete via `DeleteRowCommand`.
|
|
1447
1290
|
*/
|
|
1448
|
-
type
|
|
1449
|
-
|
|
1450
|
-
|
|
1291
|
+
type ChatOp = {
|
|
1292
|
+
action: "edit";
|
|
1293
|
+
fn: string;
|
|
1294
|
+
} | {
|
|
1295
|
+
action: "delete";
|
|
1296
|
+
fn: string;
|
|
1451
1297
|
};
|
|
1452
|
-
|
|
1453
1298
|
/**
|
|
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.
|
|
1299
|
+
* A single chunk in the stream returned from `DataEditorChat.onMessage`.
|
|
1461
1300
|
*
|
|
1462
|
-
*
|
|
1463
|
-
*
|
|
1464
|
-
*
|
|
1465
|
-
*
|
|
1301
|
+
* - `status` — progress message shown while processing (e.g. "Analyzing 500 rows...").
|
|
1302
|
+
* - `message` — chat reply shown to the user.
|
|
1303
|
+
* - `rows` — updated rows to apply to the grid. Matched by `primaryKey`.
|
|
1304
|
+
* - `ops` — array of per-row operations (edits and/or deletes) to apply in order.
|
|
1466
1305
|
*/
|
|
1467
|
-
|
|
1468
|
-
type
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1306
|
+
type ChatResponseChunk<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1307
|
+
type: "status";
|
|
1308
|
+
content: string;
|
|
1309
|
+
} | {
|
|
1310
|
+
type: "message";
|
|
1311
|
+
content: string;
|
|
1312
|
+
} | {
|
|
1313
|
+
type: "rows";
|
|
1314
|
+
content: TRow[];
|
|
1315
|
+
} | {
|
|
1316
|
+
type: "ops";
|
|
1317
|
+
content: ChatOp[];
|
|
1475
1318
|
};
|
|
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
|
-
|
|
1319
|
+
/** Status of a row in the chat sample, relative to its origin snapshot. */
|
|
1320
|
+
type ChatRowStatus = "new" | "edited" | "original";
|
|
1321
|
+
/** A sample row handed to the chat callback, with its current status and validation errors. */
|
|
1322
|
+
type ChatRow<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1323
|
+
/** Row data keyed by column ID. */
|
|
1324
|
+
data: TRow;
|
|
1325
|
+
/** Whether the row was newly added, edited, or is unchanged. */
|
|
1326
|
+
status: ChatRowStatus;
|
|
1327
|
+
/** Validation errors keyed by column ID. */
|
|
1328
|
+
errors: Record<string, string[]>;
|
|
1329
|
+
/** The source this row belongs to. */
|
|
1330
|
+
source: string;
|
|
1331
|
+
};
|
|
1332
|
+
/** Aggregated error count across the current view, grouped by field and message. */
|
|
1333
|
+
type ChatErrorSummary = {
|
|
1334
|
+
/** Column ID where the error occurred. */
|
|
1335
|
+
field: string;
|
|
1336
|
+
/** The validation message. */
|
|
1337
|
+
message: string;
|
|
1338
|
+
/** How many rows hit this error. */
|
|
1339
|
+
count: number;
|
|
1340
|
+
/** A few example values that triggered the error. */
|
|
1341
|
+
examples: string[];
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Context about the current dataset, passed to `loadSuggestions` and extended
|
|
1345
|
+
* into `ChatContext` for `onMessage`.
|
|
1346
|
+
*/
|
|
1347
|
+
type ChatDataContext<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1348
|
+
/** Full column definitions. */
|
|
1349
|
+
columns: DataEditorColumn[];
|
|
1350
|
+
/** Row identifier field. */
|
|
1351
|
+
primaryKey: keyof TRow;
|
|
1352
|
+
/** Total rows in the dataset. */
|
|
1353
|
+
totalRowCount: number;
|
|
1354
|
+
/** Rows in the current filtered view. */
|
|
1355
|
+
filteredRowCount: number;
|
|
1356
|
+
/** Sample rows, with status and errors. Size controlled by `sampleSize`. */
|
|
1357
|
+
sample: ChatRow<TRow>[];
|
|
1358
|
+
/** Aggregated error counts by field and message. */
|
|
1359
|
+
errorSummary: ChatErrorSummary[];
|
|
1360
|
+
/** Access all rows. Use for full-dataset operations. */
|
|
1361
|
+
getRows: () => ChatRow<TRow>[];
|
|
1362
|
+
};
|
|
1363
|
+
/**
|
|
1364
|
+
* The full context passed to `DataEditorChat.onMessage` when the user sends
|
|
1365
|
+
* a prompt. Includes the prompt itself and all dataset context.
|
|
1366
|
+
*/
|
|
1367
|
+
type ChatContext<TRow extends DataEditorRow = DataEditorRow> = ChatDataContext<TRow> & {
|
|
1368
|
+
/** The user's chat prompt. */
|
|
1369
|
+
message: string;
|
|
1370
|
+
};
|
|
1371
|
+
/**
|
|
1372
|
+
* Bring-your-own-AI chat configuration. When provided via the `chat` prop,
|
|
1373
|
+
* the editor shows a chat panel alongside the grid. You own the AI
|
|
1374
|
+
* integration; the SDK hands you dataset context and renders the streamed
|
|
1375
|
+
* response.
|
|
1376
|
+
*
|
|
1377
|
+
* @example
|
|
1378
|
+
* ```ts
|
|
1379
|
+
* chat={{
|
|
1380
|
+
* sampleSize: 50,
|
|
1381
|
+
* onMessage: async function* (context) {
|
|
1382
|
+
* yield { type: "status", content: "Thinking..." };
|
|
1383
|
+
* const res = await fetch("/api/ai", {
|
|
1384
|
+
* method: "POST",
|
|
1385
|
+
* body: JSON.stringify({
|
|
1386
|
+
* prompt: context.message,
|
|
1387
|
+
* columns: context.columns,
|
|
1388
|
+
* sample: context.sample.map(r => r.data),
|
|
1389
|
+
* errors: context.errorSummary,
|
|
1390
|
+
* }),
|
|
1391
|
+
* }).then(r => r.json());
|
|
1392
|
+
* yield { type: "rows", content: res.updatedRows };
|
|
1393
|
+
* yield { type: "ops", content: res.ops };
|
|
1394
|
+
* yield { type: "message", content: res.reply };
|
|
1395
|
+
* },
|
|
1396
|
+
* }}
|
|
1397
|
+
* ```
|
|
1398
|
+
*/
|
|
1399
|
+
type DataEditorChat<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1515
1400
|
/**
|
|
1516
|
-
*
|
|
1517
|
-
*
|
|
1401
|
+
* How many rows to include in the context sample. The SDK picks a
|
|
1402
|
+
* representative slice including rows with errors. When omitted, the SDK decides.
|
|
1518
1403
|
*/
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1404
|
+
sampleSize?: number;
|
|
1405
|
+
/** Title shown above the suggestion list when the chat is empty. */
|
|
1406
|
+
emptyTitle?: string;
|
|
1407
|
+
/** How many suggestions to request from `loadSuggestions`. */
|
|
1408
|
+
suggestionsCount?: number;
|
|
1409
|
+
/** Optional prompt generator for the empty-state suggestion chips. */
|
|
1410
|
+
loadSuggestions?: (context: ChatDataContext<TRow>) => Promise<string[]>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Called when the user sends a message. Receives full dataset context.
|
|
1413
|
+
* Returns an async iterable of response chunks — the SDK streams them
|
|
1414
|
+
* into the UI.
|
|
1415
|
+
*/
|
|
1416
|
+
onMessage: (context: ChatContext<TRow>) => AsyncIterable<ChatResponseChunk<TRow>>;
|
|
1417
|
+
/** Called when the user cancels a pending request. Use to abort your API call. */
|
|
1418
|
+
onCancel?: () => void;
|
|
1419
|
+
};
|
|
1522
1420
|
|
|
1523
1421
|
/**
|
|
1524
1422
|
* Categories of internal errors surfaced through the `onError` callback.
|
|
@@ -1559,6 +1457,341 @@ declare class ErrorHandler {
|
|
|
1559
1457
|
handleError(error: UpdogError): void;
|
|
1560
1458
|
}
|
|
1561
1459
|
|
|
1460
|
+
type FormulaCellContext = {
|
|
1461
|
+
value: unknown;
|
|
1462
|
+
field: string;
|
|
1463
|
+
rowId: TRowId;
|
|
1464
|
+
getField: (field: string) => unknown;
|
|
1465
|
+
/**
|
|
1466
|
+
* Positional arguments for expression-compiled formulas.
|
|
1467
|
+
* Populated by the expression evaluator when invoking multi-arg function
|
|
1468
|
+
* calls. Single-arg formulas (UPPER, TRIM, etc.) still read from `value`.
|
|
1469
|
+
* Undefined for all non-expression call sites — existing code is unaffected.
|
|
1470
|
+
*/
|
|
1471
|
+
args?: readonly unknown[];
|
|
1472
|
+
};
|
|
1473
|
+
type FormulaParamType = "string" | "number" | "boolean" | "select";
|
|
1474
|
+
type FormulaParam = {
|
|
1475
|
+
name: string;
|
|
1476
|
+
label: string;
|
|
1477
|
+
type: FormulaParamType;
|
|
1478
|
+
required?: boolean;
|
|
1479
|
+
defaultValue?: unknown;
|
|
1480
|
+
options?: Array<{
|
|
1481
|
+
id: string;
|
|
1482
|
+
text: string;
|
|
1483
|
+
}>;
|
|
1484
|
+
};
|
|
1485
|
+
type ColumnInputKind = "single" | "multiple";
|
|
1486
|
+
type ColumnInput = {
|
|
1487
|
+
name: string;
|
|
1488
|
+
label: string;
|
|
1489
|
+
kind: ColumnInputKind;
|
|
1490
|
+
required?: boolean;
|
|
1491
|
+
};
|
|
1492
|
+
type FormulaCategory = "text" | "number" | "logic" | "custom";
|
|
1493
|
+
type FormulaArity = {
|
|
1494
|
+
/** Minimum number of positional arguments. 0 means "callable with no args". */
|
|
1495
|
+
min: number;
|
|
1496
|
+
/** Maximum number of positional arguments. Use Number.POSITIVE_INFINITY for variadic. */
|
|
1497
|
+
max: number;
|
|
1498
|
+
};
|
|
1499
|
+
type FormulaBase = {
|
|
1500
|
+
name: string;
|
|
1501
|
+
label: string;
|
|
1502
|
+
category: FormulaCategory;
|
|
1503
|
+
description?: string;
|
|
1504
|
+
columns?: ColumnInput[];
|
|
1505
|
+
params: FormulaParam[];
|
|
1506
|
+
/**
|
|
1507
|
+
* The call signature of this formula when invoked from the expression
|
|
1508
|
+
* language. Required. For shortcut formulas (UPPER, TRIM, ...) use
|
|
1509
|
+
* { min: 1, max: 1 }. For CLEAR use { min: 0, max: 0 }. For MERGE use
|
|
1510
|
+
* { min: 2, max: Number.POSITIVE_INFINITY }.
|
|
1511
|
+
*/
|
|
1512
|
+
arity: FormulaArity;
|
|
1513
|
+
/** Parameter signature shown in autocomplete, without the function name. e.g. "(text, count)" */
|
|
1514
|
+
syntax?: string;
|
|
1515
|
+
/**
|
|
1516
|
+
* Whether this formula may be invoked from the expression parser.
|
|
1517
|
+
* Defaults to true when omitted. MERGE and SPLIT set this to false
|
|
1518
|
+
* because they have dedicated modals that supply their non-expression
|
|
1519
|
+
* params (column lists, separator, ...).
|
|
1520
|
+
*/
|
|
1521
|
+
expressionCallable?: boolean;
|
|
1522
|
+
};
|
|
1523
|
+
type CellFormula = FormulaBase & {
|
|
1524
|
+
kind: "cell";
|
|
1525
|
+
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => unknown;
|
|
1526
|
+
};
|
|
1527
|
+
type RowFormula = FormulaBase & {
|
|
1528
|
+
kind: "row";
|
|
1529
|
+
targetFields: (params: Record<string, unknown>) => string[];
|
|
1530
|
+
compute: (ctx: FormulaCellContext, params: Record<string, unknown>) => Record<string, unknown>;
|
|
1531
|
+
};
|
|
1532
|
+
type FormulaDefinition = CellFormula | RowFormula;
|
|
1533
|
+
|
|
1534
|
+
declare class FormulaRegistry {
|
|
1535
|
+
private readonly formulas;
|
|
1536
|
+
register(formula: FormulaDefinition): void;
|
|
1537
|
+
get(name: string): FormulaDefinition | undefined;
|
|
1538
|
+
getAll(): FormulaDefinition[];
|
|
1539
|
+
getByCategory(category: string): FormulaDefinition[];
|
|
1540
|
+
getExpressionCallable(): FormulaDefinition[];
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
type RegisterSourceOptions = {
|
|
1544
|
+
name: string;
|
|
1545
|
+
id?: DataSourceId;
|
|
1546
|
+
isDeletable?: boolean;
|
|
1547
|
+
isInitialData?: boolean;
|
|
1548
|
+
};
|
|
1549
|
+
type MergeEntry<TRow> = {
|
|
1550
|
+
row: TRow;
|
|
1551
|
+
sourceId: DataSourceId;
|
|
1552
|
+
isNew: boolean;
|
|
1553
|
+
isEdited: boolean;
|
|
1554
|
+
};
|
|
1555
|
+
type RemovalPlan<TRow> = {
|
|
1556
|
+
rowsToDelete: Set<TRowId>;
|
|
1557
|
+
rowsToRestore: Array<{
|
|
1558
|
+
rowId: TRowId;
|
|
1559
|
+
row: TRow;
|
|
1560
|
+
originalSourceId: DataSourceId;
|
|
1561
|
+
isNew: boolean;
|
|
1562
|
+
isEdited: boolean;
|
|
1563
|
+
}>;
|
|
1564
|
+
};
|
|
1565
|
+
type ExtendedRemovalPlan<TRow> = RemovalPlan<TRow> & {
|
|
1566
|
+
sourceId: DataSourceId;
|
|
1567
|
+
repairedEntries: Array<{
|
|
1568
|
+
sourceId: DataSourceId;
|
|
1569
|
+
rowId: TRowId;
|
|
1570
|
+
before: MergeEntry<TRow>;
|
|
1571
|
+
after: MergeEntry<TRow> | null;
|
|
1572
|
+
}>;
|
|
1573
|
+
};
|
|
1574
|
+
declare class SourceManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1575
|
+
private readonly _defaultSourceId;
|
|
1576
|
+
private readonly overrides;
|
|
1577
|
+
private readonly sources;
|
|
1578
|
+
private readonly mergedRows;
|
|
1579
|
+
getSourceId(rowId: TRowId): DataSourceId;
|
|
1580
|
+
setSourceId(rowId: TRowId, sourceId: DataSourceId): void;
|
|
1581
|
+
deleteSourceId(rowId: TRowId): void;
|
|
1582
|
+
getOverrides(): ReadonlyMap<TRowId, DataSourceId>;
|
|
1583
|
+
register(options: RegisterSourceOptions): DataSourceId;
|
|
1584
|
+
/**
|
|
1585
|
+
* Re-insert a source using a full captured state, preserving
|
|
1586
|
+
* isVisible, isLoading, rowCount, etc. Used by SourceLifecycle.restore.
|
|
1587
|
+
* If the source already exists, overwrites its state.
|
|
1588
|
+
*/
|
|
1589
|
+
restoreState(state: DataSourceState): void;
|
|
1590
|
+
has(sourceId: DataSourceId): boolean;
|
|
1591
|
+
get(sourceId: DataSourceId): DataSourceState | undefined;
|
|
1592
|
+
delete(sourceId: DataSourceId): void;
|
|
1593
|
+
setLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1594
|
+
finalizeAllSources(): void;
|
|
1595
|
+
values(): IterableIterator<DataSourceState>;
|
|
1596
|
+
getHiddenSourceIds(): Set<DataSourceId>;
|
|
1597
|
+
saveMergeSnapshot(sourceId: DataSourceId, rowId: TRowId, existingRow: TRow, previousSourceId: DataSourceId, isNew: boolean, isEdited: boolean): void;
|
|
1598
|
+
/**
|
|
1599
|
+
* Public so commands can re-install merge entries during undo of a remove.
|
|
1600
|
+
*/
|
|
1601
|
+
restoreMergeEntry(sourceId: DataSourceId, rowId: TRowId, entry: MergeEntry<TRow>): void;
|
|
1602
|
+
/**
|
|
1603
|
+
* Pure — computes the full removal plan without mutating any state.
|
|
1604
|
+
* Callers run applyRemovalPlan(plan) to commit.
|
|
1605
|
+
*/
|
|
1606
|
+
planRemoval(sourceId: DataSourceId): ExtendedRemovalPlan<TRow> | null;
|
|
1607
|
+
/**
|
|
1608
|
+
* Mutates internal state per plan produced by planRemoval.
|
|
1609
|
+
*/
|
|
1610
|
+
applyRemovalPlan(plan: ExtendedRemovalPlan<TRow>): void;
|
|
1611
|
+
clear(): void;
|
|
1612
|
+
private getUniqueName;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
type ServerDataManagerDeps<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1616
|
+
clear(): void;
|
|
1617
|
+
setLoading(isLoading: boolean): void;
|
|
1618
|
+
registerSource(options: RegisterSourceOptions): DataSourceId;
|
|
1619
|
+
setSourceLoading(sourceId: DataSourceId, isLoading: boolean): void;
|
|
1620
|
+
getLocalRowCount(): number;
|
|
1621
|
+
replaceServerRows(sourceId: DataSourceId, rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1622
|
+
appendServerRows(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1623
|
+
prependServerRows(rows: ServerRow<TRow>[], offset: number, counts?: ServerQueryCounts): void;
|
|
1624
|
+
applyServerRowMeta(rows: ServerRow<TRow>[], counts?: ServerQueryCounts): void;
|
|
1625
|
+
};
|
|
1626
|
+
type FetchDirection = "forward" | "backward" | "jump";
|
|
1627
|
+
declare class ServerDataManager<TRow extends DataEditorRow = DataEditorRow> {
|
|
1628
|
+
private _offset;
|
|
1629
|
+
private _totalCount;
|
|
1630
|
+
private _isFetching;
|
|
1631
|
+
private readonly _pageSize;
|
|
1632
|
+
private readonly _maxBufferRows;
|
|
1633
|
+
private _filters;
|
|
1634
|
+
private _sources;
|
|
1635
|
+
private _sort;
|
|
1636
|
+
private _filterOptions;
|
|
1637
|
+
private _filterOptionsFetched;
|
|
1638
|
+
private _abortController;
|
|
1639
|
+
private _syncAbort;
|
|
1640
|
+
private _lastVisibleStart;
|
|
1641
|
+
private _debouncedFetch;
|
|
1642
|
+
private readonly _config;
|
|
1643
|
+
private readonly _dataStoreRef;
|
|
1644
|
+
private readonly _sourceLabel;
|
|
1645
|
+
private _onChanged;
|
|
1646
|
+
constructor(config: ScaleClientApi<TRow>, dataStoreRef: ServerDataManagerDeps<TRow>, sourceLabel: string);
|
|
1647
|
+
get offset(): number;
|
|
1648
|
+
get totalCount(): number | null;
|
|
1649
|
+
get isFetching(): boolean;
|
|
1650
|
+
get pageSize(): number;
|
|
1651
|
+
get maxBufferRows(): number;
|
|
1652
|
+
setOnChanged(callback: () => void): void;
|
|
1653
|
+
setOffset(offset: number): void;
|
|
1654
|
+
setTotalCount(count: number): void;
|
|
1655
|
+
private setFetching;
|
|
1656
|
+
getExcess(currentCount: number, newCount: number): number;
|
|
1657
|
+
shouldFetch(visibleStart: number, visibleEnd: number, loadedCount: number): FetchDirection | null;
|
|
1658
|
+
/**
|
|
1659
|
+
* Full reload — abort in-flight, clear store, fetch first page.
|
|
1660
|
+
* Called on initial load, search/filter/sort changes, and resetFilters.
|
|
1661
|
+
*/
|
|
1662
|
+
reload(): void;
|
|
1663
|
+
/**
|
|
1664
|
+
* Scroll-driven pagination with velocity-based debouncing.
|
|
1665
|
+
* Called from CanvasGrid on every scroll event.
|
|
1666
|
+
*/
|
|
1667
|
+
handleScroll(visibleStart: number, visibleEnd: number): void;
|
|
1668
|
+
/**
|
|
1669
|
+
* Fetch a single page based on scroll position and current window state.
|
|
1670
|
+
*/
|
|
1671
|
+
private fetchPage;
|
|
1672
|
+
/**
|
|
1673
|
+
* Re-query the current viewport and replace row data, metadata, and counts.
|
|
1674
|
+
* Called after successful edits and find-and-replace mutations.
|
|
1675
|
+
* Each call aborts the previous in-flight sync.
|
|
1676
|
+
*/
|
|
1677
|
+
syncCurrentView(): void;
|
|
1678
|
+
/**
|
|
1679
|
+
* Merge filter keys into server filter state and reload.
|
|
1680
|
+
* Called by DataStore.setFilters() in server mode and by filter components.
|
|
1681
|
+
*/
|
|
1682
|
+
setFilters(filters: Partial<Filters>): void;
|
|
1683
|
+
/**
|
|
1684
|
+
* Set sort state and reload.
|
|
1685
|
+
*/
|
|
1686
|
+
setSort(sort: SortState): void;
|
|
1687
|
+
/**
|
|
1688
|
+
* Restrict query to visible sources and reload.
|
|
1689
|
+
* Pass `undefined` to include all sources.
|
|
1690
|
+
*/
|
|
1691
|
+
setSources(sources: string[] | undefined): void;
|
|
1692
|
+
/**
|
|
1693
|
+
* Clear all filters and sort, then reload.
|
|
1694
|
+
*/
|
|
1695
|
+
resetFilters(): void;
|
|
1696
|
+
/**
|
|
1697
|
+
* One-time fetch of filter option dictionaries for sidebar filter controls.
|
|
1698
|
+
*/
|
|
1699
|
+
fetchFilterOptions(): void;
|
|
1700
|
+
getFilterOptions(): FilterOptionsResponse | null;
|
|
1701
|
+
get onEdit(): (params: EditParams, options?: ServerCallOptions) => Promise<EditResponse | void>;
|
|
1702
|
+
get filters(): Record<string, unknown>;
|
|
1703
|
+
get sort(): SortState;
|
|
1704
|
+
get sources(): string[] | undefined;
|
|
1705
|
+
get onSourceRemove(): ((params: SourceRemoveParams) => Promise<void>) | undefined;
|
|
1706
|
+
get onColumnDelete(): ((params: ColumnDeleteParams) => Promise<EditResponse | void>) | undefined;
|
|
1707
|
+
get onColumnEdit(): ((params: ColumnEditParams) => Promise<EditResponse | void>) | undefined;
|
|
1708
|
+
get hasExport(): boolean;
|
|
1709
|
+
private _exportAbortController;
|
|
1710
|
+
export(format: DataEditorFormat, allRows: boolean, rtl: boolean): Promise<void>;
|
|
1711
|
+
clear(): void;
|
|
1712
|
+
destroy(): void;
|
|
1713
|
+
}
|
|
1714
|
+
|
|
1715
|
+
/**
|
|
1716
|
+
* A post-resolution selection rectangle in stable coordinate space.
|
|
1717
|
+
* Produced by grid-layer resolvers from CellRange[] in grid-index space.
|
|
1718
|
+
* Consumed by DataStore operations and server sync.
|
|
1719
|
+
*/
|
|
1720
|
+
type SelectionRect = {
|
|
1721
|
+
readonly fields: readonly string[];
|
|
1722
|
+
readonly rowIds: readonly TRowId[];
|
|
1723
|
+
};
|
|
1724
|
+
|
|
1725
|
+
/**
|
|
1726
|
+
* ServerEditBuilder — Stateless coordinate translator for server-delegated edits.
|
|
1727
|
+
*
|
|
1728
|
+
* Converts frontend coordinates (TRowId, column index, grid ranges) into
|
|
1729
|
+
* `EditParams` with `Region[]` that the server can interpret.
|
|
1730
|
+
*
|
|
1731
|
+
* Does NOT call `onEdit`. Only builds params.
|
|
1732
|
+
* DataStore calls the builder, then sends the result to the server.
|
|
1733
|
+
*
|
|
1734
|
+
* Responsibilities:
|
|
1735
|
+
* - TRowId → ServerRowId translation via primaryKey
|
|
1736
|
+
* - Grid index → column ID translation via columns array
|
|
1737
|
+
* - Filter/sort context attachment from ServerDataManager
|
|
1738
|
+
*/
|
|
1739
|
+
|
|
1740
|
+
type ServerEditDeps<TRow extends DataEditorRow = DataEditorRow> = {
|
|
1741
|
+
getPrimaryKey: () => string;
|
|
1742
|
+
getRowById: (id: TRowId) => TRow | undefined;
|
|
1743
|
+
getColumnIds: () => string[];
|
|
1744
|
+
getFilters: () => Record<string, unknown>;
|
|
1745
|
+
getSort: () => SortState;
|
|
1746
|
+
getLockedColumns: () => ReadonlyMap<string, ColumnLockMode>;
|
|
1747
|
+
};
|
|
1748
|
+
declare class ServerEditBuilder<TRow extends DataEditorRow = DataEditorRow> {
|
|
1749
|
+
private readonly _deps;
|
|
1750
|
+
constructor(deps: ServerEditDeps<TRow>);
|
|
1751
|
+
resolveServerRowId(rowId: TRowId): ServerRowId | undefined;
|
|
1752
|
+
buildRegion(rowIds: TRowId[], columnIds: string[]): Region;
|
|
1753
|
+
/**
|
|
1754
|
+
* Collapse rowIds × columnIds into minimal Region[].
|
|
1755
|
+
* - All columns → omit column fields (row-only regions).
|
|
1756
|
+
* - Contiguous columns in schema order → single fromColumn/toColumn span.
|
|
1757
|
+
* - Non-contiguous → one region per contiguous column group.
|
|
1758
|
+
* Rows are expressed as fromRow/toRow using first/last of the provided array.
|
|
1759
|
+
*/
|
|
1760
|
+
buildRegions(rowIds: TRowId[], columnIds: string[]): Region[];
|
|
1761
|
+
/**
|
|
1762
|
+
* Collapse columnIds into minimal column-only Region[] (all rows implied).
|
|
1763
|
+
* - All columns → `{ allSelected: true }`.
|
|
1764
|
+
* - Contiguous in schema order → single `{ fromColumn, toColumn }`.
|
|
1765
|
+
* - Non-contiguous → one region per contiguous group.
|
|
1766
|
+
*/
|
|
1767
|
+
buildColumnRegions(columnIds: string[]): Region[];
|
|
1768
|
+
/**
|
|
1769
|
+
* Build minimal Region[] from multiple selection rectangles.
|
|
1770
|
+
* Each rect is collapsed independently, preserving disjoint selections.
|
|
1771
|
+
*/
|
|
1772
|
+
buildRegionsFromRects(rects: SelectionRect[]): Region[];
|
|
1773
|
+
buildAllSelectedRegion(): Region;
|
|
1774
|
+
buildColumnRegion(columnId: string): Region;
|
|
1775
|
+
buildRowRegion(fromRowId: TRowId, toRowId: TRowId): Region;
|
|
1776
|
+
cellEdit(rowId: TRowId, field: string, value: unknown): EditParams;
|
|
1777
|
+
clear(target: Region[]): EditParams;
|
|
1778
|
+
paste(source: Region[], target: Region[], cut?: boolean): EditParams;
|
|
1779
|
+
pasteExternal(target: Region[], values: unknown[][]): EditParams;
|
|
1780
|
+
fill(source: Region[], target: Region[]): EditParams;
|
|
1781
|
+
transform(target: Region[], transform: TransformParams): EditParams;
|
|
1782
|
+
deleteRows(rowRanges: [TRowId, TRowId][]): EditParams;
|
|
1783
|
+
restoreRows(rowRanges: [TRowId, TRowId][]): EditParams;
|
|
1784
|
+
deleteAllRows(): EditParams;
|
|
1785
|
+
restoreAllRows(): EditParams;
|
|
1786
|
+
insertRow(anchorRowId: TRowId | undefined, position: InsertParams["position"], values: unknown[][], columnIds: string[]): EditParams;
|
|
1787
|
+
/**
|
|
1788
|
+
* Returns null when all columns are selected (caller decides representation).
|
|
1789
|
+
* Otherwise returns contiguous column spans as `{ fromColumn, toColumn }` regions.
|
|
1790
|
+
*/
|
|
1791
|
+
private collapseColumns;
|
|
1792
|
+
private viewContext;
|
|
1793
|
+
}
|
|
1794
|
+
|
|
1562
1795
|
/**
|
|
1563
1796
|
* DirtyTracker — Change classification and revert detection for rows.
|
|
1564
1797
|
*
|
|
@@ -1979,89 +2212,6 @@ type FillSpec = {
|
|
|
1979
2212
|
rowIdToFillIndex: ReadonlyMap<TRowId, number>;
|
|
1980
2213
|
};
|
|
1981
2214
|
|
|
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
2215
|
/**
|
|
2066
2216
|
* Paste-level delta computations.
|
|
2067
2217
|
*
|
|
@@ -2086,144 +2236,6 @@ type PasteSpec = {
|
|
|
2086
2236
|
isCut: boolean;
|
|
2087
2237
|
};
|
|
2088
2238
|
|
|
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
2239
|
type ApplyFormulaOptions = {
|
|
2228
2240
|
/**
|
|
2229
2241
|
* Column IDs to delete AFTER the formula has been applied.
|
|
@@ -2314,11 +2326,15 @@ declare class DataStore<TRow extends DataEditorRow = DataEditorRow> {
|
|
|
2314
2326
|
private _dynamicColumns;
|
|
2315
2327
|
private _effectiveColumns;
|
|
2316
2328
|
private _lastColumnsInput;
|
|
2329
|
+
private _addedOptions;
|
|
2330
|
+
private withAddedOptions;
|
|
2331
|
+
private rebuildEffectiveColumns;
|
|
2317
2332
|
setSchemaColumns(columns: DataEditorColumn[]): void;
|
|
2318
2333
|
getDynamicColumns(): DataEditorColumn[];
|
|
2319
2334
|
getEffectiveColumns: () => DataEditorColumn[];
|
|
2320
2335
|
setDynamicColumns(fn: (prev: DataEditorColumn[]) => DataEditorColumn[]): void;
|
|
2321
2336
|
addDynamicColumns(columns: DataEditorColumn[]): void;
|
|
2337
|
+
addColumnOptions(columnId: string, values: string[]): void;
|
|
2322
2338
|
setColumns(columns: DataEditorColumn[]): void;
|
|
2323
2339
|
subscribe: (listener: () => void) => (() => void);
|
|
2324
2340
|
getSnapshot: () => DataStoreSnapshot;
|