Skip to content

Declarative JS interop #290

Open
0 of 5 issues completed
Open
0 of 5 issues completed
@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.

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

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions