diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..04d5d0ad
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,26 @@
+# Config for clang-format version 18
+
+# Standard
+BasedOnStyle: llvm
+Standard: c++14
+
+# Indentation
+IndentWidth: 2
+ColumnLimit: 140
+
+# Includes
+SortIncludes: CaseSensitive
+SortUsingDeclarations: true
+
+# Pointer and reference alignment
+PointerAlignment: Left
+ReferenceAlignment: Left
+ReflowComments: true
+
+# Line breaking options
+BreakBeforeBraces: Attach
+BreakConstructorInitializers: BeforeColon
+AlwaysBreakTemplateDeclarations: true
+AllowShortFunctionsOnASingleLine: Empty
+IndentCaseLabels: true
+NamespaceIndentation: Inner
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
index d402f3d5..92578f4a 100644
--- a/.github/actions/setup/action.yml
+++ b/.github/actions/setup/action.yml
@@ -2,12 +2,13 @@ name: Setup
description: Setup Node.js and install dependencies
runs:
+ defaults:
+ run:
+ working-directory: package
using: composite
steps:
- name: Setup Node.js
uses: actions/setup-node@v3
- with:
- node-version-file: .nvmrc
- name: Cache dependencies
id: yarn-cache
diff --git a/.github/workflows/build-android.yml b/.github/workflows/build-android.yml
index 1b017ad7..5feda376 100644
--- a/.github/workflows/build-android.yml
+++ b/.github/workflows/build-android.yml
@@ -6,37 +6,42 @@ on:
- main
paths:
- '.github/workflows/build-android.yml'
- - 'android/**'
- - 'cpp/**'
- - 'example/android/**'
- - 'yarn.lock'
- - 'example/yarn.lock'
+ - 'package/android/**'
+ - 'package/cpp/**'
+ - 'package/example/android/**'
+ - 'package/yarn.lock'
+ - 'package/example/yarn.lock'
pull_request:
paths:
- '.github/workflows/build-android.yml'
- - 'android/**'
- - 'cpp/**'
- - 'example/android/**'
- - 'yarn.lock'
- - 'example/yarn.lock'
+ - 'package/android/**'
+ - 'package/cpp/**'
+ - 'package/example/android/**'
+ - 'package/yarn.lock'
+ - 'package/example/yarn.lock'
jobs:
build_example:
name: Build Android Example App
runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: package/
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- - name: Setup JDK 11
- uses: actions/setup-java@v1
+ - name: Setup JDK 17
+ uses: actions/setup-java@v4
with:
- java-version: 11
+ distribution: 'zulu'
+ java-version: 17
+ java-package: jdk
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Restore node_modules from cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@@ -49,7 +54,7 @@ jobs:
run: yarn install --frozen-lockfile --cwd example
- name: Restore Gradle cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: |
~/.gradle/caches
diff --git a/.github/workflows/build-ios.yml b/.github/workflows/build-ios.yml
index 6b82feba..f88fca17 100644
--- a/.github/workflows/build-ios.yml
+++ b/.github/workflows/build-ios.yml
@@ -6,67 +6,67 @@ on:
- main
paths:
- '.github/workflows/build-ios.yml'
- - 'ios/**'
- - 'cpp/**'
- - '*.podspec'
- - 'example/ios/**'
+ - 'package/cpp/**'
+ - 'package/ios/**'
+ - 'package/*.podspec'
+ - 'package/example/ios/**'
pull_request:
paths:
- '.github/workflows/build-ios.yml'
- - 'ios/**'
- - 'cpp/**'
- - '*.podspec'
- - 'example/ios/**'
+ - 'package/cpp/**'
+ - 'package/ios/**'
+ - 'package/*.podspec'
+ - 'package/example/ios/**'
jobs:
- build:
+ build_example:
name: Build iOS Example App
runs-on: macOS-latest
defaults:
run:
- working-directory: example/ios
+ working-directory: package/example/ios
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- name: Restore node_modules from cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- - name: Install node_modules for root
+ - name: Install node_modules
run: yarn install --frozen-lockfile --cwd ../..
- name: Install node_modules for example/
run: yarn install --frozen-lockfile --cwd ..
- name: Restore buildcache
- uses: mikehardy/buildcache-action@v1
+ uses: mikehardy/buildcache-action@v2
continue-on-error: true
- name: Setup Ruby (bundle)
uses: ruby/setup-ruby@v1
with:
- ruby-version: '2.7.6'
+ ruby-version: 2.6
bundler-cache: true
- working-directory: example
+ working-directory: package/example/ios
- name: Restore Pods cache
- uses: actions/cache@v2
+ uses: actions/cache@v4
with:
path: |
- example/ios/Pods
+ package/example/ios/Pods
~/Library/Caches/CocoaPods
~/.cocoapods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Install Pods
- run: bundle exec pod check || bundle exec pod install
+ run: yarn pods
- name: Install xcpretty
run: gem install xcpretty
- name: Build App
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
deleted file mode 100644
index 9c5ee1fa..00000000
--- a/.github/workflows/ci.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-name: CI
-on:
- push:
- branches:
- - main
- pull_request:
- branches:
- - main
-
-jobs:
- lint:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - name: Setup
- uses: ./.github/actions/setup
-
- - name: Lint files
- run: yarn lint
-
- - name: Typecheck files
- run: yarn typecheck
-
- test:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - name: Setup
- uses: ./.github/actions/setup
-
- - name: Run unit tests
- run: yarn test --maxWorkers=2 --coverage
-
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v3
-
- - name: Setup
- uses: ./.github/actions/setup
-
- - name: Build package
- run: yarn prepack
diff --git a/.github/workflows/validate-cpp.yml b/.github/workflows/validate-cpp.yml
new file mode 100644
index 00000000..5caeaade
--- /dev/null
+++ b/.github/workflows/validate-cpp.yml
@@ -0,0 +1,35 @@
+name: Validate C++
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - ".github/workflows/validate-cpp.yml"
+ - "package/cpp/**"
+ - "package/android/src/main/cpp/**"
+ - "package/ios/**"
+ pull_request:
+ paths:
+ - ".github/workflows/validate-cpp.yml"
+ - "package/cpp/**"
+ - "package/android/src/main/cpp/**"
+ - "package/ios/**"
+
+jobs:
+ lint:
+ name: Check clang-format
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ path:
+ - "package/cpp"
+ - "package/android/src/main/cpp"
+ - "package/ios"
+ steps:
+ - uses: actions/checkout@v4
+ - name: Run clang-format style check
+ uses: DoozyX/clang-format-lint-action@v0.18.2
+ with:
+ source: ${{ matrix.path }}
+ clangFormatVersion: 18.1.8
diff --git a/.github/workflows/validate-js.yml b/.github/workflows/validate-js.yml
new file mode 100644
index 00000000..def75e06
--- /dev/null
+++ b/.github/workflows/validate-js.yml
@@ -0,0 +1,135 @@
+name: Validate JS
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - '.github/workflows/validate-js.yml'
+ - 'package/src/**'
+ - 'package/*.json'
+ - 'package/*.js'
+ - 'package/*.lock'
+ - 'package/example/src/**'
+ - 'package/example/*.json'
+ - 'package/example/*.js'
+ - 'package/example/*.lock'
+ - 'package/example/*.tsx'
+ pull_request:
+ paths:
+ - '.github/workflows/validate-js.yml'
+ - 'package/src/**'
+ - 'package/*.json'
+ - 'package/*.js'
+ - 'package/*.lock'
+ - 'package/example/src/**'
+ - 'package/example/*.json'
+ - 'package/example/*.js'
+ - 'package/example/*.lock'
+ - 'package/example/*.tsx'
+
+jobs:
+ compile:
+ name: Compile JS (tsc)
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: package/
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install reviewdog
+ uses: reviewdog/action-setup@v1
+
+ - name: Get yarn cache directory path
+ id: yarn-cache-dir-path
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+ - name: Restore node_modules from cache
+ uses: actions/cache@v4
+ id: yarn-cache
+ with:
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: Install node_modules
+ run: yarn install --frozen-lockfile
+ - name: Install node_modules (example/)
+ run: yarn install --frozen-lockfile --cwd example
+
+ - name: Run TypeScript # Reviewdog tsc errorformat: %f:%l:%c - error TS%n: %m
+ run: |
+ yarn typescript | reviewdog -name="tsc" -efm="%f(%l,%c): error TS%n: %m" -reporter="github-pr-review" -filter-mode="nofilter" -fail-on-error -tee
+ env:
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Run TypeScript in example/ # Reviewdog tsc errorformat: %f:%l:%c - error TS%n: %m
+ run: |
+ cd example && yarn typescript | reviewdog -name="tsc" -efm="%f(%l,%c): error TS%n: %m" -reporter="github-pr-review" -filter-mode="nofilter" -fail-on-error -tee && cd ..
+ env:
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ lint:
+ name: Lint JS (eslint, prettier)
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: package/
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Get yarn cache directory path
+ id: yarn-cache-dir-path
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+ - name: Restore node_modules from cache
+ uses: actions/cache@v4
+ id: yarn-cache
+ with:
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: Install node_modules
+ run: yarn install --frozen-lockfile
+ - name: Install node_modules (example/)
+ run: yarn install --frozen-lockfile --cwd example
+
+ - name: Run ESLint
+ run: yarn lint -f @jamesacarr/github-actions
+
+ - name: Run ESLint with auto-fix
+ run: yarn lint --fix
+
+ - name: Verify no files have changed after auto-fix
+ run: git diff --exit-code HEAD
+
+ test:
+ name: Test JS
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: package/
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Get yarn cache directory path
+ id: yarn-cache-dir-path
+ run: echo "::set-output name=dir::$(yarn cache dir)"
+ - name: Restore node_modules from cache
+ uses: actions/cache@v4
+ id: yarn-cache
+ with:
+ path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
+ key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
+ restore-keys: |
+ ${{ runner.os }}-yarn-
+
+ - name: Install node_modules
+ run: yarn install --frozen-lockfile
+ - name: Install node_modules (example/)
+ run: yarn install --frozen-lockfile --cwd example
+
+ - name: Run Jest
+ run: yarn test --maxWorkers=2 --coverage
diff --git a/.gitignore b/.gitignore
index 75356714..068ed1ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,70 +1,6 @@
-# OSX
-#
-.DS_Store
-
-# XDE
-.expo/
-
-# VSCode
-.vscode/
-jsconfig.json
-
-# Xcode
-#
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-xcuserdata
-*.xccheckout
-*.moved-aside
-DerivedData
-*.hmap
-*.ipa
-*.xcuserstate
-project.xcworkspace
-
-# Android/IJ
-#
-.classpath
-.cxx
-.gradle
-.idea
-.project
-.settings
-local.properties
-android.iml
-
-# Cocoapods
-#
-example/ios/Pods
-
-# Ruby
-example/vendor/
-
-# node.js
-#
-node_modules/
-npm-debug.log
-yarn-debug.log
-yarn-error.log
-
-# BUCK
-buck-out/
-\.buckd/
-android/app/libs
-android/keystores/debug.keystore
-
-# Expo
-.expo/
-
-# Turborepo
-.turbo/
-
-# generated by bob
-lib/
+/example
+/lib
+/node_modules
+/react-native-worklets
+.xcode.env.*
+.DS_Store
\ No newline at end of file
diff --git a/.nvmrc b/.nvmrc
deleted file mode 100644
index 5397c87f..00000000
--- a/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-16.18.1
diff --git a/.yarnrc b/.yarnrc
deleted file mode 100644
index fedc0f11..00000000
--- a/.yarnrc
+++ /dev/null
@@ -1,3 +0,0 @@
-# Override Yarn command so we can automatically setup the repo on running `yarn`
-
-yarn-path "scripts/bootstrap.js"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 24e2b87c..0db7daaf 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -66,7 +66,7 @@ Note the `"fabric":true` and `"concurrentRoot":true` properties.
Make sure your code passes TypeScript and ESLint. Run the following to verify:
```sh
-yarn typecheck
+yarn typescript
yarn lint
```
@@ -119,7 +119,7 @@ yarn release
The `package.json` file contains various scripts for common tasks:
- `yarn bootstrap`: setup project by installing all dependencies and pods.
-- `yarn typecheck`: type-check files with TypeScript.
+- `yarn typescript`: type-check files with TypeScript.
- `yarn lint`: lint files with ESLint.
- `yarn test`: run unit tests with Jest.
- `yarn example start`: start the Metro server for the example app.
diff --git a/README.md b/README.md
index 2b573126..f487cefc 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,9 @@
-
+
+
+
+
+
# 🧵 react-native-worklets-core
@@ -13,9 +17,6 @@ const worklet = () => {
}
```
-> [!NOTE]
-> In most cases, react-native-worklets-core shouldn't be used as a standalone dependency but rather as a peer-dependency for other modules such as [react-native-vision-camera](https://github.com/mrousavy/react-native-vision-camera), [react-native-wishlist](https://github.com/margelo/react-native-wishlist), or [react-native-skia](https://github.com/Shopify/react-native-skia).
-
## Installation
1. Install the library from npm:
@@ -37,6 +38,10 @@ const worklet = () => {
yarn start --reset-cache
```
+## Requirements
+
+- Requires react-native 0.75 or higher
+
## Usage
See [USAGE.md](docs/USAGE.md)
diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt
deleted file mode 100644
index 52fdbe3c..00000000
--- a/android/CMakeLists.txt
+++ /dev/null
@@ -1,96 +0,0 @@
-project("rnworklets")
-cmake_minimum_required(VERSION 3.8)
-
-set(CMAKE_VERBOSE_MAKEFILE ON)
-set(CMAKE_CXX_STANDARD 17)
-
-if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
- string(APPEND CMAKE_CXX_FLAGS " -DDEBUG")
-endif()
-
-set(PACKAGE_NAME "rnworklets")
-
-
-# Pre-set Folly flags from React Native core
-include("${REACT_NATIVE_DIR}/ReactAndroid/cmake-utils/folly-flags.cmake")
-add_compile_options(${folly_FLAGS})
-
-# Consume shared libraries and headers from prefabs
-find_package(fbjni REQUIRED CONFIG)
-find_package(ReactAndroid REQUIRED CONFIG)
-
-if(${JS_RUNTIME} STREQUAL "hermes")
- find_package(hermes-engine REQUIRED CONFIG)
-endif()
-
-file(GLOB_RECURSE SOURCES_COMMON CONFIGURE_DEPENDS "../cpp/**.cpp")
-
-add_library(
- ${PACKAGE_NAME}
- SHARED
- ${SOURCES_COMMON}
- cpp-adapter.cpp
-)
-
-# includes
-target_include_directories(
- ${PACKAGE_NAME}
- PRIVATE
- ../cpp
- ../cpp/base
- ../cpp/decorators
- ../cpp/dispatch
- ../cpp/sharedvalues
- ../cpp/wrappers
- "${REACT_NATIVE_DIR}/ReactAndroid/src/main/jni/react/turbomodule"
- "${REACT_NATIVE_DIR}/ReactCommon"
- "${REACT_NATIVE_DIR}/ReactCommon/callinvoker"
- "${REACT_NATIVE_DIR}/ReactCommon/runtimeexecutor"
-)
-
-# build shared lib
-set_target_properties(${PACKAGE_NAME} PROPERTIES LINKER_LANGUAGE CXX)
-
-target_link_libraries(
- ${PACKAGE_NAME}
- log
- android
-)
-
-target_link_libraries(
- ${PACKAGE_NAME}
- ReactAndroid::folly_runtime
- ReactAndroid::glog
- ReactAndroid::jsi
- ReactAndroid::reactnativejni
- fbjni::fbjni
-)
-
-if(${JS_RUNTIME} STREQUAL "hermes")
- string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_HERMES=1")
-
- # From prefab from module `com.facebook.react:hermes-android`
- set(HERMES_LIB hermes-engine::libhermes)
-
- target_link_libraries(
- ${PACKAGE_NAME}
- ${HERMES_LIB}
- )
-
- if(${HERMES_ENABLE_DEBUGGER})
- set(HERMES_EXECUTOR_LIB ReactAndroid::hermes_executor)
-
- target_link_libraries(
- ${PACKAGE_NAME}
- ${HERMES_EXECUTOR_LIB}
- )
- endif()
-elseif(${JS_RUNTIME} STREQUAL "jsc")
- string(APPEND CMAKE_CXX_FLAGS " -DJS_RUNTIME_JSC=1")
-
- set(JSEXECUTOR_LIB ReactAndroid::jscexecutor)
-
- target_link_libraries(${PACKAGE_NAME} ${JSEXECUTOR_LIB})
-else()
- message(FATAL_ERROR "Unknown JS runtime ${JS_RUNTIME}.")
-endif()
diff --git a/android/cpp-adapter.cpp b/android/cpp-adapter.cpp
deleted file mode 100644
index ea6a539c..00000000
--- a/android/cpp-adapter.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include
-
-#include
-#include
-
-#include "WKTJsiWorkletApi.h"
-
-using namespace facebook; // NOLINT
-
-extern "C" JNIEXPORT jboolean JNICALL
-Java_com_worklets_WorkletsModule_nativeInstall(JNIEnv* env, jclass obj, jlong jsiRuntimeRef, jobject jsCallInvokerHolder)
-{
- auto jsiRuntime{ reinterpret_cast(jsiRuntimeRef) };
- auto jsCallInvoker{ jni::alias_ref{ reinterpret_cast(jsCallInvokerHolder) }->cthis()->getCallInvoker() };
-
- RNWorklet::JsiWorkletContext::getDefaultInstance()->initialize(
- "default", jsiRuntime, [=](std::function &&f) {
- jsCallInvoker->invokeAsync(std::move(f));
- });
-
- // Install the worklet API
- RNWorklet::JsiWorkletApi::installApi(*jsiRuntime);
-
- return true;
-}
diff --git a/android/src/main/java/com/worklets/WorkletsModule.java b/android/src/main/java/com/worklets/WorkletsModule.java
deleted file mode 100644
index eef2791a..00000000
--- a/android/src/main/java/com/worklets/WorkletsModule.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.worklets;
-
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.facebook.react.bridge.Promise;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactMethod;
-import com.facebook.react.module.annotations.ReactModule;
-import com.facebook.react.turbomodule.core.CallInvokerHolderImpl;
-import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder;
-
-import java.lang.ref.WeakReference;
-
-@ReactModule(name = WorkletsModule.NAME)
-public class WorkletsModule extends com.worklets.WorkletsSpec {
- public static final String NAME = "Worklets";
- private final WeakReference weakReactContext;
-
- WorkletsModule(ReactApplicationContext context) {
- super(context);
- this.weakReactContext = new WeakReference<>(context);
- }
-
- static {
- System.loadLibrary("rnworklets");
- }
-
- @Override
- @NonNull
- public String getName() {
- return NAME;
- }
-
- public static native boolean nativeInstall(long jsiRuntimeRef, CallInvokerHolder jsCallInvokerHolder);
-
- @ReactMethod(isBlockingSynchronousMethod = true)
- public boolean install() {
- try {
- ReactApplicationContext context = weakReactContext.get();
- if (context == null) {
- Log.e(NAME, "React Application Context was null!");
- return false;
- }
-
- long jsiRuntimeRef = context.getJavaScriptContextHolder().get();
- CallInvokerHolder jsCallInvokerHolder = context.getCatalystInstance().getJSCallInvokerHolder();
- return nativeInstall(jsiRuntimeRef, jsCallInvokerHolder);
- } catch (Exception exception) {
- Log.e(NAME, "Failed to initialize react-native-worklets-core!", exception);
- return false;
- }
- }
-}
diff --git a/android/src/main/java/com/worklets/WorkletsPackage.java b/android/src/main/java/com/worklets/WorkletsPackage.java
deleted file mode 100644
index 8c6393ce..00000000
--- a/android/src/main/java/com/worklets/WorkletsPackage.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.worklets;
-
-import androidx.annotation.Nullable;
-
-import com.facebook.react.bridge.NativeModule;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.module.annotations.ReactModule;
-import com.facebook.react.module.model.ReactModuleInfo;
-import com.facebook.react.module.model.ReactModuleInfoProvider;
-import com.facebook.react.TurboReactPackage;
-import com.facebook.react.turbomodule.core.interfaces.TurboModule;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class WorkletsPackage extends TurboReactPackage {
-
- @Nullable
- @Override
- public NativeModule getModule(String name, ReactApplicationContext reactContext) {
- if (name.equals(WorkletsModule.NAME)) {
- return new WorkletsModule(reactContext);
- } else {
- return null;
- }
- }
-
- @Override
- public ReactModuleInfoProvider getReactModuleInfoProvider() {
- return () -> {
- final Map moduleInfos = new HashMap<>();
- Class extends NativeModule> moduleClass = WorkletsModule.class;
- ReactModule reactModule = moduleClass.getAnnotation(ReactModule.class);
- moduleInfos.put(
- reactModule.name(),
- new ReactModuleInfo(
- reactModule.name(),
- moduleClass.getName(),
- true,
- reactModule.needsEagerInit(),
- reactModule.hasConstants(),
- reactModule.isCxxModule(),
- TurboModule.class.isAssignableFrom(moduleClass)));
- return moduleInfos;
- };
- }
-}
diff --git a/android/src/newarch/WorkletsSpec.java b/android/src/newarch/WorkletsSpec.java
deleted file mode 100644
index 62516704..00000000
--- a/android/src/newarch/WorkletsSpec.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package com.worklets;
-
-import com.facebook.react.bridge.ReactApplicationContext;
-
-abstract class WorkletsSpec extends NativeWorkletsSpec {
- WorkletsSpec(ReactApplicationContext context) {
- super(context);
- }
-}
diff --git a/android/src/oldarch/WorkletsSpec.java b/android/src/oldarch/WorkletsSpec.java
deleted file mode 100644
index 158cd55d..00000000
--- a/android/src/oldarch/WorkletsSpec.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.worklets;
-
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactContextBaseJavaModule;
-import com.facebook.react.bridge.Promise;
-
-abstract class WorkletsSpec extends ReactContextBaseJavaModule {
- WorkletsSpec(ReactApplicationContext context) {
- super(context);
- }
-
- public abstract boolean install();
-}
diff --git a/babel.config.js b/babel.config.js
deleted file mode 100644
index 5ae49c32..00000000
--- a/babel.config.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- presets: ["module:metro-react-native-babel-preset"],
-};
diff --git a/cpp/WKTJsiWorkletContext.cpp b/cpp/WKTJsiWorkletContext.cpp
deleted file mode 100644
index 9503d586..00000000
--- a/cpp/WKTJsiWorkletContext.cpp
+++ /dev/null
@@ -1,489 +0,0 @@
-
-#include "WKTJsiWorkletContext.h"
-#include "WKTJsiWorkletApi.h"
-#include "WKTRuntimeAwareCache.h"
-
-#include "WKTArgumentsWrapper.h"
-#include "WKTDispatchQueue.h"
-#include "WKTJsRuntimeFactory.h"
-#include "WKTJsiHostObject.h"
-#include "WKTJsiPromiseWrapper.h"
-
-#include "WKTJsiConsoleDecorator.h"
-#include "WKTJsiJsDecorator.h"
-#include "WKTJsiPerformanceDecorator.h"
-#include "WKTJsiSetImmediateDecorator.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#ifdef ANDROID
-#include
-#endif
-
-namespace RNWorklet {
-
-const char *WorkletRuntimeFlag = "__rn_worklets_runtime_flag";
-const char *GlobalPropertyName = "global";
-
-std::shared_ptr JsiWorkletContext::defaultInstance;
-std::map JsiWorkletContext::runtimeMappings;
-size_t JsiWorkletContext::contextIdNumber = 1000;
-
-namespace jsi = facebook::jsi;
-
-JsiWorkletContext::JsiWorkletContext(const std::string &name) {
- // Initialize context
- initialize(name, JsiWorkletContext::getDefaultInstance()->_jsRuntime,
- JsiWorkletContext::getDefaultInstance()->_jsCallInvoker);
-}
-
-JsiWorkletContext::JsiWorkletContext(
- const std::string &name,
- std::function &&)> workletCallInvoker) {
- // Initialize context
- initialize(name, JsiWorkletContext::getDefaultInstance()->_jsRuntime,
- JsiWorkletContext::getDefaultInstance()->_jsCallInvoker,
- workletCallInvoker);
-}
-
-JsiWorkletContext::JsiWorkletContext(
- const std::string &name, jsi::Runtime *jsRuntime,
- std::function &&)> jsCallInvoker,
- std::function &&)> workletCallInvoker) {
- // Initialize context
- initialize(name, jsRuntime, jsCallInvoker, workletCallInvoker);
-}
-
-JsiWorkletContext::~JsiWorkletContext() {
- // Remove from thread contexts
- runtimeMappings.erase(&_workletRuntime);
-}
-
-void JsiWorkletContext::initialize(
- const std::string &name, jsi::Runtime *jsRuntime,
- std::function &&)> jsCallInvoker,
- std::function &&)> workletCallInvoker) {
-
- _name = name;
- _jsRuntime = jsRuntime;
- _jsCallInvoker = jsCallInvoker;
- _workletCallInvoker = workletCallInvoker;
- _contextId = ++contextIdNumber;
-
- _jsThreadId = std::this_thread::get_id();
- runtimeMappings.emplace(&getWorkletRuntime(), this);
-
- // Add default decorators
- addDecorator(std::make_shared());
- addDecorator(std::make_shared());
- addDecorator(std::make_shared());
-}
-
-void JsiWorkletContext::initialize(
- const std::string &name, jsi::Runtime *jsRuntime,
- std::function &&)> jsCallInvoker) {
- // Create queue
- auto dispatchQueue = std::make_shared(
- name + "_worklet_dispatch_queue_" + std::to_string(_contextId));
-
- // Initialize invoker
- initialize(
- name, jsRuntime, jsCallInvoker,
- [dispatchQueue = std::move(dispatchQueue)](std::function &&f) {
- dispatchQueue->dispatch(std::move(f));
- });
-}
-
-jsi::Runtime &JsiWorkletContext::getWorkletRuntime() {
- if (!_workletRuntime) {
- // Lazy initialization of the worklet runtime
- _workletRuntime = makeJSIRuntime();
- _workletRuntime->global().setProperty(*_workletRuntime, WorkletRuntimeFlag,
- true);
-
- // Copy global which is expected to be found instead of the globalThis
- // object.
- _workletRuntime->global().setProperty(*_workletRuntime, GlobalPropertyName,
- _workletRuntime->global());
-
- // Install the WorkletAPI into the new runtime
- JsiWorkletApi::installApi(*_workletRuntime);
- }
-
- return *_workletRuntime;
-}
-
-void JsiWorkletContext::invokeOnJsThread(
- std::function &&fp) {
- if (_jsCallInvoker == nullptr) {
- throw std::runtime_error(
- "Expected Worklet context to have a JS call invoker.");
- }
- _jsCallInvoker([fp = std::move(fp), weakSelf = weak_from_this()]() {
- auto self = weakSelf.lock();
- if (self) {
- assert(self->_jsThreadId == std::this_thread::get_id());
- fp(*self->getJsRuntime());
- }
- });
-}
-
-void JsiWorkletContext::invokeOnWorkletThread(
- std::function
- &&fp) {
- if (_workletCallInvoker == nullptr) {
- throw std::runtime_error(
- "Expected Worklet context to have a worklet call invoker.");
- }
- _workletCallInvoker([fp = std::move(fp), weakSelf = weak_from_this()]() {
- auto self = weakSelf.lock();
- if (self) {
-#ifdef ANDROID
- facebook::jni::ThreadScope::WithClassLoader([fp = std::move(fp), self]() {
- fp(self.get(), self->getWorkletRuntime());
- });
-#else
- fp(self.get(), self->getWorkletRuntime());
-#endif
- }
- });
-}
-
-void JsiWorkletContext::addDecorator(
- std::shared_ptr decorator) {
- std::mutex mu;
- std::condition_variable cond;
- bool isFinished = false;
- std::unique_lock lock(mu);
-
- decorator->initialize(*getJsRuntime());
-
- // Execute decoration in context' worklet thread/runtime
- _workletCallInvoker([&]() {
- std::lock_guard lock(mu);
- decorator->decorateRuntime(getWorkletRuntime());
- isFinished = true;
- cond.notify_one();
- });
-
- // Wait untill the blocking code as finished
- cond.wait(lock, [&]() { return isFinished; });
-}
-
-jsi::HostFunctionType
-JsiWorkletContext::createCallInContext(jsi::Runtime &runtime,
- const jsi::Value &maybeFunc) {
- return createCallInContext(runtime, maybeFunc, this);
-}
-
-jsi::HostFunctionType
-JsiWorkletContext::createCallInContext(jsi::Runtime &runtime,
- const jsi::Value &maybeFunc,
- JsiWorkletContext *ctx) {
-
- // Ensure that we are passing a function as the param.
- if (!maybeFunc.isObject() ||
- !maybeFunc.asObject(runtime).isFunction(runtime)) {
- throw jsi::JSError(
- runtime,
- "Parameter to callInContext is not a valid Javascript function.");
- }
-
- // Now we can save the function in a shared ptr to be able to keep it around
- auto func = std::make_shared(
- maybeFunc.asObject(runtime).asFunction(runtime));
-
- // Create a worklet of the function if the function is a worklet - it should
- // be allowed to create a caller function and call inside the same JS or ctx
- // without having to pass a worklet
- auto workletInvoker =
- JsiWorklet::isDecoratedAsWorklet(runtime, func)
- ? std::make_shared(runtime, maybeFunc)
- : nullptr;
-
- // Now return the caller function as a hostfunction type.
- return [workletInvoker, func,
- ctx](jsi::Runtime &runtime, const jsi::Value &thisValue,
- const jsi::Value *arguments, size_t count) -> jsi::Value {
- auto callingCtx = getCurrent(runtime);
- auto convention = getCallingConvention(callingCtx, ctx);
-
- // Start by wrapping the arguments
- ArgumentsWrapper argsWrapper(runtime, arguments, count);
-
- // Wrap the this value
- auto thisWrapper = JsiWrapper::wrap(runtime, thisValue);
-
- // If we are calling directly from/to the JS context or within the same
- // context, we can just dispatch everything directly.
- if (convention == CallingConvention::JsToJs ||
- convention == CallingConvention::WithinCtx) {
-
- // Create promise
- auto promise = JsiPromiseWrapper::createPromiseWrapper(
- runtime,
- [ctx, convention, workletInvoker, callingCtx, thisWrapper,
- argsWrapper, func](jsi::Runtime &runtime,
- std::shared_ptr promise) {
- auto unwrappedThis = thisWrapper->unwrap(runtime);
- auto args = argsWrapper.getArguments(runtime);
-
- // We can resolve the result directly - we're in the same context.
- try {
- if (workletInvoker) {
- auto retVal = workletInvoker->call(
- runtime, unwrappedThis, ArgumentsWrapper::toArgs(args),
- argsWrapper.getCount());
- promise->resolve(runtime, retVal);
- } else {
- if (unwrappedThis.isObject()) {
- auto retVal = func->callWithThis(
- runtime, unwrappedThis.asObject(runtime),
- ArgumentsWrapper::toArgs(args), argsWrapper.getCount());
- promise->resolve(runtime, retVal);
- } else {
- auto retVal =
- func->call(runtime, ArgumentsWrapper::toArgs(args),
- argsWrapper.getCount());
- promise->resolve(runtime, retVal);
- }
- }
- } catch (const jsi::JSError &err) {
- // TODO: Handle Stack!!
- promise->reject(runtime, jsi::String::createFromUtf8(
- runtime, err.getMessage()));
- } catch (const std::exception &err) {
- std::string a = typeid(err).name();
- std::string b = typeid(jsi::JSError).name();
- if (a == b) {
- const auto *jsError = static_cast(&err);
- auto message = jsError->getMessage();
- // auto stack = jsError->getStack();
- // TODO: JsErrorWrapper reason(message, stack);
- promise->reject(runtime,
- jsi::String::createFromUtf8(runtime, message));
- } else {
- // TODO: JsErrorWrapper reason("Unknown error in promise",
- // "[Uknown stack]");
- promise->reject(runtime,
- jsi::String::createFromUtf8(
- runtime, "Unknown error in promise"));
- }
- } catch (...) {
- // TODO: JsErrorWrapper reason("Unknown error in promise",
- // "[Uknown stack]");
- promise->reject(runtime,
- jsi::String::createFromUtf8(
- runtime, "Unknown error in promise"));
- }
- });
-
- return jsi::Object::createFromHostObject(runtime, promise);
- }
-
- // Now we are in a situation where we are calling cross context (js -> ctx,
- // ctx -> ctx, ctx -> js)
-
- // Ensure that the function is a worklet
- if (workletInvoker == nullptr && convention != CallingConvention::CtxToJs) {
- throw jsi::JSError(runtime, "In callInContext the function parameter "
- "is not a valid worklet and "
- "cannot be called between contexts or "
- "from/to JS from/to a context.");
- }
-
- auto callIntoCorrectContext =
- [&runtime, convention,
- ctx](std::function &&func) {
- switch (convention) {
- case CallingConvention::JsToCtx:
- case CallingConvention::CtxToCtx:
- ctx->invokeOnWorkletThread(
- [func](JsiWorkletContext *, jsi::Runtime &rt) { func(rt); });
- break;
- case CallingConvention::CtxToJs:
- JsiWorkletContext::getDefaultInstance()->invokeOnJsThread(
- [func](jsi::Runtime &rt) { func(rt); });
- break;
- default:
- // Not used since the two last ones are only handling
- // inter context calling
- throw jsi::JSError(runtime,
- "Should not be reached. Callback into context.");
- }
- };
-
- auto callback = [&runtime, convention, callingCtx,
- ctx](std::function &&func) {
- // Always resolve in the calling context or the JS context if null
- if (callingCtx == nullptr) {
- JsiWorkletContext::getDefaultInstance()->invokeOnJsThread(
- [func](jsi::Runtime &rt) { func(rt); });
- } else {
- callingCtx->invokeOnWorkletThread(
- [func](JsiWorkletContext *, jsi::Runtime &rt) { func(rt); });
- }
- };
-
- // Let's create a promise that can initialize and resolve / reject in the
- // correct contexts
- auto promise = JsiPromiseWrapper::createPromiseWrapper(
- runtime, [ctx, workletInvoker, convention, callingCtx, thisWrapper,
- argsWrapper, callIntoCorrectContext, callback,
- func](jsi::Runtime &runtime,
- std::shared_ptr promise) {
- // Create callback wrapper
- callIntoCorrectContext([callback, workletInvoker, thisWrapper,
- argsWrapper, promise,
- func](jsi::Runtime &runtime) mutable {
- try {
-
- auto args = argsWrapper.getArguments(runtime);
-
- jsi::Value result;
- if (workletInvoker != nullptr) {
- result = workletInvoker->call(
- runtime, thisWrapper->unwrap(runtime),
- ArgumentsWrapper::toArgs(args), argsWrapper.getCount());
- } else {
- result = func->call(runtime, ArgumentsWrapper::toArgs(args),
- argsWrapper.getCount());
- }
-
- auto retVal = JsiWrapper::wrap(runtime, result);
-
- // Callback with the results
- callback([retVal, promise](jsi::Runtime &runtime) {
- promise->resolve(runtime, retVal->unwrap(runtime));
- });
- } catch (const jsi::JSError &err) {
- auto message = err.getMessage();
- auto stack = err.getStack();
- // TODO: Stack
- callback([message, stack, promise](jsi::Runtime &runtime) {
- promise->reject(runtime,
- jsi::String::createFromUtf8(runtime, message));
- });
- } catch (const std::exception &err) {
- std::string a = typeid(err).name();
- std::string b = typeid(jsi::JSError).name();
- if (a == b) {
- const auto *jsError = static_cast(&err);
- auto message = jsError->getMessage();
- auto stack = jsError->getStack();
- // TODO: Stack
- callback([message, stack, promise](jsi::Runtime &runtime) {
- promise->reject(
- runtime, jsi::String::createFromUtf8(runtime, message));
- });
- } else {
- // TODO: Stack
- callback([err, promise](jsi::Runtime &runtime) {
- promise->reject(runtime, jsi::String::createFromUtf8(
- runtime, err.what()));
- });
- }
- } catch (...) {
- callback([promise](jsi::Runtime &runtime) {
- // TODO: Handle Stack!!
- promise->reject(runtime,
- jsi::String::createFromUtf8(
- runtime, "Unknown error in promise."));
- });
- }
-
- // We need to explicitly clear the func shared pointer here to avoid it being
- // deleted on another thread
- promise = nullptr;
- });
- });
-
- return jsi::Object::createFromHostObject(runtime, promise);
- };
-}
-
-jsi::HostFunctionType
-JsiWorkletContext::createInvoker(jsi::Runtime &runtime,
- const jsi::Value *maybeFunc) {
- auto rtPtr = &runtime;
- auto ctx = JsiWorkletContext::getCurrent(runtime);
-
- // Create host function
- return [rtPtr, ctx,
- func = std::make_shared(
- maybeFunc->asObject(runtime).asFunction(runtime))](
- jsi::Runtime &runtime, const jsi::Value &thisValue,
- const jsi::Value *arguments, size_t count) {
- // If we are in the same context let's just call the function directly
- if (&runtime == rtPtr) {
- return func->call(runtime, arguments, count);
- }
-
- // We're about to cross contexts and will need to wrap args
- auto thisWrapper = JsiWrapper::wrap(runtime, thisValue);
- ArgumentsWrapper argsWrapper(runtime, arguments, count);
-
- if (ctx != nullptr) {
- // We are on a worklet thread
- ctx->invokeOnWorkletThread(
- [argsWrapper, rtPtr, func = std::move(func)](JsiWorkletContext *,
- jsi::Runtime &runtime) mutable {
- assert(&runtime == rtPtr && "Expected same runtime ptr!");
- auto args = argsWrapper.getArguments(runtime);
- func->call(runtime, ArgumentsWrapper::toArgs(args),
- argsWrapper.getCount());
- func = nullptr;
- });
- } else {
- JsiWorkletContext::getDefaultInstance()->invokeOnJsThread(
- [argsWrapper, rtPtr, func = std::move(func)](jsi::Runtime &runtime) mutable {
- assert(&runtime == rtPtr && "Expected same runtime ptr!");
- auto args = argsWrapper.getArguments(runtime);
- func->call(runtime, ArgumentsWrapper::toArgs(args),
- argsWrapper.getCount());
- func = nullptr;
- });
- }
-
- return jsi::Value::undefined();
- };
-}
-
-JsiWorkletContext::CallingConvention
-JsiWorkletContext::getCallingConvention(JsiWorkletContext *fromContext,
- JsiWorkletContext *toContext) {
-
- if (toContext == nullptr) {
- // Calling into JS
- if (fromContext == nullptr) {
- // Calling from JS
- return CallingConvention::JsToJs;
- } else {
- // Calling from a context
- return CallingConvention::CtxToJs;
- }
- } else {
- // Calling into another ctx
- if (fromContext == nullptr) {
- // Calling from Js
- return CallingConvention::JsToCtx;
- } else {
- // Calling from Ctx
- if (fromContext == toContext) {
- return CallingConvention::WithinCtx;
- } else {
- return CallingConvention::CtxToCtx;
- }
- }
- }
-}
-
-} // namespace RNWorklet
diff --git a/cpp/base/WKTJsiHostObject.h b/cpp/base/WKTJsiHostObject.h
deleted file mode 100644
index ee9c72f9..00000000
--- a/cpp/base/WKTJsiHostObject.h
+++ /dev/null
@@ -1,202 +0,0 @@
-#pragma once
-
-#include
-
-#include "WKTRuntimeAwareCache.h"
-
-#include
-#include