querysub 0.401.0 → 0.403.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.401.0",
3
+ "version": "0.403.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",
@@ -9,7 +9,7 @@ import { SocketFunction } from "socket-function/SocketFunction";
9
9
  import { CallerContext } from "socket-function/SocketFunctionTypes";
10
10
  import { cache, cacheWeak, lazy } from "socket-function/src/caching";
11
11
  import { getClientNodeId, getNodeId, getNodeIdDomain, getNodeIdIP, getNodeIdLocation, isClientNodeId } from "socket-function/src/nodeCache";
12
- import { getCommonName, getIdentityCA, getMachineId, getPublicIdentifier, getThreadKeyCert, parseCert, sign, validateCertificate, verify } from "../-a-auth/certs";
12
+ import { decodeNodeId, getCommonName, getIdentityCA, getMachineId, getPublicIdentifier, getThreadKeyCert, parseCert, sign, validateCertificate, verify } from "../-a-auth/certs";
13
13
  import { getShortNumber } from "../bits";
14
14
  import { measureBlock, measureFnc, measureWrap } from "socket-function/src/profiling/measure";
15
15
  import { timeoutToError } from "../errors";
@@ -18,6 +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 { getOwnThreadId } from "../-f-node-discovery/NodeDiscovery";
21
22
 
