@valve-tech/tx-flight-react 0.0.1

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 (80) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +283 -0
  4. package/dist/components/actions.d.ts +32 -0
  5. package/dist/components/actions.d.ts.map +1 -0
  6. package/dist/components/actions.js +10 -0
  7. package/dist/components/actions.js.map +1 -0
  8. package/dist/components/age.d.ts +21 -0
  9. package/dist/components/age.d.ts.map +1 -0
  10. package/dist/components/age.js +29 -0
  11. package/dist/components/age.js.map +1 -0
  12. package/dist/components/hash-link.d.ts +26 -0
  13. package/dist/components/hash-link.d.ts.map +1 -0
  14. package/dist/components/hash-link.js +20 -0
  15. package/dist/components/hash-link.js.map +1 -0
  16. package/dist/components/item.d.ts +27 -0
  17. package/dist/components/item.d.ts.map +1 -0
  18. package/dist/components/item.js +18 -0
  19. package/dist/components/item.js.map +1 -0
  20. package/dist/components/list.d.ts +27 -0
  21. package/dist/components/list.d.ts.map +1 -0
  22. package/dist/components/list.js +14 -0
  23. package/dist/components/list.js.map +1 -0
  24. package/dist/components/status-icon.d.ts +20 -0
  25. package/dist/components/status-icon.d.ts.map +1 -0
  26. package/dist/components/status-icon.js +28 -0
  27. package/dist/components/status-icon.js.map +1 -0
  28. package/dist/index.d.ts +18 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +19 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/integrations/tx-tracker.d.ts +48 -0
  33. package/dist/integrations/tx-tracker.d.ts.map +1 -0
  34. package/dist/integrations/tx-tracker.js +169 -0
  35. package/dist/integrations/tx-tracker.js.map +1 -0
  36. package/dist/integrations/wallet-adapter.d.ts +34 -0
  37. package/dist/integrations/wallet-adapter.d.ts.map +1 -0
  38. package/dist/integrations/wallet-adapter.js +97 -0
  39. package/dist/integrations/wallet-adapter.js.map +1 -0
  40. package/dist/provider.d.ts +67 -0
  41. package/dist/provider.d.ts.map +1 -0
  42. package/dist/provider.js +182 -0
  43. package/dist/provider.js.map +1 -0
  44. package/dist/storage/index.d.ts +7 -0
  45. package/dist/storage/index.d.ts.map +1 -0
  46. package/dist/storage/index.js +7 -0
  47. package/dist/storage/index.js.map +1 -0
  48. package/dist/storage/indexed-db.d.ts +21 -0
  49. package/dist/storage/indexed-db.d.ts.map +1 -0
  50. package/dist/storage/indexed-db.js +58 -0
  51. package/dist/storage/indexed-db.js.map +1 -0
  52. package/dist/storage/local-storage.d.ts +18 -0
  53. package/dist/storage/local-storage.d.ts.map +1 -0
  54. package/dist/storage/local-storage.js +39 -0
  55. package/dist/storage/local-storage.js.map +1 -0
  56. package/dist/storage/memory.d.ts +7 -0
  57. package/dist/storage/memory.d.ts.map +1 -0
  58. package/dist/storage/memory.js +17 -0
  59. package/dist/storage/memory.js.map +1 -0
  60. package/dist/storage/serialize.d.ts +13 -0
  61. package/dist/storage/serialize.d.ts.map +1 -0
  62. package/dist/storage/serialize.js +29 -0
  63. package/dist/storage/serialize.js.map +1 -0
  64. package/dist/store/reducers.d.ts +53 -0
  65. package/dist/store/reducers.d.ts.map +1 -0
  66. package/dist/store/reducers.js +135 -0
  67. package/dist/store/reducers.js.map +1 -0
  68. package/dist/store/store.d.ts +56 -0
  69. package/dist/store/store.d.ts.map +1 -0
  70. package/dist/store/store.js +93 -0
  71. package/dist/store/store.js.map +1 -0
  72. package/dist/types.d.ts +96 -0
  73. package/dist/types.d.ts.map +1 -0
  74. package/dist/types.js +21 -0
  75. package/dist/types.js.map +1 -0
  76. package/dist/use-tx-flight.d.ts +31 -0
  77. package/dist/use-tx-flight.d.ts.map +1 -0
  78. package/dist/use-tx-flight.js +47 -0
  79. package/dist/use-tx-flight.js.map +1 -0
  80. package/package.json +83 -0
