You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
P-1925 P-1926 Enhance analytics API with optional parameters and referral config (#2)
* Fix API signature inconsistencies and code quality issues for web SDK parity
- Make signature() chainId optional to match web SDK (chain-agnostic signatures)
- Add function_name and function_args to transaction() for contract call tracking
- Add optional category parameter to screen() matching web page() API
- Consolidate FormoAnalyticsProviderProps into single complete type
- Replace require() with static import in setTrafficSourceFromUrl
- Add errorHandler option to Options for global error handling
- Add ReferralOptions for configurable referral query parameter parsing
- Update tests for new optional chainId behavior
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Add package-lock.json for dependency version locking
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Fix screen() test to pass properties as third arg after category param
The screen() signature changed to screen(name, category?, properties?, ...),
so the test needs to pass undefined for category before the properties object.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Address review feedback: backward-compat screen(), implement pathPattern, dedup refParams
- Revert screen() to original (name, properties?, context?, callback?) signature
to avoid breaking existing callers. Category is passed via properties.category.
- Implement pathPattern support in parseTrafficSource so ReferralOptions.pathPattern
actually extracts referral codes from URL paths via regex capture group.
- Deduplicate referral query params using Set to avoid redundant lookups.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Guard errorHandler callback with try/catch to prevent consumer errors from bubbling
A throwing errorHandler would cause trackEvent to reject, turning telemetry
failures into app-level failures. Now secondary handler errors are logged
instead of propagated.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Add category as positional parameter to screen() for web SDK parity
Since this is v1.0.0 with no existing consumers, use the clean signature
screen(name, category?, properties?, context?, callback?) instead of the
properties.category workaround. Matches web SDK's page(category?, name?).
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Add application lifecycle event tracking (installed, updated, opened, backgrounded)
Implements the Segment/RudderStack mobile lifecycle spec using a JS-side
approach (no native modules required, works in Expo Go):
- Application Installed: first launch (no stored version in AsyncStorage)
- Application Updated: version or build changed from stored values
- Application Opened: every cold start (from_background: false) and
foreground return (from_background: true), includes deep link URL
- Application Backgrounded: app goes to background
Detection compares stored app version/build in AsyncStorage against
current values from react-native-device-info, expo-application, or
options.app config.
Controlled via autocapture.lifecycle option (default: true).
Adds AppLifecycleManager with its own AppState listener, separate from
EventQueue's flush-on-background listener.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Guard lifecycle install/update detection against non-persistent storage
When AsyncStorage is not provided, the SDK falls back to MemoryStorage
which is empty on every cold start. Without this guard, detectInstallOrUpdate
would false-positive as "Application Installed" on every launch.
Now checks if AsyncStorage adapter is actually available before comparing
stored version/build. Skips install/update events (with warning) if only
MemoryStorage is available. Application Opened/Backgrounded still fire.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Fix persistent storage check that was defeated by MemoryStorage fallback
StorageManager.getStorage("asyncStorage") silently falls back to
MemoryStorage when AsyncStorage hasn't been initialized, and
MemoryStorage.isAvailable() always returns true. This made the
lifecycle guard ineffective — install events would still fire on
every cold start without AsyncStorage.
Fix: Add StorageManager.hasPersistentStorage() that checks if an
initialized AsyncStorage adapter exists in the storages map, bypassing
the fallback logic in getStorage().
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Await async storage persistence for app version to prevent duplicate install events
storage().set() writes to the in-memory cache synchronously but persists
to AsyncStorage asynchronously without being awaited. If the app crashes
or is force-quit before the async write completes, the version data is
lost and the next launch would fire a duplicate "Application Installed"
event. Switch to awaiting setAsync() to ensure persistence completes.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Wrap lifecycle init in try-catch to prevent SDK init failure
A transient AsyncStorage write failure in lifecycle tracking (e.g.,
storage full, permission error) would reject the init() promise and
leave the SDK uninitialized with no-op methods for the entire session.
Lifecycle tracking is non-critical — it should not block the core
analytics SDK from functioning.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Fix hasPersistentStorage() to use instanceof check against fallback
getStorage("asyncStorage") caches a MemoryStorage fallback at the
asyncStorage slot when AsyncStorage hasn't been initialized. The
previous check (stored !== undefined && stored.isAvailable()) would
pass for this cached MemoryStorage since MemoryStorage.isAvailable()
always returns true.
Use instanceof AsyncStorageAdapter to ensure we're checking the real
persistent adapter, not a MemoryStorage fallback cached at that slot.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Preserve function_args key casing from toSnakeCase conversion
The toSnakeCase utility recursively converts all object keys, which
corrupts function_args values that represent smart contract ABI
parameter names (e.g., "tokenId" becomes "token_id"). Extract
function_args before conversion and re-attach after to preserve
the original key casing.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
* Apply pnpm supply chain security recommendations
Upgrade pnpm from 9.0.0 to 10.27.0 and add security settings
per https://pnpm.io/supply-chain-security:
1. onlyBuiltDependencies: [] — block lifecycle scripts by default,
only explicitly approved packages can run postinstall scripts
2. blockExoticSubdeps: true — prevent transitive deps from using
git repos or direct tarball URLs
3. minimumReleaseAge: 1440 — wait 24h before installing newly
published versions to avoid the malware exposure window
4. trustPolicy: no-downgrade — prevent installation if a package's
trust level has decreased from previous releases
Also removes package-lock.json (npm artifact) in favor of
pnpm-lock.yaml.
https://claude.ai/code/session_0117WwRELH1nzVbxRj7Kmm5N
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments