@hook-sdk/template 0.7.3 → 0.8.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.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/AppRoot.tsx
2
- import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef3, useState as useState11 } from "react";
2
+ import { useCallback as useCallback7, useEffect as useEffect8, useRef as useRef3, useState as useState12 } from "react";
3
3
  import { useHook as useHook8 } from "@hook-sdk/sdk";
4
4
 
5
5
  // src/internal/TemplateConfigContext.tsx
@@ -213,17 +213,37 @@ function SubscriptionGate({ Paywall, children }) {
213
213
  }
214
214
 
215
215
  // src/internal/PersistedKeysPrefetch.tsx
216
- import { useEffect as useEffect3 } from "react";
216
+ import { useEffect as useEffect3, useState as useState3 } from "react";
217
217
  import { useHook as useHook3 } from "@hook-sdk/sdk";
218
218
  import { Fragment as Fragment3, jsx as jsx6 } from "react/jsx-runtime";
219
+ var SAFETY_TIMEOUT_MS = 3e3;
219
220
  function PersistedKeysPrefetch({ children }) {
220
221
  const { appData } = useHook3();
221
222
  const config = useTemplateConfig();
223
+ const hasKeys = !!config.persistedKeys && config.persistedKeys.length > 0;
224
+ const [ready, setReady] = useState3(!hasKeys);
222
225
  useEffect3(() => {
223
226
  const keys = config.persistedKeys;
224
- if (!keys || keys.length === 0) return;
227
+ if (!keys || keys.length === 0) {
228
+ setReady(true);
229
+ return;
230
+ }
231
+ let cancelled = false;
225
232
  appData.cache.startPrefetch(keys, (ks) => appData.bulkRead(ks));
233
+ void appData.cache.waitForPrimed(SAFETY_TIMEOUT_MS).then((result) => {
234
+ if (cancelled) return;
235
+ if (result === "timeout") {
236
+ console.warn(
237
+ `[@hook-sdk/template] PersistedKeysPrefetch: bulk-read n\xE3o completou em ${SAFETY_TIMEOUT_MS}ms. Liberando render mesmo assim \u2014 usePersistedState pode expor defaultValue at\xE9 o fetch terminar (G77).`
238
+ );
239
+ }
240
+ setReady(true);
241
+ });
242
+ return () => {
243
+ cancelled = true;
244
+ };
226
245
  }, [appData, config.persistedKeys]);
246
+ if (!ready) return null;
227
247
  return /* @__PURE__ */ jsx6(Fragment3, { children });
228
248
  }
229
249
 
