Skip to content

Commit 9305335

Browse files
txbrownclaude
andauthored
Upgrade to new architecture (#13)
* chore: remove flipper config * chore: bump ruby version * feat: attempt to upgrade to new arch * feat: add expo example app - so we can test it works on expo * feat: add example new arch and keep old * fix: fix example run config * feat: make renderer work on new arch * chore: bump node version * fix: fix build for new arch * feat: complete new architecture migration with old arch support - Add event emitter support for TurboModules (addListener/removeListeners) - Fix iOS getSampleRate method signature for old arch bridge compatibility - Fix Android getSampleRate method signature (remove extra parameter) - Create old arch package (ElementaryTurboPackage) for Android bridge mode - Remove pre-generated codegen folders - now generated at consumer build time - Update iOS header to import spec from Pods headers - Consolidate iOS example to single project with arch toggle - Update Podfile with clear architecture toggle comment - Update C++ standard to c++20 for React Native 0.78 compatibility - Fix ESLint config to use correct package name (@react-native) Both architectures tested and working on iOS and Android. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): resolve CI validation failures - Add missing ESLint dependencies (eslint-plugin-ft-flow, hermes-eslint) - Add metro-react-native-babel-preset for Jest - Fix Jest modulePathIgnorePatterns to exclude example_old - Remove codegen from bob targets (runs at consumer build time) - Update Java version from 11 to 17 for React Native 0.78 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * style: fix prettier formatting in example app 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add Expo example app - Add example-expo/ with Expo SDK 53 and React Native 0.79 - Configure expo-dev-client for development builds - Add metro.config.js with resolveRequest to fix React duplicates in monorepo - Add react-native.config.js for proper codegen integration - Update root package.json with example-expo script - Update .gitignore for Expo generated folders Note: This library requires a development build (`expo run:ios/android`) and cannot run in Expo Go due to native C++ Elementary Audio dependency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(ci): exclude example-expo from lint and build - Add example-expo/ to eslintIgnore - Add example-expo and example_old to tsconfig.build.json exclude 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: correct exports types paths in package.json The types paths incorrectly included /src/ which doesn't exist in the build output. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: exclude example folders from typecheck 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ce2caaa commit 9305335

File tree

131 files changed

+29642
-6636
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+29642
-6636
lines changed

.elementaryspec

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"modules": {
3+
"Elementary": {
4+
"type": "NativeModule",
5+
"methods": {
6+
"getSampleRate": {
7+
"type": "Promise",
8+
"returnType": "number"
9+
},
10+
"applyInstructions": {
11+
"type": "method",
12+
"arguments": [
13+
{
14+
"name": "message",
15+
"type": "string"
16+
}
17+
]
18+
}
19+
}
20+
}
21+
}
22+
}

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
uses: actions/setup-java@v3
8383
with:
8484
distribution: 'zulu'
85-
java-version: '11'
85+
java-version: '17'
8686

8787
- name: Finalize Android SDK
8888
if: env.turbo_cache_hit != 1

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ android.iml
4343
# Cocoapods
4444
#
4545
example/ios/Pods
46+
example_old/ios/Pods
4647

4748
# Ruby
4849
example/vendor/
50+
example_old/vendor/
4951

5052
# node.js
5153
#
@@ -62,6 +64,8 @@ android/keystores/debug.keystore
6264

6365
# Expo
6466
.expo/
67+
example-expo/ios/
68+
example-expo/android/
6569

6670
# Turborepo
6771
.turbo/

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v18
1+
v20

.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.1.0

android/build.gradle

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ android {
6060
}
6161
}
6262

63+
// Include arch-specific source sets
64+
sourceSets {
65+
main {
66+
if (isNewArchitectureEnabled()) {
67+
java.srcDirs += "src/newarch"
68+
} else {
69+
java.srcDirs += "src/oldarch"
70+
}
71+
}
72+
}
73+
6374
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
6475

