Skip to content

BridgeJS: Declarative JS interop #290

@kateinoigakukun

Description

@kateinoigakukun

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.

Current Status

Try on our playground https://swiftwasm.org/JavaScriptKit/PlayBridgeJS/

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:

  1. Swift and JS bridging glue code to expose CanvasContext to Swift
  2. Swift and JS/TS bridging glue code to expose App methods to JS/TS

Breakdown

  • Produce ES Module package with some instantiation JS code and .wasm
    • Check if the current SwiftPM Plugin API has enough capability to produce a JS package
    • Packaging Plugin #288
  • Prototype a tool to expose Swift interface to TS/JS
    • Check if we can process it without swift-syntax dependency (to avoid longer build time)
    • Performance benchmark
  • Prototype a tool to import TS interface to Swift
    • Check if TypeScript Compiler API can handle third-party JS packages
    • Performance benchmark

Other Languages

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions