1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import { InjectHTMLElementStream } from "https://esm.town/v/andreterron/InjectHTMLElementStream?v=9";
import { rootValRef } from "https://esm.town/v/andreterron/rootValRef?v=3";
import { ValRef } from "https://esm.town/v/andreterron/ValRef?v=1";
import { getCurrentValVersionNumber } from "https://esm.town/v/stevekrouse/getCurrentValVersionNumber";
import { modifyResponse } from "https://esm.town/v/stevekrouse/modifyResponse";
import { parentReference } from "https://esm.town/v/stevekrouse/parentReference";
import type { MiddlewareHandler } from "npm:hono";
// this script runs client-side
export const reloadOnVals = async function(vals: ValRef[]) {
const valVersions = await Promise.all(vals.map(getCurrentValVersionNumber));
// console.log("initialValVersions: ", valVersions);
const interval = setInterval(async () => {
let newValVersions = await Promise.all(vals.map(getCurrentValVersionNumber));
// console.log("newValVersions: ", newValVersions);
if (JSON.stringify(newValVersions) !== JSON.stringify(valVersions)) {
clearInterval(interval);
window.location.reload();
}
}, 1000);
};
// experimental - don't use this
export function reloadOnSaveHonoMiddleware(vals: ValRef[] = [rootValRef()]): MiddlewareHandler {
return async function(c, next) {
await next();
// don't reload on custom domains, only reload on val.run URLs
if (!new URL(c.req.url).hostname.includes("val.run")) {
return;
}
c.res = modifyResponse(
c.res,
new InjectHTMLElementStream(ReloadScriptText(vals)),
);
};
}
/**
* @param handler http val's fetch handler
* @param vals to watch
*/
export function reloadOnSaveFetchMiddleware(
handler: (req: Request) => Response | Promise<Response>,
vals = [rootValRef()],
): (req: Request) => Promise<Response> {
return async (req: Request): Promise<Response> => {
const res = await handler(req);
// don't reload on custom domains, only reload on val.run URLs
if (!new URL(req.url).hostname.includes("val.run")) {
return res;
}
return modifyResponse(
res,
new InjectHTMLElementStream(ReloadScriptText(vals)),
);
};
}
// generates a script element as a string
export const ReloadScriptText = (vals = [rootValRef()]) =>
`<script type="module">
import { reloadOnVals } from "${import.meta.url}"
reloadOnVals(${JSON.stringify(vals)})
</script>`;