@virid/core 0.0.1 → 0.1.0

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/dist/index.mjs DELETED
@@ -1,674 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
-
4
- // app.ts
5
- import { Container } from "inversify";
6
-
7
- // message/types.ts
8
- var BaseMessage = class {
9
- static {
10
- __name(this, "BaseMessage");
11
- }
12
- static send(...args) {
13
- MessageWriter.write(this, ...args);
14
- }
15
- senderInfo;
16
- constructor() {
17
- }
18
- };
19
- var SingleMessage = class extends BaseMessage {
20
- static {
21
- __name(this, "SingleMessage");
22
- }
23
- // @ts-ignore 只用来区分的标识符
24
- __kind = "SingleMessage";
25
- constructor() {
26
- super();
27
- }
28
- };
29
- var EventMessage = class extends BaseMessage {
30
- static {
31
- __name(this, "EventMessage");
32
- }
33
- // @ts-ignore 只用来区分的标识符
34
- __kind = "EventMessage";
35
- constructor() {
36
- super();
37
- }
38
- };
39
- var ErrorMessage = class extends EventMessage {
40
- static {
41
- __name(this, "ErrorMessage");
42
- }
43
- error;
44
- context;
45
- constructor(error, context) {
46
- super(), this.error = error, this.context = context;
47
- }
48
- };
49
- var WarnMessage = class extends EventMessage {
50
- static {
51
- __name(this, "WarnMessage");
52
- }
53
- context;
54
- constructor(context) {
55
- super(), this.context = context;
56
- }
57
- };
58
- var AtomicModifyMessage = class extends EventMessage {
59
- static {
60
- __name(this, "AtomicModifyMessage");
61
- }
62
- ComponentClass;
63
- recipe;
64
- label;
65
- constructor(ComponentClass, recipe, label) {
66
- super(), this.ComponentClass = ComponentClass, this.recipe = recipe, this.label = label;
67
- }
68
- };
69
-
70
- // message/io.ts
71
- var activeInstance = null;
72
- function activatInstance(instance) {
73
- activeInstance = instance;
74
- }
75
- __name(activatInstance, "activatInstance");
76
- var publisher = new Proxy({}, {
77
- get(_, prop) {
78
- if (prop === "dispatch") {
79
- return (message) => {
80
- if (!activeInstance) {
81
- console.error(`[Virid] Message dispatched before system init: ${message.constructor.name}`);
82
- return;
83
- }
84
- return activeInstance.dispatch(message);
85
- };
86
- }
87
- return Reflect.get(activeInstance || {}, prop);
88
- }
89
- });
90
- var MessageWriter = class {
91
- static {
92
- __name(this, "MessageWriter");
93
- }
94
- /**
95
- * 核心入口:无论是类还是实例,统一交给 Internal 处理
96
- */
97
- static write(target, ...args) {
98
- const instance = typeof target === "function" ? new target(...args) : target;
99
- publisher.dispatch(instance);
100
- }
101
- /**
102
- * 快捷方式:系统内部常用
103
- */
104
- static error(e, context) {
105
- this.write(new ErrorMessage(e, context));
106
- }
107
- static warn(context) {
108
- this.write(new WarnMessage(context));
109
- }
110
- };
111
-
112
- // message/dispatcher.ts
113
- var ExecutionTask = class {
114
- static {
115
- __name(this, "ExecutionTask");
116
- }
117
- fn;
118
- priority;
119
- message;
120
- context;
121
- constructor(fn, priority, message, context) {
122
- this.fn = fn;
123
- this.priority = priority;
124
- this.message = message;
125
- this.context = context;
126
- }
127
- triggerHooks(hooks) {
128
- const sample = Array.isArray(this.message) ? this.message[0] : this.message;
129
- if (!sample) return;
130
- for (const hook of hooks) {
131
- if (sample instanceof hook.type) {
132
- try {
133
- const result = hook.handler(this.message, this.context);
134
- if (result instanceof Promise) {
135
- result.catch((e) => MessageWriter.error(e, `[Virid Hook] Async Hook Error:
136
- ${hook.type.name}`));
137
- }
138
- } catch (e) {
139
- MessageWriter.error(e, `[Virid Hook] Hook Execute Failed:
140
- Triggered by: ${sample.constructor.name}
141
- Registered type: ${hook.type.name}`);
142
- }
143
- }
144
- }
145
- }
146
- execute(beforeHooks, afterHooks) {
147
- this.triggerHooks(beforeHooks);
148
- const runAfter = /* @__PURE__ */ __name(() => this.triggerHooks(afterHooks), "runAfter");
149
- try {
150
- const result = this.fn(this.message);
151
- if (result instanceof Promise) {
152
- return result.finally(() => runAfter());
153
- }
154
- runAfter();
155
- return result;
156
- } catch (e) {
157
- runAfter();
158
- throw e;
159
- }
160
- }
161
- };
162
- var Dispatcher = class {
163
- static {
164
- __name(this, "Dispatcher");
165
- }
166
- dirtySignalTypes = /* @__PURE__ */ new Set();
167
- eventQueue = [];
168
- isRunning = false;
169
- tickCount = 0;
170
- eventHub;
171
- // 使用 MessageIdentifier 允许存入 BaseMessage, SingleMessage 等抽象类
172
- beforeHooks = [];
173
- afterHooks = [];
174
- constructor(eventHub) {
175
- this.eventHub = eventHub;
176
- }
177
- // 添加执行钩子
178
- addBefore(type, hook) {
179
- this.beforeHooks.push({
180
- type,
181
- handler: hook
182
- });
183
- }
184
- addAfter(type, hook) {
185
- this.afterHooks.push({
186
- type,
187
- handler: hook
188
- });
189
- }
190
- cleanupHook = /* @__PURE__ */ __name(() => {
191
- }, "cleanupHook");
192
- setCleanupHook(hook) {
193
- this.cleanupHook = hook;
194
- }
195
- /**
196
- * 标记脏数据:根据基类判断进入哪个池子
197
- */
198
- markDirty(message) {
199
- if (message instanceof EventMessage) {
200
- this.eventQueue.push(message);
201
- } else if (message instanceof SingleMessage) {
202
- this.dirtySignalTypes.add(message.constructor);
203
- }
204
- }
205
- tick(interestMap) {
206
- if (this.isRunning || this.dirtySignalTypes.size === 0 && this.eventQueue.length === 0) return;
207
- if (this.tickCount > 100) {
208
- this.tickCount = 0;
209
- this.dirtySignalTypes.clear();
210
- this.eventQueue = [];
211
- this.eventHub.reset();
212
- MessageWriter.error(new Error("[Virid Dispatcher] Deadlock: Recursive loop detected."));
213
- return;
214
- }
215
- this.isRunning = true;
216
- this.tickCount++;
217
- queueMicrotask(() => {
218
- try {
219
- this.eventHub.flip();
220
- const signalSnapshot = new Set(this.dirtySignalTypes);
221
- const eventSnapshot = [
222
- ...this.eventQueue
223
- ];
224
- this.dirtySignalTypes.clear();
225
- this.eventQueue = [];
226
- const tasks = [];
227
- for (const msg of eventSnapshot) {
228
- const systems = interestMap.get(msg.constructor) || [];
229
- systems.forEach((s) => {
230
- tasks.push(new ExecutionTask(s.fn, s.priority, msg, s.fn.ccsContext));
231
- });
232
- }
233
- const signalFnSet = /* @__PURE__ */ new Set();
234
- for (const type of signalSnapshot) {
235
- const systems = interestMap.get(type) || [];
236
- systems.forEach((s) => {
237
- if (!signalFnSet.has(s.fn)) {
238
- tasks.push(new ExecutionTask(s.fn, s.priority, this.eventHub.peekSignal(type), s.fn.ccsContext));
239
- signalFnSet.add(s.fn);
240
- }
241
- });
242
- }
243
- tasks.sort((a, b) => b.priority - a.priority);
244
- for (const task of tasks) {
245
- try {
246
- const result = task.execute(this.beforeHooks, this.afterHooks);
247
- if (result instanceof Promise) {
248
- result.catch((e) => MessageWriter.error(e, `[Virid Dispatcher] Async Error:
249
- targetClass:${task.context.targetClass}
250
- methodName:${task.context.methodName}
251
- `));
252
- }
253
- } catch (e) {
254
- MessageWriter.error(e, `[Virid Dispatcher] Sync Error:
255
- targetClass:${task.context.targetClass}
256
- methodName:${task.context.methodName}
257
- `);
258
- }
259
- }
260
- const processedTypes = new Set(signalSnapshot);
261
- eventSnapshot.forEach((m) => processedTypes.add(m.constructor));
262
- this.cleanupHook(processedTypes);
263
- this.isRunning = false;
264
- if (this.dirtySignalTypes.size > 0 || this.eventQueue.length > 0) {
265
- this.tick(interestMap);
266
- } else {
267
- this.tickCount = 0;
268
- }
269
- } catch (e) {
270
- MessageWriter.error(e, "[Virid Dispatcher] Unhandled Error");
271
- }
272
- });
273
- }
274
- };
275
-
276
- // message/eventHub.ts
277
- var EventHub = class {
278
- static {
279
- __name(this, "EventHub");
280
- }
281
- // --- SIGNAL 存储 (分类池) ---
282
- signalActive = /* @__PURE__ */ new Map();
283
- signalStaging = /* @__PURE__ */ new Map();
284
- // --- EVENT 存储 (顺序流) ---
285
- eventActive = [];
286
- eventStaging = [];
287
- /**
288
- * 写入逻辑:根据消息策略分流
289
- */
290
- push(event) {
291
- if (event instanceof SingleMessage) {
292
- const type = event.constructor;
293
- if (!this.signalStaging.has(type)) this.signalStaging.set(type, []);
294
- this.signalStaging.get(type).push(event);
295
- } else if (event instanceof EventMessage) {
296
- this.eventStaging.push(event);
297
- } else {
298
- MessageWriter.error(new Error(`[Virid Message] Invalid Message:
299
- ${event.constructor.name} must extend SingleMessage or EventMessage`));
300
- }
301
- }
302
- /**
303
- * 翻转缓冲区:在 Dispatcher 的 Tick 开始时调用
304
- */
305
- flip() {
306
- this.signalActive = this.signalStaging;
307
- this.signalStaging = /* @__PURE__ */ new Map();
308
- this.eventActive = this.eventStaging;
309
- this.eventStaging = [];
310
- }
311
- /**
312
- * [SIGNAL专用] 批量读取某种类型的信号
313
- */
314
- peekSignal(type) {
315
- return this.signalActive.get(type) || [];
316
- }
317
- /**
318
- * [EVENT专用] 获取当前所有待处理的事件流
319
- */
320
- getEventStream() {
321
- return this.eventActive;
322
- }
323
- /**
324
- * [新增] 根据索引精准读取 EVENT 里的某个数据
325
- * 配合 Dispatcher 逐条分发时使用
326
- */
327
- peekEventAt(index) {
328
- return this.eventActive[index];
329
- }
330
- /**
331
- * 清理已处理的内容
332
- */
333
- clearSignals(types) {
334
- types.forEach((type) => this.signalActive.delete(type));
335
- }
336
- clearEvents() {
337
- this.eventActive = [];
338
- }
339
- /**
340
- * 重置所有池子
341
- */
342
- reset() {
343
- this.signalActive.clear();
344
- this.signalStaging.clear();
345
- this.eventActive = [];
346
- this.eventStaging = [];
347
- }
348
- };
349
-
350
- // message/registry.ts
351
- var MessageRegistry = class {
352
- static {
353
- __name(this, "MessageRegistry");
354
- }
355
- interestMap = /* @__PURE__ */ new Map();
356
- /**
357
- * 注册消息并返回一个卸载函数
358
- * 这种模式能完美适配 Controller 的生命周期销毁
359
- */
360
- register(eventClass, systemFn, priority = 0) {
361
- const systems = this.interestMap.get(eventClass) || [];
362
- const existingIndex = systems.findIndex((s) => s.fn === systemFn);
363
- if (existingIndex === -1) {
364
- systems.push({
365
- fn: systemFn,
366
- priority
367
- });
368
- systems.sort((a, b) => b.priority - a.priority);
369
- this.interestMap.set(eventClass, systems);
370
- } else {
371
- const funcName = systemFn.name || "Anonymous";
372
- MessageWriter.error(new Error(`[Virid Error] System Already Registered:
373
- Class ${eventClass.name}
374
- Function ${funcName}`));
375
- return () => {
376
- };
377
- }
378
- return () => {
379
- const currentSystems = this.interestMap.get(eventClass);
380
- if (currentSystems) {
381
- const index = currentSystems.findIndex((s) => s.fn === systemFn);
382
- if (index !== -1) {
383
- currentSystems.splice(index, 1);
384
- if (currentSystems.length === 0) {
385
- this.interestMap.delete(eventClass);
386
- }
387
- }
388
- }
389
- };
390
- }
391
- };
392
-
393
- // message/internal.ts
394
- var MessageInternal = class {
395
- static {
396
- __name(this, "MessageInternal");
397
- }
398
- eventHub = new EventHub();
399
- dispatcher = new Dispatcher(this.eventHub);
400
- registry = new MessageRegistry();
401
- middlewares = [];
402
- constructor() {
403
- this.dispatcher.setCleanupHook((processedTypes) => {
404
- this.eventHub.clearSignals(processedTypes);
405
- this.eventHub.clearEvents();
406
- });
407
- activatInstance(this);
408
- }
409
- useMiddleware(mw) {
410
- this.middlewares.push(mw);
411
- }
412
- onBeforeExecute(type, hook) {
413
- this.dispatcher.addBefore(type, hook);
414
- }
415
- onAfterExecute(type, hook) {
416
- this.dispatcher.addAfter(type, hook);
417
- }
418
- /**
419
- * 消息进入系统的唯一入口
420
- */
421
- dispatch(message) {
422
- if (!this.registry.interestMap.has(message.constructor)) {
423
- MessageWriter.error(new Error(`[Virid Dispatch] No handler for message: ${message.constructor.name}`));
424
- return;
425
- }
426
- this.pipeline(message, () => {
427
- this.eventHub.push(message);
428
- this.dispatcher.markDirty(message);
429
- this.dispatcher.tick(this.registry.interestMap);
430
- });
431
- }
432
- pipeline(message, finalAction) {
433
- let index = 0;
434
- const next = /* @__PURE__ */ __name(() => {
435
- if (index < this.middlewares.length) {
436
- this.middlewares[index++](message, next);
437
- } else {
438
- finalAction();
439
- }
440
- }, "next");
441
- next();
442
- }
443
- };
444
-
445
- // app.ts
446
- var installedPlugins = /* @__PURE__ */ new Set();
447
- var ViridApp = class {
448
- static {
449
- __name(this, "ViridApp");
450
- }
451
- container = new Container();
452
- messageInternal = new MessageInternal();
453
- bindBase(identifier) {
454
- return this.container.bind(identifier).toSelf();
455
- }
456
- get(identifier) {
457
- return this.container.get(identifier);
458
- }
459
- bindController(identifier) {
460
- return this.bindBase(identifier);
461
- }
462
- bindComponent(identifier) {
463
- return this.bindBase(identifier).inSingletonScope();
464
- }
465
- useMiddleware(mw) {
466
- this.messageInternal.useMiddleware(mw);
467
- }
468
- onBeforeExecute(type, hook) {
469
- this.messageInternal.onBeforeExecute(type, hook);
470
- }
471
- onAfterExecute(type, hook) {
472
- this.messageInternal.onAfterExecute(type, hook);
473
- }
474
- register(eventClass, systemFn, priority = 0) {
475
- return this.messageInternal.registry.register(eventClass, systemFn, priority);
476
- }
477
- use(plugin, options) {
478
- if (installedPlugins.has(plugin.name)) {
479
- MessageWriter.warn(`[Virid Plugin] Plugin ${plugin.name} has already been installed.`);
480
- return this;
481
- }
482
- try {
483
- plugin.install(this, options);
484
- installedPlugins.add(plugin.name);
485
- } catch (e) {
486
- MessageWriter.error(e, `[Virid Plugin] ${plugin.name}`);
487
- }
488
- return this;
489
- }
490
- };
491
- var viridApp = new ViridApp();
492
- function withContext(params, fn, methodName) {
493
- const context = {
494
- params,
495
- targetClass: Object,
496
- methodName,
497
- originalMethod: fn
498
- };
499
- fn.ccsContext = context;
500
- return fn;
501
- }
502
- __name(withContext, "withContext");
503
- var clr = {
504
- reset: "\x1B[0m",
505
- red: "\x1B[31m",
506
- yellow: "\x1B[33m",
507
- blue: "\x1B[34m",
508
- magenta: "\x1B[35m",
509
- cyan: "\x1B[36m",
510
- gray: "\x1B[90m",
511
- bold: "\x1B[1m"
512
- };
513
- var globalErrorHandler = /* @__PURE__ */ __name((err) => {
514
- const header = `${clr.red}${clr.bold} \u2716 [Virid Error] ${clr.reset}`;
515
- const context = `${clr.magenta}${err.context}${clr.reset}`;
516
- console.error(`${header}${clr.gray}Global Error Caught:${clr.reset}
517
- ${clr.red}Context:${clr.reset} ${context}
518
- ${clr.red}Details:${clr.reset}`, err.error || "Unknown Error");
519
- }, "globalErrorHandler");
520
- viridApp.register(ErrorMessage, withContext(ErrorMessage, globalErrorHandler, "GlobalErrorHandler"), -999);
521
- var globalWarnHandler = /* @__PURE__ */ __name((warn) => {
522
- const header = `${clr.yellow}${clr.bold} \u26A0 [Virid Warn] ${clr.reset}`;
523
- const context = `${clr.cyan}${warn.context}${clr.reset}`;
524
- console.warn(`${header}${clr.gray}Global Warn Caught:${clr.reset}
525
- ${clr.yellow}Context:${clr.reset} ${context}`);
526
- }, "globalWarnHandler");
527
- viridApp.register(WarnMessage, withContext(WarnMessage, globalWarnHandler, "GlobalWarnHandler"), -999);
528
- var atomicModifyHandler = /* @__PURE__ */ __name((modifications) => {
529
- const rawComponent = viridApp.container.get(modifications.ComponentClass);
530
- if (!rawComponent) {
531
- console.error(`[Virid Modify] Component Not Found:
532
- Component ${modifications.ComponentClass.name} not found in Registry.`);
533
- return;
534
- }
535
- try {
536
- modifications.recipe(rawComponent);
537
- MessageWriter.warn(`[Virid Modify] Successfully:
538
- Modify on ${modifications.ComponentClass.name}
539
- label: ${modifications.label}`);
540
- } catch (e) {
541
- MessageWriter.error(e, `[Virid Error] Modify Failed:
542
- ${modifications.label}`);
543
- }
544
- }, "atomicModifyHandler");
545
- viridApp.register(AtomicModifyMessage, withContext(AtomicModifyMessage, atomicModifyHandler, "GlobalAtomicModifier"), 1e3);
546
-
547
- // decorators/constants.ts
548
- var virid_METADATA = {
549
- SYSTEM: "virid:system_metadata",
550
- MESSAGE: "virid:message",
551
- CONTROLLER: "virid:controller",
552
- COMPONENT: "virid:component"
553
- };
554
-
555
- // decorators/ccs.ts
556
- import { injectable } from "inversify";
557
- import "reflect-metadata";
558
- function System(priority = 0) {
559
- return (target, key, descriptor) => {
560
- const originalMethod = descriptor.value;
561
- const types = Reflect.getMetadata("design:paramtypes", target, key) || [];
562
- if (types.length === 0) {
563
- MessageWriter.error(new Error(`[Virid System] System Parameter Loss:
564
- Unable to recognize system parameters, please confirm if import "reflection-metadata" was introduced at the beginning!`));
565
- }
566
- const readerConfigs = Reflect.getMetadata(virid_METADATA.MESSAGE, target, key) || [];
567
- if (readerConfigs.length > 1) {
568
- MessageWriter.warn(`[Virid System] Multiple Messages Are Not Allowed: ${key} has multiple @Message() decorators!`);
569
- return;
570
- }
571
- const wrappedSystem = /* @__PURE__ */ __name(function(currentMessage) {
572
- const args = types.map((type, index) => {
573
- const config = readerConfigs.find((c) => c.index === index);
574
- if (config) {
575
- const { eventClass, single } = config;
576
- const sample = Array.isArray(currentMessage) ? currentMessage[0] : currentMessage;
577
- if (!(sample instanceof eventClass)) {
578
- MessageWriter.error(new Error(`[Virid System] Type Mismatch: Expected ${eventClass.name}, but received ${sample?.constructor.name}`));
579
- return null;
580
- }
581
- if (sample instanceof SingleMessage) {
582
- if (single) {
583
- return Array.isArray(currentMessage) ? currentMessage[currentMessage.length - 1] : currentMessage;
584
- }
585
- return Array.isArray(currentMessage) ? currentMessage : [
586
- currentMessage
587
- ];
588
- }
589
- if (sample instanceof EventMessage) {
590
- return currentMessage;
591
- }
592
- return currentMessage;
593
- }
594
- const param = viridApp.get(type);
595
- if (!param) MessageWriter.error(new Error(`[Virid System] Unknown Inject Data Types: ${type.name} is not registered in the container!`));
596
- return param;
597
- });
598
- const result = originalMethod(...args);
599
- const handleResult = /* @__PURE__ */ __name((res) => {
600
- if (!res) return;
601
- const messages = Array.isArray(res) ? res : [
602
- res
603
- ];
604
- messages.forEach((m) => {
605
- if (m instanceof BaseMessage) {
606
- MessageWriter.write(m);
607
- }
608
- });
609
- }, "handleResult");
610
- return result instanceof Promise ? result.then(handleResult) : handleResult(result);
611
- }, "wrappedSystem");
612
- const taskContext = {
613
- params: types,
614
- targetClass: target,
615
- methodName: key,
616
- originalMethod
617
- };
618
- wrappedSystem.ccsContext = taskContext;
619
- descriptor.value = wrappedSystem;
620
- readerConfigs.forEach((config) => {
621
- viridApp.register(config.eventClass, wrappedSystem, priority);
622
- });
623
- };
624
- }
625
- __name(System, "System");
626
- function Message(eventClass, single = true) {
627
- return (target, key, index) => {
628
- const configs = Reflect.getMetadata(virid_METADATA.MESSAGE, target, key) || [];
629
- configs.push({
630
- index,
631
- eventClass,
632
- single
633
- });
634
- Reflect.defineMetadata(virid_METADATA.MESSAGE, configs, target, key);
635
- };
636
- }
637
- __name(Message, "Message");
638
- function Controller() {
639
- return (target) => {
640
- injectable()(target);
641
- Reflect.defineMetadata(virid_METADATA.CONTROLLER, true, target);
642
- };
643
- }
644
- __name(Controller, "Controller");
645
- function Component() {
646
- return (target) => {
647
- injectable()(target);
648
- Reflect.defineMetadata(virid_METADATA.COMPONENT, true, target);
649
- };
650
- }
651
- __name(Component, "Component");
652
-
653
- // index.ts
654
- function createVirid() {
655
- return viridApp;
656
- }
657
- __name(createVirid, "createVirid");
658
- export {
659
- AtomicModifyMessage,
660
- BaseMessage,
661
- Component,
662
- Controller,
663
- ErrorMessage,
664
- EventMessage,
665
- Message,
666
- MessageInternal,
667
- MessageWriter,
668
- SingleMessage,
669
- System,
670
- WarnMessage,
671
- activatInstance,
672
- createVirid,
673
- publisher
674
- };