@marko/language-server 1.0.1 → 1.0.3

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/index.mjs CHANGED
@@ -15,17 +15,31 @@ import {
15
15
  } from "vscode-languageserver/node";
16
16
 
17
17
  // src/utils/project.ts
18
+ import path from "path";
18
19
  import * as defaultCompiler from "@marko/compiler";
19
20
  import * as defaultTranslator from "@marko/translator-default";
20
- import lassoPackageRoot from "lasso-package-root";
21
21
  import resolveFrom from "resolve-from";
22
- var cwd = process.cwd();
23
- var kTaglib = Symbol("taglib");
22
+ var ignoreErrors = (_err) => {
23
+ };
24
24
  var projectsByDir = /* @__PURE__ */ new Map();
25
+ var projectsByCompiler = /* @__PURE__ */ new Map();
25
26
  var defaultProject = {
26
- rootDir: cwd,
27
27
  cache: /* @__PURE__ */ new Map(),
28
- lookup: defaultCompiler.taglib.buildLookup(cwd, defaultTranslator),
28
+ getLookup(dir) {
29
+ const key = `taglib:${dir}`;
30
+ let lookup = defaultProject.cache.get(key);
31
+ if (!lookup) {
32
+ defaultProject.cache.set(
33
+ key,
34
+ lookup = defaultCompiler.taglib.buildLookup(
35
+ dir,
36
+ defaultTranslator,
37
+ ignoreErrors
38
+ )
39
+ );
40
+ }
41
+ return lookup;
42
+ },
29
43
  compiler: defaultCompiler,
30
44
  translator: defaultTranslator
31
45
  };
@@ -41,55 +55,119 @@ function getMarkoProject(dir) {
41
55
  return project;
42
56
  }
43
57
  function getMarkoProjects() {
44
- return new Set(projectsByDir.values());
58
+ return projectsByCompiler.values();
59
+ }
60
+ function clearMarkoProjectCaches() {
61
+ for (const project of getMarkoProjects()) {
62
+ project.cache.clear();
63
+ project.compiler.taglib.clearCaches();
64
+ }
45
65
  }
