@virid/core 0.0.1 → 0.1.1

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/README.zh.md CHANGED
@@ -1,203 +1,255 @@
1
- # 🛰️ @virid/core
1
+ # @virid/core
2
2
 
3
- > **A Lightweight, Message-Driven Logic Engine inspired by Rust's ECS Architecture and Nestjs.** **受 Rust Bevy ECS 架构与Nestjs启发的轻量级消息驱动逻辑引擎。**
3
+ `@virid/core` 是整个 Virid 生态系统的逻辑心脏。它提供了一套确定性的消息分发与调度机制,旨在将业务逻辑从复杂的 UI 框架与运行环境中彻底剥离。
4
4
 
5
- ## 特点
5
+ ## 🌟 核心设计理念
6
6
 
7
- ### 🧩 什么是 CCS 架构?
7
+ - **环境绝对独立**:本包不依赖任何浏览器、Node.js 的特殊 API 或第三方库(仅依赖 `reflect-metadata` 实现装饰器功能)。这确保了内核可以无缝运行在 Electron 主进程、Worker 线程、Web 渲染层甚至纯服务器环境中。
8
+ - **确定性调度**:引入了类似游戏引擎的 `Tick` 机制,通过双缓冲消息池确保逻辑执行顺序的可预测性。
8
9
 
9
- `virid` 采用 **CCS (Controller-Component-System)** 架构。它在传统 ECS 的基础上,为 Web/UI 环境引入了“控制器”层,实现了逻辑与视图的完美桥接。
10
+ ## 🛠️ 核心功能详解
10
11
 
11
- #### 1. 💾 Component (数据) —— “逻辑的容器”
12
+ ### 1. 消息驱动与分发机制 (Message & Dispatcher)
12
13
 
13
- - **定义**:纯粹的数据结构,不包含任何业务逻辑。
14
- - **职责**:存储状态。在 `virid` 中,它是 IoC 容器管理的单例。
14
+ Virid 中,所有的状态变更都必须通过发送一个 `Message` 指令来触发。
15
15
 
16
- #### 2. 🎮 Controller (控制器) —— “视图的锚点”
16
+ - **自动调度**:通过定义特定类型的 `Message` 和对应的 `System` 处理函数,引擎会自动在下一个微任务周期(Tick)内调用已注册的逻辑。
17
+ - **消息类型**:
18
+ - `SingleMessage`:同一 Tick 内的同类消息会自动合并,适用于状态同步。
19
+ - `EventMessage`:顺序追加,确保动作序列的完整性。
20
+ - `ErrorMessage`:顺序追加,错误也是一种消息类型,拥有默认处理System。
21
+ - `WarnMessage`:顺序追加,警告也是一种消息类型,拥有默认处理System。
22
+ - `InfoMessage`:顺序追加,信息也是一种消息类型,拥有默认处理System。
17
23
 
18
- - **定义**:UI 框架(Vue)与核心逻辑(Core)之间的代理。
19
- - **职责**:
20
- - **投影 (Projection)**:将 Component 里的数据安全地映射给 Vue。
21
- - **指令 (Command)**:接收用户的点击事件,并将其转化为 `Message` 发送给引擎。
24
+ ### 2. 依赖注入系统 (Dependency Injection)
22
25
 
23
- #### 3. ⚙️ System (系统) —— “因果的裁判”
26
+ Virid 实现了基于装饰器的轻量依赖注入,使 System 能够以极简的方式访问数据实体。
24
27
 
25
- - **定义**:无状态的静态方法集合,是逻辑变更的唯一合法场所。
26
- - **职责**:监听 `Message`,根据指令修改 `Component` 中的数据。它是确定性的,确保同样的输入永远得到同样的输出。
28
+ - **数据实体 (Component)**:通过 `@Component()` 装饰器标记 class,将其定义为数据容器。
29
+ - **自动注入**:使用 `app.bindComponent()` 注册后,Dispatcher 会根据 System 函数的参数类型自动注入对应的实例。
27
30
 
28
- ### 🛠️ 逻辑主权
31
+ ```ts
32
+ class IncrementMessage extends SingleMessage {
33
+ constructor(public amount: number) {
34
+ super();
35
+ }
36
+ }
29
37
 
30
- #### 1. 彻底的 UI 降级:框架无关核心
38
+ @Component()
39
+ class CounterComponent { public count = 0; }
31
40
 
32
- - **主权移交**:UI 框架被剥夺了状态管理与业务调度的权限,退化为纯粹的 **“状态投影层”**。所有的业务因果律、状态机转换均在 `virid Core` 中闭环执行。
33
- - **物理隔离**:Core 层不依赖任何 `DOM/BOM` API。核心逻辑可以无缝运行在 **Node.js 服务端、Web Worker、甚至是命令行 (CLI) 工具**中。
34
- - **无缝迁移**:逻辑资产不再与特定 UI 框架绑定。只需更换一个适配层,就能适配 vue 或React 应用。
41
+ class CounterSystem {
42
+ @System()
43
+ static onIncrement(
44
+ @Message(IncrementMessage) msg: IncrementMessage,
45
+ count: CounterComponent
46
+ ) {
47
+ count.count += msg.amount; // 自动注入的 CounterComponent 实例
48
+ }
49
+ }
50
+ ```
35
51
 
36
- #### 2. 生产级的可测试性
52
+ ### 3. 系统调度与钩子 (Lifecycle Hooks)
37
53
 
