expo-modules-jsi 56.0.6 → 56.0.7

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,14 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
+ ## 56.0.7 — 2026-05-20
14
+
15
+ ### 🐛 Bug fixes
16
+
17
+ - [iOS] Implement converters for `JavaScriptRepresentable` to prevent crashes on iOS 17 and 16. ([#45950](https://github.com/expo/expo/pull/45950) by [@behenate](https://github.com/behenate))
18
+
19
+ ### 💡 Others
20
+
13
21
  ## 56.0.6 — 2026-05-19
14
22
 
15
23
  ### 🐛 Bug fixes
@@ -16,7 +16,18 @@ internal protocol JSIRepresentable: JavaScriptRepresentable, Sendable, ~Copyable
16
16
  func toJSIValue(in runtime: facebook.jsi.IRuntime) -> facebook.jsi.Value
17
17
  }
18
18
 
19
- internal extension JSIRepresentable {
19
+ extension JSIRepresentable {
20
+ public static func fromJavaScriptValue(_ value: JavaScriptValue) -> Self {
21
+ guard let jsiRuntime = value.runtime else {
22
+ FatalError.runtimeLost()
23
+ }
24
+ return Self.fromJSIValue(value.pointee, in: jsiRuntime.pointee)
25
+ }
26
+
27
+ public func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
28
+ return JavaScriptValue(runtime, toJSIValue(in: runtime.pointee))
29
+ }
30
+
20
31
  static func fromJSIValue(_ value: borrowing facebook.jsi.Value, in runtime: facebook.jsi.IRuntime) -> Self {
21
32
  FatalError.unimplemented()
22
33
  }
@@ -16,25 +16,50 @@ public protocol JavaScriptRepresentable: Sendable, ~Copyable {
16
16
  func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue
17
17
  }
18
18
 
19
- public extension JavaScriptRepresentable {
20
- static func fromJavaScriptValue(_ value: JavaScriptValue) -> Self {
21
- guard let jsiRuntime = value.runtime else {
22
- FatalError.runtimeLost()
19
+ extension Optional: JavaScriptRepresentable where Wrapped: JavaScriptRepresentable {
20
+ public static func fromJavaScriptValue(_ value: JavaScriptValue) -> Self {
21
+ if value.isNull() || value.isUndefined() {
22
+ return nil
23
23
  }
24
- if let JSIRepresentableType = Self.self as? JSIRepresentable.Type {
25
- return JSIRepresentableType.fromJSIValue(value.pointee, in: jsiRuntime.pointee) as! Self
26
- }
27
- FatalError.unimplemented()
24
+ return Wrapped.fromJavaScriptValue(value)
28
25
  }
29
26
 
30
- func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
31
- if let self = self as? JSIRepresentable {
32
- return JavaScriptValue(runtime, self.toJSIValue(in: runtime.pointee))
27
+ public func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
28
+ guard let self else {
29
+ return .null
33
30
  }
34
- FatalError.unimplemented()
31
+ return self.toJavaScriptValue(in: runtime)
35
32
  }
36
33
  }
37
34
 
38
- extension Optional: JavaScriptRepresentable where Wrapped: JavaScriptRepresentable {}
39
- extension Array: JavaScriptRepresentable where Element: JavaScriptRepresentable {}
40
- extension Dictionary: JavaScriptRepresentable where Key == String, Value: JavaScriptRepresentable {}
35
+ extension Array: JavaScriptRepresentable where Element: JavaScriptRepresentable {
36
+ public static func fromJavaScriptValue(_ value: JavaScriptValue) -> Self {
37
+ return value.getArray().map { Element.fromJavaScriptValue($0) }
38
+ }
39
+
40
+ public func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
41
+ let values = map { $0.toJavaScriptValue(in: runtime) }
42
+ return JavaScriptArray(runtime, items: values).asValue()
43
+ }
44
+ }
45
+
46
+ extension Dictionary: JavaScriptRepresentable where Key == String, Value: JavaScriptRepresentable {
47
+ public static func fromJavaScriptValue(_ value: JavaScriptValue) -> Self {
48
+ let object = value.getObject()
49
+ var result: Self = [:]
50
+
51
+ for key in object.getPropertyNames() {
52
+ result[key] = Value.fromJavaScriptValue(object.getProperty(key))
53
+ }
54
+ return result
55
+ }
56
+
57
+ public func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
58
+ let object = JavaScriptObject(runtime)
59
+
60
+ for (key, value) in self {
61
+ object.setProperty(key, value: value.toJavaScriptValue(in: runtime))
62
+ }
63
+ return object.asValue()
64
+ }
65
+ }
@@ -89,7 +89,16 @@ public final class JavaScriptRef<T: JavaScriptType & ~Copyable>: JavaScriptType,
89
89
  }
90
90
  }
91
91
 
92
- extension JavaScriptRef: JavaScriptRepresentable where T: JavaScriptRepresentable & ~Copyable {}
92
+ extension JavaScriptRef: JavaScriptRepresentable where T: JavaScriptRepresentable & ~Copyable {
93
+ public static func fromJavaScriptValue(_ value: JavaScriptValue) -> JavaScriptRef<T> {
94
+ return JavaScriptRef(T.fromJavaScriptValue(value))
95
+ }
96
+
97
+ public func toJavaScriptValue(in runtime: JavaScriptRuntime) -> JavaScriptValue {
98
+ return take()?.toJavaScriptValue(in: runtime) ?? .undefined
99
+ }
100
+ }
101
+
93
102
  extension JavaScriptRef: JSIRepresentable where T: JSIRepresentable & ~Copyable {
94
103
  static func fromJSIValue(_ value: borrowing facebook.jsi.Value, in runtime: facebook.jsi.IRuntime) -> JavaScriptRef {
95
104
  FatalError.unimplemented()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-modules-jsi",
3
- "version": "56.0.6",
3
+ "version": "56.0.7",
4
4
  "description": "The JavaScript Interface for Expo Modules",
5
5
  "main": "index.js",
6
6
  "sideEffects": [],
@@ -41,7 +41,7 @@
41
41
  "./apple/scripts/test.sh"
42
42
  ]
43
43
  },
44
- "gitHead": "290368bc41026449a05a4ebf991b85c3a2fb0e3a",
44
+ "gitHead": "c4c9867a0bcbb188e55ecaec4998e38d33108a5d",
45
45
  "scripts": {
46
46
  "build": "apple/scripts/build-xcframework.sh",
47
47
  "test": "apple/scripts/test.sh"