@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,193 @@
1
+ import { hasLifecycle } from "./lifecycle.js";
2
+ class ScopedContainer {
3
+ #local = /* @__PURE__ */ new Map();
4
+ #registered = /* @__PURE__ */ new Set();
5
+ #parent;
6
+ // Dependency graph for topological sort
7
+ #dependencies = /* @__PURE__ */ new Map();
8
+ #dependents = /* @__PURE__ */ new Map();
9
+ #ready = false;
10
+ constructor(parent) {
11
+ this.#parent = parent;
12
+ }
13
+ /**
14
+ * Register a service constructor in this scope
15
+ */
16
+ register(token) {
17
+ this.#registered.add(token);
18
+ if (!this.#dependencies.has(token)) {
19
+ this.#dependencies.set(token, /* @__PURE__ */ new Set());
20
+ }
21
+ if (!this.#dependents.has(token)) {
22
+ this.#dependents.set(token, /* @__PURE__ */ new Set());
23
+ }
24
+ }
25
+ /**
26
+ * Register a dependency relationship between services in this scope.
27
+ * Only for dependencies that are BOTH registered locally.
28
+ * Cross-scope dependencies are resolved via parent chain at get() time.
29
+ */
30
+ registerDependency(parent, dependency) {
31
+ if (!this.#registered.has(parent)) {
32
+ throw new Error(
33
+ `Cannot register dependency: ${parent.name} is not registered in this scope.`
34
+ );
35
+ }
36
+ if (!this.#registered.has(dependency)) {
37
+ throw new Error(
38
+ `Cannot register dependency: ${dependency.name} is not registered in this scope.`
39
+ );
40
+ }
41
+ if (!this.#dependencies.has(parent)) {
42
+ this.#dependencies.set(parent, /* @__PURE__ */ new Set());
43
+ }
44
+ this.#dependencies.get(parent).add(dependency);
45
+ if (!this.#dependents.has(dependency)) {
46
+ this.#dependents.set(dependency, /* @__PURE__ */ new Set());
47
+ }
48
+ this.#dependents.get(dependency).add(parent);
49
+ }
50
+ /**
51
+ * Get bootstrap order using topological sort (Kahn's algorithm).
52
+ * Only considers locally registered services.
53
+ */
54
+ *#getBootstrapOrder() {
55
+ const inDegree = /* @__PURE__ */ new Map();
56
+ const queue = [];
57
+ for (const service of this.#registered) {
58
+ const deps = this.#dependencies.get(service) || /* @__PURE__ */ new Set();
59
+ inDegree.set(service, deps.size);
60
+ if (deps.size === 0) {
61
+ queue.push(service);
62
+ }
63
+ }
64
+ while (queue.length > 0) {
65
+ const service = queue.shift();
66
+ yield service;
67
+ const dependents = this.#dependents.get(service) || /* @__PURE__ */ new Set();
68
+ for (const dependent of dependents) {
69
+ const newInDegree = inDegree.get(dependent) - 1;
70
+ inDegree.set(dependent, newInDegree);
71
+ if (newInDegree === 0) {
72
+ queue.push(dependent);
73
+ }
74
+ }
75
+ }
76
+ const remaining = Array.from(inDegree.entries()).filter(
77
+ ([_, degree]) => degree > 0
78
+ );
79
+ if (remaining.length > 0) {
80
+ const cycleServices = remaining.map(([service]) => service.name).join(", ");
81
+ throw new Error(
82
+ `Circular dependency detected in scope. Services with unresolved dependencies: ${cycleServices}`
83
+ );
84
+ }
85
+ }
86
+ /**
87
+ * Bootstrap all locally registered services in dependency order.
88
+ * Each instance is associated with this container via __container.
89
+ *
90
+ * Services with async onBootstrap() are launched as fire-and-forget.
91
+ * Use the reactive pattern (@Store with isLoading) to handle async state.
92
+ */
93
+ bootstrapSync() {
94
+ if (this.#ready) return;
95
+ for (const ctor of this.#getBootstrapOrder()) {
96
+ const inst = new ctor();
97
+ inst.__container = this;
98
+ this.#local.set(ctor, inst);
99
+ if (hasLifecycle(inst)) {
100
+ inst.onBootstrap().catch((err) => {
101
+ console.error(`[ScopedContainer] Error in onBootstrap for ${ctor.name}:`, err);
102
+ });
103
+ }
104
+ }
105
+ this.#ready = true;
106
+ }
107
+ /**
108
+ * Bootstrap all locally registered services, awaiting async onBootstrap hooks.
109
+ * Use this in the DOM init() path where async is available.
110
+ */
111
+ async bootstrap() {
112
+ if (this.#ready) return;
113
+ for (const ctor of this.#getBootstrapOrder()) {
114
+ const inst = new ctor();
115
+ inst.__container = this;
116
+ this.#local.set(ctor, inst);
117
+ if (hasLifecycle(inst)) {
118
+ await inst.onBootstrap();
119
+ }
120
+ }
121
+ this.#ready = true;
122
+ }
123
+ /**
124
+ * Resolve a service by walking up the parent chain.
125
+ * Checks local scope first, then parent, then grandparent, etc.
126
+ */
127
+ get(ctor) {
128
+ if (this.#local.has(ctor)) {
129
+ return this.#local.get(ctor);
130
+ }
131
+ if (this.#parent) {
132
+ return this.#parent.get(ctor);
133
+ }
134
+ throw new Error(
135
+ `Service ${ctor.name} not found in any scope. Make sure a parent component provides it via services: [${ctor.name}].`
136
+ );
137
+ }
138
+ /**
139
+ * Check if a service exists in this scope or any parent scope.
140
+ */
141
+ has(ctor) {
142
+ if (this.#local.has(ctor)) return true;
143
+ if (this.#parent) return this.#parent.has(ctor);
144
+ return false;
145
+ }
146
+ /**
147
+ * Check if a service is registered locally (not including parents).
148
+ */
149
+ hasLocal(ctor) {
150
+ return this.#local.has(ctor);
151
+ }
152
+ /**
153
+ * Check if bootstrap has been called.
154
+ */
155
+ get isReady() {
156
+ return this.#ready;
157
+ }
158
+ /**
159
+ * Get the parent container.
160
+ */
161
+ get parent() {
162
+ return this.#parent;
163
+ }
164
+ /**
165
+ * Get all locally instantiated service instances.
166
+ */
167
+ getAllInstances() {
168
+ return Array.from(this.#local.values());
169
+ }
170
+ /**
171
+ * Dispose all local services and reset container.
172
+ * Calls onDestroy() on services that implement it.
173
+ */
174
+ dispose() {
175
+ for (const instance of this.#local.values()) {
176
+ if (typeof instance.onDestroy === "function") {
177
+ try {
178
+ instance.onDestroy();
179
+ } catch (error) {
180
+ console.error("[ScopedContainer] Error in onDestroy:", error);
181
+ }
182
+ }
183
+ }
184
+ this.#local.clear();
185
+ this.#registered.clear();
186
+ this.#dependencies.clear();
187
+ this.#dependents.clear();
188
+ this.#ready = false;
189
+ }
190
+ }
191
+ export {
192
+ ScopedContainer
193
+ };
@@ -0,0 +1,32 @@
1
+ import { Constructor } from './types';
2
+ /**
3
+ * Metadata for a service registered via decorators
4
+ * This is stored globally and can be used to register services in any container
5
+ */
6
+ export interface ServiceMetadata {
7
+ constructor: Constructor;
8
+ dependencies: Set<Constructor>;
9
+ }
10
+ /**
11
+ * Options for registering service metadata
12
+ */
13
+ export interface ServiceMetadataOptions {
14
+ dependencies?: Set<Constructor>;
15
+ }
16
+ /**
17
+ * Register service metadata (called by decorators)
18
+ */
19
+ export declare function registerServiceMetadata(ctor: Constructor, options: ServiceMetadataOptions): void;
20
+ /**
21
+ * Get metadata for a service
22
+ */
23
+ export declare function getServiceMetadata(ctor: Constructor): ServiceMetadata | undefined;
24
+ /**
25
+ * Get all registered service metadata
26
+ * Useful for registering all services in a container
27
+ */
28
+ export declare function getAllServiceMetadata(): Map<Constructor, ServiceMetadata>;
29
+ /**
30
+ * Clear all metadata (useful for testing)
31
+ */
32
+ export declare function clearServiceMetadata(): void;
@@ -0,0 +1,31 @@
1
+ const serviceMetadataRegistry = /* @__PURE__ */ new Map();
2
+ function registerServiceMetadata(ctor, options) {
3
+ const existing = serviceMetadataRegistry.get(ctor);
4
+ if (existing) {
5
+ if (options.dependencies) {
6
+ for (const dep of options.dependencies) {
7
+ existing.dependencies.add(dep);
8
+ }
9
+ }
10
+ } else {
11
+ serviceMetadataRegistry.set(ctor, {
12
+ constructor: ctor,
13
+ dependencies: options.dependencies || /* @__PURE__ */ new Set()
14
+ });
15
+ }
16
+ }
17
+ function getServiceMetadata(ctor) {
18
+ return serviceMetadataRegistry.get(ctor);
19
+ }
20
+ function getAllServiceMetadata() {
21
+ return new Map(serviceMetadataRegistry);
22
+ }
23
+ function clearServiceMetadata() {
24
+ serviceMetadataRegistry.clear();
25
+ }
26
+ export {
27
+ clearServiceMetadata,
28
+ getAllServiceMetadata,
29
+ getServiceMetadata,
30
+ registerServiceMetadata
31
+ };
@@ -0,0 +1,4 @@
1
+ export type Constructor<T = {}> = new (...args: any[]) => T;
2
+ export interface OnBootstrap {
3
+ onBootstrap(): Promise<void>;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,60 @@
1
+ /**
2
+ * BehaviorManager manages the lifecycle of Behavior instances attached to elements.
3
+ *
4
+ * Each component has its own BehaviorManager instance to track and manage
5
+ * behaviors attached to native elements within that component.
6
+ *
7
+ * Lifecycle:
8
+ * 1. attachBehaviors() - Called from bindProps, resolves and attaches behaviors
9
+ * 2. onInit() - Called on each behavior after props are assigned
10
+ * 3. onDestroy() - Called when disconnectAll() or disconnectElement() is called
11
+ */
12
+ export declare class BehaviorManager {
13
+ private instances;
14
+ private hostComponent;
15
+ constructor(hostComponent?: any);
16
+ /**
17
+ * Main entry point. Analyzes all props for an element,
18
+ * instantiates corresponding behaviors, and returns which props were consumed.
19
+ *
20
+ * @param el - The element to attach behaviors to
21
+ * @param props - All props from JSX
22
+ * @returns Set<string> with names of all props that were handled by behaviors
23
+ */
24
+ attachBehaviors(el: Element, props: Record<string, any>): Set<string>;
25
+ /**
26
+ * Attaches a specific behavior to an element.
27
+ */
28
+ private attach;
29
+ /**
30
+ * Gets the names of all @Prop decorated fields in a behavior class.
31
+ */
32
+ private getBehaviorPropNames;
33
+ /**
34
+ * Gets a specific behavior instance from an element.
35
+ * Useful for debugging or programmatic interaction.
36
+ */
37
+ get<T>(el: Element, behaviorName: string): T | undefined;
38
+ /**
39
+ * Gets all behaviors attached to an element.
40
+ */
41
+ getAll(el: Element): Map<string, any> | undefined;
42
+ /**
43
+ * Disconnects all behaviors from all elements.
44
+ * Called from disconnectedCallback of the parent component.
45
+ */
46
+ disconnectAll(): void;
47
+ /**
48
+ * Disconnects behaviors from a specific element.
49
+ * Useful if an element is removed from DOM but the component is still alive.
50
+ */
51
+ disconnectElement(el: Element): void;
52
+ /**
53
+ * Gets the total number of elements that have behaviors attached.
54
+ */
55
+ get elementCount(): number;
56
+ /**
57
+ * Gets the total number of behavior instances managed.
58
+ */
59
+ get behaviorCount(): number;
60
+ }
@@ -0,0 +1,131 @@
1
+ import { BehaviorRegistry } from "./behavior-registry.js";
2
+ import { HOST_KEY, COMPONENT_HOST_KEY, BEHAVIOR_PROPS } from "./constants.js";
3
+ class BehaviorManager {
4
+ constructor(hostComponent) {
5
+ this.instances = /* @__PURE__ */ new Map();
6
+ this.hostComponent = hostComponent;
7
+ }
8
+ /**
9
+ * Main entry point. Analyzes all props for an element,
10
+ * instantiates corresponding behaviors, and returns which props were consumed.
11
+ *
12
+ * @param el - The element to attach behaviors to
13
+ * @param props - All props from JSX
14
+ * @returns Set<string> with names of all props that were handled by behaviors
15
+ */
16
+ attachBehaviors(el, props) {
17
+ const behaviorMap = BehaviorRegistry.resolve(props);
18
+ const consumedProps = /* @__PURE__ */ new Set();
19
+ for (const [BehaviorClass, config] of behaviorMap) {
20
+ const behaviorName = BehaviorClass.name;
21
+ this.attach(el, BehaviorClass, behaviorName, config);
22
+ const behaviorProps = this.getBehaviorPropNames(BehaviorClass);
23
+ behaviorProps.forEach((prop) => {
24
+ if (prop in props) {
25
+ consumedProps.add(prop);
26
+ }
27
+ });
28
+ }
29
+ return consumedProps;
30
+ }
31
+ /**
32
+ * Attaches a specific behavior to an element.
33
+ */
34
+ attach(el, BehaviorClass, behaviorName, config) {
35
+ const instance = new BehaviorClass();
36
+ const hostPropName = BehaviorClass[HOST_KEY];
37
+ if (hostPropName) {
38
+ instance[hostPropName] = el;
39
+ }
40
+ const componentHostPropName = BehaviorClass[COMPONENT_HOST_KEY];
41
+ if (componentHostPropName && this.hostComponent) {
42
+ instance[componentHostPropName] = this.hostComponent;
43
+ }
44
+ if (this.hostComponent?.__container) {
45
+ instance.__container = this.hostComponent.__container;
46
+ }
47
+ Object.assign(instance, config);
48
+ if (!this.instances.has(el)) {
49
+ this.instances.set(el, /* @__PURE__ */ new Map());
50
+ }
51
+ this.instances.get(el).set(behaviorName, instance);
52
+ if (typeof instance.onInit === "function") {
53
+ instance.onInit();
54
+ }
55
+ }
56
+ /**
57
+ * Gets the names of all @Prop decorated fields in a behavior class.
58
+ */
59
+ getBehaviorPropNames(BehaviorClass) {
60
+ const props = BehaviorClass[BEHAVIOR_PROPS];
61
+ return props ? new Set(props) : /* @__PURE__ */ new Set();
62
+ }
63
+ /**
64
+ * Gets a specific behavior instance from an element.
65
+ * Useful for debugging or programmatic interaction.
66
+ */
67
+ get(el, behaviorName) {
68
+ return this.instances.get(el)?.get(behaviorName);
69
+ }
70
+ /**
71
+ * Gets all behaviors attached to an element.
72
+ */
73
+ getAll(el) {
74
+ return this.instances.get(el);
75
+ }
76
+ /**
77
+ * Disconnects all behaviors from all elements.
78
+ * Called from disconnectedCallback of the parent component.
79
+ */
80
+ disconnectAll() {
81
+ for (const [el, behaviors] of this.instances) {
82
+ for (const [name, instance] of behaviors) {
83
+ if (typeof instance.onDestroy === "function") {
84
+ try {
85
+ instance.onDestroy();
86
+ } catch (e) {
87
+ console.error(`[Behavior ${name}] Error in onDestroy:`, e);
88
+ }
89
+ }
90
+ }
91
+ }
92
+ this.instances.clear();
93
+ }
94
+ /**
95
+ * Disconnects behaviors from a specific element.
96
+ * Useful if an element is removed from DOM but the component is still alive.
97
+ */
98
+ disconnectElement(el) {
99
+ const behaviors = this.instances.get(el);
100
+ if (!behaviors) return;
101
+ for (const [name, instance] of behaviors) {
102
+ if (typeof instance.onDestroy === "function") {
103
+ try {
104
+ instance.onDestroy();
105
+ } catch (e) {
106
+ console.error(`[Behavior ${name}] Error in onDestroy:`, e);
107
+ }
108
+ }
109
+ }
110
+ this.instances.delete(el);
111
+ }
112
+ /**
113
+ * Gets the total number of elements that have behaviors attached.
114
+ */
115
+ get elementCount() {
116
+ return this.instances.size;
117
+ }
118
+ /**
119
+ * Gets the total number of behavior instances managed.
120
+ */
121
+ get behaviorCount() {
122
+ let count = 0;
123
+ for (const [, behaviors] of this.instances) {
124
+ count += behaviors.size;
125
+ }
126
+ return count;
127
+ }
128
+ }
129
+ export {
130
+ BehaviorManager
131
+ };
@@ -0,0 +1,68 @@
1
+ type Constructor = new (...args: any[]) => any;
2
+ /**
3
+ * BehaviorRegistry manages the mapping between prop names and Behavior classes.
4
+ *
5
+ * When a @Behavior class is registered, all its @Prop decorated fields are indexed.
6
+ * This allows the system to resolve which behaviors to instantiate based on JSX props.
7
+ *
8
+ * @example
9
+ * @Behavior
10
+ * class Link {
11
+ * @Prop() link: boolean = true; // Activator prop
12
+ * @Prop() href: string = ''; // Config prop
13
+ * @Prop() activeClass?: string; // Optional config prop
14
+ * }
15
+ *
16
+ * // In JSX: <a link href="/home" activeClass="active">
17
+ * // BehaviorRegistry.resolve({link: true, href: '/home', activeClass: 'active'})
18
+ * // Returns: Map { Link -> {link: true, href: '/home', activeClass: 'active'} }
19
+ */
20
+ export declare class BehaviorRegistry {
21
+ private static propIndex;
22
+ private static allBehaviorProps;
23
+ /**
24
+ * Registers a class as a Behavior.
25
+ * Called from the @Behavior decorator.
26
+ *
27
+ * @throws Error if a prop name is already registered by another behavior
28
+ */
29
+ static register(cls: Constructor): void;
30
+ /**
31
+ * Resolves which behaviors to apply and with what configuration.
32
+ *
33
+ * Groups all props by their registered Behavior class.
34
+ *
35
+ * @param props - Props from JSX (e.g., {link: true, href: '/', activeClass: 'active'})
36
+ * @returns Map<BehaviorClass, config>
37
+ */
38
+ static resolve(props: Record<string, any>): Map<Constructor, Record<string, any>>;
39
+ /**
40
+ * Checks if a prop name belongs to any registered behavior.
41
+ */
42
+ static isBehaviorProp(name: string): boolean;
43
+ /**
44
+ * Gets the behavior class for a given prop name.
45
+ */
46
+ static getBehaviorForProp(propName: string): Constructor | undefined;
47
+ /**
48
+ * Gets all prop names registered for a behavior class.
49
+ */
50
+ static getPropsForBehavior(cls: Constructor): Set<string>;
51
+ /**
52
+ * Unregisters a behavior (useful for testing).
53
+ */
54
+ static unregister(cls: Constructor): void;
55
+ /**
56
+ * Clears all registered behaviors (useful for testing).
57
+ */
58
+ static clear(): void;
59
+ /**
60
+ * Gets all registered prop names (useful for debugging).
61
+ */
62
+ static getRegisteredProps(): string[];
63
+ /**
64
+ * Debug output of all registered behaviors and their props.
65
+ */
66
+ static debug(): void;
67
+ }
68
+ export {};
@@ -0,0 +1,105 @@
1
+ import { BEHAVIOR_PROPS } from "./constants.js";
2
+ const _BehaviorRegistry = class _BehaviorRegistry {
3
+ /**
4
+ * Registers a class as a Behavior.
5
+ * Called from the @Behavior decorator.
6
+ *
7
+ * @throws Error if a prop name is already registered by another behavior
8
+ */
9
+ static register(cls) {
10
+ const props = cls[BEHAVIOR_PROPS];
11
+ if (!props || props.size === 0) {
12
+ console.warn(`[Behavior] ${cls.name} registered without @Props. Did you forget to decorate the properties?`);
13
+ }
14
+ props?.forEach((propName) => {
15
+ if (this.propIndex.has(propName)) {
16
+ const existing = this.propIndex.get(propName).name;
17
+ throw new Error(
18
+ `[Behavior Conflict] Property "${propName}" is already registered by behavior "${existing}". Cannot be used in "${cls.name}".`
19
+ );
20
+ }
21
+ this.propIndex.set(propName, cls);
22
+ this.allBehaviorProps.add(propName);
23
+ });
24
+ }
25
+ /**
26
+ * Resolves which behaviors to apply and with what configuration.
27
+ *
28
+ * Groups all props by their registered Behavior class.
29
+ *
30
+ * @param props - Props from JSX (e.g., {link: true, href: '/', activeClass: 'active'})
31
+ * @returns Map<BehaviorClass, config>
32
+ */
33
+ static resolve(props) {
34
+ const behaviors = /* @__PURE__ */ new Map();
35
+ for (const [key, value] of Object.entries(props)) {
36
+ const BehaviorClass = this.propIndex.get(key);
37
+ if (BehaviorClass) {
38
+ if (!behaviors.has(BehaviorClass)) {
39
+ behaviors.set(BehaviorClass, {});
40
+ }
41
+ behaviors.get(BehaviorClass)[key] = value;
42
+ }
43
+ }
44
+ return behaviors;
45
+ }
46
+ /**
47
+ * Checks if a prop name belongs to any registered behavior.
48
+ */
49
+ static isBehaviorProp(name) {
50
+ return this.allBehaviorProps.has(name);
51
+ }
52
+ /**
53
+ * Gets the behavior class for a given prop name.
54
+ */
55
+ static getBehaviorForProp(propName) {
56
+ return this.propIndex.get(propName);
57
+ }
58
+ /**
59
+ * Gets all prop names registered for a behavior class.
60
+ */
61
+ static getPropsForBehavior(cls) {
62
+ const props = cls[BEHAVIOR_PROPS];
63
+ return props ? new Set(props) : /* @__PURE__ */ new Set();
64
+ }
65
+ /**
66
+ * Unregisters a behavior (useful for testing).
67
+ */
68
+ static unregister(cls) {
69
+ const props = cls[BEHAVIOR_PROPS];
70
+ props?.forEach((propName) => {
71
+ if (this.propIndex.get(propName) === cls) {
72
+ this.propIndex.delete(propName);
73
+ this.allBehaviorProps.delete(propName);
74
+ }
75
+ });
76
+ }
77
+ /**
78
+ * Clears all registered behaviors (useful for testing).
79
+ */
80
+ static clear() {
81
+ this.propIndex.clear();
82
+ this.allBehaviorProps.clear();
83
+ }
84
+ /**
85
+ * Gets all registered prop names (useful for debugging).
86
+ */
87
+ static getRegisteredProps() {
88
+ return Array.from(this.propIndex.keys());
89
+ }
90
+ /**
91
+ * Debug output of all registered behaviors and their props.
92
+ */
93
+ static debug() {
94
+ console.log(
95
+ "[BehaviorRegistry] Registered props:",
96
+ Array.from(this.propIndex.entries()).map(([k, v]) => `${k} -> ${v.name}`)
97
+ );
98
+ }
99
+ };
100
+ _BehaviorRegistry.propIndex = /* @__PURE__ */ new Map();
101
+ _BehaviorRegistry.allBehaviorProps = /* @__PURE__ */ new Set();
102
+ let BehaviorRegistry = _BehaviorRegistry;
103
+ export {
104
+ BehaviorRegistry
105
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Symbol para almacenar metadata de props en las clases Behavior.
3
+ * Usado por @Prop para registrar qué campos son props del behavior.
4
+ */
5
+ export declare const BEHAVIOR_PROPS: unique symbol;
6
+ /**
7
+ * Symbol para marcar qué campo recibe el elemento host.
8
+ * Usado por @Host para inyectar el elemento al que se adjunta el behavior.
9
+ */
10
+ export declare const HOST_KEY: unique symbol;
11
+ /**
12
+ * Symbol para marcar qué campo recibe el componente host.
13
+ * Usado por @ComponentHost para inyectar el componente que contiene el behavior.
14
+ * Permite a behaviors acceder al contexto (@Ctx) del componente.
15
+ */
16
+ export declare const COMPONENT_HOST_KEY: unique symbol;
@@ -0,0 +1,8 @@
1
+ const BEHAVIOR_PROPS = Symbol("behavior:props");
2
+ const HOST_KEY = Symbol("behavior:host");
3
+ const COMPONENT_HOST_KEY = Symbol("behavior:componentHost");
4
+ export {
5
+ BEHAVIOR_PROPS,
6
+ COMPONENT_HOST_KEY,
7
+ HOST_KEY
8
+ };