first commit

This commit is contained in:
2026-03-10 16:18:05 +00:00
commit 11f9c069b5
31635 changed files with 3187747 additions and 0 deletions

View File

@@ -0,0 +1,34 @@
// Copyright 2022-present 650 Industries. All rights reserved.
/**
A result builder that captures the ``ClassDefinition`` elements such as functions, constants and properties.
*/
@resultBuilder
public struct ClassDefinitionBuilder<OwnerType> {
public static func buildBlock(_ elements: AnyClassDefinitionElement...) -> [AnyClassDefinitionElement] {
return elements
}
/**
Default implementation without any constraints that just returns type-erased element.
*/
public static func buildExpression<ElementType: AnyClassDefinitionElement>(
_ element: ElementType
) -> AnyClassDefinitionElement {
return element
}
/**
In case the element's owner type matches builder's generic type,
we need to instruct the function to pass `this` to the closure
as the first argument and deduct it from `argumentsCount`.
*/
public static func buildExpression<ElementType: ClassDefinitionElement>(
_ element: ElementType
) -> AnyClassDefinitionElement where ElementType.OwnerType == OwnerType {
if var function = element as? AnyFunctionDefinition {
function.takesOwner = true
}
return element
}
}

View File

@@ -0,0 +1,27 @@
// Copyright 2022-present 650 Industries. All rights reserved.
public protocol AnyObjectDefinitionElement: AnyDefinition {}
@resultBuilder
public struct ObjectDefinitionBuilder {
public static func buildBlock(_ elements: AnyObjectDefinitionElement...) -> [AnyObjectDefinitionElement] {
return elements
}
/**
Default implementation without any constraints that just returns type-erased element.
*/
public static func buildExpression<ElementType: AnyObjectDefinitionElement>(_ element: ElementType) -> AnyObjectDefinitionElement {
return element
}
}
extension SyncFunctionDefinition: AnyObjectDefinitionElement {}
extension AsyncFunctionDefinition: AnyObjectDefinitionElement {}
extension PropertyDefinition: AnyObjectDefinitionElement {}
extension ConstantDefinition: AnyObjectDefinitionElement {}
extension ConstantsDefinition: AnyObjectDefinitionElement {}

View File

@@ -0,0 +1,65 @@
/**
A result builder for the view elements such as prop setters or view events.
*/
@resultBuilder
public struct ViewDefinitionBuilder<ViewType: UIView> {
public static func buildBlock(_ elements: AnyViewDefinitionElement...) -> [AnyViewDefinitionElement] {
return elements
}
/**
Accepts `Events` definition element of `View`.
*/
public static func buildExpression(_ element: EventsDefinition) -> AnyViewDefinitionElement {
return element
}
/**
Accepts `ViewName` definition element of `View`.
*/
public static func buildExpression(_ element: ViewNameDefinition) -> AnyViewDefinitionElement {
return element
}
/**
Accepts `Prop` definition element and lets to skip defining the view type it's inferred from the `View` definition.
*/
public static func buildExpression<PropType: AnyArgument>(_ element: ConcreteViewProp<ViewType, PropType>) -> AnyViewDefinitionElement {
return element
}
/**
Accepts lifecycle methods (such as `OnViewDidUpdateProps`) as a definition element.
*/
public static func buildExpression(_ element: ViewLifecycleMethod<ViewType>) -> AnyViewDefinitionElement {
return element
}
/**
Accepts functions as a view definition elements.
*/
public static func buildExpression<ElementType: ViewDefinitionFunctionElement>(
_ element: ElementType
) -> AnyViewDefinitionElement {
return element
}
/**
Accepts functions that take the owner as a view definition elements.
*/
public static func buildExpression<ElementType: ViewDefinitionFunctionElement>(
_ element: ElementType
) -> AnyViewDefinitionElement where ElementType.ViewType == ViewType {
// Enforce async functions to run on the main queue
if var function = element as? AnyAsyncFunctionDefinition {
function.runOnQueue(.main)
function.takesOwner = true
}
if var function = element as? AnyConcurrentFunctionDefinition {
function.requiresMainActor = true
function.takesOwner = true
}
return element
}
}

View File

@@ -0,0 +1,40 @@
/**
Asynchronous function without arguments.
*/
public func AsyncFunction<R>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping () throws -> R
) -> AsyncFunctionDefinition<(), Void, R> {
return AsyncFunctionDefinition(
name,
firstArgType: Void.self,
dynamicArgumentTypes: [],
closure
)
}
/**
Asynchronous function with one or more arguments.
*/
public func AsyncFunction<R, A0: AnyArgument, each A: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping (A0, repeat each A) throws -> R
) -> AsyncFunctionDefinition<(A0, repeat each A), A0, R> {
return AsyncFunctionDefinition(
name,
firstArgType: A0.self,
dynamicArgumentTypes: buildDynamicTypes(A0.self, repeat (each A).self),
closure
)
}
func buildDynamicTypes<A0: AnyArgument, each A: AnyArgument>(
_ first: A0.Type,
_ rest: repeat (each A).Type
) -> [AnyDynamicType] {
var result: [AnyDynamicType] = [~first]
for type in repeat each rest {
result.append(~type)
}
return result
}

