Skip to content

useCodePush(): download, install and pending-restart state - #112

Merged
ofalvai merged 1 commit into
masterfrom
use-code-push-download-state
Nov 11, 2026
Merged

ofalvai merged 1 commit into
masterfrom
use-code-push-download-state

Conversation

@ofalvai

@ofalvai ofalvai commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Why

Additional improvements to useCodePush(). Two gaps came up that the hook's state could not answer:

  • "Is an update waiting for a restart?" After sync() installs with ON_NEXT_RESTART, the update stops being available and nothing in the state says it is installed.
  • "Is it downloading, and did that fail?" checkError only covers the server query. A failed download left the state at "update available" with no error. The Provider's onError only sees the syncs the Provider starts, and a component's sync() only rejects its own promise. There was also no download progress, because the hook's sync takes no callbacks.

What changes

New state in useCodePush():

  • isDownloading
  • installError, set when the download or the install of an update fails, and cleared by the next download or a successful install
  • pendingUpdate, set by every install, until the restart starts a new JS context

New hook useDownloadProgress() returns { receivedBytes, totalBytes } or undefined.

All of this is reported from the shared download and install functions in CodePush.js, so it covers the Provider, the hook's sync, legacy codePush.sync(), the HOC, and manual RemotePackage.download() / LocalPackage.install(). It doesn't matter who started the work.

Decisions

  • Progress has its own hook: Native sends many progress events per second. In the main snapshot, every useCodePush() caller would re-render at that rate during a download, including a component that only reads checkError. Progress lives in the same store but outside the snapshot, and useSyncExternalStore re-renders only the components that read it.
  • Progress events are always on: downloadUpdate() used to ask native for progress only when a callback was passed. Now it always subscribes. Follow-up optimization: Throttle iOS download progress events by time #113
  • One error for download and install: The name follows the app's view: installing an update includes downloading it.
  • installError follows checkError's rule: a new attempt clears it. A new check does not, so a background check doesn't hide a failure the user hasn't seen yet.

🤖 Generated with Claude Code

@ofalvai
ofalvai force-pushed the use-code-push-download-state branch from f6345c1 to 54f075c Compare November 10, 2026 13:39
@ofalvai
ofalvai marked this pull request as ready for review November 10, 2026 13:40
Base automatically changed from add-use-code-push to master November 11, 2026 09:56
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ofalvai
ofalvai force-pushed the use-code-push-download-state branch from 54f075c to b6c7641 Compare November 11, 2026 09:58
Copilot AI balanced review requested due to automatic review settings November 11, 2026 09:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the hook-state and download-progress changes.

No open issues 🎉

What changed in this PR

Extends CodePush’s React hooks to expose download activity, installation errors, and updates awaiting restart, regardless of which API initiated the work.

Changes:

  • Adds isDownloading, installError, and pendingUpdate to useCodePush().
  • Introduces useDownloadProgress() with a separate snapshot so progress events do not re-render consumers of only useCodePush().
  • Connects shared download and install operations to the store, with unit tests and API documentation.
File Description
typings/​react-native-code-push.d.ts Declares new state fields and the progress hook.
src/​update-state/​update-store.ts Exposes progress separately from the main snapshot.
src/​update-state/​update-state.ts Tracks downloads, installation failures, and pending updates.
src/​update-state/​track-update.ts Reports download and install outcomes to the store.
src/​update-state/​__tests__/​update-store.test.ts Tests progress notifications and snapshot stability.
src/​update-state/​__tests__/​update-state.test.ts Tests new state transitions and overlapping downloads.
src/​update-state/​__tests__/​track-update.test.ts Tests operation tracking and error propagation.
src/​react/​use-download-progress.ts Implements the dedicated progress hook.
src/​react/​store-context.ts Makes the progress getter available through context.
src/​package-metadata.ts Copies package metadata without function properties.
src/​__tests__/​package-metadata.test.ts Tests metadata filtering without mutating the package.
docs/​api-js.md Documents new state fields and progress behavior.
CodePush.js Integrates tracking, enables progress events, and exports the hook.

Review effort: Balanced

@ofalvai
ofalvai merged commit cdc8cc2 into master Nov 11, 2026
7 checks passed
@ofalvai
ofalvai deleted the use-code-push-download-state branch November 11, 2026 10:22
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.

3 participants