expo-modules-jsi 56.0.7 → 56.0.8

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/CLAUDE.md +4 -0
  3. package/apple/Package.swift +15 -11
  4. package/apple/Sources/ExpoModulesJSI/Contexts/CleanupContext.swift +2 -4
  5. package/apple/Sources/ExpoModulesJSI/Contexts/HostFunctionContext.swift +1 -3
  6. package/apple/Sources/ExpoModulesJSI/Contexts/HostObjectContext.swift +1 -3
  7. package/apple/Sources/ExpoModulesJSI/Extensions/Task+immediate.swift +2 -0
  8. package/apple/Sources/ExpoModulesJSI/Protocols/JSIRepresentable.swift +17 -14
  9. package/apple/Sources/ExpoModulesJSI/Protocols/JavaScriptRepresentable.swift +3 -9
  10. package/apple/Sources/ExpoModulesJSI/Protocols/JavaScriptThrowable.swift +21 -27
  11. package/apple/Sources/ExpoModulesJSI/Protocols/JavaScriptType.swift +10 -18
  12. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptActor.swift +22 -41
  13. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptNativeState.swift +7 -15
  14. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptPropNameID.swift +5 -15
  15. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRef.swift +21 -43
  16. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptRuntime.swift +152 -202
  17. package/apple/Sources/ExpoModulesJSI/Runtime/JavaScriptValuesBuffer.swift +38 -41
  18. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptArray.swift +340 -381
  19. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptArrayBuffer.swift +9 -21
  20. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptBigInt.swift +162 -190
  21. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptError.swift +12 -15
  22. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptFunction.swift +23 -27
  23. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptObject.swift +175 -207
  24. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptPromise.swift +22 -24
  25. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptTypedArray.swift +34 -49
  26. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptValue.swift +122 -176
  27. package/apple/Sources/ExpoModulesJSI/Runtime/Values/JavaScriptWeakObject.swift +6 -14
  28. package/apple/Sources/ExpoModulesJSI/Utilities/ErrorHandling.swift +12 -20
  29. package/apple/Sources/ExpoModulesJSI/Utilities/Errors.swift +10 -22
  30. package/apple/Sources/ExpoModulesJSI/Utilities/NonisolatedUnsafeVar.swift +2 -4
  31. package/apple/Sources/ExpoModulesJSI-Cxx/include/JSIUtils.h +11 -0
  32. package/apple/Tests/JavaScriptActorTests.swift +3 -3
  33. package/apple/Tests/JavaScriptArrayBufferTests.swift +1 -1
  34. package/apple/Tests/JavaScriptArrayTests.swift +6 -4
  35. package/apple/Tests/JavaScriptBigIntTests.swift +20 -20
  36. package/apple/Tests/JavaScriptErrorTests.swift +15 -11
  37. package/apple/Tests/JavaScriptFunctionTests.swift +26 -26
  38. package/apple/Tests/JavaScriptNativeStateTests.swift +1 -1
  39. package/apple/Tests/JavaScriptObjectTests.swift +25 -13
  40. package/apple/Tests/JavaScriptPromiseTests.swift +56 -28
  41. package/apple/Tests/JavaScriptRefTests.swift +1 -1
  42. package/apple/Tests/JavaScriptRuntimeTests.swift +93 -60
  43. package/apple/Tests/JavaScriptTypedArrayTests.swift +20 -14
  44. package/apple/Tests/JavaScriptValueTests.swift +1 -1
  45. package/apple/Tests/JavaScriptValuesBufferTests.swift +1 -1
  46. package/apple/Tests/JavaScriptWeakObjectTests.swift +1 -1
  47. package/apple/scripts/build-xcframework.sh +96 -13
  48. package/apple/scripts/xcframework-helpers.sh +4 -0
  49. package/package.json +4 -2
@@ -1,98 +1,90 @@
1
- internal import jsi
2
1
  internal import ExpoModulesJSI_Cxx
2
+ internal import jsi
3
3
 
