@saolabs/client 1.0.0 → 1.0.2

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 (378) hide show
  1. package/README.md +52 -195
  2. package/dist/index.d.ts +20 -5
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +14 -3
  5. package/dist/index.js.map +1 -1
  6. package/dist/plugins.d.ts +2 -2
  7. package/dist/plugins.js +2 -2
  8. package/dist/src/core/app/Application.d.ts +17 -15
  9. package/dist/src/core/app/Application.d.ts.map +1 -1
  10. package/dist/src/core/app/Application.js +41 -18
  11. package/dist/src/core/app/Application.js.map +1 -1
  12. package/dist/src/core/bootstrap/app.d.ts +1 -1
  13. package/dist/src/core/bootstrap/app.d.ts.map +1 -1
  14. package/dist/src/core/bootstrap/app.js +74 -4
  15. package/dist/src/core/bootstrap/app.js.map +1 -1
  16. package/dist/src/core/bootstrap/bundle.d.ts +41 -0
  17. package/dist/src/core/bootstrap/bundle.d.ts.map +1 -0
  18. package/dist/src/core/bootstrap/bundle.js +98 -0
  19. package/dist/src/core/bootstrap/bundle.js.map +1 -0
  20. package/dist/src/core/bootstrap/providers/ApiServiceProvider.d.ts +1 -1
  21. package/dist/src/core/bootstrap/providers/ApiServiceProvider.d.ts.map +1 -1
  22. package/dist/src/core/bootstrap/providers/ApiServiceProvider.js +3 -3
  23. package/dist/src/core/bootstrap/providers/ApiServiceProvider.js.map +1 -1
  24. package/dist/src/core/bootstrap/providers/CoreServiceProvider.d.ts +1 -1
  25. package/dist/src/core/bootstrap/providers/CoreServiceProvider.d.ts.map +1 -1
  26. package/dist/src/core/bootstrap/providers/CoreServiceProvider.js +11 -8
  27. package/dist/src/core/bootstrap/providers/CoreServiceProvider.js.map +1 -1
  28. package/dist/src/core/bootstrap/providers/HelperServiceProvider.d.ts +3 -1
  29. package/dist/src/core/bootstrap/providers/HelperServiceProvider.d.ts.map +1 -1
  30. package/dist/src/core/bootstrap/providers/HelperServiceProvider.js +8 -3
  31. package/dist/src/core/bootstrap/providers/HelperServiceProvider.js.map +1 -1
  32. package/dist/src/core/bootstrap/providers/RouteServiceProvider.d.ts +2 -1
  33. package/dist/src/core/bootstrap/providers/RouteServiceProvider.d.ts.map +1 -1
  34. package/dist/src/core/bootstrap/providers/RouteServiceProvider.js +14 -4
  35. package/dist/src/core/bootstrap/providers/RouteServiceProvider.js.map +1 -1
  36. package/dist/src/core/bootstrap/providers/ServiceProvider.d.ts +4 -4
  37. package/dist/src/core/bootstrap/providers/ServiceProvider.d.ts.map +1 -1
  38. package/dist/src/core/bootstrap/providers/ServiceProvider.js +5 -5
  39. package/dist/src/core/bootstrap/providers/ServiceProvider.js.map +1 -1
  40. package/dist/src/core/bootstrap/providers/ViewServiceProvider.d.ts +1 -1
  41. package/dist/src/core/bootstrap/providers/ViewServiceProvider.d.ts.map +1 -1
  42. package/dist/src/core/bootstrap/providers/ViewServiceProvider.js +3 -3
  43. package/dist/src/core/bootstrap/providers/ViewServiceProvider.js.map +1 -1
  44. package/dist/src/core/bootstrap/providers/default-providers.d.ts +1 -1
  45. package/dist/src/core/bootstrap/providers/default-providers.d.ts.map +1 -1
  46. package/dist/src/core/bootstrap/providers/default-providers.js +44 -11
  47. package/dist/src/core/bootstrap/providers/default-providers.js.map +1 -1
  48. package/dist/src/core/bootstrap/providers/index.d.ts +9 -9
  49. package/dist/src/core/bootstrap/providers/index.d.ts.map +1 -1
  50. package/dist/src/core/bootstrap/providers/index.js +8 -8
  51. package/dist/src/core/bootstrap/providers/index.js.map +1 -1
  52. package/dist/src/core/bootstrap/providers/provider-order.d.ts +1 -1
  53. package/dist/src/core/bootstrap/providers/provider-order.d.ts.map +1 -1
  54. package/dist/src/core/bootstrap/ssr.d.ts +47 -0
  55. package/dist/src/core/bootstrap/ssr.d.ts.map +1 -0
  56. package/dist/src/core/bootstrap/ssr.js +125 -0
  57. package/dist/src/core/bootstrap/ssr.js.map +1 -0
  58. package/dist/src/core/cache/ViewCache.d.ts +1 -1
  59. package/dist/src/core/cache/ViewCache.d.ts.map +1 -1
  60. package/dist/src/core/cache/index.d.ts +1 -1
  61. package/dist/src/core/cache/index.d.ts.map +1 -1
  62. package/dist/src/core/cache/index.js +1 -1
  63. package/dist/src/core/cache/index.js.map +1 -1
  64. package/dist/src/core/contracts/ApplicationInterface.d.ts +13 -11
  65. package/dist/src/core/contracts/ApplicationInterface.d.ts.map +1 -1
  66. package/dist/src/core/contracts/BlockInterface.d.ts +10 -10
  67. package/dist/src/core/contracts/BlockInterface.d.ts.map +1 -1
  68. package/dist/src/core/contracts/BundleInterface.d.ts +38 -0
  69. package/dist/src/core/contracts/BundleInterface.d.ts.map +1 -0
  70. package/dist/src/core/contracts/BundleInterface.js +2 -0
  71. package/dist/src/core/contracts/BundleInterface.js.map +1 -0
  72. package/dist/src/core/contracts/ComponentInterface.d.ts +7 -6
  73. package/dist/src/core/contracts/ComponentInterface.d.ts.map +1 -1
  74. package/dist/src/core/contracts/ElementInterface.d.ts +91 -27
  75. package/dist/src/core/contracts/ElementInterface.d.ts.map +1 -1
  76. package/dist/src/core/contracts/HeadServiceInterface.d.ts +37 -0
  77. package/dist/src/core/contracts/HeadServiceInterface.d.ts.map +1 -0
  78. package/dist/src/core/contracts/HeadServiceInterface.js +3 -0
  79. package/dist/src/core/contracts/HeadServiceInterface.js.map +1 -0
  80. package/dist/src/core/contracts/HelperInterface.d.ts +9 -1
  81. package/dist/src/core/contracts/HelperInterface.d.ts.map +1 -1
  82. package/dist/src/core/contracts/HttpServiceInterface.d.ts +3 -0
  83. package/dist/src/core/contracts/HttpServiceInterface.d.ts.map +1 -1
  84. package/dist/src/core/contracts/MarkerInterface.d.ts +29 -44
  85. package/dist/src/core/contracts/MarkerInterface.d.ts.map +1 -1
  86. package/dist/src/core/contracts/ReactiveInterface.d.ts +9 -9
  87. package/dist/src/core/contracts/ReactiveInterface.d.ts.map +1 -1
  88. package/dist/src/core/contracts/RouterInterface.d.ts +5 -2
  89. package/dist/src/core/contracts/RouterInterface.d.ts.map +1 -1
  90. package/dist/src/core/contracts/SectionInterface.d.ts +48 -0
  91. package/dist/src/core/contracts/SectionInterface.d.ts.map +1 -0
  92. package/dist/src/core/contracts/SectionInterface.js +2 -0
  93. package/dist/src/core/contracts/SectionInterface.js.map +1 -0
  94. package/dist/src/core/contracts/ServiceProviderInterface.d.ts +3 -3
  95. package/dist/src/core/contracts/ServiceProviderInterface.d.ts.map +1 -1
  96. package/dist/src/core/contracts/ViewControllerInterface.d.ts +116 -15
  97. package/dist/src/core/contracts/ViewControllerInterface.d.ts.map +1 -1
  98. package/dist/src/core/contracts/ViewInterface.d.ts +31 -5
  99. package/dist/src/core/contracts/ViewInterface.d.ts.map +1 -1
  100. package/dist/src/core/contracts/ViewManagerInterface.d.ts +47 -5
  101. package/dist/src/core/contracts/ViewManagerInterface.d.ts.map +1 -1
  102. package/dist/src/core/contracts/ViewStateInterface.d.ts +39 -2
  103. package/dist/src/core/contracts/ViewStateInterface.d.ts.map +1 -1
  104. package/dist/src/core/contracts/common.d.ts +3 -3
  105. package/dist/src/core/contracts/common.js +3 -3
  106. package/dist/src/core/contracts/utils.d.ts +19 -19
  107. package/dist/src/core/contracts/utils.d.ts.map +1 -1
  108. package/dist/src/core/contracts/views.d.ts +1 -22
  109. package/dist/src/core/contracts/views.d.ts.map +1 -1
  110. package/dist/src/core/devtools/hook.d.ts +66 -0
  111. package/dist/src/core/devtools/hook.d.ts.map +1 -0
  112. package/dist/src/core/devtools/hook.js +114 -0
  113. package/dist/src/core/devtools/hook.js.map +1 -0
  114. package/dist/src/core/devtools/index.d.ts +34 -0
  115. package/dist/src/core/devtools/index.d.ts.map +1 -0
  116. package/dist/src/core/devtools/index.js +33 -0
  117. package/dist/src/core/devtools/index.js.map +1 -0
  118. package/dist/src/core/devtools/inspector.d.ts +31 -0
  119. package/dist/src/core/devtools/inspector.d.ts.map +1 -0
  120. package/dist/src/core/devtools/inspector.js +249 -0
  121. package/dist/src/core/devtools/inspector.js.map +1 -0
  122. package/dist/src/core/elements/Block.d.ts +9 -7
  123. package/dist/src/core/elements/Block.d.ts.map +1 -1
  124. package/dist/src/core/elements/Block.js +33 -9
  125. package/dist/src/core/elements/Block.js.map +1 -1
  126. package/dist/src/core/elements/BlockOutlet.d.ts +19 -8
  127. package/dist/src/core/elements/BlockOutlet.d.ts.map +1 -1
  128. package/dist/src/core/elements/BlockOutlet.js +57 -13
  129. package/dist/src/core/elements/BlockOutlet.js.map +1 -1
  130. package/dist/src/core/elements/Component.d.ts +83 -11
  131. package/dist/src/core/elements/Component.d.ts.map +1 -1
  132. package/dist/src/core/elements/Component.js +334 -13
  133. package/dist/src/core/elements/Component.js.map +1 -1
  134. package/dist/src/core/elements/ForeachSlotCache.d.ts +95 -0
  135. package/dist/src/core/elements/ForeachSlotCache.d.ts.map +1 -0
  136. package/dist/src/core/elements/ForeachSlotCache.js +149 -0
  137. package/dist/src/core/elements/ForeachSlotCache.js.map +1 -0
  138. package/dist/src/core/elements/Fragment.d.ts +19 -13
  139. package/dist/src/core/elements/Fragment.d.ts.map +1 -1
  140. package/dist/src/core/elements/Fragment.js +43 -20
  141. package/dist/src/core/elements/Fragment.js.map +1 -1
  142. package/dist/src/core/elements/Html.d.ts +89 -12
  143. package/dist/src/core/elements/Html.d.ts.map +1 -1
  144. package/dist/src/core/elements/Html.js +707 -106
  145. package/dist/src/core/elements/Html.js.map +1 -1
  146. package/dist/src/core/elements/Output.d.ts +34 -10
  147. package/dist/src/core/elements/Output.d.ts.map +1 -1
  148. package/dist/src/core/elements/Output.js +141 -26
  149. package/dist/src/core/elements/Output.js.map +1 -1
  150. package/dist/src/core/elements/Reactive.d.ts +85 -14
  151. package/dist/src/core/elements/Reactive.d.ts.map +1 -1
  152. package/dist/src/core/elements/Reactive.js +315 -41
  153. package/dist/src/core/elements/Reactive.js.map +1 -1
  154. package/dist/src/core/elements/TextElement.d.ts +11 -7
  155. package/dist/src/core/elements/TextElement.d.ts.map +1 -1
  156. package/dist/src/core/elements/TextElement.js +18 -11
  157. package/dist/src/core/elements/TextElement.js.map +1 -1
  158. package/dist/src/core/elements/Wrapper.d.ts +24 -13
  159. package/dist/src/core/elements/Wrapper.d.ts.map +1 -1
  160. package/dist/src/core/elements/Wrapper.js +65 -8
  161. package/dist/src/core/elements/Wrapper.js.map +1 -1
  162. package/dist/src/core/elements/Yield.d.ts +10 -9
  163. package/dist/src/core/elements/Yield.d.ts.map +1 -1
  164. package/dist/src/core/elements/Yield.js +31 -19
  165. package/dist/src/core/elements/Yield.js.map +1 -1
  166. package/dist/src/core/elements/helpers.d.ts +7 -7
  167. package/dist/src/core/elements/helpers.d.ts.map +1 -1
  168. package/dist/src/core/elements/helpers.js +4 -4
  169. package/dist/src/core/elements/index.d.ts +12 -11
  170. package/dist/src/core/elements/index.d.ts.map +1 -1
  171. package/dist/src/core/elements/index.js +12 -11
  172. package/dist/src/core/elements/index.js.map +1 -1
  173. package/dist/src/core/elements/reconcileChildren.d.ts +7 -0
  174. package/dist/src/core/elements/reconcileChildren.d.ts.map +1 -0
  175. package/dist/src/core/elements/reconcileChildren.js +74 -0
  176. package/dist/src/core/elements/reconcileChildren.js.map +1 -0
  177. package/dist/src/core/hellpers/utils.d.ts +2 -2
  178. package/dist/src/core/hellpers/utils.js +4 -4
  179. package/dist/src/core/helpers/ApiClient.d.ts +58 -0
  180. package/dist/src/core/helpers/ApiClient.d.ts.map +1 -0
  181. package/dist/src/core/helpers/ApiClient.js +131 -0
  182. package/dist/src/core/helpers/ApiClient.js.map +1 -0
  183. package/dist/src/core/helpers/app.d.ts +3 -0
  184. package/dist/src/core/helpers/app.d.ts.map +1 -0
  185. package/dist/src/core/helpers/app.js +63 -0
  186. package/dist/src/core/helpers/app.js.map +1 -0
  187. package/dist/src/core/helpers/transition.d.ts +34 -0
  188. package/dist/src/core/helpers/transition.d.ts.map +1 -0
  189. package/dist/src/core/helpers/transition.js +118 -0
  190. package/dist/src/core/helpers/transition.js.map +1 -0
  191. package/dist/src/core/helpers/utils.d.ts +26 -0
  192. package/dist/src/core/helpers/utils.d.ts.map +1 -0
  193. package/dist/src/core/helpers/utils.js +96 -0
  194. package/dist/src/core/helpers/utils.js.map +1 -0
  195. package/dist/src/core/helpers/view.d.ts +39 -0
  196. package/dist/src/core/helpers/view.d.ts.map +1 -0
  197. package/dist/src/core/helpers/view.js +286 -0
  198. package/dist/src/core/helpers/view.js.map +1 -0
  199. package/dist/src/core/routers/Router.d.ts +108 -7
  200. package/dist/src/core/routers/Router.d.ts.map +1 -1
  201. package/dist/src/core/routers/Router.js +444 -68
  202. package/dist/src/core/routers/Router.js.map +1 -1
  203. package/dist/src/core/routers/index.d.ts +2 -2
  204. package/dist/src/core/routers/index.d.ts.map +1 -1
  205. package/dist/src/core/routers/index.js +1 -1
  206. package/dist/src/core/routers/index.js.map +1 -1
  207. package/dist/src/core/services/AssetManager.d.ts +112 -0
  208. package/dist/src/core/services/AssetManager.d.ts.map +1 -0
  209. package/dist/src/core/services/AssetManager.js +361 -0
  210. package/dist/src/core/services/AssetManager.js.map +1 -0
  211. package/dist/src/core/services/BlockManager.d.ts +73 -2
  212. package/dist/src/core/services/BlockManager.d.ts.map +1 -1
  213. package/dist/src/core/services/BlockManager.js +270 -48
  214. package/dist/src/core/services/BlockManager.js.map +1 -1
  215. package/dist/src/core/services/DomService.js +3 -3
  216. package/dist/src/core/services/DomService.js.map +1 -1
  217. package/dist/src/core/services/HeadService.d.ts +24 -0
  218. package/dist/src/core/services/HeadService.d.ts.map +1 -0
  219. package/dist/src/core/services/HeadService.js +120 -0
  220. package/dist/src/core/services/HeadService.js.map +1 -0
  221. package/dist/src/core/services/HelperService.d.ts +14 -3
  222. package/dist/src/core/services/HelperService.d.ts.map +1 -1
  223. package/dist/src/core/services/HelperService.js +32 -2
  224. package/dist/src/core/services/HelperService.js.map +1 -1
  225. package/dist/src/core/services/HttpService.d.ts +8 -0
  226. package/dist/src/core/services/HttpService.d.ts.map +1 -1
  227. package/dist/src/core/services/HttpService.js +121 -47
  228. package/dist/src/core/services/HttpService.js.map +1 -1
  229. package/dist/src/core/services/MarkerRegistry.d.ts +51 -8
  230. package/dist/src/core/services/MarkerRegistry.d.ts.map +1 -1
  231. package/dist/src/core/services/MarkerRegistry.js +135 -14
  232. package/dist/src/core/services/MarkerRegistry.js.map +1 -1
  233. package/dist/src/core/services/PageCache.d.ts +101 -0
  234. package/dist/src/core/services/PageCache.d.ts.map +1 -0
  235. package/dist/src/core/services/PageCache.js +184 -0
  236. package/dist/src/core/services/PageCache.js.map +1 -0
  237. package/dist/src/core/services/SectionManager.d.ts +100 -0
  238. package/dist/src/core/services/SectionManager.d.ts.map +1 -0
  239. package/dist/src/core/services/SectionManager.js +408 -0
  240. package/dist/src/core/services/SectionManager.js.map +1 -0
  241. package/dist/src/core/services/StorageService.js +1 -1
  242. package/dist/src/core/services/TranslationService.d.ts +21 -0
  243. package/dist/src/core/services/TranslationService.d.ts.map +1 -0
  244. package/dist/src/core/services/TranslationService.js +95 -0
  245. package/dist/src/core/services/TranslationService.js.map +1 -0
  246. package/dist/src/core/services/index.d.ts +11 -8
  247. package/dist/src/core/services/index.d.ts.map +1 -1
  248. package/dist/src/core/services/index.js +11 -8
  249. package/dist/src/core/services/index.js.map +1 -1
  250. package/dist/src/core/types/utils.d.ts +8 -8
  251. package/dist/src/core/types/utils.d.ts.map +1 -1
  252. package/dist/src/core/view/LoopContext.d.ts +21 -1
  253. package/dist/src/core/view/LoopContext.d.ts.map +1 -1
  254. package/dist/src/core/view/LoopContext.js +36 -0
  255. package/dist/src/core/view/LoopContext.js.map +1 -1
  256. package/dist/src/core/view/ResourceScope.d.ts +38 -0
  257. package/dist/src/core/view/ResourceScope.d.ts.map +1 -0
  258. package/dist/src/core/view/ResourceScope.js +167 -0
  259. package/dist/src/core/view/ResourceScope.js.map +1 -0
  260. package/dist/src/core/view/Section.d.ts +17 -32
  261. package/dist/src/core/view/Section.d.ts.map +1 -1
  262. package/dist/src/core/view/Section.js +14 -55
  263. package/dist/src/core/view/Section.js.map +1 -1
  264. package/dist/src/core/view/View.d.ts +43 -7
  265. package/dist/src/core/view/View.d.ts.map +1 -1
  266. package/dist/src/core/view/View.js +22 -4
  267. package/dist/src/core/view/View.js.map +1 -1
  268. package/dist/src/core/view/ViewController.d.ts +313 -40
  269. package/dist/src/core/view/ViewController.d.ts.map +1 -1
  270. package/dist/src/core/view/ViewController.js +1002 -147
  271. package/dist/src/core/view/ViewController.js.map +1 -1
  272. package/dist/src/core/view/ViewManager.d.ts +318 -27
  273. package/dist/src/core/view/ViewManager.d.ts.map +1 -1
  274. package/dist/src/core/view/ViewManager.js +1199 -258
  275. package/dist/src/core/view/ViewManager.js.map +1 -1
  276. package/dist/src/core/view/ViewState.d.ts +185 -6
  277. package/dist/src/core/view/ViewState.d.ts.map +1 -1
  278. package/dist/src/core/view/ViewState.js +851 -123
  279. package/dist/src/core/view/ViewState.js.map +1 -1
  280. package/dist/src/core/view/index.d.ts +5 -5
  281. package/dist/src/core/view/index.d.ts.map +1 -1
  282. package/dist/src/core/view/index.js +5 -5
  283. package/dist/src/core/view/index.js.map +1 -1
  284. package/dist/src/testing/index.d.ts +69 -0
  285. package/dist/src/testing/index.d.ts.map +1 -0
  286. package/dist/src/testing/index.js +140 -0
  287. package/dist/src/testing/index.js.map +1 -0
  288. package/index.ts +29 -5
  289. package/package.json +30 -21
  290. package/plugins.ts +2 -2
  291. package/src/core/app/Application.ts +58 -31
  292. package/src/core/bootstrap/app.ts +80 -6
  293. package/src/core/bootstrap/bundle.ts +101 -0
  294. package/src/core/bootstrap/providers/ApiServiceProvider.ts +4 -4
  295. package/src/core/bootstrap/providers/CoreServiceProvider.ts +14 -8
  296. package/src/core/bootstrap/providers/HelperServiceProvider.ts +8 -3
  297. package/src/core/bootstrap/providers/RouteServiceProvider.ts +15 -4
  298. package/src/core/bootstrap/providers/ServiceProvider.ts +8 -8
  299. package/src/core/bootstrap/providers/ViewServiceProvider.ts +3 -3
  300. package/src/core/bootstrap/providers/default-providers.ts +51 -16
  301. package/src/core/bootstrap/providers/index.ts +9 -9
  302. package/src/core/bootstrap/providers/provider-order.test.ts +16 -27
  303. package/src/core/bootstrap/providers/provider-order.ts +1 -1
  304. package/src/core/bootstrap/ssr.ts +136 -0
  305. package/src/core/cache/ViewCache.ts +1 -1
  306. package/src/core/cache/index.ts +1 -1
  307. package/src/core/contracts/ApplicationInterface.ts +13 -11
  308. package/src/core/contracts/BlockInterface.ts +18 -18
  309. package/src/core/contracts/BundleInterface.ts +40 -0
  310. package/src/core/contracts/ComponentInterface.ts +7 -6
  311. package/src/core/contracts/ElementInterface.ts +95 -27
  312. package/src/core/contracts/HeadServiceInterface.ts +41 -0
  313. package/src/core/contracts/HelperInterface.ts +9 -1
  314. package/src/core/contracts/HttpServiceInterface.ts +3 -0
  315. package/src/core/contracts/MarkerInterface.ts +22 -49
  316. package/src/core/contracts/ReactiveInterface.ts +9 -9
  317. package/src/core/contracts/RouterInterface.ts +5 -2
  318. package/src/core/contracts/SectionInterface.ts +49 -0
  319. package/src/core/contracts/ServiceProviderInterface.ts +3 -3
  320. package/src/core/contracts/ViewControllerInterface.ts +124 -16
  321. package/src/core/contracts/ViewInterface.ts +34 -5
  322. package/src/core/contracts/ViewManagerInterface.ts +40 -5
  323. package/src/core/contracts/ViewStateInterface.ts +39 -2
  324. package/src/core/contracts/common.ts +3 -3
  325. package/src/core/contracts/utils.ts +19 -19
  326. package/src/core/contracts/views.ts +2 -22
  327. package/src/core/devtools/hook.ts +142 -0
  328. package/src/core/devtools/index.ts +38 -0
  329. package/src/core/devtools/inspector.ts +270 -0
  330. package/src/core/elements/Block.ts +43 -21
  331. package/src/core/elements/BlockOutlet.ts +61 -21
  332. package/src/core/elements/Component.ts +352 -18
  333. package/src/core/elements/ElementManager.ts +9 -9
  334. package/src/core/elements/ForeachSlotCache.ts +170 -0
  335. package/src/core/elements/Fragment.ts +50 -32
  336. package/src/core/elements/Html.ts +696 -117
  337. package/src/core/elements/Output.ts +147 -30
  338. package/src/core/elements/Reactive.ts +329 -52
  339. package/src/core/elements/TextElement.ts +25 -16
  340. package/src/core/elements/Wrapper.ts +84 -18
  341. package/src/core/elements/Yield.ts +35 -24
  342. package/src/core/elements/helpers.ts +12 -12
  343. package/src/core/elements/index.ts +25 -24
  344. package/src/core/elements/reconcileChildren.ts +70 -0
  345. package/src/core/{hellpers → helpers}/ApiClient.ts +8 -1
  346. package/src/core/{hellpers → helpers}/app.ts +13 -2
  347. package/src/core/helpers/transition.ts +127 -0
  348. package/src/core/{hellpers → helpers}/utils.ts +4 -4
  349. package/src/core/helpers/view.ts +283 -0
  350. package/src/core/routers/Router.ts +458 -64
  351. package/src/core/routers/index.ts +2 -2
  352. package/src/core/services/AssetManager.ts +387 -0
  353. package/src/core/services/BlockManager.ts +272 -50
  354. package/src/core/services/DomService.ts +3 -3
  355. package/src/core/services/HeadService.ts +124 -0
  356. package/src/core/services/HelperService.ts +34 -4
  357. package/src/core/services/HttpService.ts +116 -55
  358. package/src/core/services/MarkerRegistry.ts +142 -16
  359. package/src/core/services/PageCache.ts +239 -0
  360. package/src/core/services/SectionManager.ts +387 -0
  361. package/src/core/services/StorageService.ts +1 -1
  362. package/src/core/services/TranslationService.ts +91 -0
  363. package/src/core/services/index.ts +11 -8
  364. package/src/core/types/utils.ts +8 -8
  365. package/src/core/view/LoopContext.ts +38 -1
  366. package/src/core/view/ResourceScope.ts +174 -0
  367. package/src/core/view/Section.ts +21 -68
  368. package/src/core/view/View.ts +57 -8
  369. package/src/core/view/ViewController.ts +1070 -186
  370. package/src/core/view/ViewManager.ts +1346 -272
  371. package/src/core/view/ViewState.ts +834 -116
  372. package/src/core/view/index.ts +5 -5
  373. package/src/testing/index.ts +184 -0
  374. package/dist/src/core/services/MarkerService.d.ts +0 -299
  375. package/dist/src/core/services/MarkerService.d.ts.map +0 -1
  376. package/dist/src/core/services/MarkerService.js +0 -723
  377. package/dist/src/core/services/MarkerService.js.map +0 -1
  378. package/src/core/services/MarkerService.ts +0 -923
