@marko/language-server 1.0.0 → 1.0.2

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.js CHANGED
@@ -27,17 +27,31 @@ var import_util2 = require("util");
27
27
  var import_node = require("vscode-languageserver/node");
28
28
 
29
29
  // src/utils/project.ts
30
+ var import_path = __toESM(require("path"));
30
31
  var defaultCompiler = __toESM(require("@marko/compiler"));
31
32
  var defaultTranslator = __toESM(require("@marko/translator-default"));
32
- var import_lasso_package_root = __toESM(require("lasso-package-root"));
33
33
  var import_resolve_from = __toESM(require("resolve-from"));
34
- var cwd = process.cwd();
35
- var kTaglib = Symbol("taglib");
34
+ var ignoreErrors = (_err) => {
35
+ };
36
36
  var projectsByDir = /* @__PURE__ */ new Map();
37
+ var projectsByCompiler = /* @__PURE__ */ new Map();
37
38
  var defaultProject = {
38
- rootDir: cwd,
39
39
  cache: /* @__PURE__ */ new Map(),
40
- lookup: defaultCompiler.taglib.buildLookup(cwd, defaultTranslator),
40
+ getLookup(dir) {
41
+ const key = `taglib:${dir}`;
42
+ let lookup = defaultProject.cache.get(key);
43
+ if (!lookup) {
44
+ defaultProject.cache.set(
45
+ key,
46
+ lookup = defaultCompiler.taglib.buildLookup(
47
+ dir,
48
+ defaultTranslator,
49
+ ignoreErrors
50
+ )
51
+ );
52
+ }
53
+ return lookup;
54
+ },
41
55
  compiler: defaultCompiler,
42
56
  translator: defaultTranslator
43
57
  };
@@ -53,55 +67,119 @@ function getMarkoProject(dir) {
53
67
  return project;
54
68
  }
55
69
  function getMarkoProjects() {
56
- return new Set(projectsByDir.values());
70
+ return projectsByCompiler.values();
71
+ }
72
+ function clearMarkoProjectCaches() {
73
+ for (const project of getMarkoProjects()) {
74
+ project.cache.clear();
75
+ project.compiler.taglib.clearCaches();
76
+ }
57
77
  }
