@valve-tech/tx-tracker 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,173 @@ this file.
6
6
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/).
8
8
 
9
+ ## [0.15.0] — 2026-05-14
10
+
11
+ ### Added
12
+
13
+ - **`CreateTxTrackerOptions.confirmationsForTerminal: number | null`**
14
+ (default `null`). When set to a positive integer, a record
15
+ transitions to terminal (`terminalAtBlockNumber` set to the current
16
+ block) the first block its `lastSeenInBlock.confirmations` reaches
17
+ the threshold. Closes the long-standing gap where a normally-mined
18
+ tx never went terminal — retention enforcement only fired on
19
+ replacement and unseen-for-N-blocks paths, so successful txs
20
+ accumulated in long-lived stores forever. Records with 5,000+
21
+ confirmations were observed in production localStorage dumps; the
22
+ new option lets consumers opt in to retire them via the normal
23
+ retention pipeline. Recommended value: `≥ reorgDepthBlocks` (default
24
+ 12) so a same-height reorg can't briefly unmine a "terminal" tx.
25
+ Validation: must be a positive integer or null/undefined; zero,
26
+ negative, and non-integer values throw at construction.
27
+ - **`TxEventConfirmedTerminal` event kind** — `{ kind: 'confirmed-terminal',
28
+ confirmations }` fires once when the threshold is reached. Consumer-
29
+ facing signal that the record is now safe to forget. Carries the
30
+ triggering confirmations count for downstream gating.
31
+ - **`TrackOptions.subscriptionId?: string`** — caller-provided stable
32
+ identifier for the persisted subscription (only meaningful when
33
+ `durable: true`). Repeated calls with the same id are idempotent.
34
+ Without an explicit id, the tracker auto-dedups by `(durable,
35
+ selector)`: a second subscribe on the same hash with `durable: true`
36
+ reuses the prior persisted entry rather than appending. Closes the
37
+ bug where React component remounts and page reloads accumulated
38
+ structurally-identical persisted entries across reloads, each
39
+ driving the same downstream fan-out N times.
40
+ - **`createLocalStorageTrackerStore({ keyPrefix, storage?, eventLogCapacity?,
41
+ cleanupLegacyPrefixes? })`** — first-party TxTrackerStore implementation
42
+ backed by `localStorage` (or any `Storage`-shaped object). Records
43
+ stored under `{keyPrefix}:{chainId}:{hash}`; eventlogs under
44
+ `{keyPrefix}:eventlog:{chainId}:{hash}`. Bigint fields round-trip
45
+ losslessly via a sentinel-tagged JSON replacer/reviver.
46
+ **`delete()` clears BOTH the record AND the eventlog** — the
47
+ canonical bug class consumer-side localStorage stores routinely got
48
+ wrong, leaving orphaned eventlogs that never expired.
49
+ `cleanupLegacyPrefixes` deletes prior-prefix keys on construction for
50
+ prefix-bump migrations. Defensive against `setItem` failures (quota
51
+ exceeded, browser disabled storage) — surfaces as a rejected promise
52
+ so the tracker's `onError` can route it cleanly.
53
+ - **`deleteKeysStartingWith(storage, prefix)`** — standalone helper for
54
+ prefix cleanup without instantiating the full store.
55
+ - **Self-healing rehydration dedup.** On `tracker.start()`,
56
+ `dedupPersistedSubscriptions` runs on the rehydrated record's
57
+ subscription list; when the count shrinks (legacy duplicates
58
+ collapsed), the cleaned record is immediately written back via
59
+ `store.put`. Defensive against legacy flat-shape entries (pre-current
60
+ `selector` nesting) — those pass through untouched rather than
61
+ crashing the dedup helper.
62
+
63
+ ### Changed
64
+
65
+ - **`runReceiptPollFallback` skips silently when `caps.ready === false`**.
66
+ Pre-v0.15, the conservative pre-probe `receiptByHash: 'unavailable'`
67
+ default tripped the "permanently unavailable" warning gate, firing
68
+ once per tracker instance even when the RPC ultimately supported the
69
+ method. The warning now waits for probe completion (`caps.ready === true`)
70
+ before deciding; pre-probe ticks no-op.
71
+ - **`TxTrackerStore.delete` docstring tightened** to make explicit that
72
+ implementations must clear ALL state associated with the hash — the
73
+ record, the eventlog, any other per-hash keys. The first-party
74
+ `createInMemoryStore` and `createLocalStorageTrackerStore` already
75
+ enforce this; consumer implementations must do the same to avoid the
76
+ orphan-eventlog leak class.
77
+
78
+ ### Notes
79
+
80
+ - The `confirmationsForTerminal` transition fires from both Path 1
81
+ (fresh inclusion at confirmations=1, relevant only when threshold=1)
82
+ and Path 2 (confirmation bump from prior block) in
83
+ `decideBlockObservation`. Terminal is anchored on the current block
84
+ (matching the existing terminal arms which all anchor on
85
+ detection-block, not origin-block) — retention math is consistent
86
+ across all four arms.
87
+ - The status-poll path's mined emit (added in v0.14) hardcodes
88
+ `confirmations: 1` and doesn't participate in the new transition.
89
+ This is correct: status-poll mined observations are one-shot per
90
+ inclusion-block; confirmation accrual happens via block-poll's
91
+ Path 2, which is where the threshold is checked.
92
+ - 40 new tests across `tracker.test.ts`, `local-storage-store.test.ts`,
93
+ and `events.test.ts`. 334 total tx-tracker tests (was 294). Coverage
94
+ remains 100/100/100/100.
95
+
96
+ ## [0.14.0] — 2026-05-14
97
+
98
+ ### Added
99
+
100
+ - **`CreateTxTrackerOptions.statusPollEveryBlocks`** — default `1`
101
+ (every block tick). Controls cadence for a new default-on per-hash
102
+ status poll via `source.getTransaction(hash)`
103
+ (`eth_getTransactionByHash`). Set `0` to disable. `2`/`3`/etc. for
104
+ less-frequent cadences on consumers tracking many hashes.
105
+ Returns are treated as authoritative for the tx's current state:
106
+ pending (no `blockHash`) emits `seen-in-mempool`; mined (with
107
+ `blockHash`) emits `seen-in-block`. Both flow through the existing
108
+ event pipeline with `source: 'receipt-poll'` (see chain-source
109
+ v0.14.0 EventSource doc widening). The path is NOT permitted to
110
+ drive reorg / vanished-from-block events (spec §12.3) — divergence
111
+ detection stays anchored on the source's block stream.
112
+ - **`TrackOptions.probeTransaction`** — per-subscription consumer
113
+ fallback called only when `source.getTransaction` returns null.
114
+ Use to consult a different RPC, multi-RPC fan-out, an indexer with
115
+ mempool support, or a commercial mempool service. First-set wins
116
+ across subscribes (mirrors `lostSignalPolicy` / `probeMined`).
117
+ - `ProbeTransaction` type exported from the package root. Function
118
+ shape `(hash: Hash) => Promise<RawTx | null>`. RawTx is the existing
119
+ chain-source primitive — consumers don't need to construct a
120
+ custom shape; whatever they get back from
121
+ `eth_getTransactionByHash` drops in directly.
122
+
123
+ ### Notes
124
+
125
+ - Motivation: `txpool_content` is gated on many public RPC gateways
126
+ (PulseChain et al), and even when available it only reflects the
127
+ polled node's local mempool — partial-visibility failures look
128
+ identical to "the tx was dropped" from the tracker's perspective.
129
+ `eth_getTransactionByHash` is universally exposed and queries the
130
+ node's indexed-tx store, so it sees txs the node has seen
131
+ referenced even if they're not currently in the local pool. Per-hash
132
+ polling is also dramatically lighter than full `txpool_content`
133
+ snapshots — one tx record vs the entire pending pool. Both
134
+ properties make per-hash status the right primitive for "is this
135
+ tx alive?" on consumer-grade RPCs.
136
+ - **Load-bearing side effect: identity priming.** The status-poll
137
+ caches `(from, nonce)` on the first pending observation. This
138
+ unblocks replacement detection for txs that were never visible in
139
+ any local mempool snapshot — `replaced-by` previously couldn't
140
+ fire because the original's identity was never cached. Critical
141
+ for chains where partial mempool visibility is the norm.
142
+ - The status-poll path is idempotent within a streak: one
143
+ `seen-in-mempool` emit per pending streak (tracked via internal
144
+ `statusPollLastEmittedKind` flag). On a pending→mined transition
145
+ the dedup flag resets, so a later pending streak (rare — e.g.
146
+ post-replacement) would re-emit cleanly.
147
+ - Cross-path duplicate handling: if `txpool_content` snapshots ARE
148
+ available AND status-poll is also running, both paths can emit
149
+ `seen-in-mempool` for the same observation. Both are truthful;
150
+ consumers wanting unique delivery dedupe on `(kind, hash)` at the
151
+ edge.
152
+ - Errors on `source.getTransaction` route through `onError` but the
153
+ dispatch falls through to `probeTransaction` if one is attached —
154
+ a transiently-failing source doesn't block the consumer's fallback.
155
+ Probe errors route through `onError` and short-circuit.
156
+ - Cost characterization: with default `statusPollEveryBlocks: 1` and
157
+ a consumer tracking N hashes, the additional RPC load is N calls
158
+ per block tick. Consumers tracking >100 hashes may want
159
+ `statusPollEveryBlocks: 2` or higher; consumers on rate-limited
160
+ RPCs may want `0` (opt out entirely).
161
+ - Closures aren't serialized — durable records rehydrated from the
162
+ store start with `probeTransaction: null` until a fresh subscribe
163
+ re-binds one. Same precedent as `probeMined` and predicate
164
+ selectors (spec §13.2).
165
+ - 18 new `tracker.test.ts` cases pin the path's contract: happy
166
+ emit (mined + pending), null no-op, source-throw falls through to
167
+ probe, probe-throw routes via onError, probe-throw-no-onError
168
+ swallowed, pending idempotency, pending→mined transition resets
169
+ dedup, height-ordering block-poll-wins, identity-check rejects
170
+ orphaned mid-await emits, bad blockNumber routes via onError,
171
+ probeTransaction first-set-wins, `statusPollEveryBlocks: 0`
172
+ disables, `statusPollEveryBlocks: 3` skips ticks, defensive
173
+ identity caching when tx lacks from/nonce, identity priming
174
+ unblocks `replaced-by` for previously-invisible originals.
175
+
9
176
  ## [0.13.0] — 2026-05-12
