Skip to content

fix(native): one lifecycle for the stored items on every platform - #687

Merged
sunnylqm merged 1 commit into
masterfrom
claude/state-lifecycle
Oct 16, 2026
Merged

sunnylqm merged 1 commit into
masterfrom
claude/state-lifecycle

Conversation

@sunnylqm

@sunnylqm sunnylqm commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

This is the first step of the state_schema item from the architecture review. Reset and binary upgrade now delete the same stored items on every platform. Nothing on disk changes format.

Before

Besides the state fields, what a reset to the packaged bundle and a binary upgrade deleted differed per platform:

  • On a binary upgrade, only Android cleared the old versions' hash_* info, the first-load marker and the response cache.
  • Only Android dropped the round breadcrumb, and it did so on both events.

Now

  • scripts/contract.ts storedItems lists every persisted item and the events that delete it. The generator emits each platform's lists in VersionScopedKeys.java, RCTPushyState.mm and UpdateContext.ts, and the reset and upgrade paths read those lists.
  • Behaviour is the same on all three platforms:
    • Both events delete the version info, the first-load marker and the response cache. A reset also deletes the iOS package-updated marker.
    • The uuid, the native config, the round breadcrumb and the bundle hash cache survive both events.
  • Physical keys are unchanged, so no migration is needed.
  • JS now normalizes getConstants values that the platforms report differently when absent:
    • isFirstTime becomes a boolean.
    • rolledBackVersion becomes ''.

Tests

  • The iOS purge-restore harness gains binary_upgrade_clears_version_keys. It fails without the new upgrade clearing.
  • New harmonyStateLifecycle.test.ts drives UpdateContext.removeKeys with the generated lists.
  • VersionScopedKeysTest covers both events.
  • Locally bun lint passes (43 generated regions are up to date) and bun test passes (464 tests).

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Summary by CodeRabbit

  • Bug Fixes
    • Resetting to the packaged bundle or upgrading the app now clears outdated update and version-specific data while preserving install-scoped settings.
    • Incomplete-update tracking data is retained during these cleanup events.
    • First-load status and version information are handled consistently when platform values are missing or falsy.

What a reset to the packaged bundle and a binary upgrade delete besides the
state fields differed per platform: a binary upgrade cleared the old
versions' info, the first-load marker and the response cache on Android
only, and only Android dropped the round breadcrumb (on both events).

scripts/contract.ts storedItems now lists every persisted item next to the
state fields with the events that delete it, and the generator emits each
platform's lists (VersionScopedKeys.java, RCTPushyState.mm,
UpdateContext.ts), which the reset and upgrade paths use. Behaviour now, on
every platform: both events delete the version info, the first-load marker
and the response cache (reset also the iOS package-updated marker); the
uuid, the native config, the round breadcrumb and the bundle hash cache
survive both. No physical key changes: nothing on disk is migrated.

JS normalizes the getConstants values the platforms report differently when
absent (isFirstTime to a boolean, rolledBackVersion to '').

Tests: the iOS purge-restore harness gains binary_upgrade_clears_version_keys
(fails without the new upgrade clearing), a Harmony test drives
UpdateContext.removeKeys with the generated lists, VersionScopedKeysTest
covers both events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7ce4c12f-8db8-4793-935f-d935f2083210
📥 Commits

Reviewing files that changed from the base of the PR and between c22800a and c9e3433.

📒 Files selected for processing: 14
  • android/src/main/java/cn/reactnative/modules/update/UpdateContext.java
  • android/src/main/java/cn/reactnative/modules/update/VersionScopedKeys.java
  • android/src/test/java/cn/reactnative/modules/update/VersionScopedKeysTest.java
  • harmony/pushy/src/main/ets/UpdateContext.ts
  • ios/RCTPushy/RCTPushy+Launch.mm
  • ios/RCTPushy/RCTPushy.mm
  • ios/RCTPushy/RCTPushyInternal.h
  • ios/RCTPushy/RCTPushyState.mm
  • scripts/contract.ts
  • scripts/generate-contract.ts
  • scripts/tests/ios-purge-restore/extract.py
  • scripts/tests/ios-purge-restore/purge_restore_test.mm
  • src/__tests__/harmonyStateLifecycle.test.ts
  • src/core.ts

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

📝 Walkthrough

Reset and binary-upgrade cleanup now use separate key sets generated from a shared inventory and applied across Android, Harmony, and iOS. Tests cover the cleanup sets and retained state. The core API also normalizes two native values.

Changes: Lifecycle state cleanup

Layer / File(s) Summary
Lifecycle inventory and cleanup sets
scripts/contract.ts, scripts/generate-contract.ts, android/src/main/java/cn/reactnative/modules/update/VersionScopedKeys.java, harmony/pushy/src/main/ets/UpdateContext.ts, ios/RCTPushy/RCTPushyState.mm
A shared inventory assigns persisted items to reset and binary-upgrade lifecycles. The generator emits platform-specific key and prefix sets. Both cleanup sets include the first-load marker, response cache, and hash_ prefix; the package-updated marker is reset-only.
Platform cleanup and lifecycle wiring
android/src/main/java/cn/reactnative/modules/update/UpdateContext.java, harmony/pushy/src/main/ets/UpdateContext.ts, ios/RCTPushy/RCTPushyInternal.h, ios/RCTPushy/RCTPushyState.mm, ios/RCTPushy/RCTPushy+Launch.mm, ios/RCTPushy/RCTPushy.mm
Android, Harmony, and iOS apply the cleanup set for resets and binary upgrades. The removal helpers handle exact keys and prefix matches.
Lifecycle cleanup tests
android/src/test/java/cn/reactnative/modules/update/VersionScopedKeysTest.java, src/__tests__/harmonyStateLifecycle.test.ts, scripts/tests/ios-purge-restore/*
Tests check the keys removed and retained on Android and Harmony. The iOS binary-upgrade test checks version state, cleared keys, retained UUID and round breadcrumb, and the package update marker.

Core value normalization

Layer / File(s) Summary
Normalize native values
src/core.ts
isFirstTime is coerced to a boolean. rolledBackVersion defaults to an empty string when its native value is falsy.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to c9e34

This change makes reset and binary-upgrade cleanup consistent across Android, iOS, and Harmony, and it normalizes two native values in the core API. No actionable merge-blocking risk was identified.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 10 files. (4 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: consistent native lifecycle handling for stored items across platforms.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 41.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 10 files. (4 skipped: 4 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

  • Fix all pre-merge checks with AI
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sunnylqm
sunnylqm merged commit 22ee8e0 into master Oct 16, 2026
16 checks passed
@sunnylqm
sunnylqm deleted the claude/state-lifecycle branch October 16, 2026 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant