@incremark/vue 0.3.2 → 0.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.
package/README.en.md CHANGED
@@ -17,7 +17,7 @@ Vue 3 integration library for Incremark, providing high-performance streaming Ma
17
17
  ## Installation
18
18
 
19
19
  ```bash
20
- pnpm add @incremark/core @incremark/vue
20
+ pnpm add @incremark/vue @incremark/theme
21
21
  ```
22
22
 
23
23
  ## Quick Start
@@ -28,7 +28,7 @@ pnpm add @incremark/core @incremark/vue
28
28
  <script setup>
29
29
  import { ref } from 'vue'
30
30
  import { IncremarkContent } from '@incremark/vue'
31
- import '@incremark/vue/style.css'
31
+ import '@incremark/theme/styles.css'
32
32
 
33
33
  const content = ref('')
34
34
  const isFinished = ref(false)
package/README.md CHANGED
@@ -15,38 +15,31 @@ Incremark 的 Vue 3 集成库。
15
15
  ## 安装
16
16
 
17
17
  ```bash
18
- pnpm add @incremark/core @incremark/vue
18
+ pnpm add @incremark/vue @incremark/theme
19
19
  ```
20
20
 
21
21
  ## 快速开始
22
22
 
23
- **1. 引入样式**
24
-
25
- ```ts
26
- import '@incremark/vue/style.css'
27
- ```
28
-
29
- **2. 在组件中使用**
30
-
31
23
  ```vue
32
24
  <script setup>
33
- import { useIncremark, Incremark } from '@incremark/vue'
34
- import '@incremark/vue/style.css'
25
+ import { ref } from 'vue'
26
+ import { IncremarkContent } from '@incremark/vue'
27
+ import '@incremark/theme/styles.css'
35
28
 
36
- const { blocks, append, finalize, reset } = useIncremark({ gfm: true })
29
+ const content = ref('')
30
+ const isFinished = ref(false)
37
31
 
38
32
  async function handleStream(stream) {
39
- reset()
40
33
  for await (const chunk of stream) {
41
- append(chunk)
34
+ content.value += chunk
42
35
  }
43
- finalize()
36
+ isFinished.value = true
44
37
  }
45
38
  </script>
46
39
 
47
40
  <template>
48
41
  <button @click="handleStream">开始</button>
49
- <Incremark :blocks="blocks" />
42
+ <IncremarkContent :content="content" :is-finished="isFinished" />
50
43
  </template>
51
44
  ```
52
45
 
@@ -2,8 +2,6 @@ export { useIncremark } from './useIncremark';
2
2
  export type { UseIncremarkOptions, TypewriterOptions, TypewriterControls } from './useIncremark';
3
3
  export { useStreamRenderer } from './useStreamRenderer';
4
4
  export type { UseStreamRendererOptions } from './useStreamRenderer';
5
- export { useDevTools } from './useDevTools';
6
- export type { UseDevToolsOptions } from './useDevTools';
7
5
  export { useBlockTransformer } from './useBlockTransformer';
8
6
  export type { UseBlockTransformerOptions, UseBlockTransformerReturn } from './useBlockTransformer';
9
7
  export { useLocale, type UseLocaleReturn } from './useLocale';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
- export { useIncremark, useStreamRenderer, useDevTools, useBlockTransformer, useLocale } from './composables';
1
+ export { useIncremark, useStreamRenderer, useBlockTransformer, useLocale } from './composables';
2
2
  export { useProvideDefinations } from './composables/useProvideDefinations';
3
3
  export { useDefinationsContext } from './composables/useDefinationsContext';
4
- export type { UseIncremarkOptions, TypewriterOptions, TypewriterControls, UseStreamRendererOptions, UseDevToolsOptions, UseBlockTransformerOptions, UseBlockTransformerReturn } from './composables';
4
+ export type { UseIncremarkOptions, TypewriterOptions, TypewriterControls, UseStreamRendererOptions, UseBlockTransformerOptions, UseBlockTransformerReturn } from './composables';
5
5
  export * from './components';
