grist-widget-sdk 0.3.27 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +1 -1
  3. package/dist/app.cjs +1139 -4336
  4. package/dist/app.cjs.map +1 -1
  5. package/dist/app.d.cts +1 -3
  6. package/dist/app.d.ts +1 -3
  7. package/dist/app.js +3 -7
  8. package/dist/chunk-4ZGVKGDF.js +204 -0
  9. package/dist/chunk-4ZGVKGDF.js.map +1 -0
  10. package/dist/{chunk-YQNMIL33.js → chunk-B5ZZNLVS.js} +528 -181
  11. package/dist/chunk-B5ZZNLVS.js.map +1 -0
  12. package/dist/chunk-O7NY46QY.js +1830 -0
  13. package/dist/chunk-O7NY46QY.js.map +1 -0
  14. package/dist/{chunk-6Y2IONGJ.js → chunk-P6VTEKWO.js} +113 -14
  15. package/dist/chunk-P6VTEKWO.js.map +1 -0
  16. package/dist/emulator/testing.cjs +1504 -4822
  17. package/dist/emulator/testing.cjs.map +1 -1
  18. package/dist/emulator/testing.d.cts +3 -6
  19. package/dist/emulator/testing.d.ts +3 -6
  20. package/dist/emulator/testing.js +7 -20
  21. package/dist/emulator/testing.js.map +1 -1
  22. package/dist/emulator.cjs +59 -249
  23. package/dist/emulator.cjs.map +1 -1
  24. package/dist/emulator.d.cts +3 -5
  25. package/dist/emulator.d.ts +3 -5
  26. package/dist/emulator.js +5 -11
  27. package/dist/index.cjs +1373 -4859
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +81 -260
  30. package/dist/index.d.ts +81 -260
  31. package/dist/index.js +8 -158
  32. package/dist/{inline-DpcT8tV9.d.ts → templates-CGmRIQBV.d.cts} +89 -35
  33. package/dist/{inline-C7DkvuET.d.cts → templates-Cq94qOcf.d.ts} +89 -35
  34. package/dist/{types-D3JxUCfL.d.cts → types-DBStn0Dk.d.cts} +2 -26
  35. package/dist/{types-D3JxUCfL.d.ts → types-DBStn0Dk.d.ts} +2 -26
  36. package/dist/use-grist-BK0eke9K.d.cts +358 -0
  37. package/dist/use-grist-C5DMZ3wU.d.ts +358 -0
  38. package/package.json +8 -37
  39. package/dist/advanced.cjs +0 -2799
  40. package/dist/advanced.cjs.map +0 -1
  41. package/dist/advanced.d.cts +0 -822
  42. package/dist/advanced.d.ts +0 -822
  43. package/dist/advanced.js +0 -872
  44. package/dist/advanced.js.map +0 -1
  45. package/dist/chunk-22U7WAY3.js +0 -463
  46. package/dist/chunk-22U7WAY3.js.map +0 -1
  47. package/dist/chunk-64SVRWW7.js +0 -758
  48. package/dist/chunk-64SVRWW7.js.map +0 -1
  49. package/dist/chunk-6Y2IONGJ.js.map +0 -1
  50. package/dist/chunk-B4AKVSWV.js +0 -2362
  51. package/dist/chunk-B4AKVSWV.js.map +0 -1
  52. package/dist/chunk-ELGVOHFD.js +0 -32
  53. package/dist/chunk-ELGVOHFD.js.map +0 -1
  54. package/dist/chunk-GTTD5HPO.js +0 -36
  55. package/dist/chunk-GTTD5HPO.js.map +0 -1
  56. package/dist/chunk-NO6FYX33.js +0 -2084
  57. package/dist/chunk-NO6FYX33.js.map +0 -1
  58. package/dist/chunk-OPTOYD2Y.js +0 -277
  59. package/dist/chunk-OPTOYD2Y.js.map +0 -1
  60. package/dist/chunk-PM3B4WYV.js +0 -12
  61. package/dist/chunk-PM3B4WYV.js.map +0 -1
  62. package/dist/chunk-REV5AUXD.js +0 -25
  63. package/dist/chunk-REV5AUXD.js.map +0 -1
  64. package/dist/chunk-YQNMIL33.js.map +0 -1
  65. package/dist/create-grist-emulator-BCqp1BF9.d.ts +0 -81
  66. package/dist/create-grist-emulator-DBM8OSIR.d.cts +0 -81
  67. package/dist/emulator/devtools.cjs +0 -1404
  68. package/dist/emulator/devtools.cjs.map +0 -1
  69. package/dist/emulator/devtools.d.cts +0 -48
  70. package/dist/emulator/devtools.d.ts +0 -48
  71. package/dist/emulator/devtools.js +0 -506
  72. package/dist/emulator/devtools.js.map +0 -1
  73. package/dist/emulator/transports.cjs +0 -1132
  74. package/dist/emulator/transports.cjs.map +0 -1
  75. package/dist/emulator/transports.d.cts +0 -38
  76. package/dist/emulator/transports.d.ts +0 -38
  77. package/dist/emulator/transports.js +0 -12
  78. package/dist/emulator/transports.js.map +0 -1
  79. package/dist/templates-8k2LKoO-.d.cts +0 -24
  80. package/dist/templates-DIwi_mvI.d.ts +0 -24
  81. package/dist/use-grist-reads-DUMvJgV7.d.ts +0 -480
  82. package/dist/use-grist-reads-DpjVuI0H.d.cts +0 -480
  83. package/dist/use-grist-types-DdOLEJXN.d.cts +0 -499
  84. package/dist/use-grist-types-kwxoFeub.d.ts +0 -499
  85. package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.cts +0 -43
  86. package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.ts +0 -43
