socket-function 1.1.41 → 1.1.43
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 +14 -8
- package/index.d.ts +8 -2
- package/package.json +1 -1
- package/require/RequireController.d.ts +8 -2
- package/require/RequireController.ts +18 -8
- package/src/callManager.ts +2 -1
|
@@ -4,6 +4,7 @@ module.allowclient = true;
|
|
|
4
4
|
|
|
5
5
|
import { SocketFunction } from "../SocketFunction";
|
|
6
6
|
import { cache, lazy } from "../src/caching";
|
|
7
|
+
import { createSingleton } from "../src/createSingleton";
|
|
7
8
|
import * as fs from "fs";
|
|
8
9
|
import crypto from "crypto";
|
|
9
10
|
import debugbreak from "debugbreak";
|
|
@@ -56,18 +57,23 @@ declare global {
|
|
|
56
57
|
var isHotReloading: (() => boolean) | undefined;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
// Shared across copies of this package, so the "currently hot reloading" flag is consistent no
|
|
61
|
+
// matter which copy set it (ex, setExternalHotReloading) or reads it (callManager.registerClass
|
|
62
|
+
// reads it via the globalThis.isHotReloading bridge, which each copy overwrites). See createSingleton.
|
|
63
|
+
const isHotReloadingState = createSingleton("HotReloadController.isHotReloading", 1, () => ({ value: false }));
|
|
60
64
|
export function isHotReloading() {
|
|
61
|
-
return
|
|
65
|
+
return isHotReloadingState.get().value;
|
|
62
66
|
}
|
|
63
67
|
globalThis.isHotReloading = isHotReloading;
|
|
64
68
|
export function hotReloadingGuard(): true {
|
|
65
69
|
return !isHotReloading() as any;
|
|
66
70
|
}
|
|
67
71
|
export function setExternalHotReloading(value: boolean) {
|
|
68
|
-
|
|
72
|
+
isHotReloadingState.get().value = value;
|
|
69
73
|
}
|
|
70
|
-
|
|
74
|
+
// Shared across copies, so callbacks registered through one copy's onHotReload still fire when the
|
|
75
|
+
// first-registered copy's controller performs a reload. See createSingleton.
|
|
76
|
+
const hotReloadCallbacks = createSingleton("HotReloadController.hotReloadCallbacks", 1, () => [] as ((modules: NodeJS.Module[]) => void)[]).get();
|
|
71
77
|
export function onHotReload(callback: (modules: NodeJS.Module[]) => void) {
|
|
72
78
|
hotReloadCallbacks.push(callback);
|
|
73
79
|
}
|
|
@@ -124,7 +130,7 @@ const hotReloadModule = cache((module: NodeJS.Module) => {
|
|
|
124
130
|
|| module.moduleContents?.includes("\r\nmodule.hotreload = true;" + "\r\n")
|
|
125
131
|
) {
|
|
126
132
|
console.log(`Serverside reloading ${module.id}`);
|
|
127
|
-
|
|
133
|
+
isHotReloadingState.get().value = true;
|
|
128
134
|
try {
|
|
129
135
|
module.loaded = false;
|
|
130
136
|
module.load(module.id);
|
|
@@ -133,7 +139,7 @@ const hotReloadModule = cache((module: NodeJS.Module) => {
|
|
|
133
139
|
console.error(e);
|
|
134
140
|
} finally {
|
|
135
141
|
setTimeout(() => {
|
|
136
|
-
|
|
142
|
+
isHotReloadingState.get().value = false;
|
|
137
143
|
}, 1000);
|
|
138
144
|
}
|
|
139
145
|
}
|
|
@@ -215,12 +221,12 @@ class HotReloadControllerBase {
|
|
|
215
221
|
for (let module of modules) {
|
|
216
222
|
module.loaded = false;
|
|
217
223
|
}
|
|
218
|
-
|
|
224
|
+
isHotReloadingState.get().value = true;
|
|
219
225
|
try {
|
|
220
226
|
await Promise.all(modules.map(module => module.load(module.filename)));
|
|
221
227
|
} finally {
|
|
222
228
|
setTimeout(() => {
|
|
223
|
-
|
|
229
|
+
isHotReloadingState.get().value = false;
|
|
224
230
|
}, 1000);
|
|
225
231
|
}
|
|
226
232
|
|
package/index.d.ts
CHANGED
|
@@ -360,8 +360,14 @@ declare module "socket-function/require/RequireController" {
|
|
|
360
360
|
declare function addStaticRoot(root: string): void;
|
|
361
361
|
type GetModulesResult = ReturnType<RequireControllerBase["getModules"]> extends Promise<infer T> ? T : never;
|
|
362
362
|
export type GetModulesArgs = Parameters<RequireControllerBase["getModules"]>;
|
|
363
|
-
declare
|
|
364
|
-
remap(result: GetModulesResult, args:
|
|
363
|
+
declare const mapGetModules: {
|
|
364
|
+
remap(result: GetModulesResult, args: [pathRequests: string[], alreadyHave?: {
|
|
365
|
+
requireSeqNumProcessId: string;
|
|
366
|
+
seqNumRanges: {
|
|
367
|
+
s: number;
|
|
368
|
+
e?: number;
|
|
369
|
+
}[];
|
|
370
|
+
} | undefined, config?: {} | undefined]): Promise<GetModulesResult>;
|
|
365
371
|
}[];
|
|
366
372
|
declare function addMapGetModules(remap: typeof mapGetModules[number]["remap"]): void;
|
|
367
373
|
declare class RequireControllerBase {
|
package/package.json
CHANGED
|
@@ -45,8 +45,14 @@ declare function injectHTMLBeforeStartup(text: string | (() => Promise<string>))
|
|
|
45
45
|
declare function addStaticRoot(root: string): void;
|
|
46
46
|
type GetModulesResult = ReturnType<RequireControllerBase["getModules"]> extends Promise<infer T> ? T : never;
|
|
47
47
|
export type GetModulesArgs = Parameters<RequireControllerBase["getModules"]>;
|
|
48
|
-
declare
|
|
49
|
-
remap(result: GetModulesResult, args:
|
|
48
|
+
declare const mapGetModules: {
|
|
49
|
+
remap(result: GetModulesResult, args: [pathRequests: string[], alreadyHave?: {
|
|
50
|
+
requireSeqNumProcessId: string;
|
|
51
|
+
seqNumRanges: {
|
|
52
|
+
s: number;
|
|
53
|
+
e?: number;
|
|
54
|
+
}[];
|
|
55
|
+
} | undefined, config?: {} | undefined]): Promise<GetModulesResult>;
|
|
50
56
|
}[];
|
|
51
57
|
declare function addMapGetModules(remap: typeof mapGetModules[number]["remap"]): void;
|
|
52
58
|
declare class RequireControllerBase {
|
|
@@ -6,6 +6,7 @@ import { getCurrentHTTPRequest, setHTTPResultHeaders } from "../src/callHTTPHand
|
|
|
6
6
|
import { formatNumberSuffixed, isNode, isNodeTrue, sha256Hash, sha256HashPromise } from "../src/misc";
|
|
7
7
|
import zlib from "zlib";
|
|
8
8
|
import { cacheLimited, lazy } from "../src/caching";
|
|
9
|
+
import { createSingleton } from "../src/createSingleton";
|
|
9
10
|
import { formatNumber } from "../src/formatting/format";
|
|
10
11
|
import { requireMain } from "./require";
|
|
11
12
|
import path from "path";
|
|
@@ -88,11 +89,16 @@ const resolvedHTMLFile = lazy(() => {
|
|
|
88
89
|
);
|
|
89
90
|
});
|
|
90
91
|
|
|
91
|
-
|
|
92
|
+
// All of these are mutated by the static helpers below (injectHTMLBeforeStartup, addStaticRoot,
|
|
93
|
+
// addMapGetModules), which callers invoke on RequireController. But only the first-registered
|
|
94
|
+
// copy's controller actually serves requireHTML/getModules, and it reads these vars. So they must
|
|
95
|
+
// be shared across copies, or a caller using a different copy would add (ex) before-entry HTML
|
|
96
|
+
// that the serving controller never reads. See createSingleton.
|
|
97
|
+
const beforeEntryText = createSingleton("RequireController.beforeEntryText", 1, () => [] as (string | (() => Promise<string>))[]).get();
|
|
92
98
|
function injectHTMLBeforeStartup(text: string | (() => Promise<string>)) {
|
|
93
99
|
beforeEntryText.push(text);
|
|
94
100
|
}
|
|
95
|
-
|
|
101
|
+
const staticRoots = createSingleton("RequireController.staticRoots", 1, () => [] as string[]).get();
|
|
96
102
|
function addStaticRoot(root: string) {
|
|
97
103
|
if (!root.endsWith("/")) {
|
|
98
104
|
root += "/";
|
|
@@ -102,9 +108,9 @@ function addStaticRoot(root: string) {
|
|
|
102
108
|
|
|
103
109
|
type GetModulesResult = ReturnType<RequireControllerBase["getModules"]> extends Promise<infer T> ? T : never;
|
|
104
110
|
export type GetModulesArgs = Parameters<RequireControllerBase["getModules"]>;
|
|
105
|
-
|
|
111
|
+
const mapGetModules = createSingleton("RequireController.mapGetModules", 1, () => [] as {
|
|
106
112
|
remap(result: GetModulesResult, args: GetModulesArgs): Promise<GetModulesResult>
|
|
107
|
-
}[]
|
|
113
|
+
}[]).get();
|
|
108
114
|
function addMapGetModules(remap: typeof mapGetModules[number]["remap"]) {
|
|
109
115
|
mapGetModules.push({ remap });
|
|
110
116
|
}
|
|
@@ -421,7 +427,7 @@ async function compressCached(bufferKey: string, buffer: () => Buffer): Promise<
|
|
|
421
427
|
export function getIsAllowClient(module: NodeJS.Module) {
|
|
422
428
|
if (module.serveronly) return false;
|
|
423
429
|
// IMPORTANT! We do not allow everything in node modules by default, as most things in node modules, you don't want to import client-side, and it will break if you import it client-side. Many of these are imported, but will never end up being called client-side, so it's fine to exclude them.
|
|
424
|
-
if (allowAllNodeModulesFlag && module.filename.includes("node_modules")) {
|
|
430
|
+
if (allowAllNodeModulesFlag.get().value && module.filename.includes("node_modules")) {
|
|
425
431
|
return true;
|
|
426
432
|
}
|
|
427
433
|
return module.allowclient;
|
|
@@ -434,7 +440,9 @@ declare global {
|
|
|
434
440
|
var remapImportRequestsClientside: undefined | ClientRemapCallback[];
|
|
435
441
|
}
|
|
436
442
|
|
|
437
|
-
|
|
443
|
+
// Shared across copies of this package, so the registered controller and rootResolvePath (set by
|
|
444
|
+
// setRequireBootRequire) are the same instance everyone reads/writes. See createSingleton.
|
|
445
|
+
const baseController = createSingleton("RequireController.baseController", 1, () => new RequireControllerBase()).get();
|
|
438
446
|
/** @deprecated, not needed, as this defaults to ".", which is a lot easier to reason about anyways. */
|
|
439
447
|
export function setRequireBootRequire(dir: string) {
|
|
440
448
|
dir = path.resolve(dir);
|
|
@@ -445,9 +453,11 @@ export function setRequireBootRequire(dir: string) {
|
|
|
445
453
|
baseController.rootResolvePath = dir;
|
|
446
454
|
}
|
|
447
455
|
|
|
448
|
-
|
|
456
|
+
// Shared across copies, so calling allowAllNodeModules() on any copy is seen by the serving
|
|
457
|
+
// controller's getIsAllowClient. See createSingleton.
|
|
458
|
+
const allowAllNodeModulesFlag = createSingleton("RequireController.allowAllNodeModules", 1, () => ({ value: false }));
|
|
449
459
|
export function allowAllNodeModules() {
|
|
450
|
-
allowAllNodeModulesFlag = true;
|
|
460
|
+
allowAllNodeModulesFlag.get().value = true;
|
|
451
461
|
}
|
|
452
462
|
|
|
453
463
|
export const RequireController = SocketFunction.register(
|
package/src/callManager.ts
CHANGED
|
@@ -86,7 +86,8 @@ export function registerClass(classGuid: string, controller: SocketExposedInterf
|
|
|
86
86
|
noFunctionMeasure?: boolean;
|
|
87
87
|
}) {
|
|
88
88
|
if (!globalThis.isHotReloading?.() && classes[classGuid]) {
|
|
89
|
-
|
|
89
|
+
console.warn(`Class ${classGuid} already registered. This is normal if you are using multiple copies of socket-function at once.`);
|
|
90
|
+
return;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
if (!config?.noFunctionMeasure) {
|