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,42 +1,32 @@
1
1
  // Copyright 2025-present 650 Industries. All rights reserved.
2
2
 
3
- internal import jsi
4
3
  internal import ExpoModulesJSI_Cxx
4
+ internal import jsi
5
5
 
6
- /**
7
- A Swift representation of a JavaScript object. Provides access to JavaScript object properties and methods,
8
- supporting property access, modification, enumeration, prototype manipulation, and function calling.
9
- */
6
+ /// A Swift representation of a JavaScript object. Provides access to JavaScript object properties and methods,
7
+ /// supporting property access, modification, enumeration, prototype manipulation, and function calling.
10
8
  public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
11
9
  internal weak let runtime: JavaScriptRuntime?
12
10
  internal var pointee: facebook.jsi.Object
13
11
 
14
- /**
15
- Creates a new object in the given runtime.
16
- */
12
+ /// Creates a new object in the given runtime.
17
13
  public init(_ runtime: JavaScriptRuntime) {
18
14
  self.init(runtime, facebook.jsi.Object(runtime.pointee))
19
15
  }
20
16
 
21
- /**
22
- Creates a new object from the dictionary whose values are representable in JS.
23
- */
17
+ /// Creates a new object from the dictionary whose values are representable in JS.
24
18
  public init<DictValue: JavaScriptRepresentable>(_ runtime: JavaScriptRuntime, _ dictionary: [String: DictValue]) {
25
19
  self.runtime = runtime
26
20
  self.pointee = dictionary.toJavaScriptValue(in: runtime).getObject().pointee
27
21
  }
28
22
 
29
- /**
30
- Creates a new object from existing JSI object.
31
- */
23
+ /// Creates a new object from existing JSI object.
32
24
  internal init(_ runtime: JavaScriptRuntime, _ object: consuming facebook.jsi.Object) {
33
25
  self.runtime = runtime
34
26
  self.pointee = object
35
27
  }
36
28
 
