@gi-tcg/gts-language-server 0.3.0 → 0.3.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.
@@ -0,0 +1,279 @@
1
+ import { createConnection, createServer, createTypeScriptProject, loadTsdkByUrl } from "@volar/language-server/browser.js";
2
+ import { GtsVirtualCode, createGtsLanguagePlugin } from "@gi-tcg/gts-language-plugin";
3
+ import path from "path-browserify-esm";
4
+ import "@gi-tcg/gts-transpiler";
5
+ import { DiagnosticSeverity } from "@volar/language-server";
6
+ import { URI } from "vscode-uri";
7
+ import { create } from "volar-service-typescript";
8
+ import { fs } from "@zenfs/core";
9
+ //#region src/utils.ts
10
+ /**
11
+ * Get virtual code from the encoded document URI
12
+ */
13
+ function getVirtualCode(document, context) {
14
+ const uri = URI.parse(document.uri);
15
+ const [sourceUri, virtualCodeId] = context.decodeEmbeddedDocumentUri(uri);
16
+ const virtualCode = context.language.scripts.get(sourceUri)?.generated?.embeddedCodes.get(virtualCodeId);
17
+ if (!virtualCode) return [null, sourceUri];
18
+ if (!(virtualCode instanceof GtsVirtualCode)) return [null, sourceUri];
19
+ return [virtualCode, sourceUri];
20
+ }
21
+ //#endregion
22
+ //#region src/diagnostics.ts
23
+ const createDiagnosticsPlugin = () => {
24
+ return {
25
+ name: "gts-diagnostics",
26
+ capabilities: { diagnosticProvider: {
27
+ interFileDependencies: false,
28
+ workspaceDiagnostics: false
29
+ } },
30
+ create: (context) => {
31
+ return { provideDiagnostics: (document) => {
32
+ try {
33
+ const [virtualCode] = getVirtualCode(document, context);
34
+ if (!virtualCode) return;
35
+ return virtualCode.errors.map((err) => {
36
+ const loc = err.position ?? {
37
+ start: {
38
+ line: 1,
39
+ column: 0
40
+ },
41
+ end: {
42
+ line: 1,
43
+ column: 1
44
+ }
45
+ };
46
+ const range = {
47
+ start: {
48
+ line: loc.start.line - 1,
49
+ character: loc.start.column
50
+ },
51
+ end: {
52
+ line: loc.end.line - 1,
53
+ character: loc.end.column
54
+ }
55
+ };
56
+ return {
57
+ severity: DiagnosticSeverity.Error,
58
+ range,
59
+ message: err.message,
60
+ source: "gts-transpiler",
61
+ code: "gts-transpiler-error"
62
+ };
63
+ });
64
+ } catch (e) {
65
+ console.error(e);
66
+ return;
67
+ }
68
+ } };
69
+ }
70
+ };
71
+ };
72
+ //#endregion
73
+ //#region src/typescript.ts
74
+ function createTypeScriptServices(ts) {
75
+ const services = create(ts);
76
+ const semanticService = services.find((service) => service.name === "typescript-semantic");
77
+ if (semanticService?.capabilities.signatureHelpProvider?.triggerCharacters) semanticService.capabilities.signatureHelpProvider.triggerCharacters.push(" ");
78
+ return services;
79
+ }
80
+ //#endregion
81
+ //#region src/completion.ts
82
+ const createCompletionPlugin = () => {
83
+ return {
84
+ name: "gts-completion",
85
+ capabilities: { completionProvider: { triggerCharacters: [":"] } },
86
+ create: (context) => {
87
+ let originalProvideCompletionItems;
88
+ for (const [plugin, instance] of context.plugins) if (plugin.name === "typescript-semantic") originalProvideCompletionItems = instance.provideCompletionItems;
89
+ if (!originalProvideCompletionItems) {
90
+ console.warn(`TS's original provideCompletionItems not found`);
91
+ return {};
92
+ }
93
+ return { provideCompletionItems: async (document, position, context, token) => {
94
+ if (context.triggerCharacter === ":") {
95
+ context.triggerCharacter = ".";
96
+ return await originalProvideCompletionItems(document, position, context, token);
97
+ }
98
+ return null;
99
+ } };
100
+ }
101
+ };
102
+ };
103
+ //#endregion
104
+ //#region src/zen_fs_provider.ts
105
+ function zenFsProvider(fs) {
106
+ return {
107
+ stat(uri) {
108
+ try {
109
+ const stats = fs.statSync(uri.path);
110
+ console.log("stat", uri.path, stats);
111
+ return {
112
+ type: stats.isFile() ? 1 : stats.isDirectory() ? 2 : stats.isSymbolicLink() ? 64 : 0,
113
+ ctime: stats.ctimeMs,
114
+ mtime: stats.mtimeMs,
115
+ size: stats.size
116
+ };
117
+ } catch {
118
+ return;
119
+ }
120
+ },
121
+ readFile(uri, encoding) {
122
+ try {
123
+ console.log("readFile", uri.path);
124
+ return fs.readFileSync(uri.path, { encoding: encoding ?? "utf-8" });
125
+ } catch {
126
+ return;
127
+ }
128
+ },
129
+ readDirectory(uri) {
130
+ try {
131
+ const files = fs.readdirSync(uri.path, { withFileTypes: true });
132
+ console.log("readDirectory", uri.path, files.map((f) => f.name));
133
+ return files.map((file) => {
134
+ return [file.name, file.isFile() ? 1 : file.isDirectory() ? 2 : file.isSymbolicLink() ? 64 : 0];
135
+ });
136
+ } catch {
137
+ return [];
138
+ }
139
+ }
140
+ };
141
+ }
142
+ //#endregion
143
+ //#region src/browser.ts
144
+ const connection = createConnection();
145
+ const server = createServer(connection);
146
+ server.fileSystem.install("file", zenFsProvider(fs));
147
+ connection.listen();
148
+ connection.onInitialize(async (params) => {
149
+ const { tsdkUrl = "https://cdn.jsdelivr.net/npm/typescript@latest/lib", fs: fs$1 = {}, inlineGtsConfig = {}, inlineCompilerOptions = {} } = params.initializationOptions ?? {};
150
+ const tsdk = await loadTsdkByUrl(tsdkUrl, params.locale);
151
+ await loadLibs(tsdkUrl);
152
+ for (const [filepath, content] of Object.entries(fs$1)) {
153
+ fs.mkdirSync(path.dirname(filepath), { recursive: true });
154
+ fs.writeFileSync(filepath, content);
155
+ }
156
+ return server.initialize(params, createTypeScriptProject(tsdk.typescript, tsdk.diagnosticMessages, ({ env }) => {
157
+ return { languagePlugins: [createGtsLanguagePlugin(tsdk.typescript, inlineGtsConfig)] };
158
+ }), [
159
+ ...createTypeScriptServices(tsdk.typescript),
160
+ createDiagnosticsPlugin(),
161
+ createCompletionPlugin()
162
+ ]);
163
+ });
164
+ connection.onInitialized(server.initialized);
165
+ connection.onShutdown(server.shutdown);
166
+ self.addEventListener("error", (event) => {
167
+ console.error("Uncaught exception:", event.error);
168
+ });
169
+ self.addEventListener("unhandledrejection", (event) => {
170
+ console.error("Unhandled rejection at:", event.promise, "reason:", event.reason);
171
+ });
172
+ async function loadLibs(tsdkUrl) {
173
+ fs.mkdirSync("/node_modules/typescript/lib", { recursive: true });
174
+ const libs = await Promise.all(ALL_LIBS.map((lib) => fetch(`${tsdkUrl}/${lib}`).then((res) => res.text()).then((content) => [lib, content])));
175
+ for (const [lib, content] of libs) fs.writeFileSync(`/node_modules/typescript/lib/${lib}`, content);
176
+ }
177
+ const ALL_LIBS = [
178
+ "lib.d.ts",
179
+ "lib.decorators.d.ts",
180
+ "lib.decorators.legacy.d.ts",
181
+ "lib.dom.asynciterable.d.ts",
182
+ "lib.dom.d.ts",
183
+ "lib.dom.iterable.d.ts",
184
+ "lib.es2015.collection.d.ts",
185
+ "lib.es2015.core.d.ts",
186
+ "lib.es2015.d.ts",
187
+ "lib.es2015.generator.d.ts",
188
+ "lib.es2015.iterable.d.ts",
189
+ "lib.es2015.promise.d.ts",
190
+ "lib.es2015.proxy.d.ts",
191
+ "lib.es2015.reflect.d.ts",
192
+ "lib.es2015.symbol.d.ts",
193
+ "lib.es2015.symbol.wellknown.d.ts",
194
+ "lib.es2016.array.include.d.ts",
195
+ "lib.es2016.d.ts",
196
+ "lib.es2016.full.d.ts",
197
+ "lib.es2016.intl.d.ts",
198
+ "lib.es2017.arraybuffer.d.ts",
199
+ "lib.es2017.d.ts",
200
+ "lib.es2017.date.d.ts",
201
+ "lib.es2017.full.d.ts",
202
+ "lib.es2017.intl.d.ts",
203
+ "lib.es2017.object.d.ts",
204
+ "lib.es2017.sharedmemory.d.ts",
205
+ "lib.es2017.string.d.ts",
206
+ "lib.es2017.typedarrays.d.ts",
207
+ "lib.es2018.asyncgenerator.d.ts",
208
+ "lib.es2018.asynciterable.d.ts",
209
+ "lib.es2018.d.ts",
210
+ "lib.es2018.full.d.ts",
211
+ "lib.es2018.intl.d.ts",
212
+ "lib.es2018.promise.d.ts",
213
+ "lib.es2018.regexp.d.ts",
214
+ "lib.es2019.array.d.ts",
215
+ "lib.es2019.d.ts",
216
+ "lib.es2019.full.d.ts",
217
+ "lib.es2019.intl.d.ts",
218
+ "lib.es2019.object.d.ts",
219
+ "lib.es2019.string.d.ts",
220
+ "lib.es2019.symbol.d.ts",
221
+ "lib.es2020.bigint.d.ts",
222
+ "lib.es2020.d.ts",
223
+ "lib.es2020.date.d.ts",
224
+ "lib.es2020.full.d.ts",
225
+ "lib.es2020.intl.d.ts",
226
+ "lib.es2020.number.d.ts",
227
+ "lib.es2020.promise.d.ts",
228
+ "lib.es2020.sharedmemory.d.ts",
229
+ "lib.es2020.string.d.ts",
230
+ "lib.es2020.symbol.wellknown.d.ts",
231
+ "lib.es2021.d.ts",
232
+ "lib.es2021.full.d.ts",
233
+ "lib.es2021.intl.d.ts",
234
+ "lib.es2021.promise.d.ts",
235
+ "lib.es2021.string.d.ts",
236
+ "lib.es2021.weakref.d.ts",
237
+ "lib.es2022.array.d.ts",
238
+ "lib.es2022.d.ts",
239
+ "lib.es2022.error.d.ts",
240
+ "lib.es2022.full.d.ts",
241
+ "lib.es2022.intl.d.ts",
242
+ "lib.es2022.object.d.ts",
243
+ "lib.es2022.regexp.d.ts",
244
+ "lib.es2022.string.d.ts",
245
+ "lib.es2023.array.d.ts",
246
+ "lib.es2023.collection.d.ts",
247
+ "lib.es2023.d.ts",
248
+ "lib.es2023.full.d.ts",
249
+ "lib.es2023.intl.d.ts",
250
+ "lib.es2024.arraybuffer.d.ts",
251
+ "lib.es2024.collection.d.ts",
252
+ "lib.es2024.d.ts",
253
+ "lib.es2024.full.d.ts",
254
+ "lib.es2024.object.d.ts",
255
+ "lib.es2024.promise.d.ts",
256
+ "lib.es2024.regexp.d.ts",
257
+ "lib.es2024.sharedmemory.d.ts",
258
+ "lib.es2024.string.d.ts",
259
+ "lib.es5.d.ts",
260
+ "lib.es6.d.ts",
261
+ "lib.esnext.array.d.ts",
262
+ "lib.esnext.collection.d.ts",
263
+ "lib.esnext.d.ts",
264
+ "lib.esnext.decorators.d.ts",
265
+ "lib.esnext.disposable.d.ts",
266
+ "lib.esnext.error.d.ts",
267
+ "lib.esnext.float16.d.ts",
268
+ "lib.esnext.full.d.ts",
269
+ "lib.esnext.intl.d.ts",
270
+ "lib.esnext.iterator.d.ts",
271
+ "lib.esnext.promise.d.ts",
272
+ "lib.esnext.sharedmemory.d.ts",
273
+ "lib.scripthost.d.ts",
274
+ "lib.webworker.asynciterable.d.ts",
275
+ "lib.webworker.d.ts",
276
+ "lib.webworker.importscripts.d.ts",
277
+ "lib.webworker.iterable.d.ts"
278
+ ];
279
+ //#endregion
package/dist/node.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { };
package/dist/node.js ADDED
@@ -0,0 +1,124 @@
1
+ import { createConnection, createServer, createTypeScriptProject, loadTsdkByPath } from "@volar/language-server/node.js";
2
+ import { GtsVirtualCode, createGtsLanguagePlugin } from "@gi-tcg/gts-language-plugin";
3
+ import { DiagnosticSeverity } from "@volar/language-server";
4
+ import { URI } from "vscode-uri";
5
+ import { create } from "volar-service-typescript";
6
+ //#region src/utils.ts
7
+ /**
8
+ * Get virtual code from the encoded document URI
9
+ */
10
+ function getVirtualCode(document, context) {
11
+ const uri = URI.parse(document.uri);
12
+ const [sourceUri, virtualCodeId] = context.decodeEmbeddedDocumentUri(uri);
13
+ const virtualCode = context.language.scripts.get(sourceUri)?.generated?.embeddedCodes.get(virtualCodeId);
14
+ if (!virtualCode) return [null, sourceUri];
15
+ if (!(virtualCode instanceof GtsVirtualCode)) return [null, sourceUri];
16
+ return [virtualCode, sourceUri];
17
+ }
18
+ //#endregion
19
+ //#region src/diagnostics.ts
20
+ const createDiagnosticsPlugin = () => {
21
+ return {
22
+ name: "gts-diagnostics",
23
+ capabilities: { diagnosticProvider: {
24
+ interFileDependencies: false,
25
+ workspaceDiagnostics: false
26
+ } },
27
+ create: (context) => {
28
+ return { provideDiagnostics: (document) => {
29
+ try {
30
+ const [virtualCode] = getVirtualCode(document, context);
31
+ if (!virtualCode) return;
32
+ return virtualCode.errors.map((err) => {
33
+ const loc = err.position ?? {
34
+ start: {
35
+ line: 1,
36
+ column: 0
37
+ },
38
+ end: {
39
+ line: 1,
40
+ column: 1
41
+ }
42
+ };
43
+ const range = {
44
+ start: {
45
+ line: loc.start.line - 1,
46
+ character: loc.start.column
47
+ },
48
+ end: {
49
+ line: loc.end.line - 1,
50
+ character: loc.end.column
51
+ }
52
+ };
53
+ return {
54
+ severity: DiagnosticSeverity.Error,
55
+ range,
56
+ message: err.message,
57
+ source: "gts-transpiler",
58
+ code: "gts-transpiler-error"
59
+ };
60
+ });
61
+ } catch (e) {
62
+ console.error(e);
63
+ return;
64
+ }
65
+ } };
66
+ }
67
+ };
68
+ };
69
+ //#endregion
70
+ //#region src/typescript.ts
71
+ function createTypeScriptServices(ts) {
72
+ const services = create(ts);
73
+ const semanticService = services.find((service) => service.name === "typescript-semantic");
74
+ if (semanticService?.capabilities.signatureHelpProvider?.triggerCharacters) semanticService.capabilities.signatureHelpProvider.triggerCharacters.push(" ");
75
+ return services;
76
+ }
77
+ //#endregion
78
+ //#region src/completion.ts
79
+ const createCompletionPlugin = () => {
80
+ return {
81
+ name: "gts-completion",
82
+ capabilities: { completionProvider: { triggerCharacters: [":"] } },
83
+ create: (context) => {
84
+ let originalProvideCompletionItems;
85
+ for (const [plugin, instance] of context.plugins) if (plugin.name === "typescript-semantic") originalProvideCompletionItems = instance.provideCompletionItems;
86
+ if (!originalProvideCompletionItems) {
87
+ console.warn(`TS's original provideCompletionItems not found`);
88
+ return {};
89
+ }
90
+ return { provideCompletionItems: async (document, position, context, token) => {
91
+ if (context.triggerCharacter === ":") {
92
+ context.triggerCharacter = ".";
93
+ return await originalProvideCompletionItems(document, position, context, token);
94
+ }
95
+ return null;
96
+ } };
97
+ }
98
+ };
99
+ };
100
+ //#endregion
101
+ //#region src/node.ts
102
+ const connection = createConnection();
103
+ const server = createServer(connection);
104
+ connection.listen();
105
+ connection.onInitialize((params) => {
106
+ const tsdk = loadTsdkByPath(params.initializationOptions.typescript.tsdk, params.locale);
107
+ return server.initialize(params, createTypeScriptProject(tsdk.typescript, tsdk.diagnosticMessages, () => {
108
+ return { languagePlugins: [createGtsLanguagePlugin(tsdk.typescript)] };
109
+ }), [
110
+ ...createTypeScriptServices(tsdk.typescript),
111
+ createDiagnosticsPlugin(),
112
+ createCompletionPlugin()
113
+ ]);
114
+ });
115
+ connection.onInitialized(server.initialized);
116
+ connection.onShutdown(server.shutdown);
117
+ process.on("uncaughtException", (err) => {
118
+ console.error("Uncaught exception:", err);
119
+ });
120
+ process.on("unhandledRejection", (reason, promise) => {
121
+ console.error("Unhandled rejection at:", promise, "reason:", reason);
122
+ });
123
+ //#endregion
124
+ export {};
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@gi-tcg/gts-language-server",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "repository": "https://github.com/piovium/gts.git",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  "./node": {
9
- "bun": "./src/node.ts",
10
- "default": "./dist/node/node.js"
9
+ "development": "./src/node.ts",
10
+ "default": "./dist/node.js"
11
11
  },
