@volar/monaco 1.6.8 → 1.7.0

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/README.md CHANGED
@@ -36,23 +36,37 @@ self.onmessage = () => {
36
36
  };
37
37
  ```
38
38
 
39
- #### TypeScript Support
39
+ #### Add TypeScript Support
40
40
 
41
- ```ts
42
- import { createLanguageService, createDtsHost } from '@volar/monaco/worker';
43
- import * as ts from 'typescript';
44
-
45
- createLanguageService({
46
- // ...
47
- typescript: {
48
- module: ts as any,
49
- compilerOptions: {
50
- // ...tsconfig options
51
- },
52
- },
53
- // Enable auto fetch node_modules types
54
- dtsHost: createDtsHost('https://unpkg.com/', { typescript: '4.9.5' }),
55
- });
41
+ ```diff
42
+ import * as worker from 'monaco-editor-core/esm/vs/editor/editor.worker';
43
+ import type * as monaco from 'monaco-editor-core';
44
+ import { createLanguageService } from '@volar/monaco/worker';
45
+ +import * as ts from 'typescript';
46
+ +import createTypeScriptService, { createJsDelivrDtsHost } from 'volar-service-typescript';
47
+
48
+ self.onmessage = () => {
49
+ worker.initialize((ctx: monaco.worker.IWorkerContext) => {
50
+ return createLanguageService({
51
+ workerContext: ctx,
52
+ config: {
53
+ // ...Language Service Config of my-lang language support
54
+ + services: {
55
+ + typescript: createTypeScriptService({
56
+ + // Enable auto fetch node_modules types
57
+ + dtsHost: createJsDelivrDtsHost({ typescript: '4.9.5' }),
58
+ + })
59
+ + },
60
+ },
61
+ + typescript: {
62
+ + module: ts as any,
63
+ + compilerOptions: {
64
+ + // ...tsconfig options
65
+ + },
66
+ + },
67
+ });
68
+ });
69
+ };
56
70
  ```
57
71
 
58
72
  ### Add worker loader to global env
package/out/editor.js CHANGED
@@ -38,7 +38,7 @@ var editor;
38
38
  let timer;
39
39
  const changeSubscription = model.onDidChangeContent(() => {
40
40
  clearTimeout(timer);
41
- timer = setTimeout(() => doValidation(model), 200);
41
+ timer = setTimeout(() => doValidation(model), 250);
42
42
  });
43
43
  const visibleSubscription = model.onDidChangeAttached(() => {
44
44
  if (model.isAttachedToEditor()) {
@@ -163,5 +163,5 @@ var editor;
163
163
  }
164
164
  }
165
165
  editor_1.activateAutoInsertion = activateAutoInsertion;
166
- })(editor = exports.editor || (exports.editor = {}));
166
+ })(editor || (exports.editor = editor = {}));
167
167
  //# sourceMappingURL=editor.js.map
package/out/languages.js CHANGED
@@ -35,5 +35,5 @@ var languages;
35
35
  return { dispose: () => disposables.forEach((d) => d.dispose()) };
36
36
  }
37
37
  languages_1.registerProvides = registerProvides;
38
- })(languages = exports.languages || (exports.languages = {}));
38
+ })(languages || (exports.languages = languages = {}));
39
39
  //# sourceMappingURL=languages.js.map