@@ -0,0 +1,358 @@
1
+ import { e as GristReplicaColumn, f as GristRowRecord, i as GristReadyOptions, j as GristFetchSelectedOptions, k as GristTableOperations, o as GristApplyUserActionsOptions, c as GristCursorPos, b as GristWidgetColumnMap } from './types-DBStn0Dk.js';
2
+
3
+ type ValidateColumnMappingsResult = {
4
+ ok: boolean;
5
+ /**
6
+ * `true` while the host has not yet reported column mappings (e.g. between
7
+ * `grist.ready()` resolving and the first `onRecord` / `onRecords` callback,
8
+ * or before `sectionApi.mappings()` returns). Callers should not gate UI or
9
+ * emit mapping alerts while pending.
10
+ */
11
+ pending?: boolean;
12
+ /** Logical names of required columns the user has not yet mapped. */
13
+ missing: string[];
14
+ /** Logical names of `allowMultiple` columns mapped to an empty list. */
15
+ emptyMultiples: string[];
16
+ };
17
+
18
+ type GristNoiseColumnsOptions = {
19
+ excludeId?: boolean;
20
+ excludeGristHelpers?: boolean;
21
+ excludeLoggingColumns?: boolean;
22
+ /**
23
+ * When `true`, treat Grist's `manualSort` column as noise (omit from filtered replicas).
24
+ * Default `false` — `manualSort` is kept unless you opt in.
25
+ */
26
+ excludeManualSort?: boolean;
27
+ };
28
+
29
+ type GristFetchedAttachmentBlob = {
30
+ blob: Blob;
31
+ contentType: string;
32
+ };
33
+ /**
34
+ * All attachment ids found in a Grist attachment cell value (ordered, deduped).
35
+ * Attachment columns are usually an **array** of file refs; a single id or one JSON object is also supported.
36
+ */
37
+ declare function extractGristAttachmentIdsFromCell(value: unknown): string[];
38
+ /** First attachment id in the cell, if any (see {@link extractGristAttachmentIdsFromCell}). */
39
+ declare function extractGristAttachmentId(value: unknown): string | undefined;
40
+
41
+ type GristEncodedAttachmentList = ["L", ...(number | string)[]];
42
+ type GristAttachmentUploadResult = {
43
+ /** All attachment ids returned by `POST /attachments`. */
44
+ ids: string[];
45
+ /** First id in `ids` (convenience for single-file uploads). */
46
+ firstId: string;
47
+ };
48
+ /** Wire value for an Attachments cell (Grist list encoding). */
49
+ declare function gristAttachmentCellValues(attachmentIds: (string | number)[]): GristEncodedAttachmentList;
50
+ /** Wire value for a single-file Attachments cell. */
51
+ declare function gristAttachmentCellValue(attachmentId: string | number): GristEncodedAttachmentList;
52
+ /**
53
+ * Merge new attachment ids into an existing Attachments cell value (deduped, order preserved).
54
+ */
55
+ declare function mergeGristAttachmentCellValue(existingCell: unknown, newIds: (string | number)[]): GristEncodedAttachmentList;
56
+
57
+ /** Column-oriented table payload (`fetchTable`, `fetchSelectedTable`): `{ id: [...], Name: [...] }`. */
58
+ type GristColumnarTable = Record<string, unknown[]>;
59
+ type GristTableRowsOrder = "none" | "id" | "grist";
60
+ type FetchGristTableRowsOptions = {
61
+ /** Column metadata, to decode each cell (except `id`) with `decodeGristValue`. */
62
+ columns?: Record<string, GristReplicaColumn>;
63
+ /**
64
+ * Row order:
65
+ * - `grist` (default): `manualSort` ascending when present, then `id`.
66
+ * - `id`: numeric `id` ascending.
67
+ * - `none`: as `fetchTable` returned them.
68
+ */
69
+ order?: GristTableRowsOrder;
70
+ };
71
+ /** Turn `fetchTable` output into row objects (order follows the `id` column). */
72
+ declare function tableDataToRows<T = Record<string, unknown>>(data: GristColumnarTable): GristRowRecord<T>[];
73
+
74
+ /**
75
+ * Grist `docApi.applyUserActions` payloads are arrays of user-action tuples.
76
+ * @see https://support.getgrist.com/code/interfaces/grist_plugin_api.GristDocAPI/#applyuseractions
77
+ */
78
+ type GristUserActionTuple = unknown[];
79
+ /** `["UpdateRecord", tableId, rowId, { col: value, ... }]` */
80
+ declare function gristUpdateRecordAction(tableId: string, rowId: number, patch: Record<string, unknown>): GristUserActionTuple;
81
+ /** `["AddRecord", tableId, null, { col: value, ... }]` */
82
+ declare function gristAddRecordAction(tableId: string, values: Record<string, unknown>): GristUserActionTuple;
83
+ /** `["RemoveRecord", tableId, rowId]` */
84
+ declare function gristRemoveRecordAction(tableId: string, rowId: number): GristUserActionTuple;
85
+ /** `["AddColumn", tableId, colId, colInfo]` — `colInfo` shape depends on Grist version / column type. */
86
+ declare function gristAddColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple;
87
+ /** `["AddVisibleColumn", tableId, colId, colInfo]` — like `AddColumn` but also adds the column to the current view section. */
88
+ declare function gristAddVisibleColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple;
89
+ /** `["RenameColumn", tableId, colId, newColId]` */
90
+ declare function gristRenameColumnAction(tableId: string, colId: string, newColId: string): GristUserActionTuple;
91
+ /** `["ModifyColumn", tableId, colId, colInfo]` */
92
+ declare function gristModifyColumnAction(tableId: string, colId: string, colInfo: Record<string, unknown>): GristUserActionTuple;
93
+ /** `["RemoveColumn", tableId, colId]` */
94
+ declare function gristRemoveColumnAction(tableId: string, colId: string): GristUserActionTuple;
95
+ /** `["AddTable", tableId, tableInfo]` */
96
+ declare function gristAddTableAction(tableId: string, tableInfo: Record<string, unknown>): GristUserActionTuple;
97
+
98
+ /**
99
+ * Typed reads, with read-only access: each mapped cell checked against the
100
+ * type its column declares in `GRIST_OPTIONS.columns`.
101
+ *
102
+ * Grist's mapping panel only offers the columns of the declared type, so for
103
+ * a mapped column the declaration is the contract; and the plugin API's
104
+ * decoded values already say what they are (a `Date`, a `Reference` with a
105
+ * `rowId`, a list of ids, a `RaisedException` for a formula error, the raw
106
+ * text of an invalid cell). Checked in Grist 1.7.22, every type, both
107
+ * `cellFormat`s. So a cell is turned into the JS value its type promises, or
108
+ * into `null` with an issue: no schema to fetch, no full access, no
109
+ * dependency.
110
+ */
111
+
112
+ /** A mapped cell that didn't match its declared type, or a rule of the widget's schema. */
113
+ type GristCellIssue = {
114
+ rowId: number;
115
+ /** The declared column name, or "" for a schema rule on the whole record. */
116
+ column: string;
117
+ message: string;
118
+ /** The value Grist sent. */
119
+ value: unknown;
120
+ };
121
+ type Check = {
122
+ ok: true;
123
+ value: unknown;
124
+ } | {
125
+ ok: false;
126
+ message: string;
127
+ };
128
+ /**
129
+ * `value` as its declared `type` promises ("Numeric", "Ref:Tasks",
130
+ * "Text,Ref"…): a match of any listed type, or a failure that says why.
131
+ * Without a type (or "Any"), the value as it is.
132
+ */
133
+ declare function checkGristCell(type: string | undefined, value: unknown): Check;
134
+ /** Minimal Standard Schema (https://standardschema.dev): zod 4, valibot, arktype implement it. */
135
+ type StandardSchema<T = unknown> = {
136
+ readonly "~standard": {
137
+ readonly version: 1;
138
+ readonly vendor: string;
139
+ readonly validate: (value: unknown) => {
140
+ readonly value: T;
141
+ readonly issues?: undefined;
142
+ } | {
143
+ readonly issues: ReadonlyArray<{
144
+ readonly message: string;
145
+ readonly path?: ReadonlyArray<PropertyKey | {
146
+ key: PropertyKey;
147
+ }>;
148
+ }>;
149
+ } | Promise<unknown>;
150
+ };
151
+ };
152
+ type BaseOf<T extends string> = T extends `${infer B}:${string}` ? B : T;
153
+ type CellOf<T extends string> = T extends `${infer A},${infer Rest}` ? CellOf<A> | CellOf<Rest> : BaseOf<T> extends "Text" ? string : BaseOf<T> extends "Numeric" | "Int" ? number | null : BaseOf<T> extends "Bool" ? boolean : BaseOf<T> extends "Date" | "DateTime" ? Date | null : BaseOf<T> extends "Choice" ? string | null : BaseOf<T> extends "ChoiceList" ? string[] : BaseOf<T> extends "Ref" ? number | null : BaseOf<T> extends "RefList" | "Attachments" ? number[] : unknown;
154
+ type ColumnValue<C> = C extends {
155
+ type: infer T extends string;
156
+ allowMultiple: true;
157
+ } ? CellOf<T>[] : C extends {
158
+ type: infer T extends string;
159
+ } ? CellOf<T> : C extends {
160
+ allowMultiple: true;
161
+ } ? unknown[] : unknown;
162
+ type RequiredName<C> = C extends {
163
+ optional: true;
164
+ } ? never : C extends string ? C : C extends {
165
+ name: infer N extends string;
166
+ } ? N : never;
167
+ type OptionalName<C> = C extends {
168
+ optional: true;
169
+ name: infer N extends string;
170
+ } ? N : never;
171
+ type ByName<Cs, N> = Extract<Cs, N | {
172
+ name: N;
173
+ }>;
174
+ /**
175
+ * The mapped record a `GRIST_OPTIONS` declaration gives, for `useGrist`'s
176
+ * second type argument. Declare the options with `as const satisfies
177
+ * UseGristOptions` so the column names and types stay literal:
178
+ *
179
+ * ```ts
180
+ * export const GRIST_OPTIONS = {
181
+ * requiredAccess: "read table",
182
+ * columns: [{ name: "Title", type: "Text" }, { name: "Due", type: "Date", optional: true }],
183
+ * } as const satisfies UseGristOptions
184
+ *
185
+ * const w = useGrist<GristRowRecord, GristMappedRow<typeof GRIST_OPTIONS>>()
186
+ * w.mappedRecord?.Due // Date | null | undefined
187
+ * ```
188
+ */
189
+ type GristMappedRow<O extends {
190
+ columns?: readonly unknown[];
191
+ }> = O["columns"] extends readonly (infer C)[] ? {
192
+ id: number;
193
+ } & {
194
+ [N in RequiredName<C>]: ColumnValue<ByName<C, N>>;
195
+ } & {
196
+ [N in OptionalName<C>]?: ColumnValue<ByName<C, N>>;
197
+ } : Record<string, unknown>;
198
+
199
+ /**
200
+ * The alerts `mountGristWidget()` shows above a running widget: what needs the
201
+ * user's attention in Grist (column mapping, access, a failed write, an
202
+ * unlinked section). The blocking states (not connected, access refused,
203
+ * required columns unmapped) are `<GristBoundary>`'s, not alerts.
204
+ */
205
+
206
+ type GristSdkAlertKind = "column-mapping" | "mapping-pending" | "section-not-linked" | "source-not-wired" | "action-error" | "access-insufficient" | "map-back-skip" | "cell-issues";
207
+
208
+ /**
209
+ * The widget's connection to Grist: one store, one `connect()`.
210
+ *
211
+ * The template loads `grist-plugin-api.js` with a classic blocking script, so
212
+ * `window.grist` is there when the widget starts, or it never will be: the
213
+ * check is synchronous (with one more look at `load`, for a page that loads
214
+ * the script asynchronously). Then `grist.ready()` once, and every Grist
215
+ * stream (records, options, mappings, theme) feeds one immutable state that
216
+ * React reads through `useSyncExternalStore`. No polling, no heartbeat: the
217
+ * iframe lives and dies with the Grist page, and a failed call fails where it
218
+ * was made.
219
+ */
220
+
221
+ type GristTheme = "light" | "dark";
222
+ type GristWidgetActionStatus = "idle" | "running" | "error";
223
+ /** What a widget asks Grist for (`UseGristOptions`). */
224
+ type GristRuntimeOptions = GristReadyOptions & {
225
+ /** Alert kinds mountGristWidget() never shows for this widget, e.g. ["section-not-linked"]. */
226
+ suppressAlerts?: GristSdkAlertKind[];
227
+ /**
228
+ * Extra rules for the mapped records, as a Standard Schema (zod 4,
229
+ * valibot, arktype…), checked after each cell's declared type. A record
230
+ * that fails keeps its typed values; its issues go to `cellIssues`.
231
+ */
232
+ schema?: StandardSchema;
233
+ };
234
+
235
+ /**
236
+ * `useGrist()`'s methods, created once per runtime: every one is
237
+ * referentially stable for the widget's lifetime, and reads `grist` when
238
+ * called (the emulator installs and removes it in tests).
239
+ */
240
+
241
+ type ListTablesOptions = {
242
+ /** Include Grist's own tables (`_grist_*`, `GristHidden_*`). */
243
+ includeSystem?: boolean;
244
+ };
245
+ type ListColumnsOptions = GristNoiseColumnsOptions & {
246
+ /** Include every column, Grist's helper and bookkeeping ones too. */
247
+ includeSystem?: boolean;
248
+ };
249
+ type GristColumnInfo = {
250
+ colId: string;
251
+ type?: string;
252
+ label?: string;
253
+ isFormula?: boolean;
254
+ formula?: string;
255
+ description?: string;
256
+ };
257
+ type GristApi = {
258
+ reload: () => Promise<void>;
259
+ fetchSelectedTable: (options?: GristFetchSelectedOptions) => Promise<GristColumnarTable>;
260
+ fetchTable: (tableId: string) => Promise<GristColumnarTable>;
261
+ fetchTableRows: <T extends Record<string, unknown> = Record<string, unknown>>(tableId: string, options?: FetchGristTableRowsOptions) => Promise<GristRowRecord<T>[]>;
262
+ listTables: (options?: ListTablesOptions) => Promise<string[]>;
263
+ listColumns: (tableId: string, options?: ListColumnsOptions) => Promise<GristColumnInfo[]>;
264
+ table: GristTableOperations;
265
+ getTable: (tableId: string) => GristTableOperations;
266
+ applyActions: (actions: GristUserActionTuple[], options?: GristApplyUserActionsOptions) => Promise<unknown>;
267
+ setWidgetOptions: (options: Record<string, unknown>) => Promise<void>;
268
+ patchWidgetOptions: (patch: Record<string, unknown>) => Promise<void>;
269
+ setCursorPosition: (pos: GristCursorPos) => Promise<void>;
270
+ setLinkedRowSelection: (rowIds: number[] | null) => Promise<void>;
271
+ getAttachmentUrl: (attachmentId: string, options?: {
272
+ readOnly?: boolean;
273
+ }) => Promise<string>;
274
+ fetchAttachmentBlob: (attachmentId: string, options?: {
275
+ readOnly?: boolean;
276
+ }) => Promise<GristFetchedAttachmentBlob>;
277
+ uploadAttachment: (file: Blob | File, options?: {
278
+ fileName?: string;
279
+ }) => Promise<GristAttachmentUploadResult>;
280
+ fetchWithAuth: (path: string, init?: RequestInit & {
281
+ readOnly?: boolean;
282
+ }) => Promise<Response>;
283
+ };
284
+
285
+ /**
286
+ * What `useGrist()` shows, derived from the runtime state: status, error,
287
+ * column-mapping status, the mapped record, and the access check. Pure
288
+ * functions, so they are tested without React or Grist.
289
+ */
290
+
291
+ /** The widget's connection to Grist, as `useGrist().status` reports it. */
292
+ type GristWidgetStatus = "booting" | "ready" | "unavailable" | "error";
293
+
294
+ /** What the widget asks Grist for: access, columns to map, and the alerts it doesn't want. */
295
+ type UseGristOptions = GristRuntimeOptions;
296
+ /** Derived from the selection: no row, a row, or the add-row placeholder. */
297
+ type GristWidgetMode = "empty" | "row" | "new-row";
298
+ /**
299
+ * The widget's Grist state and API. Every method is referentially stable for
300
+ * the widget's lifetime: safe in effect dependencies. The object itself is
301
+ * new whenever a value changes; depend on the members you use, not on it.
302
+ */
303
+ type UseGristResult<TRow = Record<string, unknown>, TMapped = Record<string, unknown>> = Omit<GristApi, "fetchTableRows"> & {
304
+ /** `"booting"` until Grist answers, then `"ready"`; `"unavailable"` outside Grist; `"error"` otherwise. */
305
+ status: GristWidgetStatus;
306
+ /** Inside Grist with its plugin API (null while connecting). */
307
+ isAvailable: boolean | null;
308
+ isReady: boolean;
309
+ /** Why the widget can't run (status `"error"` or `"unavailable"`), else null. */
310
+ error: string | null;
311
+ /** Grist's light or dark theme, null until Grist sends it. */
312
+ theme: GristTheme | null;
313
+ /** The selected row, raw column ids. */
314
+ record: GristRowRecord<TRow> | null;
315
+ /** The section's rows (what its filters show), raw column ids. */
316
+ records: GristRowRecord<TRow>[] | null;
317
+ /**
318
+ * The selected row under the declared column names, each cell the JS value
319
+ * its declared type promises (a cell that doesn't match is null, and in
320
+ * `cellIssues`); null until every required column is mapped.
321
+ */
322
+ mappedRecord: TMapped | null;
323
+ /** Every row of the section, like `mappedRecord`. */
324
+ mappedRecords: TMapped[] | null;
325
+ /** The mapped cells that didn't match their declared type (or the widget's `schema`), by row. */
326
+ cellIssues: readonly GristCellIssue[];
327
+ /** Declared column name → the Grist column id(s) mapped to it. */
328
+ mappings: GristWidgetColumnMap;
329
+ /** Whether every required declared column is mapped (`pending` until Grist reports mappings). */
330
+ columnMappingStatus: ValidateColumnMappingsResult;
331
+ mode: GristWidgetMode;
332
+ /** The Grist column id mapped to a declared name, or the name itself. */
333
+ resolveMappedColumnId: (name: string) => string;
334
+ /** A patch under declared names, as real column ids for a write (multi-column mappings are skipped). */
335
+ mapBack: (patch: Partial<TMapped>) => Record<string, unknown>;
336
+ /** The section's table id. */
337
+ currentTableId: string | null;
338
+ /** Any table as rows (full access). */
339
+ fetchTableRows: <T extends Record<string, unknown> = Record<string, unknown>>(tableId: string, options?: Parameters<GristApi["fetchTableRows"]>[1]) => Promise<GristRowRecord<T>[]>;
340
+ /** The last write's state. */
341
+ actionStatus: GristWidgetActionStatus;
342
+ actionError: string | null;
343
+ /** The options Grist stores for this widget, null until it sends them. */
344
+ widgetOptions: Record<string, unknown> | null;
345
+ };
346
+ /**
347
+ * The widget's Grist state and API. Inside `<GristWidgetProvider>` it uses the
348
+ * provider's connection and ignores `options`; outside one, the page's, made
349
+ * with the first caller's `options`.
350
+ */
351
+ declare function useGrist<TRow = Record<string, unknown>, TMapped = Record<string, unknown>>(options?: UseGristOptions): UseGristResult<TRow, TMapped>;
352
+ /** `useGrist()` inside a provider, or null outside one: for components that also work without Grist. */
353
+ declare function useGristOptional<TRow = Record<string, unknown>, TMapped = Record<string, unknown>>(): UseGristResult<TRow, TMapped> | null;
354
+ /** `useGrist()` inside `<GristWidgetProvider>`; throws outside one. */
355
+ declare function useGristContext<TRow = Record<string, unknown>, TMapped = Record<string, unknown>>(): UseGristResult<TRow, TMapped>;
356
+
357
+ export { gristRenameColumnAction as A, gristUpdateRecordAction as B, mergeGristAttachmentCellValue as C, tableDataToRows as D, useGrist as E, useGristContext as F, useGristOptional as H, checkGristCell as o, extractGristAttachmentId as p, extractGristAttachmentIdsFromCell as q, gristAddColumnAction as r, gristAddRecordAction as s, gristAddTableAction as t, gristAddVisibleColumnAction as u, gristAttachmentCellValue as v, gristAttachmentCellValues as w, gristModifyColumnAction as x, gristRemoveColumnAction as y, gristRemoveRecordAction as z };
358
+ export type { GristNoiseColumnsOptions as G, ListColumnsOptions as L, StandardSchema as S, UseGristOptions as U, ValidateColumnMappingsResult as V, GristAttachmentUploadResult as a, GristCellIssue as b, GristColumnInfo as c, GristColumnarTable as d, GristFetchedAttachmentBlob as e, GristMappedRow as f, GristSdkAlertKind as g, GristTheme as h, GristUserActionTuple as i, GristWidgetActionStatus as j, GristWidgetMode as k, GristWidgetStatus as l, ListTablesOptions as m, UseGristResult as n };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "grist-widget-sdk",
3
- "version": "0.3.27",
3
+ "version": "0.4.0",
4
4
  "description": "React hooks and helpers for Grist custom widgets",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -40,16 +40,6 @@
