From 7b716aee75c810f1ba1445fbcc0de77acb5e748f Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 17:43:58 -0700 Subject: [PATCH 01/26] chore(deps): upgrade frontend to monaco-languageclient v10 Bumps monaco-languageclient 8.8.3 -> 10.7.0 and the @codingame/monaco-vscode-* family 8.0.4 -> 25.1.2. Drops monaco-editor-wrapper entirely; the editor component now drives the underlying triplet (MonacoVscodeApiWrapper + LanguageClientWrapper + EditorApp) directly. Notable changes: * code-editor.component.ts rewritten against the v10 API. The vscode-api wrapper is started once per process; the default-extension activations await each extension's whenReady() so the TextMate grammars register before the editor opens, and a forceTokenization pass on first paint guarantees colours land before Monaco's initial render. * Worker bootstraps live in src/.../workers/. The codingame-shipped worker files re-export internals via single-line imports that webpack only emits as static assets, so the trampolines force webpack to bundle the worker dep tree under the new Worker(new URL(...)) pattern. * custom-webpack.config.js gains a oneOf rule that runs codingame CSS through css-loader with exportType: css-style-sheet, asset/resource for the bundled svg/ttf/png/woff, and an alias that redirects the css/style loader runtime back to its real install (codingame's deeper namespace breaks the relative paths css-loader generates). Patches a known empty-path crash in license-webpack-plugin. * jsdom polyfill adds Constructable Stylesheets, matchMedia, CSS.escape, and registers a Node ESM loader hook (jsdom-css-loader-hook.mjs) that short-circuits .css imports to an empty module - needed because @angular/build:unit-test pre-bundles specs with externalPackages:true, so server.deps.inline never sees the codingame chain. * All five previously-excluded specs (code-editor, codearea-custom-template, time-travel, versions-list, operator-property-edit-frame) run again. * LICENSE-binary regenerated from dist/3rdpartylicenses.json (119 -> 123 packages: more codingame sub-modules; vscode-textmate / vscode-oniguruma / monaco-editor-wrapper dropped; dompurify added). Verified: yarn build, yarn test (63 files, 269 tests, parity with main), yarn format:ci. Browser smoke test against a running backend confirmed Python TextMate highlighting, editor mount, and worker spawn. --- frontend/LICENSE-binary | 65 +- frontend/custom-webpack.config.js | 96 ++- frontend/package.json | 25 +- .../code-editor.component.ts | 226 ++++-- .../workers/editor.worker.ts | 26 + .../workers/extension-host.worker.ts | 21 + .../workers/textmate.worker.ts | 21 + frontend/src/jsdom-css-loader-hook.mjs | 48 ++ frontend/src/jsdom-svg-polyfill.ts | 127 +++- frontend/src/tsconfig.app.json | 7 +- frontend/vitest.config.ts | 18 +- frontend/yarn.lock | 678 ++++++++++-------- 12 files changed, 953 insertions(+), 405 deletions(-) create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts create mode 100644 frontend/src/jsdom-css-loader-hook.mjs diff --git a/frontend/LICENSE-binary b/frontend/LICENSE-binary index bee43c7b6b1..727d6bcabf3 100644 --- a/frontend/LICENSE-binary +++ b/frontend/LICENSE-binary @@ -211,6 +211,7 @@ Dependencies under the Apache License, Version 2.0 -------------------------------------------------------------------------------- Angular / npm packages: + - dompurify@3.3.1 - fuse.js@6.5.3 - jschardet@3.1.3 - rxjs@7.8.1 @@ -247,30 +248,41 @@ Angular / npm packages: - @ant-design/icons-angular@21.0.0 - @auth0/angular-jwt@5.1.0 - @babel/runtime@7.29.2 - - @codingame/monaco-vscode-api@8.0.4 - - @codingame/monaco-vscode-base-service-override@8.0.4 - - @codingame/monaco-vscode-configuration-service-override@8.0.4 - - @codingame/monaco-vscode-editor-api@8.0.4 - - @codingame/monaco-vscode-environment-service-override@8.0.4 - - @codingame/monaco-vscode-extensions-service-override@8.0.4 - - @codingame/monaco-vscode-files-service-override@8.0.4 - - @codingame/monaco-vscode-host-service-override@8.0.4 - - @codingame/monaco-vscode-java-default-extension@8.0.4 - - @codingame/monaco-vscode-languages-service-override@8.0.4 - - @codingame/monaco-vscode-layout-service-override@8.0.4 - - @codingame/monaco-vscode-model-service-override@8.0.4 - - @codingame/monaco-vscode-monarch-service-override@8.0.4 - - @codingame/monaco-vscode-python-default-extension@8.0.4 - - @codingame/monaco-vscode-quickaccess-service-override@8.0.4 - - @codingame/monaco-vscode-r-default-extension@8.0.4 - - @codingame/monaco-vscode-textmate-service-override@8.0.4 - - @codingame/monaco-vscode-theme-defaults-default-extension@8.0.4 - - @codingame/monaco-vscode-theme-service-override@8.0.4 + - @codingame/monaco-vscode-api@25.1.2 + - @codingame/monaco-vscode-base-service-override@25.1.2 + - @codingame/monaco-vscode-bulk-edit-service-override@25.1.2 + - @codingame/monaco-vscode-configuration-service-override@25.1.2 + - @codingame/monaco-vscode-editor-api@25.1.2 + - @codingame/monaco-vscode-editor-service-override@25.1.2 + - @codingame/monaco-vscode-environment-service-override@25.1.2 + - @codingame/monaco-vscode-extension-api@25.1.2 + - @codingame/monaco-vscode-extensions-service-override@25.1.2 + - @codingame/monaco-vscode-files-service-override@25.1.2 + - @codingame/monaco-vscode-host-service-override@25.1.2 + - @codingame/monaco-vscode-java-default-extension@25.1.2 + - @codingame/monaco-vscode-keybindings-service-override@25.1.2 + - @codingame/monaco-vscode-languages-service-override@25.1.2 + - @codingame/monaco-vscode-layout-service-override@25.1.2 + - @codingame/monaco-vscode-log-service-override@25.1.2 + - @codingame/monaco-vscode-model-service-override@25.1.2 + - @codingame/monaco-vscode-monarch-service-override@25.1.2 + - @codingame/monaco-vscode-python-default-extension@25.1.2 + - @codingame/monaco-vscode-quickaccess-service-override@25.1.2 + - @codingame/monaco-vscode-r-default-extension@25.1.2 + - @codingame/monaco-vscode-textmate-service-override@25.1.2 + - @codingame/monaco-vscode-theme-defaults-default-extension@25.1.2 + - @codingame/monaco-vscode-theme-service-override@25.1.2 + - @codingame/monaco-vscode-view-banner-service-override@25.1.2 + - @codingame/monaco-vscode-view-common-service-override@25.1.2 + - @codingame/monaco-vscode-view-status-bar-service-override@25.1.2 + - @codingame/monaco-vscode-view-title-bar-service-override@25.1.2 + - @codingame/monaco-vscode-views-service-override@25.1.2 + - @codingame/monaco-vscode-workbench-service-override@25.1.2 - @ctrl/tinycolor@3.6.1 - @ngneat/until-destroy@8.1.4 - @ngx-formly/core@6.3.12 - @ngx-formly/ng-zorro-antd@6.3.12 - - @vscode/iconv-lite-umd@0.7.0 + - @vscode/iconv-lite-umd@0.7.1 - ajv@8.10.0 - backbone@1.4.1 - balanced-match@1.0.2 @@ -291,13 +303,12 @@ Angular / npm packages: - json-schema-traverse@1.0.0 - jszip@3.10.1 - lib0@0.2.117 - - lodash@4.17.23 + - lodash@4.18.1 - lodash-es@4.18.1 - - marked@17.0.1 + - marked@14.0.0 - mobx@4.14.1 - monaco-breakpoints@0.2.0 - - monaco-editor-wrapper@5.5.3 - - monaco-languageclient@8.8.3 + - monaco-languageclient@10.7.0 - ng-zorro-antd@21.2.2 - ngx-color-picker@12.0.1 - ngx-file-drop@16.0.0 @@ -322,9 +333,7 @@ Angular / npm packages: - vscode-languageclient@9.0.1 - vscode-languageserver-protocol@3.17.5 - vscode-languageserver-types@3.17.5 - - vscode-oniguruma@1.7.0 - - vscode-textmate@9.0.0 - - vscode-ws-jsonrpc@3.3.2 + - vscode-ws-jsonrpc@3.5.0 - y-monaco@0.1.5 - y-protocols@1.0.7 - y-quill@0.1.5 @@ -337,6 +346,7 @@ Dependencies under the BSD 3-Clause License -------------------------------------------------------------------------------- Angular / npm packages: + - d3-path@2.0.0 - d3-shape@2.1.0 - ieee754@1.2.1 - quill@1.3.7 @@ -354,7 +364,6 @@ Dependencies under the ISC License Angular / npm packages: - concaveman@2.0.0 - - d3-path@2.0.0 - minimatch@5.1.9 - quickselect@3.0.0 - tinyqueue@2.0.3 diff --git a/frontend/custom-webpack.config.js b/frontend/custom-webpack.config.js index 47a804cf435..f6d9001dcf1 100644 --- a/frontend/custom-webpack.config.js +++ b/frontend/custom-webpack.config.js @@ -19,15 +19,85 @@ const { LicenseWebpackPlugin } = require("license-webpack-plugin"); +// Workaround for license-webpack-plugin v4 crashing with `ENOENT: scandir ''` when a +// bundled module has no resolvable on-disk directory. Some @codingame/monaco-vscode-* +// sub-modules surface as virtual entries (descriptionFileRoot === '') after the v25 +// upgrade. Make listPaths/readFileAsUtf8/isDirectory tolerant of empty paths. +{ + const fs = require("fs"); + const wfs = require("license-webpack-plugin/dist/WebpackFileSystem").WebpackFileSystem; + const origListPaths = wfs.prototype.listPaths; + wfs.prototype.listPaths = function (path) { + if (!path) return []; + try { + return origListPaths.call(this, path); + } catch (e) { + if (e && e.code === "ENOENT") return []; + throw e; + } + }; + const origIsDirectory = wfs.prototype.isDirectory; + wfs.prototype.isDirectory = function (path) { + if (!path) return false; + try { + return origIsDirectory.call(this, path); + } catch (e) { + if (e && e.code === "ENOENT") return false; + throw e; + } + }; + const origReadFileAsUtf8 = wfs.prototype.readFileAsUtf8; + wfs.prototype.readFileAsUtf8 = function (path) { + if (!path) return ""; + try { + return origReadFileAsUtf8.call(this, path); + } catch (e) { + if (e && e.code === "ENOENT") return ""; + throw e; + } + }; +} + +// Match CSS files shipped by codingame's monaco-vscode-* family (and the editor-api +// alias of monaco-editor / vscode that points at them). These ship as Constructable +// Stylesheet imports — they must skip style-loader and use css-loader's +// `exportType: 'css-style-sheet'` mode. See the codingame troubleshooting wiki: +// https://github.com/CodinGame/monaco-vscode-api/wiki/Troubleshooting +const codingameCssRe = /node_modules[\\/](?:@codingame[\\/]monaco-vscode-[^\\/]+|monaco-editor|vscode)[\\/].*\.css$/; + module.exports = { module: { rules: [ + { + // The codingame monaco-vscode-* family ships raw assets (.svg/.ttf/.png/.woff*) + // that webpack must emit as static files rather than parse as JS. + test: /\.(svg|ttf|woff2?|png|jpg|jpeg|gif)$/, + include: [require("path").resolve(__dirname, "node_modules/@codingame")], + type: "asset/resource", + }, { test: /\.css$/, - use: ["style-loader", "css-loader"], - include: [ - require("path").resolve(__dirname, "node_modules/monaco-editor"), - require("path").resolve(__dirname, "node_modules/monaco-breakpoints") + oneOf: [ + { + test: codingameCssRe, + use: [ + { + loader: "css-loader", + options: { + esModule: false, + exportType: "css-style-sheet", + url: true, + import: true, + }, + }, + ], + }, + { + use: ["style-loader", "css-loader"], + include: [ + require("path").resolve(__dirname, "node_modules/monaco-breakpoints"), + ], + }, ], }, ], @@ -39,10 +109,28 @@ module.exports = { }, }, }, + resolve: { + // css-loader emits relative imports (e.g. '../../../../../../../css-loader/dist/runtime/api.js') + // computed from the source CSS location. The codingame monaco-vscode-* packages live one + // namespace level deeper (`node_modules/@codingame/...`) than css-loader assumes, so the + // emitted path lands at `node_modules/@codingame/css-loader/...` instead of + // `node_modules/css-loader/...`. Alias the missing leg back to the real install. + alias: { + [require("path").resolve(__dirname, "node_modules/@codingame/css-loader")]: + require("path").resolve(__dirname, "node_modules/css-loader"), + [require("path").resolve(__dirname, "node_modules/@codingame/style-loader")]: + require("path").resolve(__dirname, "node_modules/style-loader"), + }, + }, plugins: [ new LicenseWebpackPlugin({ perChunkOutput: false, outputFilename: "3rdpartylicenses.json", + // Skip packages whose resolved directory is missing or unreadable. The codingame + // monaco-vscode-* family ships sub-modules whose package roots license-webpack-plugin + // can't always locate, and a missing license file shouldn't fail the build. + handleMissingLicenseText: () => null, + excludedPackageTest: (name) => !name, renderLicenses: (modules) => JSON.stringify( modules diff --git a/frontend/package.json b/frontend/package.json index c1f0231aec3..926a4032cfe 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -35,9 +35,17 @@ "@angular/platform-browser-dynamic": "21.2.10", "@angular/router": "21.2.10", "@auth0/angular-jwt": "5.1.0", - "@codingame/monaco-vscode-java-default-extension": "8.0.4", - "@codingame/monaco-vscode-python-default-extension": "8.0.4", - "@codingame/monaco-vscode-r-default-extension": "8.0.4", + "@codingame/monaco-vscode-configuration-service-override": "25.1.2", + "@codingame/monaco-vscode-editor-service-override": "25.1.2", + "@codingame/monaco-vscode-extensions-service-override": "25.1.2", + "@codingame/monaco-vscode-java-default-extension": "25.1.2", + "@codingame/monaco-vscode-keybindings-service-override": "25.1.2", + "@codingame/monaco-vscode-languages-service-override": "25.1.2", + "@codingame/monaco-vscode-python-default-extension": "25.1.2", + "@codingame/monaco-vscode-r-default-extension": "25.1.2", + "@codingame/monaco-vscode-textmate-service-override": "25.1.2", + "@codingame/monaco-vscode-theme-defaults-default-extension": "25.1.2", + "@codingame/monaco-vscode-theme-service-override": "25.1.2", "@ngneat/until-destroy": "8.1.4", "@ngx-formly/core": "6.3.12", "@ngx-formly/ng-zorro-antd": "6.3.12", @@ -55,9 +63,8 @@ "lodash-es": "4.18.1", "marked": "17.0.1", "monaco-breakpoints": "0.2.0", - "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@8.0.4", - "monaco-editor-wrapper": "5.5.3", - "monaco-languageclient": "8.8.3", + "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@25.1.2", + "monaco-languageclient": "10.7.0", "ng-zorro-antd": "21.2.2", "ngx-color-picker": "12.0.1", "ngx-file-drop": "16.0.0", @@ -74,7 +81,7 @@ "tinyqueue": "2.0.3", "tslib": "2.3.1", "uuid": "8.3.2", - "vscode": "npm:@codingame/monaco-vscode-api@8.0.4", + "vscode": "npm:@codingame/monaco-vscode-extension-api@25.1.2", "y-monaco": "0.1.5", "y-protocols": "1.0.5", "y-quill": "0.1.5", @@ -84,8 +91,8 @@ "zone.js": "0.15.1" }, "resolutions": { - "vscode": "npm:@codingame/monaco-vscode-api@8.0.4", - "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@8.0.4", + "vscode": "npm:@codingame/monaco-vscode-extension-api@25.1.2", + "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@25.1.2", "webpack": "5.104.1", "jschardet": "portal:./tools/jschardet-stub" }, diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index a0838e6e459..1c68329bd01 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -41,11 +41,17 @@ import { YType } from "../../types/shared-editing.interface"; import { FormControl } from "@angular/forms"; import { AIAssistantService, TypeAnnotationResponse } from "../../service/ai-assistant/ai-assistant.service"; import { AnnotationSuggestionComponent } from "./annotation-suggestion.component"; -import { MonacoEditorLanguageClientWrapper, UserConfig } from "monaco-editor-wrapper"; import * as monaco from "monaco-editor"; -import "@codingame/monaco-vscode-python-default-extension"; -import "@codingame/monaco-vscode-r-default-extension"; -import "@codingame/monaco-vscode-java-default-extension"; +import { + MonacoVscodeApiWrapper, + type MonacoVscodeApiConfig, + getEnhancedMonacoEnvironment, +} from "monaco-languageclient/vscodeApiWrapper"; +import { LanguageClientWrapper, type LanguageClientConfig } from "monaco-languageclient/lcwrapper"; +import { EditorApp, type EditorAppConfig } from "monaco-languageclient/editorApp"; +// NOTE: the @codingame/monaco-vscode-*-default-extension packages are imported +// dynamically inside `ensureVscodeApiStarted` below — see the comment there for +// why static side-effect imports get tree-shaken in this project's build pipeline. import { isDefined } from "../../../common/util/predicate"; import { filter, switchMap } from "rxjs/operators"; import { BreakpointConditionInputComponent } from "./breakpoint-condition-input/breakpoint-condition-input.component"; @@ -105,7 +111,10 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy public language: string = ""; public languageTitle: string = ""; - private editorWrapper: MonacoEditorLanguageClientWrapper = new MonacoEditorLanguageClientWrapper(); + private static apiWrapperStarted = false; + private static apiWrapperStartPromise?: Promise; + private editorApp?: EditorApp; + private languageClientWrapper?: LanguageClientWrapper; private monacoBinding?: MonacoBinding; // Boolean to determine whether the suggestion UI should be shown @@ -191,7 +200,10 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy this.monacoBinding.destroy(); } - this.editorWrapper.dispose(true); + this.languageClientWrapper?.dispose().catch(() => {}); + this.languageClientWrapper = undefined; + this.editorApp?.dispose().catch(() => {}); + this.editorApp = undefined; if (isDefined(this.workflowVersionStreamSubject)) { this.workflowVersionStreamSubject.next(); @@ -228,53 +240,130 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy } } + /** + * Lazily start the global monaco-vscode-api wrapper. The vscode API services are + * a process-wide singleton in v10; calling start() twice would throw, so we share + * a single Promise across every CodeEditorComponent instance. + */ + private static ensureVscodeApiStarted(): Promise { + if (CodeEditorComponent.apiWrapperStarted) { + return Promise.resolve(); + } + if (!CodeEditorComponent.apiWrapperStartPromise) { + const apiConfig: MonacoVscodeApiConfig = { + $type: "extended", + viewsConfig: { $type: "EditorService" }, + userConfiguration: { + json: JSON.stringify({ + "workbench.colorTheme": "Default Dark Modern", + }), + }, + // Wire up the workers monaco-vscode-api spawns at runtime (editor, + // extension host, textmate). The package's `configureDefaultWorkerFactory` + // tries to load worker scripts straight out of the codingame node_modules + // tree via `new URL('@codingame/...', import.meta.url)`, but webpack only + // emits that URL as a static asset — the worker's transitive imports are + // never bundled, so the worker 404s on its first relative import at + // runtime. Instead we use the literal `new Worker(new URL('./local.ts', + // import.meta.url))` pattern that webpack 5 recognizes as a worker entry + // point; the trampoline files in `./workers/` re-export the codingame + // worker source and pull the whole dep tree into the bundle. + monacoWorkerFactory: () => { + const env = getEnhancedMonacoEnvironment(); + env.getWorker = (_workerId: string, label: string): Worker => { + switch (label) { + case "editorWorkerService": + return new Worker(new URL("./workers/editor.worker", import.meta.url), { type: "module" }); + case "extensionHostWorkerMain": + return new Worker(new URL("./workers/extension-host.worker", import.meta.url), { type: "module" }); + case "TextMateWorker": + return new Worker(new URL("./workers/textmate.worker", import.meta.url), { type: "module" }); + default: + throw new Error(`No worker configured for label: ${label}`); + } + }; + }, + }; + const apiWrapper = new MonacoVscodeApiWrapper(apiConfig); + // Start the vscode-api FIRST, then load AND fully activate the default + // language extensions before resolving. Each extension's module exports a + // `whenReady()` that resolves after its TextMate grammar / configuration + // files are registered with the host — without waiting for it, the editor + // opens with the language detected as Python but every token rendered as + // the default `mtk1` class (no syntax colours). + // + // Dynamic `import(...)` (rather than top-level `import "@codingame/..."`) + // is required because Angular's `@angular/build:application` pipeline + // tree-shakes bare side-effect imports out of the dev bundle. + CodeEditorComponent.apiWrapperStartPromise = apiWrapper + .start() + .then(() => + Promise.all([ + import("@codingame/monaco-vscode-python-default-extension"), + import("@codingame/monaco-vscode-r-default-extension"), + import("@codingame/monaco-vscode-java-default-extension"), + import("@codingame/monaco-vscode-theme-defaults-default-extension"), + ]) + ) + .then(extensions => Promise.all(extensions.map(ext => ext.whenReady?.()))) + .then(() => { + CodeEditorComponent.apiWrapperStarted = true; + }); + } + return CodeEditorComponent.apiWrapperStartPromise; + } + /** * Create a Monaco editor and connect it to MonacoBinding. * @private */ private initializeMonacoEditor() { const fileSuffix = this.getFileSuffixByLanguage(this.language); - const userConfig: UserConfig = { - wrapperConfig: { - editorAppConfig: { - $type: "extended", - codeResources: { - main: { - text: this.code?.toString() ?? "", - uri: `in-memory-${this.currentOperatorId}.${fileSuffix}`, - }, - }, - userConfiguration: { - json: JSON.stringify({ - "workbench.colorTheme": "Default Dark Modern", - }), - }, + const editorAppConfig: EditorAppConfig = { + codeResources: { + modified: { + text: this.code?.toString() ?? "", + uri: `in-memory-${this.currentOperatorId}${fileSuffix}`, }, }, }; - // optionally, configure python language client. - // it may fail if no valid connection is established, yet the failure would be ignored. const languageServerWebsocketUrl = getWebsocketUrl( "/python-language-server", this.config.env.pythonLanguageServerPort ); - if (this.language === "python") { - userConfig.languageClientConfig = { - languageId: this.language, - options: { - $type: "WebSocketUrl", - url: languageServerWebsocketUrl, - }, - }; - } - // init monaco editor, optionally with attempt on language client. - from(this.editorWrapper.initAndStart(userConfig, this.editorElement.nativeElement)) + const startEditor = async (): Promise => { + await CodeEditorComponent.ensureVscodeApiStarted(); + this.editorApp = new EditorApp(editorAppConfig); + await this.editorApp.start(this.editorElement.nativeElement); + + // optionally, configure python language client. + // it may fail if no valid connection is established, yet the failure would be ignored. + if (this.language === "python") { + const lcConfig: LanguageClientConfig = { + languageId: this.language, + connection: { + options: { + $type: "WebSocketUrl", + url: languageServerWebsocketUrl, + }, + }, + clientOptions: { + documentSelector: [this.language], + }, + }; + this.languageClientWrapper = new LanguageClientWrapper(lcConfig); + await this.languageClientWrapper.start(); + } + return this.editorApp.getEditor(); + }; + + from(startEditor()) .pipe( timeout(LANGUAGE_SERVER_CONNECTION_TIMEOUT_MS), - switchMap(() => of(this.editorWrapper.getEditor())), - catchError(() => of(this.editorWrapper.getEditor())), + switchMap(editor => of(editor ?? this.editorApp?.getEditor())), + catchError(() => of(this.editorApp?.getEditor())), filter(isDefined), untilDestroyed(this) ) @@ -292,6 +381,22 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy new Set([editor]), this.workflowActionService.getTexeraGraph().getSharedModelAwareness() ); + // The TextMate grammar registers asynchronously (the host fetches the + // .tmLanguage.json from the codingame extension and spins up a worker). + // Even after the editor mounts, the model may have already been painted + // with the no-grammar tokens (everything as the default `mtk1` class). + // Force a re-tokenize so the syntax colours show up on first paint. + const model = editor.getModel(); + const tokenization = ( + model as unknown as { + tokenization?: { forceTokenization?: (line: number) => void }; + } + )?.tokenization; + if (model && tokenization?.forceTokenization) { + for (let line = 1; line <= model.getLineCount(); line++) { + tokenization.forceTokenization(line); + } + } this.setupAIAssistantActions(editor); this.initCodeDebuggerComponent(editor); }); @@ -304,34 +409,31 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy ?.content.operators?.find(({ operatorID }) => operatorID === this.currentOperatorId); const latestVersionCode: string = latestVersionOperator?.operatorProperties?.code ?? ""; const oldVersionCode: string = this.code?.toString() ?? ""; - const userConfig: UserConfig = { - wrapperConfig: { - editorAppConfig: { - $type: "extended", - codeResources: { - main: { - text: latestVersionCode, - uri: `in-memory-${this.currentOperatorId}.${fileSuffix}`, - }, - original: { - text: oldVersionCode, - uri: `in-memory-${this.currentOperatorId}-version.${fileSuffix}`, - }, - }, - useDiffEditor: true, - diffEditorOptions: { - readOnly: true, - }, - userConfiguration: { - json: JSON.stringify({ - "workbench.colorTheme": "Default Dark Modern", - }), - }, + const editorAppConfig: EditorAppConfig = { + codeResources: { + modified: { + text: latestVersionCode, + uri: `in-memory-${this.currentOperatorId}${fileSuffix}`, + }, + original: { + text: oldVersionCode, + uri: `in-memory-${this.currentOperatorId}-version${fileSuffix}`, }, }, + useDiffEditor: true, + diffEditorOptions: { + readOnly: true, + }, }; - this.editorWrapper.initAndStart(userConfig, this.editorElement.nativeElement); + from( + CodeEditorComponent.ensureVscodeApiStarted().then(() => { + this.editorApp = new EditorApp(editorAppConfig); + return this.editorApp.start(this.editorElement.nativeElement); + }) + ) + .pipe(untilDestroyed(this)) + .subscribe(); } private initCodeDebuggerComponent(editor: MonacoEditor) { @@ -514,7 +616,7 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy this.currentRange.endColumn ); - this.insertTypeAnnotations(this.editorWrapper.getEditor()!, selection, this.currentSuggestion); + this.insertTypeAnnotations(this.editorApp!.getEditor()!, selection, this.currentSuggestion); // Only for "Add All Type Annotation" if (this.isMultipleVariables && this.userResponseSubject) { @@ -562,7 +664,7 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy if (rect.bottom > viewportHeight) { container.style.height = `${viewportHeight - rect.top}px`; } - this.editorWrapper.getEditor()?.layout(); + this.editorApp?.getEditor()?.layout(); } onFocus() { this.workflowActionService.getJointGraphWrapper().highlightOperators(this.currentOperatorId); diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts new file mode 100644 index 00000000000..9d78785c4a0 --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts @@ -0,0 +1,26 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Worker entry — referenced via `new Worker(new URL('./editor.worker', import.meta.url))` +// from the editor component. Re-exporting the codingame-shipped worker as a local +// entry forces webpack to bundle the worker's transitive deps into the chunk. +// Without this trampoline, webpack only emits the upstream `worker.js` (a single +// `import './vscode/...'` line) and the browser fails to resolve the relative path +// at runtime. +import "@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts new file mode 100644 index 00000000000..6d667025576 --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// See ./editor.worker.ts for why this trampoline exists. +import "@codingame/monaco-vscode-api/workers/extensionHost.worker"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts new file mode 100644 index 00000000000..796224f9014 --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// See ./editor.worker.ts for why this trampoline exists. +import "@codingame/monaco-vscode-textmate-service-override/worker"; diff --git a/frontend/src/jsdom-css-loader-hook.mjs b/frontend/src/jsdom-css-loader-hook.mjs new file mode 100644 index 00000000000..044e7b61fb4 --- /dev/null +++ b/frontend/src/jsdom-css-loader-hook.mjs @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/** + * Node ESM loader hook used in the Vitest worker. Intercepts every `.css` + * import and replaces it with an empty module. + * + * Why this exists: the Angular `@angular/build:unit-test` builder pre-bundles + * spec files with esbuild and `externalPackages: true`, so transitive imports + * (e.g. `monaco-languageclient` -> `@codingame/monaco-vscode-api` -> raw + * `aria.css`) reach Node's native ESM loader instead of Vite's transform + * pipeline. Node has no built-in handler for `.css` and crashes the worker + * with `TypeError: Unknown file extension ".css"`. + * + * Vitest's `server.deps.inline` does NOT cover this because the spec is + * already bundled before vitest sees it. The loader hook is the only place + * we can intervene. + * + * Specs don't render anything, so swallowing CSS at module load is safe. + * Activated by the setupFile `jsdom-svg-polyfill.ts` calling + * `module.register(...)` at module init. + */ +export function resolve(specifier, context, nextResolve) { + if (specifier.endsWith(".css") || /\.css(\?|$)/.test(specifier)) { + return { + url: "data:text/javascript,export%20default%20%7B%7D%3B", + shortCircuit: true, + format: "module", + }; + } + return nextResolve(specifier, context); +} diff --git a/frontend/src/jsdom-svg-polyfill.ts b/frontend/src/jsdom-svg-polyfill.ts index 4d296fac544..00720b00f9d 100644 --- a/frontend/src/jsdom-svg-polyfill.ts +++ b/frontend/src/jsdom-svg-polyfill.ts @@ -32,6 +32,24 @@ * jointjs to instantiate cleanly. */ +/** + * Register a Node ESM loader hook so every transitive `.css` import resolves + * to an empty module. Required because the Angular `@angular/build:unit-test` + * builder pre-bundles spec files with `externalPackages: true`, which means + * imports like `monaco-languageclient` reach Node's native ESM loader instead + * of Vite's transform pipeline. Without the hook, every spec that transitively + * loads the codingame v25 stack crashes with `Unknown file extension ".css"`. + * + * Done at the very top of this file so the registration happens before any + * spec body imports the affected packages. `module.register` requires Node + * 20.6+; the project already mandates Node >= 24. + */ +import { register as registerLoader } from "node:module"; +import { pathToFileURL } from "node:url"; +import * as nodePath from "node:path"; + +registerLoader(pathToFileURL(nodePath.join(__dirname, "jsdom-css-loader-hook.mjs"))); + type AnyFn = (...args: unknown[]) => unknown; function fakeMatrix() { @@ -95,6 +113,106 @@ if (SVG_ELEMENT_GLOBAL?.prototype) { if (typeof proto.getBBox !== "function") proto.getBBox = fakeRect as AnyFn; } +/** + * jsdom doesn't implement the Constructable Stylesheets API + * (`new CSSStyleSheet().replaceSync(...)`), which @codingame/monaco-vscode-api + * v25's `css.js` runtime calls when registering CSS at module load time. + * Without it, every spec that transitively imports monaco-languageclient + * crashes at construction. + * + * Stub `CSSStyleSheet` with an inert constructor whose `replaceSync` is a + * no-op. Specs don't visually render anything, so swallowing CSS is safe. + */ +const CSS_GLOBAL = (globalThis as unknown as { CSSStyleSheet?: { prototype: Record } }).CSSStyleSheet; +if (!CSS_GLOBAL) { + class InertCSSStyleSheet { + cssRules: unknown[] = []; + replaceSync(): void {} + replace(): Promise { + return Promise.resolve(); + } + insertRule(): number { + return 0; + } + deleteRule(): void {} + } + (globalThis as unknown as { CSSStyleSheet: typeof InertCSSStyleSheet }).CSSStyleSheet = InertCSSStyleSheet; +} else if (typeof CSS_GLOBAL.prototype.replaceSync !== "function") { + CSS_GLOBAL.prototype.replaceSync = (() => undefined) as AnyFn; + if (typeof CSS_GLOBAL.prototype.replace !== "function") { + CSS_GLOBAL.prototype.replace = (() => Promise.resolve()) as AnyFn; + } +} + +/** + * jsdom's Document doesn't expose `adoptedStyleSheets` (it's a Constructable + * Stylesheets feature). The codingame runtime pushes new sheets onto it. + */ +const docProtoForCss = (globalThis as unknown as { Document?: { prototype: Record } }).Document + ?.prototype; +if (docProtoForCss && !("adoptedStyleSheets" in docProtoForCss)) { + Object.defineProperty(docProtoForCss, "adoptedStyleSheets", { + configurable: true, + get() { + return (this as { __adoptedStyleSheets?: unknown[] }).__adoptedStyleSheets ?? []; + }, + set(v: unknown[]) { + (this as { __adoptedStyleSheets?: unknown[] }).__adoptedStyleSheets = v; + }, + }); +} + +/** + * jsdom doesn't implement the `CSS` global namespace (`CSS.escape`, + * `CSS.supports`). The codingame v25 theme service calls `CSS.escape(...)` to + * sanitize icon class names. Without it, an idle-callback runner crashes the + * worker with `TypeError: Cannot read properties of undefined (reading 'escape')`. + * + * Provide a minimal stub. The escape implementation mirrors the spec — + * https://drafts.csswg.org/cssom/#serialize-an-identifier — but we only need + * to handle the conservative case so `value === out` as often as possible + * (otherwise a noisy `console.warn` fires every paint). + */ +const cssGlobal = globalThis as unknown as { CSS?: { escape?: (value: string) => string; supports?: AnyFn } }; +if (!cssGlobal.CSS) { + cssGlobal.CSS = {}; +} +if (typeof cssGlobal.CSS.escape !== "function") { + cssGlobal.CSS.escape = (value: string) => String(value).replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&"); +} +if (typeof cssGlobal.CSS.supports !== "function") { + cssGlobal.CSS.supports = (() => false) as AnyFn; +} + +/** + * jsdom doesn't implement `window.matchMedia` (the CSS media query API). + * The codingame v25 theme service calls it during a deferred idle callback + * to detect dark/light preference, and jsdom raises + * `TypeError: targetWindow.matchMedia is not a function`. + * + * Stub with an inert MediaQueryList that always reports no match. + */ +const winForMatchMedia = globalThis as unknown as { + matchMedia?: AnyFn; + window?: { matchMedia?: AnyFn }; +}; +const matchMediaStub: AnyFn = ((query: string) => ({ + matches: false, + media: query, + onchange: null, + addListener: () => undefined, + removeListener: () => undefined, + addEventListener: () => undefined, + removeEventListener: () => undefined, + dispatchEvent: () => false, +})) as AnyFn; +if (typeof winForMatchMedia.matchMedia !== "function") { + winForMatchMedia.matchMedia = matchMediaStub; +} +if (winForMatchMedia.window && typeof winForMatchMedia.window.matchMedia !== "function") { + winForMatchMedia.window.matchMedia = matchMediaStub; +} + /** * jsdom doesn't implement the legacy `document.queryCommandSupported`, * which monaco-editor probes during initialization. Without it the @@ -185,9 +303,16 @@ class InertWebSocket { */ function isBenignIconError(err: unknown): boolean { const msg = err instanceof Error ? err.message : String(err); + const stack = err instanceof Error ? err.stack ?? "" : ""; return ( msg.includes("[@ant-design/icons-angular]") || - (err instanceof Error && err.name === "AggregateError" && /xhr-utils/.test(err.stack ?? "")) + (err instanceof Error && err.name === "AggregateError" && /xhr-utils/.test(stack)) || + // codingame v25 default extensions try to fetch their bundled themes / + // language configs over `extension-file://` URIs at activation time. jsdom + // can't resolve that scheme so the fetch rejects, but it's purely cosmetic + // — the spec body never depends on the theme/grammar being applied. + msg.includes("extension-file://") || + /workbenchThemeService|monaco-vscode-theme|monaco-vscode-.*-default-extension/.test(stack) ); } process.on("uncaughtException", err => { diff --git a/frontend/src/tsconfig.app.json b/frontend/src/tsconfig.app.json index 6f84762b813..ada971bdcbb 100644 --- a/frontend/src/tsconfig.app.json +++ b/frontend/src/tsconfig.app.json @@ -8,6 +8,11 @@ "angularCompilerOptions": { "fullTemplateTypeCheck": true }, - "files": ["main.ts"], + "files": [ + "main.ts", + "app/workspace/component/code-editor-dialog/workers/editor.worker.ts", + "app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts", + "app/workspace/component/code-editor-dialog/workers/textmate.worker.ts" + ], "include": ["**/*.d.ts"] } diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 5462d42cf49..42f49bbf28e 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -29,17 +29,13 @@ export default defineConfig({ // which Angular's `fakeAsync` requires. Karma+Jasmine installed this // implicitly; the @angular/build:unit-test path doesn't. setupFiles: ["src/test-zone-setup.ts"], - // monaco-breakpoints' entry does `import './style.css'`. By default - // Vitest leaves third-party deps externalized, so Node's ESM loader - // tries to import the .css and crashes with - // `TypeError: Unknown file extension ".css"`. Inlining the package - // routes its imports through Vite/esbuild, which rewrites the CSS - // import to a no-op. - server: { - deps: { - inline: [/monaco-breakpoints/], - }, - }, + // CSS imports inside transitive deps (monaco-breakpoints, monaco-editor, + // @codingame/monaco-vscode-*, …) are stripped by a Node ESM loader hook + // registered at the top of `src/jsdom-svg-polyfill.ts` rather than via + // `server.deps.inline`. The `@angular/build:unit-test` builder pre-bundles + // specs with `externalPackages: true`, so transitive imports go through + // Node's native loader and bypass Vitest's inline transform — see the + // comment in that file for the full rationale. // Per-spec exclusions live in `angular.json` (the unit-test builder // applies them at the discovery stage, before Vitest's own filter, // which is what the Vitest team recommends — see the Vite warning diff --git a/frontend/yarn.lock b/frontend/yarn.lock index dca7469bbdd..e58d2b9628f 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2059,307 +2059,437 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-base-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-base-service-override@npm:8.0.4" +"@codingame/monaco-vscode-api@npm:25.1.2, @codingame/monaco-vscode-api@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-api@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/d47b59e95fb287f8fb9abbfc3bcaeb0afca7cadd9293d4ee06302798840cccb7e78a4de955048a27bf6766675d0ed91c1f418d5c6dca576ada0e8130618a115d + "@codingame/monaco-vscode-base-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-environment-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-extensions-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-host-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-layout-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override": "npm:25.1.2" + "@vscode/iconv-lite-umd": "npm:0.7.1" + dompurify: "npm:3.3.1" + jschardet: "npm:3.1.4" + marked: "npm:14.0.0" + checksum: 10c0/c2d2be484906bc81575a70b3e00b3a15098793955ff02ebc172061ce6d570a19b3d14dc236a7cd09ad5c030a348283be9d83e907a6248fbf68ac5ab9333eed01 languageName: node linkType: hard -"@codingame/monaco-vscode-configuration-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-configuration-service-override@npm:8.0.4" +"@codingame/monaco-vscode-base-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-base-service-override@npm:25.1.2" dependencies: - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/04cc87a27bc2e93e6f8ade15e53e8635bf6db55eb341b043e1583abd18eaa396065144308651de67a1ccbd2edd3148f89dcf798af0a9926362370634bfa9e9b8 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/2194d5fcdf1b606e2c0e09b702c2bd3288958f5dde4403afb165737fcc837fc11d07cc6266b6cfa0aa6f1783da92add3024da3689fc7f7237dbbcd135da974a8 languageName: node linkType: hard -"@codingame/monaco-vscode-editor-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-editor-service-override@npm:8.0.4" +"@codingame/monaco-vscode-bulk-edit-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-bulk-edit-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/82362f7df94bcf72ca21810e18f0a2f251f299f0d8fa9544e5460da38243b07340cbd82f83045fa505d3609bb57402def5011814656522b76dde1e6bd55c1622 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/8b8fea1cd62ffeef47909d775b68966d0c9f495e49ff62e87fb04af5e7cd9307f8ab4764995d0801b87ce8651b6eb5754965cb2a8e6415b5d87c3685e11cb25b languageName: node linkType: hard -"@codingame/monaco-vscode-environment-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-environment-service-override@npm:8.0.4" +"@codingame/monaco-vscode-configuration-service-override@npm:25.1.2, @codingame/monaco-vscode-configuration-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-configuration-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/5c438986315a9a22eef3d5d927350f362179e19d6293d651cf6ecb3b32446d2ba7333b53463473230329aaa3a1db77a39362274a3703ab7e3914b2bb538e8f28 + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/1733039adbf653b0105cd176a9679621aa0d174dc488b3c943b0cb3cfb11c0a65bfbf0898d895027520b31ed0121f5d3d789ddf6b9631ae5bbf2e087f933fc7f languageName: node linkType: hard -"@codingame/monaco-vscode-extensions-service-override@npm:8.0.4, @codingame/monaco-vscode-extensions-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-extensions-service-override@npm:8.0.4" +"@codingame/monaco-vscode-editor-api@npm:^25.1.2, monaco-editor@npm:@codingame/monaco-vscode-editor-api@25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-editor-api@npm:25.1.2" dependencies: - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/624b819238c017e20f29fc908ede2cd8f641d659ec23ba04879ea2f87a829d9777a6ea9c1898cacdf9e7a07734ae8eb2d00cd2ccd136356bb3e8ca3cf0bb90bc + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/46678d8eabaa487a8f8ffce9717818dc08afed748582a89b7d306113a593e5243d4e7e023a046b3cdd65e2f4de06e2be779aa82b21a3c9cc9b72cbad24565d4d languageName: node linkType: hard -"@codingame/monaco-vscode-files-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-files-service-override@npm:8.0.4" +"@codingame/monaco-vscode-editor-service-override@npm:25.1.2, @codingame/monaco-vscode-editor-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-editor-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/956b7d5636cab22e3ab66deb7f71bf2f3c9d95c166d6068a0f8d4e742f58cc7e8400b64aa2eb420cab1896ee38c62c7132c4765f997b6b5ceacbd8e01e5175d2 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/e159bb2a1fb8ae8ee883bd02d95f2fb05e21b4caabb30bc21544b87cdf05f3932a4d2a6fe5b2a31f63e87c02455a36351322ed081ff4b6b55ea36e916d8cf1fd languageName: node linkType: hard -"@codingame/monaco-vscode-host-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-host-service-override@npm:8.0.4" +"@codingame/monaco-vscode-environment-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-environment-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/a9cee88b06868ec84914bf891d42133b30ab309be41ce0eab3dd604fd4ef6756d419dd891e2ad0a271e69da3cce0c0f6c8cb289f057329bb1115f6161877c600 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/cfa7b5997a91d2b8d01acccf9fd63e998e130a2e6ded9938b4412787ae1265a0667ce47a3bd1d3f8fea2a833ff893e3efc978d1261a09af2bba1394fa0c90a35 languageName: node linkType: hard -"@codingame/monaco-vscode-java-default-extension@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-java-default-extension@npm:8.0.4" +"@codingame/monaco-vscode-extension-api@npm:^25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-extension-api@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/58f34897c29e006395a754c6cd87189ea5b30a10e879d2720777889b1f6842b5e5c931a30ffef98d369fc9420a23fcf7cf2f775077adffbf1fbd2f5702eaee3a + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-extensions-service-override": "npm:25.1.2" + checksum: 10c0/182f90e359bd3d57aaf9a58eaabe9eff226d6bc94e4f51c43f846308352982cbbe3b2dade60177c5ab90e49d8d437493715cd224c1a6063e5c52e1c5e75b9be3 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-cs@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-cs@npm:8.0.4" +"@codingame/monaco-vscode-extensions-service-override@npm:25.1.2, @codingame/monaco-vscode-extensions-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-extensions-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/87700f4599d8404e746f03ce1073396b25c268fdae55ddd65d85404d1b71cbb08c43f281745494857cda6e9ef2c88624e647335f3597a7082991ac03622f906f + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/fbbbcfae26b61582dde6ebe3f2e40a040a6593e30948d557b4ebd2c2f80fa011235fe2f8be20ccc62fa91dadfa7274a245482e1fb04a94facaa56dc33efe706a languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-de@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-de@npm:8.0.4" +"@codingame/monaco-vscode-files-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-files-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/dfb4b7a2e7abe6574fd15b40b7ee7089445917900ff2611d0fd7d309b0233e6e90c811392685e6be4b976b751dcb001b42bf422842d53b8dac80abd834e11761 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/d8d700507199c4cac564751d9c8f8bb3514cc39256d1e6381b492c80833f8428f3b6490082bbfee1b3e73b0b65dbefa6e5966280678b9ebd35f27c93b49f9c9c languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-es@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-es@npm:8.0.4" +"@codingame/monaco-vscode-host-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-host-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/c3c60adab9fb60a5e376a37260f80b95998ac94d88424b5b824751240bcc3997cb5e83c4c4f01cf18a1ccb9bce48f8e8e50a31fd87a92949c7d0bb3c0bb5a6e3 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/12522ef3494b94b195d643ffd4f3ab0e66e3be949809c19daab329661d781a8a836273914d96de15046121b562510324e75b1802fd7d8f01a59f5f371f18fff1 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-fr@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-fr@npm:8.0.4" +"@codingame/monaco-vscode-java-default-extension@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-java-default-extension@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/abe94f70eea98cddddcadb6a6c2f3b0964fa034489cf3d8d99b6953919fc2b34e74fbb2321a7623c8fb37afd80db8206d2c1c0f83a1f5bc01a2085ec28fb8b0c + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/ad00d914f1236102b1e387aff0cc61e004d0aa4bffba6dda38f3b310950372974e059383131955876ed3882dc339a06944af13529706e11f10ea27ca0d64e071 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-it@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-it@npm:8.0.4" +"@codingame/monaco-vscode-keybindings-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-keybindings-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/9e47ce0458bc37787a3d5763720657d357acbee9792b0520524f0609be90b3adf015327a03db630a7b82f391cfbb8f8293fd28f7749f83b941c3f2e322d6115a + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/81399b35c85cdcef067059370979282a282bac560b0e3f033b8dcf2877c2f33618fc75c31e671fb7486e45f0f791d7575afa40509f13b017088ee242caff65ed languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-ja@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-ja@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-cs@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-cs@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/65bc3e1e6544cb690f1b99973da1b6845d26594daf0bf95dd692ed665e58de7de0d39e15ef72bd6dc6801636c414229f07b0a6359e7e8c001ea226944181c6e1 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/55a977b197f3bf35f3061587020598ec533068d0a50d3020378bd7ea07b48d4cfb720d6584136266cc29fd18454ad47b66a4a4e0411371d7729619ccab81b709 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-ko@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-ko@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-de@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-de@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/7bc457932db34fb26cd4e2c11494c5e3b4e6757de32ddd5045a46c7c5a47ab4fa3789418a51e722af706098eab35c022f56e7027966b6894136f93d664870ede + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/45440482e91bf70fa0ec5982dc6b39b7541902b10edf2c6eb50de3ab71a9b400edb3e3ce0bb86f53a6edc587baf8b9320fe3e7536a80121acab5dc33bd3f220e languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-pl@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-pl@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-es@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-es@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/80274df3bb40b0669d522fc88064a7926f61ae436ffe557e1cd2822017b6fe3b6e8571018f3e22dcf39a074af84021f3bc7a6e7634e4f4fda9f8e7a285d1dcc8 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/58011acd0e2a247d2e38a5f9ee14c142744e889ddfd4b7863fa3b9f876fd3ef6833e6e11fa8563eec9bf66100fa39dd9b47c5895729e1053cd772a35788d9e55 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-pt-br@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-pt-br@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-fr@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-fr@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/bb61c3a6dd102b8d636101ce547a00a82806f12c38f697d2603b8ef8dc585e673a8e5e6a177a7e39721535b0773508d791ae982f61d5aad3e1291b1d87a2bd25 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/0dcef4989cce25a0a7e8dbfe352be348f691163914912cffff8d2788d468de313c60b834f2f2f8ec7f153fc6dfb9cdcde6bee1bb8cbe980bef6c4a6de64d60c9 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-qps-ploc@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-qps-ploc@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-it@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-it@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/be864dcbfe746e34c8f981ba190e3db4352b2672cf52f2471042b33ddaa600a5783a2c28b28a70cc5d8783a3a3c7f310a91cdc71ab02d65301eee89cebd5b4ec + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/f05af4dc4629be34ba87188b7700195f4e5dce747d0937792463bdfb1b0fbf7ef4653600cef0b4febf16ba6b1dec76a94dd7f7417f47e1f94e05859aad0baea8 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-ru@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-ru@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-ja@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-ja@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/345d42252634261be208df7989148b7115624a778a491afb3249e1d750fa2e7469f906c9ab11c5a8df9201ec4cd7fefab82e46d88714c27d64b9a1b8ecdd83d6 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/d816fe97a4db813875a38f25766a22d9cd5724f8919d092b4b9ffbe622e3f161f314a702af7ae0c2b9b14c7bb564a261d014613ef3ad97bf1f1295980a759132 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-tr@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-tr@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-ko@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-ko@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/fdaeff22f5b52f565f391e14be6ec6b06ef337dd148e2542e8b9c6b578bf395274c1d540bf530b91b71ad54714871941e916e618c43d526203c3d5c7c8bc310a + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/96a97f07c0f35436ba56fac26b3a227243bc27faae40152ca34d58f58a2aebf667fc2d4b039c9f8c1e51c27a90c943b1cab6eb306327b1b1f9bd6158efebf0e3 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-zh-hans@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-zh-hans@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-pl@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-pl@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/9997fc23adae93cc6bd33916085b341bdd2cdcc15a83d492809f6328bc95c14ec9c579b5dae6d35224b4eb96ab35f006c19539a765afd4c1713e8ca5eb10645b + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/d81fecd1f5858a39b9e58340883cac0198a3f855ea926fd7147f149fd98e7e070dcf6f42c713634f32a5d3bd721ce011de13df51ff9052aabd99561a523ffbe4 languageName: node linkType: hard -"@codingame/monaco-vscode-language-pack-zh-hant@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-language-pack-zh-hant@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-pt-br@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-pt-br@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/23fe87f2938cf00e2906fed63f23965a910ea8f9d3e15a6d39d3d3ef2f9e7a41dd423a59ce3a816924995479743dad6d6a67116bc2e152f9624586344dd102ba + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/4c55969eed67b15066fc2d0482f8de06694b10df48f65a239b2f34182e53bd3ebc07c28c0bf38a6b2cb637a6f5fdab979a80a38d65ec51322b08062264a310b0 languageName: node linkType: hard -"@codingame/monaco-vscode-languages-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-languages-service-override@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-qps-ploc@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-qps-ploc@npm:25.1.2" dependencies: - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/f376fb13b75c57d8f509f3465c01dc6509bcae3b4b8f40b9adbee4f7b1b9027def0a1489d1f84b7a72eeebe08570eb968dcc4bbb624279974c1b3c3c336a6d17 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/425119b73c53687a209cc05554f3b562e98b6b8ee4e531a3ddd4e10b77b1a26684597ac30da164a77b4fb0b88d61faa354507af04de3d448ad400b8dd8e388b4 languageName: node linkType: hard -"@codingame/monaco-vscode-layout-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-layout-service-override@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-ru@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-ru@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/114d5d47e25719e01a23337bbbe1d051f2e50589cc27ee171bb4c49363618029d25124b7ea7eb37cf255467f2535cef4129f3be433161c7014ff5652c19488aa + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/038be50b55f39381a4f075a549e1f07febf8019ea6cc8e094b413047e5339cd6004dc2ebcc79e9ea97180757851f1e4079b101448bedbdcae61719717ee54fb6 languageName: node linkType: hard -"@codingame/monaco-vscode-localization-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-localization-service-override@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-tr@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-tr@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/77ad94652bdc9ea82453bbe6c3d8b3d1741dbb8cd311b477639a795751de2e52c4938fca27458b8be5f71bf35252bb6d0e752d3d2012f15150b254cb26f601c3 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/4a338cbb20449a07d721e5ed80e9f99abe7102827772591df3e4b076d4c893e9c0408d4c2a96acee20b36dee32bba7a021c59d6cab2015ac63e07d50b4af606a languageName: node linkType: hard -"@codingame/monaco-vscode-model-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-model-service-override@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-zh-hans@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-zh-hans@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/5c95c11dd93d7b4f6c912b5e8c87b107406e72a1409c8ccf0acf5ef87b0fd464566a5b13661fe80e44c4f1dd9a216ae25f560ce7c1614a950af8f1fb64bcf625 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/65ce7622860502addf813631cbb70170d534764d7de3ef2318a44e39b5a3808e3c2b39945f6b7612ecdf3dbba2653f223bb834a62c6d7ac3b0657f96b6fa06c1 languageName: node linkType: hard -"@codingame/monaco-vscode-monarch-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-monarch-service-override@npm:8.0.4" +"@codingame/monaco-vscode-language-pack-zh-hant@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-language-pack-zh-hant@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/0cd64ee6e5ae23fbadde35833c86a009428088c93052bef979c51db9e22dcd53fa04177b907d77e23c133769b277845ef79c5407dab214ed27b15c4ae2f5fb81 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/4bb8461d30c6b5ddba2bb23c1890fe3397642c9b1d97b926caf7e7af9a0347624b97a9d95a67f7de5efdbf8a026e99873b3020410b46beae3435bc70ccc0a222 languageName: node linkType: hard -"@codingame/monaco-vscode-python-default-extension@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-python-default-extension@npm:8.0.4" +"@codingame/monaco-vscode-languages-service-override@npm:25.1.2, @codingame/monaco-vscode-languages-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-languages-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/d1e638b8a716f5c81ebd90ea15f7380f6448d959343118989dc5022f43e2bd7615ac9c7805d6d961380ecef2dcce21f4f08edbd562f2186c15afa6c0b8ca5b68 + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/f4590a9d33df071c7649094ec99b50f2289e70e7a147a1a2f9905650da84078fc9562d35dd5da38b193a7738501e87a71d49c0cc55a2f5ef6069950d6dfbfa49 languageName: node linkType: hard -"@codingame/monaco-vscode-quickaccess-service-override@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-quickaccess-service-override@npm:8.0.4" +"@codingame/monaco-vscode-layout-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-layout-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/9dbe054be90b4ae57f295df4071382b71c8ec5e46194af07dc03bc4aeac375e019f068c2ef883453f4234f2b53b8426f2f5475ff8d0e61ebb4892379c07bdb96 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/eca1f91e750129cc1f07be960d7c1a9f2490f5c0ea798875707ef6a0b9fec6c6cdd9c7dc54c4e2ce32c26d2d517d7f8ee65f37cb4e72739d6c25cd80195ceb0e languageName: node linkType: hard -"@codingame/monaco-vscode-r-default-extension@npm:8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-r-default-extension@npm:8.0.4" +"@codingame/monaco-vscode-localization-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-localization-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/b83948b58b0e37693f29663fb34a896a689a1abfef28babf848d854574df27ef8b9d8dce6d53df1ac65b015e21929d7abdedf0a662dd6f7ed060fe2b84188471 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/c50d04d622443fddec26d489da060a729a3ff683111162755cdb83ee159bc8b78e5ce7b8d5f521abf0e44357d7049c3d4d67a508d10142f39da64d3e984a1fff languageName: node linkType: hard -"@codingame/monaco-vscode-textmate-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-textmate-service-override@npm:8.0.4" +"@codingame/monaco-vscode-log-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-log-service-override@npm:25.1.2" dependencies: - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - vscode-oniguruma: "npm:1.7.0" - vscode-textmate: "npm:9.0.0" - checksum: 10c0/5a7ffd954bb801e2cb512efa2ff725b37a3dfb6661f050c7ab71761cd73a7d575f857cfd518d65a9412e6e45cd0c9c379a7781275eb3de19188714ee95905540 + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-environment-service-override": "npm:25.1.2" + checksum: 10c0/f5c98c3afc02bb327afb59562b8d4fc30aba3a6fbd63369de68db63bac28bfe6fbec34f3d9acf1f6e1ece9fccda3d3e70c3e3260c973352cbdd1c8bcfc8d1243 languageName: node linkType: hard -"@codingame/monaco-vscode-theme-defaults-default-extension@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-theme-defaults-default-extension@npm:8.0.4" +"@codingame/monaco-vscode-model-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-model-service-override@npm:25.1.2" dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/500dc8a1ff507a455b405477ea9558e997f23f2777562bb9cb54df0ab0b6e9bf349f0a970bcc321f28ae336379b3444787626c9d70716ce14d4e7efce55c4ec1 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/4c7a15cd3088cd41df076bc9935c154c001c3d33ae353145bf632a31ea2b40c17b1660b92c7742dcc9d447f004f376fce2bdf3a10370d6781f5cc5635c451bb6 languageName: node linkType: hard -"@codingame/monaco-vscode-theme-service-override@npm:~8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-theme-service-override@npm:8.0.4" +"@codingame/monaco-vscode-monarch-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-monarch-service-override@npm:25.1.2" dependencies: - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/9ce94a254f54c95313b59e8db63fe56031584fdb7ea76cf045557ce0076a684d5f2ffdad18fd7d3580331391b529b55d552ea39eac05a0fc2e11ee19122ed2a0 + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/ba43c4463f8e641f13408e9c271ee24e57d573b7c6fd54e56d6d8e9cf3b170d0e82a8950bc3ab90ed24de82482249fb532df319b6aba40e24234fdb8a9e66e7d + languageName: node + linkType: hard + +"@codingame/monaco-vscode-python-default-extension@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-python-default-extension@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/a43b5023805be6237070117065ecb350817596b0819a944a5a4bbce4db9ef71fb45dea06bcbbe871389b4a79489ac1d42b84be02b7a82515338ffbdd521160f7 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-quickaccess-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-quickaccess-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/03e86955a6f1dcbce91d5c13d50f28824452675e5560992118b0e7a1005d50fbebe9ef8b0869b61bcc587abea7d1d5bfa89c60a731c4ee62b9c821a840934b83 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-r-default-extension@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-r-default-extension@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/411ccd07b76da356ef50e628c2c0b2d53e82db0fa93ae9709c5fbeb0743ede8de254edf16a0dc78e6bf1e2146c0531404d9d23236e21096a893f7220c388d35e + languageName: node + linkType: hard + +"@codingame/monaco-vscode-textmate-service-override@npm:25.1.2, @codingame/monaco-vscode-textmate-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-textmate-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/1986ced74e425b5d918e9a4b262c3f6a6fa4b7699f3eff5bbfbf397b457f6de5d6d7a6cc74da522aea203f356c0ecd9ac0400beb68a07d85e4fab9d700ed8842 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-theme-defaults-default-extension@npm:25.1.2, @codingame/monaco-vscode-theme-defaults-default-extension@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-theme-defaults-default-extension@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/2d5c9af28b18e116ec2962d7c0f4c8d38e729d385243150b2bcd8d513056700b93d17bd020cc038fc0a28ed23795eb100530b5ba1dfdec53a9d391920b4bdde8 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-theme-service-override@npm:25.1.2, @codingame/monaco-vscode-theme-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-theme-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-files-service-override": "npm:25.1.2" + checksum: 10c0/041e562624bcfbf34afb76c4a06f5f1de34a1a654151763d02f25a92fe24ed3e60d35d9087d823cf52edde8d6abf8dfdfb3a6547ba1fd39bf045e5cb4589fbf9 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-view-banner-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-view-banner-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/47030d59c8b702c09954bea6cee5678927bda6b1a619f005a40f2733e07db1262d26af3faa66d88b7fdcf11e80c6a574581e55b6f86e6592384a9a1a9ce4cfa3 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-view-common-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-view-common-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-bulk-edit-service-override": "npm:25.1.2" + checksum: 10c0/b17311fbfd1157d0787762b89091841ec37572096f013fe0a37c105f258923360e851c50058f2129869a8f74758cbdbf5c7ce66eb7894565632a9ceb557d1721 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-view-status-bar-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-view-status-bar-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/136a130ff4bdf6ed87c2c7b60b63186751497b7e20e1bdc2af39c6ecdb6747418ecf274736d7377ed1df8dd1571d3b5ecd3a254d83ede2ac9a0285f3310d003e + languageName: node + linkType: hard + +"@codingame/monaco-vscode-view-title-bar-service-override@npm:25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-view-title-bar-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + checksum: 10c0/636628e73854043c41a7bd9b3020a8b6830c26f1a96b24fbf24b993a90a98efd3d8df0073b1c8f76bbd9436e53cdb05853534ec70459f0eeaee54aa277189e38 + languageName: node + linkType: hard + +"@codingame/monaco-vscode-views-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-views-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-keybindings-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-layout-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-view-common-service-override": "npm:25.1.2" + checksum: 10c0/2df81bc7504965b99d39a144f0ae04b2bbde442e28295edd19cd66be19ec71d7b9b63ae30d634f1c3e9bff0abd342d25cdceedf2885e69a7ad85040cffee88ea + languageName: node + linkType: hard + +"@codingame/monaco-vscode-workbench-service-override@npm:^25.1.2": + version: 25.1.2 + resolution: "@codingame/monaco-vscode-workbench-service-override@npm:25.1.2" + dependencies: + "@codingame/monaco-vscode-api": "npm:25.1.2" + "@codingame/monaco-vscode-keybindings-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-quickaccess-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-view-banner-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-view-common-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-view-status-bar-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-view-title-bar-service-override": "npm:25.1.2" + checksum: 10c0/594d488fc896ad30cb88e1ac3d094580d771d45528491e4485662a1b0af3733008e6f11e9911dd874fdee45c94acdd5ade87876f1c7ad70438b7af198bbc74ce languageName: node linkType: hard @@ -6303,6 +6433,13 @@ __metadata: languageName: node linkType: hard +"@types/trusted-types@npm:^2.0.7": + version: 2.0.7 + resolution: "@types/trusted-types@npm:2.0.7" + checksum: 10c0/4c4855f10de7c6c135e0d32ce462419d8abbbc33713b31d294596c0cc34ae1fa6112a2f9da729c8f7a20707782b0d69da3b1f8df6645b0366d08825ca1522e0c + languageName: node + linkType: hard + "@types/underscore@npm:*": version: 1.13.0 resolution: "@types/underscore@npm:1.13.0" @@ -6842,10 +6979,10 @@ __metadata: languageName: node linkType: hard -"@vscode/iconv-lite-umd@npm:0.7.0": - version: 0.7.0 - resolution: "@vscode/iconv-lite-umd@npm:0.7.0" - checksum: 10c0/3316664f65f2b2089f58d5f31d09ebc931da01d826c7f57d44740689bc862ba970224ebcf70da6b823b138c80c070f484c98a21ecfddf49c84c614a0b0bd3f6f +"@vscode/iconv-lite-umd@npm:0.7.1": + version: 0.7.1 + resolution: "@vscode/iconv-lite-umd@npm:0.7.1" + checksum: 10c0/ed6026004465fd2b034cae2b4f03df15b16b90d701ac380f2596972cc651dbd143a9fcf4e68472d7cceaf3d8f91fad5b45b72077127f0b275395f6358d841e5a languageName: node linkType: hard @@ -9199,6 +9336,18 @@ __metadata: languageName: node linkType: hard +"dompurify@npm:3.3.1": + version: 3.3.1 + resolution: "dompurify@npm:3.3.1" + dependencies: + "@types/trusted-types": "npm:^2.0.7" + dependenciesMeta: + "@types/trusted-types": + optional: true + checksum: 10c0/fa0a8c55a436ba0d54389195e3d2337e311f56de709a2fc9efc98dbbc7746fa53bb4b74b6ac043b77a279a8f2ebd8685f0ebaa6e58c9e32e92051d529bc0baf8 + languageName: node + linkType: hard + "domutils@npm:^3.0.1, domutils@npm:^3.2.2": version: 3.2.2 resolution: "domutils@npm:3.2.2" @@ -10855,9 +11004,17 @@ __metadata: "@angular/platform-browser-dynamic": "npm:21.2.10" "@angular/router": "npm:21.2.10" "@auth0/angular-jwt": "npm:5.1.0" - "@codingame/monaco-vscode-java-default-extension": "npm:8.0.4" - "@codingame/monaco-vscode-python-default-extension": "npm:8.0.4" - "@codingame/monaco-vscode-r-default-extension": "npm:8.0.4" + "@codingame/monaco-vscode-configuration-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-editor-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-extensions-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-java-default-extension": "npm:25.1.2" + "@codingame/monaco-vscode-keybindings-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-languages-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-python-default-extension": "npm:25.1.2" + "@codingame/monaco-vscode-r-default-extension": "npm:25.1.2" + "@codingame/monaco-vscode-textmate-service-override": "npm:25.1.2" + "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:25.1.2" + "@codingame/monaco-vscode-theme-service-override": "npm:25.1.2" "@ngneat/until-destroy": "npm:8.1.4" "@ngx-formly/core": "npm:6.3.12" "@ngx-formly/ng-zorro-antd": "npm:6.3.12" @@ -10904,9 +11061,8 @@ __metadata: lodash-es: "npm:4.18.1" marked: "npm:17.0.1" monaco-breakpoints: "npm:0.2.0" - monaco-editor: "npm:@codingame/monaco-vscode-editor-api@8.0.4" - monaco-editor-wrapper: "npm:5.5.3" - monaco-languageclient: "npm:8.8.3" + monaco-editor: "npm:@codingame/monaco-vscode-editor-api@25.1.2" + monaco-languageclient: "npm:10.7.0" ng-zorro-antd: "npm:21.2.2" ngx-color-picker: "npm:12.0.1" ngx-file-drop: "npm:16.0.0" @@ -10932,7 +11088,7 @@ __metadata: typescript: "npm:5.9.3" uuid: "npm:8.3.2" vitest: "npm:4.0.8" - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" + vscode: "npm:@codingame/monaco-vscode-extension-api@25.1.2" webpack-bundle-analyzer: "npm:4.5.0" y-monaco: "npm:0.1.5" y-protocols: "npm:1.0.5" @@ -12726,6 +12882,15 @@ __metadata: languageName: node linkType: hard +"marked@npm:14.0.0": + version: 14.0.0 + resolution: "marked@npm:14.0.0" + bin: + marked: bin/marked.js + checksum: 10c0/57a47cb110f7b1a10f398b0a7236f9183aad2dcd5345ee73f2732b6387e585d04cef472bc655d2f84c542296be9728e179aebe3ed7f2f8666b8a0a9dae592876 + languageName: node + linkType: hard + "marked@npm:17.0.1": version: 17.0.1 resolution: "marked@npm:17.0.1" @@ -13097,79 +13262,45 @@ __metadata: languageName: node linkType: hard -"monaco-editor-wrapper@npm:5.5.3": - version: 5.5.3 - resolution: "monaco-editor-wrapper@npm:5.5.3" - dependencies: - "@codingame/monaco-vscode-configuration-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-editor-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-cs": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-de": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-es": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-fr": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-it": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-ja": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-ko": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-pl": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-pt-br": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-qps-ploc": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-ru": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-tr": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-zh-hans": "npm:~8.0.4" - "@codingame/monaco-vscode-language-pack-zh-hant": "npm:~8.0.4" - "@codingame/monaco-vscode-monarch-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-textmate-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:~8.0.4" - "@codingame/monaco-vscode-theme-service-override": "npm:~8.0.4" - monaco-editor: "npm:@codingame/monaco-vscode-editor-api@~8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@~8.0.4" +"monaco-languageclient@npm:10.7.0": + version: 10.7.0 + resolution: "monaco-languageclient@npm:10.7.0" + dependencies: + "@codingame/monaco-vscode-api": "npm:^25.1.2" + "@codingame/monaco-vscode-configuration-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-editor-api": "npm:^25.1.2" + "@codingame/monaco-vscode-editor-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-extension-api": "npm:^25.1.2" + "@codingame/monaco-vscode-extensions-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-cs": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-de": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-es": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-fr": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-it": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-ja": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-ko": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-pl": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-pt-br": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-qps-ploc": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-ru": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-tr": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-zh-hans": "npm:^25.1.2" + "@codingame/monaco-vscode-language-pack-zh-hant": "npm:^25.1.2" + "@codingame/monaco-vscode-languages-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-localization-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-log-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-model-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-monarch-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-textmate-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:^25.1.2" + "@codingame/monaco-vscode-theme-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-views-service-override": "npm:^25.1.2" + "@codingame/monaco-vscode-workbench-service-override": "npm:^25.1.2" + vscode: "npm:@codingame/monaco-vscode-extension-api@^25.1.2" vscode-languageclient: "npm:~9.0.1" vscode-languageserver-protocol: "npm:~3.17.5" - vscode-ws-jsonrpc: "npm:~3.3.2" - peerDependencies: - monaco-editor: "*" - monaco-languageclient: ~8.8.3 - vscode: "*" - peerDependenciesMeta: - monaco-editor: - optional: false - monaco-languageclient: - optional: false - vscode: - optional: false - checksum: 10c0/d113ea5408cc178d7f5558e943c9fe59e060ead59d38bcc4944f19f9120814e68d7f39f97ebb1f9ab8df862cfe4810c23bd9744e6543525b607ed0676f60e268 - languageName: node - linkType: hard - -"monaco-editor@npm:@codingame/monaco-vscode-editor-api@8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-editor-api@npm:8.0.4" - dependencies: - vscode: "npm:@codingame/monaco-vscode-api@8.0.4" - checksum: 10c0/8ab6eab164826cbca220868c07a6c071e1730ac8cd7e2057353af70d7ff58f054863bb04538ac609a09aea0b0a942eed1651e9d81434e097dfc1b3251fa5ebec - languageName: node - linkType: hard - -"monaco-languageclient@npm:8.8.3": - version: 8.8.3 - resolution: "monaco-languageclient@npm:8.8.3" - dependencies: - "@codingame/monaco-vscode-extensions-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-languages-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-localization-service-override": "npm:~8.0.4" - "@codingame/monaco-vscode-model-service-override": "npm:~8.0.4" - monaco-editor: "npm:@codingame/monaco-vscode-editor-api@~8.0.4" - vscode: "npm:@codingame/monaco-vscode-api@~8.0.4" - vscode-languageclient: "npm:~9.0.1" - peerDependencies: - monaco-editor: "*" - vscode: "*" - peerDependenciesMeta: - monaco-editor: - optional: false - vscode: - optional: false - checksum: 10c0/ed32080a773de3537cae8042c83a79e90e6010f9f9fe8bb1cb57518b75330c676788b2975963ce5a97e12ebbbb32dc561570fa22c5fbeef0f88fa7d0068284b5 + vscode-ws-jsonrpc: "npm:~3.5.0" + checksum: 10c0/b8fd931cc0a490d1a744ab54f8d596eb82808e471d2fbd1f2aec55d1b65fb24243a13a9ff0bd6998af75984289c631aa606c76e3198c6dec691ada151b71ec4a languageName: node linkType: hard @@ -17759,43 +17890,12 @@ __metadata: languageName: node linkType: hard -"vscode-oniguruma@npm:1.7.0": - version: 1.7.0 - resolution: "vscode-oniguruma@npm:1.7.0" - checksum: 10c0/bef0073c665ddf8c86e51da94529c905856559e9aba97a9882f951acd572da560384775941ab6e7e8db94d9c578b25fefb951e4b73c37e8712e16b0231de2689 - languageName: node - linkType: hard - -"vscode-textmate@npm:9.0.0": - version: 9.0.0 - resolution: "vscode-textmate@npm:9.0.0" - checksum: 10c0/83d874e1776d93d926eb0eb562476d4fd3f9633074efef056a443aee0f809d6648600b73e451f74687706435a16578a2037629247fac82a8f108ea3ff434048d - languageName: node - linkType: hard - -"vscode-ws-jsonrpc@npm:~3.3.2": - version: 3.3.2 - resolution: "vscode-ws-jsonrpc@npm:3.3.2" +"vscode-ws-jsonrpc@npm:~3.5.0": + version: 3.5.0 + resolution: "vscode-ws-jsonrpc@npm:3.5.0" dependencies: vscode-jsonrpc: "npm:~8.2.1" - checksum: 10c0/35b71071ccd3c9478d8b4f2c07ef80fa2d988f6e6d4e5d1bfc7109a8282cf091905a5c9f056bb5be8946461cb3be8e50f608825cb82b16e9b7998afc13da5783 - languageName: node - linkType: hard - -"vscode@npm:@codingame/monaco-vscode-api@8.0.4": - version: 8.0.4 - resolution: "@codingame/monaco-vscode-api@npm:8.0.4" - dependencies: - "@codingame/monaco-vscode-base-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-environment-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-extensions-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-files-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-host-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-layout-service-override": "npm:8.0.4" - "@codingame/monaco-vscode-quickaccess-service-override": "npm:8.0.4" - "@vscode/iconv-lite-umd": "npm:0.7.0" - jschardet: "npm:3.1.3" - checksum: 10c0/268b6584f3e5473ecd1e4ee5492477cbf9a670204fe82d8d97490987415b63bf9b40bc539d639e7f0aaf19b982d9445b746465acf6a0b4b669050b5c2c380d21 + checksum: 10c0/be2297cddeb3850218b1c4529345e2335ead38f8114036eb02f754911a833af6d18f3b7f19ee3596692386f8f00f7d94cb85f3e65ff44381525f0e174b249cfb languageName: node linkType: hard From 831d9ea766cf3f18c5233c130a6f9cd449a53ad0 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 18:59:19 -0700 Subject: [PATCH 02/26] chore(deps): correct d3-path license to ISC in LICENSE-binary The package's npm tarball ships an older BSD-3-Clause LICENSE file but the d3-path project's upstream LICENSE (https://github.com/d3/d3-path) is ISC. license-webpack-plugin reported BSD-3-Clause off the tarball, which is the historical artifact rather than the project's current license. Move it back into the ISC bucket alongside the rest of the d3 ecosystem. --- frontend/LICENSE-binary | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/LICENSE-binary b/frontend/LICENSE-binary index 727d6bcabf3..42b2725b419 100644 --- a/frontend/LICENSE-binary +++ b/frontend/LICENSE-binary @@ -346,7 +346,6 @@ Dependencies under the BSD 3-Clause License -------------------------------------------------------------------------------- Angular / npm packages: - - d3-path@2.0.0 - d3-shape@2.1.0 - ieee754@1.2.1 - quill@1.3.7 @@ -364,6 +363,7 @@ Dependencies under the ISC License Angular / npm packages: - concaveman@2.0.0 + - d3-path@2.0.0 - minimatch@5.1.9 - quickselect@3.0.0 - tinyqueue@2.0.3 From 03b36a2bc5c87144699e5c487f2858bbdac00eeb Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 19:33:44 -0700 Subject: [PATCH 03/26] chore(deps): drop unused content-disposition + webpack-bundle-analyzer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * download.service.ts had `var contentDisposition = require("content-disposition")` that was never read or called — removed the dead require, then dropped both `content-disposition` and `@types/content-disposition` from package.json. * `webpack-bundle-analyzer` was only referenced from the `analyze` npm script and never invoked from CI. Dropped both the dep and the script. --- frontend/package.json | 6 +- .../service/user/download/download.service.ts | 2 - frontend/yarn.lock | 123 ++---------------- 3 files changed, 13 insertions(+), 118 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 926a4032cfe..935606bdbb4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,7 +9,6 @@ "start": "concurrently --kill-others \"npx y-websocket\" \"ng serve\"", "build": "node --max-old-space-size=8192 ./node_modules/@angular/cli/bin/ng build --configuration=production --progress=false --source-map=false", "build:ci": "node --max-old-space-size=8192 ./node_modules/nx/dist/bin/nx.js build --configuration=production --progress=false --source-map=false", - "analyze": "ng build --configuration=production --stats-json && webpack-bundle-analyzer dist/stats.json", "test": "ng test --watch=false", "test:ci": "node --max-old-space-size=8192 ./node_modules/nx/dist/bin/nx.js test --watch=false --progress=false --coverage --coverage-reporters=lcovonly", "prettier:fix": "prettier --write ./src", @@ -52,7 +51,6 @@ "ai": "5.0.93", "ajv": "8.10.0", "concaveman": "2.0.0", - "content-disposition": "0.5.4", "d3-shape": "2.1.0", "dagre": "0.8.5", "file-saver": "2.0.5", @@ -110,7 +108,6 @@ "@schematics/angular": "21.2.8", "@types/backbone": "1.4.15", "@types/concaveman": "1.1.6", - "@types/content-disposition": "0", "@types/d3-shape": "2.1.2", "@types/dagre": "0.7.47", "@types/file-saver": "2.0.5", @@ -143,8 +140,7 @@ "sass": "1.71.1", "ts-proto": "2.2.0", "typescript": "5.9.3", - "vitest": "4.0.8", - "webpack-bundle-analyzer": "4.5.0" + "vitest": "4.0.8" }, "browserslist": [ "defaults", diff --git a/frontend/src/app/dashboard/service/user/download/download.service.ts b/frontend/src/app/dashboard/service/user/download/download.service.ts index 0e202e0c26c..811ebe37f47 100644 --- a/frontend/src/app/dashboard/service/user/download/download.service.ts +++ b/frontend/src/app/dashboard/service/user/download/download.service.ts @@ -31,8 +31,6 @@ import { WORKFLOW_EXECUTIONS_API_BASE_URL } from "../workflow-executions/workflo import { DashboardWorkflowComputingUnit } from "../../../../common/type/workflow-computing-unit"; import { TOKEN_KEY } from "../../../../common/service/user/auth.service"; -var contentDisposition = require("content-disposition"); - export const EXPORT_BASE_URL = "result/export"; const IFRAME_TIMEOUT_MS = 10000; export const DOWNLOADABILITY_BASE_URL = "result/downloadability"; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index e58d2b9628f..afc2308c525 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -5282,13 +5282,6 @@ __metadata: languageName: node linkType: hard -"@polka/url@npm:^1.0.0-next.20": - version: 1.0.0-next.29 - resolution: "@polka/url@npm:1.0.0-next.29" - checksum: 10c0/0d58e081844095cb029d3c19a659bfefd09d5d51a2f791bc61eba7ea826f13d6ee204a8a448c2f5a855c17df07b37517373ff916dd05801063c0568ae9937684 - languageName: node - linkType: hard - "@prettier/eslint@npm:prettier-eslint@^16.1.0": version: 16.4.2 resolution: "prettier-eslint@npm:16.4.2" @@ -6038,13 +6031,6 @@ __metadata: languageName: node linkType: hard -"@types/content-disposition@npm:0": - version: 0.5.9 - resolution: "@types/content-disposition@npm:0.5.9" - checksum: 10c0/9fd520dae1a9c7b85909e59f548f905a670a6e2f83642f9734d1b05126f64ac8c8e2c282a663edf27d58bc34fbbacf46a4d4a95d3802b42106174a19a68175c8 - languageName: node - linkType: hard - "@types/d3-path@npm:^2": version: 2.0.4 resolution: "@types/d3-path@npm:2.0.4" @@ -7247,7 +7233,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.0, acorn-walk@npm:^8.1.1": +"acorn-walk@npm:^8.1.1": version: 8.3.5 resolution: "acorn-walk@npm:8.3.5" dependencies: @@ -7256,7 +7242,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": version: 8.16.0 resolution: "acorn@npm:8.16.0" bin: @@ -8493,13 +8479,6 @@ __metadata: languageName: node linkType: hard -"commander@npm:^7.2.0": - version: 7.2.0 - resolution: "commander@npm:7.2.0" - checksum: 10c0/8d690ff13b0356df7e0ebbe6c59b4712f754f4b724d4f473d3cc5b3fdcf978e3a5dc3078717858a2ceb50b0f84d0660a7f22a96cdc50fb877d0c9bb31593d23a - languageName: node - linkType: hard - "common-path-prefix@npm:^3.0.0": version: 3.0.0 resolution: "common-path-prefix@npm:3.0.0" @@ -8584,7 +8563,14 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:0.5.4, content-disposition@npm:~0.5.4": +"content-disposition@npm:^1.0.0": + version: 1.1.0 + resolution: "content-disposition@npm:1.1.0" + checksum: 10c0/94e0aef65873e69330f5f187fbc44ebce593bdcb8013dd8a68b7d0f159ca089bd30db3f8095d829f81c341695b60a6085ee6e15e6d775c4a325b586cc8d91974 + languageName: node + linkType: hard + +"content-disposition@npm:~0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -8593,13 +8579,6 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:^1.0.0": - version: 1.1.0 - resolution: "content-disposition@npm:1.1.0" - checksum: 10c0/94e0aef65873e69330f5f187fbc44ebce593bdcb8013dd8a68b7d0f159ca089bd30db3f8095d829f81c341695b60a6085ee6e15e6d775c4a325b586cc8d91974 - languageName: node - linkType: hard - "content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" @@ -9411,13 +9390,6 @@ __metadata: languageName: node linkType: hard -"duplexer@npm:^0.1.2": - version: 0.1.2 - resolution: "duplexer@npm:0.1.2" - checksum: 10c0/c57bcd4bdf7e623abab2df43a7b5b23d18152154529d166c1e0da6bee341d84c432d157d7e97b32fecb1bf3a8b8857dd85ed81a915789f550637ed25b8e64fc2 - languageName: node - linkType: hard - "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -11022,7 +10994,6 @@ __metadata: "@schematics/angular": "npm:21.2.8" "@types/backbone": "npm:1.4.15" "@types/concaveman": "npm:1.1.6" - "@types/content-disposition": "npm:0" "@types/d3-shape": "npm:2.1.2" "@types/dagre": "npm:0.7.47" "@types/file-saver": "npm:2.0.5" @@ -11044,7 +11015,6 @@ __metadata: ajv: "npm:8.10.0" concaveman: "npm:2.0.0" concurrently: "npm:7.4.0" - content-disposition: "npm:0.5.4" d3-shape: "npm:2.1.0" dagre: "npm:0.8.5" eslint: "npm:8.57.0" @@ -11089,7 +11059,6 @@ __metadata: uuid: "npm:8.3.2" vitest: "npm:4.0.8" vscode: "npm:@codingame/monaco-vscode-extension-api@25.1.2" - webpack-bundle-analyzer: "npm:4.5.0" y-monaco: "npm:0.1.5" y-protocols: "npm:1.0.5" y-quill: "npm:0.1.5" @@ -11100,15 +11069,6 @@ __metadata: languageName: unknown linkType: soft -"gzip-size@npm:^6.0.0": - version: 6.0.0 - resolution: "gzip-size@npm:6.0.0" - dependencies: - duplexer: "npm:^0.1.2" - checksum: 10c0/4ccb924626c82125897a997d1c84f2377846a6ef57fbee38f7c0e6b41387fba4d00422274440747b58008b5d60114bac2349c2908e9aba55188345281af40a3f - languageName: node - linkType: hard - "handle-thing@npm:^2.0.0": version: 2.0.1 resolution: "handle-thing@npm:2.0.1" @@ -12694,7 +12654,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": +"lodash@npm:^4.17.15, lodash@npm:^4.17.21": version: 4.18.1 resolution: "lodash@npm:4.18.1" checksum: 10c0/757228fc68805c59789e82185135cf85f05d0b2d3d54631d680ca79ec21944ec8314d4533639a14b8bcfbd97a517e78960933041a5af17ecb693ec6eecb99a27 @@ -13318,13 +13278,6 @@ __metadata: languageName: node linkType: hard -"mrmime@npm:^1.0.0": - version: 1.0.1 - resolution: "mrmime@npm:1.0.1" - checksum: 10c0/ab071441da76fd23b3b0d1823d77aacf8679d379a4a94cacd83e487d3d906763b277f3203a594c613602e31ab5209c26a8119b0477c4541ef8555b293a9db6d3 - languageName: node - linkType: hard - "ms@npm:2.0.0": version: 2.0.0 resolution: "ms@npm:2.0.0" @@ -14062,7 +14015,7 @@ __metadata: languageName: node linkType: hard -"opener@npm:^1.5.1, opener@npm:^1.5.2": +"opener@npm:^1.5.1": version: 1.5.2 resolution: "opener@npm:1.5.2" bin: @@ -16510,17 +16463,6 @@ __metadata: languageName: node linkType: hard -"sirv@npm:^1.0.7": - version: 1.0.19 - resolution: "sirv@npm:1.0.19" - dependencies: - "@polka/url": "npm:^1.0.0-next.20" - mrmime: "npm:^1.0.0" - totalist: "npm:^1.0.0" - checksum: 10c0/393cc0471e82d3e754a8c1b2b348a86249db1f686aeb11c17e4217326a8b1a96029d9f1b58362ebb3e511b7b98c47cd43c4305dde98322bb1259d07dec2d4908 - languageName: node - linkType: hard - "sisteransi@npm:^1.0.5": version: 1.0.5 resolution: "sisteransi@npm:1.0.5" @@ -17182,13 +17124,6 @@ __metadata: languageName: node linkType: hard -"totalist@npm:^1.0.0": - version: 1.1.0 - resolution: "totalist@npm:1.1.0" - checksum: 10c0/2adbd4501c8290c2a96617a83dc67dfdd02bcbd360032017e27ccf27bbb09649bbe8dad1c45d97be6874281178aca5b3f62ed059d1eeda77c479cfb8eb3a9266 - languageName: node - linkType: hard - "tough-cookie@npm:^5.0.0": version: 5.1.2 resolution: "tough-cookie@npm:5.1.2" @@ -17974,25 +17909,6 @@ __metadata: languageName: node linkType: hard -"webpack-bundle-analyzer@npm:4.5.0": - version: 4.5.0 - resolution: "webpack-bundle-analyzer@npm:4.5.0" - dependencies: - acorn: "npm:^8.0.4" - acorn-walk: "npm:^8.0.0" - chalk: "npm:^4.1.0" - commander: "npm:^7.2.0" - gzip-size: "npm:^6.0.0" - lodash: "npm:^4.17.20" - opener: "npm:^1.5.2" - sirv: "npm:^1.0.7" - ws: "npm:^7.3.1" - bin: - webpack-bundle-analyzer: lib/bin/analyzer.js - checksum: 10c0/5130be9fa58645e412e9824f98bd961afe540b9918951ddc87b688f3e176f4a101fcb16a304c74f0d1ddd9f2528ec2fa44bcfcea3fe07635fa9af0e3104644aa - languageName: node - linkType: hard - "webpack-dev-middleware@npm:7.4.5, webpack-dev-middleware@npm:^7.4.2": version: 7.4.5 resolution: "webpack-dev-middleware@npm:7.4.5" @@ -18350,21 +18266,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.3.1": - version: 7.5.10 - resolution: "ws@npm:7.5.10" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10c0/bd7d5f4aaf04fae7960c23dcb6c6375d525e00f795dd20b9385902bd008c40a94d3db3ce97d878acc7573df852056ca546328b27b39f47609f80fb22a0a9b61d - languageName: node - linkType: hard - "ws@npm:^8.18.0": version: 8.20.0 resolution: "ws@npm:8.20.0" From 08f29c5777fa2f3b7dd97b2b78b3a3e115c86867 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 19:42:58 -0700 Subject: [PATCH 04/26] chore(deps): drop redundant @codingame/monaco-vscode-* declarations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v10 commit listed every codingame service-override package texera might touch, but six of them are pulled in transitively by monaco-languageclient itself (or by another codingame override) and were never imported from texera's source. Drop the redundant declarations: - configuration-service-override (mlc dep) - editor-service-override (mlc dep) - extensions-service-override (mlc dep) - languages-service-override (mlc dep) - theme-service-override (mlc dep) - keybindings-service-override (pulled in via views- and workbench-service-override) Bundle output and LICENSE-binary are unchanged — only package.json gets shorter. Verified with yarn build + yarn test (63 files, 269 tests). --- frontend/package.json | 6 ------ frontend/yarn.lock | 14 ++++---------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 935606bdbb4..6136fc48eaf 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -34,17 +34,11 @@ "@angular/platform-browser-dynamic": "21.2.10", "@angular/router": "21.2.10", "@auth0/angular-jwt": "5.1.0", - "@codingame/monaco-vscode-configuration-service-override": "25.1.2", - "@codingame/monaco-vscode-editor-service-override": "25.1.2", - "@codingame/monaco-vscode-extensions-service-override": "25.1.2", "@codingame/monaco-vscode-java-default-extension": "25.1.2", - "@codingame/monaco-vscode-keybindings-service-override": "25.1.2", - "@codingame/monaco-vscode-languages-service-override": "25.1.2", "@codingame/monaco-vscode-python-default-extension": "25.1.2", "@codingame/monaco-vscode-r-default-extension": "25.1.2", "@codingame/monaco-vscode-textmate-service-override": "25.1.2", "@codingame/monaco-vscode-theme-defaults-default-extension": "25.1.2", - "@codingame/monaco-vscode-theme-service-override": "25.1.2", "@ngneat/until-destroy": "8.1.4", "@ngx-formly/core": "6.3.12", "@ngx-formly/ng-zorro-antd": "6.3.12", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index afc2308c525..8588add61b9 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2096,7 +2096,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-configuration-service-override@npm:25.1.2, @codingame/monaco-vscode-configuration-service-override@npm:^25.1.2": +"@codingame/monaco-vscode-configuration-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-configuration-service-override@npm:25.1.2" dependencies: @@ -2115,7 +2115,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-editor-service-override@npm:25.1.2, @codingame/monaco-vscode-editor-service-override@npm:^25.1.2": +"@codingame/monaco-vscode-editor-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-editor-service-override@npm:25.1.2" dependencies: @@ -2316,7 +2316,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-languages-service-override@npm:25.1.2, @codingame/monaco-vscode-languages-service-override@npm:^25.1.2": +"@codingame/monaco-vscode-languages-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-languages-service-override@npm:25.1.2" dependencies: @@ -2418,7 +2418,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-theme-service-override@npm:25.1.2, @codingame/monaco-vscode-theme-service-override@npm:^25.1.2": +"@codingame/monaco-vscode-theme-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-theme-service-override@npm:25.1.2" dependencies: @@ -10976,17 +10976,11 @@ __metadata: "@angular/platform-browser-dynamic": "npm:21.2.10" "@angular/router": "npm:21.2.10" "@auth0/angular-jwt": "npm:5.1.0" - "@codingame/monaco-vscode-configuration-service-override": "npm:25.1.2" - "@codingame/monaco-vscode-editor-service-override": "npm:25.1.2" - "@codingame/monaco-vscode-extensions-service-override": "npm:25.1.2" "@codingame/monaco-vscode-java-default-extension": "npm:25.1.2" - "@codingame/monaco-vscode-keybindings-service-override": "npm:25.1.2" - "@codingame/monaco-vscode-languages-service-override": "npm:25.1.2" "@codingame/monaco-vscode-python-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-r-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-textmate-service-override": "npm:25.1.2" "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:25.1.2" - "@codingame/monaco-vscode-theme-service-override": "npm:25.1.2" "@ngneat/until-destroy": "npm:8.1.4" "@ngx-formly/core": "npm:6.3.12" "@ngx-formly/ng-zorro-antd": "npm:6.3.12" From 75c2bc07fb30bbee70c11f0a774ef76ef753e21e Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 19:48:19 -0700 Subject: [PATCH 05/26] chore(deps): drop @codingame/monaco-vscode-textmate-service-override too The trampoline at `workers/textmate.worker.ts` deep-imports `@codingame/monaco-vscode-textmate-service-override/worker`, but the package is also a direct dependency of `monaco-languageclient@10.7.0`, so the resolution still works without an explicit declaration. Drop the dep and let mlc pin it. --- frontend/package.json | 1 - frontend/yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 6136fc48eaf..d02b53379b6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,6 @@ "@codingame/monaco-vscode-java-default-extension": "25.1.2", "@codingame/monaco-vscode-python-default-extension": "25.1.2", "@codingame/monaco-vscode-r-default-extension": "25.1.2", - "@codingame/monaco-vscode-textmate-service-override": "25.1.2", "@codingame/monaco-vscode-theme-defaults-default-extension": "25.1.2", "@ngneat/until-destroy": "8.1.4", "@ngx-formly/core": "6.3.12", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 8588add61b9..dc17ad3616c 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2399,7 +2399,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-textmate-service-override@npm:25.1.2, @codingame/monaco-vscode-textmate-service-override@npm:^25.1.2": +"@codingame/monaco-vscode-textmate-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-textmate-service-override@npm:25.1.2" dependencies: @@ -10979,7 +10979,6 @@ __metadata: "@codingame/monaco-vscode-java-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-python-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-r-default-extension": "npm:25.1.2" - "@codingame/monaco-vscode-textmate-service-override": "npm:25.1.2" "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:25.1.2" "@ngneat/until-destroy": "npm:8.1.4" "@ngx-formly/core": "npm:6.3.12" From 710dd1b2505798bad994cdad510dddf3de37ebb1 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 20:01:14 -0700 Subject: [PATCH 06/26] chore(deps): drop @codingame/monaco-vscode-theme-defaults-default-extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `code-editor.component.ts` `import("@codingame/monaco-vscode-theme-defaults-default-extension")` still resolves: the package is a direct dependency of `monaco-languageclient@10.7.0`. Same pattern as the previous textmate override drop — let mlc pin it. --- frontend/package.json | 1 - frontend/yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index d02b53379b6..b4e462e713b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -37,7 +37,6 @@ "@codingame/monaco-vscode-java-default-extension": "25.1.2", "@codingame/monaco-vscode-python-default-extension": "25.1.2", "@codingame/monaco-vscode-r-default-extension": "25.1.2", - "@codingame/monaco-vscode-theme-defaults-default-extension": "25.1.2", "@ngneat/until-destroy": "8.1.4", "@ngx-formly/core": "6.3.12", "@ngx-formly/ng-zorro-antd": "6.3.12", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index dc17ad3616c..8a54489bcef 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2409,7 +2409,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-theme-defaults-default-extension@npm:25.1.2, @codingame/monaco-vscode-theme-defaults-default-extension@npm:^25.1.2": +"@codingame/monaco-vscode-theme-defaults-default-extension@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-theme-defaults-default-extension@npm:25.1.2" dependencies: @@ -10979,7 +10979,6 @@ __metadata: "@codingame/monaco-vscode-java-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-python-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-r-default-extension": "npm:25.1.2" - "@codingame/monaco-vscode-theme-defaults-default-extension": "npm:25.1.2" "@ngneat/until-destroy": "npm:8.1.4" "@ngx-formly/core": "npm:6.3.12" "@ngx-formly/ng-zorro-antd": "npm:6.3.12" From dbed098b2c90e8f00d88f05fb4c2d102f2e294ac Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 21:11:10 -0700 Subject: [PATCH 07/26] feat(frontend): retire R UDF editor support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drops the R syntax-highlighting branch from the code editor + the @codingame/monaco-vscode-r-default-extension dependency. The backend RUDF / RUDFSource operators still exist; opening their code editor now falls through to the default Java highlighting (degraded but functional). * code-editor.component.ts: remove the R language detection branch and the .r file-suffix mapping; drop the dynamic-import of the R default extension from the bootstrap chain. * code-debugger.component.ts: drop the side-effect import of the R default extension. * package.json + LICENSE-binary: drop the codingame R extension. Verified: yarn build, yarn test (63 / 269 — parity). --- frontend/LICENSE-binary | 1 - frontend/package.json | 1 - .../code-editor-dialog/code-debugger.component.ts | 1 - .../code-editor-dialog/code-editor.component.ts | 7 +------ frontend/yarn.lock | 10 ---------- 5 files changed, 1 insertion(+), 19 deletions(-) diff --git a/frontend/LICENSE-binary b/frontend/LICENSE-binary index 42b2725b419..2bb45310822 100644 --- a/frontend/LICENSE-binary +++ b/frontend/LICENSE-binary @@ -268,7 +268,6 @@ Angular / npm packages: - @codingame/monaco-vscode-monarch-service-override@25.1.2 - @codingame/monaco-vscode-python-default-extension@25.1.2 - @codingame/monaco-vscode-quickaccess-service-override@25.1.2 - - @codingame/monaco-vscode-r-default-extension@25.1.2 - @codingame/monaco-vscode-textmate-service-override@25.1.2 - @codingame/monaco-vscode-theme-defaults-default-extension@25.1.2 - @codingame/monaco-vscode-theme-service-override@25.1.2 diff --git a/frontend/package.json b/frontend/package.json index b4e462e713b..e7be77ffb9a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -36,7 +36,6 @@ "@auth0/angular-jwt": "5.1.0", "@codingame/monaco-vscode-java-default-extension": "25.1.2", "@codingame/monaco-vscode-python-default-extension": "25.1.2", - "@codingame/monaco-vscode-r-default-extension": "25.1.2", "@ngneat/until-destroy": "8.1.4", "@ngx-formly/core": "6.3.12", "@ngx-formly/ng-zorro-antd": "6.3.12", diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-debugger.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-debugger.component.ts index 14384524cfa..83fcbc77ec5 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-debugger.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-debugger.component.ts @@ -21,7 +21,6 @@ import { AfterViewInit, Component, Input, ViewChild } from "@angular/core"; import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy"; import { SafeStyle } from "@angular/platform-browser"; import "@codingame/monaco-vscode-python-default-extension"; -import "@codingame/monaco-vscode-r-default-extension"; import "@codingame/monaco-vscode-java-default-extension"; import { isDefined } from "../../../common/util/predicate"; import * as monaco from "monaco-editor"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index 1c68329bd01..e742a34e9ea 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -153,9 +153,7 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy this.currentOperatorId = this.workflowActionService.getJointGraphWrapper().getCurrentHighlightedOperatorIDs()[0]; const operatorType = this.workflowActionService.getTexeraGraph().getOperator(this.currentOperatorId).operatorType; - if (operatorType === "RUDFSource" || operatorType === "RUDF") { - this.setLanguage("r"); - } else if ( + if ( operatorType === "PythonUDFV2" || operatorType === "PythonUDFSourceV2" || operatorType === "DualInputPortsPythonUDFV2" @@ -229,8 +227,6 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy switch (language.toLowerCase()) { case "python": return ".py"; - case "r": - return ".r"; case "javascript": return ".js"; case "java": @@ -300,7 +296,6 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy .then(() => Promise.all([ import("@codingame/monaco-vscode-python-default-extension"), - import("@codingame/monaco-vscode-r-default-extension"), import("@codingame/monaco-vscode-java-default-extension"), import("@codingame/monaco-vscode-theme-defaults-default-extension"), ]) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 8a54489bcef..3f6e72abc9d 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2390,15 +2390,6 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-r-default-extension@npm:25.1.2": - version: 25.1.2 - resolution: "@codingame/monaco-vscode-r-default-extension@npm:25.1.2" - dependencies: - "@codingame/monaco-vscode-api": "npm:25.1.2" - checksum: 10c0/411ccd07b76da356ef50e628c2c0b2d53e82db0fa93ae9709c5fbeb0743ede8de254edf16a0dc78e6bf1e2146c0531404d9d23236e21096a893f7220c388d35e - languageName: node - linkType: hard - "@codingame/monaco-vscode-textmate-service-override@npm:^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-textmate-service-override@npm:25.1.2" @@ -10978,7 +10969,6 @@ __metadata: "@auth0/angular-jwt": "npm:5.1.0" "@codingame/monaco-vscode-java-default-extension": "npm:25.1.2" "@codingame/monaco-vscode-python-default-extension": "npm:25.1.2" - "@codingame/monaco-vscode-r-default-extension": "npm:25.1.2" "@ngneat/until-destroy": "npm:8.1.4" "@ngx-formly/core": "npm:6.3.12" "@ngx-formly/ng-zorro-antd": "npm:6.3.12" From e49949874dfdef1fabeea9d230629e9961a74068 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 21:20:16 -0700 Subject: [PATCH 08/26] chore(deps): drop redundant `vscode` resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both consumers — texera's own `dependencies.vscode` and `monaco-languageclient@10.7.0`'s `dependencies.vscode` — already alias to `npm:@codingame/monaco-vscode-extension-api`, so yarn unifies them without a `resolutions` entry. Verified yarn.lock still resolves `vscode@npm:` to the codingame extension api. The `monaco-editor` resolution stays — it's load-bearing because `monaco-breakpoints` declares `monaco-editor: ^0.39.0` (vanilla) and without forcing the alias yarn would install two competing Monaco copies. --- frontend/package.json | 1 - frontend/yarn.lock | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index e7be77ffb9a..920db04d6e4 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -80,7 +80,6 @@ "zone.js": "0.15.1" }, "resolutions": { - "vscode": "npm:@codingame/monaco-vscode-extension-api@25.1.2", "monaco-editor": "npm:@codingame/monaco-vscode-editor-api@25.1.2", "webpack": "5.104.1", "jschardet": "portal:./tools/jschardet-stub" diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 3f6e72abc9d..f56f0e3ac4c 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2133,7 +2133,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-extension-api@npm:^25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@25.1.2": +"@codingame/monaco-vscode-extension-api@npm:^25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-extension-api@npm:25.1.2" dependencies: From f422af16dac2704ed24d74b1470b5d2d6ab0bdaf Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Wed, 6 May 2026 21:25:08 -0700 Subject: [PATCH 09/26] chore(deps): drop unused `vscode` direct dependency No texera source file imports from `vscode`. The package was only there to align with the codingame convention (`vscode` aliased to `@codingame/monaco-vscode-extension-api`). `monaco-languageclient@10.7.0` already declares the same alias as one of its dependencies, so the package still installs transitively for any dep chain that needs it. --- frontend/package.json | 1 - frontend/yarn.lock | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 920db04d6e4..ef66c4a601b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -70,7 +70,6 @@ "tinyqueue": "2.0.3", "tslib": "2.3.1", "uuid": "8.3.2", - "vscode": "npm:@codingame/monaco-vscode-extension-api@25.1.2", "y-monaco": "0.1.5", "y-protocols": "1.0.5", "y-quill": "0.1.5", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index f56f0e3ac4c..f214cf047cb 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2133,7 +2133,7 @@ __metadata: languageName: node linkType: hard -"@codingame/monaco-vscode-extension-api@npm:^25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@^25.1.2": +"@codingame/monaco-vscode-extension-api@npm:^25.1.2, vscode@npm:@codingame/monaco-vscode-extension-api@^25.1.2": version: 25.1.2 resolution: "@codingame/monaco-vscode-extension-api@npm:25.1.2" dependencies: @@ -11040,7 +11040,6 @@ __metadata: typescript: "npm:5.9.3" uuid: "npm:8.3.2" vitest: "npm:4.0.8" - vscode: "npm:@codingame/monaco-vscode-extension-api@25.1.2" y-monaco: "npm:0.1.5" y-protocols: "npm:1.0.5" y-quill: "npm:0.1.5" From 2389879a654f9a4ea2913562886e3a50c6d3c399 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 00:49:33 -0700 Subject: [PATCH 10/26] chore(frontend): inline codingame worker URL refs, drop trampoline files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The codingame worker bundles were previously pulled in via three single-line trampoline files in `code-editor-dialog/workers/`, each re-exporting one upstream worker entry. Webpack 5 recognises `new Worker(new URL("@pkg/...", import.meta.url))` natively and bundles the full dep tree into a worker chunk, so the trampolines aren't needed for the production build. The test pipeline blocks the truly-inline form: `@angular/build:unit-test` runs `@angular/build:application` (esbuild) regardless of `customWebpackConfig`, and esbuild resolves `new URL(spec, import.meta.url)` literally relative to the source file rather than through node_modules. To keep tests buildable, the URL refs live in a single sibling file that's swapped for a no-op stub via `fileReplacements` on a new `gui:build-test` target. Before After ────────────────────────────────────── ────────────────────────────────────── workers/editor.worker.ts codingame-worker-factory.ts workers/extension-host.worker.ts codingame-worker-factory.stub.ts workers/textmate.worker.ts (3 opaque trampolines) (1 readable factory + 1 test stub) Worker chunks are byte-identical to the pre-refactor build (same content hashes, same sizes: 1.3MB textmate / 518KB ext-host / 220KB editor). Tests stay at 63 / 269 parity. --- frontend/angular.json | 21 +++++-- .../code-editor.component.ts | 31 +++------- ...er.ts => codingame-worker-factory.stub.ts} | 9 ++- .../codingame-worker-factory.ts | 59 +++++++++++++++++++ .../workers/editor.worker.ts | 26 -------- .../workers/textmate.worker.ts | 21 ------- frontend/src/tsconfig.app.json | 7 +-- 7 files changed, 90 insertions(+), 84 deletions(-) rename frontend/src/app/workspace/component/code-editor-dialog/{workers/extension-host.worker.ts => codingame-worker-factory.stub.ts} (68%) create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts delete mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts delete mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts diff --git a/frontend/angular.json b/frontend/angular.json index e521d7cee9e..69746b7fd51 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -64,10 +64,6 @@ "with": "src/environments/environment.prod.ts" } ] - }, - "test": { - "tsConfig": "src/tsconfig.test.json", - "main": "src/main.test.ts" } }, "defaultConfiguration": "" @@ -84,10 +80,25 @@ } } }, + "build-test": { + "builder": "@angular/build:application", + "options": { + "outputPath": "dist", + "browser": "src/main.test.ts", + "tsConfig": "src/tsconfig.test.json", + "polyfills": ["zone.js"], + "fileReplacements": [ + { + "replace": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts", + "with": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts" + } + ] + } + }, "test": { "builder": "@angular/build:unit-test", "options": { - "buildTarget": "gui:build:test", + "buildTarget": "gui:build-test", "runner": "vitest", "runnerConfig": "vitest.config.ts", "tsConfig": "src/tsconfig.spec.json", diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index e742a34e9ea..dc43a94b3ab 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -49,6 +49,7 @@ import { } from "monaco-languageclient/vscodeApiWrapper"; import { LanguageClientWrapper, type LanguageClientConfig } from "monaco-languageclient/lcwrapper"; import { EditorApp, type EditorAppConfig } from "monaco-languageclient/editorApp"; +import { registerCodingameWorkers } from "./codingame-worker-factory"; // NOTE: the @codingame/monaco-vscode-*-default-extension packages are imported // dynamically inside `ensureVscodeApiStarted` below — see the comment there for // why static side-effect imports get tree-shaken in this project's build pipeline. @@ -255,30 +256,12 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy }), }, // Wire up the workers monaco-vscode-api spawns at runtime (editor, - // extension host, textmate). The package's `configureDefaultWorkerFactory` - // tries to load worker scripts straight out of the codingame node_modules - // tree via `new URL('@codingame/...', import.meta.url)`, but webpack only - // emits that URL as a static asset — the worker's transitive imports are - // never bundled, so the worker 404s on its first relative import at - // runtime. Instead we use the literal `new Worker(new URL('./local.ts', - // import.meta.url))` pattern that webpack 5 recognizes as a worker entry - // point; the trampoline files in `./workers/` re-export the codingame - // worker source and pull the whole dep tree into the bundle. - monacoWorkerFactory: () => { - const env = getEnhancedMonacoEnvironment(); - env.getWorker = (_workerId: string, label: string): Worker => { - switch (label) { - case "editorWorkerService": - return new Worker(new URL("./workers/editor.worker", import.meta.url), { type: "module" }); - case "extensionHostWorkerMain": - return new Worker(new URL("./workers/extension-host.worker", import.meta.url), { type: "module" }); - case "TextMateWorker": - return new Worker(new URL("./workers/textmate.worker", import.meta.url), { type: "module" }); - default: - throw new Error(`No worker configured for label: ${label}`); - } - }; - }, + // extension host, textmate). The URL refs live in a sibling file that + // gets fileReplacements'd to a stub for the test pipeline — esbuild + // (used by @angular/build:unit-test) resolves `new URL(spec, + // import.meta.url)` literally and would otherwise fail on the codingame + // package paths. Webpack 5 handles them correctly. + monacoWorkerFactory: registerCodingameWorkers, }; const apiWrapper = new MonacoVscodeApiWrapper(apiConfig); // Start the vscode-api FIRST, then load AND fully activate the default diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts similarity index 68% rename from frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts rename to frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts index 6d667025576..38ba736d851 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts @@ -17,5 +17,10 @@ * under the License. */ -// See ./editor.worker.ts for why this trampoline exists. -import "@codingame/monaco-vscode-api/workers/extensionHost.worker"; +// Test-time replacement for ./codingame-worker-factory.ts (see angular.json +// `gui:build-test`'s fileReplacements). The real file's `new URL("@codingame/...", +// import.meta.url)` calls fail to resolve under esbuild — this stub keeps unit +// tests buildable; tests don't instantiate the editor's Web Workers. +export function registerCodingameWorkers(): void { + // no-op +} diff --git a/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts b/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts new file mode 100644 index 00000000000..0d9775ee3fd --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts @@ -0,0 +1,59 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { getEnhancedMonacoEnvironment } from "monaco-languageclient/vscodeApiWrapper"; + +/** + * Wires `MonacoEnvironment.getWorker` to the codingame-shipped worker entries. + * + * Each `new Worker(new URL(...))` literal lets webpack 5 treat the URL as a + * worker entry point and bundle the worker's transitive deps into a dedicated + * chunk — `configureDefaultWorkerFactory` from monaco-vscode-api can't do this + * because it only emits the upstream worker.js as a static asset (which 404s + * on its first relative import at runtime). + * + * This file gets fileReplacements'd to `codingame-worker-factory.stub.ts` for + * the test pipeline. esbuild (used by @angular/build:unit-test) resolves + * `new URL(spec, import.meta.url)` literally relative to the source file and + * would otherwise fail on the codingame package paths. + */ +export function registerCodingameWorkers(): void { + const env = getEnhancedMonacoEnvironment(); + env.getWorker = (_workerId: string, label: string): Worker => { + switch (label) { + case "editorWorkerService": + return new Worker( + new URL("@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js", import.meta.url), + { type: "module" } + ); + case "extensionHostWorkerMain": + return new Worker( + new URL("@codingame/monaco-vscode-api/workers/extensionHost.worker", import.meta.url), + { type: "module" } + ); + case "TextMateWorker": + return new Worker( + new URL("@codingame/monaco-vscode-textmate-service-override/worker", import.meta.url), + { type: "module" } + ); + default: + throw new Error(`No worker configured for label: ${label}`); + } + }; +} diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts deleted file mode 100644 index 9d78785c4a0..00000000000 --- a/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// Worker entry — referenced via `new Worker(new URL('./editor.worker', import.meta.url))` -// from the editor component. Re-exporting the codingame-shipped worker as a local -// entry forces webpack to bundle the worker's transitive deps into the chunk. -// Without this trampoline, webpack only emits the upstream `worker.js` (a single -// `import './vscode/...'` line) and the browser fails to resolve the relative path -// at runtime. -import "@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts deleted file mode 100644 index 796224f9014..00000000000 --- a/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -// See ./editor.worker.ts for why this trampoline exists. -import "@codingame/monaco-vscode-textmate-service-override/worker"; diff --git a/frontend/src/tsconfig.app.json b/frontend/src/tsconfig.app.json index ada971bdcbb..6f84762b813 100644 --- a/frontend/src/tsconfig.app.json +++ b/frontend/src/tsconfig.app.json @@ -8,11 +8,6 @@ "angularCompilerOptions": { "fullTemplateTypeCheck": true }, - "files": [ - "main.ts", - "app/workspace/component/code-editor-dialog/workers/editor.worker.ts", - "app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts", - "app/workspace/component/code-editor-dialog/workers/textmate.worker.ts" - ], + "files": ["main.ts"], "include": ["**/*.d.ts"] } From c8d255f3f54ba091395c00af9925daf0ea91ca75 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 01:05:33 -0700 Subject: [PATCH 11/26] chore(frontend): inline jsdom CSS loader hook as data: URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Node ESM loader hook that strips transitive `.css` imports during specs used to live in its own `src/jsdom-css-loader-hook.mjs` sidecar, registered via `module.register(pathToFileURL(...))`. `module.register` accepts any module URL though, including `data:` URLs — folding the hook source into the registration call lets the sidecar file go away entirely. The vitest.config.ts cross-reference comment that pointed at the hook is also dropped since it duplicates what the polyfill file already documents. Tests stay at 63 / 269 parity. --- frontend/src/jsdom-css-loader-hook.mjs | 48 -------------------------- frontend/src/jsdom-svg-polyfill.ts | 20 ++++++++--- frontend/vitest.config.ts | 7 ---- 3 files changed, 16 insertions(+), 59 deletions(-) delete mode 100644 frontend/src/jsdom-css-loader-hook.mjs diff --git a/frontend/src/jsdom-css-loader-hook.mjs b/frontend/src/jsdom-css-loader-hook.mjs deleted file mode 100644 index 044e7b61fb4..00000000000 --- a/frontend/src/jsdom-css-loader-hook.mjs +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/** - * Node ESM loader hook used in the Vitest worker. Intercepts every `.css` - * import and replaces it with an empty module. - * - * Why this exists: the Angular `@angular/build:unit-test` builder pre-bundles - * spec files with esbuild and `externalPackages: true`, so transitive imports - * (e.g. `monaco-languageclient` -> `@codingame/monaco-vscode-api` -> raw - * `aria.css`) reach Node's native ESM loader instead of Vite's transform - * pipeline. Node has no built-in handler for `.css` and crashes the worker - * with `TypeError: Unknown file extension ".css"`. - * - * Vitest's `server.deps.inline` does NOT cover this because the spec is - * already bundled before vitest sees it. The loader hook is the only place - * we can intervene. - * - * Specs don't render anything, so swallowing CSS at module load is safe. - * Activated by the setupFile `jsdom-svg-polyfill.ts` calling - * `module.register(...)` at module init. - */ -export function resolve(specifier, context, nextResolve) { - if (specifier.endsWith(".css") || /\.css(\?|$)/.test(specifier)) { - return { - url: "data:text/javascript,export%20default%20%7B%7D%3B", - shortCircuit: true, - format: "module", - }; - } - return nextResolve(specifier, context); -} diff --git a/frontend/src/jsdom-svg-polyfill.ts b/frontend/src/jsdom-svg-polyfill.ts index 00720b00f9d..89fd8106e0e 100644 --- a/frontend/src/jsdom-svg-polyfill.ts +++ b/frontend/src/jsdom-svg-polyfill.ts @@ -40,15 +40,27 @@ * of Vite's transform pipeline. Without the hook, every spec that transitively * loads the codingame v25 stack crashes with `Unknown file extension ".css"`. * - * Done at the very top of this file so the registration happens before any + * The hook source lives inline as a `data:` URL — `module.register` accepts + * any module URL, and a data URL avoids carrying a separate `.mjs` sidecar + * file. Done at the top of this file so the registration runs before any * spec body imports the affected packages. `module.register` requires Node * 20.6+; the project already mandates Node >= 24. */ import { register as registerLoader } from "node:module"; -import { pathToFileURL } from "node:url"; -import * as nodePath from "node:path"; -registerLoader(pathToFileURL(nodePath.join(__dirname, "jsdom-css-loader-hook.mjs"))); +const cssLoaderHookSource = ` +export function resolve(specifier, context, nextResolve) { + if (specifier.endsWith(".css") || /\\.css(\\?|$)/.test(specifier)) { + return { + url: "data:text/javascript,export%20default%20%7B%7D%3B", + shortCircuit: true, + format: "module", + }; + } + return nextResolve(specifier, context); +} +`; +registerLoader(`data:text/javascript;charset=utf-8,${encodeURIComponent(cssLoaderHookSource)}`); type AnyFn = (...args: unknown[]) => unknown; diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 42f49bbf28e..de18fc57002 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -29,13 +29,6 @@ export default defineConfig({ // which Angular's `fakeAsync` requires. Karma+Jasmine installed this // implicitly; the @angular/build:unit-test path doesn't. setupFiles: ["src/test-zone-setup.ts"], - // CSS imports inside transitive deps (monaco-breakpoints, monaco-editor, - // @codingame/monaco-vscode-*, …) are stripped by a Node ESM loader hook - // registered at the top of `src/jsdom-svg-polyfill.ts` rather than via - // `server.deps.inline`. The `@angular/build:unit-test` builder pre-bundles - // specs with `externalPackages: true`, so transitive imports go through - // Node's native loader and bypass Vitest's inline transform — see the - // comment in that file for the full rationale. // Per-spec exclusions live in `angular.json` (the unit-test builder // applies them at the discovery stage, before Vitest's own filter, // which is what the Vitest team recommends — see the Vite warning From 8448f664e64630b5ad332c16f1222ba65a9367d5 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 15:25:11 -0700 Subject: [PATCH 12/26] chore(frontend): simplify code-editor.component.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tighten dead/redundant patches that crept in during the v10 migration: * Drop the unused `getEnhancedMonacoEnvironment` import — its only consumer lives in `codingame-worker-factory.ts` now. * Replace the 3-way `||` operator-type check with a `static readonly Set` + `.has(...)`; fold `generateLanguageTitle` into `setLanguage`. * `ngOnDestroy`: drop `isDefined(monacoBinding)` (optional chaining) and `isDefined(workflowVersionStreamSubject)` (always assigned). * `initializeMonacoEditor`: drop the redundant `switchMap(editor => of(editor ?? editorApp?.getEditor()))` — `startEditor()` already returns `editorApp.getEditor()` and `catchError` covers the timeout fallback. Remove the now-unused `switchMap` import. * `acceptCurrentAnnotation`: drop the redundant inner `if (currentRange && currentSuggestion)` — the early-return guard above already proves both fields are truthy. * `getCoeditorCursorStyles`: lift `clientId`/`color` to locals (each was repeated up to 3× in the same string). * Remove the orphaned `// NOTE: dynamic imports ...` comment from the imports block; the function it references documents the rationale. Net: -17 lines (650 -> 633). Build exits 0; tests stay at 63 / 269 parity. --- .../code-editor.component.ts | 87 ++++++++----------- 1 file changed, 35 insertions(+), 52 deletions(-) diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index dc43a94b3ab..4c2863fef7a 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -42,19 +42,12 @@ import { FormControl } from "@angular/forms"; import { AIAssistantService, TypeAnnotationResponse } from "../../service/ai-assistant/ai-assistant.service"; import { AnnotationSuggestionComponent } from "./annotation-suggestion.component"; import * as monaco from "monaco-editor"; -import { - MonacoVscodeApiWrapper, - type MonacoVscodeApiConfig, - getEnhancedMonacoEnvironment, -} from "monaco-languageclient/vscodeApiWrapper"; +import { MonacoVscodeApiWrapper, type MonacoVscodeApiConfig } from "monaco-languageclient/vscodeApiWrapper"; import { LanguageClientWrapper, type LanguageClientConfig } from "monaco-languageclient/lcwrapper"; import { EditorApp, type EditorAppConfig } from "monaco-languageclient/editorApp"; import { registerCodingameWorkers } from "./codingame-worker-factory"; -// NOTE: the @codingame/monaco-vscode-*-default-extension packages are imported -// dynamically inside `ensureVscodeApiStarted` below — see the comment there for -// why static side-effect imports get tree-shaken in this project's build pipeline. import { isDefined } from "../../../common/util/predicate"; -import { filter, switchMap } from "rxjs/operators"; +import { filter } from "rxjs/operators"; import { BreakpointConditionInputComponent } from "./breakpoint-condition-input/breakpoint-condition-input.component"; import { CodeDebuggerComponent } from "./code-debugger.component"; import { GuiConfigService } from "src/app/common/service/gui-config.service"; @@ -134,13 +127,15 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy public codeDebuggerComponent!: Type | null; public editorToPass!: MonacoEditor; - private generateLanguageTitle(language: string): string { - return `${language.charAt(0).toUpperCase()}${language.slice(1)} UDF`; - } + private static readonly PYTHON_OPERATOR_TYPES: ReadonlySet = new Set([ + "PythonUDFV2", + "PythonUDFSourceV2", + "DualInputPortsPythonUDFV2", + ]); setLanguage(newLanguage: string) { this.language = newLanguage; - this.languageTitle = this.generateLanguageTitle(newLanguage); + this.languageTitle = `${newLanguage.charAt(0).toUpperCase()}${newLanguage.slice(1)} UDF`; } constructor( @@ -153,16 +148,7 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy ) { this.currentOperatorId = this.workflowActionService.getJointGraphWrapper().getCurrentHighlightedOperatorIDs()[0]; const operatorType = this.workflowActionService.getTexeraGraph().getOperator(this.currentOperatorId).operatorType; - - if ( - operatorType === "PythonUDFV2" || - operatorType === "PythonUDFSourceV2" || - operatorType === "DualInputPortsPythonUDFV2" - ) { - this.setLanguage("python"); - } else { - this.setLanguage("java"); - } + this.setLanguage(CodeEditorComponent.PYTHON_OPERATOR_TYPES.has(operatorType) ? "python" : "java"); this.workflowActionService.getTexeraGraph().updateSharedModelAwareness("editingCode", true); this.title = this.workflowActionService.getTexeraGraph().getOperator(this.currentOperatorId).customDisplayName; this.code = ( @@ -195,19 +181,14 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy this.workflowActionService.getTexeraGraph().updateSharedModelAwareness("editingCode", false); localStorage.setItem(this.currentOperatorId, this.containerElement.nativeElement.style.cssText); - if (isDefined(this.monacoBinding)) { - this.monacoBinding.destroy(); - } - + this.monacoBinding?.destroy(); this.languageClientWrapper?.dispose().catch(() => {}); this.languageClientWrapper = undefined; this.editorApp?.dispose().catch(() => {}); this.editorApp = undefined; - if (isDefined(this.workflowVersionStreamSubject)) { - this.workflowVersionStreamSubject.next(); - this.workflowVersionStreamSubject.complete(); - } + this.workflowVersionStreamSubject.next(); + this.workflowVersionStreamSubject.complete(); } /** @@ -215,13 +196,16 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy * @param coeditor */ public getCoeditorCursorStyles(coeditor: Coeditor) { - const textCSS = - ""; - return this.sanitizer.bypassSecurityTrustHtml(textCSS); + const id = coeditor.clientId; + const color = coeditor.color; + const selectionBg = color?.replace("0.8", "0.5"); + return this.sanitizer.bypassSecurityTrustHtml( + `` + ); } private getFileSuffixByLanguage(language: string): string { @@ -340,7 +324,8 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy from(startEditor()) .pipe( timeout(LANGUAGE_SERVER_CONNECTION_TIMEOUT_MS), - switchMap(editor => of(editor ?? this.editorApp?.getEditor())), + // Language-server connection may time out (or fail) — fall back to the editor + // that was already mounted before `languageClientWrapper.start()` was awaited. catchError(() => of(this.editorApp?.getEditor())), filter(isDefined), untilDestroyed(this) @@ -586,21 +571,19 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy return; } - if (this.currentRange && this.currentSuggestion) { - const selection = new monaco.Selection( - this.currentRange.startLineNumber, - this.currentRange.startColumn, - this.currentRange.endLineNumber, - this.currentRange.endColumn - ); - - this.insertTypeAnnotations(this.editorApp!.getEditor()!, selection, this.currentSuggestion); + const selection = new monaco.Selection( + this.currentRange.startLineNumber, + this.currentRange.startColumn, + this.currentRange.endLineNumber, + this.currentRange.endColumn + ); + this.insertTypeAnnotations(this.editorApp!.getEditor()!, selection, this.currentSuggestion); - // Only for "Add All Type Annotation" - if (this.isMultipleVariables && this.userResponseSubject) { - this.userResponseSubject.next(); - } + // Only for "Add All Type Annotation" + if (this.isMultipleVariables && this.userResponseSubject) { + this.userResponseSubject.next(); } + // close the UI after adding the annotation this.showAnnotationSuggestion = false; } From be37e63e01a55f4f9d765fe5e2b0273ca6bf0780 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 15:37:10 -0700 Subject: [PATCH 13/26] chore(frontend): align code-editor.component with upstream lifecycle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comparing against the TypeFox monaco-languageclient `verify/angular` example surfaced two clean-ups: * Drop the dynamic `import("@codingame/monaco-vscode-theme-defaults-default-extension")` — that package is no longer a declared dep (removed earlier in this branch); the dynamic import only resolved by transitive luck and would silently break if any sibling package stops pulling it in. * Rewrite `ensureVscodeApiStarted` and the diff-editor `from(promise.then(...))` pipeline as plain `async`/`await`. The chained `.then().then().then()` shape was a holdover; the upstream example does the wrappers linearly. `apiWrapperStartPromise` now uses the `??=` idiom so the singleton-init is one expression instead of an `if` block. Worker-factory note: upstream uses `monacoWorkerFactory: configureDefaultWorkerFactory` which only works on Vite (it sets `getWorkerUrl`, depends on `@codingame/esbuild-import-meta-url-plugin`). Our webpack pipeline still needs `registerCodingameWorkers` to set `getWorker` directly so webpack-5 can statically bundle the worker chunks — verified the package paths it uses match upstream's `defineDefaultWorkerLoaders` verbatim. Net: -13 lines (633 -> 620). Build exits 0; tests stay at 63 / 269 parity. --- .../code-editor.component.ts | 65 ++++++++----------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index 4c2863fef7a..d7d31155c42 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -226,18 +226,16 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy * a process-wide singleton in v10; calling start() twice would throw, so we share * a single Promise across every CodeEditorComponent instance. */ - private static ensureVscodeApiStarted(): Promise { + private static async ensureVscodeApiStarted(): Promise { if (CodeEditorComponent.apiWrapperStarted) { - return Promise.resolve(); + return; } - if (!CodeEditorComponent.apiWrapperStartPromise) { + CodeEditorComponent.apiWrapperStartPromise ??= (async () => { const apiConfig: MonacoVscodeApiConfig = { $type: "extended", viewsConfig: { $type: "EditorService" }, userConfiguration: { - json: JSON.stringify({ - "workbench.colorTheme": "Default Dark Modern", - }), + json: JSON.stringify({ "workbench.colorTheme": "Default Dark Modern" }), }, // Wire up the workers monaco-vscode-api spawns at runtime (editor, // extension host, textmate). The URL refs live in a sibling file that @@ -247,31 +245,22 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy // package paths. Webpack 5 handles them correctly. monacoWorkerFactory: registerCodingameWorkers, }; - const apiWrapper = new MonacoVscodeApiWrapper(apiConfig); - // Start the vscode-api FIRST, then load AND fully activate the default - // language extensions before resolving. Each extension's module exports a - // `whenReady()` that resolves after its TextMate grammar / configuration - // files are registered with the host — without waiting for it, the editor - // opens with the language detected as Python but every token rendered as - // the default `mtk1` class (no syntax colours). - // - // Dynamic `import(...)` (rather than top-level `import "@codingame/..."`) - // is required because Angular's `@angular/build:application` pipeline - // tree-shakes bare side-effect imports out of the dev bundle. - CodeEditorComponent.apiWrapperStartPromise = apiWrapper - .start() - .then(() => - Promise.all([ - import("@codingame/monaco-vscode-python-default-extension"), - import("@codingame/monaco-vscode-java-default-extension"), - import("@codingame/monaco-vscode-theme-defaults-default-extension"), - ]) - ) - .then(extensions => Promise.all(extensions.map(ext => ext.whenReady?.()))) - .then(() => { - CodeEditorComponent.apiWrapperStarted = true; - }); - } + await new MonacoVscodeApiWrapper(apiConfig).start(); + + // Load AND fully activate the default language extensions. Each module + // exports a `whenReady()` that resolves after its TextMate grammar / + // configuration files are registered with the host — without waiting, + // the editor opens with every token rendered as the default `mtk1` + // class (no syntax colours). Dynamic `import(...)` is used so the + // Angular build pipeline doesn't tree-shake the side-effect imports. + const extensions = await Promise.all([ + import("@codingame/monaco-vscode-python-default-extension"), + import("@codingame/monaco-vscode-java-default-extension"), + ]); + await Promise.all(extensions.map(ext => ext.whenReady?.())); + + CodeEditorComponent.apiWrapperStarted = true; + })(); return CodeEditorComponent.apiWrapperStartPromise; } @@ -389,14 +378,12 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy }, }; - from( - CodeEditorComponent.ensureVscodeApiStarted().then(() => { - this.editorApp = new EditorApp(editorAppConfig); - return this.editorApp.start(this.editorElement.nativeElement); - }) - ) - .pipe(untilDestroyed(this)) - .subscribe(); + const startDiffEditor = async () => { + await CodeEditorComponent.ensureVscodeApiStarted(); + this.editorApp = new EditorApp(editorAppConfig); + await this.editorApp.start(this.editorElement.nativeElement); + }; + from(startDiffEditor()).pipe(untilDestroyed(this)).subscribe(); } private initCodeDebuggerComponent(editor: MonacoEditor) { From b13f0d49d9140d8c9f3eec78300147f1865ab7cd Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 15:44:02 -0700 Subject: [PATCH 14/26] chore(frontend): collapse codingame factory fileReplacements into existing test config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier in this branch the worker-factory swap lived on a brand-new `gui:build-test` target backed by `@angular/build:application`. That was overkill — `@angular-builders/custom-webpack:browser` already accepts `fileReplacements` in its schema, and the build target already had a `configurations.test` slot that the unit-test runner reads through `gui:build:test`. Moved the replacement entry into that existing slot, dropped the new build target, and reverted the test target's `buildTarget` back to `gui:build:test`. angular.json diff vs main shrinks from ~21 lines (new target + buildTarget rename + orphan-block removal) to +6 lines (one fileReplacements array). Build exits 0; tests stay at 63 / 269. --- frontend/angular.json | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/frontend/angular.json b/frontend/angular.json index 69746b7fd51..f7c0c3a04dc 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -64,6 +64,16 @@ "with": "src/environments/environment.prod.ts" } ] + }, + "test": { + "tsConfig": "src/tsconfig.test.json", + "main": "src/main.test.ts", + "fileReplacements": [ + { + "replace": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts", + "with": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts" + } + ] } }, "defaultConfiguration": "" @@ -80,25 +90,10 @@ } } }, - "build-test": { - "builder": "@angular/build:application", - "options": { - "outputPath": "dist", - "browser": "src/main.test.ts", - "tsConfig": "src/tsconfig.test.json", - "polyfills": ["zone.js"], - "fileReplacements": [ - { - "replace": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts", - "with": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts" - } - ] - } - }, "test": { "builder": "@angular/build:unit-test", "options": { - "buildTarget": "gui:build-test", + "buildTarget": "gui:build:test", "runner": "vitest", "runnerConfig": "vitest.config.ts", "tsConfig": "src/tsconfig.spec.json", From 26fdd30b69393338fa8c0b09c1e9e125ff3d526b Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Thu, 7 May 2026 23:37:49 -0700 Subject: [PATCH 15/26] chore(frontend): revert codingame factory to trampoline files, drop angular.json delta MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Earlier the worker URL refs were inlined as `new URL("@codingame/...", import.meta.url)` inside `codingame-worker-factory.ts`, with a `fileReplacements` swap on `gui:build:test` redirecting to a no-op stub during specs (esbuild can't resolve package-specifier URLs the way webpack does). Going back to a relative-path `new URL("./workers/X", import.meta.url)` pattern lets esbuild resolve the spec against the filesystem and webpack still treats it as a worker entry. Net diff vs main ───────────────────────────────────────────────────────────────────── angular.json 0 lines (was +6) tsconfig.app.json +4 lines (the 3 trampolines listed in `files`) src/.../workers/*.ts 3 trampoline files (one-line side-effect imports) src/.../codingame-... deleted (factory + stub) So the worker plumbing now costs +1 source file (3 trampolines vs 2 factory files) but `angular.json` becomes a no-op vs main and tests + build keep the same parity (63 / 269 specs, byte-identical worker chunks). --- frontend/angular.json | 8 +-- .../code-editor.component.ts | 39 +++++++++--- .../codingame-worker-factory.ts | 59 ------------------- .../workers/editor.worker.ts | 27 +++++++++ .../extension-host.worker.ts} | 9 +-- .../workers/textmate.worker.ts | 21 +++++++ frontend/src/tsconfig.app.json | 7 ++- 7 files changed, 88 insertions(+), 82 deletions(-) delete mode 100644 frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts rename frontend/src/app/workspace/component/code-editor-dialog/{codingame-worker-factory.stub.ts => workers/extension-host.worker.ts} (68%) create mode 100644 frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts diff --git a/frontend/angular.json b/frontend/angular.json index f7c0c3a04dc..e521d7cee9e 100644 --- a/frontend/angular.json +++ b/frontend/angular.json @@ -67,13 +67,7 @@ }, "test": { "tsConfig": "src/tsconfig.test.json", - "main": "src/main.test.ts", - "fileReplacements": [ - { - "replace": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts", - "with": "src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts" - } - ] + "main": "src/main.test.ts" } }, "defaultConfiguration": "" diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index d7d31155c42..012aaf9638b 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -42,10 +42,13 @@ import { FormControl } from "@angular/forms"; import { AIAssistantService, TypeAnnotationResponse } from "../../service/ai-assistant/ai-assistant.service"; import { AnnotationSuggestionComponent } from "./annotation-suggestion.component"; import * as monaco from "monaco-editor"; -import { MonacoVscodeApiWrapper, type MonacoVscodeApiConfig } from "monaco-languageclient/vscodeApiWrapper"; +import { + MonacoVscodeApiWrapper, + type MonacoVscodeApiConfig, + getEnhancedMonacoEnvironment, +} from "monaco-languageclient/vscodeApiWrapper"; import { LanguageClientWrapper, type LanguageClientConfig } from "monaco-languageclient/lcwrapper"; import { EditorApp, type EditorAppConfig } from "monaco-languageclient/editorApp"; -import { registerCodingameWorkers } from "./codingame-worker-factory"; import { isDefined } from "../../../common/util/predicate"; import { filter } from "rxjs/operators"; import { BreakpointConditionInputComponent } from "./breakpoint-condition-input/breakpoint-condition-input.component"; @@ -238,12 +241,32 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy json: JSON.stringify({ "workbench.colorTheme": "Default Dark Modern" }), }, // Wire up the workers monaco-vscode-api spawns at runtime (editor, - // extension host, textmate). The URL refs live in a sibling file that - // gets fileReplacements'd to a stub for the test pipeline — esbuild - // (used by @angular/build:unit-test) resolves `new URL(spec, - // import.meta.url)` literally and would otherwise fail on the codingame - // package paths. Webpack 5 handles them correctly. - monacoWorkerFactory: registerCodingameWorkers, + // extension host, textmate). Each `new Worker(new URL(...))` literal + // points at a thin trampoline in `./workers/` that just re-imports the + // codingame-shipped worker entry. Two reasons for the indirection: + // 1. webpack 5 only treats `new Worker(new URL("./relative", import.meta.url))` + // as a worker entry point (so it bundles the dep tree into a chunk); + // `new URL("@codingame/...", import.meta.url)` would just emit a + // static asset whose own relative imports 404 at runtime. + // 2. the test pipeline (esbuild via @angular/build:unit-test) resolves + // `new URL(spec, import.meta.url)` literally relative to the source + // file, so the spec needs to point at a real on-disk file. The + // trampolines satisfy both bundlers. + monacoWorkerFactory: () => { + const env = getEnhancedMonacoEnvironment(); + env.getWorker = (_workerId: string, label: string): Worker => { + switch (label) { + case "editorWorkerService": + return new Worker(new URL("./workers/editor.worker", import.meta.url), { type: "module" }); + case "extensionHostWorkerMain": + return new Worker(new URL("./workers/extension-host.worker", import.meta.url), { type: "module" }); + case "TextMateWorker": + return new Worker(new URL("./workers/textmate.worker", import.meta.url), { type: "module" }); + default: + throw new Error(`No worker configured for label: ${label}`); + } + }; + }, }; await new MonacoVscodeApiWrapper(apiConfig).start(); diff --git a/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts b/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts deleted file mode 100644 index 0d9775ee3fd..00000000000 --- a/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { getEnhancedMonacoEnvironment } from "monaco-languageclient/vscodeApiWrapper"; - -/** - * Wires `MonacoEnvironment.getWorker` to the codingame-shipped worker entries. - * - * Each `new Worker(new URL(...))` literal lets webpack 5 treat the URL as a - * worker entry point and bundle the worker's transitive deps into a dedicated - * chunk — `configureDefaultWorkerFactory` from monaco-vscode-api can't do this - * because it only emits the upstream worker.js as a static asset (which 404s - * on its first relative import at runtime). - * - * This file gets fileReplacements'd to `codingame-worker-factory.stub.ts` for - * the test pipeline. esbuild (used by @angular/build:unit-test) resolves - * `new URL(spec, import.meta.url)` literally relative to the source file and - * would otherwise fail on the codingame package paths. - */ -export function registerCodingameWorkers(): void { - const env = getEnhancedMonacoEnvironment(); - env.getWorker = (_workerId: string, label: string): Worker => { - switch (label) { - case "editorWorkerService": - return new Worker( - new URL("@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js", import.meta.url), - { type: "module" } - ); - case "extensionHostWorkerMain": - return new Worker( - new URL("@codingame/monaco-vscode-api/workers/extensionHost.worker", import.meta.url), - { type: "module" } - ); - case "TextMateWorker": - return new Worker( - new URL("@codingame/monaco-vscode-textmate-service-override/worker", import.meta.url), - { type: "module" } - ); - default: - throw new Error(`No worker configured for label: ${label}`); - } - }; -} diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts new file mode 100644 index 00000000000..35221effbc1 --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/editor.worker.ts @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Worker entry — referenced via `new Worker(new URL('./editor.worker', import.meta.url))` +// from code-editor.component.ts. The relative-path spec is what webpack 5 recognises +// as a worker entry point (so it bundles the codingame dep tree into a chunk) and +// what esbuild can resolve against the filesystem during the @angular/build:unit-test +// spec pre-bundle. Inlining a `new URL("@codingame/...", import.meta.url)` directly in +// the component would satisfy webpack but trip esbuild, which treats the spec as a +// literal relative URL. +import "@codingame/monaco-vscode-editor-api/esm/vs/editor/editor.worker.js"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts similarity index 68% rename from frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts rename to frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts index 38ba736d851..6d667025576 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/codingame-worker-factory.stub.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts @@ -17,10 +17,5 @@ * under the License. */ -// Test-time replacement for ./codingame-worker-factory.ts (see angular.json -// `gui:build-test`'s fileReplacements). The real file's `new URL("@codingame/...", -// import.meta.url)` calls fail to resolve under esbuild — this stub keeps unit -// tests buildable; tests don't instantiate the editor's Web Workers. -export function registerCodingameWorkers(): void { - // no-op -} +// See ./editor.worker.ts for why this trampoline exists. +import "@codingame/monaco-vscode-api/workers/extensionHost.worker"; diff --git a/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts b/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts new file mode 100644 index 00000000000..796224f9014 --- /dev/null +++ b/frontend/src/app/workspace/component/code-editor-dialog/workers/textmate.worker.ts @@ -0,0 +1,21 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// See ./editor.worker.ts for why this trampoline exists. +import "@codingame/monaco-vscode-textmate-service-override/worker"; diff --git a/frontend/src/tsconfig.app.json b/frontend/src/tsconfig.app.json index 6f84762b813..ada971bdcbb 100644 --- a/frontend/src/tsconfig.app.json +++ b/frontend/src/tsconfig.app.json @@ -8,6 +8,11 @@ "angularCompilerOptions": { "fullTemplateTypeCheck": true }, - "files": ["main.ts"], + "files": [ + "main.ts", + "app/workspace/component/code-editor-dialog/workers/editor.worker.ts", + "app/workspace/component/code-editor-dialog/workers/extension-host.worker.ts", + "app/workspace/component/code-editor-dialog/workers/textmate.worker.ts" + ], "include": ["**/*.d.ts"] } From 624f0462342c5949b3c2098d65fccc232f296b0a Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Sat, 9 May 2026 00:14:25 -0700 Subject: [PATCH 16/26] chore(frontend): fix prettier-eslint formatting on code-editor.component `format:ci` flagged two backtick-delimited string literals with no interpolation in `getCoeditorCursorStyles`. Switched them to double quotes so the file matches prettier-eslint's expected output and the CI gate passes. No behaviour change. --- .../component/code-editor-dialog/code-editor.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts index 012aaf9638b..2723b26c37e 100644 --- a/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts +++ b/frontend/src/app/workspace/component/code-editor-dialog/code-editor.component.ts @@ -203,11 +203,11 @@ export class CodeEditorComponent implements AfterViewInit, SafeStyle, OnDestroy const color = coeditor.color; const selectionBg = color?.replace("0.8", "0.5"); return this.sanitizer.bypassSecurityTrustHtml( - `` + "" ); } From 45fd824ce0aa3fd4e3a87593ba682f91537af3b3 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Sat, 9 May 2026 00:49:17 -0700 Subject: [PATCH 17/26] chore(frontend): drop stale LICENSE-binary entries MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI's `check_binary_deps.py` flagged seven packages claimed by `LICENSE-binary` that the production build no longer bundles. The bullets are leftover from earlier dep cleanups in this branch — `r@1.0.0` came from retiring R UDF support, `content-disposition` from dropping the dead `require` in `download.service.ts`, and the rest (`base64-js`, `buffer`, `ieee754`, `path-browserify`, `safe-buffer`) are browserify shims that became unused once the codingame v25 stack took over from v8. `check_binary_deps.py --ignore-transitive-version npm frontend/dist/3rdpartylicenses.json` now reports `OK: 113 npm packages match LICENSE-binary.` --- frontend/LICENSE-binary | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/LICENSE-binary b/frontend/LICENSE-binary index 6aa2ba86d8a..d3f7020f749 100644 --- a/frontend/LICENSE-binary +++ b/frontend/LICENSE-binary @@ -315,7 +315,6 @@ Angular / npm packages: - point-in-polygon@1.1.0 - python@1.0.0 - quill-cursors@3.1.2 - - r@1.0.0 - rbush@4.0.1 - read-excel-file@5.7.1 - ring-buffer-ts@1.0.3 From de4d47b7b284450e08ffe9348312cf8e982615a4 Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Sat, 9 May 2026 01:36:22 -0700 Subject: [PATCH 18/26] chore(frontend): trim custom-webpack.config.js to what's still load-bearing Probed each block by removing it and re-running yarn build:ci / check_binary_deps.py / yarn test. Dropped the parts that webpack 5 defaults or codingame v25 already cover, kept the parts that produce real `Module parse failed` / license-check failures when removed. Removed (verified dead via probe): * license-webpack-plugin WebpackFileSystem monkey-patch (38 lines). `handleMissingLicenseText: () => null` already absorbs the ENOENT cases. * `module.parser.javascript.url: true`. Webpack 5 enables this by default. * `resolve.alias` for `@codingame/css-loader` -> `css-loader` (13 lines). codingame v25 no longer trips the path-resolution quirk that was emitting `node_modules/@codingame/css-loader/...` import specs. * `excludedPackageTest: (name) => !name`. Subsumed by handleMissingLicenseText. Kept (verified load-bearing): * `asset/resource` rule for codingame `.svg/.ttf/.png/.woff*`. Without it webpack tries to parse the raw assets as JS and the build hits `Module parse failed: Unexpected token (1:0)` on the first .svg. * CSS `oneOf`: codingame -> css-loader with `exportType: 'css-style-sheet'`, monaco-breakpoints -> style-loader + css-loader. Dropping either branch fails the build (codingame Constructable Stylesheets / breakpoints CSS). * LicenseWebpackPlugin with custom `renderLicenses` -> bin/licensing/ check_binary_deps.py reads the resulting JSON array shape. Also pulled `path` to a top-level constant with a `nodeModule(...)` helper (was repeating `require("path").resolve(__dirname, "node_modules/...")`) and rewrote `renderLicenses` with optional chaining + a simpler sort. Net: 154 -> 84 lines (-69). yarn build:ci EXIT 0 with byte-identical worker chunks; check_binary_deps.py reports `OK: 113 npm packages match LICENSE-binary`; yarn test stays at 63 / 269 parity. --- frontend/custom-webpack.config.js | 107 ++++++------------------------ 1 file changed, 19 insertions(+), 88 deletions(-) diff --git a/frontend/custom-webpack.config.js b/frontend/custom-webpack.config.js index f6d9001dcf1..2fbe964e4ce 100644 --- a/frontend/custom-webpack.config.js +++ b/frontend/custom-webpack.config.js @@ -17,134 +17,65 @@ * under the License. */ +const path = require("path"); const { LicenseWebpackPlugin } = require("license-webpack-plugin"); -// Workaround for license-webpack-plugin v4 crashing with `ENOENT: scandir ''` when a -// bundled module has no resolvable on-disk directory. Some @codingame/monaco-vscode-* -// sub-modules surface as virtual entries (descriptionFileRoot === '') after the v25 -// upgrade. Make listPaths/readFileAsUtf8/isDirectory tolerant of empty paths. -{ - const fs = require("fs"); - const wfs = require("license-webpack-plugin/dist/WebpackFileSystem").WebpackFileSystem; - const origListPaths = wfs.prototype.listPaths; - wfs.prototype.listPaths = function (path) { - if (!path) return []; - try { - return origListPaths.call(this, path); - } catch (e) { - if (e && e.code === "ENOENT") return []; - throw e; - } - }; - const origIsDirectory = wfs.prototype.isDirectory; - wfs.prototype.isDirectory = function (path) { - if (!path) return false; - try { - return origIsDirectory.call(this, path); - } catch (e) { - if (e && e.code === "ENOENT") return false; - throw e; - } - }; - const origReadFileAsUtf8 = wfs.prototype.readFileAsUtf8; - wfs.prototype.readFileAsUtf8 = function (path) { - if (!path) return ""; - try { - return origReadFileAsUtf8.call(this, path); - } catch (e) { - if (e && e.code === "ENOENT") return ""; - throw e; - } - }; -} - -// Match CSS files shipped by codingame's monaco-vscode-* family (and the editor-api -// alias of monaco-editor / vscode that points at them). These ship as Constructable -// Stylesheet imports — they must skip style-loader and use css-loader's -// `exportType: 'css-style-sheet'` mode. See the codingame troubleshooting wiki: -// https://github.com/CodinGame/monaco-vscode-api/wiki/Troubleshooting +const nodeModule = (...segments) => path.resolve(__dirname, "node_modules", ...segments); const codingameCssRe = /node_modules[\\/](?:@codingame[\\/]monaco-vscode-[^\\/]+|monaco-editor|vscode)[\\/].*\.css$/; module.exports = { module: { rules: [ { - // The codingame monaco-vscode-* family ships raw assets (.svg/.ttf/.png/.woff*) - // that webpack must emit as static files rather than parse as JS. + // codingame monaco-vscode-* ships raw assets (svg/ttf/png/woff*) that + // webpack must emit as static files rather than try to parse as JS. test: /\.(svg|ttf|woff2?|png|jpg|jpeg|gif)$/, - include: [require("path").resolve(__dirname, "node_modules/@codingame")], + include: [nodeModule("@codingame")], type: "asset/resource", }, { test: /\.css$/, oneOf: [ { + // codingame monaco-vscode-* CSS ships as Constructable Stylesheet + // imports — must skip style-loader and use css-loader's + // `exportType: 'css-style-sheet'`. + // https://github.com/CodinGame/monaco-vscode-api/wiki/Troubleshooting test: codingameCssRe, use: [ { loader: "css-loader", - options: { - esModule: false, - exportType: "css-style-sheet", - url: true, - import: true, - }, + options: { esModule: false, exportType: "css-style-sheet", url: true, import: true }, }, ], }, { + // monaco-breakpoints ships a plain stylesheet that needs + // style-loader so it injects at runtime. + include: [nodeModule("monaco-breakpoints")], use: ["style-loader", "css-loader"], - include: [ - require("path").resolve(__dirname, "node_modules/monaco-breakpoints"), - ], }, ], }, ], - // Enable URL handling in webpack's JavaScript parser, required for loading .wasm files. - // See https://github.com/angular/angular-cli/issues/24617 - parser: { - javascript: { - url: true, - }, - }, - }, - resolve: { - // css-loader emits relative imports (e.g. '../../../../../../../css-loader/dist/runtime/api.js') - // computed from the source CSS location. The codingame monaco-vscode-* packages live one - // namespace level deeper (`node_modules/@codingame/...`) than css-loader assumes, so the - // emitted path lands at `node_modules/@codingame/css-loader/...` instead of - // `node_modules/css-loader/...`. Alias the missing leg back to the real install. - alias: { - [require("path").resolve(__dirname, "node_modules/@codingame/css-loader")]: - require("path").resolve(__dirname, "node_modules/css-loader"), - [require("path").resolve(__dirname, "node_modules/@codingame/style-loader")]: - require("path").resolve(__dirname, "node_modules/style-loader"), - }, }, plugins: [ new LicenseWebpackPlugin({ perChunkOutput: false, outputFilename: "3rdpartylicenses.json", - // Skip packages whose resolved directory is missing or unreadable. The codingame - // monaco-vscode-* family ships sub-modules whose package roots license-webpack-plugin - // can't always locate, and a missing license file shouldn't fail the build. + // Some codingame monaco-vscode-* sub-modules don't expose a license file + // license-webpack-plugin can find; treat that as soft instead of fatal. handleMissingLicenseText: () => null, - excludedPackageTest: (name) => !name, renderLicenses: (modules) => JSON.stringify( modules + .filter((m) => m.packageJson?.name && m.packageJson?.version) .map((m) => ({ - name: m.packageJson && m.packageJson.name, - version: m.packageJson && m.packageJson.version, + name: m.packageJson.name, + version: m.packageJson.version, license: m.licenseId, })) - .filter((e) => e.name && e.version) - .sort((a, b) => - a.name === b.name - ? a.version.localeCompare(b.version) - : a.name.localeCompare(b.name), - ), + .sort((a, b) => a.name.localeCompare(b.name) || a.version.localeCompare(b.version)), null, 2, ), From 51b4fe55461ee41b3854b7191b7e6c86d0425c0f Mon Sep 17 00:00:00 2001 From: Xinyuan Lin Date: Sat, 9 May 2026 01:49:22 -0700 Subject: [PATCH 19/26] chore(frontend): address Copilot review on code-editor.component MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three Copilot review comments on #4997 — all valid, addressed in this commit. (A fourth comment about an unused `const fs = require("fs")` in custom-webpack.config.js was already resolved by de4d47b7b2 when the license-webpack-plugin patch block was deleted as dead code.) * Timeout scope: previously `LANGUAGE_SERVER_CONNECTION_TIMEOUT_MS` wrapped the entire `startEditor()` promise, including `ensureVscodeApiStarted()` and `EditorApp.start()`. On first load codingame v25 init can easily exceed 1s, so the timeout could fire before the editor mount completes and the rxjs `catchError` fallback would emit `undefined` (filtered out → MonacoBinding/actions/debugger never attach). Pulled the timeout out of the rxjs pipeline and into a `Promise.race` around `languageClientWrapper.start()` only; the editor mount is now always awaited to completion. Drops the unused `timeout` / `catchError` / `of` rxjs imports. * Sticky rejection cache: `apiWrapperStartPromise` is shared across every CodeEditorComponent instance. If wrapper / extension activation ever rejected, the rejected promise would be returned forever and no subsequent open could retry. Wrapped the IIFE body in try/catch and reset the cache before re-throwing. * Awareness-driven CSS injection: `getCoeditorCursorStyles` interpolates `coeditor.clientId` and `coeditor.color` (both writeable by any peer via yjs awareness) into a `