@perses-dev/tempo-plugin 0.52.0 → 0.53.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 (181) hide show
  1. package/__mf/js/Tempo.2f6d49a1.js +5 -0
  2. package/__mf/js/async/1101.0dae4724.js +73 -0
  3. package/__mf/js/async/1576.83b7de56.js +1 -0
  4. package/__mf/js/async/1964.e6c5b93b.js +2 -0
  5. package/__mf/js/async/2292.75e9aa11.js +2 -0
  6. package/__mf/js/async/2913.f73e6635.js +7 -0
  7. package/__mf/js/async/2913.f73e6635.js.LICENSE.txt +21 -0
  8. package/__mf/js/async/2981.8fe4ed12.js +2 -0
  9. package/__mf/js/async/3224.ce173388.js +1 -0
  10. package/__mf/js/async/3863.8d56ecec.js +2 -0
  11. package/__mf/js/async/3960.401ff0b0.js +2 -0
  12. package/__mf/js/async/3980.4d5490b2.js +2 -0
  13. package/__mf/js/async/4075.4c5ac93a.js +1 -0
  14. package/__mf/js/async/4238.7962a7a1.js +1 -0
  15. package/__mf/js/async/4269.0cfaf9bb.js +2 -0
  16. package/__mf/js/async/4368.bd6fd0e7.js +2 -0
  17. package/__mf/js/async/4368.bd6fd0e7.js.LICENSE.txt +15 -0
  18. package/__mf/js/async/4421.14238d27.js +1 -0
  19. package/__mf/js/async/4535.7c92d3fd.js +1 -0
  20. package/__mf/js/async/5214.c44cbfe5.js +1 -0
  21. package/__mf/js/async/5266.1c520126.js +10 -0
  22. package/__mf/js/async/5409.676a5f3f.js +1 -0
  23. package/__mf/js/async/5790.b4d4134d.js +1 -0
  24. package/__mf/js/async/5876.47f40562.js +2 -0
  25. package/__mf/js/async/{7832.9f2a70d0.js.LICENSE.txt → 5876.47f40562.js.LICENSE.txt} +1 -23
  26. package/__mf/js/async/5981.c6edce96.js +2 -0
  27. package/__mf/js/async/6292.463b4f49.js +1 -0
  28. package/__mf/js/async/6333.367d6758.js +2 -0
  29. package/__mf/js/async/6495.eae3d4b4.js +1 -0
  30. package/__mf/js/async/6527.5341d09f.js +2 -0
  31. package/__mf/js/async/6751.03514b88.js +1 -0
  32. package/__mf/js/async/6770.d9c238f2.js +1 -0
  33. package/__mf/js/async/694.c2c37771.js +1 -0
  34. package/__mf/js/async/7127.a0877987.js +38 -0
  35. package/__mf/js/async/7376.588b7a17.js +1 -0
  36. package/__mf/js/async/738.93d35dc9.js +1 -0
  37. package/__mf/js/async/7740.0500bfc6.js +1 -0
  38. package/__mf/js/async/8216.2f92a883.js +1 -0
  39. package/__mf/js/async/8488.6c9a25e4.js +1 -0
  40. package/__mf/js/async/8597.d5ba4ca7.js +1 -0
  41. package/__mf/js/async/8930.dee9777e.js +1 -0
  42. package/__mf/js/async/9173.69dc268d.js +2 -0
  43. package/__mf/js/async/9314.4b8565a0.js +2 -0
  44. package/__mf/js/async/9368.f0418d24.js +101 -0
  45. package/__mf/js/async/__federation_expose_TempoDatasource.fa3e24f9.js +2 -0
  46. package/__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js +2 -0
  47. package/__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js +1 -0
  48. package/__mf/js/async/lib-router.312ca028.js +2 -0
  49. package/__mf/js/main.edbb7a5a.js +5 -0
  50. package/lib/cjs/components/AttributeFilters.js +274 -0
  51. package/lib/cjs/components/TraceQLEditor.js +9 -3
  52. package/lib/cjs/components/complete.js +29 -13
  53. package/lib/cjs/components/filter/filter.js +25 -0
  54. package/lib/cjs/components/filter/filter_to_traceql.js +66 -0
  55. package/lib/cjs/components/filter/index.js +32 -0
  56. package/lib/cjs/components/filter/traceql_to_filter.js +113 -0
  57. package/lib/cjs/components/index.js +1 -0
  58. package/lib/cjs/explore/TempoExplorer.js +25 -12
  59. package/lib/cjs/explore/links.js +77 -0
  60. package/lib/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +94 -30
  61. package/lib/cjs/plugins/tempo-trace-query/get-trace-data.js +8 -0
  62. package/lib/cjs/plugins/tempo-trace-query/query-editor-model.js +3 -44
  63. package/lib/components/AttributeFilters.d.ts +9 -0
  64. package/lib/components/AttributeFilters.d.ts.map +1 -0
  65. package/lib/components/AttributeFilters.js +261 -0
  66. package/lib/components/AttributeFilters.js.map +1 -0
  67. package/lib/components/TraceQLEditor.d.ts +3 -3
  68. package/lib/components/TraceQLEditor.d.ts.map +1 -1
  69. package/lib/components/TraceQLEditor.js +9 -3
  70. package/lib/components/TraceQLEditor.js.map +1 -1
  71. package/lib/components/complete.d.ts +10 -1
  72. package/lib/components/complete.d.ts.map +1 -1
  73. package/lib/components/complete.js +26 -7
  74. package/lib/components/complete.js.map +1 -1
  75. package/lib/components/filter/filter.d.ts +17 -0
  76. package/lib/components/filter/filter.d.ts.map +1 -0
  77. package/lib/components/filter/filter.js +17 -0
  78. package/lib/components/filter/filter.js.map +1 -0
  79. package/lib/components/filter/filter_to_traceql.d.ts +9 -0
  80. package/lib/components/filter/filter_to_traceql.d.ts.map +1 -0
  81. package/lib/components/filter/filter_to_traceql.js +63 -0
  82. package/lib/components/filter/filter_to_traceql.js.map +1 -0
  83. package/lib/components/filter/index.d.ts +4 -0
  84. package/lib/components/filter/index.d.ts.map +1 -0
  85. package/lib/components/filter/index.js +17 -0
  86. package/lib/components/filter/index.js.map +1 -0
  87. package/lib/components/filter/traceql_to_filter.d.ts +9 -0
  88. package/lib/components/filter/traceql_to_filter.d.ts.map +1 -0
  89. package/lib/components/filter/traceql_to_filter.js +110 -0
  90. package/lib/components/filter/traceql_to_filter.js.map +1 -0
  91. package/lib/components/index.d.ts +1 -0
  92. package/lib/components/index.d.ts.map +1 -1
  93. package/lib/components/index.js +1 -0
  94. package/lib/components/index.js.map +1 -1
  95. package/lib/explore/TempoExplorer.d.ts.map +1 -1
  96. package/lib/explore/TempoExplorer.js +25 -12
  97. package/lib/explore/TempoExplorer.js.map +1 -1
  98. package/lib/explore/links.d.ts +3 -0
  99. package/lib/explore/links.d.ts.map +1 -0
  100. package/lib/explore/links.js +63 -0
  101. package/lib/explore/links.js.map +1 -0
  102. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts +6 -0
  103. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
  104. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js +87 -31
  105. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
  106. package/lib/plugins/tempo-trace-query/get-trace-data.js +8 -0
  107. package/lib/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
  108. package/lib/plugins/tempo-trace-query/query-editor-model.d.ts +0 -9
  109. package/lib/plugins/tempo-trace-query/query-editor-model.d.ts.map +1 -1
  110. package/lib/plugins/tempo-trace-query/query-editor-model.js +0 -35
  111. package/lib/plugins/tempo-trace-query/query-editor-model.js.map +1 -1
  112. package/mf-manifest.json +104 -265
  113. package/mf-stats.json +112 -270
  114. package/package.json +6 -6
  115. package/__mf/js/1096.c549c391.js +0 -5
  116. package/__mf/js/Tempo.e7d268a6.js +0 -5
  117. package/__mf/js/async/1465.21c847e0.js +0 -1
  118. package/__mf/js/async/1540.089c4f28.js +0 -74
  119. package/__mf/js/async/1620.45989def.js +0 -2
  120. package/__mf/js/async/1964.75933dd4.js +0 -2
  121. package/__mf/js/async/2114.28503adb.js +0 -1
  122. package/__mf/js/async/2823.df67fd4b.js +0 -2
  123. package/__mf/js/async/3044.8b419ccf.js +0 -1
  124. package/__mf/js/async/3090.90251187.js +0 -2
  125. package/__mf/js/async/3224.8d499a63.js +0 -1
  126. package/__mf/js/async/3355.8bd6f6bd.js +0 -1
  127. package/__mf/js/async/3828.d981b319.js +0 -2
  128. package/__mf/js/async/3960.2228bf7e.js +0 -2
  129. package/__mf/js/async/3980.c94e78cd.js +0 -2
  130. package/__mf/js/async/4075.4c40db9f.js +0 -1
  131. package/__mf/js/async/4238.db631f1f.js +0 -1
  132. package/__mf/js/async/4289.5e2073e0.js +0 -1
  133. package/__mf/js/async/4421.07335985.js +0 -1
  134. package/__mf/js/async/4758.cb86850e.js +0 -1
  135. package/__mf/js/async/5207.e63b049c.js +0 -2
  136. package/__mf/js/async/5214.fb1215df.js +0 -1
  137. package/__mf/js/async/5220.80e3b05e.js +0 -10
  138. package/__mf/js/async/528.2759052c.js +0 -1
  139. package/__mf/js/async/5503.6e47fa95.js +0 -1
  140. package/__mf/js/async/5790.949d8d1c.js +0 -1
  141. package/__mf/js/async/5913.d10c6185.js +0 -73
  142. package/__mf/js/async/5924.bfb4b2fd.js +0 -2
  143. package/__mf/js/async/5981.4700ddf6.js +0 -2
  144. package/__mf/js/async/6292.2481b399.js +0 -1
  145. package/__mf/js/async/6770.4b9911ea.js +0 -1
  146. package/__mf/js/async/694.91676c53.js +0 -1
  147. package/__mf/js/async/7127.ccd78bd8.js +0 -38
  148. package/__mf/js/async/7376.a69c2e5a.js +0 -1
  149. package/__mf/js/async/738.2cdddba7.js +0 -1
  150. package/__mf/js/async/7740.1ecb3732.js +0 -1
  151. package/__mf/js/async/7832.9f2a70d0.js +0 -7
  152. package/__mf/js/async/8485.434a672e.js +0 -28
  153. package/__mf/js/async/8488.d3005164.js +0 -1
  154. package/__mf/js/async/8597.07c3a890.js +0 -1
  155. package/__mf/js/async/8930.ae855fbe.js +0 -1
  156. package/__mf/js/async/9173.83562213.js +0 -2
  157. package/__mf/js/async/9478.57f45cd9.js +0 -2
  158. package/__mf/js/async/__federation_expose_TempoDatasource.4f96e206.js +0 -2
  159. package/__mf/js/async/__federation_expose_TempoExplorer.eb09c758.js +0 -2
  160. package/__mf/js/async/__federation_expose_TempoTraceQuery.4183e294.js +0 -1
  161. package/__mf/js/async/lib-router.46460b13.js +0 -2
  162. package/__mf/js/main.4498dd88.js +0 -1
  163. /package/__mf/css/async/{4758.c10cf504.css → 1576.c10cf504.css} +0 -0
  164. /package/__mf/css/async/{5207.c10cf504.css → 9314.c10cf504.css} +0 -0
  165. /package/__mf/js/async/{5913.d10c6185.js.LICENSE.txt → 1101.0dae4724.js.LICENSE.txt} +0 -0
  166. /package/__mf/js/async/{1964.75933dd4.js.LICENSE.txt → 1964.e6c5b93b.js.LICENSE.txt} +0 -0
  167. /package/__mf/js/async/{3090.90251187.js.LICENSE.txt → 2292.75e9aa11.js.LICENSE.txt} +0 -0
  168. /package/__mf/js/async/{1620.45989def.js.LICENSE.txt → 2981.8fe4ed12.js.LICENSE.txt} +0 -0
  169. /package/__mf/js/async/{2823.df67fd4b.js.LICENSE.txt → 3863.8d56ecec.js.LICENSE.txt} +0 -0
  170. /package/__mf/js/async/{3960.2228bf7e.js.LICENSE.txt → 3960.401ff0b0.js.LICENSE.txt} +0 -0
  171. /package/__mf/js/async/{3980.c94e78cd.js.LICENSE.txt → 3980.4d5490b2.js.LICENSE.txt} +0 -0
  172. /package/__mf/js/async/{3828.d981b319.js.LICENSE.txt → 4269.0cfaf9bb.js.LICENSE.txt} +0 -0
  173. /package/__mf/js/async/{5220.80e3b05e.js.LICENSE.txt → 5266.1c520126.js.LICENSE.txt} +0 -0
  174. /package/__mf/js/async/{5981.4700ddf6.js.LICENSE.txt → 5981.c6edce96.js.LICENSE.txt} +0 -0
  175. /package/__mf/js/async/{5207.e63b049c.js.LICENSE.txt → 6333.367d6758.js.LICENSE.txt} +0 -0
  176. /package/__mf/js/async/{5924.bfb4b2fd.js.LICENSE.txt → 6527.5341d09f.js.LICENSE.txt} +0 -0
  177. /package/__mf/js/async/{9173.83562213.js.LICENSE.txt → 9173.69dc268d.js.LICENSE.txt} +0 -0
  178. /package/__mf/js/async/{9478.57f45cd9.js.LICENSE.txt → 9314.4b8565a0.js.LICENSE.txt} +0 -0
  179. /package/__mf/js/async/{__federation_expose_TempoDatasource.4f96e206.js.LICENSE.txt → __federation_expose_TempoDatasource.fa3e24f9.js.LICENSE.txt} +0 -0
  180. /package/__mf/js/async/{__federation_expose_TempoExplorer.eb09c758.js.LICENSE.txt → __federation_expose_TempoExplorer.9949b25e.js.LICENSE.txt} +0 -0
  181. /package/__mf/js/async/{lib-router.46460b13.js.LICENSE.txt → lib-router.312ca028.js.LICENSE.txt} +0 -0
