querysub 0.433.0 → 0.437.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/pathValueCore.ts +2 -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 +346 -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,32 +1,32 @@
|
|
|
1
|
-
import preact from "preact";
|
|
2
|
-
import { Querysub } from "../../src/4-querysub/QuerysubController";
|
|
3
|
-
import { qreact } from "../../src/4-dom/qreact";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export class DropdownSelector<T> extends qreact.Component<{
|
|
7
|
-
title?: string;
|
|
8
|
-
value: T;
|
|
9
|
-
onChange: (value: T) => void;
|
|
10
|
-
options: { value: T; label: string; }[];
|
|
11
|
-
}> {
|
|
12
|
-
render() {
|
|
13
|
-
const { options, value, title, onChange } = this.props;
|
|
14
|
-
let optionValues = options.map(o => String(o.value));
|
|
15
|
-
return (
|
|
16
|
-
<label style={{ display: "flex", gap: 10, alignItems: "center" }}>
|
|
17
|
-
{title && <span>{title}</span>}
|
|
18
|
-
<select
|
|
19
|
-
value={String(value)}
|
|
20
|
-
onChange={e => {
|
|
21
|
-
let option = options[optionValues.indexOf(e.currentTarget.value)];
|
|
22
|
-
onChange(option ? option.value : e.currentTarget.value as T);
|
|
23
|
-
}}
|
|
24
|
-
>
|
|
25
|
-
{options.map(({ value, label }) =>
|
|
26
|
-
<option value={String(value)}>{label}</option>
|
|
27
|
-
)}
|
|
28
|
-
</select>
|
|
29
|
-
</label>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
1
|
+
import preact from "preact";
|
|
2
|
+
import { Querysub } from "../../src/4-querysub/QuerysubController";
|
|
3
|
+
import { qreact } from "../../src/4-dom/qreact";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class DropdownSelector<T> extends qreact.Component<{
|
|
7
|
+
title?: string;
|
|
8
|
+
value: T;
|
|
9
|
+
onChange: (value: T) => void;
|
|
10
|
+
options: { value: T; label: string; }[];
|
|
11
|
+
}> {
|
|
12
|
+
render() {
|
|
13
|
+
const { options, value, title, onChange } = this.props;
|
|
14
|
+
let optionValues = options.map(o => String(o.value));
|
|
15
|
+
return (
|
|
16
|
+
<label style={{ display: "flex", gap: 10, alignItems: "center" }}>
|
|
17
|
+
{title && <span>{title}</span>}
|
|
18
|
+
<select
|
|
19
|
+
value={String(value)}
|
|
20
|
+
onChange={e => {
|
|
21
|
+
let option = options[optionValues.indexOf(e.currentTarget.value)];
|
|
22
|
+
onChange(option ? option.value : e.currentTarget.value as T);
|
|
23
|
+
}}
|
|
24
|
+
>
|
|
25
|
+
{options.map(({ value, label }) =>
|
|
26
|
+
<option value={String(value)}>{label}</option>
|
|
27
|
+
)}
|
|
28
|
+
</select>
|
|
29
|
+
</label>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
32
|
}
|
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
import preact from "preact";
|
|
2
|
-
import { Querysub } from "../4-querysub/QuerysubController";
|
|
3
|
-
import { qreact } from "../4-dom/qreact";
|
|
4
|
-
import { Button } from "../library-components/Button";
|
|
5
|
-
import { Icon } from "../library-components/icons";
|
|
6
|
-
import { createURLSync } from "./URLParam";
|
|
7
|
-
|
|
8
|
-
const popupURL = createURLSync<string>("popup", "");
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export class InlinePopup extends qreact.Component<{
|
|
12
|
-
type: string;
|
|
13
|
-
margin?: number;
|
|
14
|
-
}> {
|
|
15
|
-
render() {
|
|
16
|
-
if (popupURL.value !== this.props.type) return undefined;
|
|
17
|
-
let margin = this.props.margin ?? 100;
|
|
18
|
-
return (
|
|
19
|
-
<div
|
|
20
|
-
style={{
|
|
21
|
-
position: "fixed",
|
|
22
|
-
left: 0, top: 0,
|
|
23
|
-
width: "100vw", height: "100vh",
|
|
24
|
-
zIndex: 1000,
|
|
25
|
-
}}
|
|
26
|
-
onClick={e => qreact.isTarget(e) && (popupURL.value = "")}
|
|
27
|
-
>
|
|
28
|
-
<div style={{
|
|
29
|
-
margin,
|
|
30
|
-
position: "relative",
|
|
31
|
-
zIndex: 1,
|
|
32
|
-
}}>
|
|
33
|
-
<Button
|
|
34
|
-
hotkeys={["Escape"]}
|
|
35
|
-
showHotkeys
|
|
36
|
-
onClick={() => popupURL.value = ""}
|
|
37
|
-
style={{
|
|
38
|
-
position: "absolute",
|
|
39
|
-
right: 0, top: -10,
|
|
40
|
-
transform: "translate(0%, -100%)",
|
|
41
|
-
border: "1px solid hsl(0, 0%, 7%)",
|
|
42
|
-
}}
|
|
43
|
-
>
|
|
44
|
-
{Icon.close()}
|
|
45
|
-
</Button>
|
|
46
|
-
<div style={{
|
|
47
|
-
maxHeight: `calc(100vh - ${margin * 2}px)`,
|
|
48
|
-
overflow: "auto",
|
|
49
|
-
}}>
|
|
50
|
-
{this.props.children}
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
<div
|
|
54
|
-
className="button"
|
|
55
|
-
style={{
|
|
56
|
-
position: "absolute",
|
|
57
|
-
left: 0, top: 0,
|
|
58
|
-
width: "100%", height: "100%",
|
|
59
|
-
background: "hsl(0, 0%, 50%, 0.5)",
|
|
60
|
-
zIndex: 0,
|
|
61
|
-
}}
|
|
62
|
-
onClick={e => popupURL.value = ""}
|
|
63
|
-
/>
|
|
64
|
-
</div>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
1
|
+
import preact from "preact";
|
|
2
|
+
import { Querysub } from "../4-querysub/QuerysubController";
|
|
3
|
+
import { qreact } from "../4-dom/qreact";
|
|
4
|
+
import { Button } from "../library-components/Button";
|
|
5
|
+
import { Icon } from "../library-components/icons";
|
|
6
|
+
import { createURLSync } from "./URLParam";
|
|
7
|
+
|
|
8
|
+
const popupURL = createURLSync<string>("popup", "");
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export class InlinePopup extends qreact.Component<{
|
|
12
|
+
type: string;
|
|
13
|
+
margin?: number;
|
|
14
|
+
}> {
|
|
15
|
+
render() {
|
|
16
|
+
if (popupURL.value !== this.props.type) return undefined;
|
|
17
|
+
let margin = this.props.margin ?? 100;
|
|
18
|
+
return (
|
|
19
|
+
<div
|
|
20
|
+
style={{
|
|
21
|
+
position: "fixed",
|
|
22
|
+
left: 0, top: 0,
|
|
23
|
+
width: "100vw", height: "100vh",
|
|
24
|
+
zIndex: 1000,
|
|
25
|
+
}}
|
|
26
|
+
onClick={e => qreact.isTarget(e) && (popupURL.value = "")}
|
|
27
|
+
>
|
|
28
|
+
<div style={{
|
|
29
|
+
margin,
|
|
30
|
+
position: "relative",
|
|
31
|
+
zIndex: 1,
|
|
32
|
+
}}>
|
|
33
|
+
<Button
|
|
34
|
+
hotkeys={["Escape"]}
|
|
35
|
+
showHotkeys
|
|
36
|
+
onClick={() => popupURL.value = ""}
|
|
37
|
+
style={{
|
|
38
|
+
position: "absolute",
|
|
39
|
+
right: 0, top: -10,
|
|
40
|
+
transform: "translate(0%, -100%)",
|
|
41
|
+
border: "1px solid hsl(0, 0%, 7%)",
|
|
42
|
+
}}
|
|
43
|
+
>
|
|
44
|
+
{Icon.close()}
|
|
45
|
+
</Button>
|
|
46
|
+
<div style={{
|
|
47
|
+
maxHeight: `calc(100vh - ${margin * 2}px)`,
|
|
48
|
+
overflow: "auto",
|
|
49
|
+
}}>
|
|
50
|
+
{this.props.children}
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div
|
|
54
|
+
className="button"
|
|
55
|
+
style={{
|
|
56
|
+
position: "absolute",
|
|
57
|
+
left: 0, top: 0,
|
|
58
|
+
width: "100%", height: "100%",
|
|
59
|
+
background: "hsl(0, 0%, 50%, 0.5)",
|
|
60
|
+
zIndex: 0,
|
|
61
|
+
}}
|
|
62
|
+
onClick={e => popupURL.value = ""}
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
67
|
}
|
package/src/misc/color.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
/** hue: 0-360, saturation: 0-100, lightness: 0-100 */
|
|
3
|
-
export function hslToRGB(color: { h: number; s: number; l: number }) {
|
|
4
|
-
let { h, s, l } = color;
|
|
5
|
-
h /= 360;
|
|
6
|
-
s /= 100;
|
|
7
|
-
l /= 100;
|
|
8
|
-
let r, g, b;
|
|
9
|
-
if (s === 0) {
|
|
10
|
-
r = g = b = l; // achromatic
|
|
11
|
-
} else {
|
|
12
|
-
const hue2rgb = (p: number, q: number, t: number) => {
|
|
13
|
-
if (t < 0) t += 1;
|
|
14
|
-
if (t > 1) t -= 1;
|
|
15
|
-
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
|
16
|
-
if (t < 1 / 2) return q;
|
|
17
|
-
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
|
18
|
-
return p;
|
|
19
|
-
};
|
|
20
|
-
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
21
|
-
const p = 2 * l - q;
|
|
22
|
-
r = hue2rgb(p, q, h + 1 / 3);
|
|
23
|
-
g = hue2rgb(p, q, h);
|
|
24
|
-
b = hue2rgb(p, q, h - 1 / 3);
|
|
25
|
-
if (b < 0) {
|
|
26
|
-
b = 0;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) };
|
|
1
|
+
|
|
2
|
+
/** hue: 0-360, saturation: 0-100, lightness: 0-100 */
|
|
3
|
+
export function hslToRGB(color: { h: number; s: number; l: number }) {
|
|
4
|
+
let { h, s, l } = color;
|
|
5
|
+
h /= 360;
|
|
6
|
+
s /= 100;
|
|
7
|
+
l /= 100;
|
|
8
|
+
let r, g, b;
|
|
9
|
+
if (s === 0) {
|
|
10
|
+
r = g = b = l; // achromatic
|
|
11
|
+
} else {
|
|
12
|
+
const hue2rgb = (p: number, q: number, t: number) => {
|
|
13
|
+
if (t < 0) t += 1;
|
|
14
|
+
if (t > 1) t -= 1;
|
|
15
|
+
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
|
16
|
+
if (t < 1 / 2) return q;
|
|
17
|
+
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
|
18
|
+
return p;
|
|
19
|
+
};
|
|
20
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
21
|
+
const p = 2 * l - q;
|
|
22
|
+
r = hue2rgb(p, q, h + 1 / 3);
|
|
23
|
+
g = hue2rgb(p, q, h);
|
|
24
|
+
b = hue2rgb(p, q, h - 1 / 3);
|
|
25
|
+
if (b < 0) {
|
|
26
|
+
b = 0;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { r: Math.floor(r * 255), g: Math.floor(g * 255), b: Math.floor(b * 255) };
|
|
30
30
|
}
|
package/src/misc/hash.ts
CHANGED
|
@@ -1,84 +1,84 @@
|
|
|
1
|
-
import debugbreak from "debugbreak";
|
|
2
|
-
|
|
3
|
-
/** Returns an integer */
|
|
4
|
-
export function fastHash(text: string): number {
|
|
5
|
-
// Murmur, but we try to use more than 32 bits, as a double can store far more than 32 bits.
|
|
6
|
-
let hash1 = 5380942 ^ text.length;
|
|
7
|
-
let hash2 = 9143241 ^ text.length;
|
|
8
|
-
for (let i = 0; i < text.length; i++) {
|
|
9
|
-
let ch = text.charCodeAt(i);
|
|
10
|
-
hash1 = addToMurmurHash(hash1, ch);
|
|
11
|
-
hash2 = addToMurmurHash(hash2, ch);
|
|
12
|
-
}
|
|
13
|
-
hash1 = finishMurmurHash(hash1);
|
|
14
|
-
hash2 = finishMurmurHash(hash2);
|
|
15
|
-
return Math.abs(hash1 * (2 ** 20) + hash2);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** Hashes an object so the result is the same independent of key order
|
|
19
|
-
* Ex, consistentHash({ x: 1, y: 2 }) === consistentHash({ y: 2, x: 1 })
|
|
20
|
-
* - Works with nested values
|
|
21
|
-
* - The hash isn't small, and is really just the JSON stringified re-ordered object
|
|
22
|
-
*/
|
|
23
|
-
export function consistentHash(obj: unknown): string {
|
|
24
|
-
return JSON.stringify(orderObjectKeys(obj));
|
|
25
|
-
}
|
|
26
|
-
function orderObjectKeys(obj: unknown): unknown {
|
|
27
|
-
if (typeof obj !== "object" || obj === null) return obj;
|
|
28
|
-
if (Array.isArray(obj)) return obj.map(x => orderObjectKeys(x));
|
|
29
|
-
let keys = Object.keys(obj);
|
|
30
|
-
keys.sort();
|
|
31
|
-
let newObj: Record<string, unknown> = {};
|
|
32
|
-
for (let key of keys) {
|
|
33
|
-
newObj[key] = orderObjectKeys((obj as any)[key]);
|
|
34
|
-
}
|
|
35
|
-
return newObj;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function addToMurmurHash(curHash: number, next: number) {
|
|
39
|
-
// murmurhash, 32 bit
|
|
40
|
-
// https://github.com/mikolalysenko/murmurhash-js/blob/master/murmurhash2_gc.js
|
|
41
|
-
let h = curHash;
|
|
42
|
-
let k = next;
|
|
43
|
-
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
44
|
-
k ^= k >>> 24;
|
|
45
|
-
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
46
|
-
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
|
|
47
|
-
|
|
48
|
-
return h;
|
|
49
|
-
}
|
|
50
|
-
function finishMurmurHash(curHash: number) {
|
|
51
|
-
let h = curHash;
|
|
52
|
-
h ^= h >>> 13;
|
|
53
|
-
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
54
|
-
h ^= h >>> 15;
|
|
55
|
-
return h;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export function hashBufferRange32(buffer: Buffer, start: number, end: number) {
|
|
59
|
-
if (start < 0) start = 0;
|
|
60
|
-
if (end > buffer.byteLength) end = buffer.byteLength;
|
|
61
|
-
|
|
62
|
-
let len = end - start;
|
|
63
|
-
let len4 = len - (len % 4);
|
|
64
|
-
let hash = end - start;
|
|
65
|
-
for (let i = 0; i < len4; i += 4) {
|
|
66
|
-
hash = addToMurmurHash(hash, buffer.readUInt32LE(i + start));
|
|
67
|
-
}
|
|
68
|
-
for (let i = len4; i < len; i++) {
|
|
69
|
-
hash = addToMurmurHash(hash, buffer[i + start]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return hash;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function hashBufferRange64(buffer: Buffer, start: number, end: number) {
|
|
76
|
-
if (start < 0) start = 0;
|
|
77
|
-
if (end > buffer.byteLength) end = buffer.byteLength;
|
|
78
|
-
let size = end - start;
|
|
79
|
-
let middle = start + Math.ceil(size / 2);
|
|
80
|
-
|
|
81
|
-
let hash1 = hashBufferRange32(buffer, start, middle);
|
|
82
|
-
let hash2 = hashBufferRange32(buffer, middle, end);
|
|
83
|
-
return Math.abs(hash1 * (2 ** 20) + hash2);
|
|
1
|
+
import debugbreak from "debugbreak";
|
|
2
|
+
|
|
3
|
+
/** Returns an integer */
|
|
4
|
+
export function fastHash(text: string): number {
|
|
5
|
+
// Murmur, but we try to use more than 32 bits, as a double can store far more than 32 bits.
|
|
6
|
+
let hash1 = 5380942 ^ text.length;
|
|
7
|
+
let hash2 = 9143241 ^ text.length;
|
|
8
|
+
for (let i = 0; i < text.length; i++) {
|
|
9
|
+
let ch = text.charCodeAt(i);
|
|
10
|
+
hash1 = addToMurmurHash(hash1, ch);
|
|
11
|
+
hash2 = addToMurmurHash(hash2, ch);
|
|
12
|
+
}
|
|
13
|
+
hash1 = finishMurmurHash(hash1);
|
|
14
|
+
hash2 = finishMurmurHash(hash2);
|
|
15
|
+
return Math.abs(hash1 * (2 ** 20) + hash2);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Hashes an object so the result is the same independent of key order
|
|
19
|
+
* Ex, consistentHash({ x: 1, y: 2 }) === consistentHash({ y: 2, x: 1 })
|
|
20
|
+
* - Works with nested values
|
|
21
|
+
* - The hash isn't small, and is really just the JSON stringified re-ordered object
|
|
22
|
+
*/
|
|
23
|
+
export function consistentHash(obj: unknown): string {
|
|
24
|
+
return JSON.stringify(orderObjectKeys(obj));
|
|
25
|
+
}
|
|
26
|
+
function orderObjectKeys(obj: unknown): unknown {
|
|
27
|
+
if (typeof obj !== "object" || obj === null) return obj;
|
|
28
|
+
if (Array.isArray(obj)) return obj.map(x => orderObjectKeys(x));
|
|
29
|
+
let keys = Object.keys(obj);
|
|
30
|
+
keys.sort();
|
|
31
|
+
let newObj: Record<string, unknown> = {};
|
|
32
|
+
for (let key of keys) {
|
|
33
|
+
newObj[key] = orderObjectKeys((obj as any)[key]);
|
|
34
|
+
}
|
|
35
|
+
return newObj;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function addToMurmurHash(curHash: number, next: number) {
|
|
39
|
+
// murmurhash, 32 bit
|
|
40
|
+
// https://github.com/mikolalysenko/murmurhash-js/blob/master/murmurhash2_gc.js
|
|
41
|
+
let h = curHash;
|
|
42
|
+
let k = next;
|
|
43
|
+
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
44
|
+
k ^= k >>> 24;
|
|
45
|
+
k = (((k & 0xffff) * 0x5bd1e995) + ((((k >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
46
|
+
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16)) ^ k;
|
|
47
|
+
|
|
48
|
+
return h;
|
|
49
|
+
}
|
|
50
|
+
function finishMurmurHash(curHash: number) {
|
|
51
|
+
let h = curHash;
|
|
52
|
+
h ^= h >>> 13;
|
|
53
|
+
h = (((h & 0xffff) * 0x5bd1e995) + ((((h >>> 16) * 0x5bd1e995) & 0xffff) << 16));
|
|
54
|
+
h ^= h >>> 15;
|
|
55
|
+
return h;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function hashBufferRange32(buffer: Buffer, start: number, end: number) {
|
|
59
|
+
if (start < 0) start = 0;
|
|
60
|
+
if (end > buffer.byteLength) end = buffer.byteLength;
|
|
61
|
+
|
|
62
|
+
let len = end - start;
|
|
63
|
+
let len4 = len - (len % 4);
|
|
64
|
+
let hash = end - start;
|
|
65
|
+
for (let i = 0; i < len4; i += 4) {
|
|
66
|
+
hash = addToMurmurHash(hash, buffer.readUInt32LE(i + start));
|
|
67
|
+
}
|
|
68
|
+
for (let i = len4; i < len; i++) {
|
|
69
|
+
hash = addToMurmurHash(hash, buffer[i + start]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return hash;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function hashBufferRange64(buffer: Buffer, start: number, end: number) {
|
|
76
|
+
if (start < 0) start = 0;
|
|
77
|
+
if (end > buffer.byteLength) end = buffer.byteLength;
|
|
78
|
+
let size = end - start;
|
|
79
|
+
let middle = start + Math.ceil(size / 2);
|
|
80
|
+
|
|
81
|
+
let hash1 = hashBufferRange32(buffer, start, middle);
|
|
82
|
+
let hash2 = hashBufferRange32(buffer, middle, end);
|
|
83
|
+
return Math.abs(hash1 * (2 ** 20) + hash2);
|
|
84
84
|
}
|
package/src/misc/ipPong.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
// HTTP response with the caller IP
|
|
2
|
-
|
|
3
|
-
const http = require("http");
|
|
4
|
-
const port = 4283;
|
|
5
|
-
|
|
6
|
-
const server = http.createServer((req, res) => {
|
|
7
|
-
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
8
|
-
res.end(req.socket.remoteAddress.split(":").pop());
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
server.listen(port, () => {
|
|
12
|
-
console.log(`Server running at http://localhost:${port}/`);
|
|
13
|
-
});
|
|
1
|
+
// HTTP response with the caller IP
|
|
2
|
+
|
|
3
|
+
const http = require("http");
|
|
4
|
+
const port = 4283;
|
|
5
|
+
|
|
6
|
+
const server = http.createServer((req, res) => {
|
|
7
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
8
|
+
res.end(req.socket.remoteAddress.split(":").pop());
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
server.listen(port, () => {
|
|
12
|
+
console.log(`Server running at http://localhost:${port}/`);
|
|
13
|
+
});
|
package/src/misc/networking.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { testTCPIsListening, getExternalIP, getPublicIP } from "socket-function/src/networking";
|
|
1
|
+
import { testTCPIsListening, getExternalIP, getPublicIP } from "socket-function/src/networking";
|
|
2
2
|
export { testTCPIsListening, getExternalIP, getPublicIP };
|
package/src/misc/random.ts
CHANGED
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
import { isNode } from "socket-function/src/misc";
|
|
2
|
-
import crypto from "crypto";
|
|
3
|
-
|
|
4
|
-
export function getSeededRandom(seed: number): () => number {
|
|
5
|
-
// Multiply seed by a large prime
|
|
6
|
-
seed = (seed + 0x1235234894) * 0x1fffffff % 0x7fffffff;
|
|
7
|
-
let rand = sfc32(seed, seed, seed, seed);
|
|
8
|
-
// Run a few time, to fully seed it
|
|
9
|
-
for (let i = 0; i < 10; i++) {
|
|
10
|
-
rand();
|
|
11
|
-
}
|
|
12
|
-
return rand;
|
|
13
|
-
function sfc32(a: number, b: number, c: number, d: number) {
|
|
14
|
-
return function () {
|
|
15
|
-
a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
|
|
16
|
-
var t = (a + b) | 0;
|
|
17
|
-
a = b ^ b >>> 9;
|
|
18
|
-
b = c + (c << 3) | 0;
|
|
19
|
-
c = (c << 21 | c >>> 11);
|
|
20
|
-
d = d + 1 | 0;
|
|
21
|
-
t = t + d | 0;
|
|
22
|
-
c = c + t | 0;
|
|
23
|
-
return (t >>> 0) / 4294967296;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function shuffle<T>(array: T[], seed: number) {
|
|
29
|
-
let rand = getSeededRandom(seed);
|
|
30
|
-
let indexes = Array(array.length).fill(0).map((x, i) => i);
|
|
31
|
-
let shuffleValue = indexes.map(() => rand());
|
|
32
|
-
indexes.sort((a, b) => shuffleValue[a] - shuffleValue[b]);
|
|
33
|
-
return indexes.map(i => array[i]);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
let randomData = new Uint8Array(8);
|
|
37
|
-
let randomDataF64 = new Float64Array(randomData.buffer);
|
|
38
|
-
export function secureRandom(): number {
|
|
39
|
-
if (!isNode()) {
|
|
40
|
-
window.crypto.getRandomValues(randomData);
|
|
41
|
-
} else {
|
|
42
|
-
crypto.getRandomValues(randomData);
|
|
43
|
-
}
|
|
44
|
-
return randomDataF64[0];
|
|
1
|
+
import { isNode } from "socket-function/src/misc";
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
|
|
4
|
+
export function getSeededRandom(seed: number): () => number {
|
|
5
|
+
// Multiply seed by a large prime
|
|
6
|
+
seed = (seed + 0x1235234894) * 0x1fffffff % 0x7fffffff;
|
|
7
|
+
let rand = sfc32(seed, seed, seed, seed);
|
|
8
|
+
// Run a few time, to fully seed it
|
|
9
|
+
for (let i = 0; i < 10; i++) {
|
|
10
|
+
rand();
|
|
11
|
+
}
|
|
12
|
+
return rand;
|
|
13
|
+
function sfc32(a: number, b: number, c: number, d: number) {
|
|
14
|
+
return function () {
|
|
15
|
+
a >>>= 0; b >>>= 0; c >>>= 0; d >>>= 0;
|
|
16
|
+
var t = (a + b) | 0;
|
|
17
|
+
a = b ^ b >>> 9;
|
|
18
|
+
b = c + (c << 3) | 0;
|
|
19
|
+
c = (c << 21 | c >>> 11);
|
|
20
|
+
d = d + 1 | 0;
|
|
21
|
+
t = t + d | 0;
|
|
22
|
+
c = c + t | 0;
|
|
23
|
+
return (t >>> 0) / 4294967296;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function shuffle<T>(array: T[], seed: number) {
|
|
29
|
+
let rand = getSeededRandom(seed);
|
|
30
|
+
let indexes = Array(array.length).fill(0).map((x, i) => i);
|
|
31
|
+
let shuffleValue = indexes.map(() => rand());
|
|
32
|
+
indexes.sort((a, b) => shuffleValue[a] - shuffleValue[b]);
|
|
33
|
+
return indexes.map(i => array[i]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let randomData = new Uint8Array(8);
|
|
37
|
+
let randomDataF64 = new Float64Array(randomData.buffer);
|
|
38
|
+
export function secureRandom(): number {
|
|
39
|
+
if (!isNode()) {
|
|
40
|
+
window.crypto.getRandomValues(randomData);
|
|
41
|
+
} else {
|
|
42
|
+
crypto.getRandomValues(randomData);
|
|
43
|
+
}
|
|
44
|
+
return randomDataF64[0];
|
|
45
45
|
}
|