@slidev/cli 0.49.15 → 0.49.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -36,20 +36,21 @@ Presentation <b>slide</b>s for <b>dev</b>elopers 🧑‍💻👩‍💻👨‍
36
36
 
37
37
  ## Features
38
38
 
39
- - 📝 [**Markdown-based**](https://sli.dev/guide/syntax.html) - use your favorite editors and workflow
40
- - 🧑‍💻 [**Developer Friendly**](https://sli.dev/guide/syntax.html#code-blocks) - built-in syntax highlighting, live coding, etc.
41
- - 🎨 [**Themable**](https://sli.dev/themes/gallery.html) - theme can be shared and used with npm packages.
42
- - 🌈 [**Stylish**](https://sli.dev/guide/syntax.html#embedded-styles) - on-demand utilities via [UnoCSS](https://github.com/unocss/unocss).
43
- - 🤹 [**Interactive**](https://sli.dev/custom/directory-structure.html#components) - embedding Vue components seamlessly.
44
- - 🎙 [**Presenter Mode**](https://sli.dev/guide/presenter-mode.html) - use another window, or even your phone to control your slides.
45
- - 🧮 [**LaTeX**](https://sli.dev/guide/syntax.html#latex) - built-in LaTeX math equations support.
46
- - 📰 [**Diagrams**](https://sli.dev/guide/syntax.html#diagrams) - creates diagrams with textual descriptions
47
- - 🌟 [**Icons**](https://sli.dev/guide/syntax.html#icons) - access to icons from any iconset directly.
48
- - 💻 [**Editors**](https://sli.dev/guide/editors.html) - integrated editor, or [extension for VS Code](https://github.com/slidevjs/slidev-vscode)
49
- - 🎥 [**Recording**](https://sli.dev/guide/recording.html) - built-in recording and camera view.
50
- - 📤 [**Portable**](https://sli.dev/guide/exporting.html) - export into PDF, PNGs, or even a hostable SPA.
51
- - ⚡️ [**Fast**](https://vitejs.dev) - instant reloading powered by [Vite](https://vitejs.dev).
52
- - 🛠 [**Hackable**](https://sli.dev/custom/config-vite.html) - using Vite plugins, Vue components, or any npm packages.
39
+ - 📝 [**Markdown-based**](https://sli.dev/guide/syntax) - foucus on content and use your favorite editor
40
+ - 🧑‍💻 [**Developer Friendly**](https://sli.dev/guide/syntax#code-blocks) - built-in code highlighting, live coding, etc.
41
+ - 🎨 [**Themable**](https://sli.dev/resources/theme-gallery) - theme can be shared and used with npm packages
42
+ - 🌈 [**Stylish**](https://sli.dev/guide/syntax#embedded-styles) - on-demand utilities via [UnoCSS](https://github.com/unocss/unocss).
43
+ - 🤹 [**Interactive**](https://sli.dev/custom/directory-structure#components) - embedding Vue components seamlessly
44
+ - 🎙 [**Presenter Mode**](https://sli.dev/guide/ui#presenter-mode) - use another window, or even your phone to control your slides
45
+ - 🎨 [**Drawing**](https://sli.dev/features/drawing) - draw and annotate on your slides
46
+ - 🧮 [**LaTeX**](https://sli.dev/features/latex) - built-in LaTeX math equations support
47
+ - 📰 [**Diagrams**](https://sli.dev/guide/syntax#diagrams) - creates diagrams using textual descriptions with [Mermaid.js](https://mermaid.js.org/)
48
+ - 🌟 [**Icons**](https://sli.dev/features/icons) - access to icons from any icon set directly
49
+ - 💻 [**Editor**](https://sli.dev/guide/index#editor) - integrated editor, or the [VSCode extension](https://sli.dev/features/vscode-extension)
50
+ - 🎥 [**Recording**](https://sli.dev/features/recording) - built-in recording and camera view
51
+ - 📤 [**Portable**](https://sli.dev/guide/exporting) - export into PDF, PNGs, or PPTX
52
+ - ⚡️ [**Fast**](https://vitejs.dev) - instant reloading powered by [Vite](https://vitejs.dev)
53
+ - 🛠 [**Hackable**](https://sli.dev/custom/) - using Vite plugins, Vue components, or any npm packages
53
54
 
54
55
  ## Getting Started
55
56
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getIndexHtml,
3
3
  resolveViteConfigs
4
- } from "./chunk-VAXCTWQX.mjs";
4
+ } from "./chunk-T42M3I2X.mjs";
5
5
  import "./chunk-27Q2X57X.mjs";
6
6
 
7
7
  // node/commands/build.ts
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  resolveViteConfigs
3
- } from "./chunk-VAXCTWQX.mjs";
3
+ } from "./chunk-T42M3I2X.mjs";
4
4
 
5
5
  // node/commands/server.ts
6
6
  import { join } from "node:path";
@@ -7176,7 +7176,7 @@ var require_dist = __commonJS({
7176
7176
  });
7177
7177
 
7178
7178
  // package.json
7179
- var version = "0.49.15";
7179
+ var version = "0.49.17";
7180
7180
 
7181
7181
  // node/commands/shared.ts
7182
7182
  import { existsSync as existsSync7, promises as fs9 } from "node:fs";
@@ -7257,7 +7257,6 @@ function updateFrontmatterPatch(slide, frontmatter) {
7257
7257
  import { join as join9 } from "node:path";
7258
7258
  import { existsSync as existsSync6 } from "node:fs";
7259
7259
  import process2 from "node:process";
7260
- import { fileURLToPath as fileURLToPath4 } from "node:url";
7261
7260
  import Icons from "unplugin-icons/vite";
7262
7261
  import IconsResolver from "unplugin-icons/resolver";
7263
7262
  import Components from "unplugin-vue-components/vite";
@@ -7500,10 +7499,7 @@ function getDefine(options) {
7500
7499
  }
7501
7500
 
7502
7501
  // node/vite/loaders.ts
7503
- import path from "node:path";
7504
7502
  import { notNullish, range } from "@antfu/utils";
7505
- import fg3 from "fast-glob";
7506
- import { bold, gray, red, yellow } from "kolorist";
7507
7503
  import * as parser2 from "@slidev/parser/fs";
7508
7504
  import equal from "fast-deep-equal";
7509
7505
 
@@ -7843,35 +7839,40 @@ var templateSlides = {
7843
7839
  id: "/@slidev/slides",
7844
7840
  async getContent({ data }, { getLayouts }) {
7845
7841
  const layouts = await getLayouts();
7846
- const imports = [
7847
- `import { shallowRef } from 'vue'`,
7848
- `import * as __layout__error from '${layouts.error}'`
7842
+ const statements = [
7843
+ `import { defineAsyncComponent, shallowRef } from 'vue'`,
7844
+ `import SlideError from '${layouts.error}'`,
7845
+ `import SlideLoading from '@slidev/client/internals/SlideLoading.vue'`,
7846
+ `const componentsCache = new Array(${data.slides.length})`,
7847
+ `const getAsyncComponent = (idx, loader) => defineAsyncComponent({`,
7848
+ ` loader,`,
7849
+ ` delay: 300,`,
7850
+ ` loadingComponent: SlideLoading,`,
7851
+ ` errorComponent: SlideError,`,
7852
+ ` onError: e => console.error('Failed to load slide ' + (idx + 1), e) `,
7853
+ `})`
7849
7854
  ];
7850
7855
  const slides = data.slides.map((_, idx) => {
7851
7856
  const no = idx + 1;
7852
- imports.push(`import { meta as f${no} } from '${VIRTUAL_SLIDE_PREFIX}${no}.frontmatter'`);
7853
- return `{
7854
- no: ${no},
7855
- meta: f${no},
7856
- component: async () => {
7857
- try {
7858
- return await import('${VIRTUAL_SLIDE_PREFIX}${no}.md')
7859
- }
7860
- catch(e) {
7861
- console.error('Failed to load slide ${no}:', e)
7862
- return __layout__error
7863
- }
7864
- },
7865
- }`;
7857
+ statements.push(
7858
+ `import { meta as f${no} } from '${VIRTUAL_SLIDE_PREFIX}${no}/frontmatter'`,
7859
+ // For some unknown reason, import error won't be caught by the error component. Catch it here.
7860
+ `const load${no} = async () => {`,
7861
+ ` try { return componentsCache[${idx}] ??= await import('${VIRTUAL_SLIDE_PREFIX}${no}/md') }`,
7862
+ ` catch (e) { return SlideError }`,
7863
+ `}`
7864
+ );
7865
+ return `{ no: ${no}, meta: f${no}, load: load${no}, component: getAsyncComponent(${idx}, load${no}) }`;
7866
7866
  });
7867
7867
  return [
7868
- ...imports,
7868
+ ...statements,
7869
7869
  `const data = [
7870
7870
  ${slides.join(",\n")}
7871
7871
  ]`,
7872
7872
  `if (import.meta.hot) {`,
7873
7873
  ` import.meta.hot.data.slides ??= shallowRef()`,
7874
7874
  ` import.meta.hot.data.slides.value = data`,
7875
+ ` import.meta.hot.dispose(() => componentsCache.length = 0)`,
7875
7876
  ` import.meta.hot.accept()`,
7876
7877
  `}`,
7877
7878
  `export const slides = import.meta.hot ? import.meta.hot.data.slides : shallowRef(data)`
@@ -7941,7 +7942,7 @@ ${title}
7941
7942
  </template>`);
7942
7943
  lines.push(
7943
7944
  `<script setup lang="ts">`,
7944
- `import { useSlideContext } from '@slidev/client'`,
7945
+ `import { useSlideContext } from '@slidev/client/context.ts'`,
7945
7946
  `import { computed } from 'vue'`,
7946
7947
  `const props = defineProps<{ no?: number | string }>()`,
7947
7948
  `const { $page } = useSlideContext()`,
@@ -7978,9 +7979,11 @@ var templates = [
7978
7979
  ];
7979
7980
 
7980
7981
  // node/options.ts
7982
+ import path from "node:path";
7981
7983
  import { uniq as uniq4 } from "@antfu/utils";
7982
7984
  import Debug from "debug";
7983
7985
  import mm from "micromatch";
7986
+ import fg3 from "fast-glob";
7984
7987
 
7985
7988
  // node/parser.ts
7986
7989
  import * as parser from "@slidev/parser/fs";
@@ -8076,23 +8079,48 @@ async function resolveOptions(options, mode) {
8076
8079
  themeRoots,
8077
8080
  addonRoots,
8078
8081
  roots,
8079
- utils: createDataUtils(data)
8082
+ utils: createDataUtils(data, rootsInfo.clientRoot, roots)
8080
8083
  };
8081
8084
  return resolved;
8082
8085
  }
8083
- function createDataUtils(data) {
8086
+ function createDataUtils(data, clientRoot, roots) {
8084
8087
  const monacoTypesIgnorePackagesMatches = (data.config.monacoTypesIgnorePackages || []).map((i) => mm.matcher(i));
8088
+ let _layouts_cache_time = 0;
8089
+ let _layouts_cache = {};
8085
8090
  return {
8086
- isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i(pkg))
8091
+ isMonacoTypesIgnored: (pkg) => monacoTypesIgnorePackagesMatches.some((i) => i(pkg)),
8092
+ getLayouts: async () => {
8093
+ const now = Date.now();
8094
+ if (now - _layouts_cache_time < 2e3)
8095
+ return _layouts_cache;
8096
+ const layouts = {};
8097
+ for (const root of [clientRoot, ...roots]) {
8098
+ const layoutPaths = await fg3("layouts/**/*.{vue,ts}", {
8099
+ cwd: root,
8100
+ absolute: true,
8101
+ suppressErrors: true
8102
+ });
8103
+ for (const layoutPath of layoutPaths) {
8104
+ const layoutName = path.basename(layoutPath).replace(/\.\w+$/, "");
8105
+ layouts[layoutName] = layoutPath;
8106
+ }
8107
+ }
8108
+ _layouts_cache_time = now;
8109
+ _layouts_cache = layouts;
8110
+ return layouts;
8111
+ }
8087
8112
  };
8088
8113
  }
8089
8114
 
8090
- // node/vite/loaders.ts
8091
- var regexId = /^\/@slidev\/slide\/(\d+)\.(md|json)(?:\?import)?$/;
8092
- var regexIdQuery = /(\d+)\.(md|json|frontmatter)$/;
8115
+ // node/vite/common.ts
8116
+ var regexSlideReqPath = /^\/__slidev\/slides\/(\d+)\.json$/;
8117
+ var regexSlideFacadeId = /^\/@slidev\/slides\/(\d+)\/(md|frontmatter)($|\?)/;
8118
+ var regexSlideSourceId = /__slidev_(\d+)\.(md|frontmatter)$/;
8093
8119
  var templateInjectionMarker = "/* @slidev-injection */";
8094
8120
  var templateImportContextUtils = `import { useSlideContext as _useSlideContext, frontmatterToProps as _frontmatterToProps } from "@slidev/client/context.ts"`;
8095
8121
  var templateInitContext = `const { $slidev, $nav, $clicksContext, $clicks, $page, $renderContext, $frontmatter } = _useSlideContext()`;
8122
+
8123
+ // node/vite/loaders.ts
8096
8124
  function getBodyJson(req) {
8097
8125
  return new Promise((resolve8, reject) => {
8098
8126
  let body = "";
@@ -8123,382 +8151,247 @@ function withRenderedNote(data) {
8123
8151
  noteHTML: renderNote(data?.note)
8124
8152
  };
8125
8153
  }
8126
- function createSlidesLoader(options, pluginOptions, serverOptions) {
8154
+ function createSlidesLoader(options, serverOptions) {
8127
8155
  const hmrPages = /* @__PURE__ */ new Set();
8128
8156
  let server;
8129
- let _layouts_cache_time = 0;
8130
- let _layouts_cache = {};
8131
8157
  let skipHmr = null;
8132
8158
  const { data, clientRoot, roots, mode, utils } = options;
8133
8159
  const templateCtx = {
8134
8160
  md: sharedMd,
8135
- async getLayouts() {
8136
- const now = Date.now();
8137
- if (now - _layouts_cache_time < 2e3)
8138
- return _layouts_cache;
8139
- const layouts = {};
8140
- for (const root of [clientRoot, ...roots]) {
8141
- const layoutPaths = await fg3("layouts/**/*.{vue,ts}", {
8142
- cwd: root,
8143
- absolute: true,
8144
- suppressErrors: true
8145
- });
8146
- for (const layoutPath of layoutPaths) {
8147
- const layoutName = path.basename(layoutPath).replace(/\.\w+$/, "");
8148
- layouts[layoutName] = layoutPath;
8149
- }
8150
- }
8151
- _layouts_cache_time = now;
8152
- _layouts_cache = layouts;
8153
- return layouts;
8154
- }
8161
+ getLayouts: utils.getLayouts
8155
8162
  };
8156
- return [
8157
- {
8158
- name: "slidev:loader",
8159
- configureServer(_server) {
8160
- server = _server;
8161
- updateServerWatcher();
8162
- server.middlewares.use(async (req, res, next) => {
8163
- const match = req.url?.match(regexId);
8164
- if (!match)
8165
- return next();
8166
- const [, no, type] = match;
8167
- const idx = Number.parseInt(no) - 1;
8168
- if (type === "json" && req.method === "GET") {
8169
- res.write(JSON.stringify(withRenderedNote(data.slides[idx])));
8170
- return res.end();
8171
- }
8172
- if (type === "json" && req.method === "POST") {
8173
- const body = await getBodyJson(req);
8174
- const slide = data.slides[idx];
8175
- if (body.content && body.content !== slide.source.content)
8176
- hmrPages.add(idx);
8177
- if (body.content)
8178
- slide.content = slide.source.content = body.content;
8179
- if (body.note)
8180
- slide.note = slide.source.note = body.note;
8181
- if (body.frontmatter)
8182
- updateFrontmatterPatch(slide, body.frontmatter);
8183
- parser2.prettifySlide(slide.source);
8184
- const fileContent = await parser2.save(data.markdownFiles[slide.source.filepath]);
8185
- if (body.skipHmr) {
8186
- skipHmr = {
8187
- filePath: slide.source.filepath,
8188
- fileContent
8189
- };
8163
+ function getSourceId(index, type) {
8164
+ return `${data.slides[index].source.filepath}__slidev_${index + 1}.${type}`;
8165
+ }
8166
+ function updateServerWatcher() {
8167
+ if (!server)
8168
+ return;
8169
+ server.watcher.add(data.watchFiles);
8170
+ }
8171
+ function getFrontmatter(pageNo) {
8172
+ return {
8173
+ ...data.headmatter?.defaults || {},
8174
+ ...data.slides[pageNo]?.frontmatter || {}
8175
+ };
8176
+ }
8177
+ return {
8178
+ name: "slidev:loader",
8179
+ configureServer(_server) {
8180
+ server = _server;
8181
+ updateServerWatcher();
8182
+ server.middlewares.use(async (req, res, next) => {
8183
+ const match = req.url?.match(regexSlideReqPath);
8184
+ if (!match)
8185
+ return next();
8186
+ const [, no] = match;
8187
+ const idx = Number.parseInt(no) - 1;
8188
+ if (req.method === "GET") {
8189
+ res.write(JSON.stringify(withRenderedNote(data.slides[idx])));
8190
+ return res.end();
8191
+ } else if (req.method === "POST") {
8192
+ const body = await getBodyJson(req);
8193
+ const slide = data.slides[idx];
8194
+ if (body.content && body.content !== slide.source.content)
8195
+ hmrPages.add(idx);
8196
+ if (body.content)
8197
+ slide.content = slide.source.content = body.content;
8198
+ if (body.note)
8199
+ slide.note = slide.source.note = body.note;
8200
+ if (body.frontmatter)
8201
+ updateFrontmatterPatch(slide, body.frontmatter);
8202
+ parser2.prettifySlide(slide.source);
8203
+ const fileContent = await parser2.save(data.markdownFiles[slide.source.filepath]);
8204
+ if (body.skipHmr) {
8205
+ skipHmr = {
8206
+ filePath: slide.source.filepath,
8207
+ fileContent
8208
+ };
8209
+ server?.moduleGraph.invalidateModule(
8210
+ server.moduleGraph.getModuleById(getSourceId(idx, "md"))
8211
+ );
8212
+ if (body.frontmatter) {
8190
8213
  server?.moduleGraph.invalidateModule(
8191
- server.moduleGraph.getModuleById(`${VIRTUAL_SLIDE_PREFIX}${no}.md`)
8214
+ server.moduleGraph.getModuleById(getSourceId(idx, "frontmatter"))
8192
8215
  );
8193
- if (body.frontmatter) {
8194
- server?.moduleGraph.invalidateModule(
8195
- server.moduleGraph.getModuleById(`${VIRTUAL_SLIDE_PREFIX}${no}.frontmatter`)
8196
- );
8197
- }
8198
8216
  }
8199
- res.statusCode = 200;
8200
- res.write(JSON.stringify(withRenderedNote(slide)));
8201
- return res.end();
8202
8217
  }
8203
- next();
8204
- });
8205
- },
8206
- async handleHotUpdate(ctx) {
8207
- if (!data.watchFiles.includes(ctx.file))
8208
- return;
8209
- await ctx.read();
8210
- const newData = await serverOptions.loadData?.();
8211
- if (!newData)
8212
- return [];
8213
- if (skipHmr && newData.markdownFiles[skipHmr.filePath]?.raw === skipHmr.fileContent) {
8214
- skipHmr = null;
8215
- return [];
8218
+ res.statusCode = 200;
8219
+ res.write(JSON.stringify(withRenderedNote(slide)));
8220
+ return res.end();
8216
8221
  }
8217
- const moduleIds = /* @__PURE__ */ new Set();
8218
- if (data.slides.length !== newData.slides.length) {
8219
- moduleIds.add(templateSlides.id);
8220
- range(newData.slides.length).map((i) => hmrPages.add(i));
8221
- }
8222
- if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
8223
- moduleIds.add(templateSlides.id);
8224
- range(data.slides.length).map((i) => hmrPages.add(i));
8225
- }
8226
- if (!equal(data.config, newData.config))
8227
- moduleIds.add(templateConfigs.id);
8228
- if (!equal(data.features, newData.features)) {
8229
- setTimeout(() => {
8230
- ctx.server.hot.send({ type: "full-reload" });
8231
- }, 1);
8232
- }
8233
- const length = Math.min(data.slides.length, newData.slides.length);
8234
- for (let i = 0; i < length; i++) {
8235
- const a = data.slides[i];
8236
- const b = newData.slides[i];
8237
- if (!hmrPages.has(i) && a.content.trim() === b.content.trim() && a.title?.trim() === b.title?.trim() && equal(a.frontmatter, b.frontmatter)) {
8238
- if (a.note !== b.note) {
8239
- ctx.server.hot.send(
8240
- "slidev:update-note",
8241
- {
8242
- no: i + 1,
8243
- note: b.note || "",
8244
- noteHTML: renderNote(b.note || "")
8245
- }
8246
- );
8247
- }
8248
- continue;
8222
+ next();
8223
+ });
8224
+ },
8225
+ async handleHotUpdate(ctx) {
8226
+ if (!data.watchFiles.includes(ctx.file))
8227
+ return;
8228
+ await ctx.read();
8229
+ const newData = await serverOptions.loadData?.();
8230
+ if (!newData)
8231
+ return [];
8232
+ if (skipHmr && newData.markdownFiles[skipHmr.filePath]?.raw === skipHmr.fileContent) {
8233
+ skipHmr = null;
8234
+ return [];
8235
+ }
8236
+ const moduleIds = /* @__PURE__ */ new Set();
8237
+ if (data.slides.length !== newData.slides.length) {
8238
+ moduleIds.add(templateSlides.id);
8239
+ range(newData.slides.length).map((i) => hmrPages.add(i));
8240
+ }
8241
+ if (!equal(data.headmatter.defaults, newData.headmatter.defaults)) {
8242
+ moduleIds.add(templateSlides.id);
8243
+ range(data.slides.length).map((i) => hmrPages.add(i));
8244
+ }
8245
+ if (!equal(data.config, newData.config))
8246
+ moduleIds.add(templateConfigs.id);
8247
+ if (!equal(data.features, newData.features)) {
8248
+ setTimeout(() => {
8249
+ ctx.server.hot.send({ type: "full-reload" });
8250
+ }, 1);
8251
+ }
8252
+ const length = Math.min(data.slides.length, newData.slides.length);
8253
+ for (let i = 0; i < length; i++) {
8254
+ const a = data.slides[i];
8255
+ const b = newData.slides[i];
8256
+ if (!hmrPages.has(i) && a.content.trim() === b.content.trim() && a.title?.trim() === b.title?.trim() && equal(a.frontmatter, b.frontmatter)) {
8257
+ if (a.note !== b.note) {
8258
+ ctx.server.hot.send(
8259
+ "slidev:update-note",
8260
+ {
8261
+ no: i + 1,
8262
+ note: b.note || "",
8263
+ noteHTML: renderNote(b.note || "")
8264
+ }
8265
+ );
8249
8266
  }
8250
- ctx.server.hot.send(
8251
- "slidev:update-slide",
8252
- {
8253
- no: i + 1,
8254
- data: withRenderedNote(newData.slides[i])
8255
- }
8256
- );
8257
- hmrPages.add(i);
8258
- }
8259
- Object.assign(data, newData);
8260
- Object.assign(utils, createDataUtils(newData));
8261
- if (hmrPages.size > 0)
8262
- moduleIds.add(templateTitleRendererMd.id);
8263
- const vueModules = Array.from(hmrPages).flatMap((i) => {
8264
- const id = `${VIRTUAL_SLIDE_PREFIX}${i + 1}`;
8265
- const frontmatter = ctx.server.moduleGraph.getModuleById(`${id}.frontmatter`);
8266
- const main = ctx.server.moduleGraph.getModuleById(`${id}.md`);
8267
- const styles = main ? [...main.clientImportedModules].find((m) => m.id?.startsWith(`${id}.md?vue&type=style`)) : void 0;
8268
- return [
8269
- frontmatter,
8270
- main,
8271
- styles
8272
- ];
8273
- });
8274
- hmrPages.clear();
8275
- const moduleEntries = [
8276
- ...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
8277
- ...vueModules,
8278
- ...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
8279
- ].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
8280
- updateServerWatcher();
8281
- return moduleEntries;
8282
- },
8283
- resolveId(id) {
8284
- if (id.startsWith("/@slidev/"))
8267
+ continue;
8268
+ }
8269
+ ctx.server.hot.send(
8270
+ "slidev:update-slide",
8271
+ {
8272
+ no: i + 1,
8273
+ data: withRenderedNote(newData.slides[i])
8274
+ }
8275
+ );
8276
+ hmrPages.add(i);
8277
+ }
8278
+ Object.assign(data, newData);
8279
+ Object.assign(utils, createDataUtils(newData, clientRoot, roots));
8280
+ if (hmrPages.size > 0)
8281
+ moduleIds.add(templateTitleRendererMd.id);
8282
+ const vueModules = Array.from(hmrPages).flatMap((idx) => {
8283
+ const frontmatter = ctx.server.moduleGraph.getModuleById(getSourceId(idx, "frontmatter"));
8284
+ const main = ctx.server.moduleGraph.getModuleById(getSourceId(idx, "md"));
8285
+ const styles = main ? [...main.clientImportedModules].find((m) => m.id?.includes(`&type=style`)) : void 0;
8286
+ return [
8287
+ frontmatter,
8288
+ main,
8289
+ styles
8290
+ ];
8291
+ });
8292
+ hmrPages.clear();
8293
+ const moduleEntries = [
8294
+ ...ctx.modules.filter((i) => i.id === templateMonacoRunDeps.id || i.id === templateMonacoTypes.id),
8295
+ ...vueModules,
8296
+ ...Array.from(moduleIds).map((id) => ctx.server.moduleGraph.getModuleById(id))
8297
+ ].filter(notNullish).filter((i) => !i.id?.startsWith("/@id/@vite-icons"));
8298
+ updateServerWatcher();
8299
+ return moduleEntries;
8300
+ },
8301
+ resolveId: {
8302
+ order: "pre",
8303
+ handler(id) {
8304
+ if (id.startsWith("/@slidev/") || id.includes("__slidev_"))
8285
8305
  return id;
8286
8306
  return null;
8287
- },
8288
- async load(id) {
8289
- const template = templates.find((i) => i.id === id);
8290
- if (template) {
8307
+ }
8308
+ },
8309
+ async load(id) {
8310
+ const template = templates.find((i) => i.id === id);
8311
+ if (template) {
8312
+ return {
8313
+ code: await template.getContent(options, templateCtx, this),
8314
+ map: { mappings: "" }
8315
+ };
8316
+ }
8317
+ const matchFacade = id.match(regexSlideFacadeId);
8318
+ if (matchFacade) {
8319
+ const [, no, type] = matchFacade;
8320
+ const idx = +no - 1;
8321
+ const sourceId = JSON.stringify(getSourceId(idx, type));
8322
+ return [
8323
+ `export * from ${sourceId}`,
8324
+ `export { default } from ${sourceId}`
8325
+ ].join("\n");
8326
+ }
8327
+ const matchSource = id.match(regexSlideSourceId);
8328
+ if (matchSource) {
8329
+ const [, no, type] = matchSource;
8330
+ const idx = +no - 1;
8331
+ const slide = data.slides[idx];
8332
+ if (!slide)
8333
+ return;
8334
+ if (type === "md") {
8291
8335
  return {
8292
- code: await template.getContent(options, templateCtx, this),
8336
+ code: slide.content,
8293
8337
  map: { mappings: "" }
8294
8338
  };
8295
- }
8296
- if (id.startsWith(VIRTUAL_SLIDE_PREFIX)) {
8297
- const remaning = id.slice(VIRTUAL_SLIDE_PREFIX.length);
8298
- const match = remaning.match(regexIdQuery);
8299
- if (match) {
8300
- const [, no, type] = match;
8301
- const pageNo = Number.parseInt(no) - 1;
8302
- const slide = data.slides[pageNo];
8303
- if (!slide)
8304
- return;
8305
- if (type === "md") {
8306
- return {
8307
- code: slide?.content,
8308
- map: { mappings: "" }
8309
- };
8310
- } else if (type === "frontmatter") {
8311
- const slideBase = {
8312
- ...withRenderedNote(slide),
8313
- frontmatter: void 0,
8314
- source: void 0,
8315
- importChain: void 0,
8316
- // remove raw content in build, optimize the bundle size
8317
- ...mode === "build" ? { raw: "", content: "", note: "" } : {}
8318
- };
8319
- const fontmatter = getFrontmatter(pageNo);
8320
- return {
8321
- code: [
8322
- "// @unocss-include",
8323
- 'import { computed, reactive, shallowReactive } from "vue"',
8324
- `export const frontmatterData = ${JSON.stringify(fontmatter)}`,
8325
- // handle HMR, update frontmatter with update
8326
- "if (import.meta.hot) {",
8327
- " const firstLoad = !import.meta.hot.data.frontmatter",
8328
- " import.meta.hot.data.frontmatter ??= reactive(frontmatterData)",
8329
- " import.meta.hot.accept(({ frontmatterData: update }) => {",
8330
- " if (firstLoad) return",
8331
- " const frontmatter = import.meta.hot.data.frontmatter",
8332
- " Object.keys(frontmatter).forEach(key => {",
8333
- " if (!(key in update)) delete frontmatter[key]",
8334
- " })",
8335
- " Object.assign(frontmatter, update)",
8336
- " })",
8337
- "}",
8338
- "export const frontmatter = import.meta.hot ? import.meta.hot.data.frontmatter : reactive(frontmatterData)",
8339
- "export default frontmatter",
8340
- "export const meta = shallowReactive({",
8341
- " get layout(){ return frontmatter.layout },",
8342
- " get transition(){ return frontmatter.transition },",
8343
- " get class(){ return frontmatter.class },",
8344
- " get clicks(){ return frontmatter.clicks },",
8345
- " get name(){ return frontmatter.name },",
8346
- " get preload(){ return frontmatter.preload },",
8347
- // No need to be reactive, as it's only used once after reload
8348
- " slide: {",
8349
- ` ...(${JSON.stringify(slideBase)}),`,
8350
- ` frontmatter,`,
8351
- ` filepath: ${JSON.stringify(mode === "dev" ? slide.source.filepath : "")},`,
8352
- ` start: ${JSON.stringify(slide.source.start)},`,
8353
- ` id: ${pageNo},`,
8354
- ` no: ${no},`,
8355
- " },",
8356
- " __clicksContext: null,",
8357
- " __preloaded: false,",
8358
- "})"
8359
- ].join("\n"),
8360
- map: { mappings: "" }
8361
- };
8362
- }
8363
- }
8339
+ } else if (type === "frontmatter") {
8340
+ const slideBase = {
8341
+ ...withRenderedNote(slide),
8342
+ frontmatter: void 0,
8343
+ source: void 0,
8344
+ importChain: void 0,
8345
+ // remove raw content in build, optimize the bundle size
8346
+ ...mode === "build" ? { raw: "", content: "", note: "" } : {}
8347
+ };
8348
+ const fontmatter = getFrontmatter(idx);
8364
8349
  return {
8365
- code: "",
8350
+ code: [
8351
+ "// @unocss-include",
8352
+ 'import { computed, reactive, shallowReactive } from "vue"',
8353
+ `export const frontmatterData = ${JSON.stringify(fontmatter)}`,
8354
+ // handle HMR, update frontmatter with update
8355
+ "if (import.meta.hot) {",
8356
+ " const firstLoad = !import.meta.hot.data.frontmatter",
8357
+ " import.meta.hot.data.frontmatter ??= reactive(frontmatterData)",
8358
+ " import.meta.hot.accept(({ frontmatterData: update }) => {",
8359
+ " if (firstLoad) return",
8360
+ " const frontmatter = import.meta.hot.data.frontmatter",
8361
+ " Object.keys(frontmatter).forEach(key => {",
8362
+ " if (!(key in update)) delete frontmatter[key]",
8363
+ " })",
8364
+ " Object.assign(frontmatter, update)",
8365
+ " })",
8366
+ "}",
8367
+ "export const frontmatter = import.meta.hot ? import.meta.hot.data.frontmatter : reactive(frontmatterData)",
8368
+ "export default frontmatter",
8369
+ "export const meta = shallowReactive({",
8370
+ " get layout(){ return frontmatter.layout },",
8371
+ " get transition(){ return frontmatter.transition },",
8372
+ " get class(){ return frontmatter.class },",
8373
+ " get clicks(){ return frontmatter.clicks },",
8374
+ " get name(){ return frontmatter.name },",
8375
+ " get preload(){ return frontmatter.preload },",
8376
+ // No need to be reactive, as it's only used once after reload
8377
+ " slide: {",
8378
+ ` ...(${JSON.stringify(slideBase)}),`,
8379
+ ` frontmatter,`,
8380
+ ` filepath: ${JSON.stringify(mode === "dev" ? slide.source.filepath : "")},`,
8381
+ ` start: ${JSON.stringify(slide.source.start)},`,
8382
+ ` id: ${idx},`,
8383
+ ` no: ${no},`,
8384
+ " },",
8385
+ " __clicksContext: null,",
8386
+ " __preloaded: false,",
8387
+ "})"
8388
+ ].join("\n"),
8366
8389
  map: { mappings: "" }
8367
8390
  };
8368
8391
  }
8369
8392
  }
8370
- },
8371
- {
8372
- name: "slidev:layout-transform:pre",
8373
- enforce: "pre",
8374
- async transform(code, id) {
8375
- if (!id.startsWith(VIRTUAL_SLIDE_PREFIX))
8376
- return;
8377
- const remaning = id.slice(VIRTUAL_SLIDE_PREFIX.length);
8378
- const match = remaning.match(regexIdQuery);
8379
- if (!match)
8380
- return;
8381
- const [, no, type] = match;
8382
- if (type !== "md")
8383
- return;
8384
- return transformMarkdown(code, +no - 1);
8385
- }
8386
- },
8387
- {
8388
- name: "slidev:context-transform:pre",
8389
- enforce: "pre",
8390
- async transform(code, id) {
8391
- if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
8392
- return;
8393
- return transformVue(code);
8394
- }
8395
- },
8396
- {
8397
- name: "slidev:slide-transform:post",
8398
- enforce: "post",
8399
- transform(code, id) {
8400
- if (!id.match(/\/@slidev\/slides\/\d+\.md($|\?)/))
8401
- return;
8402
- const replaced = code.replace("if (_rerender_only)", "if (false)");
8403
- if (replaced !== code)
8404
- return replaced;
8405
- }
8406
- }
8407
- ];
8408
- function updateServerWatcher() {
8409
- if (!server)
8410
- return;
8411
- server.watcher.add(data.watchFiles);
8412
- }
8413
- function getFrontmatter(pageNo) {
8414
- return {
8415
- ...data.headmatter?.defaults || {},
8416
- ...data.slides[pageNo]?.frontmatter || {}
8417
- };
8418
- }
8419
- async function transformMarkdown(code, index) {
8420
- const layouts = await templateCtx.getLayouts();
8421
- const frontmatter = getFrontmatter(index);
8422
- let layoutName = frontmatter?.layout || (index === 0 ? "cover" : "default");
8423
- if (!layouts[layoutName]) {
8424
- console.error(red(`
8425
- Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Object.keys(layouts).map((i, idx) => (idx % 3 === 0 ? "\n " : "") + gray(i.padEnd(15, " "))).join(" "));
8426
- console.error();
8427
- layoutName = "default";
8428
8393
  }
8429
- delete frontmatter.title;
8430
- const imports = [
8431
- `import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
8432
- templateImportContextUtils,
8433
- templateInitContext,
8434
- templateInjectionMarker
8435
- ];
8436
- code = code.replace(/(<script setup.*>)/g, `$1
8437
- ${imports.join("\n")}
8438
- `);
8439
- const injectA = code.indexOf("<template>") + "<template>".length;
8440
- const injectB = code.lastIndexOf("</template>");
8441
- let body = code.slice(injectA, injectB).trim();
8442
- if (body.startsWith("<div>") && body.endsWith("</div>"))
8443
- body = body.slice(5, -6);
8444
- code = `${code.slice(0, injectA)}
8445
- <InjectedLayout v-bind="_frontmatterToProps($frontmatter,${index})">
8446
- ${body}
8447
- </InjectedLayout>
8448
- ${code.slice(injectB)}`;
8449
- return code;
8450
- }
8451
- function transformVue(code) {
8452
- if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
8453
- return code;
8454
- const imports = [
8455
- templateImportContextUtils,
8456
- templateInitContext,
8457
- templateInjectionMarker
8458
- ];
8459
- const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
8460
- if (matchScript && matchScript[2]) {
8461
- return code.replace(/(<script.*>)/g, `$1
8462
- ${imports.join("\n")}
8463
- `);
8464
- } else if (matchScript && !matchScript[2]) {
8465
- const matchExport = code.match(/export\s+default\s+\{/);
8466
- if (matchExport) {
8467
- const exportIndex = (matchExport.index || 0) + matchExport[0].length;
8468
- let component = code.slice(exportIndex);
8469
- component = component.slice(0, component.indexOf("</script>"));
8470
- const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
8471
- const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
8472
- code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
8473
- let injectIndex = exportIndex + provideImport.length;
8474
- let injectObject = "$slidev: { from: injectionSlidevContext },";
8475
- const matchInject = component.match(/.*inject\s*:\s*([[{])/);
8476
- if (matchInject) {
8477
- injectIndex += (matchInject.index || 0) + matchInject[0].length;
8478
- if (matchInject[1] === "[") {
8479
- let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
8480
- const injectEndIndex = injects.indexOf("]");
8481
- injects = injects.slice(0, injectEndIndex);
8482
- injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
8483
- return `${code.slice(0, injectIndex - 1)}{
8484
- ${injectObject}
8485
- }${code.slice(injectIndex + injectEndIndex + 1)}`;
8486
- } else {
8487
- return `${code.slice(0, injectIndex)}
8488
- ${injectObject}
8489
- ${code.slice(injectIndex)}`;
8490
- }
8491
- }
8492
- return `${code.slice(0, injectIndex)}
8493
- inject: { ${injectObject} },
8494
- ${code.slice(injectIndex)}`;
8495
- }
8496
- }
8497
- return `<script setup>
8498
- ${imports.join("\n")}
8499
- </script>
8500
- ${code}`;
8501
- }
8394
+ };
8502
8395
  }
8503
8396
 
8504
8397
  // node/vite/unocss.ts
@@ -8890,7 +8783,7 @@ function loadPrismPlugin(name) {
8890
8783
  try {
8891
8784
  require2(`prismjs/plugins/${name}/prism-${name}`);
8892
8785
  } catch (e) {
8893
- throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`);
8786
+ throw new Error(`Cannot load Prism plugin "${name}". Please check the spelling.`, { cause: e });
8894
8787
  }
8895
8788
  }
8896
8789
  function selectLanguage(options, lang) {
@@ -8994,7 +8887,7 @@ function markdownItVDrag(md, markdownTransformMap) {
8994
8887
  }
8995
8888
 
8996
8889
  // node/syntax/transform/code-wrapper.ts
8997
- var reCodeBlock = /^```([\w'-]+)(?:\s*\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n(\S[\s\S]*?)^```$/gm;
8890
+ var reCodeBlock = /^```([\w'-]+)?\s*(?:\{([\w*,|-]+)\}\s*?(\{[^}]*\})?([^\r\n]*))?\r?\n(\S[\s\S]*?)^```$/gm;
8998
8891
  function transformCodeWrapper(ctx) {
8999
8892
  ctx.s.replace(
9000
8893
  reCodeBlock,
@@ -9095,7 +8988,7 @@ function createMonacoWriter({ userRoot }) {
9095
8988
  let json;
9096
8989
  try {
9097
8990
  json = JSON.parse(data.toString());
9098
- } catch (e) {
8991
+ } catch {
9099
8992
  return;
9100
8993
  }
9101
8994
  if (json.type === "custom" && json.event === "slidev:monaco-write") {
@@ -9598,6 +9491,130 @@ async function createVuePlugin(options, pluginOptions) {
9598
9491
  ];
9599
9492
  }
9600
9493
 
9494
+ // node/vite/layoutWrapper.ts
9495
+ import { bold, gray, red, yellow } from "kolorist";
9496
+ function createLayoutWrapperPlugin({ data, utils }) {
9497
+ return {
9498
+ name: "slidev:layout-wrapper",
9499
+ async transform(code, id) {
9500
+ const match = id.match(regexSlideSourceId);
9501
+ if (!match)
9502
+ return;
9503
+ const [, no, type] = match;
9504
+ if (type !== "md")
9505
+ return;
9506
+ const index = +no - 1;
9507
+ const layouts = await utils.getLayouts();
9508
+ const rawLayoutName = data.slides[index]?.frontmatter?.layout ?? data.slides[0]?.frontmatter?.default?.layout;
9509
+ let layoutName = rawLayoutName || (index === 0 ? "cover" : "default");
9510
+ if (!layouts[layoutName]) {
9511
+ console.error(red(`
9512
+ Unknown layout "${bold(layoutName)}".${yellow(" Available layouts are:")}`) + Object.keys(layouts).map((i, idx) => (idx % 3 === 0 ? "\n " : "") + gray(i.padEnd(15, " "))).join(" "));
9513
+ console.error();
9514
+ layoutName = "default";
9515
+ }
9516
+ const setupTag = code.match(/^<script setup.*>/m);
9517
+ if (!setupTag)
9518
+ throw new Error(`[Slidev] Internal error: <script setup> block not found in slide ${index + 1}.`);
9519
+ const templatePart = code.slice(0, setupTag.index);
9520
+ const scriptPart = code.slice(setupTag.index);
9521
+ const bodyStart = templatePart.indexOf("<template>") + 10;
9522
+ const bodyEnd = templatePart.lastIndexOf("</template>");
9523
+ let body = code.slice(bodyStart, bodyEnd).trim();
9524
+ if (body.startsWith("<div>") && body.endsWith("</div>"))
9525
+ body = body.slice(5, -6);
9526
+ return [
9527
+ templatePart.slice(0, bodyStart),
9528
+ `<InjectedLayout v-bind="_frontmatterToProps($frontmatter,${index})">
9529
+ ${body}
9530
+ </InjectedLayout>`,
9531
+ templatePart.slice(bodyEnd),
9532
+ scriptPart.slice(0, setupTag[0].length),
9533
+ `import InjectedLayout from "${toAtFS(layouts[layoutName])}"`,
9534
+ templateImportContextUtils,
9535
+ templateInitContext,
9536
+ "$clicksContext.setup()",
9537
+ templateInjectionMarker,
9538
+ scriptPart.slice(setupTag[0].length)
9539
+ ].join("\n");
9540
+ }
9541
+ };
9542
+ }
9543
+
9544
+ // node/vite/contextInjection.ts
9545
+ function createContextInjectionPlugin() {
9546
+ return {
9547
+ name: "slidev:context-injection",
9548
+ async transform(code, id) {
9549
+ if (!id.endsWith(".vue") || id.includes("/@slidev/client/") || id.includes("/packages/client/"))
9550
+ return;
9551
+ if (code.includes(templateInjectionMarker) || code.includes("useSlideContext()"))
9552
+ return code;
9553
+ const imports = [
9554
+ templateImportContextUtils,
9555
+ templateInitContext,
9556
+ templateInjectionMarker
9557
+ ];
9558
+ const matchScript = code.match(/<script((?!setup).)*(setup)?.*>/);
9559
+ if (matchScript && matchScript[2]) {
9560
+ return code.replace(/(<script.*>)/g, `$1
9561
+ ${imports.join("\n")}
9562
+ `);
9563
+ } else if (matchScript && !matchScript[2]) {
9564
+ const matchExport = code.match(/export\s+default\s+\{/);
9565
+ if (matchExport) {
9566
+ const exportIndex = (matchExport.index || 0) + matchExport[0].length;
9567
+ let component = code.slice(exportIndex);
9568
+ component = component.slice(0, component.indexOf("</script>"));
9569
+ const scriptIndex = (matchScript.index || 0) + matchScript[0].length;
9570
+ const provideImport = '\nimport { injectionSlidevContext } from "@slidev/client/constants.ts"\n';
9571
+ code = `${code.slice(0, scriptIndex)}${provideImport}${code.slice(scriptIndex)}`;
9572
+ let injectIndex = exportIndex + provideImport.length;
9573
+ let injectObject = "$slidev: { from: injectionSlidevContext },";
9574
+ const matchInject = component.match(/.*inject\s*:\s*([[{])/);
9575
+ if (matchInject) {
9576
+ injectIndex += (matchInject.index || 0) + matchInject[0].length;
9577
+ if (matchInject[1] === "[") {
9578
+ let injects = component.slice((matchInject.index || 0) + matchInject[0].length);
9579
+ const injectEndIndex = injects.indexOf("]");
9580
+ injects = injects.slice(0, injectEndIndex);
9581
+ injectObject += injects.split(",").map((inject) => `${inject}: {from: ${inject}}`).join(",");
9582
+ return `${code.slice(0, injectIndex - 1)}{
9583
+ ${injectObject}
9584
+ }${code.slice(injectIndex + injectEndIndex + 1)}`;
9585
+ } else {
9586
+ return `${code.slice(0, injectIndex)}
9587
+ ${injectObject}
9588
+ ${code.slice(injectIndex)}`;
9589
+ }
9590
+ }
9591
+ return `${code.slice(0, injectIndex)}
9592
+ inject: { ${injectObject} },
9593
+ ${code.slice(injectIndex)}`;
9594
+ }
9595
+ }
9596
+ return `<script setup>
9597
+ ${imports.join("\n")}
9598
+ </script>
9599
+ ${code}`;
9600
+ }
9601
+ };
9602
+ }
9603
+
9604
+ // node/vite/hmrPatch.ts
9605
+ function createHmrPatchPlugin() {
9606
+ return {
9607
+ name: "slidev:slide-transform:post",
9608
+ transform(code, id) {
9609
+ if (!id.match(regexSlideSourceId))
9610
+ return;
9611
+ const replaced = code.replace("if (_rerender_only)", "if (false)");
9612
+ if (replaced !== code)
9613
+ return replaced;
9614
+ }
9615
+ };
9616
+ }
9617
+
9601
9618
  // node/vite/index.ts
9602
9619
  async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9603
9620
  const {
@@ -9616,10 +9633,12 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9616
9633
  const drawingData = await loadDrawings(options);
9617
9634
  const publicRoots = [...themeRoots, ...addonRoots].map((i) => join9(i, "public")).filter(existsSync6);
9618
9635
  const plugins = [
9636
+ createSlidesLoader(options, serverOptions),
9619
9637
  createMarkdownPlugin(options, pluginOptions),
9638
+ createLayoutWrapperPlugin(options),
9639
+ createContextInjectionPlugin(),
9620
9640
  createVuePlugin(options, pluginOptions),
9621
- createSlidesLoader(options, pluginOptions, serverOptions),
9622
- createMonacoWriter(options),
9641
+ createHmrPatchPlugin(),
9623
9642
  Components({
9624
9643
  extensions: ["vue", "md", "js", "ts", "jsx", "tsx"],
9625
9644
  dirs: [
@@ -9642,7 +9661,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9642
9661
  }),
9643
9662
  Icons({
9644
9663
  defaultClass: "slidev-icon",
9645
- collectionsNodeResolvePath: fileURLToPath4(import.meta.url),
9664
+ collectionsNodeResolvePath: options.cliRoot,
9646
9665
  ...iconsOptions
9647
9666
  }),
9648
9667
  config.remoteAssets === true || config.remoteAssets === mode ? import("vite-plugin-remote-assets").then((r) => r.VitePluginRemoteAssets({
@@ -9670,7 +9689,8 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9670
9689
  ...serverRefOptions.state
9671
9690
  },
9672
9691
  onChanged(key, data, patch, timestamp) {
9673
- serverRefOptions.onChanged && serverRefOptions.onChanged(key, data, patch, timestamp);
9692
+ if (serverRefOptions.onChanged)
9693
+ serverRefOptions.onChanged(key, data, patch, timestamp);
9674
9694
  if (!options.data.config.drawings.persist)
9675
9695
  return;
9676
9696
  if (key === "drawings")
@@ -9679,6 +9699,7 @@ async function ViteSlidevPlugin(options, pluginOptions, serverOptions = {}) {
9679
9699
  }),
9680
9700
  createConfigPlugin(options),
9681
9701
  createMonacoTypesLoader(options),
9702
+ createMonacoWriter(options),
9682
9703
  createVueCompilerFlagsPlugin(options),
9683
9704
  createUnocssPlugin(options, pluginOptions),
9684
9705
  publicRoots.length ? import("vite-plugin-static-copy").then((r) => r.viteStaticCopy({
package/dist/cli.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-X5LWKCT6.mjs";
3
+ } from "./chunk-KRQVQU6O.mjs";
4
4
  import {
5
5
  getThemeMeta,
6
6
  loadSetups,
@@ -9,7 +9,7 @@ import {
9
9
  resolveOptions,
10
10
  resolveTheme,
11
11
  version
12
- } from "./chunk-VAXCTWQX.mjs";
12
+ } from "./chunk-T42M3I2X.mjs";
13
13
  import {
14
14
  getRoots,
15
15
  isInstalledGlobally,
@@ -325,7 +325,7 @@ cli.command(
325
325
  }).strict().help(),
326
326
  async (args) => {
327
327
  const { entry, theme, base, download, out, inspect } = args;
328
- const { build } = await import("./build-J45HACJD.mjs");
328
+ const { build } = await import("./build-OXWIETNK.mjs");
329
329
  for (const entryFile of entry) {
330
330
  const options = await resolveOptions({ entry: entryFile, theme, inspect }, "build");
331
331
  if (download && !options.data.config.download)
package/dist/index.d.mts CHANGED
@@ -9,6 +9,6 @@ declare function ViteSlidevPlugin(options: ResolvedSlidevOptions, pluginOptions:
9
9
  declare function createServer(options: ResolvedSlidevOptions, viteConfig?: InlineConfig, serverOptions?: SlidevServerOptions): Promise<vite.ViteDevServer>;
10
10
 
11
11
  declare function resolveOptions(options: SlidevEntryOptions, mode: ResolvedSlidevOptions['mode']): Promise<ResolvedSlidevOptions>;
12
- declare function createDataUtils(data: SlidevData): ResolvedSlidevUtils;
12
+ declare function createDataUtils(data: SlidevData, clientRoot: string, roots: string[]): ResolvedSlidevUtils;
13
13
 
14
14
  export { ViteSlidevPlugin, createDataUtils, createServer, resolveOptions };
package/dist/index.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  createServer
3
- } from "./chunk-X5LWKCT6.mjs";
3
+ } from "./chunk-KRQVQU6O.mjs";
4
4
  import {
5
5
  ViteSlidevPlugin,
6
6
  createDataUtils,
7
7
  parser,
8
8
  resolveOptions
9
- } from "./chunk-VAXCTWQX.mjs";
9
+ } from "./chunk-T42M3I2X.mjs";
10
10
  import "./chunk-27Q2X57X.mjs";
11
11
  export {
12
12
  ViteSlidevPlugin,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@slidev/cli",
3
- "version": "0.49.15",
3
+ "version": "0.49.17",
4
4
  "description": "Presentation slides for developers",
5
5
  "author": "antfu <anthonyfu117@hotmail.com>",
6
6
  "license": "MIT",
@@ -48,11 +48,11 @@
48
48
  "@iconify-json/ph": "^1.1.13",
49
49
  "@iconify-json/svg-spinners": "^1.1.2",
50
50
  "@lillallol/outline-pdf": "^4.0.0",
51
- "@shikijs/markdown-it": "^1.10.0",
52
- "@shikijs/twoslash": "^1.10.0",
53
- "@shikijs/vitepress-twoslash": "^1.10.0",
54
- "@unocss/extractor-mdc": "^0.61.2",
55
- "@unocss/reset": "^0.61.2",
51
+ "@shikijs/markdown-it": "^1.10.3",
52
+ "@shikijs/twoslash": "^1.10.3",
53
+ "@shikijs/vitepress-twoslash": "^1.10.3",
54
+ "@unocss/extractor-mdc": "^0.61.3",
55
+ "@unocss/reset": "^0.61.3",
56
56
  "@vitejs/plugin-vue": "^5.0.5",
57
57
  "@vitejs/plugin-vue-jsx": "^4.0.0",
58
58
  "chokidar": "^3.6.0",
@@ -67,7 +67,7 @@
67
67
  "htmlparser2": "^9.1.0",
68
68
  "is-installed-globally": "^1.0.0",
69
69
  "jiti": "^1.21.6",
70
- "katex": "^0.16.10",
70
+ "katex": "^0.16.11",
71
71
  "kolorist": "^1.8.0",
72
72
  "local-pkg": "^0.5.0",
73
73
  "lz-string": "^1.5.0",
@@ -90,28 +90,28 @@
90
90
  "resolve-from": "^5.0.0",
91
91
  "resolve-global": "^2.0.0",
92
92
  "semver": "^7.6.2",
93
- "shiki": "^1.10.0",
93
+ "shiki": "^1.10.3",
94
94
  "shiki-magic-move": "^0.4.2",
95
95
  "sirv": "^2.0.4",
96
96
  "source-map-js": "^1.2.0",
97
- "typescript": "^5.5.2",
98
- "unocss": "^0.61.2",
97
+ "typescript": "^5.5.3",
98
+ "unocss": "^0.61.3",
99
99
  "unplugin-icons": "^0.19.0",
100
100
  "unplugin-vue-components": "^0.27.2",
101
101
  "unplugin-vue-markdown": "^0.26.2",
102
102
  "untun": "^0.1.3",
103
103
  "uqr": "^0.1.2",
104
- "vite": "^5.3.2",
104
+ "vite": "^5.3.3",
105
105
  "vite-plugin-inspect": "^0.8.4",
106
- "vite-plugin-remote-assets": "^0.4.1",
107
- "vite-plugin-static-copy": "^1.0.5",
106
+ "vite-plugin-remote-assets": "^0.5.0",
107
+ "vite-plugin-static-copy": "^1.0.6",
108
108
  "vite-plugin-vue-server-ref": "^0.4.2",
109
109
  "vitefu": "^0.2.5",
110
- "vue": "^3.4.31",
110
+ "vue": "^3.4.32",
111
111
  "yargs": "^17.7.2",
112
- "@slidev/client": "0.49.15",
113
- "@slidev/types": "0.49.15",
114
- "@slidev/parser": "0.49.15"
112
+ "@slidev/parser": "0.49.17",
113
+ "@slidev/types": "0.49.17",
114
+ "@slidev/client": "0.49.17"
115
115
  },
116
116
  "devDependencies": {
117
117
  "@hedgedoc/markdown-it-plugins": "^2.1.4",
package/template.md CHANGED
@@ -6,7 +6,7 @@ theme: seriph
6
6
  background: https://cover.sli.dev
7
7
  # apply any unocss classes to the current slide
8
8
  class: 'text-center'
9
- # https://sli.dev/custom/highlighters.html
9
+ # https://sli.dev/custom/config-highlighter.html
10
10
  highlighter: shiki
11
11
  # some information about the slides, markdown enabled
12
12
  info: |
@@ -115,7 +115,7 @@ Hover on the bottom-left corner to see the navigation's control panel, [learn mo
115
115
  | <kbd>up</kbd> | previous slide |
116
116
  | <kbd>down</kbd> | next slide |
117
117
 
118
- <!-- https://sli.dev/guide/animations.html#click-animations -->
118
+ <!-- https://sli.dev/guide/animations.html#click-animation -->
119
119
  <img
120
120
  v-click
121
121
  class="absolute -bottom-9 -left-7 w-80 opacity-50"