@anzaui/engine - v0.6.0
    Preparing search index...

    Class Setup

    Configures and starts an Engine: Setup.run checks the template root and the signing keys, then loads and parses every template once.

    Template layout. Templates are plain .html files under root, addressed by their relative path:

    Path Used by
    layout/shell.html Optional document shell for every page; the page goes into {{content}}.
    pages/home.html Route /.
    pages/<route>.html Route /<route> (fallback pages/index.html, else NOT_FOUND).
    anything else Fragments, addressed by name, e.g. feed/card.html (limited by fragments when set).

    Parse once. run() reads every .html file, splits it into static strings and {{name}} / {{{name}}} placeholders (extract) and builds one render function per template (compile). There is no parsing or regular expression work at request time, and request input never reaches the filesystem: lookups only use the in-memory cache. Symlinked directories are not followed, symlinked files that resolve outside the root are skipped, and errors name the template, never the absolute path.

    Keys. Signing keys are validated here, once. Each of these makes run() reject with a CRYPTO error, so a running engine never sends unsigned envelopes by accident: an HMAC secret that is missing or shorter than 32 bytes; an Ed25519 privateKey that is missing or not a 32-byte seed, a 64-char lowercase hex seed, a PEM string or a KeyObject; a publicKey that does not match the private key. Setup, Engine and Signer never print key material: inspect and JSON.stringify show <redacted>.

    Runtimes. The engine uses Node.js built-ins (node:fs, node:crypto) and has no runtime dependencies. It runs on Node.js 18+ (tested), and on Bun and Deno through their Node compatibility. Runtimes without a filesystem (Cloudflare Workers and similar edge isolates) are not supported; there, only the template core (extract, compile, escapeHtml, stringify) works.

    import { Setup } from '@anzaui/engine';

    const engine = await new Setup({
    root: './templates',
    signing: { mode: 'hmac', secret: process.env.ANZA_SECRET! }, // at least 32 bytes
    fragments: ['feed/', 'widgets/clock.html'],
    escape: true,
    }).run();
    import { generateKeyPairSync } from 'node:crypto';
    import { Setup } from '@anzaui/engine';

    const { privateKey } = generateKeyPairSync('ed25519');
    const engine = await new Setup({ root: './templates', signing: { mode: 'ed25519', privateKey } }).run();
    const publicHex = engine.signer.publicKey!.toString('hex'); // publish this to verifiers
    Index
    escape: boolean

    Whether {{name}} values are HTML-escaped.

    fragments: string[]

    The fragment allowlist (empty allows every template).

    maxTemplateBytes: number

    Maximum template file size in bytes.

    root: string

    The template root directory.

    signing: SignOptions

    The signing options (never printed: see Setup.toJSON).

    watch: boolean

    Whether templates are reloaded on change.

    • Validate the root and the signing keys, load and parse every template, and start the watcher when watch is set.

      Returns Promise<Engine>

      The ready engine.

      AnzaError VALIDATION when the root does not exist; CRYPTO for a missing, short or malformed signing key; TEMPLATE for a template that does not parse or is larger than maxTemplateBytes; NOT_FOUND for a template that cannot be read.

      const engine = await new Setup('./templates').run();
      
    • The options with key material replaced by <redacted> (see redact), safe to log.

      Returns Record<string, unknown>

    • Check that the template root exists.

      Returns void

      AnzaError VALIDATION when root is empty or does not exist.