@likec4/language-server 1.21.1 → 1.22.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 (113) hide show
  1. package/README.md +4 -1
  2. package/bin/likec4-language-server.mjs +5 -2
  3. package/dist/LikeC4FileSystem.js +2 -2
  4. package/dist/browser.d.ts +3 -3
  5. package/dist/browser.js +15 -2
  6. package/dist/bundled.d.ts +8 -0
  7. package/dist/bundled.js +25 -0
  8. package/dist/bundled.mjs +2555 -4022
  9. package/dist/index.d.ts +3 -3
  10. package/dist/index.js +19 -2
  11. package/dist/logger.d.ts +10 -3
  12. package/dist/logger.js +56 -50
  13. package/dist/model/fqn-computation.js +2 -2
  14. package/dist/model/model-builder.js +13 -14
  15. package/dist/model-change/ModelChanges.js +2 -2
  16. package/dist/module.js +1 -4
  17. package/dist/references/scope-provider.js +3 -3
  18. package/dist/view-utils/manual-layout.js +2 -2
  19. package/dist/views/configurable-layouter.js +4 -4
  20. package/dist/views/likec4-views.d.ts +2 -1
  21. package/dist/views/likec4-views.js +2 -2
  22. package/package.json +14 -12
  23. package/dist/test/setup.d.ts +0 -1
  24. package/dist/test/setup.js +0 -7
  25. package/src/LikeC4FileSystem.ts +0 -38
  26. package/src/Rpc.ts +0 -134
  27. package/src/ast.ts +0 -556
  28. package/src/browser.ts +0 -35
  29. package/src/documentation/documentation-provider.ts +0 -52
  30. package/src/documentation/index.ts +0 -1
  31. package/src/formatting/LikeC4Formatter.ts +0 -639
  32. package/src/formatting/utils.ts +0 -26
  33. package/src/generated/ast.ts +0 -3735
  34. package/src/generated/grammar.ts +0 -10
  35. package/src/generated/module.ts +0 -33
  36. package/src/generated-lib/icons.ts +0 -1538
  37. package/src/index.ts +0 -30
  38. package/src/like-c4.langium +0 -901
  39. package/src/likec4lib.ts +0 -6
  40. package/src/logger.ts +0 -80
  41. package/src/lsp/CodeLensProvider.ts +0 -50
  42. package/src/lsp/CompletionProvider.ts +0 -147
  43. package/src/lsp/DocumentHighlightProvider.ts +0 -12
  44. package/src/lsp/DocumentLinkProvider.ts +0 -65
  45. package/src/lsp/DocumentSymbolProvider.ts +0 -313
  46. package/src/lsp/HoverProvider.ts +0 -92
  47. package/src/lsp/RenameProvider.ts +0 -8
  48. package/src/lsp/SemanticTokenProvider.ts +0 -383
  49. package/src/lsp/index.ts +0 -8
  50. package/src/model/deployments-index.ts +0 -209
  51. package/src/model/fqn-computation.ts +0 -83
  52. package/src/model/fqn-index.ts +0 -138
  53. package/src/model/index.ts +0 -6
  54. package/src/model/model-builder.ts +0 -724
  55. package/src/model/model-locator.ts +0 -146
  56. package/src/model/model-parser-where.ts +0 -84
  57. package/src/model/model-parser.ts +0 -86
  58. package/src/model/parser/Base.ts +0 -113
  59. package/src/model/parser/DeploymentModelParser.ts +0 -192
  60. package/src/model/parser/DeploymentViewParser.ts +0 -122
  61. package/src/model/parser/FqnRefParser.ts +0 -143
  62. package/src/model/parser/GlobalsParser.ts +0 -96
  63. package/src/model/parser/ModelParser.ts +0 -170
  64. package/src/model/parser/PredicatesParser.ts +0 -315
  65. package/src/model/parser/SpecificationParser.ts +0 -133
  66. package/src/model/parser/ViewsParser.ts +0 -428
  67. package/src/model-change/ModelChanges.ts +0 -101
  68. package/src/model-change/changeElementStyle.ts +0 -172
  69. package/src/model-change/changeViewLayout.ts +0 -47
  70. package/src/model-change/saveManualLayout.ts +0 -41
  71. package/src/module.ts +0 -255
  72. package/src/protocol.ts +0 -93
  73. package/src/references/index.ts +0 -3
  74. package/src/references/name-provider.ts +0 -37
  75. package/src/references/scope-computation.ts +0 -364
  76. package/src/references/scope-provider.ts +0 -201
  77. package/src/shared/NodeKindProvider.ts +0 -121
  78. package/src/shared/WorkspaceManager.ts +0 -48
  79. package/src/shared/WorkspaceSymbolProvider.ts +0 -3
  80. package/src/shared/index.ts +0 -3
  81. package/src/test/index.ts +0 -1
  82. package/src/test/setup.ts +0 -8
  83. package/src/test/testServices.ts +0 -152
  84. package/src/utils/disposable.ts +0 -30
  85. package/src/utils/elementRef.ts +0 -26
  86. package/src/utils/fqnRef.ts +0 -56
  87. package/src/utils/index.ts +0 -2
  88. package/src/utils/printDocs.ts +0 -3
  89. package/src/utils/stringHash.ts +0 -6
  90. package/src/validation/_shared.ts +0 -29
  91. package/src/validation/deployment-checks.ts +0 -131
  92. package/src/validation/dynamic-view-rule.ts +0 -23
  93. package/src/validation/dynamic-view-step.ts +0 -36
  94. package/src/validation/element.ts +0 -56
  95. package/src/validation/index.ts +0 -171
  96. package/src/validation/property-checks.ts +0 -52
  97. package/src/validation/relation.ts +0 -63
  98. package/src/validation/specification.ts +0 -205
  99. package/src/validation/view-predicates/element-with.ts +0 -36
  100. package/src/validation/view-predicates/expanded-element.ts +0 -16
  101. package/src/validation/view-predicates/expression-v2.ts +0 -101
  102. package/src/validation/view-predicates/incoming.ts +0 -20
  103. package/src/validation/view-predicates/index.ts +0 -6
  104. package/src/validation/view-predicates/outgoing.ts +0 -20
  105. package/src/validation/view-predicates/relation-with.ts +0 -17
  106. package/src/validation/view.ts +0 -37
  107. package/src/view-utils/assignNavigateTo.ts +0 -31
  108. package/src/view-utils/index.ts +0 -2
  109. package/src/view-utils/manual-layout.ts +0 -116
  110. package/src/view-utils/resolve-relative-paths.ts +0 -90
  111. package/src/views/configurable-layouter.ts +0 -65
  112. package/src/views/index.ts +0 -1
  113. package/src/views/likec4-views.ts +0 -139
