YolkModule
The protocol every native module must conform to. In practice, you implement the protocol generated by codegen — you rarely implement YolkModule directly.
public protocol YolkModule: Sendable {
static var moduleName: String { get }
func handle(method: String, args: [YolkValue]) async throws -> YolkValue
}
Requirements
moduleName
The name TypeScript uses to reach this module. Must match the name used when constructing the generated proxy:
static var moduleName: String { "Storage" }
Codegen sets this automatically via the generated extension.
handle(method:args:)
Dispatch a method call from JS. Receives the method name and arguments as [YolkValue]. Returns a single YolkValue.
Codegen generates a handle implementation that switches on the method name, extracts and validates arguments, calls the domain method, and wraps the return value. You do not write handle yourself.
Implementing a module
The typical pattern is to conform to the generated protocol (e.g. StorageModule) on a Swift actor:
actor AppStorageModule: StorageModule {
private var store: [String: String] = [:]
func get(key: String) async throws -> String? {
store[key]
}
func set(key: String, value: String) async throws {
store[key] = value
}
func delete(key: String) async throws {
store.removeValue(forKey: key)
}
}
YolkError
Errors thrown from module methods are propagated as Promise rejections on the TypeScript side.
public enum YolkError: Error, Sendable {
case moduleNotFound(String)
case methodFailed(module: String, method: String, underlying: Error)
case invalidArgs(String)
case runtimeError(String)
case jsException(String)
}