4
- /**
5
- A Swift representation of a JavaScript array. `JavaScriptArray` provides a bridge between JavaScript arrays
6
- and Swift, allowing you to access and manipulate JavaScript array elements from Swift code. It maintains a reference
7
- to the underlying JavaScript array and provides Swift-friendly APIs for common array operations.
8
- */
4
+ /// A Swift representation of a JavaScript array. `JavaScriptArray` provides a bridge between JavaScript arrays
5
+ /// and Swift, allowing you to access and manipulate JavaScript array elements from Swift code. It maintains a reference
6
+ /// to the underlying JavaScript array and provides Swift-friendly APIs for common array operations.
9
7
  public struct JavaScriptArray: JavaScriptType, ~Copyable {
10
8
  internal weak let runtime: JavaScriptRuntime?
11
9
  internal let pointee: facebook.jsi.Array
12
10
 
13
- /**
14
- Creates a new JavaScript array with the specified length.
15
-
16
- This is the primary initializer for creating empty or pre-sized JavaScript arrays.
17
- If no length is provided, an empty array is created. When a length is specified,
18
- the array is created with that many elements, each initialized to `undefined`.
19
-
20
- - Parameters:
21
- - runtime: The JavaScript runtime in which to create the array
22
- - length: The initial length of the array. Defaults to 0 (empty array).
23
-
24
- ## Examples
25
-
26
- ```swift
27
- // Create an empty array
28
- let empty = JavaScriptArray(runtime)
29
-
30
- // Create an array with specific length (all elements are undefined)
31
- let sized = JavaScriptArray(runtime, length: 10)
32
- print(sized.length) // 10
33
- print(sized[0]) // undefined
34
- ```
35
-
36
- - Note: This initializer creates a new JavaScript array object in the runtime's heap.
37
- The array's length can be modified later using the `length` property.
38
- - SeeAlso: `init(_:items:)` for creating arrays with initial values
39
- */
11
+ /// Creates a new JavaScript array with the specified length.
12
+ ///
13
+ /// This is the primary initializer for creating empty or pre-sized JavaScript arrays.
14
+ /// If no length is provided, an empty array is created. When a length is specified,
15
+ /// the array is created with that many elements, each initialized to `undefined`.
16
+ ///
17
+ /// - Parameters:
18
+ /// - runtime: The JavaScript runtime in which to create the array
19
+ /// - length: The initial length of the array. Defaults to 0 (empty array).
20
+ ///
21
+ /// ## Examples
22
+ ///
23
+ /// ```swift
24
+ /// // Create an empty array
25
+ /// let empty = JavaScriptArray(runtime)
26
+ ///
27
+ /// // Create an array with specific length (all elements are undefined)
28
+ /// let sized = JavaScriptArray(runtime, length: 10)
29
+ /// print(sized.length) // 10
30
+ /// print(sized[0]) // undefined
31
+ /// ```
32
+ ///
33
+ /// - Note: This initializer creates a new JavaScript array object in the runtime's heap.
34
+ /// The array's length can be modified later using the `length` property.
35
+ /// - SeeAlso: `init(_:items:)` for creating arrays with initial values
40
36
  public init(_ runtime: JavaScriptRuntime, length: Int = 0) {
41
37
  self.init(runtime, facebook.jsi.Array(runtime.pointee, length))
42
38
  }
43
39
 
44
- /**
45
- Creates a Swift wrapper around an existing JSI array object.
46
-
47
- This internal initializer is used to wrap a C++ JSI `Array` object with a Swift
48
- `JavaScriptArray` interface. It takes ownership of the provided JSI array using
49
- Swift's consuming parameter ownership, ensuring proper move semantics.
50
-
51
- - Parameters:
52
- - runtime: The JavaScript runtime that owns the array
53
- - pointee: The underlying JSI `Array` object to wrap (consumed)
54
-
55
- - Note: This initializer is internal and used by the library's implementation to
56
- bridge between the C++ JSI layer and Swift. It should not be called directly
57
- by library consumers.
58
- - Note: The `pointee` parameter uses consuming ownership, meaning the JSI array
59
- object is moved into this structure and the caller's copy is invalidated.
60
- */
40
+ /// Creates a Swift wrapper around an existing JSI array object.
41
+ ///
42
+ /// This internal initializer is used to wrap a C++ JSI `Array` object with a Swift
43
+ /// `JavaScriptArray` interface. It takes ownership of the provided JSI array using
44
+ /// Swift's consuming parameter ownership, ensuring proper move semantics.
45
+ ///
46
+ /// - Parameters:
47
+ /// - runtime: The JavaScript runtime that owns the array
48
+ /// - pointee: The underlying JSI `Array` object to wrap (consumed)
49
+ ///
50
+ /// - Note: This initializer is internal and used by the library's implementation to
51
+ /// bridge between the C++ JSI layer and Swift. It should not be called directly
52
+ /// by library consumers.
53
+ /// - Note: The `pointee` parameter uses consuming ownership, meaning the JSI array
54
+ /// object is moved into this structure and the caller's copy is invalidated.
61
55
  internal init(_ runtime: JavaScriptRuntime, _ pointee: consuming facebook.jsi.Array) {
62
56
  self.runtime = runtime
63
57
  self.pointee = pointee
64
58
  }
65
59
 
66
- /**
67
- Creates a new JavaScript array initialized with the provided array of values.
68
-
69
- This initializer allows you to create a JavaScript array from a Swift array of
70
- `JavaScriptValue` elements. This is particularly useful when you already have
71
- a collection of values and want to avoid the syntactic overhead of spreading them
72
- as variadic arguments.
73
-
74
- - Parameters:
75
- - runtime: The JavaScript runtime in which to create the array
76
- - items: A Swift array of `JavaScriptValue` elements to populate the array with
77
-
78
- ## Examples
79
-
80
- ```swift
81
- // Create from an existing array
82
- let values = [JavaScriptValue.number(1), .number(2), .number(3)]
83
- let array = JavaScriptArray(runtime, items: values)
84
-
85
- // Create from a mapped collection
86
- let numbers = [1, 2, 3, 4, 5]
87
- let jsValues = numbers.map { JavaScriptValue.number(Double($0)) }
88
- let array = JavaScriptArray(runtime, items: jsValues)
89
- ```
90
-
91
- - Note: Due to limitations in Swift/C++ interop with `std::initializer_list`, this
92
- implementation creates an empty array first and then populates it element by element,
93
- rather than using JSI's `createWithElements` method directly.
94
- - SeeAlso: `init(_:items:)` for the variadic argument version
95
- */
60
+ /// Creates a new JavaScript array initialized with the provided array of values.
61
+ ///
62
+ /// This initializer allows you to create a JavaScript array from a Swift array of
63
+ /// `JavaScriptValue` elements. This is particularly useful when you already have
64
+ /// a collection of values and want to avoid the syntactic overhead of spreading them
65
+ /// as variadic arguments.
66
+ ///
67
+ /// - Parameters:
68
+ /// - runtime: The JavaScript runtime in which to create the array
69
+ /// - items: A Swift array of `JavaScriptValue` elements to populate the array with
70
+ ///
71
+ /// ## Examples
72
+ ///
73
+ /// ```swift
74
+ /// // Create from an existing array
75
+ /// let values = [JavaScriptValue.number(1), .number(2), .number(3)]
76
+ /// let array = JavaScriptArray(runtime, items: values)
77
+ ///
78
+ /// // Create from a mapped collection
79
+ /// let numbers = [1, 2, 3, 4, 5]
80
+ /// let jsValues = numbers.map { JavaScriptValue.number(Double($0)) }
81
+ /// let array = JavaScriptArray(runtime, items: jsValues)
82
+ /// ```
83
+ ///
84
+ /// - Note: Due to limitations in Swift/C++ interop with `std::initializer_list`, this
85
+ /// implementation creates an empty array first and then populates it element by element,
86
+ /// rather than using JSI's `createWithElements` method directly.
87
+ /// - SeeAlso: `init(_:items:)` for the variadic argument version
96
88
  public init(_ runtime: JavaScriptRuntime, items: [JavaScriptValue]) {
97
89
  self.init(runtime, length: items.count)
98
90
 
@@ -101,76 +93,72 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
101
93
  }
102
94
  }
