// Copyright 2025-present 650 Industries. All rights reserved. internal import ExpoModulesJSI_Cxx internal import jsi /// A Swift representation of a JavaScript array buffer. Provides access to the /// underlying raw data pointer and size of the buffer. public struct JavaScriptArrayBuffer: ~Copyable { internal weak let runtime: JavaScriptRuntime? internal let pointee: facebook.jsi.ArrayBuffer internal init(_ runtime: JavaScriptRuntime, _ arrayBuffer: consuming facebook.jsi.ArrayBuffer) { self.runtime = runtime self.pointee = arrayBuffer } /// Returns the size of the array buffer storage in bytes. /// This is not affected by overriding the `byteLength` property. public var size: Int { guard let runtime else { FatalError.runtimeLost() } return Int(expo.arrayBufferSize(runtime.pointee, pointee)) } /// Alias for `size` that matches JavaScript's `ArrayBuffer.byteLength` property. public var byteLength: Int { size } /// Returns a pointer to the underlying data of the array buffer. public func data() -> UnsafeMutablePointer { guard let runtime else { FatalError.runtimeLost() } return expo.arrayBufferData(runtime.pointee, pointee) } /// Creates a new array buffer with a copy of this buffer's data. public func copy() -> JavaScriptArrayBuffer { guard let runtime else { FatalError.runtimeLost() } let byteCount = size let newBuffer = runtime.createArrayBuffer(size: byteCount) memcpy(newBuffer.data(), data(), byteCount) return newBuffer } // MARK: - Zero-copy borrowing /// Attempts to obtain the underlying native MutableBuffer without copying. /// Returns `nil` if the buffer is JS-heap-allocated (no MutableBuffer available). /// The returned buffer keeps the underlying memory alive until it is deallocated. public func tryBorrowMutableBuffer() -> JavaScriptMutableBuffer? { guard let runtime else { FatalError.runtimeLost() } let borrowed = expo.tryBorrowMutableBuffer(runtime.pointee, pointee) guard let data = borrowed.data, let retainer = borrowed.retainer else { return nil } return JavaScriptMutableBuffer(data: data, size: Int(borrowed.size), retainer: retainer) } // MARK: - Conversions /// Returns this array buffer as a `JavaScriptValue`. public func asValue() -> JavaScriptValue { guard let runtime else { FatalError.runtimeLost() } return JavaScriptValue(runtime, expo.valueFromArrayBuffer(runtime.pointee, pointee)) } // MARK: - Providing JavaScriptObject API public func getProperty(_ name: String) -> JavaScriptValue { guard let runtime else { FatalError.runtimeLost() } return JavaScriptValue(runtime, pointee.getProperty(runtime.pointee, name)) } }