@arborium/arborium 2.13.0 → 2.14.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/arborium.d.ts +1 -1
- package/dist/arborium.iife.js +2 -2
- package/dist/arborium.iife.js.map +1 -1
- package/dist/arborium.js +96 -94
- package/dist/arborium.js.map +1 -1
- package/dist/arborium_host.d.ts +94 -0
- package/dist/arborium_host.js +300 -295
- package/dist/arborium_host_bg.wasm +0 -0
- package/dist/plugins-manifest.d.ts +1 -1
- package/dist/types.d.ts +10 -4
- package/package.json +9 -2
package/dist/arborium.js
CHANGED
|
@@ -11,7 +11,7 @@ const _ = [
|
|
|
11
11
|
[/^#!.*\bsh\b/, "bash"],
|
|
12
12
|
[/^#!.*\blua\b/, "lua"],
|
|
13
13
|
[/^#!.*\bawk\b/, "awk"]
|
|
14
|
-
],
|
|
14
|
+
], $ = [
|
|
15
15
|
// Rust - distinctive keywords
|
|
16
16
|
[/\b(fn|impl|trait|pub\s+fn|let\s+mut|&mut|->)\b/, "rust"],
|
|
17
17
|
// Go - distinctive keywords
|
|
@@ -71,23 +71,23 @@ const _ = [
|
|
|
71
71
|
// Zig
|
|
72
72
|
[/\b(pub\s+fn|const\s+\w+\s*=|@import\(|comptime)\b/, "zig"]
|
|
73
73
|
];
|
|
74
|
-
function
|
|
74
|
+
function M(e) {
|
|
75
75
|
const t = e.split(`
|
|
76
76
|
`)[0];
|
|
77
|
-
for (const [r,
|
|
77
|
+
for (const [r, s] of _)
|
|
78
78
|
if (r.test(t))
|
|
79
|
-
return
|
|
80
|
-
for (const [r,
|
|
79
|
+
return s;
|
|
80
|
+
for (const [r, s] of $)
|
|
81
81
|
if (r.test(e))
|
|
82
|
-
return
|
|
82
|
+
return s;
|
|
83
83
|
return null;
|
|
84
84
|
}
|
|
85
|
-
function
|
|
85
|
+
function R(e) {
|
|
86
86
|
const t = e.match(/\blanguage-(\w+)\b/);
|
|
87
87
|
if (t) return t[1];
|
|
88
88
|
const r = e.match(/\blang-(\w+)\b/);
|
|
89
89
|
if (r) return r[1];
|
|
90
|
-
const
|
|
90
|
+
const s = /* @__PURE__ */ new Set([
|
|
91
91
|
"rust",
|
|
92
92
|
"javascript",
|
|
93
93
|
"typescript",
|
|
@@ -124,7 +124,7 @@ function H(e) {
|
|
|
124
124
|
"sh"
|
|
125
125
|
]);
|
|
126
126
|
for (const a of e.split(/\s+/))
|
|
127
|
-
if (
|
|
127
|
+
if (s.has(a.toLowerCase()))
|
|
128
128
|
return a.toLowerCase();
|
|
129
129
|
return null;
|
|
130
130
|
}
|
|
@@ -152,7 +152,7 @@ function F(e) {
|
|
|
152
152
|
}, r = e.toLowerCase();
|
|
153
153
|
return t[r] || r;
|
|
154
154
|
}
|
|
155
|
-
const
|
|
155
|
+
const L = "2.14.0", U = [
|
|
156
156
|
"ada",
|
|
157
157
|
"agda",
|
|
158
158
|
"asciidoc",
|
|
@@ -255,7 +255,7 @@ const $ = "2.13.0", U = [
|
|
|
255
255
|
"yuri",
|
|
256
256
|
"zig",
|
|
257
257
|
"zsh"
|
|
258
|
-
],
|
|
258
|
+
], J = [
|
|
259
259
|
{
|
|
260
260
|
name: "attribute",
|
|
261
261
|
tag: "at"
|
|
@@ -592,28 +592,33 @@ const $ = "2.13.0", U = [
|
|
|
592
592
|
function P(e) {
|
|
593
593
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
594
594
|
}
|
|
595
|
-
const
|
|
595
|
+
const j = {
|
|
596
596
|
manual: !1,
|
|
597
597
|
theme: "one-dark",
|
|
598
598
|
selector: "pre code",
|
|
599
599
|
cdn: "jsdelivr",
|
|
600
|
-
version:
|
|
600
|
+
version: L,
|
|
601
601
|
// Precise version from manifest
|
|
602
602
|
pluginsUrl: "",
|
|
603
603
|
// Empty means use bundled manifest
|
|
604
604
|
hostUrl: "",
|
|
605
605
|
// Empty means use CDN based on version
|
|
606
606
|
logger: console,
|
|
607
|
+
resolveHostJs: ({ baseUrl: e, path: t }) => import(
|
|
608
|
+
/* @vite-ignore */
|
|
609
|
+
`${e}/${t}`
|
|
610
|
+
),
|
|
611
|
+
resolveHostWasm: ({ baseUrl: e, path: t }) => fetch(`${e}/${t}`),
|
|
607
612
|
resolveJs: ({ baseUrl: e, path: t }) => import(
|
|
608
613
|
/* @vite-ignore */
|
|
609
614
|
`${e}/${t}`
|
|
610
615
|
),
|
|
611
616
|
resolveWasm: ({ baseUrl: e, path: t }) => fetch(`${e}/${t}`)
|
|
612
617
|
};
|
|
613
|
-
let m = null, d = null, f = { ...
|
|
618
|
+
let m = null, d = null, f = { ...j };
|
|
614
619
|
const h = /* @__PURE__ */ new Map(), k = /* @__PURE__ */ new Map(), p = new Set(U);
|
|
615
620
|
let c = null, b = null;
|
|
616
|
-
async function
|
|
621
|
+
async function T(e) {
|
|
617
622
|
if (e.pluginsUrl)
|
|
618
623
|
return b || (b = (async () => {
|
|
619
624
|
e.logger.debug(`[arborium] Loading local plugins manifest from: ${e.pluginsUrl}`);
|
|
@@ -625,22 +630,22 @@ async function j(e) {
|
|
|
625
630
|
}
|
|
626
631
|
function E(e, t) {
|
|
627
632
|
if (c) {
|
|
628
|
-
const
|
|
629
|
-
if (
|
|
630
|
-
return
|
|
633
|
+
const n = c.entries.find((l) => l.language === e);
|
|
634
|
+
if (n)
|
|
635
|
+
return n.local_js.substring(0, n.local_js.lastIndexOf("/"));
|
|
631
636
|
}
|
|
632
|
-
const r = t.cdn,
|
|
637
|
+
const r = t.cdn, s = t.version;
|
|
633
638
|
let a;
|
|
634
|
-
return r === "jsdelivr" ? a = "https://cdn.jsdelivr.net/npm" : r === "unpkg" ? a = "https://unpkg.com" : a = r, `${a}/@arborium/${e}@${
|
|
639
|
+
return r === "jsdelivr" ? a = "https://cdn.jsdelivr.net/npm" : r === "unpkg" ? a = "https://unpkg.com" : a = r, `${a}/@arborium/${e}@${s}`;
|
|
635
640
|
}
|
|
636
641
|
async function x(e, t) {
|
|
637
642
|
const r = h.get(e);
|
|
638
643
|
if (r)
|
|
639
644
|
return t.logger.debug(`[arborium] Grammar '${e}' found in cache`), r;
|
|
640
|
-
const
|
|
641
|
-
if (
|
|
642
|
-
return t.logger.debug(`[arborium] Grammar '${e}' already loading, waiting...`),
|
|
643
|
-
const a =
|
|
645
|
+
const s = k.get(e);
|
|
646
|
+
if (s)
|
|
647
|
+
return t.logger.debug(`[arborium] Grammar '${e}' already loading, waiting...`), s;
|
|
648
|
+
const a = H(e, t);
|
|
644
649
|
k.set(e, a);
|
|
645
650
|
try {
|
|
646
651
|
return await a;
|
|
@@ -648,18 +653,18 @@ async function x(e, t) {
|
|
|
648
653
|
k.delete(e);
|
|
649
654
|
}
|
|
650
655
|
}
|
|
651
|
-
async function
|
|
652
|
-
if (await
|
|
656
|
+
async function H(e, t) {
|
|
657
|
+
if (await T(t), !p.has(e) && !c?.entries.some((r) => r.language === e))
|
|
653
658
|
return t.logger.debug(`[arborium] Grammar '${e}' not available`), null;
|
|
654
659
|
try {
|
|
655
|
-
const r = E(e, t),
|
|
656
|
-
t.logger.debug(`[arborium] Loading grammar '${e}'${
|
|
660
|
+
const r = E(e, t), s = t.resolveJs === j.resolveJs ? ` from ${r}/grammar.js` : "";
|
|
661
|
+
t.logger.debug(`[arborium] Loading grammar '${e}'${s}`);
|
|
657
662
|
const a = await t.resolveJs({
|
|
658
663
|
language: e,
|
|
659
664
|
baseUrl: r,
|
|
660
665
|
path: "grammar.js"
|
|
661
|
-
}),
|
|
662
|
-
await a.default({ module_or_path:
|
|
666
|
+
}), n = await t.resolveWasm({ language: e, baseUrl: r, path: "grammar_bg.wasm" });
|
|
667
|
+
await a.default({ module_or_path: n });
|
|
663
668
|
const l = a.language_id();
|
|
664
669
|
l !== e && t.logger.warn(`[arborium] Language ID mismatch: expected '${e}', got '${l}'`);
|
|
665
670
|
const w = a.injection_languages(), y = {
|
|
@@ -705,8 +710,8 @@ async function I(e, t) {
|
|
|
705
710
|
}
|
|
706
711
|
}
|
|
707
712
|
const v = /* @__PURE__ */ new Map();
|
|
708
|
-
let
|
|
709
|
-
function
|
|
713
|
+
let I = 1;
|
|
714
|
+
function q(e) {
|
|
710
715
|
globalThis.arboriumHost = {
|
|
711
716
|
/** Check if a language is available (sync) */
|
|
712
717
|
isLanguageAvailable(t) {
|
|
@@ -716,74 +721,71 @@ function C(e) {
|
|
|
716
721
|
async loadGrammar(t) {
|
|
717
722
|
const r = await x(t, e);
|
|
718
723
|
if (!r) return 0;
|
|
719
|
-
for (const [a,
|
|
720
|
-
if (
|
|
721
|
-
const
|
|
722
|
-
return v.set(
|
|
724
|
+
for (const [a, n] of v)
|
|
725
|
+
if (n === r) return a;
|
|
726
|
+
const s = I++;
|
|
727
|
+
return v.set(s, r), s;
|
|
723
728
|
},
|
|
724
729
|
/** Parse text using a grammar handle (sync) - returns UTF-8 offsets for Rust host */
|
|
725
730
|
parse(t, r) {
|
|
726
|
-
const
|
|
727
|
-
return
|
|
731
|
+
const s = v.get(t);
|
|
732
|
+
return s ? s.parseUtf8(r) : { spans: [], injections: [] };
|
|
728
733
|
}
|
|
729
734
|
};
|
|
730
735
|
}
|
|
731
|
-
function
|
|
736
|
+
function C(e) {
|
|
732
737
|
if (e.hostUrl)
|
|
733
738
|
return e.hostUrl;
|
|
734
739
|
const t = e.cdn, r = e.version;
|
|
735
|
-
let
|
|
736
|
-
t === "jsdelivr" ?
|
|
740
|
+
let s;
|
|
741
|
+
t === "jsdelivr" ? s = "https://cdn.jsdelivr.net/npm" : t === "unpkg" ? s = "https://unpkg.com" : s = t;
|
|
737
742
|
const a = r === "latest" ? "" : `@${r}`;
|
|
738
|
-
return `${
|
|
743
|
+
return `${s}/@arborium/arborium${a}/dist`;
|
|
739
744
|
}
|
|
740
|
-
async function
|
|
745
|
+
async function G(e) {
|
|
741
746
|
return m || d || (d = (async () => {
|
|
742
|
-
|
|
743
|
-
const t =
|
|
744
|
-
e.logger.debug(`[arborium] Loading host
|
|
747
|
+
q(e);
|
|
748
|
+
const t = C(e), r = e.resolveHostJs === j.resolveHostJs ? ` from ${t}/arborium_host.js` : "";
|
|
749
|
+
e.logger.debug(`[arborium] Loading host${r}`);
|
|
745
750
|
try {
|
|
746
|
-
const a = await
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
return await a.default(n), m = {
|
|
751
|
-
highlight: a.highlight,
|
|
752
|
-
isLanguageAvailable: a.isLanguageAvailable
|
|
751
|
+
const s = await e.resolveHostJs({ baseUrl: t, path: "arborium_host.js" }), a = await e.resolveHostWasm({ baseUrl: t, path: "arborium_host_bg.wasm" });
|
|
752
|
+
return await s.default({ module_or_path: a }), m = {
|
|
753
|
+
highlight: s.highlight,
|
|
754
|
+
isLanguageAvailable: s.isLanguageAvailable
|
|
753
755
|
}, e.logger.debug("[arborium] Host loaded successfully"), m;
|
|
754
|
-
} catch (
|
|
755
|
-
return e.logger.error("[arborium] Failed to load host:",
|
|
756
|
+
} catch (s) {
|
|
757
|
+
return e.logger.error("[arborium] Failed to load host:", s), null;
|
|
756
758
|
}
|
|
757
759
|
})(), d);
|
|
758
760
|
}
|
|
759
|
-
async function
|
|
760
|
-
const
|
|
761
|
+
async function S(e, t, r) {
|
|
762
|
+
const s = u(r), a = await G(s);
|
|
761
763
|
if (a)
|
|
762
764
|
try {
|
|
763
765
|
return a.highlight(e, t);
|
|
764
|
-
} catch (
|
|
765
|
-
|
|
766
|
+
} catch (n) {
|
|
767
|
+
s.logger.error("[arborium] Host highlight failed:", n);
|
|
766
768
|
}
|
|
767
769
|
return P(t);
|
|
768
770
|
}
|
|
769
|
-
async function
|
|
770
|
-
const r = u(t),
|
|
771
|
-
if (!
|
|
772
|
-
const { module: a } =
|
|
771
|
+
async function A(e, t) {
|
|
772
|
+
const r = u(t), s = await x(e, r);
|
|
773
|
+
if (!s) return null;
|
|
774
|
+
const { module: a } = s;
|
|
773
775
|
return {
|
|
774
|
-
languageId: () =>
|
|
775
|
-
injectionLanguages: () =>
|
|
776
|
-
highlight: async (
|
|
776
|
+
languageId: () => s.languageId,
|
|
777
|
+
injectionLanguages: () => s.injectionLanguages,
|
|
778
|
+
highlight: async (n) => S(e, n, t),
|
|
777
779
|
// Public API returns UTF-16 offsets for JavaScript compatibility
|
|
778
|
-
parse: (
|
|
780
|
+
parse: (n) => s.parseUtf16(n),
|
|
779
781
|
createSession: () => {
|
|
780
|
-
const
|
|
782
|
+
const n = a.create_session();
|
|
781
783
|
return {
|
|
782
|
-
setText: (l) => a.set_text(
|
|
784
|
+
setText: (l) => a.set_text(n, l),
|
|
783
785
|
// Session.parse() returns UTF-16 offsets for JavaScript compatibility
|
|
784
786
|
parse: () => {
|
|
785
787
|
try {
|
|
786
|
-
const l = a.parse_utf16(
|
|
788
|
+
const l = a.parse_utf16(n);
|
|
787
789
|
return {
|
|
788
790
|
spans: l.spans || [],
|
|
789
791
|
injections: l.injections || []
|
|
@@ -792,19 +794,19 @@ async function M(e, t) {
|
|
|
792
794
|
return r.logger.error("[arborium] Session parse error:", l), { spans: [], injections: [] };
|
|
793
795
|
}
|
|
794
796
|
},
|
|
795
|
-
cancel: () => a.cancel(
|
|
796
|
-
free: () => a.free_session(
|
|
797
|
+
cancel: () => a.cancel(n),
|
|
798
|
+
free: () => a.free_session(n)
|
|
797
799
|
};
|
|
798
800
|
},
|
|
799
801
|
dispose: () => {
|
|
800
802
|
}
|
|
801
803
|
};
|
|
802
804
|
}
|
|
803
|
-
async function
|
|
804
|
-
const
|
|
805
|
+
async function z(e, t, r) {
|
|
806
|
+
const s = u(r), a = e;
|
|
805
807
|
await a.default({ module_or_path: t });
|
|
806
|
-
const
|
|
807
|
-
languageId:
|
|
808
|
+
const n = a.language_id(), l = a.injection_languages(), w = {
|
|
809
|
+
languageId: n,
|
|
808
810
|
injectionLanguages: l,
|
|
809
811
|
module: a,
|
|
810
812
|
parseUtf8: (g) => {
|
|
@@ -817,7 +819,7 @@ async function N(e, t, r) {
|
|
|
817
819
|
injections: o.injections || []
|
|
818
820
|
};
|
|
819
821
|
} catch (o) {
|
|
820
|
-
return
|
|
822
|
+
return s.logger.error("[arborium] Parse error:", o), { spans: [], injections: [] };
|
|
821
823
|
} finally {
|
|
822
824
|
a.free_session(i);
|
|
823
825
|
}
|
|
@@ -832,41 +834,41 @@ async function N(e, t, r) {
|
|
|
832
834
|
injections: o.injections || []
|
|
833
835
|
};
|
|
834
836
|
} catch (o) {
|
|
835
|
-
return
|
|
837
|
+
return s.logger.error("[arborium] Parse error:", o), { spans: [], injections: [] };
|
|
836
838
|
} finally {
|
|
837
839
|
a.free_session(i);
|
|
838
840
|
}
|
|
839
841
|
}
|
|
840
842
|
};
|
|
841
|
-
return h.set(
|
|
843
|
+
return h.set(n, w), p.add(n), s.logger.debug(`[arborium] Grammar '${n}' registered`), await A(n, r);
|
|
842
844
|
}
|
|
843
845
|
function u(e) {
|
|
844
846
|
return e ? { ...f, ...e } : { ...f };
|
|
845
847
|
}
|
|
846
|
-
function
|
|
848
|
+
function N(e) {
|
|
847
849
|
f = { ...f, ...e };
|
|
848
850
|
}
|
|
849
|
-
async function
|
|
851
|
+
async function O(e, t) {
|
|
850
852
|
const r = u(t);
|
|
851
|
-
return await
|
|
853
|
+
return await T(r), p.has(e) || (c?.entries.some((s) => s.language === e) ?? !1);
|
|
852
854
|
}
|
|
853
|
-
async function
|
|
855
|
+
async function W(e) {
|
|
854
856
|
const t = u(e);
|
|
855
|
-
return await
|
|
857
|
+
return await T(t), c ? c.entries.map((r) => r.language) : Array.from(p);
|
|
856
858
|
}
|
|
857
859
|
export {
|
|
858
860
|
U as availableLanguages,
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
861
|
+
M as detectLanguage,
|
|
862
|
+
R as extractLanguageFromClass,
|
|
863
|
+
W as getAvailableLanguages,
|
|
862
864
|
u as getConfig,
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
865
|
+
S as highlight,
|
|
866
|
+
J as highlights,
|
|
867
|
+
O as isLanguageAvailable,
|
|
868
|
+
A as loadGrammar,
|
|
867
869
|
F as normalizeLanguage,
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
870
|
+
L as pluginVersion,
|
|
871
|
+
z as registerGrammar,
|
|
872
|
+
N as setConfig
|
|
871
873
|
};
|
|
872
874
|
//# sourceMappingURL=arborium.js.map
|
package/dist/arborium.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arborium.js","sources":["../src/detect.ts","../src/plugins-manifest.ts","../src/utils.ts","../src/loader.ts"],"sourcesContent":["/**\n * Simple language detection heuristics.\n * Not meant to be comprehensive - just catches common cases.\n */\n\n/** Shebang patterns */\nconst SHEBANG_PATTERNS: Array<[RegExp, string]> = [\n [/^#!.*\\bpython[23]?\\b/, 'python'],\n [/^#!.*\\bnode\\b/, 'javascript'],\n [/^#!.*\\bdeno\\b/, 'typescript'],\n [/^#!.*\\bbun\\b/, 'typescript'],\n [/^#!.*\\bruby\\b/, 'ruby'],\n [/^#!.*\\bperl\\b/, 'perl'],\n [/^#!.*\\bphp\\b/, 'php'],\n [/^#!.*\\bbash\\b/, 'bash'],\n [/^#!.*\\bzsh\\b/, 'zsh'],\n [/^#!.*\\bsh\\b/, 'bash'],\n [/^#!.*\\blua\\b/, 'lua'],\n [/^#!.*\\bawk\\b/, 'awk'],\n];\n\n/** Keyword fingerprints - first few unique keywords that identify a language */\nconst KEYWORD_FINGERPRINTS: Array<[RegExp, string]> = [\n // Rust - distinctive keywords\n [/\\b(fn|impl|trait|pub\\s+fn|let\\s+mut|&mut|->)\\b/, 'rust'],\n\n // Go - distinctive keywords\n [/\\b(func|package\\s+\\w+|import\\s+\\(|go\\s+func|chan\\s+\\w+)\\b/, 'go'],\n\n // Python - distinctive patterns\n [/\\b(def\\s+\\w+\\s*\\(|import\\s+\\w+|from\\s+\\w+\\s+import|class\\s+\\w+:)\\b/, 'python'],\n\n // TypeScript - distinctive type annotations\n [/:\\s*(string|number|boolean|void)\\b|\\binterface\\s+\\w+\\s*\\{/, 'typescript'],\n\n // JavaScript - distinctive patterns (after TS check)\n [/\\b(const|let|var)\\s+\\w+\\s*=|function\\s+\\w+\\s*\\(|=>\\s*\\{/, 'javascript'],\n\n // Ruby - distinctive keywords\n [/\\b(def\\s+\\w+|end\\b|do\\s*\\|.*\\||puts\\s+|require\\s+['\"])\\b/, 'ruby'],\n\n // Java - distinctive patterns\n [/\\b(public\\s+class|private\\s+\\w+|System\\.out\\.println)\\b/, 'java'],\n\n // C++ - distinctive patterns\n [/\\b(#include\\s*<|std::|template\\s*<|nullptr|cout\\s*<<)\\b/, 'cpp'],\n\n // C - distinctive patterns (after C++ check)\n [/\\b(#include\\s*[<\"]|printf\\s*\\(|int\\s+main\\s*\\(|void\\s+\\w+\\s*\\()\\b/, 'c'],\n\n // C# - distinctive patterns\n [/\\b(namespace\\s+\\w+|using\\s+System|public\\s+static\\s+void)\\b/, 'c-sharp'],\n\n // PHP - distinctive patterns\n [/<\\?php|\\$\\w+\\s*=/, 'php'],\n\n // Swift - distinctive patterns\n [/\\b(func\\s+\\w+|var\\s+\\w+:\\s*\\w+|let\\s+\\w+:\\s*\\w+|@objc)\\b/, 'swift'],\n\n // Kotlin - distinctive patterns\n [/\\b(fun\\s+\\w+|val\\s+\\w+|var\\s+\\w+:|data\\s+class)\\b/, 'kotlin'],\n\n // Scala - distinctive patterns\n [/\\b(def\\s+\\w+|val\\s+\\w+|var\\s+\\w+|object\\s+\\w+|case\\s+class)\\b/, 'scala'],\n\n // Haskell - distinctive patterns\n [/\\b(module\\s+\\w+|import\\s+qualified|data\\s+\\w+\\s*=|::\\s*\\w+\\s*->)\\b/, 'haskell'],\n\n // Elixir - distinctive patterns\n [/\\b(defmodule\\s+\\w+|def\\s+\\w+|defp\\s+\\w+|\\|>)\\b/, 'elixir'],\n\n // Lua - distinctive patterns\n [/\\b(local\\s+\\w+\\s*=|function\\s+\\w+\\.\\w+|require\\s*\\()\\b/, 'lua'],\n\n // SQL - distinctive patterns\n [/\\b(SELECT\\s+.*\\s+FROM|INSERT\\s+INTO|CREATE\\s+TABLE|ALTER\\s+TABLE)\\b/i, 'sql'],\n\n // Shell/Bash - distinctive patterns\n [/\\b(if\\s+\\[\\s*|then\\b|fi\\b|echo\\s+[\"']|export\\s+\\w+=)\\b/, 'bash'],\n\n // YAML - distinctive patterns\n [/^\\s*[\\w-]+:\\s*[\\w\\-\"'[{]|^---\\s*$/, 'yaml'],\n\n // JSON - distinctive patterns\n [/^\\s*\\{[\\s\\S]*\"[\\w-]+\":\\s*/, 'json'],\n\n // TOML - distinctive patterns\n [/^\\s*\\[[\\w.-]+\\]\\s*$|^\\s*\\w+\\s*=\\s*[\"'\\d\\[]/, 'toml'],\n\n // HTML - distinctive patterns\n [/<(!DOCTYPE|html|head|body|div|span|p|a\\s)/i, 'html'],\n\n // CSS - distinctive patterns\n [/^\\s*[\\w.#@][\\w\\s,#.:>+~-]*\\{[^}]*\\}|@media\\s|@import\\s/, 'css'],\n\n // Markdown - distinctive patterns\n [/^#{1,6}\\s+\\w|^\\s*[-*+]\\s+\\w|^\\s*\\d+\\.\\s+\\w|```\\w*\\n/, 'markdown'],\n\n // XML - distinctive patterns\n [/<\\?xml|<[\\w:-]+\\s+xmlns/, 'xml'],\n\n // Dockerfile\n [/^FROM\\s+\\w+|^RUN\\s+|^COPY\\s+|^ENTRYPOINT\\s+/m, 'dockerfile'],\n\n // Nginx config\n [/\\b(server\\s*\\{|location\\s+[\\/~]|proxy_pass\\s+)\\b/, 'nginx'],\n\n // Zig\n [/\\b(pub\\s+fn|const\\s+\\w+\\s*=|@import\\(|comptime)\\b/, 'zig'],\n];\n\n/**\n * Detect the language of a code snippet.\n * Returns null if detection fails.\n */\nexport function detectLanguage(source: string): string | null {\n // Check shebang first (most reliable)\n const firstLine = source.split('\\n')[0];\n for (const [pattern, language] of SHEBANG_PATTERNS) {\n if (pattern.test(firstLine)) {\n return language;\n }\n }\n\n // Check keyword fingerprints\n for (const [pattern, language] of KEYWORD_FINGERPRINTS) {\n if (pattern.test(source)) {\n return language;\n }\n }\n\n return null;\n}\n\n/**\n * Extract language from class name.\n * Supports multiple patterns:\n * - \"language-rust\" -> \"rust\" (standard)\n * - \"lang-rust\" -> \"rust\" (common alternative)\n * - \"rust\" -> \"rust\" (docs.rs style, bare language name)\n */\nexport function extractLanguageFromClass(className: string): string | null {\n // Try \"language-*\" pattern first (most specific)\n const langMatch = className.match(/\\blanguage-(\\w+)\\b/);\n if (langMatch) return langMatch[1];\n\n // Try \"lang-*\" pattern\n const shortMatch = className.match(/\\blang-(\\w+)\\b/);\n if (shortMatch) return shortMatch[1];\n\n // Try bare language names (for docs.rs compatibility)\n // Only match known language names to avoid false positives\n const knownLanguages = new Set([\n 'rust', 'javascript', 'typescript', 'python', 'ruby', 'go', 'java',\n 'c', 'cpp', 'csharp', 'php', 'swift', 'kotlin', 'scala', 'haskell',\n 'elixir', 'lua', 'sql', 'bash', 'shell', 'yaml', 'json', 'toml',\n 'html', 'css', 'xml', 'markdown', 'dockerfile', 'nginx', 'zig',\n 'text', 'plaintext', 'console', 'sh',\n ]);\n\n for (const cls of className.split(/\\s+/)) {\n if (knownLanguages.has(cls.toLowerCase())) {\n return cls.toLowerCase();\n }\n }\n\n return null;\n}\n\n/**\n * Normalize language identifier (handle aliases)\n */\nexport function normalizeLanguage(lang: string): string {\n const aliases: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n cs: 'c-sharp',\n csharp: 'c-sharp',\n 'c++': 'cpp',\n 'c#': 'c-sharp',\n 'f#': 'fsharp',\n dockerfile: 'dockerfile',\n docker: 'dockerfile',\n makefile: 'make',\n plaintext: 'text',\n plain: 'text',\n txt: 'text',\n };\n\n const lower = lang.toLowerCase();\n return aliases[lower] || lower;\n}\n","// AUTO-GENERATED by `cargo xtask gen-manifest` - DO NOT EDIT\n\nimport type { Highlight } from \"./types.js\"; \n\n/** Version of plugin packages (all @arborium/* packages share this version) */\nexport const pluginVersion = \"2.13.0\";\n\n/** All available languages */\nexport const availableLanguages: string[] = [\n \"ada\",\n \"agda\",\n \"asciidoc\",\n \"asm\",\n \"awk\",\n \"bash\",\n \"batch\",\n \"c\",\n \"c-sharp\",\n \"caddy\",\n \"capnp\",\n \"cedar\",\n \"cedarschema\",\n \"clojure\",\n \"cmake\",\n \"cobol\",\n \"commonlisp\",\n \"cpp\",\n \"css\",\n \"d\",\n \"dart\",\n \"devicetree\",\n \"diff\",\n \"dockerfile\",\n \"dot\",\n \"elisp\",\n \"elixir\",\n \"elm\",\n \"erlang\",\n \"fish\",\n \"fsharp\",\n \"gleam\",\n \"glsl\",\n \"go\",\n \"graphql\",\n \"groovy\",\n \"haskell\",\n \"hcl\",\n \"hlsl\",\n \"html\",\n \"idris\",\n \"ini\",\n \"java\",\n \"javascript\",\n \"jinja2\",\n \"jq\",\n \"json\",\n \"julia\",\n \"kotlin\",\n \"lean\",\n \"lua\",\n \"markdown\",\n \"matlab\",\n \"meson\",\n \"nginx\",\n \"ninja\",\n \"nix\",\n \"objc\",\n \"ocaml\",\n \"perl\",\n \"php\",\n \"postscript\",\n \"powershell\",\n \"prolog\",\n \"python\",\n \"query\",\n \"r\",\n \"rescript\",\n \"ron\",\n \"ruby\",\n \"rust\",\n \"scala\",\n \"scheme\",\n \"scss\",\n \"solidity\",\n \"sparql\",\n \"sql\",\n \"ssh-config\",\n \"starlark\",\n \"styx\",\n \"svelte\",\n \"swift\",\n \"textproto\",\n \"thrift\",\n \"tlaplus\",\n \"toml\",\n \"tsx\",\n \"typescript\",\n \"typst\",\n \"uiua\",\n \"vb\",\n \"verilog\",\n \"vhdl\",\n \"vim\",\n \"vue\",\n \"wit\",\n \"x86asm\",\n \"xml\",\n \"yaml\",\n \"yuri\",\n \"zig\",\n \"zsh\",\n];\n\n/** All possible highlights and their short tags */\nexport const highlights: Highlight[] = [\n {\n name: \"attribute\",\n tag: \"at\",\n },\n {\n name: \"constant\",\n tag: \"co\",\n },\n {\n name: \"constant.builtin\",\n tag: \"cb\",\n parentTag: \"constant\",\n },\n {\n name: \"constructor\",\n tag: \"cr\",\n },\n {\n name: \"function.builtin\",\n tag: \"fb\",\n parentTag: \"function\",\n },\n {\n name: \"function\",\n tag: \"f\",\n },\n {\n name: \"function.method\",\n tag: \"fm\",\n parentTag: \"function\",\n },\n {\n name: \"keyword\",\n tag: \"k\",\n },\n {\n name: \"keyword.conditional\",\n tag: \"kc\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.coroutine\",\n tag: \"ko\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.debug\",\n tag: \"kd\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.exception\",\n tag: \"ke\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.function\",\n tag: \"kf\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.import\",\n tag: \"ki\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.operator\",\n tag: \"kp\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.repeat\",\n tag: \"kr\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.return\",\n tag: \"kt\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.type\",\n tag: \"ky\",\n parentTag: \"keyword\",\n },\n {\n name: \"operator\",\n tag: \"o\",\n },\n {\n name: \"property\",\n tag: \"pr\",\n },\n {\n name: \"punctuation\",\n tag: \"p\",\n },\n {\n name: \"punctuation.bracket\",\n tag: \"pb\",\n parentTag: \"punctuation\",\n },\n {\n name: \"punctuation.delimiter\",\n tag: \"pd\",\n parentTag: \"punctuation\",\n },\n {\n name: \"punctuation.special\",\n tag: \"ps\",\n parentTag: \"punctuation\",\n },\n {\n name: \"string\",\n tag: \"s\",\n },\n {\n name: \"string.special\",\n tag: \"ss\",\n parentTag: \"string\",\n },\n {\n name: \"tag\",\n tag: \"tg\",\n },\n {\n name: \"tag.delimiter\",\n tag: \"td\",\n parentTag: \"tag\",\n },\n {\n name: \"tag.error\",\n tag: \"te\",\n parentTag: \"tag\",\n },\n {\n name: \"type\",\n tag: \"t\",\n },\n {\n name: \"type.builtin\",\n tag: \"tb\",\n parentTag: \"type\",\n },\n {\n name: \"type.qualifier\",\n tag: \"tq\",\n parentTag: \"type\",\n },\n {\n name: \"variable\",\n tag: \"v\",\n },\n {\n name: \"variable.builtin\",\n tag: \"vb\",\n parentTag: \"variable\",\n },\n {\n name: \"variable.parameter\",\n tag: \"vp\",\n parentTag: \"variable\",\n },\n {\n name: \"comment\",\n tag: \"c\",\n },\n {\n name: \"comment.documentation\",\n tag: \"cd\",\n parentTag: \"comment\",\n },\n {\n name: \"macro\",\n tag: \"m\",\n },\n {\n name: \"label\",\n tag: \"l\",\n },\n {\n name: \"diff.addition\",\n tag: \"da\",\n },\n {\n name: \"diff.deletion\",\n tag: \"dd\",\n },\n {\n name: \"number\",\n tag: \"n\",\n },\n {\n name: \"text.literal\",\n tag: \"tl\",\n },\n {\n name: \"text.emphasis\",\n tag: \"em\",\n },\n {\n name: \"text.strong\",\n tag: \"st\",\n },\n {\n name: \"text.uri\",\n tag: \"tu\",\n },\n {\n name: \"text.reference\",\n tag: \"tr\",\n },\n {\n name: \"string.escape\",\n tag: \"se\",\n parentTag: \"string\",\n },\n {\n name: \"text.title\",\n tag: \"tt\",\n },\n {\n name: \"text.strikethrough\",\n tag: \"tx\",\n },\n {\n name: \"spell\",\n tag: \"sp\",\n },\n {\n name: \"embedded\",\n tag: \"eb\",\n },\n {\n name: \"error\",\n tag: \"er\",\n },\n {\n name: \"namespace\",\n tag: \"ns\",\n },\n {\n name: \"include\",\n tag: \"in\",\n parentTag: \"keyword\",\n },\n {\n name: \"storageclass\",\n tag: \"sc\",\n parentTag: \"keyword\",\n },\n {\n name: \"repeat\",\n tag: \"rp\",\n parentTag: \"keyword\",\n },\n {\n name: \"conditional\",\n tag: \"cn\",\n parentTag: \"keyword\",\n },\n {\n name: \"exception\",\n tag: \"ex\",\n parentTag: \"keyword\",\n },\n {\n name: \"preproc\",\n tag: \"pp\",\n parentTag: \"keyword\",\n },\n {\n name: \"none\",\n tag: \"\",\n },\n {\n name: \"character\",\n tag: \"ch\",\n parentTag: \"string\",\n },\n {\n name: \"character.special\",\n tag: \"cs\",\n parentTag: \"string\",\n },\n {\n name: \"variable.member\",\n tag: \"vm\",\n parentTag: \"variable\",\n },\n {\n name: \"function.definition\",\n tag: \"fd\",\n parentTag: \"function\",\n },\n {\n name: \"type.definition\",\n tag: \"tf\",\n parentTag: \"type\",\n },\n {\n name: \"function.call\",\n tag: \"fc\",\n parentTag: \"function\",\n },\n {\n name: \"keyword.modifier\",\n tag: \"km\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.directive\",\n tag: \"dr\",\n parentTag: \"keyword\",\n },\n {\n name: \"string.regexp\",\n tag: \"rx\",\n parentTag: \"string\",\n },\n {\n name: \"nospell\",\n tag: \"\",\n },\n {\n name: \"float\",\n tag: \"n\",\n },\n {\n name: \"boolean\",\n tag: \"cb\",\n },\n];","/** Escape HTML special characters */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n","/**\n * Arborium loader - loads grammar plugins and highlights code.\n *\n * Architecture:\n * 1. Grammar registry is bundled at build time (no network request needed in production)\n * - Can be overridden via pluginsUrl config for local development\n * 2. Load grammar wasm-bindgen modules on demand from @arborium/<lang> packages\n * 3. Parse and highlight using the grammar's tree-sitter parser\n */\n\nimport type {\n Utf8ParseResult,\n Utf16ParseResult,\n ArboriumConfig,\n Grammar,\n Session,\n} from \"./types.js\";\nimport { availableLanguages, pluginVersion } from \"./plugins-manifest.js\";\nimport { escapeHtml } from \"./utils.js\";\n\n// Default config\nexport const defaultConfig: Required<ArboriumConfig> = {\n manual: false,\n theme: \"one-dark\",\n selector: \"pre code\",\n cdn: \"jsdelivr\",\n version: pluginVersion, // Precise version from manifest\n pluginsUrl: \"\", // Empty means use bundled manifest\n hostUrl: \"\", // Empty means use CDN based on version\n logger: console,\n resolveJs: ({ baseUrl, path }) => import(/* @vite-ignore */ `${baseUrl}/${path}`),\n resolveWasm: ({ baseUrl, path }) => fetch(`${baseUrl}/${path}`),\n};\n\n// Rust host module (loaded on demand)\ninterface HostModule {\n highlight: (language: string, source: string) => string;\n isLanguageAvailable: (language: string) => boolean;\n}\nlet hostModule: HostModule | null = null;\nlet hostLoadPromise: Promise<HostModule | null> | null = null;\n\n// Merged config\nlet globalConfig: Required<ArboriumConfig> = { ...defaultConfig };\n\n// Grammar plugins cache\nconst grammarCache = new Map<string, GrammarPlugin>();\n\n// In-flight grammar load promises (to prevent double-loading)\nconst grammarLoadPromises = new Map<string, Promise<GrammarPlugin | null>>();\n\n// Languages we know are available (bundled at build time)\nconst knownLanguages: Set<string> = new Set(availableLanguages);\n\n// For local development: can override with pluginsUrl to load from dev server\ninterface LocalManifest {\n entries: Array<{\n language: string;\n local_js: string;\n local_wasm: string;\n }>;\n}\nlet localManifest: LocalManifest | null = null;\nlet localManifestPromise: Promise<void> | null = null;\n\n/** Load local manifest if pluginsUrl is configured (for dev server) */\nasync function ensureLocalManifest(config: Required<ArboriumConfig>): Promise<void> {\n if (!config.pluginsUrl) {\n return;\n }\n\n if (localManifestPromise) {\n return localManifestPromise;\n }\n\n localManifestPromise = (async () => {\n config.logger.debug(`[arborium] Loading local plugins manifest from: ${config.pluginsUrl}`);\n const response = await fetch(config.pluginsUrl);\n if (!response.ok) {\n throw new Error(`Failed to load plugins.json: ${response.status}`);\n }\n localManifest = await response.json();\n config.logger.debug(`[arborium] Loaded local manifest with ${localManifest?.entries.length} entries`);\n })();\n\n return localManifestPromise;\n}\n\n/** Get the CDN base URL for a grammar */\nfunction getGrammarBaseUrl(language: string, config: Required<ArboriumConfig>): string {\n // If we have a local manifest (dev mode), use the local path\n if (localManifest) {\n const entry = localManifest.entries.find((e) => e.language === language);\n if (entry) {\n // Extract base URL from local_js path (e.g., \"/langs/group-hazel/python/npm/grammar.js\" -> \"/langs/group-hazel/python/npm\")\n return entry.local_js.substring(0, entry.local_js.lastIndexOf(\"/\"));\n }\n }\n\n // Production: derive from language name using precise version\n const cdn = config.cdn;\n const version = config.version;\n let baseUrl: string;\n if (cdn === \"jsdelivr\") {\n baseUrl = \"https://cdn.jsdelivr.net/npm\";\n } else if (cdn === \"unpkg\") {\n baseUrl = \"https://unpkg.com\";\n } else {\n baseUrl = cdn;\n }\n return `${baseUrl}/@arborium/${language}@${version}`;\n}\n\ntype MaybePromise<T> = Promise<T> | T;\n\n// See https://github.com/wasm-bindgen/wasm-bindgen/blob/dda4821ee2fbcaa7adc58bc8c385ed8d3627a272/crates/cli-support/src/js/mod.rs#L860\n/** Source of the WASM module for wasm-bindgen */\ntype WbgInitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;\n\n/** wasm-bindgen plugin module interface */\ninterface WasmBindgenPlugin {\n default: (\n module_or_path?: { module_or_path: MaybePromise<WbgInitInput> } | undefined,\n // deprecated: | MaybePromise<WbgInitInput>,\n ) => Promise<void>;\n language_id: () => string;\n injection_languages: () => string[];\n create_session: () => number;\n free_session: (session: number) => void;\n set_text: (session: number, text: string) => void;\n /** Parse and return UTF-8 byte offsets (for Rust host) */\n parse: (session: number) => Utf8ParseResult;\n /** Parse and return UTF-16 code unit indices (for JavaScript) */\n parse_utf16: (session: number) => Utf16ParseResult;\n cancel: (session: number) => void;\n}\n\n/** A loaded grammar plugin */\ninterface GrammarPlugin {\n languageId: string;\n injectionLanguages: string[];\n module: WasmBindgenPlugin;\n /** Parse returning UTF-8 offsets (for Rust host) */\n parseUtf8: (text: string) => Utf8ParseResult;\n /** Parse returning UTF-16 offsets (for JavaScript public API) */\n parseUtf16: (text: string) => Utf16ParseResult;\n}\n\n/** Load a grammar plugin */\nasync function loadGrammarPlugin(\n language: string,\n config: Required<ArboriumConfig>,\n): Promise<GrammarPlugin | null> {\n // Check cache first\n const cached = grammarCache.get(language);\n if (cached) {\n config.logger.debug(`[arborium] Grammar '${language}' found in cache`);\n return cached;\n }\n\n // Check if there's already an in-flight load for this language\n const inFlight = grammarLoadPromises.get(language);\n if (inFlight) {\n config.logger.debug(`[arborium] Grammar '${language}' already loading, waiting...`);\n return inFlight;\n }\n\n // Start the actual load and track the promise\n const loadPromise = loadGrammarPluginInner(language, config);\n grammarLoadPromises.set(language, loadPromise);\n\n try {\n return await loadPromise;\n } finally {\n // Clean up the in-flight promise once done\n grammarLoadPromises.delete(language);\n }\n}\n\n/** Internal grammar loading - called only once per language */\nasync function loadGrammarPluginInner(\n language: string,\n config: Required<ArboriumConfig>,\n): Promise<GrammarPlugin | null> {\n // Load local manifest if in dev mode\n await ensureLocalManifest(config);\n\n // Check if language is known\n if (\n !knownLanguages.has(language) &&\n !localManifest?.entries.some((e) => e.language === language)\n ) {\n config.logger.debug(`[arborium] Grammar '${language}' not available`);\n return null;\n }\n\n try {\n const baseUrl = getGrammarBaseUrl(language, config);\n const detail =\n config.resolveJs === defaultConfig.resolveJs ? ` from ${baseUrl}/grammar.js` : \"\";\n config.logger.debug(`[arborium] Loading grammar '${language}'${detail}`);\n\n const module = (await config.resolveJs({\n language,\n baseUrl,\n path: \"grammar.js\",\n })) as WasmBindgenPlugin;\n const wasm = await config.resolveWasm({ language, baseUrl, path: \"grammar_bg.wasm\" });\n\n // Initialize the WASM module\n await module.default({ module_or_path: wasm });\n\n // Verify it loaded correctly\n const loadedId = module.language_id();\n if (loadedId !== language) {\n config.logger.warn(`[arborium] Language ID mismatch: expected '${language}', got '${loadedId}'`);\n }\n\n // Get injection languages\n const injectionLanguages = module.injection_languages();\n\n // Wrap as GrammarPlugin with session-based parsing\n const plugin: GrammarPlugin = {\n languageId: language,\n injectionLanguages,\n module,\n // UTF-8 parsing for Rust host\n parseUtf8: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n // UTF-16 parsing for JavaScript public API\n parseUtf16: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse_utf16(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n };\n\n grammarCache.set(language, plugin);\n config.logger.debug(`[arborium] Grammar '${language}' loaded successfully`);\n return plugin;\n } catch (e) {\n config.logger.error(`[arborium] Failed to load grammar '${language}':`, e);\n return null;\n }\n}\n\n// Handle to plugin mapping for the host interface\nconst handleToPlugin = new Map<number, GrammarPlugin>();\nlet nextHandle = 1;\n\n/** Setup globalThis.arboriumHost for the Rust host to call into */\nfunction setupHostInterface(config: Required<ArboriumConfig>): void {\n (globalThis as any).arboriumHost = {\n /** Check if a language is available (sync) */\n isLanguageAvailable(language: string): boolean {\n return knownLanguages.has(language) || grammarCache.has(language);\n },\n\n /** Load a grammar and return a handle (async) */\n async loadGrammar(language: string): Promise<number> {\n const plugin = await loadGrammarPlugin(language, config);\n if (!plugin) return 0; // 0 = not found\n\n // Check if we already have a handle\n for (const [handle, p] of handleToPlugin) {\n if (p === plugin) return handle;\n }\n\n // Create new handle\n const handle = nextHandle++;\n handleToPlugin.set(handle, plugin);\n return handle;\n },\n\n /** Parse text using a grammar handle (sync) - returns UTF-8 offsets for Rust host */\n parse(handle: number, text: string): Utf8ParseResult {\n const plugin = handleToPlugin.get(handle);\n if (!plugin) return { spans: [], injections: [] };\n return plugin.parseUtf8(text);\n },\n };\n}\n\n/** Get the host URL based on config */\nfunction getHostUrl(config: Required<ArboriumConfig>): string {\n if (config.hostUrl) {\n return config.hostUrl;\n }\n // Use CDN\n const cdn = config.cdn;\n const version = config.version;\n let baseUrl: string;\n if (cdn === \"jsdelivr\") {\n baseUrl = \"https://cdn.jsdelivr.net/npm\";\n } else if (cdn === \"unpkg\") {\n baseUrl = \"https://unpkg.com\";\n } else {\n baseUrl = cdn;\n }\n const versionSuffix = version === \"latest\" ? \"\" : `@${version}`;\n return `${baseUrl}/@arborium/arborium${versionSuffix}/dist`;\n}\n\n/** Load the Rust host module */\nasync function loadHost(config: Required<ArboriumConfig>): Promise<HostModule | null> {\n if (hostModule) return hostModule;\n if (hostLoadPromise) return hostLoadPromise;\n\n hostLoadPromise = (async () => {\n // Setup the interface the host imports\n setupHostInterface(config);\n\n const hostUrl = getHostUrl(config);\n const jsUrl = `${hostUrl}/arborium_host.js`;\n const wasmUrl = `${hostUrl}/arborium_host_bg.wasm`;\n\n config.logger.debug(`[arborium] Loading host from ${jsUrl}`);\n try {\n const module = await import(/* @vite-ignore */ jsUrl);\n await module.default(wasmUrl);\n\n hostModule = {\n highlight: module.highlight,\n isLanguageAvailable: module.isLanguageAvailable,\n };\n config.logger.debug(`[arborium] Host loaded successfully`);\n return hostModule;\n } catch (e) {\n config.logger.error(\"[arborium] Failed to load host:\", e);\n return null;\n }\n })();\n\n return hostLoadPromise;\n}\n\n/** Highlight source code */\nexport async function highlight(\n language: string,\n source: string,\n configOverrides?: ArboriumConfig,\n): Promise<string> {\n const config = getConfig(configOverrides);\n // Use the Rust host (handles injections, proper span deduplication, etc.)\n const host = await loadHost(config);\n if (host) {\n try {\n return host.highlight(language, source);\n } catch (e) {\n config.logger.error(\"[arborium] Host highlight failed:\", e);\n }\n }\n\n // Host not available - return escaped source\n return escapeHtml(source);\n}\n\n/** Load a grammar for direct use */\nexport async function loadGrammar(\n language: string,\n configOverrides?: ArboriumConfig,\n): Promise<Grammar | null> {\n const config = getConfig(configOverrides);\n const plugin = await loadGrammarPlugin(language, config);\n if (!plugin) return null;\n\n const { module } = plugin;\n\n return {\n languageId: () => plugin.languageId,\n injectionLanguages: () => plugin.injectionLanguages,\n highlight: async (source: string) => {\n // Use the Rust host for proper highlighting with injection support\n return highlight(language, source, configOverrides);\n },\n // Public API returns UTF-16 offsets for JavaScript compatibility\n parse: (source: string) => plugin.parseUtf16(source),\n createSession: (): Session => {\n const handle = module.create_session();\n return {\n setText: (text: string) => module.set_text(handle, text),\n // Session.parse() returns UTF-16 offsets for JavaScript compatibility\n parse: () => {\n try {\n const result = module.parse_utf16(handle);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Session parse error:`, e);\n return { spans: [], injections: [] };\n }\n },\n cancel: () => module.cancel(handle),\n free: () => module.free_session(handle),\n };\n },\n dispose: () => {\n // No-op for now, plugins are cached\n },\n };\n}\n\n/**\n * Register a pre-loaded grammar module, bypassing CDN resolution.\n *\n * Use this in Node.js, Deno, or other non-browser environments where\n * dynamic `import()` of CDN URLs isn't available.\n *\n * @example\n * ```ts\n * // Deno\n * import * as pythonGrammar from \"npm:@arborium/python\";\n * import { readFile } from \"node:fs/promises\";\n * const wasm = await readFile(\"node_modules/@arborium/python/grammar_bg.wasm\");\n * const grammar = await registerGrammar(pythonGrammar, wasm);\n * const html = await grammar.highlight(\"print('hello')\");\n * ```\n */\nexport async function registerGrammar(\n jsModule: unknown,\n wasmSource: Response | BufferSource | WebAssembly.Module,\n configOverrides?: ArboriumConfig,\n): Promise<Grammar> {\n const config = getConfig(configOverrides);\n const module = jsModule as WasmBindgenPlugin;\n\n await module.default({ module_or_path: wasmSource });\n\n const language = module.language_id();\n const injectionLanguages = module.injection_languages();\n\n const plugin: GrammarPlugin = {\n languageId: language,\n injectionLanguages,\n module,\n parseUtf8: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n parseUtf16: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse_utf16(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n };\n\n grammarCache.set(language, plugin);\n knownLanguages.add(language);\n config.logger.debug(`[arborium] Grammar '${language}' registered`);\n\n // loadGrammar will find it in the cache and wrap it as a public Grammar\n const grammar = await loadGrammar(language, configOverrides);\n return grammar!;\n}\n\n/** Get current config, optionally merging with overrides */\nexport function getConfig(overrides?: Partial<ArboriumConfig>): Required<ArboriumConfig> {\n if (overrides) {\n return { ...globalConfig, ...overrides };\n }\n return { ...globalConfig };\n}\n\n/** Set/merge config */\nexport function setConfig(newConfig: Partial<ArboriumConfig>): void {\n globalConfig = { ...globalConfig, ...newConfig };\n}\n\n/** Check if a language is available */\nexport async function isLanguageAvailable(\n language: string,\n configOverrides?: ArboriumConfig,\n): Promise<boolean> {\n const config = getConfig(configOverrides);\n await ensureLocalManifest(config);\n return (\n knownLanguages.has(language) ||\n (localManifest?.entries.some((e) => e.language === language) ?? false)\n );\n}\n\n/** Get list of available languages */\nexport async function getAvailableLanguages(configOverrides?: ArboriumConfig): Promise<string[]> {\n const config = getConfig(configOverrides);\n await ensureLocalManifest(config);\n // In dev mode, use local manifest if available\n if (localManifest) {\n return localManifest.entries.map((e) => e.language);\n }\n return Array.from(knownLanguages);\n}\n"],"names":["SHEBANG_PATTERNS","KEYWORD_FINGERPRINTS","detectLanguage","source","firstLine","pattern","language","extractLanguageFromClass","className","langMatch","shortMatch","knownLanguages","cls","normalizeLanguage","lang","aliases","lower","pluginVersion","availableLanguages","highlights","escapeHtml","text","defaultConfig","baseUrl","path","hostModule","hostLoadPromise","globalConfig","grammarCache","grammarLoadPromises","localManifest","localManifestPromise","ensureLocalManifest","config","response","getGrammarBaseUrl","entry","e","cdn","version","loadGrammarPlugin","cached","inFlight","loadPromise","loadGrammarPluginInner","detail","module","wasm","loadedId","injectionLanguages","plugin","session","result","handleToPlugin","nextHandle","setupHostInterface","handle","p","getHostUrl","versionSuffix","loadHost","hostUrl","jsUrl","wasmUrl","highlight","configOverrides","getConfig","host","loadGrammar","registerGrammar","jsModule","wasmSource","overrides","setConfig","newConfig","isLanguageAvailable","getAvailableLanguages"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"arborium.js","sources":["../src/detect.ts","../src/plugins-manifest.ts","../src/utils.ts","../src/loader.ts"],"sourcesContent":["/**\n * Simple language detection heuristics.\n * Not meant to be comprehensive - just catches common cases.\n */\n\n/** Shebang patterns */\nconst SHEBANG_PATTERNS: Array<[RegExp, string]> = [\n [/^#!.*\\bpython[23]?\\b/, 'python'],\n [/^#!.*\\bnode\\b/, 'javascript'],\n [/^#!.*\\bdeno\\b/, 'typescript'],\n [/^#!.*\\bbun\\b/, 'typescript'],\n [/^#!.*\\bruby\\b/, 'ruby'],\n [/^#!.*\\bperl\\b/, 'perl'],\n [/^#!.*\\bphp\\b/, 'php'],\n [/^#!.*\\bbash\\b/, 'bash'],\n [/^#!.*\\bzsh\\b/, 'zsh'],\n [/^#!.*\\bsh\\b/, 'bash'],\n [/^#!.*\\blua\\b/, 'lua'],\n [/^#!.*\\bawk\\b/, 'awk'],\n];\n\n/** Keyword fingerprints - first few unique keywords that identify a language */\nconst KEYWORD_FINGERPRINTS: Array<[RegExp, string]> = [\n // Rust - distinctive keywords\n [/\\b(fn|impl|trait|pub\\s+fn|let\\s+mut|&mut|->)\\b/, 'rust'],\n\n // Go - distinctive keywords\n [/\\b(func|package\\s+\\w+|import\\s+\\(|go\\s+func|chan\\s+\\w+)\\b/, 'go'],\n\n // Python - distinctive patterns\n [/\\b(def\\s+\\w+\\s*\\(|import\\s+\\w+|from\\s+\\w+\\s+import|class\\s+\\w+:)\\b/, 'python'],\n\n // TypeScript - distinctive type annotations\n [/:\\s*(string|number|boolean|void)\\b|\\binterface\\s+\\w+\\s*\\{/, 'typescript'],\n\n // JavaScript - distinctive patterns (after TS check)\n [/\\b(const|let|var)\\s+\\w+\\s*=|function\\s+\\w+\\s*\\(|=>\\s*\\{/, 'javascript'],\n\n // Ruby - distinctive keywords\n [/\\b(def\\s+\\w+|end\\b|do\\s*\\|.*\\||puts\\s+|require\\s+['\"])\\b/, 'ruby'],\n\n // Java - distinctive patterns\n [/\\b(public\\s+class|private\\s+\\w+|System\\.out\\.println)\\b/, 'java'],\n\n // C++ - distinctive patterns\n [/\\b(#include\\s*<|std::|template\\s*<|nullptr|cout\\s*<<)\\b/, 'cpp'],\n\n // C - distinctive patterns (after C++ check)\n [/\\b(#include\\s*[<\"]|printf\\s*\\(|int\\s+main\\s*\\(|void\\s+\\w+\\s*\\()\\b/, 'c'],\n\n // C# - distinctive patterns\n [/\\b(namespace\\s+\\w+|using\\s+System|public\\s+static\\s+void)\\b/, 'c-sharp'],\n\n // PHP - distinctive patterns\n [/<\\?php|\\$\\w+\\s*=/, 'php'],\n\n // Swift - distinctive patterns\n [/\\b(func\\s+\\w+|var\\s+\\w+:\\s*\\w+|let\\s+\\w+:\\s*\\w+|@objc)\\b/, 'swift'],\n\n // Kotlin - distinctive patterns\n [/\\b(fun\\s+\\w+|val\\s+\\w+|var\\s+\\w+:|data\\s+class)\\b/, 'kotlin'],\n\n // Scala - distinctive patterns\n [/\\b(def\\s+\\w+|val\\s+\\w+|var\\s+\\w+|object\\s+\\w+|case\\s+class)\\b/, 'scala'],\n\n // Haskell - distinctive patterns\n [/\\b(module\\s+\\w+|import\\s+qualified|data\\s+\\w+\\s*=|::\\s*\\w+\\s*->)\\b/, 'haskell'],\n\n // Elixir - distinctive patterns\n [/\\b(defmodule\\s+\\w+|def\\s+\\w+|defp\\s+\\w+|\\|>)\\b/, 'elixir'],\n\n // Lua - distinctive patterns\n [/\\b(local\\s+\\w+\\s*=|function\\s+\\w+\\.\\w+|require\\s*\\()\\b/, 'lua'],\n\n // SQL - distinctive patterns\n [/\\b(SELECT\\s+.*\\s+FROM|INSERT\\s+INTO|CREATE\\s+TABLE|ALTER\\s+TABLE)\\b/i, 'sql'],\n\n // Shell/Bash - distinctive patterns\n [/\\b(if\\s+\\[\\s*|then\\b|fi\\b|echo\\s+[\"']|export\\s+\\w+=)\\b/, 'bash'],\n\n // YAML - distinctive patterns\n [/^\\s*[\\w-]+:\\s*[\\w\\-\"'[{]|^---\\s*$/, 'yaml'],\n\n // JSON - distinctive patterns\n [/^\\s*\\{[\\s\\S]*\"[\\w-]+\":\\s*/, 'json'],\n\n // TOML - distinctive patterns\n [/^\\s*\\[[\\w.-]+\\]\\s*$|^\\s*\\w+\\s*=\\s*[\"'\\d\\[]/, 'toml'],\n\n // HTML - distinctive patterns\n [/<(!DOCTYPE|html|head|body|div|span|p|a\\s)/i, 'html'],\n\n // CSS - distinctive patterns\n [/^\\s*[\\w.#@][\\w\\s,#.:>+~-]*\\{[^}]*\\}|@media\\s|@import\\s/, 'css'],\n\n // Markdown - distinctive patterns\n [/^#{1,6}\\s+\\w|^\\s*[-*+]\\s+\\w|^\\s*\\d+\\.\\s+\\w|```\\w*\\n/, 'markdown'],\n\n // XML - distinctive patterns\n [/<\\?xml|<[\\w:-]+\\s+xmlns/, 'xml'],\n\n // Dockerfile\n [/^FROM\\s+\\w+|^RUN\\s+|^COPY\\s+|^ENTRYPOINT\\s+/m, 'dockerfile'],\n\n // Nginx config\n [/\\b(server\\s*\\{|location\\s+[\\/~]|proxy_pass\\s+)\\b/, 'nginx'],\n\n // Zig\n [/\\b(pub\\s+fn|const\\s+\\w+\\s*=|@import\\(|comptime)\\b/, 'zig'],\n];\n\n/**\n * Detect the language of a code snippet.\n * Returns null if detection fails.\n */\nexport function detectLanguage(source: string): string | null {\n // Check shebang first (most reliable)\n const firstLine = source.split('\\n')[0];\n for (const [pattern, language] of SHEBANG_PATTERNS) {\n if (pattern.test(firstLine)) {\n return language;\n }\n }\n\n // Check keyword fingerprints\n for (const [pattern, language] of KEYWORD_FINGERPRINTS) {\n if (pattern.test(source)) {\n return language;\n }\n }\n\n return null;\n}\n\n/**\n * Extract language from class name.\n * Supports multiple patterns:\n * - \"language-rust\" -> \"rust\" (standard)\n * - \"lang-rust\" -> \"rust\" (common alternative)\n * - \"rust\" -> \"rust\" (docs.rs style, bare language name)\n */\nexport function extractLanguageFromClass(className: string): string | null {\n // Try \"language-*\" pattern first (most specific)\n const langMatch = className.match(/\\blanguage-(\\w+)\\b/);\n if (langMatch) return langMatch[1];\n\n // Try \"lang-*\" pattern\n const shortMatch = className.match(/\\blang-(\\w+)\\b/);\n if (shortMatch) return shortMatch[1];\n\n // Try bare language names (for docs.rs compatibility)\n // Only match known language names to avoid false positives\n const knownLanguages = new Set([\n 'rust', 'javascript', 'typescript', 'python', 'ruby', 'go', 'java',\n 'c', 'cpp', 'csharp', 'php', 'swift', 'kotlin', 'scala', 'haskell',\n 'elixir', 'lua', 'sql', 'bash', 'shell', 'yaml', 'json', 'toml',\n 'html', 'css', 'xml', 'markdown', 'dockerfile', 'nginx', 'zig',\n 'text', 'plaintext', 'console', 'sh',\n ]);\n\n for (const cls of className.split(/\\s+/)) {\n if (knownLanguages.has(cls.toLowerCase())) {\n return cls.toLowerCase();\n }\n }\n\n return null;\n}\n\n/**\n * Normalize language identifier (handle aliases)\n */\nexport function normalizeLanguage(lang: string): string {\n const aliases: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n cs: 'c-sharp',\n csharp: 'c-sharp',\n 'c++': 'cpp',\n 'c#': 'c-sharp',\n 'f#': 'fsharp',\n dockerfile: 'dockerfile',\n docker: 'dockerfile',\n makefile: 'make',\n plaintext: 'text',\n plain: 'text',\n txt: 'text',\n };\n\n const lower = lang.toLowerCase();\n return aliases[lower] || lower;\n}\n","// AUTO-GENERATED by `cargo xtask gen-manifest` - DO NOT EDIT\n\nimport type { Highlight } from \"./types.js\"; \n\n/** Version of plugin packages (all @arborium/* packages share this version) */\nexport const pluginVersion = \"2.14.0\";\n\n/** All available languages */\nexport const availableLanguages: string[] = [\n \"ada\",\n \"agda\",\n \"asciidoc\",\n \"asm\",\n \"awk\",\n \"bash\",\n \"batch\",\n \"c\",\n \"c-sharp\",\n \"caddy\",\n \"capnp\",\n \"cedar\",\n \"cedarschema\",\n \"clojure\",\n \"cmake\",\n \"cobol\",\n \"commonlisp\",\n \"cpp\",\n \"css\",\n \"d\",\n \"dart\",\n \"devicetree\",\n \"diff\",\n \"dockerfile\",\n \"dot\",\n \"elisp\",\n \"elixir\",\n \"elm\",\n \"erlang\",\n \"fish\",\n \"fsharp\",\n \"gleam\",\n \"glsl\",\n \"go\",\n \"graphql\",\n \"groovy\",\n \"haskell\",\n \"hcl\",\n \"hlsl\",\n \"html\",\n \"idris\",\n \"ini\",\n \"java\",\n \"javascript\",\n \"jinja2\",\n \"jq\",\n \"json\",\n \"julia\",\n \"kotlin\",\n \"lean\",\n \"lua\",\n \"markdown\",\n \"matlab\",\n \"meson\",\n \"nginx\",\n \"ninja\",\n \"nix\",\n \"objc\",\n \"ocaml\",\n \"perl\",\n \"php\",\n \"postscript\",\n \"powershell\",\n \"prolog\",\n \"python\",\n \"query\",\n \"r\",\n \"rescript\",\n \"ron\",\n \"ruby\",\n \"rust\",\n \"scala\",\n \"scheme\",\n \"scss\",\n \"solidity\",\n \"sparql\",\n \"sql\",\n \"ssh-config\",\n \"starlark\",\n \"styx\",\n \"svelte\",\n \"swift\",\n \"textproto\",\n \"thrift\",\n \"tlaplus\",\n \"toml\",\n \"tsx\",\n \"typescript\",\n \"typst\",\n \"uiua\",\n \"vb\",\n \"verilog\",\n \"vhdl\",\n \"vim\",\n \"vue\",\n \"wit\",\n \"x86asm\",\n \"xml\",\n \"yaml\",\n \"yuri\",\n \"zig\",\n \"zsh\",\n];\n\n/** All possible highlights and their short tags */\nexport const highlights: Highlight[] = [\n {\n name: \"attribute\",\n tag: \"at\",\n },\n {\n name: \"constant\",\n tag: \"co\",\n },\n {\n name: \"constant.builtin\",\n tag: \"cb\",\n parentTag: \"constant\",\n },\n {\n name: \"constructor\",\n tag: \"cr\",\n },\n {\n name: \"function.builtin\",\n tag: \"fb\",\n parentTag: \"function\",\n },\n {\n name: \"function\",\n tag: \"f\",\n },\n {\n name: \"function.method\",\n tag: \"fm\",\n parentTag: \"function\",\n },\n {\n name: \"keyword\",\n tag: \"k\",\n },\n {\n name: \"keyword.conditional\",\n tag: \"kc\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.coroutine\",\n tag: \"ko\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.debug\",\n tag: \"kd\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.exception\",\n tag: \"ke\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.function\",\n tag: \"kf\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.import\",\n tag: \"ki\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.operator\",\n tag: \"kp\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.repeat\",\n tag: \"kr\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.return\",\n tag: \"kt\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.type\",\n tag: \"ky\",\n parentTag: \"keyword\",\n },\n {\n name: \"operator\",\n tag: \"o\",\n },\n {\n name: \"property\",\n tag: \"pr\",\n },\n {\n name: \"punctuation\",\n tag: \"p\",\n },\n {\n name: \"punctuation.bracket\",\n tag: \"pb\",\n parentTag: \"punctuation\",\n },\n {\n name: \"punctuation.delimiter\",\n tag: \"pd\",\n parentTag: \"punctuation\",\n },\n {\n name: \"punctuation.special\",\n tag: \"ps\",\n parentTag: \"punctuation\",\n },\n {\n name: \"string\",\n tag: \"s\",\n },\n {\n name: \"string.special\",\n tag: \"ss\",\n parentTag: \"string\",\n },\n {\n name: \"tag\",\n tag: \"tg\",\n },\n {\n name: \"tag.delimiter\",\n tag: \"td\",\n parentTag: \"tag\",\n },\n {\n name: \"tag.error\",\n tag: \"te\",\n parentTag: \"tag\",\n },\n {\n name: \"type\",\n tag: \"t\",\n },\n {\n name: \"type.builtin\",\n tag: \"tb\",\n parentTag: \"type\",\n },\n {\n name: \"type.qualifier\",\n tag: \"tq\",\n parentTag: \"type\",\n },\n {\n name: \"variable\",\n tag: \"v\",\n },\n {\n name: \"variable.builtin\",\n tag: \"vb\",\n parentTag: \"variable\",\n },\n {\n name: \"variable.parameter\",\n tag: \"vp\",\n parentTag: \"variable\",\n },\n {\n name: \"comment\",\n tag: \"c\",\n },\n {\n name: \"comment.documentation\",\n tag: \"cd\",\n parentTag: \"comment\",\n },\n {\n name: \"macro\",\n tag: \"m\",\n },\n {\n name: \"label\",\n tag: \"l\",\n },\n {\n name: \"diff.addition\",\n tag: \"da\",\n },\n {\n name: \"diff.deletion\",\n tag: \"dd\",\n },\n {\n name: \"number\",\n tag: \"n\",\n },\n {\n name: \"text.literal\",\n tag: \"tl\",\n },\n {\n name: \"text.emphasis\",\n tag: \"em\",\n },\n {\n name: \"text.strong\",\n tag: \"st\",\n },\n {\n name: \"text.uri\",\n tag: \"tu\",\n },\n {\n name: \"text.reference\",\n tag: \"tr\",\n },\n {\n name: \"string.escape\",\n tag: \"se\",\n parentTag: \"string\",\n },\n {\n name: \"text.title\",\n tag: \"tt\",\n },\n {\n name: \"text.strikethrough\",\n tag: \"tx\",\n },\n {\n name: \"spell\",\n tag: \"sp\",\n },\n {\n name: \"embedded\",\n tag: \"eb\",\n },\n {\n name: \"error\",\n tag: \"er\",\n },\n {\n name: \"namespace\",\n tag: \"ns\",\n },\n {\n name: \"include\",\n tag: \"in\",\n parentTag: \"keyword\",\n },\n {\n name: \"storageclass\",\n tag: \"sc\",\n parentTag: \"keyword\",\n },\n {\n name: \"repeat\",\n tag: \"rp\",\n parentTag: \"keyword\",\n },\n {\n name: \"conditional\",\n tag: \"cn\",\n parentTag: \"keyword\",\n },\n {\n name: \"exception\",\n tag: \"ex\",\n parentTag: \"keyword\",\n },\n {\n name: \"preproc\",\n tag: \"pp\",\n parentTag: \"keyword\",\n },\n {\n name: \"none\",\n tag: \"\",\n },\n {\n name: \"character\",\n tag: \"ch\",\n parentTag: \"string\",\n },\n {\n name: \"character.special\",\n tag: \"cs\",\n parentTag: \"string\",\n },\n {\n name: \"variable.member\",\n tag: \"vm\",\n parentTag: \"variable\",\n },\n {\n name: \"function.definition\",\n tag: \"fd\",\n parentTag: \"function\",\n },\n {\n name: \"type.definition\",\n tag: \"tf\",\n parentTag: \"type\",\n },\n {\n name: \"function.call\",\n tag: \"fc\",\n parentTag: \"function\",\n },\n {\n name: \"keyword.modifier\",\n tag: \"km\",\n parentTag: \"keyword\",\n },\n {\n name: \"keyword.directive\",\n tag: \"dr\",\n parentTag: \"keyword\",\n },\n {\n name: \"string.regexp\",\n tag: \"rx\",\n parentTag: \"string\",\n },\n {\n name: \"nospell\",\n tag: \"\",\n },\n {\n name: \"float\",\n tag: \"n\",\n },\n {\n name: \"boolean\",\n tag: \"cb\",\n },\n];","/** Escape HTML special characters */\nexport function escapeHtml(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n","/**\n * Arborium loader - loads grammar plugins and highlights code.\n *\n * Architecture:\n * 1. Grammar registry is bundled at build time (no network request needed in production)\n * - Can be overridden via pluginsUrl config for local development\n * 2. Load grammar wasm-bindgen modules on demand from @arborium/<lang> packages\n * 3. Parse and highlight using the grammar's tree-sitter parser\n */\n\nimport type {\n Utf8ParseResult,\n Utf16ParseResult,\n ArboriumConfig,\n Grammar,\n Session,\n} from \"./types.js\";\nimport { availableLanguages, pluginVersion } from \"./plugins-manifest.js\";\nimport { escapeHtml } from \"./utils.js\";\n\n// Default config\nexport const defaultConfig: Required<ArboriumConfig> = {\n manual: false,\n theme: \"one-dark\",\n selector: \"pre code\",\n cdn: \"jsdelivr\",\n version: pluginVersion, // Precise version from manifest\n pluginsUrl: \"\", // Empty means use bundled manifest\n hostUrl: \"\", // Empty means use CDN based on version\n logger: console,\n resolveHostJs: ({ baseUrl, path }) => import(/* @vite-ignore */ `${baseUrl}/${path}`),\n resolveHostWasm: ({ baseUrl, path }) => fetch(`${baseUrl}/${path}`),\n resolveJs: ({ baseUrl, path }) => import(/* @vite-ignore */ `${baseUrl}/${path}`),\n resolveWasm: ({ baseUrl, path }) => fetch(`${baseUrl}/${path}`),\n};\n\n// Rust host module (loaded on demand)\ninterface HostModule {\n highlight: (language: string, source: string) => Promise<string>;\n isLanguageAvailable: (language: string) => boolean;\n}\nlet hostModule: HostModule | null = null;\nlet hostLoadPromise: Promise<HostModule | null> | null = null;\n\n// Merged config\nlet globalConfig: Required<ArboriumConfig> = { ...defaultConfig };\n\n// Grammar plugins cache\nconst grammarCache = new Map<string, GrammarPlugin>();\n\n// In-flight grammar load promises (to prevent double-loading)\nconst grammarLoadPromises = new Map<string, Promise<GrammarPlugin | null>>();\n\n// Languages we know are available (bundled at build time)\nconst knownLanguages: Set<string> = new Set(availableLanguages);\n\n// For local development: can override with pluginsUrl to load from dev server\ninterface LocalManifest {\n entries: Array<{\n language: string;\n local_js: string;\n local_wasm: string;\n }>;\n}\nlet localManifest: LocalManifest | null = null;\nlet localManifestPromise: Promise<void> | null = null;\n\n/** Load local manifest if pluginsUrl is configured (for dev server) */\nasync function ensureLocalManifest(config: Required<ArboriumConfig>): Promise<void> {\n if (!config.pluginsUrl) {\n return;\n }\n\n if (localManifestPromise) {\n return localManifestPromise;\n }\n\n localManifestPromise = (async () => {\n config.logger.debug(`[arborium] Loading local plugins manifest from: ${config.pluginsUrl}`);\n const response = await fetch(config.pluginsUrl);\n if (!response.ok) {\n throw new Error(`Failed to load plugins.json: ${response.status}`);\n }\n localManifest = await response.json();\n config.logger.debug(`[arborium] Loaded local manifest with ${localManifest?.entries.length} entries`);\n })();\n\n return localManifestPromise;\n}\n\n/** Get the CDN base URL for a grammar */\nfunction getGrammarBaseUrl(language: string, config: Required<ArboriumConfig>): string {\n // If we have a local manifest (dev mode), use the local path\n if (localManifest) {\n const entry = localManifest.entries.find((e) => e.language === language);\n if (entry) {\n // Extract base URL from local_js path (e.g., \"/langs/group-hazel/python/npm/grammar.js\" -> \"/langs/group-hazel/python/npm\")\n return entry.local_js.substring(0, entry.local_js.lastIndexOf(\"/\"));\n }\n }\n\n // Production: derive from language name using precise version\n const cdn = config.cdn;\n const version = config.version;\n let baseUrl: string;\n if (cdn === \"jsdelivr\") {\n baseUrl = \"https://cdn.jsdelivr.net/npm\";\n } else if (cdn === \"unpkg\") {\n baseUrl = \"https://unpkg.com\";\n } else {\n baseUrl = cdn;\n }\n return `${baseUrl}/@arborium/${language}@${version}`;\n}\n\ntype MaybePromise<T> = Promise<T> | T;\n\n// See https://github.com/wasm-bindgen/wasm-bindgen/blob/dda4821ee2fbcaa7adc58bc8c385ed8d3627a272/crates/cli-support/src/js/mod.rs#L860\n/** Source of the WASM module for wasm-bindgen */\ntype WbgInitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;\n\n/** wasm-bindgen plugin module interface */\ninterface WasmBindgenPlugin {\n default: (\n module_or_path?: { module_or_path: MaybePromise<WbgInitInput> } | undefined,\n // deprecated: | MaybePromise<WbgInitInput>,\n ) => Promise<void>;\n language_id: () => string;\n injection_languages: () => string[];\n create_session: () => number;\n free_session: (session: number) => void;\n set_text: (session: number, text: string) => void;\n /** Parse and return UTF-8 byte offsets (for Rust host) */\n parse: (session: number) => Utf8ParseResult;\n /** Parse and return UTF-16 code unit indices (for JavaScript) */\n parse_utf16: (session: number) => Utf16ParseResult;\n cancel: (session: number) => void;\n}\n\n/** A loaded grammar plugin */\ninterface GrammarPlugin {\n languageId: string;\n injectionLanguages: string[];\n module: WasmBindgenPlugin;\n /** Parse returning UTF-8 offsets (for Rust host) */\n parseUtf8: (text: string) => Utf8ParseResult;\n /** Parse returning UTF-16 offsets (for JavaScript public API) */\n parseUtf16: (text: string) => Utf16ParseResult;\n}\n\n/** Load a grammar plugin */\nasync function loadGrammarPlugin(\n language: string,\n config: Required<ArboriumConfig>,\n): Promise<GrammarPlugin | null> {\n // Check cache first\n const cached = grammarCache.get(language);\n if (cached) {\n config.logger.debug(`[arborium] Grammar '${language}' found in cache`);\n return cached;\n }\n\n // Check if there's already an in-flight load for this language\n const inFlight = grammarLoadPromises.get(language);\n if (inFlight) {\n config.logger.debug(`[arborium] Grammar '${language}' already loading, waiting...`);\n return inFlight;\n }\n\n // Start the actual load and track the promise\n const loadPromise = loadGrammarPluginInner(language, config);\n grammarLoadPromises.set(language, loadPromise);\n\n try {\n return await loadPromise;\n } finally {\n // Clean up the in-flight promise once done\n grammarLoadPromises.delete(language);\n }\n}\n\n/** Internal grammar loading - called only once per language */\nasync function loadGrammarPluginInner(\n language: string,\n config: Required<ArboriumConfig>,\n): Promise<GrammarPlugin | null> {\n // Load local manifest if in dev mode\n await ensureLocalManifest(config);\n\n // Check if language is known\n if (\n !knownLanguages.has(language) &&\n !localManifest?.entries.some((e) => e.language === language)\n ) {\n config.logger.debug(`[arborium] Grammar '${language}' not available`);\n return null;\n }\n\n try {\n const baseUrl = getGrammarBaseUrl(language, config);\n const detail =\n config.resolveJs === defaultConfig.resolveJs ? ` from ${baseUrl}/grammar.js` : \"\";\n config.logger.debug(`[arborium] Loading grammar '${language}'${detail}`);\n\n const module = (await config.resolveJs({\n language,\n baseUrl,\n path: \"grammar.js\",\n })) as WasmBindgenPlugin;\n const wasm = await config.resolveWasm({ language, baseUrl, path: \"grammar_bg.wasm\" });\n\n // Initialize the WASM module\n await module.default({ module_or_path: wasm });\n\n // Verify it loaded correctly\n const loadedId = module.language_id();\n if (loadedId !== language) {\n config.logger.warn(`[arborium] Language ID mismatch: expected '${language}', got '${loadedId}'`);\n }\n\n // Get injection languages\n const injectionLanguages = module.injection_languages();\n\n // Wrap as GrammarPlugin with session-based parsing\n const plugin: GrammarPlugin = {\n languageId: language,\n injectionLanguages,\n module,\n // UTF-8 parsing for Rust host\n parseUtf8: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n // UTF-16 parsing for JavaScript public API\n parseUtf16: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse_utf16(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n };\n\n grammarCache.set(language, plugin);\n config.logger.debug(`[arborium] Grammar '${language}' loaded successfully`);\n return plugin;\n } catch (e) {\n config.logger.error(`[arborium] Failed to load grammar '${language}':`, e);\n return null;\n }\n}\n\n// Handle to plugin mapping for the host interface\nconst handleToPlugin = new Map<number, GrammarPlugin>();\nlet nextHandle = 1;\n\n/** Setup globalThis.arboriumHost for the Rust host to call into */\nfunction setupHostInterface(config: Required<ArboriumConfig>): void {\n (globalThis as any).arboriumHost = {\n /** Check if a language is available (sync) */\n isLanguageAvailable(language: string): boolean {\n return knownLanguages.has(language) || grammarCache.has(language);\n },\n\n /** Load a grammar and return a handle (async) */\n async loadGrammar(language: string): Promise<number> {\n const plugin = await loadGrammarPlugin(language, config);\n if (!plugin) return 0; // 0 = not found\n\n // Check if we already have a handle\n for (const [handle, p] of handleToPlugin) {\n if (p === plugin) return handle;\n }\n\n // Create new handle\n const handle = nextHandle++;\n handleToPlugin.set(handle, plugin);\n return handle;\n },\n\n /** Parse text using a grammar handle (sync) - returns UTF-8 offsets for Rust host */\n parse(handle: number, text: string): Utf8ParseResult {\n const plugin = handleToPlugin.get(handle);\n if (!plugin) return { spans: [], injections: [] };\n return plugin.parseUtf8(text);\n },\n };\n}\n\n/** Get the host URL based on config */\nfunction getHostUrl(config: Required<ArboriumConfig>): string {\n if (config.hostUrl) {\n return config.hostUrl;\n }\n // Use CDN\n const cdn = config.cdn;\n const version = config.version;\n let baseUrl: string;\n if (cdn === \"jsdelivr\") {\n baseUrl = \"https://cdn.jsdelivr.net/npm\";\n } else if (cdn === \"unpkg\") {\n baseUrl = \"https://unpkg.com\";\n } else {\n baseUrl = cdn;\n }\n const versionSuffix = version === \"latest\" ? \"\" : `@${version}`;\n return `${baseUrl}/@arborium/arborium${versionSuffix}/dist`;\n}\n\ninterface WasmBindgenHost {\n default: (\n module_or_path?: { module_or_path: MaybePromise<WbgInitInput> } | undefined,\n // deprecated: | MaybePromise<WbgInitInput>,\n ) => Promise<void>;\n highlight(language: string, source: string): Promise<string>;\n isLanguageAvailable(language: string): boolean;\n}\n\n/** Load the Rust host module */\nasync function loadHost(config: Required<ArboriumConfig>): Promise<HostModule | null> {\n if (hostModule) return hostModule;\n if (hostLoadPromise) return hostLoadPromise;\n\n hostLoadPromise = (async () => {\n // Setup the interface the host imports\n setupHostInterface(config);\n\n const hostUrl = getHostUrl(config);\n const detail = config.resolveHostJs === defaultConfig.resolveHostJs ? ` from ${hostUrl}/arborium_host.js` : \"\";\n config.logger.debug(`[arborium] Loading host${detail}`);\n\n try {\n const module = (await config.resolveHostJs({ baseUrl: hostUrl, path: \"arborium_host.js\" })) as WasmBindgenHost;\n const wasm = await config.resolveHostWasm({ baseUrl: hostUrl, path: \"arborium_host_bg.wasm\" });\n\n await module.default({ module_or_path: wasm });\n\n hostModule = {\n highlight: module.highlight,\n isLanguageAvailable: module.isLanguageAvailable,\n };\n config.logger.debug(`[arborium] Host loaded successfully`);\n return hostModule;\n } catch (e) {\n config.logger.error(\"[arborium] Failed to load host:\", e);\n return null;\n }\n })();\n\n return hostLoadPromise;\n}\n\n/** Highlight source code */\nexport async function highlight(\n language: string,\n source: string,\n configOverrides?: ArboriumConfig,\n): Promise<string> {\n const config = getConfig(configOverrides);\n // Use the Rust host (handles injections, proper span deduplication, etc.)\n const host = await loadHost(config);\n if (host) {\n try {\n return host.highlight(language, source);\n } catch (e) {\n config.logger.error(\"[arborium] Host highlight failed:\", e);\n }\n }\n\n // Host not available - return escaped source\n return escapeHtml(source);\n}\n\n/** Load a grammar for direct use */\nexport async function loadGrammar(\n language: string,\n configOverrides?: ArboriumConfig,\n): Promise<Grammar | null> {\n const config = getConfig(configOverrides);\n const plugin = await loadGrammarPlugin(language, config);\n if (!plugin) return null;\n\n const { module } = plugin;\n\n return {\n languageId: () => plugin.languageId,\n injectionLanguages: () => plugin.injectionLanguages,\n highlight: async (source: string) => {\n // Use the Rust host for proper highlighting with injection support\n return highlight(language, source, configOverrides);\n },\n // Public API returns UTF-16 offsets for JavaScript compatibility\n parse: (source: string) => plugin.parseUtf16(source),\n createSession: (): Session => {\n const handle = module.create_session();\n return {\n setText: (text: string) => module.set_text(handle, text),\n // Session.parse() returns UTF-16 offsets for JavaScript compatibility\n parse: () => {\n try {\n const result = module.parse_utf16(handle);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Session parse error:`, e);\n return { spans: [], injections: [] };\n }\n },\n cancel: () => module.cancel(handle),\n free: () => module.free_session(handle),\n };\n },\n dispose: () => {\n // No-op for now, plugins are cached\n },\n };\n}\n\n/**\n * Register a pre-loaded grammar module, bypassing CDN resolution.\n *\n * Use this in Node.js, Deno, or other non-browser environments where\n * dynamic `import()` of CDN URLs isn't available.\n *\n * @example\n * ```ts\n * // Deno\n * import * as pythonGrammar from \"npm:@arborium/python\";\n * import { readFile } from \"node:fs/promises\";\n * const wasm = await readFile(\"node_modules/@arborium/python/grammar_bg.wasm\");\n * const grammar = await registerGrammar(pythonGrammar, wasm);\n * const html = await grammar.highlight(\"print('hello')\");\n * ```\n */\nexport async function registerGrammar(\n jsModule: unknown,\n wasmSource: Response | BufferSource | WebAssembly.Module,\n configOverrides?: ArboriumConfig,\n): Promise<Grammar> {\n const config = getConfig(configOverrides);\n const module = jsModule as WasmBindgenPlugin;\n\n await module.default({ module_or_path: wasmSource });\n\n const language = module.language_id();\n const injectionLanguages = module.injection_languages();\n\n const plugin: GrammarPlugin = {\n languageId: language,\n injectionLanguages,\n module,\n parseUtf8: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n parseUtf16: (text: string) => {\n const session = module.create_session();\n try {\n module.set_text(session, text);\n const result = module.parse_utf16(session);\n return {\n spans: result.spans || [],\n injections: result.injections || [],\n };\n } catch (e) {\n config.logger.error(`[arborium] Parse error:`, e);\n return { spans: [], injections: [] };\n } finally {\n module.free_session(session);\n }\n },\n };\n\n grammarCache.set(language, plugin);\n knownLanguages.add(language);\n config.logger.debug(`[arborium] Grammar '${language}' registered`);\n\n // loadGrammar will find it in the cache and wrap it as a public Grammar\n const grammar = await loadGrammar(language, configOverrides);\n return grammar!;\n}\n\n/** Get current config, optionally merging with overrides */\nexport function getConfig(overrides?: Partial<ArboriumConfig>): Required<ArboriumConfig> {\n if (overrides) {\n return { ...globalConfig, ...overrides };\n }\n return { ...globalConfig };\n}\n\n/** Set/merge config */\nexport function setConfig(newConfig: Partial<ArboriumConfig>): void {\n globalConfig = { ...globalConfig, ...newConfig };\n}\n\n/** Check if a language is available */\nexport async function isLanguageAvailable(\n language: string,\n configOverrides?: ArboriumConfig,\n): Promise<boolean> {\n const config = getConfig(configOverrides);\n await ensureLocalManifest(config);\n return (\n knownLanguages.has(language) ||\n (localManifest?.entries.some((e) => e.language === language) ?? false)\n );\n}\n\n/** Get list of available languages */\nexport async function getAvailableLanguages(configOverrides?: ArboriumConfig): Promise<string[]> {\n const config = getConfig(configOverrides);\n await ensureLocalManifest(config);\n // In dev mode, use local manifest if available\n if (localManifest) {\n return localManifest.entries.map((e) => e.language);\n }\n return Array.from(knownLanguages);\n}\n"],"names":["SHEBANG_PATTERNS","KEYWORD_FINGERPRINTS","detectLanguage","source","firstLine","pattern","language","extractLanguageFromClass","className","langMatch","shortMatch","knownLanguages","cls","normalizeLanguage","lang","aliases","lower","pluginVersion","availableLanguages","highlights","escapeHtml","text","defaultConfig","baseUrl","path","hostModule","hostLoadPromise","globalConfig","grammarCache","grammarLoadPromises","localManifest","localManifestPromise","ensureLocalManifest","config","response","getGrammarBaseUrl","entry","e","cdn","version","loadGrammarPlugin","cached","inFlight","loadPromise","loadGrammarPluginInner","detail","module","wasm","loadedId","injectionLanguages","plugin","session","result","handleToPlugin","nextHandle","setupHostInterface","handle","p","getHostUrl","versionSuffix","loadHost","hostUrl","highlight","configOverrides","getConfig","host","loadGrammar","registerGrammar","jsModule","wasmSource","overrides","setConfig","newConfig","isLanguageAvailable","getAvailableLanguages"],"mappings":"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"}
|