@ai-react-markdown/core 1.4.5 → 1.4.7
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 +10 -9
- package/dist/index.cjs +161 -156
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +60 -18
- package/dist/index.d.ts +60 -18
- package/dist/index.js +162 -157
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { JSX, ComponentType, PropsWithChildren, CSSProperties, FC } from 'react';
|
|
3
3
|
import { Element, ElementContent } from 'hast';
|
|
4
4
|
import { defaultSchema } from 'rehype-sanitize';
|
|
@@ -238,6 +238,27 @@ interface AIMarkdownRenderState<TConfig extends AIMarkdownRenderConfig = AIMarkd
|
|
|
238
238
|
* always win.
|
|
239
239
|
*/
|
|
240
240
|
documentId: string;
|
|
241
|
+
/**
|
|
242
|
+
* Whether {@link documentId} was EXPLICITLY supplied by the consumer (vs.
|
|
243
|
+
* auto-generated via `useId()`). This is the coordination signal — NOT
|
|
244
|
+
* `documentId` truthiness, which is always `true` because the provider
|
|
245
|
+
* auto-fills a fallback id for HTML/`clobberPrefix` purposes.
|
|
246
|
+
*
|
|
247
|
+
* `useDocumentRegistry` gates on this: an auto-generated id is unique by
|
|
248
|
+
* construction, so a chunk that didn't receive a `documentId` has nothing
|
|
249
|
+
* to coordinate with even when it sits inside `<AIMarkdownDocuments>`. It
|
|
250
|
+
* must take the standalone (registry === null) path, and this flag is the
|
|
251
|
+
* only thing that lets the registry hook tell "consumer wants coordination"
|
|
252
|
+
* apart from "we fabricated an id so the markup stays valid".
|
|
253
|
+
*
|
|
254
|
+
* Optional in the type ONLY so external callers that construct an
|
|
255
|
+
* `AIMarkdownRenderState` literal directly (mocks, fixtures) aren't broken
|
|
256
|
+
* by this internally-added field — the provider ALWAYS sets a concrete
|
|
257
|
+
* boolean, and internal consumers coerce a missing value to `false`
|
|
258
|
+
* (safe default: no coordination). Keeping it `?:` preserves source-level
|
|
259
|
+
* backward compatibility for the publicly-exported state type.
|
|
260
|
+
*/
|
|
261
|
+
documentIdExplicit?: boolean;
|
|
241
262
|
/**
|
|
242
263
|
* Per-document URI-safe id prefix used by all clobberable attributes
|
|
243
264
|
* (`id="…"` / `href="#…"`). Derived once by the provider and exposed here
|
|
@@ -818,8 +839,10 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
818
839
|
* });
|
|
819
840
|
* ```
|
|
820
841
|
*
|
|
821
|
-
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
822
|
-
*
|
|
842
|
+
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
843
|
+
* Gate 1 (the schema-level per-protocol allowlist, which runs inside the
|
|
844
|
+
* rehype plugin chain). Gate 2 (`urlTransform`, the per-attribute rewriter
|
|
845
|
+
* that runs later at render time in `renderHastSubtree`) must permit the
|
|
823
846
|
* same protocol independently — see the `urlTransform` prop on
|
|
824
847
|
* `<AIMarkdown>` and the exported {@link defaultUrlTransform} for
|
|
825
848
|
* composition. Keep the two protocol lists in sync.
|
|
@@ -1022,11 +1045,23 @@ declare const AIMarkdownDocuments: FC<AIMarkdownDocumentsProps>;
|
|
|
1022
1045
|
/**
|
|
1023
1046
|
* Returns the registry for the given `documentId`, or `null` if:
|
|
1024
1047
|
* - `<AIMarkdown>` is not inside an `<AIMarkdownDocuments>` wrapper, OR
|
|
1025
|
-
* - `documentId` is undefined / empty string
|
|
1048
|
+
* - `documentId` is undefined / empty string, OR
|
|
1049
|
+
* - `documentIdExplicit` is `false` — i.e. the id was auto-generated rather
|
|
1050
|
+
* than supplied by the consumer.
|
|
1051
|
+
*
|
|
1052
|
+
* The `documentIdExplicit` gate is the crux of the standalone-vs-coordinated
|
|
1053
|
+
* decision. An auto-generated id (`useId()` fallback) is non-empty and unique
|
|
1054
|
+
* by construction, so a chunk carrying one has nothing to coordinate with even
|
|
1055
|
+
* inside the wrapper — it must run standalone. Without this gate, the mere
|
|
1056
|
+
* presence of `<AIMarkdownDocuments>` would drag every uncoordinated chunk
|
|
1057
|
+
* onto the cross-chunk registry path (subscribe / allocate / evict overhead)
|
|
1058
|
+
* for no behavioral gain. The flag defaults to `true` so external callers who
|
|
1059
|
+
* pass an id directly are treated as explicit (passing an id IS the intent to
|
|
1060
|
+
* coordinate); the internal renderer threads through `state.documentIdExplicit`.
|
|
1026
1061
|
*
|
|
1027
1062
|
* Callers should treat `null` as "no coordination; run standalone path."
|
|
1028
1063
|
*/
|
|
1029
|
-
declare function useDocumentRegistry(documentId: string | undefined): Registry | null;
|
|
1064
|
+
declare function useDocumentRegistry(documentId: string | undefined, documentIdExplicit?: boolean): Registry | null;
|
|
1030
1065
|
|
|
1031
1066
|
/**
|
|
1032
1067
|
* Props for the `<AIMarkdown>` component.
|
|
@@ -1099,10 +1134,14 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1099
1134
|
*/
|
|
1100
1135
|
documentId?: string;
|
|
1101
1136
|
/**
|
|
1102
|
-
* Override the
|
|
1103
|
-
*
|
|
1104
|
-
* `
|
|
1105
|
-
*
|
|
1137
|
+
* Override the per-attribute URL rewriter (Gate 2 of the two-gate model).
|
|
1138
|
+
* Runs at render time during the hast traversal in `renderHastSubtree`,
|
|
1139
|
+
* after Gate 1 (`rehype-sanitize` schema) has already filtered URLs by
|
|
1140
|
+
* protocol allowlist in the rehype plugin chain.
|
|
1141
|
+
*
|
|
1142
|
+
* The default allowlist mirrors `react-markdown` / GitHub: `http`,
|
|
1143
|
+
* `https`, `irc`, `ircs`, `mailto`, `xmpp`. Anything else is rewritten
|
|
1144
|
+
* to `''`.
|
|
1106
1145
|
*
|
|
1107
1146
|
* **Recommended pattern**: compose with the exported
|
|
1108
1147
|
* {@link defaultUrlTransform} so the built-in XSS protections survive,
|
|
@@ -1131,13 +1170,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1131
1170
|
* as a dependency. Defining the function inline (`urlTransform={(url) =>
|
|
1132
1171
|
* …}`) creates a new closure on every parent render, discards the cache
|
|
1133
1172
|
* for the entire markdown document on each render, and effectively
|
|
1134
|
-
* disables
|
|
1173
|
+
* disables block-level memoization. In development the library will
|
|
1135
1174
|
* `console.warn` if it detects this pattern.
|
|
1136
1175
|
*
|
|
1137
1176
|
* Allowing a protocol here is necessary but **not sufficient** to render
|
|
1138
|
-
* a link —
|
|
1139
|
-
* protocol allowlist. See the `sanitizeSchema` prop on
|
|
1140
|
-
* and the {@link extendSanitizeSchema} helper for
|
|
1177
|
+
* a link — Gate 1 (`rehype-sanitize` schema) also enforces its own
|
|
1178
|
+
* protocol allowlist and runs first. See the `sanitizeSchema` prop on
|
|
1179
|
+
* this component and the {@link extendSanitizeSchema} helper for Gate 1.
|
|
1141
1180
|
*
|
|
1142
1181
|
* **API stability**: the `UrlTransform` type tracks the upstream
|
|
1143
1182
|
* `react-markdown` shape and may change with its major versions.
|
|
@@ -1146,10 +1185,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1146
1185
|
/**
|
|
1147
1186
|
* Override the `rehype-sanitize` schema applied to the rendered output.
|
|
1148
1187
|
* The library default extends `rehype-sanitize`'s own `defaultSchema`
|
|
1149
|
-
* with the `<mark>` tag,
|
|
1150
|
-
*
|
|
1151
|
-
* `
|
|
1152
|
-
*
|
|
1188
|
+
* with the `<mark>` tag, the `math-inline` / `math-display` className
|
|
1189
|
+
* markers `remark-math` emits on `<code>` (KaTeX's own output classes
|
|
1190
|
+
* survive separately because `rehype-katex` runs after `rehype-sanitize`),
|
|
1191
|
+
* and the cross-chunk coordination tags (`cross-chunk-link`,
|
|
1192
|
+
* `cross-chunk-image`, `footnote-sup`). The default is not exported as a
|
|
1193
|
+
* value — see {@link extendSanitizeSchema} for how to inspect or extend
|
|
1194
|
+
* it safely.
|
|
1153
1195
|
*
|
|
1154
1196
|
* **Recommended pattern**: build the schema with {@link extendSanitizeSchema}
|
|
1155
1197
|
* (mutate-and-return form) so those library additions stay intact, and
|
|
@@ -1189,7 +1231,7 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1189
1231
|
* Root component that preprocesses markdown content and renders it through
|
|
1190
1232
|
* a configurable remark/rehype pipeline wrapped in typography and style layers.
|
|
1191
1233
|
*/
|
|
1192
|
-
declare const AIMarkdownComponent: <TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig, TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata>({ streaming, content, fontSize, contentPreprocessors, customComponents, defaultConfig, config, metadata, Typography, ExtraStyles, variant, colorScheme, documentId, urlTransform, sanitizeSchema, }: AIMarkdownProps<TConfig, TRenderData>) =>
|
|
1234
|
+
declare const AIMarkdownComponent: <TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig, TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata>({ streaming, content, fontSize, contentPreprocessors, customComponents, defaultConfig, config, metadata, Typography, ExtraStyles, variant, colorScheme, documentId, urlTransform, sanitizeSchema, }: AIMarkdownProps<TConfig, TRenderData>) => react.JSX.Element;
|
|
1193
1235
|
declare const _default: typeof AIMarkdownComponent;
|
|
1194
1236
|
|
|
1195
1237
|
export { type AIMDContentPreprocessor, type AIMarkdownColorScheme, type AIMarkdownCustomComponents, AIMarkdownDocuments, type AIMarkdownDocumentsProps, type AIMarkdownExtraStylesComponent, type AIMarkdownExtraStylesProps, type AIMarkdownMetadata, type AIMarkdownProps, type AIMarkdownRenderConfig, AIMarkdownRenderDisplayOptimizeAbility, AIMarkdownRenderExtraSyntax, type AIMarkdownRenderState, type AIMarkdownTypographyComponent, type AIMarkdownTypographyProps, type AIMarkdownVariant, type ChunkData, type FootnoteDef, type LinkDef, type PartialDeep, type RefKind, type RefRecord, type Registry, type SanitizeSchema, type UrlTransform, _default as default, defaultAIMarkdownRenderConfig, defaultUrlTransform, extendSanitizeSchema, useAIMarkdownMetadata, useAIMarkdownRenderState, useDocumentRegistry, useStableValue };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as react from 'react';
|
|
2
2
|
import { JSX, ComponentType, PropsWithChildren, CSSProperties, FC } from 'react';
|
|
3
3
|
import { Element, ElementContent } from 'hast';
|
|
4
4
|
import { defaultSchema } from 'rehype-sanitize';
|
|
@@ -238,6 +238,27 @@ interface AIMarkdownRenderState<TConfig extends AIMarkdownRenderConfig = AIMarkd
|
|
|
238
238
|
* always win.
|
|
239
239
|
*/
|
|
240
240
|
documentId: string;
|
|
241
|
+
/**
|
|
242
|
+
* Whether {@link documentId} was EXPLICITLY supplied by the consumer (vs.
|
|
243
|
+
* auto-generated via `useId()`). This is the coordination signal — NOT
|
|
244
|
+
* `documentId` truthiness, which is always `true` because the provider
|
|
245
|
+
* auto-fills a fallback id for HTML/`clobberPrefix` purposes.
|
|
246
|
+
*
|
|
247
|
+
* `useDocumentRegistry` gates on this: an auto-generated id is unique by
|
|
248
|
+
* construction, so a chunk that didn't receive a `documentId` has nothing
|
|
249
|
+
* to coordinate with even when it sits inside `<AIMarkdownDocuments>`. It
|
|
250
|
+
* must take the standalone (registry === null) path, and this flag is the
|
|
251
|
+
* only thing that lets the registry hook tell "consumer wants coordination"
|
|
252
|
+
* apart from "we fabricated an id so the markup stays valid".
|
|
253
|
+
*
|
|
254
|
+
* Optional in the type ONLY so external callers that construct an
|
|
255
|
+
* `AIMarkdownRenderState` literal directly (mocks, fixtures) aren't broken
|
|
256
|
+
* by this internally-added field — the provider ALWAYS sets a concrete
|
|
257
|
+
* boolean, and internal consumers coerce a missing value to `false`
|
|
258
|
+
* (safe default: no coordination). Keeping it `?:` preserves source-level
|
|
259
|
+
* backward compatibility for the publicly-exported state type.
|
|
260
|
+
*/
|
|
261
|
+
documentIdExplicit?: boolean;
|
|
241
262
|
/**
|
|
242
263
|
* Per-document URI-safe id prefix used by all clobberable attributes
|
|
243
264
|
* (`id="…"` / `href="#…"`). Derived once by the provider and exposed here
|
|
@@ -818,8 +839,10 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
818
839
|
* });
|
|
819
840
|
* ```
|
|
820
841
|
*
|
|
821
|
-
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
822
|
-
*
|
|
842
|
+
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
843
|
+
* Gate 1 (the schema-level per-protocol allowlist, which runs inside the
|
|
844
|
+
* rehype plugin chain). Gate 2 (`urlTransform`, the per-attribute rewriter
|
|
845
|
+
* that runs later at render time in `renderHastSubtree`) must permit the
|
|
823
846
|
* same protocol independently — see the `urlTransform` prop on
|
|
824
847
|
* `<AIMarkdown>` and the exported {@link defaultUrlTransform} for
|
|
825
848
|
* composition. Keep the two protocol lists in sync.
|
|
@@ -1022,11 +1045,23 @@ declare const AIMarkdownDocuments: FC<AIMarkdownDocumentsProps>;
|
|
|
1022
1045
|
/**
|
|
1023
1046
|
* Returns the registry for the given `documentId`, or `null` if:
|
|
1024
1047
|
* - `<AIMarkdown>` is not inside an `<AIMarkdownDocuments>` wrapper, OR
|
|
1025
|
-
* - `documentId` is undefined / empty string
|
|
1048
|
+
* - `documentId` is undefined / empty string, OR
|
|
1049
|
+
* - `documentIdExplicit` is `false` — i.e. the id was auto-generated rather
|
|
1050
|
+
* than supplied by the consumer.
|
|
1051
|
+
*
|
|
1052
|
+
* The `documentIdExplicit` gate is the crux of the standalone-vs-coordinated
|
|
1053
|
+
* decision. An auto-generated id (`useId()` fallback) is non-empty and unique
|
|
1054
|
+
* by construction, so a chunk carrying one has nothing to coordinate with even
|
|
1055
|
+
* inside the wrapper — it must run standalone. Without this gate, the mere
|
|
1056
|
+
* presence of `<AIMarkdownDocuments>` would drag every uncoordinated chunk
|
|
1057
|
+
* onto the cross-chunk registry path (subscribe / allocate / evict overhead)
|
|
1058
|
+
* for no behavioral gain. The flag defaults to `true` so external callers who
|
|
1059
|
+
* pass an id directly are treated as explicit (passing an id IS the intent to
|
|
1060
|
+
* coordinate); the internal renderer threads through `state.documentIdExplicit`.
|
|
1026
1061
|
*
|
|
1027
1062
|
* Callers should treat `null` as "no coordination; run standalone path."
|
|
1028
1063
|
*/
|
|
1029
|
-
declare function useDocumentRegistry(documentId: string | undefined): Registry | null;
|
|
1064
|
+
declare function useDocumentRegistry(documentId: string | undefined, documentIdExplicit?: boolean): Registry | null;
|
|
1030
1065
|
|
|
1031
1066
|
/**
|
|
1032
1067
|
* Props for the `<AIMarkdown>` component.
|
|
@@ -1099,10 +1134,14 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1099
1134
|
*/
|
|
1100
1135
|
documentId?: string;
|
|
1101
1136
|
/**
|
|
1102
|
-
* Override the
|
|
1103
|
-
*
|
|
1104
|
-
* `
|
|
1105
|
-
*
|
|
1137
|
+
* Override the per-attribute URL rewriter (Gate 2 of the two-gate model).
|
|
1138
|
+
* Runs at render time during the hast traversal in `renderHastSubtree`,
|
|
1139
|
+
* after Gate 1 (`rehype-sanitize` schema) has already filtered URLs by
|
|
1140
|
+
* protocol allowlist in the rehype plugin chain.
|
|
1141
|
+
*
|
|
1142
|
+
* The default allowlist mirrors `react-markdown` / GitHub: `http`,
|
|
1143
|
+
* `https`, `irc`, `ircs`, `mailto`, `xmpp`. Anything else is rewritten
|
|
1144
|
+
* to `''`.
|
|
1106
1145
|
*
|
|
1107
1146
|
* **Recommended pattern**: compose with the exported
|
|
1108
1147
|
* {@link defaultUrlTransform} so the built-in XSS protections survive,
|
|
@@ -1131,13 +1170,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1131
1170
|
* as a dependency. Defining the function inline (`urlTransform={(url) =>
|
|
1132
1171
|
* …}`) creates a new closure on every parent render, discards the cache
|
|
1133
1172
|
* for the entire markdown document on each render, and effectively
|
|
1134
|
-
* disables
|
|
1173
|
+
* disables block-level memoization. In development the library will
|
|
1135
1174
|
* `console.warn` if it detects this pattern.
|
|
1136
1175
|
*
|
|
1137
1176
|
* Allowing a protocol here is necessary but **not sufficient** to render
|
|
1138
|
-
* a link —
|
|
1139
|
-
* protocol allowlist. See the `sanitizeSchema` prop on
|
|
1140
|
-
* and the {@link extendSanitizeSchema} helper for
|
|
1177
|
+
* a link — Gate 1 (`rehype-sanitize` schema) also enforces its own
|
|
1178
|
+
* protocol allowlist and runs first. See the `sanitizeSchema` prop on
|
|
1179
|
+
* this component and the {@link extendSanitizeSchema} helper for Gate 1.
|
|
1141
1180
|
*
|
|
1142
1181
|
* **API stability**: the `UrlTransform` type tracks the upstream
|
|
1143
1182
|
* `react-markdown` shape and may change with its major versions.
|
|
@@ -1146,10 +1185,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1146
1185
|
/**
|
|
1147
1186
|
* Override the `rehype-sanitize` schema applied to the rendered output.
|
|
1148
1187
|
* The library default extends `rehype-sanitize`'s own `defaultSchema`
|
|
1149
|
-
* with the `<mark>` tag,
|
|
1150
|
-
*
|
|
1151
|
-
* `
|
|
1152
|
-
*
|
|
1188
|
+
* with the `<mark>` tag, the `math-inline` / `math-display` className
|
|
1189
|
+
* markers `remark-math` emits on `<code>` (KaTeX's own output classes
|
|
1190
|
+
* survive separately because `rehype-katex` runs after `rehype-sanitize`),
|
|
1191
|
+
* and the cross-chunk coordination tags (`cross-chunk-link`,
|
|
1192
|
+
* `cross-chunk-image`, `footnote-sup`). The default is not exported as a
|
|
1193
|
+
* value — see {@link extendSanitizeSchema} for how to inspect or extend
|
|
1194
|
+
* it safely.
|
|
1153
1195
|
*
|
|
1154
1196
|
* **Recommended pattern**: build the schema with {@link extendSanitizeSchema}
|
|
1155
1197
|
* (mutate-and-return form) so those library additions stay intact, and
|
|
@@ -1189,7 +1231,7 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1189
1231
|
* Root component that preprocesses markdown content and renders it through
|
|
1190
1232
|
* a configurable remark/rehype pipeline wrapped in typography and style layers.
|
|
1191
1233
|
*/
|
|
1192
|
-
declare const AIMarkdownComponent: <TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig, TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata>({ streaming, content, fontSize, contentPreprocessors, customComponents, defaultConfig, config, metadata, Typography, ExtraStyles, variant, colorScheme, documentId, urlTransform, sanitizeSchema, }: AIMarkdownProps<TConfig, TRenderData>) =>
|
|
1234
|
+
declare const AIMarkdownComponent: <TConfig extends AIMarkdownRenderConfig = AIMarkdownRenderConfig, TRenderData extends AIMarkdownMetadata = AIMarkdownMetadata>({ streaming, content, fontSize, contentPreprocessors, customComponents, defaultConfig, config, metadata, Typography, ExtraStyles, variant, colorScheme, documentId, urlTransform, sanitizeSchema, }: AIMarkdownProps<TConfig, TRenderData>) => react.JSX.Element;
|
|
1193
1235
|
declare const _default: typeof AIMarkdownComponent;
|
|
1194
1236
|
|
|
1195
1237
|
export { type AIMDContentPreprocessor, type AIMarkdownColorScheme, type AIMarkdownCustomComponents, AIMarkdownDocuments, type AIMarkdownDocumentsProps, type AIMarkdownExtraStylesComponent, type AIMarkdownExtraStylesProps, type AIMarkdownMetadata, type AIMarkdownProps, type AIMarkdownRenderConfig, AIMarkdownRenderDisplayOptimizeAbility, AIMarkdownRenderExtraSyntax, type AIMarkdownRenderState, type AIMarkdownTypographyComponent, type AIMarkdownTypographyProps, type AIMarkdownVariant, type ChunkData, type FootnoteDef, type LinkDef, type PartialDeep, type RefKind, type RefRecord, type Registry, type SanitizeSchema, type UrlTransform, _default as default, defaultAIMarkdownRenderConfig, defaultUrlTransform, extendSanitizeSchema, useAIMarkdownMetadata, useAIMarkdownRenderState, useDocumentRegistry, useStableValue };
|