querysub 0.432.0 → 0.436.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 (74) 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 +1 -1
  8. package/spec.txt +1192 -1192
  9. package/src/-a-archives/archives.ts +202 -202
  10. package/src/-a-archives/archivesBackBlaze.ts +1 -0
  11. package/src/-a-archives/archivesDisk.ts +454 -454
  12. package/src/-a-auth/certs.ts +540 -540
  13. package/src/-a-auth/node-forge-ed25519.d.ts +16 -16
  14. package/src/-b-authorities/dnsAuthority.ts +138 -138
  15. package/src/-c-identity/IdentityController.ts +258 -258
  16. package/src/-d-trust/NetworkTrust2.ts +180 -180
  17. package/src/-e-certs/EdgeCertController.ts +252 -252
  18. package/src/-e-certs/certAuthority.ts +201 -201
  19. package/src/-f-node-discovery/NodeDiscovery.ts +640 -640
  20. package/src/-g-core-values/NodeCapabilities.ts +200 -200
  21. package/src/-h-path-value-serialize/stringSerializer.ts +175 -175
  22. package/src/0-path-value-core/PathValueCommitter.ts +468 -468
  23. package/src/0-path-value-core/pathValueCore.ts +2 -2
  24. package/src/2-proxy/PathValueProxyWatcher.ts +2542 -2542
  25. package/src/2-proxy/TransactionDelayer.ts +94 -94
  26. package/src/2-proxy/pathDatabaseProxyBase.ts +36 -36
  27. package/src/2-proxy/pathValueProxy.ts +159 -159
  28. package/src/3-path-functions/PathFunctionRunnerMain.ts +87 -87
  29. package/src/3-path-functions/pathFunctionLoader.ts +516 -512
  30. package/src/3-path-functions/tests/rejectTest.ts +76 -76
  31. package/src/4-deploy/deployCheck.ts +6 -6
  32. package/src/4-dom/css.tsx +29 -29
  33. package/src/4-dom/cssTypes.d.ts +211 -211
  34. package/src/4-dom/qreact.tsx +2799 -2799
  35. package/src/4-dom/qreactTest.tsx +410 -410
  36. package/src/4-querysub/permissions.ts +335 -335
  37. package/src/4-querysub/querysubPrediction.ts +483 -483
  38. package/src/5-diagnostics/qreactDebug.tsx +346 -346
  39. package/src/TestController.ts +34 -34
  40. package/src/bits.ts +104 -104
  41. package/src/buffers.ts +69 -69
  42. package/src/diagnostics/ActionsHistory.ts +57 -57
  43. package/src/diagnostics/listenOnDebugger.ts +71 -71
  44. package/src/diagnostics/periodic.ts +111 -111
  45. package/src/diagnostics/trackResources.ts +91 -91
  46. package/src/diagnostics/watchdog.ts +120 -120
  47. package/src/errors.ts +133 -133
  48. package/src/forceProduction.ts +2 -2
  49. package/src/fs.ts +80 -80
  50. package/src/functional/diff.ts +857 -857
  51. package/src/functional/promiseCache.ts +78 -78
  52. package/src/functional/random.ts +8 -8
  53. package/src/functional/stats.ts +60 -60
  54. package/src/heapDumps.ts +665 -665
  55. package/src/https.ts +1 -1
  56. package/src/library-components/AspectSizedComponent.tsx +87 -87
  57. package/src/library-components/ButtonSelector.tsx +64 -64
  58. package/src/library-components/DropdownCustom.tsx +150 -150
  59. package/src/library-components/DropdownSelector.tsx +31 -31
  60. package/src/library-components/InlinePopup.tsx +66 -66
  61. package/src/misc/color.ts +29 -29
  62. package/src/misc/hash.ts +83 -83
  63. package/src/misc/ipPong.js +13 -13
  64. package/src/misc/networking.ts +1 -1
  65. package/src/misc/random.ts +44 -44
  66. package/src/misc.ts +196 -196
  67. package/src/path.ts +255 -255
  68. package/src/persistentLocalStore.ts +41 -41
  69. package/src/promise.ts +14 -14
  70. package/src/storage/fileSystemPointer.ts +71 -71
  71. package/src/test/heapProcess.ts +35 -35
  72. package/src/zip.ts +15 -15
  73. package/tsconfig.json +26 -26
  74. package/yarnSpec.txt +56 -56