@@ -0,0 +1,182 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ /**
4
+ * @fileoverview <TxFlightProvider> — wraps the React tree with a
5
+ * tx-flight store, scoped by `id`.
6
+ *
7
+ * Lifecycle:
8
+ * - First render: lazy `useState` acquires (or reuses) a store
9
+ * registered under `id` in a module-level registry. Two Providers
10
+ * with the same `id` silently share the same store via refCount.
11
+ * - First commit: `useEffect` starts the side-effect machinery —
12
+ * eviction interval, debounced storage save subscription, storage
13
+ * rehydrate. Idempotent across same-id mounts via `entry.started`.
14
+ * - Unmount: `useEffect` cleanup decrements refCount; if 0, the
15
+ * entry is disposed (timers cleared, final save flushed) and
16
+ * removed from the registry.
17
+ *
18
+ * Why eager registration: the children's first render calls
19
+ * `useTxFlight`, which throws if no store is registered for the id.
20
+ * Lazy `useState` runs once per component instance and is safe to
21
+ * mutate the registry from (no Strict-Mode double-invoke).
22
+ *
23
+ * SSR: `'use client'` keeps Next.js RSC from running this on the
24
+ * server. Other SSR frameworks (renderToString) will reach the lazy
25
+ * registration; that's acceptable for v0.9.0 because side effects
26
+ * (timers, storage IO) are gated by `useEffect`. Task 12 audits the
27
+ * surface for residual `window`/`document` access.
28
+ */
29
+ import { createContext, useContext, useEffect, useState, } from 'react';
30
+ import { resumeByHashWatcher } from './integrations/tx-tracker.js';
31
+ import { localStorageAdapter } from './storage/local-storage.js';
32
+ import { createTxFlightStore } from './store/store.js';
33
+ const DEFAULT_ID = 'default';
34
+ const DEFAULT_MAX_ITEMS = 50;
35
+ const DEFAULT_TERMINAL_RETENTION_MS = 60000;
36
+ const DEFAULT_SAVE_DEBOUNCE_MS = 250;
37
+ const DEFAULT_EVICT_INTERVAL_MS = 5000;
38
+ const registry = new Map();
39
+ /** @internal — read by `useTxFlight` to find the store for an id. */
40
+ export const _getStoreForId = (id) => registry.get(id)?.store;
41
+ /** @internal — test escape hatch; tears down every entry. */
42
+ export const _resetRegistry = () => {
43
+ for (const entry of registry.values())
44
+ entry.dispose();
45
+ registry.clear();
46
+ };
47
+ const TxFlightContext = createContext(null);
48
+ /** @internal — read by `useTxFlight` to resolve the ambient id. */
49
+ export const _useTxFlightContext = () => useContext(TxFlightContext);
50
+ const startEntry = (id, entry, storage, onError, clientFactory) => {
51
+ // Idempotent restart: tear down any prior dispose (the placeholder
52
+ // on a fresh entry, or a real teardown on a re-start). Keeps
53
+ // startEntry safe to call more than once on the same entry.
54
+ entry.dispose();
55
+ const store = entry.store;
56
+ const evictTimer = setInterval(() => store.dispatch.evict(), DEFAULT_EVICT_INTERVAL_MS);
57
+ // No persistence: only the eviction tick.
58
+ if (!storage) {
59
+ entry.dispose = () => {
60
+ clearInterval(evictTimer);
61
+ };
62
+ return;
63
+ }
64
+ // Persistence: subscribe for debounced save, kick off rehydrate,
65
+ // tear all of it down on dispose.
66
+ let saveTimer = null;
67
+ const flushSave = () => {
68
+ if (saveTimer === null)
69
+ return;
70
+ clearTimeout(saveTimer);
71
+ saveTimer = null;
72
+ storage.save(id, [...store.getTxs()]).catch((err) => {
73
+ onError?.('storage-save', err);
74
+ });
75
+ };
76
+ const unsubscribeStore = store.subscribe(() => {
77
+ if (saveTimer !== null)
78
+ clearTimeout(saveTimer);
79
+ saveTimer = setTimeout(flushSave, DEFAULT_SAVE_DEBOUNCE_MS);
80
+ });
81
+ storage.load(id).then((loaded) => {
82
+ if (loaded === null)
83
+ return;
84
+ for (const tx of loaded) {
85
+ if (store.getState().txs.has(tx.id))
86
+ continue;
87
+ // Pre-hash in-flight states cannot resume across a reload — the
88
+ // wallet interaction is gone. Translate to a terminal failure
89
+ // so the consumer's UI shows the loss honestly.
90
+ if (tx.status === 'preparing' || tx.status === 'awaiting-signature') {
91
+ store.dispatch.addWithTx({ ...tx, status: 'failed', notes: 'lost during reload' }, null);
92
+ continue;
93
+ }
94
+ // Default: seed the entry. For 'pending' with a hash + a
95
+ // configured client, async-attach a tx-tracker watcher so the
96
+ // entry continues advancing toward terminal.
97
+ store.dispatch.addWithTx(tx, null);
98
+ if (tx.status === 'pending' &&
99
+ tx.hash !== undefined &&
100
+ clientFactory !== undefined) {
101
+ const client = clientFactory(tx.chainId);
102
+ if (client !== undefined) {
103
+ // resumeByHashWatcher swallows its own failures into onError.
104
+ void resumeByHashWatcher(store, tx, client, onError);
105
+ }
106
+ }
107
+ }
108
+ }).catch((err) => {
109
+ onError?.('storage-load', err);
110
+ });
111
+ entry.dispose = () => {
112
+ clearInterval(evictTimer);
113
+ unsubscribeStore();
114
+ flushSave();
115
+ };
116
+ };
117
+ export const TxFlightProvider = (props) => {
118
+ const id = props.id ?? DEFAULT_ID;
119
+ const maxItems = props.maxItems ?? DEFAULT_MAX_ITEMS;
120
+ const terminalRetentionMs = props.terminalRetentionMs ?? DEFAULT_TERMINAL_RETENTION_MS;
121
+ const onError = props.onError;
122
+ const clientFactory = props.clientFactory;
123
+ const storage = props.storage === null
124
+ ? null
125
+ : (props.storage ?? localStorageAdapter());
126
+ // Eager: claim a registry entry on first render so children that
127
+ // call `useTxFlight` in their FIRST render see a valid store. Lazy
128
+ // `useState` initializers run once per component instance and are
129
+ // safe to perform a single registration side effect from.
130
+ //
131
+ // refCount is owned by `useEffect` (commit phase). Render-phase
132
+ // registration leaves refCount at 0; the effect bumps it.
133
+ useState(() => {
134
+ const existing = registry.get(id);
135
+ if (existing)
136
+ return existing;
137
+ const store = createTxFlightStore({ maxItems, terminalRetentionMs, onError });
138
+ const fresh = {
139
+ store,
140
+ refCount: 0,
141
+ started: false,
142
+ dispose: () => undefined,
143
+ };
144
+ registry.set(id, fresh);
145
+ return fresh;
146
+ });
147
+ useEffect(() => {
148
+ // The render-phase entry may be missing on this commit if a Strict
149
+ // Mode dev cycle disposed it between setup runs (or a test reset
150
+ // ran). Re-create so children's hooks keep working.
151
+ let entry = registry.get(id);
152
+ if (!entry) {
153
+ const store = createTxFlightStore({ maxItems, terminalRetentionMs, onError });
154
+ entry = {
155
+ store,
156
+ refCount: 0,
157
+ started: false,
158
+ dispose: () => undefined,
159
+ };
160
+ registry.set(id, entry);
161
+ }
162
+ entry.refCount += 1;
163
+ if (!entry.started) {
164
+ entry.started = true;
165
+ startEntry(id, entry, storage, onError, clientFactory);
166
+ }
167
+ // Capture in closure so cleanup uses the entry this commit
168
+ // claimed, not whatever happens to be in the registry later.
169
+ const captured = entry;
170
+ return () => {
171
+ captured.refCount -= 1;
172
+ if (captured.refCount > 0)
173
+ return;
174
+ captured.dispose();
175
+ // Only clear our slot. A test reset may have replaced the entry.
176
+ if (registry.get(id) === captured)
177
+ registry.delete(id);
178
+ };
179
+ }, [id, storage, maxItems, terminalRetentionMs, onError, clientFactory]);
180
+ return (_jsx(TxFlightContext.Provider, { value: { id }, children: props.children }));
181
+ };
182
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Public surface for `@valve-tech/tx-flight-react/storage`.
3
+ */
4
+ export { memoryAdapter } from './memory.js';
5
+ export { localStorageAdapter, type LocalStorageAdapterOptions, } from './local-storage.js';
6
+ export { indexedDBAdapter, type IndexedDBAdapterOptions, } from './indexed-db.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Public surface for `@valve-tech/tx-flight-react/storage`.
3
+ */
4
+ export { memoryAdapter } from './memory.js';
5
+ export { localStorageAdapter, } from './local-storage.js';
6
+ export { indexedDBAdapter, } from './indexed-db.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EACL,mBAAmB,GAEpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,gBAAgB,GAEjB,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @fileoverview IndexedDB adapter — opt-in for consumers who outgrow
3
+ * localStorage's ~5MB cap or need cross-tab persistence with structured
4
+ * data. Async by nature.
5
+ *
6
+ * One database, one object store. Records are keyed by the Provider's
7
+ * `id`; each record stores the serialized JSON string (same format as
8
+ * the localStorage adapter, see `serialize.ts`).
9
+ *
10
+ * SSR-safe: when `globalThis.indexedDB === undefined`, `load` resolves
11
+ * null and `save` resolves no-op.
12
+ */
13
+ import type { TxFlightStorage } from '../types.js';
14
+ export interface IndexedDBAdapterOptions {
15
+ /** Database name. Default: 'tx-flight'. */
16
+ dbName?: string;
17
+ /** Object store name. Default: 'flights'. */
18
+ storeName?: string;
19
+ }
20
+ export declare const indexedDBAdapter: (options?: IndexedDBAdapterOptions) => TxFlightStorage;
21
+ //# sourceMappingURL=indexed-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexed-db.d.ts","sourceRoot":"","sources":["../../src/storage/indexed-db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGlD,MAAM,WAAW,uBAAuB;IACtC,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA2BD,eAAO,MAAM,gBAAgB,aAClB,uBAAuB,KAC/B,eAuBF,CAAA"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @fileoverview IndexedDB adapter — opt-in for consumers who outgrow
3
+ * localStorage's ~5MB cap or need cross-tab persistence with structured
4
+ * data. Async by nature.
5
+ *
6
+ * One database, one object store. Records are keyed by the Provider's
7
+ * `id`; each record stores the serialized JSON string (same format as
8
+ * the localStorage adapter, see `serialize.ts`).
9
+ *
10
+ * SSR-safe: when `globalThis.indexedDB === undefined`, `load` resolves
11
+ * null and `save` resolves no-op.
12
+ */
13
+ import { serialize, deserialize } from './serialize.js';
14
+ const getIndexedDB = () => {
15
+ if (typeof globalThis.indexedDB === 'undefined')
16
+ return null;
17
+ return globalThis.indexedDB;
18
+ };
19
+ const openDb = (factory, dbName, storeName) => new Promise((resolve, reject) => {
20
+ const request = factory.open(dbName, 1);
21
+ request.onupgradeneeded = () => {
22
+ request.result.createObjectStore(storeName);
23
+ };
24
+ request.onsuccess = () => resolve(request.result);
25
+ request.onerror = () => reject(request.error);
26
+ });
27
+ const promisifyRequest = (request) => new Promise((resolve, reject) => {
28
+ request.onsuccess = () => resolve(request.result);
29
+ request.onerror = () => reject(request.error);
30
+ });
31
+ export const indexedDBAdapter = (options = {}) => {
32
+ const dbName = options.dbName ?? 'tx-flight';
33
+ const storeName = options.storeName ?? 'flights';
34
+ return {
35
+ load: async (id) => {
36
+ const factory = getIndexedDB();
37
+ if (!factory)
38
+ return null;
39
+ const db = await openDb(factory, dbName, storeName);
40
+ const tx = db.transaction(storeName, 'readonly');
41
+ const raw = await promisifyRequest(tx.objectStore(storeName).get(id));
42
+ db.close();
43
+ if (typeof raw !== 'string')
44
+ return null;
45
+ return deserialize(raw);
46
+ },
47
+ save: async (id, txs) => {
48
+ const factory = getIndexedDB();
49
+ if (!factory)
50
+ return;
51
+ const db = await openDb(factory, dbName, storeName);
52
+ const tx = db.transaction(storeName, 'readwrite');
53
+ await promisifyRequest(tx.objectStore(storeName).put(serialize(txs), id));
54
+ db.close();
55
+ },
56
+ };
57
+ };
58
+ //# sourceMappingURL=indexed-db.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexed-db.js","sourceRoot":"","sources":["../../src/storage/indexed-db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview localStorage adapter — the default persistence path.
3
+ *
4
+ * Storage key: `${keyPrefix}:${id}`, default `tx-flight:default`.
5
+ * SSR-safe: when `globalThis.window === undefined`, `load` resolves
6
+ * null and `save` resolves no-op (no throw). Hydration on the client
7
+ * picks up the persisted state.
8
+ *
9
+ * The Provider debounces calls to `save` (~250ms), so the
10
+ * sync-write-on-every-keystroke concern doesn't apply here.
11
+ */
12
+ import type { TxFlightStorage } from '../types.js';
13
+ export interface LocalStorageAdapterOptions {
14
+ /** Storage key prefix. Default: 'tx-flight'. */
15
+ keyPrefix?: string;
16
+ }
17
+ export declare const localStorageAdapter: (options?: LocalStorageAdapterOptions) => TxFlightStorage;
18
+ //# sourceMappingURL=local-storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage.d.ts","sourceRoot":"","sources":["../../src/storage/local-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGlD,MAAM,WAAW,0BAA0B;IACzC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAOD,eAAO,MAAM,mBAAmB,aACrB,0BAA0B,KAClC,eAiBF,CAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview localStorage adapter — the default persistence path.
3
+ *
4
+ * Storage key: `${keyPrefix}:${id}`, default `tx-flight:default`.
5
+ * SSR-safe: when `globalThis.window === undefined`, `load` resolves
6
+ * null and `save` resolves no-op (no throw). Hydration on the client
7
+ * picks up the persisted state.
8
+ *
9
+ * The Provider debounces calls to `save` (~250ms), so the
10
+ * sync-write-on-every-keystroke concern doesn't apply here.
11
+ */
12
+ import { serialize, deserialize } from './serialize.js';
13
+ const getStorage = () => {
14
+ if (typeof globalThis.window === 'undefined')
15
+ return null;
16
+ return globalThis.window.localStorage;
17
+ };
18
+ export const localStorageAdapter = (options = {}) => {
19
+ const prefix = options.keyPrefix ?? 'tx-flight';
20
+ const keyOf = (id) => `${prefix}:${id}`;
21
+ return {
22
+ load: async (id) => {
23
+ const storage = getStorage();
24
+ if (!storage)
25
+ return null;
26
+ const raw = storage.getItem(keyOf(id));
27
+ if (raw === null)
28
+ return null;
29
+ return deserialize(raw);
30
+ },
31
+ save: async (id, txs) => {
32
+ const storage = getStorage();
33
+ if (!storage)
34
+ return;
35
+ storage.setItem(keyOf(id), serialize(txs));
36
+ },
37
+ };
38
+ };
39
+ //# sourceMappingURL=local-storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage.js","sourceRoot":"","sources":["../../src/storage/local-storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAOvD,MAAM,UAAU,GAAG,GAAmB,EAAE;IACtC,IAAI,OAAO,UAAU,CAAC,MAAM,KAAK,WAAW;QAAE,OAAO,IAAI,CAAA;IACzD,OAAO,UAAU,CAAC,MAAM,CAAC,YAAY,CAAA;AACvC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,UAAsC,EAAE,EACvB,EAAE;IACnB,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,IAAI,WAAW,CAAA;IAC/C,MAAM,KAAK,GAAG,CAAC,EAAU,EAAU,EAAE,CAAC,GAAG,MAAM,IAAI,EAAE,EAAE,CAAA;IACvD,OAAO;QACL,IAAI,EAAE,KAAK,EAAE,EAAE,EAA+B,EAAE;YAC9C,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;YAC5B,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAA;YACzB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;YACtC,IAAI,GAAG,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAA;YAC7B,OAAO,WAAW,CAAC,GAAG,CAAC,CAAA;QACzB,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAiB,EAAE;YACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;YAC5B,IAAI,CAAC,OAAO;gBAAE,OAAM;YACpB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;QAC5C,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview In-process storage adapter. Test seam; consumer-facing
3
+ * use case is "explicitly opt out of persistence."
4
+ */
5
+ import type { TxFlightStorage } from '../types.js';
6
+ export declare const memoryAdapter: () => TxFlightStorage;
7
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,eAAO,MAAM,aAAa,QAAO,eAWhC,CAAA"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview In-process storage adapter. Test seam; consumer-facing
3
+ * use case is "explicitly opt out of persistence."
4
+ */
5
+ export const memoryAdapter = () => {
6
+ const data = new Map();
7
+ return {
8
+ load: async (id) => {
9
+ const stored = data.get(id);
10
+ return stored ? [...stored] : null;
11
+ },
12
+ save: async (id, txs) => {
13
+ data.set(id, [...txs]);
14
+ },
15
+ };
16
+ };
17
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/storage/memory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,CAAC,MAAM,aAAa,GAAG,GAAoB,EAAE;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,OAAO;QACL,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACjB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;YAC3B,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACpC,CAAC;QACD,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE;YACtB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Bigint-safe JSON for TrackedTx persistence.
3
+ *
4
+ * `JSON.stringify` rejects bigints. The only bigint fields on a
5
+ * TrackedTx live under `submittedGas: { maxFeePerGas, maxPriorityFeePerGas }`,
6
+ * so the serializer narrows there. Hex-string encoding with a `0x`
7
+ * prefix matches the rest of the toolkit's wire-format convention
8
+ * (chain-source, gas-oracle).
9
+ */
10
+ import type { TrackedTx } from '@valve-tech/wallet-adapter';
11
+ export declare const serialize: (txs: readonly TrackedTx[]) => string;
12
+ export declare const deserialize: (raw: string) => TrackedTx[];
13
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/storage/serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAgB,MAAM,4BAA4B,CAAA;AAqBzE,eAAO,MAAM,SAAS,QAAS,SAAS,SAAS,EAAE,KAAG,MAMnD,CAAA;AAEH,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,SAAS,EAMlD,CAAA"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Bigint-safe JSON for TrackedTx persistence.
3
+ *
4
+ * `JSON.stringify` rejects bigints. The only bigint fields on a
5
+ * TrackedTx live under `submittedGas: { maxFeePerGas, maxPriorityFeePerGas }`,
6
+ * so the serializer narrows there. Hex-string encoding with a `0x`
7
+ * prefix matches the rest of the toolkit's wire-format convention
8
+ * (chain-source, gas-oracle).
9
+ */
10
+ const gasToWire = (gas) => ({
11
+ maxFeePerGas: '0x' + gas.maxFeePerGas.toString(16),
12
+ maxPriorityFeePerGas: '0x' + gas.maxPriorityFeePerGas.toString(16),
13
+ });
14
+ const gasFromWire = (gas) => ({
15
+ maxFeePerGas: BigInt(gas.maxFeePerGas),
16
+ maxPriorityFeePerGas: BigInt(gas.maxPriorityFeePerGas),
17
+ });
18
+ export const serialize = (txs) => JSON.stringify(txs.map(({ submittedGas, ...rest }) => ({
19
+ ...rest,
20
+ ...(submittedGas ? { submittedGas: gasToWire(submittedGas) } : {}),
21
+ })));
22
+ export const deserialize = (raw) => {
23
+ const parsed = JSON.parse(raw);
24
+ return parsed.map(({ submittedGas, ...rest }) => ({
25
+ ...rest,
26
+ ...(submittedGas ? { submittedGas: gasFromWire(submittedGas) } : {}),
27
+ }));
28
+ };
29
+ //# sourceMappingURL=serialize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.js","sourceRoot":"","sources":["../../src/storage/serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,MAAM,SAAS,GAAG,CAAC,GAAiB,EAAiB,EAAE,CAAC,CAAC;IACvD,YAAY,EAAE,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IAClD,oBAAoB,EAAE,IAAI,GAAG,GAAG,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC;CACnE,CAAC,CAAA;AAEF,MAAM,WAAW,GAAG,CAAC,GAAkB,EAAgB,EAAE,CAAC,CAAC;IACzD,YAAY,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC;IACtC,oBAAoB,EAAE,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC;CACvD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAyB,EAAU,EAAE,CAC7D,IAAI,CAAC,SAAS,CACZ,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,EAAuB,EAAE,CAAC,CAAC;IAC3D,GAAG,IAAI;IACP,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CACnE,CAAC,CAAC,CACJ,CAAA;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAAe,EAAE;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAA;IACvD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,IAAI,EAAE,EAAa,EAAE,CAAC,CAAC;QAC3D,GAAG,IAAI;QACP,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC,CAAC,CAAA;AACL,CAAC,CAAA"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview Pure reducers for the tx-flight store.
3
+ *
4
+ * Side effects (start watcher, save storage, call unsub) belong in the
5
+ * Provider. Reducers fold state changes only. The Provider invokes
6
+ * reducers with `now` parameters so timestamping is testable.
7
+ */
8
+ import type { TrackedTx } from '@valve-tech/wallet-adapter';
9
+ import type { InternalState } from '../types.js';
10
+ /**
11
+ * Insert (or overwrite) a TrackedTx and an optional watcher unsub.
12
+ *
13
+ * When overwriting a tx that previously had a watcher, the caller MUST
14
+ * call the previous watcher's unsub BEFORE invoking this reducer —
15
+ * reducers are pure and don't perform side effects. The Provider owns
16
+ * watcher lifecycle.
17
+ */
18
+ export declare const addReducer: (state: InternalState, tx: TrackedTx, watcher: (() => void) | null) => InternalState;
19
+ /**
20
+ * Patch an existing tx's fields. No-op (returns the same state
21
+ * reference) on a missing id.
22
+ *
23
+ * If the patch flips status to a terminal value and `confirmedAt` is
24
+ * not yet set, stamps `confirmedAt` to `now`. This gives `evictReducer`
25
+ * a uniform "settled at" timestamp regardless of which terminal status
26
+ * the tx ended in.
27
+ */
28
+ export declare const updateReducer: (state: InternalState, txId: string, patch: Partial<TrackedTx>, now: number) => InternalState;
29
+ /**
30
+ * Drop a tx and its watcher map entry. The Provider is responsible for
31
+ * calling the watcher's unsub BEFORE this reducer runs.
32
+ *
33
+ * No-op (returns the same state reference) on a missing id.
34
+ */
35
+ export declare const removeReducer: (state: InternalState, txId: string) => InternalState;
36
+ /**
37
+ * Two-pass eviction. Returns the same state reference when nothing
38
+ * changed.
39
+ *
40
+ * Pass 1: drop terminal entries older than `terminalRetentionMs` —
41
+ * `now - (confirmedAt ?? submittedAt) > terminalRetentionMs`.
42
+ * Pass 2: if the surviving set is still larger than `maxItems`, drop
43
+ * in priority order: terminals first (oldest first by their settled
44
+ * timestamp), then non-terminals (oldest first by submittedAt).
45
+ * Non-terminals are preserved over terminals at the same age — an
46
+ * active in-flight tx is more valuable than a settled one.
47
+ */
48
+ export declare const evictReducer: (state: InternalState, opts: {
49
+ maxItems: number;
50
+ terminalRetentionMs: number;
51
+ now: number;
52
+ }) => InternalState;
53
+ //# sourceMappingURL=reducers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducers.d.ts","sourceRoot":"","sources":["../../src/store/reducers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,4BAA4B,CAAA;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAqBhD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,UACd,aAAa,MAChB,SAAS,WACJ,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,KAC3B,aAUF,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,UACjB,aAAa,QACd,MAAM,SACL,OAAO,CAAC,SAAS,CAAC,OACpB,MAAM,KACV,aAUF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,aAAa,UACjB,aAAa,QACd,MAAM,KACX,aAOF,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,UAChB,aAAa,QACd;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,KACnE,aA0CF,CAAA"}