native-document 1.0.15 → 1.0.16-8.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 (649) hide show
  1. package/.npmrc.example +1 -0
  2. package/.vitepress/config.js +166 -0
  3. package/CHANGELOG.md +153 -0
  4. package/cdn.js +19 -0
  5. package/components.d.ts +2 -0
  6. package/components.js +30 -0
  7. package/devtools/ComponentRegistry.js +113 -0
  8. package/devtools/index.js +8 -0
  9. package/devtools/plugin/dev-tools-plugin.js +15 -0
  10. package/devtools/transformers/nd-vite-devtools.js +55 -0
  11. package/devtools/transformers/src/transformComponentForHrm.js +73 -0
  12. package/devtools/transformers/src/transformJsFile.js +9 -0
  13. package/devtools/transformers/src/utils.js +79 -0
  14. package/devtools/transformers/templates/hrm.hook.template.js +46 -0
  15. package/devtools/transformers/templates/hrm.orbservable.hook.template.js +76 -0
  16. package/devtools/widget/Widget.js +49 -0
  17. package/devtools/widget/widget.css +81 -0
  18. package/devtools/widget.js +23 -0
  19. package/dist/native-document.components.min.css +1 -0
  20. package/dist/native-document.components.min.js +23847 -0
  21. package/dist/native-document.dev.js +8421 -1492
  22. package/dist/native-document.dev.js.map +1 -0
  23. package/dist/native-document.devtools.min.js +1 -0
  24. package/dist/native-document.min.js +1 -1
  25. package/docs/advanced-components.md +419 -0
  26. package/docs/anchor.md +181 -257
  27. package/docs/cache.md +180 -0
  28. package/docs/cli.md +179 -0
  29. package/docs/components/accordion.md +172 -0
  30. package/docs/components/alert.md +99 -0
  31. package/docs/components/avatar.md +160 -0
  32. package/docs/components/badge.md +102 -0
  33. package/docs/components/breadcrumb.md +89 -0
  34. package/docs/components/button.md +183 -0
  35. package/docs/components/card.md +69 -0
  36. package/docs/components/context-menu.md +118 -0
  37. package/docs/components/data-table.md +345 -0
  38. package/docs/components/dropdown.md +214 -0
  39. package/docs/components/form/autocomplete-field.md +81 -0
  40. package/docs/components/form/checkbox-field.md +41 -0
  41. package/docs/components/form/checkbox-group-field.md +54 -0
  42. package/docs/components/form/color-field.md +64 -0
  43. package/docs/components/form/date-field.md +92 -0
  44. package/docs/components/form/field-collection.md +63 -0
  45. package/docs/components/form/file-field.md +203 -0
  46. package/docs/components/form/form-control.md +87 -0
  47. package/docs/components/form/image-field.md +90 -0
  48. package/docs/components/form/index.md +115 -0
  49. package/docs/components/form/number-field.md +65 -0
  50. package/docs/components/form/radio-field.md +51 -0
  51. package/docs/components/form/select-field.md +123 -0
  52. package/docs/components/form/slider.md +136 -0
  53. package/docs/components/form/string-field.md +134 -0
  54. package/docs/components/form/textarea-field.md +65 -0
  55. package/docs/components/form-fields.md +372 -0
  56. package/docs/components/getting-started.md +264 -0
  57. package/docs/components/index.md +337 -0
  58. package/docs/components/layout.md +279 -0
  59. package/docs/components/list.md +73 -0
  60. package/docs/components/menu.md +215 -0
  61. package/docs/components/modal.md +156 -0
  62. package/docs/components/pagination.md +95 -0
  63. package/docs/components/popover.md +131 -0
  64. package/docs/components/progress.md +111 -0
  65. package/docs/components/shortcut-manager.md +221 -0
  66. package/docs/components/simple-table.md +107 -0
  67. package/docs/components/skeleton.md +155 -0
  68. package/docs/components/spinner.md +100 -0
  69. package/docs/components/splitter.md +133 -0
  70. package/docs/components/stepper.md +163 -0
  71. package/docs/components/switch.md +113 -0
  72. package/docs/components/tabs.md +153 -0
  73. package/docs/components/toast.md +119 -0
  74. package/docs/components/tooltip.md +151 -0
  75. package/docs/components/traits.md +261 -0
  76. package/docs/conditional-rendering.md +177 -502
  77. package/docs/contributing.md +300 -25
  78. package/docs/core-concepts.md +207 -366
  79. package/docs/elements.md +266 -254
  80. package/docs/extending-native-document-element.md +259 -0
  81. package/docs/filters.md +247 -0
  82. package/docs/getting-started.md +195 -257
  83. package/docs/i18n.md +241 -0
  84. package/docs/index.md +76 -0
  85. package/docs/lifecycle-events.md +146 -67
  86. package/docs/list-rendering.md +240 -460
  87. package/docs/memory-management.md +135 -46
  88. package/docs/native-document-element.md +487 -0
  89. package/docs/native-fetch.md +213 -0
  90. package/docs/observable-resource.md +364 -0
  91. package/docs/observables.md +690 -357
  92. package/docs/routing.md +246 -646
  93. package/docs/state-management.md +213 -306
  94. package/docs/svg-elements.md +231 -0
  95. package/docs/theming.md +409 -0
  96. package/docs/tutorials/.gitkeep +0 -0
  97. package/docs/validation.md +98 -91
  98. package/docs/vitepress-conventions.md +219 -0
  99. package/elements.d.ts +7 -0
  100. package/elements.js +3 -4
  101. package/eslint.config.js +35 -0
  102. package/i18n.js +1 -0
  103. package/i18n.ts +2 -0
  104. package/index.d.ts +21 -0
  105. package/index.def.js +1086 -0
  106. package/index.js +19 -13
  107. package/package.json +59 -9
  108. package/readme.md +296 -93
  109. package/rollup.config.js +52 -3
  110. package/router.d.ts +7 -0
  111. package/router.js +0 -0
  112. package/src/components/$traits/has-draggable/HasDraggable.d.ts +4 -0
  113. package/src/components/$traits/has-draggable/HasDraggable.js +82 -0
  114. package/src/components/$traits/has-draggable/has-draggable.css +8 -0
  115. package/src/components/$traits/has-items/HasItems.d.ts +9 -0
  116. package/src/components/$traits/has-items/HasItems.js +64 -0
  117. package/src/components/$traits/has-position/HasFullPosition.d.ts +14 -0
  118. package/src/components/$traits/has-position/HasFullPosition.js +95 -0
  119. package/src/components/$traits/has-position/HasPosition.d.ts +7 -0
  120. package/src/components/$traits/has-position/HasPosition.js +45 -0
  121. package/src/components/$traits/has-resizable/HasResizable.d.ts +13 -0
  122. package/src/components/$traits/has-resizable/HasResizable.js +122 -0
  123. package/src/components/$traits/has-resizable/has-resizable.css +121 -0
  124. package/src/components/$traits/has-validation/HasValidation.d.ts +17 -0
  125. package/src/components/$traits/has-validation/HasValidation.js +133 -0
  126. package/src/components/BaseComponent.d.ts +32 -0
  127. package/src/components/BaseComponent.js +247 -0
  128. package/src/components/accordion/Accordion.js +268 -0
  129. package/src/components/accordion/AccordionItem.js +233 -0
  130. package/src/components/accordion/index.js +7 -0
  131. package/src/components/accordion/types/Accordion.d.ts +47 -0
  132. package/src/components/accordion/types/AccordionItem.d.ts +48 -0
  133. package/src/components/alert/Alert.js +350 -0
  134. package/src/components/alert/index.js +6 -0
  135. package/src/components/alert/types/Alert.d.ts +62 -0
  136. package/src/components/avatar/Avatar.js +430 -0
  137. package/src/components/avatar/AvatarGroup.js +97 -0
  138. package/src/components/avatar/index.js +7 -0
  139. package/src/components/avatar/types/Avatar.d.ts +74 -0
  140. package/src/components/avatar/types/AvatarGroup.d.ts +32 -0
  141. package/src/components/badge/Badge.js +245 -0
  142. package/src/components/badge/index.js +6 -0
  143. package/src/components/badge/types/Badge.d.ts +51 -0
  144. package/src/components/base-component.css +0 -0
  145. package/src/components/breadcrumb/BreadCrumb.js +138 -0
  146. package/src/components/breadcrumb/index.js +5 -0
  147. package/src/components/breadcrumb/types/BreadCrumb.d.ts +42 -0
  148. package/src/components/button/Button.js +320 -0
  149. package/src/components/button/index.js +5 -0
  150. package/src/components/button/types/Button.d.ts +62 -0
  151. package/src/components/card/Card.js +282 -0
  152. package/src/components/card/index.js +5 -0
  153. package/src/components/card/types/Card.d.ts +42 -0
  154. package/src/components/context-menu/ContextMenu.js +127 -0
  155. package/src/components/context-menu/ContextMenuGroup.js +29 -0
  156. package/src/components/context-menu/ContextMenuItem.js +28 -0
  157. package/src/components/context-menu/index.js +10 -0
  158. package/src/components/context-menu/types/ContextMenu.d.ts +30 -0
  159. package/src/components/context-menu/types/ContextMenuGroup.d.ts +18 -0
  160. package/src/components/context-menu/types/ContextMenuItem.d.ts +18 -0
  161. package/src/components/divider/Divider.js +256 -0
  162. package/src/components/divider/index.js +6 -0
  163. package/src/components/divider/types/Divider.d.ts +55 -0
  164. package/src/components/dropdown/Dropdown.js +531 -0
  165. package/src/components/dropdown/DropdownDivider.js +45 -0
  166. package/src/components/dropdown/DropdownGroup.js +83 -0
  167. package/src/components/dropdown/DropdownItem.js +150 -0
  168. package/src/components/dropdown/DropdownTrigger.js +93 -0
  169. package/src/components/dropdown/helpers.js +53 -0
  170. package/src/components/dropdown/index.js +13 -0
  171. package/src/components/dropdown/types/Dropdown.d.ts +88 -0
  172. package/src/components/dropdown/types/DropdownDivider.d.ts +20 -0
  173. package/src/components/dropdown/types/DropdownGroup.d.ts +25 -0
  174. package/src/components/dropdown/types/DropdownItem.d.ts +41 -0
  175. package/src/components/dropdown/types/DropdownTrigger.d.ts +32 -0
  176. package/src/components/form/FormControl.js +498 -0
  177. package/src/components/form/field/Field.js +419 -0
  178. package/src/components/form/field/FieldCollection.js +292 -0
  179. package/src/components/form/field/types/AutocompleteField.js +168 -0
  180. package/src/components/form/field/types/CheckboxField.js +77 -0
  181. package/src/components/form/field/types/CheckboxGroupField.js +171 -0
  182. package/src/components/form/field/types/ColorField.js +102 -0
  183. package/src/components/form/field/types/DateField.js +315 -0
  184. package/src/components/form/field/types/EmailField.js +104 -0
  185. package/src/components/form/field/types/FileField.js +276 -0
  186. package/src/components/form/field/types/HiddenField.js +44 -0
  187. package/src/components/form/field/types/ImageField.js +138 -0
  188. package/src/components/form/field/types/NumberField.js +177 -0
  189. package/src/components/form/field/types/PasswordField.js +200 -0
  190. package/src/components/form/field/types/RadioField.js +145 -0
  191. package/src/components/form/field/types/RangeField.js +117 -0
  192. package/src/components/form/field/types/SearchField.js +66 -0
  193. package/src/components/form/field/types/SelectField.js +247 -0
  194. package/src/components/form/field/types/StringField.js +148 -0
  195. package/src/components/form/field/types/TelField.js +98 -0
  196. package/src/components/form/field/types/TextAreaField.js +142 -0
  197. package/src/components/form/field/types/TimeField.js +215 -0
  198. package/src/components/form/field/types/UrlField.js +115 -0
  199. package/src/components/form/field/types/file-field-mode/FileAvatarMode.js +183 -0
  200. package/src/components/form/field/types/file-field-mode/FileDropzoneMode.js +117 -0
  201. package/src/components/form/field/types/file-field-mode/FileItemPreview.js +150 -0
  202. package/src/components/form/field/types/file-field-mode/FileNativeMode.js +43 -0
  203. package/src/components/form/field/types/file-field-mode/FileUploadButtonMode.js +120 -0
  204. package/src/components/form/field/types/file-field-mode/FileWallMode.js +106 -0
  205. package/src/components/form/index.js +61 -0
  206. package/src/components/form/merge +0 -0
  207. package/src/components/form/types/Field.d.ts +73 -0
  208. package/src/components/form/types/FieldCollection.d.ts +53 -0
  209. package/src/components/form/types/FormControl.d.ts +64 -0
  210. package/src/components/form/types/fields/AutocompleteField.d.ts +48 -0
  211. package/src/components/form/types/fields/CheckboxField.d.ts +33 -0
  212. package/src/components/form/types/fields/CheckboxGroupField.d.ts +49 -0
  213. package/src/components/form/types/fields/ColorField.d.ts +37 -0
  214. package/src/components/form/types/fields/DateField.d.ts +70 -0
  215. package/src/components/form/types/fields/EmailField.d.ts +35 -0
  216. package/src/components/form/types/fields/FileAvatarMode.d.ts +46 -0
  217. package/src/components/form/types/fields/FileDropzoneMode.d.ts +28 -0
  218. package/src/components/form/types/fields/FileField.d.ts +56 -0
  219. package/src/components/form/types/fields/FileItemPreview.d.ts +35 -0
  220. package/src/components/form/types/fields/FileNativeMode.d.ts +21 -0
  221. package/src/components/form/types/fields/FileUploadButtonMode.d.ts +34 -0
  222. package/src/components/form/types/fields/FileWallMode.d.ts +32 -0
  223. package/src/components/form/types/fields/HiddenField.d.ts +26 -0
  224. package/src/components/form/types/fields/ImageField.d.ts +45 -0
  225. package/src/components/form/types/fields/NumberField.d.ts +48 -0
  226. package/src/components/form/types/fields/PasswordField.d.ts +46 -0
  227. package/src/components/form/types/fields/RadioField.d.ts +48 -0
  228. package/src/components/form/types/fields/RangeField.d.ts +44 -0
  229. package/src/components/form/types/fields/SearchField.d.ts +34 -0
  230. package/src/components/form/types/fields/SelectField.d.ts +71 -0
  231. package/src/components/form/types/fields/StringField.d.ts +48 -0
  232. package/src/components/form/types/fields/TelField.d.ts +37 -0
  233. package/src/components/form/types/fields/TextAreaField.d.ts +44 -0
  234. package/src/components/form/types/fields/TimeField.d.ts +51 -0
  235. package/src/components/form/types/fields/UrlField.d.ts +35 -0
  236. package/src/components/form/utils.js +17 -0
  237. package/src/components/form/validation/Validation.js +565 -0
  238. package/src/components/index.d.ts +160 -0
  239. package/src/components/list/HasListItem.js +171 -0
  240. package/src/components/list/List.js +125 -0
  241. package/src/components/list/ListDivider.js +39 -0
  242. package/src/components/list/ListGroup.js +135 -0
  243. package/src/components/list/ListItem.js +212 -0
  244. package/src/components/list/index.js +12 -0
  245. package/src/components/list/types/List.d.ts +43 -0
  246. package/src/components/list/types/ListGroup.d.ts +37 -0
  247. package/src/components/list/types/ListItem.d.ts +53 -0
  248. package/src/components/menu/HasMenuItem.js +182 -0
  249. package/src/components/menu/Menu.js +227 -0
  250. package/src/components/menu/MenuDivider.js +37 -0
  251. package/src/components/menu/MenuGroup.js +126 -0
  252. package/src/components/menu/MenuItem.js +190 -0
  253. package/src/components/menu/MenuLink.js +51 -0
  254. package/src/components/menu/index.js +14 -0
  255. package/src/components/menu/types/Menu.d.ts +60 -0
  256. package/src/components/menu/types/MenuDivider.d.ts +19 -0
  257. package/src/components/menu/types/MenuGroup.d.ts +44 -0
  258. package/src/components/menu/types/MenuItem.d.ts +46 -0
  259. package/src/components/menu/types/MenuLink.d.ts +16 -0
  260. package/src/components/modal/Modal.js +524 -0
  261. package/src/components/modal/index.js +5 -0
  262. package/src/components/modal/types/Modal.d.ts +94 -0
  263. package/src/components/pagination/Pagination.js +411 -0
  264. package/src/components/pagination/index.js +5 -0
  265. package/src/components/pagination/types/Pagination.d.ts +68 -0
  266. package/src/components/popover/Popover.js +459 -0
  267. package/src/components/popover/PopoverFooter.js +61 -0
  268. package/src/components/popover/PopoverHeader.js +68 -0
  269. package/src/components/popover/index.js +10 -0
  270. package/src/components/popover/types/Popover.d.ts +83 -0
  271. package/src/components/popover/types/PopoverFooter.d.ts +24 -0
  272. package/src/components/popover/types/PopoverHeader.d.ts +26 -0
  273. package/src/components/progress/Progress.js +401 -0
  274. package/src/components/progress/index.js +6 -0
  275. package/src/components/progress/types/Progress.d.ts +77 -0
  276. package/src/components/skeleton/Skeleton.js +228 -0
  277. package/src/components/skeleton/index.js +6 -0
  278. package/src/components/skeleton/types/Skeleton.d.ts +55 -0
  279. package/src/components/slider/Slider.js +406 -0
  280. package/src/components/slider/index.js +5 -0
  281. package/src/components/slider/types/Slider.d.ts +82 -0
  282. package/src/components/spacer/Spacer.js +27 -0
  283. package/src/components/spacer/index.js +5 -0
  284. package/src/components/spacer/types/Spacer.d.ts +19 -0
  285. package/src/components/spinner/Spinner.js +350 -0
  286. package/src/components/spinner/index.js +5 -0
  287. package/src/components/spinner/types/Spinner.d.ts +71 -0
  288. package/src/components/splitter/Splitter.js +164 -0
  289. package/src/components/splitter/SplitterGutter.js +140 -0
  290. package/src/components/splitter/SplitterPanel.js +143 -0
  291. package/src/components/splitter/index.js +10 -0
  292. package/src/components/splitter/types/Splitter.d.ts +38 -0
  293. package/src/components/splitter/types/SplitterGutter.d.ts +38 -0
  294. package/src/components/splitter/types/SplitterPanel.d.ts +41 -0
  295. package/src/components/stacks/AbsoluteStack.js +53 -0
  296. package/src/components/stacks/FixedStack.js +53 -0
  297. package/src/components/stacks/HStack.js +54 -0
  298. package/src/components/stacks/PositionStack.js +254 -0
  299. package/src/components/stacks/RelativeStack.js +53 -0
  300. package/src/components/stacks/Stack.js +166 -0
  301. package/src/components/stacks/VStack.js +55 -0
  302. package/src/components/stacks/index.js +21 -0
  303. package/src/components/stacks/types/AbsoluteStack.d.ts +16 -0
  304. package/src/components/stacks/types/FixedStack.d.ts +16 -0
  305. package/src/components/stacks/types/HStack.d.ts +16 -0
  306. package/src/components/stacks/types/PositionStack.d.ts +54 -0
  307. package/src/components/stacks/types/RelativeStack.d.ts +17 -0
  308. package/src/components/stacks/types/Stack.d.ts +39 -0
  309. package/src/components/stacks/types/VStack.d.ts +16 -0
  310. package/src/components/stepper/Stepper.js +461 -0
  311. package/src/components/stepper/StepperStep.js +241 -0
  312. package/src/components/stepper/index.js +8 -0
  313. package/src/components/stepper/types/Stepper.d.ts +68 -0
  314. package/src/components/stepper/types/StepperStep.d.ts +54 -0
  315. package/src/components/switch/Switch.js +266 -0
  316. package/src/components/switch/index.js +6 -0
  317. package/src/components/switch/types/Switch.d.ts +55 -0
  318. package/src/components/table/Column.js +212 -0
  319. package/src/components/table/ColumnGroup.js +90 -0
  320. package/src/components/table/DataTable.js +720 -0
  321. package/src/components/table/SimpleTable.js +139 -0
  322. package/src/components/table/index.js +7 -0
  323. package/src/components/table/types/Column.d.ts +49 -0
  324. package/src/components/table/types/ColumnGroup.d.ts +28 -0
  325. package/src/components/table/types/DataTable.d.ts +97 -0
  326. package/src/components/table/types/SimpleTable.d.ts +40 -0
  327. package/src/components/tabs/Tabs.js +395 -0
  328. package/src/components/tabs/index.js +6 -0
  329. package/src/components/tabs/types/Tabs.d.ts +78 -0
  330. package/src/components/toast/Toast.js +262 -0
  331. package/src/components/toast/ToastError.js +0 -0
  332. package/src/components/toast/ToastInfo.js +0 -0
  333. package/src/components/toast/ToastSuccess.js +0 -0
  334. package/src/components/toast/ToastWarning.js +0 -0
  335. package/src/components/toast/index.js +5 -0
  336. package/src/components/toast/types/Toast.d.ts +57 -0
  337. package/src/components/toast/types/ToastError.d.ts +7 -0
  338. package/src/components/toast/types/ToastInfo.d.ts +7 -0
  339. package/src/components/toast/types/ToastSuccess.d.ts +7 -0
  340. package/src/components/toast/types/ToastWarning.d.ts +7 -0
  341. package/src/components/tooltip/Tooltip.js +359 -0
  342. package/src/components/tooltip/index.js +5 -0
  343. package/src/components/tooltip/prototypes.js +6 -0
  344. package/src/components/tooltip/types/Tooltip.d.ts +65 -0
  345. package/src/{data → core/data}/MemoryManager.js +2 -3
  346. package/src/core/data/Observable.js +227 -0
  347. package/src/core/data/ObservableArray.js +522 -0
  348. package/src/core/data/ObservableChecker.js +39 -0
  349. package/src/core/data/ObservableItem.js +611 -0
  350. package/src/core/data/ObservableObject.js +274 -0
  351. package/src/core/data/ObservableResource.js +315 -0
  352. package/src/core/data/ObservableWhen.js +54 -0
  353. package/src/core/data/Store.js +520 -0
  354. package/src/core/data/observable-helpers/observable.is-to.js +390 -0
  355. package/src/core/data/observable-helpers/observable.prototypes.js +145 -0
  356. package/src/core/elements/anchor/anchor-with-sentinel.js +66 -0
  357. package/src/core/elements/anchor/anchor.js +210 -0
  358. package/src/core/elements/anchor/one-child-anchor-overwriting.js +66 -0
  359. package/src/core/elements/content-formatter.js +169 -0
  360. package/src/core/elements/control/for-each-array.js +292 -0
  361. package/src/{elements → core/elements}/control/for-each.js +42 -23
  362. package/src/core/elements/control/show-if.js +94 -0
  363. package/src/core/elements/control/show-when.js +54 -0
  364. package/src/core/elements/control/switch.js +141 -0
  365. package/src/core/elements/description-list.js +19 -0
  366. package/src/core/elements/form.js +255 -0
  367. package/src/core/elements/fragment.js +8 -0
  368. package/src/core/elements/html5-semantics.js +55 -0
  369. package/src/core/elements/img.js +59 -0
  370. package/src/{elements → core/elements}/index.js +4 -4
  371. package/src/core/elements/interactive.js +25 -0
  372. package/src/core/elements/list.js +37 -0
  373. package/src/core/elements/medias.js +37 -0
  374. package/src/core/elements/meta-data.js +43 -0
  375. package/src/core/elements/svg.js +61 -0
  376. package/src/core/elements/table.js +73 -0
  377. package/src/{errors → core/errors}/ArgTypesError.js +1 -1
  378. package/src/{errors → core/errors}/NativeDocumentError.js +0 -0
  379. package/src/core/utils/HasEventEmitter.js +85 -0
  380. package/src/core/utils/args-types.js +140 -0
  381. package/src/core/utils/cache.js +5 -0
  382. package/src/core/utils/callback-handler.js +50 -0
  383. package/src/core/utils/debug-manager.js +40 -0
  384. package/src/core/utils/events.js +148 -0
  385. package/src/core/utils/filters/date.js +178 -0
  386. package/src/core/utils/filters/index.js +4 -0
  387. package/src/core/utils/filters/standard.js +263 -0
  388. package/src/core/utils/filters/strings.js +67 -0
  389. package/src/core/utils/filters/utils.js +77 -0
  390. package/src/core/utils/formatters.js +90 -0
  391. package/src/core/utils/helpers.js +144 -0
  392. package/src/core/utils/localstorage.js +57 -0
  393. package/src/core/utils/memoize.js +115 -0
  394. package/src/core/utils/plugins-manager.js +81 -0
  395. package/src/core/utils/property-accumulator.js +72 -0
  396. package/src/core/utils/prototypes.js +44 -0
  397. package/src/core/utils/shortcut-manager.js +242 -0
  398. package/src/{utils → core/utils}/validator.js +58 -22
  399. package/src/core/wrappers/AttributesWrapper.js +98 -0
  400. package/src/core/wrappers/DocumentObserver.js +182 -0
  401. package/src/core/wrappers/ElementCreator.js +120 -0
  402. package/src/core/wrappers/HtmlElementWrapper.js +98 -0
  403. package/src/core/wrappers/NDElement.js +613 -0
  404. package/src/core/wrappers/NdPrototype.js +233 -0
  405. package/src/core/wrappers/SingletonView.js +99 -0
  406. package/src/core/wrappers/SvgElementWrapper.js +15 -0
  407. package/src/core/wrappers/TemplateBinding.js +7 -0
  408. package/src/core/wrappers/constants.js +66 -0
  409. package/src/core/wrappers/prototypes/attributes-extensions.js +179 -0
  410. package/src/core/wrappers/prototypes/bind-class-extensions.js +0 -0
  411. package/src/core/wrappers/prototypes/nd-element-extensions.js +157 -0
  412. package/src/core/wrappers/prototypes/nd-element.transition.extensions.js +127 -0
  413. package/src/core/wrappers/template-cloner/NodeCloner.js +209 -0
  414. package/src/core/wrappers/template-cloner/TemplateCloner.js +192 -0
  415. package/src/core/wrappers/template-cloner/attributes-hydrator.js +142 -0
  416. package/src/core/wrappers/template-cloner/utils.js +173 -0
  417. package/src/fetch/NativeFetch.js +89 -0
  418. package/src/i18n/bin/scan.js +132 -0
  419. package/src/i18n/index.d.ts +2 -0
  420. package/src/i18n/service/I18nService.d.ts +27 -0
  421. package/src/i18n/service/I18nService.js +46 -0
  422. package/src/i18n/service/functions.d.ts +22 -0
  423. package/src/i18n/service/functions.js +29 -0
  424. package/src/router/Route.js +33 -8
  425. package/src/router/RouteGroupHelper.js +10 -2
  426. package/src/router/Router.js +63 -22
  427. package/src/router/RouterComponent.js +114 -6
  428. package/src/{errors → router/errors}/RouterError.js +0 -1
  429. package/src/router/link.js +9 -10
  430. package/src/router/modes/HashRouter.js +2 -2
  431. package/src/router/modes/HistoryRouter.js +2 -3
  432. package/src/router/modes/MemoryRouter.js +1 -1
  433. package/src/ui/components/accordion/AccordionItemRender.js +63 -0
  434. package/src/ui/components/accordion/AccordionRender.js +35 -0
  435. package/src/ui/components/accordion/accordion.css +121 -0
  436. package/src/ui/components/alert/AlertRender.js +81 -0
  437. package/src/ui/components/alert/alert.css +163 -0
  438. package/src/ui/components/avatar/avata-group/AvatarGroupRender.js +50 -0
  439. package/src/ui/components/avatar/avata-group/avatar-group.css +38 -0
  440. package/src/ui/components/avatar/avatar/AvatarRender.js +87 -0
  441. package/src/ui/components/avatar/avatar/avatar.css +189 -0
  442. package/src/ui/components/badge/BadgeRender.js +25 -0
  443. package/src/ui/components/badge/badge.css +168 -0
  444. package/src/ui/components/breadcrumb/BreadcrumbRender.js +44 -0
  445. package/src/ui/components/breadcrumb/breadcrumb.css +55 -0
  446. package/src/ui/components/button/ButtonRender.js +65 -0
  447. package/src/ui/components/button/button.css +296 -0
  448. package/src/ui/components/card/CardRender.js +133 -0
  449. package/src/ui/components/card/card.css +169 -0
  450. package/src/ui/components/contextmenu/ContextmenuRender.js +68 -0
  451. package/src/ui/components/contextmenu/contextmenu.css +36 -0
  452. package/src/ui/components/divider/DividerRender.js +70 -0
  453. package/src/ui/components/divider/divider.css +70 -0
  454. package/src/ui/components/dropdown/DropdownRender.js +92 -0
  455. package/src/ui/components/dropdown/divider/DropdownDividerRender.js +9 -0
  456. package/src/ui/components/dropdown/divider/dropdown-divider.css +0 -0
  457. package/src/ui/components/dropdown/dropdown.css +179 -0
  458. package/src/ui/components/dropdown/group/DropdownGroupRender.js +23 -0
  459. package/src/ui/components/dropdown/group/dropdown-group.css +0 -0
  460. package/src/ui/components/dropdown/item/DropdownItemRender.js +29 -0
  461. package/src/ui/components/dropdown/item/dropdown-item.css +0 -0
  462. package/src/ui/components/form/FieldCollectionRender.js +110 -0
  463. package/src/ui/components/form/FormControlRender.js +85 -0
  464. package/src/ui/components/form/field-collection.css +55 -0
  465. package/src/ui/components/form/fields/AutocompleteFieldRender.js +143 -0
  466. package/src/ui/components/form/fields/CheckboxFieldRender.js +59 -0
  467. package/src/ui/components/form/fields/CheckboxGroupFieldRender.js +92 -0
  468. package/src/ui/components/form/fields/ColorFieldRender.js +30 -0
  469. package/src/ui/components/form/fields/DateFieldRender.js +155 -0
  470. package/src/ui/components/form/fields/EmailFieldRender.js +5 -0
  471. package/src/ui/components/form/fields/FieldRender.js +118 -0
  472. package/src/ui/components/form/fields/FileFieldRender.js +41 -0
  473. package/src/ui/components/form/fields/HiddenFieldRender.js +13 -0
  474. package/src/ui/components/form/fields/ImageFieldRender.js +0 -0
  475. package/src/ui/components/form/fields/NumberFieldRender.js +52 -0
  476. package/src/ui/components/form/fields/PasswordFieldRender.js +65 -0
  477. package/src/ui/components/form/fields/RadioFieldRender.js +77 -0
  478. package/src/ui/components/form/fields/RangeFieldRender.js +122 -0
  479. package/src/ui/components/form/fields/SelectFieldRender.js +248 -0
  480. package/src/ui/components/form/fields/SliderFieldRender.js +359 -0
  481. package/src/ui/components/form/fields/StringFieldRender.js +6 -0
  482. package/src/ui/components/form/fields/TelFieldRender.js +6 -0
  483. package/src/ui/components/form/fields/TextAreaFieldRender.js +96 -0
  484. package/src/ui/components/form/fields/TimeFieldRender.js +142 -0
  485. package/src/ui/components/form/fields/UrlFieldRender.js +6 -0
  486. package/src/ui/components/form/fields/date-field.css +32 -0
  487. package/src/ui/components/form/fields/field.css +402 -0
  488. package/src/ui/components/form/fields/file-field.css +79 -0
  489. package/src/ui/components/form/fields/password-field.css +50 -0
  490. package/src/ui/components/form/fields/range-field.css +120 -0
  491. package/src/ui/components/form/fields/slider.css +195 -0
  492. package/src/ui/components/form/file-upload-mode/FileAvatarModeRender.js +143 -0
  493. package/src/ui/components/form/file-upload-mode/FileDropzoneModeRender.js +108 -0
  494. package/src/ui/components/form/file-upload-mode/FileNativeModeRender.js +22 -0
  495. package/src/ui/components/form/file-upload-mode/FileUploadButtonModeRender.js +89 -0
  496. package/src/ui/components/form/file-upload-mode/FileWallModeRender.js +90 -0
  497. package/src/ui/components/form/file-upload-mode/file-avatar-mode.css +139 -0
  498. package/src/ui/components/form/file-upload-mode/file-dropzone-mode.css +88 -0
  499. package/src/ui/components/form/file-upload-mode/file-upload-button-mode.css +44 -0
  500. package/src/ui/components/form/file-upload-mode/file-wall-mode.css +88 -0
  501. package/src/ui/components/form/form-control.css +40 -0
  502. package/src/ui/components/form/helpers.js +111 -0
  503. package/src/ui/components/form/index.js +27 -0
  504. package/src/ui/components/list/ListRender.js +18 -0
  505. package/src/ui/components/list/divider/ListDividerRender.js +10 -0
  506. package/src/ui/components/list/divider/list-divider.css +12 -0
  507. package/src/ui/components/list/group/ListGroupRender.js +61 -0
  508. package/src/ui/components/list/group/list-group.css +62 -0
  509. package/src/ui/components/list/item/ListItemRender.js +238 -0
  510. package/src/ui/components/list/item/list-item.css +191 -0
  511. package/src/ui/components/list/list.css +24 -0
  512. package/src/ui/components/menu/MenuDividerRender.js +12 -0
  513. package/src/ui/components/menu/MenuGroupRender.js +59 -0
  514. package/src/ui/components/menu/MenuItemRender.js +57 -0
  515. package/src/ui/components/menu/MenuLinkRender.js +55 -0
  516. package/src/ui/components/menu/MenuRender.js +22 -0
  517. package/src/ui/components/menu/helpers.js +121 -0
  518. package/src/ui/components/menu/menu.css +308 -0
  519. package/src/ui/components/modal/ModalRender.js +118 -0
  520. package/src/ui/components/modal/modal.css +156 -0
  521. package/src/ui/components/pagination/PaginationRender.js +112 -0
  522. package/src/ui/components/pagination/pagination.css +63 -0
  523. package/src/ui/components/popover/PopoverRender.js +233 -0
  524. package/src/ui/components/popover/popover.css +139 -0
  525. package/src/ui/components/progress/ProgressRender.js +168 -0
  526. package/src/ui/components/progress/progress.css +197 -0
  527. package/src/ui/components/skeleton/SkeletonRender.js +136 -0
  528. package/src/ui/components/skeleton/skeleton.css +154 -0
  529. package/src/ui/components/spacer/SpacerRender.js +10 -0
  530. package/src/ui/components/spinner/SpinnerRender.js +47 -0
  531. package/src/ui/components/spinner/spinner.css +152 -0
  532. package/src/ui/components/splitter/SplitterGutterRender.js +94 -0
  533. package/src/ui/components/splitter/SplitterPanelRender.js +38 -0
  534. package/src/ui/components/splitter/SplitterRender.js +75 -0
  535. package/src/ui/components/splitter/splitter.css +128 -0
  536. package/src/ui/components/stacks/PositionStackRender.js +39 -0
  537. package/src/ui/components/stacks/StackRender.js +41 -0
  538. package/src/ui/components/stacks/absolute-stack/AbsoluteStackRender.js +5 -0
  539. package/src/ui/components/stacks/fixed-stack/FixedStackRender.js +5 -0
  540. package/src/ui/components/stacks/h-stack/HStackRender.js +7 -0
  541. package/src/ui/components/stacks/h-stack/h-stack.css +4 -0
  542. package/src/ui/components/stacks/index.js +5 -0
  543. package/src/ui/components/stacks/position-stack.css +62 -0
  544. package/src/ui/components/stacks/relative-stack/RelativeStackRender.js +7 -0
  545. package/src/ui/components/stacks/relative-stack/relative-stack.css +3 -0
  546. package/src/ui/components/stacks/stack.css +78 -0
  547. package/src/ui/components/stacks/v-stack/VStackRender.js +6 -0
  548. package/src/ui/components/stacks/v-stack/v-stack.css +4 -0
  549. package/src/ui/components/stepper/StepperRender.js +71 -0
  550. package/src/ui/components/stepper/StepperStepRender.js +67 -0
  551. package/src/ui/components/stepper/stepper.css +359 -0
  552. package/src/ui/components/switch/SwitchRender.js +83 -0
  553. package/src/ui/components/switch/switch.css +143 -0
  554. package/src/ui/components/table/data-table/DataTableRender.js +50 -0
  555. package/src/ui/components/table/data-table/bulk-actions.js +34 -0
  556. package/src/ui/components/table/data-table/data-table.css +246 -0
  557. package/src/ui/components/table/data-table/pagination.js +56 -0
  558. package/src/ui/components/table/data-table/tables.js +368 -0
  559. package/src/ui/components/table/data-table/toolbar.js +67 -0
  560. package/src/ui/components/table/simple-table/SimpleTableRender.js +203 -0
  561. package/src/ui/components/table/simple-table/simple-table.css +50 -0
  562. package/src/ui/components/tabs/TabsRender.js +226 -0
  563. package/src/ui/components/tabs/tabs.css +253 -0
  564. package/src/ui/components/toast/ToastRender.js +99 -0
  565. package/src/ui/components/toast/toast.css +201 -0
  566. package/src/ui/components/tooltip/TooltipRender.js +8 -0
  567. package/src/ui/components/tooltip/tooltip.css +113 -0
  568. package/src/ui/index.js +47 -0
  569. package/src/ui/theme.js +0 -0
  570. package/src/ui/theme.scss +1 -0
  571. package/src/ui/tokens/animation.scss +36 -0
  572. package/src/ui/tokens/colors-dark.scss +58 -0
  573. package/src/ui/tokens/colors.scss +54 -0
  574. package/src/ui/tokens/components.scss +32 -0
  575. package/src/ui/tokens/fonts.scss +57 -0
  576. package/src/ui/tokens/glass.scss +10 -0
  577. package/src/ui/tokens/index.scss +38 -0
  578. package/src/ui/tokens/layouts.scss +228 -0
  579. package/src/ui/tokens/opacity.scss +21 -0
  580. package/src/ui/tokens/others.scss +11 -0
  581. package/src/ui/tokens/radius.scss +6 -0
  582. package/src/ui/tokens/reset.scss +51 -0
  583. package/src/ui/tokens/shadows.scss +29 -0
  584. package/src/ui/tokens/spacings.scss +13 -0
  585. package/src/ui/tokens/vars.scss +35 -0
  586. package/src/ui/tokens/viewports.scss +30 -0
  587. package/types/args-types.d.ts +58 -0
  588. package/types/control-flow.d.ts +62 -0
  589. package/types/elements.d.ts +231 -0
  590. package/types/filters/dates.d.ts +43 -0
  591. package/types/filters/index.d.ts +4 -0
  592. package/types/filters/standard.d.ts +70 -0
  593. package/types/filters/strings.d.ts +21 -0
  594. package/types/filters/types.d.ts +20 -0
  595. package/types/forms.d.ts +84 -0
  596. package/types/globals.d.ts +543 -0
  597. package/types/images.d.ts +23 -0
  598. package/types/localStorage.ts +102 -0
  599. package/types/memoize.d.ts +26 -0
  600. package/types/native-fetch.d.ts +72 -0
  601. package/types/nd-element.d.ts +407 -0
  602. package/types/observable-resource.d.ts +3 -0
  603. package/types/observable.d.ts +227 -0
  604. package/types/plugins-manager.d.ts +65 -0
  605. package/types/polyfill.d.ts +18 -0
  606. package/types/property-accumulator.d.ts +33 -0
  607. package/types/router.d.ts +85 -0
  608. package/types/service.d.ts +23 -0
  609. package/types/singleton.d.ts +19 -0
  610. package/types/store.d.ts +63 -0
  611. package/types/template-cloner.ts +43 -0
  612. package/types/validator.ts +66 -0
  613. package/ui.js +1 -0
  614. package/utils.d.ts +4 -0
  615. package/utils.js +12 -0
  616. package/src/data/Observable.js +0 -55
  617. package/src/data/ObservableChecker.js +0 -39
  618. package/src/data/ObservableItem.js +0 -195
  619. package/src/data/Store.js +0 -74
  620. package/src/data/observable-helpers/array.js +0 -74
  621. package/src/data/observable-helpers/batch.js +0 -22
  622. package/src/data/observable-helpers/computed.js +0 -28
  623. package/src/data/observable-helpers/object.js +0 -111
  624. package/src/elements/anchor.js +0 -129
  625. package/src/elements/content-formatter.js +0 -32
  626. package/src/elements/control/for-each-array.js +0 -280
  627. package/src/elements/control/show-if.js +0 -79
  628. package/src/elements/control/switch.js +0 -98
  629. package/src/elements/description-list.js +0 -5
  630. package/src/elements/form.js +0 -71
  631. package/src/elements/html5-semantics.js +0 -12
  632. package/src/elements/img.js +0 -45
  633. package/src/elements/interactive.js +0 -7
  634. package/src/elements/list.js +0 -10
  635. package/src/elements/medias.js +0 -8
  636. package/src/elements/meta-data.js +0 -9
  637. package/src/elements/table.js +0 -14
  638. package/src/utils/args-types.js +0 -100
  639. package/src/utils/debug-manager.js +0 -31
  640. package/src/utils/helpers.js +0 -60
  641. package/src/utils/plugins-manager.js +0 -12
  642. package/src/utils/prototypes.js +0 -45
  643. package/src/wrappers/AttributesWrapper.js +0 -144
  644. package/src/wrappers/DocumentObserver.js +0 -80
  645. package/src/wrappers/ElementCreator.js +0 -114
  646. package/src/wrappers/HtmlElementEventsWrapper.js +0 -64
  647. package/src/wrappers/HtmlElementWrapper.js +0 -50
  648. package/src/wrappers/NdPrototype.js +0 -109
  649. package/src/wrappers/constants.js +0 -2
