@vizejs/vite-plugin-musea 0.327.0 → 0.332.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +294 -48
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1102,6 +1102,108 @@ function resolveComponentSourcePath(art, artPath, sourceRoots) {
|
|
|
1102
1102
|
return componentPath ? resolveInsideAny(sourceRoots, componentPath, "component path") : null;
|
|
1103
1103
|
}
|
|
1104
1104
|
//#endregion
|
|
1105
|
+
//#region src/art-module-vue2.ts
|
|
1106
|
+
/**
|
|
1107
|
+
* Legacy Vue 2 variant emission.
|
|
1108
|
+
*
|
|
1109
|
+
* Vue 2 has no `openBlock`/`createElementBlock` runtime, so the compiled Vue 3
|
|
1110
|
+
* render functions the SFC pipeline produces cannot load there. Vue 2 galleries
|
|
1111
|
+
* keep the runtime-compiled `template:` string they always had — the TypeScript
|
|
1112
|
+
* fix in #3857 applies to Vue 3, which is what `.art.vue` with
|
|
1113
|
+
* `<script setup lang="ts">` targets.
|
|
1114
|
+
*/
|
|
1115
|
+
function escapeTemplateLiteral(str) {
|
|
1116
|
+
return str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
1117
|
+
}
|
|
1118
|
+
function emitLegacyVariant(context) {
|
|
1119
|
+
const { variantComponentName, variantName, template, componentTagName, componentBindingName, scriptSetup, hasSetup, isolatedSetup, setupReturn, importDeclaresName } = context;
|
|
1120
|
+
const escapedTemplate = escapeTemplateLiteral(template);
|
|
1121
|
+
const fullTemplate = `<div data-variant="${escapeTemplateLiteral(escapeHtml(variantName))}">${escapedTemplate}</div>`;
|
|
1122
|
+
const componentNames = /* @__PURE__ */ new Map();
|
|
1123
|
+
if (componentTagName) componentNames.set(componentTagName, componentBindingName);
|
|
1124
|
+
if (scriptSetup) {
|
|
1125
|
+
for (const name of scriptSetup.returnNames) if (/^[A-Z]/.test(name) && scriptSetup.imports.some((imp) => importDeclaresName(imp, name))) componentNames.set(name, name);
|
|
1126
|
+
}
|
|
1127
|
+
const components = componentNames.size > 0 ? ` components: { ${[...componentNames].map(([name, value]) => `${JSON.stringify(name)}: ${value}`).join(", ")} },\n` : "";
|
|
1128
|
+
if (scriptSetup && hasSetup && isolatedSetup) return `
|
|
1129
|
+
export const ${variantComponentName} = __museaDefineComponent({
|
|
1130
|
+
name: '${variantComponentName}',
|
|
1131
|
+
${components} setup() {
|
|
1132
|
+
${scriptSetup.setupBody.join("\n")}
|
|
1133
|
+
return ${setupReturn};
|
|
1134
|
+
},
|
|
1135
|
+
template: \`${fullTemplate}\`,
|
|
1136
|
+
});
|
|
1137
|
+
`;
|
|
1138
|
+
if (scriptSetup && hasSetup) return `
|
|
1139
|
+
export const ${variantComponentName} = __museaDefineComponent({
|
|
1140
|
+
name: '${variantComponentName}',
|
|
1141
|
+
${components} setup() {
|
|
1142
|
+
return __museaSharedSetup;
|
|
1143
|
+
},
|
|
1144
|
+
template: \`${fullTemplate}\`,
|
|
1145
|
+
});
|
|
1146
|
+
`;
|
|
1147
|
+
return `
|
|
1148
|
+
export const ${variantComponentName} = {
|
|
1149
|
+
name: '${variantComponentName}',
|
|
1150
|
+
${components} template: \`${fullTemplate}\`,
|
|
1151
|
+
};
|
|
1152
|
+
`;
|
|
1153
|
+
}
|
|
1154
|
+
//#endregion
|
|
1155
|
+
//#region src/art-component.ts
|
|
1156
|
+
/**
|
|
1157
|
+
* Resolve which component an art file demonstrates, and under what tag.
|
|
1158
|
+
*
|
|
1159
|
+
* Shared by the art module and by the per-variant SFC compiler (#3857) so both
|
|
1160
|
+
* agree on the import path, the tag `<Self>` expands to, and the binding name.
|
|
1161
|
+
* The parsed `<script setup>` is passed in rather than parsed here, so this
|
|
1162
|
+
* module does not have to import back from `art-module.ts`.
|
|
1163
|
+
*/
|
|
1164
|
+
function componentNameFromSource$1(source) {
|
|
1165
|
+
const withoutQuery = source.split(/[?#]/, 1)[0] || source;
|
|
1166
|
+
const filename = path.basename(withoutQuery);
|
|
1167
|
+
const extension = path.extname(filename);
|
|
1168
|
+
const name = toPascalCase(extension ? filename.slice(0, -extension.length) : filename);
|
|
1169
|
+
return name === "Variant" ? "MuseaComponent" : name;
|
|
1170
|
+
}
|
|
1171
|
+
function resolveArtComponent(art, filePath, scriptSetup, options = {}) {
|
|
1172
|
+
let componentImportPath;
|
|
1173
|
+
let componentTagName;
|
|
1174
|
+
let componentBindingName = "__MuseaComponent";
|
|
1175
|
+
const defineArtComponentName = scriptSetup?.defineArtComponentName;
|
|
1176
|
+
const defineArtComponentSource = scriptSetup?.defineArtComponentSource;
|
|
1177
|
+
if (art.isInline && art.componentPath) {
|
|
1178
|
+
componentImportPath = options.root ? resolveComponentSourcePath(art, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : art.componentPath;
|
|
1179
|
+
componentTagName = "MuseaComponent";
|
|
1180
|
+
} else if (defineArtComponentSource || art.metadata.component) {
|
|
1181
|
+
const componentSource = defineArtComponentSource ?? art.metadata.component;
|
|
1182
|
+
if (componentSource) {
|
|
1183
|
+
const sourceArt = componentSource === art.metadata.component ? art : {
|
|
1184
|
+
...art,
|
|
1185
|
+
metadata: {
|
|
1186
|
+
...art.metadata,
|
|
1187
|
+
component: componentSource
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
componentImportPath = options.root ? resolveComponentSourcePath(sourceArt, filePath, allowedSourceRoots(options.root, options.scanRoots ?? [])) ?? void 0 : path.isAbsolute(componentSource) ? componentSource : path.resolve(path.dirname(filePath), componentSource);
|
|
1191
|
+
}
|
|
1192
|
+
componentTagName = defineArtComponentName ?? (art.metadata.component ? componentNameFromSource$1(art.metadata.component) : "MuseaComponent");
|
|
1193
|
+
componentBindingName = componentTagName;
|
|
1194
|
+
}
|
|
1195
|
+
return {
|
|
1196
|
+
componentImportPath,
|
|
1197
|
+
componentTagName,
|
|
1198
|
+
componentBindingName
|
|
1199
|
+
};
|
|
1200
|
+
}
|
|
1201
|
+
/** Expand `<Self>` in a variant template to the resolved component tag. */
|
|
1202
|
+
function expandSelfTag(template, componentTagName) {
|
|
1203
|
+
if (!componentTagName) return template;
|
|
1204
|
+
return template.replace(/<Self(?=[\s/>])/g, `<${componentTagName}`).replace(/<\/Self\s*>/g, `</${componentTagName}>`);
|
|
1205
|
+
}
|
|
1206
|
+
//#endregion
|
|
1105
1207
|
//#region src/art-module.ts
|
|
1106
1208
|
/**
|
|
1107
1209
|
* Art module generation for Musea.
|
|
@@ -1128,9 +1230,6 @@ function resolveRelativeSpecifier(specifier, artDir) {
|
|
|
1128
1230
|
function rewriteRelativeImportStatement(statement, artDir) {
|
|
1129
1231
|
return statement.replace(/\bfrom\s+(['"])([^'"]+)\1/g, (_match, quote, specifier) => `from ${quote}${resolveRelativeSpecifier(specifier, artDir)}${quote}`).replace(/^(\s*import\s+)(['"])([^'"]+)\2(\s*;?\s*)$/s, (_match, prefix, quote, specifier, suffix) => `${prefix}${quote}${resolveRelativeSpecifier(specifier, artDir)}${quote}${suffix}`);
|
|
1130
1232
|
}
|
|
1131
|
-
function escapeTemplateLiteral(str) {
|
|
1132
|
-
return str.replace(/\\/g, "\\\\").replace(/`/g, "\\`").replace(/\$/g, "\\$");
|
|
1133
|
-
}
|
|
1134
1233
|
function countCharBalance(source, openChar, closeChar) {
|
|
1135
1234
|
let balance = 0;
|
|
1136
1235
|
for (const char of source) if (char === openChar) balance++;
|
|
@@ -1360,10 +1459,12 @@ function generateArtModule(art, filePath, options = {}) {
|
|
|
1360
1459
|
componentTagName = defineArtComponentName ?? (art.metadata.component ? componentNameFromSource(art.metadata.component) : "MuseaComponent");
|
|
1361
1460
|
componentBindingName = componentTagName;
|
|
1362
1461
|
}
|
|
1462
|
+
const hasSetupBody = scriptSetup?.setupBody.some((line) => line.trim().length > 0) ?? false;
|
|
1463
|
+
const hasSetup = !!scriptSetup && (hasSetupBody || scriptSetup.returnNames.length > 0);
|
|
1363
1464
|
let code = `
|
|
1364
1465
|
// Auto-generated module for: ${path.basename(filePath)}
|
|
1365
|
-
import { defineComponent as __museaDefineComponent } from 'vue';
|
|
1366
1466
|
`;
|
|
1467
|
+
if (options.vueVersion === 2 && hasSetup) code += `import { defineComponent as __museaDefineComponent } from 'vue';\n`;
|
|
1367
1468
|
if (scriptSetup) {
|
|
1368
1469
|
const artDir = path.dirname(filePath);
|
|
1369
1470
|
for (const imp of scriptSetup.imports) {
|
|
@@ -1380,8 +1481,6 @@ export const metadata = ${JSON.stringify(art.metadata)};
|
|
|
1380
1481
|
export const variants = ${JSON.stringify(art.variants)};
|
|
1381
1482
|
export const __styles__ = ${JSON.stringify(art.styleBlocks ?? [])};
|
|
1382
1483
|
`;
|
|
1383
|
-
const hasSetupBody = scriptSetup?.setupBody.some((line) => line.trim().length > 0) ?? false;
|
|
1384
|
-
const hasSetup = !!scriptSetup && (hasSetupBody || scriptSetup.returnNames.length > 0);
|
|
1385
1484
|
const setupReturn = `{ ${scriptSetup?.returnNames.join(", ") ?? ""} }`;
|
|
1386
1485
|
const isolatedSetup = art.scriptSetupIsolated !== false;
|
|
1387
1486
|
if (scriptSetup && hasSetup && !isolatedSetup) code += `
|
|
@@ -1392,46 +1491,26 @@ ${scriptSetup.setupBody.join("\n")}
|
|
|
1392
1491
|
`;
|
|
1393
1492
|
for (const variant of art.variants) {
|
|
1394
1493
|
const variantComponentName = toPascalCase(variant.name);
|
|
1395
|
-
|
|
1396
|
-
if (
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
});
|
|
1414
|
-
|
|
1415
|
-
else if (scriptSetup && hasSetup) code += `
|
|
1416
|
-
export const ${variantComponentName} = __museaDefineComponent({
|
|
1417
|
-
name: '${variantComponentName}',
|
|
1418
|
-
${components} setup() {
|
|
1419
|
-
return __museaSharedSetup;
|
|
1420
|
-
},
|
|
1421
|
-
template: \`${fullTemplate}\`,
|
|
1422
|
-
});
|
|
1423
|
-
`;
|
|
1424
|
-
else if (componentTagName) code += `
|
|
1425
|
-
export const ${variantComponentName} = {
|
|
1426
|
-
name: '${variantComponentName}',
|
|
1427
|
-
${components} template: \`${fullTemplate}\`,
|
|
1428
|
-
};
|
|
1429
|
-
`;
|
|
1430
|
-
else code += `
|
|
1431
|
-
export const ${variantComponentName} = {
|
|
1432
|
-
name: '${variantComponentName}',
|
|
1433
|
-
template: \`${fullTemplate}\`,
|
|
1434
|
-
};
|
|
1494
|
+
const template = expandSelfTag(variant.template, componentTagName);
|
|
1495
|
+
if (options.vueVersion === 2) {
|
|
1496
|
+
code += emitLegacyVariant({
|
|
1497
|
+
variantComponentName,
|
|
1498
|
+
variantName: variant.name,
|
|
1499
|
+
template,
|
|
1500
|
+
componentTagName,
|
|
1501
|
+
componentBindingName,
|
|
1502
|
+
scriptSetup,
|
|
1503
|
+
hasSetup,
|
|
1504
|
+
isolatedSetup,
|
|
1505
|
+
setupReturn,
|
|
1506
|
+
importDeclaresName
|
|
1507
|
+
});
|
|
1508
|
+
continue;
|
|
1509
|
+
}
|
|
1510
|
+
const variantModuleId = `virtual:musea-variant:${filePath}:${encodeURIComponent(variant.name)}`;
|
|
1511
|
+
code += `
|
|
1512
|
+
import ${variantComponentName} from ${JSON.stringify(variantModuleId)};
|
|
1513
|
+
export { ${variantComponentName} };
|
|
1435
1514
|
`;
|
|
1436
1515
|
}
|
|
1437
1516
|
const defaultVariant = art.variants.find((v) => v.isDefault) || art.variants[0];
|
|
@@ -3173,6 +3252,123 @@ function generateManifestModule(artFiles) {
|
|
|
3173
3252
|
return `export const arts = ${JSON.stringify(arts, null, 2)};`;
|
|
3174
3253
|
}
|
|
3175
3254
|
//#endregion
|
|
3255
|
+
//#region src/art-variant-sfc.ts
|
|
3256
|
+
/**
|
|
3257
|
+
* Compile an `<art>` variant through the SFC pipeline.
|
|
3258
|
+
*
|
|
3259
|
+
* Variants used to be emitted as `template:` strings for Vue's runtime
|
|
3260
|
+
* compiler, which never sees the SFC pipeline. Any template expression relying
|
|
3261
|
+
* on SFC-time compilation therefore failed at render time — most importantly
|
|
3262
|
+
* TypeScript, even though `.art.vue` files are authored with
|
|
3263
|
+
* `<script setup lang="ts">` (#3857).
|
|
3264
|
+
*
|
|
3265
|
+
* Compiling the raw template with the template compiler is not enough: it
|
|
3266
|
+
* leaves TypeScript in place *and* its identifier prefixer gives up on TS
|
|
3267
|
+
* syntax, so `items[0]!.isValid` stays unprefixed and throws at runtime. Only
|
|
3268
|
+
* the SFC pipeline handles both, which is what the issue asks for — the variant
|
|
3269
|
+
* is compiled the same way the enclosing SFC is:
|
|
3270
|
+
*
|
|
3271
|
+
* :disabled="items[0]!.isValid" -> disabled: items.value[0].isValid
|
|
3272
|
+
* @u="(f: File | null) => …" -> onU: (f) => file.value = f
|
|
3273
|
+
*/
|
|
3274
|
+
/**
|
|
3275
|
+
* Rebase the art file's `<script setup>` for a virtual module.
|
|
3276
|
+
*
|
|
3277
|
+
* A variant compiles into a virtual module, and a relative specifier cannot be
|
|
3278
|
+
* resolved from one — the art module rebases its own imports for exactly this
|
|
3279
|
+
* reason, and the variant needs the same treatment or every relative import in
|
|
3280
|
+
* an art file fails to resolve.
|
|
3281
|
+
*/
|
|
3282
|
+
function rebaseScriptSetup(scriptSetup, artDir) {
|
|
3283
|
+
if (!scriptSetup.trim()) return "";
|
|
3284
|
+
const parsed = parseScriptSetupForArt(scriptSetup);
|
|
3285
|
+
return [...parsed.imports.map((statement) => rewriteRelativeImportStatement(statement, artDir)), ...parsed.setupBody].join("\n").trim();
|
|
3286
|
+
}
|
|
3287
|
+
/**
|
|
3288
|
+
* Build the synthetic SFC source for one variant.
|
|
3289
|
+
*
|
|
3290
|
+
* The art file's own `<script setup>` becomes the variant's setup block, so
|
|
3291
|
+
* bindings resolve exactly as they do in the authored file, and `lang="ts"` is
|
|
3292
|
+
* carried over so the pipeline strips TypeScript from template expressions.
|
|
3293
|
+
*/
|
|
3294
|
+
function buildVariantSfcSource(art, variantTemplate, variantName, options = {}) {
|
|
3295
|
+
if (options.sharedBindings && options.sharedBindings.names.length > 0) {
|
|
3296
|
+
const { moduleId, names } = options.sharedBindings;
|
|
3297
|
+
const escapedShared = variantName.replace(/"/g, """);
|
|
3298
|
+
return `<script setup lang="ts">\n` + (options.componentImportPath && options.componentBindingName && !names.includes(options.componentBindingName) ? `import ${options.componentBindingName} from ${JSON.stringify(options.componentImportPath)}\n` : "") + `import { ${names.join(", ")} } from ${JSON.stringify(moduleId)}\n<\/script>\n<template><div data-variant="${escapedShared}">${variantTemplate}</div></template>\n`;
|
|
3299
|
+
}
|
|
3300
|
+
const scriptSetup = rebaseScriptSetup(options.scriptSetup ?? art.scriptSetupContent ?? "", path.dirname(options.artFilePath ?? art.path));
|
|
3301
|
+
return `${`<script setup lang="ts">\n${`${options.componentImportPath && options.componentBindingName ? `import ${options.componentBindingName} from ${JSON.stringify(options.componentImportPath)}\n` : ""}${scriptSetup.trim()}`.trim()}\n<\/script>\n`}<template><div data-variant="${variantName.replace(/"/g, """)}">${variantTemplate}</div></template>\n`;
|
|
3302
|
+
}
|
|
3303
|
+
/**
|
|
3304
|
+
* Compile a variant to a self-contained ES module exporting the component.
|
|
3305
|
+
*
|
|
3306
|
+
* Each variant compiles to its own module because `compileSfc` emits a complete
|
|
3307
|
+
* module with its own `export default` and imports; concatenating several into
|
|
3308
|
+
* one art module would redeclare bindings and collide on the default export.
|
|
3309
|
+
*/
|
|
3310
|
+
function compileVariantSfc(art, variantTemplate, variantName, filename, options = {}) {
|
|
3311
|
+
const component = resolveArtComponent(art, filename, options.parsedScriptSetup ?? null, {
|
|
3312
|
+
root: options.root,
|
|
3313
|
+
scanRoots: options.scanRoots
|
|
3314
|
+
});
|
|
3315
|
+
const source = buildVariantSfcSource(art, expandSelfTag(variantTemplate, component.componentTagName), variantName, {
|
|
3316
|
+
scriptSetup: options.scriptSetup,
|
|
3317
|
+
componentImportPath: component.componentImportPath,
|
|
3318
|
+
componentBindingName: component.componentBindingName,
|
|
3319
|
+
artFilePath: filename,
|
|
3320
|
+
sharedBindings: options.sharedBindings
|
|
3321
|
+
});
|
|
3322
|
+
const result = loadNative().compileSfc(source, { filename });
|
|
3323
|
+
return {
|
|
3324
|
+
code: result.code ?? "",
|
|
3325
|
+
errors: (result.errors ?? []).map((error) => typeof error === "string" ? error : error.message ?? JSON.stringify(error))
|
|
3326
|
+
};
|
|
3327
|
+
}
|
|
3328
|
+
//#endregion
|
|
3329
|
+
//#region src/art-shared-setup.ts
|
|
3330
|
+
/**
|
|
3331
|
+
* One shared `<script setup>` instance for an art file's variants.
|
|
3332
|
+
*
|
|
3333
|
+
* `scriptSetupIsolated: false` opts an art file out of per-variant isolation:
|
|
3334
|
+
* every variant sees the same setup instance, so state written in one variant is
|
|
3335
|
+
* visible in the next. Compiling each variant as its own SFC (#3857) would give
|
|
3336
|
+
* each one its own setup and silently drop that, so the shared case hoists the
|
|
3337
|
+
* setup into this module and the variants import its bindings instead of
|
|
3338
|
+
* declaring them.
|
|
3339
|
+
*
|
|
3340
|
+
* A dedicated module rather than the art module itself, because the art module
|
|
3341
|
+
* imports the variants — routing the shared state through it would make that a
|
|
3342
|
+
* cycle.
|
|
3343
|
+
*/
|
|
3344
|
+
/**
|
|
3345
|
+
* The binding names a variant SFC should import from the shared module.
|
|
3346
|
+
*
|
|
3347
|
+
* `<script setup>` resolves template identifiers from its own bindings, and an
|
|
3348
|
+
* import is a binding, so importing each name by hand is what makes the shared
|
|
3349
|
+
* state reachable from the variant's template.
|
|
3350
|
+
*/
|
|
3351
|
+
function sharedBindingNames(parsed) {
|
|
3352
|
+
return [...new Set(parsed.returnNames)].filter((name) => /^[A-Za-z_$][\w$]*$/.test(name));
|
|
3353
|
+
}
|
|
3354
|
+
function generateSharedSetupModule(art, filePath) {
|
|
3355
|
+
const parsed = parseSharedScriptSetup(art);
|
|
3356
|
+
if (!parsed) return "export {};\n";
|
|
3357
|
+
const artDir = path.dirname(filePath);
|
|
3358
|
+
const imports = parsed.imports.map((statement) => rewriteRelativeImportStatement(statement, artDir)).join("\n");
|
|
3359
|
+
const names = sharedBindingNames(parsed);
|
|
3360
|
+
return [
|
|
3361
|
+
imports,
|
|
3362
|
+
parsed.setupBody.join("\n"),
|
|
3363
|
+
names.length > 0 ? `export { ${names.join(", ")} };` : "export {};",
|
|
3364
|
+
""
|
|
3365
|
+
].join("\n");
|
|
3366
|
+
}
|
|
3367
|
+
function parseSharedScriptSetup(art) {
|
|
3368
|
+
if (!art.scriptSetupContent) return null;
|
|
3369
|
+
return parseScriptSetupForArt(art.scriptSetupContent);
|
|
3370
|
+
}
|
|
3371
|
+
//#endregion
|
|
3176
3372
|
//#region src/plugin/virtual.ts
|
|
3177
3373
|
/**
|
|
3178
3374
|
* Virtual module handling for the Musea Vite plugin.
|
|
@@ -3183,12 +3379,28 @@ function generateManifestModule(artFiles) {
|
|
|
3183
3379
|
const VIRTUAL_MUSEA_PREFIX = "\0musea:";
|
|
3184
3380
|
const VIRTUAL_GALLERY = "\0musea-gallery";
|
|
3185
3381
|
const VIRTUAL_MANIFEST = "\0musea-manifest";
|
|
3382
|
+
/**
|
|
3383
|
+
* Recover a variant name from a virtual module id.
|
|
3384
|
+
*
|
|
3385
|
+
* `generateArtModule` percent-encodes it, so a hand-written import with an
|
|
3386
|
+
* invalid escape still falls back to the raw text instead of throwing a
|
|
3387
|
+
* `URIError` out of `load`.
|
|
3388
|
+
*/
|
|
3389
|
+
function decodeVariantName(encoded) {
|
|
3390
|
+
try {
|
|
3391
|
+
return decodeURIComponent(encoded);
|
|
3392
|
+
} catch {
|
|
3393
|
+
return encoded;
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3186
3396
|
function createResolveId(state) {
|
|
3187
3397
|
return function resolveId(id) {
|
|
3188
3398
|
const root = state.getConfigRoot();
|
|
3189
3399
|
if (id === "\0musea-gallery") return VIRTUAL_GALLERY;
|
|
3190
3400
|
if (id === "\0musea-manifest") return VIRTUAL_MANIFEST;
|
|
3191
3401
|
if (id.startsWith("virtual:musea-preview:")) return "\0musea-preview:" + id.slice(22);
|
|
3402
|
+
if (id.startsWith("virtual:musea-variant:")) return "\0musea-variant:" + id.slice(22) + "?musea-virtual";
|
|
3403
|
+
if (id.startsWith("virtual:musea-shared:")) return "\0musea-shared:" + id.slice(21) + "?musea-virtual";
|
|
3192
3404
|
if (id.startsWith("virtual:musea-art:")) {
|
|
3193
3405
|
const artPath = id.slice(18);
|
|
3194
3406
|
if (state.artFiles.has(artPath)) return "\0musea-art:" + artPath + "?musea-virtual";
|
|
@@ -3218,12 +3430,45 @@ function createLoad(state) {
|
|
|
3218
3430
|
if (art) return generatePreviewModule(art, toPascalCase(variantName), variantName, state.resolvedPreviewCss, state.resolvedPreviewSetup, state.getVueVersion());
|
|
3219
3431
|
}
|
|
3220
3432
|
}
|
|
3433
|
+
if (id.startsWith("\0musea-shared:")) {
|
|
3434
|
+
const artPath = id.slice(14).replace(/\?musea-virtual$/, "");
|
|
3435
|
+
const art = state.artFiles.get(artPath);
|
|
3436
|
+
if (art) return generateSharedSetupModule(art, artPath);
|
|
3437
|
+
}
|
|
3438
|
+
if (id.startsWith("\0musea-variant:")) {
|
|
3439
|
+
const rest = id.slice(15).replace(/\?musea-virtual$/, "");
|
|
3440
|
+
const lastColonIndex = rest.lastIndexOf(":");
|
|
3441
|
+
if (lastColonIndex !== -1) {
|
|
3442
|
+
const artPath = rest.slice(0, lastColonIndex);
|
|
3443
|
+
const variantName = decodeVariantName(rest.slice(lastColonIndex + 1));
|
|
3444
|
+
const art = state.artFiles.get(artPath);
|
|
3445
|
+
const variant = art?.variants.find((candidate) => candidate.name === variantName);
|
|
3446
|
+
if (art && variant) {
|
|
3447
|
+
const parsedScriptSetup = art.scriptSetupContent ? parseScriptSetupForArt(art.scriptSetupContent) : null;
|
|
3448
|
+
const shared = art.scriptSetupIsolated === false && parsedScriptSetup ? {
|
|
3449
|
+
moduleId: `virtual:musea-shared:${artPath}`,
|
|
3450
|
+
names: sharedBindingNames(parsedScriptSetup)
|
|
3451
|
+
} : void 0;
|
|
3452
|
+
const compiled = compileVariantSfc(art, variant.template, variant.name, artPath, {
|
|
3453
|
+
scriptSetup: art.scriptSetupContent,
|
|
3454
|
+
parsedScriptSetup,
|
|
3455
|
+
root: state.getConfigRoot(),
|
|
3456
|
+
scanRoots: state.getScanRoots(),
|
|
3457
|
+
sharedBindings: shared
|
|
3458
|
+
});
|
|
3459
|
+
if (compiled.errors.length > 0) throw new Error(`Failed to compile <art> variant "${variantName}" in ${artPath}:\n${compiled.errors.join("\n")}`);
|
|
3460
|
+
if (!compiled.code) throw new Error(`The compiler produced no code for <art> variant "${variantName}" in ${artPath}.`);
|
|
3461
|
+
return compiled.code;
|
|
3462
|
+
}
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3221
3465
|
if (id.startsWith("\0musea-art:")) {
|
|
3222
3466
|
const artPath = id.slice(11).replace(/\?musea-virtual$/, "");
|
|
3223
3467
|
const art = state.artFiles.get(artPath);
|
|
3224
3468
|
if (art) return generateArtModule(art, artPath, {
|
|
3225
3469
|
root: state.getConfigRoot(),
|
|
3226
|
-
scanRoots: state.getScanRoots()
|
|
3470
|
+
scanRoots: state.getScanRoots(),
|
|
3471
|
+
vueVersion: state.getVueVersion()
|
|
3227
3472
|
});
|
|
3228
3473
|
}
|
|
3229
3474
|
if (id.startsWith("\0musea:")) {
|
|
@@ -3231,7 +3476,8 @@ function createLoad(state) {
|
|
|
3231
3476
|
const art = state.artFiles.get(realPath);
|
|
3232
3477
|
if (art) return generateArtModule(art, realPath, {
|
|
3233
3478
|
root: state.getConfigRoot(),
|
|
3234
|
-
scanRoots: state.getScanRoots()
|
|
3479
|
+
scanRoots: state.getScanRoots(),
|
|
3480
|
+
vueVersion: state.getVueVersion()
|
|
3235
3481
|
});
|
|
3236
3482
|
}
|
|
3237
3483
|
return null;
|