-
Notifications
You must be signed in to change notification settings - Fork 90
Add support for creating a custom webworker subclass #65
Conversation
Coming back to look at this, I've settled on |
@ark120202 mentioned in the ts discord that for the ts2lua playground, they bundle a custom webworker by setting This is a cool tactic, and maybe I could get this working using that API entirely. Without digging into it yet, I think the hard bit looks to be how to get access to the original |
👍 I've seen lots of people in issues ask for something like this. Both approaches have advantages and disadvantages. For the ESM bits, our webpack bundler plugin wants to own My concern is more on the API side. What can we type in a |
I was going to add a public API interface for the worker, which the class implements but there are already type definitions for the public API for the TS worker in If the class breaks that public API, then it's a breaking change for downstream consumers of this method, which _ I think_ should be enough. If you'd like a test for that via the compiler, I can duplicate the interface separately and have that be used to validate the class conforms to an unchanging interface? |
I thought the custom worker proposed here would be useful for people to interact directly with the ts service. |
Great point, I'll expand this demo with some of the TS infra I was expecting to use ( microsoft/TypeScript-Website#998 ) and pass in the worker's version of TS to the factory function to give it a real world example |
OK, I've got a non-trivial example now running. This is in the same ballpark as what I'd use in the TS playground (but without caching the program etc.) In the web-worker it creates a fully virtual FS, makes a TS program, extracts the AST of the editor's text as a string and passes that back to the site which logs it out. I'd class the api shape of the factory function as Monaco-typescript's public API, and so I've used: /** The shape of the factory */
export interface CustomTSWebWorkerFactory {
(TSWorkerClass: typeof TypeScriptWorker, ts: typeof import("typescript"), libs: Record<string, string>): typeof TypeScriptWorker
} As a check that we keep our side of that contract. It also means folks can use that type themselves like I do via JSDoc etc. |
18b0f5d
to
5ee395c
Compare
👍 Makes good sense! |
Hello, Can this API be used to create an ambient context in typescript? Much like how you have you see a *.d.ts files in VSCode. If so how? |
return (firstDTS && firstDTS.text) || "" | ||
} | ||
|
||
async printAST(fileName) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@orta this is a very nice example that might come handy to me, thank you for that! I'm wondering though - isn't there a way to just access the existing program? Recreating it like here seems like an overkill for what I need - especially that I'd have to learn how to properly configure it in the very same way that it's done by default and it's easy to do some mistakes in that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it can use this._langaugeService.getProgram
to grab it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exactly what I ended up doing:
https://github.com/statelyai/xstate-viz/blob/cd128a15486d9253edaaa360ee6c1b150f293f5c/public/ts-worker.js#L59
but it's not a part of the public interface so feels like a hack. I wonder if this could be added as part of the public API?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave that one to @alexdima to decide, but I'm also reaching in for it in microsoft/TypeScript-Website#2063 - which is a pretty good argument for moving it out of private IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR welcome.
It had been on my TODO to explore this for a while, but a chat with @evmar yesterday reminded me that I should take a look
This PR allows Monaco users to extend the
TypeScriptWorker
class used to handle web workers in their own code without having to dig into internals of Monaco.How it works
It adds a new option (which I'm open to bike shedding on naming, I just wanted something) to the language defaults:
This is used to synchronously call that URL in a webworker, with the JS expecting to edit the global scope of the worker adding a factory function:
Users can then make calls to the worker using the same APIs as previously:
This can be used to extend the web worker for setups where you do some heavy processing, but want to keep that backgrounded.