querysub 0.394.0 → 0.396.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.
Files changed (38) hide show
  1. package/.cursorrules +8 -0
  2. package/package.json +1 -1
  3. package/src/-a-archives/archivesJSONT.ts +71 -8
  4. package/src/-c-identity/IdentityController.ts +19 -1
  5. package/src/0-path-value-core/pathValueCore.ts +26 -7
  6. package/src/5-diagnostics/GenericFormat.tsx +1 -1
  7. package/src/deployManager/components/MachinesListPage.tsx +1 -2
  8. package/src/diagnostics/logs/IndexedLogs/BufferIndex.ts +12 -3
  9. package/src/diagnostics/logs/IndexedLogs/BufferIndexHelpers.ts +8 -3
  10. package/src/diagnostics/logs/IndexedLogs/BufferUnitIndex.ts +24 -9
  11. package/src/diagnostics/logs/IndexedLogs/BufferUnitSet.ts +0 -1
  12. package/src/diagnostics/logs/IndexedLogs/FindProgressTracker.ts +21 -5
  13. package/src/diagnostics/logs/IndexedLogs/IndexedLogs.ts +10 -4
  14. package/src/diagnostics/logs/IndexedLogs/LogViewer3.tsx +94 -124
  15. package/src/diagnostics/logs/IndexedLogs/RenderSearchStats.tsx +127 -0
  16. package/src/diagnostics/logs/IndexedLogs/bufferSearchFindMatcher.ts +4 -0
  17. package/src/diagnostics/logs/IndexedLogs/moveIndexLogsToPublic.ts +1 -1
  18. package/src/diagnostics/logs/TimeRangeSelector.tsx +11 -2
  19. package/src/diagnostics/logs/errorNotifications2/ErrorNotificationPage.tsx +1 -4
  20. package/src/diagnostics/logs/errorNotifications2/errorNotifications.ts +1 -1
  21. package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryEditor.tsx +358 -0
  22. package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleEntryReadMode.tsx +149 -0
  23. package/src/diagnostics/logs/lifeCycleAnalysis/LifeCyclePage.tsx +274 -0
  24. package/src/diagnostics/logs/lifeCycleAnalysis/LifeCycleRenderer.tsx +291 -0
  25. package/src/diagnostics/logs/lifeCycleAnalysis/NestedLifeCycleInfo.tsx +151 -0
  26. package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleMatching.ts +49 -0
  27. package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycleSearch.tsx +580 -0
  28. package/src/diagnostics/logs/lifeCycleAnalysis/lifeCycles.tsx +128 -90
  29. package/src/diagnostics/managementPages.tsx +17 -1
  30. package/src/diagnostics/misc-pages/ArchiveViewer.tsx +4 -3
  31. package/src/diagnostics/misc-pages/ArchiveViewerTree.tsx +6 -3
  32. package/src/functional/{limitProcessing.ts → throttleProcessing.ts} +1 -1
  33. package/src/library-components/StartEllipsis.tsx +13 -0
  34. package/src/misc.ts +4 -0
  35. package/tempnotes.txt +0 -0
  36. package/src/diagnostics/logs/lifeCycleAnalysis/test.wat +0 -106
  37. package/src/diagnostics/logs/lifeCycleAnalysis/test.wat.d.ts +0 -2
  38. package/src/diagnostics/logs/lifeCycleAnalysis/testHoist.ts +0 -5