6
6
  export { default as ThemeProvider } from './ThemeProvider.vue';
7
7
  export { default as ConfigProvider } from './components/ConfigProvider.vue';
8
8
  export type { ParsedBlock, IncrementalUpdate, ParserOptions, BlockStatus, Root, RootContent, SourceBlock, DisplayBlock, TransformerPlugin, TransformerOptions, TransformerState, AnimationEffect } from '@incremark/core';
9
+ 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';
9
10
  export { BlockTransformer, createBlockTransformer, countChars, sliceAst, cloneNode, codeBlockPlugin, mermaidPlugin, imagePlugin, mathPlugin, thematicBreakPlugin, defaultPlugins, allPlugins, createPlugin } from '@incremark/core';
10
11
  export { type DesignTokens, defaultTheme, darkTheme, generateCSSVars, mergeTheme, applyTheme } from '@incremark/theme';
11
12
  import { en as enShared, zhCN as zhCNShared } from '@incremark/shared';
package/dist/index.js CHANGED
@@ -434,37 +434,8 @@ function useStreamRenderer(options) {
434
434
  };
435
435
  }
436
436
 
437
- // src/composables/useDevTools.ts
438
- import { onMounted, onUnmounted as onUnmounted2 } from "vue";
439
- import { createDevTools } from "@incremark/devtools";
440
- function useDevTools(incremark, options = {}) {
441
- const devtools = createDevTools(options);
442
- incremark.parser.setOnChange((state) => {
443
- const blocks = [
444
- ...state.completedBlocks,
445
- ...state.pendingBlocks
446
- ];
447
- devtools.update({
448
- blocks,
449
- completedBlocks: state.completedBlocks,
450
- pendingBlocks: state.pendingBlocks,
451
- markdown: state.markdown,
452
- ast: state.ast,
453
- isLoading: state.pendingBlocks.length > 0
454
- });
455
- });
456
- onMounted(() => {
457
- devtools.mount();
458
- });
459
- onUnmounted2(() => {
460
- devtools.unmount();
461
- incremark.parser.setOnChange(void 0);
462
- });
463
- return devtools;
464
- }
465
-
466
437
  // src/composables/useBlockTransformer.ts
467
- import { ref as ref4, watch as watch3, computed as computed4, onUnmounted as onUnmounted3 } from "vue";
438
+ import { ref as ref4, watch as watch3, computed as computed4, onUnmounted as onUnmounted2 } from "vue";
468
439
  import {
469
440
  createBlockTransformer as createBlockTransformer2
470
441
  } from "@incremark/core";
@@ -495,7 +466,7 @@ function useBlockTransformer(sourceBlocks, options = {}) {
495
466
  },
496
467
  { immediate: true, deep: true }
497
468
  );
