docs/solutions/best-practices/2026-05-09-lexical-normalization-harvest-rows-need-selection-query-boundaries.md
Lexical's LexicalNormalization.test.tsx looks like tree-normalization
coverage by filename, but the file tests $normalizeSelection: element-backed
selection endpoints are converted to concrete text endpoints when possible.
LexicalNormalization, but every test builds a
RangeSelection and calls $normalizeSelection.Point values target text nodes.Route the portable part to Slate's public query APIs:
Editor.range(editor, path);Editor.edges(editor, path);Editor.range and
Editor.edges;Editor.point(editor, range) and { edge: 'end' }.The compact proof belongs in
.tmp/slate-v2/packages/slate/test/query-contract.ts, not in
normalization-contract.ts.
Slate's public selection model stores text points. Lexical's normalization helper is useful only as a reminder to prove that callers can pass element paths and still get stable text endpoints through the public query layer.
Decorator and element-point rows are intentionally not generic Slate behavior. They should only come back under a real decorator, void, or browser-selection owner.
normalization-contract.ts; keep
path/range/point resolution rows in query-contract.ts.