@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.
Files changed (250) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/DI/__tests__/scoped-container-dependencies.test.d.ts +1 -0
  4. package/dist/DI/bootstrap.d.ts +18 -0
  5. package/dist/DI/decorators/inject.d.ts +37 -0
  6. package/dist/DI/decorators/inject.js +45 -0
  7. package/dist/DI/decorators/service.d.ts +24 -0
  8. package/dist/DI/decorators/service.js +13 -0
  9. package/dist/DI/di-container.d.ts +53 -0
  10. package/dist/DI/di-container.js +158 -0
  11. package/dist/DI/lifecycle.d.ts +37 -0
  12. package/dist/DI/lifecycle.js +6 -0
  13. package/dist/DI/scoped-container.d.ts +68 -0
  14. package/dist/DI/scoped-container.js +193 -0
  15. package/dist/DI/service-metadata.d.ts +32 -0
  16. package/dist/DI/service-metadata.js +31 -0
  17. package/dist/DI/types.d.ts +4 -0
  18. package/dist/behaviors/__tests__/behavior-system.test.d.ts +1 -0
  19. package/dist/behaviors/behavior-manager.d.ts +60 -0
  20. package/dist/behaviors/behavior-manager.js +131 -0
  21. package/dist/behaviors/behavior-registry.d.ts +68 -0
  22. package/dist/behaviors/behavior-registry.js +105 -0
  23. package/dist/behaviors/constants.d.ts +16 -0
  24. package/dist/behaviors/constants.js +8 -0
  25. package/dist/behaviors/decorators.d.ts +87 -0
  26. package/dist/behaviors/decorators.js +46 -0
  27. package/dist/behaviors/index.d.ts +4 -0
  28. package/dist/components/__tests__/host.test.d.ts +1 -0
  29. package/dist/components/app-tree.d.ts +49 -0
  30. package/dist/components/app-tree.js +122 -0
  31. package/dist/components/base-component.d.ts +85 -0
  32. package/dist/components/base-component.js +438 -0
  33. package/dist/components/decorators/component.d.ts +27 -0
  34. package/dist/components/decorators/component.js +47 -0
  35. package/dist/components/decorators/prop.d.ts +14 -0
  36. package/dist/components/decorators/prop.js +37 -0
  37. package/dist/components/types.d.ts +26 -0
  38. package/dist/core.d.ts +23 -0
  39. package/dist/core.js +8 -0
  40. package/dist/custom-components/__tests__/for.test.d.ts +1 -0
  41. package/dist/custom-components/__tests__/show.test.d.ts +1 -0
  42. package/dist/custom-components/for.d.ts +58 -0
  43. package/dist/custom-components/for.js +313 -0
  44. package/dist/custom-components/index.d.ts +2 -0
  45. package/dist/custom-components/show.d.ts +78 -0
  46. package/dist/custom-components/show.js +88 -0
  47. package/dist/data-management/cache/cache-invalidate.decorator.d.ts +35 -0
  48. package/dist/data-management/cache/cache-invalidate.decorator.js +21 -0
  49. package/dist/data-management/cache/cache-metadata.d.ts +15 -0
  50. package/dist/data-management/cache/cache-provider.interface.d.ts +67 -0
  51. package/dist/data-management/cache/cache-tags.decorator.d.ts +52 -0
  52. package/dist/data-management/cache/cache-tags.decorator.js +13 -0
  53. package/dist/data-management/cache/cache-update.decorator.d.ts +28 -0
  54. package/dist/data-management/cache/cache-update.decorator.js +21 -0
  55. package/dist/data-management/cache/cache.decorator.d.ts +28 -0
  56. package/dist/data-management/cache/cache.decorator.js +13 -0
  57. package/dist/data-management/cache/index.d.ts +11 -0
  58. package/dist/data-management/cache/local-storage-cache.d.ts +40 -0
  59. package/dist/data-management/cache/local-storage-cache.js +268 -0
  60. package/dist/data-management/cache/memory-cache.d.ts +37 -0
  61. package/dist/data-management/cache/memory-cache.js +149 -0
  62. package/dist/data-management/cache/session-storage-cache.d.ts +35 -0
  63. package/dist/data-management/cache/session-storage-cache.js +242 -0
  64. package/dist/data-management/cache/ttl.decorator.d.ts +31 -0
  65. package/dist/data-management/cache/ttl.decorator.js +34 -0
  66. package/dist/data-management/decorators/consume.d.ts +29 -0
  67. package/dist/data-management/decorators/consume.js +28 -0
  68. package/dist/data-management/decorators/id.d.ts +28 -0
  69. package/dist/data-management/decorators/id.js +19 -0
  70. package/dist/data-management/decorators/model.d.ts +48 -0
  71. package/dist/data-management/decorators/model.js +24 -0
  72. package/dist/data-management/decorators/prop.d.ts +43 -0
  73. package/dist/data-management/decorators/prop.js +32 -0
  74. package/dist/data-management/index.d.ts +13 -0
  75. package/dist/data-management/store/json-to-model.d.ts +45 -0
  76. package/dist/data-management/store/json-to-model.js +36 -0
  77. package/dist/data-management/store/store.d.ts +108 -0
  78. package/dist/data-management/store/store.js +207 -0
  79. package/dist/data-management/store/types.d.ts +53 -0
  80. package/dist/events-handler/decorators/emit.d.ts +29 -0
  81. package/dist/events-handler/decorators/emit.js +51 -0
  82. package/dist/events-handler/event-decorators.d.ts +1 -0
  83. package/dist/events-handler/event-emitter.service.d.ts +21 -0
  84. package/dist/events-handler/event-emitter.service.js +85 -0
  85. package/dist/events-handler/event-types.d.ts +12 -0
  86. package/dist/index.d.ts +55 -0
  87. package/dist/index.js +121 -0
  88. package/dist/jsx/dynamic/__tests__/granular-array-renderer.test.d.ts +1 -0
  89. package/dist/jsx/dynamic/__tests__/jsx-array-rendering.test.d.ts +1 -0
  90. package/dist/jsx/dynamic/array-renderer.d.ts +2 -0
  91. package/dist/jsx/dynamic/array-renderer.js +133 -0
  92. package/dist/jsx/dynamic/child-renderer.d.ts +1 -0
  93. package/dist/jsx/dynamic/child-renderer.js +180 -0
  94. package/dist/jsx/dynamic/dom-utils.d.ts +5 -0
  95. package/dist/jsx/dynamic/dom-utils.js +22 -0
  96. package/dist/jsx/dynamic/granular-array-renderer.d.ts +16 -0
  97. package/dist/jsx/dynamic/granular-array-renderer.js +153 -0
  98. package/dist/jsx/dynamic/node-renderer.d.ts +2 -0
  99. package/dist/jsx/dynamic/props-handler.d.ts +3 -0
  100. package/dist/jsx/dynamic/props-handler.js +281 -0
  101. package/dist/jsx/dynamic/text-renderer.d.ts +2 -0
  102. package/dist/jsx/jsx-dev-runtime.d.ts +2 -0
  103. package/dist/jsx/jsx-runtime.d.ts +3 -0
  104. package/dist/jsx/types.d.ts +35 -0
  105. package/dist/jsx/types.js +4 -0
  106. package/dist/jsx-dev-runtime.d.ts +2 -0
  107. package/dist/jsx-dev-runtime.js +8 -0
  108. package/dist/jsx-runtime.d.ts +2 -0
  109. package/dist/jsx-runtime.js +11 -0
  110. package/dist/reactivity/__tests__/context-stack.test.d.ts +1 -0
  111. package/dist/reactivity/__tests__/nested-effects-untrack.test.d.ts +22 -0
  112. package/dist/reactivity/context-scope.d.ts +57 -0
  113. package/dist/reactivity/context-scope.js +35 -0
  114. package/dist/reactivity/decorators/__tests__/ctx-integration.test.d.ts +5 -0
  115. package/dist/reactivity/decorators/__tests__/ctx-loop.test.d.ts +10 -0
  116. package/dist/reactivity/decorators/__tests__/state-intelligent.test.d.ts +1 -0
  117. package/dist/reactivity/decorators/computed.d.ts +6 -0
  118. package/dist/reactivity/decorators/computed.js +17 -0
  119. package/dist/reactivity/decorators/create-event-decorator.d.ts +5 -0
  120. package/dist/reactivity/decorators/create-event-decorator.js +28 -0
  121. package/dist/reactivity/decorators/ctx.d.ts +9 -0
  122. package/dist/reactivity/decorators/ctx.js +91 -0
  123. package/dist/reactivity/decorators/effect.d.ts +9 -0
  124. package/dist/reactivity/decorators/effect.js +24 -0
  125. package/dist/reactivity/decorators/resource.d.ts +48 -0
  126. package/dist/reactivity/decorators/resource.js +20 -0
  127. package/dist/reactivity/decorators/state.d.ts +8 -0
  128. package/dist/reactivity/decorators/state.js +68 -0
  129. package/dist/reactivity/decorators/store.d.ts +6 -0
  130. package/dist/reactivity/decorators/store.js +25 -0
  131. package/dist/reactivity/phase-scheduler.d.ts +81 -0
  132. package/dist/reactivity/phase-scheduler.js +88 -0
  133. package/dist/reactivity/phase-scheduler.test.d.ts +1 -0
  134. package/dist/reactivity/reactive-cache.d.ts +21 -0
  135. package/dist/reactivity/reactive-cache.js +31 -0
  136. package/dist/reactivity/reactive-cache.test.d.ts +1 -0
  137. package/dist/reactivity/reactive-context.d.ts +152 -0
  138. package/dist/reactivity/reactive-context.js +184 -0
  139. package/dist/reactivity/signals/__tests__/composicion-automatica.test.d.ts +1 -0
  140. package/dist/reactivity/signals/__tests__/composite/nivel-1-estructura-basica.test.d.ts +1 -0
  141. package/dist/reactivity/signals/__tests__/composite/nivel-2-registro-subscribers.test.d.ts +1 -0
  142. package/dist/reactivity/signals/__tests__/composite/nivel-3-notificaciones-basicas.test.d.ts +1 -0
  143. package/dist/reactivity/signals/__tests__/composite/nivel-4-comparacion-valores.test.d.ts +1 -0
  144. package/dist/reactivity/signals/__tests__/composite/nivel-5-tracking-automatico.test.d.ts +1 -0
  145. package/dist/reactivity/signals/__tests__/composite/nivel-6-anti-glitch.test.d.ts +1 -0
  146. package/dist/reactivity/signals/__tests__/composite/nivel-7-objetos-anidados.test.d.ts +1 -0
  147. package/dist/reactivity/signals/__tests__/composite/nivel-8-observable-array-support.test.d.ts +1 -0
  148. package/dist/reactivity/signals/__tests__/composite-shallow-tracking.test.d.ts +1 -0
  149. package/dist/reactivity/signals/__tests__/effect.test.d.ts +1 -0
  150. package/dist/reactivity/signals/__tests__/reactive-array/nivel-1-estructura-basica.test.d.ts +1 -0
  151. package/dist/reactivity/signals/__tests__/reactive-array/nivel-2-metodos-mutadores.test.d.ts +1 -0
  152. package/dist/reactivity/signals/__tests__/reactive-array/nivel-3-tracking-por-indice.test.d.ts +1 -0
  153. package/dist/reactivity/signals/__tests__/reactive-array/nivel-4-tracking-length.test.d.ts +1 -0
  154. package/dist/reactivity/signals/__tests__/reactive-array/nivel-5-tracking-mutation.test.d.ts +1 -0
  155. package/dist/reactivity/signals/__tests__/reactive-array/nivel-6-metodos-no-mutadores.test.d.ts +1 -0
  156. package/dist/reactivity/signals/__tests__/reactive-array/nivel-7-composicion-bidireccional.test.d.ts +1 -0
  157. package/dist/reactivity/signals/__tests__/reactive-array/nivel-8-proxies.test.d.ts +1 -0
  158. package/dist/reactivity/signals/__tests__/reactive-array/nivel-9-derived-cache-optimization.test.d.ts +1 -0
  159. package/dist/reactivity/signals/__tests__/resource.test.d.ts +1 -0
  160. package/dist/reactivity/signals/__tests__/signal.test.d.ts +1 -0
  161. package/dist/reactivity/signals/array-strategies.d.ts +120 -0
  162. package/dist/reactivity/signals/array-strategies.js +261 -0
  163. package/dist/reactivity/signals/composite.d.ts +89 -0
  164. package/dist/reactivity/signals/composite.js +145 -0
  165. package/dist/reactivity/signals/computed.d.ts +61 -0
  166. package/dist/reactivity/signals/computed.js +107 -0
  167. package/dist/reactivity/signals/computed.test.d.ts +1 -0
  168. package/dist/reactivity/signals/derived.d.ts +10 -0
  169. package/dist/reactivity/signals/derived.js +24 -0
  170. package/dist/reactivity/signals/effect.d.ts +27 -0
  171. package/dist/reactivity/signals/effect.js +46 -0
  172. package/dist/reactivity/signals/event.d.ts +9 -0
  173. package/dist/reactivity/signals/event.js +15 -0
  174. package/dist/reactivity/signals/reactive-array.d.ts +133 -0
  175. package/dist/reactivity/signals/reactive-array.js +490 -0
  176. package/dist/reactivity/signals/reactive-proxy.d.ts +54 -0
  177. package/dist/reactivity/signals/reactive-proxy.js +299 -0
  178. package/dist/reactivity/signals/reactive-tracking.test.d.ts +1 -0
  179. package/dist/reactivity/signals/resource.d.ts +9 -0
  180. package/dist/reactivity/signals/resource.js +58 -0
  181. package/dist/reactivity/signals/signal.d.ts +39 -0
  182. package/dist/reactivity/signals/signal.js +56 -0
  183. package/dist/reactivity/signals/subscription-management.test.d.ts +1 -0
  184. package/dist/reactivity/types.d.ts +12 -0
  185. package/dist/router/__tests__/link-behavior-active-class.test.d.ts +1 -0
  186. package/dist/router/__tests__/loop-detector.test.d.ts +1 -0
  187. package/dist/router/__tests__/params-container-resolution.test.d.ts +1 -0
  188. package/dist/router/__tests__/router-generated-routes.test.d.ts +1 -0
  189. package/dist/router/__tests__/router-params-granular.test.d.ts +1 -0
  190. package/dist/router/__tests__/router-params-simple.test.d.ts +1 -0
  191. package/dist/router/__tests__/router-query-params.test.d.ts +1 -0
  192. package/dist/router/__tests__/router-route-candidates.test.d.ts +1 -0
  193. package/dist/router/__tests__/routeview-app-articles.test.d.ts +1 -0
  194. package/dist/router/__tests__/routeview-debug.test.d.ts +1 -0
  195. package/dist/router/__tests__/routeview-integration.test.d.ts +1 -0
  196. package/dist/router/__tests__/routeview-this.test.d.ts +1 -0
  197. package/dist/router/decorators/base-policy.d.ts +141 -0
  198. package/dist/router/decorators/base-policy.js +63 -0
  199. package/dist/router/decorators/index.d.ts +6 -0
  200. package/dist/router/decorators/params.d.ts +31 -0
  201. package/dist/router/decorators/params.js +97 -0
  202. package/dist/router/decorators/route-metadata.d.ts +11 -0
  203. package/dist/router/decorators/route-metadata.js +23 -0
  204. package/dist/router/decorators/route.d.ts +39 -0
  205. package/dist/router/decorators/route.js +7 -0
  206. package/dist/router/link.behavior.d.ts +87 -0
  207. package/dist/router/link.behavior.js +227 -0
  208. package/dist/router/policy-evaluator.d.ts +81 -0
  209. package/dist/router/policy-evaluator.js +209 -0
  210. package/dist/router/route-view.d.ts +56 -0
  211. package/dist/router/route-view.js +156 -0
  212. package/dist/router/router.d.ts +67 -0
  213. package/dist/router/router.js +308 -0
  214. package/dist/router/static-analysis/index.d.ts +37 -0
  215. package/dist/router/static-analysis/parser.d.ts +14 -0
  216. package/dist/router/static-analysis/parser.js +147 -0
  217. package/dist/router/static-analysis/scanner.d.ts +27 -0
  218. package/dist/router/static-analysis/scanner.js +91 -0
  219. package/dist/router/trie.d.ts +14 -0
  220. package/dist/router/trie.js +126 -0
  221. package/dist/router/trie.types.d.ts +36 -0
  222. package/dist/styles/base-style-sheet.d.ts +96 -0
  223. package/dist/styles/base-style-sheet.js +149 -0
  224. package/dist/styles/decorators/factories.d.ts +76 -0
  225. package/dist/styles/decorators/factories.js +11 -0
  226. package/dist/styles/decorators/keyframes.d.ts +238 -0
  227. package/dist/styles/decorators/keyframes.js +79 -0
  228. package/dist/styles/decorators/rule.d.ts +177 -0
  229. package/dist/styles/decorators/rule.js +72 -0
  230. package/dist/styles/decorators/scope.d.ts +66 -0
  231. package/dist/styles/decorators/scope.js +17 -0
  232. package/dist/styles/decorators/style.d.ts +1 -0
  233. package/dist/styles/decorators/style.js +20 -0
  234. package/dist/styles/decorators/useStyles.d.ts +5 -0
  235. package/dist/styles/decorators/useStyles.js +29 -0
  236. package/dist/styles/global-styles-registry.d.ts +72 -0
  237. package/dist/styles/global-styles-registry.js +155 -0
  238. package/dist/types.d.ts +1 -0
  239. package/dist/vite-plugins/__tests__/jsx-control-flow-transform.test.d.ts +1 -0
  240. package/dist/vite-plugins/index.d.ts +4 -0
  241. package/dist/vite-plugins/index.js +10 -0
  242. package/dist/vite-plugins/jsx-contextual.d.ts +7 -0
  243. package/dist/vite-plugins/jsx-contextual.js +53 -0
  244. package/dist/vite-plugins/jsx-control-flow-transform.d.ts +60 -0
  245. package/dist/vite-plugins/jsx-control-flow-transform.js +180 -0
  246. package/dist/vite-plugins/jsx-signals.d.ts +2 -0
  247. package/dist/vite-plugins/jsx-signals.js +124 -0
  248. package/dist/vite-plugins/router/route-generator-plugin.d.ts +63 -0
  249. package/dist/vite-plugins/router/route-generator-plugin.js +310 -0
  250. package/package.json +85 -0
