@likec4/language-server 0.19.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ast.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
- import * as ast from './generated/ast';
2
+ import type * as c4 from '@likec4/core/types';
3
3
  import type { LangiumDocument, MultiMap } from 'langium';
4
4
  import type { LikeC4Document } from './generated/ast';
5
- import type * as c4 from '@likec4/core/types';
5
+ import * as ast from './generated/ast';
6
6
  export { ast };
7
7
  export declare function c4hash({ c4Specification, c4Elements, c4Relations, c4Views }: LikeC4LangiumDocument): string;
8
8
  export interface ParsedAstSpecification {
@@ -62,7 +62,7 @@ export declare function cleanParsedModel(doc: LikeC4LangiumDocument): {
62
62
  export declare function isLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument;
63
63
  export declare function isParsedLikeC4LangiumDocument(doc: LangiumDocument): doc is LikeC4LangiumDocument;
64
64
  export declare const isValidDocument: (doc: LangiumDocument) => doc is LikeC4LangiumDocument;
65
- export declare function streamModel(doc: LikeC4LangiumDocument): Generator<ast.Element | ast.Relation, void, unknown>;
65
+ export declare function streamModel(doc: LikeC4LangiumDocument): Generator<ast.Relation | ast.Element, void, unknown>;
66
66
  export declare function resolveRelationPoints(node: ast.Relation): {
67
67
  source: ast.Element;
68
68
  target: ast.Element;
package/dist/ast.js CHANGED
@@ -1,7 +1,7 @@
1
- import * as ast from './generated/ast';
2
- import { DocumentState } from 'langium';
1
+ import { DocumentState } from 'langium/lib/workspace';
3
2
  import objectHash from 'object-hash';
4
3
  import { elementRef } from './elementRef';
4
+ import * as ast from './generated/ast';
5
5
  import { LikeC4LanguageMetaData } from './generated/module';
6
6
  export { ast };
7
7
  export function c4hash({ c4Specification, c4Elements, c4Relations, c4Views }) {
@@ -74,19 +74,34 @@ export const isValidDocument = (doc) => {
74
74
  export function* streamModel(doc) {
75
75
  const elements = doc.parseResult.value.model?.elements ?? [];
76
76
  const traverseStack = [...elements];
77
+ const relations = [];
77
78
  let el;
78
79
  while ((el = traverseStack.shift())) {
80
+ if (ast.isRelationWithSource(el)) {
81
+ relations.push(el);
82
+ continue;
83
+ }
79
84
  if (ast.isExtendElement(el)) {
80
- if (!!el.body) {
85
+ if (el.body && el.body.elements.length > 0) {
81
86
  traverseStack.push(...el.body.elements);
82
87
  }
83
88
  continue;
84
89
  }
85
- if (ast.isElement(el) && el.body) {
86
- traverseStack.push(...el.body.elements);
90
+ if (ast.isElement(el) && el.body && el.body.elements.length > 0) {
91
+ for (const nested of el.body.elements) {
92
+ if (ast.isRelation(nested)) {
93
+ relations.push(nested);
94
+ }
95
+ else {
96
+ traverseStack.push(nested);
97
+ }
98
+ }
87
99
  }
88
100
  yield el;
89
101
  }
102
+ for (const relation of relations) {
103
+ yield relation;
104
+ }
90
105
  }
91
106
  export function resolveRelationPoints(node) {
92
107
  const target = elementRef(node.target);
@@ -1,10 +1,12 @@
1
1
  import type { Fqn } from '@likec4/core/types';
2
2
  import type { LangiumDocuments } from 'langium';
3
- import { DocumentState, MultiMap, StreamImpl } from 'langium';
4
- import type { SetNonNullable } from 'type-fest';
3
+ import { StreamImpl } from 'langium';
5
4
  import type { ast } from '../ast';
6
5
  import { type LikeC4LangiumDocument } from '../ast';
7
6
  import type { LikeC4Services } from '../module';
7
+ type FqnIndexedDocument = Omit<LikeC4LangiumDocument, 'c4fqns'> & {
8
+ c4fqns: NonNullable<LikeC4LangiumDocument['c4fqns']>;
9
+ };
8
10
  export interface FqnIndexEntry {
9
11
  fqn: Fqn;
10
12
  name: string;
@@ -20,23 +22,10 @@ export declare class FqnIndex {
20
22
  get(el: ast.Element): Fqn | null;
21
23
  byFqn(fqn: Fqn): import("langium").Stream<{
22
24
  path: string;
23
- doc: SetNonNullable<{
24
- c4hash?: string;
25
- c4Specification: import("../ast").ParsedAstSpecification;
26
- c4Elements: import("../ast").ParsedAstElement[];
27
- c4Relations: import("../ast").ParsedAstRelation[];
28
- c4Views: import("../ast").ParsedAstElementView[];
29
- readonly uri: import("vscode-uri").URI;
30
- readonly textDocument: import("vscode-languageserver-textdocument").TextDocument;
31
- state: DocumentState;
32
- parseResult: import("langium").ParseResult<ast.LikeC4Document>;
33
- precomputedScopes?: import("langium").PrecomputedScopes;
34
- references: import("langium").Reference<import("langium").AstNode>[];
35
- diagnostics?: import("vscode-languageserver-types").Diagnostic[];
36
- c4fqns: MultiMap<Fqn, string> | undefined;
37
- }, "c4fqns">;
25
+ doc: FqnIndexedDocument;
38
26
  }>;
39
27
  directChildrenOf(parent: Fqn): import("langium").Stream<FqnIndexEntry>;
40
28
  uniqueDescedants(parent: Fqn): StreamImpl<IterableIterator<FqnIndexEntry> | null, FqnIndexEntry>;
41
29
  }
30
+ export {};
42
31
  //# sourceMappingURL=fqn-index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  import { nameFromFqn, parentFqn } from '@likec4/core/utils';
2
2
  import { DocumentState, DONE_RESULT, getDocument, MultiMap, StreamImpl } from 'langium';
3
- import { isNil } from 'rambdax';
3
+ import { isNil } from 'remeda';
4
4
  import { ElementOps, isLikeC4LangiumDocument } from '../ast';
5
5
  import { logger } from '../logger';
6
6
  import { computeDocumentFqn } from './fqn-computation';
@@ -1,10 +1,10 @@
1
- import { computeViews } from '@likec4/core/compute-view';
1
+ import { computeViews } from '@likec4/core';
2
2
  import { DefaultElementShape, DefaultThemeColor } from '@likec4/core/types';
3
3
  import { compareByFqnHierarchically, parentFqn } from '@likec4/core/utils';
4
- import { A, O, flow, pipe } from '@mobily/ts-belt';
5
4
  import { DocumentState, getDocument } from 'langium';
6
5
  import objectHash from 'object-hash';
7
- import { clone, isNil, mergeDeepRight, reduce } from 'rambdax';
6
+ import { clone, isNil } from 'rambdax';
7
+ import * as R from 'remeda';
8
8
  import invariant from 'tiny-invariant';
9
9
  import { ElementViewOps, ast, c4hash, cleanParsedModel, isLikeC4LangiumDocument, isParsedLikeC4LangiumDocument, resolveRelationPoints, streamModel, toAutoLayout, toElementStyle } from '../ast';
10
10
  import { elementRef, strictElementRefFqn } from '../elementRef';
@@ -31,7 +31,7 @@ export class LikeC4ModelBuilder {
31
31
  }
32
32
  }
33
33
  catch (e) {
34
- logger.warn(`Error parsing document ${doc.uri.toString()}`);
34
+ logger.error(`Error parsing document ${doc.uri.toString()}`);
35
35
  }
36
36
  }
37
37
  if (countOfChangedDocs > 0 && !cancelToken.isCancellationRequested) {
@@ -53,14 +53,10 @@ export class LikeC4ModelBuilder {
53
53
  }
54
54
  // TODO:
55
55
  try {
56
- const c4Specification = reduce((acc, doc) => mergeDeepRight(acc, doc.c4Specification), {
56
+ const c4Specification = {
57
57
  kinds: {}
58
- }, docs);
59
- // const c4Specification = docs.reduce<ParsedAstSpecification>((acc, doc) => {
60
- // return mergeDeepRight(acc, doc.c4Specification)
61
- // }, {
62
- // kinds: {}
63
- // })
58
+ };
59
+ R.pipe(R.map(docs, R.prop('c4Specification')), R.forEach(spec => Object.assign(c4Specification.kinds, spec.kinds)));
64
60
  const toModelElement = (el) => {
65
61
  const kind = c4Specification.kinds[el.kind];
66
62
  if (kind) {
@@ -77,7 +73,7 @@ export class LikeC4ModelBuilder {
77
73
  const { astPath, ...model } = rel;
78
74
  return model;
79
75
  };
80
- const elements = pipe(docs.flatMap(d => d.c4Elements), A.filterMap(flow(toModelElement, O.fromNullable)), A.sort(compareByFqnHierarchically), A.reduce({}, (acc, el) => {
76
+ const elements = R.pipe(R.flatMap(docs, d => d.c4Elements), R.map(toModelElement), R.compact, R.sort(compareByFqnHierarchically), R.reduce((acc, el) => {
81
77
  const parent = parentFqn(el.id);
82
78
  if (!parent || parent in acc) {
83
79
  if (el.id in acc) {
@@ -87,15 +83,8 @@ export class LikeC4ModelBuilder {
87
83
  acc[el.id] = el;
88
84
  }
89
85
  return acc;
90
- }));
91
- const relations = pipe(docs.flatMap(d => d.c4Relations), A.filterMap(flow(toModelRelation, O.fromPredicate(({ source, target }) => source in elements && target in elements))), A.reduce({}, (acc, el) => {
92
- if (el.id in acc) {
93
- logger.warn(`Duplicate relation id: ${el.id}`);
94
- return acc;
95
- }
96
- acc[el.id] = el;
97
- return acc;
98
- }));
86
+ }, {}));
87
+ const relations = R.pipe(R.flatMap(docs, d => d.c4Relations), R.map(toModelRelation), R.filter(({ source, target }) => source in elements && target in elements), R.mapToObj(r => [r.id, r]));
99
88
  const toModelView = (view) => {
100
89
  // eslint-disable-next-line prefer-const
101
90
  let { astPath, rules, title, ...model } = view;
@@ -111,14 +100,7 @@ export class LikeC4ModelBuilder {
111
100
  rules: clone(rules)
112
101
  };
113
102
  };
114
- const views = pipe(docs.flatMap(d => d.c4Views), A.filterMap(flow(toModelView, O.fromPredicate(v => isNil(v.viewOf) || v.viewOf in elements))), A.reduce({}, (acc, v) => {
115
- if (v.id in acc) {
116
- logger.warn(`Duplicate view id: ${v.id}`);
117
- return acc;
118
- }
119
- acc[v.id] = v;
120
- return acc;
121
- }));
103
+ const views = R.pipe(docs, R.flatMap(d => d.c4Views), R.map(toModelView), R.filter(v => isNil(v.viewOf) || v.viewOf in elements), R.mapToObj(v => [v.id, v]));
122
104
  return computeViews({
123
105
  elements,
124
106
  relations,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/language-server",
3
3
  "description": "LikeC4 Language Server",
4
- "version": "0.19.0",
4
+ "version": "0.20.1",
5
5
  "license": "MIT",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
@@ -20,15 +20,11 @@
20
20
  "directory": "packages/language-server"
21
21
  },
22
22
  "type": "module",
23
- "main": "./dist/index.js",
24
- "module": "./dist/index.js",
25
- "types": "./dist/index.d.ts",
23
+ "main": "src/index.ts",
24
+ "module": "src/index.ts",
25
+ "types": "src/index.ts",
26
26
  "exports": {
27
- ".": {
28
- "types": "./dist/index.d.ts",
29
- "import": "./dist/index.js",
30
- "require": "./dist/index.js"
31
- }
27
+ ".": "./src/index.ts"
32
28
  },
33
29
  "publishConfig": {
34
30
  "registry": "https://registry.npmjs.org",
@@ -58,15 +54,14 @@
58
54
  "test:watch": "run -T vitest"
59
55
  },
60
56
  "dependencies": {
61
- "@likec4/core": "0.19.0",
62
- "@mobily/ts-belt": "^3.13.1",
57
+ "@likec4/core": "0.20.1",
63
58
  "langium": "^1.2.0",
64
59
  "nanoid": "^4.0.2",
65
60
  "object-hash": "^3.0.0",
66
61
  "rambdax": "^9.1.1",
62
+ "remeda": "^1.19.0",
67
63
  "strip-indent": "^4.0.0",
68
64
  "tiny-invariant": "^1.3.1",
69
- "type-fest": "^3.11.1",
70
65
  "vscode-languageserver": "~8.1.0",
71
66
  "vscode-languageserver-protocol": "~3.17.3"
72
67
  },
@@ -77,4 +72,4 @@
77
72
  "npm-run-all": "^4.1.5",
78
73
  "typescript": "^5.1.3"
79
74
  }
80
- }
75
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { createLanguageServices } from './module'
2
+ export type { LikeC4Services } from './module'