querysub 0.269.0 → 0.271.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.269.0",
3
+ "version": "0.271.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",
@@ -323,6 +323,7 @@ export function getSpecFromModule(module: NodeJS.Module): LoadFunctionSpec | und
323
323
  async function getModuleFromSpecBase(
324
324
  spec: LoadFunctionSpec
325
325
  ): Promise<NodeJS.Module> {
326
+ console.log(blue(`Loading module for ${JSON.stringify(spec)}`));
326
327
  // Register ourself as overlapping, to prevent ambient modules from being set in this way.
327
328
  registerSpec(module.filename, "overlapping");
328
329
 
@@ -41,7 +41,7 @@ import { waitForFirstTimeSync } from "socket-function/time/trueTimeShim";
41
41
  import { logMeasureTable, measureBlock, measureFnc, measureWrap, startMeasure } from "socket-function/src/profiling/measure";
42
42
  import { delay } from "socket-function/src/batching";
43
43
  import { MaybePromise } from "socket-function/src/types";
44
- import { devDebugbreak, getDomain, isDynamicallyLoading, isPublic, noSyncing } from "../config";
44
+ import { devDebugbreak, getDomain, isBootstrapOnly, isDynamicallyLoading, isPublic, noSyncing } from "../config";
45
45
  import { Schema2, Schema2T, t } from "../2-proxy/schema2";
46
46
  import { CALL_PERMISSIONS_KEY } from "./permissionsShared";
47
47
  import yargs, { check } from "yargs";
@@ -67,8 +67,6 @@ let yargObj = parseArgsFactory()
67
67
  .option("verbosenetwork", { type: "boolean", desc: "Log all network activity" })
68
68
  .option("verboseframework", { type: "boolean", desc: "Log internal SocketFunction framework" })
69
69
  .option("nodelay", { type: "boolean", desc: "Don't delay committing functions, even ones that are marked to be delayed." })
70
- // TODO: The bootstrapper is a single file. Maybe we shouldn't run the entire service just for that. Although... maybe it's fine, as services are light?
71
- .option("bootstraponly", { type: "boolean", desc: "Don't register as an edge node, so we serve the bootstrap files, but we don't need up to date code because we are not used for endpoints or the UI." })
72
70
  .argv
73
71
  ;
74
72
  setImmediate(() => {
@@ -769,7 +767,7 @@ export class Querysub {
769
767
  }
770
768
  allowHostnames.push("127-0-0-1." + getDomain());
771
769
 
772
- if (yargObj.bootstraponly && isPublic()) {
770
+ if (isBootstrapOnly() && isPublic()) {
773
771
  if (config.port !== 443) {
774
772
  throw new Error(`--bootstraponly requires you to set port 443. There can only be one bootstrap node per server.`);
775
773
  }
@@ -790,7 +788,7 @@ export class Querysub {
790
788
 
791
789
  let { ip, ipDomain } = await publishMachineARecords();
792
790
 
793
- if (!yargObj.bootstraponly) {
791
+ if (!isBootstrapOnly()) {
794
792
  await registerEdgeNode({
795
793
  host: ipDomain + ":" + config.port,
796
794
  entryPaths,
@@ -801,6 +799,8 @@ export class Querysub {
801
799
  let existingRecords = await getRecords("A", getDomain());
802
800
  if (ip !== "127.0.0.1") {
803
801
  let validRecords: string[] = [];
802
+ // Ignore ourself, we want OTHER records.
803
+ existingRecords = existingRecords.filter(x => x !== ip);
804
804
  await Promise.all(existingRecords.map(async (record) => {
805
805
  let isListening = await timeoutToUndefined(timeInSecond * 10, testTCPIsListening(record, 443));
806
806
  if (isListening) {
@@ -43,7 +43,7 @@ setFlag(require, "preact", "allowclient", true);
43
43
  import yargs from "yargs";
44
44
  import { mergeFilterables, parseFilterable, serializeFilterable } from "../misc/filterable";
45
45
  import { isManagementUser, onAllPredictionsFinished } from "../-0-hooks/hooks";
46
- import { isLocal } from "../config";
46
+ import { isBootstrapOnly, isLocal } from "../config";
47
47
 
48
48
  let yargObj = isNodeTrue() && yargs(process.argv)
49
49
  .option("fncfilter", { type: "string", default: "", desc: `Sets the filterable state for function calls, causing them to target specific FunctionRunners. If no FunctionRunner matches, all functions will fail to run. For example: "devtestserver" will match a FunctionRunner that uses the "devtestserver" filter. Merges with the existing filterable state if a client sets it explicitly.` })
@@ -262,6 +262,7 @@ export async function baseAddCall(call: CallSpec, nodeId: string, cancel: () =>
262
262
 
263
263
  export class QuerysubControllerBase {
264
264
  public async watch(config: WatchConfig) {
265
+ if (isBootstrapOnly()) throw new Error(`Cannot watch on bootstrap only server`);
265
266
  for (let path of config.paths) {
266
267
  Querysub.assertDomainAllowed(path);
267
268
  }
@@ -485,6 +486,7 @@ export class QuerysubControllerBase {
485
486
  };
486
487
  }
487
488
  public async unwatch(config: WatchConfig) {
489
+ if (isBootstrapOnly()) throw new Error(`Cannot unwatch on bootstrap only server`);
488
490
  let pHash = permissionsHash(SocketFunction.getCaller());
489
491
  let callerId = SocketFunction.getCaller().nodeId;
490
492
  let permissionsObjIn = permissionsPerNode.get(pHash);
@@ -516,6 +518,7 @@ export class QuerysubControllerBase {
516
518
  }
517
519
 
518
520
  public async addCall(call: CallSpec) {
521
+ if (isBootstrapOnly()) throw new Error(`Cannot add calls to bootstrap only server`);
519
522
  if (Querysub.DEBUG_CALLS) {
520
523
  console.log(`[Querysub] addCall @${debugTime(call.runAtTime)}: ${call.DomainName}.${call.ModuleId}.${call.FunctionId}`);
521
524
  }
@@ -600,6 +603,7 @@ export class QuerysubControllerBase {
600
603
  FunctionId: string;
601
604
  };
602
605
  }): Promise<string> {
606
+ if (isBootstrapOnly()) throw new Error(`Cannot get module path on bootstrap only server`);
603
607
  let spec = config.functionSpec;
604
608
  Querysub.assertDomainAllowed(getPathStr1(spec.DomainName));
605
609
 
@@ -620,6 +624,7 @@ export class QuerysubControllerBase {
620
624
  ModuleId: string;
621
625
  FunctionId: string;
622
626
  }) {
627
+ if (isBootstrapOnly()) throw new Error(`Cannot get dev function spec from call on bootstrap only server`);
623
628
  let functionSpec = getDevFunctionSpecFromCall(call);
624
629
  if (!functionSpec) return undefined;
625
630
  let modulePath = (await getModuleFromConfig(functionSpec)).filename;
package/src/config.ts CHANGED
@@ -18,6 +18,8 @@ let yargObj = parseArgsFactory()
18
18
  .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.` })
19
19
  .option("nosyncing", { type: "boolean", desc: `Disabled any syncing code, just using HTTP. Still manages routing via backblaze though.` })
20
20
  .option("recovery", { type: "boolean", desc: `Allows any localhost connections to act like a superuser (and a trusted node), to help recover the database (as you need permission to access the snapshot page).` })
21
+ // TODO: The bootstrapper is a single file. Maybe we shouldn't run the entire service just for that. Although... maybe it's fine, as services are light?
22
+ .option("bootstraponly", { type: "boolean", desc: "Don't register as an edge node, so we serve the bootstrap files, but we don't need up to date code because we are not used for endpoints or the UI." })
21
23
  .argv
22
24
  ;
23
25
 
@@ -41,6 +43,10 @@ export function isNoNetwork() {
41
43
  return yargObj.nonetwork;
42
44
  }
43
45
 
46
+ export function isBootstrapOnly() {
47
+ return yargObj.bootstraponly;
48
+ }
49
+
44
50
  export function getDomain() {
45
51
  if (!isNode()) {
46
52
  return location.hostname.split(".").slice(-2).join(".");
@@ -1,8 +1,3 @@
1
- Bug, if we refresh immediately after an update, we get into a state where we know we should be using a new hash, but the lookup for the hashes is cached, so we think the server doesn't exist,
2
- - Hopefully it's just that we're using the cache we received from the server. If it's actually being cached in Cloudflare, that's annoying and I think we just need to fall back if we see the live hash has been updated recently. Although I don't think we're storing the timestamps so that's annoying.
3
-
4
- 7) verify manually refreshing removes the message
5
-
6
1
  8) Use a special service for the HTTP bootstrapper, and then have 2 others that are on other ports
7
2
  --bootstraponly is added, and should work?
8
3
 
@@ -95,6 +95,8 @@ export function getSyncedController<T extends SocketRegistered>(
95
95
  */
96
96
  reads?: { [key in keyof T["nodes"][""]]?: string[]; };
97
97
  writes?: { [key in keyof T["nodes"][""]]?: string[]; };
98
+ // TODO: Add a flag to give timeouts, so values are automatically refreshed every once in a while, so pages don't get too stale?
99
+ // - BUT with a "softRefresh", so we don't trigger a re-render, we only update it if it is accessed again!
98
100
  }
99
101
  ): {
100
102
  (nodeId: string): {