qsharp-lang 1.0.28-dev → 1.0.30-dev

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/browser.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as wasm from "../lib/web/qsc_wasm.js";
1
2
  import { TargetProfile } from "../lib/web/qsc_wasm.js";
2
3
  import { ICompiler, ICompilerWorker } from "./compiler/compiler.js";
3
4
  import { IDebugService, IDebugServiceWorker } from "./debug-service/debug-service.js";
@@ -7,10 +8,15 @@ export { qsharpLibraryUriScheme };
7
8
  export declare function loadWasmModule(uriOrBuffer: string | ArrayBuffer): Promise<void>;
8
9
  export declare function getLibrarySourceContent(path: string): Promise<string | undefined>;
9
10
  export declare function getDebugService(): Promise<IDebugService>;
11
+ export declare function getProjectLoader(readFile: (path: string) => Promise<string | null>, loadDirectory: (path: string) => Promise<[string, number][]>, getManifest: (path: string) => Promise<{
12
+ manifestDirectory: string;
13
+ } | null>): Promise<wasm.ProjectLoader>;
10
14
  export declare function getDebugServiceWorker(workerArg: string | Worker): IDebugServiceWorker;
11
15
  export declare function getCompiler(): Promise<ICompiler>;
12
16
  export declare function getCompilerWorker(workerArg: string | Worker): ICompilerWorker;
13
- export declare function getLanguageService(): Promise<ILanguageService>;
17
+ export declare function getLanguageService(readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
18
+ manifestDirectory: string;
19
+ } | null>): Promise<ILanguageService>;
14
20
  export declare function getLanguageServiceWorker(workerArg: string | Worker): ILanguageServiceWorker;
15
21
  export { type Dump, type ShotResult } from "./compiler/common.js";
16
22
  export { type CompilerState } from "./compiler/compiler.js";
package/dist/browser.js CHANGED
@@ -72,6 +72,10 @@ export async function getDebugService() {
72
72
  await instantiateWasm();
73
73
  return new QSharpDebugService(wasm);
74
74
  }
75
+ export async function getProjectLoader(readFile, loadDirectory, getManifest) {
76
+ await instantiateWasm();
77
+ return new wasm.ProjectLoader(readFile, loadDirectory, getManifest);
78
+ }
75
79
  // Create the debugger inside a WebWorker and proxy requests.
76
80
  // If the Worker was already created via other means and is ready to receive
77
81
  // messages, then the worker may be passed in and it will be initialized.
@@ -122,9 +126,9 @@ export function getCompilerWorker(workerArg) {
122
126
  worker.onmessage = (ev) => proxy.onMsgFromWorker(ev.data);
123
127
  return proxy;
124
128
  }
