diff --git a/build/npm/postinstall.ts b/build/npm/postinstall.ts index db659fa78a423..9b7d0a7cf94d3 100644 --- a/build/npm/postinstall.ts +++ b/build/npm/postinstall.ts @@ -259,6 +259,7 @@ async function main() { if (process.env['CXX']) { env['CXX'] = 'g++'; } if (process.env['CXXFLAGS']) { env['CXXFLAGS'] = ''; } if (process.env['LDFLAGS']) { env['LDFLAGS'] = ''; } + env['npm_config_jobs'] = 'max'; setNpmrcConfig('build', env); return npmInstallAsync('build', { env }); }); @@ -285,6 +286,34 @@ async function main() { if (process.env['VSCODE_REMOTE_CXXFLAGS']) { env['CXXFLAGS'] = process.env['VSCODE_REMOTE_CXXFLAGS']; } if (process.env['VSCODE_REMOTE_LDFLAGS']) { env['LDFLAGS'] = process.env['VSCODE_REMOTE_LDFLAGS']; } if (process.env['VSCODE_REMOTE_NODE_GYP']) { env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; } + env['npm_config_jobs'] = 'max'; + setNpmrcConfig('remote', env); + return npmInstallAsync(remoteDir, { env }); + }); + continue; + } + + if (/^(.build\/distro\/npm\/)?remote$/.test(dir)) { + const remoteDir = dir; + nativeTasks.push(() => { + const env: NodeJS.ProcessEnv = { ...process.env }; + if (process.env['VSCODE_REMOTE_CC']) { + env['CC'] = process.env['VSCODE_REMOTE_CC']; + } else { + delete env['CC']; + } + if (process.env['VSCODE_REMOTE_CXX']) { + env['CXX'] = process.env['VSCODE_REMOTE_CXX']; + } else { + delete env['CXX']; + } + if (process.env['CXXFLAGS']) { delete env['CXXFLAGS']; } + if (process.env['CFLAGS']) { delete env['CFLAGS']; } + if (process.env['LDFLAGS']) { delete env['LDFLAGS']; } + if (process.env['VSCODE_REMOTE_CXXFLAGS']) { env['CXXFLAGS'] = process.env['VSCODE_REMOTE_CXXFLAGS']; } + if (process.env['VSCODE_REMOTE_LDFLAGS']) { env['LDFLAGS'] = process.env['VSCODE_REMOTE_LDFLAGS']; } + if (process.env['VSCODE_REMOTE_NODE_GYP']) { env['npm_config_node_gyp'] = process.env['VSCODE_REMOTE_NODE_GYP']; } + env['npm_config_jobs'] = 'max'; setNpmrcConfig('remote', env); return npmInstallAsync(remoteDir, { env }); }); diff --git a/build/rspack/rspack.serve-out.config.mts b/build/rspack/rspack.serve-out.config.mts index 8e5c1ec41a98b..1016e1d6b6c78 100644 --- a/build/rspack/rspack.serve-out.config.mts +++ b/build/rspack/rspack.serve-out.config.mts @@ -34,7 +34,7 @@ export default { output: { path: path.join(repoRoot, '.build', 'rspack-serve-out'), filename: 'bundled/[name].js', - chunkFilename: 'bundled/[name].js', + chunkFilename: 'bundled/[name].[contenthash].js', assetModuleFilename: 'bundled/assets/[name][ext][query]', publicPath: '/', clean: true, @@ -42,6 +42,26 @@ export default { experiments: { css: true, }, + optimization: { + moduleIds: 'deterministic', + splitChunks: { + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name: 'vendors', + chunks: 'all', + priority: 10, + }, + common: { + name: 'common', + minChunks: 2, + chunks: 'all', + priority: 5, + reuseExistingChunk: true, + }, + }, + }, + }, module: { rules: [ { diff --git a/build/vite/vite.config.ts b/build/vite/vite.config.ts index 24aaa12c02655..ca601d0311566 100644 --- a/build/vite/vite.config.ts +++ b/build/vite/vite.config.ts @@ -185,22 +185,31 @@ export default defineConfig({ } } }, - root: '../..', // To support /out/... paths + root: '../..', build: { outDir: join(__dirname, 'dist'), + minify: 'esbuild', + sourcemap: true, rollupOptions: { input: { - //index: path.resolve(__dirname, 'index.html'), workbench: path.resolve(__dirname, 'workbench-vite.html'), - } - } + }, + output: { + manualChunks: { + vendor: ['vscode-textmate', 'vscode-oniguruma', 'katex'], + xterm: ['@xterm/xterm', '@xterm/addon-clipboard', '@xterm/addon-search'], + }, + }, + }, + commonjsOptions: { + include: [/node_modules/], + }, }, server: { cors: true, port: 5199, fs: { allow: [ - // To allow loading from sources, not needed when loading monaco-editor from npm package join(import.meta.dirname, '../../../') ] } diff --git a/package.json b/package.json index 2c720a8553ab7..5e9def3d1ff42 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "watch-copilotd": "deemon npm run watch-copilot", "kill-watch-copilotd": "deemon --kill npm run watch-copilot", "precommit": "node --experimental-strip-types build/hygiene.ts", - "gulp": "node --max-old-space-size=8192 ./node_modules/gulp/bin/gulp.js", + "gulp": "node --max-old-space-size=16384 ./node_modules/gulp/bin/gulp.js", "electron": "node build/lib/electron.ts", "7z": "7z", "update-grammars": "node build/npm/update-all-grammars.ts", diff --git a/src/tsconfig.base.json b/src/tsconfig.base.json index b1c66907abf97..6fde2e95aa9d3 100644 --- a/src/tsconfig.base.json +++ b/src/tsconfig.base.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "incremental": true, "module": "nodenext", "moduleResolution": "nodenext", "moduleDetection": "legacy", diff --git a/src/tsconfig.json b/src/tsconfig.json index bfda0ebafc1e5..9909a1b3c9b9c 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "./tsconfig.base.json", "compilerOptions": { + "incremental": true, + "tsBuildInfoFile": "../out/tsconfig.tsbuildinfo", "esModuleInterop": true, "removeComments": false, "preserveConstEnums": true, diff --git a/src/vs/workbench/api/common/extHostChatContext.ts b/src/vs/workbench/api/common/extHostChatContext.ts index 74a9fab7e5f4c..c737b6bac5600 100644 --- a/src/vs/workbench/api/common/extHostChatContext.ts +++ b/src/vs/workbench/api/common/extHostChatContext.ts @@ -32,6 +32,10 @@ export class ExtHostChatContext extends Disposable implements ExtHostChatContext private _globalItems: Map = new Map(); /** Track which items belong to which provider for cleanup */ private _providerItems: Map> = new Map(); // providerHandle -> Set + /** Track insertion order for LRU eviction */ + private _itemInsertionOrder: number[] = []; + /** Maximum number of global items to prevent unbounded growth */ + private static readonly MAX_GLOBAL_ITEMS = 10000; constructor( @IExtHostRpcService extHostRpc: IExtHostRpcService, @@ -252,6 +256,10 @@ export class ExtHostChatContext extends Disposable implements ExtHostChatContext if (itemHandles) { for (const itemHandle of itemHandles) { this._globalItems.delete(itemHandle); + const idx = this._itemInsertionOrder.indexOf(itemHandle); + if (idx !== -1) { + this._itemInsertionOrder.splice(idx, 1); + } } itemHandles.clear(); } @@ -259,7 +267,9 @@ export class ExtHostChatContext extends Disposable implements ExtHostChatContext private _addTrackedItem(providerHandle: number, item: vscode.ChatContextItem): number { const itemHandle = this._itemPool++; + this._evictOldestIfNecessary(); this._globalItems.set(itemHandle, item); + this._itemInsertionOrder.push(itemHandle); if (!this._providerItems.has(providerHandle)) { this._providerItems.set(providerHandle, new Set()); } @@ -267,6 +277,17 @@ export class ExtHostChatContext extends Disposable implements ExtHostChatContext return itemHandle; } + private _evictOldestIfNecessary(): void { + if (this._globalItems.size < ExtHostChatContext.MAX_GLOBAL_ITEMS) { + return; + } + const itemsToEvict = Math.ceil(ExtHostChatContext.MAX_GLOBAL_ITEMS * 0.1); + for (let i = 0; i < itemsToEvict && this._itemInsertionOrder.length > 0; i++) { + const oldestHandle = this._itemInsertionOrder.shift()!; + this._globalItems.delete(oldestHandle); + } + } + private _convertItems(handle: number, items: vscode.ChatContextItem[]): IChatContextItem[] { const result: IChatContextItem[] = []; for (const item of items) { @@ -330,5 +351,8 @@ export class ExtHostChatContext extends Disposable implements ExtHostChatContext for (const { disposables } of this._providers.values()) { disposables.dispose(); } + this._globalItems.clear(); + this._itemInsertionOrder = []; + this._providerItems.clear(); } } diff --git a/src/vs/workbench/api/common/extHostTerminalService.ts b/src/vs/workbench/api/common/extHostTerminalService.ts index a526f4df3231d..693d9a9b3b351 100644 --- a/src/vs/workbench/api/common/extHostTerminalService.ts +++ b/src/vs/workbench/api/common/extHostTerminalService.ts @@ -978,6 +978,15 @@ export abstract class BaseExtHostTerminalService extends Disposable implements I processDiposable.dispose(); delete this._terminalProcessDisposables[id]; } + + // Clean up terminal link cache and cancellation sources + this._terminalLinkCache.delete(id); + const cancellationSource = this._terminalLinkCancellationSource.get(id); + if (cancellationSource) { + cancellationSource.dispose(true); + this._terminalLinkCancellationSource.delete(id); + } + // Send exit event to main side this._proxy.$sendProcessExit(id, exitCode); } diff --git a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts index a63b68b7d3810..c036f41f93d25 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -433,7 +433,7 @@ class CellInfoContentProvider { static readonly ID = 'workbench.contrib.cellInfoContentProvider'; - private readonly _disposables: IDisposable[] = []; + private readonly _disposables = this._register(new DisposableStore()); constructor( @ITextModelService textModelService: ITextModelService, @@ -442,15 +442,15 @@ class CellInfoContentProvider { @ILabelService private readonly _labelService: ILabelService, @INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService, ) { - this._disposables.push(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookCellMetadata, { + this._disposables.add(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookCellMetadata, { provideTextContent: this.provideMetadataTextContent.bind(this) })); - this._disposables.push(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookCellOutput, { + this._disposables.add(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookCellOutput, { provideTextContent: this.provideOutputTextContent.bind(this) })); - this._disposables.push(this._labelService.registerFormatter({ + this._disposables.add(this._labelService.registerFormatter({ scheme: Schemas.vscodeNotebookCellMetadata, formatting: { label: '${path} (metadata)', @@ -458,7 +458,7 @@ class CellInfoContentProvider { } })); - this._disposables.push(this._labelService.registerFormatter({ + this._disposables.add(this._labelService.registerFormatter({ scheme: Schemas.vscodeNotebookCellOutput, formatting: { label: '${path} (output)', @@ -467,10 +467,6 @@ class CellInfoContentProvider { })); } - dispose(): void { - dispose(this._disposables); - } - async provideMetadataTextContent(resource: URI): Promise { const existing = this._modelService.getModel(resource); if (existing) { @@ -654,7 +650,7 @@ class CellInfoContentProvider { class NotebookMetadataContentProvider { static readonly ID = 'workbench.contrib.notebookMetadataContentProvider'; - private readonly _disposables: IDisposable[] = []; + private readonly _disposables = this._register(new DisposableStore()); constructor( @ITextModelService textModelService: ITextModelService, @@ -663,11 +659,11 @@ class NotebookMetadataContentProvider { @ILabelService private readonly _labelService: ILabelService, @INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService, ) { - this._disposables.push(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookMetadata, { + this._disposables.add(textModelService.registerTextModelContentProvider(Schemas.vscodeNotebookMetadata, { provideTextContent: this.provideMetadataTextContent.bind(this) })); - this._disposables.push(this._labelService.registerFormatter({ + this._disposables.add(this._labelService.registerFormatter({ scheme: Schemas.vscodeNotebookMetadata, formatting: { label: '${path} (metadata)', @@ -676,10 +672,6 @@ class NotebookMetadataContentProvider { })); } - dispose(): void { - dispose(this._disposables); - } - async provideMetadataTextContent(resource: URI): Promise { const existing = this._modelService.getModel(resource); if (existing) { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts b/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts index fbd8325319e16..eae8c09210589 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalGroup.ts @@ -327,6 +327,10 @@ export class TerminalGroup extends Disposable implements ITerminalGroup { override dispose(): void { this._terminalInstances = []; this._onInstancesChanged.fire(); + for (const disposables of this._instanceDisposables.values()) { + dispose(disposables); + } + this._instanceDisposables.clear(); this._splitPaneContainer?.dispose(); super.dispose(); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 5eaceee04d043..8dadaf822fa26 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -231,6 +231,14 @@ export class TerminalService extends Disposable implements ITerminalService { timeout(0).then(() => this._register(this._instantiationService.createInstance(TerminalEditorStyle, mainWindow.document.head))); } + override dispose(): void { + for (const disposables of this._backgroundedTerminalDisposables.values()) { + dispose(disposables); + } + this._backgroundedTerminalDisposables.clear(); + super.dispose(); + } + async showProfileQuickPick(type: 'setDefault' | 'createInstance', cwd?: string | URI): Promise { const quickPick = this._instantiationService.createInstance(TerminalProfileQuickpick); const result = await quickPick.showAndGetResult(type);