@flamingo-stack/openframe-frontend-core 0.0.718 → 0.0.720

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 (175) hide show
  1. package/dist/{chunk-MIQLUUVF.cjs → chunk-2C72EWQR.cjs} +93 -29
  2. package/dist/{chunk-IWCPXJEE.js → chunk-3HZ6XSZC.js} +2 -4
  3. package/dist/{chunk-ZXCZYMN4.cjs → chunk-4SIZCHVZ.cjs} +13 -15
  4. package/dist/{chunk-BOTM373R.cjs → chunk-5XDCCQ4A.cjs} +15 -15
  5. package/dist/{chunk-DXCBOZVT.cjs → chunk-6BLN5WDS.cjs} +41 -41
  6. package/dist/{chunk-DCD5WZUF.js → chunk-6W46LVK4.js} +5 -5
  7. package/dist/{chunk-JHQ334WS.js → chunk-742BGXNX.js} +2 -0
  8. package/dist/{chunk-AECTRMGQ.cjs → chunk-7GRPR7XA.cjs} +13 -1
  9. package/dist/{chunk-45F7PXUI.js → chunk-7HYEQKN6.js} +6 -6
  10. package/dist/{chunk-N2PF5CFX.js → chunk-7IOU6BJE.js} +12 -11
  11. package/dist/{chunk-BWIN42ZA.cjs → chunk-7LPR4RZ3.cjs} +34 -36
  12. package/dist/chunk-AFTRPEXO.js +13 -0
  13. package/dist/{chunk-JPD4NXH6.js → chunk-AZRI4XBP.js} +1 -1
  14. package/dist/{chunk-4QFWGLZO.js → chunk-B2N4YX66.js} +1 -1
  15. package/dist/{chunk-QXZCLQNV.js → chunk-B5LNX4GZ.js} +2 -2
  16. package/dist/{chunk-GN4A7PMB.cjs → chunk-DHNJSQGX.cjs} +91 -91
  17. package/dist/{chunk-NDZ5ZXOQ.cjs → chunk-DOPOHO6H.cjs} +20 -20
  18. package/dist/{chunk-Z3CVSPO3.cjs → chunk-DYDDAA6O.cjs} +519 -518
  19. package/dist/{chunk-2RKFMUNW.cjs → chunk-EVMM3JE6.cjs} +64 -63
  20. package/dist/chunk-EWPR7662.cjs +13 -0
  21. package/dist/{chunk-AGVXKD4K.js → chunk-FSQQZFVG.js} +12 -0
  22. package/dist/{chunk-TTVOLEUS.js → chunk-GANIUMRU.js} +89 -2
  23. package/dist/{chunk-S2FUFMLW.cjs → chunk-HFEYEPOG.cjs} +27 -27
  24. package/dist/{chunk-LE5WKGJV.cjs → chunk-HTS46FFY.cjs} +3 -3
  25. package/dist/{chunk-6A43ZDWV.cjs → chunk-IL3ZWNM2.cjs} +4 -4
  26. package/dist/{chunk-PSVSEN4J.cjs → chunk-IMTY3GRR.cjs} +2 -0
  27. package/dist/{chunk-YC5COB5V.cjs → chunk-ISCZ6UNF.cjs} +85 -89
  28. package/dist/{chunk-XGHGGBM3.js → chunk-K2BYVPGR.js} +3 -3
  29. package/dist/{chunk-HWVUR735.cjs → chunk-KSGMZHVV.cjs} +2 -2
  30. package/dist/{chunk-SGFTTJKO.js → chunk-LO3KCLEF.js} +1 -1
  31. package/dist/{chunk-MA4Q5RBP.cjs → chunk-NYSMDM4J.cjs} +2 -2
  32. package/dist/{chunk-67QBMN4R.js → chunk-O3MKJU6A.js} +6 -6
  33. package/dist/{chunk-APJZBDQN.js → chunk-PSMJYZMV.js} +27 -26
  34. package/dist/{chunk-JH2SIWPQ.js → chunk-PXAKSPLZ.js} +1586 -1263
  35. package/dist/{chunk-TBCZCRQ5.js → chunk-Q5327DXK.js} +13 -17
  36. package/dist/{chunk-EZC2F5OT.cjs → chunk-QF464PPL.cjs} +39 -39
  37. package/dist/{chunk-UWQWMGJ7.cjs → chunk-RDP5UZXQ.cjs} +888 -565
  38. package/dist/{chunk-ETYLOZOB.cjs → chunk-RFUOIQSG.cjs} +100 -13
  39. package/dist/{chunk-DC4RTYWK.cjs → chunk-RZQGIWK3.cjs} +3 -3
  40. package/dist/{chunk-PQ6HBLZ7.js → chunk-TORERAXD.js} +105 -41
  41. package/dist/{chunk-6YPTUHM7.js → chunk-URW23QUM.js} +1 -1
  42. package/dist/{chunk-QBCDSTLE.cjs → chunk-UWJMDFDO.cjs} +18 -18
  43. package/dist/{chunk-YEMCCYIF.js → chunk-V6B2FBZK.js} +5 -5
  44. package/dist/{chunk-JIWMBIVZ.js → chunk-VBHGJFA3.js} +10 -10
  45. package/dist/{chunk-Z5UWW3Z2.cjs → chunk-VF2CJXZ2.cjs} +81 -65
  46. package/dist/{chunk-DEZDMTBM.js → chunk-VYVPII4W.js} +8 -10
  47. package/dist/{chunk-MM7MCIXL.js → chunk-VYZCKY5K.js} +9 -9
  48. package/dist/{chunk-E7YCPY7K.cjs → chunk-XSM46FHD.cjs} +3 -3
  49. package/dist/{chunk-NZ5BHDFZ.js → chunk-XW3Q623Q.js} +1 -1
  50. package/dist/{chunk-LOYPRJWA.js → chunk-YK3X74SF.js} +67 -51
  51. package/dist/{chunk-WALCXC7J.cjs → chunk-ZHD3F2TH.cjs} +3 -3
  52. package/dist/{chunk-KBJJQFYU.js → chunk-ZPHOQDAE.js} +1 -1
  53. package/dist/{cloud-tenants-TAKOWXLD.js → cloud-tenants-RKQRSDNE.js} +9 -9
  54. package/dist/{cloud-tenants-PFDF7O5U.cjs → cloud-tenants-UQZASXUB.cjs} +10 -10
  55. package/dist/components/case-studies/index.cjs +23 -23
  56. package/dist/components/case-studies/index.js +10 -10
  57. package/dist/components/chat/ask-prompts.d.ts +10 -2
  58. package/dist/components/chat/ask-prompts.d.ts.map +1 -1
  59. package/dist/components/chat/assistant-ask-prompts.d.ts +27 -0
  60. package/dist/components/chat/assistant-ask-prompts.d.ts.map +1 -0
  61. package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
  62. package/dist/components/chat/hooks/index.d.ts +1 -0
  63. package/dist/components/chat/hooks/index.d.ts.map +1 -1
  64. package/dist/components/chat/hooks/use-ask-prompts.d.ts +63 -0
  65. package/dist/components/chat/hooks/use-ask-prompts.d.ts.map +1 -0
  66. package/dist/components/chat/index.cjs +23 -6
  67. package/dist/components/chat/index.d.ts +1 -0
  68. package/dist/components/chat/index.d.ts.map +1 -1
  69. package/dist/components/chat/index.js +22 -5
  70. package/dist/components/chat/utils/icon-library.d.ts.map +1 -1
  71. package/dist/components/contact/index.cjs +11 -11
  72. package/dist/components/contact/index.js +10 -10
  73. package/dist/components/docs/index.cjs +14 -14
  74. package/dist/components/docs/index.js +13 -13
  75. package/dist/components/embeds/index.cjs +11 -11
  76. package/dist/components/embeds/index.js +10 -10
  77. package/dist/components/faq/faq-ask-card.d.ts +44 -0
  78. package/dist/components/faq/faq-ask-card.d.ts.map +1 -0
  79. package/dist/components/faq/faq-document-page.d.ts +5 -1
  80. package/dist/components/faq/faq-document-page.d.ts.map +1 -1
  81. package/dist/components/faq/faq-section.d.ts +18 -5
  82. package/dist/components/faq/faq-section.d.ts.map +1 -1
  83. package/dist/components/faq/index.cjs +13 -12
  84. package/dist/components/faq/index.d.ts +1 -0
  85. package/dist/components/faq/index.d.ts.map +1 -1
  86. package/dist/components/faq/index.js +12 -11
  87. package/dist/components/features/auth/auth-benefits-panel.d.ts.map +1 -1
  88. package/dist/components/features/index.cjs +10 -10
  89. package/dist/components/features/index.js +9 -9
  90. package/dist/components/features/remote-session/remote-desktop-view.d.ts +6 -2
  91. package/dist/components/features/remote-session/remote-desktop-view.d.ts.map +1 -1
  92. package/dist/components/help-center-pages/index.cjs +104 -105
  93. package/dist/components/help-center-pages/index.js +28 -29
  94. package/dist/components/help-center-pages/trust-center-page.d.ts +4 -1
  95. package/dist/components/help-center-pages/trust-center-page.d.ts.map +1 -1
  96. package/dist/components/index.cjs +109 -197
  97. package/dist/components/index.js +228 -316
  98. package/dist/components/meeting-scheduler/index.cjs +50 -51
  99. package/dist/components/meeting-scheduler/index.js +12 -13
  100. package/dist/components/navigation/index.cjs +13 -13
  101. package/dist/components/navigation/index.js +12 -12
  102. package/dist/components/navigation/mingo-ai-button.d.ts +1 -1
  103. package/dist/components/navigation/mingo-ai-button.d.ts.map +1 -1
  104. package/dist/components/onboarding-guides/index.cjs +13 -14
  105. package/dist/components/onboarding-guides/index.js +12 -13
  106. package/dist/components/product-demo/index.cjs +7 -7
  107. package/dist/components/product-demo/index.js +7 -7
  108. package/dist/components/related-content/index.cjs +5 -7
  109. package/dist/components/related-content/index.js +4 -6
  110. package/dist/components/related-content/related-content-section.d.ts +6 -6
  111. package/dist/components/related-content/related-content-section.d.ts.map +1 -1
  112. package/dist/components/tickets/index.cjs +15 -15
  113. package/dist/components/tickets/index.js +14 -14
  114. package/dist/components/ui/index.cjs +26 -10
  115. package/dist/components/ui/index.js +25 -9
  116. package/dist/contexts/assistant-runtime-context.d.ts +74 -0
  117. package/dist/contexts/assistant-runtime-context.d.ts.map +1 -0
  118. package/dist/contexts/index.cjs +7 -1
  119. package/dist/contexts/index.d.ts +1 -0
  120. package/dist/contexts/index.d.ts.map +1 -1
  121. package/dist/contexts/index.js +6 -0
  122. package/dist/{devices-KRCGZMGA.cjs → devices-7Q2EUM7B.cjs} +11 -11
  123. package/dist/{devices-LHEX7O5T.js → devices-U3Y4IIW4.js} +9 -9
  124. package/dist/hooks/index.cjs +3 -4
  125. package/dist/hooks/index.js +2 -3
  126. package/dist/hooks/use-self-fetch.d.ts +3 -0
  127. package/dist/hooks/use-self-fetch.d.ts.map +1 -1
  128. package/dist/index.cjs +34 -14
  129. package/dist/index.js +33 -13
  130. package/dist/{knowledge-RZSFNR33.js → knowledge-NST53EXE.js} +9 -9
  131. package/dist/{knowledge-KLVPVEYZ.cjs → knowledge-UYIZ74MA.cjs} +11 -11
  132. package/dist/{logs-OX3XTVL2.cjs → logs-HTH7X7KV.cjs} +18 -18
  133. package/dist/{logs-E5DOV5JO.js → logs-JVTRG232.js} +9 -9
  134. package/dist/{policies-MC2S4S5G.js → policies-DTXTRK56.js} +9 -9
  135. package/dist/{policies-FOSCIZGK.cjs → policies-MXK2HB4W.cjs} +14 -14
  136. package/dist/{remote-session-JQ2BPIE3.js → remote-session-LAJZKQBN.js} +3 -3
  137. package/dist/{remote-session-DRFE5XZE.cjs → remote-session-SKKF4PBV.cjs} +5 -5
  138. package/dist/{software-update-D4OEIH65.js → software-update-6RHMPM3W.js} +9 -9
  139. package/dist/{software-update-HOBSTWVO.cjs → software-update-P6BSM6HX.cjs} +14 -14
  140. package/dist/utils/index.cjs +26 -2
  141. package/dist/utils/index.d.ts +1 -0
  142. package/dist/utils/index.d.ts.map +1 -1
  143. package/dist/utils/index.js +25 -3
  144. package/dist/utils/list-url.d.ts.map +1 -1
  145. package/dist/utils/source-icons.d.ts.map +1 -1
  146. package/dist/utils/trial.d.ts +18 -0
  147. package/dist/utils/trial.d.ts.map +1 -0
  148. package/package.json +1 -1
  149. package/src/components/chat/ask-prompts.tsx +25 -3
  150. package/src/components/chat/assistant-ask-prompts.tsx +78 -0
  151. package/src/components/chat/entity-cards/dispatch.tsx +38 -4
  152. package/src/components/chat/hooks/index.ts +12 -0
  153. package/src/components/chat/hooks/use-ask-prompts.ts +188 -0
  154. package/src/components/chat/index.ts +1 -0
  155. package/src/components/chat/utils/icon-library.tsx +6 -0
  156. package/src/components/faq/faq-ask-card.tsx +115 -0
  157. package/src/components/faq/faq-document-page.tsx +6 -1
  158. package/src/components/faq/faq-section.tsx +27 -5
  159. package/src/components/faq/index.ts +1 -0
  160. package/src/components/features/auth/auth-benefits-panel.tsx +5 -4
  161. package/src/components/features/remote-session/remote-desktop-view.tsx +86 -63
  162. package/src/components/help-center-pages/trust-center-page.tsx +5 -2
  163. package/src/components/navigation/mingo-ai-button.tsx +27 -6
  164. package/src/components/related-content/related-content-section.tsx +46 -47
  165. package/src/contexts/assistant-runtime-context.tsx +84 -0
  166. package/src/contexts/index.ts +9 -0
  167. package/src/hooks/use-self-fetch.ts +7 -0
  168. package/src/utils/index.ts +1 -0
  169. package/src/utils/list-url.ts +4 -0
  170. package/src/utils/source-icons.ts +10 -2
  171. package/src/utils/trial.ts +19 -0
  172. package/dist/chunk-AUMKE74M.cjs +0 -16
  173. package/dist/chunk-G3GRYDMS.js +0 -16
  174. package/dist/chunk-GEDY7HQI.cjs +0 -85
  175. package/dist/chunk-YBQQNDC7.js +0 -85
