@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,89 @@
|
|
|
1
|
+
import { Subscriber } from '../types.js';
|
|
2
|
+
export type { Subscriber };
|
|
3
|
+
/**
|
|
4
|
+
* CompositeSignal - Con caché compartido y composición automática
|
|
5
|
+
*
|
|
6
|
+
* Soporta reactividad profunda con composición automática:
|
|
7
|
+
* - Objetos anidados se envuelven automáticamente en CompositeSignal
|
|
8
|
+
* - Arrays anidados se envuelven automáticamente en ReactiveArray
|
|
9
|
+
* - Usa caché compartido global para garantizar consistencia
|
|
10
|
+
* - El tracking funciona en cualquier nivel de profundidad
|
|
11
|
+
*
|
|
12
|
+
* IMPORTANTE: Usa el mismo tipo Subscriber que Signal, que es una función.
|
|
13
|
+
* Esto permite integración completa con el sistema de reactividad existente.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CompositeSignal<T extends object> {
|
|
16
|
+
private value;
|
|
17
|
+
private propertySubscribers;
|
|
18
|
+
private nestedReactives;
|
|
19
|
+
private onChangeCallback?;
|
|
20
|
+
constructor(initialValue: T);
|
|
21
|
+
/**
|
|
22
|
+
* Registra un callback que se llamará cada vez que cualquier propiedad cambie
|
|
23
|
+
* El callback se llama síncronamente antes de cualquier notificación a subscribers
|
|
24
|
+
*
|
|
25
|
+
* @param callback - Función que recibe (property, oldValue, newValue)
|
|
26
|
+
*/
|
|
27
|
+
onChange(callback: (property: string | symbol, oldValue: any, newValue: any) => void): void;
|
|
28
|
+
/**
|
|
29
|
+
* Obtiene el objeto JavaScript plano subyacente, sin envolver en CompositeSignal
|
|
30
|
+
*
|
|
31
|
+
* @returns El objeto plano original
|
|
32
|
+
*/
|
|
33
|
+
getPlainValue(): T;
|
|
34
|
+
/**
|
|
35
|
+
* Obtiene el valor de una propiedad del objeto almacenado
|
|
36
|
+
* Si hay un efecto activo en reactiveContext, lo registra automáticamente
|
|
37
|
+
* como subscriber de esta propiedad
|
|
38
|
+
*
|
|
39
|
+
* COMPOSICIÓN AUTOMÁTICA:
|
|
40
|
+
* - Si el valor es un objeto → devuelve CompositeSignal
|
|
41
|
+
* - Si el valor es un array → devuelve ReactiveArray
|
|
42
|
+
* - Si el valor es primitivo → devuelve el valor directo
|
|
43
|
+
*
|
|
44
|
+
* Usa caché compartido para garantizar consistencia
|
|
45
|
+
*
|
|
46
|
+
* @param property - La clave de la propiedad a leer
|
|
47
|
+
* @returns El valor de la propiedad (envuelto si es objeto/array)
|
|
48
|
+
*/
|
|
49
|
+
get(property: string | symbol): any;
|
|
50
|
+
/**
|
|
51
|
+
* Actualiza el valor de una propiedad en el objeto almacenado y notifica a los subscribers
|
|
52
|
+
* Solo notifica si el valor realmente cambió (usa Object.is para comparación)
|
|
53
|
+
*
|
|
54
|
+
* IMPORTANTE: Si se reemplaza un objeto, invalida el caché del CompositeSignal anidado
|
|
55
|
+
*
|
|
56
|
+
* @param property - La clave de la propiedad a actualizar
|
|
57
|
+
* @param newValue - El nuevo valor para la propiedad
|
|
58
|
+
*/
|
|
59
|
+
set(property: string | symbol, newValue: any): void;
|
|
60
|
+
/**
|
|
61
|
+
* Notifica a todos los subscribers de una propiedad específica
|
|
62
|
+
* Distingue entre Computed (síncrono) y Effect (agendado en scheduler)
|
|
63
|
+
* @param property - La propiedad cuyos subscribers deben ser notificados
|
|
64
|
+
*/
|
|
65
|
+
private _notifyProperty;
|
|
66
|
+
/**
|
|
67
|
+
* Registra un subscriber para una propiedad específica
|
|
68
|
+
* @param property - La propiedad a observar
|
|
69
|
+
* @param subscriber - El subscriber que se ejecutará cuando la propiedad cambie
|
|
70
|
+
*/
|
|
71
|
+
subscribeToProperty(property: string | symbol, subscriber: Subscriber): void;
|
|
72
|
+
/**
|
|
73
|
+
* Método helper para inspeccionar los subscribers registrados (útil para testing)
|
|
74
|
+
* @param property - La propiedad a inspeccionar
|
|
75
|
+
* @returns El Set de subscribers para esa propiedad, o undefined si no hay
|
|
76
|
+
*/
|
|
77
|
+
getSubscribers(property: string | symbol): Set<Subscriber> | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Método helper para obtener todas las propiedades que tienen subscribers
|
|
80
|
+
* @returns Array de propiedades que tienen al menos un subscriber
|
|
81
|
+
*/
|
|
82
|
+
getSubscribedProperties(): (string | symbol)[];
|
|
83
|
+
/**
|
|
84
|
+
* ✅ NUEVO: Trackea shallow (cualquier cambio en el objeto)
|
|
85
|
+
* Se llama cuando se itera sobre el objeto (Object.keys, for...in, etc.)
|
|
86
|
+
* El effect se ejecutará cuando CUALQUIER propiedad cambie
|
|
87
|
+
*/
|
|
88
|
+
trackShallow(): void;
|
|
89
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { reactiveContext } from "../reactive-context.js";
|
|
2
|
+
import { phaseScheduler } from "../phase-scheduler.js";
|
|
3
|
+
import { getOrCreateReactive } from "../reactive-cache.js";
|
|
4
|
+
const SHALLOW_KEY = Symbol.for("__composite_shallow__");
|
|
5
|
+
class CompositeSignal {
|
|
6
|
+
constructor(initialValue) {
|
|
7
|
+
this.propertySubscribers = /* @__PURE__ */ new Map();
|
|
8
|
+
this.nestedReactives = /* @__PURE__ */ new Map();
|
|
9
|
+
this.value = initialValue;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Registra un callback que se llamará cada vez que cualquier propiedad cambie
|
|
13
|
+
* El callback se llama síncronamente antes de cualquier notificación a subscribers
|
|
14
|
+
*
|
|
15
|
+
* @param callback - Función que recibe (property, oldValue, newValue)
|
|
16
|
+
*/
|
|
17
|
+
onChange(callback) {
|
|
18
|
+
this.onChangeCallback = callback;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Obtiene el objeto JavaScript plano subyacente, sin envolver en CompositeSignal
|
|
22
|
+
*
|
|
23
|
+
* @returns El objeto plano original
|
|
24
|
+
*/
|
|
25
|
+
getPlainValue() {
|
|
26
|
+
return this.value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Obtiene el valor de una propiedad del objeto almacenado
|
|
30
|
+
* Si hay un efecto activo en reactiveContext, lo registra automáticamente
|
|
31
|
+
* como subscriber de esta propiedad
|
|
32
|
+
*
|
|
33
|
+
* COMPOSICIÓN AUTOMÁTICA:
|
|
34
|
+
* - Si el valor es un objeto → devuelve CompositeSignal
|
|
35
|
+
* - Si el valor es un array → devuelve ReactiveArray
|
|
36
|
+
* - Si el valor es primitivo → devuelve el valor directo
|
|
37
|
+
*
|
|
38
|
+
* Usa caché compartido para garantizar consistencia
|
|
39
|
+
*
|
|
40
|
+
* @param property - La clave de la propiedad a leer
|
|
41
|
+
* @returns El valor de la propiedad (envuelto si es objeto/array)
|
|
42
|
+
*/
|
|
43
|
+
get(property) {
|
|
44
|
+
if (reactiveContext.currentComputation && reactiveContext.isTracking) {
|
|
45
|
+
this.subscribeToProperty(property, reactiveContext.currentComputation);
|
|
46
|
+
}
|
|
47
|
+
const value = this.value[property];
|
|
48
|
+
if (value === null || typeof value !== "object") {
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
if (!this.nestedReactives.has(property)) {
|
|
52
|
+
const reactive = getOrCreateReactive(value);
|
|
53
|
+
this.nestedReactives.set(property, reactive);
|
|
54
|
+
}
|
|
55
|
+
return this.nestedReactives.get(property);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Actualiza el valor de una propiedad en el objeto almacenado y notifica a los subscribers
|
|
59
|
+
* Solo notifica si el valor realmente cambió (usa Object.is para comparación)
|
|
60
|
+
*
|
|
61
|
+
* IMPORTANTE: Si se reemplaza un objeto, invalida el caché del CompositeSignal anidado
|
|
62
|
+
*
|
|
63
|
+
* @param property - La clave de la propiedad a actualizar
|
|
64
|
+
* @param newValue - El nuevo valor para la propiedad
|
|
65
|
+
*/
|
|
66
|
+
set(property, newValue) {
|
|
67
|
+
const oldValue = this.value[property];
|
|
68
|
+
if (!Object.is(oldValue, newValue)) {
|
|
69
|
+
this.value[property] = newValue;
|
|
70
|
+
if (this.onChangeCallback) {
|
|
71
|
+
this.onChangeCallback(property, oldValue, newValue);
|
|
72
|
+
}
|
|
73
|
+
if (this.nestedReactives.has(property)) {
|
|
74
|
+
this.nestedReactives.delete(property);
|
|
75
|
+
}
|
|
76
|
+
this._notifyProperty(property);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Notifica a todos los subscribers de una propiedad específica
|
|
81
|
+
* Distingue entre Computed (síncrono) y Effect (agendado en scheduler)
|
|
82
|
+
* @param property - La propiedad cuyos subscribers deben ser notificados
|
|
83
|
+
*/
|
|
84
|
+
_notifyProperty(property) {
|
|
85
|
+
const subscribers = this.propertySubscribers.get(property);
|
|
86
|
+
if (subscribers) {
|
|
87
|
+
subscribers.forEach((subscriber) => {
|
|
88
|
+
if (subscriber._isComputation) {
|
|
89
|
+
subscriber();
|
|
90
|
+
} else {
|
|
91
|
+
phaseScheduler.schedule(subscriber);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const shallowSubscribers = this.propertySubscribers.get(SHALLOW_KEY);
|
|
96
|
+
if (shallowSubscribers) {
|
|
97
|
+
shallowSubscribers.forEach((subscriber) => {
|
|
98
|
+
if (subscriber._isComputation) {
|
|
99
|
+
subscriber();
|
|
100
|
+
} else {
|
|
101
|
+
phaseScheduler.schedule(subscriber);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Registra un subscriber para una propiedad específica
|
|
108
|
+
* @param property - La propiedad a observar
|
|
109
|
+
* @param subscriber - El subscriber que se ejecutará cuando la propiedad cambie
|
|
110
|
+
*/
|
|
111
|
+
subscribeToProperty(property, subscriber) {
|
|
112
|
+
if (!this.propertySubscribers.has(property)) {
|
|
113
|
+
this.propertySubscribers.set(property, /* @__PURE__ */ new Set());
|
|
114
|
+
}
|
|
115
|
+
this.propertySubscribers.get(property).add(subscriber);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Método helper para inspeccionar los subscribers registrados (útil para testing)
|
|
119
|
+
* @param property - La propiedad a inspeccionar
|
|
120
|
+
* @returns El Set de subscribers para esa propiedad, o undefined si no hay
|
|
121
|
+
*/
|
|
122
|
+
getSubscribers(property) {
|
|
123
|
+
return this.propertySubscribers.get(property);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Método helper para obtener todas las propiedades que tienen subscribers
|
|
127
|
+
* @returns Array de propiedades que tienen al menos un subscriber
|
|
128
|
+
*/
|
|
129
|
+
getSubscribedProperties() {
|
|
130
|
+
return Array.from(this.propertySubscribers.keys());
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* ✅ NUEVO: Trackea shallow (cualquier cambio en el objeto)
|
|
134
|
+
* Se llama cuando se itera sobre el objeto (Object.keys, for...in, etc.)
|
|
135
|
+
* El effect se ejecutará cuando CUALQUIER propiedad cambie
|
|
136
|
+
*/
|
|
137
|
+
trackShallow() {
|
|
138
|
+
if (reactiveContext.currentComputation && reactiveContext.isTracking) {
|
|
139
|
+
this.subscribeToProperty(SHALLOW_KEY, reactiveContext.currentComputation);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export {
|
|
144
|
+
CompositeSignal
|
|
145
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { ISignal } from './signal';
|
|
2
|
+
/**
|
|
3
|
+
* Computed Signal - Lazy evaluation with dirty flag (like Solid.js, Vue 3)
|
|
4
|
+
*
|
|
5
|
+
* Características:
|
|
6
|
+
* - Solo recalcula cuando se lee (lazy/pull-based)
|
|
7
|
+
* - Usa un flag "_isDirty" para saber si necesita recalcular
|
|
8
|
+
* - Recalcula SÍNCRONAMENTE cuando se lee y está dirty
|
|
9
|
+
* - NO usa scheduler asíncrono para recalcular (no hay glitches)
|
|
10
|
+
* - Trackea sus dependencias automáticamente
|
|
11
|
+
*
|
|
12
|
+
* STACK UNIFICADO:
|
|
13
|
+
* - Usa reactiveContext.enter() para crear su contexto de tracking
|
|
14
|
+
* - Garantiza limpieza correcta del contexto
|
|
15
|
+
*/
|
|
16
|
+
export declare class Computed<T> implements ISignal<T> {
|
|
17
|
+
readonly isSignal = true;
|
|
18
|
+
private _value;
|
|
19
|
+
private _subscribers;
|
|
20
|
+
private _getter;
|
|
21
|
+
private _isDirty;
|
|
22
|
+
private _computation;
|
|
23
|
+
private _sources;
|
|
24
|
+
constructor(getter: () => T);
|
|
25
|
+
get(): T;
|
|
26
|
+
/**
|
|
27
|
+
* Recalcula el valor del computed síncronamente.
|
|
28
|
+
* Se ejecuta cuando:
|
|
29
|
+
* 1. Se lee el computed (get) y está dirty
|
|
30
|
+
* 2. Es la primera vez que se lee
|
|
31
|
+
*/
|
|
32
|
+
private _recompute;
|
|
33
|
+
/**
|
|
34
|
+
* Notifica a los subscribers que este computed cambió.
|
|
35
|
+
*
|
|
36
|
+
* FIX: Distingue entre Computed y Effect:
|
|
37
|
+
* - Computed: Ejecutar síncronamente
|
|
38
|
+
* - Effect: Agendar en el scheduler
|
|
39
|
+
*/
|
|
40
|
+
private _notify;
|
|
41
|
+
/**
|
|
42
|
+
* Limpia las suscripciones a las signals anteriores.
|
|
43
|
+
* Este es el patrón Solid/Vue de bi-directional tracking:
|
|
44
|
+
* - Signal sabe quién depende de ella (_subscribers)
|
|
45
|
+
* - Computed sabe de qué signals depende (_sources)
|
|
46
|
+
*
|
|
47
|
+
* Cuando recalculamos, necesitamos:
|
|
48
|
+
* 1. Des-suscribirnos de las signals viejas
|
|
49
|
+
* 2. Re-trackear las nuevas signals que leemos
|
|
50
|
+
*
|
|
51
|
+
* Esto permite dependencias dinámicas/condicionales.
|
|
52
|
+
*/
|
|
53
|
+
private _cleanup;
|
|
54
|
+
set(newValue: T): void;
|
|
55
|
+
update(updater: (currentValue: T) => T): void;
|
|
56
|
+
/**
|
|
57
|
+
* Limpia los recursos del computed.
|
|
58
|
+
*/
|
|
59
|
+
dispose(): void;
|
|
60
|
+
}
|
|
61
|
+
export declare function computed<T>(getter: () => T): ISignal<T>;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { reactiveContext } from "../reactive-context.js";
|
|
2
|
+
import { phaseScheduler } from "../phase-scheduler.js";
|
|
3
|
+
class Computed {
|
|
4
|
+
constructor(getter) {
|
|
5
|
+
this.isSignal = true;
|
|
6
|
+
this._subscribers = /* @__PURE__ */ new Set();
|
|
7
|
+
this._isDirty = true;
|
|
8
|
+
this._sources = /* @__PURE__ */ new Set();
|
|
9
|
+
this._getter = getter;
|
|
10
|
+
this._value = void 0;
|
|
11
|
+
const self = this;
|
|
12
|
+
this._computation = () => {
|
|
13
|
+
self._isDirty = true;
|
|
14
|
+
self._notify();
|
|
15
|
+
};
|
|
16
|
+
this._computation.priority = "Sync";
|
|
17
|
+
this._computation._isComputation = true;
|
|
18
|
+
}
|
|
19
|
+
get() {
|
|
20
|
+
if (this._isDirty) {
|
|
21
|
+
this._recompute();
|
|
22
|
+
}
|
|
23
|
+
if (reactiveContext.currentComputation && reactiveContext.isTracking) {
|
|
24
|
+
this._subscribers.add(reactiveContext.currentComputation);
|
|
25
|
+
}
|
|
26
|
+
return this._value;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Recalcula el valor del computed síncronamente.
|
|
30
|
+
* Se ejecuta cuando:
|
|
31
|
+
* 1. Se lee el computed (get) y está dirty
|
|
32
|
+
* 2. Es la primera vez que se lee
|
|
33
|
+
*/
|
|
34
|
+
_recompute() {
|
|
35
|
+
this._isDirty = false;
|
|
36
|
+
this._cleanup();
|
|
37
|
+
const previousOnTrack = reactiveContext.onTrack;
|
|
38
|
+
reactiveContext.onTrack = (signal) => {
|
|
39
|
+
this._sources.add(signal);
|
|
40
|
+
};
|
|
41
|
+
const exitContext = reactiveContext.enter(this._computation, true, "computed");
|
|
42
|
+
try {
|
|
43
|
+
const newValue = this._getter();
|
|
44
|
+
this._value = newValue;
|
|
45
|
+
} finally {
|
|
46
|
+
exitContext();
|
|
47
|
+
reactiveContext.onTrack = previousOnTrack;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Notifica a los subscribers que este computed cambió.
|
|
52
|
+
*
|
|
53
|
+
* FIX: Distingue entre Computed y Effect:
|
|
54
|
+
* - Computed: Ejecutar síncronamente
|
|
55
|
+
* - Effect: Agendar en el scheduler
|
|
56
|
+
*/
|
|
57
|
+
_notify() {
|
|
58
|
+
this._subscribers.forEach((subscriber) => {
|
|
59
|
+
if (subscriber._isComputation) {
|
|
60
|
+
subscriber();
|
|
61
|
+
} else {
|
|
62
|
+
phaseScheduler.schedule(subscriber);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Limpia las suscripciones a las signals anteriores.
|
|
68
|
+
* Este es el patrón Solid/Vue de bi-directional tracking:
|
|
69
|
+
* - Signal sabe quién depende de ella (_subscribers)
|
|
70
|
+
* - Computed sabe de qué signals depende (_sources)
|
|
71
|
+
*
|
|
72
|
+
* Cuando recalculamos, necesitamos:
|
|
73
|
+
* 1. Des-suscribirnos de las signals viejas
|
|
74
|
+
* 2. Re-trackear las nuevas signals que leemos
|
|
75
|
+
*
|
|
76
|
+
* Esto permite dependencias dinámicas/condicionales.
|
|
77
|
+
*/
|
|
78
|
+
_cleanup() {
|
|
79
|
+
this._sources.forEach((source) => {
|
|
80
|
+
if (source._unsubscribe) {
|
|
81
|
+
source._unsubscribe(this._computation);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this._sources.clear();
|
|
85
|
+
}
|
|
86
|
+
// Las signals computadas son de solo lectura
|
|
87
|
+
set(newValue) {
|
|
88
|
+
throw new Error("Cannot set a computed signal.");
|
|
89
|
+
}
|
|
90
|
+
update(updater) {
|
|
91
|
+
throw new Error("Cannot update a computed signal.");
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Limpia los recursos del computed.
|
|
95
|
+
*/
|
|
96
|
+
dispose() {
|
|
97
|
+
this._cleanup();
|
|
98
|
+
this._subscribers.clear();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function computed(getter) {
|
|
102
|
+
return new Computed(getter);
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
Computed,
|
|
106
|
+
computed
|
|
107
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ISignal } from './signal';
|
|
2
|
+
export declare class Derived<T> implements ISignal<T> {
|
|
3
|
+
readonly isSignal = true;
|
|
4
|
+
private _inner;
|
|
5
|
+
constructor(source: ISignal<T>, mapper?: (value: T) => T);
|
|
6
|
+
get(): T;
|
|
7
|
+
set(_: T): void;
|
|
8
|
+
update(_: (currentValue: T) => T): void;
|
|
9
|
+
}
|
|
10
|
+
export declare function derived<T>(source: ISignal<T>, mapper?: (value: T) => T): ISignal<T>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { computed } from "./computed.js";
|
|
2
|
+
class Derived {
|
|
3
|
+
constructor(source, mapper) {
|
|
4
|
+
this.isSignal = true;
|
|
5
|
+
const safeMapper = mapper ?? ((v) => v);
|
|
6
|
+
this._inner = computed(() => safeMapper(source.get()));
|
|
7
|
+
}
|
|
8
|
+
get() {
|
|
9
|
+
return this._inner.get();
|
|
10
|
+
}
|
|
11
|
+
set(_) {
|
|
12
|
+
throw new Error("Cannot set a ContextSignal.");
|
|
13
|
+
}
|
|
14
|
+
update(_) {
|
|
15
|
+
throw new Error("Cannot update a ContextSignal.");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function derived(source, mapper) {
|
|
19
|
+
return new Derived(source, mapper);
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
Derived,
|
|
23
|
+
derived
|
|
24
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
interface Computation extends Function {
|
|
2
|
+
}
|
|
3
|
+
/**
|
|
4
|
+
* Crea un effect reactivo que se re-ejecuta cuando sus dependencias cambian
|
|
5
|
+
*
|
|
6
|
+
* Sistema basado en fases:
|
|
7
|
+
* - Elimina glitches garantizando orden de ejecución consistente
|
|
8
|
+
* - Batching automático de actualizaciones
|
|
9
|
+
* - Ordenamiento topológico de dependencias
|
|
10
|
+
*
|
|
11
|
+
* IMPORTANTE (Stack Unificado):
|
|
12
|
+
* - Cada effect usa reactiveContext.enter() para crear su propio frame
|
|
13
|
+
* - Esto garantiza que el effect tenga su propio contexto incluso si
|
|
14
|
+
* se crea dentro de un untrack() del padre
|
|
15
|
+
* - Resuelve el bug de suscripciones perdidas en effects anidados
|
|
16
|
+
*
|
|
17
|
+
* @param fn - Función a ejecutar. Recibe onCleanup para registrar limpieza
|
|
18
|
+
* @param options - Opciones (deprecado: priority ya no se usa)
|
|
19
|
+
* @returns Objeto con métodos run y dispose
|
|
20
|
+
*/
|
|
21
|
+
export declare function effect(fn: (onCleanup: (cb: () => void) => void) => void | Promise<void>, options?: {
|
|
22
|
+
priority?: string;
|
|
23
|
+
}): {
|
|
24
|
+
run: Computation;
|
|
25
|
+
dispose: () => void;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { reactiveContext } from "../reactive-context.js";
|
|
2
|
+
function effect(fn, options) {
|
|
3
|
+
let cleanupFn = null;
|
|
4
|
+
let isDisposed = false;
|
|
5
|
+
const onCleanup = (cb) => {
|
|
6
|
+
cleanupFn = cb;
|
|
7
|
+
};
|
|
8
|
+
const computation = () => {
|
|
9
|
+
if (isDisposed) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
if (cleanupFn) {
|
|
13
|
+
cleanupFn();
|
|
14
|
+
cleanupFn = null;
|
|
15
|
+
}
|
|
16
|
+
const exitContext = reactiveContext.enter(computation, true, "effect");
|
|
17
|
+
try {
|
|
18
|
+
const result = fn(onCleanup);
|
|
19
|
+
if (result && typeof result.then === "function") {
|
|
20
|
+
result.finally(exitContext);
|
|
21
|
+
} else {
|
|
22
|
+
exitContext();
|
|
23
|
+
}
|
|
24
|
+
} catch (error) {
|
|
25
|
+
exitContext();
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
computation();
|
|
30
|
+
return {
|
|
31
|
+
run: computation,
|
|
32
|
+
dispose: () => {
|
|
33
|
+
if (isDisposed) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
isDisposed = true;
|
|
37
|
+
if (cleanupFn) {
|
|
38
|
+
cleanupFn();
|
|
39
|
+
cleanupFn = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
effect
|
|
46
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Signal } from './signal';
|
|
2
|
+
export declare function eventListener<T, K extends keyof HTMLElementEventMap>(eventTarget: EventTarget, eventType: K, valueGetter: (e: HTMLElementEventMap[K]) => T, initialValueGetter?: () => T): {
|
|
3
|
+
signal: Signal<T>;
|
|
4
|
+
cleanup: () => void;
|
|
5
|
+
};
|
|
6
|
+
export declare function eventListener<T>(eventTarget: EventTarget, eventType: string, valueGetter: (e: Event) => T, initialValueGetter?: () => T): {
|
|
7
|
+
signal: Signal<T>;
|
|
8
|
+
cleanup: () => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Signal } from "./signal.js";
|
|
2
|
+
function eventListener(eventTarget, eventType, valueGetter, initialValueGetter) {
|
|
3
|
+
const signal = new Signal(
|
|
4
|
+
valueGetter(null)
|
|
5
|
+
);
|
|
6
|
+
const updateSignal = (e) => signal.set(valueGetter(e));
|
|
7
|
+
eventTarget.addEventListener(eventType, updateSignal);
|
|
8
|
+
const cleanup = () => {
|
|
9
|
+
eventTarget.removeEventListener(eventType, updateSignal);
|
|
10
|
+
};
|
|
11
|
+
return { signal, cleanup };
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
eventListener
|
|
15
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Subscriber } from '../types.js';
|
|
2
|
+
export type { Subscriber };
|
|
3
|
+
export declare class ReactiveArray<T> {
|
|
4
|
+
private strategy;
|
|
5
|
+
private ownedStrategy?;
|
|
6
|
+
private subscribers;
|
|
7
|
+
private onChangeCallback?;
|
|
8
|
+
private mapCache;
|
|
9
|
+
constructor(itemsOrConfig?: T[] | {
|
|
10
|
+
source: ReactiveArray<any>;
|
|
11
|
+
transform: (value: any, index: number) => T;
|
|
12
|
+
} | {
|
|
13
|
+
source: ReactiveArray<T>;
|
|
14
|
+
predicate: (value: T, index: number, array: T[]) => boolean;
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* Registra un callback que se llama síncronamente antes de notificar subscribers
|
|
18
|
+
*/
|
|
19
|
+
onChange(callback: (operation: string, ...args: any[]) => void): void;
|
|
20
|
+
/**
|
|
21
|
+
* Retorna el array plano subyacente (sin reactividad)
|
|
22
|
+
* Útil para serialización o interoperación con código no reactivo
|
|
23
|
+
*/
|
|
24
|
+
getPlainValue(): T[];
|
|
25
|
+
/**
|
|
26
|
+
* Getter reactivo para la longitud del array
|
|
27
|
+
*/
|
|
28
|
+
get length(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Método at() reactivo que soporta índices negativos
|
|
31
|
+
* Similar a array.at() pero con tracking granular por índice
|
|
32
|
+
*/
|
|
33
|
+
at(index: number): T | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Asegura que el array esté en modo owned (tiene datos propios)
|
|
36
|
+
* Lanza error si se intenta mutar un array derivado
|
|
37
|
+
*/
|
|
38
|
+
private ensureOwned;
|
|
39
|
+
push(...items: T[]): number;
|
|
40
|
+
pop(): T | undefined;
|
|
41
|
+
shift(): T | undefined;
|
|
42
|
+
unshift(...items: T[]): number;
|
|
43
|
+
splice(start: number, deleteCount?: number, ...items: T[]): T[];
|
|
44
|
+
sort(compareFn?: (a: T, b: T) => number): this;
|
|
45
|
+
reverse(): this;
|
|
46
|
+
fill(value: T, start?: number, end?: number): this;
|
|
47
|
+
/**
|
|
48
|
+
* map() ahora retorna un ReactiveArray derivado, no un array plano
|
|
49
|
+
* Este es el corazón de tu insight: mantener la reactividad en la cadena
|
|
50
|
+
*
|
|
51
|
+
* MEMOIZACIÓN INTELIGENTE:
|
|
52
|
+
* - Cachea el array derivado por toString() del callback
|
|
53
|
+
* - Captura dependencias externas (signals que el callback lee)
|
|
54
|
+
* - Si las dependencias no cambiaron, retorna el MISMO array derivado
|
|
55
|
+
* - Esto permite granularidad: push/pop solo afectan nuevos elementos
|
|
56
|
+
*/
|
|
57
|
+
map<U>(callback: (value: T, index: number, array: T[]) => U): ReactiveArray<U>;
|
|
58
|
+
/**
|
|
59
|
+
* filter() también retorna un ReactiveArray derivado
|
|
60
|
+
* Implementación especial que necesita manejar índices no lineales
|
|
61
|
+
*/
|
|
62
|
+
filter(callback: (value: T, index: number, array: T[]) => boolean): ReactiveArray<T>;
|
|
63
|
+
slice(start?: number, end?: number): T[];
|
|
64
|
+
concat(...items: (T | T[])[]): T[];
|
|
65
|
+
find(callback: (value: T, index: number, array: T[]) => boolean): T | undefined;
|
|
66
|
+
findIndex(callback: (value: T, index: number, array: T[]) => boolean): number;
|
|
67
|
+
indexOf(searchElement: T, fromIndex?: number): number;
|
|
68
|
+
includes(searchElement: T, fromIndex?: number): boolean;
|
|
69
|
+
forEach(callback: (value: T, index: number, array: T[]) => void): void;
|
|
70
|
+
some(callback: (value: T, index: number, array: T[]) => boolean): boolean;
|
|
71
|
+
every(callback: (value: T, index: number, array: T[]) => boolean): boolean;
|
|
72
|
+
reduce<U>(callback: (accumulator: U, value: T, index: number, array: T[]) => U, initialValue: U): U;
|
|
73
|
+
reduceRight<U>(callback: (accumulator: U, value: T, index: number, array: T[]) => U, initialValue: U): U;
|
|
74
|
+
join(separator?: string): string;
|
|
75
|
+
toString(): string;
|
|
76
|
+
toLocaleString(): string;
|
|
77
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
78
|
+
entries(): IterableIterator<[number, T]>;
|
|
79
|
+
keys(): IterableIterator<number>;
|
|
80
|
+
values(): IterableIterator<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Registra un subscriber para un tipo específico de cambio
|
|
83
|
+
*/
|
|
84
|
+
private _subscribe;
|
|
85
|
+
/**
|
|
86
|
+
* Notifica a subscribers de un tipo específico de cambio
|
|
87
|
+
*/
|
|
88
|
+
private _notify;
|
|
89
|
+
/**
|
|
90
|
+
* Notifica que el array mutó (cualquier cambio en contenido)
|
|
91
|
+
*/
|
|
92
|
+
private _notifyMutation;
|
|
93
|
+
/**
|
|
94
|
+
* Notifica que la longitud cambió
|
|
95
|
+
*/
|
|
96
|
+
private _notifyLength;
|
|
97
|
+
/**
|
|
98
|
+
* Notifica a todos los índices numéricos suscritos
|
|
99
|
+
* Se usa cuando operaciones como shift/unshift/splice afectan múltiples índices
|
|
100
|
+
*/
|
|
101
|
+
private _notifyAllIndices;
|
|
102
|
+
/**
|
|
103
|
+
* Notifica todos los índices desde start hacia adelante
|
|
104
|
+
* Útil cuando splice/insert afecta índices posteriores
|
|
105
|
+
*/
|
|
106
|
+
private _notifyIndicesFrom;
|
|
107
|
+
getSubscribers(key: string | number): Set<Subscriber> | undefined;
|
|
108
|
+
getSubscribedKeys(): (string | number)[];
|
|
109
|
+
}
|
|
110
|
+
export type ObservableArray<T> = ReactiveArray<T>;
|
|
111
|
+
export type Collection<T> = ReactiveArray<T>;
|
|
112
|
+
/**
|
|
113
|
+
* Factory function to create a new ReactiveArray
|
|
114
|
+
*/
|
|
115
|
+
export declare function collection<T>(items?: T[]): ReactiveArray<T>;
|
|
116
|
+
/**
|
|
117
|
+
* Type guard to check if a value is a ReactiveArray
|
|
118
|
+
*/
|
|
119
|
+
export declare function isObservableArray(value: any): value is ReactiveArray<any>;
|
|
120
|
+
/**
|
|
121
|
+
* Type guard to check if a value is a Collection (same as ObservableArray)
|
|
122
|
+
*/
|
|
123
|
+
export declare function isCollection(value: any): value is ReactiveArray<any>;
|
|
124
|
+
/**
|
|
125
|
+
* Type guard to check if a value is a ReactiveArray OR a proxy wrapping a ReactiveArray
|
|
126
|
+
* This is useful in JSX rendering where arrays might be wrapped in proxies
|
|
127
|
+
*/
|
|
128
|
+
export declare function isReactiveArrayLike(value: any): boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Unwraps a ReactiveArray from a proxy if necessary
|
|
131
|
+
* Returns the underlying ReactiveArray or null if the value is not a ReactiveArray
|
|
132
|
+
*/
|
|
133
|
+
export declare function unwrapReactiveArray<T = any>(value: any): ReactiveArray<T> | null;
|