@nestjs/core 11.0.8 → 11.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,8 @@
1
+ import { Module } from '../module';
2
+ export declare class TopologyTree {
3
+ private root;
4
+ private links;
5
+ constructor(moduleRef: Module);
6
+ walk(callback: (value: Module, depth: number) => void): void;
7
+ private traverseAndMapToTree;
8
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TopologyTree = void 0;
4
+ const tree_node_1 = require("./tree-node");
5
+ class TopologyTree {
6
+ constructor(moduleRef) {
7
+ this.links = new Map();
8
+ this.root = new tree_node_1.TreeNode({
9
+ value: moduleRef,
10
+ parent: null,
11
+ });
12
+ this.links.set(moduleRef, this.root);
13
+ this.traverseAndMapToTree(this.root);
14
+ }
15
+ walk(callback) {
16
+ function walkNode(node, depth = 1) {
17
+ callback(node.value, depth);
18
+ node.children.forEach(child => walkNode(child, depth + 1));
19
+ }
20
+ walkNode(this.root);
21
+ }
22
+ traverseAndMapToTree(node, depth = 1) {
23
+ if (!node.value.imports) {
24
+ return;
25
+ }
26
+ node.value.imports.forEach(child => {
27
+ if (!child) {
28
+ return;
29
+ }
30
+ if (this.links.has(child)) {
31
+ const existingSubtree = this.links.get(child);
32
+ if (node.hasCycleWith(child)) {
33
+ return;
34
+ }
35
+ const existingDepth = existingSubtree.getDepth();
36
+ if (existingDepth < depth) {
37
+ existingSubtree.relink(node);
38
+ }
39
+ return;
40
+ }
41
+ const childNode = new tree_node_1.TreeNode({
42
+ value: child,
43
+ parent: node,
44
+ });
45
+ node.addChild(childNode);
46
+ this.links.set(child, childNode);
47
+ this.traverseAndMapToTree(childNode, depth + 1);
48
+ });
49
+ }
50
+ }
51
+ exports.TopologyTree = TopologyTree;
@@ -0,0 +1,14 @@
1
+ export declare class TreeNode<T> {
2
+ readonly value: T;
3
+ readonly children: Set<TreeNode<T>>;
4
+ private parent;
5
+ constructor({ value, parent }: {
6
+ value: T;
7
+ parent: TreeNode<T> | null;
8
+ });
9
+ addChild(child: TreeNode<T>): void;
10
+ removeChild(child: TreeNode<T>): void;
11
+ relink(parent: TreeNode<T>): void;
12
+ getDepth(): number;
13
+ hasCycleWith(target: T): boolean;
14
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TreeNode = void 0;
4
+ class TreeNode {
5
+ constructor({ value, parent }) {
6
+ this.children = new Set();
7
+ this.value = value;
8
+ this.parent = parent;
9
+ }
10
+ addChild(child) {
11
+ this.children.add(child);
12
+ }
13
+ removeChild(child) {
14
+ this.children.delete(child);
15
+ }
16
+ relink(parent) {
17
+ this.parent?.removeChild(this);
18
+ this.parent = parent;
19
+ this.parent.addChild(this);
20
+ }
21
+ getDepth() {
22
+ const visited = new Set();
23
+ let depth = 0;
24
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
25
+ let current = this;
26
+ while (current) {
27
+ depth++;
28
+ current = current.parent;
29
+ // Stop on cycle
30
+ if (visited.has(current)) {
31
+ return -1;
32
+ }
33
+ visited.add(current);
34
+ }
35
+ return depth;
36
+ }
37
+ hasCycleWith(target) {
38
+ const visited = new Set();
39
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
40
+ let current = this;
41
+ while (current) {
42
+ if (current.value === target) {
43
+ return true;
44
+ }
45
+ current = current.parent;
46
+ if (visited.has(current)) {
47
+ return false;
48
+ }
49
+ visited.add(current);
50
+ }
51
+ return false;
52
+ }
53
+ }
54
+ exports.TreeNode = TreeNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nestjs/core",
3
- "version": "11.0.8",
3
+ "version": "11.0.10",
4
4
  "description": "Nest - modern, fast, powerful node.js web framework (@core)",
5
5
  "author": "Kamil Mysliwiec",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "uid": "2.0.2"
40
40
  },
41
41
  "devDependencies": {
42
- "@nestjs/common": "11.0.8"
42
+ "@nestjs/common": "11.0.10"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@nestjs/common": "^11.0.0",
package/scanner.js CHANGED
@@ -13,6 +13,7 @@ const invalid_module_exception_1 = require("./errors/exceptions/invalid-module.e
13
13
  const undefined_module_exception_1 = require("./errors/exceptions/undefined-module.exception");
14
14
  const get_class_scope_1 = require("./helpers/get-class-scope");
15
15
  const internal_core_module_factory_1 = require("./injector/internal-core-module/internal-core-module-factory");
16
+ const topology_tree_1 = require("./injector/topology-tree/topology-tree");
16
17
  const uuid_factory_1 = require("./inspector/uuid-factory");
17
18
  class DependenciesScanner {
18
19
  constructor(container, metadataScanner, graphInspector, applicationConfig = new application_config_1.ApplicationConfig()) {
@@ -199,27 +200,21 @@ class DependenciesScanner {
199
200
  }
200
201
  calculateModulesDistance() {
201
202
  const modulesGenerator = this.container.getModules().values();
202
- // Skip "InternalCoreModule" from calculating distance
203
+ // Skip "InternalCoreModule"
204
+ // The second element is the actual root module
203
205
  modulesGenerator.next();
204
- const calculateDistance = (moduleRef, distance = 1, modulesStack = []) => {
205
- const localModulesStack = [...modulesStack];
206
- if (!moduleRef || localModulesStack.includes(moduleRef)) {
206
+ const rootModule = modulesGenerator.next().value;
207
+ if (!rootModule) {
208
+ return;
209
+ }
210
+ // Convert modules to an acyclic connected graph
211
+ const tree = new topology_tree_1.TopologyTree(rootModule);
212
+ tree.walk((moduleRef, depth) => {
213
+ if (moduleRef.isGlobal) {
207
214
  return;
208
215
  }
209
- localModulesStack.push(moduleRef);
210
- const moduleImports = moduleRef.imports;
211
- moduleImports.forEach(importedModuleRef => {
212
- if (importedModuleRef) {
213
- if (distance > importedModuleRef.distance &&
214
- !importedModuleRef.isGlobal) {
215
- importedModuleRef.distance = distance;
216
- }
217
- calculateDistance(importedModuleRef, distance + 1, localModulesStack);
218
- }
219
- });
220
- };
221
- const rootModule = modulesGenerator.next().value;
222
- calculateDistance(rootModule);
216
+ moduleRef.distance = depth;
217
+ });
223
218
  }
224
219
  async insertImport(related, token, context) {
225
220
  if ((0, shared_utils_1.isUndefined)(related)) {