grist-widget-sdk 0.2.1 → 0.2.15

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/dist/advanced.cjs CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var advanced_exports = {};
22
22
  __export(advanced_exports, {
23
23
  GristHandshakeProvider: () => GristHandshakeProvider,
24
+ useAmbientGristHandshake: () => useAmbientGristHandshake,
24
25
  useGristAccessToken: () => useGristAccessToken,
25
26
  useGristActions: () => useGristActions,
26
27
  useGristAvailability: () => useGristAvailability,
@@ -743,14 +744,24 @@ var ACCESS_RANK2 = {
743
744
  };
744
745
  var inFlight = null;
745
746
  var lastAccess = null;
746
- function shouldReinit(next) {
747
+ var lastColumnNames = null;
748
+ function columnNamesOf(columns) {
749
+ return new Set((columns ?? []).map((c) => typeof c === "string" ? c : c.name));
750
+ }
751
+ function shouldReinit(next, nextColumns) {
747
752
  if (!lastAccess) return true;
748
- return ACCESS_RANK2[next] > ACCESS_RANK2[lastAccess];
753
+ if (ACCESS_RANK2[next] > ACCESS_RANK2[lastAccess]) return true;
754
+ for (const name of nextColumns) {
755
+ if (!lastColumnNames?.has(name)) return true;
756
+ }
757
+ return false;
749
758
  }
750
759
  function ensureGristReady(payload) {
751
760
  const access = payload.requiredAccess ?? "read table";
752
- if (inFlight && !shouldReinit(access)) return inFlight;
761
+ const columns = columnNamesOf(payload.columns);
762
+ if (inFlight && !shouldReinit(access, columns)) return inFlight;
753
763
  lastAccess = access;
764
+ lastColumnNames = columns;
754
765
  const next = Promise.resolve().then(() => {
755
766
  const result = grist.ready(payload);
756
767
  return result instanceof Promise ? result : Promise.resolve();
@@ -758,6 +769,7 @@ function ensureGristReady(payload) {
758
769
  inFlight = next.catch((err) => {
759
770
  inFlight = null;
760
771
  lastAccess = null;
772
+ lastColumnNames = null;
761
773
  throw err;
762
774
  });
763
775
  return inFlight;
@@ -765,6 +777,7 @@ function ensureGristReady(payload) {
765
777
  function resetGristReadySingleton() {
766
778
  inFlight = null;
767
779
  lastAccess = null;
780
+ lastColumnNames = null;
768
781
  }
769
782
 
770
783
  // src/sdk/internal/build-manager-options.ts
@@ -1729,7 +1742,17 @@ function useGristHandshake(options = {}) {
1729
1742
  optionsRef.current = options;
1730
1743
  const managerRef = (0, import_react3.useRef)(null);
1731
1744
  if (managerRef.current === null) {
1732
- managerRef.current = createGristHandshakeManager(options);
1745
+ managerRef.current = createGristHandshakeManager({
1746
+ ...options,
1747
+ negotiate: {
1748
+ readyImpl: (payload) => ensureGristReady(payload),
1749
+ ...options.negotiate
1750
+ },
1751
+ onBeforeReload: () => {
1752
+ resetGristReadySingleton();
1753
+ options.onBeforeReload?.();
1754
+ }
1755
+ });
1733
1756
  }
1734
1757
  const manager = managerRef.current;
1735
1758
  (0, import_react3.useEffect)(() => {
@@ -1767,28 +1790,63 @@ function useGristCapabilities(options = {}) {
1767
1790
  return useGristHandshake(options).capabilities;
1768
1791
  }
1769
1792
 
1770
- // src/sdk/components/grist-handshake-provider.tsx
1793
+ // src/sdk/low-level-hooks/use-ambient-grist-handshake.ts
1771
1794
  var import_react4 = require("react");
1795
+ var noopSubscribe = () => () => {
1796
+ };
1797
+ var getInitialSnapshot = () => initialGristSnapshot();
1798
+ function useAmbientGristHandshake() {
1799
+ const manager = useGristManagerOptional();
1800
+ const snapshot = (0, import_react4.useSyncExternalStore)(
1801
+ manager?.subscribe ?? noopSubscribe,
1802
+ manager?.getSnapshot ?? getInitialSnapshot,
1803
+ getInitialSnapshot
1804
+ );
1805
+ return (0, import_react4.useMemo)(() => {
1806
+ if (!manager) return null;
1807
+ return {
1808
+ snapshot,
1809
+ status: deriveStatus(snapshot),
1810
+ error: deriveErrorMessage(snapshot),
1811
+ capabilities: deriveCapabilities(snapshot),
1812
+ reload: manager.reload,
1813
+ restart: manager.restart
1814
+ };
1815
+ }, [manager, snapshot]);
1816
+ }
1817
+
1818
+ // src/sdk/components/grist-handshake-provider.tsx
1819
+ var import_react5 = require("react");
1772
1820
  var import_jsx_runtime = require("react/jsx-runtime");
1773
- var GristHandshakeReactContext = (0, import_react4.createContext)(null);
1821
+ var GristHandshakeReactContext = (0, import_react5.createContext)(null);
1774
1822
  function GristHandshakeProvider({ options, children }) {
1775
- const managerRef = (0, import_react4.useRef)(null);
1823
+ const managerRef = (0, import_react5.useRef)(null);
1776
1824
  if (managerRef.current === null) {
1777
- managerRef.current = createGristHandshakeManager(options ?? {});
1825
+ managerRef.current = createGristHandshakeManager({
1826
+ ...options,
1827
+ negotiate: {
1828
+ readyImpl: (payload) => ensureGristReady(payload),
1829
+ ...options?.negotiate
1830
+ },
1831
+ onBeforeReload: () => {
1832
+ resetGristReadySingleton();
1833
+ options?.onBeforeReload?.();
1834
+ }
1835
+ });
1778
1836
  }
1779
1837
  const manager = managerRef.current;
1780
- (0, import_react4.useEffect)(() => {
1838
+ (0, import_react5.useEffect)(() => {
1781
1839
  manager.start();
1782
1840
  return () => {
1783
1841
  manager.stop();
1784
1842
  };
1785
1843
  }, [manager]);
1786
- const snapshot = (0, import_react4.useSyncExternalStore)(
1844
+ const snapshot = (0, import_react5.useSyncExternalStore)(
1787
1845
  manager.subscribe,
1788
1846
  manager.getSnapshot,
1789
1847
  initialGristSnapshot
1790
1848
  );
1791
- const value = (0, import_react4.useMemo)(
1849
+ const value = (0, import_react5.useMemo)(
1792
1850
  () => ({
1793
1851
  snapshot,
1794
1852
  status: deriveStatus(snapshot),
@@ -1804,7 +1862,7 @@ function GristHandshakeProvider({ options, children }) {
1804
1862
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GristHandshakeReactContext.Provider, { value, children });
1805
1863
  }
1806
1864
  function useGristHandshakeContext() {
1807
- const ctx = (0, import_react4.useContext)(GristHandshakeReactContext);
1865
+ const ctx = (0, import_react5.useContext)(GristHandshakeReactContext);
1808
1866
  if (!ctx) {
1809
1867
  throw new Error(
1810
1868
  "useGristHandshakeContext() must be used inside <GristHandshakeProvider>"
@@ -1813,17 +1871,17 @@ function useGristHandshakeContext() {
1813
1871
  return ctx;
1814
1872
  }
1815
1873
  function useGristHandshakeContextOptional() {
1816
- return (0, import_react4.useContext)(GristHandshakeReactContext);
1874
+ return (0, import_react5.useContext)(GristHandshakeReactContext);
1817
1875
  }
1818
1876
 
1819
1877
  // src/sdk/low-level-hooks/use-grist-record.ts
1820
- var import_react5 = require("react");
1878
+ var import_react6 = require("react");
1821
1879
  function useGristRecord(cb, options) {
1822
- const cbRef = (0, import_react5.useRef)(cb);
1823
- (0, import_react5.useEffect)(() => {
1880
+ const cbRef = (0, import_react6.useRef)(cb);
1881
+ (0, import_react6.useEffect)(() => {
1824
1882
  cbRef.current = cb;
1825
1883
  }, [cb]);
1826
- const [mappings, setMappings] = (0, import_react5.useState)(null);
1884
+ const [mappings, setMappings] = (0, import_react6.useState)(null);
1827
1885
  const { docApi, error: readyError } = useGristReady({
1828
1886
  requiredAccess: options?.requiredAccess ?? "read table",
1829
1887
  columns: options?.columns,
@@ -1831,7 +1889,7 @@ function useGristRecord(cb, options) {
1831
1889
  hasCustomOptions: options?.hasCustomOptions,
1832
1890
  onEditOptions: options?.onEditOptions
1833
1891
  });
1834
- (0, import_react5.useEffect)(() => {
1892
+ (0, import_react6.useEffect)(() => {
1835
1893
  if (!docApi) return;
1836
1894
  return recordEvent.subscribe(({ record, mappings: nextMappings }) => {
1837
1895
  setMappings(nextMappings);
@@ -1846,13 +1904,13 @@ function useGristRecord(cb, options) {
1846
1904
  }
1847
1905
 
1848
1906
  // src/sdk/low-level-hooks/use-grist-records.ts
1849
- var import_react6 = require("react");
1907
+ var import_react7 = require("react");
1850
1908
  function useGristRecords(cb, options) {
1851
- const cbRef = (0, import_react6.useRef)(cb);
1852
- (0, import_react6.useEffect)(() => {
1909
+ const cbRef = (0, import_react7.useRef)(cb);
1910
+ (0, import_react7.useEffect)(() => {
1853
1911
  cbRef.current = cb;
1854
1912
  }, [cb]);
1855
- const [mappings, setMappings] = (0, import_react6.useState)(null);
1913
+ const [mappings, setMappings] = (0, import_react7.useState)(null);
1856
1914
  const { docApi, error: readyError } = useGristReady({
1857
1915
  requiredAccess: options?.requiredAccess ?? "read table",
1858
1916
  columns: options?.columns,
@@ -1860,7 +1918,7 @@ function useGristRecords(cb, options) {
1860
1918
  hasCustomOptions: options?.hasCustomOptions,
1861
1919
  onEditOptions: options?.onEditOptions
1862
1920
  });
1863
- (0, import_react6.useEffect)(() => {
1921
+ (0, import_react7.useEffect)(() => {
1864
1922
  if (!docApi) return;
1865
1923
  return recordsEvent.subscribe(({ records, mappings: nextMappings }) => {
1866
1924
  setMappings(nextMappings);
@@ -1875,7 +1933,7 @@ function useGristRecords(cb, options) {
1875
1933
  }
1876
1934
 
1877
1935
  // src/sdk/low-level-hooks/use-grist-new-record.ts
1878
- var import_react7 = require("react");
1936
+ var import_react8 = require("react");
1879
1937
  function useGristNewRecord(options) {
1880
1938
  const { docApi, error: readyError } = useGristReady({
1881
1939
  requiredAccess: options?.requiredAccess ?? "read table",
@@ -1884,10 +1942,10 @@ function useGristNewRecord(options) {
1884
1942
  hasCustomOptions: options?.hasCustomOptions,
1885
1943
  onEditOptions: options?.onEditOptions
1886
1944
  });
1887
- const [isNewRecord, setIsNewRecord] = (0, import_react7.useState)(false);
1888
- const [mappings, setMappings] = (0, import_react7.useState)(null);
1889
- const subscribedRef = (0, import_react7.useRef)(false);
1890
- (0, import_react7.useEffect)(() => {
1945
+ const [isNewRecord, setIsNewRecord] = (0, import_react8.useState)(false);
1946
+ const [mappings, setMappings] = (0, import_react8.useState)(null);
1947
+ const subscribedRef = (0, import_react8.useRef)(false);
1948
+ (0, import_react8.useEffect)(() => {
1891
1949
  if (!docApi || subscribedRef.current) return;
1892
1950
  if (typeof grist.onNewRecord !== "function") return;
1893
1951
  subscribedRef.current = true;
@@ -1905,7 +1963,7 @@ function useGristNewRecord(options) {
1905
1963
  }
1906
1964
 
1907
1965
  // src/sdk/mid-level-hooks/use-grist-actions.ts
1908
- var import_react9 = require("react");
1966
+ var import_react10 = require("react");
1909
1967
 
1910
1968
  // src/sdk/helpers/grist-user-actions.ts
1911
1969
  function gristUpdateRecordAction(tableId, rowId, patch) {
@@ -1934,10 +1992,10 @@ function inferBulkLength(values) {
1934
1992
  }
1935
1993
 
1936
1994
  // src/sdk/internal/hooks/use-rpc-heartbeat-coalesce.ts
1937
- var import_react8 = require("react");
1995
+ var import_react9 = require("react");
1938
1996
  function useRpcHeartbeatCoalesce() {
1939
1997
  const manager = useGristManagerOptional();
1940
- return (0, import_react8.useCallback)(
1998
+ return (0, import_react9.useCallback)(
1941
1999
  async (fn) => {
1942
2000
  try {
1943
2001
  const result = await fn();
@@ -1961,10 +2019,10 @@ function useGristActions(options) {
1961
2019
  hasCustomOptions: options?.hasCustomOptions,
1962
2020
  onEditOptions: options?.onEditOptions
1963
2021
  });
1964
- const [status, setStatus] = (0, import_react9.useState)("idle");
1965
- const [actionError, setActionError] = (0, import_react9.useState)(null);
2022
+ const [status, setStatus] = (0, import_react10.useState)("idle");
2023
+ const [actionError, setActionError] = (0, import_react10.useState)(null);
1966
2024
  const coalesceRpc = useRpcHeartbeatCoalesce();
1967
- const apply = (0, import_react9.useCallback)(
2025
+ const apply = (0, import_react10.useCallback)(
1968
2026
  async (actions, applyOptions) => {
1969
2027
  if (!docApi) throw new Error("Grist docApi is not ready");
1970
2028
  setStatus("running");
@@ -1982,27 +2040,27 @@ function useGristActions(options) {
1982
2040
  },
1983
2041
  [docApi, coalesceRpc]
1984
2042
  );
1985
- const updateRecord = (0, import_react9.useCallback)(
2043
+ const updateRecord = (0, import_react10.useCallback)(
1986
2044
  (tableId, recordId, patch, applyOptions) => apply([gristUpdateRecordAction(tableId, recordId, patch)], applyOptions),
1987
2045
  [apply]
1988
2046
  );
1989
- const addRecord = (0, import_react9.useCallback)(
2047
+ const addRecord = (0, import_react10.useCallback)(
1990
2048
  (tableId, values, applyOptions) => apply([gristAddRecordAction(tableId, values)], applyOptions),
1991
2049
  [apply]
1992
2050
  );
1993
- const removeRecord = (0, import_react9.useCallback)(
2051
+ const removeRecord = (0, import_react10.useCallback)(
1994
2052
  (tableId, recordId, applyOptions) => apply([gristRemoveRecordAction(tableId, recordId)], applyOptions),
1995
2053
  [apply]
1996
2054
  );
1997
- const bulkAddRecord = (0, import_react9.useCallback)(
2055
+ const bulkAddRecord = (0, import_react10.useCallback)(
1998
2056
  (tableId, values, applyOptions) => apply([gristBulkAddRecordAction(tableId, values)], applyOptions),
1999
2057
  [apply]
2000
2058
  );
2001
- const bulkUpdateRecord = (0, import_react9.useCallback)(
2059
+ const bulkUpdateRecord = (0, import_react10.useCallback)(
2002
2060
  (tableId, rowIds, columnarPatch, applyOptions) => apply([gristBulkUpdateRecordAction(tableId, rowIds, columnarPatch)], applyOptions),
2003
2061
  [apply]
2004
2062
  );
2005
- const bulkRemoveRecord = (0, import_react9.useCallback)(
2063
+ const bulkRemoveRecord = (0, import_react10.useCallback)(
2006
2064
  (tableId, rowIds, applyOptions) => apply([gristBulkRemoveRecordAction(tableId, rowIds)], applyOptions),
2007
2065
  [apply]
2008
2066
  );
@@ -2020,7 +2078,7 @@ function useGristActions(options) {
2020
2078
  }
2021
2079
 
2022
2080
  // src/sdk/mid-level-hooks/use-grist-mapped-record.ts
2023
- var import_react10 = require("react");
2081
+ var import_react11 = require("react");
2024
2082
  function manualMapBack(patch, mappings) {
2025
2083
  if (!mappings) return { ...patch };
2026
2084
  const out = {};
@@ -2045,10 +2103,10 @@ function useGristMappedRecord(options) {
2045
2103
  hasCustomOptions: options?.hasCustomOptions,
2046
2104
  onEditOptions: options?.onEditOptions
2047
2105
  });
2048
- const [rawRecord, setRawRecord] = (0, import_react10.useState)(null);
2049
- const [mappedRecord, setMappedRecord] = (0, import_react10.useState)(null);
2050
- const [mappings, setMappings] = (0, import_react10.useState)(null);
2051
- (0, import_react10.useEffect)(() => {
2106
+ const [rawRecord, setRawRecord] = (0, import_react11.useState)(null);
2107
+ const [mappedRecord, setMappedRecord] = (0, import_react11.useState)(null);
2108
+ const [mappings, setMappings] = (0, import_react11.useState)(null);
2109
+ (0, import_react11.useEffect)(() => {
2052
2110
  if (!docApi) return;
2053
2111
  return recordEvent.subscribe(({ record, mappings: nextMappings }) => {
2054
2112
  setRawRecord(record);
@@ -2067,7 +2125,7 @@ function useGristMappedRecord(options) {
2067
2125
  setMappedRecord(record);
2068
2126
  });
2069
2127
  }, [docApi]);
2070
- const mapBack = (0, import_react10.useCallback)(
2128
+ const mapBack = (0, import_react11.useCallback)(
2071
2129
  (patch) => {
2072
2130
  if (typeof grist.mapColumnNamesBack === "function") {
2073
2131
  return grist.mapColumnNamesBack(patch);
@@ -2076,7 +2134,7 @@ function useGristMappedRecord(options) {
2076
2134
  },
2077
2135
  [mappings]
2078
2136
  );
2079
- const resolveColumnId = (0, import_react10.useCallback)(
2137
+ const resolveColumnId = (0, import_react11.useCallback)(
2080
2138
  (logicalName) => {
2081
2139
  const value = mappings?.[logicalName];
2082
2140
  if (Array.isArray(value)) return void 0;
@@ -2096,7 +2154,7 @@ function useGristMappedRecord(options) {
2096
2154
  }
2097
2155
 
2098
2156
  // src/sdk/mid-level-hooks/use-grist-table-ops.ts
2099
- var import_react11 = require("react");
2157
+ var import_react12 = require("react");
2100
2158
  function resolveOps(tableId) {
2101
2159
  if (tableId === "selected") {
2102
2160
  if (!grist.selectedTable) throw new Error("grist.selectedTable is not available");
@@ -2117,8 +2175,8 @@ function useGristTableOps(options) {
2117
2175
  hasCustomOptions: options?.hasCustomOptions,
2118
2176
  onEditOptions: options?.onEditOptions
2119
2177
  });
2120
- const [status, setStatus] = (0, import_react11.useState)("idle");
2121
- const [actionError, setActionError] = (0, import_react11.useState)(null);
2178
+ const [status, setStatus] = (0, import_react12.useState)("idle");
2179
+ const [actionError, setActionError] = (0, import_react12.useState)(null);
2122
2180
  const coalesceRpc = useRpcHeartbeatCoalesce();
2123
2181
  let ops = null;
2124
2182
  let resolveError = null;
@@ -2129,7 +2187,7 @@ function useGristTableOps(options) {
2129
2187
  resolveError = err instanceof Error ? err.message : String(err);
2130
2188
  }
2131
2189
  }
2132
- const wrap = (0, import_react11.useCallback)(
2190
+ const wrap = (0, import_react12.useCallback)(
2133
2191
  async (run) => {
2134
2192
  if (!ops) throw new Error("Grist table operations are not ready");
2135
2193
  setStatus("running");
@@ -2147,23 +2205,23 @@ function useGristTableOps(options) {
2147
2205
  },
2148
2206
  [ops, coalesceRpc]
2149
2207
  );
2150
- const getTableId = (0, import_react11.useCallback)(async () => {
2208
+ const getTableId = (0, import_react12.useCallback)(async () => {
2151
2209
  if (!ops) throw new Error("Grist table operations are not ready");
2152
2210
  return ops.getTableId();
2153
2211
  }, [ops]);
2154
- const create = (0, import_react11.useCallback)(
2212
+ const create = (0, import_react12.useCallback)(
2155
2213
  (records, opOptions) => wrap((o) => o.create(records, opOptions)),
2156
2214
  [wrap]
2157
2215
  );
2158
- const update = (0, import_react11.useCallback)(
2216
+ const update = (0, import_react12.useCallback)(
2159
2217
  (records, opOptions) => wrap((o) => o.update(records, opOptions)),
2160
2218
  [wrap]
2161
2219
  );
2162
- const upsert = (0, import_react11.useCallback)(
2220
+ const upsert = (0, import_react12.useCallback)(
2163
2221
  (records, opOptions) => wrap((o) => o.upsert(records, opOptions)),
2164
2222
  [wrap]
2165
2223
  );
2166
- const destroy = (0, import_react11.useCallback)(
2224
+ const destroy = (0, import_react12.useCallback)(
2167
2225
  (recordIds) => wrap((o) => o.destroy(recordIds)),
2168
2226
  [wrap]
2169
2227
  );
@@ -2179,7 +2237,7 @@ function useGristTableOps(options) {
2179
2237
  }
2180
2238
 
2181
2239
  // src/sdk/mid-level-hooks/use-grist-rows-from-table.ts
2182
- var import_react13 = require("react");
2240
+ var import_react14 = require("react");
2183
2241
 
2184
2242
  // src/sdk/helpers/grist-table-data.ts
2185
2243
  function tableDataToRows(data) {
@@ -2200,19 +2258,19 @@ function tableDataToRows(data) {
2200
2258
  }
2201
2259
 
2202
2260
  // src/sdk/internal/contexts.tsx
2203
- var import_react12 = require("react");
2204
- var GristCoreContext = (0, import_react12.createContext)(null);
2205
- var GristSelectionContext = (0, import_react12.createContext)(null);
2206
- var GristCurrentTableContext = (0, import_react12.createContext)(null);
2207
- var GristWritesContext = (0, import_react12.createContext)(null);
2208
- var GristReadsContext = (0, import_react12.createContext)(null);
2209
- var GristWidgetOptionsApiContext = (0, import_react12.createContext)(null);
2210
- var GristLinkingContext = (0, import_react12.createContext)(null);
2211
- var GristAttachmentsRestContext = (0, import_react12.createContext)(null);
2212
- var GristThemeContext = (0, import_react12.createContext)(null);
2213
- var GristSectionApiContext = (0, import_react12.createContext)(null);
2261
+ var import_react13 = require("react");
2262
+ var GristCoreContext = (0, import_react13.createContext)(null);
2263
+ var GristSelectionContext = (0, import_react13.createContext)(null);
2264
+ var GristCurrentTableContext = (0, import_react13.createContext)(null);
2265
+ var GristWritesContext = (0, import_react13.createContext)(null);
2266
+ var GristReadsContext = (0, import_react13.createContext)(null);
2267
+ var GristWidgetOptionsApiContext = (0, import_react13.createContext)(null);
2268
+ var GristLinkingContext = (0, import_react13.createContext)(null);
2269
+ var GristAttachmentsRestContext = (0, import_react13.createContext)(null);
2270
+ var GristThemeContext = (0, import_react13.createContext)(null);
2271
+ var GristSectionApiContext = (0, import_react13.createContext)(null);
2214
2272
  function useRequiredContext(ctx, name) {
2215
- const value = (0, import_react12.useContext)(ctx);
2273
+ const value = (0, import_react13.useContext)(ctx);
2216
2274
  if (!value) {
2217
2275
  throw new Error(`${name} must be used inside <GristWidgetProvider>`);
2218
2276
  }
@@ -2235,14 +2293,14 @@ function useGristRowsFromTable(options) {
2235
2293
  hasCustomOptions: options.hasCustomOptions,
2236
2294
  onEditOptions: options.onEditOptions
2237
2295
  });
2238
- const providerFetchTable = (0, import_react13.useContext)(GristReadsContext)?.fetchTable;
2239
- const [rows, setRows] = (0, import_react13.useState)(null);
2240
- const [loading, setLoading] = (0, import_react13.useState)(false);
2241
- const [fetchError, setFetchError] = (0, import_react13.useState)(null);
2242
- const transformRef = (0, import_react13.useRef)(options.transform);
2296
+ const providerFetchTable = (0, import_react14.useContext)(GristReadsContext)?.fetchTable;
2297
+ const [rows, setRows] = (0, import_react14.useState)(null);
2298
+ const [loading, setLoading] = (0, import_react14.useState)(false);
2299
+ const [fetchError, setFetchError] = (0, import_react14.useState)(null);
2300
+ const transformRef = (0, import_react14.useRef)(options.transform);
2243
2301
  transformRef.current = options.transform;
2244
2302
  const coalesceRpc = useRpcHeartbeatCoalesce();
2245
- const refresh = (0, import_react13.useCallback)(async () => {
2303
+ const refresh = (0, import_react14.useCallback)(async () => {
2246
2304
  if (!docApi) return;
2247
2305
  setLoading(true);
2248
2306
  setFetchError(null);
@@ -2260,10 +2318,10 @@ function useGristRowsFromTable(options) {
2260
2318
  setLoading(false);
2261
2319
  }
2262
2320
  }, [docApi, providerFetchTable, options.tableId, coalesceRpc]);
2263
- (0, import_react13.useEffect)(() => {
2321
+ (0, import_react14.useEffect)(() => {
2264
2322
  if (docApi) void refresh();
2265
2323
  }, [docApi, refresh]);
2266
- (0, import_react13.useEffect)(() => {
2324
+ (0, import_react14.useEffect)(() => {
2267
2325
  if (!docApi || !options.pollIntervalMs || options.pollIntervalMs <= 0) return;
2268
2326
  const id = window.setInterval(() => void refresh(), options.pollIntervalMs);
2269
2327
  return () => window.clearInterval(id);
@@ -2277,7 +2335,7 @@ function useGristRowsFromTable(options) {
2277
2335
  }
2278
2336
 
2279
2337
  // src/sdk/mid-level-hooks/use-grist-access-token.ts
2280
- var import_react14 = require("react");
2338
+ var import_react15 = require("react");
2281
2339
 
2282
2340
  // src/sdk/helpers/grist-fetch-with-auth.ts
2283
2341
  var TOKEN_TTL_MS = 45e3;
@@ -2349,10 +2407,10 @@ function useGristAccessToken(options) {
2349
2407
  hasCustomOptions: options?.hasCustomOptions,
2350
2408
  onEditOptions: options?.onEditOptions
2351
2409
  });
2352
- const [token, setToken] = (0, import_react14.useState)(null);
2353
- const [loading, setLoading] = (0, import_react14.useState)(false);
2354
- const [error, setError] = (0, import_react14.useState)(null);
2355
- const refresh = (0, import_react14.useCallback)(
2410
+ const [token, setToken] = (0, import_react15.useState)(null);
2411
+ const [loading, setLoading] = (0, import_react15.useState)(false);
2412
+ const [error, setError] = (0, import_react15.useState)(null);
2413
+ const refresh = (0, import_react15.useCallback)(
2356
2414
  async (overrides) => {
2357
2415
  if (!docApi) throw new Error("Grist is not ready");
2358
2416
  setLoading(true);
@@ -2371,14 +2429,14 @@ function useGristAccessToken(options) {
2371
2429
  },
2372
2430
  [docApi, readOnlyDefault]
2373
2431
  );
2374
- const fetchFn = (0, import_react14.useCallback)(
2432
+ const fetchFn = (0, import_react15.useCallback)(
2375
2433
  (path, init) => {
2376
2434
  if (!docApi) throw new Error("Grist is not ready");
2377
2435
  return fetchWithGristAuth(docApi, path, { readOnly: readOnlyDefault, ...init });
2378
2436
  },
2379
2437
  [docApi, readOnlyDefault]
2380
2438
  );
2381
- (0, import_react14.useEffect)(() => {
2439
+ (0, import_react15.useEffect)(() => {
2382
2440
  if (docApi && prefetch) void refresh();
2383
2441
  }, [docApi, prefetch, refresh]);
2384
2442
  return {
@@ -2391,7 +2449,7 @@ function useGristAccessToken(options) {
2391
2449
  }
2392
2450
 
2393
2451
  // src/sdk/mid-level-hooks/use-grist-section.ts
2394
- var import_react15 = require("react");
2452
+ var import_react16 = require("react");
2395
2453
  function useGristSection(options) {
2396
2454
  const { docApi, error: readyError } = useGristReady({
2397
2455
  requiredAccess: options?.requiredAccess ?? "read table",
@@ -2400,10 +2458,10 @@ function useGristSection(options) {
2400
2458
  hasCustomOptions: options?.hasCustomOptions,
2401
2459
  onEditOptions: options?.onEditOptions
2402
2460
  });
2403
- const [mappings, setMappings] = (0, import_react15.useState)(null);
2404
- const [loading, setLoading] = (0, import_react15.useState)(false);
2405
- const [error, setError] = (0, import_react15.useState)(null);
2406
- const refresh = (0, import_react15.useCallback)(async () => {
2461
+ const [mappings, setMappings] = (0, import_react16.useState)(null);
2462
+ const [loading, setLoading] = (0, import_react16.useState)(false);
2463
+ const [error, setError] = (0, import_react16.useState)(null);
2464
+ const refresh = (0, import_react16.useCallback)(async () => {
2407
2465
  if (!docApi) return;
2408
2466
  if (!grist.sectionApi?.mappings) {
2409
2467
  setError("grist.sectionApi.mappings is not available in this Grist version");
@@ -2420,13 +2478,13 @@ function useGristSection(options) {
2420
2478
  setLoading(false);
2421
2479
  }
2422
2480
  }, [docApi]);
2423
- const configure = (0, import_react15.useCallback)(async (next) => {
2481
+ const configure = (0, import_react16.useCallback)(async (next) => {
2424
2482
  if (!grist.sectionApi?.configure) {
2425
2483
  throw new Error("grist.sectionApi.configure is not available in this Grist version");
2426
2484
  }
2427
2485
  await grist.sectionApi.configure(next);
2428
2486
  }, []);
2429
- (0, import_react15.useEffect)(() => {
2487
+ (0, import_react16.useEffect)(() => {
2430
2488
  if (docApi) void refresh();
2431
2489
  }, [docApi, refresh]);
2432
2490
  return {
@@ -2439,7 +2497,7 @@ function useGristSection(options) {
2439
2497
  }
2440
2498
 
2441
2499
  // src/sdk/mid-level-hooks/use-grist-widget-options.ts
2442
- var import_react16 = require("react");
2500
+ var import_react17 = require("react");
2443
2501
  function mergeWithDefaults(defaults, stored, namespace) {
2444
2502
  if (stored === null || stored === void 0) return { ...defaults };
2445
2503
  const source = namespace ? stored[namespace] : stored;
@@ -2457,16 +2515,16 @@ function useGristWidgetOptions(config) {
2457
2515
  hasCustomOptions,
2458
2516
  onEditOptions: config.onEditOptions
2459
2517
  });
2460
- const defaultsRef = (0, import_react16.useRef)(config.defaults);
2461
- (0, import_react16.useEffect)(() => {
2518
+ const defaultsRef = (0, import_react17.useRef)(config.defaults);
2519
+ (0, import_react17.useEffect)(() => {
2462
2520
  defaultsRef.current = config.defaults;
2463
2521
  }, [config.defaults]);
2464
- const [options, setOptionsState] = (0, import_react16.useState)(() => ({ ...config.defaults }));
2465
- const [loading, setLoading] = (0, import_react16.useState)(true);
2466
- const [error, setError] = (0, import_react16.useState)(null);
2467
- const lastWrittenRef = (0, import_react16.useRef)(null);
2468
- const debounceRef = (0, import_react16.useRef)(null);
2469
- (0, import_react16.useEffect)(() => {
2522
+ const [options, setOptionsState] = (0, import_react17.useState)(() => ({ ...config.defaults }));
2523
+ const [loading, setLoading] = (0, import_react17.useState)(true);
2524
+ const [error, setError] = (0, import_react17.useState)(null);
2525
+ const lastWrittenRef = (0, import_react17.useRef)(null);
2526
+ const debounceRef = (0, import_react17.useRef)(null);
2527
+ (0, import_react17.useEffect)(() => {
2470
2528
  if (!docApi) return;
2471
2529
  return optionsEvent.subscribe(({ options: stored }) => {
2472
2530
  const merged = mergeWithDefaults(defaultsRef.current, stored, config.namespace);
@@ -2475,7 +2533,7 @@ function useGristWidgetOptions(config) {
2475
2533
  setLoading(false);
2476
2534
  });
2477
2535
  }, [docApi, config.namespace]);
2478
- const flushWrite = (0, import_react16.useCallback)(
2536
+ const flushWrite = (0, import_react17.useCallback)(
2479
2537
  async (value) => {
2480
2538
  try {
2481
2539
  if (config.namespace) {
@@ -2490,7 +2548,7 @@ function useGristWidgetOptions(config) {
2490
2548
  },
2491
2549
  [config.namespace]
2492
2550
  );
2493
- const scheduleWrite = (0, import_react16.useCallback)(
2551
+ const scheduleWrite = (0, import_react17.useCallback)(
2494
2552
  (value) => {
2495
2553
  if (debounceRef.current) window.clearTimeout(debounceRef.current);
2496
2554
  debounceRef.current = window.setTimeout(() => {
@@ -2500,19 +2558,19 @@ function useGristWidgetOptions(config) {
2500
2558
  },
2501
2559
  [debounceMs, flushWrite]
2502
2560
  );
2503
- (0, import_react16.useEffect)(() => {
2561
+ (0, import_react17.useEffect)(() => {
2504
2562
  return () => {
2505
2563
  if (debounceRef.current) window.clearTimeout(debounceRef.current);
2506
2564
  };
2507
2565
  }, []);
2508
- const setOptionsApi = (0, import_react16.useCallback)(
2566
+ const setOptionsApi = (0, import_react17.useCallback)(
2509
2567
  (next) => {
2510
2568
  setOptionsState(next);
2511
2569
  scheduleWrite(next);
2512
2570
  },
2513
2571
  [scheduleWrite]
2514
2572
  );
2515
- const patchOptionsApi = (0, import_react16.useCallback)(
2573
+ const patchOptionsApi = (0, import_react17.useCallback)(
2516
2574
  (patch) => {
2517
2575
  setOptionsState((prev) => {
2518
2576
  const next = { ...prev, ...patch };
@@ -2522,7 +2580,7 @@ function useGristWidgetOptions(config) {
2522
2580
  },
2523
2581
  [scheduleWrite]
2524
2582
  );
2525
- const reset = (0, import_react16.useCallback)(async () => {
2583
+ const reset = (0, import_react17.useCallback)(async () => {
2526
2584
  if (debounceRef.current) {
2527
2585
  window.clearTimeout(debounceRef.current);
2528
2586
  debounceRef.current = null;
@@ -2531,7 +2589,7 @@ function useGristWidgetOptions(config) {
2531
2589
  setOptionsState(next);
2532
2590
  await flushWrite(next);
2533
2591
  }, [flushWrite]);
2534
- return (0, import_react16.useMemo)(
2592
+ return (0, import_react17.useMemo)(
2535
2593
  () => ({
2536
2594
  options,
2537
2595
  loading,
@@ -2545,7 +2603,7 @@ function useGristWidgetOptions(config) {
2545
2603
  }
2546
2604
 
2547
2605
  // src/sdk/mid-level-hooks/use-grist-widget-options-from-context.ts
2548
- var import_react17 = require("react");
2606
+ var import_react18 = require("react");
2549
2607
  function mergeWithDefaults2(defaults, stored, namespace) {
2550
2608
  if (stored === null || stored === void 0) return { ...defaults };
2551
2609
  const source = namespace ? stored[namespace] : stored;
@@ -2556,23 +2614,23 @@ function useGristWidgetOptionsFromContext(config) {
2556
2614
  const debounceMs = config.debounceMs ?? 250;
2557
2615
  const selection = useGristSelectionContext();
2558
2616
  const optionsApi = useGristWidgetOptionsApiContext();
2559
- const defaultsRef = (0, import_react17.useRef)(config.defaults);
2560
- (0, import_react17.useEffect)(() => {
2617
+ const defaultsRef = (0, import_react18.useRef)(config.defaults);
2618
+ (0, import_react18.useEffect)(() => {
2561
2619
  defaultsRef.current = config.defaults;
2562
2620
  }, [config.defaults]);
2563
2621
  const rawOptions = selection.widgetOptions;
2564
2622
  const hasReceived = rawOptions !== null;
2565
- const merged = (0, import_react17.useMemo)(
2623
+ const merged = (0, import_react18.useMemo)(
2566
2624
  () => mergeWithDefaults2(defaultsRef.current, rawOptions, config.namespace),
2567
2625
  [rawOptions, config.namespace]
2568
2626
  );
2569
- const [localOverride, setLocalOverride] = (0, import_react17.useState)(null);
2627
+ const [localOverride, setLocalOverride] = (0, import_react18.useState)(null);
2570
2628
  const options = localOverride ?? merged;
2571
- (0, import_react17.useEffect)(() => {
2629
+ (0, import_react18.useEffect)(() => {
2572
2630
  setLocalOverride(null);
2573
2631
  }, [rawOptions]);
2574
- const debounceRef = (0, import_react17.useRef)(null);
2575
- const flushWrite = (0, import_react17.useCallback)(
2632
+ const debounceRef = (0, import_react18.useRef)(null);
2633
+ const flushWrite = (0, import_react18.useCallback)(
2576
2634
  async (value) => {
2577
2635
  if (config.namespace) {
2578
2636
  await optionsApi.setWidgetOption(config.namespace, value);
@@ -2582,7 +2640,7 @@ function useGristWidgetOptionsFromContext(config) {
2582
2640
  },
2583
2641
  [config.namespace, optionsApi]
2584
2642
  );
2585
- const scheduleWrite = (0, import_react17.useCallback)(
2643
+ const scheduleWrite = (0, import_react18.useCallback)(
2586
2644
  (value) => {
2587
2645
  if (debounceRef.current) window.clearTimeout(debounceRef.current);
2588
2646
  debounceRef.current = window.setTimeout(() => {
@@ -2592,19 +2650,19 @@ function useGristWidgetOptionsFromContext(config) {
2592
2650
  },
2593
2651
  [debounceMs, flushWrite]
2594
2652
  );
2595
- (0, import_react17.useEffect)(() => {
2653
+ (0, import_react18.useEffect)(() => {
2596
2654
  return () => {
2597
2655
  if (debounceRef.current) window.clearTimeout(debounceRef.current);
2598
2656
  };
2599
2657
  }, []);
2600
- const setOptions = (0, import_react17.useCallback)(
2658
+ const setOptions = (0, import_react18.useCallback)(
2601
2659
  (next) => {
2602
2660
  setLocalOverride(next);
2603
2661
  scheduleWrite(next);
2604
2662
  },
2605
2663
  [scheduleWrite]
2606
2664
  );
2607
- const patchOptions = (0, import_react17.useCallback)(
2665
+ const patchOptions = (0, import_react18.useCallback)(
2608
2666
  (patch) => {
2609
2667
  setLocalOverride((prev) => {
2610
2668
  const base = prev ?? merged;
@@ -2615,7 +2673,7 @@ function useGristWidgetOptionsFromContext(config) {
2615
2673
  },
2616
2674
  [merged, scheduleWrite]
2617
2675
  );
2618
- const reset = (0, import_react17.useCallback)(async () => {
2676
+ const reset = (0, import_react18.useCallback)(async () => {
2619
2677
  if (debounceRef.current) {
2620
2678
  window.clearTimeout(debounceRef.current);
2621
2679
  debounceRef.current = null;
@@ -2624,7 +2682,7 @@ function useGristWidgetOptionsFromContext(config) {
2624
2682
  setLocalOverride(null);
2625
2683
  await flushWrite(next);
2626
2684
  }, [flushWrite]);
2627
- return (0, import_react17.useMemo)(
2685
+ return (0, import_react18.useMemo)(
2628
2686
  () => ({
2629
2687
  options,
2630
2688
  loading: !hasReceived,
@@ -2637,7 +2695,7 @@ function useGristWidgetOptionsFromContext(config) {
2637
2695
  }
2638
2696
 
2639
2697
  // src/sdk/use-grist-table.ts
2640
- var import_react18 = require("react");
2698
+ var import_react19 = require("react");
2641
2699
  function isCurrentMode(option) {
2642
2700
  return option === void 0 || option === "current";
2643
2701
  }
@@ -2651,26 +2709,26 @@ function useGristTable(options) {
2651
2709
  hasCustomOptions: options?.hasCustomOptions,
2652
2710
  onEditOptions: options?.onEditOptions
2653
2711
  });
2654
- const [tableId, setTableId] = (0, import_react18.useState)(null);
2655
- const [loading, setLoading] = (0, import_react18.useState)(false);
2656
- const [error, setError] = (0, import_react18.useState)(null);
2657
- const fetchTable = (0, import_react18.useCallback)(
2712
+ const [tableId, setTableId] = (0, import_react19.useState)(null);
2713
+ const [loading, setLoading] = (0, import_react19.useState)(false);
2714
+ const [error, setError] = (0, import_react19.useState)(null);
2715
+ const fetchTable = (0, import_react19.useCallback)(
2658
2716
  async (targetTableId) => {
2659
2717
  if (!docApi) throw new Error("Grist is not ready");
2660
2718
  return docApi.fetchTable(targetTableId);
2661
2719
  },
2662
2720
  [docApi]
2663
2721
  );
2664
- const listTables = (0, import_react18.useCallback)(async () => {
2722
+ const listTables = (0, import_react19.useCallback)(async () => {
2665
2723
  if (!docApi) throw new Error("Grist is not ready");
2666
2724
  const out = await Promise.resolve(docApi.listTables());
2667
2725
  return [...out];
2668
2726
  }, [docApi]);
2669
- const getDocName = (0, import_react18.useCallback)(async () => {
2727
+ const getDocName = (0, import_react19.useCallback)(async () => {
2670
2728
  if (!docApi) throw new Error("Grist is not ready");
2671
2729
  return String(await Promise.resolve(docApi.getDocName()));
2672
2730
  }, [docApi]);
2673
- const fetchSelectedTable = (0, import_react18.useCallback)(
2731
+ const fetchSelectedTable = (0, import_react19.useCallback)(
2674
2732
  async (fetchOptions) => {
2675
2733
  if (!docApi) throw new Error("Grist is not ready");
2676
2734
  const impl = docApi.fetchSelectedTable ?? grist.fetchSelectedTable;
@@ -2680,7 +2738,7 @@ function useGristTable(options) {
2680
2738
  },
2681
2739
  [docApi]
2682
2740
  );
2683
- const fetchSelectedRecord = (0, import_react18.useCallback)(
2741
+ const fetchSelectedRecord = (0, import_react19.useCallback)(
2684
2742
  async (rowId, fetchOptions) => {
2685
2743
  if (!docApi) throw new Error("Grist is not ready");
2686
2744
  const impl = docApi.fetchSelectedRecord ?? grist.fetchSelectedRecord;
@@ -2690,7 +2748,7 @@ function useGristTable(options) {
2690
2748
  },
2691
2749
  [docApi]
2692
2750
  );
2693
- const refresh = (0, import_react18.useCallback)(async () => {
2751
+ const refresh = (0, import_react19.useCallback)(async () => {
2694
2752
  if (!docApi) return;
2695
2753
  if (!isCurrentMode(tableIdOption)) {
2696
2754
  setTableId(tableIdOption);
@@ -2709,7 +2767,7 @@ function useGristTable(options) {
2709
2767
  setLoading(false);
2710
2768
  }
2711
2769
  }, [docApi, tableIdOption]);
2712
- (0, import_react18.useEffect)(() => {
2770
+ (0, import_react19.useEffect)(() => {
2713
2771
  if (docApi) void refresh();
2714
2772
  }, [docApi, refresh]);
2715
2773
  return {
@@ -2727,6 +2785,7 @@ function useGristTable(options) {
2727
2785
  // Annotate the CommonJS export names for ESM import in node:
2728
2786
  0 && (module.exports = {
2729
2787
  GristHandshakeProvider,
2788
+ useAmbientGristHandshake,
2730
2789
  useGristAccessToken,
2731
2790
  useGristActions,
2732
2791
  useGristAvailability,