diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
new file mode 100644
index 0000000..1264626
--- /dev/null
+++ b/.github/workflows/checks.yml
@@ -0,0 +1,31 @@
+name: Checks
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ types: [opened, synchronize]
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ checks:
+ runs-on: ubuntu-latest
+ steps:
+ - name: 🏗 Setup repository
+ uses: actions/checkout@v4
+
+ - name: 🏗 Setup Bun
+ uses: oven-sh/setup-bun@v2
+ with:
+ bun-version: latest
+
+ - name: 📦 Install dependencies
+ run: bun install --frozen-lockfile
+
+ - name: 🔍 Check apps
+ run: |
+ bun run lint:apps
+ bun run typecheck:apps
diff --git a/apps/example/package.json b/apps/example/package.json
index a06ea5a..f106116 100644
--- a/apps/example/package.json
+++ b/apps/example/package.json
@@ -8,7 +8,8 @@
"ios": "expo run:ios",
"web": "expo start --web",
"lint": "expo lint",
- "fix-deps": "expo install --check"
+ "fix-deps": "expo install --check",
+ "typecheck": "tsc --noEmit"
},
"dependencies": {
"@apollo/client": "^3.11.10",
diff --git a/apps/example/src/app/_layout.tsx b/apps/example/src/app/_layout.tsx
index 61f325e..1593164 100644
--- a/apps/example/src/app/_layout.tsx
+++ b/apps/example/src/app/_layout.tsx
@@ -1,7 +1,7 @@
import { useReactNavigationDevTools } from '@dev-plugins/react-navigation';
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { useFonts } from 'expo-font';
-import { SplashScreen, Stack , useNavigationContainerRef } from 'expo-router';
+import { SplashScreen, Stack, useNavigationContainerRef } from 'expo-router';
import { useEffect } from 'react';
import { StatusBar } from 'expo-status-bar';
diff --git a/apps/example/src/app/index.tsx b/apps/example/src/app/index.tsx
index 8d30593..59a7902 100644
--- a/apps/example/src/app/index.tsx
+++ b/apps/example/src/app/index.tsx
@@ -8,19 +8,19 @@ export default function TesterScreen() {
-
-
-
-
-
-
-
+
+
+
+
+
+
+
);
}
-function TestCase({ title, route }: { title: string; route: LinkProps['href'] }) {
+function TestCase({ title, route }: { title: string; route: LinkProps['href'] }) {
return (
diff --git a/bun.lock b/bun.lock
index 9bba0be..fbeda97 100644
--- a/bun.lock
+++ b/bun.lock
@@ -65,6 +65,7 @@
"expo": "53.0.7",
"expo-module-scripts": "^4.1.7",
"graphql": "^16.9.0",
+ "react-dom": "19.1.0",
"typescript": "~5.8.3",
},
"peerDependencies": {
diff --git a/package.json b/package.json
index ff91adb..c7c0f50 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,8 @@
"version": "1.0.0",
"private": true,
"scripts": {
+ "lint:apps": "bun run --filter './apps/**' lint",
+ "typecheck:apps": "bun run --filter './apps/**' typecheck",
"postinstall": "./scripts/prepare-packages.js"
},
"workspaces": [
diff --git a/packages/apollo-client/package.json b/packages/apollo-client/package.json
index ea90cdd..6c69fa1 100644
--- a/packages/apollo-client/package.json
+++ b/packages/apollo-client/package.json
@@ -41,6 +41,7 @@
"expo": "53.0.7",
"expo-module-scripts": "^4.1.7",
"graphql": "^16.9.0",
+ "react-dom": "19.1.0",
"typescript": "~5.8.3"
},
"peerDependencies": {
diff --git a/packages/react-navigation/build/useReactNavigationDevTools.d.ts b/packages/react-navigation/build/useReactNavigationDevTools.d.ts
index bec27df..7c19082 100644
--- a/packages/react-navigation/build/useReactNavigationDevTools.d.ts
+++ b/packages/react-navigation/build/useReactNavigationDevTools.d.ts
@@ -1,3 +1,3 @@
import type { NavigationContainerRef } from '@react-navigation/core';
-export declare function useReactNavigationDevTools(ref: React.RefObject>): void;
+export declare function useReactNavigationDevTools(ref: React.RefObject | null>): void;
//# sourceMappingURL=useReactNavigationDevTools.d.ts.map
\ No newline at end of file
diff --git a/packages/react-navigation/build/useReactNavigationDevTools.d.ts.map b/packages/react-navigation/build/useReactNavigationDevTools.d.ts.map
index 4a3a7d5..5b67cc2 100644
--- a/packages/react-navigation/build/useReactNavigationDevTools.d.ts.map
+++ b/packages/react-navigation/build/useReactNavigationDevTools.d.ts.map
@@ -1 +1 @@
-{"version":3,"file":"useReactNavigationDevTools.d.ts","sourceRoot":"","sources":["../src/useReactNavigationDevTools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAOrE,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC,QAmE3F"}
\ No newline at end of file
+{"version":3,"file":"useReactNavigationDevTools.d.ts","sourceRoot":"","sources":["../src/useReactNavigationDevTools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAOrE,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,QAqEzD"}
\ No newline at end of file
diff --git a/packages/react-navigation/build/useReactNavigationDevTools.js b/packages/react-navigation/build/useReactNavigationDevTools.js
index b3eeb72..92e1c77 100644
--- a/packages/react-navigation/build/useReactNavigationDevTools.js
+++ b/packages/react-navigation/build/useReactNavigationDevTools.js
@@ -9,6 +9,7 @@ export function useReactNavigationDevTools(ref) {
globalThis.__REDUX_DEVTOOLS_EXTENSION__ = {
connect: () => adapterRef.current,
};
+ // @ts-ignore: useReduxDevToolsExtension does not accept null ref from NavigationContainerRefWithCurrent
useReduxDevToolsExtension(ref);
useEffect(() => {
adapterRef.current.setClient(client);
diff --git a/packages/react-navigation/build/useReactNavigationDevTools.js.map b/packages/react-navigation/build/useReactNavigationDevTools.js.map
index 182c611..3223bfe 100644
--- a/packages/react-navigation/build/useReactNavigationDevTools.js.map
+++ b/packages/react-navigation/build/useReactNavigationDevTools.js.map
@@ -1 +1 @@
-{"version":3,"file":"useReactNavigationDevTools.js","sourceRoot":"","sources":["../src/useReactNavigationDevTools.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NavigationContainerRef } from '@react-navigation/core';\nimport { useReduxDevToolsExtension } from '@react-navigation/devtools';\nimport { useDevToolsPluginClient, type EventSubscription } from 'expo/devtools';\nimport { useEffect, useRef } from 'react';\n\nimport { ReduxExtensionAdapter } from './ReduxExtensionAdapter';\n\nexport function useReactNavigationDevTools(ref: React.RefObject>) {\n const client = useDevToolsPluginClient('react-navigation');\n const adapterRef = useRef(new ReduxExtensionAdapter());\n // @ts-ignore: Override global\n globalThis.__REDUX_DEVTOOLS_EXTENSION__ = {\n connect: () => adapterRef.current,\n };\n useReduxDevToolsExtension(ref);\n\n useEffect(() => {\n adapterRef.current.setClient(client);\n\n const on = (event: string, listener: (params: any) => Promise) => {\n return client?.addMessageListener(event, async (params) => {\n try {\n const result = await listener(params);\n\n if (params.id) {\n client?.sendMessage(`ack:${event}`, { id: params.id, result });\n }\n } catch {}\n });\n };\n\n const subscriptions: (EventSubscription | undefined)[] = [];\n subscriptions.push(\n on('navigation.invoke', ({ method, args = [] }) => {\n switch (method) {\n case 'resetRoot':\n return adapterRef.current?.resetRoot(args[0]);\n default:\n // @ts-ignore: this might not exist\n return ref.current?.[method](...args);\n }\n })\n );\n\n subscriptions.push(\n on('linking.invoke', ({ method, args = [] }) => {\n const linking: any = ref.current\n ? // @ts-ignore: this might not exist\n global.REACT_NAVIGATION_DEVTOOLS?.get(ref.current)?.linking\n : null;\n\n switch (method) {\n case 'getStateFromPath':\n case 'getPathFromState':\n case 'getActionFromState':\n return linking?.[method](\n args[0],\n args[1]?.trim()\n ? // eslint-disable-next-line no-eval\n eval(`(function() { return ${args[1]}; }())`)\n : linking.config\n );\n default:\n return linking?.[method](...args);\n }\n })\n );\n\n return () => {\n for (const subscription of subscriptions) {\n subscription?.remove();\n }\n };\n }, [client]);\n}\n"]}
\ No newline at end of file
+{"version":3,"file":"useReactNavigationDevTools.js","sourceRoot":"","sources":["../src/useReactNavigationDevTools.ts"],"names":[],"mappings":"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","sourcesContent":["import type { NavigationContainerRef } from '@react-navigation/core';\nimport { useReduxDevToolsExtension } from '@react-navigation/devtools';\nimport { useDevToolsPluginClient, type EventSubscription } from 'expo/devtools';\nimport { useEffect, useRef } from 'react';\n\nimport { ReduxExtensionAdapter } from './ReduxExtensionAdapter';\n\nexport function useReactNavigationDevTools(\n ref: React.RefObject | null>\n) {\n const client = useDevToolsPluginClient('react-navigation');\n const adapterRef = useRef(new ReduxExtensionAdapter());\n // @ts-ignore: Override global\n globalThis.__REDUX_DEVTOOLS_EXTENSION__ = {\n connect: () => adapterRef.current,\n };\n // @ts-ignore: useReduxDevToolsExtension does not accept null ref from NavigationContainerRefWithCurrent\n useReduxDevToolsExtension(ref);\n\n useEffect(() => {\n adapterRef.current.setClient(client);\n\n const on = (event: string, listener: (params: any) => Promise) => {\n return client?.addMessageListener(event, async (params) => {\n try {\n const result = await listener(params);\n\n if (params.id) {\n client?.sendMessage(`ack:${event}`, { id: params.id, result });\n }\n } catch {}\n });\n };\n\n const subscriptions: (EventSubscription | undefined)[] = [];\n subscriptions.push(\n on('navigation.invoke', ({ method, args = [] }) => {\n switch (method) {\n case 'resetRoot':\n return adapterRef.current?.resetRoot(args[0]);\n default:\n // @ts-ignore: this might not exist\n return ref.current?.[method](...args);\n }\n })\n );\n\n subscriptions.push(\n on('linking.invoke', ({ method, args = [] }) => {\n const linking: any = ref.current\n ? // @ts-ignore: this might not exist\n global.REACT_NAVIGATION_DEVTOOLS?.get(ref.current)?.linking\n : null;\n\n switch (method) {\n case 'getStateFromPath':\n case 'getPathFromState':\n case 'getActionFromState':\n return linking?.[method](\n args[0],\n args[1]?.trim()\n ? // eslint-disable-next-line no-eval\n eval(`(function() { return ${args[1]}; }())`)\n : linking.config\n );\n default:\n return linking?.[method](...args);\n }\n })\n );\n\n return () => {\n for (const subscription of subscriptions) {\n subscription?.remove();\n }\n };\n }, [client]);\n}\n"]}
\ No newline at end of file
diff --git a/packages/react-navigation/src/useReactNavigationDevTools.ts b/packages/react-navigation/src/useReactNavigationDevTools.ts
index fc41583..15a0c5c 100644
--- a/packages/react-navigation/src/useReactNavigationDevTools.ts
+++ b/packages/react-navigation/src/useReactNavigationDevTools.ts
@@ -5,13 +5,16 @@ import { useEffect, useRef } from 'react';
import { ReduxExtensionAdapter } from './ReduxExtensionAdapter';
-export function useReactNavigationDevTools(ref: React.RefObject>) {
+export function useReactNavigationDevTools(
+ ref: React.RefObject | null>
+) {
const client = useDevToolsPluginClient('react-navigation');
const adapterRef = useRef(new ReduxExtensionAdapter());
// @ts-ignore: Override global
globalThis.__REDUX_DEVTOOLS_EXTENSION__ = {
connect: () => adapterRef.current,
};
+ // @ts-ignore: useReduxDevToolsExtension does not accept null ref from NavigationContainerRefWithCurrent
useReduxDevToolsExtension(ref);
useEffect(() => {