@libraz/formulon
v0.9.2
Published
Excel 365 calculation engine -- WASM binding
Downloads
677
Maintainers
Readme
@libraz/formulon
Excel 365 calculation engine, compiled to WebAssembly. Evaluates formulas,
loads and saves .xlsx workbooks, and aims for 1-bit compatibility with
Mac Excel 365 (ja-JP locale).
Install
npm install @libraz/formulonRequires Node.js 18 or newer (the package is shipped as ES modules).
Quick start
import createFormulon from '@libraz/formulon';
const Module = await createFormulon();
const r = Module.evalFormula('=SUM(1,2,3)');
console.log(r.value.number); // 6evalFormula returns an envelope of the form { status, value }. Excel
errors (e.g. #DIV/0!) are surfaced as a value.kind === 4 (Error)
result rather than a failed status; only host-side problems
(out-of-memory, parser crashes) populate status.ok === false.
Workbook example
import createFormulon from '@libraz/formulon';
import { readFile, writeFile } from 'node:fs/promises';
const Module = await createFormulon();
// Load an existing workbook from disk.
const bytes = await readFile('input.xlsx');
const wb = Module.Workbook.loadBytes(bytes);
try {
if (!wb.isValid()) {
throw new Error(`load failed: ${Module.lastErrorMessage()}`);
}
// Mutate, recalc, save.
wb.setNumber(0, 0, 0, 42); // Sheet1!A1 = 42
wb.setFormula(0, 1, 0, '=A1*2'); // Sheet1!A2 = =A1*2
wb.recalc();
const a2 = wb.getValue(0, 1, 0);
console.log(a2.value.number); // 84
const saved = wb.save();
if (saved.status.ok) {
await writeFile('output.xlsx', saved.bytes);
}
} finally {
// Always release the native handle.
wb.delete();
}Bundler integration (Vite, webpack, esbuild)
The package ships a single ES module factory plus the companion
formulon.wasm. Two consumer-side concerns are worth knowing about:
1. Pthread workers require ES module workers. Internally the engine
runs the recalc scheduler on Web Workers spawned by Emscripten with
new Worker(new URL("formulon.js", import.meta.url), {type: "module"}).
Bundlers default to classic (IIFE) workers and must be told otherwise:
// vite.config.ts
export default defineConfig({
worker: { format: 'es' },
});webpack 5 picks up the {type: "module"} automatically when
output.module: true. esbuild requires --format=esm for the worker
chunk.
2. Node bridging code is compiled in. The factory contains a Node
branch (lazy-loaded node:module / node:worker_threads for Node
runtime support) that browser bundlers will warn about as
"externalised". The warnings are harmless — the branch is dead code at
runtime in browsers — but if you want to silence them, mark the imports
external:
// vite.config.ts
export default defineConfig({
optimizeDeps: { exclude: ['@libraz/formulon'] },
build: {
rollupOptions: {
external: [/^node:/],
},
},
});If your bundler errors on the await import("node:...") form rather
than just warning, raise the build target to es2022 so the
async-function-scoped await lexes cleanly:
// vite.config.ts
export default defineConfig({
build: { target: 'es2022' },
});3. Workers + SharedArrayBuffer require cross-origin isolation. When
hosting in a browser, serve the page with Cross-Origin-Opener-Policy:
same-origin and Cross-Origin-Embedder-Policy: require-corp headers,
or pthread workers will refuse to start.
API reference
The full TypeScript surface is shipped as dist/formulon.d.ts and is the
authoritative reference. Highlights:
createFormulon(opts?)-- the default export. Returns a Promise resolving to aFormulonModule.Module.evalFormula(formula)-- one-shot evaluation against a fresh workbook.Module.Workbook.createDefault() / createEmpty() / loadBytes(bytes)-- factory methods for building or loading a workbook.Workbook.setNumber / setBool / setText / setBlank / setFormula-- cell mutators.Workbook.recalc()-- triggers a full dependency-ordered recalculation.Workbook.getValue(sheet, row, col)-- reads a cached cell value.Workbook.save()-- serialises back to an in-memory.xlsxbyte buffer.
Workbook handles wrap a native pointer; always call wb.delete() (in a
finally block) when done.
Project
Source, design notes, and the oracle test suite live at https://github.com/libraz/formulon.
