From 26d78129faf0c9a6b1b8fbf848ca5ee78bcdaea2 Mon Sep 17 00:00:00 2001 From: Orta Date: Fri, 21 Aug 2020 07:43:59 -0400 Subject: [PATCH] Add support for creating a custom webworker subclass --- src/monaco.contribution.ts | 19 +++- src/monaco.d.ts | 4 + src/tsWorker.ts | 21 +++- src/workerManager.ts | 3 +- test/custom-worker.html | 211 +++++++++++++++++++++++++++++++++++++ test/custom-worker.js | 9 ++ 6 files changed, 262 insertions(+), 5 deletions(-) create mode 100644 test/custom-worker.html create mode 100644 test/custom-worker.js diff --git a/src/monaco.contribution.ts b/src/monaco.contribution.ts index c038d4b5..a26b7e2a 100644 --- a/src/monaco.contribution.ts +++ b/src/monaco.contribution.ts @@ -31,13 +31,15 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript. private _eagerModelSync: boolean; private _compilerOptions!: monaco.languages.typescript.CompilerOptions; private _diagnosticsOptions!: monaco.languages.typescript.DiagnosticsOptions; + private _workerOptions!: monaco.languages.typescript.WorkerOptions; private _onDidExtraLibsChangeTimeout: number; - constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions) { + constructor(compilerOptions: monaco.languages.typescript.CompilerOptions, diagnosticsOptions: monaco.languages.typescript.DiagnosticsOptions, workerOptions: monaco.languages.typescript.WorkerOptions) { this._extraLibs = Object.create(null); this._eagerModelSync = false; this.setCompilerOptions(compilerOptions); this.setDiagnosticsOptions(diagnosticsOptions); + this.setWorkerOptions(workerOptions) this._onDidExtraLibsChangeTimeout = -1; } @@ -49,6 +51,10 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript. return this._onDidExtraLibsChange.event; } + get workerOptions(): monaco.languages.typescript.WorkerOptions { + return this._workerOptions + } + getExtraLibs(): IExtraLibs { return this._extraLibs; } @@ -142,6 +148,11 @@ export class LanguageServiceDefaultsImpl implements monaco.languages.typescript. this._onDidChange.fire(undefined); } + setWorkerOptions(options: monaco.languages.typescript.WorkerOptions): void { + this._workerOptions = options || Object.create(null); + this._onDidChange.fire(undefined); + } + setMaximumWorkerIdleTime(value: number): void { } @@ -202,11 +213,13 @@ enum ModuleResolutionKind { const typescriptDefaults = new LanguageServiceDefaultsImpl( { allowNonTsExtensions: true, target: ScriptTarget.Latest }, - { noSemanticValidation: false, noSyntaxValidation: false }); + { noSemanticValidation: false, noSyntaxValidation: false }, + {}); const javascriptDefaults = new LanguageServiceDefaultsImpl( { allowNonTsExtensions: true, allowJs: true, target: ScriptTarget.Latest }, - { noSemanticValidation: true, noSyntaxValidation: false }); + { noSemanticValidation: true, noSyntaxValidation: false }, + {}); function getTypeScriptWorker(): Promise<(...uris: monaco.Uri[]) => Promise> { return getMode().then(mode => mode.getTypeScriptWorker()); diff --git a/src/monaco.d.ts b/src/monaco.d.ts index 1e99b41b..698ce738 100644 --- a/src/monaco.d.ts +++ b/src/monaco.d.ts @@ -137,6 +137,10 @@ declare module monaco.languages.typescript { diagnosticCodesToIgnore?: number[]; } + export interface WorkerOptions { + customWorkerPath?: string; + } + interface IExtraLib { content: string; version: number; diff --git a/src/tsWorker.ts b/src/tsWorker.ts index e5560f86..a7e012db 100644 --- a/src/tsWorker.ts +++ b/src/tsWorker.ts @@ -238,8 +238,27 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, monaco.language export interface ICreateData { compilerOptions: ts.CompilerOptions; extraLibs: IExtraLibs; + customWorkerPath?: string } export function create(ctx: IWorkerContext, createData: ICreateData): TypeScriptWorker { - return new TypeScriptWorker(ctx, createData); + let TSWorkerClass = TypeScriptWorker + if (createData.customWorkerPath) { + + // @ts-ignore - This is available in a webworker + if (typeof importScripts === "undefined") { + console.warn("Monaco is not using webworker workers, and that is needed to support the customWorkerPath flag") + } else { + // @ts-ignore - This is available in a webworker + importScripts(createData.customWorkerPath) + // @ts-ignore - This should come from + if(!self.extendTSWorkerFactory) { + throw new Error(`The script at ${createData.customWorkerPath} does not add extendTSWorkerFactory to self`) + } + // @ts-ignore - The throw validates this + TSWorkerClass = self.extendTSWorkerFactory(TypeScriptWorker) + } + } + + return new TSWorkerClass(ctx, createData); } diff --git a/src/workerManager.ts b/src/workerManager.ts index ff0b560e..fe6e2455 100644 --- a/src/workerManager.ts +++ b/src/workerManager.ts @@ -72,7 +72,8 @@ export class WorkerManager { // passed in to the create() method createData: { compilerOptions: this._defaults.getCompilerOptions(), - extraLibs: this._defaults.getExtraLibs() + extraLibs: this._defaults.getExtraLibs(), + customWorkerPath: this._defaults.workerOptions.customWorkerPath } }); diff --git a/test/custom-worker.html b/test/custom-worker.html new file mode 100644 index 00000000..fcaceaf3 --- /dev/null +++ b/test/custom-worker.html @@ -0,0 +1,211 @@ + + + + + + + + + +

Monaco Editor TypeScript test page

+ +
+

Compiler settings

+
+ + + + + + + + + + diff --git a/test/custom-worker.js b/test/custom-worker.js new file mode 100644 index 00000000..ad3c8dfd --- /dev/null +++ b/test/custom-worker.js @@ -0,0 +1,9 @@ +/// + +console.log("worker") + +self.extendTSWorkerFactory = (TypeScriptWorker) => { + return class MonacoTSWorker extends TypeScriptWorker { + + } +}