@@ -1,203 +1,203 @@
1
- import { isNode } from "socket-function/src/misc";
2
- import { getDomain, isNoNetwork } from "../config";
3
- import { getStorageDir, getSubFolder } from "../fs";
4
- import { getArchivesBackblaze, hasBackblazePermissions } from "./archivesBackBlaze";
5
- import { getArchivesLocal } from "./archivesDisk";
6
- import { magenta } from "socket-function/src/formatting/logColors";
7
- import debugbreak from "debugbreak";
8
- import { isClient } from "../config2";
9
- import { wrapArchivesWithCache } from "./archiveCache";
10
- import { Args } from "socket-function/src/types";
11
-
12
- export interface Archives {
13
- getDebugName(): string;
14
-
15
- get(path: string, config?: {
16
- range?: { start: number; end: number; };
17
- retryCount?: number;
18
- // Skips checking if the file exists on the remote. Only appropriate when the file name is fresh (recently obtained from find).
19
- fastRead?: boolean;
20
- }): Promise<Buffer | undefined>;
21
- set(path: string, data: Buffer): Promise<void>;
22
- del(path: string): Promise<void>;
23
-
24
- append(path: string, data: Buffer): Promise<void>;
25
-
26
- getInfo(path: string): Promise<{ writeTime: number; size: number; } | undefined>;
27
-
28
- setLargeFile(config: { path: string; getNextData(): Promise<Buffer | undefined>; }): Promise<void>;
29
-
30
- // For example findFileNames("ips/")
31
- /** Returns to full paths. Returns paths WILL NOT end with / */
32
- find(
33
- prefix: string,
34
- config?: {
35
- shallow?: boolean;
36
- // Defaults to files
37
- type: "files" | "folders";
38
- }
39
- ): Promise<string[]>;
40
- findInfo(
41
- prefix: string,
42
- config?: {
43
- shallow?: boolean;
44
- // Defaults to files
45
- type: "files" | "folders";
46
- }
47
- ): Promise<{ path: string; createTime: number; size: number; }[]>;
48
-
49
- move(config: {
50
- path: string;
51
- target: Archives;
52
- targetPath: string;
53
- }): Promise<void>;
54
- copy(config: {
55
- path: string;
56
- target: Archives;
57
- targetPath: string;
58
- }): Promise<void>;
59
-
60
-
61
- enableLogging(): void;
62
-
63
- /** Might throw due to too long of a length. Should never throw due to characters, as we can always encode special characters. */
64
- assertPathValid(path: string): Promise<void>;
65
-
66
- getBaseArchives?: () => { parentPath: string; archives: Archives; } | undefined;
67
-
68
- /** Get a download URL for a file. Only implemented for some archive types (like Backblaze). */
69
- getURL?: (path: string) => Promise<string>;
70
-
71
- // NOTE: This isn't part of getURL, as it is much more efficient to call it once and reuse the authorization. This is only for backblaze as of right now.
72
- // NOTE: This also gives authorization for ALL files, so... ONLY use it for internal download links. If we need external links, we should use a public folder with hash links, or... make a new endpoint.
73
- getDownloadAuthorization?: (config: {
74
- validDurationInSeconds: number;
75
- }) => Promise<{
76
- bucketId: string;
77
- fileNamePrefix: string;
78
- authorizationToken: string;
79
- }>;
80
- }
81
-
82
- export function createArchivesOverride<T extends Partial<Archives>>(
83
- baseArchives: Archives,
84
- overrideArchives: T
85
- ): T & Archives {
86
- return {
87
- getDebugName: () => baseArchives.getDebugName(),
88
- get: (fileName: string, config) => baseArchives.get(fileName, config),
89
- set: (fileName: string, data: Buffer) => baseArchives.set(fileName, data),
90
- append: (fileName: string, data: Buffer) => baseArchives.append(fileName, data),
91
- del: (fileName: string) => baseArchives.del(fileName),
92
- getInfo: (fileName: string) => baseArchives.getInfo(fileName),
93
- setLargeFile: (config) => baseArchives.setLargeFile(config),
94
- find: async (prefix: string, config) => baseArchives.find(prefix, config),
95
- findInfo: async (prefix: string, config) => baseArchives.findInfo(prefix, config),
96
- enableLogging: () => baseArchives.enableLogging(),
97
- move: (config) => baseArchives.move(config),
98
- copy: (config) => baseArchives.copy(config),
99
- assertPathValid: (path: string) => baseArchives.assertPathValid(path),
100
- getBaseArchives: () => baseArchives.getBaseArchives?.() ?? ({ archives: baseArchives, parentPath: "" }),
101
- getURL: baseArchives.getURL ? (filePath: string) => baseArchives.getURL!(filePath) : undefined,
102
- getDownloadAuthorization: baseArchives.getDownloadAuthorization ? (config: { validDurationInSeconds: number }) => baseArchives.getDownloadAuthorization!(config) : undefined,
103
- ...overrideArchives,
104
- };
105
- }
106
-
107
- export function nestArchives(path: string, archives: Archives): Archives {
108
- if (!path) return archives;
109
- if (!path.endsWith("/")) {
110
- path = path + "/";
111
- }
112
- function stripFilePrefix(file: string) {
113
- if (file.startsWith("/")) {
114
- return file.slice(1);
115
- }
116
- return file;
117
- }
118
- return {
119
- getDebugName: () => archives.getDebugName() + "/" + path,
120
- get: (fileName: string, config) => archives.get(path + stripFilePrefix(fileName), config),
121
- setLargeFile: (config) => archives.setLargeFile({ ...config, path: path + stripFilePrefix(config.path) }),
122
- set: (fileName: string, data: Buffer) => archives.set(path + stripFilePrefix(fileName), data),
123
- append: (fileName: string, data: Buffer) => archives.append(path + stripFilePrefix(fileName), data),
124
- del: (fileName: string) => archives.del(path + stripFilePrefix(fileName)),
125
- getInfo: (fileName: string) => archives.getInfo(path + stripFilePrefix(fileName)),
126
- find: async (prefix: string, config) => archives.find(path + prefix, config).then(x => x.map(x => x.slice(path.length))),
127
- findInfo: async (prefix: string, config) => archives.findInfo(path + prefix, config).then(x => x.map(x => ({ path: x.path.slice(path.length), createTime: x.createTime, size: x.size }))),
128
- enableLogging: () => archives.enableLogging(),
129
- move: (config) => archives.move({
130
- path: path + config.path,
131
- target: config.target,
132
- targetPath: config.targetPath,
133
- }),
134
- copy: (config) => archives.copy({
135
- path: path + config.path,
136
- target: config.target,
137
- targetPath: config.targetPath,
138
- }),
139
- assertPathValid: (path: string) => archives.assertPathValid(path),
140
- getBaseArchives: () => {
141
- let result = { parentPath: path, archives };
142
- let base = archives.getBaseArchives?.();
143
- if (base) {
144
- result.parentPath = base.parentPath + path;
145
- result.archives = base.archives;
146
- }
147
- return result;
148
- },
149
- getURL: archives.getURL ? (filePath: string) => archives.getURL!(path + stripFilePrefix(filePath)) : undefined,
150
- getDownloadAuthorization: archives.getDownloadAuthorization && ((...args: Args<typeof archives.getDownloadAuthorization>) => archives.getDownloadAuthorization!(...args)),
151
- };
152
- }
153
-
154
- let archivesLogging = false;
155
- export function enableArchivesLogging() {
156
- archivesLogging = true;
157
- }
158
-
159
- let cached = new Map<string, Archives>();
160
- export function getArchives(rootPath = ""): Archives {
161
- let value = cached.get(rootPath);
162
- if (!value) {
163
- value = getArchivesBase(rootPath);
164
- cached.set(rootPath, value);
165
- }
166
- return value;
167
- }
168
- export function getArchivesBase(rootPath = ""): Archives {
169
- let archives: Archives;
170
- let domain = getDomain();
171
- if (isNoNetwork()) {
172
- archives = getArchivesLocal(domain);
173
- archives = nestArchives(rootPath, archives);
174
- } else {
175
- archives = getArchivesBackblaze(domain);
176
- archives = nestArchives(rootPath, archives);
177
- // Why did we think we should always cache? We absolutely should not. Even if we were checking
178
- // file hashes on every read (which we do not), it would still potentially fill the cache up
179
- // with large temporary files we have no intention of using (which might evict entries we
180
- // intend to use).
181
- //archives = wrapArchivesWithCache(archives);
182
- }
183
- if (archivesLogging) {
184
- archives.enableLogging();
185
- }
186
- return archives;
187
- }
188
-
189
- export function hasArchivesPermissions() {
190
- if (isNoNetwork()) {
191
- return true;
192
- }
193
- return hasBackblazePermissions();
194
- }
195
-
196
- if (isNode()) {
197
- if (isNoNetwork()) {
198
- console.log("Primary data storage: " + magenta(getStorageDir()));
199
- } else {
200
- console.log("Config storage path: " + magenta(getStorageDir()));
201
- console.log("Primary data storage: " + magenta(`backblaze:${getDomain()}`));
202
- }
1
+ import { isNode } from "socket-function/src/misc";
2
+ import { getDomain, isNoNetwork } from "../config";
3
+ import { getStorageDir, getSubFolder } from "../fs";
4
+ import { getArchivesBackblaze, hasBackblazePermissions } from "./archivesBackBlaze";
5
+ import { getArchivesLocal } from "./archivesDisk";
6
+ import { magenta } from "socket-function/src/formatting/logColors";
7
+ import debugbreak from "debugbreak";
8
+ import { isClient } from "../config2";
9
+ import { wrapArchivesWithCache } from "./archiveCache";
10
+ import { Args } from "socket-function/src/types";
11
+
12
+ export interface Archives {
13
+ getDebugName(): string;
14
+
15
+ get(path: string, config?: {
16
+ range?: { start: number; end: number; };
17
+ retryCount?: number;
18
+ // Skips checking if the file exists on the remote. Only appropriate when the file name is fresh (recently obtained from find).
19
+ fastRead?: boolean;
20
+ }): Promise<Buffer | undefined>;
21
+ set(path: string, data: Buffer): Promise<void>;
22
+ del(path: string): Promise<void>;
23
+
24
+ append(path: string, data: Buffer): Promise<void>;
25
+
26
+ getInfo(path: string): Promise<{ writeTime: number; size: number; } | undefined>;
27
+
28
+ setLargeFile(config: { path: string; getNextData(): Promise<Buffer | undefined>; }): Promise<void>;
29
+
30
+ // For example findFileNames("ips/")
31
+ /** Returns to full paths. Returns paths WILL NOT end with / */
32
+ find(
33
+ prefix: string,
34
+ config?: {
35
+ shallow?: boolean;
36
+ // Defaults to files
37
+ type: "files" | "folders";
38
+ }
39
+ ): Promise<string[]>;
40
+ findInfo(
41
+ prefix: string,
42
+ config?: {
43
+ shallow?: boolean;
44
+ // Defaults to files
45
+ type: "files" | "folders";
46
+ }
47
+ ): Promise<{ path: string; createTime: number; size: number; }[]>;
48
+
49
+ move(config: {
50
+ path: string;
51
+ target: Archives;
52
+ targetPath: string;
53
+ }): Promise<void>;
54
+ copy(config: {
55
+ path: string;
56
+ target: Archives;
57
+ targetPath: string;
58
+ }): Promise<void>;
59
+
60
+
61
+ enableLogging(): void;
62
+
63
+ /** Might throw due to too long of a length. Should never throw due to characters, as we can always encode special characters. */
64
+ assertPathValid(path: string): Promise<void>;
65
+
66
+ getBaseArchives?: () => { parentPath: string; archives: Archives; } | undefined;
67
+
68
+ /** Get a download URL for a file. Only implemented for some archive types (like Backblaze). */
69
+ getURL?: (path: string) => Promise<string>;
70
+
71
+ // NOTE: This isn't part of getURL, as it is much more efficient to call it once and reuse the authorization. This is only for backblaze as of right now.
72
+ // NOTE: This also gives authorization for ALL files, so... ONLY use it for internal download links. If we need external links, we should use a public folder with hash links, or... make a new endpoint.
73
+ getDownloadAuthorization?: (config: {
74
+ validDurationInSeconds: number;
75
+ }) => Promise<{
76
+ bucketId: string;
77
+ fileNamePrefix: string;
78
+ authorizationToken: string;
79
+ }>;
80
+ }
81
+
82
+ export function createArchivesOverride<T extends Partial<Archives>>(
83
+ baseArchives: Archives,
84
+ overrideArchives: T
85
+ ): T & Archives {
86
+ return {
87
+ getDebugName: () => baseArchives.getDebugName(),
88
+ get: (fileName: string, config) => baseArchives.get(fileName, config),
89
+ set: (fileName: string, data: Buffer) => baseArchives.set(fileName, data),
90
+ append: (fileName: string, data: Buffer) => baseArchives.append(fileName, data),
91
+ del: (fileName: string) => baseArchives.del(fileName),
92
+ getInfo: (fileName: string) => baseArchives.getInfo(fileName),
93
+ setLargeFile: (config) => baseArchives.setLargeFile(config),
94
+ find: async (prefix: string, config) => baseArchives.find(prefix, config),
95
+ findInfo: async (prefix: string, config) => baseArchives.findInfo(prefix, config),
96
+ enableLogging: () => baseArchives.enableLogging(),
97
+ move: (config) => baseArchives.move(config),
98
+ copy: (config) => baseArchives.copy(config),
99
+ assertPathValid: (path: string) => baseArchives.assertPathValid(path),
100
+ getBaseArchives: () => baseArchives.getBaseArchives?.() ?? ({ archives: baseArchives, parentPath: "" }),
101
+ getURL: baseArchives.getURL ? (filePath: string) => baseArchives.getURL!(filePath) : undefined,
102
+ getDownloadAuthorization: baseArchives.getDownloadAuthorization ? (config: { validDurationInSeconds: number }) => baseArchives.getDownloadAuthorization!(config) : undefined,
103
+ ...overrideArchives,
104
+ };
105
+ }
106
+
107
+ export function nestArchives(path: string, archives: Archives): Archives {
108
+ if (!path) return archives;
109
+ if (!path.endsWith("/")) {
110
+ path = path + "/";
111
+ }
112
+ function stripFilePrefix(file: string) {
113
+ if (file.startsWith("/")) {
114
+ return file.slice(1);
115
+ }
116
+ return file;
117
+ }
118
+ return {
119
+ getDebugName: () => archives.getDebugName() + "/" + path,
120
+ get: (fileName: string, config) => archives.get(path + stripFilePrefix(fileName), config),
121
+ setLargeFile: (config) => archives.setLargeFile({ ...config, path: path + stripFilePrefix(config.path) }),
122
+ set: (fileName: string, data: Buffer) => archives.set(path + stripFilePrefix(fileName), data),
123
+ append: (fileName: string, data: Buffer) => archives.append(path + stripFilePrefix(fileName), data),
124
+ del: (fileName: string) => archives.del(path + stripFilePrefix(fileName)),
125
+ getInfo: (fileName: string) => archives.getInfo(path + stripFilePrefix(fileName)),
126
+ find: async (prefix: string, config) => archives.find(path + prefix, config).then(x => x.map(x => x.slice(path.length))),
127
+ findInfo: async (prefix: string, config) => archives.findInfo(path + prefix, config).then(x => x.map(x => ({ path: x.path.slice(path.length), createTime: x.createTime, size: x.size }))),
128
+ enableLogging: () => archives.enableLogging(),
129
+ move: (config) => archives.move({
130
+ path: path + config.path,
131
+ target: config.target,
132
+ targetPath: config.targetPath,
133
+ }),
134
+ copy: (config) => archives.copy({
135
+ path: path + config.path,
136
+ target: config.target,
137
+ targetPath: config.targetPath,
138
+ }),
139
+ assertPathValid: (path: string) => archives.assertPathValid(path),
140
+ getBaseArchives: () => {
141
+ let result = { parentPath: path, archives };
142
+ let base = archives.getBaseArchives?.();
143
+ if (base) {
144
+ result.parentPath = base.parentPath + path;
145
+ result.archives = base.archives;
146
+ }
147
+ return result;
148
+ },
149
+ getURL: archives.getURL ? (filePath: string) => archives.getURL!(path + stripFilePrefix(filePath)) : undefined,
150
+ getDownloadAuthorization: archives.getDownloadAuthorization && ((...args: Args<typeof archives.getDownloadAuthorization>) => archives.getDownloadAuthorization!(...args)),
151
+ };
152
+ }
153
+
154
+ let archivesLogging = false;
155
+ export function enableArchivesLogging() {
156
+ archivesLogging = true;
157
+ }
158
+
159
+ let cached = new Map<string, Archives>();
160
+ export function getArchives(rootPath = ""): Archives {
161
+ let value = cached.get(rootPath);
162
+ if (!value) {
163
+ value = getArchivesBase(rootPath);
164
+ cached.set(rootPath, value);
165
+ }
166
+ return value;
167
+ }
168
+ export function getArchivesBase(rootPath = ""): Archives {
169
+ let archives: Archives;
170
+ let domain = getDomain();
171
+ if (isNoNetwork()) {
172
+ archives = getArchivesLocal(domain);
173
+ archives = nestArchives(rootPath, archives);
174
+ } else {
175
+ archives = getArchivesBackblaze(domain);
176
+ archives = nestArchives(rootPath, archives);
177
+ // Why did we think we should always cache? We absolutely should not. Even if we were checking
178
+ // file hashes on every read (which we do not), it would still potentially fill the cache up
179
+ // with large temporary files we have no intention of using (which might evict entries we
180
+ // intend to use).
181
+ //archives = wrapArchivesWithCache(archives);
182
+ }
183
+ if (archivesLogging) {
184
+ archives.enableLogging();
185
+ }
186
+ return archives;
187
+ }
188
+
189
+ export function hasArchivesPermissions() {
190
+ if (isNoNetwork()) {
191
+ return true;
192
+ }
193
+ return hasBackblazePermissions();
194
+ }
195
+
196
+ if (isNode()) {
197
+ if (isNoNetwork()) {
198
+ console.log("Primary data storage: " + magenta(getStorageDir()));
199
+ } else {
200
+ console.log("Config storage path: " + magenta(getStorageDir()));
201
+ console.log("Primary data storage: " + magenta(`backblaze:${getDomain()}`));
202
+ }
203
203
  }
@@ -13,6 +13,7 @@ import debugbreak from "debugbreak";
13
13
  import { onTimeProfile } from "../-0-hooks/hooks";
14
14
  import dns from "dns";
15
15
 
16
+
16
17
  export function hasBackblazePermissions() {
17
18
  return isNode() && fs.existsSync(getBackblazePath());
18
19
  }