@incremark/svelte 0.3.2 → 0.3.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.
@@ -5,6 +5,7 @@
5
5
  - 在脚本顶层创建和消费 stream(类似 Vue setup)
6
6
  - 使用 $state 存储 tokens
7
7
  - 使用 $effect 监听 code 变化
8
+ - SSR 兼容:Web Streams API 只在浏览器中使用
8
9
  -->
9
10
  <script lang="ts">
10
11
  import type { ThemedToken } from '@shikijs/core'
@@ -22,6 +23,9 @@
22
23
 
23
24
  let { code, lang, theme, highlighter }: Props = $props()
24
25
 
26
+ // SSR 检测:Web Streams API 只在浏览器中可用
27
+ const isBrowser = typeof window !== 'undefined'
28
+
25
29
  // Stream 错误状态
26
30
  let hasStreamError = $state(false)
27
31
 
@@ -31,57 +35,58 @@
31
35
  // 已处理的 code 长度
32
36
  let index = $state(0)
33
37
 
34
- // 创建文本流(在脚本顶层,类似 Vue setup)
38
+ // Stream 相关状态(只在浏览器中初始化)
35
39
  let controller: ReadableStreamController<string> | null = null
36
- const textStream = new ReadableStream<string>({
37
- start(_controller) {
38
- controller = _controller
39
- }
40
- })
41
-
42
- // 创建 token stream
43
- // 使用 untrack 获取初始值,因为 stream 创建后不支持动态更改 lang/theme/highlighter
44
40
  let tokenStream: ReadableStream<any> | null = null
45
41
 
