feat: AnalyticsClient wiring + openURL public API [rn] (3/4)#36
Open
choudlet wants to merge 1 commit into
Open
Conversation
Wires the storage foundation (#34) and emitter (#35) into `MetaRouterAnalyticsClient` and adds the public `openURL` API. Behavior - Cold-launch state machine: detects fresh install vs SDK-upgrade vs version change vs no-op, emits Installed/Updated *before* the first Application Opened so attribution pipelines see the install/update before the session start. - Background-launched processes (push, headless JS) suppress the cold-launch Application Opened; the next background→active emits with from_background:false as the cold-launch bridge. - inactive→active transitions (Control Center, FaceID, system alerts) are suppressed — only background→active emits Application Opened. - Application Backgrounded is enqueued *before* the dispatcher's flush-to-disk pass so the event ships in the same drain. - Auto-captures cold-launch URL via Linking.getInitialURL() and runtime URLs via Linking.addEventListener('url', ...). One-shot deep-link buffer with last-write-wins overwrite, cleared on the next Application Opened emit. Public API - `openURL(url, sourceApplication?)` — forwards a URL the host received (Linking, UIScene URL handler, Android Intent, custom deep-link library) so it is attached to the next Application Opened. No-op with a Logger.warn when trackLifecycleEvents is disabled — silent no-ops are bad DX, hosts wiring this up should know they have the feature flag off. - Wired through AnalyticsInterface, the proxy (so pre-bind calls are queued), and init.ts boundClient. Defaults - `trackLifecycleEvents` defaults to **false** (opt-in). Existing customers upgrading the SDK do not begin emitting these events without explicitly setting the flag — matches iOS / Android v1.5. App metadata - Single `appContext` snapshot held on the client, populated once from `this.context.app` after `getContextInfo` resolves. Replaces three sites that independently re-derived `{version, build}` from the cached context — single source of truth, parity with the iOS `AppContext` consolidation. Tests - `disableDispatcherFlush` helper added to the lifecycle describe block: the dispatcher's flush() synchronously drains the in-memory queue inside its first while iteration (drainBatch runs before the await), which empties events that were emitted right before `this.flush()` in handleAppStateChange. Production behavior is correct (event still ships via fetch); the helper just keeps the queue snapshot intact for assertions. - 6 new tests cover the openURL public API: buffered URL on next Opened, sourceApplication → referring_application, last-write-wins, one-shot clear, disabled no-op + warning, invalid input rejection. - 1 new test confirms the opt-in default (omitted flag → no events). - Pre-existing `preserves lifecycle storage across reset()` test fixed: AsyncStorage mock module shape is `{ default: { ... } }`, so the spy must target the `default` export, not the top object. Slice 3 of 4 in the RN lifecycle stack (sc-36800).
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Slice 3 of 4 in the RN lifecycle stack (sc-36800). Wires the storage foundation (#34) and emitter (#35) into `MetaRouterAnalyticsClient`, adds the public `openURL` API, and flips the `trackLifecycleEvents` default to opt-in.
Stacked on #35. Review the diff against that branch.
Behavior contract
Public API
```ts
analytics.openURL(url: string, sourceApplication?: string): void
```
Forwards a URL the host received from any source (Linking, UIScene URL handler, Android Intent, deep-link libraries that bypass Linking) so it's attached to the next `Application Opened`. No-op with a `Logger.warn` when `trackLifecycleEvents` is disabled — silent no-ops are bad DX. Wired through:
Defaults flipped
`InitOptions.trackLifecycleEvents` now defaults to `false` (opt-in). Existing customers upgrading the SDK do not begin emitting these events without explicitly setting the flag. Matches iOS / Android v1.5.
App metadata consolidation
A single `appContext` snapshot is held on the client, populated once from `this.context.app` after `getContextInfo` resolves. Replaces three sites that independently re-derived `{version, build}` from the cached context — parity with the iOS `AppContext` consolidation. New `versionInfo()` private helper centralizes the read.
Test changes
Stack
Test plan