@carbon/ai-chat-components 1.4.0 → 1.5.0-rc.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.
Files changed (100) hide show
  1. package/custom-elements.json +837 -284
  2. package/es/components/chat-history/src/chat-history.scss.js +1 -1
  3. package/es/components/chat-history/src/history-panel-item.d.ts +14 -0
  4. package/es/components/chat-history/src/history-panel-item.js +30 -0
  5. package/es/components/chat-history/src/history-panel-item.js.map +1 -1
  6. package/es/components/code-snippet/src/code-snippet.d.ts +5 -0
  7. package/es/components/code-snippet/src/code-snippet.js +17 -5
  8. package/es/components/code-snippet/src/code-snippet.js.map +1 -1
  9. package/es/components/feedback/src/feedback.d.ts +4 -0
  10. package/es/components/feedback/src/feedback.js +6 -4
  11. package/es/components/feedback/src/feedback.js.map +1 -1
  12. package/es/components/markdown/index.d.ts +3 -1
  13. package/es/components/markdown/index.js +1 -1
  14. package/es/components/markdown/src/markdown-renderer-types.d.ts +100 -0
  15. package/es/components/markdown/src/markdown-renderer-types.js +8 -0
  16. package/es/components/markdown/src/markdown-renderer-types.js.map +1 -0
  17. package/es/components/markdown/src/markdown-renderer.d.ts +14 -64
  18. package/es/components/markdown/src/markdown-renderer.js +120 -134
  19. package/es/components/markdown/src/markdown-renderer.js.map +1 -1
  20. package/es/components/markdown/src/markdown-token-tree.d.ts +50 -5
  21. package/es/components/markdown/src/markdown-token-tree.js +182 -47
  22. package/es/components/markdown/src/markdown-token-tree.js.map +1 -1
  23. package/es/components/markdown/src/markdown.d.ts +49 -1
  24. package/es/components/markdown/src/markdown.js +307 -106
  25. package/es/components/markdown/src/markdown.js.map +1 -1
  26. package/es/components/markdown/src/markdown.scss.js +1 -1
  27. package/es/components/markdown/src/plugins/markdown-it-task-lists.js +2 -5
  28. package/es/components/markdown/src/plugins/markdown-it-task-lists.js.map +1 -1
  29. package/es/components/markdown/src/utils/lit-directives.d.ts +17 -0
  30. package/es/components/markdown/src/utils/lit-directives.js +84 -0
  31. package/es/components/markdown/src/utils/lit-directives.js.map +1 -0
  32. package/es/components/markdown/src/utils/plugin-fallback.d.ts +33 -0
  33. package/es/components/markdown/src/utils/plugin-fallback.js +219 -0
  34. package/es/components/markdown/src/utils/plugin-fallback.js.map +1 -0
  35. package/es/components/markdown/src/utils/streaming-table.d.ts +28 -0
  36. package/es/components/markdown/src/utils/streaming-table.js +86 -0
  37. package/es/components/markdown/src/utils/streaming-table.js.map +1 -0
  38. package/es/components/markdown/src/utils/table-helpers.d.ts +17 -0
  39. package/es/components/markdown/src/utils/table-helpers.js +104 -2
  40. package/es/components/markdown/src/utils/table-helpers.js.map +1 -1
  41. package/es/components/table/src/table.js +4 -1
  42. package/es/components/table/src/table.js.map +1 -1
  43. package/es/components/truncated-text/src/truncated-text.scss.js +1 -1
  44. package/es/components/workspace-shell/src/workspace-shell.scss.js +1 -1
  45. package/es/react/markdown.d.ts +46 -2
  46. package/es/react/markdown.js +177 -20
  47. package/es/react/markdown.js.map +1 -1
  48. package/es-custom/components/chat-history/src/chat-history.scss.js +1 -1
  49. package/es-custom/components/chat-history/src/history-panel-item.d.ts +14 -0
  50. package/es-custom/components/chat-history/src/history-panel-item.js +30 -0
  51. package/es-custom/components/chat-history/src/history-panel-item.js.map +1 -1
  52. package/es-custom/components/code-snippet/src/code-snippet.d.ts +5 -0
  53. package/es-custom/components/code-snippet/src/code-snippet.js +17 -5
  54. package/es-custom/components/code-snippet/src/code-snippet.js.map +1 -1
  55. package/es-custom/components/feedback/src/feedback.d.ts +4 -0
  56. package/es-custom/components/feedback/src/feedback.js +6 -4
  57. package/es-custom/components/feedback/src/feedback.js.map +1 -1
  58. package/es-custom/components/markdown/index.d.ts +3 -1
  59. package/es-custom/components/markdown/index.js +1 -1
  60. package/es-custom/components/markdown/src/markdown-renderer-types.d.ts +100 -0
  61. package/es-custom/components/markdown/src/markdown-renderer-types.js +8 -0
  62. package/es-custom/components/markdown/src/markdown-renderer-types.js.map +1 -0
  63. package/es-custom/components/markdown/src/markdown-renderer.d.ts +14 -64
  64. package/es-custom/components/markdown/src/markdown-renderer.js +120 -134
  65. package/es-custom/components/markdown/src/markdown-renderer.js.map +1 -1
  66. package/es-custom/components/markdown/src/markdown-token-tree.d.ts +50 -5
  67. package/es-custom/components/markdown/src/markdown-token-tree.js +182 -47
  68. package/es-custom/components/markdown/src/markdown-token-tree.js.map +1 -1
  69. package/es-custom/components/markdown/src/markdown.d.ts +49 -1
  70. package/es-custom/components/markdown/src/markdown.js +307 -106
  71. package/es-custom/components/markdown/src/markdown.js.map +1 -1
  72. package/es-custom/components/markdown/src/markdown.scss.js +1 -1
  73. package/es-custom/components/markdown/src/plugins/markdown-it-task-lists.js +2 -5
  74. package/es-custom/components/markdown/src/plugins/markdown-it-task-lists.js.map +1 -1
  75. package/es-custom/components/markdown/src/utils/lit-directives.d.ts +17 -0
  76. package/es-custom/components/markdown/src/utils/lit-directives.js +84 -0
  77. package/es-custom/components/markdown/src/utils/lit-directives.js.map +1 -0
  78. package/es-custom/components/markdown/src/utils/plugin-fallback.d.ts +33 -0
  79. package/es-custom/components/markdown/src/utils/plugin-fallback.js +219 -0
  80. package/es-custom/components/markdown/src/utils/plugin-fallback.js.map +1 -0
  81. package/es-custom/components/markdown/src/utils/streaming-table.d.ts +28 -0
  82. package/es-custom/components/markdown/src/utils/streaming-table.js +86 -0
  83. package/es-custom/components/markdown/src/utils/streaming-table.js.map +1 -0
  84. package/es-custom/components/markdown/src/utils/table-helpers.d.ts +17 -0
  85. package/es-custom/components/markdown/src/utils/table-helpers.js +104 -2
  86. package/es-custom/components/markdown/src/utils/table-helpers.js.map +1 -1
  87. package/es-custom/components/table/src/table.js +4 -1
  88. package/es-custom/components/table/src/table.js.map +1 -1
  89. package/es-custom/components/truncated-text/src/truncated-text.scss.js +1 -1
  90. package/es-custom/components/workspace-shell/src/workspace-shell.scss.js +1 -1
  91. package/es-custom/react/markdown.d.ts +46 -2
  92. package/es-custom/react/markdown.js +177 -20
  93. package/es-custom/react/markdown.js.map +1 -1
  94. package/package.json +5 -4
  95. package/es/components/markdown/src/utils.d.ts +0 -4
  96. package/es/components/markdown/src/utils.js +0 -25
  97. package/es/components/markdown/src/utils.js.map +0 -1
  98. package/es-custom/components/markdown/src/utils.d.ts +0 -4
  99. package/es-custom/components/markdown/src/utils.js +0 -25
  100. package/es-custom/components/markdown/src/utils.js.map +0 -1
