@meshconnect/uwc-core 1.0.3 → 1.1.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/README.md +247 -76
- package/dist/events.d.ts +241 -5
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +77 -1
- package/dist/events.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/logger/create-logger.d.ts +32 -0
- package/dist/logger/create-logger.d.ts.map +1 -0
- package/dist/logger/create-logger.js +79 -0
- package/dist/logger/create-logger.js.map +1 -0
- package/dist/managers/event-manager.d.ts.map +1 -1
- package/dist/managers/event-manager.js +5 -1
- package/dist/managers/event-manager.js.map +1 -1
- package/dist/observability/connect-observer.d.ts +33 -0
- package/dist/observability/connect-observer.d.ts.map +1 -0
- package/dist/observability/connect-observer.js +115 -0
- package/dist/observability/connect-observer.js.map +1 -0
- package/dist/observability/focus-tracker.d.ts +42 -0
- package/dist/observability/focus-tracker.d.ts.map +1 -0
- package/dist/observability/focus-tracker.js +57 -0
- package/dist/observability/focus-tracker.js.map +1 -0
- package/dist/observability/instrument-handoff.d.ts +54 -0
- package/dist/observability/instrument-handoff.d.ts.map +1 -0
- package/dist/observability/instrument-handoff.js +173 -0
- package/dist/observability/instrument-handoff.js.map +1 -0
- package/dist/observability/lifecycle-bridge.d.ts +69 -0
- package/dist/observability/lifecycle-bridge.d.ts.map +1 -0
- package/dist/observability/lifecycle-bridge.js +155 -0
- package/dist/observability/lifecycle-bridge.js.map +1 -0
- package/dist/observability/scrub.d.ts +31 -0
- package/dist/observability/scrub.d.ts.map +1 -0
- package/dist/observability/scrub.js +167 -0
- package/dist/observability/scrub.js.map +1 -0
- package/dist/observability/telemetry.d.ts +157 -0
- package/dist/observability/telemetry.d.ts.map +1 -0
- package/dist/observability/telemetry.js +373 -0
- package/dist/observability/telemetry.js.map +1 -0
- package/dist/services/connection-service.d.ts +23 -1
- package/dist/services/connection-service.d.ts.map +1 -1
- package/dist/services/connection-service.js +128 -19
- package/dist/services/connection-service.js.map +1 -1
- package/dist/services/network-switch-service.d.ts +2 -1
- package/dist/services/network-switch-service.d.ts.map +1 -1
- package/dist/services/network-switch-service.js +45 -16
- package/dist/services/network-switch-service.js.map +1 -1
- package/dist/services/signature-service.d.ts +14 -7
- package/dist/services/signature-service.d.ts.map +1 -1
- package/dist/services/signature-service.js +56 -58
- package/dist/services/signature-service.js.map +1 -1
- package/dist/services/transaction-service.d.ts +19 -5
- package/dist/services/transaction-service.d.ts.map +1 -1
- package/dist/services/transaction-service.js +55 -38
- package/dist/services/transaction-service.js.map +1 -1
- package/dist/universal-wallet-connector.d.ts +56 -1
- package/dist/universal-wallet-connector.d.ts.map +1 -1
- package/dist/universal-wallet-connector.js +207 -110
- package/dist/universal-wallet-connector.js.map +1 -1
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +41 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/resolve-session-provider.d.ts +10 -0
- package/dist/utils/resolve-session-provider.d.ts.map +1 -0
- package/dist/utils/resolve-session-provider.js +21 -0
- package/dist/utils/resolve-session-provider.js.map +1 -0
- package/dist/utils/to-wallet-error.d.ts +35 -0
- package/dist/utils/to-wallet-error.d.ts.map +1 -0
- package/dist/utils/to-wallet-error.js +130 -0
- package/dist/utils/to-wallet-error.js.map +1 -0
- package/dist/utils/validate-wallet-session.d.ts +15 -0
- package/dist/utils/validate-wallet-session.d.ts.map +1 -0
- package/dist/utils/validate-wallet-session.js +29 -0
- package/dist/utils/validate-wallet-session.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -6
- package/src/events.ts +326 -14
- package/src/index.ts +10 -0
- package/src/logger/create-logger.test.ts +126 -0
- package/src/logger/create-logger.ts +112 -0
- package/src/managers/event-manager.test.ts +55 -0
- package/src/managers/event-manager.ts +5 -1
- package/src/observability/connect-observer.test.ts +214 -0
- package/src/observability/connect-observer.ts +128 -0
- package/src/observability/focus-tracker.test.ts +191 -0
- package/src/observability/focus-tracker.ts +96 -0
- package/src/observability/instrument-handoff.test.ts +397 -0
- package/src/observability/instrument-handoff.ts +231 -0
- package/src/observability/lifecycle-bridge.test.ts +398 -0
- package/src/observability/lifecycle-bridge.ts +216 -0
- package/src/observability/scrub.test.ts +183 -0
- package/src/observability/scrub.ts +174 -0
- package/src/observability/telemetry.test.ts +549 -0
- package/src/observability/telemetry.ts +546 -0
- package/src/services/connection-service.test.ts +261 -1
- package/src/services/connection-service.ts +167 -38
- package/src/services/network-switch-service.test.ts +51 -1
- package/src/services/network-switch-service.ts +56 -24
- package/src/services/signature-service.test.ts +181 -76
- package/src/services/signature-service.ts +75 -85
- package/src/services/transaction-service.test.ts +270 -69
- package/src/services/transaction-service.ts +74 -51
- package/src/universal-wallet-connector.instrumentation-guard.test.ts +199 -0
- package/src/universal-wallet-connector.observability.test.ts +610 -0
- package/src/universal-wallet-connector.test.ts +27 -146
- package/src/universal-wallet-connector.ts +279 -142
- package/src/utils/id.test.ts +15 -0
- package/src/utils/id.ts +48 -0
- package/src/utils/resolve-session-provider.test.ts +54 -0
- package/src/utils/resolve-session-provider.ts +25 -0
- package/src/utils/to-wallet-error.test.ts +181 -0
- package/src/utils/to-wallet-error.ts +152 -0
- package/src/utils/validate-wallet-session.test.ts +77 -0
- package/src/utils/validate-wallet-session.ts +40 -0
- package/src/version.test.ts +11 -0
- package/src/version.ts +2 -0
package/dist/events.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { Session, Network, WalletMetadata, ConnectionMode, WalletError, EVMCapabilities } from '@meshconnect/uwc-types';
|
|
1
|
+
import type { Session, Network, WalletMetadata, ConnectionMode, WalletError, EVMCapabilities, LogLevel, WalletFlowType, Platform, Namespace, NetworkId, FailureKind, ErrorSource, LifecycleUnavailableReason } from '@meshconnect/uwc-types';
|
|
2
2
|
/**
|
|
3
|
-
* User-initiated operations that can surface through the `error` event.
|
|
3
|
+
* User-initiated operations that can surface through the `error` event. The
|
|
4
|
+
* runtime tuple is the single source of truth; the type is derived from it so a
|
|
5
|
+
* guard test can enumerate every op — and catch a new one added without handoff
|
|
6
|
+
* instrumentation — instead of relying on a hand-maintained list.
|
|
4
7
|
*/
|
|
5
|
-
export
|
|
8
|
+
export declare const UWC_OPERATIONS: readonly ["connect", "disconnect", "switchNetwork", "signMessage", "signTypedData", "sendTransaction", "signSolanaTransaction", "getWalletCapabilities", "initialize"];
|
|
9
|
+
export type UWCOperation = (typeof UWC_OPERATIONS)[number];
|
|
6
10
|
/**
|
|
7
11
|
* Typed event map emitted by UniversalWalletConnector.
|
|
8
12
|
*
|
|
@@ -15,9 +19,51 @@ export type UWCOperation = 'connect' | 'disconnect' | 'switchNetwork' | 'signMes
|
|
|
15
19
|
export interface UWCEventMap {
|
|
16
20
|
/** Wallet detection finished; `getWallets()` now reflects which are installed. */
|
|
17
21
|
ready: void;
|
|
18
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Emitted once detection finishes, with the final wallet list. `discovery` is a
|
|
24
|
+
* per-namespace requested-vs-matched summary (telemetry-only, non-PII counts) so
|
|
25
|
+
* "we asked for N solana wallets, matched 0" is distinguishable from "asked for
|
|
26
|
+
* none" — answers "why didn't wallet X appear?".
|
|
27
|
+
*/
|
|
19
28
|
walletsDetected: {
|
|
20
29
|
wallets: WalletMetadata[];
|
|
30
|
+
discovery?: Record<string, {
|
|
31
|
+
requested: number;
|
|
32
|
+
matched: number;
|
|
33
|
+
}> | undefined;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* A single namespace × connector discovery task threw. Telemetry-only — replaces
|
|
37
|
+
* the historical silent catch so a discovery failure is observable rather than
|
|
38
|
+
* vanishing. Carries the namespace + connection mode + scrubbed error; never an
|
|
39
|
+
* address or payload.
|
|
40
|
+
*/
|
|
41
|
+
walletDiscoveryFailed: {
|
|
42
|
+
namespace: Namespace;
|
|
43
|
+
connectionMode: ConnectionMode;
|
|
44
|
+
error: WalletError;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* A bridge operation failed — e.g. wallet-discovery marshaling across the iframe
|
|
48
|
+
* Comlink boundary timed out or threw. Telemetry-only; replaces silent catches in
|
|
49
|
+
* `BridgeChild` so "the wallet never showed up via the bridge" (the Bitstarz
|
|
50
|
+
* class) is observable. Carries the namespace + scrubbed error; no address /
|
|
51
|
+
* payload. Deduped + benign poll-misses excluded at the source.
|
|
52
|
+
*/
|
|
53
|
+
bridgeError: {
|
|
54
|
+
namespace?: Namespace | undefined;
|
|
55
|
+
error: WalletError;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The WalletConnect relay socket surfaced a transport/provider error — e.g. an
|
|
59
|
+
* abnormal close (code 3000 "JWT Token is not yet valid" when the device clock is
|
|
60
|
+
* skewed past the relay's 120s leeway). Emitted from the relayer's error event,
|
|
61
|
+
* deduped at the connector. This failure is detached from the connect() promise,
|
|
62
|
+
* so without it the error escapes the handoff funnel entirely. Telemetry-only;
|
|
63
|
+
* carries only a scrubbed message (no address / payload).
|
|
64
|
+
*/
|
|
65
|
+
relayError: {
|
|
66
|
+
error: WalletError;
|
|
21
67
|
};
|
|
22
68
|
/** `connect()` has started. */
|
|
23
69
|
connecting: {
|
|
@@ -55,10 +101,193 @@ export interface UWCEventMap {
|
|
|
55
101
|
capabilitiesUpdated: {
|
|
56
102
|
capabilities: Record<string, EVMCapabilities>;
|
|
57
103
|
};
|
|
58
|
-
/**
|
|
104
|
+
/**
|
|
105
|
+
* A user-initiated operation failed. Carries optional, telemetry-only
|
|
106
|
+
* classification (`errorCode` / `failureKind` / `source`) and, for a
|
|
107
|
+
* no-common-network connect failure, the two CAIP-2 id lists — so a PRE-wallet
|
|
108
|
+
* validation failure (which never enters the handoff funnel) is still
|
|
109
|
+
* diagnosable. The React-facing payload is still `{ error, operation }`; the
|
|
110
|
+
* rest is `undefined` for ordinary errors.
|
|
111
|
+
*/
|
|
59
112
|
error: {
|
|
60
113
|
error: WalletError;
|
|
61
114
|
operation: UWCOperation;
|
|
115
|
+
errorCode?: string | undefined;
|
|
116
|
+
failureKind?: FailureKind | undefined;
|
|
117
|
+
source?: ErrorSource | undefined;
|
|
118
|
+
networkMismatch?: {
|
|
119
|
+
walletNetworkIds: string[];
|
|
120
|
+
configuredNetworkIds: string[];
|
|
121
|
+
} | undefined;
|
|
122
|
+
/**
|
|
123
|
+
* `true` when a handoff terminal (`walletRejected`/`walletFailed`) already
|
|
124
|
+
* reported this same failure — this record is the back-compat duplicate.
|
|
125
|
+
* For failure metrics: count terminals + `error` where NOT handoffCovered;
|
|
126
|
+
* absent on pre-wallet validation failures (which have no terminal).
|
|
127
|
+
*/
|
|
128
|
+
handoffCovered?: boolean | undefined;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* A line emitted through the internal `Logger`. Fires for ALL levels regardless
|
|
132
|
+
* of the console threshold so an observer can capture `debug`/`info` even when
|
|
133
|
+
* the console is quiet. `args` is scrubbed before reaching `observer.onLog`.
|
|
134
|
+
*/
|
|
135
|
+
log: {
|
|
136
|
+
level: LogLevel;
|
|
137
|
+
message: string;
|
|
138
|
+
args: unknown[];
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Emitted immediately BEFORE control is handed to the wallet for a boundary op
|
|
142
|
+
* (the moment the blind window opens). Pair with exactly one terminal event via
|
|
143
|
+
* `handoffId`. Carries no signing payload and no address — only routing facets.
|
|
144
|
+
*/
|
|
145
|
+
awaitingWallet: {
|
|
146
|
+
operation: UWCOperation;
|
|
147
|
+
connectionMode: ConnectionMode;
|
|
148
|
+
walletId?: string | undefined;
|
|
149
|
+
/** CAIP namespace (eip155 | solana | tron | tvm …) — not an address. */
|
|
150
|
+
namespace?: Namespace | undefined;
|
|
151
|
+
/** CAIP chain id (e.g. `eip155:1`) — not an address. */
|
|
152
|
+
chainId?: NetworkId | undefined;
|
|
153
|
+
handoffId: string;
|
|
154
|
+
/** Derived, best-effort flow taxonomy (heuristic — see deriveWalletFlowType). */
|
|
155
|
+
walletFlowType: WalletFlowType;
|
|
156
|
+
/** Coarse runtime surface (heuristic — see derivePlatform). */
|
|
157
|
+
platform: Platform;
|
|
158
|
+
/** switchNetwork only: target chain already the active one (no-op switch). */
|
|
159
|
+
targetAlreadyActive?: boolean | undefined;
|
|
160
|
+
};
|
|
161
|
+
/** The wallet resolved the op successfully. Closes a handoff. */
|
|
162
|
+
walletSucceeded: {
|
|
163
|
+
handoffId: string;
|
|
164
|
+
operation: UWCOperation;
|
|
165
|
+
durationMs: number;
|
|
166
|
+
connectionMode: ConnectionMode;
|
|
167
|
+
walletId?: string | undefined;
|
|
168
|
+
namespace?: Namespace | undefined;
|
|
169
|
+
chainId?: NetworkId | undefined;
|
|
170
|
+
/** A `walletTimedOut` marker fired before this terminal (late completion). */
|
|
171
|
+
timedOut: boolean;
|
|
172
|
+
/** The deadline that elapsed, present only when `timedOut`. */
|
|
173
|
+
timeoutMs?: number | undefined;
|
|
174
|
+
/** switchNetwork only: target chain already the active one (no-op switch). */
|
|
175
|
+
targetAlreadyActive?: boolean | undefined;
|
|
176
|
+
};
|
|
177
|
+
/** The user explicitly rejected (4001 / WalletError.type === 'rejected'). Closes a handoff. */
|
|
178
|
+
walletRejected: {
|
|
179
|
+
handoffId: string;
|
|
180
|
+
operation: UWCOperation;
|
|
181
|
+
durationMs: number;
|
|
182
|
+
connectionMode: ConnectionMode;
|
|
183
|
+
walletId?: string | undefined;
|
|
184
|
+
namespace?: Namespace | undefined;
|
|
185
|
+
chainId?: NetworkId | undefined;
|
|
186
|
+
timedOut: boolean;
|
|
187
|
+
timeoutMs?: number | undefined;
|
|
188
|
+
targetAlreadyActive?: boolean | undefined;
|
|
189
|
+
/** Stringified error code (EIP-1193 numeric / string), when present. */
|
|
190
|
+
errorCode?: string | undefined;
|
|
191
|
+
failureKind?: FailureKind | undefined;
|
|
192
|
+
source?: ErrorSource | undefined;
|
|
193
|
+
};
|
|
194
|
+
/** The op failed for any non-rejection reason. Closes a handoff. */
|
|
195
|
+
walletFailed: {
|
|
196
|
+
handoffId: string;
|
|
197
|
+
operation: UWCOperation;
|
|
198
|
+
durationMs: number;
|
|
199
|
+
error: WalletError;
|
|
200
|
+
connectionMode: ConnectionMode;
|
|
201
|
+
walletId?: string | undefined;
|
|
202
|
+
namespace?: Namespace | undefined;
|
|
203
|
+
chainId?: NetworkId | undefined;
|
|
204
|
+
timedOut: boolean;
|
|
205
|
+
timeoutMs?: number | undefined;
|
|
206
|
+
targetAlreadyActive?: boolean | undefined;
|
|
207
|
+
/** Stringified error code (EIP-1193 numeric / string), when present. */
|
|
208
|
+
errorCode?: string | undefined;
|
|
209
|
+
failureKind?: FailureKind | undefined;
|
|
210
|
+
source?: ErrorSource | undefined;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Side marker: the deadline passed with the op still pending. OBSERVATIONAL —
|
|
214
|
+
* it does NOT reject, abort, or mutate state; the wallet may still complete and
|
|
215
|
+
* produce the real terminal. Never fires for an op that settled before the
|
|
216
|
+
* deadline. Not itself a terminal.
|
|
217
|
+
*/
|
|
218
|
+
walletTimedOut: {
|
|
219
|
+
handoffId: string;
|
|
220
|
+
operation: UWCOperation;
|
|
221
|
+
durationMs: number;
|
|
222
|
+
connectionMode: ConnectionMode;
|
|
223
|
+
walletId?: string | undefined;
|
|
224
|
+
namespace?: Namespace | undefined;
|
|
225
|
+
chainId?: NetworkId | undefined;
|
|
226
|
+
/** The deadline that elapsed (the configured marker timeout). */
|
|
227
|
+
timeoutMs: number;
|
|
228
|
+
/** switchNetwork only: target chain already the active one (no-op switch). */
|
|
229
|
+
targetAlreadyActive?: boolean | undefined;
|
|
230
|
+
};
|
|
231
|
+
/** The wallet's active account/list changed. Signals THAT it changed, not which. */
|
|
232
|
+
walletAccountChanged: {
|
|
233
|
+
connectionMode: ConnectionMode;
|
|
234
|
+
walletId?: string | undefined;
|
|
235
|
+
namespace?: Namespace | undefined;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* The wallet switched chain on its own. Deduped against the echo of a
|
|
239
|
+
* UWC-initiated `switchNetwork` (which already surfaces via `networkSwitched`).
|
|
240
|
+
*/
|
|
241
|
+
walletChainChanged: {
|
|
242
|
+
connectionMode: ConnectionMode;
|
|
243
|
+
walletId?: string | undefined;
|
|
244
|
+
namespace?: Namespace | undefined;
|
|
245
|
+
chainId?: NetworkId | undefined;
|
|
246
|
+
};
|
|
247
|
+
/** The wallet disconnected the session from its side. */
|
|
248
|
+
walletDisconnected: {
|
|
249
|
+
connectionMode: ConnectionMode;
|
|
250
|
+
walletId?: string | undefined;
|
|
251
|
+
namespace?: Namespace | undefined;
|
|
252
|
+
};
|
|
253
|
+
/** A WalletConnect / TON session expired. */
|
|
254
|
+
walletSessionExpired: {
|
|
255
|
+
connectionMode: ConnectionMode;
|
|
256
|
+
walletId?: string | undefined;
|
|
257
|
+
namespace?: Namespace | undefined;
|
|
258
|
+
};
|
|
259
|
+
/**
|
|
260
|
+
* Lifecycle telemetry could not be attached for this connection — emitted once
|
|
261
|
+
* so analytics can tell "genuinely silent" from "never wired". Carries WHY +
|
|
262
|
+
* whether the runtime is the direct page or the production iframe.
|
|
263
|
+
*/
|
|
264
|
+
lifecycleTelemetryUnavailable: {
|
|
265
|
+
reason: LifecycleUnavailableReason;
|
|
266
|
+
connectionMode: ConnectionMode;
|
|
267
|
+
walletId?: string | undefined;
|
|
268
|
+
namespace?: Namespace | undefined;
|
|
269
|
+
runtime: 'direct' | 'iframe';
|
|
270
|
+
};
|
|
271
|
+
/**
|
|
272
|
+
* The page was backgrounded (tab hidden / app-switched) while a wallet handoff
|
|
273
|
+
* was still pending. Telemetry-only. On mobile this usually means the user
|
|
274
|
+
* left for the wallet app — a deep-link round-trip in progress, not an
|
|
275
|
+
* abandonment. UWC emits the raw FACT only; never an interpreted "abandoned".
|
|
276
|
+
*/
|
|
277
|
+
pageHiddenDuringHandoff: {
|
|
278
|
+
handoffId: string;
|
|
279
|
+
platform: Platform;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* The page became visible again (returned from the wallet / bfcache restore)
|
|
283
|
+
* while a handoff was still pending. Pairs with `pageHiddenDuringHandoff` to
|
|
284
|
+
* bracket an app-switch — consecutive same-state transitions are deduped per
|
|
285
|
+
* handoff (a bfcache restore can fire both `pageshow` and `visibilitychange`
|
|
286
|
+
* for one physical return). Telemetry-only.
|
|
287
|
+
*/
|
|
288
|
+
pageVisibleDuringHandoff: {
|
|
289
|
+
handoffId: string;
|
|
290
|
+
platform: Platform;
|
|
62
291
|
};
|
|
63
292
|
/**
|
|
64
293
|
* Back-compat catch-all. Fires after every other event above.
|
|
@@ -66,6 +295,13 @@ export interface UWCEventMap {
|
|
|
66
295
|
*/
|
|
67
296
|
change: void;
|
|
68
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Events that describe telemetry rather than a state change. `EventManager.emit`
|
|
300
|
+
* skips the legacy `change` cascade for these so high-frequency logging / handoff
|
|
301
|
+
* instrumentation can't trigger React re-renders through `subscribe()`.
|
|
302
|
+
*/
|
|
303
|
+
export declare const TELEMETRY_ONLY_EVENTS: ReadonlySet<UWCEventName>;
|
|
69
304
|
export type UWCEventName = keyof UWCEventMap;
|
|
70
305
|
export type UWCEventListener<K extends UWCEventName> = (data: UWCEventMap[K]) => void;
|
|
306
|
+
export declare const UWC_EVENT_NAMES: UWCEventName[];
|
|
71
307
|
//# sourceMappingURL=events.d.ts.map
|
package/dist/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,OAAO,EACP,OAAO,EACP,cAAc,EACd,cAAc,EACd,WAAW,EACX,eAAe,
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"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"}
|
package/dist/events.js
CHANGED
|
@@ -1,2 +1,78 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* User-initiated operations that can surface through the `error` event. The
|
|
3
|
+
* runtime tuple is the single source of truth; the type is derived from it so a
|
|
4
|
+
* guard test can enumerate every op — and catch a new one added without handoff
|
|
5
|
+
* instrumentation — instead of relying on a hand-maintained list.
|
|
6
|
+
*/
|
|
7
|
+
export const UWC_OPERATIONS = [
|
|
8
|
+
'connect',
|
|
9
|
+
'disconnect',
|
|
10
|
+
'switchNetwork',
|
|
11
|
+
'signMessage',
|
|
12
|
+
'signTypedData',
|
|
13
|
+
'sendTransaction',
|
|
14
|
+
'signSolanaTransaction',
|
|
15
|
+
'getWalletCapabilities',
|
|
16
|
+
'initialize'
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Events that describe telemetry rather than a state change. `EventManager.emit`
|
|
20
|
+
* skips the legacy `change` cascade for these so high-frequency logging / handoff
|
|
21
|
+
* instrumentation can't trigger React re-renders through `subscribe()`.
|
|
22
|
+
*/
|
|
23
|
+
export const TELEMETRY_ONLY_EVENTS = new Set([
|
|
24
|
+
'log',
|
|
25
|
+
'awaitingWallet',
|
|
26
|
+
'walletSucceeded',
|
|
27
|
+
'walletRejected',
|
|
28
|
+
'walletFailed',
|
|
29
|
+
'walletTimedOut',
|
|
30
|
+
'walletDiscoveryFailed',
|
|
31
|
+
'bridgeError',
|
|
32
|
+
'relayError',
|
|
33
|
+
'walletAccountChanged',
|
|
34
|
+
'walletChainChanged',
|
|
35
|
+
'walletDisconnected',
|
|
36
|
+
'walletSessionExpired',
|
|
37
|
+
'lifecycleTelemetryUnavailable',
|
|
38
|
+
'pageHiddenDuringHandoff',
|
|
39
|
+
'pageVisibleDuringHandoff'
|
|
40
|
+
]);
|
|
41
|
+
/**
|
|
42
|
+
* Runtime list of every event name. The `Record<UWCEventName, true>` literal
|
|
43
|
+
* forces this to stay exhaustive — adding an event to `UWCEventMap` without
|
|
44
|
+
* listing it here is a compile error — so the observer bridge can never silently
|
|
45
|
+
* drop a new event.
|
|
46
|
+
*/
|
|
47
|
+
const EVENT_NAME_FLAGS = {
|
|
48
|
+
ready: true,
|
|
49
|
+
walletsDetected: true,
|
|
50
|
+
walletDiscoveryFailed: true,
|
|
51
|
+
bridgeError: true,
|
|
52
|
+
relayError: true,
|
|
53
|
+
connecting: true,
|
|
54
|
+
connected: true,
|
|
55
|
+
disconnected: true,
|
|
56
|
+
connectionUri: true,
|
|
57
|
+
sessionChanged: true,
|
|
58
|
+
networkSwitching: true,
|
|
59
|
+
networkSwitched: true,
|
|
60
|
+
capabilitiesUpdated: true,
|
|
61
|
+
error: true,
|
|
62
|
+
log: true,
|
|
63
|
+
awaitingWallet: true,
|
|
64
|
+
walletSucceeded: true,
|
|
65
|
+
walletRejected: true,
|
|
66
|
+
walletFailed: true,
|
|
67
|
+
walletTimedOut: true,
|
|
68
|
+
walletAccountChanged: true,
|
|
69
|
+
walletChainChanged: true,
|
|
70
|
+
walletDisconnected: true,
|
|
71
|
+
walletSessionExpired: true,
|
|
72
|
+
lifecycleTelemetryUnavailable: true,
|
|
73
|
+
pageHiddenDuringHandoff: true,
|
|
74
|
+
pageVisibleDuringHandoff: true,
|
|
75
|
+
change: true
|
|
76
|
+
};
|
|
77
|
+
export const UWC_EVENT_NAMES = Object.keys(EVENT_NAME_FLAGS);
|
|
2
78
|
//# sourceMappingURL=events.js.map
|
package/dist/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAiBA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS;IACT,YAAY;IACZ,eAAe;IACf,aAAa;IACb,eAAe;IACf,iBAAiB;IACjB,uBAAuB;IACvB,uBAAuB;IACvB,YAAY;CACJ,CAAA;AA6RV;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAA8B,IAAI,GAAG,CAAC;IACtE,KAAK;IACL,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB,uBAAuB;IACvB,aAAa;IACb,YAAY;IACZ,sBAAsB;IACtB,oBAAoB;IACpB,oBAAoB;IACpB,sBAAsB;IACtB,+BAA+B;IAC/B,yBAAyB;IACzB,0BAA0B;CAC3B,CAAC,CAAA;AAOF;;;;;GAKG;AACH,MAAM,gBAAgB,GAA+B;IACnD,KAAK,EAAE,IAAI;IACX,eAAe,EAAE,IAAI;IACrB,qBAAqB,EAAE,IAAI;IAC3B,WAAW,EAAE,IAAI;IACjB,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,YAAY,EAAE,IAAI;IAClB,aAAa,EAAE,IAAI;IACnB,cAAc,EAAE,IAAI;IACpB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,mBAAmB,EAAE,IAAI;IACzB,KAAK,EAAE,IAAI;IACX,GAAG,EAAE,IAAI;IACT,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,oBAAoB,EAAE,IAAI;IAC1B,kBAAkB,EAAE,IAAI;IACxB,kBAAkB,EAAE,IAAI;IACxB,oBAAoB,EAAE,IAAI;IAC1B,6BAA6B,EAAE,IAAI;IACnC,uBAAuB,EAAE,IAAI;IAC7B,wBAAwB,EAAE,IAAI;IAC9B,MAAM,EAAE,IAAI;CACb,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAmB,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { UniversalWalletConnector, type UWCConfig, type OperationOptions } from './universal-wallet-connector';
|
|
2
2
|
export type { UWCEventMap, UWCEventName, UWCEventListener, UWCOperation } from './events';
|
|
3
|
+
export { createLogger, type ManagedLogger, type CreateLoggerOptions } from './logger/create-logger';
|
|
4
|
+
export { TELEMETRY_SCHEMA_VERSION, type UWCObserver, type UWCTelemetryEvent } from './observability/telemetry';
|
|
3
5
|
export { toBaseUnits } from './utils/to-base-units';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,KAAK,SAAS,EACd,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAA;AACrC,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,YAAY,EACb,MAAM,UAAU,CAAA;AACjB,OAAO,EACL,YAAY,EACZ,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,wBAAwB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACvB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { UniversalWalletConnector } from './universal-wallet-connector';
|
|
2
|
+
export { createLogger } from './logger/create-logger';
|
|
3
|
+
export { TELEMETRY_SCHEMA_VERSION } from './observability/telemetry';
|
|
2
4
|
export { toBaseUnits } from './utils/to-base-units';
|
|
3
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EAGzB,MAAM,8BAA8B,CAAA;AAOrC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EAGzB,MAAM,8BAA8B,CAAA;AAOrC,OAAO,EACL,YAAY,EAGb,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,wBAAwB,EAGzB,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { LogLevel, Logger } from '@meshconnect/uwc-types';
|
|
2
|
+
/** The logger returned by `createLogger`, with runtime-tunable level controls. */
|
|
3
|
+
export interface ManagedLogger extends Logger {
|
|
4
|
+
/** Lower/raise the console threshold at runtime (e.g. from a support toggle). */
|
|
5
|
+
setLevel(level: LogLevel): void;
|
|
6
|
+
/** The currently configured threshold (ignores the global override). */
|
|
7
|
+
getLevel(): LogLevel;
|
|
8
|
+
}
|
|
9
|
+
export interface CreateLoggerOptions {
|
|
10
|
+
/** Console threshold. Default `'warn'` — UWC stays quiet unless asked. */
|
|
11
|
+
level?: LogLevel | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Pre-gate tap: invoked for EVERY log line regardless of the console threshold.
|
|
14
|
+
* The observer bridge subscribes here so `debug`/`info` reach remote telemetry
|
|
15
|
+
* even when the console is silent. Throws are swallowed — a bad sink must not
|
|
16
|
+
* break a log call.
|
|
17
|
+
*/
|
|
18
|
+
onLog?: ((level: LogLevel, message: string, args: unknown[]) => void) | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Output sink for gated lines. When provided (e.g. a consumer's own logger), it
|
|
21
|
+
* receives the RAW `(message, ...args)` so it can apply its own formatting. When
|
|
22
|
+
* omitted, the default `console` sink is used with an ISO/level prefix.
|
|
23
|
+
*/
|
|
24
|
+
sink?: Logger | undefined;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Console-backed, level-gated logger. ~zero-dep. Two seams:
|
|
28
|
+
* - `onLog` fires pre-gate (all levels) → drives the observer.
|
|
29
|
+
* - the console sink fires only at/above the threshold.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createLogger(options?: CreateLoggerOptions): ManagedLogger;
|
|
32
|
+
//# sourceMappingURL=create-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-logger.d.ts","sourceRoot":"","sources":["../../src/logger/create-logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AAS9D,kFAAkF;AAClF,MAAM,WAAW,aAAc,SAAQ,MAAM;IAC3C,iFAAiF;IACjF,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC/B,wEAAwE;IACxE,QAAQ,IAAI,QAAQ,CAAA;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B;;;;;OAKG;IACH,KAAK,CAAC,EACF,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC,GAC7D,SAAS,CAAA;IACb;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC1B;AAgCD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,aAAa,CAuC7E"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const LEVEL_WEIGHT = {
|
|
2
|
+
debug: 0,
|
|
3
|
+
info: 1,
|
|
4
|
+
warn: 2,
|
|
5
|
+
error: 3
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Resolve the effective console threshold, honouring a runtime global override so
|
|
9
|
+
* an issue can be triaged in a wallet's in-app browser WITHOUT a redeploy:
|
|
10
|
+
*
|
|
11
|
+
* window.UWC_DEBUG = true // surface everything (debug)
|
|
12
|
+
* window.UWC_DEBUG = 'info' // surface info and above
|
|
13
|
+
*
|
|
14
|
+
* The override only ever LOWERS the threshold (shows more) — it can't hide logs a
|
|
15
|
+
* consumer explicitly opted into. Re-read on every call so toggling it mid-session
|
|
16
|
+
* takes effect immediately. SSR/Node-safe via the `globalThis` guard.
|
|
17
|
+
*/
|
|
18
|
+
function resolveWeight(configured) {
|
|
19
|
+
if (typeof globalThis !== 'undefined') {
|
|
20
|
+
const override = globalThis.UWC_DEBUG;
|
|
21
|
+
if (override === true)
|
|
22
|
+
return LEVEL_WEIGHT.debug;
|
|
23
|
+
// Own-property check, not `in`: the prototype chain would accept keys like
|
|
24
|
+
// 'toString', whose "weight" is a function → NaN → the gate never closes.
|
|
25
|
+
if (typeof override === 'string' &&
|
|
26
|
+
Object.prototype.hasOwnProperty.call(LEVEL_WEIGHT, override)) {
|
|
27
|
+
return Math.min(LEVEL_WEIGHT[override], LEVEL_WEIGHT[configured]);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return LEVEL_WEIGHT[configured];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Console-backed, level-gated logger. ~zero-dep. Two seams:
|
|
34
|
+
* - `onLog` fires pre-gate (all levels) → drives the observer.
|
|
35
|
+
* - the console sink fires only at/above the threshold.
|
|
36
|
+
*/
|
|
37
|
+
export function createLogger(options = {}) {
|
|
38
|
+
let configured = options.level ?? 'warn';
|
|
39
|
+
const customSink = options.sink;
|
|
40
|
+
const emit = (level, message, args) => {
|
|
41
|
+
// Pre-gate tap first — observability must not depend on the console threshold.
|
|
42
|
+
if (options.onLog) {
|
|
43
|
+
try {
|
|
44
|
+
options.onLog(level, message, args);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// A failing sink must never break the caller's log statement.
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (LEVEL_WEIGHT[level] < resolveWeight(configured))
|
|
51
|
+
return;
|
|
52
|
+
// Same contract as the `onLog` tap above: the sink (a consumer logger or the
|
|
53
|
+
// console) must never break the caller's log statement if it throws.
|
|
54
|
+
try {
|
|
55
|
+
if (customSink) {
|
|
56
|
+
customSink[level](message, ...args);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
const line = `[${new Date().toISOString()}] ${level.toUpperCase()}: ${message}`;
|
|
60
|
+
// eslint-disable-next-line no-console -- this IS the default console sink
|
|
61
|
+
console[level](line, ...args);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Swallowed by design — a broken sink is not the caller's problem.
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return {
|
|
69
|
+
debug: (message, ...args) => emit('debug', message, args),
|
|
70
|
+
info: (message, ...args) => emit('info', message, args),
|
|
71
|
+
warn: (message, ...args) => emit('warn', message, args),
|
|
72
|
+
error: (message, ...args) => emit('error', message, args),
|
|
73
|
+
setLevel: level => {
|
|
74
|
+
configured = level;
|
|
75
|
+
},
|
|
76
|
+
getLevel: () => configured
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=create-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-logger.js","sourceRoot":"","sources":["../../src/logger/create-logger.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAA6B;IAC7C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAA;AA8BD;;;;;;;;;;GAUG;AACH,SAAS,aAAa,CAAC,UAAoB;IACzC,IAAI,OAAO,UAAU,KAAK,WAAW,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAI,UAAsC,CAAC,SAAS,CAAA;QAClE,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,YAAY,CAAC,KAAK,CAAA;QAChD,2EAA2E;QAC3E,0EAA0E;QAC1E,IACE,OAAO,QAAQ,KAAK,QAAQ;YAC5B,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,EAC5D,CAAC;YACD,OAAO,IAAI,CAAC,GAAG,CACb,YAAY,CAAC,QAAoB,CAAC,EAClC,YAAY,CAAC,UAAU,CAAC,CACzB,CAAA;QACH,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC,UAAU,CAAC,CAAA;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAA+B,EAAE;IAC5D,IAAI,UAAU,GAAa,OAAO,CAAC,KAAK,IAAI,MAAM,CAAA;IAClD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAA;IAE/B,MAAM,IAAI,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,IAAe,EAAQ,EAAE;QACvE,+EAA+E;QAC/E,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;YACrC,CAAC;YAAC,MAAM,CAAC;gBACP,8DAA8D;YAChE,CAAC;QACH,CAAC;QACD,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC;YAAE,OAAM;QAC3D,6EAA6E;QAC7E,qEAAqE;QACrE,IAAI,CAAC;YACH,IAAI,UAAU,EAAE,CAAC;gBACf,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAA;YACrC,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAA;gBAC/E,0EAA0E;gBAC1E,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;QACrE,CAAC;IACH,CAAC,CAAA;IAED,OAAO;QACL,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;QACzD,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QACvD,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QACvD,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;QACzD,QAAQ,EAAE,KAAK,CAAC,EAAE;YAChB,UAAU,GAAG,KAAK,CAAA;QACpB,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE,CAAC,UAAU;KAC3B,CAAA;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-manager.d.ts","sourceRoot":"","sources":["../../src/managers/event-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"event-manager.d.ts","sourceRoot":"","sources":["../../src/managers/event-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAG5E,KAAK,cAAc,GAAG,MAAM,IAAI,CAAA;AAGhC;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAqD;IAEtE,mEAAmE;IACnE,EAAE,CAAC,CAAC,SAAS,YAAY,EACvB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC5B,MAAM,IAAI;IAUb,wEAAwE;IACxE,IAAI,CAAC,CAAC,SAAS,YAAY,EACzB,KAAK,EAAE,CAAC,EACR,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAC5B,MAAM,IAAI;IAQb,GAAG,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAK1E,IAAI,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI;IAUlE,OAAO,CAAC,QAAQ;IAkBhB;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,IAAI;IAI/C,kFAAkF;IAClF,MAAM,IAAI,IAAI;IAId,gBAAgB,IAAI,MAAM;IAQ1B,iBAAiB,IAAI,IAAI;CAG1B"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TELEMETRY_ONLY_EVENTS } from '../events';
|
|
1
2
|
/**
|
|
2
3
|
* Typed event emitter used by UniversalWalletConnector.
|
|
3
4
|
*
|
|
@@ -31,7 +32,10 @@ export class EventManager {
|
|
|
31
32
|
}
|
|
32
33
|
emit(event, data) {
|
|
33
34
|
this.dispatch(event, data);
|
|
34
|
-
|
|
35
|
+
// Telemetry-only events (logs, handoff instrumentation) describe what
|
|
36
|
+
// happened, not a state change — don't cascade them to `change`, or every
|
|
37
|
+
// log line would trigger a React re-render via legacy `subscribe()`.
|
|
38
|
+
if (event !== 'change' && !TELEMETRY_ONLY_EVENTS.has(event)) {
|
|
35
39
|
this.dispatch('change', undefined);
|
|
36
40
|
}
|
|
37
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-manager.js","sourceRoot":"","sources":["../../src/managers/event-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-manager.js","sourceRoot":"","sources":["../../src/managers/event-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAKjD;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACf,SAAS,GAA4C,IAAI,GAAG,EAAE,CAAA;IAEtE,mEAAmE;IACnE,EAAE,CACA,KAAQ,EACR,QAA6B;QAE7B,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACnC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG,GAAG,IAAI,GAAG,EAAE,CAAA;YACf,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;QAChC,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,QAA2B,CAAC,CAAA;QACpC,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,wEAAwE;IACxE,IAAI,CACF,KAAQ,EACR,QAA6B;QAE7B,MAAM,OAAO,GAAwB,IAAI,CAAC,EAAE;YAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YACxB,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC,CAAA;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAChC,CAAC;IAED,GAAG,CAAyB,KAAQ,EAAE,QAA6B;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrC,GAAG,EAAE,MAAM,CAAC,QAA2B,CAAC,CAAA;IAC1C,CAAC;IAED,IAAI,CAAyB,KAAQ,EAAE,IAAoB;QACzD,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC1B,sEAAsE;QACtE,0EAA0E;QAC1E,qEAAqE;QACrE,IAAI,KAAK,KAAK,QAAQ,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAkC,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IAEO,QAAQ,CACd,KAAQ,EACR,IAAoB;QAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACrC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;YAAE,OAAM;QAClC,mDAAmD;QACnD,KAAK,MAAM,QAAQ,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,CAAA;YAChB,CAAC;YAAC,MAAM,CAAC;gBACP,iEAAiE;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,oEAAoE;IAEpE;;;OAGG;IACH,SAAS,CAAC,QAAwB;QAChC,OAAO,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACpC,CAAC;IAED,kFAAkF;IAClF,MAAM;QACJ,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAkC,CAAC,CAAA;IAC7D,CAAC;IAED,gBAAgB;QACd,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1C,KAAK,IAAI,GAAG,CAAC,IAAI,CAAA;QACnB,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,iBAAiB;QACf,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAA;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Logger } from '@meshconnect/uwc-types';
|
|
2
|
+
import type { EventManager } from '../managers/event-manager';
|
|
3
|
+
import { type UWCObserver } from './telemetry';
|
|
4
|
+
/**
|
|
5
|
+
* Bridge the internal event bus to a consumer-supplied `UWCObserver`.
|
|
6
|
+
*
|
|
7
|
+
* Subscribes to every `UWCEventMap` event, normalizes each to a PII-safe
|
|
8
|
+
* `UWCTelemetryEvent`, and forwards it to `observer.onEvent`. The `log` event is
|
|
9
|
+
* routed to `observer.onLog` instead (with scrubbed args) — it's the logging
|
|
10
|
+
* channel, not a telemetry record. `change` is skipped: it's the legacy
|
|
11
|
+
* re-render cascade and carries no payload.
|
|
12
|
+
*
|
|
13
|
+
* Returns a teardown function that removes every subscription. The caller MUST
|
|
14
|
+
* invoke it on connector teardown — leaving these attached is the same listener-
|
|
15
|
+
* leak class as the historical `BridgeParent.destroy()` zombie bug.
|
|
16
|
+
*
|
|
17
|
+
* @param sdkSessionId - per-connector-instance id stamped on every record.
|
|
18
|
+
* @param getCorrelationId - resolves the optional consumer correlation id,
|
|
19
|
+
* called per-event so an id that arrives/changes after construction is
|
|
20
|
+
* honoured. Must not throw (the caller pre-wraps it). Defaults to `undefined`.
|
|
21
|
+
* @param now - clock injectable for deterministic tests; defaults to `Date.now`.
|
|
22
|
+
* @param logger - optional; a throwing observer is reported via `logger.debug`.
|
|
23
|
+
* When omitted the throw is swallowed silently (the historical behaviour).
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Cap on distinct observer-error messages remembered for dedup. Same storm-guard
|
|
27
|
+
* contract as the relay/bridge dedup sets: bounding keeps memory flat on a
|
|
28
|
+
* long-lived instance even when a broken observer throws high-cardinality
|
|
29
|
+
* messages (e.g. embedding event data or timestamps).
|
|
30
|
+
*/
|
|
31
|
+
export declare const MAX_REPORTED_OBSERVER_ERRORS = 100;
|
|
32
|
+
export declare function connectObserver(eventManager: EventManager, observer: UWCObserver, sdkSessionId: string, getCorrelationId?: () => string | undefined, now?: () => number, logger?: Logger): () => void;
|
|
33
|
+
//# sourceMappingURL=connect-observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect-observer.d.ts","sourceRoot":"","sources":["../../src/observability/connect-observer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAG7D,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAG9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,MAAM,CAAA;AAE/C,wBAAgB,eAAe,CAC7B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,WAAW,EACrB,YAAY,EAAE,MAAM,EACpB,gBAAgB,GAAE,MAAM,MAAM,GAAG,SAA2B,EAC5D,GAAG,GAAE,MAAM,MAAiB,EAC5B,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,IAAI,CAmFZ"}
|