@perses-dev/tempo-plugin 0.53.0 → 0.53.2

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 (39) hide show
  1. package/__mf/js/Tempo.2d6235bb.js +5 -0
  2. package/__mf/js/async/3391.41e6de04.js +73 -0
  3. package/__mf/js/async/4368.2c879fe0.js +2 -0
  4. package/__mf/js/async/4421.838809cd.js +1 -0
  5. package/__mf/js/async/{2913.f73e6635.js → 6286.6e0d8da6.js} +5 -5
  6. package/__mf/js/async/6714.11904981.js +2 -0
  7. package/__mf/js/async/{__federation_expose_TempoDatasource.fa3e24f9.js → __federation_expose_TempoDatasource.a20f4483.js} +2 -2
  8. package/__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js +2 -0
  9. package/__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js +1 -0
  10. package/__mf/js/main.a9e2b86c.js +5 -0
  11. package/lib/cjs/components/complete.js +15 -10
  12. package/lib/cjs/explore/TempoExplorer.js +3 -0
  13. package/lib/cjs/plugins/tempo-trace-query/TempoTraceQueryEditor.js +4 -0
  14. package/lib/components/complete.d.ts.map +1 -1
  15. package/lib/components/complete.js +15 -10
  16. package/lib/components/complete.js.map +1 -1
  17. package/lib/explore/TempoExplorer.d.ts.map +1 -1
  18. package/lib/explore/TempoExplorer.js +3 -0
  19. package/lib/explore/TempoExplorer.js.map +1 -1
  20. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.d.ts.map +1 -1
  21. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js +4 -0
  22. package/lib/plugins/tempo-trace-query/TempoTraceQueryEditor.js.map +1 -1
  23. package/mf-manifest.json +25 -25
  24. package/mf-stats.json +25 -25
  25. package/package.json +7 -7
  26. package/__mf/js/Tempo.2f6d49a1.js +0 -5
  27. package/__mf/js/async/1101.0dae4724.js +0 -73
  28. package/__mf/js/async/4368.bd6fd0e7.js +0 -2
  29. package/__mf/js/async/4421.14238d27.js +0 -1
  30. package/__mf/js/async/5876.47f40562.js +0 -2
  31. package/__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js +0 -2
  32. package/__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js +0 -1
  33. package/__mf/js/main.edbb7a5a.js +0 -5
  34. /package/__mf/js/async/{1101.0dae4724.js.LICENSE.txt → 3391.41e6de04.js.LICENSE.txt} +0 -0
  35. /package/__mf/js/async/{4368.bd6fd0e7.js.LICENSE.txt → 4368.2c879fe0.js.LICENSE.txt} +0 -0
  36. /package/__mf/js/async/{2913.f73e6635.js.LICENSE.txt → 6286.6e0d8da6.js.LICENSE.txt} +0 -0
  37. /package/__mf/js/async/{5876.47f40562.js.LICENSE.txt → 6714.11904981.js.LICENSE.txt} +0 -0
  38. /package/__mf/js/async/{__federation_expose_TempoDatasource.fa3e24f9.js.LICENSE.txt → __federation_expose_TempoDatasource.a20f4483.js.LICENSE.txt} +0 -0
  39. /package/__mf/js/async/{__federation_expose_TempoExplorer.9949b25e.js.LICENSE.txt → __federation_expose_TempoExplorer.bc71c3ab.js.LICENSE.txt} +0 -0
@@ -306,11 +306,14 @@ async function completeTagName(completionCfg, scope) {
306
306
  }));
307
307
  }
308
308
  function escapeString(input, quoteChar) {
309
+ // do not escape raw strings (when using backticks)
310
+ if (quoteChar === '`') {
311
+ return input;
312
+ }
309
313
  let escaped = input;
314
+ // escape sequences: https://grafana.com/docs/tempo/v2.8.x/traceql/construct-traceql-queries/#quoted-attribute-names
310
315
  escaped = escaped.replaceAll('\\', '\\\\');
311
- if (quoteChar == '"') {
312
- escaped = escaped.replaceAll('"', '\\"');
313
- }
316
+ escaped = escaped.replaceAll('"', '\\"');
314
317
  return escaped;
315
318
  }
