querysub 0.399.0 → 0.401.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.399.0",
3
+ "version": "0.401.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",
@@ -87,9 +87,6 @@ class PathValueControllerBase {
87
87
  }
88
88
  }
89
89
  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
90
 
94
91
  if (isCoreQuiet) {
95
92
  await pathValueCommitter.ingestRemoteValues({
@@ -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,9 +1579,8 @@ class PathWatcher {
1584
1579
  stripSource: !allowSource,
1585
1580
  });
1586
1581
 
1587
- if (isDebugLogEnabled()) {
1582
+ if (isDiskAudit()) {
1588
1583
  for (let pathValue of changes) {
1589
-
1590
1584
  auditLog("SEND VALUE", { path: pathValue.path, time: pathValue.time.time, watcher, nodeId: debugNodeId(watcher), transparent: pathValue.isTransparent, canGC: pathValue.canGCValue });
1591
1585
  }
1592
1586
  }
@@ -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);
@@ -57,7 +57,7 @@ export class LifeCycleEntryEditor extends qreact.Component<{
57
57
  <Button
58
58
  hue={0}
59
59
  onClick={() => {
60
- if (!confirm("Delete this entry?")) return;
60
+ if (!confirm(`Delete this entry "${entry.matchPattern}"?`)) return;
61
61
 
62
62
  let updatedLifeCycle = deepCloneJSON(lifeCycle);
63
63
  updatedLifeCycle.entries.splice(entryIndex, 1);
@@ -0,0 +1,62 @@
1
+ import { qreact } from "../../../4-dom/qreact";
2
+ import { Table } from "../../../5-diagnostics/Table";
3
+ import { formatValue } from "../../../5-diagnostics/GenericFormat";
4
+ import { LifeCycle, getVariables } from "./lifeCycles";
5
+ import { LifecycleInstance } from "./lifeCycleSearch";
6
+
7
+ export class LifeCycleInstanceTableView extends qreact.Component<{
8
+ lifeCycle: LifeCycle;
9
+ instance: LifecycleInstance;
10
+ }> {
11
+ render() {
12
+ let { lifeCycle, instance } = this.props;
13
+
14
+ let columnKeyToTitle = new Map<string, string>();
15
+ let allColumnKeys = new Set<string>();
16
+
17
+ for (let entryData of instance.entries) {
18
+ let entry = lifeCycle.entries.find(e => e.matchPattern === entryData.matchPattern);
19
+ if (!entry) continue;
20
+
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);
27
+ }
28
+ }
29
+ }
30
+
31
+ let rows = instance.entries.map((entryData) => {
32
+ let entry = lifeCycle.entries.find(e => e.matchPattern === entryData.matchPattern);
33
+ let entryTitle = entry && (entry.description || entry.matchPattern) || entryData.matchPattern;
34
+
35
+ let row: { entryTitle: string;[key: string]: unknown } = {
36
+ entryTitle: entryTitle,
37
+ };
38
+
39
+ if (entry) {
40
+ let variables = getVariables(entry);
41
+ for (let variable of variables) {
42
+ row[variable.key] = entryData.datum[variable.key];
43
+ }
44
+ }
45
+
46
+ return row;
47
+ });
48
+
49
+ let columns: any = {
50
+ entryTitle: { title: "Entry" },
51
+ };
52
+
53
+ for (let columnKey of allColumnKeys) {
54
+ columns[columnKey] = {
55
+ title: columnKeyToTitle.get(columnKey) || columnKey,
56
+ formatter: (value: unknown) => formatValue(value),
57
+ };
58
+ }
59
+
60
+ return <Table rows={rows} columns={columns} />;
61
+ }
62
+ }
@@ -1,7 +1,7 @@
1
1
  import { qreact } from "../../../4-dom/qreact";
2
2
  import { t } from "../../../2-proxy/schema2";
3
3
  import { css } from "typesafecss";
4
- import { deepCloneJSON, nextId } from "socket-function/src/misc";
4
+ import { deepCloneJSON, nextId, sort } from "socket-function/src/misc";
5
5
  import { Querysub } from "../../../4-querysub/QuerysubController";
6
6
  import { InputLabel } from "../../../library-components/InputLabel";
7
7
  import { Button } from "../../../library-components/Button";
@@ -32,6 +32,7 @@ import { isPublic } from "../../../config";
32
32
  export let lifecycleIdURL = new URLParam("lifecycleid", "");
33
33
  export let limitURL = new URLParam("lifecyclelimit", 16);
34
34
  export let additionalSearchURL = new URLParam("lifecyclesearch", "");
35
+ export let lifecycleTableViewURL = new URLParam("lifecycletable", false);
35
36
 
36
37
  export class LifeCyclePage extends qreact.Component {
37
38
  controller = LifeCyclesController(SocketFunction.browserNodeId());
@@ -69,9 +70,10 @@ export class LifeCyclePage extends qreact.Component {
69
70
  <div>Loading...</div>
70
71
  </div>;
71
72
  }
72
- let sortedLifeCycles = deepCloneJSON(lifeCycles);
73
+ lifeCycles = deepCloneJSON(lifeCycles);
74
+ sort(lifeCycles, x => -x.id.split("_")[0]);
73
75
 
74
- let filteredLifeCycles = sortedLifeCycles.filter(x =>
76
+ let filteredLifeCycles = lifeCycles.filter(x =>
75
77
  matchFilter({ value: this.state.filterText }, JSON.stringify(x))
76
78
  );
77
79
 
@@ -83,6 +85,7 @@ export class LifeCyclePage extends qreact.Component {
83
85
  filteredLifeCycles = filteredLifeCycles.filter(lc => lc.id === this.state.searchingLifeCycleId);
84
86
  }
85
87
 
88
+
86
89
  return <div className={css.vbox(16).pad2(16).fillWidth}>
87
90
  <style>{`
88
91
  .LifeCycleInstanceRenderer:has(.LifeCycleEntryEditor:hover) {
@@ -112,6 +115,7 @@ export class LifeCyclePage extends qreact.Component {
112
115
  fillWidth
113
116
  onKeyDown={(e) => {
114
117
  if (e.key === "Enter" && lifecycleIdURL.value) {
118
+ additionalSearchURL.value = e.currentTarget.value;
115
119
  void this.searchLifeCycle(lifecycleIdURL.value);
116
120
  }
117
121
  }}
@@ -149,7 +153,7 @@ export class LifeCyclePage extends qreact.Component {
149
153
  }}
150
154
  className={css.width(500)}
151
155
  />
152
- <span>({filteredLifeCycles.length} / {sortedLifeCycles.length})</span>
156
+ <span>({filteredLifeCycles.length} / {lifeCycles.length})</span>
153
157
  {this.state.searchingLifeCycleId && (
154
158
  <Button
155
159
  hue={120}
@@ -264,7 +268,7 @@ export class LifeCyclePage extends qreact.Component {
264
268
  )}
265
269
 
266
270
  {this.state.lifecycleInstances.length > 0 && (() => {
267
- let searchedLifeCycle = sortedLifeCycles.find(lc => lc.id === this.state.searchingLifeCycleId);
271
+ let searchedLifeCycle = lifeCycles.find(lc => lc.id === this.state.searchingLifeCycleId);
268
272
  if (!searchedLifeCycle) return <div>Cannot find life cycle instance {this.state.searchingLifeCycleId}</div>;
269
273
 
270
274
  let lc = searchedLifeCycle;
@@ -13,9 +13,10 @@ import { niceStringify } from "../../../niceStringify";
13
13
  import { getPathStr } from "../../../path";
14
14
  import { MachineThreadInfo } from "../../MachineThreadInfo";
15
15
  import { LifeCycleEntryEditor } from "./LifeCycleEntryEditor";
16
- import { lifecycleIdURL } from "./LifeCyclePage";
16
+ import { lifecycleIdURL, lifecycleTableViewURL } from "./LifeCyclePage";
17
17
  import { LifecycleInstance } from "./lifeCycleSearch";
18
18
  import { LifeCycle, LifeCyclesController, LifeCycleEntry } from "./lifeCycles";
19
+ import { LifeCycleInstanceTableView } from "./LifeCycleInstanceTableView";
19
20
 
20
21
  export class LifeCycleRenderer extends qreact.Component<{
21
22
  lifeCycle: LifeCycle;
@@ -200,7 +201,7 @@ export class LifeCycleInstanceRenderer extends qreact.Component<{
200
201
  }
201
202
  title={statusTitle}
202
203
  onClick={(e) => {
203
- if ((e.target as HTMLElement).closest(".LifeCycleEntryEditor")) {
204
+ if ((e.target as HTMLElement).closest(".LifeCycleRenderer-contents")) {
204
205
  return;
205
206
  }
206
207
  this.state.expanded = !this.state.expanded;
@@ -270,19 +271,37 @@ export class LifeCycleInstanceRenderer extends qreact.Component<{
270
271
  </div>
271
272
 
272
273
  {this.state.expanded && (
273
- <div className={css.vbox(8)}>
274
- {instance.entries.map((entryData, idx) => {
275
- let entryIndex = lifeCycle.entries.findIndex(e => e.matchPattern === entryData.matchPattern);
276
- let entry = lifeCycle.entries[entryIndex];
277
- return <LifeCycleEntryEditor
278
- key={idx}
274
+ <div className={css.vbox(8) + "LifeCycleRenderer-contents"}>
275
+ <Button
276
+ hue={200}
277
+ onClick={() => {
278
+ lifecycleTableViewURL.value = !lifecycleTableViewURL.value;
279
+ }}
280
+ >
281
+ {lifecycleTableViewURL.value && "List View" || "Table View"}
282
+ </Button>
283
+
284
+ {lifecycleTableViewURL.value && (
285
+ <LifeCycleInstanceTableView
279
286
  lifeCycle={lifeCycle}
280
- entry={entry}
281
- entryIndex={entryIndex}
282
- defaultEditMode={false}
283
- datum={entryData.datum}
284
- />;
285
- })}
287
+ instance={instance}
288
+ />
289
+ ) || (
290
+ <div className={css.vbox(8)}>
291
+ {instance.entries.map((entryData, idx) => {
292
+ let entryIndex = lifeCycle.entries.findIndex(e => e.matchPattern === entryData.matchPattern);
293
+ let entry = lifeCycle.entries[entryIndex];
294
+ return <LifeCycleEntryEditor
295
+ key={idx}
296
+ lifeCycle={lifeCycle}
297
+ entry={entry}
298
+ entryIndex={entryIndex}
299
+ defaultEditMode={false}
300
+ datum={entryData.datum}
301
+ />;
302
+ })}
303
+ </div>
304
+ )}
286
305
  </div>
287
306
  )}
288
307
  </div>;
@@ -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
  };