querysub 0.466.0 → 0.468.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.466.0",
3
+ "version": "0.468.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",
@@ -12,6 +12,9 @@ import { setFlag } from "socket-function/require/compileFlags";
12
12
 
13
13
  import cbor from "cbor-x";
14
14
  import { atomicObjectWrite, atomicObjectWriteNoFreeze, doAtomicWrites } from "../2-proxy/PathValueProxyWatcher";
15
+ import { getOwnThreadId } from "../-a-auth/certs";
16
+
17
+ const LAZY_INSTANCE_MARKER = Symbol("PathValueSerializer.lazyInstance");
15
18
  import { formatNumber, formatPercent, formatTime } from "socket-function/src/formatting/format";
16
19
  setFlag(require, "cbor-x", "allowclient", true);
17
20
 
@@ -989,11 +992,26 @@ class PathValueSerializer {
989
992
  // NOTE: Using an object makes garbage collection MUCH easier, basically eliminating leaks (and...
990
993
  // it should be fairly fast? We create a Buffer anyways... which is probably a lot slower than
991
994
  // creating an object).
992
- let lazyInstance = { call_PathValueSerializer_getPathValue_toGetThisValue: true };
995
+ // The symbol marker is non-enumerable to JSON/cbor, so a round-tripped lazyInstance will be missing it
996
+ // lets the throw sites distinguish "stale ref / cross-instance" from "serialized through JSON".
997
+ let lazyInstance: { [k: string]: unknown } = {
998
+ call_PathValueSerializer_getPathValue_toGetThisValue: true,
999
+ lazyCreatedAt: Date.now(),
1000
+ lazyCreatedByThreadId: getOwnThreadId(),
1001
+ };
1002
+ lazyInstance[LAZY_INSTANCE_MARKER as unknown as string] = true;
993
1003
  this.lazyValues.set(lazyInstance, buf);
994
1004
  return lazyInstance;
995
1005
  }
996
1006
 