@@ -1,12 +1,12 @@
1
- import type { BlockRenderFactory } from "../contracts/BlockInterface";
2
- import type { HtmlInterface, OneElementConfig, OneChildrenFactory } from "../contracts/ElementInterface";
3
- import type { ReactiveRenderFn } from "../contracts/ReactiveInterface";
4
- import type { ViewControllerInterface } from "../contracts/ViewControllerInterface";
5
- import { Html } from "./Html";
6
- import { TextElement } from "./TextElement";
7
- import { Reactive } from "./Reactive";
8
- import { Fragment } from "./Fragment";
9
- import { Block } from "./Block";
1
+ import type { BlockRenderFactory } from "../contracts/BlockInterface.js";
2
+ import type { HtmlInterface, SaoElementConfig, SaoChildrenFactory } from "../contracts/ElementInterface.js";
3
+ import type { ReactiveRenderFn } from "../contracts/ReactiveInterface.js";
4
+ import type { ViewControllerInterface } from "../contracts/ViewControllerInterface.js";
5
+ import { Html } from "./Html.js";
6
+ import { TextElement } from "./TextElement.js";
7
+ import { Reactive } from "./Reactive.js";
8
+ import { Fragment } from "./Fragment.js";
9
+ import { Block } from "./Block.js";
10
10
 
