querysub 0.433.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 -516
  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
package/src/path.ts CHANGED
@@ -1,256 +1,256 @@
1
- /**
2
- * Overview
3
- * We escape path segments so we can quickly create a str representing
4
- * that path. We do this by escaping some special character and then using a that
5
- * character to indicate special values.
6
- * - This appears to be faster than JSON.stringify
7
- * - A random benchmark showed 140ns per, compared to 260ns for a JSON.stringify call
8
- * - ALSO, using "appendToPathStr(rootPathStr, str)" instead of getPathStr([str]) is even
9
- * faster, about 70ns per.
10
- * - This lets us extend existing stres without recreating the entire str,
11
- * which is significantly faster than JSON.stringify.
12
- * - ALSO, escapes "." and "$", letting us use this to escape keys for mongodb usage.
13
- */
14
-
15
- // TODO: Change our escaping so we can turn paths into valid mongodb key names see:
16
- // https://stackoverflow.com/questions/7975185/mongodb-query-over-a-str-with-special-chars-in-keys/7976235#7976235
17
-
18
- const specialChar = ".";
19
-
20
- // The character after this character is special, forming a 2 character sequence.
21
- export const PATH_SPECIAL_CHAR = specialChar;
22
-
23
- const pathDelimitChar = ",";
24
- const specialCharEscape = specialChar + "_";
25
-
26
-
27
- // NOTE: Our paths end up looking something like: pathDelimitEscaped + arr[0] + pathDelimitEscaped + arr[1] + pathDelimitEscaped,
28
- // with the delimitter at both ends and between all elements (and with everything escaped properly).
29
-
30
- const pathDelimitEscaped = specialChar + pathDelimitChar;
31
-
32
- const afterChildSuffix = specialChar + String.fromCharCode(pathDelimitChar.charCodeAt(0) + 1);
33
-
34
- export const rootPathStr = getPathStr([]);
35
-
36
- function regexEscape(text: string) {
37
- text = text.replace(/\./g, "\\.");
38
- text = text.replace(/\$/g, "\\$");
39
- return text;
40
- }
41
-
42
- let regexSpecialChar = new RegExp(regexEscape(specialChar), "g");
43
- let regexUnescapeSpecialChar = new RegExp(regexEscape(specialCharEscape), "g");
44
-
45
- export function escapePathPart(part: string | number | boolean | undefined | null) {
46
- if (typeof part !== "string") return part;
47
- if (isValidPathStr(part)) {
48
- if (part.indexOf(specialChar) < 0) {
49
- return part;
50
- }
51
- }
52
- return part.replace(regexSpecialChar, specialCharEscape);
53
- }
54
- function unescapePathPart(part: string) {
55
- part = part.replace(regexUnescapeSpecialChar, specialChar);
56
- return part;
57
- }
58
-
59
-
60
-
61
- export function getPathStr(path: (string | number | boolean | undefined | null)[]) {
62
- return pathDelimitEscaped + path.map(x => escapePathPart(x) + pathDelimitEscaped).join("");
63
- }
64
- /** Equivalent to getPathStr([path0]), except a bit faster */
65
- export function getPathStr1(path0: string) {
66
- return appendToPathStr(rootPathStr, path0);
67
- }
68
- /** Equivalent to getPathStr([path0, path1]), except a bit faster */
69
- export function getPathStr2(path0: string, path1: string) {
70
- // TODO: Benchmark this again. If I recall correctly, if we are ONLY string paths, this is about
71
- // twice as fast as getPathStr([path0, path1])? This is because allocating arrays is slow.
72
- return appendToPathStr(appendToPathStr(rootPathStr, path0), path1);
73
- }
74
- /** Equivalent to getPathStr([path0, path1, path2]), except a bit faster */
75
- export function getPathStr3(path0: string, path1: string, path2: string) {
76
- return appendToPathStr(appendToPathStr(appendToPathStr(rootPathStr, path0), path1), path2);
77
- }
78
- export function getPathStr4(path0: string, path1: string, path2: string, path3: string) {
79
- let value = rootPathStr;
80
- value = appendToPathStr(value, path0);
81
- value = appendToPathStr(value, path1);
82
- value = appendToPathStr(value, path2);
83
- value = appendToPathStr(value, path3);
84
- return value;
85
- }
86
-
87
- export function appendToPathStr(pathStr: string, pathPart: string) {
88
- if (pathStr[pathStr.length - 1] !== pathDelimitChar) {
89
- // Might be a hacked path
90
- pathStr = hack_stripPackedPath(pathStr);
91
- }
92
- return pathStr + escapePathPart(pathPart) + pathDelimitEscaped;
93
- }
94
- export function prependToPathStr(pathStr: string, pathPart: string) {
95
- return pathDelimitEscaped + escapePathPart(pathPart) + pathStr;
96
- }
97
-
98
- export function pathStrIncludesValue(pathStr: string, value: string) {
99
- value = String(escapePathPart(value));
100
- return pathStr.includes(value);
101
- }
102
-
103
- export function joinPathStres(lhsStr: string, rhsStr: string) {
104
- return lhsStr + rhsStr.slice(rootPathStr.length);
105
- }
106
-
107
- export function getPathIndexAssert(pathStr: string, index: number): string {
108
- let value = getPathIndex(pathStr, index);
109
- if (value === undefined) {
110
- throw new Error(`Path index ${index} was undefined in pathStr ${pathStr}`);
111
- }
112
- return value;
113
- }
114
- export function getPathIndex(pathStr: string, index: number) {
115
- let parts = pathStr.split(pathDelimitEscaped);
116
- if (parts.length - 2 <= index) {
117
- return undefined;
118
- }
119
- if (index < 0) {
120
- index = parts.length - 2 + index;
121
- }
122
- let part = parts[index + 1];
123
- if (part === undefined) {
124
- return undefined;
125
- }
126
- return unescapePathPart(part);
127
- }
128
- export function getPathFromStr(pathStr: string) {
129
- return pathStr.split(pathDelimitEscaped).slice(1, -1).map(x => unescapePathPart(x));
130
- }
131
-
132
- export function isValidPathStr(pathStr: string) {
133
- return pathStr.startsWith(pathDelimitEscaped) && pathStr.endsWith(pathDelimitEscaped);
134
- }
135
-
136
- /** Gets the path after all children of the pathStr, BUT, before the next sibling (when sorting lexicographically by path str). */
137
- export function getPathAfterLastChild(pathStr: string) {
138
- if (pathStr === "") {
139
- return afterChildSuffix;
140
- }
141
- // NOTE: assertArg isn't used, to reduce the readLocks of path.ts, which is used itself by assertArg.
142
- if (!pathStr.endsWith(pathDelimitEscaped)) {
143
- throw new Error(`pathStr must end with ${JSON.stringify(pathDelimitEscaped)}, was ${JSON.stringify(pathStr)}`);
144
- }
145
- // Any sibling before us, will lexicographically be < us BEFORE the last character, the same as any sibling after us.
146
- // However, children't will match all the way to our suffix, and then be < our modified suffix.
147
- return pathStr.slice(0, -pathDelimitEscaped.length) + afterChildSuffix;
148
- }
149
-
150
- function getStartOfLastPart(pathStr: string) {
151
- // I'm not sure if this is what we should be doing for hacked paths. In theory, a hacked path basically represents select these children, selecting specific children. So, in theory, that should mean... The parent is the parent of those children. However, we also use it to keep track of the parent sync, in which case we are syncing the parent. And so the parent we want, if we ever recall this, would be actually the parent of that. So I think in theory we should uncomment this code, but in practice we need to keep it commented.
152
- // if(hack_isPackedPath(pathStr)) {
153
- // let index = pathStr.lastIndexOf(pathDelimitEscaped);
154
- // if(index < 0) return pathStr.length;
155
- // return index + pathDelimitEscaped.length;
156
- // }
157
- let index = pathStr.lastIndexOf(pathDelimitEscaped);
158
- if (index < 0) return pathStr.length;
159
- let index2 = pathStr.lastIndexOf(pathDelimitEscaped, index - 1);
160
- if (index2 < 0) return 0;
161
- return index2 + pathDelimitEscaped.length;
162
- }
163
-
164
- /** === getPathStr(getPathFromStr(pathStr).slice(0, -1)), getParentPathStr(rootPathStr) === rootPathStr */
165
- export function getParentPathStr(pathStr: string) {
166
- // Allow empty string? Better than throwing on it, I guess
167
- if (pathStr === "") {
168
- return "";
169
- }
170
- // an additional check.
171
- return pathStr.slice(0, getStartOfLastPart(pathStr));
172
- }
173
-
174
- /** === getPathFromStr(pathStr).slice(-1)[0] || "" */
175
- export function getLastPathPart(pathStr: string) {
176
- let lastPartIndex = pathStr.lastIndexOf(pathDelimitEscaped);
177
- if (lastPartIndex < 0) return "";
178
- return unescapePathPart(
179
- pathStr.slice(
180
- getStartOfLastPart(pathStr),
181
- lastPartIndex,
182
- )
183
- );
184
- }
185
-
186
- /** === getPathStr(getPathFromStr(pathStr).slice(0, -1)) */
187
- export function removePathLastPart(pathStr: string) {
188
- return pathStr.slice(0, getStartOfLastPart(pathStr));
189
- }
190
-
191
- let lastPastPath = { path: "", depth: 0 };
192
- /** getPathDepth(pathStr) === getPathFromStr(pathStr).length */
193
- export function getPathDepth(pathStr: string): number {
194
- if (lastPastPath.path === pathStr) {
195
- return lastPastPath.depth;
196
- }
197
- // Start at 1, to skip the first pathDelimit
198
- let index = 1;
199
- // Start at -1, as the last loop doesn't have pathDelimitEscaped, but is still incremented
200
- let count = -1;
201
- while (index > 0) {
202
- count++;
203
- index = pathStr.indexOf(pathDelimitEscaped, index) + 1;
204
- }
205
- lastPastPath.path = pathStr;
206
- lastPastPath.depth = count;
207
- return count;
208
- }
209
-
210
- export const getPathPrefix = trimPathStrToDepth;
211
- export function trimPathStrToDepth(pathStr: string, depth: number): string {
212
- let index = 0;
213
- let count = 0;
214
- while (count < depth) {
215
- let nextIndex = pathStr.indexOf(pathDelimitEscaped, index + 1);
216
- if (nextIndex < 0) break;
217
- count++;
218
- index = nextIndex;
219
- }
220
- return pathStr.slice(0, index + pathDelimitEscaped.length);
221
- }
222
- export const slicePathStrToDepth = trimPathStrToDepth;
223
- export function getPathSuffix(pathStr: string, depth: number): string {
224
- let index = 0;
225
- let count = 0;
226
- while (count < depth) {
227
- let nextIndex = pathStr.indexOf(pathDelimitEscaped, index + 1);
228
- if (nextIndex < 0) break;
229
- count++;
230
- index = nextIndex;
231
- }
232
- return pathStr.slice(index);
233
- }
234
-
235
- /** A hack, which breaks some path functions, but... which works with enough to save a
236
- * lot of code and time when we need a bit more information that shouldn't count as
237
- * path information. */
238
- export function hack_setPackedPathSuffix(path: string, suffix: string): string {
239
- return path + suffix;
240
- }
241
- export function hack_isPackedPath(path: string) {
242
- return !path.endsWith(pathDelimitEscaped);
243
- }
244
- export function hack_getPackedPathSuffix(path: string): string {
245
- if (!hack_isPackedPath(path)) {
246
- return "";
247
- }
248
- return getPathSuffix(path, getPathDepth(path)).slice(pathDelimitEscaped.length);
249
- }
250
- export function hack_stripPackedPath(path: string): string {
251
- if (!hack_isPackedPath(path)) {
252
- return path;
253
- }
254
- let suffix = hack_getPackedPathSuffix(path);
255
- return path.slice(0, -suffix.length);
1
+ /**
2
+ * Overview
3
+ * We escape path segments so we can quickly create a str representing
4
+ * that path. We do this by escaping some special character and then using a that
5
+ * character to indicate special values.
6
+ * - This appears to be faster than JSON.stringify
7
+ * - A random benchmark showed 140ns per, compared to 260ns for a JSON.stringify call
8
+ * - ALSO, using "appendToPathStr(rootPathStr, str)" instead of getPathStr([str]) is even
9
+ * faster, about 70ns per.
10
+ * - This lets us extend existing stres without recreating the entire str,
11
+ * which is significantly faster than JSON.stringify.
12
+ * - ALSO, escapes "." and "$", letting us use this to escape keys for mongodb usage.
13
+ */
14
+
15
+ // TODO: Change our escaping so we can turn paths into valid mongodb key names see:
16
+ // https://stackoverflow.com/questions/7975185/mongodb-query-over-a-str-with-special-chars-in-keys/7976235#7976235
17
+
18
+ const specialChar = ".";
19
+
20
+ // The character after this character is special, forming a 2 character sequence.
21
+ export const PATH_SPECIAL_CHAR = specialChar;
22
+
23
+ const pathDelimitChar = ",";
24
+ const specialCharEscape = specialChar + "_";
25
+
26
+
27
+ // NOTE: Our paths end up looking something like: pathDelimitEscaped + arr[0] + pathDelimitEscaped + arr[1] + pathDelimitEscaped,
28
+ // with the delimitter at both ends and between all elements (and with everything escaped properly).
29
+
30
+ const pathDelimitEscaped = specialChar + pathDelimitChar;
31
+
32
+ const afterChildSuffix = specialChar + String.fromCharCode(pathDelimitChar.charCodeAt(0) + 1);
33
+
34
+ export const rootPathStr = getPathStr([]);
35
+
36
+ function regexEscape(text: string) {
37
+ text = text.replace(/\./g, "\\.");
38
+ text = text.replace(/\$/g, "\\$");
39
+ return text;
40
+ }
41
+
42
+ let regexSpecialChar = new RegExp(regexEscape(specialChar), "g");
43
+ let regexUnescapeSpecialChar = new RegExp(regexEscape(specialCharEscape), "g");
44
+
45
+ export function escapePathPart(part: string | number | boolean | undefined | null) {
46
+ if (typeof part !== "string") return part;
47
+ if (isValidPathStr(part)) {
48
+ if (part.indexOf(specialChar) < 0) {
49
+ return part;
50
+ }
51
+ }
52
+ return part.replace(regexSpecialChar, specialCharEscape);
53
+ }
54
+ function unescapePathPart(part: string) {
55
+ part = part.replace(regexUnescapeSpecialChar, specialChar);
56
+ return part;
57
+ }
58
+
59
+
60
+
61
+ export function getPathStr(path: (string | number | boolean | undefined | null)[]) {
62
+ return pathDelimitEscaped + path.map(x => escapePathPart(x) + pathDelimitEscaped).join("");
63
+ }
64
+ /** Equivalent to getPathStr([path0]), except a bit faster */
65
+ export function getPathStr1(path0: string) {
66
+ return appendToPathStr(rootPathStr, path0);
67
+ }
68
+ /** Equivalent to getPathStr([path0, path1]), except a bit faster */
69
+ export function getPathStr2(path0: string, path1: string) {
70
+ // TODO: Benchmark this again. If I recall correctly, if we are ONLY string paths, this is about
71
+ // twice as fast as getPathStr([path0, path1])? This is because allocating arrays is slow.
72
+ return appendToPathStr(appendToPathStr(rootPathStr, path0), path1);
73
+ }
74
+ /** Equivalent to getPathStr([path0, path1, path2]), except a bit faster */
75
+ export function getPathStr3(path0: string, path1: string, path2: string) {
76
+ return appendToPathStr(appendToPathStr(appendToPathStr(rootPathStr, path0), path1), path2);
77
+ }
78
+ export function getPathStr4(path0: string, path1: string, path2: string, path3: string) {
79
+ let value = rootPathStr;
80
+ value = appendToPathStr(value, path0);
81
+ value = appendToPathStr(value, path1);
82
+ value = appendToPathStr(value, path2);
83
+ value = appendToPathStr(value, path3);
84
+ return value;
85
+ }
86
+
87
+ export function appendToPathStr(pathStr: string, pathPart: string) {
88
+ if (pathStr[pathStr.length - 1] !== pathDelimitChar) {
89
+ // Might be a hacked path
90
+ pathStr = hack_stripPackedPath(pathStr);
91
+ }
92
+ return pathStr + escapePathPart(pathPart) + pathDelimitEscaped;
93
+ }
94
+ export function prependToPathStr(pathStr: string, pathPart: string) {
95
+ return pathDelimitEscaped + escapePathPart(pathPart) + pathStr;
96
+ }
97
+
98
+ export function pathStrIncludesValue(pathStr: string, value: string) {
99
+ value = String(escapePathPart(value));
100
+ return pathStr.includes(value);
101
+ }
102
+
103
+ export function joinPathStres(lhsStr: string, rhsStr: string) {
104
+ return lhsStr + rhsStr.slice(rootPathStr.length);
105
+ }
106
+
107
+ export function getPathIndexAssert(pathStr: string, index: number): string {
108
+ let value = getPathIndex(pathStr, index);
109
+ if (value === undefined) {
110
+ throw new Error(`Path index ${index} was undefined in pathStr ${pathStr}`);
111
+ }
112
+ return value;
113
+ }
114
+ export function getPathIndex(pathStr: string, index: number) {
115
+ let parts = pathStr.split(pathDelimitEscaped);
116
+ if (parts.length - 2 <= index) {
117
+ return undefined;
118
+ }
119
+ if (index < 0) {
120
+ index = parts.length - 2 + index;
121
+ }
122
+ let part = parts[index + 1];
123
+ if (part === undefined) {
124
+ return undefined;
125
+ }
126
+ return unescapePathPart(part);
127
+ }
128
+ export function getPathFromStr(pathStr: string) {
129
+ return pathStr.split(pathDelimitEscaped).slice(1, -1).map(x => unescapePathPart(x));
130
+ }
131
+
132
+ export function isValidPathStr(pathStr: string) {
133
+ return pathStr.startsWith(pathDelimitEscaped) && pathStr.endsWith(pathDelimitEscaped);
134
+ }
135
+
136
+ /** Gets the path after all children of the pathStr, BUT, before the next sibling (when sorting lexicographically by path str). */
137
+ export function getPathAfterLastChild(pathStr: string) {
138
+ if (pathStr === "") {
139
+ return afterChildSuffix;
140
+ }
141
+ // NOTE: assertArg isn't used, to reduce the readLocks of path.ts, which is used itself by assertArg.
142
+ if (!pathStr.endsWith(pathDelimitEscaped)) {
143
+ throw new Error(`pathStr must end with ${JSON.stringify(pathDelimitEscaped)}, was ${JSON.stringify(pathStr)}`);
144
+ }
145
+ // Any sibling before us, will lexicographically be < us BEFORE the last character, the same as any sibling after us.
146
+ // However, children't will match all the way to our suffix, and then be < our modified suffix.
147
+ return pathStr.slice(0, -pathDelimitEscaped.length) + afterChildSuffix;
148
+ }
149
+
150
+ function getStartOfLastPart(pathStr: string) {
151
+ // I'm not sure if this is what we should be doing for hacked paths. In theory, a hacked path basically represents select these children, selecting specific children. So, in theory, that should mean... The parent is the parent of those children. However, we also use it to keep track of the parent sync, in which case we are syncing the parent. And so the parent we want, if we ever recall this, would be actually the parent of that. So I think in theory we should uncomment this code, but in practice we need to keep it commented.
152
+ // if(hack_isPackedPath(pathStr)) {
153
+ // let index = pathStr.lastIndexOf(pathDelimitEscaped);
154
+ // if(index < 0) return pathStr.length;
155
+ // return index + pathDelimitEscaped.length;
156
+ // }
157
+ let index = pathStr.lastIndexOf(pathDelimitEscaped);
158
+ if (index < 0) return pathStr.length;
159
+ let index2 = pathStr.lastIndexOf(pathDelimitEscaped, index - 1);
160
+ if (index2 < 0) return 0;
161
+ return index2 + pathDelimitEscaped.length;
162
+ }
163
+
164
+ /** === getPathStr(getPathFromStr(pathStr).slice(0, -1)), getParentPathStr(rootPathStr) === rootPathStr */
165
+ export function getParentPathStr(pathStr: string) {
166
+ // Allow empty string? Better than throwing on it, I guess
167
+ if (pathStr === "") {
168
+ return "";
169
+ }
170
+ // an additional check.
171
+ return pathStr.slice(0, getStartOfLastPart(pathStr));
172
+ }
173
+
174
+ /** === getPathFromStr(pathStr).slice(-1)[0] || "" */
175
+ export function getLastPathPart(pathStr: string) {
176
+ let lastPartIndex = pathStr.lastIndexOf(pathDelimitEscaped);
177
+ if (lastPartIndex < 0) return "";
178
+ return unescapePathPart(
179
+ pathStr.slice(
180
+ getStartOfLastPart(pathStr),
181
+ lastPartIndex,
182
+ )
183
+ );
184
+ }
185
+
186
+ /** === getPathStr(getPathFromStr(pathStr).slice(0, -1)) */
187
+ export function removePathLastPart(pathStr: string) {
188
+ return pathStr.slice(0, getStartOfLastPart(pathStr));
189
+ }
190
+
191
+ let lastPastPath = { path: "", depth: 0 };
192
+ /** getPathDepth(pathStr) === getPathFromStr(pathStr).length */
193
+ export function getPathDepth(pathStr: string): number {
194
+ if (lastPastPath.path === pathStr) {
195
+ return lastPastPath.depth;
196
+ }
197
+ // Start at 1, to skip the first pathDelimit
198
+ let index = 1;
199
+ // Start at -1, as the last loop doesn't have pathDelimitEscaped, but is still incremented
200
+ let count = -1;
201
+ while (index > 0) {
202
+ count++;
203
+ index = pathStr.indexOf(pathDelimitEscaped, index) + 1;
204
+ }
205
+ lastPastPath.path = pathStr;
206
+ lastPastPath.depth = count;
207
+ return count;
208
+ }
209
+
210
+ export const getPathPrefix = trimPathStrToDepth;
211
+ export function trimPathStrToDepth(pathStr: string, depth: number): string {
212
+ let index = 0;
213
+ let count = 0;
214
+ while (count < depth) {
215
+ let nextIndex = pathStr.indexOf(pathDelimitEscaped, index + 1);
216
+ if (nextIndex < 0) break;
217
+ count++;
218
+ index = nextIndex;
219
+ }
220
+ return pathStr.slice(0, index + pathDelimitEscaped.length);
221
+ }
222
+ export const slicePathStrToDepth = trimPathStrToDepth;
223
+ export function getPathSuffix(pathStr: string, depth: number): string {
224
+ let index = 0;
225
+ let count = 0;
226
+ while (count < depth) {
227
+ let nextIndex = pathStr.indexOf(pathDelimitEscaped, index + 1);
228
+ if (nextIndex < 0) break;
229
+ count++;
230
+ index = nextIndex;
231
+ }
232
+ return pathStr.slice(index);
233
+ }
234
+
235
+ /** A hack, which breaks some path functions, but... which works with enough to save a
236
+ * lot of code and time when we need a bit more information that shouldn't count as
237
+ * path information. */
238
+ export function hack_setPackedPathSuffix(path: string, suffix: string): string {
239
+ return path + suffix;
240
+ }
241
+ export function hack_isPackedPath(path: string) {
242
+ return !path.endsWith(pathDelimitEscaped);
243
+ }
244
+ export function hack_getPackedPathSuffix(path: string): string {
245
+ if (!hack_isPackedPath(path)) {
246
+ return "";
247
+ }
248
+ return getPathSuffix(path, getPathDepth(path)).slice(pathDelimitEscaped.length);
249
+ }
250
+ export function hack_stripPackedPath(path: string): string {
251
+ if (!hack_isPackedPath(path)) {
252
+ return path;
253
+ }
254
+ let suffix = hack_getPackedPathSuffix(path);
255
+ return path.slice(0, -suffix.length);
256
256
  }
@@ -1,42 +1,42 @@
1
- module.allowclient = true;
2
-
3
- import { isNode } from "socket-function/src/misc";
4
- import fs from "fs";
5
- import { getStorageDir, getSubFolder } from "./fs";
6
- import { isClient } from "./config2";
7
- import { getDomain } from "./config";
8
- import os from "os";
9
-
10
- export function createKeyStore<T>(key: string): {
11
- value: T | null;
12
- } {
13
- if (isNode()) {
14
- let keyStoreDir = os.homedir() + "/querysub/";
15
- if (!fs.existsSync(keyStoreDir)) {
16
- fs.mkdirSync(keyStoreDir);
17
- }
18
- let path = keyStoreDir + key + ".json";
19
- return {
20
- get value() {
21
- let contents: string | undefined = undefined;
22
- try { contents = fs.readFileSync(path, "utf8"); } catch { }
23
- if (!contents) return null;
24
- return JSON.parse(contents) as T;
25
- },
26
- set value(value: T | null) {
27
- fs.writeFileSync(path, JSON.stringify(value));
28
- }
29
- };
30
- } else {
31
- return {
32
- get value() {
33
- let json = localStorage.getItem(key);
34
- if (!json) return null;
35
- return JSON.parse(json) as T;
36
- },
37
- set value(value: T | null) {
38
- localStorage.setItem(key, JSON.stringify(value));
39
- }
40
- };
41
- }
1
+ module.allowclient = true;
2
+
3
+ import { isNode } from "socket-function/src/misc";
4
+ import fs from "fs";
5
+ import { getStorageDir, getSubFolder } from "./fs";
6
+ import { isClient } from "./config2";
7
+ import { getDomain } from "./config";
8
+ import os from "os";
9
+
10
+ export function createKeyStore<T>(key: string): {
11
+ value: T | null;
12
+ } {
13
+ if (isNode()) {
14
+ let keyStoreDir = os.homedir() + "/querysub/";
15
+ if (!fs.existsSync(keyStoreDir)) {
16
+ fs.mkdirSync(keyStoreDir);
17
+ }
18
+ let path = keyStoreDir + key + ".json";
19
+ return {
20
+ get value() {
21
+ let contents: string | undefined = undefined;
22
+ try { contents = fs.readFileSync(path, "utf8"); } catch { }
23
+ if (!contents) return null;
24
+ return JSON.parse(contents) as T;
25
+ },
26
+ set value(value: T | null) {
27
+ fs.writeFileSync(path, JSON.stringify(value));
28
+ }
29
+ };
30
+ } else {
31
+ return {
32
+ get value() {
33
+ let json = localStorage.getItem(key);
34
+ if (!json) return null;
35
+ return JSON.parse(json) as T;
36
+ },
37
+ set value(value: T | null) {
38
+ localStorage.setItem(key, JSON.stringify(value));
39
+ }
40
+ };
41
+ }
42
42
  }
package/src/promise.ts CHANGED
@@ -1,15 +1,15 @@
1
- export class PromiseObj<T = void> {
2
- public promise: Promise<T>;
3
- public resolve!: (value: T | PromiseLike<T>) => void;
4
- public reject!: (reason?: any) => void;
5
- public resolved = false;
6
- public rejected = false;
7
- constructor() {
8
- this.promise = new Promise<T>((resolve, reject) => {
9
- this.resolve = resolve;
10
- this.reject = reject;
11
- });
12
- void this.promise.finally(() => this.resolved = true);
13
- this.promise.catch(() => this.rejected = true);
14
- }
1
+ export class PromiseObj<T = void> {
2
+ public promise: Promise<T>;
3
+ public resolve!: (value: T | PromiseLike<T>) => void;
4
+ public reject!: (reason?: any) => void;
5
+ public resolved = false;
6
+ public rejected = false;
7
+ constructor() {
8
+ this.promise = new Promise<T>((resolve, reject) => {
9
+ this.resolve = resolve;
10
+ this.reject = reject;
11
+ });
12
+ void this.promise.finally(() => this.resolved = true);
13
+ this.promise.catch(() => this.rejected = true);
14
+ }
15
15
  }