38
- - **告别模拟 (Mock) 地狱**:无需 JSDOM,无需模拟复杂的浏览器环境。由于核心逻辑是纯 JS/TS 驱动的,可以直接在 Node.js 中启动 Core,通过 **“发送消息 -> 断言状态”** 的方式,完成对复杂业务流的单元测试。
39
- - **逻辑回放**:所有副作用都通过消息触发,让业务逻辑变成**纯净的流水线**,支持对线上逻辑路径进行离线重构与自动化回归。
54
+ Dispatcher 提供了完备的生命周期监控能力:
40
55
 
41
- #### 3. 强力控制反转
56
+ - **执行钩子**:支持 `onBeforeExecute` 和 `onAfterExecute`,允许在逻辑执行前后插入全局审计或过滤逻辑。
57
+ - **周期钩子**:`onBeforeTick` 与 `onAfterTick` 用于监控每一轮逻辑帧的起止。
42
58
 
43
- - **深度 IoC 架构**:基于 **InversifyJS** 实现依赖注入。`System`、`Component` 与 `Controller` 之间通过容器自动装配。
44
- - **动态生命周期**:支持逻辑模块的按需加载与自动注入。无论是全局单例的 `System` 还是随组件销毁的 `Controller`,均由容器统一接管生命周期。
59
+ ### 4. 工业级健壮性
45
60
 
46
- ### 🏎️ 游戏级调度引擎
61
+ - **死循环防御**:Dispatcher 内部设有 `internalDepth` 计数器。若逻辑链路产生超过 100 层的递归触发,系统将自动熔断并报错,防止环境假死。
62
+ - **执行优先级**:支持通过 `@System({ priority: number })` 明确多个系统处理同一消息时的先后顺序。
47
63
 
48
- - **确定性 Tick 机制**: 引入类 Bevy 的消息循环,所有逻辑变更在 Tick 中推进。
49
- - **双缓冲消息池**: 物理隔离“正在处理”与“新产生”的消息,避死循环与逻辑抖动。
50
- - **物理隔离消息策略**:
51
- - **SingleMessage (信号)**: 自动合并同类项,同 Tick 内仅触发一次批量处理。
52
- - **EventMessage (事件)**: 严格保序执行,确保逻辑链条的原子性。
64
+ ## 🛠️ @virid/core 核心 API 概览
53
65
 
54
- ### 🛡️ 状态安全与权限控制
66
+ ### 1. 引擎初始化 (Engine Entry)
55
67
 
56
- - **只读数据护盾**: Controller 层(@virid/vue中)默认获得只读代理,禁止在 System 之外非法篡改 Component 状态。
57
- - **原子修改协议**: 强制通过特定的 `AtomicModifyMessage` 变更数据,让每一次状态改变都有迹可循、可被审计。
68
+ #### `createVirid()`
58
69
 
59
- ### 🧬 声明式元编程
70
+ - **功能**:初始化逻辑内核,创建全局唯一的 `Dispatcher` 与容器。
60
71
 
61
- - **装饰器驱动**: 使用 `@System`, `@Message`, `@Inherit`, `@Project` 等装饰器,以声明式的方式描述复杂的依赖网络和逻辑响应流。
62
- - **自动数据路由**: 消息发送即触发,参数自动注入,无需手动编写复杂的监听与分发代码。
72
+ ------
63
73
 
64
- ## 📖 快速上手
74
+ ### 2. 指令与消息 (Messages)
65
75
 
66
- 只需三步,即可在纯 JS 环境中构建一个受严格保护的状态机。
76
+ 消息是驱动系统的唯一原因。Virid 区分了两种不同的执行范式:
67
77
 
68
- #### 1. 定义组件与消息 (Component & Message)
78
+ #### `SingleMessage`
69
79
 
70
- 组件(Component)是纯粹的数据结构,消息是唯一的驱动契约。
80
+ - **特性**:**状态同步型消息**。
71
81
 
72
- ```ts
73
- import {
74
- createvirid,
75
- Component,
76
- System,
77
- Message,
78
- SingleMessage,
79
- AtomicModifyMessage,
80
- } from "@virid/core";
82
+ - **逻辑**:在同一个 `Tick` 内发送的多次同类型 `SingleMessage` 会被自动合并。默认情况下,`System` 仅会收到最新的一条。
83
+
84
+ - **示例:**
85
+
86
+ ```ts
87
+ import {SingleMessage} form "@virid/core"
88
+ class MyMessage extends SingleMessage{}
89
+
90
+ //在任何的地方,只要发送
91
+ //send内的参数为MyMessage的构造函数可以接受的参数
92
+ MyMessage.send()
93
+ ```
94
+
95
+ #### `EventMessage`
96
+
97
+ - **特性**:**动作指令型消息**。
98
+ - **逻辑**:顺序追加,不合并。每一条 `EventMessage` 都会严格触发一次 `System` 执行。
99
+ - **示例:**同`SingleMessage`
81
100
 
82
- // Initialize the core engine
83
- const app = createvirid();
101
+ ------
84
102
 
85
- // Define Data Entity (Component)
103
+ ### 3. 数据与逻辑定义 (Decorators)
104
+
105
+ #### `@Component()`
106
+
107
+ - **功能**:标记一个类为**数据实体**。
108
+ - **设计**:配合 `bindComponent` 使用,注册后可以在System中声明类型以获得依赖注入功能。
109
+ - **示例:**
110
+
111
+ ```ts
86
112
  @Component()
87
113
  class CounterComponent {
88
114
  public count = 0;
89
115
  }