125
- export async function getLanguageService() {
129
+ export async function getLanguageService(readFile, listDir, getManifest) {
126
130
  await instantiateWasm();
127
- return new QSharpLanguageService(wasm);
131
+ return new QSharpLanguageService(wasm, readFile, listDir, getManifest);
128
132
  }
129
133
  // Create the compiler inside a WebWorker and proxy requests.
130
134
  // If the Worker was already created via other means and is ready to receive
@@ -5,9 +5,9 @@ type Wasm = typeof import("../../lib/node/qsc_wasm.cjs");
5
5
  export interface ICompiler {
6
6
  checkCode(code: string): Promise<VSDiagnostic[]>;
7
7
  getHir(code: string): Promise<string>;
8
- run(code: string, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
9
- getQir(code: string): Promise<string>;
10
- getEstimates(code: string, params: string): Promise<string>;
8
+ run(sources: [string, string][], expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
9
+ getQir(sources: [string, string][]): Promise<string>;
10
+ getEstimates(sources: [string, string][], params: string): Promise<string>;
11
11
  checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
12
12
  }
13
13
  export type ICompilerWorker = ICompiler & IServiceProxy;
@@ -16,10 +16,10 @@ export declare class Compiler implements ICompiler {
16
16
  private wasm;
17
17
  constructor(wasm: Wasm);
18
18
  checkCode(code: string): Promise<VSDiagnostic[]>;
19
- getQir(code: string): Promise<string>;
20
- getEstimates(code: string, params: string): Promise<string>;
19
+ getQir(sources: [string, string][]): Promise<string>;
20
+ getEstimates(sources: [string, string][], params: string): Promise<string>;
21
21
  getHir(code: string): Promise<string>;
22
- run(code: string, expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
22
+ run(sources: [string, string][], expr: string, shots: number, eventHandler: IQscEventTarget): Promise<void>;
23
23
  checkExerciseSolution(user_code: string, exercise_sources: string[], eventHandler: IQscEventTarget): Promise<boolean>;
24
24
  }
25
25
  export declare function onCompilerEvent(msg: string, eventTarget: IQscEventTarget): void;
@@ -10,28 +10,36 @@ export class Compiler {
10
10
  this.wasm = wasm;
11
11
  globalThis.qscGitHash = this.wasm.git_hash();
12
12
  }
13
+ // Note: This function does not support project mode.
14
+ // see https://github.com/microsoft/qsharp/pull/849#discussion_r1409821143
13
15
  async checkCode(code) {
14
16
  let diags = [];
15
- const languageService = new this.wasm.LanguageService((uri, version, errors) => {
17
+ const languageService = new this.wasm.LanguageService();
18
+ const work = languageService.start_background_work((uri, version, errors) => {
16
19
  diags = errors;
17
- });
20
+ }, () => Promise.resolve(null), () => Promise.resolve([]), () => Promise.resolve(null));
18
21
  languageService.update_document("code", 1, code);
22
+ // Yield to let the language service background worker handle the update
23
+ await Promise.resolve();
24
+ languageService.stop_background_work();
25
+ await work;
26
+ languageService.free();
19
27
  return mapDiagnostics(diags, code);
20
28
  }
21
- async getQir(code) {
22
- return this.wasm.get_qir(code);
29
+ async getQir(sources) {
30
+ return this.wasm.get_qir(sources);
23
31
  }
24
- async getEstimates(code, params) {
25
- return this.wasm.get_estimates(code, params);
32
+ async getEstimates(sources, params) {
33
+ return this.wasm.get_estimates(sources, params);
26
34
  }
27
35
  async getHir(code) {
28
36
  return this.wasm.get_hir(code);
29
37
  }
30
- async run(code, expr, shots, eventHandler) {
38
+ async run(sources, expr, shots, eventHandler) {
31
39
  // All results are communicated as events, but if there is a compiler error (e.g. an invalid
32
40
  // entry expression or similar), it may throw on run. The caller should expect this promise
33
41
  // may reject without all shots running or events firing.
34
- this.wasm.run(code, expr, (msg) => onCompilerEvent(msg, eventHandler), shots);
42
+ this.wasm.run(sources, expr, (msg) => onCompilerEvent(msg, eventHandler), shots);
35
43
  }
36
44
  async checkExerciseSolution(user_code, exercise_sources, eventHandler) {
37
45
  const success = this.wasm.check_exercise_solution(user_code, exercise_sources, (msg) => onCompilerEvent(msg, eventHandler));
@@ -4,7 +4,7 @@ import { IQscEventTarget } from "../compiler/events.js";
4
4
  import { IServiceProxy } from "../worker-proxy.js";
5
5
  type QscWasm = typeof import("../../lib/node/qsc_wasm.cjs");
6
6
  export interface IDebugService {
7
- loadSource(path: string, source: string, target: TargetProfile, entry: string | undefined): Promise<string>;
7
+ loadSource(sources: [string, string][], target: TargetProfile, entry: string | undefined): Promise<string>;
8
8
  getBreakpoints(path: string): Promise<IBreakpointSpan[]>;
9
9
  getLocalVariables(): Promise<Array<IVariable>>;
10
10
  captureQuantumState(): Promise<Array<IQuantumState>>;
@@ -21,7 +21,7 @@ export declare class QSharpDebugService implements IDebugService {
21
21
  private debugService;
22
22
  private code;
23
23
  constructor(wasm: QscWasm);
24
- loadSource(path: string, source: string, target: TargetProfile, entry: string | undefined): Promise<string>;
24
+ loadSource(sources: [string, string][], target: TargetProfile, entry: string | undefined): Promise<string>;
25
25
  getStackFrames(): Promise<IStackFrame[]>;
26
26
  evalNext(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
27
27
  evalStepIn(bps: number[], eventHandler: IQscEventTarget): Promise<IStructStepResult>;
@@ -12,9 +12,11 @@ export class QSharpDebugService {
12
12
  this.wasm = wasm;
13
13
  this.debugService = new wasm.DebugService();
14
14
  }
15
- async loadSource(path, source, target, entry) {
16
- this.code[path] = source;
17
- return this.debugService.load_source(path, source, target, entry);
15
+ async loadSource(sources, target, entry) {
16
+ for (const [path, source] of sources) {
17
+ this.code[path] = source;
18
+ }
19
+ return this.debugService.load_source(sources, target, entry);
18
20
  }
19
21
  async getStackFrames() {
20
22
  const stack_frame_list = this.debugService.get_stack_frames();
@@ -19,7 +19,7 @@ export interface ILanguageService {
19
19
  code: string;
20
20
  }[]): Promise<void>;
21
21
  closeDocument(uri: string): Promise<void>;
22
- closeNotebookDocument(notebookUri: string, cellUris: string[]): Promise<void>;
22
+ closeNotebookDocument(notebookUri: string): Promise<void>;
23
23
  getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
24
24
  getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
25
25
  getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
@@ -41,7 +41,12 @@ export declare class QSharpLanguageService implements ILanguageService {
41
41
  private languageService;
42
42
  private eventHandler;
43
43
  private code;
44
- constructor(wasm: QscWasm);
44
+ private readFile;
45
+ private backgroundWork;
46
+ constructor(wasm: QscWasm, readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
47
+ manifestDirectory: string;
48
+ } | null>);
49
+ loadFile(uri: string): Promise<string | null>;
45
50
  updateConfiguration(config: IWorkspaceConfiguration): Promise<void>;
46
51
  updateDocument(documentUri: string, version: number, code: string): Promise<void>;
47
52
  updateNotebookDocument(notebookUri: string, version: number, metadata: INotebookMetadata, cells: {
@@ -50,7 +55,7 @@ export declare class QSharpLanguageService implements ILanguageService {
50
55
  code: string;
51
56
  }[]): Promise<void>;
52
57
  closeDocument(documentUri: string): Promise<void>;
53
- closeNotebookDocument(documentUri: string, cellUris: string[]): Promise<void>;
58
+ closeNotebookDocument(documentUri: string): Promise<void>;
54
59
  getCompletions(documentUri: string, offset: number): Promise<ICompletionList>;
55
60
  getHover(documentUri: string, offset: number): Promise<IHover | undefined>;
56
61
  getDefinition(documentUri: string, offset: number): Promise<ILocation | undefined>;
@@ -65,6 +70,6 @@ export declare class QSharpLanguageService implements ILanguageService {
65
70
  removeEventListener<T extends LanguageServiceEvent["type"]>(type: T, listener: (event: Extract<LanguageServiceEvent, {
66
71
  type: T;
67
72
  }>) => void): void;
68
- onDiagnostics(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]): void;
73
+ onDiagnostics(uri: string, version: number | undefined, diagnostics: VSDiagnostic[]): Promise<void>;
69
74
  }
70
75
  export {};
@@ -5,12 +5,25 @@ import { log } from "../log.js";
5
5
  import { mapDiagnostics, mapUtf16UnitsToUtf8Units, mapUtf8UnitsToUtf16Units, } from "../vsdiagnostic.js";
6
6
  export const qsharpLibraryUriScheme = "qsharp-library-source";
7
7
  export class QSharpLanguageService {
8
- constructor(wasm) {
8
+ constructor(wasm, readFile = () => Promise.resolve(null), listDir = () => Promise.resolve([]), getManifest = () => Promise.resolve(null)) {
9
9
  this.eventHandler = new EventTarget();
10
10
  // We need to keep a copy of the code for mapping diagnostics to utf16 offsets
11
11
  this.code = {};
12
12
  log.info("Constructing a QSharpLanguageService instance");
13
- this.languageService = new wasm.LanguageService(this.onDiagnostics.bind(this));
13
+ this.languageService = new wasm.LanguageService();
14
+ this.backgroundWork = this.languageService.start_background_work(this.onDiagnostics.bind(this), readFile, listDir, getManifest);
15
+ this.readFile = readFile;
16
+ }
17
+ async loadFile(uri) {
18
+ const result = this.code[uri];
19
+ if (result === undefined || result === null) {
20
+ return await this.readFile(uri);
21
+ }
22
+ if (result === null || result === undefined) {
23
+ log.error("File", uri, "wasn't in document map when we expected it to be");
24
+ return null;
25
+ }
26
+ return result;
14
27
  }
15
28
  async updateConfiguration(config) {
16
29
  this.languageService.update_configuration(config);
@@ -32,13 +45,12 @@ export class QSharpLanguageService {
32
45
  delete this.code[documentUri];
33
46
  this.languageService.close_document(documentUri);
34
47
  }
35
- async closeNotebookDocument(documentUri, cellUris) {
36
- cellUris.forEach((uri) => delete this.code[uri]);
37
- this.languageService.close_notebook_document(documentUri, cellUris);
48
+ async closeNotebookDocument(documentUri) {
49
+ this.languageService.close_notebook_document(documentUri);
38
50
  }
39
51
  async getCompletions(documentUri, offset) {
40
- const code = this.code[documentUri];
41
- if (code === undefined) {
52
+ const code = await this.loadFile(documentUri);
53
+ if (code === null) {
42
54
  log.error(`getCompletions: expected ${documentUri} to be in the document map`);
43
55
  return { items: [] };
44
56
  }
@@ -50,8 +62,8 @@ export class QSharpLanguageService {
50
62
  return result;
51
63
  }
52
64
  async getHover(documentUri, offset) {
53
- const code = this.code[documentUri];
54
- if (code === undefined) {
65
+ const code = await this.loadFile(documentUri);
66
+ if (code === null) {
55
67
  log.error(`getHover: expected ${documentUri} to be in the document map`);
56
68
  return undefined;
57
69
  }
@@ -63,22 +75,22 @@ export class QSharpLanguageService {
63
75
  return result;
64
76
  }
65
77
  async getDefinition(documentUri, offset) {
66
- const sourceCode = this.code[documentUri];
67
- if (sourceCode === undefined) {
78
+ const sourceCode = await this.loadFile(documentUri);
79
+ if (sourceCode === undefined || sourceCode === null) {
68
80
  log.error(`getDefinition: expected ${documentUri} to be in the document map`);
69
81
  return undefined;
70
82
  }
71
83
  const convertedOffset = mapUtf16UnitsToUtf8Units([offset], sourceCode)[offset];
72
84
  const result = this.languageService.get_definition(documentUri, convertedOffset);
73
85
  if (result) {
74
- let targetCode = this.code[result.source];
75
- if (targetCode === undefined) {
86
+ let targetCode = (await this.loadFile(result.source)) || null;
87
+ if (targetCode === null) {
76
88
  // Inspect the URL protocol (equivalent to the URI scheme + ":").
77
89
  // If the scheme is our library scheme, we need to call the wasm to
78
90
  // provide the library file's contents to do the utf8->utf16 mapping.
79
91
  const url = new URL(result.source);
80
92
  if (url.protocol === qsharpLibraryUriScheme + ":") {
81
- targetCode = wasm.get_library_source_content(url.pathname);
93
+ targetCode = wasm.get_library_source_content(url.pathname) || null;
82
94
  if (targetCode === undefined) {
83
95
  log.error(`getDefinition: expected ${url} to be in the library`);
84
96
  return undefined;
@@ -96,8 +108,8 @@ export class QSharpLanguageService {
96
108
  return result;
97
109
  }
98
110
  async getReferences(documentUri, offset, includeDeclaration) {
99
- const sourceCode = this.code[documentUri];
100
- if (sourceCode === undefined) {
111
+ const sourceCode = await this.loadFile(documentUri);
112
+ if (sourceCode === undefined || sourceCode === null) {
101
113
  log.error(`getReferences: expected ${documentUri} to be in the document map`);
102
114
  return [];
103
115
  }
@@ -106,13 +118,13 @@ export class QSharpLanguageService {
106
118
  if (results && results.length > 0) {
107
119
  const references = [];
108
120
  for (const result of results) {
109
- let resultCode = this.code[result.source];
121
+ let resultCode = await this.loadFile(result.source);
110
122
  // Inspect the URL protocol (equivalent to the URI scheme + ":").
111
123
  // If the scheme is our library scheme, we need to call the wasm to
112
124
  // provide the library file's contents to do the utf8->utf16 mapping.
113
125
  const url = new URL(result.source);
114
126
  if (url.protocol === qsharpLibraryUriScheme + ":") {
115
- resultCode = wasm.get_library_source_content(url.pathname);
127
+ resultCode = wasm.get_library_source_content(url.pathname) || null;
116
128
  if (resultCode === undefined) {
117
129
  log.error(`getReferences: expected ${url} to be in the library`);
118
130
  }
@@ -133,8 +145,8 @@ export class QSharpLanguageService {
133
145
  }
134
146
  }
135
147
  async getSignatureHelp(documentUri, offset) {
136
- const code = this.code[documentUri];
137
- if (code === undefined) {
148
+ const code = await this.loadFile(documentUri);
149
+ if (code === null) {
138
150
  log.error(`expected ${documentUri} to be in the document map`);
139
151
  return undefined;
140
152
  }
@@ -152,8 +164,8 @@ export class QSharpLanguageService {
152
164
  return result;
153
165
  }
154
166
  async getRename(documentUri, offset, newName) {
155
- const code = this.code[documentUri];
156
- if (code === undefined) {
167
+ const code = await this.loadFile(documentUri);
168
+ if (code === null) {
157
169
  log.error(`expected ${documentUri} to be in the document map`);
158
170
  return undefined;
159
171
  }
@@ -161,7 +173,7 @@ export class QSharpLanguageService {
161
173
  const result = this.languageService.get_rename(documentUri, convertedOffset, newName);
162
174
  const mappedChanges = [];
163
175
  for (const [uri, edits] of result.changes) {
164
- const code = this.code[uri];
176
+ const code = await this.loadFile(uri);
165
177
  if (code) {
166
178
  const mappedEdits = edits.map((edit) => {
167
179
  updateSpanFromUtf8ToUtf16(edit.range, code);
@@ -174,8 +186,8 @@ export class QSharpLanguageService {
174
186
  return result;
175
187
  }
176
188
  async prepareRename(documentUri, offset) {
177
- const code = this.code[documentUri];
178
- if (code === undefined) {
189
+ const code = await this.loadFile(documentUri);
190
+ if (code === null) {
179
191
  log.error(`expected ${documentUri} to be in the document map`);
180
192
  return undefined;
181
193
  }
@@ -187,6 +199,8 @@ export class QSharpLanguageService {
187
199
  return result;
188
200
  }
189
201
  async dispose() {
202
+ this.languageService.stop_background_work();
203
+ await this.backgroundWork;
190
204
  this.languageService.free();
191
205
  }
192
206
  addEventListener(type, listener) {
@@ -195,18 +209,21 @@ export class QSharpLanguageService {
195
209
  removeEventListener(type, listener) {
196
210
  this.eventHandler.removeEventListener(type, listener);
197
211
  }
198
- onDiagnostics(uri, version, diagnostics) {
212
+ async onDiagnostics(uri, version, diagnostics) {
199
213
  try {
200
- const code = this.code[uri];
214
+ const code = await this.loadFile(uri);
201
215
  const empty = diagnostics.length === 0;
202
- if (code === undefined && !empty) {
216
+ if (code === null && !empty) {
203
217
  // We need the contents of the document to convert error offsets to utf16.
204
218
  // But the contents aren't available after a document is closed.
205
- // It is possible to get a diagnostics event after a document is closed,
206
- // but it will be done with an empty array, to clear the diagnostics.
207
- // In that case, it's ok not to have the document contents available,
208
- // because there are no offsets to convert.
209
- log.error(`onDiagnostics: expected ${uri} to be in the document map`);
219
+ // It is possible to get diagnostics events for a document after it's been closed,
220
+ // since document events are handled asynchronously by the language service.
221
+ // We just drop those diagnostics, assuming that eventually we will receive further
222
+ // events that will bring the diagnostics up to date.
223
+ // However, if we receive an *empty* array of diagnostics for a document, we don't want
224
+ // to drop that update. It's necessary for the diagnostics to get cleared for a document
225
+ // that has been closed.
226
+ log.warn(`onDiagnostics: received diagnostics for ${uri} which is not in the document map`);
210
227
  return;
211
228
  }
212
229
  const event = new Event("diagnostics");
package/dist/main.d.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import { ICompiler, ICompilerWorker } from "./compiler/compiler.js";
2
2
  import { ILanguageService, ILanguageServiceWorker, qsharpLibraryUriScheme } from "./language-service/language-service.js";
3
3
  import { IDebugService, IDebugServiceWorker } from "./debug-service/debug-service.js";
4
+ import { ProjectLoader } from "../lib/node/qsc_wasm.cjs";
4
5
  export { qsharpLibraryUriScheme };
5
6
  export declare function getLibrarySourceContent(path: string): Promise<string | undefined>;
6
7
  export declare function getCompiler(): ICompiler;
8
+ export declare function getProjectLoader(readFile: (path: string) => Promise<string | null>, loadDirectory: (path: string) => Promise<[string, number][]>, getManifest: (path: string) => Promise<{
9
+ manifestDirectory: string;
10
+ } | null>): ProjectLoader;
7
11
  export declare function getCompilerWorker(): ICompilerWorker;
8
12
  export declare function getDebugService(): IDebugService;
9
13
  export declare function getDebugServiceWorker(): IDebugServiceWorker;
10
- export declare function getLanguageService(): ILanguageService;
14
+ export declare function getLanguageService(readFile?: (uri: string) => Promise<string | null>, listDir?: (uri: string) => Promise<[string, number][]>, getManifest?: (uri: string) => Promise<{
15
+ manifestDirectory: string;
16
+ } | null>): ILanguageService;
11
17
  export declare function getLanguageServiceWorker(): ILanguageServiceWorker;
package/dist/main.js CHANGED
@@ -31,6 +31,15 @@ export function getCompiler() {
31
31
  }
32
32
  return new Compiler(wasm);
33
33
  }
34
+ export function getProjectLoader(readFile, loadDirectory, getManifest) {
35
+ if (!wasm) {
36
+ wasm = require("../lib/node/qsc_wasm.cjs");
37
+ // Set up logging and telemetry as soon as possible after instantiating
38
+ wasm.initLogging(log.logWithLevel, log.getLogLevel());
39
+ log.onLevelChanged = (level) => wasm?.setLogLevel(level);
40
+ }
41
+ return new wasm.ProjectLoader(readFile, loadDirectory, getManifest);
42
+ }
34
43
  export function getCompilerWorker() {
35
44
  const thisDir = dirname(fileURLToPath(import.meta.url));
36
45
  const worker = new Worker(join(thisDir, "./compiler/worker-node.js"), {
@@ -62,10 +71,10 @@ export function getDebugServiceWorker() {
62
71
  worker.addListener("message", proxy.onMsgFromWorker);
63
72
  return proxy;
64
73
  }
65
- export function getLanguageService() {
74
+ export function getLanguageService(readFile, listDir, getManifest) {
66
75
  if (!wasm)
67
76
  wasm = require("../lib/node/qsc_wasm.cjs");
68
- return new QSharpLanguageService(wasm);
77
+ return new QSharpLanguageService(wasm, readFile, listDir, getManifest);
69
78
  }
70
79
  export function getLanguageServiceWorker() {
71
80
  const thisDir = dirname(fileURLToPath(import.meta.url));