Skip to content

Commit

Permalink
refactor(demo): transform sample source code at compile time (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
divdavem authored Sep 12, 2023
1 parent e23893f commit b565a62
Showing 1 changed file with 64 additions and 57 deletions.
121 changes: 64 additions & 57 deletions demo/scripts/includeSamples.plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {Frameworks} from '$lib/stores';
import {readFile} from 'fs/promises';

const samplePrefix = '@agnos-ui/samples/';
const rawSampleSuffix = '?raw&sample';

const importRegExp = /import([^;]+from)?\s*['"]([^'"]+)['"]\s*;/g;
const findDependencies = (fileContent: string) => {
Expand All @@ -22,69 +23,75 @@ export const includeSamples = (): Plugin => {
return {id: source};
}
},
async load(id, options) {
if (id.startsWith(samplePrefix)) {
const parts = id.substring(samplePrefix.length).split('/');
if (parts.length !== 2) {
throw new Error('Invalid sample path: ' + id);
}
const [componentName, sampleName] = parts;
const normalizedSampleName = `${sampleName[0].toUpperCase()}${sampleName.substring(1)}`;

const files: Record<Frameworks, {fileName: string; filePath: string}[]> = {} as any;
const addFile = async (framework: Frameworks, fileName: string, filePath: string) => {
if (!files[framework]) {
files[framework] = [];
load: {
order: 'pre',
async handler(id, options) {
if (id.endsWith(rawSampleSuffix)) {
id = id.substring(0, id.length - rawSampleSuffix.length);
let fileContent = await readFile(id, 'utf8');
fileContent = fileContent.replace(/@agnos-ui\/common\/samples\/[^/]+/g, '.');
return `export default ${JSON.stringify(fileContent)};`;
} else if (id.startsWith(samplePrefix)) {
const parts = id.substring(samplePrefix.length).split('/');
if (parts.length !== 2) {
throw new Error('Invalid sample path: ' + id);
}
if (files[framework].some((file) => file.filePath === filePath)) return;
files[framework].push({fileName, filePath});
this.addWatchFile(filePath);
const fileContent = await readFile(filePath, {encoding: 'utf8'});
const dependencies = findDependencies(fileContent);
const directory = path.dirname(filePath);
for (const dependency of dependencies) {
const dependencyParts = dependency.split('/');
if (dependencyParts[0] === '.') {
await addFile(framework, path.basename(dependency), path.join(directory, dependency));
} else if (dependency.startsWith('@agnos-ui/common/samples')) {
await addFile(framework, path.basename(dependency), path.join(__dirname, '..', '..', 'common', dependency.substring(17)));
} else {
// TODO: check that the dependency is valid and included in package.json
const [componentName, sampleName] = parts;
const normalizedSampleName = `${sampleName[0].toUpperCase()}${sampleName.substring(1)}`;

const files: Record<Frameworks, {fileName: string; filePath: string}[]> = {} as any;
const addFile = async (framework: Frameworks, fileName: string, filePath: string) => {
if (!files[framework]) {
files[framework] = [];
}
}
};
if (files[framework].some((file) => file.filePath === filePath)) return;
files[framework].push({fileName, filePath});
this.addWatchFile(filePath);
const fileContent = await readFile(filePath, {encoding: 'utf8'});
const dependencies = findDependencies(fileContent);
const directory = path.dirname(filePath);
for (const dependency of dependencies) {
const dependencyParts = dependency.split('/');
if (dependencyParts[0] === '.') {
await addFile(framework, path.basename(dependency), path.join(directory, dependency));
} else if (dependency.startsWith('@agnos-ui/common/samples')) {
await addFile(framework, path.basename(dependency), path.join(__dirname, '..', '..', 'common', dependency.substring(17)));
} else {
// TODO: check that the dependency is valid and included in package.json
}
}
};

await addFile(
'angular',
`${sampleName}.component.ts`,
path.join(__dirname, `../../angular/demo/src/app/samples/${componentName}/${sampleName}.route.ts`)
);
await addFile(
'react',
`${sampleName}.tsx`,
path.join(__dirname, `../../react/demo/app/samples/${componentName}/${normalizedSampleName}.route.tsx`)
);
await addFile(
'svelte',
`${sampleName}.svelte`,
path.join(__dirname, `../../svelte/demo/samples/${componentName}/${normalizedSampleName}.route.svelte`)
);
await addFile(
'angular',
`${sampleName}.component.ts`,
path.join(__dirname, `../../angular/demo/src/app/samples/${componentName}/${sampleName}.route.ts`)
);
await addFile(
'react',
`${sampleName}.tsx`,
path.join(__dirname, `../../react/demo/app/samples/${componentName}/${normalizedSampleName}.route.tsx`)
);
await addFile(
'svelte',
`${sampleName}.svelte`,
path.join(__dirname, `../../svelte/demo/samples/${componentName}/${normalizedSampleName}.route.svelte`)
);

let output = `export default {componentName:${JSON.stringify(componentName)},sampleName:${JSON.stringify(sampleName)},files:{`;
(Object.keys(files) as Frameworks[]).forEach((framework) => {
const frameworkFiles = files[framework];
output += `${JSON.stringify(framework)}:{entryPoint:${JSON.stringify(frameworkFiles[0].fileName)},files:{`;
frameworkFiles.forEach(({fileName, filePath}) => {
output += `[${JSON.stringify(fileName)}]: () => import(${JSON.stringify(
filePath + '?raw'
)}).then(file=>file.default).then(file=>file.replace(/@agnos-ui\\/common\\/samples\\/[^/]+/g,'.')),`;
let output = `export default {componentName:${JSON.stringify(componentName)},sampleName:${JSON.stringify(sampleName)},files:{`;
(Object.keys(files) as Frameworks[]).forEach((framework) => {
const frameworkFiles = files[framework];
output += `${JSON.stringify(framework)}:{entryPoint:${JSON.stringify(frameworkFiles[0].fileName)},files:{`;
frameworkFiles.forEach(({fileName, filePath}) => {
output += `[${JSON.stringify(fileName)}]: () => import(${JSON.stringify(filePath + rawSampleSuffix)}).then(file=>file.default),`;
});
output += `}},`;
});
output += `}},`;
});

output += `}};`;
return output;
}
output += `}};`;
return output;
}
},
},
};
};

0 comments on commit b565a62

Please sign in to comment.