12
12
  "./browser": {
13
- "bun": "./src/browser.ts",
14
- "default": "./dist/browser/browser.js"
13
+ "development": "./src/browser.ts",
14
+ "default": "./dist/browser.js"
15
15
  }
16
16
  },
17
17
  "bin": {
@@ -22,16 +22,19 @@
22
22
  "dist",
23
23
  "bin"
24
24
  ],
25
- "scripts": {},
26
25
  "dependencies": {
27
- "@gi-tcg/gts-language-plugin": "0.3.0",
28
- "@gi-tcg/gts-transpiler": "0.3.0",
29
26
  "@volar/language-server": "~2.4.0",
30
27
  "@zenfs/core": "^2.5.0",
28
+ "path-browserify-esm": "^1.0.6",
31
29
  "volar-service-typescript": "volar-2.4",
32
- "vscode-uri": "^3.0.8"
30
+ "vscode-uri": "^3.0.8",
31
+ "@gi-tcg/gts-language-plugin": "0.3.2",
32
+ "@gi-tcg/gts-transpiler": "0.3.2"
33
33
  },
34
34
  "devDependencies": {
35
35
  "vscode-languageserver-textdocument": "^1.0.12"
36
+ },
37
+ "scripts": {
38
+ "build": "tsdown"
36
39
  }
