@incremark/svelte 0.2.5 → 0.2.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.
Files changed (37) hide show
  1. package/dist/components/AutoScrollContainer.svelte +18 -18
  2. package/dist/components/Incremark.svelte +37 -74
  3. package/dist/components/Incremark.svelte.d.ts +9 -2
  4. package/dist/components/Incremark.svelte.d.ts.map +1 -1
  5. package/dist/components/IncremarkBlockquote.svelte +3 -7
  6. package/dist/components/IncremarkBlockquote.svelte.d.ts.map +1 -1
  7. package/dist/components/IncremarkCode.svelte +44 -124
  8. package/dist/components/IncremarkCode.svelte.d.ts +6 -0
  9. package/dist/components/IncremarkCode.svelte.d.ts.map +1 -1
  10. package/dist/components/IncremarkContent.svelte +114 -0
  11. package/dist/components/IncremarkContent.svelte.d.ts +6 -0
  12. package/dist/components/IncremarkContent.svelte.d.ts.map +1 -0
  13. package/dist/components/IncremarkList.svelte +10 -12
  14. package/dist/components/IncremarkList.svelte.d.ts +0 -1
  15. package/dist/components/IncremarkList.svelte.d.ts.map +1 -1
  16. package/dist/components/IncremarkRenderer.svelte +18 -16
  17. package/dist/components/IncremarkRenderer.svelte.d.ts +3 -0
  18. package/dist/components/IncremarkRenderer.svelte.d.ts.map +1 -1
  19. package/dist/components/index.d.ts +2 -1
  20. package/dist/components/index.d.ts.map +1 -1
  21. package/dist/components/index.js +1 -0
  22. package/dist/components/types.d.ts +29 -3
  23. package/dist/components/types.d.ts.map +1 -1
  24. package/dist/index.d.ts +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/stores/useDevTools.js +2 -2
  28. package/dist/stores/useIncremark.d.ts +4 -3
  29. package/dist/stores/useIncremark.d.ts.map +1 -1
  30. package/dist/stores/useIncremark.js +34 -27
  31. package/dist/stores/useShiki.svelte.d.ts +9 -0
  32. package/dist/stores/useShiki.svelte.d.ts.map +1 -0
  33. package/dist/stores/useShiki.svelte.js +98 -0
  34. package/dist/stores/useTypewriter.d.ts +1 -1
  35. package/dist/stores/useTypewriter.d.ts.map +1 -1
  36. package/dist/stores/useTypewriter.js +3 -3
  37. package/package.json +5 -5
