diff --git a/docs/docs/guides/EXPOSURE.mdx b/docs/docs/guides/EXPOSURE.mdx
index 563ea4a402..5ed2c5f4cb 100644
--- a/docs/docs/guides/EXPOSURE.mdx
+++ b/docs/docs/guides/EXPOSURE.mdx
@@ -49,12 +49,12 @@ Just like [`zoom`](zooming), this property can be animated using Reanimated.
return interpolate(exposureSlider.value,
[-1, 0, 1],
[device.minExposure, 0, device.maxExposure])
- }, [exposureSlider, device])
+ })
// 3. pass it as an animated prop
const animatedProps = useAnimatedProps(() => ({
exposure: exposureValue.value
- }), [exposureValue])
+ }))
// 4. render Camera
return (
diff --git a/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx b/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx
index ef8e77964a..a53781fcd2 100644
--- a/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx
+++ b/docs/docs/guides/FRAME_PROCESSORS_CREATE_OVERVIEW.mdx
@@ -21,7 +21,7 @@ function App() {
// highlight-next-line
const faces = detectFaces(frame)
console.log(`Faces in Frame: ${faces}`)
- }, [])
+ })
return (
@@ -91,7 +91,7 @@ const frameProcessor = useFrameProcessor((frame) => {
// by downscaling the frame, the `detectObjects` function runs faster.
const objects = detectObjects(resizedFrame)
console.log(objects)
-}, [])
+})
```
### Parameters
@@ -102,7 +102,7 @@ Frame Processors can also accept parameters, following the same type convention
const frameProcessor = useFrameProcessor((frame) => {
'worklet'
const faces = scanFaces(frame, { accuracy: 'fast' })
-}, [])
+})
```
### Exceptions
@@ -131,7 +131,7 @@ const frameProcessor = useFrameProcessor((frame) => {
} catch (e) {
console.log(`Error: ${e.message}`)
}
-}, [])
+})
```
## What's possible?
@@ -177,7 +177,7 @@ function App() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet'
SomeAI.process(frame) // does not block frame processor, runs async
- }, [])
+ })
useEffect(() => {
SomeAI.addListener((results) => {
diff --git a/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx b/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx
index ff561d2e8c..dbe5e293dd 100644
--- a/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx
+++ b/docs/docs/guides/FRAME_PROCESSORS_CREATE_PLUGIN_CPP.mdx
@@ -49,7 +49,7 @@ const frameProcessor = useFrameProcessor((frame) => {
'worklet'
const result = global.myCppPlugin(frame)
console.log(`C++ result: ${result}`) // <-- 42
-}, [])
+})
```
To include VisionCamera's C++ library in your plugin's C++ code, you need to link it and include the headers.
diff --git a/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx b/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx
index 72e4c42aea..b72f13260c 100644
--- a/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx
+++ b/docs/docs/guides/FRAME_PROCESSORS_INTERACTING.mdx
@@ -30,7 +30,7 @@ const frameProcessor = useFrameProcessor((frame) => {
const objects = detectObjects(frame)
const bananas = objects.filter((o) => o.type === targetObject)
console.log(`Detected ${bananas} bananas!`)
-}, [targetObject])
+})
```
### Shared Values
@@ -45,7 +45,7 @@ const frameProcessor = useFrameProcessor((frame) => {
'worklet'
const objects = detectObjects(frame)
bananas.value = objects.filter((o) => o.type === 'banana')
-}, [bananas])
+})
// Draw bananas in a Skia Canvas
const onDraw = useDrawCallback((canvas) => {
@@ -76,7 +76,7 @@ const frameProcessor = useFrameProcessor((frame) => {
if (faces.length > 0) {
onFaceDetected(faces[0])
}
-}, [onFaceDetected])
+})
```
## Threading
@@ -101,7 +101,7 @@ const frameProcessor = useFrameProcessor((frame) => {
console.log("I'm running asynchronously, possibly at a lower FPS rate!")
const faces = detectFaces(frame)
})
-}, [])
+})
```
### Running at a throttled FPS rate
@@ -118,7 +118,7 @@ const frameProcessor = useFrameProcessor((frame) => {
console.log("I'm running synchronously at 2 FPS!")
const brightness = detectBrightness(frame)
})
-}, [])
+})
```
#### 🚀 Next section: [Zooming](/docs/guides/zooming) (or [creating a Frame Processor Plugin](/docs/guides/frame-processors-plugins-overview))
diff --git a/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx b/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx
index 4776272c32..b2fda6fda0 100644
--- a/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx
+++ b/docs/docs/guides/FRAME_PROCESSORS_TIPS.mdx
@@ -38,10 +38,6 @@ If you use native Frame Processor Plugins, make sure they are optimized for real
- Prefer plugins that support **GPU acceleration**. For Tensorflow, this might be the CoreML or Metal GPU delegates
- For operations such as resizing, **prefer GPU or CPU vector acceleration** (e.g. Accelerate/vImage) instead of just array loops
-## ESLint react-hooks plugin
-
-If you are using the [react-hooks ESLint plugin](https://www.npmjs.com/package/eslint-plugin-react-hooks), make sure to add `useFrameProcessor` and `useSkiaFrameProcessor` to `additionalHooks` inside your ESLint config so dependencies are detected properly. (See ["advanced configuration"](https://www.npmjs.com/package/eslint-plugin-react-hooks#advanced-configuration))
-
## Technical
### Frame Processors
diff --git a/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx b/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx
index b60a235e5a..53fc83ee2f 100644
--- a/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx
+++ b/docs/docs/guides/FRAME_PROCESSOR_CREATE_FINAL.mdx
@@ -34,7 +34,7 @@ function App() {
// highlight-next-line
const faces = scanFaces(frame)
console.log(`Faces in Frame: ${faces}`)
- }, [])
+ })
return (
diff --git a/docs/docs/guides/PIXEL_FORMATS.mdx b/docs/docs/guides/PIXEL_FORMATS.mdx
index 431cecefb3..c5a37283d2 100644
--- a/docs/docs/guides/PIXEL_FORMATS.mdx
+++ b/docs/docs/guides/PIXEL_FORMATS.mdx
@@ -38,7 +38,7 @@ function App() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet'
console.log(frame.pixelFormat) // <-- "rgb"
- }, [])
+ })
return (
(
- () => ({ zoom: zoom.value }),
- [zoom]
- )
+ const animatedProps = useAnimatedProps(() => ({ zoom: zoom.value }))
// highlight-end
if (device == null) return
diff --git a/package/.eslintrc.js b/package/.eslintrc.js
index 56b2157d6d..462ad2f7a4 100644
--- a/package/.eslintrc.js
+++ b/package/.eslintrc.js
@@ -74,14 +74,6 @@ module.exports = {
'@typescript-eslint/no-non-null-assertion': 'error',
'@typescript-eslint/no-unnecessary-condition': 'error',
'@typescript-eslint/consistent-type-imports': 'warn',
-
- // react hooks
- 'react-hooks/exhaustive-deps': [
- 'error',
- {
- additionalHooks: '(useDerivedValue|useAnimatedStyle|useAnimatedProps|useWorkletCallback|useFrameProcessor|useSkiaFrameProcessor)',
- },
- ],
},
env: {
node: true,
diff --git a/package/example/ios/Podfile.lock b/package/example/ios/Podfile.lock
index da2ed6afb2..690530576f 100644
--- a/package/example/ios/Podfile.lock
+++ b/package/example/ios/Podfile.lock
@@ -337,7 +337,7 @@ PODS:
- react-native-video/Video (= 5.2.1)
- react-native-video/Video (5.2.1):
- React-Core
- - react-native-worklets-core (1.2.0):
+ - react-native-worklets-core (1.3.2):
- React
- React-callinvoker
- React-Core
@@ -684,7 +684,7 @@ SPEC CHECKSUMS:
react-native-safe-area-context: 0ee144a6170530ccc37a0fd9388e28d06f516a89
react-native-skia: d368ae81d61c0253df36106ea76324b5a5519ddc
react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253
- react-native-worklets-core: a316975bba20b73d47aa4d41bffb0ca984ba592e
+ react-native-worklets-core: ff4a4076ad86469e61ec8e39da2cb13c55da2385
React-NativeModulesApple: b6868ee904013a7923128892ee4a032498a1024a
React-perflogger: 31ea61077185eb1428baf60c0db6e2886f141a5a
React-RCTActionSheet: 392090a3abc8992eb269ef0eaa561750588fc39d
diff --git a/package/example/package.json b/package/example/package.json
index 9b8df2180d..2bf0e499ae 100644
--- a/package/example/package.json
+++ b/package/example/package.json
@@ -29,7 +29,7 @@
"react-native-static-safe-area-insets": "^2.2.0",
"react-native-vector-icons": "^10.0.0",
"react-native-video": "^5.2.1",
- "react-native-worklets-core": "^1.2.0"
+ "react-native-worklets-core": "^1.3.2"
},
"devDependencies": {
"@babel/core": "^7.22.10",
diff --git a/package/example/src/CameraPage.tsx b/package/example/src/CameraPage.tsx
index 28ae31146c..c9ede28f9d 100644
--- a/package/example/src/CameraPage.tsx
+++ b/package/example/src/CameraPage.tsx
@@ -92,7 +92,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
return {
zoom: z,
}
- }, [maxZoom, minZoom, zoom])
+ })
//#endregion
//#region Callbacks
@@ -187,7 +187,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
examplePlugin(frame)
exampleKotlinSwiftPlugin(frame)
})
- }, [])
+ })
const videoHdr = format?.supportsVideoHdr && enableHdr
const photoHdr = format?.supportsPhotoHdr && enableHdr && !videoHdr
diff --git a/package/example/src/views/CaptureButton.tsx b/package/example/src/views/CaptureButton.tsx
index ecd041da45..cf4b952288 100644
--- a/package/example/src/views/CaptureButton.tsx
+++ b/package/example/src/views/CaptureButton.tsx
@@ -196,20 +196,17 @@ const _CaptureButton: React.FC = ({
})
//#endregion
- const shadowStyle = useAnimatedStyle(
- () => ({
- transform: [
- {
- scale: withSpring(isPressingButton.value ? 1 : 0, {
- mass: 1,
- damping: 35,
- stiffness: 300,
- }),
- },
- ],
- }),
- [isPressingButton],
- )
+ const shadowStyle = useAnimatedStyle(() => ({
+ transform: [
+ {
+ scale: withSpring(isPressingButton.value ? 1 : 0, {
+ mass: 1,
+ damping: 35,
+ stiffness: 300,
+ }),
+ },
+ ],
+ }))
const buttonStyle = useAnimatedStyle(() => {
let scale: number
if (enabled) {
@@ -246,7 +243,7 @@ const _CaptureButton: React.FC = ({
},
],
}
- }, [enabled, isPressingButton])
+ })
return (
=1.2.3",
"react": "*",
"react-native": "*",
"react-native-reanimated": "*",
- "react-native-worklets-core": "*"
+ "react-native-worklets-core": ">=1.3.2"
},
"peerDependenciesMeta": {
"react-native-worklets-core": {
diff --git a/package/src/hooks/useFrameProcessor.ts b/package/src/hooks/useFrameProcessor.ts
index a7348927be..f533e83d0b 100644
--- a/package/src/hooks/useFrameProcessor.ts
+++ b/package/src/hooks/useFrameProcessor.ts
@@ -1,8 +1,8 @@
-import type { DependencyList } from 'react'
import { useMemo } from 'react'
import { withFrameRefCounting } from '../frame-processors/withFrameRefCounting'
import type { ReadonlyFrameProcessor } from '../types/CameraProps'
import type { Frame } from '../types/Frame'
+import { WorkletsProxy } from '../dependencies/WorkletsProxy'
/**
* Create a new Frame Processor function which you can pass to the ``.
@@ -28,7 +28,6 @@ export function createFrameProcessor(frameProcessor: (frame: Frame) => void): Re
*
* @worklet
* @param frameProcessor The Frame Processor
- * @param dependencies The React dependencies which will be copied into the VisionCamera JS-Runtime.
* @returns The memoized Frame Processor.
* @example
* ```ts
@@ -36,10 +35,13 @@ export function createFrameProcessor(frameProcessor: (frame: Frame) => void): Re
* 'worklet'
* const faces = scanFaces(frame)
* console.log(`Faces: ${faces}`)
- * }, [])
+ * })
* ```
*/
-export function useFrameProcessor(frameProcessor: (frame: Frame) => void, dependencies: DependencyList): ReadonlyFrameProcessor {
- // eslint-disable-next-line react-hooks/exhaustive-deps
- return useMemo(() => createFrameProcessor(frameProcessor), dependencies)
+export function useFrameProcessor(frameProcessor: (frame: Frame) => void): ReadonlyFrameProcessor {
+ return useMemo(
+ () => createFrameProcessor(frameProcessor),
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ WorkletsProxy.getWorkletDependencies(frameProcessor),
+ )
}
diff --git a/package/src/skia/useSkiaFrameProcessor.ts b/package/src/skia/useSkiaFrameProcessor.ts
index 30efc014ca..32af5c08ca 100644
--- a/package/src/skia/useSkiaFrameProcessor.ts
+++ b/package/src/skia/useSkiaFrameProcessor.ts
@@ -1,5 +1,4 @@
import type { Frame, FrameInternal } from '../types/Frame'
-import type { DependencyList } from 'react'
import { useEffect, useMemo } from 'react'
import type { Orientation } from '../types/Orientation'
import type { DrawableFrameProcessor } from '../types/CameraProps'
@@ -247,7 +246,6 @@ export function createSkiaFrameProcessor(
*
* @worklet
* @param frameProcessor The Frame Processor
- * @param dependencies The React dependencies which will be copied into the VisionCamera JS-Runtime.
* @returns The memoized Skia Frame Processor.
* @example
* ```ts
@@ -260,13 +258,10 @@ export function createSkiaFrameProcessor(
* const rect = Skia.XYWHRect(face.x, face.y, face.width, face.height)
* frame.drawRect(rect)
* }
- * }, [])
+ * })
* ```
*/
-export function useSkiaFrameProcessor(
- frameProcessor: (frame: DrawableFrame) => void,
- dependencies: DependencyList,
-): DrawableFrameProcessor {
+export function useSkiaFrameProcessor(frameProcessor: (frame: DrawableFrame) => void): DrawableFrameProcessor {
const surface = WorkletsProxy.useSharedValue({})
const offscreenTextures = WorkletsProxy.useSharedValue([])
@@ -292,6 +287,6 @@ export function useSkiaFrameProcessor(
return useMemo(
() => createSkiaFrameProcessor(frameProcessor, surface, offscreenTextures),
// eslint-disable-next-line react-hooks/exhaustive-deps
- dependencies,
+ WorkletsProxy.getWorkletDependencies(frameProcessor),
)
}
diff --git a/package/src/types/CameraProps.ts b/package/src/types/CameraProps.ts
index ea96a6ce76..01850a9640 100644
--- a/package/src/types/CameraProps.ts
+++ b/package/src/types/CameraProps.ts
@@ -314,7 +314,7 @@ export interface CameraProps extends ViewProps {
* 'worklet'
* const faces = scanFaces(frame)
* console.log(`Faces: ${faces}`)
- * }, [])
+ * })
*
* return
* ```
diff --git a/package/src/types/Frame.ts b/package/src/types/Frame.ts
index f558c51bf3..cf11c01ebf 100644
--- a/package/src/types/Frame.ts
+++ b/package/src/types/Frame.ts
@@ -10,7 +10,7 @@ import type { PixelFormat } from './PixelFormat'
* const frameProcessor = useFrameProcessor((frame) => {
* 'worklet'
* console.log(`Frame: ${frame.width}x${frame.height} (${frame.pixelFormat})`)
- * }, [])
+ * })
* ```
*/
export interface Frame {
@@ -73,7 +73,7 @@ export interface Frame {
* const data = new Uint8Array(buffer)
* console.log(`Pixel at 0,0: RGB(${data[0]}, ${data[1]}, ${data[2]})`)
* }
- * }, [])
+ * })
* ```
*/
toArrayBuffer(): ArrayBuffer
diff --git a/package/yarn.lock b/package/yarn.lock
index 39fcc4d245..8067b5b317 100644
--- a/package/yarn.lock
+++ b/package/yarn.lock
@@ -6744,10 +6744,10 @@ react-native-reanimated@^3.8.1:
convert-source-map "^2.0.0"
invariant "^2.2.4"
-react-native-worklets-core@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.2.0.tgz#155040a48d1e3f66107544867ec579c2f5044271"
- integrity sha512-Uuf1Hg4V1w4I8eYNinwnnf+h+2YdQgwkUDQszY2yEEXWPWcZBWec0xjYn079RFRcKmGWuJ/zOtokjwy/IjJ9Fw==
+react-native-worklets-core@^1.3.2:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/react-native-worklets-core/-/react-native-worklets-core-1.3.2.tgz#0851ad7b524eae152d63adc20ad626eabecd9f26"
+ integrity sha512-wx2MdfiUP9gBluhtzrb5XeiAGxdnqVqosLCPIhP1sSF9EcgOKTBV4jxuRkYmZJ/DDcHvGPy0qwdqwyVtWAn3jQ==
dependencies:
string-hash-64 "^1.0.3"