@path-ioc/core 0.1.1 → 0.1.3

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Hanlin Lian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,60 +1,66 @@
1
1
  <div align="center">
2
2
  <h1>@path-ioc/core</h1>
3
- <p><b>Spring 有 Bean,Nest 有 Provider,Path-IoC 有 Mesh。</b></p>
4
- <p><b>像 lodash-es 一样纯粹通用的 TypeScript/JavaScript 路径依赖查找引擎 (IoC-DL)</b></p>
5
- <p><b>JavaScript/TypeScript 动态语言模块控制反转的原生正解</b></p>
3
+ <p><b>Spring has Beans, Nest has Providers, Path-IoC has Meshes.</b></p>
4
+ <p><b>A pure, universal TypeScript/JavaScript Dependency Lookup (IoC-DL) engine as lightweight as lodash-es</b></p>
5
+ <p><b>The native Inversion-of-Control solution designed specifically for dynamic languages</b></p>
6
6
 
7
7
  <p>
8
8
  <a href="https://www.npmjs.com/package/@path-ioc/core"><img src="https://img.shields.io/npm/v/@path-ioc/core.svg" alt="NPM version"></a>
9
9
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/@path-ioc/core.svg" alt="License"></a>
10
10
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.0+-3178C6?logo=typescript&logoColor=white" alt="TypeScript"></a>
11
+ <a href="https://path-ioc.dev"><img src="https://img.shields.io/badge/docs-path--ioc.dev-8A2BE2.svg" alt="Docs"></a>
12
+ <a href="https://github.com/sponsors/path-ioc"><img src="https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-EA4AAA.svg" alt="Sponsor"></a>
13
+ </p>
14
+
15
+ <p>
16
+ <b>English</b> | <a href="./README.zh-CN.md">简体中文</a> | <a href="https://path-ioc.dev">Official Docs</a>
11
17
  </p>
12
18
  </div>
13
19
 
14
- > **什么是 Path-IoC (IoC-DL)?**
15
- > 告别原始 `import` 泥潭与传统重型黑盒 DI 在 JS 异步生态里的死锁与元数据包袱。Path-IoC 采用 **Dependency Lookup (依赖查找)** 范式——物理路径即抽象契约,静态图启动期预编译,原生 `async/await` 拓扑并发。零反射、零概念包袱,组件面向 `container` 极简解构。
20
+ > **What is Path-IoC (IoC-DL)?**
21
+ > Say goodbye to explicit `import` hell and the deadlocks, reflection penalties, and metadata bloat of legacy DI containers in asynchronous JavaScript. Path-IoC adopts the **Dependency Lookup (IoC-DL)** paradigm: physical file paths serve as abstract contracts, static topology graphs are compiled once, and modules awaken through native `async/await` DAG concurrency. Zero decorators, zero `reflect-metadata`, and zero framework intrusion.
16
22
 
17
23
  ---
18
24
 
19
- ## 快速上手 (Quick Start)
25
+ ## Quick Start
20
26
 
21
- 在真实的现代前端与全栈工程中,`@path-ioc/core` 与编译期插件 `@path-ioc/unplugin` 深度协同(Compiler-Runtime Co-design)。
27
+ In production applications, `@path-ioc/core` works in tandem with the compiler plugin `@path-ioc/unplugin` (Compiler-Runtime Co-design).
22
28
 
23
- ### 1. 安装核心与构建插件
29
+ ### 1. Install Runtime & Bundler Plugin
24
30
 
25
31
  ```bash
26
- # 运行时核心
32
+ # Runtime Core
27
33
  pnpm add @path-ioc/core
28
34
 
29
- # 通用构建插件 (开发依赖)
35
+ # Universal Bundler Plugin (Dev Dependency)
30
36
  pnpm add -D @path-ioc/unplugin
31
37
  ```
32
38
 
33
- ### 2. 配置构建工具 (支持 Vite / Rolldown / Webpack / Rspack / Rollup / Esbuild)
39
+ ### 2. Configure Bundler (Vite / Rolldown / Webpack / Rspack / Rollup / Esbuild)
34
40
 
35
- 在你的构建配置文件中引入 `@path-ioc/unplugin`:
41
+ Add `@path-ioc/unplugin` to your build configuration:
36
42
 
37
43
  ```typescript
38
- // vite.config.ts (或 rolldown.config.ts)
44
+ // vite.config.ts (or rolldown.config.ts)
39
45
  import { defineConfig } from "vite";
40
46
  import { vitePlugin as pathIoc } from "@path-ioc/unplugin";
41
- // 若使用 Rolldown: import { rolldownPlugin as pathIoc } from "@path-ioc/unplugin";
47
+ // If using Rolldown: import { rolldownPlugin as pathIoc } from "@path-ioc/unplugin";
42
48
 
43
49
  export default defineConfig({
44
50
  plugins: [
45
51
  pathIoc({
46
- modulesPath: "src/modules", // 模块扫描根目录 (默认: 'src/modules')
47
- typeFileOutput: "types", // 自动生成的全局类型输出目录
52
+ modulesPath: "src/modules", // Directory scanned for modules (default: 'src/modules')
53
+ typeFileOutput: "types", // Output directory for auto-generated TypeScript definitions
48
54
  }),
49
55
  ],
50
56
  });
51
57
  ```
52
58
 
53
- *注:Webpack 5 请使用 `webpackPlugin`,Rspack 使用 `rspackPlugin`,Rollup 使用 `rollupPlugin`,Esbuild 使用 `esbuildPlugin`。*
59
+ *Note: For Webpack 5 use `webpackPlugin`, Rspack use `rspackPlugin`, Rollup use `rollupPlugin`, and Esbuild use `esbuildPlugin`.*
54
60
 
