markstream-vue2 2.0.23 → 2.0.24

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/dist/index.js CHANGED
@@ -54,8 +54,8 @@ import { sanitizeHtmlAttrs, hasCustomHtmlComponents, tokenizeHtml, BLOCKED_HTML_
54
54
  export * from "stream-markdown-parser";
55
55
  import { KATEX_COMMANDS, normalizeStandaloneBackslashT, setDefaultMathOptions as setDefaultMathOptions2 } from "stream-markdown-parser";
56
56
  import * as VueModule from "vue-demi";
57
- import { defineComponent, getCurrentInstance, computed, shallowRef, h, inject, ref, watch, readonly, useAttrs, onMounted, nextTick, onUpdated, onBeforeUnmount, provide, onUnmounted, getCurrentScope, onScopeDispose, markRaw, reactive } from "vue-demi";
58
- import { normalizeShikiLanguage, createSmoothMarkdownStream, createPanGesture, applyMermaidThemeDirective } from "markstream-core";
57
+ import { defineComponent, getCurrentInstance, computed, shallowRef, h, inject, ref, onMounted, watch, onBeforeUnmount, readonly, useAttrs, nextTick, onUpdated, provide, onUnmounted, getCurrentScope, onScopeDispose, markRaw, reactive } from "vue-demi";
58
+ import { createStreamingTextDom, normalizeShikiLanguage, createSmoothMarkdownStream, RENDERER_STREAM_DEFAULTS, createRendererStreamBridge, createStreamingTextScope, createPanGesture, applyMermaidThemeDirective } from "markstream-core";
59
59
  import { autoUpdate, offset, flip, shift, computePosition } from "@floating-ui/dom";
60
60
  function getVue2MinorVersion$1(version) {
61
61
  const raw = typeof version === "string" ? version : "";
@@ -633,20 +633,6 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
633
633
  },
634
634
  setup(__props) {
635
635
  const props = __props;
636
- function settleAndMergeSegments(current, segmentId) {
637
- return current.reduce((result, segment) => {
638
- const nextSegment = segment.id === segmentId ? __spreadProps(__spreadValues({}, segment), { fading: false }) : segment;
639
- const previousSegment = result[result.length - 1];
640
- if (previousSegment && !previousSegment.fading && !nextSegment.fading) {
641
- result[result.length - 1] = __spreadProps(__spreadValues({}, previousSegment), {
642
- content: previousSegment.content + nextSegment.content
643
- });
644
- } else {
645
- result.push(nextSegment);
646
- }
647
- return result;
648
- }, []);
649
- }
650
636
  const instance = getCurrentInstance();
651
637
  const attrs = computed(() => {
652
638
  var _a2, _b;
@@ -676,82 +662,29 @@ const _sfc_main$D = /* @__PURE__ */ defineComponent({
676
662
  return "";
677
663
  return String(raw);
678
664
  });
679
- const segments = ref(props.node.code ? [{ id: 0, content: props.node.code, fading: false }] : []);
680
- const renderedCode = ref(props.node.code);
681
- let nextSegmentId = 1;
682
- function setFullContent(next) {
683
- var _a2;
684
- if (segments.value.length === 1 && !((_a2 = segments.value[0]) == null ? void 0 : _a2.fading) && segments.value[0].content === next)
685
- return;
686
- segments.value = next ? [{ id: nextSegmentId++, content: next, fading: false }] : [];
687
- }
688
- function settleSegment(segmentId) {
689
- if (!segments.value.some((segment) => segment.id === segmentId && segment.fading))
690
- return;
691
- segments.value = settleAndMergeSegments(segments.value, segmentId);
692
- }
693
- function streamedDeltaClass(segment) {
694
- return segment.id % 2 === 0 ? "inline-code-stream-delta--a" : "inline-code-stream-delta--b";
665
+ const scope = inject("markstreamTextScope", void 0);
666
+ const host = ref();
667
+ const initial = props.node.code;
668
+ let binding;
669
+ function update() {
670
+ const content2 = props.node.code;
671
+ const key = streamStateKey.value;
672
+ binding == null ? void 0 : binding.update(content2, fadeEnabled.value, key ? inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.get(key) : void 0);
673
+ if (key)
674
+ inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, content2);
695
675
  }
696
- watch(
697
- [() => props.node.code, streamStateKey, fadeEnabled],
698
- ([next]) => {
699
- const normalized = String(next != null ? next : "");
700
- const key = streamStateKey.value;
701
- const previousPersisted = key ? inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.get(key) : void 0;
702
- const previousContent = previousPersisted != null ? previousPersisted : renderedCode.value;
703
- const resumeFromPersistedContent = previousPersisted !== void 0 && previousPersisted !== renderedCode.value;
704
- if (!fadeEnabled.value) {
705
- setFullContent(normalized);
706
- } else if (normalized !== previousContent) {
707
- if (previousContent && normalized.startsWith(previousContent)) {
708
- const appendedContent = normalized.slice(previousContent.length);
709
- const lastSegment = segments.value[segments.value.length - 1];
710
- if (resumeFromPersistedContent) {
711
- segments.value = [
712
- { id: nextSegmentId++, content: previousContent, fading: false },
713
- { id: nextSegmentId++, content: appendedContent, fading: true }
714
- ];
715
- } else if (lastSegment == null ? void 0 : lastSegment.fading) {
716
- segments.value = [
717
- ...segments.value.slice(0, -1),
718
- __spreadProps(__spreadValues({}, lastSegment), { content: lastSegment.content + appendedContent })
719
- ];
720
- } else {
721
- segments.value = [
722
- ...segments.value,
723
- { id: nextSegmentId++, content: appendedContent, fading: true }
724
- ];
725
- }
726
- } else {
727
- setFullContent(normalized);
728
- }
729
- }
730
- renderedCode.value = normalized;
731
- if (key)
732
- inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, normalized);
733
- },
734
- { immediate: true }
735
- );
736
- watch(
737
- fadeEnabled,
738
- (enabled) => {
739
- if (enabled)
740
- return;
741
- setFullContent(renderedCode.value);
742
- }
743
- );
744
- return { __sfc: true, props, settleAndMergeSegments, instance, attrs, inheritedFade, inheritedTextStreamState, explicitFade, fadeEnabled, streamStateKey, segments, renderedCode, nextSegmentId, setFullContent, settleSegment, streamedDeltaClass };
676
+ onMounted(() => {
677
+ binding = createStreamingTextDom(host.value, initial, scope);
678
+ update();
679
+ });
680
+ watch([() => props.node.code, streamStateKey, fadeEnabled], update);
681
+ onBeforeUnmount(() => binding == null ? void 0 : binding.dispose());
682
+ return { __sfc: true, props, instance, attrs, inheritedFade, inheritedTextStreamState, explicitFade, fadeEnabled, streamStateKey, scope, host, initial, binding, update };
745
683
  }
746
684
  });
