js-sdk
js-sdk copied to clipboard
Add 'fileDescriptors' option to allow file I/O to be used in the browser
This option is only used by wasi-browser.ts. It doesn't really make sense for node/deno/bun since those runtimes have native support for WASI.
I'm having issues running the tests so I haven't bothered trying to enable fileAccess for the browser tests.
I have done some manual testing to verify that things are working as expected. I have a plugin with the following F# cord:
[<UnmanagedCallersOnly(EntryPoint = "greet")>]
let Greet () : int32 =
printfn "Greet called"
let contents = File.ReadAllText("./input.txt")
printfn "contents = %s" contents
let input = Pdk.GetInputString()
printfn $"input = {input}"
let data = JsonSerializer.Deserialize<Data> input
printfn $"greeting = {data.greeting}, name = {data.name}"
let result = $"{data.greeting}, {data.name}!"
Pdk.SetOutput(result)
0
The JavaScript host code looks like this (note, this requires input.txt to exist in the directory being served):
import createPlugin from '@extism/extism';
import { WASI, File, OpenFile, ConsoleStdout, PreopenDirectory } from "@bjorn3/browser_wasi_shim";
const input = await fetch(`/input.txt`);
const inputBuffer = await input.arrayBuffer();
const url = new URL(`${location.protocol}/${location.host}/Plugin/bin/Debug/net8.0/wasi-wasm/AppBundle/Plugin.wasm`);
const options = {
useWasi: true,
enableWasiOutput: true,
fileDescriptors: [
new PreopenDirectory(".", {
"input.txt": new File(inputBuffer),
}),
]
};
const plugin = await createPlugin(url, options);
const input = JSON.stringify({ greeting: "hello", name: "world" });
const out = await plugin.call("greet", input);
console.log(out.text());
The output in the browser console looks like this:
Greet called
contents = This is a text file
input = {"greeting":"hello","name":"world"}
greeting = hello, name = world
hello, world!