expo-modules-jsi 57.0.3 → 57.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,6 +10,12 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 57.0.4 — 2026-07-22
14
+
15
+ ### 💡 Others
16
+
17
+ - Added a script to clear local build caches and artifacts. ([#47603](https://github.com/expo/expo/pull/47603) by [@tsapeta](https://github.com/tsapeta))
18
+
13
19
  ## 57.0.3 — 2026-07-15
14
20
 
15
21
  _This version does not introduce any user-facing changes._
@@ -84,6 +90,21 @@ _This version does not introduce any user-facing changes._
84
90
  - [iOS] Throw instead of aborting when `getPropertyAsFunction` targets a missing or non-callable property. ([#46437](https://github.com/expo/expo/pull/46437) by [@tsapeta](https://github.com/tsapeta))
85
91
  - [iOS] Throw instead of aborting when `getPropertyAsObject` targets a non-object property. ([#46438](https://github.com/expo/expo/pull/46438) by [@tsapeta](https://github.com/tsapeta))
86
92
  - [iOS] Include the Swift toolchain version in the xcframework cache key so upgrading Xcode rebuilds slices instead of reusing ones built by an older compiler. ([#46523](https://github.com/expo/expo/pull/46523) by [@tsapeta](https://github.com/tsapeta))
93
+ - [iOS] Clear stale build intermediates before rebuilding xcframework slices to avoid compiler errors. ([#46399](https://github.com/expo/expo/pull/46399) by [@alanjhughes](https://github.com/alanjhughes))
94
+ - [iOS] Type the host-object setter pointer explicitly so the nil-check conversion type-checks reliably. ([#46736](https://github.com/expo/expo/pull/46736) by [@tsapeta](https://github.com/tsapeta))
95
+ - [iOS] Awaiting a `JavaScriptPromise` that is rejected after the await begins now throws instead of resuming with the rejection value as if fulfilled. ([#47154](https://github.com/expo/expo/pull/47154) by [@tsapeta](https://github.com/tsapeta))
96
+ - [iOS] Preserve the `code` on the JavaScript error when an async function rejects with a `JavaScriptThrowable` (e.g. an `Exception`), instead of stringifying it and dropping the `code` — mirroring the synchronous throw path. ([#47259](https://github.com/expo/expo/pull/47259) by [@wwdrew](https://github.com/wwdrew))
97
+ - [iOS] Return `NSNull` instead of trapping in the deprecated `JavaScriptValue.getAny()` when it encounters a unrepresentable value. ([#47381](https://github.com/expo/expo/pull/47381) by [@alanjhughes](https://github.com/alanjhughes))
98
+ - [iOS] Fixed the `Build ExpoModulesJSI xcframework` build phase intermittently failing on Xcode 27 when clearing stale build state raced Xcode's background indexer writing into the SwiftPM index store. ([#47914](https://github.com/expo/expo/pull/47914) by [@tsapeta](https://github.com/tsapeta))
99
+
100
+ ### 💡 Others
101
+
102
+ - [iOS] Sync host functions no longer allocate a `JavaScriptRef` per call: the arguments buffer is now built inside the synchronous `assumeIsolated` closure instead of being boxed to cross the closure boundary, removing a heap allocation and its retain/release/dealloc from every host call (measured ~10% faster on the no-op `@JS` host-call floor). ([#46949](https://github.com/expo/expo/pull/46949) by [@tsapeta](https://github.com/tsapeta))
103
+ - [iOS] `JavaScriptUnownedValue` and `JavaScriptValuesBuffer` now cache the runtime as the immortal `facebook.jsi.IRuntime` instead of the ARC-managed `JavaScriptRuntime` wrapper, removing per-call retain/release on the argument-decode hot path (measured ~16% faster `addNumbers`, ~24% faster `addStrings`). ([#46678](https://github.com/expo/expo/pull/46678) by [@tsapeta](https://github.com/tsapeta))
104
+ - `NativeArrayBuffer` arguments no longer copy the buffer when it's already native-backed. ([#46448](https://github.com/expo/expo/pull/46448) by [@barthap](https://github.com/barthap))
105
+ - [iOS] `JavaScriptNativeState` can now back any `jsi::NativeState` subtype via a `void *` factory, so consumers without Swift/C++ interop (e.g. `expo-modules-core`) can supply their own pointee. `expo::NativeState` ships from the xcframework as a public C++ header. ([#46330](https://github.com/expo/expo/pull/46330) by [@tsapeta](https://github.com/tsapeta))
106
+ - [iOS] Ignore already-settled promises. ([#46765](https://github.com/expo/expo/pull/46765) by [@jakex7](https://github.com/jakex7))
107
+ - [iOS] `getExpoNativeState` now probes with the specialized `hasNativeState<jsi::NativeState>` and dynamic-casts the raw pointer once, avoiding a redundant `dynamic_pointer_cast` on the shared object argument unwrap hot path. ([#46712](https://github.com/expo/expo/pull/46712) by [@tsapeta](https://github.com/tsapeta))
87
108
 
88
109
  ## 56.0.7 — 2026-05-20
89
110
 
@@ -194,6 +194,16 @@ build_slice() {
194
194
  # default, which breaks callers that pin a toolchain via DEVELOPER_DIR (e.g. the
195
195
  # publish pipeline targeting a specific Xcode) and the in-Xcode build phase when
196
196
  # the running Xcode differs from the global one.
197
+ #
198
+ # SYMROOT/OBJROOT are pinned explicitly because Xcode emits
199
+ # "Supported platforms for the buildables in the current scheme is empty" for
200
+ # an auto-generated SwiftPM scheme and then ignores -derivedDataPath when
201
+ # placing build products — writing them to a default $TMPDIR-derived location
202
+ # instead. The build still succeeds, but the framework lands outside
203
+ # DERIVED_DATA_PATH and the "did not produce" check below fails. Pinning
204
+ # SYMROOT/OBJROOT to the paths this script reads from forces products and the
205
+ # generated module maps back into DERIVED_DATA_PATH. On Xcode versions that
206
+ # honor -derivedDataPath these point at the same locations, so it's a no-op.
197
207
  local env_args=(PATH="$PATH" HOME="$HOME" PODS_ROOT="$PODS_ROOT" RN_ROOT="$RN_ROOT")
198
208
  if [[ -n "${DEVELOPER_DIR:-}" ]]; then
199
209
  env_args+=(DEVELOPER_DIR="$DEVELOPER_DIR")
@@ -212,6 +222,8 @@ build_slice() {
212
222
  -skipPackagePluginValidation \
213
223
  -skipMacroValidation \
214
224
  -parallelizeTargets \
225
+ SYMROOT="${BUILD_PRODUCTS_PATH}" \
226
+ OBJROOT="${DERIVED_DATA_PATH}/Build/Intermediates.noindex" \
215
227
  BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
216
228
  SKIP_INSTALL=NO \
217
229
  DEBUG_INFORMATION_FORMAT=dwarf-with-dsym \
@@ -401,7 +413,7 @@ GENERATED_MODULE_MAP="${PACKAGE_DIR}/.generated/module.modulemap"
401
413
  SOURCE_FILES+=("$GENERATED_MODULE_MAP")
402
414
 
403
415
  if [[ "$CLEAN" == true ]]; then
404
- rm -rf "$XCFRAMEWORK_PATH" "$DERIVED_DATA_PATH" "$SPM_BUILD_PATH" "$SPM_WORKSPACE_PATH"
416
+ clean_xcframework_state "$PACKAGE_DIR"
405
417
  log "Cleaned existing xcframework, DerivedData, and SwiftPM state"
406
418
  # Re-stamp stub slices so the post-clean state matches a fresh `pod install`:
407
419
  # CocoaPods reads Info.plist before this script runs, and would fail to
@@ -441,6 +453,16 @@ fi
441
453
 
442
454
  PLATFORMS=("${platforms_to_build[@]}")
443
455
 
456
+ # Wipe stale intermediates before compiling: DerivedData's module cache and the
457
+ # SwiftPM workspace/.build tree carry over from earlier runs and can reference
458
+ # headers or module layouts that no longer match (e.g. after switching branches).
459
+ # Only runs when a slice needs rebuilding, so the up-to-date fast path is unaffected.
460
+ # Products/ is preserved. build_slice replaces only the slice it rebuilds. The
461
+ # generated modulemap is left intact — it was already regenerated above for the
462
+ # cache hash, so wiping it here would just force a redundant rebuild.
463
+ log "Clearing stale build state (DerivedData, SwiftPM) before rebuild"
464
+ safe_remove_dirs "$DERIVED_DATA_PATH" "$SPM_BUILD_PATH" "$SPM_WORKSPACE_PATH"
465
+
444
466
  SECONDS=0
445
467
 
446
468
  for platform in "${PLATFORMS[@]}"; do
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+
3
+ # Removes the package's local build caches and artifacts.
4
+
5
+ set -euo pipefail
6
+
7
+ PACKAGE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8
+
9
+ source "${PACKAGE_DIR}/scripts/xcframework-helpers.sh"
10
+
11
+ BLUE=""; RESET=""
12
+ if [ -t 1 ]; then
13
+ BLUE="\033[34m"
14
+ RESET="\033[0m"
15
+ fi
16
+ echo -e "${BLUE}[Expo]${RESET} Clearing ExpoModulesJSI caches and build artifacts"
17
+
18
+ clean_xcframework_state "$PACKAGE_DIR"
19
+ safe_remove_dirs \
20
+ "${PACKAGE_DIR}/.generated" \
21
+ "${PACKAGE_DIR}/.xcframework-slices" \
22
+ "${PACKAGE_DIR}/.test-frameworks"
@@ -1,8 +1,40 @@
1
1
  # Shared helpers for managing ExpoModulesJSI.xcframework.
2
2
  #
3
- # Sourced by create-stub-xcframework.sh and build-xcframework.sh. Defines the
4
- # canonical slice metadata and the Info.plist writer used by both scripts so
5
- # the manifest is produced from a single place.
3
+ # Sourced by create-stub-xcframework.sh, build-xcframework.sh and
4
+ # clear-caches.sh. Defines the canonical slice metadata and the Info.plist
5
+ # writer used by those scripts so the manifest is produced from a single place.
6
+
7
+ # safe_remove_dirs DIR...
8
+ # Deletes directories tolerantly. Xcode's background indexer keeps writing into
9
+ # the SwiftPM index store under `.build`, which can make a plain `rm -rf` fail
10
+ # with ENOTEMPTY mid-walk and abort the caller under `set -e`. Renaming each
11
+ # directory away first (atomic within the filesystem) detaches the live path, so
12
+ # the delete of the leftover can race harmlessly; its failure is ignored.
13
+ safe_remove_dirs() {
14
+ local dir
15
+ for dir in "$@"; do
16
+ [[ -e "$dir" ]] || continue
17
+ local trash="${dir}.trash.$$"
18
+ if mv "$dir" "$trash" 2>/dev/null; then
19
+ rm -rf "$trash" 2>/dev/null || true
20
+ else
21
+ rm -rf "$dir" 2>/dev/null || true
22
+ fi
23
+ done
24
+ }
25
+
26
+ # clean_xcframework_state PACKAGE_DIR
27
+ # Removes the built xcframework and the SwiftPM/Xcode build state next to the
28
+ # package. Shared by build-xcframework.sh's --clean path and clear-caches.sh.
29
+ clean_xcframework_state() {
30
+ local package_dir="$1"
31
+
32
+ safe_remove_dirs \
33
+ "${package_dir}/Products/ExpoModulesJSI.xcframework" \
34
+ "${package_dir}/.DerivedData" \
35
+ "${package_dir}/.build" \
36
+ "${package_dir}/.swiftpm"
37
+ }
6
38
 
7
39
  # resolve_pods_root PACKAGE_DIR
8
40
  # Sets PODS_ROOT, preferring an explicit value (e.g. from CocoaPods build phase)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-jsi",
3
- "version": "57.0.3",
3
+ "version": "57.0.4",
4
4
  "description": "The JavaScript Interface for Expo Modules",
5
5
  "main": "index.js",
6
6
  "sideEffects": [],
@@ -41,9 +41,10 @@
41
41
  "./apple/scripts/test.sh"
42
42
  ]
43
43
  },
44
- "gitHead": "b9503d06b8e130abfca1bc16f671dbefb41ad709",
44
+ "gitHead": "a4789f1e53353f4929b0baddcfe5a7c622b99c71",
45
45
  "scripts": {
46
46
  "build": "apple/scripts/build-xcframework.sh",
47
+ "clean": "apple/scripts/clear-caches.sh",
47
48
  "swift:format": "../../scripts/swift-format.sh",
48
49
  "swift:lint": "../../scripts/swift-format.sh --lint",
49
50
  "test": "apple/scripts/test.sh"