@@ -0,0 +1,274 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ Object.defineProperty(exports, "AttributeFilters", {
18
+ enumerable: true,
19
+ get: function() {
20
+ return AttributeFilters;
21
+ }
22
+ });
23
+ const _jsxruntime = require("react/jsx-runtime");
24
+ const _react = require("react");
25
+ const _material = require("@mui/material");
26
+ const _core = require("@perses-dev/core");
27
+ const _pluginsystem = require("@perses-dev/plugin-system");
28
+ const _reactquery = require("@tanstack/react-query");
29
+ const _CheckboxOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/CheckboxOutline"));
30
+ const _CheckboxBlankOutline = /*#__PURE__*/ _interop_require_default(require("mdi-material-ui/CheckboxBlankOutline"));
31
+ const _filter_to_traceql = require("./filter/filter_to_traceql");
32
+ const _traceql_to_filter = require("./filter/traceql_to_filter");
33
+ const _filter = require("./filter/filter");
34
+ function _interop_require_default(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
39
+ const statusOptions = [
40
+ 'unset',
41
+ 'ok',
42
+ 'error'
43
+ ];
44
+ function AttributeFilters(props) {
45
+ const { client, query, setQuery } = props;
46
+ const filter = (0, _traceql_to_filter.traceQLToFilter)(query);
47
+ const setFilter = (filter)=>{
48
+ setQuery((0, _filter_to_traceql.filterToTraceQL)(filter));
49
+ };
50
+ const { timeRange } = (0, _pluginsystem.useTimeRange)();
51
+ const absTimeRange = !(0, _core.isAbsoluteTimeRange)(timeRange) ? (0, _core.toAbsoluteTimeRange)(timeRange) : timeRange;
52
+ const startTime = Math.round(absTimeRange.start.getTime() / 1000);
53
+ const endTime = Math.round(absTimeRange.end.getTime() / 1000);
54
+ const { data: serviceNameOptions } = useTagValues(client, 'resource.service.name', (0, _filter_to_traceql.filterToTraceQL)({
55
+ ...filter,
56
+ serviceName: []
57
+ }), startTime, endTime);
58
+ const { data: spanNameOptions } = useTagValues(client, 'name', (0, _filter_to_traceql.filterToTraceQL)({
59
+ ...filter,
60
+ spanName: []
61
+ }), startTime, endTime);
62
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_jsxruntime.Fragment, {
63
+ children: [
64
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
65
+ label: "Service Name",
66
+ options: serviceNameOptions ?? [],
67
+ value: filter.serviceName,
68
+ setValue: (x)=>setFilter({
69
+ ...filter,
70
+ serviceName: x
71
+ })
72
+ }),
73
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
74
+ label: "Span Name",
75
+ options: spanNameOptions ?? [],
76
+ value: filter.spanName,
77
+ setValue: (x)=>setFilter({
78
+ ...filter,
79
+ spanName: x
80
+ })
81
+ }),
82
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(StringAttributeFilter, {
83
+ label: "Status",
84
+ width: 210,
85
+ options: statusOptions ?? [],
86
+ value: filter.status,
87
+ setValue: (x)=>setFilter({
88
+ ...filter,
89
+ status: x
90
+ })
91
+ }),
92
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(DurationAttributeFilter, {
93
+ label: "Trace Duration",
94
+ value: filter.traceDuration,
95
+ setValue: (value)=>setFilter({
96
+ ...filter,
97
+ traceDuration: value
98
+ })
99
+ }),
100
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(CustomAttributesFilter, {
101
+ label: "Custom Attributes",
102
+ value: filter.customMatchers,
103
+ setValue: (value)=>setFilter({
104
+ ...filter,
105
+ customMatchers: value
106
+ })
107
+ })
108
+ ]
109
+ });
110
+ }
111
+ const checkboxBlankIcon = /*#__PURE__*/ (0, _jsxruntime.jsx)(_CheckboxBlankOutline.default, {
112
+ fontSize: "small"
113
+ });
114
+ const checkedMarkedIcon = /*#__PURE__*/ (0, _jsxruntime.jsx)(_CheckboxOutline.default, {
115
+ fontSize: "small"
116
+ });
117
+ function StringAttributeFilter(props) {
118
+ const { label, width, options, value, setValue } = props;
119
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Autocomplete, {
120
+ multiple: true,
121
+ size: "small",
122
+ limitTags: 1,
123
+ disableCloseOnSelect: true,
124
+ value: value,
125
+ onChange: (_event, newValue)=>setValue(newValue),
126
+ options: options,
127
+ renderOption: (props, option, { selected })=>{
128
+ const { key, ...optionProps } = props;
129
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)("li", {
130
+ ...optionProps,
131
+ children: [
132
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.Checkbox, {
133
+ icon: checkboxBlankIcon,
134
+ checkedIcon: checkedMarkedIcon,
135
+ style: {
136
+ marginRight: 8
137
+ },
138
+ checked: selected
139
+ }),
140
+ option
141
+ ]
142
+ }, key);
143
+ },
144
+ renderInput: (params)=>/*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
145
+ ...params,
146
+ label: label
147
+ }),
148
+ // Reduce the size of the chips to make space for the <input> element, the +X text and the X button to avoid a line break.
149
+ // See https://github.com/mui/material-ui/issues/38835 for more details.
150
+ slotProps: {
151
+ chip: {
152
+ sx: {
153
+ maxWidth: 'calc(100% - 45px) !important'
154
+ }
155
+ }
156
+ },
157
+ // Reduce the size of the <input> field
158
+ sx: {
159
+ width: width ?? 250,
160
+ '& input': {
161
+ minWidth: '5px !important'
162
+ }
163
+ }
164
+ });
165
+ }
166
+ function DurationAttributeFilter(props) {
167
+ const { label, value, setValue } = props;
168
+ const { min, max } = value;
169
+ return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
170
+ direction: "row",
171
+ gap: 0.5,
172
+ children: [
173
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(DurationTextInput, {
174
+ label: `Min ${label}`,
175
+ value: min ?? '',
176
+ setValue: (min)=>setValue({
177
+ min,
178
+ max
179
+ })
180
+ }),
181
+ /*#__PURE__*/ (0, _jsxruntime.jsx)(DurationTextInput, {
182
+ label: `Max ${label}`,
183
+ value: max ?? '',
184
+ setValue: (max)=>setValue({
185
+ min,
186
+ max
187
+ })
188
+ })
189
+ ]
190
+ });
191
+ }
192
+ const durationFormatRegex = /^([0-9]+\.)?[0-9]+(ns|ms|s|m|h)$/;
193
+ function DurationTextInput(props) {
194
+ const { label, value, setValue } = props;
195
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(LazyTextInput, {
196
+ label: label,
197
+ size: "small",
198
+ value: value,
199
+ setValue: setValue,
200
+ validationRegex: durationFormatRegex,
201
+ validationFailedMessage: "Invalid format. Accepted format e.g. 100ms, accepted units: ns, ms, s, m, h",
202
+ sx: {
203
+ width: 150
204
+ }
205
+ });
206
+ }
207
+ function CustomAttributesFilter(props) {
208
+ const { label, value, setValue } = props;
209
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(LazyTextInput, {
210
+ label: label,
211
+ size: "small",
212
+ placeholder: 'span.http.status_code=200 span.http.method="GET"',
213
+ value: value.join(' '),
214
+ setValue: (x)=>setValue((0, _filter.splitByUnquotedWhitespace)(x)),
215
+ sx: {
216
+ flexGrow: 1
217
+ }
218
+ });
219
+ }
220
+ /** A <TextField> which calls props.setValue when the input field is blurred and the validation passes. */ function LazyTextInput(props) {
221
+ const { validationRegex, validationFailedMessage, value, setValue, ...otherProps } = props;
222
+ const [draftValue, setDraftValue] = (0, _react.useState)(value);
223
+ const isValidInput = draftValue == '' || validationRegex == undefined || validationRegex.test(draftValue);
224
+ (0, _react.useEffect)(()=>{
225
+ setDraftValue(value);
226
+ }, [
227
+ value,
228
+ setDraftValue
229
+ ]);
230
+ const handleChange = (0, _react.useCallback)((event)=>{
231
+ setDraftValue(event.target.value);
232
+ }, []);
233
+ const handleBlur = (0, _react.useCallback)(()=>{
234
+ if (isValidInput) {
235
+ setValue(draftValue);
236
+ }
237
+ }, [
238
+ isValidInput,
239
+ setValue,
240
+ draftValue
241
+ ]);
242
+ return /*#__PURE__*/ (0, _jsxruntime.jsx)(_material.TextField, {
243
+ ...otherProps,
244
+ error: !isValidInput,
245
+ helperText: isValidInput ? undefined : validationFailedMessage,
246
+ value: draftValue,
247
+ onChange: handleChange,
248
+ onBlur: handleBlur
249
+ });
250
+ }
251
+ function useTagValues(client, tag, query, start, end) {
252
+ return (0, _reactquery.useQuery)({
253
+ queryKey: [
254
+ 'useTagValues',
255
+ client,
256
+ tag,
257
+ query,
258
+ start,
259
+ end
260
+ ],
261
+ enabled: !!client,
262
+ queryFn: async function() {
263
+ if (!client) return;
264
+ const values = await client.searchTagValues({
265
+ tag,
266
+ q: query,
267
+ start,
268
+ end
269
+ });
270
+ return values.tagValues.map((tagValue)=>tagValue.value ?? '').sort();
271
+ },
272
+ staleTime: 60 * 1000
273
+ });
274
+ }
@@ -25,6 +25,7 @@ const _react = require("react");
25
25
  const _material = require("@mui/material");