6576
defaultConfig {

android/src/main/java/com/elementary/ElementaryModule.kt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import com.facebook.react.bridge.ReactApplicationContext
44
import com.facebook.react.bridge.ReactContextBaseJavaModule
55
import com.facebook.react.bridge.ReactMethod
66
import com.facebook.react.bridge.Promise
7+
import com.facebook.react.bridge.WritableMap
8+
import com.facebook.react.modules.core.DeviceEventManagerModule
79

810
class ElementaryModule(reactContext: ReactApplicationContext) :
911
ReactContextBaseJavaModule(reactContext) {
@@ -13,15 +15,36 @@ class ElementaryModule(reactContext: ReactApplicationContext) :
1315
}
1416

1517
@ReactMethod
16-
fun getSampleRate(number: Double, promise: Promise) {
18+
fun getSampleRate(promise: Promise) {
1719
promise.resolve(nativeGetSampleRate())
1820
}
1921

20-
@ReactMethod
22+
@ReactMethod
2123
fun applyInstructions(message: String) {
2224
nativeApplyInstructions(message)
2325
}
2426

27+
@ReactMethod
28+
fun addListener(eventName: String) {
29+
// No-op, RN handles subscription tracking
30+
}
31+
32+
@ReactMethod
33+
fun removeListeners(count: Double) {
34+
// No-op
35+
}
36+
37+
// Helper to emit events
38+
private fun sendEvent(eventName: String, params: WritableMap?) {
39+
reactApplicationContext
40+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
41+
.emit(eventName, params)
42+
}
43+
44+
fun emitAudioPlaybackFinished() {
45+
sendEvent("AudioPlaybackFinished", null)
46+
}
47+
2548
companion object {
2649
const val NAME = "Elementary"
2750
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.elementary;
2+
3+
import androidx.annotation.NonNull;
4+
import com.facebook.react.bridge.ReactApplicationContext;
5+
import com.facebook.react.bridge.Promise;
6+
import com.elementary.NativeElementarySpec;
7+
8+
public class ElementaryTurboModule extends NativeElementarySpec {
9+
private final ElementaryModule module;
10+
11+
public ElementaryTurboModule(ReactApplicationContext reactContext) {
12+
super(reactContext);
13+
module = new ElementaryModule(reactContext);
14+
}
15+
16+
@Override
17+
public void getSampleRate(Promise promise) {
18+
module.getSampleRate(promise);
19+
}
20+
21+
@Override
22+
public void applyInstructions(String message) {
23+
module.applyInstructions(message);
24+
}
25+
26+
@Override
27+
public void addListener(String eventName) {
28+
module.addListener(eventName);
29+
}
30+
31+
@Override
32+
public void removeListeners(double count) {
33+
module.removeListeners(count);
34+
}
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.elementary;
2+
3+
import androidx.annotation.Nullable;
4+
import com.facebook.react.bridge.NativeModule;
5+
import com.facebook.react.bridge.ReactApplicationContext;
6+
import com.facebook.react.module.model.ReactModuleInfo;
7+
import com.facebook.react.module.model.ReactModuleInfoProvider;
8+
import com.facebook.react.TurboReactPackage;
9+
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
public class ElementaryTurboPackage extends TurboReactPackage {
14+
@Nullable
15+
@Override
16+
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
17+
if (name.equals(ElementaryModule.NAME)) {
18+
return new ElementaryTurboModule(reactContext);
19+
} else {
20+
return null;
21+
}
22+
}
23+
24+
@Override
25+
public ReactModuleInfoProvider getReactModuleInfoProvider() {
26+
return () -> {
27+
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
28+
moduleInfos.put(
29+
ElementaryModule.NAME,
30+
new ReactModuleInfo(
31+
ElementaryModule.NAME,
32+
ElementaryModule.NAME,
33+
false, // canOverrideExistingModule
34+
false, // needsEagerInit
35+
true, // hasConstants
36+
false, // isCxxModule
37+
true // isTurboModule
38+
)
39+
);
40+
return moduleInfos;
41+
};
42+
}
43+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.elementary;
2+
3+
import androidx.annotation.NonNull;
4+
import com.facebook.react.ReactPackage;
5+
import com.facebook.react.bridge.NativeModule;
6+
import com.facebook.react.bridge.ReactApplicationContext;
7+
import com.facebook.react.uimanager.ViewManager;
8+
9+
import java.util.ArrayList;
10+
import java.util.Collections;
11+
import java.util.List;
12+
13+
public class ElementaryTurboPackage implements ReactPackage {
14+
@NonNull
15+
@Override
16+
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
17+
List<NativeModule> modules = new ArrayList<>();
18+
modules.add(new ElementaryModule(reactContext));
19+
return modules;
20+
}
21+
22+
@NonNull
23+
@Override
24+
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
25+
return Collections.emptyList();
26+
}
27+
}

0 commit comments

Comments
 (0)