Skip to content

Commit

Permalink
feat(*): support wasi-wasm32 target (#752)
Browse files Browse the repository at this point in the history
* feat(*): support wasi-wasm32 target

* patch

* fix filter
  • Loading branch information
Brooooooklyn committed Jan 2, 2024
1 parent d38c394 commit 12f25b5
Show file tree
Hide file tree
Showing 148 changed files with 1,776 additions and 549 deletions.
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ coverage
target
packages/deno-lint/cli.js
packages/deno-lint/cli.d.ts
packages/*/*.wasi.cjs
packages/*/wasi-worker.mjs
packages/*/index.js
packages/*/index.d.ts
47 changes: 47 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ jobs:
- host: windows-latest
target: 'aarch64-pc-windows-msvc'
build: yarn build --target aarch64-pc-windows-msvc
- host: ubuntu-latest
target: 'wasm32-wasi-preview1-threads'
build: yarn workspaces foreach -A --no-private -j 1 --exclude "@node-rs/{jsonwebtoken,deno-lint}" run build --target wasm32-wasi-preview1-threads

name: stable - ${{ matrix.settings.target }} - node@20
runs-on: ${{ matrix.settings.host }}
Expand Down Expand Up @@ -133,11 +136,20 @@ jobs:

- name: Upload artifact
uses: actions/upload-artifact@v4
if: ${{ matrix.settings.target != 'wasm32-wasi-preview1-threads' }}
with:
name: bindings-${{ matrix.settings.target }}
path: packages/*/*.node
if-no-files-found: error

- name: Upload artifact
uses: actions/upload-artifact@v4
if: ${{ matrix.settings.target == 'wasm32-wasi-preview1-threads' }}
with:
name: bindings-${{ matrix.settings.target }}
path: packages/*/*.wasm
if-no-files-found: error

build-freebsd:
runs-on: macos-12
name: Build FreeBSD
Expand Down Expand Up @@ -520,6 +532,40 @@ jobs:
yarn test -s
ls -la
test-wasi-nodejs:
name: Test bindings on wasi - node@${{ matrix.node }}
needs:
- build
strategy:
fail-fast: false
matrix:
node: ['18', '20']
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: yarn
- name: 'Install dependencies'
run: yarn install --immutable --mode=skip-build
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: bindings-wasm32-wasi-preview1-threads
path: artifacts
- name: Move artifacts
run: yarn artifacts
shell: bash
- name: List packages
run: ls -R .
- name: Test
run: |
yarn build:ts
yarn test -s
env:
NAPI_RS_FORCE_WASI: 'true'

publish:
name: Publish
runs-on: ubuntu-latest
Expand All @@ -532,6 +578,7 @@ jobs:
- test-linux-aarch64-musl-binding
- test-linux-arm-gnueabihf-binding
- test-macOS-windows-binding
- test-wasi-nodejs
steps:
- uses: actions/checkout@v4

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ temp/
# End of https://www.gitignore.io/api/node

*.node
*.wasm
lib
artifacts

Expand All @@ -186,4 +187,4 @@ artifacts
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
!.yarn/versions
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@ node_modules
lib
.yarn
yarn.lock
packages/*/*.wasi.js
packages/*/index.js
packages/*/index.d.ts
8 changes: 7 additions & 1 deletion ava.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default {
const avaConfig = {
extensions: ['ts'],
workerThreads: false,
cache: false,
Expand All @@ -9,3 +9,9 @@ export default {
TS_NODE_PROJECT: './tsconfig.test.json',
},
}

if (process.env.NAPI_RS_FORCE_WASI) {
avaConfig.files.push(`!packages/jsonwebtoken/**/*.spec.ts`)
}

export default avaConfig
2 changes: 1 addition & 1 deletion crates/alloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ version = "0.1.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[target.'cfg(not(target_os = "linux"))'.dependencies]
[target.'cfg(all(not(target_os = "linux"), not(target_family = "wasm")))'.dependencies]
mimalloc = { version = "0.1" }

[target.'cfg(target_os = "linux")'.dependencies]
Expand Down
1 change: 1 addition & 0 deletions crates/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
#[cfg(not(target_family = "wasm"))]
#[global_allocator]
static ALLOC: mimalloc::MiMalloc = mimalloc::MiMalloc;
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"postinstall": "husky install"
},
"devDependencies": {
"@napi-rs/cli": "^3.0.0-alpha.25",
"@emnapi/core": "^0.45.0",
"@emnapi/runtime": "^0.45.0",
"@napi-rs/cli": "^3.0.0-alpha.29",
"@swc-node/core": "^1.10.6",
"@swc-node/register": "^1.6.8",
"@swc/core": "^1.3.101",
Expand Down
93 changes: 93 additions & 0 deletions packages/argon2/argon2.wasi.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/* eslint-disable */
/* prettier-ignore */

/* auto-generated by NAPI-RS */

const __nodeFs= require('node:fs')
const __nodePath = require('node:path')
const { WASI: __nodeWASI } = require('node:wasi')
const { Worker } = require('node:worker_threads')

const { instantiateNapiModuleSync: __emnapiInstantiateNapiModuleSync } = require('@emnapi/core')
const { getDefaultContext: __emnapiGetDefaultContext } = require('@emnapi/runtime')

const __wasi = new __nodeWASI({
version: 'preview1',
env: process.env,
preopens: {
'/': '/'
}
})

const __emnapiContext = __emnapiGetDefaultContext()

const __sharedMemory = new WebAssembly.Memory({
initial: 1024,
maximum: 10240,
shared: true,
})

let __wasmFilePath = __nodePath.join(__dirname, 'argon2.wasm32-wasi.wasm')

if (!__nodeFs.existsSync(__wasmFilePath)) {
try {
__wasmFilePath = __nodePath.resolve('@node-rs/argon2-wasm32-wasi')
} catch {
throw new Error('Cannot find argon2.wasm32-wasi.wasm file, and @node-rs/argon2-wasm32-wasi package is not installed.')
}
}

const { instance: __napiInstance, module: __wasiModule, napiModule: __napiModule } = __emnapiInstantiateNapiModuleSync(__nodeFs.readFileSync(__wasmFilePath), {
context: __emnapiContext,
asyncWorkPoolSize: (function() {
const threadsSizeFromEnv = Number(process.env.NAPI_RS_ASYNC_WORK_POOL_SIZE ?? process.env.UV_THREADPOOL_SIZE)
// NaN > 0 is false
if (threadsSizeFromEnv > 0) {
return threadsSizeFromEnv
} else {
return 4
}
})(),
wasi: __wasi,
onCreateWorker() {
return new Worker(__nodePath.join(__dirname, 'wasi-worker.mjs'), {
env: process.env,
execArgv: ['--experimental-wasi-unstable-preview1'],
})
},
overwriteImports(importObject) {
importObject.env = {
...importObject.env,
...importObject.napi,
...importObject.emnapi,
memory: __sharedMemory,
}
return importObject
},
beforeInit({ instance }) {
__napi_rs_initialize_modules(instance)
}
})

function __napi_rs_initialize_modules(__napiInstance) {
__napiInstance.exports['__napi_register__Algorithm_0']?.()
__napiInstance.exports['__napi_register__Version_1']?.()
__napiInstance.exports['__napi_register__Options_struct_2']?.()
__napiInstance.exports['__napi_register__HashTask_impl_3']?.()
__napiInstance.exports['__napi_register__hash_4']?.()
__napiInstance.exports['__napi_register__hash_sync_5']?.()
__napiInstance.exports['__napi_register__RawHashTask_impl_6']?.()
__napiInstance.exports['__napi_register__hash_raw_7']?.()
__napiInstance.exports['__napi_register__hash_raw_sync_8']?.()
__napiInstance.exports['__napi_register__VerifyTask_impl_9']?.()
__napiInstance.exports['__napi_register__verify_10']?.()
__napiInstance.exports['__napi_register__verify_sync_11']?.()
}
module.exports.Algorithm = __napiModule.exports.Algorithm,
module.exports.hash = __napiModule.exports.hash,
module.exports.hashRaw = __napiModule.exports.hashRaw,
module.exports.hashRawSync = __napiModule.exports.hashRawSync,
module.exports.hashSync = __napiModule.exports.hashSync,
module.exports.verify = __napiModule.exports.verify,
module.exports.verifySync = __napiModule.exports.verifySync,
module.exports.Version = __napiModule.exports.Version
30 changes: 7 additions & 23 deletions packages/argon2/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,12 @@ export const enum Algorithm {
* Hybrid that mixes Argon2i and Argon2d passes.
* Uses the Argon2i approach for the first half pass over memory and Argon2d approach for subsequent passes. This effectively places it in the “middle” between the other two: it doesn’t provide as good TMTO/GPU cracking resistance as Argon2d, nor as good of side-channel resistance as Argon2i, but overall provides the most well-rounded approach to both classes of attacks.
*/
Argon2id = 2,
Argon2id = 2
}

export function hash(
password: string | Buffer,
options?: Options | undefined | null,
abortSignal?: AbortSignal | undefined | null,
): Promise<string>
export function hash(password: string | Buffer, options?: Options | undefined | null, abortSignal?: AbortSignal | undefined | null): Promise<string>

export function hashRaw(
password: string | Buffer,
options?: Options | undefined | null,
abortSignal?: AbortSignal | undefined | null,
): Promise<Buffer>
export function hashRaw(password: string | Buffer, options?: Options | undefined | null, abortSignal?: AbortSignal | undefined | null): Promise<Buffer>

export function hashRawSync(password: string | Buffer, options?: Options | undefined | null): Buffer

Expand Down Expand Up @@ -73,18 +65,9 @@ export interface Options {
salt?: Buffer
}

export function verify(
hashed: string | Buffer,
password: string | Buffer,
options?: Options | undefined | null,
abortSignal?: AbortSignal | undefined | null,
): Promise<boolean>
export function verify(hashed: string | Buffer, password: string | Buffer, options?: Options | undefined | null, abortSignal?: AbortSignal | undefined | null): Promise<boolean>

export function verifySync(
hashed: string | Buffer,
password: string | Buffer,
options?: Options | undefined | null,
): boolean
export function verifySync(hashed: string | Buffer, password: string | Buffer, options?: Options | undefined | null): boolean

export const enum Version {
/** Version 16 (0x10 in hex) */
Expand All @@ -93,5 +76,6 @@ export const enum Version {
* Default value
* Version 19 (0x13 in hex)
*/
V0x13 = 1,
V0x13 = 1
}

0 comments on commit 12f25b5

Please sign in to comment.