grist-widget-sdk 0.3.26 → 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 (90) hide show
  1. package/CHANGELOG.md +53 -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 +9 -517
  8. package/dist/app.js.map +1 -1
  9. package/dist/chunk-4ZGVKGDF.js +204 -0
  10. package/dist/chunk-4ZGVKGDF.js.map +1 -0
  11. package/dist/{chunk-YQNMIL33.js → chunk-B5ZZNLVS.js} +528 -181
  12. package/dist/chunk-B5ZZNLVS.js.map +1 -0
  13. package/dist/chunk-O7NY46QY.js +1830 -0
  14. package/dist/chunk-O7NY46QY.js.map +1 -0
  15. package/dist/chunk-P6VTEKWO.js +618 -0
  16. package/dist/chunk-P6VTEKWO.js.map +1 -0
  17. package/dist/emulator/testing.cjs +2084 -391
  18. package/dist/emulator/testing.cjs.map +1 -1
  19. package/dist/emulator/testing.d.cts +55 -7
  20. package/dist/emulator/testing.d.ts +55 -7
  21. package/dist/emulator/testing.js +144 -19
  22. package/dist/emulator/testing.js.map +1 -1
  23. package/dist/emulator.cjs +59 -249
  24. package/dist/emulator.cjs.map +1 -1
  25. package/dist/emulator.d.cts +3 -5
  26. package/dist/emulator.d.ts +3 -5
  27. package/dist/emulator.js +5 -11
  28. package/dist/index.cjs +1373 -4859
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +81 -260
  31. package/dist/index.d.ts +81 -260
  32. package/dist/index.js +8 -161
  33. package/dist/{inline-C7DkvuET.d.cts → templates-CGmRIQBV.d.cts} +89 -35
  34. package/dist/{inline-DpcT8tV9.d.ts → templates-Cq94qOcf.d.ts} +89 -35
  35. package/dist/{types-D3JxUCfL.d.cts → types-DBStn0Dk.d.cts} +2 -26
  36. package/dist/{types-D3JxUCfL.d.ts → types-DBStn0Dk.d.ts} +2 -26
  37. package/dist/use-grist-BK0eke9K.d.cts +358 -0
  38. package/dist/use-grist-C5DMZ3wU.d.ts +358 -0
  39. package/package.json +8 -37
  40. package/dist/advanced.cjs +0 -2799
  41. package/dist/advanced.cjs.map +0 -1
  42. package/dist/advanced.d.cts +0 -822
  43. package/dist/advanced.d.ts +0 -822
  44. package/dist/advanced.js +0 -875
  45. package/dist/advanced.js.map +0 -1
  46. package/dist/chunk-22U7WAY3.js +0 -463
  47. package/dist/chunk-22U7WAY3.js.map +0 -1
  48. package/dist/chunk-64SVRWW7.js +0 -758
  49. package/dist/chunk-64SVRWW7.js.map +0 -1
  50. package/dist/chunk-ELGVOHFD.js +0 -32
  51. package/dist/chunk-ELGVOHFD.js.map +0 -1
  52. package/dist/chunk-EPEBKXVN.js +0 -470
  53. package/dist/chunk-EPEBKXVN.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-JASMM2YC.js +0 -243
  57. package/dist/chunk-JASMM2YC.js.map +0 -1
  58. package/dist/chunk-N3X46JW2.js +0 -37
  59. package/dist/chunk-N3X46JW2.js.map +0 -1
  60. package/dist/chunk-PDGEZ24B.js +0 -2366
  61. package/dist/chunk-PDGEZ24B.js.map +0 -1
  62. package/dist/chunk-PM3B4WYV.js +0 -12
  63. package/dist/chunk-PM3B4WYV.js.map +0 -1
  64. package/dist/chunk-REV5AUXD.js +0 -25
  65. package/dist/chunk-REV5AUXD.js.map +0 -1
  66. package/dist/chunk-TZB3OZA6.js +0 -1630
  67. package/dist/chunk-TZB3OZA6.js.map +0 -1
  68. package/dist/chunk-YQNMIL33.js.map +0 -1
  69. package/dist/create-grist-emulator-BCqp1BF9.d.ts +0 -81
  70. package/dist/create-grist-emulator-DBM8OSIR.d.cts +0 -81
  71. package/dist/emulator/devtools.cjs +0 -1404
  72. package/dist/emulator/devtools.cjs.map +0 -1
  73. package/dist/emulator/devtools.d.cts +0 -48
  74. package/dist/emulator/devtools.d.ts +0 -48
  75. package/dist/emulator/devtools.js +0 -508
  76. package/dist/emulator/devtools.js.map +0 -1
  77. package/dist/emulator/transports.cjs +0 -1132
  78. package/dist/emulator/transports.cjs.map +0 -1
  79. package/dist/emulator/transports.d.cts +0 -38
  80. package/dist/emulator/transports.d.ts +0 -38
  81. package/dist/emulator/transports.js +0 -12
  82. package/dist/emulator/transports.js.map +0 -1
  83. package/dist/templates-8k2LKoO-.d.cts +0 -24
  84. package/dist/templates-DIwi_mvI.d.ts +0 -24
  85. package/dist/use-grist-reads-DUMvJgV7.d.ts +0 -480
  86. package/dist/use-grist-reads-DpjVuI0H.d.cts +0 -480
  87. package/dist/use-grist-types-DdOLEJXN.d.cts +0 -499
  88. package/dist/use-grist-types-kwxoFeub.d.ts +0 -499
  89. package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.cts +0 -43
  90. package/dist/use-grist-widget-options-from-context-CGOlQ5Vc.d.ts +0 -43
