feat: macOS support (+example app +ci/cd) - #298
Open
samuelscheit wants to merge 7 commits into
Open
Conversation
The benchmark reset flow used the module-scoped largeDb variable as a proxy for whether the on-disk database existed. SQLite files survive app restarts while that variable does not, so a fresh runtime reopened an existing large database and unconditionally attempted to create Test again. This surfaced as "table Test already exists" before the benchmark could run.\n\nKeep the benchmark connection open for the current runtime and rebuild its schema transactionally on every reset. The shared schema helper drops the old Test table before recreating the expected STRICT table, preserving deterministic benchmark data whether the database is new, persisted from a previous launch, or reused in the same session. The misleading user-database error label is corrected as well.\n\nAdd a native regression test that begins with an incompatible existing Test table and verifies that the reset helper replaces it with the full benchmark schema. Register it with the unit suite so the persisted-schema lifecycle is covered without inserting 300,000 benchmark rows during tests.
Add a first-class React Native macOS example workspace that reuses the shared SQLite, TypeORM, sqlite-vec, console, and benchmark flows while providing a macOS-safe navigation implementation and platform-specific Metro/Babel configuration. Wire CocoaPods, autolinking, generated native registration, app sandbox configuration, database storage under Application Support, and sqlite-vec opt-in support for macOS. Patch react-native-get-random-values so it registers correctly in the macOS new-architecture build. Replace the legacy thread-unsafe SQLite performance toggle with a single thread-safe configuration. Async operations execute on Nitro worker threads, so SQLite must retain mutex support to avoid crashes during repeat and concurrent test runs. Add matching CI coverage: a cached macOS build workflow for pushes and pull requests, plus a PR integration workflow that builds the app, starts Metro on an ephemeral port, launches the compiled app, and waits for its structured test report. The runner propagates app and Metro startup failures, validates results, and reliably tears down child process groups. React Native Harness currently supports Android and iOS targets, but has no macOS platform runner or desktop-process lifecycle integration. The macOS workflow therefore uses a small explicit result transport instead of the Harness WebSocket bridge: the runner creates a loopback HTTP endpoint, supplies its unguessable URL and Metro port through the launched app's environment, and the AppDelegate exposes the URL only as a test initial prop. The test-only macOS root runs the shared Mocha suite and posts its structured result to that endpoint. This preserves normal app behavior while giving CI a deterministic completion signal and actionable test failures; it can be replaced by the standard Harness bridge once macOS support exists upstream. Keep release lockfile maintenance in sync with the new macOS Pods workspace, share the test registration used by the UI and CI runner, and document macOS installation, launch, database-location, and vector-search workflows.
Restore the original performance_mode selector and its mode 1 default, including the thread-unsafe SQLite compile flag and the existing mode 2 thread-safe branch. This preserves the Apple build behavior and local configuration point that existed before macOS support was added. Regenerate the iOS and macOS Pod lockfiles so CocoaPods consumes the restored podspec consistently in local builds, release lockfile maintenance, and CI.
Expose the Android, iOS, and macOS harness workflows through workflow_dispatch so maintainers can validate any platform without waiting for a pull request event.\n\nThe existing pull_request path filters remain unchanged, preserving the current automatic CI scope while enabling on-demand reruns and investigation from the Actions UI.
Replace the hard-coded legacy performance selector with the validated NITRO_SQLITE_THREADSAFE CocoaPods setting. The setting accepts only 0 or 1 and defaults to 0, retaining the existing iOS build configuration. Opt the React Native macOS example into SQLITE_THREADSAFE=1 because its async APIs execute on Nitro worker threads. This avoids unsafe concurrent SQLite access while leaving iOS behavior unchanged. Regenerate the macOS Podfile lockfile and document how downstream Apple applications can opt into mutex support before installing Pods. Validation: ruby podspec syntax check; macOS and iOS pod installs; generated Debug/Release xcconfig checks for macOS=1 and iOS=0; clean macOS Debug build; four CI-style macOS runner passes with 69 passing tests each; root typecheck; non-mutating ESLint checks; Prettier check; invalid configuration rejection.
Align every handwritten SQLite helper and hybrid object with Nitrogen's generated margelo::nitro::rnnitrosqlite namespace. This removes the stale parallel namespace and broad using declarations that made the generated macOS bindings and native implementation refer to different types. Resolve internal headers relative to their owning directory so CocoaPods cannot accidentally select op-sqlite's similarly named headers. Correct SQLite column metadata comparisons so declared BOOLEAN, FLOAT, INTEGER, TEXT, and BLOB types map to their intended Nitro result representations. Expose the package source through the react-native export condition. React Native macOS can now resolve the local package without falling back from a missing prebuilt CommonJS artifact during development. Validated with package type checking and build, a clean Metro macOS bundle, CocoaPods installation, an arm64 macOS Xcode build, and the ORM benchmark's native Column, Objects, Types, and unsupported Arrays paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Partially resolves #34
This PR adds first-class React Native macOS support to the example app and test infrastructure.
The new desktop workspace reuses the existing SQLite, TypeORM, sqlite-vec, SQL console, benchmark, and shared Mocha test flows while adding the macOS-specific native, navigation, Metro, Babel, CocoaPods, and CI plumbing required to run them reliably.
It also introduces a deterministic macOS integration-test transport because React Native Harness does not currently provide a macOS runner or desktop-app lifecycle bridge.
What鈥檚 included
React Native macOS example workspace
example/macosReact Native macOS workspace.Native macOS integration
react-native-get-random-valuesso it registers correctly in a macOS new-architecture build.SQLite thread-safety configuration
SQLite is now configured per Apple target through
NITRO_SQLITE_THREADSAFE.0or1.SQLITE_THREADSAFE=0.SQLITE_THREADSAFE=1.This preserves the existing iOS configuration while preventing the macOS app from crashing during repeated or concurrent async SQLite CI work.
macOS CI coverage
Added dedicated macOS workflows for pushes and pull requests.
Test-result transport
React Native Harness currently supports Android and iOS, but not macOS desktop-process lifecycle management.
Until upstream macOS support exists, the macOS runner uses a small explicit test-only transport:
AppDelegateexposes the report URL only as a test initial prop.This keeps production behavior unchanged while giving CI deterministic completion and actionable failures.
Documentation
Added or updated documentation for:
NITRO_SQLITE_THREADSAFEconfiguration for Apple buildsValidation
SQLITE_THREADSAFE=1.SQLITE_THREADSAFE=0.69 passed, 0 failedAI assistance
This PR was implemented and documented with AI assistance. The validation results above were run locally against the resulting macOS build.
Screenshots