From 69c1894f23da0520e62a739a3d544e47f9ec0bf3 Mon Sep 17 00:00:00 2001 From: Oskar Eichler <62393985+OskarEichler@users.noreply.github.com> Date: Fri, 28 Aug 2026 02:45:58 +0300 Subject: [PATCH 1/4] fix(example): scope setup caches and refresh each demo installation --- .gitignore | 1 + examples/demo-no-location/metro.config.js | 9 ++- examples/demo/metro.config.js | 6 ++ examples/setup.sh | 78 +++++++++++++---------- 4 files changed, 58 insertions(+), 36 deletions(-) diff --git a/.gitignore b/.gitignore index 6a670398..42c91ba7 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ dist android/build *.tgz .rn-sdk-source.stamp +.rn-demo-env.stamp # OSX # diff --git a/examples/demo-no-location/metro.config.js b/examples/demo-no-location/metro.config.js index 2a0a21ce..4b9a4662 100644 --- a/examples/demo-no-location/metro.config.js +++ b/examples/demo-no-location/metro.config.js @@ -1,4 +1,6 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); +const { FileStore } = require('metro-cache'); +const path = require('node:path'); /** * Metro configuration @@ -6,6 +8,11 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); * * @type {import('@react-native/metro-config').MetroConfig} */ -const config = {}; +const config = { + cacheStores: [ + new FileStore({ root: path.join(__dirname, 'node_modules/.cache/metro/transform') }), + ], + fileMapCacheDirectory: path.join(__dirname, 'node_modules/.cache/metro/file-map'), +}; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/examples/demo/metro.config.js b/examples/demo/metro.config.js index 74bce611..1ffde377 100644 --- a/examples/demo/metro.config.js +++ b/examples/demo/metro.config.js @@ -1,4 +1,6 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); +const { FileStore } = require('metro-cache'); +const path = require('node:path'); /** * Metro configuration @@ -10,6 +12,10 @@ const defaultConfig = getDefaultConfig(__dirname); const { assetExts, sourceExts } = defaultConfig.resolver; const config = { + cacheStores: [ + new FileStore({ root: path.join(__dirname, 'node_modules/.cache/metro/transform') }), + ], + fileMapCacheDirectory: path.join(__dirname, 'node_modules/.cache/metro/file-map'), transformer: { babelTransformerPath: require.resolve('react-native-svg-transformer'), }, diff --git a/examples/setup.sh b/examples/setup.sh index 9f2b6313..0ce76475 100755 --- a/examples/setup.sh +++ b/examples/setup.sh @@ -2,11 +2,15 @@ set -euo pipefail # Invoked from a demo dir (e.g. examples/demo/) via `vp run setup`. -# ORIGINAL_DIR captures that dir so we can return to it after building -# the SDK; SDK_ROOT is two levels up (the SDK package itself). -ORIGINAL_DIR=$(pwd) -SDK_ROOT="$(cd ../../ && pwd)" +# Resolve the SDK independently of the caller before touching generated files. +ORIGINAL_DIR=$(pwd -P) +SDK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +case "$ORIGINAL_DIR" in + "$SDK_ROOT/examples/demo"|"$SDK_ROOT/examples/demo-no-location") ;; + *) echo "Run setup from examples/demo or examples/demo-no-location." >&2; exit 1 ;; +esac STAMP_FILE="$SDK_ROOT/.rn-sdk-source.stamp" +DEMO_SDK_STAMP_FILE="$ORIGINAL_DIR/.rn-sdk-source.stamp" DEMO_ENV_STAMP_FILE="$ORIGINAL_DIR/.rn-demo-env.stamp" TGZ_FILE="$SDK_ROOT/react-native-onesignal.tgz" INSTALLED_DIR="$ORIGINAL_DIR/node_modules/react-native-onesignal" @@ -16,18 +20,20 @@ INSTALLED_DIR="$ORIGINAL_DIR/node_modules/react-native-onesignal" # combined list) instead of using `find -newer`, because mtimes get # bumped by routine git operations (checkout, branch switch, rebase) # even when the source is identical — that caused needless rebuilds. -src_hash=$(find "$SDK_ROOT/src" "$SDK_ROOT/ios" "$SDK_ROOT/android" \ +src_hash=$(find "$SDK_ROOT/src" "$SDK_ROOT/ios" "$SDK_ROOT/android/src" \ + "$SDK_ROOT/android/build.gradle" "$SDK_ROOT/android/proguard-rules.pro" \ "$SDK_ROOT/package.json" "$SDK_ROOT/tsconfig.json" \ + "$SDK_ROOT/vite.config.ts" "$SDK_ROOT/bun.lock" \ + "$SDK_ROOT/README.md" "$SDK_ROOT/LICENSE" \ "$SDK_ROOT"/*.podspec \ - -type f 2>/dev/null \ - | sort \ - | xargs shasum 2>/dev/null \ + -type f -exec shasum {} + \ + | LC_ALL=C sort \ | shasum \ | awk '{print $1}') demo_env_hash=$( { - for file in "$ORIGINAL_DIR/.env" "$ORIGINAL_DIR/babel.config.js"; do + for file in "$ORIGINAL_DIR/.env" "$ORIGINAL_DIR/babel.config.js" "$ORIGINAL_DIR/metro.config.js"; do if [ -f "$file" ]; then shasum "$file" else @@ -39,49 +45,52 @@ demo_env_hash=$( if [ ! -f "$DEMO_ENV_STAMP_FILE" ] || [ "$(cat "$DEMO_ENV_STAMP_FILE")" != "$demo_env_hash" ]; then echo "Demo env inputs changed, clearing Metro cache..." - rm -rf "${TMPDIR:-/tmp}"/metro-* "${TMPDIR:-/tmp}"/haste-map-* "$ORIGINAL_DIR/node_modules/.cache/metro" 2>/dev/null || true + # Both demo Metro configs keep their transform and file-map caches here. + rm -rf "$ORIGINAL_DIR/node_modules/.cache/metro" metro_pids=$(lsof -ti tcp:8081 2>/dev/null || true) for pid in $metro_pids; do args=$(ps -p "$pid" -o args= 2>/dev/null || true) case "$args" in *react-native*|*metro*) - echo "Stopping Metro so @env values are reloaded..." - kill "$pid" 2>/dev/null || true + metro_cwd=$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' || true) + if [ "$metro_cwd" = "$ORIGINAL_DIR" ]; then + echo "Stopping this demo's Metro so @env values are reloaded..." + kill "$pid" 2>/dev/null || true + fi ;; esac done echo "$demo_env_hash" > "$DEMO_ENV_STAMP_FILE" fi -# Skip the whole rebuild when: -# - the demo already has the SDK installed, -# - the cached tarball is still on disk, and -# - the source hash matches the last successful build. +# Track each demo's installation separately from the shared package build. # FORCE_SETUP=1 bypasses the cache when something feels off. if [ "${FORCE_SETUP:-0}" != "1" ] \ && [ -d "$INSTALLED_DIR" ] \ && [ -f "$STAMP_FILE" ] \ + && [ -f "$DEMO_SDK_STAMP_FILE" ] \ && [ -f "$TGZ_FILE" ] \ - && [ "$(cat "$STAMP_FILE")" = "$src_hash" ]; then + && [ "$(cat "$STAMP_FILE")" = "$src_hash" ] \ + && [ "$(cat "$DEMO_SDK_STAMP_FILE")" = "$src_hash" ]; then echo "SDK source unchanged, skipping rebuild. Set FORCE_SETUP=1 to override." exit 0 fi -cd "$SDK_ROOT" -vp run build - -# `vp pm pack` (wraps bun pm pack) honors package.json's "files" field -# (so the tarball matches what would actually be published). The version -# suffix in the filename is unstable, so we normalize to -# react-native-onesignal.tgz for a deterministic path that package.json + -# the extract step can reference. -rm -f react-native-onesignal*.tgz -vp pm pack -mv react-native-onesignal-*.tgz react-native-onesignal.tgz +if [ "${FORCE_SETUP:-0}" = "1" ] \ + || [ ! -f "$STAMP_FILE" ] \ + || [ ! -f "$TGZ_FILE" ] \ + || [ "$(cat "$STAMP_FILE")" != "$src_hash" ]; then + cd "$SDK_ROOT" + vp run build + # Use the pinned package manager through Vite+; the local CLI also supports + # `exec`, unlike the global-only `vp pm`/`vp add` shortcuts. + vp exec bun pm pack --filename "$TGZ_FILE" + echo "$src_hash" > "$STAMP_FILE" +fi cd "$ORIGINAL_DIR" -# Always go through `vp add` (wraps bun) so bun.lock's integrity hash for +# Always go through the package manager so bun.lock's integrity hash for # the tarball stays in sync with the freshly-built tarball on disk. A # previous version of this script had a "hot path" that just untarred # over node_modules directly, which was faster but left a stale sha512 @@ -89,15 +98,14 @@ cd "$ORIGINAL_DIR" # (e.g. when the lockfile was touched by another dep) would fail with # IntegrityCheckFailed. # -# `vp remove` first because bun verifies the existing integrity hash -# before replacing the entry; without removing, a stale hash from a prior -# build causes `vp add` itself to fail. The relative `file:../../...` +# Remove first because bun verifies the existing integrity hash before +# replacing the entry. The relative `file:../../...` # path is intentional — an absolute path would leak this machine's # layout into the lockfile. echo "Registering tarball with vp (refreshes bun.lock integrity hash)..." -vp remove react-native-onesignal 2>/dev/null || true -vp add file:../../react-native-onesignal.tgz +vp exec bun remove react-native-onesignal +vp install file:../../react-native-onesignal.tgz # Record the hash only after a successful build/install so that an # interrupted run forces a full retry next time. -echo "$src_hash" > "$STAMP_FILE" +echo "$src_hash" > "$DEMO_SDK_STAMP_FILE" From 87837e832699affbcd795591a9f3845c1d343fcd Mon Sep 17 00:00:00 2001 From: Oskar Eichler <62393985+OskarEichler@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:07:55 +0300 Subject: [PATCH 2/4] Use Vite+ package removal command --- examples/setup.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/setup.sh b/examples/setup.sh index 0ce76475..19b07410 100755 --- a/examples/setup.sh +++ b/examples/setup.sh @@ -103,7 +103,7 @@ cd "$ORIGINAL_DIR" # path is intentional — an absolute path would leak this machine's # layout into the lockfile. echo "Registering tarball with vp (refreshes bun.lock integrity hash)..." -vp exec bun remove react-native-onesignal +vp remove react-native-onesignal vp install file:../../react-native-onesignal.tgz # Record the hash only after a successful build/install so that an From 21a396a53412ee6462b83cba6bc7aef8cc8e5c11 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Sun, 30 Aug 2026 14:47:52 +0700 Subject: [PATCH 3/4] Fix Vite+ demo package registration --- examples/setup.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/setup.sh b/examples/setup.sh index 19b07410..4686f8b7 100755 --- a/examples/setup.sh +++ b/examples/setup.sh @@ -82,8 +82,8 @@ if [ "${FORCE_SETUP:-0}" = "1" ] \ || [ "$(cat "$STAMP_FILE")" != "$src_hash" ]; then cd "$SDK_ROOT" vp run build - # Use the pinned package manager through Vite+; the local CLI also supports - # `exec`, unlike the global-only `vp pm`/`vp add` shortcuts. + # Use the pinned package manager through Vite+ so the archive is written to + # the deterministic filename consumed below. vp exec bun pm pack --filename "$TGZ_FILE" echo "$src_hash" > "$STAMP_FILE" fi @@ -104,7 +104,7 @@ cd "$ORIGINAL_DIR" # layout into the lockfile. echo "Registering tarball with vp (refreshes bun.lock integrity hash)..." vp remove react-native-onesignal -vp install file:../../react-native-onesignal.tgz +vp add file:../../react-native-onesignal.tgz # Record the hash only after a successful build/install so that an # interrupted run forces a full retry next time. From 5b6177c17ce641c8ef6f331c5079fb5fbfe0e1d1 Mon Sep 17 00:00:00 2001 From: Fadi George Date: Mon, 31 Aug 2026 11:05:14 -0700 Subject: [PATCH 4/4] refactor(example): simplify demo tarball cache and keep Metro env invalidation Co-authored-by: Cursor --- examples/demo-no-location/metro.config.js | 14 ++- examples/demo/metro.config.js | 13 +- examples/run-android.sh | 2 +- examples/run-ios.sh | 2 +- examples/setup.sh | 138 +++++++--------------- package.json | 2 +- 6 files changed, 61 insertions(+), 110 deletions(-) diff --git a/examples/demo-no-location/metro.config.js b/examples/demo-no-location/metro.config.js index 4b9a4662..4b112559 100644 --- a/examples/demo-no-location/metro.config.js +++ b/examples/demo-no-location/metro.config.js @@ -1,5 +1,6 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); -const { FileStore } = require('metro-cache'); +const crypto = require('node:crypto'); +const fs = require('node:fs'); const path = require('node:path'); /** @@ -8,11 +9,14 @@ const path = require('node:path'); * * @type {import('@react-native/metro-config').MetroConfig} */ +const envPath = path.join(__dirname, '.env'); +const envHash = fs.existsSync(envPath) + ? crypto.createHash('sha1').update(fs.readFileSync(envPath)).digest('hex') + : 'missing'; + const config = { - cacheStores: [ - new FileStore({ root: path.join(__dirname, 'node_modules/.cache/metro/transform') }), - ], - fileMapCacheDirectory: path.join(__dirname, 'node_modules/.cache/metro/file-map'), + // react-native-dotenv does not include .env in Metro's transform cache key. + cacheVersion: `env-${envHash}`, }; module.exports = mergeConfig(getDefaultConfig(__dirname), config); diff --git a/examples/demo/metro.config.js b/examples/demo/metro.config.js index 1ffde377..7427d98f 100644 --- a/examples/demo/metro.config.js +++ b/examples/demo/metro.config.js @@ -1,5 +1,6 @@ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); -const { FileStore } = require('metro-cache'); +const crypto = require('node:crypto'); +const fs = require('node:fs'); const path = require('node:path'); /** @@ -10,12 +11,14 @@ const path = require('node:path'); */ const defaultConfig = getDefaultConfig(__dirname); const { assetExts, sourceExts } = defaultConfig.resolver; +const envPath = path.join(__dirname, '.env'); +const envHash = fs.existsSync(envPath) + ? crypto.createHash('sha1').update(fs.readFileSync(envPath)).digest('hex') + : 'missing'; const config = { - cacheStores: [ - new FileStore({ root: path.join(__dirname, 'node_modules/.cache/metro/transform') }), - ], - fileMapCacheDirectory: path.join(__dirname, 'node_modules/.cache/metro/file-map'), + // react-native-dotenv does not include .env in Metro's transform cache key. + cacheVersion: `env-${envHash}`, transformer: { babelTransformerPath: require.resolve('react-native-svg-transformer'), }, diff --git a/examples/run-android.sh b/examples/run-android.sh index df6736f1..1f95b9ae 100755 --- a/examples/run-android.sh +++ b/examples/run-android.sh @@ -37,4 +37,4 @@ else selected="${devices[$idx]}" fi -ANDROID_SERIAL="$selected" bunx react-native run-android --deviceId "$selected" +ANDROID_SERIAL="$selected" vp exec react-native run-android --deviceId "$selected" diff --git a/examples/run-ios.sh b/examples/run-ios.sh index a46af8f4..60d4e940 100755 --- a/examples/run-ios.sh +++ b/examples/run-ios.sh @@ -70,4 +70,4 @@ name="${selected%%|*}" udid="${selected##*|}" echo "Using simulator: $name ($udid)" -bunx react-native run-ios --udid "$udid" +vp exec react-native run-ios --udid "$udid" diff --git a/examples/setup.sh b/examples/setup.sh index 4686f8b7..e92019d3 100755 --- a/examples/setup.sh +++ b/examples/setup.sh @@ -1,111 +1,55 @@ #!/usr/bin/env bash set -euo pipefail -# Invoked from a demo dir (e.g. examples/demo/) via `vp run setup`. -# Resolve the SDK independently of the caller before touching generated files. -ORIGINAL_DIR=$(pwd -P) +DEMO_DIR=$(pwd -P) SDK_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" -case "$ORIGINAL_DIR" in - "$SDK_ROOT/examples/demo"|"$SDK_ROOT/examples/demo-no-location") ;; - *) echo "Run setup from examples/demo or examples/demo-no-location." >&2; exit 1 ;; -esac -STAMP_FILE="$SDK_ROOT/.rn-sdk-source.stamp" -DEMO_SDK_STAMP_FILE="$ORIGINAL_DIR/.rn-sdk-source.stamp" -DEMO_ENV_STAMP_FILE="$ORIGINAL_DIR/.rn-demo-env.stamp" -TGZ_FILE="$SDK_ROOT/react-native-onesignal.tgz" -INSTALLED_DIR="$ORIGINAL_DIR/node_modules/react-native-onesignal" - -# Content hash of every input that can affect the published tarball. -# We deliberately hash file contents (shasum each file, then shasum the -# combined list) instead of using `find -newer`, because mtimes get -# bumped by routine git operations (checkout, branch switch, rebase) -# even when the source is identical — that caused needless rebuilds. -src_hash=$(find "$SDK_ROOT/src" "$SDK_ROOT/ios" "$SDK_ROOT/android/src" \ - "$SDK_ROOT/android/build.gradle" "$SDK_ROOT/android/proguard-rules.pro" \ - "$SDK_ROOT/package.json" "$SDK_ROOT/tsconfig.json" \ - "$SDK_ROOT/vite.config.ts" "$SDK_ROOT/bun.lock" \ - "$SDK_ROOT/README.md" "$SDK_ROOT/LICENSE" \ - "$SDK_ROOT"/*.podspec \ - -type f -exec shasum {} + \ - | LC_ALL=C sort \ - | shasum \ - | awk '{print $1}') - -demo_env_hash=$( - { - for file in "$ORIGINAL_DIR/.env" "$ORIGINAL_DIR/babel.config.js" "$ORIGINAL_DIR/metro.config.js"; do - if [ -f "$file" ]; then - shasum "$file" - else - echo "missing $file" - fi - done - } | shasum | awk '{print $1}' -) +TARBALL="$SDK_ROOT/react-native-onesignal.tgz" +INSTALL_STAMP="$DEMO_DIR/.rn-sdk-source.stamp" +INSTALLED_DIR="$DEMO_DIR/node_modules/react-native-onesignal" +ENV_STAMP="$DEMO_DIR/.rn-demo-env.stamp" + +if [ -f "$DEMO_DIR/.env" ]; then + env_hash=$(shasum "$DEMO_DIR/.env" | awk '{print $1}') +else + env_hash=missing +fi -if [ ! -f "$DEMO_ENV_STAMP_FILE" ] || [ "$(cat "$DEMO_ENV_STAMP_FILE")" != "$demo_env_hash" ]; then - echo "Demo env inputs changed, clearing Metro cache..." - # Both demo Metro configs keep their transform and file-map caches here. - rm -rf "$ORIGINAL_DIR/node_modules/.cache/metro" +if [ ! -f "$ENV_STAMP" ] || [ "$(cat "$ENV_STAMP")" != "$env_hash" ]; then + echo "Demo environment changed; restarting Metro." metro_pids=$(lsof -ti tcp:8081 2>/dev/null || true) for pid in $metro_pids; do - args=$(ps -p "$pid" -o args= 2>/dev/null || true) - case "$args" in - *react-native*|*metro*) - metro_cwd=$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' || true) - if [ "$metro_cwd" = "$ORIGINAL_DIR" ]; then - echo "Stopping this demo's Metro so @env values are reloaded..." - kill "$pid" 2>/dev/null || true - fi - ;; - esac + metro_cwd=$(lsof -a -p "$pid" -d cwd -Fn 2>/dev/null | sed -n 's/^n//p' || true) + if [ "$metro_cwd" = "$DEMO_DIR" ]; then + kill "$pid" 2>/dev/null || true + fi done - echo "$demo_env_hash" > "$DEMO_ENV_STAMP_FILE" + echo "$env_hash" > "$ENV_STAMP" fi -# Track each demo's installation separately from the shared package build. -# FORCE_SETUP=1 bypasses the cache when something feels off. -if [ "${FORCE_SETUP:-0}" != "1" ] \ - && [ -d "$INSTALLED_DIR" ] \ - && [ -f "$STAMP_FILE" ] \ - && [ -f "$DEMO_SDK_STAMP_FILE" ] \ - && [ -f "$TGZ_FILE" ] \ - && [ "$(cat "$STAMP_FILE")" = "$src_hash" ] \ - && [ "$(cat "$DEMO_SDK_STAMP_FILE")" = "$src_hash" ]; then - echo "SDK source unchanged, skipping rebuild. Set FORCE_SETUP=1 to override." - exit 0 +cd "$SDK_ROOT" +vp run build +rm -f react-native-onesignal-*.tgz +vp pm pack + +new_tarball=(react-native-onesignal-*.tgz) +if [ -f "$TARBALL" ] && cmp -s "${new_tarball[0]}" "$TARBALL"; then + rm "${new_tarball[0]}" + echo "SDK package unchanged; using cached react-native-onesignal.tgz." +else + mv "${new_tarball[0]}" "$TARBALL" + echo "SDK package changed; refreshed react-native-onesignal.tgz." fi -if [ "${FORCE_SETUP:-0}" = "1" ] \ - || [ ! -f "$STAMP_FILE" ] \ - || [ ! -f "$TGZ_FILE" ] \ - || [ "$(cat "$STAMP_FILE")" != "$src_hash" ]; then - cd "$SDK_ROOT" - vp run build - # Use the pinned package manager through Vite+ so the archive is written to - # the deterministic filename consumed below. - vp exec bun pm pack --filename "$TGZ_FILE" - echo "$src_hash" > "$STAMP_FILE" +tarball_hash=$(shasum "$TARBALL" | awk '{print $1}') +if [ -d "$INSTALLED_DIR" ] \ + && [ -f "$INSTALL_STAMP" ] \ + && [ "$(cat "$INSTALL_STAMP")" = "$tarball_hash" ]; then + echo "Demo already has this SDK package; skipping reinstall." + exit 0 fi -cd "$ORIGINAL_DIR" - -# Always go through the package manager so bun.lock's integrity hash for -# the tarball stays in sync with the freshly-built tarball on disk. A -# previous version of this script had a "hot path" that just untarred -# over node_modules directly, which was faster but left a stale sha512 -# in bun.lock — any subsequent `vp install` that re-resolved this entry -# (e.g. when the lockfile was touched by another dep) would fail with -# IntegrityCheckFailed. -# -# Remove first because bun verifies the existing integrity hash before -# replacing the entry. The relative `file:../../...` -# path is intentional — an absolute path would leak this machine's -# layout into the lockfile. -echo "Registering tarball with vp (refreshes bun.lock integrity hash)..." -vp remove react-native-onesignal -vp add file:../../react-native-onesignal.tgz - -# Record the hash only after a successful build/install so that an -# interrupted run forces a full retry next time. -echo "$src_hash" > "$DEMO_SDK_STAMP_FILE" +cd "$DEMO_DIR" +echo "Installing updated SDK package in demo..." +vp remove react-native-onesignal 2>/dev/null || true +vp install file:../../react-native-onesignal.tgz +echo "$tarball_hash" > "$INSTALL_STAMP" diff --git a/package.json b/package.json index 0172cc73..799bfdb7 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "vite": "npm:@voidzero-dev/vite-plus-core@latest", "vitest": "npm:@voidzero-dev/vite-plus-test@latest" }, - "packageManager": "bun@1.3.13", + "packageManager": "bun@1.4.0", "codegenConfig": { "name": "RNOneSignalSpec", "type": "modules",