diff --git a/framework/lib/view.ts b/framework/lib/view.ts index 8a1c0f6..ee672e2 100644 --- a/framework/lib/view.ts +++ b/framework/lib/view.ts @@ -56,6 +56,11 @@ export async function renderView( })); } +export function provideViews(v: typeof views, s: typeof scripts) { + views = v; + scripts = s; +} + export function joinScripts(scriptSources: string[]) { const { length } = scriptSources; if (length === 0) return ""; diff --git a/framework/watch.ts b/framework/watch.ts index 1ad18b2..af540e0 100644 --- a/framework/watch.ts +++ b/framework/watch.ts @@ -3,11 +3,11 @@ const debounceMilliseconds = 25; export async function main() { - // Catch up state + // Catch up state by running a main build. const { incr } = await generate.main(); - - // Initialize a watch + // ...and watch the files that cause invals. const watch = new Watch(rebuild); + watch.add(...incr.invals.keys()); statusLine(); function rebuild(files: string[]) { @@ -21,7 +21,7 @@ export async function main() { return; } withSpinner, any>({ - text: "Recovering State", + text: "Rebuilding", successText: generate.successText, failureText: () => "sitegen FAIL", }, async (spinner) => { @@ -34,6 +34,10 @@ export async function main() { ); const result = await generate.sitegen(spinner, incr); incr.toDisk(); // Allows picking up this state again + for (const file of watch.files) { + const relative = path.relative(hot.projectRoot, file); + if (!incr.invals.has(file)) watch.remove(file); + } return result; }).catch((err) => { console.error(util.inspect(err)); @@ -41,7 +45,6 @@ export async function main() { } function statusLine() { - watch.add(...incr.invals.keys()); console.info( `Watching ${incr.invals.size} files \x1b[36m[last change: ${ new Date().toLocaleTimeString() @@ -104,6 +107,22 @@ class Watch { } } + remove(...files: string[]) { + for (const file of files) this.files.delete(path.resolve(file)); + // Find watches that are covering no files + const { roots, watchers } = this; + const existingFiles = Array.from(this.files); + let i = roots.length; + while (i > 0) { + i -= 1; + const root = roots[i]; + if (!existingFiles.some((file) => file.startsWith(root))) { + watchers.splice(i, 1)[0].close(); + roots.splice(i, 1); + } + } + } + stop() { for (const w of this.watchers) w.close(); }