feat(cli): improve the browser binding (#2056)

This commit is contained in:
LongYinan 2024-04-19 16:12:30 +08:00 committed by GitHub
parent cd3a850dcb
commit 4ccbb61179
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 65 additions and 32 deletions

View file

@ -931,6 +931,7 @@ class Builder {
wasiRegisterFunctions,
this.config.wasm?.initialMemory,
this.config.wasm?.maximumMemory,
this.config.wasm?.browser?.fs,
) +
idents
.map(

View file

@ -3,25 +3,33 @@ export const createWasiBrowserBinding = (
wasiRegisterFunctions: string[],
initialMemory = 4000,
maximumMemory = 65536,
) => `import {
instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
getDefaultContext as __emnapiGetDefaultContext,
WASI as __WASI,
} from '@napi-rs/wasm-runtime'
import { Volume as __Volume, createFsFromVolume as __createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
import __wasmUrl from './${wasiFilename}.wasm?url'
const __fs = __createFsFromVolume(
__Volume.fromJSON({
'/': null,
}),
)
fs = false,
) => {
const fsImport = fs ? `import { memfs } from '@napi-rs/wasm-runtime/fs'` : ''
const wasiCreation = fs
? `
export const { fs: __fs, vol: __volume } = memfs()
const __wasi = new __WASI({
version: 'preview1',
fs: __fs,
})
preopens: {
'/': '/',
}
})`
: `
const __wasi = new __WASI({
version: 'preview1',
})`
return `import {
instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
getDefaultContext as __emnapiGetDefaultContext,
WASI as __WASI,
} from '@napi-rs/wasm-runtime'
${fsImport}
import __wasmUrl from './${wasiFilename}.wasm?url'
${wasiCreation}
const __emnapiContext = __emnapiGetDefaultContext()
@ -66,6 +74,7 @@ ${wasiRegisterFunctions
.join('\n')}
}
`
}
export const createWasiBinding = (
wasmFileName: string,
@ -88,11 +97,13 @@ const {
getDefaultContext: __emnapiGetDefaultContext,
} = require('@napi-rs/wasm-runtime')
const __rootDir = __nodePath.parse(process.cwd()).root
const __wasi = new __nodeWASI({
version: 'preview1',
env: process.env,
preopens: {
'/': '/'
[__rootDir]: __rootDir,
}
})

View file

@ -66,6 +66,16 @@ export interface UserNapiConfig {
* @default 65536 pages (4GiB)
*/
maximumMemory?: number
/**
* Browser wasm binding configuration
*/
browser: {
/**
* Whether to use fs module in browser
*/
fs?: boolean
}
}
/**

View file

@ -2,11 +2,16 @@ import { describe, it, expect } from 'vitest'
// @ts-expect-error
const {
// @ts-expect-error
__fs,
// @ts-expect-error
__volume,
DEFAULT_COST,
Bird,
GetterSetterWithClosures,
tsfnReturnPromise,
tsfnReturnPromiseTimeout,
readFileAsync,
}: typeof import('../index.cjs') = await import('../example.wasi-browser')
describe('NAPI-RS wasi browser test', function () {
@ -53,4 +58,10 @@ describe('NAPI-RS wasi browser test', function () {
// trigger Promise.then in Rust after `Promise` is dropped
await new Promise((resolve) => setTimeout(resolve, 400))
})
it.skip('readFileAsync', async () => {
__volume.writeFileSync('/test.txt', 'hello world')
const value = await readFileAsync('/test.txt')
expect(value).toBe('hello world')
})
})

View file

@ -3,22 +3,17 @@ import {
getDefaultContext as __emnapiGetDefaultContext,
WASI as __WASI,
} from '@napi-rs/wasm-runtime'
import {
Volume as __Volume,
createFsFromVolume as __createFsFromVolume,
} from '@napi-rs/wasm-runtime/fs'
import { memfs } from '@napi-rs/wasm-runtime/fs'
import __wasmUrl from './example.wasm32-wasi.wasm?url'
const __fs = __createFsFromVolume(
__Volume.fromJSON({
'/': null,
}),
)
export const { fs: __fs, vol: __volume } = memfs()
const __wasi = new __WASI({
version: 'preview1',
fs: __fs,
preopens: {
'/': '/',
},
})
const __emnapiContext = __emnapiGetDefaultContext()

View file

@ -13,11 +13,13 @@ const {
getDefaultContext: __emnapiGetDefaultContext,
} = require('@napi-rs/wasm-runtime')
const __rootDir = __nodePath.parse(process.cwd()).root
const __wasi = new __nodeWASI({
version: 'preview1',
env: process.env,
preopens: {
'/': '/'
[__rootDir]: __rootDir,
}
})

View file

@ -13,7 +13,10 @@
"napi": {
"binaryName": "example",
"wasm": {
"initialMemory": 16384
"initialMemory": 16384,
"browser": {
"fs": true
}
},
"dtsHeader": "type MaybePromise<T> = T | Promise<T>",
"dtsHeaderFile": "./dts-header.d.ts"

View file

@ -3,7 +3,7 @@ import {
Kind,
asyncMultiTwo,
tsfnReturnPromise,
} from './index.wasi-browser'
} from './example.wasi-browser'
console.info(new Animal(Kind.Cat, 'Tom'))
asyncMultiTwo(200).then((res) => {

View file

@ -1,5 +1,5 @@
import * as memfs from 'memfs'
import * as memfsExported from 'memfs'
const { createFsFromVolume, Volume, fs } = memfs
const { createFsFromVolume, Volume, fs, memfs } = memfsExported
export { createFsFromVolume, Volume, fs }
export { createFsFromVolume, Volume, fs, memfs }