90
- // Register component
91
- app.bindComponent(CounterComponent);
92
-
93
- // Define operation instructions (Message)
94
- class IncrementMessage extends SingleMessage {
95
- constructor(public amount: number) {
96
- super();
97
- }
98
- }
99
116
  ```
100
117
 
101
- #### 2. 编写系统 (System)
118
+ #### `@System(params?)`
102
119
 
103
- 系统是无状态的静态方法,通过依赖注入获取组件并处理业务逻辑。**你无需任何操作,他们是纯static的,virid会自动找到他们并正确地调用他们。**
120
+ - **功能**:将静态方法注册为业务逻辑处理器。它实现了“依赖自动装配”。你只需要在参数里写上对应的 `Component` 类型,引擎就会在执行时自动注入实例。
121
+ - **参数**:
122
+ - `priority`: 执行优先级。数值越大,在同一个 `Tick` 中执行越早。
123
+ - `messageClass`: 触发该System需要的消息类型,不能与`@Message`共存
124
+ - **示例**:
104
125
 
105
126
  ```ts
106
- //Define System
127
+ import {
128
+ System,
129
+ Message,
130
+ } from "@virid/core";
131
+
107
132
  class CounterSystem {
108
- @System()
133
+ // 可以为System设置优先级
134
+ // count参数将被自动注入
135
+ @System({ priority: 0})
109
136
  static onIncrement(
110
137
  @Message(IncrementMessage) message: IncrementMessage,
111
138
  count: CounterComponent,
112
139
  ) {
113
- console.log("---------------------System----------------------");
114
- console.log("message :>> ", message);
115
140
  count.count += message.amount;
116
141
  }
142
+ //可以不使用@Message
143
+ @System({messageClass:IncrementMessage})
144
+ static onIncrement(
145
+ count: CounterComponent,
146
+ ) {
147
+ count.count += 1;
148
+ }
149
+ @System()
150
+ static onProcess(msg: SomeMessage) {
151
+ // 直接 return 消息,即可实现逻辑链式触发,无需手动调用 MessageWriter
152
+ // 也可以return一个message数组来连续触发
153
+ return new NextStepMessage();
154
+ }
117
155
  }
156
+ //直接通过.send来发送消息
157
+ IncrementMessage.send(5);
118
158
  ```
119
159
 
120
- #### 3. 纯环境运行 (Headless Execution)
160
+ #### `@Message(Class, single?)`
161
+
162
+ - **功能**:参数级装饰器,明确当前 `System` 关注的消息类型。
163
+ - **批处理模式**:若设置 `single: false`,`System` 会收到一个包含本轮 `Tick` 内所有该消息的数组,适用于高性能的批量计算(如物理引擎或日志聚合)。
164
+ - **示例:**见System
165
+
166
+ ### `@Observer(callback)`
121
167
 
122
- 无需浏览器,直接在 Node.js 或测试框架中驱动你的业务。
168
+ - **功能**:属性级变更监听,用于处理那些“非指令驱动”的副作用
169
+ - **逻辑**:当 `Component` 中被标记的属性发生变更时,引擎会自动触发指定的回调函数。
170
+ - **示例**:
123
171
 
124
172
  ```ts