@@ -0,0 +1,274 @@
1
+ import ObservableItem from './ObservableItem';
2
+ import Validator from '../utils/validator';
3
+ import {nextTick} from '../utils/helpers';
4
+ import ObservableArray from './ObservableArray';
5
+
6
+ /**
7
+ * Reactive object container extending ObservableItem.
8
+ * Each property of the target object becomes an individual ObservableItem (or ObservableArray/ObservableObject for nested structures).
9
+ * Use Observable.object() or Observable.init() rather than instantiating directly.
10
+ *
11
+ * @constructor
12
+ * @param {Record<string, *>} target - Plain object to make reactive
13
+ * @param {{ deep?: boolean, reset?: boolean, propagation?: boolean }|null} [configs] - Configuration
14
+ * @param {boolean} [configs.deep] - If false, nested objects and arrays are not wrapped recursively (default: true)
15
+ * @example
16
+ * const user = Observable.object({ name: 'John', age: 25 });
17
+ * user.name.$value = 'Jane'; // triggers reactivity on name only
18
+ */
19
+ export const ObservableObject = function(target, configs) {
20
+ ObservableItem.call(this, target);
21
+ this.$observables = {};
22
+ this.configs = configs;
23
+
24
+ for(const key in target) {
25
+ if(!Object.hasOwn(this, key)) {
26
+ Object.defineProperty(this, key, {
27
+ get: () => this.$observables[key],
28
+ set: (value) => {
29
+ this.$observables[key].set(value);
30
+ },
31
+ configurable: true,
32
+ enumerable: true,
33
+ });
34
+ }
35
+ }
36
+
37
+ this.$load(target);
38
+
39
+ Object.defineProperty(this, '$currentValue', {
40
+ get: function() {
41
+ return this.val();
42
+ },
43
+ set(value) {
44
+ this.set(value);
45
+ }
46
+ });
47
+ };
48
+
49
+ ObservableObject.prototype = Object.create(ObservableItem.prototype);
50
+
51
+ Object.defineProperty(ObservableObject, '$value', {
52
+ get() {
53
+ return this.val();
54
+ },
55
+ set(value) {
56
+ this.set(value);
57
+ },
58
+ });
59
+
60
+ ObservableObject.prototype.__$isObservableObject = true;
61
+ ObservableObject.prototype.__isProxy__ = true;
62
+
63
+ /**
64
+ * Initialises (or reinitialize) the internal observables map from a plain object.
65
+ * Called automatically in the constructor.
66
+ *
67
+ * @internal
68
+ * @param {Record<string, *>} initialValue - Object whose properties are turned into observables
69
+ */
70
+ ObservableObject.prototype.$load = function(initialValue) {
71
+ const configs = this.configs;
72
+ for(const key in initialValue) {
73
+ const itemValue = initialValue[key];
74
+ if(Array.isArray(itemValue)) {
75
+ if(configs?.deep !== false) {
76
+ const mappedItemValue = itemValue.map(item => {
77
+ if(Validator.isJson(item)) {
78
+ return new ObservableObject(item, configs);
79
+ }
80
+ if(Validator.isArray(item)) {
81
+ return new ObservableArray(item, configs);
82
+ }
83
+ return new ObservableItem(item, configs);
84
+ });
85
+ this.$observables[key] = new ObservableArray(mappedItemValue, configs);
86
+ continue;
87
+ }
88
+ this.$observables[key] = new ObservableArray(itemValue, configs);
89
+ continue;
90
+ }
91
+ if(itemValue?.__$Observable) {
92
+ this.$observables[key] = itemValue;
93
+ continue;
94
+ }
95
+ this.$observables[key] = (Validator.isJson(itemValue)) ? new ObservableObject(itemValue, configs) : new ObservableItem(itemValue, configs);
96
+ }
97
+ };
98
+
99
+ /**
100
+ * Returns a plain snapshot of all observable values.
101
+ * Unwraps nested ObservableItem, ObservableArray, and ObservableObject recursively.
102
+ * Alias: $val()
103
+ *
104
+ * @returns {Record<string, *>} Plain object with current values
105
+ * @example
106
+ * const user = Observable.object({ name: 'John', age: 25 });
107
+ * user.val(); // { name: 'John', age: 25 }
108
+ */
109
+ ObservableObject.prototype.val = function() {
110
+ const result = {};
111
+ for(const key in this.$observables) {
112
+ const dataItem = this.$observables[key];
113
+ if(dataItem?.__$Observable) {
114
+ let value = dataItem.val();
115
+ if(Array.isArray(value)) {
116
+ value = value.map(item => {
117
+ if(item.__$Observable) {
118
+ return item.val();
119
+ }
120
+ return item;
121
+ });
122
+ }
123
+ result[key] = value;
124
+ } else {
125
+ result[key] = dataItem;
126
+ }
127
+ }
128
+ return result;
129
+ };
130
+ ObservableObject.prototype.$val = ObservableObject.prototype.val;
131
+
132
+ /**
133
+ * Returns the current value of a single property, unwrapped from its observable.
134
+ * Alias: $get(property)
135
+ *
136
+ * @param {string} property - Property name
137
+ * @returns {*} The current value of that property
138
+ * @example
139
+ * const user = Observable.object({ name: 'John' });
140
+ * user.get('name'); // 'John'
141
+ */
142
+ ObservableObject.prototype.get = function(property) {
143
+ const item = this.$observables[property];
144
+ if(item?.__$Observable) {
145
+ return item.val();
146
+ }
147
+ return item;
148
+ };
149
+ ObservableObject.prototype.$get = ObservableObject.prototype.get;
150
+
151
+ /**
152
+ * Updates one or more properties with new values.
153
+ * Supports partial updates — only provided keys are changed.
154
+ * Aliases: $set(newData), $updateWith(newData), update(newData)
155
+ *
156
+ * @param {Partial<Record<string, *>>} newData - Object with properties to update
157
+ * @example
158
+ * const user = Observable.object({ name: 'John', age: 25 });
159
+ * user.set({ name: 'Jane' }); // Only name changes, age stays 25
160
+ */
161
+ ObservableObject.prototype.set = function(newData) {
162
+ const data = newData?.__$Observable ? newData.$value : newData;
163
+ const configs = this.configs;
164
+
165
+ for(const key in data) {
166
+ const targetItem = this.$observables[key];
167
+ const newValueOrigin = newData[key];
168
+ const newValue = data[key];
169
+
170
+ if(targetItem?.__$Observable) {
171
+ if(targetItem.__$isObservableObject) {
172
+ targetItem.update(newValue);
173
+ continue;
174
+ }
175
+ if(!Validator.isArray(newValue)) {
176
+ targetItem.set(newValue);
177
+ continue;
178
+ }
179
+ const firstElementFromOriginalValue = newValueOrigin.at(0);
180
+ if(firstElementFromOriginalValue?.__$Observable) {
181
+ const newValues = newValue.map(item => {
182
+ if(firstElementFromOriginalValue.__$isObservableObject) {
183
+ return new ObservableObject(item, configs);
184
+ }
185
+ return ObservableItem(item, configs);
186
+ });
187
+ targetItem.set(newValues);
188
+ continue;
189
+ }
190
+ targetItem.set([...newValue]);
191
+ continue;
192
+ }
193
+ this[key] = newValue;
194
+ }
195
+ };
196
+ ObservableObject.prototype.$set = ObservableObject.prototype.set;
197
+ ObservableObject.prototype.$updateWith = ObservableObject.prototype.set;
198
+
199
+ /**
200
+ * Returns an array of all internal observable instances (one per property).
201
+ * Alias: $observables()
202
+ *
203
+ * @returns {ObservableItem[]} Array of observable instances
204
+ */
205
+ ObservableObject.prototype.observables = function() {
206
+ return Object.values(this.$observables);
207
+ };
208
+ ObservableObject.prototype.$observables = ObservableObject.prototype.observables;
209
+
210
+ /**
211
+ * Returns all property names of the observable object.
212
+ * Alias: $keys()
213
+ *
214
+ * @returns {string[]} Array of property names
215
+ */
216
+ ObservableObject.prototype.keys = function() {
217
+ return Object.keys(this.$observables);
218
+ };
219
+ ObservableObject.prototype.$keys = ObservableObject.prototype.keys;
220
+
221
+ /**
222
+ * Creates a new ObservableObject with a snapshot of the current values.
223
+ * Changes to the clone do not affect the original.
224
+ * Alias: $clone()
225
+ *
226
+ * @returns {ObservableObject} New independent ObservableObject with the same structure and values
227
+ */
228
+ ObservableObject.prototype.clone = function() {
229
+ return new ObservableObject(this.val(), this.configs);
230
+ };
231
+ ObservableObject.prototype.$clone = ObservableObject.prototype.clone;
232
+
233
+ /**
234
+ * Resets all properties to their initial values by calling .reset() on each child observable.
235
+ * Only works if observables were created with { reset: true }.
236
+ */
237
+ ObservableObject.prototype.reset = function() {
238
+ for(const key in this.$observables) {
239
+ this.$observables[key].reset();
240
+ }
241
+ };
242
+ ObservableObject.prototype.originalSubscribe = ObservableObject.prototype.subscribe;
243
+
244
+ /**
245
+ * Subscribes to changes across all nested observables.
246
+ * The callback is called whenever any property (or nested value) changes.
247
+ * Internally uses debouncing (nextTick) to batch multiple simultaneous changes.
248
+ *
249
+ * @param {(value: Record<string, *>) => void} callback - Called on any nested change
250
+ * @example
251
+ * const user = Observable.object({ name: 'John', age: 25 });
252
+ * user.subscribe(() => console.log('user changed:', user.val()));
253
+ * user.name.$value = 'Jane'; // logs 'user changed: { name: "Jane", age: 25 }'
254
+ */
255
+ ObservableObject.prototype.subscribe = function(callback) {
256
+ const observables = this.observables();
257
+ const updatedValue = nextTick(() => this.trigger());
258
+
259
+ this.originalSubscribe(callback);
260
+
261
+ for (let i = 0, length = observables.length; i < length; i++) {
262
+ const observable = observables[i];
263
+ if (observable.__$isObservableArray) {
264
+ observable.deepSubscribe(updatedValue);
265
+ continue;
266
+ }
267
+ observable.subscribe(updatedValue);
268
+ }
269
+ };
270
+ ObservableObject.prototype.configs = function() {
271
+ return this.configs;
272
+ };
273
+
274
+ ObservableObject.prototype.update = ObservableObject.prototype.set;
@@ -0,0 +1,315 @@
1
+ import ObservableItem from './ObservableItem';
2
+ import {debounce} from '../utils/helpers';
3
+
4
+ const STATE = {
5
+ UNRESOLVED: 'unresolved',
6
+ PENDING: 'pending',
7
+ READY: 'ready',
8
+ REFRESHING: 'refreshing',
9
+ ERRORED: 'errored',
10
+ };
11
+
12
+ /**
13
+ * Reactive async data fetcher with built-in state management.
14
+ * Tracks loading, ready, refreshing, and error states automatically.
15
+ * Use Observable.resource() rather than instantiating directly.
16
+ *
17
+ * @constructor
18
+ * @param {(...depValues: any[], signal?: AbortSignal) => Promise<*>} fn - Async function to fetch data. Receives dependency values as arguments. If its arity exceeds the number of dependencies, an AbortSignal is passed as the last argument.
19
+ * @param {ObservableItem[]} deps - Observable dependencies — resource re-fetches when any changes
20
+ * @param {{ auto?: boolean, lazy?: boolean, debounce?: number, into?: ObservableItem, apply?: Function }} config - Configuration
21
+ * @param {boolean} [config.auto=false] - If true, fetch runs automatically on creation (or when deps change)
22
+ * @param {boolean} [config.lazy=false] - If true with deps, does not fetch immediately — waits for first dep change
23
+ * @param {number} [config.debounce=0] - Debounce delay in ms for dependency-triggered re-fetches
24
+ * @param {ObservableItem} [config.into] - Observable to write results into instead of creating a new one
25
+ * @param {Function} [config.apply] - Custom function to apply the result to this.data
26
+ * @example
27
+ * const userId = Observable(1);
28
+ * const user = Observable.resource(
29
+ * async (id, signal) => fetch(`/api/users/${id}`, { signal }).then(r => r.json()),
30
+ * [userId],
31
+ * { auto: true }
32
+ * );
33
+ */
34
+ export default function ObservableResource(fn, deps, config) {
35
+ this.$fn = (config.debounce > 0) ? debounce(fn, config.debounce) : fn;
36
+ this.$dependencies = deps;
37
+ this.$config = config;
38
+ this.$controller = null;
39
+ this.$subscriptions = [];
40
+
41
+ this.data = config.into ?? new ObservableItem(null);
42
+ this.error = new ObservableItem(null);
43
+ this.state = new ObservableItem(STATE.UNRESOLVED);
44
+
45
+ this.loading = ObservableItem.computed(
46
+ (state) => state === STATE.PENDING || state === STATE.REFRESHING,
47
+ [this.state],
48
+ );
49
+
50
+ if (config.auto) {
51
+ if (deps.length > 0) {
52
+ this.$watchDependencies();
53
+ return;
54
+ }
55
+ this.fetch();
56
+ }
57
+ }
58
+
59
+ ObservableResource.prototype.$applyResult = function(result) {
60
+ if(this.$config.apply) {
61
+ this.$config.apply(result, this.data);
62
+ return;
63
+ }
64
+ this.data.set(result);
65
+ };
66
+
67
+ ObservableResource.prototype.$abort = function() {
68
+ if (this.$controller) {
69
+ this.$controller.abort();
70
+ this.$controller = null;
71
+ }
72
+ };
73
+
74
+ ObservableResource.prototype.$runWithAbortController = function(isRefetch = false) {
75
+ this.$abort();
76
+
77
+ this.$controller = new AbortController();
78
+ const signal = this.$controller.signal;
79
+
80
+ const hasData = this.data.val() !== null;
81
+ const nextState = isRefetch && hasData ? STATE.REFRESHING : STATE.PENDING;
82
+
83
+ this.error.set(null);
84
+ this.state.set(nextState);
85
+
86
+ const depValues = this.$dependencies.map(dep => dep.val());
87
+ const args = [...depValues, signal];
88
+
89
+ Promise.resolve(this.$fn(...args))
90
+ .then(result => {
91
+ if (signal.aborted) {
92
+ return;
93
+ }
94
+ this.$applyResult(result);
95
+ this.error.set(null);
96
+ this.state.set(STATE.READY);
97
+ this.$controller = null;
98
+ })
99
+ .catch(err => {
100
+ if (signal.aborted) {
101
+ return;
102
+ }
103
+ this.error.set(err);
104
+ this.state.set(STATE.ERRORED);
105
+ this.$controller = null;
106
+ });
107
+ };
108
+ ObservableResource.prototype.$runWithoutAbortController = function(isRefetch = false) {
109
+ const hasData = this.data.val() !== null;
110
+ const nextState = isRefetch && hasData ? STATE.REFRESHING : STATE.PENDING;
111
+
112
+ this.error.set(null);
113
+ this.state.set(nextState);
114
+
115
+ const args = this.$dependencies.map(dep => dep.val());
116
+
117
+ Promise.resolve(this.$fn(...args))
118
+ .then(result => {
119
+ this.$applyResult(result);
120
+ this.error.set(null);
121
+ this.state.set(STATE.READY);
122
+ })
123
+ .catch(err => {
124
+ this.error.set(err);
125
+ this.state.set(STATE.ERRORED);
126
+ });
127
+ };
128
+
129
+ ObservableResource.prototype.into = function($observable) {
130
+ this.data = $observable;
131
+ return this;
132
+ };
133
+
134
+ ObservableResource.prototype.$run = function(isRefetch = false) {
135
+ const needsSignal = this.$fn.length > this.$dependencies.length;
136
+ if(needsSignal) {
137
+ this.$run = this.$runWithAbortController;
138
+ return this.$runWithAbortController(isRefetch);
139
+ }
140
+ this.$run = this.$runWithoutAbortController;
141
+
142
+ return this.$run(isRefetch);
143
+ };
144
+
145
+ ObservableResource.prototype.$watchDependencies = function() {
146
+ this.$subscriptions.forEach(unsub => unsub());
147
+ this.$subscriptions = [];
148
+
149
+ this.$dependencies.forEach(dep => {
150
+ const callback = () => this.$run(true);
151
+ dep.subscribe(callback);
152
+ this.$subscriptions.push(() => dep.unsubscribe(callback));
153
+ });
154
+ if (!this.$config.lazy) {
155
+ this.$run(false);
156
+ }
157
+ };
158
+
159
+ /**
160
+ * Sets a custom function to apply fetched results to this.data.
161
+ * Useful when the raw response needs transformation before storing.
162
+ *
163
+ * @param {(result: *, data: ObservableItem) => void} fn - Function receiving the result and the data observable
164
+ * @returns {this}
165
+ * @example
166
+ * resource.apply((result, data) => data.set(result.items));
167
+ */
168
+ ObservableResource.prototype.apply = function(fn) {
169
+ this.$config.apply = fn;
170
+ return this;
171
+ };
172
+
173
+ /**
174
+ * Redirects fetched results into an existing ObservableItem instead of the default internal one.
175
+ * Updates both this.data reference and config.into.
176
+ *
177
+ * @param {ObservableItem} $observable - Target observable to write results into
178
+ * @returns {this}
179
+ * @example
180
+ * const items = Observable([]);
181
+ * resource.into(items);
182
+ */
183
+ ObservableResource.prototype.into = function($observable) {
184
+ this.$config.into = $observable;
185
+ this.data = $observable;
186
+ return this;
187
+ };
188
+
189
+ /**
190
+ * Triggers a fresh fetch (state transitions to 'pending').
191
+ * Use when no prior data exists or when a full reload is needed.
192
+ *
193
+ * @returns {this}
194
+ */
195
+ ObservableResource.prototype.fetch = function() {
196
+ this.$run(false);
197
+ return this;
198
+ };
199
+
200
+ /**
201
+ * Triggers a re-fetch (state transitions to 'refreshing' if data already exists).
202
+ * Use when you want to reload while keeping the previous data visible.
203
+ *
204
+ * @returns {this}
205
+ */
206
+ ObservableResource.prototype.refetch = function() {
207
+ this.$run(true);
208
+ return this;
209
+ };
210
+
211
+ /**
212
+ * Manually sets the data value and marks the state as 'ready'.
213
+ * Useful for optimistic updates or seeding initial data without a network call.
214
+ *
215
+ * @param {*} value - New value to set on this.data
216
+ * @returns {this}
217
+ * @example
218
+ * resource.mutate([...resource.data.val(), newItem]);
219
+ */
220
+ ObservableResource.prototype.mutate = function(value) {
221
+ this.data.set(value);
222
+ this.state.set(STATE.READY);
223
+ return this;
224
+ };
225
+
226
+ /**
227
+ * Cancels any pending request, unsubscribes from all dependencies, and clears subscriptions.
228
+ * Call this when the component using this resource is unmounted.
229
+ *
230
+ * @returns {void}
231
+ */
232
+ ObservableResource.prototype.destroy = function() {
233
+ this.$abort();
234
+ this.$subscriptions.forEach(unsub => unsub());
235
+ this.$subscriptions = [];
236
+ };
237
+
238
+ /**
239
+ * Returns a derived observable that emits true when the state is 'ready'.
240
+ *
241
+ * @returns {ObservableChecker<boolean>}
242
+ */
243
+ ObservableResource.prototype.isReady = function() {
244
+ return this.state.isEqualTo(STATE.READY);
245
+ };
246
+
247
+ /**
248
+ * Returns a derived observable that emits true when the state is 'pending' (initial load).
249
+ *
250
+ * @returns {ObservableChecker<boolean>}
251
+ */
252
+ ObservableResource.prototype.isPending = function() {
253
+ return this.state.isEqualTo(STATE.PENDING);
254
+ };
255
+
256
+ /**
257
+ * Returns a derived observable that emits true when the state is 'refreshing' (reload with existing data).
258
+ *
259
+ * @returns {ObservableChecker<boolean>}
260
+ */
261
+ ObservableResource.prototype.isRefreshing = function() {
262
+ return this.state.isEqualTo(STATE.REFRESHING);
263
+ };
264
+
265
+ /**
266
+ * Returns a derived observable that emits true when the state is 'errored'.
267
+ *
268
+ * @returns {ObservableChecker<boolean>}
269
+ */
270
+ ObservableResource.prototype.isErrored = function() {
271
+ return this.state.isEqualTo(STATE.ERRORED);
272
+ };
273
+
274
+ /**
275
+ * Returns a derived observable that emits true when no fetch has been triggered yet.
276
+ *
277
+ * @returns {ObservableChecker<boolean>}
278
+ */
279
+ ObservableResource.prototype.isUnresolved = function() {
280
+ return this.state.isEqualTo(STATE.UNRESOLVED);
281
+ };
282
+
283
+ /**
284
+ * Registers a callback that is called every time a fetch completes successfully.
285
+ *
286
+ * @param {(value: *) => void} callback - Called with the fetched data value
287
+ * @returns {this}
288
+ * @example
289
+ * resource.onSuccess((data) => console.log('Loaded:', data));
290
+ */
291
+ ObservableResource.prototype.onSuccess = function(callback) {
292
+ this.data.subscribe((value) => {
293
+ if (this.state.val() === STATE.READY) {
294
+ callback(value);
295
+ }
296
+ });
297
+ return this;
298
+ };
299
+
300
+ /**
301
+ * Registers a callback called every time a fetch fails.
302
+ *
303
+ * @param {(error: Error) => void} callback - Called with the error object
304
+ * @returns {this}
305
+ * @example
306
+ * resource.onError((err) => console.error('Failed:', err.message));
307
+ */
308
+ ObservableResource.prototype.onError = function(callback) {
309
+ this.error.subscribe((err) => {
310
+ if (err !== null) {
311
+ callback(err);
312
+ }
313
+ });
314
+ return this;
315
+ };
@@ -0,0 +1,54 @@
1
+
2
+ /**
3
+ * Creates an ObservableWhen that tracks whether an observable equals a specific value.
4
+ *
5
+ * @param {ObservableItem} observer - The observable to watch
6
+ * @param {*} value - The value to compare against
7
+ * @class ObservableWhen
8
+ */
9
+ export const ObservableWhen = function(observer, value) {
10
+ this.$target = value;
11
+ this.$observer = observer;
12
+ };
13
+
14
+ ObservableWhen.prototype.__$Observable = true;
15
+ ObservableWhen.prototype.__$isObservableWhen = true;
16
+
17
+ /**
18
+ * Subscribes to changes in the match status (true when observable equals target value).
19
+ *
20
+ * @param {Function} callback - Function called with boolean indicating if values match
21
+ * @returns {Function} Unsubscribe function
22
+ * @example
23
+ * const status = Observable('idle');
24
+ * const isLoading = status.when('loading');
25
+ * isLoading.subscribe(active => console.log('Loading:', active));
26
+ */
27
+ ObservableWhen.prototype.subscribe = function(callback) {
28
+ return this.$observer.on(this.$target, callback);
29
+ };
30
+
31
+ /**
32
+ * Returns true if the observable's current value equals the target value.
33
+ *
34
+ * @returns {boolean} True if observable value matches target value
35
+ */
36
+ ObservableWhen.prototype.val = function() {
37
+ return this.$observer.$currentValue === this.$target;
38
+ };
39
+
40
+ /**
41
+ * Returns true if the observable's current value equals the target value.
42
+ * Alias for val().
43
+ *
44
+ * @returns {boolean} True if observable value matches target value
45
+ */
46
+ ObservableWhen.prototype.isMatch = ObservableWhen.prototype.val;
47
+
48
+ /**
49
+ * Returns true if the observable's current value equals the target value.
50
+ * Alias for val().
51
+ *
52
+ * @returns {boolean} True if observable value matches target value
53
+ */
54
+ ObservableWhen.prototype.isActive = ObservableWhen.prototype.val;