11
11
  /**
12
12
  * OneElementManager — factory/registry for creating One elements.
@@ -0,0 +1,170 @@
1
+ /**
2
+ * ForeachSlotCache — keyed slot manager cho @foreach reconciliation.
3
+ *
4
+ * # Cơ chế
5
+ * Mỗi item được identify bằng một cache key:
6
+ * - Có @key(expr) → key = giá trị expr (field keying, vd `item.id`)
7
+ * - Không có @key → key = object reference của item (identity keying)
8
+ * Duplicate keys (primitive lists `['a','b','a']`, refs lặp) được phân biệt
9
+ * bằng occurrence index trong pass — key thứ n trùng nhau map vào slot thứ n.
10
+ *
11
+ * # Reuse contract
12
+ * Slot chỉ được REUSE khi cache key khớp VÀ item ref không đổi
13
+ * (`slot.item === item`). Ref đổi → recreate, vì compiled output đóng gói
14
+ * `item` trực tiếp vào closure (`() => item.name`) — reuse với ref cũ sẽ
15
+ * hiển thị data cũ. Field key vì vậy chủ yếu mang lại: bookkeeping đúng cho
16
+ * duplicate/primitive items + ý định tường minh của developer.
17
+ *
18
+ * # Pass protocol (một chu kỳ render)
19
+ * 1. `beginPass()` — reset occurrence counters + tập slot touched
20
+ * 2. `claim(key, item)` mỗi item theo thứ tự list:
21
+ * hit (slot.item === item) → dùng lại, slot được mark touched
22
+ * miss → caller tạo elements rồi `store(key, occ, item, elements)`
23
+ * 3. `prunePass(onRemove)` — slot KHÔNG được touch trong pass = item đã rời
24
+ * list → callback destroy + gỡ khỏi cache. (Trước đây bước này là dead
25
+ * code — cache không bao giờ gỡ entry → element của item bị xoá leak.)
26
+ * Slot bị `store()` GHI ĐÈ (cùng key, ref mới) cũng đi qua đây: nó rơi khỏi
27
+ * `_map` ngay lúc ghi đè nên prunePass không còn thấy → phải giữ tạm trong
28
+ * `_evicted`. Thiếu bước này thì refresh list từ server (`@key` giữ nguyên,
29
+ * ref đổi) KHÔNG destroy elements cũ → view con của @include bị tái dùng
30
+ * trong DOM đã detach và biến mất khỏi trang.
31
+ *
32
+ * # Quan hệ với Reactive
33
+ * Reactive type 'foreach' giữ một instance; cửa sổ `_currentForeachCache`
34
+ * chỉ mở quanh CHÍNH childrenFactory call (không mở trong child.render() —
35
+ * tránh nested @foreach ghi nhầm vào cache của loop ngoài).
36
+ *
37
+ * @see Reactive.renderForeach()
38
+ * @see ViewController.__foreach()
39
+ */
40
+
41
+ /** Một slot tương ứng với một item trong foreach list. */
42
+ export interface ForeachSlot {
43
+ /** Reference tới item gốc — điều kiện reuse là ref không đổi */
44
+ item: any;
45
+ /** Saola elements sinh ra bởi item factory — Html, Output, Reactive, ... */
46
+ elements: any[];
47
+ /** Compiler opt-in: closures are refreshed within this occurrence's scope. */
48
+ registry?: Map<string, any>;
49
+ identity?: number;
50
+ }
51
+
52
+ /** Kết quả claim: slot khi reuse được, occ để store khi phải tạo mới. */
53
+ export interface ForeachClaim {
54
+ slot: ForeachSlot | null;
55
+ occ: number;
56
+ }
57
+
58
+ export class ForeachSlotCache {
59
+ readonly refreshedElements = new Set<any>();
60
+ private nextIdentity = 0;
61
+
62
+ /** Initial SSR indexes, then monotonically allocated identities for new rows. */
63
+ allocateIdentity(index: number): number {
64
+ const identity = Math.max(index, this.nextIdentity);
65
+ this.nextIdentity = identity + 1;
66
+ return identity;
67
+ }
68
+ /** Map key → danh sách slot theo occurrence (duplicate keys) */
69
+ private _map: Map<any, ForeachSlot[]> = new Map();
70
+ /** Occurrence counter của pass hiện tại */
71
+ private _passOcc: Map<any, number> = new Map();
72
+ /** Slots được claim-hit hoặc store trong pass hiện tại */
73
+ private _touched: Set<ForeachSlot> = new Set();
74
+ /** Slots bị store() ghi đè trong pass hiện tại — prunePass destroy rồi clear */
75
+ private _evicted: ForeachSlot[] = [];
76
+
77
+ /** Tổng số slot đang cache (mọi occurrence). */
78
+ get size(): number {
79
+ let n = 0;
80
+ for (const slots of this._map.values()) n += slots.length;
81
+ return n;
82
+ }
83
+
84
+ /** Bắt đầu một chu kỳ render — reset counters + touched set. */
85
+ beginPass(): void {
86
+ this.refreshedElements.clear();
87
+ this._passOcc = new Map();
88
+ this._touched = new Set();
89
+ this._evicted = [];
90
+ }
91
+
92
+ /**
93
+ * Claim slot cho (key, item) theo thứ tự list.
94
+ * Trả slot khi reuse được (key khớp + ref không đổi); ngược lại slot=null
95
+ * và caller phải store(key, occ, ...) sau khi tạo elements.
96
+ */
97
+ claim(key: any, item: any, reconcile = false): ForeachClaim {
98
+ const occ = this._passOcc.get(key) ?? 0;
99
+ this._passOcc.set(key, occ + 1);
100
+
101
+ const slot = this._map.get(key)?.[occ] ?? null;
102
+ if (slot && (slot.item === item || (reconcile && slot.registry))) {
103
+ this._touched.add(slot);
104
+ return { slot, occ };
105
+ }
106
+ return { slot: null, occ };
107
+ }
108
+
109
+ /**
110
+ * Lưu slot mới tại (key, occ) — ghi đè slot cũ nếu ref đã đổi.
111
+ * Slot bị ghi đè KHÔNG còn nằm trong `_map` nên prunePass duyệt `_map` sẽ
112
+ * không thấy nó nữa → phải chuyển sang `_evicted` để vẫn được destroy.
113
+ */
114
+ store(key: any, occ: number, item: any, elements: any[], registry?: Map<string, any>): ForeachSlot {
115
+ const slot: ForeachSlot = { item, elements, registry };
116
+ let slots = this._map.get(key);
117
+ if (!slots) {
118
+ slots = [];
119
+ this._map.set(key, slots);
120
+ }
121
+ const evicted = slots[occ];
122
+ if (evicted && !this._touched.has(evicted)) {
123
+ this._evicted.push(evicted);
124
+ }
125
+ slots[occ] = slot;
126
+ this._touched.add(slot);
127
+ return slot;
128
+ }
129
+
130
+ /**
131
+ * Kết thúc pass: mọi slot không được touch = item đã rời list (hoặc bị
132
+ * thay bằng ref mới) → gọi onRemove(slot) để destroy elements, gỡ khỏi cache.
133
+ */
134
+ prunePass(onRemove: (slot: ForeachSlot) => void): void {
135
+ // Slot bị ghi đè: đã rời `_map` lúc store() nên chỉ cần destroy.
136
+ for (const slot of this._evicted) onRemove(slot);
137
+ this._evicted = [];
138
+
139
+ for (const [key, slots] of this._map) {
140
+ let hasRemoval = false;
141
+ for (const slot of slots) {
142
+ if (slot && !this._touched.has(slot)) {
143
+ onRemove(slot);
144
+ hasRemoval = true;
145
+ }
146
+ }
147
+ if (hasRemoval) {
148
+ const kept = slots.filter(s => s && this._touched.has(s));
149
+ if (kept.length) {
150
+ this._map.set(key, kept);
151
+ } else {
152
+ this._map.delete(key);
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Xoá toàn bộ cache — dùng khi Reactive bị destroy.
160
+ * KHÔNG tự gọi destroy() trên elements — caller phải làm trước.
161
+ */
162
+ clear(): void {
163
+ this.nextIdentity = 0;
164
+ this.refreshedElements.clear();
165
+ this._map.clear();
166
+ this._passOcc = new Map();
167
+ this._touched = new Set();
168
+ this._evicted = [];
169
+ }
170
+ }
@@ -1,8 +1,8 @@
1
- import { InitMode, InitModes } from "../contracts/common";
2
- import type { FragmentInterface, HtmlInterface, OneChildrenFactory, OneChildrenFactoryOutput, OneElementChildren } from "../contracts/ElementInterface";
3
- import type { ViewControllerInterface } from "../contracts/ViewControllerInterface";
4
- import { generateUUID } from "../hellpers/utils";
5
- import type { OneObjectType } from "../types/utils";
1
+ import { InitMode, InitModes } from "../contracts/common.js";
2
+ import type { FragmentInterface, HtmlInterface, SaoChildrenFactory, SaoChildrenFactoryOutput, SaoElementChildren } from "../contracts/ElementInterface.js";
3
+ import type { ViewControllerInterface } from "../contracts/ViewControllerInterface.js";
4
+ import { generateUUID } from "../helpers/utils.js";
5
+ import type { SaoObjectType } from "../types/utils.js";
6
6
 
7
7
  /**
8
8
  * Fragment — renders multiple root nodes into a parent without a wrapping tag.
@@ -14,13 +14,13 @@ import type { OneObjectType } from "../types/utils";
14
14
  * similar to Reactive but without the reactivity overhead.
15
15
  */
16
16
  export class Fragment implements FragmentInterface {
17
- oneType: OneObjectType = 'Fragment';
17
+ saoType: SaoObjectType = 'Fragment';
18
18
  public parent: HtmlInterface | null;
19
19
  public nodes: Node[] = [];
20
20
  /** Tracked child element wrappers (Html, Output, Reactive, TextElement, etc.) */
21
- public children: OneElementChildren = [];
21
+ public children: SaoElementChildren = [];
22
22
  private ctx: ViewControllerInterface;
23
- private childrenFactory: OneChildrenFactory;
23
+ private childrenFactory: SaoChildrenFactory;
24
24
  public openTag: Comment;
25
25
  public closeTag: Comment;
26
26
  public id: string; // Unique ID for debugging and marker registry
@@ -39,7 +39,7 @@ export class Fragment implements FragmentInterface {
39
39
  id?: string | null,
40
40
  initMode?: InitMode,
41
41
  parentElement?: HtmlInterface | null,
42
- childrenFactory: OneChildrenFactory
42
+ childrenFactory: SaoChildrenFactory
43
43
  }) {
44
44
  this.ctx = ctx;
45
45
  this.parent = parentElement;
@@ -52,48 +52,64 @@ export class Fragment implements FragmentInterface {
52
52
  setParentElement(parent: HtmlInterface | null): void {
53
53
  this.parent = parent;
54
54
  }
55
- render(): void {
56
- if (!this.parent || !this.parent.element) return;
57
-
58
- const parentEl = this.parent.element;
55
+ /** Registry guard — element đã destroy không được reuse */
56
+ public __destroyed__: boolean = false;
59
57
 
60
- // Place start marker
61
- parentEl.appendChild(this.openTag);
58
+ /**
59
+ * Render — idempotent + position-aware (RUNTIME_CONTRACT.md §2),
60
+ * cùng pattern với Reactive.render().
61
+ */
62
+ render(): void {
63
+ if (this.__destroyed__) return;
64
+
65
+ if (!this.openTag.parentNode) {
66
+ if (!this.parent || !this.parent.element) return;
67
+ const parentEl = this.parent.element;
68
+ parentEl.appendChild(this.openTag);
69
+ parentEl.appendChild(this.closeTag);
70
+ } else {
71
+ this.clear(false);
72
+ }
62
73
 
63
74
  // Build children — compiled output uses (parentElement) => [...] signature
64
- const output: OneChildrenFactoryOutput = this.childrenFactory(this.parent);
75
+ const output: SaoChildrenFactoryOutput = this.childrenFactory(this.parent);
76
+ const insertBeforeClose = (node: Node) => {
77
+ this.closeTag.parentNode?.insertBefore(node, this.closeTag);
78
+ };
65
79
 
66
80
  for (const child of output) {
81
+ if (child === null || child === undefined) continue;
67
82
  if (typeof child === 'string' || typeof child === 'number') {
68
83
  const textNode = document.createTextNode(String(child));
69
- parentEl.appendChild(textNode);
84
+ insertBeforeClose(textNode);
70
85
  this.nodes.push(textNode);
71
- } else if (child && typeof child === 'object') {
72
- if ('element' in child) {
73
- // HtmlInterface, TextInterface — append their DOM element
74
- parentEl.appendChild(child.element);
75
- this.nodes.push(child.element);
86
+ } else if (child instanceof Node) {
87
+ insertBeforeClose(child);
88
+ this.nodes.push(child);
89
+ } else if (typeof child === 'object') {
90
+ if ('element' in child && (child as any).element) {
91
+ insertBeforeClose((child as any).element);
92
+ this.nodes.push((child as any).element);
76
93
  this.children.push(child);
77
94
  child.render();
78
95
  } else if ('openTag' in child) {
79
- // Reactive, nested Fragment, Output — they self-append markers
96
+ // Marker-based: đặt markers đúng vị trí trước, render sau
80
97
  if ('parent' in child) {
81
98
  (child as any).parent = this.parent;
82
99
  }
83
100
  if ('parentElement' in child) {
84
101
  (child as any).parentElement = this.parent;
85
102
  }
103
+ insertBeforeClose((child as any).openTag);
104
+ insertBeforeClose((child as any).closeTag);
86
105
  this.children.push(child);
87
106
  child.render();
88
107
  }
89
108
  }
90
109
  }
91
-
92
- // Place end marker
93
- parentEl.appendChild(this.closeTag);
94
110
  }
95
111
 
96
- setChildrenFactory(factory: OneChildrenFactory): void {
112
+ setChildrenFactory(factory: SaoChildrenFactory): void {
97
113
  this.childrenFactory = factory;
98
114
  }
99
115
 
@@ -126,7 +142,7 @@ export class Fragment implements FragmentInterface {
126
142
  }
127
143
 
128
144
  /** Remove all nodes between markers from the DOM */
129
- clear(): void {
145
+ clear(_destroyChildren: boolean = true): void {
130
146
  // Destroy managed children first
131
147
  for (const child of this.children) {
132
148
  if ('destroy' in child && typeof child.destroy === 'function') {
@@ -146,23 +162,25 @@ export class Fragment implements FragmentInterface {
146
162
  }
147
163
 
148
164
  destroy(): void {
165
+ this.__destroyed__ = true;
166
+ this.ctx.releaseElement?.(this);
149
167
  this.clear();
150
168
  this.openTag.remove();
151
169
  this.closeTag.remove();
152
170
  this.parent = null;
153
171
  }
154
172
 
155
- get isOneElement(): boolean {
173
+ get isSaoElement(): boolean {
156
174
  return true;
157
175
  }
158
- set isOneElement(value: boolean) {
176
+ set isSaoElement(value: boolean) {
159
177
  // No-op setter to satisfy the Interface; this property is always true for Fragment elements
160
178
  }
161
179
 
162
- get isOneFragment(): boolean {
180
+ get isSaoFragment(): boolean {
163
181
  return true;
164
182
  }
165
- set isOneFragment(value: boolean) {
183
+ set isSaoFragment(value: boolean) {
166
184
  // No-op setter to satisfy the Interface; this property is always true for Fragment elements
167
185
  }
168
186
  }