@@ -1,4 +1,22 @@
1
- import { Token } from "markdown-it";
1
+ /**
2
+ * The parse/diff layer between raw markdown source and the renderer. Parses with markdown-it (built-in plugins plus any caller-supplied `markdownItPlugins`), builds a nested {@link TokenTree}, and diffs it against the previous tree so streaming updates can reuse stable subtrees.
3
+ *
4
+ * ### Why diff
5
+ *
6
+ * `diffTokenTree` reuses old nodes by `key` whenever the key matches. This is what lets `./markdown-renderer.ts`'s use of Lit's `repeat` directive keep DOM stable during streaming: each incoming chunk re-parses the full source, but matched keys reuse the prior subtree, so only the genuinely new tail differs.
7
+ *
8
+ * ### Why `cachedHtml`
9
+ *
10
+ * For the leaf token types in {@link PLUGIN_DELEGABLE_TOKEN_TYPES}, when a user plugin's renderer rule produces the HTML (via `./utils/plugin-fallback.ts`), the result is cached on the `TokenTree` node and carried forward by `diffTokenTree` whenever the underlying token's `content` / `attrs` / `info` are unchanged. A stable earlier-in-document fence/image/etc. therefore isn't re-rendered through the plugin's rule on every streaming chunk. The cache is tagged with the `MarkdownIt` instance that produced it; a plugin swap (which builds a fresh instance) invalidates the cache on read.
11
+ *
12
+ * The block comment on {@link PLUGIN_DELEGABLE_TOKEN_TYPES} explains why only those four token types are eligible for delegation.
13
+ *
14
+ * ### Related files
15
+ *
16
+ * - `./markdown-renderer.ts` — consumes the `TokenTree` and produces a Lit `TemplateResult`.
17
+ * - `./utils/plugin-fallback.ts` — reads `cachedHtml` and {@link getPluginOverriddenRules} to drive the delegated-render flow.
18
+ */
19
+ import MarkdownIt, { Token } from "markdown-it";
2
20
  /**
3
21
  * Represents a node in the token tree structure.
4
22
  */