10
177
 
11
178
  ### Added
package/dist/events.d.ts CHANGED
@@ -153,6 +153,23 @@ export interface TxEventUnseenForNBlocks extends Envelope {
153
153
  kind: 'unseen-for-N-blocks';
154
154
  blocks: number;
155
155
  }
156
+ /**
157
+ * Mined-and-confirmed terminal — fires when an included tx's
158
+ * `confirmations` reaches the `confirmationsForTerminal` threshold
159
+ * configured on the tracker. Marks the record as terminal for
160
+ * retention purposes (the existing terminal anchors are
161
+ * replacement and unseen-for-N-blocks; v0.15 closes the gap where a
162
+ * normally-mined tx never goes terminal and leaks records in
163
+ * long-lived stores). Carries the confirmations count that triggered
164
+ * the transition so consumers can gate downstream UI cleanup off the
165
+ * same event. Fires exactly once per record — the
166
+ * `terminalAtBlockNumber == null` gate on the decision arm dedups
167
+ * subsequent confirmation bumps.
168
+ */
169
+ export interface TxEventConfirmedTerminal extends Envelope {
170
+ kind: 'confirmed-terminal';
171
+ confirmations: number;
172
+ }
156
173
  /**
157
174
  * A capability the tracker had been relying on for this hash is
158
175
  * no longer authoritative — typically because the WS subscription
@@ -192,7 +209,7 @@ export interface TxEventStopped extends Envelope {
192
209
  * Discriminated union of every event variant. Narrow on `kind` to
193
210
  * access variant-specific fields.
194
211
  */
