mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
SceneShotList and SceneOptions render the project from a gev-scenes store instead of scenePresentation building rows with createElement. SceneControls stays the owner: it publishes the director's state and attaches the row actions, and a late destroy cannot detach a newer owner. Rows keep their identity across selection; a rename keeps its typed text across republishing and ends with its row. The select still changes its choice only when its options are rendered. Vue keeps whitespace in every component, so Prettier formats single-file components with strict whitespace sensitivity, and the test loader parses templates with the same options as the browser build. The i18n check reads view text without its interpolations, whose t() calls are scanned with the sources.
54 lines
1.8 KiB
JavaScript
54 lines
1.8 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { compileScript, compileTemplate, parse } from 'vue/compiler-sfc';
|
|
import { VUE_TEMPLATE_OPTIONS } from './vueOptions.js';
|
|
|
|
/**
|
|
* Compile a single-file component to an ES module for Node, so unit tests (the
|
|
* application's and a host's) can import components without a bundler.
|
|
* Styles are dropped: tests read the global stylesheet separately.
|
|
*/
|
|
export function compileVueModule(source, filename) {
|
|
// The template is parsed with the SFC; parse it as the browser build does.
|
|
const { descriptor, errors } = parse(source, {
|
|
filename,
|
|
templateParseOptions: VUE_TEMPLATE_OPTIONS.compilerOptions,
|
|
});
|
|
if (errors.length) throw errors[0];
|
|
const id = filename;
|
|
if (descriptor.scriptSetup) {
|
|
return compileScript(descriptor, {
|
|
id,
|
|
inlineTemplate: true,
|
|
templateOptions: VUE_TEMPLATE_OPTIONS,
|
|
}).content;
|
|
}
|
|
const script = descriptor.script
|
|
? compileScript(descriptor, { id, genDefaultAs: '__sfc__' }).content
|
|
: 'const __sfc__ = {};';
|
|
let template = '';
|
|
if (descriptor.template) {
|
|
const compiled = compileTemplate({
|
|
source: descriptor.template.content,
|
|
filename,
|
|
id,
|
|
...VUE_TEMPLATE_OPTIONS,
|
|
});
|
|
if (compiled.errors.length) throw compiled.errors[0];
|
|
template = compiled.code;
|
|
}
|
|
return `${script}\n${template}\nif (typeof render === 'function') __sfc__.render = render;\nexport default __sfc__;\n`;
|
|
}
|
|
|
|
/** Node module hook: load `.vue` files as compiled modules. */
|
|
export async function load(url, context, nextLoad) {
|
|
if (!url.endsWith('.vue')) return nextLoad(url, context);
|
|
const filename = fileURLToPath(url);
|
|
const source = await readFile(filename, 'utf8');
|
|
return {
|
|
format: 'module',
|
|
source: compileVueModule(source, filename),
|
|
shortCircuit: true,
|
|
};
|
|
}
|