@@ -11,9 +29,20 @@ export interface TokenTree {
11
29
  children: TokenTree[];
12
30
  }
13
31
  /**
14
- * Parses markdown text into a flat array of markdown-it tokens.
32
+ * A markdown-it plugin reference. Either a bare plugin function or a
33
+ * `[plugin, options]` / `[plugin, ...params]` tuple matching
34
+ * `MarkdownIt.use(...)`.
35
+ *
36
+ * @experimental
37
+ */
38
+ export type MarkdownItPlugin = MarkdownIt.PluginSimple | [MarkdownIt.PluginWithOptions<unknown>, unknown] | [MarkdownIt.PluginWithParams, ...unknown[]];
39
+ /**
40
+ * Returns a (cached) markdown-it instance for the given plugin set, choosing the
41
+ * html-enabled variant or the html-disabled (HTML-neutralizing) variant based on
42
+ * `removeHtml`. Calling with the same `plugins` reference and `removeHtml` returns
43
+ * the same instance.
15
44
  */
16
- export declare function markdownToMarkdownItTokens(fullText: string, allowHtml?: boolean): Token[];
45
+ export declare function getMarkdownIt(plugins?: MarkdownItPlugin[], removeHtml?: boolean): MarkdownIt;
17
46
  /**
18
47
  * Converts a flat list of markdown-it tokens into a tree.
19
48
  */
@@ -27,6 +56,22 @@ export declare function buildTokenTree(tokens: Token[]): TokenTree;
27
56
  */
28
57
  export declare function diffTokenTree(oldTree: TokenTree | undefined, newTree: TokenTree): TokenTree;
29
58
  /**
30
- * Converts markdown into a tree with keys on it for Lit.
59
+ * Result of {@link markdownToTokenTree}. Returns the parsed tree plus the
60
+ * markdown-it instance used to produce it so the renderer can fall back to
61
+ * `md.renderer.render()` for plugin-introduced tokens. The set of
62
+ * plugin-overridden rules is read from the per-instance WeakMap via
63
+ * {@link getPluginOverriddenRules} as needed.
64
+ */
65
+ export interface MarkdownToTokenTreeResult {
66
+ tree: TokenTree;
67
+ md: MarkdownIt;
68
+ }
69
+ /**
70
+ * Converts markdown into a tree with keys on it for Lit. The returned `md` is the
71
+ * (cached) markdown-it instance keyed by `markdownItPlugins` identity and the
72
+ * `removeHtml` flag (html-enabled vs html-neutralizing variant).
31
73
  */
