@likec4/language-server 1.19.0 → 1.19.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 (59) hide show
  1. package/dist/Rpc.js +6 -0
  2. package/dist/browser.d.ts +1 -0
  3. package/dist/documentation/documentation-provider.d.ts +8 -0
  4. package/dist/documentation/documentation-provider.js +46 -0
  5. package/dist/documentation/index.d.ts +1 -0
  6. package/dist/documentation/index.js +1 -0
  7. package/dist/index.d.ts +1 -0
  8. package/dist/index.js +3 -2
  9. package/dist/lsp/DocumentSymbolProvider.d.ts +11 -2
  10. package/dist/lsp/DocumentSymbolProvider.js +78 -6
  11. package/dist/model/fqn-computation.js +2 -2
  12. package/dist/model/model-builder.js +3 -3
  13. package/dist/module.d.ts +9 -1
  14. package/dist/module.js +47 -8
  15. package/dist/protocol.d.ts +19 -1
  16. package/dist/protocol.js +1 -0
  17. package/dist/references/scope-computation.d.ts +2 -2
  18. package/dist/references/scope-computation.js +9 -9
  19. package/dist/validation/dynamic-view-rule.js +3 -2
  20. package/dist/validation/dynamic-view-step.js +23 -27
  21. package/dist/validation/property-checks.js +3 -2
  22. package/dist/validation/specification.js +14 -14
  23. package/dist/validation/view-predicates/element-with.js +3 -2
  24. package/dist/validation/view-predicates/expanded-element.js +3 -2
  25. package/dist/validation/view-predicates/incoming.js +3 -2
  26. package/dist/validation/view-predicates/outgoing.js +3 -2
  27. package/dist/validation/view-predicates/relation-with.js +3 -2
  28. package/dist/validation/view.js +3 -3
  29. package/dist/views/configurable-layouter.d.ts +7 -0
  30. package/dist/views/configurable-layouter.js +55 -0
  31. package/dist/views/index.d.ts +1 -0
  32. package/dist/views/index.js +1 -0
  33. package/dist/views/likec4-views.d.ts +26 -0
  34. package/dist/views/likec4-views.js +113 -0
  35. package/package.json +13 -10
  36. package/src/Rpc.ts +13 -7
  37. package/src/browser.ts +1 -0
  38. package/src/documentation/documentation-provider.ts +52 -0
  39. package/src/documentation/index.ts +1 -0
  40. package/src/index.ts +4 -2
  41. package/src/lsp/DocumentSymbolProvider.ts +110 -28
  42. package/src/model/fqn-computation.ts +8 -8
  43. package/src/model/model-builder.ts +52 -52
  44. package/src/module.ts +56 -9
  45. package/src/protocol.ts +29 -4
  46. package/src/references/scope-computation.ts +35 -35
  47. package/src/validation/dynamic-view-rule.ts +5 -4
  48. package/src/validation/dynamic-view-step.ts +23 -26
  49. package/src/validation/property-checks.ts +11 -10
  50. package/src/validation/specification.ts +38 -38
  51. package/src/validation/view-predicates/element-with.ts +6 -5
  52. package/src/validation/view-predicates/expanded-element.ts +6 -5
  53. package/src/validation/view-predicates/incoming.ts +6 -5
  54. package/src/validation/view-predicates/outgoing.ts +6 -5
  55. package/src/validation/view-predicates/relation-with.ts +6 -5
  56. package/src/validation/view.ts +5 -5
  57. package/src/views/configurable-layouter.ts +65 -0
  58. package/src/views/index.ts +1 -0
  59. package/src/views/likec4-views.ts +139 -0
package/dist/Rpc.js CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  computeView,
11
11
  fetchComputedModel,
12
12
  fetchModel,
13
+ layoutView,
13
14
  locate,
14
15
  onDidChangeModel
15
16
  } from "./protocol.js";