1007
+ private describeMissingLazy(pathValue: PathValue): string {
1008
+ let value = pathValue.value as { [k: string]: unknown } | undefined;
1009
+ let hasMarker = !!value && (value as { [k: symbol]: unknown })[LAZY_INSTANCE_MARKER] === true;
1010
+ let createdAt = value && value.lazyCreatedAt;
1011
+ let createdBy = value && value.lazyCreatedByThreadId;
1012
+ return `Path: ${pathValue.path}, time: ${JSON.stringify(pathValue.time)}, currentThreadId: ${getOwnThreadId()}, hasSymbolMarker: ${hasMarker}, lazyCreatedAt: ${createdAt}, lazyCreatedByThreadId: ${createdBy}`;
1013
+ }
1014
+
997
1015
  public getPathValue(pathValue: PathValue | undefined, noMutate?: "noMutate"): unknown {
998
1016
  if (!pathValue) return undefined;
999
1017
  if (pathValue.isValueLazy) {
@@ -1001,7 +1019,7 @@ class PathValueSerializer {
1001
1019
  if (!buffer) {
1002
1020
  debugbreak(2);
1003
1021
  debugger;
1004
- throw new Error(`(getPathValue) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)})`);
1022
+ throw new Error(`(getPathValue) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)}). ${this.describeMissingLazy(pathValue)}`);
1005
1023
  }
1006
1024
  let newValue = recursiveFreeze(cbor.decode(buffer));
1007
1025
  if (!noMutate && !pathValue.isValueLazy) {
@@ -1031,7 +1049,7 @@ class PathValueSerializer {
1031
1049
  // NOTE: Did you pass a raw PathValue and then try to use PathValueSerializer with it?
1032
1050
  // - Instead you should pass a buffer serialized with pathValueSerializer.serialize and
1033
1051
  // deserialized with pathValueSerializer.deserialize.
1034
- throw new Error(`(getPathValueOrBuffer) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)})`);
1052
+ throw new Error(`(getPathValueOrBuffer) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)}). ${this.describeMissingLazy(pathValue)}`);
1035
1053
  }
1036
1054
  return buffer;
1037
1055
  }
@@ -1044,7 +1062,7 @@ class PathValueSerializer {
1044
1062
  if (!buffer) {
1045
1063
  debugbreak(2);
1046
1064
  debugger;
1047
- throw new Error(`(getBuffer) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)})`);
1065
+ throw new Error(`(getBuffer) Expected lazy value to have a buffer, but it didn't. Lazy ref has a typeof ${typeof pathValue.value} (${String(pathValue.value)}). ${this.describeMissingLazy(pathValue)}`);
1048
1066
  }
1049
1067
  return buffer;
1050
1068
  }
@@ -27,9 +27,9 @@ export class StatWarning extends qreact.Component<{
27
27
  <span>Threshold exceeded: {this.props.threshold}</span>
28
28
  </div>
29
29
  <div className={restClass}>
30
- <span>{this.props.children}</span>
31
- <span> -</span>
32
30
  <span>{this.props.name}</span>
31
+ <span> -</span>
32
+ <span>{this.props.children}</span>
33
33
  {actions.map(action =>
34
34
  <div
35
35
  className={css.button.pad2(6, 2).background("hsla(0, 0%, 100%, 0.15)")}
@@ -40,7 +40,7 @@ type StatInfo = {
40
40
  isOverDiet: boolean;
41
41
  };
42
42
 
43
- export class StatsHeader extends qreact.Component<{ getStats: () => StatDefinition[] }> {
43
+ export class StatsHeader extends qreact.Component<{ getStats: () => StatDefinition[]; onlyWarnings?: boolean }> {
44
44
  state = t.state({
45
45
  expanded: t.lookup({ open: t.booleanOptional }),
46
46
  nowTick: t.number,
@@ -190,6 +190,13 @@ export class StatsHeader extends qreact.Component<{ getStats: () => StatDefiniti
190
190
  info.isOverDiet && !(info.stat.category in this.state.expanded)
191
191
  );
192
192
 
193
+ if (this.props.onlyWarnings) {
194
+ if (activeWarnings.length === 0) return undefined;
195
+ return <div className={css.vbox(4)}>
196
+ {activeWarnings.map(info => this.renderWarning(info))}
197
+ </div>;
198
+ }
199
+
193
200
  return <div className={css.vbox(4)}>
194
201
  <div className={css.hbox(2).wrap}>
195
202
  {categories.map(category => {
@@ -396,13 +396,16 @@ async function auditAuthority(nodeId: string, pathsToAudit: { path: string }[],
396
396
  }
397
397
 
398
398
  if (valuesToRequest.length > 0) {
399
- let receivedValues = await PathAuditerController.nodes[nodeId].getPathValues(valuesToRequest);
400
- if (receivedValues.length > 0) {
401
- validStateComputer.ingestValuesAndValidStates({
402
- pathValues: receivedValues,
403
- parentSyncs: [],
404
- initialTriggers: { values: new Set(), parentPaths: new Set() },
405
- });
399
+ let receivedBuffers = await PathAuditerController.nodes[nodeId].getPathValues(valuesToRequest);
400
+ if (receivedBuffers.length > 0) {
401
+ let receivedValues = await pathValueSerializer.deserialize(receivedBuffers);
402
+ if (receivedValues.length > 0) {
403
+ validStateComputer.ingestValuesAndValidStates({
404
+ pathValues: receivedValues,
405
+ parentSyncs: [],
406
+ initialTriggers: { values: new Set(), parentPaths: new Set() },
407
+ });
408
+ }
406
409
  }
407
410
  }
408
411
 
@@ -456,7 +459,7 @@ class PathAuditerService {
456
459
  return results;
457
460
  }
458
461
 
459
- public async getPathValues(requests: PathTimeRequest[]): Promise<PathValue[]> {
462
+ public async getPathValues(requests: PathTimeRequest[]): Promise<Buffer[]> {
460
463
  let results: PathValue[] = [];
461
464
  for (let request of requests) {
462
465
  let value = authorityStorage.getValueAtOrBeforeTime(request.path, request.time);
@@ -464,7 +467,8 @@ class PathAuditerService {
464
467
  results.push(value);
465
468
  }
466
469
  }
467
- return results;
470
+ if (results.length === 0) return [];
471
+ return await pathValueSerializer.serialize(results);
468
472
  }
469
473
 
470
474
  public async ingestPathValues(serializedValues: Buffer[]): Promise<void> {