103
95
 
104
- /**
105
- Creates a new JavaScript array initialized with the provided values.
106
-
107
- This convenience initializer allows you to create a JavaScript array from a variable
108
- number of `JavaScriptValue` arguments. The array is created with the appropriate length
109
- and populated with the provided values in order.
110
-
111
- - Parameters:
112
- - runtime: The JavaScript runtime in which to create the array
113
- - items: A variadic list of `JavaScriptValue` elements to populate the array with
114
-
115
- ## Examples
116
-
117
- ```swift
118
- // Create an empty array
119
- let empty = JavaScriptArray(runtime, items: )
120
-
121
- // Create an array with values
122
- let numbers = JavaScriptArray(runtime, items: .number(1), .number(2), .number(3))
123
-
124
- // Mix different value types
125
- let mixed = JavaScriptArray(runtime,
126
- items: .string("hello"), .number(42), .bool(true))
127
- ```
128
-
129
- - Note: This variadic version internally creates a Swift array and delegates to the
130
- array-based initializer. If you already have an array of values, consider using
131
- `init(_:items:)` directly for cleaner syntax.
132
- - SeeAlso: `init(_:items:)` for the array version
133
- */
96
+ /// Creates a new JavaScript array initialized with the provided values.
97
+ ///
98
+ /// This convenience initializer allows you to create a JavaScript array from a variable
99
+ /// number of `JavaScriptValue` arguments. The array is created with the appropriate length
100
+ /// and populated with the provided values in order.
101
+ ///
102
+ /// - Parameters:
103
+ /// - runtime: The JavaScript runtime in which to create the array
104
+ /// - items: A variadic list of `JavaScriptValue` elements to populate the array with
105
+ ///
106
+ /// ## Examples
107
+ ///
108
+ /// ```swift
109
+ /// // Create an empty array
110
+ /// let empty = JavaScriptArray(runtime, items: )
111
+ ///
112
+ /// // Create an array with values
113
+ /// let numbers = JavaScriptArray(runtime, items: .number(1), .number(2), .number(3))
114
+ ///
115
+ /// // Mix different value types
116
+ /// let mixed = JavaScriptArray(runtime,
117
+ /// items: .string("hello"), .number(42), .bool(true))
118
+ /// ```
119
+ ///
120
+ /// - Note: This variadic version internally creates a Swift array and delegates to the
121
+ /// array-based initializer. If you already have an array of values, consider using
122
+ /// `init(_:items:)` directly for cleaner syntax.
123
+ /// - SeeAlso: `init(_:items:)` for the array version
134
124
  public init(_ runtime: JavaScriptRuntime, items: JavaScriptValue...) {
135
125
  self.init(runtime, items: items)
136
126
  }
137
127
 
