neo.mjs 10.0.0-beta.5 → 10.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/RELEASE_NOTES/v10.0.0-beta.1.md +20 -0
- package/.github/RELEASE_NOTES/v10.0.0-beta.2.md +73 -0
- package/.github/RELEASE_NOTES/v10.0.0-beta.3.md +39 -0
- package/.github/RELEASE_NOTES/v10.0.0-beta.5.md +70 -0
- package/.github/RELEASE_NOTES/v10.0.0-beta.6.md +48 -0
- package/.github/RELEASE_NOTES/v10.0.0.md +52 -0
- package/.github/epic-functional-components.md +498 -0
- package/.github/ticket-asymmetric-vdom-updates.md +122 -0
- package/README.md +0 -3
- package/ServiceWorker.mjs +2 -2
- package/apps/colors/store/Colors.mjs +1 -0
- package/apps/colors/view/GridContainer.mjs +3 -0
- package/apps/colors/view/HeaderToolbar.mjs +2 -0
- package/apps/colors/view/Viewport.mjs +3 -0
- package/apps/covid/view/FooterContainer.mjs +3 -0
- package/apps/covid/view/GalleryContainer.mjs +2 -0
- package/apps/covid/view/GalleryContainerController.mjs +1 -0
- package/apps/covid/view/HeaderContainer.mjs +2 -0
- package/apps/covid/view/HelixContainer.mjs +2 -0
- package/apps/covid/view/HelixContainerController.mjs +1 -0
- package/apps/covid/view/MainContainer.mjs +3 -0
- package/apps/covid/view/TableContainer.mjs +3 -0
- package/apps/covid/view/TableContainerController.mjs +1 -0
- package/apps/covid/view/WorldMapContainer.mjs +2 -0
- package/apps/covid/view/country/Gallery.mjs +3 -0
- package/apps/covid/view/country/Helix.mjs +8 -0
- package/apps/covid/view/country/HistoricalDataTable.mjs +1 -0
- package/apps/covid/view/country/Table.mjs +2 -0
- package/apps/covid/view/mapboxGl/Component.mjs +1 -0
- package/apps/covid/view/mapboxGl/Container.mjs +2 -0
- package/apps/email/EPIC_PLAN.md +58 -0
- package/apps/email/neo-config.json +2 -2
- package/apps/email/store/Emails.mjs +11 -1
- package/apps/email/view/ComposeView.mjs +44 -0
- package/apps/email/view/MainView.mjs +89 -0
- package/apps/email/view/Viewport.mjs +4 -33
- package/apps/email/view/ViewportStateProvider.mjs +3 -3
- package/apps/form/store/SideNav.mjs +1 -0
- package/apps/form/view/FormContainer.mjs +1 -0
- package/apps/form/view/FormPageContainer.mjs +2 -0
- package/apps/form/view/SideNavList.mjs +1 -0
- package/apps/form/view/Viewport.mjs +3 -0
- package/apps/portal/childapps/preview/MainContainer.mjs +1 -0
- package/apps/portal/index.html +1 -1
- package/apps/portal/store/BlogPosts.mjs +2 -0
- package/apps/portal/store/Content.mjs +1 -0
- package/apps/portal/store/ContentSections.mjs +1 -0
- package/apps/portal/store/Examples.mjs +1 -0
- package/apps/portal/view/HeaderToolbar.mjs +1 -0
- package/apps/portal/view/Viewport.mjs +5 -0
- package/apps/portal/view/ViewportController.mjs +11 -3
- package/apps/portal/view/about/Container.mjs +2 -0
- package/apps/portal/view/about/MemberContainer.mjs +7 -0
- package/apps/portal/view/blog/Container.mjs +2 -0
- package/apps/portal/view/blog/List.mjs +2 -0
- package/apps/portal/view/examples/List.mjs +29 -19
- package/apps/portal/view/examples/TabContainer.mjs +4 -0
- package/apps/portal/view/home/ContentBox.mjs +3 -0
- package/apps/portal/view/home/FeatureSection.mjs +8 -0
- package/apps/portal/view/home/FooterContainer.mjs +4 -1
- package/apps/portal/view/home/MainContainer.mjs +2 -0
- package/apps/portal/view/home/parts/AfterMath.mjs +2 -0
- package/apps/portal/view/home/parts/BaseContainer.mjs +1 -0
- package/apps/portal/view/home/parts/Colors.mjs +4 -0
- package/apps/portal/view/home/parts/Features.mjs +2 -0
- package/apps/portal/view/home/parts/Helix.mjs +5 -0
- package/apps/portal/view/home/parts/How.mjs +4 -0
- package/apps/portal/view/home/parts/MainNeo.mjs +1 -0
- package/apps/portal/view/home/parts/References.mjs +2 -0
- package/apps/portal/view/learn/ContentComponent.mjs +11 -5
- package/apps/portal/view/learn/ContentTreeList.mjs +2 -0
- package/apps/portal/view/learn/CubeLayoutButton.mjs +1 -0
- package/apps/portal/view/learn/MainContainer.mjs +4 -0
- package/apps/portal/view/learn/PageContainer.mjs +2 -0
- package/apps/portal/view/learn/PageSectionsContainer.mjs +3 -0
- package/apps/portal/view/learn/PageSectionsList.mjs +1 -0
- package/apps/portal/view/services/Component.mjs +1 -0
- package/apps/realworld/api/Base.mjs +1 -0
- package/apps/realworld/view/HeaderComponent.mjs +4 -0
- package/apps/realworld/view/HomeComponent.mjs +7 -0
- package/apps/realworld/view/MainContainer.mjs +2 -0
- package/apps/realworld/view/MainContainerController.mjs +2 -0
- package/apps/realworld/view/article/CommentComponent.mjs +3 -0
- package/apps/realworld/view/article/Component.mjs +17 -10
- package/apps/realworld/view/article/CreateCommentComponent.mjs +2 -0
- package/apps/realworld/view/article/CreateComponent.mjs +5 -0
- package/apps/realworld/view/article/PreviewComponent.mjs +9 -0
- package/apps/realworld/view/article/TagListComponent.mjs +2 -0
- package/apps/realworld/view/user/ProfileComponent.mjs +7 -0
- package/apps/realworld/view/user/SettingsComponent.mjs +5 -0
- package/apps/realworld/view/user/SignUpComponent.mjs +3 -0
- package/apps/realworld2/api/Base.mjs +1 -0
- package/apps/realworld2/view/FooterComponent.mjs +1 -0
- package/apps/realworld2/view/HeaderToolbar.mjs +3 -0
- package/apps/realworld2/view/HomeContainer.mjs +1 -0
- package/apps/realworld2/view/MainContainer.mjs +2 -0
- package/apps/realworld2/view/MainContainerController.mjs +1 -0
- package/apps/realworld2/view/article/Helix.mjs +1 -0
- package/apps/realworld2/view/article/PreviewComponent.mjs +9 -0
- package/apps/realworld2/view/article/PreviewList.mjs +1 -0
- package/apps/realworld2/view/article/TagListComponent.mjs +2 -0
- package/apps/route/view/CenterContainer.mjs +1 -0
- package/apps/route/view/MainView.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidchart/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidgallery/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidhelix/MainContainer.mjs +1 -0
- package/apps/sharedcovid/childapps/sharedcovidmap/MainContainer.mjs +1 -0
- package/apps/sharedcovid/view/FooterContainer.mjs +3 -0
- package/apps/sharedcovid/view/GalleryContainer.mjs +2 -0
- package/apps/sharedcovid/view/GalleryContainerController.mjs +1 -0
- package/apps/sharedcovid/view/HeaderContainer.mjs +2 -0
- package/apps/sharedcovid/view/HelixContainer.mjs +2 -0
- package/apps/sharedcovid/view/HelixContainerController.mjs +1 -0
- package/apps/sharedcovid/view/MainContainer.mjs +3 -0
- package/apps/sharedcovid/view/TableContainer.mjs +3 -0
- package/apps/sharedcovid/view/TableContainerController.mjs +1 -0
- package/apps/sharedcovid/view/WorldMapContainer.mjs +2 -0
- package/apps/sharedcovid/view/country/Gallery.mjs +3 -0
- package/apps/sharedcovid/view/country/Helix.mjs +8 -0
- package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -0
- package/apps/sharedcovid/view/country/Table.mjs +2 -0
- package/apps/sharedcovid/view/mapboxGl/Component.mjs +1 -0
- package/apps/sharedcovid/view/mapboxGl/Container.mjs +2 -0
- package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +2 -0
- package/apps/shareddialog/view/DemoDialog.mjs +2 -0
- package/apps/shareddialog/view/MainContainer.mjs +2 -0
- package/apps/shareddialog/view/MainContainerController.mjs +1 -0
- package/buildScripts/addReactiveTags.mjs +191 -0
- package/buildScripts/checkReactiveTags.mjs +160 -0
- package/docs/app/store/Api.mjs +1 -0
- package/docs/app/store/Examples.mjs +1 -0
- package/docs/app/view/ApiTreeList.mjs +1 -0
- package/docs/app/view/ContentTabContainer.mjs +2 -0
- package/docs/app/view/ExamplesTreeList.mjs +2 -0
- package/docs/app/view/HeaderContainer.mjs +3 -0
- package/docs/app/view/MainContainer.mjs +5 -0
- package/docs/app/view/classdetails/HeaderComponent.mjs +1 -0
- package/docs/app/view/classdetails/MainContainer.mjs +3 -0
- package/docs/app/view/classdetails/MembersList.mjs +5 -0
- package/docs/app/view/classdetails/SourceViewComponent.mjs +2 -0
- package/examples/ConfigurationViewport.mjs +14 -8
- package/examples/calendar/weekview/MainContainer.mjs +4 -0
- package/examples/component/coronaGallery/CountryGallery.mjs +2 -0
- package/examples/component/coronaGallery/CountryStore.mjs +1 -0
- package/examples/component/coronaGallery/Viewport.mjs +3 -0
- package/examples/component/coronaGallery/ViewportController.mjs +1 -0
- package/examples/component/coronaHelix/CountryHelix.mjs +7 -0
- package/examples/component/coronaHelix/MainContainer.mjs +1 -0
- package/examples/component/gallery/ImageStore.mjs +1 -0
- package/examples/component/helix/ImageStore.mjs +1 -0
- package/examples/component/helix/Viewport.mjs +3 -0
- package/examples/component/helix/ViewportController.mjs +1 -0
- package/examples/component/multiWindowCoronaGallery/childapp/Viewport.mjs +1 -0
- package/examples/component/multiWindowHelix/childapp/Viewport.mjs +1 -0
- package/examples/component/wrapper/googleMaps/MapComponent.mjs +2 -0
- package/examples/core/config/MainContainer.mjs +2 -0
- package/examples/dialog/DemoDialog.mjs +2 -0
- package/examples/dialog/MainContainer.mjs +1 -0
- package/examples/form/field/color/MainStore.mjs +1 -0
- package/examples/functional/button/base/MainContainer.mjs +207 -0
- package/examples/functional/button/base/app.mjs +6 -0
- package/examples/functional/button/base/index.html +11 -0
- package/examples/functional/button/base/neo-config.json +6 -0
- package/examples/functional/defineComponent/Component.mjs +18 -0
- package/examples/functional/defineComponent/MainContainer.mjs +41 -0
- package/examples/functional/defineComponent/app.mjs +6 -0
- package/examples/functional/defineComponent/index.html +11 -0
- package/examples/functional/defineComponent/neo-config.json +6 -0
- package/examples/functional/hostComponent/Component.mjs +32 -0
- package/examples/functional/hostComponent/MainContainer.mjs +48 -0
- package/examples/functional/hostComponent/app.mjs +6 -0
- package/examples/functional/hostComponent/index.html +11 -0
- package/examples/functional/hostComponent/neo-config.json +6 -0
- package/examples/grid/animatedRowSorting/Viewport.mjs +1 -1
- package/examples/grid/bigData/ControlsContainer.mjs +3 -0
- package/examples/grid/bigData/GridContainer.mjs +4 -2
- package/examples/grid/bigData/MainContainer.mjs +2 -0
- package/examples/grid/bigData/MainModel.mjs +1 -0
- package/examples/grid/bigData/MainStore.mjs +3 -0
- package/examples/grid/cellEditing/MainContainer.mjs +1 -1
- package/examples/grid/container/MainContainer.mjs +1 -1
- package/examples/grid/covid/GridContainer.mjs +3 -0
- package/examples/grid/covid/MainContainer.mjs +2 -0
- package/examples/grid/covid/Store.mjs +1 -0
- package/examples/grid/nestedRecordFields/EditUserDialog.mjs +3 -0
- package/examples/grid/nestedRecordFields/Viewport.mjs +3 -1
- package/examples/list/animate/List.mjs +4 -0
- package/examples/list/animate/MainContainer.mjs +2 -0
- package/examples/list/circle/MainStore.mjs +1 -0
- package/examples/list/color/MainStore.mjs +1 -0
- package/examples/preloadingAssets/view/MainContainer.mjs +2 -0
- package/examples/stateProvider/advanced/MainContainer.mjs +1 -0
- package/examples/stateProvider/dialog/EditUserDialog.mjs +2 -0
- package/examples/stateProvider/dialog/MainContainer.mjs +1 -0
- package/examples/stateProvider/extendedClass/MainContainer.mjs +2 -0
- package/examples/stateProvider/inline/MainContainer.mjs +1 -0
- package/examples/stateProvider/inlineNoStateProvider/MainContainer.mjs +1 -0
- package/examples/stateProvider/inlineNoStateProvider/MainContainerController.mjs +2 -0
- package/examples/stateProvider/multiWindow/EditUserDialog.mjs +3 -0
- package/examples/stateProvider/multiWindow/MainContainer.mjs +1 -0
- package/examples/stateProvider/multiWindow/Viewport.mjs +1 -0
- package/examples/stateProvider/nestedData/MainContainer.mjs +1 -0
- package/examples/stateProvider/table/MainContainer.mjs +1 -0
- package/examples/table/covid/MainContainer.mjs +2 -0
- package/examples/table/covid/Store.mjs +1 -0
- package/examples/table/covid/TableContainer.mjs +3 -0
- package/examples/table/nestedRecordFields/EditUserDialog.mjs +3 -0
- package/examples/table/nestedRecordFields/Viewport.mjs +1 -0
- package/examples/todoList/version1/MainComponent.mjs +1 -1
- package/examples/toolbar/breadcrumb/view/MainContainer.mjs +2 -0
- package/examples/toolbar/paging/store/Users.mjs +1 -0
- package/examples/toolbar/paging/view/AddUserDialog.mjs +3 -0
- package/examples/toolbar/paging/view/MainContainer.mjs +3 -0
- package/examples/treeAccordion/MainContainer.mjs +2 -2
- package/examples/worker/task/MainContainer.mjs +1 -0
- package/learn/Glossary.md +1 -0
- package/learn/UsingTheseTopics.md +1 -0
- package/learn/benefits/ConfigSystem.md +2 -0
- package/learn/benefits/Effort.md +1 -0
- package/learn/benefits/Features.md +1 -0
- package/learn/benefits/FormsEngine.md +1 -0
- package/learn/benefits/FourEnvironments.md +2 -0
- package/learn/benefits/Introduction.md +2 -0
- package/learn/benefits/MultiWindow.md +3 -1
- package/learn/benefits/OffTheMainThread.md +2 -0
- package/learn/benefits/Quick.md +2 -0
- package/learn/benefits/RPCLayer.md +2 -0
- package/learn/benefits/Speed.md +2 -0
- package/learn/blog/v10-deep-dive-functional-components.md +293 -0
- package/learn/blog/v10-deep-dive-reactivity.md +522 -0
- package/learn/blog/v10-deep-dive-state-provider.md +432 -0
- package/learn/blog/v10-deep-dive-vdom-revolution.md +194 -0
- package/learn/blog/v10-post1-love-story.md +383 -0
- package/learn/comparisons/NeoVsAngular.md +90 -0
- package/learn/comparisons/NeoVsExtJs.md +178 -0
- package/learn/comparisons/NeoVsNextJs.md +124 -0
- package/learn/comparisons/NeoVsReact.md +95 -0
- package/learn/comparisons/NeoVsSolid.md +78 -0
- package/learn/comparisons/NeoVsVue.md +92 -0
- package/learn/comparisons/Overview.md +46 -0
- package/learn/gettingstarted/ComponentModels.md +2 -0
- package/learn/gettingstarted/Config.md +2 -0
- package/learn/gettingstarted/DescribingTheUI.md +2 -0
- package/learn/gettingstarted/Events.md +2 -0
- package/learn/gettingstarted/Extending.md +2 -0
- package/learn/gettingstarted/References.md +2 -0
- package/learn/gettingstarted/Setup.md +3 -2
- package/learn/gettingstarted/Workspaces.md +2 -0
- package/learn/guides/datahandling/Collections.md +1 -0
- package/learn/guides/datahandling/Records.md +1 -0
- package/learn/guides/datahandling/StateProviders.md +130 -16
- package/learn/guides/datahandling/Tables.md +1 -1
- package/learn/guides/fundamentals/ConfigSystemDeepDive.md +1 -0
- package/learn/guides/fundamentals/DeclarativeComponentTreesVsImperativeVdom.md +2 -0
- package/learn/guides/fundamentals/DeclarativeVDOMWithEffects.md +10 -8
- package/learn/guides/fundamentals/ExtendingNeoClasses.md +1 -0
- package/learn/guides/fundamentals/InstanceLifecycle.md +3 -1
- package/learn/guides/fundamentals/MainThreadAddons.md +2 -0
- package/learn/guides/specificfeatures/Mixins.md +3 -1
- package/learn/guides/specificfeatures/MultiWindow.md +3 -1
- package/learn/guides/specificfeatures/PortalApp.md +2 -0
- package/learn/guides/uibuildingblocks/ComponentsAndContainers.md +2 -0
- package/learn/guides/uibuildingblocks/CustomComponents.md +2 -0
- package/learn/guides/uibuildingblocks/Layouts.md +2 -0
- package/learn/guides/uibuildingblocks/WorkingWithVDom.md +28 -2
- package/learn/guides/userinteraction/Forms.md +2 -0
- package/learn/guides/userinteraction/events/CustomEvents.md +2 -1
- package/learn/guides/userinteraction/events/DomEvents.md +2 -0
- package/learn/javascript/ClassFeatures.md +4 -3
- package/learn/javascript/Classes.md +10 -13
- package/learn/javascript/Overrides.md +10 -6
- package/learn/javascript/Super.md +12 -8
- package/learn/tree.json +71 -64
- package/learn/tutorials/Earthquakes.md +2 -0
- package/learn/tutorials/RSP.md +3 -1
- package/learn/tutorials/TodoList.md +103 -7
- package/package.json +8 -6
- package/resources/scss/src/apps/email/ComposeView.scss +16 -0
- package/resources/scss/src/apps/email/MainView.scss +5 -0
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +5 -4
- package/src/DefaultConfig.mjs +12 -2
- package/src/Main.mjs +1 -0
- package/src/Neo.mjs +219 -166
- package/src/Xhr.mjs +1 -0
- package/src/button/Base.mjs +13 -0
- package/src/button/Effect.mjs +16 -2
- package/src/button/Split.mjs +2 -0
- package/src/calendar/store/Calendars.mjs +1 -0
- package/src/calendar/store/Colors.mjs +1 -0
- package/src/calendar/store/Events.mjs +1 -0
- package/src/calendar/view/DayComponent.mjs +2 -0
- package/src/calendar/view/EditEventContainer.mjs +4 -1
- package/src/calendar/view/MainContainer.mjs +13 -0
- package/src/calendar/view/MainContainerStateProvider.mjs +14 -28
- package/src/calendar/view/SettingsContainer.mjs +1 -0
- package/src/calendar/view/YearComponent.mjs +16 -0
- package/src/calendar/view/calendars/ColorsList.mjs +2 -0
- package/src/calendar/view/calendars/Container.mjs +2 -0
- package/src/calendar/view/calendars/EditContainer.mjs +1 -0
- package/src/calendar/view/month/Component.mjs +11 -0
- package/src/calendar/view/settings/GeneralContainer.mjs +1 -0
- package/src/calendar/view/settings/MonthContainer.mjs +1 -0
- package/src/calendar/view/settings/WeekContainer.mjs +1 -0
- package/src/calendar/view/settings/YearContainer.mjs +1 -0
- package/src/calendar/view/week/Component.mjs +15 -1
- package/src/calendar/view/week/TimeAxisComponent.mjs +4 -0
- package/src/code/LivePreview.mjs +51 -23
- package/src/collection/Base.mjs +7 -10
- package/src/collection/Filter.mjs +6 -0
- package/src/collection/Sorter.mjs +3 -0
- package/src/component/Abstract.mjs +412 -0
- package/src/component/Base.mjs +48 -1077
- package/src/component/Canvas.mjs +1 -0
- package/src/component/Chip.mjs +4 -0
- package/src/component/Circle.mjs +14 -0
- package/src/component/Clock.mjs +4 -0
- package/src/component/DateSelector.mjs +12 -0
- package/src/component/Gallery.mjs +11 -0
- package/src/component/Helix.mjs +24 -0
- package/src/component/Label.mjs +1 -0
- package/src/component/Legend.mjs +3 -0
- package/src/component/MagicMoveText.mjs +4 -0
- package/src/component/Progress.mjs +3 -0
- package/src/component/Splitter.mjs +3 -0
- package/src/component/StatusBadge.mjs +6 -0
- package/src/component/Timer.mjs +4 -0
- package/src/component/Toast.mjs +6 -0
- package/src/component/Video.mjs +1 -0
- package/src/component/mwc/Button.mjs +7 -0
- package/src/component/mwc/TextField.mjs +9 -0
- package/src/component/wrapper/AmChart.mjs +2 -0
- package/src/component/wrapper/GoogleMaps.mjs +3 -0
- package/src/component/wrapper/MapboxGL.mjs +5 -0
- package/src/component/wrapper/MonacoEditor.mjs +12 -0
- package/src/container/Accordion.mjs +2 -0
- package/src/container/Base.mjs +7 -3
- package/src/container/Panel.mjs +1 -0
- package/src/container/Viewport.mjs +1 -0
- package/src/controller/Application.mjs +1 -0
- package/src/controller/Base.mjs +1 -0
- package/src/controller/Component.mjs +1 -0
- package/src/core/Base.mjs +86 -33
- package/src/core/Compare.mjs +4 -7
- package/src/core/Config.mjs +65 -52
- package/src/core/Effect.mjs +86 -24
- package/src/core/EffectManager.mjs +117 -8
- package/src/core/IdGenerator.mjs +13 -44
- package/src/core/Observable.mjs +69 -65
- package/src/data/Model.mjs +2 -0
- package/src/data/Store.mjs +7 -0
- package/src/data/connection/WebSocket.mjs +2 -0
- package/src/date/DayViewComponent.mjs +2 -0
- package/src/date/SelectorContainer.mjs +14 -0
- package/src/dialog/Base.mjs +8 -0
- package/src/draggable/DragZone.mjs +5 -0
- package/src/draggable/tree/DragZone.mjs +1 -0
- package/src/filter/BooleanContainer.mjs +2 -0
- package/src/filter/NumberContainer.mjs +3 -0
- package/src/filter/ToggleOperatorsButton.mjs +2 -0
- package/src/form/Fieldset.mjs +6 -0
- package/src/form/field/Base.mjs +7 -0
- package/src/form/field/CheckBox.mjs +18 -0
- package/src/form/field/Chip.mjs +1 -0
- package/src/form/field/ComboBox.mjs +8 -0
- package/src/form/field/Country.mjs +1 -0
- package/src/form/field/Currency.mjs +2 -0
- package/src/form/field/Date.mjs +4 -0
- package/src/form/field/Display.mjs +1 -0
- package/src/form/field/Email.mjs +1 -0
- package/src/form/field/FileUpload.mjs +7 -0
- package/src/form/field/Hidden.mjs +1 -0
- package/src/form/field/Number.mjs +7 -0
- package/src/form/field/Password.mjs +1 -0
- package/src/form/field/Phone.mjs +3 -0
- package/src/form/field/Picker.mjs +2 -0
- package/src/form/field/Radio.mjs +1 -0
- package/src/form/field/Range.mjs +3 -0
- package/src/form/field/Search.mjs +2 -0
- package/src/form/field/Text.mjs +43 -5
- package/src/form/field/TextArea.mjs +7 -0
- package/src/form/field/Time.mjs +6 -0
- package/src/form/field/Url.mjs +3 -0
- package/src/form/field/ZipCode.mjs +2 -0
- package/src/form/field/trigger/Base.mjs +3 -0
- package/src/form/field/trigger/Clear.mjs +2 -0
- package/src/form/field/trigger/CopyToClipboard.mjs +2 -0
- package/src/form/field/trigger/Date.mjs +1 -0
- package/src/form/field/trigger/Picker.mjs +1 -0
- package/src/form/field/trigger/Search.mjs +1 -0
- package/src/form/field/trigger/SpinDown.mjs +2 -0
- package/src/form/field/trigger/SpinUp.mjs +1 -0
- package/src/form/field/trigger/Time.mjs +2 -0
- package/src/functional/_export.mjs +6 -0
- package/src/functional/button/Base.mjs +384 -0
- package/src/functional/component/Base.mjs +405 -0
- package/src/functional/defineComponent.mjs +102 -0
- package/src/functional/useConfig.mjs +52 -0
- package/src/functional/useEvent.mjs +43 -0
- package/src/grid/Body.mjs +20 -1
- package/src/grid/Container.mjs +50 -60
- package/src/grid/ScrollManager.mjs +2 -0
- package/src/grid/VerticalScrollbar.mjs +2 -0
- package/src/grid/column/Base.mjs +2 -0
- package/src/grid/header/Button.mjs +7 -0
- package/src/grid/header/Toolbar.mjs +6 -0
- package/src/grid/plugin/AnimateRows.mjs +2 -0
- package/src/layout/Base.mjs +3 -0
- package/src/layout/Card.mjs +1 -0
- package/src/layout/Cube.mjs +18 -4
- package/src/layout/Fit.mjs +1 -0
- package/src/layout/Flexbox.mjs +7 -0
- package/src/layout/Form.mjs +2 -0
- package/src/layout/Grid.mjs +1 -0
- package/src/layout/HBox.mjs +1 -0
- package/src/layout/VBox.mjs +1 -0
- package/src/list/Base.mjs +13 -0
- package/src/list/Chip.mjs +1 -0
- package/src/list/Circle.mjs +2 -0
- package/src/list/Color.mjs +1 -0
- package/src/list/plugin/Animate.mjs +2 -0
- package/src/main/DeltaUpdates.mjs +1 -0
- package/src/main/DomEvents.mjs +2 -0
- package/src/main/addon/CloneNode.mjs +1 -0
- package/src/main/addon/Cookie.mjs +1 -0
- package/src/main/addon/GoogleMaps.mjs +1 -0
- package/src/main/addon/LocalStorage.mjs +1 -0
- package/src/main/addon/MapboxGL.mjs +1 -0
- package/src/main/addon/Markdown.mjs +1 -0
- package/src/main/addon/Navigator.mjs +1 -0
- package/src/main/addon/Popover.mjs +1 -0
- package/src/main/addon/Stylesheet.mjs +1 -0
- package/src/main/addon/WindowPosition.mjs +1 -0
- package/src/manager/Component.mjs +0 -71
- package/src/manager/VDomUpdate.mjs +320 -0
- package/src/menu/List.mjs +6 -0
- package/src/menu/Model.mjs +1 -0
- package/src/menu/Panel.mjs +3 -0
- package/src/menu/Store.mjs +1 -0
- package/src/mixin/DomEvents.mjs +130 -0
- package/src/mixin/VdomLifecycle.mjs +670 -0
- package/src/plugin/Base.mjs +1 -0
- package/src/plugin/Resizable.mjs +2 -0
- package/src/selection/Model.mjs +15 -18
- package/src/selection/grid/BaseModel.mjs +1 -0
- package/src/sitemap/Component.mjs +1 -0
- package/src/state/Provider.mjs +129 -87
- package/src/state/createHierarchicalDataProxy.mjs +39 -25
- package/src/tab/Container.mjs +6 -0
- package/src/tab/Strip.mjs +1 -0
- package/src/tab/header/Button.mjs +2 -0
- package/src/tab/header/EffectButton.mjs +2 -0
- package/src/tab/header/Toolbar.mjs +1 -0
- package/src/table/Body.mjs +3 -0
- package/src/table/Container.mjs +10 -0
- package/src/table/header/Button.mjs +8 -0
- package/src/table/header/Toolbar.mjs +5 -0
- package/src/table/plugin/CellEditing.mjs +1 -0
- package/src/toolbar/Base.mjs +4 -0
- package/src/toolbar/Breadcrumb.mjs +3 -0
- package/src/toolbar/Paging.mjs +5 -0
- package/src/tooltip/Base.mjs +2 -0
- package/src/tree/List.mjs +3 -0
- package/src/util/HashHistory.mjs +1 -0
- package/src/util/KeyNavigation.mjs +2 -0
- package/src/util/Matrix.mjs +1 -0
- package/src/util/VDom.mjs +18 -5
- package/src/util/VNode.mjs +7 -1
- package/src/util/vdom/TreeBuilder.mjs +105 -0
- package/src/vdom/Helper.mjs +35 -23
- package/src/vdom/VNode.mjs +4 -6
- package/src/worker/App.mjs +1 -0
- package/src/worker/Base.mjs +2 -0
- package/src/worker/Manager.mjs +2 -0
- package/src/worker/ServiceBase.mjs +6 -1
- package/src/worker/mixin/RemoteMethodAccess.mjs +1 -6
- package/test/siesta/siesta.js +17 -2
- package/test/siesta/tests/VdomCalendar.mjs +19 -15
- package/test/siesta/tests/VdomHelper.mjs +7 -7
- package/test/siesta/tests/classic/Button.mjs +113 -0
- package/test/siesta/tests/core/Effect.mjs +10 -14
- package/test/siesta/tests/core/EffectBatching.mjs +72 -79
- package/test/siesta/tests/functional/Button.mjs +113 -0
- package/test/siesta/tests/state/ProviderNestedDataConfigs.mjs +314 -0
- package/test/siesta/tests/state/createHierarchicalDataProxy.mjs +42 -55
- package/test/siesta/tests/vdom/Advanced.mjs +14 -8
- package/test/siesta/tests/vdom/VdomAsymmetricUpdates.mjs +366 -0
- package/test/siesta/tests/vdom/VdomRealWorldUpdates.mjs +249 -0
- package/test/siesta/tests/vdom/layout/Cube.mjs +11 -7
- package/test/siesta/tests/vdom/table/Container.mjs +9 -5
- package/learn/javascript/NewNode.md +0 -31
- package/src/core/EffectBatchManager.mjs +0 -68
package/learn/benefits/Speed.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# Extreme Speed
|
2
|
+
|
1
3
|
The Neo.mjs architecture leverages web workers to run application logic, data processing,
|
2
4
|
and even parts of the rendering pipeline in parallel, on separate CPU cores.
|
3
5
|
This offloads heavy computations from the main thread, ensuring the UI remains responsive.
|
@@ -0,0 +1,293 @@
|
|
1
|
+
# Beyond Hooks: A New Breed of Functional Components for a Multi-Threaded World
|
2
|
+
|
3
|
+
If you're a seasoned React developer, you've mastered the art of hooks. You know how to build complex, stateful UIs with
|
4
|
+
`useState`, `useEffect`, and `useMemo`. You also know the trade-offs—the intricate dependency arrays, the constant battle
|
5
|
+
against unnecessary re-renders, and the "memoization tax" you pay to keep your application performant.
|
6
|
+
|
7
|
+
We've been taught that these trade-offs are fundamental to the functional component model. But what if they aren't?
|
8
|
+
What if they are merely symptoms of a single-threaded architecture?
|
9
|
+
|
10
|
+
This article will show you a new breed of functional component, born from a multi-threaded world, that eliminates these
|
11
|
+
compromises by design. We didn't build them to copy other frameworks; we built them because our architecture unlocked a
|
12
|
+
better way to write UIs.
|
13
|
+
|
14
|
+
*(Part 3 of 5 in the v10 blog series. Details at the bottom.)*
|
15
|
+
|
16
|
+
### A First Look: The Anatomy of a Neo.mjs Functional Component
|
17
|
+
|
18
|
+
Before we dive into the "why," let's look at the "what." Here is a simple, complete, and reactive functional component
|
19
|
+
in Neo.mjs. Keep this structure in mind as we explore how it solves the problems you've come to accept as normal.
|
20
|
+
|
21
|
+
```javascript
|
22
|
+
import {defineComponent, useConfig, useEvent} from 'neo.mjs';
|
23
|
+
|
24
|
+
export default defineComponent({
|
25
|
+
// The component's public API (like props)
|
26
|
+
config: {
|
27
|
+
className: 'My.Counter',
|
28
|
+
labelText_: 'Counter:'
|
29
|
+
},
|
30
|
+
|
31
|
+
// The function that creates the VDOM
|
32
|
+
createVdom(config) {
|
33
|
+
// Internal, private state (like useState)
|
34
|
+
const [count, setCount] = useConfig(0);
|
35
|
+
|
36
|
+
// An event listener that updates the private state
|
37
|
+
useEvent('click', () => setCount(prev => prev + 1));
|
38
|
+
|
39
|
+
return {
|
40
|
+
tag: 'button',
|
41
|
+
cn: [
|
42
|
+
{tag: 'span', text: config.labelText},
|
43
|
+
{tag: 'span', cls: ['count-badge'], text: count}
|
44
|
+
]
|
45
|
+
}
|
46
|
+
}
|
47
|
+
});
|
48
|
+
```
|
49
|
+
|
50
|
+
Notice what's missing: there are no dependency arrays, no `memo` wrappers, and no `useCallback` hooks. Now, let's explore
|
51
|
+
the architecture that makes this clean, simple code possible.
|
52
|
+
|
53
|
+
---
|
54
|
+
|
55
|
+
### The Architectural Divide: Why Your Component's Environment Matters
|
56
|
+
|
57
|
+
Before we deconstruct the problems, we have to address the fundamental difference that changes everything. In a
|
58
|
+
traditional framework like React, your component function, its state, its reconciliation (diffing), and its DOM
|
59
|
+
manipulation all happen on the **same main thread** that is responsible for user interactions.
|
60
|
+
|
61
|
+
In Neo.mjs, the architecture is fundamentally different:
|
62
|
+
|
63
|
+
1. **Your Application Logic (including your component's `createVdom` function) runs in a dedicated App Worker.**
|
64
|
+
2. **The VDOM diffing happens in a separate VDom Worker.**
|
65
|
+
3. **The Main Thread is left with one primary job: applying the calculated DOM patches.**
|
66
|
+
|
67
|
+
This isn't just a minor difference; it's a paradigm shift. Your component code is decoupled from the rendering engine,
|
68
|
+
which allows for a level of performance and predictability that is architecturally impossible on the main thread.
|
69
|
+
With this in mind, let's see how this new architecture solves old problems.
|
70
|
+
|
71
|
+
---
|
72
|
+
|
73
|
+
### Deconstructing the "React Tax": How a New Architecture Solves Old Problems
|
74
|
+
|
75
|
+
Let's tackle the compromises you've learned to live with, one by one, and show how a multi-threaded architecture solves
|
76
|
+
them at their root.
|
77
|
+
|
78
|
+
#### 1. The Problem: Cascading Re-Renders & The `memo` Tax
|
79
|
+
|
80
|
+
**The React Way:** You know the drill. A state change in a parent component triggers a re-render. By default, React then
|
81
|
+
re-renders **all of its children**, whether their props have changed or not. To prevent this performance drain,
|
82
|
+
you are forced to pay the `memo` tax: wrapping components in `React.memo()`, manually memoizing functions with
|
83
|
+
`useCallback()`, and objects with `useMemo()`. This manual optimization becomes a core, and often frustrating,
|
84
|
+
part of the development process.
|
85
|
+
|
86
|
+
```javascript
|
87
|
+
// A typical "optimized" React component
|
88
|
+
const MyComponent = React.memo(({ onButtonClick, user }) => {
|
89
|
+
console.log('Rendering MyComponent');
|
90
|
+
return <button onClick={onButtonClick}>{user.name}</button>;
|
91
|
+
});
|
92
|
+
|
93
|
+
const App = () => {
|
94
|
+
const [count, setCount] = useState(0);
|
95
|
+
|
96
|
+
// We must wrap this in useCallback to prevent MyComponent from re-rendering
|
97
|
+
// every time the App component's state changes.
|
98
|
+
const handleClick = useCallback(() => {
|
99
|
+
console.log('Button clicked!');
|
100
|
+
}, []);
|
101
|
+
|
102
|
+
// We must wrap this in useMemo to ensure the object reference is stable.
|
103
|
+
const user = useMemo(() => ({ name: 'John Doe' }), []);
|
104
|
+
|
105
|
+
return (
|
106
|
+
<div>
|
107
|
+
<button onClick={() => setCount(c => c + 1)}>App Clicks: {count}</button>
|
108
|
+
<MyComponent onButtonClick={handleClick} user={user} />
|
109
|
+
</div>
|
110
|
+
);
|
111
|
+
};
|
112
|
+
```
|
113
|
+
|
114
|
+
**The Neo.mjs Solution: Surgical Effects, Not Brute-Force Renders**
|
115
|
+
|
116
|
+
Our `createVdom` method is a surgical `Effect`. It automatically and precisely tracks every piece of reactive state it reads.
|
117
|
+
When a piece of state changes, **only the specific `createVdom` effects that depend on that exact piece of state are queued
|
118
|
+
for re-execution.**
|
119
|
+
|
120
|
+
There are no cascading re-renders. If a parent's `createVdom` re-runs, but the configs passed to a child have not changed,
|
121
|
+
the child component's `createVdom` function is **never executed**.
|
122
|
+
|
123
|
+
This means `memo`, `useCallback`, and `useMemo` are not needed. The architecture is efficient by default, eliminating an
|
124
|
+
entire class of performance optimizations and bugs.
|
125
|
+
|
126
|
+
#### 2. The Problem: The Boilerplate of Immutability
|
127
|
+
|
128
|
+
**The React Way:** To change a nested object in React state, you have to meticulously reconstruct the object path with
|
129
|
+
spread syntax (`...`), creating new references for every level. This is required to signal to React's diffing algorithm
|
130
|
+
that something has changed.
|
131
|
+
|
132
|
+
```javascript
|
133
|
+
// The familiar immutable update dance
|
134
|
+
setState(prevState => ({
|
135
|
+
...prevState,
|
136
|
+
deeply: {
|
137
|
+
...prevState.deeply,
|
138
|
+
nested: {
|
139
|
+
...prevState.deeply.nested,
|
140
|
+
property: 'new value'
|
141
|
+
}
|
142
|
+
}
|
143
|
+
}));
|
144
|
+
```
|
145
|
+
|
146
|
+
**The Neo.mjs Solution: Mutability for You, Immutability for the Machine**
|
147
|
+
|
148
|
+
We believe the developer should not carry this cognitive load. In Neo.mjs, you can just mutate the state directly.
|
149
|
+
It's simple and intuitive.
|
150
|
+
|
151
|
+
```javascript
|
152
|
+
// Just change the value. That's it.
|
153
|
+
this.myObject.deeply.nested.property = 'new value';
|
154
|
+
```
|
155
|
+
|
156
|
+
How does it work? When an update is triggered, the framework handles creating an immutable JSON snapshot of the VDOM for
|
157
|
+
the diffing process in the VDom Worker. We provide the best of both worlds: simple, direct mutation for the developer
|
158
|
+
and a safe, immutable structure for the high-performance diffing algorithm.
|
159
|
+
|
160
|
+
#### 3. The Problem: The "SSR and Hydration is the ONLY way" Mindset
|
161
|
+
|
162
|
+
**The React/Next.js Way:** The industry has invested heavily in Server-Side Rendering and hydration to improve perceived
|
163
|
+
performance and SEO. For content-heavy sites, this is a valid strategy. But for complex, stateful Single-Page Applications,
|
164
|
+
it introduces immense complexity: the "hydration crisis," the difficulty of managing server vs. client components, and
|
165
|
+
the fact that after all that work, your application is *still* running on the client's main thread.
|
166
|
+
|
167
|
+
**The Neo.mjs Solution: Blueprints, Not Dehydrated HTML**
|
168
|
+
|
169
|
+
We offer a more robust and scalable model for SPAs. Instead of sending pre-rendered HTML that needs to be brought back
|
170
|
+
to life, we can send a compact **JSON blueprint**. The client-side engine, running in a worker, constructs the live,
|
171
|
+
interactive UI from this blueprint. This is a more efficient, more predictable, and architecturally cleaner way to build
|
172
|
+
complex applications that are not primarily focused on static content.
|
173
|
+
|
174
|
+
---
|
175
|
+
|
176
|
+
### The "WOW" Effect: Building a Real Application
|
177
|
+
|
178
|
+
The simple counter example is a great start, but the true power of functional components is revealed when you build a
|
179
|
+
complete, interactive application. Let's build a slightly more advanced "Task List" application to demonstrate how all
|
180
|
+
the pieces come together.
|
181
|
+
|
182
|
+
This example will showcase:
|
183
|
+
- **Component Composition:** Using a class-based `List` component within our functional view.
|
184
|
+
- **State Management:** Tracking the currently selected task.
|
185
|
+
- **Conditional Rendering:** Displaying task details only when a task is selected.
|
186
|
+
- **Event Handling:** Updating state based on events from a child component.
|
187
|
+
|
188
|
+
Here is the complete, interactive example.
|
189
|
+
|
190
|
+
```javascript live-preview
|
191
|
+
import {defineComponent, useConfig} from 'neo.mjs';
|
192
|
+
import List from 'neo.mjs/src/list/Base.mjs';
|
193
|
+
import Store from 'neo.mjs/src/data/Store.mjs';
|
194
|
+
|
195
|
+
// 1. Define a simple data Store for our list
|
196
|
+
const TaskStore = Neo.create(Store, {
|
197
|
+
data: [
|
198
|
+
{id: 1, title: 'Build a better component model', description: 'Re-imagine what a component can be when freed from the main thread.'},
|
199
|
+
{id: 2, title: 'Create a new reactivity system', description: 'Design a two-tier system that is both powerful and intuitive.'},
|
200
|
+
{id: 3, title: 'Revolutionize the VDOM', description: 'Build an asymmetric, off-thread VDOM engine for maximum performance.'}
|
201
|
+
]
|
202
|
+
});
|
203
|
+
|
204
|
+
// 2. Define our main application view
|
205
|
+
export default defineComponent({
|
206
|
+
config: {
|
207
|
+
className: 'My.TaskListApp',
|
208
|
+
layout: {ntype: 'hbox', align: 'stretch'}
|
209
|
+
},
|
210
|
+
createVdom() {
|
211
|
+
// 3. Manage the selected task with useConfig
|
212
|
+
const [selectedTask, setSelectedTask] = useConfig(null);
|
213
|
+
|
214
|
+
const onSelectionChange = ({value}) => {
|
215
|
+
// 4. Update our state when the list selection changes
|
216
|
+
setSelectedTask(TaskStore.get(value[0]));
|
217
|
+
};
|
218
|
+
|
219
|
+
const paneStyle = {
|
220
|
+
border : '1px solid #c0c0c0',
|
221
|
+
margin : '10px',
|
222
|
+
padding: '10px'
|
223
|
+
};
|
224
|
+
|
225
|
+
return {
|
226
|
+
cn: [{
|
227
|
+
// 5. The List Component
|
228
|
+
module : List,
|
229
|
+
store : TaskStore,
|
230
|
+
width : 250,
|
231
|
+
style : paneStyle,
|
232
|
+
listeners: {
|
233
|
+
selectionChange: onSelectionChange
|
234
|
+
}
|
235
|
+
}, {
|
236
|
+
// 6. The Details Pane (with conditional rendering)
|
237
|
+
flex: 1,
|
238
|
+
style: paneStyle,
|
239
|
+
cn: selectedTask ? [
|
240
|
+
{tag: 'h2', text: selectedTask.title},
|
241
|
+
{tag: 'p', text: selectedTask.description}
|
242
|
+
] : [{
|
243
|
+
tag : 'div',
|
244
|
+
style: {color: '#888'},
|
245
|
+
text : 'Please select a task to see the details.'
|
246
|
+
}]
|
247
|
+
}]
|
248
|
+
}
|
249
|
+
}
|
250
|
+
});
|
251
|
+
```
|
252
|
+
|
253
|
+
This single `defineComponent` call creates a fully-featured application. Notice how the `createVdom` function is a pure,
|
254
|
+
declarative representation of the UI. When the `selectedTask` state changes, the framework surgically re-renders only
|
255
|
+
the details pane. This is the power of the new component model in action: complex, stateful, and performant applications
|
256
|
+
with beautifully simple code.
|
257
|
+
|
258
|
+
---
|
259
|
+
|
260
|
+
### The AI Connection: The Inevitable Next Step
|
261
|
+
|
262
|
+
This blueprint-first, surgically reactive, and mutable-by-default model isn't just better for you; it's the architecture
|
263
|
+
an AI would choose. An AI can easily generate and manipulate a structured JSON blueprint, but it struggles to generate
|
264
|
+
flawless, complex JSX. By building on these principles, you are not just using a new framework; you are future-proofing
|
265
|
+
your skills for the AI era.
|
266
|
+
|
267
|
+
---
|
268
|
+
|
269
|
+
### Conclusion: A Different Philosophy, A Better Component
|
270
|
+
|
271
|
+
Neo.mjs functional components are not a "React clone." They are a re-imagining of what a functional component can be
|
272
|
+
when freed from the architectural constraints of the main thread. They offer a development experience that is not only
|
273
|
+
more performant by default but also simpler, more intuitive, and ready for the AI-driven future of the web.
|
274
|
+
|
275
|
+
This is what it feels like to stop paying the performance tax and start building again.
|
276
|
+
|
277
|
+
The clean, hook-based API for functional components is possible because it stands on the shoulders of a robust, modular,
|
278
|
+
and deeply integrated class system. We've engineered the framework's core to handle the complex machinery of reactivity
|
279
|
+
and lifecycle management automatically. To learn more about the powerful engine that makes this all possible, see our
|
280
|
+
deep dive on the **Two-Tier Reactivity System**.
|
281
|
+
|
282
|
+
Next, we will look at how this architecture revolutionizes the very way we render UIs with the Asymmetric VDOM
|
283
|
+
and JSON Blueprints.
|
284
|
+
|
285
|
+
---
|
286
|
+
|
287
|
+
## The Neo.mjs v10 Blog Post Series
|
288
|
+
|
289
|
+
1. [A Frontend Love Story: Why the Strategies of Today Won't Build the Apps of Tomorrow](./v10-post1-love-story.md)
|
290
|
+
2. [Deep Dive: Named vs. Anonymous State - A New Era of Component Reactivity](./v10-deep-dive-reactivity.md)
|
291
|
+
3. Beyond Hooks: A New Breed of Functional Components for a Multi-Threaded World
|
292
|
+
4. [Deep Dive: The VDOM Revolution - JSON Blueprints & Asymmetric Rendering](./v10-deep-dive-vdom-revolution.md)
|
293
|
+
5. [Deep Dive: The State Provider Revolution](./v10-deep-dive-state-provider.md)
|