Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .elementaryspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"modules": {
"Elementary": {
"type": "NativeModule",
"methods": {
"getSampleRate": {
"type": "Promise",
"returnType": "number"
},
"applyInstructions": {
"type": "method",
"arguments": [
{
"name": "message",
"type": "string"
}
]
}
}
}
}
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '11'
java-version: '17'

- name: Finalize Android SDK
if: env.turbo_cache_hit != 1
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ android.iml
# Cocoapods
#
example/ios/Pods
example_old/ios/Pods

# Ruby
example/vendor/
example_old/vendor/

# node.js
#
Expand All @@ -62,6 +64,8 @@ android/keystores/debug.keystore

# Expo
.expo/
example-expo/ios/
example-expo/android/

# Turborepo
.turbo/
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v18
v20
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.1.0
11 changes: 11 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ android {
}
}

// Include arch-specific source sets
sourceSets {
main {
if (isNewArchitectureEnabled()) {
java.srcDirs += "src/newarch"
} else {
java.srcDirs += "src/oldarch"
}
}
}

compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")

defaultConfig {
Expand Down
27 changes: 25 additions & 2 deletions android/src/main/java/com/elementary/ElementaryModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.WritableMap
import com.facebook.react.modules.core.DeviceEventManagerModule

class ElementaryModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {
Expand All @@ -13,15 +15,36 @@ class ElementaryModule(reactContext: ReactApplicationContext) :
}

@ReactMethod
fun getSampleRate(number: Double, promise: Promise) {
fun getSampleRate(promise: Promise) {
promise.resolve(nativeGetSampleRate())
}

@ReactMethod
@ReactMethod
fun applyInstructions(message: String) {
nativeApplyInstructions(message)
}

@ReactMethod
fun addListener(eventName: String) {
// No-op, RN handles subscription tracking
}

@ReactMethod
fun removeListeners(count: Double) {
// No-op
}

// Helper to emit events
private fun sendEvent(eventName: String, params: WritableMap?) {
reactApplicationContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
.emit(eventName, params)
}

fun emitAudioPlaybackFinished() {
sendEvent("AudioPlaybackFinished", null)
}

companion object {
const val NAME = "Elementary"
}
Expand Down
35 changes: 35 additions & 0 deletions android/src/newarch/com/elementary/ElementaryTurboModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.elementary;

import androidx.annotation.NonNull;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.Promise;
import com.elementary.NativeElementarySpec;

public class ElementaryTurboModule extends NativeElementarySpec {
private final ElementaryModule module;

public ElementaryTurboModule(ReactApplicationContext reactContext) {
super(reactContext);
module = new ElementaryModule(reactContext);
}

@Override
public void getSampleRate(Promise promise) {
module.getSampleRate(promise);
}

@Override
public void applyInstructions(String message) {
module.applyInstructions(message);
}

@Override
public void addListener(String eventName) {
module.addListener(eventName);
}

@Override
public void removeListeners(double count) {
module.removeListeners(count);
}
}
43 changes: 43 additions & 0 deletions android/src/newarch/com/elementary/ElementaryTurboPackage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.elementary;

import androidx.annotation.Nullable;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.TurboReactPackage;

import java.util.HashMap;
import java.util.Map;

public class ElementaryTurboPackage extends TurboReactPackage {
@Nullable
@Override
public NativeModule getModule(String name, ReactApplicationContext reactContext) {
if (name.equals(ElementaryModule.NAME)) {
return new ElementaryTurboModule(reactContext);
} else {
return null;
}
}

@Override
public ReactModuleInfoProvider getReactModuleInfoProvider() {
return () -> {
final Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
moduleInfos.put(
ElementaryModule.NAME,
new ReactModuleInfo(
ElementaryModule.NAME,
ElementaryModule.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
true, // hasConstants
false, // isCxxModule
true // isTurboModule
)
);
return moduleInfos;
};
}
}
27 changes: 27 additions & 0 deletions android/src/oldarch/com/elementary/ElementaryTurboPackage.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.elementary;

import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ElementaryTurboPackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new ElementaryModule(reactContext));
return modules;
}

@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
File renamed without changes.
16 changes: 16 additions & 0 deletions example-expo/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"expo": {
"name": "Elementary Expo Example",
"slug": "example-expo",
"version": "1.0.0",
"newArchEnabled": true,
"ios": {
"bundleIdentifier": "com.elementary.expoexample",
"supportsTablet": true
},
"android": {
"package": "com.elementary.expoexample"
},
"plugins": []
}
}
6 changes: 6 additions & 0 deletions example-expo/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
};
};
4 changes: 4 additions & 0 deletions example-expo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { registerRootComponent } from 'expo';
import App from './App';

registerRootComponent(App);
38 changes: 38 additions & 0 deletions example-expo/metro.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '..');

const config = getDefaultConfig(projectRoot);

// Watch the monorepo root for changes
config.watchFolders = [monorepoRoot];

// Resolve modules from both the example and root node_modules
config.resolver.nodeModulesPaths = [
path.resolve(projectRoot, 'node_modules'),
path.resolve(monorepoRoot, 'node_modules'),
];

config.resolver.resolveRequest = (context, moduleName, platform) => {
// Force react to always come from this project
if (moduleName === 'react' || moduleName.startsWith('react/')) {
return context.resolveRequest(
{ ...context, originModulePath: projectRoot + '/index.ts' },
moduleName,
platform
);
}
// Force react-native to always come from this project
if (moduleName === 'react-native' || moduleName.startsWith('react-native/')) {
return context.resolveRequest(
{ ...context, originModulePath: projectRoot + '/index.ts' },
moduleName,
platform
);
}
return context.resolveRequest(context, moduleName, platform);
};

module.exports = config;
25 changes: 25 additions & 0 deletions example-expo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "example-expo",
"version": "1.0.0",
"main": "index.ts",
"scripts": {
"start": "expo start --dev-client",
"android": "expo run:android",
"ios": "expo run:ios",
"prebuild": "expo prebuild"
},
"dependencies": {
"@elemaudio/core": "^2.0.1",
"expo": "~53.0.0",
"expo-dev-client": "~5.1.0",
"react": "19.0.0",
"react-native": "0.79.2",
"react-native-elementary": "file:.."
},
"devDependencies": {
"@babel/core": "^7.24.0",
"@types/react": "~19.0.10",
"typescript": "~5.3.3"
},
"private": true
}
21 changes: 21 additions & 0 deletions example-expo/react-native.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const path = require('path');
const pkg = require('../package.json');

module.exports = {
project: {
ios: {
automaticPodsInstallation: true,
},
},
dependencies: {
[pkg.name]: {
root: path.join(__dirname, '..'),
platforms: {
// Codegen script incorrectly fails without this
// So we explicitly specify the platforms with empty object
ios: {},
android: {},
},
},
},
};
6 changes: 6 additions & 0 deletions example-expo/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}
Loading