normaliz.wasm 1.0.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/LICENSE +682 -0
- package/README.md +85 -0
- package/dist/normaliz.js +4985 -0
- package/dist/normaliz.wasm +0 -0
- package/package.json +30 -0
- package/src/normaliz.js +153 -0
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "normaliz.wasm",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "WebAssembly build of Normaliz",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./src/normaliz.js",
|
|
8
|
+
"./dist/normaliz.js": "./dist/normaliz.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src/",
|
|
12
|
+
"dist/"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "bash build/build.sh"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/DominikPeters/normaliz.wasm"
|
|
20
|
+
},
|
|
21
|
+
"license": "GPL-3.0-or-later",
|
|
22
|
+
"keywords": [
|
|
23
|
+
"normaliz",
|
|
24
|
+
"wasm",
|
|
25
|
+
"emscripten",
|
|
26
|
+
"polytope",
|
|
27
|
+
"cone",
|
|
28
|
+
"hilbert"
|
|
29
|
+
]
|
|
30
|
+
}
|
package/src/normaliz.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* normaliz.wasm — JavaScript wrapper for Normaliz WebAssembly module.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { Normaliz } from 'normaliz.wasm';
|
|
6
|
+
* const nmz = await Normaliz.create();
|
|
7
|
+
* const result = nmz.run('amb_space 2\ncone 2\n1 3\n2 1\n');
|
|
8
|
+
* console.log(result.output); // main .out file contents
|
|
9
|
+
* console.log(result.console); // verbose console log
|
|
10
|
+
* console.log(result.files); // { 'gen': '...', 'ext': '...', ... }
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import createNormaliz from '../dist/normaliz.js';
|
|
14
|
+
|
|
15
|
+
const OUTPUT_EXTENSIONS = [
|
|
16
|
+
'out', 'gen', 'egn', 'esp', 'ext', 'typ',
|
|
17
|
+
'lat', 'cst', 'inv', 'tri', 'ht1', 'dec',
|
|
18
|
+
'mod', 'msp', 'fac', 'inc', 'tgn',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export class Normaliz {
|
|
22
|
+
/**
|
|
23
|
+
* Create a new Normaliz instance.
|
|
24
|
+
* Each instance holds its own wasm module with a virtual filesystem.
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} [opts]
|
|
27
|
+
* @param {Function} [opts.loadModule] - Custom module loader (overrides default)
|
|
28
|
+
* @param {Function} [opts.onStdout] - Called with each line of stdout during computation
|
|
29
|
+
* @param {Function} [opts.onStderr] - Called with each line of stderr during computation
|
|
30
|
+
* @returns {Promise<Normaliz>}
|
|
31
|
+
*/
|
|
32
|
+
static async create(opts = {}) {
|
|
33
|
+
const instance = new Normaliz();
|
|
34
|
+
const loader = opts.loadModule || createNormaliz;
|
|
35
|
+
instance._onStdout = opts.onStdout || null;
|
|
36
|
+
instance._onStderr = opts.onStderr || null;
|
|
37
|
+
instance._module = await loader({
|
|
38
|
+
print: (text) => {
|
|
39
|
+
instance._stdoutBuf.push(text);
|
|
40
|
+
if (instance._onStdout) instance._onStdout(text);
|
|
41
|
+
},
|
|
42
|
+
printErr: (text) => {
|
|
43
|
+
instance._stderrBuf.push(text);
|
|
44
|
+
if (instance._onStderr) instance._onStderr(text);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
return instance;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
constructor() {
|
|
51
|
+
this._module = null;
|
|
52
|
+
this._stdoutBuf = [];
|
|
53
|
+
this._stderrBuf = [];
|
|
54
|
+
this._onStdout = null;
|
|
55
|
+
this._onStderr = null;
|
|
56
|
+
this._runCounter = 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Run a Normaliz computation.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} input - Contents of the .in file
|
|
63
|
+
* @param {Object} [opts]
|
|
64
|
+
* @param {string[]} [opts.flags] - Extra CLI flags, e.g. ['--verbose', '-a']
|
|
65
|
+
* @returns {{ output: string, console: string, stderr: string, files: Object<string,string>, exitCode: number }}
|
|
66
|
+
*/
|
|
67
|
+
run(input, opts = {}) {
|
|
68
|
+
const m = this._module;
|
|
69
|
+
const flags = opts.flags || [];
|
|
70
|
+
const name = `_run${this._runCounter++}`;
|
|
71
|
+
const inFile = `${name}.in`;
|
|
72
|
+
|
|
73
|
+
// Clear buffers
|
|
74
|
+
this._stdoutBuf = [];
|
|
75
|
+
this._stderrBuf = [];
|
|
76
|
+
|
|
77
|
+
// Write input
|
|
78
|
+
m.FS.writeFile(inFile, input);
|
|
79
|
+
|
|
80
|
+
// Run normaliz
|
|
81
|
+
let exitCode = 0;
|
|
82
|
+
try {
|
|
83
|
+
exitCode = m.callMain([...flags, name]);
|
|
84
|
+
} catch (e) {
|
|
85
|
+
// callMain may throw on non-zero exit
|
|
86
|
+
exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Collect output files
|
|
90
|
+
const files = {};
|
|
91
|
+
for (const ext of OUTPUT_EXTENSIONS) {
|
|
92
|
+
const fname = `${name}.${ext}`;
|
|
93
|
+
try {
|
|
94
|
+
files[ext] = m.FS.readFile(fname, { encoding: 'utf8' });
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// File doesn't exist — computation didn't produce it
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Read main output
|
|
101
|
+
const output = files.out || '';
|
|
102
|
+
|
|
103
|
+
// Clean up virtual filesystem
|
|
104
|
+
try { m.FS.unlink(inFile); } catch (e) {}
|
|
105
|
+
for (const ext of OUTPUT_EXTENSIONS) {
|
|
106
|
+
try { m.FS.unlink(`${name}.${ext}`); } catch (e) {}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
output,
|
|
111
|
+
console: this._stdoutBuf.join('\n'),
|
|
112
|
+
stderr: this._stderrBuf.join('\n'),
|
|
113
|
+
files,
|
|
114
|
+
exitCode,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* List available example file names.
|
|
120
|
+
* (Requires examples to be loaded via loadExamples first.)
|
|
121
|
+
* @returns {string[]}
|
|
122
|
+
*/
|
|
123
|
+
listExamples() {
|
|
124
|
+
try {
|
|
125
|
+
return this._module.FS.readdir('/examples')
|
|
126
|
+
.filter(f => f.endsWith('.in'))
|
|
127
|
+
.sort();
|
|
128
|
+
} catch (e) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Load example files into the virtual filesystem.
|
|
135
|
+
* @param {Object<string,string>} examples - Map of filename to contents
|
|
136
|
+
*/
|
|
137
|
+
loadExamples(examples) {
|
|
138
|
+
const m = this._module;
|
|
139
|
+
try { m.FS.mkdir('/examples'); } catch (e) {}
|
|
140
|
+
for (const [name, content] of Object.entries(examples)) {
|
|
141
|
+
m.FS.writeFile(`/examples/${name}`, content);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Read an example file's contents.
|
|
147
|
+
* @param {string} name - Filename (e.g. '2cone.in')
|
|
148
|
+
* @returns {string}
|
|
149
|
+
*/
|
|
150
|
+
readExample(name) {
|
|
151
|
+
return this._module.FS.readFile(`/examples/${name}`, { encoding: 'utf8' });
|
|
152
|
+
}
|
|
153
|
+
}
|