@bananapus/nana-sdk-core 2.38.2 → 2.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/cjs/review/heldWrite.d.ts +113 -0
  2. package/dist/cjs/review/heldWrite.d.ts.map +1 -0
  3. package/dist/cjs/review/heldWrite.js +569 -0
  4. package/dist/cjs/review/heldWrite.js.map +1 -0
  5. package/dist/cjs/review/index.d.ts +2 -0
  6. package/dist/cjs/review/index.d.ts.map +1 -1
  7. package/dist/cjs/review/index.js +2 -0
  8. package/dist/cjs/review/index.js.map +1 -1
  9. package/dist/cjs/review/messages.d.ts +30 -0
  10. package/dist/cjs/review/messages.d.ts.map +1 -1
  11. package/dist/cjs/review/messages.js +34 -1
  12. package/dist/cjs/review/messages.js.map +1 -1
  13. package/dist/cjs/review/react/HeldWritesNotice.d.ts +11 -0
  14. package/dist/cjs/review/react/HeldWritesNotice.d.ts.map +1 -0
  15. package/dist/cjs/review/react/HeldWritesNotice.js +22 -0
  16. package/dist/cjs/review/react/HeldWritesNotice.js.map +1 -0
  17. package/dist/cjs/review/react/index.d.ts +5 -0
  18. package/dist/cjs/review/react/index.d.ts.map +1 -0
  19. package/dist/cjs/review/react/index.js +21 -0
  20. package/dist/cjs/review/react/index.js.map +1 -0
  21. package/dist/cjs/review/react/useHeldWrite.d.ts +63 -0
  22. package/dist/cjs/review/react/useHeldWrite.d.ts.map +1 -0
  23. package/dist/cjs/review/react/useHeldWrite.js +107 -0
  24. package/dist/cjs/review/react/useHeldWrite.js.map +1 -0
  25. package/dist/cjs/review/react/useHeldWrites.d.ts +40 -0
  26. package/dist/cjs/review/react/useHeldWrites.d.ts.map +1 -0
  27. package/dist/cjs/review/react/useHeldWrites.js +95 -0
  28. package/dist/cjs/review/react/useHeldWrites.js.map +1 -0
  29. package/dist/cjs/review/react/useSavedAttempt.d.ts +54 -0
  30. package/dist/cjs/review/react/useSavedAttempt.d.ts.map +1 -0
  31. package/dist/cjs/review/react/useSavedAttempt.js +105 -0
  32. package/dist/cjs/review/react/useSavedAttempt.js.map +1 -0
  33. package/dist/cjs/review/savedAttempt.d.ts +180 -0
  34. package/dist/cjs/review/savedAttempt.d.ts.map +1 -0
  35. package/dist/cjs/review/savedAttempt.js +527 -0
  36. package/dist/cjs/review/savedAttempt.js.map +1 -0
  37. package/dist/cjs/review/writeHold.d.ts +94 -2
  38. package/dist/cjs/review/writeHold.d.ts.map +1 -1
  39. package/dist/cjs/review/writeHold.js +284 -43
  40. package/dist/cjs/review/writeHold.js.map +1 -1
  41. package/dist/cjs/review/writeRecovery.d.ts +58 -0
  42. package/dist/cjs/review/writeRecovery.d.ts.map +1 -1
  43. package/dist/cjs/review/writeRecovery.js +161 -2
  44. package/dist/cjs/review/writeRecovery.js.map +1 -1
  45. package/dist/esm/review/heldWrite.d.ts +113 -0
  46. package/dist/esm/review/heldWrite.d.ts.map +1 -0
  47. package/dist/esm/review/heldWrite.js +562 -0
  48. package/dist/esm/review/heldWrite.js.map +1 -0
  49. package/dist/esm/review/index.d.ts +2 -0
  50. package/dist/esm/review/index.d.ts.map +1 -1
  51. package/dist/esm/review/index.js +2 -0
  52. package/dist/esm/review/index.js.map +1 -1
  53. package/dist/esm/review/messages.d.ts +30 -0
  54. package/dist/esm/review/messages.d.ts.map +1 -1
  55. package/dist/esm/review/messages.js +32 -0
  56. package/dist/esm/review/messages.js.map +1 -1
  57. package/dist/esm/review/react/HeldWritesNotice.d.ts +11 -0
  58. package/dist/esm/review/react/HeldWritesNotice.d.ts.map +1 -0
  59. package/dist/esm/review/react/HeldWritesNotice.js +19 -0
  60. package/dist/esm/review/react/HeldWritesNotice.js.map +1 -0
  61. package/dist/esm/review/react/index.d.ts +5 -0
  62. package/dist/esm/review/react/index.d.ts.map +1 -0
  63. package/dist/esm/review/react/index.js +5 -0
  64. package/dist/esm/review/react/index.js.map +1 -0
  65. package/dist/esm/review/react/useHeldWrite.d.ts +63 -0
  66. package/dist/esm/review/react/useHeldWrite.d.ts.map +1 -0
  67. package/dist/esm/review/react/useHeldWrite.js +104 -0
  68. package/dist/esm/review/react/useHeldWrite.js.map +1 -0
  69. package/dist/esm/review/react/useHeldWrites.d.ts +40 -0
  70. package/dist/esm/review/react/useHeldWrites.d.ts.map +1 -0
  71. package/dist/esm/review/react/useHeldWrites.js +91 -0
  72. package/dist/esm/review/react/useHeldWrites.js.map +1 -0
  73. package/dist/esm/review/react/useSavedAttempt.d.ts +54 -0
  74. package/dist/esm/review/react/useSavedAttempt.d.ts.map +1 -0
  75. package/dist/esm/review/react/useSavedAttempt.js +102 -0
  76. package/dist/esm/review/react/useSavedAttempt.js.map +1 -0
  77. package/dist/esm/review/savedAttempt.d.ts +180 -0
  78. package/dist/esm/review/savedAttempt.d.ts.map +1 -0
  79. package/dist/esm/review/savedAttempt.js +524 -0
  80. package/dist/esm/review/savedAttempt.js.map +1 -0
  81. package/dist/esm/review/writeHold.d.ts +94 -2
  82. package/dist/esm/review/writeHold.d.ts.map +1 -1
  83. package/dist/esm/review/writeHold.js +285 -44
  84. package/dist/esm/review/writeHold.js.map +1 -1
  85. package/dist/esm/review/writeRecovery.d.ts +58 -0
  86. package/dist/esm/review/writeRecovery.d.ts.map +1 -1
  87. package/dist/esm/review/writeRecovery.js +160 -2
  88. package/dist/esm/review/writeRecovery.js.map +1 -1
  89. package/package.json +16 -2
