@ai-react-markdown/core 1.4.4 → 1.4.6
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 +38 -9
- package/dist/index.cjs +156 -156
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -16
- package/dist/index.d.ts +62 -16
- package/dist/index.js +157 -157
- package/dist/index.js.map +1 -1
- package/dist/typography/all.css +34 -29
- package/dist/typography/all.css.map +1 -1
- package/dist/typography/default.css +34 -29
- package/dist/typography/default.css.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -183,6 +183,10 @@ interface AIMarkdownTypographyProps extends PropsWithChildren {
|
|
|
183
183
|
* `font-size: var(--aim-font-size-root)` to opt out of `em` compounding
|
|
184
184
|
* when a stable size is needed.
|
|
185
185
|
*
|
|
186
|
+
* The built-in `default` variant consumes this variable: its spacing,
|
|
187
|
+
* font-size, and heading tokens are defined as `calc(var(--aim-font-size-root) * k)`,
|
|
188
|
+
* so the `fontSize` prop proportionally scales every rendered dimension.
|
|
189
|
+
*
|
|
186
190
|
* @example
|
|
187
191
|
* ```tsx
|
|
188
192
|
* const MyTypography: AIMarkdownTypographyComponent = ({ children, fontSize, style }) => (
|
|
@@ -234,6 +238,27 @@ interface AIMarkdownRenderState<TConfig extends AIMarkdownRenderConfig = AIMarkd
|
|
|
234
238
|
* always win.
|
|
235
239
|
*/
|
|
236
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;
|
|
237
262
|
/**
|
|
238
263
|
* Per-document URI-safe id prefix used by all clobberable attributes
|
|
239
264
|
* (`id="…"` / `href="#…"`). Derived once by the provider and exposed here
|
|
@@ -814,8 +839,10 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
814
839
|
* });
|
|
815
840
|
* ```
|
|
816
841
|
*
|
|
817
|
-
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
818
|
-
*
|
|
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
|
|
819
846
|
* same protocol independently — see the `urlTransform` prop on
|
|
820
847
|
* `<AIMarkdown>` and the exported {@link defaultUrlTransform} for
|
|
821
848
|
* composition. Keep the two protocol lists in sync.
|
|
@@ -1018,11 +1045,23 @@ declare const AIMarkdownDocuments: FC<AIMarkdownDocumentsProps>;
|
|
|
1018
1045
|
/**
|
|
1019
1046
|
* Returns the registry for the given `documentId`, or `null` if:
|
|
1020
1047
|
* - `<AIMarkdown>` is not inside an `<AIMarkdownDocuments>` wrapper, OR
|
|
1021
|
-
* - `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`.
|
|
1022
1061
|
*
|
|
1023
1062
|
* Callers should treat `null` as "no coordination; run standalone path."
|
|
1024
1063
|
*/
|
|
1025
|
-
declare function useDocumentRegistry(documentId: string | undefined): Registry | null;
|
|
1064
|
+
declare function useDocumentRegistry(documentId: string | undefined, documentIdExplicit?: boolean): Registry | null;
|
|
1026
1065
|
|
|
1027
1066
|
/**
|
|
1028
1067
|
* Props for the `<AIMarkdown>` component.
|
|
@@ -1095,10 +1134,14 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1095
1134
|
*/
|
|
1096
1135
|
documentId?: string;
|
|
1097
1136
|
/**
|
|
1098
|
-
* Override the
|
|
1099
|
-
*
|
|
1100
|
-
* `
|
|
1101
|
-
*
|
|
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 `''`.
|
|
1102
1145
|
*
|
|
1103
1146
|
* **Recommended pattern**: compose with the exported
|
|
1104
1147
|
* {@link defaultUrlTransform} so the built-in XSS protections survive,
|
|
@@ -1127,13 +1170,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1127
1170
|
* as a dependency. Defining the function inline (`urlTransform={(url) =>
|
|
1128
1171
|
* …}`) creates a new closure on every parent render, discards the cache
|
|
1129
1172
|
* for the entire markdown document on each render, and effectively
|
|
1130
|
-
* disables
|
|
1173
|
+
* disables block-level memoization. In development the library will
|
|
1131
1174
|
* `console.warn` if it detects this pattern.
|
|
1132
1175
|
*
|
|
1133
1176
|
* Allowing a protocol here is necessary but **not sufficient** to render
|
|
1134
|
-
* a link —
|
|
1135
|
-
* protocol allowlist. See the `sanitizeSchema` prop on
|
|
1136
|
-
* 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.
|
|
1137
1180
|
*
|
|
1138
1181
|
* **API stability**: the `UrlTransform` type tracks the upstream
|
|
1139
1182
|
* `react-markdown` shape and may change with its major versions.
|
|
@@ -1142,10 +1185,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1142
1185
|
/**
|
|
1143
1186
|
* Override the `rehype-sanitize` schema applied to the rendered output.
|
|
1144
1187
|
* The library default extends `rehype-sanitize`'s own `defaultSchema`
|
|
1145
|
-
* with the `<mark>` tag,
|
|
1146
|
-
*
|
|
1147
|
-
* `
|
|
1148
|
-
*
|
|
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.
|
|
1149
1195
|
*
|
|
1150
1196
|
* **Recommended pattern**: build the schema with {@link extendSanitizeSchema}
|
|
1151
1197
|
* (mutate-and-return form) so those library additions stay intact, and
|
package/dist/index.d.ts
CHANGED
|
@@ -183,6 +183,10 @@ interface AIMarkdownTypographyProps extends PropsWithChildren {
|
|
|
183
183
|
* `font-size: var(--aim-font-size-root)` to opt out of `em` compounding
|
|
184
184
|
* when a stable size is needed.
|
|
185
185
|
*
|
|
186
|
+
* The built-in `default` variant consumes this variable: its spacing,
|
|
187
|
+
* font-size, and heading tokens are defined as `calc(var(--aim-font-size-root) * k)`,
|
|
188
|
+
* so the `fontSize` prop proportionally scales every rendered dimension.
|
|
189
|
+
*
|
|
186
190
|
* @example
|
|
187
191
|
* ```tsx
|
|
188
192
|
* const MyTypography: AIMarkdownTypographyComponent = ({ children, fontSize, style }) => (
|
|
@@ -234,6 +238,27 @@ interface AIMarkdownRenderState<TConfig extends AIMarkdownRenderConfig = AIMarkd
|
|
|
234
238
|
* always win.
|
|
235
239
|
*/
|
|
236
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;
|
|
237
262
|
/**
|
|
238
263
|
* Per-document URI-safe id prefix used by all clobberable attributes
|
|
239
264
|
* (`id="…"` / `href="#…"`). Derived once by the provider and exposed here
|
|
@@ -814,8 +839,10 @@ type SanitizeSchema = typeof defaultSchema;
|
|
|
814
839
|
* });
|
|
815
840
|
* ```
|
|
816
841
|
*
|
|
817
|
-
* @remarks Allowing a protocol on `protocols.href` lets the URL through
|
|
818
|
-
*
|
|
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
|
|
819
846
|
* same protocol independently — see the `urlTransform` prop on
|
|
820
847
|
* `<AIMarkdown>` and the exported {@link defaultUrlTransform} for
|
|
821
848
|
* composition. Keep the two protocol lists in sync.
|
|
@@ -1018,11 +1045,23 @@ declare const AIMarkdownDocuments: FC<AIMarkdownDocumentsProps>;
|
|
|
1018
1045
|
/**
|
|
1019
1046
|
* Returns the registry for the given `documentId`, or `null` if:
|
|
1020
1047
|
* - `<AIMarkdown>` is not inside an `<AIMarkdownDocuments>` wrapper, OR
|
|
1021
|
-
* - `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`.
|
|
1022
1061
|
*
|
|
1023
1062
|
* Callers should treat `null` as "no coordination; run standalone path."
|
|
1024
1063
|
*/
|
|
1025
|
-
declare function useDocumentRegistry(documentId: string | undefined): Registry | null;
|
|
1064
|
+
declare function useDocumentRegistry(documentId: string | undefined, documentIdExplicit?: boolean): Registry | null;
|
|
1026
1065
|
|
|
1027
1066
|
/**
|
|
1028
1067
|
* Props for the `<AIMarkdown>` component.
|
|
@@ -1095,10 +1134,14 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1095
1134
|
*/
|
|
1096
1135
|
documentId?: string;
|
|
1097
1136
|
/**
|
|
1098
|
-
* Override the
|
|
1099
|
-
*
|
|
1100
|
-
* `
|
|
1101
|
-
*
|
|
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 `''`.
|
|
1102
1145
|
*
|
|
1103
1146
|
* **Recommended pattern**: compose with the exported
|
|
1104
1147
|
* {@link defaultUrlTransform} so the built-in XSS protections survive,
|
|
@@ -1127,13 +1170,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1127
1170
|
* as a dependency. Defining the function inline (`urlTransform={(url) =>
|
|
1128
1171
|
* …}`) creates a new closure on every parent render, discards the cache
|
|
1129
1172
|
* for the entire markdown document on each render, and effectively
|
|
1130
|
-
* disables
|
|
1173
|
+
* disables block-level memoization. In development the library will
|
|
1131
1174
|
* `console.warn` if it detects this pattern.
|
|
1132
1175
|
*
|
|
1133
1176
|
* Allowing a protocol here is necessary but **not sufficient** to render
|
|
1134
|
-
* a link —
|
|
1135
|
-
* protocol allowlist. See the `sanitizeSchema` prop on
|
|
1136
|
-
* 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.
|
|
1137
1180
|
*
|
|
1138
1181
|
* **API stability**: the `UrlTransform` type tracks the upstream
|
|
1139
1182
|
* `react-markdown` shape and may change with its major versions.
|
|
@@ -1142,10 +1185,13 @@ interface AIMarkdownProps<TConfig extends AIMarkdownRenderConfig = AIMarkdownRen
|
|
|
1142
1185
|
/**
|
|
1143
1186
|
* Override the `rehype-sanitize` schema applied to the rendered output.
|
|
1144
1187
|
* The library default extends `rehype-sanitize`'s own `defaultSchema`
|
|
1145
|
-
* with the `<mark>` tag,
|
|
1146
|
-
*
|
|
1147
|
-
* `
|
|
1148
|
-
*
|
|
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.
|
|
1149
1195
|
*
|
|
1150
1196
|
* **Recommended pattern**: build the schema with {@link extendSanitizeSchema}
|
|
1151
1197
|
* (mutate-and-return form) so those library additions stay intact, and
|