40
40
  "default": "./dist/index.cjs"
41
41
  }
42
42
  },
43
- "./advanced": {
44
- "import": {
45
- "types": "./dist/advanced.d.ts",
46
- "default": "./dist/advanced.js"
47
- },
48
- "require": {
49
- "types": "./dist/advanced.d.cts",
50
- "default": "./dist/advanced.cjs"
51
- }
52
- },
53
43
  "./app": {
54
44
  "import": {
55
45
  "types": "./dist/app.d.ts",
@@ -70,16 +60,6 @@
70
60
  "default": "./dist/emulator.cjs"
71
61
  }
72
62
  },
73
- "./emulator/transports": {
74
- "import": {
75
- "types": "./dist/emulator/transports.d.ts",
76
- "default": "./dist/emulator/transports.js"
77
- },
78
- "require": {
79
- "types": "./dist/emulator/transports.d.cts",
80
- "default": "./dist/emulator/transports.cjs"
81
- }
82
- },
83
63
  "./emulator/testing": {
84
64
  "import": {
85
65
  "types": "./dist/emulator/testing.d.ts",
@@ -90,16 +70,6 @@
90
70
  "default": "./dist/emulator/testing.cjs"
91
71
  }
92
72
  },
93
- "./emulator/devtools": {
94
- "import": {
95
- "types": "./dist/emulator/devtools.d.ts",
96
- "default": "./dist/emulator/devtools.js"
97
- },
98
- "require": {
99
- "types": "./dist/emulator/devtools.d.cts",
100
- "default": "./dist/emulator/devtools.cjs"
101
- }
102
- },
103
73
  "./tsconfig/app.json": "./tsconfig/app.json",
