@perses-dev/tempo-plugin 0.47.0 → 0.48.0-rc.1
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/dist/cjs/components/TraceQLEditor.js +98 -0
- package/dist/cjs/components/TraceQLExtension.js +73 -0
- package/dist/cjs/components/complete.js +322 -0
- package/dist/cjs/components/highlight.js +41 -0
- package/dist/cjs/components/index.js +30 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/model/tempo-client.js +33 -15
- package/dist/cjs/plugins/tempo-datasource.js +22 -4
- package/dist/cjs/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
- package/dist/cjs/plugins/tempo-trace-query/get-trace-data.js +3 -13
- package/dist/cjs/test/mock-data.js +58 -0
- package/dist/components/TraceQLEditor.d.ts +7 -0
- package/dist/components/TraceQLEditor.d.ts.map +1 -0
- package/dist/{plugins/tempo-trace-query → components}/TraceQLEditor.js +20 -4
- package/dist/components/TraceQLEditor.js.map +1 -0
- package/dist/components/TraceQLExtension.d.ts +8 -0
- package/dist/components/TraceQLExtension.d.ts.map +1 -0
- package/dist/components/TraceQLExtension.js +65 -0
- package/dist/components/TraceQLExtension.js.map +1 -0
- package/dist/components/complete.d.ts +36 -0
- package/dist/components/complete.d.ts.map +1 -0
- package/dist/components/complete.js +313 -0
- package/dist/components/complete.js.map +1 -0
- package/dist/components/highlight.d.ts +2 -0
- package/dist/components/highlight.d.ts.map +1 -0
- package/dist/components/highlight.js +33 -0
- package/dist/components/highlight.js.map +1 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +15 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/model/api-types.d.ts +62 -11
- package/dist/model/api-types.d.ts.map +1 -1
- package/dist/model/api-types.js.map +1 -1
- package/dist/model/tempo-client.d.ts +18 -8
- package/dist/model/tempo-client.d.ts.map +1 -1
- package/dist/model/tempo-client.js +26 -10
- package/dist/model/tempo-client.js.map +1 -1
- package/dist/plugins/tempo-datasource.d.ts.map +1 -1
- package/dist/plugins/tempo-datasource.js +23 -5
- package/dist/plugins/tempo-datasource.js.map +1 -1
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
- package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
- package/dist/plugins/tempo-trace-query/get-trace-data.js +3 -13
- package/dist/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
- package/dist/test/mock-data.d.ts +6 -5
- package/dist/test/mock-data.d.ts.map +1 -1
- package/dist/test/mock-data.js +55 -0
- package/dist/test/mock-data.js.map +1 -1
- package/package.json +8 -4
- package/dist/cjs/plugins/tempo-trace-query/TraceQLEditor.js +0 -46
- package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts +0 -4
- package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts.map +0 -1
- package/dist/plugins/tempo-trace-query/TraceQLEditor.js.map +0 -1
|
@@ -24,20 +24,38 @@ const _tempoclient = require("../model/tempo-client");
|
|
|
24
24
|
/**
|
|
25
25
|
* Creates a TempoClient for a specific datasource spec.
|
|
26
26
|
*/ const createClient = (spec, options)=>{
|
|
27
|
-
const { directUrl } = spec;
|
|
27
|
+
const { directUrl, proxy } = spec;
|
|
28
28
|
const { proxyUrl } = options;
|
|
29
29
|
// Use the direct URL if specified, but fallback to the proxyUrl by default if not specified
|
|
30
30
|
const datasourceUrl = directUrl !== null && directUrl !== void 0 ? directUrl : proxyUrl;
|
|
31
31
|
if (datasourceUrl === undefined) {
|
|
32
32
|
throw new Error('No URL specified for Tempo client. You can use directUrl in the spec to configure it.');
|
|
33
33
|
}
|
|
34
|
+
const specHeaders = proxy === null || proxy === void 0 ? void 0 : proxy.spec.headers;
|
|
34
35
|
return {
|
|
35
36
|
options: {
|
|
36
37
|
datasourceUrl
|
|
37
38
|
},
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
query: (params, headers)=>(0, _tempoclient.query)(params, {
|
|
40
|
+
datasourceUrl,
|
|
41
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
42
|
+
}),
|
|
43
|
+
search: (params, headers)=>(0, _tempoclient.search)(params, {
|
|
44
|
+
datasourceUrl,
|
|
45
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
46
|
+
}),
|
|
47
|
+
searchWithFallback: (params, headers)=>(0, _tempoclient.searchWithFallback)(params, {
|
|
48
|
+
datasourceUrl,
|
|
49
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
50
|
+
}),
|
|
51
|
+
searchTags: (params, headers)=>(0, _tempoclient.searchTags)(params, {
|
|
52
|
+
datasourceUrl,
|
|
53
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
54
|
+
}),
|
|
55
|
+
searchTagValues: (params, headers)=>(0, _tempoclient.searchTagValues)(params, {
|
|
56
|
+
datasourceUrl,
|
|
57
|
+
headers: headers !== null && headers !== void 0 ? headers : specHeaders
|
|
58
|
+
})
|
|
41
59
|
};
|
|
42
60
|
};
|
|
43
61
|
const TempoDatasource = {
|
|
@@ -24,9 +24,10 @@ const _jsxruntime = require("react/jsx-runtime");
|
|
|
24
24
|
const _material = require("@mui/material");
|
|
25
25
|
const _pluginsystem = require("@perses-dev/plugin-system");
|
|
26
26
|
const _temposelectors = require("../../model/tempo-selectors");
|
|
27
|
-
const
|
|
27
|
+
const _components = require("../../components");
|
|
28
28
|
function DashboardTempoTraceQueryEditor(props) {
|
|
29
29
|
const { selectedDatasource, handleDatasourceChange, query, handleQueryChange, handleQueryBlur } = props;
|
|
30
|
+
const { data: client } = (0, _pluginsystem.useDatasourceClient)(selectedDatasource);
|
|
30
31
|
return /*#__PURE__*/ (0, _jsxruntime.jsxs)(_material.Stack, {
|
|
31
32
|
spacing: 2,
|
|
32
33
|
children: [
|
|
@@ -47,7 +48,10 @@ function DashboardTempoTraceQueryEditor(props) {
|
|
|
47
48
|
})
|
|
48
49
|
]
|
|
49
50
|
}),
|
|
50
|
-
/*#__PURE__*/ (0, _jsxruntime.jsx)(
|
|
51
|
+
/*#__PURE__*/ (0, _jsxruntime.jsx)(_components.TraceQLEditor, {
|
|
52
|
+
completeConfig: {
|
|
53
|
+
client
|
|
54
|
+
},
|
|
51
55
|
value: query,
|
|
52
56
|
onChange: handleQueryChange,
|
|
53
57
|
onBlur: handleQueryBlur
|
|
@@ -40,7 +40,6 @@ function getUnixTimeRange(timeRange) {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
const getTraceData = async (spec, context)=>{
|
|
43
|
-
var _client_options;
|
|
44
43
|
if (spec.query === undefined || spec.query === null || spec.query === '') {
|
|
45
44
|
// Do not make a request to the backend, instead return an empty TraceData
|
|
46
45
|
console.error('TempoTraceQuery is undefined, null, or an empty string.');
|
|
@@ -53,13 +52,6 @@ const getTraceData = async (spec, context)=>{
|
|
|
53
52
|
};
|
|
54
53
|
var _spec_datasource;
|
|
55
54
|
const client = await context.datasourceStore.getDatasourceClient((_spec_datasource = spec.datasource) !== null && _spec_datasource !== void 0 ? _spec_datasource : defaultTempoDatasource);
|
|
56
|
-
const datasourceUrl = client === null || client === void 0 ? void 0 : (_client_options = client.options) === null || _client_options === void 0 ? void 0 : _client_options.datasourceUrl;
|
|
57
|
-
if (datasourceUrl === undefined || datasourceUrl === null || datasourceUrl === '') {
|
|
58
|
-
console.error('TempoDatasource is undefined, null, or an empty string.');
|
|
59
|
-
return {
|
|
60
|
-
searchResult: []
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
55
|
const getQuery = ()=>{
|
|
64
56
|
// if time range not defined -- only return the query from the spec
|
|
65
57
|
if (context.absoluteTimeRange === undefined) {
|
|
@@ -80,8 +72,8 @@ const getTraceData = async (spec, context)=>{
|
|
|
80
72
|
* if the query is a valid traceId, fetch the trace by traceId
|
|
81
73
|
* otherwise, execute a TraceQL query
|
|
82
74
|
*/ if ((0, _core.isValidTraceId)(spec.query)) {
|
|
83
|
-
const response = await client.
|
|
84
|
-
|
|
75
|
+
const response = await client.query({
|
|
76
|
+
traceId: spec.query
|
|
85
77
|
});
|
|
86
78
|
return {
|
|
87
79
|
trace: parseTraceResponse(response),
|
|
@@ -90,9 +82,7 @@ const getTraceData = async (spec, context)=>{
|
|
|
90
82
|
}
|
|
91
83
|
};
|
|
92
84
|
} else {
|
|
93
|
-
const response = await client.
|
|
94
|
-
datasourceUrl
|
|
95
|
-
});
|
|
85
|
+
const response = await client.searchWithFallback(getQuery());
|
|
96
86
|
return {
|
|
97
87
|
searchResult: parseSearchResponse(response),
|
|
98
88
|
metadata: {
|
|
@@ -21,6 +21,9 @@ function _export(target, all) {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
_export(exports, {
|
|
24
|
+
MOCK_SEARCH_RESPONSE_MIXED_VPARQUET3_AND_4: function() {
|
|
25
|
+
return MOCK_SEARCH_RESPONSE_MIXED_VPARQUET3_AND_4;
|
|
26
|
+
},
|
|
24
27
|
MOCK_SEARCH_RESPONSE_VPARQUET3: function() {
|
|
25
28
|
return MOCK_SEARCH_RESPONSE_VPARQUET3;
|
|
26
29
|
},
|
|
@@ -2363,6 +2366,61 @@ const MOCK_SEARCH_RESPONSE_VPARQUET4 = {
|
|
|
2363
2366
|
}
|
|
2364
2367
|
]
|
|
2365
2368
|
};
|
|
2369
|
+
const MOCK_SEARCH_RESPONSE_MIXED_VPARQUET3_AND_4 = {
|
|
2370
|
+
traces: [
|
|
2371
|
+
{
|
|
2372
|
+
traceID: '224a0e75a0d244f1a3dab3af233e6cf3',
|
|
2373
|
+
rootServiceName: 'telemetrygen',
|
|
2374
|
+
rootTraceName: 'lets-go',
|
|
2375
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2376
|
+
spanSets: [
|
|
2377
|
+
{
|
|
2378
|
+
spans: [
|
|
2379
|
+
{
|
|
2380
|
+
spanID: '237f68dfbed2f473',
|
|
2381
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2382
|
+
durationNanos: '123000'
|
|
2383
|
+
},
|
|
2384
|
+
{
|
|
2385
|
+
spanID: 'a8eefdaad116a872',
|
|
2386
|
+
startTimeUnixNano: '1727969811138427469',
|
|
2387
|
+
durationNanos: '123000'
|
|
2388
|
+
}
|
|
2389
|
+
],
|
|
2390
|
+
matched: 2
|
|
2391
|
+
}
|
|
2392
|
+
],
|
|
2393
|
+
serviceStats: {
|
|
2394
|
+
telemetrygen: {
|
|
2395
|
+
spanCount: 2
|
|
2396
|
+
}
|
|
2397
|
+
}
|
|
2398
|
+
},
|
|
2399
|
+
{
|
|
2400
|
+
traceID: '71bd40553a881d98dc52f2a27fd53fe3',
|
|
2401
|
+
rootServiceName: 'telemetrygen',
|
|
2402
|
+
rootTraceName: 'lets-go',
|
|
2403
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2404
|
+
spanSets: [
|
|
2405
|
+
{
|
|
2406
|
+
spans: [
|
|
2407
|
+
{
|
|
2408
|
+
spanID: '968a78f0ffbc6570',
|
|
2409
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2410
|
+
durationNanos: '123000'
|
|
2411
|
+
},
|
|
2412
|
+
{
|
|
2413
|
+
spanID: 'bb8ab44ffd46ca07',
|
|
2414
|
+
startTimeUnixNano: '1727969665041183110',
|
|
2415
|
+
durationNanos: '123000'
|
|
2416
|
+
}
|
|
2417
|
+
],
|
|
2418
|
+
matched: 2
|
|
2419
|
+
}
|
|
2420
|
+
]
|
|
2421
|
+
}
|
|
2422
|
+
]
|
|
2423
|
+
};
|
|
2366
2424
|
const MOCK_TRACE_DATA_SEARCHRESULT = {
|
|
2367
2425
|
searchResult: [
|
|
2368
2426
|
{
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactCodeMirrorProps } from '@uiw/react-codemirror';
|
|
2
|
+
import { CompletionConfig } from './TraceQLExtension';
|
|
3
|
+
export interface TraceQLEditorProps extends Omit<ReactCodeMirrorProps, 'theme' | 'extensions'> {
|
|
4
|
+
completeConfig: CompletionConfig;
|
|
5
|
+
}
|
|
6
|
+
export declare function TraceQLEditor({ completeConfig, ...rest }: TraceQLEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=TraceQLEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceQLEditor.d.ts","sourceRoot":"","sources":["../../src/components/TraceQLEditor.tsx"],"names":[],"mappings":"AAeA,OAAmB,EAAc,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAErF,OAAO,EAAE,gBAAgB,EAAoB,MAAM,oBAAoB,CAAC;AAExE,MAAM,WAAW,kBAAmB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,OAAO,GAAG,YAAY,CAAC;IAC5F,cAAc,EAAE,gBAAgB,CAAC;CAClC;AAED,wBAAgB,aAAa,CAAC,EAAE,cAAc,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,2CAwB5E"}
|
|
@@ -11,11 +11,20 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
|
+
import { useMemo } from 'react';
|
|
14
15
|
import { useTheme } from '@mui/material';
|
|
15
|
-
import CodeMirror from '@uiw/react-codemirror';
|
|
16
|
-
|
|
16
|
+
import CodeMirror, { EditorView } from '@uiw/react-codemirror';
|
|
17
|
+
import { isValidTraceId } from '@perses-dev/core';
|
|
18
|
+
import { TraceQLExtension } from './TraceQLExtension';
|
|
19
|
+
export function TraceQLEditor({ completeConfig, ...rest }) {
|
|
17
20
|
const theme = useTheme();
|
|
18
21
|
const isDarkMode = theme.palette.mode === 'dark';
|
|
22
|
+
const traceQLExtension = useMemo(()=>{
|
|
23
|
+
return TraceQLExtension(completeConfig);
|
|
24
|
+
}, [
|
|
25
|
+
completeConfig
|
|
26
|
+
]);
|
|
27
|
+
var _rest_value;
|
|
19
28
|
return /*#__PURE__*/ _jsx(CodeMirror, {
|
|
20
29
|
...rest,
|
|
21
30
|
style: {
|
|
@@ -25,8 +34,15 @@ export function TraceQLEditor({ ...rest }) {
|
|
|
25
34
|
basicSetup: {
|
|
26
35
|
highlightActiveLine: false,
|
|
27
36
|
highlightActiveLineGutter: false,
|
|
28
|
-
foldGutter: false
|
|
29
|
-
|
|
37
|
+
foldGutter: false,
|
|
38
|
+
// The explore view accepts either a TraceQL query or a Trace ID as input. The lezer grammar marks Trace IDs as invalid,
|
|
39
|
+
// therefore let's disable syntax highlighting if the input is a Trace ID.
|
|
40
|
+
syntaxHighlighting: !isValidTraceId((_rest_value = rest.value) !== null && _rest_value !== void 0 ? _rest_value : '')
|
|
41
|
+
},
|
|
42
|
+
extensions: [
|
|
43
|
+
EditorView.lineWrapping,
|
|
44
|
+
traceQLExtension
|
|
45
|
+
]
|
|
30
46
|
});
|
|
31
47
|
}
|
|
32
48
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TraceQLEditor.tsx"],"sourcesContent":["// Copyright 2023 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { useMemo } from 'react';\nimport { useTheme } from '@mui/material';\nimport CodeMirror, { EditorView, ReactCodeMirrorProps } from '@uiw/react-codemirror';\nimport { isValidTraceId } from '@perses-dev/core';\nimport { CompletionConfig, TraceQLExtension } from './TraceQLExtension';\n\nexport interface TraceQLEditorProps extends Omit<ReactCodeMirrorProps, 'theme' | 'extensions'> {\n completeConfig: CompletionConfig;\n}\n\nexport function TraceQLEditor({ completeConfig, ...rest }: TraceQLEditorProps) {\n const theme = useTheme();\n const isDarkMode = theme.palette.mode === 'dark';\n\n const traceQLExtension = useMemo(() => {\n return TraceQLExtension(completeConfig);\n }, [completeConfig]);\n\n return (\n <CodeMirror\n {...rest}\n style={{ border: `1px solid ${theme.palette.divider}` }}\n theme={isDarkMode ? 'dark' : 'light'}\n basicSetup={{\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n foldGutter: false,\n // The explore view accepts either a TraceQL query or a Trace ID as input. The lezer grammar marks Trace IDs as invalid,\n // therefore let's disable syntax highlighting if the input is a Trace ID.\n syntaxHighlighting: !isValidTraceId(rest.value ?? ''),\n }}\n extensions={[EditorView.lineWrapping, traceQLExtension]}\n />\n );\n}\n"],"names":["useMemo","useTheme","CodeMirror","EditorView","isValidTraceId","TraceQLExtension","TraceQLEditor","completeConfig","rest","theme","isDarkMode","palette","mode","traceQLExtension","style","border","divider","basicSetup","highlightActiveLine","highlightActiveLineGutter","foldGutter","syntaxHighlighting","value","extensions","lineWrapping"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;;AAEjC,SAASA,OAAO,QAAQ,QAAQ;AAChC,SAASC,QAAQ,QAAQ,gBAAgB;AACzC,OAAOC,cAAcC,UAAU,QAA8B,wBAAwB;AACrF,SAASC,cAAc,QAAQ,mBAAmB;AAClD,SAA2BC,gBAAgB,QAAQ,qBAAqB;AAMxE,OAAO,SAASC,cAAc,EAAEC,cAAc,EAAE,GAAGC,MAA0B;IAC3E,MAAMC,QAAQR;IACd,MAAMS,aAAaD,MAAME,OAAO,CAACC,IAAI,KAAK;IAE1C,MAAMC,mBAAmBb,QAAQ;QAC/B,OAAOK,iBAAiBE;IAC1B,GAAG;QAACA;KAAe;QAauBC;IAX1C,qBACE,KAACN;QACE,GAAGM,IAAI;QACRM,OAAO;YAAEC,QAAQ,CAAC,UAAU,EAAEN,MAAME,OAAO,CAACK,OAAO,CAAC,CAAC;QAAC;QACtDP,OAAOC,aAAa,SAAS;QAC7BO,YAAY;YACVC,qBAAqB;YACrBC,2BAA2B;YAC3BC,YAAY;YACZ,wHAAwH;YACxH,0EAA0E;YAC1EC,oBAAoB,CAACjB,eAAeI,CAAAA,cAAAA,KAAKc,KAAK,cAAVd,yBAAAA,cAAc;QACpD;QACAe,YAAY;YAACpB,WAAWqB,YAAY;YAAEX;SAAiB;;AAG7D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { LRLanguage } from '@codemirror/language';
|
|
2
|
+
import { TempoClient } from '../model/tempo-client';
|
|
3
|
+
export interface CompletionConfig {
|
|
4
|
+
client?: TempoClient;
|
|
5
|
+
endpoint?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function TraceQLExtension(completionCfg: CompletionConfig): (import("@codemirror/state").Extension | LRLanguage)[];
|
|
8
|
+
//# sourceMappingURL=TraceQLExtension.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceQLExtension.d.ts","sourceRoot":"","sources":["../../src/components/TraceQLExtension.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AA2BpD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,gBAAgB,0DAQ/D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Copyright 2024 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
|
+
import { LRLanguage } from '@codemirror/language';
|
|
14
|
+
import { parser } from '@grafana/lezer-traceql';
|
|
15
|
+
import { TempoDatasource } from '../plugins/tempo-datasource';
|
|
16
|
+
import { traceQLHighlight } from './highlight';
|
|
17
|
+
import { complete } from './complete';
|
|
18
|
+
function traceQLLanguage() {
|
|
19
|
+
return LRLanguage.define({
|
|
20
|
+
parser: parser.configure({
|
|
21
|
+
props: [
|
|
22
|
+
traceQLHighlight
|
|
23
|
+
]
|
|
24
|
+
}),
|
|
25
|
+
languageData: {
|
|
26
|
+
closeBrackets: {
|
|
27
|
+
brackets: [
|
|
28
|
+
'(',
|
|
29
|
+
'[',
|
|
30
|
+
'{',
|
|
31
|
+
"'",
|
|
32
|
+
'"',
|
|
33
|
+
'`'
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
commentTokens: {
|
|
37
|
+
line: '//'
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function getTempoClient(completionCfg) {
|
|
43
|
+
if (completionCfg.client) {
|
|
44
|
+
return completionCfg.client;
|
|
45
|
+
}
|
|
46
|
+
if (completionCfg.endpoint) {
|
|
47
|
+
return TempoDatasource.createClient({
|
|
48
|
+
directUrl: completionCfg.endpoint
|
|
49
|
+
}, {});
|
|
50
|
+
}
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
export function TraceQLExtension(completionCfg) {
|
|
54
|
+
const tempoClient = getTempoClient(completionCfg);
|
|
55
|
+
const language = traceQLLanguage();
|
|
56
|
+
const completion = language.data.of({
|
|
57
|
+
autocomplete: (ctx)=>complete(ctx, tempoClient).catch((e)=>console.error('error during TraceQL auto-complete', e))
|
|
58
|
+
});
|
|
59
|
+
return [
|
|
60
|
+
language,
|
|
61
|
+
completion
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=TraceQLExtension.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/TraceQLExtension.ts"],"sourcesContent":["// Copyright 2024 The Perses Authors\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nimport { LRLanguage } from '@codemirror/language';\nimport { parser } from '@grafana/lezer-traceql';\nimport { CompletionContext } from '@codemirror/autocomplete';\nimport { TempoClient } from '../model/tempo-client';\nimport { TempoDatasource } from '../plugins/tempo-datasource';\nimport { traceQLHighlight } from './highlight';\nimport { complete } from './complete';\n\nfunction traceQLLanguage(): LRLanguage {\n return LRLanguage.define({\n parser: parser.configure({\n props: [traceQLHighlight],\n }),\n languageData: {\n closeBrackets: { brackets: ['(', '[', '{', \"'\", '\"', '`'] },\n commentTokens: { line: '//' },\n },\n });\n}\n\nfunction getTempoClient(completionCfg: CompletionConfig): TempoClient | undefined {\n if (completionCfg.client) {\n return completionCfg.client;\n }\n if (completionCfg.endpoint) {\n return TempoDatasource.createClient({ directUrl: completionCfg.endpoint }, {});\n }\n return undefined;\n}\n\nexport interface CompletionConfig {\n client?: TempoClient;\n endpoint?: string;\n}\n\nexport function TraceQLExtension(completionCfg: CompletionConfig) {\n const tempoClient = getTempoClient(completionCfg);\n const language = traceQLLanguage();\n const completion = language.data.of({\n autocomplete: (ctx: CompletionContext) =>\n complete(ctx, tempoClient).catch((e) => console.error('error during TraceQL auto-complete', e)),\n });\n return [language, completion];\n}\n"],"names":["LRLanguage","parser","TempoDatasource","traceQLHighlight","complete","traceQLLanguage","define","configure","props","languageData","closeBrackets","brackets","commentTokens","line","getTempoClient","completionCfg","client","endpoint","createClient","directUrl","undefined","TraceQLExtension","tempoClient","language","completion","data","of","autocomplete","ctx","catch","e","console","error"],"mappings":"AAAA,oCAAoC;AACpC,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,6CAA6C;AAC7C,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AAEjC,SAASA,UAAU,QAAQ,uBAAuB;AAClD,SAASC,MAAM,QAAQ,yBAAyB;AAGhD,SAASC,eAAe,QAAQ,8BAA8B;AAC9D,SAASC,gBAAgB,QAAQ,cAAc;AAC/C,SAASC,QAAQ,QAAQ,aAAa;AAEtC,SAASC;IACP,OAAOL,WAAWM,MAAM,CAAC;QACvBL,QAAQA,OAAOM,SAAS,CAAC;YACvBC,OAAO;gBAACL;aAAiB;QAC3B;QACAM,cAAc;YACZC,eAAe;gBAAEC,UAAU;oBAAC;oBAAK;oBAAK;oBAAK;oBAAK;oBAAK;iBAAI;YAAC;YAC1DC,eAAe;gBAAEC,MAAM;YAAK;QAC9B;IACF;AACF;AAEA,SAASC,eAAeC,aAA+B;IACrD,IAAIA,cAAcC,MAAM,EAAE;QACxB,OAAOD,cAAcC,MAAM;IAC7B;IACA,IAAID,cAAcE,QAAQ,EAAE;QAC1B,OAAOf,gBAAgBgB,YAAY,CAAC;YAAEC,WAAWJ,cAAcE,QAAQ;QAAC,GAAG,CAAC;IAC9E;IACA,OAAOG;AACT;AAOA,OAAO,SAASC,iBAAiBN,aAA+B;IAC9D,MAAMO,cAAcR,eAAeC;IACnC,MAAMQ,WAAWlB;IACjB,MAAMmB,aAAaD,SAASE,IAAI,CAACC,EAAE,CAAC;QAClCC,cAAc,CAACC,MACbxB,SAASwB,KAAKN,aAAaO,KAAK,CAAC,CAACC,IAAMC,QAAQC,KAAK,CAAC,sCAAsCF;IAChG;IACA,OAAO;QAACP;QAAUC;KAAW;AAC/B"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
|
2
|
+
import { EditorState } from '@codemirror/state';
|
|
3
|
+
import { Tree } from '@lezer/common';
|
|
4
|
+
import { TempoClient } from '../model/tempo-client';
|
|
5
|
+
/** CompletionScope specifies the completion kind, e.g. whether to complete tag names or values etc. */
|
|
6
|
+
type CompletionScope = {
|
|
7
|
+
kind: 'Scopes';
|
|
8
|
+
} | {
|
|
9
|
+
kind: 'TagName';
|
|
10
|
+
scope: 'resource' | 'span' | 'intrinsic';
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'TagValue';
|
|
13
|
+
tag: string;
|
|
14
|
+
quotes?: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Completions specifies the identified scopes and position of the completion in the current editor text.
|
|
18
|
+
* For example, when entering '{' the following completions are possible: Scopes(), TagName(scope=intrinsic)
|
|
19
|
+
*/
|
|
20
|
+
export interface Completions {
|
|
21
|
+
scopes: CompletionScope[];
|
|
22
|
+
from: number;
|
|
23
|
+
to?: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function complete({ state, pos }: CompletionContext, client?: TempoClient): Promise<CompletionResult | null>;
|
|
26
|
+
/**
|
|
27
|
+
* Identify completion scopes (e.g. TagValue) and position, based on the current node in the syntax tree.
|
|
28
|
+
*
|
|
29
|
+
* For development, you can visualize the tree of a TraceQL query using this tool:
|
|
30
|
+
* https://github.com/grafana/lezer-traceql/blob/main/tools/tree-viz.html
|
|
31
|
+
*
|
|
32
|
+
* Function is exported for tests only.
|
|
33
|
+
*/
|
|
34
|
+
export declare function identifyCompletions(state: EditorState, pos: number, tree: Tree): Completions | undefined;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=complete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complete.d.ts","sourceRoot":"","sources":["../../src/components/complete.ts"],"names":[],"mappings":"AAaA,OAAO,EAAc,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE3F,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAWrC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,uGAAuG;AACvG,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,WAAW,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,QAAQ,CAC5B,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,iBAAiB,EACjC,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAWlC;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,WAAW,GAAG,SAAS,CAsHxG"}
|