58
78
  function loadProject(dir) {
59
- const rootDir = import_lasso_package_root.default.getRootDir(dir) || cwd;
60
- const pkgPath = import_resolve_from.default.silent(rootDir, "@marko/compiler/package.json");
61
- const pkg = pkgPath && require(pkgPath);
62
- const cache = /* @__PURE__ */ new Map();
63
- let translator = defaultTranslator;
64
- let compiler = defaultCompiler;
65
- if (pkg && /^5\./.test(pkg.version)) {
66
- try {
67
- let checkTranslator = [].concat(
68
- Object.keys(pkg.dependencies),
69
- Object.keys(pkg.peerDependencies),
70
- Object.keys(pkg.devDependencies)
71
- ).find((name) => /^marko$|^(@\/marko\/|marko-)translator-/.test(name));
72
- if (checkTranslator === "marko" || !checkTranslator) {
73
- checkTranslator = require((0, import_resolve_from.default)(dir, "@marko/compiler/config")).translator;
79
+ try {
80
+ const compilerConfigPath = (0, import_resolve_from.default)(dir, "@marko/compiler/config");
81
+ const cachedProject = projectsByCompiler.get(compilerConfigPath);
82
+ if (cachedProject)
83
+ return cachedProject;
84
+ const [compiler, translator] = [
85
+ require(import_path.default.join(compilerConfigPath, "..")),
86
+ require((0, import_resolve_from.default)(
87
+ dir,
88
+ interopDefault(require(compilerConfigPath)).translator
89
+ ))
90
+ ];
91
+ const project = {
92
+ cache: /* @__PURE__ */ new Map(),
93
+ getLookup(dir2) {
94
+ const key = `taglib:${dir2}`;
95
+ let lookup = project.cache.get(key);
96
+ if (lookup === void 0) {
97
+ try {
98
+ lookup = compiler.taglib.buildLookup(dir2, translator, ignoreErrors);
99
+ } catch {
100
+ lookup = defaultProject.getLookup(dir2);
101
+ }
102
+ project.cache.set(key, lookup);
103
+ }
104
+ return lookup;
105
+ },
106
+ compiler,
107
+ translator
108
+ };
109
+ projectsByCompiler.set(compilerConfigPath, project);
110
+ return project;
111
+ } catch {
112
+ return defaultProject;
113
+ }
114
+ }
115
+ function interopDefault(mod) {
116
+ return mod.default || mod;
117
+ }
118
+
119
+ // src/utils/file.ts
120
+ var import_path2 = __toESM(require("path"));
121
+ var import_language_tools = require("@marko/language-tools");
122
+ var import_vscode_uri = require("vscode-uri");
123
+ var processorCaches = /* @__PURE__ */ new WeakMap();
124
+ function getFSPath(doc) {
125
+ return import_vscode_uri.URI.parse(doc.uri).fsPath;
126
+ }
127
+ function getMarkoFile(doc) {
128
+ const { uri } = doc;
129
+ const { fsPath: filename, scheme } = import_vscode_uri.URI.parse(uri);
130
+ const dirname = filename && import_path2.default.dirname(filename);
131
+ const project = getMarkoProject(dirname);
132
+ const cache = project.cache;
133
+ let file = cache.get(doc);
134
+ if (!file) {
135
+ const { version } = doc;
136
+ const code = doc.getText();
137
+ const parsed = (0, import_language_tools.parse)(code, filename);
138
+ const lookup = project.getLookup(dirname);
139
+ cache.set(
140
+ doc,
141
+ file = {
142
+ project,
143
+ uri,
144
+ scheme,
145
+ version,
146
+ lookup,
147
+ filename,
148
+ dirname,
149
+ parsed,
150
+ code
74
151
  }
75
- [compiler, translator] = [
76
- require((0, import_resolve_from.default)(dir, "@marko/compiler")),
77
- require((0, import_resolve_from.default)(dir, checkTranslator))
78
- ];
79
- } catch {
152
+ );
153
+ }
154
+ return file;
155
+ }
156
+ function clearMarkoCacheForFile(doc) {
157
+ const { fsPath: filename } = import_vscode_uri.URI.parse(doc.uri);
158
+ const dirname = filename && import_path2.default.dirname(filename);
159
+ const project = getMarkoProject(dirname);
160
+ const cache = project.cache;
161
+ cache.delete(doc);
162
+ }
163
+ function processDoc(doc, process2) {
164
+ const file = getMarkoFile(doc);
165
+ const cache = processorCaches.get(file.parsed);
166
+ let result;
167
+ if (cache) {
168
+ result = cache.get(process2);
169
+ if (!result) {
170
+ result = process2(file);
171
+ cache.set(process2, result);
80
172
  }
173
+ } else {
174
+ result = process2(file);
175
+ processorCaches.set(file.parsed, /* @__PURE__ */ new Map([[process2, result]]));
81
176
  }
82
- return {
83
- rootDir,
84
- cache,
85
- get lookup() {
86
- let lookup = cache.get(kTaglib);
87
- if (lookup === void 0) {
88
- try {
89
- lookup = compiler.taglib.buildLookup(dir, translator);
90
- } catch {
91
- lookup = defaultProject.lookup;
92
- }
93
- cache.set(kTaglib, lookup);
94
- }
95
- return lookup;
96
- },
97
- compiler,
98
- translator
99
- };
177
+ return result;
100
178
  }
101
179
 
102
180
  // src/utils/text-documents.ts
103
181
  var import_fs = __toESM(require("fs"));
104
- var import_vscode_uri = require("vscode-uri");
182
+ var import_vscode_uri2 = require("vscode-uri");
105
183
  var import_vscode_languageserver = require("vscode-languageserver");
106
184
  var import_vscode_languageserver_textdocument = require("vscode-languageserver-textdocument");
107
185
  var docs = /* @__PURE__ */ new Map();
@@ -119,7 +197,7 @@ function get(uri) {
119
197
  const doc = docs.get(uri);
120
198
  if (doc)
121
199
  return doc;
122
- const { fsPath, scheme } = import_vscode_uri.URI.parse(uri);
200
+ const { fsPath, scheme } = import_vscode_uri2.URI.parse(uri);
123
201
  if (scheme === "file") {
124
202
  if (fileExists.get(uri) === false)
125
203
  return void 0;
@@ -142,7 +220,7 @@ function exists(uri) {
142
220
  const cached = fileExists.get(uri);
143
221
  if (cached !== void 0)
144
222
  return cached;
145
- const { fsPath, scheme } = import_vscode_uri.URI.parse(uri);
223
+ const { fsPath, scheme } = import_vscode_uri2.URI.parse(uri);
146
224
  if (scheme === "file") {
147
225
  try {
148
226
  import_fs.default.accessSync(fsPath);
@@ -196,7 +274,7 @@ function setup(connection4) {
196
274
  if (doc) {
197
275
  projectVersion++;
198
276
  openDocs.delete(doc);
199
- if (import_vscode_uri.URI.parse(ref.uri).scheme !== "file") {
277
+ if (import_vscode_uri2.URI.parse(ref.uri).scheme !== "file") {
200
278
  docs.delete(ref.uri);
201
279
  }
202
280
  }
@@ -299,62 +377,6 @@ function display(type, data) {
299
377
  setImmediate(() => connection2.sendNotification(type, msg));
300
378
  }
301
379
 
302
- // src/utils/file.ts
303
- var import_path = __toESM(require("path"));
304
- var import_language_tools = require("@marko/language-tools");
305
- var import_vscode_uri2 = require("vscode-uri");
306
- var processorCaches = /* @__PURE__ */ new WeakMap();
307
- function getFSDir(doc) {
308
- const filename = getFSPath(doc);
309
- return filename ? import_path.default.dirname(filename) : void 0;
310
- }
311
- function getFSPath(doc) {
312
- return import_vscode_uri2.URI.parse(doc.uri).fsPath;
313
- }
314
- function getMarkoFile(doc) {
315
- const { uri } = doc;
316
- const { fsPath: filename, scheme } = import_vscode_uri2.URI.parse(uri);
317
- const dirname = filename && import_path.default.dirname(filename);
318
- const project = getMarkoProject(dirname);
319
- const cache = project.cache;
320
- let file = cache.get(doc);
321
- if (!file) {
322
- const { version } = doc;
323
- const code = doc.getText();
324
- const parsed = (0, import_language_tools.parse)(code, filename);
325
- cache.set(
326
- doc,
327
- file = {
328
- project,
329
- uri,
330
- scheme,
331
- version,
332
- filename,
333
- dirname,
334
- parsed,
335
- code
336
- }
337
- );
338
- }
339
- return file;
340
- }
341
- function processDoc(doc, process2) {
342
- const file = getMarkoFile(doc);
343
- const cache = processorCaches.get(file.parsed);
344
- let result;
345
- if (cache) {
346
- result = cache.get(process2);
347
- if (!result) {
348
- result = process2(file);
349
- cache.set(process2, result);
350
- }
351
- } else {
352
- result = process2(file);
353
- processorCaches.set(file.parsed, /* @__PURE__ */ new Map([[process2, result]]));
354
- }
355
- return result;
356
- }
357
-
358
380
  // src/service/index.ts
359
381
  var import_vscode_languageserver12 = require("vscode-languageserver");
360
382
 
@@ -366,10 +388,7 @@ var import_vscode_languageserver2 = require("vscode-languageserver");
366
388
  function AttrName({
367
389
  offset,
368
390
  node,
369
- file: {
370
- parsed,
371
- project: { lookup }
372
- }
391
+ file: { parsed, lookup }
373
392
  }) {
374
393
  let name = parsed.read(node);
375
394
  const modifierIndex = name.indexOf(":");
@@ -466,7 +485,7 @@ function isExternalModule(file) {
466
485
  }
467
486
 
468
487
  // src/service/marko/complete/AttrValue.ts
469
- var import_path2 = __toESM(require("path"));
488
+ var import_path3 = __toESM(require("path"));
470
489
  var import_vscode_languageserver3 = require("vscode-languageserver");
471
490
 
472
491
  // src/service/marko/util/is-document-link-attr.ts
@@ -576,7 +595,7 @@ async function AttrValue({
576
595
  const resolved = resolveUrl(req, uri);
577
596
  if (resolved) {
578
597
  const result = [];
579
- const curFile = req === "." ? import_path2.default.basename(uri) : void 0;
598
+ const curFile = req === "." ? import_path3.default.basename(uri) : void 0;
580
599
  const replaceRange = parsed.locationAt({
581
600
  start: start + segmentStart + 1,
582
601
  end: start + rawValue.length
@@ -609,7 +628,7 @@ async function AttrValue({
609
628
  var import_vscode_languageserver5 = require("vscode-languageserver");
610
629
 
611
630
  // src/service/marko/util/get-tag-name-completion.ts
612
- var import_path3 = __toESM(require("path"));
631
+ var import_path4 = __toESM(require("path"));
613
632
  var import_vscode_languageserver4 = require("vscode-languageserver");
614
633
  var import_vscode_uri3 = require("vscode-uri");
615
634
  var deprecated = [import_vscode_languageserver4.CompletionItemTag.Deprecated];
@@ -632,7 +651,7 @@ function getTagNameCompletion({
632
651
  kind: import_vscode_languageserver4.MarkupKind.Markdown,
633
652
  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:
634
653
 
635
- [${importer ? import_path3.default.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
654
+ [${importer ? import_path4.default.relative(importer, fileForTag) : fileForTag}](${fileURIForTag})`
636
655
  };
637
656
  if (tag.description) {
638
657
  documentation.value += `
@@ -669,11 +688,7 @@ ${autocomplete.description}`;
669
688
  var importTagReg = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/;
670
689
  function Import({
671
690
  node,
672
- file: {
673
- parsed,
674
- filename,
675
- project: { lookup }
676
- }
691
+ file: { parsed, filename, lookup }
677
692
  }) {
678
693
  var _a;
679
694
  const value = parsed.read(node);
@@ -705,11 +720,7 @@ function Import({
705
720
  var import_language_tools3 = require("@marko/language-tools");
706
721
  function OpenTagName({
707
722
  node,
708
- file: {
709
- parsed,
710
- filename,
711
- project: { lookup }
712
- }
723
+ file: { parsed, filename, lookup }
713
724
  }) {
714
725
  var _a;
715
726
  const tag = node.parent;
@@ -826,14 +837,14 @@ var doComplete = async (doc, params) => {
826
837
  };
827
838
 
828
839
  // src/service/marko/validate.ts
829
- var import_path4 = __toESM(require("path"));
840
+ var import_path5 = __toESM(require("path"));
830
841
  var import_vscode_languageserver7 = require("vscode-languageserver");
831
842
  var markoErrorRegExp = /^(.+?)\.marko(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
832
843
  var doValidate = (doc) => {
833
844
  const filename = getFSPath(doc);
834
845
  const diagnostics = [];
835
846
  const { compiler, translator, cache } = getMarkoProject(
836
- filename && import_path4.default.dirname(filename)
847
+ filename && import_path5.default.dirname(filename)
837
848
  );
838
849
  try {
839
850
  compiler.compileSync(doc.getText(), filename || "untitled.marko", {
@@ -889,11 +900,7 @@ var START_LOCATION = {
889
900
  // src/service/marko/hover/OpenTagName.ts
890
901
  function OpenTagName2({
891
902
  node,
892
- file: {
893
- parsed,
894
- filename,
895
- project: { lookup }
896
- }
903
+ file: { parsed, filename, lookup }
897
904
  }) {
898
905
  const tag = node.parent;
899
906
  const range = parsed.locationAt(node);
@@ -965,10 +972,7 @@ function escape(val) {
965
972
  // src/service/marko/definition/AttrName.ts
966
973
  function AttrName2({
967
974
  node,
968
- file: {
969
- parsed,
970
- project: { lookup }
971
- }
975
+ file: { parsed, lookup }
972
976
  }) {
973
977
  const tagName = node.parent.parent.nameText;
974
978
  const attrName = parsed.read(node);
@@ -1007,15 +1011,12 @@ function AttrName2({
1007
1011
 
1008
1012
  // src/service/marko/definition/OpenTagName.ts
1009
1013
  var import_fs3 = __toESM(require("fs"));
1010
- var import_path5 = __toESM(require("path"));
1014
+ var import_path6 = __toESM(require("path"));
1011
1015
  var import_vscode_uri5 = require("vscode-uri");
1012
1016
  var import_language_tools8 = require("@marko/language-tools");
1013
1017
  function OpenTagName3({
1014
1018
  node,
1015
- file: {
1016
- parsed,
1017
- project: { lookup }
1018
- }
1019
+ file: { parsed, lookup }
1019
1020
  }) {
1020
1021
  const tag = node.parent;
1021
1022
  let tagDef;
@@ -1032,7 +1033,7 @@ function OpenTagName3({
1032
1033
  return;
1033
1034
  }
1034
1035
  const tagEntryFile = tagDef.template || tagDef.renderer || tagDef.filePath;
1035
- if (!import_path5.default.isAbsolute(tagEntryFile)) {
1036
+ if (!import_path6.default.isAbsolute(tagEntryFile)) {
1036
1037
  return;
1037
1038
  }
1038
1039
  if (/\/marko(?:-tag)?\.json$/.test(tagEntryFile)) {
@@ -1087,7 +1088,7 @@ function extractDocumentLinks({
1087
1088
  scheme,
1088
1089
  parsed,
1089
1090
  code,
1090
- project: { lookup }
1091
+ lookup
1091
1092
  }) {
1092
1093
  if (scheme !== "file") {
1093
1094
  return [];
@@ -1163,7 +1164,7 @@ function extractDocumentSymbols({
1163
1164
  uri,
1164
1165
  scheme,
1165
1166
  parsed,
1166
- project: { lookup }
1167
+ lookup
1167
1168
  }) {
1168
1169
  if (scheme !== "file") {
1169
1170
  return [];
@@ -1244,7 +1245,7 @@ var marko_default = {
1244
1245
  };
1245
1246
 
1246
1247
  // src/service/script/index.ts
1247
- var import_path9 = __toESM(require("path"));
1248
+ var import_path10 = __toESM(require("path"));
1248
1249
  var import_relative_import_path = require("relative-import-path");
1249
1250
  var import_tsserverlibrary = __toESM(require("typescript/lib/tsserverlibrary"));
1250
1251
  var import_vscode_languageserver10 = require("vscode-languageserver");
@@ -1253,19 +1254,19 @@ var prettier2 = __toESM(require("prettier"));
1253
1254
  var import_language_tools14 = require("@marko/language-tools");
1254
1255
 
1255
1256
  // src/ts-plugin/host.ts
1256
- var import_path8 = __toESM(require("path"));
1257
+ var import_path9 = __toESM(require("path"));
1257
1258
  var import_language_tools13 = require("@marko/language-tools");
1258
1259
 
1259
1260
  // src/utils/get-runtime-types.ts
1260
- var import_path6 = __toESM(require("path"));
1261
- var internalTypesFile = import_path6.default.join(__dirname, "marko.internal.d.ts");
1262
- var defaultMarkoTypesFile = import_path6.default.join(__dirname, "marko.runtime.d.ts");
1261
+ var import_path7 = __toESM(require("path"));
1262
+ var internalTypesFile = import_path7.default.join(__dirname, "marko.internal.d.ts");
1263
+ var defaultMarkoTypesFile = import_path7.default.join(__dirname, "marko.runtime.d.ts");
1263
1264
  function getProjectTypeLibs(project, ts2, host) {
1264
1265
  let cached = project.cache.get(getProjectTypeLibs);
1265
1266
  if (cached === void 0) {
1266
1267
  const { resolvedTypeReferenceDirective } = ts2.resolveTypeReferenceDirective(
1267
1268
  project.translator.runtimeTypes || "marko",
1268
- import_path6.default.join(project.rootDir, "_.d.ts"),
1269
+ import_path7.default.join(host.getCurrentDirectory(), "_.d.ts"),
1269
1270
  host.getCompilationSettings(),
1270
1271
  host
1271
1272
  );
@@ -1304,21 +1305,19 @@ function getScriptLang(filename, ts2, host, projectScriptLang) {
1304
1305
  }
1305
1306
 
1306
1307
  // src/utils/get-component-filename.ts
1307
- var import_path7 = __toESM(require("path"));
1308
- function getComponentFilename(from, host) {
1309
- const dir = import_path7.default.dirname(from);
1310
- const nameNoExt = import_path7.default.basename(from, ".marko");
1308
+ var import_fs4 = __toESM(require("fs"));
1309
+ var import_path8 = __toESM(require("path"));
1310
+ function getComponentFilename(from) {
1311
+ const dir = import_path8.default.dirname(from);
1312
+ const nameNoExt = import_path8.default.basename(from, ".marko");
1311
1313
  const isEntry = nameNoExt === "index";
1312
- const componentFull = import_path7.default.join(dir, `${nameNoExt}.component.`);
1313
- const componentBrowserFull = import_path7.default.join(
1314
- dir,
1315
- `${nameNoExt}.component-browser.`
1316
- );
1317
- const componentPartial = isEntry ? import_path7.default.join(dir, "component.") : void 0;
1318
- const componentBrowserPartial = isEntry ? import_path7.default.join(dir, "component-browser.") : void 0;
1319
- for (const entry of host.readDirectory(dir)) {
1314
+ const componentFull = `${nameNoExt}.component.`;
1315
+ const componentBrowserFull = `${nameNoExt}.component-browser.`;
1316
+ const componentPartial = isEntry ? "component." : void 0;
1317
+ const componentBrowserPartial = isEntry ? "component-browser." : void 0;
1318
+ for (const entry of import_fs4.default.readdirSync(dir)) {
1320
1319
  if (entry !== from && (isEntry && entry.startsWith(componentBrowserPartial) || entry.startsWith(componentPartial)) || entry.startsWith(componentBrowserFull) || entry.startsWith(componentFull)) {
1321
- return entry;
1320
+ return import_path8.default.join(dir, entry);
1322
1321
  }
1323
1322
  }
1324
1323
  }
@@ -1356,14 +1355,15 @@ function patch(ts2, scriptLang, cache, host) {
1356
1355
  let cached = cache.get(filename);
1357
1356
  if (!cached) {
1358
1357
  const code = host.readFile(filename, "utf-8") || "";
1359
- const markoProject = getMarkoProject(import_path8.default.dirname(filename));
1358
+ const dir = import_path9.default.dirname(filename);
1359
+ const markoProject = getMarkoProject(dir);
1360
1360
  cached = (0, import_language_tools13.extractScript)({
1361
1361
  ts: ts2,
1362
1362
  parsed: (0, import_language_tools13.parse)(code, filename),
1363
- lookup: markoProject.lookup,
1363
+ lookup: markoProject.getLookup(dir),
1364
1364
  scriptLang: getScriptLang(filename, ts2, host, scriptLang),
1365
1365
  runtimeTypesCode: projectTypeLibs.markoTypesCode,
1366
- componentFilename: getComponentFilename(filename, host)
1366
+ componentFilename: getComponentFilename(filename)
1367
1367
  });
1368
1368
  cached.snapshot = ts2.ScriptSnapshot.fromString(cached.toString());
1369
1369
  cache.set(filename, cached);
@@ -1372,11 +1372,20 @@ function patch(ts2, scriptLang, cache, host) {
1372
1372
  }
1373
1373
  return getScriptSnapshot(filename);
1374
1374
  };
1375
+ if (host.getProjectVersion) {
1376
+ const getScriptVersion = host.getScriptVersion.bind(host);
1377
+ host.getScriptVersion = (filename) => {
1378
+ if (markoExtReg.test(filename)) {
1379
+ return host.getProjectVersion();
1380
+ }
1381
+ return getScriptVersion(filename);
1382
+ };
1383
+ }
1375
1384
  const readDirectory2 = (_b = host.readDirectory) == null ? void 0 : _b.bind(host);
1376
1385
  if (readDirectory2) {
1377
- host.readDirectory = (path10, extensions, exclude, include, depth) => {
1386
+ host.readDirectory = (path11, extensions, exclude, include, depth) => {
1378
1387
  return readDirectory2(
1379
- path10,
1388
+ path11,
1380
1389
  extensions == null ? void 0 : extensions.concat(markoExt),
1381
1390
  exclude,
1382
1391
  include,
@@ -1387,31 +1396,16 @@ function patch(ts2, scriptLang, cache, host) {
1387
1396
  const resolveModuleNames = (_c = host.resolveModuleNames) == null ? void 0 : _c.bind(host);
1388
1397
  if (resolveModuleNames) {
1389
1398
  host.resolveModuleNames = (moduleNames, containingFile, reusedNames, redirectedReference, options, sourceFile) => {
1390
- const resolvedModules = resolveModuleNames(
1391
- moduleNames,
1392
- containingFile,
1393
- reusedNames,
1394
- redirectedReference,
1395
- options,
1396
- sourceFile
1397
- );
1398
- for (let i = resolvedModules.length; i--; ) {
1399
+ let normalModuleNames = moduleNames;
1400
+ let resolvedModules;
1401
+ for (let i = 0; i < moduleNames.length; i++) {
1399
1402
  const moduleName = moduleNames[i];
1400
- if (!resolvedModules[i] && markoExtReg.test(moduleName)) {
1403
+ const shouldProcess = moduleName[0] !== "*" ? markoExtReg.test(moduleName) : void 0;
1404
+ if (shouldProcess) {
1405
+ let resolvedFileName;
1401
1406
  if (fsPathReg.test(moduleName)) {
1402
- const resolvedFileName = import_path8.default.resolve(
1403
- containingFile,
1404
- "..",
1405
- moduleName
1406
- );
1407
- if (host.fileExists(resolvedFileName)) {
1408
- resolvedModules[i] = {
1409
- resolvedFileName,
1410
- extension: isMarkoTSFile(resolvedFileName) ? ts2.Extension.Ts : ts2.Extension.Js,
1411
- isExternalLibraryImport: false
1412
- };
1413
- }
1414
- } else if (moduleName[0] !== "*") {
1407
+ resolvedFileName = import_path9.default.resolve(containingFile, "..", moduleName);
1408
+ } else {
1415
1409
  const [, nodeModuleName, relativeModulePath] = modulePartsReg.exec(moduleName);
1416
1410
  const { resolvedModule } = ts2.resolveModuleName(
1417
1411
  `${nodeModuleName}/package.json`,
@@ -1420,24 +1414,63 @@ function patch(ts2, scriptLang, cache, host) {
1420
1414
  host
1421
1415
  );
1422
1416
  if (resolvedModule) {
1423
- const resolvedFileName = import_path8.default.join(
1417
+ resolvedFileName = import_path9.default.join(
1424
1418
  resolvedModule.resolvedFileName,
1425
1419
  "..",
1426
1420
  relativeModulePath
1427
1421
  );
1428
- if (host.fileExists(resolvedFileName)) {
1429
- const isTS = isMarkoTSFile(resolvedFileName);
1430
- resolvedModules[i] = {
1431
- resolvedFileName,
1432
- extension: isTS ? ts2.Extension.Ts : ts2.Extension.Js,
1433
- isExternalLibraryImport: isTS
1434
- };
1435
- }
1422
+ }
1423
+ }
1424
+ if (!resolvedModules) {
1425
+ resolvedModules = [];
1426
+ normalModuleNames = [];
1427
+ for (let j = 0; j < i; j++) {
1428
+ resolvedModules.push(void 0);
1429
+ normalModuleNames.push(moduleNames[j]);
1430
+ }
1431
+ }
1432
+ resolvedModules.push(
1433
+ resolvedFileName && host.fileExists(resolvedFileName) ? {
1434
+ resolvedFileName,
1435
+ extension: isMarkoTSFile(resolvedFileName) ? ts2.Extension.Ts : ts2.Extension.Js,
1436
+ isExternalLibraryImport: false
1437
+ } : null
1438
+ );
1439
+ } else if (resolvedModules) {
1440
+ resolvedModules.push(void 0);
1441
+ }
1442
+ }
1443
+ const normalResolvedModules = normalModuleNames.length ? resolveModuleNames(
1444
+ normalModuleNames,
1445
+ containingFile,
1446
+ reusedNames,
1447
+ redirectedReference,
1448
+ options,
1449
+ sourceFile
1450
+ ) : void 0;
1451
+ if (resolvedModules) {
1452
+ if (normalResolvedModules) {
1453
+ for (let i = 0, j = 0; i < resolvedModules.length; i++) {
1454
+ switch (resolvedModules[i]) {
1455
+ case void 0:
1456
+ resolvedModules[i] = normalResolvedModules[j++];
1457
+ break;
1458
+ case null:
1459
+ resolvedModules[i] = void 0;
1460
+ break;
1461
+ }
1462
+ }
1463
+ } else {
1464
+ for (let i = resolvedModules.length; i--; ) {
1465
+ if (resolvedModules[i] === null) {
1466
+ resolvedModules[i] = void 0;
1436
1467
  }
1437
1468
  }
1438
1469
  }
1470
+ return resolvedModules;
1471
+ } else {
1472
+ return normalResolvedModules;
1439
1473
  }
1440
- return resolvedModules;
1441
1474
  };
1442
1475
  }
1443
1476
  return host;
@@ -1447,6 +1480,7 @@ function patch(ts2, scriptLang, cache, host) {
1447
1480
  var IGNORE_DIAG_REG = /^(?:Expression|Identifier|['"][^\w]['"]) expected.$/;
1448
1481
  var extractCache = /* @__PURE__ */ new Map();
1449
1482
  var snapshotCache = /* @__PURE__ */ new Map();
1483
+ var insertModuleStatementLocCache = /* @__PURE__ */ new WeakMap();
1450
1484
  var markoFileReg = /\.marko$/;
1451
1485
  var tsTriggerChars = /* @__PURE__ */ new Set([".", '"', "'", "`", "/", "@", "<", "#", " "]);
1452
1486
  var optionalModifierReg = /\boptional\b/;
@@ -1537,7 +1571,7 @@ var ScriptService = {
1537
1571
  let source = completion.source;
1538
1572
  if (source && completion.hasAction) {
1539
1573
  if (source[0] === ".") {
1540
- source = import_path9.default.resolve(fileName, "..", source);
1574
+ source = import_path10.default.resolve(fileName, "..", source);
1541
1575
  }
1542
1576
  detail = (0, import_relative_import_path.relativeImportPath)(fileName, source);
1543
1577
  sortText = `\uFFFF${sortText}`;
@@ -1627,18 +1661,29 @@ var ScriptService = {
1627
1661
  for (const change of action.changes) {
1628
1662
  if (change.fileName !== fileName)
1629
1663
  continue;
1630
- for (const { span, newText } of change.textChanges) {
1631
- const sourceRange = /^\s*(?:import|export) /.test(newText) ? (
1632
- // Ensure import inserts are always in the program root.
1633
- // TODO: this could probably be updated to more closely reflect
1634
- // where typescript wants to put the import/export.
1635
- START_LOCATION
1636
- ) : sourceLocationAtTextSpan(extracted, span);
1637
- if (sourceRange) {
1638
- textEdits.push({
1639
- newText,
1640
- range: sourceRange
1641
- });
1664
+ for (const { span, newText: rawText } of change.textChanges) {
1665
+ let range;
1666
+ let newText = rawText;
1667
+ if (span.length === 0 && /^\s*(?:import|export) /.test(newText)) {
1668
+ const cached = insertModuleStatementLocCache.get(extracted);
1669
+ newText = newText.replace(/\n\s*$/, "\n");
1670
+ if (cached) {
1671
+ range = cached;
1672
+ } else {
1673
+ const { parsed } = getMarkoFile(doc);
1674
+ const offset = getInsertModuleStatementOffset(parsed);
1675
+ const start = parsed.positionAt(offset);
1676
+ range = {
1677
+ start,
1678
+ end: start
1679
+ };
1680
+ insertModuleStatementLocCache.set(extracted, range);
1681
+ }
1682
+ } else {
1683
+ range = sourceLocationAtTextSpan(extracted, span);
1684
+ }
1685
+ if (range) {
1686
+ textEdits.push({ newText, range });
1642
1687
  }
1643
1688
  }
1644
1689
  }
@@ -1830,19 +1875,57 @@ ${documentation}`;
1830
1875
  }
1831
1876
  };
1832
1877
  function processScript(doc, tsProject) {
1833
- return processDoc(doc, ({ parsed, filename, project: markoProject }) => {
1834
- var _a;
1835
- const { lookup } = markoProject;
1836
- const { host, markoScriptLang } = tsProject;
1837
- return (0, import_language_tools14.extractScript)({
1838
- ts: import_tsserverlibrary.default,
1839
- parsed,
1840
- lookup,
1841
- scriptLang: getScriptLang(filename, import_tsserverlibrary.default, host, markoScriptLang),
1842
- runtimeTypesCode: (_a = getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode,
1843
- componentFilename: getComponentFilename(filename, host)
1844
- });
1845
- });
1878
+ return processDoc(
1879
+ doc,
1880
+ ({ filename, parsed, lookup, project: markoProject }) => {
1881
+ var _a;
1882
+ const { host, markoScriptLang } = tsProject;
1883
+ return (0, import_language_tools14.extractScript)({
1884
+ ts: import_tsserverlibrary.default,
1885
+ parsed,
1886
+ lookup,
1887
+ scriptLang: getScriptLang(filename, import_tsserverlibrary.default, host, markoScriptLang),
1888
+ runtimeTypesCode: (_a = getProjectTypeLibs(markoProject, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode,
1889
+ componentFilename: getComponentFilename(filename)
1890
+ });
1891
+ }
1892
+ );
1893
+ }
1894
+ function getInsertModuleStatementOffset(parsed) {
1895
+ const { program } = parsed;
1896
+ let firstNode;
1897
+ if (program.static.length) {
1898
+ let lastImport;
1899
+ for (const node of program.static) {
1900
+ switch (node.type) {
1901
+ case import_language_tools14.NodeType.Export:
1902
+ return node.start;
1903
+ case import_language_tools14.NodeType.Import:
1904
+ lastImport = node;
1905
+ break;
1906
+ }
1907
+ }
1908
+ if (lastImport) {
1909
+ return lastImport.end + 1;
1910
+ }
1911
+ firstNode = program.static[0];
1912
+ }
1913
+ if (program.body.length) {
1914
+ if (!firstNode || firstNode.start > program.body[0].start) {
1915
+ firstNode = program.body[0];
1916
+ }
1917
+ }
1918
+ if (firstNode) {
1919
+ return getOffsetAfterComments(firstNode);
1920
+ }
1921
+ return 0;
1922
+ }
1923
+ function getOffsetAfterComments(node) {
1924
+ const { comments } = node;
1925
+ if (comments) {
1926
+ return comments.at(-1).end + 1;
1927
+ }
1928
+ return Math.max(0, node.start - 1);
1846
1929
  }
1847
1930
  function sourceLocationAtTextSpan(extracted, { start, length }) {
1848
1931
  if (start === 0 && length === 0)
@@ -1875,7 +1958,7 @@ function getTSProject(docFsPath) {
1875
1958
  );
1876
1959
  }
1877
1960
  }
1878
- const rootDir = configPath && import_path9.default.dirname(configPath) || process.cwd();
1961
+ const rootDir = configPath && import_path10.default.dirname(configPath) || process.cwd();
1879
1962
  const markoProject = getMarkoProject(configPath && rootDir);
1880
1963
  let projectCache = markoProject.cache.get(getTSProject);
1881
1964
  let cached;
@@ -1889,7 +1972,8 @@ function getTSProject(docFsPath) {
1889
1972
  }
1890
1973
  const { fileNames, options, projectReferences } = import_tsserverlibrary.default.parseJsonConfigFileContent(
1891
1974
  configPath && import_tsserverlibrary.default.readConfigFile(configPath, import_tsserverlibrary.default.sys.readFile).config || {
1892
- compilerOptions: { lib: ["dom", "node", "esnext"] }
1975
+ compilerOptions: { lib: ["dom", "node", "esnext"] },
1976
+ include: []
1893
1977
  },
1894
1978
  import_tsserverlibrary.default.sys,
1895
1979
  rootDir,
@@ -1910,10 +1994,11 @@ function getTSProject(docFsPath) {
1910
1994
  options.rootDir ??= rootDir;
1911
1995
  options.module = import_tsserverlibrary.default.ModuleKind.ESNext;
1912
1996
  options.moduleResolution = import_tsserverlibrary.default.ModuleResolutionKind.NodeJs;
1913
- options.noEmit = options.allowJs = options.declaration = options.skipLibCheck = options.isolatedModules = options.resolveJsonModule = options.skipDefaultLibCheck = options.allowNonTsExtensions = true;
1997
+ options.declaration = false;
1998
+ options.noEmit = options.allowJs = options.skipLibCheck = options.isolatedModules = options.resolveJsonModule = options.skipDefaultLibCheck = options.allowNonTsExtensions = true;
1914
1999
  const tsPkgFile = configPath && ((_a = import_tsserverlibrary.default.resolveModuleName("typescript/package.json", configPath, options, import_tsserverlibrary.default.sys).resolvedModule) == null ? void 0 : _a.resolvedFileName);
1915
- const defaultLibFile = import_path9.default.join(
1916
- tsPkgFile ? import_path9.default.join(tsPkgFile, "../lib") : __dirname,
2000
+ const defaultLibFile = import_path10.default.join(
2001
+ tsPkgFile ? import_path10.default.join(tsPkgFile, "../lib") : __dirname,
1917
2002
  import_tsserverlibrary.default.getDefaultLibFileName(options)
1918
2003
  );
1919
2004
  const host = patch(
@@ -1967,12 +2052,16 @@ function getTSProject(docFsPath) {
1967
2052
  return `${((_a2 = get(filenameToURI(filename))) == null ? void 0 : _a2.version) ?? -1}`;
1968
2053
  },
1969
2054
  getScriptKind(filename) {
1970
- switch (import_path9.default.extname(filename)) {
2055
+ switch (import_path10.default.extname(filename)) {
1971
2056
  case import_tsserverlibrary.default.Extension.Js:
2057
+ case import_tsserverlibrary.default.Extension.Cjs:
2058
+ case import_tsserverlibrary.default.Extension.Mjs:
1972
2059
  return import_tsserverlibrary.default.ScriptKind.JS;
1973
2060
  case import_tsserverlibrary.default.Extension.Jsx:
1974
2061
  return import_tsserverlibrary.default.ScriptKind.JSX;
1975
2062
  case import_tsserverlibrary.default.Extension.Ts:
2063
+ case import_tsserverlibrary.default.Extension.Cts:
2064
+ case import_tsserverlibrary.default.Extension.Mts:
1976
2065
  return import_tsserverlibrary.default.ScriptKind.TS;
1977
2066
  case import_tsserverlibrary.default.Extension.Tsx:
1978
2067
  return import_tsserverlibrary.default.ScriptKind.TSX;
@@ -2468,7 +2557,7 @@ var StyleSheetService = {
2468
2557
  }
2469
2558
  };
2470
2559
  function processStyle(doc) {
2471
- return processDoc(doc, ({ uri, version, parsed, project: { lookup } }) => {
2560
+ return processDoc(doc, ({ uri, version, parsed, lookup }) => {
2472
2561
  var _a;
2473
2562
  const result = [];
2474
2563
  for (const [ext, extracted] of (0, import_language_tools15.extractStyle)({
@@ -2946,7 +3035,7 @@ setup(connection3);
2946
3035
  onFileChange((changeDoc) => {
2947
3036
  if (changeDoc) {
2948
3037
  queueDiagnostic();
2949
- getMarkoProject(getFSDir(changeDoc)).cache.delete(changeDoc);
3038
+ clearMarkoCacheForFile(changeDoc);
2950
3039
  } else {
2951
3040
  validateDocs();
2952
3041
  }
@@ -3043,10 +3132,7 @@ for (const command in service.commands) {
3043
3132
  }
3044
3133
  function validateDocs() {
3045
3134
  queueDiagnostic();
3046
- for (const project of getMarkoProjects()) {
3047
- project.cache.clear();
3048
- project.compiler.taglib.clearCaches();
3049
- }
3135
+ clearMarkoProjectCaches();
3050
3136
  }
3051
3137
  function queueDiagnostic() {
3052
3138
  clearTimeout(diagnosticTimeout);