@virid/vue 0.0.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.md +294 -0
- package/README.zh.md +279 -0
- package/dist/index.d.mts +63 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +559 -0
- package/dist/index.mjs +525 -0
- package/package.json +37 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { SingleMessage, ViridPlugin } from '@virid/core';
|
|
2
|
+
export { CCSSystemContext } from '@virid/core';
|
|
3
|
+
import { WatchOptions } from 'vue';
|
|
4
|
+
|
|
5
|
+
declare abstract class ControllerMessage extends SingleMessage {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @description:实现Watch
|
|
10
|
+
* 用法:@Watch('a.b.c') 或 @Watch(instance => instance.a.b.c)
|
|
11
|
+
*/
|
|
12
|
+
declare function Watch<T>(source: (instance: T) => any, options?: WatchOptions): any;
|
|
13
|
+
declare function Watch<C>(component: new (...args: any[]) => C, source: (comp: C) => any, options?: WatchOptions): any;
|
|
14
|
+
/**
|
|
15
|
+
* @description: 实现数据投影
|
|
16
|
+
* 用法:@Project() 或 @Project('a.b.c')
|
|
17
|
+
*/
|
|
18
|
+
declare function Project<T>(source: (instance: T) => any): any;
|
|
19
|
+
declare function Project<C>(component: new (...args: any[]) => C, source: (comp: C) => any): any;
|
|
20
|
+
/**
|
|
21
|
+
* @description: 给数据增加响应式
|
|
22
|
+
* 用法:@Responsive()
|
|
23
|
+
*/
|
|
24
|
+
declare function Responsive(shallow?: boolean): (target: any, propertyKey: string) => void;
|
|
25
|
+
/**
|
|
26
|
+
* @description: 声明式生命周期钩子
|
|
27
|
+
* 用法:@OnHook("onMounted")
|
|
28
|
+
*/
|
|
29
|
+
declare function OnHook(hookName: "onMounted" | "onUnmounted" | "onUpdated" | "onActivated" | "onDeactivated" | "onSetup"): (target: any, methodName: string) => void;
|
|
30
|
+
/**
|
|
31
|
+
* @description: 万能 Hook 注入装饰器
|
|
32
|
+
* 用法:@Use(() => useRoute()) public route!: RouteLocationNormalized
|
|
33
|
+
*/
|
|
34
|
+
declare function Use(hookFactory: () => any): (target: any, propertyKey: string) => void;
|
|
35
|
+
/**
|
|
36
|
+
* @description: Inherit注入装饰器
|
|
37
|
+
* 用法:@Inherit(Contronller,(instance) => instance.xxxx) public data!: SomeType
|
|
38
|
+
*/
|
|
39
|
+
declare function Inherit<T>(token: new (...args: any[]) => T, id: string, selector?: (instance: T) => any): (target: any, propertyKey: string) => void;
|
|
40
|
+
/**
|
|
41
|
+
* @description: 标记一个属性是从外部环境(context)注入的
|
|
42
|
+
* 纯元数据标记,什么也不干,方便后期做自动化文档或 TS 类型提示
|
|
43
|
+
*/
|
|
44
|
+
declare function Env(): (_target: any, _propertyKey: string) => void;
|
|
45
|
+
/**
|
|
46
|
+
* @description: Listener 装饰器 - 标记 Controller 的成员方法为消息监听器
|
|
47
|
+
* 模仿 Bevy 的即时响应机制,但严格限制其只能处理 UI 逻辑
|
|
48
|
+
*/
|
|
49
|
+
declare function Listener<T extends ControllerMessage>(eventClass: new (...args: any[]) => T, priority?: number, single?: boolean): (target: any, propertyKey: string) => void;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @description: vue的hooks适配器,注入IOC容器中的Controller实例,并挂在vue的各种方法
|
|
53
|
+
* @param token
|
|
54
|
+
* @return {*}
|
|
55
|
+
*/
|
|
56
|
+
declare function useController<T>(token: new (...args: any[]) => T, options?: {
|
|
57
|
+
id?: string;
|
|
58
|
+
context?: any;
|
|
59
|
+
}): T;
|
|
60
|
+
|
|
61
|
+
declare const VuePlugin: ViridPlugin;
|
|
62
|
+
|
|
63
|
+
export { ControllerMessage, Env, Inherit, Listener, OnHook, Project, Responsive, Use, VuePlugin, Watch, useController };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ControllerMessage: () => ControllerMessage,
|
|
24
|
+
Env: () => Env,
|
|
25
|
+
Inherit: () => Inherit,
|
|
26
|
+
Listener: () => Listener,
|
|
27
|
+
OnHook: () => OnHook,
|
|
28
|
+
Project: () => Project,
|
|
29
|
+
Responsive: () => Responsive,
|
|
30
|
+
Use: () => Use,
|
|
31
|
+
VuePlugin: () => VuePlugin,
|
|
32
|
+
Watch: () => Watch,
|
|
33
|
+
useController: () => useController
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// decorators/constants.ts
|
|
38
|
+
var virid_METADATA = {
|
|
39
|
+
COMPONENT: "virid:component",
|
|
40
|
+
CONTROLLER: "virid:controller",
|
|
41
|
+
PROJECT: "virid:project_metadata",
|
|
42
|
+
WATCH: "virid:watch_metadata",
|
|
43
|
+
MESSAGE: "virid:message",
|
|
44
|
+
RESPONSIVE: "virid:responsive",
|
|
45
|
+
LIFE_CRICLE: "virid:life_cricle",
|
|
46
|
+
USE_HOOKS: "virid:use_hooks",
|
|
47
|
+
CONTROLLER_LISTENERS: "virid:controller_listeners",
|
|
48
|
+
INHERIT: "virid:inherit",
|
|
49
|
+
ATTR: "virid:attr"
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// decorators/vue.ts
|
|
53
|
+
function Watch(arg1, arg2, arg3) {
|
|
54
|
+
return (target, methodName) => {
|
|
55
|
+
const existing = Reflect.getMetadata(virid_METADATA.WATCH, target) || [];
|
|
56
|
+
if (typeof arg2 === "function") {
|
|
57
|
+
existing.push({
|
|
58
|
+
type: "component",
|
|
59
|
+
componentClass: arg1,
|
|
60
|
+
source: arg2,
|
|
61
|
+
options: arg3,
|
|
62
|
+
methodName
|
|
63
|
+
});
|
|
64
|
+
} else {
|
|
65
|
+
existing.push({
|
|
66
|
+
type: "local",
|
|
67
|
+
source: arg1,
|
|
68
|
+
options: arg2,
|
|
69
|
+
methodName
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
Reflect.defineMetadata(virid_METADATA.WATCH, existing, target);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
__name(Watch, "Watch");
|
|
76
|
+
function Project(arg1, arg2) {
|
|
77
|
+
return (target, propertyKey, descriptor) => {
|
|
78
|
+
const existing = Reflect.getMetadata(virid_METADATA.PROJECT, target) || [];
|
|
79
|
+
const metadata = {
|
|
80
|
+
propertyKey,
|
|
81
|
+
isAccessor: !!(descriptor?.get || descriptor?.set),
|
|
82
|
+
// 这里的逻辑和 Watch 保持高度一致
|
|
83
|
+
type: typeof arg2 === "function" ? "component" : "local",
|
|
84
|
+
componentClass: typeof arg2 === "function" ? arg1 : null,
|
|
85
|
+
source: typeof arg2 === "function" ? arg2 : arg1
|
|
86
|
+
};
|
|
87
|
+
existing.push(metadata);
|
|
88
|
+
Reflect.defineMetadata(virid_METADATA.PROJECT, existing, target);
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
__name(Project, "Project");
|
|
92
|
+
function Responsive(shallow = false) {
|
|
93
|
+
return (target, propertyKey) => {
|
|
94
|
+
const props = Reflect.getMetadata(virid_METADATA.RESPONSIVE, target) || [];
|
|
95
|
+
props.push({
|
|
96
|
+
propertyKey,
|
|
97
|
+
shallow
|
|
98
|
+
});
|
|
99
|
+
Reflect.defineMetadata(virid_METADATA.RESPONSIVE, props, target);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
__name(Responsive, "Responsive");
|
|
103
|
+
function OnHook(hookName) {
|
|
104
|
+
return (target, methodName) => {
|
|
105
|
+
const existing = Reflect.getMetadata(virid_METADATA.LIFE_CRICLE, target) || [];
|
|
106
|
+
existing.push({
|
|
107
|
+
hookName,
|
|
108
|
+
methodName
|
|
109
|
+
});
|
|
110
|
+
Reflect.defineMetadata(virid_METADATA.LIFE_CRICLE, existing, target);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
__name(OnHook, "OnHook");
|
|
114
|
+
function Use(hookFactory) {
|
|
115
|
+
return (target, propertyKey) => {
|
|
116
|
+
const existing = Reflect.getMetadata(virid_METADATA.USE_HOOKS, target) || [];
|
|
117
|
+
existing.push({
|
|
118
|
+
propertyKey,
|
|
119
|
+
hookFactory
|
|
120
|
+
});
|
|
121
|
+
Reflect.defineMetadata(virid_METADATA.USE_HOOKS, existing, target);
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
__name(Use, "Use");
|
|
125
|
+
function Inherit(token, id, selector) {
|
|
126
|
+
return (target, propertyKey) => {
|
|
127
|
+
const metadata = Reflect.getMetadata(virid_METADATA.INHERIT, target) || [];
|
|
128
|
+
metadata.push({
|
|
129
|
+
propertyKey,
|
|
130
|
+
token,
|
|
131
|
+
id,
|
|
132
|
+
selector
|
|
133
|
+
});
|
|
134
|
+
Reflect.defineMetadata(virid_METADATA.INHERIT, metadata, target);
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
__name(Inherit, "Inherit");
|
|
138
|
+
function Env() {
|
|
139
|
+
return (_target, _propertyKey) => {
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
__name(Env, "Env");
|
|
143
|
+
function Listener(eventClass, priority = 0, single = true) {
|
|
144
|
+
return (target, propertyKey) => {
|
|
145
|
+
const listeners = Reflect.getMetadata(virid_METADATA.CONTROLLER_LISTENERS, target) || [];
|
|
146
|
+
listeners.push({
|
|
147
|
+
propertyKey,
|
|
148
|
+
eventClass,
|
|
149
|
+
priority,
|
|
150
|
+
single
|
|
151
|
+
});
|
|
152
|
+
Reflect.defineMetadata(virid_METADATA.CONTROLLER_LISTENERS, listeners, target);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
__name(Listener, "Listener");
|
|
156
|
+
|
|
157
|
+
// decorators/types.ts
|
|
158
|
+
var import_core = require("@virid/core");
|
|
159
|
+
var ControllerMessage = class extends import_core.SingleMessage {
|
|
160
|
+
static {
|
|
161
|
+
__name(this, "ControllerMessage");
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// adapters/bind.ts
|
|
166
|
+
var import_vue = require("vue");
|
|
167
|
+
var import_core2 = require("@virid/core");
|
|
168
|
+
|
|
169
|
+
// app.ts
|
|
170
|
+
var activeApp = null;
|
|
171
|
+
function activateApp(instance) {
|
|
172
|
+
activeApp = instance;
|
|
173
|
+
}
|
|
174
|
+
__name(activateApp, "activateApp");
|
|
175
|
+
var viridApp = new Proxy({}, {
|
|
176
|
+
get(_, prop) {
|
|
177
|
+
return (...args) => {
|
|
178
|
+
if (!activeApp) {
|
|
179
|
+
console.warn(`[Virid Vue] App method "${String(prop)}" called before initialization.`);
|
|
180
|
+
if (prop === "register") {
|
|
181
|
+
return () => {
|
|
182
|
+
console.warn("[Virid Vue] Cleanup ignored: source listener was never registered.");
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
return void 0;
|
|
186
|
+
}
|
|
187
|
+
const targetMethod = activeApp[prop];
|
|
188
|
+
if (typeof targetMethod === "function") {
|
|
189
|
+
return targetMethod.apply(activeApp, args);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
// adapters/bind.ts
|
|
196
|
+
var GlobalRegistry = class {
|
|
197
|
+
static {
|
|
198
|
+
__name(this, "GlobalRegistry");
|
|
199
|
+
}
|
|
200
|
+
static globalRegistry = (0, import_vue.shallowReactive)(/* @__PURE__ */ new Map());
|
|
201
|
+
static set(id, instance) {
|
|
202
|
+
if (!this.globalRegistry.has(id)) {
|
|
203
|
+
this.globalRegistry.set(id, instance);
|
|
204
|
+
return () => {
|
|
205
|
+
this.globalRegistry.delete(id);
|
|
206
|
+
return true;
|
|
207
|
+
};
|
|
208
|
+
} else {
|
|
209
|
+
import_core2.MessageWriter.error(new Error(`[Virid UseController] Duplicate ID: Controller ${id} already exists`));
|
|
210
|
+
return () => false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
static get(id) {
|
|
214
|
+
if (!this.globalRegistry.has(id)) {
|
|
215
|
+
import_core2.MessageWriter.error(new Error(`[Virid UseController] ID Not Found: No Controller found with ID: ${id}`));
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
return this.globalRegistry.get(id);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
function bindProject(proto, instance, rawDeps) {
|
|
222
|
+
const projects = Reflect.getMetadata(virid_METADATA.PROJECT, proto);
|
|
223
|
+
projects?.forEach((config) => {
|
|
224
|
+
const { propertyKey, isAccessor, type, componentClass, source } = config;
|
|
225
|
+
let c;
|
|
226
|
+
let setter = /* @__PURE__ */ __name(() => {
|
|
227
|
+
import_core2.MessageWriter.error(new Error(`[Virid Shield] Property "${propertyKey}" is read-only.
|
|
228
|
+
If you need to mutate, define an explicit setter and ensure the dependency is injected.`));
|
|
229
|
+
}, "setter");
|
|
230
|
+
const getTarget = /* @__PURE__ */ __name(() => {
|
|
231
|
+
const target = type === "component" ? viridApp.get(componentClass) : instance;
|
|
232
|
+
if (target && !target.__ccs_processed__) {
|
|
233
|
+
bindResponsive(target);
|
|
234
|
+
}
|
|
235
|
+
return target;
|
|
236
|
+
}, "getTarget");
|
|
237
|
+
if (isAccessor) {
|
|
238
|
+
const rawDescriptor = Object.getOwnPropertyDescriptor(proto, propertyKey);
|
|
239
|
+
if (rawDescriptor?.set) {
|
|
240
|
+
import_core2.MessageWriter.warn(`[Virid Project] Possible Implicit Modification:
|
|
241
|
+
Manual Set on "${propertyKey}".If this is not intentional, please do not use set.`);
|
|
242
|
+
setter = /* @__PURE__ */ __name((val) => {
|
|
243
|
+
const elevatedContext = new Proxy(instance, {
|
|
244
|
+
get(target, key) {
|
|
245
|
+
if (typeof key === "string" && rawDeps[key]) {
|
|
246
|
+
return rawDeps[key];
|
|
247
|
+
}
|
|
248
|
+
return Reflect.get(target, key);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
rawDescriptor?.set?.call(elevatedContext, val);
|
|
252
|
+
}, "setter");
|
|
253
|
+
}
|
|
254
|
+
c = (0, import_vue.computed)({
|
|
255
|
+
get: /* @__PURE__ */ __name(() => {
|
|
256
|
+
return rawDescriptor?.get?.call(instance);
|
|
257
|
+
}, "get"),
|
|
258
|
+
set: setter
|
|
259
|
+
});
|
|
260
|
+
} else {
|
|
261
|
+
c = (0, import_vue.computed)(() => {
|
|
262
|
+
const target = getTarget();
|
|
263
|
+
return source(target);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
const currentDescriptor = Object.getOwnPropertyDescriptor(instance, propertyKey);
|
|
267
|
+
if (currentDescriptor && currentDescriptor.configurable === false) return;
|
|
268
|
+
Object.defineProperty(instance, propertyKey, {
|
|
269
|
+
get: /* @__PURE__ */ __name(() => c.value, "get"),
|
|
270
|
+
set: /* @__PURE__ */ __name((val) => c.value = val, "set"),
|
|
271
|
+
enumerable: true,
|
|
272
|
+
configurable: true
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
__name(bindProject, "bindProject");
|
|
277
|
+
function bindWatch(proto, instance) {
|
|
278
|
+
const watches = Reflect.getMetadata(virid_METADATA.WATCH, proto) || [];
|
|
279
|
+
const stops = [];
|
|
280
|
+
watches.forEach((config) => {
|
|
281
|
+
const { type, source, methodName, options, componentClass } = config;
|
|
282
|
+
const target = type === "component" ? viridApp.get(componentClass) : instance;
|
|
283
|
+
if (target && !target.__ccs_processed__) {
|
|
284
|
+
bindResponsive(target);
|
|
285
|
+
}
|
|
286
|
+
const getter = /* @__PURE__ */ __name(() => {
|
|
287
|
+
try {
|
|
288
|
+
return source(target);
|
|
289
|
+
} catch (e) {
|
|
290
|
+
import_core2.MessageWriter.error(e, `[Virid Watch] Getter error in ${methodName}`);
|
|
291
|
+
return void 0;
|
|
292
|
+
}
|
|
293
|
+
}, "getter");
|
|
294
|
+
const callback = instance[methodName].bind(instance);
|
|
295
|
+
const stop = (0, import_vue.watch)(getter, (newVal, oldVal) => {
|
|
296
|
+
callback(newVal, oldVal);
|
|
297
|
+
}, {
|
|
298
|
+
...options
|
|
299
|
+
});
|
|
300
|
+
stops.push(stop);
|
|
301
|
+
});
|
|
302
|
+
return stops;
|
|
303
|
+
}
|
|
304
|
+
__name(bindWatch, "bindWatch");
|
|
305
|
+
function bindResponsive(instance) {
|
|
306
|
+
if (!instance || typeof instance !== "object") return;
|
|
307
|
+
if (Object.prototype.hasOwnProperty.call(instance, "__ccs_processed__")) return;
|
|
308
|
+
Object.defineProperty(instance, "__ccs_processed__", {
|
|
309
|
+
value: true,
|
|
310
|
+
enumerable: false
|
|
311
|
+
});
|
|
312
|
+
const props = Reflect.getMetadata(virid_METADATA.RESPONSIVE, instance) || [];
|
|
313
|
+
props.forEach((config) => {
|
|
314
|
+
const key = config.propertyKey;
|
|
315
|
+
const rawValue = instance[key];
|
|
316
|
+
const descriptor = Object.getOwnPropertyDescriptor(instance, key);
|
|
317
|
+
if (descriptor && descriptor.get) return;
|
|
318
|
+
const internalState = config.shallow ? (0, import_vue.shallowRef)(rawValue) : (0, import_vue.ref)(rawValue);
|
|
319
|
+
Object.defineProperty(instance, key, {
|
|
320
|
+
get: /* @__PURE__ */ __name(() => internalState.value, "get"),
|
|
321
|
+
set: /* @__PURE__ */ __name((val) => {
|
|
322
|
+
internalState.value = val;
|
|
323
|
+
}, "set"),
|
|
324
|
+
enumerable: true,
|
|
325
|
+
configurable: true
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
Reflect.ownKeys(instance).forEach((key) => {
|
|
329
|
+
if (key === "__ccs_processed__") return;
|
|
330
|
+
const val = instance[key];
|
|
331
|
+
if (val && typeof val === "object" && !(0, import_vue.isRef)(val)) {
|
|
332
|
+
bindResponsive(val);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
__name(bindResponsive, "bindResponsive");
|
|
337
|
+
function createDeepShield(target, rootName, path = "") {
|
|
338
|
+
if (target === null || typeof target !== "object") {
|
|
339
|
+
return target;
|
|
340
|
+
}
|
|
341
|
+
if (target.__ccs_shield__) return target;
|
|
342
|
+
return new Proxy(target, {
|
|
343
|
+
get(obj, prop) {
|
|
344
|
+
if (prop === "__ccs_shield__") return true;
|
|
345
|
+
if (prop === "__raw__") return obj;
|
|
346
|
+
const value = Reflect.get(obj, prop);
|
|
347
|
+
const currentPath = path ? `${path}.${String(prop)}` : String(prop);
|
|
348
|
+
return createDeepShield(value, rootName, currentPath);
|
|
349
|
+
},
|
|
350
|
+
set(_obj, prop) {
|
|
351
|
+
const currentPath = path ? `${path}.${String(prop)}` : String(prop);
|
|
352
|
+
const errorMsg = [
|
|
353
|
+
`[Virid DeepShield]`,
|
|
354
|
+
`------------------------------------------------`,
|
|
355
|
+
`Component: ${rootName}`,
|
|
356
|
+
`Code: this.${rootName}.${currentPath}`,
|
|
357
|
+
`Result: Rejected`,
|
|
358
|
+
`Repair suggestion: Please use @ Project (${currentPath}) to create a projection in the Controller.`,
|
|
359
|
+
`------------------------------------------------`
|
|
360
|
+
].join("\n");
|
|
361
|
+
import_core2.MessageWriter.error(new Error(errorMsg));
|
|
362
|
+
return false;
|
|
363
|
+
},
|
|
364
|
+
deleteProperty(_obj, prop) {
|
|
365
|
+
import_core2.MessageWriter.error(new Error(`[Virid DeepShield] Physical Protection:
|
|
366
|
+
Prohibit Deletion of Component Attributes ${String(prop)}`));
|
|
367
|
+
return false;
|
|
368
|
+
},
|
|
369
|
+
// 拦截 Object.defineProperty 等底层操作
|
|
370
|
+
defineProperty() {
|
|
371
|
+
import_core2.MessageWriter.error(new Error(`[Virid DeepShield] Physical Protection:
|
|
372
|
+
Prohibit redefining component attribute structure`));
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
__name(createDeepShield, "createDeepShield");
|
|
378
|
+
function bindHooks(proto, instance) {
|
|
379
|
+
const hooks = Reflect.getMetadata(virid_METADATA.LIFE_CRICLE, proto);
|
|
380
|
+
hooks?.forEach((config) => {
|
|
381
|
+
const { hookName, methodName } = config;
|
|
382
|
+
const fn = instance[methodName].bind(instance);
|
|
383
|
+
switch (hookName) {
|
|
384
|
+
case "onMounted":
|
|
385
|
+
(0, import_vue.onMounted)(fn);
|
|
386
|
+
break;
|
|
387
|
+
case "onUnmounted":
|
|
388
|
+
(0, import_vue.onUnmounted)(fn);
|
|
389
|
+
break;
|
|
390
|
+
case "onUpdated":
|
|
391
|
+
(0, import_vue.onUpdated)(fn);
|
|
392
|
+
break;
|
|
393
|
+
case "onActivated":
|
|
394
|
+
(0, import_vue.onActivated)(fn);
|
|
395
|
+
break;
|
|
396
|
+
case "onDeactivated":
|
|
397
|
+
(0, import_vue.onDeactivated)(fn);
|
|
398
|
+
break;
|
|
399
|
+
case "onSetup":
|
|
400
|
+
fn();
|
|
401
|
+
break;
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
__name(bindHooks, "bindHooks");
|
|
406
|
+
function bindUseHooks(proto, instance) {
|
|
407
|
+
const hooks = Reflect.getMetadata(virid_METADATA.USE_HOOKS, proto);
|
|
408
|
+
hooks?.forEach((config) => {
|
|
409
|
+
const hookResult = config.hookFactory();
|
|
410
|
+
instance[config.propertyKey] = hookResult;
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
__name(bindUseHooks, "bindUseHooks");
|
|
414
|
+
function bindListener(proto, instance) {
|
|
415
|
+
const listenerConfigs = Reflect.getMetadata(virid_METADATA.CONTROLLER_LISTENERS, proto) || [];
|
|
416
|
+
const unbindFunctions = [];
|
|
417
|
+
listenerConfigs.forEach(({ propertyKey, eventClass, priority, single }) => {
|
|
418
|
+
const originalMethod = instance[propertyKey];
|
|
419
|
+
const wrappedHandler = /* @__PURE__ */ __name(function(msgs) {
|
|
420
|
+
const message = single && Array.isArray(msgs) ? msgs[msgs.length - 1] : msgs;
|
|
421
|
+
if (msgs.length > 0) {
|
|
422
|
+
originalMethod.apply(instance, [
|
|
423
|
+
message
|
|
424
|
+
]);
|
|
425
|
+
}
|
|
426
|
+
}, "wrappedHandler");
|
|
427
|
+
const taskContext = {
|
|
428
|
+
params: eventClass,
|
|
429
|
+
targetClass: instance.constructor,
|
|
430
|
+
methodName: propertyKey,
|
|
431
|
+
originalMethod
|
|
432
|
+
};
|
|
433
|
+
wrappedHandler.ccsContext = taskContext;
|
|
434
|
+
const unregister = viridApp.register(eventClass, wrappedHandler, priority);
|
|
435
|
+
unbindFunctions.push(unregister);
|
|
436
|
+
});
|
|
437
|
+
return unbindFunctions;
|
|
438
|
+
}
|
|
439
|
+
__name(bindListener, "bindListener");
|
|
440
|
+
function bindInherit(proto, instance) {
|
|
441
|
+
const inherits = Reflect.getMetadata(virid_METADATA.INHERIT, proto);
|
|
442
|
+
if (!inherits) return;
|
|
443
|
+
inherits.forEach(({ propertyKey, token, id, selector }) => {
|
|
444
|
+
const tunnel = (0, import_vue.computed)(() => {
|
|
445
|
+
const target = GlobalRegistry.get(id);
|
|
446
|
+
if (!target) {
|
|
447
|
+
import_core2.MessageWriter.warn(`[Virid Inherit] Warning:
|
|
448
|
+
Inherit target not found: ${id}`);
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
return selector ? selector(target) : target;
|
|
452
|
+
});
|
|
453
|
+
Object.defineProperty(instance, propertyKey, {
|
|
454
|
+
get: /* @__PURE__ */ __name(() => {
|
|
455
|
+
const val = tunnel.value;
|
|
456
|
+
return val ? createDeepShield(val, propertyKey, "") : null;
|
|
457
|
+
}, "get"),
|
|
458
|
+
set: /* @__PURE__ */ __name(() => {
|
|
459
|
+
import_core2.MessageWriter.error(new Error(`[Virid Inherit] No Modification:
|
|
460
|
+
Attempted to set read-only Inherit property: ${propertyKey}`));
|
|
461
|
+
}, "set"),
|
|
462
|
+
enumerable: true,
|
|
463
|
+
configurable: true
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
__name(bindInherit, "bindInherit");
|
|
468
|
+
|
|
469
|
+
// adapters/hooks.ts
|
|
470
|
+
var import_vue2 = require("vue");
|
|
471
|
+
var import_core3 = require("@virid/core");
|
|
472
|
+
function useController(token, options) {
|
|
473
|
+
const instance = viridApp.get(token);
|
|
474
|
+
bindResponsive(instance);
|
|
475
|
+
const reactiveContext = options?.context || (0, import_vue2.useAttrs)();
|
|
476
|
+
if (reactiveContext) {
|
|
477
|
+
injectContext(reactiveContext, instance);
|
|
478
|
+
}
|
|
479
|
+
const isController = Reflect.hasMetadata(virid_METADATA.CONTROLLER, token);
|
|
480
|
+
const rawDeps = {};
|
|
481
|
+
if (isController) {
|
|
482
|
+
Object.keys(instance).forEach((key) => {
|
|
483
|
+
const dep = instance[key];
|
|
484
|
+
if (dep && typeof dep === "object" && dep.constructor) {
|
|
485
|
+
if (Reflect.hasMetadata(virid_METADATA.COMPONENT, dep.constructor)) {
|
|
486
|
+
rawDeps[key] = dep;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
const proto = Object.getPrototypeOf(instance);
|
|
492
|
+
bindProject(proto, instance, rawDeps);
|
|
493
|
+
bindUseHooks(proto, instance);
|
|
494
|
+
const stops = bindWatch(proto, instance);
|
|
495
|
+
const unbindList = bindListener(proto, instance);
|
|
496
|
+
if (isController) {
|
|
497
|
+
Object.keys(rawDeps).forEach((key) => {
|
|
498
|
+
instance[key] = createDeepShield(rawDeps[key], key, "");
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
bindHooks(proto, instance);
|
|
502
|
+
bindInherit(proto, instance);
|
|
503
|
+
let unbindRegister = /* @__PURE__ */ __name(() => true, "unbindRegister");
|
|
504
|
+
if (options?.id) {
|
|
505
|
+
unbindRegister = GlobalRegistry.set(options?.id, instance);
|
|
506
|
+
}
|
|
507
|
+
(0, import_vue2.onUnmounted)(() => {
|
|
508
|
+
stops.forEach((stop) => stop());
|
|
509
|
+
unbindList.forEach((unreg) => unreg());
|
|
510
|
+
unbindRegister();
|
|
511
|
+
});
|
|
512
|
+
return instance;
|
|
513
|
+
}
|
|
514
|
+
__name(useController, "useController");
|
|
515
|
+
function injectContext(context, instance) {
|
|
516
|
+
if (context && typeof context === "object") {
|
|
517
|
+
Object.keys(context).forEach((key) => {
|
|
518
|
+
Object.defineProperty(instance, key, {
|
|
519
|
+
// Getter 确保了 @Watch 的依赖收集能一路穿透到 Vue 源头
|
|
520
|
+
get: /* @__PURE__ */ __name(() => context[key], "get"),
|
|
521
|
+
// 处理写入逻辑
|
|
522
|
+
set: /* @__PURE__ */ __name((val) => {
|
|
523
|
+
if (context[key] === val) return;
|
|
524
|
+
try {
|
|
525
|
+
context[key] = val;
|
|
526
|
+
} catch (e) {
|
|
527
|
+
import_core3.MessageWriter.error(e, `[Virid Context] Set Failed:
|
|
528
|
+
"${key}" is only readable.`);
|
|
529
|
+
}
|
|
530
|
+
}, "set"),
|
|
531
|
+
enumerable: true,
|
|
532
|
+
configurable: true
|
|
533
|
+
});
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
__name(injectContext, "injectContext");
|
|
538
|
+
|
|
539
|
+
// index.ts
|
|
540
|
+
var VuePlugin = {
|
|
541
|
+
name: "@virid/vue",
|
|
542
|
+
install(app, _options) {
|
|
543
|
+
activateApp(app);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
547
|
+
0 && (module.exports = {
|
|
548
|
+
ControllerMessage,
|
|
549
|
+
Env,
|
|
550
|
+
Inherit,
|
|
551
|
+
Listener,
|
|
552
|
+
OnHook,
|
|
553
|
+
Project,
|
|
554
|
+
Responsive,
|
|
555
|
+
Use,
|
|
556
|
+
VuePlugin,
|
|
557
|
+
Watch,
|
|
558
|
+
useController
|
|
559
|
+
});
|