woxi-wasm 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +64 -0
- package/index.js +174 -0
- package/package.json +40 -0
- package/pkg/woxi.d.ts +111 -0
- package/pkg/woxi.js +858 -0
- package/pkg/woxi_bg.wasm +0 -0
- package/pkg/woxi_bg.wasm.d.ts +28 -0
- package/readme.md +111 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** One structured output item produced by evaluating a statement. */
|
|
2
|
+
export interface OutputItem {
|
|
3
|
+
/** Kind of output this item carries. */
|
|
4
|
+
type:
|
|
5
|
+
| "text"
|
|
6
|
+
| "graphics"
|
|
7
|
+
| "print"
|
|
8
|
+
| "warning"
|
|
9
|
+
| "error"
|
|
10
|
+
| "sound"
|
|
11
|
+
| "manipulate";
|
|
12
|
+
/** Textual content (present for text/print/warning/error items). */
|
|
13
|
+
text?: string;
|
|
14
|
+
/** SVG markup (present for graphics items and rich text renderings). */
|
|
15
|
+
svg?: string;
|
|
16
|
+
/** Base64-encoded audio data (present for sound items). */
|
|
17
|
+
audio?: string;
|
|
18
|
+
/** MIME type of the audio data (present for sound items). */
|
|
19
|
+
mime?: string;
|
|
20
|
+
/** Label shown next to the audio player (optional on sound items). */
|
|
21
|
+
label?: string;
|
|
22
|
+
/** Additional fields (e.g. the Manipulate widget spec). */
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Evaluate one or more Wolfram Language statements and return the combined
|
|
28
|
+
* output (Print output followed by the final result) as a string.
|
|
29
|
+
* Evaluation errors are returned as a string starting with "Error: ".
|
|
30
|
+
*/
|
|
31
|
+
export function evaluate(code: string): string;
|
|
32
|
+
|
|
33
|
+
/** Evaluate all top-level statements and return structured output items. */
|
|
34
|
+
export function evaluateAll(code: string): OutputItem[];
|
|
35
|
+
|
|
36
|
+
/** Split code into top-level statements (for progressive evaluation). */
|
|
37
|
+
export function splitStatements(code: string): string[];
|
|
38
|
+
|
|
39
|
+
/** Evaluate a single statement, returning structured output items. */
|
|
40
|
+
export function evaluateStatement(statement: string): OutputItem[];
|
|
41
|
+
|
|
42
|
+
/** SVG graphics captured by the last evaluate() call ("" when none). */
|
|
43
|
+
export function getGraphics(): string;
|
|
44
|
+
|
|
45
|
+
/** Base64-encoded audio captured by the last evaluate() call ("" when none). */
|
|
46
|
+
export function getSound(): string;
|
|
47
|
+
|
|
48
|
+
/** Warnings emitted by the last evaluate() call. */
|
|
49
|
+
export function getWarnings(): string[];
|
|
50
|
+
|
|
51
|
+
/** Clear all interpreter state (variables and function definitions). */
|
|
52
|
+
export function clear(): void;
|
|
53
|
+
|
|
54
|
+
/** Toggle dark-mode colors for SVG output. */
|
|
55
|
+
export function setDarkMode(enabled: boolean): void;
|
|
56
|
+
|
|
57
|
+
/** Register an in-memory file so `Import["name"]` can read it. */
|
|
58
|
+
export function setVirtualFile(
|
|
59
|
+
name: string,
|
|
60
|
+
data: string | Uint8Array | ArrayBuffer,
|
|
61
|
+
): void;
|
|
62
|
+
|
|
63
|
+
/** Remove all files registered with setVirtualFile(). */
|
|
64
|
+
export function clearVirtualFiles(): void;
|
package/index.js
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// JavaScript wrapper around the Woxi WebAssembly build (see ../src/wasm.rs).
|
|
2
|
+
//
|
|
3
|
+
// The generated bindings in pkg/ (built by `make npm-build` in the repo
|
|
4
|
+
// root) expose the raw wasm-bindgen functions. This module adds:
|
|
5
|
+
//
|
|
6
|
+
// - camelCase names and JSON parsing for the structured APIs
|
|
7
|
+
// - a Node implementation of the `__woxi_fetch_url` host hook, so
|
|
8
|
+
// `Import["https://..."]` works out of the box
|
|
9
|
+
// - panic recovery: a Rust panic leaves the wasm instance unusable, so the
|
|
10
|
+
// wrapper converts it into a JS Error carrying the panic message and
|
|
11
|
+
// transparently loads a fresh instance on the next call
|
|
12
|
+
|
|
13
|
+
"use strict"
|
|
14
|
+
|
|
15
|
+
const path = require("node:path")
|
|
16
|
+
|
|
17
|
+
const PKG_ENTRY = path.join(__dirname, "pkg", "woxi.js")
|
|
18
|
+
|
|
19
|
+
let lastPanicMessage = null
|
|
20
|
+
|
|
21
|
+
// Host hook called by the wasm panic hook right before the trap fires.
|
|
22
|
+
if (typeof globalThis.__woxi_report_panic !== "function") {
|
|
23
|
+
globalThis.__woxi_report_panic = (msg) => {
|
|
24
|
+
lastPanicMessage = msg
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Host hook used by `Import["https://..."]`: fetch a URL synchronously and
|
|
29
|
+
// return its body base64-encoded. The wasm side is fully synchronous, so we
|
|
30
|
+
// shell out to a child Node process that performs the async fetch.
|
|
31
|
+
if (typeof globalThis.__woxi_fetch_url !== "function") {
|
|
32
|
+
globalThis.__woxi_fetch_url = (url) => {
|
|
33
|
+
const { execFileSync } = require("node:child_process")
|
|
34
|
+
const script = `
|
|
35
|
+
fetch(process.argv[1])
|
|
36
|
+
.then((res) => {
|
|
37
|
+
if (!res.ok) throw new Error("HTTP status " + res.status)
|
|
38
|
+
return res.arrayBuffer()
|
|
39
|
+
})
|
|
40
|
+
.then((buf) => process.stdout.write(Buffer.from(buf).toString("base64")))
|
|
41
|
+
.catch((err) => { process.stderr.write(String(err.message || err)); process.exit(1) })
|
|
42
|
+
`
|
|
43
|
+
try {
|
|
44
|
+
return execFileSync(process.execPath, ["-e", script, url], {
|
|
45
|
+
encoding: "utf8",
|
|
46
|
+
maxBuffer: 512 * 1024 * 1024,
|
|
47
|
+
})
|
|
48
|
+
} catch (err) {
|
|
49
|
+
const stderr = err.stderr ? String(err.stderr).trim() : ""
|
|
50
|
+
throw new Error(stderr || `failed to fetch ${url}`)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let wasm = null
|
|
56
|
+
|
|
57
|
+
function getWasm() {
|
|
58
|
+
if (wasm === null) {
|
|
59
|
+
// Drop stale copies from the require cache so that a reload after a
|
|
60
|
+
// panic instantiates a fresh wasm instance instead of the broken one.
|
|
61
|
+
delete require.cache[require.resolve(PKG_ENTRY)]
|
|
62
|
+
wasm = require(PKG_ENTRY)
|
|
63
|
+
}
|
|
64
|
+
return wasm
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Run a raw wasm call, translating a Rust panic (which surfaces as a
|
|
68
|
+
// WebAssembly "unreachable" RuntimeError) into a descriptive JS Error and
|
|
69
|
+
// discarding the now-broken instance.
|
|
70
|
+
function guarded(fn) {
|
|
71
|
+
lastPanicMessage = null
|
|
72
|
+
try {
|
|
73
|
+
return fn(getWasm())
|
|
74
|
+
} catch (err) {
|
|
75
|
+
if (lastPanicMessage !== null) {
|
|
76
|
+
wasm = null // instance is poisoned - reload lazily on the next call
|
|
77
|
+
throw new Error(`Woxi crashed while evaluating: ${lastPanicMessage}`, {
|
|
78
|
+
cause: err,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
throw err
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Evaluate one or more Wolfram Language statements and return the combined
|
|
87
|
+
* output (Print output followed by the final result) as a string.
|
|
88
|
+
*/
|
|
89
|
+
function evaluate(code) {
|
|
90
|
+
return guarded((w) => w.evaluate(code))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Evaluate all top-level statements and return structured output items
|
|
95
|
+
* ({type: "text" | "graphics" | "print" | "warning" | "error" | ...}).
|
|
96
|
+
*/
|
|
97
|
+
function evaluateAll(code) {
|
|
98
|
+
return JSON.parse(guarded((w) => w.evaluate_all(code)))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Split code into top-level statements (for progressive evaluation). */
|
|
102
|
+
function splitStatements(code) {
|
|
103
|
+
return JSON.parse(guarded((w) => w.split_statements(code)))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Evaluate a single statement, returning structured output items. */
|
|
107
|
+
function evaluateStatement(statement) {
|
|
108
|
+
return JSON.parse(guarded((w) => w.evaluate_statement(statement)))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** SVG graphics captured by the last evaluate() call ("" when none). */
|
|
112
|
+
function getGraphics() {
|
|
113
|
+
return guarded((w) => w.get_graphics())
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Base64-encoded audio captured by the last evaluate() call ("" when none). */
|
|
117
|
+
function getSound() {
|
|
118
|
+
return guarded((w) => w.get_sound())
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Warnings emitted by the last evaluate() call. */
|
|
122
|
+
function getWarnings() {
|
|
123
|
+
const text = guarded((w) => w.get_warnings())
|
|
124
|
+
return text === "" ? [] : text.split("\n")
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Clear all interpreter state (variables and function definitions). */
|
|
128
|
+
function clear() {
|
|
129
|
+
guarded((w) => w.clear())
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Toggle dark-mode colors for SVG output. */
|
|
133
|
+
function setDarkMode(enabled) {
|
|
134
|
+
guarded((w) => w.set_dark_mode(enabled))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Register an in-memory file so `Import["name"]` can read it. `data` may be
|
|
139
|
+
* a string, Buffer, Uint8Array, or ArrayBuffer.
|
|
140
|
+
*/
|
|
141
|
+
function setVirtualFile(name, data) {
|
|
142
|
+
let bytes
|
|
143
|
+
if (typeof data === "string") {
|
|
144
|
+
bytes = new TextEncoder().encode(data)
|
|
145
|
+
} else if (data instanceof Uint8Array) {
|
|
146
|
+
bytes = data
|
|
147
|
+
} else if (data instanceof ArrayBuffer) {
|
|
148
|
+
bytes = new Uint8Array(data)
|
|
149
|
+
} else {
|
|
150
|
+
throw new TypeError(
|
|
151
|
+
"setVirtualFile data must be a string, Uint8Array, Buffer, or ArrayBuffer",
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
guarded((w) => w.set_virtual_file(name, bytes))
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** Remove all files registered with setVirtualFile(). */
|
|
158
|
+
function clearVirtualFiles() {
|
|
159
|
+
guarded((w) => w.clear_virtual_files())
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = {
|
|
163
|
+
evaluate,
|
|
164
|
+
evaluateAll,
|
|
165
|
+
splitStatements,
|
|
166
|
+
evaluateStatement,
|
|
167
|
+
getGraphics,
|
|
168
|
+
getSound,
|
|
169
|
+
getWarnings,
|
|
170
|
+
clear,
|
|
171
|
+
setDarkMode,
|
|
172
|
+
setVirtualFile,
|
|
173
|
+
clearVirtualFiles,
|
|
174
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "woxi-wasm",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Interpreter for a subset of the Wolfram Language, compiled to WebAssembly",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"wolfram",
|
|
7
|
+
"wolfram-language",
|
|
8
|
+
"mathematica",
|
|
9
|
+
"cas",
|
|
10
|
+
"math",
|
|
11
|
+
"interpreter",
|
|
12
|
+
"wasm"
|
|
13
|
+
],
|
|
14
|
+
"license": "AGPL-3.0-or-later",
|
|
15
|
+
"author": "Adrian Sieber",
|
|
16
|
+
"homepage": "https://woxi.ad-si.com",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/ad-si/Woxi.git",
|
|
20
|
+
"directory": "npm"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/ad-si/Woxi/issues"
|
|
24
|
+
},
|
|
25
|
+
"main": "index.js",
|
|
26
|
+
"types": "index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"index.js",
|
|
29
|
+
"index.d.ts",
|
|
30
|
+
"pkg/"
|
|
31
|
+
],
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "make -C .. npm-build",
|
|
37
|
+
"test": "node --test",
|
|
38
|
+
"prepublishOnly": "node -e \"require('./pkg/woxi.js')\" || (echo 'pkg/ is missing - run `make npm-build` in the repo root first' && exit 1)"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/pkg/woxi.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Render a Manipulate body, its extra display elements, and any pending
|
|
5
|
+
* interactive write-backs in one call. Used by widgets that have display
|
|
6
|
+
* elements (e.g. a `Checkbox` grid) that both read and rewrite shared
|
|
7
|
+
* state.
|
|
8
|
+
*
|
|
9
|
+
* `displays_json` and `mutations_json` are JSON string arrays. Each
|
|
10
|
+
* mutation is an assignment (e.g. `data[[3, 5]] = 1`) applied before the
|
|
11
|
+
* re-render; the updated value of every mutated variable is returned under
|
|
12
|
+
* `state` so the frontend can keep its binding set in sync.
|
|
13
|
+
*
|
|
14
|
+
* The result is `{"output":{svg|text|textSvg}, "displays":[<tree>…],
|
|
15
|
+
* "state":{name:value,…}}`.
|
|
16
|
+
*/
|
|
17
|
+
export function evaluate_manipulate_full(body: string, displays_json: string, bindings_json: string, mutations_json: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Register (or replace) an in-memory file so `Import["name"]` can read it
|
|
20
|
+
* in the browser.
|
|
21
|
+
*/
|
|
22
|
+
export function set_virtual_file(name: string, data: Uint8Array): void;
|
|
23
|
+
/**
|
|
24
|
+
* Return the captured SVG graphics from the last `evaluate()` call, if any.
|
|
25
|
+
* Returns an empty string when there is no graphics output.
|
|
26
|
+
*/
|
|
27
|
+
export function get_graphics(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Evaluate all top-level statements and return a JSON array of output items.
|
|
30
|
+
* Each item has a "type" field ("text", "graphics", "print", "warning", "error",
|
|
31
|
+
* "manipulate") and corresponding content fields.
|
|
32
|
+
*/
|
|
33
|
+
export function evaluate_all(input: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Evaluate a single statement and return a JSON array of output items
|
|
36
|
+
* (same shape as `evaluate_all`'s elements). Use together with
|
|
37
|
+
* `split_statements` for progressive output.
|
|
38
|
+
*/
|
|
39
|
+
export function evaluate_statement(stmt: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* Split `input` into top-level statements and return a JSON array of strings.
|
|
42
|
+
* Lets the front-end loop one statement at a time so output (and side
|
|
43
|
+
* effects like `Pause[n]`) appear progressively rather than batched.
|
|
44
|
+
*/
|
|
45
|
+
export function split_statements(input: string): string;
|
|
46
|
+
/**
|
|
47
|
+
* Remove all host-registered in-memory files.
|
|
48
|
+
*/
|
|
49
|
+
export function clear_virtual_files(): void;
|
|
50
|
+
/**
|
|
51
|
+
* Evaluate a Manipulate body with a specific set of variable bindings
|
|
52
|
+
* and return a single JSON output item representing the result.
|
|
53
|
+
*
|
|
54
|
+
* `body` must be the body expression in InputForm (as produced by
|
|
55
|
+
* `evaluate_all`'s manipulate item). `bindings_json` must be a JSON
|
|
56
|
+
* object mapping variable names to InputForm-serialized values, e.g.
|
|
57
|
+
* `{"a": "1.5", "b": "\"foo\""}`.
|
|
58
|
+
*
|
|
59
|
+
* The result is a JSON object of the same shape as `initial` from
|
|
60
|
+
* the evaluate_all manipulate item: `{"svg": "...", "text": "..."}`.
|
|
61
|
+
*/
|
|
62
|
+
export function evaluate_manipulate(body: string, bindings_json: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Evaluate, returning only the final expression result (no Print output).
|
|
65
|
+
*/
|
|
66
|
+
export function evaluate_expr(input: string): string;
|
|
67
|
+
/**
|
|
68
|
+
* Return SVG rendering of the last text result (with superscripts etc.).
|
|
69
|
+
* Returns an empty string when there is no output SVG (e.g. for Graphics results).
|
|
70
|
+
*/
|
|
71
|
+
export function get_output_svg(): string;
|
|
72
|
+
/**
|
|
73
|
+
* Enable or disable dark mode for SVG output colors.
|
|
74
|
+
*/
|
|
75
|
+
export function set_dark_mode(enabled: boolean): void;
|
|
76
|
+
/**
|
|
77
|
+
* Evaluate a Wolfram Language expression and return the result.
|
|
78
|
+
* If the expression produces Print output, it is prepended to the result.
|
|
79
|
+
*/
|
|
80
|
+
export function evaluate(input: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Return warnings from the last `evaluate()` call as newline-separated text.
|
|
83
|
+
* Returns an empty string when there are no warnings.
|
|
84
|
+
*/
|
|
85
|
+
export function get_warnings(): string;
|
|
86
|
+
/**
|
|
87
|
+
* Return the playable audio (base64-encoded) from the last `evaluate()`
|
|
88
|
+
* call, if any. Returns an empty string when there is no sound.
|
|
89
|
+
*/
|
|
90
|
+
export function get_sound(): string;
|
|
91
|
+
/**
|
|
92
|
+
* Clear all interpreter state (variables and function definitions).
|
|
93
|
+
*/
|
|
94
|
+
export function clear(): void;
|
|
95
|
+
export function init(): void;
|
|
96
|
+
/**
|
|
97
|
+
* Evaluate each Manipulate control's `Enabled` condition against a binding
|
|
98
|
+
* set and return a JSON array of booleans (one per control, in order).
|
|
99
|
+
*
|
|
100
|
+
* `conditions_json` is a JSON string array aligned with the control list;
|
|
101
|
+
* an empty string marks a control with no condition (always enabled).
|
|
102
|
+
* `bindings_json` is the same JSON object of variable bindings used by
|
|
103
|
+
* `evaluate_manipulate`. Used by the Playground to grey out controls that a
|
|
104
|
+
* `Enabled -> Dynamic[…]` option has switched off for the current state.
|
|
105
|
+
*/
|
|
106
|
+
export function evaluate_manipulate_enabled(conditions_json: string, bindings_json: string): string;
|
|
107
|
+
/**
|
|
108
|
+
* Return the captured GraphicsBox expression from the last `evaluate()` call.
|
|
109
|
+
* Returns an empty string when there is no graphics output.
|
|
110
|
+
*/
|
|
111
|
+
export function get_graphicsbox(): string;
|
package/pkg/woxi.js
ADDED
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
|
|
2
|
+
let imports = {};
|
|
3
|
+
imports['__wbindgen_placeholder__'] = module.exports;
|
|
4
|
+
|
|
5
|
+
function debugString(val) {
|
|
6
|
+
// primitive types
|
|
7
|
+
const type = typeof val;
|
|
8
|
+
if (type == 'number' || type == 'boolean' || val == null) {
|
|
9
|
+
return `${val}`;
|
|
10
|
+
}
|
|
11
|
+
if (type == 'string') {
|
|
12
|
+
return `"${val}"`;
|
|
13
|
+
}
|
|
14
|
+
if (type == 'symbol') {
|
|
15
|
+
const description = val.description;
|
|
16
|
+
if (description == null) {
|
|
17
|
+
return 'Symbol';
|
|
18
|
+
} else {
|
|
19
|
+
return `Symbol(${description})`;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (type == 'function') {
|
|
23
|
+
const name = val.name;
|
|
24
|
+
if (typeof name == 'string' && name.length > 0) {
|
|
25
|
+
return `Function(${name})`;
|
|
26
|
+
} else {
|
|
27
|
+
return 'Function';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// objects
|
|
31
|
+
if (Array.isArray(val)) {
|
|
32
|
+
const length = val.length;
|
|
33
|
+
let debug = '[';
|
|
34
|
+
if (length > 0) {
|
|
35
|
+
debug += debugString(val[0]);
|
|
36
|
+
}
|
|
37
|
+
for(let i = 1; i < length; i++) {
|
|
38
|
+
debug += ', ' + debugString(val[i]);
|
|
39
|
+
}
|
|
40
|
+
debug += ']';
|
|
41
|
+
return debug;
|
|
42
|
+
}
|
|
43
|
+
// Test for built-in
|
|
44
|
+
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
|
45
|
+
let className;
|
|
46
|
+
if (builtInMatches && builtInMatches.length > 1) {
|
|
47
|
+
className = builtInMatches[1];
|
|
48
|
+
} else {
|
|
49
|
+
// Failed to match the standard '[object ClassName]'
|
|
50
|
+
return toString.call(val);
|
|
51
|
+
}
|
|
52
|
+
if (className == 'Object') {
|
|
53
|
+
// we're a user defined class or Object
|
|
54
|
+
// JSON.stringify avoids problems with cycles, and is generally much
|
|
55
|
+
// easier than looping through ownProperties of `val`.
|
|
56
|
+
try {
|
|
57
|
+
return 'Object(' + JSON.stringify(val) + ')';
|
|
58
|
+
} catch (_) {
|
|
59
|
+
return 'Object';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// errors
|
|
63
|
+
if (val instanceof Error) {
|
|
64
|
+
return `${val.name}: ${val.message}\n${val.stack}`;
|
|
65
|
+
}
|
|
66
|
+
// TODO we could test for more things here, like `Set`s and `Map`s.
|
|
67
|
+
return className;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let WASM_VECTOR_LEN = 0;
|
|
71
|
+
|
|
72
|
+
let cachedUint8ArrayMemory0 = null;
|
|
73
|
+
|
|
74
|
+
function getUint8ArrayMemory0() {
|
|
75
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
76
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
77
|
+
}
|
|
78
|
+
return cachedUint8ArrayMemory0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const cachedTextEncoder = new TextEncoder();
|
|
82
|
+
|
|
83
|
+
if (!('encodeInto' in cachedTextEncoder)) {
|
|
84
|
+
cachedTextEncoder.encodeInto = function (arg, view) {
|
|
85
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
86
|
+
view.set(buf);
|
|
87
|
+
return {
|
|
88
|
+
read: arg.length,
|
|
89
|
+
written: buf.length
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function passStringToWasm0(arg, malloc, realloc) {
|
|
95
|
+
|
|
96
|
+
if (realloc === undefined) {
|
|
97
|
+
const buf = cachedTextEncoder.encode(arg);
|
|
98
|
+
const ptr = malloc(buf.length, 1) >>> 0;
|
|
99
|
+
getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
|
|
100
|
+
WASM_VECTOR_LEN = buf.length;
|
|
101
|
+
return ptr;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let len = arg.length;
|
|
105
|
+
let ptr = malloc(len, 1) >>> 0;
|
|
106
|
+
|
|
107
|
+
const mem = getUint8ArrayMemory0();
|
|
108
|
+
|
|
109
|
+
let offset = 0;
|
|
110
|
+
|
|
111
|
+
for (; offset < len; offset++) {
|
|
112
|
+
const code = arg.charCodeAt(offset);
|
|
113
|
+
if (code > 0x7F) break;
|
|
114
|
+
mem[ptr + offset] = code;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (offset !== len) {
|
|
118
|
+
if (offset !== 0) {
|
|
119
|
+
arg = arg.slice(offset);
|
|
120
|
+
}
|
|
121
|
+
ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
|
|
122
|
+
const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
|
|
123
|
+
const ret = cachedTextEncoder.encodeInto(arg, view);
|
|
124
|
+
|
|
125
|
+
offset += ret.written;
|
|
126
|
+
ptr = realloc(ptr, len, offset, 1) >>> 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
WASM_VECTOR_LEN = offset;
|
|
130
|
+
return ptr;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let cachedDataViewMemory0 = null;
|
|
134
|
+
|
|
135
|
+
function getDataViewMemory0() {
|
|
136
|
+
if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
|
|
137
|
+
cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
|
|
138
|
+
}
|
|
139
|
+
return cachedDataViewMemory0;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
143
|
+
|
|
144
|
+
cachedTextDecoder.decode();
|
|
145
|
+
|
|
146
|
+
function decodeText(ptr, len) {
|
|
147
|
+
return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function getStringFromWasm0(ptr, len) {
|
|
151
|
+
ptr = ptr >>> 0;
|
|
152
|
+
return decodeText(ptr, len);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function addToExternrefTable0(obj) {
|
|
156
|
+
const idx = wasm.__externref_table_alloc();
|
|
157
|
+
wasm.__wbindgen_externrefs.set(idx, obj);
|
|
158
|
+
return idx;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function handleError(f, args) {
|
|
162
|
+
try {
|
|
163
|
+
return f.apply(this, args);
|
|
164
|
+
} catch (e) {
|
|
165
|
+
const idx = addToExternrefTable0(e);
|
|
166
|
+
wasm.__wbindgen_exn_store(idx);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isLikeNone(x) {
|
|
171
|
+
return x === undefined || x === null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
175
|
+
ptr = ptr >>> 0;
|
|
176
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Render a Manipulate body, its extra display elements, and any pending
|
|
180
|
+
* interactive write-backs in one call. Used by widgets that have display
|
|
181
|
+
* elements (e.g. a `Checkbox` grid) that both read and rewrite shared
|
|
182
|
+
* state.
|
|
183
|
+
*
|
|
184
|
+
* `displays_json` and `mutations_json` are JSON string arrays. Each
|
|
185
|
+
* mutation is an assignment (e.g. `data[[3, 5]] = 1`) applied before the
|
|
186
|
+
* re-render; the updated value of every mutated variable is returned under
|
|
187
|
+
* `state` so the frontend can keep its binding set in sync.
|
|
188
|
+
*
|
|
189
|
+
* The result is `{"output":{svg|text|textSvg}, "displays":[<tree>…],
|
|
190
|
+
* "state":{name:value,…}}`.
|
|
191
|
+
* @param {string} body
|
|
192
|
+
* @param {string} displays_json
|
|
193
|
+
* @param {string} bindings_json
|
|
194
|
+
* @param {string} mutations_json
|
|
195
|
+
* @returns {string}
|
|
196
|
+
*/
|
|
197
|
+
exports.evaluate_manipulate_full = function(body, displays_json, bindings_json, mutations_json) {
|
|
198
|
+
let deferred5_0;
|
|
199
|
+
let deferred5_1;
|
|
200
|
+
try {
|
|
201
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
202
|
+
const len0 = WASM_VECTOR_LEN;
|
|
203
|
+
const ptr1 = passStringToWasm0(displays_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
204
|
+
const len1 = WASM_VECTOR_LEN;
|
|
205
|
+
const ptr2 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
206
|
+
const len2 = WASM_VECTOR_LEN;
|
|
207
|
+
const ptr3 = passStringToWasm0(mutations_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
208
|
+
const len3 = WASM_VECTOR_LEN;
|
|
209
|
+
const ret = wasm.evaluate_manipulate_full(ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
210
|
+
deferred5_0 = ret[0];
|
|
211
|
+
deferred5_1 = ret[1];
|
|
212
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
213
|
+
} finally {
|
|
214
|
+
wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
219
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
220
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
221
|
+
WASM_VECTOR_LEN = arg.length;
|
|
222
|
+
return ptr;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Register (or replace) an in-memory file so `Import["name"]` can read it
|
|
226
|
+
* in the browser.
|
|
227
|
+
* @param {string} name
|
|
228
|
+
* @param {Uint8Array} data
|
|
229
|
+
*/
|
|
230
|
+
exports.set_virtual_file = function(name, data) {
|
|
231
|
+
const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
232
|
+
const len0 = WASM_VECTOR_LEN;
|
|
233
|
+
const ptr1 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
234
|
+
const len1 = WASM_VECTOR_LEN;
|
|
235
|
+
wasm.set_virtual_file(ptr0, len0, ptr1, len1);
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Return the captured SVG graphics from the last `evaluate()` call, if any.
|
|
240
|
+
* Returns an empty string when there is no graphics output.
|
|
241
|
+
* @returns {string}
|
|
242
|
+
*/
|
|
243
|
+
exports.get_graphics = function() {
|
|
244
|
+
let deferred1_0;
|
|
245
|
+
let deferred1_1;
|
|
246
|
+
try {
|
|
247
|
+
const ret = wasm.get_graphics();
|
|
248
|
+
deferred1_0 = ret[0];
|
|
249
|
+
deferred1_1 = ret[1];
|
|
250
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
251
|
+
} finally {
|
|
252
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Evaluate all top-level statements and return a JSON array of output items.
|
|
258
|
+
* Each item has a "type" field ("text", "graphics", "print", "warning", "error",
|
|
259
|
+
* "manipulate") and corresponding content fields.
|
|
260
|
+
* @param {string} input
|
|
261
|
+
* @returns {string}
|
|
262
|
+
*/
|
|
263
|
+
exports.evaluate_all = function(input) {
|
|
264
|
+
let deferred2_0;
|
|
265
|
+
let deferred2_1;
|
|
266
|
+
try {
|
|
267
|
+
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
268
|
+
const len0 = WASM_VECTOR_LEN;
|
|
269
|
+
const ret = wasm.evaluate_all(ptr0, len0);
|
|
270
|
+
deferred2_0 = ret[0];
|
|
271
|
+
deferred2_1 = ret[1];
|
|
272
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
273
|
+
} finally {
|
|
274
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Evaluate a single statement and return a JSON array of output items
|
|
280
|
+
* (same shape as `evaluate_all`'s elements). Use together with
|
|
281
|
+
* `split_statements` for progressive output.
|
|
282
|
+
* @param {string} stmt
|
|
283
|
+
* @returns {string}
|
|
284
|
+
*/
|
|
285
|
+
exports.evaluate_statement = function(stmt) {
|
|
286
|
+
let deferred2_0;
|
|
287
|
+
let deferred2_1;
|
|
288
|
+
try {
|
|
289
|
+
const ptr0 = passStringToWasm0(stmt, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
290
|
+
const len0 = WASM_VECTOR_LEN;
|
|
291
|
+
const ret = wasm.evaluate_statement(ptr0, len0);
|
|
292
|
+
deferred2_0 = ret[0];
|
|
293
|
+
deferred2_1 = ret[1];
|
|
294
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
295
|
+
} finally {
|
|
296
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
297
|
+
}
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Split `input` into top-level statements and return a JSON array of strings.
|
|
302
|
+
* Lets the front-end loop one statement at a time so output (and side
|
|
303
|
+
* effects like `Pause[n]`) appear progressively rather than batched.
|
|
304
|
+
* @param {string} input
|
|
305
|
+
* @returns {string}
|
|
306
|
+
*/
|
|
307
|
+
exports.split_statements = function(input) {
|
|
308
|
+
let deferred2_0;
|
|
309
|
+
let deferred2_1;
|
|
310
|
+
try {
|
|
311
|
+
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
312
|
+
const len0 = WASM_VECTOR_LEN;
|
|
313
|
+
const ret = wasm.split_statements(ptr0, len0);
|
|
314
|
+
deferred2_0 = ret[0];
|
|
315
|
+
deferred2_1 = ret[1];
|
|
316
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
317
|
+
} finally {
|
|
318
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Remove all host-registered in-memory files.
|
|
324
|
+
*/
|
|
325
|
+
exports.clear_virtual_files = function() {
|
|
326
|
+
wasm.clear_virtual_files();
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Evaluate a Manipulate body with a specific set of variable bindings
|
|
331
|
+
* and return a single JSON output item representing the result.
|
|
332
|
+
*
|
|
333
|
+
* `body` must be the body expression in InputForm (as produced by
|
|
334
|
+
* `evaluate_all`'s manipulate item). `bindings_json` must be a JSON
|
|
335
|
+
* object mapping variable names to InputForm-serialized values, e.g.
|
|
336
|
+
* `{"a": "1.5", "b": "\"foo\""}`.
|
|
337
|
+
*
|
|
338
|
+
* The result is a JSON object of the same shape as `initial` from
|
|
339
|
+
* the evaluate_all manipulate item: `{"svg": "...", "text": "..."}`.
|
|
340
|
+
* @param {string} body
|
|
341
|
+
* @param {string} bindings_json
|
|
342
|
+
* @returns {string}
|
|
343
|
+
*/
|
|
344
|
+
exports.evaluate_manipulate = function(body, bindings_json) {
|
|
345
|
+
let deferred3_0;
|
|
346
|
+
let deferred3_1;
|
|
347
|
+
try {
|
|
348
|
+
const ptr0 = passStringToWasm0(body, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
349
|
+
const len0 = WASM_VECTOR_LEN;
|
|
350
|
+
const ptr1 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
351
|
+
const len1 = WASM_VECTOR_LEN;
|
|
352
|
+
const ret = wasm.evaluate_manipulate(ptr0, len0, ptr1, len1);
|
|
353
|
+
deferred3_0 = ret[0];
|
|
354
|
+
deferred3_1 = ret[1];
|
|
355
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
356
|
+
} finally {
|
|
357
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Evaluate, returning only the final expression result (no Print output).
|
|
363
|
+
* @param {string} input
|
|
364
|
+
* @returns {string}
|
|
365
|
+
*/
|
|
366
|
+
exports.evaluate_expr = function(input) {
|
|
367
|
+
let deferred2_0;
|
|
368
|
+
let deferred2_1;
|
|
369
|
+
try {
|
|
370
|
+
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
371
|
+
const len0 = WASM_VECTOR_LEN;
|
|
372
|
+
const ret = wasm.evaluate_expr(ptr0, len0);
|
|
373
|
+
deferred2_0 = ret[0];
|
|
374
|
+
deferred2_1 = ret[1];
|
|
375
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
376
|
+
} finally {
|
|
377
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Return SVG rendering of the last text result (with superscripts etc.).
|
|
383
|
+
* Returns an empty string when there is no output SVG (e.g. for Graphics results).
|
|
384
|
+
* @returns {string}
|
|
385
|
+
*/
|
|
386
|
+
exports.get_output_svg = function() {
|
|
387
|
+
let deferred1_0;
|
|
388
|
+
let deferred1_1;
|
|
389
|
+
try {
|
|
390
|
+
const ret = wasm.get_output_svg();
|
|
391
|
+
deferred1_0 = ret[0];
|
|
392
|
+
deferred1_1 = ret[1];
|
|
393
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
394
|
+
} finally {
|
|
395
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Enable or disable dark mode for SVG output colors.
|
|
401
|
+
* @param {boolean} enabled
|
|
402
|
+
*/
|
|
403
|
+
exports.set_dark_mode = function(enabled) {
|
|
404
|
+
wasm.set_dark_mode(enabled);
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Evaluate a Wolfram Language expression and return the result.
|
|
409
|
+
* If the expression produces Print output, it is prepended to the result.
|
|
410
|
+
* @param {string} input
|
|
411
|
+
* @returns {string}
|
|
412
|
+
*/
|
|
413
|
+
exports.evaluate = function(input) {
|
|
414
|
+
let deferred2_0;
|
|
415
|
+
let deferred2_1;
|
|
416
|
+
try {
|
|
417
|
+
const ptr0 = passStringToWasm0(input, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
418
|
+
const len0 = WASM_VECTOR_LEN;
|
|
419
|
+
const ret = wasm.evaluate(ptr0, len0);
|
|
420
|
+
deferred2_0 = ret[0];
|
|
421
|
+
deferred2_1 = ret[1];
|
|
422
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
423
|
+
} finally {
|
|
424
|
+
wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Return warnings from the last `evaluate()` call as newline-separated text.
|
|
430
|
+
* Returns an empty string when there are no warnings.
|
|
431
|
+
* @returns {string}
|
|
432
|
+
*/
|
|
433
|
+
exports.get_warnings = function() {
|
|
434
|
+
let deferred1_0;
|
|
435
|
+
let deferred1_1;
|
|
436
|
+
try {
|
|
437
|
+
const ret = wasm.get_warnings();
|
|
438
|
+
deferred1_0 = ret[0];
|
|
439
|
+
deferred1_1 = ret[1];
|
|
440
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
441
|
+
} finally {
|
|
442
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Return the playable audio (base64-encoded) from the last `evaluate()`
|
|
448
|
+
* call, if any. Returns an empty string when there is no sound.
|
|
449
|
+
* @returns {string}
|
|
450
|
+
*/
|
|
451
|
+
exports.get_sound = function() {
|
|
452
|
+
let deferred1_0;
|
|
453
|
+
let deferred1_1;
|
|
454
|
+
try {
|
|
455
|
+
const ret = wasm.get_sound();
|
|
456
|
+
deferred1_0 = ret[0];
|
|
457
|
+
deferred1_1 = ret[1];
|
|
458
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
459
|
+
} finally {
|
|
460
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
461
|
+
}
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Clear all interpreter state (variables and function definitions).
|
|
466
|
+
*/
|
|
467
|
+
exports.clear = function() {
|
|
468
|
+
wasm.clear();
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
exports.init = function() {
|
|
472
|
+
wasm.init();
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Evaluate each Manipulate control's `Enabled` condition against a binding
|
|
477
|
+
* set and return a JSON array of booleans (one per control, in order).
|
|
478
|
+
*
|
|
479
|
+
* `conditions_json` is a JSON string array aligned with the control list;
|
|
480
|
+
* an empty string marks a control with no condition (always enabled).
|
|
481
|
+
* `bindings_json` is the same JSON object of variable bindings used by
|
|
482
|
+
* `evaluate_manipulate`. Used by the Playground to grey out controls that a
|
|
483
|
+
* `Enabled -> Dynamic[…]` option has switched off for the current state.
|
|
484
|
+
* @param {string} conditions_json
|
|
485
|
+
* @param {string} bindings_json
|
|
486
|
+
* @returns {string}
|
|
487
|
+
*/
|
|
488
|
+
exports.evaluate_manipulate_enabled = function(conditions_json, bindings_json) {
|
|
489
|
+
let deferred3_0;
|
|
490
|
+
let deferred3_1;
|
|
491
|
+
try {
|
|
492
|
+
const ptr0 = passStringToWasm0(conditions_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
493
|
+
const len0 = WASM_VECTOR_LEN;
|
|
494
|
+
const ptr1 = passStringToWasm0(bindings_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
495
|
+
const len1 = WASM_VECTOR_LEN;
|
|
496
|
+
const ret = wasm.evaluate_manipulate_enabled(ptr0, len0, ptr1, len1);
|
|
497
|
+
deferred3_0 = ret[0];
|
|
498
|
+
deferred3_1 = ret[1];
|
|
499
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
500
|
+
} finally {
|
|
501
|
+
wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Return the captured GraphicsBox expression from the last `evaluate()` call.
|
|
507
|
+
* Returns an empty string when there is no graphics output.
|
|
508
|
+
* @returns {string}
|
|
509
|
+
*/
|
|
510
|
+
exports.get_graphicsbox = function() {
|
|
511
|
+
let deferred1_0;
|
|
512
|
+
let deferred1_1;
|
|
513
|
+
try {
|
|
514
|
+
const ret = wasm.get_graphicsbox();
|
|
515
|
+
deferred1_0 = ret[0];
|
|
516
|
+
deferred1_1 = ret[1];
|
|
517
|
+
return getStringFromWasm0(ret[0], ret[1]);
|
|
518
|
+
} finally {
|
|
519
|
+
wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
|
|
520
|
+
}
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
exports.__wbg___wbindgen_debug_string_df47ffb5e35e6763 = function(arg0, arg1) {
|
|
524
|
+
const ret = debugString(arg1);
|
|
525
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
526
|
+
const len1 = WASM_VECTOR_LEN;
|
|
527
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
528
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
exports.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function(arg0) {
|
|
532
|
+
const ret = typeof(arg0) === 'function';
|
|
533
|
+
return ret;
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
exports.__wbg___wbindgen_is_object_c818261d21f283a4 = function(arg0) {
|
|
537
|
+
const val = arg0;
|
|
538
|
+
const ret = typeof(val) === 'object' && val !== null;
|
|
539
|
+
return ret;
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
exports.__wbg___wbindgen_is_string_fbb76cb2940daafd = function(arg0) {
|
|
543
|
+
const ret = typeof(arg0) === 'string';
|
|
544
|
+
return ret;
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
exports.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function(arg0) {
|
|
548
|
+
const ret = arg0 === undefined;
|
|
549
|
+
return ret;
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
exports.__wbg___wbindgen_throw_b855445ff6a94295 = function(arg0, arg1) {
|
|
553
|
+
throw new Error(getStringFromWasm0(arg0, arg1));
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
exports.__wbg___woxi_fetch_url_b456f49aff4e3138 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
557
|
+
const ret = __woxi_fetch_url(getStringFromWasm0(arg1, arg2));
|
|
558
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
559
|
+
const len1 = WASM_VECTOR_LEN;
|
|
560
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
561
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
562
|
+
}, arguments) };
|
|
563
|
+
|
|
564
|
+
exports.__wbg___woxi_report_panic_13444e27f27ce1cd = function() { return handleError(function (arg0, arg1) {
|
|
565
|
+
__woxi_report_panic(getStringFromWasm0(arg0, arg1));
|
|
566
|
+
}, arguments) };
|
|
567
|
+
|
|
568
|
+
exports.__wbg_append_ed363d026656dfbd = function() { return handleError(function (arg0, arg1) {
|
|
569
|
+
arg0.append(arg1);
|
|
570
|
+
}, arguments) };
|
|
571
|
+
|
|
572
|
+
exports.__wbg_body_8c26b54829a0c4cb = function(arg0) {
|
|
573
|
+
const ret = arg0.body;
|
|
574
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
exports.__wbg_call_525440f72fbfc0ea = function() { return handleError(function (arg0, arg1, arg2) {
|
|
578
|
+
const ret = arg0.call(arg1, arg2);
|
|
579
|
+
return ret;
|
|
580
|
+
}, arguments) };
|
|
581
|
+
|
|
582
|
+
exports.__wbg_call_e762c39fa8ea36bf = function() { return handleError(function (arg0, arg1) {
|
|
583
|
+
const ret = arg0.call(arg1);
|
|
584
|
+
return ret;
|
|
585
|
+
}, arguments) };
|
|
586
|
+
|
|
587
|
+
exports.__wbg_createElement_964ab674a0176cd8 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
588
|
+
const ret = arg0.createElement(getStringFromWasm0(arg1, arg2));
|
|
589
|
+
return ret;
|
|
590
|
+
}, arguments) };
|
|
591
|
+
|
|
592
|
+
exports.__wbg_crypto_574e78ad8b13b65f = function(arg0) {
|
|
593
|
+
const ret = arg0.crypto;
|
|
594
|
+
return ret;
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
exports.__wbg_document_725ae06eb442a6db = function(arg0) {
|
|
598
|
+
const ret = arg0.document;
|
|
599
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
exports.__wbg_error_7534b8e9a36f1ab4 = function(arg0, arg1) {
|
|
603
|
+
let deferred0_0;
|
|
604
|
+
let deferred0_1;
|
|
605
|
+
try {
|
|
606
|
+
deferred0_0 = arg0;
|
|
607
|
+
deferred0_1 = arg1;
|
|
608
|
+
console.error(getStringFromWasm0(arg0, arg1));
|
|
609
|
+
} finally {
|
|
610
|
+
wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
|
|
614
|
+
exports.__wbg_getDate_5a70d2f6a482d99f = function(arg0) {
|
|
615
|
+
const ret = arg0.getDate();
|
|
616
|
+
return ret;
|
|
617
|
+
};
|
|
618
|
+
|
|
619
|
+
exports.__wbg_getFullYear_8240d5a15191feae = function(arg0) {
|
|
620
|
+
const ret = arg0.getFullYear();
|
|
621
|
+
return ret;
|
|
622
|
+
};
|
|
623
|
+
|
|
624
|
+
exports.__wbg_getHours_5e476e0b9ebc42d1 = function(arg0) {
|
|
625
|
+
const ret = arg0.getHours();
|
|
626
|
+
return ret;
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
exports.__wbg_getMilliseconds_9fc7184d90e04a16 = function(arg0) {
|
|
630
|
+
const ret = arg0.getMilliseconds();
|
|
631
|
+
return ret;
|
|
632
|
+
};
|
|
633
|
+
|
|
634
|
+
exports.__wbg_getMinutes_c95dfb65f1ea8f02 = function(arg0) {
|
|
635
|
+
const ret = arg0.getMinutes();
|
|
636
|
+
return ret;
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
exports.__wbg_getMonth_25c1c5a601d72773 = function(arg0) {
|
|
640
|
+
const ret = arg0.getMonth();
|
|
641
|
+
return ret;
|
|
642
|
+
};
|
|
643
|
+
|
|
644
|
+
exports.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {
|
|
645
|
+
arg0.getRandomValues(arg1);
|
|
646
|
+
}, arguments) };
|
|
647
|
+
|
|
648
|
+
exports.__wbg_getSeconds_8113bf8709718eb2 = function(arg0) {
|
|
649
|
+
const ret = arg0.getSeconds();
|
|
650
|
+
return ret;
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
exports.__wbg_getTime_14776bfb48a1bff9 = function(arg0) {
|
|
654
|
+
const ret = arg0.getTime();
|
|
655
|
+
return ret;
|
|
656
|
+
};
|
|
657
|
+
|
|
658
|
+
exports.__wbg_getTimezoneOffset_d391cb11d54969f8 = function(arg0) {
|
|
659
|
+
const ret = arg0.getTimezoneOffset();
|
|
660
|
+
return ret;
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
exports.__wbg_instanceof_HtmlElement_e20a729df22f9e1c = function(arg0) {
|
|
664
|
+
let result;
|
|
665
|
+
try {
|
|
666
|
+
result = arg0 instanceof HTMLElement;
|
|
667
|
+
} catch (_) {
|
|
668
|
+
result = false;
|
|
669
|
+
}
|
|
670
|
+
const ret = result;
|
|
671
|
+
return ret;
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
exports.__wbg_instanceof_Window_4846dbb3de56c84c = function(arg0) {
|
|
675
|
+
let result;
|
|
676
|
+
try {
|
|
677
|
+
result = arg0 instanceof Window;
|
|
678
|
+
} catch (_) {
|
|
679
|
+
result = false;
|
|
680
|
+
}
|
|
681
|
+
const ret = result;
|
|
682
|
+
return ret;
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
exports.__wbg_length_69bca3cb64fc8748 = function(arg0) {
|
|
686
|
+
const ret = arg0.length;
|
|
687
|
+
return ret;
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
exports.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {
|
|
691
|
+
const ret = arg0.msCrypto;
|
|
692
|
+
return ret;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
exports.__wbg_new_0_f9740686d739025c = function() {
|
|
696
|
+
const ret = new Date();
|
|
697
|
+
return ret;
|
|
698
|
+
};
|
|
699
|
+
|
|
700
|
+
exports.__wbg_new_8a6f238a6ece86ea = function() {
|
|
701
|
+
const ret = new Error();
|
|
702
|
+
return ret;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
exports.__wbg_new_93d9417ed3fb115d = function(arg0) {
|
|
706
|
+
const ret = new Date(arg0);
|
|
707
|
+
return ret;
|
|
708
|
+
};
|
|
709
|
+
|
|
710
|
+
exports.__wbg_new_no_args_ee98eee5275000a4 = function(arg0, arg1) {
|
|
711
|
+
const ret = new Function(getStringFromWasm0(arg0, arg1));
|
|
712
|
+
return ret;
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
exports.__wbg_new_with_length_01aa0dc35aa13543 = function(arg0) {
|
|
716
|
+
const ret = new Uint8Array(arg0 >>> 0);
|
|
717
|
+
return ret;
|
|
718
|
+
};
|
|
719
|
+
|
|
720
|
+
exports.__wbg_new_with_year_month_day_6236812cf591750d = function(arg0, arg1, arg2) {
|
|
721
|
+
const ret = new Date(arg0 >>> 0, arg1, arg2);
|
|
722
|
+
return ret;
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
exports.__wbg_node_905d3e251edff8a2 = function(arg0) {
|
|
726
|
+
const ret = arg0.node;
|
|
727
|
+
return ret;
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
exports.__wbg_now_2c95c9de01293173 = function(arg0) {
|
|
731
|
+
const ret = arg0.now();
|
|
732
|
+
return ret;
|
|
733
|
+
};
|
|
734
|
+
|
|
735
|
+
exports.__wbg_now_793306c526e2e3b6 = function() {
|
|
736
|
+
const ret = Date.now();
|
|
737
|
+
return ret;
|
|
738
|
+
};
|
|
739
|
+
|
|
740
|
+
exports.__wbg_offsetHeight_9cb4257b24361e2a = function(arg0) {
|
|
741
|
+
const ret = arg0.offsetHeight;
|
|
742
|
+
return ret;
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
exports.__wbg_offsetWidth_16b33c540f3e9ddb = function(arg0) {
|
|
746
|
+
const ret = arg0.offsetWidth;
|
|
747
|
+
return ret;
|
|
748
|
+
};
|
|
749
|
+
|
|
750
|
+
exports.__wbg_performance_7a3ffd0b17f663ad = function(arg0) {
|
|
751
|
+
const ret = arg0.performance;
|
|
752
|
+
return ret;
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
exports.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {
|
|
756
|
+
const ret = arg0.process;
|
|
757
|
+
return ret;
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
exports.__wbg_prototypesetcall_2a6620b6922694b2 = function(arg0, arg1, arg2) {
|
|
761
|
+
Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), arg2);
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
exports.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {
|
|
765
|
+
arg0.randomFillSync(arg1);
|
|
766
|
+
}, arguments) };
|
|
767
|
+
|
|
768
|
+
exports.__wbg_remove_4ba46706a8e17d9d = function(arg0) {
|
|
769
|
+
arg0.remove();
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
exports.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {
|
|
773
|
+
const ret = module.require;
|
|
774
|
+
return ret;
|
|
775
|
+
}, arguments) };
|
|
776
|
+
|
|
777
|
+
exports.__wbg_setAttribute_9bad76f39609daac = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
|
778
|
+
arg0.setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
|
779
|
+
}, arguments) };
|
|
780
|
+
|
|
781
|
+
exports.__wbg_set_textContent_12af0b0f84feb710 = function(arg0, arg1, arg2) {
|
|
782
|
+
arg0.textContent = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
|
|
783
|
+
};
|
|
784
|
+
|
|
785
|
+
exports.__wbg_stack_0ed75d68575b0f3c = function(arg0, arg1) {
|
|
786
|
+
const ret = arg1.stack;
|
|
787
|
+
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
788
|
+
const len1 = WASM_VECTOR_LEN;
|
|
789
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
|
|
790
|
+
getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
|
|
791
|
+
};
|
|
792
|
+
|
|
793
|
+
exports.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function() {
|
|
794
|
+
const ret = typeof global === 'undefined' ? null : global;
|
|
795
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
exports.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function() {
|
|
799
|
+
const ret = typeof globalThis === 'undefined' ? null : globalThis;
|
|
800
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
exports.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function() {
|
|
804
|
+
const ret = typeof self === 'undefined' ? null : self;
|
|
805
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
exports.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function() {
|
|
809
|
+
const ret = typeof window === 'undefined' ? null : window;
|
|
810
|
+
return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
exports.__wbg_subarray_480600f3d6a9f26c = function(arg0, arg1, arg2) {
|
|
814
|
+
const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0);
|
|
815
|
+
return ret;
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
exports.__wbg_versions_c01dfd4722a88165 = function(arg0) {
|
|
819
|
+
const ret = arg0.versions;
|
|
820
|
+
return ret;
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
exports.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {
|
|
824
|
+
// Cast intrinsic for `Ref(String) -> Externref`.
|
|
825
|
+
const ret = getStringFromWasm0(arg0, arg1);
|
|
826
|
+
return ret;
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
exports.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {
|
|
830
|
+
// Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref("Uint8Array")`.
|
|
831
|
+
const ret = getArrayU8FromWasm0(arg0, arg1);
|
|
832
|
+
return ret;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
exports.__wbindgen_cast_d6cd19b81560fd6e = function(arg0) {
|
|
836
|
+
// Cast intrinsic for `F64 -> Externref`.
|
|
837
|
+
const ret = arg0;
|
|
838
|
+
return ret;
|
|
839
|
+
};
|
|
840
|
+
|
|
841
|
+
exports.__wbindgen_init_externref_table = function() {
|
|
842
|
+
const table = wasm.__wbindgen_externrefs;
|
|
843
|
+
const offset = table.grow(4);
|
|
844
|
+
table.set(0, undefined);
|
|
845
|
+
table.set(offset + 0, undefined);
|
|
846
|
+
table.set(offset + 1, null);
|
|
847
|
+
table.set(offset + 2, true);
|
|
848
|
+
table.set(offset + 3, false);
|
|
849
|
+
;
|
|
850
|
+
};
|
|
851
|
+
|
|
852
|
+
const wasmPath = `${__dirname}/woxi_bg.wasm`;
|
|
853
|
+
const wasmBytes = require('fs').readFileSync(wasmPath);
|
|
854
|
+
const wasmModule = new WebAssembly.Module(wasmBytes);
|
|
855
|
+
const wasm = exports.__wasm = new WebAssembly.Instance(wasmModule, imports).exports;
|
|
856
|
+
|
|
857
|
+
wasm.__wbindgen_start();
|
|
858
|
+
|
package/pkg/woxi_bg.wasm
ADDED
|
Binary file
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
export const memory: WebAssembly.Memory;
|
|
4
|
+
export const clear_virtual_files: () => void;
|
|
5
|
+
export const evaluate: (a: number, b: number) => [number, number];
|
|
6
|
+
export const evaluate_all: (a: number, b: number) => [number, number];
|
|
7
|
+
export const evaluate_expr: (a: number, b: number) => [number, number];
|
|
8
|
+
export const evaluate_manipulate: (a: number, b: number, c: number, d: number) => [number, number];
|
|
9
|
+
export const evaluate_manipulate_enabled: (a: number, b: number, c: number, d: number) => [number, number];
|
|
10
|
+
export const evaluate_manipulate_full: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number];
|
|
11
|
+
export const evaluate_statement: (a: number, b: number) => [number, number];
|
|
12
|
+
export const get_graphics: () => [number, number];
|
|
13
|
+
export const get_graphicsbox: () => [number, number];
|
|
14
|
+
export const get_output_svg: () => [number, number];
|
|
15
|
+
export const get_sound: () => [number, number];
|
|
16
|
+
export const get_warnings: () => [number, number];
|
|
17
|
+
export const set_dark_mode: (a: number) => void;
|
|
18
|
+
export const set_virtual_file: (a: number, b: number, c: number, d: number) => void;
|
|
19
|
+
export const split_statements: (a: number, b: number) => [number, number];
|
|
20
|
+
export const clear: () => void;
|
|
21
|
+
export const init: () => void;
|
|
22
|
+
export const __wbindgen_malloc: (a: number, b: number) => number;
|
|
23
|
+
export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
|
|
24
|
+
export const __wbindgen_exn_store: (a: number) => void;
|
|
25
|
+
export const __externref_table_alloc: () => number;
|
|
26
|
+
export const __wbindgen_externrefs: WebAssembly.Table;
|
|
27
|
+
export const __wbindgen_free: (a: number, b: number, c: number) => void;
|
|
28
|
+
export const __wbindgen_start: () => void;
|
package/readme.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Woxi
|
|
2
|
+
|
|
3
|
+
An interpreter for a subset of the
|
|
4
|
+
[Wolfram Language](https://www.wolfram.com/language/)
|
|
5
|
+
powered by Rust and compiled to WebAssembly.
|
|
6
|
+
|
|
7
|
+
This package wraps the [Woxi](https://github.com/ad-si/Woxi) interpreter
|
|
8
|
+
so it can be used from Node.js — no Wolfram installation required.
|
|
9
|
+
Woxi is a computer algebra system (CAS): computations are solved symbolically.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install woxi-wasm
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
(The package is named `woxi-wasm` because the name `woxi` is not
|
|
19
|
+
available on npm.)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import { evaluate } from "woxi-wasm"
|
|
26
|
+
|
|
27
|
+
evaluate("Plus[1, 2]") //=> "3"
|
|
28
|
+
evaluate("1/3 + 1/6") //=> "1/2"
|
|
29
|
+
evaluate("Sqrt[8]") //=> "2*Sqrt[2]"
|
|
30
|
+
evaluate('StringReverse["hello"]') //=> "olleh"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
CommonJS works too:
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
const { evaluate } = require("woxi-wasm")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Interpreter state (variables, function definitions) persists across calls:
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import woxi from "woxi-wasm"
|
|
43
|
+
|
|
44
|
+
woxi.evaluate("f[x_] := x^2")
|
|
45
|
+
woxi.evaluate("f[5]") //=> "25"
|
|
46
|
+
woxi.clear() // reset all state
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Structured output
|
|
51
|
+
|
|
52
|
+
`evaluateAll` returns one item per output, including graphics as SVG:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
const items = woxi.evaluateAll('Print["hi"]\nGraphics[{Disk[]}]')
|
|
56
|
+
//=> [
|
|
57
|
+
// { type: "print", text: "hi" },
|
|
58
|
+
// { type: "graphics", svg: "<svg …" },
|
|
59
|
+
// ]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Item types: `text`, `print`, `graphics`, `warning`, `error`, `sound`,
|
|
63
|
+
and `manipulate`.
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
### Virtual files
|
|
67
|
+
|
|
68
|
+
There is no filesystem access from WebAssembly, so `Import[…]` reads from
|
|
69
|
+
an in-memory store you populate first:
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
woxi.setVirtualFile("data.csv", "a,b\n1,2\n")
|
|
73
|
+
woxi.evaluate('Import["data.csv"]') //=> "{{a, b}, {1, 2}}"
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`Import["https://…"]` fetches over HTTP automatically.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## API
|
|
80
|
+
|
|
81
|
+
| Function | Description |
|
|
82
|
+
|------------------------------|---------------------------------------------------|
|
|
83
|
+
| `evaluate(code)` | Evaluate code, return output as a string |
|
|
84
|
+
| `evaluateAll(code)` | Evaluate code, return structured output items |
|
|
85
|
+
| `splitStatements(code)` | Split code into top-level statements |
|
|
86
|
+
| `evaluateStatement(stmt)` | Evaluate a single statement (structured output) |
|
|
87
|
+
| `getGraphics()` | SVG captured by the last `evaluate()` call |
|
|
88
|
+
| `getSound()` | Base64 audio captured by the last call |
|
|
89
|
+
| `getWarnings()` | Warnings of the last call as an array |
|
|
90
|
+
| `clear()` | Clear all interpreter state |
|
|
91
|
+
| `setDarkMode(enabled)` | Toggle dark-mode colors for SVG output |
|
|
92
|
+
| `setVirtualFile(name, data)` | Register an in-memory file for `Import[…]` |
|
|
93
|
+
| `clearVirtualFiles()` | Remove all registered in-memory files |
|
|
94
|
+
|
|
95
|
+
TypeScript definitions are included.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
The wasm bundle in `pkg/` is generated from the Rust sources — build it from
|
|
101
|
+
the [repository](https://github.com/ad-si/Woxi) root:
|
|
102
|
+
|
|
103
|
+
```sh
|
|
104
|
+
make npm-build # build pkg/ with wasm-pack
|
|
105
|
+
make npm-test # build + run the JS test suite
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
[AGPL-3.0-or-later](https://github.com/ad-si/Woxi/blob/main/license.txt)
|