@likec4/language-server 1.28.0 → 1.28.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.
@@ -187,7 +187,7 @@ export function ViewsParser(B) {
187
187
  }
188
188
  parseViewRuleStyle(astRule) {
189
189
  const styleProps = astRule.props.filter(ast.isStyleProperty);
190
- const targets = astRule.target;
190
+ const targets = astRule.targets;
191
191
  const notation = astRule.props.find(ast.isNotationProperty);
192
192
  return this.parseRuleStyle(styleProps, targets, notation);
193
193
  }
@@ -3,7 +3,6 @@ import { GrammarUtils } from "langium";
3
3
  import { entries, filter, findLast, isTruthy, last } from "remeda";
4
4
  import { TextEdit } from "vscode-languageserver-types";
5
5
  import { ast } from "../ast.js";
6
- import { isReferenceToLogicalModel } from "../utils/index.js";
7
6
  const { findNodeForKeyword, findNodeForProperty } = GrammarUtils;
8
7
  const asViewStyleRule = (target, style, indent = 0) => {
9
8
  const indentStr = indent > 0 ? " ".repeat(indent) : "";
@@ -16,15 +15,15 @@ const asViewStyleRule = (target, style, indent = 0) => {
16
15
  ];
17
16
  };
18
17
  const isMatchingViewRule = (fqn, index) => (rule) => {
19
- if (!ast.isViewRuleStyle(rule)) {
18
+ if (!ast.isViewRuleStyle(rule) && !ast.isDeploymentViewRuleStyle(rule)) {
20
19
  return false;
21
20
  }
22
- const target = rule.target.value;
23
- if (!target || isTruthy(rule.target.prev) || target.$type !== "FqnRefExpr" || !isReferenceToLogicalModel(target.ref)) {
21
+ const target = rule.targets.value;
22
+ if (!target || isTruthy(rule.targets.prev) || target.$type !== "FqnRefExpr" || isTruthy(target.selector)) {
24
23
  return false;
25
24
  }
26
- const ref = target.el.ref;
27
- const _fqn = ref ? index.getFqn(ref) : null;
25
+ const ref = target.ref?.value?.ref;
26
+ const _fqn = ref ? index.resolve(ref) : null;
28
27
  return _fqn === fqn;
29
28
  };
30
29
  export function changeElementStyle(services, {
@@ -40,7 +39,10 @@ export function changeElementStyle(services, {
40
39
  invariant(insertPos, "insertPos is not defined");
41
40
  const indent = viewCstNode.range.start.character + 2;
42
41
  const fqnIndex = services.likec4.FqnIndex;
43
- const styleRules = filter(viewAst.body.rules, ast.isViewRuleStyle);
42
+ const styleRules = filter(
43
+ viewAst.body.rules,
44
+ (r) => ast.isViewRuleStyle(r) || ast.isDeploymentViewRuleStyle(r)
45
+ );
44
46
  const viewOf = view.__ === "element" ? view.viewOf : null;
45
47
  const existing = [];
46
48
  const insert = [];
@@ -25,6 +25,7 @@ export declare class DefaultLikeC4Views implements LikeC4Views {
25
25
  private cache;
26
26
  private viewsWithReportedErrors;
27
27
  private ModelBuilder;
28
+ private queue;
28
29
  constructor(services: LikeC4Services);
29
30
  get layouter(): GraphvizLayouter;
30
31
  computedViews(projectId?: ProjectId | undefined, cancelToken?: CancellationToken): Promise<ComputedView[]>;
@@ -1,9 +1,9 @@
1
1
  import { loggable } from "@likec4/log";
2
+ import PQueue from "p-queue";
2
3
  import prettyMs from "pretty-ms";
3
4
  import { values } from "remeda";
4
5
  import { CancellationToken } from "vscode-jsonrpc";
5
6
  import { logError, logger as rootLogger, logWarnError } from "../logger.js";
6
- const logger = rootLogger.getChild("Views");
7
7
  export class DefaultLikeC4Views {
8
8
  constructor(services) {
9
9
  this.services = services;
@@ -12,6 +12,7 @@ export class DefaultLikeC4Views {
12
12
  cache = /* @__PURE__ */ new WeakMap();
13
13
  viewsWithReportedErrors = /* @__PURE__ */ new Set();
14
14
  ModelBuilder;
15
+ queue = new PQueue({ concurrency: 4, timeout: 1e4, throwOnTimeout: true });
15
16
  get layouter() {
16
17
  return this.services.likec4.Layouter;
17
18
  }
@@ -24,19 +25,28 @@ export class DefaultLikeC4Views {
24
25
  if (views.length === 0) {
25
26
  return [];
26
27
  }
28
+ const logger = rootLogger.getChild(["views", projectId ?? ""]);
27
29
  logger.debug`layoutAll: ${views.length} views`;
28
30
  const results = [];
29
31
  const tasks = [];
30
32
  for (const view of views) {
31
33
  this.viewsWithReportedErrors.delete(view.id);
32
34
  tasks.push(
33
- this.layouter.layout(view).then((result) => {
35
+ Promise.resolve().then(async () => {
36
+ const result = await this.queue.add(async () => {
37
+ logger.debug`layouting view ${view.id}...`;
38
+ return await this.layouter.layout(view);
39
+ });
40
+ if (!result) {
41
+ return Promise.reject(new Error(`Failed to layout view ${view.id}`));
42
+ }
43
+ logger.debug`done layout view ${view.id}`;
34
44
  this.viewsWithReportedErrors.delete(view.id);
35
45
  this.cache.set(view, result);
36
46
  return result;
37
47
  }).catch((e) => {
48
+ logger.warn(`fail layout view ${view.id}`, { e });
38
49
  this.cache.delete(view);
39
- logWarnError(e);
40
50
  return Promise.reject(e);
41
51
  })
42
52
  );
@@ -44,6 +54,8 @@ export class DefaultLikeC4Views {
44
54
  for (const task of await Promise.allSettled(tasks)) {
45
55
  if (task.status === "fulfilled") {
46
56
  results.push(task.value);
57
+ } else {
58
+ logger.error(loggable(task.reason));
47
59
  }
48
60
  }
49
61
  if (results.length !== views.length) {
@@ -56,6 +68,7 @@ export class DefaultLikeC4Views {
56
68
  async layoutView(viewId, projectId, cancelToken = CancellationToken.None) {
57
69
  const model = await this.ModelBuilder.buildLikeC4Model(projectId, cancelToken);
58
70
  const view = model.findView(viewId)?.$view;
71
+ const logger = rootLogger.getChild(["views", projectId ?? ""]);
59
72
  if (!view) {
60
73
  logger.warn`layoutView ${viewId} not found`;
61
74
  return null;
@@ -67,7 +80,13 @@ export class DefaultLikeC4Views {
67
80
  }
68
81
  try {
69
82
  const start = performance.now();
70
- const result = await this.layouter.layout(view);
83
+ const result = await this.queue.add(async () => {
84
+ logger.debug`layouting view ${view.id}...`;
85
+ return await this.layouter.layout(view);
86
+ });
87
+ if (!result) {
88
+ throw new Error(`Failed to layout view ${viewId}`);
89
+ }
71
90
  this.viewsWithReportedErrors.delete(viewId);
72
91
  this.cache.set(view, result);
73
92
  logger.debug(`layout {viewId} ready in ${prettyMs(performance.now() - start)}`, { viewId });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@likec4/language-server",
3
3
  "description": "LikeC4 Language Server",
4
- "version": "1.28.0",
4
+ "version": "1.28.1",
5
5
  "license": "MIT",
6
6
  "bugs": "https://github.com/likec4/likec4/issues",
7
7
  "homepage": "https://likec4.dev",
@@ -96,7 +96,8 @@
96
96
  "devDependencies": {
97
97
  "@msgpack/msgpack": "^3.1.1",
98
98
  "@smithy/util-base64": "^4.0.0",
99
- "@types/node": "^20.17.28",
99
+ "@types/node": "^20.17.30",
100
+ "@types/picomatch": "^4.0.0",
100
101
  "@types/which": "^3.0.4",
101
102
  "esm-env": "^1.2.2",
102
103
  "fast-equals": "^5.2.2",
@@ -107,28 +108,29 @@
107
108
  "langium-cli": "3.4.0",
108
109
  "natural-compare-lite": "^1.4.0",
109
110
  "p-debounce": "^4.0.0",
111
+ "p-queue": "^8.1.0",
112
+ "picomatch": "^4.0.2",
113
+ "p-timeout": "^6.1.4",
110
114
  "pretty-ms": "^9.2.0",
111
115
  "remeda": "^2.21.2",
112
- "@types/picomatch": "^4.0.0",
113
- "picomatch": "^4.0.2",
114
116
  "strip-indent": "^4.0.0",
115
117
  "tsx": "~4.19.3",
116
118
  "turbo": "^2.5.0",
117
119
  "type-fest": "^4.39.1",
118
120
  "typescript": "^5.8.3",
119
- "ufo": "^1.5.4",
121
+ "ufo": "^1.6.1",
120
122
  "unbuild": "^3.5.0",
121
123
  "valibot": "^1.0.0",
122
124
  "vitest": "^3.1.1",
123
125
  "vscode-languageserver": "9.0.1",
124
- "vscode-languageserver-types": "3.17.5",
125
126
  "vscode-languageserver-protocol": "3.17.5",
127
+ "vscode-languageserver-types": "3.17.5",
126
128
  "which": "^5.0.0",
127
- "@likec4/core": "1.28.0",
128
- "@likec4/icons": "1.28.0",
129
- "@likec4/log": "1.28.0",
130
- "@likec4/layouts": "1.28.0",
131
- "@likec4/tsconfig": "1.28.0"
129
+ "@likec4/core": "1.28.1",
130
+ "@likec4/layouts": "1.28.1",
131
+ "@likec4/tsconfig": "1.28.1",
132
+ "@likec4/log": "1.28.1",
133
+ "@likec4/icons": "1.28.1"
132
134
  },
133
135
  "scripts": {
134
136
  "typecheck": "tsc --noEmit",