@@ -54,8 +54,12 @@ export const SOURCE_ICON_NAMES: Record<string, string> = {
54
54
  'audience-mssp': 'shield-lock',
55
55
  'audience-it-team': 'buildings',
56
56
 
57
- // Trust (single-record live source over the public Vanta projection)
58
- 'trust-center': 'shield',
57
+ // Trust (single-record live source over the public Vanta projection): the icon its menu entry draws
58
+ 'trust-center': 'shield-check',
59
+ // The public website's own pages (live source): the site's own mark, as a glyph in the slot's colour
60
+ 'website-pages': 'flamingo-logo-grey',
61
+ // The OpenMSP vendor directory: the icon the site menu's "Tool directory" entry draws (it reads this one)
62
+ vendors: 'package-search',
59
63
 
60
64
  // Financials
61
65
  'investor-updates': 'mail',
@@ -145,6 +149,8 @@ export const SOURCE_LABELS_BY_TABLE: Record<string, string> = {
145
149
 
146
150
  // Trust
147
151
  'trust-center': 'Trust Center',
152
+ 'website-pages': 'Website',
153
+ vendors: 'Vendor Directory',
148
154
 
149
155
  // Financials
150
156
  'investor-updates': 'Investor Updates',
@@ -248,6 +254,8 @@ export const DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID: Record<string, string> = {
248
254
 
249
255
  // Trust
250
256
  trust_center: 'trust-center',
257
+ site_page: 'website-pages',
258
+ vendor: 'vendors',
251
259
 
252
260
  // Financials
253
261
  investor_update: 'investor-updates',
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The free trial's facts and the words every surface says them with: the
3
+ * sign-up panel here, and the host site's trial buttons, trust rows and pricing
4
+ * copy. Stated once, so a trial that changes length changes everywhere.
5
+ *
6
+ * Server-safe (no React, no DOM).
7
+ */
8
+
9
+ /** How long the free trial runs, in days. */
10
+ export const TRIAL_DAYS = 14;
11
+
12
+ /** The reassurance labels shown beside a trial button. */
13
+ export const TRIAL_LABELS = {
14
+ /** "14 day free trial" */
15
+ length: `${TRIAL_DAYS} day free trial`,
16
+ noCard: 'No card required',
17
+ cancel: 'Cancel Anytime',
18
+ noContract: 'No Contract',
19
+ } as const;
@@ -1,16 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
-
3
-
4
-
5
- var _chunkULWVKHSIcjs = require('./chunk-ULWVKHSI.cjs');
6
-
7
- // src/utils/embed-content-fetch.ts
8
- var contentFetch = (input, init) => {
9
- if (!_chunkULWVKHSIcjs.hasEmbedAuthAdapter.call(void 0, )) return fetch(input, init);
10
- const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
11
- return _chunkULWVKHSIcjs.embedAuthedFetch.call(void 0, url, init);
12
- };
13
-
14
-
15
-
16
- exports.contentFetch = contentFetch;
@@ -1,16 +0,0 @@
1
- "use client";
2
- import {
3
- embedAuthedFetch,
4
- hasEmbedAuthAdapter
5
- } from "./chunk-ADBE7QF3.js";
6
-
7
- // src/utils/embed-content-fetch.ts
8
- var contentFetch = (input, init) => {
9
- if (!hasEmbedAuthAdapter()) return fetch(input, init);
10
- const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
11
- return embedAuthedFetch(url, init);
12
- };
13
-
14
- export {
15
- contentFetch
16
- };
@@ -1,85 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
-
3
-
4
- var _chunkAUMKE74Mcjs = require('./chunk-AUMKE74M.cjs');
5
-
6
- // src/hooks/use-self-fetch.ts
7
- var _react = require('react');
8
- function useSelfFetch(url, options) {
9
- const initialData = _optionalChain([options, 'optionalAccess', _ => _.initialData]);
10
- const revalidateOnVisibleAfterMs = _optionalChain([options, 'optionalAccess', _2 => _2.revalidateOnVisibleAfterMs]);
11
- const [data, setData] = _react.useState.call(void 0, _nullishCoalesce(initialData, () => ( null)));
12
- const [isLoading, setIsLoading] = _react.useState.call(void 0, initialData === void 0 && url !== null);
13
- const [error, setError] = _react.useState.call(void 0, false);
14
- const [reloadKey, setReloadKey] = _react.useState.call(void 0, 0);
15
- const [mountedAt] = _react.useState.call(void 0, () => Date.now());
16
- const dataAtRef = _react.useRef.call(void 0, initialData !== void 0 ? mountedAt : 0);
17
- const dataUrlRef = _react.useRef.call(void 0, initialData !== void 0 ? url : null);
18
- const [syncedProps, setSyncedProps] = _react.useState.call(void 0, { url, initialData });
19
- if (syncedProps.url !== url || syncedProps.initialData !== initialData) {
20
- setSyncedProps({ url, initialData });
21
- if (syncedProps.initialData !== initialData && initialData !== void 0) {
22
- setData(initialData);
23
- }
24
- if (syncedProps.url !== url && url === null) {
25
- setIsLoading(false);
26
- }
27
- }
28
- _react.useEffect.call(void 0, () => {
29
- if (url === null) return void 0;
30
- if (dataUrlRef.current === url) return void 0;
31
- const ctrl = new AbortController();
32
- let cancelled = false;
33
- async function load() {
34
- try {
35
- setIsLoading(true);
36
- setError(false);
37
- const res = await _chunkAUMKE74Mcjs.contentFetch.call(void 0, url, { signal: ctrl.signal });
38
- if (!res.ok) throw new Error(`Request failed (${res.status})`);
39
- const json = await res.json();
40
- if (!cancelled) {
41
- setData(json);
42
- dataUrlRef.current = url;
43
- dataAtRef.current = Date.now();
44
- }
45
- } catch (err) {
46
- if (cancelled || _optionalChain([err, 'optionalAccess', _3 => _3.name]) === "AbortError") return;
47
- setError(true);
48
- console.error("useSelfFetch:", url, err);
49
- } finally {
50
- if (!cancelled) setIsLoading(false);
51
- }
52
- }
53
- void load();
54
- return () => {
55
- cancelled = true;
56
- ctrl.abort();
57
- };
58
- }, [url, reloadKey]);
59
- const forceReload = () => {
60
- dataUrlRef.current = null;
61
- setReloadKey((k) => k + 1);
62
- };
63
- _react.useEffect.call(void 0, () => {
64
- if (!revalidateOnVisibleAfterMs || url === null) return void 0;
65
- const onVisible = () => {
66
- if (document.visibilityState !== "visible") return;
67
- if (Date.now() - dataAtRef.current < revalidateOnVisibleAfterMs) return;
68
- forceReload();
69
- };
70
- document.addEventListener("visibilitychange", onVisible);
71
- return () => document.removeEventListener("visibilitychange", onVisible);
72
- }, [url, revalidateOnVisibleAfterMs]);
73
- return {
74
- data,
75
- setData,
76
- isLoading,
77
- error,
78
- // Force a re-fetch of the current url (error-retry affordance).
79
- reload: forceReload
80
- };
81
- }
82
-
83
-
84
-
85
- exports.useSelfFetch = useSelfFetch;
@@ -1,85 +0,0 @@
1
- "use client";
2
- import {
3
- contentFetch
4
- } from "./chunk-G3GRYDMS.js";
5
-
6
- // src/hooks/use-self-fetch.ts
7
- import { useEffect, useRef, useState } from "react";
8
- function useSelfFetch(url, options) {
9
- const initialData = options?.initialData;
10
- const revalidateOnVisibleAfterMs = options?.revalidateOnVisibleAfterMs;
11
- const [data, setData] = useState(initialData ?? null);
12
- const [isLoading, setIsLoading] = useState(initialData === void 0 && url !== null);
13
- const [error, setError] = useState(false);
14
- const [reloadKey, setReloadKey] = useState(0);
15
- const [mountedAt] = useState(() => Date.now());
16
- const dataAtRef = useRef(initialData !== void 0 ? mountedAt : 0);
17
- const dataUrlRef = useRef(initialData !== void 0 ? url : null);
18
- const [syncedProps, setSyncedProps] = useState({ url, initialData });
19
- if (syncedProps.url !== url || syncedProps.initialData !== initialData) {
20
- setSyncedProps({ url, initialData });
21
- if (syncedProps.initialData !== initialData && initialData !== void 0) {
22
- setData(initialData);
23
- }
24
- if (syncedProps.url !== url && url === null) {
25
- setIsLoading(false);
26
- }
27
- }
28
- useEffect(() => {
29
- if (url === null) return void 0;
30
- if (dataUrlRef.current === url) return void 0;
31
- const ctrl = new AbortController();
32
- let cancelled = false;
33
- async function load() {
34
- try {
35
- setIsLoading(true);
36
- setError(false);
37
- const res = await contentFetch(url, { signal: ctrl.signal });
38
- if (!res.ok) throw new Error(`Request failed (${res.status})`);
39
- const json = await res.json();
40
- if (!cancelled) {
41
- setData(json);
42
- dataUrlRef.current = url;
43
- dataAtRef.current = Date.now();
44
- }
45
- } catch (err) {
46
- if (cancelled || err?.name === "AbortError") return;
47
- setError(true);
48
- console.error("useSelfFetch:", url, err);
49
- } finally {
50
- if (!cancelled) setIsLoading(false);
51
- }
52
- }
53
- void load();
54
- return () => {
55
- cancelled = true;
56
- ctrl.abort();
57
- };
58
- }, [url, reloadKey]);
59
- const forceReload = () => {
60
- dataUrlRef.current = null;
61
- setReloadKey((k) => k + 1);
62
- };
63
- useEffect(() => {
64
- if (!revalidateOnVisibleAfterMs || url === null) return void 0;
65
- const onVisible = () => {
66
- if (document.visibilityState !== "visible") return;
67
- if (Date.now() - dataAtRef.current < revalidateOnVisibleAfterMs) return;
68
- forceReload();
69
- };
70
- document.addEventListener("visibilitychange", onVisible);
71
- return () => document.removeEventListener("visibilitychange", onVisible);
72
- }, [url, revalidateOnVisibleAfterMs]);
73
- return {
74
- data,
75
- setData,
76
- isLoading,
77
- error,
78
- // Force a re-fetch of the current url (error-retry affordance).
79
- reload: forceReload
80
- };
81
- }
82
-
83
- export {
84
- useSelfFetch
85
- };