Platform Parity
Generated from packages/contract-fixtures/fixtures/surface/{operations,events}.json — the
same fixtures the web, Android, and iOS SDK contract tests run against. This table cannot
drift from the fixtures: next build fails if a fixture case is added without a matching
label in lib/operation-names.ts.
✅ required · ⚠️ unimplemented · — absent (reason in Notes)
The returns field in the fixtures records cross-platform intent, not a per-platform
signature — see each platform’s API Reference for the real
return type.
Operations
| Operation | Web | iOS | Android | Flutter | Notes |
|---|---|---|---|---|---|
init | ✅ | ✅ | ✅ | ✅ | |
track | ✅ | ✅ | ✅ | ✅ | |
identify | ✅ | ✅ | ✅ | ✅ | |
logout | ✅ | ✅ | ✅ | ✅ | |
reset | — | ✅ | ✅ | ✅ | web: Product question — web has never distinguished 'clear the identified user' from 'mint a new anonymous ID'; deferred rather than guessed (see SCHEMA.md's Known divergences: reset on web). |
setApiKey | — | ✅ | ✅ | ✅ | web: Web's API design takes the key directly as init()'s first argument; there is no separate override method to mirror. |
setLocale | — | ✅ | ✅ | ✅ | web: Deferred — web's locale is fixed at init() time; making it live-reactive like the natives is a product decision, not guessed here (see SCHEMA.md's Known divergences: live setLocale on web). |
setSurveysEnabled | ✅ | ✅ | ✅ | ✅ | |
areSurveysEnabled | ✅ | ✅ | ✅ | ✅ | |
flush | ✅ | — | — | — | android: No public manual-flush hook exists — EventTracker/ResponseFlusher's periodic timers are internal, with nothing exposed for a caller to trigger early. ios: No public manual-flush hook exists — EventTracker/ResponseFlusher's periodic timers are internal, with nothing exposed for a caller to trigger early. bridge: Nothing to bridge — neither native exposes a manual flush. |
isInitialized | ✅ | ✅ | ✅ | ✅ | |
on | ✅ | ✅ | ✅ | ✅ | |
off | ✅ | ✅ | ✅ | ✅ | |
shutdown | ✅ | ✅ | ✅ | ✅ |
emit and internal-accessors are excluded from this table — they’re deliberately not
public API on any platform (internal-only dispatch/test accessors).
Events
| Event | Web | iOS | Android | Flutter | Notes |
|---|---|---|---|---|---|
ready | — | ✅ | ✅ | ✅ | web: Web signals readiness through the init() promise resolving, not a separate event — a structural difference from the natives' callback-plus-event pair, not a bug. |
survey:shown | ✅ | ✅ | ✅ | ✅ | |
survey:completed | ✅ | ✅ | ✅ | ✅ | |
survey:dismissed | ✅ | ✅ | ✅ | ✅ | |
survey:question_answered | — | ✅ | ✅ | ✅ | web: Web emits 'survey:step' instead, with payload { surveyId, questionId, step } — one name/payload should win, but renaming either breaks existing integrators of that platform. Deferred (see SCHEMA.md's Known divergences: survey:step vs survey:question_answered). |
survey:step | ✅ | — | — | — | android: Native's equivalent is 'survey:question_answered', with a different payload — same deferred decision as the survey-question-answered case. ios: Native's equivalent is 'survey:question_answered', with a different payload — same deferred decision as the survey-question-answered case. bridge: Bridges the native 'survey:question_answered' event only; web's 'survey:step' has no channel wire equivalent. |