125
- // Business logic automatically completes scheduling in the next microtask
126
- queueMicrotask(() => {
127
- IncrementMessage.send(1);
128
- IncrementMessage.send(5);
129
- queueMicrotask(() => {
130
- AtomicModifyMessage.send(
131
- CounterComponent,
132
- (comp) => {
133
- console.log("----------------AtomicModifyMessage------------------");
134
- console.log("CounterComponent :>> ", comp);
135
- },
136
- "Check CounterComponent",
137
- );
138
- });
139
- });
173
+ @Component()
174
+ class PlayerComponent {
175
+ // 当 progress 变更时,自动发送一个同步消息或执行回调
176
+ @Observer((old, val) => new SyncLyricMessage(val))
177
+ public progress = 0;
178
+ }
140
179
  ```
141
180
 
142
- ## 🛠️ 高级工程实践 (Advanced Engineering)
181
+ ### `@Safe()`
143
182
 
144
- ### 全生命周期拦截 (Lifecycle Hooks & Middleware)
183
+ - **功能**:方法访问权限标记,在virid中外部环境(UI 层)严禁直接修改逻辑层数据。但对于某些“只读类”或“安全计算类”方法,可以通过 `@Safe()` 显式授权,允许视图层直接调用。
184
+ - **设计**:主要服务于 `@virid/vue` 等外部投影层,详情请前往vue适配层文档。
185
+ - **示例**:
145
186
 
146
- virid 提供了深度介入消息管道的能力,你可以轻易地将其扩展为支持 **Undo/Redo**、**状态同步** 或 **自动日志** 的系统。
187
+ ```ts
188
+ @Component()
189
+ class PlayerComponent {
190
+ // 如果不加Safe,virid将会禁止在任何vue的controller中调用该方法
191
+ @Safe()
192
+ public someMethod(){}
193
+ }
194
+ ```
147
195
 
148
- - **Middleware**: 在消息进入 EventHub 之前进行预处理。
196
+ ------
149
197
 
150
- TypeScript
198
+ ### 4. 调度与拦截 (Dispatcher & Hooks)
151
199
 
152
- ```ts
153
- app.useMiddleware((message, next) => {
154
- console.log(`Identified message ${message.constructor.name}`);
155
- next(); // 继续流转
156
- });
157
- ```
200
+ #### `Dispatcher`
158
201
 
159
- - **AOP Hooks**: 针对特定消息的执行前后进行切面处理。
160
- - `onBeforeExecute`: 在 System 逻辑运行前触发(如权限检查)。
161
- - `onAfterExecute`: 在逻辑运行后触发(如数据持久化)。
202
+ - **核心逻辑**:
203
+ 1. **双缓冲交换 (Flip)**:调度器基于逻辑Tick运行,以微任务开始为起点,直到系统内部不在产生新的Message为止为一个逻辑Tick。每次执行调度器锁定当前待处理消息,新产生的消息自动进入下一轮。
204
+ 2. **死循环熔断**:若递归执行深度 `internalDepth > 100`,立即停止执行并报错,保护主线程不被逻辑黑洞卡死。
162
205
 
163
- ```ts
164
- app.onBeforeExecute(IncrementMessage, (message, context) => {
165
- console.log("----------------onBeforeExecute------------------");
166
- console.log("message :>> ", message);
167
- console.log("targetClass :>> ", context.targetClass);
168
- console.log("methodName :>> ", context.methodName);
169
- console.log("params :>> ", context.params);
170
- });
171
- ```
206
+ #### 生命周期钩子 (Life-Cycle Hooks)
172
207
 
173
- ### 原子修改:“快照”特权 (Atomic Modification)
208
+ - `onBeforeTick` / `onAfterTick`: 监控逻辑帧的脉搏。
209
+ - `onBeforeExecute` / `onAfterExecute`: 针对特定消息的执行全过程进行审计。
210
+ - **示例**:
174
211
 
175
- 为了兼顾“严苛约束”与“开发效率”,virid 允许通过 `AtomicModifyMessage` 直接描述状态变更,而无需编写完整的 System。
212
+ ```ts
213
+ const app = createVirid();
214
+ app.onBeforeExecute(MyMessage, (msg, context) => {
215
+ // 可以在这里实现全局的性能追踪或权限校验
216
+ // 只会对MyMessage和子类消息生效
217
+ });
218
+ app.onAfterTick((context) => {
219
+ console.log("----------------onAfterTick------------------");
220
+ });
221
+ ```
176
222
 
177
- - **语义化变更**:每一条原子修改都强制要求一个 `label`,让原本“随意的”赋值操作变得可被审计。
178
- - **一致性保证**:原子修改依然遵循 Tick 调度,确保数据变更与 System 逻辑同步生效。
223
+ ------
179
224
 
180
- ### 🚨 万物皆消息:健壮的异常监控 (Error as Message)
225
+ ### 5. 系统通讯 (IO)
181
226
 
182
- virid 将异常视为系统的一等公民:
227
+ #### `MessageWriter`
183
228
 
184
- - **自动封装**:任何 System 或 Hook 中的同步/异步异常,都会被 Dispatcher 自动捕获并封装为 `ErrorMessage`。
185
- - **防御式编程**:你可以定义一个 `ErrorSystem` 统一处理这些消息(如发送 Sentry 日志或触发 UI 告警),确保核心逻辑引擎永远不会因为单一组件的崩溃而宕机。
229
+ - **功能**:全局静态通讯工具。
230
+ - **API**:
231
+ - `MessageWriter.write(MessageClass, ...args)`: 发送消息的底层入口。
232
+ - `MessageWriter.error(Error, context?)`: 抛出一个系统级错误,它会自动触发 `ErrorMessage`。
233
+ - `MessageWriter.warn(context)`: 写入一个警告,他会自动触发`WarnMessage`。
234
+ - `MessageWriter.info(context)`: 写入一个信息,它会自动触发 `InfoMessage`。
186
235
 
187
- ---
236
+ ------
188
237
 
189
- ## 🚀 结语:为什么是 virid?
238
+ ## 🔬 进阶:原子化修改 (Atomic Operations)
190
239
 
191
- virid 不是在重复造一个状态库,它是在为 Web 开发引入一套**具备强确定性的工业标准**。
240
+ #### `AtomicModifyMessage`
192
241
 
193
- 当你的项目从几十个组件增长到几千个,当你的业务逻辑从简单的 CRUD 变成复杂的跨组件联动时,virid 的架构将确保你的代码依然:**逻辑可寻迹、修改可预期、测试可脱离 UI。**
242
+ - **功能**:提供一种“即插即用”的临时逻辑修改方案。
243
+ - **场景**:当你需要对某个 `Component` 进行一次性的观察或微调,又不想专门写一个 `System` 时,可以使用此消息在下一帧执行一段闭包逻辑。
244
+ - **示例**:
194
245
 
246
+ ```ts
247
+ AtomicModifyMessage.send(
248
+ CounterComponent,
249
+ (comp) => {
250
+ console.log("----------------AtomicModifyMessage------------------");
251
+ },
252
+ "Check CounterComponent",
253
+ );
195
254
  ```
196
- 数据流转示意图
197
- User -->|Dispatch| Writer[MessageWriter]
198
- Writer -->|Middleware| Hub[EventHub: Staging]
199
- Hub -->|Tick/Flip| Active[EventHub: Active]
200
- Active -->|Execute| System[System/Hook]
201
- System -->|Update| Component[Raw Component Data]
202
- Component -->|Reactive| UI[Vue/React View]
203
- ```
255
+
package/dist/index.cjs ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @virid/core v0.0.1
3
+ * A lightweight and powerful message core built using dependency injection and CCS concepts
4
+ */
5
+ var C=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var de=Object.getOwnPropertyNames;var fe=Object.prototype.hasOwnProperty;var pe=(s,e,t)=>e in s?C(s,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):s[e]=t;var o=(s,e)=>C(s,"name",{value:e,configurable:!0});var ge=(s,e)=>{for(var t in e)C(s,t,{get:e[t],enumerable:!0})},me=(s,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of de(e))!fe.call(s,n)&&n!==t&&C(s,n,{get:()=>e[n],enumerable:!(r=ue(e,n))||r.enumerable});return s};var ye=s=>me(C({},"__esModule",{value:!0}),s);var i=(s,e,t)=>pe(s,typeof e!="symbol"?e+"":e,t);var He={};ge(He,{AtomicModifyMessage:()=>w,BaseMessage:()=>y,Component:()=>$e,Controller:()=>Ae,ErrorMessage:()=>v,EventMessage:()=>p,InfoMessage:()=>S,Message:()=>we,MessageInternal:()=>M,MessageRegistry:()=>E,MessageWriter:()=>a,Observer:()=>Me,Safe:()=>Ee,SingleMessage:()=>x,System:()=>ke,VIRID_METADATA:()=>g,WarnMessage:()=>b,activateInstance:()=>J,bindObservers:()=>R,createVirid:()=>Ce,handleResult:()=>A,publisher:()=>oe});module.exports=ye(He);var j=class j{static send(...e){a.write(this,...e)}};o(j,"BaseMessage");var y=j,L=class L extends y{constructor(){super();i(this,"__kind","SingleMessage")}};o(L,"SingleMessage");var x=L,W=class W extends y{constructor(){super();i(this,"__kind","EventMessage")}};o(W,"EventMessage");var p=W,F=class F extends p{constructor(t,r){super();i(this,"error");i(this,"context");this.error=t,this.context=r}};o(F,"ErrorMessage");var v=F,Q=class Q extends p{constructor(t){super();i(this,"context");this.context=t}};o(Q,"WarnMessage");var b=Q,z=class z extends p{constructor(t){super();i(this,"context");this.context=t}};o(z,"InfoMessage");var S=z,U=class U extends p{constructor(t,r,n){super();i(this,"ComponentClass");i(this,"recipe");i(this,"label");this.ComponentClass=t,this.recipe=r,this.label=n}};o(U,"AtomicModifyMessage");var w=U;var D=null;function J(s){D=s}o(J,"activateInstance");var oe=new Proxy({},{get(s,e){return e==="dispatch"?t=>{if(!D){console.error(`[Virid] Message dispatched before system init: ${t.constructor.name}`);return}return D.dispatch(t)}:Reflect.get(D||{},e)}}),Y=class Y{static write(e,...t){let r=typeof e=="function"?new e(...t):e;oe.dispatch(r)}static error(e,t=""){this.write(new v(e,t))}static warn(e){this.write(new b(e))}static info(e){this.write(new S(e))}};o(Y,"MessageWriter");var a=Y;var q=class q{constructor(e){i(this,"dirtySignalTypes",new Set);i(this,"eventQueue",[]);i(this,"isRunning",!1);i(this,"globalTick",0);i(this,"internalDepth",0);i(this,"eventHub");i(this,"tickPayload",{});i(this,"beforeExecuteHooks",[]);i(this,"afterExecuteHooks",[]);i(this,"beforeTickHooks",[]);i(this,"afterTickHooks",[]);this.eventHub=e}addBeforeExecute(e,t,r){r?this.beforeExecuteHooks.unshift({type:e,handler:t}):this.beforeExecuteHooks.push({type:e,handler:t})}addAfterExecute(e,t,r){r?this.afterExecuteHooks.unshift({type:e,handler:t}):this.afterExecuteHooks.push({type:e,handler:t})}addBeforeTick(e,t){t?this.beforeTickHooks.unshift(e):this.beforeTickHooks.push(e)}addAfterTick(e,t){t?this.afterTickHooks.unshift(e):this.afterTickHooks.push(e)}markDirty(e){e instanceof p?this.eventQueue.push(e):e instanceof x&&this.dirtySignalTypes.add(e.constructor)}tick(e){if(!(this.isRunning||this.dirtySignalTypes.size===0&&this.eventQueue.length===0)){if(this.internalDepth>100){this.internalDepth=0,this.dirtySignalTypes.clear(),this.eventQueue=[],this.eventHub.reset(),a.error(new Error("[Virid Dispatcher] Deadlock: Recursive loop detected \u{1F4A5}."));return}this.isRunning=!0,this.internalDepth++,queueMicrotask(()=>{let t,r;try{this.internalDepth==0&&(this.tickPayload={},this.executeTickHooks(this.beforeTickHooks));let n=this.prepareSnapshot();t=n.signalSnapshot,r=n.eventSnapshot;let u=this.collectTasks(r,t,e);this.executeTasks(u)}catch(n){a.error(n,"[Virid Dispatcher] Unhandled Error")}finally{t&&r&&this.clear(r,t),this.isRunning=!1,this.dirtySignalTypes.size>0||this.eventQueue.length>0?this.tick(e):(this.executeTickHooks(this.afterTickHooks),this.globalTick++,this.internalDepth=0)}})}}collectTasks(e,t,r){let n=[];for(let l of e)(r.get(l.constructor)||[]).forEach(f=>{n.push(new P(f.fn,f.priority,l,{context:f.fn.systemContext,tick:this.globalTick,payload:{}}))});let u=new Set;for(let l of t)(r.get(l)||[]).forEach(f=>{u.has(f.fn)||(n.push(new P(f.fn,f.priority,this.eventHub.peekSignal(l),{context:f.fn.systemContext,tick:this.globalTick,payload:{}})),u.add(f.fn))});return n}executeTasks(e){e.sort((t,r)=>r.priority-t.priority);for(let t of e)try{let r=t.execute(this.beforeExecuteHooks,this.afterExecuteHooks);r instanceof Promise&&r.catch(n=>a.error(n,`[Virid Dispatcher]: Async System Error.
6
+ SystemLocation: ${t.hookContext.context.targetClass.name}.${t.hookContext.context.methodName}
7
+ MessageName: ${t.message.constructor.name}
8
+ MessageData: ${JSON.stringify(t.message)}`))}catch(r){a.error(r,`[Virid Dispatcher]: Sync System Error.
9
+ SystemLocation: ${t.hookContext.context.targetClass.name}.${t.hookContext.context.methodName}
10
+ MessageName: ${t.message.constructor.name}
11
+ MessageData: ${JSON.stringify(t.message)}`)}}prepareSnapshot(){this.eventHub.flip();let e=new Set(this.dirtySignalTypes),t=[...this.eventQueue];return this.dirtySignalTypes.clear(),this.eventQueue=[],{signalSnapshot:e,eventSnapshot:t}}clear(e,t){let r=new Set(t);e.forEach(n=>r.add(n.constructor)),this.eventHub.clearSignals(r),this.eventHub.clearEvents()}executeTickHooks(e){let t={tick:this.globalTick,timestamp:Date.now(),payload:this.tickPayload};e.forEach(r=>r(t))}};o(q,"Dispatcher");var O=q,K=class K{constructor(e,t,r,n){i(this,"fn");i(this,"priority");i(this,"message");i(this,"hookContext");this.fn=e,this.priority=t,this.message=r,this.hookContext=n}triggerHooks(e){let t=Array.isArray(this.message)?this.message[0]:this.message;if(t){for(let r of e)if(t instanceof r.type)try{let n=r.handler(this.message,this.hookContext);n instanceof Promise&&n.catch(u=>{a.error(u,`[Virid Hook] Async Hook Error:
12
+ It is prohibited to use asynchronous hooks within Hook:
13
+ ${r.type.name}`)})}catch(n){a.error(n,`[Virid Hook] Hook Execute Failed:
14
+ Triggered by: ${t.constructor.name}
15
+ Registered type: ${r.type.name}`)}}}execute(e,t){this.triggerHooks(e);let r=o(()=>this.triggerHooks(t),"runAfter");try{let n=this.fn(this.message);return n instanceof Promise?n.finally(()=>r()):(r(),n)}catch(n){throw r(),n}}};o(K,"ExecutionTask");var P=K;var X=class X{constructor(){i(this,"signalActive",new Map);i(this,"signalStaging",new Map);i(this,"eventActive",[]);i(this,"eventStaging",[])}push(e){if(e instanceof x){let t=e.constructor;this.signalStaging.has(t)||this.signalStaging.set(t,[]),this.signalStaging.get(t).push(e)}else e instanceof p?this.eventStaging.push(e):a.error(new Error(`[Virid Message] Invalid Message:
16
+ ${e.constructor.name} must extend SingleMessage or EventMessage`))}flip(){this.signalActive=this.signalStaging,this.signalStaging=new Map,this.eventActive=this.eventStaging,this.eventStaging=[]}peekSignal(e){return this.signalActive.get(e)||[]}getEventStream(){return this.eventActive}peekEventAt(e){return this.eventActive[e]}clearSignals(e){e.forEach(t=>this.signalActive.delete(t))}clearEvents(){this.eventActive=[]}reset(){this.signalActive.clear(),this.signalStaging.clear(),this.eventActive=[],this.eventStaging=[]}};o(X,"EventHub");var N=X;var Z=class Z{constructor(){i(this,"systemTaskMap",new Map)}register(e,t,r=0){let n=this.systemTaskMap.get(e)||[];if(n.findIndex(l=>l.fn===t)===-1)n.push({fn:t,priority:r}),n.sort((l,d)=>d.priority-l.priority),this.systemTaskMap.set(e,n);else{let l=t.name||"Anonymous";return a.error(new Error(`[Virid Error] System Already Registered:
17
+ Class ${e.name}
18
+ Function ${l}`)),()=>{}}return()=>{let l=this.systemTaskMap.get(e);if(l){let d=l.findIndex(f=>f.fn===t);d!==-1&&(l.splice(d,1),l.length===0&&this.systemTaskMap.delete(e))}}}};o(Z,"MessageRegistry");var E=Z;var ee=class ee{constructor(){i(this,"eventHub",new N);i(this,"dispatcher",new O(this.eventHub));i(this,"registry",new E);i(this,"middlewares",[]);J(this)}useMiddleware(e,t){this.middlewares.push(e)}onBeforeExecute(e,t,r){this.dispatcher.addBeforeExecute(e,t,r)}onAfterExecute(e,t,r){this.dispatcher.addAfterExecute(e,t,r)}onBeforeTick(e,t){this.dispatcher.addBeforeTick(e,t)}onAfterTick(e,t){this.dispatcher.addAfterTick(e,t)}dispatch(e){if(!(e instanceof y)){a.error(new Error(`[Virid Dispatch] Type Error: Message must be an instance of BaseMessage,message:${e}`));return}this.pipeline(e,()=>{if(!this.registry.systemTaskMap.has(e.constructor)){a.error(new Error(`[Virid Dispatch] No handler for message: ${e.constructor.name}`));return}this.eventHub.push(e),this.dispatcher.markDirty(e),this.dispatcher.tick(this.registry.systemTaskMap)})}pipeline(e,t){let r=0,n=o(()=>{r<this.middlewares.length?this.middlewares[r++](e,n):t()},"next");n()}register(e,t,r=0){return this.registry.register(e,t,r)}};o(ee,"MessageInternal");var M=ee;var te=class te{constructor(){i(this,"bindings",new Map);i(this,"singletonInstances",new Map)}bind(e){let t={type:"transient",ctor:e};return this.bindings.set(e,t),{toSelf:o(()=>({inSingletonScope:o(()=>(t.type="singleton",{onActivation:o(r=>{},"onActivation")}),"inSingletonScope")}),"toSelf")}}get(e,t){let r=this.bindings.get(e);if(!r)throw new Error(`[Virid Container] Unbound Constructor: No binding found for ${e.name}`);let n=r.ctor;if(r.type==="singleton"){if(!this.singletonInstances.has(e)){let l=new n,d=t(l);this.singletonInstances.set(e,d)}return this.singletonInstances.get(e)}let u=new n;return t(u)}};o(te,"ViridContainer");var _=te;var c={reset:"\x1B[0m",red:"\x1B[31m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",cyan:"\x1B[36m",gray:"\x1B[90m",bold:"\x1B[1m",green:"\x1B[32m"};function B(s,e,t){let r={params:s,targetClass:Object,methodName:t,originalMethod:e};return e.ccsContext=r,e}o(B,"withContext");var xe=o(s=>{let e=`${c.green}${c.bold} \u2714 [Virid Info] ${c.reset}`,t=`${c.magenta}${s.context}${c.reset}`;console.log(`${e}${c.gray}Global Info Caught:${c.reset}
19
+ ${c.green}Details:${c.reset}`,s.context||"unknown Info")},"globalInfoHandler"),ve=o(s=>{let e=`${c.red}${c.bold} \u2716 [Virid Error] ${c.reset}`,t=`${c.magenta}${s.context}${c.reset}`;console.error(`${e}${c.gray}Global Error Caught:${c.reset}
20
+ ${c.red}Context:${c.reset} ${t}
21
+ ${c.red}Details:${c.reset}`,s.error||s||"unknown Error")},"globalErrorHandler"),be=o(s=>{let e=`${c.yellow}${c.bold} \u26A0 [Virid Warn] ${c.reset}`,t=`${c.cyan}${s.context}${c.reset}`;console.warn(`${e}${c.gray}Global Warn Caught:${c.reset}
22
+ ${c.yellow}Context:${c.reset} ${t}`)},"globalWarnHandler"),Se=o(s=>{let e=H.get(s.ComponentClass);if(!e){console.error(`[Virid Modify] Component Not Found:
23
+ Component ${s.ComponentClass.name} not found in Registry.`);return}try{s.recipe(e),a.warn(`[Virid Modify] Successfully:
24
+ Modify on ${s.ComponentClass.name}
25
+ label: ${s.label}`)}catch(t){a.error(t,`[Virid Error] Modify Failed:
26
+ ${s.label}`)}},"atomicModifyHandler");function ie(s){s.register(w,B(w,Se,"GlobalAtomicModifier"),1e3),s.register(b,B(b,be,"GlobalWarnHandler"),-999),s.register(v,B(v,ve,"GlobalErrorHandler"),-999),s.register(S,B(S,xe,"GlobalInfoHandler"),-999),H=s}o(ie,"initializeGlobalSystems");var H=null,ht=new Proxy({},{get(s,e){return(...t)=>{if(!H){console.warn(`[Virid Vue] App method "${String(e)}" called before initialization.`);return}let r=H[e];if(typeof r=="function")return r.apply(H,t)}}});var ae=new Set,se=class se{constructor(){i(this,"container",new _);i(this,"messageInternal",new M);i(this,"activationHooks",[])}addActivationHook(e){this.activationHooks.push(e)}get(e){return e.length>0&&a.error(new Error(`[Virid Container] Violation: Component "${e.name}" should not have constructor arguments. Dependency Injection is only allowed in Systems.`)),this.container.get(e,t=>this.handleActivation(t))}handleActivation(e){return e&&this.activationHooks.reduce((t,r)=>{try{let n=r(t);return n===void 0&&a.warn(`[Virid Container] Hook Does Bot Return A Value: Hook "${r.name}" should return a instance to continue.`),n!==void 0?n:t}catch(n){return a.error(n,"[Virid Container] Activation Hook Failed"),t}},e)}bindController(e){return this.container.bind(e).toSelf(),{inSingletonScope:o(()=>({onActivation:o(()=>{},"onActivation")}),"inSingletonScope")}}bindComponent(e){return this.container.bind(e).toSelf().inSingletonScope(),{onActivation:o(()=>{},"onActivation")}}useMiddleware(e,t=!1){this.messageInternal.useMiddleware(e,t)}onBeforeExecute(e,t,r=!1){this.messageInternal.onBeforeExecute(e,t,r)}onAfterExecute(e,t,r=!1){this.messageInternal.onAfterExecute(e,t,r)}onBeforeTick(e,t=!1){this.messageInternal.onBeforeTick(e,t)}onAfterTick(e,t=!1){this.messageInternal.onAfterTick(e,t)}register(e,t,r=0){return this.messageInternal.register(e,t,r)}use(e,t){if(ae.has(e.name))return a.warn(`[Virid Plugin] Duplicate Installation: Plugin ${e.name} has already been installed.`),this;try{e.install(this,t),ae.add(e.name)}catch(r){a.error(r,`[Virid Plugin]: Install Failed: ${e.name}`)}return this}};o(se,"ViridApp");var re=se,k=new re;k.addActivationHook(R);ie(k);var g={SYSTEM:"virid:core:system",MESSAGE:"virid:core:message",CONTROLLER:"virid:core:controller",COMPONENT:"virid:core:component",SAFE:"virid:core:safe",OBSERVER:"virid:core:observer"};var A=o(s=>{if(!s)return;(Array.isArray(s)?s:[s]).forEach(t=>{t instanceof y?a.write(t):a.warn("[Virid HandleResult] Invalid Return Type: Must return Message or Message[].")})},"handleResult");function ke(s={priority:0,messageClass:null}){return(e,t,r)=>{let n=r.value,u=Reflect.getMetadata("design:paramtypes",e,t),l=Reflect.getMetadata(g.MESSAGE,e,t)||null;if(!u){let h=new Error(`[Virid System] System Parameter Loss:
27
+ Unable to recognize system parameters, please confirm if import "reflection-metadata" was introduced at the beginning!`);a.error(h);return}if(u.some(h=>h===void 0)){let h=new Error(`[Virid System] Parameter Metadata Loss in "${t}":
28
+ One or more parameters have 'undefined' types.
29
+ This usually happens when you forget to add a type annotation to a decorated parameter.
30
+ Check parameter at index: ${u.indexOf(void 0)}`);a.error(h);return}if(s.messageClass&&l){a.error(new Error(`[Virid System] Multiple Messages Are Not Allowed: Cannot use @ message() and SystemParams simultaneously in ${t}`));return}if(!s.messageClass&&!l){a.error(new Error(`[Virid System] System Parameter Loss:
31
+ Please declare the message type using the Message decorator`));return}let d=o(h=>{let $=u.map((V,ce)=>{if(l&&l.index==ce){let{messageClass:G,single:le}=l,I=Array.isArray(h)?h[0]:h;if(!(I instanceof G)){let he=I.constructor.name;throw new Error(`[Virid System] Type Mismatch: Expected ${G.name}, but received ${he}`)}if(I instanceof x)return le?Array.isArray(h)?h[h.length-1]:h:Array.isArray(h)?h:[h];if(I instanceof p)return h;throw new Error(`[Virid System] unknown Message Types: Message ${G.name} is not a subclass of SingleMessage or EventMessage!`)}let ne=k.get(V);if(!ne)throw new Error(`[Virid System] unknown Inject Data Types: ${V.name} is not registered in the container!`);return ne}),T=n.apply(e,$);return T instanceof Promise?T.then(A):A(T)},"wrappedSystem"),f={params:u,targetClass:e,methodName:t,originalMethod:n};d.systemContext=f,r.value=d;let m=s.messageClass||l.messageClass;k.register(m,d,s.priority)}}o(ke,"System");function we(s,e=!0){return(t,r,n)=>{if(Reflect.hasOwnMetadata(g.MESSAGE,t,r)){a.error(new Error(`[Virid Message] Multiple Messages Are Not Allowed: ${r} has multiple @Message() decorators!`));return}let u={index:n,messageClass:s,single:e};Reflect.defineMetadata(g.MESSAGE,u,t,r)}}o(we,"Message");function Ee(){return(s,e,t)=>{let r=Reflect.getMetadata(g.SAFE,s)||new Set;r.add(e),Reflect.defineMetadata(g.SAFE,r,s)}}o(Ee,"Safe");function Me(s,[]){return(e,t)=>{let r=Reflect.getMetadata(g.OBSERVER,e)||[];r.push({key:t,callback:s}),Reflect.defineMetadata(g.OBSERVER,r,e)}}o(Me,"Observer");function Ae(){return s=>{Reflect.defineMetadata(g.CONTROLLER,!0,s)}}o(Ae,"Controller");function $e(){return s=>{Reflect.defineMetadata(g.COMPONENT,!0,s)}}o($e,"Component");var Te=["push","pop","shift","unshift","splice","sort","reverse"];function R(s){return!s||typeof s!="object"||Object.prototype.hasOwnProperty.call(s,"__virid_observer_processed__")||(Object.defineProperty(s,"__virid_observer_processed__",{value:!0,enumerable:!1,configurable:!0}),(Reflect.getMetadata(g.OBSERVER,s.constructor)||[]).forEach(({propertyKey:t,callback:r})=>{let n={value:s[t]},u=new Proxy(n,{get(d,f){let m=d.value;return Array.isArray(m)&&Te.includes(f)?(...h)=>{let $=[...m],T=m[f].apply(m,h),V=r.call(s,$,m);return A(V),T}:m},set(d,f,m){let h=d.value;if(m===h)return!0;d.value=m;let $=r.call(s,h,m);return A($),!0}}),l=o(()=>u.value,"getter");l.__virid_box__=n,Object.defineProperty(s,t,{get:l,set:o(d=>{u.value=d},"set"),enumerable:!0,configurable:!0}),n.value&&typeof n.value=="object"&&R(n.value)}),Reflect.ownKeys(s).forEach(t=>{if(t==="__virid_observer_processed__")return;let r=Object.getOwnPropertyDescriptor(s,t);if(r&&r.get)return;let n=s[t];n&&typeof n=="object"&&R(n)})),s}o(R,"bindObservers");function Ce(){return k}o(Ce,"createVirid");0&&(module.exports={AtomicModifyMessage,BaseMessage,Component,Controller,ErrorMessage,EventMessage,InfoMessage,Message,MessageInternal,MessageRegistry,MessageWriter,Observer,Safe,SingleMessage,System,VIRID_METADATA,WarnMessage,activateInstance,bindObservers,createVirid,handleResult,publisher});
32
+ //# sourceMappingURL=index.cjs.map