37
- /**
38
- Result of `object instanceof constructor`, which tests if the prototype property of a constructor appears anywhere in the prototype chain of an object.
39
- */
29
+ /// Result of `object instanceof constructor`, which tests if the prototype property of a constructor appears anywhere in the prototype chain of an object.
40
30
  public func instanceOf(_ constructor: borrowing JavaScriptFunction) -> Bool {
41
31
  guard let runtime else {
42
32
  FatalError.runtimeLost()
@@ -44,16 +34,12 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
44
34
  return pointee.instanceOf(runtime.pointee, constructor.pointee)
45
35
  }
46
36
 
47
- /**
48
- Result of `object instanceof constructor`, which tests if the prototype property of a constructor appears anywhere in the prototype chain of an object.
49
- */
37
+ /// Result of `object instanceof constructor`, which tests if the prototype property of a constructor appears anywhere in the prototype chain of an object.
50
38
  public func instanceOf(_ constructor: JavaScriptValue) -> Bool {
51
39
  return instanceOf(constructor.getFunction())
52
40
  }
53
41
 
54
- /**
55
- Equivalent to `Array.isArray()` in JS. If it returns `true`, then `getArray()` will succeed.
56
- */
42
+ /// Equivalent to `Array.isArray()` in JS. If it returns `true`, then `getArray()` will succeed.
57
43
  public func isArray() -> Bool {
58
44
  guard let runtime else {
59
45
  FatalError.runtimeLost()
@@ -61,9 +47,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
61
47
  return pointee.isArray(runtime.pointee)
62
48
  }
63
49
 
64
- /**
65
- Returns `true` if the object is callable. If so, then `getFunction()` will succeed.
66
- */
50
+ /// Returns `true` if the object is callable. If so, then `getFunction()` will succeed.
67
51
  public func isFunction() -> Bool {
68
52
  guard let runtime else {
69
53
  FatalError.runtimeLost()
@@ -71,10 +55,8 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
71
55
  return pointee.isFunction(runtime.pointee)
72
56
  }
73
57
 
74
- /**
75
- Returns `true` if the object is backed by a `jsi::HostObject`, including host objects
76
- created via `JavaScriptRuntime.createHostObject` and ones produced by other native code.
77
- */
58
+ /// Returns `true` if the object is backed by a `jsi::HostObject`, including host objects
59
+ /// created via `JavaScriptRuntime.createHostObject` and ones produced by other native code.
78
60
  public func isHostObject() -> Bool {
79
61
  guard let runtime else {
80
62
  FatalError.runtimeLost()
@@ -89,9 +71,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
89
71
  return pointee.isArrayBuffer(runtime.pointee)
90
72
  }
91
73
 
92
- /**
93
- Returns the object as an array buffer, or asserts if not an array buffer.
94
- */
74
+ /// Returns the object as an array buffer, or asserts if not an array buffer.
95
75
  public func getArrayBuffer() -> JavaScriptArrayBuffer {
96
76
  guard let runtime else {
97
77
  FatalError.runtimeLost()
@@ -100,9 +80,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
100
80
  return JavaScriptArrayBuffer(runtime, pointee.getArrayBuffer(runtime.pointee))
101
81
  }
102
82
 
103
- /**
104
- Returns the object as an array, or asserts if not an array.
105
- */
83
+ /// Returns the object as an array, or asserts if not an array.
106
84
  public func getArray() -> JavaScriptArray {
107
85
  guard let runtime else {
108
86
  FatalError.runtimeLost()
@@ -111,9 +89,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
111
89
  return JavaScriptArray(runtime, pointee.getArray(runtime.pointee))
112
90
  }
113
91
 
114
- /**
115
- Returns the object as a function, or asserts if not a function.
116
- */
92
+ /// Returns the object as a function, or asserts if not a function.
117
93
  public func getFunction() -> JavaScriptFunction {
118
94
  guard let runtime else {
119
95
  FatalError.runtimeLost()
@@ -124,9 +100,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
124
100
 
125
101
  // MARK: - Accessing object properties
126
102
 
127
- /**
128
- Checks whether the object has a property with the given name.
129
- */
103
+ /// Checks whether the object has a property with the given name.
130
104
  public func hasProperty(_ name: String) -> Bool {
131
105
  guard let runtime else {
132
106
  FatalError.runtimeLost()
@@ -134,10 +108,8 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
134
108
  return pointee.hasProperty(runtime.pointee, name)
135
109
  }
136
110
 
137
- /**
138
- Returns the property of the object with the given name,
139
- or `undefined` value if the name is not a property of the object.
140
- */
111
+ /// Returns the property of the object with the given name,
112
+ /// or `undefined` value if the name is not a property of the object.
141
113
  public func getProperty(_ name: String) -> JavaScriptValue {
142
114
  guard let runtime else {
143
115
  FatalError.runtimeLost()
@@ -145,19 +117,26 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
145
117
  return JavaScriptValue(runtime, pointee.getProperty(runtime.pointee, name))
146
118
  }
147
119
 
148
- /**
149
- Accesses nested properties in a single subscript operation by traversing the object chain.
150
- This subscript provides a convenient way to access deeply nested properties without
151
- multiple chained calls to `getProperty()`. Each key in the chain is accessed sequentially,
152
- treating intermediate values as objects.
120
+ /// Returns the property of the object with the given prop name id,
121
+ /// or `undefined` value if the name is not a property of the object.
122
+ public func getProperty(_ propName: JavaScriptPropNameID) -> JavaScriptValue {
123
+ guard let runtime else {
124
+ FatalError.runtimeLost()
125
+ }
126
+ return JavaScriptValue(runtime, pointee.getProperty(runtime.pointee, propName.pointee))
127
+ }
153
128
 
154
- - Parameters:
155
- - key: The first property name to access on this object
156
- - nestedKeys: Variadic list of subsequent property names to access on nested objects
157
- - Returns: The `JavaScriptValue` at the end of the property chain
158
- - Note: Each intermediate value in the chain (except the last) must be an object.
159
- If any intermediate value is not an object, the behavior is undefined and may crash.
160
- */
129
+ /// Accesses nested properties in a single subscript operation by traversing the object chain.
130
+ /// This subscript provides a convenient way to access deeply nested properties without
131
+ /// multiple chained calls to `getProperty()`. Each key in the chain is accessed sequentially,
132
+ /// treating intermediate values as objects.
133
+ ///
134
+ /// - Parameters:
135
+ /// - key: The first property name to access on this object
136
+ /// - nestedKeys: Variadic list of subsequent property names to access on nested objects
137
+ /// - Returns: The `JavaScriptValue` at the end of the property chain
138
+ /// - Note: Each intermediate value in the chain (except the last) must be an object.
139
+ /// If any intermediate value is not an object, the behavior is undefined and may crash.
161
140
  public subscript(_ key: String, _ nestedKeys: String...) -> JavaScriptValue {
162
141
  guard let runtime else {
163
142
  FatalError.runtimeLost()
@@ -171,13 +150,11 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
171
150
  return JavaScriptValue(runtime, value)
172
151
  }
173
152
 
174
- /**
175
- Returns an array of the object's own enumerable property names.
176
- This method is equivalent to JavaScript's `Object.keys()`, returning only properties
177
- that are enumerable and directly owned by the object (not inherited from the prototype chain).
178
-
179
- - Returns: An array of property names as strings
180
- */
153
+ /// Returns an array of the object's own enumerable property names.
154
+ /// This method is equivalent to JavaScript's `Object.keys()`, returning only properties
155
+ /// that are enumerable and directly owned by the object (not inherited from the prototype chain).
156
+ ///
157
+ /// - Returns: An array of property names as strings
181
158
  public func getPropertyNames() -> [String] {
182
159
  guard let jsiRuntime = runtime?.pointee else {
183
160
  FatalError.runtimeLost()
@@ -190,50 +167,47 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
190
167
  }
191
168
  }
192
169
 
193
- /**
194
- Same as `getProperty(name).getObject()`.
195
- */
196
- public func getPropertyAsObject(_ name: String) -> JavaScriptObject {
197
- guard let runtime else {
198
- FatalError.runtimeLost()
170
+ /// Same as `getProperty(name).getObject()`, but throws instead of aborting when the property is
171
+ /// not an object.
172
+ public func getPropertyAsObject(_ name: String) throws -> JavaScriptObject {
173
+ let property = getProperty(name)
174
+ guard property.isObject() else {
175
+ throw PropertyNotObjectError(name: name)
199
176
  }
200
- return JavaScriptObject(runtime, pointee.getPropertyAsObject(runtime.pointee, name))
177
+ return property.getObject()
201
178
  }
202
179
 
203
- /**
204
- Same as `getProperty(propName).getObject()`.
205
- */
206
- public func getPropertyAsObject(_ propName: JavaScriptPropNameID) -> JavaScriptObject {
207
- guard let runtime else {
208
- FatalError.runtimeLost()
180
+ /// Same as `getProperty(propName).getObject()`, but throws instead of aborting when the property is
181
+ /// not an object.
182
+ public func getPropertyAsObject(_ propName: JavaScriptPropNameID) throws -> JavaScriptObject {
183
+ let property = getProperty(propName)
184
+ guard property.isObject() else {
185
+ throw PropertyNotObjectError(name: propName.utf8())
209
186
  }
210
- return JavaScriptObject(runtime, pointee.getProperty(runtime.pointee, propName.pointee).getObject(runtime.pointee))
187
+ return property.getObject()
211
188
  }
212
189
 
213
- /**
214
- Same as `getProperty(name).getObject().getFunction()`.
215
- */
216
- public func getPropertyAsFunction(_ name: String) -> JavaScriptFunction {
217
- guard let runtime else {
218
- FatalError.runtimeLost()
190
+ /// Same as `getProperty(name).getObject().getFunction()`, but throws instead of aborting when the
191
+ /// property is missing or not callable.
192
+ public func getPropertyAsFunction(_ name: String) throws -> JavaScriptFunction {
193
+ let property = getProperty(name)
194
+ guard property.isFunction() else {
195
+ throw PropertyNotFunctionError(name: name)
219
196
  }
220
- return JavaScriptFunction(runtime, pointee.getPropertyAsFunction(runtime.pointee, name))
197
+ return property.getFunction()
221
198
  }
222
199
 
223
- /**
224
- Same as `getProperty(propName).getObject().getFunction()`.
225
- */
226
- public func getPropertyAsFunction(_ propName: JavaScriptPropNameID) -> JavaScriptFunction {
227
- guard let runtime else {
228
- FatalError.runtimeLost()
200
+ /// Same as `getProperty(propName).getObject().getFunction()`, but throws instead of aborting when the
201
+ /// property is missing or not callable.
202
+ public func getPropertyAsFunction(_ propName: JavaScriptPropNameID) throws -> JavaScriptFunction {
203
+ let property = getProperty(propName)
204
+ guard property.isFunction() else {
205
+ throw PropertyNotFunctionError(name: propName.utf8())
229
206
  }
230
- let jsiFunction = pointee.getProperty(runtime.pointee, propName.pointee).getObject(runtime.pointee).getFunction(runtime.pointee)
231
- return JavaScriptFunction(runtime, jsiFunction)
207
+ return property.getFunction()
232
208
  }
233
209
 
234
- /**
235
- Returns a prototype of the object. Same as `Object.getPrototypeOf(object)` in JS.
236
- */
210
+ /// Returns a prototype of the object. Same as `Object.getPrototypeOf(object)` in JS.
237
211
  public func getPrototype() -> JavaScriptValue {
238
212
  guard let runtime else {
239
213
  FatalError.runtimeLost()
@@ -241,9 +215,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
241
215
  return JavaScriptValue(runtime, pointee.getPrototype(runtime.pointee))
242
216
  }
243
217
 
244
- /**
245
- Sets a prototype of the object. Same as `Object.setPrototypeOf(object, prototype)` in JS.
246
- */
218
+ /// Sets a prototype of the object. Same as `Object.setPrototypeOf(object, prototype)` in JS.
247
219
  public func setPrototype(_ prototype: JavaScriptValue) {
248
220
  guard let runtime else {
249
221
  FatalError.runtimeLost()
@@ -284,16 +256,17 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
284
256
  expo.setProperty(runtime.pointee, pointee, name, facebook.jsi.Value(runtime.pointee, object.pointee))
285
257
  }
286
258
 
287
- /**
288
- Deletes a property with the given name. After calling this function,
289
- `hasProperty` will return `false`, and `getProperty` will return `undefined` value.
290
- */
259
+ /// Deletes a property with the given name. After calling this function,
260
+ /// `hasProperty` will return `false`, and `getProperty` will return `undefined` value.
261
+ #if !os(macOS)
262
+ // TODO: remove when bumping to react-native-macos 0.86
291
263
  public func deleteProperty(_ name: String) {
292
264
  guard let runtime else {
293
265
  FatalError.runtimeLost()
294
266
  }
295
267
  pointee.deleteProperty(runtime.pointee, name)
296
268
  }
269
+ #endif
297
270
 
298
271
  public func defineProperty(_ name: String, descriptor: consuming JavaScriptObject) {
299
272
  guard let runtime else {
@@ -314,7 +287,9 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
314
287
  defineProperty(name, descriptor: descriptorObject)
315
288
  }
316
289
 
317
- public func defineProperty<T: JavaScriptRepresentable & ~Copyable>(_ name: String, value: borrowing T, options: PropertyOptions = []) {
290
+ public func defineProperty<T: JavaScriptRepresentable & ~Copyable>(
291
+ _ name: String, value: borrowing T, options: PropertyOptions = []
292
+ ) {
318
293
  guard let runtime else {
319
294
  FatalError.runtimeLost()
320
295
  }
@@ -329,21 +304,21 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
329
304
 
330
305
  // MARK: - Calling owned functions
331
306
 
332
- /**
333
- Compact form of `object.getPropertyAsFunction(functionName).call(this: object, arguments: ...)`.
334
- */
307
+ /// Compact form of `object.getPropertyAsFunction(functionName).call(this: object, arguments: ...)`.
335
308
  @discardableResult
336
309
  @JavaScriptActor
337
- public func callFunction<each T: JavaScriptRepresentable>(_ functionName: String, arguments: repeat each T) throws -> JavaScriptValue {
310
+ public func callFunction<each T: JavaScriptRepresentable>(_ functionName: String, arguments: repeat each T) throws
311
+ -> JavaScriptValue
312
+ {
338
313
  return try getPropertyAsFunction(functionName).call(this: self, arguments: repeat each arguments)
339
314
  }
340
315
 
341
- /**
342
- Compact form of `object.getPropertyAsFunction(functionName).call(this: object, arguments: ...)`.
343
- */
316
+ /// Compact form of `object.getPropertyAsFunction(functionName).call(this: object, arguments: ...)`.
344
317
  @discardableResult
345
318
  @JavaScriptActor
346
- public func callFunction<each T: JavaScriptRepresentable>(_ functionName: JavaScriptPropNameID, arguments: repeat each T) throws -> JavaScriptValue {
319
+ public func callFunction<each T: JavaScriptRepresentable>(
320
+ _ functionName: JavaScriptPropNameID, arguments: repeat each T
321
+ ) throws -> JavaScriptValue {
347
322
  return try getPropertyAsFunction(functionName).call(this: self, arguments: repeat each arguments)
348
323
  }
349
324
 
@@ -356,9 +331,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
356
331
  return JavaScriptValue(runtime, facebook.jsi.Value(runtime.pointee, pointee))
357
332
  }
358
333
 
359
- /**
360
- Returns the object as a `facebook.jsi.Value` instance.
361
- */
334
+ /// Returns the object as a `facebook.jsi.Value` instance.
362
335
  internal func asJSIValue() -> facebook.jsi.Value {
363
336
  guard let runtime else {
364
337
  FatalError.runtimeLost()
@@ -366,29 +339,23 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
366
339
  return facebook.jsi.Value(runtime.pointee, pointee)
367
340
  }
368
341
 
369
- /**
370
- Provides scoped access to a raw pointer to the underlying `facebook.jsi.Object`.
371
- The pointer is valid only for the duration of the closure and must not be stored or escaped.
372
- */
342
+ /// Provides scoped access to a raw pointer to the underlying `facebook.jsi.Object`.
343
+ /// The pointer is valid only for the duration of the closure and must not be stored or escaped.
373
344
  public func withUnsafePointee<R>(_ body: (UnsafeRawPointer) throws -> R) rethrows -> R {
374
345
  return try withUnsafeBytes(of: pointee) { bytes in
375
346
  return try body(bytes.baseAddress!)
376
347
  }
377
348
  }
378
349
 
379
- /**
380
- Provides scoped mutable access to a raw pointer to the underlying `facebook.jsi.Object`.
381
- The pointer is valid only for the duration of the closure and must not be stored or escaped.
382
- */
350
+ /// Provides scoped mutable access to a raw pointer to the underlying `facebook.jsi.Object`.
351
+ /// The pointer is valid only for the duration of the closure and must not be stored or escaped.
383
352
  public mutating func withUnsafeMutablePointee<R>(_ body: (UnsafeMutableRawPointer) throws -> R) rethrows -> R {
384
353
  return try withUnsafeMutableBytes(of: &pointee) { bytes in
385
354
  return try body(bytes.baseAddress!)
386
355
  }
387
356
  }
388
357
 
389
- /**
390
- Creates a weak reference to the object. If the only references to an object are these, the object is eligible for GC.
391
- */
358
+ /// Creates a weak reference to the object. If the only references to an object are these, the object is eligible for GC.
392
359
  public func createWeak() -> JavaScriptWeakObject {
393
360
  guard let runtime else {
394
361
  FatalError.runtimeLost()
@@ -398,9 +365,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
398
365
 
399
366
  // MARK: - Native state
400
367
 
401
- /**
402
- Returns whether this object has native state previously set by `setNativeState`.
403
- */
368
+ /// Returns whether this object has native state previously set by `setNativeState`.
404
369
  public func hasNativeState() -> Bool {
405
370
  guard let runtime else {
406
371
  FatalError.runtimeLost()
@@ -408,10 +373,8 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
408
373
  return expo.hasNativeState(runtime.pointee, pointee)
409
374
  }
410
375
 
411
- /**
412
- Returns a native state previously set by `setNativeState`.
413
- If `hasNativeState()` is false or object's native state is of unrelated type, this will return `nil`.
414
- */
376
+ /// Returns a native state previously set by `setNativeState`.
377
+ /// If `hasNativeState()` is false or object's native state is of unrelated type, this will return `nil`.
415
378
  public func getNativeState<T: JavaScriptNativeState>(as: T.Type = JavaScriptNativeState.self) -> T? {
416
379
  guard let runtime else {
417
380
  FatalError.runtimeLost()
@@ -422,12 +385,12 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
422
385
  return T.from(cxx: cxxNativeState)
423
386
  }
424
387
 
425
- /**
426
- Sets the internal native state property of this object, overwriting any old value.
427
- Creates a new shared_ptr to the object managed by state, which will live until the value at this property becomes unreachable.
428
- - TODO: throw a type error if this object is a proxy or host object.
429
- */
430
- public func setNativeState<T: JavaScriptNativeState>(_ nativeState: T) throws(JavaScriptNativeState.NativeStateReleasedError) {
388
+ /// Sets the internal native state property of this object, overwriting any old value.
389
+ /// Creates a new shared_ptr to the object managed by state, which will live until the value at this property becomes unreachable.
390
+ /// - TODO: throw a type error if this object is a proxy or host object.
391
+ public func setNativeState<T: JavaScriptNativeState>(_ nativeState: T) throws(JavaScriptNativeState
392
+ .NativeStateReleasedError)
393
+ {
431
394
  guard let runtime else {
432
395
  FatalError.runtimeLost()
433
396
  }
@@ -437,9 +400,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
437
400
  expo.setNativeState(runtime.pointee, pointee, nativeStatePointee)
438
401
  }
439
402
 
440
- /**
441
- Unsets the native state of this object.
442
- */
403
+ /// Unsets the native state of this object.
443
404
  public func unsetNativeState() {
444
405
  guard let runtime else {
445
406
  FatalError.runtimeLost()
@@ -458,9 +419,7 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
458
419
 
459
420
  // MARK: - Equality
460
421
 
461
- /**
462
- Compares whether the two `JavaScriptObject`s are pointing to the same underlying JS object.
463
- */
422
+ /// Compares whether the two `JavaScriptObject`s are pointing to the same underlying JS object.
464
423
  public static func == (lhs: borrowing JavaScriptObject, rhs: borrowing JavaScriptObject) -> Bool {
465
424
  // Note that we implement comparison operator, but we don't add conformance to `Equatable` because it requires types to be copyable.
466
425
  // This proposal solves it: https://github.com/swiftlang/swift-evolution/blob/main/proposals/0499-support-non-copyable-simple-protocols.md
@@ -469,55 +428,45 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
469
428
 
470
429
  // MARK: - Property options and descriptor
471
430
 
472
- /**
473
- Options for defining property attributes on JavaScript objects. These options correspond to the property
474
- descriptor attributes in JavaScript's `Object.defineProperty()` method. They control how a property behaves when
475
- accessed, enumerated, or modified.
476
-
477
- - SeeAlso: `PropertyDescriptor` for more fine-grained control over property definitions
478
- */
431
+ /// Options for defining property attributes on JavaScript objects. These options correspond to the property
432
+ /// descriptor attributes in JavaScript's `Object.defineProperty()` method. They control how a property behaves when
433
+ /// accessed, enumerated, or modified.
434
+ ///
435
+ /// - SeeAlso: `PropertyDescriptor` for more fine-grained control over property definitions
479
436
  public struct PropertyOptions: OptionSet, Sendable {
480
437
  public let rawValue: Int
481
438
 
482
439
  public init(rawValue: Int) {
483
440
  self.rawValue = rawValue
484
441
  }
485
- /**
486
- When `true`, the property descriptor may be changed and the property may be deleted.
487
- Default is `false` when not specified.
488
-
489
- Corresponds to JavaScript's `configurable` property attribute. A configurable property
490
- can have its descriptor redefined or be deleted from the object.
491
- */
442
+ /// When `true`, the property descriptor may be changed and the property may be deleted.
443
+ /// Default is `false` when not specified.
444
+ ///
445
+ /// Corresponds to JavaScript's `configurable` property attribute. A configurable property
446
+ /// can have its descriptor redefined or be deleted from the object.
492
447
  public static let configurable = PropertyOptions(rawValue: 1 << 0)
493
- /**
494
- When `true`, the property shows up during enumeration of properties.
495
- Default is `false` when not specified.
496
-
497
- Corresponds to JavaScript's `enumerable` property attribute. Enumerable properties
498
- appear in `for...in` loops and `Object.keys()` results.
499
- */
448
+ /// When `true`, the property shows up during enumeration of properties.
449
+ /// Default is `false` when not specified.
450
+ ///
451
+ /// Corresponds to JavaScript's `enumerable` property attribute. Enumerable properties
452
+ /// appear in `for...in` loops and `Object.keys()` results.
500
453
  public static let enumerable = PropertyOptions(rawValue: 1 << 1)
501
- /**
502
- When `true`, the property's value can be changed with an assignment operator.
503
- Default is `false` when not specified.
504
-
505
- Corresponds to JavaScript's `writable` property attribute. Writable properties
506
- can be modified after they are defined.
507
- */
454
+ /// When `true`, the property's value can be changed with an assignment operator.
455
+ /// Default is `false` when not specified.
456
+ ///
457
+ /// Corresponds to JavaScript's `writable` property attribute. Writable properties
458
+ /// can be modified after they are defined.
508
459
  public static let writable = PropertyOptions(rawValue: 1 << 2)
509
460
  }
510
- /**
511
- A descriptor that defines the characteristics of a property on a JavaScript object.
512
- Property descriptors provide fine-grained control over how properties behave,
513
- corresponding directly to JavaScript's property descriptor objects used with
514
- `Object.defineProperty()`. Each descriptor specifies whether the property is
515
- configurable, enumerable, writable, and what value it should hold.
516
-
517
- - Note: All boolean properties default to `false`, matching JavaScript's behavior
518
- when properties are defined via `Object.defineProperty()`.
519
- - SeeAlso: `PropertyOptions` for a simpler option-set based approach
520
- */
461
+ /// A descriptor that defines the characteristics of a property on a JavaScript object.
462
+ /// Property descriptors provide fine-grained control over how properties behave,
463
+ /// corresponding directly to JavaScript's property descriptor objects used with
464
+ /// `Object.defineProperty()`. Each descriptor specifies whether the property is
465
+ /// configurable, enumerable, writable, and what value it should hold.
466
+ ///
467
+ /// - Note: All boolean properties default to `false`, matching JavaScript's behavior
468
+ /// when properties are defined via `Object.defineProperty()`.
469
+ /// - SeeAlso: `PropertyOptions` for a simpler option-set based approach
521
470
  public struct PropertyDescriptor: ~Copyable {
522
471
  /// When `true`, the property descriptor may be changed and the property may be deleted from the object.
523
472
  let configurable: Bool
@@ -531,32 +480,30 @@ public struct JavaScriptObject: JavaScriptType, Sendable, ~Copyable {
531
480
  /// The value associated with the property. Can be any JavaScript value or `nil`.
532
481
  let value: JavaScriptValue?
533
482
 
534
- /**
535
- Creates a new property descriptor with the specified attributes.
536
-
537
- - Parameters:
538
- - configurable: Whether the property can be deleted or have its descriptor modified. Defaults to `false`.
539
- - enumerable: Whether the property appears during enumeration. Defaults to `false`.
540
- - writable: Whether the property's value can be changed. Defaults to `false`.
541
- - value: The value to assign to the property. Defaults to `nil`.
542
- - Note: When all parameters use their default values, this creates a non-configurable,
543
- non-enumerable, non-writable property with no value (undefined in JavaScript).
544
- */
545
- public init(configurable: Bool = false, enumerable: Bool = false, writable: Bool = false, value: JavaScriptValue? = nil) {
483
+ /// Creates a new property descriptor with the specified attributes.
484
+ ///
485
+ /// - Parameters:
486
+ /// - configurable: Whether the property can be deleted or have its descriptor modified. Defaults to `false`.
487
+ /// - enumerable: Whether the property appears during enumeration. Defaults to `false`.
488
+ /// - writable: Whether the property's value can be changed. Defaults to `false`.
489
+ /// - value: The value to assign to the property. Defaults to `nil`.
490
+ /// - Note: When all parameters use their default values, this creates a non-configurable,
491
+ /// non-enumerable, non-writable property with no value (undefined in JavaScript).
492
+ public init(
493
+ configurable: Bool = false, enumerable: Bool = false, writable: Bool = false, value: JavaScriptValue? = nil
494
+ ) {
546
495
  self.configurable = configurable
547
496
  self.enumerable = enumerable
548
497
  self.writable = writable
549
498
  self.value = value
550
499
  }
551
- /**
552
- Converts the descriptor to a JavaScript object that can be used with `Object.defineProperty()`.
553
- This method creates a JavaScript object with the descriptor's attributes set as properties.
554
- Only attributes that are `true` or non-nil are included in the resulting object,
555
- following JavaScript conventions.
556
-
557
- - Parameter runtime: The JavaScript runtime in which to create the descriptor object
558
- - Returns: A JavaScript object representing this property descriptor
559
- */
500
+ /// Converts the descriptor to a JavaScript object that can be used with `Object.defineProperty()`.
501
+ /// This method creates a JavaScript object with the descriptor's attributes set as properties.
502
+ /// Only attributes that are `true` or non-nil are included in the resulting object,
503
+ /// following JavaScript conventions.
504
+ ///
505
+ /// - Parameter runtime: The JavaScript runtime in which to create the descriptor object
506
+ /// - Returns: A JavaScript object representing this property descriptor
560
507
  public consuming func toObject(_ runtime: borrowing JavaScriptRuntime) -> JavaScriptObject {
561
508
  let object = runtime.createObject()
562
509
  if configurable {
@@ -587,7 +534,8 @@ extension JavaScriptObject: JavaScriptRepresentable {
587
534
  }
588
535
 
589
536
  extension JavaScriptObject: JSIRepresentable {
590
- static func fromJSIValue(_ value: borrowing facebook.jsi.Value, in runtime: facebook.jsi.IRuntime) -> JavaScriptObject {
537
+ static func fromJSIValue(_ value: borrowing facebook.jsi.Value, in runtime: facebook.jsi.IRuntime) -> JavaScriptObject
538
+ {
591
539
  FatalError.unimplemented()
592
540
  }
593
541
 
@@ -595,3 +543,23 @@ extension JavaScriptObject: JSIRepresentable {
595
543
  return asJSIValue()
596
544
  }
597
545
  }
546
+
547
+ // MARK: - Errors
548
+
549
+ extension JavaScriptObject {
550
+ public struct PropertyNotFunctionError: Error, CustomStringConvertible {
551
+ let name: String
552
+
553
+ public var description: String {
554
+ return "Property '\(name)' is not a function"
555
+ }
556
+ }
557
+
558
+ public struct PropertyNotObjectError: Error, CustomStringConvertible {
559
+ let name: String
560
+
561
+ public var description: String {
562
+ return "Property '\(name)' is not an object"
563
+ }
564
+ }
565
+ }