JavaScriptKit
JavaScriptKit copied to clipboard
BridgeJS: Declarative JS interop
Motivation
Current JS interop system, JavaScriptKit, has two main issues:
- It's based on dynamic, string-based method calls and properties access.
- It's not type-safe and can easily lead to runtime errors even if the JS side is written with types (like TypeScript).
- There are non-trivial performance penalties due to the dynamism.
- There is no easy way to expose Swift functionalities to JS side.
- Developer productivity
- We need to write so many boilerplates to set up closures and type conversions for each exposed function.
- Has some performance penalties too.
High-level API
Given the following interface:
// bridge.d.ts
export interface CanvasContext {
drawRect(x: number, y: number, width: number, height: number) => void;
}
// App.swift
public struct App {
let context: CanvasContext
@ExposeToJS
init(context: CanvasContext) {
self.context = context
}
struct PointerEvent {
let x: Int
let y: Int
let pointerId: Int
}
@ExposeToJS
func feedPointerEvents(_ events: [PointerEvent]) {
...
context.drawRect(...)
}
}
Then SwiftPM Build Plugin or standalone CLI tool should generate:
- Swift and JS bridging glue code to expose
CanvasContextto Swift - Swift and JS/TS bridging glue code to expose
Appmethods to JS/TS
Breakdown
- [x] Produce ES Module package with some instantiation JS code and .wasm
- [x] Check if the current SwiftPM Plugin API has enough capability to produce a JS package
- [x] https://github.com/swiftwasm/JavaScriptKit/pull/288
- [x] Prototype a tool to expose Swift interface to TS/JS
- [x] Check if we can process it without swift-syntax dependency (to avoid longer build time)
- [x] Performance benchmark
- [x] Prototype a tool to import TS interface to Swift
- [x] Check if TypeScript Compiler API can handle third-party JS packages
- [x] Performance benchmark
Other Languages
- https://learn.microsoft.com/en-us/aspnet/core/client-side/dotnet-interop?view=aspnetcore-9.0
- https://kotlinlang.org/docs/js-to-kotlin-interop.html
- https://rescript-lang.org/docs/manual/v11.0.0/interop-cheatsheet
- https://github.com/rustwasm/wasm-bindgen/
- https://github.com/siefkenj/tsify
- https://github.com/ocsigen/ts2ocaml