@void/md 0.26.1 → 0.28.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.
@@ -33,29 +33,26 @@ function createContainer(md, klass, defaultTitle) {
33
33
  * Custom container blocks: :::tip, :::info, :::warning, :::danger, :::details
34
34
  * Ported from VitePress.
35
35
  */
36
- function containerPlugin(md, options) {
37
- md.use(...createContainer(md, "tip", options?.tipLabel ?? "TIP")).use(...createContainer(md, "info", options?.infoLabel ?? "INFO")).use(...createContainer(md, "warning", options?.warningLabel ?? "WARNING")).use(...createContainer(md, "danger", options?.dangerLabel ?? "DANGER")).use(...createContainer(md, "details", options?.detailsLabel ?? "Details"));
36
+ function containerPlugin(md) {
37
+ md.use(...createContainer(md, "tip", "TIP")).use(...createContainer(md, "info", "INFO")).use(...createContainer(md, "warning", "WARNING")).use(...createContainer(md, "danger", "DANGER")).use(...createContainer(md, "details", "Details"));
38
38
  }
39
39
  //#endregion
40
40
  //#region src/plugins/github-alerts.ts
41
41
  const markerRE = /^\[!(TIP|NOTE|INFO|IMPORTANT|WARNING|CAUTION|DANGER)\]([^\n\r]*)/i;
42
- function capitalize(str) {
43
- return str.charAt(0).toUpperCase() + str.slice(1);
44
- }
42
+ const titleMark = {
43
+ tip: "TIP",
44
+ note: "NOTE",
45
+ info: "INFO",
46
+ important: "IMPORTANT",
47
+ warning: "WARNING",
48
+ caution: "CAUTION",
49
+ danger: "DANGER"
50
+ };
45
51
  /**
46
52
  * GitHub-flavored alerts: > [!NOTE], > [!TIP], > [!WARNING], etc.
47
53
  * Ported from VitePress.
48
54
  */
49
- function gitHubAlertsPlugin(md, options) {
50
- const titleMark = {
51
- tip: options?.tipLabel ?? "TIP",
52
- note: options?.noteLabel ?? "NOTE",
53
- info: options?.infoLabel ?? "INFO",
54
- important: options?.importantLabel ?? "IMPORTANT",
55
- warning: options?.warningLabel ?? "WARNING",
56
- caution: options?.cautionLabel ?? "CAUTION",
57
- danger: options?.dangerLabel ?? "DANGER"
58
- };
55
+ function gitHubAlertsPlugin(md) {
59
56
  const rule = (state) => {
60
57
  const tokens = state.tokens;
61
58
  for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) if (tokens[tokenIndex].type === "blockquote_open") {
@@ -70,7 +67,7 @@ function gitHubAlertsPlugin(md, options) {
70
67
  const match = firstContent.content.match(markerRE);
71
68
  if (!match) continue;
72
69
  const type = match[1].toLowerCase();
73
- const title = match[2].trim() || titleMark[type] || capitalize(type);
70
+ const title = match[2].trim() || titleMark[type];
74
71
  firstContent.content = firstContent.content.slice(match[0].length).trimStart();
75
72
  open.type = "github_alert_open";
76
73
  open.tag = "div";
@@ -111,17 +108,17 @@ function imagePlugin(md, options) {
111
108
  //#endregion
112
109
  //#region src/plugins/line-numbers.ts
113
110
  /**
114
- * Adds line number gutter to code blocks.
115
- * Supports `:line-numbers` / `:no-line-numbers` per-block control and `{=N}` start line.
111
+ * Adds a line number gutter to code blocks that opt in with `:line-numbers`.
112
+ * `{=N}` sets the start line.
116
113
  * Ported from VitePress.
117
114
  */
118
- function lineNumberPlugin(md, enable = false) {
115
+ function lineNumberPlugin(md) {
119
116
  const fence = md.renderer.rules.fence;
120
117
  md.renderer.rules.fence = async (...args) => {
121
118
  const rawCode = await fence(...args);
122
119
  const [tokens, idx] = args;
123
120
  const info = tokens[idx].info;
124
- if (!enable && !/:line-numbers\b/.test(info) || enable && /:no-line-numbers\b/.test(info)) return rawCode;
121
+ if (!/:line-numbers\b/.test(info)) return rawCode;
125
122
  let startLineNumber = 1;
126
123
  const matchStart = info.match(/=(\d+)/);
127
124
  if (matchStart?.[1]) startLineNumber = parseInt(matchStart[1]);
@@ -133,23 +130,23 @@ function lineNumberPlugin(md, enable = false) {
133
130
  //#endregion
134
131
  //#region src/plugins/link.ts
135
132
  const EXTERNAL_URL_RE = /^[a-z]+:/i;
133
+ const EXTERNAL_ATTRS = {
134
+ target: "_blank",
135
+ rel: "noreferrer"
136
+ };
136
137
  /**
137
138
  * Adds target="_blank" and rel="noreferrer" to external links.
138
139
  * Normalizes internal .md links to route paths.
139
140
  * Ported from VitePress.
140
141
  */
141
- function linkPlugin(md, options) {
142
- const externalAttrs = options?.externalAttrs ?? {
143
- target: "_blank",
144
- rel: "noreferrer"
145
- };
142
+ function linkPlugin(md) {
146
143
  md.renderer.rules.link_open = (tokens, idx, mdOptions, _env, self) => {
147
144
  const token = tokens[idx];
148
145
  const hrefIndex = token.attrIndex("href");
149
146
  if (hrefIndex < 0) return self.renderToken(tokens, idx, mdOptions);
150
147
  const url = token.attrs?.[hrefIndex]?.[1] ?? "";
151
148
  if (url.startsWith("#") || token.attrGet("class") === "header-anchor") return self.renderToken(tokens, idx, mdOptions);
152
- if (EXTERNAL_URL_RE.test(url)) for (const [key, val] of Object.entries(externalAttrs)) token.attrSet(key, val);
149
+ if (EXTERNAL_URL_RE.test(url)) for (const [key, val] of Object.entries(EXTERNAL_ATTRS)) token.attrSet(key, val);
153
150
  else {
154
151
  let normalized = url;
155
152
  if (normalized.endsWith(".md")) normalized = normalized.slice(0, -3);
@@ -168,8 +165,7 @@ function extractLang(info) {
168
165
  * Wraps fenced code blocks with a language label and copy button.
169
166
  * Ported from VitePress.
170
167
  */
171
- function preWrapperPlugin(md, options) {
172
- const title = options?.codeCopyButtonTitle ?? "Copy Code";
168
+ function preWrapperPlugin(md) {
173
169
  const fence = md.renderer.rules.fence;
174
170
  md.renderer.rules.fence = async (...args) => {
175
171
  const [tokens, idx] = args;
@@ -179,41 +175,38 @@ function preWrapperPlugin(md, options) {
179
175
  token.info = token.info.replace(/ active$/, "").replace(/ active /, " ");
180
176
  const lang = extractLang(token.info);
181
177
  const highlighted = await fence(...args);
182
- return `<div class="language-${lang}${active}"><button title="${title}" class="copy"></button><span class="lang">${lang}</span>` + highlighted + `</div>`;
178
+ return `<div class="language-${lang}${active}"><button title="Copy Code" class="copy"></button><span class="lang">${lang}</span>` + highlighted + `</div>`;
183
179
  };
184
180
  }
185
181
  //#endregion
186
182
  //#region src/plugins/toc.ts
187
- function renderHeaders(headers, listTag) {
183
+ const TOC_RE = /^\[\[toc\]\]$/i;
184
+ const TOC_LEVELS = [2, 3];
185
+ function renderHeaders(headers) {
188
186
  if (headers.length === 0) return "";
189
- let result = `<${listTag}>`;
187
+ let result = "<ul>";
190
188
  for (const h of headers) result += `<li><a href="#${h.slug}">${h.text}</a></li>`;
191
- result += `</${listTag}>`;
189
+ result += "</ul>";
192
190
  return result;
193
191
  }
194
192
  /**
195
193
  * [[toc]] directive — renders inline table of contents.
196
194
  * Ported from VitePress.
197
195
  */
198
- function tocPlugin(md, options) {
199
- const pattern = options?.pattern ?? /^\[\[toc\]\]$/i;
200
- const containerTag = options?.containerTag ?? "nav";
201
- const containerClass = options?.containerClass ?? "table-of-contents";
202
- const listTag = options?.listTag ?? "ul";
203
- const level = options?.level ?? [2, 3];
196
+ function tocPlugin(md) {
204
197
  md.block.ruler.before("heading", "toc", ((state, startLine, _endLine, silent) => {
205
198
  const pos = state.bMarks[startLine] + state.tShift[startLine];
206
199
  const max = state.eMarks[startLine];
207
200
  const content = state.src.slice(pos, max).trim();
208
- if (!pattern.test(content)) return false;
201
+ if (!TOC_RE.test(content)) return false;
209
202
  if (silent) return true;
210
203
  state.line = startLine + 1;
211
- const openToken = state.push("toc_open", containerTag, 1);
204
+ const openToken = state.push("toc_open", "nav", 1);
212
205
  openToken.markup = content;
213
- openToken.attrSet("class", containerClass);
206
+ openToken.attrSet("class", "table-of-contents");
214
207
  const bodyToken = state.push("toc_body", "", 0);
215
208
  bodyToken.markup = content;
216
- const closeToken = state.push("toc_close", containerTag, -1);
209
+ const closeToken = state.push("toc_close", "nav", -1);
217
210
  closeToken.markup = content;
218
211
  return true;
219
212
  }), { alt: [
@@ -222,7 +215,7 @@ function tocPlugin(md, options) {
222
215
  "blockquote"
223
216
  ] });
224
217
  md.renderer.rules.toc_body = (tokens) => {
225
- return renderHeaders(extractHeadings(tokens).filter((heading) => level.includes(heading.depth)), listTag);
218
+ return renderHeaders(extractHeadings(tokens).filter((heading) => TOC_LEVELS.includes(heading.depth)));
226
219
  };
227
220
  }
228
221
  //#endregion
@@ -275,7 +268,7 @@ async function createCompiler(options) {
275
268
  markdown.use(containerPlugin);
276
269
  markdown.use(imagePlugin, { lazyLoading: true });
277
270
  markdown.use(linkPlugin);
278
- markdown.use(lineNumberPlugin, false);
271
+ markdown.use(lineNumberPlugin);
279
272
  markdown.use(gitHubAlertsPlugin);
280
273
  const stashFenceInfo = (state) => {
281
274
  for (const token of state.tokens) if (token.type === "fence") token.meta = {
@@ -294,10 +287,11 @@ async function createCompiler(options) {
294
287
  async function compile(source, options) {
295
288
  const { data: frontmatter, content } = matter(source);
296
289
  const compiler = await getCompiler(options);
297
- const tokens = compiler.parse(content, {});
290
+ const env = {};
291
+ const tokens = compiler.parse(content, env);
298
292
  const headings = extractHeadings(tokens);
299
293
  return {
300
- html: await compiler.renderAsync(content, {}),
294
+ html: await compiler.renderer.renderAsync(tokens, compiler.options, env),
301
295
  frontmatter,
302
296
  headings,
303
297
  title: frontmatter.title ?? headings.find((heading) => heading.depth === 1)?.text ?? ""
package/dist/plugin.mjs CHANGED
@@ -1,35 +1,11 @@
1
1
  import { n as extractMetadata } from "./metadata-TdHmXD-i.mjs";
2
2
  import { createHash } from "node:crypto";
3
- import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
3
+ import { existsSync, readFileSync, readdirSync } from "node:fs";
4
4
  import { dirname, join, relative, resolve } from "pathslash";
5
5
  import { glob } from "tinyglobby";
6
6
  import { normalizePath } from "vite";
7
7
  import { resolvePagesDir } from "void/pages";
8
8
  import { editIslandSource, findIslandImports } from "void/pages-islands-plugin";
9
- //#region src/codegen/md-types.ts
10
- /**
11
- * Generate .void/md.d.ts content.
12
- *
13
- * Declares the `@void/md/pages` virtual module so TypeScript can resolve it
14
- * from anywhere in the project (pages/, routes/, etc.) without @ts-ignore.
15
- */
16
- function generateMdTypes() {
17
- return [
18
- "// Auto-generated by @void/md — do not edit",
19
- "",
20
- "export type VoidMdPage = Readonly<{",
21
- " path: string;",
22
- " title: string;",
23
- " frontmatter: Record<string, unknown>;",
24
- " headings: ReadonlyArray<{ depth: number; slug: string; text: string }>;",
25
- "}>;",
26
- "",
27
- "declare const pages: ReadonlyArray<VoidMdPage>;",
28
- "export default pages;",
29
- ""
30
- ].join("\n");
31
- }
32
- //#endregion
33
9
  //#region src/emit-shared.ts
34
10
  const ISLAND_TAG_RE = /<([A-Z]\w*)\s*((?:[^>/"']|"[^"]*"|'[^']*')*)\/\s*>|<([A-Z]\w*)\s*((?:[^>/"']|"[^"]*"|'[^']*')*)>([\s\S]*?)<\/\3\s*>/g;
35
11
  function findIslandTags(html, names) {
@@ -54,10 +30,11 @@ function parseAttrs(attrStr) {
54
30
  while ((match = attrRe.exec(attrStr)) !== null) result[match[1]] = match[2] ?? match[3] ?? match[4] ?? "";
55
31
  return result;
56
32
  }
57
- function toIslandId(imp) {
58
- return imp.islandId ?? imp.specifier.replace(/\.[^.]+$/, "");
59
- }
60
33
  function buildRenderChunks(html, islandImports) {
34
+ if (islandImports.length === 0) return [{
35
+ type: "html",
36
+ html
37
+ }];
61
38
  const islandByName = new Map(islandImports.map((item) => [item.name, item]));
62
39
  const tags = findIslandTags(html, new Set(islandByName.keys()));
63
40
  const chunks = [];
@@ -89,28 +66,7 @@ function buildRenderChunks(html, islandImports) {
89
66
  }
90
67
  //#endregion
91
68
  //#region src/emit-react.ts
92
- function emitReactComponent(result) {
93
- return `
94
- import React from "react";
95
- import { FrontmatterContext } from "@void/md";
96
-
97
- const __frontmatter = ${JSON.stringify(result.frontmatter)};
98
- const __headings = ${JSON.stringify(result.headings)};
99
- const __html = ${JSON.stringify(result.html)};
100
-
101
- export const frontmatter = __frontmatter;
102
- export const headings = __headings;
103
-
104
- export default function MarkdownPage() {
105
- return React.createElement(
106
- FrontmatterContext.Provider,
107
- { value: __frontmatter },
108
- React.createElement("div", { dangerouslySetInnerHTML: { __html: __html } })
109
- );
110
- }
111
- `;
112
- }
113
- function emitReactComponentWithIslands(result, islandImports) {
69
+ function emitReactComponent(result, islandImports) {
114
70
  const chunks = buildRenderChunks(result.html, islandImports);
115
71
  let code = `import React from "react";\n`;
116
72
  code += `import { FrontmatterContext } from "@void/md";\n`;
@@ -124,7 +80,7 @@ function emitReactComponentWithIslands(result, islandImports) {
124
80
  return React.createElement(
125
81
  "div",
126
82
  {
127
- "data-island": ${JSON.stringify(toIslandId(islandImport))},
83
+ "data-island": ${JSON.stringify(islandImport.islandId)},
128
84
  "data-props": JSON.stringify(props),
129
85
  "data-hydrate": ${JSON.stringify(islandImport.strategy)}
130
86
  },
@@ -162,27 +118,7 @@ export default function MarkdownPage() {
162
118
  }
163
119
  //#endregion
164
120
  //#region src/emit-solid.ts
165
- function emitSolidComponent(result) {
166
- return `
167
- import { FrontmatterContext } from "@void/md";
168
-
169
- const __frontmatter = ${JSON.stringify(result.frontmatter)};
170
- const __headings = ${JSON.stringify(result.headings)};
171
- const __html = ${JSON.stringify(result.html)};
172
-
173
- export const frontmatter = __frontmatter;
174
- export const headings = __headings;
175
-
176
- export default function MarkdownPage() {
177
- return (
178
- <FrontmatterContext.Provider value={__frontmatter}>
179
- <div innerHTML={__html} />
180
- </FrontmatterContext.Provider>
181
- );
182
- }
183
- `;
184
- }
185
- function emitSolidComponentWithIslands(result, islandImports) {
121
+ function emitSolidComponent(result, islandImports) {
186
122
  const chunks = buildRenderChunks(result.html, islandImports);
187
123
  const importAliasByName = /* @__PURE__ */ new Map();
188
124
  let code = `import { FrontmatterContext } from "@void/md";\n`;
@@ -212,7 +148,7 @@ export const headings = __headings;
212
148
  const importAlias = importAliasByName.get(chunk.islandImport.name) ?? chunk.islandImport.name;
213
149
  const propsLiteral = Object.keys(chunk.props).length > 0 ? JSON.stringify(chunk.props) : "{}";
214
150
  code += `\nconst ${propsName} = ${propsLiteral};`;
215
- bodyLines.push(`<div data-island=${JSON.stringify(toIslandId(chunk.islandImport))} data-props={JSON.stringify(${propsName})} data-hydrate=${JSON.stringify(chunk.islandImport.strategy)}><${importAlias} {...${propsName}} /></div>`);
151
+ bodyLines.push(`<div data-island=${JSON.stringify(chunk.islandImport.islandId)} data-props={JSON.stringify(${propsName})} data-hydrate=${JSON.stringify(chunk.islandImport.strategy)}><${importAlias} {...${propsName}} /></div>`);
216
152
  }
217
153
  if (bodyLines.length === 0) bodyLines.push("<></>");
218
154
  code += `
@@ -234,24 +170,7 @@ export default function MarkdownPage() {
234
170
  function toSvelteLiteral(value) {
235
171
  return JSON.stringify(value).replace(/<\//g, "<\\/");
236
172
  }
237
- function emitSvelteComponent(result) {
238
- const frontmatter = toSvelteLiteral(result.frontmatter);
239
- return `<script context="module">
240
- export const frontmatter = ${frontmatter};
241
- export const headings = ${toSvelteLiteral(result.headings)};
242
- <\/script>
243
-
244
- <script>
245
- import { setFrontmatter } from "@void/md";
246
-
247
- const __frontmatter = ${frontmatter};
248
- setFrontmatter(__frontmatter);
249
- <\/script>
250
-
251
- {@html ${toSvelteLiteral(result.html)}}
252
- `;
253
- }
254
- function emitSvelteComponentWithIslands(result, islandImports) {
173
+ function emitSvelteComponent(result, islandImports) {
255
174
  const chunks = buildRenderChunks(result.html, islandImports);
256
175
  const importAliasByName = /* @__PURE__ */ new Map();
257
176
  const frontmatter = toSvelteLiteral(result.frontmatter);
@@ -286,7 +205,7 @@ setFrontmatter(__frontmatter);
286
205
  const propsLiteral = Object.keys(chunk.props).length > 0 ? toSvelteLiteral(chunk.props) : "{}";
287
206
  source += `const ${propsName} = ${propsLiteral};
288
207
  `;
289
- body.push(`<div data-island="${toIslandId(chunk.islandImport)}" data-props={JSON.stringify(${propsName})} data-hydrate="${chunk.islandImport.strategy}"><${alias} {...${propsName}} /></div>`);
208
+ body.push(`<div data-island="${chunk.islandImport.islandId}" data-props={JSON.stringify(${propsName})} data-hydrate="${chunk.islandImport.strategy}"><${alias} {...${propsName}} /></div>`);
290
209
  }
291
210
  source += `<\/script>
292
211
 
@@ -296,26 +215,7 @@ ${body.join("\n")}
296
215
  }
297
216
  //#endregion
298
217
  //#region src/emit-vue.ts
299
- function emitVueComponent(result) {
300
- return `
301
- import { defineComponent, createStaticVNode, provide } from "vue";
302
-
303
- const __frontmatter = ${JSON.stringify(result.frontmatter)};
304
- const __headings = ${JSON.stringify(result.headings)};
305
- const __html = ${JSON.stringify(result.html)};
306
-
307
- export const frontmatter = __frontmatter;
308
- export const headings = __headings;
309
-
310
- export default defineComponent({
311
- setup() {
312
- provide("__void_frontmatter", __frontmatter);
313
- return () => createStaticVNode(__html, 1);
314
- }
315
- });
316
- `;
317
- }
318
- function emitVueComponentWithIslands(result, islandImports) {
218
+ function emitVueComponent(result, islandImports) {
319
219
  const chunks = buildRenderChunks(result.html, islandImports);
320
220
  let code = `import { defineComponent, h, createStaticVNode, provide } from "vue";\n`;
321
221
  for (let islandIndex = 0; islandIndex < islandImports.length; islandIndex++) {
@@ -327,7 +227,7 @@ function emitVueComponentWithIslands(result, islandImports) {
327
227
  code += `const ${islandImport.name} = { inheritAttrs: false, render() {
328
228
  const props = this.$attrs;
329
229
  return h("div", {
330
- "data-island": ${JSON.stringify(toIslandId(islandImport))},
230
+ "data-island": ${JSON.stringify(islandImport.islandId)},
331
231
  "data-props": JSON.stringify(props),
332
232
  "data-hydrate": ${JSON.stringify(islandImport.strategy)}
333
233
  }, h(_raw_island_${islandIndex}, props));
@@ -339,6 +239,7 @@ function emitVueComponentWithIslands(result, islandImports) {
339
239
  const propsStr = Object.keys(chunk.props).length > 0 ? JSON.stringify(chunk.props) : "null";
340
240
  vnodes.push(`h(${chunk.islandImport.name}, ${propsStr})`);
341
241
  }
242
+ const root = islandImports.length > 0 ? `[\n ${vnodes.join(",\n ")}\n ]` : vnodes[0];
342
243
  code += `
343
244
  const __frontmatter = ${JSON.stringify(result.frontmatter)};
344
245
  const __headings = ${JSON.stringify(result.headings)};
@@ -349,9 +250,7 @@ export const headings = __headings;
349
250
  export default defineComponent({
350
251
  setup() {
351
252
  provide("__void_frontmatter", __frontmatter);
352
- return () => [
353
- ${vnodes.join(",\n ")}
354
- ];
253
+ return () => ${root};
355
254
  }
356
255
  });
357
256
  `;
@@ -450,11 +349,6 @@ function voidMarkdown(options) {
450
349
  };
451
350
  }))).sort((leftPage, rightPage) => leftPage.path.localeCompare(rightPage.path));
452
351
  }
453
- function writeMdTypes() {
454
- const outDir = join(root, ".void");
455
- mkdirSync(outDir, { recursive: true });
456
- writeFileSync(join(outDir, "md.d.ts"), generateMdTypes());
457
- }
458
352
  return [{
459
353
  name: "void-md",
460
354
  enforce: "pre",
@@ -488,7 +382,6 @@ function voidMarkdown(options) {
488
382
  solidModules.clear();
489
383
  clientScripts.clear();
490
384
  mdPages = await scanMdPages();
491
- writeMdTypes();
492
385
  },
493
386
  configureServer(server) {
494
387
  const normalizedPagesDir = normalizePath(pagesDir);
@@ -574,35 +467,27 @@ export function useFrontmatter() { return useContext(FrontmatterContext) ?? {};
574
467
  const componentId = stripPageSuffix(_id.slice(pagesPrefix.length)) || "index";
575
468
  clientScripts.set(componentId, clientCode);
576
469
  }
577
- for (const imp of islandImports) {
470
+ const islands = islandImports.map((imp) => {
578
471
  const absPath = resolve(dirname(_id), imp.specifier);
579
- imp.islandId = normalizePath(relative(root, absPath)).replace(/\.[^.]+$/, "");
580
- }
581
- const { compile } = await import("./compile-BwShiv84.mjs");
582
- const result = await compile(body, { shiki: options?.shiki });
583
- if (adapter === "vue") {
584
- if (islandImports.length > 0) return {
585
- code: emitVueComponentWithIslands(result, islandImports),
586
- map: null
587
- };
472
+ const islandId = normalizePath(relative(root, absPath)).replace(/\.[^.]+$/, "");
588
473
  return {
589
- code: emitVueComponent(result),
590
- map: null
474
+ ...imp,
475
+ islandId
591
476
  };
592
- }
593
- if (adapter === "react") {
594
- if (islandImports.length > 0) return {
595
- code: emitReactComponentWithIslands(result, islandImports),
596
- map: null
597
- };
598
- return {
599
- code: emitReactComponent(result),
600
- map: null
601
- };
602
- }
477
+ });
478
+ const { compile } = await import("./compile-BN4Az3Z3.mjs");
479
+ const result = await compile(body, { shiki: options?.shiki });
480
+ if (adapter === "vue") return {
481
+ code: emitVueComponent(result, islands),
482
+ map: null
483
+ };
484
+ if (adapter === "react") return {
485
+ code: emitReactComponent(result, islands),
486
+ map: null
487
+ };
603
488
  if (adapter === "svelte") {
604
489
  const virtualId = createVirtualModuleId(SVELTE_VIRTUAL_PREFIX, _id, code, "svelte");
605
- svelteModules.set(virtualId, islandImports.length > 0 ? emitSvelteComponentWithIslands(result, islandImports) : emitSvelteComponent(result));
490
+ svelteModules.set(virtualId, emitSvelteComponent(result, islands));
606
491
  return {
607
492
  code: `export { default, frontmatter, headings } from ${JSON.stringify(virtualId)};`,
608
493
  map: null
@@ -610,7 +495,7 @@ export function useFrontmatter() { return useContext(FrontmatterContext) ?? {};
610
495
  }
611
496
  if (adapter === "solid") {
612
497
  const virtualId = createVirtualModuleId(SOLID_VIRTUAL_PREFIX, _id, code, "tsx");
613
- solidModules.set(virtualId, islandImports.length > 0 ? emitSolidComponentWithIslands(result, islandImports) : emitSolidComponent(result));
498
+ solidModules.set(virtualId, emitSolidComponent(result, islands));
614
499
  return {
615
500
  code: `export { default, frontmatter, headings } from ${JSON.stringify(virtualId)};`,
616
501
  map: null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@void/md",
3
- "version": "0.26.1",
3
+ "version": "0.28.0",
4
4
  "description": "Markdown pages with layouts and interactive islands for Void.",
5
5
  "homepage": "https://void.cloud",
6
6
  "bugs": {
@@ -53,12 +53,11 @@
53
53
  "@types/node": "^26.6.4",
54
54
  "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
55
55
  "vite-plus": "1.1.0",
56
- "void": "0.26.1",
57
- "vue": "^3.5.43"
56
+ "void": "0.28.0"
58
57
  },
59
58
  "peerDependencies": {
60
59
  "vite": "^8.0.0",
61
- "void": "0.26.1"
60
+ "void": "0.28.0"
62
61
  },
63
62
  "scripts": {
64
63
  "build": "vp pack",