View File

@@ -0,0 +1,51 @@
// Copyright 2022-present 650 Industries. All rights reserved.
/**
Class constructor without arguments.
*/
public func Constructor<R>(
@_implicitSelfCapture _ body: @escaping () throws -> R
) -> SyncFunctionDefinition<(), Void, R> {
return Function("constructor", body)
}
/**
Class constructor with one or more arguments.
*/
public func Constructor<R, A0: AnyArgument, each A: AnyArgument>(
@_implicitSelfCapture _ body: @escaping (A0, repeat each A) throws -> R
) -> SyncFunctionDefinition<(A0, repeat each A), A0, R> {
return Function("constructor", body)
}
/**
Creates the definition describing a JavaScript class.
*/
public func Class(
_ name: String,
@ClassDefinitionBuilder<JavaScriptObject> @_implicitSelfCapture _ elements: () -> [AnyClassDefinitionElement]
) -> ClassDefinition {
return ClassDefinition(name: name, associatedType: JavaScriptObject.self, elements: elements())
}
/**
Creates the definition describing a JavaScript class with an associated native shared object class.
*/
public func Class<SharedObjectType: SharedObject>(
_ name: String = String(describing: SharedObjectType.self),
_ sharedObjectType: SharedObjectType.Type,
@ClassDefinitionBuilder<SharedObjectType> @_implicitSelfCapture _ elements: () -> [AnyClassDefinitionElement]
) -> ClassDefinition {
return ClassDefinition(name: name, associatedType: SharedObjectType.self, elements: elements())
}
/**
Creates the definition describing a JavaScript class with an associated native shared object class
and with the name that is inferred from the shared object type.
*/
public func Class<SharedObjectType: SharedObject>(
_ sharedObjectType: SharedObjectType.Type,
@ClassDefinitionBuilder<SharedObjectType> @_implicitSelfCapture _ elements: () -> [AnyClassDefinitionElement]
) -> ClassDefinition {
return ClassDefinition(name: String(describing: SharedObjectType.self), associatedType: SharedObjectType.self, elements: elements())
}

View File

@@ -0,0 +1,29 @@
/**
Concurrently-executing asynchronous function without arguments.
*/
public func AsyncFunction<R>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping () async throws -> R
) -> ConcurrentFunctionDefinition<(), Void, R> {
return ConcurrentFunctionDefinition(
name,
firstArgType: Void.self,
dynamicArgumentTypes: [],
closure
)
}
/**
Concurrently-executing asynchronous function with one or more arguments.
*/
public func AsyncFunction<R, A0: AnyArgument, each A: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping (A0, repeat each A) async throws -> R
) -> ConcurrentFunctionDefinition<(A0, repeat each A), A0, R> {
return ConcurrentFunctionDefinition(
name,
firstArgType: A0.self,
dynamicArgumentTypes: buildDynamicTypes(A0.self, repeat (each A).self),
closure
)
}

View File

@@ -0,0 +1,13 @@
/**
Creates the read-only constant with the given name. The definition is no-op if you don't call `.get(_:)` on it.
*/
public func Constant<Value: AnyArgument>(_ name: String) -> ConstantDefinition<Value> {
return ConstantDefinition(name: name)
}
/**
Creates the read-only constant whose getter doesn't take the owner as an argument.
*/
public func Constant<Value: AnyArgument>(_ name: String, @_implicitSelfCapture get: @escaping () -> Value) -> ConstantDefinition<Value> {
return ConstantDefinition(name: name, getter: get)
}

View File

@@ -0,0 +1,41 @@
/**
Creates module's lifecycle listener that is called right after module initialization.
*/
public func OnCreate(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.moduleCreate, closure)
}
/**
Creates module's lifecycle listener that is called when the module is about to be deallocated.
*/
public func OnDestroy(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.moduleDestroy, closure)
}
/**
Creates module's lifecycle listener that is called when the app context owning the module is about to be deallocated.
*/
public func OnAppContextDestroys(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.appContextDestroys, closure)
}
/**
Creates a listener that is called when the app is about to enter the foreground mode.
*/
public func OnAppEntersForeground(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.appEntersForeground, closure)
}
/**
Creates a listener that is called when the app becomes active again.
*/
public func OnAppBecomesActive(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.appBecomesActive, closure)
}
/**
Creates a listener that is called when the app enters the background mode.
*/
public func OnAppEntersBackground(@_implicitSelfCapture _ closure: @escaping () -> Void) -> AnyDefinition {
return EventListener(.appEntersBackground, closure)
}

