querysub 0.437.0 → 0.439.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.
Files changed (81) hide show
  1. package/.eslintrc.js +50 -50
  2. package/bin/deploy.js +0 -0
  3. package/bin/function.js +0 -0
  4. package/bin/server.js +0 -0
  5. package/costsBenefits.txt +115 -115
  6. package/deploy.ts +2 -2
  7. package/package.json +2 -2
  8. package/spec.txt +1192 -1192
  9. package/src/-a-archives/archives.ts +202 -202
  10. package/src/-a-archives/archivesDisk.ts +454 -454
  11. package/src/-a-auth/certs.ts +540 -540
  12. package/src/-a-auth/node-forge-ed25519.d.ts +16 -16
  13. package/src/-b-authorities/dnsAuthority.ts +138 -138
  14. package/src/-c-identity/IdentityController.ts +258 -258
  15. package/src/-d-trust/NetworkTrust2.ts +180 -180
  16. package/src/-e-certs/EdgeCertController.ts +252 -252
  17. package/src/-e-certs/certAuthority.ts +201 -201
  18. package/src/-f-node-discovery/NodeDiscovery.ts +640 -640
  19. package/src/-g-core-values/NodeCapabilities.ts +200 -200
  20. package/src/-h-path-value-serialize/stringSerializer.ts +175 -175
  21. package/src/0-path-value-core/PathValueCommitter.ts +468 -468
  22. package/src/0-path-value-core/PathValueController.ts +0 -2
  23. package/src/0-path-value-core/archiveLocks/archiveSnapshots.ts +37 -1
  24. package/src/0-path-value-core/pathValueCore.ts +12 -0
  25. package/src/2-proxy/PathValueProxyWatcher.ts +2542 -2542
  26. package/src/2-proxy/TransactionDelayer.ts +94 -94
  27. package/src/2-proxy/pathDatabaseProxyBase.ts +36 -36
  28. package/src/2-proxy/pathValueProxy.ts +159 -159
  29. package/src/3-path-functions/PathFunctionRunner.ts +24 -13
  30. package/src/3-path-functions/PathFunctionRunnerMain.ts +87 -87
  31. package/src/3-path-functions/pathFunctionLoader.ts +516 -516
  32. package/src/3-path-functions/tests/rejectTest.ts +76 -76
  33. package/src/4-deploy/deployCheck.ts +6 -6
  34. package/src/4-dom/css.tsx +29 -29
  35. package/src/4-dom/cssTypes.d.ts +211 -211
  36. package/src/4-dom/qreact.tsx +2799 -2799
  37. package/src/4-dom/qreactTest.tsx +410 -410
  38. package/src/4-querysub/permissions.ts +335 -335
  39. package/src/4-querysub/querysubPrediction.ts +483 -483
  40. package/src/5-diagnostics/qreactDebug.tsx +400 -346
  41. package/src/TestController.ts +34 -34
  42. package/src/bits.ts +104 -104
  43. package/src/buffers.ts +69 -69
  44. package/src/diagnostics/ActionsHistory.ts +57 -57
  45. package/src/diagnostics/PathDistributionInfo.tsx +9 -1
  46. package/src/diagnostics/listenOnDebugger.ts +71 -71
  47. package/src/diagnostics/logs/IndexedLogs/BufferUnitIndex.ts +1 -1
  48. package/src/diagnostics/logs/diskLogger.ts +6 -0
  49. package/src/diagnostics/misc-pages/SnapshotViewer.tsx +78 -1
  50. package/src/diagnostics/periodic.ts +111 -111
  51. package/src/diagnostics/trackResources.ts +91 -91
  52. package/src/diagnostics/watchdog.ts +120 -120
  53. package/src/errors.ts +133 -133
  54. package/src/forceProduction.ts +2 -2
  55. package/src/fs.ts +80 -80
  56. package/src/functional/diff.ts +857 -857
  57. package/src/functional/promiseCache.ts +78 -78
  58. package/src/functional/random.ts +8 -8
  59. package/src/functional/stats.ts +60 -60
  60. package/src/heapDumps.ts +665 -665
  61. package/src/https.ts +1 -1
  62. package/src/library-components/AspectSizedComponent.tsx +87 -87
  63. package/src/library-components/ButtonSelector.tsx +64 -64
  64. package/src/library-components/DropdownCustom.tsx +150 -150
  65. package/src/library-components/DropdownSelector.tsx +31 -31
  66. package/src/library-components/InlinePopup.tsx +66 -66
  67. package/src/library-components/uncaughtToast.tsx +2 -0
  68. package/src/misc/color.ts +29 -29
  69. package/src/misc/hash.ts +83 -83
  70. package/src/misc/ipPong.js +13 -13
  71. package/src/misc/networking.ts +1 -1
  72. package/src/misc/random.ts +44 -44
  73. package/src/misc.ts +196 -196
  74. package/src/path.ts +255 -255
  75. package/src/persistentLocalStore.ts +41 -41
  76. package/src/promise.ts +14 -14
  77. package/src/storage/fileSystemPointer.ts +71 -71
  78. package/src/test/heapProcess.ts +35 -35
  79. package/src/zip.ts +15 -15
  80. package/tsconfig.json +26 -26
  81. 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
  }
@@ -13,6 +13,8 @@ function onUncaught(...args: unknown[]) {
13
13
  // Ignore ResizeObserver errors, they are spurious
14
14
  // - https://github.com/vercel/next.js/discussions/51551
15
15
  if (error.message.startsWith("ResizeObserver loop")) return;
16
+ // We should really do this better. Basically, if we're disposing or canceling, it's not actually an error, just ignore it.
17
+ if (error.message.startsWith("Dispose")) return;
16
18
 
17
19
  onMessage({
18
20
  type: "error",
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
  }
@@ -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
+ });
@@ -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 };
@@ -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
  }