316
319
  /**
@@ -323,16 +326,18 @@ function escapeString(input, quoteChar) {
323
326
  let quoteChar = defaultQuoteChar;
324
327
  if (quoteChars.includes(view.state.sliceDoc(from - 1, from))) {
325
328
  quoteChar = view.state.sliceDoc(from - 1, from);
326
- } else if (quoteChars.includes(view.state.sliceDoc(to, to + 1))) {
327
- quoteChar = view.state.sliceDoc(to, to + 1);
329
+ from--;
328
330
  }
329
- let insertText = escapeString(completion.label, quoteChar);
330
- if (view.state.sliceDoc(from - 1, from) !== quoteChar) {
331
- insertText = quoteChar + insertText;
331
+ if (quoteChars.includes(view.state.sliceDoc(to, to + 1))) {
332
+ quoteChar = view.state.sliceDoc(to, to + 1);
333
+ to++;
332
334
  }
333
- if (view.state.sliceDoc(to, to + 1) !== quoteChar) {
334
- insertText = insertText + quoteChar;
335
+ // When using raw strings (`), we cannot escape a backtick.
336
+ // Therefore, switch the quote character.
337
+ if (completion.label.includes('`')) {
338
+ quoteChar = '"';
335
339
  }
340
+ const insertText = `${quoteChar}${escapeString(completion.label, quoteChar)}${quoteChar}`;
336
341
  view.dispatch(insertCompletionText(view.state, insertText, from, to));
337
342
  }
338
343
  async function completeTagValue(completionCfg, tag) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/complete.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 { Completion, CompletionContext, CompletionResult, insertCompletionText } from '@codemirror/autocomplete';\nimport { syntaxTree } from '@codemirror/language';\nimport { EditorState } from '@codemirror/state';\nimport { Tree } from '@lezer/common';\nimport {\n String as StringType,\n FieldExpression,\n AttributeField,\n Resource,\n Identifier,\n Span,\n SpansetFilter,\n FieldOp,\n} from '@grafana/lezer-traceql';\nimport { EditorView } from '@uiw/react-codemirror';\nimport { isAbsoluteTimeRange, TimeRangeValue, toAbsoluteTimeRange } from '@perses-dev/core';\nimport { CompletionConfig } from './TraceQLExtension';\n\n/** CompletionScope specifies the completion kind, e.g. whether to complete tag names or values etc. */\ntype CompletionScope =\n | { kind: 'Scopes' } // 'resource'|'span'\n | { kind: 'TagName'; scope: 'resource' | 'span' | 'intrinsic' }\n | { kind: 'TagValue'; tag: string };\n\n/**\n * Completions specifies the identified scopes and position of the completion in the current editor text.\n * For example, when entering '{' the following completions are possible: Scopes(), TagName(scope=intrinsic)\n */\nexport interface Completions {\n scopes: CompletionScope[];\n from: number;\n to?: number;\n}\n\nconst quoteChars = ['\"', '`'];\nconst defaultQuoteChar = '\"';\n\nexport async function complete(\n completionCfg: CompletionConfig,\n { state, pos }: CompletionContext\n): Promise<CompletionResult | null> {\n // First, identify the completion scopes, for example Scopes() and TagName(scope=intrinsic)\n const completions = identifyCompletions(state, pos, syntaxTree(state));\n if (!completions) {\n // No completion scopes found for current cursor position.\n return null;\n }\n\n // Then, retrieve completion options for all identified scopes (from the Tempo API).\n const options = await retrieveOptions(completionCfg, completions.scopes);\n return { options, from: completions.from, to: completions.to };\n}\n\n/**\n * Identify completion scopes (e.g. TagValue) and position, based on the current node in the syntax tree.\n *\n * For development, you can visualize the tree of a TraceQL query using this tool:\n * https://github.com/grafana/lezer-traceql/blob/main/tools/tree-viz.html\n *\n * Function is exported for tests only.\n */\nexport function identifyCompletions(state: EditorState, pos: number, tree: Tree): Completions | undefined {\n const node = tree.resolveInner(pos, -1);\n\n switch (node.type.id) {\n case SpansetFilter:\n // autocomplete {\n // autocomplete {}\n // do not autocomplete if cursor is after } or { status=ok }\n if (\n (node.firstChild === null || node.firstChild?.type.id === 0) &&\n !state.sliceDoc(node.from, pos).includes('}')\n ) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n }\n break;\n\n case FieldExpression:\n // autocomplete { status=ok &&\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n\n case AttributeField:\n // autocomplete { resource.\n if (node.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: pos };\n }\n\n // autocomplete { span.\n if (node.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: pos };\n }\n\n // autocomplete { .\n if (state.sliceDoc(node.from, node.to) === '.') {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: pos,\n };\n }\n break;\n\n case Identifier:\n if (node.parent?.type.id === AttributeField) {\n const text = state.sliceDoc(node.parent.from, node.parent.to);\n // autocomplete { span:s\n // only intrinsic fields can have a : in the name.\n if (text.includes(':')) {\n return { scopes: [{ kind: 'TagName', scope: 'intrinsic' }], from: node.parent.from };\n }\n\n // autocomplete { resource.s\n if (node.parent?.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: node.from };\n }\n\n // autocomplete { span.s\n if (node.parent?.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: node.from };\n }\n\n // autocomplete { .s\n if (node.parent?.firstChild?.type.id === Identifier) {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: node.from,\n };\n }\n }\n break;\n\n case FieldOp:\n // autocomplete { status=\n // autocomplete { span.http.method=\n if (node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: pos };\n }\n break;\n\n case StringType:\n // autocomplete { resource.service.name=\"\n // do not autocomplete if cursor is after closing quotes { resource.service.name=\"\"\n if (\n node.parent?.parent?.parent?.firstChild?.type.id === FieldExpression &&\n !/^\".*\"$/.test(state.sliceDoc(node.from, pos))\n ) {\n const fieldExpr = node.parent.parent.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: node.from + 1 }; // node.from+1 to ignore leading \"\n }\n break;\n\n case 0 /* error node */:\n // autocomplete { status=e\n if (node.prevSibling?.type.id === FieldOp && node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n // ignore leading \" in { name=\"HT\n const from = quoteChars.includes(state.sliceDoc(node.from, node.from + 1)) ? node.from + 1 : node.from;\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from };\n }\n\n // autocomplete { s\n // autocomplete { status=ok && s\n if (node.parent?.type.id === SpansetFilter || node.parent?.type.id === FieldExpression) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: node.from,\n };\n }\n break;\n }\n}\n\n/**\n * Retrieve all completion options based on the previously identified completion scopes.\n */\nasync function retrieveOptions(completionCfg: CompletionConfig, completions: CompletionScope[]): Promise<Completion[]> {\n const results: Array<Promise<Completion[]>> = [];\n\n for (const completion of completions) {\n switch (completion.kind) {\n case 'Scopes':\n results.push(Promise.resolve([{ label: 'span' }, { label: 'resource' }]));\n break;\n\n case 'TagName':\n results.push(completeTagName(completionCfg, completion.scope));\n break;\n\n case 'TagValue':\n results.push(completeTagValue(completionCfg, completion.tag));\n break;\n }\n }\n\n // Retrieve options concurrently\n // e.g. for unscoped attribute fields, retrieve list of span and resource attributes concurrently.\n const options = await Promise.all(results);\n return options.flat();\n}\n\nfunction getUnixTimeRange(timeRange?: TimeRangeValue): { start?: number; end?: number } {\n if (!timeRange) {\n return {};\n }\n\n const absTimeRange = !isAbsoluteTimeRange(timeRange) ? toAbsoluteTimeRange(timeRange) : timeRange;\n const start = Math.round(absTimeRange.start.getTime() / 1000);\n const end = Math.round(absTimeRange.end.getTime() / 1000);\n return { start, end };\n}\n\nasync function completeTagName(\n completionCfg: CompletionConfig,\n scope: 'resource' | 'span' | 'intrinsic'\n): Promise<Completion[]> {\n if (!completionCfg.client) {\n return [];\n }\n\n const { start, end } = getUnixTimeRange(completionCfg.timeRange);\n const { limit, maxStaleValues } = completionCfg;\n\n const response = await completionCfg.client.searchTags({ scope, start, end, limit, maxStaleValues });\n return response.scopes.flatMap((scope) => scope.tags).map((tag) => ({ label: tag }));\n}\n\nfunction escapeString(input: string, quoteChar: string) {\n let escaped = input;\n escaped = escaped.replaceAll('\\\\', '\\\\\\\\');\n if (quoteChar == '\"') {\n escaped = escaped.replaceAll('\"', '\\\\\"');\n }\n return escaped;\n}\n\n/**\n * Add quotes to the completion text in case quotes are not present already.\n * This handles the following cases:\n * { name=HTTP\n * { name=\"x\n * { name=\"x\" where cursor is after the 'x'\n */\nexport function applyQuotedCompletion(view: EditorView, completion: Completion, from: number, to: number): void {\n let quoteChar = defaultQuoteChar;\n if (quoteChars.includes(view.state.sliceDoc(from - 1, from))) {\n quoteChar = view.state.sliceDoc(from - 1, from);\n } else if (quoteChars.includes(view.state.sliceDoc(to, to + 1))) {\n quoteChar = view.state.sliceDoc(to, to + 1);\n }\n\n let insertText = escapeString(completion.label, quoteChar);\n\n if (view.state.sliceDoc(from - 1, from) !== quoteChar) {\n insertText = quoteChar + insertText;\n }\n if (view.state.sliceDoc(to, to + 1) !== quoteChar) {\n insertText = insertText + quoteChar;\n }\n view.dispatch(insertCompletionText(view.state, insertText, from, to));\n}\n\nasync function completeTagValue(completionCfg: CompletionConfig, tag: string): Promise<Completion[]> {\n if (!completionCfg.client) {\n return [];\n }\n\n const { start, end } = getUnixTimeRange(completionCfg.timeRange);\n const { limit, maxStaleValues } = completionCfg;\n\n const response = await completionCfg.client.searchTagValues({ tag, start, end, limit, maxStaleValues });\n const completions: Completion[] = [];\n for (const { type, value } of response.tagValues) {\n switch (type) {\n case 'string':\n completions.push({ label: value ?? '', displayLabel: value ?? '(empty string)', apply: applyQuotedCompletion });\n break;\n\n case 'keyword':\n case 'int':\n completions.push({ label: value ?? '', displayLabel: value ?? '(empty string)' });\n break;\n }\n }\n return completions;\n}\n"],"names":["insertCompletionText","syntaxTree","String","StringType","FieldExpression","AttributeField","Resource","Identifier","Span","SpansetFilter","FieldOp","isAbsoluteTimeRange","toAbsoluteTimeRange","quoteChars","defaultQuoteChar","complete","completionCfg","state","pos","completions","identifyCompletions","options","retrieveOptions","scopes","from","to","tree","node","resolveInner","type","id","firstChild","sliceDoc","includes","kind","scope","parent","text","fieldExpr","attribute","tag","test","prevSibling","results","completion","push","Promise","resolve","label","completeTagName","completeTagValue","all","flat","getUnixTimeRange","timeRange","absTimeRange","start","Math","round","getTime","end","client","limit","maxStaleValues","response","searchTags","flatMap","tags","map","escapeString","input","quoteChar","escaped","replaceAll","applyQuotedCompletion","view","insertText","dispatch","searchTagValues","value","tagValues","displayLabel","apply"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/complete.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 { Completion, CompletionContext, CompletionResult, insertCompletionText } from '@codemirror/autocomplete';\nimport { syntaxTree } from '@codemirror/language';\nimport { EditorState } from '@codemirror/state';\nimport { Tree } from '@lezer/common';\nimport {\n String as StringType,\n FieldExpression,\n AttributeField,\n Resource,\n Identifier,\n Span,\n SpansetFilter,\n FieldOp,\n} from '@grafana/lezer-traceql';\nimport { EditorView } from '@uiw/react-codemirror';\nimport { isAbsoluteTimeRange, TimeRangeValue, toAbsoluteTimeRange } from '@perses-dev/core';\nimport { CompletionConfig } from './TraceQLExtension';\n\n/** CompletionScope specifies the completion kind, e.g. whether to complete tag names or values etc. */\ntype CompletionScope =\n | { kind: 'Scopes' } // 'resource'|'span'\n | { kind: 'TagName'; scope: 'resource' | 'span' | 'intrinsic' }\n | { kind: 'TagValue'; tag: string };\n\n/**\n * Completions specifies the identified scopes and position of the completion in the current editor text.\n * For example, when entering '{' the following completions are possible: Scopes(), TagName(scope=intrinsic)\n */\nexport interface Completions {\n scopes: CompletionScope[];\n from: number;\n to?: number;\n}\n\nconst quoteChars = ['\"', '`'];\nconst defaultQuoteChar = '\"';\n\nexport async function complete(\n completionCfg: CompletionConfig,\n { state, pos }: CompletionContext\n): Promise<CompletionResult | null> {\n // First, identify the completion scopes, for example Scopes() and TagName(scope=intrinsic)\n const completions = identifyCompletions(state, pos, syntaxTree(state));\n if (!completions) {\n // No completion scopes found for current cursor position.\n return null;\n }\n\n // Then, retrieve completion options for all identified scopes (from the Tempo API).\n const options = await retrieveOptions(completionCfg, completions.scopes);\n return { options, from: completions.from, to: completions.to };\n}\n\n/**\n * Identify completion scopes (e.g. TagValue) and position, based on the current node in the syntax tree.\n *\n * For development, you can visualize the tree of a TraceQL query using this tool:\n * https://github.com/grafana/lezer-traceql/blob/main/tools/tree-viz.html\n *\n * Function is exported for tests only.\n */\nexport function identifyCompletions(state: EditorState, pos: number, tree: Tree): Completions | undefined {\n const node = tree.resolveInner(pos, -1);\n\n switch (node.type.id) {\n case SpansetFilter:\n // autocomplete {\n // autocomplete {}\n // do not autocomplete if cursor is after } or { status=ok }\n if (\n (node.firstChild === null || node.firstChild?.type.id === 0) &&\n !state.sliceDoc(node.from, pos).includes('}')\n ) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n }\n break;\n\n case FieldExpression:\n // autocomplete { status=ok &&\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: pos,\n };\n\n case AttributeField:\n // autocomplete { resource.\n if (node.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: pos };\n }\n\n // autocomplete { span.\n if (node.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: pos };\n }\n\n // autocomplete { .\n if (state.sliceDoc(node.from, node.to) === '.') {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: pos,\n };\n }\n break;\n\n case Identifier:\n if (node.parent?.type.id === AttributeField) {\n const text = state.sliceDoc(node.parent.from, node.parent.to);\n // autocomplete { span:s\n // only intrinsic fields can have a : in the name.\n if (text.includes(':')) {\n return { scopes: [{ kind: 'TagName', scope: 'intrinsic' }], from: node.parent.from };\n }\n\n // autocomplete { resource.s\n if (node.parent?.firstChild?.type.id === Resource) {\n return { scopes: [{ kind: 'TagName', scope: 'resource' }], from: node.from };\n }\n\n // autocomplete { span.s\n if (node.parent?.firstChild?.type.id === Span) {\n return { scopes: [{ kind: 'TagName', scope: 'span' }], from: node.from };\n }\n\n // autocomplete { .s\n if (node.parent?.firstChild?.type.id === Identifier) {\n return {\n scopes: [\n { kind: 'TagName', scope: 'resource' },\n { kind: 'TagName', scope: 'span' },\n ],\n from: node.from,\n };\n }\n }\n break;\n\n case FieldOp:\n // autocomplete { status=\n // autocomplete { span.http.method=\n if (node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: pos };\n }\n break;\n\n case StringType:\n // autocomplete { resource.service.name=\"\n // do not autocomplete if cursor is after closing quotes { resource.service.name=\"\"\n if (\n node.parent?.parent?.parent?.firstChild?.type.id === FieldExpression &&\n !/^\".*\"$/.test(state.sliceDoc(node.from, pos))\n ) {\n const fieldExpr = node.parent.parent.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from: node.from + 1 }; // node.from+1 to ignore leading \"\n }\n break;\n\n case 0 /* error node */:\n // autocomplete { status=e\n if (node.prevSibling?.type.id === FieldOp && node.parent?.firstChild?.type.id === FieldExpression) {\n const fieldExpr = node.parent.firstChild;\n const attribute = state.sliceDoc(fieldExpr.from, fieldExpr.to);\n // ignore leading \" in { name=\"HT\n const from = quoteChars.includes(state.sliceDoc(node.from, node.from + 1)) ? node.from + 1 : node.from;\n return { scopes: [{ kind: 'TagValue', tag: attribute }], from };\n }\n\n // autocomplete { s\n // autocomplete { status=ok && s\n if (node.parent?.type.id === SpansetFilter || node.parent?.type.id === FieldExpression) {\n return {\n scopes: [{ kind: 'Scopes' }, { kind: 'TagName', scope: 'intrinsic' }],\n from: node.from,\n };\n }\n break;\n }\n}\n\n/**\n * Retrieve all completion options based on the previously identified completion scopes.\n */\nasync function retrieveOptions(completionCfg: CompletionConfig, completions: CompletionScope[]): Promise<Completion[]> {\n const results: Array<Promise<Completion[]>> = [];\n\n for (const completion of completions) {\n switch (completion.kind) {\n case 'Scopes':\n results.push(Promise.resolve([{ label: 'span' }, { label: 'resource' }]));\n break;\n\n case 'TagName':\n results.push(completeTagName(completionCfg, completion.scope));\n break;\n\n case 'TagValue':\n results.push(completeTagValue(completionCfg, completion.tag));\n break;\n }\n }\n\n // Retrieve options concurrently\n // e.g. for unscoped attribute fields, retrieve list of span and resource attributes concurrently.\n const options = await Promise.all(results);\n return options.flat();\n}\n\nfunction getUnixTimeRange(timeRange?: TimeRangeValue): { start?: number; end?: number } {\n if (!timeRange) {\n return {};\n }\n\n const absTimeRange = !isAbsoluteTimeRange(timeRange) ? toAbsoluteTimeRange(timeRange) : timeRange;\n const start = Math.round(absTimeRange.start.getTime() / 1000);\n const end = Math.round(absTimeRange.end.getTime() / 1000);\n return { start, end };\n}\n\nasync function completeTagName(\n completionCfg: CompletionConfig,\n scope: 'resource' | 'span' | 'intrinsic'\n): Promise<Completion[]> {\n if (!completionCfg.client) {\n return [];\n }\n\n const { start, end } = getUnixTimeRange(completionCfg.timeRange);\n const { limit, maxStaleValues } = completionCfg;\n\n const response = await completionCfg.client.searchTags({ scope, start, end, limit, maxStaleValues });\n return response.scopes.flatMap((scope) => scope.tags).map((tag) => ({ label: tag }));\n}\n\nfunction escapeString(input: string, quoteChar: string) {\n // do not escape raw strings (when using backticks)\n if (quoteChar === '`') {\n return input;\n }\n\n let escaped = input;\n // escape sequences: https://grafana.com/docs/tempo/v2.8.x/traceql/construct-traceql-queries/#quoted-attribute-names\n escaped = escaped.replaceAll('\\\\', '\\\\\\\\');\n escaped = escaped.replaceAll('\"', '\\\\\"');\n return escaped;\n}\n\n/**\n * Add quotes to the completion text in case quotes are not present already.\n * This handles the following cases:\n * { name=HTTP\n * { name=\"x\n * { name=\"x\" where cursor is after the 'x'\n */\nexport function applyQuotedCompletion(view: EditorView, completion: Completion, from: number, to: number): void {\n let quoteChar = defaultQuoteChar;\n if (quoteChars.includes(view.state.sliceDoc(from - 1, from))) {\n quoteChar = view.state.sliceDoc(from - 1, from);\n from--;\n }\n if (quoteChars.includes(view.state.sliceDoc(to, to + 1))) {\n quoteChar = view.state.sliceDoc(to, to + 1);\n to++;\n }\n\n // When using raw strings (`), we cannot escape a backtick.\n // Therefore, switch the quote character.\n if (completion.label.includes('`')) {\n quoteChar = '\"';\n }\n\n const insertText = `${quoteChar}${escapeString(completion.label, quoteChar)}${quoteChar}`;\n view.dispatch(insertCompletionText(view.state, insertText, from, to));\n}\n\nasync function completeTagValue(completionCfg: CompletionConfig, tag: string): Promise<Completion[]> {\n if (!completionCfg.client) {\n return [];\n }\n\n const { start, end } = getUnixTimeRange(completionCfg.timeRange);\n const { limit, maxStaleValues } = completionCfg;\n\n const response = await completionCfg.client.searchTagValues({ tag, start, end, limit, maxStaleValues });\n const completions: Completion[] = [];\n for (const { type, value } of response.tagValues) {\n switch (type) {\n case 'string':\n completions.push({ label: value ?? '', displayLabel: value ?? '(empty string)', apply: applyQuotedCompletion });\n break;\n\n case 'keyword':\n case 'int':\n completions.push({ label: value ?? '', displayLabel: value ?? '(empty string)' });\n break;\n }\n }\n return completions;\n}\n"],"names":["insertCompletionText","syntaxTree","String","StringType","FieldExpression","AttributeField","Resource","Identifier","Span","SpansetFilter","FieldOp","isAbsoluteTimeRange","toAbsoluteTimeRange","quoteChars","defaultQuoteChar","complete","completionCfg","state","pos","completions","identifyCompletions","options","retrieveOptions","scopes","from","to","tree","node","resolveInner","type","id","firstChild","sliceDoc","includes","kind","scope","parent","text","fieldExpr","attribute","tag","test","prevSibling","results","completion","push","Promise","resolve","label","completeTagName","completeTagValue","all","flat","getUnixTimeRange","timeRange","absTimeRange","start","Math","round","getTime","end","client","limit","maxStaleValues","response","searchTags","flatMap","tags","map","escapeString","input","quoteChar","escaped","replaceAll","applyQuotedCompletion","view","insertText","dispatch","searchTagValues","value","tagValues","displayLabel","apply"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TempoExplorer.d.ts","sourceRoot":"","sources":["../../../src/explore/TempoExplorer.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAkHrC,wBAAgB,aAAa,IAAI,YAAY,CAwC5C"}
