@ai-markdown/core 3.4.1 → 3.5.0
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/components/index.cjs +515 -30
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +369 -170
- package/dist/components/index.d.ts +369 -170
- package/dist/components/index.js +504 -32
- package/dist/components/index.js.map +1 -1
- package/package.json +4 -4
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,234 @@
|
|
|
1
|
-
import { StreamingLanguageDetector } from "@ai-markdown/code-language-detector";
|
|
1
|
+
import { StreamingLanguageDetector, normalizeHighlightJsLanguage, normalizeShikiLanguage } from "@ai-markdown/code-language-detector";
|
|
2
|
+
let CodeLanguageFormat = /* @__PURE__ */ function(CodeLanguageFormat) {
|
|
3
|
+
CodeLanguageFormat["HighlightJs"] = "highlight-js";
|
|
4
|
+
CodeLanguageFormat["Shiki"] = "shiki";
|
|
5
|
+
CodeLanguageFormat["Pierre"] = "pierre";
|
|
6
|
+
return CodeLanguageFormat;
|
|
7
|
+
}({});
|
|
8
|
+
function resolveCodeHighlightLanguage(language, format = "highlight-js") {
|
|
9
|
+
if (format === "pierre") {
|
|
10
|
+
const name = normalizeShikiLanguage(language);
|
|
11
|
+
return name === "common-lisp" ? "lisp" : name;
|
|
12
|
+
}
|
|
13
|
+
return typeof format === "function" ? format(language) : format === "shiki" ? normalizeShikiLanguage(language) : normalizeHighlightJsLanguage(language);
|
|
14
|
+
}
|
|
15
|
+
function resolveCodeHighlightInterval(value, fallback = 50) {
|
|
16
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
17
|
+
}
|
|
18
|
+
function createCodeHighlightSession(onChange) {
|
|
19
|
+
let committed = false;
|
|
20
|
+
let prepared;
|
|
21
|
+
let cached;
|
|
22
|
+
let fault;
|
|
23
|
+
let epoch = 0;
|
|
24
|
+
let backend;
|
|
25
|
+
const release = () => {
|
|
26
|
+
const previous = backend;
|
|
27
|
+
backend = void 0;
|
|
28
|
+
try {
|
|
29
|
+
previous?.value.dispose();
|
|
30
|
+
} catch {}
|
|
31
|
+
};
|
|
32
|
+
const sameInput = (a, b) => a?.adapter === b.adapter && a?.code === b.code && a?.language === b.language && a?.colorScheme === b.colorScheme && a?.generation === b.generation && a?.streaming === b.streaming;
|
|
33
|
+
const commitHighlight = (input, request) => {
|
|
34
|
+
const adapter = input.adapter;
|
|
35
|
+
if (!adapter.createSession || sameInput(cached?.input, input)) return;
|
|
36
|
+
let snapshot;
|
|
37
|
+
try {
|
|
38
|
+
backend ??= {
|
|
39
|
+
adapter,
|
|
40
|
+
language: request.language,
|
|
41
|
+
colorScheme: request.colorScheme,
|
|
42
|
+
generation: input.generation,
|
|
43
|
+
value: adapter.createSession()
|
|
44
|
+
};
|
|
45
|
+
const result = backend.value.highlight(request);
|
|
46
|
+
snapshot = {
|
|
47
|
+
language: request.language,
|
|
48
|
+
status: result ? "ready" : "plain",
|
|
49
|
+
result
|
|
50
|
+
};
|
|
51
|
+
} catch (error) {
|
|
52
|
+
release();
|
|
53
|
+
snapshot = {
|
|
54
|
+
language: request.language,
|
|
55
|
+
status: "error",
|
|
56
|
+
error
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
cached = {
|
|
60
|
+
input: { ...input },
|
|
61
|
+
snapshot
|
|
62
|
+
};
|
|
63
|
+
onChange();
|
|
64
|
+
};
|
|
65
|
+
const matches = (adapter, request) => prepared?.adapter === adapter && prepared.language === request.language && prepared.colorScheme === request.colorScheme;
|
|
66
|
+
const requestOf = (input) => ({
|
|
67
|
+
code: input.code,
|
|
68
|
+
language: input.adapter ? resolveCodeHighlightLanguage(input.language, input.adapter.languageFormat) : input.language,
|
|
69
|
+
colorScheme: input.colorScheme,
|
|
70
|
+
streaming: input.streaming
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
read(input) {
|
|
74
|
+
const adapter = input.adapter;
|
|
75
|
+
if (!adapter || input.active === false) return {
|
|
76
|
+
language: input.language,
|
|
77
|
+
status: "plain"
|
|
78
|
+
};
|
|
79
|
+
if (adapter.prepare && !committed) return {
|
|
80
|
+
language: input.language,
|
|
81
|
+
status: "loading"
|
|
82
|
+
};
|
|
83
|
+
if (fault && sameInput(fault.input, input)) return {
|
|
84
|
+
language: input.language,
|
|
85
|
+
status: "error",
|
|
86
|
+
error: fault.error
|
|
87
|
+
};
|
|
88
|
+
let request;
|
|
89
|
+
try {
|
|
90
|
+
request = requestOf(input);
|
|
91
|
+
if (adapter.supports?.(request.language) === false) return {
|
|
92
|
+
language: request.language,
|
|
93
|
+
status: "plain"
|
|
94
|
+
};
|
|
95
|
+
if (matches(adapter, request) && prepared?.failed) return {
|
|
96
|
+
language: request.language,
|
|
97
|
+
status: "error",
|
|
98
|
+
error: prepared.error
|
|
99
|
+
};
|
|
100
|
+
if (adapter.prepare && !adapter.isReady?.(request) && !(matches(adapter, request) && prepared?.ready)) return {
|
|
101
|
+
language: request.language,
|
|
102
|
+
status: "loading"
|
|
103
|
+
};
|
|
104
|
+
if (sameInput(cached?.input, input)) return cached.snapshot;
|
|
105
|
+
if (adapter.createSession) return {
|
|
106
|
+
language: request.language,
|
|
107
|
+
status: "loading"
|
|
108
|
+
};
|
|
109
|
+
const result = adapter.highlight(request);
|
|
110
|
+
const snapshot = {
|
|
111
|
+
language: request.language,
|
|
112
|
+
status: result ? "ready" : "plain",
|
|
113
|
+
result
|
|
114
|
+
};
|
|
115
|
+
cached = {
|
|
116
|
+
input: { ...input },
|
|
117
|
+
snapshot
|
|
118
|
+
};
|
|
119
|
+
return snapshot;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return {
|
|
122
|
+
language: input.language,
|
|
123
|
+
status: "error",
|
|
124
|
+
error
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
commit(input) {
|
|
129
|
+
const firstCommit = !committed;
|
|
130
|
+
committed = true;
|
|
131
|
+
if (input.adapter && input.active !== false && fault && sameInput(fault.input, input)) return;
|
|
132
|
+
fault = void 0;
|
|
133
|
+
const adapter = input.adapter;
|
|
134
|
+
if (!adapter || input.active === false) {
|
|
135
|
+
epoch++;
|
|
136
|
+
prepared = void 0;
|
|
137
|
+
cached = void 0;
|
|
138
|
+
release();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
let request;
|
|
142
|
+
try {
|
|
143
|
+
request = requestOf(input);
|
|
144
|
+
if (backend && (backend.adapter !== adapter || backend.language !== request.language || backend.colorScheme !== request.colorScheme || backend.generation !== input.generation)) {
|
|
145
|
+
release();
|
|
146
|
+
cached = void 0;
|
|
147
|
+
}
|
|
148
|
+
if (adapter.supports?.(request.language) === false) {
|
|
149
|
+
if (firstCommit && adapter.prepare) onChange();
|
|
150
|
+
epoch++;
|
|
151
|
+
prepared = void 0;
|
|
152
|
+
cached = void 0;
|
|
153
|
+
release();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (matches(adapter, request)) {
|
|
157
|
+
if (!prepared?.failed && (!adapter.prepare || adapter.isReady?.(request) || prepared?.ready)) commitHighlight(input, request);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const ticket = ++epoch;
|
|
161
|
+
prepared = {
|
|
162
|
+
adapter,
|
|
163
|
+
language: request.language,
|
|
164
|
+
colorScheme: request.colorScheme
|
|
165
|
+
};
|
|
166
|
+
if (!adapter.prepare || adapter.isReady?.(request)) {
|
|
167
|
+
if (firstCommit && adapter.prepare && !adapter.createSession) onChange();
|
|
168
|
+
commitHighlight(input, request);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
Promise.resolve().then(() => {
|
|
172
|
+
if (ticket !== epoch) return;
|
|
173
|
+
return adapter.prepare(request);
|
|
174
|
+
}).then(() => {
|
|
175
|
+
if (ticket !== epoch) return;
|
|
176
|
+
prepared.ready = true;
|
|
177
|
+
cached = void 0;
|
|
178
|
+
onChange();
|
|
179
|
+
}, (error) => {
|
|
180
|
+
if (ticket !== epoch) return;
|
|
181
|
+
prepared.failed = true;
|
|
182
|
+
prepared.error = error;
|
|
183
|
+
onChange();
|
|
184
|
+
});
|
|
185
|
+
} catch (error) {
|
|
186
|
+
epoch++;
|
|
187
|
+
release();
|
|
188
|
+
prepared = void 0;
|
|
189
|
+
cached = void 0;
|
|
190
|
+
fault = {
|
|
191
|
+
input: { ...input },
|
|
192
|
+
error
|
|
193
|
+
};
|
|
194
|
+
onChange();
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
retry() {
|
|
198
|
+
fault = void 0;
|
|
199
|
+
release();
|
|
200
|
+
epoch++;
|
|
201
|
+
prepared = void 0;
|
|
202
|
+
cached = void 0;
|
|
203
|
+
onChange();
|
|
204
|
+
},
|
|
205
|
+
dispose() {
|
|
206
|
+
committed = false;
|
|
207
|
+
fault = void 0;
|
|
208
|
+
release();
|
|
209
|
+
epoch++;
|
|
210
|
+
prepared = void 0;
|
|
211
|
+
cached = void 0;
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
const defaultCodeBlockPolicy = Object.freeze({
|
|
216
|
+
defaultExpanded: true,
|
|
217
|
+
autoDetectUnknownLanguage: true,
|
|
218
|
+
formatJson: false,
|
|
219
|
+
expandNestedJson: false,
|
|
220
|
+
highlightIntervalMs: 50
|
|
221
|
+
});
|
|
222
|
+
function resolveCodeBlockPolicy(overrides, inherited, defaults = defaultCodeBlockPolicy) {
|
|
223
|
+
const value = (key) => overrides?.[key] ?? inherited?.[key] ?? defaults[key] ?? defaultCodeBlockPolicy[key];
|
|
224
|
+
return {
|
|
225
|
+
defaultExpanded: value("defaultExpanded"),
|
|
226
|
+
autoDetectUnknownLanguage: value("autoDetectUnknownLanguage"),
|
|
227
|
+
formatJson: value("formatJson"),
|
|
228
|
+
expandNestedJson: value("expandNestedJson"),
|
|
229
|
+
highlightIntervalMs: resolveCodeHighlightInterval(value("highlightIntervalMs"), defaults.highlightIntervalMs ?? 50)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
2
232
|
function extractCode(node) {
|
|
3
233
|
if (node?.tagName !== "pre" || node.children.length !== 1 || Object.keys(node.properties).length) return null;
|
|
4
234
|
const child = node.children[0];
|
|
@@ -409,6 +639,25 @@ const ensureMermaidInitialized = (mermaid, isDark) => {
|
|
|
409
639
|
}
|
|
410
640
|
mermaid.initialize(next);
|
|
411
641
|
};
|
|
642
|
+
var UnsupportedDiagramError = class extends Error {
|
|
643
|
+
diagramType;
|
|
644
|
+
constructor(diagramType) {
|
|
645
|
+
super(`Unsupported diagram type: ${diagramType}`);
|
|
646
|
+
this.diagramType = diagramType;
|
|
647
|
+
this.name = "UnsupportedDiagramError";
|
|
648
|
+
}
|
|
649
|
+
};
|
|
650
|
+
const resolveDiagramInterval = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 300;
|
|
651
|
+
function createCachedDiagramLoader(load) {
|
|
652
|
+
let pending;
|
|
653
|
+
return () => pending ??= Promise.resolve().then(load).catch((error) => {
|
|
654
|
+
pending = void 0;
|
|
655
|
+
throw error;
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
function preloadDiagramEngine(load) {
|
|
659
|
+
return Promise.resolve().then(load).then(() => void 0);
|
|
660
|
+
}
|
|
412
661
|
function diagramErrorText(error, labels) {
|
|
413
662
|
if (error.reason === "tooLarge") return labels.tooLarge(error.length, error.limit);
|
|
414
663
|
return error.message || labels.renderFailed;
|
|
@@ -427,7 +676,7 @@ var DiagramFailure = class {
|
|
|
427
676
|
}
|
|
428
677
|
};
|
|
429
678
|
const diagramId = () => `mermaid-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
430
|
-
function createDiagramController(load, publish) {
|
|
679
|
+
function createDiagramController(load, publish, fallback) {
|
|
431
680
|
const owner = {};
|
|
432
681
|
let request;
|
|
433
682
|
let current;
|
|
@@ -443,6 +692,7 @@ function createDiagramController(load, publish) {
|
|
|
443
692
|
let nonce = 0;
|
|
444
693
|
let ran;
|
|
445
694
|
let epoch = 0;
|
|
695
|
+
let disposed = false;
|
|
446
696
|
let retryTimer;
|
|
447
697
|
const sameError = (a, b) => a.reason === "tooLarge" ? b.reason === "tooLarge" && a.length === b.length && a.limit === b.limit : b.reason === a.reason && a.message === b.message;
|
|
448
698
|
const emit = () => publish({
|
|
@@ -463,13 +713,10 @@ function createDiagramController(load, publish) {
|
|
|
463
713
|
};
|
|
464
714
|
const attempt = async (code, dark, streaming, generation) => {
|
|
465
715
|
const stale = () => generation !== epoch;
|
|
466
|
-
|
|
467
|
-
try {
|
|
468
|
-
engine = await load();
|
|
469
|
-
} catch {
|
|
716
|
+
const loadFailedAttempt = () => {
|
|
470
717
|
if (stale()) return;
|
|
471
718
|
if (loadFailures < LOAD_RETRIES) {
|
|
472
|
-
loadFailures
|
|
719
|
+
loadFailures++;
|
|
473
720
|
retryTimer = setTimeout(() => {
|
|
474
721
|
retryTimer = void 0;
|
|
475
722
|
nonce++;
|
|
@@ -479,42 +726,95 @@ function createDiagramController(load, publish) {
|
|
|
479
726
|
loadFailed = true;
|
|
480
727
|
emit();
|
|
481
728
|
}
|
|
729
|
+
};
|
|
730
|
+
let engine;
|
|
731
|
+
try {
|
|
732
|
+
engine = await load();
|
|
733
|
+
} catch {
|
|
734
|
+
loadFailedAttempt();
|
|
482
735
|
return;
|
|
483
736
|
}
|
|
484
|
-
loadFailures = 0;
|
|
485
737
|
let reason = "render";
|
|
486
738
|
try {
|
|
487
739
|
if (stale()) return;
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
kind
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
740
|
+
const render = async (target) => {
|
|
741
|
+
if (target.kind !== "svg") ensureMermaidInitialized(target, dark);
|
|
742
|
+
const maxTextSize = target.kind === "svg" ? target.maxTextSize ?? 5e4 : getMermaidMaxTextSize(target);
|
|
743
|
+
if (code.length > maxTextSize) throw new DiagramFailure({
|
|
744
|
+
kind: "error",
|
|
745
|
+
reason: "tooLarge",
|
|
746
|
+
length: code.length,
|
|
747
|
+
limit: maxTextSize
|
|
748
|
+
});
|
|
749
|
+
reason = "parse";
|
|
750
|
+
if (target.kind !== "svg" && !await target.parse(code)) throw new DiagramFailure({
|
|
751
|
+
kind: "error",
|
|
752
|
+
reason: "parse",
|
|
753
|
+
message: ""
|
|
754
|
+
});
|
|
755
|
+
reason = "render";
|
|
756
|
+
if (stale()) return void 0;
|
|
757
|
+
return target.kind === "svg" ? target.render(diagramId(), code, dark) : target.render(diagramId(), code);
|
|
758
|
+
};
|
|
759
|
+
let result;
|
|
760
|
+
try {
|
|
761
|
+
result = await render(engine);
|
|
762
|
+
} catch (error) {
|
|
763
|
+
if (!(error instanceof UnsupportedDiagramError) || !fallback || stale()) throw error;
|
|
764
|
+
try {
|
|
765
|
+
engine = await fallback();
|
|
766
|
+
} catch {
|
|
767
|
+
loadFailedAttempt();
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
if (stale()) return;
|
|
771
|
+
result = await render(engine);
|
|
772
|
+
}
|
|
773
|
+
if (!result) return;
|
|
774
|
+
const { svg, bindFunctions, diagramType } = result;
|
|
505
775
|
if (stale()) return;
|
|
776
|
+
loadFailures = 0;
|
|
777
|
+
const previousView = view.kind === "diagram" ? {
|
|
778
|
+
...view,
|
|
779
|
+
onBindError: void 0
|
|
780
|
+
} : view;
|
|
781
|
+
if (previousView.kind === "diagram") previousView.onBindError = (error) => {
|
|
782
|
+
if (disposed || view !== previousView) return;
|
|
783
|
+
lastSuccess = void 0;
|
|
784
|
+
show({
|
|
785
|
+
kind: "error",
|
|
786
|
+
reason: "render",
|
|
787
|
+
message: engineMessage(error)
|
|
788
|
+
});
|
|
789
|
+
};
|
|
790
|
+
const corrective = needsCorrective;
|
|
506
791
|
needsCorrective = false;
|
|
507
792
|
lastSuccess = {
|
|
508
793
|
code,
|
|
509
794
|
dark
|
|
510
795
|
};
|
|
511
796
|
loadFailed = false;
|
|
512
|
-
|
|
797
|
+
const nextView = {
|
|
513
798
|
kind: "diagram",
|
|
514
799
|
svg,
|
|
515
800
|
chartType: diagramType ?? "",
|
|
516
|
-
bind: bindFunctions
|
|
517
|
-
|
|
801
|
+
bind: bindFunctions,
|
|
802
|
+
...engine.kind === "svg" ? {
|
|
803
|
+
palette: engine.palette,
|
|
804
|
+
dark
|
|
805
|
+
} : {},
|
|
806
|
+
onBindError(error) {
|
|
807
|
+
if (disposed || view !== nextView) return;
|
|
808
|
+
lastSuccess = void 0;
|
|
809
|
+
if (streaming || !corrective && previousView.kind === "diagram") show(previousView);
|
|
810
|
+
else show({
|
|
811
|
+
kind: "error",
|
|
812
|
+
reason: "render",
|
|
813
|
+
message: engineMessage(error)
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
};
|
|
817
|
+
show(nextView);
|
|
518
818
|
} catch (error) {
|
|
519
819
|
if (stale()) return;
|
|
520
820
|
if (streaming) return;
|
|
@@ -556,7 +856,17 @@ function createDiagramController(load, publish) {
|
|
|
556
856
|
}
|
|
557
857
|
} else if (!streaming && previousStreaming) needsCorrective = true;
|
|
558
858
|
previousStreaming = streaming;
|
|
559
|
-
if (!code
|
|
859
|
+
if (!code) {
|
|
860
|
+
lastSuccess = void 0;
|
|
861
|
+
needsCorrective = false;
|
|
862
|
+
if (view.kind !== "source" || loadFailed) {
|
|
863
|
+
view = { kind: "source" };
|
|
864
|
+
loadFailed = false;
|
|
865
|
+
emit();
|
|
866
|
+
}
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
if (!active) return;
|
|
560
870
|
if (lastSuccess?.code === code && lastSuccess.dark === dark) {
|
|
561
871
|
needsCorrective = false;
|
|
562
872
|
return;
|
|
@@ -566,7 +876,11 @@ function createDiagramController(load, publish) {
|
|
|
566
876
|
}
|
|
567
877
|
return {
|
|
568
878
|
update(next) {
|
|
569
|
-
|
|
879
|
+
disposed = false;
|
|
880
|
+
request = {
|
|
881
|
+
...next,
|
|
882
|
+
interval: resolveDiagramInterval(next.interval)
|
|
883
|
+
};
|
|
570
884
|
updating = true;
|
|
571
885
|
try {
|
|
572
886
|
if (!frames || !current) {
|
|
@@ -576,22 +890,25 @@ function createDiagramController(load, publish) {
|
|
|
576
890
|
if (!updating) run();
|
|
577
891
|
});
|
|
578
892
|
} else current = nextCodeFrame(current, next.code, "");
|
|
579
|
-
frames.update(current, next.streaming,
|
|
893
|
+
frames.update(current, next.streaming, request.interval);
|
|
580
894
|
} finally {
|
|
581
895
|
updating = false;
|
|
582
896
|
}
|
|
583
897
|
run();
|
|
584
898
|
},
|
|
585
899
|
retry() {
|
|
900
|
+
if (disposed) return;
|
|
586
901
|
loadFailures = 0;
|
|
587
902
|
if (loadFailed) {
|
|
588
903
|
loadFailed = false;
|
|
589
904
|
emit();
|
|
590
905
|
}
|
|
906
|
+
lastSuccess = void 0;
|
|
591
907
|
nonce++;
|
|
592
908
|
run();
|
|
593
909
|
},
|
|
594
910
|
dispose() {
|
|
911
|
+
disposed = true;
|
|
595
912
|
cancel();
|
|
596
913
|
frames?.dispose();
|
|
597
914
|
ran = void 0;
|
|
@@ -1215,6 +1532,161 @@ const imageActionNames = Object.freeze([
|
|
|
1215
1532
|
"flipX",
|
|
1216
1533
|
"flipY"
|
|
1217
1534
|
]);
|
|
1218
|
-
|
|
1535
|
+
function createSvgLoader(load, palette, options) {
|
|
1536
|
+
const renderOptions = { ...options?.renderOptions };
|
|
1537
|
+
const limit = renderOptions.limit ?? 5e4;
|
|
1538
|
+
if (!Number.isFinite(limit) || limit < 0) throw new RangeError("Diagram limit must be a finite non-negative number");
|
|
1539
|
+
return createCachedDiagramLoader(async () => {
|
|
1540
|
+
const renderer = await load();
|
|
1541
|
+
return {
|
|
1542
|
+
kind: "svg",
|
|
1543
|
+
palette,
|
|
1544
|
+
maxTextSize: limit,
|
|
1545
|
+
async render(id, code) {
|
|
1546
|
+
try {
|
|
1547
|
+
const result = await renderer.render(code, {
|
|
1548
|
+
...renderOptions,
|
|
1549
|
+
idPrefix: id,
|
|
1550
|
+
limit
|
|
1551
|
+
});
|
|
1552
|
+
return {
|
|
1553
|
+
svg: result.svg,
|
|
1554
|
+
diagramType: result.type
|
|
1555
|
+
};
|
|
1556
|
+
} catch (error) {
|
|
1557
|
+
const diagnostic = error;
|
|
1558
|
+
if (diagnostic?.code === "unsupported-diagram" && typeof diagnostic.type === "string" && diagnostic.type) throw new UnsupportedDiagramError(diagnostic.type);
|
|
1559
|
+
throw error;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
};
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
function createPeleLoader(load, options) {
|
|
1566
|
+
return createSvgLoader(load, "pele", options);
|
|
1567
|
+
}
|
|
1568
|
+
function createOndineLoader(load, options) {
|
|
1569
|
+
return createSvgLoader(load, "ondine", options);
|
|
1570
|
+
}
|
|
1571
|
+
function convert(token, foreground) {
|
|
1572
|
+
return {
|
|
1573
|
+
text: token.content,
|
|
1574
|
+
color: token.color ?? foreground,
|
|
1575
|
+
backgroundColor: token.bgColor,
|
|
1576
|
+
fontStyle: token.fontStyle
|
|
1577
|
+
};
|
|
1578
|
+
}
|
|
1579
|
+
function createPierreHighlightAdapter(options) {
|
|
1580
|
+
let runtime;
|
|
1581
|
+
let pending;
|
|
1582
|
+
const adapter = {
|
|
1583
|
+
languageFormat: "pierre",
|
|
1584
|
+
supports: (language) => ![
|
|
1585
|
+
"",
|
|
1586
|
+
"plain",
|
|
1587
|
+
"plaintext",
|
|
1588
|
+
"text",
|
|
1589
|
+
"txt"
|
|
1590
|
+
].includes(language) && (!runtime || runtime.isSupportedLanguage(language)),
|
|
1591
|
+
isReady: () => Boolean(runtime),
|
|
1592
|
+
prepare: () => {
|
|
1593
|
+
if (runtime) return;
|
|
1594
|
+
return pending ??= Promise.resolve().then(options.load).then((loaded) => {
|
|
1595
|
+
runtime = loaded;
|
|
1596
|
+
}).finally(() => {
|
|
1597
|
+
pending = void 0;
|
|
1598
|
+
});
|
|
1599
|
+
},
|
|
1600
|
+
highlight: ({ code, language, colorScheme }) => {
|
|
1601
|
+
if (!runtime?.isSupportedLanguage(language)) return;
|
|
1602
|
+
const result = runtime.codeToTokens(code, {
|
|
1603
|
+
lang: language,
|
|
1604
|
+
theme: runtime.themes[colorScheme]
|
|
1605
|
+
});
|
|
1606
|
+
const tokens = [];
|
|
1607
|
+
let cursor = 0;
|
|
1608
|
+
for (const line of result.tokens) for (const token of line) {
|
|
1609
|
+
if (token.offset > cursor) tokens.push({
|
|
1610
|
+
text: code.slice(cursor, token.offset),
|
|
1611
|
+
color: result.fg
|
|
1612
|
+
});
|
|
1613
|
+
tokens.push(convert(token, result.fg));
|
|
1614
|
+
cursor = token.offset + token.content.length;
|
|
1615
|
+
}
|
|
1616
|
+
if (cursor < code.length) tokens.push({
|
|
1617
|
+
text: code.slice(cursor),
|
|
1618
|
+
color: result.fg
|
|
1619
|
+
});
|
|
1620
|
+
return { tokens };
|
|
1621
|
+
}
|
|
1622
|
+
};
|
|
1623
|
+
if (options.incremental !== false) adapter.createSession = () => {
|
|
1624
|
+
let live;
|
|
1625
|
+
let previous = "", previousLanguage = "", previousScheme = "";
|
|
1626
|
+
let lines = [];
|
|
1627
|
+
const dispose = () => {
|
|
1628
|
+
live?.dispose();
|
|
1629
|
+
live = void 0;
|
|
1630
|
+
lines = [];
|
|
1631
|
+
previous = "";
|
|
1632
|
+
};
|
|
1633
|
+
return {
|
|
1634
|
+
dispose,
|
|
1635
|
+
highlight(request) {
|
|
1636
|
+
const { code, language, colorScheme } = request;
|
|
1637
|
+
if (!runtime?.isSupportedLanguage(language)) return;
|
|
1638
|
+
if (!request.streaming || !runtime.LiveTokenizer) {
|
|
1639
|
+
dispose();
|
|
1640
|
+
return adapter.highlight(request);
|
|
1641
|
+
}
|
|
1642
|
+
const appended = startsWithText(code, previous);
|
|
1643
|
+
const terminatorLength = previous.endsWith("\r\n") ? 2 : previous.endsWith("\n") ? 1 : 0;
|
|
1644
|
+
const suffixStart = previous.length - terminatorLength;
|
|
1645
|
+
const replacesTerminator = !appended && terminatorLength > 0 && startsWithText(code, previous.slice(0, suffixStart));
|
|
1646
|
+
if (!live || language !== previousLanguage || colorScheme !== previousScheme || !appended && !replacesTerminator) {
|
|
1647
|
+
dispose();
|
|
1648
|
+
live = new runtime.LiveTokenizer({
|
|
1649
|
+
code,
|
|
1650
|
+
lang: language,
|
|
1651
|
+
theme: runtime.themes[colorScheme]
|
|
1652
|
+
});
|
|
1653
|
+
lines = Array.from({ length: live.lineCount }, (_, line) => live.getLineTokens(line).tokens.map((token) => convert(token)));
|
|
1654
|
+
} else if (code !== previous) {
|
|
1655
|
+
const line = live.lineCount - 1;
|
|
1656
|
+
const end = {
|
|
1657
|
+
line,
|
|
1658
|
+
character: live.getLineLength(line)
|
|
1659
|
+
};
|
|
1660
|
+
const start = replacesTerminator ? {
|
|
1661
|
+
line: line - 1,
|
|
1662
|
+
character: live.getLineLength(line - 1)
|
|
1663
|
+
} : end;
|
|
1664
|
+
const update = live.applyEdits([{
|
|
1665
|
+
range: {
|
|
1666
|
+
start,
|
|
1667
|
+
end
|
|
1668
|
+
},
|
|
1669
|
+
newText: code.slice(replacesTerminator ? suffixStart : previous.length)
|
|
1670
|
+
}]);
|
|
1671
|
+
for (const change of [...update.lineChanges].reverse()) {
|
|
1672
|
+
const replacement = Array.from({ length: change.newEndLine - change.newStartLine }, (_, index) => live.getLineTokens(change.newStartLine + index).tokens.map((token) => convert(token)));
|
|
1673
|
+
lines = [
|
|
1674
|
+
...lines.slice(0, change.oldStartLine),
|
|
1675
|
+
...replacement,
|
|
1676
|
+
...lines.slice(change.oldEndLine)
|
|
1677
|
+
];
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
previous = code;
|
|
1681
|
+
previousLanguage = language;
|
|
1682
|
+
previousScheme = colorScheme;
|
|
1683
|
+
const breaks = code.match(/\r\n|\r|\n/g) ?? [];
|
|
1684
|
+
return { tokens: lines.flatMap((line, index) => index < breaks.length ? [...line, { text: breaks[index] }] : line) };
|
|
1685
|
+
}
|
|
1686
|
+
};
|
|
1687
|
+
};
|
|
1688
|
+
return adapter;
|
|
1689
|
+
}
|
|
1690
|
+
export { CodeLanguageFormat, UnsupportedDiagramError, createCachedDiagramLoader, createCodeBlockSession, createCodeFrame, createCodeHighlightSession, createCodeLanguageTracker, createDiagramController, createImagePreviewController, createJsonCompletenessScanner, createOndineLoader, createPeleLoader, createPierreHighlightAdapter, defaultCodeBlockLabels, defaultCodeBlockPolicy, defaultDiagramLabels, defaultImageLabels, defaultTableLabels, diagramErrorText, ensureMermaidInitialized, extendsCode, extractCode, getImageGallery, getMermaidMaxTextSize, imageActionNames, imageIconPaths, imagePinchCenter, imageTransformStyle, imageWheelRatio, initialImageTransform, jsonLooksComplete, lockImagePreviewScroll, mermaidRenderQueue, nextCodeFrame, normalizeRenderers, preloadDiagramEngine, prettyPrintJson, projectTable, reboundImage, resolveCodeBlockPolicy, resolveCodeHighlightInterval, resolveCodeHighlightLanguage, resolveDiagramInterval, resolveLabels, serializeTable, zoomImage };
|
|
1219
1691
|
|
|
1220
1692
|
//# sourceMappingURL=index.js.map
|