55
- ### 3. 创建业务模块 (无需 import,物理路径即契约)
61
+ ### 3. Create Business Modules (Zero imports; Physical Paths as Contracts)
56
62
 
57
- 在 `src/modules` 下自由创建模块目录并导出 `main` 纯函数:
63
+ Create module directories inside `src/modules` and export a pure `main` function:
58
64
 
59
65
  ```typescript
60
66
  // src/modules/infra/db/index.ts
@@ -65,20 +71,21 @@ export const main = () => {
65
71
  };
66
72
 
67
73
  // src/modules/biz/user/index.ts
68
- export const dependencies = ["db"]; // 声明正向依赖
74
+ export const dependencies = ["db"]; // Declare forward dependencies
69
75
 
70
76
  export const main = (container: any) => {
71
- const { db } = container; // 依赖查找 (DL),由拓扑引擎保障前置就绪
77
+ const { db } = container; // Dependency Lookup (DL), guaranteed resolved by DAG topological scheduler
72
78
  return {
73
79
  getUser: (id: string) => db.query(`SELECT * FROM users WHERE id = ${id}`),
74
80
  };
75
81
  };
76
82
  ```
77
83
 
78
- ### 4. 编写应用启动模块 (`src/modules/start-app/index.ts`)
84
+ ### 4. Create App Bootstrap Module (`src/modules/start-app/index.ts`)
79
85
 
80
86
  ```typescript
81
- // 一切业务皆模块:初始调用收敛在 IoC 模块内,天然保障 AOP 切面与依赖拓扑就绪
87
+ // Everything is a module: Bootstrap logic stays within the IoC container,
88
+ // guaranteeing AOP aspect interception and topological readiness.
82
89
  export const main = (container: any) => {
83
90
  const { user } = container;
84
91
  console.log(user.getUser("1001"));
@@ -87,30 +94,30 @@ export const main = (container: any) => {
87
94
  export const dependencies = ["user"];
88
95
  ```
89
96
 
90
- ### 5. 应用入口点火唤醒 (`src/main.ts`)
97
+ ### 5. Ignite the Container (`src/main.ts`)
91
98
 
92
- 在应用入口(如 `src/main.ts`),一行代码唤醒全量无锁拓扑流:
99
+ In your application entrypoint (e.g. `src/main.ts`), ignite the lock-free topological engine with a single line:
93
100
 
94
101
  ```typescript
95
102
  // src/main.ts
96
103
  import { createModularContainer } from "virtual:modular-container";
97
104
 
98
- // 入口保持绝对纯粹:仅充当容器点火器,零业务逻辑污染
105
+ // Pure ignite: zero business logic contamination
99
106
  createModularContainer();
100
107
  ```
101
108
 
102
- 插件会自动为全量模块生成 `ignore.modular.d.ts`,享受 100% 静态类型安全与 IDE 自动补全!
109
+ The plugin automatically generates `ignore.modular.d.ts` in the background, providing 100% static type safety and intelligent IDE autocompletion!
103
110
 
104
111
  ---
105
112
 
106
- ### 6. 原生 Core 独立运行模式 (无打包器 / 纯单测模式)
113
+ ### 6. Standalone / Pure Node.js & Testing Mode
107
114
 
108
- 若在纯 Node.js 脚本、无打包工具或编写隔离单元测试时,亦可直接使用 `@path-ioc/core` 原生纯函数接口:
115
+ When writing isolated unit tests, CLI scripts, or running without a bundler, you can directly invoke the pure function runtime of `@path-ioc/core`:
109
116
 
110
117
  ```typescript
111
118
  import { compileModuleGraph, instantiateModuleContainer } from "@path-ioc/core";
112
119
 
113
- // 1. 显式定义模块列表 (短名称声明依赖与依赖查找)
120
+ // 1. Explicitly define modules (declaring dependencies via keys / short-keys)
114
121
  const modules = [
115
122
  { key: "/infra/db", module: { main: () => "PostgreSQL Connection" } },
116
123
  {
@@ -122,72 +129,74 @@ const modules = [
122
129
  },
123
130
  ];
124
131
 
125
- // 2. 纯同步编译拓扑图 (单次纳秒级)
132
+ // 2. Synchronous topology graph compilation (sub-millisecond)
126
133
  const compiledGraph = compileModuleGraph(modules);
127
134
 
128
- // 3. 动态填充容器
135
+ // 3. Instantiate and populate container
129
136
  const container: Record<string, unknown> = {};
130
137
  await instantiateModuleContainer(compiledGraph, container);
138
+
139
+ console.log(container.userService.getUser("1001"));
131
140
  ```
132
141
 
133
142
  ---
134
143
 
135
- ## 核心设计哲学:向 Spring 致敬与动态语言范式应答 (Architecture Philosophy)
136
-
137
- Path-IoC 的底层设计建立在对 **Java Spring 经典控制反转 (IoC) 哲学** 的深切致敬上。它让 Spring 的伟大解耦思想在 JavaScript/TypeScript 的单线程 `async`、动态语言特性与纯函数语境下得到了原生的继承与演进:
144
+ ## Core Architecture & Philosophy
138
145
 
139
- ### 1. 动态语言范式应答:单线程 Event Loop 下的原生 DAG 拓扑并发
146
+ Path-IoC pays deep homage to **Java Spring's classic Inversion-of-Control (IoC) principles**, while advancing its decoupled vision natively for JavaScript/TypeScript's single-threaded, asynchronous, and functional execution model:
140
147
 
