@formo/analytics 1.35.2 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/FormoAnalytics.d.ts +79 -363
- package/dist/cjs/src/FormoAnalytics.js +368 -2234
- package/dist/cjs/src/event/EventManager.d.ts +3 -1
- package/dist/cjs/src/event/EventManager.js +5 -1
- package/dist/cjs/src/event/type.d.ts +1 -0
- package/dist/cjs/src/evm/EvmEventTracker.d.ts +175 -0
- package/dist/cjs/src/evm/EvmEventTracker.js +1030 -0
- package/dist/cjs/src/evm/EvmProviderRegistry.d.ts +132 -0
- package/dist/cjs/src/evm/EvmProviderRegistry.js +348 -0
- package/dist/cjs/src/evm/EvmRequestTracker.d.ts +120 -0
- package/dist/cjs/src/evm/EvmRequestTracker.js +756 -0
- package/dist/cjs/src/queue/EventQueue.d.ts +28 -0
- package/dist/cjs/src/queue/EventQueue.js +97 -19
- package/dist/cjs/src/queue/type.d.ts +1 -0
- package/dist/cjs/src/tracking/TrackingPolicy.d.ts +146 -0
- package/dist/cjs/src/tracking/TrackingPolicy.js +200 -0
- package/dist/cjs/src/validators/address.d.ts +1 -1
- package/dist/cjs/src/version.d.ts +1 -1
- package/dist/cjs/src/version.js +1 -1
- package/dist/cjs/src/wallet/WalletStateStore.d.ts +223 -0
- package/dist/cjs/src/wallet/WalletStateStore.js +515 -0
- package/dist/esm/src/FormoAnalytics.d.ts +79 -363
- package/dist/esm/src/FormoAnalytics.js +369 -2235
- package/dist/esm/src/event/EventManager.d.ts +3 -1
- package/dist/esm/src/event/EventManager.js +5 -1
- package/dist/esm/src/event/type.d.ts +1 -0
- package/dist/esm/src/evm/EvmEventTracker.d.ts +175 -0
- package/dist/esm/src/evm/EvmEventTracker.js +1027 -0
- package/dist/esm/src/evm/EvmProviderRegistry.d.ts +132 -0
- package/dist/esm/src/evm/EvmProviderRegistry.js +345 -0
- package/dist/esm/src/evm/EvmRequestTracker.d.ts +120 -0
- package/dist/esm/src/evm/EvmRequestTracker.js +753 -0
- package/dist/esm/src/queue/EventQueue.d.ts +28 -0
- package/dist/esm/src/queue/EventQueue.js +97 -19
- package/dist/esm/src/queue/type.d.ts +1 -0
- package/dist/esm/src/tracking/TrackingPolicy.d.ts +146 -0
- package/dist/esm/src/tracking/TrackingPolicy.js +197 -0
- package/dist/esm/src/version.d.ts +1 -1
- package/dist/esm/src/version.js +1 -1
- package/dist/esm/src/wallet/WalletStateStore.d.ts +223 -0
- package/dist/esm/src/wallet/WalletStateStore.js +512 -0
- package/dist/index.umd.min.js +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { Address, ChainID, ChainNamespace, EIP1193Provider } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* A ticket identifying one wallet observation, taken before any async work.
|
|
4
|
+
* See `WalletStateStore.observe`.
|
|
5
|
+
*/
|
|
6
|
+
export interface Observation {
|
|
7
|
+
readonly id: number;
|
|
8
|
+
readonly namespace: ChainNamespace;
|
|
9
|
+
}
|
|
10
|
+
/** What the store needs from the SDK that owns it. */
|
|
11
|
+
export interface WalletStateStoreDeps {
|
|
12
|
+
/** Opt-out or an excluded timezone: purge persisted identity, don't keep it. */
|
|
13
|
+
isPersistedIdentityPurgeRequired(): boolean;
|
|
14
|
+
/** Excluded host or path: skip writing and restoring, but keep the cookie. */
|
|
15
|
+
isPageExcluded(): boolean;
|
|
16
|
+
/** Any visitor-level or page-level suppression: never LEARN a wallet. */
|
|
17
|
+
isTrackingSuppressed(): boolean;
|
|
18
|
+
/** Whether the identity cookie is shared across subdomains. */
|
|
19
|
+
crossSubdomainCookies(): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* The last chain heard from a provider, or undefined if none.
|
|
22
|
+
*
|
|
23
|
+
* Used to refuse a captured chain the wallet has since left. That state
|
|
24
|
+
* belongs to provider tracking, so the store asks rather than owns it.
|
|
25
|
+
*/
|
|
26
|
+
providerChainId(provider: EIP1193Provider): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* A provider stopped being the active one.
|
|
29
|
+
*
|
|
30
|
+
* From the SDK's point of view its connection has ended, so whatever the
|
|
31
|
+
* owner records about it (a reported connect, for one) must stop counting.
|
|
32
|
+
* The active provider is reassigned from several paths, so the store
|
|
33
|
+
* reports it centrally rather than each caller remembering to.
|
|
34
|
+
*/
|
|
35
|
+
onProviderDisplaced(previous: EIP1193Provider): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Wallet identity and chain state, and the cookie that outlives the page.
|
|
39
|
+
*
|
|
40
|
+
* Split out of `FormoAnalytics` so there is one owner for "which wallet is
|
|
41
|
+
* active, on which chain". Before this, `_chainState`, the derived
|
|
42
|
+
* `currentAddress`/`currentChainId`, the active-wallet cookie and the session
|
|
43
|
+
* generation were manipulated from a dozen places across a 3400-line class,
|
|
44
|
+
* which is what made the ordering races in #341 possible to write.
|
|
45
|
+
*/
|
|
46
|
+
export declare class WalletStateStore {
|
|
47
|
+
private readonly deps;
|
|
48
|
+
private state;
|
|
49
|
+
/**
|
|
50
|
+
* Which namespace last claimed the wallet slot. Last-connected wins, so an
|
|
51
|
+
* EVM connect after a Solana one repoints the derived values, and vice
|
|
52
|
+
* versa, rather than one namespace permanently shadowing the other.
|
|
53
|
+
*/
|
|
54
|
+
private _activeNamespace?;
|
|
55
|
+
/** Which namespace currently owns the derived values, if any. */
|
|
56
|
+
get activeNamespace(): ChainNamespace | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Ticket counter for wallet observations.
|
|
59
|
+
*
|
|
60
|
+
* Every signal from a wallet is handled asynchronously: resolving an
|
|
61
|
+
* address, emitting an event. Between the moment a handler decides what to
|
|
62
|
+
* do and the moment it commits, a newer signal can arrive and be fully
|
|
63
|
+
* processed. Whichever handler resumes last then writes its captured data
|
|
64
|
+
* over the newer state.
|
|
65
|
+
*
|
|
66
|
+
* Bespoke guards were added for each case as it was found - a per-provider
|
|
67
|
+
* disconnect count, a per-namespace session generation, a "currently
|
|
68
|
+
* processing" flag - and a fourth review round kept producing new ones,
|
|
69
|
+
* because each guard answers one question and none establishes an order.
|
|
70
|
+
*
|
|
71
|
+
* A ticket does. A handler takes one before its first await; anything it
|
|
72
|
+
* commits afterwards is refused if a newer observation has claimed the
|
|
73
|
+
* namespace since.
|
|
74
|
+
*/
|
|
75
|
+
private observationSeq;
|
|
76
|
+
private newestObservation;
|
|
77
|
+
/**
|
|
78
|
+
* How many disconnects a namespace has begun.
|
|
79
|
+
*
|
|
80
|
+
* Separate from the observation ticket on purpose, because they answer
|
|
81
|
+
* different questions. A ticket asks "is the state I captured still the
|
|
82
|
+
* newest?", which is what a switch or a probe needs. This asks "did the
|
|
83
|
+
* wallet go away after I started?", which is what a connect handler needs.
|
|
84
|
+
*
|
|
85
|
+
* Conflating them loses connects: a connect observation superseded by a
|
|
86
|
+
* NEWER connect must still be reported by somebody, and the ticket cannot
|
|
87
|
+
* tell that apart from being superseded by a disconnect.
|
|
88
|
+
*/
|
|
89
|
+
private disconnectCount;
|
|
90
|
+
/** Derived from the active namespace. Read by integrations and by events. */
|
|
91
|
+
address?: Address;
|
|
92
|
+
chainId?: ChainID;
|
|
93
|
+
constructor(deps: WalletStateStoreDeps);
|
|
94
|
+
/** Which namespace a chain id belongs to. */
|
|
95
|
+
namespaceOf(chainId?: ChainID): ChainNamespace;
|
|
96
|
+
get evmAddress(): Address | undefined;
|
|
97
|
+
get evmChainId(): ChainID | undefined;
|
|
98
|
+
get provider(): EIP1193Provider | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* Take a ticket for an observation about to be processed.
|
|
101
|
+
*
|
|
102
|
+
* MUST be called before the handler's first await, so the order recorded is
|
|
103
|
+
* the order the signals arrived in, not the order their async work happens
|
|
104
|
+
* to finish in.
|
|
105
|
+
*/
|
|
106
|
+
observe(namespace: ChainNamespace): Observation;
|
|
107
|
+
/**
|
|
108
|
+
* Record that a namespace's wallet is being torn down.
|
|
109
|
+
*
|
|
110
|
+
* Called at EVERY teardown site before anything is awaited, and whether or
|
|
111
|
+
* not a disconnect event will be emitted: whether the app opted into
|
|
112
|
+
* disconnect autocapture has no bearing on ordering.
|
|
113
|
+
*/
|
|
114
|
+
beginDisconnect(namespace: ChainNamespace): void;
|
|
115
|
+
/** How many disconnects this namespace has begun so far. */
|
|
116
|
+
disconnectsSoFar(namespace: ChainNamespace): number;
|
|
117
|
+
/**
|
|
118
|
+
* The newest observation for a namespace, for a caller that must NOT
|
|
119
|
+
* supersede its own caller.
|
|
120
|
+
*
|
|
121
|
+
* `disconnect()` is reached both directly by a consumer and from a handler
|
|
122
|
+
* that already holds a ticket. Taking a fresh ticket there would invalidate
|
|
123
|
+
* the handler that called it. Reading the current value and checking it
|
|
124
|
+
* later asks the same question without changing the answer for anyone else.
|
|
125
|
+
*/
|
|
126
|
+
snapshot(namespace: ChainNamespace): number;
|
|
127
|
+
/** Whether nothing newer has claimed the namespace since `snapshot`. */
|
|
128
|
+
isUnchangedSince(namespace: ChainNamespace, snapshot: number): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* The current newest observation, as a ticket, WITHOUT taking a new one.
|
|
131
|
+
*
|
|
132
|
+
* For a handler that must respect the order but has nothing to claim: it
|
|
133
|
+
* still abandons its work if something newer arrives, but it does not
|
|
134
|
+
* supersede whatever is already in flight.
|
|
135
|
+
*/
|
|
136
|
+
currentObservation(namespace: ChainNamespace): Observation;
|
|
137
|
+
/**
|
|
138
|
+
* Whether this observation is still the newest for its namespace.
|
|
139
|
+
*
|
|
140
|
+
* False means a newer signal arrived while this handler was suspended, and
|
|
141
|
+
* it must abandon whatever it captured rather than write it over the newer
|
|
142
|
+
* state. Superseding, not dropping: the newer handler is already running.
|
|
143
|
+
*/
|
|
144
|
+
isCurrent(observation: Observation): boolean;
|
|
145
|
+
set provider(next: EIP1193Provider | undefined);
|
|
146
|
+
/**
|
|
147
|
+
* Update a namespace and re-derive `address`/`chainId`.
|
|
148
|
+
*
|
|
149
|
+
* Accepts a namespace or a chain id. A chain id is also stored as the
|
|
150
|
+
* namespace's chain unless the update names one explicitly.
|
|
151
|
+
*/
|
|
152
|
+
set(namespaceOrChainId: ChainNamespace | ChainID | undefined, update: {
|
|
153
|
+
address?: Address;
|
|
154
|
+
chainId?: ChainID;
|
|
155
|
+
provider?: EIP1193Provider;
|
|
156
|
+
}): void;
|
|
157
|
+
/** Wipe a namespace. Per-namespace so a Solana disconnect spares EVM. */
|
|
158
|
+
clear(namespaceOrChainId: ChainNamespace | ChainID | undefined): void;
|
|
159
|
+
/** Both namespaces, keeping the EVM provider so tracking can resume. */
|
|
160
|
+
reset(): void;
|
|
161
|
+
/** Drop the active provider without touching identity. */
|
|
162
|
+
clearProvider(): void;
|
|
163
|
+
/**
|
|
164
|
+
* Repoint the active identity at a wallet, as `identify(setActive)` does,
|
|
165
|
+
* without disturbing per-namespace chain state.
|
|
166
|
+
*
|
|
167
|
+
* Deliberately transient. The next wallet event for either namespace
|
|
168
|
+
* re-derives from namespace state and replaces this, which is the intended
|
|
169
|
+
* order: a wallet that actually connects outranks one merely named by
|
|
170
|
+
* `identify()`. The alternative, making an identify sticky until another
|
|
171
|
+
* identify, would silently mis-attribute every event after a connect.
|
|
172
|
+
*/
|
|
173
|
+
setActiveAddress(address: Address | undefined): void;
|
|
174
|
+
/** Repoint (or forget) the derived chain while keeping the wallet. */
|
|
175
|
+
setActiveChainId(chainId: ChainID | undefined): void;
|
|
176
|
+
/** Forget the derived chain while keeping the wallet. */
|
|
177
|
+
clearActiveChainId(): void;
|
|
178
|
+
/**
|
|
179
|
+
* Record validated wallet/chain state WITHOUT emitting an event.
|
|
180
|
+
*
|
|
181
|
+
* Integrations (the wagmi handler among them) must call this on every
|
|
182
|
+
* connect / chain change / disconnect, even when the matching autocapture
|
|
183
|
+
* event is disabled. Otherwise `chainId` stays stale and the exclusion gate,
|
|
184
|
+
* which keys off it rather than the event payload, can be bypassed.
|
|
185
|
+
*/
|
|
186
|
+
syncWalletState(params: {
|
|
187
|
+
chainId?: ChainID;
|
|
188
|
+
address?: Address;
|
|
189
|
+
}): void;
|
|
190
|
+
/**
|
|
191
|
+
* Learn an EVM wallet observed on an autocaptured signature or transaction,
|
|
192
|
+
* when nothing is known yet.
|
|
193
|
+
*
|
|
194
|
+
* Deliberately conservative: it never overwrites a different wallet, and it
|
|
195
|
+
* corrects only a stale chain for the wallet already known.
|
|
196
|
+
*/
|
|
197
|
+
backfill(address: Address, chainId?: ChainID, provider?: EIP1193Provider): void;
|
|
198
|
+
/**
|
|
199
|
+
* Apply an EVM connect/switch seen while tracking is suppressed: never
|
|
200
|
+
* learn the wallet, but if it is a switch away from one already learned,
|
|
201
|
+
* drop the stale one so it cannot attach to a later allowed-page event.
|
|
202
|
+
*/
|
|
203
|
+
clearStaleEvmWalletOnSwitchWhileSuppressed(address: string): void;
|
|
204
|
+
/**
|
|
205
|
+
* Persist (or clear) the wallet snapshot, so the next page load can
|
|
206
|
+
* repopulate identity before the wallet reconnects. Without it, every
|
|
207
|
+
* `track()` / `page()` between page-show and reconnection ships with no
|
|
208
|
+
* address.
|
|
209
|
+
*/
|
|
210
|
+
persist(): void;
|
|
211
|
+
/** Seed identity from the persisted snapshot, once, during construction. */
|
|
212
|
+
load(): void;
|
|
213
|
+
private clearForChain;
|
|
214
|
+
private displaceProvider;
|
|
215
|
+
/**
|
|
216
|
+
* Re-derive `address`/`chainId` from the active namespace.
|
|
217
|
+
*
|
|
218
|
+
* Last-connected wins, then fall through to the other namespace so a
|
|
219
|
+
* still-connected wallet keeps attribution when its neighbour disconnects.
|
|
220
|
+
*/
|
|
221
|
+
private syncDerived;
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=WalletStateStore.d.ts.map
|