43 lines
1.7 KiB
JavaScript
43 lines
1.7 KiB
JavaScript
import { flatByTag, stubDescriptors } from "../child-stub.js";
|
|
import { NAME_TO_TYPE, TYPE_NAMES } from "./generated/node-types.js";
|
|
const N = NAME_TO_TYPE;
|
|
/** Per-type stub fields, mirroring `materializeHastNode`'s switch. */
|
|
const HAST_STUB_FIELDS = {
|
|
[N.root]: ["children"],
|
|
[N.element]: ["tagName", "properties", "children"],
|
|
[N.text]: ["value"],
|
|
[N.comment]: ["value"],
|
|
[N.doctype]: [],
|
|
[N.raw]: ["value"],
|
|
[N.mdxJsxFlowElement]: ["name", "attributes", "children"],
|
|
[N.mdxJsxTextElement]: ["name", "attributes", "children"],
|
|
[N.mdxFlowExpression]: ["value"],
|
|
[N.mdxTextExpression]: ["value"],
|
|
[N.mdxjsEsm]: ["value"],
|
|
};
|
|
const TYPE_NAME_BY_TAG = flatByTag(TYPE_NAMES);
|
|
const HAST_STUB_DESCRIPTORS = [];
|
|
for (const tag of Object.keys(HAST_STUB_FIELDS)) {
|
|
const nodeType = Number(tag);
|
|
HAST_STUB_DESCRIPTORS[nodeType] = stubDescriptors(HAST_STUB_FIELDS[nodeType]);
|
|
}
|
|
/** Unknown node types still expose the prelude-backed lazy fields. */
|
|
const FALLBACK_DESCRIPTORS = stubDescriptors([]);
|
|
/**
|
|
* Walk-path child stub: arena id + `type` eagerly, every other field a lazy
|
|
* forward to the materialized node (first read snapshots the arena via
|
|
* `materializeOne`, which enforces the handle epoch — the pass seal is checked
|
|
* where the stubs are built). Spread/identity rules are enforced by `nid()`
|
|
* in hast-visitor.ts.
|
|
*/
|
|
export class HastChildStub {
|
|
_resolver;
|
|
_id;
|
|
type;
|
|
constructor(resolver, id, nodeType) {
|
|
this._resolver = resolver;
|
|
this._id = id;
|
|
this.type = TYPE_NAME_BY_TAG[nodeType] ?? `unknown(${nodeType})`;
|
|
Object.defineProperties(this, HAST_STUB_DESCRIPTORS[nodeType] ?? FALLBACK_DESCRIPTORS);
|
|
}
|
|
}
|