141
- 并非 Path-IoC 创造了神迹,而是 Path-IoC 彻底顺应了 JavaScript 单线程非阻塞 Event Loop 的物理特性:
148
+ ### 1. The Dynamic Language Paradigm: Native DAG Topological Concurrency
149
+ - **Mirroring Physical Models (Multi-threaded Serial vs. Single-threaded Concurrent)**:
150
+ In Java, despite OS-level multi-threading, Spring must strictly fall back to a **serial pipeline** during container initialization to avoid race conditions, memory visibility bugs (JMM), and thread deadlocks during bean creation.
151
+ - **Embracing JavaScript's Strengths**:
152
+ JavaScript's single-threaded Event Loop **naturally eliminates shared-memory data races and lock deadlocks**. Path-IoC leverages this advantage by building a **reactive Directed Acyclic Graph (DAG)** with native `async/await`, activating all independent nodes in the same topological tier in **parallel/concurrent batches**. This bypasses single-thread queuing bottlenecks while fully exploiting non-blocking I/O throughput.
142
153
 
143
- - **物理特性的镜像差异(多线程串行 vs 单线程并行/并发)**:Java 虽然拥有物理多线程,但为了规避并发创建 Bean 带来的共享内存竞争、内存可见性与死锁隐患(JMM 模型限制),Spring 容器初始化阶段在框架底层只能退守于**严谨的单线程严格串行装配(Serial Pipeline)**;
144
- - **利用 JS 天然优势**:JavaScript 的单线程 Event Loop **天然消除了共享内存竞态条件与锁死锁**。Path-IoC 利用这一天然物理优势建立 **原生 `async/await` 反应式拓扑有向无环图 (DAG)**,在初始化阶段实现同层无依赖节点的**全量并行/并发级联点火(Parallel / Concurrent Activation)**——既消除了单线程串行排队的吞吐瓶颈,又发挥了事件驱动非阻塞 I/O 的极高吞吐优势。
154
+ ### 2. Path as Contract (Dependency Inversion Principle)
155
+ - **Strings are Interfaces**: Whether Java's `interface UserData`, `Class.forName("com.xxx.UserService")`, or Path-IoC's physical path coordinates, both decouple clients by **depending upon abstractions rather than concrete implementations** (true DIP).
156
+ - **Physical Features as Service Discovery**: File paths provide natural coordinates for service discovery. For instance, filtering by `name.includes("/entity/orm/")` allows dynamic, zero-configuration discovery of all ORM entity modules.
145
157
 
146
- ### 2. 字符串即接口表征:物理特征即为抽象契约 (Path as Contract)
158
+ ### 3. Aspect-Oriented Programming (AOP) via Pure Closures
159
+ - **Zero Framework Primitives**: Path-IoC avoids heavy specialized abstractions (`Guards`, `Interceptors`, `Pipes`, `Filters`, or JVM byte-code manipulation). In dynamic languages, higher-order functions and proxy wrappers represent the purest form of AOP.
160
+ - **Natural Aspect Meshes**: An aspect module simply declares dependencies matching the path patterns of target modules. The topological engine guarantees target instances are created first; the aspect then wraps target methods via higher-order proxies without intrusive annotations.
147
161
 
148
- - **字符串也是接口的一种表达形式**:无论是 Java 传统的 `interface UserData`、`Class.forName("com.xxx.UserService")` 包路径,还是 Path-IoC 中的全限定路径与短名称,本质上都是在**依赖抽象而非依赖具体**,这正是依赖倒置原则 (DIP) 的终极真相。
149
- - **物理路径特征契约**:路径不仅是坐标,更是服务发现的天然接口。例如在服务端开发中,只需通过路径特征过滤函数 `name.includes("/entity/orm/")`,即可零配置全自动感知并收集所有 ORM 实体(如 `orm-entities` 模块),达到浑然天成的解耦与热插拔。
162
+ ### 4. Circular Dependency & Fail-Fast Engineering
163
+ - **Theory of Dependency Sensing**: Dynamic dependency resolution and circular dependency unwinding are two perspectives of the same underlying mechanism. While dynamic resolution can break cycles, it frequently conceals architecture rot and breaks native `async` DAG preheating.
164
+ - **Core's Standpoint**: `@path-ioc/core` remains strictly rigorous—DFS static cycle analysis enforces **Fail-Fast** error reporting with full cycle chain traces. (For legacy synchronous cycles, the companion `@path-ioc/container` provides a Turbo mode with dynamic getter proxies).
150
165
 
151
- ### 3. AOP 切面机制:零学习成本的原生切面 (DL-based Aspect)
166
+ ### 5. Two-Stage Execution & Edge Serverless Readiness
167
+ By completely eliminating `reflect-metadata`, Path-IoC cleanly separates **Static Graph Compilation (`compileModuleGraph`)** from **Dynamic Container Instantiation (`instantiateModuleContainer`)**. In Cloudflare Workers or serverless Node.js endpoints, the module graph is compiled once on worker cold-start and permanently cached; subsequent requests instantiate lightweight containers directly, reducing framework CPU overhead by over 80%.
152
168
 
