@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.
Files changed (60) hide show
  1. package/dist/cjs/components/TraceQLEditor.js +98 -0
  2. package/dist/cjs/components/TraceQLExtension.js +73 -0
  3. package/dist/cjs/components/complete.js +322 -0
  4. package/dist/cjs/components/highlight.js +41 -0
  5. package/dist/cjs/components/index.js +30 -0
  6. package/dist/cjs/index.js +1 -0
  7. package/dist/cjs/model/tempo-client.js +33 -15
  8. package/dist/cjs/plugins/tempo-datasource.js +22 -4
  9. package/dist/cjs/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
  10. package/dist/cjs/plugins/tempo-trace-query/get-trace-data.js +3 -13
  11. package/dist/cjs/test/mock-data.js +58 -0
  12. package/dist/components/TraceQLEditor.d.ts +7 -0
  13. package/dist/components/TraceQLEditor.d.ts.map +1 -0
  14. package/dist/{plugins/tempo-trace-query → components}/TraceQLEditor.js +20 -4
  15. package/dist/components/TraceQLEditor.js.map +1 -0
  16. package/dist/components/TraceQLExtension.d.ts +8 -0
  17. package/dist/components/TraceQLExtension.d.ts.map +1 -0
  18. package/dist/components/TraceQLExtension.js +65 -0
  19. package/dist/components/TraceQLExtension.js.map +1 -0
  20. package/dist/components/complete.d.ts +36 -0
  21. package/dist/components/complete.d.ts.map +1 -0
  22. package/dist/components/complete.js +313 -0
  23. package/dist/components/complete.js.map +1 -0
  24. package/dist/components/highlight.d.ts +2 -0
  25. package/dist/components/highlight.d.ts.map +1 -0
  26. package/dist/components/highlight.js +33 -0
  27. package/dist/components/highlight.js.map +1 -0
  28. package/dist/components/index.d.ts +2 -0
  29. package/dist/components/index.d.ts.map +1 -0
  30. package/dist/components/index.js +15 -0
  31. package/dist/components/index.js.map +1 -0
  32. package/dist/index.d.ts +1 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/model/api-types.d.ts +62 -11
  37. package/dist/model/api-types.d.ts.map +1 -1
  38. package/dist/model/api-types.js.map +1 -1
  39. package/dist/model/tempo-client.d.ts +18 -8
  40. package/dist/model/tempo-client.d.ts.map +1 -1
  41. package/dist/model/tempo-client.js +26 -10
  42. package/dist/model/tempo-client.js.map +1 -1
  43. package/dist/plugins/tempo-datasource.d.ts.map +1 -1
  44. package/dist/plugins/tempo-datasource.js +23 -5
  45. package/dist/plugins/tempo-datasource.js.map +1 -1
  46. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.d.ts.map +1 -1
  47. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js +6 -2
  48. package/dist/plugins/tempo-trace-query/DashboardTempoTraceQueryEditor.js.map +1 -1
  49. package/dist/plugins/tempo-trace-query/get-trace-data.d.ts.map +1 -1
  50. package/dist/plugins/tempo-trace-query/get-trace-data.js +3 -13
  51. package/dist/plugins/tempo-trace-query/get-trace-data.js.map +1 -1
  52. package/dist/test/mock-data.d.ts +6 -5
  53. package/dist/test/mock-data.d.ts.map +1 -1
  54. package/dist/test/mock-data.js +55 -0
  55. package/dist/test/mock-data.js.map +1 -1
  56. package/package.json +8 -4
  57. package/dist/cjs/plugins/tempo-trace-query/TraceQLEditor.js +0 -46
  58. package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts +0 -4
  59. package/dist/plugins/tempo-trace-query/TraceQLEditor.d.ts.map +0 -1
  60. 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
- searchTraceQuery: (params, queryOptions)=>(0, _tempoclient.searchTraceQuery)(params, queryOptions),
39
- searchTraceQueryFallback: (params, queryOptions)=>(0, _tempoclient.searchTraceQueryFallback)(params, queryOptions),
40
- searchTraceID: (traceID, queryOptions)=>(0, _tempoclient.searchTraceID)(traceID, queryOptions)
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 _TraceQLEditor = require("./TraceQLEditor");
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)(_TraceQLEditor.TraceQLEditor, {
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.searchTraceID(spec.query, {
84
- datasourceUrl
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.searchTraceQueryFallback(getQuery(), {
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
- export function TraceQLEditor({ ...rest }) {
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"}