26
26
  const _reactcodemirror = /*#__PURE__*/ _interop_require_wildcard(require("@uiw/react-codemirror"));
27
27
  const _core = require("@perses-dev/core");
28
+ const _pluginsystem = require("@perses-dev/plugin-system");
28
29
  const _TraceQLExtension = require("./TraceQLExtension");
29
30
  function _getRequireWildcardCache(nodeInterop) {
30
31
  if (typeof WeakMap !== "function") return null;
@@ -67,13 +68,18 @@ function _interop_require_wildcard(obj, nodeInterop) {
67
68
  }
68
69
  return newObj;
69
70
  }
70
- function TraceQLEditor({ completionConfig, ...rest }) {
71
+ function TraceQLEditor({ client, ...rest }) {
71
72
  const theme = (0, _material.useTheme)();
72
73
  const isDarkMode = theme.palette.mode === 'dark';
74
+ const { timeRange } = (0, _pluginsystem.useTimeRange)();
73
75
  const traceQLExtension = (0, _react.useMemo)(()=>{
74
- return (0, _TraceQLExtension.TraceQLExtension)(completionConfig);
76
+ return (0, _TraceQLExtension.TraceQLExtension)({
77
+ client,
78
+ timeRange
79
+ });
75
80
  }, [
76
- completionConfig
81
+ client,
82
+ timeRange
77
83
  ]);
78
84
  const codemirrorTheme = (0, _react.useMemo)(()=>{
79
85
  // https://github.com/mui/material-ui/blob/v5.16.7/packages/mui-material/src/OutlinedInput/OutlinedInput.js#L43
@@ -21,6 +21,9 @@ function _export(target, all) {
21
21
  });
22
22
  }
23
23
  _export(exports, {
24
+ applyQuotedCompletion: function() {
25
+ return applyQuotedCompletion;
26
+ },
24
27
  complete: function() {
25
28
  return complete;
26
29
  },
@@ -32,6 +35,11 @@ const _autocomplete = require("@codemirror/autocomplete");
32
35
  const _language = require("@codemirror/language");
33
36
  const _lezertraceql = require("@grafana/lezer-traceql");
34
37
  const _core = require("@perses-dev/core");
38
+ const quoteChars = [
39
+ '"',
40
+ '`'
41
+ ];
42
+ const defaultQuoteChar = '"';
35
43
  async function complete(completionCfg, { state, pos }) {
36
44
  // First, identify the completion scopes, for example Scopes() and TagName(scope=intrinsic)
37
45
  const completions = identifyCompletions(state, pos, (0, _language.syntaxTree)(state));
@@ -223,7 +231,7 @@ function identifyCompletions(state, pos, tree) {
223
231
  const fieldExpr = node.parent.firstChild;
224
232
  const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);
225
233
  // ignore leading " in { name="HT
226
- const from = state.sliceDoc(node.from, node.from + 1) === '"' ? node.from + 1 : node.from;
234
+ const from = quoteChars.includes(state.sliceDoc(node.from, node.from + 1)) ? node.from + 1 : node.from;
227
235
  return {
228
236
  scopes: [
229
237
  {
@@ -311,19 +319,27 @@ async function completeTagName(completionCfg, scope) {
311
319
  label: tag
312
320
  }));
313
321
  }
314
- /**
315
- * Add quotes to the completion text in case quotes are not present already.
316
- * This handles the following cases:
317
- * { name=HTTP
318
- * { name="x
319
- * { name="x" where cursor is after the 'x'
320
- */ function applyQuotedCompletion(view, completion, from, to) {
321
- let insertText = completion.label;
322
- if (view.state.sliceDoc(from - 1, from) !== '"') {
323
- insertText = '"' + insertText;
322
+ function escapeString(input, quoteChar) {
323
+ let escaped = input;
324
+ escaped = escaped.replaceAll('\\', '\\\\');
325
+ if (quoteChar == '"') {
326
+ escaped = escaped.replaceAll('"', '\\"');
327
+ }
328
+ return escaped;
329
+ }
330
+ function applyQuotedCompletion(view, completion, from, to) {
331
+ let quoteChar = defaultQuoteChar;
332
+ if (quoteChars.includes(view.state.sliceDoc(from - 1, from))) {
333
+ quoteChar = view.state.sliceDoc(from - 1, from);
334
+ } else if (quoteChars.includes(view.state.sliceDoc(to, to + 1))) {
335
+ quoteChar = view.state.sliceDoc(to, to + 1);
336
+ }
337
+ let insertText = escapeString(completion.label, quoteChar);
338
+ if (view.state.sliceDoc(from - 1, from) !== quoteChar) {
339
+ insertText = quoteChar + insertText;
324
340
  }
325
- if (view.state.sliceDoc(to, to + 1) !== '"') {
326
- insertText = insertText + '"';
341
+ if (view.state.sliceDoc(to, to + 1) !== quoteChar) {
342
+ insertText = insertText + quoteChar;
327
343
  }
328
344
  view.dispatch((0, _autocomplete.insertCompletionText)(view.state, insertText, from, to));
329
345
  }
@@ -0,0 +1,25 @@
1
+ /** A model of a filter bar for common tracing attributes. All attributes are combined with AND, the values of an attribute are combined with OR. */ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "splitByUnquotedWhitespace", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return splitByUnquotedWhitespace;
9
+ }
10
+ });
11
+ function splitByUnquotedWhitespace(x) {
12
+ let quote = false;
13
+ let from = 0;
14
+ const chunks = [];
15
+ for(let i = 0; i < x.length; i++){
16
+ if (x[i] == '"' && x[i - 1] != '\\') {
17
+ quote = !quote;
18
+ } else if (x[i] == ' ' && !quote) {
19
+ chunks.push(x.slice(from, i));
20
+ from = i + 1;
21
+ }
22
+ }
23
+ chunks.push(x.slice(from, x.length));
24
+ return chunks.filter((x)=>x);
25
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "filterToTraceQL", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return filterToTraceQL;
9
+ }
10
+ });
11
+ function filterToTraceQL(filter) {
12
+ const matchers = [
13
+ ...stringMatcher('resource.service.name', filter.serviceName),
14
+ ...stringMatcher('name', filter.spanName),
15
+ ...stringMatcher('resource.k8s.namespace.name', filter.namespace),
16
+ ...intrinsicMatcher('status', filter.status),
17
+ ...durationMatcher('duration', filter.spanDuration),
18
+ ...durationMatcher('traceDuration', filter.traceDuration),
19
+ ...customMatcher(filter.customMatchers)
20
+ ];
21
+ if (matchers.length === 0) {
22
+ return '{}';
23
+ }
24
+ return `{ ${matchers.join(' && ')} }`;
25
+ }
26
+ function escape(q) {
27
+ return q.replaceAll('\\', '\\\\').replaceAll('"', '\\"');
28
+ }
29
+ function stringMatcher(attribute, values) {
30
+ const escapedValues = values.map(escape);
31
+ if (escapedValues.length > 1) {
32
+ return [
33
+ `${attribute} =~ "${escapedValues.join('|')}"`
34
+ ];
35
+ } else if (escapedValues.length == 1) {
36
+ return [
37
+ `${attribute} = "${escapedValues[0]}"`
38
+ ];
39
+ }
40
+ return [];
41
+ }
42
+ function intrinsicMatcher(attribute, values) {
43
+ const orConds = values.map((x)=>`${attribute} = ${x}`);
44
+ if (orConds.length > 1) {
45
+ return [
46
+ '(' + orConds.join(' || ') + ')'
47
+ ];
48
+ } else if (orConds.length === 1) {
49
+ return orConds;
50
+ } else {
51
+ return [];
52
+ }
53
+ }
54
+ function durationMatcher(attribute, value) {
55
+ const matchers = [];
56
+ if (value.min) {
57
+ matchers.push(`${attribute} >= ${value.min}`);
58
+ }
59
+ if (value.max) {
60
+ matchers.push(`${attribute} <= ${value.max}`);
61
+ }
62
+ return matchers;
63
+ }
64
+ function customMatcher(customMatchers) {
65
+ return customMatchers;
66
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright 2025 The Perses Authors
2
+ // Licensed under the Apache License, Version 2.0 (the "License");
3
+ // you may not use this file except in compliance with the License.
4
+ // You may obtain a copy of the License at
5
+ //
6
+ // http://www.apache.org/licenses/LICENSE-2.0
7
+ //
8
+ // Unless required by applicable law or agreed to in writing, software
9
+ // distributed under the License is distributed on an "AS IS" BASIS,
10
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ // See the License for the specific language governing permissions and
12
+ // limitations under the License.
13
+ "use strict";
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
17
+ _export_star(require("./filter"), exports);
18
+ _export_star(require("./filter_to_traceql"), exports);
19
+ _export_star(require("./traceql_to_filter"), exports);
20
+ function _export_star(from, to) {
21
+ Object.keys(from).forEach(function(k) {
22
+ if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
23
+ Object.defineProperty(to, k, {
24
+ enumerable: true,
25
+ get: function() {
26
+ return from[k];
27
+ }
28
+ });
29
+ }
30
+ });
31
+ return from;
32
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "traceQLToFilter", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return traceQLToFilter;
9
+ }
10
+ });
11
+ const _lezertraceql = require("@grafana/lezer-traceql");
12
+ function traceQLToFilter(query) {
13
+ const matchers = parseQuery(query);
14
+ return {
15
+ serviceName: reverseStringMatcher(matchers['resource.service.name']),
16
+ spanName: reverseStringMatcher(matchers['name']),
17
+ namespace: reverseStringMatcher(matchers['resource.k8s.namespace.name']),
18
+ status: reverseIntrinsicMatcher(matchers['status']),
19
+ spanDuration: reverseDurationMatcher(matchers['duration']),
20
+ traceDuration: reverseDurationMatcher(matchers['traceDuration']),
21
+ customMatchers: reverseCustomMatcher(matchers, new Set([
22
+ 'resource.service.name',
23
+ 'name',
24
+ 'resource.k8s.namespace.name',
25
+ 'status',
26
+ 'duration',
27
+ 'traceDuration'
28
+ ]))
29
+ };
30
+ }
31
+ function parseQuery(query) {
32
+ const matchers = {};
33
+ let attribute = '';
34
+ let operator = '';
35
+ let value = '';
36
+ const syntaxTree = _lezertraceql.parser.parse(query);
37
+ syntaxTree.iterate({
38
+ enter (node) {
39
+ switch(node.type.id){
40
+ case _lezertraceql.AttributeField:
41
+ attribute = query.slice(node.from, node.to);
42
+ return false;
43
+ case _lezertraceql.IntrinsicField:
44
+ attribute = query.slice(node.from, node.to);
45
+ return false;
46
+ case _lezertraceql.FieldOp:
47
+ operator = query.slice(node.from, node.to);
48
+ return false;
49
+ case _lezertraceql.Static:
50
+ value = query.slice(node.from, node.to);
51
+ return false;
52
+ }
53
+ },
54
+ leave (node) {
55
+ if (node.type.id === _lezertraceql.FieldExpression && node.node.getChild(_lezertraceql.FieldOp)) {
56
+ const newMatchers = matchers[attribute] ?? [];
57
+ newMatchers.push({
58
+ operator,
59
+ value
60
+ });
61
+ matchers[attribute] = newMatchers;
62
+ }
63
+ }
64
+ });
65
+ return matchers;
66
+ }
67
+ function unescape(q) {
68
+ return q.replaceAll('\\"', '"').replaceAll('\\\\', '\\');
69
+ }
70
+ function reverseStringMatcher(matches) {
71
+ const values = [];
72
+ for (const { operator, value } of matches ?? []){
73
+ const unescaped = unescape(value.slice(1, -1));
74
+ if (operator == '=') {
75
+ values.push(unescaped);
76
+ } else if (operator == '=~') {
77
+ values.push(...unescaped.split('|'));
78
+ }
79
+ }
80
+ return values;
81
+ }
82
+ function reverseIntrinsicMatcher(matches) {
83
+ const values = [];
84
+ for (const { operator, value } of matches ?? []){
85
+ if (operator == '=') {
86
+ values.push(value);
87
+ }
88
+ }
89
+ return values;
90
+ }
91
+ function reverseDurationMatcher(matches) {
92
+ const duration = {};
93
+ for (const { operator, value } of matches ?? []){
94
+ if (operator == '>=') {
95
+ duration.min = value;
96
+ } else if (operator == '<=') {
97
+ duration.max = value;
98
+ }
99
+ }
100
+ return duration;
101
+ }
102
+ function reverseCustomMatcher(matchers, skipAttrs) {
103
+ const customMatchers = [];
104
+ for (const [attribute, matches] of Object.entries(matchers)){
105
+ if (skipAttrs.has(attribute)) {
106
+ continue;
107
+ }
108
+ for (const { operator, value } of matches){
109
+ customMatchers.push(`${attribute}${operator}${value}`);
110
+ }
111
+ }
112
+ return customMatchers;
113
+ }
@@ -14,6 +14,7 @@
14
14
  Object.defineProperty(exports, "__esModule", {
15
15
  value: true
16
16
  });
17
+ _export_star(require("./filter"), exports);
17
18
  _export_star(require("./TraceQLEditor"), exports);
18
19
  _export_star(require("./TraceQLExtension"), exports);
19
20
  function _export_star(from, to) {