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,121 +1,121 @@
|
|
|
1
|
-
import { runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
2
|
-
import { FormattedMeasureTable, MeasureProfile, logMeasureTable, startMeasure } from "socket-function/src/profiling/measure";
|
|
3
|
-
import { logErrors } from "../errors";
|
|
4
|
-
import { isNode, sort } from "socket-function/src/misc";
|
|
5
|
-
import debugbreak from "debugbreak";
|
|
6
|
-
import { registerPeriodic } from "./periodic";
|
|
7
|
-
import { getOwnMachineId } from "../-a-auth/certs";
|
|
8
|
-
import { SocketFunction } from "socket-function/SocketFunction";
|
|
9
|
-
import { formatPercent, formatTime } from "socket-function/src/formatting/format";
|
|
10
|
-
import { pathWatcher } from "../0-path-value-core/PathWatcher";
|
|
11
|
-
import { addStatPeriodic, addStatSumPeriodic, addTimeProfileDistribution, registerNodeMetadata } from "../-0-hooks/hooks";
|
|
12
|
-
import { logDisk } from "./logs/diskLogger";
|
|
13
|
-
import { getDebuggerUrl } from "./listenOnDebugger";
|
|
14
|
-
import { isPublic } from "../config";
|
|
15
|
-
|
|
16
|
-
let lastProfile: MeasureProfile | undefined;
|
|
17
|
-
|
|
18
|
-
addStatPeriodic({
|
|
19
|
-
title: "Performance|% Profiled",
|
|
20
|
-
getValue: () => {
|
|
21
|
-
if (!lastProfile) return 0;
|
|
22
|
-
let entries = Object.values(lastProfile.entries);
|
|
23
|
-
if (entries.length === 0) return 0;
|
|
24
|
-
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
25
|
-
|
|
26
|
-
let timeActive = entries.map(x => x.ownTime.sum).reduce((a, b) => a + b, 0);
|
|
27
|
-
return timeActive / timeProfiled;
|
|
28
|
-
},
|
|
29
|
-
format: formatPercent,
|
|
30
|
-
});
|
|
31
|
-
registerNodeMetadata({
|
|
32
|
-
columnName: "Performance|Top Profiled",
|
|
33
|
-
getValue() {
|
|
34
|
-
if (!lastProfile) return "";
|
|
35
|
-
let entries = Object.values(lastProfile.entries);
|
|
36
|
-
if (entries.length === 0) return "";
|
|
37
|
-
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
38
|
-
|
|
39
|
-
let rootSums = new Map<string, number>();
|
|
40
|
-
for (let entry of entries) {
|
|
41
|
-
let name = entry.name.split("|")[0];
|
|
42
|
-
let sum = rootSums.get(name) ?? 0;
|
|
43
|
-
rootSums.set(name, sum + entry.ownTime.sum);
|
|
44
|
-
}
|
|
45
|
-
let most = sort(Array.from(rootSums.entries()), x => -x[1])[0];
|
|
46
|
-
return `${endEllipsis(most[0], 26)} = ${formatPercent(most[1] / timeProfiled)}`;
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
addTimeProfileDistribution("Performance|Network Calls", () => SocketFunction.harvestCallTimes());
|
|
50
|
-
addStatPeriodic({
|
|
51
|
-
title: "Performance|Pending Net Calls",
|
|
52
|
-
getValue: () => SocketFunction.getPendingCallCount(),
|
|
53
|
-
});
|
|
54
|
-
addStatSumPeriodic({
|
|
55
|
-
title: "Performance|Failed Net Calls",
|
|
56
|
-
getValue: () => SocketFunction.harvestFailedCallCount(),
|
|
57
|
-
});
|
|
58
|
-
addTimeProfileDistribution("Performance|Syncing", () => pathWatcher.debug_harvestSyncTimes());
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
function endEllipsis(str: string, maxLength: number) {
|
|
62
|
-
if (str.length <= maxLength) return str;
|
|
63
|
-
return "..." + str.slice(-(maxLength - 3));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let minTimeToLog = 250;
|
|
67
|
-
export function watchdogSetMinTimeToLog(_minTimeToLog: number) {
|
|
68
|
-
minTimeToLog = _minTimeToLog;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
let measureObj = startMeasure();
|
|
72
|
-
function logProfileMeasuresTimingsNow() {
|
|
73
|
-
let profile = measureObj.finish();
|
|
74
|
-
measureObj = startMeasure();
|
|
75
|
-
function diskLogMeasureObj(table: FormattedMeasureTable | undefined) {
|
|
76
|
-
if (!table) return;
|
|
77
|
-
console.info(table.title, { entries: table.entries });
|
|
78
|
-
}
|
|
79
|
-
diskLogMeasureObj(logMeasureTable(profile, {
|
|
80
|
-
name: `watchdog at ${new Date().toLocaleString()}`,
|
|
81
|
-
// NOTE: Much higher min log times, now that we are combining logs.
|
|
82
|
-
minTimeToLog: minTimeToLog,
|
|
83
|
-
thresholdInTable: 0,
|
|
84
|
-
setTitle: true
|
|
85
|
-
}));
|
|
86
|
-
diskLogMeasureObj(logMeasureTable(profile, {
|
|
87
|
-
name: `watchdog at ${new Date().toLocaleString()}`,
|
|
88
|
-
mergeDepth: 1,
|
|
89
|
-
minTimeToLog: minTimeToLog,
|
|
90
|
-
}));
|
|
91
|
-
|
|
92
|
-
if (isNode() && !isPublic()) {
|
|
93
|
-
let debuggerValue = getDebuggerUrl();
|
|
94
|
-
process.stdout.write(`\n${debuggerValue}\n`);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
lastProfile = profile;
|
|
98
|
-
// if (isNode()) {
|
|
99
|
-
// if (SocketFunction.mountedNodeId) {
|
|
100
|
-
// console.log("Mounted as " + SocketFunction.mountedNodeId);
|
|
101
|
-
// } else {
|
|
102
|
-
// console.log("Not mounted");
|
|
103
|
-
// }
|
|
104
|
-
// }
|
|
105
|
-
}
|
|
106
|
-
(globalThis as any).logProfileMeasuresNow = logProfileMeasuresTimingsNow;
|
|
107
|
-
|
|
108
|
-
(globalThis as any).logUnfiltered = function logUnfiltered(depth = 2) {
|
|
109
|
-
let profile = measureObj.finish();
|
|
110
|
-
measureObj = startMeasure();
|
|
111
|
-
logMeasureTable(profile, {
|
|
112
|
-
name: `all logs at ${new Date().toLocaleString()}`,
|
|
113
|
-
mergeDepth: depth,
|
|
114
|
-
minTimeToLog: 0,
|
|
115
|
-
maxTableEntries: 10000000,
|
|
116
|
-
thresholdInTable: 0
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
|
|
1
|
+
import { runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
2
|
+
import { FormattedMeasureTable, MeasureProfile, logMeasureTable, startMeasure } from "socket-function/src/profiling/measure";
|
|
3
|
+
import { logErrors } from "../errors";
|
|
4
|
+
import { isNode, sort } from "socket-function/src/misc";
|
|
5
|
+
import debugbreak from "debugbreak";
|
|
6
|
+
import { registerPeriodic } from "./periodic";
|
|
7
|
+
import { getOwnMachineId } from "../-a-auth/certs";
|
|
8
|
+
import { SocketFunction } from "socket-function/SocketFunction";
|
|
9
|
+
import { formatPercent, formatTime } from "socket-function/src/formatting/format";
|
|
10
|
+
import { pathWatcher } from "../0-path-value-core/PathWatcher";
|
|
11
|
+
import { addStatPeriodic, addStatSumPeriodic, addTimeProfileDistribution, registerNodeMetadata } from "../-0-hooks/hooks";
|
|
12
|
+
import { logDisk } from "./logs/diskLogger";
|
|
13
|
+
import { getDebuggerUrl } from "./listenOnDebugger";
|
|
14
|
+
import { isPublic } from "../config";
|
|
15
|
+
|
|
16
|
+
let lastProfile: MeasureProfile | undefined;
|
|
17
|
+
|
|
18
|
+
addStatPeriodic({
|
|
19
|
+
title: "Performance|% Profiled",
|
|
20
|
+
getValue: () => {
|
|
21
|
+
if (!lastProfile) return 0;
|
|
22
|
+
let entries = Object.values(lastProfile.entries);
|
|
23
|
+
if (entries.length === 0) return 0;
|
|
24
|
+
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
25
|
+
|
|
26
|
+
let timeActive = entries.map(x => x.ownTime.sum).reduce((a, b) => a + b, 0);
|
|
27
|
+
return timeActive / timeProfiled;
|
|
28
|
+
},
|
|
29
|
+
format: formatPercent,
|
|
30
|
+
});
|
|
31
|
+
registerNodeMetadata({
|
|
32
|
+
columnName: "Performance|Top Profiled",
|
|
33
|
+
getValue() {
|
|
34
|
+
if (!lastProfile) return "";
|
|
35
|
+
let entries = Object.values(lastProfile.entries);
|
|
36
|
+
if (entries.length === 0) return "";
|
|
37
|
+
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
38
|
+
|
|
39
|
+
let rootSums = new Map<string, number>();
|
|
40
|
+
for (let entry of entries) {
|
|
41
|
+
let name = entry.name.split("|")[0];
|
|
42
|
+
let sum = rootSums.get(name) ?? 0;
|
|
43
|
+
rootSums.set(name, sum + entry.ownTime.sum);
|
|
44
|
+
}
|
|
45
|
+
let most = sort(Array.from(rootSums.entries()), x => -x[1])[0];
|
|
46
|
+
return `${endEllipsis(most[0], 26)} = ${formatPercent(most[1] / timeProfiled)}`;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
addTimeProfileDistribution("Performance|Network Calls", () => SocketFunction.harvestCallTimes());
|
|
50
|
+
addStatPeriodic({
|
|
51
|
+
title: "Performance|Pending Net Calls",
|
|
52
|
+
getValue: () => SocketFunction.getPendingCallCount(),
|
|
53
|
+
});
|
|
54
|
+
addStatSumPeriodic({
|
|
55
|
+
title: "Performance|Failed Net Calls",
|
|
56
|
+
getValue: () => SocketFunction.harvestFailedCallCount(),
|
|
57
|
+
});
|
|
58
|
+
addTimeProfileDistribution("Performance|Syncing", () => pathWatcher.debug_harvestSyncTimes());
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
function endEllipsis(str: string, maxLength: number) {
|
|
62
|
+
if (str.length <= maxLength) return str;
|
|
63
|
+
return "..." + str.slice(-(maxLength - 3));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let minTimeToLog = 250;
|
|
67
|
+
export function watchdogSetMinTimeToLog(_minTimeToLog: number) {
|
|
68
|
+
minTimeToLog = _minTimeToLog;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let measureObj = startMeasure();
|
|
72
|
+
function logProfileMeasuresTimingsNow() {
|
|
73
|
+
let profile = measureObj.finish();
|
|
74
|
+
measureObj = startMeasure();
|
|
75
|
+
function diskLogMeasureObj(table: FormattedMeasureTable | undefined) {
|
|
76
|
+
if (!table) return;
|
|
77
|
+
console.info(table.title, { entries: table.entries });
|
|
78
|
+
}
|
|
79
|
+
diskLogMeasureObj(logMeasureTable(profile, {
|
|
80
|
+
name: `watchdog at ${new Date().toLocaleString()}`,
|
|
81
|
+
// NOTE: Much higher min log times, now that we are combining logs.
|
|
82
|
+
minTimeToLog: minTimeToLog,
|
|
83
|
+
thresholdInTable: 0,
|
|
84
|
+
setTitle: true
|
|
85
|
+
}));
|
|
86
|
+
diskLogMeasureObj(logMeasureTable(profile, {
|
|
87
|
+
name: `watchdog at ${new Date().toLocaleString()}`,
|
|
88
|
+
mergeDepth: 1,
|
|
89
|
+
minTimeToLog: minTimeToLog,
|
|
90
|
+
}));
|
|
91
|
+
|
|
92
|
+
if (isNode() && !isPublic()) {
|
|
93
|
+
let debuggerValue = getDebuggerUrl();
|
|
94
|
+
process.stdout.write(`\n${debuggerValue}\n`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
lastProfile = profile;
|
|
98
|
+
// if (isNode()) {
|
|
99
|
+
// if (SocketFunction.mountedNodeId) {
|
|
100
|
+
// console.log("Mounted as " + SocketFunction.mountedNodeId);
|
|
101
|
+
// } else {
|
|
102
|
+
// console.log("Not mounted");
|
|
103
|
+
// }
|
|
104
|
+
// }
|
|
105
|
+
}
|
|
106
|
+
(globalThis as any).logProfileMeasuresNow = logProfileMeasuresTimingsNow;
|
|
107
|
+
|
|
108
|
+
(globalThis as any).logUnfiltered = function logUnfiltered(depth = 2) {
|
|
109
|
+
let profile = measureObj.finish();
|
|
110
|
+
measureObj = startMeasure();
|
|
111
|
+
logMeasureTable(profile, {
|
|
112
|
+
name: `all logs at ${new Date().toLocaleString()}`,
|
|
113
|
+
mergeDepth: depth,
|
|
114
|
+
minTimeToLog: 0,
|
|
115
|
+
maxTableEntries: 10000000,
|
|
116
|
+
thresholdInTable: 0
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
|
|
121
121
|
registerPeriodic(logProfileMeasuresTimingsNow);
|
package/src/errors.ts
CHANGED
|
@@ -1,134 +1,134 @@
|
|
|
1
|
-
import debugbreak from "debugbreak";
|
|
2
|
-
import { delay } from "socket-function/src/batching";
|
|
3
|
-
import { blue, red } from "socket-function/src/formatting/logColors";
|
|
4
|
-
import { canHaveChildren } from "socket-function/src/types";
|
|
5
|
-
|
|
6
|
-
let callstackTracking = false;
|
|
7
|
-
/** WARNING: This can be VERY slow. The only way to record the callstack of some errors is to record it
|
|
8
|
-
* on promise initialization, which results in gathering callstacks even for successful promises.
|
|
9
|
-
*/
|
|
10
|
-
export function enableCallbackTracking() {
|
|
11
|
-
callstackTracking = true;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function logError(e: Error, callstack: unknown) {
|
|
15
|
-
console.error(`${blue("Error from promise")}: ${red(e.stack || e.message)}`);
|
|
16
|
-
if (callstackTracking) {
|
|
17
|
-
console.log(callstack);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
export function logErrors(promiseorError: Promise<unknown> | unknown | undefined) {
|
|
21
|
-
let callstack = callstackTracking && new Error().stack;
|
|
22
|
-
if (!promiseorError) return;
|
|
23
|
-
if (!canHaveChildren(promiseorError)) return;
|
|
24
|
-
if (promiseorError instanceof Promise) {
|
|
25
|
-
promiseorError.catch(e => {
|
|
26
|
-
logError(e, callstack);
|
|
27
|
-
});
|
|
28
|
-
} else {
|
|
29
|
-
if (promiseorError instanceof Error) {
|
|
30
|
-
logError(promiseorError, callstack);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export function ignoreErrors(promise: Promise<unknown>) {
|
|
35
|
-
if (!promise) return;
|
|
36
|
-
if (!promise?.catch) return;
|
|
37
|
-
promise.catch(e => { });
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/** Logs the error as well. */
|
|
41
|
-
export function errorToUndefined<T>(p: Promise<T>): Promise<T | undefined> {
|
|
42
|
-
if (!p?.catch) return p;
|
|
43
|
-
return p.catch((e) => {
|
|
44
|
-
console.error(`${blue("Error to undefined error")}: ${red(e.stack)}`);
|
|
45
|
-
return undefined;
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
export function errorToUndefinedSilent<T>(p: Promise<T>): Promise<T | undefined> {
|
|
49
|
-
if (!p?.catch) return Promise.resolve(undefined);
|
|
50
|
-
return p.catch((e) => {
|
|
51
|
-
return undefined;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export function timeoutToError<T>(time: number, p: Promise<T>, err: () => Error) {
|
|
56
|
-
return new Promise<T>((resolve, reject) => {
|
|
57
|
-
let timeout = setTimeout(() => reject(err()), time);
|
|
58
|
-
p.then(resolve, reject).finally(() => clearTimeout(timeout));
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// NOTE: Both errors and timeouts are converted to undefined
|
|
63
|
-
export function timeoutToUndefined<T>(time: number, p: Promise<T>) {
|
|
64
|
-
return new Promise<T | undefined>((resolve, reject) => {
|
|
65
|
-
let timeout = setTimeout(() => {
|
|
66
|
-
console.error(blue(`timeoutToUndefined timed out after ${time}`));
|
|
67
|
-
resolve(undefined);
|
|
68
|
-
}, time);
|
|
69
|
-
p.then(resolve,
|
|
70
|
-
(err) => {
|
|
71
|
-
console.error(`${blue("timeoutToUndefined error")}: ${red(err.stack)}`);
|
|
72
|
-
resolve(undefined);
|
|
73
|
-
}
|
|
74
|
-
).finally(() => clearTimeout(timeout));
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
export function timeoutToUndefinedSilent<T>(time: number, p: Promise<T>) {
|
|
78
|
-
return new Promise<T | undefined>((resolve, reject) => {
|
|
79
|
-
let timeout = setTimeout(() => {
|
|
80
|
-
resolve(undefined);
|
|
81
|
-
}, time);
|
|
82
|
-
p.then(
|
|
83
|
-
resolve,
|
|
84
|
-
(err) => {
|
|
85
|
-
resolve(undefined);
|
|
86
|
-
}
|
|
87
|
-
).finally(() => clearTimeout(timeout));
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Used when accessing paid resources, so we don't rack up charges due to an error,
|
|
92
|
-
* but also so that it doesn't take forever for the initial call to run.
|
|
93
|
-
*/
|
|
94
|
-
export async function backoffRetryLoop<T>(code: () => Promise<T>, waitTime = 5 * 1000) {
|
|
95
|
-
while (true) {
|
|
96
|
-
try {
|
|
97
|
-
return await code();
|
|
98
|
-
} catch (e: any) {
|
|
99
|
-
console.error(`Error retrying in ${waitTime}ms\n${e.stack}`);
|
|
100
|
-
await delay(waitTime);
|
|
101
|
-
waitTime *= 1.01;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export function errorify(error: any, messageOverride?: string) {
|
|
107
|
-
if (error instanceof Error) {
|
|
108
|
-
return error;
|
|
109
|
-
}
|
|
110
|
-
let errorObj = new Error();
|
|
111
|
-
if (typeof error === "string" && error.includes("\n")) {
|
|
112
|
-
errorObj.stack = error;
|
|
113
|
-
errorObj.message = error.split("\n")[0];
|
|
114
|
-
} else {
|
|
115
|
-
errorObj.message = error;
|
|
116
|
-
errorObj.stack = error + "\n" + errorObj.stack;
|
|
117
|
-
}
|
|
118
|
-
if (messageOverride) {
|
|
119
|
-
errorObj.message = messageOverride;
|
|
120
|
-
}
|
|
121
|
-
return errorObj;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function assertValue<T>(value: T | undefined | null, message?: string): T {
|
|
125
|
-
if (value === undefined || value === null) {
|
|
126
|
-
throw new Error(`Value is ${value === undefined ? "undefined" : "null"}, ${message}`);
|
|
127
|
-
}
|
|
128
|
-
return value;
|
|
129
|
-
}
|
|
130
|
-
export function assert<T>(value: T | undefined | null, message?: string): asserts value is T {
|
|
131
|
-
if (value === undefined || value === null) {
|
|
132
|
-
throw new Error(`Value is ${value === undefined ? "undefined" : "null"}, ${message}`);
|
|
133
|
-
}
|
|
1
|
+
import debugbreak from "debugbreak";
|
|
2
|
+
import { delay } from "socket-function/src/batching";
|
|
3
|
+
import { blue, red } from "socket-function/src/formatting/logColors";
|
|
4
|
+
import { canHaveChildren } from "socket-function/src/types";
|
|
5
|
+
|
|
6
|
+
let callstackTracking = false;
|
|
7
|
+
/** WARNING: This can be VERY slow. The only way to record the callstack of some errors is to record it
|
|
8
|
+
* on promise initialization, which results in gathering callstacks even for successful promises.
|
|
9
|
+
*/
|
|
10
|
+
export function enableCallbackTracking() {
|
|
11
|
+
callstackTracking = true;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function logError(e: Error, callstack: unknown) {
|
|
15
|
+
console.error(`${blue("Error from promise")}: ${red(e.stack || e.message)}`);
|
|
16
|
+
if (callstackTracking) {
|
|
17
|
+
console.log(callstack);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export function logErrors(promiseorError: Promise<unknown> | unknown | undefined) {
|
|
21
|
+
let callstack = callstackTracking && new Error().stack;
|
|
22
|
+
if (!promiseorError) return;
|
|
23
|
+
if (!canHaveChildren(promiseorError)) return;
|
|
24
|
+
if (promiseorError instanceof Promise) {
|
|
25
|
+
promiseorError.catch(e => {
|
|
26
|
+
logError(e, callstack);
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
if (promiseorError instanceof Error) {
|
|
30
|
+
logError(promiseorError, callstack);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function ignoreErrors(promise: Promise<unknown>) {
|
|
35
|
+
if (!promise) return;
|
|
36
|
+
if (!promise?.catch) return;
|
|
37
|
+
promise.catch(e => { });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Logs the error as well. */
|
|
41
|
+
export function errorToUndefined<T>(p: Promise<T>): Promise<T | undefined> {
|
|
42
|
+
if (!p?.catch) return p;
|
|
43
|
+
return p.catch((e) => {
|
|
44
|
+
console.error(`${blue("Error to undefined error")}: ${red(e.stack)}`);
|
|
45
|
+
return undefined;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export function errorToUndefinedSilent<T>(p: Promise<T>): Promise<T | undefined> {
|
|
49
|
+
if (!p?.catch) return Promise.resolve(undefined);
|
|
50
|
+
return p.catch((e) => {
|
|
51
|
+
return undefined;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function timeoutToError<T>(time: number, p: Promise<T>, err: () => Error) {
|
|
56
|
+
return new Promise<T>((resolve, reject) => {
|
|
57
|
+
let timeout = setTimeout(() => reject(err()), time);
|
|
58
|
+
p.then(resolve, reject).finally(() => clearTimeout(timeout));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// NOTE: Both errors and timeouts are converted to undefined
|
|
63
|
+
export function timeoutToUndefined<T>(time: number, p: Promise<T>) {
|
|
64
|
+
return new Promise<T | undefined>((resolve, reject) => {
|
|
65
|
+
let timeout = setTimeout(() => {
|
|
66
|
+
console.error(blue(`timeoutToUndefined timed out after ${time}`));
|
|
67
|
+
resolve(undefined);
|
|
68
|
+
}, time);
|
|
69
|
+
p.then(resolve,
|
|
70
|
+
(err) => {
|
|
71
|
+
console.error(`${blue("timeoutToUndefined error")}: ${red(err.stack)}`);
|
|
72
|
+
resolve(undefined);
|
|
73
|
+
}
|
|
74
|
+
).finally(() => clearTimeout(timeout));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export function timeoutToUndefinedSilent<T>(time: number, p: Promise<T>) {
|
|
78
|
+
return new Promise<T | undefined>((resolve, reject) => {
|
|
79
|
+
let timeout = setTimeout(() => {
|
|
80
|
+
resolve(undefined);
|
|
81
|
+
}, time);
|
|
82
|
+
p.then(
|
|
83
|
+
resolve,
|
|
84
|
+
(err) => {
|
|
85
|
+
resolve(undefined);
|
|
86
|
+
}
|
|
87
|
+
).finally(() => clearTimeout(timeout));
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Used when accessing paid resources, so we don't rack up charges due to an error,
|
|
92
|
+
* but also so that it doesn't take forever for the initial call to run.
|
|
93
|
+
*/
|
|
94
|
+
export async function backoffRetryLoop<T>(code: () => Promise<T>, waitTime = 5 * 1000) {
|
|
95
|
+
while (true) {
|
|
96
|
+
try {
|
|
97
|
+
return await code();
|
|
98
|
+
} catch (e: any) {
|
|
99
|
+
console.error(`Error retrying in ${waitTime}ms\n${e.stack}`);
|
|
100
|
+
await delay(waitTime);
|
|
101
|
+
waitTime *= 1.01;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function errorify(error: any, messageOverride?: string) {
|
|
107
|
+
if (error instanceof Error) {
|
|
108
|
+
return error;
|
|
109
|
+
}
|
|
110
|
+
let errorObj = new Error();
|
|
111
|
+
if (typeof error === "string" && error.includes("\n")) {
|
|
112
|
+
errorObj.stack = error;
|
|
113
|
+
errorObj.message = error.split("\n")[0];
|
|
114
|
+
} else {
|
|
115
|
+
errorObj.message = error;
|
|
116
|
+
errorObj.stack = error + "\n" + errorObj.stack;
|
|
117
|
+
}
|
|
118
|
+
if (messageOverride) {
|
|
119
|
+
errorObj.message = messageOverride;
|
|
120
|
+
}
|
|
121
|
+
return errorObj;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function assertValue<T>(value: T | undefined | null, message?: string): T {
|
|
125
|
+
if (value === undefined || value === null) {
|
|
126
|
+
throw new Error(`Value is ${value === undefined ? "undefined" : "null"}, ${message}`);
|
|
127
|
+
}
|
|
128
|
+
return value;
|
|
129
|
+
}
|
|
130
|
+
export function assert<T>(value: T | undefined | null, message?: string): asserts value is T {
|
|
131
|
+
if (value === undefined || value === null) {
|
|
132
|
+
throw new Error(`Value is ${value === undefined ? "undefined" : "null"}, ${message}`);
|
|
133
|
+
}
|
|
134
134
|
}
|
package/src/forceProduction.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
if (typeof process === "object") {
|
|
2
|
-
process.env["NODE_ENV"] = "production";
|
|
1
|
+
if (typeof process === "object") {
|
|
2
|
+
process.env["NODE_ENV"] = "production";
|
|
3
3
|
}
|