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