querysub 0.437.0 → 0.438.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/.eslintrc.js +50 -50
- package/bin/deploy.js +0 -0
- package/bin/function.js +0 -0
- package/bin/server.js +0 -0
- package/costsBenefits.txt +115 -115
- package/deploy.ts +2 -2
- package/package.json +1 -1
- package/spec.txt +1192 -1192
- package/src/-a-archives/archives.ts +202 -202
- package/src/-a-archives/archivesDisk.ts +454 -454
- package/src/-a-auth/certs.ts +540 -540
- package/src/-a-auth/node-forge-ed25519.d.ts +16 -16
- package/src/-b-authorities/dnsAuthority.ts +138 -138
- package/src/-c-identity/IdentityController.ts +258 -258
- package/src/-d-trust/NetworkTrust2.ts +180 -180
- package/src/-e-certs/EdgeCertController.ts +252 -252
- package/src/-e-certs/certAuthority.ts +201 -201
- package/src/-f-node-discovery/NodeDiscovery.ts +640 -640
- package/src/-g-core-values/NodeCapabilities.ts +200 -200
- package/src/-h-path-value-serialize/stringSerializer.ts +175 -175
- package/src/0-path-value-core/PathValueCommitter.ts +468 -468
- package/src/0-path-value-core/PathValueController.ts +0 -2
- package/src/2-proxy/PathValueProxyWatcher.ts +2542 -2542
- package/src/2-proxy/TransactionDelayer.ts +94 -94
- package/src/2-proxy/pathDatabaseProxyBase.ts +36 -36
- package/src/2-proxy/pathValueProxy.ts +159 -159
- package/src/3-path-functions/PathFunctionRunnerMain.ts +87 -87
- package/src/3-path-functions/pathFunctionLoader.ts +516 -516
- package/src/3-path-functions/tests/rejectTest.ts +76 -76
- package/src/4-deploy/deployCheck.ts +6 -6
- package/src/4-dom/css.tsx +29 -29
- package/src/4-dom/cssTypes.d.ts +211 -211
- package/src/4-dom/qreact.tsx +2799 -2799
- package/src/4-dom/qreactTest.tsx +410 -410
- package/src/4-querysub/permissions.ts +335 -335
- package/src/4-querysub/querysubPrediction.ts +483 -483
- package/src/5-diagnostics/qreactDebug.tsx +377 -346
- package/src/TestController.ts +34 -34
- package/src/bits.ts +104 -104
- package/src/buffers.ts +69 -69
- package/src/diagnostics/ActionsHistory.ts +57 -57
- package/src/diagnostics/listenOnDebugger.ts +71 -71
- package/src/diagnostics/periodic.ts +111 -111
- package/src/diagnostics/trackResources.ts +91 -91
- package/src/diagnostics/watchdog.ts +120 -120
- package/src/errors.ts +133 -133
- package/src/forceProduction.ts +2 -2
- package/src/fs.ts +80 -80
- package/src/functional/diff.ts +857 -857
- package/src/functional/promiseCache.ts +78 -78
- package/src/functional/random.ts +8 -8
- package/src/functional/stats.ts +60 -60
- package/src/heapDumps.ts +665 -665
- package/src/https.ts +1 -1
- package/src/library-components/AspectSizedComponent.tsx +87 -87
- package/src/library-components/ButtonSelector.tsx +64 -64
- package/src/library-components/DropdownCustom.tsx +150 -150
- package/src/library-components/DropdownSelector.tsx +31 -31
- package/src/library-components/InlinePopup.tsx +66 -66
- package/src/misc/color.ts +29 -29
- package/src/misc/hash.ts +83 -83
- package/src/misc/ipPong.js +13 -13
- package/src/misc/networking.ts +1 -1
- package/src/misc/random.ts +44 -44
- package/src/misc.ts +196 -196
- package/src/path.ts +255 -255
- package/src/persistentLocalStore.ts +41 -41
- package/src/promise.ts +14 -14
- package/src/storage/fileSystemPointer.ts +71 -71
- package/src/test/heapProcess.ts +35 -35
- package/src/zip.ts +15 -15
- package/tsconfig.json +26 -26
- package/yarnSpec.txt +56 -56
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import { isNode, list } from "socket-function/src/misc";
|
|
2
|
-
import inspector from "inspector";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import { getSubFolder } from "../fs";
|
|
5
|
-
import { SocketFunction } from "socket-function/SocketFunction";
|
|
6
|
-
import debugbreak from "debugbreak";
|
|
7
|
-
import http from "http";
|
|
8
|
-
import { lazy } from "socket-function/src/caching";
|
|
9
|
-
|
|
10
|
-
let devToolsUrl = "";
|
|
11
|
-
|
|
12
|
-
const listenOnDebugger = lazy(function listenOnDebugger() {
|
|
13
|
-
if (devToolsUrl) return;
|
|
14
|
-
if (!isNode()) return;
|
|
15
|
-
// IMPORTANT! NEVER use the built-in port. This adds a tiny bit of security. Not much,
|
|
16
|
-
// as port scanning is easier (there are only 65K ports!), but... at least port scanning
|
|
17
|
-
// is loud, so if a site port scans all of it's users it will probably get flagged by
|
|
18
|
-
// chrome fairly quickly as being malicious.
|
|
19
|
-
let url = baseGetInspectorUrl();
|
|
20
|
-
|
|
21
|
-
devToolsUrl = `devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&${url.replace("://", "=")}`;
|
|
22
|
-
devToolsUrl = devToolsUrl.replace("devtools://devtools/bundled", "https://notdevtools.com/devtools");
|
|
23
|
-
console.log(`Debugger listening on ${devToolsUrl}`);
|
|
24
|
-
|
|
25
|
-
const ext = ".url";
|
|
26
|
-
const debuggerFolder = getSubFolder("debugger");
|
|
27
|
-
let otherDebuggers = fs.readdirSync(debuggerFolder);
|
|
28
|
-
otherDebuggers = otherDebuggers.filter(x => x.endsWith(ext));
|
|
29
|
-
// Delete all files for processes that no longer exist
|
|
30
|
-
for (let other of otherDebuggers) {
|
|
31
|
-
let pid = +other.split("-")[0];
|
|
32
|
-
let ppid = +other.split("-")[1];
|
|
33
|
-
if (!doesProcessExist(pid) || !doesProcessExist(ppid)) {
|
|
34
|
-
try {
|
|
35
|
-
fs.unlinkSync(debuggerFolder + other);
|
|
36
|
-
} catch { }
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
export function getDebuggerUrl() {
|
|
41
|
-
// NOTE: Very unfortunate, as this means that if a developer is debugging a server for a bit,
|
|
42
|
-
// the inspector is left open. It's kind of hard to tell when they are done though.
|
|
43
|
-
// - This is still somewhat secure, as only localhost can connect, but... having local network
|
|
44
|
-
// accessing turning into remote execution access isn't great (especially for developers,
|
|
45
|
-
// who could then get pwned just by clicking on a link).
|
|
46
|
-
// TODO: The security of this can be improved, see NodeViewer.tsx:getExternalInspectURL
|
|
47
|
-
listenOnDebugger();
|
|
48
|
-
return devToolsUrl;
|
|
49
|
-
}
|
|
50
|
-
function doesProcessExist(pid: number) {
|
|
51
|
-
try {
|
|
52
|
-
process.kill(pid, 0);
|
|
53
|
-
return true;
|
|
54
|
-
} catch {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function baseGetInspectorUrl() {
|
|
59
|
-
function getNextPort() {
|
|
60
|
-
return 49152 + ~~((65535 - 49152) * Math.random());
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
while (true) {
|
|
64
|
-
let url = inspector.url();
|
|
65
|
-
if (url) return url;
|
|
66
|
-
try {
|
|
67
|
-
inspector.open(getNextPort());
|
|
68
|
-
} catch {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
1
|
+
import { isNode, list } from "socket-function/src/misc";
|
|
2
|
+
import inspector from "inspector";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import { getSubFolder } from "../fs";
|
|
5
|
+
import { SocketFunction } from "socket-function/SocketFunction";
|
|
6
|
+
import debugbreak from "debugbreak";
|
|
7
|
+
import http from "http";
|
|
8
|
+
import { lazy } from "socket-function/src/caching";
|
|
9
|
+
|
|
10
|
+
let devToolsUrl = "";
|
|
11
|
+
|
|
12
|
+
const listenOnDebugger = lazy(function listenOnDebugger() {
|
|
13
|
+
if (devToolsUrl) return;
|
|
14
|
+
if (!isNode()) return;
|
|
15
|
+
// IMPORTANT! NEVER use the built-in port. This adds a tiny bit of security. Not much,
|
|
16
|
+
// as port scanning is easier (there are only 65K ports!), but... at least port scanning
|
|
17
|
+
// is loud, so if a site port scans all of it's users it will probably get flagged by
|
|
18
|
+
// chrome fairly quickly as being malicious.
|
|
19
|
+
let url = baseGetInspectorUrl();
|
|
20
|
+
|
|
21
|
+
devToolsUrl = `devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&${url.replace("://", "=")}`;
|
|
22
|
+
devToolsUrl = devToolsUrl.replace("devtools://devtools/bundled", "https://notdevtools.com/devtools");
|
|
23
|
+
console.log(`Debugger listening on ${devToolsUrl}`);
|
|
24
|
+
|
|
25
|
+
const ext = ".url";
|
|
26
|
+
const debuggerFolder = getSubFolder("debugger");
|
|
27
|
+
let otherDebuggers = fs.readdirSync(debuggerFolder);
|
|
28
|
+
otherDebuggers = otherDebuggers.filter(x => x.endsWith(ext));
|
|
29
|
+
// Delete all files for processes that no longer exist
|
|
30
|
+
for (let other of otherDebuggers) {
|
|
31
|
+
let pid = +other.split("-")[0];
|
|
32
|
+
let ppid = +other.split("-")[1];
|
|
33
|
+
if (!doesProcessExist(pid) || !doesProcessExist(ppid)) {
|
|
34
|
+
try {
|
|
35
|
+
fs.unlinkSync(debuggerFolder + other);
|
|
36
|
+
} catch { }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
export function getDebuggerUrl() {
|
|
41
|
+
// NOTE: Very unfortunate, as this means that if a developer is debugging a server for a bit,
|
|
42
|
+
// the inspector is left open. It's kind of hard to tell when they are done though.
|
|
43
|
+
// - This is still somewhat secure, as only localhost can connect, but... having local network
|
|
44
|
+
// accessing turning into remote execution access isn't great (especially for developers,
|
|
45
|
+
// who could then get pwned just by clicking on a link).
|
|
46
|
+
// TODO: The security of this can be improved, see NodeViewer.tsx:getExternalInspectURL
|
|
47
|
+
listenOnDebugger();
|
|
48
|
+
return devToolsUrl;
|
|
49
|
+
}
|
|
50
|
+
function doesProcessExist(pid: number) {
|
|
51
|
+
try {
|
|
52
|
+
process.kill(pid, 0);
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function baseGetInspectorUrl() {
|
|
59
|
+
function getNextPort() {
|
|
60
|
+
return 49152 + ~~((65535 - 49152) * Math.random());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
while (true) {
|
|
64
|
+
let url = inspector.url();
|
|
65
|
+
if (url) return url;
|
|
66
|
+
try {
|
|
67
|
+
inspector.open(getNextPort());
|
|
68
|
+
} catch {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
72
|
}
|
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
import { delay, runInfinitePoll, runInfinitePollCallAtStart, shutdownPolling } from "socket-function/src/batching";
|
|
2
|
-
import { isNode, timeInMinute } from "socket-function/src/misc";
|
|
3
|
-
import { logErrors, timeoutToError } from "../errors";
|
|
4
|
-
import debugbreak from "debugbreak";
|
|
5
|
-
import { nodeDiscoveryShutdown } from "../-f-node-discovery/NodeDiscovery";
|
|
6
|
-
import { authorityStorage } from "../0-path-value-core/pathValueCore";
|
|
7
|
-
import { red } from "socket-function/src/formatting/logColors";
|
|
8
|
-
|
|
9
|
-
// Import querysub, so all the hooks we use will exist at some point
|
|
10
|
-
setImmediate(async () => {
|
|
11
|
-
await import("../4-querysub/QuerysubController");
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
let periodicFncs: (() => void)[] = [];
|
|
15
|
-
export function registerPeriodic(fnc: () => void) {
|
|
16
|
-
periodicFncs.push(fnc);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
let shutdownHandlers: (() => Promise<void>)[] = [];
|
|
20
|
-
// NOTE: Won't be always called, but at least makes it possible to gracefully shutdown.
|
|
21
|
-
export function registerShutdownHandler(fnc: () => Promise<void>) {
|
|
22
|
-
shutdownHandlers.push(fnc);
|
|
23
|
-
}
|
|
24
|
-
let preshutdownHandlers: (() => Promise<void>)[] = [];
|
|
25
|
-
export function registerPreshutdownHandler(fnc: () => Promise<void>) {
|
|
26
|
-
preshutdownHandlers.push(fnc);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function logAll() {
|
|
30
|
-
for (let fnc of periodicFncs) {
|
|
31
|
-
fnc();
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
logErrors(runInfinitePollCallAtStart(timeInMinute * 5, logAll));
|
|
36
|
-
|
|
37
|
-
let shuttingDown = false;
|
|
38
|
-
export async function shutdown() {
|
|
39
|
-
if (shuttingDown) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
console.log(red("Starting shutdown"));
|
|
43
|
-
shuttingDown = true;
|
|
44
|
-
const { authorityStorage } = await import("../0-path-value-core/pathValueCore");
|
|
45
|
-
try {
|
|
46
|
-
await Promise.allSettled([
|
|
47
|
-
...preshutdownHandlers,
|
|
48
|
-
].map(fnc => timeoutToError(timeInMinute, fnc(), () => new Error(`Preshutdown handler ${fnc.name} timed out`))));
|
|
49
|
-
} catch (e) {
|
|
50
|
-
console.log(`Error on preshutdown handlers`, e);
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
await Promise.allSettled([
|
|
54
|
-
function authorityStorageShutdown() { return authorityStorage.onShutdown(); },
|
|
55
|
-
nodeDiscoveryShutdown,
|
|
56
|
-
shutdownPolling,
|
|
57
|
-
...shutdownHandlers,
|
|
58
|
-
].map(fnc => timeoutToError(timeInMinute, fnc(), () => new Error(`Shutdown handler ${fnc.name} timed out`))));
|
|
59
|
-
} catch (e) {
|
|
60
|
-
console.log("Error on shutdown", e);
|
|
61
|
-
}
|
|
62
|
-
// Wait to allow any logged errors to hopefully be written somewhere?
|
|
63
|
-
await delay(2000);
|
|
64
|
-
process.exit();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// IMPORTANT! Yarn detaches the processes, so they keep running when you ctrl+c, even though the shell shows back up. We can fix this by using `node -r ./node_modules/typenode/index.js ./test.ts`. However, it's probably fine, as we still run the shutdown code, it's just that the manager doesn't know if we've shutdown or not.
|
|
68
|
-
if (isNode()) {
|
|
69
|
-
let lineBuffer = "";
|
|
70
|
-
process.stdin.on("data", data => {
|
|
71
|
-
lineBuffer += data.toString();
|
|
72
|
-
let lines = lineBuffer.split("\r");
|
|
73
|
-
lineBuffer = lines.pop()!;
|
|
74
|
-
for (let line of lines) {
|
|
75
|
-
if (line === "SHUTDOWN_NOW_MULTIRUN") {
|
|
76
|
-
logErrors(shutdown());
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (data.toString().includes("\r")) {
|
|
81
|
-
logAll();
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// NOTE: This extra code is required to actual capture ctrl+c
|
|
87
|
-
if (process.platform === "win32") {
|
|
88
|
-
var rl = require("readline").createInterface({
|
|
89
|
-
input: process.stdin,
|
|
90
|
-
output: process.stdout
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
rl.on("SIGINT", function () {
|
|
94
|
-
process.emit("SIGINT");
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
let killCount = 0;
|
|
98
|
-
function doShutdown() {
|
|
99
|
-
killCount++;
|
|
100
|
-
console.log(`Caught interrupt signal. Attempt number ${killCount}`);
|
|
101
|
-
if (killCount >= 3) {
|
|
102
|
-
console.log("Force exit");
|
|
103
|
-
process.exit();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
logErrors(shutdown());
|
|
107
|
-
}
|
|
108
|
-
process.on("SIGINT", doShutdown);
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
(globalThis as any).logAll = logAll;
|
|
1
|
+
import { delay, runInfinitePoll, runInfinitePollCallAtStart, shutdownPolling } from "socket-function/src/batching";
|
|
2
|
+
import { isNode, timeInMinute } from "socket-function/src/misc";
|
|
3
|
+
import { logErrors, timeoutToError } from "../errors";
|
|
4
|
+
import debugbreak from "debugbreak";
|
|
5
|
+
import { nodeDiscoveryShutdown } from "../-f-node-discovery/NodeDiscovery";
|
|
6
|
+
import { authorityStorage } from "../0-path-value-core/pathValueCore";
|
|
7
|
+
import { red } from "socket-function/src/formatting/logColors";
|
|
8
|
+
|
|
9
|
+
// Import querysub, so all the hooks we use will exist at some point
|
|
10
|
+
setImmediate(async () => {
|
|
11
|
+
await import("../4-querysub/QuerysubController");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
let periodicFncs: (() => void)[] = [];
|
|
15
|
+
export function registerPeriodic(fnc: () => void) {
|
|
16
|
+
periodicFncs.push(fnc);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let shutdownHandlers: (() => Promise<void>)[] = [];
|
|
20
|
+
// NOTE: Won't be always called, but at least makes it possible to gracefully shutdown.
|
|
21
|
+
export function registerShutdownHandler(fnc: () => Promise<void>) {
|
|
22
|
+
shutdownHandlers.push(fnc);
|
|
23
|
+
}
|
|
24
|
+
let preshutdownHandlers: (() => Promise<void>)[] = [];
|
|
25
|
+
export function registerPreshutdownHandler(fnc: () => Promise<void>) {
|
|
26
|
+
preshutdownHandlers.push(fnc);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function logAll() {
|
|
30
|
+
for (let fnc of periodicFncs) {
|
|
31
|
+
fnc();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
logErrors(runInfinitePollCallAtStart(timeInMinute * 5, logAll));
|
|
36
|
+
|
|
37
|
+
let shuttingDown = false;
|
|
38
|
+
export async function shutdown() {
|
|
39
|
+
if (shuttingDown) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log(red("Starting shutdown"));
|
|
43
|
+
shuttingDown = true;
|
|
44
|
+
const { authorityStorage } = await import("../0-path-value-core/pathValueCore");
|
|
45
|
+
try {
|
|
46
|
+
await Promise.allSettled([
|
|
47
|
+
...preshutdownHandlers,
|
|
48
|
+
].map(fnc => timeoutToError(timeInMinute, fnc(), () => new Error(`Preshutdown handler ${fnc.name} timed out`))));
|
|
49
|
+
} catch (e) {
|
|
50
|
+
console.log(`Error on preshutdown handlers`, e);
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
await Promise.allSettled([
|
|
54
|
+
function authorityStorageShutdown() { return authorityStorage.onShutdown(); },
|
|
55
|
+
nodeDiscoveryShutdown,
|
|
56
|
+
shutdownPolling,
|
|
57
|
+
...shutdownHandlers,
|
|
58
|
+
].map(fnc => timeoutToError(timeInMinute, fnc(), () => new Error(`Shutdown handler ${fnc.name} timed out`))));
|
|
59
|
+
} catch (e) {
|
|
60
|
+
console.log("Error on shutdown", e);
|
|
61
|
+
}
|
|
62
|
+
// Wait to allow any logged errors to hopefully be written somewhere?
|
|
63
|
+
await delay(2000);
|
|
64
|
+
process.exit();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// IMPORTANT! Yarn detaches the processes, so they keep running when you ctrl+c, even though the shell shows back up. We can fix this by using `node -r ./node_modules/typenode/index.js ./test.ts`. However, it's probably fine, as we still run the shutdown code, it's just that the manager doesn't know if we've shutdown or not.
|
|
68
|
+
if (isNode()) {
|
|
69
|
+
let lineBuffer = "";
|
|
70
|
+
process.stdin.on("data", data => {
|
|
71
|
+
lineBuffer += data.toString();
|
|
72
|
+
let lines = lineBuffer.split("\r");
|
|
73
|
+
lineBuffer = lines.pop()!;
|
|
74
|
+
for (let line of lines) {
|
|
75
|
+
if (line === "SHUTDOWN_NOW_MULTIRUN") {
|
|
76
|
+
logErrors(shutdown());
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (data.toString().includes("\r")) {
|
|
81
|
+
logAll();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
// NOTE: This extra code is required to actual capture ctrl+c
|
|
87
|
+
if (process.platform === "win32") {
|
|
88
|
+
var rl = require("readline").createInterface({
|
|
89
|
+
input: process.stdin,
|
|
90
|
+
output: process.stdout
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
rl.on("SIGINT", function () {
|
|
94
|
+
process.emit("SIGINT");
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
let killCount = 0;
|
|
98
|
+
function doShutdown() {
|
|
99
|
+
killCount++;
|
|
100
|
+
console.log(`Caught interrupt signal. Attempt number ${killCount}`);
|
|
101
|
+
if (killCount >= 3) {
|
|
102
|
+
console.log("Force exit");
|
|
103
|
+
process.exit();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
logErrors(shutdown());
|
|
107
|
+
}
|
|
108
|
+
process.on("SIGINT", doShutdown);
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
(globalThis as any).logAll = logAll;
|
|
112
112
|
(globalThis as any).logNow = logAll;
|
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
import { runInfinitePoll } from "socket-function/src/batching";
|
|
2
|
-
import { lazy } from "socket-function/src/caching";
|
|
3
|
-
import { formatNumber } from "socket-function/src/formatting/format";
|
|
4
|
-
import { blue } from "socket-function/src/formatting/logColors";
|
|
5
|
-
import { isNode } from "socket-function/src/misc";
|
|
6
|
-
import { registerPeriodic } from "./periodic";
|
|
7
|
-
import { registerMeasureInfo } from "socket-function/src/profiling/measure";
|
|
8
|
-
import { logNodeStateStats } from "../-0-hooks/hooks";
|
|
9
|
-
|
|
10
|
-
let resources: {
|
|
11
|
-
name: string;
|
|
12
|
-
getCount: () => number;
|
|
13
|
-
}[] = [];
|
|
14
|
-
|
|
15
|
-
export function registerResource<T extends Set<unknown> | Map<unknown, unknown> | unknown[]>(name: string, data: T): T {
|
|
16
|
-
let getCount: () => number;
|
|
17
|
-
if (Array.isArray(data)) {
|
|
18
|
-
getCount = () => data.length;
|
|
19
|
-
} else {
|
|
20
|
-
getCount = () => data.size;
|
|
21
|
-
}
|
|
22
|
-
resources.push({ name, getCount });
|
|
23
|
-
return data;
|
|
24
|
-
}
|
|
25
|
-
export function registerMapArrayResource<T extends Map<unknown, unknown[]>>(name: string, data: T): T {
|
|
26
|
-
let getCount = () => {
|
|
27
|
-
let sum = 0;
|
|
28
|
-
for (let value of data.values()) {
|
|
29
|
-
sum += value.length;
|
|
30
|
-
}
|
|
31
|
-
return sum;
|
|
32
|
-
};
|
|
33
|
-
resources.push({ name, getCount });
|
|
34
|
-
return data;
|
|
35
|
-
}
|
|
36
|
-
export function registerDynamicResource(name: string, getCount: () => number) {
|
|
37
|
-
resources.push({ name, getCount });
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getHeapSize() {
|
|
41
|
-
if (isNode()) {
|
|
42
|
-
let usage = process.memoryUsage();
|
|
43
|
-
// Not really the heap size, but it is more what we are looking for
|
|
44
|
-
return usage.rss;
|
|
45
|
-
} else {
|
|
46
|
-
return (window.performance as any).memory.totalJSHeapSize;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function getUsedHeapSize() {
|
|
50
|
-
if (isNode()) {
|
|
51
|
-
let usage = process.memoryUsage();
|
|
52
|
-
return usage.heapUsed + usage.arrayBuffers;
|
|
53
|
-
} else {
|
|
54
|
-
if (!window.performance) return 0;
|
|
55
|
-
return (window.performance as any).memory.usedJSHeapSize;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
function getBufferUsage() {
|
|
59
|
-
if (isNode()) {
|
|
60
|
-
let usage = process.memoryUsage();
|
|
61
|
-
return usage.arrayBuffers;
|
|
62
|
-
} else {
|
|
63
|
-
return 0;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
registerDynamicResource("Heap", getUsedHeapSize);
|
|
68
|
-
registerDynamicResource("Buffers", getBufferUsage);
|
|
69
|
-
registerDynamicResource("Used Memory", getHeapSize);
|
|
70
|
-
|
|
71
|
-
function logResourcesNow() {
|
|
72
|
-
let resourcesWithCounts = resources.map(resource => ({ ...resource, count: resource.getCount() }));
|
|
73
|
-
resourcesWithCounts.sort((a, b) => b.count - a.count);
|
|
74
|
-
if (!isNode()) {
|
|
75
|
-
console.log(`Memory usage ${blue(formatNumber(getUsedHeapSize()) + "B")}/${blue(formatNumber(getHeapSize()) + "B")} at ${new Date().toISOString()}`);
|
|
76
|
-
for (let resource of resourcesWithCounts) {
|
|
77
|
-
if (resource.count === 0) continue;
|
|
78
|
-
console.log(` ${resource.name}: ${formatNumber(resource.count)}`);
|
|
79
|
-
}
|
|
80
|
-
} else {
|
|
81
|
-
for (let resource of resourcesWithCounts) {
|
|
82
|
-
if (resource.count === 0) continue;
|
|
83
|
-
logNodeStateStats(resource.name, formatNumber, resource.count);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
registerMeasureInfo(() => {
|
|
89
|
-
return `MEM ${formatNumber(getUsedHeapSize())}B+${formatNumber(getBufferUsage())}B/${formatNumber(getHeapSize())}B `;
|
|
90
|
-
});
|
|
91
|
-
|
|
1
|
+
import { runInfinitePoll } from "socket-function/src/batching";
|
|
2
|
+
import { lazy } from "socket-function/src/caching";
|
|
3
|
+
import { formatNumber } from "socket-function/src/formatting/format";
|
|
4
|
+
import { blue } from "socket-function/src/formatting/logColors";
|
|
5
|
+
import { isNode } from "socket-function/src/misc";
|
|
6
|
+
import { registerPeriodic } from "./periodic";
|
|
7
|
+
import { registerMeasureInfo } from "socket-function/src/profiling/measure";
|
|
8
|
+
import { logNodeStateStats } from "../-0-hooks/hooks";
|
|
9
|
+
|
|
10
|
+
let resources: {
|
|
11
|
+
name: string;
|
|
12
|
+
getCount: () => number;
|
|
13
|
+
}[] = [];
|
|
14
|
+
|
|
15
|
+
export function registerResource<T extends Set<unknown> | Map<unknown, unknown> | unknown[]>(name: string, data: T): T {
|
|
16
|
+
let getCount: () => number;
|
|
17
|
+
if (Array.isArray(data)) {
|
|
18
|
+
getCount = () => data.length;
|
|
19
|
+
} else {
|
|
20
|
+
getCount = () => data.size;
|
|
21
|
+
}
|
|
22
|
+
resources.push({ name, getCount });
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
export function registerMapArrayResource<T extends Map<unknown, unknown[]>>(name: string, data: T): T {
|
|
26
|
+
let getCount = () => {
|
|
27
|
+
let sum = 0;
|
|
28
|
+
for (let value of data.values()) {
|
|
29
|
+
sum += value.length;
|
|
30
|
+
}
|
|
31
|
+
return sum;
|
|
32
|
+
};
|
|
33
|
+
resources.push({ name, getCount });
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
export function registerDynamicResource(name: string, getCount: () => number) {
|
|
37
|
+
resources.push({ name, getCount });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function getHeapSize() {
|
|
41
|
+
if (isNode()) {
|
|
42
|
+
let usage = process.memoryUsage();
|
|
43
|
+
// Not really the heap size, but it is more what we are looking for
|
|
44
|
+
return usage.rss;
|
|
45
|
+
} else {
|
|
46
|
+
return (window.performance as any).memory.totalJSHeapSize;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function getUsedHeapSize() {
|
|
50
|
+
if (isNode()) {
|
|
51
|
+
let usage = process.memoryUsage();
|
|
52
|
+
return usage.heapUsed + usage.arrayBuffers;
|
|
53
|
+
} else {
|
|
54
|
+
if (!window.performance) return 0;
|
|
55
|
+
return (window.performance as any).memory.usedJSHeapSize;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function getBufferUsage() {
|
|
59
|
+
if (isNode()) {
|
|
60
|
+
let usage = process.memoryUsage();
|
|
61
|
+
return usage.arrayBuffers;
|
|
62
|
+
} else {
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
registerDynamicResource("Heap", getUsedHeapSize);
|
|
68
|
+
registerDynamicResource("Buffers", getBufferUsage);
|
|
69
|
+
registerDynamicResource("Used Memory", getHeapSize);
|
|
70
|
+
|
|
71
|
+
function logResourcesNow() {
|
|
72
|
+
let resourcesWithCounts = resources.map(resource => ({ ...resource, count: resource.getCount() }));
|
|
73
|
+
resourcesWithCounts.sort((a, b) => b.count - a.count);
|
|
74
|
+
if (!isNode()) {
|
|
75
|
+
console.log(`Memory usage ${blue(formatNumber(getUsedHeapSize()) + "B")}/${blue(formatNumber(getHeapSize()) + "B")} at ${new Date().toISOString()}`);
|
|
76
|
+
for (let resource of resourcesWithCounts) {
|
|
77
|
+
if (resource.count === 0) continue;
|
|
78
|
+
console.log(` ${resource.name}: ${formatNumber(resource.count)}`);
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
for (let resource of resourcesWithCounts) {
|
|
82
|
+
if (resource.count === 0) continue;
|
|
83
|
+
logNodeStateStats(resource.name, formatNumber, resource.count);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
registerMeasureInfo(() => {
|
|
89
|
+
return `MEM ${formatNumber(getUsedHeapSize())}B+${formatNumber(getBufferUsage())}B/${formatNumber(getHeapSize())}B `;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
92
|
registerPeriodic(logResourcesNow);
|