Skip to content

Commit 1fd8592

Browse files
aparzicrisbeto
authored andcommitted
refactor: inject an instance of typescript-vfs.worker
Modified tsVfsWorker worker initialization logic (cherry picked from commit e155a1e)
1 parent 6daabb0 commit 1fd8592

4 files changed

Lines changed: 53 additions & 8 deletions

File tree

adev/src/app/app.config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {ContentLoader} from './core/services/content-loader.service';
3232
import {CustomErrorHandler} from './core/services/errors-handling/error-handler';
3333
import {ExampleContentLoader} from './core/services/example-content-loader.service';
3434
import {routerProviders} from './routing/router_providers';
35+
import {TYPESCRIPT_VFS_WORKER_PROVIDER} from './editor/code-editor/workers/factory-provider';
3536

3637
export const appConfig: ApplicationConfig = {
3738
providers: [
@@ -51,5 +52,6 @@ export const appConfig: ApplicationConfig = {
5152
useFactory: (document: Document) => windowProvider(document),
5253
deps: [DOCUMENT],
5354
},
55+
TYPESCRIPT_VFS_WORKER_PROVIDER,
5456
],
5557
};

adev/src/app/editor/code-editor/code-mirror-editor.service.spec.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {EmbeddedTutorialManager} from '../embedded-tutorial-manager.service';
1717

1818
import {CodeMirrorEditor, EDITOR_CONTENT_CHANGE_DELAY_MILLIES} from './code-mirror-editor.service';
1919
import {TutorialConfig, TutorialMetadata} from '@angular/docs';
20+
import {TYPESCRIPT_VFS_WORKER_FACTORY} from './workers/factory-provider';
2021

2122
class FakeNodeRuntimeSandbox {
2223
async writeFile(path: string, content: string) {}
@@ -64,8 +65,16 @@ export class FakeEmbeddedTutorialManager {
6465
}
6566
}
6667

68+
class MockWorker {
69+
addEventListener = jasmine.createSpy('addEventListener');
70+
postMessage = jasmine.createSpy('postMessage');
71+
removeEventListener = jasmine.createSpy('removeEventListener');
72+
terminate = jasmine.createSpy('terminate');
73+
}
74+
6775
describe('CodeMirrorEditor', () => {
6876
let service: CodeMirrorEditor;
77+
let mockWorker: MockWorker;
6978

7079
const fakeNodeRuntimeSandbox = new FakeNodeRuntimeSandbox();
7180
const fakeEmbeddedTutorialManager = new FakeEmbeddedTutorialManager();
@@ -80,13 +89,19 @@ describe('CodeMirrorEditor', () => {
8089
}
8190

8291
beforeEach(() => {
92+
mockWorker = new MockWorker();
93+
8394
TestBed.configureTestingModule({
8495
providers: [
8596
CodeMirrorEditor,
8697
{
8798
provide: NodeRuntimeSandbox,
8899
useValue: fakeNodeRuntimeSandbox,
89100
},
101+
{
102+
provide: TYPESCRIPT_VFS_WORKER_FACTORY,
103+
useValue: () => mockWorker as unknown as Worker,
104+
},
90105
{
91106
provide: EmbeddedTutorialManager,
92107
useValue: fakeEmbeddedTutorialManager,

adev/src/app/editor/code-editor/code-mirror-editor.service.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {TsVfsWorkerActions} from './workers/enums/actions';
2929
import {CodeChangeRequest} from './workers/interfaces/code-change-request';
3030
import {ActionMessage} from './workers/interfaces/message';
3131
import {NodeRuntimeState} from '../node-runtime-state.service';
32+
import {TYPESCRIPT_VFS_WORKER_FACTORY} from './workers/factory-provider';
3233

3334
export interface EditorFile {
3435
filename: string;
@@ -71,7 +72,6 @@ export class CodeMirrorEditor {
7172

7273
// An instance of web worker used to run virtual TypeScript environment in the browser.
7374
// It allows to enrich CodeMirror UX for TypeScript files.
74-
private tsVfsWorker: Worker | null = null;
7575
// EventManager gives ability to communicate between tsVfsWorker and CodeMirror instance
7676
private readonly eventManager$ = new Subject<ActionMessage>();
7777

@@ -81,6 +81,8 @@ export class CodeMirrorEditor {
8181
private readonly typingsLoader = inject(TypingsLoader);
8282
private readonly destroyRef = inject(DestroyRef);
8383
private readonly diagnosticsState = inject(DiagnosticsState);
84+
private readonly tsVfsWorkerFactory = inject(TYPESCRIPT_VFS_WORKER_FACTORY);
85+
private tsVfsWorker: Worker | null = null;
8486

8587
private _editorView: EditorView | null = INITIAL_STATES._editorView;
8688
private readonly _editorStates = new Map<EditorFile['filename'], EditorState>();
@@ -182,14 +184,11 @@ export class CodeMirrorEditor {
182184
}
183185

184186
private initTypescriptVfsWorker(): void {
185-
if (this.tsVfsWorker) {
187+
if (this.tsVfsWorker || !this.tsVfsWorkerFactory) {
186188
return;
187189
}
188190

189-
this.tsVfsWorker = new Worker(new URL('./workers/typescript-vfs.worker', import.meta.url), {
190-
type: 'module',
191-
});
192-
191+
this.tsVfsWorker = this.tsVfsWorkerFactory();
193192
this.tsVfsWorker.addEventListener('message', ({data}: MessageEvent<ActionMessage>) => {
194193
this.eventManager$.next(data);
195194
});
@@ -214,10 +213,13 @@ export class CodeMirrorEditor {
214213

215214
// Method is responsible for sending request to Typescript VFS worker.
216215
private sendRequestToTsVfs = <T>(request: ActionMessage<T>) => {
217-
if (!this.tsVfsWorker) return;
216+
if (!this.tsVfsWorker) {
217+
console.warn('TypeScript VFS worker not available');
218+
return;
219+
}
218220

219221
// Send message to tsVfsWorker only when current file is TypeScript file.
220-
if (!this.currentFile().filename.endsWith('.ts')) return;
222+
if (!this.currentFile()?.filename.endsWith('.ts')) return;
221223

222224
this.tsVfsWorker.postMessage(request);
223225
};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*!
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {InjectionToken, Provider} from '@angular/core';
10+
11+
export type TypescriptVfsWorkerFactory = () => Worker;
12+
13+
export const TYPESCRIPT_VFS_WORKER_FACTORY = new InjectionToken<TypescriptVfsWorkerFactory>(
14+
'TYPESCRIPT_VFS_WORKER_FACTORY',
15+
);
16+
17+
export function createTypescriptVfsWorker(): Worker {
18+
return new Worker(new URL('./typescript-vfs.worker.ts', import.meta.url), {
19+
type: 'module',
20+
});
21+
}
22+
23+
export const TYPESCRIPT_VFS_WORKER_PROVIDER: Provider = {
24+
provide: TYPESCRIPT_VFS_WORKER_FACTORY,
25+
useValue: createTypescriptVfsWorker,
26+
};

0 commit comments

Comments
 (0)