32
- export declare function markdownToTokenTree(markdown: string, lastTree?: TokenTree, allowHtml?: boolean): TokenTree;
74
+ export declare function markdownToTokenTree(markdown: string, lastTree: TokenTree | undefined, opts?: {
75
+ removeHtml?: boolean;
76
+ markdownItPlugins?: MarkdownItPlugin[];
77
+ }): MarkdownToTokenTreeResult;
@@ -19,48 +19,148 @@ import { markdownItTaskLists } from './plugins/markdown-it-task-lists.js';
19
19
  * @license
20
20
  */
21
21
  /**
22
- * Pre-configured markdown-it instance that allows HTML content.
23
- * Uses CommonMark preset for GitHub Flavored Markdown compatibility.
22
+ * The parse/diff layer between raw markdown source and the renderer. Parses with markdown-it (built-in plugins plus any caller-supplied `markdownItPlugins`), builds a nested {@link TokenTree}, and diffs it against the previous tree so streaming updates can reuse stable subtrees.
23
+ *
24
+ * ### Why diff
25
+ *
26
+ * `diffTokenTree` reuses old nodes by `key` whenever the key matches. This is what lets `./markdown-renderer.ts`'s use of Lit's `repeat` directive keep DOM stable during streaming: each incoming chunk re-parses the full source, but matched keys reuse the prior subtree, so only the genuinely new tail differs.
27
+ *
28
+ * ### Why `cachedHtml`
29
+ *
30
+ * For the leaf token types in {@link PLUGIN_DELEGABLE_TOKEN_TYPES}, when a user plugin's renderer rule produces the HTML (via `./utils/plugin-fallback.ts`), the result is cached on the `TokenTree` node and carried forward by `diffTokenTree` whenever the underlying token's `content` / `attrs` / `info` are unchanged. A stable earlier-in-document fence/image/etc. therefore isn't re-rendered through the plugin's rule on every streaming chunk. The cache is tagged with the `MarkdownIt` instance that produced it; a plugin swap (which builds a fresh instance) invalidates the cache on read.
31
+ *
32
+ * The block comment on {@link PLUGIN_DELEGABLE_TOKEN_TYPES} explains why only those four token types are eligible for delegation.
33
+ *
34
+ * ### Related files
35
+ *
36
+ * - `./markdown-renderer.ts` — consumes the `TokenTree` and produces a Lit `TemplateResult`.
37
+ * - `./utils/plugin-fallback.ts` — reads `cachedHtml` and {@link getPluginOverriddenRules} to drive the delegated-render flow.
24
38
  */
