feat: React Native New Architecture (Bridgeless) support v8.0.0-rc.1#343
feat: React Native New Architecture (Bridgeless) support v8.0.0-rc.1#343
Conversation
156c118 to
96f8f02
Compare
- Update version to 8.0.0-rc.1 - Update peer dependencies: RN >= 0.70.0, React >= 18.0.0 - Add playground/ to .npmignore - Update description for New Architecture
- Add TypeScript spec for Codegen (specs/NativeZipArchive.ts) - Migrate iOS from RCTBridgeModule to TurboModule protocol - Migrate Android from ReactContextBaseJavaModule to NativeZipArchiveSpec - Update JS entry point to use TurboModuleRegistry with Legacy fallback - Update podspec to include .mm files
- Add complete Expo playground with expo-dev-client - Include 7 demo screens for all library features - Add Jest test suite with 27 passing tests - Add TurboModule integration tests - Configure Metro for local module linking
- Rewrite README with New Architecture focus - Add MIGRATION.md with step-by-step guide - Add CHANGELOG.md with v8.0.0 release notes - Document Expo Development Build requirements - Preserve all existing API documentation
- Explain why Expo Go is not supported - Add step-by-step Development Build setup - Include comparison table for clarity - Link to playground example
- iOS: Extend RCTEventEmitter to support progress events (critical fix) - Podspec: Add install_modules_dependencies for modern RN support - index.d.ts: Fix unzipWithPassword parameter name - Android: Remove outdated AGP buildscript block - CHANGELOG: Update release date - .npmignore: Exclude dev files from npm package - Mock: Remove non-existent native method from mock
…layground This commit migrates react-native-zip-archive to support React Native 0.76 New Architecture (Fabric + TurboModules) with Bridgeless mode enabled. Library changes: - iOS: add RCT_EXPORT_MODULE() and getTurboModule: returning NativeZipArchiveSpecJSI for Bridgeless registration - iOS: fix podspec install_modules_dependencies check and flatten subspec - Android: add conditional com.facebook.react plugin and codegen sourceSets when newArchEnabled=true - Android: add Paper (Old Architecture) fallback spec - Android: fix illegal switch-on-double in getCompressionLevel() - JS: implement lazy TurboModule loading to avoid Bridgeless init crash - JS: update unit tests for lazy loading behavior Playground (new Expo 52 app): - Create Expo dev-client playground with expo-router - Enable newArchEnabled in app.json - Add demo screens: zip, unzip, password, progress, benchmarks, assets - Fix nested file creation (ensureDir before writeAsStringAsync) - Add expo-linking explicitly (pnpm transitive dep fix) - Add accessibilityLabel for E2E automation E2E testing: - Add Maestro flows for iOS and Android - Handle iOS dev-client launcher (tap Metro URL) - Handle Android cold-start with 45s timeout - Add npm scripts: test:e2e, test:e2e:android, test:e2e:ios - Add shell scripts for sequential test execution Documentation: - Add e2e/README.md with Maestro setup instructions
- iOS: call [super addListener:] / [super removeListeners:] to preserve RCTEventEmitter lifecycle (startObserving/stopObserving) for progress events - Android: add missing return after promise.reject in unzipWithPassword and zipWithPassword to prevent double-resolve / NullPointerException - Android: use TurboReactPackage instead of BaseReactPackage for RN 0.70+ backward compatibility - README: fix broken Buy Me A Coffee markdown link
- Android unzipWithPassword: resolve with destDirectory string instead of WritableArray to match TurboModule spec (Promise<string>) and iOS behavior - Android processZip: add missing return after promise.reject when file doesn't exist, preventing double promise settlement - Android processZip: move updateProgress(100%) outside the for loop so it fires once after all entries are processed, not on every iteration
Devin review noted that early RN 0.70.x releases require a 7-arg ReactModuleInfo constructor including hasConstants. Adding the 7th arg maintains backward compatibility with >= 0.70.0 peer dep.
96f8f02 to
283bb74
Compare
- Fix encryption method default inconsistency: empty string now defaults to non-AES (ZIP_STANDARD) on iOS, matching Android behavior. - Add RCT_NEW_ARCH_ENABLED guards for old architecture compatibility: conditionally import NativeZipArchiveSpec header and conform to the protocol only when New Architecture is enabled, matching the Android paper shim pattern. Refs: Devin review comments #3193190132, #3193190251
Add Maestro E2E test for the Android Assets demo screen. The test navigates to Assets (Android), taps Unzip Assets, and asserts the sample.zip contents are extracted correctly. Also includes the new flow in the Android E2E test script.
plrthink
left a comment
There was a problem hiding this comment.
Fixed in commit d08ce66. Added a null check before Arrays.asList(f.listFiles()) — if listFiles() returns null (e.g., directory unreadable due to permissions), we now fall back to an empty ArrayList instead of throwing NPE.
| - (dispatch_queue_t)methodQueue { | ||
| return dispatch_queue_create("com.mockingbot.ReactNative.ZipArchiveQueue", DISPATCH_QUEUE_SERIAL); | ||
| } |
There was a problem hiding this comment.
🚩 iOS methodQueue creates a new dispatch queue on every call
The methodQueue method at RNZipArchive.mm:252-254 calls dispatch_queue_create every time it's invoked, rather than caching the queue. This means each method invocation may get a different serial queue (depending on how React Native caches the result). This is a pre-existing pattern unchanged by this PR. In practice, React Native caches the result of methodQueue internally, but this implementation is unusual compared to the typical pattern of storing the queue in an ivar.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
This PR migrates
react-native-zip-archiveto support React Native 0.76 New Architecture (Fabric + TurboModules) with Bridgeless mode enabled.Library Changes
iOS:
RCTTurboModuleRegistryandgetTurboModule:returningNativeZipArchiveSpecJSIfor Bridgeless registrationinstall_modules_dependenciescheck and flattenheader_search_pathsencryptionTypenow defaults to standard ZipCrypto (matching Android)#ifdef RCT_NEW_ARCH_ENABLEDguards in header and implementationAndroid:
com.facebook.reactplugin and codegen sourceSets whennewArchEnabled=trueandroid/src/oldarch/NativeZipArchiveSpec.javaSSZipArchivesymbol inbuild.gradleunzipAssetsfor compressed assets:AssetManager.openFd()fails for.zipfiles stored compressed in the APK; now falls back toInputStream.available()JS:
Playground (New Expo 52 App)
newArchEnabled=trueinapp.jsonensureDirbefore write)listFilesRecursiveutility for displaying extracted nested filesexpo-document-pickerexplicitly (pnpm transitive dep fix)E2E Testing
assets.yamlflow for AndroidunzipAssetsdemoe2e:ios,e2e:android,e2eTest Results
Breaking Changes
Requires React Native >= 0.70.0. New Architecture is opt-in (enabled via
newArchEnabled=truein consuming app).Version
6.1.0