From 27e4c54db4ed956b3037281224b5acea803617b2 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 23 Oct 2026 08:17:14 +0000 Subject: [PATCH 1/3] refactor(@angular-devkit/core): simplify Set operations with ES2025 Set methods --- .../core/src/json/schema/utility.ts | 12 +++++----- .../core/src/utils/partially-ordered-set.ts | 24 +++---------------- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/packages/angular_devkit/core/src/json/schema/utility.ts b/packages/angular_devkit/core/src/json/schema/utility.ts index e23f5fad9cbe..8451aa2bee06 100644 --- a/packages/angular_devkit/core/src/json/schema/utility.ts +++ b/packages/angular_devkit/core/src/json/schema/utility.ts @@ -53,13 +53,13 @@ export function getTypesOfSchema(schema: JsonSchema): Set { if (isJsonObject(schema.not)) { const notTypes = getTypesOfSchema(schema.not); - potentials = new Set([...potentials].filter((p) => !notTypes.has(p))); + potentials = potentials.difference(notTypes); } if (Array.isArray(schema.allOf)) { for (const sub of schema.allOf) { const types = getTypesOfSchema(sub as JsonObject); - potentials = new Set([...types].filter((t) => potentials.has(t))); + potentials = potentials.intersection(types); } } @@ -67,18 +67,18 @@ export function getTypesOfSchema(schema: JsonSchema): Set { let options = new Set(); for (const sub of schema.oneOf) { const types = getTypesOfSchema(sub as JsonObject); - options = new Set([...options, ...types]); + options = options.union(types); } - potentials = new Set([...options].filter((o) => potentials.has(o))); + potentials = potentials.intersection(options); } if (Array.isArray(schema.anyOf)) { let options = new Set(); for (const sub of schema.anyOf) { const types = getTypesOfSchema(sub as JsonObject); - options = new Set([...options, ...types]); + options = options.union(types); } - potentials = new Set([...options].filter((o) => potentials.has(o))); + potentials = potentials.intersection(options); } if (schema.properties) { diff --git a/packages/angular_devkit/core/src/utils/partially-ordered-set.ts b/packages/angular_devkit/core/src/utils/partially-ordered-set.ts index 21e3fb5c5410..258b6138f66f 100644 --- a/packages/angular_devkit/core/src/utils/partially-ordered-set.ts +++ b/packages/angular_devkit/core/src/utils/partially-ordered-set.ts @@ -84,23 +84,7 @@ export class PartiallyOrderedSet { const itemDeps = this._items.get(item) || new Set(); // If the dependency list is equal, just return, otherwise remove and keep going. - let equal = true; - for (const dep of deps) { - if (!itemDeps.has(dep)) { - equal = false; - break; - } - } - if (equal) { - for (const dep of itemDeps) { - if (!deps.has(dep)) { - equal = false; - break; - } - } - } - - if (equal) { + if (deps.size === itemDeps.size && deps.isSubsetOf(itemDeps)) { return this; } else { this._items.delete(item); @@ -108,10 +92,8 @@ export class PartiallyOrderedSet { } // Verify all dependencies are part of the Set. - for (const dep of deps) { - if (!this._items.has(dep)) { - throw new DependencyNotFoundException(); - } + if (!deps.isSubsetOf(this._items)) { + throw new DependencyNotFoundException(); } // Verify there's no dependency cycle. From bc5c0669d85d5dc33c983dc6fb4fc52270770cc2 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 23 Oct 2026 08:17:20 +0000 Subject: [PATCH 2/3] refactor(@angular/build): simplify Set operations with ES2025 Set methods --- .../src/builders/library/builder-state.ts | 28 +++++-------------- .../builders/library/pipeline/entry-points.ts | 28 ++----------------- .../build/src/tools/sass/rebasing-importer.ts | 4 +-- 3 files changed, 11 insertions(+), 49 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder-state.ts b/packages/angular/build/src/builders/library/builder-state.ts index 9057ef41b815..5f55f5b2b915 100644 --- a/packages/angular/build/src/builders/library/builder-state.ts +++ b/packages/angular/build/src/builders/library/builder-state.ts @@ -256,10 +256,8 @@ export class BuilderState { return true; } - for (const file of this.#pendingCompilationFiles) { - if (this.#watchedCompilationFiles.has(file)) { - return true; - } + if (!this.#pendingCompilationFiles.isDisjointFrom(this.#watchedCompilationFiles)) { + return true; } this.#pendingCompilationFiles.clear(); @@ -281,12 +279,7 @@ export class BuilderState { return undefined; } - const files = new Set(modifiedFiles); - for (const file of this.#pendingCompilationFiles) { - files.add(file); - } - - return files; + return modifiedFiles.union(this.#pendingCompilationFiles); } /** @@ -380,7 +373,7 @@ export class BuilderState { collectedAssets: CollectedAssets, manifestFiles?: readonly OutputFile[], ): ReadonlySet { - const filesToDelete = new Set(); + let filesToDelete = new Set(); if (this.#hasUpdatedBundles) { this.#hasUpdatedBundles = false; @@ -394,21 +387,14 @@ export class BuilderState { } } - for (const prevFile of this.#emittedBundleFiles) { - if (!nextBundleFiles.has(prevFile)) { - filesToDelete.add(prevFile); - } - } - + filesToDelete = this.#emittedBundleFiles.difference(nextBundleFiles); this.#emittedBundleFiles = nextBundleFiles; } if (manifestFiles) { const nextManifestFiles = new Set(manifestFiles.map((file) => file.path)); - for (const prevFile of this.#emittedManifestFiles) { - if (!nextManifestFiles.has(prevFile)) { - filesToDelete.add(prevFile); - } + for (const prevFile of this.#emittedManifestFiles.difference(nextManifestFiles)) { + filesToDelete.add(prevFile); } this.#emittedManifestFiles = nextManifestFiles; diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points.ts b/packages/angular/build/src/builders/library/pipeline/entry-points.ts index f932fb992fc6..8e4bda376326 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points.ts @@ -308,10 +308,10 @@ export function collectEntryPointsToBundle( const previousBundleResult = previousBundleResults.get(entryPoint.name); const hasEsmChanges = !previousBundleResult || - hasEntryPointChanges(previousBundleResult.esmModuleIds, pendingChangedEsmFiles); + !previousBundleResult.esmModuleIds.isDisjointFrom(pendingChangedEsmFiles); const hasDtsChanges = !previousBundleResult || - hasEntryPointChanges(previousBundleResult.dtsModuleIds, pendingChangedDtsFiles); + !previousBundleResult.dtsModuleIds.isDisjointFrom(pendingChangedDtsFiles); if (hasEsmChanges || hasDtsChanges) { executionResult.addLog(`Compiling ${entryPoint.displayName}...`); @@ -326,27 +326,3 @@ export function collectEntryPointsToBundle( return itemsToBundle; } - -/** - * Checks whether any file in `changedFiles` belongs to the given entry point's `moduleIds`. - * - * @param moduleIds Set of virtual POSIX module IDs referenced by the entry point's previous bundle. - * @param changedFiles Set of POSIX file paths that changed during compilation. - * @returns `true` if at least one changed file is part of `moduleIds`; otherwise `false`. - */ -function hasEntryPointChanges( - moduleIds: ReadonlySet, - changedFiles: ReadonlySet, -): boolean { - if (changedFiles.size === 0) { - return false; - } - - for (const file of changedFiles) { - if (moduleIds.has(file)) { - return true; - } - } - - return false; -} diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index 889d26ef567e..ccc5fa3c4664 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -209,8 +209,8 @@ export class RelativeUrlRebasingImporter extends UrlRebasingImporter { // If there is a preprocessed cache of the directory, perform an intersection of the potentials // and the directory files. const { files, directories } = cachedEntries; - foundDefaults = [...defaultPotentials].filter((potential) => files.has(potential)); - foundImports = [...importPotentials].filter((potential) => files.has(potential)); + foundDefaults = [...defaultPotentials.intersection(files)]; + foundImports = [...importPotentials.intersection(files)]; hasPotentialIndex = checkDirectory && !hasStyleExtension && directories.has(filename); } else { // If no preprocessed cache exists, get the entries from the file system and, while searching, From 81f4a334849d2ccc57700086b49c93da8de04b21 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 23 Oct 2026 15:36:43 +0000 Subject: [PATCH 3/3] fixup! refactor(@angular-devkit/core): simplify Set operations with ES2025 Set methods --- packages/angular_devkit/core/src/json/schema/utility.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/angular_devkit/core/src/json/schema/utility.ts b/packages/angular_devkit/core/src/json/schema/utility.ts index 8451aa2bee06..83bc336e0952 100644 --- a/packages/angular_devkit/core/src/json/schema/utility.ts +++ b/packages/angular_devkit/core/src/json/schema/utility.ts @@ -59,7 +59,7 @@ export function getTypesOfSchema(schema: JsonSchema): Set { if (Array.isArray(schema.allOf)) { for (const sub of schema.allOf) { const types = getTypesOfSchema(sub as JsonObject); - potentials = potentials.intersection(types); + potentials = new Set([...types].filter((t) => potentials.has(t))); } } @@ -69,7 +69,7 @@ export function getTypesOfSchema(schema: JsonSchema): Set { const types = getTypesOfSchema(sub as JsonObject); options = options.union(types); } - potentials = potentials.intersection(options); + potentials = new Set([...options].filter((o) => potentials.has(o))); } if (Array.isArray(schema.anyOf)) { @@ -78,7 +78,7 @@ export function getTypesOfSchema(schema: JsonSchema): Set { const types = getTypesOfSchema(sub as JsonObject); options = options.union(types); } - potentials = potentials.intersection(options); + potentials = new Set([...options].filter((o) => potentials.has(o))); } if (schema.properties) {