View File

@@ -0,0 +1,6 @@
/**
Sets the name of the module that is exported to the JavaScript world.
*/
public func Name(_ name: String) -> AnyDefinition {
return ModuleNameDefinition(name: name)
}

View File

@@ -0,0 +1,56 @@
/// This file implements factories for definitions that are allowed in any object-based definition `ObjectDefinition`.
/// So far only constants and functions belong to plain object.
// MARK: - Object
public func Object(@ObjectDefinitionBuilder @_implicitSelfCapture _ body: () -> [AnyDefinition]) -> ObjectDefinition {
return ObjectDefinition(definitions: body())
}
// MARK: - Constants
/**
Definition function setting the module's constants to export.
*/
@available(*, deprecated, message: "Use `Constant` or `Property` instead")
public func Constants(@_implicitSelfCapture _ body: @escaping () -> [String: Any?]) -> AnyDefinition {
return ConstantsDefinition(body: body)
}
/**
Definition function setting the module's constants to export.
*/
@available(*, deprecated, message: "Use `Constant` or `Property` instead")
public func Constants(@_implicitSelfCapture _ body: @autoclosure @escaping () -> [String: Any?]) -> AnyDefinition {
return ConstantsDefinition(body: body)
}
// MARK: - Events
/**
Defines event names that the object can send to JavaScript.
*/
public func Events(_ names: String...) -> EventsDefinition {
return EventsDefinition(names: names)
}
/**
Defines event names that the object can send to JavaScript.
*/
public func Events(_ names: [String]) -> EventsDefinition {
return EventsDefinition(names: names)
}
/**
Function that is invoked when the first event listener is added.
*/
public func OnStartObserving(_ event: String? = nil, @_implicitSelfCapture _ closure: @escaping () -> Void) -> EventObservingDefinition {
return EventObservingDefinition(type: .startObserving, event: event, closure)
}
/**
Function that is invoked when all event listeners are removed.
*/
public func OnStopObserving(_ event: String? = nil, @_implicitSelfCapture _ closure: @escaping () -> Void) -> EventObservingDefinition {
return EventObservingDefinition(type: .stopObserving, event: event, closure)
}

View File

@@ -0,0 +1,50 @@
/**
Creates the property with given name. The definition is basically no-op if you don't call `.get(_:)` or `.set(_:)` on it.
*/
public func Property(_ name: String) -> PropertyDefinition<Void> {
return PropertyDefinition(name: name)
}
/**
Creates the read-only property whose getter doesn't take the owner as an argument.
*/
public func Property<Value: AnyArgument>(_ name: String, @_implicitSelfCapture get: @escaping () -> Value) -> PropertyDefinition<Void> {
return PropertyDefinition(name: name, getter: get)
}
/**
Creates the read-only property whose getter takes the owner as an argument.
*/
public func Property<Value: AnyArgument, OwnerType>(
_ name: String,
@_implicitSelfCapture get: @escaping (_ this: OwnerType) -> Value
) -> PropertyDefinition<OwnerType> {
return PropertyDefinition<OwnerType>(name: name, getter: get)
}
/**
Creates the property that references to an immutable property of the owner object using the key path.
*/
public func Property<Value: AnyArgument, OwnerType>(
_ name: String,
_ keyPath: KeyPath<OwnerType, Value>
) -> PropertyDefinition<OwnerType> {
return PropertyDefinition<OwnerType>(name: name) { owner in
return owner[keyPath: keyPath]
}
}
/**
Creates the property that references to a mutable property of the owner object using the key path.
*/
public func Property<Value: AnyArgument, OwnerType>(
_ name: String,
_ keyPath: ReferenceWritableKeyPath<OwnerType, Value>
) -> PropertyDefinition<OwnerType> {
return PropertyDefinition<OwnerType>(name: name) { owner in
return owner[keyPath: keyPath]
}
.set { owner, newValue in
owner[keyPath: keyPath] = newValue
}
}

View File

