querysub 0.406.0 → 0.408.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/bin/audit-disk-values.js +7 -0
- package/bin/deploy-prefixes.js +7 -0
- package/package.json +5 -3
- package/src/-a-archives/archiveCache.ts +12 -9
- package/src/-a-auth/certs.ts +1 -1
- package/src/-c-identity/IdentityController.ts +9 -1
- package/src/-f-node-discovery/NodeDiscovery.ts +63 -10
- package/src/0-path-value-core/AuthorityLookup.ts +14 -4
- package/src/0-path-value-core/PathRouter.ts +247 -117
- package/src/0-path-value-core/PathRouterRouteOverride.ts +1 -1
- package/src/0-path-value-core/PathRouterServerAuthoritySpec.tsx +4 -2
- package/src/0-path-value-core/PathValueCommitter.ts +68 -31
- package/src/0-path-value-core/PathValueController.ts +77 -8
- package/src/0-path-value-core/PathWatcher.ts +46 -4
- package/src/0-path-value-core/ShardPrefixes.ts +6 -0
- package/src/0-path-value-core/ValidStateComputer.ts +20 -8
- package/src/0-path-value-core/hackedPackedPathParentFiltering.ts +18 -55
- package/src/0-path-value-core/pathValueArchives.ts +19 -8
- package/src/0-path-value-core/pathValueCore.ts +75 -27
- package/src/0-path-value-core/startupAuthority.ts +9 -9
- package/src/1-path-client/RemoteWatcher.ts +217 -178
- package/src/1-path-client/pathValueClientWatcher.ts +6 -11
- package/src/2-proxy/pathValueProxy.ts +2 -3
- package/src/3-path-functions/PathFunctionRunner.ts +3 -1
- package/src/3-path-functions/syncSchema.ts +6 -2
- package/src/4-deploy/deployGetFunctionsInner.ts +1 -1
- package/src/4-deploy/deployPrefixes.ts +14 -0
- package/src/4-deploy/edgeNodes.ts +1 -1
- package/src/4-querysub/Querysub.ts +17 -5
- package/src/4-querysub/QuerysubController.ts +21 -10
- package/src/4-querysub/predictionQueue.tsx +3 -0
- package/src/4-querysub/querysubPrediction.ts +27 -20
- package/src/5-diagnostics/nodeMetadata.ts +17 -0
- package/src/diagnostics/NodeConnectionsPage.tsx +167 -0
- package/src/diagnostics/NodeViewer.tsx +11 -15
- package/src/diagnostics/PathDistributionInfo.tsx +102 -0
- package/src/diagnostics/SyncTestPage.tsx +19 -8
- package/src/diagnostics/auditDiskValues.ts +221 -0
- package/src/diagnostics/auditDiskValuesEntry.ts +43 -0
- package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +5 -1
- package/src/diagnostics/logs/TimeRangeSelector.tsx +3 -3
- package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleRenderer.tsx +2 -0
- package/src/diagnostics/managementPages.tsx +10 -1
- package/src/diagnostics/misc-pages/ArchiveViewer.tsx +3 -2
- package/src/diagnostics/pathAuditer.ts +21 -0
- package/src/path.ts +9 -2
- package/src/rangeMath.ts +41 -0
- package/tempnotes.txt +5 -58
- package/test.ts +13 -295
- package/src/diagnostics/benchmark.ts +0 -139
- package/src/diagnostics/runSaturationTest.ts +0 -416
- package/src/diagnostics/satSchema.ts +0 -64
- package/src/test/mongoSatTest.tsx +0 -55
- package/src/test/satTest.ts +0 -193
- package/src/test/test.tsx +0 -552
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "querysub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.408.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"bin": {
|
|
25
25
|
"deploy": "./bin/deploy.js",
|
|
26
|
+
"deploy-prefixes": "./bin/deploy-prefixes.js",
|
|
26
27
|
"server": "./bin/server.js",
|
|
27
28
|
"server-public": "./bin/server-public.js",
|
|
28
29
|
"function": "./bin/function.js",
|
|
@@ -39,7 +40,8 @@
|
|
|
39
40
|
"addsuperuser": "./bin/addsuperuser.js",
|
|
40
41
|
"error-watch": "./bin/error-watch.js",
|
|
41
42
|
"error-watch-public": "./bin/error-watch-public.js",
|
|
42
|
-
"audit-imports": "./bin/audit-imports.js"
|
|
43
|
+
"audit-imports": "./bin/audit-imports.js",
|
|
44
|
+
"audit-disk-values": "./bin/audit-disk-values.js"
|
|
43
45
|
},
|
|
44
46
|
"dependencies": {
|
|
45
47
|
"@types/fs-ext": "^2.0.3",
|
|
@@ -60,7 +62,7 @@
|
|
|
60
62
|
"pako": "^2.1.0",
|
|
61
63
|
"peggy": "^5.0.6",
|
|
62
64
|
"querysub": "^0.357.0",
|
|
63
|
-
"socket-function": "^1.1.
|
|
65
|
+
"socket-function": "^1.1.18",
|
|
64
66
|
"terser": "^5.31.0",
|
|
65
67
|
"typesafecss": "^0.28.0",
|
|
66
68
|
"yaml": "^2.5.0",
|
|
@@ -82,15 +82,18 @@ const getDiskMetricsBase = async () => {
|
|
|
82
82
|
usedCacheBytes += info.size;
|
|
83
83
|
usedCacheFiles++;
|
|
84
84
|
} else {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
try {
|
|
86
|
+
// TEMP files, and... any files?
|
|
87
|
+
// If it's too old, delete it
|
|
88
|
+
let stat = await fs.promises.stat(cacheArchives2 + file);
|
|
89
|
+
let threshold = Date.now() - TEMP_THRESHOLD;
|
|
90
|
+
if (stat.mtimeMs < threshold) {
|
|
91
|
+
try {
|
|
92
|
+
await fs.promises.unlink(cacheArchives2 + file);
|
|
93
|
+
} catch { }
|
|
94
|
+
}
|
|
95
|
+
// If we can't stat it, someone else deleted it, so that's fine...
|
|
96
|
+
} catch { }
|
|
94
97
|
}
|
|
95
98
|
}
|
|
96
99
|
let processFileParallel = runInParallel({ parallelCount: 32 }, processFile);
|
package/src/-a-auth/certs.ts
CHANGED
|
@@ -480,7 +480,7 @@ export function decodeNodeId(nodeId: string, allowMissingThreadId?: "allowMissin
|
|
|
480
480
|
export function decodeNodeIdAssert(nodeId: string, allowMissingThreadId?: "allowMissingThreadId"): NodeIdParts {
|
|
481
481
|
let result = decodeNodeId(nodeId, allowMissingThreadId);
|
|
482
482
|
if (!result) {
|
|
483
|
-
throw new Error(`Invalid nodeId: ${nodeId}`);
|
|
483
|
+
throw new Error(`Invalid nodeId: ${JSON.stringify(nodeId)}`);
|
|
484
484
|
}
|
|
485
485
|
return result;
|
|
486
486
|
}
|
|
@@ -18,7 +18,7 @@ import { formatTime } from "socket-function/src/formatting/format";
|
|
|
18
18
|
import { waitForFirstTimeSync } from "socket-function/time/trueTimeShim";
|
|
19
19
|
import { red } from "socket-function/src/formatting/logColors";
|
|
20
20
|
import { isNode } from "typesafecss";
|
|
21
|
-
import { areNodeIdsEqual, getOwnThreadId } from "../-f-node-discovery/NodeDiscovery";
|
|
21
|
+
import { areNodeIdsEqual, getOwnNodeId, getOwnThreadId } from "../-f-node-discovery/NodeDiscovery";
|
|
22
22
|
|
|
23
23
|
let callerInfo = new Map<CallerContext, {
|
|
24
24
|
reconnectNodeId: string | undefined;
|
|
@@ -109,6 +109,7 @@ export const IdentityController_getOwnPubKeyShort = lazy((): number => {
|
|
|
109
109
|
return getShortNumber(pubKey);
|
|
110
110
|
});
|
|
111
111
|
|
|
112
|
+
|
|
112
113
|
export interface ChangeIdentityPayload {
|
|
113
114
|
time: number;
|
|
114
115
|
cert: string;
|
|
@@ -116,6 +117,7 @@ export interface ChangeIdentityPayload {
|
|
|
116
117
|
serverId: string;
|
|
117
118
|
mountedPort: number | undefined;
|
|
118
119
|
debugEntryPoint: string | undefined;
|
|
120
|
+
clientIsNode: boolean;
|
|
119
121
|
}
|
|
120
122
|
class IdentityControllerBase {
|
|
121
123
|
// IMPORTANT! We HAVE to call changeIdentity NOT JUST because we can't use peer certificates in the browser, BUT, also
|
|
@@ -133,6 +135,11 @@ class IdentityControllerBase {
|
|
|
133
135
|
throw new Error(`Signed payload too old, ${payload.time} < ${signedThreshold} from ${caller.localNodeId} (${caller.nodeId})`);
|
|
134
136
|
}
|
|
135
137
|
|
|
138
|
+
if (payload.clientIsNode && payload.serverId !== getOwnNodeId()) {
|
|
139
|
+
// This is extremely common when we reuse ports, which we do frequently for the edge nodes.
|
|
140
|
+
throw new Error(`You tried to contact another server. We are ${getOwnNodeId()}, you tried to contact ${payload.serverId}.`);
|
|
141
|
+
}
|
|
142
|
+
|
|
136
143
|
// Verify the signature is meant for us, otherwise any other site can hijack the login!
|
|
137
144
|
// (We don't have to worry about other servers on the same domain, as all servers
|
|
138
145
|
// on the same domain should be the same!)
|
|
@@ -221,6 +228,7 @@ const changeIdentityOnce = cacheWeak(async function changeIdentityOnce(connectio
|
|
|
221
228
|
certIssuer: issuer.cert.toString(),
|
|
222
229
|
mountedPort: getNodeIdLocation(SocketFunction.mountedNodeId)?.port,
|
|
223
230
|
debugEntryPoint: isNode() ? process.argv[1] : "browser",
|
|
231
|
+
clientIsNode: isNode(),
|
|
224
232
|
};
|
|
225
233
|
let signature = sign(threadKeyCert, payload);
|
|
226
234
|
await timeoutToError(
|
|
@@ -3,11 +3,11 @@ import { getArchives } from "../-a-archives/archives";
|
|
|
3
3
|
import { getDomain, isDevDebugbreak, isNoNetwork, isPublic } from "../config";
|
|
4
4
|
import { measureBlock } from "socket-function/src/profiling/measure";
|
|
5
5
|
import { isNode, sha256Hash, throttleFunction, timeInMinute, timeInSecond } from "socket-function/src/misc";
|
|
6
|
-
import { errorToUndefinedSilent, ignoreErrors, logErrors, timeoutToUndefinedSilent } from "../errors";
|
|
6
|
+
import { errorToUndefinedSilent, ignoreErrors, logErrors, timeoutToError, timeoutToUndefinedSilent } from "../errors";
|
|
7
7
|
import { ensureWeAreTrusted, requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
|
|
8
8
|
import { delay, runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
9
|
-
import { getNodeId, getNodeIdFromLocation, getNodeIdLocation } from "socket-function/src/nodeCache";
|
|
10
|
-
import { lazy } from "socket-function/src/caching";
|
|
9
|
+
import { getCallFactory, getCreateCallFactory, getNodeId, getNodeIdFromLocation, getNodeIdLocation } from "socket-function/src/nodeCache";
|
|
10
|
+
import { cache, lazy } from "socket-function/src/caching";
|
|
11
11
|
import { shuffle } from "../misc/random";
|
|
12
12
|
import { blue, green, magenta, red, yellow } from "socket-function/src/formatting/logColors";
|
|
13
13
|
import { PromiseObj } from "../promise";
|
|
@@ -46,8 +46,6 @@ let DISK_AUDIT_RATE = timeInMinute * 15;
|
|
|
46
46
|
// probably is less than that). Which is around 2.5 cents on digital ocean IF we go over
|
|
47
47
|
// our 1TB/month allowance.
|
|
48
48
|
let API_AUDIT_RATE = timeInSecond * 30;
|
|
49
|
-
// BUT, for now, poll less often... because I think it is lagging our 2 core potato digital ocean server.
|
|
50
|
-
API_AUDIT_RATE = timeInMinute * 5;
|
|
51
49
|
let API_AUDIT_COUNT = 12;
|
|
52
50
|
|
|
53
51
|
|
|
@@ -196,8 +194,12 @@ function addNodeIdBase(nodeId: string) {
|
|
|
196
194
|
allNodeIds2.add(nodeId);
|
|
197
195
|
onNodesChanged();
|
|
198
196
|
}
|
|
199
|
-
function setNodeIds(nodeIds: string[]) {
|
|
197
|
+
async function setNodeIds(nodeIds: string[]) {
|
|
200
198
|
nodeIds = nodeIds.filter(x => x !== SPECIAL_NODE_ID_FOR_UNMOUNTED_NODE);
|
|
199
|
+
if (isNode()) {
|
|
200
|
+
await Promise.allSettled(nodeIds.map(checkWrongServerNodeId));
|
|
201
|
+
nodeIds = nodeIds.filter(nodeId => !wrongServerNodeIds.has(nodeId));
|
|
202
|
+
}
|
|
201
203
|
|
|
202
204
|
console.info("setNodeIds", { nodeIds });
|
|
203
205
|
let newNodeIds = nodeIds.filter(nodeId => !allNodeIds2.has(nodeId));
|
|
@@ -295,25 +297,74 @@ export async function triggerNodeChange() {
|
|
|
295
297
|
}));
|
|
296
298
|
}
|
|
297
299
|
|
|
300
|
+
// If we can connect on the same port, but it has a different thread ID, it means the old thread ID is gone. We're never going to go back to an old thread ID, and we can't have two threads on the same port.
|
|
301
|
+
let wrongServerNodeIds = new Set<string>();
|
|
302
|
+
let checkWrongServerNodeId = cache(async (nodeId: string) => {
|
|
303
|
+
if (wrongServerNodeIds.has(nodeId)) return;
|
|
304
|
+
let callFactory = await timeoutToUndefinedSilent(timeInSecond * 5, Promise.resolve(getCreateCallFactory(nodeId)));
|
|
305
|
+
if (!callFactory) {
|
|
306
|
+
if (SocketFunction.logMessages) {
|
|
307
|
+
console.log(`Did not find call factory for ${nodeId}`);
|
|
308
|
+
}
|
|
309
|
+
// Clear it right away, so we can check for it being alive quickly.
|
|
310
|
+
checkWrongServerNodeId.clear(nodeId);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (callFactory) {
|
|
314
|
+
// Not great, but... this should work well enough.
|
|
315
|
+
for (let i = 0; i < 10; i++) {
|
|
316
|
+
if (callFactory.receivedInitializeState) break;
|
|
317
|
+
await delay(500);
|
|
318
|
+
}
|
|
319
|
+
if (!callFactory.receivedInitializeState && SocketFunction.logMessages) {
|
|
320
|
+
console.log(`Did not receive initialize state from ${nodeId}`);
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
if (SocketFunction.logMessages) {
|
|
324
|
+
console.log(`Did not find call factory for ${nodeId}`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (callFactory && callFactory.realNodeId && callFactory.realNodeId !== nodeId) {
|
|
328
|
+
if (SocketFunction.logMessages) {
|
|
329
|
+
console.log(red(`Found dead thread, disconnecting node and deleting from archives ${nodeId}`));
|
|
330
|
+
}
|
|
331
|
+
wrongServerNodeIds.add(nodeId);
|
|
332
|
+
callFactory?.disconnect();
|
|
333
|
+
// Dead threads never come back, so this should be safe to do.
|
|
334
|
+
await archives().del(nodeId);
|
|
335
|
+
// Return, so we don't clear this.
|
|
336
|
+
return;
|
|
337
|
+
} else {
|
|
338
|
+
if (SocketFunction.logMessages) {
|
|
339
|
+
console.log(green(`Found live thread, node ${nodeId}, real node id ${callFactory?.realNodeId}`));
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
setTimeout(() => {
|
|
344
|
+
checkWrongServerNodeId.clear(nodeId);
|
|
345
|
+
}, timeInMinute * 5);
|
|
346
|
+
});
|
|
347
|
+
|
|
298
348
|
async function syncArchives() {
|
|
299
349
|
if (isServer()) {
|
|
300
350
|
// Make sure we are present
|
|
301
351
|
await writeHeartbeat();
|
|
302
352
|
let nodeIds = await archives().find("");
|
|
303
353
|
console.log(green(`Syncing node ids from archives`), { nodeIds });
|
|
304
|
-
|
|
354
|
+
console.log(green(`Synced node ids from archives`), { nodeIds });
|
|
355
|
+
await setNodeIds(nodeIds);
|
|
305
356
|
} else {
|
|
306
357
|
if (isNoNetwork() || !isNode()) {
|
|
307
358
|
// NOTE: If no network, our trust source might be different, so we can't talk to regular nodes,
|
|
308
359
|
// and instead have to only talk to HTTP nodes
|
|
309
|
-
setNodeIds([getBrowserUrlNode()]);
|
|
360
|
+
await setNodeIds([getBrowserUrlNode()]);
|
|
310
361
|
} else {
|
|
311
362
|
// If on the network, NetworkTrust2 should sync the trusted machines from backblaze, so we should be
|
|
312
363
|
// able to talk to any nodes.
|
|
313
364
|
// - If they user is using --client they only want to talk to querysub nodes. There might be multiple,
|
|
314
365
|
// which cloudflare will proxy, HOWEVER, it is more efficient to directly access the node list, which
|
|
315
366
|
// will be better for load balancing and updating on failure than the cloudflare proxying... probably.
|
|
316
|
-
setNodeIds(await NodeDiscoveryController.nodes[getBrowserUrlNode()].getAllNodeIds());
|
|
367
|
+
await setNodeIds(await NodeDiscoveryController.nodes[getBrowserUrlNode()].getAllNodeIds());
|
|
317
368
|
}
|
|
318
369
|
}
|
|
319
370
|
}
|
|
@@ -332,7 +383,7 @@ async function runHeartbeatAuditLoop() {
|
|
|
332
383
|
let deadTime = Date.now() - DEAD_THRESHOLD;
|
|
333
384
|
let nodeIds = await archives().find("");
|
|
334
385
|
// We spent the money checking the node list, so we might as well update it
|
|
335
|
-
setNodeIds(nodeIds);
|
|
386
|
+
await setNodeIds(nodeIds);
|
|
336
387
|
|
|
337
388
|
let pendingDeadCount = 0;
|
|
338
389
|
|
|
@@ -565,6 +616,7 @@ class NodeDiscoveryControllerBase {
|
|
|
565
616
|
public async addNode(nodeId: string) {
|
|
566
617
|
console.log(magenta(`Received addNode`), { nodeId });
|
|
567
618
|
addNodeId(nodeId);
|
|
619
|
+
return true;
|
|
568
620
|
}
|
|
569
621
|
public async resyncNodes(reason: string) {
|
|
570
622
|
let caller = SocketFunction.getCaller();
|
|
@@ -589,6 +641,7 @@ const NodeDiscoveryController = SocketFunction.register(
|
|
|
589
641
|
"NodeDiscoveryController-7991037e-fd9e-4085-b1db-52035487e72c",
|
|
590
642
|
new NodeDiscoveryControllerBase(),
|
|
591
643
|
() => ({
|
|
644
|
+
getOwnNodeId: { noClientHooks: true, noDefaultHooks: true },
|
|
592
645
|
addNode: { hooks: [requiresNetworkTrustHook] },
|
|
593
646
|
resyncNodes: { hooks: [requiresNetworkTrustHook] },
|
|
594
647
|
getAllNodesHash: { hooks: [requiresNetworkTrustHook] },
|
|
@@ -5,7 +5,7 @@ import { archiveJSONT } from "../-a-archives/archivesJSONT";
|
|
|
5
5
|
import { getDomain, isPublic } from "../config";
|
|
6
6
|
import { cache, lazy } from "socket-function/src/caching";
|
|
7
7
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
8
|
-
import { runInSerial, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
8
|
+
import { delay, runInSerial, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
9
9
|
import { getAllNodeIds, getOwnNodeId, isOwnNodeId, onNodeBroadcasted, syncNodesNow, watchDeltaNodeIds, watchNodeIds } from "../-f-node-discovery/NodeDiscovery";
|
|
10
10
|
import { IdentityController_getCurrentReconnectNodeIdAssert } from "../-c-identity/IdentityController";
|
|
11
11
|
import { requiresNetworkTrustHook } from "../-d-trust/NetworkTrust2";
|
|
@@ -16,6 +16,7 @@ import { AuthoritySpec } from "./PathRouter";
|
|
|
16
16
|
import { formatTime } from "socket-function/src/formatting/format";
|
|
17
17
|
import { getAllAuthoritySpec, getEmptyAuthoritySpec } from "./PathRouterServerAuthoritySpec";
|
|
18
18
|
|
|
19
|
+
setImmediate(() => import("../3-path-functions/syncSchema"));
|
|
19
20
|
|
|
20
21
|
let NETWORK_POLL_INTERVAL = timeInMinute * 5;
|
|
21
22
|
let CALL_TIMEOUT = isPublic() ? timeInSecond * 20 : timeInSecond * 3;
|
|
@@ -46,11 +47,15 @@ class AuthorityLookup {
|
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
public getTopologySync() {
|
|
49
|
-
if (!this.didInitialSync)
|
|
50
|
+
if (!this.didInitialSync) {
|
|
51
|
+
require("debugbreak")(2);
|
|
52
|
+
debugger;
|
|
53
|
+
throw new Error("Cannot call getTopologySync without awaiting syncAllNow or startSyncing.");
|
|
54
|
+
}
|
|
50
55
|
return Array.from(this.topology.nodes.values()).filter(x => x.isReady);
|
|
51
56
|
}
|
|
52
57
|
public getAuthoritySpecForNodeId(nodeId: string): AuthoritySpec | undefined {
|
|
53
|
-
if (!this.didInitialSync) throw new Error("Cannot call getAuthoritySpecForNodeId without
|
|
58
|
+
if (!this.didInitialSync) throw new Error("Cannot call getAuthoritySpecForNodeId without awaiting syncAllNow or startSyncing.");
|
|
54
59
|
return this.topology.nodes.get(nodeId)?.authoritySpec;
|
|
55
60
|
}
|
|
56
61
|
|
|
@@ -201,9 +206,14 @@ class AuthorityLookup {
|
|
|
201
206
|
if (isClient()) {
|
|
202
207
|
// Doesn't matter what the node ID is, we should really only be connecting to the browser node ID, Which will have all the data for the current domain.
|
|
203
208
|
// - Get all node IDs should restrict our nodes to just the browser node ID. If we ever change this, then either it's redundant nodes and they all have all the same data, or we need to figure out what data they have, And as their proxies, it probably won't be their actual authority data. So that will require new API functions, etc.
|
|
209
|
+
await new Promise(r => setImmediate(r));
|
|
210
|
+
await delay(1);
|
|
211
|
+
let { getPrefixesForDeploy } = await import("../3-path-functions/syncSchema");
|
|
204
212
|
this.updatePaths(nodeId, {
|
|
205
|
-
...getAllAuthoritySpec(),
|
|
206
213
|
nodeId: nodeId,
|
|
214
|
+
prefixes: await getPrefixesForDeploy(),
|
|
215
|
+
routeStart: 0,
|
|
216
|
+
routeEnd: 1,
|
|
207
217
|
}, true);
|
|
208
218
|
return;
|
|
209
219
|
}
|