@@ -0,0 +1,24 @@
1
+ import { effect } from "../signals/effect.js";
2
+ function Effect(target, context) {
3
+ if (context.kind !== "method") {
4
+ throw new Error("@Effect solo se puede aplicar a métodos de clase.");
5
+ }
6
+ context.addInitializer(function() {
7
+ const userMethod = target;
8
+ const instance = this;
9
+ const effectRunner = (onCleanup) => {
10
+ userMethod.call(this, onCleanup);
11
+ };
12
+ const registerEffect = () => {
13
+ effect(effectRunner);
14
+ };
15
+ if (typeof instance.queueEffect === "function") {
16
+ instance.queueEffect(registerEffect);
17
+ } else {
18
+ queueMicrotask(registerEffect);
19
+ }
20
+ });
21
+ }
22
+ export {
23
+ Effect
24
+ };
@@ -0,0 +1,48 @@
1
+ import { IResource } from '../signals/resource';
2
+ export declare const RESOURCE_PROPERTY_KEYS: unique symbol;
3
+ /**
4
+ * Tipo para la función source que obtiene los datos del resource.
5
+ * Recibe un AbortSignal como primer parámetro que puede usarse para cancelar
6
+ * la operación si el resource necesita refetch antes de que complete.
7
+ */
8
+ type ResourceSourceFn<Ctx extends object, T> = (this: Ctx, signal: AbortSignal) => Promise<T>;
9
+ /**
10
+ * Metadata interna que guarda el framework sobre cada resource.
11
+ */
12
+ export interface ResourceMetadata<T = any> {
13
+ key: string | symbol;
14
+ source: ResourceSourceFn<any, T>;
15
+ }
16
+ /**
17
+ * Decorador @Resource para crear propiedades reactivas que cargan datos asíncronos.
18
+ *
19
+ * La función source recibe un AbortSignal como primer parámetro que debe pasarse
20
+ * a cualquier operación asíncrona que soporte cancelación. Esto permite que el
21
+ * framework cancele automáticamente operaciones obsoletas cuando las dependencias
22
+ * del resource cambian.
23
+ *
24
+ * @example
25
+ * // Resource con fetch cancelable
26
+ * @Resource((signal) =>
27
+ * fetch('/api/user', { signal }).then(r => r.json())
28
+ * )
29
+ * userResource!: IResource<User>;
30
+ *
31
+ * @example
32
+ * // Resource que usa el signal en operaciones personalizadas
33
+ * @Resource((signal) => {
34
+ * return new Promise((resolve, reject) => {
35
+ * signal.addEventListener('abort', () => {
36
+ * reject(new Error('Operation cancelled'));
37
+ * });
38
+ *
39
+ * // Tu lógica asíncrona aquí
40
+ * fetchDataSomehow().then(resolve);
41
+ * });
42
+ * })
43
+ * dataResource!: IResource<Data>;
44
+ *
45
+ * @param source Función que recibe un AbortSignal y retorna una Promise con los datos
46
+ */
47
+ export declare function Resource<Ctx extends object, T>(source: ResourceSourceFn<Ctx, T>): (target: undefined, context: ClassFieldDecoratorContext<Ctx, IResource<T>>) => void;
48
+ export {};
@@ -0,0 +1,20 @@
1
+ const RESOURCE_PROPERTY_KEYS = Symbol("ResourcePropertyKeys");
2
+ function Resource(source) {
3
+ return function(target, context) {
4
+ if (context.kind !== "field") {
5
+ throw new Error(
6
+ "@Resource solo se puede aplicar a campos de clase."
7
+ );
8
+ }
9
+ const metadata = context.metadata;
10
+ metadata.resourceKeys ??= [];
11
+ metadata.resourceKeys.push({
12
+ key: context.name,
13
+ source
14
+ });
15
+ };
16
+ }
17
+ export {
18
+ RESOURCE_PROPERTY_KEYS,
19
+ Resource
20
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @State es un decorador para campos de clase que los convierte en señales reactivas.
3
+ * Automáticamente detecta el tipo de valor y crea la señal apropiada:
4
+ * - Primitivos (string, number, boolean, etc.) → Signal
5
+ * - Objetos → CompositeSignal con Proxy para sintaxis nativa
6
+ * - Arrays → ReactiveArray con Proxy para sintaxis nativa
7
+ */
8
+ export declare function State<This extends object, Value>(target: undefined, context: ClassFieldDecoratorContext<This, Value>): (this: This, initialValue: Value) => Value;
@@ -0,0 +1,68 @@
1
+ import { Signal } from "../signals/signal.js";
2
+ import { CompositeSignal } from "../signals/composite.js";
3
+ import { ReactiveArray } from "../signals/reactive-array.js";
4
+ import { createArrayProxy, createObjectProxy } from "../signals/reactive-proxy.js";
5
+ function State(target, context) {
6
+ if (context.kind !== "field") {
7
+ throw new Error("@State solo se puede aplicar a campos de clase.");
8
+ }
9
+ const signalKey = Symbol(`signal_${String(context.name)}`);
10
+ const signalPropName = `$${String(context.name)}`;
11
+ return function(initialValue) {
12
+ let signal;
13
+ if (Array.isArray(initialValue)) {
14
+ signal = new ReactiveArray(initialValue);
15
+ } else if (initialValue !== null && typeof initialValue === "object") {
16
+ signal = new CompositeSignal(initialValue);
17
+ } else {
18
+ signal = new Signal(initialValue);
19
+ }
20
+ this[signalKey] = signal;
21
+ Object.defineProperty(this, context.name, {
22
+ get: () => {
23
+ const sig = this[signalKey];
24
+ if (sig instanceof ReactiveArray) {
25
+ return createArrayProxy(sig);
26
+ } else if (sig instanceof CompositeSignal) {
27
+ return createObjectProxy(sig);
28
+ } else if (sig instanceof Signal) {
29
+ return sig.get();
30
+ }
31
+ return sig;
32
+ },
33
+ set: (newValue) => {
34
+ const currentSig = this[signalKey];
35
+ if (Array.isArray(newValue)) {
36
+ if (currentSig instanceof ReactiveArray) {
37
+ this[signalKey] = new ReactiveArray(newValue);
38
+ } else {
39
+ this[signalKey] = new ReactiveArray(newValue);
40
+ }
41
+ } else if (newValue !== null && typeof newValue === "object") {
42
+ if (currentSig instanceof CompositeSignal) {
43
+ this[signalKey] = new CompositeSignal(newValue);
44
+ } else {
45
+ this[signalKey] = new CompositeSignal(newValue);
46
+ }
47
+ } else {
48
+ if (currentSig instanceof Signal && !(currentSig instanceof CompositeSignal) && !(currentSig instanceof ReactiveArray)) {
49
+ currentSig.set(newValue);
50
+ } else {
51
+ this[signalKey] = new Signal(newValue);
52
+ }
53
+ }
54
+ },
55
+ enumerable: true,
56
+ configurable: true
57
+ });
58
+ Object.defineProperty(this, signalPropName, {
59
+ get: () => this[signalKey],
60
+ enumerable: false,
61
+ configurable: true
62
+ });
63
+ return initialValue;
64
+ };
65
+ }
66
+ export {
67
+ State
68
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @Store es un decorador para campos de clase que convierte un objeto o array
3
+ * en un "store" reactivo profundo. Cada propiedad del objeto se vuelve
4
+ * reactiva de forma granular.
5
+ */
6
+ export declare function Store<This extends object, Value extends object>(target: undefined, context: ClassFieldDecoratorContext<This, Value>): (this: This, initialValue: Value) => Value;
@@ -0,0 +1,25 @@
1
+ import { createStore } from "../signals/reactive-proxy.js";
2
+ function Store(target, context) {
3
+ if (context.kind !== "field") {
4
+ throw new Error("@Store solo se puede aplicar a campos de clase.");
5
+ }
6
+ const storeKey = Symbol(`store_${String(context.name)}`);
7
+ return function(initialValue) {
8
+ const store = createStore(initialValue);
9
+ this[storeKey] = store;
10
+ Object.defineProperty(this, context.name, {
11
+ // El getter devuelve el store reactivo (el Proxy).
12
+ get: () => this[storeKey],
13
+ // El setter permite reemplazar el store completo por un nuevo objeto/array.
14
+ set: (newValue) => {
15
+ this[storeKey] = createStore(newValue);
16
+ },
17
+ enumerable: true,
18
+ configurable: true
19
+ });
20
+ return initialValue;
21
+ };
22
+ }
23
+ export {
24
+ Store
25
+ };
@@ -0,0 +1,81 @@
1
+ import { Subscriber } from './types';
2
+ /**
3
+ * Fases de ejecución del scheduler reactivo
4
+ */
5
+ export declare enum Phase {
6
+ IDLE = 0,// No hay actualizaciones pendientes
7
+ COLLECT = 1,// Recolectando cambios (señales marcadas como dirty)
8
+ EXECUTE = 2,// Ejecutando effects
9
+ COMMIT = 3
10
+ }
11
+ /**
12
+ * PhaseScheduler Simplificado - Sistema reactivo basado en fases
13
+ *
14
+ * FILOSOFÍA:
15
+ * - Effects NO tienen dependencias entre sí
16
+ * - Effects solo LEEN signals y producen side effects
17
+ * - Transformaciones de datos se hacen con Computed signals
18
+ *
19
+ * Si parece que un effect depende de otro effect, falta un Computed signal intermedio.
20
+ *
21
+ * Ventajas sobre sistema de prioridades:
22
+ * - Elimina glitches mediante batching
23
+ * - Orden de ejecución predecible (insertion order)
24
+ * - Más simple y rápido (sin grafos ni ordenamiento topológico)
25
+ * - No hay "starvation" de procesos
26
+ *
27
+ * Ejemplo CORRECTO:
28
+ * ```typescript
29
+ * const a = new Signal(1);
30
+ * const b = computed(() => a.get() * 2); // Computed, no effect
31
+ * const c = computed(() => b.get() + 10); // Computed, no effect
32
+ * effect(() => console.log(c.get())); // Effect solo lee
33
+ * ```
34
+ *
35
+ * Ejemplo INCORRECTO (anti-pattern):
36
+ * ```typescript
37
+ * effect(() => b.set(a.get() * 2)); // ❌ Effect modificando signal
38
+ * effect(() => c.set(b.get() + 10)); // ❌ Otro effect leyendo
39
+ * ```
40
+ */
41
+ declare class PhaseScheduler {
42
+ private currentPhase;
43
+ private dirtyEffects;
44
+ private isFlushScheduled;
45
+ /**
46
+ * Marca un effect como dirty (necesita re-ejecutarse)
47
+ * FASE: COLLECT
48
+ */
49
+ schedule(effect: Subscriber): void;
50
+ /**
51
+ * Agenda la ejecución del ciclo de fases
52
+ */
53
+ private scheduleFlush;
54
+ /**
55
+ * Ejecuta el ciclo completo de fases
56
+ *
57
+ * Simple y directo:
58
+ * 1. COLLECT: Marcar effects como dirty (ya hecho en schedule())
59
+ * 2. EXECUTE: Ejecutar todos los effects dirty en orden
60
+ * 3. COMMIT: Limpiar
61
+ */
62
+ flush(): void;
63
+ /**
64
+ * Ejecuta un effect inmediatamente si está scheduled
65
+ * Útil para evitar lecturas de valores viejos (glitch-free reads)
66
+ */
67
+ runIfScheduled(effect: Subscriber): void;
68
+ /**
69
+ * Obtiene la fase actual (útil para debugging)
70
+ */
71
+ getCurrentPhase(): Phase;
72
+ /**
73
+ * Obtiene información del scheduler (útil para debugging)
74
+ */
75
+ getInfo(): {
76
+ dirtyEffects: number;
77
+ currentPhase: Phase;
78
+ };
79
+ }
80
+ export declare const phaseScheduler: PhaseScheduler;
81
+ export {};
@@ -0,0 +1,88 @@
1
+ class PhaseScheduler {
2
+ constructor() {
3
+ this.currentPhase = 0;
4
+ this.dirtyEffects = /* @__PURE__ */ new Set();
5
+ this.isFlushScheduled = false;
6
+ }
7
+ /**
8
+ * Marca un effect como dirty (necesita re-ejecutarse)
9
+ * FASE: COLLECT
10
+ */
11
+ schedule(effect) {
12
+ this.dirtyEffects.add(effect);
13
+ this.scheduleFlush();
14
+ }
15
+ /**
16
+ * Agenda la ejecución del ciclo de fases
17
+ */
18
+ scheduleFlush() {
19
+ if (!this.isFlushScheduled) {
20
+ this.isFlushScheduled = true;
21
+ queueMicrotask(() => this.flush());
22
+ }
23
+ }
24
+ /**
25
+ * Ejecuta el ciclo completo de fases
26
+ *
27
+ * Simple y directo:
28
+ * 1. COLLECT: Marcar effects como dirty (ya hecho en schedule())
29
+ * 2. EXECUTE: Ejecutar todos los effects dirty en orden
30
+ * 3. COMMIT: Limpiar
31
+ */
32
+ flush() {
33
+ this.isFlushScheduled = false;
34
+ if (this.dirtyEffects.size === 0) {
35
+ this.currentPhase = 0;
36
+ return;
37
+ }
38
+ this.currentPhase = 1;
39
+ const effectsToRun = Array.from(this.dirtyEffects);
40
+ this.dirtyEffects.clear();
41
+ this.currentPhase = 2;
42
+ effectsToRun.forEach((effect) => {
43
+ try {
44
+ effect();
45
+ } catch (error) {
46
+ console.error("Error executing effect:", error);
47
+ }
48
+ });
49
+ this.currentPhase = 3;
50
+ if (this.dirtyEffects.size > 0) {
51
+ this.scheduleFlush();
52
+ }
53
+ this.currentPhase = 0;
54
+ }
55
+ /**
56
+ * Ejecuta un effect inmediatamente si está scheduled
57
+ * Útil para evitar lecturas de valores viejos (glitch-free reads)
58
+ */
59
+ runIfScheduled(effect) {
60
+ if (this.dirtyEffects.has(effect)) {
61
+ this.dirtyEffects.delete(effect);
62
+ try {
63
+ effect();
64
+ } catch (error) {
65
+ console.error("Error executing effect:", error);
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Obtiene la fase actual (útil para debugging)
71
+ */
72
+ getCurrentPhase() {
73
+ return this.currentPhase;
74
+ }
75
+ /**
76
+ * Obtiene información del scheduler (útil para debugging)
77
+ */
78
+ getInfo() {
79
+ return {
80
+ dirtyEffects: this.dirtyEffects.size,
81
+ currentPhase: this.currentPhase
82
+ };
83
+ }
84
+ }
85
+ const phaseScheduler = new PhaseScheduler();
86
+ export {
87
+ phaseScheduler
88
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Obtiene o crea una versión reactiva de un valor
3
+ *
4
+ * REGLAS:
5
+ * - Valores primitivos → se devuelven tal cual
6
+ * - Objetos → se envuelven en CompositeSignal
7
+ * - Arrays → se envuelven en ReactiveArray
8
+ * - Objetos especiales (Date, RegExp, etc.) → se devuelven tal cual
9
+ * - Instancias ya reactivas → se devuelven tal cual
10
+ *
11
+ * Usa un caché global para garantizar que el mismo objeto/array
12
+ * siempre devuelve la misma instancia reactiva.
13
+ */
14
+ export declare function getOrCreateReactive<T>(value: T): T;
15
+ /**
16
+ * Limpia el caché (útil para testing)
17
+ * Nota: WeakMap no tiene método clear(), así que esta función
18
+ * es principalmente documentativa. El GC limpiará automáticamente
19
+ * las entradas cuando los objetos originales sean recolectados.
20
+ */
21
+ export declare function clearReactiveCache(): void;
@@ -0,0 +1,31 @@
1
+ import { CompositeSignal } from "./signals/composite.js";
2
+ import { ReactiveArray } from "./signals/reactive-array.js";
3
+ const reactiveCache = /* @__PURE__ */ new WeakMap();
4
+ function getOrCreateReactive(value) {
5
+ if (value instanceof CompositeSignal || value instanceof ReactiveArray) {
6
+ return value;
7
+ }
8
+ if (value === null || typeof value !== "object") {
9
+ return value;
10
+ }
11
+ const cached = reactiveCache.get(value);
12
+ if (cached) {
13
+ return cached;
14
+ }
15
+ let reactive;
16
+ if (Array.isArray(value)) {
17
+ reactive = new ReactiveArray(value);
18
+ } else if (isWrappableObject(value)) {
19
+ reactive = new CompositeSignal(value);
20
+ } else {
21
+ return value;
22
+ }
23
+ reactiveCache.set(value, reactive);
24
+ return reactive;
25
+ }
26
+ function isWrappableObject(value) {
27
+ return value !== null && typeof value === "object" && !Array.isArray(value) && !(value instanceof Date) && !(value instanceof RegExp) && !(value instanceof Map) && !(value instanceof Set) && !(value instanceof CompositeSignal) && !(value instanceof ReactiveArray);
28
+ }
29
+ export {
30
+ getOrCreateReactive
31
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,152 @@
1
+ import { Subscriber } from './types';
2
+ export type OnTrackCallback = (signal: any) => void;
3
+ /**
4
+ * ReactiveFrame - Representa un nivel en el stack de contextos reactivos
5
+ *
6
+ * Cada frame contiene toda la información necesaria para ese contexto:
7
+ * - computation: El subscriber (effect/computed) que debe recibir suscripciones
8
+ * - tracking: Si el tracking está activo (lecturas de signals crean suscripciones)
9
+ * - type: El tipo de contexto (para debugging y semántica)
10
+ */
11
+ export interface ReactiveFrame {
12
+ computation: Subscriber | null;
13
+ tracking: boolean;
14
+ type: 'effect' | 'computed' | 'untrack' | 'batch' | 'legacy';
15
+ }
16
+ /**
17
+ * ReactiveContext - Gestiona el contexto reactivo usando un STACK UNIFICADO
18
+ *
19
+ * ARQUITECTURA (POST-FIX):
20
+ * - Un solo stack que contiene todo el estado de contexto
21
+ * - Cada operación (effect, computed, untrack) push/pop un frame
22
+ * - Elimina la ambigüedad de dos stacks con prioridades conflictivas
23
+ * - Garantiza que effects anidados dentro de untrack tengan su propio contexto
24
+ *
25
+ * PROBLEMA QUE RESUELVE:
26
+ * El sistema anterior tenía dos stacks (computationStack y contextStack)
27
+ * donde contextStack tenía prioridad. Esto causaba que effects creados
28
+ * dentro de untrack() usaran la computation del padre en lugar de la propia.
29
+ */
30
+ declare class ReactiveContext {
31
+ /**
32
+ * Stack unificado de contextos reactivos
33
+ * El último frame (top) es siempre el contexto actual
34
+ */
35
+ private stack;
36
+ onTrack: OnTrackCallback | null;
37
+ /**
38
+ * Entra a un nuevo contexto reactivo.
39
+ * Retorna una función para salir del contexto (dispose).
40
+ *
41
+ * @param computation - El subscriber que recibirá suscripciones
42
+ * @param tracking - Si el tracking está activo
43
+ * @param type - Tipo de contexto (para debugging)
44
+ * @returns Función dispose para salir del contexto
45
+ *
46
+ * @example
47
+ * const exit = reactiveContext.enter(computation, true, 'effect');
48
+ * try {
49
+ * // código reactivo...
50
+ * } finally {
51
+ * exit();
52
+ * }
53
+ */
54
+ enter(computation: Subscriber | null, tracking: boolean, type: ReactiveFrame['type']): () => void;
55
+ /**
56
+ * Sale del contexto actual (pop del stack)
57
+ *
58
+ * NOTA: No lanza error si el stack está vacío.
59
+ * Esto es intencional para manejar casos donde:
60
+ * 1. Tests limpian el stack manualmente
61
+ * 2. Async effects intentan cerrar contexto después de cleanup
62
+ */
63
+ exit(): void;
64
+ /**
65
+ * Obtiene la computación actual del contexto.
66
+ * Si hay un frame en el stack, retorna su computation.
67
+ * Si el stack está vacío, retorna null.
68
+ */
69
+ get currentComputation(): Subscriber | null;
70
+ /**
71
+ * Obtiene el estado de tracking actual.
72
+ * Si hay un frame en el stack, retorna su tracking.
73
+ * Si el stack está vacío, retorna false (no tracking por defecto).
74
+ */
75
+ get isTracking(): boolean;
76
+ /**
77
+ * Ejecuta una función sin tracking.
78
+ * Útil para operaciones que no deben crear suscripciones.
79
+ *
80
+ * @param fn - Función a ejecutar sin tracking
81
+ * @returns El resultado de la función
82
+ */
83
+ untrack<T>(fn: () => T): T;
84
+ /**
85
+ * @deprecated Usar enter() en su lugar
86
+ * Push un contexto al stack (para compatibilidad)
87
+ */
88
+ pushContext(computation: Subscriber | null, tracking: boolean): void;
89
+ /**
90
+ * @deprecated Usar exit() en su lugar
91
+ * Pop del stack (para compatibilidad)
92
+ * @throws Error si el stack está vacío (para compatibilidad con tests)
93
+ */
94
+ popContext(): void;
95
+ /**
96
+ * @deprecated Usar enter() en su lugar
97
+ * Agrega una computation al contexto (para compatibilidad con computed.ts)
98
+ */
99
+ pushComputation(comp: Subscriber): void;
100
+ /**
101
+ * @deprecated El sistema unificado no necesita esto
102
+ * Intenta remover una computation (no-op en el nuevo sistema)
103
+ * Nota: En el sistema unificado, el context se maneja via push/pop,
104
+ * no necesitamos remover computaciones específicas.
105
+ */
106
+ removeComputation(computationToRemove: Subscriber): void;
107
+ /**
108
+ * @deprecated Usar enter() con tracking específico
109
+ * Modifica el tracking del frame actual (para compatibilidad)
110
+ */
111
+ setTracking(tracking: boolean): void;
112
+ /**
113
+ * @internal - Solo para testing
114
+ * Obtiene el tamaño del stack
115
+ */
116
+ getContextStackSize(): number;
117
+ /**
118
+ * @internal - Solo para testing/compatibilidad
119
+ * En el sistema unificado, esto es equivalente a getContextStackSize
120
+ */
121
+ getComputationStackSize(): number;
122
+ /**
123
+ * @internal - Solo para testing/debugging
124
+ * Obtiene una copia del stack actual (para inspección)
125
+ */
126
+ getStackSnapshot(): ReactiveFrame[];
127
+ /**
128
+ * @internal - Solo para testing
129
+ * Limpia completamente el stack (útil en beforeEach de tests)
130
+ */
131
+ clearStack(): void;
132
+ /**
133
+ * @internal - Solo para compatibilidad con tests existentes
134
+ * Getter/setter para simular el computationStack antiguo
135
+ */
136
+ get computationStack(): Subscriber[];
137
+ set computationStack(value: Subscriber[]);
138
+ /**
139
+ * @internal - Solo para compatibilidad con tests existentes
140
+ * Getter/setter para simular el contextStack antiguo
141
+ */
142
+ get contextStack(): Array<{
143
+ computation: Subscriber | null;
144
+ tracking: boolean;
145
+ }>;
146
+ set contextStack(value: Array<{
147
+ computation: Subscriber | null;
148
+ tracking: boolean;
149
+ }>);
150
+ }
151
+ export declare const reactiveContext: ReactiveContext;
152
+ export {};