svelte-streamdown 2.2.1 → 2.2.3

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.
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { useStreamdown } from './streamdown.svelte.js';
3
+ import { useStreamdown } from './context.svelte.js';
4
4
 
5
5
  let { children }: { children: Snippet } = $props();
6
6
 
@@ -1,6 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from './streamdown.svelte.js';
3
-
2
+ import { useStreamdown } from './context.svelte.js';
4
3
  let { text }: { text: string } = $props();
5
4
 
6
5
  const streamdown = useStreamdown();
@@ -17,10 +16,7 @@
17
16
 
18
17
  return text.split(splitRegex).filter((token) => token.length > 0);
19
18
  };
20
-
21
- let tokens = $derived.by(() => {
22
- return tokenizeNewContent(text);
23
- });
19
+ const tokens = $derived(tokenizeNewContent(text));
24
20
 
25
21
  const isMounted = streamdown.isMounted;
26
22
  </script>
package/dist/Block.svelte CHANGED
@@ -3,13 +3,15 @@
3
3
  import Element from './Elements/Element.svelte';
4
4
  import { lex, type StreamdownToken } from './marked/index.js';
5
5
  import AnimatedText from './AnimatedText.svelte';
6
- import { useStreamdown } from './streamdown.svelte.js';
6
+ import { useStreamdown } from './context.svelte.js';
7
7
  import AnimatedBlock from './AnimatedBlock.svelte';
8
8
 
9
9
  let {
10
- block
10
+ block,
11
+ insideFootnote = false
11
12
  }: {
12
13
  block: string;
14
+ insideFootnote?: boolean;
13
15
  } = $props();
14
16
  const id = $props.id();
15
17
  const tokens = $derived(lex(parseIncompleteMarkdown(block.trim())));
@@ -23,7 +25,7 @@
23
25
  {@const isTextOnlyNode = children.length === 0}
24
26
  <Element {token}>