@@ -22,6 +23,7 @@ export class Rpc {
22
23
  const modelBuilder = this.services.likec4.ModelBuilder;
23
24
  const modelLocator = this.services.likec4.ModelLocator;
24
25
  const modelEditor = this.services.likec4.ModelChanges;
26
+ const views = this.services.likec4.Views;
25
27
  const connection = this.services.shared.lsp.Connection;
26
28
  if (!connection) {
27
29
  logger.info(`[ServerRpc] no connection, not initializing`);
@@ -64,6 +66,10 @@ export class Rpc {
64
66
  const view = await modelBuilder.computeView(viewId, cancelToken);
65
67
  return { view };
66
68
  }),
69
+ connection.onRequest(layoutView, async ({ viewId }, cancelToken) => {
70
+ const result = await views.layoutView(viewId, cancelToken);
71
+ return { result };
72
+ }),
67
73
  connection.onRequest(buildDocuments, async ({ docs }, cancelToken) => {
68
74
  const changed = docs.map((d) => URI.parse(d));
69
75
  const notChanged = (uri) => changed.every((c) => !UriUtils.equals(c, uri));
package/dist/browser.d.ts CHANGED
@@ -3,6 +3,7 @@ export { logger as lspLogger, setLogLevel } from './logger';
3
3
  export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
4
4
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module';
5
5
  export type { LikeC4Services, LikeC4SharedServices } from './module';
6
+ export type { LikeC4Views } from './views';
6
7
  export declare function startLanguageServer(): {
7
8
  shared: LikeC4SharedServices;
8
9
  likec4: LikeC4Services;
@@ -0,0 +1,8 @@
1
+ import { type AstNode, type DocumentationProvider } from 'langium';
2
+ import type { LikeC4Services } from '../module';
3
+ export declare class LikeC4DocumentationProvider implements DocumentationProvider {
4
+ private parser;
5
+ private locator;
6
+ constructor(services: LikeC4Services);
7
+ getDocumentation(node: AstNode): string | undefined;
8
+ }
@@ -0,0 +1,46 @@
1
+ import { AstUtils } from "langium";
2
+ import { ast } from "../ast.js";
3
+ import { logWarnError } from "../logger.js";
4
+ export class LikeC4DocumentationProvider {
5
+ parser;
6
+ locator;
7
+ constructor(services) {
8
+ this.parser = services.likec4.ModelParser;
9
+ this.locator = services.likec4.ModelLocator;
10
+ }
11
+ getDocumentation(node) {
12
+ try {
13
+ if (ast.isDeploymentNode(node)) {
14
+ const doc = AstUtils.getDocument(node);
15
+ const el = this.parser.forDocument(doc).parseDeploymentNode(node);
16
+ const lines = [el.id];
17
+ if (el.title !== node.name) {
18
+ lines.push(" ", `**${el.title}**`);
19
+ }
20
+ return lines.join(" \n");
21
+ }
22
+ if (ast.isDeployedInstance(node)) {
23
+ const doc = AstUtils.getDocument(node);
24
+ const instance = this.parser.forDocument(doc).parseDeployedInstance(node);
25
+ const el = this.locator.getParsedElement(instance.element);
26
+ const lines = [instance.id, `_instance of_ ${instance.element}`];
27
+ if (el) {
28
+ lines.push(" ", `**${el.title}**`);
29
+ }
30
+ return lines.join(" \n");
31
+ }
32
+ if (ast.isElement(node)) {
33
+ const doc = AstUtils.getDocument(node);
34
+ const el = this.parser.forDocument(doc).parseElement(node);
35
+ if (!el) {
36
+ return;
37
+ }
38
+ const lines = [el.id, " ", `**${el.title}**`];
39
+ return lines.join(" \n");
40
+ }
41
+ } catch (e) {
42
+ logWarnError(e);
43
+ }
44
+ return;
45
+ }
46
+ }
@@ -0,0 +1 @@
1
+ export { LikeC4DocumentationProvider } from './documentation-provider';
@@ -0,0 +1 @@
1
+ export { LikeC4DocumentationProvider } from "./documentation-provider.js";
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { logger as lspLogger, setLogLevel } from './logger';
4
4
  export type { DocumentParser, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
5
5
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from './module';
6
6
  export type { LikeC4Services, LikeC4SharedServices } from './module';
7
+ export type { LikeC4Views } from './views';
7
8
  export { LikeC4FileSystem };
8
9
  export declare function startLanguageServer(): {
9
10
  shared: LikeC4SharedServices;
package/dist/index.js CHANGED
@@ -1,13 +1,14 @@
1
1
  import { startLanguageServer as startLanguim } from "langium/lsp";
2
2
  import { createConnection, ProposedFeatures } from "vscode-languageserver/node";
3
3
  import { LikeC4FileSystem } from "./LikeC4FileSystem.js";
4
- import { createLanguageServices } from "./module.js";
4
+ import { createCustomLanguageServices } from "./module.js";
5
+ import { ConfigurableLayouter } from "./views/configurable-layouter.js";
5
6
  export { logger as lspLogger, setLogLevel } from "./logger.js";
6
7
  export { createCustomLanguageServices, createLanguageServices, LikeC4Module } from "./module.js";
7
8
  export { LikeC4FileSystem };
8
9
  export function startLanguageServer() {
9
10
  const connection = createConnection(ProposedFeatures.all);
10
- const services = createLanguageServices({ connection, ...LikeC4FileSystem });
11
+ const services = createCustomLanguageServices({ connection, ...LikeC4FileSystem }, ConfigurableLayouter);
11
12
  startLanguim(services.shared);
12
13
  return services;
13
14
  }
@@ -1,16 +1,22 @@
1
1
  import { type AstNode, type MaybePromise } from 'langium';
2
2
  import type { DocumentSymbolProvider, NodeKindProvider } from 'langium/lsp';
3
3
  import { type DocumentSymbol, SymbolKind } from 'vscode-languageserver-types';
4
- import { ast, type LikeC4LangiumDocument } from '../ast';
4
+ import { type LikeC4LangiumDocument, ast } from '../ast';
5
+ import type { LikeC4ModelLocator, LikeC4ModelParser } from '../model';
5
6
  import type { LikeC4Services } from '../module';
7
+ import type { LikeC4NameProvider } from '../references';
6
8
  export declare class LikeC4DocumentSymbolProvider implements DocumentSymbolProvider {
7
9
  private services;
8
10
  protected readonly nodeKindProvider: NodeKindProvider;
11
+ protected readonly nameProvider: LikeC4NameProvider;
12
+ protected readonly parser: LikeC4ModelParser;
13
+ protected readonly locator: LikeC4ModelLocator;
9
14
  constructor(services: LikeC4Services);
10
- getSymbols({ parseResult: { value: { specifications, models, views, likec4lib } } }: LikeC4LangiumDocument): MaybePromise<DocumentSymbol[]>;
15
+ getSymbols({ parseResult: { value: { specifications, models, deployments, views, likec4lib }, }, }: LikeC4LangiumDocument): MaybePromise<DocumentSymbol[]>;
11
16
  protected getLikec4LibSymbol(astLib: ast.LikeC4Lib): DocumentSymbol[];
12
17
  protected getSpecSymbol(astSpec: ast.SpecificationRule): DocumentSymbol[];
13
18
  protected getModelSymbol(astModel: ast.Model): DocumentSymbol[];
19
+ protected getDeploymentModelSymbol(astModel: ast.ModelDeployments): DocumentSymbol[];
14
20
  protected getElementsSymbol(el: ast.Element | ast.Relation | ast.ExtendElement): DocumentSymbol[];
15
21
  protected getExtendElementSymbol(astElement: ast.ExtendElement): DocumentSymbol[];
16
22
  protected getElementSymbol(astElement: ast.Element): DocumentSymbol[];
@@ -19,5 +25,8 @@ export declare class LikeC4DocumentSymbolProvider implements DocumentSymbolProvi
19
25
  protected getTagSymbol(astTag: ast.SpecificationTag): DocumentSymbol | null;
20
26
  protected getLibIconSymbol(astTag: ast.LibIcon): DocumentSymbol | null;
21
27
  protected getViewSymbol(astView: ast.LikeC4View): DocumentSymbol[];
28
+ protected getDeploymentElementSymbol(el: ast.DeploymentElement | ast.DeploymentRelation): DocumentSymbol[];
29
+ protected getDeploymentNodeSymbol(astElement: ast.DeploymentNode): DocumentSymbol[];
30
+ protected getDeployedInstanceSymbol(astElement: ast.DeployedInstance): DocumentSymbol[];
22
31
  protected symbolKind(node: AstNode): SymbolKind;
23
32
  }
@@ -1,31 +1,38 @@
1
1
  import { nonexhaustive } from "@likec4/core";
2
- import { GrammarUtils } from "langium";
2
+ import { AstUtils, GrammarUtils } from "langium";
3
3
  import { filter, isEmpty, isTruthy, map, pipe } from "remeda";
4
4
  import { SymbolKind } from "vscode-languageserver-types";
5
5
  import { ast } from "../ast.js";
6
- import { logError } from "../logger.js";
6
+ import { logWarnError } from "../logger.js";
7
7
  import { getFqnElementRef } from "../utils/elementRef.js";
8
8
  export class LikeC4DocumentSymbolProvider {
9
9
  constructor(services) {
10
10
  this.services = services;
11
11
  this.nodeKindProvider = services.shared.lsp.NodeKindProvider;
12
+ this.parser = services.likec4.ModelParser;
13
+ this.locator = services.likec4.ModelLocator;
14
+ this.nameProvider = services.references.NameProvider;
12
15
  }
13
16
  nodeKindProvider;
17
+ nameProvider;
18
+ parser;
19
+ locator;
14
20
  getSymbols({
15
21
  parseResult: {
16
- value: { specifications, models, views, likec4lib }
22
+ value: { specifications, models, deployments, views, likec4lib }
17
23
  }
18
24
  }) {
19
25
  return [
20
26
  ...likec4lib.map((l) => () => this.getLikec4LibSymbol(l)),
21
27
  ...specifications.map((s) => () => this.getSpecSymbol(s)),
22
28
  ...models.map((s) => () => this.getModelSymbol(s)),
29
+ ...deployments.map((s) => () => this.getDeploymentModelSymbol(s)),
23
30
  ...views.map((s) => () => this.getModelViewsSymbol(s))
24
31
  ].flatMap((fn) => {
25
32
  try {
26
33
  return fn() ?? [];
27
34
  } catch (e) {
28
- logError(e);
35
+ logWarnError(e);
29
36
  return [];
30
37
  }
31
38
  });
@@ -61,7 +68,7 @@ export class LikeC4DocumentSymbolProvider {
61
68
  return this.getTagSymbol(nd);
62
69
  }
63
70
  } catch (e) {
64
- logError(e);
71
+ logWarnError(e);
65
72
  return null;
66
73
  }
67
74
  nonexhaustive(nd);
@@ -94,6 +101,21 @@ export class LikeC4DocumentSymbolProvider {
94
101
  }
95
102
  ];
96
103
  }
104
+ getDeploymentModelSymbol(astModel) {
105
+ const cstModel = astModel.$cstNode;
106
+ if (!cstModel) return [];
107
+ const nameNode = GrammarUtils.findNodeForProperty(cstModel, "name");
108
+ if (!nameNode) return [];
109
+ return [
110
+ {
111
+ kind: this.symbolKind(astModel),
112
+ name: astModel.name,
113
+ range: cstModel.range,
114
+ selectionRange: nameNode.range,
115
+ children: astModel.elements.flatMap((e) => this.getDeploymentElementSymbol(e))
116
+ }
117
+ ];
118
+ }
97
119
  getElementsSymbol(el) {
98
120
  try {
99
121
  if (ast.isExtendElement(el)) {
@@ -103,7 +125,7 @@ export class LikeC4DocumentSymbolProvider {
103
125
  return this.getElementSymbol(el);
104
126
  }
105
127
  } catch (e) {
106
- logError(e);
128
+ logWarnError(e);
107
129
  }
108
130
  return [];
109
131
  }
@@ -196,6 +218,56 @@ export class LikeC4DocumentSymbolProvider {
196
218
  }
197
219
  ];
198
220
  }
221
+ getDeploymentElementSymbol(el) {
222
+ try {
223
+ if (ast.isDeploymentNode(el)) {
224
+ return this.getDeploymentNodeSymbol(el);
225
+ }
226
+ if (ast.isDeployedInstance(el)) {
227
+ return this.getDeployedInstanceSymbol(el);
228
+ }
229
+ } catch (e) {
230
+ logWarnError(e);
231
+ }
232
+ return [];
233
+ }
234
+ getDeploymentNodeSymbol(astElement) {
235
+ const cst = astElement.$cstNode;
236
+ const nameNode = this.nameProvider.getNameNode(astElement);
237
+ if (!nameNode || !cst) return [];
238
+ const name = this.nameProvider.getNameStrict(astElement);
239
+ const kind = astElement.kind.$refText;
240
+ const detail = kind;
241
+ return [
242
+ {
243
+ kind: this.symbolKind(astElement),
244
+ name,
245
+ range: cst.range,
246
+ selectionRange: nameNode.range,
247
+ detail,
248
+ children: astElement.body?.elements.flatMap((e) => this.getDeploymentElementSymbol(e)) ?? []
249
+ }
250
+ ];
251
+ }
252
+ getDeployedInstanceSymbol(astElement) {
253
+ const cst = astElement.$cstNode;
254
+ const nameNode = this.nameProvider.getNameNode(astElement);
255
+ if (!nameNode || !cst) return [];
256
+ const doc = AstUtils.getDocument(astElement);
257
+ const instance = this.parser.forDocument(doc).parseDeployedInstance(astElement);
258
+ const name = this.nameProvider.getNameStrict(astElement);
259
+ const detail = "instance of " + instance.element;
260
+ return [
261
+ {
262
+ kind: this.symbolKind(astElement),
263
+ name,
264
+ range: cst.range,
265
+ selectionRange: nameNode.range,
266
+ detail,
267
+ children: []
268
+ }
269
+ ];
270
+ }
199
271
  symbolKind(node) {
200
272
  return this.nodeKindProvider.getSymbolKind(node);
201
273
  }
@@ -1,4 +1,4 @@
1
- import { AsFqn, nonexhaustive } from "@likec4/core";
1
+ import { AsFqn, LinkedList, nonexhaustive } from "@likec4/core";
2
2
  import { AstUtils, CstUtils, GrammarUtils, MultiMap } from "langium";
3
3
  import { isDefined, isEmpty } from "remeda";
4
4
  import { ast, ElementOps } from "../ast.js";
@@ -29,7 +29,7 @@ export function computeDocumentFqn(document, services) {
29
29
  return;
30
30
  }
31
31
  const locator = services.workspace.AstNodeLocator;
32
- const traverseStack = elements.map((el) => [el, null]);
32
+ const traverseStack = LinkedList.from(elements.map((el) => [el, null]));
33
33
  let pair;
34
34
  while (pair = traverseStack.shift()) {
35
35
  try {
@@ -33,7 +33,7 @@ import {
33
33
  values
34
34
  } from "remeda";
35
35
  import { isParsedLikeC4LangiumDocument } from "../ast.js";
36
- import { logError, logger, logWarnError } from "../logger.js";
36
+ import { logger, logWarnError } from "../logger.js";
37
37
  import { assignNavigateTo, resolveRelativePaths } from "../view-utils/index.js";
38
38
  function buildModel(services, docs) {
39
39
  const c4Specification = {
@@ -542,7 +542,7 @@ export class LikeC4ModelBuilder {
542
542
  }
543
543
  const result = LikeC4Model.makeCompute(model)(view);
544
544
  if (!result.isSuccess) {
545
- logError(result.error);
545
+ logWarnError(result.error);
546
546
  return null;
547
547
  }
548
548
  let computedView = result.view;
@@ -588,7 +588,7 @@ export class LikeC4ModelBuilder {
588
588
  try {
589
589
  listener(docs);
590
590
  } catch (e) {
591
- logError(e);
591
+ logWarnError(e);
592
592
  }
593
593
  }
594
594
  }
package/dist/module.d.ts CHANGED
@@ -1,11 +1,14 @@
1
+ import { GraphvizLayouter } from '@likec4/layouts';
1
2
  import { type Module, DocumentCache, WorkspaceCache } from 'langium';
2
3
  import { type DefaultSharedModuleContext, type LangiumServices, type LangiumSharedServices, type PartialLangiumServices } from 'langium/lsp';
4
+ import { LikeC4DocumentationProvider } from './documentation';
3
5
  import { LikeC4CodeLensProvider, LikeC4CompletionProvider, LikeC4DocumentHighlightProvider, LikeC4DocumentLinkProvider, LikeC4DocumentSymbolProvider, LikeC4HoverProvider, LikeC4SemanticTokenProvider } from './lsp';
4
6
  import { DeploymentsIndex, FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from './model';
5
7
  import { LikeC4ModelChanges } from './model-change/ModelChanges';
6
8
  import { LikeC4NameProvider, LikeC4ScopeComputation, LikeC4ScopeProvider } from './references';
7
9
  import { Rpc } from './Rpc';
8
10
  import { LikeC4WorkspaceManager, NodeKindProvider, WorkspaceSymbolProvider } from './shared';
11
+ import { LikeC4Views } from './views';
9
12
  interface LikeC4AddedSharedServices {
10
13
  lsp: {
11
14
  NodeKindProvider: NodeKindProvider;
@@ -20,10 +23,15 @@ export type LikeC4SharedServices = LangiumSharedServices & LikeC4AddedSharedServ
20
23
  * Declaration of custom services - add your own service classes here.
21
24
  */
22
25
  export interface LikeC4AddedServices {
26
+ documentation: {
27
+ DocumentationProvider: LikeC4DocumentationProvider;
28
+ };
23
29
  WorkspaceCache: WorkspaceCache<string, any>;
24
30
  DocumentCache: DocumentCache<string, any>;
25
31
  Rpc: Rpc;
26
32
  likec4: {
33
+ Views: LikeC4Views;
34
+ Layouter: GraphvizLayouter;
27
35
  DeploymentsIndex: DeploymentsIndex;
28
36
  FqnIndex: FqnIndex;
29
37
  ModelParser: LikeC4ModelParser;
@@ -50,7 +58,7 @@ export interface LikeC4AddedServices {
50
58
  export type LikeC4Services = LangiumServices & LikeC4AddedServices;
51
59
  export declare const LikeC4Module: Module<LikeC4Services, PartialLangiumServices & LikeC4AddedServices>;
52
60
  export type LanguageServicesContext = Partial<DefaultSharedModuleContext>;
53
- export declare function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & LikeC4Services>(context: LanguageServicesContext, module: Module<I, I1>, module2?: Module<I, I2>, module3?: Module<I, I3>): {
61
+ export declare function createCustomLanguageServices<I1, I2, I3, I extends I1 & I2 & I3 & LikeC4Services>(context: LanguageServicesContext, module?: Module<I, I1>, module2?: Module<I, I2>, module3?: Module<I, I3>): {
54
62
  shared: LikeC4SharedServices;
55
63
  likec4: I;
56
64
  };
package/dist/module.js CHANGED
@@ -1,11 +1,21 @@
1
- import { DocumentCache, EmptyFileSystem, inject, WorkspaceCache } from "langium";
1
+ import { GraphvizLayouter, GraphvizWasmAdapter } from "@likec4/layouts";
2
+ import {
3
+ DocumentCache,
4
+ EmptyFileSystem,
5
+ inject,
6
+ WorkspaceCache
7
+ } from "langium";
2
8
  import {
3
9
  createDefaultModule,
4
10
  createDefaultSharedModule
5
11
  } from "langium/lsp";
12
+ import { LikeC4DocumentationProvider } from "./documentation/index.js";
6
13
  import { LikeC4Formatter } from "./formatting/LikeC4Formatter.js";
7
- import { LikeC4GeneratedModule, LikeC4GeneratedSharedModule } from "./generated/module.js";
8
- import { logToLspConnection } from "./logger.js";
14
+ import {
15
+ LikeC4GeneratedModule,
16
+ LikeC4GeneratedSharedModule
17
+ } from "./generated/module.js";
18
+ import { logger, logToLspConnection } from "./logger.js";
9
19
  import {
10
20
  LikeC4CodeLensProvider,
11
21
  LikeC4CompletionProvider,
@@ -15,12 +25,27 @@ import {
15
25
  LikeC4HoverProvider,
16
26
  LikeC4SemanticTokenProvider
17
27
  } from "./lsp/index.js";
18
- import { DeploymentsIndex, FqnIndex, LikeC4ModelBuilder, LikeC4ModelLocator, LikeC4ModelParser } from "./model/index.js";
28
+ import {
29
+ DeploymentsIndex,
30
+ FqnIndex,
31
+ LikeC4ModelBuilder,
32
+ LikeC4ModelLocator,
33
+ LikeC4ModelParser
34
+ } from "./model/index.js";
19
35
  import { LikeC4ModelChanges } from "./model-change/ModelChanges.js";
20
- import { LikeC4NameProvider, LikeC4ScopeComputation, LikeC4ScopeProvider } from "./references/index.js";
36
+ import {
37
+ LikeC4NameProvider,
38
+ LikeC4ScopeComputation,
39
+ LikeC4ScopeProvider
40
+ } from "./references/index.js";
21
41
  import { Rpc } from "./Rpc.js";
22
- import { LikeC4WorkspaceManager, NodeKindProvider, WorkspaceSymbolProvider } from "./shared/index.js";
42
+ import {
43
+ LikeC4WorkspaceManager,
44
+ NodeKindProvider,
45
+ WorkspaceSymbolProvider
46
+ } from "./shared/index.js";
23
47
  import { registerValidationChecks } from "./validation/index.js";
48
+ import { LikeC4Views } from "./views/index.js";
24
49
  const LikeC4SharedModule = {
25
50
  lsp: {
26
51
  NodeKindProvider: (services) => new NodeKindProvider(services),
@@ -34,10 +59,18 @@ function bind(Type) {
34
59
  return (services) => new Type(services);
35
60
  }
36
61
  export const LikeC4Module = {
62
+ documentation: {
63
+ DocumentationProvider: bind(LikeC4DocumentationProvider)
64
+ },
37
65
  WorkspaceCache: (services) => new WorkspaceCache(services.shared),
38
66
  DocumentCache: (services) => new DocumentCache(services.shared),
39
67
  Rpc: bind(Rpc),
40
68
  likec4: {
69
+ Layouter: (_services) => {
70
+ logger.debug("Creating GraphvizLayouter with GraphvizWasmAdapter");
71
+ return new GraphvizLayouter(new GraphvizWasmAdapter());
72
+ },
73
+ Views: bind(LikeC4Views),
41
74
  DeploymentsIndex: bind(DeploymentsIndex),
42
75
  ModelChanges: bind(LikeC4ModelChanges),
43
76
  FqnIndex: bind(FqnIndex),
@@ -98,10 +131,16 @@ export function createSharedServices(context = {}) {
98
131
  }
99
132
  export function createLanguageServices(context = {}) {
100
133
  const shared = createSharedServices(context);
101
- const likec4 = inject(createDefaultModule({ shared }), LikeC4GeneratedModule, LikeC4Module);
134
+ const likec4 = inject(
135
+ createDefaultModule({ shared }),
136
+ LikeC4GeneratedModule,
137
+ LikeC4Module
138
+ );
102
139
  shared.ServiceRegistry.register(likec4);
103
140
  registerValidationChecks(likec4);
104
- if (context.connection) {
141
+ if (!context.connection) {
142
+ shared.workspace.ConfigurationProvider.initialized({});
143
+ } else {
105
144
  likec4.Rpc.init();
106
145
  }
107
146
  return { shared, likec4 };
@@ -1,4 +1,4 @@
1
- import type { ComputedLikeC4Model, ComputedView, Fqn, ParsedLikeC4Model, RelationId, ViewChange, ViewId } from '@likec4/core';
1
+ import type { ComputedLikeC4Model, ComputedView, DiagramView, Fqn, ParsedLikeC4Model, RelationId, ViewChange, ViewId } from '@likec4/core';
2
2
  import { NotificationType, RequestType, RequestType0 } from 'vscode-jsonrpc';
3
3
  import type { DocumentUri, Location } from 'vscode-languageserver-types';
4
4
  export declare const onDidChangeModel: NotificationType<string>;
@@ -19,11 +19,29 @@ export declare const computeView: RequestType<{
19
19
  view: ComputedView | null;
20
20
  }, void>;
21
21
  export type ComputeViewRequest = typeof computeView;
22
+ /**
23
+ * Request to layout a view.
24
+ */
25
+ export declare const layoutView: RequestType<{
26
+ viewId: ViewId;
27
+ }, {
28
+ result: {
29
+ dot: string;
30
+ diagram: DiagramView;
31
+ } | null;
32
+ }, void>;
33
+ export type LayoutViewRequest = typeof layoutView;
34
+ /**
35
+ * Request to build documents.
36
+ */
22
37
  export interface BuildDocumentsParams {
23
38
  docs: DocumentUri[];
24
39
  }
25
40
  export declare const buildDocuments: RequestType<BuildDocumentsParams, void, void>;
26
41
  export type BuildDocumentsRequest = typeof buildDocuments;
42
+ /**
43
+ * Request to locate an element, relation, deployment or view.
44
+ */
27
45
  export type LocateParams = {
28
46
  element: Fqn;
29
47
  property?: string;
package/dist/protocol.js CHANGED
@@ -9,6 +9,7 @@ export const fetchComputedModel = new RequestType(
9
9
  export const computeView = new RequestType(
10
10
  "likec4/computeView"
11
11
  );
12
+ export const layoutView = new RequestType("likec4/layout-view");
12
13
  export const buildDocuments = new RequestType("likec4/build");
13
14
  export const locate = new RequestType("likec4/locate");
14
15
  export const changeView = new RequestType("likec4/change-view");
@@ -1,6 +1,6 @@
1
- import { type AstNodeDescription, DefaultScopeComputation, type PrecomputedScopes } from 'langium';
1
+ import { type AstNodeDescription, type PrecomputedScopes, DefaultScopeComputation } from 'langium';
2
2
  import type { CancellationToken } from 'vscode-languageserver';
3
- import { ast, type LikeC4LangiumDocument } from '../ast';
3
+ import { type LikeC4LangiumDocument, ast } from '../ast';
4
4
  import type { LikeC4Services } from '../module';
5
5
  type ElementsContainer = ast.Model | ast.ElementBody | ast.ExtendElementBody;
6
6
  type DeploymentsContainer = ast.ModelDeployments | ast.DeploymentNodeBody;
@@ -5,7 +5,7 @@ import {
5
5
  } from "langium";
6
6
  import { entries, filter, flatMap, forEachObj, groupBy, isNullish, isTruthy, pipe } from "remeda";
7
7
  import { ast } from "../ast.js";
8
- import { logError, logWarnError } from "../logger.js";
8
+ import { logWarnError } from "../logger.js";
9
9
  function uniqueDescriptions(descs) {
10
10
  return pipe(
11
11
  descs,
@@ -29,7 +29,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
29
29
  this.exportGlobals(globals, docExports, document);
30
30
  this.exportDeployments(deployments, docExports, document);
31
31
  } catch (e) {
32
- logError(e);
32
+ logWarnError(e);
33
33
  }
34
34
  return docExports;
35
35
  }
@@ -44,7 +44,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
44
44
  docExports.push(this.descriptions.createDescription(viewAst, viewAst.name, document));
45
45
  }
46
46
  } catch (e) {
47
- logError(e);
47
+ logWarnError(e);
48
48
  }
49
49
  }
50
50
  }
@@ -59,7 +59,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
59
59
  docExports.push(this.descriptions.createDescription(id, id.name, document));
60
60
  }
61
61
  } catch (e) {
62
- logError(e);
62
+ logWarnError(e);
63
63
  }
64
64
  }
65
65
  for (const globalStyleAst of globals.flatMap((g) => g.styles)) {
@@ -69,7 +69,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
69
69
  docExports.push(this.descriptions.createDescription(id, id.name, document));
70
70
  }
71
71
  } catch (e) {
72
- logError(e);
72
+ logWarnError(e);
73
73
  }
74
74
  }
75
75
  }
@@ -83,7 +83,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
83
83
  docExports.push(this.descriptions.createDescription(elAst, elAst.name, document));
84
84
  }
85
85
  } catch (e) {
86
- logError(e);
86
+ logWarnError(e);
87
87
  }
88
88
  }
89
89
  }
@@ -96,7 +96,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
96
96
  docExports.push(this.descriptions.createDescription(iconAst, iconAst.name, document));
97
97
  }
98
98
  } catch (e) {
99
- logError(e);
99
+ logWarnError(e);
100
100
  }
101
101
  }
102
102
  exportSpecification(specifications, docExports, document) {
@@ -151,7 +151,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
151
151
  nonexhaustive(spec);
152
152
  }
153
153
  } catch (e) {
154
- logError(e);
154
+ logWarnError(e);
155
155
  }
156
156
  }
157
157
  }
@@ -181,7 +181,7 @@ export class LikeC4ScopeComputation extends DefaultScopeComputation {
181
181
  ...this.processContainer(model, scopes, document)
182
182
  );
183
183
  } catch (e) {
184
- logError(e);
184
+ logWarnError(e);
185
185
  }
186
186
  }
187
187
  for (const deployment of root.deployments) {
@@ -1,6 +1,7 @@
1
1
  import { ast, elementExpressionFromPredicate } from "../ast.js";
2
+ import { tryOrLog } from "./_shared.js";
2
3
  export const dynamicViewRulePredicate = (_services) => {
3
- return (predicate, accept) => {
4
+ return tryOrLog((predicate, accept) => {
4
5
  const expr = elementExpressionFromPredicate(predicate.value);
5
6
  switch (true) {
6
7
  case ast.isElementKindExpression(expr):
@@ -12,5 +13,5 @@ export const dynamicViewRulePredicate = (_services) => {
12
13
  return;
13
14
  }
14
15
  }
15
- };
16
+ });
16
17
  };