diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 0e720b4df..000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-root = true
-
-[*]
-indent_style = space
-indent_size = 4
-trim_trailing_whitespace = true
-insert_final_newline = true
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index 95204dad7..000000000
--- a/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-Sources/JavaScriptKit/Runtime/** linguist-generated
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
deleted file mode 100644
index 89b4d26e4..000000000
--- a/.github/FUNDING.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-# These are supported funding model platforms
-
-github: [swiftwasm] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
-patreon: # Replace with a single Patreon username
-open_collective: swiftwasm # Replace with a single Open Collective username
-ko_fi: # Replace with a single Ko-fi username
-tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-liberapay: # Replace with a single Liberapay username
-issuehunt: # Replace with a single IssueHunt username
-otechie: # Replace with a single Otechie username
-custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
diff --git a/.github/actions/install-swift/action.yml b/.github/actions/install-swift/action.yml
deleted file mode 100644
index d6fbcc969..000000000
--- a/.github/actions/install-swift/action.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: 'Install Swift toolchain'
-description: 'Install Swift toolchain tarball from URL'
-inputs:
- download-url:
- description: 'URL to download Swift toolchain tarball'
- required: true
-
-runs:
- using: composite
- steps:
- # https://www.swift.org/install/linux/#installation-via-tarball
- - name: Install dependent packages for Swift
- shell: bash
- run: >
- sudo apt-get -q update &&
- sudo apt-get install -y
- binutils
- git
- gnupg2
- libc6-dev
- libcurl4-openssl-dev
- libedit2
- libgcc-9-dev
- libpython3.8
- libsqlite3-0
- libstdc++-9-dev
- libxml2-dev
- libz3-dev
- pkg-config
- tzdata
- unzip
- zlib1g-dev
- curl
-
- - name: Install Swift
- shell: bash
- run: curl -fL ${{ inputs.download-url }} | sudo tar xfz - --strip-components=2 -C /usr/local
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index 8a923bf7a..000000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-# To get started with Dependabot version updates, you'll need to specify which
-# package ecosystems to update and where the package manifests are located.
-# Please see the documentation for all configuration options:
-# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
-
-version: 2
-updates:
- - package-ecosystem: 'github-actions'
- directory: '/'
- schedule:
- interval: 'weekly'
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
deleted file mode 100644
index cf0224346..000000000
--- a/.github/workflows/test.yml
+++ /dev/null
@@ -1,90 +0,0 @@
-name: Run unit tests
-on:
- pull_request:
- push:
- branches: [main]
-jobs:
- test:
- name: Build and Test
- strategy:
- matrix:
- entry:
- - os: ubuntu-22.04
- toolchain:
- download-url: https://download.swift.org/swift-6.0.2-release/ubuntu2204/swift-6.0.2-RELEASE/swift-6.0.2-RELEASE-ubuntu22.04.tar.gz
- wasi-backend: Node
- target: "wasm32-unknown-wasi"
- - os: ubuntu-22.04
- toolchain:
- download-url: https://download.swift.org/swift-6.1-release/ubuntu2204/swift-6.1-RELEASE/swift-6.1-RELEASE-ubuntu22.04.tar.gz
- wasi-backend: Node
- target: "wasm32-unknown-wasi"
- - os: ubuntu-22.04
- toolchain:
- download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2025-04-12-a/swift-DEVELOPMENT-SNAPSHOT-2025-04-12-a-ubuntu22.04.tar.gz
- wasi-backend: Node
- target: "wasm32-unknown-wasi"
- - os: ubuntu-22.04
- toolchain:
- download-url: https://download.swift.org/development/ubuntu2204/swift-DEVELOPMENT-SNAPSHOT-2025-04-12-a/swift-DEVELOPMENT-SNAPSHOT-2025-04-12-a-ubuntu22.04.tar.gz
- wasi-backend: Node
- target: "wasm32-unknown-wasip1-threads"
-
- runs-on: ${{ matrix.entry.os }}
- env:
- JAVASCRIPTKIT_WASI_BACKEND: ${{ matrix.entry.wasi-backend }}
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- - uses: ./.github/actions/install-swift
- with:
- download-url: ${{ matrix.entry.toolchain.download-url }}
- - uses: swiftwasm/setup-swiftwasm@v2
- id: setup-swiftwasm
- with:
- target: ${{ matrix.entry.target }}
- - name: Configure environment variables
- run: |
- echo "SWIFT_SDK_ID=${{ steps.setup-swiftwasm.outputs.swift-sdk-id }}" >> $GITHUB_ENV
- echo "SWIFT_PATH=$(dirname $(which swiftc))" >> $GITHUB_ENV
- - run: make bootstrap
- - run: make unittest
- # Skip unit tests with uwasi because its proc_exit throws
- # unhandled promise rejection.
- if: ${{ matrix.entry.wasi-backend != 'MicroWASI' }}
- - name: Check if SwiftPM resources are stale
- run: |
- make regenerate_swiftpm_resources
- git diff --exit-code Sources/JavaScriptKit/Runtime
- - run: swift test --package-path ./Plugins/PackageToJS
- - run: swift test --package-path ./Plugins/BridgeJS
-
- native-build:
- # Check native build to make it easy to develop applications by Xcode
- name: Build for native target
- strategy:
- matrix:
- include:
- - os: macos-15
- xcode: Xcode_16
- runs-on: ${{ matrix.os }}
- steps:
- - uses: actions/checkout@v4
- - run: swift build --package-path ./Examples/Basic
- env:
- DEVELOPER_DIR: /Applications/${{ matrix.xcode }}.app/Contents/Developer/
-
- format:
- runs-on: ubuntu-latest
- container:
- image: swift:6.0.3
- steps:
- - uses: actions/checkout@v4
- - run: ./Utilities/format.swift
- - name: Check for formatting changes
- run: |
- git config --global --add safe.directory "$GITHUB_WORKSPACE"
- git diff --exit-code || {
- echo "::error::The formatting changed some files. Please run \`./Utilities/format.swift\` and commit the changes."
- exit 1
- }
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5aac0048c..000000000
--- a/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-dist
-node_modules
-.DS_Store
-.build
-/Packages
-/*.xcodeproj
-xcuserdata/
-.swiftpm
-.vscode
-Examples/*/Bundle
-Examples/*/package-lock.json
-Package.resolved
-Plugins/BridgeJS/Sources/JavaScript/package-lock.json
diff --git a/.prettierignore b/.prettierignore
deleted file mode 100644
index 24e5b0a1a..000000000
--- a/.prettierignore
+++ /dev/null
@@ -1 +0,0 @@
-.build
diff --git a/.prettierrc b/.prettierrc
deleted file mode 100644
index c7d8640bf..000000000
--- a/.prettierrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "overrides": [
- {
- "files": ["tsconfig.json", "*.js", "*.ts"],
- "options": {
- "tabWidth": 4
- }
- }
- ]
-}
diff --git a/.spi.yml b/.spi.yml
deleted file mode 100644
index 94203e1d3..000000000
--- a/.spi.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-version: 1
-builder:
- configs:
- - documentation_targets:
- - JavaScriptKit
- - JavaScriptEventLoop
- - JavaScriptBigIntSupport
diff --git a/.swift-format b/.swift-format
deleted file mode 100644
index 22ce671e7..000000000
--- a/.swift-format
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "version": 1,
- "lineLength": 120,
- "indentation": {
- "spaces": 4
- },
- "lineBreakBeforeEachArgument": true,
- "indentConditionalCompilationBlocks": false,
- "prioritizeKeepingFunctionOutputTogether": true,
- "rules": {
- "AlwaysUseLowerCamelCase": false
- }
-}
diff --git a/404.html b/404.html
new file mode 100644
index 000000000..af1942659
--- /dev/null
+++ b/404.html
@@ -0,0 +1,3 @@
+---
+redirect_to: https://swiftpackageindex.com/swiftwasm/JavaScriptKit/main/documentation/javascriptkit
+---
diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift
deleted file mode 100644
index 4d59c772e..000000000
--- a/Benchmarks/Package.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-// swift-tools-version: 6.0
-
-import PackageDescription
-
-let package = Package(
- name: "Benchmarks",
- dependencies: [
- .package(path: "../")
- ],
- targets: [
- .executableTarget(
- name: "Benchmarks",
- dependencies: ["JavaScriptKit"],
- exclude: ["Generated/JavaScript", "bridge.d.ts"],
- swiftSettings: [
- .enableExperimentalFeature("Extern")
- ]
- )
- ]
-)
diff --git a/Benchmarks/README.md b/Benchmarks/README.md
deleted file mode 100644
index eeafc395a..000000000
--- a/Benchmarks/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# JavaScriptKit Benchmarks
-
-This directory contains performance benchmarks for JavaScriptKit.
-
-## Building Benchmarks
-
-Before running the benchmarks, you need to build the test suite:
-
-```bash
-JAVASCRIPTKIT_EXPERIMENTAL_BRIDGEJS=1 swift package --swift-sdk $SWIFT_SDK_ID js -c release
-```
-
-## Running Benchmarks
-
-```bash
-# Run with default settings
-node run.js
-
-# Save results to a JSON file
-node run.js --output=results.json
-
-# Specify number of iterations
-node run.js --runs=20
-
-# Run in adaptive mode until results stabilize
-node run.js --adaptive --output=stable-results.json
-
-# Run benchmarks and compare with previous results
-node run.js --baseline=previous-results.json
-```
diff --git a/Benchmarks/Sources/Benchmarks.swift b/Benchmarks/Sources/Benchmarks.swift
deleted file mode 100644
index 602aa843c..000000000
--- a/Benchmarks/Sources/Benchmarks.swift
+++ /dev/null
@@ -1,78 +0,0 @@
-import JavaScriptKit
-
-class Benchmark {
- init(_ title: String) {
- self.title = title
- }
-
- let title: String
-
- func testSuite(_ name: String, _ body: @escaping () -> Void) {
- let jsBody = JSClosure { arguments -> JSValue in
- body()
- return .undefined
- }
- benchmarkRunner("\(title)/\(name)", jsBody)
- }
-}
-
-@JS func run() {
-
- let call = Benchmark("Call")
-
- call.testSuite("JavaScript function call through Wasm import") {
- for _ in 0..<20_000_000 {
- benchmarkHelperNoop()
- }
- }
-
- call.testSuite("JavaScript function call through Wasm import with int") {
- for _ in 0..<10_000_000 {
- benchmarkHelperNoopWithNumber(42)
- }
- }
-
- let propertyAccess = Benchmark("Property access")
-
- do {
- let swiftInt: Double = 42
- let object = JSObject()
- object.jsNumber = JSValue.number(swiftInt)
- propertyAccess.testSuite("Write Number") {
- for _ in 0..<1_000_000 {
- object.jsNumber = JSValue.number(swiftInt)
- }
- }
- }
-
- do {
- let object = JSObject()
- object.jsNumber = JSValue.number(42)
- propertyAccess.testSuite("Read Number") {
- for _ in 0..<1_000_000 {
- _ = object.jsNumber.number
- }
- }
- }
-
- do {
- let swiftString = "Hello, world"
- let object = JSObject()
- object.jsString = swiftString.jsValue
- propertyAccess.testSuite("Write String") {
- for _ in 0..<1_000_000 {
- object.jsString = swiftString.jsValue
- }
- }
- }
-
- do {
- let object = JSObject()
- object.jsString = JSValue.string("Hello, world")
- propertyAccess.testSuite("Read String") {
- for _ in 0..<1_000_000 {
- _ = object.jsString.string
- }
- }
- }
-}
diff --git a/Benchmarks/Sources/Generated/ExportSwift.swift b/Benchmarks/Sources/Generated/ExportSwift.swift
deleted file mode 100644
index a8745b649..000000000
--- a/Benchmarks/Sources/Generated/ExportSwift.swift
+++ /dev/null
@@ -1,15 +0,0 @@
-// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
-// DO NOT EDIT.
-//
-// To update this file, just rebuild your project or run
-// `swift package bridge-js`.
-@_extern(wasm, module: "bjs", name: "return_string")
-private func _return_string(_ ptr: UnsafePointer?, _ len: Int32)
-@_extern(wasm, module: "bjs", name: "init_memory")
-private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?)
-
-@_expose(wasm, "bjs_main")
-@_cdecl("bjs_main")
-public func _bjs_main() -> Void {
- main()
-}
\ No newline at end of file
diff --git a/Benchmarks/Sources/Generated/ImportTS.swift b/Benchmarks/Sources/Generated/ImportTS.swift
deleted file mode 100644
index 583b9ba58..000000000
--- a/Benchmarks/Sources/Generated/ImportTS.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
-// DO NOT EDIT.
-//
-// To update this file, just rebuild your project or run
-// `swift package bridge-js`.
-
-@_spi(JSObject_id) import JavaScriptKit
-
-@_extern(wasm, module: "bjs", name: "make_jsstring")
-private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32
-
-@_extern(wasm, module: "bjs", name: "init_memory_with_result")
-private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32)
-
-@_extern(wasm, module: "bjs", name: "free_jsobject")
-private func _free_jsobject(_ ptr: Int32) -> Void
-
-func benchmarkHelperNoop() -> Void {
- @_extern(wasm, module: "Benchmarks", name: "bjs_benchmarkHelperNoop")
- func bjs_benchmarkHelperNoop() -> Void
- bjs_benchmarkHelperNoop()
-}
-
-func benchmarkHelperNoopWithNumber(_ n: Double) -> Void {
- @_extern(wasm, module: "Benchmarks", name: "bjs_benchmarkHelperNoopWithNumber")
- func bjs_benchmarkHelperNoopWithNumber(_ n: Float64) -> Void
- bjs_benchmarkHelperNoopWithNumber(n)
-}
-
-func benchmarkRunner(_ name: String, _ body: JSObject) -> Void {
- @_extern(wasm, module: "Benchmarks", name: "bjs_benchmarkRunner")
- func bjs_benchmarkRunner(_ name: Int32, _ body: Int32) -> Void
- var name = name
- let nameId = name.withUTF8 { b in
- _make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
- }
- bjs_benchmarkRunner(nameId, Int32(bitPattern: body.id))
-}
\ No newline at end of file
diff --git a/Benchmarks/Sources/Generated/JavaScript/ExportSwift.json b/Benchmarks/Sources/Generated/JavaScript/ExportSwift.json
deleted file mode 100644
index 0b1b70b70..000000000
--- a/Benchmarks/Sources/Generated/JavaScript/ExportSwift.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "classes" : [
-
- ],
- "functions" : [
- {
- "abiName" : "bjs_main",
- "name" : "main",
- "parameters" : [
-
- ],
- "returnType" : {
- "void" : {
-
- }
- }
- }
- ]
-}
\ No newline at end of file
diff --git a/Benchmarks/Sources/Generated/JavaScript/ImportTS.json b/Benchmarks/Sources/Generated/JavaScript/ImportTS.json
deleted file mode 100644
index 366342bbc..000000000
--- a/Benchmarks/Sources/Generated/JavaScript/ImportTS.json
+++ /dev/null
@@ -1,67 +0,0 @@
-{
- "children" : [
- {
- "functions" : [
- {
- "name" : "benchmarkHelperNoop",
- "parameters" : [
-
- ],
- "returnType" : {
- "void" : {
-
- }
- }
- },
- {
- "name" : "benchmarkHelperNoopWithNumber",
- "parameters" : [
- {
- "name" : "n",
- "type" : {
- "double" : {
-
- }
- }
- }
- ],
- "returnType" : {
- "void" : {
-
- }
- }
- },
- {
- "name" : "benchmarkRunner",
- "parameters" : [
- {
- "name" : "name",
- "type" : {
- "string" : {
-
- }
- }
- },
- {
- "name" : "body",
- "type" : {
- "jsObject" : {
-
- }
- }
- }
- ],
- "returnType" : {
- "void" : {
-
- }
- }
- }
- ],
- "types" : [
-
- ]
- }
- ],
- "moduleName" : "Benchmarks"
-}
\ No newline at end of file
diff --git a/Benchmarks/Sources/bridge.d.ts b/Benchmarks/Sources/bridge.d.ts
deleted file mode 100644
index a9eb5d0bf..000000000
--- a/Benchmarks/Sources/bridge.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-declare function benchmarkHelperNoop(): void;
-declare function benchmarkHelperNoopWithNumber(n: number): void;
-declare function benchmarkRunner(name: string, body: (n: number) => void): void;
diff --git a/Benchmarks/package.json b/Benchmarks/package.json
deleted file mode 100644
index 5ffd9800b..000000000
--- a/Benchmarks/package.json
+++ /dev/null
@@ -1 +0,0 @@
-{ "type": "module" }
diff --git a/Benchmarks/run.js b/Benchmarks/run.js
deleted file mode 100644
index 2305373a5..000000000
--- a/Benchmarks/run.js
+++ /dev/null
@@ -1,449 +0,0 @@
-import { instantiate } from "./.build/plugins/PackageToJS/outputs/Package/instantiate.js"
-import { defaultNodeSetup } from "./.build/plugins/PackageToJS/outputs/Package/platforms/node.js"
-import fs from 'fs';
-import path from 'path';
-import { parseArgs } from "util";
-
-/**
- * Update progress bar on the current line
- * @param {number} current - Current progress
- * @param {number} total - Total items
- * @param {string} label - Label for the progress bar
- * @param {number} width - Width of the progress bar
- */
-function updateProgress(current, total, label = '', width) {
- const percent = (current / total) * 100;
- const completed = Math.round(width * (percent / 100));
- const remaining = width - completed;
- const bar = '█'.repeat(completed) + '░'.repeat(remaining);
- process.stdout.clearLine();
- process.stdout.cursorTo(0);
- process.stdout.write(`${label} [${bar}] ${current}/${total}`);
-}
-
-/**
- * Calculate coefficient of variation (relative standard deviation)
- * @param {Array} values - Array of measurement values
- * @returns {number} Coefficient of variation as a percentage
- */
-function calculateCV(values) {
- if (values.length < 2) return 0;
-
- const sum = values.reduce((a, b) => a + b, 0);
- const mean = sum / values.length;
-
- if (mean === 0) return 0;
-
- const variance = values.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / values.length;
- const stdDev = Math.sqrt(variance);
-
- return (stdDev / mean) * 100; // Return as percentage
-}
-
-/**
- * Calculate statistics from benchmark results
- * @param {Object} results - Raw benchmark results
- * @returns {Object} Formatted results with statistics
- */
-function calculateStatistics(results) {
- const formattedResults = {};
- const consoleTable = [];
-
- for (const [name, times] of Object.entries(results)) {
- const sum = times.reduce((a, b) => a + b, 0);
- const avg = sum / times.length;
- const min = Math.min(...times);
- const max = Math.max(...times);
- const variance = times.reduce((a, b) => a + Math.pow(b - avg, 2), 0) / times.length;
- const stdDev = Math.sqrt(variance);
- const cv = (stdDev / avg) * 100; // Coefficient of variation as percentage
-
- formattedResults[name] = {
- "avg_ms": parseFloat(avg.toFixed(2)),
- "min_ms": parseFloat(min.toFixed(2)),
- "max_ms": parseFloat(max.toFixed(2)),
- "stdDev_ms": parseFloat(stdDev.toFixed(2)),
- "cv_percent": parseFloat(cv.toFixed(2)),
- "samples": times.length,
- "rawTimes_ms": times.map(t => parseFloat(t.toFixed(2)))
- };
-
- consoleTable.push({
- Test: name,
- 'Avg (ms)': avg.toFixed(2),
- 'Min (ms)': min.toFixed(2),
- 'Max (ms)': max.toFixed(2),
- 'StdDev (ms)': stdDev.toFixed(2),
- 'CV (%)': cv.toFixed(2),
- 'Samples': times.length
- });
- }
-
- return { formattedResults, consoleTable };
-}
-
-/**
- * Load a JSON file
- * @param {string} filePath - Path to the JSON file
- * @returns {Object|null} Parsed JSON or null if file doesn't exist
- */
-function loadJsonFile(filePath) {
- try {
- if (fs.existsSync(filePath)) {
- const fileContent = fs.readFileSync(filePath, 'utf8');
- return JSON.parse(fileContent);
- }
- } catch (error) {
- console.error(`Error loading JSON file ${filePath}:`, error.message);
- }
- return null;
-}
-
-/**
- * Compare current results with baseline
- * @param {Object} current - Current benchmark results
- * @param {Object} baseline - Baseline benchmark results
- * @returns {Object} Comparison results with percent change
- */
-function compareWithBaseline(current, baseline) {
- const comparisonTable = [];
-
- // Get all unique test names from both current and baseline
- const allTests = new Set([
- ...Object.keys(current),
- ...Object.keys(baseline)
- ]);
-
- for (const test of allTests) {
- const currentTest = current[test];
- const baselineTest = baseline[test];
-
- if (!currentTest) {
- comparisonTable.push({
- Test: test,
- 'Status': 'REMOVED',
- 'Baseline (ms)': baselineTest.avg_ms.toFixed(2),
- 'Current (ms)': 'N/A',
- 'Change': 'N/A',
- 'Change (%)': 'N/A'
- });
- continue;
- }
-
- if (!baselineTest) {
- comparisonTable.push({
- Test: test,
- 'Status': 'NEW',
- 'Baseline (ms)': 'N/A',
- 'Current (ms)': currentTest.avg_ms.toFixed(2),
- 'Change': 'N/A',
- 'Change (%)': 'N/A'
- });
- continue;
- }
-
- const change = currentTest.avg_ms - baselineTest.avg_ms;
- const percentChange = (change / baselineTest.avg_ms) * 100;
-
- let status = 'NEUTRAL';
- if (percentChange < -5) status = 'FASTER';
- else if (percentChange > 5) status = 'SLOWER';
-
- comparisonTable.push({
- Test: test,
- 'Status': status,
- 'Baseline (ms)': baselineTest.avg_ms.toFixed(2),
- 'Current (ms)': currentTest.avg_ms.toFixed(2),
- 'Change': (0 < change ? '+' : '') + change.toFixed(2) + ' ms',
- 'Change (%)': (0 < percentChange ? '+' : '') + percentChange.toFixed(2) + '%'
- });
- }
-
- return comparisonTable;
-}
-
-/**
- * Format and print comparison results
- * @param {Array} comparisonTable - Comparison results
- */
-function printComparisonResults(comparisonTable) {
- console.log("\n==============================");
- console.log(" COMPARISON WITH BASELINE ");
- console.log("==============================\n");
-
- // Color code the output if terminal supports it
- const colorize = (text, status) => {
- if (process.stdout.isTTY) {
- if (status === 'FASTER') return `\x1b[32m${text}\x1b[0m`; // Green
- if (status === 'SLOWER') return `\x1b[31m${text}\x1b[0m`; // Red
- if (status === 'NEW') return `\x1b[36m${text}\x1b[0m`; // Cyan
- if (status === 'REMOVED') return `\x1b[33m${text}\x1b[0m`; // Yellow
- }
- return text;
- };
-
- // Manually format table for better control over colors
- const columnWidths = {
- Test: Math.max(4, ...comparisonTable.map(row => row.Test.length)),
- Status: 8,
- Baseline: 15,
- Current: 15,
- Change: 15,
- PercentChange: 15
- };
-
- // Print header
- console.log(
- 'Test'.padEnd(columnWidths.Test) + ' | ' +
- 'Status'.padEnd(columnWidths.Status) + ' | ' +
- 'Baseline (ms)'.padEnd(columnWidths.Baseline) + ' | ' +
- 'Current (ms)'.padEnd(columnWidths.Current) + ' | ' +
- 'Change'.padEnd(columnWidths.Change) + ' | ' +
- 'Change (%)'
- );
-
- console.log('-'.repeat(columnWidths.Test + columnWidths.Status + columnWidths.Baseline +
- columnWidths.Current + columnWidths.Change + columnWidths.PercentChange + 10));
-
- // Print rows
- for (const row of comparisonTable) {
- console.log(
- row.Test.padEnd(columnWidths.Test) + ' | ' +
- colorize(row.Status.padEnd(columnWidths.Status), row.Status) + ' | ' +
- row['Baseline (ms)'].toString().padEnd(columnWidths.Baseline) + ' | ' +
- row['Current (ms)'].toString().padEnd(columnWidths.Current) + ' | ' +
- colorize(row.Change.padEnd(columnWidths.Change), row.Status) + ' | ' +
- colorize(row['Change (%)'].padEnd(columnWidths.PercentChange), row.Status)
- );
- }
-}
-
-/**
- * Save results to JSON file
- * @param {string} filePath - Output file path
- * @param {Object} data - Data to save
- */
-function saveJsonResults(filePath, data) {
- const outputDir = path.dirname(filePath);
- if (outputDir !== '.' && !fs.existsSync(outputDir)) {
- fs.mkdirSync(outputDir, { recursive: true });
- }
-
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2));
- console.log(`\nDetailed results saved to ${filePath}`);
-}
-
-/**
- * Run a single benchmark iteration
- * @param {Object} results - Results object to store benchmark data
- * @returns {Promise}
- */
-async function singleRun(results) {
- const options = await defaultNodeSetup({})
- const { exports } = await instantiate({
- ...options,
- imports: {
- benchmarkHelperNoop: () => { },
- benchmarkHelperNoopWithNumber: (n) => { },
- benchmarkRunner: (name, body) => {
- const startTime = performance.now();
- body();
- const endTime = performance.now();
- const duration = endTime - startTime;
- if (!results[name]) {
- results[name] = []
- }
- results[name].push(duration)
- }
- }
- });
- exports.run();
-}
-
-/**
- * Run until the coefficient of variation of measurements is below the threshold
- * @param {Object} results - Benchmark results object
- * @param {Object} options - Adaptive sampling options
- * @returns {Promise}
- */
-async function runUntilStable(results, options, width) {
- const {
- minRuns = 5,
- maxRuns = 50,
- targetCV = 5,
- } = options;
-
- let runs = 0;
- let allStable = false;
-
- console.log("\nAdaptive sampling enabled:");
- console.log(`- Minimum runs: ${minRuns}`);
- console.log(`- Maximum runs: ${maxRuns}`);
- console.log(`- Target CV: ${targetCV}%`);
-
- while (runs < maxRuns) {
- // Update progress with estimated completion
- updateProgress(runs, maxRuns, "Benchmark Progress:", width);
-
- await singleRun(results);
- runs++;
-
- // Check if we've reached minimum runs
- if (runs < minRuns) continue;
-
- // Check stability of all tests after each run
- const cvs = [];
- allStable = true;
-
- for (const [name, times] of Object.entries(results)) {
- const cv = calculateCV(times);
- cvs.push({ name, cv });
-
- if (cv > targetCV) {
- allStable = false;
- }
- }
-
- // Display current CV values periodically
- if (runs % 3 === 0 || allStable) {
- process.stdout.write("\n");
- console.log(`After ${runs} runs, coefficient of variation (%):`)
- for (const { name, cv } of cvs) {
- const stable = cv <= targetCV;
- const status = stable ? '✓' : '…';
- const cvStr = cv.toFixed(2) + '%';
- console.log(` ${status} ${name}: ${stable ? '\x1b[32m' : ''}${cvStr}${stable ? '\x1b[0m' : ''}`);
- }
- }
-
- // Check if we should stop
- if (allStable) {
- console.log("\nAll benchmarks stable! Stopping adaptive sampling.");
- break;
- }
- }
-
- updateProgress(maxRuns, maxRuns, "Benchmark Progress:", width);
- console.log("\n");
-
- if (!allStable) {
- console.log("\nWarning: Not all benchmarks reached target stability!");
- for (const [name, times] of Object.entries(results)) {
- const cv = calculateCV(times);
- if (cv > targetCV) {
- console.log(` ! ${name}: ${cv.toFixed(2)}% > ${targetCV}%`);
- }
- }
- }
-}
-
-function showHelp() {
- console.log(`
-Usage: node run.js [options]
-
-Options:
- --runs=NUMBER Number of benchmark runs (default: 10)
- --output=FILENAME Save JSON results to specified file
- --baseline=FILENAME Compare results with baseline JSON file
- --adaptive Enable adaptive sampling (run until stable)
- --min-runs=NUMBER Minimum runs for adaptive sampling (default: 5)
- --max-runs=NUMBER Maximum runs for adaptive sampling (default: 50)
- --target-cv=NUMBER Target coefficient of variation % (default: 5)
- --help Show this help message
-`);
-}
-
-async function main() {
- const args = parseArgs({
- options: {
- runs: { type: 'string', default: '10' },
- output: { type: 'string' },
- baseline: { type: 'string' },
- help: { type: 'boolean', default: false },
- adaptive: { type: 'boolean', default: false },
- 'min-runs': { type: 'string', default: '5' },
- 'max-runs': { type: 'string', default: '50' },
- 'target-cv': { type: 'string', default: '5' }
- }
- });
-
- if (args.values.help) {
- showHelp();
- return;
- }
-
- const results = {};
- const width = 30;
-
- if (args.values.adaptive) {
- // Adaptive sampling mode
- const options = {
- minRuns: parseInt(args.values['min-runs'], 10),
- maxRuns: parseInt(args.values['max-runs'], 10),
- targetCV: parseFloat(args.values['target-cv'])
- };
-
- console.log("Starting benchmark with adaptive sampling...");
- if (args.values.output) {
- console.log(`Results will be saved to: ${args.values.output}`);
- }
-
- await runUntilStable(results, options, width);
- } else {
- // Fixed number of runs mode
- const runs = parseInt(args.values.runs, 10);
- if (isNaN(runs)) {
- console.error('Invalid number of runs:', args.values.runs);
- process.exit(1);
- }
-
- console.log(`Starting benchmark suite with ${runs} runs per test...`);
- if (args.values.output) {
- console.log(`Results will be saved to: ${args.values.output}`);
- }
-
- if (args.values.baseline) {
- console.log(`Will compare with baseline: ${args.values.baseline}`);
- }
-
- // Show overall progress
- console.log("\nOverall Progress:");
- for (let i = 0; i < runs; i++) {
- updateProgress(i, runs, "Benchmark Runs:", width);
- await singleRun(results);
- }
- updateProgress(runs, runs, "Benchmark Runs:", width);
- console.log("\n");
- }
-
- // Calculate and display statistics
- console.log("\n==============================");
- console.log(" BENCHMARK SUMMARY ");
- console.log("==============================\n");
-
- const { formattedResults, consoleTable } = calculateStatistics(results);
-
- // Print readable format to console
- console.table(consoleTable);
-
- // Compare with baseline if provided
- if (args.values.baseline) {
- const baseline = loadJsonFile(args.values.baseline);
- if (baseline) {
- const comparisonResults = compareWithBaseline(formattedResults, baseline);
- printComparisonResults(comparisonResults);
- } else {
- console.error(`Could not load baseline file: ${args.values.baseline}`);
- }
- }
-
- // Save JSON to file if specified
- if (args.values.output) {
- saveJsonResults(args.values.output, formattedResults);
- }
-}
-
-main().catch(err => {
- console.error('Benchmark error:', err);
- process.exit(1);
-});
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 9e9e0bd6f..000000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,465 +0,0 @@
-> [!IMPORTANT]
-> For future releases, please refer to the [GitHub releases page](https://github.com/swiftwasm/JavaScriptKit/releases)
-
-----
-
-# 0.20.0 (11 July 2024)
-
-This release adds an initial multi-threading support.
-
-## What's Changed
-* Start migrating imported functions to the new definition style by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/252
-* Allocate JavaScriptEventLoop per thread in multi-threaded environment by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/255
-* Add `WebWorkerTaskExecutor` by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/256
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.19.3...0.20.0
-
-# 0.19.3 (6 Jun 2024)
-
-## What's Changed
-* Fix `JSClosure` leak by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/240
-* Update README file to include new carton 1.0 implementation. by @kuhl in https://github.com/swiftwasm/JavaScriptKit/pull/243
-* Update Carton context on README. by @kuhl in https://github.com/swiftwasm/JavaScriptKit/pull/245
-* Support latest nightly snapshot by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/246
-* Use Swift SDK for development snapshot testing in CI by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/248
-* Add `sharedMemory` option to allow threads with shared memory by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/247
-* Check 5.10 toolchain in CI by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/249
-
-## New Contributors
-* @kuhl made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/243
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.19.2...0.19.3
-
-# 0.19.2 (11 Apr 2024)
-
-## What's Changed
-* [CI] macos-14 by @ikesyo in https://github.com/swiftwasm/JavaScriptKit/pull/233
-* [CI] Drop macos-11 since that is deprecated and will be removed in Q2 2024 by @ikesyo in https://github.com/swiftwasm/JavaScriptKit/pull/234
-* Update swift-tools-version to reflect the supported Swift versions by @ikesyo in https://github.com/swiftwasm/JavaScriptKit/pull/235
-* [CI] Update actions and configure Dependabot by @ikesyo in https://github.com/swiftwasm/JavaScriptKit/pull/236
-* Fix Optional implementation for ConstructibleFromJSValue by @omochi in https://github.com/swiftwasm/JavaScriptKit/pull/238
-* Inherit JSFunction from JSClosure by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/239
-* Fix object decode by @omochi in https://github.com/swiftwasm/JavaScriptKit/pull/241
-
-## New Contributors
-* @ikesyo made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/233
-* @omochi made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/238
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.19.1...0.19.2
-
-# 0.19.1 (6 Feb 2024)
-
-## What's Changed
-* Fix availability marker for Swift 5.9 compiler targeting host machine by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/232
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.19.0...0.19.1
-
-
-# 0.19.0 (16 Jan 2024)
-
-## What's Changed
-* Update 5.7 patch version by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/226
-* Add 5.8 toolchain matrix by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/227
-* Fix warnings Aug 5, 2023 by @STREGA in https://github.com/swiftwasm/JavaScriptKit/pull/228
-* Swift 5.9 Changes by @STREGA in https://github.com/swiftwasm/JavaScriptKit/pull/229
-
-## New Contributors
-* @STREGA made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/228
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.18.0...0.19.0
-
-
-# 0.18.0 (13 Mar 2023)
-
-## What's Changed
-* Use swiftwasm/setup-swiftwasm instead of swiftenv on CI by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/215
-* Support Clock-based sleep APIs by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/216
-* Prefer `UInt(bitPattern:)` for object id to guarantee uniqueness by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/219
-* Fix wrong markdown in documentation by @gibachan in https://github.com/swiftwasm/JavaScriptKit/pull/221
-* Add `withUnsafeBytesAsync` function to `JSTypedArray` by @fjtrujy in https://github.com/swiftwasm/JavaScriptKit/pull/222
-* Trivial fixes to JSTypedArray by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/223
-
-## New Contributors
-* @gibachan made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/221
-* @fjtrujy made their first contribution in https://github.com/swiftwasm/JavaScriptKit/pull/222
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.17.0...0.18.0
-
-
-# 0.17.0 (4 Oct 2022)
-
-This release introduces testing support module, minor API enhancements for `JavaScriptEventLoop`.
-
-Linking the new `JavaScriptEventLoopTestSupport` module automatically activates JS event loop based global executor.
-This automatic activation is just for XCTest integration since XCTest with SwiftPM doesn't allow to call `JavaScriptEventLoop.installGlobalExecutor()` at first.
-
-## What's Changed
-
-* Bump @actions/core from 1.2.6 to 1.9.1 in /ci/perf-tester by @dependabot in https://github.com/swiftwasm/JavaScriptKit/pull/209
-* Remove baseline tests (e.g. “Call JavaScript function directly”) from comparison by @j-f1 in https://github.com/swiftwasm/JavaScriptKit/pull/211
-* Add 5.7 toolchain matrix by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/210
-* Add JavaScriptEventLoopTestSupport module to install executor by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/213
-* Expose `JavaScriptEventLoop.queueMicrotask` and `.setTimeout` by @kateinoigakukun in https://github.com/swiftwasm/JavaScriptKit/pull/214
-
-
-**Full Changelog**: https://github.com/swiftwasm/JavaScriptKit/compare/0.16.0...0.17.0
-
-# 0.16.0 (22 Aug 2022)
-
-This release contains significant performance improvements, API enhancements for `JSPromise` / `JSBigInt` / `JSClosure`, and documentation improvements.
-
-**Merged pull requests:**
-
-- Runtime Performance Optimization ([#207](https://github.com/swiftwasm/JavaScriptKit/pull/207)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Add missing doc comments for more types ([#208](https://github.com/swiftwasm/JavaScriptKit/pull/208)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Add Int64/UInt64 to Bigint slow conversion ([#204](https://github.com/swiftwasm/JavaScriptKit/pull/204)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Test native builds with Xcode 14.0 ([#206](https://github.com/swiftwasm/JavaScriptKit/pull/206)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Support DocC generation in Swift Package Index ([#205](https://github.com/swiftwasm/JavaScriptKit/pull/205)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Refine benchmark suite ([#203](https://github.com/swiftwasm/JavaScriptKit/pull/203)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Add diagnostics for those who build with WASI command line ABI ([#202](https://github.com/swiftwasm/JavaScriptKit/pull/202)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Bump terser from 5.10.0 to 5.14.2 in /Example ([#201](https://github.com/swiftwasm/JavaScriptKit/pull/201)) via [@dependabot[bot]](https://github.com/dependabot[bot])
-- Test with uwasi implementation ([#198](https://github.com/swiftwasm/JavaScriptKit/pull/198)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Add async JSPromise.result property ([#200](https://github.com/swiftwasm/JavaScriptKit/pull/200)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Asynchronous calls in JSClosure ([#157](https://github.com/swiftwasm/JavaScriptKit/issues/157)) via [@j-f1](https://github.com/j-f1)
-- JSPromise(resolver:) usage ([#156](https://github.com/swiftwasm/JavaScriptKit/issues/156)) via [@j-f1](https://github.com/j-f1)
-
-
-# 0.15.0 (17 May 2022)
-
-This is a major release that adds new features and fixes issues. Specifically:
-* `BigInt` and `BigInt`-based `JSTypedArray` types are now supported. Now, when passing `Int64` values from Swift,
-they will be mapped to `BigInt` values on the JavaScript side.
-* The `constructor` property on `JSBridgedClass` is now an Optional, which allows bridging JavaScript classes that aren't
-available in every browser or environment.
-* JavaScriptKit runtime files are now supplied as SwiftPM resources. This allows us to resolve a long-standing issue
-in `carton` that could lead to a version mismatch between JavaScriptKit dependency in `Package.swift` or
-`Package.resolved` and carton’s bundled JavaScriptKit runtime version.
-* The `JSSymbol` type has been added, enabling support for [JavaScript `Symbol` values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol), including accessing `Symbol`-keyed properties on objects.
-
-**Source breaking changes**
-
-`UInt64.jsValue` and `Int64.jsValue`, which are a part of `JavaScriptKit` module, have been moved into `JavaScriptBigIntSupport` module since their implementation changed to require [JS-BigInt-integration](https://github.com/WebAssembly/JS-BigInt-integration) to avoid implicit casts from 64-bit integer to JS number type.
-
-If you want to keep the behavior so far, please cast the 64-bit integer values to `Double`.
-
-**Merged pull requests:**
-
-- Improve JSKit diagnostics for use-after-free of JSClosure ([#195](https://github.com/swiftwasm/JavaScriptKit/pull/195)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Gracefully handle unavailable `JSBridgedClass` ([#190](https://github.com/swiftwasm/JavaScriptKit/pull/190)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Supply JSKit runtime in SwiftPM resources ([#193](https://github.com/swiftwasm/JavaScriptKit/pull/193)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Test with Node.js's WASI implementation ([#192](https://github.com/swiftwasm/JavaScriptKit/pull/192)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Add support for BigInts and BigInt-based TypedArrays ([#184](https://github.com/swiftwasm/JavaScriptKit/pull/184)) via [@j-f1](https://github.com/j-f1)
-- Update toolchain references to 5.6.0 in `README.md` ([#189](https://github.com/swiftwasm/JavaScriptKit/pull/189)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Bump async from 2.6.3 to 2.6.4 in /Example ([#188](https://github.com/swiftwasm/JavaScriptKit/pull/188)) via [@dependabot[bot]](https://github.com/dependabot[bot])
-- Remove outdated `BigInt` support `FIXME` from `JSTypedArray` ([#187](https://github.com/swiftwasm/JavaScriptKit/pull/187)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Cleanup & improvements to perf-tester ([#186](https://github.com/swiftwasm/JavaScriptKit/pull/186)) via [@j-f1](https://github.com/j-f1)
-- Re-add support for Symbol objects via JSSymbol ([#183](https://github.com/swiftwasm/JavaScriptKit/pull/183)) via [@j-f1](https://github.com/j-f1)
-- Fix JSValueDecoder ([#185](https://github.com/swiftwasm/JavaScriptKit/pull/185)) via [@j-f1](https://github.com/j-f1)
-- Fix deprecation warning in `JSFunction.swift` ([#182](https://github.com/swiftwasm/JavaScriptKit/pull/182)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-
-# 0.14.0 (8 April 2022)
-
-This is a breaking release that enables full support for SwiftWasm 5.6 and lays groundwork for future updates to [DOMKit](https://github.com/swiftwasm/DOMKit/).
-
-- The `ConvertibleToJSValue` conformance on `Array` and `Dictionary` has been swapped from the `== ConvertibleToJSValue` case to the `: ConvertibleToJSValue` case.
- - This means that e.g. `[String]` is now `ConvertibleToJSValue`, but `[ConvertibleToJSValue]` no longer conforms;
- - the `jsValue()` method still works in both cases;
- - to adapt existing code, use one of these approaches:
- - use generics where possible (for single-type arrays)
- - call `.map { $0.jsValue() }` (or `mapValues`) to get an array/dictionary of `JSValue` which you can then use as `ConvertibleToJSValue`
- - add `.jsValue` to the end of all of the values in the array/dictionary literal.
-
-**Merged pull requests:**
-
-- Reenable integration tests ([#180](https://github.com/swiftwasm/JavaScriptKit/pull/180)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Updates for DOMKit ([#174](https://github.com/swiftwasm/JavaScriptKit/pull/174)) via [@j-f1](https://github.com/j-f1)
-- Add 5.6 release and macOS 12 with Xcode 13.3 to CI matrix ([#176](https://github.com/swiftwasm/JavaScriptKit/pull/176)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-
-# 0.13.0 (31 March 2022)
-
-This release improves handling of JavaScript exceptions and compatibility with Xcode.
-
-Thanks to [@kateinoigakukun](https://github.com/kateinoigakukun), [@pedrovgs](https://github.com/pedrovgs), and
-[@valeriyvan](https://github.com/valeriyvan) for contributions!
-
-**Closed issues:**
-
-- UserAgent support? ([#169](https://github.com/swiftwasm/JavaScriptKit/issues/169))
-- Compile error on macOS 12.2.1 ([#167](https://github.com/swiftwasm/JavaScriptKit/issues/167))
-
-**Merged pull requests:**
-
-- Improve error messages when JS code throws exceptions ([#173](https://github.com/swiftwasm/JavaScriptKit/pull/173)) via [@pedrovgs](https://github.com/pedrovgs)
-- Update npm dependencies ([#175](https://github.com/swiftwasm/JavaScriptKit/pull/175)) via [@MaxDesiatov](https://github.com/MaxDesiatov)
-- Bump minimist from 1.2.5 to 1.2.6 in /Example ([#172](https://github.com/swiftwasm/JavaScriptKit/pull/172)) via [@dependabot[bot]](https://github.com/dependabot[bot])
-- Use availability guarded APIs under @available for Xcode development ([#171](https://github.com/swiftwasm/JavaScriptKit/pull/171)) via [@kateinoigakukun](https://github.com/kateinoigakukun)
-- Fix warning in snippet ([#166](https://github.com/swiftwasm/JavaScriptKit/pull/166)) via [@valeriyvan](https://github.com/valeriyvan)
-- Bump follow-redirects from 1.14.5 to 1.14.8 in /Example ([#165](https://github.com/swiftwasm/JavaScriptKit/pull/165)) via [@dependabot[bot]](https://github.com/dependabot[bot])
-
-# 0.12.0 (08 February 2022)
-
-This release introduces a [major refactor](https://github.com/swiftwasm/JavaScriptKit/pull/150) of the JavaScript runtime by [@j-f1] and several performance enhancements.
-
-**Merged pull requests:**
-
-- Add Hashable conformance to JSObject ([#162](https://github.com/swiftwasm/JavaScriptKit/pull/162)) via [@yonihemi]
-- Add test for detached ArrayBuffer ([#154](https://github.com/swiftwasm/JavaScriptKit/pull/154)) via [@yonihemi]
-- Fix detached ArrayBuffer errors ([#153](https://github.com/swiftwasm/JavaScriptKit/pull/153)) via [@yonihemi]
-- Split runtime into multiple files ([#150](https://github.com/swiftwasm/JavaScriptKit/pull/150)) via [@j-f1]
-- Add a way for Swift code to access raw contents of a Typed Array ([#151](https://github.com/swiftwasm/JavaScriptKit/pull/151)) via [@yonihemi]
-- Prevent installGlobalExecutor() from running more than once ([#152](https://github.com/swiftwasm/JavaScriptKit/pull/152)) via [@yonihemi]
-- Return from runtime functions instead of taking a pointer where possible ([#147](https://github.com/swiftwasm/JavaScriptKit/pull/147)) via [@j-f1]
-- Use TypedArray.set to copy a bunch of bytes ([#146](https://github.com/swiftwasm/JavaScriptKit/pull/146)) via [@kateinoigakukun]
-
-# 0.11.1 (22 November 2021)
-
-This is a bugfix release that removes a requirement for macOS Monterey in `Package.swift` for this
-package. `README.md` was updated to explicitly specify that if you're building an app or a library
-that depends on JavaScriptKit for macOS (i.e. cross-platform code that supports both WebAssembly
-and macOS), you need either
-
-- macOS Monterey that has the new Swift concurrency runtime available, or
-- any version of macOS that supports Swift concurrency back-deployment with Xcode 13.2 or later, or
-- add `.unsafeFlags(["-Xfrontend", "-disable-availability-checking"])` in `Package.swift` manifest.
-
-**Merged pull requests:**
-
-- Remove macOS Monterey requirement from `Package.swift` ([#144](https://github.com/swiftwasm/JavaScriptKit/pull/144)) via [@MaxDesiatov]
-
-# 0.11.0 (22 November 2021)
-
-This release adds support for `async`/`await` and SwiftWasm 5.5. Use the new `value` async property
-on a `JSPromise` instance to `await` for its result. You'll have to add a dependency on the new
-`JavaScriptEventLoop` target in your `Package.swift`, `import JavaScriptEventLoop`, and call
-`JavaScriptEventLoop.installGlobalExecutor()` in your code before you start using `await` and `Task`
-APIs.
-
-Additionally, manual memory management API of `JSClosure` has been removed to improve usability.
-This significantly bumps minimum browser version requirements for users of apps depending on
-JavaScriptKit. Previous manual memory management mode is still available though with a special
-compiler flags, see [`README.md`](./README.md) for more details.
-
-This new release of JavaScriptKit may work with SwiftWasm 5.4 and 5.3, but is no longer tested with
-those versions due to compatibility issues introduced on macOS by latest versions of Xcode.
-
-Many thanks to [@j-f1], [@kateinoigakukun],
-and [@PatrickPijnappel] for their contributions to this release!
-
-**Closed issues:**
-
-- Enchancement: Add a link to the docs ([#136](https://github.com/swiftwasm/JavaScriptKit/issues/136))
-- Use `FinalizationRegistry` to auto-deinit `JSClosure` ([#131](https://github.com/swiftwasm/JavaScriptKit/issues/131))
-- `make test` crashes due to `JSClosure` memory issues ([#129](https://github.com/swiftwasm/JavaScriptKit/issues/129))
-- Avoid manual memory management with `JSClosure` ([#106](https://github.com/swiftwasm/JavaScriptKit/issues/106))
-
-**Merged pull requests:**
-
-- Fix recursion in `JSTypedArray` initializer ([#142](https://github.com/swiftwasm/JavaScriptKit/pull/142)) via [@PatrickPijnappel]
-- Experimental global executor cooperating with JS event loop ([#141](https://github.com/swiftwasm/JavaScriptKit/pull/141)) via [@kateinoigakukun]
-- Update NPM dependencies of `Example` project ([#140](https://github.com/swiftwasm/JavaScriptKit/pull/140)) via [@MaxDesiatov]
-- Refactor `JSClosure` to leverage `FinalizationRegistry` ([#128](https://github.com/swiftwasm/JavaScriptKit/pull/128)) via [@j-f1]
-- Test with the latest 5.5 snapshot ([#138](https://github.com/swiftwasm/JavaScriptKit/pull/138)) via [@MaxDesiatov]
-- Test with multiple toolchain versions ([#135](https://github.com/swiftwasm/JavaScriptKit/pull/135)) via [@kateinoigakukun]
-- Gardening tests ([#133](https://github.com/swiftwasm/JavaScriptKit/pull/133)) via [@kateinoigakukun]
-
-# 0.10.1 (29 April 2021)
-
-This is a minor patch release that includes updates to our dependencies and minor documentation
-tweaks.
-
-**Closed issues:**
-
-- Do you accept contributions for wrappers over JavaScript objects? ([#124](https://github.com/swiftwasm/JavaScriptKit/issues/124))
-- Can't read from a file using `JSPromise` ([#121](https://github.com/swiftwasm/JavaScriptKit/issues/121))
-- TypeError when trying to implement a `JSBridgedClass` for `WebSocket.send` ([#120](https://github.com/swiftwasm/JavaScriptKit/issues/120))
-
-**Merged pull requests:**
-
-- Update JS dependencies in package-lock.json ([#126](https://github.com/swiftwasm/JavaScriptKit/pull/126)) via [@MaxDesiatov]
-- Fix typo in method documentation ([#125](https://github.com/swiftwasm/JavaScriptKit/pull/125)) via [@revolter]
-- Update exported func name to match exported name ([#123](https://github.com/swiftwasm/JavaScriptKit/pull/123)) via [@kateinoigakukun]
-- Fix incorrect link in `JSDate` documentation ([#122](https://github.com/swiftwasm/JavaScriptKit/pull/122)) via [@revolter]
-
-# 0.10.0 (21 January 2021)
-
-This release contains multiple breaking changes in preparation for enabling `async`/`await`, when
-this feature is available in a stable SwiftWasm release. Namely:
-
-- `JSClosure.init(_ body: @escaping ([JSValue]) -> ())` overload is deprecated to simplify type
- checking. Its presence requires explicit type signatures at the place of use. It will be removed
- in a future version of JavaScriptKit.
-- `JSClosure` is no longer a subclass of `JSFunction`. These classes are not related enough to keep
- them in the same class hierarchy.
- As a result, you can no longer call `JSClosure` objects directly from Swift.
-- Introduced `JSOneshotClosure` for closures that are going to be called only once. You don't need
- to manage references to these closures manually, as opposed to `JSClosure`.
- However, they can only be called a single time from the JS side. Subsequent invocation attempts will raise a fatal error on the Swift side.
-- Removed generic parameters on `JSPromise`, now both success and failure values are always assumed
- to be of `JSValue` type. This also significantly simplifies type checking and allows callers to
- fully control type casting if needed.
-
-**Closed issues:**
-
-- DOMKit? ([#21](https://github.com/swiftwasm/JavaScriptKit/issues/21))
-
-**Merged pull requests:**
-
-- Simplify `JSPromise` API ([#115](https://github.com/swiftwasm/JavaScriptKit/pull/115)) via [@kateinoigakukun]
-- Create `FUNDING.yml` ([#117](https://github.com/swiftwasm/JavaScriptKit/pull/117)) via [@MaxDesiatov]
-- Major API change on `JSClosure` ([#113](https://github.com/swiftwasm/JavaScriptKit/pull/113)) via [@kateinoigakukun]
-- Update `package.json` to lockfileVersion 2 ([#114](https://github.com/swiftwasm/JavaScriptKit/pull/114)) via [@kateinoigakukun]
-- Bump `ini` from 1.3.5 to 1.3.8 in `/Example` ([#111](https://github.com/swiftwasm/JavaScriptKit/pull/111)) via [@dependabot]
-- Update doc comment in `JSTypedArray.swift` ([#110](https://github.com/swiftwasm/JavaScriptKit/pull/110)) via [@MaxDesiatov]
-
-# 0.9.0 (27 November 2020)
-
-This release introduces support for catching `JSError` instances in Swift from throwing JavaScript
-functions. This is possible thanks to the new `JSThrowingFunction` and `JSThrowingObject` classes.
-The former can only be called with `try`, while the latter will expose all of its member functions
-as throwing. Use the new `throws` property on `JSFunction` to convert it to `JSThrowingFunction`,
-and the new `throwing` property on `JSObject` to convert it to `JSThrowingObject`.
-
-**Closed issues:**
-
-- Support JS errors ([#37](https://github.com/swiftwasm/JavaScriptKit/issues/37))
-
-**Merged pull requests:**
-
-- Update toolchain version swift-wasm-5.3.0-RELEASE ([#108](https://github.com/swiftwasm/JavaScriptKit/pull/108)) via [@kateinoigakukun]
-- Update ci trigger condition ([#104](https://github.com/swiftwasm/JavaScriptKit/pull/104)) via [@kateinoigakukun]
-- Fix branch and triple in `compatibility.yml` ([#105](https://github.com/swiftwasm/JavaScriptKit/pull/105)) via [@MaxDesiatov]
-- Check source code compatibility ([#103](https://github.com/swiftwasm/JavaScriptKit/pull/103)) via [@kateinoigakukun]
-- JS Exception Support ([#102](https://github.com/swiftwasm/JavaScriptKit/pull/102)) via [@kateinoigakukun]
-- Mention `carton` Docker image and refine wording in `README.md` ([#101](https://github.com/swiftwasm/JavaScriptKit/pull/101)) via [@MaxDesiatov]
-
-# 0.8.0 (21 October 2020)
-
-This release introduces a few enhancements and deprecations. Namely, `JSValueConstructible`
-and `JSValueConvertible` were renamed to `ConstructibleFromJSValue` and `ConvertibleToJSValue`
-respectively. The old names are deprecated, and you should move away from using the old names in
-your code. Additionally, JavaScriptKit now requires the most recent 5.3 and development toolchains,
-but thanks to this it no longer uses unsafe flags, which prevented building other libraries
-depending on JavaScriptKit on other platforms.
-
-The main user-visible enhancement is that now force casts are no longer required in client code.
-That is, we now allow this
-
-```swift
-let document = JSObject.global.document
-let foundDivs = document.getElementsByTagName("div")
-```
-
-in addition to the previously available explicit style with force unwrapping:
-
-```swift
-let document = JSObject.global.document.object!
-let foundDivs = document.getElementsByTagName!("div").object!
-```
-
-Note that the code in the first example is still dynamically typed. The Swift compiler won't warn
-you if you misspell names of properties or cast them to a wrong type. This feature is purely
-additive, and is added for convenience. You can still use force unwraps in your code interfacing
-with JavaScriptKit. If you're interested in a statically-typed DOM API, we recommend having a look
-at the [DOMKit](https://github.com/swiftwasm/DOMKit) library, which is currently in development.
-
-Lastly, `JSError` now conforms to the `JSBridgedClass` protocol, which makes it easier to integrate
-with idiomatic Swift code.
-
-**Closed issues:**
-
-- Errors building example: undefined symbols ([#95](https://github.com/swiftwasm/JavaScriptKit/issues/95))
-- Documentation website is broken ([#93](https://github.com/swiftwasm/JavaScriptKit/issues/93))
-- Rename `JSValueConstructible` and `JSValueConvertible` ([#87](https://github.com/swiftwasm/JavaScriptKit/issues/87))
-- Build fails with the unsafe flags error ([#6](https://github.com/swiftwasm/JavaScriptKit/issues/6))
-
-**Merged pull requests:**
-
-- Update example code in `README.md` ([#100](https://github.com/swiftwasm/JavaScriptKit/pull/100)) via [@MaxDesiatov]
-- Update toolchain version, script, and `README.md` ([#96](https://github.com/swiftwasm/JavaScriptKit/pull/96)) via [@MaxDesiatov]
-- [Proposal] Add unsafe convenience methods for JSValue ([#98](https://github.com/swiftwasm/JavaScriptKit/pull/98)) via [@kateinoigakukun]
-- Remove all unsafe linker flags from Package.swift ([#91](https://github.com/swiftwasm/JavaScriptKit/pull/91)) via [@kateinoigakukun]
-- Sync package.json and package-lock.json ([#90](https://github.com/swiftwasm/JavaScriptKit/pull/90)) via [@kateinoigakukun]
-- Rename JSValueConvertible/Constructible/Codable ([#88](https://github.com/swiftwasm/JavaScriptKit/pull/88)) via [@j-f1]
-- Bump @actions/core from 1.2.2 to 1.2.6 in /ci/perf-tester ([#89](https://github.com/swiftwasm/JavaScriptKit/pull/89)) via [@dependabot]
-- Make `JSError` conform to `JSBridgedClass` ([#86](https://github.com/swiftwasm/JavaScriptKit/pull/86)) via [@MaxDesiatov]
-
-# 0.7.2 (28 September 2020)
-
-This is a bugfix release that resolves an issue with the JavaScript runtime being unavailable when installed via NPM.
-
-# 0.7.1 (27 September 2020)
-
-This is a bugfix release that resolves an issue with the JavaScript runtime being unavailable when installed via NPM.
-
-**Closed issues:**
-
-- 0.7.0 unavailable on NPM ([#79](https://github.com/swiftwasm/JavaScriptKit/issues/79))
-- Automatic performance testing ([#67](https://github.com/swiftwasm/JavaScriptKit/issues/67))
-
-**Merged pull requests:**
-
-- Fix runtime files location in `package.json` ([#81](https://github.com/swiftwasm/JavaScriptKit/pull/81)) via [@MaxDesiatov]
-- Run 4 perf tests instead of 2 ([#80](https://github.com/swiftwasm/JavaScriptKit/pull/80)) via [@j-f1]
-- Specify correct SwiftWasm snapshot in `README.md` ([#78](https://github.com/swiftwasm/JavaScriptKit/pull/78)) via [@MaxDesiatov]
-
-# 0.7.0 (25 September 2020)
-
-This release adds multiple new types bridged from JavaScript, namely `JSError`, `JSDate`, `JSTimer` (which corresponds to `setTimeout`/`setInterval` calls and manages closure lifetime for you), `JSString` and `JSPromise`. We now also have [documentation published automatically](https://swiftwasm.github.io/JavaScriptKit/) for the main branch.
-
-**Closed issues:**
-
-- `TypedArray` improvement? ([#52](https://github.com/swiftwasm/JavaScriptKit/issues/52))
-
-**Merged pull requests:**
-
-- Add a generic `JSPromise` implementation ([#62](https://github.com/swiftwasm/JavaScriptKit/pull/62)) via [@MaxDesiatov]
-- Remove payload2 from value bridging interface ([#64](https://github.com/swiftwasm/JavaScriptKit/pull/64)) via [@kateinoigakukun]
-- Update Node.js dependencies ([#65](https://github.com/swiftwasm/JavaScriptKit/pull/65)) via [@MaxDesiatov]
-- Implement `JSString` to reduce bridging overhead ([#63](https://github.com/swiftwasm/JavaScriptKit/pull/63)) via [@kateinoigakukun]
-- Add `JSBridgedType` and `JSBridgedClass` ([#26](https://github.com/swiftwasm/JavaScriptKit/pull/26)) via [@j-f1]
-- Make `JSValue` conform to `ExpressibleByNilLiteral` ([#59](https://github.com/swiftwasm/JavaScriptKit/pull/59)) via [@j-f1]
-- Remove `JavaScriptTypedArrayKind` ([#58](https://github.com/swiftwasm/JavaScriptKit/pull/58)) via [@j-f1]
-- Add doc comments for public APIs (Part 2) ([#57](https://github.com/swiftwasm/JavaScriptKit/pull/57)) via [@kateinoigakukun]
-- Add doc comments for public APIs (Part 1) ([#55](https://github.com/swiftwasm/JavaScriptKit/pull/55)) via [@kateinoigakukun]
-- Cleanup invalid test target ([#53](https://github.com/swiftwasm/JavaScriptKit/pull/53)) via [@kateinoigakukun]
-- Remove deprecated Ref suffix ([#51](https://github.com/swiftwasm/JavaScriptKit/pull/51)) via [@j-f1]
-- Rename `ref` to `jsObject` on JSDate for consistency with JSError ([#50](https://github.com/swiftwasm/JavaScriptKit/pull/50)) via [@MaxDesiatov]
-- Generate and publish documentation with `swift-doc` ([#49](https://github.com/swiftwasm/JavaScriptKit/pull/49)) via [@MaxDesiatov]
-- Add `JSTimer` implementation with tests ([#46](https://github.com/swiftwasm/JavaScriptKit/pull/46)) via [@MaxDesiatov]
-- Add `JSError.stack`, add `Error` conformance ([#48](https://github.com/swiftwasm/JavaScriptKit/pull/48)) via [@MaxDesiatov]
-- Add `JSDate` implementation with tests ([#45](https://github.com/swiftwasm/JavaScriptKit/pull/45)) via [@MaxDesiatov]
-- Add `JSError` with tests, add JSObject.description ([#47](https://github.com/swiftwasm/JavaScriptKit/pull/47)) via [@MaxDesiatov]
-
-# 0.6.0 (11 September 2020)
-
-This release adds `JSTypedArray` generic type, renames `JSObjectRef` to `JSObject`, and makes `JSClosure` memory management more explicit.
-
-**Closed issues:**
-
-- Support for JS Arrays “holes”, including the test suite ([#39](https://github.com/swiftwasm/JavaScriptKit/issues/39))
-- BigInt Support ([#29](https://github.com/swiftwasm/JavaScriptKit/issues/29))
-- Separate namespaces for methods and properties? ([#27](https://github.com/swiftwasm/JavaScriptKit/issues/27))
-
-**Merged pull requests:**
-
-- Add a helper method to copy an array of numbers to a JS TypedArray ([#31](https://github.com/swiftwasm/JavaScriptKit/pull/31)) via [@j-f1]
-- Resolve small issues ([#44](https://github.com/swiftwasm/JavaScriptKit/pull/44)) via [@kateinoigakukun]
-- Bump bl from 3.0.0 to 3.0.1 in /IntegrationTests ([#42](https://github.com/swiftwasm/JavaScriptKit/pull/42)) via [@dependabot]
-- Bump bl from 3.0.0 to 3.0.1 in /Example ([#43](https://github.com/swiftwasm/JavaScriptKit/pull/43)) via [@dependabot]
-- Support Holes in Array ([#41](https://github.com/swiftwasm/JavaScriptKit/pull/41)) via [@kateinoigakukun]
-- Refine public API ([#40](https://github.com/swiftwasm/JavaScriptKit/pull/40)) via [@kateinoigakukun]
-- Fix invalid array termination for null and undefined ([#38](https://github.com/swiftwasm/JavaScriptKit/pull/38)) via [@kateinoigakukun]
-- Add a test helper function ([#36](https://github.com/swiftwasm/JavaScriptKit/pull/36)) via [@j-f1]
-- Enable Xcode 12 with fresh SwiftWasm 5.3 snapshot ([#35](https://github.com/swiftwasm/JavaScriptKit/pull/35)) via [@MaxDesiatov]
-- Add void-returning overload to `JSClosure.init` ([#34](https://github.com/swiftwasm/JavaScriptKit/pull/34)) via [@MaxDesiatov]
-- Change `JSClosure.release` to `deinit` ([#33](https://github.com/swiftwasm/JavaScriptKit/pull/33)) via [@MaxDesiatov]
-- Clean up the `JSObjectRef` API ([#28](https://github.com/swiftwasm/JavaScriptKit/pull/28)) via [@j-f1]
-- Remove unused `Tests` directory ([#32](https://github.com/swiftwasm/JavaScriptKit/pull/32)) via [@MaxDesiatov]
-
-[@maxdesiatov]: https://github.com/MaxDesiatov
-[@j-f1]: https://github.com/j-f1
-[@kateinoigakukun]: https://github.com/kateinoigakukun
-[@yonihemi]: https://github.com/yonihemi
-[@patrickpijnappel]: https://github.com/PatrickPijnappel
-[@revolter]: https://github.com/revolter
-[@dependabot]: https://github.com/dependabot
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index f71ca83ae..000000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,85 +0,0 @@
-# Contributing to JavaScriptKit
-
-Thank you for considering contributing to JavaScriptKit! We welcome contributions of all kinds and value your time and effort.
-
-## Getting Started
-
-### Reporting Issues
-- If you find a bug, have a feature request, or need help, please [open an issue](https://github.com/swiftwasm/JavaScriptKit/issues).
-- Provide as much detail as possible:
- - Steps to reproduce the issue
- - Expected vs. actual behavior
- - Relevant error messages or logs
-
-### Setting Up the Development Environment
-1. Clone the repository:
- ```bash
- git clone https://github.com/swiftwasm/JavaScriptKit.git
- cd JavaScriptKit
- ```
-
-2. Install **OSS** Swift toolchain (not the one from Xcode):
-
- For macOS users
-
- ```bash
- (
- SWIFT_TOOLCHAIN_CHANNEL=swift-6.0.2-release;
- SWIFT_TOOLCHAIN_TAG="swift-6.0.2-RELEASE";
- SWIFT_SDK_TAG="swift-wasm-6.0.2-RELEASE";
- SWIFT_SDK_CHECKSUM="6ffedb055cb9956395d9f435d03d53ebe9f6a8d45106b979d1b7f53358e1dcb4";
- pkg="$(mktemp -d)/InstallMe.pkg"; set -ex;
- curl -o "$pkg" "https://download.swift.org/$SWIFT_TOOLCHAIN_CHANNEL/xcode/$SWIFT_TOOLCHAIN_TAG/$SWIFT_TOOLCHAIN_TAG-osx.pkg";
- installer -pkg "$pkg" -target CurrentUserHomeDirectory;
- export TOOLCHAINS="$(plutil -extract CFBundleIdentifier raw ~/Library/Developer/Toolchains/$SWIFT_TOOLCHAIN_TAG.xctoolchain/Info.plist)";
- swift sdk install "https://github.com/swiftwasm/swift/releases/download/$SWIFT_SDK_TAG/$SWIFT_SDK_TAG-wasm32-unknown-wasi.artifactbundle.zip" --checksum "$SWIFT_SDK_CHECKSUM";
- )
- ```
-
-
-
-
- For Linux users
- Install Swift 6.0.2 by following the instructions on the official Swift website.
-
- ```bash
- (
- SWIFT_SDK_TAG="swift-wasm-6.0.2-RELEASE";
- SWIFT_SDK_CHECKSUM="6ffedb055cb9956395d9f435d03d53ebe9f6a8d45106b979d1b7f53358e1dcb4";
- swift sdk install "https://github.com/swiftwasm/swift/releases/download/$SWIFT_SDK_TAG/$SWIFT_SDK_TAG-wasm32-unknown-wasi.artifactbundle.zip" --checksum "$SWIFT_SDK_CHECKSUM";
- )
- ```
-
-
-
-3. Install dependencies:
- ```bash
- make bootstrap
- ```
-
-### Running Tests
-
-Unit tests running on WebAssembly:
-
-```bash
-make unittest SWIFT_SDK_ID=wasm32-unknown-wasi
-```
-
-Tests for `PackageToJS` plugin:
-
-```bash
-swift test --package-path ./Plugins/PackageToJS
-```
-
-### Editing `./Runtime` directory
-
-The `./Runtime` directory contains the JavaScript runtime that interacts with the JavaScript environment and Swift code.
-The runtime is written in TypeScript and is checked into the repository as compiled JavaScript files.
-To make changes to the runtime, you need to edit the TypeScript files and regenerate the JavaScript files by running:
-
-```bash
-make regenerate_swiftpm_resources
-```
-
-## Support
-If you have any questions or need assistance, feel free to reach out via [GitHub Issues](https://github.com/swiftwasm/JavaScriptKit/issues) or [Discord](https://discord.gg/ashJW8T8yp).
diff --git a/Examples/ActorOnWebWorker/Package.swift b/Examples/ActorOnWebWorker/Package.swift
deleted file mode 100644
index 82e87dfdc..000000000
--- a/Examples/ActorOnWebWorker/Package.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-// swift-tools-version: 6.0
-
-import PackageDescription
-
-let package = Package(
- name: "Example",
- platforms: [.macOS("15"), .iOS("18"), .watchOS("11"), .tvOS("18"), .visionOS("2")],
- dependencies: [
- .package(path: "../../")
- ],
- targets: [
- .executableTarget(
- name: "MyApp",
- dependencies: [
- .product(name: "JavaScriptKit", package: "JavaScriptKit"),
- .product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
- ]
- )
- ]
-)
diff --git a/Examples/ActorOnWebWorker/README.md b/Examples/ActorOnWebWorker/README.md
deleted file mode 100644
index c0c849962..000000000
--- a/Examples/ActorOnWebWorker/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# WebWorker + Actor example
-
-Install Development Snapshot toolchain `DEVELOPMENT-SNAPSHOT-2024-07-08-a` or later from [swift.org/install](https://www.swift.org/install/) and run the following commands:
-
-```sh
-$ (
- set -eo pipefail; \
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"] | "swift sdk install \"\(.url)\" --checksum \"\(.checksum)\""' | sh -x
-)
-$ export SWIFT_SDK_ID=$(
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"]["id"]'
-)
-$ ./build.sh
-$ npx serve
-```
diff --git a/Examples/ActorOnWebWorker/Sources/MyApp.swift b/Examples/ActorOnWebWorker/Sources/MyApp.swift
deleted file mode 100644
index 9b38fa30c..000000000
--- a/Examples/ActorOnWebWorker/Sources/MyApp.swift
+++ /dev/null
@@ -1,293 +0,0 @@
-import JavaScriptEventLoop
-import JavaScriptKit
-
-// Simple full-text search service
-actor SearchService {
- struct Error: Swift.Error, CustomStringConvertible {
- let message: String
-
- var description: String {
- return self.message
- }
- }
-
- let serialExecutor: OwnedExecutor
-
- // Simple in-memory index: word -> positions
- var index: [String: [Int]] = [:]
- var originalContent: String = ""
- lazy var console: JSValue = {
- JSObject.global.console
- }()
-
- nonisolated var unownedExecutor: UnownedSerialExecutor {
- return self.serialExecutor.unownedExecutor
- }
-
- init(serialExecutor: OwnedExecutor) {
- self.serialExecutor = serialExecutor
- }
-
- // Utility function for fetch
- func fetch(_ url: String) -> JSPromise {
- let jsFetch = JSObject.global.fetch.function!
- return JSPromise(jsFetch(url).object!)!
- }
-
- func fetchAndIndex(url: String) async throws {
- let response = try await fetch(url).value()
- if response.status != 200 {
- throw Error(message: "Failed to fetch content")
- }
- let text = try await JSPromise(response.text().object!)!.value()
- let content = text.string!
- index(content)
- }
-
- func index(_ contents: String) {
- self.originalContent = contents
- self.index = [:]
-
- // Simple tokenization and indexing
- var position = 0
- let words = contents.lowercased().split(whereSeparator: { !$0.isLetter && !$0.isNumber })
-
- for word in words {
- let wordStr = String(word)
- if wordStr.count > 1 { // Skip single-character words
- if index[wordStr] == nil {
- index[wordStr] = []
- }
- index[wordStr]?.append(position)
- }
- position += 1
- }
-
- _ = console.log("Indexing complete with", index.count, "unique words")
- }
-
- func search(_ query: String) -> [SearchResult] {
- let queryWords = query.lowercased().split(whereSeparator: { !$0.isLetter && !$0.isNumber })
-
- if queryWords.isEmpty {
- return []
- }
-
- var results: [SearchResult] = []
-
- // Start with the positions of the first query word
- guard let firstWord = queryWords.first,
- let firstWordPositions = index[String(firstWord)]
- else {
- return []
- }
-
- for position in firstWordPositions {
- // Extract context around this position
- let words = originalContent.lowercased().split(whereSeparator: {
- !$0.isLetter && !$0.isNumber
- })
- var contextWords: [String] = []
-
- // Get words for context (5 words before, 10 words after)
- let contextStart = max(0, position - 5)
- let contextEnd = min(position + 10, words.count - 1)
-
- if contextStart <= contextEnd && contextStart < words.count {
- for i in contextStart...contextEnd {
- if i < words.count {
- contextWords.append(String(words[i]))
- }
- }
- }
-
- let context = contextWords.joined(separator: " ")
- results.append(SearchResult(position: position, context: context))
- }
-
- return results
- }
-}
-
-struct SearchResult {
- let position: Int
- let context: String
-}
-
-@MainActor
-final class App {
- private let document = JSObject.global.document
- private let alert = JSObject.global.alert.function!
-
- // UI elements
- private let container: JSValue
- private let urlInput: JSValue
- private let indexButton: JSValue
- private let searchInput: JSValue
- private let searchButton: JSValue
- private let statusElement: JSValue
- private let resultsElement: JSValue
-
- // Search service
- private let service: SearchService
-
- init(service: SearchService) {
- self.service = service
- container = document.getElementById("container")
- urlInput = document.getElementById("urlInput")
- indexButton = document.getElementById("indexButton")
- searchInput = document.getElementById("searchInput")
- searchButton = document.getElementById("searchButton")
- statusElement = document.getElementById("status")
- resultsElement = document.getElementById("results")
- setupEventHandlers()
- }
-
- private func setupEventHandlers() {
- indexButton.onclick = .object(
- JSClosure { [weak self] _ in
- guard let self else { return .undefined }
- self.performIndex()
- return .undefined
- }
- )
-
- searchButton.onclick = .object(
- JSClosure { [weak self] _ in
- guard let self else { return .undefined }
- self.performSearch()
- return .undefined
- }
- )
- }
-
- private func performIndex() {
- let url = urlInput.value.string!
-
- if url.isEmpty {
- alert("Please enter a URL")
- return
- }
-
- updateStatus("Downloading and indexing content...")
-
- Task { [weak self] in
- guard let self else { return }
- do {
- try await self.service.fetchAndIndex(url: url)
- await MainActor.run {
- self.updateStatus("Indexing complete!")
- }
- } catch {
- await MainActor.run {
- self.updateStatus("Error: \(error)")
- }
- }
- }
- }
-
- private func performSearch() {
- let query = searchInput.value.string!
-
- if query.isEmpty {
- alert("Please enter a search query")
- return
- }
-
- updateStatus("Searching...")
-
- Task { [weak self] in
- guard let self else { return }
- let searchResults = await self.service.search(query)
- await MainActor.run {
- self.displaySearchResults(searchResults)
- }
- }
- }
-
- private func updateStatus(_ message: String) {
- statusElement.innerText = .string(message)
- }
-
- private func displaySearchResults(_ results: [SearchResult]) {
- statusElement.innerText = .string("Search complete! Found \(results.count) results.")
- resultsElement.innerHTML = .string("")
-
- if results.isEmpty {
- let noResults = document.createElement("p")
- noResults.innerText = .string("No results found.")
- _ = resultsElement.appendChild(noResults)
- } else {
- // Display up to 10 results
- for (index, result) in results.prefix(10).enumerated() {
- let resultItem = document.createElement("div")
- resultItem.style = .string(
- "padding: 10px; margin: 5px 0; background: #f5f5f5; border-left: 3px solid blue;"
- )
- resultItem.innerHTML = .string(
- "Result \(index + 1): \(result.context)"
- )
- _ = resultsElement.appendChild(resultItem)
- }
- }
- }
-}
-
-/// The fallback executor actor is used when the dedicated worker is not available.
-actor FallbackExecutorActor {}
-
-enum OwnedExecutor {
- case dedicated(WebWorkerDedicatedExecutor)
- case fallback(FallbackExecutorActor)
-
- var unownedExecutor: UnownedSerialExecutor {
- switch self {
- case .dedicated(let executor):
- return executor.asUnownedSerialExecutor()
- case .fallback(let x):
- return x.unownedExecutor
- }
- }
-}
-
-@main struct Main {
- @MainActor static var app: App?
-
- static func main() {
- JavaScriptEventLoop.installGlobalExecutor()
- let useDedicatedWorker = !(JSObject.global.disableDedicatedWorker.boolean ?? false)
-
- Task {
- let ownedExecutor: OwnedExecutor
- if useDedicatedWorker {
- // Create dedicated worker
- let dedicatedWorker = try await WebWorkerDedicatedExecutor()
- ownedExecutor = .dedicated(dedicatedWorker)
- } else {
- // Fallback to main thread executor
- let fallbackExecutor = FallbackExecutorActor()
- ownedExecutor = .fallback(fallbackExecutor)
- }
- // Create the service and app
- let service = SearchService(serialExecutor: ownedExecutor)
- app = App(service: service)
- }
- }
-}
-
-#if canImport(wasi_pthread)
-import wasi_pthread
-import WASILibc
-
-/// Trick to avoid blocking the main thread. pthread_mutex_lock function is used by
-/// the Swift concurrency runtime.
-@_cdecl("pthread_mutex_lock")
-func pthread_mutex_lock(_ mutex: UnsafeMutablePointer) -> Int32 {
- // DO NOT BLOCK MAIN THREAD
- var ret: Int32
- repeat {
- ret = pthread_mutex_trylock(mutex)
- } while ret == EBUSY
- return ret
-}
-#endif
diff --git a/Examples/ActorOnWebWorker/build.sh b/Examples/ActorOnWebWorker/build.sh
deleted file mode 100755
index c82a10c32..000000000
--- a/Examples/ActorOnWebWorker/build.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-swift package --swift-sdk "${SWIFT_SDK_ID:-wasm32-unknown-wasip1-threads}" -c release \
- plugin --allow-writing-to-package-directory \
- js --use-cdn --output ./Bundle
diff --git a/Examples/ActorOnWebWorker/index.html b/Examples/ActorOnWebWorker/index.html
deleted file mode 100644
index 4a16f16a0..000000000
--- a/Examples/ActorOnWebWorker/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
- WebWorker + Actor example
-
-
-
-
- Full-text Search with Actor on Web Worker
-
-
-
-
-
-
-
-
-
Ready
-
-
-
-
-
diff --git a/Examples/ActorOnWebWorker/serve.json b/Examples/ActorOnWebWorker/serve.json
deleted file mode 100644
index 537a16904..000000000
--- a/Examples/ActorOnWebWorker/serve.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "headers": [{
- "source": "**/*",
- "headers": [
- {
- "key": "Cross-Origin-Embedder-Policy",
- "value": "require-corp"
- }, {
- "key": "Cross-Origin-Opener-Policy",
- "value": "same-origin"
- }
- ]
- }]
-}
diff --git a/Examples/Basic/Package.swift b/Examples/Basic/Package.swift
deleted file mode 100644
index 6c729741c..000000000
--- a/Examples/Basic/Package.swift
+++ /dev/null
@@ -1,21 +0,0 @@
-// swift-tools-version:6.0
-
-import PackageDescription
-
-let package = Package(
- name: "Basic",
- platforms: [
- .macOS(.v14)
- ],
- dependencies: [.package(name: "JavaScriptKit", path: "../../")],
- targets: [
- .executableTarget(
- name: "Basic",
- dependencies: [
- "JavaScriptKit",
- .product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
- ]
- )
- ],
- swiftLanguageModes: [.v5]
-)
diff --git a/Examples/Basic/README.md b/Examples/Basic/README.md
deleted file mode 100644
index a09d6a924..000000000
--- a/Examples/Basic/README.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Basic example
-
-Install Development Snapshot toolchain `DEVELOPMENT-SNAPSHOT-2024-07-08-a` from [swift.org/install](https://www.swift.org/install/) and run the following commands:
-
-```sh
-$ swift sdk install https://github.com/swiftwasm/swift/releases/download/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-07-09-a/swift-wasm-DEVELOPMENT-SNAPSHOT-2024-07-09-a-wasm32-unknown-wasi.artifactbundle.zip
-$ ./build.sh
-$ npx serve
-```
diff --git a/Examples/Basic/Sources/main.swift b/Examples/Basic/Sources/main.swift
deleted file mode 100644
index 7ea9231e1..000000000
--- a/Examples/Basic/Sources/main.swift
+++ /dev/null
@@ -1,52 +0,0 @@
-import JavaScriptEventLoop
-import JavaScriptKit
-
-let alert = JSObject.global.alert.function!
-let document = JSObject.global.document
-
-let divElement = document.createElement("div")
-divElement.innerText = "Hello, world"
-_ = document.body.appendChild(divElement)
-
-let buttonElement = document.createElement("button")
-buttonElement.innerText = "Alert demo"
-buttonElement.onclick = .object(
- JSClosure { _ in
- alert("Swift is running on browser!")
- return .undefined
- }
-)
-
-_ = document.body.appendChild(buttonElement)
-
-private let jsFetch = JSObject.global.fetch.function!
-func fetch(_ url: String) -> JSPromise {
- JSPromise(jsFetch(url).object!)!
-}
-
-JavaScriptEventLoop.installGlobalExecutor()
-
-struct Response: Decodable {
- let uuid: String
-}
-
-let asyncButtonElement = document.createElement("button")
-asyncButtonElement.innerText = "Fetch UUID demo"
-asyncButtonElement.onclick = .object(
- JSClosure { _ in
- Task {
- do {
- let response = try await fetch("https://httpbin.org/uuid").value
- let json = try await JSPromise(response.json().object!)!.value
- let parsedResponse = try JSValueDecoder().decode(Response.self, from: json)
- alert(parsedResponse.uuid)
- } catch {
- print(error)
- }
- }
-
- return .undefined
- }
-)
-
-_ = document.body.appendChild(asyncButtonElement)
diff --git a/Examples/Basic/build.sh b/Examples/Basic/build.sh
deleted file mode 100755
index 826e90f81..000000000
--- a/Examples/Basic/build.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-set -ex
-swift package --swift-sdk "${SWIFT_SDK_ID:-wasm32-unknown-wasi}" -c "${1:-debug}" js --use-cdn
diff --git a/Examples/Basic/index.html b/Examples/Basic/index.html
deleted file mode 100644
index 93868214d..000000000
--- a/Examples/Basic/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Getting Started
-
-
-
-
-
-
-
diff --git a/Examples/Embedded/Package.swift b/Examples/Embedded/Package.swift
deleted file mode 100644
index 5ae19adc6..000000000
--- a/Examples/Embedded/Package.swift
+++ /dev/null
@@ -1,37 +0,0 @@
-// swift-tools-version:6.0
-
-import PackageDescription
-
-let package = Package(
- name: "Embedded",
- dependencies: [
- .package(name: "JavaScriptKit", path: "../../"),
- .package(url: "https://github.com/swiftwasm/swift-dlmalloc", branch: "0.1.0"),
- ],
- targets: [
- .executableTarget(
- name: "EmbeddedApp",
- dependencies: [
- "JavaScriptKit",
- .product(name: "dlmalloc", package: "swift-dlmalloc"),
- ],
- cSettings: [.unsafeFlags(["-fdeclspec"])],
- swiftSettings: [
- .enableExperimentalFeature("Embedded"),
- .enableExperimentalFeature("Extern"),
- .unsafeFlags([
- "-Xfrontend", "-gnone",
- "-Xfrontend", "-disable-stack-protector",
- ]),
- ],
- linkerSettings: [
- .unsafeFlags([
- "-Xclang-linker", "-nostdlib",
- "-Xlinker", "--no-entry",
- "-Xlinker", "--export-if-defined=__main_argc_argv",
- ])
- ]
- )
- ],
- swiftLanguageModes: [.v5]
-)
diff --git a/Examples/Embedded/README.md b/Examples/Embedded/README.md
deleted file mode 100644
index e99d659ff..000000000
--- a/Examples/Embedded/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Embedded example
-
-Requires a recent DEVELOPMENT-SNAPSHOT toolchain. (tested with swift-6.1-DEVELOPMENT-SNAPSHOT-2025-02-21-a)
-
-```sh
-$ ./build.sh
-$ npx serve
-```
diff --git a/Examples/Embedded/Sources/EmbeddedApp/_thingsThatShouldNotBeNeeded.swift b/Examples/Embedded/Sources/EmbeddedApp/_thingsThatShouldNotBeNeeded.swift
deleted file mode 100644
index 8f45ccee9..000000000
--- a/Examples/Embedded/Sources/EmbeddedApp/_thingsThatShouldNotBeNeeded.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-import JavaScriptKit
-
-// NOTE: it seems the embedded tree shaker gets rid of these exports if they are not used somewhere
-func _i_need_to_be_here_for_wasm_exports_to_work() {
- _ = _swjs_library_features
- _ = _swjs_call_host_function
- _ = _swjs_free_host_function
-}
-
-// TODO: why do I need this? and surely this is not ideal... figure this out, or at least have this come from a C lib
-@_cdecl("strlen")
-func strlen(_ s: UnsafePointer) -> Int {
- var p = s
- while p.pointee != 0 {
- p += 1
- }
- return p - s
-}
-
-enum LCG {
- static var x: UInt8 = 0
- static let a: UInt8 = 0x05
- static let c: UInt8 = 0x0b
-
- static func next() -> UInt8 {
- x = a &* x &+ c
- return x
- }
-}
-
-@_cdecl("arc4random_buf")
-public func arc4random_buf(_ buffer: UnsafeMutableRawPointer, _ size: Int) {
- for i in 0..(
- unsafelyWrapping: encode(this: textEncoder, textInputElement.value).object!
- )
- encodeResultElement.innerText = .string(
- encodedData.withUnsafeBytes { bytes in
- bytes.map { hex($0) }.joined(separator: " ")
- }
- )
- return .undefined
- }
-)
-let encoderContainer = document.createElement("div")
-_ = encoderContainer.appendChild(textInputElement)
-_ = encoderContainer.appendChild(encodeResultElement)
-_ = document.body.appendChild(encoderContainer)
-
-func print(_ message: String) {
- _ = JSObject.global.console.log(message)
-}
-
-func hex(_ value: UInt8) -> String {
- var result = "0x"
- let hexChars: [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"]
- result.append(hexChars[Int(value / 16)])
- result.append(hexChars[Int(value % 16)])
- return result
-}
diff --git a/Examples/Embedded/build.sh b/Examples/Embedded/build.sh
deleted file mode 100755
index f807cdbf5..000000000
--- a/Examples/Embedded/build.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-package_dir="$(cd "$(dirname "$0")" && pwd)"
-JAVASCRIPTKIT_EXPERIMENTAL_EMBEDDED_WASM=true \
- swift package --package-path "$package_dir" \
- -c release --triple wasm32-unknown-none-wasm js
diff --git a/Examples/Embedded/index.html b/Examples/Embedded/index.html
deleted file mode 100644
index 93868214d..000000000
--- a/Examples/Embedded/index.html
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
-
- Getting Started
-
-
-
-
-
-
-
diff --git a/Examples/ExportSwift/Package.swift b/Examples/ExportSwift/Package.swift
deleted file mode 100644
index 191278fda..000000000
--- a/Examples/ExportSwift/Package.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-// swift-tools-version:6.0
-
-import PackageDescription
-
-let package = Package(
- name: "MyApp",
- platforms: [
- .macOS(.v14)
- ],
- dependencies: [.package(name: "JavaScriptKit", path: "../../")],
- targets: [
- .executableTarget(
- name: "MyApp",
- dependencies: [
- "JavaScriptKit"
- ],
- swiftSettings: [
- .enableExperimentalFeature("Extern")
- ],
- plugins: [
- .plugin(name: "BridgeJS", package: "JavaScriptKit")
- ]
- )
- ]
-)
diff --git a/Examples/ExportSwift/Sources/main.swift b/Examples/ExportSwift/Sources/main.swift
deleted file mode 100644
index 449155214..000000000
--- a/Examples/ExportSwift/Sources/main.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-import JavaScriptKit
-
-// Mark functions you want to export to JavaScript with the @JS attribute
-// This function will be available as `renderCircleSVG(size)` in JavaScript
-@JS public func renderCircleSVG(size: Int) -> String {
- let strokeWidth = 3
- let strokeColor = "black"
- let fillColor = "red"
- let cx = size / 2
- let cy = size / 2
- let r = (size / 2) - strokeWidth
- var svg = ""
- return svg
-}
-
-// Classes can also be exported using the @JS attribute
-// This class will be available as a constructor in JavaScript: new Greeter("name")
-@JS class Greeter {
- var name: String
-
- // Use @JS for initializers you want to expose
- @JS init(name: String) {
- self.name = name
- }
-
- // Methods need the @JS attribute to be accessible from JavaScript
- // This method will be available as greeter.greet() in JavaScript
- @JS public func greet() -> String {
- "Hello, \(name)!"
- }
-}
diff --git a/Examples/ExportSwift/index.html b/Examples/ExportSwift/index.html
deleted file mode 100644
index ef3d190ac..000000000
--- a/Examples/ExportSwift/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- Getting Started
-
-
-
-
-
-
-
diff --git a/Examples/ExportSwift/index.js b/Examples/ExportSwift/index.js
deleted file mode 100644
index 4c5576b25..000000000
--- a/Examples/ExportSwift/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js";
-const { exports } = await init({});
-
-const Greeter = exports.Greeter;
-const greeter = new Greeter("World");
-const circle = exports.renderCircleSVG(100);
-
-// Display the results
-const textOutput = document.createElement("div");
-textOutput.innerText = greeter.greet()
-document.body.appendChild(textOutput);
-const circleOutput = document.createElement("div");
-circleOutput.innerHTML = circle;
-document.body.appendChild(circleOutput);
diff --git a/Examples/ImportTS/Package.swift b/Examples/ImportTS/Package.swift
deleted file mode 100644
index 4809ec006..000000000
--- a/Examples/ImportTS/Package.swift
+++ /dev/null
@@ -1,29 +0,0 @@
-// swift-tools-version:6.0
-
-import PackageDescription
-
-let package = Package(
- name: "MyApp",
- platforms: [
- .macOS(.v10_15),
- .iOS(.v13),
- .tvOS(.v13),
- .watchOS(.v6),
- .macCatalyst(.v13),
- ],
- dependencies: [.package(name: "JavaScriptKit", path: "../../")],
- targets: [
- .executableTarget(
- name: "MyApp",
- dependencies: [
- "JavaScriptKit"
- ],
- swiftSettings: [
- .enableExperimentalFeature("Extern")
- ],
- plugins: [
- .plugin(name: "BridgeJS", package: "JavaScriptKit")
- ]
- )
- ]
-)
diff --git a/Examples/ImportTS/Sources/bridge.d.ts b/Examples/ImportTS/Sources/bridge.d.ts
deleted file mode 100644
index 856bba9c4..000000000
--- a/Examples/ImportTS/Sources/bridge.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-// Function definition to expose console.log to Swift
-// Will be imported as a Swift function: consoleLog(message: String)
-export function consoleLog(message: string): void
-
-// TypeScript interface types are converted to Swift structs
-// This defines a subset of the browser's HTMLElement interface
-type HTMLElement = Pick & {
- // Methods with object parameters are properly handled
- appendChild(child: HTMLElement): void
-}
-
-// TypeScript object type with read-only properties
-// Properties will become Swift properties with appropriate access level
-type Document = {
- // Regular property - will be read/write in Swift
- title: string
- // Read-only property - will be read-only in Swift
- readonly body: HTMLElement
- // Method returning an object - will become a Swift method returning an HTMLElement
- createElement(tagName: string): HTMLElement
-}
-// Function returning a complex object
-// Will be imported as a Swift function: getDocument() -> Document
-export function getDocument(): Document
diff --git a/Examples/ImportTS/Sources/main.swift b/Examples/ImportTS/Sources/main.swift
deleted file mode 100644
index 4328b0a3b..000000000
--- a/Examples/ImportTS/Sources/main.swift
+++ /dev/null
@@ -1,26 +0,0 @@
-import JavaScriptKit
-
-// This function is automatically generated by the @JS plugin
-// It demonstrates how to use TypeScript functions and types imported from bridge.d.ts
-@JS public func run() {
- // Call the imported consoleLog function defined in bridge.d.ts
- consoleLog("Hello, World!")
-
- // Get the document object - this comes from the imported getDocument() function
- let document = getDocument()
-
- // Access and modify properties - the title property is read/write
- document.title = "Hello, World!"
-
- // Access read-only properties - body is defined as readonly in TypeScript
- let body = document.body
-
- // Create a new element using the document.createElement method
- let h1 = document.createElement("h1")
-
- // Set properties on the created element
- h1.innerText = "Hello, World!"
-
- // Call methods on objects - appendChild is defined in the HTMLElement interface
- body.appendChild(h1)
-}
diff --git a/Examples/ImportTS/index.html b/Examples/ImportTS/index.html
deleted file mode 100644
index 31881c499..000000000
--- a/Examples/ImportTS/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
- Getting Started
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Examples/ImportTS/index.js b/Examples/ImportTS/index.js
deleted file mode 100644
index 9452b7ec7..000000000
--- a/Examples/ImportTS/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { init } from "./.build/plugins/PackageToJS/outputs/Package/index.js";
-const { exports } = await init({
- imports: {
- consoleLog: (message) => {
- console.log(message);
- },
- getDocument: () => {
- return document;
- },
- }
-});
-
-exports.run()
diff --git a/Examples/Multithreading/Package.resolved b/Examples/Multithreading/Package.resolved
deleted file mode 100644
index f55b8400a..000000000
--- a/Examples/Multithreading/Package.resolved
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "originHash" : "072d03a6e24e01bd372682a6090adb80cf29dea39421e065de6ff8853de704c9",
- "pins" : [
- {
- "identity" : "chibi-ray",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/kateinoigakukun/chibi-ray",
- "state" : {
- "revision" : "c8cab621a3338dd2f8e817d3785362409d3b8cf1"
- }
- },
- {
- "identity" : "swift-syntax",
- "kind" : "remoteSourceControl",
- "location" : "https://github.com/swiftlang/swift-syntax",
- "state" : {
- "revision" : "0687f71944021d616d34d922343dcef086855920",
- "version" : "600.0.1"
- }
- }
- ],
- "version" : 3
-}
diff --git a/Examples/Multithreading/Package.swift b/Examples/Multithreading/Package.swift
deleted file mode 100644
index 4d1ebde70..000000000
--- a/Examples/Multithreading/Package.swift
+++ /dev/null
@@ -1,25 +0,0 @@
-// swift-tools-version: 5.10
-
-import PackageDescription
-
-let package = Package(
- name: "Example",
- platforms: [.macOS("15"), .iOS("18"), .watchOS("11"), .tvOS("18"), .visionOS("2")],
- dependencies: [
- .package(path: "../../"),
- .package(
- url: "https://github.com/kateinoigakukun/chibi-ray",
- revision: "c8cab621a3338dd2f8e817d3785362409d3b8cf1"
- ),
- ],
- targets: [
- .executableTarget(
- name: "MyApp",
- dependencies: [
- .product(name: "JavaScriptKit", package: "JavaScriptKit"),
- .product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
- .product(name: "ChibiRay", package: "chibi-ray"),
- ]
- )
- ]
-)
diff --git a/Examples/Multithreading/README.md b/Examples/Multithreading/README.md
deleted file mode 100644
index 346f8cc8b..000000000
--- a/Examples/Multithreading/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Multithreading example
-
-Install Development Snapshot toolchain `DEVELOPMENT-SNAPSHOT-2024-07-08-a` or later from [swift.org/install](https://www.swift.org/install/) and run the following commands:
-
-```sh
-$ (
- set -eo pipefail; \
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"] | "swift sdk install \"\(.url)\" --checksum \"\(.checksum)\""' | sh -x
-)
-$ export SWIFT_SDK_ID=$(
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"]["id"]'
-)
-$ ./build.sh
-$ npx serve
-```
diff --git a/Examples/Multithreading/Sources/MyApp/Scene.swift b/Examples/Multithreading/Sources/MyApp/Scene.swift
deleted file mode 100644
index bddde1715..000000000
--- a/Examples/Multithreading/Sources/MyApp/Scene.swift
+++ /dev/null
@@ -1,93 +0,0 @@
-import ChibiRay
-
-func createDemoScene(size: Int) -> Scene {
- return Scene(
- width: size,
- height: size,
- fov: 90,
- elements: [
- .sphere(
- Sphere(
- center: Point(x: 1.0, y: -1.0, z: -7.0),
- radius: 1.0,
- material: Material(
- color: Color(red: 0.8, green: 0.2, blue: 0.4),
- albedo: 0.6,
- surface: .reflective(reflectivity: 0.9)
- )
- )
- ),
- .sphere(
- Sphere(
- center: Point(x: -2.0, y: 1.0, z: -10.0),
- radius: 3.0,
- material: Material(
- color: Color(red: 1.0, green: 0.4, blue: 0.4),
- albedo: 0.7,
- surface: .diffuse
- )
- )
- ),
- .sphere(
- Sphere(
- center: Point(x: 3.0, y: 2.0, z: -5.0),
- radius: 2.0,
- material: Material(
- color: Color(red: 0.4, green: 0.4, blue: 0.8),
- albedo: 0.5,
- surface: .refractive(index: 2, transparency: 0.9)
- )
- )
- ),
- .plane(
- Plane(
- origin: Point(x: 0.0, y: -2.0, z: -5.0),
- normal: Vector3(x: 0.0, y: -1.0, z: 0.0),
- material: Material(
- color: Color(red: 1.0, green: 1.0, blue: 1.0),
- albedo: 0.18,
- surface: .reflective(reflectivity: 0.5)
- )
- )
- ),
- .plane(
- Plane(
- origin: Point(x: 0.0, y: 0.0, z: -20.0),
- normal: Vector3(x: 0.0, y: 0.0, z: -1.0),
- material: Material(
- color: Color(red: 0.2, green: 0.3, blue: 1.0),
- albedo: 0.38,
- surface: .diffuse
- )
- )
- ),
- ],
- lights: [
- .spherical(
- SphericalLight(
- position: Point(x: 5.0, y: 10.0, z: -3.0),
- color: Color(red: 1.0, green: 1.0, blue: 1.0),
- intensity: 16000
- )
- ),
- .spherical(
- SphericalLight(
- position: Point(x: -3.0, y: 3.0, z: -5.0),
- color: Color(red: 0.3, green: 0.3, blue: 1.0),
- intensity: 1000
- )
- ),
- .directional(
- DirectionalLight(
- direction: Vector3(x: 0.0, y: -1.0, z: -1.0),
- color: Color(red: 0.8, green: 0.8, blue: 0.8),
- intensity: 0.2
- )
- ),
- ],
- shadowBias: 1e-13,
- maxRecursionDepth: 10
- )
-}
-
-extension Scene: @retroactive @unchecked Sendable {}
diff --git a/Examples/Multithreading/Sources/MyApp/main.swift b/Examples/Multithreading/Sources/MyApp/main.swift
deleted file mode 100644
index f9839ffde..000000000
--- a/Examples/Multithreading/Sources/MyApp/main.swift
+++ /dev/null
@@ -1,177 +0,0 @@
-import ChibiRay
-import JavaScriptEventLoop
-import JavaScriptKit
-
-JavaScriptEventLoop.installGlobalExecutor()
-
-func renderInCanvas(ctx: JSObject, image: ImageView) {
- let imageData = ctx.createImageData!(image.width, image.height).object!
- let data = imageData.data.object!
-
- for y in 0..
-
- subscript(x: Int, y: Int) -> Color {
- get {
- return buffer[y * width + x]
- }
- nonmutating set {
- buffer[y * width + x] = newValue
- }
- }
-}
-
-struct Work: Sendable {
- let scene: Scene
- let imageView: ImageView
- let yRange: CountableRange
-
- init(scene: Scene, imageView: ImageView, yRange: CountableRange) {
- self.scene = scene
- self.imageView = imageView
- self.yRange = yRange
- }
- func run() {
- for y in yRange {
- for x in 0...allocate(capacity: scene.width * scene.height)
- // Initialize the buffer with black color
- imageBuffer.initialize(repeating: .black)
- let imageView = ImageView(width: scene.width, height: scene.height, buffer: imageBuffer)
-
- let clock = ContinuousClock()
- let start = clock.now
-
- func updateRenderTime() {
- let renderSceneDuration = clock.now - start
- renderTimeElement.textContent = .string("Render time: \(renderSceneDuration)")
- }
-
- var checkTimer: JSValue?
- checkTimer = JSObject.global.setInterval!(
- JSClosure { _ in
- print("Checking thread work...")
- renderInCanvas(ctx: ctx, image: imageView)
- updateRenderTime()
- return .undefined
- },
- 250
- )
-
- await withTaskGroup(of: Void.self) { group in
- let yStride = scene.height / concurrency
- for i in 0..) -> Int32 {
- // DO NOT BLOCK MAIN THREAD
- var ret: Int32
- repeat {
- ret = pthread_mutex_trylock(mutex)
- } while ret == EBUSY
- return ret
-}
-#endif
diff --git a/Examples/Multithreading/build.sh b/Examples/Multithreading/build.sh
deleted file mode 100755
index c82a10c32..000000000
--- a/Examples/Multithreading/build.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-swift package --swift-sdk "${SWIFT_SDK_ID:-wasm32-unknown-wasip1-threads}" -c release \
- plugin --allow-writing-to-package-directory \
- js --use-cdn --output ./Bundle
diff --git a/Examples/Multithreading/index.html b/Examples/Multithreading/index.html
deleted file mode 100644
index 20696d83a..000000000
--- a/Examples/Multithreading/index.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
- Threading Example
-
-
-
-
-
-
- Threading Example
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
🧵
-
-
-
-
-
-
diff --git a/Examples/Multithreading/serve.json b/Examples/Multithreading/serve.json
deleted file mode 100644
index 537a16904..000000000
--- a/Examples/Multithreading/serve.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "headers": [{
- "source": "**/*",
- "headers": [
- {
- "key": "Cross-Origin-Embedder-Policy",
- "value": "require-corp"
- }, {
- "key": "Cross-Origin-Opener-Policy",
- "value": "same-origin"
- }
- ]
- }]
-}
diff --git a/Examples/OffscrenCanvas/Package.swift b/Examples/OffscrenCanvas/Package.swift
deleted file mode 100644
index ca6d7357f..000000000
--- a/Examples/OffscrenCanvas/Package.swift
+++ /dev/null
@@ -1,20 +0,0 @@
-// swift-tools-version: 5.10
-
-import PackageDescription
-
-let package = Package(
- name: "Example",
- platforms: [.macOS("15"), .iOS("18"), .watchOS("11"), .tvOS("18"), .visionOS("2")],
- dependencies: [
- .package(path: "../../")
- ],
- targets: [
- .executableTarget(
- name: "MyApp",
- dependencies: [
- .product(name: "JavaScriptKit", package: "JavaScriptKit"),
- .product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
- ]
- )
- ]
-)
diff --git a/Examples/OffscrenCanvas/README.md b/Examples/OffscrenCanvas/README.md
deleted file mode 100644
index 395b0c295..000000000
--- a/Examples/OffscrenCanvas/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# OffscreenCanvas example
-
-Install Development Snapshot toolchain `DEVELOPMENT-SNAPSHOT-2024-07-08-a` or later from [swift.org/install](https://www.swift.org/install/) and run the following commands:
-
-```sh
-$ (
- set -eo pipefail; \
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"] | "swift sdk install \"\(.url)\" --checksum \"\(.checksum)\""' | sh -x
-)
-$ export SWIFT_SDK_ID=$(
- V="$(swiftc --version | head -n1)"; \
- TAG="$(curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/tag-by-version.json" | jq -e -r --arg v "$V" '.[$v] | .[-1]')"; \
- curl -sL "https://raw.githubusercontent.com/swiftwasm/swift-sdk-index/refs/heads/main/v1/builds/$TAG.json" | \
- jq -r '.["swift-sdks"]["wasm32-unknown-wasip1-threads"]["id"]'
-)
-$ ./build.sh
-$ npx serve
-```
diff --git a/Examples/OffscrenCanvas/Sources/MyApp/main.swift b/Examples/OffscrenCanvas/Sources/MyApp/main.swift
deleted file mode 100644
index 5709c664c..000000000
--- a/Examples/OffscrenCanvas/Sources/MyApp/main.swift
+++ /dev/null
@@ -1,141 +0,0 @@
-import JavaScriptEventLoop
-import JavaScriptKit
-
-JavaScriptEventLoop.installGlobalExecutor()
-
-protocol CanvasRenderer {
- func render(canvas: JSObject, size: Int) async throws
-}
-
-struct BackgroundRenderer: CanvasRenderer {
- func render(canvas: JSObject, size: Int) async throws {
- let executor = try await WebWorkerTaskExecutor(numberOfThreads: 1)
- let transfer = JSSending.transfer(canvas)
- let renderingTask = Task(executorPreference: executor) {
- let canvas = try await transfer.receive()
- try await renderAnimation(canvas: canvas, size: size)
- }
- await withTaskCancellationHandler {
- try? await renderingTask.value
- } onCancel: {
- renderingTask.cancel()
- }
- executor.terminate()
- }
-}
-
-struct MainThreadRenderer: CanvasRenderer {
- func render(canvas: JSObject, size: Int) async throws {
- try await renderAnimation(canvas: canvas, size: size)
- }
-}
-
-// FPS Counter for CSS animation
-func startFPSMonitor() {
- let fpsCounterElement = JSObject.global.document.getElementById("fps-counter").object!
-
- var lastTime = JSObject.global.performance.now().number!
- var frames = 0
-
- // Create a frame counter function
- func countFrame() {
- frames += 1
- let currentTime = JSObject.global.performance.now().number!
- let elapsed = currentTime - lastTime
-
- if elapsed >= 1000 {
- let fps = Int(Double(frames) * 1000 / elapsed)
- fpsCounterElement.textContent = .string("FPS: \(fps)")
- frames = 0
- lastTime = currentTime
- }
-
- // Request next frame
- _ = JSObject.global.requestAnimationFrame!(
- JSClosure { _ in
- countFrame()
- return .undefined
- }
- )
- }
-
- // Start counting
- countFrame()
-}
-
-@MainActor
-func onClick(renderer: CanvasRenderer) async throws {
- let document = JSObject.global.document
-
- let canvasContainerElement = document.getElementById("canvas-container").object!
-
- // Remove all child elements from the canvas container
- for i in 0..? = nil
-
- // Start the FPS monitor for CSS animations
- startFPSMonitor()
-
- _ = renderButtonElement.addEventListener!(
- "click",
- JSClosure { _ in
- renderingTask?.cancel()
- renderingTask = Task {
- let selectedValue = rendererSelectElement.value.string!
- let renderer: CanvasRenderer =
- selectedValue == "main" ? MainThreadRenderer() : BackgroundRenderer()
- try await onClick(renderer: renderer)
- }
- return JSValue.undefined
- }
- )
-
- _ = cancelButtonElement.addEventListener!(
- "click",
- JSClosure { _ in
- renderingTask?.cancel()
- return JSValue.undefined
- }
- )
-}
-
-Task {
- try await main()
-}
-
-#if canImport(wasi_pthread)
-import wasi_pthread
-import WASILibc
-
-/// Trick to avoid blocking the main thread. pthread_mutex_lock function is used by
-/// the Swift concurrency runtime.
-@_cdecl("pthread_mutex_lock")
-func pthread_mutex_lock(_ mutex: UnsafeMutablePointer) -> Int32 {
- // DO NOT BLOCK MAIN THREAD
- var ret: Int32
- repeat {
- ret = pthread_mutex_trylock(mutex)
- } while ret == EBUSY
- return ret
-}
-#endif
diff --git a/Examples/OffscrenCanvas/Sources/MyApp/render.swift b/Examples/OffscrenCanvas/Sources/MyApp/render.swift
deleted file mode 100644
index 6a9d057a9..000000000
--- a/Examples/OffscrenCanvas/Sources/MyApp/render.swift
+++ /dev/null
@@ -1,179 +0,0 @@
-import Foundation
-import JavaScriptKit
-
-func sleepOnThread(milliseconds: Int, isolation: isolated (any Actor)? = #isolation) async {
- // Use the JavaScript setTimeout function to avoid hopping back to the main thread
- await withCheckedContinuation(isolation: isolation) { continuation in
- _ = JSObject.global.setTimeout!(
- JSOneshotClosure { _ in
- continuation.resume()
- return JSValue.undefined
- },
- milliseconds
- )
- }
-}
-
-func renderAnimation(
- canvas: JSObject,
- size: Int,
- isolation: isolated (any Actor)? = #isolation
-)
- async throws
-{
- let ctx = canvas.getContext!("2d").object!
-
- // Animation state variables
- var time: Double = 0
-
- // Create a large number of particles
- let particleCount = 5000
- var particles: [[Double]] = []
-
- // Initialize particles with random positions and velocities
- for _ in 0.. Double(size) {
- particles[i][2] *= -0.8
- }
- if particles[i][1] < 0 || particles[i][1] > Double(size) {
- particles[i][3] *= -0.8
- }
-
- // Calculate opacity based on lifespan
- let opacity = particles[i][6] / particles[i][7]
-
- // Get coordinates and properties
- let x = particles[i][0]
- let y = particles[i][1]
- let size = particles[i][4]
- let hue = (particles[i][5] + time * 10).truncatingRemainder(dividingBy: 360)
-
- // Draw particle
- _ = ctx.beginPath!()
- ctx.fillStyle = .string("hsla(\(hue), 100%, 60%, \(opacity))")
- _ = ctx.arc!(x, y, size, 0, 2 * Double.pi)
- _ = ctx.fill!()
-
- // Connect nearby particles with lines (only check some to save CPU)
- if i % 20 == 0 {
- for j in (i + 1)..
-
-
-
- OffscreenCanvas Example
-
-
-
-
-
- OffscreenCanvas Example
-
-
-
-
-
-
-
-
- CSS Animation (Main Thread Performance Indicator)
-
-
- FPS: 0
-
-
-
-
-