@@ -1,17 +0,0 @@
1
- import { type ValidationCheck, AstUtils } from 'langium'
2
- import { ast } from '../../ast'
3
- import type { LikeC4Services } from '../../module'
4
- import { tryOrLog } from '../_shared'
5
-
6
- export const relationPredicateWithChecks = (
7
- _services: LikeC4Services,
8
- ): ValidationCheck<ast.RelationPredicateWith> => {
9
- return tryOrLog((el, accept) => {
10
- const container = AstUtils.getContainerOfType(el, ast.isViewRulePredicate)
11
- if (ast.isExcludePredicate(container)) {
12
- accept('error', 'Invalid usage inside "exclude"', {
13
- node: el,
14
- })
15
- }
16
- })
17
- }
@@ -1,37 +0,0 @@
1
- import { type ValidationCheck } from 'langium'
2
- import { ast } from '../ast'
3
- import type { LikeC4Services } from '../module'
4
- import { RESERVED_WORDS, tryOrLog } from './_shared'
5
-
6
- export const viewChecks = (services: LikeC4Services): ValidationCheck<ast.LikeC4View> => {
7
- const index = services.shared.workspace.IndexManager
8
- return tryOrLog((el, accept) => {
9
- // const commentNode = CstUtils.findCommentNode(el.$cstNode, ['BLOCK_COMMENT'])
10
- // if (commentNode && hasManualLayout(commentNode.text) && !deserializeFromComment(commentNode.text)) {
11
- // accept('warning', `Malformed @likec4-generated (ignored)`, {
12
- // node: el,
13
- // range: commentNode.range
14
- // })
15
- // }
16
- if (!el.name) {
17
- return
18
- }
19
- if (RESERVED_WORDS.includes(el.name)) {
20
- accept('error', `Reserved word: ${el.name}`, {
21
- node: el,
22
- property: 'name',
23
- })
24
- }
25
- const anotherViews = index
26
- .allElements(ast.LikeC4View)
27
- .filter(n => n.name === el.name)
28
- .limit(2)
29
- .count()
30
- if (anotherViews > 1) {
31
- accept('error', `Duplicate view '${el.name}'`, {
32
- node: el,
33
- property: 'name',
34
- })
35
- }
36
- })
37
- }
@@ -1,31 +0,0 @@
1
- import { ComputedNode, ComputedView, type Fqn, type ViewId } from '@likec4/core'
2
- import { find, isNullish } from 'remeda'
3
-
4
- export function assignNavigateTo<R extends Iterable<ComputedView>>(views: R): R {
5
- const allElementViews = new Map<Fqn, ViewId[]>()
6
-
7
- for (const v of views) {
8
- if (ComputedView.isElement(v) && v.viewOf && isNullish(v.extends)) {
9
- const viewsOf = allElementViews.get(v.viewOf) ?? []
10
- viewsOf.push(v.id)
11
- allElementViews.set(v.viewOf, viewsOf)
12
- }
13
- }
14
-
15
- // set default navigateTo
16
- for (const { id, nodes } of views) {
17
- for (const node of nodes) {
18
- const modelRef = ComputedNode.modelRef(node)
19
- if (node.navigateTo || !modelRef) {
20
- continue
21
- }
22
- // find first element view that is not the current one
23
- const navigateTo = find(allElementViews.get(modelRef) ?? [], v => v !== id)
24
- if (navigateTo) {
25
- node.navigateTo = navigateTo
26
- }
27
- }
28
- }
29
-
30
- return views
31
- }
@@ -1,2 +0,0 @@
1
- export * from './assignNavigateTo'
2
- export * from './resolve-relative-paths'
@@ -1,116 +0,0 @@
1
- import type * as c4 from '@likec4/core'
2
- import { isAutoLayoutDirection, type ViewManualLayout } from '@likec4/core'
3
- import { decode, encode } from '@msgpack/msgpack'
4
- import { fromBase64, toBase64 } from '@smithy/util-base64'
5
- import { AstUtils, CstUtils } from 'langium'
6
- import { mapValues } from 'remeda'
7
- import type { ast } from '../ast'
8
- import { logger } from '../logger'
9
-
10
- const { getDocument } = AstUtils
11
-
12
- function pack({
13
- nodes,
14
- edges,
15
- ...rest
16
- }: ViewManualLayout) {
17
- return {
18
- ...rest,
19
- nodes: mapValues(nodes, ({ x, y, width, height, isCompound, ...n }) => ({
20
- ...n,
21
- b: [x, y, width, height] as const,
22
- c: isCompound
23
- })),
24
- edges: mapValues(edges, ({ points, controlPoints, labelBBox, dotpos, ...e }) => ({
25
- ...!!controlPoints && { cp: controlPoints },
26
- ...!!labelBBox && { l: labelBBox },
27
- ...!!dotpos && { dp: dotpos },
28
- ...e,
29
- p: points
30
- }))
31
- }
32
- }
33
-
34
- function unpack({
35
- nodes,
36
- edges,
37
- autoLayout,
38
- ...rest
39
- }: ReturnType<typeof pack>): ViewManualLayout {
40
- return {
41
- ...rest,
42
- /// Try to parse the old format for backward compatibility
43
- autoLayout: isAutoLayoutDirection(autoLayout) ? { direction: autoLayout } : autoLayout,
44
- nodes: mapValues(nodes, ({ b, c, ...n }) => ({
45
- x: b[0],
46
- y: b[1],
47
- width: b[2],
48
- height: b[3],
49
- isCompound: c,
50
- ...n
51
- })),
52
- edges: mapValues(edges, ({ p, cp, l, dp, ...e }) => ({
53
- ...!!cp && { controlPoints: cp },
54
- ...!!l && { labelBBox: l },
55
- ...!!dp && { dotpos: dp },
56
- ...e,
57
- points: p
58
- }))
59
- }
60
- }
61
-
62
- const MAX_LINE_LENGTH = 500
63
- export function serializeToComment(layout: ViewManualLayout) {
64
- const bytes = encode(pack(layout))
65
- const base64 = toBase64(bytes)
66
- const lines = [] as string[]
67
- let offset = 0
68
- while (offset < base64.length) {
69
- lines.push(' * ' + base64.slice(offset, Math.min(offset + MAX_LINE_LENGTH, base64.length)))
70
- offset += MAX_LINE_LENGTH
71
- }
72
- lines.unshift(
73
- '/**',
74
- ' * @likec4-generated(v1)'
75
- )
76
- lines.push(' */')
77
-
78
- return lines.join('\n')
79
- }
80
-
81
- export function hasManualLayout(comment: string) {
82
- return comment.includes('@likec4-generated')
83
- }
84
-
85
- export function deserializeFromComment(comment: string): ViewManualLayout {
86
- if (!hasManualLayout(comment)) {
87
- throw new Error(`Not a likec4-generated comment: ${comment}`)
88
- }
89
- const b64 = comment
90
- .trim()
91
- .split('\n')
92
- .filter(l => !l.includes('**') && !l.includes('@likec4-') && !l.includes('*/'))
93
- .map(l => l.replaceAll('*', '').trim())
94
- .join('')
95
- const decodedb64 = fromBase64(b64)
96
- return unpack(decode(decodedb64) as any) as ViewManualLayout
97
- }
98
-
99
- export function parseViewManualLayout(node: ast.LikeC4View): c4.ViewManualLayout | undefined {
100
- const commentNode = CstUtils.findCommentNode(node.$cstNode, ['BLOCK_COMMENT'])
101
- if (!commentNode || !hasManualLayout(commentNode.text)) {
102
- return undefined
103
- }
104
- try {
105
- return deserializeFromComment(commentNode.text)
106
- } catch (e) {
107
- const doc = getDocument(node)
108
- logger.warn(e)
109
- logger.warn(
110
- `Ignoring manual layout of "${node.name ?? 'unnamed'}" at ${doc.uri.fsPath}:${
111
- 1 + (commentNode.range.start.line || 0)
112
- }`
113
- )
114
- return undefined
115
- }
116
- }
@@ -1,90 +0,0 @@
1
- import type { LikeC4View } from '@likec4/core'
2
- import { compareNatural, invariant } from '@likec4/core'
3
- import { filter, hasAtLeast, isTruthy, map, pipe, unique } from 'remeda'
4
- import { parsePath } from 'ufo'
5
-
6
- function commonAncestorPath(views: LikeC4View[], sep = '/') {
7
- const uniqURIs = pipe(
8
- views,
9
- map(v => v.docUri),
10
- filter(isTruthy),
11
- unique()
12
- )
13
- if (uniqURIs.length === 0) return ''
14
- if (uniqURIs.length === 1) {
15
- const parts = parsePath(uniqURIs[0]).pathname.split(sep)
16
- if (parts.length <= 1) return sep
17
- parts.pop() // remove filename
18
- return parts.join(sep) + sep
19
- }
20
- invariant(hasAtLeast(uniqURIs, 2), 'Expected at least 2 unique URIs')
21
- const [baseUri, ...tail] = uniqURIs
22
- const parts = parsePath(baseUri).pathname.split(sep)
23
- let endOfPrefix = parts.length
24
- for (const uri of tail) {
25
- if (uri === baseUri) {
26
- continue
27
- }
28
- const compare = parsePath(uri).pathname.split(sep)
29
- for (let i = 0; i < endOfPrefix; i++) {
30
- if (compare[i] !== parts[i]) {
31
- endOfPrefix = i
32
- }
33
- }
34
- if (endOfPrefix === 0) return ''
35
- }
36
- const prefix = parts.slice(0, endOfPrefix).join(sep)
37
- return prefix.endsWith(sep) ? prefix : prefix + sep
38
- }
39
-
40
- export function resolveRelativePaths(views: LikeC4View[]): LikeC4View[] {
41
- const sep = '/'
42
- const commonPrefix = commonAncestorPath(views, sep)
43
- return (
44
- views
45
- // For each view, compute the relative path to the common prefix
46
- // Store array of path segments
47
- .map(view => {
48
- if (!view.docUri) {
49
- return {
50
- view,
51
- parts: []
52
- }
53
- }
54
- let path = parsePath(view.docUri).pathname
55
- if (commonPrefix.length > 0) {
56
- invariant(
57
- path.startsWith(commonPrefix),
58
- `Expect path "${path}" to start with common prefix: "${commonPrefix}"`
59
- )
60
- path = path.slice(commonPrefix.length)
61
- } else {
62
- path = path.includes(sep) ? path.slice(path.lastIndexOf(sep) + 1) : path
63
- }
64
- return {
65
- view,
66
- parts: path.split(sep)
67
- }
68
- })
69
- // Sort views by path segments
70
- .sort((a, b) => {
71
- if (a.parts.length !== b.parts.length) {
72
- return a.parts.length - b.parts.length
73
- }
74
- for (let i = 0; i < a.parts.length; i++) {
75
- const compare = compareNatural(a.parts[i], b.parts[i])
76
- if (compare !== 0) {
77
- return compare
78
- }
79
- }
80
- return compareNatural(a.view.title ?? a.view.id, b.view.title ?? b.view.id)
81
- })
82
- // Build relativePath from path segments
83
- .map(({ parts, view }) => {
84
- return {
85
- ...view,
86
- relativePath: parts.join(sep)
87
- }
88
- })
89
- )
90
- }
@@ -1,65 +0,0 @@
1
- import { GraphvizLayouter, GraphvizWasmAdapter } from '@likec4/layouts'
2
- import { GraphvizBinaryAdapter } from '@likec4/layouts/graphviz/binary'
3
- import { isEmpty } from 'remeda'
4
- import which from 'which'
5
- import { logger } from '../logger'
6
- import type { LikeC4Services } from '../module'
7
-
8
- function graphvizBinPath() {
9
- try {
10
- return which.sync('dot')
11
- } catch (error) {
12
- logger.error('Error checking for native Graphviz:', error)
13
- return null
14
- }
15
- }
16
-
17
- export const ConfigurableLayouter = {
18
- likec4: {
19
- Layouter(services: LikeC4Services): GraphvizLayouter {
20
- logger.debug('Creating ConfigurableLayouter')
21
- const wasmAdapter = new GraphvizWasmAdapter()
22
- const layouter = new GraphvizLayouter(wasmAdapter)
23
- const langId = services.LanguageMetaData.languageId
24
- services.shared.workspace.ConfigurationProvider.onConfigurationSectionUpdate((update) => {
25
- logger.debug('Configuration update', update)
26
- if (update.section === langId) {
27
- try {
28
- const { mode, path } = update.configuration.graphviz ?? {
29
- mode: 'wasm',
30
- path: '',
31
- }
32
-
33
- if (mode === 'wasm') {
34
- layouter.changePort(wasmAdapter)
35
- logger.info('use graphviz wasm')
36
- return
37
- }
38
-
39
- let binaryPath = isEmpty(path) ? graphvizBinPath() : path
40
-
41
- if (binaryPath === null) {
42
- layouter.changePort(wasmAdapter)
43
- logger.warn(`No Graphviz binaries found on PATH, use graphviz wasm`)
44
- services.shared.lsp.Connection?.window.showWarningMessage(
45
- 'No Graphviz binaries found on PATH, set path to binaries in settings.',
46
- )
47
- return
48
- }
49
-
50
- layouter.changePort(new GraphvizBinaryAdapter(binaryPath))
51
-
52
- logger.info(`use graphviz binary: ${binaryPath}`)
53
- } catch (error) {
54
- logger.error('Failed to update configuration', error)
55
- }
56
- return
57
- }
58
-
59
- logger.warn('Unexpected configuration update', update)
60
- })
61
-
62
- return layouter
63
- },
64
- },
65
- }
@@ -1 +0,0 @@
1
- export { LikeC4Views } from './likec4-views'
@@ -1,139 +0,0 @@
1
- import type { ComputedView, DiagramView, OverviewGraph, ViewId } from '@likec4/core'
2
- import { GraphvizLayouter } from '@likec4/layouts'
3
- import { type Cancellation, type WorkspaceCache } from 'langium'
4
- import { values } from 'remeda'
5
- import { logger, logWarnError } from '../logger'
6
- import type { LikeC4Services } from '../module'
7
-
8
- export type GraphvizOut = {
9
- dot: string
10
- diagram: DiagramView
11
- }
12
-
13
- type GraphvizSvgOut = {
14
- id: ViewId
15
- dot: string
16
- svg: string
17
- }
18
-
19
- export class LikeC4Views {
20
- private cache = new WeakMap<ComputedView, GraphvizOut>()
21
-
22
- private viewsWithReportedErrors = new Set<ViewId>()
23
-
24
- constructor(private services: LikeC4Services) {
25
- }
26
-
27
- private get layouter(): GraphvizLayouter {
28
- return this.services.likec4.Layouter
29
- }
30
-
31
- async computedViews(cancelToken?: Cancellation.CancellationToken): Promise<ComputedView[]> {
32
- const model = await this.services.likec4.ModelBuilder.buildComputedModel(cancelToken)
33
- return model ? values(model.views) : []
34
- }
35
-
36
- async layoutAllViews(cancelToken?: Cancellation.CancellationToken): Promise<Array<Readonly<GraphvizOut>>> {
37
- const views = await this.computedViews(cancelToken)
38
- if (views.length === 0) {
39
- return []
40
- }
41
- const results = [] as GraphvizOut[]
42
- const tasks = [] as Promise<GraphvizOut>[]
43
- for (const view of views) {
44
- this.viewsWithReportedErrors.delete(view.id)
45
- tasks.push(
46
- this.layouter.layout(view)
47
- .then(result => {
48
- this.cache.set(view, result)
49
- return result
50
- })
51
- .catch(e => {
52
- this.cache.delete(view)
53
- logWarnError(e)
54
- return Promise.reject(e)
55
- }),
56
- )
57
- }
58
- for (const task of await Promise.allSettled(tasks)) {
59
- if (task.status === 'fulfilled') {
60
- results.push(task.value)
61
- }
62
- }
63
- return results
64
- }
65
-
66
- async layoutView(viewId: ViewId, cancelToken?: Cancellation.CancellationToken): Promise<GraphvizOut | null> {
67
- const model = await this.services.likec4.ModelBuilder.buildComputedModel(cancelToken)
68
- if (!model) {
69
- return null
70
- }
71
- const view = model.views[viewId]
72
- if (!view) {
73
- return null
74
- }
75
- let cached = this.cache.get(view)
76
- if (cached) {
77
- return cached
78
- }
79
- try {
80
- const result = await this.layouter.layout(view)
81
- this.viewsWithReportedErrors.delete(viewId)
82
- this.cache.set(view, result)
83
- return result
84
- } catch (e) {
85
- if (!this.viewsWithReportedErrors.has(viewId)) {
86
- const errMessage = e instanceof Error ? e.message : '' + e
87
- this.services.shared.lsp.Connection?.window.showErrorMessage(`LikeC4: ${errMessage}`)
88
- this.viewsWithReportedErrors.add(viewId)
89
- }
90
- logger.error(e)
91
- return Promise.reject(e)
92
- }
93
- }
94
-
95
- async diagrams(): Promise<Array<DiagramView>> {
96
- const layouted = await this.layoutAllViews()
97
- return layouted.map(l => l.diagram)
98
- }
99
-
100
- async viewsAsGraphvizOut(): Promise<Array<GraphvizSvgOut>> {
101
- const KEY = 'All-LayoutedViews-DotWithSvg'
102
- const cache = this.services.WorkspaceCache as WorkspaceCache<string, GraphvizSvgOut[]>
103
- if (cache.has(KEY)) {
104
- return await Promise.resolve(cache.get(KEY)!)
105
- }
106
- const views = await this.computedViews()
107
- const tasks = views.map(async view => {
108
- const { dot, svg } = await this.layouter.svg(view)
109
- return {
110
- id: view.id,
111
- dot,
112
- svg,
113
- }
114
- })
115
- const succeed = [] as GraphvizSvgOut[]
116
- const settledResult = await Promise.allSettled(tasks)
117
- for (const result of settledResult) {
118
- if (result.status === 'fulfilled') {
119
- succeed.push(result.value)
120
- } else {
121
- logWarnError(result.reason)
122
- }
123
- }
124
- cache.set(KEY, succeed)
125
- return succeed
126
- }
127
-
128
- async overviewGraph(): Promise<OverviewGraph> {
129
- const KEY = 'OverviewGraph'
130
- const cache = this.services.WorkspaceCache as WorkspaceCache<string, OverviewGraph>
131
- if (cache.has(KEY)) {
132
- return await Promise.resolve(cache.get(KEY)!)
133
- }
134
- const views = await this.computedViews()
135
- const overviewGraph = await this.layouter.layoutOverviewGraph(views)
136
- cache.set(KEY, overviewGraph)
137
- return overviewGraph
138
- }
139
- }