diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 454d580fd..e6b0db563 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -18,28 +18,34 @@ jobs:
# Ensure that test succeeds with all toolchains and wasi backend combinations
- { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: Node }
- { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Node }
- - { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: Wasmer }
+ - { os: ubuntu-20.04, toolchain: wasm-5.7.1-RELEASE, wasi-backend: Node }
- { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: Wasmer }
- - { os: ubuntu-20.04, toolchain: wasm-5.5.0-RELEASE, wasi-backend: MicroWASI }
+ - { os: ubuntu-20.04, toolchain: wasm-5.7.1-RELEASE, wasi-backend: Wasmer }
- { os: ubuntu-20.04, toolchain: wasm-5.6.0-RELEASE, wasi-backend: MicroWASI }
+ - { os: ubuntu-20.04, toolchain: wasm-5.7.1-RELEASE, wasi-backend: MicroWASI }
runs-on: ${{ matrix.entry.os }}
+ env:
+ JAVASCRIPTKIT_WASI_BACKEND: ${{ matrix.entry.wasi-backend }}
+ SWIFT_VERSION: ${{ matrix.entry.toolchain }}
steps:
- name: Checkout
uses: actions/checkout@master
with:
fetch-depth: 1
- - name: Run Test
- env:
- JAVASCRIPTKIT_WASI_BACKEND: ${{ matrix.entry.wasi-backend }}
+ - name: Install swiftenv
run: |
git clone https://github.com/kylef/swiftenv.git ~/.swiftenv
export SWIFTENV_ROOT="$HOME/.swiftenv"
export PATH="$SWIFTENV_ROOT/bin:$PATH"
eval "$(swiftenv init -)"
- SWIFT_VERSION=${{ matrix.entry.toolchain }} make bootstrap
+ echo $PATH >> $GITHUB_PATH
+ env >> $GITHUB_ENV
echo ${{ matrix.entry.toolchain }} > .swift-version
- make test
+ - run: make bootstrap
+ - run: make test
+ - run: make unittest
+ if: ${{ startsWith(matrix.toolchain, 'wasm-5.7.') }}
- name: Check if SwiftPM resources are stale
run: |
make regenerate_swiftpm_resources
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17f460cd5..d0d336ed5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,21 @@
+# 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.
diff --git a/Example/package-lock.json b/Example/package-lock.json
index b112f5885..24b287a21 100644
--- a/Example/package-lock.json
+++ b/Example/package-lock.json
@@ -21,7 +21,7 @@
},
"..": {
"name": "javascript-kit-swift",
- "version": "0.16.0",
+ "version": "0.17.0",
"license": "MIT",
"devDependencies": {
"@rollup/plugin-typescript": "^8.3.1",
diff --git a/IntegrationTests/lib.js b/IntegrationTests/lib.js
index a0af77527..e708816cb 100644
--- a/IntegrationTests/lib.js
+++ b/IntegrationTests/lib.js
@@ -9,7 +9,7 @@ const fs = require("fs");
const readFile = promisify(fs.readFile);
const WASI = {
- Wasmer: () => {
+ Wasmer: ({ programName }) => {
// Instantiate a new WASI Instance
const wasmFs = new WasmFs();
// Output stdout and stderr to console
@@ -27,7 +27,7 @@ const WASI = {
return originalWriteSync(fd, buffer, offset, length, position);
};
const wasi = new WasmerWASI({
- args: [],
+ args: [programName],
env: {},
bindings: {
...WasmerWASI.defaultBindings,
@@ -44,9 +44,9 @@ const WASI = {
}
}
},
- MicroWASI: () => {
+ MicroWASI: ({ programName }) => {
const wasi = new MicroWASI({
- args: [],
+ args: [programName],
env: {},
features: [useAll()],
})
@@ -59,11 +59,11 @@ const WASI = {
}
}
},
- Node: () => {
+ Node: ({ programName }) => {
const wasi = new NodeWASI({
- args: [],
+ args: [programName],
env: {},
- returnOnExit: true,
+ returnOnExit: false,
})
return {
@@ -91,7 +91,7 @@ const startWasiTask = async (wasmPath, wasiConstructor = selectWASIBackend()) =>
const swift = new SwiftRuntime();
// Fetch our Wasm File
const wasmBinary = await readFile(wasmPath);
- const wasi = wasiConstructor();
+ const wasi = wasiConstructor({ programName: wasmPath });
// Instantiate the WebAssembly file
let { instance } = await WebAssembly.instantiate(wasmBinary, {
diff --git a/Makefile b/Makefile
index bd93f2e60..7b8736221 100644
--- a/Makefile
+++ b/Makefile
@@ -12,12 +12,19 @@ build:
.PHONY: test
test:
+ @echo Running integration tests
cd IntegrationTests && \
CONFIGURATION=debug make test && \
CONFIGURATION=debug SWIFT_BUILD_FLAGS="-Xswiftc -DJAVASCRIPTKIT_WITHOUT_WEAKREFS" make test && \
CONFIGURATION=release make test && \
CONFIGURATION=release SWIFT_BUILD_FLAGS="-Xswiftc -DJAVASCRIPTKIT_WITHOUT_WEAKREFS" make test
+.PHONY: unittest
+unittest:
+ @echo Running unit tests
+ swift build --build-tests --triple wasm32-unknown-wasi -Xswiftc -Xclang-linker -Xswiftc -mexec-model=reactor -Xlinker --export=main
+ node --experimental-wasi-unstable-preview1 scripts/test-harness.js ./.build/wasm32-unknown-wasi/debug/JavaScriptKitPackageTests.wasm
+
.PHONY: benchmark_setup
benchmark_setup:
cd IntegrationTests && CONFIGURATION=release make benchmark_setup
diff --git a/Package.swift b/Package.swift
index d278e5ab9..c8f55dd0b 100644
--- a/Package.swift
+++ b/Package.swift
@@ -8,6 +8,7 @@ let package = Package(
.library(name: "JavaScriptKit", targets: ["JavaScriptKit"]),
.library(name: "JavaScriptEventLoop", targets: ["JavaScriptEventLoop"]),
.library(name: "JavaScriptBigIntSupport", targets: ["JavaScriptBigIntSupport"]),
+ .library(name: "JavaScriptEventLoopTestSupport", targets: ["JavaScriptEventLoopTestSupport"]),
],
targets: [
.target(
@@ -26,5 +27,20 @@ let package = Package(
dependencies: ["JavaScriptKit", "_CJavaScriptEventLoop"]
),
.target(name: "_CJavaScriptEventLoop"),
+ .target(
+ name: "JavaScriptEventLoopTestSupport",
+ dependencies: [
+ "_CJavaScriptEventLoopTestSupport",
+ "JavaScriptEventLoop",
+ ]
+ ),
+ .target(name: "_CJavaScriptEventLoopTestSupport"),
+ .testTarget(
+ name: "JavaScriptEventLoopTestSupportTests",
+ dependencies: [
+ "JavaScriptKit",
+ "JavaScriptEventLoopTestSupport"
+ ]
+ ),
]
)
diff --git a/README.md b/README.md
index 42af64320..0c2c6988c 100644
--- a/README.md
+++ b/README.md
@@ -125,6 +125,23 @@ asyncButtonElement.onclick = .object(JSClosure { _ in
_ = document.body.appendChild(asyncButtonElement)
```
+### `JavaScriptEventLoop` activation in XCTest suites
+
+If you need to execute Swift async functions that can be resumed by JS event loop in your XCTest suites, please add `JavaScriptEventLoopTestSupport` to your test target dependencies.
+
+```diff
+ .testTarget(
+ name: "MyAppTests",
+ dependencies: [
+ "MyApp",
++ "JavaScriptEventLoopTestSupport",
+ ]
+ )
+```
+
+Linking this module automatically activates JS event loop based global executor by calling `JavaScriptEventLoop.installGlobalExecutor()`
+
+
## Requirements
### For developers
diff --git a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift
index d8f4ad0ad..7c4a1c905 100644
--- a/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift
+++ b/Sources/JavaScriptEventLoop/JavaScriptEventLoop.swift
@@ -39,9 +39,9 @@ public final class JavaScriptEventLoop: SerialExecutor, @unchecked Sendable {
/// A function that queues a given closure as a microtask into JavaScript event loop.
/// See also: https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide
- let queueMicrotask: @Sendable (@escaping () -> Void) -> Void
+ public var queueMicrotask: @Sendable (@escaping () -> Void) -> Void
/// A function that invokes a given closure after a specified number of milliseconds.
- let setTimeout: @Sendable (Double, @escaping () -> Void) -> Void
+ public var setTimeout: @Sendable (Double, @escaping () -> Void) -> Void
/// A mutable state to manage internal job queue
/// Note that this should be guarded atomically when supporting multi-threaded environment.
diff --git a/Sources/JavaScriptEventLoopTestSupport/JavaScriptEventLoopTestSupport.swift b/Sources/JavaScriptEventLoopTestSupport/JavaScriptEventLoopTestSupport.swift
new file mode 100644
index 000000000..9922de945
--- /dev/null
+++ b/Sources/JavaScriptEventLoopTestSupport/JavaScriptEventLoopTestSupport.swift
@@ -0,0 +1,31 @@
+/// If you need to execute Swift async functions that can be resumed by JS
+/// event loop in your XCTest suites, please add `JavaScriptEventLoopTestSupport`
+/// to your test target dependencies.
+///
+/// ```diff
+/// .testTarget(
+/// name: "MyAppTests",
+/// dependencies: [
+/// "MyApp",
+/// + "JavaScriptEventLoopTestSupport",
+/// ]
+/// )
+/// ```
+///
+/// Linking this module automatically activates JS event loop based global
+/// executor by calling `JavaScriptEventLoop.installGlobalExecutor()`
+
+import JavaScriptEventLoop
+
+// This module just expose 'JavaScriptEventLoop.installGlobalExecutor' to C ABI
+// See _CJavaScriptEventLoopTestSupport.c for why this is needed
+
+#if compiler(>=5.5)
+
+@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
+@_cdecl("swift_javascriptkit_activate_js_executor_impl")
+func swift_javascriptkit_activate_js_executor_impl() {
+ JavaScriptEventLoop.installGlobalExecutor()
+}
+
+#endif
diff --git a/Sources/_CJavaScriptEventLoopTestSupport/_CJavaScriptEventLoopTestSupport.c b/Sources/_CJavaScriptEventLoopTestSupport/_CJavaScriptEventLoopTestSupport.c
new file mode 100644
index 000000000..7dfdbe2e8
--- /dev/null
+++ b/Sources/_CJavaScriptEventLoopTestSupport/_CJavaScriptEventLoopTestSupport.c
@@ -0,0 +1,19 @@
+// This 'ctor' function is called at startup time of this program.
+// It's invoked by '_start' of command-line or '_initialize' of reactor.
+// This ctor activate the event loop based global executor automatically
+// before running the test cases. For general applications, applications
+// have to activate the event loop manually on their responsibility.
+// However, XCTest framework doesn't provide a way to run arbitrary code
+// before running all of the test suites. So, we have to do it here.
+//
+// See also: https://github.com/WebAssembly/WASI/blob/main/legacy/application-abi.md#current-unstable-abi
+
+extern void swift_javascriptkit_activate_js_executor_impl(void);
+
+// priority 0~100 is reserved by wasi-libc
+// https://github.com/WebAssembly/wasi-libc/blob/30094b6ed05f19cee102115215863d185f2db4f0/libc-bottom-half/sources/environ.c#L20
+__attribute__((constructor(/* priority */ 200)))
+void swift_javascriptkit_activate_js_executor(void) {
+ swift_javascriptkit_activate_js_executor_impl();
+}
+
diff --git a/Sources/_CJavaScriptEventLoopTestSupport/include/dummy.h b/Sources/_CJavaScriptEventLoopTestSupport/include/dummy.h
new file mode 100644
index 000000000..e69de29bb
diff --git a/Tests/JavaScriptEventLoopTestSupportTests/JavaScriptEventLoopTestSupportTests.swift b/Tests/JavaScriptEventLoopTestSupportTests/JavaScriptEventLoopTestSupportTests.swift
new file mode 100644
index 000000000..cca303a09
--- /dev/null
+++ b/Tests/JavaScriptEventLoopTestSupportTests/JavaScriptEventLoopTestSupportTests.swift
@@ -0,0 +1,15 @@
+import XCTest
+import JavaScriptKit
+
+final class JavaScriptEventLoopTestSupportTests: XCTestCase {
+ func testAwaitMicrotask() async {
+ let _: () = await withCheckedContinuation { cont in
+ JSObject.global.queueMicrotask.function!(
+ JSOneshotClosure { _ in
+ cont.resume(returning: ())
+ return .undefined
+ }
+ )
+ }
+ }
+}
diff --git a/ci/perf-tester/package-lock.json b/ci/perf-tester/package-lock.json
index c0cbbbdb2..82918bd59 100644
--- a/ci/perf-tester/package-lock.json
+++ b/ci/perf-tester/package-lock.json
@@ -5,16 +5,20 @@
"packages": {
"": {
"devDependencies": {
- "@actions/core": "^1.2.6",
+ "@actions/core": "^1.9.1",
"@actions/exec": "^1.0.3",
"@actions/github": "^2.0.1"
}
},
"node_modules/@actions/core": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
- "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==",
- "dev": true
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
+ "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
+ "dev": true,
+ "dependencies": {
+ "@actions/http-client": "^2.0.1",
+ "uuid": "^8.3.2"
+ }
},
"node_modules/@actions/exec": {
"version": "1.0.3",
@@ -35,6 +39,15 @@
"@octokit/rest": "^16.15.0"
}
},
+ "node_modules/@actions/http-client": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
+ "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
+ "dev": true,
+ "dependencies": {
+ "tunnel": "^0.0.6"
+ }
+ },
"node_modules/@actions/io": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz",
@@ -412,6 +425,15 @@
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"dev": true
},
+ "node_modules/tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+ }
+ },
"node_modules/universal-user-agent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
@@ -421,6 +443,15 @@
"os-name": "^3.1.0"
}
},
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -470,10 +501,14 @@
},
"dependencies": {
"@actions/core": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.6.tgz",
- "integrity": "sha512-ZQYitnqiyBc3D+k7LsgSBmMDVkOVidaagDG7j3fOym77jNunWRuYx7VSHa9GNfFZh+zh61xsCjRj4JxMZlDqTA==",
- "dev": true
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz",
+ "integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==",
+ "dev": true,
+ "requires": {
+ "@actions/http-client": "^2.0.1",
+ "uuid": "^8.3.2"
+ }
},
"@actions/exec": {
"version": "1.0.3",
@@ -494,6 +529,15 @@
"@octokit/rest": "^16.15.0"
}
},
+ "@actions/http-client": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
+ "integrity": "sha512-PIXiMVtz6VvyaRsGY268qvj57hXQEpsYogYOu2nrQhlf+XCGmZstmuZBbAybUl1nQGnvS1k1eEsQ69ZoD7xlSw==",
+ "dev": true,
+ "requires": {
+ "tunnel": "^0.0.6"
+ }
+ },
"@actions/io": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz",
@@ -815,6 +859,12 @@
"integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
"dev": true
},
+ "tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true
+ },
"universal-user-agent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.0.tgz",
@@ -824,6 +874,12 @@
"os-name": "^3.1.0"
}
},
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true
+ },
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
diff --git a/ci/perf-tester/package.json b/ci/perf-tester/package.json
index 97718ab9a..7a00de44d 100644
--- a/ci/perf-tester/package.json
+++ b/ci/perf-tester/package.json
@@ -2,7 +2,7 @@
"private": true,
"main": "src/index.js",
"devDependencies": {
- "@actions/core": "^1.2.6",
+ "@actions/core": "^1.9.1",
"@actions/exec": "^1.0.3",
"@actions/github": "^2.0.1"
}
diff --git a/ci/perf-tester/src/utils.js b/ci/perf-tester/src/utils.js
index a4b717ab7..c7ecd662b 100644
--- a/ci/perf-tester/src/utils.js
+++ b/ci/perf-tester/src/utils.js
@@ -168,6 +168,7 @@ exports.diffTable = (
) => {
let changedRows = [];
let unChangedRows = [];
+ let baselineRows = [];
let totalTime = 0;
let totalDelta = 0;
@@ -187,7 +188,9 @@ exports.diffTable = (
getDeltaText(delta, difference),
iconForDifference(difference),
];
- if (isUnchanged && collapseUnchanged) {
+ if (name.includes('directly')) {
+ baselineRows.push(columns);
+ } else if (isUnchanged && collapseUnchanged) {
unChangedRows.push(columns);
} else {
changedRows.push(columns);
@@ -200,6 +203,11 @@ exports.diffTable = (
const outUnchanged = markdownTable(unChangedRows);
out += `\n\nView Unchanged
\n\n${outUnchanged}\n\n \n\n`;
}
+
+ if (baselineRows.length !== 0) {
+ const outBaseline = markdownTable(baselineRows.map(line => line.slice(0, 2)));
+ out += `\n\nView Baselines
\n\n${outBaseline}\n\n \n\n`;
+ }
if (showTotal) {
const totalDifference = ((totalDelta / totalTime) * 100) | 0;
diff --git a/package-lock.json b/package-lock.json
index 7d66e97ec..dcc23dc1b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "javascript-kit-swift",
- "version": "0.16.0",
+ "version": "0.17.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "javascript-kit-swift",
- "version": "0.16.0",
+ "version": "0.17.0",
"license": "MIT",
"devDependencies": {
"@rollup/plugin-typescript": "^8.3.1",
diff --git a/package.json b/package.json
index c4d459201..8bd772b21 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "javascript-kit-swift",
- "version": "0.16.0",
+ "version": "0.17.0",
"description": "A runtime library of JavaScriptKit which is Swift framework to interact with JavaScript through WebAssembly.",
"main": "Runtime/lib/index.js",
"module": "Runtime/lib/index.mjs",
diff --git a/scripts/test-harness.js b/scripts/test-harness.js
new file mode 100644
index 000000000..39a7dbe9a
--- /dev/null
+++ b/scripts/test-harness.js
@@ -0,0 +1,10 @@
+Error.stackTraceLimit = Infinity;
+
+const { startWasiTask, WASI } = require("../IntegrationTests/lib");
+
+const handleExitOrError = (error) => {
+ console.log(error);
+ process.exit(1);
+}
+
+startWasiTask(process.argv[2]).catch(handleExitOrError);