@v-ibe/core 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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/DI/__tests__/scoped-container-dependencies.test.d.ts +1 -0
- package/dist/DI/bootstrap.d.ts +18 -0
- package/dist/DI/decorators/inject.d.ts +37 -0
- package/dist/DI/decorators/inject.js +45 -0
- package/dist/DI/decorators/service.d.ts +24 -0
- package/dist/DI/decorators/service.js +13 -0
- package/dist/DI/di-container.d.ts +53 -0
- package/dist/DI/di-container.js +158 -0
- package/dist/DI/lifecycle.d.ts +37 -0
- package/dist/DI/lifecycle.js +6 -0
- package/dist/DI/scoped-container.d.ts +68 -0
- package/dist/DI/scoped-container.js +193 -0
- package/dist/DI/service-metadata.d.ts +32 -0
- package/dist/DI/service-metadata.js +31 -0
- package/dist/DI/types.d.ts +4 -0
- package/dist/behaviors/__tests__/behavior-system.test.d.ts +1 -0
- package/dist/behaviors/behavior-manager.d.ts +60 -0
- package/dist/behaviors/behavior-manager.js +131 -0
- package/dist/behaviors/behavior-registry.d.ts +68 -0
- package/dist/behaviors/behavior-registry.js +105 -0
- package/dist/behaviors/constants.d.ts +16 -0
- package/dist/behaviors/constants.js +8 -0
- package/dist/behaviors/decorators.d.ts +87 -0
- package/dist/behaviors/decorators.js +46 -0
- package/dist/behaviors/index.d.ts +4 -0
- package/dist/components/__tests__/host.test.d.ts +1 -0
- package/dist/components/app-tree.d.ts +49 -0
- package/dist/components/app-tree.js +122 -0
- package/dist/components/base-component.d.ts +85 -0
- package/dist/components/base-component.js +438 -0
- package/dist/components/decorators/component.d.ts +27 -0
- package/dist/components/decorators/component.js +47 -0
- package/dist/components/decorators/prop.d.ts +14 -0
- package/dist/components/decorators/prop.js +37 -0
- package/dist/components/types.d.ts +26 -0
- package/dist/core.d.ts +23 -0
- package/dist/core.js +8 -0
- package/dist/custom-components/__tests__/for.test.d.ts +1 -0
- package/dist/custom-components/__tests__/show.test.d.ts +1 -0
- package/dist/custom-components/for.d.ts +58 -0
- package/dist/custom-components/for.js +313 -0
- package/dist/custom-components/index.d.ts +2 -0
- package/dist/custom-components/show.d.ts +78 -0
- package/dist/custom-components/show.js +88 -0
- package/dist/data-management/cache/cache-invalidate.decorator.d.ts +35 -0
- package/dist/data-management/cache/cache-invalidate.decorator.js +21 -0
- package/dist/data-management/cache/cache-metadata.d.ts +15 -0
- package/dist/data-management/cache/cache-provider.interface.d.ts +67 -0
- package/dist/data-management/cache/cache-tags.decorator.d.ts +52 -0
- package/dist/data-management/cache/cache-tags.decorator.js +13 -0
- package/dist/data-management/cache/cache-update.decorator.d.ts +28 -0
- package/dist/data-management/cache/cache-update.decorator.js +21 -0
- package/dist/data-management/cache/cache.decorator.d.ts +28 -0
- package/dist/data-management/cache/cache.decorator.js +13 -0
- package/dist/data-management/cache/index.d.ts +11 -0
- package/dist/data-management/cache/local-storage-cache.d.ts +40 -0
- package/dist/data-management/cache/local-storage-cache.js +268 -0
- package/dist/data-management/cache/memory-cache.d.ts +37 -0
- package/dist/data-management/cache/memory-cache.js +149 -0
- package/dist/data-management/cache/session-storage-cache.d.ts +35 -0
- package/dist/data-management/cache/session-storage-cache.js +242 -0
- package/dist/data-management/cache/ttl.decorator.d.ts +31 -0
- package/dist/data-management/cache/ttl.decorator.js +34 -0
- package/dist/data-management/decorators/consume.d.ts +29 -0
- package/dist/data-management/decorators/consume.js +28 -0
- package/dist/data-management/decorators/id.d.ts +28 -0
- package/dist/data-management/decorators/id.js +19 -0
- package/dist/data-management/decorators/model.d.ts +48 -0
- package/dist/data-management/decorators/model.js +24 -0
- package/dist/data-management/decorators/prop.d.ts +43 -0
- package/dist/data-management/decorators/prop.js +32 -0
- package/dist/data-management/index.d.ts +13 -0
- package/dist/data-management/store/json-to-model.d.ts +45 -0
- package/dist/data-management/store/json-to-model.js +36 -0
- package/dist/data-management/store/store.d.ts +108 -0
- package/dist/data-management/store/store.js +207 -0
- package/dist/data-management/store/types.d.ts +53 -0
- package/dist/events-handler/decorators/emit.d.ts +29 -0
- package/dist/events-handler/decorators/emit.js +51 -0
- package/dist/events-handler/event-decorators.d.ts +1 -0
- package/dist/events-handler/event-emitter.service.d.ts +21 -0
- package/dist/events-handler/event-emitter.service.js +85 -0
- package/dist/events-handler/event-types.d.ts +12 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +121 -0
- package/dist/jsx/dynamic/__tests__/granular-array-renderer.test.d.ts +1 -0
- package/dist/jsx/dynamic/__tests__/jsx-array-rendering.test.d.ts +1 -0
- package/dist/jsx/dynamic/array-renderer.d.ts +2 -0
- package/dist/jsx/dynamic/array-renderer.js +133 -0
- package/dist/jsx/dynamic/child-renderer.d.ts +1 -0
- package/dist/jsx/dynamic/child-renderer.js +180 -0
- package/dist/jsx/dynamic/dom-utils.d.ts +5 -0
- package/dist/jsx/dynamic/dom-utils.js +22 -0
- package/dist/jsx/dynamic/granular-array-renderer.d.ts +16 -0
- package/dist/jsx/dynamic/granular-array-renderer.js +153 -0
- package/dist/jsx/dynamic/node-renderer.d.ts +2 -0
- package/dist/jsx/dynamic/props-handler.d.ts +3 -0
- package/dist/jsx/dynamic/props-handler.js +281 -0
- package/dist/jsx/dynamic/text-renderer.d.ts +2 -0
- package/dist/jsx/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx/jsx-runtime.d.ts +3 -0
- package/dist/jsx/types.d.ts +35 -0
- package/dist/jsx/types.js +4 -0
- package/dist/jsx-dev-runtime.d.ts +2 -0
- package/dist/jsx-dev-runtime.js +8 -0
- package/dist/jsx-runtime.d.ts +2 -0
- package/dist/jsx-runtime.js +11 -0
- package/dist/reactivity/__tests__/context-stack.test.d.ts +1 -0
- package/dist/reactivity/__tests__/nested-effects-untrack.test.d.ts +22 -0
- package/dist/reactivity/context-scope.d.ts +57 -0
- package/dist/reactivity/context-scope.js +35 -0
- package/dist/reactivity/decorators/__tests__/ctx-integration.test.d.ts +5 -0
- package/dist/reactivity/decorators/__tests__/ctx-loop.test.d.ts +10 -0
- package/dist/reactivity/decorators/__tests__/state-intelligent.test.d.ts +1 -0
- package/dist/reactivity/decorators/computed.d.ts +6 -0
- package/dist/reactivity/decorators/computed.js +17 -0
- package/dist/reactivity/decorators/create-event-decorator.d.ts +5 -0
- package/dist/reactivity/decorators/create-event-decorator.js +28 -0
- package/dist/reactivity/decorators/ctx.d.ts +9 -0
- package/dist/reactivity/decorators/ctx.js +91 -0
- package/dist/reactivity/decorators/effect.d.ts +9 -0
- package/dist/reactivity/decorators/effect.js +24 -0
- package/dist/reactivity/decorators/resource.d.ts +48 -0
- package/dist/reactivity/decorators/resource.js +20 -0
- package/dist/reactivity/decorators/state.d.ts +8 -0
- package/dist/reactivity/decorators/state.js +68 -0
- package/dist/reactivity/decorators/store.d.ts +6 -0
- package/dist/reactivity/decorators/store.js +25 -0
- package/dist/reactivity/phase-scheduler.d.ts +81 -0
- package/dist/reactivity/phase-scheduler.js +88 -0
- package/dist/reactivity/phase-scheduler.test.d.ts +1 -0
- package/dist/reactivity/reactive-cache.d.ts +21 -0
- package/dist/reactivity/reactive-cache.js +31 -0
- package/dist/reactivity/reactive-cache.test.d.ts +1 -0
- package/dist/reactivity/reactive-context.d.ts +152 -0
- package/dist/reactivity/reactive-context.js +184 -0
- package/dist/reactivity/signals/__tests__/composicion-automatica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-1-estructura-basica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-2-registro-subscribers.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-3-notificaciones-basicas.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-4-comparacion-valores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-5-tracking-automatico.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-6-anti-glitch.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-7-objetos-anidados.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite/nivel-8-observable-array-support.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/composite-shallow-tracking.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/effect.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-1-estructura-basica.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-2-metodos-mutadores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-3-tracking-por-indice.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-4-tracking-length.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-5-tracking-mutation.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-6-metodos-no-mutadores.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-7-composicion-bidireccional.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-8-proxies.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/reactive-array/nivel-9-derived-cache-optimization.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/resource.test.d.ts +1 -0
- package/dist/reactivity/signals/__tests__/signal.test.d.ts +1 -0
- package/dist/reactivity/signals/array-strategies.d.ts +120 -0
- package/dist/reactivity/signals/array-strategies.js +261 -0
- package/dist/reactivity/signals/composite.d.ts +89 -0
- package/dist/reactivity/signals/composite.js +145 -0
- package/dist/reactivity/signals/computed.d.ts +61 -0
- package/dist/reactivity/signals/computed.js +107 -0
- package/dist/reactivity/signals/computed.test.d.ts +1 -0
- package/dist/reactivity/signals/derived.d.ts +10 -0
- package/dist/reactivity/signals/derived.js +24 -0
- package/dist/reactivity/signals/effect.d.ts +27 -0
- package/dist/reactivity/signals/effect.js +46 -0
- package/dist/reactivity/signals/event.d.ts +9 -0
- package/dist/reactivity/signals/event.js +15 -0
- package/dist/reactivity/signals/reactive-array.d.ts +133 -0
- package/dist/reactivity/signals/reactive-array.js +490 -0
- package/dist/reactivity/signals/reactive-proxy.d.ts +54 -0
- package/dist/reactivity/signals/reactive-proxy.js +299 -0
- package/dist/reactivity/signals/reactive-tracking.test.d.ts +1 -0
- package/dist/reactivity/signals/resource.d.ts +9 -0
- package/dist/reactivity/signals/resource.js +58 -0
- package/dist/reactivity/signals/signal.d.ts +39 -0
- package/dist/reactivity/signals/signal.js +56 -0
- package/dist/reactivity/signals/subscription-management.test.d.ts +1 -0
- package/dist/reactivity/types.d.ts +12 -0
- package/dist/router/__tests__/link-behavior-active-class.test.d.ts +1 -0
- package/dist/router/__tests__/loop-detector.test.d.ts +1 -0
- package/dist/router/__tests__/params-container-resolution.test.d.ts +1 -0
- package/dist/router/__tests__/router-generated-routes.test.d.ts +1 -0
- package/dist/router/__tests__/router-params-granular.test.d.ts +1 -0
- package/dist/router/__tests__/router-params-simple.test.d.ts +1 -0
- package/dist/router/__tests__/router-query-params.test.d.ts +1 -0
- package/dist/router/__tests__/router-route-candidates.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-app-articles.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-debug.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-integration.test.d.ts +1 -0
- package/dist/router/__tests__/routeview-this.test.d.ts +1 -0
- package/dist/router/decorators/base-policy.d.ts +141 -0
- package/dist/router/decorators/base-policy.js +63 -0
- package/dist/router/decorators/index.d.ts +6 -0
- package/dist/router/decorators/params.d.ts +31 -0
- package/dist/router/decorators/params.js +97 -0
- package/dist/router/decorators/route-metadata.d.ts +11 -0
- package/dist/router/decorators/route-metadata.js +23 -0
- package/dist/router/decorators/route.d.ts +39 -0
- package/dist/router/decorators/route.js +7 -0
- package/dist/router/link.behavior.d.ts +87 -0
- package/dist/router/link.behavior.js +227 -0
- package/dist/router/policy-evaluator.d.ts +81 -0
- package/dist/router/policy-evaluator.js +209 -0
- package/dist/router/route-view.d.ts +56 -0
- package/dist/router/route-view.js +156 -0
- package/dist/router/router.d.ts +67 -0
- package/dist/router/router.js +308 -0
- package/dist/router/static-analysis/index.d.ts +37 -0
- package/dist/router/static-analysis/parser.d.ts +14 -0
- package/dist/router/static-analysis/parser.js +147 -0
- package/dist/router/static-analysis/scanner.d.ts +27 -0
- package/dist/router/static-analysis/scanner.js +91 -0
- package/dist/router/trie.d.ts +14 -0
- package/dist/router/trie.js +126 -0
- package/dist/router/trie.types.d.ts +36 -0
- package/dist/styles/base-style-sheet.d.ts +96 -0
- package/dist/styles/base-style-sheet.js +149 -0
- package/dist/styles/decorators/factories.d.ts +76 -0
- package/dist/styles/decorators/factories.js +11 -0
- package/dist/styles/decorators/keyframes.d.ts +238 -0
- package/dist/styles/decorators/keyframes.js +79 -0
- package/dist/styles/decorators/rule.d.ts +177 -0
- package/dist/styles/decorators/rule.js +72 -0
- package/dist/styles/decorators/scope.d.ts +66 -0
- package/dist/styles/decorators/scope.js +17 -0
- package/dist/styles/decorators/style.d.ts +1 -0
- package/dist/styles/decorators/style.js +20 -0
- package/dist/styles/decorators/useStyles.d.ts +5 -0
- package/dist/styles/decorators/useStyles.js +29 -0
- package/dist/styles/global-styles-registry.d.ts +72 -0
- package/dist/styles/global-styles-registry.js +155 -0
- package/dist/types.d.ts +1 -0
- package/dist/vite-plugins/__tests__/jsx-control-flow-transform.test.d.ts +1 -0
- package/dist/vite-plugins/index.d.ts +4 -0
- package/dist/vite-plugins/index.js +10 -0
- package/dist/vite-plugins/jsx-contextual.d.ts +7 -0
- package/dist/vite-plugins/jsx-contextual.js +53 -0
- package/dist/vite-plugins/jsx-control-flow-transform.d.ts +60 -0
- package/dist/vite-plugins/jsx-control-flow-transform.js +180 -0
- package/dist/vite-plugins/jsx-signals.d.ts +2 -0
- package/dist/vite-plugins/jsx-signals.js +124 -0
- package/dist/vite-plugins/router/route-generator-plugin.d.ts +63 -0
- package/dist/vite-plugins/router/route-generator-plugin.js +310 -0
- package/package.json +85 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { Service } from "../../DI/decorators/service.js";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
6
|
+
var __typeError = (msg) => {
|
|
7
|
+
throw TypeError(msg);
|
|
8
|
+
};
|
|
9
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
11
|
+
var __decoratorStart = (base) => [, , , __create(null)];
|
|
12
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
13
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
|
|
14
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
15
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
16
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
17
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self);
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
21
|
+
var it, done, ctx, k = flags & 7, p = false;
|
|
22
|
+
var j = 0;
|
|
23
|
+
var extraInitializers = array[j] || (array[j] = []);
|
|
24
|
+
var desc = k && (target = target.prototype, k < 5 && (k > 3 || !p) && __getOwnPropDesc(target, name));
|
|
25
|
+
__name(target, name);
|
|
26
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
27
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
28
|
+
it = (0, decorators[i])(target, ctx), done._ = 1;
|
|
29
|
+
__expectFn(it) && (target = it);
|
|
30
|
+
}
|
|
31
|
+
return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
32
|
+
};
|
|
33
|
+
var _SessionStorageCache_decorators, _init;
|
|
34
|
+
_SessionStorageCache_decorators = [Service];
|
|
35
|
+
class SessionStorageCache {
|
|
36
|
+
constructor() {
|
|
37
|
+
this.prefix = "cache";
|
|
38
|
+
this.tagIndexKey = "cache:tagIndex";
|
|
39
|
+
}
|
|
40
|
+
getStorageKey(key) {
|
|
41
|
+
return `${this.prefix}:${key}`;
|
|
42
|
+
}
|
|
43
|
+
getTagIndex() {
|
|
44
|
+
try {
|
|
45
|
+
const data = sessionStorage.getItem(this.tagIndexKey);
|
|
46
|
+
if (!data) {
|
|
47
|
+
return /* @__PURE__ */ new Map();
|
|
48
|
+
}
|
|
49
|
+
const parsed = JSON.parse(data);
|
|
50
|
+
return new Map(
|
|
51
|
+
Object.entries(parsed).map(([tag, keys]) => [tag, new Set(keys)])
|
|
52
|
+
);
|
|
53
|
+
} catch {
|
|
54
|
+
return /* @__PURE__ */ new Map();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
saveTagIndex(tagIndex) {
|
|
58
|
+
try {
|
|
59
|
+
const obj = {};
|
|
60
|
+
tagIndex.forEach((keys, tag) => {
|
|
61
|
+
obj[tag] = Array.from(keys);
|
|
62
|
+
});
|
|
63
|
+
sessionStorage.setItem(this.tagIndexKey, JSON.stringify(obj));
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error("[SessionStorageCache] Error saving tag index:", error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
get(key) {
|
|
69
|
+
try {
|
|
70
|
+
const storageKey = this.getStorageKey(key);
|
|
71
|
+
const item = sessionStorage.getItem(storageKey);
|
|
72
|
+
if (!item) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const entry = JSON.parse(item);
|
|
76
|
+
const now = Date.now();
|
|
77
|
+
const age = now - entry.timestamp;
|
|
78
|
+
if (age > entry.ttl) {
|
|
79
|
+
this.delete(key);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
return entry.value;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error("[SessionStorageCache] Error getting item:", error);
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
set(key, value, ttl, tags = []) {
|
|
89
|
+
try {
|
|
90
|
+
const storageKey = this.getStorageKey(key);
|
|
91
|
+
const entry = {
|
|
92
|
+
value,
|
|
93
|
+
timestamp: Date.now(),
|
|
94
|
+
ttl,
|
|
95
|
+
tags
|
|
96
|
+
};
|
|
97
|
+
sessionStorage.setItem(storageKey, JSON.stringify(entry));
|
|
98
|
+
if (tags.length > 0) {
|
|
99
|
+
const tagIndex = this.getTagIndex();
|
|
100
|
+
tags.forEach((tag) => {
|
|
101
|
+
if (!tagIndex.has(tag)) {
|
|
102
|
+
tagIndex.set(tag, /* @__PURE__ */ new Set());
|
|
103
|
+
}
|
|
104
|
+
tagIndex.get(tag).add(key);
|
|
105
|
+
});
|
|
106
|
+
this.saveTagIndex(tagIndex);
|
|
107
|
+
}
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error("[SessionStorageCache] Error setting item:", error);
|
|
110
|
+
this.clearExpired();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
delete(key) {
|
|
114
|
+
try {
|
|
115
|
+
const storageKey = this.getStorageKey(key);
|
|
116
|
+
const item = sessionStorage.getItem(storageKey);
|
|
117
|
+
if (item) {
|
|
118
|
+
const entry = JSON.parse(item);
|
|
119
|
+
if (entry.tags && entry.tags.length > 0) {
|
|
120
|
+
const tagIndex = this.getTagIndex();
|
|
121
|
+
entry.tags.forEach((tag) => {
|
|
122
|
+
tagIndex.get(tag)?.delete(key);
|
|
123
|
+
if (tagIndex.get(tag)?.size === 0) {
|
|
124
|
+
tagIndex.delete(tag);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
this.saveTagIndex(tagIndex);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
sessionStorage.removeItem(storageKey);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error("[SessionStorageCache] Error deleting item:", error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
clear() {
|
|
136
|
+
const keysToRemove = [];
|
|
137
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
138
|
+
const key = sessionStorage.key(i);
|
|
139
|
+
if (key && key.startsWith(`${this.prefix}:`)) {
|
|
140
|
+
keysToRemove.push(key);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
keysToRemove.forEach((key) => sessionStorage.removeItem(key));
|
|
144
|
+
sessionStorage.removeItem(this.tagIndexKey);
|
|
145
|
+
}
|
|
146
|
+
invalidatePattern(pattern) {
|
|
147
|
+
const keysToRemove = [];
|
|
148
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
149
|
+
const storageKey = sessionStorage.key(i);
|
|
150
|
+
if (storageKey && storageKey.startsWith(`${this.prefix}:`)) {
|
|
151
|
+
const key = storageKey.substring(this.prefix.length + 1);
|
|
152
|
+
if (pattern.test(key)) {
|
|
153
|
+
keysToRemove.push(key);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
keysToRemove.forEach((key) => this.delete(key));
|
|
158
|
+
}
|
|
159
|
+
invalidateTag(tag) {
|
|
160
|
+
const tagIndex = this.getTagIndex();
|
|
161
|
+
const keysToInvalidate = tagIndex.get(tag);
|
|
162
|
+
if (!keysToInvalidate) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const keys = Array.from(keysToInvalidate);
|
|
166
|
+
keys.forEach((key) => this.delete(key));
|
|
167
|
+
}
|
|
168
|
+
getKeysByTag(tag) {
|
|
169
|
+
const tagIndex = this.getTagIndex();
|
|
170
|
+
const keys = tagIndex.get(tag);
|
|
171
|
+
return keys ? Array.from(keys) : [];
|
|
172
|
+
}
|
|
173
|
+
updateByTags(tags, value) {
|
|
174
|
+
const tagIndex = this.getTagIndex();
|
|
175
|
+
const keysToUpdate = /* @__PURE__ */ new Set();
|
|
176
|
+
tags.forEach((tag) => {
|
|
177
|
+
const keys = tagIndex.get(tag);
|
|
178
|
+
if (keys) {
|
|
179
|
+
keys.forEach((key) => keysToUpdate.add(key));
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
keysToUpdate.forEach((key) => {
|
|
183
|
+
const storageKey = this.getStorageKey(key);
|
|
184
|
+
const item = sessionStorage.getItem(storageKey);
|
|
185
|
+
if (item) {
|
|
186
|
+
try {
|
|
187
|
+
const fullEntry = JSON.parse(item);
|
|
188
|
+
this.set(key, value, fullEntry.ttl, fullEntry.tags);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.error(`[SessionStorageCache] Error parsing entry for ${key}:`, error);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
invalidateTags(tags) {
|
|
196
|
+
const tagIndex = this.getTagIndex();
|
|
197
|
+
const keysToInvalidate = /* @__PURE__ */ new Set();
|
|
198
|
+
tags.forEach((tag) => {
|
|
199
|
+
const keys = tagIndex.get(tag);
|
|
200
|
+
if (keys) {
|
|
201
|
+
keys.forEach((key) => keysToInvalidate.add(key));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
keysToInvalidate.forEach((key) => this.delete(key));
|
|
205
|
+
}
|
|
206
|
+
clearExpired() {
|
|
207
|
+
const now = Date.now();
|
|
208
|
+
const keysToRemove = [];
|
|
209
|
+
for (let i = 0; i < sessionStorage.length; i++) {
|
|
210
|
+
const storageKey = sessionStorage.key(i);
|
|
211
|
+
if (storageKey && storageKey.startsWith(`${this.prefix}:`)) {
|
|
212
|
+
try {
|
|
213
|
+
const item = sessionStorage.getItem(storageKey);
|
|
214
|
+
if (item) {
|
|
215
|
+
const entry = JSON.parse(item);
|
|
216
|
+
const age = now - entry.timestamp;
|
|
217
|
+
if (age > entry.ttl) {
|
|
218
|
+
const key = storageKey.substring(this.prefix.length + 1);
|
|
219
|
+
keysToRemove.push(key);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} catch (error) {
|
|
223
|
+
const key = storageKey.substring(this.prefix.length + 1);
|
|
224
|
+
keysToRemove.push(key);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
keysToRemove.forEach((key) => this.delete(key));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Lifecycle hook - se ejecuta cuando el container se destruye
|
|
232
|
+
*/
|
|
233
|
+
onDestroy() {
|
|
234
|
+
this.clearExpired();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
_init = __decoratorStart();
|
|
238
|
+
SessionStorageCache = __decorateElement(_init, 0, "SessionStorageCache", _SessionStorageCache_decorators, SessionStorageCache);
|
|
239
|
+
__runInitializers(_init, 1, SessionStorageCache);
|
|
240
|
+
export {
|
|
241
|
+
SessionStorageCache
|
|
242
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @TTL - Decorador para cachear resultados de métodos con time-to-live.
|
|
3
|
+
*
|
|
4
|
+
* IMPORTANTE: El método debe ser async o retornar una Promise.
|
|
5
|
+
*
|
|
6
|
+
* @param ttl - Time-to-live en milisegundos
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Cache en memoria (default) por 5 segundos
|
|
10
|
+
* @TTL(5000)
|
|
11
|
+
* async getStores() {
|
|
12
|
+
* return await fetch('/api/stores').then(r => r.json());
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Cache en localStorage por 1 hora
|
|
17
|
+
* @Cache(LocalStorageCache)
|
|
18
|
+
* @TTL(3600000)
|
|
19
|
+
* async getUserPreferences() {
|
|
20
|
+
* return await fetch('/api/preferences').then(r => r.json());
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Cache con argumentos
|
|
25
|
+
* @Cache(LocalStorageCache)
|
|
26
|
+
* @TTL(5000)
|
|
27
|
+
* async getUserById(id: string) {
|
|
28
|
+
* return await fetch(`/api/users/${id}`).then(r => r.json());
|
|
29
|
+
* }
|
|
30
|
+
*/
|
|
31
|
+
export declare function TTL(ttl: number): (originalMethod: Function, context: ClassMethodDecoratorContext) => (this: any, ...args: any[]) => Promise<any>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { MemoryCache } from "./memory-cache.js";
|
|
2
|
+
function generateCacheKey(instance, methodName, args) {
|
|
3
|
+
const className = instance.constructor.name;
|
|
4
|
+
if (args.length === 0) {
|
|
5
|
+
return `${className}:${methodName}`;
|
|
6
|
+
}
|
|
7
|
+
const argsKey = JSON.stringify(args);
|
|
8
|
+
return `${className}:${methodName}:${argsKey}`;
|
|
9
|
+
}
|
|
10
|
+
function TTL(ttl) {
|
|
11
|
+
return function(originalMethod, context) {
|
|
12
|
+
const methodName = String(context.name);
|
|
13
|
+
const wrappedMethod = async function(...args) {
|
|
14
|
+
this.constructor.name;
|
|
15
|
+
const metadata = context.metadata;
|
|
16
|
+
const ProviderClass = metadata.cacheProviders?.[methodName] || MemoryCache;
|
|
17
|
+
const tagExtractor = metadata.cacheTagExtractors?.[methodName];
|
|
18
|
+
const provider = this.__container.get(ProviderClass);
|
|
19
|
+
const cacheKey = generateCacheKey(this, methodName, args);
|
|
20
|
+
const cached = provider.get(cacheKey);
|
|
21
|
+
if (cached !== null) {
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
const result = await originalMethod.apply(this, args);
|
|
25
|
+
const tags = tagExtractor ? tagExtractor(result, args) : [];
|
|
26
|
+
provider.set(cacheKey, result, ttl, tags);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
return wrappedMethod;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
TTL
|
|
34
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Constructor } from '../store/types';
|
|
2
|
+
/**
|
|
3
|
+
* @Consume - Decorador para métodos de Repository
|
|
4
|
+
*
|
|
5
|
+
* @param modelClass - La clase del modelo (ej: User, Article)
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* @Service
|
|
9
|
+
* class UserRepository {
|
|
10
|
+
* @Consume(User)
|
|
11
|
+
* async findAll() {
|
|
12
|
+
* const response = await fetch('/api/users');
|
|
13
|
+
* return await response.json();
|
|
14
|
+
* }
|
|
15
|
+
*
|
|
16
|
+
* @Consume(User)
|
|
17
|
+
* async findById(id: string) {
|
|
18
|
+
* const response = await fetch(`/api/users/${id}`);
|
|
19
|
+
* return await response.json();
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // Uso:
|
|
24
|
+
* const users = await repo.findAll();
|
|
25
|
+
* // users es User[], no JSON
|
|
26
|
+
* // users ya están en el Store
|
|
27
|
+
* users[0].changeName('New Name'); // Métodos de dominio funcionan
|
|
28
|
+
*/
|
|
29
|
+
export declare function Consume<T>(modelClass: Constructor<T>): <This extends object, Args extends any[], Return>(originalMethod: (this: This, ...args: Args) => Promise<Return>, context: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Promise<Return>>) => (this: This, ...args: Args) => Promise<any>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { EntityStore } from "../store/store.js";
|
|
2
|
+
import { convertResponse } from "../store/json-to-model.js";
|
|
3
|
+
function Consume(modelClass) {
|
|
4
|
+
return function(originalMethod, context) {
|
|
5
|
+
if (context.kind !== "method") {
|
|
6
|
+
throw new Error("@Consume can only be applied to methods");
|
|
7
|
+
}
|
|
8
|
+
const methodName = String(context.name);
|
|
9
|
+
return async function(...args) {
|
|
10
|
+
try {
|
|
11
|
+
const result = await originalMethod.apply(this, args);
|
|
12
|
+
if (result === null || result === void 0) {
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
const instances = convertResponse(modelClass, result);
|
|
16
|
+
const entityStore = this.__container.get(EntityStore);
|
|
17
|
+
entityStore.set(modelClass, instances);
|
|
18
|
+
return instances;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`[Consume] Error en ${methodName}():`, error);
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
Consume
|
|
28
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Id DECORATOR
|
|
3
|
+
*
|
|
4
|
+
* Marca un campo como el identificador único de la entidad.
|
|
5
|
+
* Cada @Model debe tener exactamente un campo con @Id.
|
|
6
|
+
*
|
|
7
|
+
* USO:
|
|
8
|
+
* @Model
|
|
9
|
+
* class User {
|
|
10
|
+
* @Id id: string;
|
|
11
|
+
* @Prop name: string;
|
|
12
|
+
* }
|
|
13
|
+
*
|
|
14
|
+
* IMPLEMENTACIÓN:
|
|
15
|
+
* Este decorador se ejecuta ANTES que @Model (los field decorators van primero).
|
|
16
|
+
* Por eso, almacenamos la información en context.metadata, que @Model podrá leer después.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* @Id - Decorador para marcar el campo identificador
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* class User {
|
|
23
|
+
* @Id id: string; // Campo ID
|
|
24
|
+
* @Id userId: string; // También funciona con otros nombres
|
|
25
|
+
* @Id _id: string; // MongoDB style
|
|
26
|
+
* }
|
|
27
|
+
*/
|
|
28
|
+
export declare function Id<This extends object, Value extends string | number>(target: undefined, context: ClassFieldDecoratorContext<This, Value>): (this: This, initialValue: Value) => Value;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Id(target, context) {
|
|
2
|
+
if (context.kind !== "field") {
|
|
3
|
+
throw new Error("@Id can only be applied to class fields");
|
|
4
|
+
}
|
|
5
|
+
const fieldName = String(context.name);
|
|
6
|
+
const metadata = context.metadata;
|
|
7
|
+
if (metadata.idField) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
`Cannot have multiple @Id decorators in the same class. Found @Id on '${metadata.idField}' and '${fieldName}'.`
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
metadata.idField = fieldName;
|
|
13
|
+
return function(initialValue) {
|
|
14
|
+
return initialValue;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
Id
|
|
19
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Model DECORATOR
|
|
3
|
+
*
|
|
4
|
+
* Decorador de clase que registra un modelo en el Store.
|
|
5
|
+
* Se ejecuta DESPUÉS de @Id y @Prop, por lo que puede leer
|
|
6
|
+
* la metadata que estos decoradores dejaron.
|
|
7
|
+
*
|
|
8
|
+
* USO:
|
|
9
|
+
* @Model
|
|
10
|
+
* class User {
|
|
11
|
+
* @Id id: string;
|
|
12
|
+
* @Prop name: string;
|
|
13
|
+
* @Prop email: string;
|
|
14
|
+
*
|
|
15
|
+
* // Métodos de dominio
|
|
16
|
+
* changeName(newName: string) {
|
|
17
|
+
* this.name = newName;
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* RESPONSABILIDADES:
|
|
22
|
+
* 1. Leer metadata de @Id y @Prop
|
|
23
|
+
* 2. Validar que hay exactamente un @Id
|
|
24
|
+
* 3. Registrar metadata en el Store
|
|
25
|
+
* 4. Retornar la clase sin modificarla
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* @Model - Decorador de clase para modelos de datos
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* @Model
|
|
32
|
+
* class User {
|
|
33
|
+
* @Id id: string;
|
|
34
|
+
* @Prop name: string;
|
|
35
|
+
*
|
|
36
|
+
* constructor(id: string, name: string) {
|
|
37
|
+
* this.id = id;
|
|
38
|
+
* this.name = name;
|
|
39
|
+
* }
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* // Ahora el Store sabe sobre User
|
|
43
|
+
* const user = new User("1", "Julian");
|
|
44
|
+
* store.set(User, user);
|
|
45
|
+
*/
|
|
46
|
+
export declare function Model<T extends {
|
|
47
|
+
new (...args: any[]): {};
|
|
48
|
+
}>(target: T, context: ClassDecoratorContext<T>): T;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { registerModelMetadata } from "../store/store.js";
|
|
2
|
+
function Model(target, context) {
|
|
3
|
+
if (context.kind !== "class") {
|
|
4
|
+
throw new Error("@Model can only be applied to classes");
|
|
5
|
+
}
|
|
6
|
+
const metadata = context.metadata;
|
|
7
|
+
const idField = metadata.idField;
|
|
8
|
+
if (!idField) {
|
|
9
|
+
throw new Error(
|
|
10
|
+
`@Model class ${target.name} must have exactly one field decorated with @Id`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
const propFields = metadata.propFields || [];
|
|
14
|
+
const modelMetadata = {
|
|
15
|
+
modelClass: target,
|
|
16
|
+
idField,
|
|
17
|
+
propFields
|
|
18
|
+
};
|
|
19
|
+
registerModelMetadata(modelMetadata);
|
|
20
|
+
return target;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
Model
|
|
24
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @Prop DECORATOR
|
|
3
|
+
*
|
|
4
|
+
* Convierte un campo en una propiedad reactiva usando signals.
|
|
5
|
+
* Similar a @State, pero también registra el campo en la metadata del modelo.
|
|
6
|
+
*
|
|
7
|
+
* USO:
|
|
8
|
+
* @Model
|
|
9
|
+
* class User {
|
|
10
|
+
* @Id id: string;
|
|
11
|
+
* @Prop name: string; // Reactivo
|
|
12
|
+
* @Prop email: string; // Reactivo
|
|
13
|
+
* }
|
|
14
|
+
*
|
|
15
|
+
* IMPLEMENTACIÓN:
|
|
16
|
+
* 1. Crea una Signal interna para almacenar el valor
|
|
17
|
+
* 2. Define getter/setter que usan la Signal
|
|
18
|
+
* 3. Define propiedad `$nombre` que expone la Signal
|
|
19
|
+
* 4. Registra el campo en metadata para que @Model lo sepa
|
|
20
|
+
*
|
|
21
|
+
* DIFERENCIA CON @State:
|
|
22
|
+
* @State es para componentes, @Prop es para entidades de datos.
|
|
23
|
+
* Ambos usan el mismo mecanismo interno (Signals).
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* @Prop - Decorador para propiedades reactivas de modelos
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* @Model
|
|
30
|
+
* class User {
|
|
31
|
+
* @Id id: string;
|
|
32
|
+
* @Prop name: string;
|
|
33
|
+
* @Prop email: string;
|
|
34
|
+
* @Prop age: number;
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* // Uso:
|
|
38
|
+
* const user = new User();
|
|
39
|
+
* user.name = "Julian"; // Setter actualiza la signal
|
|
40
|
+
* console.log(user.name); // Getter lee de la signal
|
|
41
|
+
* console.log(user.$name); // Acceso directo a la signal
|
|
42
|
+
*/
|
|
43
|
+
export declare function Prop<This extends object, Value>(target: undefined, context: ClassFieldDecoratorContext<This, Value>): (this: This, initialValue: Value) => Value;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Signal } from "../../reactivity/signals/signal.js";
|
|
2
|
+
function Prop(target, context) {
|
|
3
|
+
if (context.kind !== "field") {
|
|
4
|
+
throw new Error("@Prop can only be applied to class fields");
|
|
5
|
+
}
|
|
6
|
+
const fieldName = String(context.name);
|
|
7
|
+
const signalKey = Symbol(`prop_signal_${fieldName}`);
|
|
8
|
+
const signalPropName = `$${fieldName}`;
|
|
9
|
+
const metadata = context.metadata;
|
|
10
|
+
metadata.propFields ??= [];
|
|
11
|
+
metadata.propFields.push(fieldName);
|
|
12
|
+
return function(initialValue) {
|
|
13
|
+
const signal = new Signal(initialValue);
|
|
14
|
+
this[signalKey] = signal;
|
|
15
|
+
Object.defineProperty(this, fieldName, {
|
|
16
|
+
get: () => this[signalKey].get(),
|
|
17
|
+
set: (newValue) => this[signalKey].set(newValue),
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(this, signalPropName, {
|
|
22
|
+
get: () => this[signalKey],
|
|
23
|
+
enumerable: false,
|
|
24
|
+
// No aparece en Object.keys()
|
|
25
|
+
configurable: true
|
|
26
|
+
});
|
|
27
|
+
return initialValue;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
Prop
|
|
32
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DATA MANAGEMENT SYSTEM - Public API
|
|
3
|
+
*
|
|
4
|
+
* Este archivo expone la API pública del sistema de gestión de datos.
|
|
5
|
+
*/
|
|
6
|
+
export { EntityStore, registerModelMetadata, getModelMetadata } from './store/store';
|
|
7
|
+
export { Model } from './decorators/model';
|
|
8
|
+
export { Id } from './decorators/id';
|
|
9
|
+
export { Prop } from './decorators/prop';
|
|
10
|
+
export { Consume } from './decorators/consume';
|
|
11
|
+
export { MemoryCache, LocalStorageCache, SessionStorageCache, Cache, TTL, CacheTags, CacheUpdate, CacheInvalidate } from './cache';
|
|
12
|
+
export type { CacheProvider, CacheEntry, TagExtractor } from './cache';
|
|
13
|
+
export type { Constructor, ModelMetadata, StoreEntity, Predicate, QueryResult, } from './store/types';
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Constructor } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Convierte un objeto JSON plano en una instancia de modelo.
|
|
4
|
+
*
|
|
5
|
+
* @param modelClass - La clase del modelo (ej: User)
|
|
6
|
+
* @param data - Objeto JSON plano con los datos
|
|
7
|
+
* @returns Instancia del modelo con propiedades reactivas
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const json = { id: "1", name: "Julian", email: "j@example.com" };
|
|
11
|
+
* const user = jsonToModel(User, json);
|
|
12
|
+
* // user es una instancia de User con propiedades reactivas
|
|
13
|
+
*/
|
|
14
|
+
export declare function jsonToModel<T>(modelClass: Constructor<T>, data: Record<string, any>): T;
|
|
15
|
+
/**
|
|
16
|
+
* Convierte un array de JSON en un array de instancias de modelo.
|
|
17
|
+
*
|
|
18
|
+
* @param modelClass - La clase del modelo
|
|
19
|
+
* @param dataArray - Array de objetos JSON
|
|
20
|
+
* @returns Array de instancias del modelo
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* const jsonArray = [
|
|
24
|
+
* { id: "1", name: "Julian" },
|
|
25
|
+
* { id: "2", name: "Alice" }
|
|
26
|
+
* ];
|
|
27
|
+
* const users = jsonArrayToModels(User, jsonArray);
|
|
28
|
+
* // [User instance, User instance]
|
|
29
|
+
*/
|
|
30
|
+
export declare function jsonArrayToModels<T>(modelClass: Constructor<T>, dataArray: Record<string, any>[]): T[];
|
|
31
|
+
/**
|
|
32
|
+
* Convierte cualquier respuesta (objeto o array) a modelo(s).
|
|
33
|
+
*
|
|
34
|
+
* @param modelClass - La clase del modelo
|
|
35
|
+
* @param response - Puede ser un objeto o un array
|
|
36
|
+
* @returns Instancia o array de instancias
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Objeto único
|
|
40
|
+
* const user = convertResponse(User, { id: "1", name: "Julian" });
|
|
41
|
+
*
|
|
42
|
+
* // Array
|
|
43
|
+
* const users = convertResponse(User, [{ id: "1" }, { id: "2" }]);
|
|
44
|
+
*/
|
|
45
|
+
export declare function convertResponse<T>(modelClass: Constructor<T>, response: any): T | T[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { getModelMetadata } from "./store.js";
|
|
2
|
+
function jsonToModel(modelClass, data) {
|
|
3
|
+
const metadata = getModelMetadata(modelClass);
|
|
4
|
+
if (!metadata) {
|
|
5
|
+
throw new Error(
|
|
6
|
+
`Cannot convert to model: ${modelClass.name} is not decorated with @Model`
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
const instance = new modelClass();
|
|
10
|
+
Object.keys(data).forEach((key) => {
|
|
11
|
+
if (data[key] !== void 0 && data[key] !== null) {
|
|
12
|
+
instance[key] = data[key];
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
return instance;
|
|
16
|
+
}
|
|
17
|
+
function jsonArrayToModels(modelClass, dataArray) {
|
|
18
|
+
return dataArray.map((data) => jsonToModel(modelClass, data));
|
|
19
|
+
}
|
|
20
|
+
function convertResponse(modelClass, response) {
|
|
21
|
+
if (response === null || response === void 0) {
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
if (Array.isArray(response)) {
|
|
25
|
+
return jsonArrayToModels(modelClass, response);
|
|
26
|
+
}
|
|
27
|
+
if (typeof response === "object") {
|
|
28
|
+
return jsonToModel(modelClass, response);
|
|
29
|
+
}
|
|
30
|
+
return response;
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
convertResponse,
|
|
34
|
+
jsonArrayToModels,
|
|
35
|
+
jsonToModel
|
|
36
|
+
};
|