DOM ENGINEV0.10.0FIZLET

BOARD PAGE V0.10.0

fizlet/board-page

The host page as the board. Its text glyphs become terrain and food, its buttons become targets. Geometry is measured only in the read phase, on a budget (Range reads capped per refresh; 12.5 Hz while the page moves, 2 Hz once it is still), kept in typed arrays and indexed with a collide Grid, so near / hit in a step never read layout or allocate. consume writes a literal 0/1 into the page's own Text node through the ledger (no wrappers, no clones); from a step it is queued and written in render. Recall gives every glyph back, and a newer edit by the host page wins. Coordinates are viewport CSS px (getBoundingClientRect). Glyph indices hold for a frame: a rescan (read phase, after the page changed) renumbers them.

fizlet/board-page · GZIP3,812 B3.7 KB of a 4.0 KB budget

Measured on this build: minified and gzipped with everything it imports, the way npm run size checks the budget in CI.

MODULES · hosted on this site
import { boardPage } from "https://coded-dot-design.github.io/fizlet/dist/board-page.js";
NPM · COMING SOON
npm install fizlet   # not published yet
import { boardPage } from "fizlet/board-page";

API

Every export, with its doc comment, read from the published type declarations of v0.10.0.

BoardPageOptions interface

export interface BoardPageOptions {
    /** The part of the page that is the board (default document.body). */
    root?: Element;
    /** Text containers (default headings, p, li, blockquote, [data-fizlet-text]); 160 at most. */
    text?: string;
    /** Targets (default button, [role=button], a.button, a.btn, [data-fizlet-target]). */
    targets?: string;
    /** More to leave alone, on top of fields, editable, code, live regions, dialogs, [data-fizlet-ignore]. */
    exclude?: string;
    /** Glyphs indexed at most (default 8000). */
    maxGlyphs?: number;
    /** Targets at most (default 32). */
    maxTargets?: number;
    /** Range reads per refresh at most (default 900); the rest are measured on the next refresh. */
    reads?: number;
    /** Hex colour for consumed glyphs (a CSS Custom Highlight, where supported). Off by default. */
    color?: string;
}

BoardTarget interface

export interface BoardTarget {
    readonly el: Element;
    /** Viewport rect, measured in read; w = h = 0 while hidden or off screen. */
    x: number;
    y: number;
    w: number;
    h: number;
    /** The game's to use: starts at 100 and survives a rescan. */
    hp: number;
}

boardPage function

export declare function boardPage(e: Engine, o?: BoardPageOptions): {
    glyphs: {
        /** Glyphs indexed, spent ones included (w = 0 while not on screen). */
        readonly count: number;
        x: Float32Array<ArrayBuffer>;
        y: Float32Array<ArrayBuffer>;
        w: Float32Array<ArrayBuffer>;
        h: Float32Array<ArrayBuffer>;
        /** 1 once consumed. */
        spent: Uint8Array<ArrayBuffer>;
    };
    /** Page targets (rects measured in read). */
    targets: readonly BoardTarget[];
    /** Unspent on-screen glyphs touching the circle, into `out`. Returns how many. */
    near(px: number, py: number, pr: number, out: Int32Array): number;
    /** First unspent glyph the segment touches (2 px pad), or -1; how far along it (0..1) is `t`. */
    hit(x0: number, y0: number, x1: number, y1: number): number;
    readonly t: number;
    /** Range reads made by the last refresh (never more than `reads`). */
    readonly reads: number;
    /**
     * Consume glyph i: a 0/1 ("binary") or a no-break space ("erase") in the page's own text,
     * through the ledger; from a step it is written in render. False if spent or not ours anymore.
     */
    consume(i: number, as?: "binary" | "erase"): boolean;
    /** Rescan and re-measure now; from a step, at the next read. */
    refresh(): void;
    system: System;
};

BoardPage type

export type BoardPage = ReturnType<typeof boardPage>;