Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
9c9d21f
feat(shims): zustand + expo-sqlite stubs for smoke coverage
OmgImAlexis May 31, 2026
5a91006
feat(shims): @react-navigation/* family (native/stack/drawer/tabs) re…
OmgImAlexis May 31, 2026
dd94a10
ci(smoke): force GSK_RENDERER=ngl + GTK_THEME=Adwaita; dump log on bl…
OmgImAlexis May 31, 2026
f4bfed8
feat(shims): moti — degrades to static at-animate-values placement
OmgImAlexis May 31, 2026
a8d5280
feat(shims): batch — expo-updates, expo-av, sentry, socket.io, styled…
OmgImAlexis May 31, 2026
04bbff1
feat(shims): expo-asset + sentry integrations + createStaticNavigatio…
OmgImAlexis May 31, 2026
df6d133
feat(shims): expo-auth-session, jwt-decode, apollo, firebase, picker,…
OmgImAlexis May 31, 2026
ae0f4fe
feat(shims): batch of one-example stubs + LogBox/UIManager/StatusBar/…
OmgImAlexis May 31, 2026
9b37cb3
feat(shims): uuid (with default export) + smoke threshold 4 -> 2
OmgImAlexis May 31, 2026
8531aa7
feat(shims): legend-state observablePersistAsyncStorage (lowercase) +…
OmgImAlexis May 31, 2026
52e49d5
ci(smoke): detect src/app/ layout for newer expo-router examples
OmgImAlexis May 31, 2026
0e34b6b
docs(expo-examples): update baseline — 67/69 PASS
OmgImAlexis May 31, 2026
1dd8f5f
feat(rn): bump React Native 0.81 -> 0.85.3 + Hermes 0.16 + new Schedu…
OmgImAlexis Jun 1, 2026
f207b95
fix(zustand): memoize selector result + return shallow as default export
OmgImAlexis Jun 1, 2026
afb6d96
ci(deps): bump actions/checkout from 5 to 6
dependabot[bot] Jun 1, 2026
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
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
lint-js:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
Expand All @@ -45,7 +45,7 @@ jobs:
lint-cpp:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install clang-format
run: |
sudo apt-get update
Expand All @@ -64,7 +64,7 @@ jobs:
autolink-drift:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
Expand Down Expand Up @@ -99,7 +99,7 @@ jobs:
# before they hit a contributor's machine.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- name: Install native build deps
run: |
Expand Down Expand Up @@ -191,7 +191,7 @@ jobs:
# from the lint-js job's cache.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
Expand Down Expand Up @@ -254,7 +254,7 @@ jobs:
# prefix because the subdir layout differs.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6

- name: Install native build + xvfb deps
run: |
Expand Down Expand Up @@ -381,7 +381,7 @@ jobs:
runs-on: ubuntu-24.04
needs: smoke-playground
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
submodules: recursive

Expand Down Expand Up @@ -471,7 +471,7 @@ jobs:
# lands the build-vnext job can also `ctest --label-regex vnext`.
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
if: needs.release-please.outputs.releases_created == 'true'
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6
with:
version: ${{ env.PNPM_VERSION }}
Expand Down
164 changes: 162 additions & 2 deletions apps/playground/bundle.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,22 @@ const refreshTransformPlugin = {
// through swc with ES5 target lowers classes to prototype-based
// assignments Hermes accepts.
const inNodeModules = args.path.includes('/node_modules/');
// expo/examples is a sibling tree we vendor under
// external/expo-examples/ via a git submodule; treat it like
// node_modules for class-lowering purposes since esbuild can
// still emit `var X = class extends Y.Z` from user code there.
const inExternalExamples = args.path.includes('/external/expo-examples/');
// Match any `class <Identifier>` declaration — Hermes 0.12
// rejects both `class extends X.Y` (member-expression super)
// and `class _X { ... }` (the renamed-binding form esbuild
// emits for `var X = class { ... }`). The earlier
// `class … extends …` filter missed the second case, which
// showed up in expo-asset's AssetSourceResolver.
const looksClassHeavy =
inNodeModules &&
(inNodeModules || inExternalExamples) &&
!isShimPackage &&
!isNativeSpec &&
/\bclass\b\s+\w*\s*\bextends\b/.test(lazySource());
/\bclass\b\s+\w/.test(lazySource());
if (!inUserCode && !isNativeSpec && !isShimPackage && !looksClassHeavy) return null;

// RN's Native* spec files are usually Flow-flavoured (// @flow,
Expand Down Expand Up @@ -187,6 +198,11 @@ const baseOpts = {
'.gif': 'dataurl',
'.webp': 'dataurl',
'.ttf': 'dataurl',
// .svg: real handling needs react-native-svg-transformer to
// parse the SVG into a React component. For smoke purposes
// empty-ing the file (default value: undefined) lets the import
// resolve; `<ExpoLogo />` then renders as nothing.
'.svg': 'empty',
'.otf': 'dataurl',
},
jsx: 'automatic',
Expand Down Expand Up @@ -285,6 +301,77 @@ const appOpts = {
'@expo/metro-runtime',
'@expo/vector-icons',
'@expo/vector-icons/*',
'zustand',
'zustand/shallow',
'expo-sqlite',
'@react-navigation/native',
'@react-navigation/native-stack',
'@react-navigation/stack',
'@react-navigation/drawer',
'@react-navigation/bottom-tabs',
'@react-navigation/material-top-tabs',
'@react-navigation/material-bottom-tabs',
'@react-navigation/elements',
'moti',
'expo-updates',
'expo-av',
'@sentry/react-native',
'socket.io-client',
'styled-components',
'styled-components/native',
'react-native-maps',
'react-native-pdf',
'react-native-webrtc',
'react-native-svg',
'react-native-svg/css',
'victory-native',
'react-router-dom',
'react-router',
'expo-asset',
'expo-auth-session',
'expo-auth-session/providers/google',
'expo-auth-session/providers/facebook',
'expo-auth-session/providers/apple',
'jwt-decode',
'@apollo/client',
'@apollo/client/react',
'@apollo/client/link/http',
'@apollo/client/cache',
'firebase/app',
'firebase/auth',
'firebase/auth/react-native',
'firebase/firestore',
'firebase/storage',
'@react-native-picker/picker',
'tinybase',
'tinybase/ui-react',
'tinybase/persisters/persister-browser',
'tinybase/persisters/persister-expo-sqlite',
'@legendapp/state',
'@legendapp/state/react',
'@legendapp/state/persist',
'@legendapp/state/sync',
'@legendapp/state/persist-plugins/async-storage',
'@legendapp/state/sync-plugins/supabase',
'three',
'expo-gl',
'expo-three',
'expo-processing',
'@magic-sdk/react-native',
'@magic-sdk/react-native-bare',
'@react-three/fiber',
'@react-three/fiber/native',
'@react-three/drei',
'react-native-get-random-values',
'@supabase/supabase-js',
'aws-amplify',
'@aws-amplify/core',
'@aws-amplify/auth',
'@aws-amplify/storage',
'@tensorflow/tfjs',
'@tensorflow/tfjs-react-native',
'@tensorflow-models/mobilenet',
'uuid',
'crypto',
'node:crypto',
'expo-application',
Expand Down Expand Up @@ -342,6 +429,79 @@ const appOpts = {
' if (id === "expo-router/entry") return rnv.expoRouterEntry();\n' +
' if (id === "@expo/metro-runtime") return rnv.expoMetroRuntime;\n' +
' if (id === "crypto" || id === "node:crypto") return rnv.nodeCrypto;\n' +
' if (id === "zustand") return rnv.zustand;\n' +
// zustand/shallow ships BOTH `import shallow from "zustand/shallow"`
// (the function as default) AND `import {shallow} from "zustand/shallow"`.
// Return an __esModule namespace that satisfies both shapes; esbuild
// sees __esModule:true and pipes it through interop untouched.
' if (id === "zustand/shallow") {\n' +
' var sh = rnv.zustand.shallow;\n' +
' var ns = {default: sh, shallow: sh};\n' +
' Object.defineProperty(ns, "__esModule", {value: true});\n' +
' return ns;\n' +
' }\n' +
' if (id === "expo-sqlite") return rnv.expoSqlite;\n' +
// Every @react-navigation/* package routes through the same
// minimal shim — the navigator factories cover stack / native-
// stack / drawer / bottom-tabs / material-* with one impl.
' if (id === "@react-navigation/native") return rnv.rnNavigation;\n' +
' if (id === "@react-navigation/native-stack") return {createNativeStackNavigator: rnv.rnNavigation.createNativeStackNavigator};\n' +
' if (id === "@react-navigation/stack") return {createStackNavigator: rnv.rnNavigation.createStackNavigator};\n' +
' if (id === "@react-navigation/drawer") return {createDrawerNavigator: rnv.rnNavigation.createDrawerNavigator};\n' +
' if (id === "@react-navigation/bottom-tabs") return {createBottomTabNavigator: rnv.rnNavigation.createBottomTabNavigator};\n' +
' if (id === "@react-navigation/material-top-tabs") return {createMaterialTopTabNavigator: rnv.rnNavigation.createMaterialTopTabNavigator};\n' +
' if (id === "@react-navigation/material-bottom-tabs") return {createMaterialBottomTabNavigator: rnv.rnNavigation.createMaterialBottomTabNavigator};\n' +
' if (id === "@react-navigation/elements") return {};\n' +
' if (id === "moti") return rnv.moti;\n' +
' if (id === "expo-updates") return rnv.expoUpdates;\n' +
' if (id === "expo-av") return rnv.expoAv;\n' +
' if (id === "@sentry/react-native") return rnv.sentry;\n' +
' if (id === "socket.io-client") return rnv.socketIo;\n' +
' if (id === "styled-components" || id === "styled-components/native") return rnv.styledComponents;\n' +
' if (id === "react-native-maps") return rnv.reactNativeMaps;\n' +
' if (id === "react-native-pdf") return rnv.reactNativePdf;\n' +
' if (id === "react-native-webrtc") return rnv.reactNativeWebrtc;\n' +
' if (id === "react-native-svg" || id === "react-native-svg/css") return rnv.reactNativeSvg;\n' +
' if (id === "victory-native") return rnv.victoryNative;\n' +
' if (id === "react-router-dom" || id === "react-router") return rnv.reactRouterDom;\n' +
' if (id === "expo-asset") return rnv.expoAsset;\n' +
' if (id === "expo-auth-session") return rnv.expoAuthSession;\n' +
' if (id.indexOf("expo-auth-session/providers/") === 0) {\n' +
' var prov = id.slice("expo-auth-session/providers/".length);\n' +
' return rnv.expoAuthSession.Providers[prov[0].toUpperCase()+prov.slice(1)] || rnv.expoAuthSession;\n' +
' }\n' +
' if (id === "jwt-decode") return rnv.jwtDecode;\n' +
' if (id === "@apollo/client" || id.indexOf("@apollo/client/") === 0) return rnv.apolloClient;\n' +
' if (id === "firebase/app") return rnv.firebase.app;\n' +
' if (id === "firebase/auth" || id === "firebase/auth/react-native") return rnv.firebase.auth;\n' +
' if (id === "firebase/firestore") return rnv.firebase.firestore;\n' +
' if (id === "firebase/storage") return rnv.firebase.storage;\n' +
' if (id === "@react-native-picker/picker") return rnv.reactNativePicker;\n' +
' if (id === "tinybase") return rnv.tinybase.base;\n' +
' if (id === "tinybase/ui-react") return rnv.tinybase.uiReact;\n' +
' if (id.indexOf("tinybase/persisters/") === 0) return rnv.tinybase.persisters;\n' +
' if (id === "@legendapp/state") return rnv.legendState.base;\n' +
' if (id === "@legendapp/state/react") return rnv.legendState.react;\n' +
' if (id === "@legendapp/state/persist") return rnv.legendState.persist;\n' +
' if (id === "@legendapp/state/sync") return rnv.legendState.sync;\n' +
' if (id === "@legendapp/state/persist-plugins/async-storage") return rnv.legendState.persistAsyncStorage;\n' +
' if (id === "@legendapp/state/sync-plugins/supabase") return rnv.legendState.syncSupabase;\n' +
' if (id === "three") return rnv.expoGlThree.three;\n' +
' if (id === "expo-gl") return rnv.expoGlThree.expoGl;\n' +
' if (id === "expo-three") return rnv.expoGlThree.expoThree;\n' +
' if (id === "expo-processing") return rnv.expoGlThree.expoProcessing;\n' +
' if (id === "@magic-sdk/react-native" || id === "@magic-sdk/react-native-bare") return rnv.misc.magicSdk;\n' +
' if (id === "@react-three/fiber" || id === "@react-three/fiber/native" || id === "@react-three/drei") return rnv.misc.reactThreeFiber;\n' +
' if (id === "react-native-get-random-values") return rnv.misc.reactNativeGetRandomValues;\n' +
' if (id === "@supabase/supabase-js") return rnv.misc.supabase;\n' +
' if (id === "aws-amplify") return rnv.misc.amplify;\n' +
' if (id === "@aws-amplify/core") return rnv.misc.ampCore;\n' +
' if (id === "@aws-amplify/auth") return rnv.misc.ampAuth;\n' +
' if (id === "@aws-amplify/storage") return rnv.misc.ampStorage;\n' +
' if (id === "@tensorflow/tfjs") return rnv.misc.tfjs;\n' +
' if (id === "@tensorflow/tfjs-react-native") return rnv.misc.tfjsReactNative;\n' +
' if (id === "@tensorflow-models/mobilenet") return rnv.misc.mobilenet;\n' +
' if (id === "uuid") return rnv.uuid;\n' +
// @expo/vector-icons/<Font> sub-paths route through the shared
// shim; the bare-module form (no sub-path) returns the index
// with every font pre-built.
Expand Down
10 changes: 5 additions & 5 deletions apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
"@react-native-async-storage/async-storage": "^3.1.0",
"expo-camera": "^56.0.7",
"expo-location": "^56.0.14",
"react": "19.1.7",
"react-native": "^0.81.0",
"react": "19.2.3",
"react-native": "^0.85.3",
"react-native-device-info": "^15.0.2",
"react-native-paper": "^5",
"react-native-vector-icons": "^10.3.0",
Expand All @@ -31,16 +31,16 @@
"@babel/runtime": "^7.24.0",
"@lucid-softworks/react-native-linux-cli": "workspace:*",
"@react-native-community/cli": "^20.0.0",
"@react-native/babel-preset": "^0.81.0",
"@react-native/metro-config": "^0.81.0",
"@react-native/babel-preset": "^0.85.3",
"@react-native/metro-config": "^0.85.3",
"@swc/core": "^1.15.40",
"@types/react": "^19.1.0",
"babel-jest": "^29.7.0",
"esbuild": "^0.25.12",
"flow-remove-types": "^2.314.0",
"jest": "^29.7.0",
"react-refresh": "^0.18.0",
"react-test-renderer": "19.1.7",
"react-test-renderer": "19.2.3",
"typescript": "^5.4.0"
},
"engines": {
Expand Down
Loading
Loading