querysub 0.400.0 → 0.402.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.400.0",
3
+ "version": "0.402.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!)
@@ -17,6 +17,8 @@ import { ClientWatcher } from "../1-path-client/pathValueClientWatcher";
17
17
  import { auditLog, isDebugLogEnabled } from "./auditLogs";
18
18
  import { debugNodeId } 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,16 +82,18 @@ 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, });
90
- for (let value of values) {
91
- console.info("Received PathValue for path", { path: value.path, time: value.time.time, callerId });
92
- }
93
97
 
94
98
  if (isCoreQuiet) {
95
99
  await pathValueCommitter.ingestRemoteValues({
@@ -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";
@@ -1567,11 +1567,6 @@ class PathWatcher {
1567
1567
  callback(changes, parentPaths ?? []);
1568
1568
  }
1569
1569
  } else {
1570
- if (isDiskAudit()) {
1571
- for (let change of changes) {
1572
- auditLog("non-local TRIGGER", { path: change.path, time: change.time.time, watcher });
1573
- }
1574
- }
1575
1570
  if (!isCoreQuiet) {
1576
1571
  console.log(`(${Date.now()}) Sending values to client: ${changes.length} (${watcher})`);
1577
1572
  }
@@ -1584,10 +1579,18 @@ class PathWatcher {
1584
1579
  stripSource: !allowSource,
1585
1580
  });
1586
1581
 
1587
- if (isDebugLogEnabled()) {
1582
+ if (isDebugLogEnabled() || isDiskAudit()) {
1588
1583
  for (let pathValue of changes) {
1589
-
1590
- auditLog("SEND VALUE", { path: pathValue.path, time: pathValue.time.time, watcher, nodeId: debugNodeId(watcher), transparent: pathValue.isTransparent, canGC: pathValue.canGCValue });
1584
+ auditLog("SEND VALUE", {
1585
+ path: pathValue.path,
1586
+ time: pathValue.time.time,
1587
+ watcher,
1588
+ nodeId: debugNodeId(watcher),
1589
+ targetNodeId: debugNodeId(watcher),
1590
+ targetNodeThreadId: debugNodeThread(watcher),
1591
+ transparent: pathValue.isTransparent,
1592
+ canGC: pathValue.canGCValue,
1593
+ });
1591
1594
  }
1592
1595
  }
1593
1596
  await PathValueController.nodes[watcher].forwardWrites(
@@ -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
  }
@@ -426,7 +426,7 @@ class SuppressionItem extends qreact.Component<{
426
426
  <Button
427
427
  hue={0}
428
428
  onClick={() => {
429
- if (!confirm(`Delete this suppression?`)) return;
429
+ if (!confirm(`Delete this suppression "${suppression.pattern}"?`)) return;
430
430
 
431
431
  Querysub.onCommitFinished(async () => {
432
432
  await this.manager.deleteSuppression(suppression.id);
@@ -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
  }>
@@ -57,7 +56,7 @@ export class LifeCycleEntryEditor extends qreact.Component<{
57
56
  <Button
58
57
  hue={0}
59
58
  onClick={() => {
60
- if (!confirm("Delete this entry?")) return;
59
+ if (!confirm(`Delete this entry "${entry.matchPattern}"?`)) return;
61
60
 
62
61
  let updatedLifeCycle = deepCloneJSON(lifeCycle);
63
62
  updatedLifeCycle.entries.splice(entryIndex, 1);
@@ -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"
@@ -18,11 +18,12 @@ export class LifeCycleInstanceTableView extends qreact.Component<{
18
18
  let entry = lifeCycle.entries.find(e => e.matchPattern === entryData.matchPattern);
19
19
  if (!entry) continue;
20
20
 
21
- let variables = getVariables(entry);
22
- for (let variable of variables) {
23
- allColumnKeys.add(variable.key);
24
- if (variable.title && !columnKeyToTitle.has(variable.key)) {
25
- columnKeyToTitle.set(variable.key, variable.title);
21
+ // ONLY variables, as the group by values will be the same for all entries in this instance!
22
+ for (let [key, value] of Object.entries(entry.variables)) {
23
+ let title = value.title || key;
24
+ allColumnKeys.add(key);
25
+ if (!columnKeyToTitle.has(key)) {
26
+ columnKeyToTitle.set(key, title);
26
27
  }
27
28
  }
28
29
  }
@@ -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={() => {
@@ -564,7 +564,13 @@ export function createLifeCycleSearch(
564
564
  }
565
565
  }
566
566
 
567
- sort(allInstances, x => -x.startTime);
567
+ let range = Querysub.localRead(() => getTimeRange());
568
+
569
+ if (range.searchFromStart) {
570
+ sort(allInstances, x => x.startTime);
571
+ } else {
572
+ sort(allInstances, x => -x.startTime);
573
+ }
568
574
 
569
575
  return allInstances;
570
576
  };