46
66
  function loadProject(dir) {
47
- const rootDir = lassoPackageRoot.getRootDir(dir) || cwd;
48
- const pkgPath = resolveFrom.silent(rootDir, "@marko/compiler/package.json");
49
- const pkg = pkgPath && __require(pkgPath);
50
- const cache = /* @__PURE__ */ new Map();
51
- let translator = defaultTranslator;
52
- let compiler = defaultCompiler;
53
- if (pkg && /^5\./.test(pkg.version)) {
54
- try {
55
- let checkTranslator = [].concat(
56
- Object.keys(pkg.dependencies),
57
- Object.keys(pkg.peerDependencies),
58
- Object.keys(pkg.devDependencies)
59
- ).find((name) => /^marko$|^(@\/marko\/|marko-)translator-/.test(name));
60
- if (checkTranslator === "marko" || !checkTranslator) {
61
- checkTranslator = __require(resolveFrom(dir, "@marko/compiler/config")).translator;
67
+ try {
68
+ const compilerConfigPath = resolveFrom(dir, "@marko/compiler/config");
69
+ const cachedProject = projectsByCompiler.get(compilerConfigPath);
70
+ if (cachedProject)
71
+ return cachedProject;
72
+ const [compiler, translator] = [
73
+ __require(path.join(compilerConfigPath, "..")),
74
+ __require(resolveFrom(
75
+ dir,
76
+ interopDefault(__require(compilerConfigPath)).translator
77
+ ))
78
+ ];
79
+ const project = {
80
+ cache: /* @__PURE__ */ new Map(),
81
+ getLookup(dir2) {
82
+ const key = `taglib:${dir2}`;
83
+ let lookup = project.cache.get(key);
84
+ if (lookup === void 0) {
85
+ try {
86
+ lookup = compiler.taglib.buildLookup(dir2, translator, ignoreErrors);
87
+ } catch {
88
+ lookup = defaultProject.getLookup(dir2);
89
+ }
90
+ project.cache.set(key, lookup);
91
+ }
92
+ return lookup;
93
+ },
94
+ compiler,
95
+ translator
96
+ };
97
+ projectsByCompiler.set(compilerConfigPath, project);
98
+ return project;
99
+ } catch {
100
+ return defaultProject;
101
+ }
102
+ }
103
+ function interopDefault(mod) {
104
+ return mod.default || mod;
105
+ }
106
+
107
+ // src/utils/file.ts
108
+ import path2 from "path";
109
+ import { parse } from "@marko/language-tools";
110
+ import { URI } from "vscode-uri";
111
+ var processorCaches = /* @__PURE__ */ new WeakMap();
112
+ function getFSPath(doc) {
113
+ return URI.parse(doc.uri).fsPath;
114
+ }
115
+ function getMarkoFile(doc) {
116
+ const { uri } = doc;
117
+ const { fsPath: filename, scheme } = URI.parse(uri);
118
+ const dirname = filename && path2.dirname(filename);
119
+ const project = getMarkoProject(dirname);
120
+ const cache = project.cache;
121
+ let file = cache.get(doc);
122
+ if (!file) {
123
+ const { version } = doc;
124
+ const code = doc.getText();
125
+ const parsed = parse(code, filename);
126
+ const lookup = project.getLookup(dirname);
127
+ cache.set(
128
+ doc,
129
+ file = {
130
+ project,
131
+ uri,
132
+ scheme,
133
+ version,
134
+ lookup,
135
+ filename,
136
+ dirname,
137
+ parsed,
138
+ code
62
139
  }
63
- [compiler, translator] = [
64
- __require(resolveFrom(dir, "@marko/compiler")),
65
- __require(resolveFrom(dir, checkTranslator))
66
- ];
67
- } catch {
140
+ );
141
+ }
142
+ return file;
143
+ }
144
+ function clearMarkoCacheForFile(doc) {
145
+ const { fsPath: filename } = URI.parse(doc.uri);
146
+ const dirname = filename && path2.dirname(filename);
147
+ const project = getMarkoProject(dirname);
148
+ const cache = project.cache;
149
+ cache.delete(doc);
150
+ }
151
+ function processDoc(doc, process2) {
152
+ const file = getMarkoFile(doc);
153
+ const cache = processorCaches.get(file.parsed);
154
+ let result;
155
+ if (cache) {
156
+ result = cache.get(process2);
157
+ if (!result) {
158
+ result = process2(file);
159
+ cache.set(process2, result);
68
160
  }
161
+ } else {
162
+ result = process2(file);
163
+ processorCaches.set(file.parsed, /* @__PURE__ */ new Map([[process2, result]]));
69
164
  }
70
- return {
71
- rootDir,
72
- cache,
73
- get lookup() {
74
- let lookup = cache.get(kTaglib);
75
- if (lookup === void 0) {
76
- try {
77
- lookup = compiler.taglib.buildLookup(dir, translator);
78
- } catch {
79
- lookup = defaultProject.lookup;
80
- }
81
- cache.set(kTaglib, lookup);
82
- }
83
- return lookup;
84
- },
85
- compiler,
86
- translator
87
- };
165
+ return result;
88
166
  }
89
167
 
90
168
  // src/utils/text-documents.ts
91
169
  import fs from "fs";
92
- import { URI } from "vscode-uri";
170
+ import { URI as URI2 } from "vscode-uri";
93
171
  import { FileChangeType } from "vscode-languageserver";
94
172
  import { TextDocument } from "vscode-languageserver-textdocument";
95
173
  var docs = /* @__PURE__ */ new Map();
@@ -107,7 +185,7 @@ function get(uri) {
107
185
  const doc = docs.get(uri);
108
186
  if (doc)
109
187
  return doc;
110
- const { fsPath, scheme } = URI.parse(uri);
188
+ const { fsPath, scheme } = URI2.parse(uri);
111
189
  if (scheme === "file") {
112
190
  if (fileExists.get(uri) === false)
113
191
  return void 0;
@@ -130,7 +208,7 @@ function exists(uri) {
130
208
  const cached = fileExists.get(uri);
131
209
  if (cached !== void 0)
132
210
  return cached;
133
- const { fsPath, scheme } = URI.parse(uri);
211
+ const { fsPath, scheme } = URI2.parse(uri);
134
212
  if (scheme === "file") {
135
213
  try {
136
214
  fs.accessSync(fsPath);
@@ -184,7 +262,7 @@ function setup(connection4) {
184
262
  if (doc) {
185
263
  projectVersion++;
186
264
  openDocs.delete(doc);
187
- if (URI.parse(ref.uri).scheme !== "file") {
265
+ if (URI2.parse(ref.uri).scheme !== "file") {
188
266
  docs.delete(ref.uri);
189
267
  }
190
268
  }
@@ -287,62 +365,6 @@ function display(type, data) {
287
365
  setImmediate(() => connection2.sendNotification(type, msg));
288
366
  }
289
367
 
290
- // src/utils/file.ts
291
- import path from "path";
292
- import { parse } from "@marko/language-tools";
293
- import { URI as URI2 } from "vscode-uri";
294
- var processorCaches = /* @__PURE__ */ new WeakMap();
295
- function getFSDir(doc) {
296
- const filename = getFSPath(doc);
297
- return filename ? path.dirname(filename) : void 0;
298
- }
299
- function getFSPath(doc) {
300
- return URI2.parse(doc.uri).fsPath;
301
- }
302
- function getMarkoFile(doc) {
303
- const { uri } = doc;
304
- const { fsPath: filename, scheme } = URI2.parse(uri);
305
- const dirname = filename && path.dirname(filename);
306
- const project = getMarkoProject(dirname);
307
- const cache = project.cache;
308
- let file = cache.get(doc);
309
- if (!file) {
310
- const { version } = doc;
311
- const code = doc.getText();
312
- const parsed = parse(code, filename);
313
- cache.set(
314
- doc,
315
- file = {
316
- project,
317
- uri,
318
- scheme,
319
- version,
320
- filename,
321
- dirname,
322
- parsed,
323
- code
324
- }
325
- );
326
- }
327
- return file;
328
- }
329
- function processDoc(doc, process2) {
330
- const file = getMarkoFile(doc);
331
- const cache = processorCaches.get(file.parsed);
332
- let result;
333
- if (cache) {
334
- result = cache.get(process2);
335
- if (!result) {
336
- result = process2(file);
337
- cache.set(process2, result);
338
- }
339
- } else {
340
- result = process2(file);
341
- processorCaches.set(file.parsed, /* @__PURE__ */ new Map([[process2, result]]));
342
- }
343
- return result;
344
- }
345
-
346
368
  // src/service/index.ts
347
369
  import { MarkupContent, MarkupKind as MarkupKind3 } from "vscode-languageserver";
348
370
 
@@ -359,10 +381,7 @@ import {
359
381
  function AttrName({
360
382
  offset,
361
383
  node,
362
- file: {
363
- parsed,
364
- project: { lookup }
365
- }
384
+ file: { parsed, lookup }
366
385
  }) {
367
386
  let name = parsed.read(node);
368
387
  const modifierIndex = name.indexOf(":");
@@ -459,7 +478,7 @@ function isExternalModule(file) {
459
478
  }
460
479
 
461
480
  // src/service/marko/complete/AttrValue.ts
462
- import path2 from "path";
481
+ import path3 from "path";
463
482
  import {
464
483
  CompletionItemKind as CompletionItemKind2,
465
484
  TextEdit as TextEdit2
@@ -572,7 +591,7 @@ async function AttrValue({
572
591
  const resolved = resolveUrl(req, uri);
573
592
  if (resolved) {
574
593
  const result = [];
575
- const curFile = req === "." ? path2.basename(uri) : void 0;
594
+ const curFile = req === "." ? path3.basename(uri) : void 0;
576
595
  const replaceRange = parsed.locationAt({
577
596
  start: start + segmentStart + 1,
578
597
  end: start + rawValue.length
@@ -605,7 +624,7 @@ async function AttrValue({
605
624
  import { TextEdit as TextEdit4 } from "vscode-languageserver";
606
625
 
607
626
  // src/service/marko/util/get-tag-name-completion.ts
608
- import path3 from "path";
627
+ import path4 from "path";
609
628
  import {
610
629
  CompletionItemKind as CompletionItemKind3,
611
630
  CompletionItemTag,
@@ -634,7 +653,7 @@ function getTagNameCompletion({
634
653
  kind: MarkupKind2.Markdown,
635
654
  value: tag.html ? `Built in [<${tag.name}>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/${tag.name}) HTML tag.` : isCoreTag ? `Core Marko <${tag.name}> tag.` : nodeModuleName ? `Custom Marko tag discovered from the ["${nodeModuleName}"](${fileURIForTag}) npm package.` : `Custom Marko tag discovered from:
636
655
 
637
- [${importer ? path3.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
656
+ [${importer ? path4.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
638
657
  };
639
658
  if (tag.description) {
640
659
  documentation.value += `
@@ -671,11 +690,7 @@ ${autocomplete.description}`;
671
690
  var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/;
672
691
  function Import({
673
692
  node,
674
- file: {
675
- parsed,
676
- filename,
677
- project: { lookup }
678
- }
693
+ file: { parsed, filename, lookup }
679
694
  }) {
680
695
  var _a;
681
696
  const value = parsed.read(node);
@@ -707,11 +722,7 @@ function Import({
707
722
  import { NodeType as NodeType2 } from "@marko/language-tools";
708
723
  function OpenTagName({
709
724
  node,
710
- file: {
711
- parsed,
712
- filename,
713
- project: { lookup }
714
- }
725
+ file: { parsed, filename, lookup }
715
726
  }) {
716
727
  var _a;
717
728
  const tag = node.parent;
@@ -832,14 +843,14 @@ var doComplete = async (doc, params) => {
832
843
  };
833
844
 
834
845
  // src/service/marko/validate.ts
835
- import path4 from "path";
846
+ import path5 from "path";
836
847
  import { DiagnosticSeverity } from "vscode-languageserver";
837
848
  var markoErrorRegExp = /^(.+?)\.marko(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
838
849
  var doValidate = (doc) => {
839
850
  const filename = getFSPath(doc);
840
851
  const diagnostics = [];
841
852
  const { compiler, translator, cache } = getMarkoProject(
842
- filename && path4.dirname(filename)
853
+ filename && path5.dirname(filename)
843
854
  );
844
855
  try {
845
856
  compiler.compileSync(doc.getText(), filename || "untitled.marko", {
@@ -895,11 +906,7 @@ var START_LOCATION = {
895
906
  // src/service/marko/hover/OpenTagName.ts
896
907
  function OpenTagName2({
897
908
  node,
898
- file: {
899
- parsed,
900
- filename,
901
- project: { lookup }
902
- }
909
+ file: { parsed, filename, lookup }
903
910
  }) {
904
911
  const tag = node.parent;
905
912
  const range = parsed.locationAt(node);
@@ -971,10 +978,7 @@ function escape(val) {
971
978
  // src/service/marko/definition/AttrName.ts
972
979
  function AttrName2({
973
980
  node,
974
- file: {
975
- parsed,
976
- project: { lookup }
977
- }
981
+ file: { parsed, lookup }
978
982
  }) {
979
983
  const tagName = node.parent.parent.nameText;
980
984
  const attrName = parsed.read(node);
@@ -1013,7 +1017,7 @@ function AttrName2({
1013
1017
 
1014
1018
  // src/service/marko/definition/OpenTagName.ts
1015
1019
  import fs4 from "fs";
1016
- import path5 from "path";
1020
+ import path6 from "path";
1017
1021
  import { URI as URI5 } from "vscode-uri";
1018
1022
  import {
1019
1023
  NodeType as NodeType5,
@@ -1022,10 +1026,7 @@ import {
1022
1026
  } from "@marko/language-tools";
1023
1027
  function OpenTagName3({
1024
1028
  node,
1025
- file: {
1026
- parsed,
1027
- project: { lookup }
1028
- }
1029
+ file: { parsed, lookup }
1029
1030
  }) {
1030
1031
  const tag = node.parent;
1031
1032
  let tagDef;
@@ -1042,7 +1043,7 @@ function OpenTagName3({
1042
1043
  return;
1043
1044
  }
1044
1045
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
1045
- if (!path5.isAbsolute(tagEntryFile)) {
1046
+ if (!path6.isAbsolute(tagEntryFile)) {
1046
1047
  return;
1047
1048
  }
1048
1049
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
@@ -1097,7 +1098,7 @@ function extractDocumentLinks({
1097
1098
  scheme,
1098
1099
  parsed,
1099
1100
  code,
1100
- project: { lookup }
1101
+ lookup
1101
1102
  }) {
1102
1103
  if (scheme !== "file") {
1103
1104
  return [];
@@ -1173,7 +1174,7 @@ function extractDocumentSymbols({
1173
1174
  uri,
1174
1175
  scheme,
1175
1176
  parsed,
1176
- project: { lookup }
1177
+ lookup
1177
1178
  }) {
1178
1179
  if (scheme !== "file") {
1179
1180
  return [];
@@ -1254,7 +1255,7 @@ var marko_default = {
1254
1255
  };
1255
1256
 
1256
1257
  // src/service/script/index.ts
1257
- import path9 from "path";
1258
+ import path10 from "path";
1258
1259
  import { relativeImportPath } from "relative-import-path";
1259
1260
  import ts from "typescript/lib/tsserverlibrary";
1260
1261
  import {
@@ -1273,7 +1274,7 @@ import {
1273
1274
  } from "@marko/language-tools";
1274
1275
 
1275
1276
  // src/ts-plugin/host.ts
1276
- import path8 from "path";
1277
+ import path9 from "path";
1277
1278
  import {
1278
1279
  ScriptLang as ScriptLang2,
1279
1280
  extractScript,
@@ -1281,23 +1282,38 @@ import {
1281
1282
  } from "@marko/language-tools";
1282
1283
 
1283
1284
  // src/utils/get-runtime-types.ts
1284
- import path6 from "path";
1285
- var internalTypesFile = path6.join(__dirname, "marko.internal.d.ts");
1286
- var defaultMarkoTypesFile = path6.join(__dirname, "marko.runtime.d.ts");
1287
- function getProjectTypeLibs(project, ts2, host) {
1285
+ import path7 from "path";
1286
+ var internalTypesFile = path7.join(__dirname, "marko.internal.d.ts");
1287
+ var defaultMarkoTypesFile = path7.join(__dirname, "marko.runtime.d.ts");
1288
+ function getProjectTypeLibs(rootDir, project, ts2, host) {
1288
1289
  let cached = project.cache.get(getProjectTypeLibs);
1289
1290
  if (cached === void 0) {
1290
- const { resolvedTypeReferenceDirective } = ts2.resolveTypeReferenceDirective(
1291
+ const markoRunGeneratedTypesFile = path7.join(
1292
+ rootDir,
1293
+ ".marko-run/routes.d.ts"
1294
+ );
1295
+ const resolveFromFile = path7.join(host.getCurrentDirectory(), "_.d.ts");
1296
+ const compilerOptions = host.getCompilationSettings();
1297
+ const { resolvedTypeReferenceDirective: resolvedMarkoTypes } = ts2.resolveTypeReferenceDirective(
1291
1298
  project.translator.runtimeTypes || "marko",
1292
- path6.join(project.rootDir, "_.d.ts"),
1293
- host.getCompilationSettings(),
1299
+ resolveFromFile,
1300
+ compilerOptions,
1301
+ host
1302
+ );
1303
+ const { resolvedTypeReferenceDirective: resolvedMarkoRunTypes } = ts2.resolveTypeReferenceDirective(
1304
+ "@marko/run",
1305
+ resolveFromFile,
1306
+ compilerOptions,
1294
1307
  host
1295
1308
  );
1296
- const markoTypesFile = (resolvedTypeReferenceDirective == null ? void 0 : resolvedTypeReferenceDirective.resolvedFileName) || defaultMarkoTypesFile;
1309
+ const markoTypesFile = (resolvedMarkoTypes == null ? void 0 : resolvedMarkoTypes.resolvedFileName) || defaultMarkoTypesFile;
1310
+ const markoRunTypesFile = resolvedMarkoRunTypes == null ? void 0 : resolvedMarkoRunTypes.resolvedFileName;
1297
1311
  cached = {
1298
1312
  internalTypesFile,
1299
1313
  markoTypesFile,
1300
- markoTypesCode: host.readFile(markoTypesFile, "utf-8") || ""
1314
+ markoTypesCode: host.readFile(markoTypesFile, "utf-8") || "",
1315
+ markoRunTypesFile,
1316
+ markoRunGeneratedTypesFile: host.fileExists(markoRunGeneratedTypesFile) ? markoRunGeneratedTypesFile : void 0
1301
1317
  };
1302
1318
  project.cache.set(getProjectTypeLibs, cached);
1303
1319
  }
@@ -1328,24 +1344,29 @@ function getScriptLang(filename, ts2, host, projectScriptLang) {
1328
1344
  }
1329
1345
 
1330
1346
  // src/utils/get-component-filename.ts
1331
- import path7 from "path";
1332
- function getComponentFilename(from, host) {
1333
- const dir = path7.dirname(from);
1334
- const nameNoExt = path7.basename(from, ".marko");
1347
+ import fs5 from "fs";
1348
+ import path8 from "path";
1349
+ function getComponentFilename(from) {
1350
+ const dir = path8.dirname(from);
1351
+ const nameNoExt = path8.basename(from, ".marko");
1335
1352
  const isEntry = nameNoExt === "index";
1336
- const componentFull = path7.join(dir, `${nameNoExt}.component.`);
1337
- const componentBrowserFull = path7.join(
1338
- dir,
1339
- `${nameNoExt}.component-browser.`
1340
- );
1341
- const componentPartial = isEntry ? path7.join(dir, "component.") : void 0;
1342
- const componentBrowserPartial = isEntry ? path7.join(dir, "component-browser.") : void 0;
1343
- for (const entry of host.readDirectory(dir)) {
1353
+ const componentFull = `${nameNoExt}.component.`;
1354
+ const componentBrowserFull = `${nameNoExt}.component-browser.`;
1355
+ const componentPartial = isEntry ? "component." : void 0;
1356
+ const componentBrowserPartial = isEntry ? "component-browser." : void 0;
1357
+ for (const entry of tryReaddirSync(dir)) {
1344
1358
  if (entry !== from && (isEntry && entry.startsWith(componentBrowserPartial) || entry.startsWith(componentPartial)) || entry.startsWith(componentBrowserFull) || entry.startsWith(componentFull)) {
1345
- return entry;
1359
+ return path8.join(dir, entry);
1346
1360
  }
1347
1361
  }
1348
1362
  }
1363
+ function tryReaddirSync(dir) {
1364
+ try {
1365
+ return fs5.readdirSync(dir);
1366
+ } catch {
1367
+ return [];
1368
+ }
1369
+ }
1349
1370
 
1350
1371
  // src/ts-plugin/host.ts
1351
1372
  var markoExt = ".marko";
@@ -1354,19 +1375,27 @@ var modulePartsReg = /^((?:@(?:[^/]+)\/)?(?:[^/]+))(.*)$/;
1354
1375
  var fsPathReg = /^(?:[./\\]|[A-Z]:)/i;
1355
1376
  function patch(ts2, scriptLang, cache, host) {
1356
1377
  var _a, _b, _c;
1378
+ const rootDir = host.getCurrentDirectory();
1357
1379
  const projectTypeLibs = getProjectTypeLibs(
1358
- getMarkoProject(host.getCurrentDirectory()),
1380
+ rootDir,
1381
+ getMarkoProject(rootDir),
1359
1382
  ts2,
1360
1383
  host
1361
1384
  );
1385
+ const projectTypeLibsFiles = [
1386
+ projectTypeLibs.internalTypesFile,
1387
+ projectTypeLibs.markoTypesFile
1388
+ ];
1389
+ if (projectTypeLibs.markoRunTypesFile) {
1390
+ projectTypeLibsFiles.push(projectTypeLibs.markoRunTypesFile);
1391
+ }
1392
+ if (projectTypeLibs.markoRunGeneratedTypesFile) {
1393
+ projectTypeLibsFiles.push(projectTypeLibs.markoRunGeneratedTypesFile);
1394
+ }
1362
1395
  const isMarkoTSFile = (fileName) => getScriptLang(fileName, ts2, host, scriptLang) === ScriptLang2.ts;
1363
1396
  const getScriptFileNames = host.getScriptFileNames.bind(host);
1364
1397
  host.getScriptFileNames = () => [
1365
- .../* @__PURE__ */ new Set([
1366
- ...getScriptFileNames(),
1367
- projectTypeLibs.internalTypesFile,
1368
- projectTypeLibs.markoTypesFile
1369
- ])
1398
+ ...new Set(projectTypeLibsFiles.concat(getScriptFileNames()))
1370
1399
  ];
1371
1400
  const getScriptKind = (_a = host.getScriptKind) == null ? void 0 : _a.bind(host);
1372
1401
  if (getScriptKind) {
@@ -1380,27 +1409,41 @@ function patch(ts2, scriptLang, cache, host) {
1380
1409
  let cached = cache.get(filename);
1381
1410
  if (!cached) {
1382
1411
  const code = host.readFile(filename, "utf-8") || "";
1383
- const markoProject = getMarkoProject(path8.dirname(filename));
1384
- cached = extractScript({
1385
- ts: ts2,
1386
- parsed: parse2(code, filename),
1387
- lookup: markoProject.lookup,
1388
- scriptLang: getScriptLang(filename, ts2, host, scriptLang),
1389
- runtimeTypesCode: projectTypeLibs.markoTypesCode,
1390
- componentFilename: getComponentFilename(filename, host)
1391
- });
1392
- cached.snapshot = ts2.ScriptSnapshot.fromString(cached.toString());
1412
+ const dir = path9.dirname(filename);
1413
+ try {
1414
+ const markoProject = getMarkoProject(dir);
1415
+ cached = extractScript({
1416
+ ts: ts2,
1417
+ parsed: parse2(code, filename),
1418
+ lookup: markoProject.getLookup(dir),
1419
+ scriptLang: getScriptLang(filename, ts2, host, scriptLang),
1420
+ runtimeTypesCode: projectTypeLibs.markoTypesCode,
1421
+ componentFilename: getComponentFilename(filename)
1422
+ });
1423
+ cached.snapshot = ts2.ScriptSnapshot.fromString(cached.toString());
1424
+ } catch {
1425
+ cached = { snapshot: ts2.ScriptSnapshot.fromString("") };
1426
+ }
1393
1427
  cache.set(filename, cached);
1394
1428
  }
1395
1429
  return cached.snapshot;
1396
1430
  }
1397
1431
  return getScriptSnapshot(filename);
1398
1432
  };
1433
+ if (host.getProjectVersion) {
1434
+ const getScriptVersion = host.getScriptVersion.bind(host);
1435
+ host.getScriptVersion = (filename) => {
1436
+ if (markoExtReg.test(filename)) {
1437
+ return host.getProjectVersion();
1438
+ }
1439
+ return getScriptVersion(filename);
1440
+ };
1441
+ }
1399
1442
  const readDirectory2 = (_b = host.readDirectory) == null ? void 0 : _b.bind(host);
1400
1443
  if (readDirectory2) {
1401
- host.readDirectory = (path10, extensions, exclude, include, depth) => {
1444
+ host.readDirectory = (path11, extensions, exclude, include, depth) => {
1402
1445
  return readDirectory2(
1403
- path10,
1446
+ path11,
1404
1447
  extensions == null ? void 0 : extensions.concat(markoExt),
1405
1448
  exclude,
1406
1449
  include,
@@ -1411,31 +1454,16 @@ function patch(ts2, scriptLang, cache, host) {
1411
1454
  const resolveModuleNames = (_c = host.resolveModuleNames) == null ? void 0 : _c.bind(host);
1412
1455
  if (resolveModuleNames) {
1413
1456
  host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, sourceFile) => {
1414
- const resolvedModules = resolveModuleNames(
1415
- moduleNames,
1416
- containingFile,
1417
- reusedNames,
1418
- redirectedReference,
1419
- options,
1420
- sourceFile
1421
- );
1422
- for (let i = resolvedModules.length; i--; ) {
1457
+ let normalModuleNames = moduleNames;
1458
+ let resolvedModules;
1459
+ for (let i = 0; i < moduleNames.length; i++) {
1423
1460
  const moduleName = moduleNames[i];
1424
- if (!resolvedModules[i] && markoExtReg.test(moduleName)) {
1461
+ const shouldProcess = moduleName[0] !== "*" ? markoExtReg.test(moduleName) : void 0;
1462
+ if (shouldProcess) {
1463
+ let resolvedFileName;
1425
1464
  if (fsPathReg.test(moduleName)) {
1426
- const resolvedFileName = path8.resolve(
1427
- containingFile,
1428
- "..",
1429
- moduleName
1430
- );
1431
- if (host.fileExists(resolvedFileName)) {
1432
- resolvedModules[i] = {
1433
- resolvedFileName,
1434
- extension: isMarkoTSFile(resolvedFileName) ? ts2.Extension.Ts : ts2.Extension.Js,
1435
- isExternalLibraryImport: false
1436
- };
1437
- }
1438
- } else if (moduleName[0] !== "*") {
1465
+ resolvedFileName = path9.resolve(containingFile, "..", moduleName);
1466
+ } else {
1439
1467
  const [, nodeModuleName, relativeModulePath] = modulePartsReg.exec(moduleName);
1440
1468
  const { resolvedModule } = ts2.resolveModuleName(
1441
1469
  `${nodeModuleName}/package.json`,
@@ -1444,31 +1472,70 @@ function patch(ts2, scriptLang, cache, host) {
1444
1472
  host
1445
1473
  );
1446
1474
  if (resolvedModule) {
1447
- const resolvedFileName = path8.join(
1475
+ resolvedFileName = path9.join(
1448
1476
  resolvedModule.resolvedFileName,
1449
1477
  "..",
1450
1478
  relativeModulePath
1451
1479
  );
1452
- if (host.fileExists(resolvedFileName)) {
1453
- const isTS = isMarkoTSFile(resolvedFileName);
1454
- resolvedModules[i] = {
1455
- resolvedFileName,
1456
- extension: isTS ? ts2.Extension.Ts : ts2.Extension.Js,
1457
- isExternalLibraryImport: isTS
1458
- };
1459
- }
1480
+ }
1481
+ }
1482
+ if (!resolvedModules) {
1483
+ resolvedModules = [];
1484
+ normalModuleNames = [];
1485
+ for (let j = 0; j < i; j++) {
1486
+ resolvedModules.push(void 0);
1487
+ normalModuleNames.push(moduleNames[j]);
1488
+ }
1489
+ }
1490
+ resolvedModules.push(
1491
+ resolvedFileName && host.fileExists(resolvedFileName) ? {
1492
+ resolvedFileName,
1493
+ extension: isMarkoTSFile(resolvedFileName) ? ts2.Extension.Ts : ts2.Extension.Js,
1494
+ isExternalLibraryImport: false
1495
+ } : null
1496
+ );
1497
+ } else if (resolvedModules) {
1498
+ resolvedModules.push(void 0);
1499
+ }
1500
+ }
1501
+ const normalResolvedModules = normalModuleNames.length ? resolveModuleNames(
1502
+ normalModuleNames,
1503
+ containingFile,
1504
+ reusedNames,
1505
+ redirectedReference,
1506
+ options,
1507
+ sourceFile
1508
+ ) : void 0;
1509
+ if (resolvedModules) {
1510
+ if (normalResolvedModules) {
1511
+ for (let i = 0, j = 0; i < resolvedModules.length; i++) {
1512
+ switch (resolvedModules[i]) {
1513
+ case void 0:
1514
+ resolvedModules[i] = normalResolvedModules[j++];
1515
+ break;
1516
+ case null:
1517
+ resolvedModules[i] = void 0;
1518
+ break;
1519
+ }
1520
+ }
1521
+ } else {
1522
+ for (let i = resolvedModules.length; i--; ) {
1523
+ if (resolvedModules[i] === null) {
1524
+ resolvedModules[i] = void 0;
1460
1525
  }
1461
1526
  }
1462
1527
  }
1528
+ return resolvedModules;
1529
+ } else {
1530
+ return normalResolvedModules;
1463
1531
  }
1464
- return resolvedModules;
1465
1532
  };
1466
1533
  }
1467
1534
  return host;
1468
1535
  }
1469
1536
 
1470
1537
  // src/service/script/index.ts
1471
- var IGNORE_DIAG_REG = /^(?:Expression|Identifier|['"][^\w]['"]) expected.$/;
1538
+ var IGNORE_DIAG_REG = /^(?:(?:Expression|Identifier|['"][^\w]['"]) expected|Invalid character)\b/i;
1472
1539
  var extractCache = /* @__PURE__ */ new Map();
1473
1540
  var snapshotCache = /* @__PURE__ */ new Map();
1474
1541
  var insertModuleStatementLocCache = /* @__PURE__ */ new WeakMap();
@@ -1478,6 +1545,34 @@ var optionalModifierReg = /\boptional\b/;
1478
1545
  var deprecatedModifierReg = /\bdeprecated\b/;
1479
1546
  var colorModifierReg = /\bcolor\b/;
1480
1547
  var localInternalsPrefix = "__marko_internal_";
1548
+ var requiredTSCompilerOptions = {
1549
+ module: ts.ModuleKind.ESNext,
1550
+ moduleResolution: ts.ModuleResolutionKind.NodeJs,
1551
+ noEmit: true,
1552
+ allowJs: true,
1553
+ composite: false,
1554
+ declaration: false,
1555
+ skipLibCheck: true,
1556
+ isolatedModules: true,
1557
+ resolveJsonModule: true,
1558
+ skipDefaultLibCheck: true,
1559
+ emitDeclarationOnly: false,
1560
+ allowNonTsExtensions: true,
1561
+ emitDecoratorMetadata: false
1562
+ };
1563
+ var defaultTSConfig = {
1564
+ include: [],
1565
+ compilerOptions: {
1566
+ lib: ["dom", "node", "esnext"]
1567
+ }
1568
+ };
1569
+ var extraTSCompilerExtensions = [
1570
+ {
1571
+ extension: ".marko",
1572
+ isMixedContent: false,
1573
+ scriptKind: ts.ScriptKind.Deferred
1574
+ }
1575
+ ];
1481
1576
  var ScriptService = {
1482
1577
  commands: {
1483
1578
  "$/showScriptOutput": async (uri) => {
@@ -1562,7 +1657,7 @@ var ScriptService = {
1562
1657
  let source = completion.source;
1563
1658
  if (source && completion.hasAction) {
1564
1659
  if (source[0] === ".") {
1565
- source = path9.resolve(fileName, "..", source);
1660
+ source = path10.resolve(fileName, "..", source);
1566
1661
  }
1567
1662
  detail = relativeImportPath(fileName, source);
1568
1663
  sortText = `\uFFFF${sortText}`;
@@ -1866,19 +1961,26 @@ ${documentation}`;
1866
1961
  }
1867
1962
  };
1868
1963
  function processScript(doc, tsProject) {
1869
- return processDoc(doc, ({ parsed, filename, project: markoProject }) => {
1870
- var _a;
1871
- const { lookup } = markoProject;
1872
- const { host, markoScriptLang } = tsProject;
1873
- return extractScript2({
1874
- ts,
1875
- parsed,
1876
- lookup,
1877
- scriptLang: getScriptLang(filename, ts, host, markoScriptLang),
1878
- runtimeTypesCode: (_a = getProjectTypeLibs(markoProject, ts, host)) == null ? void 0 : _a.markoTypesCode,
1879
- componentFilename: getComponentFilename(filename, host)
1880
- });
1881
- });
1964
+ return processDoc(
1965
+ doc,
1966
+ ({ filename, parsed, lookup, project: markoProject }) => {
1967
+ var _a;
1968
+ const { host, markoScriptLang } = tsProject;
1969
+ return extractScript2({
1970
+ ts,
1971
+ parsed,
1972
+ lookup,
1973
+ scriptLang: getScriptLang(filename, ts, host, markoScriptLang),
1974
+ runtimeTypesCode: (_a = getProjectTypeLibs(
1975
+ tsProject.rootDir,
1976
+ markoProject,
1977
+ ts,
1978
+ host
1979
+ )) == null ? void 0 : _a.markoTypesCode,
1980
+ componentFilename: getComponentFilename(filename)
1981
+ });
1982
+ }
1983
+ );
1882
1984
  }
1883
1985
  function getInsertModuleStatementOffset(parsed) {
1884
1986
  const { program } = parsed;
@@ -1947,7 +2049,7 @@ function getTSProject(docFsPath) {
1947
2049
  );
1948
2050
  }
1949
2051
  }
1950
- const rootDir = configPath && path9.dirname(configPath) || process.cwd();
2052
+ const rootDir = configPath && path10.dirname(configPath) || process.cwd();
1951
2053
  const markoProject = getMarkoProject(configPath && rootDir);
1952
2054
  let projectCache = markoProject.cache.get(getTSProject);
1953
2055
  let cached;
@@ -1960,32 +2062,21 @@ function getTSProject(docFsPath) {
1960
2062
  markoProject.cache.set(getTSProject, projectCache);
1961
2063
  }
1962
2064
  const { fileNames, options, projectReferences } = ts.parseJsonConfigFileContent(
1963
- configPath && ts.readConfigFile(configPath, ts.sys.readFile).config || {
1964
- compilerOptions: { lib: ["dom", "node", "esnext"] }
1965
- },
2065
+ configPath && ts.readConfigFile(configPath, ts.sys.readFile).config || defaultTSConfig,
1966
2066
  ts.sys,
1967
2067
  rootDir,
1968
- void 0,
2068
+ requiredTSCompilerOptions,
1969
2069
  configPath,
1970
2070
  void 0,
1971
- [
1972
- {
1973
- extension: ".marko",
1974
- isMixedContent: false,
1975
- scriptKind: ts.ScriptKind.Deferred
1976
- }
1977
- ]
2071
+ extraTSCompilerExtensions
1978
2072
  );
2073
+ options.rootDir ??= rootDir;
1979
2074
  const potentialGlobalFiles = new Set(
1980
2075
  fileNames.filter((file) => /\.[cm]?ts$/.test(file))
1981
2076
  );
1982
- options.rootDir ??= rootDir;
1983
- options.module = ts.ModuleKind.ESNext;
1984
- options.moduleResolution = ts.ModuleResolutionKind.NodeJs;
1985
- options.noEmit = options.allowJs = options.declaration = options.skipLibCheck = options.isolatedModules = options.resolveJsonModule = options.skipDefaultLibCheck = options.allowNonTsExtensions = true;
1986
2077
  const tsPkgFile = configPath && ((_a = ts.resolveModuleName("typescript/package.json", configPath, options, ts.sys).resolvedModule) == null ? void 0 : _a.resolvedFileName);
1987
- const defaultLibFile = path9.join(
1988
- tsPkgFile ? path9.join(tsPkgFile, "../lib") : __dirname,
2078
+ const defaultLibFile = path10.join(
2079
+ tsPkgFile ? path10.join(tsPkgFile, "../lib") : __dirname,
1989
2080
  ts.getDefaultLibFileName(options)
1990
2081
  );
1991
2082
  const host = patch(
@@ -2039,12 +2130,16 @@ function getTSProject(docFsPath) {
2039
2130
  return `${((_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.version) ?? -1}`;
2040
2131
  },
2041
2132
  getScriptKind(filename) {
2042
- switch (path9.extname(filename)) {
2133
+ switch (path10.extname(filename)) {
2043
2134
  case ts.Extension.Js:
2135
+ case ts.Extension.Cjs:
2136
+ case ts.Extension.Mjs:
2044
2137
  return ts.ScriptKind.JS;
2045
2138
  case ts.Extension.Jsx:
2046
2139
  return ts.ScriptKind.JSX;
2047
2140
  case ts.Extension.Ts:
2141
+ case ts.Extension.Cts:
2142
+ case ts.Extension.Mts:
2048
2143
  return ts.ScriptKind.TS;
2049
2144
  case ts.Extension.Tsx:
2050
2145
  return ts.ScriptKind.TSX;
@@ -2073,7 +2168,12 @@ function getTSProject(docFsPath) {
2073
2168
  service: ts.createLanguageService(host),
2074
2169
  markoProject,
2075
2170
  markoScriptLang,
2076
- markoProjectTypeLibs: getProjectTypeLibs(markoProject, ts, host)
2171
+ markoProjectTypeLibs: getProjectTypeLibs(
2172
+ options.rootDir,
2173
+ markoProject,
2174
+ ts,
2175
+ host
2176
+ )
2077
2177
  };
2078
2178
  projectCache.set(rootDir, tsProject);
2079
2179
  return tsProject;
@@ -2546,7 +2646,7 @@ var StyleSheetService = {
2546
2646
  }
2547
2647
  };
2548
2648
  function processStyle(doc) {
2549
- return processDoc(doc, ({ uri, version, parsed, project: { lookup } }) => {
2649
+ return processDoc(doc, ({ uri, version, parsed, lookup }) => {
2550
2650
  var _a;
2551
2651
  const result = [];
2552
2652
  for (const [ext, extracted] of extractStyle({
@@ -3024,7 +3124,7 @@ setup(connection3);
3024
3124
  onFileChange((changeDoc) => {
3025
3125
  if (changeDoc) {
3026
3126
  queueDiagnostic();
3027
- getMarkoProject(getFSDir(changeDoc)).cache.delete(changeDoc);
3127
+ clearMarkoCacheForFile(changeDoc);
3028
3128
  } else {
3029
3129
  validateDocs();
3030
3130
  }
@@ -3121,10 +3221,7 @@ for (const command in service.commands) {
3121
3221
  }
3122
3222
  function validateDocs() {
3123
3223
  queueDiagnostic();
3124
- for (const project of getMarkoProjects()) {
3125
- project.cache.clear();
3126
- project.compiler.taglib.clearCaches();
3127
- }
3224
+ clearMarkoProjectCaches();
3128
3225
  }
3129
3226
  function queueDiagnostic() {
3130
3227
  clearTimeout(diagnosticTimeout);