747
- const InlineCodeNode_vue_vue_type_style_index_0_scoped_8b374652_lang = "";
748
685
  var _sfc_render$D = function render6() {
749
686
  var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;
750
- return _c("code", { staticClass: "inline text-[85%] px-1 py-0.5 rounded font-mono bg-[hsl(var(--secondary))] whitespace-normal break-words max-w-full before:content-[''] after:content-['']" }, _vm._l(_setup.segments, function(segment) {
751
- return _c("span", { key: segment.id, class: segment.fading ? ["inline-code-stream-delta", _setup.streamedDeltaClass(segment)] : void 0, on: { "animationend": function($event) {
752
- segment.fading && _setup.settleSegment(segment.id);
753
- } } }, [_vm._v(" " + _vm._s(segment.content) + " ")]);
754
- }), 0);
687
+ return _c("code", { ref: "host", staticClass: "inline text-[85%] px-1 py-0.5 rounded font-mono bg-[hsl(var(--secondary))] whitespace-normal break-words max-w-full before:content-[''] after:content-['']" }, [_c("span", [_vm._v(_vm._s(_setup.initial))])]);
755
688
  };
756
689
  var _sfc_staticRenderFns$D = [];
757
690
  var __component__$D = /* @__PURE__ */ normalizeComponent(
@@ -760,7 +693,7 @@ var __component__$D = /* @__PURE__ */ normalizeComponent(
760
693
  _sfc_staticRenderFns$D,
761
694
  false,
762
695
  null,
763
- "8b374652",
696
+ null,
764
697
  null,
765
698
  null
766
699
  );
@@ -1144,23 +1077,8 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
1144
1077
  props: {
1145
1078
  node: null
1146
1079
  },
1147
- emits: ["copy"],
1148
1080
  setup(__props) {
1149
1081
  const props = __props;
1150
- function settleAndMergeSegments(current, segmentId) {
1151
- return current.reduce((result, segment) => {
1152
- const nextSegment = segmentId == null || segment.id === segmentId ? __spreadProps(__spreadValues({}, segment), { fading: false }) : segment;
1153
- const previousSegment = result[result.length - 1];
1154
- if (previousSegment && !previousSegment.fading && !nextSegment.fading) {
1155
- result[result.length - 1] = __spreadProps(__spreadValues({}, previousSegment), {
1156
- content: previousSegment.content + nextSegment.content
1157
- });
1158
- } else {
1159
- result.push(nextSegment);
1160
- }
1161
- return result;
1162
- }, []);
1163
- }
1164
1082
  const katexReady = useKatexReady();
1165
1083
  const instance = getCurrentInstance();
1166
1084
  const attrs = computed(() => {
@@ -1169,7 +1087,6 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
1169
1087
  });
1170
1088
  const inheritedFade = inject("markstreamFade", void 0);
1171
1089
  const inheritedTextStreamState = inject("markstreamTextStreamState", void 0);
1172
- const inheritedStreamVersion = inject("markstreamStreamVersion", void 0);
1173
1090
  const explicitFade = computed(() => {
1174
1091
  const raw = attrs.value.fade;
1175
1092
  if (raw === "" || raw === true || raw === "true")
@@ -1192,100 +1109,30 @@ const _sfc_main$B = /* @__PURE__ */ defineComponent({
1192
1109
  return "";
1193
1110
  return String(raw);
1194
1111
  });
1195
- const segments = ref(props.node.content ? [{ id: 0, content: props.node.content, fading: false }] : []);
1196
- const renderedContent = ref(props.node.content);
1197
- let nextSegmentId = 1;
1198
- function setFullContent(next) {
1199
- var _a2;
1200
- if (segments.value.length === 1 && !((_a2 = segments.value[0]) == null ? void 0 : _a2.fading) && segments.value[0].content === next)
1201
- return;
1202
- segments.value = next ? [{ id: nextSegmentId++, content: next, fading: false }] : [];
1203
- }
1204
- function settleSegment(segmentId) {
1205
- if (!segments.value.some((segment) => segment.id === segmentId && segment.fading))
1206
- return;
1207
- segments.value = settleAndMergeSegments(segments.value, segmentId);
1208
- }
1209
- function settleFadingSegments() {
1210
- if (!segments.value.some((segment) => segment.fading))
1211
- return;
1212
- segments.value = settleAndMergeSegments(segments.value);
1213
- }
1214
- function streamedDeltaClass(segment) {
1215
- return segment.id % 2 === 0 ? "text-node-stream-delta--a" : "text-node-stream-delta--b";
1112
+ const scope = inject("markstreamTextScope", void 0);
1113
+ const host = ref();
1114
+ const initial = props.node.content;
1115
+ let binding;
1116
+ function update() {
1117
+ const content2 = props.node.content;
1118
+ const key = streamStateKey.value;
1119
+ binding == null ? void 0 : binding.update(content2, fadeEnabled.value, key ? inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.get(key) : void 0);
1120
+ if (key)
1121
+ inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, content2);
1216
1122
  }
1217
- watch(
1218
- [() => props.node.content, streamStateKey, fadeEnabled, () => inheritedStreamVersion == null ? void 0 : inheritedStreamVersion.value],
1219
- ([next]) => {
1220
- const normalized = String(next != null ? next : "");
1221
- const key = streamStateKey.value;
1222
- const previousPersisted = key ? inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.get(key) : void 0;
1223
- const previousContent = previousPersisted != null ? previousPersisted : renderedContent.value;
1224
- const resumeFromPersistedContent = previousPersisted !== void 0 && previousPersisted !== renderedContent.value;
1225
- if (!fadeEnabled.value) {
1226
- setFullContent(normalized);
1227
- renderedContent.value = normalized;
1228
- if (key)
1229
- inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, normalized);
1230
- return;
1231
- }
1232
- if (normalized === previousContent) {
1233
- if (segments.value.some((segment) => segment.fading))
1234
- settleFadingSegments();
1235
- else if (renderedContent.value !== normalized)
1236
- setFullContent(normalized);
1237
- if (key)
1238
- inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, normalized);
1239
- renderedContent.value = normalized;
1240
- return;
1241
- }
1242
- if (previousContent && normalized.startsWith(previousContent)) {
1243
- const appendedContent = normalized.slice(previousContent.length);
1244
- const lastSegment = segments.value[segments.value.length - 1];
1245
- if (resumeFromPersistedContent) {
1246
- segments.value = [
1247
- { id: nextSegmentId++, content: previousContent, fading: false },
1248
- { id: nextSegmentId++, content: appendedContent, fading: true }
1249
- ];
1250
- } else if (lastSegment == null ? void 0 : lastSegment.fading) {
1251
- segments.value = [
1252
- ...segments.value.slice(0, -1),
1253
- __spreadProps(__spreadValues({}, lastSegment), { content: lastSegment.content + appendedContent })
1254
- ];
1255
- } else {
1256
- segments.value = [
1257
- ...segments.value,
1258
- { id: nextSegmentId++, content: appendedContent, fading: true }
1259
- ];
1260
- }
1261
- } else {
1262
- setFullContent(normalized);
1263
- }
1264
- renderedContent.value = normalized;
1265
- if (key)
1266
- inheritedTextStreamState == null ? void 0 : inheritedTextStreamState.set(key, normalized);
1267
- },
1268
- { immediate: true }
1269
- );
1270
- watch(
1271
- fadeEnabled,
1272
- (enabled) => {
1273
- if (enabled)
1274
- return;
1275
- setFullContent(renderedContent.value);
1276
- }
1277
- );
1278
- return { __sfc: true, props, settleAndMergeSegments, katexReady, instance, attrs, inheritedFade, inheritedTextStreamState, inheritedStreamVersion, explicitFade, fadeEnabled, streamStateKey, segments, renderedContent, nextSegmentId, setFullContent, settleSegment, settleFadingSegments, streamedDeltaClass };
1123
+ onMounted(() => {
1124
+ binding = createStreamingTextDom(host.value, initial, scope);
1125
+ update();
1126
+ });
1127
+ watch([() => props.node.content, streamStateKey, fadeEnabled], update);
1128
+ onBeforeUnmount(() => binding == null ? void 0 : binding.dispose());
1129
+ return { __sfc: true, props, katexReady, instance, attrs, inheritedFade, inheritedTextStreamState, explicitFade, fadeEnabled, streamStateKey, scope, host, initial, binding, update };
1279
1130
  }
1280
1131
  });