@@ -14,10 +14,10 @@ async function createLanguageFeaturesProvider(worker, getSyncUris) {
14
14
  const inlayHints = new WeakMap();
15
15
  const languageService = await worker.getProxy();
16
16
  return {
17
- triggerCharacters: await languageService.triggerCharacters(),
18
- autoFormatTriggerCharacters: await languageService.autoFormatTriggerCharacters(),
19
- signatureHelpTriggerCharacters: await languageService.signatureHelpTriggerCharacters(),
20
- signatureHelpRetriggerCharacters: await languageService.signatureHelpRetriggerCharacters(),
17
+ triggerCharacters: await languageService.getTriggerCharacters(),
18
+ autoFormatTriggerCharacters: await languageService.getAutoFormatTriggerCharacters(),
19
+ signatureHelpTriggerCharacters: await languageService.getSignatureHelpTriggerCharacters(),
20
+ signatureHelpRetriggerCharacters: await languageService.getSignatureHelpRetriggerCharacters(),
21
21
  getLegend() {
22
22
  return language_service_1.standardSemanticTokensLegend;
23
23
  },
package/out/worker.d.ts CHANGED
@@ -3,31 +3,9 @@ import type * as monaco from 'monaco-editor-core';
3
3
  import type * as ts from 'typescript/lib/tsserverlibrary';
4
4
  export declare function createLanguageService(options: {
5
5
  workerContext: monaco.worker.IWorkerContext<any>;
6
- dtsHost?: DtsHost;
7
6
  config: Config;
8
7
  typescript?: {
9
8
  module: typeof import('typescript/lib/tsserverlibrary');
10
9
  compilerOptions: ts.CompilerOptions;
11
10
  };
12
11
  }): {};
13
- export declare function createBaseDtsHost(cdn: string, versions?: Record<string, string>, flat?: (pkg: string, version: string | undefined) => Promise<string[]>, onFetch?: (fileName: string, text: string) => void): CdnDtsHost;
14
- export declare function createJsDelivrDtsHost(versions?: Record<string, string>, onFetch?: (fileName: string, text: string) => void): CdnDtsHost;
15
- export interface DtsHost {
16
- readFile(fileName: string): Thenable<string | undefined>;
17
- getVersion(): Thenable<number>;
18
- }
19
- declare class CdnDtsHost implements DtsHost {
20
- private cdn;
21
- private versions;
22
- private flat?;
23
- private onFetch?;
24
- files: Map<string, Promise<string | undefined>>;
25
- flatResult: Map<string, Promise<string[]>>;
26
- lastUpdateFilesSize: number;
27
- constructor(cdn: string, versions?: Record<string, string>, flat?: ((pkg: string, version: string | undefined) => Promise<string[]>) | undefined, onFetch?: ((fileName: string, text: string) => void) | undefined);
28
- getVersion(): Promise<number>;
29
- readFile(fileName: string): Promise<string | undefined>;
30
- fetchFile(fileName: string): Promise<string | undefined>;
31
- resolveRequestFileName(fileName: string): string;
32
- }
33
- export {};
package/out/worker.js CHANGED
@@ -1,81 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createJsDelivrDtsHost = exports.createBaseDtsHost = exports.createLanguageService = void 0;
3
+ exports.createLanguageService = void 0;
4
4
  const language_service_1 = require("@volar/language-service");
5
5
  const vscode_uri_1 = require("vscode-uri");
6
6
  function createLanguageService(options) {
7
7
  const ts = options.typescript?.module;
8
- const dtsFiles = new Map();
9
8
  const config = options.config ?? {};
10
- const compilerOptions = options.typescript?.compilerOptions ?? {};
11
- let host = createLanguageServiceHost();
12
- let languageService = (0, language_service_1.createLanguageService)({ typescript: ts }, {
9
+ const host = createLanguageServiceHost();
10
+ const languageService = (0, language_service_1.createLanguageService)({ typescript: ts }, {
13
11
  uriToFileName: uri => vscode_uri_1.URI.parse(uri).fsPath.replace(/\\/g, '/'),
14
12
  fileNameToUri: fileName => vscode_uri_1.URI.file(fileName).toString(),
15
13
  rootUri: vscode_uri_1.URI.file('/'),
16
14
  }, config, host);
17
- let dtsVersion = 0;
18
- let runningApis = 0;
19
- const toClear = new Set();
20
15
  class InnocentRabbit {
21
16
  }
22
17
  ;
23
18
  for (const api in languageService) {
24
19
  const isFunction = typeof languageService[api] === 'function';
25
- ;
26
- if (!isFunction) {
27
- InnocentRabbit.prototype[api] = () => languageService[api];
28
- continue;
20
+ if (isFunction) {
21
+ InnocentRabbit.prototype[api] = languageService[api];
29
22
  }
30
- InnocentRabbit.prototype[api] = async (...args) => {
31
- if (!options.dtsHost) {
32
- return languageService[api](...args);
33
- }
34
- let result;
35
- try {
36
- runningApis++;
37
- let oldVersion = await options.dtsHost.getVersion();
38
- result = await languageService[api](...args);
39
- let newVersion = await options.dtsHost.getVersion();
40
- while (newVersion !== oldVersion) {
41
- oldVersion = newVersion;
42
- if (newVersion !== dtsVersion) {
43
- dtsVersion = newVersion;
44
- toClear.add(languageService);
45
- languageService = (0, language_service_1.createLanguageService)({ typescript: ts }, {
46
- rootUri: vscode_uri_1.URI.file('/'),
47
- uriToFileName: (uri) => vscode_uri_1.URI.parse(uri).fsPath.replace(/\\/g, '/'),
48
- fileNameToUri: (fileName) => vscode_uri_1.URI.file(fileName).toString(),
49
- }, config, host);
50
- }
51
- result = await languageService[api](...args);
52
- newVersion = await options.dtsHost.getVersion();
53
- }
54
- }
55
- finally {
56
- runningApis--;
57
- }
58
- if (runningApis === 0 && toClear.size > 0) {
59
- for (const languageService of toClear) {
60
- languageService.dispose();
61
- }
62
- toClear.clear();
63
- }
64
- return result;
65
- };
66
23
  }
67
24
  return new InnocentRabbit();
68
25
  function createLanguageServiceHost() {
69
26
  let projectVersion = 0;
70
27
  const modelSnapshot = new WeakMap();
71
- const dtsFileSnapshot = new Map();
72
28
  const modelVersions = new Map();
73
29
  const host = {
74
30
  getProjectVersion() {
75
31
  const models = options.workerContext.getMirrorModels();
76
32
  if (modelVersions.size === options.workerContext.getMirrorModels().length) {
77
33
  if (models.every(model => modelVersions.get(model) === model.version)) {
78
- return projectVersion.toString();
34
+ return projectVersion;
79
35
  }
80
36
  }
81
37
  modelVersions.clear();
@@ -83,7 +39,7 @@ function createLanguageService(options) {
83
39
  modelVersions.set(model, model.version);
84
40
  }
85
41
  projectVersion++;
86
- return projectVersion.toString();
42
+ return projectVersion;
87
43
  },
88
44
  getScriptFileNames() {
89
45
  const models = options.workerContext.getMirrorModels();
@@ -91,14 +47,7 @@ function createLanguageService(options) {
91
47
  },
92
48
  getScriptVersion(fileName) {
93
49
  const model = options.workerContext.getMirrorModels().find(model => model.uri.fsPath === fileName);
94
- if (model) {
95
- return model.version.toString();
96
- }
97
- const dts = readDtsFile(fileName);
98
- if (dts) {
99
- return dts.length.toString();
100
- }
101
- return '';
50
+ return model?.version.toString();
102
51
  },
103
52
  getScriptSnapshot(fileName) {
104
53
  const model = options.workerContext.getMirrorModels().find(model => model.uri.fsPath === fileName);
@@ -115,195 +64,16 @@ function createLanguageService(options) {
115
64
  }]);
116
65
  return modelSnapshot.get(model)?.[1];
117
66
  }
118
- if (dtsFileSnapshot.has(fileName)) {
119
- return dtsFileSnapshot.get(fileName);
120
- }
121
- const dtsFileText = readDtsFile(fileName);
122
- if (dtsFileText !== undefined) {
123
- dtsFileSnapshot.set(fileName, {
124
- getText: (start, end) => dtsFileText.substring(start, end),
125
- getLength: () => dtsFileText.length,
126
- getChangeRange: () => undefined,
127
- });
128
- return dtsFileSnapshot.get(fileName);
129
- }
130
67
  },
131
68
  getCompilationSettings() {
132
- return compilerOptions;
69
+ return options.typescript?.compilerOptions ?? {};
133
70
  },
134
71
  getCurrentDirectory() {
135
72
  return '/';
136
73
  },
137
- getDefaultLibFileName(options) {
138
- if (ts) {
139
- return `/node_modules/typescript/lib/${ts.getDefaultLibFileName(options)}`;
140
- }
141
- return '';
142
- },
143
- readFile(fileName) {
144
- const model = options.workerContext.getMirrorModels().find(model => model.uri.fsPath === fileName);
145
- if (model) {
146
- return model.getValue();
147
- }
148
- return readDtsFile(fileName);
149
- },
150
- fileExists(fileName) {
151
- const model = options.workerContext.getMirrorModels().find(model => model.uri.fsPath === fileName);
152
- if (model) {
153
- return true;
154
- }
155
- return readDtsFile(fileName) !== undefined;
156
- },
157
74
  };
158
75
  return host;
159
76
  }
160
- function readDtsFile(fileName) {
161
- if (!dtsFiles.has(fileName) && options.dtsHost) {
162
- dtsFiles.set(fileName, undefined);
163
- readDtsFileAsync(fileName);
164
- }
165
- return dtsFiles.get(fileName);
166
- }
167
- async function readDtsFileAsync(fileName) {
168
- const text = await options.dtsHost?.readFile(fileName);
169
- dtsFiles.set(fileName, text);
170
- }
171
77
  }
172
78
  exports.createLanguageService = createLanguageService;
173
- function createBaseDtsHost(cdn, versions = {}, flat, onFetch) {
174
- return new CdnDtsHost(cdn, versions, flat, onFetch);
175
- }
176
- exports.createBaseDtsHost = createBaseDtsHost;
177
- function createJsDelivrDtsHost(versions = {}, onFetch) {
178
- return new CdnDtsHost('https://cdn.jsdelivr.net/npm/', versions, async (pkg, version) => {
179
- if (!version) {
180
- const data = await fetchJson(`https://data.jsdelivr.com/v1/package/resolve/npm/${pkg}@latest`);
181
- if (data?.version) {
182
- version = data.version;
183
- }
184
- }
185
- if (!version) {
186
- return [];
187
- }
188
- const flat = await fetchJson(`https://data.jsdelivr.com/v1/package/npm/${pkg}@${version}/flat`);
189
- if (!flat) {
190
- return [];
191
- }
192
- return flat.files.map(file => file.name);
193
- }, onFetch);
194
- }
195
- exports.createJsDelivrDtsHost = createJsDelivrDtsHost;
196
- class CdnDtsHost {
197
- constructor(cdn, versions = {}, flat, onFetch) {
198
- this.cdn = cdn;
199
- this.versions = versions;
200
- this.flat = flat;
201
- this.onFetch = onFetch;
202
- this.files = new Map();
203
- this.flatResult = new Map();
204
- this.lastUpdateFilesSize = 0;
205
- }
206
- async getVersion() {
207
- while (this.files.size !== this.lastUpdateFilesSize) {
208
- const newFileSize = this.files.size;
209
- await Promise.all(this.files.values());
210
- if (newFileSize > this.lastUpdateFilesSize) {
211
- this.lastUpdateFilesSize = newFileSize;
212
- }
213
- }
214
- return this.files.size;
215
- }
216
- async readFile(fileName) {
217
- if (fileName.startsWith('/node_modules/')
218
- // ignore .js because it's no help for intellisense
219
- && (fileName.endsWith('.d.ts') || fileName.endsWith('/package.json'))) {
220
- if (!this.files.has(fileName)) {
221
- this.files.set(fileName, this.fetchFile(fileName));
222
- }
223
- return await this.files.get(fileName);
224
- }
225
- return undefined;
226
- }
227
- async fetchFile(fileName) {
228
- if (this.flat) {
229
- let pkgName = fileName.split('/')[2];
230
- if (pkgName.startsWith('@')) {
231
- pkgName += '/' + fileName.split('/')[3];
232
- }
233
- if (pkgName.endsWith('.d.ts') || pkgName.endsWith('/node_modules')) {
234
- return undefined;
235
- }
236
- // hard code for known invalid package
237
- if (pkgName.startsWith('@typescript/') || pkgName.startsWith('@types/typescript__')) {
238
- return undefined;
239
- }
240
- // don't check @types if original package already having types
241
- if (pkgName.startsWith('@types/')) {
242
- let originalPkgName = pkgName.slice('@types/'.length);
243
- if (originalPkgName.indexOf('__') >= 0) {
244
- originalPkgName = '@' + originalPkgName.replace('__', '/');
245
- }
246
- const packageJson = await this.readFile(`/node_modules/${originalPkgName}/package.json`);
247
- if (packageJson) {
248
- const packageJsonObj = JSON.parse(packageJson);
249
- if (packageJsonObj.types || packageJsonObj.typings) {
250
- return undefined;
251
- }
252
- const indexDts = await this.readFile(`/node_modules/${originalPkgName}/index.d.ts`);
253
- if (indexDts) {
254
- return undefined;
255
- }
256
- }
257
- }
258
- if (!this.flatResult.has(pkgName)) {
259
- this.flatResult.set(pkgName, this.flat(pkgName, this.versions[pkgName]));
260
- }
261
- const flat = await this.flatResult.get(pkgName);
262
- const include = flat.includes(fileName.slice(`/node_modules/${pkgName}`.length));
263
- if (!include) {
264
- return undefined;
265
- }
266
- }
267
- const requestFileName = this.resolveRequestFileName(fileName);
268
- const url = this.cdn + requestFileName.slice('/node_modules/'.length);
269
- const text = await fetchText(url);
270
- if (text) {
271
- if (this.onFetch) {
272
- this.onFetch(fileName, text);
273
- }
274
- }
275
- return text;
276
- }
277
- resolveRequestFileName(fileName) {
278
- for (const [key, version] of Object.entries(this.versions)) {
279
- if (fileName.startsWith(`/node_modules/${key}/`)) {
280
- fileName = fileName.replace(`/node_modules/${key}/`, `/node_modules/${key}@${version}/`);
281
- return fileName;
282
- }
283
- }
284
- return fileName;
285
- }
286
- }
287
- async function fetchText(url) {
288
- try {
289
- const res = await fetch(url);
290
- if (res.status === 200) {
291
- return await res.text();
292
- }
293
- }
294
- catch {
295
- // ignore
296
- }
297
- }
298
- async function fetchJson(url) {
299
- try {
300
- const res = await fetch(url);
301
- if (res.status === 200) {
302
- return await res.json();
303
- }
304
- }
305
- catch {
306
- // ignore
307
- }
308
- }
309
79
  //# sourceMappingURL=worker.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volar/monaco",
3
- "version": "1.6.8",
3
+ "version": "1.7.0",
4
4
  "main": "out/index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -15,12 +15,12 @@
15
15
  "directory": "packages/monaco"
16
16
  },
17
17
  "dependencies": {
18
- "@volar/language-service": "1.6.8",
18
+ "@volar/language-service": "1.7.0",
19
19
  "vscode-uri": "^3.0.7"
20
20
  },
21
21
  "devDependencies": {
22
22
  "monaco-editor-core": "latest",
23
23
  "vscode-languageserver-protocol": "^3.17.3"
24
24
  },
25
- "gitHead": "3d269c7e69850ac5497469bede13f057db8a4980"
25
+ "gitHead": "38ec4f727b32dbf2cf3284ab02695e3a8effacc5"
26
26
  }