neo.mjs 10.0.0-alpha.5 → 10.0.0-beta.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.
- package/ServiceWorker.mjs +2 -2
- package/apps/colors/view/GridContainer.mjs +1 -1
- package/apps/covid/view/AttributionComponent.mjs +1 -1
- package/apps/covid/view/HeaderContainer.mjs +6 -6
- package/apps/covid/view/MainContainerController.mjs +5 -5
- package/apps/covid/view/TableContainerController.mjs +1 -1
- package/apps/covid/view/country/Gallery.mjs +13 -13
- package/apps/covid/view/country/Helix.mjs +13 -13
- package/apps/covid/view/country/HistoricalDataTable.mjs +1 -1
- package/apps/email/view/Viewport.mjs +2 -2
- package/apps/form/view/SideNavList.mjs +1 -1
- package/apps/portal/index.html +1 -1
- package/apps/portal/resources/data/examples_devmode.json +26 -27
- package/apps/portal/resources/data/examples_dist_dev.json +26 -27
- package/apps/portal/resources/data/examples_dist_esm.json +25 -26
- package/apps/portal/resources/data/examples_dist_prod.json +26 -27
- package/apps/portal/view/HeaderToolbar.mjs +3 -3
- package/apps/portal/view/about/Container.mjs +2 -2
- package/apps/portal/view/about/MemberContainer.mjs +3 -3
- package/apps/portal/view/blog/List.mjs +7 -7
- package/apps/portal/view/examples/List.mjs +4 -4
- package/apps/portal/view/home/ContentBox.mjs +2 -2
- package/apps/portal/view/home/FeatureSection.mjs +3 -3
- package/apps/portal/view/home/FooterContainer.mjs +7 -7
- package/apps/portal/view/home/parts/AfterMath.mjs +3 -3
- package/apps/portal/view/home/parts/MainNeo.mjs +3 -3
- package/apps/portal/view/home/parts/References.mjs +6 -6
- package/apps/portal/view/learn/ContentComponent.mjs +102 -111
- package/apps/portal/view/learn/PageSectionsContainer.mjs +1 -1
- package/apps/portal/view/learn/PageSectionsList.mjs +2 -2
- package/apps/portal/view/services/Component.mjs +16 -16
- package/apps/realworld/view/FooterComponent.mjs +1 -1
- package/apps/realworld/view/HeaderComponent.mjs +8 -8
- package/apps/realworld/view/HomeComponent.mjs +6 -6
- package/apps/realworld/view/article/CommentComponent.mjs +4 -4
- package/apps/realworld/view/article/Component.mjs +14 -14
- package/apps/realworld/view/article/CreateCommentComponent.mjs +3 -3
- package/apps/realworld/view/article/CreateComponent.mjs +3 -3
- package/apps/realworld/view/article/PreviewComponent.mjs +1 -1
- package/apps/realworld/view/article/TagListComponent.mjs +2 -2
- package/apps/realworld/view/user/ProfileComponent.mjs +8 -8
- package/apps/realworld/view/user/SettingsComponent.mjs +4 -4
- package/apps/realworld/view/user/SignUpComponent.mjs +4 -4
- package/apps/realworld2/view/FooterComponent.mjs +1 -1
- package/apps/realworld2/view/HomeContainer.mjs +3 -3
- package/apps/realworld2/view/article/DetailsContainer.mjs +1 -1
- package/apps/realworld2/view/article/PreviewComponent.mjs +7 -7
- package/apps/realworld2/view/article/TagListComponent.mjs +2 -2
- package/apps/realworld2/view/user/ProfileContainer.mjs +1 -1
- package/apps/route/view/center/CardAdministration.mjs +2 -2
- package/apps/route/view/center/CardAdministrationDenied.mjs +1 -1
- package/apps/route/view/center/CardContact.mjs +2 -2
- package/apps/route/view/center/CardHome.mjs +1 -1
- package/apps/route/view/center/CardSection1.mjs +1 -1
- package/apps/route/view/center/CardSection2.mjs +1 -1
- package/apps/sharedcovid/view/AttributionComponent.mjs +1 -1
- package/apps/sharedcovid/view/HeaderContainer.mjs +6 -6
- package/apps/sharedcovid/view/MainContainerController.mjs +5 -5
- package/apps/sharedcovid/view/TableContainerController.mjs +1 -1
- package/apps/sharedcovid/view/country/Gallery.mjs +13 -13
- package/apps/sharedcovid/view/country/Helix.mjs +13 -13
- package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -1
- package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +1 -1
- package/apps/shareddialog/view/MainContainer.mjs +1 -1
- package/buildScripts/createApp.mjs +2 -2
- package/examples/table/cellEditing/MainContainer.mjs +1 -1
- package/examples/table/container/MainContainer.mjs +3 -3
- package/examples/table/nestedRecordFields/Viewport.mjs +6 -6
- package/examples/tableFiltering/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer.mjs +1 -1
- package/examples/tablePerformance/MainContainer2.mjs +1 -1
- package/examples/tablePerformance/MainContainer3.mjs +2 -2
- package/examples/tableStore/MainContainer.mjs +2 -2
- package/learn/Glossary.md +261 -0
- package/learn/UsingTheseTopics.md +2 -2
- package/learn/benefits/ConfigSystem.md +538 -28
- package/learn/benefits/Effort.md +47 -2
- package/learn/benefits/Features.md +50 -32
- package/learn/benefits/FormsEngine.md +68 -38
- package/learn/benefits/MultiWindow.md +33 -7
- package/learn/benefits/OffTheMainThread.md +2 -2
- package/learn/benefits/Quick.md +45 -12
- package/learn/benefits/RPCLayer.md +75 -0
- package/learn/benefits/Speed.md +16 -11
- package/learn/gettingstarted/ComponentModels.md +4 -4
- package/learn/gettingstarted/Config.md +6 -6
- package/learn/gettingstarted/DescribingTheUI.md +4 -4
- package/learn/gettingstarted/Events.md +6 -6
- package/learn/gettingstarted/Extending.md +4 -4
- package/learn/gettingstarted/References.md +6 -6
- package/learn/gettingstarted/Workspaces.md +6 -6
- package/learn/guides/ApplicationBootstrap.md +26 -26
- package/learn/guides/ComponentsAndContainers.md +12 -12
- package/learn/guides/ConfigSystemDeepDive.md +280 -0
- package/learn/guides/CustomComponents.md +2 -2
- package/learn/guides/DeclarativeComponentTreesVsImperativeVdom.md +17 -17
- package/learn/guides/InstanceLifecycle.md +295 -1
- package/learn/guides/MainThreadAddons.md +475 -0
- package/learn/guides/PortalApp.md +2 -2
- package/learn/guides/StateProviders.md +12 -12
- package/learn/guides/WorkingWithVDom.md +14 -14
- package/learn/guides/events/CustomEvents.md +16 -16
- package/learn/guides/events/DomEvents.md +12 -12
- package/learn/javascript/ClassFeatures.md +3 -2
- package/learn/javascript/Classes.md +8 -8
- package/learn/javascript/NewNode.md +4 -4
- package/learn/javascript/Overrides.md +8 -8
- package/learn/javascript/Super.md +10 -8
- package/learn/tree.json +52 -51
- package/learn/tutorials/Earthquakes.md +54 -57
- package/learn/tutorials/TodoList.md +4 -4
- package/package.json +2 -2
- package/resources/scss/src/apps/portal/learn/ContentComponent.scss +12 -0
- package/resources/scss/src/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/src/table/plugin/CellEditing.scss +1 -1
- package/resources/scss/theme-dark/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/table/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/Global.scss +1 -2
- package/resources/scss/theme-neo-light/table/{View.scss → Body.scss} +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/Main.mjs +8 -7
- package/src/Neo.mjs +16 -2
- package/src/button/Base.mjs +2 -2
- package/src/calendar/view/SettingsContainer.mjs +2 -2
- package/src/calendar/view/YearComponent.mjs +9 -9
- package/src/calendar/view/calendars/ColorsList.mjs +1 -1
- package/src/calendar/view/calendars/List.mjs +1 -1
- package/src/calendar/view/month/Component.mjs +15 -15
- package/src/calendar/view/week/Component.mjs +12 -12
- package/src/calendar/view/week/EventDragZone.mjs +4 -4
- package/src/calendar/view/week/TimeAxisComponent.mjs +3 -3
- package/src/component/Base.mjs +17 -2
- package/src/component/Carousel.mjs +2 -2
- package/src/component/Chip.mjs +3 -3
- package/src/component/Circle.mjs +2 -2
- package/src/component/DateSelector.mjs +8 -8
- package/src/component/Helix.mjs +1 -1
- package/src/component/Label.mjs +3 -18
- package/src/component/Legend.mjs +3 -3
- package/src/component/MagicMoveText.mjs +6 -14
- package/src/component/Process.mjs +3 -3
- package/src/component/Progress.mjs +1 -1
- package/src/component/StatusBadge.mjs +2 -2
- package/src/component/Timer.mjs +2 -2
- package/src/component/Toast.mjs +5 -3
- package/src/container/AccordionItem.mjs +2 -2
- package/src/container/Base.mjs +1 -1
- package/src/core/Base.mjs +77 -14
- package/src/core/Util.mjs +14 -2
- package/src/date/DayViewComponent.mjs +2 -2
- package/src/date/SelectorContainer.mjs +1 -1
- package/src/draggable/grid/header/toolbar/SortZone.mjs +21 -21
- package/src/draggable/table/header/toolbar/SortZone.mjs +1 -1
- package/src/form/field/CheckBox.mjs +4 -4
- package/src/form/field/FileUpload.mjs +25 -39
- package/src/form/field/Range.mjs +1 -1
- package/src/form/field/Text.mjs +3 -3
- package/src/form/field/TextArea.mjs +2 -3
- package/src/grid/Body.mjs +8 -5
- package/src/grid/_export.mjs +1 -1
- package/src/list/Color.mjs +2 -2
- package/src/main/DeltaUpdates.mjs +157 -98
- package/src/main/addon/AmCharts.mjs +61 -84
- package/src/main/addon/Base.mjs +161 -42
- package/src/main/addon/GoogleMaps.mjs +9 -16
- package/src/main/addon/HighlightJS.mjs +2 -13
- package/src/main/addon/IntersectionObserver.mjs +21 -21
- package/src/main/addon/MonacoEditor.mjs +32 -64
- package/src/manager/ClassHierarchy.mjs +114 -0
- package/src/menu/List.mjs +1 -1
- package/src/plugin/Popover.mjs +2 -2
- package/src/sitemap/Component.mjs +1 -1
- package/src/table/{View.mjs → Body.mjs} +25 -22
- package/src/table/Container.mjs +43 -43
- package/src/table/_export.mjs +2 -2
- package/src/table/plugin/CellEditing.mjs +19 -19
- package/src/tooltip/Base.mjs +1 -6
- package/src/tree/Accordion.mjs +3 -3
- package/src/vdom/Helper.mjs +19 -22
- package/src/worker/App.mjs +1 -2
- package/src/worker/Base.mjs +7 -5
- package/src/worker/Canvas.mjs +2 -3
- package/src/worker/Data.mjs +5 -7
- package/src/worker/Task.mjs +2 -3
- package/src/worker/VDom.mjs +3 -4
- package/src/worker/mixin/RemoteMethodAccess.mjs +5 -2
- package/learn/guides/MainThreadAddonExample.md +0 -15
- package/learn/guides/MainThreadAddonIntro.md +0 -44
@@ -1,46 +1,64 @@
|
|
1
|
-
###Multi-Window Apps
|
2
1
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
- Moving components across windows while keeping the same JS instances
|
2
|
+
Neo.mjs is engineered to address the most pressing challenges in modern web development, offering a suite of features
|
3
|
+
that deliver unparalleled performance, developer productivity, and architectural flexibility. Below are the core
|
4
|
+
capabilities that set Neo.mjs apart.
|
7
5
|
|
8
|
-
|
6
|
+
## Multi-Window Applications
|
9
7
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
-
|
14
|
-
-
|
8
|
+
Neo.mjs provides native, robust support for applications spanning multiple browser windows without the need for external
|
9
|
+
shells like Electron. This enables seamless data and state sharing across windows, allowing components to be moved between
|
10
|
+
them while maintaining their JavaScript instances. This capability is crucial for complex enterprise applications requiring
|
11
|
+
sophisticated multi-screen workflows. For more details, see
|
12
|
+
[Multi-Window Applications](#/learn/benefits.MultiWindow).
|
15
13
|
|
16
|
-
|
14
|
+
## True Multi-threading (Off-The-Main-Thread Architecture)
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
-
|
21
|
-
|
16
|
+
At the heart of Neo.mjs is its revolutionary Off-Main-Thread (OMT) paradigm. Your entire application, including the
|
17
|
+
framework itself, runs within a dedicated application worker. This offloads all business logic, data processing, and
|
18
|
+
intensive UI updates from the main thread, ensuring a consistently non-blocking, freeze-free user experience, even during
|
19
|
+
heavy computations or data I/O. Neo.mjs further enhances this with additional workers for OffscreenCanvas, data handling,
|
20
|
+
delta-updates, and tasks, alongside a ServiceWorker for predictive caching. Learn more about this in
|
21
|
+
[Off the Main Thread](#/learn/benefits.OffTheMainThread) and
|
22
|
+
[Extreme Speed](#/learn/benefits.Speed).
|
22
23
|
|
24
|
+
## Modern JavaScript Development
|
23
25
|
|
24
|
-
|
26
|
+
Embrace the future of web development with Neo.mjs. Its development mode operates without the need for transpilation or
|
27
|
+
compilation, allowing you to work directly with 100% web standards-based JavaScript. This means instant feedback, simpler
|
28
|
+
debugging, and the ability to leverage the latest ECMAScript features as soon as browser support is available,
|
29
|
+
significantly reducing development costs and accelerating iteration cycles. Discover the details in
|
30
|
+
[4 Environments](#/learn/benefits.FourEnvironments) and
|
31
|
+
[Quick Application Development](#/learn/benefits.Quick).
|
25
32
|
|
26
|
-
|
27
|
-
- High order components
|
28
|
-
- Many out-of-the-box Components, including nested lazy-loaded forms
|
29
|
-
- Multiple themes, which can get nested
|
33
|
+
## Powerful Component Library
|
30
34
|
|
31
|
-
|
35
|
+
Neo.mjs offers a comprehensive and highly performant component library. Build complex user interfaces with declarative
|
36
|
+
component trees and high-order components. The library includes a wide array of out-of-the-box components, such as
|
37
|
+
nested lazy-loaded forms, and supports multiple theming options that can be nested for granular control over your
|
38
|
+
application's aesthetics. Explore the forms engine in
|
39
|
+
[Forms Engine](#/learn/benefits.FormsEngine).
|
32
40
|
|
33
|
-
|
34
|
-
- Observable
|
35
|
-
- Supporting different architectures like MVVM without enforcing them
|
41
|
+
## Elegant State Management
|
36
42
|
|
43
|
+
Manage your application's data with Neo.mjs's elegant state management system. It supports multiple communicating state
|
44
|
+
providers and leverages observable patterns for reactive data flows. This flexible approach allows you to adopt various
|
45
|
+
architectural patterns, like MVVM, without being rigidly enforced, giving you the freedom to choose the best fit for
|
46
|
+
your project. More on this in
|
47
|
+
[Quick Application Development](#/learn/benefits.Quick).
|
37
48
|
|
38
|
-
|
49
|
+
## Core Architectural Features
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
-
|
45
|
-
|
51
|
+
* **RPC Layer**: A robust Remote Procedure Call (RPC) layer facilitates seamless, cross-realm communication,
|
52
|
+
extending even to backend integrations. Learn more in
|
53
|
+
[The Neo.mjs RPC Layer](#/learn/benefits.RPCLayer).
|
54
|
+
* **Extensibility & Scalability**: The framework is designed for maximum extensibility, allowing you to easily integrate
|
55
|
+
custom logic and scale your applications from small prototypes to large-scale enterprise solutions.
|
56
|
+
* **Class Config System**: A unified, declarative class config system simplifies component definition and management,
|
57
|
+
ensuring consistency across your entire application.
|
58
|
+
* **Drag & Drop**: Built-in support for intuitive drag-and-drop interactions enhances user experience.
|
59
|
+
* **Mixins, Plugins & Main-Thread Addons**: A rich set of tools for extending functionality, integrating third-party
|
60
|
+
libraries, and interacting with the main browser thread when necessary.
|
61
|
+
|
62
|
+
Neo.mjs's feature set is meticulously crafted to provide a superior development experience and deliver high-performance,
|
63
|
+
scalable, and maintainable web applications that stand out in today's demanding digital landscape.
|
46
64
|
|
@@ -1,9 +1,25 @@
|
|
1
|
-
## Forms include a State-Provider
|
2
1
|
|
3
|
-
|
4
|
-
It is sufficient to just use namespaces inside the `name` attribute of each field.
|
2
|
+
## Simplifying Complex Data Input
|
5
3
|
|
6
|
-
|
4
|
+
Building robust and user-friendly forms is often a significant challenge in web development. Traditional approaches can
|
5
|
+
lead to complex state management, difficult validation, and performance bottlenecks, especially with large or dynamic
|
6
|
+
forms. The Neo.mjs Forms Engine is designed from the ground up to simplify these complexities, offering a powerful,
|
7
|
+
declarative, and highly efficient solution for all your data input needs.
|
8
|
+
|
9
|
+
### Forms Include a State-Provider: Effortless Data Management
|
10
|
+
|
11
|
+
One of the most compelling features of the Neo.mjs Forms Engine is its integrated state management. You don't need to
|
12
|
+
manually define a separate state tree or connect external state management libraries. Instead, the form itself acts as
|
13
|
+
a state provider, automatically managing the data for its fields.
|
14
|
+
|
15
|
+
This is achieved by simply using namespaces within the `name` attribute of each field. The form engine intelligently
|
16
|
+
structures your data based on these names, providing a clean, hierarchical data object.
|
17
|
+
|
18
|
+
**Benefit**: This significantly reduces boilerplate code and simplifies data flow. Developers can focus on defining the
|
19
|
+
form structure and validation rules, rather than wrestling with data synchronization. For businesses, this means faster
|
20
|
+
development cycles and fewer bugs related to data handling.
|
21
|
+
|
22
|
+
```javascript live-preview
|
7
23
|
import Button from '../button/Base.mjs';
|
8
24
|
import FormContainer from '../form/Container.mjs';
|
9
25
|
import TextField from '../form/field/Text.mjs';
|
@@ -38,18 +54,19 @@ class MainView extends FormContainer {
|
|
38
54
|
}
|
39
55
|
}
|
40
56
|
MainView = Neo.setupClass(MainView);
|
41
|
-
|
57
|
+
```
|
42
58
|
|
43
|
-
|
59
|
+
### Forms Can Be Validated Without Being Mounted: Flexible UI Design
|
44
60
|
|
45
|
-
Neo.mjs
|
46
|
-
|
47
|
-
Getting the field values still works like before.
|
61
|
+
Neo.mjs forms exist as a pure abstraction layer within JavaScript, decoupled from their DOM representation. This unique
|
62
|
+
capability allows forms to be validated and their values retrieved even if they are not currently mounted in the DOM.
|
48
63
|
|
49
|
-
|
50
|
-
|
64
|
+
**Benefit**: This is incredibly powerful for complex user interfaces, such as multi-step wizards, tabbed forms, or
|
65
|
+
forms with conditionally rendered sections. You can maintain the state and validate parts of a form that are not
|
66
|
+
currently visible, ensuring data integrity without the performance overhead of rendering unnecessary DOM elements.
|
67
|
+
For users, this translates to a smoother, more responsive experience, as the UI remains lightweight.
|
51
68
|
|
52
|
-
|
69
|
+
```javascript live-preview
|
53
70
|
import Button from '../button/Base.mjs';
|
54
71
|
import Container from '../container/Base.mjs';
|
55
72
|
import FormContainer from '../form/Container.mjs';
|
@@ -89,43 +106,45 @@ class MainView extends Container {
|
|
89
106
|
}
|
90
107
|
}
|
91
108
|
MainView = Neo.setupClass(MainView);
|
92
|
-
|
109
|
+
```
|
93
110
|
|
94
|
-
|
111
|
+
### Nested Forms: Unprecedented Structural Flexibility
|
95
112
|
|
96
|
-
|
97
|
-
|
98
|
-
`{module: FormContainer, tag: 'div'}`
|
113
|
+
Unlike the limitations of HTML, where nesting `<form>` tags is not permitted, Neo.mjs allows for true nested forms.
|
114
|
+
This is achieved by mapping form containers to generic DOM nodes (e.g., `{module: FormContainer, tag: 'div'}`).
|
99
115
|
|
100
|
-
This
|
101
|
-
|
116
|
+
**Benefit**: This capability provides unparalleled structural flexibility, enabling you to build highly modular and
|
117
|
+
complex forms. You can validate or retrieve values from individual nested forms, or from the top-level form (which
|
118
|
+
includes all nested items), as needed. This promotes better organization of large forms, improves maintainability,
|
119
|
+
and allows for fine-grained control over validation and data submission. For complex business processes, this means
|
120
|
+
forms can accurately reflect intricate data relationships.
|
102
121
|
|
103
122
|
Inside the example preview, clear the user lastname via hitting the x-button.
|
104
123
|
Afterwards, click on the 3 buttons at the bottom and inspect the output inside the main window console carefully.
|
105
124
|
|
106
125
|
The main form will log:
|
107
|
-
|
126
|
+
```javascript readonly
|
108
127
|
{
|
109
128
|
account: 'My Account',
|
110
129
|
product: {brand: 'Tesla', name: 'Car'},
|
111
130
|
user : {firstname: 'John', lastname: null}
|
112
131
|
}
|
113
132
|
'isValid: false'
|
114
|
-
|
133
|
+
```
|
115
134
|
|
116
135
|
The user form will log:
|
117
|
-
|
136
|
+
```javascript readonly
|
118
137
|
{user: {firstname: 'John', lastname: null}}
|
119
138
|
'isValid: false'
|
120
|
-
|
139
|
+
```
|
121
140
|
|
122
141
|
The product form will log:
|
123
|
-
|
142
|
+
```javascript readonly
|
124
143
|
{product: {brand: 'Tesla', name: 'Car'}}
|
125
144
|
'isValid: true'
|
126
|
-
|
145
|
+
```
|
127
146
|
|
128
|
-
|
147
|
+
```javascript live-preview
|
129
148
|
import Button from '../button/Base.mjs';
|
130
149
|
import Container from '../container/Base.mjs';
|
131
150
|
import FormContainer from '../form/Container.mjs';
|
@@ -223,7 +242,7 @@ class MainView extends FormContainer {
|
|
223
242
|
}
|
224
243
|
}
|
225
244
|
MainView = Neo.setupClass(MainView);
|
226
|
-
|
245
|
+
```
|
227
246
|
|
228
247
|
Bonus: Inspect the DOM Inside the `TabContainer`.
|
229
248
|
You will notice that only the active Tab is mounted inside the DOM.
|
@@ -231,20 +250,21 @@ You will notice that only the active Tab is mounted inside the DOM.
|
|
231
250
|
1. We can still get field values of unmounted forms
|
232
251
|
2. We can still validate unmounted forms
|
233
252
|
|
234
|
-
|
253
|
+
### Nested Lazy-Loaded Forms: Optimizing Performance for Complex UIs
|
235
254
|
|
236
|
-
If you look
|
237
|
-
`
|
255
|
+
If you look closely at the `Button` handlers in the last example, you'll notice that `getValues()` and `validate()`
|
256
|
+
are both `async` methods. The reason for this is that `form.getFields()` itself is also asynchronous: it will
|
257
|
+
lazy-load (but not necessarily mount) missing fields when needed.
|
238
258
|
|
239
|
-
|
240
|
-
|
259
|
+
**Benefit**: This asynchronous, lazy-loading mechanism is crucial for optimizing the performance of complex forms.
|
260
|
+
Instead of loading all form fields and their associated logic upfront, Neo.mjs only loads what's necessary, when it's
|
261
|
+
needed. This results in significantly faster initial load times, reduced memory footprint, and a more responsive
|
262
|
+
application, especially for forms with many fields or conditional sections.
|
241
263
|
|
242
|
-
The lazy-loading use case is not easy to display inside the `LivePreview`,
|
243
|
-
|
244
|
-
and dynamically importing them.
|
264
|
+
The lazy-loading use case is not easy to display inside the `LivePreview`, since it does rely on defining child modules
|
265
|
+
inside their own class files and dynamically importing them. However, the pattern is straightforward:
|
245
266
|
|
246
|
-
|
247
|
-
<pre data-code-readonly>
|
267
|
+
```javascript readonly
|
248
268
|
{
|
249
269
|
module: TabContainer,
|
250
270
|
items : [
|
@@ -252,4 +272,14 @@ In a nutshell:
|
|
252
272
|
{module: () => import('./MyChildForm2.mjs')}
|
253
273
|
]
|
254
274
|
}
|
255
|
-
|
275
|
+
```
|
276
|
+
|
277
|
+
This allows for highly modular and performant form structures, where even entire sections of a form can be loaded
|
278
|
+
on-demand, further enhancing the user experience and application efficiency.
|
279
|
+
|
280
|
+
## Conclusion: A Comprehensive Solution for Form Development
|
281
|
+
|
282
|
+
The Neo.mjs Forms Engine provides a comprehensive and intuitive solution for building forms of any complexity.
|
283
|
+
By offering integrated state management, the ability to validate unmounted forms, true nested forms, and intelligent
|
284
|
+
lazy-loading, Neo.mjs empowers developers to create highly performant, maintainable, and user-friendly data input
|
285
|
+
experiences. This translates directly into increased developer productivity and a superior end-user experience.
|
@@ -1,10 +1,36 @@
|
|
1
|
-
|
2
|
-
application run in multiple browser windows; those windows can be moved to multiple monitors.
|
1
|
+
## Multi-Window Applications: Unleashing Desktop-Class Experiences
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
Traditional web applications are often confined to a single browser window or tab, limiting user productivity and the
|
4
|
+
ability to manage complex workflows. Neo.mjs shatters this limitation by providing native, robust support for
|
5
|
+
multi-window applications, enabling truly desktop-class experiences directly within the browser.
|
7
6
|
|
7
|
+
Neo.mjs applications can seamlessly launch and operate across multiple browser windows, leveraging **shared web workers**.
|
8
|
+
This allows a single application instance to run concurrently in various windows, which can even be moved to different
|
9
|
+
monitors, all while sharing the same underlying data and application state.
|
10
|
+
|
11
|
+
### Key Advantages & Use Cases:
|
12
|
+
|
13
|
+
* **Enhanced Productivity**: Users can arrange different parts of an application across multiple screens, optimizing
|
14
|
+
their workspace for complex tasks. Imagine a financial trading platform with real-time charts on one monitor, order
|
15
|
+
books on another, and a control panel on a third.
|
16
|
+
|
17
|
+
* **Seamless Data & State Sharing**: All open windows remain synchronized, sharing the same data and application state
|
18
|
+
in real-time. This eliminates the need for complex inter-window communication logic, as events and data flow effortlessly
|
19
|
+
across all connected contexts.
|
20
|
+
|
21
|
+
* **Rich User Experiences**: Beyond data analysis, this capability is transformative for applications like:
|
22
|
+
* **Creative Suites**: Designers working with multiple canvases or tool palettes.
|
23
|
+
* **Control Centers**: Operators monitoring various system dashboards simultaneously.
|
24
|
+
* **Educational Platforms**: Students viewing course material, interactive exercises, and communication tools side-by-side.
|
25
|
+
* **Customer Service Desks**: Agents managing multiple customer interactions or data sources concurrently.
|
26
|
+
|
27
|
+
* **Consistent JavaScript Instances**: Components can even be moved across windows while retaining their original
|
28
|
+
JavaScript instances, ensuring continuity and preventing unnecessary re-initialization.
|
29
|
+
|
30
|
+
**Benefit**: For businesses, this translates to a significantly more powerful and intuitive user experience, leading to
|
31
|
+
increased user satisfaction, reduced training times, and the ability to handle more complex tasks efficiently. For
|
32
|
+
developers, it simplifies the creation of sophisticated multi-screen layouts, as the framework handles the underlying
|
33
|
+
communication complexities.
|
8
34
|
|
9
35
|
<details>
|
10
36
|
<summary><h3>Example</h3></summary>
|
@@ -14,7 +40,7 @@ running the code. Even though it's running in a new window, it's still part of t
|
|
14
40
|
(In this case, the app is the web site you're looking at now.) That means both the code in both windows
|
15
41
|
seamlessly share events, data, etc. — the code doesn't care that some code is running in a
|
16
42
|
separate window.
|
17
|
-
|
43
|
+
```javascript live-preview
|
18
44
|
import Button from '../button/Base.mjs';
|
19
45
|
import Container from '../container/Base.mjs';
|
20
46
|
|
@@ -31,6 +57,6 @@ class MainView extends Container {
|
|
31
57
|
}
|
32
58
|
|
33
59
|
MainView = Neo.setupClass(MainView);
|
34
|
-
|
60
|
+
```
|
35
61
|
|
36
62
|
</details>
|
@@ -89,13 +89,13 @@ The worst case that could happen now is that your app worker will slow down and
|
|
89
89
|
this will not affect your UI (rendering thread → main).
|
90
90
|
Probably the best solution for single page apps (SPAs) as well as multi-window apps (MWAs) looks like this:
|
91
91
|
|
92
|
-
|
92
|
+
```json neo-component
|
93
93
|
{
|
94
94
|
"cls" : "neo-worker-setup",
|
95
95
|
"tag" : "element-loader",
|
96
96
|
"vdom": {"src": "./resources/images/workers-focus.svg"}
|
97
97
|
}
|
98
|
-
|
98
|
+
```
|
99
99
|
|
100
100
|
To prevent the app worker from handling too much logic, we can optionally spawn more workers.
|
101
101
|
Each thread has its fixed scope. Let us take a quick look into each of them.
|
package/learn/benefits/Quick.md
CHANGED
@@ -1,16 +1,49 @@
|
|
1
|
-
|
1
|
+
## Rapid Application Development with Neo.mjs
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
In today's fast-paced development landscape, speed and efficiency are paramount. Neo.mjs is engineered to dramatically
|
4
|
+
accelerate the application development process, enabling teams to build high-quality web applications faster and with
|
5
|
+
less effort. This rapid development capability stems from its intuitive syntax, powerful features, and unparalleled
|
6
|
+
debugging convenience.
|
6
7
|
|
7
|
-
|
8
|
-
Neo.mjs has elegant yet powerful state management features that make it easy to create shared, bindable data.
|
9
|
-
For example, if two components are bound to the same property, a change to the property will automatically be
|
10
|
-
applied to both components.
|
8
|
+
### Property Lifecycle Hooks: Streamlined Data Flow and Validation
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
Neo.mjs classes provide sophisticated property lifecycle hooks (e.g., `beforeGet`, `beforeSet`, `afterSet`). These
|
11
|
+
allow developers to precisely control how properties are accessed, validated, transformed, and reacted to. This means
|
12
|
+
you can easily implement complex logic for data validation, computed properties, or side effects directly within the
|
13
|
+
property definition.
|
14
|
+
|
15
|
+
**Benefit**: By centralizing property logic, these hooks significantly reduce boilerplate code and the potential for
|
16
|
+
bugs. Developers spend less time writing repetitive validation or update logic and more time on core features, leading
|
17
|
+
to faster development cycles and more robust applications.
|
18
|
+
|
19
|
+
### Elegant State Management: Simplified Data Synchronization
|
20
|
+
|
21
|
+
Neo.mjs offers an elegant yet powerful approach to state management, making it effortless to create shared, bindable
|
22
|
+
data across your application. When multiple components are bound to the same data property, any change to that property
|
23
|
+
is automatically and reactively applied to all bound components.
|
24
|
+
|
25
|
+
**Benefit**: This eliminates the complexities of manual data synchronization and prop drilling, common pain points in
|
26
|
+
other frameworks. Developers can build highly interactive UIs with confidence, knowing that data consistency is handled
|
27
|
+
automatically. This translates to faster feature implementation, reduced debugging time, and a more predictable application
|
28
|
+
state, ultimately accelerating time-to-market.
|
29
|
+
|
30
|
+
### Simple and Powerful Debugging: Instant Feedback and Control
|
31
|
+
|
32
|
+
Debugging in Neo.mjs is exceptionally straightforward and efficient. Leveraging standard JavaScript, the intuitive
|
33
|
+
Neo.mjs class config system, and built-in debugging tools, developers gain unprecedented control and insight into their
|
34
|
+
applications. For instance, during development, you can directly select any component in the browser's developer console,
|
35
|
+
inspect its properties, and even update its reactive configurations on the fly. These changes are immediately reflected
|
36
|
+
in the running application.
|
37
|
+
|
38
|
+
**Benefit**: This live interaction and direct manipulation capability drastically reduces the debugging cycle. Developers
|
39
|
+
can quickly pinpoint issues, experiment with different states, and validate changes without constant recompilations or
|
40
|
+
reloads. This leads to a significantly more productive and less frustrating development experience, allowing teams to
|
41
|
+
resolve issues faster and deliver features more reliably.
|
42
|
+
|
43
|
+
## Conclusion: Accelerating Your Development Workflow
|
44
|
+
|
45
|
+
Neo.mjs's focus on streamlined property management, elegant state synchronization, and powerful debugging tools collectively
|
46
|
+
contributes to a development workflow that is both rapid and enjoyable. By minimizing common development hurdles, Neo.mjs
|
47
|
+
empowers teams to deliver high-quality, performant web applications with unprecedented speed and efficiency, providing a
|
48
|
+
clear competitive advantage.
|
16
49
|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
## Seamless Communication Across Threads and Beyond
|
2
|
+
|
3
|
+
In a multi-threaded architecture like Neo.mjs, efficient and seamless communication between different execution contexts
|
4
|
+
(Web Workers, Main Thread, and even backend services) is paramount. The Neo.mjs Remote Procedure Call (RPC) Layer
|
5
|
+
provides a powerful abstraction that simplifies this complex inter-thread and inter-process communication, allowing
|
6
|
+
developers to invoke methods on remote objects as if they were local.
|
7
|
+
|
8
|
+
### Abstracting Cross-Worker Communication
|
9
|
+
|
10
|
+
At its core, the RPC Layer eliminates the need for developers to manually handle `postMessage` calls, message parsing,
|
11
|
+
and promise resolution when communicating between Web Workers. Whether it's your App Worker interacting with the VDom
|
12
|
+
Worker to update the UI, or with the Data Worker to fetch and process information, the RPC Layer provides a clean,
|
13
|
+
promise-based API.
|
14
|
+
|
15
|
+
**Benefit**: This abstraction significantly reduces boilerplate code and cognitive load. Developers can focus on the
|
16
|
+
business logic of their application rather than the intricacies of message passing between threads. This leads to faster
|
17
|
+
development, more readable code, and fewer errors related to inter-thread communication.
|
18
|
+
|
19
|
+
### Extending to Backend Integration
|
20
|
+
|
21
|
+
The power of the Neo.mjs RPC Layer extends beyond just inter-worker communication within the browser. It provides a
|
22
|
+
consistent mechanism for interacting with backend services. This means the same patterns and mental model used for
|
23
|
+
communicating with a Data Worker can be applied to making API calls to your server.
|
24
|
+
|
25
|
+
**Benefit**: A unified approach to both frontend inter-thread communication and backend integration streamlines the
|
26
|
+
development process. It reduces the learning curve for new team members and ensures consistency in how data and
|
27
|
+
commands are exchanged across the entire application stack.
|
28
|
+
|
29
|
+
### Key Advantages:
|
30
|
+
|
31
|
+
* **Simplicity**: Invoke remote methods with a simple function call, receiving a promise that resolves with the result.
|
32
|
+
The RPC Layer handles serialization, deserialization, and message routing automatically.
|
33
|
+
* **Reduced Boilerplate**: Eliminates the need for manual message listeners, dispatchers, and complex state management
|
34
|
+
around asynchronous operations.
|
35
|
+
* **Improved Readability & Maintainability**: Code becomes cleaner and easier to understand, as the underlying
|
36
|
+
communication mechanism is abstracted away.
|
37
|
+
* **Performance**: Designed for efficiency, the RPC Layer ensures that inter-thread communication is as performant as
|
38
|
+
possible, minimizing overhead and contributing to the overall responsiveness of Neo.mjs applications.
|
39
|
+
* **Error Handling**: Provides robust error propagation across thread boundaries, making it easier to debug and handle
|
40
|
+
issues that arise during remote method invocations.
|
41
|
+
|
42
|
+
### Conceptual Example: Consistent API for Internal and External Calls
|
43
|
+
|
44
|
+
Imagine calling a method on a data service defined within the Data Worker realm (e.g., `MyApp.data.UserService`) from your App Worker:
|
45
|
+
|
46
|
+
```javascript readonly
|
47
|
+
// In your App Worker code
|
48
|
+
const userData = await MyApp.data.UserService.fetchUser(userId);
|
49
|
+
console.log(userData);
|
50
|
+
```
|
51
|
+
|
52
|
+
Now, consider triggering a backend request using the same RPC pattern, as seen in `apps/colors/view/ViewportController.mjs`:
|
53
|
+
|
54
|
+
```javascript readonly
|
55
|
+
// In apps/colors/view/ViewportController.mjs
|
56
|
+
response = await Colors.backend.ColorService.read({
|
57
|
+
amountColors : stateProvider.getData('amountColors'),
|
58
|
+
amountColumns: stateProvider.getData('amountColumns'),
|
59
|
+
amountRows : stateProvider.getData('amountRows')
|
60
|
+
});
|
61
|
+
```
|
62
|
+
|
63
|
+
Notice how the syntax for invoking a method on a backend service (`Colors.backend.ColorService.read`) is virtually
|
64
|
+
identical to invoking a method on an internal worker service (`Neo.worker.Data.getService('UserService').fetchUser`).
|
65
|
+
This consistency is a core strength of the Neo.mjs RPC Layer.
|
66
|
+
|
67
|
+
Behind the scenes, for both internal and external remote calls, the RPC Layer handles:
|
68
|
+
1. Serializing the method call and arguments.
|
69
|
+
2. Sending a message to the target (worker or backend).
|
70
|
+
3. The target receiving the message, invoking the method.
|
71
|
+
4. Serializing the result and sending it back.
|
72
|
+
5. Resolving the promise in the caller with the received data.
|
73
|
+
|
74
|
+
This powerful abstraction is a cornerstone of Neo.mjs's multi-threaded architecture, enabling developers to build
|
75
|
+
complex, highly responsive, and scalable applications with remarkable ease.
|
package/learn/benefits/Speed.md
CHANGED
@@ -1,15 +1,20 @@
|
|
1
|
-
The Neo.mjs web
|
1
|
+
The Neo.mjs architecture leverages web workers to run application logic, data processing,
|
2
|
+
and even parts of the rendering pipeline in parallel, on separate CPU cores.
|
3
|
+
This offloads heavy computations from the main thread, ensuring the UI remains responsive.
|
2
4
|
|
3
|
-
By contrast, other JavaScript frameworks
|
4
|
-
data handling, and DOM rendering compete for CPU resources
|
5
|
+
By contrast, most other JavaScript frameworks operate predominantly within a single main thread.
|
6
|
+
This means all business logic, data handling, and DOM rendering compete for the same CPU resources,
|
7
|
+
often leading to a "janky" or unresponsive user interface during intensive operations.
|
5
8
|
|
6
|
-
This
|
7
|
-
particularly beneficial for processor- and data-intensive applications,
|
8
|
-
|
9
|
-
easily apply over 20,000 DOM updates per second
|
9
|
+
This multi-threaded approach allows Neo.mjs applications to run and render significantly faster.
|
10
|
+
This is particularly beneficial for processor- and data-intensive applications, as well as those
|
11
|
+
requiring rapid UI updates. In internal testing, Neo.mjs applications have consistently
|
12
|
+
demonstrated the ability to easily apply over 20,000 DOM updates per second without
|
13
|
+
compromising user experience.
|
10
14
|
|
11
|
-
|
12
|
-
to
|
15
|
+
Should your application demand even greater parallel processing power, Neo.mjs provides the
|
16
|
+
flexibility to launch additional web worker threads to handle specialized logic or
|
17
|
+
further distribute computational load.
|
13
18
|
|
14
19
|
|
15
20
|
<details><summary>Example</summary>
|
@@ -20,7 +25,7 @@ Click on Preview, then use your mouse or trackpad to pan and zoom — the he
|
|
20
25
|
If you move quickly, you might reach 20,000 or 30,000 delta updates per second. We've seen some examples that go over 40,000 updates per
|
21
26
|
second — but we've never actually hit the limit.
|
22
27
|
|
23
|
-
|
28
|
+
```javascript live-preview
|
24
29
|
import Container from '../container/Base.mjs';
|
25
30
|
import Helix from '../component/Helix.mjs';
|
26
31
|
|
@@ -43,7 +48,7 @@ class MainView extends Container {
|
|
43
48
|
}
|
44
49
|
}
|
45
50
|
MainView = Neo.setupClass(MainView);
|
46
|
-
|
51
|
+
```
|
47
52
|
|
48
53
|
|
49
54
|
If you're interested, there's <a href="../../examples/component/helix/index.html" target="_blank">a more full-featured helix example</a> that includes showing delta updates,
|
@@ -3,7 +3,7 @@ Neo has a feature that allows shared, bindable, data.
|
|
3
3
|
A _state provider_ — `Neo.state.Provider` — instance holds properties that
|
4
4
|
can be bound to component properties.
|
5
5
|
|
6
|
-
|
6
|
+
```javascript live-preview
|
7
7
|
import Container from '../container/Base.mjs';
|
8
8
|
import Label from '../component/Label.mjs';
|
9
9
|
import TextField from '../form/field/Text.mjs';
|
@@ -35,7 +35,7 @@ class MainView extends Container {
|
|
35
35
|
}
|
36
36
|
}
|
37
37
|
MainView = Neo.setupClass(MainView);
|
38
|
-
|
38
|
+
```
|
39
39
|
|
40
40
|
View model properties are visible down the containment hierarchy:
|
41
41
|
Properties introduced in a parent container will be available to any child component, and properties
|
@@ -55,7 +55,7 @@ usually coded as separate classes.)
|
|
55
55
|
|
56
56
|
Below is another example.
|
57
57
|
|
58
|
-
|
58
|
+
```javascript live-preview
|
59
59
|
import Container from '../container/Base.mjs';
|
60
60
|
import Label from '../component/Label.mjs';
|
61
61
|
import Panel from '../container/Panel.mjs';
|
@@ -107,7 +107,7 @@ class MainView extends Container {
|
|
107
107
|
}
|
108
108
|
}
|
109
109
|
MainView = Neo.setupClass(MainView);
|
110
|
-
|
110
|
+
```
|
111
111
|
|
112
112
|
In this case, the main view has three child items of type `MyPanel`, each containing a label.
|
113
113
|
The main view has a state provider with a `foo` property, and the third child has its own state provider with a `foo` property.
|
@@ -17,7 +17,7 @@ Here's an example of a new component class `Simple` with three config properties
|
|
17
17
|
The `Simple` class introduces syntax. It doesn't have any content, so if you run the code you won't
|
18
18
|
see anything. We'll change that in the next example.
|
19
19
|
|
20
|
-
|
20
|
+
```javascript live-preview
|
21
21
|
import Component from '../component/Base.mjs';
|
22
22
|
import Container from '../container/Base.mjs';
|
23
23
|
|
@@ -48,7 +48,7 @@ class MainView extends Container {
|
|
48
48
|
}
|
49
49
|
}
|
50
50
|
MainView = Neo.setupClass(MainView);
|
51
|
-
|
51
|
+
```
|
52
52
|
|
53
53
|
## Detecting when a value changes
|
54
54
|
|
@@ -57,7 +57,7 @@ a _lifecyle property_. A lifecycle property provides methods that are run as the
|
|
57
57
|
updated or accessed. You're free to implment these methods to provide business rules, normalize
|
58
58
|
values, or have side-effects, such as updating a view or firing an event.
|
59
59
|
|
60
|
-
|
60
|
+
```javascript live-preview
|
61
61
|
import Component from '../component/Base.mjs';
|
62
62
|
import Container from '../container/Base.mjs';
|
63
63
|
|
@@ -98,7 +98,7 @@ class MainView extends Container {
|
|
98
98
|
}
|
99
99
|
}
|
100
100
|
MainView = Neo.setupClass(MainView);
|
101
|
-
|
101
|
+
```
|
102
102
|
|
103
103
|
This time if you run the code you'll see "hi there" in the view. That's because the Simple instance is
|
104
104
|
configured with `bar: 'hi there'`, and since that's a lifecycle property the `afterSetBar()` method
|
@@ -110,7 +110,7 @@ Typically, the _afterSet_ method is used to update a view or to fire an event.
|
|
110
110
|
|
111
111
|
Look at this code: `afterSetBar()` fires an event, and the config in the `items[]` is listening to it.
|
112
112
|
|
113
|
-
|
113
|
+
```javascript live-preview
|
114
114
|
import Component from '../component/Base.mjs';
|
115
115
|
import Container from '../container/Base.mjs';
|
116
116
|
|
@@ -149,5 +149,5 @@ class MainView extends Container {
|
|
149
149
|
}
|
150
150
|
}
|
151
151
|
MainView = Neo.setupClass(MainView);
|
152
|
-
|
152
|
+
```
|
153
153
|
|