Appearance
Browser Usage
hizi engine generator works in the browser. It uses OPFS (Origin Private File System) for file storage. The same HiziEngineGenerator class works in both Node.js and the browser. The generator detects the environment automatically.
Requirements
- Run the generator in a dedicated Web Worker. OPFS sync access handles require this.
- The server must set Cross-Origin-Isolation headers for access to OPFS:
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corp
Import
typescript
import { HiziEngineGenerator } from '@hizi.io/engine-generator';Generating and Downloading
All files are plain JSONL during generation. The generator does not need compression at runtime.
typescript
const generator = new HiziEngineGenerator();
// Start - writes to OPFS
await generator.start('/sim-output');
// Record results (same as Node.js)
for (const outcome of simulationResults) {
generator.addResult(outcome.scenario, {
win: outcome.win,
metaTags: outcome.tags,
});
}
// Finalize - writes entries to OPFS, closes scenario stream
await generator.end();
// Get generated file contents (since 0.6.0 - getOutputFiles() was removed
// in 0.6.0). scenarios.jsonl is intentionally NOT retrievable this way: it
// can be arbitrarily large, so it stays on OPFS. Read it via
// `generator.outputDirectory` (see below).
const entries = generator.getEntries(); // entries.jsonl content
const config = generator.getConfig(); // config.json content, or null if
// end() was called without a configWARNING
getEntries() throws in three cases: before end() runs, in Node.js, or when end() writes no entries. In Node.js, read entries.jsonl.br from the output directory instead. getConfig() throws before end() runs or in Node.js.
Compressing for Download
To produce brotli-compressed .br files in the browser, use brotli-wasm:
bash
npm install brotli-wasmtypescript
import brotliWasm from 'brotli-wasm';
const bw = await brotliWasm;
const compress = (data: Uint8Array) => bw.compress(data, { quality: 9 });
// entries.jsonl is returned in memory by getEntries()
const entriesBr = compress(new TextEncoder().encode(generator.getEntries()));
// config.json (if you passed a config to end())
const config = generator.getConfig();
const configBr = config !== null ? compress(new TextEncoder().encode(config)) : null;
// scenarios.jsonl stays on OPFS - read it back from the output directory
async function readOpfsFile(dirPath: string, name: string): Promise<Uint8Array> {
let dir = await navigator.storage.getDirectory();
for (const part of dirPath.split('/').filter(Boolean)) {
dir = await dir.getDirectoryHandle(part);
}
const file = await (await dir.getFileHandle(name)).getFile();
return new Uint8Array(await file.arrayBuffer());
}
const scenarios = await readOpfsFile(generator.outputDirectory!, 'scenarios.jsonl');
const scenariosBr = compress(scenarios);Available Methods
| Method / Property | Description |
|---|---|
start(dir) | Start streaming to OPFS |
addResult() | Record a game outcome (scenarios stream directly to disk) |
end() | Finalize output: write entries, close scenario stream |
getEntries() | Get entries.jsonl content as a string (since 0.6.0). Throws before end() runs, in Node.js, or when end() writes no entries |
getConfig() | Get config.json content as a string, or null when end() runs without a config (since 0.6.0). Throws before end() runs or in Node.js |
outputDirectory | OPFS path (available after end() runs). Read scenarios directly from OPFS without loading them into memory. |