authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-06-10 22:29:12-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2025-10-14 02:40:44-07:00
log69a5d0ab42a5b739a835fea2fe2735e93eba30fd
tree2484902fd0cc4ffdf3aac68ba15309ef2ed50060
parenta176037c3c37afa39eac946515d3d5a533076674
signature Commit is signed but in an unrecognized format.

clean up watching


2 files changed, 29 insertions(+), 5 deletions(-)

framework/lib/view.ts+5
...@@ -56,6 +56,11 @@ export async function renderView(...@@ -56,6 +56,11 @@ export async function renderView(
56 })); 56 }));
57} 57}
58 58
59export function provideViews(v: typeof views, s: typeof scripts) {
60 views = v;
61 scripts = s;
62}
63
59export function joinScripts(scriptSources: string[]) { 64export function joinScripts(scriptSources: string[]) {
60 const { length } = scriptSources; 65 const { length } = scriptSources;
61 if (length === 0) return ""; 66 if (length === 0) return "";
framework/watch.ts+24-5
...@@ -3,11 +3,11 @@...@@ -3,11 +3,11 @@
3const debounceMilliseconds = 25; 3const debounceMilliseconds = 25;
4 4
5export async function main() { 5export async function main() {
6 // Catch up state 6 // Catch up state by running a main build.
7 const { incr } = await generate.main(); 7 const { incr } = await generate.main();
8 8 // ...and watch the files that cause invals.
9 // Initialize a watch
10 const watch = new Watch(rebuild); 9 const watch = new Watch(rebuild);
10 watch.add(...incr.invals.keys());
11 statusLine(); 11 statusLine();
12 12
13 function rebuild(files: string[]) { 13 function rebuild(files: string[]) {
...@@ -21,7 +21,7 @@ export async function main() {...@@ -21,7 +21,7 @@ export async function main() {
21 return; 21 return;
22 } 22 }
23 withSpinner<Record<string, unknown>, any>({ 23 withSpinner<Record<string, unknown>, any>({
24 text: "Recovering State", 24 text: "Rebuilding",
25 successText: generate.successText, 25 successText: generate.successText,
26 failureText: () => "sitegen FAIL", 26 failureText: () => "sitegen FAIL",
27 }, async (spinner) => { 27 }, async (spinner) => {
...@@ -34,6 +34,10 @@ export async function main() {...@@ -34,6 +34,10 @@ export async function main() {
34 ); 34 );
35 const result = await generate.sitegen(spinner, incr); 35 const result = await generate.sitegen(spinner, incr);
36 incr.toDisk(); // Allows picking up this state again 36 incr.toDisk(); // Allows picking up this state again
37 for (const file of watch.files) {
38 const relative = path.relative(hot.projectRoot, file);
39 if (!incr.invals.has(file)) watch.remove(file);
40 }
37 return result; 41 return result;
38 }).catch((err) => { 42 }).catch((err) => {
39 console.error(util.inspect(err)); 43 console.error(util.inspect(err));
...@@ -41,7 +45,6 @@ export async function main() {...@@ -41,7 +45,6 @@ export async function main() {
41 } 45 }
42 46
43 function statusLine() { 47 function statusLine() {
44 watch.add(...incr.invals.keys());
45 console.info( 48 console.info(
46 `Watching ${incr.invals.size} files \x1b[36m[last change: ${ 49 `Watching ${incr.invals.size} files \x1b[36m[last change: ${
47 new Date().toLocaleTimeString() 50 new Date().toLocaleTimeString()
...@@ -104,6 +107,22 @@ class Watch {...@@ -104,6 +107,22 @@ class Watch {
104 } 107 }
105 } 108 }
106 109
110 remove(...files: string[]) {
111 for (const file of files) this.files.delete(path.resolve(file));
112 // Find watches that are covering no files
113 const { roots, watchers } = this;
114 const existingFiles = Array.from(this.files);
115 let i = roots.length;
116 while (i > 0) {
117 i -= 1;
118 const root = roots[i];
119 if (!existingFiles.some((file) => file.startsWith(root))) {
120 watchers.splice(i, 1)[0].close();
121 roots.splice(i, 1);
122 }
123 }
124 }
125
107 stop() { 126 stop() {
108 for (const w of this.watchers) w.close(); 127 for (const w of this.watchers) w.close();
109 } 128 }