Add svelte as a view engine to swaf #33

Merged
ashpie merged 97 commits from svelte into develop 2021-11-09 19:31:22 +01:00
2 changed files with 26 additions and 17 deletions
Showing only changes of commit c4f71e569f - Show all commits

View File

@ -72,9 +72,6 @@ export default class SvelteViewEngine extends ViewEngine {
css, css,
] = view.split(SvelteViewEngine.getPreCompileSeparator(canonicalViewName)); ] = view.split(SvelteViewEngine.getPreCompileSeparator(canonicalViewName));
// Props (locals)
locals = Object.assign(this.getGlobals(), locals);
const localMap: Record<string, unknown> = {}; const localMap: Record<string, unknown> = {};
backendLines.split('\n').forEach(line => { backendLines.split('\n').forEach(line => {
const key = line.substring(1, line.indexOf(',') >= 0 ? line.indexOf(',') - 1 : line.length - 1); const key = line.substring(1, line.indexOf(',') >= 0 ? line.indexOf(',') - 1 : line.length - 1);
@ -140,16 +137,6 @@ export default class SvelteViewEngine extends ViewEngine {
await this.stopRollup(); await this.stopRollup();
} }
/**
* TODO: add a way to add globals from anywhere
*/
private getGlobals(): Record<string, unknown> {
return {
route: (name: string) => 'unimplemented route ' + name,
direct: 'access',
};
}
public async preCompile(canonicalName: string, alsoCompileDependents: boolean): Promise<void> { public async preCompile(canonicalName: string, alsoCompileDependents: boolean): Promise<void> {
const file = await this.resolveFileFromCanonicalName(canonicalName); const file = await this.resolveFileFromCanonicalName(canonicalName);
const intermediateFile = path.join(this.getBuildDir(), canonicalName); const intermediateFile = path.join(this.getBuildDir(), canonicalName);
@ -345,15 +332,15 @@ export default class SvelteViewEngine extends ViewEngine {
cssOutputFilename: file + '.css', cssOutputFilename: file + '.css',
}); });
const locals = this.getGlobals(); const globals = ViewEngine.getGlobals();
delete require.cache[path.resolve(file)]; delete require.cache[path.resolve(file)];
return requireFromString(svelteSsr.js.code, file).default.render({ return requireFromString(svelteSsr.js.code, file).default.render({
swaf: (key: string, args?: unknown[]) => { swaf: (key: string, args?: unknown[]) => {
if (!args) return locals[key]; if (!args) return globals[key];
const f = locals[key]; const f = globals[key];
if (typeof f !== 'function') throw new Error(key + ' is not a function.'); if (typeof f !== 'function') throw new Error(key + ' is not a function.');
return f.call(locals, ...args); return f.call(globals, ...args);
}, },
}); });
} }

View File

@ -3,8 +3,20 @@ import fs from "fs";
import chokidar, {FSWatcher} from "chokidar"; import chokidar, {FSWatcher} from "chokidar";
import {logger} from "../Logger"; import {logger} from "../Logger";
import {afs, readdirRecursively} from "../Utils"; import {afs, readdirRecursively} from "../Utils";
import {Express} from "express";
export default abstract class ViewEngine { export default abstract class ViewEngine {
private static readonly globals: Record<string, unknown> = {};
public static getGlobals(): Record<string, unknown> {
return this.globals;
}
public static setGlobal(key: string, value: unknown): void {
this.globals[key] = value;
}
protected readonly viewPaths: string[]; protected readonly viewPaths: string[];
private watcher?: FSWatcher; private watcher?: FSWatcher;
@ -42,6 +54,16 @@ export default abstract class ViewEngine {
callback: (err: Error | null, output?: string) => void, callback: (err: Error | null, output?: string) => void,
): Promise<void>; ): Promise<void>;
public setup(app: Express): void {
app.engine(this.getExtension(), (path, options, callback) => {
// Props (locals)
const locals = Object.assign(ViewEngine.getGlobals(), options);
this.render(path, locals, callback)
.catch(err => callback(err));
});
}
public getViewPaths(): string[] { public getViewPaths(): string[] {
return this.viewPaths; return this.viewPaths;
} }