@@ -0,0 +1,151 @@
1
+ import { SocketFunction } from "socket-function/SocketFunction";
2
+ import { css } from "typesafecss";
3
+ import { t } from "../../../2-proxy/schema2";
4
+ import { qreact } from "../../../4-dom/qreact";
5
+ import { formatValue } from "../../../5-diagnostics/GenericFormat";
6
+ import { Button } from "../../../library-components/Button";
7
+ import { niceStringify } from "../../../niceStringify";
8
+ import { LogDatum } from "../diskLogger";
9
+ import { LifeCycle, LifeCyclesController, getVariables } from "./lifeCycles";
10
+ import { createLifeCycleSearch, LifecycleInstance } from "./lifeCycleSearch";
11
+ import { IndexedLogResults } from "../IndexedLogs/BufferIndexHelpers";
12
+ import { formatSearchString } from "../IndexedLogs/LogViewerParams";
13
+ import { getPathStr, getPathStr2 } from "../../../path";
14
+
15
+ export class NestedLifeCycleInfo extends qreact.Component<{
16
+ keyName: string;
17
+ value: unknown;
18
+ aliases: string[];
19
+ currentLifeCycleId: string;
20
+ }> {
21
+ state = t.state({
22
+ searchingLifeCycleId: t.atomic<string | undefined>(undefined),
23
+ phase1Results: t.atomic<LogDatum[]>([]),
24
+ phase1InvalidResults: t.atomic<Array<{ datum: LogDatum; missingKeys: string[] }>>([]),
25
+ phase1Stats: t.atomic<IndexedLogResults | undefined>(undefined),
26
+ phase1Searching: t.boolean(false),
27
+ phase2Results: t.atomic<LogDatum[]>([]),
28
+ phase2Stats: t.atomic<IndexedLogResults | undefined>(undefined),
29
+ phase2Searching: t.boolean(false),
30
+ phase2HitLimit: t.boolean(false),
31
+ lifecycleInstances: t.atomic<LifecycleInstance[]>([]),
32
+ });
33
+
34
+ controller = LifeCyclesController(SocketFunction.browserNodeId());
35
+ search = createLifeCycleSearch(this);
36
+
37
+ render() {
38
+ let lifeCycles = this.controller.getLifeCycles();
39
+ if (!lifeCycles) return null;
40
+
41
+ let { keyName, value, aliases, currentLifeCycleId } = this.props;
42
+
43
+ let allKeysToMatch = [keyName, ...aliases].filter(x => !["__threadId", "__machineId"].includes(x));
44
+ let matchingLifeCycles: Array<{ lifecycle: LifeCycle; matchedKey: string }> = [];
45
+
46
+ for (let lifecycle of lifeCycles) {
47
+ if (lifecycle.id === currentLifeCycleId) continue;
48
+
49
+ let matchedKey: string | undefined = undefined;
50
+ for (let entry of lifecycle.entries) {
51
+ for (let groupByKey of entry.groupByKeys) {
52
+ if (allKeysToMatch.includes(groupByKey.ourKey)) {
53
+ matchedKey = groupByKey.ourKey;
54
+ break;
55
+ }
56
+ }
57
+ if (matchedKey !== undefined) break;
58
+ }
59
+
60
+ if (matchedKey !== undefined) {
61
+ matchingLifeCycles.push({ lifecycle, matchedKey });
62
+ }
63
+ }
64
+
65
+ if (matchingLifeCycles.length === 0) return null;
66
+
67
+ return <>
68
+ {matchingLifeCycles.map(({ lifecycle, matchedKey }) => {
69
+ let isSearchingThis = this.state.searchingLifeCycleId === lifecycle.id;
70
+ let isSearching = isSearchingThis && (this.state.phase1Searching || this.state.phase2Searching);
71
+ let hasSearched = isSearchingThis && !isSearching;
72
+
73
+ let instances = hasSearched && this.state.lifecycleInstances.filter(inst =>
74
+ inst.keys.some(k => k.key === matchedKey && k.value === value)
75
+ ) || [];
76
+ let hasResults = instances.length > 0;
77
+
78
+ let progressText = "";
79
+ if (isSearching && isSearchingThis) {
80
+ let parts: string[] = [];
81
+
82
+ if (this.state.phase1Searching || this.state.phase1Stats) {
83
+ let stats = this.state.phase1Stats;
84
+ let blocksScanned = stats && (stats.localFilesSearched + stats.backblazeFilesSearched) || 0;
85
+ let resultsCount = this.state.phase1Results.length;
86
+ parts.push(`${blocksScanned} > ${resultsCount}`);
87
+ }
88
+
89
+ if (this.state.phase2Searching) {
90
+ let stats = this.state.phase2Stats;
91
+ let blocksScanned = stats && (stats.localFilesSearched + stats.backblazeFilesSearched) || 0;
92
+ let resultsCount = this.state.phase2Results.length;
93
+ parts.push(`${blocksScanned} > ${resultsCount}`);
94
+ }
95
+
96
+ progressText = parts.length > 0 && `(${parts.join(" | ")})` || "(...)";
97
+ }
98
+
99
+ return <>
100
+ <Button
101
+ hue={180}
102
+ onClick={() => {
103
+ void this.search.searchLifeCycle({
104
+ lifeCycleId: lifecycle.id,
105
+ limit: 10,
106
+ additionalSearch: formatSearchString({ [matchedKey]: value })
107
+ });
108
+ }}
109
+ >
110
+ {lifecycle.title} {isSearching && "⏳" || ""} {progressText} {hasSearched && `(${instances.length})` || ""}
111
+ </Button>
112
+ {hasSearched && !hasResults && (
113
+ <div className={css.pad2(4).colorhsl(0, 0, 50)}>No results found</div>
114
+ )}
115
+ {hasResults && (() => {
116
+ let firstInstance = instances[0];
117
+ let totalCount = instances.length;
118
+ let hitLimit = totalCount >= 10;
119
+
120
+ let keys = lifecycle.entries.map(x => x.groupByKeys.map(y => y.ourKey).concat(Object.keys(x.variables))).flat();
121
+
122
+ function valueHash(key: string, value: unknown) {
123
+ return getPathStr2(key, String(value));
124
+ }
125
+ let values = new Map<string, { key: string; value: unknown }>();
126
+ for (let entry of firstInstance.entries) {
127
+ for (let [key, value] of Object.entries(entry.datum)) {
128
+ if (!keys.includes(key)) continue;
129
+ if (key === matchedKey) continue;
130
+ if (["__threadId", "__machineId"].includes(key)) continue;
131
+ values.set(valueHash(key, value), { key, value });
132
+ }
133
+ }
134
+
135
+ return <>
136
+ <div className={css.hbox(4)}>
137
+ {hitLimit && <span className={css.colorhsl(30, 80, 40).boldStyle}>(hit limit!)</span>}
138
+ </div>
139
+ {Array.from(values.values()).map(({ key, value }, idx) => (
140
+ <div key={idx} className={css.hbox(4)}>
141
+ <span className={css.colorhsl(200, 50, 60).boldStyle}>{key}:</span>
142
+ <span className={css.colorhsl(0, 0, 50)}>{niceStringify(value)}</span>
143
+ </div>
144
+ ))}
145
+ </>;
146
+ })()}
147
+ </>;
148
+ })}
149
+ </>;
150
+ }
151
+ }
@@ -0,0 +1,49 @@
1
+ import { LifeCycle, LifeCycleEntry } from "./lifeCycles";
2
+ import { LogDatum } from "../diskLogger";
3
+ import { createMatchesPatternCached } from "../IndexedLogs/bufferSearchFindMatcher";
4
+
5
+ export type LifecycleMatch = {
6
+ lifecycle: LifeCycle;
7
+ entry: LifeCycleEntry;
8
+ datum: Record<string, unknown>;
9
+ };
10
+
11
+ export function getLifecycleMatchesForDatum(
12
+ lifecycles: LifeCycle[],
13
+ datum: LogDatum
14
+ ): LifecycleMatch[] {
15
+ let matches: LifecycleMatch[] = [];
16
+
17
+ let matchStr = String(datum.param0);
18
+ let matchBuffer = Buffer.from(matchStr, "utf8");
19
+
20
+ for (let lifecycle of lifecycles) {
21
+ for (let entry of lifecycle.entries) {
22
+ let matcher = createMatchesPatternCached(entry.matchPattern);
23
+ if (!matcher(matchBuffer)) continue;
24
+
25
+ let extractedDatum: Record<string, unknown> = {};
26
+ let hasAllKeys = true;
27
+
28
+ for (let keyConfig of entry.groupByKeys) {
29
+ let keyToLookup = keyConfig.startKey || keyConfig.ourKey;
30
+ let value = datum[keyToLookup];
31
+ if (value === undefined) {
32
+ hasAllKeys = false;
33
+ break;
34
+ }
35
+ extractedDatum[keyConfig.ourKey] = value;
36
+ }
37
+
38
+ if (!hasAllKeys || entry.groupByKeys.length === 0) continue;
39
+
40
+ matches.push({
41
+ lifecycle,
42
+ entry,
43
+ datum: extractedDatum,
44
+ });
45
+ }
46
+ }
47
+
48
+ return matches;
49
+ }