socket-function 0.124.0 → 0.126.0
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/hot/HotReloadController.ts +54 -8
- package/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -5,10 +5,12 @@ module.allowclient = true;
|
|
|
5
5
|
import { SocketFunction } from "../SocketFunction";
|
|
6
6
|
import { cache, lazy } from "../src/caching";
|
|
7
7
|
import * as fs from "fs";
|
|
8
|
+
import crypto from "crypto";
|
|
8
9
|
import debugbreak from "debugbreak";
|
|
9
10
|
import { isNode } from "../src/misc";
|
|
10
11
|
import { magenta, red } from "../src/formatting/logColors";
|
|
11
12
|
import { formatTime } from "../src/formatting/format";
|
|
13
|
+
import { batchFunction } from "../src/batching";
|
|
12
14
|
|
|
13
15
|
/** Enables some hot reload functionality.
|
|
14
16
|
* - Triggers a refresh clientside
|
|
@@ -46,6 +48,8 @@ declare global {
|
|
|
46
48
|
* - Also useful if you want files to hotreload clientside, but not serverside.
|
|
47
49
|
*/
|
|
48
50
|
noserverhotreload?: boolean;
|
|
51
|
+
|
|
52
|
+
watchAdditionalFiles?: string[];
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
var isHotReloading: (() => boolean) | undefined;
|
|
@@ -75,9 +79,41 @@ const hotReloadModule = cache((module: NodeJS.Module) => {
|
|
|
75
79
|
interval = 10;
|
|
76
80
|
fast = true;
|
|
77
81
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
|
|
83
|
+
let lastHashes = new Map<string, string>();
|
|
84
|
+
function getHash(path: string) {
|
|
85
|
+
try {
|
|
86
|
+
let contents = fs.readFileSync(path, "utf8");
|
|
87
|
+
return crypto.createHash("sha256").update(contents).digest("hex");
|
|
88
|
+
} catch {
|
|
89
|
+
return "";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
watchFile(module.filename);
|
|
94
|
+
for (let path of module.watchAdditionalFiles || []) {
|
|
95
|
+
watchFile(path);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function watchFile(path: string) {
|
|
99
|
+
lastHashes.set(path, getHash(path));
|
|
100
|
+
fs.watchFile(path, { persistent: false, interval }, (curr, prev) => {
|
|
101
|
+
let newHash = getHash(path);
|
|
102
|
+
if (newHash === lastHashes.get(path)) return;
|
|
103
|
+
lastHashes.set(path, newHash);
|
|
104
|
+
if (path === module.filename) {
|
|
105
|
+
console.log(`Hot reloading ${module.filename} due to change`);
|
|
106
|
+
} else {
|
|
107
|
+
console.log(`Hot reloading ${module.filename} due to change in ${path}`);
|
|
108
|
+
}
|
|
109
|
+
doHotReload(curr.mtimeMs);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
// IMPORTANT! changeTime is for benchmarking how long we took to hotreload (and nothing else)
|
|
116
|
+
function doHotReload(changeTime: number) {
|
|
81
117
|
module.updateContents?.();
|
|
82
118
|
if (isNode() && !module.noserverhotreload) {
|
|
83
119
|
if (
|
|
@@ -104,34 +140,44 @@ const hotReloadModule = cache((module: NodeJS.Module) => {
|
|
|
104
140
|
callback([module]);
|
|
105
141
|
}
|
|
106
142
|
}
|
|
143
|
+
//module.sourceSHA256;
|
|
144
|
+
// crypto.createHash("sha256").update(contents).digest("hex")
|
|
107
145
|
if (module.allowclient) {
|
|
108
146
|
triggerClientSideReload({
|
|
109
147
|
files: [module.filename],
|
|
110
|
-
changeTime
|
|
148
|
+
changeTime,
|
|
111
149
|
fast,
|
|
112
150
|
});
|
|
113
151
|
}
|
|
114
|
-
}
|
|
152
|
+
}
|
|
115
153
|
});
|
|
116
154
|
let reloadTriggering = false;
|
|
117
155
|
let clientWatcherNodes = new Set<string>();
|
|
156
|
+
let pendingTriggerFiles = new Set<string>();
|
|
118
157
|
function triggerClientSideReload(config: {
|
|
119
158
|
files: string[];
|
|
120
159
|
changeTime: number;
|
|
121
160
|
fast?: boolean;
|
|
122
161
|
}) {
|
|
162
|
+
for (let file of config.files) {
|
|
163
|
+
pendingTriggerFiles.add(file);
|
|
164
|
+
}
|
|
123
165
|
if (reloadTriggering) return;
|
|
124
166
|
reloadTriggering = true;
|
|
125
167
|
setTimeout(async () => {
|
|
126
168
|
reloadTriggering = false;
|
|
169
|
+
let files = Array.from(pendingTriggerFiles);
|
|
170
|
+
pendingTriggerFiles.clear();
|
|
127
171
|
for (let clientNodeId of clientWatcherNodes) {
|
|
128
|
-
console.log(`Notifying client of hot reload: ${clientNodeId}
|
|
129
|
-
HotReloadController.nodes[clientNodeId].fileUpdated(
|
|
172
|
+
console.log(`Notifying client of hot reload: ${clientNodeId}`, files);
|
|
173
|
+
HotReloadController.nodes[clientNodeId].fileUpdated(files, config.changeTime).catch(() => {
|
|
130
174
|
console.log(`Removing erroring client: ${clientNodeId}`);
|
|
131
175
|
clientWatcherNodes.delete(clientNodeId);
|
|
132
176
|
});
|
|
133
177
|
}
|
|
134
|
-
|
|
178
|
+
// We need to wait, otherwise batched updates fail, WHICH, can result in updates while reloading,
|
|
179
|
+
// which causes missed updates.
|
|
180
|
+
}, config.fast ? 50 : 300);
|
|
135
181
|
}
|
|
136
182
|
|
|
137
183
|
class HotReloadControllerBase {
|
package/index.d.ts
CHANGED