/** * lightning-yaml — a single-pass, allocation-minimal, pure-JS YAML 1.2.2 parser * engineered for V8 (see site/src/content/docs/research/notes/2026-07-12-design-a-pure-js-parser.md). * * The public surface mirrors `JSON.parse`: * - `parse(text)` text → JS value (a single document; throws if a second * document follows, like js-yaml's `load`) * - `parseAll(text)` text → array of document values — a real multi-document * stream, split on `---`/`...` markers * - `stringify(value)` value → YAML text (M6): block-style maps/sequences, * 1.2-core-safe scalar quoting, `Uint8Array` → `!!binary`, * and anchors/aliases for shared references and cycles — * see the "Stringify (dump)" section near the end of this * file for the design. * * Implementation status: the flow layer (JSON subset + YAML flow), block * structure (M3+), literal/folded block scalars (`|`/`>`, M4), document * markers (`---`/`...`), `%YAML`/`%TAG` directives, multi-document streams, * anchors/aliases (`&`/`*`, M5 — including self-referential/cyclic anchors and * structural sharing), tags (`!!binary` and friends), and `stringify` (M6) are * implemented. * * Design invariants enforced throughout (V8 rules, see doc 12): * - scan the flat JS string with `charCodeAt` (never `str[i]`) and hop long * runs with `indexOf` (memchr/SIMD class); never decode to bytes; * - materialize each scalar with exactly one `slice` from integer offsets; * - accumulate small integers as Smis (`v*10 + d`), no intermediate string; * - many small monomorphic functions, cold paths (errors, escapes) out of line; * - char classification via a Uint8Array(256) flag table (V8's json scan flags); * - module-level scalar state (non-reentrant, reset on entry) — no god-object * with a polymorphic `result` field; * - security from day one: `__proto__` never pollutes a prototype, and a hard * recursion-depth cap turns deep-nesting attacks into a controlled throw. * * Scalar typing follows YAML 1.2 **core schema** (the repo oracle, `yaml`): so * `null|Null|NULL|~` and empty → null; `true|True|TRUE|false|False|FALSE` → bool * (exact case; `yes/no/on/off` stay strings); decimal/`0o`/`0x` ints, floats, * and `.inf`/`.nan` are numbers; timestamps are NOT resolved (`2026-08-02` is a * string). Quoted scalars are never typed. This deliberately diverges from * js-yaml's 1.1-flavoured defaults (binary `0b`, `_` separators, sexagesimals, * timestamp→Date); those divergences are covered by differential tests. */ /** * Thrown by parts of the public API that aren't implemented yet. A dedicated * class lets the benchmark harness tell "not built yet" apart from a genuine * bug and skip the candidate rather than crash. */ declare class NotImplementedError extends Error { constructor(fn: string); } /** * Thrown by {@link parse} / {@link parseAll} when the input is not well-formed * YAML (or violates a parse constraint). The message includes the 1-based line * and column of the problem, rendered as `… (line L, column C)`. * * @example * ```ts * try { * parse("items: [1, 2"); * } catch (err) { * if (err instanceof YAMLParseError) console.error(err.message); * } * ``` */ declare class YAMLParseError extends Error { constructor(message: string); } /** * Opt-in parse-time performance tradeoffs. * * IMPORTANT DESIGN RULE: only optimizations that carry a real COST as well as a * benefit belong under `optimizations`. They are OFF by default so the caller * consciously opts in and accepts the tradeoff. Optimizations that are ~free * wins are ALWAYS enabled and never appear here (e.g. the existing key cache and * block-scalar accumulation). */ interface ParseOptimizations { /** * Intern repeated string scalar VALUES so equal values share one heap string * (map keys are always interned regardless). Trades ~+16% parse CPU for up to * ~-28% retained heap on data with many repeated string values; ~no benefit on * unique-value data. Correctness-invisible either way (interned strings are * `===`-equal and immutable). Default: `false`. */ internStrings?: boolean; } /** Options for {@link parse} / {@link parseAll}. Every field is optional; an omitted or `undefined` value leaves the parse behaviour byte-for-byte the default. */ interface ParseOptions { /** Opt-in performance tradeoffs — see {@link ParseOptimizations}. */ optimizations?: ParseOptimizations; } /** * Parse a single YAML document into a JavaScript value. * * Reads exactly one document — like `JSON.parse` and js-yaml's `load`. If * `text` contains more than one `---`-separated document (or any trailing * content after the first), `parse` throws rather than silently returning the * first; use {@link parseAll} for multi-document streams. Plain scalars are * typed per the YAML 1.2 core schema (`1` is a number, `true` a boolean, * `null`/`~`/empty a `null`); an empty document is `null`. * * @param text - The YAML source text. * @param options - Optional {@link ParseOptions}; omitting it (the default) * leaves parsing byte-for-byte unchanged. * @returns The document's value: an object, array, string, number, boolean, * or `null`. * @throws {@link YAMLParseError} if `text` is not well-formed YAML, or contains * more than one document. * * @example * ```ts * parse("dish: pancakes\nserves: 4") * // { dish: "pancakes", serves: 4 } * ``` */ declare function parse(text: string, options?: ParseOptions): unknown; /** * Parse a multi-document stream into an array of values, one entry per * document. * * Documents are separated by `---` (start) and/or `...` (end) markers; a * stream with no markers at all is a single (possibly bare) document, same as * {@link parse}. A source with no documents returns an empty array. * * @param text - The YAML source text, potentially containing multiple documents. * @param options - Optional {@link ParseOptions}; omitting it (the default) * leaves parsing byte-for-byte unchanged. * @returns One value per document, in document order. * @throws {@link YAMLParseError} if any document in the stream is not * well-formed YAML. * * @example * ```ts * parseAll("---\ndish: pancakes\n---\ndish: omelette\n") * // [{ dish: "pancakes" }, { dish: "omelette" }] * ``` */ declare function parseAll(text: string, options?: ParseOptions): unknown[]; /** * Serialize a JavaScript value into a YAML document string (always ending in a * trailing newline). * * Emits block-style collections; strings, numbers, booleans and `null` become * scalars, and a `Uint8Array` becomes a `!!binary` scalar. Values that share a * reference — or form a cycle — are emitted once with an anchor (`&`) and * referenced by alias (`*`) rather than duplicated, so `parse(stringify(x))` * reconstructs the same shared-reference graph rather than a deep copy. * * @param value - The value to serialize. * @returns The YAML document text. * * @example * ```ts * stringify({ dish: "pancakes", ingredients: ["flour", "milk", "eggs"] }) * // "dish: pancakes\ningredients:\n - flour\n - milk\n - eggs\n" * ``` */ declare function stringify(value: unknown): string; export { NotImplementedError, type ParseOptimizations, type ParseOptions, YAMLParseError, parse, parseAll, stringify };