@@ -0,0 +1,61 @@
/**
Static synchronous function without arguments.
*/
public func StaticFunction<R>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping () throws -> R
) -> StaticSyncFunctionDefinition<(), Void, R> {
return StaticSyncFunctionDefinition(
name,
firstArgType: Void.self,
dynamicArgumentTypes: [],
returnType: ~R.self,
closure
)
}
/**
Static synchronous function with one or more arguments.
*/
public func StaticFunction<R, A0: AnyArgument, each A: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping (A0, repeat each A) throws -> R
) -> StaticSyncFunctionDefinition<(A0, repeat each A), A0, R> {
return StaticSyncFunctionDefinition(
name,
firstArgType: A0.self,
dynamicArgumentTypes: buildDynamicTypes(A0.self, repeat (each A).self),
returnType: ~R.self,
closure
)
}
/**
Static asynchronous function without arguments.
*/
public func StaticAsyncFunction<R>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping () throws -> R
) -> StaticAsyncFunctionDefinition<(), Void, R> {
return StaticAsyncFunctionDefinition(
name,
firstArgType: Void.self,
dynamicArgumentTypes: [],
closure
)
}
/**
Static asynchronous function with one or more arguments.
*/
public func StaticAsyncFunction<R, A0: AnyArgument, each A: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping (A0, repeat each A) throws -> R
) -> StaticAsyncFunctionDefinition<(A0, repeat each A), A0, R> {
return StaticAsyncFunctionDefinition(
name,
firstArgType: A0.self,
dynamicArgumentTypes: buildDynamicTypes(A0.self, repeat (each A).self),
closure
)
}

View File

@@ -0,0 +1,31 @@
/**
Synchronous function without arguments.
*/
public func Function<R>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping () throws -> R
) -> SyncFunctionDefinition<(), Void, R> {
return SyncFunctionDefinition(
name,
firstArgType: Void.self,
dynamicArgumentTypes: [],
returnType: ~R.self,
closure
)
}
/**
Synchronous function with one or more arguments.
*/
public func Function<R, A0: AnyArgument, each A: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ closure: @escaping (A0, repeat each A) throws -> R
) -> SyncFunctionDefinition<(A0, repeat each A), A0, R> {
return SyncFunctionDefinition(
name,
firstArgType: A0.self,
dynamicArgumentTypes: buildDynamicTypes(A0.self, repeat (each A).self),
returnType: ~R.self,
closure
)
}

View File

@@ -0,0 +1,83 @@
/// Here we implement factories for the definitions exclusive for native views.
// Function names should start with a lowercase character, but in this one case
// we want it to be uppercase for Expo Modules DSL
// swiftlint:disable identifier_name
/**
Creates a view definition describing the native view exported to React.
*/
public func View<ViewType: UIView>(
_ viewType: ViewType.Type,
@ViewDefinitionBuilder<ViewType> _ elements: @escaping () -> [AnyViewDefinitionElement]
) -> ViewDefinition<ViewType> {
return ViewDefinition(viewType, elements: elements())
}
/**
Creates a view definition describing the native SwiftUI view exported to React.
*/
public func View<Props: ExpoSwiftUI.ViewProps, ViewType: ExpoSwiftUI.View>(
_ viewType: ViewType.Type
) -> ExpoSwiftUI.ViewDefinition<Props, ViewType> {
return ExpoSwiftUI.ViewDefinition(ViewType.self)
}
public func View<Props: ExpoSwiftUI.ViewProps, ViewType: ExpoSwiftUI.View>(
_ viewType: ViewType.Type,
@ExpoSwiftUI.ViewDefinitionBuilder<ViewType> _ elements: @escaping () -> [AnyViewDefinitionElement]
) -> ExpoSwiftUI.ViewDefinition<Props, ViewType> {
return ExpoSwiftUI.ViewDefinition(ViewType.self, elements: elements())
}
// MARK: Props
/**
Creates a view prop that defines its name and setter.
*/
public func Prop<ViewType: UIView, PropType: AnyArgument>(
_ name: String,
@_implicitSelfCapture _ setter: @escaping @MainActor (ViewType, PropType) -> Void
) -> ConcreteViewProp<ViewType, PropType> {
return ConcreteViewProp(
name: name,
propType: ~PropType.self,
setter: setter
)
}
/**
Creates a view prop that defines its name, default value and setter.
*/
public func Prop<ViewType: UIView, PropType: AnyArgument>(
_ name: String,
_ defaultValue: PropType,
@_implicitSelfCapture _ setter: @escaping @MainActor (ViewType, PropType) -> Void
) -> ConcreteViewProp<ViewType, PropType> {
return ConcreteViewProp(
name: name,
propType: ~PropType.self,
defaultValue: defaultValue,
setter: setter
)
}
// MARK: - View lifecycle
/**
Defines the view lifecycle method that is called when the view finished updating all props.
*/
public func OnViewDidUpdateProps<ViewType: UIView>(
@_implicitSelfCapture _ closure: @escaping @MainActor (_ view: ViewType) -> Void
) -> ViewLifecycleMethod<ViewType> {
return ViewLifecycleMethod(type: .didUpdateProps, closure: closure)
}
/**
Sets the name of the view that is exported to the JavaScript world.
*/
public func ViewName(_ name: String) -> ViewNameDefinition {
return ViewNameDefinition(name: name)
}
// swiftlint:enable identifier_name