Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Declarative JS interop #290

Open
3 of 11 tasks
kateinoigakukun opened this issue Mar 10, 2025 · 0 comments
Open
3 of 11 tasks

Declarative JS interop #290

kateinoigakukun opened this issue Mar 10, 2025 · 0 comments

Comments

@kateinoigakukun
Copy link
Member

kateinoigakukun commented Mar 10, 2025

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
  • Implementation Plan
  • TBD

Other Languages

@kateinoigakukun kateinoigakukun converted this from a draft issue Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In progress
Development

No branches or pull requests

1 participant