25
- const htmlMarkdown = new MarkdownIt("commonmark", {
26
- html: true,
27
- breaks: true,
28
- linkify: true,
29
- })
30
- .enable("table")
31
- .enable("strikethrough")
32
- .enable("linkify")
33
- .use(markdownItAttrs)
34
- .use(markdownItHighlight)
35
- .use(markdownItTaskLists);
36
39
  /**
37
- * Pre-configured markdown-it instance that strips HTML content.
38
- * Same features as htmlMarkdown but with HTML disabled for security.
40
+ * Token types whose renderer rule, when overridden by a user-supplied
41
+ * markdown-it plugin, will be honored instead of the native Lit dispatch.
42
+ * All four are leaf tokens (`nesting === 0`) so the slice handed to
43
+ * `md.renderer.render()` is a single token and the rendered HTML can be
44
+ * safely cached on the {@link TokenTree} node.
45
+ *
46
+ * Container tokens (paragraph_open, heading_open, list_*_open, table_open)
47
+ * are intentionally excluded: delegating them would erase Carbon custom
48
+ * elements (cds-unordered-list, cds-list-item, cds-aichat-table) and break
49
+ * streaming-friendly per-child diffing for the subtree. Link tokens are
50
+ * excluded because the native `<a>` dispatch injects `target="_blank"` for
51
+ * chat-link safety.
52
+ *
53
+ * @internal
54
+ */
55
+ const PLUGIN_DELEGABLE_TOKEN_TYPES = new Set([
56
+ "fence",
57
+ "image",
58
+ "code_inline",
59
+ "html_block",
60
+ ]);
61
+ // Per-instance set of renderer-rule keys that user plugins overrode (or
62
+ // added) relative to the snapshot taken after our built-in plugins ran.
63
+ // WeakMap so cleanup follows the MarkdownIt instance's lifetime.
64
+ const pluginOverriddenRulesByMd = new WeakMap();
65
+ const EMPTY_RULE_SET = new Set();
66
+ /**
67
+ * Returns the set of renderer-rule keys that user-supplied plugins overrode
68
+ * (or freshly added) on the given markdown-it instance, relative to the
69
+ * baseline established after our built-in plugins (markdownItAttrs,
70
+ * markdownItHighlight, markdownItTaskLists) ran. The renderer uses this to
71
+ * decide which token types to route through `md.renderer.render()` instead
72
+ * of native Lit dispatch. Returns an empty set for instances we didn't build.
73
+ *
74
+ * @internal
75
+ */
76
+ function getPluginOverriddenRules(md) {
77
+ return pluginOverriddenRulesByMd.get(md) ?? EMPTY_RULE_SET;
78
+ }
79
+ /**
80
+ * Builds a new markdown-it instance with the built-in plugins and any user-supplied
81
+ * plugins applied on top. `options.html` selects whether raw HTML is parsed as HTML
82
+ * (`true`, the default) or neutralized to inert escaped text (`false`, used when
83
+ * {@link CDSAIChatMarkdown.removeHTML} is set). Both variants are built through this
84
+ * same path so plugin application and overridden-rule snapshotting stay identical.
85
+ *
86
+ * Snapshots `md.renderer.rules` after the built-in plugins but before the user
87
+ * plugins, then records the keys whose function reference changed (or whose
88
+ * key was added) into {@link pluginOverriddenRulesByMd}.
89
+ */
90
+ function createMarkdownIt(plugins, options = {}) {
91
+ const md = new MarkdownIt("commonmark", {
92
+ html: options.html ?? true,
93
+ breaks: true,
94
+ linkify: true,
95
+ })
96
+ .enable("table")
97
+ .enable("strikethrough")
98
+ .enable("linkify")
99
+ .use(markdownItAttrs)
100
+ .use(markdownItHighlight)
101
+ .use(markdownItTaskLists);
102
+ const baselineRules = {
103
+ ...md.renderer.rules,
104
+ };
105
+ for (const plugin of plugins ?? []) {
106
+ if (Array.isArray(plugin)) {
107
+ const [fn, ...args] = plugin;
108
+ md.use(fn, ...args);
109
+ }
110
+ else {
111
+ md.use(plugin);
112
+ }
113
+ }
114
+ const currentRules = md.renderer.rules;
115
+ const overridden = new Set();
116
+ const allKeys = new Set([
117
+ ...Object.keys(baselineRules),
118
+ ...Object.keys(currentRules),
119
+ ]);
120
+ for (const key of allKeys) {
121
+ if (currentRules[key] !== baselineRules[key]) {
122
+ overridden.add(key);
123
+ }
124
+ }
125
+ pluginOverriddenRulesByMd.set(md, overridden);
126
+ return md;
127
+ }
128
+ // Cache for the no-plugins default instances.
129
+ const defaultMarkdownIt = {};
130
+ // Cache keyed by plugin-array identity. WeakMap so plugin arrays that go out of
131
+ // scope can be collected.
132
+ const markdownItCache = new WeakMap();
133
+ /**
134
+ * Returns a (cached) markdown-it instance for the given plugin set, choosing the
135
+ * html-enabled variant or the html-disabled (HTML-neutralizing) variant based on
136
+ * `removeHtml`. Calling with the same `plugins` reference and `removeHtml` returns
137
+ * the same instance.
39
138
  */
40
- const noHtmlMarkdown = new MarkdownIt("commonmark", {
41
- html: false,
42
- breaks: true,
43
- linkify: true,
44
- })
45
- .enable("table")
46
- .enable("strikethrough")
47
- .enable("linkify")
48
- .use(markdownItAttrs)
49
- .use(markdownItHighlight)
50
- .use(markdownItTaskLists);
139
+ function getMarkdownIt(plugins, removeHtml = false) {
140
+ const variants = !plugins || plugins.length === 0
141
+ ? defaultMarkdownIt
142
+ : (markdownItCache.get(plugins) ??
143
+ (() => {
144
+ const created = {};
145
+ markdownItCache.set(plugins, created);
146
+ return created;
147
+ })());
148
+ const slot = removeHtml ? "noHtml" : "html";
149
+ if (!variants[slot]) {
150
+ variants[slot] = createMarkdownIt(plugins, { html: !removeHtml });
151
+ }
152
+ return variants[slot];
153
+ }
51
154
  // markdown-it treats a closing HTML tag and the next markdown line (ie. </div>\n##Heading) as one HTML
