@ai-react-markdown/engine 2.4.5 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +380 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +52 -58
- package/dist/index.d.ts +52 -58
- package/dist/index.dev.cjs +380 -65
- package/dist/index.dev.cjs.map +1 -1
- package/dist/index.dev.js +380 -63
- package/dist/index.dev.js.map +1 -1
- package/dist/index.js +380 -63
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -360,6 +360,16 @@ interface FreezeScanCheckpoint {
|
|
|
360
360
|
piOpen: boolean;
|
|
361
361
|
declOpen: boolean;
|
|
362
362
|
cdataOpen: boolean;
|
|
363
|
+
/** parse5 BOGUS COMMENT open inside a real html-flow run: `<!` not
|
|
364
|
+
* followed by `--` / letter / `[CDATA[`, or `</` not followed by a
|
|
365
|
+
* letter (`<!\n`, `<!-`, `</\n`, `<//`) — eaten up to the next `>`;
|
|
366
|
+
* a `</div>` inside is comment text, not a close (2026-08-19 review r2
|
|
367
|
+
* P1-3: the balance zeroed past an open div). micromark has no such
|
|
368
|
+
* construct: those bytes are just html-block content. */
|
|
369
|
+
bogusOpen: boolean;
|
|
370
|
+
/** The RAW_TEXT_ELEMENTS element currently open (its content is text to
|
|
371
|
+
* parse5): tags and comment tokens are ignored until `</name>`. */
|
|
372
|
+
rawTextOpen: string | null;
|
|
363
373
|
inFence: boolean;
|
|
364
374
|
fenceChar: string;
|
|
365
375
|
fenceLen: number;
|
|
@@ -457,6 +467,10 @@ interface FreezeScanCheckpoint {
|
|
|
457
467
|
* — or may still be the same html block (root-level ` </div\n</div>`,
|
|
458
468
|
* still garbage). Unknowable here → poison (oracle 3rd pass). */
|
|
459
469
|
tagAcrossLinesIndent: number;
|
|
470
|
+
/** parse5's position inside that tag's attribute area at the end of the
|
|
471
|
+
* last scanned line (see TagAttrState). A quoted value left open swallows
|
|
472
|
+
* `>` and line endings; a `>` that arrives while `outside` ends the tag. */
|
|
473
|
+
tagAcrossLinesState: TagAttrState;
|
|
460
474
|
/** The html-flow run since the last blank REALLY started as a micromark
|
|
461
475
|
* html block (type 6 / type 1 / a paragraph-not-interrupting type 7) —
|
|
462
476
|
* as opposed to `htmlFlowSinceBlank`, which any `<tag` / `</tag` line
|
|
@@ -469,6 +483,13 @@ interface FreezeScanCheckpoint {
|
|
|
469
483
|
* blank; a type 6/1 start on a later line of a non-real run promotes it. */
|
|
470
484
|
htmlFlowReal: boolean;
|
|
471
485
|
}
|
|
486
|
+
/** parse5 tokenizer position inside a tag's attribute area, tracked across
|
|
487
|
+
* line endings for `tagAcrossLines` (2026-08-19 review r2 P1-2 / P2-3):
|
|
488
|
+
* `outside` = before/in an attribute name (a `"` here starts a NAME, not a
|
|
489
|
+
* value); `afterEq` = just past `=`; `unquoted` = in an unquoted value
|
|
490
|
+
* (whitespace ends it); `"` / `'` = inside a quoted value — `>` and line
|
|
491
|
+
* endings are value bytes there, only the matching quote leaves it. */
|
|
492
|
+
type TagAttrState = 'outside' | 'afterEq' | 'unquoted' | '"' | "'";
|
|
472
493
|
declare function computeFreezeBoundary(text: string, options: FreezeBoundaryOptions, resume?: FreezeScanCheckpoint | null): FreezeScanResult;
|
|
473
494
|
|
|
474
495
|
/**
|
|
@@ -692,38 +713,6 @@ interface DefLabels {
|
|
|
692
713
|
linkLabels: Set<string>;
|
|
693
714
|
}
|
|
694
715
|
declare function collectDefLabels(source: string): DefLabels;
|
|
695
|
-
/** Index just past the LAST blank line of `source`, or 0 if none.
|
|
696
|
-
* Plain non-overlapping scan: for runs of blanks ("\n\n\n") this can land
|
|
697
|
-
* a newline or two early, but the slack is whitespace-only and whitespace
|
|
698
|
-
* can never satisfy DEF_LINE_START_RE, so the decision is identical.
|
|
699
|
-
* @internal exported for tests only — the fast path is otherwise
|
|
700
|
-
* indistinguishable from a full parse whose sets came out equal. */
|
|
701
|
-
declare function lastRegionStart(source: string): number;
|
|
702
|
-
/** A line that can START a definition, matched by the FULL def signature:
|
|
703
|
-
* container prefixes (blockquote `>`, list bullets, ordered-list digits),
|
|
704
|
-
* then `[label]` with the closing bracket IMMEDIATELY followed by `:` —
|
|
705
|
-
* remark accepts a definition only with that adjacency (grammar-verified:
|
|
706
|
-
* `[x]\n: url` and `[x] : url` are paragraphs, and `[a][b]: url` is a
|
|
707
|
-
* reference because the label's first unescaped `]` isn't followed by
|
|
708
|
-
* `:`). The label alternation admits escape pairs (`\]` stays inside the
|
|
709
|
-
* label) and spans newlines (labels may soft-wrap; they cannot cross the
|
|
710
|
-
* blank line that bounds the region). Both alternatives are disjoint, so
|
|
711
|
-
* the scan is linear — no backtracking blowup on bracket-dense regions.
|
|
712
|
-
*
|
|
713
|
-
* Requiring the signature (not just a line-start `[`) is what keeps the
|
|
714
|
-
* streaming-heavy shapes — bulleted link lists `- [t](u)`, task boxes
|
|
715
|
-
* `- [x]`, reference lists `- [a][b]` — on the fast path; a bracket-only
|
|
716
|
-
* probe made every append inside a blank-line-free link list pay a full
|
|
717
|
-
* reparse (the measured Documents+smooth cliff). An INCOMPLETE def line
|
|
718
|
-
* (`[x` with `]:` still in flight) correctly stays on the fast path too:
|
|
719
|
-
* the parser sees no definition in it either, and the region re-check on
|
|
720
|
-
* the completing append flips to the full parse exactly when the answer
|
|
721
|
-
* can change. The `m` flag also matches at index 0, which is a true line
|
|
722
|
-
* start (the region begins just past a blank line or at the document
|
|
723
|
-
* start). Residual over-matching (e.g. `[x]:` inside an open code fence)
|
|
724
|
-
* is safe: it costs a redundant full parse, never a wrong result.
|
|
725
|
-
* @internal exported for tests only. */
|
|
726
|
-
declare const DEF_LINE_START_RE: RegExp;
|
|
727
716
|
interface DefLabelScanner {
|
|
728
717
|
/** Equivalent to `collectDefLabels(source)` at every call, but cheap for
|
|
729
718
|
* the streaming common case. Returns a REFERENCE-STABLE result while the
|
|
@@ -949,8 +938,18 @@ interface RegistryInternal extends Registry {
|
|
|
949
938
|
* keeps the version monotonic-by-1-per-mount which makes debugging
|
|
950
939
|
* easier). The granular `allocateSymbol` / `contributeLabels` methods
|
|
951
940
|
* remain available for tests that need to exercise each step. */
|
|
952
|
-
registerChunk(reactId: string, footnotes: Set<string>, links: Set<string
|
|
953
|
-
|
|
941
|
+
registerChunk(reactId: string, footnotes: Set<string>, links: Set<string>, documentIndex?: number): symbol;
|
|
942
|
+
/** `documentIndex` — the chunk's position in the DOCUMENT (not its mount
|
|
943
|
+
* order). Without it a chunk joins `chunkOrder` at the end, which is
|
|
944
|
+
* wrong for any list that unmounts and remounts chunks: a virtualized
|
|
945
|
+
* transcript scrolling back re-registers an earlier chunk after the ones
|
|
946
|
+
* still mounted, and footnote numbering plus "which chunk renders the
|
|
947
|
+
* aggregate footer" follow that order (2026-08-19 review r2 P2-10).
|
|
948
|
+
* Chunks that supply an index are kept sorted by it; chunks without one
|
|
949
|
+
* keep mount order after them. */
|
|
950
|
+
allocateSymbol(reactId: string, documentIndex?: number): symbol;
|
|
951
|
+
/** @internal Insert a chunk Symbol at its document position. */
|
|
952
|
+
_placeChunk(sym: symbol, documentIndex?: number): void;
|
|
954
953
|
releaseSymbol(reactId: string): void;
|
|
955
954
|
contributeLabels(symbol: symbol, footnotes: Set<string>, links: Set<string>): void;
|
|
956
955
|
contributeChunkData(symbol: symbol, data: ChunkData): void;
|
|
@@ -958,6 +957,8 @@ interface RegistryInternal extends Registry {
|
|
|
958
957
|
symbol: symbol;
|
|
959
958
|
refcount: number;
|
|
960
959
|
}>;
|
|
960
|
+
/** Symbol → the `documentIndex` its chunk supplied (see allocateSymbol). */
|
|
961
|
+
_chunkIndex: Map<symbol, number>;
|
|
961
962
|
_subscribers: Set<() => void>;
|
|
962
963
|
_notifyScheduled: boolean;
|
|
963
964
|
_notify(): void;
|
|
@@ -1062,6 +1063,12 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
1062
1063
|
* uncaught — there is no try/catch. Callers usually invoke this once at
|
|
1063
1064
|
* module load, where a thrown error surfaces as a startup-time crash and
|
|
1064
1065
|
* is the correct failure mode.
|
|
1066
|
+
* - **Widening is total.** Adding a tag to `tagNames` admits that element
|
|
1067
|
+
* with ALL of its semantics — `script`, `iframe`, `style`, `object`,
|
|
1068
|
+
* `form`, `base` re-enter the tree verbatim, and the two-gate URL story
|
|
1069
|
+
* in the README / SECURITY.md no longer describes your renderer. Prefer
|
|
1070
|
+
* allowing an attribute or a protocol over allowing an element; treat
|
|
1071
|
+
* any element you add as trusted input.
|
|
1065
1072
|
*
|
|
1066
1073
|
* @param modifier - Receives a deep clone of the library default. Mutate it
|
|
1067
1074
|
* freely; either return the (possibly different) result, or return
|
|
@@ -1456,10 +1463,16 @@ declare function isFootnoteSection(node: Element): boolean;
|
|
|
1456
1463
|
|
|
1457
1464
|
declare function normalizeId(s: string): string;
|
|
1458
1465
|
/**
|
|
1459
|
-
*
|
|
1460
|
-
*
|
|
1461
|
-
*
|
|
1462
|
-
*
|
|
1466
|
+
* The form of raw chunk SOURCE that the PASS 0.5 substring pre-check compares
|
|
1467
|
+
* registry labels against. It is exactly {@link normalizeId}: micromark's
|
|
1468
|
+
* `identifier` (what the registry keys are built from) is the label's
|
|
1469
|
+
* source bytes with backslashes KEPT (`[^a\*b]` → `a\*b`; only the `label`
|
|
1470
|
+
* field is unescaped), so the source must NOT be unescaped before matching
|
|
1471
|
+
* — an unescaping pass made every label holding an escaped punctuation
|
|
1472
|
+
* character miss the pre-check for good, and the cross-chunk reference
|
|
1473
|
+
* rendered as literal `[text][label]` (2026-08-19 review r2 P2-5; the
|
|
1474
|
+
* 2.4.5 narrowing to ASCII punctuation kept the wrong premise). Kept as a
|
|
1475
|
+
* named export for API stability.
|
|
1463
1476
|
*/
|
|
1464
1477
|
declare function normalizeForMatch(s: string): string;
|
|
1465
1478
|
|
|
@@ -1647,25 +1660,6 @@ type AttributeEntry = NonNullable<NonNullable<Schema['attributes']>[string]>[num
|
|
|
1647
1660
|
* is always tuple-form, so this branch is defensive only.
|
|
1648
1661
|
*/
|
|
1649
1662
|
declare function mergeClassNameAllowlist(existing: ReadonlyArray<AttributeEntry> | undefined, extraClassNames: readonly string[]): AttributeEntry[];
|
|
1650
|
-
/**
|
|
1651
|
-
* The full sanitize schema used by the markdown renderer: extends
|
|
1652
|
-
* `defaultSchema` to allow `<mark>`, the KaTeX math class names, and the
|
|
1653
|
-
* three custom hast tags emitted by cross-chunk coordination handlers.
|
|
1654
|
-
*
|
|
1655
|
-
* **Owns its arrays and objects.** The shallow spread of `defaultSchema`
|
|
1656
|
-
* alone would leave `attributes.a`, `attributes.img`, `protocols`,
|
|
1657
|
-
* `ancestors`, and similar nested fields aliased to `rehype-sanitize`'s
|
|
1658
|
-
* default singleton. A consumer who reasonably (but mistakenly) writes
|
|
1659
|
-
* `sanitizeSchema.protocols.href.push('myapp')` would then poison
|
|
1660
|
-
* `rehype-sanitize`'s `defaultSchema` for every other consumer in the
|
|
1661
|
-
* process — a cross-package side-effect that's near-impossible to debug.
|
|
1662
|
-
*
|
|
1663
|
-
* One `cloneDeep` at module init breaks that aliasing without measurable
|
|
1664
|
-
* cost (init-time only, single small object graph). The recommended
|
|
1665
|
-
* extension API is still {@link extendSanitizeSchema}, which clones again
|
|
1666
|
-
* per call; this layer just makes the exported singleton safe if someone
|
|
1667
|
-
* skips the helper.
|
|
1668
|
-
*/
|
|
1669
1663
|
declare const sanitizeSchema: Schema;
|
|
1670
1664
|
|
|
1671
1665
|
/**
|
|
@@ -2027,4 +2021,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
|
|
|
2027
2021
|
*/
|
|
2028
2022
|
declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
|
|
2029
2023
|
|
|
2030
|
-
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD,
|
|
2024
|
+
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|
package/dist/index.d.ts
CHANGED
|
@@ -360,6 +360,16 @@ interface FreezeScanCheckpoint {
|
|
|
360
360
|
piOpen: boolean;
|
|
361
361
|
declOpen: boolean;
|
|
362
362
|
cdataOpen: boolean;
|
|
363
|
+
/** parse5 BOGUS COMMENT open inside a real html-flow run: `<!` not
|
|
364
|
+
* followed by `--` / letter / `[CDATA[`, or `</` not followed by a
|
|
365
|
+
* letter (`<!\n`, `<!-`, `</\n`, `<//`) — eaten up to the next `>`;
|
|
366
|
+
* a `</div>` inside is comment text, not a close (2026-08-19 review r2
|
|
367
|
+
* P1-3: the balance zeroed past an open div). micromark has no such
|
|
368
|
+
* construct: those bytes are just html-block content. */
|
|
369
|
+
bogusOpen: boolean;
|
|
370
|
+
/** The RAW_TEXT_ELEMENTS element currently open (its content is text to
|
|
371
|
+
* parse5): tags and comment tokens are ignored until `</name>`. */
|
|
372
|
+
rawTextOpen: string | null;
|
|
363
373
|
inFence: boolean;
|
|
364
374
|
fenceChar: string;
|
|
365
375
|
fenceLen: number;
|
|
@@ -457,6 +467,10 @@ interface FreezeScanCheckpoint {
|
|
|
457
467
|
* — or may still be the same html block (root-level ` </div\n</div>`,
|
|
458
468
|
* still garbage). Unknowable here → poison (oracle 3rd pass). */
|
|
459
469
|
tagAcrossLinesIndent: number;
|
|
470
|
+
/** parse5's position inside that tag's attribute area at the end of the
|
|
471
|
+
* last scanned line (see TagAttrState). A quoted value left open swallows
|
|
472
|
+
* `>` and line endings; a `>` that arrives while `outside` ends the tag. */
|
|
473
|
+
tagAcrossLinesState: TagAttrState;
|
|
460
474
|
/** The html-flow run since the last blank REALLY started as a micromark
|
|
461
475
|
* html block (type 6 / type 1 / a paragraph-not-interrupting type 7) —
|
|
462
476
|
* as opposed to `htmlFlowSinceBlank`, which any `<tag` / `</tag` line
|
|
@@ -469,6 +483,13 @@ interface FreezeScanCheckpoint {
|
|
|
469
483
|
* blank; a type 6/1 start on a later line of a non-real run promotes it. */
|
|
470
484
|
htmlFlowReal: boolean;
|
|
471
485
|
}
|
|
486
|
+
/** parse5 tokenizer position inside a tag's attribute area, tracked across
|
|
487
|
+
* line endings for `tagAcrossLines` (2026-08-19 review r2 P1-2 / P2-3):
|
|
488
|
+
* `outside` = before/in an attribute name (a `"` here starts a NAME, not a
|
|
489
|
+
* value); `afterEq` = just past `=`; `unquoted` = in an unquoted value
|
|
490
|
+
* (whitespace ends it); `"` / `'` = inside a quoted value — `>` and line
|
|
491
|
+
* endings are value bytes there, only the matching quote leaves it. */
|
|
492
|
+
type TagAttrState = 'outside' | 'afterEq' | 'unquoted' | '"' | "'";
|
|
472
493
|
declare function computeFreezeBoundary(text: string, options: FreezeBoundaryOptions, resume?: FreezeScanCheckpoint | null): FreezeScanResult;
|
|
473
494
|
|
|
474
495
|
/**
|
|
@@ -692,38 +713,6 @@ interface DefLabels {
|
|
|
692
713
|
linkLabels: Set<string>;
|
|
693
714
|
}
|
|
694
715
|
declare function collectDefLabels(source: string): DefLabels;
|
|
695
|
-
/** Index just past the LAST blank line of `source`, or 0 if none.
|
|
696
|
-
* Plain non-overlapping scan: for runs of blanks ("\n\n\n") this can land
|
|
697
|
-
* a newline or two early, but the slack is whitespace-only and whitespace
|
|
698
|
-
* can never satisfy DEF_LINE_START_RE, so the decision is identical.
|
|
699
|
-
* @internal exported for tests only — the fast path is otherwise
|
|
700
|
-
* indistinguishable from a full parse whose sets came out equal. */
|
|
701
|
-
declare function lastRegionStart(source: string): number;
|
|
702
|
-
/** A line that can START a definition, matched by the FULL def signature:
|
|
703
|
-
* container prefixes (blockquote `>`, list bullets, ordered-list digits),
|
|
704
|
-
* then `[label]` with the closing bracket IMMEDIATELY followed by `:` —
|
|
705
|
-
* remark accepts a definition only with that adjacency (grammar-verified:
|
|
706
|
-
* `[x]\n: url` and `[x] : url` are paragraphs, and `[a][b]: url` is a
|
|
707
|
-
* reference because the label's first unescaped `]` isn't followed by
|
|
708
|
-
* `:`). The label alternation admits escape pairs (`\]` stays inside the
|
|
709
|
-
* label) and spans newlines (labels may soft-wrap; they cannot cross the
|
|
710
|
-
* blank line that bounds the region). Both alternatives are disjoint, so
|
|
711
|
-
* the scan is linear — no backtracking blowup on bracket-dense regions.
|
|
712
|
-
*
|
|
713
|
-
* Requiring the signature (not just a line-start `[`) is what keeps the
|
|
714
|
-
* streaming-heavy shapes — bulleted link lists `- [t](u)`, task boxes
|
|
715
|
-
* `- [x]`, reference lists `- [a][b]` — on the fast path; a bracket-only
|
|
716
|
-
* probe made every append inside a blank-line-free link list pay a full
|
|
717
|
-
* reparse (the measured Documents+smooth cliff). An INCOMPLETE def line
|
|
718
|
-
* (`[x` with `]:` still in flight) correctly stays on the fast path too:
|
|
719
|
-
* the parser sees no definition in it either, and the region re-check on
|
|
720
|
-
* the completing append flips to the full parse exactly when the answer
|
|
721
|
-
* can change. The `m` flag also matches at index 0, which is a true line
|
|
722
|
-
* start (the region begins just past a blank line or at the document
|
|
723
|
-
* start). Residual over-matching (e.g. `[x]:` inside an open code fence)
|
|
724
|
-
* is safe: it costs a redundant full parse, never a wrong result.
|
|
725
|
-
* @internal exported for tests only. */
|
|
726
|
-
declare const DEF_LINE_START_RE: RegExp;
|
|
727
716
|
interface DefLabelScanner {
|
|
728
717
|
/** Equivalent to `collectDefLabels(source)` at every call, but cheap for
|
|
729
718
|
* the streaming common case. Returns a REFERENCE-STABLE result while the
|
|
@@ -949,8 +938,18 @@ interface RegistryInternal extends Registry {
|
|
|
949
938
|
* keeps the version monotonic-by-1-per-mount which makes debugging
|
|
950
939
|
* easier). The granular `allocateSymbol` / `contributeLabels` methods
|
|
951
940
|
* remain available for tests that need to exercise each step. */
|
|
952
|
-
registerChunk(reactId: string, footnotes: Set<string>, links: Set<string
|
|
953
|
-
|
|
941
|
+
registerChunk(reactId: string, footnotes: Set<string>, links: Set<string>, documentIndex?: number): symbol;
|
|
942
|
+
/** `documentIndex` — the chunk's position in the DOCUMENT (not its mount
|
|
943
|
+
* order). Without it a chunk joins `chunkOrder` at the end, which is
|
|
944
|
+
* wrong for any list that unmounts and remounts chunks: a virtualized
|
|
945
|
+
* transcript scrolling back re-registers an earlier chunk after the ones
|
|
946
|
+
* still mounted, and footnote numbering plus "which chunk renders the
|
|
947
|
+
* aggregate footer" follow that order (2026-08-19 review r2 P2-10).
|
|
948
|
+
* Chunks that supply an index are kept sorted by it; chunks without one
|
|
949
|
+
* keep mount order after them. */
|
|
950
|
+
allocateSymbol(reactId: string, documentIndex?: number): symbol;
|
|
951
|
+
/** @internal Insert a chunk Symbol at its document position. */
|
|
952
|
+
_placeChunk(sym: symbol, documentIndex?: number): void;
|
|
954
953
|
releaseSymbol(reactId: string): void;
|
|
955
954
|
contributeLabels(symbol: symbol, footnotes: Set<string>, links: Set<string>): void;
|
|
956
955
|
contributeChunkData(symbol: symbol, data: ChunkData): void;
|
|
@@ -958,6 +957,8 @@ interface RegistryInternal extends Registry {
|
|
|
958
957
|
symbol: symbol;
|
|
959
958
|
refcount: number;
|
|
960
959
|
}>;
|
|
960
|
+
/** Symbol → the `documentIndex` its chunk supplied (see allocateSymbol). */
|
|
961
|
+
_chunkIndex: Map<symbol, number>;
|
|
961
962
|
_subscribers: Set<() => void>;
|
|
962
963
|
_notifyScheduled: boolean;
|
|
963
964
|
_notify(): void;
|
|
@@ -1062,6 +1063,12 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
1062
1063
|
* uncaught — there is no try/catch. Callers usually invoke this once at
|
|
1063
1064
|
* module load, where a thrown error surfaces as a startup-time crash and
|
|
1064
1065
|
* is the correct failure mode.
|
|
1066
|
+
* - **Widening is total.** Adding a tag to `tagNames` admits that element
|
|
1067
|
+
* with ALL of its semantics — `script`, `iframe`, `style`, `object`,
|
|
1068
|
+
* `form`, `base` re-enter the tree verbatim, and the two-gate URL story
|
|
1069
|
+
* in the README / SECURITY.md no longer describes your renderer. Prefer
|
|
1070
|
+
* allowing an attribute or a protocol over allowing an element; treat
|
|
1071
|
+
* any element you add as trusted input.
|
|
1065
1072
|
*
|
|
1066
1073
|
* @param modifier - Receives a deep clone of the library default. Mutate it
|
|
1067
1074
|
* freely; either return the (possibly different) result, or return
|
|
@@ -1456,10 +1463,16 @@ declare function isFootnoteSection(node: Element): boolean;
|
|
|
1456
1463
|
|
|
1457
1464
|
declare function normalizeId(s: string): string;
|
|
1458
1465
|
/**
|
|
1459
|
-
*
|
|
1460
|
-
*
|
|
1461
|
-
*
|
|
1462
|
-
*
|
|
1466
|
+
* The form of raw chunk SOURCE that the PASS 0.5 substring pre-check compares
|
|
1467
|
+
* registry labels against. It is exactly {@link normalizeId}: micromark's
|
|
1468
|
+
* `identifier` (what the registry keys are built from) is the label's
|
|
1469
|
+
* source bytes with backslashes KEPT (`[^a\*b]` → `a\*b`; only the `label`
|
|
1470
|
+
* field is unescaped), so the source must NOT be unescaped before matching
|
|
1471
|
+
* — an unescaping pass made every label holding an escaped punctuation
|
|
1472
|
+
* character miss the pre-check for good, and the cross-chunk reference
|
|
1473
|
+
* rendered as literal `[text][label]` (2026-08-19 review r2 P2-5; the
|
|
1474
|
+
* 2.4.5 narrowing to ASCII punctuation kept the wrong premise). Kept as a
|
|
1475
|
+
* named export for API stability.
|
|
1463
1476
|
*/
|
|
1464
1477
|
declare function normalizeForMatch(s: string): string;
|
|
1465
1478
|
|
|
@@ -1647,25 +1660,6 @@ type AttributeEntry = NonNullable<NonNullable<Schema['attributes']>[string]>[num
|
|
|
1647
1660
|
* is always tuple-form, so this branch is defensive only.
|
|
1648
1661
|
*/
|
|
1649
1662
|
declare function mergeClassNameAllowlist(existing: ReadonlyArray<AttributeEntry> | undefined, extraClassNames: readonly string[]): AttributeEntry[];
|
|
1650
|
-
/**
|
|
1651
|
-
* The full sanitize schema used by the markdown renderer: extends
|
|
1652
|
-
* `defaultSchema` to allow `<mark>`, the KaTeX math class names, and the
|
|
1653
|
-
* three custom hast tags emitted by cross-chunk coordination handlers.
|
|
1654
|
-
*
|
|
1655
|
-
* **Owns its arrays and objects.** The shallow spread of `defaultSchema`
|
|
1656
|
-
* alone would leave `attributes.a`, `attributes.img`, `protocols`,
|
|
1657
|
-
* `ancestors`, and similar nested fields aliased to `rehype-sanitize`'s
|
|
1658
|
-
* default singleton. A consumer who reasonably (but mistakenly) writes
|
|
1659
|
-
* `sanitizeSchema.protocols.href.push('myapp')` would then poison
|
|
1660
|
-
* `rehype-sanitize`'s `defaultSchema` for every other consumer in the
|
|
1661
|
-
* process — a cross-package side-effect that's near-impossible to debug.
|
|
1662
|
-
*
|
|
1663
|
-
* One `cloneDeep` at module init breaks that aliasing without measurable
|
|
1664
|
-
* cost (init-time only, single small object graph). The recommended
|
|
1665
|
-
* extension API is still {@link extendSanitizeSchema}, which clones again
|
|
1666
|
-
* per call; this layer just makes the exported singleton safe if someone
|
|
1667
|
-
* skips the helper.
|
|
1668
|
-
*/
|
|
1669
1663
|
declare const sanitizeSchema: Schema;
|
|
1670
1664
|
|
|
1671
1665
|
/**
|
|
@@ -2027,4 +2021,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
|
|
|
2027
2021
|
*/
|
|
2028
2022
|
declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
|
|
2029
2023
|
|
|
2030
|
-
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD,
|
|
2024
|
+
export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, type DefLabelScanner, type DefLabels, type Deprecation, type EnginePluginInternals, type EnginePluginStage, type ExtractContributionsOptions, type FootnoteDef, type FreezeBoundaryOptions, type IncrementalParseState, type IncrementalStage, type LinkDef, PIPELINE_STAGES, type ParsedMarkdown, type PhantomLabels, type PipelineOptions, type PipelineStage, type RefKind, type RefRecord, type Registry, type RegistryInternal, type RehypePlugins, type RehypeRebaseHashLinksOptions, type RemarkPlugins, type RemarkRehypeOptions, type RemendPreprocessorOptions, SENTINEL_FN_CONTENT, SENTINEL_LINK_URL, SMOOTH_STREAM_PACING_PRESETS, STAGE_MEASURE_PREFIX, type SanitizeSchema, type SmoothStreamController, type SmoothStreamOptions, type SmoothStreamPacing, type SmoothStreamPacingParams, type TransformContext, type UrlAttrKey, type UrlAttrTag, type UrlTransform, advanceIncrementalParse, attributeHastChildren, buildCoreRehypePlugins, buildCoreRemarkPlugins, buildCoreRemarkRehypeOptions, buildCrossChunkHandlers, buildPhantomSuffix, buildTransform, codePointSnapshots, collectDefLabels, computeFreezeBoundary, createDefLabelScanner, createFile, createIncrementalLatexPreprocessor, createProcessor, createRegistry, createRemendPreprocessor, createSmoothStreamController, defaultEnginePlugins, defaultUrlTransform, definitionList, extendSanitizeSchema, extractContributions, extractDefBodiesFromHast, footnoteSafeId, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
|