mirror of
https://github.com/stablyai/orca.git
synced 2026-11-13 17:37:40 +00:00
* build(mobile): upgrade to Expo SDK 58 and React Native 0.88 Expo 58 drops Zod from @expo/cli, which clears the last Zod 3 advisory (GHSA-mrhx-c7xc-m3w5) in mobile along with its local patch and override. - Expo 55 -> 58, React Native 0.83 -> 0.88, React 19.3, gesture-handler 3, webview 14, reanimated 4.7, worklets 0.13 (SDK 58 bundled versions, pinned below today's batch to respect minimumReleaseAge). - Port the react-native and react-native-webview patches unchanged; drop expo-constants, expo-notifications, @expo/cli, expo-router, zod and query-string patches plus the zod/query-string/xcode>uuid overrides, which upstream fixed or no longer need. - iOS minimum rises to 16.4 (Expo 58 / RN 0.88 requirement). - Migrate to RN 0.88 strict types: instance ref types, NamedStyles, AppState.currentState, list header/footer nulls. - Replace removed runtime APIs: InteractionManager -> idle callback with a macrotask fallback; StyleSheet.absoluteFillObject -> absoluteFill; FileHandle.readBytes -> readBytesSync (it became async). - Resolve react-native/asset-registry for shared assets in Metro and alias the old registry path for react-native-svg in the desktop mobile-web bundle. - Reduce the iOS scene plugin to the reconnect override; Expo 58's template now ships the scene delegate itself. * fix(mobile): bridge react-native-svg web imports and libsodium runtime for RN 0.88 - Share react-native-svg web shims between the mobile-web build and its render checks: map the old asset-registry path to react-native-web's registry and stub the Android-only touch-sound TurboModule. - Patch react-native-libsodium 1.7.0 to read the JSI runtime from the bridge proxy; RN 0.88 removed RCTCxxBridge.runtime. * fix(mobile): use Expo 58's legacy promise resolver for audio permissions * fix(mobile): skip null handles in the RPC recording timer shims for RN 0.88 types * style(mobile): format MobilePRSidebar after rebase * fix(mobile): name RN 0.88 text input refs for declarations; allow queued back in stack render check - Type text input refs with an exported interface so declaration emit can name hook results (RN 0.88 aliases TextInputInstance to an unexported class). - Expo Router 58 drains back() after a commit; check the interrupted push's exit from the frame it starts, bounded to three frames of lag. * chore(mobile): justify the text input handle interface for React Doctor * chore(mobile): use a nameable intersection alias for text input refs * fix(mobile): use sync expo-file-system writes, copies and moves on Expo 58 Expo 58 made File.write/copy/move and FileHandle.writeBytes return promises. Our callers never awaited them, so failures escaped their try/catch and the store's tmp-then-move and PDF writes could race their close or rename. * build(mobile): raise the page bundle budget to 10 MiB for Expo 58 Expo 58 adds about 310 KB to the page: expo-router (+258 KB, now carrying React Navigation, net about +110 KB) and Reanimated 4.7 (+152 KB). Main had 85 KB of headroom left. 10 MiB still stays within the 10 MiB per-asset contract. * fix(mobile): drop the window-metrics seed RN 0.88 removed from Android RN 0.88 no longer holds window metrics: DeviceInfoModule reads the activity's WindowMetrics on demand and setWindowDisplayMetrics is gone, so MainActivity no longer compiled. Layout scale still comes from the screen metrics we reseed. --------- Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
65 lines
2.5 KiB
JavaScript
65 lines
2.5 KiB
JavaScript
const fs = require('node:fs')
|
|
const path = require('node:path')
|
|
const { withDangerousMod } = require('expo/config-plugins')
|
|
|
|
// Why: Expo SDK 58's template adopts the UIScene lifecycle the iOS 27 SDK requires (TN3187), and
|
|
// its ExpoAppSceneDelegate forwards URLs and user activities. It starts React Native on every
|
|
// scene connect, though, and iOS may disconnect the app's only scene in the background and
|
|
// reconnect it later. Reattach the running root then, so a reconnect keeps the app's state
|
|
// instead of starting a second React Native instance.
|
|
const MARKER = 'orca: UIScene reconnect'
|
|
const EXTENSION_POINT = ' // Extension point for config plugins.\n'
|
|
const TEMPLATE_CLASS = 'class SceneDelegate: ExpoAppSceneDelegate {\n'
|
|
|
|
const RECONNECT_OVERRIDE = ` // ${MARKER}, generated by plugins/ios-scene-lifecycle.js.
|
|
override func scene(
|
|
_ scene: UIScene,
|
|
willConnectTo session: UISceneSession,
|
|
options connectionOptions: UIScene.ConnectionOptions
|
|
) {
|
|
guard let windowScene = scene as? UIWindowScene,
|
|
let provider = UIApplication.shared.delegate as? ExpoReactNativeFactoryProvider,
|
|
let runningRoot = provider.window?.rootViewController
|
|
else {
|
|
super.scene(scene, willConnectTo: session, options: connectionOptions)
|
|
return
|
|
}
|
|
let window = UIWindow(windowScene: windowScene)
|
|
self.window = window
|
|
provider.window = window
|
|
window.rootViewController = runningRoot
|
|
window.makeKeyAndVisible()
|
|
if !connectionOptions.urlContexts.isEmpty {
|
|
self.scene(scene, openURLContexts: connectionOptions.urlContexts)
|
|
}
|
|
for activity in connectionOptions.userActivities {
|
|
self.scene(scene, continue: activity)
|
|
}
|
|
}
|
|
`
|
|
|
|
function patchSceneDelegate(contents) {
|
|
if (contents.includes(MARKER)) {
|
|
return contents
|
|
}
|
|
// A changed template must fail prebuild rather than silently drop the reconnect behavior.
|
|
if (!contents.includes(TEMPLATE_CLASS) || !contents.includes(EXTENSION_POINT)) {
|
|
throw new Error(
|
|
"ios-scene-lifecycle: Expo's SceneDelegate template changed; update the plugin before building."
|
|
)
|
|
}
|
|
return contents.replace(EXTENSION_POINT, `${EXTENSION_POINT}\n${RECONNECT_OVERRIDE}`)
|
|
}
|
|
|
|
module.exports = function withIosSceneLifecycle(config) {
|
|
return withDangerousMod(config, [
|
|
'ios',
|
|
(cfg) => {
|
|
const { platformProjectRoot, projectName } = cfg.modRequest
|
|
const file = path.join(platformProjectRoot, projectName, 'SceneDelegate.swift')
|
|
fs.writeFileSync(file, patchSceneDelegate(fs.readFileSync(file, 'utf8')))
|
|
return cfg
|
|
}
|
|
])
|
|
}
|