@@ -236,7 +256,7 @@ function PushPrompt() {
236
256
  import { useEffect as useEffect5, useRef as useRef2 } from "react";
237
257
 
238
258
  // src/hooks/useInstallPrompt.ts
239
- import { useCallback as useCallback2, useEffect as useEffect4, useState as useState3 } from "react";
259
+ import { useCallback as useCallback2, useEffect as useEffect4, useState as useState4 } from "react";
240
260
  var IOS_RE = /iPad|iPhone|iPod/;
241
261
  var IOS_NON_SAFARI_RE = /CriOS|FxiOS|EdgiOS/;
242
262
  var ANDROID_RE = /Android/;
@@ -369,17 +389,17 @@ function useInstallPrompt(slug) {
369
389
  const iosBrowser = detectIOSBrowser(ua);
370
390
  const androidBrowser = detectAndroidBrowser(ua);
371
391
  const inAppApp = detectInAppApp(ua);
372
- const [isInstallable, setIsInstallable] = useState3(() => {
392
+ const [isInstallable, setIsInstallable] = useState4(() => {
373
393
  if (typeof window === "undefined") return false;
374
394
  return window.__pwaInstallPrompt != null;
375
395
  });
376
- const [isInstalled, setIsInstalled] = useState3(() => {
396
+ const [isInstalled, setIsInstalled] = useState4(() => {
377
397
  const { installed } = detectStandalone();
378
398
  return installed || readInstalledMarker(slug);
379
399
  });
380
- const [isDismissedSession, setIsDismissedSession] = useState3(() => readSessionSkip(slug));
381
- const [isDismissedPermanent, setIsDismissedPermanent] = useState3(() => readPermanentDismiss(slug).dismissed);
382
- const [skipCount, setSkipCount] = useState3(() => readSkipCount(slug));
400
+ const [isDismissedSession, setIsDismissedSession] = useState4(() => readSessionSkip(slug));
401
+ const [isDismissedPermanent, setIsDismissedPermanent] = useState4(() => readPermanentDismiss(slug).dismissed);
402
+ const [skipCount, setSkipCount] = useState4(() => readSkipCount(slug));
383
403
  useEffect4(() => {
384
404
  if (typeof window === "undefined") return;
385
405
  if (window.__pwaInstallPrompt) {
@@ -1234,7 +1254,7 @@ function IOSOtherVariant({
1234
1254
  }
1235
1255
 
1236
1256
  // src/components/InstallGate/variants/InAppBrowserVariant.tsx
1237
- import { useState as useState4 } from "react";
1257
+ import { useState as useState5 } from "react";
1238
1258
  import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
1239
1259
  function InAppBrowserVariant({
1240
1260
  state,
@@ -1244,7 +1264,7 @@ function InAppBrowserVariant({
1244
1264
  const appCopy = INSTALL_COPY.inApp[app] ?? INSTALL_COPY.inApp.other;
1245
1265
  const copy = INSTALL_COPY.inApp;
1246
1266
  const showPermanent = shouldShowPermanentOption(state);
1247
- const [copied, setCopied] = useState4(false);
1267
+ const [copied, setCopied] = useState5(false);
1248
1268
  const handleCopy = async () => {
1249
1269
  await actions.copyLink();
1250
1270
  setCopied(true);
@@ -1513,7 +1533,7 @@ var ErrorBoundary = class extends Component {
1513
1533
  };
1514
1534
 
1515
1535
  // src/hooks/useLoginForm.ts
1516
- import { useCallback as useCallback3, useMemo as useMemo2, useState as useState5 } from "react";
1536
+ import { useCallback as useCallback3, useMemo as useMemo2, useState as useState6 } from "react";
1517
1537
  import { useHook as useHook4 } from "@hook-sdk/sdk";
1518
1538
 
1519
1539
  // src/errors.ts
@@ -1550,10 +1570,10 @@ var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1550
1570
  var MIN_PASSWORD = 8;
1551
1571
  function useLoginForm() {
1552
1572
  const { auth } = useHook4();
1553
- const [email, setEmail] = useState5("");
1554
- const [password, setPassword] = useState5("");
1555
- const [submitting, setSubmitting] = useState5(false);
1556
- const [error, setError] = useState5(null);
1573
+ const [email, setEmail] = useState6("");
1574
+ const [password, setPassword] = useState6("");
1575
+ const [submitting, setSubmitting] = useState6(false);
1576
+ const [error, setError] = useState6(null);
1557
1577
  const emailError = useMemo2(() => {
1558
1578
  if (email.length === 0) return null;
1559
1579
  if (!EMAIL_RE.test(email)) return "Formato de e-mail inv\xE1lido.";
@@ -1664,7 +1684,7 @@ function GoogleGlyph() {
1664
1684
  }
1665
1685
 
1666
1686
  // src/internal/OAuthErrorBanner.tsx
1667
- import { useEffect as useEffect6, useState as useState6 } from "react";
1687
+ import { useEffect as useEffect6, useState as useState7 } from "react";
1668
1688
  import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
1669
1689
  var ERROR_MESSAGES = {
1670
1690
  invalid_state: "Sess\xE3o expirou, tente de novo.",
@@ -1685,7 +1705,7 @@ function stripErrorFromUrl() {
1685
1705
  window.history.replaceState({}, "", url.toString());
1686
1706
  }
1687
1707
  function OAuthErrorBanner() {
1688
- const [code, setCode] = useState6(() => readErrorCode());
1708
+ const [code, setCode] = useState7(() => readErrorCode());
1689
1709
  useEffect6(() => {
1690
1710
  if (code !== null) stripErrorFromUrl();
1691
1711
  }, [code]);
@@ -1819,17 +1839,17 @@ function DefaultLoginScreen({ onNavigate }) {
1819
1839
  }
1820
1840
 
1821
1841
  // src/hooks/useSignupForm.ts
1822
- import { useCallback as useCallback4, useMemo as useMemo3, useState as useState7 } from "react";
1842
+ import { useCallback as useCallback4, useMemo as useMemo3, useState as useState8 } from "react";
1823
1843
  import { useHook as useHook5 } from "@hook-sdk/sdk";
1824
1844
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1825
1845
  var MIN_PASSWORD2 = 8;
1826
1846
  function useSignupForm() {
1827
1847
  const { auth } = useHook5();
1828
- const [name, setName] = useState7("");
1829
- const [email, setEmail] = useState7("");
1830
- const [password, setPassword] = useState7("");
1831
- const [submitting, setSubmitting] = useState7(false);
1832
- const [error, setError] = useState7(null);
1848
+ const [name, setName] = useState8("");
1849
+ const [email, setEmail] = useState8("");
1850
+ const [password, setPassword] = useState8("");
1851
+ const [submitting, setSubmitting] = useState8(false);
1852
+ const [error, setError] = useState8(null);
1833
1853
  const nameError = useMemo3(() => {
1834
1854
  if (name.length === 0) return null;
1835
1855
  if (name.trim().length < 2) return "Nome muito curto.";
@@ -1934,15 +1954,15 @@ function DefaultSignupScreen({ onNavigate }) {
1934
1954
  }
1935
1955
 
1936
1956
  // src/hooks/useForgotForm.ts
1937
- import { useCallback as useCallback5, useMemo as useMemo4, useState as useState8 } from "react";
1957
+ import { useCallback as useCallback5, useMemo as useMemo4, useState as useState9 } from "react";
1938
1958
  import { useHook as useHook6 } from "@hook-sdk/sdk";
1939
1959
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1940
1960
  function useForgotForm() {
1941
1961
  const { auth } = useHook6();
1942
- const [email, setEmail] = useState8("");
1943
- const [submitting, setSubmitting] = useState8(false);
1944
- const [sent, setSent] = useState8(false);
1945
- const [error, setError] = useState8(null);
1962
+ const [email, setEmail] = useState9("");
1963
+ const [submitting, setSubmitting] = useState9(false);
1964
+ const [sent, setSent] = useState9(false);
1965
+ const [error, setError] = useState9(null);
1946
1966
  const emailError = useMemo4(() => {
1947
1967
  if (email.length === 0) return null;
1948
1968
  if (!EMAIL_RE3.test(email)) return "Formato de e-mail inv\xE1lido.";
@@ -2008,17 +2028,17 @@ function DefaultForgotScreen({ onNavigate }) {
2008
2028
  }
2009
2029
 
2010
2030
  // src/hooks/useResetForm.ts
2011
- import { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo5, useState as useState9 } from "react";
2031
+ import { useCallback as useCallback6, useEffect as useEffect7, useMemo as useMemo5, useState as useState10 } from "react";
2012
2032
  import { useHook as useHook7 } from "@hook-sdk/sdk";
2013
2033
  var MIN_PASSWORD3 = 12;
2014
2034
  function useResetForm() {
2015
2035
  const { auth } = useHook7();
2016
- const [token, setToken] = useState9(null);
2017
- const [password, setPassword] = useState9("");
2018
- const [confirm, setConfirm] = useState9("");
2019
- const [submitting, setSubmitting] = useState9(false);
2020
- const [done, setDone] = useState9(false);
2021
- const [error, setError] = useState9(null);
2036
+ const [token, setToken] = useState10(null);
2037
+ const [password, setPassword] = useState10("");
2038
+ const [confirm, setConfirm] = useState10("");
2039
+ const [submitting, setSubmitting] = useState10(false);
2040
+ const [done, setDone] = useState10(false);
2041
+ const [error, setError] = useState10(null);
2022
2042
  useEffect7(() => {
2023
2043
  if (typeof window === "undefined") return;
2024
2044
  const params = new URLSearchParams(window.location.search);
@@ -2114,13 +2134,13 @@ function DefaultResetScreen({ onNavigate }) {
2114
2134
  }
2115
2135
 
2116
2136
  // src/defaults/DefaultPaywall.tsx
2117
- import { useState as useState10 } from "react";
2137
+ import { useState as useState11 } from "react";
2118
2138
  import { jsx as jsx24, jsxs as jsxs18 } from "react/jsx-runtime";
2119
2139
  function DefaultPaywall() {
2120
2140
  const config = useTemplateConfig();
2121
2141
  const { checkout, opening, error } = usePaywallState();
2122
2142
  const p = config.subscription.paywall_config;
2123
- const [cpf, setCpf] = useState10("");
2143
+ const [cpf, setCpf] = useState11("");
2124
2144
  const cpfDigits = cpf.replace(/\D/g, "");
2125
2145
  const canCheckout = cpfDigits.length === 11 && !opening;
2126
2146
  return /* @__PURE__ */ jsxs18("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
@@ -2180,7 +2200,7 @@ function PaymentReturnHandler({ children }) {
2180
2200
  const subRef = useRef3(subscription);
2181
2201
  subRef.current = subscription;
2182
2202
  const runIdRef = useRef3(0);
2183
- const [state, setState] = useState11("idle");
2203
+ const [state, setState] = useState12("idle");
2184
2204
  const runPoll = useCallback7(() => {
2185
2205
  const runId = ++runIdRef.current;
2186
2206
  setState("confirming");
@@ -2284,7 +2304,7 @@ function AppRoot({
2284
2304
  }
2285
2305
 
2286
2306
  // src/hooks/usePush.ts
2287
- import { useCallback as useCallback8, useEffect as useEffect9, useState as useState12 } from "react";
2307
+ import { useCallback as useCallback8, useEffect as useEffect9, useState as useState13 } from "react";
2288
2308
  import { useHook as useHook9 } from "@hook-sdk/sdk";
2289
2309
  function detectIosNeedsInstall() {
2290
2310
  if (typeof navigator === "undefined" || typeof window === "undefined") return false;
@@ -2312,7 +2332,7 @@ function deriveState(push) {
2312
2332
  }
2313
2333
  function usePush() {
2314
2334
  const { push } = useHook9();
2315
- const [state, setState] = useState12(() => deriveState(push));
2335
+ const [state, setState] = useState13(() => deriveState(push));
2316
2336
  useEffect9(() => {
2317
2337
  setState(deriveState(push));
2318
2338
  }, [push]);
@@ -2465,13 +2485,13 @@ function useSubscription() {
2465
2485
  }
2466
2486
 
2467
2487
  // src/hooks/useReminders.ts
2468
- import { useCallback as useCallback9, useEffect as useEffect11, useState as useState13 } from "react";
2488
+ import { useCallback as useCallback9, useEffect as useEffect11, useState as useState14 } from "react";
2469
2489
  import { useHook as useHook13 } from "@hook-sdk/sdk";
2470
2490
  function useReminders() {
2471
2491
  const { push } = useHook13();
2472
2492
  const r = push.reminders;
2473
- const [reminders, setReminders] = useState13([]);
2474
- const [loading, setLoading] = useState13(true);
2493
+ const [reminders, setReminders] = useState14([]);
2494
+ const [loading, setLoading] = useState14(true);
2475
2495
  const reload = useCallback9(async () => {
2476
2496
  setLoading(true);
2477
2497
  try {
@@ -2502,9 +2522,9 @@ function useReminders() {
2502
2522
  }
2503
2523
 
2504
2524
  // src/hooks/useToast.ts
2505
- import { useCallback as useCallback10, useState as useState14 } from "react";
2525
+ import { useCallback as useCallback10, useState as useState15 } from "react";
2506
2526
  function useToast() {
2507
- const [items, setItems] = useState14([]);
2527
+ const [items, setItems] = useState15([]);
2508
2528
  const show = useCallback10((message, kind = "info") => {
2509
2529
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2510
2530
  setItems((prev) => [...prev, { id, message, kind }]);