195
- export type TxEvent = TxEventStarted | TxEventSeenInMempool | TxEventLeftMempool | TxEventSeenInBlock | TxEventVanishedFromBlock | TxEventReplacedBy | TxEventUnseenForNBlocks | TxEventSignalDegraded | TxEventSignalRecovered | TxEventStopped;
212
+ export type TxEvent = TxEventStarted | TxEventSeenInMempool | TxEventLeftMempool | TxEventSeenInBlock | TxEventVanishedFromBlock | TxEventReplacedBy | TxEventUnseenForNBlocks | TxEventConfirmedTerminal | TxEventSignalDegraded | TxEventSignalRecovered | TxEventStopped;
196
213
  /**
197
214
  * `TxStatus` — cached snapshot the state machine maintains per
198
215
  * tracked hash. `getTxStatus(hash)` returns this; the iterator and
@@ -292,6 +309,10 @@ export declare const buildReplacedBy: (input: Envelope & {
292
309
  export declare const buildUnseenForNBlocks: (input: Envelope & {
293
310
  blocks: number;
294
311
  }) => TxEventUnseenForNBlocks;
312
+ /** Build a `confirmed-terminal` event. */
313
+ export declare const buildConfirmedTerminal: (input: Envelope & {
314
+ confirmations: number;
315
+ }) => TxEventConfirmedTerminal;
295
316
  /** Build a `signal-degraded` event. */
