feat(cli): improve the browser binding (#2056)
This commit is contained in:
parent
cd3a850dcb
commit
4ccbb61179
9 changed files with 65 additions and 32 deletions
|
@ -931,6 +931,7 @@ class Builder {
|
||||||
wasiRegisterFunctions,
|
wasiRegisterFunctions,
|
||||||
this.config.wasm?.initialMemory,
|
this.config.wasm?.initialMemory,
|
||||||
this.config.wasm?.maximumMemory,
|
this.config.wasm?.maximumMemory,
|
||||||
|
this.config.wasm?.browser?.fs,
|
||||||
) +
|
) +
|
||||||
idents
|
idents
|
||||||
.map(
|
.map(
|
||||||
|
|
|
@ -3,25 +3,33 @@ export const createWasiBrowserBinding = (
|
||||||
wasiRegisterFunctions: string[],
|
wasiRegisterFunctions: string[],
|
||||||
initialMemory = 4000,
|
initialMemory = 4000,
|
||||||
maximumMemory = 65536,
|
maximumMemory = 65536,
|
||||||
) => `import {
|
fs = false,
|
||||||
instantiateNapiModuleSync as __emnapiInstantiateNapiModuleSync,
|
) => {
|
||||||
getDefaultContext as __emnapiGetDefaultContext,
|
const fsImport = fs ? `import { memfs } from '@napi-rs/wasm-runtime/fs'` : ''
|
||||||
WASI as __WASI,
|
const wasiCreation = fs
|
||||||
} from '@napi-rs/wasm-runtime'
|
? `
|
||||||
import { Volume as __Volume, createFsFromVolume as __createFsFromVolume } from '@napi-rs/wasm-runtime/fs'
|
export const { fs: __fs, vol: __volume } = memfs()
|
||||||
|
|
||||||
import __wasmUrl from './${wasiFilename}.wasm?url'
|
|
||||||
|
|
||||||
const __fs = __createFsFromVolume(
|
|
||||||
__Volume.fromJSON({
|
|
||||||
'/': null,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const __wasi = new __WASI({
|
const __wasi = new __WASI({
|
||||||
version: 'preview1',
|
version: 'preview1',
|
||||||
fs: __fs,
|
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()
|
const __emnapiContext = __emnapiGetDefaultContext()
|
||||||
|
|
||||||
|
@ -66,6 +74,7 @@ ${wasiRegisterFunctions
|
||||||
.join('\n')}
|
.join('\n')}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
}
|
||||||
|
|
||||||
export const createWasiBinding = (
|
export const createWasiBinding = (
|
||||||
wasmFileName: string,
|
wasmFileName: string,
|
||||||
|
@ -88,11 +97,13 @@ const {
|
||||||
getDefaultContext: __emnapiGetDefaultContext,
|
getDefaultContext: __emnapiGetDefaultContext,
|
||||||
} = require('@napi-rs/wasm-runtime')
|
} = require('@napi-rs/wasm-runtime')
|
||||||
|
|
||||||
|
const __rootDir = __nodePath.parse(process.cwd()).root
|
||||||
|
|
||||||
const __wasi = new __nodeWASI({
|
const __wasi = new __nodeWASI({
|
||||||
version: 'preview1',
|
version: 'preview1',
|
||||||
env: process.env,
|
env: process.env,
|
||||||
preopens: {
|
preopens: {
|
||||||
'/': '/'
|
[__rootDir]: __rootDir,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,16 @@ export interface UserNapiConfig {
|
||||||
* @default 65536 pages (4GiB)
|
* @default 65536 pages (4GiB)
|
||||||
*/
|
*/
|
||||||
maximumMemory?: number
|
maximumMemory?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Browser wasm binding configuration
|
||||||
|
*/
|
||||||
|
browser: {
|
||||||
|
/**
|
||||||
|
* Whether to use fs module in browser
|
||||||
|
*/
|
||||||
|
fs?: boolean
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,11 +2,16 @@ import { describe, it, expect } from 'vitest'
|
||||||
|
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const {
|
const {
|
||||||
|
// @ts-expect-error
|
||||||
|
__fs,
|
||||||
|
// @ts-expect-error
|
||||||
|
__volume,
|
||||||
DEFAULT_COST,
|
DEFAULT_COST,
|
||||||
Bird,
|
Bird,
|
||||||
GetterSetterWithClosures,
|
GetterSetterWithClosures,
|
||||||
tsfnReturnPromise,
|
tsfnReturnPromise,
|
||||||
tsfnReturnPromiseTimeout,
|
tsfnReturnPromiseTimeout,
|
||||||
|
readFileAsync,
|
||||||
}: typeof import('../index.cjs') = await import('../example.wasi-browser')
|
}: typeof import('../index.cjs') = await import('../example.wasi-browser')
|
||||||
|
|
||||||
describe('NAPI-RS wasi browser test', function () {
|
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
|
// trigger Promise.then in Rust after `Promise` is dropped
|
||||||
await new Promise((resolve) => setTimeout(resolve, 400))
|
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')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,22 +3,17 @@ import {
|
||||||
getDefaultContext as __emnapiGetDefaultContext,
|
getDefaultContext as __emnapiGetDefaultContext,
|
||||||
WASI as __WASI,
|
WASI as __WASI,
|
||||||
} from '@napi-rs/wasm-runtime'
|
} from '@napi-rs/wasm-runtime'
|
||||||
import {
|
import { memfs } from '@napi-rs/wasm-runtime/fs'
|
||||||
Volume as __Volume,
|
|
||||||
createFsFromVolume as __createFsFromVolume,
|
|
||||||
} from '@napi-rs/wasm-runtime/fs'
|
|
||||||
|
|
||||||
import __wasmUrl from './example.wasm32-wasi.wasm?url'
|
import __wasmUrl from './example.wasm32-wasi.wasm?url'
|
||||||
|
|
||||||
const __fs = __createFsFromVolume(
|
export const { fs: __fs, vol: __volume } = memfs()
|
||||||
__Volume.fromJSON({
|
|
||||||
'/': null,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const __wasi = new __WASI({
|
const __wasi = new __WASI({
|
||||||
version: 'preview1',
|
version: 'preview1',
|
||||||
fs: __fs,
|
fs: __fs,
|
||||||
|
preopens: {
|
||||||
|
'/': '/',
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const __emnapiContext = __emnapiGetDefaultContext()
|
const __emnapiContext = __emnapiGetDefaultContext()
|
||||||
|
|
|
@ -13,11 +13,13 @@ const {
|
||||||
getDefaultContext: __emnapiGetDefaultContext,
|
getDefaultContext: __emnapiGetDefaultContext,
|
||||||
} = require('@napi-rs/wasm-runtime')
|
} = require('@napi-rs/wasm-runtime')
|
||||||
|
|
||||||
|
const __rootDir = __nodePath.parse(process.cwd()).root
|
||||||
|
|
||||||
const __wasi = new __nodeWASI({
|
const __wasi = new __nodeWASI({
|
||||||
version: 'preview1',
|
version: 'preview1',
|
||||||
env: process.env,
|
env: process.env,
|
||||||
preopens: {
|
preopens: {
|
||||||
'/': '/'
|
[__rootDir]: __rootDir,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@
|
||||||
"napi": {
|
"napi": {
|
||||||
"binaryName": "example",
|
"binaryName": "example",
|
||||||
"wasm": {
|
"wasm": {
|
||||||
"initialMemory": 16384
|
"initialMemory": 16384,
|
||||||
|
"browser": {
|
||||||
|
"fs": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"dtsHeader": "type MaybePromise<T> = T | Promise<T>",
|
"dtsHeader": "type MaybePromise<T> = T | Promise<T>",
|
||||||
"dtsHeaderFile": "./dts-header.d.ts"
|
"dtsHeaderFile": "./dts-header.d.ts"
|
||||||
|
|
|
@ -3,7 +3,7 @@ import {
|
||||||
Kind,
|
Kind,
|
||||||
asyncMultiTwo,
|
asyncMultiTwo,
|
||||||
tsfnReturnPromise,
|
tsfnReturnPromise,
|
||||||
} from './index.wasi-browser'
|
} from './example.wasi-browser'
|
||||||
|
|
||||||
console.info(new Animal(Kind.Cat, 'Tom'))
|
console.info(new Animal(Kind.Cat, 'Tom'))
|
||||||
asyncMultiTwo(200).then((res) => {
|
asyncMultiTwo(200).then((res) => {
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
Loading…
Reference in a new issue