498
- onUnmounted3(() => {
469
+ onUnmounted2(() => {
499
470
  transformer.destroy();
500
471
  });
501
472
  return {
@@ -572,12 +543,12 @@ import {
572
543
 
573
544
  // sfc-script:/Users/yishuai/develop/ai/markdown/packages/vue/src/components/IncremarkMath.vue?type=script
574
545
  import { defineComponent as _defineComponent } from "vue";
575
- import { computed as computed6, ref as ref6, watch as watch4, shallowRef as shallowRef3, onUnmounted as onUnmounted4 } from "vue";
546
+ import { computed as computed6, ref as ref6, watch as watch4, shallowRef as shallowRef3, onUnmounted as onUnmounted3 } from "vue";
576
547
  var IncremarkMath_default = /* @__PURE__ */ _defineComponent({
577
548
  __name: "IncremarkMath",
578
549
  props: {
579
550
  node: { type: Object, required: true },
580
- renderDelay: { type: Number, required: false, default: 300 }
551
+ renderDelay: { type: Number, required: false, default: 0 }
581
552
  },
582
553
  setup(__props, { expose: __expose }) {
583
554
  __expose();
@@ -623,7 +594,7 @@ var IncremarkMath_default = /* @__PURE__ */ _defineComponent({
623
594
  isLoading.value = false;
624
595
  }
625
596
  }
626
- onUnmounted4(() => {
597
+ onUnmounted3(() => {
627
598
  if (renderTimer) {
628
599
  clearTimeout(renderTimer);
629
600
  }
@@ -1333,7 +1304,7 @@ import { computed as computed10 } from "vue";
1333
1304
 
1334
1305
  // sfc-script:/Users/yishuai/develop/ai/markdown/packages/vue/src/components/IncremarkCodeMermaid.vue?type=script
1335
1306
  import { defineComponent as _defineComponent7 } from "vue";
1336
- import { computed as computed8, ref as ref7, onUnmounted as onUnmounted5, shallowRef as shallowRef4, watch as watch5 } from "vue";
1307
+ import { computed as computed8, ref as ref7, onUnmounted as onUnmounted4, shallowRef as shallowRef4, watch as watch5 } from "vue";
1337
1308
  import { GravityMermaid, LucideCode, LucideEye, LucideCopy, LucideCopyCheck } from "@incremark/icons";
1338
1309
  import { isClipboardAvailable } from "@incremark/shared";
1339
1310
 
@@ -1426,7 +1397,7 @@ var IncremarkCodeMermaid_default = /* @__PURE__ */ _defineComponent7({
1426
1397
  }
1427
1398
  }
1428
1399
  watch5(code, scheduleRenderMermaid, { immediate: true });
1429
- onUnmounted5(() => {
1400
+ onUnmounted4(() => {
1430
1401
  if (mermaidTimer) {
1431
1402
  clearTimeout(mermaidTimer);
1432
1403
  }
@@ -1750,7 +1721,7 @@ function useShiki(theme) {
1750
1721
 
1751
1722
  // sfc-script:/Users/yishuai/develop/ai/markdown/packages/vue/src/components/CachedCodeRenderer.vue?type=script
1752
1723
  import { defineComponent as _defineComponent8 } from "vue";
1753
- import { h, ref as ref8, reactive, watch as watch6, renderList, onUnmounted as onUnmounted6 } from "vue";
1724
+ import { h, ref as ref8, reactive, watch as watch6, renderList, onUnmounted as onUnmounted5 } from "vue";
1754
1725
  import { CodeToTokenTransformStream } from "shiki-stream";
1755
1726
 
1756
1727
  // ../../node_modules/.pnpm/@shikijs+vscode-textmate@10.0.2/node_modules/@shikijs/vscode-textmate/dist/index.js
@@ -2372,89 +2343,91 @@ var CachedCodeRenderer_default = /* @__PURE__ */ _defineComponent8({
2372
2343
  __expose();
2373
2344
  const props = __props;
2374
2345
  const emit = __emit;
2346
+ const isBrowser = typeof window !== "undefined";
2375
2347
  const hasStreamError = ref8(false);
2348
+ const tokens = reactive([]);
2376
2349
  const index = ref8(0);
2377
2350
  let controller = null;
2378
- const textStream = new ReadableStream({
2379
- start(_controller) {
2380
- controller = _controller;
2351
+ let textStream = null;
2352
+ let tokenStream = null;
2353
+ if (isBrowser) {
2354
+ textStream = new ReadableStream({
2355
+ start(_controller) {
2356
+ controller = _controller;
2357
+ }
2358
+ });
2359
+ try {
2360
+ tokenStream = textStream.pipeThrough(
2361
+ new CodeToTokenTransformStream({
2362
+ highlighter: props.highlighter,
2363
+ lang: props.lang,
2364
+ theme: props.theme,
2365
+ allowRecalls: true
2366
+ })
2367
+ );
2368
+ } catch (error) {
2369
+ console.error("Failed to create token stream:", error);
2370
+ hasStreamError.value = true;
2371
+ emit("stream-error");
2381
2372
  }
2382
- });
2373
+ if (tokenStream) {
2374
+ tokenStream.pipeTo(new WritableStream({
2375
+ write(token) {
2376
+ if ("recall" in token)
2377
+ tokens.splice(tokens.length - token.recall, token.recall);
2378
+ else
2379
+ tokens.push(token);
2380
+ },
2381
+ close: () => {
2382
+ emit("stream-end");
2383
+ }
2384
+ })).catch((error) => {
2385
+ console.error("Stream error:", error);
2386
+ hasStreamError.value = true;
2387
+ emit("stream-error");
2388
+ });
2389
+ }
2390
+ }
2383
2391
  watch6(() => props.code, (newCode) => {
2392
+ if (!isBrowser || !controller) return;
2384
2393
  if (newCode.length > index.value && !hasStreamError.value) {
2385
2394
  const incremental = newCode.slice(index.value);
2386
- controller?.enqueue(incremental);
2395
+ controller.enqueue(incremental);
2387
2396
  index.value = newCode.length;
2388
2397
  }
2389
2398
  }, { immediate: true });
2390
- let tokenStream = null;
2391
- try {
2392
- tokenStream = textStream.pipeThrough(
2393
- new CodeToTokenTransformStream({
2394
- highlighter: props.highlighter,
2395
- lang: props.lang,
2396
- theme: props.theme,
2397
- allowRecalls: true
2398
- })
2399
- );
2400
- } catch (error) {
2401
- console.error("Failed to create token stream:", error);
2402
- hasStreamError.value = true;
2403
- emit("stream-error");
2404
- }
2405
- const tokens = reactive([]);
2406
- if (tokenStream) {
2407
- let tokenCount = 0;
2408
- tokenStream.pipeTo(new WritableStream({
2409
- write(token) {
2410
- const start = performance.now();
2411
- if ("recall" in token)
2412
- tokens.splice(tokens.length - token.recall, token.recall);
2413
- else
2414
- tokens.push(token);
2415
- const elapsed = performance.now() - start;
2416
- tokenCount++;
2417
- if (elapsed > 1) {
2418
- console.log(`[Vue CodeRenderer] Token #${tokenCount} update took ${elapsed.toFixed(2)}ms, total tokens: ${tokens.length}`);
2419
- }
2420
- },
2421
- close: () => {
2422
- console.log(`[Vue CodeRenderer] Stream completed, total tokens: ${tokenCount}`);
2423
- emit("stream-end");
2424
- }
2425
- })).catch((error) => {
2426
- console.error("Stream error:", error);
2427
- hasStreamError.value = true;
2428
- emit("stream-error");
2429
- });
2430
- }
2431
2399
  const render24 = () => {
2432
- if (hasStreamError.value) {
2433
- return h("pre", { class: "shiki incremark-code-stream" }, h("code", props.code));
2400
+ if (hasStreamError.value || !isBrowser || tokens.length === 0) {
2401
+ return h("pre", { class: "shiki incremark-code-stream" }, h("code", {}, props.code));
2434
2402
  }
2435
2403
  return h(
2436
2404
  "pre",
2437
2405
  { class: "shiki incremark-code-stream" },
2438
2406
  h(
2439
2407
  "code",
2408
+ {},
2440
2409
  renderList(tokens, (token) => h("span", { key: objectId(token), style: token.htmlStyle || getTokenStyleObject(token) }, token.content))
2441
2410
  )
2442
2411
  );
2443
2412
  };
2444
- onUnmounted6(() => {
2413
+ onUnmounted5(() => {
2445
2414
  hasStreamError.value = false;
2446
2415
  tokens.length = 0;
2447
2416
  index.value = 0;
2448
2417
  });
2449
- const __returned__ = { props, emit, hasStreamError, index, get controller() {
2418
+ const __returned__ = { props, emit, isBrowser, hasStreamError, tokens, index, get controller() {
2450
2419
  return controller;
2451
2420
  }, set controller(v) {
2452
2421
  controller = v;
2453
- }, textStream, get tokenStream() {
2422
+ }, get textStream() {
2423
+ return textStream;
2424
+ }, set textStream(v) {
2425
+ textStream = v;
2426
+ }, get tokenStream() {
2454
2427
  return tokenStream;
2455
2428
  }, set tokenStream(v) {
2456
2429
  tokenStream = v;
2457
- }, tokens, render: render24 };
2430
+ }, render: render24 };
2458
2431
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
2459
2432
  return __returned__;
2460
2433
  }
@@ -3447,7 +3420,8 @@ var Incremark_default2 = Incremark_default;
3447
3420
 
3448
3421
  // sfc-script:/Users/yishuai/develop/ai/markdown/packages/vue/src/components/IncremarkContent.vue?type=script
3449
3422
  import { defineComponent as _defineComponent20 } from "vue";
3450
- import { computed as computed15, watch as watch8 } from "vue";
3423
+ import { computed as computed15, watch as watch8, onMounted as onMounted4, onUnmounted as onUnmounted6 } from "vue";
3424
+ import { generateParserId } from "@incremark/shared";
3451
3425
  var IncremarkContent_default = /* @__PURE__ */ _defineComponent20({
3452
3426
  __name: "IncremarkContent",
3453
3427
  props: {
@@ -3460,7 +3434,10 @@ var IncremarkContent_default = /* @__PURE__ */ _defineComponent20({
3460
3434
  isFinished: { type: Boolean, required: false },
3461
3435
  incremarkOptions: { type: Object, required: false },
3462
3436
  pendingClass: { type: String, required: false },
3463
- showBlockStatus: { type: Boolean, required: false }
3437
+ showBlockStatus: { type: Boolean, required: false },
3438
+ devtools: { type: null, required: false },
3439
+ devtoolsId: { type: String, required: false },
3440
+ devtoolsLabel: { type: String, required: false }
3464
3441
  },
3465
3442
  setup(__props, { expose: __expose }) {
3466
3443
  __expose();
@@ -3472,7 +3449,22 @@ var IncremarkContent_default = /* @__PURE__ */ _defineComponent20({
3472
3449
  math: true,
3473
3450
  ...props.incremarkOptions
3474
3451
  }));
3475
- const { blocks, append, finalize, render: render24, reset, isDisplayComplete, markdown } = useIncremark(incremarkOptions);
3452
+ const incremark = useIncremark(incremarkOptions);
3453
+ const { blocks, append, finalize, render: render24, reset, isDisplayComplete, markdown } = incremark;
3454
+ const parserId = props.devtoolsId || generateParserId();
3455
+ onMounted4(() => {
3456
+ if (props.devtools) {
3457
+ props.devtools.register(incremark.parser, {
3458
+ id: parserId,
3459
+ label: props.devtoolsLabel || parserId
3460
+ });
3461
+ }
3462
+ });
3463
+ onUnmounted6(() => {
3464
+ if (props.devtools) {
3465
+ props.devtools.unregister(parserId);
3466
+ }
3467
+ });
3476
3468
  const isStreamMode = computed15(() => typeof props.stream === "function");
3477
3469
  async function handleStreamInput() {
3478
3470
  if (!props.stream) return;
@@ -3513,7 +3505,7 @@ var IncremarkContent_default = /* @__PURE__ */ _defineComponent20({
3513
3505
  finalize();
3514
3506
  }
3515
3507
  }, { immediate: true });
3516
- const __returned__ = { props, incremarkOptions, blocks, append, finalize, render: render24, reset, isDisplayComplete, markdown, isStreamMode, handleStreamInput, handleContentInput, Incremark: Incremark_default2 };
3508
+ const __returned__ = { props, incremarkOptions, incremark, blocks, append, finalize, render: render24, reset, isDisplayComplete, markdown, parserId, isStreamMode, handleStreamInput, handleContentInput, Incremark: Incremark_default2 };
3517
3509
  Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
3518
3510
  return __returned__;
3519
3511
  }
@@ -3829,7 +3821,6 @@ export {
3829
3821
  thematicBreakPlugin,
3830
3822
  useBlockTransformer,
3831
3823
  useDefinationsContext,
3832
- useDevTools,
3833
3824
  useIncremark,
3834
3825
  useLocale,
3835
3826
  useProvideDefinations,