Readme

ReloadScript: Reload HTML pages on new versions a val or its dependencies

Setup

  1. Fork this val
  2. Include ReloadScript(import.meta.url) in your HTML output

Example

import { htmlResponse } from "https://esm.town/v/postpostscript/htmlComponentLibrary"; import { ReloadScript } from "https://esm.town/v/[username]/ReloadScript"; export default async function(req: Request): Promise<Response> { return htmlResponse` It worked!!! ${Math.random()} ${ReloadScript(import.meta.url)} `; }

Todo

  • use import list to pare down dependency list and prevent unnecessary reloads

forked from @stevekrouse/ReloadScript

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import { extractValInfo } from "https://esm.town/v/pomdtr/extractValInfo";
import { getDependencies } from "https://esm.town/v/postpostscript/getDependencyGraph";
import { html } from "https://esm.town/v/postpostscript/html";
import { provideBlob } from "https://esm.town/v/postpostscript/provideBlob";
import { typescriptProxyUrl } from "https://esm.town/v/postpostscript/typescriptProxy";
import { getCurrentValVersionNumber } from "https://esm.town/v/stevekrouse/getCurrentValVersionNumber";
import { parentReference } from "https://esm.town/v/stevekrouse/parentReference";
const id = ({ userHandle, valName }) => `${userHandle}/${valName}`;
export const reloadOnVals = async function(vals: { userHandle: string; valName: string }[], delay = 500) {
const initialVersions = Object.fromEntries(
await Promise.all(vals.map(async (val) => {
return [
id(val),
await getCurrentValVersionNumber(val),
];
})),
);
let timeout;
const check = async () => {
for await (const val of vals) {
const newVersion = await getCurrentValVersionNumber(val);
if (newVersion !== initialVersions[id(val)]) {
console.log("val changed, reloading", id(val));
window.location.reload();
return;
}
await new Promise(resolve => setTimeout(resolve, delay));
}
timeout = setTimeout(check, delay);
};
check();
return () => {
clearTimeout(timeout);
};
};
export const ReloadScript = (
url: string,
{ maxDepth = 3, maxDependencies = 8 } = {},
filter = (value: string) => true,
) => {
return html`
<script type="module">
import { reloadOnVals } from "${
typescriptProxyUrl(import.meta.url, {
excludeExtensions: [".ts"],
})
}"
${
provideBlob(async () => {
const dependencies = [];
for await (
const dependency of getDependencies(url.split("?")[0], maxDepth, (module) => {
console.log(module);
return !module.version;
})
) {
if (!filter(dependency.id)) {
continue;
}
const { author, name } = extractValInfo(dependency.id);
dependencies.push({
userHandle: author,
valName: name,
});
if (dependencies.length === maxDependencies) {
break;
}
}
return JSON.stringify(dependencies);
}).jsPromise()
}
.then(blob => blob.text())
.then(text => JSON.parse(text))
.then(vals => {
console.log("auto reloading on changes for these vals:", vals)
window.stopReload = reloadOnVals(vals)
})
</script>
`;
};
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
March 1, 2024