@hook-sdk/template 0.1.2 → 0.1.3

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,6 +1,6 @@
1
1
  // src/AppRoot.tsx
2
- import { useEffect as useEffect3, useState as useState8 } from "react";
3
- import { useHook as useHook7 } from "@hook-sdk/sdk";
2
+ import { useCallback as useCallback6, useEffect as useEffect4, useRef, useState as useState8 } from "react";
3
+ import { useHook as useHook8 } from "@hook-sdk/sdk";
4
4
 
5
5
  // src/internal/TemplateConfigContext.tsx
6
6
  import { createContext, useContext, useMemo } from "react";
@@ -144,6 +144,21 @@ function SubscriptionGate({ Paywall, children }) {
144
144
  return /* @__PURE__ */ jsx5(Fragment2, { children });
145
145
  }
146
146
 
147
+ // src/internal/PersistedKeysPrefetch.tsx
148
+ import { useEffect as useEffect2 } from "react";
149
+ import { useHook as useHook3 } from "@hook-sdk/sdk";
150
+ import { Fragment as Fragment3, jsx as jsx6 } from "react/jsx-runtime";
151
+ function PersistedKeysPrefetch({ children }) {
152
+ const { appData } = useHook3();
153
+ const config = useTemplateConfig();
154
+ useEffect2(() => {
155
+ const keys = config.persistedKeys;
156
+ if (!keys || keys.length === 0) return;
157
+ appData.cache.startPrefetch(keys, (ks) => appData.bulkRead(ks));
158
+ }, [appData, config.persistedKeys]);
159
+ return /* @__PURE__ */ jsx6(Fragment3, { children });
160
+ }
161
+
147
162
  // src/internal/PushPrompt.tsx