1281
- const TextNode_vue_vue_type_style_index_0_scoped_152fed75_lang = "";
1132
+ const TextNode_vue_vue_type_style_index_0_scoped_593a680b_lang = "";
1282
1133
  var _sfc_render$B = function render8() {
1283
1134
  var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;
1284
- return _c("span", { staticClass: "whitespace-pre-wrap break-words text-node", class: [_setup.katexReady && _vm.node.center ? "text-node-center" : ""] }, _vm._l(_setup.segments, function(segment) {
1285
- return _c("span", { key: segment.id, class: segment.fading ? ["text-node-stream-delta", _setup.streamedDeltaClass(segment)] : void 0, on: { "animationend": function($event) {
1286
- segment.fading && _setup.settleSegment(segment.id);
1287
- } } }, [_vm._v(" " + _vm._s(segment.content) + " ")]);
1288
- }), 0);
1135
+ return _c("span", { ref: "host", staticClass: "whitespace-pre-wrap break-words text-node", class: _setup.katexReady && _vm.node.center ? "text-node-center" : "" }, [_c("span", [_vm._v(_vm._s(_setup.initial))])]);
1289
1136
  };
1290
1137
  var _sfc_staticRenderFns$B = [];
1291
1138
  var __component__$B = /* @__PURE__ */ normalizeComponent(
@@ -1294,7 +1141,7 @@ var __component__$B = /* @__PURE__ */ normalizeComponent(
1294
1141
  _sfc_staticRenderFns$B,
1295
1142
  false,
1296
1143
  null,
1297
- "152fed75",
1144
+ "593a680b",
1298
1145
  null,
1299
1146
  null
1300
1147
  );
@@ -4126,9 +3973,8 @@ const _sfc_main$e = /* @__PURE__ */ defineComponent({
4126
3973
  return {
4127
3974
  index: index2,
4128
3975
  indexKey: `${indexPrefix.value}-${index2}`,
4129
- // Keep code blocks mounted during streaming so Shiki/stream-diffs renderers can
4130
- // preserve their last successful DOM instead of flashing back to <pre>.
4131
- renderKey: type === "code_block" ? `${indexPrefix.value}-${index2}-${type}` : `${indexPrefix.value}-${index2}-${type}-${String((rawNode == null ? void 0 : rawNode.raw) || "").length}`,
3976
+ // Streaming updates must preserve word animations and selected text nodes.
3977
+ renderKey: `${indexPrefix.value}-${index2}-${type}`,
4132
3978
  node,
4133
3979
  isCodeBlock: (node == null ? void 0 : node.type) === "code_block",
4134
3980
  component,
@@ -5789,8 +5635,8 @@ function useSmoothMarkdownStream(options = {}) {
5789
5635
  pendingChars,
5790
5636
  enqueue: (chunk) => controller.enqueue(chunk),
5791
5637
  finish: (options2) => controller.finish(options2),
5792
- flush: () => controller.flush(),
5793
- reset: (initialMarkdown) => controller.reset(initialMarkdown),
5638
+ flush: (options2) => controller.flush(options2),
5639
+ reset: (initialMarkdown, options2) => controller.reset(initialMarkdown, options2),
5794
5640
  pause: () => controller.pause(),
5795
5641
  resume: () => controller.resume()
5796
5642
  };
@@ -5889,7 +5735,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5889
5735
  },
5890
5736
  emits: ["copy", "copy-code", "handleArtifactClick", "click", "mouseover", "mouseout"],
5891
5737
  setup(__props, { emit }) {
5892
- var _a2, _b, _c;
5738
+ var _a2, _b, _c, _d;
5893
5739
  const props = __props;
5894
5740
  function isNativeDomEvent(value) {
5895
5741
  return typeof Event !== "undefined" && value instanceof Event;
@@ -5919,7 +5765,25 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5919
5765
  });
5920
5766
  const textStreamState = /* @__PURE__ */ new Map();
5921
5767
  const streamRenderVersion = ref(0);
5922
- const smoothStream = useSmoothMarkdownStream(props.smoothStreamingOptions);
5768
+ const smoothStream = useSmoothMarkdownStream(__spreadProps(__spreadValues(__spreadValues({}, RENDERER_STREAM_DEFAULTS), props.smoothStreamingOptions), { burstInitialContent: props.fade === false && !props.typewriter }));
5769
+ const finalReady = ref(false);
5770
+ const streamBridge = createRendererStreamBridge(__spreadProps(__spreadValues({}, smoothStream), {
5771
+ getSnapshot: () => ({ source: smoothStream.source.value, pendingChars: smoothStream.pendingChars.value, caughtUp: smoothStream.caughtUp.value })
5772
+ }), {
5773
+ flushOnFinish: (_a2 = props.smoothStreamingOptions) == null ? void 0 : _a2.flushOnFinish,
5774
+ commit: (work) => __async(this, null, function* () {
5775
+ work();
5776
+ yield nextTick();
5777
+ }),
5778
+ measure: () => {
5779
+ var _a3;
5780
+ void ((_a3 = containerRef.value) == null ? void 0 : _a3.offsetHeight);
5781
+ },
5782
+ onReady: (value) => {
5783
+ finalReady.value = value;
5784
+ }
5785
+ });
5786
+ onBeforeUnmount(streamBridge.dispose);
5923
5787
  const resolvedShowTooltips = computed(() => {
5924
5788
  var _a3;
5925
5789
  if (typeof props.showTooltips === "boolean")
@@ -5983,11 +5847,15 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
5983
5847
  const base = (_a3 = props.parseOptions) != null ? _a3 : {};
5984
5848
  return (_b2 = props.final) != null ? _b2 : base.final;
5985
5849
  });
5850
+ const inheritedTextScope = inject("markstreamTextScope", void 0);
5851
+ const ownTextScope = createStreamingTextScope(streamBridge.scheduleCleanup, inheritedTextScope);
5852
+ provide("markstreamTextScope", ownTextScope);
5853
+ watch(requestedFinal, (value) => ownTextScope.setFinal(value === true), { immediate: true, flush: "sync" });
5986
5854
  const effectiveFinal = computed(() => {
5987
5855
  const finalRequested = requestedFinal.value;
5988
5856
  if (smoothStreamingEnabled.value && finalRequested != null) {
5989
5857
  return Boolean(
5990
- finalRequested && smoothSourceSynced.value && smoothStream.caughtUp.value
5858
+ finalRequested && finalReady.value && smoothSourceSynced.value && smoothStream.caughtUp.value
5991
5859
  );
5992
5860
  }
5993
5861
  return finalRequested;
@@ -6001,29 +5869,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6001
5869
  watch(
6002
5870
  [() => props.content, () => props.nodes, smoothStreamingEnabled, requestedFinal],
6003
5871
  ([content2, nodes, enabled, finalRequested]) => {
6004
- if (nodes == null ? void 0 : nodes.length) {
6005
- smoothStream.reset("");
6006
- return;
6007
- }
6008
- const nextContent = content2 != null ? content2 : "";
6009
- if (!enabled) {
6010
- smoothStream.reset(nextContent);
6011
- if (finalRequested)
6012
- smoothStream.finish({ flush: true });
6013
- return;
6014
- }
6015
- const source = smoothStream.source.value;
6016
- if (!nextContent) {
6017
- smoothStream.reset("");
6018
- } else if (nextContent === source)
6019
- ;
6020
- else if (nextContent.startsWith(source)) {
6021
- smoothStream.enqueue(nextContent.slice(source.length));
6022
- } else {
6023
- smoothStream.reset(nextContent);
6024
- }
6025
- if (finalRequested)
6026
- smoothStream.finish();
5872
+ streamBridge.update(content2 != null ? content2 : "", !!(nodes == null ? void 0 : nodes.length), enabled, finalRequested, props.fade !== false);
6027
5873
  },
6028
5874
  { immediate: true }
6029
5875
  );
@@ -6116,8 +5962,9 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6116
5962
  const arr = (_a3 = mergedParseOptions.value.customHtmlTags) != null ? _a3 : [];
6117
5963
  return new Set(arr.map((t) => String(t).trim().toLowerCase()).filter(Boolean));
6118
5964
  });
5965
+ const parsedSnapshots = /* @__PURE__ */ new WeakMap();
6119
5966
  const parsedNodes = computed(() => {
6120
- var _a3;
5967
+ var _a3, _b2;
6121
5968
  if (isLegacyVue26Vm(instance == null ? void 0 : instance.proxy) && !props.content && Array.isArray(props.nodes))
6122
5969
  return EMPTY_PARSED_NODES;
6123
5970
  if ((_a3 = props.nodes) == null ? void 0 : _a3.length)
@@ -6125,7 +5972,12 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6125
5972
  const contentToParse = renderContent.value;
6126
5973
  if (contentToParse) {
6127
5974
  const parseStart = debugPerformanceEnabled.value ? performance.now() : 0;
6128
- const parsed = parseMarkdownToStructure(contentToParse, mdInstance.value, mergedParseOptions.value);
5975
+ const base = mergedParseOptions.value;
5976
+ const reuse = !props.customMarkdownIt && !base.preTransformTokens && !base.postTransformTokens && !base.postTransformNodes;
5977
+ const parsed = parseMarkdownToStructure(contentToParse, mdInstance.value, __spreadProps(__spreadValues({}, base), {
5978
+ streamParse: (_b2 = base.streamParse) != null ? _b2 : true,
5979
+ reuseStableTopLevelNodes: reuse
5980
+ }));
6129
5981
  if (debugPerformanceEnabled.value) {
6130
5982
  logPerf("parse(sync)", {
6131
5983
  ms: Math.round(performance.now() - parseStart),
@@ -6133,7 +5985,15 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6133
5985
  contentLength: contentToParse.length
6134
5986
  });
6135
5987
  }
6136
- return markRaw(cloneParsedNodeList(parsed));
5988
+ return markRaw(parsed.map((node) => {
5989
+ const cached = reuse ? parsedSnapshots.get(node) : void 0;
5990
+ if (cached)
5991
+ return cached;
5992
+ const snapshot = cloneNodeValue(node);
5993
+ if (reuse)
5994
+ parsedSnapshots.set(node, snapshot);
5995
+ return snapshot;
5996
+ }));
6137
5997
  }
6138
5998
  return [];
6139
5999
  });
@@ -6163,7 +6023,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6163
6023
  );
6164
6024
  const requestFrame = isClient && typeof window.requestAnimationFrame === "function" ? window.requestAnimationFrame.bind(window) : null;
6165
6025
  const cancelFrame = isClient && typeof window.cancelAnimationFrame === "function" ? window.cancelAnimationFrame.bind(window) : null;
6166
- const isTestEnv = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && ((_b = (_a2 = globalThis.process) == null ? void 0 : _a2.env) == null ? void 0 : _b.NODE_ENV) === "test";
6026
+ const isTestEnv = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && ((_c = (_b = globalThis.process) == null ? void 0 : _b.env) == null ? void 0 : _c.NODE_ENV) === "test";
6167
6027
  const hasIdleCallback = isClient && typeof window.requestIdleCallback === "function";
6168
6028
  const resolvedBatchSize = computed(() => {
6169
6029
  var _a3;
@@ -6235,7 +6095,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6235
6095
  const previousBatchConfig = ref({
6236
6096
  batchSize: resolvedBatchSize.value,
6237
6097
  initial: resolvedInitialBatch.value,
6238
- delay: (_c = props.renderBatchDelay) != null ? _c : 16,
6098
+ delay: (_d = props.renderBatchDelay) != null ? _d : 16,
6239
6099
  enabled: incrementalRenderingActive.value
6240
6100
  });
6241
6101
  const shouldObserveSlots = computed(() => !!registerNodeVisibility && (deferNodes.value || virtualizationEnabled.value));
@@ -6299,11 +6159,11 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6299
6159
  return Math.max(renderedCount.value, target);
6300
6160
  });
6301
6161
  function resolveScrollContainer(node) {
6302
- var _a3, _b2, _c2, _d;
6162
+ var _a3, _b2, _c2, _d2;
6303
6163
  const resolved = resolveViewportRoot((_a3 = node != null ? node : containerRef.value) != null ? _a3 : null);
6304
6164
  if (resolved)
6305
6165
  return resolved;
6306
- const host = (_d = (_c2 = node == null ? void 0 : node.ownerDocument) != null ? _c2 : (_b2 = containerRef.value) == null ? void 0 : _b2.ownerDocument) != null ? _d : typeof document !== "undefined" ? document : null;
6166
+ const host = (_d2 = (_c2 = node == null ? void 0 : node.ownerDocument) != null ? _c2 : (_b2 = containerRef.value) == null ? void 0 : _b2.ownerDocument) != null ? _d2 : typeof document !== "undefined" ? document : null;
6307
6167
  return (host == null ? void 0 : host.scrollingElement) || (host == null ? void 0 : host.documentElement) || null;
6308
6168
  }
6309
6169
  function isReverseFlexScrollRoot(root) {
@@ -6321,9 +6181,9 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6321
6181
  }
6322
6182
  }
6323
6183
  function getNormalizedScrollTop(root, doc, isViewportRoot) {
6324
- var _a3, _b2, _c2, _d, _e, _f;
6184
+ var _a3, _b2, _c2, _d2, _e, _f;
6325
6185
  if (isViewportRoot)
6326
- return (_d = (_c2 = (_a3 = doc == null ? void 0 : doc.documentElement) == null ? void 0 : _a3.scrollTop) != null ? _c2 : (_b2 = doc == null ? void 0 : doc.body) == null ? void 0 : _b2.scrollTop) != null ? _d : 0;
6186
+ return (_d2 = (_c2 = (_a3 = doc == null ? void 0 : doc.documentElement) == null ? void 0 : _a3.scrollTop) != null ? _c2 : (_b2 = doc == null ? void 0 : doc.body) == null ? void 0 : _b2.scrollTop) != null ? _d2 : 0;
6327
6187
  const raw = root.scrollTop;
6328
6188
  if (!isReverseFlexScrollRoot(root))
6329
6189
  return raw;
@@ -6401,7 +6261,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6401
6261
  }
6402
6262
  }