153
- - **不内置多余特权概念**:Path-IoC 不内置任何繁重的特权概念工具(如 `Guards`、`Interceptors`、`Pipes`、`Filters` 或复杂的 JDK 动态代理)。Path-IoC 认为在 JavaScript 动态语言下,高阶函数与解构代理本身就是最纯粹的 AOP。
154
- - **完全 AOP 能力 & 零学习成本**:凭借底层的依赖查找 (DL) 能力与动态语言直觉,切面模块(Aspect Mesh)只需在自身的 `dependencies` 函数中声明它要切入的目标模块路径模式(物理上正向依赖目标模块)。拓扑引擎保证目标模块优先完成实例化,切面模块随后唤醒并对 `container` 上的目标对象施加高阶代理包装,无需学习任何框架特有概念,即可具备完全的非侵入式 AOP 切面能力。
155
-
156
- ### 4. 循环依赖与“依赖感知”理论哲学 (Circular Dependency & Dependency Sensing)
157
-
158
- - **纯理论提炼**:**“依赖感知”与“循环依赖解环”本质上是同一物理能力的不同理解角度**。
159
- - **“依赖感知”是核心能力**;
160
- - **正面作用一**:运行时循环依赖解环;
161
- - **正面作用二**:按需子图懒加载 (Lazy Loading);
162
- - **伴生副作用**:遮蔽系统设计缺陷、导致架构隐式腐烂、以及无法原生支持 `async` 异步初始化。
163
- - **Core 引擎的工程立场**:`@path-ioc/core` 保持严谨正义——用 DFS 静态深搜 Fail-Fast 抛错,拒绝用隐式解环遮蔽系统架构漏洞。
164
- - **Container 的 Turbo 机制对比**:若因历史包袱需解环,在纯同步全模块场景下,扩展层 `@path-ioc/container` 的 Turbo 模式通过 Proxy Dynamic Getter 实现按需“依赖感知”,在运行期无痛完成无锁解环。
165
-
166
- ### 5. 全局类型补齐:开发期 DX 与静态类型的殊途同归
169
+ ---
167
170
 
168
- Java 在编译期拥有原生的 class 类型,而 JS/TS 字符串路径在静态阶段缺乏推导。Path-IoC 通过构建插件(`@path-ioc/unplugin`)在开发期(DX 阶段)自动扫描物理目录并实时生成 `ModularContainer` 全局类型接口(`ignore.modular.d.ts`),**完美补齐了动态语言在静态类型推导上的短板**,达到了与 Java 静态编译完全一致的类型安全与智能补全体验。
171
+ ## Hardware-Verified Benchmarks
169
172
 
170
- ### 6. 零运行期反射与两阶段图编译 (Two-Stage Separation)
173
+ Tested on Apple Silicon under Node.js v24 (`pnpm bench`):
171
174
 
172
- 彻底摆脱 `reflect-metadata` 重型反射包袱。架构上将 **静态图编译 (`compileModuleGraph`)** 与 **动态容器填充 (`instantiateModuleContainer`)** 彻底分离。在 Node.js / Workers 高频 HTTP 请求场景中,服务启动时仅编译一次拓扑图,单次请求到来时直通填充容器,彻底免去每次请求重复解析依赖树与反射的开销,大流量下实测可降低 80% 以上的框架层 CPU 开销。
175
+ | Target Function | Complexity | Mean Duration | Evaluation |
176
+ | :--- | :--- | :--- | :--- |
177
+ | **`instantiateModuleContainer`** | **50 Nodes** | **`21.2 µs`** | Microsecond direct resolution; zero request-time latency |
178
+ | **`compileModuleGraph`** | **50 Nodes** | **`90.8 µs`** | Sub-millisecond cycle validation |
179
+ | **`instantiateModuleContainer`** | **500 Nodes** | **`227 µs`** | Ultra-large module graphs resolve with negligible cost |
180
+ | **`compileModuleGraph`** | **500 Nodes** | **`1.72 ms`** | Executed once on process cold boot, cached permanently |
181
+ | **`compileModuleGraph`** | **2,000 Nodes** | **`15.5 ms`** | Industrial-grade deep topology limit |
173
182
 
174
183
  ---
175
184
 
176
- ## 主流 IoC 框架选型对比矩阵 (Selection Matrix)
185
+ ## Selection Matrix
177
186
 
178
- | 对比维度 | **TS 装饰器派**<br>(NestJS / Inversify / TSyringe) | **正则 Proxy 派**<br>(Awilix) | **JVM 反射派**<br>(Java Spring) | **@path-ioc/core** *(及 container 扩展)* |
187
+ | Comparison Dimension | **TS Decorator Stack**<br>(NestJS / Inversify / TSyringe) | **Regex Proxy Stack**<br>(Awilix) | **JVM Reflection Stack**<br>(Java Spring) | **@path-ioc/core** *(with container)* |
179
188
  | :--- | :--- | :--- | :--- | :--- |
