@deot/docs-playground 1.1.7 → 1.1.9

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
@@ -145,6 +145,7 @@ const handleMessage = async () => {
145
145
  | `slugifyPlaygroundTitle(title)` / `resolvePlaygroundTitleId(title, id?)` | 标题锚点 id,规则对齐 markdown-it-anchor。 |
146
146
  | `DEFAULT_CDN_URL` | 默认 CDN 根地址(jsDelivr)。 |
147
147
  | `createBuiltinImports(cdnURL?)` / `createBuiltinStyles(cdnURL?)` | 按 CDN 生成内置 import map 与预览样式表 URL。 |
148
+ | `resolveCdnURL(url, cdnURL?, config?)` | 内置转换后调用可选 `resolve.cdn`;默认读取当前站点配置。 |
148
149
  | `normalizeCdnURL(value?)` | 规范化 CDN 根地址。 |
149
150
 
150
151
  同时导出 `PlaygroundFiles`、`PlaygroundView`、`PlaygroundViewport`、`PlaygroundOptions`、`PlaygroundPreviewOptions`、`EditorFilesChange` 和 `EditorFilesChangeAction` 类型。
@@ -154,9 +155,9 @@ const handleMessage = async () => {
154
155
  ## 运行环境
155
156
 
156
157
  - iframe 运行时通过公共 CDN 加载 Vue 和默认 import map 中的依赖;local 运行时加载 URL 覆盖或宿主未提供的模块时也需要网络访问。
157
- - 默认 CDN 为 `https://cdn.jsdelivr.net/npm`,可通过 `options.cdnURL` 换成 unpkg 等兼容 `/{package}/{file}` 路径的镜像;该地址用于预览样式和内置 import map。
158
- - `lodash-es` 和在线 Sass 编译器使用 jsDelivr 的 `/+esm` 入口;unpkg 等 CDN 不支持该路径。
159
- - 直接渲染时,宿主未提供且未配置的 npm 模块(含作用域包和子路径)自动从 jsDelivr 的 `/+esm` 入口加载;组件包的传递依赖也适用,`import()` 在调用时加载。可用 `options.builtinImportMap.imports` 指定依赖的版本和 URL。
158
+ - 默认 CDN 为 `https://cdn.jsdelivr.net/npm`;未使用 launch 时可通过 `options.cdnURL` 调整默认节点。launch 已选点时统一使用 `$docs.runtime.cdn`,优先于实例 `cdnURL`。
159
+ - jsDelivr npm、旧 `unpkg.com` 和 `esm.unpkg.com` 地址在实际加载时转换,再经过可选 `$docs.resolve.cdn({ url })`。jsDelivr 转换入口使用 `/+esm`,ESM UNPKG 使用包或文件入口。预览 CSS、import map、裸包回退和 Sass 共用该规则;原始映射与缓存不被改写。
160
+ - 直接渲染时,宿主未提供且未配置的 npm 模块(含作用域包和子路径)自动通过上述 ESM 规则加载;组件包的传递依赖也适用,`import()` 在调用时加载。可用 `options.builtinImportMap.imports` 指定依赖的版本和 URL。
160
161
  - Vue SFC 的 `<style lang="scss">` / `lang="sass"` 以及独立 `.scss` / `.sass` 文件会在浏览器里编译;`_partial.scss` 只作为 `@use` 依赖。
161
162
  - local 模式按模块识别显式 URL 覆盖,即使地址与内置默认相同也会加载该 URL。覆盖 `vue` 时,预览的编译产物、挂载、组件引用和注入使用这份 Vue;内置组件、hooks、locale、Pinia 和 vue-router 随之重新加载以匹配 Vue,未覆盖的普通工具模块继续复用宿主。不同预览的覆盖互不影响,显式覆盖的模块在各自预览内执行。
162
163
  - local 模式在当前页面按 URL 缓存外部模块的下载和转换成果,并合并并发请求;切换文档时可复用,最多保留最近使用的 128 个模块。各预览仍独立执行模块并解析依赖覆盖;失败的加载不缓存,同源模块实时读取,刷新页面会清空缓存。
@@ -1,4 +1,4 @@
1
- import { a as transformScript, c as createFileIndex, h as resolveEntry, m as normalizeVirtualPath, s as collectReachableFilenames, t as collectCss, u as getExtension, v as compileScssSource, y as extractScssExports } from "./css-DleINdoA.js";
1
+ import { a as transformScript, c as createFileIndex, h as resolveEntry, m as normalizeVirtualPath, s as collectReachableFilenames, t as collectCss, u as getExtension, v as compileScssSource, y as extractScssExports } from "./css-D47JLekg.js";
2
2
  import { compileString } from "sass";
3
3
  //#region packages/playground/src/core/runtime/local/compile/scss.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_css = require("./css-DpqJBQ5c.cjs");
1
+ const require_css = require("./css-DGNVJsLz.cjs");
2
2
  let sass = require("sass");
3
3
  //#region packages/playground/src/core/runtime/local/compile/scss.ts
4
4
  /**
@@ -8,6 +8,7 @@ var DEFAULT_CDN_URL = "https://cdn.jsdelivr.net/npm";
8
8
  var NEW_SFC_CODE = `<script setup lang="ts"><\/script>\n\n<template>\n <div>\n <slot />\n <\/div>\n<\/template>\n`;
9
9
  //#endregion
10
10
  //#region packages/playground/src/cdn.ts
11
+ var DOCS_ESM_ENTRY = /^@deot\/docs-(?:client|locale|markdown|playground|renderer|theme)$/u;
11
12
  var PREVIEW_STYLE_ASSETS = [
12
13
  "@deot/style/dist/index.normalize-only.css",
13
14
  "@deot/vc-components/dist/index.style.css",
@@ -53,6 +54,53 @@ var createBuiltinImports = (cdnURL = DEFAULT_CDN_URL) => ({
53
54
  });
54
55
  var createBuiltinStyles = (cdnURL = DEFAULT_CDN_URL) => Object.fromEntries(PREVIEW_STYLE_ASSETS.map((asset) => [asset, cdnAsset(cdnURL, asset)]));
55
56
  var resolveNpmImport = (specifier) => /^https?:\/\//.test(specifier) ? specifier : jsdelivrEsmURL(`${specifier}/+esm`);
57
+ var docsCdnConfig = () => globalThis.window?.$docs || {};
58
+ var npmCdnUrl = (value) => {
59
+ if (!/^https?:\/\//i.test(value)) return null;
60
+ const url = new URL(value);
61
+ const prefix = /(?:^|\.)jsdelivr\.net$/u.test(url.hostname) && url.pathname.startsWith("/npm/") ? "/npm/" : /^(?:esm\.)?unpkg\.com$/u.test(url.hostname) ? "/" : null;
62
+ if (!prefix) return null;
63
+ const asset = url.pathname.slice(prefix.length);
64
+ const match = asset.match(/^((?:@[^/]+\/)?[^/]+)(.*)$/u);
65
+ return match ? {
66
+ url,
67
+ asset,
68
+ name: match[1].replace(/@[^/@]+$/u, ""),
69
+ path: match[2]
70
+ } : null;
71
+ };
72
+ var cdnModuleName = (url) => {
73
+ const parsed = npmCdnUrl(url);
74
+ return parsed && (!parsed.path || parsed.path === "/+esm" || DOCS_ESM_ENTRY.test(parsed.name) && parsed.path === "/dist/index.js" || /^\/(?:es\d+|esnext)\/[^/]+\.m?js$/u.test(parsed.path)) ? parsed.name : null;
75
+ };
76
+ var isCdnEsmURL = (url) => /\/\+esm(?:[?#]|$)/u.test(url) || npmCdnUrl(url)?.url.hostname === "esm.unpkg.com";
77
+ var resolveCdnURL = (url, cdnURL, config = docsCdnConfig()) => {
78
+ const parsed = npmCdnUrl(url);
79
+ const target = config.runtime?.cdn || cdnURL;
80
+ let converted = url;
81
+ if (parsed && target) {
82
+ const origin = normalizeCdnURL(target);
83
+ const unpkg = new URL(origin).hostname === "esm.unpkg.com";
84
+ let asset = parsed.asset;
85
+ if (unpkg) {
86
+ asset = asset.replace(/\/\+esm$/u, "");
87
+ if (DOCS_ESM_ENTRY.test(parsed.name) && (!parsed.path || parsed.path === "/+esm")) asset += "/dist/index.js";
88
+ } else if (!parsed.path.endsWith("/+esm") && (!parsed.path || !/\.[^/]+$/u.test(parsed.path) || /unpkg\.com$/u.test(parsed.url.hostname) && /\.[cm]?[jt]sx?$/u.test(parsed.path))) asset = `${asset.replace(/\/+$/u, "")}/+esm`;
89
+ converted = `${origin}/${asset}${parsed.url.search}${parsed.url.hash}`;
90
+ }
91
+ return config.resolve?.cdn?.({ url: converted }) || converted;
92
+ };
93
+ var createCdnResolver = (cdnURL) => {
94
+ const resolved = /* @__PURE__ */ new Map();
95
+ return (url) => {
96
+ if (!resolved.has(url)) {
97
+ const target = resolveCdnURL(url, cdnURL);
98
+ resolved.set(url, target);
99
+ resolved.set(target, target);
100
+ }
101
+ return resolved.get(url);
102
+ };
103
+ };
56
104
  //#endregion
57
105
  //#region packages/playground/src/core/scss.ts
58
106
  var SCHEME = "docs-playground";
@@ -84,7 +132,7 @@ var resolveSassModule = async (url) => {
84
132
  return sass;
85
133
  };
86
134
  var loadSass = () => {
87
- loadPromise ??= (() => resolveSassModule(SASS_CDN_URL))().then((sass) => {
135
+ loadPromise ??= (() => resolveSassModule(resolveCdnURL(SASS_CDN_URL)))().then((sass) => {
88
136
  loadedSass = sass;
89
137
  return sass;
90
138
  });
@@ -577,4 +625,4 @@ var removeStyle = (id) => {
577
625
  document.querySelector(`style[data-playground-id="${id}"]`)?.remove();
578
626
  };
579
627
  //#endregion
580
- export { normalizeCdnURL as C, NEW_SFC_CODE as D, DEFAULT_ENTRY as E, createBuiltinStyles as S, DEFAULT_CDN_URL as T, bindPlaygroundScss as _, transformScript as a, whenSassReady as b, createFileIndex as c, isIgnoredFilename as d, isInsideRoot as f, resolveModulePath as g, resolveEntry as h, rewriteImportMeta as i, getCommonRoot as l, normalizeVirtualPath as m, injectStyle as n, collectBareSpecifiers as o, isRelativeSpecifier as p, removeStyle as r, collectReachableFilenames as s, collectCss as t, getExtension as u, compileScssSource as v, resolveNpmImport as w, createBuiltinImports as x, extractScssExports as y };
628
+ export { DEFAULT_ENTRY as A, createBuiltinStyles as C, resolveCdnURL as D, normalizeCdnURL as E, resolveNpmImport as O, createBuiltinImports as S, isCdnEsmURL as T, bindPlaygroundScss as _, transformScript as a, whenSassReady as b, createFileIndex as c, isIgnoredFilename as d, isInsideRoot as f, resolveModulePath as g, resolveEntry as h, rewriteImportMeta as i, NEW_SFC_CODE as j, DEFAULT_CDN_URL as k, getCommonRoot as l, normalizeVirtualPath as m, injectStyle as n, collectBareSpecifiers as o, isRelativeSpecifier as p, removeStyle as r, collectReachableFilenames as s, collectCss as t, getExtension as u, compileScssSource as v, createCdnResolver as w, cdnModuleName as x, extractScssExports as y };
@@ -40,6 +40,7 @@ var DEFAULT_CDN_URL = "https://cdn.jsdelivr.net/npm";
40
40
  var NEW_SFC_CODE = `<script setup lang="ts"><\/script>\n\n<template>\n <div>\n <slot />\n <\/div>\n<\/template>\n`;
41
41
  //#endregion
42
42
  //#region packages/playground/src/cdn.ts
43
+ var DOCS_ESM_ENTRY = /^@deot\/docs-(?:client|locale|markdown|playground|renderer|theme)$/u;
43
44
  var PREVIEW_STYLE_ASSETS = [
44
45
  "@deot/style/dist/index.normalize-only.css",
45
46
  "@deot/vc-components/dist/index.style.css",
@@ -85,6 +86,53 @@ var createBuiltinImports = (cdnURL = DEFAULT_CDN_URL) => ({
85
86
  });
86
87
  var createBuiltinStyles = (cdnURL = DEFAULT_CDN_URL) => Object.fromEntries(PREVIEW_STYLE_ASSETS.map((asset) => [asset, cdnAsset(cdnURL, asset)]));
87
88
  var resolveNpmImport = (specifier) => /^https?:\/\//.test(specifier) ? specifier : jsdelivrEsmURL(`${specifier}/+esm`);
89
+ var docsCdnConfig = () => globalThis.window?.$docs || {};
90
+ var npmCdnUrl = (value) => {
91
+ if (!/^https?:\/\//i.test(value)) return null;
92
+ const url = new URL(value);
93
+ const prefix = /(?:^|\.)jsdelivr\.net$/u.test(url.hostname) && url.pathname.startsWith("/npm/") ? "/npm/" : /^(?:esm\.)?unpkg\.com$/u.test(url.hostname) ? "/" : null;
94
+ if (!prefix) return null;
95
+ const asset = url.pathname.slice(prefix.length);
96
+ const match = asset.match(/^((?:@[^/]+\/)?[^/]+)(.*)$/u);
97
+ return match ? {
98
+ url,
99
+ asset,
100
+ name: match[1].replace(/@[^/@]+$/u, ""),
101
+ path: match[2]
102
+ } : null;
103
+ };
104
+ var cdnModuleName = (url) => {
105
+ const parsed = npmCdnUrl(url);
106
+ return parsed && (!parsed.path || parsed.path === "/+esm" || DOCS_ESM_ENTRY.test(parsed.name) && parsed.path === "/dist/index.js" || /^\/(?:es\d+|esnext)\/[^/]+\.m?js$/u.test(parsed.path)) ? parsed.name : null;
107
+ };
108
+ var isCdnEsmURL = (url) => /\/\+esm(?:[?#]|$)/u.test(url) || npmCdnUrl(url)?.url.hostname === "esm.unpkg.com";
109
+ var resolveCdnURL = (url, cdnURL, config = docsCdnConfig()) => {
110
+ const parsed = npmCdnUrl(url);
111
+ const target = config.runtime?.cdn || cdnURL;
112
+ let converted = url;
113
+ if (parsed && target) {
114
+ const origin = normalizeCdnURL(target);
115
+ const unpkg = new URL(origin).hostname === "esm.unpkg.com";
116
+ let asset = parsed.asset;
117
+ if (unpkg) {
118
+ asset = asset.replace(/\/\+esm$/u, "");
119
+ if (DOCS_ESM_ENTRY.test(parsed.name) && (!parsed.path || parsed.path === "/+esm")) asset += "/dist/index.js";
120
+ } else if (!parsed.path.endsWith("/+esm") && (!parsed.path || !/\.[^/]+$/u.test(parsed.path) || /unpkg\.com$/u.test(parsed.url.hostname) && /\.[cm]?[jt]sx?$/u.test(parsed.path))) asset = `${asset.replace(/\/+$/u, "")}/+esm`;
121
+ converted = `${origin}/${asset}${parsed.url.search}${parsed.url.hash}`;
122
+ }
123
+ return config.resolve?.cdn?.({ url: converted }) || converted;
124
+ };
125
+ var createCdnResolver = (cdnURL) => {
126
+ const resolved = /* @__PURE__ */ new Map();
127
+ return (url) => {
128
+ if (!resolved.has(url)) {
129
+ const target = resolveCdnURL(url, cdnURL);
130
+ resolved.set(url, target);
131
+ resolved.set(target, target);
132
+ }
133
+ return resolved.get(url);
134
+ };
135
+ };
88
136
  //#endregion
89
137
  //#region packages/playground/src/core/scss.ts
90
138
  var SCHEME = "docs-playground";
@@ -117,7 +165,7 @@ var resolveSassModule = async (url) => {
117
165
  return sass;
118
166
  };
119
167
  var loadSass = () => {
120
- loadPromise ??= (testLoader ?? (() => resolveSassModule(SASS_CDN_URL)))().then((sass) => {
168
+ loadPromise ??= (testLoader ?? (() => resolveSassModule(resolveCdnURL(SASS_CDN_URL))))().then((sass) => {
121
169
  loadedSass = sass;
122
170
  return sass;
123
171
  });
@@ -646,6 +694,12 @@ Object.defineProperty(exports, "bindPlaygroundScss", {
646
694
  return bindPlaygroundScss;
647
695
  }
648
696
  });
697
+ Object.defineProperty(exports, "cdnModuleName", {
698
+ enumerable: true,
699
+ get: function() {
700
+ return cdnModuleName;
701
+ }
702
+ });
649
703
  Object.defineProperty(exports, "collectBareSpecifiers", {
650
704
  enumerable: true,
651
705
  get: function() {
@@ -682,6 +736,12 @@ Object.defineProperty(exports, "createBuiltinStyles", {
682
736
  return createBuiltinStyles;
683
737
  }
684
738
  });
739
+ Object.defineProperty(exports, "createCdnResolver", {
740
+ enumerable: true,
741
+ get: function() {
742
+ return createCdnResolver;
743
+ }
744
+ });
685
745
  Object.defineProperty(exports, "createFileIndex", {
686
746
  enumerable: true,
687
747
  get: function() {
@@ -712,6 +772,12 @@ Object.defineProperty(exports, "injectStyle", {
712
772
  return injectStyle;
713
773
  }
714
774
  });
775
+ Object.defineProperty(exports, "isCdnEsmURL", {
776
+ enumerable: true,
777
+ get: function() {
778
+ return isCdnEsmURL;
779
+ }
780
+ });
715
781
  Object.defineProperty(exports, "isIgnoredFilename", {
716
782
  enumerable: true,
717
783
  get: function() {
@@ -748,6 +814,12 @@ Object.defineProperty(exports, "removeStyle", {
748
814
  return removeStyle;
749
815
  }
750
816
  });
817
+ Object.defineProperty(exports, "resolveCdnURL", {
818
+ enumerable: true,
819
+ get: function() {
820
+ return resolveCdnURL;
821
+ }
822
+ });
751
823
  Object.defineProperty(exports, "resolveEntry", {
752
824
  enumerable: true,
753
825
  get: function() {
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_css = require("./css-DpqJBQ5c.cjs");
2
+ const require_css = require("./css-DGNVJsLz.cjs");
3
3
  let vue = require("vue");
4
4
  vue = require_css.__toESM(vue);
5
5
  let _deot_vc = require("@deot/vc");
@@ -2066,14 +2066,16 @@ var moduleSpecifier = (item) => item.type === "import-meta" || !item.specifier |
2066
2066
  * 发现自定义 ESM 的传递引用;缺失的 npm 包映射到 CDN,动态依赖只登记地址。
2067
2067
  * @param imports 当前预览的模块覆盖。
2068
2068
  * @param specifiers 源文件实际引用的模块。
2069
+ * @param resolve 本次预览共用的最终 URL 转换。
2069
2070
  * @returns 补齐后的 import map。
2070
2071
  */
2071
- var resolveReplImports = async (imports, specifiers) => {
2072
+ var resolveReplImports = async (imports, specifiers, resolve = require_css.createCdnResolver()) => {
2072
2073
  const resolved = { ...imports };
2073
2074
  const visited = /* @__PURE__ */ new Set();
2074
2075
  const visit = async (specifier, importer) => {
2075
- const url = require_css.isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier) ? new URL(specifier, importer || location.href).href : resolved[specifier] ||= require_css.resolveNpmImport(specifier);
2076
- if (visited.has(url) || /\/\+esm(?:[?#]|$)/.test(url)) return;
2076
+ const source = require_css.isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier) ? new URL(specifier, importer || location.href).href : resolved[specifier] ||= require_css.resolveNpmImport(specifier);
2077
+ const url = resolve(source);
2078
+ if (visited.has(url) || require_css.isCdnEsmURL(source)) return;
2077
2079
  visited.add(url);
2078
2080
  const response = await fetch(url);
2079
2081
  if (!response.ok) throw new Error(`${response.status} ${url}`);
@@ -2138,8 +2140,10 @@ var rewriteImportedExports = (code) => {
2138
2140
  /**
2139
2141
  * REPL 将 ./ 引用按 src 根目录解析,编译结果需要先转成文件表中的完整路径。
2140
2142
  * @param store iframe 预览的文件和编译结果。
2143
+ * @param getImportMap 未转换的原始 import map。
2144
+ * @param resolve 本次预览共用的最终 URL 转换。
2141
2145
  */
2142
- var bindReplModules = (store) => {
2146
+ var bindReplModules = (store, getImportMap = store.getImportMap.bind(store), resolve = require_css.createCdnResolver()) => {
2143
2147
  (0, vue.watch)(() => Object.values(store.files).map((file) => [
2144
2148
  file.filename,
2145
2149
  file.code,
@@ -2147,7 +2151,7 @@ var bindReplModules = (store) => {
2147
2151
  file.compiled.ssr
2148
2152
  ]), () => {
2149
2153
  const files = require_css.createFileIndex(Object.fromEntries(Object.entries(store.files).map(([name, file]) => [name, file.code])));
2150
- const importMap = store.getImportMap();
2154
+ const importMap = getImportMap();
2151
2155
  const imports = { ...importMap.imports };
2152
2156
  let importsChanged = false;
2153
2157
  for (const file of Object.values(store.files)) for (const output of ["js", "ssr"]) {
@@ -2167,7 +2171,11 @@ var bindReplModules = (store) => {
2167
2171
  const target = `./${resolved.replace(/^\/?src\//, "")}`;
2168
2172
  const text = item.type === "dynamic" ? JSON.stringify(target) : target;
2169
2173
  code = code.slice(0, item.start) + text + code.slice(item.end);
2170
- } else if (!/^https?:\/\//.test(specifier) && !imports[specifier]) {
2174
+ } else if (/^https?:\/\//.test(specifier)) {
2175
+ const target = resolve(specifier);
2176
+ const text = item.type === "dynamic" ? JSON.stringify(target) : target;
2177
+ code = code.slice(0, item.start) + text + code.slice(item.end);
2178
+ } else if (!imports[specifier]) {
2171
2179
  imports[specifier] = require_css.resolveNpmImport(specifier);
2172
2180
  importsChanged = true;
2173
2181
  }
@@ -2204,13 +2212,14 @@ var escapeHtmlAttr = (value) => value.replace(/&/gu, "&amp;").replace(/"/gu, "&q
2204
2212
  * `--vc-background-color-lightest` 不同,否则会出现色带割裂。
2205
2213
  */
2206
2214
  var PLAYGROUND_RUNTIME_CANVAS_BACKGROUND = "var(--vc-background-color-lightest, var(--docs-background-color, #fff))";
2207
- var createRuntimePreviewOptions = (cdnURL = require_css.DEFAULT_CDN_URL, options = {}) => {
2215
+ var createRuntimePreviewOptions = (cdnURL, options = {}) => {
2208
2216
  const previewScroller = options.previewScroller === true;
2217
+ const resolve = require_css.createCdnResolver(cdnURL);
2209
2218
  const hrefs = Object.values({
2210
2219
  ...require_css.createBuiltinStyles(cdnURL),
2211
2220
  ...getPlaygroundSiteStyles(),
2212
2221
  ...getPlaygroundStyleOverrides()
2213
- });
2222
+ }).map(resolve);
2214
2223
  const styleBlocks = [
2215
2224
  `html,body{height:auto;min-height:0;background:${PLAYGROUND_RUNTIME_CANVAS_BACKGROUND}}`,
2216
2225
  "body{color:var(--vc-foreground-color,#080f20)}",
@@ -2254,7 +2263,7 @@ var createRuntimeImportOverrides = (builtinImportMap) => ({
2254
2263
  * @param cdnURL
2255
2264
  * @param builtinImportMap
2256
2265
  */
2257
- var createRuntimeImports = (cdnURL = require_css.DEFAULT_CDN_URL, builtinImportMap) => ({
2266
+ var createRuntimeImports = (cdnURL, builtinImportMap) => ({
2258
2267
  ...require_css.createBuiltinImports(cdnURL),
2259
2268
  ...createRuntimeImportOverrides(builtinImportMap)
2260
2269
  });
@@ -2268,8 +2277,14 @@ var createRuntimeStore = (files, entry, options) => {
2268
2277
  const mainFile = (0, vue.ref)(toReplFilename(entry));
2269
2278
  const activeFilename = (0, vue.ref)(toReplFilename(entry));
2270
2279
  const imports = createRuntimeImports(cdnURL, builtinImportMap);
2280
+ const resolve = require_css.createCdnResolver(cdnURL);
2281
+ const resourceLinks = (0, vue.unref)(storeOptions.resourceLinks);
2271
2282
  const store = (0, _vue_repl.useStore)({
2272
2283
  ...storeOptions,
2284
+ resourceLinks: (0, vue.ref)({
2285
+ ...resourceLinks,
2286
+ esModuleShims: resolve(resourceLinks?.esModuleShims || "https://cdn.jsdelivr.net/npm/es-module-shims@1.5.18/dist/es-module-shims.wasm.js?raw")
2287
+ }),
2273
2288
  files: replFiles,
2274
2289
  mainFile,
2275
2290
  activeFilename,
@@ -2288,7 +2303,17 @@ var createRuntimeStore = (files, entry, options) => {
2288
2303
  "import-map.json": store.files["import-map.json"].code,
2289
2304
  ...nextFiles
2290
2305
  }, nextEntry);
2291
- bindReplModules(store);
2306
+ const getImportMap = store.getImportMap.bind(store);
2307
+ bindReplModules(store, getImportMap, resolve);
2308
+ store.getImportMap = () => {
2309
+ const map = getImportMap();
2310
+ const convert = (items = {}) => Object.fromEntries(Object.entries(items).filter((item) => typeof item[1] === "string").map(([id, url]) => [id, resolve(url)]));
2311
+ return {
2312
+ ...map,
2313
+ imports: convert(map.imports),
2314
+ scopes: map.scopes && Object.fromEntries(Object.entries(map.scopes).map(([scope, items]) => [resolve(scope), convert(items)]))
2315
+ };
2316
+ };
2292
2317
  require_css.whenSassReady(files, () => {
2293
2318
  const specifiers = require_css.collectBareSpecifiers(files, Object.keys(files));
2294
2319
  if (!specifiers.length) {
@@ -2296,8 +2321,12 @@ var createRuntimeStore = (files, entry, options) => {
2296
2321
  return;
2297
2322
  }
2298
2323
  store.loading = true;
2299
- resolveReplImports(imports, specifiers).then((resolved) => {
2300
- if (Object.keys(resolved).length !== Object.keys(imports).length) store.setImportMap({ imports: resolved }, true);
2324
+ const currentImports = {
2325
+ ...imports,
2326
+ ...filterSafeHrefs(getImportMap().imports)
2327
+ };
2328
+ resolveReplImports(currentImports, specifiers, resolve).then((resolved) => {
2329
+ if (Object.keys(resolved).length !== Object.keys(currentImports).length) store.setImportMap({ imports: resolved }, true);
2301
2330
  store.init();
2302
2331
  }).catch((error) => {
2303
2332
  store.errors.push(error);
@@ -3098,12 +3127,15 @@ var readRemoteSource = (url) => {
3098
3127
  * @param builtins 宿主 Vue 与 vue-router。
3099
3128
  * @param overrides 显式配置的模块名,与自动补齐的默认地址区分。
3100
3129
  * @param importModule 浏览器原生 ESM 加载器。
3130
+ * @param cdnURL 没有 launch 选点结果时使用的实例 CDN。
3101
3131
  * @returns 按 URL 加载并执行远程模块的加载器。
3102
3132
  */
3103
3133
  var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imports)), importModule = (url) => import(
3104
3134
  /* @vite-ignore */
3105
3135
  url
3106
- )) => {
3136
+ ), cdnURL) => {
3137
+ const resolve = require_css.createCdnResolver(cdnURL);
3138
+ const resolveUrl = (url) => resolve(moduleUrl(url));
3107
3139
  const hostModules = {
3108
3140
  "vue": builtins.vue,
3109
3141
  "vue-router": builtins.vueRouter
@@ -3140,16 +3172,16 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3140
3172
  const dependencySpecifier = (from, specifier) => {
3141
3173
  if (require_css.isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier)) {
3142
3174
  const url = new URL(specifier, from);
3143
- const match = url.origin === "https://cdn.jsdelivr.net" ? url.pathname.match(/^\/npm\/((?:@[^/]+\/)?[^/@]+)(?:@[^/]+)?\/\+esm$/) : null;
3144
- if (match && (imports[match[1]] || localBuiltinIds.has(match[1]))) return match[1];
3175
+ const name = require_css.cdnModuleName(url.href);
3176
+ if (name && (imports[name] || localBuiltinIds.has(name))) return name;
3145
3177
  return url.href;
3146
3178
  }
3147
3179
  return specifier;
3148
3180
  };
3149
3181
  const dependencyUrl = (from, id) => {
3150
3182
  const specifier = dependencySpecifier(from, id);
3151
- if (/^https?:\/\//.test(specifier)) return specifier;
3152
- if (imports[specifier] && !prefersLocalBuiltin(specifier, imports, overrides)) return moduleUrl(imports[specifier]);
3183
+ if (/^https?:\/\//.test(specifier)) return resolveUrl(specifier);
3184
+ if (imports[specifier] && !prefersLocalBuiltin(specifier, imports, overrides)) return resolveUrl(imports[specifier]);
3153
3185
  if (HOST_VUE.has(specifier) && prefersLocalBuiltin(specifier, imports, overrides)) return null;
3154
3186
  let cursor = specifier;
3155
3187
  while (cursor) {
@@ -3164,12 +3196,12 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3164
3196
  const target = imports[specifier] ? specifier : resolveImportTarget(specifier, imports);
3165
3197
  if (!target) {
3166
3198
  imports[specifier] = require_css.resolveNpmImport(specifier);
3167
- return imports[specifier];
3199
+ return resolveUrl(imports[specifier]);
3168
3200
  }
3169
- return moduleUrl(imports[target]);
3201
+ return resolveUrl(imports[target]);
3170
3202
  };
3171
3203
  const crawl = async (url, visited = /* @__PURE__ */ new Set()) => {
3172
- if (!overrides.size && /\/\+esm(?:[?#]|$)/.test(url)) {
3204
+ if (!overrides.size && require_css.isCdnEsmURL(url)) {
3173
3205
  await loadNative(url);
3174
3206
  return;
3175
3207
  }
@@ -3195,7 +3227,7 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3195
3227
  if (require_css.isRelativeSpecifier(id) || /^https?:\/\//.test(id)) return evaluate(dependencyUrl(from, id));
3196
3228
  const target = imports[id] ? id : resolveImportTarget(id, imports);
3197
3229
  if (!target || !imports[target]) throw new Error(`[Playground] 未注册的模块 "${id}"`);
3198
- const loaded = evaluate(moduleUrl(imports[target]));
3230
+ const loaded = evaluate(resolveUrl(imports[target]));
3199
3231
  if (target === id) return loaded;
3200
3232
  if (!resolveHostModule(id, { [target]: loaded }))
3201
3233
  /* istanbul ignore next -- 父包没有对应导出时才拒绝 */
@@ -3223,7 +3255,7 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3223
3255
  };
3224
3256
  const loading = /* @__PURE__ */ new Map();
3225
3257
  const load = (sourceUrl) => {
3226
- const url = moduleUrl(sourceUrl);
3258
+ const url = resolveUrl(sourceUrl);
3227
3259
  const pending = loading.get(url);
3228
3260
  if (pending) return pending;
3229
3261
  const task = (async () => {
@@ -3383,7 +3415,7 @@ var local_sandbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ (0
3383
3415
  publishError();
3384
3416
  destroyPreview();
3385
3417
  try {
3386
- const { compilePlayground } = await Promise.resolve().then(() => require("./compile-29EUKPOy.cjs"));
3418
+ const { compilePlayground } = await Promise.resolve().then(() => require("./compile-yveCpyT3.cjs"));
3387
3419
  /* istanbul ignore if -- 并发编译时只保留最后一次 */
3388
3420
  if (current !== version) return;
3389
3421
  const compiled = await compilePlayground(props.files, { entry: props.entry });
@@ -3402,7 +3434,7 @@ var local_sandbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ (0
3402
3434
  const remote = createRemoteLoader(imports, {
3403
3435
  vue,
3404
3436
  vueRouter: vue_router
3405
- }, overrides);
3437
+ }, overrides, void 0, props.options.cdnURL);
3406
3438
  const loaded = await loadLocalModules(specifiers, imports, {
3407
3439
  vue,
3408
3440
  vueRouter: vue_router
@@ -4277,6 +4309,7 @@ exports.normalizeCdnURL = require_css.normalizeCdnURL;
4277
4309
  exports.registerVueHighlight = registerVueHighlight;
4278
4310
  exports.removePlaygroundImportMapOverride = removePlaygroundImportMapOverride;
4279
4311
  exports.removePlaygroundStyleOverride = removePlaygroundStyleOverride;
4312
+ exports.resolveCdnURL = require_css.resolveCdnURL;
4280
4313
  exports.resolveHighlightLanguage = resolveHighlightLanguage;
4281
4314
  exports.resolvePlaygroundTitleId = resolvePlaygroundTitleId;
4282
4315
  exports.setPlaygroundImportMapOverrides = setPlaygroundImportMapOverrides;
package/dist/index.d.ts CHANGED
@@ -81,6 +81,17 @@ export declare const applyPlaygroundStyleOverride: (alias: string, url: string)
81
81
  [x: string]: string;
82
82
  };
83
83
 
84
+ declare interface CdnConfig {
85
+ runtime?: {
86
+ cdn?: string;
87
+ };
88
+ resolve?: {
89
+ cdn?: (context: {
90
+ url: string;
91
+ }) => string | null | undefined;
92
+ };
93
+ }
94
+
84
95
  export declare const clearPlaygroundMaps: () => void;
85
96
 
86
97
  export declare const CodePreview: typeof __VLS_export;
@@ -250,6 +261,8 @@ export declare const removePlaygroundStyleOverride: (alias: string) => {
250
261
  [x: string]: string;
251
262
  };
252
263
 
264
+ export declare const resolveCdnURL: (url: string, cdnURL?: string, config?: CdnConfig) => string;
265
+
253
266
  export declare const resolveHighlightLanguage: (filename: string) => "xml" | "javascript" | "typescript" | "css" | "scss" | "vue" | "json" | "plaintext";
254
267
 
255
268
  export declare const resolvePlaygroundTitleId: (title: string, explicitId?: string, isOccupied?: (id: string) => boolean) => string;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as normalizeCdnURL, D as NEW_SFC_CODE, E as DEFAULT_ENTRY, S as createBuiltinStyles, T as DEFAULT_CDN_URL, _ as bindPlaygroundScss, a as transformScript, b as whenSassReady, c as createFileIndex, d as isIgnoredFilename, f as isInsideRoot, g as resolveModulePath, i as rewriteImportMeta, l as getCommonRoot, m as normalizeVirtualPath, n as injectStyle, o as collectBareSpecifiers, p as isRelativeSpecifier, r as removeStyle, s as collectReachableFilenames, w as resolveNpmImport, x as createBuiltinImports } from "./css-DleINdoA.js";
1
+ import { A as DEFAULT_ENTRY, C as createBuiltinStyles, D as resolveCdnURL, E as normalizeCdnURL, O as resolveNpmImport, S as createBuiltinImports, T as isCdnEsmURL, _ as bindPlaygroundScss, a as transformScript, b as whenSassReady, c as createFileIndex, d as isIgnoredFilename, f as isInsideRoot, g as resolveModulePath, i as rewriteImportMeta, j as NEW_SFC_CODE, k as DEFAULT_CDN_URL, l as getCommonRoot, m as normalizeVirtualPath, n as injectStyle, o as collectBareSpecifiers, p as isRelativeSpecifier, r as removeStyle, s as collectReachableFilenames, w as createCdnResolver, x as cdnModuleName } from "./css-D47JLekg.js";
2
2
  import * as Vue from "vue";
3
3
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineAsyncComponent, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, shallowRef, toDisplayString, unref, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
4
4
  import * as Vc from "@deot/vc";
@@ -2068,14 +2068,16 @@ var moduleSpecifier = (item) => item.type === "import-meta" || !item.specifier |
2068
2068
  * 发现自定义 ESM 的传递引用;缺失的 npm 包映射到 CDN,动态依赖只登记地址。
2069
2069
  * @param imports 当前预览的模块覆盖。
2070
2070
  * @param specifiers 源文件实际引用的模块。
2071
+ * @param resolve 本次预览共用的最终 URL 转换。
2071
2072
  * @returns 补齐后的 import map。
2072
2073
  */
2073
- var resolveReplImports = async (imports, specifiers) => {
2074
+ var resolveReplImports = async (imports, specifiers, resolve = createCdnResolver()) => {
2074
2075
  const resolved = { ...imports };
2075
2076
  const visited = /* @__PURE__ */ new Set();
2076
2077
  const visit = async (specifier, importer) => {
2077
- const url = isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier) ? new URL(specifier, importer || location.href).href : resolved[specifier] ||= resolveNpmImport(specifier);
2078
- if (visited.has(url) || /\/\+esm(?:[?#]|$)/.test(url)) return;
2078
+ const source = isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier) ? new URL(specifier, importer || location.href).href : resolved[specifier] ||= resolveNpmImport(specifier);
2079
+ const url = resolve(source);
2080
+ if (visited.has(url) || isCdnEsmURL(source)) return;
2079
2081
  visited.add(url);
2080
2082
  const response = await fetch(url);
2081
2083
  if (!response.ok) throw new Error(`${response.status} ${url}`);
@@ -2140,8 +2142,10 @@ var rewriteImportedExports = (code) => {
2140
2142
  /**
2141
2143
  * REPL 将 ./ 引用按 src 根目录解析,编译结果需要先转成文件表中的完整路径。
2142
2144
  * @param store iframe 预览的文件和编译结果。
2145
+ * @param getImportMap 未转换的原始 import map。
2146
+ * @param resolve 本次预览共用的最终 URL 转换。
2143
2147
  */
2144
- var bindReplModules = (store) => {
2148
+ var bindReplModules = (store, getImportMap = store.getImportMap.bind(store), resolve = createCdnResolver()) => {
2145
2149
  watch(() => Object.values(store.files).map((file) => [
2146
2150
  file.filename,
2147
2151
  file.code,
@@ -2149,7 +2153,7 @@ var bindReplModules = (store) => {
2149
2153
  file.compiled.ssr
2150
2154
  ]), () => {
2151
2155
  const files = createFileIndex(Object.fromEntries(Object.entries(store.files).map(([name, file]) => [name, file.code])));
2152
- const importMap = store.getImportMap();
2156
+ const importMap = getImportMap();
2153
2157
  const imports = { ...importMap.imports };
2154
2158
  let importsChanged = false;
2155
2159
  for (const file of Object.values(store.files)) for (const output of ["js", "ssr"]) {
@@ -2169,7 +2173,11 @@ var bindReplModules = (store) => {
2169
2173
  const target = `./${resolved.replace(/^\/?src\//, "")}`;
2170
2174
  const text = item.type === "dynamic" ? JSON.stringify(target) : target;
2171
2175
  code = code.slice(0, item.start) + text + code.slice(item.end);
2172
- } else if (!/^https?:\/\//.test(specifier) && !imports[specifier]) {
2176
+ } else if (/^https?:\/\//.test(specifier)) {
2177
+ const target = resolve(specifier);
2178
+ const text = item.type === "dynamic" ? JSON.stringify(target) : target;
2179
+ code = code.slice(0, item.start) + text + code.slice(item.end);
2180
+ } else if (!imports[specifier]) {
2173
2181
  imports[specifier] = resolveNpmImport(specifier);
2174
2182
  importsChanged = true;
2175
2183
  }
@@ -2206,13 +2214,14 @@ var escapeHtmlAttr = (value) => value.replace(/&/gu, "&amp;").replace(/"/gu, "&q
2206
2214
  * `--vc-background-color-lightest` 不同,否则会出现色带割裂。
2207
2215
  */
2208
2216
  var PLAYGROUND_RUNTIME_CANVAS_BACKGROUND = "var(--vc-background-color-lightest, var(--docs-background-color, #fff))";
2209
- var createRuntimePreviewOptions = (cdnURL = DEFAULT_CDN_URL, options = {}) => {
2217
+ var createRuntimePreviewOptions = (cdnURL, options = {}) => {
2210
2218
  const previewScroller = options.previewScroller === true;
2219
+ const resolve = createCdnResolver(cdnURL);
2211
2220
  const hrefs = Object.values({
2212
2221
  ...createBuiltinStyles(cdnURL),
2213
2222
  ...getPlaygroundSiteStyles(),
2214
2223
  ...getPlaygroundStyleOverrides()
2215
- });
2224
+ }).map(resolve);
2216
2225
  const styleBlocks = [
2217
2226
  `html,body{height:auto;min-height:0;background:${PLAYGROUND_RUNTIME_CANVAS_BACKGROUND}}`,
2218
2227
  "body{color:var(--vc-foreground-color,#080f20)}",
@@ -2256,7 +2265,7 @@ var createRuntimeImportOverrides = (builtinImportMap) => ({
2256
2265
  * @param cdnURL
2257
2266
  * @param builtinImportMap
2258
2267
  */
2259
- var createRuntimeImports = (cdnURL = DEFAULT_CDN_URL, builtinImportMap) => ({
2268
+ var createRuntimeImports = (cdnURL, builtinImportMap) => ({
2260
2269
  ...createBuiltinImports(cdnURL),
2261
2270
  ...createRuntimeImportOverrides(builtinImportMap)
2262
2271
  });
@@ -2270,8 +2279,14 @@ var createRuntimeStore = (files, entry, options) => {
2270
2279
  const mainFile = ref(toReplFilename(entry));
2271
2280
  const activeFilename = ref(toReplFilename(entry));
2272
2281
  const imports = createRuntimeImports(cdnURL, builtinImportMap);
2282
+ const resolve = createCdnResolver(cdnURL);
2283
+ const resourceLinks = unref(storeOptions.resourceLinks);
2273
2284
  const store = useStore({
2274
2285
  ...storeOptions,
2286
+ resourceLinks: ref({
2287
+ ...resourceLinks,
2288
+ esModuleShims: resolve(resourceLinks?.esModuleShims || "https://cdn.jsdelivr.net/npm/es-module-shims@1.5.18/dist/es-module-shims.wasm.js?raw")
2289
+ }),
2275
2290
  files: replFiles,
2276
2291
  mainFile,
2277
2292
  activeFilename,
@@ -2290,7 +2305,17 @@ var createRuntimeStore = (files, entry, options) => {
2290
2305
  "import-map.json": store.files["import-map.json"].code,
2291
2306
  ...nextFiles
2292
2307
  }, nextEntry);
2293
- bindReplModules(store);
2308
+ const getImportMap = store.getImportMap.bind(store);
2309
+ bindReplModules(store, getImportMap, resolve);
2310
+ store.getImportMap = () => {
2311
+ const map = getImportMap();
2312
+ const convert = (items = {}) => Object.fromEntries(Object.entries(items).filter((item) => typeof item[1] === "string").map(([id, url]) => [id, resolve(url)]));
2313
+ return {
2314
+ ...map,
2315
+ imports: convert(map.imports),
2316
+ scopes: map.scopes && Object.fromEntries(Object.entries(map.scopes).map(([scope, items]) => [resolve(scope), convert(items)]))
2317
+ };
2318
+ };
2294
2319
  whenSassReady(files, () => {
2295
2320
  const specifiers = collectBareSpecifiers(files, Object.keys(files));
2296
2321
  if (!specifiers.length) {
@@ -2298,8 +2323,12 @@ var createRuntimeStore = (files, entry, options) => {
2298
2323
  return;
2299
2324
  }
2300
2325
  store.loading = true;
2301
- resolveReplImports(imports, specifiers).then((resolved) => {
2302
- if (Object.keys(resolved).length !== Object.keys(imports).length) store.setImportMap({ imports: resolved }, true);
2326
+ const currentImports = {
2327
+ ...imports,
2328
+ ...filterSafeHrefs(getImportMap().imports)
2329
+ };
2330
+ resolveReplImports(currentImports, specifiers, resolve).then((resolved) => {
2331
+ if (Object.keys(resolved).length !== Object.keys(currentImports).length) store.setImportMap({ imports: resolved }, true);
2303
2332
  store.init();
2304
2333
  }).catch((error) => {
2305
2334
  store.errors.push(error);
@@ -3097,12 +3126,15 @@ var readRemoteSource = (url) => {
3097
3126
  * @param builtins 宿主 Vue 与 vue-router。
3098
3127
  * @param overrides 显式配置的模块名,与自动补齐的默认地址区分。
3099
3128
  * @param importModule 浏览器原生 ESM 加载器。
3129
+ * @param cdnURL 没有 launch 选点结果时使用的实例 CDN。
3100
3130
  * @returns 按 URL 加载并执行远程模块的加载器。
3101
3131
  */
3102
3132
  var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imports)), importModule = (url) => import(
3103
3133
  /* @vite-ignore */
3104
3134
  url
3105
- )) => {
3135
+ ), cdnURL) => {
3136
+ const resolve = createCdnResolver(cdnURL);
3137
+ const resolveUrl = (url) => resolve(moduleUrl(url));
3106
3138
  const hostModules = {
3107
3139
  "vue": builtins.vue,
3108
3140
  "vue-router": builtins.vueRouter
@@ -3139,16 +3171,16 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3139
3171
  const dependencySpecifier = (from, specifier) => {
3140
3172
  if (isRelativeSpecifier(specifier) || /^https?:\/\//.test(specifier)) {
3141
3173
  const url = new URL(specifier, from);
3142
- const match = url.origin === "https://cdn.jsdelivr.net" ? url.pathname.match(/^\/npm\/((?:@[^/]+\/)?[^/@]+)(?:@[^/]+)?\/\+esm$/) : null;
3143
- if (match && (imports[match[1]] || localBuiltinIds.has(match[1]))) return match[1];
3174
+ const name = cdnModuleName(url.href);
3175
+ if (name && (imports[name] || localBuiltinIds.has(name))) return name;
3144
3176
  return url.href;
3145
3177
  }
3146
3178
  return specifier;
3147
3179
  };
3148
3180
  const dependencyUrl = (from, id) => {
3149
3181
  const specifier = dependencySpecifier(from, id);
3150
- if (/^https?:\/\//.test(specifier)) return specifier;
3151
- if (imports[specifier] && !prefersLocalBuiltin(specifier, imports, overrides)) return moduleUrl(imports[specifier]);
3182
+ if (/^https?:\/\//.test(specifier)) return resolveUrl(specifier);
3183
+ if (imports[specifier] && !prefersLocalBuiltin(specifier, imports, overrides)) return resolveUrl(imports[specifier]);
3152
3184
  if (HOST_VUE.has(specifier) && prefersLocalBuiltin(specifier, imports, overrides)) return null;
3153
3185
  let cursor = specifier;
3154
3186
  while (cursor) {
@@ -3163,12 +3195,12 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3163
3195
  const target = imports[specifier] ? specifier : resolveImportTarget(specifier, imports);
3164
3196
  if (!target) {
3165
3197
  imports[specifier] = resolveNpmImport(specifier);
3166
- return imports[specifier];
3198
+ return resolveUrl(imports[specifier]);
3167
3199
  }
3168
- return moduleUrl(imports[target]);
3200
+ return resolveUrl(imports[target]);
3169
3201
  };
3170
3202
  const crawl = async (url, visited = /* @__PURE__ */ new Set()) => {
3171
- if (!overrides.size && /\/\+esm(?:[?#]|$)/.test(url)) {
3203
+ if (!overrides.size && isCdnEsmURL(url)) {
3172
3204
  await loadNative(url);
3173
3205
  return;
3174
3206
  }
@@ -3194,7 +3226,7 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3194
3226
  if (isRelativeSpecifier(id) || /^https?:\/\//.test(id)) return evaluate(dependencyUrl(from, id));
3195
3227
  const target = imports[id] ? id : resolveImportTarget(id, imports);
3196
3228
  if (!target || !imports[target]) throw new Error(`[Playground] 未注册的模块 "${id}"`);
3197
- const loaded = evaluate(moduleUrl(imports[target]));
3229
+ const loaded = evaluate(resolveUrl(imports[target]));
3198
3230
  if (target === id) return loaded;
3199
3231
  if (!resolveHostModule(id, { [target]: loaded }))
3200
3232
  /* istanbul ignore next -- 父包没有对应导出时才拒绝 */
@@ -3222,7 +3254,7 @@ var createRemoteLoader = (imports, builtins, overrides = new Set(Object.keys(imp
3222
3254
  };
3223
3255
  const loading = /* @__PURE__ */ new Map();
3224
3256
  const load = (sourceUrl) => {
3225
- const url = moduleUrl(sourceUrl);
3257
+ const url = resolveUrl(sourceUrl);
3226
3258
  const pending = loading.get(url);
3227
3259
  if (pending) return pending;
3228
3260
  const task = (async () => {
@@ -3382,7 +3414,7 @@ var local_sandbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
3382
3414
  publishError();
3383
3415
  destroyPreview();
3384
3416
  try {
3385
- const { compilePlayground } = await import("./compile-CM_OyqYN.js");
3417
+ const { compilePlayground } = await import("./compile-no-AB7-B.js");
3386
3418
  /* istanbul ignore if -- 并发编译时只保留最后一次 */
3387
3419
  if (current !== version) return;
3388
3420
  const compiled = await compilePlayground(props.files, { entry: props.entry });
@@ -3401,7 +3433,7 @@ var local_sandbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
3401
3433
  const remote = createRemoteLoader(imports, {
3402
3434
  vue: Vue,
3403
3435
  vueRouter: VueRouter
3404
- }, overrides);
3436
+ }, overrides, void 0, props.options.cdnURL);
3405
3437
  const loaded = await loadLocalModules(specifiers, imports, {
3406
3438
  vue: Vue,
3407
3439
  vueRouter: VueRouter
@@ -4251,4 +4283,4 @@ var playground_default = /* @__PURE__ */ defineComponent({
4251
4283
  }
4252
4284
  });
4253
4285
  //#endregion
4254
- export { code_preview_default as CodePreview, DEFAULT_CDN_URL, Editor, PREVIEW_SCROLLER_USE_CODE, PREVIEW_SCROLL_CONTENT_CLASS, PREVIEW_SCROLL_HTML_CLASS, playground_default as Playground, PlaygroundService, applyPlaygroundImportMapOverride, applyPlaygroundStyleOverride, clearPlaygroundMaps, createBuiltinImports, createBuiltinStyles, createRuntimePreviewOptions, getPlaygroundImportMapOverrides, getPlaygroundSiteModules, getPlaygroundSiteStyles, getPlaygroundStyleOverrides, highlightCode, highlightCodeByLanguage, isSafePlaygroundHref, normalizeCdnURL, registerVueHighlight, removePlaygroundImportMapOverride, removePlaygroundStyleOverride, resolveHighlightLanguage, resolvePlaygroundTitleId, setPlaygroundImportMapOverrides, setPlaygroundSiteModules, setPlaygroundSiteStyles, setPlaygroundStyleOverrides, slugifyPlaygroundTitle, vueHighlight };
4286
+ export { code_preview_default as CodePreview, DEFAULT_CDN_URL, Editor, PREVIEW_SCROLLER_USE_CODE, PREVIEW_SCROLL_CONTENT_CLASS, PREVIEW_SCROLL_HTML_CLASS, playground_default as Playground, PlaygroundService, applyPlaygroundImportMapOverride, applyPlaygroundStyleOverride, clearPlaygroundMaps, createBuiltinImports, createBuiltinStyles, createRuntimePreviewOptions, getPlaygroundImportMapOverrides, getPlaygroundSiteModules, getPlaygroundSiteStyles, getPlaygroundStyleOverrides, highlightCode, highlightCodeByLanguage, isSafePlaygroundHref, normalizeCdnURL, registerVueHighlight, removePlaygroundImportMapOverride, removePlaygroundStyleOverride, resolveCdnURL, resolveHighlightLanguage, resolvePlaygroundTitleId, setPlaygroundImportMapOverrides, setPlaygroundSiteModules, setPlaygroundSiteStyles, setPlaygroundStyleOverrides, slugifyPlaygroundTitle, vueHighlight };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deot/docs-playground",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {
@@ -18,8 +18,8 @@
18
18
  "access": "public"
19
19
  },
20
20
  "dependencies": {
21
- "@deot/docs-locale": "^1.1.4",
22
- "@deot/docs-theme": "^1.1.4",
21
+ "@deot/docs-locale": "^1.1.5",
22
+ "@deot/docs-theme": "^1.1.5",
23
23
  "@deot/helper": "^1.1.21",
24
24
  "@deot/http": "^1.1.10",
25
25
  "@deot/vc": "^1.2.3",