@parca/profile 0.16.385 → 0.16.386
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/CHANGELOG.md +4 -0
- package/dist/ProfileExplorer/index.js +28 -14
- package/dist/ProfileSource.d.ts +2 -3
- package/dist/ProfileSource.js +14 -30
- package/package.json +4 -4
- package/src/ProfileExplorer/index.tsx +29 -23
- package/src/ProfileSource.tsx +19 -34
- package/src/__tests__/suffix_params.test.ts +1 -6
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.16.386](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.385...@parca/profile@0.16.386) (2024-06-06)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
6
10
|
## [0.16.385](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.384...@parca/profile@0.16.385) (2024-06-05)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -66,30 +66,32 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
66
66
|
}
|
|
67
67
|
}, [profileTypesError, onError]);
|
|
68
68
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
69
|
-
let { from_a, to_a,
|
|
69
|
+
let { from_a, to_a, merge_from_a, merge_to_a, time_selection_a, compare_a, from_b, to_b, merge_from_b, merge_to_b, time_selection_b, compare_b, filter_by_function, dashboard_items, } = queryParams;
|
|
70
70
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
71
71
|
const expression_a = getExpressionAsAString(queryParams.expression_a);
|
|
72
72
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
73
73
|
const expression_b = getExpressionAsAString(queryParams.expression_b);
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
75
|
+
const selection_a = getExpressionAsAString(queryParams.selection_a);
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
77
|
+
const selection_b = getExpressionAsAString(queryParams.selection_b);
|
|
74
78
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
75
79
|
const [profileA, setProfileA] = useState(null);
|
|
76
80
|
const [profileB, setProfileB] = useState(null);
|
|
77
81
|
useEffect(() => {
|
|
78
82
|
const mergeFrom = merge_from_a ?? undefined;
|
|
79
83
|
const mergeTo = merge_to_a ?? undefined;
|
|
80
|
-
const
|
|
81
|
-
const profileA = ProfileSelectionFromParams(expression_a, from_a, to_a, mergeFrom, mergeTo, labels, filter_by_function);
|
|
84
|
+
const profileA = ProfileSelectionFromParams(mergeFrom, mergeTo, selection_a, filter_by_function);
|
|
82
85
|
setProfileA(profileA);
|
|
83
86
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
84
|
-
}, [
|
|
87
|
+
}, [merge_from_a, merge_to_a, selection_a, filter_by_function]);
|
|
85
88
|
useEffect(() => {
|
|
86
89
|
const mergeFrom = merge_from_b ?? undefined;
|
|
87
90
|
const mergeTo = merge_to_b ?? undefined;
|
|
88
|
-
const
|
|
89
|
-
const profileB = ProfileSelectionFromParams(expression_b, from_b, to_b, mergeFrom, mergeTo, labels, filter_by_function);
|
|
91
|
+
const profileB = ProfileSelectionFromParams(mergeFrom, mergeTo, selection_b, filter_by_function);
|
|
90
92
|
setProfileB(profileB);
|
|
91
93
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
92
|
-
}, [
|
|
94
|
+
}, [merge_from_b, merge_to_b, selection_b, filter_by_function]);
|
|
93
95
|
if (profileTypesLoading) {
|
|
94
96
|
return _jsx(_Fragment, { children: loader });
|
|
95
97
|
}
|
|
@@ -112,7 +114,9 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
112
114
|
queryParams.expression_b = expression_b;
|
|
113
115
|
const selectProfile = (p, suffix) => {
|
|
114
116
|
queryParams.expression_a = encodeURIComponent(queryParams.expression_a);
|
|
117
|
+
queryParams.selection_a = encodeURIComponent(queryParams.selection_a);
|
|
115
118
|
queryParams.expression_b = encodeURIComponent(queryParams.expression_b);
|
|
119
|
+
queryParams.selection_b = encodeURIComponent(queryParams.selection_b);
|
|
116
120
|
return navigateTo('/', {
|
|
117
121
|
...queryParams,
|
|
118
122
|
...SuffixParams(p.HistoryParams(), suffix),
|
|
@@ -130,13 +134,16 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
130
134
|
from: parseInt(from_a),
|
|
131
135
|
to: parseInt(to_a),
|
|
132
136
|
timeSelection: time_selection_a,
|
|
133
|
-
profile_name: profile_name_a,
|
|
134
137
|
};
|
|
135
138
|
// Show the SingleProfileExplorer when not comparing
|
|
136
139
|
if (compare_a !== 'true' && compare_b !== 'true') {
|
|
137
140
|
const selectQuery = (q) => {
|
|
138
141
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
139
|
-
? {
|
|
142
|
+
? {
|
|
143
|
+
merge_from_a: q.mergeFrom,
|
|
144
|
+
merge_to_a: q.mergeTo,
|
|
145
|
+
selection_a: encodeURIComponent(q.expression),
|
|
146
|
+
}
|
|
140
147
|
: {};
|
|
141
148
|
return navigateTo('/',
|
|
142
149
|
// Filtering the _a suffix causes us to reset potential profile
|
|
@@ -168,13 +175,11 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
168
175
|
from_a: queryA.from.toString(),
|
|
169
176
|
to_a: queryA.to.toString(),
|
|
170
177
|
time_selection_a: queryA.timeSelection,
|
|
171
|
-
profile_name_a: queryA.profile_name,
|
|
172
178
|
compare_b: 'true',
|
|
173
179
|
expression_b: encodeURIComponent(queryA.expression),
|
|
174
180
|
from_b: queryA.from.toString(),
|
|
175
181
|
to_b: queryA.to.toString(),
|
|
176
182
|
time_selection_b: queryA.timeSelection,
|
|
177
|
-
profile_name_b: queryA.profile_name,
|
|
178
183
|
};
|
|
179
184
|
if (profileA != null) {
|
|
180
185
|
compareQuery = {
|
|
@@ -195,11 +200,14 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
195
200
|
from: parseInt(from_b),
|
|
196
201
|
to: parseInt(to_b),
|
|
197
202
|
timeSelection: time_selection_b,
|
|
198
|
-
profile_name: profile_name_b,
|
|
199
203
|
};
|
|
200
204
|
const selectQueryA = (q) => {
|
|
201
205
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
202
|
-
? {
|
|
206
|
+
? {
|
|
207
|
+
merge_from_a: q.mergeFrom,
|
|
208
|
+
merge_to_a: q.mergeTo,
|
|
209
|
+
selection_a: encodeURIComponent(q.expression),
|
|
210
|
+
}
|
|
203
211
|
: {};
|
|
204
212
|
return navigateTo('/',
|
|
205
213
|
// Filtering the _a suffix causes us to reset potential profile
|
|
@@ -210,6 +218,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
210
218
|
compare_a: 'true',
|
|
211
219
|
expression_a: encodeURIComponent(q.expression),
|
|
212
220
|
expression_b: encodeURIComponent(expression_b),
|
|
221
|
+
selection_b: encodeURIComponent(selection_b),
|
|
213
222
|
from_a: q.from.toString(),
|
|
214
223
|
to_a: q.to.toString(),
|
|
215
224
|
time_selection_a: q.timeSelection,
|
|
@@ -221,7 +230,11 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
221
230
|
};
|
|
222
231
|
const selectQueryB = (q) => {
|
|
223
232
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
224
|
-
? {
|
|
233
|
+
? {
|
|
234
|
+
merge_from_b: q.mergeFrom,
|
|
235
|
+
merge_to_b: q.mergeTo,
|
|
236
|
+
selection_b: encodeURIComponent(q.expression),
|
|
237
|
+
}
|
|
225
238
|
: {};
|
|
226
239
|
return navigateTo('/',
|
|
227
240
|
// Filtering the _b suffix causes us to reset potential profile
|
|
@@ -232,6 +245,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
232
245
|
compare_b: 'true',
|
|
233
246
|
expression_b: encodeURIComponent(q.expression),
|
|
234
247
|
expression_a: encodeURIComponent(expression_a),
|
|
248
|
+
selection_a: encodeURIComponent(selection_a),
|
|
235
249
|
from_b: q.from.toString(),
|
|
236
250
|
to_b: q.to.toString(),
|
|
237
251
|
time_selection_b: q.timeSelection,
|
package/dist/ProfileSource.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
2
|
+
import { ProfileDiffSelection, QueryRequest } from '@parca/client';
|
|
3
3
|
import { ProfileType, Query } from '@parca/parser';
|
|
4
4
|
export interface ProfileSource {
|
|
5
5
|
QueryRequest: () => QueryRequest;
|
|
@@ -23,8 +23,7 @@ export declare function SuffixParams(params: {
|
|
|
23
23
|
}, suffix: string): {
|
|
24
24
|
[key: string]: any;
|
|
25
25
|
};
|
|
26
|
-
export declare function
|
|
27
|
-
export declare function ProfileSelectionFromParams(expression: string | undefined, from: string | undefined, to: string | undefined, mergeFrom: string | undefined, mergeTo: string | undefined, labels: string[], filterQuery?: string): ProfileSelection | null;
|
|
26
|
+
export declare function ProfileSelectionFromParams(mergeFrom: string | undefined, mergeTo: string | undefined, selection: string | undefined, filterQuery?: string): ProfileSelection | null;
|
|
28
27
|
export declare class MergedProfileSelection implements ProfileSelection {
|
|
29
28
|
mergeFrom: number;
|
|
30
29
|
mergeTo: number;
|
package/dist/ProfileSource.js
CHANGED
|
@@ -12,7 +12,7 @@ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
import { ProfileDiffSelection_Mode, QueryRequest_Mode, QueryRequest_ReportType, Timestamp, } from '@parca/client';
|
|
15
|
-
import { ProfileType, Query } from '@parca/parser';
|
|
15
|
+
import { NewParser, ProfileType, Query } from '@parca/parser';
|
|
16
16
|
import { formatDate } from '@parca/utilities';
|
|
17
17
|
const timeFormat = (timezone) => {
|
|
18
18
|
if (timezone !== undefined) {
|
|
@@ -30,34 +30,20 @@ export function ParamsString(params) {
|
|
|
30
30
|
export function SuffixParams(params, suffix) {
|
|
31
31
|
return Object.fromEntries(Object.entries(params).map(([key, value]) => [`${key}${suffix}`, value]));
|
|
32
32
|
}
|
|
33
|
-
export function
|
|
34
|
-
|
|
35
|
-
.filter(str => str !== '')
|
|
36
|
-
.map(function (labelString) {
|
|
37
|
-
const parts = labelString.split('=', 2);
|
|
38
|
-
return { name: parts[0], value: parts[1] };
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
export function ProfileSelectionFromParams(expression, from, to, mergeFrom, mergeTo, labels, filterQuery) {
|
|
42
|
-
if (from !== undefined &&
|
|
43
|
-
to !== undefined &&
|
|
44
|
-
mergeFrom !== undefined &&
|
|
33
|
+
export function ProfileSelectionFromParams(mergeFrom, mergeTo, selection, filterQuery) {
|
|
34
|
+
if (mergeFrom !== undefined &&
|
|
45
35
|
mergeTo !== undefined &&
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
query = newQuery;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
36
|
+
selection !== undefined &&
|
|
37
|
+
selection !== '') {
|
|
38
|
+
const p = NewParser();
|
|
39
|
+
p.save();
|
|
40
|
+
const { successfulParse } = Query.tryParse(p, selection);
|
|
41
|
+
if (!successfulParse) {
|
|
42
|
+
console.log('Failed to parse selected query.');
|
|
43
|
+
console.log(selection);
|
|
44
|
+
return null;
|
|
59
45
|
}
|
|
60
|
-
return new MergedProfileSelection(parseInt(mergeFrom), parseInt(mergeTo),
|
|
46
|
+
return new MergedProfileSelection(parseInt(mergeFrom), parseInt(mergeTo), Query.parse(selection), filterQuery);
|
|
61
47
|
}
|
|
62
48
|
return null;
|
|
63
49
|
}
|
|
@@ -76,9 +62,7 @@ export class MergedProfileSelection {
|
|
|
76
62
|
return {
|
|
77
63
|
merge_from: this.mergeFrom.toString(),
|
|
78
64
|
merge_to: this.mergeTo.toString(),
|
|
79
|
-
|
|
80
|
-
profile_name: this.ProfileName(),
|
|
81
|
-
labels: this.query.matchers.map(m => `${m.key}=${encodeURIComponent(m.value)}`),
|
|
65
|
+
selection: encodeURIComponent(this.query.toString()),
|
|
82
66
|
};
|
|
83
67
|
}
|
|
84
68
|
Type() {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.386",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@headlessui/react": "^1.7.19",
|
|
7
7
|
"@iconify/react": "^4.0.0",
|
|
8
8
|
"@parca/client": "0.16.117",
|
|
9
|
-
"@parca/components": "0.16.
|
|
9
|
+
"@parca/components": "0.16.282",
|
|
10
10
|
"@parca/dynamicsize": "0.16.65",
|
|
11
11
|
"@parca/hooks": "0.0.60",
|
|
12
12
|
"@parca/icons": "0.16.69",
|
|
13
|
-
"@parca/parser": "0.16.
|
|
13
|
+
"@parca/parser": "0.16.75",
|
|
14
14
|
"@parca/store": "0.16.149",
|
|
15
15
|
"@parca/utilities": "0.0.77",
|
|
16
16
|
"@popperjs/core": "^2.11.8",
|
|
@@ -71,5 +71,5 @@
|
|
|
71
71
|
"access": "public",
|
|
72
72
|
"registry": "https://registry.npmjs.org/"
|
|
73
73
|
},
|
|
74
|
-
"gitHead": "
|
|
74
|
+
"gitHead": "a1ab45b0895ab2b3b5d67fdcf33123199dc93c5f"
|
|
75
75
|
}
|
|
@@ -116,16 +116,12 @@ const ProfileExplorerApp = ({
|
|
|
116
116
|
let {
|
|
117
117
|
from_a,
|
|
118
118
|
to_a,
|
|
119
|
-
profile_name_a,
|
|
120
|
-
labels_a,
|
|
121
119
|
merge_from_a,
|
|
122
120
|
merge_to_a,
|
|
123
121
|
time_selection_a,
|
|
124
122
|
compare_a,
|
|
125
123
|
from_b,
|
|
126
124
|
to_b,
|
|
127
|
-
profile_name_b,
|
|
128
|
-
labels_b,
|
|
129
125
|
merge_from_b,
|
|
130
126
|
merge_to_b,
|
|
131
127
|
time_selection_b,
|
|
@@ -140,6 +136,12 @@ const ProfileExplorerApp = ({
|
|
|
140
136
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
141
137
|
const expression_b = getExpressionAsAString(queryParams.expression_b);
|
|
142
138
|
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
140
|
+
const selection_a = getExpressionAsAString(queryParams.selection_a);
|
|
141
|
+
|
|
142
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
143
|
+
const selection_b = getExpressionAsAString(queryParams.selection_b);
|
|
144
|
+
|
|
143
145
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
144
146
|
const [profileA, setProfileA] = useState<ProfileSelection | null>(null);
|
|
145
147
|
const [profileB, setProfileB] = useState<ProfileSelection | null>(null);
|
|
@@ -147,38 +149,30 @@ const ProfileExplorerApp = ({
|
|
|
147
149
|
useEffect(() => {
|
|
148
150
|
const mergeFrom = merge_from_a ?? undefined;
|
|
149
151
|
const mergeTo = merge_to_a ?? undefined;
|
|
150
|
-
const labels = typeof labels_a === 'string' ? [labels_a] : (labels_a as string[]) ?? [''];
|
|
151
152
|
const profileA = ProfileSelectionFromParams(
|
|
152
|
-
expression_a,
|
|
153
|
-
from_a as string,
|
|
154
|
-
to_a as string,
|
|
155
153
|
mergeFrom as string,
|
|
156
154
|
mergeTo as string,
|
|
157
|
-
|
|
155
|
+
selection_a,
|
|
158
156
|
filter_by_function as string
|
|
159
157
|
);
|
|
160
158
|
|
|
161
159
|
setProfileA(profileA);
|
|
162
160
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
163
|
-
}, [
|
|
161
|
+
}, [merge_from_a, merge_to_a, selection_a, filter_by_function]);
|
|
164
162
|
|
|
165
163
|
useEffect(() => {
|
|
166
164
|
const mergeFrom = merge_from_b ?? undefined;
|
|
167
165
|
const mergeTo = merge_to_b ?? undefined;
|
|
168
|
-
const labels = typeof labels_b === 'string' ? [labels_b] : (labels_b as string[]) ?? [''];
|
|
169
166
|
const profileB = ProfileSelectionFromParams(
|
|
170
|
-
expression_b,
|
|
171
|
-
from_b as string,
|
|
172
|
-
to_b as string,
|
|
173
167
|
mergeFrom as string,
|
|
174
168
|
mergeTo as string,
|
|
175
|
-
|
|
169
|
+
selection_b,
|
|
176
170
|
filter_by_function as string
|
|
177
171
|
);
|
|
178
172
|
|
|
179
173
|
setProfileB(profileB);
|
|
180
174
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
181
|
-
}, [
|
|
175
|
+
}, [merge_from_b, merge_to_b, selection_b, filter_by_function]);
|
|
182
176
|
|
|
183
177
|
if (profileTypesLoading) {
|
|
184
178
|
return <>{loader}</>;
|
|
@@ -206,7 +200,9 @@ const ProfileExplorerApp = ({
|
|
|
206
200
|
|
|
207
201
|
const selectProfile = (p: ProfileSelection, suffix: string): void => {
|
|
208
202
|
queryParams.expression_a = encodeURIComponent(queryParams.expression_a);
|
|
203
|
+
queryParams.selection_a = encodeURIComponent(queryParams.selection_a);
|
|
209
204
|
queryParams.expression_b = encodeURIComponent(queryParams.expression_b);
|
|
205
|
+
queryParams.selection_b = encodeURIComponent(queryParams.selection_b);
|
|
210
206
|
return navigateTo('/', {
|
|
211
207
|
...queryParams,
|
|
212
208
|
...SuffixParams(p.HistoryParams(), suffix),
|
|
@@ -227,7 +223,6 @@ const ProfileExplorerApp = ({
|
|
|
227
223
|
from: parseInt(from_a as string),
|
|
228
224
|
to: parseInt(to_a as string),
|
|
229
225
|
timeSelection: time_selection_a as string,
|
|
230
|
-
profile_name: profile_name_a as string,
|
|
231
226
|
};
|
|
232
227
|
|
|
233
228
|
// Show the SingleProfileExplorer when not comparing
|
|
@@ -235,7 +230,11 @@ const ProfileExplorerApp = ({
|
|
|
235
230
|
const selectQuery = (q: QuerySelection): void => {
|
|
236
231
|
const mergeParams =
|
|
237
232
|
q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
238
|
-
? {
|
|
233
|
+
? {
|
|
234
|
+
merge_from_a: q.mergeFrom,
|
|
235
|
+
merge_to_a: q.mergeTo,
|
|
236
|
+
selection_a: encodeURIComponent(q.expression),
|
|
237
|
+
}
|
|
239
238
|
: {};
|
|
240
239
|
return navigateTo(
|
|
241
240
|
'/',
|
|
@@ -271,14 +270,12 @@ const ProfileExplorerApp = ({
|
|
|
271
270
|
from_a: queryA.from.toString(),
|
|
272
271
|
to_a: queryA.to.toString(),
|
|
273
272
|
time_selection_a: queryA.timeSelection,
|
|
274
|
-
profile_name_a: queryA.profile_name,
|
|
275
273
|
|
|
276
274
|
compare_b: 'true',
|
|
277
275
|
expression_b: encodeURIComponent(queryA.expression),
|
|
278
276
|
from_b: queryA.from.toString(),
|
|
279
277
|
to_b: queryA.to.toString(),
|
|
280
278
|
time_selection_b: queryA.timeSelection,
|
|
281
|
-
profile_name_b: queryA.profile_name,
|
|
282
279
|
};
|
|
283
280
|
|
|
284
281
|
if (profileA != null) {
|
|
@@ -313,13 +310,16 @@ const ProfileExplorerApp = ({
|
|
|
313
310
|
from: parseInt(from_b as string),
|
|
314
311
|
to: parseInt(to_b as string),
|
|
315
312
|
timeSelection: time_selection_b as string,
|
|
316
|
-
profile_name: profile_name_b as string,
|
|
317
313
|
};
|
|
318
314
|
|
|
319
315
|
const selectQueryA = (q: QuerySelection): void => {
|
|
320
316
|
const mergeParams =
|
|
321
317
|
q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
322
|
-
? {
|
|
318
|
+
? {
|
|
319
|
+
merge_from_a: q.mergeFrom,
|
|
320
|
+
merge_to_a: q.mergeTo,
|
|
321
|
+
selection_a: encodeURIComponent(q.expression),
|
|
322
|
+
}
|
|
323
323
|
: {};
|
|
324
324
|
return navigateTo(
|
|
325
325
|
'/',
|
|
@@ -331,6 +331,7 @@ const ProfileExplorerApp = ({
|
|
|
331
331
|
compare_a: 'true',
|
|
332
332
|
expression_a: encodeURIComponent(q.expression),
|
|
333
333
|
expression_b: encodeURIComponent(expression_b),
|
|
334
|
+
selection_b: encodeURIComponent(selection_b),
|
|
334
335
|
from_a: q.from.toString(),
|
|
335
336
|
to_a: q.to.toString(),
|
|
336
337
|
time_selection_a: q.timeSelection,
|
|
@@ -345,7 +346,11 @@ const ProfileExplorerApp = ({
|
|
|
345
346
|
const selectQueryB = (q: QuerySelection): void => {
|
|
346
347
|
const mergeParams =
|
|
347
348
|
q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
348
|
-
? {
|
|
349
|
+
? {
|
|
350
|
+
merge_from_b: q.mergeFrom,
|
|
351
|
+
merge_to_b: q.mergeTo,
|
|
352
|
+
selection_b: encodeURIComponent(q.expression),
|
|
353
|
+
}
|
|
349
354
|
: {};
|
|
350
355
|
return navigateTo(
|
|
351
356
|
'/',
|
|
@@ -357,6 +362,7 @@ const ProfileExplorerApp = ({
|
|
|
357
362
|
compare_b: 'true',
|
|
358
363
|
expression_b: encodeURIComponent(q.expression),
|
|
359
364
|
expression_a: encodeURIComponent(expression_a),
|
|
365
|
+
selection_a: encodeURIComponent(selection_a),
|
|
360
366
|
from_b: q.from.toString(),
|
|
361
367
|
to_b: q.to.toString(),
|
|
362
368
|
time_selection_b: q.timeSelection,
|
package/src/ProfileSource.tsx
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
14
|
import {
|
|
15
|
-
Label,
|
|
16
15
|
ProfileDiffSelection,
|
|
17
16
|
ProfileDiffSelection_Mode,
|
|
18
17
|
QueryRequest,
|
|
@@ -20,7 +19,7 @@ import {
|
|
|
20
19
|
QueryRequest_ReportType,
|
|
21
20
|
Timestamp,
|
|
22
21
|
} from '@parca/client';
|
|
23
|
-
import {Matcher, ProfileType, Query} from '@parca/parser';
|
|
22
|
+
import {Matcher, NewParser, ProfileType, Query} from '@parca/parser';
|
|
24
23
|
import {formatDate} from '@parca/utilities';
|
|
25
24
|
|
|
26
25
|
export interface ProfileSource {
|
|
@@ -58,46 +57,34 @@ export function SuffixParams(params: {[key: string]: any}, suffix: string): {[ke
|
|
|
58
57
|
);
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
export function ParseLabels(labels: string[]): Label[] {
|
|
62
|
-
return labels
|
|
63
|
-
.filter(str => str !== '')
|
|
64
|
-
.map(function (labelString): Label {
|
|
65
|
-
const parts = labelString.split('=', 2);
|
|
66
|
-
return {name: parts[0], value: parts[1]};
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
60
|
export function ProfileSelectionFromParams(
|
|
71
|
-
expression: string | undefined,
|
|
72
|
-
from: string | undefined,
|
|
73
|
-
to: string | undefined,
|
|
74
61
|
mergeFrom: string | undefined,
|
|
75
62
|
mergeTo: string | undefined,
|
|
76
|
-
|
|
63
|
+
selection: string | undefined,
|
|
77
64
|
filterQuery?: string
|
|
78
65
|
): ProfileSelection | null {
|
|
79
66
|
if (
|
|
80
|
-
from !== undefined &&
|
|
81
|
-
to !== undefined &&
|
|
82
67
|
mergeFrom !== undefined &&
|
|
83
68
|
mergeTo !== undefined &&
|
|
84
|
-
|
|
69
|
+
selection !== undefined &&
|
|
70
|
+
selection !== ''
|
|
85
71
|
) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
query = newQuery;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
});
|
|
72
|
+
const p = NewParser();
|
|
73
|
+
p.save();
|
|
74
|
+
const {successfulParse} = Query.tryParse(p, selection);
|
|
75
|
+
|
|
76
|
+
if (!successfulParse) {
|
|
77
|
+
console.log('Failed to parse selected query.');
|
|
78
|
+
console.log(selection);
|
|
79
|
+
return null;
|
|
98
80
|
}
|
|
99
81
|
|
|
100
|
-
return new MergedProfileSelection(
|
|
82
|
+
return new MergedProfileSelection(
|
|
83
|
+
parseInt(mergeFrom),
|
|
84
|
+
parseInt(mergeTo),
|
|
85
|
+
Query.parse(selection),
|
|
86
|
+
filterQuery
|
|
87
|
+
);
|
|
101
88
|
}
|
|
102
89
|
|
|
103
90
|
return null;
|
|
@@ -131,9 +118,7 @@ export class MergedProfileSelection implements ProfileSelection {
|
|
|
131
118
|
return {
|
|
132
119
|
merge_from: this.mergeFrom.toString(),
|
|
133
120
|
merge_to: this.mergeTo.toString(),
|
|
134
|
-
|
|
135
|
-
profile_name: this.ProfileName(),
|
|
136
|
-
labels: this.query.matchers.map(m => `${m.key}=${encodeURIComponent(m.value)}`),
|
|
121
|
+
selection: encodeURIComponent(this.query.toString()),
|
|
137
122
|
};
|
|
138
123
|
}
|
|
139
124
|
|
|
@@ -11,14 +11,9 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import {SuffixParams} from '../ProfileSource';
|
|
15
15
|
|
|
16
16
|
test('prefixes keys', () => {
|
|
17
17
|
const input = {key: 'value'};
|
|
18
18
|
expect(SuffixParams(input, '_a')).toMatchObject({key_a: 'value'});
|
|
19
19
|
});
|
|
20
|
-
|
|
21
|
-
test('parses labels', () => {
|
|
22
|
-
const input = ['key=value'];
|
|
23
|
-
expect(ParseLabels(input)).toMatchObject([{name: 'key', value: 'value'}]);
|
|
24
|
-
});
|