1
+ {"version":3,"file":"TempoExplorer.d.ts","sourceRoot":"","sources":["../../../src/explore/TempoExplorer.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAmHrC,wBAAgB,aAAa,IAAI,YAAY,CAwC5C"}
@@ -101,6 +101,9 @@ function TracingGanttChartPanel(props) {
101
101
  const { queries, selectedSpanId } = props;
102
102
  const firstQuery = queries[0]?.spec.plugin.spec?.query;
103
103
  return /*#__PURE__*/ _jsx(Panel, {
104
+ panelOptions: {
105
+ showIcons: 'always'
106
+ },
104
107
  definition: {
105
108
  kind: 'Panel',
106
109
  spec: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/explore/TempoExplorer.tsx"],"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 { Box, Stack } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary, LoadingOverlay, NoDataOverlay } from '@perses-dev/components';\nimport { QueryDefinition, isValidTraceId } from '@perses-dev/core';\nimport { Panel } from '@perses-dev/dashboards';\nimport { useExplorerManagerContext } from '@perses-dev/explore';\nimport { DataQueriesProvider, MultiQueryEditor, useDataQueries } from '@perses-dev/plugin-system';\nimport { ReactElement } from 'react';\nimport { TempoTraceQuerySpec } from '../model';\nimport { linkToSpan, linkToTrace } from './links';\n\ninterface TracesExplorerQueryParams {\n queries?: QueryDefinition[];\n spanId?: string;\n}\n\ninterface SearchResultsPanelProps {\n queries: QueryDefinition[];\n}\n\nfunction SearchResultsPanel({ queries }: SearchResultsPanelProps): ReactElement {\n const { isFetching, isLoading, queryResults } = useDataQueries('TraceQuery');\n\n // no query executed, show empty panel\n if (queryResults.length === 0) {\n return <></>;\n }\n\n if (isLoading || isFetching) {\n return <LoadingOverlay />;\n }\n\n const queryError = queryResults.find((d) => d.error);\n if (queryError) {\n throw queryError.error;\n }\n\n const tracesFound = queryResults.some((traceData) => (traceData.data?.searchResult ?? []).length > 0);\n if (!tracesFound) {\n return <NoDataOverlay resource=\"traces\" />;\n }\n\n return (\n <Stack sx={{ height: '100%' }} gap={2}>\n <Box sx={{ height: '35%', flexShrink: 0 }}>\n <Panel\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'ScatterChart',\n spec: {\n link: linkToTrace,\n },\n },\n },\n }}\n />\n </Box>\n <Panel\n sx={{ flexGrow: 1 }}\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'TraceTable',\n spec: {\n links: {\n trace: linkToTrace,\n },\n },\n },\n },\n }}\n />\n </Stack>\n );\n}\n\ninterface TracingGanttChartPanelProps {\n queries: QueryDefinition[];\n selectedSpanId?: string;\n}\n\nfunction TracingGanttChartPanel(props: TracingGanttChartPanelProps): ReactElement {\n const { queries, selectedSpanId } = props;\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n\n return (\n <Panel\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: `Trace ${firstQuery}` },\n plugin: {\n kind: 'TracingGanttChart',\n spec: {\n links: {\n trace: linkToTrace,\n span: linkToSpan,\n },\n selectedSpanId,\n },\n },\n },\n }}\n />\n );\n}\n\nexport function TempoExplorer(): ReactElement {\n const {\n data: { queries = [], spanId: selectedSpanId },\n setData,\n } = useExplorerManagerContext<TracesExplorerQueryParams>();\n\n // map TraceQueryDefinition to Definition<UnknownSpec>\n const definitions = queries.length\n ? queries.map((query: QueryDefinition) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n })\n : [];\n\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n const isSingleTrace = isValidTraceId(firstQuery ?? '');\n\n return (\n <Stack gap={2} sx={{ width: '100%' }}>\n <MultiQueryEditor\n queryTypes={['TraceQuery']}\n onChange={(newQueries) => setData({ queries: newQueries })}\n queries={queries}\n />\n\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[queries]}>\n <DataQueriesProvider definitions={definitions}>\n <Box height={700}>\n {isSingleTrace ? (\n <TracingGanttChartPanel queries={queries} selectedSpanId={selectedSpanId} />\n ) : (\n <SearchResultsPanel queries={queries} />\n )}\n </Box>\n </DataQueriesProvider>\n </ErrorBoundary>\n </Stack>\n );\n}\n"],"names":["Box","Stack","ErrorAlert","ErrorBoundary","LoadingOverlay","NoDataOverlay","isValidTraceId","Panel","useExplorerManagerContext","DataQueriesProvider","MultiQueryEditor","useDataQueries","linkToSpan","linkToTrace","SearchResultsPanel","queries","isFetching","isLoading","queryResults","length","queryError","find","d","error","tracesFound","some","traceData","data","searchResult","resource","sx","height","gap","flexShrink","panelOptions","hideHeader","definition","kind","spec","display","name","plugin","link","flexGrow","links","trace","TracingGanttChartPanel","props","selectedSpanId","firstQuery","query","span","TempoExplorer","spanId","setData","definitions","map","isSingleTrace","width","queryTypes","onChange","newQueries","FallbackComponent","resetKeys"],"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,GAAG,EAAEC,KAAK,QAAQ,gBAAgB;AAC3C,SAASC,UAAU,EAAEC,aAAa,EAAEC,cAAc,EAAEC,aAAa,QAAQ,yBAAyB;AAClG,SAA0BC,cAAc,QAAQ,mBAAmB;AACnE,SAASC,KAAK,QAAQ,yBAAyB;AAC/C,SAASC,yBAAyB,QAAQ,sBAAsB;AAChE,SAASC,mBAAmB,EAAEC,gBAAgB,EAAEC,cAAc,QAAQ,4BAA4B;AAGlG,SAASC,UAAU,EAAEC,WAAW,QAAQ,UAAU;AAWlD,SAASC,mBAAmB,EAAEC,OAAO,EAA2B;IAC9D,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAEC,YAAY,EAAE,GAAGP,eAAe;IAE/D,sCAAsC;IACtC,IAAIO,aAAaC,MAAM,KAAK,GAAG;QAC7B,qBAAO;IACT;IAEA,IAAIF,aAAaD,YAAY;QAC3B,qBAAO,KAACZ;IACV;IAEA,MAAMgB,aAAaF,aAAaG,IAAI,CAAC,CAACC,IAAMA,EAAEC,KAAK;IACnD,IAAIH,YAAY;QACd,MAAMA,WAAWG,KAAK;IACxB;IAEA,MAAMC,cAAcN,aAAaO,IAAI,CAAC,CAACC,YAAc,AAACA,CAAAA,UAAUC,IAAI,EAAEC,gBAAgB,EAAE,AAAD,EAAGT,MAAM,GAAG;IACnG,IAAI,CAACK,aAAa;QAChB,qBAAO,KAACnB;YAAcwB,UAAS;;IACjC;IAEA,qBACE,MAAC5B;QAAM6B,IAAI;YAAEC,QAAQ;QAAO;QAAGC,KAAK;;0BAClC,KAAChC;gBAAI8B,IAAI;oBAAEC,QAAQ;oBAAOE,YAAY;gBAAE;0BACtC,cAAA,KAAC1B;oBACC2B,cAAc;wBACZC,YAAY;oBACd;oBACAC,YAAY;wBACVC,MAAM;wBACNC,MAAM;4BACJvB;4BACAwB,SAAS;gCAAEC,MAAM;4BAAG;4BACpBC,QAAQ;gCACNJ,MAAM;gCACNC,MAAM;oCACJI,MAAM7B;gCACR;4BACF;wBACF;oBACF;;;0BAGJ,KAACN;gBACCuB,IAAI;oBAAEa,UAAU;gBAAE;gBAClBT,cAAc;oBACZC,YAAY;gBACd;gBACAC,YAAY;oBACVC,MAAM;oBACNC,MAAM;wBACJvB;wBACAwB,SAAS;4BAAEC,MAAM;wBAAG;wBACpBC,QAAQ;4BACNJ,MAAM;4BACNC,MAAM;gCACJM,OAAO;oCACLC,OAAOhC;gCACT;4BACF;wBACF;oBACF;gBACF;;;;AAIR;AAOA,SAASiC,uBAAuBC,KAAkC;IAChE,MAAM,EAAEhC,OAAO,EAAEiC,cAAc,EAAE,GAAGD;IACpC,MAAME,aAAclC,OAAO,CAAC,EAAE,EAAEuB,KAAKG,OAAOH,MAA0CY;IAEtF,qBACE,KAAC3C;QACC6B,YAAY;YACVC,MAAM;YACNC,MAAM;gBACJvB;gBACAwB,SAAS;oBAAEC,MAAM,CAAC,MAAM,EAAES,YAAY;gBAAC;gBACvCR,QAAQ;oBACNJ,MAAM;oBACNC,MAAM;wBACJM,OAAO;4BACLC,OAAOhC;4BACPsC,MAAMvC;wBACR;wBACAoC;oBACF;gBACF;YACF;QACF;;AAGN;AAEA,OAAO,SAASI;IACd,MAAM,EACJzB,MAAM,EAAEZ,UAAU,EAAE,EAAEsC,QAAQL,cAAc,EAAE,EAC9CM,OAAO,EACR,GAAG9C;IAEJ,sDAAsD;IACtD,MAAM+C,cAAcxC,QAAQI,MAAM,GAC9BJ,QAAQyC,GAAG,CAAC,CAACN;QACX,OAAO;YACLb,MAAMa,MAAMZ,IAAI,CAACG,MAAM,CAACJ,IAAI;YAC5BC,MAAMY,MAAMZ,IAAI,CAACG,MAAM,CAACH,IAAI;QAC9B;IACF,KACA,EAAE;IAEN,MAAMW,aAAclC,OAAO,CAAC,EAAE,EAAEuB,KAAKG,OAAOH,MAA0CY;IACtF,MAAMO,gBAAgBnD,eAAe2C,cAAc;IAEnD,qBACE,MAAChD;QAAM+B,KAAK;QAAGF,IAAI;YAAE4B,OAAO;QAAO;;0BACjC,KAAChD;gBACCiD,YAAY;oBAAC;iBAAa;gBAC1BC,UAAU,CAACC,aAAeP,QAAQ;wBAAEvC,SAAS8C;oBAAW;gBACxD9C,SAASA;;0BAGX,KAACZ;gBAAc2D,mBAAmB5D;gBAAY6D,WAAW;oBAAChD;iBAAQ;0BAChE,cAAA,KAACN;oBAAoB8C,aAAaA;8BAChC,cAAA,KAACvD;wBAAI+B,QAAQ;kCACV0B,8BACC,KAACX;4BAAuB/B,SAASA;4BAASiC,gBAAgBA;2CAE1D,KAAClC;4BAAmBC,SAASA;;;;;;;AAO3C"}
1
+ {"version":3,"sources":["../../../src/explore/TempoExplorer.tsx"],"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 { Box, Stack } from '@mui/material';\nimport { ErrorAlert, ErrorBoundary, LoadingOverlay, NoDataOverlay } from '@perses-dev/components';\nimport { QueryDefinition, isValidTraceId } from '@perses-dev/core';\nimport { Panel } from '@perses-dev/dashboards';\nimport { useExplorerManagerContext } from '@perses-dev/explore';\nimport { DataQueriesProvider, MultiQueryEditor, useDataQueries } from '@perses-dev/plugin-system';\nimport { ReactElement } from 'react';\nimport { TempoTraceQuerySpec } from '../model';\nimport { linkToSpan, linkToTrace } from './links';\n\ninterface TracesExplorerQueryParams {\n queries?: QueryDefinition[];\n spanId?: string;\n}\n\ninterface SearchResultsPanelProps {\n queries: QueryDefinition[];\n}\n\nfunction SearchResultsPanel({ queries }: SearchResultsPanelProps): ReactElement {\n const { isFetching, isLoading, queryResults } = useDataQueries('TraceQuery');\n\n // no query executed, show empty panel\n if (queryResults.length === 0) {\n return <></>;\n }\n\n if (isLoading || isFetching) {\n return <LoadingOverlay />;\n }\n\n const queryError = queryResults.find((d) => d.error);\n if (queryError) {\n throw queryError.error;\n }\n\n const tracesFound = queryResults.some((traceData) => (traceData.data?.searchResult ?? []).length > 0);\n if (!tracesFound) {\n return <NoDataOverlay resource=\"traces\" />;\n }\n\n return (\n <Stack sx={{ height: '100%' }} gap={2}>\n <Box sx={{ height: '35%', flexShrink: 0 }}>\n <Panel\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'ScatterChart',\n spec: {\n link: linkToTrace,\n },\n },\n },\n }}\n />\n </Box>\n <Panel\n sx={{ flexGrow: 1 }}\n panelOptions={{\n hideHeader: true,\n }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: '' },\n plugin: {\n kind: 'TraceTable',\n spec: {\n links: {\n trace: linkToTrace,\n },\n },\n },\n },\n }}\n />\n </Stack>\n );\n}\n\ninterface TracingGanttChartPanelProps {\n queries: QueryDefinition[];\n selectedSpanId?: string;\n}\n\nfunction TracingGanttChartPanel(props: TracingGanttChartPanelProps): ReactElement {\n const { queries, selectedSpanId } = props;\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n\n return (\n <Panel\n panelOptions={{ showIcons: 'always' }}\n definition={{\n kind: 'Panel',\n spec: {\n queries,\n display: { name: `Trace ${firstQuery}` },\n plugin: {\n kind: 'TracingGanttChart',\n spec: {\n links: {\n trace: linkToTrace,\n span: linkToSpan,\n },\n selectedSpanId,\n },\n },\n },\n }}\n />\n );\n}\n\nexport function TempoExplorer(): ReactElement {\n const {\n data: { queries = [], spanId: selectedSpanId },\n setData,\n } = useExplorerManagerContext<TracesExplorerQueryParams>();\n\n // map TraceQueryDefinition to Definition<UnknownSpec>\n const definitions = queries.length\n ? queries.map((query: QueryDefinition) => {\n return {\n kind: query.spec.plugin.kind,\n spec: query.spec.plugin.spec,\n };\n })\n : [];\n\n const firstQuery = (queries[0]?.spec.plugin.spec as TempoTraceQuerySpec | undefined)?.query;\n const isSingleTrace = isValidTraceId(firstQuery ?? '');\n\n return (\n <Stack gap={2} sx={{ width: '100%' }}>\n <MultiQueryEditor\n queryTypes={['TraceQuery']}\n onChange={(newQueries) => setData({ queries: newQueries })}\n queries={queries}\n />\n\n <ErrorBoundary FallbackComponent={ErrorAlert} resetKeys={[queries]}>\n <DataQueriesProvider definitions={definitions}>\n <Box height={700}>\n {isSingleTrace ? (\n <TracingGanttChartPanel queries={queries} selectedSpanId={selectedSpanId} />\n ) : (\n <SearchResultsPanel queries={queries} />\n )}\n </Box>\n </DataQueriesProvider>\n </ErrorBoundary>\n </Stack>\n );\n}\n"],"names":["Box","Stack","ErrorAlert","ErrorBoundary","LoadingOverlay","NoDataOverlay","isValidTraceId","Panel","useExplorerManagerContext","DataQueriesProvider","MultiQueryEditor","useDataQueries","linkToSpan","linkToTrace","SearchResultsPanel","queries","isFetching","isLoading","queryResults","length","queryError","find","d","error","tracesFound","some","traceData","data","searchResult","resource","sx","height","gap","flexShrink","panelOptions","hideHeader","definition","kind","spec","display","name","plugin","link","flexGrow","links","trace","TracingGanttChartPanel","props","selectedSpanId","firstQuery","query","showIcons","span","TempoExplorer","spanId","setData","definitions","map","isSingleTrace","width","queryTypes","onChange","newQueries","FallbackComponent","resetKeys"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAY5D,OAAO,EAAE,qBAAqB,EAAiB,MAAM,sBAAsB,CAAC;AAE5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA2FhF;AASD,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAyBlD"}
1
+ {"version":3,"file":"TempoTraceQueryEditor.d.ts","sourceRoot":"","sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"names":[],"mappings":"AAsBA,OAAO,EAAE,YAAY,EAAyB,MAAM,OAAO,CAAC;AAY5D,OAAO,EAAE,qBAAqB,EAAiB,MAAM,sBAAsB,CAAC;AAE5E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,qBAAqB,GAAG,YAAY,CA6FhF;AASD,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,2CAyBlD"}
@@ -37,6 +37,10 @@ export function TempoTraceQueryEditor(props) {
37
37
  const nextDatasource = isDefaultTempoSelector(next) ? undefined : next;
38
38
  draft.datasource = nextDatasource;
39
39
  }));
40
+ if (queryHandlerSettings?.setWatchOtherSpecs) queryHandlerSettings.setWatchOtherSpecs({
41
+ ...value,
42
+ datasource: next
43
+ });
40
44
  return;
41
45
  }
42
46
  throw new Error('Got unexpected non-Tempo datasource selector');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2025 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 { Box, Button, FormControl, InputLabel, MenuItem, Select, Stack } from '@mui/material';\nimport { useId } from '@perses-dev/components';\nimport {\n DatasourceSelect,\n DatasourceSelectProps,\n useDatasourceClient,\n useDatasourceSelectValueToSelector,\n} from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport { ReactElement, useCallback, useState } from 'react';\nimport { TraceQLEditor } from '../../components';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n DEFAULT_TEMPO,\n isDefaultTempoSelector,\n isTempoDatasourceSelector,\n TEMPO_DATASOURCE_KIND,\n} from '../../model/tempo-selectors';\nimport { AttributeFilters } from '../../components/AttributeFilters';\nimport { filterToTraceQL } from '../../components/filter/filter_to_traceql';\nimport { traceQLToFilter } from '../../components/filter/traceql_to_filter';\nimport { TraceQueryEditorProps, useQueryState } from './query-editor-model';\n\nexport function TempoTraceQueryEditor(props: TraceQueryEditorProps): ReactElement {\n const {\n onChange,\n value,\n value: { datasource, limit },\n queryHandlerSettings,\n } = props;\n\n const datasourceSelectValue = datasource ?? DEFAULT_TEMPO;\n const selectedDatasource = useDatasourceSelectValueToSelector(datasourceSelectValue, TEMPO_DATASOURCE_KIND);\n const datasourceSelectLabelID = useId('tempo-datasource-label'); // for panels with multiple queries, this component is rendered multiple times on the same page\n\n const { data: client } = useDatasourceClient<TempoClient>(selectedDatasource);\n const { query, handleQueryChange, handleQueryBlur } = useQueryState(props);\n const [showAttributeFilters, setShowAttributeFilters] = useState(() => isSimpleTraceQLQuery(query));\n\n const handleDatasourceChange: DatasourceSelectProps['onChange'] = (next) => {\n if (isTempoDatasourceSelector(next)) {\n onChange(\n produce(value, (draft) => {\n // If they're using the default, just omit the datasource prop (i.e. set to undefined)\n const nextDatasource = isDefaultTempoSelector(next) ? undefined : next;\n draft.datasource = nextDatasource;\n })\n );\n return;\n }\n\n throw new Error('Got unexpected non-Tempo datasource selector');\n };\n\n const runQuery = (newQuery: string) => {\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(newQuery);\n }\n onChange(\n produce(value, (draft) => {\n draft.query = newQuery;\n })\n );\n };\n\n const handleTraceQueryChange = useCallback(\n (e: string) => {\n handleQueryChange(e);\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(e);\n }\n },\n [handleQueryChange, queryHandlerSettings]\n );\n\n return (\n <Stack spacing={2}>\n <FormControl margin=\"dense\" fullWidth={false}>\n <DatasourceSelect\n datasourcePluginKind={TEMPO_DATASOURCE_KIND}\n value={datasourceSelectValue}\n onChange={handleDatasourceChange}\n labelId={datasourceSelectLabelID}\n label=\"Tempo Datasource\"\n notched\n />\n </FormControl>\n <Stack direction=\"row\" spacing={2} sx={{ alignItems: 'flex-start' }}>\n {showAttributeFilters ? (\n <AttributeFilters client={client} query={query} setQuery={runQuery} />\n ) : (\n <TraceQLEditor\n client={client}\n value={query}\n onChange={handleTraceQueryChange}\n onBlur={queryHandlerSettings?.runWithOnBlur ? handleQueryBlur : undefined}\n />\n )}\n <Button onClick={() => setShowAttributeFilters(!showAttributeFilters)}>\n {showAttributeFilters ? 'Show query' : 'Hide query'}\n </Button>\n <LimitSelect\n value={limit ?? 20}\n setValue={(newLimit: number) =>\n onChange(\n produce(value, (draft) => {\n draft.limit = newLimit;\n })\n )\n }\n />\n </Stack>\n </Stack>\n );\n}\n\nfunction isSimpleTraceQLQuery(query: string) {\n // if a query can be transformed to a filter and back to the original query, we can show the attribute filter toolbar\n return query == '' || filterToTraceQL(traceQLToFilter(query)) === query;\n}\n\nconst limitOptions = [20, 50, 100, 500, 1000, 5000];\n\ninterface LimitSelectProps {\n value: number;\n setValue: (x: number) => void;\n}\n\nexport function LimitSelect(props: LimitSelectProps) {\n const { value, setValue } = props;\n\n // the outer <Box> is required, because <FormControl> has display: inline-flex, which doesn't work with the parent <Stack> of the query editor\n return (\n <Box>\n <FormControl size=\"small\">\n <InputLabel id=\"max-traces-label\">Max Traces</InputLabel>\n <Select\n labelId=\"max-traces-label\"\n id=\"max-traces-select\"\n value={value}\n label=\"Max Traces\"\n onChange={(e) => setValue(typeof e.target.value === 'number' ? e.target.value : parseInt(e.target.value))}\n sx={{ width: 110 }}\n >\n {limitOptions.map((option) => (\n <MenuItem key={option} value={option}>\n {option}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n );\n}\n"],"names":["Box","Button","FormControl","InputLabel","MenuItem","Select","Stack","useId","DatasourceSelect","useDatasourceClient","useDatasourceSelectValueToSelector","produce","useCallback","useState","TraceQLEditor","DEFAULT_TEMPO","isDefaultTempoSelector","isTempoDatasourceSelector","TEMPO_DATASOURCE_KIND","AttributeFilters","filterToTraceQL","traceQLToFilter","useQueryState","TempoTraceQueryEditor","props","onChange","value","datasource","limit","queryHandlerSettings","datasourceSelectValue","selectedDatasource","datasourceSelectLabelID","data","client","query","handleQueryChange","handleQueryBlur","showAttributeFilters","setShowAttributeFilters","isSimpleTraceQLQuery","handleDatasourceChange","next","draft","nextDatasource","undefined","Error","runQuery","newQuery","watchQueryChanges","handleTraceQueryChange","e","spacing","margin","fullWidth","datasourcePluginKind","labelId","label","notched","direction","sx","alignItems","setQuery","onBlur","runWithOnBlur","onClick","LimitSelect","setValue","newLimit","limitOptions","size","id","target","parseInt","width","map","option"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/plugins/tempo-trace-query/TempoTraceQueryEditor.tsx"],"sourcesContent":["// Copyright 2025 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 { Box, Button, FormControl, InputLabel, MenuItem, Select, Stack } from '@mui/material';\nimport { useId } from '@perses-dev/components';\nimport {\n DatasourceSelect,\n DatasourceSelectProps,\n useDatasourceClient,\n useDatasourceSelectValueToSelector,\n} from '@perses-dev/plugin-system';\nimport { produce } from 'immer';\nimport { ReactElement, useCallback, useState } from 'react';\nimport { TraceQLEditor } from '../../components';\nimport { TempoClient } from '../../model/tempo-client';\nimport {\n DEFAULT_TEMPO,\n isDefaultTempoSelector,\n isTempoDatasourceSelector,\n TEMPO_DATASOURCE_KIND,\n} from '../../model/tempo-selectors';\nimport { AttributeFilters } from '../../components/AttributeFilters';\nimport { filterToTraceQL } from '../../components/filter/filter_to_traceql';\nimport { traceQLToFilter } from '../../components/filter/traceql_to_filter';\nimport { TraceQueryEditorProps, useQueryState } from './query-editor-model';\n\nexport function TempoTraceQueryEditor(props: TraceQueryEditorProps): ReactElement {\n const {\n onChange,\n value,\n value: { datasource, limit },\n queryHandlerSettings,\n } = props;\n\n const datasourceSelectValue = datasource ?? DEFAULT_TEMPO;\n const selectedDatasource = useDatasourceSelectValueToSelector(datasourceSelectValue, TEMPO_DATASOURCE_KIND);\n const datasourceSelectLabelID = useId('tempo-datasource-label'); // for panels with multiple queries, this component is rendered multiple times on the same page\n\n const { data: client } = useDatasourceClient<TempoClient>(selectedDatasource);\n const { query, handleQueryChange, handleQueryBlur } = useQueryState(props);\n const [showAttributeFilters, setShowAttributeFilters] = useState(() => isSimpleTraceQLQuery(query));\n\n const handleDatasourceChange: DatasourceSelectProps['onChange'] = (next) => {\n if (isTempoDatasourceSelector(next)) {\n onChange(\n produce(value, (draft) => {\n // If they're using the default, just omit the datasource prop (i.e. set to undefined)\n const nextDatasource = isDefaultTempoSelector(next) ? undefined : next;\n draft.datasource = nextDatasource;\n })\n );\n if (queryHandlerSettings?.setWatchOtherSpecs)\n queryHandlerSettings.setWatchOtherSpecs({ ...value, datasource: next });\n return;\n }\n\n throw new Error('Got unexpected non-Tempo datasource selector');\n };\n\n const runQuery = (newQuery: string) => {\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(newQuery);\n }\n onChange(\n produce(value, (draft) => {\n draft.query = newQuery;\n })\n );\n };\n\n const handleTraceQueryChange = useCallback(\n (e: string) => {\n handleQueryChange(e);\n if (queryHandlerSettings?.watchQueryChanges) {\n queryHandlerSettings.watchQueryChanges(e);\n }\n },\n [handleQueryChange, queryHandlerSettings]\n );\n\n return (\n <Stack spacing={2}>\n <FormControl margin=\"dense\" fullWidth={false}>\n <DatasourceSelect\n datasourcePluginKind={TEMPO_DATASOURCE_KIND}\n value={datasourceSelectValue}\n onChange={handleDatasourceChange}\n labelId={datasourceSelectLabelID}\n label=\"Tempo Datasource\"\n notched\n />\n </FormControl>\n <Stack direction=\"row\" spacing={2} sx={{ alignItems: 'flex-start' }}>\n {showAttributeFilters ? (\n <AttributeFilters client={client} query={query} setQuery={runQuery} />\n ) : (\n <TraceQLEditor\n client={client}\n value={query}\n onChange={handleTraceQueryChange}\n onBlur={queryHandlerSettings?.runWithOnBlur ? handleQueryBlur : undefined}\n />\n )}\n <Button onClick={() => setShowAttributeFilters(!showAttributeFilters)}>\n {showAttributeFilters ? 'Show query' : 'Hide query'}\n </Button>\n <LimitSelect\n value={limit ?? 20}\n setValue={(newLimit: number) =>\n onChange(\n produce(value, (draft) => {\n draft.limit = newLimit;\n })\n )\n }\n />\n </Stack>\n </Stack>\n );\n}\n\nfunction isSimpleTraceQLQuery(query: string) {\n // if a query can be transformed to a filter and back to the original query, we can show the attribute filter toolbar\n return query == '' || filterToTraceQL(traceQLToFilter(query)) === query;\n}\n\nconst limitOptions = [20, 50, 100, 500, 1000, 5000];\n\ninterface LimitSelectProps {\n value: number;\n setValue: (x: number) => void;\n}\n\nexport function LimitSelect(props: LimitSelectProps) {\n const { value, setValue } = props;\n\n // the outer <Box> is required, because <FormControl> has display: inline-flex, which doesn't work with the parent <Stack> of the query editor\n return (\n <Box>\n <FormControl size=\"small\">\n <InputLabel id=\"max-traces-label\">Max Traces</InputLabel>\n <Select\n labelId=\"max-traces-label\"\n id=\"max-traces-select\"\n value={value}\n label=\"Max Traces\"\n onChange={(e) => setValue(typeof e.target.value === 'number' ? e.target.value : parseInt(e.target.value))}\n sx={{ width: 110 }}\n >\n {limitOptions.map((option) => (\n <MenuItem key={option} value={option}>\n {option}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Box>\n );\n}\n"],"names":["Box","Button","FormControl","InputLabel","MenuItem","Select","Stack","useId","DatasourceSelect","useDatasourceClient","useDatasourceSelectValueToSelector","produce","useCallback","useState","TraceQLEditor","DEFAULT_TEMPO","isDefaultTempoSelector","isTempoDatasourceSelector","TEMPO_DATASOURCE_KIND","AttributeFilters","filterToTraceQL","traceQLToFilter","useQueryState","TempoTraceQueryEditor","props","onChange","value","datasource","limit","queryHandlerSettings","datasourceSelectValue","selectedDatasource","datasourceSelectLabelID","data","client","query","handleQueryChange","handleQueryBlur","showAttributeFilters","setShowAttributeFilters","isSimpleTraceQLQuery","handleDatasourceChange","next","draft","nextDatasource","undefined","setWatchOtherSpecs","Error","runQuery","newQuery","watchQueryChanges","handleTraceQueryChange","e","spacing","margin","fullWidth","datasourcePluginKind","labelId","label","notched","direction","sx","alignItems","setQuery","onBlur","runWithOnBlur","onClick","LimitSelect","setValue","newLimit","limitOptions","size","id","target","parseInt","width","map","option"],"mappings":"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"}
package/mf-manifest.json CHANGED
@@ -5,11 +5,11 @@
5
5
  "name": "Tempo",
6
6
  "type": "app",
7
7
  "buildInfo": {
8
- "buildVersion": "0.53.0",
8
+ "buildVersion": "0.53.2",
9
9
  "buildName": "@perses-dev/tempo-plugin"
10
10
  },
11
11
  "remoteEntry": {
12
- "name": "__mf/js/Tempo.2f6d49a1.js",
12
+ "name": "__mf/js/Tempo.2d6235bb.js",
13
13
  "path": "",
14
14
  "type": "global"
15
15
  },
@@ -20,7 +20,7 @@
20
20
  "api": ""
21
21
  },
22
22
  "globalName": "Tempo",
23
- "pluginVersion": "0.18.1",
23
+ "pluginVersion": "0.19.1",
24
24
  "prefetchInterface": false,
25
25
  "publicPath": "/plugins/Tempo/"
26
26
  },
@@ -88,14 +88,14 @@
88
88
  {
89
89
  "id": "Tempo:@perses-dev/components",
90
90
  "name": "@perses-dev/components",
91
- "version": "0.52.0-beta.5",
91
+ "version": "0.52.0",
92
92
  "singleton": true,
93
- "requiredVersion": "^0.52.0-beta.5",
93
+ "requiredVersion": "^0.52.0",
94
94
  "assets": {
95
95
  "js": {
96
96
  "async": [],
97
97
  "sync": [
98
- "__mf/js/async/2913.f73e6635.js"
98
+ "__mf/js/async/6286.6e0d8da6.js"
99
99
  ]
100
100
  },
101
101
  "css": {
@@ -107,14 +107,14 @@
107
107
  {
108
108
  "id": "Tempo:@perses-dev/dashboards",
109
109
  "name": "@perses-dev/dashboards",
110
- "version": "0.52.0-beta.5",
110
+ "version": "0.52.0",
111
111
  "singleton": true,
112
- "requiredVersion": "^0.52.0-beta.5",
112
+ "requiredVersion": "^0.52.0",
113
113
  "assets": {
114
114
  "js": {
115
115
  "async": [],
116
116
  "sync": [
117
- "__mf/js/async/1101.0dae4724.js"
117
+ "__mf/js/async/3391.41e6de04.js"
118
118
  ]
119
119
  },
120
120
  "css": {
@@ -126,14 +126,14 @@
126
126
  {
127
127
  "id": "Tempo:@perses-dev/explore",
128
128
  "name": "@perses-dev/explore",
129
- "version": "0.52.0-beta.5",
129
+ "version": "0.52.0",
130
130
  "singleton": true,
131
- "requiredVersion": "^0.52.0-beta.5",
131
+ "requiredVersion": "^0.52.0",
132
132
  "assets": {
133
133
  "js": {
134
134
  "async": [],
135
135
  "sync": [
136
- "__mf/js/async/4421.14238d27.js"
136
+ "__mf/js/async/4421.838809cd.js"
137
137
  ]
138
138
  },
139
139
  "css": {
@@ -145,14 +145,14 @@
145
145
  {
146
146
  "id": "Tempo:@perses-dev/plugin-system",
147
147
  "name": "@perses-dev/plugin-system",
148
- "version": "0.52.0-beta.5",
148
+ "version": "0.52.0",
149
149
  "singleton": true,
150
- "requiredVersion": "^0.52.0-beta.5",
150
+ "requiredVersion": "^0.52.0",
151
151
  "assets": {
152
152
  "js": {
153
153
  "async": [],
154
154
  "sync": [
155
- "__mf/js/async/4368.bd6fd0e7.js"
155
+ "__mf/js/async/4368.2c879fe0.js"
156
156
  ]
157
157
  },
158
158
  "css": {
@@ -322,7 +322,7 @@
322
322
  "assets": {
323
323
  "js": {
324
324
  "sync": [
325
- "__mf/js/async/__federation_expose_TempoDatasource.fa3e24f9.js"
325
+ "__mf/js/async/__federation_expose_TempoDatasource.a20f4483.js"
326
326
  ],
327
327
  "async": [
328
328
  "__mf/js/async/lib-router.312ca028.js",
@@ -331,11 +331,11 @@
331
331
  "__mf/js/async/5266.1c520126.js",
332
332
  "__mf/js/async/8597.d5ba4ca7.js",
333
333
  "__mf/js/async/2981.8fe4ed12.js",
334
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js",
334
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js",
335
335
  "__mf/js/async/6751.03514b88.js",
336
336
  "__mf/js/async/7376.588b7a17.js",
337
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js",
338
- "__mf/js/async/5876.47f40562.js",
337
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js",
338
+ "__mf/js/async/6714.11904981.js",
339
339
  "__mf/js/async/4535.7c92d3fd.js",
340
340
  "__mf/js/async/7127.a0877987.js",
341
341
  "__mf/js/async/4238.7962a7a1.js",
@@ -365,7 +365,7 @@
365
365
  "__mf/js/async/5266.1c520126.js",
366
366
  "__mf/js/async/8597.d5ba4ca7.js",
367
367
  "__mf/js/async/2981.8fe4ed12.js",
368
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js"
368
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js"
369
369
  ],
370
370
  "async": [
371
371
  "__mf/js/async/4238.7962a7a1.js",
@@ -373,10 +373,10 @@
373
373
  "__mf/js/async/lib-router.312ca028.js",
374
374
  "__mf/js/async/6751.03514b88.js",
375
375
  "__mf/js/async/7376.588b7a17.js",
376
- "__mf/js/async/5876.47f40562.js",
376
+ "__mf/js/async/6714.11904981.js",
377
377
  "__mf/js/async/4535.7c92d3fd.js",
378
378
  "__mf/js/async/5266.1c520126.js",
379
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js",
379
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js",
380
380
  "__mf/js/async/7127.a0877987.js",
381
381
  "__mf/js/async/2292.75e9aa11.js",
382
382
  "__mf/js/async/8488.6c9a25e4.js",
@@ -401,7 +401,7 @@
401
401
  "js": {
402
402
  "sync": [
403
403
  "__mf/js/async/5266.1c520126.js",
404
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js"
404
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js"
405
405
  ],
406
406
  "async": [
407
407
  "__mf/js/async/9368.f0418d24.js",
@@ -409,13 +409,13 @@
409
409
  "__mf/js/async/5266.1c520126.js",
410
410
  "__mf/js/async/8597.d5ba4ca7.js",
411
411
  "__mf/js/async/2981.8fe4ed12.js",
412
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js",
412
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js",
413
413
  "__mf/js/async/7376.588b7a17.js",
414
414
  "__mf/js/async/4535.7c92d3fd.js",
415
415
  "__mf/js/async/8488.6c9a25e4.js",
416
416
  "__mf/js/async/lib-router.312ca028.js",
417
417
  "__mf/js/async/6751.03514b88.js",
418
- "__mf/js/async/5876.47f40562.js",
418
+ "__mf/js/async/6714.11904981.js",
419
419
  "__mf/js/async/4238.7962a7a1.js",
420
420
  "__mf/js/async/3224.ce173388.js",
421
421
  "__mf/js/async/2292.75e9aa11.js",
package/mf-stats.json CHANGED
@@ -5,11 +5,11 @@
5
5
  "name": "Tempo",
6
6
  "type": "app",
7
7
  "buildInfo": {
8
- "buildVersion": "0.53.0",
8
+ "buildVersion": "0.53.2",
9
9
  "buildName": "@perses-dev/tempo-plugin"
10
10
  },
11
11
  "remoteEntry": {
12
- "name": "__mf/js/Tempo.2f6d49a1.js",
12
+ "name": "__mf/js/Tempo.2d6235bb.js",
13
13
  "path": "",
14
14
  "type": "global"
15
15
  },
@@ -20,7 +20,7 @@
20
20
  "api": ""
21
21
  },
22
22
  "globalName": "Tempo",
23
- "pluginVersion": "0.18.1",
23
+ "pluginVersion": "0.19.1",
24
24
  "prefetchInterface": false,
25
25
  "publicPath": "/plugins/Tempo/"
26
26
  },
@@ -96,17 +96,17 @@
96
96
  },
97
97
  {
98
98
  "singleton": true,
99
- "requiredVersion": "^0.52.0-beta.5",
99
+ "requiredVersion": "^0.52.0",
100
100
  "shareScope": "default",
101
101
  "name": "@perses-dev/components",
102
- "version": "0.52.0-beta.5",
102
+ "version": "0.52.0",
103
103
  "eager": false,
104
104
  "id": "Tempo:@perses-dev/components",
105
105
  "assets": {
106
106
  "js": {
107
107
  "async": [],
108
108
  "sync": [
109
- "__mf/js/async/2913.f73e6635.js"
109
+ "__mf/js/async/6286.6e0d8da6.js"
110
110
  ]
111
111
  },
112
112
  "css": {
@@ -121,17 +121,17 @@
121
121
  },
122
122
  {
123
123
  "singleton": true,
124
- "requiredVersion": "^0.52.0-beta.5",
124
+ "requiredVersion": "^0.52.0",
125
125
  "shareScope": "default",
126
126
  "name": "@perses-dev/dashboards",
127
- "version": "0.52.0-beta.5",
127
+ "version": "0.52.0",
128
128
  "eager": false,
129
129
  "id": "Tempo:@perses-dev/dashboards",
130
130
  "assets": {
131
131
  "js": {
132
132
  "async": [],
133
133
  "sync": [
134
- "__mf/js/async/1101.0dae4724.js"
134
+ "__mf/js/async/3391.41e6de04.js"
135
135
  ]
136
136
  },
137
137
  "css": {
@@ -145,17 +145,17 @@
145
145
  },
146
146
  {
147
147
  "singleton": true,
148
- "requiredVersion": "^0.52.0-beta.5",
148
+ "requiredVersion": "^0.52.0",
149
149
  "shareScope": "default",
150
150
  "name": "@perses-dev/explore",
151
- "version": "0.52.0-beta.5",
151
+ "version": "0.52.0",
152
152
  "eager": false,
153
153
  "id": "Tempo:@perses-dev/explore",
154
154
  "assets": {
155
155
  "js": {
156
156
  "async": [],
157
157
  "sync": [
158
- "__mf/js/async/4421.14238d27.js"
158
+ "__mf/js/async/4421.838809cd.js"
159
159
  ]
160
160
  },
161
161
  "css": {
@@ -169,17 +169,17 @@
169
169
  },
170
170
  {
171
171
  "singleton": true,
172
- "requiredVersion": "^0.52.0-beta.5",
172
+ "requiredVersion": "^0.52.0",
173
173
  "shareScope": "default",
174
174
  "name": "@perses-dev/plugin-system",
175
- "version": "0.52.0-beta.5",
175
+ "version": "0.52.0",
176
176
  "eager": false,
177
177
  "id": "Tempo:@perses-dev/plugin-system",
178
178
  "assets": {
179
179
  "js": {
180
180
  "async": [],
181
181
  "sync": [
182
- "__mf/js/async/4368.bd6fd0e7.js"
182
+ "__mf/js/async/4368.2c879fe0.js"
183
183
  ]
184
184
  },
185
185
  "css": {
@@ -391,7 +391,7 @@
391
391
  "assets": {
392
392
  "js": {
393
393
  "sync": [
394
- "__mf/js/async/__federation_expose_TempoDatasource.fa3e24f9.js"
394
+ "__mf/js/async/__federation_expose_TempoDatasource.a20f4483.js"
395
395
  ],
396
396
  "async": [
397
397
  "__mf/js/async/lib-router.312ca028.js",
@@ -400,11 +400,11 @@
400
400
  "__mf/js/async/5266.1c520126.js",
401
401
  "__mf/js/async/8597.d5ba4ca7.js",
402
402
  "__mf/js/async/2981.8fe4ed12.js",
403
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js",
403
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js",
404
404
  "__mf/js/async/6751.03514b88.js",
405
405
  "__mf/js/async/7376.588b7a17.js",
406
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js",
407
- "__mf/js/async/5876.47f40562.js",
406
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js",
407
+ "__mf/js/async/6714.11904981.js",
408
408
  "__mf/js/async/4535.7c92d3fd.js",
409
409
  "__mf/js/async/7127.a0877987.js",
410
410
  "__mf/js/async/4238.7962a7a1.js",
@@ -442,7 +442,7 @@
442
442
  "__mf/js/async/5266.1c520126.js",
443
443
  "__mf/js/async/8597.d5ba4ca7.js",
444
444
  "__mf/js/async/2981.8fe4ed12.js",
445
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js"
445
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js"
446
446
  ],
447
447
  "async": [
448
448
  "__mf/js/async/4238.7962a7a1.js",
@@ -450,10 +450,10 @@
450
450
  "__mf/js/async/lib-router.312ca028.js",
451
451
  "__mf/js/async/6751.03514b88.js",
452
452
  "__mf/js/async/7376.588b7a17.js",
453
- "__mf/js/async/5876.47f40562.js",
453
+ "__mf/js/async/6714.11904981.js",
454
454
  "__mf/js/async/4535.7c92d3fd.js",
455
455
  "__mf/js/async/5266.1c520126.js",
456
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js",
456
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js",
457
457
  "__mf/js/async/7127.a0877987.js",
458
458
  "__mf/js/async/2292.75e9aa11.js",
459
459
  "__mf/js/async/8488.6c9a25e4.js",
@@ -485,7 +485,7 @@
485
485
  "js": {
486
486
  "sync": [
487
487
  "__mf/js/async/5266.1c520126.js",
488
- "__mf/js/async/__federation_expose_TempoExplorer.9949b25e.js"
488
+ "__mf/js/async/__federation_expose_TempoExplorer.bc71c3ab.js"
489
489
  ],
490
490
  "async": [
491
491
  "__mf/js/async/9368.f0418d24.js",
@@ -493,13 +493,13 @@
493
493
  "__mf/js/async/5266.1c520126.js",
494
494
  "__mf/js/async/8597.d5ba4ca7.js",
495
495
  "__mf/js/async/2981.8fe4ed12.js",
496
- "__mf/js/async/__federation_expose_TempoTraceQuery.13537765.js",
496
+ "__mf/js/async/__federation_expose_TempoTraceQuery.3098cb27.js",
497
497
  "__mf/js/async/7376.588b7a17.js",
498
498
  "__mf/js/async/4535.7c92d3fd.js",
499
499
  "__mf/js/async/8488.6c9a25e4.js",
500
500
  "__mf/js/async/lib-router.312ca028.js",
501
501
  "__mf/js/async/6751.03514b88.js",
502
- "__mf/js/async/5876.47f40562.js",
502
+ "__mf/js/async/6714.11904981.js",
503
503
  "__mf/js/async/4238.7962a7a1.js",
504
504
  "__mf/js/async/3224.ce173388.js",
505
505
  "__mf/js/async/2292.75e9aa11.js",