148
163
  function PushPrompt() {
149
164
  return null;
@@ -151,7 +166,7 @@ function PushPrompt() {
151
166
 
152
167
  // src/defaults/ErrorBoundary.tsx
153
168
  import { Component } from "react";
154
- import { Fragment as Fragment3, jsx as jsx6, jsxs } from "react/jsx-runtime";
169
+ import { Fragment as Fragment4, jsx as jsx7, jsxs } from "react/jsx-runtime";
155
170
  var ErrorBoundary = class extends Component {
156
171
  state = { error: null };
157
172
  static getDerivedStateFromError(error) {
@@ -163,17 +178,17 @@ var ErrorBoundary = class extends Component {
163
178
  render() {
164
179
  if (this.state.error) {
165
180
  return this.props.fallback ?? /* @__PURE__ */ jsxs("div", { role: "alert", style: { padding: 24, textAlign: "center" }, children: [
166
- /* @__PURE__ */ jsx6("h2", { children: "Algo deu errado" }),
167
- /* @__PURE__ */ jsx6("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
181
+ /* @__PURE__ */ jsx7("h2", { children: "Algo deu errado" }),
182
+ /* @__PURE__ */ jsx7("p", { style: { opacity: 0.7 }, children: "Recarregue a p\xE1gina pra tentar de novo." })
168
183
  ] });
169
184
  }
170
- return /* @__PURE__ */ jsx6(Fragment3, { children: this.props.children });
185
+ return /* @__PURE__ */ jsx7(Fragment4, { children: this.props.children });
171
186
  }
172
187
  };
173
188
 
174
189
  // src/hooks/useLoginForm.ts
175
190
  import { useCallback as useCallback2, useMemo as useMemo2, useState as useState3 } from "react";
176
- import { useHook as useHook3 } from "@hook-sdk/sdk";
191
+ import { useHook as useHook4 } from "@hook-sdk/sdk";
177
192
 
178
193
  // src/errors.ts
179
194
  import { SdkError, SdkAuthError, SdkRateLimitError } from "@hook-sdk/sdk";
@@ -208,7 +223,7 @@ function mapSdkError(err) {
208
223
  var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
209
224
  var MIN_PASSWORD = 8;
210
225
  function useLoginForm() {
211
- const { auth } = useHook3();
226
+ const { auth } = useHook4();
212
227
  const [email, setEmail] = useState3("");
213
228
  const [password, setPassword] = useState3("");
214
229
  const [submitting, setSubmitting] = useState3(false);
@@ -253,20 +268,20 @@ function useLoginForm() {
253
268
  }
254
269
 
255
270
  // src/defaults/DefaultLoginScreen.tsx
256
- import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
271
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
257
272
  function DefaultLoginScreen({ onNavigate }) {
258
273
  const { name } = useTemplateConfig();
259
274
  const f = useLoginForm();
260
275
  return /* @__PURE__ */ jsxs2("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
261
- /* @__PURE__ */ jsx7("h1", { style: { marginBottom: 8 }, children: name }),
262
- /* @__PURE__ */ jsx7("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Entre na sua conta" }),
276
+ /* @__PURE__ */ jsx8("h1", { style: { marginBottom: 8 }, children: name }),
277
+ /* @__PURE__ */ jsx8("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Entre na sua conta" }),
263
278
  /* @__PURE__ */ jsxs2("form", { onSubmit: (e) => {
264
279
  e.preventDefault();
265
280
  void f.submit();
266
281
  }, children: [
267
282
  /* @__PURE__ */ jsxs2("label", { style: { display: "block", marginBottom: 12 }, children: [
268
283
  "E-mail",
269
- /* @__PURE__ */ jsx7(
284
+ /* @__PURE__ */ jsx8(
270
285
  "input",
271
286
  {
272
287
  "data-testid": "login-email",
@@ -276,11 +291,11 @@ function DefaultLoginScreen({ onNavigate }) {
276
291
  style: { display: "block", width: "100%" }
277
292
  }
278
293
  ),
279
- f.emailError && /* @__PURE__ */ jsx7("small", { style: { color: "#c00" }, children: f.emailError })
294
+ f.emailError && /* @__PURE__ */ jsx8("small", { style: { color: "#c00" }, children: f.emailError })
280
295
  ] }),
281
296
  /* @__PURE__ */ jsxs2("label", { style: { display: "block", marginBottom: 12 }, children: [
282
297
  "Senha",
283
- /* @__PURE__ */ jsx7(
298
+ /* @__PURE__ */ jsx8(
284
299
  "input",
285
300
  {
286
301
  "data-testid": "login-password",
@@ -290,10 +305,10 @@ function DefaultLoginScreen({ onNavigate }) {
290
305
  style: { display: "block", width: "100%" }
291
306
  }
292
307
  ),
293
- f.passwordError && /* @__PURE__ */ jsx7("small", { style: { color: "#c00" }, children: f.passwordError })
308
+ f.passwordError && /* @__PURE__ */ jsx8("small", { style: { color: "#c00" }, children: f.passwordError })
294
309
  ] }),
295
- f.error && /* @__PURE__ */ jsx7("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
296
- /* @__PURE__ */ jsx7(
310
+ f.error && /* @__PURE__ */ jsx8("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
311
+ /* @__PURE__ */ jsx8(
297
312
  "button",
298
313
  {
299
314
  "data-testid": "login-submit",
@@ -313,19 +328,19 @@ function DefaultLoginScreen({ onNavigate }) {
313
328
  )
314
329
  ] }),
315
330
  /* @__PURE__ */ jsxs2("div", { style: { marginTop: 16, display: "flex", justifyContent: "space-between" }, children: [
316
- /* @__PURE__ */ jsx7("button", { "data-testid": "login-goto-signup", type: "button", onClick: () => onNavigate("signup"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Criar conta" }),
317
- /* @__PURE__ */ jsx7("button", { "data-testid": "login-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Esqueci senha" })
331
+ /* @__PURE__ */ jsx8("button", { "data-testid": "login-goto-signup", type: "button", onClick: () => onNavigate("signup"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Criar conta" }),
332
+ /* @__PURE__ */ jsx8("button", { "data-testid": "login-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Esqueci senha" })
318
333
  ] })
319
334
  ] });
320
335
  }
321
336
 
322
337
  // src/hooks/useSignupForm.ts
323
338
  import { useCallback as useCallback3, useMemo as useMemo3, useState as useState4 } from "react";
324
- import { useHook as useHook4 } from "@hook-sdk/sdk";
339
+ import { useHook as useHook5 } from "@hook-sdk/sdk";
325
340
  var EMAIL_RE2 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
326
341
  var MIN_PASSWORD2 = 8;
327
342
  function useSignupForm() {
328
- const { auth } = useHook4();
343
+ const { auth } = useHook5();
329
344
  const [name, setName] = useState4("");
330
345
  const [email, setEmail] = useState4("");
331
346
  const [password, setPassword] = useState4("");
@@ -379,45 +394,45 @@ function useSignupForm() {
379
394
  }
380
395
 
381
396
  // src/defaults/DefaultSignupScreen.tsx
382
- import { jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
397
+ import { jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
383
398
  function DefaultSignupScreen({ onNavigate }) {
384
399
  const { name } = useTemplateConfig();
385
400
  const f = useSignupForm();
386
401
  return /* @__PURE__ */ jsxs3("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
387
- /* @__PURE__ */ jsx8("h1", { style: { marginBottom: 8 }, children: name }),
388
- /* @__PURE__ */ jsx8("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Criar sua conta" }),
402
+ /* @__PURE__ */ jsx9("h1", { style: { marginBottom: 8 }, children: name }),
403
+ /* @__PURE__ */ jsx9("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Criar sua conta" }),
389
404
  /* @__PURE__ */ jsxs3("form", { onSubmit: (e) => {
390
405
  e.preventDefault();
391
406
  void f.submit();
392
407
  }, children: [
393
408
  /* @__PURE__ */ jsxs3("label", { style: { display: "block", marginBottom: 12 }, children: [
394
409
  "Nome",
395
- /* @__PURE__ */ jsx8("input", { "data-testid": "signup-name", value: f.name, onChange: (e) => f.setName(e.target.value), style: { display: "block", width: "100%" } }),
396
- f.nameError && /* @__PURE__ */ jsx8("small", { style: { color: "#c00" }, children: f.nameError })
410
+ /* @__PURE__ */ jsx9("input", { "data-testid": "signup-name", value: f.name, onChange: (e) => f.setName(e.target.value), style: { display: "block", width: "100%" } }),
411
+ f.nameError && /* @__PURE__ */ jsx9("small", { style: { color: "#c00" }, children: f.nameError })
397
412
  ] }),
398
413
  /* @__PURE__ */ jsxs3("label", { style: { display: "block", marginBottom: 12 }, children: [
399
414
  "E-mail",
400
- /* @__PURE__ */ jsx8("input", { "data-testid": "signup-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
401
- f.emailError && /* @__PURE__ */ jsx8("small", { style: { color: "#c00" }, children: f.emailError })
415
+ /* @__PURE__ */ jsx9("input", { "data-testid": "signup-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
416
+ f.emailError && /* @__PURE__ */ jsx9("small", { style: { color: "#c00" }, children: f.emailError })
402
417
  ] }),
403
418
  /* @__PURE__ */ jsxs3("label", { style: { display: "block", marginBottom: 12 }, children: [
404
419
  "Senha",
405
- /* @__PURE__ */ jsx8("input", { "data-testid": "signup-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" } }),
406
- f.passwordError && /* @__PURE__ */ jsx8("small", { style: { color: "#c00" }, children: f.passwordError })
420
+ /* @__PURE__ */ jsx9("input", { "data-testid": "signup-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" } }),
421
+ f.passwordError && /* @__PURE__ */ jsx9("small", { style: { color: "#c00" }, children: f.passwordError })
407
422
  ] }),
408
- f.error && /* @__PURE__ */ jsx8("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
409
- /* @__PURE__ */ jsx8("button", { "data-testid": "signup-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Criando..." : "Criar conta" })
423
+ f.error && /* @__PURE__ */ jsx9("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
424
+ /* @__PURE__ */ jsx9("button", { "data-testid": "signup-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Criando..." : "Criar conta" })
410
425
  ] }),
411
- /* @__PURE__ */ jsx8("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx8("button", { "data-testid": "signup-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "J\xE1 tem conta? Entre" }) })
426
+ /* @__PURE__ */ jsx9("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx9("button", { "data-testid": "signup-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "J\xE1 tem conta? Entre" }) })
412
427
  ] });
413
428
  }
414
429
 
415
430
  // src/hooks/useForgotForm.ts
416
431
  import { useCallback as useCallback4, useMemo as useMemo4, useState as useState5 } from "react";
417
- import { useHook as useHook5 } from "@hook-sdk/sdk";
432
+ import { useHook as useHook6 } from "@hook-sdk/sdk";
418
433
  var EMAIL_RE3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
419
434
  function useForgotForm() {
420
- const { auth } = useHook5();
435
+ const { auth } = useHook6();
421
436
  const [email, setEmail] = useState5("");
422
437
  const [submitting, setSubmitting] = useState5(false);
423
438
  const [sent, setSent] = useState5(false);
@@ -456,49 +471,49 @@ function useForgotForm() {
456
471
  }
457
472
 
458
473
  // src/defaults/DefaultForgotScreen.tsx
459
- import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
474
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
460
475
  function DefaultForgotScreen({ onNavigate }) {
461
476
  const { name } = useTemplateConfig();
462
477
  const f = useForgotForm();
463
478
  if (f.sent) {
464
479
  return /* @__PURE__ */ jsxs4("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
465
- /* @__PURE__ */ jsx9("h1", { children: "Verifique seu e-mail" }),
466
- /* @__PURE__ */ jsx9("p", { style: { opacity: 0.7 }, children: "Enviamos um link pra redefinir sua senha." }),
467
- /* @__PURE__ */ jsx9("button", { "data-testid": "forgot-back-login", type: "button", onClick: () => onNavigate("login"), children: "Voltar pro login" })
480
+ /* @__PURE__ */ jsx10("h1", { children: "Verifique seu e-mail" }),
481
+ /* @__PURE__ */ jsx10("p", { style: { opacity: 0.7 }, children: "Enviamos um link pra redefinir sua senha." }),
482
+ /* @__PURE__ */ jsx10("button", { "data-testid": "forgot-back-login", type: "button", onClick: () => onNavigate("login"), children: "Voltar pro login" })
468
483
  ] });
469
484
  }
470
485
  return /* @__PURE__ */ jsxs4("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
471
- /* @__PURE__ */ jsx9("h1", { style: { marginBottom: 8 }, children: name }),
472
- /* @__PURE__ */ jsx9("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Redefinir senha" }),
486
+ /* @__PURE__ */ jsx10("h1", { style: { marginBottom: 8 }, children: name }),
487
+ /* @__PURE__ */ jsx10("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Redefinir senha" }),
473
488
  /* @__PURE__ */ jsxs4("form", { onSubmit: (e) => {
474
489
  e.preventDefault();
475
490
  void f.submit();
476
491
  }, children: [
477
492
  /* @__PURE__ */ jsxs4("label", { style: { display: "block", marginBottom: 12 }, children: [
478
493
  "E-mail",
479
- /* @__PURE__ */ jsx9("input", { "data-testid": "forgot-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
480
- f.emailError && /* @__PURE__ */ jsx9("small", { style: { color: "#c00" }, children: f.emailError })
494
+ /* @__PURE__ */ jsx10("input", { "data-testid": "forgot-email", type: "email", value: f.email, onChange: (e) => f.setEmail(e.target.value), style: { display: "block", width: "100%" } }),
495
+ f.emailError && /* @__PURE__ */ jsx10("small", { style: { color: "#c00" }, children: f.emailError })
481
496
  ] }),
482
- f.error && /* @__PURE__ */ jsx9("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
483
- /* @__PURE__ */ jsx9("button", { "data-testid": "forgot-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Enviando..." : "Enviar link" })
497
+ f.error && /* @__PURE__ */ jsx10("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
498
+ /* @__PURE__ */ jsx10("button", { "data-testid": "forgot-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Enviando..." : "Enviar link" })
484
499
  ] }),
485
- /* @__PURE__ */ jsx9("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx9("button", { "data-testid": "forgot-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Voltar pro login" }) })
500
+ /* @__PURE__ */ jsx10("div", { style: { marginTop: 16 }, children: /* @__PURE__ */ jsx10("button", { "data-testid": "forgot-goto-login", type: "button", onClick: () => onNavigate("login"), style: { background: "none", border: "none", cursor: "pointer" }, children: "Voltar pro login" }) })
486
501
  ] });
487
502
  }
488
503
 
489
504
  // src/hooks/useResetForm.ts
490
- import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo5, useState as useState6 } from "react";
491
- import { useHook as useHook6 } from "@hook-sdk/sdk";
505
+ import { useCallback as useCallback5, useEffect as useEffect3, useMemo as useMemo5, useState as useState6 } from "react";
506
+ import { useHook as useHook7 } from "@hook-sdk/sdk";
492
507
  var MIN_PASSWORD3 = 12;
493
508
  function useResetForm() {
494
- const { auth } = useHook6();
509
+ const { auth } = useHook7();
495
510
  const [token, setToken] = useState6(null);
496
511
  const [password, setPassword] = useState6("");
497
512
  const [confirm, setConfirm] = useState6("");
498
513
  const [submitting, setSubmitting] = useState6(false);
499
514
  const [done, setDone] = useState6(false);
500
515
  const [error, setError] = useState6(null);
501
- useEffect2(() => {
516
+ useEffect3(() => {
502
517
  if (typeof window === "undefined") return;
503
518
  const params = new URLSearchParams(window.location.search);
504
519
  const t = params.get("token");
@@ -551,50 +566,50 @@ function useResetForm() {
551
566
  }
552
567
 
553
568
  // src/defaults/DefaultResetScreen.tsx
554
- import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
569
+ import { jsx as jsx11, jsxs as jsxs5 } from "react/jsx-runtime";
555
570
  function DefaultResetScreen({ onNavigate }) {
556
571
  const { name } = useTemplateConfig();
557
572
  const f = useResetForm();
558
573
  if (f.done) {
559
574
  return /* @__PURE__ */ jsxs5("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
560
- /* @__PURE__ */ jsx10("h1", { children: "Senha alterada" }),
561
- /* @__PURE__ */ jsx10("p", { style: { opacity: 0.7 }, children: "Agora \xE9 s\xF3 fazer login com a nova senha." }),
562
- /* @__PURE__ */ jsx10("button", { "data-testid": "reset-back-login", type: "button", onClick: () => onNavigate("login"), children: "Ir pro login" })
575
+ /* @__PURE__ */ jsx11("h1", { children: "Senha alterada" }),
576
+ /* @__PURE__ */ jsx11("p", { style: { opacity: 0.7 }, children: "Agora \xE9 s\xF3 fazer login com a nova senha." }),
577
+ /* @__PURE__ */ jsx11("button", { "data-testid": "reset-back-login", type: "button", onClick: () => onNavigate("login"), children: "Ir pro login" })
563
578
  ] });
564
579
  }
565
580
  if (f.token === null) {
566
581
  return /* @__PURE__ */ jsxs5("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto", textAlign: "center" }, children: [
567
- /* @__PURE__ */ jsx10("h1", { children: "Link inv\xE1lido" }),
568
- /* @__PURE__ */ jsx10("p", { style: { opacity: 0.7 }, children: "Pe\xE7a um novo link de reset." }),
569
- /* @__PURE__ */ jsx10("button", { "data-testid": "reset-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), children: "Pedir novo link" })
582
+ /* @__PURE__ */ jsx11("h1", { children: "Link inv\xE1lido" }),
583
+ /* @__PURE__ */ jsx11("p", { style: { opacity: 0.7 }, children: "Pe\xE7a um novo link de reset." }),
584
+ /* @__PURE__ */ jsx11("button", { "data-testid": "reset-goto-forgot", type: "button", onClick: () => onNavigate("forgot"), children: "Pedir novo link" })
570
585
  ] });
571
586
  }
572
587
  return /* @__PURE__ */ jsxs5("main", { style: { padding: 24, maxWidth: 360, margin: "0 auto" }, children: [
573
- /* @__PURE__ */ jsx10("h1", { style: { marginBottom: 8 }, children: name }),
574
- /* @__PURE__ */ jsx10("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Escolha uma nova senha" }),
588
+ /* @__PURE__ */ jsx11("h1", { style: { marginBottom: 8 }, children: name }),
589
+ /* @__PURE__ */ jsx11("p", { style: { opacity: 0.7, marginBottom: 24 }, children: "Escolha uma nova senha" }),
575
590
  /* @__PURE__ */ jsxs5("form", { onSubmit: (e) => {
576
591
  e.preventDefault();
577
592
  void f.submit();
578
593
  }, children: [
579
594
  /* @__PURE__ */ jsxs5("label", { style: { display: "block", marginBottom: 12 }, children: [
580
595
  "Nova senha",
581
- /* @__PURE__ */ jsx10("input", { "data-testid": "reset-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
582
- f.passwordError && /* @__PURE__ */ jsx10("small", { style: { color: "#c00" }, children: f.passwordError })
596
+ /* @__PURE__ */ jsx11("input", { "data-testid": "reset-password", type: "password", value: f.password, onChange: (e) => f.setPassword(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
597
+ f.passwordError && /* @__PURE__ */ jsx11("small", { style: { color: "#c00" }, children: f.passwordError })
583
598
  ] }),
584
599
  /* @__PURE__ */ jsxs5("label", { style: { display: "block", marginBottom: 12 }, children: [
585
600
  "Confirmar senha",
586
- /* @__PURE__ */ jsx10("input", { "data-testid": "reset-confirm", type: "password", value: f.confirm, onChange: (e) => f.setConfirm(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
587
- f.confirmError && /* @__PURE__ */ jsx10("small", { style: { color: "#c00" }, children: f.confirmError })
601
+ /* @__PURE__ */ jsx11("input", { "data-testid": "reset-confirm", type: "password", value: f.confirm, onChange: (e) => f.setConfirm(e.target.value), style: { display: "block", width: "100%" }, autoComplete: "new-password" }),
602
+ f.confirmError && /* @__PURE__ */ jsx11("small", { style: { color: "#c00" }, children: f.confirmError })
588
603
  ] }),
589
- f.error && /* @__PURE__ */ jsx10("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
590
- /* @__PURE__ */ jsx10("button", { "data-testid": "reset-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Alterando..." : "Alterar senha" })
604
+ f.error && /* @__PURE__ */ jsx11("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: f.error.message }),
605
+ /* @__PURE__ */ jsx11("button", { "data-testid": "reset-submit", type: "submit", disabled: !f.canSubmit, style: { width: "100%", padding: 12, background: "var(--hook-color-primary)", color: "#fff", border: "none", borderRadius: 8, opacity: f.canSubmit ? 1 : 0.5 }, children: f.submitting ? "Alterando..." : "Alterar senha" })
591
606
  ] })
592
607
  ] });
593
608
  }
594
609
 
595
610
  // src/defaults/DefaultPaywall.tsx
596
611
  import { useState as useState7 } from "react";
597
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
612
+ import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
598
613
  function DefaultPaywall() {
599
614
  const config = useTemplateConfig();
600
615
  const { checkout, opening, error } = usePaywallState();
@@ -603,15 +618,15 @@ function DefaultPaywall() {
603
618
  const cpfDigits = cpf.replace(/\D/g, "");
604
619
  const canCheckout = cpfDigits.length === 11 && !opening;
605
620
  return /* @__PURE__ */ jsxs6("main", { style: { padding: 24, maxWidth: 440, margin: "0 auto", textAlign: "center" }, children: [
606
- /* @__PURE__ */ jsx11("h1", { style: { marginBottom: 8 }, children: p.title }),
607
- p.subtitle && /* @__PURE__ */ jsx11("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
608
- /* @__PURE__ */ jsx11("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", marginBottom: 24 }, children: p.benefits.map((b) => /* @__PURE__ */ jsxs6("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
609
- /* @__PURE__ */ jsx11("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
610
- /* @__PURE__ */ jsx11("span", { children: b })
621
+ /* @__PURE__ */ jsx12("h1", { style: { marginBottom: 8 }, children: p.title }),
622
+ p.subtitle && /* @__PURE__ */ jsx12("p", { style: { opacity: 0.7, marginBottom: 24 }, children: p.subtitle }),
623
+ /* @__PURE__ */ jsx12("ul", { style: { listStyle: "none", padding: 0, textAlign: "left", marginBottom: 24 }, children: p.benefits.map((b) => /* @__PURE__ */ jsxs6("li", { style: { padding: "8px 0", display: "flex", alignItems: "center" }, children: [
624
+ /* @__PURE__ */ jsx12("span", { "aria-hidden": true, style: { marginRight: 8 }, children: "\u2713" }),
625
+ /* @__PURE__ */ jsx12("span", { children: b })
611
626
  ] }, b)) }),
612
627
  /* @__PURE__ */ jsxs6("div", { style: { textAlign: "left", marginBottom: 16 }, children: [
613
- /* @__PURE__ */ jsx11("label", { style: { display: "block", fontSize: 14, opacity: 0.7, marginBottom: 4 }, children: "Seu CPF (pra emiss\xE3o de recibo)" }),
614
- /* @__PURE__ */ jsx11(
628
+ /* @__PURE__ */ jsx12("label", { style: { display: "block", fontSize: 14, opacity: 0.7, marginBottom: 4 }, children: "Seu CPF (pra emiss\xE3o de recibo)" }),
629
+ /* @__PURE__ */ jsx12(
615
630
  "input",
616
631
  {
617
632
  "data-testid": "paywall-cpf",
@@ -624,8 +639,8 @@ function DefaultPaywall() {
624
639
  }
625
640
  )
626
641
  ] }),
627
- error && /* @__PURE__ */ jsx11("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: error.message }),
628
- /* @__PURE__ */ jsx11(
642
+ error && /* @__PURE__ */ jsx12("div", { role: "alert", style: { color: "#c00", marginBottom: 12 }, children: error.message }),
643
+ /* @__PURE__ */ jsx12(
629
644
  "button",
630
645
  {
631
646
  "data-testid": "paywall-cta",
@@ -646,72 +661,107 @@ function DefaultPaywall() {
646
661
  children: opening ? "Abrindo..." : p.cta
647
662
  }
648
663
  ),
649
- p.priceHint && /* @__PURE__ */ jsx11("p", { style: { opacity: 0.6, marginTop: 12 }, children: p.priceHint }),
650
- p.footerNote && /* @__PURE__ */ jsx11("p", { style: { opacity: 0.5, marginTop: 16, fontSize: 12 }, children: p.footerNote })
664
+ p.priceHint && /* @__PURE__ */ jsx12("p", { style: { opacity: 0.6, marginTop: 12 }, children: p.priceHint }),
665
+ p.footerNote && /* @__PURE__ */ jsx12("p", { style: { opacity: 0.5, marginTop: 16, fontSize: 12 }, children: p.footerNote })
651
666
  ] });
652
667
  }
653
668
 
654
669
  // src/AppRoot.tsx
655
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
670
+ import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
671
+ var BACKOFF_MS = [2e3, 5e3, 1e4, 2e4, 4e4];
656
672
  function PaymentReturnHandler({ children }) {
657
- const { subscription } = useHook7();
658
- const [confirming, setConfirming] = useState8(false);
659
- useEffect3(() => {
660
- if (typeof window === "undefined") return;
661
- const url = new URL(window.location.href);
662
- if (url.searchParams.get("paymentReturn") !== "1") return;
663
- let cancelled = false;
673
+ const { subscription } = useHook8();
674
+ const subRef = useRef(subscription);
675
+ subRef.current = subscription;
676
+ const runIdRef = useRef(0);
677
+ const [state, setState] = useState8("idle");
678
+ const runPoll = useCallback6(() => {
679
+ const runId = ++runIdRef.current;
680
+ setState("confirming");
664
681
  let attempts = 0;
665
- setConfirming(true);
666
682
  const tick = async () => {
667
- if (cancelled) return;
668
- if (attempts >= 10) {
669
- setConfirming(false);
670
- return;
671
- }
683
+ if (runIdRef.current !== runId) return;
672
684
  attempts++;
673
685
  try {
674
- await subscription.refresh();
686
+ await subRef.current.refresh();
675
687
  } catch {
676
688
  }
677
- if (cancelled) return;
678
- if (subscription.status() === "active") {
689
+ if (runIdRef.current !== runId) return;
690
+ const status = subRef.current.status();
691
+ if (status === "active" || status === "trialing") {
679
692
  const cleanUrl = new URL(window.location.href);
680
693
  cleanUrl.searchParams.delete("paymentReturn");
681
694
  window.history.replaceState({}, "", cleanUrl.toString());
682
- setConfirming(false);
695
+ setState("idle");
696
+ return;
697
+ }
698
+ const delay = BACKOFF_MS[attempts - 1];
699
+ if (delay === void 0) {
700
+ setState("waiting");
683
701
  return;
684
702
  }
685
- setTimeout(tick, 1e3);
703
+ setTimeout(tick, delay);
686
704
  };
687
705
  void tick();
706
+ }, []);
707
+ useEffect4(() => {
708
+ if (typeof window === "undefined") return;
709
+ const url = new URL(window.location.href);
710
+ if (url.searchParams.get("paymentReturn") !== "1") return;
711
+ runPoll();
688
712
  return () => {
689
- cancelled = true;
713
+ runIdRef.current++;
690
714
  };
691
- }, [subscription]);
692
- if (confirming) {
693
- return /* @__PURE__ */ jsx12(
715
+ }, [runPoll]);
716
+ if (state === "confirming") {
717
+ return /* @__PURE__ */ jsx13(
694
718
  "div",
695
719
  {
696
720
  role: "status",
697
721
  "aria-live": "polite",
698
- style: {
699
- position: "fixed",
700
- inset: 0,
701
- display: "flex",
702
- alignItems: "center",
703
- justifyContent: "center",
704
- background: "rgba(0,0,0,0.4)",
705
- zIndex: 9999,
706
- color: "white",
707
- fontSize: "1rem"
708
- },
722
+ style: overlayStyle,
709
723
  children: "Confirmando pagamento\u2026"
710
724
  }
711
725
  );
712
726
  }
713
- return /* @__PURE__ */ jsx12(Fragment4, { children });
727
+ if (state === "waiting") {
728
+ return /* @__PURE__ */ jsx13("div", { role: "status", "aria-live": "polite", style: overlayStyle, children: /* @__PURE__ */ jsxs7("div", { style: { maxWidth: 320, textAlign: "center", lineHeight: 1.5 }, children: [
729
+ /* @__PURE__ */ jsx13("div", { style: { marginBottom: 16 }, children: "Pagamento aceito. Estamos confirmando com o banco \u2014 pode levar alguns minutos." }),
730
+ /* @__PURE__ */ jsx13(
731
+ "button",
732
+ {
733
+ type: "button",
734
+ onClick: runPoll,
735
+ style: buttonStyle,
736
+ children: "Atualizar"
737
+ }
738
+ )
739
+ ] }) });
740
+ }
741
+ return /* @__PURE__ */ jsx13(Fragment5, { children });
714
742
  }
743
+ var overlayStyle = {
744
+ position: "fixed",
745
+ inset: 0,
746
+ display: "flex",
747
+ alignItems: "center",
748
+ justifyContent: "center",
749
+ background: "rgba(0,0,0,0.4)",
750
+ zIndex: 9999,
751
+ color: "white",
752
+ fontSize: "1rem",
753
+ padding: 24
754
+ };
755
+ var buttonStyle = {
756
+ background: "white",
757
+ color: "black",
758
+ border: "none",
759
+ borderRadius: 8,
760
+ padding: "10px 24px",
761
+ fontSize: "1rem",
762
+ fontWeight: 600,
763
+ cursor: "pointer"
764
+ };
715
765
  function AppRoot({
716
766
  config,
717
767
  children,
@@ -721,29 +771,29 @@ function AppRoot({
721
771
  Reset = DefaultResetScreen,
722
772
  Paywall = DefaultPaywall
723
773
  }) {
724
- return /* @__PURE__ */ jsx12(PaymentReturnHandler, { children: /* @__PURE__ */ jsx12(TemplateConfigProvider, { config, children: /* @__PURE__ */ jsx12(ErrorBoundary, { children: /* @__PURE__ */ jsx12(ThemeProvider, { children: /* @__PURE__ */ jsx12(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ jsxs7(SubscriptionGate, { Paywall, children: [
774
+ return /* @__PURE__ */ jsx13(PaymentReturnHandler, { children: /* @__PURE__ */ jsx13(TemplateConfigProvider, { config, children: /* @__PURE__ */ jsx13(ErrorBoundary, { children: /* @__PURE__ */ jsx13(ThemeProvider, { children: /* @__PURE__ */ jsx13(AuthGate, { Login, Signup, Forgot, Reset, children: /* @__PURE__ */ jsx13(PersistedKeysPrefetch, { children: /* @__PURE__ */ jsxs7(SubscriptionGate, { Paywall, children: [
725
775
  children,
726
- /* @__PURE__ */ jsx12(PushPrompt, {})
727
- ] }) }) }) }) }) });
776
+ /* @__PURE__ */ jsx13(PushPrompt, {})
777
+ ] }) }) }) }) }) }) });
728
778
  }
729
779
 
730
780
  // src/defaults/EmptyState.tsx
731
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
781
+ import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
732
782
  function EmptyState({ title, description, action }) {
733
783
  return /* @__PURE__ */ jsxs8("div", { role: "status", style: { padding: 32, textAlign: "center" }, children: [
734
- /* @__PURE__ */ jsx13("h2", { style: { marginBottom: 8 }, children: title }),
735
- description && /* @__PURE__ */ jsx13("p", { style: { opacity: 0.7 }, children: description }),
736
- action && /* @__PURE__ */ jsx13("div", { style: { marginTop: 16 }, children: action })
784
+ /* @__PURE__ */ jsx14("h2", { style: { marginBottom: 8 }, children: title }),
785
+ description && /* @__PURE__ */ jsx14("p", { style: { opacity: 0.7 }, children: description }),
786
+ action && /* @__PURE__ */ jsx14("div", { style: { marginTop: 16 }, children: action })
737
787
  ] });
738
788
  }
739
789
 
740
790
  // src/hooks/useAuthPrimitives.ts
741
- import { useEffect as useEffect4 } from "react";
742
- import { useHook as useHook8 } from "@hook-sdk/sdk";
791
+ import { useEffect as useEffect5 } from "react";
792
+ import { useHook as useHook9 } from "@hook-sdk/sdk";
743
793
  var warned = false;
744
794
  function useAuthPrimitives() {
745
- const { auth } = useHook8();
746
- useEffect4(() => {
795
+ const { auth } = useHook9();
796
+ useEffect5(() => {
747
797
  if (!warned && process.env.NODE_ENV !== "production") {
748
798
  warned = true;
749
799
  console.warn(
@@ -765,18 +815,18 @@ function useAuthPrimitives() {
765
815
  }
766
816
 
767
817
  // src/hooks/useSubscription.ts
768
- import { useHook as useHook9 } from "@hook-sdk/sdk";
818
+ import { useHook as useHook10 } from "@hook-sdk/sdk";
769
819
  function useSubscription() {
770
- const { subscription } = useHook9();
820
+ const { subscription } = useHook10();
771
821
  return {
772
822
  status: subscription.status()
773
823
  };
774
824
  }
775
825
 
776
826
  // src/hooks/usePush.ts
777
- import { useHook as useHook10 } from "@hook-sdk/sdk";
827
+ import { useHook as useHook11 } from "@hook-sdk/sdk";
778
828
  function usePush() {
779
- const { push } = useHook10();
829
+ const { push } = useHook11();
780
830
  return {
781
831
  status: push.status(),
782
832
  subscribe: push.subscribe,
@@ -785,17 +835,17 @@ function usePush() {
785
835
  }
786
836
 
787
837
  // src/hooks/useToast.ts
788
- import { useCallback as useCallback6, useState as useState9 } from "react";
838
+ import { useCallback as useCallback7, useState as useState9 } from "react";
789
839
  function useToast() {
790
840
  const [items, setItems] = useState9([]);
791
- const show = useCallback6((message, kind = "info") => {
841
+ const show = useCallback7((message, kind = "info") => {
792
842
  const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
793
843
  setItems((prev) => [...prev, { id, message, kind }]);
794
844
  setTimeout(() => {
795
845
  setItems((prev) => prev.filter((t) => t.id !== id));
796
846
  }, 4e3);
797
847
  }, []);
798
- const dismiss = useCallback6((id) => {
848
+ const dismiss = useCallback7((id) => {
799
849
  setItems((prev) => prev.filter((t) => t.id !== id));
800
850
  }, []);
801
851
  return { items, show, dismiss };