svelte-streamdown 2.3.3 → 2.3.4

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.
@@ -14,7 +14,8 @@
14
14
  } = $props();
15
15
 
16
16
  const streamdown = useStreamdown();
17
- const highlighter = HighlighterManager.create(streamdown.shikiPreloadThemes || []);
17
+ const highlighter = HighlighterManager.create(streamdown.shikiPreloadThemes);
18
+
18
19
  const copy = useCopy({
19
20
  get content() {
20
21
  return token.text;
@@ -44,8 +45,6 @@
44
45
  void highlighter.load(theme, lang);
45
46
  });
46
47
  });
47
-
48
- const isMounted = streamdown.isMounted;
49
48
  </script>
50
49
 
51
50
  <div class={streamdown.theme.code.base}>
@@ -84,7 +83,7 @@
84
83
  <span class={streamdown.theme.code.line}>
85
84
  {#each line as token}
86
85
  <span
87
- style={isMounted ? streamdown.animationTextStyle : undefined}
86
+ style={streamdown.isMounted ? streamdown.animationTextStyle : undefined}
88
87
  style:color={token.color}
89
88
  style:background-color={token.bgColor}
90
89
  >
@@ -97,7 +96,10 @@
97
96
 
98
97
  {#snippet Skeleton(lines: string[])}
99
98
  {#each lines as line}
100
- <span class={streamdown.theme.code.skeleton}>
99
+ <span
100
+ style={streamdown.isMounted ? streamdown.animationTextStyle : undefined}
101
+ class={streamdown.theme.code.skeleton}
102
+ >
101
103
  {line.trim().length > 0 ? line : '\u200B'}
102
104
  </span>
103
105
  {/each}
@@ -17,7 +17,7 @@ declare class HighlighterManager {
17
17
  * Preloads themes by creating minimal highlighter instances.
18
18
  * This reduces flickering when switching themes.
19
19
  */
20
- preloadThemes(highlighter: Highlighter): Promise<void>;
20
+ preloadThemes(highlighter: Highlighter): Promise<void[]>;
21
21
  /**
22
22
  * Ensures the highlighter is ready for the given theme and language.
23
23
  */
@@ -26,7 +26,7 @@ declare class HighlighterManager {
26
26
  * Highlights code synchronously. Must call isReady() first.
27
27
  */
28
28
  highlightCode(code: string, language: string | undefined, theme: BundledTheme): ThemedToken[][];
29
- static create(preloadedThemes: BundledTheme[]): HighlighterManager;
29
+ static create(preloadedThemes?: BundledTheme[]): HighlighterManager;
30
30
  }
31
31
  export { HighlighterManager };
32
32
  export declare const languageExtensionMap: Record<string, string>;
@@ -23,7 +23,7 @@ class HighlighterManager {
23
23
  if (this.highlighter instanceof Promise) {
24
24
  return this.highlighter;
25
25
  }
26
- else {
26
+ else if (!this.highlighter) {
27
27
  this.highlighter = new Promise((resolve, reject) => {
28
28
  loadShiki().then(([engine, createHighlighter]) => {
29
29
  return createHighlighter({
@@ -38,6 +38,9 @@ class HighlighterManager {
38
38
  });
39
39
  return this.highlighter;
40
40
  }
41
+ else {
42
+ return this.highlighter;
43
+ }
41
44
  }
42
45
  async loadTheme(theme, highlighter) {
43
46
  const themeLoader = this.loadedThemes.get(theme);
@@ -50,6 +53,7 @@ class HighlighterManager {
50
53
  });
51
54
  this.loadedThemes.set(theme, themeLoaderPromise);
52
55
  await themeLoaderPromise;
56
+ this.loadedThemes.set(theme, true);
53
57
  }
54
58
  }
55
59
  async loadLanguage(language, highlighter) {
@@ -63,6 +67,7 @@ class HighlighterManager {
63
67
  });
64
68
  this.loadedLanguages.set(language, languageLoaderPromise);
65
69
  await languageLoaderPromise;
70
+ this.loadedLanguages.set(language, true);
66
71
  }
67
72
  }
68
73
  isLanguageSupported = (language) => {
@@ -70,26 +75,15 @@ class HighlighterManager {
70
75
  };
71
76
  isReady(theme, language = 'bash') {
72
77
  return (!(this.highlighter instanceof Promise) &&
73
- this.loadedLanguages.get(this.isLanguageSupported(language) ? language : 'bash') === true &&
74
- this.loadedThemes.get(theme) === true);
78
+ this.loadedThemes.get(theme) === true &&
79
+ this.loadedLanguages.get(this.isLanguageSupported(language) ? language : 'bash') === true);
75
80
  }
76
81
  /**
77
82
  * Preloads themes by creating minimal highlighter instances.
78
83
  * This reduces flickering when switching themes.
79
84
  */
80
85
  async preloadThemes(highlighter) {
81
- for (const theme of this.preloadedThemes) {
82
- const themeLoader = this.loadedThemes.get(theme);
83
- if (themeLoader === true) {
84
- return;
85
- }
86
- else if (themeLoader instanceof Promise) {
87
- await themeLoader;
88
- }
89
- else {
90
- await this.loadTheme(theme, highlighter);
91
- }
92
- }
86
+ return Promise.all(Array.from(this.preloadedThemes).map((theme) => this.loadTheme(theme, highlighter)));
93
87
  }
94
88
  /**
95
89
  * Ensures the highlighter is ready for the given theme and language.
@@ -101,7 +95,6 @@ class HighlighterManager {
101
95
  !(this.highlighter instanceof Promise) &&
102
96
  themeLoader === true &&
103
97
  languageLoader === true) {
104
- // already loaded
105
98
  return;
106
99
  }
107
100
  const highlighter = await this.loadHighlighter();
@@ -131,7 +124,7 @@ class HighlighterManager {
131
124
  return [];
132
125
  }
133
126
  }
134
- static create(preloadedThemes) {
127
+ static create(preloadedThemes = []) {
135
128
  if (typeof window !== 'undefined' && 'STREAMDOWN_HIGHLIGHTER' in window) {
136
129
  const previousHighlighter = window.STREAMDOWN_HIGHLIGHTER;
137
130
  preloadedThemes.forEach((theme) => previousHighlighter.preloadedThemes.add(theme));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-streamdown",
3
- "version": "2.3.3",
3
+ "version": "2.3.4",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",