138
- /**
139
- Creates a new JavaScript array from variadic arguments of any types conforming to `JavaScriptRepresentable`.
140
-
141
- This generic initializer uses Swift's parameter pack feature to accept a variable number of
142
- arguments of potentially different types, as long as each type conforms to `JavaScriptRepresentable`.
143
- This provides a type-safe and ergonomic way to create JavaScript arrays from Swift values without
144
- needing to manually convert them to `JavaScriptValue` first.
145
-
146
- - Parameters:
147
- - runtime: The JavaScript runtime in which to create the array
148
- - items: A variadic parameter pack of values conforming to `JavaScriptRepresentable`
149
-
150
- ## Examples
151
-
152
- ```swift
153
- // Mix different Swift types directly
154
- let array = JavaScriptArray(runtime, items: 42, "hello", true, 3.14)
155
-
156
- // All same type works too
157
- let numbers = JavaScriptArray(runtime, items: 1, 2, 3, 4, 5)
158
-
159
- // Use with custom types that conform to JavaScriptRepresentable
160
- struct Person: JavaScriptRepresentable {
161
- let name: String
162
- let age: Int
163
- }
164
- let people = [Person(name: "Alice", age: 30), Person(name: "Bob", age: 25)]
165
- let array = JavaScriptArray(runtime, items: people[0], people[1])
166
- ```
167
-
168
- - Note: This initializer automatically converts each item to a `JavaScriptValue` using
169
- its `toJavaScriptValue(in:)` method, providing compile-time type safety.
170
- - Note: Unlike the `JavaScriptValue` variadic initializer, this version accepts heterogeneous
171
- types directly without requiring explicit `JavaScriptValue` wrapping.
172
- - SeeAlso: `init(_:items:)` for the `JavaScriptValue` array version
173
- */
128
+ /// Creates a new JavaScript array from variadic arguments of any types conforming to `JavaScriptRepresentable`.
129
+ ///
130
+ /// This generic initializer uses Swift's parameter pack feature to accept a variable number of
131
+ /// arguments of potentially different types, as long as each type conforms to `JavaScriptRepresentable`.
132
+ /// This provides a type-safe and ergonomic way to create JavaScript arrays from Swift values without
133
+ /// needing to manually convert them to `JavaScriptValue` first.
134
+ ///
135
+ /// - Parameters:
136
+ /// - runtime: The JavaScript runtime in which to create the array
137
+ /// - items: A variadic parameter pack of values conforming to `JavaScriptRepresentable`
138
+ ///
139
+ /// ## Examples
140
+ ///
141
+ /// ```swift
142
+ /// // Mix different Swift types directly
143
+ /// let array = JavaScriptArray(runtime, items: 42, "hello", true, 3.14)
144
+ ///
145
+ /// // All same type works too
146
+ /// let numbers = JavaScriptArray(runtime, items: 1, 2, 3, 4, 5)
147
+ ///
148
+ /// // Use with custom types that conform to JavaScriptRepresentable
149
+ /// struct Person: JavaScriptRepresentable {
150
+ /// let name: String
151
+ /// let age: Int
152
+ /// }
153
+ /// let people = [Person(name: "Alice", age: 30), Person(name: "Bob", age: 25)]
154
+ /// let array = JavaScriptArray(runtime, items: people[0], people[1])
155
+ /// ```
156
+ ///
157
+ /// - Note: This initializer automatically converts each item to a `JavaScriptValue` using
158
+ /// its `toJavaScriptValue(in:)` method, providing compile-time type safety.
159
+ /// - Note: Unlike the `JavaScriptValue` variadic initializer, this version accepts heterogeneous
160
+ /// types directly without requiring explicit `JavaScriptValue` wrapping.
161
+ /// - SeeAlso: `init(_:items:)` for the `JavaScriptValue` array version
174
162
  public init<each T: JavaScriptRepresentable>(_ runtime: JavaScriptRuntime, items: repeat each T) {
175
163
  var length: Int = 0
176
164
  for _ in repeat each items {
@@ -186,42 +174,40 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
186
174
  }
187
175
  }
188
176
 
