refactor(suite-native): separate app composition from initialization - #32199
Conversation
⚡️ Performance report (alpha)Note Alpha release: The limits are still being calibrated, and each measurement is desktop / group 6🟢 Within limits.Each metric reads
|
| useReportAppInitToAnalytics(); | ||
|
|
||
| useEffect(() => { | ||
| if (!isApplicationInitDispatchedRef.current) { |
There was a problem hiding this comment.
Removing isApplicationInitDispatchedRef does not remove the duplicate-initialization guard: it moves that responsibility from React into createNativeInit. The service caches its initialization promise with initialization ??= ..., so repeated calls to the same init() instance return the same promise and dispatch applicationInitThunk only once. Because the composition root is created outside React, component rerenders or remounts do not reset that guard; the old ref only protected a single mounted component instance.
There is a separate lifecycle change to review: initialization previously started from a React effect after the component mounted, whereas it now starts after Redux hydration and may run before the React providers mount. Initialization code that relies on mounted UI infrastructure therefore needs checking. That timing concern—and hydration/error handling—is independent of removing the ref; adding the ref back would not address it.
|
✅ Previously successful run of [Test] suite-native Android E2E workflow has been found. |
cfc6ee0 to
1ba49cb
Compare
1ba49cb to
8abd17b
Compare
| return () => { | ||
| // Repeated startup calls must not start duplicate Connect sessions or periodic workers. | ||
| if (App === null) { | ||
| markStartupJsBundleEvaluated(); |
There was a problem hiding this comment.
move this before call of the compositionRoot into an index.js
|
adhoc builds pipeline: https://github.com/trezor/trezor-suite/actions/runs/34237160999 |
e2ca868 to
a2f1dde
Compare
matejkriz
left a comment
There was a problem hiding this comment.
Tested on both iOS and Android on local and ad-hoc builds and I haven't observed any issues.
771ff4d to
65a9d0b
Compare
Description
Align native startup with web and desktop by creating the Redux store and services synchronously, then injecting services into Redux extra. A separate init service starts persistence, waits for hydration, and runs application initialization while preserving native storage and migrations. This follows #32195.
🌐 Preview deployments
🌐 Suite Web preview: https://dev.suite.sldev.cz/suite-web/refactor-native-app-initialization/web/
🔍 Currents Test Results
🔍 Suite desktop test results: View in Currents
🔍 Suite web test results: View in Currents
🔍 Suite native android test results: View in Currents
🔒 Quarantined E2E Tests
Trezor Suite (web) — 3 test(s)
Updated: 2026-09-08T18:25:17.235Z • 3 test(s) total
Trezor Suite (desktop) — 3 test(s)
Updated: 2026-09-08T18:23:45.650Z • 3 test(s) total
🤖 LLM Test Recommendations
Summary: The changes span Redux store creation and extra-dependency configuration for both web and native Suite. Most candidate tests only transitively import these global files, so a minimal representative set is recommended: validate app boot and persistence (initial-run, db-migration) and exercise state-dependent flows that rely on correct store setup (analytics, multi-session, remembered-wallet hydration). The bulk of the diff is native-only and is not covered by the web/electron E2E suite; those native files should be validated separately via the modified native E2E tests.
Changed files (22)
packages/suite/src/reducers/createReduxStore.tssuite-common/redux-utils/src/createReduxExtra.test.tssuite-common/redux-utils/src/createReduxExtra.tssuite-common/redux-utils/src/index.tssuite-native/app/e2e/tests/tradingExchangeFlow.test.tssuite-native/app/e2e/tests/tradingSellFlow.test.tssuite-native/app/index.jssuite-native/app/package.jsonsuite-native/app/src/App.tsxsuite-native/app/src/createNativeInit.tsxsuite-native/app/src/createSuiteNativeCompositionRoot.tssuite-native/app/src/initSentry.tssuite-native/app/tsconfig.jsonsuite-native/state/mocks/mockInitialAppState.tssuite-native/state/src/NativeServices.tssuite-native/state/src/StoreProvider.tsxsuite-native/state/src/createHydrateReduxStore.tssuite-native/state/src/createNativeExtraDependencies.tssuite-native/state/src/createNativeServicesCompositionRoot.tssuite-native/state/src/createReduxStore.tssuite-native/state/src/createStorePersistor.tssuite-native/state/src/index.tsRecommended tests (5)
🔴 High priority (2)
suite/e2e/tests/suite/initial-run.test.ts— This test validates the app boots correctly on first run and that onboarding/analytics state persists across reloads, which directly exercises the web Redux store creation and hydration path changed in createReduxStore.ts and createReduxExtra.ts.suite/e2e/tests/suite/db-migration.test.ts— This test upgrades an older Suite version's persisted state and verifies settings survive migration, directly stressing store hydration, persistence, and state shape from the changed store/extra-dependency code.🟡 Medium priority (3)
suite/e2e/tests/analytics/events.test.ts— Analytics event dispatching and interception depend on the store's middleware and extra thunk dependencies configured by createReduxExtra.ts; this test verifies the analytics pipeline still emits correct events after the shared utility changes.suite/e2e/tests/suite/multiple-sessions.test.ts— This test exercises Bridge session state across page reloads and multiple tabs, which relies on the store being re-created correctly on each load.suite/e2e/tests/trading/remembered-wallet-loading.test.ts— This test seeds persisted wallet state into IndexedDB and reloads Suite, validating that the store hydrates remembered wallets correctly after the store creation changes.suite-common/redux-utils/src/createReduxExtra.test.tssuite-native/app/e2e/tests/tradingExchangeFlow.test.tssuite-native/app/e2e/tests/tradingSellFlow.test.tssuite-native/app/index.jssuite-native/app/package.jsonsuite-native/app/src/App.tsxsuite-native/app/src/createNativeInit.tsxsuite-native/app/src/createSuiteNativeCompositionRoot.tssuite-native/app/src/initSentry.tssuite-native/app/tsconfig.jsonsuite-native/state/mocks/mockInitialAppState.tssuite-native/state/src/NativeServices.tssuite-native/state/src/StoreProvider.tsxsuite-native/state/src/createHydrateReduxStore.tssuite-native/state/src/createNativeExtraDependencies.tssuite-native/state/src/createNativeServicesCompositionRoot.tssuite-native/state/src/createReduxStore.tssuite-native/state/src/createStorePersistor.tssuite-native/state/src/index.tsUpdated: 2026-09-08T18:22:23.637Z