neo.mjs 10.0.0-alpha.3 → 10.0.0-alpha.5
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/CODING_GUIDELINES.md +1 -1
- package/README.md +52 -11
- package/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/blog/List.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/learn/ContentComponent.mjs +2 -1
- package/apps/portal/view/learn/MainContainerStateProvider.mjs +3 -6
- package/apps/realworld/view/HomeComponent.mjs +1 -1
- package/apps/realworld/view/user/ProfileComponent.mjs +1 -1
- package/apps/sharedcovid/view/MainContainerController.mjs +1 -1
- package/apps/shareddialog/view/MainContainerController.mjs +2 -2
- package/buildScripts/buildThemes.mjs +1 -1
- package/examples/grid/animatedRowSorting/Viewport.mjs +4 -4
- package/examples/grid/bigData/ControlsContainer.mjs +3 -3
- package/examples/grid/bigData/GridContainer.mjs +8 -8
- package/examples/grid/cellEditing/MainContainer.mjs +5 -5
- package/examples/grid/container/MainContainer.mjs +4 -4
- package/examples/grid/nestedRecordFields/Viewport.mjs +5 -5
- package/learn/README.md +83 -0
- package/learn/guides/ApplicationBootstrap.md +352 -0
- package/learn/guides/DeclarativeComponentTreesVsImperativeVdom.md +500 -0
- package/learn/guides/WorkingWithVDom.md +748 -0
- package/learn/tree.json +53 -0
- package/package.json +2 -2
- package/resources/scss/src/grid/{View.scss → Body.scss} +2 -2
- package/resources/scss/src/grid/VerticalScrollbar.scss +1 -1
- package/resources/scss/src/grid/plugin/AnimateRows.scss +1 -1
- package/resources/scss/src/grid/plugin/CellEditing.scss +1 -1
- package/resources/scss/theme-dark/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-light/grid/{View.scss → Body.scss} +1 -1
- package/resources/scss/theme-neo-light/grid/{View.scss → Body.scss} +1 -1
- package/src/DefaultConfig.mjs +27 -14
- package/src/Main.mjs +1 -1
- package/src/Neo.mjs +16 -0
- package/src/button/Base.mjs +2 -2
- package/src/calendar/view/MainContainerStateProvider.mjs +1 -1
- package/src/grid/{View.mjs → Body.mjs} +17 -17
- package/src/grid/Container.mjs +58 -58
- package/src/grid/ScrollManager.mjs +56 -56
- package/src/grid/VerticalScrollbar.mjs +2 -2
- package/src/grid/_export.mjs +2 -2
- package/src/grid/column/AnimatedChange.mjs +5 -5
- package/src/grid/column/Base.mjs +1 -1
- package/src/grid/column/Component.mjs +6 -6
- package/src/grid/header/Button.mjs +1 -1
- package/src/grid/header/Toolbar.mjs +9 -9
- package/src/grid/plugin/AnimateRows.mjs +1 -2
- package/src/layout/Cube.mjs +2 -2
- package/src/main/DeltaUpdates.mjs +11 -10
- package/src/main/addon/Navigator.mjs +1 -1
- package/src/main/addon/WindowPosition.mjs +1 -1
- package/src/main/render/StringBasedRenderer.mjs +1 -1
- package/src/tab/header/Toolbar.mjs +1 -1
- package/src/table/header/Button.mjs +1 -1
- package/src/toolbar/Base.mjs +1 -1
- package/src/util/Style.mjs +2 -6
- package/src/util/VDom.mjs +1 -1
- package/src/util/VNode.mjs +1 -1
- package/src/vdom/Helper.mjs +96 -49
- package/src/vdom/VNode.mjs +38 -2
- package/src/worker/App.mjs +8 -19
- package/src/worker/Base.mjs +87 -5
- package/src/worker/Manager.mjs +90 -36
- package/resources/data/deck/learnneo/tree.json +0 -50
- package/resources/data/deck/whyneo.md +0 -80
- /package/{resources/data/deck/learnneo/pages → learn}/Glossary.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/UsingTheseTopics.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/ConfigSystem.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Effort.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Features.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/FormsEngine.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/FourEnvironments.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Introduction.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/MultiWindow.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/OffTheMainThread.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Quick.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/benefits/Speed.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/ComponentModels.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Config.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/DescribingTheUI.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Events.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Extending.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/References.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Setup.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/gettingstarted/Workspaces.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/ComponentsAndContainers.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/CustomComponents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Forms.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/InstanceLifecycle.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Layouts.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MainThreadAddonExample.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MainThreadAddonIntro.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Mixins.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/MultiWindow.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/PortalApp.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/StateProviders.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/Tables.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/events/CustomEvents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/guides/events/DomEvents.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/ClassFeatures.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Classes.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/NewNode.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Overrides.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/javascript/Super.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/Earthquakes.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/RSP.md +0 -0
- /package/{resources/data/deck/learnneo/pages → learn}/tutorials/TodoList.md +0 -0
- /package/resources/data/{deck/learnneo/data/theBeatles.json → theBeatles.json} +0 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
# Neo.mjs Application Bootstrap Process
|
2
|
+
|
3
|
+
This guide explains how Neo.mjs applications start, initialize, and come to life - from the initial HTML file to your
|
4
|
+
first rendered component.
|
5
|
+
|
6
|
+
## Overview
|
7
|
+
|
8
|
+
When you run a Neo.mjs application in the browser, a sophisticated multi-threaded orchestration happens behind the scenes.
|
9
|
+
Unlike traditional web frameworks that run everything on the main thread, Neo.mjs distributes work across multiple threads
|
10
|
+
using Web Workers.
|
11
|
+
|
12
|
+
> **Note:** For a deeper understanding of Neo.mjs's multi-threaded architecture, see the
|
13
|
+
> [Off The Main Thread](../benefits/OffTheMainThread.md) guide.
|
14
|
+
|
15
|
+
## Bootstrap Sequence
|
16
|
+
|
17
|
+
```
|
18
|
+
myapp/
|
19
|
+
├── view/
|
20
|
+
│ └── Viewport.mjs // The app main view
|
21
|
+
├── app.mjs // The entry-point for your code inside the app worker
|
22
|
+
├── index.html // The entry-point for a main-thread
|
23
|
+
└── neo-config.json // Framework global configs for your app
|
24
|
+
```
|
25
|
+
|
26
|
+
### 1. Entry Point: index.html
|
27
|
+
|
28
|
+
The bootstrap process begins with a minimal HTML file:
|
29
|
+
|
30
|
+
```html
|
31
|
+
<!DOCTYPE HTML>
|
32
|
+
<html>
|
33
|
+
<head>
|
34
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
35
|
+
<meta charset="UTF-8">
|
36
|
+
<title>My Neo.mjs App</title>
|
37
|
+
</head>
|
38
|
+
<body>
|
39
|
+
<script src="../../src/MicroLoader.mjs" type="module"></script>
|
40
|
+
</body>
|
41
|
+
</html>
|
42
|
+
```
|
43
|
+
|
44
|
+
The only JavaScript file imported is the `MicroLoader.mjs`, which is loaded as an ES module.
|
45
|
+
|
46
|
+
> **Note:** You don't need to create these files manually. Neo.mjs provides CLI tools to generate the basic
|
47
|
+
> application structure. You can use `npm run create-app` inside the framework repo or `npx neo-app` to generate
|
48
|
+
> a workspace with the same structure.
|
49
|
+
|
50
|
+
### 2. MicroLoader: Configuration Loading
|
51
|
+
|
52
|
+
The `MicroLoader.mjs` is a small script that fetches the application configuration and bootstraps the main thread:
|
53
|
+
|
54
|
+
```javascript
|
55
|
+
fetch('./neo-config.json').then(r => r.json()).then(d => {
|
56
|
+
globalThis.Neo = {config: {...d}};
|
57
|
+
import(d.mainPath)
|
58
|
+
})
|
59
|
+
```
|
60
|
+
|
61
|
+
It performs these steps:
|
62
|
+
1. Fetches the `neo-config.json` file from the current directory
|
63
|
+
2. Parses the JSON response
|
64
|
+
3. Creates a global `Neo` object with the `config` property set to the parsed JSON
|
65
|
+
4. Dynamically imports the module specified by the `mainPath` property from the config
|
66
|
+
|
67
|
+
### 3. Configuration: neo-config.json
|
68
|
+
|
69
|
+
The `neo-config.json` file contains essential configuration for the application bootstrap. For a complete overview
|
70
|
+
of all available configuration options, you can refer to the `src/DefaultConfig.mjs` file in the Neo.mjs framework:
|
71
|
+
|
72
|
+
```json
|
73
|
+
{
|
74
|
+
"appPath" : "apps/myapp/app.mjs",
|
75
|
+
"basePath" : "../../",
|
76
|
+
"environment" : "development",
|
77
|
+
"mainPath" : "./Main.mjs",
|
78
|
+
"mainThreadAddons": ["DragDrop", "Navigator", "Stylesheet"],
|
79
|
+
"themes" : ["neo-theme-light"],
|
80
|
+
"useCanvasWorker" : false,
|
81
|
+
"useDataWorker" : false,
|
82
|
+
"useServiceWorker": false,
|
83
|
+
"useSharedWorkers": false,
|
84
|
+
"useTaskWorker" : false,
|
85
|
+
"useVdomWorker" : true,
|
86
|
+
"workerBasePath" : "../../src/worker/"
|
87
|
+
}
|
88
|
+
```
|
89
|
+
|
90
|
+
**Key Configuration Properties:**
|
91
|
+
- **`appPath`** - Points to your application's entry point (app.mjs)
|
92
|
+
- **`basePath`** - Root path for resolving other paths
|
93
|
+
- **`environment`** - Controls optimization and debugging features
|
94
|
+
- **`mainPath`** - Framework's main thread bootstrap file
|
95
|
+
- **`mainThreadAddons`** - Additional features to load in the main thread
|
96
|
+
- **`themes`** - CSS themes to load
|
97
|
+
- **`useCanvasWorker`** - Controls whether to use a separate worker for canvas operations
|
98
|
+
- **`useDataWorker`** - Controls whether to use a separate worker for data operations
|
99
|
+
- **`useServiceWorker`** - Controls whether to use a service worker for caching
|
100
|
+
- **`useSharedWorkers`** - When set to true, ALL workers (App, VDom, Data, etc.) will be created as SharedWorkers,
|
101
|
+
enabling multi-window applications. When false, all workers will be dedicated workers (better for single-page applications).
|
102
|
+
The `worker.Base` class provides an abstraction layer that supports both types with a consistent API, allowing developers
|
103
|
+
to create an app with dedicated workers first (which are easier to debug) and then switch to shared workers with just
|
104
|
+
a one-line configuration change.
|
105
|
+
- **`useTaskWorker`** - Controls whether to use a separate worker for background tasks
|
106
|
+
- **`useVdomWorker`** - Controls whether to use a separate worker for virtual DOM operations
|
107
|
+
- **`workerBasePath`** - Location of worker initialization files
|
108
|
+
|
109
|
+
**Configuration Categories:**
|
110
|
+
- **Path Resolution** - Where to find files and modules (auto-generated by default)
|
111
|
+
- **Worker Settings** - Which workers to use and how they should be configured
|
112
|
+
- **Theme Management** - CSS themes to load
|
113
|
+
- **Addon Loading** - Additional main thread features to load
|
114
|
+
|
115
|
+
### 4. Main Thread Initialization
|
116
|
+
|
117
|
+
The MicroLoader imports `Main.mjs`, which initializes the main thread:
|
118
|
+
|
119
|
+
```javascript
|
120
|
+
import Neo from './Neo.mjs';
|
121
|
+
import * as core from './core/_export.mjs';
|
122
|
+
import DomAccess from './main/DomAccess.mjs';
|
123
|
+
import DeltaUpdates from './main/DeltaUpdates.mjs';
|
124
|
+
import DomEvents from './main/DomEvents.mjs';
|
125
|
+
import Observable from './core/Observable.mjs';
|
126
|
+
import WorkerManager from './worker/Manager.mjs';
|
127
|
+
|
128
|
+
class Main extends core.Base {
|
129
|
+
// ...
|
130
|
+
|
131
|
+
construct(config) {
|
132
|
+
super.construct(config);
|
133
|
+
|
134
|
+
let me = this;
|
135
|
+
|
136
|
+
WorkerManager.on({
|
137
|
+
'automount' : me.onRender,
|
138
|
+
'message:mountDom' : me.onMountDom,
|
139
|
+
'message:updateDom': me.onUpdateDom,
|
140
|
+
'updateVdom' : me.onUpdateVdom,
|
141
|
+
scope : me
|
142
|
+
});
|
143
|
+
|
144
|
+
DomEvents.on('domContentLoaded', me.onDomContentLoaded, me);
|
145
|
+
|
146
|
+
if (document.readyState !== 'loading') {
|
147
|
+
DomEvents.onDomContentLoaded()
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
// ...
|
152
|
+
}
|
153
|
+
```
|
154
|
+
|
155
|
+
The Main class:
|
156
|
+
1. Imports the WorkerManager and other core modules
|
157
|
+
2. Sets up event listeners for worker messages
|
158
|
+
3. Listens for the 'domContentLoaded' event
|
159
|
+
4. When the DOM is loaded, it loads any main thread addons and notifies the WorkerManager
|
160
|
+
|
161
|
+
### 5. Neo.worker.Manager: Creating Workers
|
162
|
+
|
163
|
+
```javascript
|
164
|
+
class Manager extends core.Base {
|
165
|
+
// ...
|
166
|
+
|
167
|
+
createWorkers() {
|
168
|
+
let me = this,
|
169
|
+
config = Neo.clone(NeoConfig, true),
|
170
|
+
{hash, href, search} = location,
|
171
|
+
{windowId} = me,
|
172
|
+
key, value;
|
173
|
+
|
174
|
+
// Configure the workers
|
175
|
+
// ...
|
176
|
+
|
177
|
+
for ([key, value] of Object.entries(me.workers)) {
|
178
|
+
if (key === 'canvas' && !config.useCanvasWorker ||
|
179
|
+
key === 'task' && !config.useTaskWorker ||
|
180
|
+
key === 'vdom' && !config.useVdomWorker
|
181
|
+
) {
|
182
|
+
continue
|
183
|
+
}
|
184
|
+
|
185
|
+
try {
|
186
|
+
value.worker = me.createWorker(value)
|
187
|
+
} catch (e) {
|
188
|
+
document.body.innerHTML = e;
|
189
|
+
me.stopCommunication = true;
|
190
|
+
break
|
191
|
+
}
|
192
|
+
|
193
|
+
me.sendMessage(key, {
|
194
|
+
action: 'registerNeoConfig',
|
195
|
+
data : {...config, windowId}
|
196
|
+
})
|
197
|
+
}
|
198
|
+
}
|
199
|
+
|
200
|
+
onWorkerConstructed(data) {
|
201
|
+
let me = this;
|
202
|
+
|
203
|
+
me.constructedThreads++;
|
204
|
+
|
205
|
+
if (me.constructedThreads === me.activeWorkers) {
|
206
|
+
// All workers are constructed, load the application
|
207
|
+
NeoConfig.appPath && me.timeout(NeoConfig.loadApplicationDelay).then(() => {
|
208
|
+
me.loadApplication()
|
209
|
+
})
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
loadApplication() {
|
214
|
+
this.sendMessage('app', {action: 'loadApplication' })
|
215
|
+
}
|
216
|
+
|
217
|
+
// ...
|
218
|
+
}
|
219
|
+
```
|
220
|
+
|
221
|
+
`Neo.worker.Manager`:
|
222
|
+
1. Detects browser features (Web Workers, SharedWorkers)
|
223
|
+
2. Creates workers for App, VDom, Data, etc. based on configuration
|
224
|
+
3. Sends the Neo.config to each worker
|
225
|
+
4. When all workers are constructed, it loads the application by sending a message to the App worker
|
226
|
+
|
227
|
+
### 6. App Worker: Loading the Application
|
228
|
+
|
229
|
+
The App worker receives the 'loadApplication' message and loads the application. It's important to note that an "App"
|
230
|
+
in Neo.mjs is an instance of Neo.controller.Application, which is not common in other frameworks like React, Angular,
|
231
|
+
or Vue (which typically just use a tag):
|
232
|
+
|
233
|
+
```javascript
|
234
|
+
class App extends Base {
|
235
|
+
// ...
|
236
|
+
|
237
|
+
onLoadApplication(data) {
|
238
|
+
let me = this,
|
239
|
+
{config} = Neo,
|
240
|
+
app, path;
|
241
|
+
|
242
|
+
if (data) {
|
243
|
+
me.data = data;
|
244
|
+
config.resourcesPath = data.resourcesPath
|
245
|
+
}
|
246
|
+
|
247
|
+
path = me.data.path;
|
248
|
+
|
249
|
+
if (config.environment !== 'development') {
|
250
|
+
path = path.startsWith('/') ? path.substring(1) : path
|
251
|
+
}
|
252
|
+
|
253
|
+
me.importApp(path).then(module => {
|
254
|
+
app = module.onStart();
|
255
|
+
|
256
|
+
// short delay to ensure Component Controllers are ready
|
257
|
+
config.hash && me.timeout(5).then(() => {
|
258
|
+
HashHistory.push(config.hash);
|
259
|
+
})
|
260
|
+
})
|
261
|
+
}
|
262
|
+
|
263
|
+
importApp(path) {
|
264
|
+
if (path.endsWith('.mjs')) {
|
265
|
+
path = path.slice(0, -4)
|
266
|
+
}
|
267
|
+
|
268
|
+
return import(`../../${path}.mjs`)
|
269
|
+
}
|
270
|
+
|
271
|
+
// ...
|
272
|
+
}
|
273
|
+
```
|
274
|
+
|
275
|
+
The App worker:
|
276
|
+
1. Receives the 'loadApplication' message with the path to the application
|
277
|
+
2. Calls importApp(path) to dynamically import the application module
|
278
|
+
3. When the module is loaded, it calls the onStart method of the module
|
279
|
+
4. If there's a hash in the config, it pushes it to the HashHistory after a short delay
|
280
|
+
|
281
|
+
### 7. Application Entry Point: app.mjs
|
282
|
+
|
283
|
+
Finally, the application's `app.mjs` file is loaded and executed:
|
284
|
+
|
285
|
+
```javascript
|
286
|
+
import Overwrites from './Overwrites.mjs'; // Optional class config default value changes for framework classes
|
287
|
+
import Viewport from './view/Viewport.mjs'; // Your main UI component
|
288
|
+
|
289
|
+
export const onStart = () => Neo.app({
|
290
|
+
mainView: Viewport, // Root component of your application
|
291
|
+
name : 'MyApp' // Application identifier
|
292
|
+
})
|
293
|
+
```
|
294
|
+
|
295
|
+
The app.mjs file:
|
296
|
+
1. Imports any overwrites and the main view (Viewport)
|
297
|
+
2. Exports an onStart function that creates a new Neo application
|
298
|
+
3. The application is configured with a main view and a name
|
299
|
+
|
300
|
+
### 8. Component Tree Construction
|
301
|
+
|
302
|
+
When Neo.app() is called, it creates an Application controller and instantiates your mainView component:
|
303
|
+
|
304
|
+
```javascript
|
305
|
+
// Your Viewport component
|
306
|
+
class Viewport extends Container {
|
307
|
+
static config = {
|
308
|
+
className: 'MyApp.view.Viewport',
|
309
|
+
layout: 'vbox',
|
310
|
+
items: [
|
311
|
+
HeaderComponent, // Child components
|
312
|
+
MainContainer, // All created in App Worker
|
313
|
+
FooterComponent
|
314
|
+
]
|
315
|
+
}
|
316
|
+
}
|
317
|
+
```
|
318
|
+
|
319
|
+
The component instantiation process:
|
320
|
+
1. Viewport is created in the App Worker
|
321
|
+
2. Child components are instantiated recursively
|
322
|
+
3. Event listeners are attached via the framework's event system
|
323
|
+
4. Data bindings are established for reactive updates
|
324
|
+
|
325
|
+
### 9. VDom Generation and Initial Render
|
326
|
+
|
327
|
+
Once the component tree is built:
|
328
|
+
|
329
|
+
1. Each component generates its virtual DOM structure
|
330
|
+
2. The framework builds a complete virtual DOM tree
|
331
|
+
3. The VDom Worker calculates the initial DOM structure
|
332
|
+
4. Relevant CSS files will get lazy-loaded before the DOM is touched to avoid reflows
|
333
|
+
5. The Main Thread creates the actual DOM elements
|
334
|
+
6. The event system is activated
|
335
|
+
|
336
|
+
## Summary
|
337
|
+
|
338
|
+
The Neo.mjs application bootstrap process follows these key steps:
|
339
|
+
|
340
|
+
1. **index.html** loads the MicroLoader
|
341
|
+
2. **MicroLoader.mjs** fetches the configuration and imports Neo.Main
|
342
|
+
3. **Neo.Main** initializes the main thread and creates the Neo.worker.Manager
|
343
|
+
4. **Neo.worker.Manager** creates the workers (Neo.worker.App, VDom, Data, etc.)
|
344
|
+
5. When all workers are constructed, Neo.worker.Manager sends a 'loadApplication' message to the Neo.worker.App worker
|
345
|
+
6. **Neo.worker.App** receives the message and dynamically imports the application module
|
346
|
+
7. **app.mjs** is executed, and its onStart function creates the application
|
347
|
+
8. **Component Tree** is constructed in the Neo.worker.App worker
|
348
|
+
9. **VDom Generation and Rendering** processes vdom changes: App Worker sends vdom to VDom Worker, which calculates deltas,
|
349
|
+
and Main Thread applies these deltas to the DOM
|
350
|
+
|
351
|
+
This multi-threaded architecture allows your application code to run in either a dedicated or shared Neo.worker.App worker,
|
352
|
+
completely separate from DOM manipulation, providing better performance and responsiveness.
|