@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,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 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/reactivity/signals/__tests__/composite/nivel-8-observable-array-support.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/reactivity/signals/__tests__/reactive-array/nivel-3-tracking-por-indice.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/reactivity/signals/__tests__/reactive-array/nivel-6-metodos-no-mutadores.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/reactivity/signals/__tests__/reactive-array/nivel-7-composicion-bidireccional.test.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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
|
+
};
|