@@ -1,508 +0,0 @@
1
- import {
2
- isGristNoiseColumn
3
- } from "../chunk-REV5AUXD.js";
4
- import {
5
- materializeGristRowsFromColumnar,
6
- safeParseRowsToDisplayRows
7
- } from "../chunk-JASMM2YC.js";
8
- import {
9
- gristAccessLevelLabel
10
- } from "../chunk-N3X46JW2.js";
11
- import {
12
- rowsToColumnar
13
- } from "../chunk-ELGVOHFD.js";
14
- import {
15
- resolveMappings
16
- } from "../chunk-PM3B4WYV.js";
17
- import {
18
- gristAddRecordAction,
19
- gristRemoveRecordAction,
20
- gristUpdateRecordAction
21
- } from "../chunk-64SVRWW7.js";
22
-
23
- // src/emulator/devtools/inspector.tsx
24
- import { useState } from "react";
25
-
26
- // src/emulator/devtools/use-emulator-state.ts
27
- import { useSyncExternalStore } from "react";
28
- function useEmulatorSnapshot(emulator) {
29
- const subscribe = (notify) => {
30
- return emulator.bus.on(() => notify());
31
- };
32
- const getSnapshot = () => snapshotKey(emulator);
33
- useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
34
- return {
35
- state: emulator.state,
36
- history: emulator.bus.history()
37
- };
38
- }
39
- function snapshotKey(emulator) {
40
- const history = emulator.bus.history();
41
- const last = history[history.length - 1];
42
- return `${history.length}:${eventTag(last)}`;
43
- }
44
- function eventTag(event) {
45
- if (!event) return "empty";
46
- switch (event.type) {
47
- case "data-change":
48
- return `data:${event.tableId}`;
49
- case "cursor-change":
50
- return `cursor:${event.tableId}:${String(event.rowId)}`;
51
- case "options-change":
52
- return `options:${Object.keys(event.options).length}`;
53
- case "ready":
54
- return "ready";
55
- case "user-action":
56
- return `action:${event.action[0] ?? "?"}`;
57
- case "mappings-change":
58
- return "mappings";
59
- case "theme-change":
60
- return "theme";
61
- }
62
- }
63
-
64
- // src/emulator/devtools/inspector.tsx
65
- import { jsx, jsxs } from "react/jsx-runtime";
66
- var ACCESS_LEVELS = ["none", "read table", "full"];
67
- function EmulatorInspector({ emulator, className, showTimeline = true }) {
68
- const { state, history } = useEmulatorSnapshot(emulator);
69
- const tableIds = [...state.tables.keys()];
70
- const selectedTableId = state.selection.tableId;
71
- const table = state.tables.get(selectedTableId);
72
- const columnIds = table ? Object.keys(table.columns) : [];
73
- const onSelectTable = (tableId) => emulator.selectTable(tableId);
74
- const onSelectRow = (rowId) => emulator.selectRow(rowId);
75
- const onAddRow = () => {
76
- if (!table) return;
77
- const fields = {};
78
- for (const col of columnIds) fields[col] = "";
79
- emulator.apply([gristAddRecordAction(selectedTableId, fields)]);
80
- };
81
- const onDeleteRow = (rowId) => {
82
- emulator.apply([gristRemoveRecordAction(selectedTableId, rowId)]);
83
- };
84
- const onEditCell = (rowId, colId, value) => {
85
- emulator.apply([gristUpdateRecordAction(selectedTableId, rowId, { [colId]: value })]);
86
- };
87
- const grantedAccessLevel = state.widgetInteraction.access_level ?? "read table";
88
- const onSetAccessLevel = (level) => {
89
- emulator.setInteraction({ ...state.widgetInteraction, access_level: level });
90
- };
91
- return /* @__PURE__ */ jsxs("div", { className, style: baseStyle, children: [
92
- /* @__PURE__ */ jsxs("div", { style: headerStyle, children: [
93
- /* @__PURE__ */ jsx("span", { style: badgeStyle, children: "EMULATOR" }),
94
- /* @__PURE__ */ jsx("strong", { children: state.docName }),
95
- /* @__PURE__ */ jsxs("span", { style: mutedStyle, children: [
96
- "\xB7 ",
97
- tableIds.length,
98
- " table",
99
- tableIds.length === 1 ? "" : "s"
100
- ] })
101
- ] }),
102
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 6, padding: "8px 12px", flexWrap: "wrap" }, children: tableIds.map((id) => {
103
- const t = state.tables.get(id);
104
- const active = id === selectedTableId;
105
- return /* @__PURE__ */ jsxs(
106
- "button",
107
- {
108
- type: "button",
109
- onClick: () => onSelectTable(id),
110
- style: active ? tabActiveStyle : tabStyle,
111
- children: [
112
- t.label ?? id,
113
- /* @__PURE__ */ jsxs("span", { style: mutedStyle, children: [
114
- " \xB7 ",
115
- t.rows.length
116
- ] })
117
- ]
118
- },
119
- id
120
- );
121
- }) }),
122
- /* @__PURE__ */ jsx(Section, { title: "Rows", children: !table ? /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "No table selected." }) : /* @__PURE__ */ jsxs("div", { children: [
123
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 6, marginBottom: 6 }, children: [
124
- /* @__PURE__ */ jsx("button", { type: "button", onClick: onAddRow, style: primaryBtnStyle, children: "+ Row" }),
125
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onSelectRow("new"), style: ghostBtnStyle, children: "Cursor \u2192 new" }),
126
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onSelectRow(null), style: ghostBtnStyle, children: "Cursor \u2192 none" })
127
- ] }),
128
- /* @__PURE__ */ jsx("div", { style: { overflowX: "auto" }, children: /* @__PURE__ */ jsxs("table", { style: tableStyle, children: [
129
- /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { style: { borderBottom: "1px solid #2a2f37" }, children: [
130
- /* @__PURE__ */ jsx("th", { style: thStyle, children: "id" }),
131
- columnIds.map((col) => /* @__PURE__ */ jsx("th", { style: thStyle, children: table.columns[col]?.label ?? col }, col)),
132
- /* @__PURE__ */ jsx("th", { style: thStyle })
133
- ] }) }),
134
- /* @__PURE__ */ jsx("tbody", { children: table.rows.map((row) => {
135
- const rowId = row.id;
136
- const active = state.selection.rowId === rowId;
137
- return /* @__PURE__ */ jsxs(
138
- "tr",
139
- {
140
- style: active ? trActiveStyle : trStyle,
141
- onClick: () => onSelectRow(rowId),
142
- children: [
143
- /* @__PURE__ */ jsx("td", { style: tdStyle, children: rowId }),
144
- columnIds.map((col) => /* @__PURE__ */ jsx("td", { style: tdStyle, children: /* @__PURE__ */ jsx(
145
- "input",
146
- {
147
- value: formatCell(row[col]),
148
- style: inputStyle,
149
- onClick: (event) => event.stopPropagation(),
150
- onChange: (event) => onEditCell(rowId, col, event.target.value)
151
- }
152
- ) }, col)),
153
- /* @__PURE__ */ jsx("td", { style: tdStyle, children: /* @__PURE__ */ jsx(
154
- "button",
155
- {
156
- type: "button",
157
- style: dangerBtnStyle,
158
- onClick: (event) => {
159
- event.stopPropagation();
160
- onDeleteRow(rowId);
161
- },
162
- children: "Delete"
163
- }
164
- ) })
165
- ]
166
- },
167
- rowId
168
- );
169
- }) })
170
- ] }) })
171
- ] }) }),
172
- /* @__PURE__ */ jsx(Section, { title: "Selection / mappings", children: /* @__PURE__ */ jsxs("div", { style: kvStyle, children: [
173
- /* @__PURE__ */ jsx(KV, { k: "tableId", v: state.selection.tableId }),
174
- /* @__PURE__ */ jsx(KV, { k: "rowId", v: String(state.selection.rowId) }),
175
- /* @__PURE__ */ jsx(KV, { k: "mappings", v: JSON.stringify(resolveMappings(state)) }),
176
- /* @__PURE__ */ jsx(KV, { k: "configuration", v: JSON.stringify(state.configuration) })
177
- ] }) }),
178
- /* @__PURE__ */ jsxs(Section, { title: "Access level", children: [
179
- /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 6, marginBottom: 6, flexWrap: "wrap" }, children: ACCESS_LEVELS.map((level) => /* @__PURE__ */ jsx(
180
- "button",
181
- {
182
- type: "button",
183
- onClick: () => onSetAccessLevel(level),
184
- style: level === grantedAccessLevel ? tabActiveStyle : tabStyle,
185
- title: gristAccessLevelLabel(level),
186
- children: level
187
- },
188
- level
189
- )) }),
190
- /* @__PURE__ */ jsxs("p", { style: mutedStyle, children: [
191
- "Granted to the widget via ",
192
- /* @__PURE__ */ jsx("code", { children: "access_level" }),
193
- " \u2014 ",
194
- gristAccessLevelLabel(grantedAccessLevel),
195
- "."
196
- ] })
197
- ] }),
198
- /* @__PURE__ */ jsxs(Section, { title: "Widget options", children: [
199
- /* @__PURE__ */ jsx("pre", { style: preStyle, children: JSON.stringify(state.widgetOptions, null, 2) }),
200
- /* @__PURE__ */ jsx(KV, { k: "interaction", v: JSON.stringify(state.widgetInteraction) })
201
- ] }),
202
- showTimeline && /* @__PURE__ */ jsx(Section, { title: `Event timeline (${history.length})`, children: /* @__PURE__ */ jsxs("div", { style: { maxHeight: 200, overflow: "auto", fontFamily: "monospace", fontSize: 11 }, children: [
203
- history.slice(-50).reverse().map((event, idx) => /* @__PURE__ */ jsxs("div", { style: timelineRowStyle, children: [
204
- /* @__PURE__ */ jsx("span", { style: typeBadgeStyle(event.type), children: event.type }),
205
- /* @__PURE__ */ jsx("span", { style: mutedStyle, children: summariseEvent(event) })
206
- ] }, idx)),
207
- history.length === 0 && /* @__PURE__ */ jsx("p", { style: mutedStyle, children: "No events yet." })
208
- ] }) })
209
- ] });
210
- }
211
- function Section({ title, children }) {
212
- const [open, setOpen] = useState(true);
213
- return /* @__PURE__ */ jsxs("div", { style: { borderTop: "1px solid #2a2f37" }, children: [
214
- /* @__PURE__ */ jsxs("button", { type: "button", style: sectionHeaderStyle, onClick: () => setOpen((v) => !v), children: [
215
- /* @__PURE__ */ jsx("span", { children: open ? "\u25BE" : "\u25B8" }),
216
- /* @__PURE__ */ jsx("strong", { children: title })
217
- ] }),
218
- open && /* @__PURE__ */ jsx("div", { style: { padding: "0 12px 12px" }, children })
219
- ] });
220
- }
221
- function KV({ k, v }) {
222
- return /* @__PURE__ */ jsxs("div", { style: kvRowStyle, children: [
223
- /* @__PURE__ */ jsx("span", { style: mutedStyle, children: k }),
224
- /* @__PURE__ */ jsx("code", { style: { fontFamily: "monospace", fontSize: 11 }, children: v })
225
- ] });
226
- }
227
- function summariseEvent(event) {
228
- switch (event.type) {
229
- case "user-action":
230
- return JSON.stringify(event.action);
231
- case "data-change":
232
- return `tableId=${String(event.tableId)}`;
233
- case "cursor-change":
234
- return `tableId=${String(event.tableId)} rowId=${String(event.rowId)}`;
235
- case "options-change":
236
- return JSON.stringify(event.options);
237
- case "ready":
238
- return JSON.stringify(event.configuration);
239
- case "theme-change":
240
- return JSON.stringify(event.message);
241
- case "mappings-change":
242
- return JSON.stringify(event.mappings);
243
- default:
244
- return "";
245
- }
246
- }
247
- function formatCell(value) {
248
- if (value === null || value === void 0) return "";
249
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return String(value);
250
- return JSON.stringify(value);
251
- }
252
- var baseStyle = {
253
- background: "#15171c",
254
- color: "#e6e6e6",
255
- fontFamily: "system-ui, sans-serif",
256
- fontSize: 13,
257
- border: "1px solid #2a2f37",
258
- borderRadius: 8,
259
- overflow: "hidden"
260
- };
261
- var headerStyle = {
262
- display: "flex",
263
- alignItems: "center",
264
- gap: 8,
265
- padding: "10px 12px",
266
- background: "#0f1115",
267
- borderBottom: "1px solid #2a2f37"
268
- };
269
- var badgeStyle = {
270
- background: "#3a8e57",
271
- color: "#fff",
272
- padding: "1px 6px",
273
- borderRadius: 4,
274
- fontSize: 10,
275
- letterSpacing: 0.5
276
- };
277
- var mutedStyle = { color: "#9ba1ad" };
278
- var sectionHeaderStyle = {
279
- display: "flex",
280
- alignItems: "center",
281
- gap: 6,
282
- width: "100%",
283
- background: "transparent",
284
- color: "inherit",
285
- border: "none",
286
- padding: "10px 12px",
287
- textAlign: "left",
288
- cursor: "pointer"
289
- };
290
- var tabStyle = {
291
- background: "#1c1f26",
292
- color: "#cfd2d8",
293
- border: "1px solid #2a2f37",
294
- borderRadius: 6,
295
- padding: "4px 10px",
296
- cursor: "pointer"
297
- };
298
- var tabActiveStyle = { ...tabStyle, background: "#27313f", borderColor: "#3a4f6e", color: "#fff" };
299
- var primaryBtnStyle = {
300
- background: "#3a8e57",
301
- color: "#fff",
302
- border: "none",
303
- borderRadius: 6,
304
- padding: "4px 10px",
305
- cursor: "pointer"
306
- };
307
- var ghostBtnStyle = {
308
- background: "transparent",
309
- color: "#cfd2d8",
310
- border: "1px solid #2a2f37",
311
- borderRadius: 6,
312
- padding: "4px 10px",
313
- cursor: "pointer"
314
- };
315
- var dangerBtnStyle = {
316
- background: "transparent",
317
- color: "#e58f8f",
318
- border: "1px solid #4a2226",
319
- borderRadius: 6,
320
- padding: "2px 8px",
321
- cursor: "pointer"
322
- };
323
- var tableStyle = { width: "100%", borderCollapse: "collapse", fontSize: 12 };
324
- var thStyle = { textAlign: "left", padding: "4px 6px", color: "#9ba1ad", fontWeight: 500 };
325
- var trStyle = { borderBottom: "1px solid #1f232b" };
326
- var trActiveStyle = { ...trStyle, background: "#1d2733" };
327
- var tdStyle = { padding: "4px 6px" };
328
- var inputStyle = {
329
- width: "100%",
330
- background: "#0f1115",
331
- color: "#e6e6e6",
332
- border: "1px solid #2a2f37",
333
- borderRadius: 4,
334
- padding: "2px 4px",
335
- fontSize: 12,
336
- fontFamily: "monospace"
337
- };
338
- var preStyle = {
339
- background: "#0f1115",
340
- border: "1px solid #2a2f37",
341
- borderRadius: 4,
342
- padding: 8,
343
- fontSize: 11,
344
- fontFamily: "monospace",
345
- margin: 0,
346
- whiteSpace: "pre-wrap"
347
- };
348
- var kvStyle = { display: "flex", flexDirection: "column", gap: 4 };
349
- var kvRowStyle = { display: "flex", gap: 8 };
350
- var timelineRowStyle = {
351
- display: "flex",
352
- gap: 8,
353
- padding: "2px 0",
354
- borderBottom: "1px solid #1f232b"
355
- };
356
- function typeBadgeStyle(type) {
357
- const colour = {
358
- "user-action": "#a06bff",
359
- "data-change": "#3a8e57",
360
- "cursor-change": "#3a87b8",
361
- "options-change": "#b8893a",
362
- ready: "#888",
363
- "theme-change": "#888",
364
- "mappings-change": "#888"
365
- }[type] ?? "#888";
366
- return {
367
- background: colour,
368
- color: "#fff",
369
- padding: "1px 6px",
370
- borderRadius: 4,
371
- fontSize: 10,
372
- flexShrink: 0
373
- };
374
- }
375
-
376
- // src/emulator/devtools/use-rows.ts
377
- import { useEffect, useState as useState2 } from "react";
378
- function fetchEmulatorRows(emulator, tableId) {
379
- const table = emulator.state.tables.get(tableId);
380
- if (!table) {
381
- return { rows: [], invalidCellKeys: /* @__PURE__ */ new Set() };
382
- }
383
- let cellMetaByKey = {};
384
- const data = rowsToColumnar(table, table.rows);
385
- const parsedRows = materializeGristRowsFromColumnar(data, {
386
- columns: table.columns,
387
- order: "grist",
388
- safeParse: {
389
- refMode: "detailed"
390
- },
391
- onSafeParseCellMetaByKey: (metaByKey) => {
392
- cellMetaByKey = metaByKey;
393
- }
394
- });
395
- const rows = safeParseRowsToDisplayRows(parsedRows);
396
- const invalidCellKeys = /* @__PURE__ */ new Set();
397
- for (const [cellKey, meta] of Object.entries(cellMetaByKey)) {
398
- const hasIssue = meta.issues.some(
399
- (issue) => issue.code === "type_mismatch" || issue.code === "invalid_format"
400
- );
401
- if (hasIssue) invalidCellKeys.add(cellKey);
402
- }
403
- return { rows, invalidCellKeys };
404
- }
405
- function useEmulatorRows(emulator, tableId) {
406
- const { history } = useEmulatorSnapshot(emulator);
407
- const [result, setResult] = useState2({
408
- rows: [],
409
- invalidCellKeys: /* @__PURE__ */ new Set()
410
- });
411
- useEffect(() => {
412
- let cancelled = false;
413
- if (!tableId) {
414
- queueMicrotask(() => {
415
- if (!cancelled) setResult({ rows: [], invalidCellKeys: /* @__PURE__ */ new Set() });
416
- });
417
- return () => {
418
- cancelled = true;
419
- };
420
- }
421
- try {
422
- const next = fetchEmulatorRows(emulator, tableId);
423
- if (!cancelled) setResult(next);
424
- } catch {
425
- const table = emulator.state.tables.get(tableId);
426
- if (!cancelled) {
427
- setResult({
428
- rows: table?.rows ?? [],
429
- invalidCellKeys: /* @__PURE__ */ new Set()
430
- });
431
- }
432
- }
433
- return () => {
434
- cancelled = true;
435
- };
436
- }, [emulator, tableId, history.length]);
437
- return result;
438
- }
439
-
440
- // src/emulator/devtools/use-columns.ts
441
- import { useMemo } from "react";
442
- function useEmulatorColumns(emulator) {
443
- const { state } = useEmulatorSnapshot(emulator);
444
- const requestedTableId = state.selection.tableId;
445
- const document = useMemo(() => {
446
- const tables = {};
447
- for (const [tableId, table2] of state.tables.entries()) {
448
- const filteredColumns = Object.fromEntries(
449
- Object.entries(table2.columns).filter(([colId, col]) => {
450
- return !isGristNoiseColumn(colId, col, {
451
- excludeId: true,
452
- excludeGristHelpers: true,
453
- excludeLoggingColumns: true,
454
- excludeManualSort: true
455
- });
456
- })
457
- );
458
- tables[tableId] = {
459
- label: table2.label,
460
- columns: filteredColumns,
461
- rows: table2.rows.map((row) => ({ ...row })),
462
- rowCount: table2.rows.length
463
- };
464
- }
465
- return {
466
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
467
- docName: state.docName,
468
- mode: "schema+data",
469
- source: "emulator-devtools",
470
- tables
471
- };
472
- }, [state]);
473
- const table = useMemo(() => {
474
- if (!requestedTableId) return null;
475
- const slice = document.tables[requestedTableId];
476
- if (!slice) return null;
477
- return { tableId: requestedTableId, ...slice };
478
- }, [document, requestedTableId]);
479
- const isNoiseColumnId = useMemo(
480
- () => (colId, col) => isGristNoiseColumn(colId, col, {
481
- excludeId: true,
482
- excludeGristHelpers: true,
483
- excludeLoggingColumns: true,
484
- excludeManualSort: true
485
- }),
486
- []
487
- );
488
- const sortColumnIds = useMemo(
489
- () => (colIds, columns) => {
490
- return [...colIds].sort((a, b) => {
491
- const la = (columns[a]?.label || a).toLowerCase();
492
- const lb = (columns[b]?.label || b).toLowerCase();
493
- if (la !== lb) return la.localeCompare(lb);
494
- return a.localeCompare(b);
495
- });
496
- },
497
- []
498
- );
499
- return { document, table, isNoiseColumnId, sortColumnIds };
500
- }
501
- export {
502
- EmulatorInspector,
503
- fetchEmulatorRows,
504
- useEmulatorColumns,
505
- useEmulatorRows,
506
- useEmulatorSnapshot
507
- };
508
- //# sourceMappingURL=devtools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/emulator/devtools/inspector.tsx","../../src/emulator/devtools/use-emulator-state.ts","../../src/emulator/devtools/use-rows.ts","../../src/emulator/devtools/use-columns.ts"],"sourcesContent":["/**\n * `<EmulatorInspector />` — drop-in DevTools for the playground / IDE.\n *\n * Capabilities:\n * - Multi-table picker with row count + label\n * - Inline row editor (Add / Update / Delete) routed through the emulator's\n * action engine — every edit produces real Grist user actions on the bus.\n * - Cursor selector that drives `onRecord` for the widget under test.\n * - Widget options & mappings panel.\n * - Live event timeline (last 50 events) with pretty formatting.\n *\n * The component owns no state of its own beyond UI accordion toggles —\n * everything is read off the emulator and re-renders via {@link\n * useEmulatorSnapshot}.\n */\n\nimport type { CSSProperties, ReactNode } from \"react\"\nimport { useState } from \"react\"\n\nimport { gristAddRecordAction, gristRemoveRecordAction, gristUpdateRecordAction } from \"../../sdk/helpers/grist-user-actions\"\nimport { gristAccessLevelLabel } from \"../../sdk/internal/handshake/access\"\nimport type { GristRequiredAccess } from \"../../sdk/types\"\nimport type { GristEmulator } from \"../create-grist-emulator\"\nimport { resolveMappings } from \"../core/mappings\"\nimport { useEmulatorSnapshot } from \"./use-emulator-state\"\n\nconst ACCESS_LEVELS: readonly GristRequiredAccess[] = [\"none\", \"read table\", \"full\"]\n\nexport type EmulatorInspectorProps = {\n emulator: GristEmulator\n /** Override visual style. */\n className?: string\n /** Default `true`. Set to `false` to render only the toolbar. */\n showTimeline?: boolean\n}\n\nexport function EmulatorInspector({ emulator, className, showTimeline = true }: EmulatorInspectorProps) {\n const { state, history } = useEmulatorSnapshot(emulator)\n const tableIds = [...state.tables.keys()]\n const selectedTableId = state.selection.tableId\n const table = state.tables.get(selectedTableId)\n const columnIds = table ? Object.keys(table.columns) : []\n\n const onSelectTable = (tableId: string) => emulator.selectTable(tableId)\n const onSelectRow = (rowId: number | \"new\" | null) => emulator.selectRow(rowId)\n const onAddRow = () => {\n if (!table) return\n const fields: Record<string, unknown> = {}\n for (const col of columnIds) fields[col] = \"\"\n emulator.apply([gristAddRecordAction(selectedTableId, fields)])\n }\n const onDeleteRow = (rowId: number) => {\n emulator.apply([gristRemoveRecordAction(selectedTableId, rowId)])\n }\n const onEditCell = (rowId: number, colId: string, value: string) => {\n emulator.apply([gristUpdateRecordAction(selectedTableId, rowId, { [colId]: value })])\n }\n\n const grantedAccessLevel = (state.widgetInteraction.access_level as GristRequiredAccess | undefined) ?? \"read table\"\n const onSetAccessLevel = (level: GristRequiredAccess) => {\n emulator.setInteraction({ ...state.widgetInteraction, access_level: level })\n }\n\n return (\n <div className={className} style={baseStyle}>\n <div style={headerStyle}>\n <span style={badgeStyle}>EMULATOR</span>\n <strong>{state.docName}</strong>\n <span style={mutedStyle}>· {tableIds.length} table{tableIds.length === 1 ? \"\" : \"s\"}</span>\n </div>\n\n <div style={{ display: \"flex\", gap: 6, padding: \"8px 12px\", flexWrap: \"wrap\" }}>\n {tableIds.map((id) => {\n const t = state.tables.get(id)!\n const active = id === selectedTableId\n return (\n <button\n key={id}\n type=\"button\"\n onClick={() => onSelectTable(id)}\n style={active ? tabActiveStyle : tabStyle}\n >\n {t.label ?? id}\n <span style={mutedStyle}> · {t.rows.length}</span>\n </button>\n )\n })}\n </div>\n\n <Section title=\"Rows\">\n {!table ? (\n <p style={mutedStyle}>No table selected.</p>\n ) : (\n <div>\n <div style={{ display: \"flex\", gap: 6, marginBottom: 6 }}>\n <button type=\"button\" onClick={onAddRow} style={primaryBtnStyle}>+ Row</button>\n <button type=\"button\" onClick={() => onSelectRow(\"new\")} style={ghostBtnStyle}>Cursor → new</button>\n <button type=\"button\" onClick={() => onSelectRow(null)} style={ghostBtnStyle}>Cursor → none</button>\n </div>\n <div style={{ overflowX: \"auto\" }}>\n <table style={tableStyle}>\n <thead>\n <tr style={{ borderBottom: \"1px solid #2a2f37\" }}>\n <th style={thStyle}>id</th>\n {columnIds.map((col) => (\n <th key={col} style={thStyle}>\n {table.columns[col]?.label ?? col}\n </th>\n ))}\n <th style={thStyle}></th>\n </tr>\n </thead>\n <tbody>\n {table.rows.map((row) => {\n const rowId = row.id\n const active = state.selection.rowId === rowId\n return (\n <tr\n key={rowId}\n style={active ? trActiveStyle : trStyle}\n onClick={() => onSelectRow(rowId)}\n >\n <td style={tdStyle}>{rowId}</td>\n {columnIds.map((col) => (\n <td key={col} style={tdStyle}>\n <input\n value={formatCell(row[col])}\n style={inputStyle}\n onClick={(event) => event.stopPropagation()}\n onChange={(event) => onEditCell(rowId, col, event.target.value)}\n />\n </td>\n ))}\n <td style={tdStyle}>\n <button\n type=\"button\"\n style={dangerBtnStyle}\n onClick={(event) => {\n event.stopPropagation()\n onDeleteRow(rowId)\n }}\n >\n Delete\n </button>\n </td>\n </tr>\n )\n })}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </Section>\n\n <Section title=\"Selection / mappings\">\n <div style={kvStyle}>\n <KV k=\"tableId\" v={state.selection.tableId} />\n <KV k=\"rowId\" v={String(state.selection.rowId)} />\n <KV k=\"mappings\" v={JSON.stringify(resolveMappings(state))} />\n <KV k=\"configuration\" v={JSON.stringify(state.configuration)} />\n </div>\n </Section>\n\n <Section title=\"Access level\">\n <div style={{ display: \"flex\", gap: 6, marginBottom: 6, flexWrap: \"wrap\" }}>\n {ACCESS_LEVELS.map((level) => (\n <button\n key={level}\n type=\"button\"\n onClick={() => onSetAccessLevel(level)}\n style={level === grantedAccessLevel ? tabActiveStyle : tabStyle}\n title={gristAccessLevelLabel(level)}\n >\n {level}\n </button>\n ))}\n </div>\n <p style={mutedStyle}>\n Granted to the widget via <code>access_level</code> — {gristAccessLevelLabel(grantedAccessLevel)}.\n </p>\n </Section>\n\n <Section title=\"Widget options\">\n <pre style={preStyle}>{JSON.stringify(state.widgetOptions, null, 2)}</pre>\n <KV k=\"interaction\" v={JSON.stringify(state.widgetInteraction)} />\n </Section>\n\n {showTimeline && (\n <Section title={`Event timeline (${history.length})`}>\n <div style={{ maxHeight: 200, overflow: \"auto\", fontFamily: \"monospace\", fontSize: 11 }}>\n {history.slice(-50).reverse().map((event, idx) => (\n <div key={idx} style={timelineRowStyle}>\n <span style={typeBadgeStyle(event.type)}>{event.type}</span>\n <span style={mutedStyle}>{summariseEvent(event)}</span>\n </div>\n ))}\n {history.length === 0 && <p style={mutedStyle}>No events yet.</p>}\n </div>\n </Section>\n )}\n </div>\n )\n}\n\nfunction Section({ title, children }: { title: string; children: ReactNode }) {\n const [open, setOpen] = useState(true)\n return (\n <div style={{ borderTop: \"1px solid #2a2f37\" }}>\n <button type=\"button\" style={sectionHeaderStyle} onClick={() => setOpen((v) => !v)}>\n <span>{open ? \"▾\" : \"▸\"}</span>\n <strong>{title}</strong>\n </button>\n {open && <div style={{ padding: \"0 12px 12px\" }}>{children}</div>}\n </div>\n )\n}\n\nfunction KV({ k, v }: { k: string; v: ReactNode }) {\n return (\n <div style={kvRowStyle}>\n <span style={mutedStyle}>{k}</span>\n <code style={{ fontFamily: \"monospace\", fontSize: 11 }}>{v}</code>\n </div>\n )\n}\n\nfunction summariseEvent(event: { type: string } & Record<string, unknown>): string {\n switch (event.type) {\n case \"user-action\":\n return JSON.stringify(event.action)\n case \"data-change\":\n return `tableId=${String(event.tableId)}`\n case \"cursor-change\":\n return `tableId=${String(event.tableId)} rowId=${String(event.rowId)}`\n case \"options-change\":\n return JSON.stringify(event.options)\n case \"ready\":\n return JSON.stringify(event.configuration)\n case \"theme-change\":\n return JSON.stringify(event.message)\n case \"mappings-change\":\n return JSON.stringify(event.mappings)\n default:\n return \"\"\n }\n}\n\nfunction formatCell(value: unknown): string {\n if (value === null || value === undefined) return \"\"\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") return String(value)\n return JSON.stringify(value)\n}\n\n// --- styles -----------------------------------------------------------------\n\nconst baseStyle: CSSProperties = {\n background: \"#15171c\",\n color: \"#e6e6e6\",\n fontFamily: \"system-ui, sans-serif\",\n fontSize: 13,\n border: \"1px solid #2a2f37\",\n borderRadius: 8,\n overflow: \"hidden\",\n}\nconst headerStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"10px 12px\",\n background: \"#0f1115\",\n borderBottom: \"1px solid #2a2f37\",\n}\nconst badgeStyle: CSSProperties = {\n background: \"#3a8e57\",\n color: \"#fff\",\n padding: \"1px 6px\",\n borderRadius: 4,\n fontSize: 10,\n letterSpacing: 0.5,\n}\nconst mutedStyle: CSSProperties = { color: \"#9ba1ad\" }\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: 6,\n width: \"100%\",\n background: \"transparent\",\n color: \"inherit\",\n border: \"none\",\n padding: \"10px 12px\",\n textAlign: \"left\" as const,\n cursor: \"pointer\",\n}\nconst tabStyle: CSSProperties = {\n background: \"#1c1f26\",\n color: \"#cfd2d8\",\n border: \"1px solid #2a2f37\",\n borderRadius: 6,\n padding: \"4px 10px\",\n cursor: \"pointer\",\n}\nconst tabActiveStyle: CSSProperties = { ...tabStyle, background: \"#27313f\", borderColor: \"#3a4f6e\", color: \"#fff\" }\nconst primaryBtnStyle: CSSProperties = {\n background: \"#3a8e57\",\n color: \"#fff\",\n border: \"none\",\n borderRadius: 6,\n padding: \"4px 10px\",\n cursor: \"pointer\",\n}\nconst ghostBtnStyle: CSSProperties = {\n background: \"transparent\",\n color: \"#cfd2d8\",\n border: \"1px solid #2a2f37\",\n borderRadius: 6,\n padding: \"4px 10px\",\n cursor: \"pointer\",\n}\nconst dangerBtnStyle: CSSProperties = {\n background: \"transparent\",\n color: \"#e58f8f\",\n border: \"1px solid #4a2226\",\n borderRadius: 6,\n padding: \"2px 8px\",\n cursor: \"pointer\",\n}\nconst tableStyle: CSSProperties = { width: \"100%\", borderCollapse: \"collapse\" as const, fontSize: 12 }\nconst thStyle: CSSProperties = { textAlign: \"left\" as const, padding: \"4px 6px\", color: \"#9ba1ad\", fontWeight: 500 }\nconst trStyle: CSSProperties = { borderBottom: \"1px solid #1f232b\" }\nconst trActiveStyle: CSSProperties = { ...trStyle, background: \"#1d2733\" }\nconst tdStyle: CSSProperties = { padding: \"4px 6px\" }\nconst inputStyle: CSSProperties = {\n width: \"100%\",\n background: \"#0f1115\",\n color: \"#e6e6e6\",\n border: \"1px solid #2a2f37\",\n borderRadius: 4,\n padding: \"2px 4px\",\n fontSize: 12,\n fontFamily: \"monospace\",\n}\nconst preStyle: CSSProperties = {\n background: \"#0f1115\",\n border: \"1px solid #2a2f37\",\n borderRadius: 4,\n padding: 8,\n fontSize: 11,\n fontFamily: \"monospace\",\n margin: 0,\n whiteSpace: \"pre-wrap\",\n}\nconst kvStyle: CSSProperties = { display: \"flex\", flexDirection: \"column\" as const, gap: 4 }\nconst kvRowStyle: CSSProperties = { display: \"flex\", gap: 8 }\nconst timelineRowStyle: CSSProperties = {\n display: \"flex\",\n gap: 8,\n padding: \"2px 0\",\n borderBottom: \"1px solid #1f232b\",\n}\nfunction typeBadgeStyle(type: string): CSSProperties {\n const colour = ({\n \"user-action\": \"#a06bff\",\n \"data-change\": \"#3a8e57\",\n \"cursor-change\": \"#3a87b8\",\n \"options-change\": \"#b8893a\",\n ready: \"#888\",\n \"theme-change\": \"#888\",\n \"mappings-change\": \"#888\",\n } as Record<string, string>)[type] ?? \"#888\"\n return {\n background: colour,\n color: \"#fff\",\n padding: \"1px 6px\",\n borderRadius: 4,\n fontSize: 10,\n flexShrink: 0,\n }\n}\n","import { useSyncExternalStore } from \"react\"\n\nimport type { GristEmulator } from \"../create-grist-emulator\"\nimport type { EmulatorEvent } from \"../core/event-bus\"\n\n/**\n * React-friendly snapshot of the emulator state. Re-renders whenever the\n * event bus fires (so the inspector stays in lock-step with widget actions).\n */\nexport function useEmulatorSnapshot(emulator: GristEmulator) {\n const subscribe = (notify: () => void) => {\n return emulator.bus.on(() => notify())\n }\n const getSnapshot = () => snapshotKey(emulator)\n useSyncExternalStore(subscribe, getSnapshot, getSnapshot)\n return {\n state: emulator.state,\n history: emulator.bus.history(),\n }\n}\n\n/**\n * A monotonic-ish key that changes on every event. We tag each event with\n * its index in the history so React detects changes cheaply.\n */\nfunction snapshotKey(emulator: GristEmulator): string {\n const history = emulator.bus.history()\n const last = history[history.length - 1]\n return `${history.length}:${eventTag(last)}`\n}\n\nfunction eventTag(event: EmulatorEvent | undefined): string {\n if (!event) return \"empty\"\n switch (event.type) {\n case \"data-change\":\n return `data:${event.tableId}`\n case \"cursor-change\":\n return `cursor:${event.tableId}:${String(event.rowId)}`\n case \"options-change\":\n return `options:${Object.keys(event.options).length}`\n case \"ready\":\n return \"ready\"\n case \"user-action\":\n return `action:${(event.action[0] as string | undefined) ?? \"?\"}`\n case \"mappings-change\":\n return \"mappings\"\n case \"theme-change\":\n return \"theme\"\n }\n}\n","import { useEffect, useState } from \"react\"\n\nimport {\n materializeGristRowsFromColumnar,\n safeParseRowsToDisplayRows,\n} from \"../../sdk/helpers/grist-table-data\"\nimport type { GristRowRecord } from \"../../sdk/types\"\nimport type { GristEmulator } from \"../create-grist-emulator\"\nimport { rowsToColumnar } from \"../core/columnar\"\nimport { useEmulatorSnapshot } from \"./use-emulator-state\"\n\nexport type UseEmulatorRowsResult<T extends Record<string, unknown> = Record<string, unknown>> = {\n rows: GristRowRecord<T>[]\n invalidCellKeys: Set<string>\n}\n\n/**\n * Build display-ready rows from emulator in-memory state (same parse pipeline as\n * {@link fetchGristTableRows}, without `docApi.fetchTable`).\n */\nexport function fetchEmulatorRows<T extends Record<string, unknown> = Record<string, unknown>>(\n emulator: GristEmulator,\n tableId: string\n): UseEmulatorRowsResult<T> {\n const table = emulator.state.tables.get(tableId)\n if (!table) {\n return { rows: [], invalidCellKeys: new Set() }\n }\n\n let cellMetaByKey: Record<string, { issues: Array<{ code: string }> }> = {}\n const data = rowsToColumnar(table, table.rows)\n const parsedRows = materializeGristRowsFromColumnar<T>(data, {\n columns: table.columns,\n order: \"grist\",\n safeParse: {\n refMode: \"detailed\",\n },\n onSafeParseCellMetaByKey: (metaByKey) => {\n cellMetaByKey = metaByKey as Record<string, { issues: Array<{ code: string }> }>\n },\n })\n const rows = safeParseRowsToDisplayRows(parsedRows) as GristRowRecord<T>[]\n const invalidCellKeys = new Set<string>()\n for (const [cellKey, meta] of Object.entries(cellMetaByKey)) {\n const hasIssue = meta.issues.some(\n (issue) => issue.code === \"type_mismatch\" || issue.code === \"invalid_format\"\n )\n if (hasIssue) invalidCellKeys.add(cellKey)\n }\n return { rows, invalidCellKeys }\n}\n\nexport function useEmulatorRows<T extends Record<string, unknown> = Record<string, unknown>>(\n emulator: GristEmulator,\n tableId: string | undefined | null\n): UseEmulatorRowsResult<T> {\n const { history } = useEmulatorSnapshot(emulator)\n const [result, setResult] = useState<UseEmulatorRowsResult<T>>({\n rows: [],\n invalidCellKeys: new Set(),\n })\n\n useEffect(() => {\n let cancelled = false\n if (!tableId) {\n queueMicrotask(() => {\n if (!cancelled) setResult({ rows: [], invalidCellKeys: new Set() })\n })\n return () => {\n cancelled = true\n }\n }\n\n try {\n const next = fetchEmulatorRows<T>(emulator, tableId)\n if (!cancelled) setResult(next)\n } catch {\n const table = emulator.state.tables.get(tableId)\n if (!cancelled) {\n setResult({\n rows: (table?.rows ?? []) as GristRowRecord<T>[],\n invalidCellKeys: new Set(),\n })\n }\n }\n\n return () => {\n cancelled = true\n }\n }, [emulator, tableId, history.length])\n\n return result\n}\n","import { useMemo } from \"react\"\n\nimport type { GristReplicaColumn, GristReplicaDocument, GristReplicaTable } from \"../../sdk/replica-document\"\nimport { isGristNoiseColumn } from \"../../sdk/helpers/grist-columns-filters\"\nimport type { GristEmulator } from \"../create-grist-emulator\"\nimport { useEmulatorSnapshot } from \"./use-emulator-state\"\n\nexport type EmulatorColumnsTableView = GristReplicaTable & { tableId: string }\n\nexport type UseEmulatorColumnsResult = {\n document: GristReplicaDocument\n table: EmulatorColumnsTableView | null\n isNoiseColumnId: (colId: string, col?: GristReplicaColumn) => boolean\n sortColumnIds: (colIds: string[], columns: Record<string, GristReplicaColumn>) => string[]\n}\n\nexport function useEmulatorColumns(emulator: GristEmulator): UseEmulatorColumnsResult {\n const { state } = useEmulatorSnapshot(emulator)\n const requestedTableId = state.selection.tableId\n\n const document = useMemo<GristReplicaDocument>(() => {\n const tables: Record<string, GristReplicaTable> = {}\n for (const [tableId, table] of state.tables.entries()) {\n const filteredColumns = Object.fromEntries(\n Object.entries(table.columns).filter(([colId, col]) => {\n return !isGristNoiseColumn(colId, col, {\n excludeId: true,\n excludeGristHelpers: true,\n excludeLoggingColumns: true,\n excludeManualSort: true,\n })\n })\n )\n tables[tableId] = {\n label: table.label,\n columns: filteredColumns,\n rows: table.rows.map((row) => ({ ...row })),\n rowCount: table.rows.length,\n }\n }\n return {\n generatedAt: new Date().toISOString(),\n docName: state.docName,\n mode: \"schema+data\",\n source: \"emulator-devtools\",\n tables,\n }\n }, [state])\n\n const table = useMemo<EmulatorColumnsTableView | null>(() => {\n if (!requestedTableId) return null\n const slice = document.tables[requestedTableId]\n if (!slice) return null\n return { tableId: requestedTableId, ...slice }\n }, [document, requestedTableId])\n\n const isNoiseColumnId = useMemo(\n () =>\n (colId: string, col?: GristReplicaColumn): boolean =>\n isGristNoiseColumn(colId, col, {\n excludeId: true,\n excludeGristHelpers: true,\n excludeLoggingColumns: true,\n excludeManualSort: true,\n }),\n []\n )\n\n const sortColumnIds = useMemo(\n () => (colIds: string[], columns: Record<string, GristReplicaColumn>): string[] => {\n return [...colIds].sort((a, b) => {\n const la = (columns[a]?.label || a).toLowerCase()\n const lb = (columns[b]?.label || b).toLowerCase()\n if (la !== lb) return la.localeCompare(lb)\n return a.localeCompare(b)\n })\n },\n []\n )\n\n return { document, table, isNoiseColumnId, sortColumnIds }\n}\n"],"mappings":"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","names":["useState","useState","table"]}