-
Notifications
You must be signed in to change notification settings - Fork 4
/
webr.js
69 lines (66 loc) · 2.71 KB
/
webr.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { create } from 'gc-hook';
import { dedent } from '../utils.js';
import { fetchFiles, fetchJSModules, fetchPaths } from './_utils.js';
import { io, stdio } from './_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 });
};
export default {
type,
experimental: true,
module: (version = '0.4.2') =>
`https://cdn.jsdelivr.net/npm/webr@${version}/dist/webr.mjs`,
async engine(module, config, _, baseURL) {
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, baseURL);
if (config.fetch) await fetchPaths(this, interpreter, config.fetch, baseURL);
if (config.js_modules) await fetchJSModules(config.js_modules, baseURL);
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 conversion
// 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 */