189
- /**
190
- The length of the JavaScript array, equivalent to the `length` property in JavaScript.
191
-
192
- This property provides direct access to the array's length, which can be both read and
193
- modified. Changing the length affects the array size, matching JavaScript's behavior.
194
-
195
- ## Getting the Length
196
-
197
- Returns the current number of elements in the array:
198
-
199
- ```swift
200
- let array = try runtime.eval("[1, 2, 3]").getArray()
201
- print(array.length) // 3
202
- ```
203
-
204
- ## Setting the Length
205
-
206
- Modifying the length changes the array size:
207
- - **Increasing** the length adds `undefined` elements to fill the gap
208
- - **Decreasing** the length truncates the array, removing elements
209
-
210
- ```swift
211
- let array = try runtime.eval("[1, 2, 3, 4, 5]").getArray()
212
-
213
- // Truncate the array
214
- array.length = 3
215
- // Array is now [1, 2, 3]
216
-
217
- // Expand the array
218
- array.length = 5
219
- // Array is now [1, 2, 3, undefined, undefined]
220
- ```
221
-
222
- - Note: This property directly modifies the JavaScript array's `length` property,
223
- providing the same semantics as `array.length = newValue` in JavaScript.
224
- */
177
+ /// The length of the JavaScript array, equivalent to the `length` property in JavaScript.
178
+ ///
179
+ /// This property provides direct access to the array's length, which can be both read and
180
+ /// modified. Changing the length affects the array size, matching JavaScript's behavior.
181
+ ///
182
+ /// ## Getting the Length
183
+ ///
184
+ /// Returns the current number of elements in the array:
185
+ ///
186
+ /// ```swift
187
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
188
+ /// print(array.length) // 3
189
+ /// ```
190
+ ///
191
+ /// ## Setting the Length
192
+ ///
193
+ /// Modifying the length changes the array size:
194
+ /// - **Increasing** the length adds `undefined` elements to fill the gap
195
+ /// - **Decreasing** the length truncates the array, removing elements
196
+ ///
197
+ /// ```swift
198
+ /// let array = try runtime.eval("[1, 2, 3, 4, 5]").getArray()
199
+ ///
200
+ /// // Truncate the array
201
+ /// array.length = 3
202
+ /// // Array is now [1, 2, 3]
203
+ ///
204
+ /// // Expand the array
205
+ /// array.length = 5
206
+ /// // Array is now [1, 2, 3, undefined, undefined]
207
+ /// ```
208
+ ///
209
+ /// - Note: This property directly modifies the JavaScript array's `length` property,
210
+ /// providing the same semantics as `array.length = newValue` in JavaScript.
225
211
  public var length: Int {
226
212
  get {
227
213
  guard let runtime else {
@@ -237,14 +223,12 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
237
223
  }
238
224
  }
239
225
 
240
- /**
241
- Retrieves the value at the specified index in the array.
242
-
243
- - Parameter index: The zero-based index of the element to retrieve
244
- - Returns: The `JavaScriptValue` at the specified index
245
- - Throws: `JavaScriptArray.Errors.indexOutOfRange` if the index is negative or
246
- greater than or equal to the array's length
247
- */
226
+ /// Retrieves the value at the specified index in the array.
227
+ ///
228
+ /// - Parameter index: The zero-based index of the element to retrieve
229
+ /// - Returns: The `JavaScriptValue` at the specified index
230
+ /// - Throws: `JavaScriptArray.Errors.indexOutOfRange` if the index is negative or
231
+ /// greater than or equal to the array's length
248
232
  public func getValue(at index: Int) throws -> JavaScriptValue {
249
233
  guard let runtime else {
250
234
  FatalError.runtimeLost()
@@ -256,24 +240,20 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
256
240
  return JavaScriptValue(runtime, pointee.getValueAtIndex(runtime.pointee, index))
257
241
  }
258
242
 
259
- /**
260
- Returns the value at the given index without bounds-checking. Used by the iteration
261
- helpers (`map`, `forEach`, `reduce`, `filter`, `enumerated`) which iterate
262
- `0..<length` and never produce an out-of-range index. Skipping the redundant bounds
263
- check avoids a weak-runtime load on every element on the hot path.
264
- */
243
+ /// Returns the value at the given index without bounds-checking. Used by the iteration
244
+ /// helpers (`map`, `forEach`, `reduce`, `filter`, `enumerated`) which iterate
245
+ /// `0..<length` and never produce an out-of-range index. Skipping the redundant bounds
246
+ /// check avoids a weak-runtime load on every element on the hot path.
265
247
  internal func getValueUnchecked(at index: Int, in runtime: JavaScriptRuntime) -> JavaScriptValue {
266
248
  return JavaScriptValue(runtime, pointee.getValueAtIndex(runtime.pointee, index))
267
249
  }
268
250
 
269
- /**
270
- Sets the element at the specified index.
271
-
272
- - Parameters:
273
- - value: The value to set, conforming to `JavaScriptRepresentable`
274
- - index: The zero-based index where the value should be set
275
- - Throws: `JavaScriptArray.Errors.indexOutOfRange` if the index is out of bounds
276
- */
251
+ /// Sets the element at the specified index.
252
+ ///
253
+ /// - Parameters:
254
+ /// - value: The value to set, conforming to `JavaScriptRepresentable`
255
+ /// - index: The zero-based index where the value should be set
256
+ /// - Throws: `JavaScriptArray.Errors.indexOutOfRange` if the index is out of bounds
277
257
  public func set<T: JavaScriptRepresentable & ~Copyable>(value: borrowing T, at index: Int) throws {
278
258
  guard let runtime else {
279
259
  FatalError.runtimeLost()
@@ -286,42 +266,40 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
286
266
  expo.setValueAtIndex(runtime.pointee, pointee, index, jsiValue)
287
267
  }
288
268
 
289
- /**
290
- Accesses array elements by numeric index with safe, non-throwing behavior.
291
-
292
- This subscript provides a convenient way to read and write array elements without
293
- explicit error handling. It mimics JavaScript's array behavior by automatically
294
- handling out-of-bounds access and dynamic resizing.
295
-
296
- - Parameter index: The zero-based index of the element to access or modify
297
- - Returns: The `JavaScriptValue` at the specified index, or `undefined` if the index
298
- is out of range
299
-
300
- ## Getting Values
301
-
302
- Returns `undefined` if the index is out of bounds (no error thrown):
303
-
304
- ```swift
305
- let array = try runtime.eval("[1, 2, 3]").getArray()
306
- let value = array[1] // JavaScriptValue(2)
307
- let outOfRange = array[10] // JavaScriptValue.undefined
308
- ```
309
-
310
- ## Setting Values
311
-
312
- Automatically expands the array if the index is beyond the current length:
313
-
314
- ```swift
315
- let array = try runtime.eval("[1, 2, 3]").getArray()
316
- array[1] = .number(99) // Updates existing element
317
- array[10] = .string("hello") // Expands array to size 11
318
- ```
319
-
320
- - Note: This subscript never throws. For strict bounds checking with errors,
321
- use `getValue(at:)` and `set(value:at:)` instead.
322
- - Note: When setting an element beyond the current length, intermediate elements
323
- are filled with `undefined`, matching JavaScript's behavior.
324
- */
269
+ /// Accesses array elements by numeric index with safe, non-throwing behavior.
270
+ ///
271
+ /// This subscript provides a convenient way to read and write array elements without
272
+ /// explicit error handling. It mimics JavaScript's array behavior by automatically
273
+ /// handling out-of-bounds access and dynamic resizing.
274
+ ///
275
+ /// - Parameter index: The zero-based index of the element to access or modify
276
+ /// - Returns: The `JavaScriptValue` at the specified index, or `undefined` if the index
277
+ /// is out of range
278
+ ///
279
+ /// ## Getting Values
280
+ ///
281
+ /// Returns `undefined` if the index is out of bounds (no error thrown):
282
+ ///
283
+ /// ```swift
284
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
285
+ /// let value = array[1] // JavaScriptValue(2)
286
+ /// let outOfRange = array[10] // JavaScriptValue.undefined
287
+ /// ```
288
+ ///
289
+ /// ## Setting Values
290
+ ///
291
+ /// Automatically expands the array if the index is beyond the current length:
292
+ ///
293
+ /// ```swift
294
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
295
+ /// array[1] = .number(99) // Updates existing element
296
+ /// array[10] = .string("hello") // Expands array to size 11
297
+ /// ```
298
+ ///
299
+ /// - Note: This subscript never throws. For strict bounds checking with errors,
300
+ /// use `getValue(at:)` and `set(value:at:)` instead.
301
+ /// - Note: When setting an element beyond the current length, intermediate elements
302
+ /// are filled with `undefined`, matching JavaScript's behavior.
325
303
  public subscript(index: Int) -> JavaScriptValue {
326
304
  get {
327
305
  return (try? self.getValue(at: index)) ?? .undefined
@@ -337,46 +315,44 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
337
315
  }
338
316
  }
339
317
 
340
- /**
341
- Type-safe subscript for accessing and modifying array elements with automatic conversion.
342
-
343
- This subscript provides a convenient way to work with JavaScript array elements using
344
- Swift types that conform to `JavaScriptRepresentable`. It automatically converts between
345
- JavaScript values and Swift types.
346
-
347
- - Parameter index: The zero-based index of the element to access or modify
348
- - Returns: An optional value of type `T` if the element exists and can be converted,
349
- or `nil` if the index is out of range or conversion fails
350
-
351
- ## Getting Values
352
-
353
- When reading, returns `nil` if:
354
- - The index is out of range
355
- - The JavaScript value cannot be converted to type `T`
356
-
357
- ```swift
358
- let array = try runtime.eval("[1, 2, 3]").getArray()
359
- let value: Int? = array[0] // Returns 1
360
- let outOfRange: Int? = array[10] // Returns nil
361
- ```
362
-
363
- ## Setting Values
364
-
365
- When writing:
366
- - Automatically resizes the array if the index is beyond the current length (JavaScript behavior)
367
- - Setting `nil` sets the element to `undefined`
368
- - Accepts any value conforming to `JavaScriptRepresentable`
369
-
370
- ```swift
371
- array[0] = 42 // Sets element to number
372
- array[5] = "hello" // Resizes array and sets element
373
- array[1] = nil // Sets element to undefined
374
- ```
375
-
376
- - Note: Unlike `getValue(at:)` and `set(value:at:)`, this subscript mimics JavaScript's
377
- dynamic array behavior by automatically expanding the array when setting elements beyond
378
- the current length.
379
- */
318
+ /// Type-safe subscript for accessing and modifying array elements with automatic conversion.
319
+ ///
320
+ /// This subscript provides a convenient way to work with JavaScript array elements using
321
+ /// Swift types that conform to `JavaScriptRepresentable`. It automatically converts between
322
+ /// JavaScript values and Swift types.
323
+ ///
324
+ /// - Parameter index: The zero-based index of the element to access or modify
325
+ /// - Returns: An optional value of type `T` if the element exists and can be converted,
326
+ /// or `nil` if the index is out of range or conversion fails
327
+ ///
328
+ /// ## Getting Values
329
+ ///
330
+ /// When reading, returns `nil` if:
331
+ /// - The index is out of range
332
+ /// - The JavaScript value cannot be converted to type `T`
333
+ ///
334
+ /// ```swift
335
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
336
+ /// let value: Int? = array[0] // Returns 1
337
+ /// let outOfRange: Int? = array[10] // Returns nil
338
+ /// ```
339
+ ///
340
+ /// ## Setting Values
341
+ ///
342
+ /// When writing:
343
+ /// - Automatically resizes the array if the index is beyond the current length (JavaScript behavior)
344
+ /// - Setting `nil` sets the element to `undefined`
345
+ /// - Accepts any value conforming to `JavaScriptRepresentable`
346
+ ///
347
+ /// ```swift
348
+ /// array[0] = 42 // Sets element to number
349
+ /// array[5] = "hello" // Resizes array and sets element
350
+ /// array[1] = nil // Sets element to undefined
351
+ /// ```
352
+ ///
353
+ /// - Note: Unlike `getValue(at:)` and `set(value:at:)`, this subscript mimics JavaScript's
354
+ /// dynamic array behavior by automatically expanding the array when setting elements beyond
355
+ /// the current length.
380
356
  public subscript<T: JavaScriptRepresentable & ~Copyable>(index: Int) -> T? {
381
357
  get {
382
358
  return try? T.fromJavaScriptValue(self.getValue(at: index))
@@ -388,42 +364,41 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
388
364
  if index >= length {
389
365
  self.length = index + 1
390
366
  }
391
- let jsiValue = if let newValue {
392
- newValue.toJavaScriptValue(in: runtime).toJSIValue(in: runtime.pointee)
393
- } else {
394
- facebook.jsi.Value.undefined()
395
- }
367
+ let jsiValue =
368
+ if let newValue {
369
+ newValue.toJavaScriptValue(in: runtime).toJSIValue(in: runtime.pointee)
370
+ } else {
371
+ facebook.jsi.Value.undefined()
372
+ }
396
373
  expo.setValueAtIndex(runtime.pointee, pointee, index, jsiValue)
397
374
  }
398
375
  }
399
376
 
400
- /**
401
- Accesses properties of the array using string keys.
402
-
403
- Since JavaScript arrays are also objects, they can have named properties in addition
404
- to numeric indices. This subscript allows you to access and modify these properties.
405
-
406
- - Parameter key: The property name to access or modify
407
- - Returns: The value of the property as a `JavaScriptValue`
408
-
409
- ## Examples
410
-
411
- ```swift
412
- let array = try runtime.eval("[1, 2, 3]").getArray()
413
-
414
- // Access built-in properties
415
- let length = array["length"] // JavaScriptValue(3)
416
-
417
- // Set custom properties
418
- array["customProperty"] = .string("custom value")
419
-
420
- // Access custom properties
421
- let custom = array["customProperty"] // JavaScriptValue("custom value")
422
- ```
423
-
424
- - Note: This subscript accesses object properties, not array elements. To access
425
- array elements by index, use the numeric subscript `array[0]` instead of `array["0"]`.
426
- */
377
+ /// Accesses properties of the array using string keys.
378
+ ///
379
+ /// Since JavaScript arrays are also objects, they can have named properties in addition
380
+ /// to numeric indices. This subscript allows you to access and modify these properties.
381
+ ///
382
+ /// - Parameter key: The property name to access or modify
383
+ /// - Returns: The value of the property as a `JavaScriptValue`
384
+ ///
385
+ /// ## Examples
386
+ ///
387
+ /// ```swift
388
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
389
+ ///
390
+ /// // Access built-in properties
391
+ /// let length = array["length"] // JavaScriptValue(3)
392
+ ///
393
+ /// // Set custom properties
394
+ /// array["customProperty"] = .string("custom value")
395
+ ///
396
+ /// // Access custom properties
397
+ /// let custom = array["customProperty"] // JavaScriptValue("custom value")
398
+ /// ```
399
+ ///
400
+ /// - Note: This subscript accesses object properties, not array elements. To access
401
+ /// array elements by index, use the numeric subscript `array[0]` instead of `array["0"]`.
427
402
  public subscript(key: String) -> JavaScriptValue {
428
403
  get {
429
404
  guard let runtime else {
@@ -441,20 +416,18 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
441
416
  }
442
417
  }
443
418
 
444
- /**
445
- Transforms each element in the JavaScript array using the provided closure. This method creates a new Swift array
446
- by calling the transform closure on each element of the JavaScript array.
447
- The closure receives a `JavaScriptValue` for each element and returns a transformed value.
448
-
449
- - Parameter transform: A closure that accepts a `JavaScriptValue` representing an element
450
- from the array and returns a transformed value. The closure can throw an error, which
451
- will be propagated to the caller.
452
- - Returns: A Swift array containing the transformed elements in the same order as
453
- the original JavaScript array.
454
- - Throws: Any error thrown by the `transform` closure.
455
- - Note: This method uses Swift's standard `map` semantics and follows the `rethrows`
456
- pattern, meaning it only throws if the transform closure throws.
457
- */
419
+ /// Transforms each element in the JavaScript array using the provided closure. This method creates a new Swift array
420
+ /// by calling the transform closure on each element of the JavaScript array.
421
+ /// The closure receives a `JavaScriptValue` for each element and returns a transformed value.
422
+ ///
423
+ /// - Parameter transform: A closure that accepts a `JavaScriptValue` representing an element
424
+ /// from the array and returns a transformed value. The closure can throw an error, which
425
+ /// will be propagated to the caller.
426
+ /// - Returns: A Swift array containing the transformed elements in the same order as
427
+ /// the original JavaScript array.
428
+ /// - Throws: Any error thrown by the `transform` closure.
429
+ /// - Note: This method uses Swift's standard `map` semantics and follows the `rethrows`
430
+ /// pattern, meaning it only throws if the transform closure throws.
458
431
  public func map<T>(_ transform: (_ value: JavaScriptValue) throws -> T) rethrows -> [T] {
459
432
  guard let runtime else {
460
433
  FatalError.runtimeLost()
@@ -469,14 +442,12 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
469
442
  return result
470
443
  }
471
444
 
472
- /**
473
- Converts the JavaScript array to a `JavaScriptValue`.
474
-
475
- - Returns: A `JavaScriptValue` representing this array
476
- - Note: The returned value maintains a reference to the same underlying JavaScript
477
- array, so modifications to the array in JavaScript will be reflected in the value.
478
- - SeeAlso: `JavaScriptValue.getArray()` for the inverse operation
479
- */
445
+ /// Converts the JavaScript array to a `JavaScriptValue`.
446
+ ///
447
+ /// - Returns: A `JavaScriptValue` representing this array
448
+ /// - Note: The returned value maintains a reference to the same underlying JavaScript
449
+ /// array, so modifications to the array in JavaScript will be reflected in the value.
450
+ /// - SeeAlso: `JavaScriptValue.getArray()` for the inverse operation
480
451
  public func asValue() -> JavaScriptValue {
481
452
  guard let runtime else {
482
453
  FatalError.runtimeLost()
@@ -484,43 +455,37 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
484
455
  return JavaScriptValue(runtime, expo.valueFromArray(runtime.pointee, pointee))
485
456
  }
486
457
 
487
- /**
488
- Converts the array to a `JavaScriptObject`.
489
-
490
- Since JavaScript arrays are also objects, this method allows you to access the array
491
- as a generic object to use object-specific APIs like property enumeration or prototype
492
- manipulation.
493
-
494
- - Returns: A `JavaScriptObject` representing the same underlying array
495
-
496
- ```swift
497
- let array = try runtime.eval("[1, 2, 3]").getArray()
498
- let object = array.toObject()
499
-
500
- // Access array properties as an object
501
- let length = object.getProperty("length") // JavaScriptValue(3)
502
- ```
503
-
504
- - Note: The returned object maintains a reference to the same underlying JavaScript
505
- array, so modifications through either the array or object interface will affect
506
- the same data.
507
- - SeeAlso: `asValue()` for converting to a `JavaScriptValue`
508
- */
458
+ /// Converts the array to a `JavaScriptObject`.
459
+ ///
460
+ /// Since JavaScript arrays are also objects, this method allows you to access the array
461
+ /// as a generic object to use object-specific APIs like property enumeration or prototype
462
+ /// manipulation.
463
+ ///
464
+ /// - Returns: A `JavaScriptObject` representing the same underlying array
465
+ ///
466
+ /// ```swift
467
+ /// let array = try runtime.eval("[1, 2, 3]").getArray()
468
+ /// let object = array.toObject()
469
+ ///
470
+ /// // Access array properties as an object
471
+ /// let length = object.getProperty("length") // JavaScriptValue(3)
472
+ /// ```
473
+ ///
474
+ /// - Note: The returned object maintains a reference to the same underlying JavaScript
475
+ /// array, so modifications through either the array or object interface will affect
476
+ /// the same data.
477
+ /// - SeeAlso: `asValue()` for converting to a `JavaScriptValue`
509
478
  public func toObject() -> JavaScriptObject {
510
479
  return asValue().getObject()
511
480
  }
512
481
 
513
- /**
514
- Errors that can occur when working with JavaScript arrays.
515
- */
482
+ /// Errors that can occur when working with JavaScript arrays.
516
483
  public enum Errors: Error, Equatable, CustomStringConvertible {
517
- /**
518
- The specified index is out of the array's valid range.
519
-
520
- - Parameters:
521
- - index: The invalid index that was accessed
522
- - length: The actual length of the array
523
- */
484
+ /// The specified index is out of the array's valid range.
485
+ ///
486
+ /// - Parameters:
487
+ /// - index: The invalid index that was accessed
488
+ /// - length: The actual length of the array
524
489
  case indexOutOfRange(index: Int, length: Int)
525
490
 
526
491
  public var description: String {
@@ -540,11 +505,9 @@ public struct JavaScriptArray: JavaScriptType, ~Copyable {
540
505
  // equivalent functionality without requiring protocol conformance.
541
506
 
542
507
  extension JavaScriptArray {
543
- /**
544
- Returns an array of `(offset, element)` pairs, similar to `Sequence.enumerated()`.
545
-
546
- - Note: Eagerly evaluates all elements. For large arrays, prefer `forEach(_:)`.
547
- */
508
+ /// Returns an array of `(offset, element)` pairs, similar to `Sequence.enumerated()`.
509
+ ///
510
+ /// - Note: Eagerly evaluates all elements. For large arrays, prefer `forEach(_:)`.
548
511
  public func enumerated() -> [(offset: Int, element: JavaScriptValue)] {
549
512
  guard let runtime else {
550
513
  FatalError.runtimeLost()
@@ -558,9 +521,7 @@ extension JavaScriptArray {
558
521
  return result
559
522
  }
560
523
 
561
- /**
562
- Calls the given closure on each element in the array.
563
- */
524
+ /// Calls the given closure on each element in the array.
564
525
  public func forEach(_ body: (JavaScriptValue) throws -> Void) rethrows {
565
526
  guard let runtime else {
566
527
  FatalError.runtimeLost()
@@ -571,9 +532,7 @@ extension JavaScriptArray {
571
532
  }
572
533
  }
573
534
 
574
- /**
575
- Returns an array of elements satisfying the given predicate.
576
- */
535
+ /// Returns an array of elements satisfying the given predicate.
577
536
  public func filter(_ isIncluded: (JavaScriptValue) throws -> Bool) rethrows -> [JavaScriptValue] {
578
537
  guard let runtime else {
579
538
  FatalError.runtimeLost()
@@ -589,10 +548,10 @@ extension JavaScriptArray {
589
548
  return result
590
549
  }
591
550
 
592
- /**
593
- Returns the result of combining the elements using the given closure.
594
- */
595
- public func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, JavaScriptValue) throws -> Result) rethrows -> Result {
551
+ /// Returns the result of combining the elements using the given closure.
552
+ public func reduce<Result>(_ initialResult: Result, _ nextPartialResult: (Result, JavaScriptValue) throws -> Result)
553
+ rethrows -> Result
554
+ {
596
555
  guard let runtime else {
597
556
  FatalError.runtimeLost()
598
557
  }