Skip to content

Commit 954bdb4

Browse files
committed
Initial commit.
0 parents  commit 954bdb4

24 files changed

+733
-0
lines changed

.eslintrc.json

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"es2021": true
5+
},
6+
"extends": "eslint:recommended",
7+
"parserOptions": {
8+
"ecmaVersion": "latest",
9+
"sourceType": "module"
10+
},
11+
"rules": {
12+
"semi": "error",
13+
"eqeqeq": "error",
14+
"no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
15+
"no-constant-condition": ["error", { "checkLoops": false }]
16+
}
17+
}

.github/FUNDING

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
patreon: whitequark

.github/workflows/package.yml

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
on: [push, pull_request]
2+
name: Test & publish
3+
env:
4+
RELEASE_BRANCH: "${{ startsWith(github.event.ref, 'refs/heads/develop-') || startsWith(github.event.ref, 'refs/heads/release-') }}"
5+
jobs:
6+
test:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- name: Check out source code
10+
uses: actions/checkout@v3
11+
- name: Set up node
12+
uses: actions/setup-node@v3
13+
with:
14+
node-version: '18.x'
15+
- name: Prepare metadata
16+
run: node prepare.mjs
17+
- name: Install dependencies
18+
run: npm install
19+
- name: Run tests
20+
run: ./test/run.sh
21+
- name: Run lints
22+
run: npm run lint
23+
check: # group all `test (*)` workflows into one for the required status check
24+
needs: test
25+
if: always() && !contains(needs.*.result, 'cancelled')
26+
runs-on: ubuntu-latest
27+
steps:
28+
- run: ${{ contains(needs.*.result, 'failure') && 'false' || 'true' }}
29+
publish:
30+
needs: check
31+
runs-on: ubuntu-latest
32+
steps:
33+
- name: Check out source code
34+
uses: actions/checkout@v3
35+
- name: Set up node
36+
uses: actions/setup-node@v3
37+
with:
38+
registry-url: 'https://registry.npmjs.org'
39+
- name: Prepare metadata
40+
run: node prepare.mjs
41+
- name: Publish package to NPM
42+
run: npm publish --access public
43+
env:
44+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
45+
release:
46+
needs: check
47+
runs-on: ubuntu-latest
48+
if: "contains(github.event.head_commit.message, 'autorelease') && github.event_name == 'push' && startsWith(github.event.ref, 'refs/heads/develop')"
49+
steps:
50+
- name: Check out source code
51+
uses: actions/checkout@v3
52+
with:
53+
fetch-depth: 0
54+
token: ${{ secrets.PUSH_TOKEN }}
55+
- name: Update release branch
56+
run: |
57+
git push origin develop:release

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/package-lock.json
2+
/package.json
3+
/node_modules
4+
/dist
5+
/gen

LICENSE.txt

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
ISC License
2+
3+
Copyright (C) Catherine <[email protected]>
4+
5+
Permission to use, copy, modify, and/or distribute this software for any
6+
purpose with or without fee is hereby granted, provided that the above
7+
copyright notice and this permission notice appear in all copies.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
YoWASP JavaScript runtime
2+
=========================
3+
4+
This package is an internal support package for the [YoWASP project][yowasp]. It handles interfacing with the [WebAssembly][] runtime and the supported execution environments (Node.js and the browser). Do not depend on this package in your own code.
5+
6+
[webassembly]: https://webassembly.org/
7+
[yowasp]: https://yowasp.github.io/
8+
9+
10+
License
11+
-------
12+
13+
This package is covered by the [ISC license](LICENSE.txt).

bin/pack-resources.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env node
2+
3+
import { readdir, readFile, writeFile } from 'fs/promises';
4+
5+
async function packDirectory(root) {
6+
const files = await readdir(root, { withFileTypes: true });
7+
const packedFiles = {};
8+
for (const file of files) {
9+
const filePath = `${root}/${file.name}`;
10+
if (file.isDirectory())
11+
packedFiles[file.name] = await packDirectory(filePath);
12+
if (file.isFile())
13+
packedFiles[file.name] = await readFile(filePath, {encoding: 'utf-8'});
14+
}
15+
return packedFiles;
16+
}
17+
18+
const args = process.argv.slice(2);
19+
if (args.length !== 2) {
20+
console.error(`Usage: yowasp-pack-resources <directory> <file.json>`);
21+
process.exit(1);
22+
}
23+
24+
await writeFile(args[1], JSON.stringify(await packDirectory(args[0])));

lib/api-base.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Exit, Environment, directoryFromTree, directoryIntoTree } from './wasi-virt.js';
2+
3+
export { Exit } from './wasi-virt.js';
4+
5+
export class BaseApplication {
6+
constructor(getResources, wasmModules, instantiate) {
7+
this._resources = null;
8+
this.getResources = getResources;
9+
this.wasmModules = wasmModules;
10+
this.instantiate = instantiate;
11+
}
12+
13+
async run(args, files, printLine = console.log) {
14+
if (this._resources === null)
15+
this._resources = await this.getResources();
16+
17+
const environment = new Environment();
18+
environment.args = args;
19+
environment.root = directoryFromTree(files);
20+
for (const [dirName, resourceFiles] of Object.entries(this._resources))
21+
environment.root.files[dirName] = directoryFromTree(resourceFiles);
22+
environment.printLine = printLine;
23+
24+
const wasmCommand = await this.instantiate(
25+
(filename) => this.wasmModules[filename],
26+
{ runtime: environment.exports });
27+
try {
28+
wasmCommand.run.run();
29+
} catch (e) {
30+
if (!(e instanceof Exit && e.code === 0))
31+
throw e;
32+
}
33+
34+
for (const dirName of Object.keys(this._resources))
35+
delete environment.root[dirName];
36+
return directoryIntoTree(environment.root);
37+
}
38+
}

lib/api-browser.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { BaseApplication } from './api-base.js';
2+
3+
export { Exit } from './api-base.js';
4+
5+
export class Application extends BaseApplication {
6+
constructor(baseURL, resourceFilenames, wasmFilenames, instantiate) {
7+
async function getResources() {
8+
const resources = {};
9+
for (const [dirName, jsonFilename] of Object.entries(resourceFilenames))
10+
resources[dirName] = JSON.parse(await fetch(new URL(jsonFilename, baseURL)));
11+
return resources;
12+
}
13+
14+
const wasmModules = {};
15+
for (const [modName, wasmFilename] of Object.entries(wasmFilenames))
16+
wasmModules[modName] = fetch(new URL(wasmFilename, baseURL)).then(WebAssembly.compileStreaming);
17+
18+
super(getResources, wasmModules, instantiate);
19+
}
20+
}

lib/api-node.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { readFile } from 'fs/promises';
2+
import { BaseApplication } from './api-base.js';
3+
4+
export { Exit } from './api-base.js';
5+
6+
export class Application extends BaseApplication {
7+
constructor(baseURL, resourceFilenames, wasmFilenames, instantiate) {
8+
async function getResources() {
9+
const resources = {};
10+
for (const [dirName, jsonFilename] of Object.entries(resourceFilenames))
11+
resources[dirName] = JSON.parse(await readFile(new URL(jsonFilename, baseURL)));
12+
return resources;
13+
}
14+
15+
const wasmModules = {};
16+
for (const [modName, wasmFilename] of Object.entries(wasmFilenames))
17+
wasmModules[modName] = readFile(new URL(wasmFilename, baseURL)).then(WebAssembly.compile);
18+
19+
super(getResources, wasmModules, instantiate);
20+
}
21+
}

0 commit comments

Comments
 (0)