fsa1-wasm
v0.3.3
Published
FSA1 in the browser: unpack an .xlsx to an in-memory file tree, render it, check it, evaluate formulas against it, and pack it back -- with no backend and no filesystem.
Maintainers
Readme
fsa1-wasm
FSA1 in the browser. Unpack an .xlsx into an in-memory file tree — tabs are folders, cells are
files — then render, check, evaluate and pack it back. No backend, no filesystem.
fsa1.sh — what it is, and why, with worked examples.
import init, { xlsx_to_html } from "fsa1-wasm";
await init(); // fetches the .wasm beside this module
const html = xlsx_to_html(new Uint8Array(bytes)); // xlsx -> tree -> a standalone documentUnder a bundler that hands you the asset URL, pass it as an object — a bare argument is the deprecated form and warns:
import wasmUrl from "fsa1-wasm/fsa1_wasm_bg.wasm?url";
await init({ module_or_path: wasmUrl });The payload is ~3.5 MB (~1.4 MB over the wire), so most hosts want it lazily.
A refusal crosses as a thrown Error whose name is a RefusalKind — the vocabulary fsa1-cli
maps to exit codes — carrying the located findings as its message. The union is exported, so a
switch over it is checkable.
A Session holds wasm memory. Call free() when you are done with it — from a component's unmount
hook, not on every render.
API
/**
* What `Session.render_fragment` hands back: the grid, for a page a host supplies itself.
*
* `markup` CARRIES `<style>` and `<script>` elements of its own -- a sidecar's layer rides in one,
* a figure's Vega runtime and mount script in others -- so mount it with
* `document.createRange().createContextualFragment(markup)`. `innerHTML` inserts those scripts
* inert, and no figure ever draws.
*/
export interface RenderedFragment {
/** The cascade, for a `<style>` in `<head>`: the `@layer` order THIS view computes. */
styles: string;
/** The body to mount, `<style>`, `<script>` and all. */
markup: string;
/** The formula bar's only listener, for a `<script>` after the markup. Without it the bar
* renders spans that never fill. */
script: string;
/** Advisories about the answer: an empty tab, or a figure whose spec would not expand. */
notes: string[];
}
/** Every `name` an `Error` thrown by this module carries. */
export type RefusalKind = "invalid-arguments" | "validation" | "conflict" | "not-found" | "io";
export class Session {
private constructor();
free(): void;
[Symbol.dispose](): void;
check(target: string): string[];
check_table(target: string): string;
eval(target: string, formula: string): any;
pack_xlsx(): Uint8Array;
render_ascii(target: string): string;
/**
* The four keys `RenderedFragment` spells in `fsa1_wasm.d.ts`.
*/
render_fragment(target: string): any;
render_html(target: string): string;
tabs(): string[];
tree(): any;
tree_ascii(target: string, full: boolean): string;
warnings(): string[];
}
export function load_tree(entries: any): Session;
export function unpack_xlsx(bytes: Uint8Array, strict: boolean, decomposition?: string | null): Session;
export function xlsx_to_html(bytes: Uint8Array, target?: string | null): string;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly memory: WebAssembly.Memory;
readonly __wbg_session_free: (a: number, b: number) => void;
readonly load_tree: (a: any) => [number, number, number];
readonly session_check: (a: number, b: number, c: number) => [number, number, number, number];
readonly session_check_table: (a: number, b: number, c: number) => [number, number, number, number];
readonly session_eval: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
readonly session_pack_xlsx: (a: number) => [number, number, number, number];
readonly session_render_ascii: (a: number, b: number, c: number) => [number, number, number, number];
readonly session_render_fragment: (a: number, b: number, c: number) => [number, number, number];
readonly session_render_html: (a: number, b: number, c: number) => [number, number, number, number];
readonly session_tabs: (a: number) => [number, number];
readonly session_tree: (a: number) => [number, number, number];
readonly session_tree_ascii: (a: number, b: number, c: number, d: number) => [number, number, number, number];
readonly session_warnings: (a: number) => [number, number];
readonly unpack_xlsx: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
readonly xlsx_to_html: (a: number, b: number, c: number, d: number) => [number, number, number, number];
readonly __wbindgen_malloc: (a: number, b: number) => number;
readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
readonly __wbindgen_exn_store: (a: number) => void;
readonly __externref_table_alloc: () => number;
readonly __wbindgen_externrefs: WebAssembly.Table;
readonly __externref_table_dealloc: (a: number) => void;
readonly __externref_drop_slice: (a: number, b: number) => void;
readonly __wbindgen_free: (a: number, b: number, c: number) => void;
readonly __wbindgen_start: () => void;
}
export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
*
* @returns {InitOutput}
*/
export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;MIT. Built from https://github.com/fredrikolis/FSA1
