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
package/src/worker/Manager.mjs
CHANGED
@@ -27,11 +27,6 @@ class Manager extends Base {
|
|
27
27
|
* @protected
|
28
28
|
*/
|
29
29
|
className: 'Neo.worker.Manager',
|
30
|
-
/**
|
31
|
-
* @member {Boolean} singleton=true
|
32
|
-
* @protected
|
33
|
-
*/
|
34
|
-
singleton: true,
|
35
30
|
/**
|
36
31
|
* @member {Number} activeWorkers=0
|
37
32
|
* @protected
|
@@ -51,12 +46,29 @@ class Manager extends Base {
|
|
51
46
|
* @member {String[]|Neo.core.Base[]|null} mixins=[Observable, RemoteMethodAccess]
|
52
47
|
*/
|
53
48
|
mixins: [Observable, RemoteMethodAccess],
|
49
|
+
/**
|
50
|
+
* Remote method access for other workers
|
51
|
+
* @member {Object} remote
|
52
|
+
* @protected
|
53
|
+
*/
|
54
|
+
remote: {
|
55
|
+
app : ['setNeoConfig'],
|
56
|
+
canvas: ['setNeoConfig'],
|
57
|
+
data : ['setNeoConfig'],
|
58
|
+
task : ['setNeoConfig'],
|
59
|
+
vdom : ['setNeoConfig']
|
60
|
+
},
|
54
61
|
/**
|
55
62
|
* True in case the current browser supports window.SharedWorker.
|
56
63
|
* @member {Boolean} sharedWorkersEnabled=false
|
57
64
|
* @protected
|
58
65
|
*/
|
59
66
|
sharedWorkersEnabled: false,
|
67
|
+
/**
|
68
|
+
* @member {Boolean} singleton=true
|
69
|
+
* @protected
|
70
|
+
*/
|
71
|
+
singleton: true,
|
60
72
|
/**
|
61
73
|
* Internal flag to stop the worker communication in case their creation fails
|
62
74
|
* @member {Boolean} stopCommunication=false
|
@@ -71,7 +83,7 @@ class Manager extends Base {
|
|
71
83
|
*/
|
72
84
|
webWorkersEnabled: false,
|
73
85
|
/**
|
74
|
-
* Using the current timestamp as
|
86
|
+
* Using the current timestamp as a unique window identifier
|
75
87
|
* @member {Number} windowId=new Date().getTime()
|
76
88
|
* @protected
|
77
89
|
*/
|
@@ -121,7 +133,8 @@ class Manager extends Base {
|
|
121
133
|
|
122
134
|
!Neo.insideWorker && me.createWorkers();
|
123
135
|
|
124
|
-
Neo.
|
136
|
+
Neo.setGlobalConfig = me.setGlobalConfig.bind(me);
|
137
|
+
Neo.workerId = 'main';
|
125
138
|
|
126
139
|
me.promises = {};
|
127
140
|
|
@@ -136,18 +149,18 @@ class Manager extends Base {
|
|
136
149
|
|
137
150
|
/**
|
138
151
|
* Sends a message to each worker defined inside the this.workers config.
|
139
|
-
*
|
152
|
+
* Only sends to workers that are currently active and available.
|
153
|
+
* @param {Object} msg The message payload to broadcast.
|
154
|
+
* @param {Object} [excludeOrigin] Optionally pass the origin realm name to exclude from the broadcast.
|
140
155
|
*/
|
141
|
-
broadcast(msg) {
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
name
|
147
|
-
)) {
|
148
|
-
this.sendMessage(name, msg)
|
156
|
+
broadcast(msg, excludeOrigin) {
|
157
|
+
let me = this;
|
158
|
+
|
159
|
+
Object.keys(me.workers).forEach(name => {
|
160
|
+
if (name !== excludeOrigin && me.getWorker(name)) {
|
161
|
+
me.sendMessage(name, msg)
|
149
162
|
}
|
150
|
-
})
|
163
|
+
})
|
151
164
|
}
|
152
165
|
|
153
166
|
/**
|
@@ -257,14 +270,10 @@ class Manager extends Base {
|
|
257
270
|
}
|
258
271
|
|
259
272
|
/**
|
260
|
-
*
|
273
|
+
*
|
261
274
|
*/
|
262
|
-
loadApplication(
|
263
|
-
this.sendMessage('app', {
|
264
|
-
action : 'loadApplication',
|
265
|
-
path,
|
266
|
-
resourcesPath: NeoConfig.resourcesPath
|
267
|
-
})
|
275
|
+
loadApplication() {
|
276
|
+
this.sendMessage('app', {action: 'loadApplication' })
|
268
277
|
}
|
269
278
|
|
270
279
|
/**
|
@@ -278,7 +287,7 @@ class Manager extends Base {
|
|
278
287
|
if (me.constructedThreads === me.activeWorkers) {
|
279
288
|
// better safe than sorry => all remotes need to be registered
|
280
289
|
NeoConfig.appPath && me.timeout(NeoConfig.loadApplicationDelay).then(() => {
|
281
|
-
me.loadApplication(
|
290
|
+
me.loadApplication()
|
282
291
|
})
|
283
292
|
}
|
284
293
|
}
|
@@ -325,8 +334,10 @@ class Manager extends Base {
|
|
325
334
|
data = data.data
|
326
335
|
}
|
327
336
|
|
328
|
-
|
329
|
-
|
337
|
+
if (data) {
|
338
|
+
promise[data.reject ? 'reject' : 'resolve'](data);
|
339
|
+
delete me.promises[replyId]
|
340
|
+
}
|
330
341
|
}
|
331
342
|
}
|
332
343
|
|
@@ -385,7 +396,14 @@ class Manager extends Base {
|
|
385
396
|
|
386
397
|
return new Promise((resolve, reject) => {
|
387
398
|
let message = me.sendMessage(dest, opts, transfer),
|
388
|
-
msgId
|
399
|
+
msgId;
|
400
|
+
|
401
|
+
if (!message) {
|
402
|
+
reject(new Error(me.stopCommunication ? 'Communication is stopped.' : `Target worker '${dest}' does not exist.`));
|
403
|
+
return
|
404
|
+
}
|
405
|
+
|
406
|
+
msgId = message.id;
|
389
407
|
|
390
408
|
me.promises[msgId] = {reject, resolve}
|
391
409
|
})
|
@@ -412,7 +430,7 @@ class Manager extends Base {
|
|
412
430
|
* @param {Array} [transfer] An optional array of Transferable objects to transfer ownership of.
|
413
431
|
* If the ownership of an object is transferred, it becomes unusable (neutered) in the context it was sent from
|
414
432
|
* and becomes available only to the worker it was sent to.
|
415
|
-
* @returns {Neo.worker.Message}
|
433
|
+
* @returns {Neo.worker.Message|null}
|
416
434
|
* @protected
|
417
435
|
*/
|
418
436
|
sendMessage(dest, opts, transfer) {
|
@@ -427,17 +445,53 @@ class Manager extends Base {
|
|
427
445
|
worker = me.getWorker(dest)
|
428
446
|
}
|
429
447
|
|
430
|
-
if (
|
431
|
-
|
448
|
+
if (worker) {
|
449
|
+
opts.destination = dest;
|
450
|
+
|
451
|
+
message = new Message(opts);
|
452
|
+
|
453
|
+
(worker.port ? worker.port : worker).postMessage(message, transfer);
|
454
|
+
return message
|
432
455
|
}
|
456
|
+
}
|
433
457
|
|
434
|
-
|
458
|
+
return null
|
459
|
+
}
|
435
460
|
|
436
|
-
|
461
|
+
/**
|
462
|
+
* Initiates a global Neo.config change from the Main Thread.
|
463
|
+
*
|
464
|
+
* This method acts as a proxy, routing the config change request to the App Worker.
|
465
|
+
* This design centralizes the complex multi-threaded and multi-window synchronization
|
466
|
+
* logic within the App Worker's `setGlobalConfig` method.
|
467
|
+
*
|
468
|
+
* Developers should typically use `Neo.setGlobalConfig(config)` directly,
|
469
|
+
* which will correctly resolve to this proxy when called from the Main Thread.
|
470
|
+
*
|
471
|
+
* @param {Object} config The partial or full Neo.config object with changes to apply.
|
472
|
+
*/
|
473
|
+
setGlobalConfig(config) {
|
474
|
+
// Remotely calls the App Worker's setGlobalConfig method.
|
475
|
+
// This ensures all global config changes are processed through the App Worker
|
476
|
+
// which contains the centralized multi-window synchronization logic.
|
477
|
+
Neo.worker.App.setGlobalConfig(config)
|
478
|
+
}
|
437
479
|
|
438
|
-
|
439
|
-
|
440
|
-
|
480
|
+
/**
|
481
|
+
* Change Neo.config globally from a worker
|
482
|
+
* @param {Object} data
|
483
|
+
* @param {Boolean} data.broadcast
|
484
|
+
* @param {Object} data.config
|
485
|
+
* @param {String} [data.excludeOrigin]
|
486
|
+
*/
|
487
|
+
setNeoConfig({broadcast, config, excludeOrigin}) {
|
488
|
+
let me = this;
|
489
|
+
|
490
|
+
Neo.merge(Neo.config, config);
|
491
|
+
|
492
|
+
me.fire('neoConfigChange', config);
|
493
|
+
|
494
|
+
broadcast && me.broadcast({action: 'setNeoConfig', config}, excludeOrigin)
|
441
495
|
}
|
442
496
|
}
|
443
497
|
|
@@ -1,50 +0,0 @@
|
|
1
|
-
{"data": [
|
2
|
-
{"name": "Using These Topics", "parentId": null, "id": "UsingTheseTopics" },
|
3
|
-
{"name": "Benefits", "parentId": null, "isLeaf": false, "id": "Benefits"},
|
4
|
-
{"name": "Introduction ", "parentId": "Benefits", "id": "benefits.Introduction"},
|
5
|
-
{"name": "Off the Main Thread", "parentId": "Benefits", "id": "benefits.OffTheMainThread"},
|
6
|
-
{"name": "4 Environments", "parentId": "Benefits", "id": "benefits.FourEnvironments"},
|
7
|
-
{"name": "Unified Config System", "parentId": "Benefits", "id": "benefits.ConfigSystem"},
|
8
|
-
{"name": "Extreme Speed", "parentId": "Benefits", "id": "benefits.Speed"},
|
9
|
-
{"name": "Multi-Window Applications", "parentId": "Benefits", "id": "benefits.MultiWindow"},
|
10
|
-
{"name": "Quick Application Development", "parentId": "Benefits", "id": "benefits.Quick"},
|
11
|
-
{"name": "Complexity and Effort", "parentId": "Benefits", "id": "benefits.Effort"},
|
12
|
-
{"name": "Forms Engine", "parentId": "Benefits", "id": "benefits.FormsEngine"},
|
13
|
-
{"name": "Features and Benefits Summary", "parentId": "Benefits", "id": "benefits.Features"},
|
14
|
-
{"name": "Getting Started", "parentId": null, "isLeaf": false, "id": "GettingStarted", "collapsed": true},
|
15
|
-
{"name": "Setup", "parentId": "GettingStarted", "id": "gettingstarted.Setup"},
|
16
|
-
{"name": "Workspaces and Applications", "parentId": "GettingStarted", "id": "gettingstarted.Workspaces"},
|
17
|
-
{"name": "Describing a View", "parentId": "GettingStarted", "id": "gettingstarted.DescribingTheUI"},
|
18
|
-
{"name": "Events", "parentId": "GettingStarted", "id": "gettingstarted.Events"},
|
19
|
-
{"name": "Component References", "parentId": "GettingStarted", "id": "gettingstarted.References"},
|
20
|
-
{"name": "Extending Classes", "parentId": "GettingStarted", "id": "gettingstarted.Extending"},
|
21
|
-
{"name": "Config", "parentId": "GettingStarted", "id": "gettingstarted.Config"},
|
22
|
-
{"name": "Shared Bindable Data", "parentId": "GettingStarted", "id": "gettingstarted.ComponentModels"},
|
23
|
-
{"name": "Tutorials", "parentId": null, "isLeaf": false, "id": "Tutorials", "collapsed": true},
|
24
|
-
{"name": "Rock Scissors Paper", "parentId": "Tutorials", "id": "tutorials.RSP", "hidden": true},
|
25
|
-
{"name": "Earthquakes", "parentId": "Tutorials", "id": "tutorials.Earthquakes"},
|
26
|
-
{"name": "Todo List", "parentId": "Tutorials", "id": "tutorials.TodoList"},
|
27
|
-
{"name": "Guides", "parentId": null, "isLeaf": false, "id": "InDepth", "collapsed": true},
|
28
|
-
{"name": "Instance Lifecycle", "parentId": "InDepth", "id": "guides.InstanceLifecycle", "hidden": true},
|
29
|
-
{"name": "User Input (Forms)", "parentId": "InDepth", "id": "guides.Forms", "hidden": true},
|
30
|
-
{"name": "Component and Container Basics", "parentId": "InDepth", "id": "guides.ComponentsAndContainers"},
|
31
|
-
{"name": "Layouts", "parentId": "InDepth", "isLeaf": false, "id": "guides.Layouts", "hidden": true},
|
32
|
-
{"name": "Shared Bindable Data (State Providers)", "parentId": "InDepth", "id": "guides.StateProviders"},
|
33
|
-
{"name": "Custom Components", "parentId": "InDepth", "id": "guides.CustomComponents", "hidden": true},
|
34
|
-
{"name": "Events", "parentId": "InDepth", "isLeaf": false, "id": "GuideEvents"},
|
35
|
-
{"name": "Custom Events", "parentId": "GuideEvents", "id": "guides.events.CustomEvents"},
|
36
|
-
{"name": "DOM Events", "parentId": "GuideEvents", "id": "guides.events.DomEvents"},
|
37
|
-
{"name": "Portal App", "parentId": "InDepth", "id": "guides.PortalApp"},
|
38
|
-
{"name": "Tables (Stores)", "parentId": "InDepth", "id": "guides.Tables", "hidden": true},
|
39
|
-
{"name": "Multi-Window Applications", "parentId": "InDepth", "id": "guides.MultiWindow", "hidden": true},
|
40
|
-
{"name": "Main Thread Addons", "parentId": "InDepth", "isLeaf": false, "id": "MainThreadAddons", "hidden": true},
|
41
|
-
{"name": "Introduction", "parentId": "MainThreadAddons", "id": "guides.MainThreadAddonIntro"},
|
42
|
-
{"name": "Example", "parentId": "MainThreadAddons", "id": "guides.MainThreadAddonExample"},
|
43
|
-
{"name": "Mixins", "parentId": "InDepth", "id": "guides.Mixins", "hidden": true},
|
44
|
-
{"name": "JavaScript Classes", "parentId": null, "isLeaf": false, "id": "JavaScript", "hidden": true},
|
45
|
-
{"name": "Classes, Properties, and Methods", "parentId": "JavaScript", "id": "javascript.Classes"},
|
46
|
-
{"name": "Overriding Methods", "parentId": "JavaScript", "id": "javascript.Overrides"},
|
47
|
-
{"name": "Other JavaScript Class Features", "parentId": "JavaScript", "id": "javascript.ClassFeatures"},
|
48
|
-
{"name": "Super", "parentId": "JavaScript", "id": "javascript.Super"},
|
49
|
-
{"name": "New Node", "parentId": "JavaScript", "id": "javascript.NewNode"}
|
50
|
-
]}
|
@@ -1,80 +0,0 @@
|
|
1
|
-
|
2
|
-
#hi
|
3
|
-
|
4
|
-
|
5
|
-
Neo.mjs is a framework used to create browser-based applications.
|
6
|
-
|
7
|
-
Some key features and benefits of Neo.mjs are:
|
8
|
-
|
9
|
-
<div type="expander" caption="Multi-Threaded">
|
10
|
-
<p>
|
11
|
-
When a Neo.mjs application starts, the framework spawns three web-workers.
|
12
|
-
Web-workers are each run in their own thread. As a result, a typical Neo.mjs application
|
13
|
-
has four threads:
|
14
|
-
<ol>
|
15
|
-
<li>The _main_ thread, where DOM updates are applied
|
16
|
-
<li>An _application_ web-worker where normal application locic is run
|
17
|
-
<li>A _data_ web-worker were HTTP and socket calls are run
|
18
|
-
<li>A _view_ web-worker that manages delta updates
|
19
|
-
</ol>
|
20
|
-
</div>
|
21
|
-
|
22
|
-
<div type="expander" caption="Extreme Speed">
|
23
|
-
<p>
|
24
|
-
The Neo.mjs web-worker proccesses are automatically run in parallel, on separate CPU cores.
|
25
|
-
</p>
|
26
|
-
<p>
|
27
|
-
By contrast, other JavaScript frameworks run in a single thread. That means
|
28
|
-
in a typical framework all business logic, data handling, and DOM rendering compete for
|
29
|
-
CPU reasources.
|
30
|
-
</p>
|
31
|
-
<p>
|
32
|
-
This means Neo.mjs applications run and render faster. This is
|
33
|
-
particularly beneficial for processor- and data-intensive applications,
|
34
|
-
and applications that need to rapidly update what's viewed. In testing, Neo.mjs applications
|
35
|
-
easily apply over 20,000 DOM updates per second.
|
36
|
-
</p>
|
37
|
-
<p>
|
38
|
-
If the default four threads aren't enough, you're free to launch additional web-worker threads
|
39
|
-
to run other specialized logic.
|
40
|
-
</p>
|
41
|
-
</div>
|
42
|
-
|
43
|
-
<div type="expander" caption="Quick Application Development">
|
44
|
-
<p>
|
45
|
-
Neo.js classes let you specify properties in a way that allows code to detect "before" and "after"
|
46
|
-
changes. This makes it easy to handle value validation and transformation, and react to changes.
|
47
|
-
</p>
|
48
|
-
<p>
|
49
|
-
Neo.mjs also has elegant yet powerful state management features that make it easy to create shared,
|
50
|
-
bindable data. For example, if two components are bound to the same propery, a change to the
|
51
|
-
property will automatically be applied to both components.
|
52
|
-
</p>
|
53
|
-
</div>
|
54
|
-
|
55
|
-
<div type="expander" caption="Multi-Window Applications">
|
56
|
-
<p>
|
57
|
-
Neo.mjs applications can also launch as _shared web workers_, which allows you to have a single
|
58
|
-
application run in multiple browser windows; those windows could be moved to multiple monitors.
|
59
|
-
</p>
|
60
|
-
<p>
|
61
|
-
For example, you can have a data analysis application with a control panel on one monitor,
|
62
|
-
tabular data in another, and charts on another — all sharing the same data, handling events
|
63
|
-
across windows, running seamlessly as a single application.
|
64
|
-
</p>
|
65
|
-
</div>
|
66
|
-
|
67
|
-
<div type="expander" caption="Open-Source and Standards-Based">
|
68
|
-
<p>
|
69
|
-
Neo.mjs is an open-source library. Features needed for the community can be added to the
|
70
|
-
library via pull-requests. And since Neo.mjs uses the standard JavaScript class system,
|
71
|
-
all Neo.mjs classes can be extended.
|
72
|
-
</p>
|
73
|
-
<p>
|
74
|
-
Neo.mjs uses standard modular JavaScript, so developers don't need to learn non-standard language
|
75
|
-
syntax, and there's no need for special pre-compilers or WebPack modules.
|
76
|
-
That means fewer dependencies and easier configuration. Furthermore, the use of
|
77
|
-
standard JavaScript makes debugging easier: any statement you write while developing your
|
78
|
-
applcation can also be run in the debugging console.
|
79
|
-
</p>
|
80
|
-
</div>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|