25
27
  {#if isTextOnlyNode}
26
- {#if streamdown.animation.enabled}
28
+ {#if streamdown.animation.enabled && !insideFootnote}
27
29
  <AnimatedText text={'text' in token ? token.text : ''} />
28
30
  {:else}
29
31
  {'text' in token ? token.text : ''}
@@ -36,7 +38,7 @@
36
38
  {/each}
37
39
  {/snippet}
38
40
 
39
- {#if streamdown.animation.enabled}
41
+ {#if streamdown.animation.enabled && !insideFootnote}
40
42
  <AnimatedBlock>
41
43
  {@render renderChildren(tokens)}
42
44
  </AnimatedBlock>
@@ -1,5 +1,6 @@
1
1
  type $$ComponentProps = {
2
2
  block: string;
3
+ insideFootnote?: boolean;
3
4
  };
4
5
  declare const Block: import("svelte").Component<$$ComponentProps, {}, "">;
5
6
  type Block = ReturnType<typeof Block>;
@@ -13,7 +13,7 @@
13
13
  /><path d="M12 17h.01" />`
14
14
  };
15
15
 
16
- import { useStreamdown } from '../streamdown.svelte.js';
16
+ import { useStreamdown } from '../context.svelte.js';
17
17
  import Slot from './Slot.svelte';
18
18
  import type { AlertToken } from '../marked/index.js';
19
19
  import type { Snippet } from 'svelte';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../streamdown.svelte.js';
2
+ import { useStreamdown } from '../context.svelte.js';
3
3
  import { save } from '../utils/save.js';
4
4
  import { useCopy } from '../utils/copy.svelte.js';
5
5
  import { HighlighterManager, languageExtensionMap } from '../utils/hightlighter.svelte.js';
@@ -8,7 +8,7 @@
8
8
  import Alert from './Alert.svelte';
9
9
  import type { StreamdownToken } from '../marked/index.js';
10
10
  import Slot from './Slot.svelte';
11
- import { useStreamdown } from '../streamdown.svelte.js';
11
+ import { useStreamdown } from '../context.svelte.js';
12
12
  import FootnoteRef from './FootnoteRef.svelte';
13
13
  let { token, children }: { token: StreamdownToken; children: Snippet } = $props();
14
14
  const streamdown = useStreamdown();
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../streamdown.svelte.js';
2
+ import { useStreamdown } from '../context.svelte.js';
3
3
  import Slot from './Slot.svelte';
4
4
  import type { FootnoteRef } from '../marked/marked-footnotes.js';
5
5
  import {
@@ -100,7 +100,7 @@
100
100
  class={`${streamdown.theme.footnotePopover.base}`}
101
101
  >
102
102
  {#each token.content.lines as line}
103
- <Block block={line} />
103
+ <Block insideFootnote block={line} />
104
104
  {/each}
105
105
  </dialog>
106
106
  </Slot>
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../streamdown.svelte.js';
2
+ import { useStreamdown } from '../context.svelte.js';
3
3
  import { transformUrl } from '../utils/url.js';
4
4
  import Slot from './Slot.svelte';
5
5
  import type { Tokens } from 'marked';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../streamdown.svelte.js';
2
+ import { useStreamdown } from '../context.svelte.js';
3
3
  import { transformUrl } from '../utils/url.js';
4
4
  import Slot from './Slot.svelte';
5
5
  import type { Tokens } from 'marked';
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount, untrack } from 'svelte';
3
- import { useStreamdown } from '../streamdown.svelte.js';
3
+ import { useStreamdown } from '../context.svelte.js';
4
4
  import type { MathToken } from '../marked/index.js';
5
5
  import type { KatexOptions } from 'katex';
6
6
  import 'katex/dist/katex.min.css';
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount } from 'svelte';
3
- import { useStreamdown } from '../streamdown.svelte.js';
3
+ import { useStreamdown } from '../context.svelte.js';
4
4
  import type { Tokens } from 'marked';
5
5
  import type { MermaidConfig } from 'mermaid';
6
6
  import { on } from 'svelte/events';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { useStreamdown } from '../streamdown.svelte.js';
2
+ import { useStreamdown } from '../context.svelte.js';
3
3
  import Slot from './Slot.svelte';
4
4
  import type { Tokens } from 'marked';
5
5
  import type { Snippet } from 'svelte';
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import Block from './Block.svelte';
3
- import { StreamdownContext, type StreamdownProps } from './streamdown.svelte.js';
3
+ import { StreamdownContext, type StreamdownProps } from './context.svelte.js';
4
4
  import { mergeTheme, shadcnTheme } from './theme.js';
5
5
  import { parseBlocks } from './marked/index.js';
6
6
 
@@ -0,0 +1,4 @@
1
+ import { type StreamdownProps } from './context.svelte.js';
2
+ declare const Streamdown: import("svelte").Component<StreamdownProps, {}, "streamdown" | "element">;
3
+ type Streamdown = ReturnType<typeof Streamdown>;
4
+ export default Streamdown;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { default as Streamdown } from './Streamdown.svelte';
2
- export { useStreamdown, type StreamdownProps } from './streamdown.svelte.js';
2
+ export { useStreamdown, type StreamdownProps } from './context.svelte.js';
3
3
  export { theme, shadcnTheme, mergeTheme, type Theme } from './theme.js';
4
4
  export { lex, parseBlocks, type StreamdownToken } from './marked/index.js';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { default as Streamdown } from './Streamdown.svelte';
2
- export { useStreamdown } from './streamdown.svelte.js';
2
+ export { useStreamdown } from './context.svelte.js';
3
3
  export { theme, shadcnTheme, mergeTheme } from './theme.js';
4
4
  export { lex, parseBlocks } from './marked/index.js';
@@ -1,33 +1,56 @@
1
- import { Lexer, Marked } from 'marked';
1
+ import { Lexer } from 'marked';
2
2
  import markedAlert, {} from './marked-alert.js';
3
3
  import markedFootnote, {} from './marked-footnotes.js';
4
4
  import { markedMath } from './marked-math.js';
5
5
  import markedSubSup, {} from './marked-subsup.js';
6
6
  import { markedList } from './marked-list.js';
7
7
  import { markedTable } from './marked-table.js';
8
- const completeLexer = new Marked({
9
- tokenizer: {
10
- table: () => {
11
- return false;
8
+ const extensions = [
9
+ markedTable(),
10
+ markedFootnote(),
11
+ markedAlert(),
12
+ markedMath(),
13
+ markedSubSup(),
14
+ markedList()
15
+ ];
16
+ const parseExtensions = (...ext) => {
17
+ const options = {
18
+ gfm: true,
19
+ extensions: {
20
+ block: [],
21
+ inline: [],
22
+ childTokens: {},
23
+ renderers: {},
24
+ startBlock: [],
25
+ startInline: []
12
26
  }
13
- }
14
- })
15
- .use(markedAlert())
16
- .use(markedFootnote())
17
- .use(markedMath())
18
- .use(markedSubSup())
19
- .use(markedList())
20
- .use(markedTable());
21
- const blockLexer = new Lexer({
22
- extensions: {
23
- childTokens: {},
24
- renderers: {},
25
- block: [markedFootnote().extensions[0].tokenizer, markedTable().extensions[0].tokenizer]
26
- }
27
- });
27
+ };
28
+ ext.forEach(({ extensions }) => {
29
+ extensions.forEach(({ level, name, tokenizer, ...rest }) => {
30
+ if ('start' in rest && rest.start) {
31
+ if (level === 'block') {
32
+ options.extensions.startBlock.push(rest.start);
33
+ }
34
+ else {
35
+ options.extensions.startInline.push(rest.start);
36
+ }
37
+ }
38
+ if (tokenizer) {
39
+ if (level === 'block') {
40
+ options.extensions.block.push(tokenizer);
41
+ }
42
+ else {
43
+ options.extensions.inline.push(tokenizer);
44
+ }
45
+ }
46
+ });
47
+ });
48
+ return options;
49
+ };
50
+ const blockLexer = new Lexer(parseExtensions(markedFootnote(), markedTable()));
28
51
  export const lex = (markdown) => {
29
- return completeLexer
30
- .lexer(markdown)
52
+ return new Lexer(parseExtensions(...extensions))
53
+ .lex(markdown)
31
54
  .filter((token) => token.type !== 'space' && token.type !== 'footnote');
32
55
  };
33
56
  export const parseBlocks = (markdown) => {
@@ -1,5 +1,5 @@
1
1
  import {} from './index.js';
2
- import { StreamdownContext } from '../streamdown.svelte.js';
2
+ import { StreamdownContext } from '../context.svelte.js';
3
3
  import { getContext } from 'svelte';
4
4
  const safeGetContext = () => {
5
5
  try {
@@ -1,6 +1,11 @@
1
- import type { TokenizerAndRendererExtension } from 'marked';
1
+ import type { TokenizerExtensionFunction, TokenizerStartFunction } from 'marked';
2
2
  export declare function markedMath(): {
3
- extensions: TokenizerAndRendererExtension<string, string>[];
3
+ extensions: Array<{
4
+ name: string;
5
+ level: 'block' | 'inline';
6
+ start?: TokenizerStartFunction;
7
+ tokenizer: TokenizerExtensionFunction;
8
+ }>;
4
9
  };
5
10
  export type MathToken = {
6
11
  type: 'math';
@@ -1,9 +1,25 @@
1
- const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1(?=[\s?!\.,:?!。,:]|$)/;
1
+ // const inlineRule =
2
+ // /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1(?=[\s?!\.,:?!。,:]|$)/;
2
3
  const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n\$]))\1/; // Non-standard, even if there are no spaces before and after $ or $$, try to parse
3
4
  const blockRule = /^(\${1,2})\n((?:\\[\s\S]|[^\\])+?)\n\1(?:\n|$)/;
4
5
  export function markedMath() {
5
6
  return {
6
7
  extensions: [
8
+ {
9
+ name: 'block-math',
10
+ level: 'block',
11
+ tokenizer(src) {
12
+ const match = src.match(blockRule);
13
+ if (match) {
14
+ return {
15
+ type: 'math',
16
+ isInline: false,
17
+ raw: match[0],
18
+ text: match[2].trim()
19
+ };
20
+ }
21
+ }
22
+ },
7
23
  {
8
24
  name: 'inline-math',
9
25
  level: 'inline',
@@ -36,21 +52,6 @@ export function markedMath() {
36
52
  };
37
53
  }
38
54
  }
39
- },
40
- {
41
- name: 'block-math',
42
- level: 'block',
43
- tokenizer(src) {
44
- const match = src.match(blockRule);
45
- if (match) {
46
- return {
47
- type: 'math',
48
- isInline: false,
49
- raw: match[0],
50
- text: match[2].trim()
51
- };
52
- }
53
- }
54
55
  }
55
56
  ]
56
57
  };
@@ -1,10 +1,10 @@
1
- import type { TokenizerExtensionFunction } from 'marked';
1
+ import type { TokenizerExtensionFunction, TokenizerStartFunction } from 'marked';
2
2
  export default function markedSubSup(): {
3
3
  extensions: {
4
4
  name: string;
5
5
  level: 'inline';
6
6
  tokenizer: TokenizerExtensionFunction;
7
- start?: (src: string) => number | undefined;
7
+ start?: TokenizerStartFunction;
8
8
  }[];
9
9
  };
10
10
  /**
@@ -1,4 +1,4 @@
1
- import type { TokenizerExtensionFunction } from 'marked';
1
+ import type { TokenizerExtensionFunction, TokenizerStartFunction } from 'marked';
2
2
  export interface SpanTableOptions {
3
3
  useTheadTbody?: boolean;
4
4
  useTfoot?: boolean;
@@ -59,7 +59,7 @@ export declare function markedTable(options?: SpanTableOptions): {
59
59
  extensions: {
60
60
  name: string;
61
61
  level: 'block' | 'inline';
62
- start: (src: string) => number | undefined;
62
+ start: TokenizerStartFunction;
63
63
  tokenizer: TokenizerExtensionFunction;
64
64
  }[];
65
65
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-streamdown",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",