180
- | **底层依据** | `reflect-metadata` + TS Decorator | 函数 `.toString()` 正则 + Proxy | Java 反射 + 字节码 + 缓存 (静态语言工业标杆) | **物理路径契约 + 纯闭包工厂 + DAG 图编译** |
181
- | **编译/环境兼容性** | 差 (强依赖元数据,纯类型擦除转译即崩溃) | 良好 | JVM 物理机原生支持 | **极致** (纯 ES Module 函数闭包,零元数据) |
182
- | **初始化装配机制** | 串行主导 / Class 构造纯同步,async Provider 阻塞 | 不支持异步初始化 | 严格单线程串行装配 (出于 JMM 线程安全考量) | **原生 DAG 拓扑并行/并发点火** (利用单线程天然安全,无锁级联调度) |
183
- | **AOP 切面机制** | 概念繁杂 & 强绑定且仅限 Controller | 无内置 AOP 能力 | 划时代声明式代理 (AspectJ) | **完全 AOP 能力 & 零学习成本** (基于 DL 依赖查找与 JS 高阶代理) |
184
- | **循环依赖与解环机制** | 死锁重灾区 (`forwardRef` 遇 async 死锁) | 受限 (仅限纯同步) | 辩证支持 (三级缓存解环,易诱发隐蔽 Bug) | **底层 DFS Fail-Fast 拦截** (拒绝遮蔽漏洞)<br>扩展层 Turbo 模式 (Dynamic Getter 解环) |
185
- | **高并发 / 运行期性能** | 高频元数据反射损耗 | Proxy 属性访问开销 | 工业级高可靠 (受限 JVM 物理模型) | **极高** (静态图编译与填充分离,提升 80% CPU 性能) |
186
- | **架构解耦与侵入性** | 强侵入 (代码处处与框架类和注解绑定) | 中度 (绑定参数名) | 低侵入 (支持 JSR-330 标准注解) | **零侵入** (模块仅为纯函数,脱离框架完全可跑) |
189
+ | **Core Contract** | `reflect-metadata` + TS Decorators | Function `.toString()` parsing + Proxy | Reflection + Bytecode + Caching (Enterprise benchmark) | **Physical Path Contract + Pure Closures + DAG Compilation** |
190
+ | **Bundler Compatibility** | Poor (breaks on pure AST type-erasure bundlers) | Good | Native JVM support | **Universal** (Pure ES Modules & closures; zero reflection) |
191
+ | **Initialization & Concurrency** | Serial pipeline; async providers block sequentially | Synchronous only | Strict single-thread serial assembly (JMM thread safety) | **Native DAG Topological Concurrency** (Lock-free cascading activation) |
192
+ | **AOP Mechanism** | Complex & restricted to HTTP controller layers | None built-in | Declarative bytecode proxy (AspectJ) | **Complete Native AOP** (Zero extra concepts; pure DL & higher-order wrappers) |
193
+ | **Cycle Handling** | Deadlock hazard (`forwardRef` + async hangs) | Limited (Sync only) | Three-level cache unwinding | **Fail-Fast Cycle Interception** (Turbo mode available for legacy sync graphs) |
194
+ | **Edge / Serverless Performance** | High CPU overhead due to dynamic metadata reflection | Proxy traversal overhead | Heavy memory footprint | **Ultra-lightweight** (Two-stage separation, 80%+ lower CPU cost) |
195
+ | **Code Intrusion** | High (pervasive framework decorators) | Moderate (binds parameter names) | Low (supports JSR-330 standard) | **Zero** (Pure ES functions; runs completely independently) |
187
196
 
188
197
  ---
189
198
 
190
- ## 形式化 API 规范 (Formal API Specification)
199
+ ## Formal API Reference
191
200
 
192
201
  ### 1. `compileModuleGraph`
193
202
 
@@ -212,8 +221,8 @@ export function compileModuleGraph(
212
221
  ): CompiledModuleGraph;
213
222
  ```
214
223
 
215
- - **算法复杂度**:时间复杂度 $O(V + E)$,空间复杂度 $O(V + E)$(基于 Kahn 拓扑排序算法);
216
- - **异常捕获**:若检测到环路依赖,立即抛出附带完整环路链路路径的错误;若检测到短名称命名冲突,抛出明确的提示。
224
+ - **Complexity**: Time $O(V + E)$, Space $O(V + E)$ (Kahn's Topological Algorithm);
225
+ - **Fail-Fast Error Handling**: Throws descriptive errors with full cycle paths upon detecting cyclic dependencies, or on short-key collisions.
217
226
 
218
227
  ### 2. `instantiateModuleContainer`
219
228
 
@@ -224,14 +233,14 @@ export function instantiateModuleContainer(
224
233
  ): Promise<void>;
225
234
  ```
226
235
 
227
- - **行为规范**:
228
- - 按 `compiledGraph.sortedKeys` 顺序依次唤醒模块 `main` 函数;
229
- - 自动将模块执行返回值挂载到 `container[fullKey]` 与 `container[shortKey]`;
230
- - 若模块的 `main` 为异步 Promise,引擎自动 `await` 并级联唤醒后续依赖它的子节点。
236
+ - **Execution Semantics**:
237
+ - Iterates through `compiledGraph.sortedKeys` in validated topological order;
238
+ - Mounts return values to both `container[fullKey]` and `container[shortKey]`;
239
+ - Awaits asynchronous `main` promises before triggering dependent child nodes.
231
240
 
232
241
  ---
233
242
 
234
- ## 许可证 (License)
243
+ ## License
235
244
 
236
245
  Released under the [MIT License](./LICENSE).
