Skip to content

Export custom TypeScript worker variables#3488

Merged
hediet merged 2 commits intomicrosoft:mainfrom
remcohaszing:export-typescript-worker-members
Jul 7, 2023
Merged

Export custom TypeScript worker variables#3488
hediet merged 2 commits intomicrosoft:mainfrom
remcohaszing:export-typescript-worker-members

Conversation

@remcohaszing
Copy link
Copy Markdown
Contributor

A custom TypeScript worker factory function gets passed TypeScriptWorker, ts, and libFileMap. It also exports create using ESM. However, this can’t be used, because the custom worker factory is only called if a custom worker path is defined.

Exposing these members, means a worker can be defined using ESM.

A practical use case:

/**
 * @typedef {import('monaco-editor').languages.typescript.CompilerOptions} CompilerOptions
 * @typedef {import('monaco-editor').languages.typescript.IExtraLibs} IExtraLibs
 * @typedef {import('monaco-editor').languages.typescript.InlayHintsOptions} InlayHintsOptions
 * @typedef {import('monaco-editor').languages.typescript.TypeScriptWorker} TypeScriptWorker
 * @typedef {import('monaco-editor').worker.IWorkerContext} IWorkerContext
 * @typedef {import('typescript').LanguageServiceHost} LanguageServiceHost
 *
 * @typedef {object} CreateData
 * @property {CompilerOptions} compilerOptions The TypeScript compiler options configured by the user.
 * @property {string} customWorkerPath The path to a custom worker.
 * @property {IExtraLibs} extraLibs Additional libraries to load.
 * @property {InlayHintsOptions} inlayHintsOptions The TypeScript inlay hints options.
 *
 * @typedef {TypeScriptWorker & LanguageServiceHost} MDXWorker
 * @typedef {new (ctx: IWorkerContext, createData: CreateData) => MDXWorker} TypeScriptWorkerClass
 */

import {createMdxLanguageService} from '@mdx-js/language-service'
// @ts-expect-error This module is untyped.
import {initialize} from 'monaco-editor/esm/vs/editor/editor.worker.js'
// @ts-expect-error This module is untyped.
import {create} from 'monaco-editor/esm/vs/language/typescript/ts.worker.js'

/**
 * @param {TypeScriptWorkerClass} TypeScriptWorker
 * @returns {TypeScriptWorkerClass} A custom TypeScript worker which knows how to handle MDX.
 */
function worker(TypeScriptWorker) {
  return class MDXWorker extends TypeScriptWorker {
    _languageService = createMdxLanguageService(
      // @ts-expect-error This is globally defined in the worker.
      ts,
      this
    )
  }
}

// @ts-expect-error This is missing in the Monaco type definitions.
self.customTSWorkerFactory = worker

// Trick the TypeScript worker into using the `customTSWorkerFactory`
self.importScripts = () => {}

self.onmessage = () => {
  initialize(
    /**
     * @param {IWorkerContext} ctx
     * @param {CreateData} createData
     * @returns {MDXWorker} The MDX TypeScript worker.
     */
    (ctx, createData) => create(ctx, {...createData, customWorkerPath: true})
  )
}

becomes:

/**
 * @typedef {import('monaco-editor').languages.typescript.CompilerOptions} CompilerOptions
 * @typedef {import('monaco-editor').languages.typescript.IExtraLibs} IExtraLibs
 * @typedef {import('monaco-editor').languages.typescript.InlayHintsOptions} InlayHintsOptions
 * @typedef {import('monaco-editor').languages.typescript.TypeScriptWorker} TypeScriptWorker
 * @typedef {import('monaco-editor').worker.IWorkerContext} IWorkerContext
 *
 * @typedef {object} CreateData
 * @property {CompilerOptions} compilerOptions The TypeScript compiler options configured by the user.
 * @property {string} customWorkerPath The path to a custom worker.
 * @property {IExtraLibs} extraLibs Additional libraries to load.
 * @property {InlayHintsOptions} inlayHintsOptions The TypeScript inlay hints options.
 */

import {createMdxLanguageService} from '@mdx-js/language-service'
import {
  initialize,
  ts,
  TypeScriptWorker
  // @ts-expect-error This module is untyped.
} from 'monaco-editor/esm/vs/language/typescript/ts.worker.js'

class MDXWorker extends TypeScriptWorker {
  _languageService = createMdxLanguageService(
    ts,
    // @ts-expect-error This is missing in the Monaco type definitions.
    this
  )
}

self.onmessage = () => {
  initialize(
    /**
     * @param {IWorkerContext} ctx
     * @param {CreateData} createData
     * @returns {MDXWorker} The MDX TypeScript worker.
     */
    (ctx, createData) =>
      // @ts-expect-error This is missing in the Monaco type definitions.
      new MDXWorker(ctx, createData)
  )
}

A custom TypeScript worker factory function gets passed
`TypeScriptWorker`, `ts`, and `libFileMap`. It also exports `create`
using ESM. However, this can’t be used, because the custom worker
factory is only called if a custom worker path is defined.

Exposing these members, means a worker can be defined using ESM.
@hediet hediet enabled auto-merge July 7, 2023 15:49
@hediet
Copy link
Copy Markdown
Member

hediet commented Jul 7, 2023

Thanks for the PR! Sorry for not looking at it early.

@hediet hediet merged commit f191382 into microsoft:main Jul 7, 2023
jakebailey added a commit to jakebailey/monaco-editor that referenced this pull request Aug 4, 2023
…pescript-worker-members"

This reverts commit f191382, reversing
changes made to 0365f0e.
@github-actions github-actions bot locked and limited conversation to collaborators Aug 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants