@pierre/diffs 1.6.0-beta.1 → 1.6.0

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.
Files changed (151) hide show
  1. package/dist/components/CodeView.d.ts +3 -2
  2. package/dist/components/CodeView.d.ts.map +1 -1
  3. package/dist/components/CodeView.js +18 -14
  4. package/dist/components/CodeView.js.map +1 -1
  5. package/dist/components/File.d.ts +31 -9
  6. package/dist/components/File.d.ts.map +1 -1
  7. package/dist/components/File.js +165 -84
  8. package/dist/components/File.js.map +1 -1
  9. package/dist/components/FileDiff.d.ts +32 -9
  10. package/dist/components/FileDiff.d.ts.map +1 -1
  11. package/dist/components/FileDiff.js +213 -124
  12. package/dist/components/FileDiff.js.map +1 -1
  13. package/dist/components/UnresolvedFile.d.ts +14 -4
  14. package/dist/components/UnresolvedFile.d.ts.map +1 -1
  15. package/dist/components/UnresolvedFile.js +35 -16
  16. package/dist/components/UnresolvedFile.js.map +1 -1
  17. package/dist/components/VirtualizedFile.d.ts +3 -2
  18. package/dist/components/VirtualizedFile.d.ts.map +1 -1
  19. package/dist/components/VirtualizedFile.js +28 -20
  20. package/dist/components/VirtualizedFile.js.map +1 -1
  21. package/dist/components/VirtualizedFileDiff.d.ts +3 -2
  22. package/dist/components/VirtualizedFileDiff.d.ts.map +1 -1
  23. package/dist/components/VirtualizedFileDiff.js +31 -24
  24. package/dist/components/VirtualizedFileDiff.js.map +1 -1
  25. package/dist/constants.d.ts +2 -1
  26. package/dist/constants.d.ts.map +1 -1
  27. package/dist/constants.js +2 -1
  28. package/dist/constants.js.map +1 -1
  29. package/dist/editor/platform.d.ts +1 -1
  30. package/dist/editor/platform.js +5 -4
  31. package/dist/editor/platform.js.map +1 -1
  32. package/dist/editor/selection.d.ts +2 -2
  33. package/dist/editor/selection.d.ts.map +1 -1
  34. package/dist/editor/selection.js +31 -6
  35. package/dist/editor/selection.js.map +1 -1
  36. package/dist/highlighter/shared_highlighter.d.ts +2 -1
  37. package/dist/highlighter/shared_highlighter.d.ts.map +1 -1
  38. package/dist/highlighter/shared_highlighter.js +2 -2
  39. package/dist/highlighter/shared_highlighter.js.map +1 -1
  40. package/dist/index.d.ts +10 -5
  41. package/dist/index.js +8 -3
  42. package/dist/react/CodeView.d.ts +4 -3
  43. package/dist/react/CodeView.d.ts.map +1 -1
  44. package/dist/react/CodeView.js +48 -39
  45. package/dist/react/CodeView.js.map +1 -1
  46. package/dist/react/File.js +3 -3
  47. package/dist/react/File.js.map +1 -1
  48. package/dist/react/FileDiff.js +3 -3
  49. package/dist/react/FileDiff.js.map +1 -1
  50. package/dist/react/MultiFileDiff.js +2 -2
  51. package/dist/react/MultiFileDiff.js.map +1 -1
  52. package/dist/react/PatchDiff.js +3 -3
  53. package/dist/react/PatchDiff.js.map +1 -1
  54. package/dist/react/UnresolvedFile.js +2 -2
  55. package/dist/react/UnresolvedFile.js.map +1 -1
  56. package/dist/react/index.d.ts +2 -2
  57. package/dist/react/types.d.ts +4 -2
  58. package/dist/react/types.d.ts.map +1 -1
  59. package/dist/react/utils/renderDiffChildren.js +1 -1
  60. package/dist/react/utils/renderDiffChildren.js.map +1 -1
  61. package/dist/react/utils/renderFileChildren.js +1 -1
  62. package/dist/react/utils/renderFileChildren.js.map +1 -1
  63. package/dist/react/utils/useFileDiffInstance.d.ts +1 -0
  64. package/dist/react/utils/useFileDiffInstance.d.ts.map +1 -1
  65. package/dist/react/utils/useFileDiffInstance.js +29 -24
  66. package/dist/react/utils/useFileDiffInstance.js.map +1 -1
  67. package/dist/react/utils/useFileInstance.d.ts +2 -0
  68. package/dist/react/utils/useFileInstance.d.ts.map +1 -1
  69. package/dist/react/utils/useFileInstance.js +38 -28
  70. package/dist/react/utils/useFileInstance.js.map +1 -1
  71. package/dist/react/utils/useForceUpdate.d.ts +5 -0
  72. package/dist/react/utils/useForceUpdate.d.ts.map +1 -0
  73. package/dist/react/utils/useForceUpdate.js +27 -0
  74. package/dist/react/utils/useForceUpdate.js.map +1 -0
  75. package/dist/react/utils/useNextRenderData.d.ts +9 -0
  76. package/dist/react/utils/useNextRenderData.d.ts.map +1 -0
  77. package/dist/react/utils/useNextRenderData.js +9 -0
  78. package/dist/react/utils/useNextRenderData.js.map +1 -0
  79. package/dist/react/utils/useUnresolvedFileInstance.d.ts +1 -0
  80. package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
  81. package/dist/react/utils/useUnresolvedFileInstance.js +26 -11
  82. package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
  83. package/dist/renderers/DiffHunksRenderer.d.ts +2 -1
  84. package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
  85. package/dist/renderers/DiffHunksRenderer.js +62 -32
  86. package/dist/renderers/DiffHunksRenderer.js.map +1 -1
  87. package/dist/renderers/FileRenderer.d.ts +4 -1
  88. package/dist/renderers/FileRenderer.d.ts.map +1 -1
  89. package/dist/renderers/FileRenderer.js +55 -30
  90. package/dist/renderers/FileRenderer.js.map +1 -1
  91. package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
  92. package/dist/renderers/UnresolvedFileHunksRenderer.js +1 -1
  93. package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
  94. package/dist/ssr/FileDiffReact.js +1 -1
  95. package/dist/types.d.ts +10 -0
  96. package/dist/types.d.ts.map +1 -1
  97. package/dist/utils/canUseWASM.d.ts +13 -0
  98. package/dist/utils/canUseWASM.d.ts.map +1 -0
  99. package/dist/utils/canUseWASM.js +59 -0
  100. package/dist/utils/canUseWASM.js.map +1 -0
  101. package/dist/utils/getCodeViewItemRenderData.d.ts +10 -0
  102. package/dist/utils/getCodeViewItemRenderData.d.ts.map +1 -0
  103. package/dist/utils/getCodeViewItemRenderData.js +19 -0
  104. package/dist/utils/getCodeViewItemRenderData.js.map +1 -0
  105. package/dist/utils/hastToHtml.d.ts +2 -2
  106. package/dist/utils/hastToHtml.js +2 -2
  107. package/dist/utils/hastToHtml.js.map +1 -1
  108. package/dist/utils/hydratePartialDiff.js +4 -0
  109. package/dist/utils/hydratePartialDiff.js.map +1 -1
  110. package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
  111. package/dist/utils/parseMergeConflictDiffFromFile.js +2 -0
  112. package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
  113. package/dist/utils/parsePatchFiles.d.ts.map +1 -1
  114. package/dist/utils/parsePatchFiles.js +24 -4
  115. package/dist/utils/parsePatchFiles.js.map +1 -1
  116. package/dist/utils/renderTokenLines.d.ts +6 -1
  117. package/dist/utils/renderTokenLines.d.ts.map +1 -1
  118. package/dist/utils/renderTokenLines.js +4 -0
  119. package/dist/utils/renderTokenLines.js.map +1 -1
  120. package/dist/utils/resolveRegion.js +20 -10
  121. package/dist/utils/resolveRegion.js.map +1 -1
  122. package/dist/utils/tokenStyle.d.ts +5 -1
  123. package/dist/utils/tokenStyle.d.ts.map +1 -1
  124. package/dist/utils/tokenStyle.js +5 -1
  125. package/dist/utils/tokenStyle.js.map +1 -1
  126. package/dist/utils/tokensToHtml.d.ts +5 -2
  127. package/dist/utils/tokensToHtml.d.ts.map +1 -1
  128. package/dist/utils/tokensToHtml.js +5 -2
  129. package/dist/utils/tokensToHtml.js.map +1 -1
  130. package/dist/utils/updateDiffHunks.d.ts +2 -2
  131. package/dist/utils/updateDiffHunks.d.ts.map +1 -1
  132. package/dist/utils/updateDiffHunks.js +7 -3
  133. package/dist/utils/updateDiffHunks.js.map +1 -1
  134. package/dist/worker/WorkerPoolManager.d.ts +12 -0
  135. package/dist/worker/WorkerPoolManager.d.ts.map +1 -1
  136. package/dist/worker/WorkerPoolManager.js +99 -21
  137. package/dist/worker/WorkerPoolManager.js.map +1 -1
  138. package/dist/worker/{highlights-sAHlxqlf.js → highlights-CpZm9DAR.js} +2 -2
  139. package/dist/worker/{highlights-sAHlxqlf.js.map → highlights-CpZm9DAR.js.map} +1 -1
  140. package/dist/worker/{shiki-Bx2JpdqZ.js → shiki-Ci4cdHsM.js} +2 -2
  141. package/dist/worker/{shiki-Bx2JpdqZ.js.map → shiki-Ci4cdHsM.js.map} +1 -1
  142. package/dist/worker/{stream-tokenizer-YZ6M1qSx.js → stream-tokenizer-DK9xp5M5.js} +8 -5
  143. package/dist/worker/stream-tokenizer-DK9xp5M5.js.map +1 -0
  144. package/dist/worker/types.d.ts +11 -0
  145. package/dist/worker/types.d.ts.map +1 -1
  146. package/dist/worker/worker-portable.js +2 -2
  147. package/dist/worker/worker-portable.js.map +1 -1
  148. package/dist/worker/worker.js +12 -3
  149. package/dist/worker/worker.js.map +1 -1
  150. package/package.json +28 -30
  151. package/dist/worker/stream-tokenizer-YZ6M1qSx.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WorkerPoolManager.js","names":[],"sources":["../../src/worker/WorkerPoolManager.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\nimport type { LRUMap } from 'lru_map';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { resolveHighlighterType } from '../highlighter/highlighterType';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport { getResolvedLanguages } from '../highlighter/languages/getResolvedLanguages';\nimport { hasResolvedLanguages } from '../highlighter/languages/hasResolvedLanguages';\nimport { resolveLanguages } from '../highlighter/languages/resolveLanguages';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n HighlighterDisposedError,\n} from '../highlighter/shared_highlighter';\nimport { getResolvedThemes } from '../highlighter/themes/getResolvedThemes';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport { resolveThemes } from '../highlighter/themes/resolveThemes';\nimport type {\n DiffsTheme,\n DiffsThemeNames,\n FileContents,\n FileDiffMetadata,\n HighlighterTypes,\n HunkExpansionRegion,\n RenderDiffOptions,\n RenderDiffResult,\n RenderFileOptions,\n RenderFileResult,\n SupportedLanguages,\n ThemedDiffResult,\n ThemedFileResult,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areFileRenderOptionsEqual } from '../utils/areFileRenderOptionsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport {\n getCustomExtensionsMap,\n getCustomExtensionsVersion,\n getFiletypeFromFileName,\n} from '../utils/getFiletypeFromFileName';\nimport { getThemes } from '../utils/getThemes';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport {\n isHandledWorkerPoolError,\n markWorkerErrorReported,\n WorkerPoolTaskCanceledError,\n WorkerPoolTerminatedError,\n WorkerPoolWorkerError,\n} from './errors';\nimport { decodeHastLines } from './hastLinesTransport';\nimport type {\n AllWorkerTasks,\n DiffRendererInstance,\n FileRendererInstance,\n InitializeWorkerRequest,\n InitializeWorkerTask,\n RenderDiffRequest,\n RenderDiffTask,\n RenderFileRequest,\n RenderFileTask,\n ResolvedLanguage,\n SetRenderOptionsWorkerTask,\n SubmitRequest,\n WorkerInitializationRenderOptions,\n WorkerPoolOptions,\n WorkerRenderingOptions,\n WorkerRequestId,\n WorkerStats,\n} from './types';\nimport type {\n InitializeWorkerWireRequest,\n WorkerWireResponse,\n} from './workerMessage';\n\nconst IGNORE_RESPONSE = Symbol('IGNORE_RESPONSE');\nconst DEFAULT_WORKER_INITIALIZATION_TIMEOUT = 10_000;\n\ninterface GetCachesResult {\n fileCache: LRUMap<string, RenderFileResult>;\n diffCache: LRUMap<string, RenderDiffResult>;\n}\n\ninterface ManagedWorker {\n worker: Worker;\n requestId: string | undefined;\n pendingSetupRequestId: WorkerRequestId | undefined;\n initialized: boolean;\n langs: Set<SupportedLanguages>;\n customExtensionsVersion: number;\n}\n\ninterface ThemeSubscriber {\n onThemeChange(): void;\n}\n\ntype RenderTask = RenderFileTask | RenderDiffTask;\n\ntype RenderTaskInstance = FileRendererInstance | DiffRendererInstance;\n\nexport class WorkerPoolManager {\n private readonly preferredHighlighter: HighlighterTypes;\n private renderOptions: WorkerRenderingOptions;\n private renderOptionsRequestVersion = 0;\n private renderOptionsVersion = 0;\n private initialized: Promise<void> | boolean = false;\n private workers: ManagedWorker[] = [];\n // Tasks that are waiting to get processed by a worker\n private queuedTasks: RenderTask[] = [];\n private queuedTaskByInstance = new Map<RenderTaskInstance, RenderTask>();\n\n // Tasks that map to highlightKey are essentially singular, so we only\n // need one map to include queued and active\n private taskByHighlightKey = new Map<string, RenderTask>();\n\n // Tasks that have already been sent to a worker and are awaiting a response.\n private activeTaskById = new Map<WorkerRequestId, AllWorkerTasks>();\n private activeRequestByInstance = new Map<\n RenderTaskInstance,\n WorkerRequestId\n >();\n\n private nextRequestId = 0;\n private themeSubscribers = new Set<ThemeSubscriber>();\n private workersFailed = false;\n private statSubscribers = new Set<(stats: WorkerStats) => unknown>();\n private fileCache: LRUMap<string, RenderFileResult>;\n private diffCache: LRUMap<string, RenderDiffResult>;\n private _queuedBroadcast: number | undefined;\n // Incremented on terminate so async lifecycle work can identify stale results.\n private lifecycleGeneration = 0;\n\n constructor(\n private options: WorkerPoolOptions,\n {\n langs,\n theme = DEFAULT_THEMES,\n useTokenTransformer = false,\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n tokenizeMaxLineLength = 1000,\n preferredHighlighter,\n }: WorkerInitializationRenderOptions\n ) {\n this.preferredHighlighter = resolveHighlighterType(preferredHighlighter);\n this.renderOptions = {\n theme,\n useTokenTransformer,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n this.fileCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.diffCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.queueInitialization(langs);\n }\n\n public isWorkingPool(): boolean {\n return !this.workersFailed;\n }\n\n public getFileResultCache(file: FileContents): RenderFileResult | undefined {\n return file.cacheKey != null\n ? this.fileCache.get(file.cacheKey)\n : undefined;\n }\n\n public getDiffResultCache(\n diff: FileDiffMetadata\n ): RenderDiffResult | undefined {\n return diff.cacheKey != null\n ? this.diffCache.get(diff.cacheKey)\n : undefined;\n }\n\n public inspectCaches(): GetCachesResult {\n const { fileCache, diffCache } = this;\n return { fileCache, diffCache };\n }\n\n public evictFileFromCache(cacheKey: string): boolean {\n try {\n return this.fileCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n public evictDiffFromCache(cacheKey: string): boolean {\n try {\n return this.diffCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n async setRenderOptions({\n theme = this.renderOptions.theme ?? DEFAULT_THEMES,\n useTokenTransformer = this.renderOptions.useTokenTransformer ?? false,\n lineDiffType = this.renderOptions.lineDiffType ?? 'word-alt',\n maxLineDiffLength = this.renderOptions.maxLineDiffLength ?? 1000,\n tokenizeMaxLineLength = this.renderOptions.tokenizeMaxLineLength ?? 1000,\n }: Partial<WorkerRenderingOptions>): Promise<void> {\n const { lifecycleGeneration } = this;\n const renderOptionsRequestVersion = ++this.renderOptionsRequestVersion;\n const isCurrentRequest = (): boolean =>\n this.isCurrentLifecycle(lifecycleGeneration) &&\n this.renderOptionsRequestVersion === renderOptionsRequestVersion;\n try {\n const newRenderOptions: WorkerRenderingOptions = {\n theme,\n useTokenTransformer,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n if (!this.isInitialized()) {\n await this.initialize();\n }\n if (\n !isCurrentRequest() ||\n areDiffRenderOptionsEqual(newRenderOptions, this.renderOptions)\n ) {\n return;\n }\n\n const themeNames = getThemes(theme);\n let resolvedThemes: DiffsTheme[] = [];\n if (!areThemesEqual(newRenderOptions.theme, this.renderOptions.theme)) {\n resolvedThemes = hasResolvedThemes(\n themeNames,\n this.preferredHighlighter\n )\n ? getResolvedThemes(themeNames, this.preferredHighlighter)\n : await resolveThemes(themeNames, this.preferredHighlighter);\n }\n\n if (!isCurrentRequest()) {\n return;\n }\n\n // Warning: resolvedThemes use the workers' backend. The main-thread\n // highlighter can be another backend, so it loads its own copies.\n if (getHighlighterIfLoaded({ theme }) == null) {\n await this.loadSharedHighlighter(themeNames, ['text']);\n if (!isCurrentRequest()) {\n return;\n }\n }\n\n const workerSetup = this.setRenderOptionsOnWorkers(\n newRenderOptions,\n resolvedThemes\n );\n\n this.renderOptions = newRenderOptions;\n this.renderOptionsVersion++;\n this.diffCache.clear();\n this.fileCache.clear();\n this.invalidateRenderTasks();\n\n for (const instance of this.themeSubscribers) {\n instance.onThemeChange();\n }\n\n await workerSetup;\n } catch (error) {\n if (error instanceof WorkerPoolTerminatedError || !isCurrentRequest()) {\n return;\n }\n throw error;\n }\n }\n\n public getPreferredHighlighter(): HighlighterTypes {\n return this.preferredHighlighter;\n }\n\n public getFileRenderOptions(): RenderFileOptions {\n const { tokenizeMaxLineLength, theme, useTokenTransformer } =\n this.renderOptions;\n return { theme, useTokenTransformer, tokenizeMaxLineLength };\n }\n\n public getDiffRenderOptions(): RenderDiffOptions {\n return { ...this.renderOptions };\n }\n\n private async setRenderOptionsOnWorkers(\n renderOptions: WorkerRenderingOptions,\n resolvedThemes: DiffsTheme[]\n ): Promise<void> {\n if (this.workersFailed) {\n return;\n }\n if (!this.isInitialized()) {\n await this.initialize();\n }\n const taskPromises: Promise<void>[] = [];\n for (const managedWorker of this.workers) {\n if (!managedWorker.initialized) {\n console.log({ managedWorker });\n throw new Error(\n 'setRenderOptionsOnWorkers: Somehow we have an uninitialized worker'\n );\n }\n taskPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: SetRenderOptionsWorkerTask = {\n type: 'set-render-options',\n id,\n request: {\n type: 'set-render-options',\n id,\n renderOptions,\n resolvedThemes,\n },\n resolve,\n reject,\n requestStart: Date.now(),\n };\n // Render-option updates are posted immediately, but the worker stays\n // unavailable for new render work until it acknowledges this message.\n this.activeTaskById.set(id, task);\n managedWorker.pendingSetupRequestId = id;\n managedWorker.worker.postMessage(task.request);\n })\n );\n }\n await Promise.all(taskPromises);\n }\n\n public subscribeToThemeChanges(instance: ThemeSubscriber): () => void {\n this.themeSubscribers.add(instance);\n this.queueBroadcastStateChanges();\n return () => {\n this.unsubscribeToThemeChanges(instance);\n this.queueBroadcastStateChanges();\n };\n }\n\n public unsubscribeToThemeChanges(instance: ThemeSubscriber): void {\n this.themeSubscribers.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n public subscribeToStatChanges(\n callback: (stats: WorkerStats) => unknown\n ): () => void {\n this.statSubscribers.add(callback);\n callback(this.getStats());\n return () => {\n this.statSubscribers.delete(callback);\n };\n }\n\n private queueBroadcastStateChanges() {\n if (this._queuedBroadcast != null) return;\n this._queuedBroadcast = requestAnimationFrame(this._broadcastStateChanges);\n }\n\n private _broadcastStateChanges = () => {\n if (this._queuedBroadcast != null) {\n cancelAnimationFrame(this._queuedBroadcast);\n this._queuedBroadcast = undefined;\n }\n const stats = this.getStats();\n for (const callback of this.statSubscribers) {\n callback(stats);\n }\n };\n\n public cleanUpTasks(instance: RenderTaskInstance): void {\n this.detachInstanceFromQueuedTasks(instance);\n const requestId = this.activeRequestByInstance.get(instance);\n if (requestId != null) {\n const task = this.activeTaskById.get(requestId);\n if (isRenderTask(task)) {\n this.detachInstanceFromRenderTask(task, instance);\n if (!task.primeCache && task.instances.size === 0) {\n this.removeActiveTask(task);\n }\n } else {\n this.activeTaskById.delete(requestId);\n }\n }\n this.activeRequestByInstance.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n public isInitialized(): boolean {\n return this.initialized === true;\n }\n\n public async initialize(languages: SupportedLanguages[] = []): Promise<void> {\n if (this.initialized === true) {\n if (getHighlighterIfLoaded({ theme: this.renderOptions.theme }) == null) {\n await this.loadSharedHighlighter(getThemes(this.renderOptions.theme), [\n 'text',\n ...languages,\n ]);\n }\n return;\n } else if (this.initialized === false) {\n const { lifecycleGeneration } = this;\n const initialization = new Promise<void>((resolve, reject) => {\n void (async () => {\n try {\n const themes = getThemes(this.renderOptions.theme);\n const resolvedThemes = hasResolvedThemes(\n themes,\n this.preferredHighlighter\n )\n ? getResolvedThemes(themes, this.preferredHighlighter)\n : await resolveThemes(themes, this.preferredHighlighter);\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n resolve();\n return;\n }\n\n let resolvedLanguages: ResolvedLanguage[] = [];\n if (this.preferredHighlighter !== 'highlights') {\n resolvedLanguages = hasResolvedLanguages(languages)\n ? getResolvedLanguages(languages)\n : await resolveLanguages(languages);\n }\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n resolve();\n return;\n }\n\n await Promise.all([\n this.loadSharedHighlighter(themes, ['text', ...languages]),\n this.initializeWorkers(resolvedThemes, resolvedLanguages),\n ]);\n\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n this.terminateWorkers();\n resolve();\n return;\n }\n this.initialized = true;\n this.diffCache.clear();\n this.fileCache.clear();\n this.drainQueue();\n this.queueBroadcastStateChanges();\n resolve();\n } catch (e) {\n if (\n e instanceof WorkerPoolTerminatedError ||\n !this.isCurrentLifecycle(lifecycleGeneration)\n ) {\n resolve();\n return;\n }\n this.initialized = false;\n this.workersFailed = true;\n // A partial pool is not supported, so stop every worker before\n // consumers rerender through the main-thread fallback.\n this.cancelActiveWorkerTasks();\n this.terminateWorkers();\n this.activeTaskById.clear();\n for (const task of this.queuedTasks) {\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(e));\n }\n this.queueBroadcastStateChanges();\n reject(e);\n }\n })();\n });\n this.initialized = initialization;\n this.queueBroadcastStateChanges();\n // Return the startup promise so callers can await initialization and the\n // constructor's error handler can catch startup failures.\n return initialization;\n } else {\n return this.initialized;\n }\n }\n\n // Warning: workers never use the main-thread highlighter. If\n // disposeHighlighter() runs during this load, pool work must not fail; the\n // next plain render loads the highlighter again.\n private async loadSharedHighlighter(\n themes: DiffsThemeNames[],\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n await getSharedHighlighter({\n themes,\n langs,\n preferredHighlighter: this.preferredHighlighter,\n });\n } catch (error) {\n if (!(error instanceof HighlighterDisposedError)) {\n throw error;\n }\n }\n }\n\n private async initializeWorkers(\n resolvedThemes: DiffsTheme[],\n resolvedLanguages: ResolvedLanguage[]\n ): Promise<void> {\n this.workersFailed = false;\n const initPromises: Promise<unknown>[] = [];\n const customExtensionVersion = getCustomExtensionsVersion();\n const customExtensionMap =\n customExtensionVersion > 0 ? getCustomExtensionsMap() : undefined;\n if (this.workers.length > 0) {\n this.terminateWorkers();\n }\n for (let i = 0; i < (this.options.poolSize ?? 8); i++) {\n const worker = this.options.workerFactory();\n const managedWorker: ManagedWorker = {\n worker,\n requestId: undefined,\n pendingSetupRequestId: undefined,\n initialized: false,\n langs: new Set(['text', ...resolvedLanguages.map(({ name }) => name)]),\n customExtensionsVersion: 0,\n };\n worker.addEventListener(\n 'message',\n (event: MessageEvent<WorkerWireResponse>) => {\n this.handleWorkerMessage(managedWorker, event.data);\n }\n );\n worker.addEventListener('error', (error) =>\n this.handleWorkerError(managedWorker, error)\n );\n this.workers.push(managedWorker);\n initPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const request: InitializeWorkerWireRequest = {\n type: 'initialize',\n resultFormat: 'hast-ops-v1',\n id,\n renderOptions: this.renderOptions,\n preferredHighlighter: this.preferredHighlighter,\n resolvedThemes,\n resolvedLanguages,\n customExtensionsVersion:\n customExtensionMap != null ? customExtensionVersion : undefined,\n customExtensionMap,\n };\n const task: InitializeWorkerTask = {\n type: 'initialize',\n id,\n request,\n resolve() {\n managedWorker.initialized = true;\n resolve();\n },\n reject,\n requestStart: Date.now(),\n };\n managedWorker.pendingSetupRequestId = id;\n this.activeTaskById.set(id, task);\n this.executeTask(managedWorker, task);\n })\n );\n }\n const timeoutMs =\n this.options.workerInitializationTimeout ??\n DEFAULT_WORKER_INITIALIZATION_TIMEOUT;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n Promise.all(initPromises),\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new Error(\n `WorkerPoolManager: worker initialization timed out after ${timeoutMs}ms`\n )\n );\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Pass worker errors to onWorkerError, or log them if no callback is set.\n *\n * A startup error rejects initialization so components can highlight on the\n * main thread. Other requests wait for their own responses: worker.ts catches\n * request errors, so this event may be unrelated to the current request.\n * A worker that stops responding remains busy and receives no further work.\n */\n private handleWorkerError(\n managedWorker: ManagedWorker,\n event: ErrorEvent | Event\n ): void {\n const { onWorkerError } = this.options;\n if (onWorkerError != null) {\n try {\n onWorkerError(event, managedWorker.worker);\n } catch (hookError) {\n console.error('WorkerPoolManager: onWorkerError threw:', hookError);\n }\n } else {\n console.error('Worker error:', event, managedWorker);\n }\n const { pendingSetupRequestId } = managedWorker;\n if (pendingSetupRequestId == null) {\n return;\n }\n const task = this.activeTaskById.get(pendingSetupRequestId);\n if (task?.type !== 'initialize') {\n return;\n }\n const error = errorFromWorkerErrorEvent(event);\n if (onWorkerError != null) {\n markWorkerErrorReported(error);\n }\n task.reject(error);\n this.cleanWorkerAndTask(managedWorker, task);\n }\n\n private drainQueue = () => {\n this._queuedDrain = undefined;\n // If we are initializing or things got cancelled while initializing, we\n // should not attempt to drain the queue\n if (this.initialized !== true || this.queuedTasks.length === 0) {\n return;\n }\n for (let i = 0; i < this.queuedTasks.length; ) {\n const task = this.queuedTasks[i];\n // If any instance has a request in progress, we should wait for it to\n // finish before starting work that would notify that instance.\n if (this.hasActiveRequest(task)) {\n i++;\n continue;\n }\n const langs = getLangsFromTask(task);\n const availableWorker = this.getAvailableWorker(langs);\n if (availableWorker == null) {\n break;\n }\n this.queuedTasks.splice(i, 1);\n this.assignWorkerToTask(task, availableWorker);\n void this.resolveLanguagesAndExecuteTask(availableWorker, task, langs);\n }\n this.queueBroadcastStateChanges();\n };\n\n public highlightFileAST(\n instance: FileRendererInstance,\n file: FileContents\n ): void {\n const cachedResult = this.getFileResultCache(file);\n // If we've already highlighted the file or it's plain text, we should not\n // attempt to highlight. This should be mostly never hit, but it's just an\n // extra level of safety\n if (\n isFilePlainText(file) ||\n (cachedResult != null &&\n areFileRenderOptionsEqual(\n cachedResult.options,\n this.getFileRenderOptions()\n ))\n ) {\n return;\n }\n if (!this.hasMatchingFileInstanceTask(instance, file)) {\n this.submitTask(instance, { type: 'file', file });\n }\n }\n\n public primeFileHighlightCache(file: FileContents): Promise<void> {\n if (!this.isWorkingPool()) {\n return Promise.reject(\n new Error(\n 'WorkerPoolManager.primeFileHighlightCache: worker pool is not working'\n )\n );\n }\n\n const task = this.getOrCreateFileHighlightCacheTask(file);\n return task != null\n ? this.createRenderTaskCallbacks(task)\n : Promise.resolve();\n }\n\n private getOrCreateFileHighlightCacheTask(\n file: FileContents\n ): RenderFileTask | undefined {\n if (file.cacheKey == null) {\n console.warn(\n `WorkerPoolManager.primeFileHighlightCache: priming highlight cache requires file.cacheKey; skipping \"${file.name}\".`\n );\n return undefined;\n }\n const cachedResult = this.getFileResultCache(file);\n const highlightKey = this.getFileHighlightKey(file);\n if (\n highlightKey == null ||\n isFilePlainText(file) ||\n (cachedResult != null &&\n areFileRenderOptionsEqual(\n cachedResult.options,\n this.getFileRenderOptions()\n ))\n ) {\n return undefined;\n }\n const existingTask = this.getTaskByHighlightKey(highlightKey);\n if (existingTask != null) {\n existingTask.primeCache = true;\n return existingTask.type === 'file' ? existingTask : undefined;\n } else {\n const task = this.submitCacheTask({ type: 'file', file }, highlightKey);\n return task.type === 'file' ? task : undefined;\n }\n }\n\n public getPlainFileAST(\n file: FileContents,\n startingLine: number,\n totalLines: number,\n lines?: string[]\n ): ThemedFileResult | undefined {\n const highlighter = getHighlighterIfLoaded({\n theme: this.renderOptions.theme,\n });\n if (highlighter == null) {\n this.queueInitialization();\n return undefined;\n }\n return renderFileWithHighlighter(file, highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n lines,\n });\n }\n\n public highlightDiffAST(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): void {\n const cachedResult = this.getDiffResultCache(diff);\n // If we've already highlighted the diff or it's plain text, we should not\n // attempt to highlight. This should be mostly never hit, but it's just an\n // extra level of safety\n if (\n isDiffPlainText(diff) ||\n (cachedResult != null &&\n areDiffRenderOptionsEqual(\n cachedResult.options,\n this.getDiffRenderOptions()\n ))\n ) {\n return;\n }\n if (!this.hasMatchingDiffInstanceTask(instance, diff)) {\n this.submitTask(instance, { type: 'diff', diff });\n }\n }\n\n public primeDiffHighlightCache(diff: FileDiffMetadata): Promise<void> {\n if (!this.isWorkingPool()) {\n return Promise.reject(\n new Error(\n 'WorkerPoolManager.primeDiffHighlightCache: worker pool is not working'\n )\n );\n }\n\n const task = this.getOrCreateDiffHighlightCacheTask(diff);\n return task != null\n ? this.createRenderTaskCallbacks(task)\n : Promise.resolve();\n }\n\n private getOrCreateDiffHighlightCacheTask(\n diff: FileDiffMetadata\n ): RenderDiffTask | undefined {\n if (diff.cacheKey == null) {\n console.warn(\n `WorkerPoolManager.primeDiffHighlightCache: priming highlight cache requires diff.cacheKey; skipping \"${diff.prevName ?? diff.name}\" -> \"${diff.name}\".`\n );\n return undefined;\n }\n const cachedResult = this.getDiffResultCache(diff);\n const highlightKey = this.getDiffHighlightKey(diff);\n if (\n highlightKey == null ||\n isDiffPlainText(diff) ||\n (cachedResult != null &&\n areDiffRenderOptionsEqual(\n cachedResult.options,\n this.getDiffRenderOptions()\n ))\n ) {\n return undefined;\n }\n const existingTask = this.getTaskByHighlightKey(highlightKey);\n if (existingTask != null) {\n existingTask.primeCache = true;\n return existingTask.type === 'diff' ? existingTask : undefined;\n } else {\n const task = this.submitCacheTask({ type: 'diff', diff }, highlightKey);\n return task.type === 'diff' ? task : undefined;\n }\n }\n\n public getPlainDiffAST(\n diff: FileDiffMetadata,\n startingLine: number,\n totalLines: number,\n expandedHunks?: Map<number, HunkExpansionRegion> | true,\n collapsedContextThreshold?: number\n ): ThemedDiffResult | undefined {\n const highlighter = getHighlighterIfLoaded({\n theme: this.renderOptions.theme,\n });\n if (highlighter == null) {\n this.queueInitialization();\n return undefined;\n }\n return renderDiffWithHighlighter(diff, highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold,\n });\n }\n\n public terminate(): void {\n this.lifecycleGeneration++;\n this.cancelActiveWorkerTasks();\n this.terminateWorkers();\n const error = new WorkerPoolTerminatedError();\n for (const task of this.queuedTasks) {\n this.rejectRenderTaskCallbacks(task, error);\n }\n this.fileCache.clear();\n this.diffCache.clear();\n this.activeRequestByInstance.clear();\n this.queuedTasks.length = 0;\n this.queuedTaskByInstance.clear();\n this.taskByHighlightKey.clear();\n this.activeTaskById.clear();\n this.initialized = false;\n this.workersFailed = false;\n this.queueBroadcastStateChanges();\n }\n\n private isCurrentLifecycle(lifecycleGeneration: number): boolean {\n return this.lifecycleGeneration === lifecycleGeneration;\n }\n\n private queueInitialization(languages?: SupportedLanguages[]): void {\n void this.initialize(languages).catch((error) => {\n // Skip cancellations and worker errors already passed to onWorkerError.\n if (isHandledWorkerPoolError(error)) {\n return;\n }\n console.error(error);\n });\n }\n\n private cancelActiveWorkerTasks(): void {\n const error = new WorkerPoolTerminatedError();\n for (const task of this.activeTaskById.values()) {\n if ('reject' in task) {\n task.reject(error);\n } else if (isRenderTask(task)) {\n this.rejectRenderTaskCallbacks(task, error);\n }\n }\n }\n\n private terminateWorkers() {\n for (const managedWorker of this.workers) {\n managedWorker.worker.terminate();\n }\n this.workers.length = 0;\n }\n\n public getStats(): WorkerStats {\n return {\n managerState: (() => {\n if (this.initialized === false) {\n return 'waiting';\n }\n if (this.initialized !== true) {\n return 'initializing';\n }\n return 'initialized';\n })(),\n totalWorkers: this.workers.length,\n workersFailed: this.workersFailed,\n busyWorkers: this.workers.filter(\n (w) => w.requestId != null || w.pendingSetupRequestId != null\n ).length,\n queuedTasks: this.queuedTasks.length,\n activeTasks: this.activeTaskById.size,\n themeSubscribers: this.themeSubscribers.size,\n fileCacheSize: this.fileCache.size,\n diffCacheSize: this.diffCache.size,\n };\n }\n\n private submitTask(\n instance: FileRendererInstance,\n request: Omit<RenderFileRequest, 'id'>\n ): void;\n private submitTask(\n instance: DiffRendererInstance,\n request: Omit<RenderDiffRequest, 'id'>\n ): void;\n private submitTask(\n instance: FileRendererInstance | DiffRendererInstance,\n request: SubmitRequest\n ): void {\n if (this.initialized === false) {\n this.queueInitialization();\n }\n\n const highlightKey = this.getHighlightKeyForRequest(request);\n const existingTask =\n highlightKey != null\n ? this.getTaskByHighlightKey(highlightKey)\n : undefined;\n if (existingTask != null) {\n this.detachInstanceFromQueuedTasks(instance, existingTask);\n this.addInstanceToTask(existingTask, instance);\n this.queueBroadcastStateChanges();\n return;\n }\n\n this.detachInstanceFromQueuedTasks(instance);\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const { renderOptionsVersion } = this;\n const task: RenderTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instances: new Set([instance as FileRendererInstance]),\n primeCache: false,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instances: new Set([instance as DiffRendererInstance]),\n primeCache: false,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n }\n })();\n this.enqueueRenderTask(task, instance);\n }\n\n private submitCacheTask(\n request: SubmitRequest,\n highlightKey: string\n ): RenderTask {\n if (this.initialized === false) {\n this.queueInitialization();\n }\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const { renderOptionsVersion } = this;\n const task: RenderTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instances: new Set<FileRendererInstance>(),\n primeCache: true,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instances: new Set<DiffRendererInstance>(),\n primeCache: true,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n }\n })();\n this.enqueueRenderTask(task);\n return task;\n }\n\n private enqueueRenderTask(\n task: RenderTask,\n instance?: RenderTaskInstance\n ): void {\n this.queuedTasks.push(task);\n if (instance != null) {\n this.queuedTaskByInstance.set(instance, task);\n }\n if (task.highlightKey != null) {\n this.taskByHighlightKey.set(task.highlightKey, task);\n }\n this.queueDrain();\n }\n\n private async resolveLanguagesAndExecuteTask(\n availableWorker: ManagedWorker,\n task: RenderFileTask | RenderDiffTask,\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n // Preload the same languages on the main thread for editing.\n const highlighter = getHighlighterIfLoaded();\n const mainThreadLangs = langs.filter(\n (lang) =>\n highlighter == null || !areLanguagesAttached(lang, highlighter)\n );\n if (mainThreadLangs.length > 0) {\n void this.loadSharedHighlighter(getThemes(this.renderOptions.theme), [\n 'text',\n ...mainThreadLangs,\n ]).catch((error: unknown) => {\n console.error(error);\n });\n }\n // Add resolved languages if required\n const workerMissingLangs =\n this.preferredHighlighter === 'highlights'\n ? []\n : langs.filter((lang) => !availableWorker.langs.has(lang));\n\n if (workerMissingLangs.length > 0) {\n if (hasResolvedLanguages(workerMissingLangs)) {\n task.request.resolvedLanguages =\n getResolvedLanguages(workerMissingLangs);\n } else {\n task.request.resolvedLanguages =\n await resolveLanguages(workerMissingLangs);\n }\n }\n // If the task has been cleaned up after awaiting language resolving,\n // lets fully clean it up\n if (!this.activeTaskById.has(task.id)) {\n if (availableWorker.requestId === task.id) {\n this.cleanWorkerAndTask(availableWorker, task);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n return;\n }\n this.executeTask(availableWorker, task);\n } catch (error) {\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(error));\n this.cleanWorkerAndTask(availableWorker, task);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n }\n\n private handleWorkerMessage(\n managedWorker: ManagedWorker,\n response: WorkerWireResponse\n ): void {\n const task = this.activeTaskById.get(response.id);\n try {\n if (task == null) {\n // If we can't find a task for this response, it probably means the\n // component has been unmounted, so we should silently ignore it\n throw IGNORE_RESPONSE;\n } else if (response.type === 'error') {\n const error = new Error(response.error);\n if (response.stack) {\n error.stack = response.stack;\n }\n if ('reject' in task) {\n task.reject(error);\n } else if (isRenderTask(task)) {\n this.notifyHighlightError(task, error);\n this.rejectRenderTaskCallbacks(task, error);\n } else {\n throw new Error('handleWorkerMessage: unknown task type');\n }\n throw error;\n } else {\n // A failed request may not have attached its languages. Only remember\n // them after success so later tasks resend grammars that were rejected.\n if (isRenderTask(task)) {\n for (const { name } of task.request.resolvedLanguages ?? []) {\n managedWorker.langs.add(name);\n }\n }\n switch (response.requestType) {\n case 'initialize':\n if (task.type !== 'initialize') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n this.syncCustomExtensionVersion(managedWorker, task.request);\n task.resolve();\n break;\n case 'set-render-options':\n if (task.type !== 'set-render-options') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'file': {\n if (task.type !== 'file') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { options } = response;\n if (\n !this.isCurrentRenderTask(task) ||\n !areFileRenderOptionsEqual(options, this.getFileRenderOptions())\n ) {\n throw IGNORE_RESPONSE;\n }\n const { request } = task;\n const result: ThemedFileResult = {\n ...response.result,\n code: decodeHastLines(response.result.code),\n };\n this.syncCustomExtensionVersion(managedWorker, request);\n if (task.cacheKeyAtDispatch != null) {\n this.fileCache.set(task.cacheKeyAtDispatch, { result, options });\n }\n this.resolveRenderTaskCallbacks(task);\n this.notifyFileInstances(task, result, options);\n break;\n }\n case 'diff': {\n if (task.type !== 'diff') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { options } = response;\n if (\n !this.isCurrentRenderTask(task) ||\n !areDiffRenderOptionsEqual(options, this.getDiffRenderOptions())\n ) {\n throw IGNORE_RESPONSE;\n }\n const { request } = task;\n const result: ThemedDiffResult = {\n ...response.result,\n code: {\n deletionLines: decodeHastLines(\n response.result.code.deletionLines\n ),\n additionLines: decodeHastLines(\n response.result.code.additionLines\n ),\n },\n };\n this.syncCustomExtensionVersion(managedWorker, request);\n if (task.cacheKeyAtDispatch != null) {\n this.diffCache.set(task.cacheKeyAtDispatch, { result, options });\n }\n this.resolveRenderTaskCallbacks(task);\n this.notifyDiffInstances(task, result, options);\n break;\n }\n }\n }\n } catch (error) {\n if (error !== IGNORE_RESPONSE) {\n console.error(error, task, response);\n }\n }\n\n this.cleanWorkerAndTask(managedWorker, task, response.id);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n // We queue drain so that potentially multiple workers can free up\n // allowing for better language matches if possible\n this.queueDrain();\n }\n }\n\n private _queuedDrain: Promise<void> | undefined;\n private queueDrain() {\n if (this._queuedDrain != null) return;\n this._queuedDrain = Promise.resolve().then(this.drainQueue);\n this.queueBroadcastStateChanges();\n }\n\n private assignWorkerToTask(\n task: AllWorkerTasks,\n managedWorker: ManagedWorker\n ) {\n managedWorker.requestId = task.id;\n if (isRenderTask(task)) {\n this.clearQueuedInstanceRequests(task);\n this.trackInstanceRequests(task);\n }\n this.activeTaskById.set(task.id, task);\n }\n\n private cleanWorkerAndTask(\n managedWorker: ManagedWorker,\n task?: AllWorkerTasks,\n requestId: WorkerRequestId | undefined = task?.id\n ) {\n if (managedWorker.requestId === requestId) {\n managedWorker.requestId = undefined;\n }\n if (managedWorker.pendingSetupRequestId === requestId) {\n managedWorker.pendingSetupRequestId = undefined;\n }\n if (task != null) {\n if (isRenderTask(task)) {\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearInstanceRequests(task);\n this.clearHighlightKey(task);\n }\n this.activeTaskById.delete(task.id);\n }\n }\n\n private executeTask(\n managedWorker: ManagedWorker,\n task: AllWorkerTasks\n ): void {\n if (shouldSyncCustomExtensions(task.request)) {\n this.maybeAttachCustomExtensions(managedWorker, task.request);\n }\n if (!this.activeTaskById.has(task.id)) {\n this.assignWorkerToTask(task, managedWorker);\n }\n try {\n // postMessage clones the request now, so keep the matching cache key on\n // the task instead of reading the caller's mutable target on response.\n if (task.type === 'file') {\n task.cacheKeyAtDispatch = task.request.file.cacheKey;\n } else if (task.type === 'diff') {\n task.cacheKeyAtDispatch = task.request.diff.cacheKey;\n }\n managedWorker.worker.postMessage(task.request);\n } catch (error) {\n console.error('Failed to post message to worker:', error);\n if (isRenderTask(task)) {\n this.notifyHighlightError(task, error);\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(error));\n } else if ('reject' in task) {\n task.reject(error as Error);\n }\n this.cleanWorkerAndTask(managedWorker, task);\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n this.queueBroadcastStateChanges();\n }\n\n private maybeAttachCustomExtensions(\n managedWorker: ManagedWorker,\n request: InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest\n ): void {\n if (request.customExtensionsVersion != null) {\n return;\n }\n const version = getCustomExtensionsVersion();\n if (managedWorker.customExtensionsVersion >= version) {\n return;\n }\n request.customExtensionsVersion = version;\n request.customExtensionMap = getCustomExtensionsMap();\n }\n\n private syncCustomExtensionVersion(\n managedWorker: ManagedWorker,\n request: InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest\n ): void {\n if (request.customExtensionsVersion == null) {\n return;\n }\n managedWorker.customExtensionsVersion = request.customExtensionsVersion;\n }\n\n private getAvailableWorker(\n langs: SupportedLanguages[]\n ): ManagedWorker | undefined {\n let worker: ManagedWorker | undefined;\n for (const managedWorker of this.workers) {\n if (\n managedWorker.requestId != null ||\n managedWorker.pendingSetupRequestId != null ||\n !managedWorker.initialized\n ) {\n continue;\n }\n worker = managedWorker;\n if (langs.length === 0) {\n break;\n }\n let hasEveryLang = true;\n for (const lang of langs) {\n if (!managedWorker.langs.has(lang)) {\n hasEveryLang = false;\n break;\n }\n }\n if (hasEveryLang) {\n break;\n }\n }\n return worker;\n }\n\n private getFileHighlightKey(file: FileContents): string | undefined {\n if (file.cacheKey == null) {\n return undefined;\n }\n return `file:${file.cacheKey}:${this.renderOptionsVersion}`;\n }\n\n private getDiffHighlightKey(diff: FileDiffMetadata): string | undefined {\n if (diff.cacheKey == null) {\n return undefined;\n }\n return `diff:${diff.cacheKey}:${this.renderOptionsVersion}`;\n }\n\n private getHighlightKeyForRequest(\n request: SubmitRequest\n ): string | undefined {\n switch (request.type) {\n case 'file':\n return this.getFileHighlightKey(request.file);\n case 'diff':\n return this.getDiffHighlightKey(request.diff);\n }\n }\n\n private hasActiveRequest(task: RenderTask): boolean {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.has(instance)) {\n return true;\n }\n }\n return false;\n }\n\n private addInstanceToTask(\n task: RenderTask,\n instance: FileRendererInstance | DiffRendererInstance\n ): void {\n if (task.type === 'file') {\n task.instances.add(instance as FileRendererInstance);\n } else {\n task.instances.add(instance as DiffRendererInstance);\n }\n if (this.activeTaskById.has(task.id)) {\n this.activeRequestByInstance.set(instance, task.id);\n } else {\n this.queuedTaskByInstance.set(instance, task);\n }\n }\n\n private detachInstanceFromQueuedTasks(\n instance: RenderTaskInstance,\n exceptTask?: RenderTask\n ): void {\n const task = this.queuedTaskByInstance.get(instance);\n if (task == null || task === exceptTask) {\n return;\n }\n this.queuedTaskByInstance.delete(instance);\n this.detachInstanceFromRenderTask(task, instance);\n if (!task.primeCache && task.instances.size === 0) {\n this.removeQueuedTask(task);\n }\n }\n\n private detachInstanceFromRenderTask(\n task: RenderTask,\n instance: RenderTaskInstance\n ): void {\n if (task.type === 'file') {\n task.instances.delete(instance as FileRendererInstance);\n } else {\n task.instances.delete(instance as DiffRendererInstance);\n }\n }\n\n private removeQueuedTask(task: RenderTask): void {\n const index = this.queuedTasks.indexOf(task);\n if (index !== -1) {\n this.queuedTasks.splice(index, 1);\n }\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearQueuedInstanceRequests(task);\n this.clearHighlightKey(task);\n }\n\n private removeActiveTask(task: RenderTask): void {\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearInstanceRequests(task);\n this.clearHighlightKey(task);\n this.activeTaskById.delete(task.id);\n }\n\n private createRenderTaskCallbacks(task: RenderTask): Promise<void> {\n return new Promise((resolve, reject) => {\n task.callbacks.add({ resolve, reject });\n });\n }\n\n private resolveRenderTaskCallbacks(task: RenderTask): void {\n for (const callbacks of task.callbacks) {\n callbacks.resolve();\n }\n task.callbacks.clear();\n }\n\n private rejectRenderTaskCallbacks(task: RenderTask, error: Error): void {\n for (const callbacks of task.callbacks) {\n callbacks.reject(error);\n }\n task.callbacks.clear();\n }\n\n private invalidateRenderTasks(): void {\n for (let index = this.queuedTasks.length - 1; index >= 0; index--) {\n const task = this.queuedTasks[index];\n if (task.renderOptionsVersion !== this.renderOptionsVersion) {\n this.removeQueuedTask(task);\n }\n }\n\n for (const task of Array.from(this.activeTaskById.values())) {\n if (\n isRenderTask(task) &&\n task.renderOptionsVersion !== this.renderOptionsVersion\n ) {\n this.removeActiveTask(task);\n }\n }\n }\n\n private clearQueuedInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n if (this.queuedTaskByInstance.get(instance) === task) {\n this.queuedTaskByInstance.delete(instance);\n }\n }\n }\n\n private clearHighlightKey(task: RenderTask): void {\n if (\n task.highlightKey != null &&\n this.taskByHighlightKey.get(task.highlightKey) === task\n ) {\n this.taskByHighlightKey.delete(task.highlightKey);\n }\n }\n\n private trackInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n this.activeRequestByInstance.set(instance, task.id);\n }\n }\n\n private clearInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n this.activeRequestByInstance.delete(instance);\n }\n }\n }\n\n private notifyFileInstances(\n task: RenderFileTask,\n result: ThemedFileResult,\n options: RenderFileOptions\n ): void {\n for (const instance of task.instances) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightSuccess(task.request.file, result, options);\n }\n }\n }\n\n private notifyDiffInstances(\n task: RenderDiffTask,\n result: ThemedDiffResult,\n options: RenderDiffOptions\n ): void {\n for (const instance of task.instances) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightSuccess(task.request.diff, result, options);\n }\n }\n }\n\n private notifyHighlightError(task: RenderTask, error: unknown): void {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightError(error);\n }\n }\n }\n\n private hasMatchingFileInstanceTask(\n instance: FileRendererInstance,\n file: FileContents\n ): boolean {\n for (const task of this.iterateRenderTasks()) {\n if (\n task.type === 'file' &&\n this.isCurrentRenderTask(task) &&\n task.instances.has(instance) &&\n areFilesEqual(file, task.request.file)\n ) {\n return true;\n }\n }\n return false;\n }\n\n private hasMatchingDiffInstanceTask(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): boolean {\n for (const task of this.iterateRenderTasks()) {\n if (\n task.type === 'diff' &&\n this.isCurrentRenderTask(task) &&\n task.instances.has(instance) &&\n areDiffTargetsEqual(task.request.diff, diff)\n ) {\n return true;\n }\n }\n return false;\n }\n\n private getTaskByHighlightKey(highlightKey: string): RenderTask | undefined {\n const task = this.taskByHighlightKey.get(highlightKey);\n return task != null && this.isCurrentRenderTask(task) ? task : undefined;\n }\n\n private isCurrentRenderTask(task: RenderTask): boolean {\n return task.renderOptionsVersion === this.renderOptionsVersion;\n }\n\n private *iterateRenderTasks(): Generator<RenderTask> {\n for (const task of this.queuedTasks) {\n yield task;\n }\n for (const task of this.activeTaskById.values()) {\n if (isRenderTask(task)) {\n yield task;\n }\n }\n }\n\n private generateRequestId(): WorkerRequestId {\n return `req_${++this.nextRequestId}`;\n }\n}\n\nfunction shouldSyncCustomExtensions(\n request: AllWorkerTasks['request']\n): request is InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest {\n return (\n request.type === 'initialize' ||\n request.type === 'file' ||\n request.type === 'diff'\n );\n}\n\nfunction getLangsFromTask(task: AllWorkerTasks): SupportedLanguages[] {\n const langs = new Set<SupportedLanguages>();\n if (task.type === 'initialize' || task.type === 'set-render-options') {\n return [];\n }\n switch (task.type) {\n case 'file': {\n langs.add(\n task.request.file.lang ??\n getFiletypeFromFileName(task.request.file.name)\n );\n break;\n }\n case 'diff': {\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.name)\n );\n langs.add(\n task.request.diff.lang ??\n getFiletypeFromFileName(task.request.diff.prevName ?? '-')\n );\n break;\n }\n }\n langs.delete('text');\n return Array.from(langs);\n}\n\nfunction isRenderTask(task: AllWorkerTasks | undefined): task is RenderTask {\n return task?.type === 'file' || task?.type === 'diff';\n}\n\nfunction getInstances(\n task: RenderTask\n): Set<FileRendererInstance | DiffRendererInstance> {\n return task.instances;\n}\n\nfunction normalizeWorkerError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n if (error != null && typeof error === 'object') {\n if ('error' in error && error.error instanceof Error) {\n return error.error;\n }\n if ('message' in error && typeof error.message === 'string') {\n return new Error(error.message);\n }\n }\n return new Error(String(error));\n}\n\n// Convert a worker error event into a startup error, preserving its cause.\n// Script load failures can provide a plain Event without an error or message,\n// so use a default message when no details are available.\nfunction errorFromWorkerErrorEvent(\n event: ErrorEvent | Event\n): WorkerPoolWorkerError {\n const cause: unknown = 'error' in event ? event.error : undefined;\n const message =\n 'message' in event &&\n typeof event.message === 'string' &&\n event.message !== ''\n ? event.message\n : cause instanceof Error\n ? cause.message\n : 'the worker script failed to load (the error event carries no message)';\n return new WorkerPoolWorkerError(\n `WorkerPoolManager: worker failed: ${message}`,\n cause instanceof Error ? { cause } : undefined\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA+EA,MAAM,kBAAkB,OAAO,iBAAiB;AAChD,MAAM,wCAAwC;AAwB9C,IAAa,oBAAb,MAA+B;CAiCnB;CAhCV;CACA;CACA,8BAAsC;CACtC,uBAA+B;CAC/B,cAA+C;CAC/C,UAAmC,CAAC;CAEpC,cAAoC,CAAC;CACrC,uCAA+B,IAAI,IAAoC;CAIvE,qCAA6B,IAAI,IAAwB;CAGzD,iCAAyB,IAAI,IAAqC;CAClE,0CAAkC,IAAI,IAGpC;CAEF,gBAAwB;CACxB,mCAA2B,IAAI,IAAqB;CACpD,gBAAwB;CACxB,kCAA0B,IAAI,IAAqC;CACnE;CACA;CACA;CAEA,sBAA8B;CAE9B,YACE,SACA,EACE,OACA,QAAQ,gBACR,sBAAsB,OACtB,eAAe,YACf,oBAAoB,KACpB,wBAAwB,KACxB,wBAEF;EAVQ,KAAA,UAAA;EAWR,KAAK,uBAAuB,uBAAuB,oBAAoB;EACvE,KAAK,gBAAgB;GACnB;GACA;GACA;GACA;GACA;EACF;EACA,KAAK,YAAY,IAAI,UAAU,OAAO,QAAQ,wBAAwB,GAAG;EACzE,KAAK,YAAY,IAAI,UAAU,OAAO,QAAQ,wBAAwB,GAAG;EACzE,KAAK,oBAAoB,KAAK;CAChC;CAEA,gBAAgC;EAC9B,OAAO,CAAC,KAAK;CACf;CAEA,mBAA0B,MAAkD;EAC1E,OAAO,KAAK,YAAY,OACpB,KAAK,UAAU,IAAI,KAAK,QAAQ,IAChC,KAAA;CACN;CAEA,mBACE,MAC8B;EAC9B,OAAO,KAAK,YAAY,OACpB,KAAK,UAAU,IAAI,KAAK,QAAQ,IAChC,KAAA;CACN;CAEA,gBAAwC;EACtC,MAAM,EAAE,WAAW,cAAc;EACjC,OAAO;GAAE;GAAW;EAAU;CAChC;CAEA,mBAA0B,UAA2B;EACnD,IAAI;GACF,OAAO,KAAK,UAAU,OAAO,QAAQ,MAAM,KAAA;EAC7C,UAAU;GACR,KAAK,2BAA2B;EAClC;CACF;CAEA,mBAA0B,UAA2B;EACnD,IAAI;GACF,OAAO,KAAK,UAAU,OAAO,QAAQ,MAAM,KAAA;EAC7C,UAAU;GACR,KAAK,2BAA2B;EAClC;CACF;CAEA,MAAM,iBAAiB,EACrB,QAAQ,KAAK,cAAc,SAAS,gBACpC,sBAAsB,KAAK,cAAc,uBAAuB,OAChE,eAAe,KAAK,cAAc,gBAAgB,YAClD,oBAAoB,KAAK,cAAc,qBAAqB,KAC5D,wBAAwB,KAAK,cAAc,yBAAyB,OACnB;EACjD,MAAM,EAAE,wBAAwB;EAChC,MAAM,8BAA8B,EAAE,KAAK;EAC3C,MAAM,yBACJ,KAAK,mBAAmB,mBAAmB,KAC3C,KAAK,gCAAgC;EACvC,IAAI;GACF,MAAM,mBAA2C;IAC/C;IACA;IACA;IACA;IACA;GACF;GACA,IAAI,CAAC,KAAK,cAAc,GACtB,MAAM,KAAK,WAAW;GAExB,IACE,CAAC,iBAAiB,KAClB,0BAA0B,kBAAkB,KAAK,aAAa,GAE9D;GAGF,MAAM,aAAa,UAAU,KAAK;GAClC,IAAI,iBAA+B,CAAC;GACpC,IAAI,CAAC,eAAe,iBAAiB,OAAO,KAAK,cAAc,KAAK,GAClE,iBAAiB,kBACf,YACA,KAAK,oBACP,IACI,kBAAkB,YAAY,KAAK,oBAAoB,IACvD,MAAM,cAAc,YAAY,KAAK,oBAAoB;GAG/D,IAAI,CAAC,iBAAiB,GACpB;GAKF,IAAI,uBAAuB,EAAE,MAAM,CAAC,KAAK,MAAM;IAC7C,MAAM,KAAK,sBAAsB,YAAY,CAAC,MAAM,CAAC;IACrD,IAAI,CAAC,iBAAiB,GACpB;GAEJ;GAEA,MAAM,cAAc,KAAK,0BACvB,kBACA,cACF;GAEA,KAAK,gBAAgB;GACrB,KAAK;GACL,KAAK,UAAU,MAAM;GACrB,KAAK,UAAU,MAAM;GACrB,KAAK,sBAAsB;GAE3B,KAAK,MAAM,YAAY,KAAK,kBAC1B,SAAS,cAAc;GAGzB,MAAM;EACR,SAAS,OAAO;GACd,IAAI,iBAAiB,6BAA6B,CAAC,iBAAiB,GAClE;GAEF,MAAM;EACR;CACF;CAEA,0BAAmD;EACjD,OAAO,KAAK;CACd;CAEA,uBAAiD;EAC/C,MAAM,EAAE,uBAAuB,OAAO,wBACpC,KAAK;EACP,OAAO;GAAE;GAAO;GAAqB;EAAsB;CAC7D;CAEA,uBAAiD;EAC/C,OAAO,EAAE,GAAG,KAAK,cAAc;CACjC;CAEA,MAAc,0BACZ,eACA,gBACe;EACf,IAAI,KAAK,eACP;EAEF,IAAI,CAAC,KAAK,cAAc,GACtB,MAAM,KAAK,WAAW;EAExB,MAAM,eAAgC,CAAC;EACvC,KAAK,MAAM,iBAAiB,KAAK,SAAS;GACxC,IAAI,CAAC,cAAc,aAAa;IAC9B,QAAQ,IAAI,EAAE,cAAc,CAAC;IAC7B,MAAM,IAAI,MACR,oEACF;GACF;GACA,aAAa,KACX,IAAI,SAAe,SAAS,WAAW;IACrC,MAAM,KAAK,KAAK,kBAAkB;IAClC,MAAM,OAAmC;KACvC,MAAM;KACN;KACA,SAAS;MACP,MAAM;MACN;MACA;MACA;KACF;KACA;KACA;KACA,cAAc,KAAK,IAAI;IACzB;IAGA,KAAK,eAAe,IAAI,IAAI,IAAI;IAChC,cAAc,wBAAwB;IACtC,cAAc,OAAO,YAAY,KAAK,OAAO;GAC/C,CAAC,CACH;EACF;EACA,MAAM,QAAQ,IAAI,YAAY;CAChC;CAEA,wBAA+B,UAAuC;EACpE,KAAK,iBAAiB,IAAI,QAAQ;EAClC,KAAK,2BAA2B;EAChC,aAAa;GACX,KAAK,0BAA0B,QAAQ;GACvC,KAAK,2BAA2B;EAClC;CACF;CAEA,0BAAiC,UAAiC;EAChE,KAAK,iBAAiB,OAAO,QAAQ;EACrC,KAAK,2BAA2B;CAClC;CAEA,uBACE,UACY;EACZ,KAAK,gBAAgB,IAAI,QAAQ;EACjC,SAAS,KAAK,SAAS,CAAC;EACxB,aAAa;GACX,KAAK,gBAAgB,OAAO,QAAQ;EACtC;CACF;CAEA,6BAAqC;EACnC,IAAI,KAAK,oBAAoB,MAAM;EACnC,KAAK,mBAAmB,sBAAsB,KAAK,sBAAsB;CAC3E;CAEA,+BAAuC;EACrC,IAAI,KAAK,oBAAoB,MAAM;GACjC,qBAAqB,KAAK,gBAAgB;GAC1C,KAAK,mBAAmB,KAAA;EAC1B;EACA,MAAM,QAAQ,KAAK,SAAS;EAC5B,KAAK,MAAM,YAAY,KAAK,iBAC1B,SAAS,KAAK;CAElB;CAEA,aAAoB,UAAoC;EACtD,KAAK,8BAA8B,QAAQ;EAC3C,MAAM,YAAY,KAAK,wBAAwB,IAAI,QAAQ;EAC3D,IAAI,aAAa,MAAM;GACrB,MAAM,OAAO,KAAK,eAAe,IAAI,SAAS;GAC9C,IAAI,aAAa,IAAI,GAAG;IACtB,KAAK,6BAA6B,MAAM,QAAQ;IAChD,IAAI,CAAC,KAAK,cAAc,KAAK,UAAU,SAAS,GAC9C,KAAK,iBAAiB,IAAI;GAE9B,OACE,KAAK,eAAe,OAAO,SAAS;EAExC;EACA,KAAK,wBAAwB,OAAO,QAAQ;EAC5C,KAAK,2BAA2B;CAClC;CAEA,gBAAgC;EAC9B,OAAO,KAAK,gBAAgB;CAC9B;CAEA,MAAa,WAAW,YAAkC,CAAC,GAAkB;EAC3E,IAAI,KAAK,gBAAgB,MAAM;GAC7B,IAAI,uBAAuB,EAAE,OAAO,KAAK,cAAc,MAAM,CAAC,KAAK,MACjE,MAAM,KAAK,sBAAsB,UAAU,KAAK,cAAc,KAAK,GAAG,CACpE,QACA,GAAG,SACL,CAAC;GAEH;EACF,OAAO,IAAI,KAAK,gBAAgB,OAAO;GACrC,MAAM,EAAE,wBAAwB;GAChC,MAAM,iBAAiB,IAAI,SAAe,SAAS,WAAW;IAC5D,CAAM,YAAY;KAChB,IAAI;MACF,MAAM,SAAS,UAAU,KAAK,cAAc,KAAK;MACjD,MAAM,iBAAiB,kBACrB,QACA,KAAK,oBACP,IACI,kBAAkB,QAAQ,KAAK,oBAAoB,IACnD,MAAM,cAAc,QAAQ,KAAK,oBAAoB;MACzD,IAAI,CAAC,KAAK,mBAAmB,mBAAmB,GAAG;OACjD,QAAQ;OACR;MACF;MAEA,IAAI,oBAAwC,CAAC;MAC7C,IAAI,KAAK,yBAAyB,cAChC,oBAAoB,qBAAqB,SAAS,IAC9C,qBAAqB,SAAS,IAC9B,MAAM,iBAAiB,SAAS;MAEtC,IAAI,CAAC,KAAK,mBAAmB,mBAAmB,GAAG;OACjD,QAAQ;OACR;MACF;MAEA,MAAM,QAAQ,IAAI,CAChB,KAAK,sBAAsB,QAAQ,CAAC,QAAQ,GAAG,SAAS,CAAC,GACzD,KAAK,kBAAkB,gBAAgB,iBAAiB,CAC1D,CAAC;MAED,IAAI,CAAC,KAAK,mBAAmB,mBAAmB,GAAG;OACjD,KAAK,iBAAiB;OACtB,QAAQ;OACR;MACF;MACA,KAAK,cAAc;MACnB,KAAK,UAAU,MAAM;MACrB,KAAK,UAAU,MAAM;MACrB,KAAK,WAAW;MAChB,KAAK,2BAA2B;MAChC,QAAQ;KACV,SAAS,GAAG;MACV,IACE,aAAa,6BACb,CAAC,KAAK,mBAAmB,mBAAmB,GAC5C;OACA,QAAQ;OACR;MACF;MACA,KAAK,cAAc;MACnB,KAAK,gBAAgB;MAGrB,KAAK,wBAAwB;MAC7B,KAAK,iBAAiB;MACtB,KAAK,eAAe,MAAM;MAC1B,KAAK,MAAM,QAAQ,KAAK,aACtB,KAAK,0BAA0B,MAAM,qBAAqB,CAAC,CAAC;MAE9D,KAAK,2BAA2B;MAChC,OAAO,CAAC;KACV;IACF,EAAA,CAAG;GACL,CAAC;GACD,KAAK,cAAc;GACnB,KAAK,2BAA2B;GAGhC,OAAO;EACT,OACE,OAAO,KAAK;CAEhB;CAKA,MAAc,sBACZ,QACA,OACe;EACf,IAAI;GACF,MAAM,qBAAqB;IACzB;IACA;IACA,sBAAsB,KAAK;GAC7B,CAAC;EACH,SAAS,OAAO;GACd,IAAI,EAAE,iBAAiB,2BACrB,MAAM;EAEV;CACF;CAEA,MAAc,kBACZ,gBACA,mBACe;EACf,KAAK,gBAAgB;EACrB,MAAM,eAAmC,CAAC;EAC1C,MAAM,yBAAyB,2BAA2B;EAC1D,MAAM,qBACJ,yBAAyB,IAAI,uBAAuB,IAAI,KAAA;EAC1D,IAAI,KAAK,QAAQ,SAAS,GACxB,KAAK,iBAAiB;EAExB,KAAK,IAAI,IAAI,GAAG,KAAK,KAAK,QAAQ,YAAY,IAAI,KAAK;GACrD,MAAM,SAAS,KAAK,QAAQ,cAAc;GAC1C,MAAM,gBAA+B;IACnC;IACA,WAAW,KAAA;IACX,uBAAuB,KAAA;IACvB,aAAa;IACb,uBAAO,IAAI,IAAI,CAAC,QAAQ,GAAG,kBAAkB,KAAK,EAAE,WAAW,IAAI,CAAC,CAAC;IACrE,yBAAyB;GAC3B;GACA,OAAO,iBACL,YACC,UAA4C;IAC3C,KAAK,oBAAoB,eAAe,MAAM,IAAI;GACpD,CACF;GACA,OAAO,iBAAiB,UAAU,UAChC,KAAK,kBAAkB,eAAe,KAAK,CAC7C;GACA,KAAK,QAAQ,KAAK,aAAa;GAC/B,aAAa,KACX,IAAI,SAAe,SAAS,WAAW;IACrC,MAAM,KAAK,KAAK,kBAAkB;IAalC,MAAM,OAA6B;KACjC,MAAM;KACN;KACA,SAAA;MAdA,MAAM;MACN,cAAc;MACd;MACA,eAAe,KAAK;MACpB,sBAAsB,KAAK;MAC3B;MACA;MACA,yBACE,sBAAsB,OAAO,yBAAyB,KAAA;MACxD;KAKM;KACN,UAAU;MACR,cAAc,cAAc;MAC5B,QAAQ;KACV;KACA;KACA,cAAc,KAAK,IAAI;IACzB;IACA,cAAc,wBAAwB;IACtC,KAAK,eAAe,IAAI,IAAI,IAAI;IAChC,KAAK,YAAY,eAAe,IAAI;GACtC,CAAC,CACH;EACF;EACA,MAAM,YACJ,KAAK,QAAQ,+BACb;EACF,IAAI;EACJ,IAAI;GACF,MAAM,QAAQ,KAAK,CACjB,QAAQ,IAAI,YAAY,GACxB,IAAI,SAAgB,GAAG,WAAW;IAChC,YAAY,iBAAiB;KAC3B,uBACE,IAAI,MACF,4DAA4D,UAAU,GACxE,CACF;IACF,GAAG,SAAS;GACd,CAAC,CACH,CAAC;EACH,UAAU;GACR,IAAI,aAAa,MACf,aAAa,SAAS;EAE1B;CACF;;;;;;;;;CAUA,kBACE,eACA,OACM;EACN,MAAM,EAAE,kBAAkB,KAAK;EAC/B,IAAI,iBAAiB,MACnB,IAAI;GACF,cAAc,OAAO,cAAc,MAAM;EAC3C,SAAS,WAAW;GAClB,QAAQ,MAAM,2CAA2C,SAAS;EACpE;OAEA,QAAQ,MAAM,iBAAiB,OAAO,aAAa;EAErD,MAAM,EAAE,0BAA0B;EAClC,IAAI,yBAAyB,MAC3B;EAEF,MAAM,OAAO,KAAK,eAAe,IAAI,qBAAqB;EAC1D,IAAI,MAAM,SAAS,cACjB;EAEF,MAAM,QAAQ,0BAA0B,KAAK;EAC7C,IAAI,iBAAiB,MACnB,wBAAwB,KAAK;EAE/B,KAAK,OAAO,KAAK;EACjB,KAAK,mBAAmB,eAAe,IAAI;CAC7C;CAEA,mBAA2B;EACzB,KAAK,eAAe,KAAA;EAGpB,IAAI,KAAK,gBAAgB,QAAQ,KAAK,YAAY,WAAW,GAC3D;EAEF,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,YAAY,SAAU;GAC7C,MAAM,OAAO,KAAK,YAAY;GAG9B,IAAI,KAAK,iBAAiB,IAAI,GAAG;IAC/B;IACA;GACF;GACA,MAAM,QAAQ,iBAAiB,IAAI;GACnC,MAAM,kBAAkB,KAAK,mBAAmB,KAAK;GACrD,IAAI,mBAAmB,MACrB;GAEF,KAAK,YAAY,OAAO,GAAG,CAAC;GAC5B,KAAK,mBAAmB,MAAM,eAAe;GAC7C,KAAU,+BAA+B,iBAAiB,MAAM,KAAK;EACvE;EACA,KAAK,2BAA2B;CAClC;CAEA,iBACE,UACA,MACM;EACN,MAAM,eAAe,KAAK,mBAAmB,IAAI;EAIjD,IACE,gBAAgB,IAAI,KACnB,gBAAgB,QACf,0BACE,aAAa,SACb,KAAK,qBAAqB,CAC5B,GAEF;EAEF,IAAI,CAAC,KAAK,4BAA4B,UAAU,IAAI,GAClD,KAAK,WAAW,UAAU;GAAE,MAAM;GAAQ;EAAK,CAAC;CAEpD;CAEA,wBAA+B,MAAmC;EAChE,IAAI,CAAC,KAAK,cAAc,GACtB,OAAO,QAAQ,uBACb,IAAI,MACF,uEACF,CACF;EAGF,MAAM,OAAO,KAAK,kCAAkC,IAAI;EACxD,OAAO,QAAQ,OACX,KAAK,0BAA0B,IAAI,IACnC,QAAQ,QAAQ;CACtB;CAEA,kCACE,MAC4B;EAC5B,IAAI,KAAK,YAAY,MAAM;GACzB,QAAQ,KACN,wGAAwG,KAAK,KAAK,GACpH;GACA;EACF;EACA,MAAM,eAAe,KAAK,mBAAmB,IAAI;EACjD,MAAM,eAAe,KAAK,oBAAoB,IAAI;EAClD,IACE,gBAAgB,QAChB,gBAAgB,IAAI,KACnB,gBAAgB,QACf,0BACE,aAAa,SACb,KAAK,qBAAqB,CAC5B,GAEF;EAEF,MAAM,eAAe,KAAK,sBAAsB,YAAY;EAC5D,IAAI,gBAAgB,MAAM;GACxB,aAAa,aAAa;GAC1B,OAAO,aAAa,SAAS,SAAS,eAAe,KAAA;EACvD,OAAO;GACL,MAAM,OAAO,KAAK,gBAAgB;IAAE,MAAM;IAAQ;GAAK,GAAG,YAAY;GACtE,OAAO,KAAK,SAAS,SAAS,OAAO,KAAA;EACvC;CACF;CAEA,gBACE,MACA,cACA,YACA,OAC8B;EAC9B,MAAM,cAAc,uBAAuB,EACzC,OAAO,KAAK,cAAc,MAC5B,CAAC;EACD,IAAI,eAAe,MAAM;GACvB,KAAK,oBAAoB;GACzB;EACF;EACA,OAAO,0BAA0B,MAAM,aAAa,KAAK,eAAe;GACtE,gBAAgB;GAChB;GACA;GACA;EACF,CAAC;CACH;CAEA,iBACE,UACA,MACM;EACN,MAAM,eAAe,KAAK,mBAAmB,IAAI;EAIjD,IACE,gBAAgB,IAAI,KACnB,gBAAgB,QACf,0BACE,aAAa,SACb,KAAK,qBAAqB,CAC5B,GAEF;EAEF,IAAI,CAAC,KAAK,4BAA4B,UAAU,IAAI,GAClD,KAAK,WAAW,UAAU;GAAE,MAAM;GAAQ;EAAK,CAAC;CAEpD;CAEA,wBAA+B,MAAuC;EACpE,IAAI,CAAC,KAAK,cAAc,GACtB,OAAO,QAAQ,uBACb,IAAI,MACF,uEACF,CACF;EAGF,MAAM,OAAO,KAAK,kCAAkC,IAAI;EACxD,OAAO,QAAQ,OACX,KAAK,0BAA0B,IAAI,IACnC,QAAQ,QAAQ;CACtB;CAEA,kCACE,MAC4B;EAC5B,IAAI,KAAK,YAAY,MAAM;GACzB,QAAQ,KACN,wGAAwG,KAAK,YAAY,KAAK,KAAK,QAAQ,KAAK,KAAK,GACvJ;GACA;EACF;EACA,MAAM,eAAe,KAAK,mBAAmB,IAAI;EACjD,MAAM,eAAe,KAAK,oBAAoB,IAAI;EAClD,IACE,gBAAgB,QAChB,gBAAgB,IAAI,KACnB,gBAAgB,QACf,0BACE,aAAa,SACb,KAAK,qBAAqB,CAC5B,GAEF;EAEF,MAAM,eAAe,KAAK,sBAAsB,YAAY;EAC5D,IAAI,gBAAgB,MAAM;GACxB,aAAa,aAAa;GAC1B,OAAO,aAAa,SAAS,SAAS,eAAe,KAAA;EACvD,OAAO;GACL,MAAM,OAAO,KAAK,gBAAgB;IAAE,MAAM;IAAQ;GAAK,GAAG,YAAY;GACtE,OAAO,KAAK,SAAS,SAAS,OAAO,KAAA;EACvC;CACF;CAEA,gBACE,MACA,cACA,YACA,eACA,2BAC8B;EAC9B,MAAM,cAAc,uBAAuB,EACzC,OAAO,KAAK,cAAc,MAC5B,CAAC;EACD,IAAI,eAAe,MAAM;GACvB,KAAK,oBAAoB;GACzB;EACF;EACA,OAAO,0BAA0B,MAAM,aAAa,KAAK,eAAe;GACtE,gBAAgB;GAChB;GACA;GACA;GACA;EACF,CAAC;CACH;CAEA,YAAyB;EACvB,KAAK;EACL,KAAK,wBAAwB;EAC7B,KAAK,iBAAiB;EACtB,MAAM,QAAQ,IAAI,0BAA0B;EAC5C,KAAK,MAAM,QAAQ,KAAK,aACtB,KAAK,0BAA0B,MAAM,KAAK;EAE5C,KAAK,UAAU,MAAM;EACrB,KAAK,UAAU,MAAM;EACrB,KAAK,wBAAwB,MAAM;EACnC,KAAK,YAAY,SAAS;EAC1B,KAAK,qBAAqB,MAAM;EAChC,KAAK,mBAAmB,MAAM;EAC9B,KAAK,eAAe,MAAM;EAC1B,KAAK,cAAc;EACnB,KAAK,gBAAgB;EACrB,KAAK,2BAA2B;CAClC;CAEA,mBAA2B,qBAAsC;EAC/D,OAAO,KAAK,wBAAwB;CACtC;CAEA,oBAA4B,WAAwC;EAClE,KAAU,WAAW,SAAS,CAAC,CAAC,OAAO,UAAU;GAE/C,IAAI,yBAAyB,KAAK,GAChC;GAEF,QAAQ,MAAM,KAAK;EACrB,CAAC;CACH;CAEA,0BAAwC;EACtC,MAAM,QAAQ,IAAI,0BAA0B;EAC5C,KAAK,MAAM,QAAQ,KAAK,eAAe,OAAO,GAC5C,IAAI,YAAY,MACd,KAAK,OAAO,KAAK;OACZ,IAAI,aAAa,IAAI,GAC1B,KAAK,0BAA0B,MAAM,KAAK;CAGhD;CAEA,mBAA2B;EACzB,KAAK,MAAM,iBAAiB,KAAK,SAC/B,cAAc,OAAO,UAAU;EAEjC,KAAK,QAAQ,SAAS;CACxB;CAEA,WAA+B;EAC7B,OAAO;GACL,qBAAqB;IACnB,IAAI,KAAK,gBAAgB,OACvB,OAAO;IAET,IAAI,KAAK,gBAAgB,MACvB,OAAO;IAET,OAAO;GACT,EAAA,CAAG;GACH,cAAc,KAAK,QAAQ;GAC3B,eAAe,KAAK;GACpB,aAAa,KAAK,QAAQ,QACvB,MAAM,EAAE,aAAa,QAAQ,EAAE,yBAAyB,IAC3D,CAAC,CAAC;GACF,aAAa,KAAK,YAAY;GAC9B,aAAa,KAAK,eAAe;GACjC,kBAAkB,KAAK,iBAAiB;GACxC,eAAe,KAAK,UAAU;GAC9B,eAAe,KAAK,UAAU;EAChC;CACF;CAUA,WACE,UACA,SACM;EACN,IAAI,KAAK,gBAAgB,OACvB,KAAK,oBAAoB;EAG3B,MAAM,eAAe,KAAK,0BAA0B,OAAO;EAC3D,MAAM,eACJ,gBAAgB,OACZ,KAAK,sBAAsB,YAAY,IACvC,KAAA;EACN,IAAI,gBAAgB,MAAM;GACxB,KAAK,8BAA8B,UAAU,YAAY;GACzD,KAAK,kBAAkB,cAAc,QAAQ;GAC7C,KAAK,2BAA2B;GAChC;EACF;EAEA,KAAK,8BAA8B,QAAQ;EAC3C,MAAM,KAAK,KAAK,kBAAkB;EAClC,MAAM,eAAe,KAAK,IAAI;EAC9B,MAAM,EAAE,yBAAyB;EACjC,MAAM,cAA0B;GAC9B,QAAQ,QAAQ,MAAhB;IACE,KAAK,QACH,OAAO;KACL,MAAM;KACN;KACA,SAAS;MAAE,GAAG;MAAS;KAAG;KAC1B,2BAAW,IAAI,IAAI,CAAC,QAAgC,CAAC;KACrD,YAAY;KACZ;KACA,2BAAW,IAAI,IAAI;KACnB;KACA;IACF;IACF,KAAK,QACH,OAAO;KACL,MAAM;KACN;KACA,SAAS;MAAE,GAAG;MAAS;KAAG;KAC1B,2BAAW,IAAI,IAAI,CAAC,QAAgC,CAAC;KACrD,YAAY;KACZ;KACA,2BAAW,IAAI,IAAI;KACnB;KACA;IACF;GACJ;EACF,EAAA,CAAG;EACH,KAAK,kBAAkB,MAAM,QAAQ;CACvC;CAEA,gBACE,SACA,cACY;EACZ,IAAI,KAAK,gBAAgB,OACvB,KAAK,oBAAoB;EAE3B,MAAM,KAAK,KAAK,kBAAkB;EAClC,MAAM,eAAe,KAAK,IAAI;EAC9B,MAAM,EAAE,yBAAyB;EACjC,MAAM,cAA0B;GAC9B,QAAQ,QAAQ,MAAhB;IACE,KAAK,QACH,OAAO;KACL,MAAM;KACN;KACA,SAAS;MAAE,GAAG;MAAS;KAAG;KAC1B,2BAAW,IAAI,IAA0B;KACzC,YAAY;KACZ;KACA,2BAAW,IAAI,IAAI;KACnB;KACA;IACF;IACF,KAAK,QACH,OAAO;KACL,MAAM;KACN;KACA,SAAS;MAAE,GAAG;MAAS;KAAG;KAC1B,2BAAW,IAAI,IAA0B;KACzC,YAAY;KACZ;KACA,2BAAW,IAAI,IAAI;KACnB;KACA;IACF;GACJ;EACF,EAAA,CAAG;EACH,KAAK,kBAAkB,IAAI;EAC3B,OAAO;CACT;CAEA,kBACE,MACA,UACM;EACN,KAAK,YAAY,KAAK,IAAI;EAC1B,IAAI,YAAY,MACd,KAAK,qBAAqB,IAAI,UAAU,IAAI;EAE9C,IAAI,KAAK,gBAAgB,MACvB,KAAK,mBAAmB,IAAI,KAAK,cAAc,IAAI;EAErD,KAAK,WAAW;CAClB;CAEA,MAAc,+BACZ,iBACA,MACA,OACe;EACf,IAAI;GAEF,MAAM,cAAc,uBAAuB;GAC3C,MAAM,kBAAkB,MAAM,QAC3B,SACC,eAAe,QAAQ,CAAC,qBAAqB,MAAM,WAAW,CAClE;GACA,IAAI,gBAAgB,SAAS,GAC3B,KAAU,sBAAsB,UAAU,KAAK,cAAc,KAAK,GAAG,CACnE,QACA,GAAG,eACL,CAAC,CAAC,CAAC,OAAO,UAAmB;IAC3B,QAAQ,MAAM,KAAK;GACrB,CAAC;GAGH,MAAM,qBACJ,KAAK,yBAAyB,eAC1B,CAAC,IACD,MAAM,QAAQ,SAAS,CAAC,gBAAgB,MAAM,IAAI,IAAI,CAAC;GAE7D,IAAI,mBAAmB,SAAS,GAAG;IACjC,IAAI,qBAAqB,kBAAkB,GACzC,KAAK,QAAQ,oBACX,qBAAqB,kBAAkB;SAEzC,KAAK,QAAQ,oBACX,MAAM,iBAAiB,kBAAkB;GAE/C;GAGA,IAAI,CAAC,KAAK,eAAe,IAAI,KAAK,EAAE,GAAG;IACrC,IAAI,gBAAgB,cAAc,KAAK,IAAI;KACzC,KAAK,mBAAmB,iBAAiB,IAAI;KAC7C,KAAK,2BAA2B;KAChC,IAAI,KAAK,YAAY,SAAS,GAC5B,KAAK,WAAW;IAEpB;IACA;GACF;GACA,KAAK,YAAY,iBAAiB,IAAI;EACxC,SAAS,OAAO;GACd,KAAK,0BAA0B,MAAM,qBAAqB,KAAK,CAAC;GAChE,KAAK,mBAAmB,iBAAiB,IAAI;GAC7C,KAAK,2BAA2B;GAChC,IAAI,KAAK,YAAY,SAAS,GAC5B,KAAK,WAAW;EAEpB;CACF;CAEA,oBACE,eACA,UACM;EACN,MAAM,OAAO,KAAK,eAAe,IAAI,SAAS,EAAE;EAChD,IAAI;GACF,IAAI,QAAQ,MAGV,MAAM;QACD,IAAI,SAAS,SAAS,SAAS;IACpC,MAAM,QAAQ,IAAI,MAAM,SAAS,KAAK;IACtC,IAAI,SAAS,OACX,MAAM,QAAQ,SAAS;IAEzB,IAAI,YAAY,MACd,KAAK,OAAO,KAAK;SACZ,IAAI,aAAa,IAAI,GAAG;KAC7B,KAAK,qBAAqB,MAAM,KAAK;KACrC,KAAK,0BAA0B,MAAM,KAAK;IAC5C,OACE,MAAM,IAAI,MAAM,wCAAwC;IAE1D,MAAM;GACR,OAAO;IAGL,IAAI,aAAa,IAAI,GACnB,KAAK,MAAM,EAAE,UAAU,KAAK,QAAQ,qBAAqB,CAAC,GACxD,cAAc,MAAM,IAAI,IAAI;IAGhC,QAAQ,SAAS,aAAjB;KACE,KAAK;MACH,IAAI,KAAK,SAAS,cAChB,MAAM,IAAI,MAAM,+CAA+C;MAEjE,KAAK,2BAA2B,eAAe,KAAK,OAAO;MAC3D,KAAK,QAAQ;MACb;KACF,KAAK;MACH,IAAI,KAAK,SAAS,sBAChB,MAAM,IAAI,MAAM,+CAA+C;MAEjE,KAAK,QAAQ;MACb;KACF,KAAK,QAAQ;MACX,IAAI,KAAK,SAAS,QAChB,MAAM,IAAI,MAAM,+CAA+C;MAEjE,MAAM,EAAE,YAAY;MACpB,IACE,CAAC,KAAK,oBAAoB,IAAI,KAC9B,CAAC,0BAA0B,SAAS,KAAK,qBAAqB,CAAC,GAE/D,MAAM;MAER,MAAM,EAAE,YAAY;MACpB,MAAM,SAA2B;OAC/B,GAAG,SAAS;OACZ,MAAM,gBAAgB,SAAS,OAAO,IAAI;MAC5C;MACA,KAAK,2BAA2B,eAAe,OAAO;MACtD,IAAI,KAAK,sBAAsB,MAC7B,KAAK,UAAU,IAAI,KAAK,oBAAoB;OAAE;OAAQ;MAAQ,CAAC;MAEjE,KAAK,2BAA2B,IAAI;MACpC,KAAK,oBAAoB,MAAM,QAAQ,OAAO;MAC9C;KACF;KACA,KAAK,QAAQ;MACX,IAAI,KAAK,SAAS,QAChB,MAAM,IAAI,MAAM,+CAA+C;MAEjE,MAAM,EAAE,YAAY;MACpB,IACE,CAAC,KAAK,oBAAoB,IAAI,KAC9B,CAAC,0BAA0B,SAAS,KAAK,qBAAqB,CAAC,GAE/D,MAAM;MAER,MAAM,EAAE,YAAY;MACpB,MAAM,SAA2B;OAC/B,GAAG,SAAS;OACZ,MAAM;QACJ,eAAe,gBACb,SAAS,OAAO,KAAK,aACvB;QACA,eAAe,gBACb,SAAS,OAAO,KAAK,aACvB;OACF;MACF;MACA,KAAK,2BAA2B,eAAe,OAAO;MACtD,IAAI,KAAK,sBAAsB,MAC7B,KAAK,UAAU,IAAI,KAAK,oBAAoB;OAAE;OAAQ;MAAQ,CAAC;MAEjE,KAAK,2BAA2B,IAAI;MACpC,KAAK,oBAAoB,MAAM,QAAQ,OAAO;MAC9C;KACF;IACF;GACF;EACF,SAAS,OAAO;GACd,IAAI,UAAU,iBACZ,QAAQ,MAAM,OAAO,MAAM,QAAQ;EAEvC;EAEA,KAAK,mBAAmB,eAAe,MAAM,SAAS,EAAE;EACxD,KAAK,2BAA2B;EAChC,IAAI,KAAK,YAAY,SAAS,GAG5B,KAAK,WAAW;CAEpB;CAEA;CACA,aAAqB;EACnB,IAAI,KAAK,gBAAgB,MAAM;EAC/B,KAAK,eAAe,QAAQ,QAAQ,CAAC,CAAC,KAAK,KAAK,UAAU;EAC1D,KAAK,2BAA2B;CAClC;CAEA,mBACE,MACA,eACA;EACA,cAAc,YAAY,KAAK;EAC/B,IAAI,aAAa,IAAI,GAAG;GACtB,KAAK,4BAA4B,IAAI;GACrC,KAAK,sBAAsB,IAAI;EACjC;EACA,KAAK,eAAe,IAAI,KAAK,IAAI,IAAI;CACvC;CAEA,mBACE,eACA,MACA,YAAyC,MAAM,IAC/C;EACA,IAAI,cAAc,cAAc,WAC9B,cAAc,YAAY,KAAA;EAE5B,IAAI,cAAc,0BAA0B,WAC1C,cAAc,wBAAwB,KAAA;EAExC,IAAI,QAAQ,MAAM;GAChB,IAAI,aAAa,IAAI,GAAG;IACtB,KAAK,0BAA0B,MAAM,IAAI,4BAA4B,CAAC;IACtE,KAAK,sBAAsB,IAAI;IAC/B,KAAK,kBAAkB,IAAI;GAC7B;GACA,KAAK,eAAe,OAAO,KAAK,EAAE;EACpC;CACF;CAEA,YACE,eACA,MACM;EACN,IAAI,2BAA2B,KAAK,OAAO,GACzC,KAAK,4BAA4B,eAAe,KAAK,OAAO;EAE9D,IAAI,CAAC,KAAK,eAAe,IAAI,KAAK,EAAE,GAClC,KAAK,mBAAmB,MAAM,aAAa;EAE7C,IAAI;GAGF,IAAI,KAAK,SAAS,QAChB,KAAK,qBAAqB,KAAK,QAAQ,KAAK;QACvC,IAAI,KAAK,SAAS,QACvB,KAAK,qBAAqB,KAAK,QAAQ,KAAK;GAE9C,cAAc,OAAO,YAAY,KAAK,OAAO;EAC/C,SAAS,OAAO;GACd,QAAQ,MAAM,qCAAqC,KAAK;GACxD,IAAI,aAAa,IAAI,GAAG;IACtB,KAAK,qBAAqB,MAAM,KAAK;IACrC,KAAK,0BAA0B,MAAM,qBAAqB,KAAK,CAAC;GAClE,OAAO,IAAI,YAAY,MACrB,KAAK,OAAO,KAAc;GAE5B,KAAK,mBAAmB,eAAe,IAAI;GAC3C,IAAI,KAAK,YAAY,SAAS,GAC5B,KAAK,WAAW;EAEpB;EACA,KAAK,2BAA2B;CAClC;CAEA,4BACE,eACA,SACM;EACN,IAAI,QAAQ,2BAA2B,MACrC;EAEF,MAAM,UAAU,2BAA2B;EAC3C,IAAI,cAAc,2BAA2B,SAC3C;EAEF,QAAQ,0BAA0B;EAClC,QAAQ,qBAAqB,uBAAuB;CACtD;CAEA,2BACE,eACA,SACM;EACN,IAAI,QAAQ,2BAA2B,MACrC;EAEF,cAAc,0BAA0B,QAAQ;CAClD;CAEA,mBACE,OAC2B;EAC3B,IAAI;EACJ,KAAK,MAAM,iBAAiB,KAAK,SAAS;GACxC,IACE,cAAc,aAAa,QAC3B,cAAc,yBAAyB,QACvC,CAAC,cAAc,aAEf;GAEF,SAAS;GACT,IAAI,MAAM,WAAW,GACnB;GAEF,IAAI,eAAe;GACnB,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,cAAc,MAAM,IAAI,IAAI,GAAG;IAClC,eAAe;IACf;GACF;GAEF,IAAI,cACF;EAEJ;EACA,OAAO;CACT;CAEA,oBAA4B,MAAwC;EAClE,IAAI,KAAK,YAAY,MACnB;EAEF,OAAO,QAAQ,KAAK,SAAS,GAAG,KAAK;CACvC;CAEA,oBAA4B,MAA4C;EACtE,IAAI,KAAK,YAAY,MACnB;EAEF,OAAO,QAAQ,KAAK,SAAS,GAAG,KAAK;CACvC;CAEA,0BACE,SACoB;EACpB,QAAQ,QAAQ,MAAhB;GACE,KAAK,QACH,OAAO,KAAK,oBAAoB,QAAQ,IAAI;GAC9C,KAAK,QACH,OAAO,KAAK,oBAAoB,QAAQ,IAAI;EAChD;CACF;CAEA,iBAAyB,MAA2B;EAClD,KAAK,MAAM,YAAY,aAAa,IAAI,GACtC,IAAI,KAAK,wBAAwB,IAAI,QAAQ,GAC3C,OAAO;EAGX,OAAO;CACT;CAEA,kBACE,MACA,UACM;EACN,IAAI,KAAK,SAAS,QAChB,KAAK,UAAU,IAAI,QAAgC;OAEnD,KAAK,UAAU,IAAI,QAAgC;EAErD,IAAI,KAAK,eAAe,IAAI,KAAK,EAAE,GACjC,KAAK,wBAAwB,IAAI,UAAU,KAAK,EAAE;OAElD,KAAK,qBAAqB,IAAI,UAAU,IAAI;CAEhD;CAEA,8BACE,UACA,YACM;EACN,MAAM,OAAO,KAAK,qBAAqB,IAAI,QAAQ;EACnD,IAAI,QAAQ,QAAQ,SAAS,YAC3B;EAEF,KAAK,qBAAqB,OAAO,QAAQ;EACzC,KAAK,6BAA6B,MAAM,QAAQ;EAChD,IAAI,CAAC,KAAK,cAAc,KAAK,UAAU,SAAS,GAC9C,KAAK,iBAAiB,IAAI;CAE9B;CAEA,6BACE,MACA,UACM;EACN,IAAI,KAAK,SAAS,QAChB,KAAK,UAAU,OAAO,QAAgC;OAEtD,KAAK,UAAU,OAAO,QAAgC;CAE1D;CAEA,iBAAyB,MAAwB;EAC/C,MAAM,QAAQ,KAAK,YAAY,QAAQ,IAAI;EAC3C,IAAI,UAAU,IACZ,KAAK,YAAY,OAAO,OAAO,CAAC;EAElC,KAAK,0BAA0B,MAAM,IAAI,4BAA4B,CAAC;EACtE,KAAK,4BAA4B,IAAI;EACrC,KAAK,kBAAkB,IAAI;CAC7B;CAEA,iBAAyB,MAAwB;EAC/C,KAAK,0BAA0B,MAAM,IAAI,4BAA4B,CAAC;EACtE,KAAK,sBAAsB,IAAI;EAC/B,KAAK,kBAAkB,IAAI;EAC3B,KAAK,eAAe,OAAO,KAAK,EAAE;CACpC;CAEA,0BAAkC,MAAiC;EACjE,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAK,UAAU,IAAI;IAAE;IAAS;GAAO,CAAC;EACxC,CAAC;CACH;CAEA,2BAAmC,MAAwB;EACzD,KAAK,MAAM,aAAa,KAAK,WAC3B,UAAU,QAAQ;EAEpB,KAAK,UAAU,MAAM;CACvB;CAEA,0BAAkC,MAAkB,OAAoB;EACtE,KAAK,MAAM,aAAa,KAAK,WAC3B,UAAU,OAAO,KAAK;EAExB,KAAK,UAAU,MAAM;CACvB;CAEA,wBAAsC;EACpC,KAAK,IAAI,QAAQ,KAAK,YAAY,SAAS,GAAG,SAAS,GAAG,SAAS;GACjE,MAAM,OAAO,KAAK,YAAY;GAC9B,IAAI,KAAK,yBAAyB,KAAK,sBACrC,KAAK,iBAAiB,IAAI;EAE9B;EAEA,KAAK,MAAM,QAAQ,MAAM,KAAK,KAAK,eAAe,OAAO,CAAC,GACxD,IACE,aAAa,IAAI,KACjB,KAAK,yBAAyB,KAAK,sBAEnC,KAAK,iBAAiB,IAAI;CAGhC;CAEA,4BAAoC,MAAwB;EAC1D,KAAK,MAAM,YAAY,aAAa,IAAI,GACtC,IAAI,KAAK,qBAAqB,IAAI,QAAQ,MAAM,MAC9C,KAAK,qBAAqB,OAAO,QAAQ;CAG/C;CAEA,kBAA0B,MAAwB;EAChD,IACE,KAAK,gBAAgB,QACrB,KAAK,mBAAmB,IAAI,KAAK,YAAY,MAAM,MAEnD,KAAK,mBAAmB,OAAO,KAAK,YAAY;CAEpD;CAEA,sBAA8B,MAAwB;EACpD,KAAK,MAAM,YAAY,aAAa,IAAI,GACtC,KAAK,wBAAwB,IAAI,UAAU,KAAK,EAAE;CAEtD;CAEA,sBAA8B,MAAwB;EACpD,KAAK,MAAM,YAAY,aAAa,IAAI,GACtC,IAAI,KAAK,wBAAwB,IAAI,QAAQ,MAAM,KAAK,IACtD,KAAK,wBAAwB,OAAO,QAAQ;CAGlD;CAEA,oBACE,MACA,QACA,SACM;EACN,KAAK,MAAM,YAAY,KAAK,WAC1B,IAAI,KAAK,wBAAwB,IAAI,QAAQ,MAAM,KAAK,IACtD,SAAS,mBAAmB,KAAK,QAAQ,MAAM,QAAQ,OAAO;CAGpE;CAEA,oBACE,MACA,QACA,SACM;EACN,KAAK,MAAM,YAAY,KAAK,WAC1B,IAAI,KAAK,wBAAwB,IAAI,QAAQ,MAAM,KAAK,IACtD,SAAS,mBAAmB,KAAK,QAAQ,MAAM,QAAQ,OAAO;CAGpE;CAEA,qBAA6B,MAAkB,OAAsB;EACnE,KAAK,MAAM,YAAY,aAAa,IAAI,GACtC,IAAI,KAAK,wBAAwB,IAAI,QAAQ,MAAM,KAAK,IACtD,SAAS,iBAAiB,KAAK;CAGrC;CAEA,4BACE,UACA,MACS;EACT,KAAK,MAAM,QAAQ,KAAK,mBAAmB,GACzC,IACE,KAAK,SAAS,UACd,KAAK,oBAAoB,IAAI,KAC7B,KAAK,UAAU,IAAI,QAAQ,KAC3B,cAAc,MAAM,KAAK,QAAQ,IAAI,GAErC,OAAO;EAGX,OAAO;CACT;CAEA,4BACE,UACA,MACS;EACT,KAAK,MAAM,QAAQ,KAAK,mBAAmB,GACzC,IACE,KAAK,SAAS,UACd,KAAK,oBAAoB,IAAI,KAC7B,KAAK,UAAU,IAAI,QAAQ,KAC3B,oBAAoB,KAAK,QAAQ,MAAM,IAAI,GAE3C,OAAO;EAGX,OAAO;CACT;CAEA,sBAA8B,cAA8C;EAC1E,MAAM,OAAO,KAAK,mBAAmB,IAAI,YAAY;EACrD,OAAO,QAAQ,QAAQ,KAAK,oBAAoB,IAAI,IAAI,OAAO,KAAA;CACjE;CAEA,oBAA4B,MAA2B;EACrD,OAAO,KAAK,yBAAyB,KAAK;CAC5C;CAEA,CAAS,qBAA4C;EACnD,KAAK,MAAM,QAAQ,KAAK,aACtB,MAAM;EAER,KAAK,MAAM,QAAQ,KAAK,eAAe,OAAO,GAC5C,IAAI,aAAa,IAAI,GACnB,MAAM;CAGZ;CAEA,oBAA6C;EAC3C,OAAO,OAAO,EAAE,KAAK;CACvB;AACF;AAEA,SAAS,2BACP,SAC4E;CAC5E,OACE,QAAQ,SAAS,gBACjB,QAAQ,SAAS,UACjB,QAAQ,SAAS;AAErB;AAEA,SAAS,iBAAiB,MAA4C;CACpE,MAAM,wBAAQ,IAAI,IAAwB;CAC1C,IAAI,KAAK,SAAS,gBAAgB,KAAK,SAAS,sBAC9C,OAAO,CAAC;CAEV,QAAQ,KAAK,MAAb;EACE,KAAK;GACH,MAAM,IACJ,KAAK,QAAQ,KAAK,QAChB,wBAAwB,KAAK,QAAQ,KAAK,IAAI,CAClD;GACA;EAEF,KAAK;GACH,MAAM,IACJ,KAAK,QAAQ,KAAK,QAChB,wBAAwB,KAAK,QAAQ,KAAK,IAAI,CAClD;GACA,MAAM,IACJ,KAAK,QAAQ,KAAK,QAChB,wBAAwB,KAAK,QAAQ,KAAK,YAAY,GAAG,CAC7D;CAGJ;CACA,MAAM,OAAO,MAAM;CACnB,OAAO,MAAM,KAAK,KAAK;AACzB;AAEA,SAAS,aAAa,MAAsD;CAC1E,OAAO,MAAM,SAAS,UAAU,MAAM,SAAS;AACjD;AAEA,SAAS,aACP,MACkD;CAClD,OAAO,KAAK;AACd;AAEA,SAAS,qBAAqB,OAAuB;CACnD,IAAI,iBAAiB,OACnB,OAAO;CAET,IAAI,SAAS,QAAQ,OAAO,UAAU,UAAU;EAC9C,IAAI,WAAW,SAAS,MAAM,iBAAiB,OAC7C,OAAO,MAAM;EAEf,IAAI,aAAa,SAAS,OAAO,MAAM,YAAY,UACjD,OAAO,IAAI,MAAM,MAAM,OAAO;CAElC;CACA,OAAO,IAAI,MAAM,OAAO,KAAK,CAAC;AAChC;AAKA,SAAS,0BACP,OACuB;CACvB,MAAM,QAAiB,WAAW,QAAQ,MAAM,QAAQ,KAAA;CACxD,MAAM,UACJ,aAAa,SACb,OAAO,MAAM,YAAY,YACzB,MAAM,YAAY,KACd,MAAM,UACN,iBAAiB,QACf,MAAM,UACN;CACR,OAAO,IAAI,sBACT,qCAAqC,WACrC,iBAAiB,QAAQ,EAAE,MAAM,IAAI,KAAA,CACvC;AACF"}