6403
6263
  function syncFocusToScroll(force = false) {
6404
- var _a3, _b2, _c2, _d, _e, _f, _g;
6264
+ var _a3, _b2, _c2, _d2, _e, _f, _g;
6405
6265
  if (!virtualizationEnabled.value)
6406
6266
  return;
6407
6267
  const root = scrollRootElement.value || resolveScrollContainer();
@@ -6453,7 +6313,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
6453
6313
  const offsetTop = getOffsetTopWithinRoot(container, root);
6454
6314
  return Math.max(0, rootScrollTop - offsetTop);
6455
6315
  })();
6456
- const viewportHeight = isViewportRoot ? (_g = (_f = (_e = view == null ? void 0 : view.innerHeight) != null ? _e : (_d = doc == null ? void 0 : doc.documentElement) == null ? void 0 : _d.clientHeight) != null ? _f : root.clientHeight) != null ? _g : 0 : root.clientHeight;
6316
+ const viewportHeight = isViewportRoot ? (_g = (_f = (_e = view == null ? void 0 : view.innerHeight) != null ? _e : (_d2 = doc == null ? void 0 : doc.documentElement) == null ? void 0 : _d2.clientHeight) != null ? _f : root.clientHeight) != null ? _g : 0 : root.clientHeight;
6457
6317
  const targetOffset = relativeScrollTop + Math.max(0, viewportHeight) * 0.5;
