'use strict'; const { create } = require('gc-hook'); const { dedent } = require('../utils.js'); const { fetchFiles, fetchJSModules, fetchPaths } = require('./_utils.js'); const { io, stdio } = require('./_io.js'); const type = 'webr'; const r = new WeakMap(); // REQUIRES INTEGRATION TEST /* c8 ignore start */ const run = async (interpreter, code) => { const { shelter, destroy, io } = r.get(interpreter); const { output, result } = await shelter.captureR(dedent(code)); for (const { type, data } of output) io[type](data); // this is a double proxy but it's OK as the consumer // of the result here needs to invoke explicitly a conversion // or trust the `(await p.toJs()).values` returns what's expected. return create(result, destroy, { token: false }); }; module.exports = { type, experimental: true, module: (version = '0.3.3') => `https://cdn.jsdelivr.net/npm/webr@${version}/dist/webr.mjs`, async engine(module, config) { const { get } = stdio(); const interpreter = new module.WebR(); await get(interpreter.init().then(() => interpreter)); const shelter = await new interpreter.Shelter(); r.set(interpreter, { module, shelter, destroy: shelter.destroy.bind(shelter), io: io.get(interpreter), }); if (config.files) await fetchFiles(this, interpreter, config.files); if (config.fetch) await fetchPaths(this, interpreter, config.fetch); if (config.js_modules) await fetchJSModules(config.js_modules); return interpreter; }, // Fallback to globally defined module fields (i.e. $xworker) registerJSModule(_, name) { console.warn(`Experimental interpreter: module ${name} is not supported (yet)`); // TODO: as complex JS objects / modules are not allowed // it's not clear how we can bind anything or import a module // in a context that doesn't understand methods from JS // https://docs.r-wasm.org/webr/latest/convert-js-to-r.html#constructing-r-objects-from-javascript-objects }, run, runAsync: run, async runEvent(interpreter, code, event) { // TODO: WebR cannot convert exoteric objects or any literal // to an easy to reason about data/frame ... that convertion // is reserved for the future: // https://docs.r-wasm.org/webr/latest/convert-js-to-r.html#constructing-r-objects-from-javascript-objects await interpreter.evalRVoid(`${code}(event)`, { env: { event: { type: [ event.type ] } } }); }, transform: (_, value) => { console.log('transforming', value); return value; }, writeFile: () => { // MAYBE ??? }, }; /* c8 ignore stop */