socket-function 0.8.1 → 0.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SocketFunctionTypes.ts
CHANGED
|
@@ -33,13 +33,13 @@ export interface SocketFunctionHook<ExposedType extends SocketExposedInterface =
|
|
|
33
33
|
export type HookContext<ExposedType extends SocketExposedInterface = SocketExposedInterface, CallContext extends CallContextType = CallContextType> = {
|
|
34
34
|
call: CallType;
|
|
35
35
|
context: SocketRegistered["context"];
|
|
36
|
-
// If the result is overriden, we continue evaluating hooks
|
|
36
|
+
// If the result is overriden, we continue evaluating hooks BUT NOT perform the final call
|
|
37
37
|
overrideResult?: unknown;
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export type ClientHookContext<ExposedType extends SocketExposedInterface = SocketExposedInterface, CallContext extends CallContextType = CallContextType> = {
|
|
41
41
|
call: CallType;
|
|
42
|
-
// If the result is overriden, we continue evaluating hooks
|
|
42
|
+
// If the result is overriden, we continue evaluating hooks BUT NOT perform the final call
|
|
43
43
|
overrideResult?: unknown;
|
|
44
44
|
};
|
|
45
45
|
export interface SocketFunctionClientHook<ExposedType extends SocketExposedInterface = SocketExposedInterface, CallContext extends CallContextType = CallContextType> {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module.allowclient = true;
|
|
2
|
+
|
|
3
|
+
import { SocketFunction } from "../SocketFunction";
|
|
4
|
+
import { cache, lazy } from "../src/caching";
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
|
|
7
|
+
/** Hot reloads server and client files, just trigger a refresh clientside,
|
|
8
|
+
* while triggering per file re-evaluation and export updates serverside.
|
|
9
|
+
* - Requires HotReloadController to be exposed both serverside and clientside.
|
|
10
|
+
*/
|
|
11
|
+
export function watchFilesAndTriggerHotReloading() {
|
|
12
|
+
setInterval(() => {
|
|
13
|
+
for (let module of Object.values(require.cache)) {
|
|
14
|
+
if (!module) continue;
|
|
15
|
+
hotReloadModule(module);
|
|
16
|
+
}
|
|
17
|
+
}, 5000);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
const hotReloadModule = cache((module: NodeJS.Module) => {
|
|
22
|
+
if (!module.updateContents) return;
|
|
23
|
+
fs.watchFile(module.filename, { persistent: false, interval: 1000 }, (curr, prev) => {
|
|
24
|
+
if (curr.mtime.getTime() === prev.mtime.getTime()) return;
|
|
25
|
+
console.log(`Hot reloading due to change: ${module.filename}`);
|
|
26
|
+
module.updateContents?.();
|
|
27
|
+
triggerClientSideReload();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
let reloadTriggering = false;
|
|
31
|
+
let clientWatcherNodes = new Set<string>();
|
|
32
|
+
function triggerClientSideReload() {
|
|
33
|
+
if (reloadTriggering) return;
|
|
34
|
+
reloadTriggering = true;
|
|
35
|
+
setTimeout(async () => {
|
|
36
|
+
reloadTriggering = false;
|
|
37
|
+
for (let clientNodeId of clientWatcherNodes) {
|
|
38
|
+
console.log(`Notifying client of hot reload: ${clientNodeId}`);
|
|
39
|
+
HotReloadController.nodes[clientNodeId].fileUpdated().catch(() => {
|
|
40
|
+
console.log(`Removing erroring client: ${clientNodeId}`);
|
|
41
|
+
clientWatcherNodes.delete(clientNodeId);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}, 300);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
class HotReloadControllerBase {
|
|
48
|
+
async watchFiles() {
|
|
49
|
+
let callerId = HotReloadController.context.caller?.nodeId;
|
|
50
|
+
if (!callerId) {
|
|
51
|
+
throw new Error("No nodeId?");
|
|
52
|
+
}
|
|
53
|
+
clientWatcherNodes.add(callerId);
|
|
54
|
+
}
|
|
55
|
+
async fileUpdated() {
|
|
56
|
+
document.location.reload();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const HotReloadController = SocketFunction.register(
|
|
61
|
+
"HotReloadController-032b2250-3aac-4187-8c95-75412742b8f5",
|
|
62
|
+
new HotReloadControllerBase(),
|
|
63
|
+
{
|
|
64
|
+
watchFiles: {},
|
|
65
|
+
fileUpdated: {}
|
|
66
|
+
}
|
|
67
|
+
);
|
package/package.json
CHANGED
package/src/callHTTPHandler.ts
CHANGED
|
@@ -175,8 +175,8 @@ export async function httpCallHandler(request: http.IncomingMessage, response: h
|
|
|
175
175
|
|
|
176
176
|
// NOTE: Our ETag caching is only to reduce data sent on the wire, we evaluate the calls
|
|
177
177
|
// every time (so it is strictly a wire cache, not computation cache)
|
|
178
|
-
response.setHeader("cache-control", "private, s-maxage=0, max-age=0, must-revalidate");
|
|
179
178
|
if (SocketFunction.httpETagCache) {
|
|
179
|
+
response.setHeader("cache-control", "private, s-maxage=0, max-age=0, must-revalidate");
|
|
180
180
|
let hash = sha256Hash(resultBuffer);
|
|
181
181
|
response.setHeader("ETag", hash);
|
|
182
182
|
if (request.headers["if-none-match"] === hash) {
|