52
155
  // block when there is no blank line between them. Insert an extra newline so the
53
156
  // following markdown is parsed as markdown, not swallowed into the HTML token.
54
- function normalizeHtmlBlockBoundaries(markdown, allowHtml) {
55
- if (!allowHtml) {
56
- return markdown;
57
- }
157
+ function normalizeHtmlBlockBoundaries(markdown) {
58
158
  return markdown.replace(/(^|\n)(\s*<\/\s*[A-Za-z][\w:-]*\s*>)(\r?\n)(?=\S)/g, "$1$2$3$3");
59
159
  }
60
160
  // Fallback for html_block tokens that still bundle a closing tag with trailing
61
161
  // markdown on the next line. Split them so the closer stays HTML and the rest
62
162
  // is re-parsed as markdown.
63
- function splitHtmlBlockTrailingMarkdown(tokens, allowHtml) {
163
+ function splitHtmlBlockTrailingMarkdown(tokens, md) {
64
164
  return tokens.flatMap((token) => {
65
165
  if (token.type !== "html_block") {
66
166
  return [token];
@@ -77,18 +177,23 @@ function splitHtmlBlockTrailingMarkdown(tokens, allowHtml) {
77
177
  };
78
178
  return [
79
179
  htmlToken,
80
- ...markdownToMarkdownItTokens(`${leadingWhitespace}${trailingMarkdown}`, allowHtml),
180
+ ...md.parse(`${leadingWhitespace}${trailingMarkdown}`, {}),
81
181
  ];
82
182
  });
83
183
  }
84
184
  /**
85
- * Parses markdown text into a flat array of markdown-it tokens.
185
+ * Parses markdown text into a flat array of markdown-it tokens using the given instance.
186
+ *
187
+ * When `removeHtml` is set, `md` is the html-disabled instance: raw HTML is
188
+ * neutralized to inert escaped text (content preserved) and there are no HTML
189
+ * blocks to normalize or split, so the boundary fixups are skipped.
86
190
  */
87
- function markdownToMarkdownItTokens(fullText, allowHtml = true) {
88
- const normalizedText = normalizeHtmlBlockBoundaries(fullText, allowHtml);
89
- return allowHtml
90
- ? splitHtmlBlockTrailingMarkdown(htmlMarkdown.parse(normalizedText, {}), true)
91
- : noHtmlMarkdown.parse(normalizedText, {});
191
+ function parseMarkdown(fullText, md, removeHtml) {
192
+ if (removeHtml) {
193
+ return md.parse(fullText, {});
194
+ }
195
+ const normalizedText = normalizeHtmlBlockBoundaries(fullText);
196
+ return splitHtmlBlockTrailingMarkdown(md.parse(normalizedText, {}), md);
92
197
  }
93
198
  /**
94
199
  * Generates a unique string key for a markdown-it token.
@@ -156,6 +261,23 @@ function buildTokenTree(tokens) {
156
261
  });
157
262
  return root;
158
263
  }
264
+ function attrsEqual(a, b) {
265
+ if (a === b) {
266
+ return true;
267
+ }
268
+ if (!a || !b) {
269
+ return false;
270
+ }
271
+ if (a.length !== b.length) {
272
+ return false;
273
+ }
274
+ for (let i = 0; i < a.length; i++) {
275
+ if (a[i][0] !== b[i][0] || a[i][1] !== b[i][1]) {
276
+ return false;
277
+ }
278
+ }
279
+ return true;
280
+ }
159
281
  /**
160
282
  * Compares two TokenTree structures and creates a new tree that reuses
161
283
  * unchanged nodes from the old tree.
@@ -174,6 +296,18 @@ function diffTokenTree(oldTree, newTree) {
174
296
  token: newTree.token,
175
297
  children: [],
176
298
  };
299
+ // Carry forward the rendered-HTML cache for leaf tokens delegated to the
300
+ // markdown-it renderer. Skip when the underlying token content, attrs, or
301
+ // info changed (info is the fence's language string and drives the rendered
302
+ // output for plugins like markdown-it-mermaid / syntax highlighters).
303
+ if (oldTree.cachedHtml !== undefined &&
304
+ typeof newTree.token.type === "string" &&
305
+ PLUGIN_DELEGABLE_TOKEN_TYPES.has(newTree.token.type) &&
306
+ oldTree.token.content === newTree.token.content &&
307
+ oldTree.token.info === newTree.token.info &&
308
+ attrsEqual(oldTree.token.attrs ?? undefined, newTree.token.attrs ?? undefined)) {
309
+ merged.cachedHtml = oldTree.cachedHtml;
310
+ }
177
311
  // Create lookup map of old children by key for efficient comparison
178
312
  const oldChildrenByKey = new Map(oldTree.children.map((child) => [child.key, child]));
179
313
  // Process each new child, reusing old ones where possible
@@ -191,16 +325,17 @@ function diffTokenTree(oldTree, newTree) {
191
325
  return merged;
192
326
  }
193
327
  /**
194
- * Converts markdown into a tree with keys on it for Lit.
328
+ * Converts markdown into a tree with keys on it for Lit. The returned `md` is the
329
+ * (cached) markdown-it instance keyed by `markdownItPlugins` identity and the
330
+ * `removeHtml` flag (html-enabled vs html-neutralizing variant).
195
331
  */
196
- function markdownToTokenTree(markdown, lastTree, allowHtml = true) {
197
- // Parse markdown into flat token array
198
- const tokens = markdownToMarkdownItTokens(markdown, allowHtml);
199
- // Build hierarchical tree structure
200
- const tree = buildTokenTree(tokens);
201
- // Optimize by reusing unchanged parts of previous tree
202
- return diffTokenTree(lastTree, tree);
332
+ function markdownToTokenTree(markdown, lastTree, opts = {}) {
333
+ const removeHtml = opts.removeHtml ?? false;
334
+ const md = getMarkdownIt(opts.markdownItPlugins, removeHtml);
335
+ const tokens = parseMarkdown(markdown, md, removeHtml);
336
+ const tree = diffTokenTree(lastTree, buildTokenTree(tokens));
337
+ return { tree, md };
203
338
  }
204
339
 
205
- export { buildTokenTree, diffTokenTree, markdownToMarkdownItTokens, markdownToTokenTree };
340
+ export { PLUGIN_DELEGABLE_TOKEN_TYPES, buildTokenTree, diffTokenTree, getMarkdownIt, getPluginOverriddenRules, markdownToTokenTree };
206
341
  //# sourceMappingURL=markdown-token-tree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"markdown-token-tree.js","sources":["../../../../src/components/markdown/src/markdown-token-tree.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown-token-tree.js","sources":["../../../../src/components/markdown/src/markdown-token-tree.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,6 +1,33 @@
1
1
  import { LitElement, PropertyValues, TemplateResult } from "lit";
2
+ import { type MarkdownItPlugin } from "./markdown-token-tree.js";
3
+ import { type MarkdownCustomRenderers } from "./markdown-renderer.js";
2
4
  /**
3
- * Markdown component
5
+ * Renders markdown as Carbon-styled DOM. Streaming-friendly: incremental updates reparse the markdown source into a `TokenTree`, diff it against the prior tree to reuse stable subtrees, then walk it into a Lit `TemplateResult` — Lit's `repeat` directive keys off the diffed nodes so unchanged DOM stays put.
6
+ *
7
+ * ### Lifecycle
8
+ *
9
+ * 1. A property setter (or a light-DOM mutation) lands. `willUpdate` decides whether the change requires a reparse (`markdown`, `removeHTML`, `markdownItPlugins`) or only a re-render (translated strings, `streaming`, `sanitizeHTML`, `customRenderers`).
10
+ * 2. `scheduleRender` throttles bursts to 100ms (leading + trailing).
11
+ * 3. `renderMarkdown` parses (if needed) via {@link markdownToTokenTree}, then calls {@link renderMarkdownTree} to produce both a `TemplateResult` and a batch of {@link MarkdownRendererSlotDescriptor} records.
12
+ * 4. After Lit commits, `updated()` runs `reconcileCustomRendererHosts` — that is where consumer-supplied `customRenderers` callbacks fire and plugin-fallback HTML is adopted into light-DOM slot hosts.
13
+ *
14
+ * ### Extensibility
15
+ *
16
+ * - {@link markdownItPlugins} runs after the built-in markdown-it plugins (markdown-it-attrs, highlight, task-lists). A new array identity rebuilds the markdown-it instance and forces a full reparse. Tokens introduced by a plugin that the native dispatch can't handle — either an unknown tag, or a plugin-overridden rule on a curated allow-list of leaf tokens — route through `md.renderer.render()` via `./utils/plugin-fallback.ts` and surface as `pluginFallback` descriptors. Their rendered HTML is adopted into a light-DOM slot host so consumer-supplied CSS (e.g. a KaTeX stylesheet on the host page) reaches it.
17
+ * - {@link customRenderers} overrides per-element rendering for `table` and `codeBlock`. The renderer emits a named `<slot>` placeholder; the reconciler invokes the consumer's callback with the parsed data and appends the returned `HTMLElement` as a `<div slot="…">` light-DOM child. Returning the same element reference across renders avoids DOM churn.
18
+ *
19
+ * ### Light-DOM source adoption
20
+ *
21
+ * When the `markdown` property has never been set explicitly, the element treats its light-DOM text content as the initial source and watches for further mutations via a `MutationObserver`. Setting the property explicitly stops the observer — the property is then the authoritative source.
22
+ *
23
+ * ### Related files
24
+ *
25
+ * - `./markdown-token-tree.ts` — markdown-it parse + tree builder + streaming-aware diff (with `cachedHtml` carry-forward for plugin-delegated tokens).
26
+ * - `./markdown-renderer.ts` — `TokenTree` → Lit `TemplateResult`, plus descriptor collection.
27
+ * - `./markdown-renderer-types.ts` — public ({@link MarkdownCustomRenderers}) and internal ({@link MarkdownRendererSlotDescriptor}, `RenderTokenTreeOptions`) contracts.
28
+ * - `./utils/plugin-fallback.ts` — delegation to `md.renderer.render()` for plugin-introduced tokens.
29
+ * - `./utils/streaming-table.ts` — heuristics that hold a streaming table in a skeleton "loading" state until its tail stabilizes.
30
+ *
4
31
  * @element cds-aichat-markdown
5
32
  */
6
33
  declare class CDSAIChatMarkdown extends LitElement {
@@ -61,6 +88,26 @@ declare class CDSAIChatMarkdown extends LitElement {
61
88
  end: number;
62
89
  count: number;
63
90
  }) => string;
91
+ /**
92
+ * Markdown-it plugins applied after the built-in plugins
93
+ * (markdown-it-attrs, markdown-it-highlight, markdown-it-task-lists).
94
+ * Changes force a reparse. Memoize this array — a new reference each render
95
+ * rebuilds the markdown-it instance.
96
+ */
97
+ markdownItPlugins?: MarkdownItPlugin[];
98
+ /**
99
+ * Per-element render overrides. For each `kind` whose callback is provided,
100
+ * the markdown element emits a named `<slot>` placeholder in its shadow
101
+ * DOM, then — after each render — invokes the callback with the parsed
102
+ * data and adopts the returned `HTMLElement` as a `<div slot="…">`
103
+ * light-DOM child of this element. Return `null` to fall back to the
104
+ * default Carbon rendering. Returning the same element reference across
105
+ * renders avoids DOM churn.
106
+ *
107
+ * The consumer's returned element lives in this element's light DOM, not
108
+ * in its shadow root, so external CSS applies normally.
109
+ */
110
+ customRenderers?: MarkdownCustomRenderers;
64
111
  private hasRenderedStreamingTableLoadingFrame;
65
112
  private stagedStreamingTokenTree;
66
113
  private isStreamingTableLoadingMode;
@@ -72,6 +119,7 @@ declare class CDSAIChatMarkdown extends LitElement {
72
119
  private stopObservingLightDom;
73
120
  protected willUpdate(changed: PropertyValues<this>): void;
74
121
  protected getUpdateComplete(): Promise<boolean>;
122
+ protected updated(changed: PropertyValues<this>): void;
75
123
  protected render(): TemplateResult<1>;
76
124
  }
77
125
  declare global {