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
package/dist/emulator.cjs CHANGED
@@ -86,26 +86,7 @@ function coerceGristDocApiRefRowId(value) {
86
86
  return void 0;
87
87
  }
88
88
 
89
- // src/sdk/helpers/grist-safe-parse.ts
90
- var import_zod = require("zod");
91
- var gristSafeRefValueSchema = import_zod.z.object({
92
- rowId: import_zod.z.number(),
93
- display: import_zod.z.string().nullable().optional()
94
- });
95
- var gristSafeRefListValueSchema = import_zod.z.object({
96
- rowIds: import_zod.z.array(import_zod.z.number()),
97
- displays: import_zod.z.array(import_zod.z.string()).optional()
98
- });
99
- var gristCellValueSchema = import_zod.z.union([
100
- import_zod.z.null(),
101
- import_zod.z.string(),
102
- import_zod.z.number(),
103
- import_zod.z.boolean(),
104
- import_zod.z.date(),
105
- import_zod.z.array(import_zod.z.unknown()),
106
- gristSafeRefValueSchema,
107
- gristSafeRefListValueSchema
108
- ]);
89
+ // src/emulator/core/display-helpers.ts
109
90
  function inferDisplayHelpersByRef(columns) {
110
91
  const out = {};
111
92
  const helperColumns = Object.entries(columns).filter(
@@ -918,8 +899,9 @@ function createWidgetApiImpl(state, bus) {
918
899
  async getOptions() {
919
900
  return Object.keys(state.widgetOptions).length > 0 ? { ...state.widgetOptions } : null;
920
901
  },
902
+ // Replaces every option, as Grist's WidgetAPI.setOptions does.
921
903
  async setOptions(options) {
922
- state.widgetOptions = { ...state.widgetOptions, ...options };
904
+ state.widgetOptions = { ...options };
923
905
  emit();
924
906
  },
925
907
  async clearOptions() {
@@ -985,157 +967,6 @@ function buildGristThemeHostMessage(appearance, options) {
985
967
  };
986
968
  }
987
969
 
988
- // src/emulator/transports/iframe.ts
989
- var import_grain_rpc = require("grain-rpc");
990
- function createIframeTransport(options) {
991
- const { iframe, state, bus, api, targetOrigin = "*" } = options;
992
- const timers = /* @__PURE__ */ new Set();
993
- const rpc = new import_grain_rpc.Rpc({
994
- sendMessage: (msg) => {
995
- const target = iframe.contentWindow;
996
- if (!target) return;
997
- target.postMessage(msg, targetOrigin);
998
- },
999
- logger: { info: () => {
1000
- }, warn: () => {
1001
- } }
1002
- });
1003
- rpc.queueOutgoingUntilReadyMessage();
1004
- const receiveFromWidget = rpc.receiveMessage.bind(rpc);
1005
- rpc.receiveMessage = (msg) => {
1006
- if (msg && typeof msg === "object" && msg.mtype === import_grain_rpc.MsgType.RpcCall && msg.mdest === "grist") {
1007
- const copy = { ...msg };
1008
- delete copy.mdest;
1009
- receiveFromWidget(copy);
1010
- return;
1011
- }
1012
- receiveFromWidget(msg);
1013
- };
1014
- const onMessage = (event) => {
1015
- if (event.source !== iframe.contentWindow) return;
1016
- if (!isRpcEnvelope(event.data)) return;
1017
- rpc.receiveMessage(event.data);
1018
- };
1019
- window.addEventListener("message", onMessage);
1020
- rpc.registerImpl("GristView", api.GristView);
1021
- rpc.registerImpl("GristDocAPI", api.GristDocAPI);
1022
- rpc.registerImpl("WidgetAPI", api.WidgetAPI);
1023
- rpc.registerImpl("CustomSectionAPI", api.CustomSectionAPI);
1024
- rpc.registerImpl("_grist_api", api.GristAPI);
1025
- rpc.registerImpl("CommandAPI", api.CommandAPI);
1026
- const buildInteraction = options.buildInteraction ?? defaultInteraction(state);
1027
- const cursorOf = options.cursor ?? (() => state.selection.cursor);
1028
- const initialCursorOf = options.initialCursor ?? (() => state.selection.rowId);
1029
- function fireDataChange(tableId, opts) {
1030
- safePostMessage({
1031
- tableId: tableId ?? state.selection.tableId,
1032
- dataChange: true,
1033
- ...opts?.mappingsChange ? { mappingsChange: true } : {}
1034
- });
1035
- }
1036
- function fireCursor(rowId, opts) {
1037
- const id = rowId === void 0 ? initialCursorOf() : rowId;
1038
- if (id === null) return;
1039
- safePostMessage({
1040
- tableId: state.selection.tableId,
1041
- rowId: id,
1042
- cursor: cursorOf(),
1043
- ...opts?.mappingsChange ? { mappingsChange: true } : {}
1044
- });
1045
- }
1046
- function fireOptions() {
1047
- safePostMessage({
1048
- options: hasOptions(state.widgetOptions) ? { ...state.widgetOptions } : null,
1049
- settings: { ...buildInteraction() }
1050
- });
1051
- }
1052
- function fireTheme(message) {
1053
- safePostMessage(message);
1054
- }
1055
- function emitInitialState(opts) {
1056
- fireOptions();
1057
- if (options.initialTheme) {
1058
- fireTheme(buildGristThemeHostMessage(options.initialTheme, { fromReady: true }));
1059
- }
1060
- fireDataChange(void 0, opts);
1061
- fireCursor(void 0, opts);
1062
- }
1063
- function emitInitialStateWithReplay(opts) {
1064
- emitInitialState(opts);
1065
- queueMicrotask(() => emitInitialState(opts));
1066
- const timer = setTimeout(() => {
1067
- timers.delete(timer);
1068
- emitInitialState(opts);
1069
- }, 0);
1070
- timers.add(timer);
1071
- }
1072
- const offBus = bus.on((event) => {
1073
- switch (event.type) {
1074
- case "ready":
1075
- emitInitialStateWithReplay();
1076
- break;
1077
- case "data-change":
1078
- fireDataChange(event.tableId);
1079
- break;
1080
- case "cursor-change": {
1081
- const rowId = event.rowId === null ? state.selection.rowId : event.rowId;
1082
- if (rowId !== null) {
1083
- safePostMessage({
1084
- tableId: event.tableId,
1085
- rowId,
1086
- cursor: cursorOf()
1087
- });
1088
- }
1089
- fireDataChange(event.tableId);
1090
- break;
1091
- }
1092
- case "options-change":
1093
- fireOptions();
1094
- break;
1095
- case "mappings-change":
1096
- emitInitialStateWithReplay({ mappingsChange: true });
1097
- break;
1098
- case "theme-change":
1099
- fireTheme(event.message);
1100
- break;
1101
- }
1102
- });
1103
- rpc.processIncoming();
1104
- function safePostMessage(payload) {
1105
- try {
1106
- rpc.postMessage(payload);
1107
- } catch (err) {
1108
- console.warn("[grist-emulator/iframe] failed to deliver postMessage", err);
1109
- }
1110
- }
1111
- return {
1112
- dispose() {
1113
- window.removeEventListener("message", onMessage);
1114
- offBus();
1115
- for (const timer of timers) clearTimeout(timer);
1116
- timers.clear();
1117
- },
1118
- fireDataChange,
1119
- fireCursor,
1120
- fireOptions,
1121
- fireTheme,
1122
- emitInitialState
1123
- };
1124
- }
1125
- function hasOptions(options) {
1126
- return Object.keys(options).length > 0;
1127
- }
1128
- function isRpcEnvelope(data) {
1129
- if (!data || typeof data !== "object") return false;
1130
- return typeof data.mtype === "number";
1131
- }
1132
- function defaultInteraction(state) {
1133
- return () => ({
1134
- access_level: state.configuration?.requiredAccess ?? "read table",
1135
- ...state.widgetInteraction
1136
- });
1137
- }
1138
-
1139
970
  // src/sdk/helpers/grist-user-actions.ts
1140
971
  function gristUpdateRecordAction(tableId, rowId, patch) {
1141
972
  return ["UpdateRecord", tableId, rowId, patch];
@@ -1191,14 +1022,6 @@ function createInlineTransport(options) {
1191
1022
  logErr(err);
1192
1023
  }
1193
1024
  }
1194
- lastRecord = { record: null, mappings };
1195
- for (const [cb] of recordCbs) {
1196
- try {
1197
- cb(null, mappings);
1198
- } catch (err) {
1199
- logErr(err);
1200
- }
1201
- }
1202
1025
  return;
1203
1026
  }
1204
1027
  if (rowId === null) {
@@ -1537,57 +1360,57 @@ function installFakeIframeContext(target) {
1537
1360
  }
1538
1361
 
1539
1362
  // src/emulator/validators.ts
1540
- var import_zod2 = require("zod");
1541
- var emulatorRowSchema = import_zod2.z.object({ id: import_zod2.z.number() }).catchall(import_zod2.z.unknown());
1542
- var formulaKindSchema = import_zod2.z.enum(["computed", "trigger", "none", "empty_slot"]);
1543
- var replicaColumnSchema = import_zod2.z.object({
1544
- colRef: import_zod2.z.number().optional(),
1545
- type: import_zod2.z.string().optional(),
1546
- label: import_zod2.z.string().optional(),
1547
- parentPos: import_zod2.z.number().optional(),
1548
- isFormula: import_zod2.z.boolean().optional(),
1363
+ var import_zod = require("zod");
1364
+ var emulatorRowSchema = import_zod.z.object({ id: import_zod.z.number() }).catchall(import_zod.z.unknown());
1365
+ var formulaKindSchema = import_zod.z.enum(["computed", "trigger", "none", "empty_slot"]);
1366
+ var replicaColumnSchema = import_zod.z.object({
1367
+ colRef: import_zod.z.number().optional(),
1368
+ type: import_zod.z.string().optional(),
1369
+ label: import_zod.z.string().optional(),
1370
+ parentPos: import_zod.z.number().optional(),
1371
+ isFormula: import_zod.z.boolean().optional(),
1549
1372
  formulaKind: formulaKindSchema.optional(),
1550
- formula: import_zod2.z.string().optional(),
1551
- description: import_zod2.z.string().optional(),
1552
- widgetOptions: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).optional(),
1553
- displayColRef: import_zod2.z.number().optional(),
1554
- visibleColRef: import_zod2.z.number().optional()
1373
+ formula: import_zod.z.string().optional(),
1374
+ description: import_zod.z.string().optional(),
1375
+ widgetOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
1376
+ displayColRef: import_zod.z.number().optional(),
1377
+ visibleColRef: import_zod.z.number().optional()
1555
1378
  }).strict();
1556
- var replicaTableSchema = import_zod2.z.object({
1557
- label: import_zod2.z.string().optional(),
1558
- columns: import_zod2.z.record(import_zod2.z.string(), replicaColumnSchema).optional(),
1559
- rows: import_zod2.z.array(emulatorRowSchema).optional(),
1560
- rowCount: import_zod2.z.number().optional(),
1561
- dataOmitted: import_zod2.z.boolean().optional(),
1562
- dataOmittedReason: import_zod2.z.string().optional(),
1563
- error: import_zod2.z.string().optional()
1379
+ var replicaTableSchema = import_zod.z.object({
1380
+ label: import_zod.z.string().optional(),
1381
+ columns: import_zod.z.record(import_zod.z.string(), replicaColumnSchema).optional(),
1382
+ rows: import_zod.z.array(emulatorRowSchema).optional(),
1383
+ rowCount: import_zod.z.number().optional(),
1384
+ dataOmitted: import_zod.z.boolean().optional(),
1385
+ dataOmittedReason: import_zod.z.string().optional(),
1386
+ error: import_zod.z.string().optional()
1564
1387
  }).strict();
1565
- var replicaSelectionSchema = import_zod2.z.object({
1566
- tableId: import_zod2.z.string().optional(),
1567
- rowId: import_zod2.z.union([import_zod2.z.number(), import_zod2.z.literal("new"), import_zod2.z.null()]).optional(),
1568
- mappings: import_zod2.z.unknown().nullable().optional(),
1569
- cursor: import_zod2.z.unknown().optional()
1388
+ var replicaSelectionSchema = import_zod.z.object({
1389
+ tableId: import_zod.z.string().optional(),
1390
+ rowId: import_zod.z.union([import_zod.z.number(), import_zod.z.literal("new"), import_zod.z.null()]).optional(),
1391
+ mappings: import_zod.z.unknown().nullable().optional(),
1392
+ cursor: import_zod.z.unknown().optional()
1570
1393
  }).strict();
1571
- var replicaWidgetConfigurationSchema = import_zod2.z.object({
1572
- requiredAccess: import_zod2.z.string().optional(),
1573
- columns: import_zod2.z.unknown().optional(),
1574
- allowSelectBy: import_zod2.z.boolean().optional(),
1575
- hasCustomOptions: import_zod2.z.boolean().optional()
1394
+ var replicaWidgetConfigurationSchema = import_zod.z.object({
1395
+ requiredAccess: import_zod.z.string().optional(),
1396
+ columns: import_zod.z.unknown().optional(),
1397
+ allowSelectBy: import_zod.z.boolean().optional(),
1398
+ hasCustomOptions: import_zod.z.boolean().optional()
1576
1399
  }).strict();
1577
- var replicaAccessTokenSchema = import_zod2.z.object({
1578
- token: import_zod2.z.string(),
1579
- baseUrl: import_zod2.z.string(),
1580
- ttlMsecs: import_zod2.z.number()
1400
+ var replicaAccessTokenSchema = import_zod.z.object({
1401
+ token: import_zod.z.string(),
1402
+ baseUrl: import_zod.z.string(),
1403
+ ttlMsecs: import_zod.z.number()
1581
1404
  }).strict();
1582
- var replicaDocumentSchema = import_zod2.z.object({
1583
- generatedAt: import_zod2.z.string(),
1584
- source: import_zod2.z.string().optional(),
1585
- docName: import_zod2.z.string().optional(),
1586
- mode: import_zod2.z.enum(["schema-only", "schema+samples", "schema+data"]).optional(),
1587
- tables: import_zod2.z.record(import_zod2.z.string(), replicaTableSchema),
1405
+ var replicaDocumentSchema = import_zod.z.object({
1406
+ generatedAt: import_zod.z.string(),
1407
+ source: import_zod.z.string().optional(),
1408
+ docName: import_zod.z.string().optional(),
1409
+ mode: import_zod.z.enum(["schema-only", "schema+samples", "schema+data"]).optional(),
1410
+ tables: import_zod.z.record(import_zod.z.string(), replicaTableSchema),
1588
1411
  selection: replicaSelectionSchema.optional(),
1589
- widgetOptions: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).optional(),
1590
- widgetInteraction: import_zod2.z.unknown().optional(),
1412
+ widgetOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.unknown()).optional(),
1413
+ widgetInteraction: import_zod.z.unknown().optional(),
1591
1414
  configuration: replicaWidgetConfigurationSchema.optional(),
1592
1415
  accessToken: replicaAccessTokenSchema.nullable().optional()
1593
1416
  }).strict().refine((value) => Object.keys(value.tables).length > 0, {
@@ -1618,34 +1441,21 @@ function createGristEmulator(options) {
1618
1441
  const state = createDocument({
1619
1442
  ...validatedDocument,
1620
1443
  widgetOptions: options.widgetOptions ?? validatedDocument.widgetOptions,
1621
- widgetInteraction: options.widgetInteraction ?? validatedDocument.widgetInteraction ?? { access_level: "read table" }
1444
+ // No access_level by default: the emulator then grants the access the
1445
+ // widget asks for in grist.ready(), as a user accepting it in Grist would.
1446
+ widgetInteraction: options.widgetInteraction ?? validatedDocument.widgetInteraction ?? {}
1622
1447
  });
1623
1448
  const bus = createEventBus();
1624
1449
  const api = createApiBundle(state, bus);
1625
- const transportKind = options.transport?.kind ?? "inline";
1626
- let transport;
1627
- let grist;
1628
- if (transportKind === "iframe") {
1629
- if (options.transport?.kind !== "iframe") throw new Error("transport mismatch");
1630
- transport = createIframeTransport({
1631
- iframe: options.transport.iframe,
1632
- targetOrigin: options.transport.targetOrigin,
1633
- state,
1634
- bus,
1635
- api,
1636
- initialTheme: options.initialTheme
1637
- });
1638
- } else {
1639
- const inline = createInlineTransport({
1640
- state,
1641
- bus,
1642
- api,
1643
- initialTheme: options.initialTheme,
1644
- target: options.transport?.kind === "inline" ? options.transport.target : void 0
1645
- });
1646
- transport = inline;
1647
- grist = inline.grist;
1648
- }
1450
+ const inline = createInlineTransport({
1451
+ state,
1452
+ bus,
1453
+ api,
1454
+ initialTheme: options.initialTheme,
1455
+ target: options.transport?.target
1456
+ });
1457
+ const transport = inline;
1458
+ const grist = inline.grist;
1649
1459
  function apply(actions) {
1650
1460
  return applyUserActions(state, bus, actions);
1651
1461
  }