@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,184 @@
1
+ class ReactiveContext {
2
+ constructor() {
3
+ this.stack = [];
4
+ this.onTrack = null;
5
+ }
6
+ // --- API Principal (Nueva) ---
7
+ /**
8
+ * Entra a un nuevo contexto reactivo.
9
+ * Retorna una función para salir del contexto (dispose).
10
+ *
11
+ * @param computation - El subscriber que recibirá suscripciones
12
+ * @param tracking - Si el tracking está activo
13
+ * @param type - Tipo de contexto (para debugging)
14
+ * @returns Función dispose para salir del contexto
15
+ *
16
+ * @example
17
+ * const exit = reactiveContext.enter(computation, true, 'effect');
18
+ * try {
19
+ * // código reactivo...
20
+ * } finally {
21
+ * exit();
22
+ * }
23
+ */
24
+ enter(computation, tracking, type) {
25
+ this.stack.push({ computation, tracking, type });
26
+ let disposed = false;
27
+ return () => {
28
+ if (!disposed) {
29
+ disposed = true;
30
+ this.exit();
31
+ }
32
+ };
33
+ }
34
+ /**
35
+ * Sale del contexto actual (pop del stack)
36
+ *
37
+ * NOTA: No lanza error si el stack está vacío.
38
+ * Esto es intencional para manejar casos donde:
39
+ * 1. Tests limpian el stack manualmente
40
+ * 2. Async effects intentan cerrar contexto después de cleanup
41
+ */
42
+ exit() {
43
+ if (this.stack.length === 0) {
44
+ return;
45
+ }
46
+ this.stack.pop();
47
+ }
48
+ // --- Getters Principales ---
49
+ /**
50
+ * Obtiene la computación actual del contexto.
51
+ * Si hay un frame en el stack, retorna su computation.
52
+ * Si el stack está vacío, retorna null.
53
+ */
54
+ get currentComputation() {
55
+ if (this.stack.length === 0) {
56
+ return null;
57
+ }
58
+ return this.stack[this.stack.length - 1].computation;
59
+ }
60
+ /**
61
+ * Obtiene el estado de tracking actual.
62
+ * Si hay un frame en el stack, retorna su tracking.
63
+ * Si el stack está vacío, retorna false (no tracking por defecto).
64
+ */
65
+ get isTracking() {
66
+ if (this.stack.length === 0) {
67
+ return false;
68
+ }
69
+ return this.stack[this.stack.length - 1].tracking;
70
+ }
71
+ // --- Método Utilitario ---
72
+ /**
73
+ * Ejecuta una función sin tracking.
74
+ * Útil para operaciones que no deben crear suscripciones.
75
+ *
76
+ * @param fn - Función a ejecutar sin tracking
77
+ * @returns El resultado de la función
78
+ */
79
+ untrack(fn) {
80
+ const exit = this.enter(this.currentComputation, false, "untrack");
81
+ try {
82
+ return fn();
83
+ } finally {
84
+ exit();
85
+ }
86
+ }
87
+ // --- API de Compatibilidad (Deprecated pero funcional) ---
88
+ /**
89
+ * @deprecated Usar enter() en su lugar
90
+ * Push un contexto al stack (para compatibilidad)
91
+ */
92
+ pushContext(computation, tracking) {
93
+ this.stack.push({ computation, tracking, type: "legacy" });
94
+ }
95
+ /**
96
+ * @deprecated Usar exit() en su lugar
97
+ * Pop del stack (para compatibilidad)
98
+ * @throws Error si el stack está vacío (para compatibilidad con tests)
99
+ */
100
+ popContext() {
101
+ if (this.stack.length === 0) {
102
+ throw new Error("Cannot pop context: stack is empty");
103
+ }
104
+ this.stack.pop();
105
+ }
106
+ /**
107
+ * @deprecated Usar enter() en su lugar
108
+ * Agrega una computation al contexto (para compatibilidad con computed.ts)
109
+ */
110
+ pushComputation(comp) {
111
+ this.stack.push({ computation: comp, tracking: true, type: "computed" });
112
+ }
113
+ /**
114
+ * @deprecated El sistema unificado no necesita esto
115
+ * Intenta remover una computation (no-op en el nuevo sistema)
116
+ * Nota: En el sistema unificado, el context se maneja via push/pop,
117
+ * no necesitamos remover computaciones específicas.
118
+ */
119
+ removeComputation(computationToRemove) {
120
+ }
121
+ /**
122
+ * @deprecated Usar enter() con tracking específico
123
+ * Modifica el tracking del frame actual (para compatibilidad)
124
+ */
125
+ setTracking(tracking) {
126
+ if (this.stack.length > 0) {
127
+ this.stack[this.stack.length - 1].tracking = tracking;
128
+ }
129
+ }
130
+ // --- Métodos de Debug/Testing ---
131
+ /**
132
+ * @internal - Solo para testing
133
+ * Obtiene el tamaño del stack
134
+ */
135
+ getContextStackSize() {
136
+ return this.stack.length;
137
+ }
138
+ /**
139
+ * @internal - Solo para testing/compatibilidad
140
+ * En el sistema unificado, esto es equivalente a getContextStackSize
141
+ */
142
+ getComputationStackSize() {
143
+ return this.stack.length;
144
+ }
145
+ /**
146
+ * @internal - Solo para testing/debugging
147
+ * Obtiene una copia del stack actual (para inspección)
148
+ */
149
+ getStackSnapshot() {
150
+ return [...this.stack];
151
+ }
152
+ /**
153
+ * @internal - Solo para testing
154
+ * Limpia completamente el stack (útil en beforeEach de tests)
155
+ */
156
+ clearStack() {
157
+ this.stack = [];
158
+ }
159
+ // --- Compatibilidad con tests que acceden a propiedades privadas ---
160
+ /**
161
+ * @internal - Solo para compatibilidad con tests existentes
162
+ * Getter/setter para simular el computationStack antiguo
163
+ */
164
+ get computationStack() {
165
+ return this.stack.filter((f) => f.computation !== null).map((f) => f.computation);
166
+ }
167
+ set computationStack(value) {
168
+ this.stack = [];
169
+ }
170
+ /**
171
+ * @internal - Solo para compatibilidad con tests existentes
172
+ * Getter/setter para simular el contextStack antiguo
173
+ */
174
+ get contextStack() {
175
+ return this.stack.map((f) => ({ computation: f.computation, tracking: f.tracking }));
176
+ }
177
+ set contextStack(value) {
178
+ this.stack = [];
179
+ }
180
+ }
181
+ const reactiveContext = new ReactiveContext();
182
+ export {
183
+ reactiveContext
184
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,120 @@
1
+ import { ReactiveArray } from './reactive-array.js';
2
+ /**
3
+ * Estrategia interna para manejar el acceso a elementos
4
+ * Permite que ReactiveArray funcione tanto con datos propios como derivados
5
+ */
6
+ export interface ArrayStrategy<T> {
7
+ getLength(): number;
8
+ getAt(index: number): T | undefined;
9
+ getItems(): T[];
10
+ isOwned(): boolean;
11
+ }
12
+ /**
13
+ * Estrategia normal: array con datos propios que pueden ser mutados
14
+ * Envuelve automáticamente objetos y arrays con getOrCreateReactive para composición bidireccional
15
+ */
16
+ export declare class OwnedArrayStrategy<T> implements ArrayStrategy<T> {
17
+ private items;
18
+ constructor(items: T[]);
19
+ getLength(): number;
20
+ getAt(index: number): T | undefined;
21
+ getItems(): T[];
22
+ isOwned(): boolean;
23
+ push(...items: T[]): number;
24
+ pop(): T | undefined;
25
+ shift(): T | undefined;
26
+ unshift(...items: T[]): number;
27
+ splice(start: number, deleteCount?: number, ...items: T[]): T[];
28
+ sort(compareFn?: (a: T, b: T) => number): void;
29
+ reverse(): void;
30
+ fill(value: T, start?: number, end?: number): void;
31
+ }
32
+ /**
33
+ * Estrategia derivada: array que computa sus valores desde otro array
34
+ * Implementa memoización granular por elemento
35
+ *
36
+ * El truco clave aquí es que cada elemento tiene su propio subscriber,
37
+ * entonces cuando se transforma un elemento, registramos qué propiedades
38
+ * del objeto fuente se leyeron. Solo invalidamos el caché del elemento
39
+ * si esas propiedades específicas cambian.
40
+ *
41
+ * OPTIMIZACIÓN DE CACHÉ:
42
+ * - push: NO limpia el caché, solo marca que hay nuevos elementos
43
+ * - pop: Solo remueve el último elemento del caché
44
+ * - Otras operaciones: Comportamiento conservador (limpia caché afectado)
45
+ */
46
+ export declare class DerivedArrayStrategy<TSource, TResult> implements ArrayStrategy<TResult> {
47
+ private notifyChange;
48
+ private sourceArray;
49
+ private transformFn;
50
+ private cache;
51
+ private elementSubscribers;
52
+ private structurallyInvalid;
53
+ private knownSourceLength;
54
+ constructor(sourceArray: ReactiveArray<TSource>, transformFn: (value: TSource, index: number) => TResult, notifyChange: () => void);
55
+ /**
56
+ * Configura el tracking para cambios estructurales (longitud y mutation)
57
+ *
58
+ * Usa DOS mecanismos:
59
+ * 1. onChange() para saber qué tipo de operación y optimizar el caché
60
+ * 2. Suscripción reactiva a 'mutation' para disparar re-ejecución de effects externos
61
+ */
62
+ private setupSourceTracking;
63
+ /**
64
+ * Maneja cambios del array fuente de forma inteligente según la operación
65
+ */
66
+ private handleSourceChange;
67
+ /**
68
+ * Invalida todo el caché (comportamiento conservador)
69
+ */
70
+ private invalidateAll;
71
+ getLength(): number;
72
+ /**
73
+ * Este es el método más importante: obtiene un elemento con memoización granular
74
+ *
75
+ * La magia sucede aquí:
76
+ * 1. Si el elemento está en caché y no hay invalidación estructural, lo devuelve
77
+ * 2. Si no, ejecuta la transformación en un contexto de tracking
78
+ * 3. Las propiedades accedidas durante la transformación se registran
79
+ * 4. Solo si esas propiedades específicas cambian, se invalida el caché
80
+ */
81
+ getAt(index: number): TResult | undefined;
82
+ getItems(): TResult[];
83
+ isOwned(): boolean;
84
+ }
85
+ /**
86
+ * Estrategia derivada para arrays filtrados
87
+ * Mantiene una relación entre índices filtrados y fuente
88
+ *
89
+ * La complejidad aquí es que los índices no son lineales:
90
+ * - filtered[0] podría corresponder a source[2]
91
+ * - filtered[1] podría corresponder a source[4]
92
+ *
93
+ * Esta estrategia mantiene dos mapeos:
94
+ * 1. sourceIndex -> filteredIndex (o -1 si no pasa el filtro)
95
+ * 2. filteredIndex -> sourceIndex
96
+ */
97
+ export declare class FilteredArrayStrategy<T> implements ArrayStrategy<T> {
98
+ private notifyChange;
99
+ private sourceArray;
100
+ private predicateFn;
101
+ private filteredCache;
102
+ private sourceToFiltered;
103
+ private filteredToSource;
104
+ private elementSubscribers;
105
+ private structurallyInvalid;
106
+ private structuralSubscriber?;
107
+ constructor(sourceArray: ReactiveArray<T>, predicateFn: (value: T, index: number, array: T[]) => boolean, notifyChange: () => void);
108
+ /**
109
+ * Configura tracking para cambios estructurales y mutation
110
+ */
111
+ private setupSourceTracking;
112
+ /**
113
+ * Recalcula los mapeos y cache si es necesario
114
+ */
115
+ private recalculateIfNeeded;
116
+ getLength(): number;
117
+ getAt(index: number): T | undefined;
118
+ getItems(): T[];
119
+ isOwned(): boolean;
120
+ }
@@ -0,0 +1,261 @@
1
+ import { withContext } from "../context-scope.js";
2
+ import { getOrCreateReactive } from "../reactive-cache.js";
3
+ class OwnedArrayStrategy {
4
+ constructor(items) {
5
+ this.items = items;
6
+ this.items = items.map((item) => getOrCreateReactive(item));
7
+ }
8
+ getLength() {
9
+ return this.items.length;
10
+ }
11
+ getAt(index) {
12
+ const normalized = index < 0 ? this.items.length + index : index;
13
+ return this.items[normalized];
14
+ }
15
+ getItems() {
16
+ return this.items;
17
+ }
18
+ isOwned() {
19
+ return true;
20
+ }
21
+ // CLAVE: Envolver elementos automáticamente en todas las mutaciones
22
+ push(...items) {
23
+ const wrappedItems = items.map((item) => getOrCreateReactive(item));
24
+ return this.items.push(...wrappedItems);
25
+ }
26
+ pop() {
27
+ return this.items.pop();
28
+ }
29
+ shift() {
30
+ return this.items.shift();
31
+ }
32
+ unshift(...items) {
33
+ const wrappedItems = items.map((item) => getOrCreateReactive(item));
34
+ return this.items.unshift(...wrappedItems);
35
+ }
36
+ splice(start, deleteCount, ...items) {
37
+ const wrappedItems = items.map((item) => getOrCreateReactive(item));
38
+ return this.items.splice(start, deleteCount ?? this.items.length - start, ...wrappedItems);
39
+ }
40
+ sort(compareFn) {
41
+ this.items.sort(compareFn);
42
+ }
43
+ reverse() {
44
+ this.items.reverse();
45
+ }
46
+ fill(value, start, end) {
47
+ const wrappedValue = getOrCreateReactive(value);
48
+ this.items.fill(wrappedValue, start, end);
49
+ }
50
+ }
51
+ class DerivedArrayStrategy {
52
+ constructor(sourceArray, transformFn, notifyChange) {
53
+ this.notifyChange = notifyChange;
54
+ this.cache = /* @__PURE__ */ new Map();
55
+ this.elementSubscribers = /* @__PURE__ */ new Map();
56
+ this.structurallyInvalid = true;
57
+ this.knownSourceLength = 0;
58
+ this.sourceArray = sourceArray;
59
+ this.transformFn = transformFn;
60
+ this.setupSourceTracking();
61
+ }
62
+ /**
63
+ * Configura el tracking para cambios estructurales (longitud y mutation)
64
+ *
65
+ * Usa DOS mecanismos:
66
+ * 1. onChange() para saber qué tipo de operación y optimizar el caché
67
+ * 2. Suscripción reactiva a 'mutation' para disparar re-ejecución de effects externos
68
+ */
69
+ setupSourceTracking() {
70
+ this.sourceArray.onChange((operation, ...args) => {
71
+ this.handleSourceChange(operation, args);
72
+ });
73
+ const reactiveSubscriber = () => {
74
+ this.notifyChange();
75
+ };
76
+ reactiveSubscriber._isComputation = true;
77
+ this.sourceArray._subscribe("mutation", reactiveSubscriber);
78
+ this.knownSourceLength = this.sourceArray.length;
79
+ }
80
+ /**
81
+ * Maneja cambios del array fuente de forma inteligente según la operación
82
+ */
83
+ handleSourceChange(operation, args) {
84
+ const newLength = this.sourceArray.length;
85
+ switch (operation) {
86
+ case "push":
87
+ this.knownSourceLength = newLength;
88
+ break;
89
+ case "pop":
90
+ const removedIndex = this.knownSourceLength - 1;
91
+ if (removedIndex >= 0) {
92
+ this.cache.delete(removedIndex);
93
+ this.elementSubscribers.delete(removedIndex);
94
+ }
95
+ this.knownSourceLength = newLength;
96
+ break;
97
+ case "shift":
98
+ case "unshift":
99
+ case "splice":
100
+ case "sort":
101
+ case "reverse":
102
+ case "fill":
103
+ this.invalidateAll();
104
+ this.knownSourceLength = newLength;
105
+ break;
106
+ default:
107
+ this.invalidateAll();
108
+ this.knownSourceLength = newLength;
109
+ break;
110
+ }
111
+ }
112
+ /**
113
+ * Invalida todo el caché (comportamiento conservador)
114
+ */
115
+ invalidateAll() {
116
+ this.structurallyInvalid = true;
117
+ this.cache.clear();
118
+ this.elementSubscribers.clear();
119
+ }
120
+ getLength() {
121
+ return this.sourceArray.length;
122
+ }
123
+ /**
124
+ * Este es el método más importante: obtiene un elemento con memoización granular
125
+ *
126
+ * La magia sucede aquí:
127
+ * 1. Si el elemento está en caché y no hay invalidación estructural, lo devuelve
128
+ * 2. Si no, ejecuta la transformación en un contexto de tracking
129
+ * 3. Las propiedades accedidas durante la transformación se registran
130
+ * 4. Solo si esas propiedades específicas cambian, se invalida el caché
131
+ */
132
+ getAt(index) {
133
+ const normalized = index < 0 ? this.getLength() + index : index;
134
+ if (normalized < 0 || normalized >= this.getLength()) {
135
+ return void 0;
136
+ }
137
+ if (!this.structurallyInvalid && this.cache.has(normalized)) {
138
+ return this.cache.get(normalized);
139
+ }
140
+ if (!this.elementSubscribers.has(normalized)) {
141
+ const elementSubscriber = () => {
142
+ this.cache.delete(normalized);
143
+ this.notifyChange();
144
+ };
145
+ elementSubscriber._isComputation = true;
146
+ this.elementSubscribers.set(normalized, elementSubscriber);
147
+ }
148
+ return withContext(this.elementSubscribers.get(normalized), true, () => {
149
+ const sourceElement = this.sourceArray.at(normalized);
150
+ const result = this.transformFn(sourceElement, normalized);
151
+ this.cache.set(normalized, result);
152
+ this.structurallyInvalid = false;
153
+ return result;
154
+ });
155
+ }
156
+ getItems() {
157
+ const length = this.getLength();
158
+ const result = [];
159
+ for (let i = 0; i < length; i++) {
160
+ const item = this.getAt(i);
161
+ result.push(item);
162
+ }
163
+ return result;
164
+ }
165
+ isOwned() {
166
+ return false;
167
+ }
168
+ }
169
+ class FilteredArrayStrategy {
170
+ constructor(sourceArray, predicateFn, notifyChange) {
171
+ this.notifyChange = notifyChange;
172
+ this.filteredCache = [];
173
+ this.sourceToFiltered = /* @__PURE__ */ new Map();
174
+ this.filteredToSource = /* @__PURE__ */ new Map();
175
+ this.elementSubscribers = /* @__PURE__ */ new Map();
176
+ this.structurallyInvalid = true;
177
+ this.sourceArray = sourceArray;
178
+ this.predicateFn = predicateFn;
179
+ this.setupSourceTracking();
180
+ }
181
+ /**
182
+ * Configura tracking para cambios estructurales y mutation
183
+ */
184
+ setupSourceTracking() {
185
+ const structuralSubscriber = () => {
186
+ this.structurallyInvalid = true;
187
+ this.filteredCache = [];
188
+ this.sourceToFiltered.clear();
189
+ this.filteredToSource.clear();
190
+ this.elementSubscribers.clear();
191
+ this.notifyChange();
192
+ };
193
+ structuralSubscriber._isComputation = true;
194
+ this.structuralSubscriber = structuralSubscriber;
195
+ withContext(structuralSubscriber, true, () => {
196
+ void this.sourceArray.length;
197
+ this.sourceArray._subscribe("mutation", structuralSubscriber);
198
+ });
199
+ }
200
+ /**
201
+ * Recalcula los mapeos y cache si es necesario
202
+ */
203
+ recalculateIfNeeded() {
204
+ if (!this.structurallyInvalid && this.filteredCache.length > 0) {
205
+ return;
206
+ }
207
+ this.filteredCache = [];
208
+ this.sourceToFiltered.clear();
209
+ this.filteredToSource.clear();
210
+ const sourceLength = this.sourceArray.length;
211
+ let filteredIndex = 0;
212
+ for (let sourceIndex = 0; sourceIndex < sourceLength; sourceIndex++) {
213
+ if (!this.elementSubscribers.has(sourceIndex)) {
214
+ const elementSubscriber = () => {
215
+ this.structurallyInvalid = true;
216
+ this.notifyChange();
217
+ };
218
+ elementSubscriber._isComputation = true;
219
+ this.elementSubscribers.set(sourceIndex, elementSubscriber);
220
+ }
221
+ withContext(this.elementSubscribers.get(sourceIndex), true, () => {
222
+ const sourceElement = this.sourceArray.at(sourceIndex);
223
+ const sourceItems = this.sourceArray.getPlainValue();
224
+ const passesFilter = this.predicateFn(sourceElement, sourceIndex, sourceItems);
225
+ if (passesFilter) {
226
+ this.filteredCache.push(sourceElement);
227
+ this.sourceToFiltered.set(sourceIndex, filteredIndex);
228
+ this.filteredToSource.set(filteredIndex, sourceIndex);
229
+ filteredIndex++;
230
+ } else {
231
+ this.sourceToFiltered.set(sourceIndex, -1);
232
+ }
233
+ });
234
+ }
235
+ this.structurallyInvalid = false;
236
+ }
237
+ getLength() {
238
+ this.recalculateIfNeeded();
239
+ return this.filteredCache.length;
240
+ }
241
+ getAt(index) {
242
+ this.recalculateIfNeeded();
243
+ const normalized = index < 0 ? this.filteredCache.length + index : index;
244
+ if (normalized < 0 || normalized >= this.filteredCache.length) {
245
+ return void 0;
246
+ }
247
+ return this.filteredCache[normalized];
248
+ }
249
+ getItems() {
250
+ this.recalculateIfNeeded();
251
+ return [...this.filteredCache];
252
+ }
253
+ isOwned() {
254
+ return false;
255
+ }
256
+ }
257
+ export {
258
+ DerivedArrayStrategy,
259
+ FilteredArrayStrategy,
260
+ OwnedArrayStrategy
261
+ };