1
+ {"version":3,"file":"WorkerPoolManager.js","names":[],"sources":["../../src/worker/WorkerPoolManager.ts"],"sourcesContent":["import LRUMapPkg from 'lru_map';\nimport type { LRUMap } from 'lru_map';\n\nimport { DEFAULT_THEMES } from '../constants';\nimport { resolveHighlighterType } from '../highlighter/highlighterType';\nimport { areLanguagesAttached } from '../highlighter/languages/areLanguagesAttached';\nimport { getResolvedLanguages } from '../highlighter/languages/getResolvedLanguages';\nimport { hasResolvedLanguages } from '../highlighter/languages/hasResolvedLanguages';\nimport { resolveLanguages } from '../highlighter/languages/resolveLanguages';\nimport {\n getHighlighterIfLoaded,\n getSharedHighlighter,\n HighlighterDisposedError,\n} from '../highlighter/shared_highlighter';\nimport { getResolvedThemes } from '../highlighter/themes/getResolvedThemes';\nimport { hasResolvedThemes } from '../highlighter/themes/hasResolvedThemes';\nimport { resolveThemes } from '../highlighter/themes/resolveThemes';\nimport type {\n DiffsHighlighter,\n DiffsTheme,\n DiffsThemeNames,\n FileContents,\n FileDiffMetadata,\n HighlighterTypes,\n HunkExpansionRegion,\n RenderDiffOptions,\n RenderDiffResult,\n RenderFileOptions,\n RenderFileResult,\n SupportedLanguages,\n ThemedDiffResult,\n ThemedFileResult,\n} from '../types';\nimport { areDiffRenderOptionsEqual } from '../utils/areDiffRenderOptionsEqual';\nimport { areDiffTargetsEqual } from '../utils/areDiffTargetsEqual';\nimport { areFileRenderOptionsEqual } from '../utils/areFileRenderOptionsEqual';\nimport { areFilesEqual } from '../utils/areFilesEqual';\nimport { areThemesEqual } from '../utils/areThemesEqual';\nimport {\n getCustomExtensionsMap,\n getCustomExtensionsVersion,\n getFiletypeFromFileName,\n} from '../utils/getFiletypeFromFileName';\nimport { getThemes } from '../utils/getThemes';\nimport { isDiffPlainText } from '../utils/isDiffPlainText';\nimport { isFilePlainText } from '../utils/isFilePlainText';\nimport { renderDiffWithHighlighter } from '../utils/renderDiffWithHighlighter';\nimport { renderFileWithHighlighter } from '../utils/renderFileWithHighlighter';\nimport {\n isHandledWorkerPoolError,\n markWorkerErrorReported,\n WorkerPoolTaskCanceledError,\n WorkerPoolTerminatedError,\n WorkerPoolWorkerError,\n} from './errors';\nimport { decodeHastLines } from './hastLinesTransport';\nimport type {\n AllWorkerTasks,\n DiffRendererInstance,\n FileRendererInstance,\n InitializeWorkerRequest,\n InitializeWorkerTask,\n RenderDiffRequest,\n RenderDiffTask,\n RenderFileRequest,\n RenderFileTask,\n ResolvedLanguage,\n SetRenderOptionsWorkerTask,\n SubmitRequest,\n WorkerInitializationRenderOptions,\n WorkerPoolOptions,\n WorkerRenderingOptions,\n WorkerRequestId,\n WorkerStats,\n} from './types';\nimport type {\n InitializeWorkerWireRequest,\n WorkerWireResponse,\n} from './workerMessage';\n\nconst IGNORE_RESPONSE = Symbol('IGNORE_RESPONSE');\nconst DEFAULT_WORKER_INITIALIZATION_TIMEOUT = 10_000;\n\ninterface GetCachesResult {\n fileCache: LRUMap<string, RenderFileResult>;\n diffCache: LRUMap<string, RenderDiffResult>;\n}\n\ninterface ManagedWorker {\n worker: Worker;\n requestId: string | undefined;\n pendingSetupRequestId: WorkerRequestId | undefined;\n initialized: boolean;\n langs: Set<SupportedLanguages>;\n customExtensionsVersion: number;\n}\n\ninterface ThemeSubscriber {\n onThemeChange(): void;\n}\n\ntype RenderTask = RenderFileTask | RenderDiffTask;\n\ntype RenderTaskInstance = FileRendererInstance | DiffRendererInstance;\n\nexport class WorkerPoolManager {\n private readonly preferredHighlighter: HighlighterTypes;\n private renderOptions: WorkerRenderingOptions;\n private renderOptionsRequestVersion = 0;\n private renderOptionsVersion = 0;\n private initialized: Promise<void> | boolean = false;\n private workers: ManagedWorker[] = [];\n // Tasks that are waiting to get processed by a worker\n private queuedTasks: RenderTask[] = [];\n private queuedTaskByInstance = new Map<RenderTaskInstance, RenderTask>();\n\n // Tasks that map to highlightKey are essentially singular, so we only\n // need one map to include queued and active\n private taskByHighlightKey = new Map<string, RenderTask>();\n\n // Tasks that have already been sent to a worker and are awaiting a response.\n private activeTaskById = new Map<WorkerRequestId, AllWorkerTasks>();\n private activeRequestByInstance = new Map<\n RenderTaskInstance,\n WorkerRequestId\n >();\n\n private nextRequestId = 0;\n private themeSubscribers = new Set<ThemeSubscriber>();\n private workersFailed = false;\n private terminated = false;\n private statSubscribers = new Set<(stats: WorkerStats) => unknown>();\n private fileCache: LRUMap<string, RenderFileResult>;\n private diffCache: LRUMap<string, RenderDiffResult>;\n private _queuedBroadcast: number | undefined;\n // Incremented on terminate so async lifecycle work can identify stale results.\n private lifecycleGeneration = 0;\n\n constructor(\n private options: WorkerPoolOptions,\n {\n langs,\n theme = DEFAULT_THEMES,\n useTokenTransformer = false,\n lineDiffType = 'word-alt',\n maxLineDiffLength = 1000,\n tokenizeMaxLineLength = 1000,\n preferredHighlighter,\n }: WorkerInitializationRenderOptions\n ) {\n this.preferredHighlighter = resolveHighlighterType(preferredHighlighter);\n this.renderOptions = {\n theme,\n useTokenTransformer,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n this.fileCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.diffCache = new LRUMapPkg.LRUMap(options.totalASTLRUCacheSize ?? 100);\n this.queueInitialization(langs);\n }\n\n public isWorkingPool(): boolean {\n return !this.workersFailed && !this.terminated;\n }\n\n /**\n * Whether a file or diff fits within `mainThreadMaxCharacters`, so it\n * highlights on the main thread instead of a worker. Files count `contents`;\n * diffs count both sides.\n */\n public shouldHighlightOnMainThread(\n fileOrDiff: FileContents | FileDiffMetadata\n ): boolean {\n const { mainThreadMaxCharacters = -1 } = this.options;\n const characterCount =\n 'contents' in fileOrDiff\n ? fileOrDiff.contents.length\n : fileOrDiff.deletionCharacterCount + fileOrDiff.additionCharacterCount;\n return characterCount <= mainThreadMaxCharacters;\n }\n\n public getFileResultCache(file: FileContents): RenderFileResult | undefined {\n return file.cacheKey != null\n ? this.fileCache.get(file.cacheKey)\n : undefined;\n }\n\n public getDiffResultCache(\n diff: FileDiffMetadata\n ): RenderDiffResult | undefined {\n return diff.cacheKey != null\n ? this.diffCache.get(diff.cacheKey)\n : undefined;\n }\n\n // Returns whether the result was stored. Results without a cache key or\n // rendered with outdated options are dropped.\n public setFileResultCache(\n cacheKey: string | undefined,\n { result, options }: RenderFileResult\n ): boolean {\n if (\n cacheKey == null ||\n !areFileRenderOptionsEqual(options, this.getFileRenderOptions())\n ) {\n return false;\n }\n this.fileCache.set(cacheKey, { result, options });\n this.queueBroadcastStateChanges();\n return true;\n }\n\n // Returns whether the result was stored. Results without a cache key or\n // rendered with outdated options are dropped.\n public setDiffResultCache(\n cacheKey: string | undefined,\n { result, options }: RenderDiffResult\n ): boolean {\n if (\n cacheKey == null ||\n !areDiffRenderOptionsEqual(options, this.getDiffRenderOptions())\n ) {\n return false;\n }\n this.diffCache.set(cacheKey, { result, options });\n this.queueBroadcastStateChanges();\n return true;\n }\n\n public inspectCaches(): GetCachesResult {\n const { fileCache, diffCache } = this;\n return { fileCache, diffCache };\n }\n\n public evictFileFromCache(cacheKey: string): boolean {\n try {\n return this.fileCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n public evictDiffFromCache(cacheKey: string): boolean {\n try {\n return this.diffCache.delete(cacheKey) !== undefined;\n } finally {\n this.queueBroadcastStateChanges();\n }\n }\n\n async setRenderOptions({\n theme = this.renderOptions.theme ?? DEFAULT_THEMES,\n useTokenTransformer = this.renderOptions.useTokenTransformer ?? false,\n lineDiffType = this.renderOptions.lineDiffType ?? 'word-alt',\n maxLineDiffLength = this.renderOptions.maxLineDiffLength ?? 1000,\n tokenizeMaxLineLength = this.renderOptions.tokenizeMaxLineLength ?? 1000,\n }: Partial<WorkerRenderingOptions>): Promise<void> {\n const { lifecycleGeneration } = this;\n const renderOptionsRequestVersion = ++this.renderOptionsRequestVersion;\n const isCurrentRequest = (): boolean =>\n this.isCurrentLifecycle(lifecycleGeneration) &&\n this.renderOptionsRequestVersion === renderOptionsRequestVersion;\n try {\n const newRenderOptions: WorkerRenderingOptions = {\n theme,\n useTokenTransformer,\n lineDiffType,\n maxLineDiffLength,\n tokenizeMaxLineLength,\n };\n if (!this.isInitialized()) {\n try {\n await this.initialize();\n } catch (error) {\n // When the workers fail to start, components highlight on the main\n // thread with this pool's render options. Keep applying the new\n // options so theme changes still take effect there;\n // setRenderOptionsOnWorkers skips the failed workers. The pool has\n // already reported the failure.\n if (!this.workersFailed) {\n throw error;\n }\n }\n }\n if (\n !isCurrentRequest() ||\n areDiffRenderOptionsEqual(newRenderOptions, this.renderOptions)\n ) {\n return;\n }\n\n const themeNames = getThemes(theme);\n let resolvedThemes: DiffsTheme[] = [];\n if (!areThemesEqual(newRenderOptions.theme, this.renderOptions.theme)) {\n resolvedThemes = hasResolvedThemes(\n themeNames,\n this.preferredHighlighter\n )\n ? getResolvedThemes(themeNames, this.preferredHighlighter)\n : await resolveThemes(themeNames, this.preferredHighlighter);\n }\n\n if (!isCurrentRequest()) {\n return;\n }\n\n // Warning: resolvedThemes use the workers' backend. The main-thread\n // highlighter can be another backend, so it loads its own copies.\n if (getHighlighterIfLoaded({ theme }) == null) {\n await this.loadSharedHighlighter(themeNames, ['text']);\n if (!isCurrentRequest()) {\n return;\n }\n }\n\n const workerSetup = this.setRenderOptionsOnWorkers(\n newRenderOptions,\n resolvedThemes\n );\n\n this.renderOptions = newRenderOptions;\n this.renderOptionsVersion++;\n this.diffCache.clear();\n this.fileCache.clear();\n this.invalidateRenderTasks();\n\n for (const instance of this.themeSubscribers) {\n instance.onThemeChange();\n }\n\n await workerSetup;\n } catch (error) {\n if (error instanceof WorkerPoolTerminatedError || !isCurrentRequest()) {\n return;\n }\n throw error;\n }\n }\n\n public getPreferredHighlighter(): HighlighterTypes {\n return this.preferredHighlighter;\n }\n\n public getFileRenderOptions(): RenderFileOptions {\n const { tokenizeMaxLineLength, theme, useTokenTransformer } =\n this.renderOptions;\n return { theme, useTokenTransformer, tokenizeMaxLineLength };\n }\n\n public getDiffRenderOptions(): RenderDiffOptions {\n return { ...this.renderOptions };\n }\n\n private async setRenderOptionsOnWorkers(\n renderOptions: WorkerRenderingOptions,\n resolvedThemes: DiffsTheme[]\n ): Promise<void> {\n if (this.workersFailed) {\n return;\n }\n if (!this.isInitialized()) {\n await this.initialize();\n }\n const taskPromises: Promise<void>[] = [];\n for (const managedWorker of this.workers) {\n if (!managedWorker.initialized) {\n console.log({ managedWorker });\n throw new Error(\n 'setRenderOptionsOnWorkers: Somehow we have an uninitialized worker'\n );\n }\n taskPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const task: SetRenderOptionsWorkerTask = {\n type: 'set-render-options',\n id,\n request: {\n type: 'set-render-options',\n id,\n renderOptions,\n resolvedThemes,\n },\n resolve,\n reject,\n requestStart: Date.now(),\n };\n // Render-option updates are posted immediately, but the worker stays\n // unavailable for new render work until it acknowledges this message.\n this.activeTaskById.set(id, task);\n managedWorker.pendingSetupRequestId = id;\n managedWorker.worker.postMessage(task.request);\n })\n );\n }\n await Promise.all(taskPromises);\n }\n\n public subscribeToThemeChanges(instance: ThemeSubscriber): () => void {\n this.themeSubscribers.add(instance);\n this.queueBroadcastStateChanges();\n return () => {\n this.unsubscribeToThemeChanges(instance);\n this.queueBroadcastStateChanges();\n };\n }\n\n public unsubscribeToThemeChanges(instance: ThemeSubscriber): void {\n this.themeSubscribers.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n public subscribeToStatChanges(\n callback: (stats: WorkerStats) => unknown\n ): () => void {\n this.statSubscribers.add(callback);\n callback(this.getStats());\n return () => {\n this.statSubscribers.delete(callback);\n };\n }\n\n private queueBroadcastStateChanges() {\n if (this._queuedBroadcast != null) return;\n this._queuedBroadcast = requestAnimationFrame(this._broadcastStateChanges);\n }\n\n private _broadcastStateChanges = () => {\n if (this._queuedBroadcast != null) {\n cancelAnimationFrame(this._queuedBroadcast);\n this._queuedBroadcast = undefined;\n }\n const stats = this.getStats();\n for (const callback of this.statSubscribers) {\n callback(stats);\n }\n };\n\n public cleanUpTasks(instance: RenderTaskInstance): void {\n this.detachInstanceFromQueuedTasks(instance);\n const requestId = this.activeRequestByInstance.get(instance);\n if (requestId != null) {\n const task = this.activeTaskById.get(requestId);\n if (isRenderTask(task)) {\n this.detachInstanceFromRenderTask(task, instance);\n if (!task.primeCache && task.instances.size === 0) {\n this.removeActiveTask(task);\n }\n } else {\n this.activeTaskById.delete(requestId);\n }\n }\n this.activeRequestByInstance.delete(instance);\n this.queueBroadcastStateChanges();\n }\n\n public isInitialized(): boolean {\n return this.initialized === true;\n }\n\n public async initialize(languages: SupportedLanguages[] = []): Promise<void> {\n if (this.initialized === true) {\n if (getHighlighterIfLoaded({ theme: this.renderOptions.theme }) == null) {\n await this.loadSharedHighlighter(getThemes(this.renderOptions.theme), [\n 'text',\n ...languages,\n ]);\n }\n return;\n } else if (this.initialized === false) {\n this.terminated = false;\n const { lifecycleGeneration } = this;\n const initialization = new Promise<void>((resolve, reject) => {\n void (async () => {\n try {\n const themes = getThemes(this.renderOptions.theme);\n const resolvedThemes = hasResolvedThemes(\n themes,\n this.preferredHighlighter\n )\n ? getResolvedThemes(themes, this.preferredHighlighter)\n : await resolveThemes(themes, this.preferredHighlighter);\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n resolve();\n return;\n }\n\n let resolvedLanguages: ResolvedLanguage[] = [];\n if (this.preferredHighlighter !== 'highlights') {\n resolvedLanguages = hasResolvedLanguages(languages)\n ? getResolvedLanguages(languages)\n : await resolveLanguages(languages);\n }\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n resolve();\n return;\n }\n\n await Promise.all([\n this.loadSharedHighlighter(themes, ['text', ...languages]),\n this.initializeWorkers(resolvedThemes, resolvedLanguages),\n ]);\n\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n this.terminateWorkers();\n resolve();\n return;\n }\n this.initialized = true;\n this.drainQueue();\n this.queueBroadcastStateChanges();\n resolve();\n } catch (e) {\n if (\n e instanceof WorkerPoolTerminatedError ||\n !this.isCurrentLifecycle(lifecycleGeneration)\n ) {\n resolve();\n return;\n }\n this.initialized = false;\n this.workersFailed = true;\n // A partial pool is not supported, so stop every worker before\n // consumers rerender through the main-thread fallback.\n this.cancelActiveWorkerTasks();\n this.terminateWorkers();\n this.activeTaskById.clear();\n for (const task of this.queuedTasks) {\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(e));\n }\n this.queueBroadcastStateChanges();\n reject(e);\n }\n })();\n });\n this.initialized = initialization;\n this.queueBroadcastStateChanges();\n // Return the startup promise so callers can await initialization and the\n // constructor's error handler can catch startup failures.\n return initialization;\n } else {\n return this.initialized;\n }\n }\n\n // Warning: workers never use the main-thread highlighter. If\n // disposeHighlighter() runs during this load, pool work must not fail; the\n // next plain render loads the highlighter again.\n private async loadSharedHighlighter(\n themes: DiffsThemeNames[],\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n await getSharedHighlighter({\n themes,\n langs,\n preferredHighlighter: this.preferredHighlighter,\n });\n } catch (error) {\n if (!(error instanceof HighlighterDisposedError)) {\n throw error;\n }\n }\n }\n\n private async initializeWorkers(\n resolvedThemes: DiffsTheme[],\n resolvedLanguages: ResolvedLanguage[]\n ): Promise<void> {\n this.workersFailed = false;\n const initPromises: Promise<unknown>[] = [];\n const customExtensionVersion = getCustomExtensionsVersion();\n const customExtensionMap =\n customExtensionVersion > 0 ? getCustomExtensionsMap() : undefined;\n if (this.workers.length > 0) {\n this.terminateWorkers();\n }\n for (let i = 0; i < (this.options.poolSize ?? 8); i++) {\n const worker = this.options.workerFactory();\n const managedWorker: ManagedWorker = {\n worker,\n requestId: undefined,\n pendingSetupRequestId: undefined,\n initialized: false,\n langs: new Set(['text', ...resolvedLanguages.map(({ name }) => name)]),\n customExtensionsVersion: 0,\n };\n worker.addEventListener(\n 'message',\n (event: MessageEvent<WorkerWireResponse>) => {\n this.handleWorkerMessage(managedWorker, event.data);\n }\n );\n worker.addEventListener('error', (error) =>\n this.handleWorkerError(managedWorker, error)\n );\n this.workers.push(managedWorker);\n initPromises.push(\n new Promise<void>((resolve, reject) => {\n const id = this.generateRequestId();\n const request: InitializeWorkerWireRequest = {\n type: 'initialize',\n resultFormat: 'hast-ops-v1',\n id,\n renderOptions: this.renderOptions,\n preferredHighlighter: this.preferredHighlighter,\n resolvedThemes,\n resolvedLanguages,\n customExtensionsVersion:\n customExtensionMap != null ? customExtensionVersion : undefined,\n customExtensionMap,\n };\n const task: InitializeWorkerTask = {\n type: 'initialize',\n id,\n request,\n resolve() {\n managedWorker.initialized = true;\n resolve();\n },\n reject,\n requestStart: Date.now(),\n };\n managedWorker.pendingSetupRequestId = id;\n this.activeTaskById.set(id, task);\n this.executeTask(managedWorker, task);\n })\n );\n }\n const timeoutMs =\n this.options.workerInitializationTimeout ??\n DEFAULT_WORKER_INITIALIZATION_TIMEOUT;\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n Promise.all(initPromises),\n new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(\n new Error(\n `WorkerPoolManager: worker initialization timed out after ${timeoutMs}ms`\n )\n );\n }, timeoutMs);\n }),\n ]);\n } finally {\n if (timeoutId != null) {\n clearTimeout(timeoutId);\n }\n }\n }\n\n /**\n * Pass worker errors to onWorkerError, or log them if no callback is set.\n *\n * A startup error rejects initialization so components can highlight on the\n * main thread. Other requests wait for their own responses: worker.ts catches\n * request errors, so this event may be unrelated to the current request.\n * A worker that stops responding remains busy and receives no further work.\n */\n private handleWorkerError(\n managedWorker: ManagedWorker,\n event: ErrorEvent | Event\n ): void {\n const { onWorkerError } = this.options;\n if (onWorkerError != null) {\n try {\n onWorkerError(event, managedWorker.worker);\n } catch (hookError) {\n console.error('WorkerPoolManager: onWorkerError threw:', hookError);\n }\n } else {\n console.error('Worker error:', event, managedWorker);\n }\n const { pendingSetupRequestId } = managedWorker;\n if (pendingSetupRequestId == null) {\n return;\n }\n const task = this.activeTaskById.get(pendingSetupRequestId);\n if (task?.type !== 'initialize') {\n return;\n }\n const error = errorFromWorkerErrorEvent(event);\n if (onWorkerError != null) {\n markWorkerErrorReported(error);\n }\n task.reject(error);\n this.cleanWorkerAndTask(managedWorker, task);\n }\n\n private drainQueue = () => {\n this._queuedDrain = undefined;\n // If we are initializing or things got cancelled while initializing, we\n // should not attempt to drain the queue\n if (this.initialized !== true || this.queuedTasks.length === 0) {\n return;\n }\n for (let i = 0; i < this.queuedTasks.length; ) {\n const task = this.queuedTasks[i];\n // If any instance has a request in progress, we should wait for it to\n // finish before starting work that would notify that instance.\n if (this.hasActiveRequest(task)) {\n i++;\n continue;\n }\n const langs = getLangsFromRequest(task.request);\n const availableWorker = this.getAvailableWorker(langs);\n if (availableWorker == null) {\n break;\n }\n this.queuedTasks.splice(i, 1);\n this.assignWorkerToTask(task, availableWorker);\n void this.resolveLanguagesAndExecuteTask(availableWorker, task, langs);\n }\n this.queueBroadcastStateChanges();\n };\n\n public highlightFileAST(\n instance: FileRendererInstance,\n file: FileContents\n ): void {\n const cachedResult = this.getFileResultCache(file);\n // If we've already highlighted the file or it's plain text, we should not\n // attempt to highlight. This should be mostly never hit, but it's just an\n // extra level of safety\n if (\n isFilePlainText(file) ||\n (cachedResult != null &&\n areFileRenderOptionsEqual(\n cachedResult.options,\n this.getFileRenderOptions()\n ))\n ) {\n return;\n }\n if (!this.hasMatchingFileInstanceTask(instance, file)) {\n this.submitTask(instance, { type: 'file', file });\n }\n }\n\n public primeFileHighlightCache(file: FileContents): Promise<void> {\n if (!this.isWorkingPool()) {\n return Promise.reject(\n new Error(\n 'WorkerPoolManager.primeFileHighlightCache: worker pool is not working'\n )\n );\n }\n\n if (!this.shouldPrimeFileHighlightCache(file)) {\n return Promise.resolve();\n }\n if (this.shouldHighlightOnMainThread(file)) {\n const options = this.getFileRenderOptions();\n return this.primeHighlightCacheOnMainThread(\n getLangsFromRequest({ type: 'file', file }),\n options.theme,\n (highlighter) =>\n this.setFileResultCache(file.cacheKey, {\n result: renderFileWithHighlighter(file, highlighter, options),\n options,\n })\n );\n }\n const task = this.getOrCreateFileHighlightCacheTask(file);\n return task != null\n ? this.createRenderTaskCallbacks(task)\n : Promise.resolve();\n }\n\n // Priming needs a cache key to store the result under, and skips files that\n // are plain text or already cached with the current render options.\n private shouldPrimeFileHighlightCache(file: FileContents): boolean {\n if (file.cacheKey == null) {\n console.warn(\n `WorkerPoolManager.primeFileHighlightCache: priming highlight cache requires file.cacheKey; skipping \"${file.name}\".`\n );\n return false;\n }\n const cachedResult = this.getFileResultCache(file);\n return (\n !isFilePlainText(file) &&\n (cachedResult == null ||\n !areFileRenderOptionsEqual(\n cachedResult.options,\n this.getFileRenderOptions()\n ))\n );\n }\n\n private getOrCreateFileHighlightCacheTask(\n file: FileContents\n ): RenderFileTask | undefined {\n const highlightKey = this.getFileHighlightKey(file);\n if (highlightKey == null) {\n return undefined;\n }\n const existingTask = this.getTaskByHighlightKey(highlightKey);\n if (existingTask != null) {\n if (existingTask.type !== 'file') {\n throw new Error(\n 'WorkerPoolManager.getOrCreateFileHighlightCacheTask: Invalid task type'\n );\n }\n existingTask.primeCache = true;\n return existingTask;\n } else {\n const task = this.submitCacheTask({ type: 'file', file }, highlightKey);\n if (task.type !== 'file') {\n throw new Error(\n 'WorkerPoolManager.getOrCreateFileHighlightCacheTask: Invalid task created'\n );\n }\n return task;\n }\n }\n\n public getPlainFileAST(\n file: FileContents,\n startingLine: number,\n totalLines: number,\n lines?: string[]\n ): ThemedFileResult | undefined {\n const highlighter = getHighlighterIfLoaded({\n theme: this.renderOptions.theme,\n });\n if (highlighter == null) {\n this.queueInitialization();\n return undefined;\n }\n return renderFileWithHighlighter(file, highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n lines,\n });\n }\n\n public highlightDiffAST(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): void {\n const cachedResult = this.getDiffResultCache(diff);\n // If we've already highlighted the diff or it's plain text, we should not\n // attempt to highlight. This should be mostly never hit, but it's just an\n // extra level of safety\n if (\n isDiffPlainText(diff) ||\n (cachedResult != null &&\n areDiffRenderOptionsEqual(\n cachedResult.options,\n this.getDiffRenderOptions()\n ))\n ) {\n return;\n }\n if (!this.hasMatchingDiffInstanceTask(instance, diff)) {\n this.submitTask(instance, { type: 'diff', diff });\n }\n }\n\n public primeDiffHighlightCache(diff: FileDiffMetadata): Promise<void> {\n if (!this.isWorkingPool()) {\n return Promise.reject(\n new Error(\n 'WorkerPoolManager.primeDiffHighlightCache: worker pool is not working'\n )\n );\n }\n\n if (!this.shouldPrimeDiffHighlightCache(diff)) {\n return Promise.resolve();\n }\n if (this.shouldHighlightOnMainThread(diff)) {\n const options = this.getDiffRenderOptions();\n return this.primeHighlightCacheOnMainThread(\n getLangsFromRequest({ type: 'diff', diff }),\n options.theme,\n (highlighter) =>\n this.setDiffResultCache(diff.cacheKey, {\n result: renderDiffWithHighlighter(diff, highlighter, options),\n options,\n })\n );\n }\n const task = this.getOrCreateDiffHighlightCacheTask(diff);\n return task != null\n ? this.createRenderTaskCallbacks(task)\n : Promise.resolve();\n }\n\n // Priming needs a cache key to store the result under, and skips diffs that\n // are plain text or already cached with the current render options.\n private shouldPrimeDiffHighlightCache(diff: FileDiffMetadata): boolean {\n if (diff.cacheKey == null) {\n console.warn(\n `WorkerPoolManager.primeDiffHighlightCache: priming highlight cache requires diff.cacheKey; skipping \"${diff.prevName ?? diff.name}\" -> \"${diff.name}\".`\n );\n return false;\n }\n const cachedResult = this.getDiffResultCache(diff);\n return (\n !isDiffPlainText(diff) &&\n (cachedResult == null ||\n !areDiffRenderOptionsEqual(\n cachedResult.options,\n this.getDiffRenderOptions()\n ))\n );\n }\n\n // Runs `highlightAndCacheResult` with the main-thread highlighter for primes\n // within the main-thread threshold. It runs synchronously when the\n // highlighter already has the theme and languages, and after loading them\n // otherwise. Like a worker prime, it rejects as canceled when nothing could\n // be cached, such as after a render options change during the load.\n private primeHighlightCacheOnMainThread(\n langs: SupportedLanguages[],\n theme: WorkerRenderingOptions['theme'],\n highlightAndCacheResult: (highlighter: DiffsHighlighter) => boolean\n ): Promise<void> {\n function highlightAndCacheIfLoaded(): boolean {\n const highlighter = getHighlighterIfLoaded({ theme, langs });\n return highlighter != null && highlightAndCacheResult(highlighter);\n }\n if (highlightAndCacheIfLoaded()) {\n return Promise.resolve();\n }\n const { lifecycleGeneration } = this;\n return this.loadSharedHighlighter(getThemes(theme), [\n 'text',\n ...langs,\n ]).then(() => {\n if (!this.isCurrentLifecycle(lifecycleGeneration)) {\n throw new WorkerPoolTerminatedError();\n }\n if (!highlightAndCacheIfLoaded()) {\n throw new WorkerPoolTaskCanceledError();\n }\n });\n }\n\n private getOrCreateDiffHighlightCacheTask(\n diff: FileDiffMetadata\n ): RenderDiffTask | undefined {\n const highlightKey = this.getDiffHighlightKey(diff);\n if (highlightKey == null) {\n return undefined;\n }\n const existingTask = this.getTaskByHighlightKey(highlightKey);\n if (existingTask != null) {\n if (existingTask.type !== 'diff') {\n throw new Error(\n 'WorkerPoolManager.getOrCreateDiffHighlightCacheTask: Invalid task type'\n );\n }\n existingTask.primeCache = true;\n return existingTask;\n } else {\n const task = this.submitCacheTask({ type: 'diff', diff }, highlightKey);\n if (task.type !== 'diff') {\n throw new Error(\n 'WorkerPoolManager.getOrCreateDiffHighlightCacheTask: Invalid task created'\n );\n }\n return task;\n }\n }\n\n public getPlainDiffAST(\n diff: FileDiffMetadata,\n startingLine: number,\n totalLines: number,\n expandedHunks?: Map<number, HunkExpansionRegion> | true,\n collapsedContextThreshold?: number\n ): ThemedDiffResult | undefined {\n const highlighter = getHighlighterIfLoaded({\n theme: this.renderOptions.theme,\n });\n if (highlighter == null) {\n this.queueInitialization();\n return undefined;\n }\n return renderDiffWithHighlighter(diff, highlighter, this.renderOptions, {\n forcePlainText: true,\n startingLine,\n totalLines,\n expandedHunks,\n collapsedContextThreshold,\n });\n }\n\n public terminate(): void {\n this.lifecycleGeneration++;\n this.cancelActiveWorkerTasks();\n this.terminateWorkers();\n const error = new WorkerPoolTerminatedError();\n for (const task of this.queuedTasks) {\n this.rejectRenderTaskCallbacks(task, error);\n }\n this.fileCache.clear();\n this.diffCache.clear();\n this.activeRequestByInstance.clear();\n this.queuedTasks.length = 0;\n this.queuedTaskByInstance.clear();\n this.taskByHighlightKey.clear();\n this.activeTaskById.clear();\n this.initialized = false;\n this.workersFailed = false;\n this.terminated = true;\n this.queueBroadcastStateChanges();\n }\n\n private isCurrentLifecycle(lifecycleGeneration: number): boolean {\n return this.lifecycleGeneration === lifecycleGeneration;\n }\n\n private queueInitialization(languages?: SupportedLanguages[]): void {\n void this.initialize(languages).catch((error) => {\n // Skip cancellations and worker errors already passed to onWorkerError.\n if (isHandledWorkerPoolError(error)) {\n return;\n }\n console.error(error);\n });\n }\n\n private cancelActiveWorkerTasks(): void {\n const error = new WorkerPoolTerminatedError();\n for (const task of this.activeTaskById.values()) {\n if ('reject' in task) {\n task.reject(error);\n } else if (isRenderTask(task)) {\n this.rejectRenderTaskCallbacks(task, error);\n }\n }\n }\n\n private terminateWorkers() {\n for (const managedWorker of this.workers) {\n managedWorker.worker.terminate();\n }\n this.workers.length = 0;\n }\n\n public getStats(): WorkerStats {\n return {\n managerState: (() => {\n if (this.initialized === false) {\n return 'waiting';\n }\n if (this.initialized !== true) {\n return 'initializing';\n }\n return 'initialized';\n })(),\n totalWorkers: this.workers.length,\n workersFailed: this.workersFailed,\n busyWorkers: this.workers.filter(\n (w) => w.requestId != null || w.pendingSetupRequestId != null\n ).length,\n queuedTasks: this.queuedTasks.length,\n activeTasks: this.activeTaskById.size,\n themeSubscribers: this.themeSubscribers.size,\n fileCacheSize: this.fileCache.size,\n diffCacheSize: this.diffCache.size,\n };\n }\n\n private submitTask(\n instance: FileRendererInstance,\n request: Omit<RenderFileRequest, 'id'>\n ): void;\n private submitTask(\n instance: DiffRendererInstance,\n request: Omit<RenderDiffRequest, 'id'>\n ): void;\n private submitTask(\n instance: FileRendererInstance | DiffRendererInstance,\n request: SubmitRequest\n ): void {\n if (this.initialized === false) {\n this.queueInitialization();\n }\n\n const highlightKey = this.getHighlightKeyForRequest(request);\n const existingTask =\n highlightKey != null\n ? this.getTaskByHighlightKey(highlightKey)\n : undefined;\n if (existingTask != null) {\n this.detachInstanceFromQueuedTasks(instance, existingTask);\n this.addInstanceToTask(existingTask, instance);\n this.queueBroadcastStateChanges();\n return;\n }\n\n this.detachInstanceFromQueuedTasks(instance);\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const { renderOptionsVersion } = this;\n const task: RenderTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instances: new Set([instance as FileRendererInstance]),\n primeCache: false,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instances: new Set([instance as DiffRendererInstance]),\n primeCache: false,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n }\n })();\n this.enqueueRenderTask(task, instance);\n }\n\n private submitCacheTask(\n request: SubmitRequest,\n highlightKey: string\n ): RenderTask {\n if (this.initialized === false) {\n this.queueInitialization();\n }\n const id = this.generateRequestId();\n const requestStart = Date.now();\n const { renderOptionsVersion } = this;\n const task: RenderTask = (() => {\n switch (request.type) {\n case 'file':\n return {\n type: 'file',\n id,\n request: { ...request, id },\n instances: new Set<FileRendererInstance>(),\n primeCache: true,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n case 'diff':\n return {\n type: 'diff',\n id,\n request: { ...request, id },\n instances: new Set<DiffRendererInstance>(),\n primeCache: true,\n highlightKey,\n callbacks: new Set(),\n renderOptionsVersion,\n requestStart,\n };\n }\n })();\n this.enqueueRenderTask(task);\n return task;\n }\n\n private enqueueRenderTask(\n task: RenderTask,\n instance?: RenderTaskInstance\n ): void {\n this.queuedTasks.push(task);\n if (instance != null) {\n this.queuedTaskByInstance.set(instance, task);\n }\n if (task.highlightKey != null) {\n this.taskByHighlightKey.set(task.highlightKey, task);\n }\n this.queueDrain();\n }\n\n private async resolveLanguagesAndExecuteTask(\n availableWorker: ManagedWorker,\n task: RenderFileTask | RenderDiffTask,\n langs: SupportedLanguages[]\n ): Promise<void> {\n try {\n // Preload the same languages on the main thread for editing.\n const highlighter = getHighlighterIfLoaded();\n const mainThreadLangs = langs.filter(\n (lang) =>\n highlighter == null || !areLanguagesAttached(lang, highlighter)\n );\n if (mainThreadLangs.length > 0) {\n void this.loadSharedHighlighter(getThemes(this.renderOptions.theme), [\n 'text',\n ...mainThreadLangs,\n ]).catch((error: unknown) => {\n console.error(error);\n });\n }\n // Add resolved languages if required\n const workerMissingLangs =\n this.preferredHighlighter === 'highlights'\n ? []\n : langs.filter((lang) => !availableWorker.langs.has(lang));\n\n if (workerMissingLangs.length > 0) {\n if (hasResolvedLanguages(workerMissingLangs)) {\n task.request.resolvedLanguages =\n getResolvedLanguages(workerMissingLangs);\n } else {\n task.request.resolvedLanguages =\n await resolveLanguages(workerMissingLangs);\n }\n }\n // If the task has been cleaned up after awaiting language resolving,\n // lets fully clean it up\n if (!this.activeTaskById.has(task.id)) {\n if (availableWorker.requestId === task.id) {\n this.cleanWorkerAndTask(availableWorker, task);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n return;\n }\n this.executeTask(availableWorker, task);\n } catch (error) {\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(error));\n this.cleanWorkerAndTask(availableWorker, task);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n }\n\n private handleWorkerMessage(\n managedWorker: ManagedWorker,\n response: WorkerWireResponse\n ): void {\n const task = this.activeTaskById.get(response.id);\n try {\n if (task == null) {\n // If we can't find a task for this response, it probably means the\n // component has been unmounted, so we should silently ignore it\n throw IGNORE_RESPONSE;\n } else if (response.type === 'error') {\n const error = new Error(response.error);\n if (response.stack) {\n error.stack = response.stack;\n }\n if ('reject' in task) {\n task.reject(error);\n } else if (isRenderTask(task)) {\n this.notifyHighlightError(task, error);\n this.rejectRenderTaskCallbacks(task, error);\n } else {\n throw new Error('handleWorkerMessage: unknown task type');\n }\n throw error;\n } else {\n // A failed request may not have attached its languages. Only remember\n // them after success so later tasks resend grammars that were rejected.\n if (isRenderTask(task)) {\n for (const { name } of task.request.resolvedLanguages ?? []) {\n managedWorker.langs.add(name);\n }\n }\n switch (response.requestType) {\n case 'initialize':\n if (task.type !== 'initialize') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n this.syncCustomExtensionVersion(managedWorker, task.request);\n task.resolve();\n break;\n case 'set-render-options':\n if (task.type !== 'set-render-options') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n task.resolve();\n break;\n case 'file': {\n if (task.type !== 'file') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { options } = response;\n if (\n !this.isCurrentRenderTask(task) ||\n !areFileRenderOptionsEqual(options, this.getFileRenderOptions())\n ) {\n throw IGNORE_RESPONSE;\n }\n const { request } = task;\n const result: ThemedFileResult = {\n ...response.result,\n code: decodeHastLines(response.result.code),\n };\n this.syncCustomExtensionVersion(managedWorker, request);\n if (task.cacheKeyAtDispatch != null) {\n this.fileCache.set(task.cacheKeyAtDispatch, { result, options });\n }\n this.resolveRenderTaskCallbacks(task);\n this.notifyFileInstances(task, result, options);\n break;\n }\n case 'diff': {\n if (task.type !== 'diff') {\n throw new Error('handleWorkerMessage: task/response dont match');\n }\n const { options } = response;\n if (\n !this.isCurrentRenderTask(task) ||\n !areDiffRenderOptionsEqual(options, this.getDiffRenderOptions())\n ) {\n throw IGNORE_RESPONSE;\n }\n const { request } = task;\n const result: ThemedDiffResult = {\n ...response.result,\n code: {\n deletionLines: decodeHastLines(\n response.result.code.deletionLines\n ),\n additionLines: decodeHastLines(\n response.result.code.additionLines\n ),\n },\n };\n this.syncCustomExtensionVersion(managedWorker, request);\n if (task.cacheKeyAtDispatch != null) {\n this.diffCache.set(task.cacheKeyAtDispatch, { result, options });\n }\n this.resolveRenderTaskCallbacks(task);\n this.notifyDiffInstances(task, result, options);\n break;\n }\n }\n }\n } catch (error) {\n if (error !== IGNORE_RESPONSE) {\n console.error(error, task, response);\n }\n }\n\n this.cleanWorkerAndTask(managedWorker, task, response.id);\n this.queueBroadcastStateChanges();\n if (this.queuedTasks.length > 0) {\n // We queue drain so that potentially multiple workers can free up\n // allowing for better language matches if possible\n this.queueDrain();\n }\n }\n\n private _queuedDrain: Promise<void> | undefined;\n private queueDrain() {\n if (this._queuedDrain != null) return;\n this._queuedDrain = Promise.resolve().then(this.drainQueue);\n this.queueBroadcastStateChanges();\n }\n\n private assignWorkerToTask(\n task: AllWorkerTasks,\n managedWorker: ManagedWorker\n ) {\n managedWorker.requestId = task.id;\n if (isRenderTask(task)) {\n this.clearQueuedInstanceRequests(task);\n this.trackInstanceRequests(task);\n }\n this.activeTaskById.set(task.id, task);\n }\n\n private cleanWorkerAndTask(\n managedWorker: ManagedWorker,\n task?: AllWorkerTasks,\n requestId: WorkerRequestId | undefined = task?.id\n ) {\n if (managedWorker.requestId === requestId) {\n managedWorker.requestId = undefined;\n }\n if (managedWorker.pendingSetupRequestId === requestId) {\n managedWorker.pendingSetupRequestId = undefined;\n }\n if (task != null) {\n if (isRenderTask(task)) {\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearInstanceRequests(task);\n this.clearHighlightKey(task);\n }\n this.activeTaskById.delete(task.id);\n }\n }\n\n private executeTask(\n managedWorker: ManagedWorker,\n task: AllWorkerTasks\n ): void {\n if (shouldSyncCustomExtensions(task.request)) {\n this.maybeAttachCustomExtensions(managedWorker, task.request);\n }\n if (!this.activeTaskById.has(task.id)) {\n this.assignWorkerToTask(task, managedWorker);\n }\n try {\n // postMessage clones the request now, so keep the matching cache key on\n // the task instead of reading the caller's mutable target on response.\n if (task.type === 'file') {\n task.cacheKeyAtDispatch = task.request.file.cacheKey;\n } else if (task.type === 'diff') {\n task.cacheKeyAtDispatch = task.request.diff.cacheKey;\n }\n managedWorker.worker.postMessage(task.request);\n } catch (error) {\n console.error('Failed to post message to worker:', error);\n if (isRenderTask(task)) {\n this.notifyHighlightError(task, error);\n this.rejectRenderTaskCallbacks(task, normalizeWorkerError(error));\n } else if ('reject' in task) {\n task.reject(error as Error);\n }\n this.cleanWorkerAndTask(managedWorker, task);\n if (this.queuedTasks.length > 0) {\n this.queueDrain();\n }\n }\n this.queueBroadcastStateChanges();\n }\n\n private maybeAttachCustomExtensions(\n managedWorker: ManagedWorker,\n request: InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest\n ): void {\n if (request.customExtensionsVersion != null) {\n return;\n }\n const version = getCustomExtensionsVersion();\n if (managedWorker.customExtensionsVersion >= version) {\n return;\n }\n request.customExtensionsVersion = version;\n request.customExtensionMap = getCustomExtensionsMap();\n }\n\n private syncCustomExtensionVersion(\n managedWorker: ManagedWorker,\n request: InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest\n ): void {\n if (request.customExtensionsVersion == null) {\n return;\n }\n managedWorker.customExtensionsVersion = request.customExtensionsVersion;\n }\n\n private getAvailableWorker(\n langs: SupportedLanguages[]\n ): ManagedWorker | undefined {\n let worker: ManagedWorker | undefined;\n for (const managedWorker of this.workers) {\n if (\n managedWorker.requestId != null ||\n managedWorker.pendingSetupRequestId != null ||\n !managedWorker.initialized\n ) {\n continue;\n }\n worker = managedWorker;\n if (langs.length === 0) {\n break;\n }\n let hasEveryLang = true;\n for (const lang of langs) {\n if (!managedWorker.langs.has(lang)) {\n hasEveryLang = false;\n break;\n }\n }\n if (hasEveryLang) {\n break;\n }\n }\n return worker;\n }\n\n private getFileHighlightKey(file: FileContents): string | undefined {\n if (file.cacheKey == null) {\n return undefined;\n }\n return `file:${file.cacheKey}:${this.renderOptionsVersion}`;\n }\n\n private getDiffHighlightKey(diff: FileDiffMetadata): string | undefined {\n if (diff.cacheKey == null) {\n return undefined;\n }\n return `diff:${diff.cacheKey}:${this.renderOptionsVersion}`;\n }\n\n private getHighlightKeyForRequest(\n request: SubmitRequest\n ): string | undefined {\n switch (request.type) {\n case 'file':\n return this.getFileHighlightKey(request.file);\n case 'diff':\n return this.getDiffHighlightKey(request.diff);\n }\n }\n\n private hasActiveRequest(task: RenderTask): boolean {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.has(instance)) {\n return true;\n }\n }\n return false;\n }\n\n private addInstanceToTask(\n task: RenderTask,\n instance: FileRendererInstance | DiffRendererInstance\n ): void {\n if (task.type === 'file') {\n task.instances.add(instance as FileRendererInstance);\n } else {\n task.instances.add(instance as DiffRendererInstance);\n }\n if (this.activeTaskById.has(task.id)) {\n this.activeRequestByInstance.set(instance, task.id);\n } else {\n this.queuedTaskByInstance.set(instance, task);\n }\n }\n\n private detachInstanceFromQueuedTasks(\n instance: RenderTaskInstance,\n exceptTask?: RenderTask\n ): void {\n const task = this.queuedTaskByInstance.get(instance);\n if (task == null || task === exceptTask) {\n return;\n }\n this.queuedTaskByInstance.delete(instance);\n this.detachInstanceFromRenderTask(task, instance);\n if (!task.primeCache && task.instances.size === 0) {\n this.removeQueuedTask(task);\n }\n }\n\n private detachInstanceFromRenderTask(\n task: RenderTask,\n instance: RenderTaskInstance\n ): void {\n if (task.type === 'file') {\n task.instances.delete(instance as FileRendererInstance);\n } else {\n task.instances.delete(instance as DiffRendererInstance);\n }\n }\n\n private removeQueuedTask(task: RenderTask): void {\n const index = this.queuedTasks.indexOf(task);\n if (index !== -1) {\n this.queuedTasks.splice(index, 1);\n }\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearQueuedInstanceRequests(task);\n this.clearHighlightKey(task);\n }\n\n private removeActiveTask(task: RenderTask): void {\n this.rejectRenderTaskCallbacks(task, new WorkerPoolTaskCanceledError());\n this.clearInstanceRequests(task);\n this.clearHighlightKey(task);\n this.activeTaskById.delete(task.id);\n }\n\n private createRenderTaskCallbacks(task: RenderTask): Promise<void> {\n return new Promise((resolve, reject) => {\n task.callbacks.add({ resolve, reject });\n });\n }\n\n private resolveRenderTaskCallbacks(task: RenderTask): void {\n for (const callbacks of task.callbacks) {\n callbacks.resolve();\n }\n task.callbacks.clear();\n }\n\n private rejectRenderTaskCallbacks(task: RenderTask, error: Error): void {\n for (const callbacks of task.callbacks) {\n callbacks.reject(error);\n }\n task.callbacks.clear();\n }\n\n private invalidateRenderTasks(): void {\n for (let index = this.queuedTasks.length - 1; index >= 0; index--) {\n const task = this.queuedTasks[index];\n if (task.renderOptionsVersion !== this.renderOptionsVersion) {\n this.removeQueuedTask(task);\n }\n }\n\n for (const task of Array.from(this.activeTaskById.values())) {\n if (\n isRenderTask(task) &&\n task.renderOptionsVersion !== this.renderOptionsVersion\n ) {\n this.removeActiveTask(task);\n }\n }\n }\n\n private clearQueuedInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n if (this.queuedTaskByInstance.get(instance) === task) {\n this.queuedTaskByInstance.delete(instance);\n }\n }\n }\n\n private clearHighlightKey(task: RenderTask): void {\n if (\n task.highlightKey != null &&\n this.taskByHighlightKey.get(task.highlightKey) === task\n ) {\n this.taskByHighlightKey.delete(task.highlightKey);\n }\n }\n\n private trackInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n this.activeRequestByInstance.set(instance, task.id);\n }\n }\n\n private clearInstanceRequests(task: RenderTask): void {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n this.activeRequestByInstance.delete(instance);\n }\n }\n }\n\n private notifyFileInstances(\n task: RenderFileTask,\n result: ThemedFileResult,\n options: RenderFileOptions\n ): void {\n for (const instance of task.instances) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightSuccess(task.request.file, result, options);\n }\n }\n }\n\n private notifyDiffInstances(\n task: RenderDiffTask,\n result: ThemedDiffResult,\n options: RenderDiffOptions\n ): void {\n for (const instance of task.instances) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightSuccess(task.request.diff, result, options);\n }\n }\n }\n\n private notifyHighlightError(task: RenderTask, error: unknown): void {\n for (const instance of getInstances(task)) {\n if (this.activeRequestByInstance.get(instance) === task.id) {\n instance.onHighlightError(error);\n }\n }\n }\n\n private hasMatchingFileInstanceTask(\n instance: FileRendererInstance,\n file: FileContents\n ): boolean {\n for (const task of this.iterateRenderTasks()) {\n if (\n task.type === 'file' &&\n this.isCurrentRenderTask(task) &&\n task.instances.has(instance) &&\n areFilesEqual(file, task.request.file)\n ) {\n return true;\n }\n }\n return false;\n }\n\n private hasMatchingDiffInstanceTask(\n instance: DiffRendererInstance,\n diff: FileDiffMetadata\n ): boolean {\n for (const task of this.iterateRenderTasks()) {\n if (\n task.type === 'diff' &&\n this.isCurrentRenderTask(task) &&\n task.instances.has(instance) &&\n areDiffTargetsEqual(task.request.diff, diff)\n ) {\n return true;\n }\n }\n return false;\n }\n\n private getTaskByHighlightKey(highlightKey: string): RenderTask | undefined {\n const task = this.taskByHighlightKey.get(highlightKey);\n return task != null && this.isCurrentRenderTask(task) ? task : undefined;\n }\n\n private isCurrentRenderTask(task: RenderTask): boolean {\n return task.renderOptionsVersion === this.renderOptionsVersion;\n }\n\n private *iterateRenderTasks(): Generator<RenderTask> {\n for (const task of this.queuedTasks) {\n yield task;\n }\n for (const task of this.activeTaskById.values()) {\n if (isRenderTask(task)) {\n yield task;\n }\n }\n }\n\n private generateRequestId(): WorkerRequestId {\n return `req_${++this.nextRequestId}`;\n }\n}\n\nfunction shouldSyncCustomExtensions(\n request: AllWorkerTasks['request']\n): request is InitializeWorkerRequest | RenderFileRequest | RenderDiffRequest {\n return (\n request.type === 'initialize' ||\n request.type === 'file' ||\n request.type === 'diff'\n );\n}\n\nfunction getLangsFromRequest(request: SubmitRequest): SupportedLanguages[] {\n const langs = new Set<SupportedLanguages>();\n switch (request.type) {\n case 'file': {\n langs.add(\n request.file.lang ?? getFiletypeFromFileName(request.file.name)\n );\n break;\n }\n case 'diff': {\n langs.add(\n request.diff.lang ?? getFiletypeFromFileName(request.diff.name)\n );\n langs.add(\n request.diff.lang ??\n getFiletypeFromFileName(request.diff.prevName ?? '-')\n );\n break;\n }\n }\n langs.delete('text');\n return Array.from(langs);\n}\n\nfunction isRenderTask(task: AllWorkerTasks | undefined): task is RenderTask {\n return task?.type === 'file' || task?.type === 'diff';\n}\n\nfunction getInstances(\n task: RenderTask\n): Set<FileRendererInstance | DiffRendererInstance> {\n return task.instances;\n}\n\nfunction normalizeWorkerError(error: unknown): Error {\n if (error instanceof Error) {\n return error;\n }\n if (error != null && typeof error === 'object') {\n if ('error' in error && error.error instanceof Error) {\n return error.error;\n }\n if ('message' in error && typeof error.message === 'string') {\n return new Error(error.message);\n }\n }\n return new Error(String(error));\n}\n\n// Convert a worker error event into a startup error, preserving its cause.\n// Script load failures can provide a plain Event without an error or message,\n// so use a default message when no details are available.\nfunction errorFromWorkerErrorEvent(\n event: ErrorEvent | Event\n): WorkerPoolWorkerError {\n const cause: unknown = 'error' in event ? event.error : undefined;\n const message =\n 'message' in event &&\n typeof event.message === 'string' &&\n event.message !== ''\n ? event.message\n : cause instanceof Error\n ? cause.message\n : 'the worker script failed to load (the error event carries no message)';\n return new WorkerPoolWorkerError(\n `WorkerPoolManager: worker failed: ${message}`,\n cause instanceof Error ? { cause } : undefined\n );\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { n as DiffsHighlighter, r as createDiffsThemeResolver, t as BaseStreamTokenizer } from "./stream-tokenizer-YZ6M1qSx.js";
1
+ import { n as DiffsHighlighter, r as createDiffsThemeResolver, t as BaseStreamTokenizer } from "./stream-tokenizer-DK9xp5M5.js";
2
2
  import { n as formatCSSVariablePrefix, r as appendItems } from "./worker.js";
3
3
  import { LiveTokenizer, codeToTokens, isSupportedLanguage } from "@pierre/highlights";
4
4
  //#region src/highlighter/highlights-editor.ts
@@ -314,4 +314,4 @@ var HighlightsHighlighter = class extends DiffsHighlighter {
314
314
  //#endregion
315
315
  export { HighlightsHighlighter };
316
316
 
317
- //# sourceMappingURL=highlights-sAHlxqlf.js.map
317
+ //# sourceMappingURL=highlights-CpZm9DAR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"highlights-sAHlxqlf.js","names":[],"sources":["../../src/highlighter/highlights-editor.ts","../../src/highlighter/highlights-stream.ts","../../src/highlighter/backends/highlights.ts"],"sourcesContent":["import {\n type CodeToTokensOptions as HighlightsOptions,\n LiveTokenizer,\n type LiveTokenizerUpdate,\n} from '@pierre/highlights';\n\nimport type { TextDocumentChange } from '../editor/textDocument';\nimport type { HighlightedToken, RenderRange } from '../types';\nimport { formatCSSVariablePrefix } from '../utils/formatCSSVariablePrefix';\nimport type { DiffsEditorTokenizer } from './DiffsEditorTokenizer';\nimport type { DiffsEditorTokenizerOptions } from './tokenizer-types';\nimport type { CodeToTokensOptions } from './types';\n\nexport class HighlightsEditorTokenizer implements DiffsEditorTokenizer {\n #tokenizer: LiveTokenizer;\n #version: number;\n #disposed = false;\n // Delivering these lines through onDeferTokenize would patch them twice.\n #returnedRange: readonly [start: number, end: number] | undefined;\n // Flush, edit and reset resume the lexer; reads must restore this pause.\n #paused = false;\n // Defer callbacks during bracket matching to avoid re-entering the renderer.\n #capturedLines: Map<number, HighlightedToken[]> | undefined;\n #pendingDelivery: Map<number, HighlightedToken[]> | undefined;\n\n constructor(\n private readonly options: DiffsEditorTokenizerOptions,\n private readonly resolveOptions: (\n options: CodeToTokensOptions\n ) => HighlightsOptions\n ) {\n this.#version = options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n #createTokenizer(): LiveTokenizer {\n return new LiveTokenizer({\n ...this.resolveOptions({\n lang: this.options.textDocument.languageId,\n theme: this.options.theme,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n tokenizeMaxLineLength: this.options.tokenizeMaxLineLength ?? 1000,\n }),\n code: this.options.textDocument.getText(),\n renderRange: [0, 0],\n onDeferTokenize: (lines) => this.#deliver(lines),\n });\n }\n\n #deliver(lines: Map<number, HighlightedToken[]>): void {\n const captured = this.#capturedLines;\n if (captured != null) {\n for (const [line, tokens] of lines) captured.set(line, tokens);\n return;\n }\n const range = this.#returnedRange;\n if (range != null) {\n for (const line of lines.keys()) {\n if (line >= range[0] && line < range[1]) lines.delete(line);\n }\n if (lines.size === 0) return;\n }\n this.options.onDeferTokenize(lines);\n }\n\n // Wait until bracket matching returns before patching rows. Edits, resets\n // and theme changes discard the batch because its tokens may be stale.\n #queueDelivery(lines: Map<number, HighlightedToken[]>): void {\n const pending = this.#pendingDelivery;\n if (pending != null) {\n for (const [line, tokens] of lines) pending.set(line, tokens);\n return;\n }\n this.#pendingDelivery = lines;\n queueMicrotask(() => {\n const batch = this.#pendingDelivery;\n this.#pendingDelivery = undefined;\n if (batch != null && batch.size > 0 && !this.#disposed)\n this.options.onDeferTokenize(batch);\n });\n }\n\n tokenize(\n change: TextDocumentChange,\n renderRange?: RenderRange,\n hostRealignsRows = false\n ): Map<number, HighlightedToken[]> {\n const document = this.options.textDocument;\n const start = Math.min(renderRange?.startingLine ?? 0, document.lineCount);\n const end = Math.min(\n start + (renderRange?.totalLines ?? Infinity),\n document.lineCount\n );\n const returnedStart = Math.max(start, change.startLine);\n // Edits, resets and flushes all resume the native background work.\n this.#paused = false;\n let lines: Map<number, HighlightedToken[]>;\n if (this.#version !== document.version) {\n this.#pendingDelivery = undefined;\n lines = this.#syncDocument(change, [start, end]).lines;\n this.#version = document.version;\n } else if (this.#tokenizer.lineCount !== document.lineCount) {\n this.#pendingDelivery = undefined;\n lines = this.#tokenizer.reset(document.getText(), {\n renderRange: [start, end],\n }).lines;\n } else {\n lines = new Map();\n this.#readLines(lines, returnedStart, end);\n if (this.#pendingDelivery != null) {\n for (const line of lines.keys()) this.#pendingDelivery.delete(line);\n }\n return lines;\n }\n // Balanced insert/delete batches shift rows without triggering host realignment.\n // Other structural edits need the suffix only when the host does not move rows.\n if (\n change.lineDelta === 0\n ? (change.changedLineChanges?.some(\n ([, , lineDelta]) => lineDelta !== 0\n ) ?? false)\n : !hostRealignsRows\n ) {\n this.#readLines(lines, returnedStart, end);\n }\n return lines;\n }\n\n // Reload the lexer document if edits were skipped or combined; applying\n // them to stale text can produce incorrect tokens or out-of-range reads.\n #syncDocument(\n change: TextDocumentChange,\n renderRange: readonly [start: number, end: number]\n ): LiveTokenizerUpdate {\n const document = this.options.textDocument;\n const options = { renderRange };\n if (\n Math.abs(document.version - this.#version) === 1 &&\n change.changes.length > 0 &&\n this.#tokenizer.lineCount === change.previousLineCount\n ) {\n try {\n const update = this.#tokenizer.applyEdits(\n change.changes.map(({ range, text }) => ({ range, newText: text })),\n options\n );\n if (this.#tokenizer.lineCount === document.lineCount) return update;\n } catch (error) {\n // Out-of-range edits require a reload; other errors must propagate.\n if (!(error instanceof RangeError)) throw error;\n }\n }\n return this.#tokenizer.reset(document.getText(), options);\n }\n\n // Flushing may complete lines outside [from, to); deliver those by callback.\n #readLines(\n lines: Map<number, HighlightedToken[]>,\n from: number,\n to: number\n ): void {\n this.#returnedRange = [from, to];\n try {\n this.#tokenizer.flush(to);\n } finally {\n this.#returnedRange = undefined;\n }\n for (let line = from; line < to; line++) {\n if (lines.has(line)) continue;\n const { tokens } = this.#tokenizer.getLineTokens(line);\n lines.set(\n line,\n tokens.length === 0\n ? [[0, '', '']]\n : tokens.map((token) => [\n token.offset,\n token.color ?? '',\n token.content,\n ])\n );\n }\n }\n\n setTheme(themeName: string): void {\n if (themeName === this.options.theme) return;\n this.options.theme = themeName;\n this.#tokenizer.dispose();\n this.#pendingDelivery = undefined;\n this.#paused = false;\n this.#version = this.options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n getStringCommentRegexpRangesInLine(\n lineIndex: number\n ): [number, number][] | null {\n const document = this.options.textDocument;\n if (\n this.options.matchBrackets === false ||\n lineIndex < 0 ||\n lineIndex >= document.lineCount\n )\n return null;\n // Reset and flush resume background work and invoke callbacks immediately.\n // Defer those callbacks and restore any pause before returning.\n const captured = new Map<number, HighlightedToken[]>();\n this.#capturedLines = captured;\n try {\n // Bracket matching can precede rendering. Record the reloaded version\n // so the next render does not apply the same edits again.\n if (\n this.#version !== document.version ||\n this.#tokenizer.lineCount !== document.lineCount\n ) {\n this.#pendingDelivery = undefined;\n this.#tokenizer.reset(document.getText(), {\n renderRange: [lineIndex, lineIndex + 1],\n });\n this.#version = document.version;\n }\n this.#tokenizer.flush(lineIndex + 1);\n } finally {\n this.#capturedLines = undefined;\n if (this.#paused) this.#tokenizer.pause();\n }\n if (captured.size > 0) this.#queueDelivery(captured);\n return this.#tokenizer.getLineTokens(lineIndex).bracketIgnoredRanges;\n }\n\n // Rendering calls this while background tokenization may be paused; do not resume it.\n prebuildStateStack(): void {}\n stopBackgroundTokenize(): void {\n this.pauseBackgroundTokenize();\n }\n pauseBackgroundTokenize(): void {\n this.#paused = true;\n this.#tokenizer.pause();\n }\n resumeBackgroundTokenize(): void {\n this.#paused = false;\n this.#tokenizer.resume();\n }\n dispose(): void {\n this.#disposed = true;\n this.#pendingDelivery = undefined;\n this.#tokenizer.dispose();\n }\n}\n","import { type CodeToTokensOptions, LiveTokenizer } from '@pierre/highlights';\n\nimport { appendItems } from '../utils/appendItems';\nimport { BaseStreamTokenizer } from './stream-tokenizer';\nimport type { ThemedToken } from './types';\n\n// Completed lines the tokenizer keeps before it tries to drop older ones.\nconst TRIM_LINE_COUNT = 1024;\nconst DOCUMENT_START = { line: 0, character: 0 };\n\n/** Keeps the unfinished line editable so new chunks can recall provisional tokens. */\nexport class HighlightsStreamTokenizer extends BaseStreamTokenizer {\n #tokenizer: LiveTokenizer;\n #trimLineCount = TRIM_LINE_COUNT;\n\n constructor(private readonly options: CodeToTokensOptions) {\n super();\n this.#tokenizer = new LiveTokenizer(options);\n }\n\n protected tokenizeChunk(\n chunk: string,\n stable: ThemedToken[]\n ): { unstable: ThemedToken[]; tailLength: number } {\n const lineBreaks = [...chunk.matchAll(/\\r\\n|\\r|\\n/g)];\n const startLine = this.#tokenizer.lineCount - 1;\n const position = {\n line: startLine,\n character: this.#tokenizer.getLineLength(startLine),\n };\n this.#tokenizer.applyEdits([\n { range: { start: position, end: position }, newText: chunk },\n ]);\n const lastLine = this.#tokenizer.lineCount - 1;\n let unstable: ThemedToken[] = [];\n for (let line = startLine; line <= lastLine; line++) {\n const { tokens } = this.#tokenizer.getLineTokens(line);\n for (const token of tokens) token.offset += this.stableOffset;\n if (line < lastLine) {\n appendItems(stable, tokens);\n this.pushLineBreak(\n stable,\n this.#tokenizer.getLineLength(line),\n lineBreaks[line - startLine][0]\n );\n } else {\n unstable = tokens;\n }\n }\n const tailLength = this.#tokenizer.getLineLength(lastLine);\n if (lastLine > this.#trimLineCount) {\n // Warning: keep the last completed line. Lexed from the initial state,\n // it must end in its old state, or the unfinished line would be lexed\n // from the wrong state; then restore the dropped lines.\n const text = this.#tokenizer.getText();\n const { lineChanges } = this.#tokenizer.applyEdits([\n {\n range: {\n start: DOCUMENT_START,\n end: { line: lastLine - 1, character: 0 },\n },\n newText: '',\n },\n ]);\n if (lineChanges.every((change) => change.newEndLine <= 1)) {\n this.#trimLineCount = TRIM_LINE_COUNT;\n } else {\n const keptLength = this.#tokenizer.getText().length;\n this.#tokenizer.applyEdits([\n {\n range: { start: DOCUMENT_START, end: DOCUMENT_START },\n newText: text.slice(0, text.length - keptLength),\n },\n ]);\n // Retry after the window doubles, such as inside a long comment.\n this.#trimLineCount = lastLine * 2;\n }\n }\n return { unstable, tailLength };\n }\n\n clone(): HighlightsStreamTokenizer {\n this.assertActive();\n const clone = new HighlightsStreamTokenizer(this.options);\n clone.#tokenizer.reset(this.#tokenizer.getText());\n this.copyStateTo(clone);\n return clone;\n }\n\n protected resetSource(): void {\n this.#tokenizer.reset('');\n this.#trimLineCount = TRIM_LINE_COUNT;\n }\n\n protected releaseSource(): void {\n this.#tokenizer.dispose();\n }\n}\n","import {\n codeToTokens,\n type CodeToTokensOptions as HighlightsOptions,\n isSupportedLanguage,\n type Theme,\n} from '@pierre/highlights';\n\nimport { DiffsHighlighter } from '../DiffsHighlighter';\nimport { HighlightsEditorTokenizer } from '../highlights-editor';\nimport { HighlightsStreamTokenizer } from '../highlights-stream';\nimport { createDiffsThemeResolver } from '../themes/themeResolver';\nimport type { DiffsTheme } from '../themes/types';\nimport type {\n DiffsEditorTokenizerOptions,\n DiffsStreamTokenizer,\n} from '../tokenizer-types';\nimport type { CodeToTokensOptions, TokensResult } from '../types';\n\n/**\n * Highlights uses bundled lexers. Unsupported and custom languages render as text.\n */\nexport class HighlightsHighlighter extends DiffsHighlighter {\n // Independent instances need their themes after the shared cache is cleared.\n private readonly usedThemes = new Map<string, DiffsTheme>();\n\n constructor() {\n super('highlights', createDiffsThemeResolver('highlights'));\n }\n\n getTheme(name: string): DiffsTheme {\n this.assertNotDisposed();\n const theme =\n this.themeResolver.getResolvedTheme(name) ?? this.usedThemes.get(name);\n if (theme == null) {\n throw new Error(`Theme \"${name}\" has not been resolved`);\n }\n this.usedThemes.set(name, theme);\n return theme;\n }\n\n codeToTokens(code: string, options: CodeToTokensOptions): TokensResult {\n this.assertNotDisposed();\n // Warning: use the library's shared Wasm instance. It replaces instances\n // above 8 MiB; a private instance keeps its peak memory.\n return codeToTokens(code, this.resolveOptions(options));\n }\n\n createEditorTokenizer(\n options: DiffsEditorTokenizerOptions\n ): HighlightsEditorTokenizer {\n this.assertNotDisposed();\n return new HighlightsEditorTokenizer(options, (tokenizerOptions) =>\n this.resolveOptions(tokenizerOptions)\n );\n }\n\n createStreamTokenizer(options: CodeToTokensOptions): DiffsStreamTokenizer {\n return new HighlightsStreamTokenizer(this.resolveOptions(options));\n }\n\n loadLanguages(): Promise<void> {\n this.assertNotDisposed();\n return Promise.resolve();\n }\n\n hasLoadedLanguages(): boolean {\n return !this.disposed;\n }\n\n attachLanguages(): void {\n this.assertNotDisposed();\n }\n\n protected releaseResources(): void {\n this.usedThemes.clear();\n }\n\n // Omit the unused theme key; callers may pass both keys with one undefined.\n private resolveOptions({\n theme,\n themes,\n ...options\n }: CodeToTokensOptions): HighlightsOptions {\n const lang = isSupportedLanguage(options.lang) ? options.lang : 'text';\n if (theme != null) {\n return { ...options, lang, theme: this.getZedTheme(theme) };\n }\n if (themes == null) {\n throw new Error('A theme or themes option is required');\n }\n const resolved: Record<string, Theme> = {};\n for (const [key, name] of Object.entries(themes)) {\n resolved[key] = this.getZedTheme(name);\n }\n return { ...options, lang, themes: resolved };\n }\n\n private getZedTheme(name: string): Theme {\n const theme = this.getTheme(name);\n if (theme.zed == null) {\n throw new Error(`Theme \"${name}\" does not support Highlights`);\n }\n return theme.zed;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"highlights-CpZm9DAR.js","names":[],"sources":["../../src/highlighter/highlights-editor.ts","../../src/highlighter/highlights-stream.ts","../../src/highlighter/backends/highlights.ts"],"sourcesContent":["import {\n type CodeToTokensOptions as HighlightsOptions,\n LiveTokenizer,\n type LiveTokenizerUpdate,\n} from '@pierre/highlights';\n\nimport type { TextDocumentChange } from '../editor/textDocument';\nimport type { HighlightedToken, RenderRange } from '../types';\nimport { formatCSSVariablePrefix } from '../utils/formatCSSVariablePrefix';\nimport type { DiffsEditorTokenizer } from './DiffsEditorTokenizer';\nimport type { DiffsEditorTokenizerOptions } from './tokenizer-types';\nimport type { CodeToTokensOptions } from './types';\n\nexport class HighlightsEditorTokenizer implements DiffsEditorTokenizer {\n #tokenizer: LiveTokenizer;\n #version: number;\n #disposed = false;\n // Delivering these lines through onDeferTokenize would patch them twice.\n #returnedRange: readonly [start: number, end: number] | undefined;\n // Flush, edit and reset resume the lexer; reads must restore this pause.\n #paused = false;\n // Defer callbacks during bracket matching to avoid re-entering the renderer.\n #capturedLines: Map<number, HighlightedToken[]> | undefined;\n #pendingDelivery: Map<number, HighlightedToken[]> | undefined;\n\n constructor(\n private readonly options: DiffsEditorTokenizerOptions,\n private readonly resolveOptions: (\n options: CodeToTokensOptions\n ) => HighlightsOptions\n ) {\n this.#version = options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n #createTokenizer(): LiveTokenizer {\n return new LiveTokenizer({\n ...this.resolveOptions({\n lang: this.options.textDocument.languageId,\n theme: this.options.theme,\n cssVariablePrefix: formatCSSVariablePrefix('token'),\n tokenizeMaxLineLength: this.options.tokenizeMaxLineLength ?? 1000,\n }),\n code: this.options.textDocument.getText(),\n renderRange: [0, 0],\n onDeferTokenize: (lines) => this.#deliver(lines),\n });\n }\n\n #deliver(lines: Map<number, HighlightedToken[]>): void {\n const captured = this.#capturedLines;\n if (captured != null) {\n for (const [line, tokens] of lines) captured.set(line, tokens);\n return;\n }\n const range = this.#returnedRange;\n if (range != null) {\n for (const line of lines.keys()) {\n if (line >= range[0] && line < range[1]) lines.delete(line);\n }\n if (lines.size === 0) return;\n }\n this.options.onDeferTokenize(lines);\n }\n\n // Wait until bracket matching returns before patching rows. Edits, resets\n // and theme changes discard the batch because its tokens may be stale.\n #queueDelivery(lines: Map<number, HighlightedToken[]>): void {\n const pending = this.#pendingDelivery;\n if (pending != null) {\n for (const [line, tokens] of lines) pending.set(line, tokens);\n return;\n }\n this.#pendingDelivery = lines;\n queueMicrotask(() => {\n const batch = this.#pendingDelivery;\n this.#pendingDelivery = undefined;\n if (batch != null && batch.size > 0 && !this.#disposed)\n this.options.onDeferTokenize(batch);\n });\n }\n\n tokenize(\n change: TextDocumentChange,\n renderRange?: RenderRange,\n hostRealignsRows = false\n ): Map<number, HighlightedToken[]> {\n const document = this.options.textDocument;\n const start = Math.min(renderRange?.startingLine ?? 0, document.lineCount);\n const end = Math.min(\n start + (renderRange?.totalLines ?? Infinity),\n document.lineCount\n );\n const returnedStart = Math.max(start, change.startLine);\n // Edits, resets and flushes all resume the native background work.\n this.#paused = false;\n let lines: Map<number, HighlightedToken[]>;\n if (this.#version !== document.version) {\n this.#pendingDelivery = undefined;\n lines = this.#syncDocument(change, [start, end]).lines;\n this.#version = document.version;\n } else if (this.#tokenizer.lineCount !== document.lineCount) {\n this.#pendingDelivery = undefined;\n lines = this.#tokenizer.reset(document.getText(), {\n renderRange: [start, end],\n }).lines;\n } else {\n lines = new Map();\n this.#readLines(lines, returnedStart, end);\n if (this.#pendingDelivery != null) {\n for (const line of lines.keys()) this.#pendingDelivery.delete(line);\n }\n return lines;\n }\n // Balanced insert/delete batches shift rows without triggering host realignment.\n // Other structural edits need the suffix only when the host does not move rows.\n if (\n change.lineDelta === 0\n ? (change.changedLineChanges?.some(\n ([, , lineDelta]) => lineDelta !== 0\n ) ?? false)\n : !hostRealignsRows\n ) {\n this.#readLines(lines, returnedStart, end);\n }\n return lines;\n }\n\n // Reload the lexer document if edits were skipped or combined; applying\n // them to stale text can produce incorrect tokens or out-of-range reads.\n #syncDocument(\n change: TextDocumentChange,\n renderRange: readonly [start: number, end: number]\n ): LiveTokenizerUpdate {\n const document = this.options.textDocument;\n const options = { renderRange };\n if (\n Math.abs(document.version - this.#version) === 1 &&\n change.changes.length > 0 &&\n this.#tokenizer.lineCount === change.previousLineCount\n ) {\n try {\n const update = this.#tokenizer.applyEdits(\n change.changes.map(({ range, text }) => ({ range, newText: text })),\n options\n );\n if (this.#tokenizer.lineCount === document.lineCount) return update;\n } catch (error) {\n // Out-of-range edits require a reload; other errors must propagate.\n if (!(error instanceof RangeError)) throw error;\n }\n }\n return this.#tokenizer.reset(document.getText(), options);\n }\n\n // Flushing may complete lines outside [from, to); deliver those by callback.\n #readLines(\n lines: Map<number, HighlightedToken[]>,\n from: number,\n to: number\n ): void {\n this.#returnedRange = [from, to];\n try {\n this.#tokenizer.flush(to);\n } finally {\n this.#returnedRange = undefined;\n }\n for (let line = from; line < to; line++) {\n if (lines.has(line)) continue;\n const { tokens } = this.#tokenizer.getLineTokens(line);\n lines.set(\n line,\n tokens.length === 0\n ? [[0, '', '']]\n : tokens.map((token) => [\n token.offset,\n token.color ?? '',\n token.content,\n ])\n );\n }\n }\n\n setTheme(themeName: string): void {\n if (themeName === this.options.theme) return;\n this.options.theme = themeName;\n this.#tokenizer.dispose();\n this.#pendingDelivery = undefined;\n this.#paused = false;\n this.#version = this.options.textDocument.version;\n this.#tokenizer = this.#createTokenizer();\n }\n\n getStringCommentRegexpRangesInLine(\n lineIndex: number\n ): [number, number][] | null {\n const document = this.options.textDocument;\n if (\n this.options.matchBrackets === false ||\n lineIndex < 0 ||\n lineIndex >= document.lineCount\n )\n return null;\n // Reset and flush resume background work and invoke callbacks immediately.\n // Defer those callbacks and restore any pause before returning.\n const captured = new Map<number, HighlightedToken[]>();\n this.#capturedLines = captured;\n try {\n // Bracket matching can precede rendering. Record the reloaded version\n // so the next render does not apply the same edits again.\n if (\n this.#version !== document.version ||\n this.#tokenizer.lineCount !== document.lineCount\n ) {\n this.#pendingDelivery = undefined;\n this.#tokenizer.reset(document.getText(), {\n renderRange: [lineIndex, lineIndex + 1],\n });\n this.#version = document.version;\n }\n this.#tokenizer.flush(lineIndex + 1);\n } finally {\n this.#capturedLines = undefined;\n if (this.#paused) this.#tokenizer.pause();\n }\n if (captured.size > 0) this.#queueDelivery(captured);\n return this.#tokenizer.getLineTokens(lineIndex).bracketIgnoredRanges;\n }\n\n // Rendering calls this while background tokenization may be paused; do not resume it.\n prebuildStateStack(): void {}\n stopBackgroundTokenize(): void {\n this.pauseBackgroundTokenize();\n }\n pauseBackgroundTokenize(): void {\n this.#paused = true;\n this.#tokenizer.pause();\n }\n resumeBackgroundTokenize(): void {\n this.#paused = false;\n this.#tokenizer.resume();\n }\n dispose(): void {\n this.#disposed = true;\n this.#pendingDelivery = undefined;\n this.#tokenizer.dispose();\n }\n}\n","import { type CodeToTokensOptions, LiveTokenizer } from '@pierre/highlights';\n\nimport { appendItems } from '../utils/appendItems';\nimport { BaseStreamTokenizer } from './stream-tokenizer';\nimport type { ThemedToken } from './types';\n\n// Completed lines the tokenizer keeps before it tries to drop older ones.\nconst TRIM_LINE_COUNT = 1024;\nconst DOCUMENT_START = { line: 0, character: 0 };\n\n/** Keeps the unfinished line editable so new chunks can recall provisional tokens. */\nexport class HighlightsStreamTokenizer extends BaseStreamTokenizer {\n #tokenizer: LiveTokenizer;\n #trimLineCount = TRIM_LINE_COUNT;\n\n constructor(private readonly options: CodeToTokensOptions) {\n super();\n this.#tokenizer = new LiveTokenizer(options);\n }\n\n protected tokenizeChunk(\n chunk: string,\n stable: ThemedToken[]\n ): { unstable: ThemedToken[]; tailLength: number } {\n const lineBreaks = [...chunk.matchAll(/\\r\\n|\\r|\\n/g)];\n const startLine = this.#tokenizer.lineCount - 1;\n const position = {\n line: startLine,\n character: this.#tokenizer.getLineLength(startLine),\n };\n this.#tokenizer.applyEdits([\n { range: { start: position, end: position }, newText: chunk },\n ]);\n const lastLine = this.#tokenizer.lineCount - 1;\n let unstable: ThemedToken[] = [];\n for (let line = startLine; line <= lastLine; line++) {\n const { tokens } = this.#tokenizer.getLineTokens(line);\n for (const token of tokens) token.offset += this.stableOffset;\n if (line < lastLine) {\n appendItems(stable, tokens);\n this.pushLineBreak(\n stable,\n this.#tokenizer.getLineLength(line),\n lineBreaks[line - startLine][0]\n );\n } else {\n unstable = tokens;\n }\n }\n const tailLength = this.#tokenizer.getLineLength(lastLine);\n if (lastLine > this.#trimLineCount) {\n // Warning: keep the last completed line. Lexed from the initial state,\n // it must end in its old state, or the unfinished line would be lexed\n // from the wrong state; then restore the dropped lines.\n const text = this.#tokenizer.getText();\n const { lineChanges } = this.#tokenizer.applyEdits([\n {\n range: {\n start: DOCUMENT_START,\n end: { line: lastLine - 1, character: 0 },\n },\n newText: '',\n },\n ]);\n if (lineChanges.every((change) => change.newEndLine <= 1)) {\n this.#trimLineCount = TRIM_LINE_COUNT;\n } else {\n const keptLength = this.#tokenizer.getText().length;\n this.#tokenizer.applyEdits([\n {\n range: { start: DOCUMENT_START, end: DOCUMENT_START },\n newText: text.slice(0, text.length - keptLength),\n },\n ]);\n // Retry after the window doubles, such as inside a long comment.\n this.#trimLineCount = lastLine * 2;\n }\n }\n return { unstable, tailLength };\n }\n\n clone(): HighlightsStreamTokenizer {\n this.assertActive();\n const clone = new HighlightsStreamTokenizer(this.options);\n clone.#tokenizer.reset(this.#tokenizer.getText());\n this.copyStateTo(clone);\n return clone;\n }\n\n protected resetSource(): void {\n this.#tokenizer.reset('');\n this.#trimLineCount = TRIM_LINE_COUNT;\n }\n\n protected releaseSource(): void {\n this.#tokenizer.dispose();\n }\n}\n","import {\n codeToTokens,\n type CodeToTokensOptions as HighlightsOptions,\n isSupportedLanguage,\n type Theme,\n} from '@pierre/highlights';\n\nimport { DiffsHighlighter } from '../DiffsHighlighter';\nimport { HighlightsEditorTokenizer } from '../highlights-editor';\nimport { HighlightsStreamTokenizer } from '../highlights-stream';\nimport { createDiffsThemeResolver } from '../themes/themeResolver';\nimport type { DiffsTheme } from '../themes/types';\nimport type {\n DiffsEditorTokenizerOptions,\n DiffsStreamTokenizer,\n} from '../tokenizer-types';\nimport type { CodeToTokensOptions, TokensResult } from '../types';\n\n/**\n * Highlights uses bundled lexers. Unsupported and custom languages render as text.\n */\nexport class HighlightsHighlighter extends DiffsHighlighter {\n // Independent instances need their themes after the shared cache is cleared.\n private readonly usedThemes = new Map<string, DiffsTheme>();\n\n constructor() {\n super('highlights', createDiffsThemeResolver('highlights'));\n }\n\n getTheme(name: string): DiffsTheme {\n this.assertNotDisposed();\n const theme =\n this.themeResolver.getResolvedTheme(name) ?? this.usedThemes.get(name);\n if (theme == null) {\n throw new Error(`Theme \"${name}\" has not been resolved`);\n }\n this.usedThemes.set(name, theme);\n return theme;\n }\n\n codeToTokens(code: string, options: CodeToTokensOptions): TokensResult {\n this.assertNotDisposed();\n // Warning: use the library's shared Wasm instance. It replaces instances\n // above 8 MiB; a private instance keeps its peak memory.\n return codeToTokens(code, this.resolveOptions(options));\n }\n\n createEditorTokenizer(\n options: DiffsEditorTokenizerOptions\n ): HighlightsEditorTokenizer {\n this.assertNotDisposed();\n return new HighlightsEditorTokenizer(options, (tokenizerOptions) =>\n this.resolveOptions(tokenizerOptions)\n );\n }\n\n createStreamTokenizer(options: CodeToTokensOptions): DiffsStreamTokenizer {\n return new HighlightsStreamTokenizer(this.resolveOptions(options));\n }\n\n loadLanguages(): Promise<void> {\n this.assertNotDisposed();\n return Promise.resolve();\n }\n\n hasLoadedLanguages(): boolean {\n return !this.disposed;\n }\n\n attachLanguages(): void {\n this.assertNotDisposed();\n }\n\n protected releaseResources(): void {\n this.usedThemes.clear();\n }\n\n // Omit the unused theme key; callers may pass both keys with one undefined.\n private resolveOptions({\n theme,\n themes,\n ...options\n }: CodeToTokensOptions): HighlightsOptions {\n const lang = isSupportedLanguage(options.lang) ? options.lang : 'text';\n if (theme != null) {\n return { ...options, lang, theme: this.getZedTheme(theme) };\n }\n if (themes == null) {\n throw new Error('A theme or themes option is required');\n }\n const resolved: Record<string, Theme> = {};\n for (const [key, name] of Object.entries(themes)) {\n resolved[key] = this.getZedTheme(name);\n }\n return { ...options, lang, themes: resolved };\n }\n\n private getZedTheme(name: string): Theme {\n const theme = this.getTheme(name);\n if (theme.zed == null) {\n throw new Error(`Theme \"${name}\" does not support Highlights`);\n }\n return theme.zed;\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { i as isWorkerContext, n as DiffsHighlighter, r as createDiffsThemeResolver, t as BaseStreamTokenizer } from "./stream-tokenizer-YZ6M1qSx.js";
1
+ import { i as isWorkerContext, n as DiffsHighlighter, r as createDiffsThemeResolver, t as BaseStreamTokenizer } from "./stream-tokenizer-DK9xp5M5.js";
2
2
  import { c as RegisteredCustomLanguages, l as ResolvedLanguages, r as appendItems, s as attachResolvedLanguages, u as ResolvingLanguages } from "./worker.js";
3
3
  import { createCssVariablesTheme, createHighlighterCore } from "shiki/core";
4
4
  import { EncodedTokenMetadata, INITIAL } from "shiki/textmate";
@@ -694,4 +694,4 @@ var ShikiHighlighter = class ShikiHighlighter extends DiffsHighlighter {
694
694
  //#endregion
695
695
  export { ShikiHighlighter };
696
696
 
697
- //# sourceMappingURL=shiki-Bx2JpdqZ.js.map
697
+ //# sourceMappingURL=shiki-Ci4cdHsM.js.map