Skip to content

feat: add Swift package for rendering with the WebAssembly modules - #14

Open
deodad wants to merge 2 commits into
wevm:mainfrom
deodad:feat/swift-package
Open

deodad wants to merge 2 commits into
wevm:mainfrom
deodad:feat/swift-package

Conversation

@deodad

@deodad deodad commented Oct 31, 2026 •

Copy link
Copy Markdown

Motivation

Native apps on macOS and iOS, and Swift servers on Linux, cannot use ondine/compiler/wasm without a JavaScript engine. iOS allows no JIT, so these apps need a WebAssembly interpreter and a wrapper for the module's ABI. Each app now writes and maintains its own wrapper.

Changes

  • Adds Package.swift at the repository root with the Ondine library under swift/. It runs a caller-supplied module in WasmKit 0.4.
  • Ondine.Compiler(module:) takes one module: all.generated.wasm for every diagram type, or the module of one type, which renders only that type.
  • Ondine.Options has the fields of render.Options and sends the same JSON. A fuel budget stops a pathological source with RenderError.fuelExhausted. Options.defaultFuel is one billion instructions, about one second in an optimized build, and callers can raise it.
  • Ondine.RenderError.diagnostic carries the code, line, column, snippet, and message of RenderError. After a trap, the next render uses a fresh instance.
  • Compiler is Sendable, and a lock serializes its renders.
  • Adds a Swift job to the Verify workflow, the Swift Package guide, and a changeset.

Example

import Ondine

// Renders with all.generated.wasm from the npm package
let compiler = try Ondine.Compiler(module: Data(contentsOf: url))
let rendered = try compiler.render("flowchart LR\n  A --> B", options: .init(maxWidth: 640))
print(rendered.type, rendered.width, rendered.svg.prefix(4)) // flowchart 160.0 <svg

Validation

swift test passes with Swift 6.4.2 and in the swift:6.3-noble container (8 tests). Diagnostics, links, and widths in the tests match ondine/compiler/wasm for the same source and modules. Every sample in test/vectors/samples.json renders within ten million fuel, and one billion fuel runs out in 0.6 s in a release build. pnpm check and pnpm check:types pass.

Open Question

Should the package stay in this repository, with callers copying the .wasm from the npm package, or move to a separate repository such as ondine-swift? Tagged releases there could bundle the module as a resource, so Swift apps add one dependency and SwiftPM pins versions (this repository has no semver tags). The in-repo package needs no release process, while a separate repository must publish a release for each ondine version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant