querysub 0.115.0 → 0.117.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/deploy.js +1 -1
- package/package.json +4 -4
- package/src/-a-archives/archivesBackBlaze.ts +1 -1
- package/src/-f-node-discovery/NodeDiscovery.ts +1 -1
- package/src/3-path-functions/PathFunctionHelpers.ts +0 -2
- package/src/3-path-functions/pathFunctionLoader.ts +66 -16
- package/src/{3-path-functions → 4-deploy}/deployMain.ts +15 -15
- package/src/4-deploy/deploySchema.ts +69 -0
- package/src/{4-querysub/edge → 4-deploy}/edgeBootstrap.ts +1 -2
- package/src/{4-querysub/edge → 4-deploy}/edgeNodes.ts +97 -9
- package/src/4-deploy/git.ts +7 -0
- package/src/4-dom/qreact.tsx +1 -1
- package/src/4-dom/qreactTest.tsx +1 -1
- package/src/4-querysub/Querysub.ts +1 -1
- package/src/test/test.tsx +1 -1
- /package/src/{3-path-functions → 4-deploy}/deployBlock.ts +0 -0
- /package/src/{3-path-functions → 4-deploy}/deployCheck.ts +0 -0
package/bin/deploy.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "querysub",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.117.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",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6",
|
|
25
25
|
"pako": "^2.1.0",
|
|
26
26
|
"preact": "^10.11.3",
|
|
27
|
-
"socket-function": "^0.
|
|
27
|
+
"socket-function": "^0.78.0",
|
|
28
28
|
"terser": "^5.31.0",
|
|
29
29
|
"typesafecss": "^0.6.3",
|
|
30
30
|
"yaml": "^2.5.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"server": "yarn typenode ./src/server.ts",
|
|
38
38
|
"serversharded": "yarn server --authority ./pathremain.json & yarn server --authority ./patha.json & yarn server --authority ./pathb.json & yarn server --authority ./pathc.json & yarn server --authority ./pathd.json",
|
|
39
39
|
"function": "yarn typenode ./src/3-path-functions/PathFunctionRunnerMain.ts --function --local D:/repos/shard/",
|
|
40
|
-
"deploy": "yarn typenode ./src/
|
|
40
|
+
"deploy": "yarn typenode ./src/4-deploy/deployMain.ts --domain querysub.com --local D:/repos/shard/",
|
|
41
41
|
"type": "yarn tsc --noEmit",
|
|
42
42
|
"depend": "yarn --silent depcruise src --include-only \"^src\" --config --output-type dot | dot -T svg > dependency-graph.svg",
|
|
43
43
|
"dbmerge": "yarn typenode ./src/dbmerge.ts",
|
|
@@ -57,4 +57,4 @@
|
|
|
57
57
|
"resolutions": {
|
|
58
58
|
"node-forge": "https://github.com/sliftist/forge#e618181b469b07bdc70b968b0391beb8ef5fecd6"
|
|
59
59
|
}
|
|
60
|
-
}
|
|
60
|
+
}
|
|
@@ -406,7 +406,7 @@ export class ArchivesBackblaze {
|
|
|
406
406
|
corsRuleName: "onlyCurrentOrigin",
|
|
407
407
|
allowedOrigins: ["*"],
|
|
408
408
|
allowedOperations: ["b2_download_file_by_id", "b2_download_file_by_name"],
|
|
409
|
-
allowedHeaders: [],
|
|
409
|
+
allowedHeaders: ["range"],
|
|
410
410
|
exposeHeaders: ["x-bz-content-sha1"],
|
|
411
411
|
maxAgeSeconds: cacheTime / 1000,
|
|
412
412
|
}] : [];
|
|
@@ -23,7 +23,7 @@ import dns from "dns/promises";
|
|
|
23
23
|
import { isDefined } from "../misc";
|
|
24
24
|
import { diskLog, noDiskLogPrefix } from "../diagnostics/logs/diskLogger";
|
|
25
25
|
import { getDebuggerUrl } from "../diagnostics/listenOnDebugger";
|
|
26
|
-
import { getBootedEdgeNode } from "../4-
|
|
26
|
+
import { getBootedEdgeNode } from "../4-deploy/edgeBootstrap";
|
|
27
27
|
|
|
28
28
|
let HEARTBEAT_INTERVAL = timeInMinute * 2;
|
|
29
29
|
// Interval which we check other heartbeats
|
|
@@ -15,8 +15,6 @@ import { getPathStr2 } from "../path";
|
|
|
15
15
|
import { isNode, sort } from "socket-function/src/misc";
|
|
16
16
|
import { decodeCborx, encodeCborx } from "../misc/cloneHelpers";
|
|
17
17
|
import { parseFilterable } from "../misc/filterable";
|
|
18
|
-
const cborxInstance = lazy(() => new cborx.Encoder({ structuredClone: true }));
|
|
19
|
-
|
|
20
18
|
|
|
21
19
|
// NOTE: We could deploy single functions, but... we will almost always be updating all functions at
|
|
22
20
|
// once, because keeping everything on the same git hash reduces a lot of potential bugs.
|
|
@@ -24,6 +24,13 @@ import { sha256 } from "js-sha256";
|
|
|
24
24
|
import os from "os";
|
|
25
25
|
import { formatTime } from "socket-function/src/formatting/format";
|
|
26
26
|
|
|
27
|
+
export type LoadFunctionSpec = {
|
|
28
|
+
gitURL: string;
|
|
29
|
+
gitRef: string;
|
|
30
|
+
FilePath: string;
|
|
31
|
+
FunctionId: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
27
34
|
// Get localPathRemappings using yargs, so it is easy to configure in multiple entry points
|
|
28
35
|
let yargObj = isNodeTrue() && yargs(process.argv)
|
|
29
36
|
.option("local", { type: "boolean", desc: `If true, uses the local directory instead of the remote git repo. Also hotreloads from disk. Determines the repo to replace through the package.json "repository" property.` })
|
|
@@ -82,20 +89,17 @@ let moduleCache = new Map<string, {
|
|
|
82
89
|
result: MaybePromise<NodeJS.Module>;
|
|
83
90
|
error: Error | undefined;
|
|
84
91
|
}>();
|
|
85
|
-
function getSpecKey(spec:
|
|
92
|
+
function getSpecKey(spec: LoadFunctionSpec) {
|
|
86
93
|
// Only include these specific keys AND order them, so the hash hits no matter how this function is called
|
|
87
94
|
spec = {
|
|
88
95
|
FilePath: spec.FilePath,
|
|
89
96
|
gitURL: spec.gitURL,
|
|
90
97
|
gitRef: spec.gitRef,
|
|
91
|
-
DomainName: spec.DomainName,
|
|
92
|
-
exportPathStr: spec.exportPathStr,
|
|
93
98
|
FunctionId: spec.FunctionId,
|
|
94
|
-
ModuleId: spec.ModuleId,
|
|
95
99
|
};
|
|
96
100
|
return JSON.stringify(spec);
|
|
97
101
|
}
|
|
98
|
-
export function getModuleFromConfig(spec:
|
|
102
|
+
export function getModuleFromConfig(spec: LoadFunctionSpec): MaybePromise<NodeJS.Module> {
|
|
99
103
|
let key = getSpecKey(spec);
|
|
100
104
|
let value = moduleCache.get(key);
|
|
101
105
|
if (!value) {
|
|
@@ -126,7 +130,10 @@ export function setGitURLMapping(config: {
|
|
|
126
130
|
const loadTimeIndicatorFileName = "loadTimeIndicator-71cd93ba-1667-49ac-9206-b27930bbd983";
|
|
127
131
|
|
|
128
132
|
/** spec => path that we can use with require */
|
|
129
|
-
let moduleResolver = async (spec:
|
|
133
|
+
let moduleResolver = async (spec: {
|
|
134
|
+
gitURL: string;
|
|
135
|
+
gitRef: string;
|
|
136
|
+
}) => {
|
|
130
137
|
let gitURL = spec.gitURL;
|
|
131
138
|
let urlForPath = gitURL;
|
|
132
139
|
|
|
@@ -160,7 +167,7 @@ let moduleResolver = async (spec: FunctionSpec) => {
|
|
|
160
167
|
|
|
161
168
|
// Remove any previous attempt to sync it
|
|
162
169
|
if (fs.existsSync(repoPath)) {
|
|
163
|
-
await fs.promises.rename(repoPath, repoPath + "_" + Date.now());
|
|
170
|
+
await fs.promises.rename(repoPath, repoPath.slice(0, -1) + "_" + Date.now());
|
|
164
171
|
}
|
|
165
172
|
// Clone it
|
|
166
173
|
await executeCommand("git", ["clone", gitURL, repoPath]);
|
|
@@ -257,7 +264,7 @@ function getCallstackFiles(): string[] {
|
|
|
257
264
|
}
|
|
258
265
|
|
|
259
266
|
async function getModuleFromSpecBase(
|
|
260
|
-
spec:
|
|
267
|
+
spec: LoadFunctionSpec
|
|
261
268
|
): Promise<NodeJS.Module> {
|
|
262
269
|
everLoadedRepos.add(spec.gitURL);
|
|
263
270
|
let hotReloadPackagePath = "";
|
|
@@ -328,10 +335,10 @@ async function getModuleFromSpecBase(
|
|
|
328
335
|
return module;
|
|
329
336
|
}
|
|
330
337
|
|
|
331
|
-
let evaluatingFunctionSpec:
|
|
338
|
+
let evaluatingFunctionSpec: LoadFunctionSpec | undefined;
|
|
332
339
|
|
|
333
|
-
let moduleToSpec = new Map<NodeJS.Module,
|
|
334
|
-
export function getSpecFromModule(module: NodeJS.Module):
|
|
340
|
+
let moduleToSpec = new Map<NodeJS.Module, LoadFunctionSpec>();
|
|
341
|
+
export function getSpecFromModule(module: NodeJS.Module): LoadFunctionSpec | undefined {
|
|
335
342
|
return evaluatingFunctionSpec ?? moduleToSpec.get(module);
|
|
336
343
|
}
|
|
337
344
|
|
|
@@ -401,16 +408,59 @@ const hotreloadIfChanged = batchFunction({ delay: 100, name: "hotreloadIfChanged
|
|
|
401
408
|
}
|
|
402
409
|
});
|
|
403
410
|
|
|
411
|
+
async function which(command: string): Promise<string> {
|
|
412
|
+
let whichOrWhere = os.platform() === "win32" ? "where" : "which";
|
|
413
|
+
let path = child_process.execSync(`${whichOrWhere} ${command}`).toString().trim().replaceAll("\r", "").split("\n")[0].trim().replaceAll("\\", "/");
|
|
414
|
+
if (!path) {
|
|
415
|
+
throw new Error(`Command ${command} not found`);
|
|
416
|
+
}
|
|
417
|
+
path = `"${path}"`;
|
|
418
|
+
return path;
|
|
419
|
+
}
|
|
420
|
+
|
|
404
421
|
async function executeCommand(command: string, args: string[], options?: {
|
|
405
422
|
cwd?: string;
|
|
406
|
-
}) {
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
423
|
+
}): Promise<string> {
|
|
424
|
+
let resolvedCommandPath = await which(command);
|
|
425
|
+
let debug = `${resolvedCommandPath} ${args.join(" ")}`;
|
|
426
|
+
if (options?.cwd) {
|
|
427
|
+
debug += ` (in ${options.cwd})`;
|
|
428
|
+
}
|
|
429
|
+
console.log(`Running command: ${debug}`);
|
|
430
|
+
return new Promise((resolve, reject) => {
|
|
431
|
+
const child = child_process.spawn(resolvedCommandPath, args, {
|
|
432
|
+
cwd: options?.cwd,
|
|
433
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
434
|
+
shell: process.platform === "win32",
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
let stdout = "";
|
|
438
|
+
let stderr = "";
|
|
439
|
+
|
|
440
|
+
child.stdout.on("data", (data) => {
|
|
441
|
+
console.log(data.toString());
|
|
442
|
+
stdout += data.toString();
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
child.stderr.on("data", (data) => {
|
|
446
|
+
console.log(data.toString());
|
|
447
|
+
stderr += data.toString();
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
child.on("error", (error) => {
|
|
451
|
+
reject(new Error(`Failed to execute command ${debug}: ${error.message}`));
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
child.on("close", (code) => {
|
|
455
|
+
if (code !== 0) {
|
|
456
|
+
reject(new Error(`Command ${debug} failed with code ${code}.\nstdout: ${JSON.stringify(stdout)}\nstderr: ${JSON.stringify(stderr)}`));
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
resolve(stdout.trim());
|
|
460
|
+
});
|
|
410
461
|
});
|
|
411
462
|
}
|
|
412
463
|
|
|
413
|
-
|
|
414
464
|
// Helps us exclude non-function loaders (PathValueServer), which really shouldn't
|
|
415
465
|
// be loading code anyways!
|
|
416
466
|
let everLoadedRepos = new Set<string>();
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import "../inject";
|
|
2
2
|
|
|
3
|
-
import { FunctionSpec } from "
|
|
3
|
+
import { FunctionSpec } from "../3-path-functions/PathFunctionRunner";
|
|
4
4
|
import path from "path";
|
|
5
|
-
import { getExportPath, getSchemaObject, PERMISSIONS_FUNCTION_ID } from "
|
|
6
|
-
import { getModuleRelativePath } from "
|
|
7
|
-
import * as child_process from "child_process";
|
|
5
|
+
import { getExportPath, getSchemaObject, PERMISSIONS_FUNCTION_ID } from "../3-path-functions/syncSchema";
|
|
6
|
+
import { getModuleRelativePath } from "../3-path-functions/syncSchema";
|
|
8
7
|
import fs from "fs";
|
|
9
8
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
10
9
|
import { getThreadKeyCert } from "../-a-auth/certs";
|
|
11
|
-
import { replaceFunctions } from "
|
|
10
|
+
import { replaceFunctions } from "../3-path-functions/PathFunctionHelpers";
|
|
12
11
|
import { getPathStr2 } from "../path";
|
|
13
12
|
import { setIsDeploy } from "./deployCheck";
|
|
14
13
|
|
|
@@ -16,11 +15,13 @@ import yargs from "yargs";
|
|
|
16
15
|
import { isPublic } from "../config";
|
|
17
16
|
import { deployBlock } from "./deployBlock";
|
|
18
17
|
import { LOCAL_DOMAIN } from "../0-path-value-core/PathController";
|
|
19
|
-
import { preloadFunctions } from "
|
|
18
|
+
import { preloadFunctions } from "../3-path-functions/pathFunctionLoader";
|
|
20
19
|
import { magenta } from "socket-function/src/formatting/logColors";
|
|
20
|
+
import { getGitRef } from "./git";
|
|
21
|
+
import { getGitURL } from "./git";
|
|
22
|
+
import { setLiveDeployedHash } from "./deploySchema";
|
|
21
23
|
let yargObj = yargs(process.argv)
|
|
22
24
|
.option("domain", { type: "string", required: true, desc: "Domain to deploy to" })
|
|
23
|
-
.option("nogit", { type: "boolean", default: false, desc: `Disable git operations. Useful for debugging, when using --local` })
|
|
24
25
|
.argv
|
|
25
26
|
;
|
|
26
27
|
|
|
@@ -56,6 +57,12 @@ export async function deployMain() {
|
|
|
56
57
|
}
|
|
57
58
|
let gitRef = getGitRef(gitDir);
|
|
58
59
|
|
|
60
|
+
|
|
61
|
+
//todonext
|
|
62
|
+
// Flags to set this
|
|
63
|
+
//setLiveDeployedHash(gitRef);
|
|
64
|
+
|
|
65
|
+
|
|
59
66
|
let usedModules = new Map<string, string>();
|
|
60
67
|
|
|
61
68
|
for (let module of Object.values(require.cache)) {
|
|
@@ -121,13 +128,6 @@ export async function deployMain() {
|
|
|
121
128
|
|
|
122
129
|
console.log(magenta(`FINISHED DEPLOY`));
|
|
123
130
|
}
|
|
124
|
-
|
|
125
|
-
if (yargObj.nogit) return "git@github.com:nogit/nogit.git";
|
|
126
|
-
return child_process.execSync(`git remote get-url origin`, { cwd: gitDir }).toString().trim();
|
|
127
|
-
}
|
|
128
|
-
function getGitRef(gitDir: string) {
|
|
129
|
-
if (yargObj.nogit) return "nogit";
|
|
130
|
-
return child_process.execSync(`git rev-parse HEAD`, { cwd: gitDir }).toString().trim();
|
|
131
|
-
}
|
|
131
|
+
|
|
132
132
|
|
|
133
133
|
deployMain().catch(e => console.error(e)).finally(() => process.exit());
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { nextId } from "socket-function/src/misc";
|
|
2
|
+
import { proxyWatcher } from "../2-proxy/PathValueProxyWatcher";
|
|
3
|
+
import { rawSchema } from "../2-proxy/pathDatabaseProxyBase";
|
|
4
|
+
import { functionSchema } from "../3-path-functions/PathFunctionRunner";
|
|
5
|
+
import { syncSchema } from "../3-path-functions/syncSchema";
|
|
6
|
+
import { getDomain } from "../config";
|
|
7
|
+
|
|
8
|
+
//todonext
|
|
9
|
+
// Current hash, history of hashes
|
|
10
|
+
export const deploySchema = rawSchema<{
|
|
11
|
+
[domainName: string]: {
|
|
12
|
+
deploy: {
|
|
13
|
+
live: DeployedHash;
|
|
14
|
+
history: {
|
|
15
|
+
[id: string]: DeployedHash;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}>();
|
|
20
|
+
export interface DeployedHash {
|
|
21
|
+
hash: string;
|
|
22
|
+
time: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export function setLiveDeployedHash(hash: string) {
|
|
27
|
+
proxyWatcher.writeOnly({
|
|
28
|
+
watchFunction: function writeCall() {
|
|
29
|
+
let hashObj: DeployedHash = {
|
|
30
|
+
hash,
|
|
31
|
+
time: Date.now(),
|
|
32
|
+
};
|
|
33
|
+
deploySchema()[getDomain()].deploy.live = hashObj;
|
|
34
|
+
deploySchema()[getDomain()].deploy.history[nextId()] = hashObj;
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//todonext
|
|
40
|
+
// - Function to dynamically deploy edge service based on hash (try on old hashes)
|
|
41
|
+
// - Watch live hash, and when it changes, deploy new edge service
|
|
42
|
+
// - Add flag to deploy script which sets it (with all the flags, so we can just deploy it)
|
|
43
|
+
// - Update edge node code to pass live hash, and try to connect to a service with that
|
|
44
|
+
|
|
45
|
+
//todonext
|
|
46
|
+
/*
|
|
47
|
+
Force client refresh mechanism / update notification ON `yarn deploy`
|
|
48
|
+
- deployonlycode / deployonlyui / deploynotifyforced
|
|
49
|
+
- OH! Actually...
|
|
50
|
+
- This HAS to use a synced value!
|
|
51
|
+
- Add a new synced value which specifies the UI hash!
|
|
52
|
+
- THEN! Have front-end servers dynamically launch this services with this hash when it's set (loading the code and then serving the specific path, with the hash, etc)
|
|
53
|
+
- Also, serve this to clients!
|
|
54
|
+
- Clients will watch this value (normally, like any other value), and notify the user when it is out of date, letting them ignore it, but eventually forcing a refresh
|
|
55
|
+
- AND, support preloading it
|
|
56
|
+
- So our order will be
|
|
57
|
+
(git push)
|
|
58
|
+
preload functions
|
|
59
|
+
preload UI
|
|
60
|
+
atomically set function hashes + ui hashes
|
|
61
|
+
clients are notified they should refresh
|
|
62
|
+
new clients use services with the latest hash (which servers are already hosting)
|
|
63
|
+
functions will run this hash
|
|
64
|
+
- Ah, also... add a flag which tells us NOT to use the service HTML cache
|
|
65
|
+
- Remove it when used
|
|
66
|
+
- Required on refresh, otherwise we might refresh and use an outdated service
|
|
67
|
+
|
|
68
|
+
ALSO, have FunctionRunner watch the hash using the get/watch mechanism (for preloading, as it will dynamically load the code depending on what is really deployed anyways...)
|
|
69
|
+
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cache } from "socket-function/src/caching";
|
|
2
|
-
import { isServer } from "
|
|
2
|
+
import { isServer } from "../config2";
|
|
3
3
|
import { EdgeNodeConfig, EdgeNodesIndex } from "./edgeNodes";
|
|
4
4
|
import { timeInMinute } from "socket-function/src/misc";
|
|
5
5
|
import { measureBlock } from "socket-function/src/profiling/measure";
|
|
@@ -279,7 +279,6 @@ async function edgeNodeFunction(config: {
|
|
|
279
279
|
return true;
|
|
280
280
|
});
|
|
281
281
|
|
|
282
|
-
|
|
283
282
|
// If they are using an IP domain, that's the only node we accept (we still need to pick the node
|
|
284
283
|
// though, as we need to know the entryPaths to import)
|
|
285
284
|
{
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { waitForFirstTimeSync } from "socket-function/time/trueTimeShim";
|
|
2
|
-
import { getOwnMachineId } from "
|
|
3
|
-
import { getDomain, isPublic } from "
|
|
2
|
+
import { getOwnMachineId } from "../-a-auth/certs";
|
|
3
|
+
import { devDebugbreak, getDomain, isPublic } from "../config";
|
|
4
4
|
import child_process from "child_process";
|
|
5
|
-
import { getAllNodeIds, getOwnNodeId } from "
|
|
6
|
-
import { getArchivesBackblazePublic } from "
|
|
7
|
-
import { nestArchives } from "
|
|
5
|
+
import { getAllNodeIds, getOwnNodeId } from "../-f-node-discovery/NodeDiscovery";
|
|
6
|
+
import { getArchivesBackblazePublic } from "../-a-archives/archivesBackBlaze";
|
|
7
|
+
import { nestArchives } from "../-a-archives/archives";
|
|
8
8
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
9
9
|
import { runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
10
10
|
import { compare, compareArray, timeInMinute } from "socket-function/src/misc";
|
|
11
11
|
import { cacheLimited, lazy } from "socket-function/src/caching";
|
|
12
12
|
import { canHaveChildren } from "socket-function/src/types";
|
|
13
|
-
import { shutdown } from "
|
|
14
|
-
import { hostArchives } from "
|
|
13
|
+
import { shutdown } from "../diagnostics/periodic";
|
|
14
|
+
import { hostArchives } from "../-b-authorities/cdnAuthority";
|
|
15
|
+
import { getGitRef, getGitURL } from "./git";
|
|
16
|
+
import { getModuleFromConfig } from "../3-path-functions/pathFunctionLoader";
|
|
17
|
+
import path from "path";
|
|
18
|
+
import debugbreak from "debugbreak";
|
|
15
19
|
|
|
16
20
|
const UPDATE_POLL_INTERVAL = timeInMinute;
|
|
17
21
|
const DEAD_NODE_COUNT_THRESHOLD = 15;
|
|
@@ -70,7 +74,8 @@ export async function registerEdgeNode(config: {
|
|
|
70
74
|
|
|
71
75
|
await waitForFirstTimeSync();
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
|
|
78
|
+
let gitHash = getGitRef();
|
|
74
79
|
let nodeId = getOwnNodeId();
|
|
75
80
|
let machineId = getOwnMachineId();
|
|
76
81
|
|
|
@@ -87,9 +92,83 @@ export async function registerEdgeNode(config: {
|
|
|
87
92
|
|
|
88
93
|
await edgeNodeStorage.set("node_" + nodeId, Buffer.from(JSON.stringify(edgeNodeConfig)));
|
|
89
94
|
|
|
95
|
+
await loadEntryPointsByHash({
|
|
96
|
+
host: config.host,
|
|
97
|
+
entryPaths: config.entryPaths,
|
|
98
|
+
hash: gitHash,
|
|
99
|
+
});
|
|
100
|
+
|
|
90
101
|
await startUpdateLoop();
|
|
91
102
|
}
|
|
92
103
|
|
|
104
|
+
async function loadEntryPointsByHash(config: {
|
|
105
|
+
host: string;
|
|
106
|
+
entryPaths: string[];
|
|
107
|
+
hash: string;
|
|
108
|
+
}) {
|
|
109
|
+
let gitHash = config.hash;
|
|
110
|
+
let entryPaths = config.entryPaths;
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
debugbreak(2);
|
|
114
|
+
debugger;
|
|
115
|
+
|
|
116
|
+
let module = await getModuleFromConfig({
|
|
117
|
+
gitURL: getGitURL(),
|
|
118
|
+
gitRef: gitHash,
|
|
119
|
+
FilePath: entryPaths[0],
|
|
120
|
+
FunctionId: "entryPoint",
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
debugbreak(2);
|
|
125
|
+
debugger;
|
|
126
|
+
|
|
127
|
+
module.filename;
|
|
128
|
+
debugger;
|
|
129
|
+
|
|
130
|
+
//todonext;
|
|
131
|
+
// 1) Run this file specifically, and verify this code somewhat runs
|
|
132
|
+
// 2) Run aipaint normally. This should have a later bootTime, and therefore be picked,
|
|
133
|
+
// so it should test our browser loading other gitHashes
|
|
134
|
+
// 3) Setup the deployMain code to set the live hash
|
|
135
|
+
// - Inside of replaceFunctions, via passing a callback function to it. The nested commits SHOULD
|
|
136
|
+
// just work? Hmm... I guess verify they do (that the writeOnly functions, etc)
|
|
137
|
+
// - With all the flags (that only do one or the other)
|
|
138
|
+
// - Add preloading capability, so we can preload the hashes before we deploy
|
|
139
|
+
// 3) Dynamically watch the live hash, and load new hashes (deploying their services)
|
|
140
|
+
// - Test by pushing, deploying, and refreshing (we should prefer to latest service)
|
|
141
|
+
// 3.1) If local, DO NOT watch the live hash
|
|
142
|
+
// 5) Write the live hash to public backblaze, and have the client read it, and prefer that hash
|
|
143
|
+
// 6) Pass the live hash to the client with the edge node
|
|
144
|
+
// 7) Client live hash watch code + notify + refresh + flag to ignore the baked in live hash + edge node
|
|
145
|
+
// - Test by pushing, deploying, and then we should immediately see a notify to refresh
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
let depth = entryPaths[0].replaceAll("\\", "/").split("/").filter(x => x && x !== ".").length;
|
|
149
|
+
|
|
150
|
+
let firstPath = path.resolve(module.filename);
|
|
151
|
+
let rootPath = firstPath.replaceAll("\\", "/").split("/").slice(0, -depth).join("/") + "/";
|
|
152
|
+
|
|
153
|
+
entryPaths = entryPaths.map(x => path.resolve(rootPath + x).replaceAll("\\", "/"));
|
|
154
|
+
|
|
155
|
+
let nodeId = getOwnNodeId();
|
|
156
|
+
let machineId = getOwnMachineId();
|
|
157
|
+
|
|
158
|
+
let edgeNodeConfig: EdgeNodeConfig = {
|
|
159
|
+
nodeId,
|
|
160
|
+
machineId,
|
|
161
|
+
host: config.host,
|
|
162
|
+
gitHash,
|
|
163
|
+
bootTime: Date.now(),
|
|
164
|
+
entryPaths,
|
|
165
|
+
public: isPublic(),
|
|
166
|
+
};
|
|
167
|
+
registeredEdgeNode = edgeNodeConfig;
|
|
168
|
+
|
|
169
|
+
await edgeNodeStorage.set("node_" + nodeId, Buffer.from(JSON.stringify(edgeNodeConfig)));
|
|
170
|
+
}
|
|
171
|
+
|
|
93
172
|
export const getEdgeNodeConfigURL = lazy(async () => {
|
|
94
173
|
let { getURL } = await hostArchives({
|
|
95
174
|
archives: edgeNodeStorage,
|
|
@@ -163,4 +242,13 @@ async function updateEdgeNodesFile() {
|
|
|
163
242
|
}
|
|
164
243
|
|
|
165
244
|
await edgeNodeStorage.set("edge-nodes-index.json", Buffer.from(JSON.stringify(newEdgeNodeIndex)));
|
|
166
|
-
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
async function main() {
|
|
248
|
+
await loadEntryPointsByHash({
|
|
249
|
+
host: "127-0-0-1.querysub.com:1111",
|
|
250
|
+
entryPaths: ["./src/browser.ts"],
|
|
251
|
+
hash: "2d4fe9f2d1c80b7edd4c0f0ec4842fc38eab3b45",
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
main().catch(console.error).finally(() => process.exit());
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as child_process from "child_process";
|
|
2
|
+
export function getGitURL(gitDir = ".") {
|
|
3
|
+
return child_process.execSync(`git remote get-url origin`, { cwd: gitDir }).toString().trim();
|
|
4
|
+
}
|
|
5
|
+
export function getGitRef(gitDir = ".") {
|
|
6
|
+
return child_process.execSync(`git rev-parse HEAD`, { cwd: gitDir }).toString().trim();
|
|
7
|
+
}
|
package/src/4-dom/qreact.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type preact from "preact";
|
|
2
2
|
import { isNode, sort } from "socket-function/src/misc";
|
|
3
|
-
import { isDeploy } from "../
|
|
3
|
+
import { isDeploy } from "../4-deploy/deployCheck";
|
|
4
4
|
import { PermissionsCheck } from "../4-querysub/permissions";
|
|
5
5
|
import { ClientWatcher, clientWatcher } from "../1-path-client/pathValueClientWatcher";
|
|
6
6
|
import { LOCAL_DOMAIN } from "../0-path-value-core/PathController";
|
package/src/4-dom/qreactTest.tsx
CHANGED
|
@@ -4,7 +4,7 @@ disableMeasurements();
|
|
|
4
4
|
import preact from "preact";
|
|
5
5
|
import { isNode, list, timeInHour } from "socket-function/src/misc";
|
|
6
6
|
import { ClientWatcher, clientWatcher } from "../1-path-client/pathValueClientWatcher";
|
|
7
|
-
import { isDeploy } from "../
|
|
7
|
+
import { isDeploy } from "../4-deploy/deployCheck";
|
|
8
8
|
import { logErrors } from "../errors";
|
|
9
9
|
import { watchFilesAndTriggerHotReloading } from "socket-function/hot/HotReloadController";
|
|
10
10
|
import { qreact } from "./qreact";
|
|
@@ -891,5 +891,5 @@ registerGetCompressDisk(() => Querysub.COMPRESS_DISK);
|
|
|
891
891
|
import "../diagnostics/watchdog";
|
|
892
892
|
import "../diagnostics/trackResources";
|
|
893
893
|
import "../diagnostics/benchmark";
|
|
894
|
-
import { getEdgeNodeConfigURL, registerEdgeNode } from "
|
|
894
|
+
import { getEdgeNodeConfigURL, registerEdgeNode } from "../4-deploy/edgeNodes"; import { getEdgeBootstrapScript } from "../4-deploy/edgeBootstrap";
|
|
895
895
|
|
package/src/test/test.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { watchFilesAndTriggerHotReloading } from "socket-function/hot/HotReloadC
|
|
|
7
7
|
import { Querysub } from "../4-querysub/QuerysubController";
|
|
8
8
|
import { red } from "socket-function/src/formatting/logColors";
|
|
9
9
|
import { PermissionsCheck } from "../4-querysub/permissions";
|
|
10
|
-
import { isDeploy } from "../
|
|
10
|
+
import { isDeploy } from "../4-deploy/deployCheck";
|
|
11
11
|
import { formatTime } from "socket-function/src/formatting/format";
|
|
12
12
|
|
|
13
13
|
import { PromiseObj } from "../promise";
|
|
File without changes
|
|
File without changes
|