UNPKG

wasmrs-js

Version:

A JavaScript implementation of the RSocket protocol over WebAssembly.

105 lines 3.43 kB
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck import { PreopenDirectory, WASI as WasiShim, SyncOPFSFile, Fd, } from '@candlecorp/browser_wasi_shim'; class CallbackFd extends Fd { fn; constructor(fn) { super(); this.fn = fn; } fd_write(view8, iovs) { let nwritten = 0; for (const iovec of iovs) { const buffer = view8.slice(iovec.buf, iovec.buf + iovec.buf_len); this.fn(new TextDecoder().decode(buffer)); nwritten += iovec.buf_len; } return { ret: 0, nwritten }; } } class NullFd extends Fd { constructor() { super(); } } async function openOpfsDirectory(root, to) { const files = {}; for await (const [name, item] of root.entries()) { if (item.kind === 'file') { const file = item; files[name] = new SyncOPFSFile(await file.createSyncAccessHandle()); } else if (item.kind === 'directory') { files[name] = await openOpfsDirectory(item, to + '/' + name); } else { throw new Error('Unknown item kind: ' + item.kind); } } return new PreopenDirectory(to, files); } export class WASI { wasi; constructor(wasi) { this.wasi = wasi; } static async create(options) { const opfsRoot = await navigator.storage.getDirectory(); const files = []; if (options.stdin === 0) { files.push(new NullFd()); } else if (options.stdin === undefined) { files.push(new NullFd()); } else { throw new Error('Unsupported stdin mode'); } if (options.stdout === 1) { files.push(new CallbackFd(console.log.bind(console, 'stdout: '))); } else if (options.stdin === undefined) { files.push(new NullFd()); } else { throw new Error('Unsupported stdout mode'); } if (options.stderr === 2) { files.push(new CallbackFd(console.error.bind(console, 'stderr: '))); } else if (options.stdin === undefined) { files.push(new NullFd()); } else { throw new Error('Unsupported stderr mode'); } for (const [to, from] of Object.entries(options.preopens || {})) { if (from.startsWith('opfs:')) { const opfsPath = from.slice(5); if (opfsPath === '/') { files.push(await openOpfsDirectory(opfsRoot, to)); } else { const root = await opfsRoot.getDirectoryHandle(opfsPath, { create: true, }); files.push(await openOpfsDirectory(root, to)); } } } const env = Object.entries(options.env || {}).map(([key, value]) => `${key}=${value}`); return new WASI(new WasiShim(options.args || [], env, files, { debug: true })); } // eslint-disable-next-line @typescript-eslint/no-explicit-any start(instance) { this.wasi.start(instance); } // eslint-disable-next-line @typescript-eslint/no-explicit-any initialize(instance) { this.wasi.initialize(instance); } getImports() { return this.wasi.wasiImport; } } //# sourceMappingURL=wasi.js.map