@@ -67,4 +67,36 @@ export const WRITE_HOLD_SAFE_UNPROVEN_LINE = "This Safe transaction couldn't be
67
67
  export const WRITE_HOLD_MINED_LINE = "Your transaction is onchain, but its result can't be read yet.";
68
68
  /** A send whose review went stale because another window's attempt of the same write ended meanwhile. */
69
69
  export const WRITE_HOLD_STALE_REVIEW_LINE = "This was just sent from another window. Review it again to send another.";
70
+ /** The one line while a sent write, direct or through a Safe, is being confirmed. */
71
+ export const HELD_CONFIRMING_LINE = "Confirming your transaction.";
72
+ /** A held write the user released with their exit: they can send it again. */
73
+ export const HELD_RELEASED_LINE = "Released. You can send it again.";
74
+ /** A held write another window released: neutral, never a result. */
75
+ export const HELD_RELEASED_ELSEWHERE_LINE = "This was released in another window.";
76
+ /** The exit button where the review follows on its own. */
77
+ export const HELD_EXIT_LABEL = "I checked my wallet";
78
+ /** The exit button where only the hold is released (an app-wide notice). */
79
+ export const HELD_RELEASE_LABEL = "I checked my wallet. Release it";
80
+ /** A held write settled with success on authenticated evidence. */
81
+ export const HELD_SUCCESS_LINE = "Your transaction went through.";
82
+ /** A held Safe proposal proven expired before it ran. */
83
+ export const HELD_EXPIRED_LINE = "Your Safe proposal expired before it ran.";
84
+ /** A success the hold settled while the user was away: shown until they say to send again. */
85
+ export const HELD_AWAY_SUCCESS_LINE = "This went through while you were away.";
86
+ /** The one action on a success settled while away: acknowledge it, then send. */
87
+ export const HELD_SEND_AGAIN_LABEL = "Send it again";
88
+ /** A saved attempt that can't be shown here: absence of evidence is never permission to send. */
89
+ export const SAVED_ATTEMPT_CHECK_LINE = "This transaction may already be in your wallet, and it cannot be confirmed from here.";
90
+ /** The warning under it. */
91
+ export const SAVED_ATTEMPT_CHECK_WARNING = "Check your wallet and the explorer first. Continuing can send it twice.";
92
+ /** The one check action's label: "I checked it. Review it again." or the flow's next step ("Create again"). */
93
+ export function checkedItLabel(next = "Review it again") {
94
+ return `I checked it. ${next.replace(/\.+$/, "")}.`;
95
+ }
96
+ /** Under a retirement that lasts in this tab alone (`durable: false`). */
97
+ export const SAVED_ATTEMPT_TAB_ONLY_LINE = "This applies to this tab only.";
98
+ /** When the browser has storage but can't read it: the warned exit's line. */
99
+ export const SAVED_ATTEMPT_UNREADABLE_LINE = "This browser can't read its saved transactions. Check your wallet before sending again.";
100
+ /** The warned exit's label, offered only after a check action found storage unreadable. */
101
+ export const SAVED_ATTEMPT_CONTINUE_ANYWAY_LABEL = "I checked my wallet. Continue anyway";
70
102
  //# sourceMappingURL=messages.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/review/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAa,EACb,EACE,MAAM,GAAG,QAAQ,EACjB,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,EAClB,UAAU,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,EAAE,MAKxD,EAAE;IAEN,OAAO,KAAK,GAAG,KAAK,GAAG,KAAK;QAC1B,CAAC,CAAC,QAAQ,MAAM,4CAA4C,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,yBAAyB;QAC9G,CAAC,CAAC,QAAQ,MAAM,iEAAiE,CAAC;AACtF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAqB,EACrB,EACE,MAAM,GAAG,QAAQ,EACjB,OAAO,GAAG,SAAS,EACnB,gBAAgB,GAAG,KAAK,MAC6C,EAAE;IAEzE,IAAI,MAAM,KAAK,KAAK;QAClB,OAAO,QAAQ,MAAM,wDAAwD,OAAO,uCAAuC,CAAC;IAC9H,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,OAAO,OAAO,6BAA6B,CAAC;IAC7E,OAAO,gBAAgB;QACrB,CAAC,CAAC,iDAAiD,MAAM,qDAAqD;QAC9G,CAAC,CAAC,QAAQ,MAAM,gDAAgD,CAAC;AACrE,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,gBAAgB,CAAC,MAAM,GAAG,aAAa;IACrD,OAAO,gBAAgB,MAAM,2CAA2C,CAAC;AAC3E,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,iCAAiC,CAAC;AAElE,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAC9B,IAAiC,EACjC,MAAM,GAAG,aAAa;IAEtB,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE;QACjC,CAAC,CAAC,mBAAmB,MAAM,0CAA0C;QACrE,CAAC,CAAC,mBAAmB,MAAM,6CAA6C,CAAC;AAC7E,CAAC;AAED,iEAAiE;AACjE,MAAM,CAAC,MAAM,2BAA2B,GACtC,uEAAuE,CAAC;AAE1E,gDAAgD;AAChD,MAAM,CAAC,MAAM,2BAA2B,GAAG,iCAAiC,CAAC;AAE7E,yEAAyE;AACzE,MAAM,CAAC,MAAM,4BAA4B,GACvC,wEAAwE,CAAC;AAE3E,sFAAsF;AACtF,MAAM,CAAC,MAAM,sBAAsB,GACjC,2FAA2F,CAAC;AAE9F,mFAAmF;AACnF,MAAM,CAAC,MAAM,uBAAuB,GAClC,+DAA+D,CAAC;AAElE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,wBAAwB,GACnC,sEAAsE,CAAC;AAEzE,gGAAgG;AAChG,MAAM,CAAC,MAAM,yBAAyB,GACpC,oFAAoF,CAAC;AAEvF,qFAAqF;AACrF,MAAM,CAAC,MAAM,qBAAqB,GAChC,0FAA0F,CAAC;AAE7F,+DAA+D;AAC/D,MAAM,CAAC,MAAM,2BAA2B,GACtC,8EAA8E,CAAC;AAEjF,wFAAwF;AACxF,MAAM,CAAC,MAAM,6BAA6B,GACxC,6EAA6E,CAAC;AAEhF,6GAA6G;AAC7G,MAAM,CAAC,MAAM,0BAA0B,GACrC,oDAAoD,CAAC;AAEvD,iFAAiF;AACjF,MAAM,CAAC,MAAM,6BAA6B,GACxC,qFAAqF,CAAC;AAExF,+FAA+F;AAC/F,MAAM,CAAC,MAAM,qBAAqB,GAChC,gEAAgE,CAAC;AAEnE,yGAAyG;AACzG,MAAM,CAAC,MAAM,4BAA4B,GACvC,0EAA0E,CAAC"}
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/review/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { HeldWriteItem } from "./useHeldWrites.js";
2
+ /**
3
+ * The one app-wide notice of held writes: each with its action's label, its
4
+ * line, any warning, and the release when its hold offers the exit. Feed it
5
+ * useHeldWrites, useHeldIntents, or both. Unstyled: `className` is the hook.
6
+ */
7
+ export declare function HeldWritesNotice({ items, className, }: {
8
+ items: readonly HeldWriteItem[];
9
+ className?: string;
10
+ }): import("react").JSX.Element | null;
11
+ //# sourceMappingURL=HeldWritesNotice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeldWritesNotice.d.ts","sourceRoot":"","sources":["../../../../src/review/react/HeldWritesNotice.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,SAAS,GACV,EAAE;IACD,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,sCA4BA"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { HELD_RELEASE_LABEL } from "../index.js";
3
+ import { useState } from "react";
4
+ /**
5
+ * The one app-wide notice of held writes: each with its action's label, its
6
+ * line, any warning, and the release when its hold offers the exit. Feed it
7
+ * useHeldWrites, useHeldIntents, or both. Unstyled: `className` is the hook.
8
+ */
9
+ export function HeldWritesNotice({ items, className, }) {
10
+ const [busy, setBusy] = useState(null);
11
+ const shown = items.filter(({ view }) => view.line);
12
+ if (!shown.length)
13
+ return null;
14
+ return (_jsx("div", { role: "status", className: className, children: shown.map(({ key, label, view, release }) => (_jsxs("div", { "data-phase": view.phase, children: [label ? _jsx("p", { children: label }) : null, _jsx("p", { children: view.line }), view.warning ? _jsx("p", { children: view.warning }) : null, view.notice ? _jsx("p", { children: view.notice }) : null, view.exit ? (_jsx("button", { type: "button", disabled: busy === key, onClick: () => {
15
+ setBusy(key);
16
+ void release().finally(() => setBusy(null));
17
+ }, children: HELD_RELEASE_LABEL })) : null] }, key))) }));
18
+ }
19
+ //# sourceMappingURL=HeldWritesNotice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HeldWritesNotice.js","sourceRoot":"","sources":["../../../../src/review/react/HeldWritesNotice.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAGjC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,KAAK,EACL,SAAS,GAIV;IACC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,CACL,cAAK,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAE,SAAS,YACpC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAC5C,6BAA2B,IAAI,CAAC,KAAK,aAClC,KAAK,CAAC,CAAC,CAAC,sBAAI,KAAK,GAAK,CAAC,CAAC,CAAC,IAAI,EAC9B,sBAAI,IAAI,CAAC,IAAI,GAAK,EACjB,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAI,IAAI,CAAC,OAAO,GAAK,CAAC,CAAC,CAAC,IAAI,EAC3C,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,sBAAI,IAAI,CAAC,MAAM,GAAK,CAAC,CAAC,CAAC,IAAI,EACzC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CACX,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,IAAI,KAAK,GAAG,EACtB,OAAO,EAAE,GAAG,EAAE;wBACZ,OAAO,CAAC,GAAG,CAAC,CAAC;wBACb,KAAK,OAAO,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC9C,CAAC,YAEA,kBAAkB,GACZ,CACV,CAAC,CAAC,CAAC,IAAI,KAhBA,GAAG,CAiBP,CACP,CAAC,GACE,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./HeldWritesNotice.js";
2
+ export * from "./useHeldWrite.js";
3
+ export * from "./useHeldWrites.js";
4
+ export * from "./useSavedAttempt.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/review/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./HeldWritesNotice.js";
2
+ export * from "./useHeldWrite.js";
3
+ export * from "./useHeldWrites.js";
4
+ export * from "./useSavedAttempt.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/review/react/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { type HeldWriteEvidence, type HeldWriteView, type ReviewedWriteRecoveryInput, type WriteHold, type WriteHoldClient, type WriteHoldGate, type WriteHoldHandle, type WriteHoldSettled, type WriteHoldState } from "../index.js";
2
+ import type { Address, Hex, TransactionReceipt } from "viem";
3
+ export type UseHeldWriteOptions = {
4
+ /** The app's one write hold controller (createWriteHold()). */
5
+ hold: WriteHold;
6
+ chainId: number;
7
+ /** The account that sends: the wallet, or the Safe. */
8
+ account: Address;
9
+ /** Whether `account` is a Safe whose writes are proposals. */
10
+ safe?: boolean;
11
+ /** The action's intent key (payIntent and the other builders). */
12
+ namespace?: string;
13
+ /** Keys an earlier version held this write under. */
14
+ legacy?: Parameters<WriteHold["open"]>[1] extends infer O ? O extends {
15
+ legacy?: infer L;
16
+ } ? L : never : never;
17
+ /** The reviewed call, when built; without one, the hold is found by `namespace`. */
18
+ call?: ReviewedWriteRecoveryInput["call"];
19
+ /** Reads the account's chain. */
20
+ client: WriteHoldClient | undefined;
21
+ /** A previous deploy's saved evidence of this write: adopted before any send. */
22
+ adopt?: () => Promise<HeldWriteEvidence | null | undefined>;
23
+ onAdopted?: (state: WriteHoldState) => void;
24
+ /** The hold settled what this view saw held, on authenticated evidence: once. */
25
+ onSettled?: (settled: WriteHoldSettled, receipt: TransactionReceipt | null) => void;
26
+ /** Released: by the user's exit (reopen the review), or by another window. */
27
+ onReleased?: (by: "user" | "other-tab") => void;
28
+ /** How often a held write is asked again (15 s to 60 s, 30 s by default). */
29
+ pollMs?: number;
30
+ };
31
+ export type UseHeldWriteResult = HeldWriteView & {
32
+ /** The exit the hold offers now, with its label; null when none. */
33
+ exitAction: {
34
+ label: string;
35
+ run: () => Promise<boolean>;
36
+ } | null;
37
+ /**
38
+ * On a success settled while away ("This went through while you were
39
+ * away."): the user's choice to send it again. Null otherwise.
40
+ */
41
+ sendAgainAction: {
42
+ label: string;
43
+ run: () => Promise<void>;
44
+ } | null;
45
+ /** Send under the hold, once any adoption is done. */
46
+ send: (run: (gate: WriteHoldGate) => Promise<Hex>) => Promise<Hex>;
47
+ /** Ask the chain now. */
48
+ check: () => Promise<HeldWriteView>;
49
+ /** The hold handle, for anything else. */
50
+ handle: WriteHoldHandle | undefined;
51
+ };
52
+ /**
53
+ * One held write, the one way every app runs it: its send under the hold,
54
+ * the watch, the shared follower of its transaction or Safe proposal, its
55
+ * one line, its exit and the adoption of a previous deploy's record.
56
+ *
57
+ * The exit ("I checked my wallet") only releases the hold: `onReleased("user")`
58
+ * is where the app reopens its review, so a resend always shows the values it
59
+ * sends. A release by another window is neutral (`releasedBy: "other-tab"`),
60
+ * and `onSettled` fires only for a settlement of what this view saw held.
61
+ */
62
+ export declare function useHeldWrite(options: UseHeldWriteOptions): UseHeldWriteResult;
63
+ //# sourceMappingURL=useHeldWrite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHeldWrite.d.ts","sourceRoot":"","sources":["../../../../src/review/react/useHeldWrite.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,0BAA0B,EAC/B,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACpB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,MAAM,CAAC;AAQ7D,MAAM,MAAM,mBAAmB,GAAG;IAChC,+DAA+D;IAC/D,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,MAAM,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,GACrD,CAAC,SAAS;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAA;KAAE,GAC5B,CAAC,GACD,KAAK,GACP,KAAK,CAAC;IACV,oFAAoF;IACpF,IAAI,CAAC,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;IAC1C,iCAAiC;IACjC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,iBAAiB,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IAC5D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC5C,iFAAiF;IACjF,SAAS,CAAC,EAAE,CACV,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,kBAAkB,GAAG,IAAI,KAC/B,IAAI,CAAC;IACV,8EAA8E;IAC9E,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,KAAK,IAAI,CAAC;IAChD,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG;IAC/C,oEAAoE;IACpE,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE;;;OAGG;IACH,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACpE,sDAAsD;IACtD,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IACnE,yBAAyB;IACzB,KAAK,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,CAAC;IACpC,0CAA0C;IAC1C,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;CACrC,CAAC;AAiBF;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAgG7E"}
@@ -0,0 +1,104 @@
1
+ import { createHeldWriteView, HELD_EXIT_LABEL, HELD_SEND_AGAIN_LABEL, } from "../index.js";
2
+ import { useEffect, useMemo, useRef, useSyncExternalStore } from "react";
3
+ /** A call stand-in for a hold found by its intent alone, before any call is built. */
4
+ const NO_CALL = {
5
+ to: "0x0000000000000000000000000000000000000000",
6
+ data: "0x",
7
+ };
8
+ const IDLE = {
9
+ phase: "clear",
10
+ state: null,
11
+ line: null,
12
+ exit: false,
13
+ adopting: false,
14
+ };
15
+ const none = () => () => { };
16
+ /** A value's identity for a memo key, wei amounts (bigints) included. */
17
+ const keyOf = (value) => JSON.stringify(value, (_, field) => typeof field === "bigint" ? `${field}n` : field);
18
+ const idle = () => IDLE;
19
+ /**
20
+ * One held write, the one way every app runs it: its send under the hold,
21
+ * the watch, the shared follower of its transaction or Safe proposal, its
22
+ * one line, its exit and the adoption of a previous deploy's record.
23
+ *
24
+ * The exit ("I checked my wallet") only releases the hold: `onReleased("user")`
25
+ * is where the app reopens its review, so a resend always shows the values it
26
+ * sends. A release by another window is neutral (`releasedBy: "other-tab"`),
27
+ * and `onSettled` fires only for a settlement of what this view saw held.
28
+ */
29
+ export function useHeldWrite(options) {
30
+ const { hold, chainId, account, safe = false, namespace, client, pollMs, } = options;
31
+ const callKey = keyOf(options.call ?? null);
32
+ const legacyKey = keyOf(options.legacy ?? null);
33
+ const latest = useRef(options);
34
+ latest.current = options;
35
+ const handle = useMemo(() => {
36
+ const call = latest.current.call;
37
+ if (!call && !namespace)
38
+ return undefined;
39
+ const legacy = latest.current.legacy;
40
+ return hold.open({
41
+ chainId,
42
+ account,
43
+ safe,
44
+ call: call ?? NO_CALL,
45
+ ...(namespace ? { namespace } : {}),
46
+ }, legacy ? { legacy } : undefined);
47
+ // The call and legacy keys stand for their values.
48
+ }, [hold, chainId, account, safe, namespace, callKey, legacyKey]);
49
+ // Whether the app has a previous deploy's record to adopt: a change makes a
50
+ // new view, whose adoption runs before any send.
51
+ const adopts = !!options.adopt;
52
+ /** The view whose callbacks are the app's now: an earlier one's late answers reach none. */
53
+ const active = useRef(undefined);
54
+ const view = useMemo(() => {
55
+ if (!handle || !client)
56
+ return undefined;
57
+ /** Only while this view is the app's: an earlier one's late answers reach no callback. */
58
+ const own = (callback) => (...args) => {
59
+ if (active.current === created)
60
+ callback(...args);
61
+ };
62
+ const created = createHeldWriteView(handle, {
63
+ client,
64
+ pollMs,
65
+ onSettled: own((settled, receipt) => latest.current.onSettled?.(settled, receipt)),
66
+ onReleased: own((by) => latest.current.onReleased?.(by)),
67
+ onAdopted: own((state) => latest.current.onAdopted?.(state)),
68
+ // A view made with a provider: the app's current one (a removed one
69
+ // makes a new view, and this one stops).
70
+ ...(adopts ? { adopt: () => latest.current.adopt() } : {}),
71
+ });
72
+ return created;
73
+ }, [handle, client, pollMs, adopts]);
74
+ useEffect(() => {
75
+ if (!view)
76
+ return;
77
+ active.current = view;
78
+ const stop = view.start();
79
+ return () => {
80
+ if (active.current === view)
81
+ active.current = undefined;
82
+ stop();
83
+ };
84
+ }, [view]);
85
+ const shown = useSyncExternalStore(view?.subscribe ?? none, view?.get ?? idle, view?.get ?? idle);
86
+ return {
87
+ ...shown,
88
+ exitAction: shown.exit && view ? { label: HELD_EXIT_LABEL, run: view.exit } : null,
89
+ sendAgainAction: shown.phase === "succeeded" && view
90
+ ? { label: HELD_SEND_AGAIN_LABEL, run: view.acknowledge }
91
+ : null,
92
+ send: (run) => {
93
+ if (!view)
94
+ return Promise.reject(new Error("Connect a wallet and build the call before sending."));
95
+ // A record to adopt that this view doesn't know of yet: never send past it.
96
+ if (!!latest.current.adopt !== adopts)
97
+ return Promise.reject(new Error("Saved transactions are still being checked. Try again in a moment."));
98
+ return view.send(run);
99
+ },
100
+ check: () => (view ? view.check() : Promise.resolve(IDLE)),
101
+ handle,
102
+ };
103
+ }
104
+ //# sourceMappingURL=useHeldWrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHeldWrite.js","sourceRoot":"","sources":["../../../../src/review/react/useHeldWrite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { type HeldWriteView, type WriteHold, type WriteHoldClient } from "../index.js";
2
+ import type { Address } from "viem";
3
+ /** One held write an app-wide notice shows. */
4
+ export type HeldWriteItem = {
5
+ key: string;
6
+ /** What the action is, when the app names it. */
7
+ label?: string;
8
+ view: HeldWriteView;
9
+ /** Release it (the notice's exit): true when released. */
10
+ release: () => Promise<boolean>;
11
+ };
12
+ /**
13
+ * The holds of a fixed set of actions, found by their intents alone and
14
+ * shown with their lines and exits, whatever the actions' buttons allow now.
15
+ */
16
+ export declare function useHeldIntents({ hold, chainId, account, client, intents, pollMs, }: {
17
+ hold: WriteHold;
18
+ chainId: number;
19
+ account: Address | undefined;
20
+ client: WriteHoldClient | undefined;
21
+ intents: readonly {
22
+ namespace: string;
23
+ label?: string;
24
+ }[];
25
+ pollMs?: number;
26
+ }): HeldWriteItem[];
27
+ /**
28
+ * Every write held for `account` on `chainId`, whatever action made it
29
+ * (`hold.list`), read again when another window changes one and every poll.
30
+ */
31
+ export declare function useHeldWrites({ hold, chainId, account, client, label, pollMs, }: {
32
+ hold: WriteHold;
33
+ chainId: number;
34
+ account: Address | undefined;
35
+ client: WriteHoldClient | undefined;
36
+ /** The app's name for a listed write's action, when it knows it. */
37
+ label?: (record: ReturnType<WriteHold["list"]>[number]["record"]) => string | undefined;
38
+ pollMs?: number;
39
+ }): HeldWriteItem[];
40
+ //# sourceMappingURL=useHeldWrites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHeldWrites.d.ts","sourceRoot":"","sources":["../../../../src/review/react/useHeldWrites.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,aAAa,EAElB,KAAK,SAAS,EACd,KAAK,eAAe,EAErB,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,OAAO,EAAO,MAAM,MAAM,CAAC;AAEzC,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,aAAa,CAAC;IACpB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC,CAAC;AAqDF;;;GAGG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,OAAO,EACP,MAAM,EACN,OAAO,EACP,MAAM,GACP,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,OAAO,EAAE,SAAS;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,EAAE,CAqBlB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,OAAO,EACP,OAAO,EACP,MAAM,EACN,KAAK,EACL,MAAe,GAChB,EAAE;IACD,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,oEAAoE;IACpE,KAAK,CAAC,EAAE,CACN,MAAM,EAAE,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KACpD,MAAM,GAAG,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,aAAa,EAAE,CA6BlB"}
@@ -0,0 +1,91 @@
1
+ import { createHeldWriteView, } from "../index.js";
2
+ import { useEffect, useMemo, useState, useSyncExternalStore } from "react";
3
+ /** Watch each entry's hold as one held write view; held ones (and fresh results) come back as items. */
4
+ function useHeldViews(entries, client, pollMs) {
5
+ const views = useMemo(() => client
6
+ ? entries.map((entry) => ({
7
+ entry,
8
+ view: createHeldWriteView(entry.handle, { client, pollMs }),
9
+ }))
10
+ : [], [entries, client, pollMs]);
11
+ useEffect(() => {
12
+ const stops = views.map(({ view }) => view.start());
13
+ return () => stops.forEach((stop) => stop());
14
+ }, [views]);
15
+ const store = useMemo(() => feed(views.map(({ view }) => view)), [views]);
16
+ const shown = useSyncExternalStore(store.subscribe, store.get, store.get);
17
+ return views
18
+ .map(({ entry, view }, index) => ({
19
+ key: entry.key,
20
+ ...(entry.label ? { label: entry.label } : {}),
21
+ view: shown[index],
22
+ release: view.exit,
23
+ }))
24
+ .filter(({ view }) => view.phase !== "clear");
25
+ }
26
+ /** Several views as one store: a snapshot array that changes when any view does. */
27
+ function feed(views) {
28
+ let snapshot = views.map((view) => view.get());
29
+ return {
30
+ subscribe(listener) {
31
+ const stops = views.map((view) => view.subscribe(() => {
32
+ snapshot = views.map((each) => each.get());
33
+ listener();
34
+ }));
35
+ return () => stops.forEach((stop) => stop());
36
+ },
37
+ get: () => snapshot,
38
+ };
39
+ }
40
+ /**
41
+ * The holds of a fixed set of actions, found by their intents alone and
42
+ * shown with their lines and exits, whatever the actions' buttons allow now.
43
+ */
44
+ export function useHeldIntents({ hold, chainId, account, client, intents, pollMs, }) {
45
+ const intentsKey = JSON.stringify(intents);
46
+ const entries = useMemo(() => account
47
+ ? intents.map(({ namespace, label }) => ({
48
+ key: namespace,
49
+ label,
50
+ handle: hold.open({
51
+ chainId,
52
+ account,
53
+ safe: false,
54
+ namespace,
55
+ call: { to: account, data: "0x" },
56
+ }),
57
+ }))
58
+ : [],
59
+ // The intents key stands for the intents.
60
+ [hold, chainId, account, intentsKey]);
61
+ return useHeldViews(entries, client, pollMs);
62
+ }
63
+ /**
64
+ * Every write held for `account` on `chainId`, whatever action made it
65
+ * (`hold.list`), read again when another window changes one and every poll.
66
+ */
67
+ export function useHeldWrites({ hold, chainId, account, client, label, pollMs = 30_000, }) {
68
+ const [generation, setGeneration] = useState(0);
69
+ useEffect(() => {
70
+ const again = () => setGeneration((value) => value + 1);
71
+ globalThis.addEventListener?.("storage", again);
72
+ const timer = setInterval(again, pollMs);
73
+ return () => {
74
+ globalThis.removeEventListener?.("storage", again);
75
+ clearInterval(timer);
76
+ };
77
+ }, [pollMs]);
78
+ const listed = useMemo(() => (account ? hold.list({ account, chainId }) : []), [hold, account, chainId, generation]);
79
+ const listedKey = listed
80
+ .map(({ key, record }) => `${key}:${record.id}`)
81
+ .join("|");
82
+ const entries = useMemo(() => listed.map(({ key, record, handle }) => ({
83
+ key,
84
+ label: label?.(record),
85
+ handle,
86
+ })),
87
+ // The listed key stands for the list.
88
+ [listedKey]);
89
+ return useHeldViews(entries, client, pollMs);
90
+ }
91
+ //# sourceMappingURL=useHeldWrites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHeldWrites.js","sourceRoot":"","sources":["../../../../src/review/react/useHeldWrites.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { type SavedAttempt, type SavedAttemptOutcome, type SavedAttemptRecovery, type SavedAttemptRetirement, type WriteHoldClient } from "../index.js";
2
+ export type UseSavedAttemptOptions<T> = {
3
+ /** The app's one saved-attempt recovery (createSavedAttemptRecovery()). */
4
+ recovery: SavedAttemptRecovery;
5
+ /** The saved attempt; none while nothing is saved. */
6
+ attempt: SavedAttempt<T> | null | undefined;
7
+ /** Reads the attempt's chain. */
8
+ client: WriteHoldClient | undefined;
9
+ /** The check action's next step: "I checked it. <next>." ("Review it again" by default). */
10
+ checkNext?: string;
11
+ };
12
+ /** What a retirement returned: whether it took, and whether it outlives this tab. */
13
+ type Retired = Awaited<ReturnType<SavedAttemptRecovery["retire"]>>;
14
+ export type UseSavedAttemptResult<T> = {
15
+ /** How recovery ended; null until it has, or with no attempt. */
16
+ outcome: SavedAttemptOutcome<T> | null;
17
+ recovering: boolean;
18
+ /** Recover again now: also "Check again" on a success whose details are unavailable. */
19
+ recover: () => Promise<SavedAttemptOutcome<T> | null>;
20
+ /** On `check`: the one explicit action, which retires the attempt for every tab and reload. */
21
+ checkAction: {
22
+ line: string;
23
+ warning: string;
24
+ label: string;
25
+ run: () => Promise<Retired>;
26
+ } | null;
27
+ /**
28
+ * Only after the check action came back `reason: "unreadable"` (the browser
29
+ * has storage it can't read): the warned exit, "I checked my wallet.
30
+ * Continue anyway", which retires in this tab alone if storage still can't
31
+ * be read. Never a first option.
32
+ */
33
+ unreadableAction: {
34
+ line: string;
35
+ label: string;
36
+ run: () => Promise<Retired>;
37
+ } | null;
38
+ /**
39
+ * Retire after the user's exit or a followed settlement; recovers again.
40
+ * Bound to the attempt it was rendered for: called after that attempt (or
41
+ * its recovery or client) changed, it refuses before anything is saved.
42
+ */
43
+ retire: (reason: SavedAttemptRetirement) => Promise<Retired>;
44
+ };
45
+ /**
46
+ * One saved attempt's recovery, the one way every app runs it: recovered
47
+ * when it (or the client) appears, before the app prepares any new send, with
48
+ * the check action ready on `check`. Every answer and callback belongs to the
49
+ * attempt, recovery and client it started with: an earlier one's, or an older
50
+ * request's, never reaches the current one.
51
+ */
52
+ export declare function useSavedAttempt<T>(options: UseSavedAttemptOptions<T>): UseSavedAttemptResult<T>;
53
+ export {};
54
+ //# sourceMappingURL=useSavedAttempt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedAttempt.d.ts","sourceRoot":"","sources":["../../../../src/review/react/useSavedAttempt.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AAUrB,MAAM,MAAM,sBAAsB,CAAC,CAAC,IAAI;IACtC,2EAA2E;IAC3E,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,sDAAsD;IACtD,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,iCAAiC;IACjC,MAAM,EAAE,eAAe,GAAG,SAAS,CAAC;IACpC,4FAA4F;IAC5F,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qFAAqF;AACrF,KAAK,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AAEnE,MAAM,MAAM,qBAAqB,CAAC,CAAC,IAAI;IACrC,iEAAiE;IACjE,OAAO,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,UAAU,EAAE,OAAO,CAAC;IACpB,wFAAwF;IACxF,OAAO,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtD,+FAA+F;IAC/F,WAAW,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT;;;;;OAKG;IACH,gBAAgB,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT;;;;OAIG;IACH,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAC9D,CAAC;AASF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,OAAO,EAAE,sBAAsB,CAAC,CAAC,CAAC,GACjC,qBAAqB,CAAC,CAAC,CAAC,CAoG1B"}
@@ -0,0 +1,102 @@
1
+ import { checkedItLabel, SAVED_ATTEMPT_CONTINUE_ANYWAY_LABEL, SAVED_ATTEMPT_UNREADABLE_LINE, } from "../index.js";
2
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
3
+ const keyOf = (attempt) => attempt
4
+ ? JSON.stringify({ ...attempt, authenticate: undefined }, (_, value) => typeof value === "bigint" ? value.toString() : value)
5
+ : null;
6
+ /**
7
+ * One saved attempt's recovery, the one way every app runs it: recovered
8
+ * when it (or the client) appears, before the app prepares any new send, with
9
+ * the check action ready on `check`. Every answer and callback belongs to the
10
+ * attempt, recovery and client it started with: an earlier one's, or an older
11
+ * request's, never reaches the current one.
12
+ */
13
+ export function useSavedAttempt(options) {
14
+ const { recovery, client, checkNext } = options;
15
+ const key = keyOf(options.attempt);
16
+ const attempt = options.attempt;
17
+ /** The attempt as last rendered: the same saved fields, with the app's newest callbacks. */
18
+ const latest = useRef(attempt);
19
+ latest.current = attempt;
20
+ /** One lifecycle per attempt, recovery and client, with its latest request. */
21
+ const lifecycle = useMemo(() => ({ attempt, recovery, client, request: 0 }),
22
+ // The key stands for the attempt.
23
+ [key, recovery, client]);
24
+ /** Whether `of` is the mounted hook's lifecycle now. */
25
+ const current = (of) => mounted.current && rendered.current === of;
26
+ /**
27
+ * The lifecycle last rendered: set during render, so a callback of an
28
+ * earlier one is refused from the next commit's first layout effect on. A
29
+ * render React then discards leaves the shown callbacks refused (fail
30
+ * closed) until the next commit.
31
+ */
32
+ const rendered = useRef(undefined);
33
+ rendered.current = lifecycle;
34
+ /** Whether the hook is mounted: no callback or answer acts after unmount. */
35
+ const mounted = useRef(false);
36
+ useLayoutEffect(() => {
37
+ mounted.current = true;
38
+ return () => {
39
+ mounted.current = false;
40
+ };
41
+ }, []);
42
+ const [shown, setShown] = useState({ outcome: null, recovering: false });
43
+ /** The lifecycle whose check action last found storage unreadable. */
44
+ const [unreadable, setUnreadable] = useState();
45
+ const recover = useCallback(async () => {
46
+ const { recovery, client } = lifecycle;
47
+ const attempt = latest.current;
48
+ if (!attempt || !client || !current(lifecycle))
49
+ return null;
50
+ const request = ++lifecycle.request;
51
+ setShown((now) => ({
52
+ of: lifecycle,
53
+ outcome: now.of === lifecycle ? now.outcome : null,
54
+ recovering: true,
55
+ }));
56
+ const outcome = await recovery.recover(attempt, client);
57
+ // Only the latest request of the mounted lifecycle shows.
58
+ if (!current(lifecycle) || lifecycle.request !== request)
59
+ return null;
60
+ setShown({ of: lifecycle, outcome, recovering: false });
61
+ return outcome;
62
+ }, [lifecycle]);
63
+ useEffect(() => {
64
+ void recover();
65
+ }, [recover]);
66
+ const retire = useCallback(async (reason) => {
67
+ const { recovery } = lifecycle;
68
+ const attempt = latest.current;
69
+ if (!attempt || !current(lifecycle))
70
+ return { retired: false };
71
+ const retired = await recovery.retire(attempt, reason);
72
+ if (!current(lifecycle))
73
+ return retired;
74
+ if (!retired.retired && retired.reason === "unreadable")
75
+ setUnreadable(lifecycle);
76
+ await recover();
77
+ return retired;
78
+ }, [lifecycle, recover]);
79
+ const outcome = shown.of === lifecycle ? shown.outcome : null;
80
+ return {
81
+ outcome,
82
+ recovering: shown.of === lifecycle && shown.recovering,
83
+ recover,
84
+ checkAction: outcome?.status === "check"
85
+ ? {
86
+ line: outcome.line,
87
+ warning: outcome.warning,
88
+ label: checkedItLabel(checkNext),
89
+ run: () => retire({ by: "check", outcome }),
90
+ }
91
+ : null,
92
+ unreadableAction: outcome?.status === "check" && unreadable === lifecycle
93
+ ? {
94
+ line: SAVED_ATTEMPT_UNREADABLE_LINE,
95
+ label: SAVED_ATTEMPT_CONTINUE_ANYWAY_LABEL,
96
+ run: () => retire({ by: "check", outcome, force: "unreadable" }),
97
+ }
98
+ : null,
99
+ retire,
100
+ };
101
+ }
102
+ //# sourceMappingURL=useSavedAttempt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedAttempt.js","sourceRoot":"","sources":["../../../../src/review/react/useSavedAttempt.ts"],"names":[],"mappings":"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"}