296
317
  export declare const buildSignalDegraded: (input: Envelope & {
297
318
  capabilityLost: keyof Capabilities;
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/events.js CHANGED
@@ -91,6 +91,12 @@ export const buildUnseenForNBlocks = (input) => ({
91
91
  kind: 'unseen-for-N-blocks',
92
92
  blocks: input.blocks,
93
93
  });
94
+ /** Build a `confirmed-terminal` event. */
95
+ export const buildConfirmedTerminal = (input) => ({
96
+ ...makeEnvelope(input),
97
+ kind: 'confirmed-terminal',
98
+ confirmations: input.confirmations,
99
+ });
94
100
  /** Build a `signal-degraded` event. */
95
101
  export const buildSignalDegraded = (input) => ({
96
102
  ...makeEnvelope(input),
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -40,9 +40,11 @@
40
40
  * source.stop()
41
41
  */
42
42
  export { createTxTracker } from './tracker.js';
43
- export type { CreateTxTrackerOptions, TxTracker, TrackOptions, BulkTrackOptions, TxMatchEvent, TxSubscription, LostSignalPolicy, GroupOptions, TxGroupSubscription, } from './tracker.js';
44
- export { buildStarted, buildSeenInMempool, buildLeftMempool, buildSeenInBlock, buildVanishedFromBlock, buildReplacedBy, buildUnseenForNBlocks, buildSignalDegraded, buildSignalRecovered, buildStopped, buildInitialStatus, } from './events.js';
45
- export type { Address, At, Envelope, Hash, TxEvent, TxEventStarted, TxEventSeenInMempool, TxEventLeftMempool, TxEventSeenInBlock, TxEventVanishedFromBlock, TxEventReplacedBy, TxEventUnseenForNBlocks, TxEventSignalDegraded, TxEventSignalRecovered, TxEventStopped, TxStatus, } from './events.js';
43
+ export type { CreateTxTrackerOptions, TxTracker, TrackOptions, BulkTrackOptions, TxMatchEvent, TxSubscription, LostSignalPolicy, ProbeMined, ProbeMinedResult, ProbeTransaction, GroupOptions, TxGroupSubscription, } from './tracker.js';
44
+ export { createLocalStorageTrackerStore, deleteKeysStartingWith, } from './local-storage-store.js';
45
+ export type { LocalStorageLike, LocalStorageTrackerStoreOptions, } from './local-storage-store.js';
46
+ export { buildStarted, buildSeenInMempool, buildLeftMempool, buildSeenInBlock, buildVanishedFromBlock, buildReplacedBy, buildUnseenForNBlocks, buildConfirmedTerminal, buildSignalDegraded, buildSignalRecovered, buildStopped, buildInitialStatus, } from './events.js';
47
+ export type { Address, At, Envelope, Hash, TxEvent, TxEventStarted, TxEventSeenInMempool, TxEventLeftMempool, TxEventSeenInBlock, TxEventVanishedFromBlock, TxEventReplacedBy, TxEventUnseenForNBlocks, TxEventConfirmedTerminal, TxEventSignalDegraded, TxEventSignalRecovered, TxEventStopped, TxStatus, } from './events.js';
46
48
  export { createInMemoryStore, computeRetentionExpiry, defaultRetentionBlocks, } from './store.js';
47
49
  export type { BulkSelector, HashSelector, InMemoryStoreOptions, PersistedSubscription, TrackedTxRecord, TxTrackerStore, } from './store.js';
48
50
  export { appendBlock, defaultReorgDepthBlocks, detectDivergences, } from './reorg.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EACV,sBAAsB,EACtB,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,OAAO,EACP,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE9D,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,QAAQ,GACT,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,YAAY,EACV,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,YAAY,EACV,sBAAsB,EACtB,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,GACpB,MAAM,cAAc,CAAA;AAErB,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EACV,gBAAgB,EAChB,+BAA+B,GAChC,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,OAAO,EACP,EAAE,EACF,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,cAAc,EACd,QAAQ,GACT,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AACnB,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,oBAAoB,EACpB,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE9D,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,QAAQ,GACT,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAExE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAErE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,YAAY,EACV,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAElE,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAC1B,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA;AAC7D,YAAY,EACV,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,0BAA0B,CAAA"}
package/dist/index.js CHANGED
@@ -40,7 +40,8 @@
40
40
  * source.stop()
41
41
  */
42
42
  export { createTxTracker } from './tracker.js';
43
- export { buildStarted, buildSeenInMempool, buildLeftMempool, buildSeenInBlock, buildVanishedFromBlock, buildReplacedBy, buildUnseenForNBlocks, buildSignalDegraded, buildSignalRecovered, buildStopped, buildInitialStatus, } from './events.js';
43
+ export { createLocalStorageTrackerStore, deleteKeysStartingWith, } from './local-storage-store.js';
44
+ export { buildStarted, buildSeenInMempool, buildLeftMempool, buildSeenInBlock, buildVanishedFromBlock, buildReplacedBy, buildUnseenForNBlocks, buildConfirmedTerminal, buildSignalDegraded, buildSignalRecovered, buildStopped, buildInitialStatus, } from './events.js';
44
45
  export { createInMemoryStore, computeRetentionExpiry, defaultRetentionBlocks, } from './store.js';
45
46
  export { appendBlock, defaultReorgDepthBlocks, detectDivergences, } from './reorg.js';
46
47
  export { compileSelector, defaultMaxBulkSubscriptions, matchAll, } from './selectors.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAa9C,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAA;AAoBpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAUnB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,QAAQ,GACT,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAGzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAM9D,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAU1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAgB9C,OAAO,EACL,8BAA8B,EAC9B,sBAAsB,GACvB,MAAM,0BAA0B,CAAA;AAMjC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,sBAAsB,EACtB,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,YAAY,EACZ,kBAAkB,GACnB,MAAM,aAAa,CAAA;AAqBpB,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,YAAY,CAAA;AAUnB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,QAAQ,GACT,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AAGzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAM9D,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,mBAAmB,CAAA;AAU1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * `createLocalStorageTrackerStore` — first-party `TxTrackerStore`
3
+ * implementation backed by `localStorage` (or any `Storage`-shaped
4
+ * object). Targeted at browser dApps that need durable per-hash
5
+ * subscriptions surviving page reloads but don't want to maintain
6
+ * their own custom store.
7
+ *
8
+ * Key layout (under the consumer-supplied `keyPrefix`):
9
+ *
10
+ * {keyPrefix}:{chainId}:{hash} → the TrackedTxRecord JSON
11
+ * {keyPrefix}:eventlog:{chainId}:{hash} → the per-hash event log JSON
12
+ *
13
+ * The eventlog is a separate key from the record so put/get can avoid
14
+ * paying read-and-rewrite for the (potentially-large) log on every
15
+ * status update.
16
+ *
17
+ * **`delete()` clears BOTH keys.** This is the contract the
18
+ * `TxTrackerStore.delete` docstring requires; we lock it in here so
19
+ * consumers don't accumulate orphan eventlogs when records expire
20
+ * (the canonical bug that motivated this first-party store —
21
+ * consumer-implemented localStorage stores routinely forgot to clear
22
+ * the eventlog key).
23
+ *
24
+ * Browser-safety: `localStorage` is browser-only. The factory accepts
25
+ * a `storage` override (defaults to `globalThis.localStorage`) so
26
+ * (a) tests can inject a fake and (b) consumers running in
27
+ * server-rendered contexts can supply a no-op implementation rather
28
+ * than throwing at construction.
29
+ */
30
+ import type { PersistedSubscription, TxTrackerStore } from './store.js';
31
+ /**
32
+ * Storage-shaped interface — the subset of the DOM `Storage` API the
33
+ * store needs. `localStorage` and `sessionStorage` both satisfy this;
34
+ * consumers can supply any object with the same shape (in-memory fake,
35
+ * server-rendered no-op, IndexedDB-backed polyfill, etc.).
36
+ */
37
+ export interface LocalStorageLike {
38
+ getItem(key: string): string | null;
39
+ setItem(key: string, value: string): void;
40
+ removeItem(key: string): void;
41
+ readonly length: number;
42
+ key(index: number): string | null;
43
+ }
44
+ export interface LocalStorageTrackerStoreOptions {
45
+ /**
46
+ * Namespace prefix for all keys this store writes. Required. Use
47
+ * a versioned prefix (e.g. `'myapp.tx-tracker.v1'`) and bump the
48
+ * version suffix when the persisted shape changes — the prior-
49
+ * prefix keys can then be cleaned up via `cleanupLegacyPrefixes`.
50
+ */
51
+ keyPrefix: string;
52
+ /**
53
+ * Storage backend. Defaults to `globalThis.localStorage` when
54
+ * available; throws at construction otherwise (server-rendered or
55
+ * Node contexts must supply an explicit `storage` parameter, even
56
+ * if it's a no-op).
57
+ */
58
+ storage?: LocalStorageLike;
59
+ /**
60
+ * Cap on the per-hash event log. When `appendEvent` would push the
61
+ * log past this length, the oldest entries are dropped. Default 256
62
+ * (matches `InMemoryStoreOptions.eventLogCapacity`).
63
+ */
64
+ eventLogCapacity?: number;
65
+ /**
66
+ * On construction, delete every key in `storage` that starts with
67
+ * any of these prefixes followed by `:`. Use to clean up records
68
+ * orphaned by a prior `keyPrefix` bump. Pass the OLD prefix (or
69
+ * prefixes), not the current one — passing the current one would
70
+ * wipe live state.
71
+ */
72
+ cleanupLegacyPrefixes?: string[];
73
+ }
74
+ /**
75
+ * Build a localStorage-backed `TxTrackerStore`. See module docstring
76
+ * for the key layout and serialization details.
77
+ *
78
+ * @example
79
+ * import {
80
+ * createTxTracker,
81
+ * createLocalStorageTrackerStore,
82
+ * } from '@valve-tech/tx-tracker'
83
+ *
84
+ * const store = createLocalStorageTrackerStore({
85
+ * keyPrefix: 'myapp.tx-tracker.v1',
86
+ * cleanupLegacyPrefixes: ['myapp.tx-tracker.v0'],
87
+ * })
88
+ * const tracker = createTxTracker({ source, chainId: 1, store })
89
+ */
90
+ export declare const createLocalStorageTrackerStore: (options: LocalStorageTrackerStoreOptions) => TxTrackerStore;
91
+ /**
92
+ * Delete every key in `storage` whose name starts with `prefix`.
93
+ * Exported so consumers can run prefix cleanup without instantiating
94
+ * the full store — e.g., on app boot before constructing the tracker.
95
+ */
96
+ export declare const deleteKeysStartingWith: (storage: LocalStorageLike, prefix: string) => void;
97
+ export type { PersistedSubscription };
98
+ //# sourceMappingURL=local-storage-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage-store.d.ts","sourceRoot":"","sources":["../src/local-storage-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EACV,qBAAqB,EAErB,cAAc,EACf,MAAM,YAAY,CAAA;AAEnB;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACzC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,+BAA+B;IAC9C;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAA;IAEjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAE1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;CACjC;AAwDD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,8BAA8B,GACzC,SAAS,+BAA+B,KACvC,cA2GF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,SAAS,gBAAgB,EACzB,QAAQ,MAAM,KACb,IASF,CAAA;AAMD,YAAY,EAAE,qBAAqB,EAAE,CAAA"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * `createLocalStorageTrackerStore` — first-party `TxTrackerStore`
3
+ * implementation backed by `localStorage` (or any `Storage`-shaped
4
+ * object). Targeted at browser dApps that need durable per-hash
5
+ * subscriptions surviving page reloads but don't want to maintain
6
+ * their own custom store.
7
+ *
8
+ * Key layout (under the consumer-supplied `keyPrefix`):
9
+ *
10
+ * {keyPrefix}:{chainId}:{hash} → the TrackedTxRecord JSON
11
+ * {keyPrefix}:eventlog:{chainId}:{hash} → the per-hash event log JSON
12
+ *
13
+ * The eventlog is a separate key from the record so put/get can avoid
14
+ * paying read-and-rewrite for the (potentially-large) log on every
15
+ * status update.
16
+ *
17
+ * **`delete()` clears BOTH keys.** This is the contract the
18
+ * `TxTrackerStore.delete` docstring requires; we lock it in here so
19
+ * consumers don't accumulate orphan eventlogs when records expire
20
+ * (the canonical bug that motivated this first-party store —
21
+ * consumer-implemented localStorage stores routinely forgot to clear
22
+ * the eventlog key).
23
+ *
24
+ * Browser-safety: `localStorage` is browser-only. The factory accepts
25
+ * a `storage` override (defaults to `globalThis.localStorage`) so
26
+ * (a) tests can inject a fake and (b) consumers running in
27
+ * server-rendered contexts can supply a no-op implementation rather
28
+ * than throwing at construction.
29
+ */
30
+ const DEFAULT_EVENT_LOG_CAPACITY = 256;
31
+ const recordKey = (prefix, chainId, hash) => `${prefix}:${chainId}:${hash}`;
32
+ const eventLogKey = (prefix, chainId, hash) => `${prefix}:eventlog:${chainId}:${hash}`;
33
+ /**
34
+ * JSON replacer that round-trips `bigint` losslessly. The toolkit's
35
+ * persisted shapes carry block numbers and other on-chain quantities
36
+ * as bigint; native `JSON.stringify` throws on them. We tag with a
37
+ * sentinel discriminator so the reviver can rehydrate to bigint
38
+ * without ambiguity against arbitrary user strings.
39
+ */
40
+ const SENTINEL = '$tx-tracker:bigint';
41
+ const bigintReplacer = (_key, value) => {
42
+ if (typeof value === 'bigint') {
43
+ return { [SENTINEL]: value.toString() };
44
+ }
45
+ return value;
46
+ };
47
+ const bigintReviver = (_key, value) => {
48
+ if (value !== null &&
49
+ typeof value === 'object' &&
50
+ SENTINEL in value &&
51
+ typeof value[SENTINEL] === 'string') {
52
+ try {
53
+ return BigInt(value[SENTINEL]);
54
+ }
55
+ catch {
56
+ // Malformed sentinel — fall back to the raw object; downstream
57
+ // type guards (typeof === 'bigint') will treat as missing.
58
+ return value;
59
+ }
60
+ }
61
+ return value;
62
+ };
63
+ const stringifyRecord = (value) => JSON.stringify(value, bigintReplacer);
64
+ const parseRecord = (raw) => {
65
+ if (raw === null)
66
+ return null;
67
+ try {
68
+ return JSON.parse(raw, bigintReviver);
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ };
74
+ /**
75
+ * Build a localStorage-backed `TxTrackerStore`. See module docstring
76
+ * for the key layout and serialization details.
77
+ *
78
+ * @example
79
+ * import {
80
+ * createTxTracker,
81
+ * createLocalStorageTrackerStore,
82
+ * } from '@valve-tech/tx-tracker'
83
+ *
84
+ * const store = createLocalStorageTrackerStore({
85
+ * keyPrefix: 'myapp.tx-tracker.v1',
86
+ * cleanupLegacyPrefixes: ['myapp.tx-tracker.v0'],
87
+ * })
88
+ * const tracker = createTxTracker({ source, chainId: 1, store })
89
+ */
90
+ export const createLocalStorageTrackerStore = (options) => {
91
+ const storage = options.storage ??
92
+ (typeof globalThis !== 'undefined' &&
93
+ 'localStorage' in globalThis &&
94
+ globalThis.localStorage
95
+ ? globalThis.localStorage
96
+ : null);
97
+ if (!storage) {
98
+ throw new Error('createLocalStorageTrackerStore: no `storage` supplied and globalThis.localStorage is unavailable. Pass `storage: ...` explicitly when running in a non-browser environment.');
99
+ }
100
+ if (!options.keyPrefix) {
101
+ throw new Error('createLocalStorageTrackerStore: keyPrefix is required');
102
+ }
103
+ const keyPrefix = options.keyPrefix;
104
+ const eventLogCapacity = options.eventLogCapacity ?? DEFAULT_EVENT_LOG_CAPACITY;
105
+ // Cleanup pass on construction. Skip the current prefix even if a
106
+ // consumer accidentally lists it — wiping live state mid-session
107
+ // would be the most-surprising-thing possible.
108
+ for (const legacy of options.cleanupLegacyPrefixes ?? []) {
109
+ if (!legacy || legacy === keyPrefix)
110
+ continue;
111
+ deleteKeysStartingWith(storage, `${legacy}:`);
112
+ }
113
+ return {
114
+ put: async (record) => {
115
+ storage.setItem(recordKey(keyPrefix, record.chainId, record.hash), stringifyRecord(record));
116
+ },
117
+ get: async (chainId, hash) => {
118
+ const raw = storage.getItem(recordKey(keyPrefix, chainId, hash));
119
+ return parseRecord(raw);
120
+ },
121
+ delete: async (chainId, hash) => {
122
+ // Critically: clear BOTH the record AND the eventlog. The bug
123
+ // class this fixes is the consumer-side localStorage store that
124
+ // remembered only the record key on delete, leaving the eventlog
125
+ // as a permanent orphan.
126
+ storage.removeItem(recordKey(keyPrefix, chainId, hash));
127
+ storage.removeItem(eventLogKey(keyPrefix, chainId, hash));
128
+ },
129
+ listDurable: async (chainId) => {
130
+ const prefix = `${keyPrefix}:${chainId}:`;
131
+ const result = [];
132
+ // Snapshot the keys first — mutations during iteration would
133
+ // shift the `key(i)` indexing. Browser localStorage is
134
+ // synchronous, but defensive against any Storage-shaped object
135
+ // that mutates during the iteration.
136
+ //
137
+ // Filter: record keys are `{keyPrefix}:{chainId}:{hash}`, eventlog
138
+ // keys are `{keyPrefix}:eventlog:{chainId}:{hash}`. With a numeric
139
+ // chainId the two prefixes don't overlap (`p:1:` vs `p:eventlog:`),
140
+ // so a single `startsWith(prefix)` check is enough — eventlog keys
141
+ // can never match the record prefix.
142
+ const keys = [];
143
+ for (let i = 0; i < storage.length; i++) {
144
+ const k = storage.key(i);
145
+ if (k === null)
146
+ continue;
147
+ if (!k.startsWith(prefix))
148
+ continue;
149
+ keys.push(k);
150
+ }
151
+ for (const k of keys) {
152
+ const record = parseRecord(storage.getItem(k));
153
+ if (!record)
154
+ continue;
155
+ if (record.chainId !== chainId)
156
+ continue;
157
+ if (record.subscriptions.some((sub) => sub.durable)) {
158
+ result.push(record);
159
+ }
160
+ }
161
+ return result;
162
+ },
163
+ appendEvent: async (chainId, hash, event) => {
164
+ // Async so a `storage.setItem` throw (quota exceeded, browser
165
+ // disabled storage, private-mode constraints) surfaces as a
166
+ // rejected promise rather than a synchronous throw — the tracker
167
+ // routes store errors through `onError` and never lets them
168
+ // halt the live emit fanout (spec Appendix A).
169
+ const key = eventLogKey(keyPrefix, chainId, hash);
170
+ const existing = parseRecord(storage.getItem(key)) ?? [];
171
+ existing.push(event);
172
+ // Drop oldest entries when the log exceeds the cap. Slicing
173
+ // from the tail keeps the most-recent window — the audit-trail
174
+ // pattern indexers expect.
175
+ const trimmed = existing.length > eventLogCapacity
176
+ ? existing.slice(existing.length - eventLogCapacity)
177
+ : existing;
178
+ storage.setItem(key, stringifyRecord(trimmed));
179
+ },
180
+ readEventLog: async (chainId, hash, since) => {
181
+ const key = eventLogKey(keyPrefix, chainId, hash);
182
+ const raw = storage.getItem(key);
183
+ const events = parseRecord(raw) ?? [];
184
+ if (since === undefined)
185
+ return events;
186
+ return events.filter((e) => e.at.blockNumber >= since);
187
+ },
188
+ };
189
+ };
190
+ /**
191
+ * Delete every key in `storage` whose name starts with `prefix`.
192
+ * Exported so consumers can run prefix cleanup without instantiating
193
+ * the full store — e.g., on app boot before constructing the tracker.
194
+ */
195
+ export const deleteKeysStartingWith = (storage, prefix) => {
196
+ if (!prefix)
197
+ return;
198
+ // Snapshot keys first; removing during iteration shifts indexing.
199
+ const matched = [];
200
+ for (let i = 0; i < storage.length; i++) {
201
+ const k = storage.key(i);
202
+ if (k !== null && k.startsWith(prefix))
203
+ matched.push(k);
204
+ }
205
+ for (const k of matched)
206
+ storage.removeItem(k);
207
+ };
208
+ //# sourceMappingURL=local-storage-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-storage-store.js","sourceRoot":"","sources":["../src/local-storage-store.ts"],"names":[],"mappings":"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"}