46
- try {
47
- const initialHighlighter = untrack(() => highlighter)
48
- const initialLang = untrack(() => lang)
49
- const initialTheme = untrack(() => theme)
50
-
51
- tokenStream = textStream.pipeThrough(
52
- new CodeToTokenTransformStream({
53
- highlighter: initialHighlighter,
54
- lang: initialLang,
55
- theme: initialTheme,
56
- allowRecalls: true
57
- })
58
- )
59
- } catch (error) {
60
- console.error('Failed to create token stream:', error)
61
- hasStreamError = true
62
- }
42
+ // 只在浏览器环境中创建 stream
43
+ if (isBrowser) {
44
+ const textStream = new ReadableStream<string>({
45
+ start(_controller) {
46
+ controller = _controller
47
+ }
48
+ })
49
+
50
+ try {
51
+ const initialHighlighter = untrack(() => highlighter)
52
+ const initialLang = untrack(() => lang)
53
+ const initialTheme = untrack(() => theme)
54
+
55
+ tokenStream = textStream.pipeThrough(
56
+ new CodeToTokenTransformStream({
57
+ highlighter: initialHighlighter,
58
+ lang: initialLang,
59
+ theme: initialTheme,
60
+ allowRecalls: true
61
+ })
62
+ )
63
+ } catch (error) {
64
+ console.error('Failed to create token stream:', error)
65
+ hasStreamError = true
66
+ }
63
67
 
64
- // 消费 token stream(与 Vue/React 版本对齐)
65
- if (tokenStream) {
66
- tokenStream.pipeTo(
67
- new WritableStream({
68
- write(token: any) {
69
- if ('recall' in token) {
70
- tokens.splice(tokens.length - token.recall, token.recall)
71
- } else {
72
- tokens.push(token)
68
+ // 消费 token stream
69
+ if (tokenStream) {
70
+ tokenStream.pipeTo(
71
+ new WritableStream({
72
+ write(token: any) {
73
+ if ('recall' in token) {
74
+ tokens.splice(tokens.length - token.recall, token.recall)
75
+ } else {
76
+ tokens.push(token)
77
+ }
73
78
  }
74
- }
79
+ })
80
+ ).catch((error) => {
81
+ console.error('Stream error:', error)
82
+ hasStreamError = true
75
83
  })
76
- ).catch((error) => {
77
- console.error('Stream error:', error)
78
- hasStreamError = true
79
- })
84
+ }
80
85
  }
81
86
 
82
87
  // 监听 code 变化,增量推送到流中(与 Vue 的 watchEffect 对齐)
83
88
  $effect(() => {
84
- if (hasStreamError) return
89
+ if (!isBrowser || hasStreamError || !controller) return
85
90
 
86
91
  // 读取 code 的值来建立依赖
87
92
  const currentCode = code
@@ -92,7 +97,7 @@
92
97
  // 只处理增量更新:传入新增的部分
93
98
  if (currentCode.length > currentIndex) {
94
99
  const incremental = currentCode.slice(currentIndex)
95
- controller?.enqueue(incremental as any)
100
+ controller.enqueue(incremental as any)
96
101
  index = currentCode.length
97
102
  }
98
103
  })
@@ -103,8 +108,8 @@
103
108
  })
104
109
  </script>
105
110
 
106
- {#if hasStreamError}
107
- <!-- 错误状态:渲染纯文本 -->
111
+ {#if hasStreamError || !isBrowser || tokens.length === 0}
112
+ <!-- SSR 或错误时渲染原始代码 -->
108
113
  <pre class="shiki incremark-code-stream"><code>{code}</code></pre>
109
114
  {:else}
110
115
  <!-- 正常渲染高亮代码(与 Vue/React 的渲染结构对齐) -->
@@ -1 +1 @@
1
- {"version":3,"file":"CachedCodeRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/components/CachedCodeRenderer.svelte.ts"],"names":[],"mappings":"AAUE,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,GAAG,CAAA;CACjB;AA+GH,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"CachedCodeRenderer.svelte.d.ts","sourceRoot":"","sources":["../../src/components/CachedCodeRenderer.svelte.ts"],"names":[],"mappings":"AAUE,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,GAAG,CAAA;CACjB;AAmHH,QAAA,MAAM,kBAAkB,2CAAwC,CAAC;AACjE,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAChE,eAAe,kBAAkB,CAAC"}
@@ -30,7 +30,7 @@
30
30
 
31
31
  let {
32
32
  node,
33
- renderDelay = 300
33
+ renderDelay = 0
34
34
  }: Props = $props()
35
35
 
36
36
  // 状态
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export { default as AutoScrollContainer } from './components/AutoScrollContainer
12
12
  export { default as ThemeProvider } from './ThemeProvider.svelte';
13
13
  export { default as ConfigProvider } from './components/ConfigProvider.svelte';
14
14
  export type { ParsedBlock, IncrementalUpdate, ParserOptions, BlockStatus, Root, RootContent, SourceBlock, DisplayBlock, TransformerPlugin, TransformerOptions, TransformerState, AnimationEffect } from '@incremark/core';
15
+ export type { Root as MdastRoot, Parent, Heading, Paragraph, Code, Blockquote, List, ListItem, Table, TableCell, ThematicBreak, Text, PhrasingContent, InlineCode, Link, LinkReference, Image, ImageReference, HTML, Definition, FootnoteDefinition } from 'mdast';
15
16
  export { BlockTransformer, createBlockTransformer, countChars, sliceAst, cloneNode, codeBlockPlugin, mermaidPlugin, imagePlugin, mathPlugin, thematicBreakPlugin, defaultPlugins, allPlugins, createPlugin } from '@incremark/core';
16
17
  export { type DesignTokens, defaultTheme, darkTheme, generateCSSVars, mergeTheme, applyTheme } from '@incremark/theme';
17
18
  import { en as enShared, zhCN as zhCNShared } from '@incremark/shared';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAClK,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC/B,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAG9E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wCAAwC,CAAA;AAGnI,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAA;AACxF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAA;AAG9E,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,IAAI,EACJ,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,SAAS,EACT,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA;AAC7C,YAAY,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AAClK,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACrF,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC/B,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,8BAA8B,CAAA;AAG9E,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wCAAwC,CAAA;AAGnI,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACrB,MAAM,cAAc,CAAA;AAGrB,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,yCAAyC,CAAA;AACxF,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAA;AAG9E,YAAY,EACV,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,IAAI,EACJ,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EAChB,MAAM,iBAAiB,CAAA;AAGxB,YAAY,EACV,IAAI,IAAI,SAAS,EACjB,MAAM,EAEN,OAAO,EACP,SAAS,EACT,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,SAAS,EACT,aAAa,EAEb,IAAI,EACJ,eAAe,EACf,UAAU,EACV,IAAI,EACJ,aAAa,EACb,KAAK,EACL,cAAc,EAEd,IAAI,EAEJ,UAAU,EACV,kBAAkB,EACnB,MAAM,OAAO,CAAA;AAGd,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,UAAU,EACV,QAAQ,EACR,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,YAAY,EACb,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,SAAS,EACT,eAAe,EACf,UAAU,EACV,UAAU,EACX,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EAAE,EAAE,IAAI,QAAQ,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,UAAU,IAAI,IAAI,EAAE,CAAA;AAC7C,YAAY,EAAE,eAAe,EAAE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@incremark/svelte",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "High-performance streaming markdown renderer for Svelte 5 ecosystem.",
5
5
  "type": "module",
6
6
  "svelte": "./dist/index.js",
@@ -26,11 +26,11 @@
26
26
  "@antfu/utils": "^9.3.0",
27
27
  "shiki": "^3.20.0",
28
28
  "shiki-stream": "^0.1.4",
29
- "@incremark/core": "0.3.2",
30
- "@incremark/icons": "0.3.2",
31
- "@incremark/shared": "0.3.2",
32
- "@incremark/theme": "0.3.2",
33
- "@incremark/devtools": "0.3.2"
29
+ "@incremark/core": "0.3.3",
30
+ "@incremark/devtools": "0.3.3",
31
+ "@incremark/icons": "0.3.3",
32
+ "@incremark/shared": "0.3.3",
33
+ "@incremark/theme": "0.3.3"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "svelte": "^5.0.0",