6458
6318
  const estimated = estimateIndexForOffset(targetOffset);
6459
6319
  focusIndex.value = clamp(estimated, 0, Math.max(0, parsedNodes.value.length - 1));
@@ -7400,14 +7260,14 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7400
7260
  return code ? code.split(/\r\n|\n|\r/).length : 1;
7401
7261
  }
7402
7262
  function estimateBuiltinCodeBlockHeight(node) {
7403
- var _a3, _b2, _c2, _d, _e, _f, _g;
7263
+ var _a3, _b2, _c2, _d2, _e, _f, _g;
7404
7264
  const lineHeight = (_b2 = (_a3 = props.codeBlockOptions) == null ? void 0 : _a3.lineHeight) != null ? _b2 : 18;
7405
7265
  const isDiff = Boolean(node.diff);
7406
7266
  const configuredDiffInline = pickBoolean(builtinCodeBlockExtraProps.value.diffInline);
7407
7267
  const diffInline = isDiff && (configuredDiffInline != null ? configuredDiffInline : ((_c2 = props.codeBlockOptions) == null ? void 0 : _c2.diffStyle) === "unified");
7408
7268
  const lineCount = isDiff ? diffInline ? countCodeLines(node.originalCode) + countCodeLines(node.updatedCode) : Math.max(countCodeLines(node.originalCode), countCodeLines(node.updatedCode)) : countCodeLines(node.code);
7409
7269
  const defaultPadding = isDiff ? 0 : 8;
7410
- const padding = (_e = (_d = props.codeBlockOptions) == null ? void 0 : _d.padding) != null ? _e : defaultPadding;
7270
+ const padding = (_e = (_d2 = props.codeBlockOptions) == null ? void 0 : _d2.padding) != null ? _e : defaultPadding;
7411
7271
  const paddingTop = padding;
7412
7272
  const paddingBottom = padding;
7413
7273
  const maxHeight = (_g = (_f = props.codeBlockOptions) == null ? void 0 : _f.maxHeight) != null ? _g : 500;
@@ -7459,7 +7319,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7459
7319
  const listBindings = computed(() => __spreadValues(__spreadValues({}, nonCodeBindings.value), typeof props.showTooltips === "boolean" ? { showTooltips: props.showTooltips } : {}));
7460
7320
  const legacyRenderedItems = computed(() => {
7461
7321
  return legacyNodeItems.value.map((item, index2) => {
7462
- var _a3, _b2, _c2, _d;
7322
+ var _a3, _b2, _c2, _d2;
7463
7323
  const node = getCodeBlockRenderNode(item, index2);
7464
7324
  const language = getCodeBlockLanguage(node);
7465
7325
  let resolvedNode = node;
@@ -7479,7 +7339,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7479
7339
  });
7480
7340
  }
7481
7341
  } else if (shouldRenderUnknownHtmlTagAsText((_b2 = node.content) != null ? _b2 : node.raw, tag)) {
7482
- const rawContent2 = String((_d = (_c2 = node.content) != null ? _c2 : node.raw) != null ? _d : "");
7342
+ const rawContent2 = String((_d2 = (_c2 = node.content) != null ? _c2 : node.raw) != null ? _d2 : "");
7483
7343
  if (node.type === "html_inline") {
7484
7344
  component = TextNode;
7485
7345
  resolvedNode = {
@@ -7516,7 +7376,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7516
7376
  });
7517
7377
  const renderedItems = computed(() => {
7518
7378
  return visibleNodes.value.map((item) => {
7519
- var _a3, _b2, _c2, _d;
7379
+ var _a3, _b2, _c2, _d2;
7520
7380
  let node = getCodeBlockRenderNode(item.node, item.index);
7521
7381
  const language = getCodeBlockLanguage(node);
7522
7382
  let component = getNodeComponent(node, language);
@@ -7535,7 +7395,7 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7535
7395
  });
7536
7396
  }
7537
7397
  } else if (shouldRenderUnknownHtmlTagAsText((_b2 = node.content) != null ? _b2 : node.raw, tag)) {
7538
- const rawContent2 = String((_d = (_c2 = node.content) != null ? _c2 : node.raw) != null ? _d : "");
7398
+ const rawContent2 = String((_d2 = (_c2 = node.content) != null ? _c2 : node.raw) != null ? _d2 : "");
7539
7399
  if (node.type === "html_inline") {
7540
7400
  component = TextNode;
7541
7401
  node = {
@@ -7887,14 +7747,14 @@ const _sfc_main$9 = /* @__PURE__ */ defineComponent({
7887
7747
  }),
7888
7748
  { flush: "post" }
7889
7749
  );
7890
- return { __sfc: true, props, emit, isNativeDomEvent, emitCodeCopy, MAX_DEFERRED_NODE_COUNT, MAX_VIEWPORT_OBSERVER_TARGETS, VIEWPORT_PRIORITY_RECOVERY_COUNT, containerRef, viewportPriorityAutoDisabled, SCROLL_PARENT_OVERFLOW_RE, isClient, instance, debugPerformanceEnabled, attrs, textStreamState, streamRenderVersion, smoothStream, resolvedShowTooltips, inheritedHtmlPolicy, inheritedSmoothStreaming, inheritedClipboardWriter, resolvedHtmlPolicy, smoothStreamingEligible, hasMountedForSmoothStreaming, smoothStreamingEnabled, renderContent, rawContent, smoothSourceSynced, requestedFinal, effectiveFinal, renderVersionSource, logPerf, resolveViewportRoot, instanceMsgId, defaultMd, customTagCache, EMPTY_PARSED_NODES, customComponentsMap, effectiveCustomHtmlTags, mdBase, mdInstance, cloneNodeValue, cloneParsedNodeList, mergedParseOptions, effectiveCustomHtmlTagsSet, parsedNodes, maxLiveNodesResolved, virtualizationEnabled, viewportPriorityEnabled, registerNodeVisibility, requestFrame, cancelFrame, isTestEnv, hasIdleCallback, resolvedBatchSize, resolvedInitialBatch, batchingEnabled, renderedCount, previousRenderContext, adaptiveBatchSize, nodeVisibilityState, nodeVisibilityHandles, nodeVisibilityFallbackTimers, nodeSlotElements, codeBlockRenderCache, nodeSlotVersion, sortedNodeSlots, scrollRootElement, detachScrollHandler, pendingFocusSync, liveRange, visibleNodes, deferNodes, incrementalRenderingActive, previousBatchConfig, shouldObserveSlots, liveNodeBufferResolved, focusIndex, nodeContentElements, legacyVue26, legacyNodesMode, legacyNodeItems, syncNodeRefs, resolveTemplateRef, desiredRenderedCount, resolveScrollContainer, isReverseFlexScrollRoot, getNormalizedScrollTop, getOffsetTopWithinRoot, cleanupScrollListener, setupScrollListener, cancelScheduledFocusSync, scheduleFocusSync, syncFocusToScroll, clamp, updateLiveRange, nodeHeights, heightStats, heightTreeSize, heightSumTree, heightKnownTree, resetHeightMeasurements, pruneHeightMeasurements, fenwickUpdate, fenwickQuery, fenwickRangeSum, rebuildHeightTrees, recordNodeHeight, averageNodeHeight, estimateHeightRange, topSpacerHeight, bottomSpacerHeight, estimateIndexForOffset, estimateIndexForOffsetFromEnd, cleanupNodeVisibility, markNodeVisible, shouldRenderNode, destroyNodeHandle, setNodeSlotElement, bumpNodeSlotVersion, setNodeContentRef, batchRaf, batchTimeout, batchPending, pendingIncrement, batchIdle, VIEWPORT_FALLBACK_DELAY, VIEWPORT_FALLBACK_MARGIN_PX, cancelBatchTimers, clearVisibilityFallback, scheduleVisibilityFallback, autoDisableViewportPriority, scheduleBatch, queueNextBatch, adjustAdaptiveBatchSize, MermaidBlockNodeLoading, mermaidBlockNodeComponent, mermaidBlockNodeImport, loadMermaidBlockNode, resolveMermaidBlockNodeComponent, InfographicBlockNodeLoading, infographicBlockNodeComponent, infographicBlockNodeImport, loadInfographicBlockNode, resolveInfographicBlockNodeComponent, D2BlockNodeAsync, codeBlockComponent, nodeComponents, indexPrefix, codeBlockExtraProps, builtinCodeBlockExtraProps, codeBlockBindings, customCodeBlockBindings, countCodeLines, estimateBuiltinCodeBlockHeight, pickBoolean, preCodeBlockBindings, mermaidBindings, d2Bindings, infographicBindings, nonCodeBindings, linkBindings, listBindings, legacyRenderedItems, legacyStructuredContentMode, renderedItems, getCodeBlockRenderNode, getCodeBlockLanguage, getCustomCodeLanguageComponent, isLegacyStructuredNode, getRenderKey, getMermaidBindingsFor, getInfographicBindingsFor, getNodeComponent, isCustomCodeBlockComponent, isCustomLanguageCodeBlockComponent, getBindingsFor, handleContainerClick, handleContainerMouseover, handleContainerMouseout, hasExplicitNodes, typewriterCursorRef, showTypewriterCursor, typewriterCursorTimeout, lastTypewriterContentLength, TYPEWRITER_CURSOR_EXCLUDED_NODE_TYPES, shouldSkipTypewriterCursorForNode, shouldShowTypewriterCursorForCurrentNodes, getNodeTextLength, getTypewriterContentLength, clearTypewriterCursorTimeout, getLastTextNode, updateTypewriterCursorPosition, LegacyNodesRenderer };
7750
+ return { __sfc: true, props, emit, isNativeDomEvent, emitCodeCopy, MAX_DEFERRED_NODE_COUNT, MAX_VIEWPORT_OBSERVER_TARGETS, VIEWPORT_PRIORITY_RECOVERY_COUNT, containerRef, viewportPriorityAutoDisabled, SCROLL_PARENT_OVERFLOW_RE, isClient, instance, debugPerformanceEnabled, attrs, textStreamState, streamRenderVersion, smoothStream, finalReady, streamBridge, resolvedShowTooltips, inheritedHtmlPolicy, inheritedSmoothStreaming, inheritedClipboardWriter, resolvedHtmlPolicy, smoothStreamingEligible, hasMountedForSmoothStreaming, smoothStreamingEnabled, renderContent, rawContent, smoothSourceSynced, requestedFinal, inheritedTextScope, ownTextScope, effectiveFinal, renderVersionSource, logPerf, resolveViewportRoot, instanceMsgId, defaultMd, customTagCache, EMPTY_PARSED_NODES, customComponentsMap, effectiveCustomHtmlTags, mdBase, mdInstance, cloneNodeValue, cloneParsedNodeList, mergedParseOptions, effectiveCustomHtmlTagsSet, parsedSnapshots, parsedNodes, maxLiveNodesResolved, virtualizationEnabled, viewportPriorityEnabled, registerNodeVisibility, requestFrame, cancelFrame, isTestEnv, hasIdleCallback, resolvedBatchSize, resolvedInitialBatch, batchingEnabled, renderedCount, previousRenderContext, adaptiveBatchSize, nodeVisibilityState, nodeVisibilityHandles, nodeVisibilityFallbackTimers, nodeSlotElements, codeBlockRenderCache, nodeSlotVersion, sortedNodeSlots, scrollRootElement, detachScrollHandler, pendingFocusSync, liveRange, visibleNodes, deferNodes, incrementalRenderingActive, previousBatchConfig, shouldObserveSlots, liveNodeBufferResolved, focusIndex, nodeContentElements, legacyVue26, legacyNodesMode, legacyNodeItems, syncNodeRefs, resolveTemplateRef, desiredRenderedCount, resolveScrollContainer, isReverseFlexScrollRoot, getNormalizedScrollTop, getOffsetTopWithinRoot, cleanupScrollListener, setupScrollListener, cancelScheduledFocusSync, scheduleFocusSync, syncFocusToScroll, clamp, updateLiveRange, nodeHeights, heightStats, heightTreeSize, heightSumTree, heightKnownTree, resetHeightMeasurements, pruneHeightMeasurements, fenwickUpdate, fenwickQuery, fenwickRangeSum, rebuildHeightTrees, recordNodeHeight, averageNodeHeight, estimateHeightRange, topSpacerHeight, bottomSpacerHeight, estimateIndexForOffset, estimateIndexForOffsetFromEnd, cleanupNodeVisibility, markNodeVisible, shouldRenderNode, destroyNodeHandle, setNodeSlotElement, bumpNodeSlotVersion, setNodeContentRef, batchRaf, batchTimeout, batchPending, pendingIncrement, batchIdle, VIEWPORT_FALLBACK_DELAY, VIEWPORT_FALLBACK_MARGIN_PX, cancelBatchTimers, clearVisibilityFallback, scheduleVisibilityFallback, autoDisableViewportPriority, scheduleBatch, queueNextBatch, adjustAdaptiveBatchSize, MermaidBlockNodeLoading, mermaidBlockNodeComponent, mermaidBlockNodeImport, loadMermaidBlockNode, resolveMermaidBlockNodeComponent, InfographicBlockNodeLoading, infographicBlockNodeComponent, infographicBlockNodeImport, loadInfographicBlockNode, resolveInfographicBlockNodeComponent, D2BlockNodeAsync, codeBlockComponent, nodeComponents, indexPrefix, codeBlockExtraProps, builtinCodeBlockExtraProps, codeBlockBindings, customCodeBlockBindings, countCodeLines, estimateBuiltinCodeBlockHeight, pickBoolean, preCodeBlockBindings, mermaidBindings, d2Bindings, infographicBindings, nonCodeBindings, linkBindings, listBindings, legacyRenderedItems, legacyStructuredContentMode, renderedItems, getCodeBlockRenderNode, getCodeBlockLanguage, getCustomCodeLanguageComponent, isLegacyStructuredNode, getRenderKey, getMermaidBindingsFor, getInfographicBindingsFor, getNodeComponent, isCustomCodeBlockComponent, isCustomLanguageCodeBlockComponent, getBindingsFor, handleContainerClick, handleContainerMouseover, handleContainerMouseout, hasExplicitNodes, typewriterCursorRef, showTypewriterCursor, typewriterCursorTimeout, lastTypewriterContentLength, TYPEWRITER_CURSOR_EXCLUDED_NODE_TYPES, shouldSkipTypewriterCursorForNode, shouldShowTypewriterCursorForCurrentNodes, getNodeTextLength, getTypewriterContentLength, clearTypewriterCursorTimeout, getLastTextNode, updateTypewriterCursorPosition, LegacyNodesRenderer };
7891
7751
  }
7892
7752
  });
7893
- const NodeRenderer_vue_vue_type_style_index_0_scoped_095485e0_lang = "";
7753
+ const NodeRenderer_vue_vue_type_style_index_0_scoped_a9d123de_lang = "";
7894
7754
  const NodeRenderer_vue_vue_type_style_index_1_lang = "";
7895
7755
  var _sfc_render$9 = function render36() {
7896
7756
  var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;
7897
- return _c("div", { ref: "containerRef", staticClass: "markstream-vue2 markdown-renderer", class: [{ dark: _setup.props.isDark }, { virtualized: _setup.virtualizationEnabled }], attrs: { "data-custom-id": _setup.props.customId }, on: { "click": _setup.handleContainerClick, "mouseover": _setup.handleContainerMouseover, "mouseout": _setup.handleContainerMouseout } }, [_setup.legacyNodesMode ? _vm._l(_setup.legacyRenderedItems, function(item) {
7757
+ return _c("div", { ref: "containerRef", staticClass: "markstream-vue2 markdown-renderer", class: [{ dark: _setup.props.isDark }, { virtualized: _setup.virtualizationEnabled }], attrs: { "data-stream-final": _setup.requestedFinal === true ? "" : void 0, "data-custom-id": _setup.props.customId }, on: { "click": _setup.handleContainerClick, "mouseover": _setup.handleContainerMouseover, "mouseout": _setup.handleContainerMouseout } }, [_setup.legacyNodesMode ? _vm._l(_setup.legacyRenderedItems, function(item) {
7898
7758
  return _c("div", { key: item.renderKey, staticClass: "node-slot", attrs: { "data-node-index": item.index, "data-node-type": item.node.type } }, [_c("div", { staticClass: "node-content" }, [!item.isCodeBlock && _setup.props.fade !== false ? _c("transition", { attrs: { "name": "fade", "appear": "" } }, [_c(item.component, _vm._b({ tag: "component", attrs: { "node": item.node, "loading": item.node.loading, "index-key": item.indexKey, "custom-id": _setup.props.customId, "is-dark": _setup.props.isDark }, on: { "copy": function($event) {
7899
7759
  return _setup.emitCodeCopy($event);
7900
7760
  }, "handle-artifact-click": function($event) {
@@ -7928,7 +7788,7 @@ var __component__$9 = /* @__PURE__ */ normalizeComponent(
7928
7788
  _sfc_staticRenderFns$9,
7929
7789
  false,
7930
7790
  null,
7931
- "095485e0",
7791
+ "a9d123de",
7932
7792
  null,
7933
7793
  null
7934
7794
  );
@@ -9072,10 +8932,25 @@ const _sfc_main$5 = defineComponent({
9072
8932
  LegacyNodesRenderer,
9073
8933
  NodeRenderer
9074
8934
  },
8935
+ inject: {
8936
+ inheritedSmooth: { from: "markstreamSmoothStreaming", default: void 0 },
8937
+ inheritedTextScope: { from: "markstreamTextScope", default: void 0 }
8938
+ },
8939
+ provide() {
8940
+ if (!this.legacyVue26)
8941
+ return {};
8942
+ const pacing = () => this.legacyPacing;
8943
+ return {
8944
+ markstreamTextScope: this.legacyTextScope,
8945
+ markstreamSmoothStreaming: { get value() {
8946
+ return pacing();
8947
+ } }
8948
+ };
8949
+ },
9075
8950
  props: {
9076
8951
  content: String,
9077
8952
  nodes: Array,
9078
- final: Boolean,
8953
+ final: { type: Boolean, default: void 0 },
9079
8954
  parseOptions: Object,
9080
8955
  customMarkdownIt: Function,
9081
8956
  debugPerformance: Boolean,
@@ -9102,6 +8977,8 @@ const _sfc_main$5 = defineComponent({
9102
8977
  type: Boolean,
9103
8978
  default: true
9104
8979
  },
8980
+ smoothStreaming: { type: [Boolean, String], default: "auto" },
8981
+ smoothStreamingOptions: Object,
9105
8982
  batchRendering: Boolean,
9106
8983
  initialRenderBatchSize: Number,
9107
8984
  renderBatchSize: Number,
@@ -9114,17 +8991,30 @@ const _sfc_main$5 = defineComponent({
9114
8991
  },
9115
8992
  data() {
9116
8993
  return {
8994
+ legacyVisible: "",
8995
+ legacyReady: false,
8996
+ legacyStream: null,
8997
+ legacyBridge: null,
8998
+ legacyTextScope: createStreamingTextScope((work) => {
8999
+ var _a2;
9000
+ return (_a2 = this.legacyBridge) == null ? void 0 : _a2.scheduleCleanup(work);
9001
+ }, this.inheritedTextScope),
9117
9002
  instanceMsgId: this.customId ? `renderer-${this.customId}` : `renderer-${Date.now()}-${Math.random().toString(36).slice(2)}`
9118
9003
  };
9119
9004
  },
9120
9005
  computed: {
9006
+ legacyPacing() {
9007
+ var _a2, _b, _c;
9008
+ return this.smoothStreaming !== false && !((_a2 = this.nodes) == null ? void 0 : _a2.length) && (this.smoothStreaming === true || !((_b = this.inheritedSmooth) == null ? void 0 : _b.value) && (this.typewriter || ((_c = this.maxLiveNodes) != null ? _c : 0) <= 0));
9009
+ },
9121
9010
  legacyVue26() {
9122
9011
  return isLegacyVue26Vm(this);
9123
9012
  },
9124
9013
  mergedParseOptions() {
9125
- var _a2, _b;
9014
+ var _a2, _b, _c;
9126
9015
  const base = (_a2 = this.parseOptions) != null ? _a2 : {};
9127
- const resolvedFinal = (_b = this.final) != null ? _b : base.final;
9016
+ const requestedFinal = (_b = this.final) != null ? _b : base.final;
9017
+ const resolvedFinal = this.legacyVue26 && this.legacyPacing && requestedFinal === true ? this.legacyReady && this.legacyVisible === ((_c = this.content) != null ? _c : "") : requestedFinal;
9128
9018
  const merged = mergeCustomHtmlTags(this.customHtmlTags, base.customHtmlTags);
9129
9019
  const hasFinal = resolvedFinal != null;
9130
9020
  const hasCustom = merged.length > 0;
@@ -9133,17 +9023,22 @@ const _sfc_main$5 = defineComponent({
9133
9023
  return __spreadValues(__spreadValues(__spreadValues({}, base), hasFinal ? { final: resolvedFinal } : {}), hasCustom ? { customHtmlTags: merged } : {});
9134
9024
  },
9135
9025
  parsedLegacyNodes() {
9136
- var _a2;
9026
+ var _a2, _b, _c;
9137
9027
  if (Array.isArray(this.nodes) && this.nodes.length > 0)
9138
9028
  return this.nodes;
9139
- if (!this.content)
9029
+ const content2 = this.legacyPacing ? this.legacyVisible : this.content;
9030
+ if (!content2)
9140
9031
  return [];
9141
9032
  const { key, tags } = resolveCustomHtmlTags((_a2 = this.mergedParseOptions) == null ? void 0 : _a2.customHtmlTags);
9142
9033
  const markdown = getMarkdown(key ? `${this.instanceMsgId}:${key}` : this.instanceMsgId, {
9143
9034
  customHtmlTags: tags
9144
9035
  });
9145
9036
  const md = this.customMarkdownIt ? this.customMarkdownIt(markdown) : markdown;
9146
- return parseMarkdownToStructure(this.content, md, this.mergedParseOptions);
9037
+ const options = (_b = this.mergedParseOptions) != null ? _b : {};
9038
+ return markRaw(parseMarkdownToStructure(content2, md, __spreadProps(__spreadValues({}, options), {
9039
+ streamParse: (_c = options.streamParse) != null ? _c : true,
9040
+ reuseStableTopLevelNodes: !this.customMarkdownIt && !options.preTransformTokens && !options.postTransformTokens && !options.postTransformNodes
9041
+ })));
9147
9042
  },
9148
9043
  forwardedProps() {
9149
9044
  return {
@@ -9170,6 +9065,8 @@ const _sfc_main$5 = defineComponent({
9170
9065
  indexKey: this.indexKey,
9171
9066
  typewriter: this.typewriter,
9172
9067
  fade: this.fade,
9068
+ smoothStreaming: this.smoothStreaming,
9069
+ smoothStreamingOptions: this.smoothStreamingOptions,
9173
9070
  batchRendering: this.batchRendering,
9174
9071
  initialRenderBatchSize: this.initialRenderBatchSize,
9175
9072
  renderBatchSize: this.renderBatchSize,
@@ -9182,6 +9079,53 @@ const _sfc_main$5 = defineComponent({
9182
9079
  };
9183
9080
  }
9184
9081
  },
9082
+ watch: {
9083
+ content: "syncLegacyStream",
9084
+ nodes: "syncLegacyStream",
9085
+ final: "syncLegacyStream",
9086
+ parseOptions: "syncLegacyStream",
9087
+ smoothStreaming: "syncLegacyStream"
9088
+ },
9089
+ created() {
9090
+ var _a2;
9091
+ if (!this.legacyVue26)
9092
+ return;
9093
+ const stream = createSmoothMarkdownStream(__spreadValues(__spreadValues({}, RENDERER_STREAM_DEFAULTS), this.smoothStreamingOptions));
9094
+ this.legacyStream = stream;
9095
+ stream.subscribe(() => {
9096
+ this.legacyVisible = stream.getSnapshot().visible;
9097
+ });
9098
+ this.legacyBridge = createRendererStreamBridge(stream, {
9099
+ flushOnFinish: (_a2 = this.smoothStreamingOptions) == null ? void 0 : _a2.flushOnFinish,
9100
+ commit: (work) => __async(this, null, function* () {
9101
+ work();
9102
+ yield this.$nextTick();
9103
+ }),
9104
+ measure: () => {
9105
+ var _a3;
9106
+ void ((_a3 = this.$el) == null ? void 0 : _a3.offsetHeight);
9107
+ },
9108
+ onReady: (ready) => {
9109
+ this.legacyReady = ready;
9110
+ }
9111
+ });
9112
+ this.syncLegacyStream();
9113
+ },
9114
+ beforeUnmount() {
9115
+ var _a2, _b;
9116
+ (_a2 = this.legacyBridge) == null ? void 0 : _a2.dispose();
9117
+ (_b = this.legacyStream) == null ? void 0 : _b.destroy();
9118
+ },
9119
+ methods: {
9120
+ syncLegacyStream() {
9121
+ var _a2, _b, _c, _d;
9122
+ if (!this.legacyBridge)
9123
+ return;
9124
+ const final = (_b = this.final) != null ? _b : (_a2 = this.parseOptions) == null ? void 0 : _a2.final;
9125
+ this.legacyTextScope.setFinal(final === true);
9126
+ this.legacyBridge.update((_c = this.content) != null ? _c : "", !!((_d = this.nodes) == null ? void 0 : _d.length), this.legacyPacing, final, this.fade !== false);
9127
+ }
9128
+ },
9185
9129
  render(h2) {
9186
9130
  const listeners = resolveVueListeners(this);
9187
9131
  if (this.legacyVue26) {