104
74
  "./tsconfig/node.json": "./tsconfig/node.json"
105
75
  },
@@ -118,22 +88,22 @@
118
88
  "@testing-library/dom": "^10",
119
89
  "@testing-library/jest-dom": "^7.0.1",
120
90
  "@testing-library/react": "^16.3.3",
121
- "@types/node": "^26.6.5",
91
+ "@types/node": "^26.6.6",
122
92
  "@types/react": "^19.3.0",
123
93
  "@types/react-dom": "^19.3.0",
124
- "@vitejs/plugin-react": "^6.1.2",
125
- "@vitest/coverage-v8": "^5.0.5",
94
+ "@vitejs/plugin-react": "^6.2.1",
95
+ "@vitest/coverage-v8": "^5.1.0",
126
96
  "eslint": "^10.13.0",
127
97
  "eslint-plugin-react-hooks": "^7.1.1",
128
98
  "fast-check": "^4.10.2",
129
- "globals": "^17.13.0",
99
+ "globals": "^17.14.0",
130
100
  "grist-plugin-api": "^0.0.1",
131
101
  "jsdom": "^30.1.3",
132
102
  "tsup": "^9.0.0",
133
103
  "typescript": "^6.0.3",
134
- "typescript-eslint": "^8.72.0",
104
+ "typescript-eslint": "^8.72.1",
135
105
  "vite": "^8.3.5",
136
- "vitest": "^5.0.5"
106
+ "vitest": "^5.1.0"
137
107
  },
138
108
  "dependencies": {
139
109
  "grain-rpc": "^0.1.7",
@@ -147,6 +117,7 @@
147
117
  "test:emulator": "vitest --run --project emulator --passWithNoTests",
148
118
  "test:coverage": "vitest --run --project unit --project emulator --coverage",
149
119
  "bench": "vitest run --project bench",
120
+ "bench:update": "BENCH_UPDATE=1 vitest run --project bench",
150
121
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.vitest.json --noEmit",
151
122
  "lint": "eslint ."
152
123
  }