@ai-react-markdown/engine 2.4.0 → 2.4.2

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/dist/index.d.cts CHANGED
@@ -218,9 +218,11 @@ declare const defaultUrlTransform: UrlTransform;
218
218
  * whether a sibling node FOLLOWS it. A tail block that flips between
219
219
  * def (no hast output) and paragraph therefore reshapes the frozen
220
220
  * region retroactively (2026-07-31 direction-battery counterexample,
221
- * reproduced on v1.8.0). The candidate adjacent to such a run is
222
- * rejected until a later confirmed content line pins the seam from the
223
- * frozen side; dropping candidates only over-blocks (safe direction).
221
+ * reproduced on v1.8.0). Every candidate emitted while the remnant is
222
+ * the last frozen child is rejected (they stay rejected for good); once
223
+ * a later confirmed content line pins the seam from the frozen side,
224
+ * the candidates AFTER that line are safe again. Dropping candidates
225
+ * only over-blocks (safe direction). Whitespace-only remnant counts.
224
226
  * A type 2-5 block that opens AND closes on its first line owns the
225
227
  * rest of that line as raw content too (`<!-- c --> tail`) — same seam.
226
228
  * 7. **Phase poison** (`phasePoisonedAt`) — points where this line-level
@@ -382,6 +384,16 @@ interface FreezeScanCheckpoint {
382
384
  prevLineWasValidDef: boolean;
383
385
  /** An earlier line of the current paragraph left an unpaired backtick
384
386
  * run — masking is disabled until the paragraph ends (safety gate). */
387
+ /** A `[` left unclosed at the end of a paragraph line (code spans
388
+ * masked). micromark lets a reference label span soft line breaks, so
389
+ * the label may close on a LATER line where the per-line REF_RE never
390
+ * sees a `[…]` pair (v2.4.1 review P1: `see [foo\nbar] end` + a late
391
+ * `[foo bar]: /u` retargeted frozen output). Cleared wherever the
392
+ * paragraph ends. */
393
+ openBracket: {
394
+ offset: number;
395
+ text: string;
396
+ } | null;
385
397
  paragraphHasUnpairedRun: boolean;
386
398
  /** Blocker-6 pending flag: a confirmed html-flow line left balanced
387
399
  * floating raw remnant, and no later content line has pinned the seam
@@ -708,6 +720,17 @@ interface DefLabelScanner {
708
720
  */
709
721
  declare function createDefLabelScanner(parse?: (source: string) => DefLabels): DefLabelScanner;
710
722
 
723
+ /**
724
+ * The id fragment mdast-util-to-hast derives from a footnote identifier for
725
+ * `fn-…` / `fnref-…` (`normalizeUri(identifier.toLowerCase())` — percent-
726
+ * encodes non-ASCII, whitespace and URL-unsafe punctuation). Every place
727
+ * that MINTS a footnote id — the standalone footer (upstream), the
728
+ * cross-chunk marks and the aggregate footer — must use this same
729
+ * encoding, or a mark's `href` and its `<li id>` disagree (v2.4.0 review:
730
+ * the fallback mark wrote the raw label while the local footer was
731
+ * encoded; `[^注]` / `[^a%b]` anchors broke).
732
+ */
733
+ declare function footnoteSafeId(identifier: string): string;
711
734
  /**
712
735
  * Extract the SOURCE identifier from a footnote `<li>` id, covering both id
713
736
  * shapes in the codebase — standalone (mdast-util-to-hast `fn-` +
@@ -837,10 +860,12 @@ interface ChunkData {
837
860
  * interface. Driving the registry directly is reserved for internal
838
861
  * coordinators (the package's own `MarkdownContent` renderer) and tests,
839
862
  * which import the wider `RegistryInternal` type from this module.
840
- * `RegistryInternal` is exported here but NOT re-exported from the package
841
- * barrel keeping mutators off the public surface prevents a misbehaving
842
- * consumer-component from corrupting refcounts, skipping version bumps, or
843
- * otherwise breaking the invariants the renderer relies on.
863
+ * `RegistryInternal` is exported from this engine package (the core
864
+ * renderer consumes it) but NOT from `@ai-react-markdown/core`'s public
865
+ * barrel keeping mutators off the consumer-facing surface prevents a
866
+ * misbehaving consumer-component from corrupting refcounts, skipping
867
+ * version bumps, or otherwise breaking the invariants the renderer relies
868
+ * on.
844
869
  */
845
870
  interface Registry {
846
871
  /** Chunk mount-order Symbol list. **Read-only.** Direct mutation
@@ -893,9 +918,10 @@ interface Registry {
893
918
  * methods and implementation-private fields (reactId-keyed refcount table,
894
919
  * subscriber set, microtask-coalesce flag, `_notify` itself).
895
920
  *
896
- * Exported from this module so internal coordinators (`MarkdownContent`)
897
- * and tests can hold a strongly-typed reference, but **not** re-exported
898
- * from the package barrel a consumer flipping `_notifyScheduled = true`
921
+ * Exported from this module (and the engine barrel) so internal
922
+ * coordinators (`MarkdownContent`) and tests can hold a strongly-typed
923
+ * reference, but **not** re-exported from `@ai-react-markdown/core`'s
924
+ * barrel — a consumer flipping `_notifyScheduled = true`
899
925
  * or pushing into `chunkOrder` directly would silently break the
900
926
  * coalesce / numbering invariants. The runtime value returned by
901
927
  * {@link createRegistry} always satisfies this wider shape; public consumers
@@ -1235,11 +1261,16 @@ declare function buildPhantomSuffix(phantoms: PhantomLabels): string;
1235
1261
  * extend past `content.length`, which every consumer already tolerates for
1236
1262
  * the suffix's own nodes).
1237
1263
  *
1238
- * The closer is emitted at the opener line's indent, which closes the block
1239
- * both at top level (≤3 spaces are permitted there) and inside a list item
1240
- * whose content indent the opener already satisfies (a column-0 closer
1241
- * would END the item and open a NEW block that swallows the suffix worse
1242
- * than not closing).
1264
+ * A closer is emitted ONLY for a block whose opener line sits at column 0:
1265
+ * that is provably a top-level fence, which only a top-level closer (same
1266
+ * char, length, ≤3 spaces indent) can end exactly what the line scanner
1267
+ * tracks. Openers with any indent are left alone: the line model cannot
1268
+ * see container boundaries, and an indented opener may live in a list item
1269
+ * that later de-indented content already ended (micromark closed the fence
1270
+ * with the item; an emitted closer would OPEN a new fence around the
1271
+ * sentinel lines — v2.4.0 review R1) or be closed by a ≥4-space closer the
1272
+ * `^ {0,3}` scan does not recognize. Those shapes keep the plain append
1273
+ * (swallowed at worst — the pre-2.4.0 behaviour), never a wrong closer.
1243
1274
  *
1244
1275
  * Only fences and flow math are closed. Raw-HTML constructs (`<!--`, `<?`,
1245
1276
  * `<![CDATA[`, `<!X`, `<script>`) that stay open to EOF also swallow the
@@ -1301,11 +1332,13 @@ declare function buildCrossChunkHandlers(): Handlers;
1301
1332
  * In the standalone path, every `<a href>` and `<img src>` element passes
1302
1333
  * through TWO gates before render:
1303
1334
  *
1304
- * 1. `urlTransform(url, key, node)` — the caller's allowlist (default:
1305
- * `defaultUrlTransform`, which mirrors GitHub's protocol allowlist).
1306
- * Runs in `markdown/transform.ts` during the hast visit pass.
1307
- * 2. `rehype-sanitize` `protocols.<attr>` allowlist — drops the attribute
1335
+ * 1. `rehype-sanitize` `protocols.<attr>` allowlist drops the attribute
1308
1336
  * entirely if the URL's protocol isn't permitted for that attribute.
1337
+ * Runs in the rehype plugin chain.
1338
+ * 2. `urlTransform(url, key, node)` — the caller's allowlist (default:
1339
+ * `defaultUrlTransform`, which mirrors GitHub's protocol allowlist).
1340
+ * Runs in `markdown/transform.ts` during the hast visit pass; its
1341
+ * return value IS the attribute (`''` renders `href=""`).
1309
1342
  *
1310
1343
  * Cross-chunk references skip BOTH passes naturally: the placeholder hast
1311
1344
  * tag (`<cross-chunk-link>` / `<cross-chunk-image>`) carries only a `label`
@@ -1335,13 +1368,20 @@ declare function buildCrossChunkHandlers(): Handlers;
1335
1368
  type UrlAttrKey = 'href' | 'src';
1336
1369
  type UrlAttrTag = 'a' | 'img';
1337
1370
  /**
1338
- * Run a cross-chunk-resolved URL through both standalone gates.
1371
+ * Run a cross-chunk-resolved URL through both standalone gates, in the
1372
+ * standalone ORDER: `rehype-sanitize`'s protocol allowlist runs in the
1373
+ * plugin chain first (a blocked URL loses the attribute entirely), then
1374
+ * `urlTransform` rewrites whatever survived during the hast visit pass (its
1375
+ * return value is the attribute — `''` from `defaultUrlTransform` renders
1376
+ * `href=""`, exactly like a legal empty destination `[x]: <>`).
1339
1377
  *
1340
- * @returns Sanitized URL string. Empty string when either gate strips the
1341
- * URL — matches `defaultUrlTransform`'s and `rehype-sanitize`'s observable
1342
- * behavior of replacing a blocked URL with `''`.
1378
+ * @returns `null` when the protocol gate strips the attribute (render it
1379
+ * ABSENT); otherwise the transformed URL string possibly `''`, which
1380
+ * the caller must render as `href=""` / `src=""` to stay byte-identical
1381
+ * with standalone (v2.4.1 review: the two used to collapse into `''` and
1382
+ * the placeholder omitted the attribute for `[x]: <>` too).
1343
1383
  */
1344
- declare function sanitizeCrossChunkUrl(rawUrl: string, key: UrlAttrKey, tagName: UrlAttrTag, urlTransform: UrlTransform, schema: SanitizeSchema): string;
1384
+ declare function sanitizeCrossChunkUrl(rawUrl: string, key: UrlAttrKey, tagName: UrlAttrTag, urlTransform: UrlTransform, schema: SanitizeSchema): string | null;
1345
1385
 
1346
1386
  /**
1347
1387
  * The five shipped engine plugins and the default set.
@@ -1951,4 +1991,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
1951
1991
  */
1952
1992
  declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
1953
1993
 
1954
- export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, DEF_LINE_START_RE, 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, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, lastRegionStart, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
1994
+ export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, DEF_LINE_START_RE, 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, lastRegionStart, 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
@@ -218,9 +218,11 @@ declare const defaultUrlTransform: UrlTransform;
218
218
  * whether a sibling node FOLLOWS it. A tail block that flips between
219
219
  * def (no hast output) and paragraph therefore reshapes the frozen
220
220
  * region retroactively (2026-07-31 direction-battery counterexample,
221
- * reproduced on v1.8.0). The candidate adjacent to such a run is
222
- * rejected until a later confirmed content line pins the seam from the
223
- * frozen side; dropping candidates only over-blocks (safe direction).
221
+ * reproduced on v1.8.0). Every candidate emitted while the remnant is
222
+ * the last frozen child is rejected (they stay rejected for good); once
223
+ * a later confirmed content line pins the seam from the frozen side,
224
+ * the candidates AFTER that line are safe again. Dropping candidates
225
+ * only over-blocks (safe direction). Whitespace-only remnant counts.
224
226
  * A type 2-5 block that opens AND closes on its first line owns the
225
227
  * rest of that line as raw content too (`<!-- c --> tail`) — same seam.
226
228
  * 7. **Phase poison** (`phasePoisonedAt`) — points where this line-level
@@ -382,6 +384,16 @@ interface FreezeScanCheckpoint {
382
384
  prevLineWasValidDef: boolean;
383
385
  /** An earlier line of the current paragraph left an unpaired backtick
384
386
  * run — masking is disabled until the paragraph ends (safety gate). */
387
+ /** A `[` left unclosed at the end of a paragraph line (code spans
388
+ * masked). micromark lets a reference label span soft line breaks, so
389
+ * the label may close on a LATER line where the per-line REF_RE never
390
+ * sees a `[…]` pair (v2.4.1 review P1: `see [foo\nbar] end` + a late
391
+ * `[foo bar]: /u` retargeted frozen output). Cleared wherever the
392
+ * paragraph ends. */
393
+ openBracket: {
394
+ offset: number;
395
+ text: string;
396
+ } | null;
385
397
  paragraphHasUnpairedRun: boolean;
386
398
  /** Blocker-6 pending flag: a confirmed html-flow line left balanced
387
399
  * floating raw remnant, and no later content line has pinned the seam
@@ -708,6 +720,17 @@ interface DefLabelScanner {
708
720
  */
709
721
  declare function createDefLabelScanner(parse?: (source: string) => DefLabels): DefLabelScanner;
710
722
 
723
+ /**
724
+ * The id fragment mdast-util-to-hast derives from a footnote identifier for
725
+ * `fn-…` / `fnref-…` (`normalizeUri(identifier.toLowerCase())` — percent-
726
+ * encodes non-ASCII, whitespace and URL-unsafe punctuation). Every place
727
+ * that MINTS a footnote id — the standalone footer (upstream), the
728
+ * cross-chunk marks and the aggregate footer — must use this same
729
+ * encoding, or a mark's `href` and its `<li id>` disagree (v2.4.0 review:
730
+ * the fallback mark wrote the raw label while the local footer was
731
+ * encoded; `[^注]` / `[^a%b]` anchors broke).
732
+ */
733
+ declare function footnoteSafeId(identifier: string): string;
711
734
  /**
712
735
  * Extract the SOURCE identifier from a footnote `<li>` id, covering both id
713
736
  * shapes in the codebase — standalone (mdast-util-to-hast `fn-` +
@@ -837,10 +860,12 @@ interface ChunkData {
837
860
  * interface. Driving the registry directly is reserved for internal
838
861
  * coordinators (the package's own `MarkdownContent` renderer) and tests,
839
862
  * which import the wider `RegistryInternal` type from this module.
840
- * `RegistryInternal` is exported here but NOT re-exported from the package
841
- * barrel keeping mutators off the public surface prevents a misbehaving
842
- * consumer-component from corrupting refcounts, skipping version bumps, or
843
- * otherwise breaking the invariants the renderer relies on.
863
+ * `RegistryInternal` is exported from this engine package (the core
864
+ * renderer consumes it) but NOT from `@ai-react-markdown/core`'s public
865
+ * barrel keeping mutators off the consumer-facing surface prevents a
866
+ * misbehaving consumer-component from corrupting refcounts, skipping
867
+ * version bumps, or otherwise breaking the invariants the renderer relies
868
+ * on.
844
869
  */
845
870
  interface Registry {
846
871
  /** Chunk mount-order Symbol list. **Read-only.** Direct mutation
@@ -893,9 +918,10 @@ interface Registry {
893
918
  * methods and implementation-private fields (reactId-keyed refcount table,
894
919
  * subscriber set, microtask-coalesce flag, `_notify` itself).
895
920
  *
896
- * Exported from this module so internal coordinators (`MarkdownContent`)
897
- * and tests can hold a strongly-typed reference, but **not** re-exported
898
- * from the package barrel a consumer flipping `_notifyScheduled = true`
921
+ * Exported from this module (and the engine barrel) so internal
922
+ * coordinators (`MarkdownContent`) and tests can hold a strongly-typed
923
+ * reference, but **not** re-exported from `@ai-react-markdown/core`'s
924
+ * barrel — a consumer flipping `_notifyScheduled = true`
899
925
  * or pushing into `chunkOrder` directly would silently break the
900
926
  * coalesce / numbering invariants. The runtime value returned by
901
927
  * {@link createRegistry} always satisfies this wider shape; public consumers
@@ -1235,11 +1261,16 @@ declare function buildPhantomSuffix(phantoms: PhantomLabels): string;
1235
1261
  * extend past `content.length`, which every consumer already tolerates for
1236
1262
  * the suffix's own nodes).
1237
1263
  *
1238
- * The closer is emitted at the opener line's indent, which closes the block
1239
- * both at top level (≤3 spaces are permitted there) and inside a list item
1240
- * whose content indent the opener already satisfies (a column-0 closer
1241
- * would END the item and open a NEW block that swallows the suffix worse
1242
- * than not closing).
1264
+ * A closer is emitted ONLY for a block whose opener line sits at column 0:
1265
+ * that is provably a top-level fence, which only a top-level closer (same
1266
+ * char, length, ≤3 spaces indent) can end exactly what the line scanner
1267
+ * tracks. Openers with any indent are left alone: the line model cannot
1268
+ * see container boundaries, and an indented opener may live in a list item
1269
+ * that later de-indented content already ended (micromark closed the fence
1270
+ * with the item; an emitted closer would OPEN a new fence around the
1271
+ * sentinel lines — v2.4.0 review R1) or be closed by a ≥4-space closer the
1272
+ * `^ {0,3}` scan does not recognize. Those shapes keep the plain append
1273
+ * (swallowed at worst — the pre-2.4.0 behaviour), never a wrong closer.
1243
1274
  *
1244
1275
  * Only fences and flow math are closed. Raw-HTML constructs (`<!--`, `<?`,
1245
1276
  * `<![CDATA[`, `<!X`, `<script>`) that stay open to EOF also swallow the
@@ -1301,11 +1332,13 @@ declare function buildCrossChunkHandlers(): Handlers;
1301
1332
  * In the standalone path, every `<a href>` and `<img src>` element passes
1302
1333
  * through TWO gates before render:
1303
1334
  *
1304
- * 1. `urlTransform(url, key, node)` — the caller's allowlist (default:
1305
- * `defaultUrlTransform`, which mirrors GitHub's protocol allowlist).
1306
- * Runs in `markdown/transform.ts` during the hast visit pass.
1307
- * 2. `rehype-sanitize` `protocols.<attr>` allowlist — drops the attribute
1335
+ * 1. `rehype-sanitize` `protocols.<attr>` allowlist drops the attribute
1308
1336
  * entirely if the URL's protocol isn't permitted for that attribute.
1337
+ * Runs in the rehype plugin chain.
1338
+ * 2. `urlTransform(url, key, node)` — the caller's allowlist (default:
1339
+ * `defaultUrlTransform`, which mirrors GitHub's protocol allowlist).
1340
+ * Runs in `markdown/transform.ts` during the hast visit pass; its
1341
+ * return value IS the attribute (`''` renders `href=""`).
1309
1342
  *
1310
1343
  * Cross-chunk references skip BOTH passes naturally: the placeholder hast
1311
1344
  * tag (`<cross-chunk-link>` / `<cross-chunk-image>`) carries only a `label`
@@ -1335,13 +1368,20 @@ declare function buildCrossChunkHandlers(): Handlers;
1335
1368
  type UrlAttrKey = 'href' | 'src';
1336
1369
  type UrlAttrTag = 'a' | 'img';
1337
1370
  /**
1338
- * Run a cross-chunk-resolved URL through both standalone gates.
1371
+ * Run a cross-chunk-resolved URL through both standalone gates, in the
1372
+ * standalone ORDER: `rehype-sanitize`'s protocol allowlist runs in the
1373
+ * plugin chain first (a blocked URL loses the attribute entirely), then
1374
+ * `urlTransform` rewrites whatever survived during the hast visit pass (its
1375
+ * return value is the attribute — `''` from `defaultUrlTransform` renders
1376
+ * `href=""`, exactly like a legal empty destination `[x]: <>`).
1339
1377
  *
1340
- * @returns Sanitized URL string. Empty string when either gate strips the
1341
- * URL — matches `defaultUrlTransform`'s and `rehype-sanitize`'s observable
1342
- * behavior of replacing a blocked URL with `''`.
1378
+ * @returns `null` when the protocol gate strips the attribute (render it
1379
+ * ABSENT); otherwise the transformed URL string possibly `''`, which
1380
+ * the caller must render as `href=""` / `src=""` to stay byte-identical
1381
+ * with standalone (v2.4.1 review: the two used to collapse into `''` and
1382
+ * the placeholder omitted the attribute for `[x]: <>` too).
1343
1383
  */
1344
- declare function sanitizeCrossChunkUrl(rawUrl: string, key: UrlAttrKey, tagName: UrlAttrTag, urlTransform: UrlTransform, schema: SanitizeSchema): string;
1384
+ declare function sanitizeCrossChunkUrl(rawUrl: string, key: UrlAttrKey, tagName: UrlAttrTag, urlTransform: UrlTransform, schema: SanitizeSchema): string | null;
1345
1385
 
1346
1386
  /**
1347
1387
  * The five shipped engine plugins and the default set.
@@ -1951,4 +1991,4 @@ type RemendPreprocessorOptions = Omit<RemendOptions, 'katex' | 'inlineKatex'>;
1951
1991
  */
1952
1992
  declare function createRemendPreprocessor(options?: RemendPreprocessorOptions): AIMDContentPreprocessor;
1953
1993
 
1954
- export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, DEF_LINE_START_RE, 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, getEnginePluginInternals, hasLoneSurrogate, highlight, isFootnoteSection, lastRegionStart, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };
1994
+ export { type AIMDContentPreprocessor, type AIMarkdownEnginePlugin, type AIMarkdownEnginePluginName, type AdvanceOptions, type AdvanceResult, type AllowElement, type ChunkData, type Contribution, type CrossChunkHandlerOptions, DEFAULT_PAYLOAD, DEF_LINE_START_RE, 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, lastRegionStart, measureStage, mergeClassNameAllowlist, normalizeForMatch, normalizeId, pangu, parseStage, phantomSuffixCloser, preprocessAIMDContent, preprocessLaTeX, rehypeFooterAdorn, rehypeRebaseHashLinks, removeComments, sanitizeCrossChunkUrl, sanitizeSchema, shortenDocumentId, smartypants, sourceIdFromFootnoteLiId, splitByProtectedRegions, subscribeStageTimings, transformStage, withDefs };