37
- }
40
+ }
package/src/browser.ts CHANGED
@@ -9,13 +9,14 @@ import {
9
9
  type InitializeParams,
10
10
  } from "@volar/language-server/browser.js";
11
11
  import { createGtsLanguagePlugin } from "@gi-tcg/gts-language-plugin";
12
- import { path, type GtsConfig } from "@gi-tcg/gts-transpiler";
13
- import { createDiagnosticsPlugin } from "./diagnostics";
14
- import { createTypeScriptServices } from "./typescript";
15
- import { createCompletionPlugin } from "./completion";
12
+ import path from "path-browserify-esm";
13
+ import { type GtsConfig } from "@gi-tcg/gts-transpiler";
14
+ import { createDiagnosticsPlugin } from "./diagnostics.ts";
15
+ import { createTypeScriptServices } from "./typescript.ts";
16
+ import { createCompletionPlugin } from "./completion.ts";
16
17
  import { Dirent, fs as memfs } from "@zenfs/core";
17
- import ts from "typescript";
18
- import zenFsProvider from "./zen_fs_provider";
18
+ import type ts from "typescript";
19
+ import zenFsProvider from "./zen_fs_provider.ts";
19
20
 
20
21
  export interface GtsLanguageServerBrowserInitializationOptions {
21
22
  tsdkUrl?: string;
@@ -3,7 +3,7 @@ import {
3
3
  Range,
4
4
  type LanguageServicePlugin,
5
5
  } from "@volar/language-server";
6
- import { getVirtualCode } from "./utils";
6
+ import { getVirtualCode } from "./utils.ts";
7
7
  export const createDiagnosticsPlugin = (): LanguageServicePlugin => {
8
8
  return {
9
9
  name: "gts-diagnostics",
package/src/node.ts CHANGED
@@ -6,9 +6,9 @@ import {
6
6
  loadTsdkByPath,
7
7
  } from "@volar/language-server/node.js";
8
8
  import { createGtsLanguagePlugin } from "@gi-tcg/gts-language-plugin";
9
- import { createDiagnosticsPlugin } from "./diagnostics";
10
- import { createTypeScriptServices } from "./typescript";
11
- import { createCompletionPlugin } from "./completion";
9
+ import { createDiagnosticsPlugin } from "./diagnostics.ts";
10
+ import { createTypeScriptServices } from "./typescript.ts";
11
+ import { createCompletionPlugin } from "./completion.ts";
12
12
 
13
13
  const connection = createConnection();
14
14
  const server = createServer(connection);
@@ -1,9 +0,0 @@
1
- import { GtsConfig } from "@gi-tcg/gts-transpiler";
2
- import ts from "typescript";
3
- interface GtsLanguageServerBrowserInitializationOptions {
4
- tsdkUrl?: string;
5
- inlineGtsConfig?: GtsConfig;
6
- inlineCompilerOptions?: ts.CompilerOptions;
7
- fs?: Record<string, string>;
8
- }
9
- export { GtsLanguageServerBrowserInitializationOptions };