22
23
  let callerInfo = new Map<CallerContext, {
23
24
  reconnectNodeId: string | undefined;
@@ -68,6 +69,11 @@ export function debugNodeId(nodeId: string) {
68
69
  };
69
70
  (globalThis as any).debugNodeId = debugNodeId;
70
71
 
72
+ export function debugNodeThread(nodeId: string) {
73
+ nodeId = debugNodeId(nodeId);
74
+ return decodeNodeId(nodeId)?.threadId || nodeId;
75
+ }
76
+
71
77
  /** Gets the nodeId of the machine, which should be consistent. When deciding to trust a node
72
78
  * this should be used instead of the reconnectId (otherwise you will have to trust
73
79
  * every single process individually, which will take forever!)
@@ -15,8 +15,10 @@ import { sha256 } from "js-sha256";
15
15
  import debugbreak from "debugbreak";
16
16
  import { ClientWatcher } from "../1-path-client/pathValueClientWatcher";
17
17
  import { auditLog, isDebugLogEnabled } from "./auditLogs";
18
- import { debugNodeId } from "../-c-identity/IdentityController";
18
+ import { debugNodeId, debugNodeThread } from "../-c-identity/IdentityController";
19
19
  import { logDisk } from "../diagnostics/logs/diskLogger";
20
+ import { isDiskAudit } from "../config";
21
+ import { decodeNodeId } from "../-a-auth/certs";
20
22
  export { pathValueCommitter };
21
23
 
22
24
  class PathValueControllerBase {
@@ -80,10 +82,15 @@ class PathValueControllerBase {
80
82
  }
81
83
  }
82
84
 
83
- if (isDebugLogEnabled()) {
85
+ if (isDebugLogEnabled() || isDiskAudit()) {
84
86
  let sourceNodeId = debugNodeId(callerId);
85
87
  for (let value of values) {
86
- auditLog("RECEIVE VALUE", { path: value.path, time: value.time.time, sourceNodeId });
88
+ auditLog("RECEIVE VALUE", {
89
+ path: value.path,
90
+ time: value.time.time,
91
+ sourceNodeId,
92
+ sourceNodeThreadId: decodeNodeId(sourceNodeId)?.threadId,
93
+ });
87
94
  }
88
95
  }
89
96
  console.info("Received PathValues via forwardWrites", { valueCount: values.length, callerId, });
@@ -175,7 +182,7 @@ class PathValueControllerBase {
175
182
  if (isDebugLogEnabled()) {
176
183
  let sourceNodeId = debugNodeId(callerId);
177
184
  for (let value of config.paths) {
178
- auditLog("WATCH PATH", { path: value, sourceNodeId });
185
+ auditLog("WATCH PATH", { path: value, sourceNodeId, sourceNodeThreadId: debugNodeThread(callerId) });
179
186
  }
180
187
  for (let value of config.parentPaths) {
181
188
  auditLog("WATCH PARENT PATH", { path: value, sourceNodeId });
@@ -188,7 +195,7 @@ class PathValueControllerBase {
188
195
  if (isDebugLogEnabled()) {
189
196
  let sourceNodeId = debugNodeId(SocketFunction.getCaller().nodeId);
190
197
  for (let value of config.paths) {
191
- auditLog("UNWATCH PATH", { path: value, sourceNodeId });
198
+ auditLog("UNWATCH PATH", { path: value, sourceNodeId, sourceNodeThreadId: debugNodeThread(callerId) });
192
199
  }
193
200
  for (let value of config.parentPaths) {
194
201
  auditLog("UNWATCH PARENT PATH", { path: value, sourceNodeId });
@@ -5,7 +5,7 @@ import { addEpsilons, getBufferFraction, minusEpsilon } from "../bits";
5
5
  import { errorToUndefined, ignoreErrors, logErrors } from "../errors";
6
6
  import { appendToPathStr, getParentPathStr, getPathDepth, getPathFromStr, getPathIndexAssert, getPathStr, hack_getPackedPathSuffix, hack_setPackedPathSuffix, hack_stripPackedPath, removePathLastPart, rootPathStr } from "../path";
7
7
  import { measureBlock, measureFnc, measureWrap } from "socket-function/src/profiling/measure";
8
- import { IdentityController_getOwnPubKeyShort, debugNodeId } from "../-c-identity/IdentityController";
8
+ import { IdentityController_getOwnPubKeyShort, debugNodeId, debugNodeThread } from "../-c-identity/IdentityController";
9
9
  import { pathValueArchives } from "./pathValueArchives";
10
10
  import { blue, magenta, red, yellow } from "socket-function/src/formatting/logColors";
11
11
  import { PathValueController, pathValueCommitter } from "./PathValueController";
@@ -1254,7 +1254,11 @@ class PathWatcher {
1254
1254
  }
1255
1255
  } else {
1256
1256
  for (let path of newPathsWatched) {
1257
- auditLog("new non-local WATCH VALUE", { path, watcher: config.callback });
1257
+ auditLog("new non-local WATCH VALUE", {
1258
+ path,
1259
+ watcher: config.callback,
1260
+ targetNodeThreadId: debugNodeThread(config.callback),
1261
+ });
1258
1262
  }
1259
1263
  for (let path of newParentsWatched) {
1260
1264
  auditLog("new non-local WATCH PARENT", { path, watcher: config.callback });
@@ -1579,9 +1583,18 @@ class PathWatcher {
1579
1583
  stripSource: !allowSource,
1580
1584
  });
1581
1585
 
1582
- if (isDiskAudit()) {
1586
+ if (isDebugLogEnabled() || isDiskAudit()) {
1583
1587
  for (let pathValue of changes) {
1584
- auditLog("SEND VALUE", { path: pathValue.path, time: pathValue.time.time, watcher, nodeId: debugNodeId(watcher), transparent: pathValue.isTransparent, canGC: pathValue.canGCValue });
1588
+ auditLog("SEND VALUE", {
1589
+ path: pathValue.path,
1590
+ time: pathValue.time.time,
1591
+ watcher,
1592
+ nodeId: debugNodeId(watcher),
1593
+ targetNodeId: debugNodeId(watcher),
1594
+ targetNodeThreadId: debugNodeThread(watcher),
1595
+ transparent: pathValue.isTransparent,
1596
+ canGC: pathValue.canGCValue,
1597
+ });
1585
1598
  }
1586
1599
  }
1587
1600
  await PathValueController.nodes[watcher].forwardWrites(
@@ -17,7 +17,8 @@ import { appendToPathStr, getParentPathStr, getPathDepth, getPathIndexAssert, ge
17
17
  import { isEmpty } from "../misc";
18
18
  import debugbreak from "debugbreak";
19
19
  import { isDevDebugbreak } from "../config";
20
- import { auditLog } from "../0-path-value-core/auditLogs";
20
+ import { auditLog, isDebugLogEnabled } from "../0-path-value-core/auditLogs";
21
+ import { debugNodeThread } from "../-c-identity/IdentityController";
21
22
 
22
23
  // NOTE: In some cases this can half our the PathValues sent. AND, it can reduce our sync requests by N, and as those are uploads those are event more expensive. However, it also complicates other code, requiring not just checking if a value is synced, but also the parent path. We should try to make this stable, but worst case scenario, we can set this to false, and it will make our synchronization a lot easier to verify.
23
24
  const STOP_KEYS_DOUBLE_SENDS = true;
@@ -457,6 +458,14 @@ export class RemoteWatcher {
457
458
  paths: Array.from(paths),
458
459
  parentPaths: Array.from(parentPaths),
459
460
  };
461
+ if (isDebugLogEnabled()) {
462
+ for (let path of paths) {
463
+ auditLog("Asking to watch path", { path, authorityId, targetNodeThreadId: debugNodeThread(authorityId) });
464
+ }
465
+ for (let path of parentPaths) {
466
+ auditLog("Asking to watch parent path", { path, authorityId, targetNodeThreadId: debugNodeThread(authorityId) });
467
+ }
468
+ }
460
469
  logErrors(RemoteWatcher.REMOTE_WATCH_FUNCTION(config, authorityId));
461
470
  }
462
471
  });
@@ -53,6 +53,7 @@ export class FullscreenModal extends qreact.Component<{
53
53
  if (this.props.noModalWrap) return base;
54
54
  return (
55
55
  <Modal
56
+ onlyExplicitClose={this.props.onlyExplicitClose}
56
57
  onClose={() => {
57
58
  if (this.props.parentState) this.props.parentState.open = false;
58
59
  return this.props.onCancel?.();
@@ -43,6 +43,7 @@ const ensureRendering = lazy(() => {
43
43
  /** IMPORTANT! Use the .keepModalsOpen class to prevent clicks from closing the model */
44
44
  export class Modal extends qreact.Component<{
45
45
  onClose?: () => void | "abortClose";
46
+ onlyExplicitClose?: boolean;
46
47
  }> {
47
48
  id = nextId();
48
49
  componentWillUnmount(): void {
@@ -55,6 +56,7 @@ export class Modal extends qreact.Component<{
55
56
  data().modals[this.id] = atomicObjectWriteNoFreeze({
56
57
  value: this.props.children,
57
58
  onClose: this.props.onClose,
59
+ onlyExplicitClose: this.props.onlyExplicitClose,
58
60
  });
59
61
  return undefined;
60
62
  }
@@ -35,7 +35,6 @@ export class LifeCycleEntryEditor extends qreact.Component<{
35
35
  return <div className={
36
36
  css.pad2(4).bord2(150, 30, 70)
37
37
  .vbox(4)
38
- .cursor("auto")
39
38
  + bgClass
40
39
  + " LifeCycleEntryEditor"
41
40
  }>
@@ -282,6 +281,21 @@ export class LifeCycleEntryEditor extends qreact.Component<{
282
281
  >
283
282
  Copy to All
284
283
  </Button>
284
+ <Button hue={160} onClick={() => {
285
+ let updatedLifeCycle = deepCloneJSON(lifeCycle);
286
+ updatedLifeCycle.entries.forEach((e) => {
287
+ if (key in e.variables) {
288
+ let varData = e.variables[key];
289
+ delete e.variables[key];
290
+ e.variables = { [key]: varData, ...e.variables };
291
+ }
292
+ });
293
+ Querysub.onCommitFinished(async () => {
294
+ await this.controller.setLifeCycle.promise(updatedLifeCycle);
295
+ });
296
+ }}>
297
+ Move to start
298
+ </Button>
285
299
  <span className={css.minWidth(150).boldStyle}>{key}</span>
286
300
  <InputLabel
287
301
  placeholder="Variable title"
@@ -317,7 +331,11 @@ export class LifeCycleEntryEditor extends qreact.Component<{
317
331
  hue={0}
318
332
  onClick={() => {
319
333
  let updatedLifeCycle = deepCloneJSON(lifeCycle);
320
- delete updatedLifeCycle.entries[entryIndex].variables[key];
334
+ for (let e of updatedLifeCycle.entries) {
335
+ if (key in e.variables) {
336
+ delete e.variables[key];
337
+ }
338
+ }
321
339
  Querysub.onCommitFinished(async () => {
322
340
  await this.controller.setLifeCycle.promise(updatedLifeCycle);
323
341
  });
@@ -271,7 +271,7 @@ export class LifeCycleInstanceRenderer extends qreact.Component<{
271
271
  </div>
272
272
 
273
273
  {this.state.expanded && (
274
- <div className={css.vbox(8) + "LifeCycleRenderer-contents"}>
274
+ <div className={css.vbox(8).cursor("auto") + "LifeCycleRenderer-contents"}>
275
275
  <Button
276
276
  hue={200}
277
277
  onClick={() => {