@@ -0,0 +1,98 @@
1
+ // ============ 单例管理器 ============
2
+ class ShikiManager {
3
+ static instance = null;
4
+ highlighters = new Map();
5
+ constructor() { }
6
+ static getInstance() {
7
+ if (!ShikiManager.instance) {
8
+ ShikiManager.instance = new ShikiManager();
9
+ }
10
+ return ShikiManager.instance;
11
+ }
12
+ async getHighlighter(theme) {
13
+ if (this.highlighters.has(theme)) {
14
+ return this.highlighters.get(theme);
15
+ }
16
+ const { createHighlighter } = await import('shiki');
17
+ const highlighter = await createHighlighter({
18
+ themes: [theme],
19
+ langs: []
20
+ });
21
+ const info = {
22
+ highlighter,
23
+ loadedLanguages: new Set(),
24
+ loadedThemes: new Set([theme])
25
+ };
26
+ this.highlighters.set(theme, info);
27
+ return info;
28
+ }
29
+ async loadLanguage(theme, lang) {
30
+ const info = this.highlighters.get(theme);
31
+ if (!info || info.loadedLanguages.has(lang))
32
+ return;
33
+ try {
34
+ await info.highlighter.loadLanguage(lang);
35
+ info.loadedLanguages.add(lang);
36
+ }
37
+ catch { /* 静默处理 */ }
38
+ }
39
+ async loadTheme(theme) {
40
+ const info = this.highlighters.get(theme);
41
+ if (!info || info.loadedThemes.has(theme))
42
+ return;
43
+ try {
44
+ await info.highlighter.loadTheme(theme);
45
+ info.loadedThemes.add(theme);
46
+ }
47
+ catch { /* 静默处理 */ }
48
+ }
49
+ async codeToHtml(theme, code, lang, fallbackTheme) {
50
+ const info = this.highlighters.get(theme);
51
+ if (!info)
52
+ throw new Error('Highlighter not found');
53
+ const actualLang = info.loadedLanguages.has(lang) ? lang : 'text';
54
+ return info.highlighter.codeToHtml(code, {
55
+ lang: actualLang,
56
+ theme: theme
57
+ });
58
+ }
59
+ }
60
+ const shikiManager = ShikiManager.getInstance();
61
+ // ============ Svelte 5 Composable ============
62
+ /**
63
+ * 使用 Shiki Highlighter
64
+ * @param themeGetter 传入一个返回主题字符串的函数,例如 () => theme
65
+ */
66
+ export function useShiki(themeGetter) {
67
+ // 使用 Svelte 5 的原生响应式状态
68
+ let isHighlighting = $state(false);
69
+ /**
70
+ * 高亮代码
71
+ */
72
+ async function highlight(code, lang, fallbackTheme) {
73
+ // 关键:每次执行时通过 Getter 获取最新的主题
74
+ const currentTheme = themeGetter();
75
+ const currentFallback = fallbackTheme;
76
+ isHighlighting = true;
77
+ try {
78
+ const info = await shikiManager.getHighlighter(currentTheme);
79
+ // 按需加载语言
80
+ if (!info.loadedLanguages.has(lang) && lang !== 'text') {
81
+ await shikiManager.loadLanguage(currentTheme, lang);
82
+ }
83
+ // 按需加载主题
84
+ if (!info.loadedThemes.has(currentTheme)) {
85
+ await shikiManager.loadTheme(currentTheme);
86
+ }
87
+ return await shikiManager.codeToHtml(currentTheme, code, lang, currentFallback);
88
+ }
89
+ finally {
90
+ isHighlighting = false;
91
+ }
92
+ }
93
+ return {
94
+ // 使用 getter 暴露只读状态,保持 UI 响应
95
+ get isHighlighting() { return isHighlighting; },
96
+ highlight
97
+ };
98
+ }
@@ -22,7 +22,7 @@ export interface UseTypewriterOptions {
22
22
  export interface UseTypewriterReturn {
23
23
  /** 用于渲染的 blocks(经过打字机处理或原始blocks) */
24
24
  blocks: Readable<Array<ParsedBlock & {
25
- stableId: string;
25
+ isLastPending?: boolean;
26
26
  }>>;
27
27
  /** 打字机控制对象 */
28
28
  typewriter: TypewriterControls;
@@ -1 +1 @@
1
- {"version":3,"file":"useTypewriter.d.ts","sourceRoot":"","sources":["../../src/stores/useTypewriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,WAAW,EAGhB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAG3E;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY;IACZ,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,oBAAoB;IACpB,eAAe,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACxC,oBAAoB;IACpB,aAAa,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAA;IAC3D,cAAc;IACd,UAAU,EAAE,kBAAkB,CAAA;IAC9B,qBAAqB;IACrB,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;IACjD,oCAAoC;IACpC,mBAAmB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;CACvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CA4KhF"}
1
+ {"version":3,"file":"useTypewriter.d.ts","sourceRoot":"","sources":["../../src/stores/useTypewriter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAqB,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC9E,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,WAAW,EAGhB,KAAK,gBAAgB,EAEtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAG3E;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,YAAY;IACZ,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,oBAAoB;IACpB,eAAe,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACxC,oBAAoB;IACpB,aAAa,EAAE,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;CACvC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,GAAG;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC,CAAA;IAClE,cAAc;IACd,UAAU,EAAE,kBAAkB,CAAA;IAC9B,qBAAqB;IACrB,WAAW,EAAE,gBAAgB,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;IACjD,oCAAoC;IACpC,mBAAmB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;CACvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,mBAAmB,CA4KhF"}
@@ -79,12 +79,13 @@ export function useTypewriter(options) {
79
79
  const rawBlocks = derived([completedBlocks, pendingBlocks], ([$completedBlocks, $pendingBlocks]) => {
80
80
  const result = [];
81
81
  for (const block of $completedBlocks) {
82
- result.push({ ...block, stableId: block.id });
82
+ result.push(block);
83
83
  }
84
84
  for (let i = 0; i < $pendingBlocks.length; i++) {
85
+ const isLastPending = i === $pendingBlocks.length - 1;
85
86
  result.push({
86
87
  ...$pendingBlocks[i],
87
- stableId: `pending-${i}`
88
+ isLastPending
88
89
  });
89
90
  }
90
91
  return result;
@@ -106,7 +107,6 @@ export function useTypewriter(options) {
106
107
  }
107
108
  return {
108
109
  id: db.id,
109
- stableId: db.id,
110
110
  status: (db.isDisplayComplete ? 'completed' : 'pending'),
111
111
  isLastPending,
112
112
  node,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@incremark/svelte",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Incremark Svelte 5 集成",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",
@@ -24,10 +24,10 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "shiki": "^3.20.0",
27
- "@incremark/core": "0.2.5",
28
- "@incremark/devtools": "0.2.5",
29
- "@incremark/shared": "0.2.5",
30
- "@incremark/theme": "0.2.5"
27
+ "@incremark/devtools": "0.2.7",
28
+ "@incremark/core": "0.2.7",
29
+ "@incremark/shared": "0.2.7",
30
+ "@incremark/theme": "0.2.7"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "svelte": "^5.0.0",