237
- Copyright © 2026 [Path-IoC Organization](https://github.com/path-ioc) & Lian HanLin.
246
+ Copyright © 2026-present [Path-IoC Organization](https://github.com/path-ioc) & Lian HanLin.
@@ -0,0 +1,242 @@
1
+ <div align="center">
2
+ <h1>@path-ioc/core</h1>
3
+ <p><b>Spring 有 Bean,Nest 有 Provider,Path-IoC 有 Mesh。</b></p>
4
+ <p><b>像 lodash-es 一样纯粹通用的 TypeScript/JavaScript 路径依赖查找引擎 (IoC-DL)</b></p>
5
+ <p><b>JavaScript/TypeScript 动态语言模块控制反转的原生正解</b></p>
6
+
7
+ <p>
8
+ <a href="https://www.npmjs.com/package/@path-ioc/core"><img src="https://img.shields.io/npm/v/@path-ioc/core.svg" alt="NPM version"></a>
9
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/@path-ioc/core.svg" alt="License"></a>
10
+ <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.0+-3178C6?logo=typescript&logoColor=white" alt="TypeScript"></a>
11
+ <a href="https://path-ioc.dev/zh/"><img src="https://img.shields.io/badge/文档-path--ioc.dev-8A2BE2.svg" alt="Documentation"></a>
12
+ </p>
13
+
14
+ <p>
15
+ <a href="./README.md">English</a> | <b>简体中文</b> | <a href="https://path-ioc.dev/zh/">官方文档</a>
16
+ </p>
17
+ </div>
18
+
19
+ > **什么是 Path-IoC (IoC-DL)?**
20
+ > 告别原始 `import` 泥潭与传统重型黑盒 DI 在 JS 异步生态里的死锁与元数据包袱。Path-IoC 采用 **Dependency Lookup (依赖查找)** 范式——物理路径即抽象契约,静态图启动期预编译,原生 `async/await` 拓扑并发。零反射、零概念包袱,组件面向 `container` 极简解构。
21
+
22
+ ---
23
+
24
+ ## 快速上手 (Quick Start)
25
+
26
+ 在真实的现代前端与全栈工程中,`@path-ioc/core` 与编译期插件 `@path-ioc/unplugin` 深度协同(Compiler-Runtime Co-design)。
27
+
28
+ ### 1. 安装核心与构建插件
29
+
30
+ ```bash
31
+ # 运行时核心
32
+ pnpm add @path-ioc/core
33
+
34
+ # 通用构建插件 (开发依赖)
35
+ pnpm add -D @path-ioc/unplugin
36
+ ```
37
+
38
+ ### 2. 配置构建工具 (支持 Vite / Rolldown / Webpack / Rspack / Rollup / Esbuild)
39
+
40
+ 在你的构建配置文件中引入 `@path-ioc/unplugin`:
41
+
42
+ ```typescript
43
+ // vite.config.ts (或 rolldown.config.ts)
44
+ import { defineConfig } from "vite";
45
+ import { vitePlugin as pathIoc } from "@path-ioc/unplugin";
46
+ // 若使用 Rolldown: import { rolldownPlugin as pathIoc } from "@path-ioc/unplugin";
47
+
48
+ export default defineConfig({
49
+ plugins: [
50
+ pathIoc({
51
+ modulesPath: "src/modules", // 模块扫描根目录 (默认: 'src/modules')
52
+ typeFileOutput: "types", // 自动生成的全局类型输出目录
53
+ }),
54
+ ],
55
+ });
56
+ ```
57
+
58
+ *注:Webpack 5 请使用 `webpackPlugin`,Rspack 使用 `rspackPlugin`,Rollup 使用 `rollupPlugin`,Esbuild 使用 `esbuildPlugin`。*
59
+
60
+ ### 3. 创建业务模块 (无需 import,物理路径即契约)
61
+
62
+ 在 `src/modules` 下自由创建模块目录并导出 `main` 纯函数:
63
+
64
+ ```typescript
65
+ // src/modules/infra/db/index.ts
66
+ export const main = () => {
67
+ return {
68
+ query: (sql: string) => `Executed: ${sql}`,
69
+ };
70
+ };
71
+
72
+ // src/modules/biz/user/index.ts
73
+ export const dependencies = ["db"]; // 声明正向依赖
74
+
75
+ export const main = (container: any) => {
76
+ const { db } = container; // 依赖查找 (DL),由拓扑引擎保障前置就绪
77
+ return {
78
+ getUser: (id: string) => db.query(`SELECT * FROM users WHERE id = ${id}`),
79
+ };
80
+ };
81
+ ```
82
+
83
+ ### 4. 编写应用启动模块 (`src/modules/start-app/index.ts`)
84
+
85
+ ```typescript
86
+ // 一切业务皆模块:初始调用收敛在 IoC 模块内,天然保障 AOP 切面与依赖拓扑就绪
87
+ export const main = (container: any) => {
88
+ const { user } = container;
89
+ console.log(user.getUser("1001"));
90
+ };
91
+
92
+ export const dependencies = ["user"];
93
+ ```
94
+
95
+ ### 5. 应用入口点火唤醒 (`src/main.ts`)
96
+
97
+ 在应用入口(如 `src/main.ts`),一行代码唤醒全量无锁拓扑流:
98
+
99
+ ```typescript
100
+ // src/main.ts
101
+ import { createModularContainer } from "virtual:modular-container";
102
+
103
+ // 入口保持绝对纯粹:仅充当容器点火器,零业务逻辑污染
104
+ createModularContainer();
105
+ ```
106
+
107
+ 插件会自动为全量模块生成 `ignore.modular.d.ts`,享受 100% 静态类型安全与 IDE 自动补全!
108
+
109
+ ---
110
+
111
+ ### 6. 原生 Core 独立运行模式 (无打包器 / 纯单测模式)
112
+
113
+ 若在纯 Node.js 脚本、无打包工具或编写隔离单元测试时,亦可直接使用 `@path-ioc/core` 原生纯函数接口:
114
+
115
+ ```typescript
116
+ import { compileModuleGraph, instantiateModuleContainer } from "@path-ioc/core";
117
+
118
+ // 1. 显式定义模块列表 (短名称声明依赖与依赖查找)
119
+ const modules = [
120
+ { key: "/infra/db", module: { main: () => "PostgreSQL Connection" } },
121
+ {
122
+ key: "/biz/userService",
123
+ module: {
124
+ dependencies: ["db"],
125
+ main: (c) => ({ db: c.db, getUser: (id: string) => `User ${id}` }),
126
+ },
127
+ },
128
+ ];
129
+
130
+ // 2. 纯同步编译拓扑图 (单次纳秒级)
131
+ const compiledGraph = compileModuleGraph(modules);
132
+
133
+ // 3. 动态填充容器
134
+ const container: Record<string, unknown> = {};
135
+ await instantiateModuleContainer(compiledGraph, container);
136
+ ```
137
+
138
+ ---
139
+
140
+ ## 核心设计哲学:向 Spring 致敬与动态语言范式应答 (Architecture Philosophy)
141
+
142
+ Path-IoC 的底层设计建立在对 **Java Spring 经典控制反转 (IoC) 哲学** 的深切致敬上。它让 Spring 的伟大解耦思想在 JavaScript/TypeScript 的单线程 `async`、动态语言特性与纯函数语境下得到了原生的继承与演进:
143
+
144
+ ### 1. 动态语言范式应答:单线程 Event Loop 下的原生 DAG 拓扑并发
145
+
146
+ 并非 Path-IoC 创造了神迹,而是 Path-IoC 彻底顺应了 JavaScript 单线程非阻塞 Event Loop 的物理特性:
147
+
148
+ - **物理特性的镜像差异(多线程串行 vs 单线程并行/并发)**:Java 虽然拥有物理多线程,但为了规避并发创建 Bean 带来的共享内存竞争、内存可见性与死锁隐患(JMM 模型限制),Spring 容器初始化阶段在框架底层只能退守于**严谨的单线程严格串行装配(Serial Pipeline)**;
149
+ - **利用 JS 天然优势**:JavaScript 的单线程 Event Loop **天然消除了共享内存竞态条件与锁死锁**。Path-IoC 利用这一天然物理优势建立 **原生 `async/await` 反应式拓扑有向无环图 (DAG)**,在初始化阶段实现同层无依赖节点的**全量并行/并发级联点火(Parallel / Concurrent Activation)**——既消除了单线程串行排队的吞吐瓶颈,又发挥了事件驱动非阻塞 I/O 的极高吞吐优势。
150
+
151
+ ### 2. 字符串即接口表征:物理特征即为抽象契约 (Path as Contract)
152
+
153
+ - **字符串也是接口的一种表达形式**:无论是 Java 传统的 `interface UserData`、`Class.forName("com.xxx.UserService")` 包路径,还是 Path-IoC 中的全限定路径与短名称,本质上都是在**依赖抽象而非依赖具体**,这正是依赖倒置原则 (DIP) 的终极真相。
154
+ - **物理路径特征契约**:路径不仅是坐标,更是服务发现的天然接口。例如在服务端开发中,只需通过路径特征过滤函数 `name.includes("/entity/orm/")`,即可零配置全自动感知并收集所有 ORM 实体(如 `orm-entities` 模块),达到浑然天成的解耦与热插拔。
155
+
156
+ ### 3. AOP 切面机制:零学习成本的原生切面 (DL-based Aspect)
157
+
158
+ - **不内置多余特权概念**:Path-IoC 不内置任何繁重的特权概念工具(如 `Guards`、`Interceptors`、`Pipes`、`Filters` 或复杂的 JDK 动态代理)。Path-IoC 认为在 JavaScript 动态语言下,高阶函数与解构代理本身就是最纯粹的 AOP。
159
+ - **完全 AOP 能力 & 零学习成本**:凭借底层的依赖查找 (DL) 能力与动态语言直觉,切面模块(Aspect Mesh)只需在自身的 `dependencies` 函数中声明它要切入的目标模块路径模式(物理上正向依赖目标模块)。拓扑引擎保证目标模块优先完成实例化,切面模块随后唤醒并对 `container` 上的目标对象施加高阶代理包装,无需学习任何框架特有概念,即可具备完全的非侵入式 AOP 切面能力。
160
+
161
+ ### 4. 循环依赖与“依赖感知”理论哲学 (Circular Dependency & Dependency Sensing)
162
+
163
+ - **纯理论提炼**:**“依赖感知”与“循环依赖解环”本质上是同一物理能力的不同理解角度**。
164
+ - **“依赖感知”是核心能力**;
165
+ - **正面作用一**:运行时循环依赖解环;
166
+ - **正面作用二**:按需子图懒加载 (Lazy Loading);
167
+ - **伴生副作用**:遮蔽系统设计缺陷、导致架构隐式腐烂、以及无法原生支持 `async` 异步初始化。
168
+ - **Core 引擎的工程立场**:`@path-ioc/core` 保持严谨正义——用 DFS 静态深搜 Fail-Fast 抛错,拒绝用隐式解环遮蔽系统架构漏洞。
169
+ - **Container 的 Turbo 机制对比**:若因历史包袱需解环,在纯同步全模块场景下,扩展层 `@path-ioc/container` 的 Turbo 模式通过 Proxy Dynamic Getter 实现按需“依赖感知”,在运行期无痛完成无锁解环。
170
+
171
+ ### 5. 全局类型补齐:开发期 DX 与静态类型的殊途同归
172
+
173
+ Java 在编译期拥有原生的 class 类型,而 JS/TS 字符串路径在静态阶段缺乏推导。Path-IoC 通过构建插件(`@path-ioc/unplugin`)在开发期(DX 阶段)自动扫描物理目录并实时生成 `ModularContainer` 全局类型接口(`ignore.modular.d.ts`),**完美补齐了动态语言在静态类型推导上的短板**,达到了与 Java 静态编译完全一致的类型安全与智能补全体验。
174
+
175
+ ### 6. 零运行期反射与两阶段图编译 (Two-Stage Separation)
176
+
177
+ 彻底摆脱 `reflect-metadata` 重型反射包袱。架构上将 **静态图编译 (`compileModuleGraph`)** 与 **动态容器填充 (`instantiateModuleContainer`)** 彻底分离。在 Node.js / Workers 高频 HTTP 请求场景中,服务启动时仅编译一次拓扑图,单次请求到来时直通填充容器,彻底免去每次请求重复解析依赖树与反射的开销,大流量下实测可降低 80% 以上的框架层 CPU 开销。
178
+
179
+ ---
180
+
181
+ ## 主流 IoC 框架选型对比矩阵 (Selection Matrix)
182
+
183
+ | 对比维度 | **TS 装饰器派**<br>(NestJS / Inversify / TSyringe) | **正则 Proxy 派**<br>(Awilix) | **JVM 反射派**<br>(Java Spring) | **@path-ioc/core** *(及 container 扩展)* |
184
+ | :--- | :--- | :--- | :--- | :--- |
185
+ | **底层依据** | `reflect-metadata` + TS Decorator | 函数 `.toString()` 正则 + Proxy | Java 反射 + 字节码 + 缓存 (静态语言工业标杆) | **物理路径契约 + 纯闭包工厂 + DAG 图编译** |
186
+ | **编译/环境兼容性** | 差 (强依赖元数据,纯类型擦除转译即崩溃) | 良好 | JVM 物理机原生支持 | **极致** (纯 ES Module 函数闭包,零元数据) |
187
+ | **初始化装配机制** | 串行主导 / Class 构造纯同步,async Provider 阻塞 | 不支持异步初始化 | 严格单线程串行装配 (出于 JMM 线程安全考量) | **原生 DAG 拓扑并行/并发点火** (利用单线程天然安全,无锁级联调度) |
188
+ | **AOP 切面机制** | 概念繁杂 & 强绑定且仅限 Controller | 无内置 AOP 能力 | 划时代声明式代理 (AspectJ) | **完全 AOP 能力 & 零学习成本** (基于 DL 依赖查找与 JS 高阶代理) |
189
+ | **循环依赖与解环机制** | 死锁重灾区 (`forwardRef` 遇 async 死锁) | 受限 (仅限纯同步) | 辩证支持 (三级缓存解环,易诱发隐蔽 Bug) | **底层 DFS Fail-Fast 拦截** (拒绝遮蔽漏洞)<br>扩展层 Turbo 模式 (Dynamic Getter 解环) |
190
+ | **高并发 / 运行期性能** | 高频元数据反射损耗 | Proxy 属性访问开销 | 工业级高可靠 (受限 JVM 物理模型) | **极高** (静态图编译与填充分离,提升 80% CPU 性能) |
191
+ | **架构解耦与侵入性** | 强侵入 (代码处处与框架类和注解绑定) | 中度 (绑定参数名) | 低侵入 (支持 JSR-330 标准注解) | **零侵入** (模块仅为纯函数,脱离框架完全可跑) |
192
+
193
+ ---
194
+
195
+ ## 形式化 API 规范 (Formal API Specification)
196
+
197
+ ### 1. `compileModuleGraph`
198
+
199
+ ```typescript
200
+ export interface IOCModule {
201
+ main: (container: any, moduleNames: string[]) => any | Promise<any>;
202
+ dependencies?: string[] | ((moduleNames: string[]) => string[]);
203
+ order?: number;
204
+ skip?: boolean;
205
+ }
206
+
207
+ export interface CompiledModuleGraph {
208
+ sortedKeys: string[];
209
+ resolvedDepsMap: Record<string, string[]>;
210
+ shortKeyToFullKeyMap: Record<string, string>;
211
+ fullKeyToShortKeyMap: Record<string, string>;
212
+ moduleMap: Record<string, IOCModule>;
213
+ }
214
+
215
+ export function compileModuleGraph(
216
+ modules: { key: string; module: IOCModule }[]
217
+ ): CompiledModuleGraph;
218
+ ```
219
+
220
+ - **算法复杂度**:时间复杂度 $O(V + E)$,空间复杂度 $O(V + E)$(基于 Kahn 拓扑排序算法);
221
+ - **异常捕获**:若检测到环路依赖,立即抛出附带完整环路链路路径的错误;若检测到短名称命名冲突,抛出明确的提示。
222
+
223
+ ### 2. `instantiateModuleContainer`
224
+
225
+ ```typescript
226
+ export function instantiateModuleContainer(
227
+ compiledGraph: CompiledModuleGraph,
228
+ container: Record<string, unknown>
229
+ ): Promise<void>;
230
+ ```
231
+
232
+ - **行为规范**:
233
+ - 按 `compiledGraph.sortedKeys` 顺序依次唤醒模块 `main` 函数;
234
+ - 自动将模块执行返回值挂载到 `container[fullKey]` 与 `container[shortKey]`;
235
+ - 若模块的 `main` 为异步 Promise,引擎自动 `await` 并级联唤醒后续依赖它的子节点。
236
+
237
+ ---
238
+
239
+ ## 许可证 (License)
240
+
241
+ Released under the [MIT License](./LICENSE).
242
+ Copyright © 2026 [Path-IoC Organization](https://github.com/path-ioc) & Lian HanLin.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@path-ioc/core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Pure topological dependency resolution engine & zero-reflection IoC runtime",
5
5
  "keywords": [
6
6
  "ioc",