neo.mjs 10.0.0-beta.1 → 10.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. package/ServiceWorker.mjs +2 -2
  2. package/apps/colors/view/GridContainer.mjs +1 -1
  3. package/apps/covid/view/AttributionComponent.mjs +1 -1
  4. package/apps/covid/view/HeaderContainer.mjs +6 -6
  5. package/apps/covid/view/MainContainerController.mjs +5 -5
  6. package/apps/covid/view/TableContainerController.mjs +1 -1
  7. package/apps/covid/view/country/Gallery.mjs +13 -13
  8. package/apps/covid/view/country/Helix.mjs +13 -13
  9. package/apps/covid/view/country/HistoricalDataTable.mjs +1 -1
  10. package/apps/email/view/Viewport.mjs +2 -2
  11. package/apps/form/view/FormPageContainer.mjs +2 -3
  12. package/apps/form/view/SideNavList.mjs +1 -1
  13. package/apps/portal/index.html +1 -1
  14. package/apps/portal/resources/data/examples_dist_esm.json +1 -1
  15. package/apps/portal/resources/data/examples_dist_prod.json +2 -2
  16. package/apps/portal/view/HeaderToolbar.mjs +3 -3
  17. package/apps/portal/view/about/Container.mjs +2 -2
  18. package/apps/portal/view/about/MemberContainer.mjs +3 -3
  19. package/apps/portal/view/blog/List.mjs +7 -7
  20. package/apps/portal/view/examples/List.mjs +4 -4
  21. package/apps/portal/view/home/ContentBox.mjs +2 -2
  22. package/apps/portal/view/home/FeatureSection.mjs +3 -3
  23. package/apps/portal/view/home/FooterContainer.mjs +7 -7
  24. package/apps/portal/view/home/parts/AfterMath.mjs +3 -3
  25. package/apps/portal/view/home/parts/MainNeo.mjs +3 -3
  26. package/apps/portal/view/home/parts/References.mjs +6 -6
  27. package/apps/portal/view/learn/ContentComponent.mjs +18 -11
  28. package/apps/portal/view/learn/PageSectionsContainer.mjs +1 -1
  29. package/apps/portal/view/learn/PageSectionsList.mjs +2 -2
  30. package/apps/portal/view/services/Component.mjs +16 -16
  31. package/apps/realworld/view/FooterComponent.mjs +1 -1
  32. package/apps/realworld/view/HeaderComponent.mjs +8 -8
  33. package/apps/realworld/view/HomeComponent.mjs +6 -6
  34. package/apps/realworld/view/article/CommentComponent.mjs +4 -4
  35. package/apps/realworld/view/article/Component.mjs +14 -14
  36. package/apps/realworld/view/article/CreateCommentComponent.mjs +3 -3
  37. package/apps/realworld/view/article/CreateComponent.mjs +3 -3
  38. package/apps/realworld/view/article/PreviewComponent.mjs +1 -1
  39. package/apps/realworld/view/article/TagListComponent.mjs +2 -2
  40. package/apps/realworld/view/user/ProfileComponent.mjs +8 -8
  41. package/apps/realworld/view/user/SettingsComponent.mjs +4 -4
  42. package/apps/realworld/view/user/SignUpComponent.mjs +4 -4
  43. package/apps/realworld2/view/FooterComponent.mjs +1 -1
  44. package/apps/realworld2/view/HomeContainer.mjs +3 -3
  45. package/apps/realworld2/view/article/DetailsContainer.mjs +1 -1
  46. package/apps/realworld2/view/article/PreviewComponent.mjs +7 -7
  47. package/apps/realworld2/view/article/TagListComponent.mjs +2 -2
  48. package/apps/realworld2/view/user/ProfileContainer.mjs +1 -1
  49. package/apps/route/view/center/CardAdministration.mjs +2 -2
  50. package/apps/route/view/center/CardAdministrationDenied.mjs +1 -1
  51. package/apps/route/view/center/CardContact.mjs +2 -2
  52. package/apps/route/view/center/CardHome.mjs +1 -1
  53. package/apps/route/view/center/CardSection1.mjs +1 -1
  54. package/apps/route/view/center/CardSection2.mjs +1 -1
  55. package/apps/sharedcovid/view/AttributionComponent.mjs +1 -1
  56. package/apps/sharedcovid/view/HeaderContainer.mjs +6 -6
  57. package/apps/sharedcovid/view/MainContainerController.mjs +5 -5
  58. package/apps/sharedcovid/view/TableContainerController.mjs +1 -1
  59. package/apps/sharedcovid/view/country/Gallery.mjs +13 -13
  60. package/apps/sharedcovid/view/country/Helix.mjs +13 -13
  61. package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -1
  62. package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +1 -1
  63. package/apps/shareddialog/view/MainContainer.mjs +1 -1
  64. package/buildScripts/createApp.mjs +2 -2
  65. package/learn/Glossary.md +261 -0
  66. package/learn/README.md +9 -14
  67. package/learn/benefits/ConfigSystem.md +536 -26
  68. package/learn/benefits/Effort.md +47 -2
  69. package/learn/benefits/Features.md +50 -32
  70. package/learn/benefits/FormsEngine.md +54 -24
  71. package/learn/benefits/MultiWindow.md +31 -5
  72. package/learn/benefits/Quick.md +45 -12
  73. package/learn/benefits/RPCLayer.md +75 -0
  74. package/learn/benefits/Speed.md +17 -12
  75. package/learn/guides/Collections.md +436 -0
  76. package/learn/guides/ConfigSystemDeepDive.md +280 -0
  77. package/learn/guides/CustomComponents.md +256 -14
  78. package/learn/guides/DeclarativeComponentTreesVsImperativeVdom.md +17 -17
  79. package/learn/guides/ExtendingNeoClasses.md +331 -0
  80. package/learn/guides/Forms.md +449 -1
  81. package/learn/guides/InstanceLifecycle.md +295 -1
  82. package/learn/guides/Layouts.md +246 -1
  83. package/learn/guides/MainThreadAddons.md +475 -0
  84. package/learn/guides/Records.md +286 -0
  85. package/learn/guides/WorkingWithVDom.md +14 -14
  86. package/learn/guides/form_fields/ComboBox.md +241 -0
  87. package/learn/tree.json +57 -51
  88. package/package.json +2 -2
  89. package/resources/scss/src/apps/portal/learn/ContentComponent.scss +9 -0
  90. package/src/DefaultConfig.mjs +2 -2
  91. package/src/Main.mjs +8 -7
  92. package/src/Neo.mjs +16 -2
  93. package/src/button/Base.mjs +2 -2
  94. package/src/calendar/view/SettingsContainer.mjs +2 -2
  95. package/src/calendar/view/YearComponent.mjs +9 -9
  96. package/src/calendar/view/calendars/ColorsList.mjs +1 -1
  97. package/src/calendar/view/calendars/List.mjs +1 -1
  98. package/src/calendar/view/month/Component.mjs +15 -15
  99. package/src/calendar/view/week/Component.mjs +12 -12
  100. package/src/calendar/view/week/EventDragZone.mjs +4 -4
  101. package/src/calendar/view/week/TimeAxisComponent.mjs +3 -3
  102. package/src/component/Base.mjs +17 -2
  103. package/src/component/Carousel.mjs +2 -2
  104. package/src/component/Chip.mjs +3 -3
  105. package/src/component/Circle.mjs +2 -2
  106. package/src/component/DateSelector.mjs +8 -8
  107. package/src/component/Helix.mjs +1 -1
  108. package/src/component/Label.mjs +3 -18
  109. package/src/component/Legend.mjs +3 -3
  110. package/src/component/MagicMoveText.mjs +6 -14
  111. package/src/component/Process.mjs +3 -3
  112. package/src/component/Progress.mjs +1 -1
  113. package/src/component/StatusBadge.mjs +2 -2
  114. package/src/component/Timer.mjs +2 -2
  115. package/src/component/Toast.mjs +5 -3
  116. package/src/container/AccordionItem.mjs +2 -2
  117. package/src/container/Base.mjs +1 -1
  118. package/src/core/Base.mjs +18 -2
  119. package/src/date/DayViewComponent.mjs +2 -2
  120. package/src/date/SelectorContainer.mjs +1 -1
  121. package/src/form/field/CheckBox.mjs +4 -4
  122. package/src/form/field/ComboBox.mjs +6 -1
  123. package/src/form/field/FileUpload.mjs +25 -39
  124. package/src/form/field/Range.mjs +1 -1
  125. package/src/form/field/Text.mjs +3 -3
  126. package/src/form/field/TextArea.mjs +2 -3
  127. package/src/grid/Body.mjs +6 -2
  128. package/src/list/Color.mjs +2 -2
  129. package/src/main/DeltaUpdates.mjs +157 -98
  130. package/src/main/addon/AmCharts.mjs +53 -73
  131. package/src/main/addon/Base.mjs +11 -0
  132. package/src/main/addon/MonacoEditor.mjs +31 -58
  133. package/src/manager/ClassHierarchy.mjs +114 -0
  134. package/src/menu/List.mjs +1 -1
  135. package/src/plugin/Popover.mjs +2 -2
  136. package/src/sitemap/Component.mjs +1 -1
  137. package/src/table/Body.mjs +6 -2
  138. package/src/tooltip/Base.mjs +1 -6
  139. package/src/tree/Accordion.mjs +3 -3
  140. package/src/vdom/Helper.mjs +21 -19
  141. package/src/worker/App.mjs +1 -2
  142. package/src/worker/Base.mjs +6 -4
  143. package/src/worker/Canvas.mjs +2 -3
  144. package/src/worker/Data.mjs +5 -7
  145. package/src/worker/Task.mjs +2 -3
  146. package/src/worker/VDom.mjs +3 -4
  147. package/src/worker/mixin/RemoteMethodAccess.mjs +4 -1
  148. package/learn/guides/MainThreadAddonExample.md +0 -15
  149. package/learn/guides/MainThreadAddonIntro.md +0 -44
@@ -16,6 +16,20 @@ class MonacoEditor extends Base {
16
16
  * @protected
17
17
  */
18
18
  className: 'Neo.main.addon.MonacoEditor',
19
+ /**
20
+ * List methods which must get cached until the addon reaches its `isReady` state
21
+ * @member {String[]} interceptRemotes
22
+ */
23
+ interceptRemotes: [
24
+ 'createInstance',
25
+ 'destroyInstance',
26
+ 'getValue',
27
+ 'layoutEditor',
28
+ 'setLanguage',
29
+ 'setTheme',
30
+ 'setValue',
31
+ 'updateOptions'
32
+ ],
19
33
  /**
20
34
  * @member {String} libraryBasePath='../../node_modules/monaco-editor/min/vs'
21
35
  */
@@ -53,23 +67,18 @@ class MonacoEditor extends Base {
53
67
  createInstance(data) {
54
68
  let me = this,
55
69
  {id} = data,
56
- editor, node;
70
+ node = DomAccess.getElement(id),
71
+ editor;
57
72
 
58
- if (!me.isReady) {
59
- return me.cacheMethodCall({fn: 'createInstance', data})
60
- } else {
61
- delete data.appName;
62
- delete data.id;
73
+ delete data.appName;
74
+ delete data.id;
63
75
 
64
- node = DomAccess.getElement(id);
76
+ if (node) {
77
+ editor = me.map[id] = monaco.editor.create(node, data);
65
78
 
66
- if (node) {
67
- editor = me.map[id] = monaco.editor.create(node, data);
68
-
69
- editor.getModel().onDidChangeContent(me.onContentChange.bind(me, id))
70
- } else if (Neo.config.environment === 'development') {
71
- console.warn(`addon.MonacoEditor: node ${id} not found`)
72
- }
79
+ editor.getModel().onDidChangeContent(me.onContentChange.bind(me, id))
80
+ } else if (Neo.config.environment === 'development') {
81
+ console.warn(`addon.MonacoEditor: node ${id} not found`)
73
82
  }
74
83
  }
75
84
 
@@ -78,14 +87,8 @@ class MonacoEditor extends Base {
78
87
  * @param {String} data.id
79
88
  */
80
89
  destroyInstance(data) {
81
- let me = this;
82
-
83
- if (!me.isReady) {
84
- return me.cacheMethodCall({fn: 'destroyInstance', data})
85
- } else {
86
- // todo: destroy the editor instance if possible
87
- delete this.map[data.id]
88
- }
90
+ // todo: destroy the editor instance if possible
91
+ delete this.map[data.id]
89
92
  }
90
93
 
91
94
  /**
@@ -94,13 +97,7 @@ class MonacoEditor extends Base {
94
97
  * @returns {Object}
95
98
  */
96
99
  getValue(data) {
97
- let me = this;
98
-
99
- if (!me.isReady) {
100
- return me.cacheMethodCall({fn: 'getValue', data})
101
- } else {
102
- return me.map[data.id].getModel().getValue()
103
- }
100
+ return this.map[data.id].getModel().getValue()
104
101
  }
105
102
 
106
103
  /**
@@ -109,7 +106,7 @@ class MonacoEditor extends Base {
109
106
  * @param {String} data.id
110
107
  */
111
108
  layoutEditor(data) {
112
- this.isReady && this.map[data.id].layout()
109
+ this.map[data.id].layout()
113
110
  }
114
111
 
115
112
  /**
@@ -154,13 +151,7 @@ class MonacoEditor extends Base {
154
151
  * @param {String} data.value
155
152
  */
156
153
  setLanguage(data) {
157
- let me = this;
158
-
159
- if (!me.isReady) {
160
- return me.cacheMethodCall({fn: 'setLanguage', data})
161
- } else {
162
- me.map[data.id].getModel().setLanguage(data.value)
163
- }
154
+ this.map[data.id].getModel().setLanguage(data.value)
164
155
  }
165
156
 
166
157
  /**
@@ -169,13 +160,7 @@ class MonacoEditor extends Base {
169
160
  * @param {String} data.value
170
161
  */
171
162
  setTheme(data) {
172
- let me = this;
173
-
174
- if (!me.isReady) {
175
- return me.cacheMethodCall({fn: 'setTheme', data})
176
- } else {
177
- me.map[data.id]._themeService.setTheme(data.value)
178
- }
163
+ this.map[data.id]._themeService.setTheme(data.value)
179
164
  }
180
165
 
181
166
  /**
@@ -184,13 +169,7 @@ class MonacoEditor extends Base {
184
169
  * @param {String} data.value
185
170
  */
186
171
  setValue(data) {
187
- let me = this;
188
-
189
- if (!me.isReady) {
190
- return me.cacheMethodCall({fn: 'setValue', data})
191
- } else {
192
- me.map[data.id].getModel().setValue(data.value)
193
- }
172
+ this.map[data.id].getModel().setValue(data.value)
194
173
  }
195
174
 
196
175
  /**
@@ -199,13 +178,7 @@ class MonacoEditor extends Base {
199
178
  * @param {Object} data.options
200
179
  */
201
180
  updateOptions(data) {
202
- let me = this;
203
-
204
- if (!me.isReady) {
205
- return me.cacheMethodCall({fn: 'updateOptions', data})
206
- } else {
207
- me.map[data.id].updateOptions(data.options)
208
- }
181
+ this.map[data.id].updateOptions(data.options)
209
182
  }
210
183
  }
211
184
 
@@ -0,0 +1,114 @@
1
+ import BaseManager from './Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.manager.ClassHierarchy
5
+ * @extends Neo.manager.Base
6
+ * @singleton
7
+ *
8
+ * This manager maintains a registry of all classes defined within the Neo.mjs framework's current realm (main or worker),
9
+ * including their inheritance relationships and key metadata.
10
+ * Each registered item (value in the manager's store) has the following structure:
11
+ * @typedef {Object} ClassHierarchyInfo
12
+ * @property {String} className - The full Neo.mjs class name (e.g., 'Neo.component.Base').
13
+ * @property {Function|Object} module - The direct reference to the class constructor function itself (for non-singletons)
14
+ * or the instantiated singleton object (for singletons).
15
+ * @property {String|null} ntype - The ntype of the class if defined (e.g., 'button', 'container'), otherwise `null`.
16
+ * @property {String|null} parentClassName - The full class name of its direct parent class,
17
+ * or `null` if it's a top-level class (e.g., 'Neo.core.Base').
18
+ */
19
+ class ClassHierarchy extends BaseManager {
20
+ static config = {
21
+ /**
22
+ * @member {String} className='Neo.manager.ClassHierarchy'
23
+ * @protected
24
+ */
25
+ className: 'Neo.manager.ClassHierarchy',
26
+ /**
27
+ * @member {String} keyProperty='className'
28
+ * @protected
29
+ */
30
+ keyProperty: 'className',
31
+ /**
32
+ * @member {Boolean} singleton=true
33
+ * @protected
34
+ */
35
+ singleton: true
36
+ }
37
+
38
+ /**
39
+ * Memoizes the return values of isA() calls
40
+ * @member {Map} isAQueryMap=new Map()
41
+ * @protected
42
+ */
43
+ isAQueryMap = new Map()
44
+
45
+ /**
46
+ * @param {Object} config
47
+ */
48
+ construct(config) {
49
+ super.construct(config);
50
+ this.consumeTempMap()
51
+ }
52
+
53
+ /**
54
+ * Register all classes that got applied to the Neo namespace before this instance got created
55
+ * @protected
56
+ */
57
+ consumeTempMap() {
58
+ if (Neo.classHierarchyMap) {
59
+ this.add(Object.values(Neo.classHierarchyMap));
60
+ delete Neo.classHierarchyMap
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Both params represent classNames.
66
+ *
67
+ * Example use cases:
68
+ * - isA('Neo.button.Menu', 'Neo.button.Base') => true
69
+ * - isA('Neo.button.Base', 'Neo.button.Menu') => false
70
+ * - isA('Neo.button.Base', 'Neo.component.Base') => true
71
+ * - isA('Neo.component.Base', 'Neo.core.Base') => true
72
+ * @param {String} descendant
73
+ * @param {String} ancestor
74
+ * @returns {Boolean}
75
+ */
76
+ isA(descendant, ancestor) {
77
+ if (descendant === ancestor) {
78
+ return true
79
+ }
80
+
81
+ let parent = descendant,
82
+ {isAQueryMap} = this,
83
+ queryName = `${descendant},${ancestor}`,
84
+ returnValue = false;
85
+
86
+ if (isAQueryMap.has(queryName)) {
87
+ return isAQueryMap.get(queryName)
88
+ }
89
+
90
+ while (parent = this.get(parent)?.parentClassName) {
91
+ if (parent === ancestor) {
92
+ returnValue = true;
93
+ break
94
+ }
95
+
96
+ // Assumption: component.Base directly extends core.Base
97
+ if (parent === 'Neo.component.Base' && ancestor !== 'Neo.core.Base') {
98
+ returnValue = false;
99
+ break
100
+ }
101
+
102
+ if (parent === 'Neo.core.Base') {
103
+ returnValue = false;
104
+ break
105
+ }
106
+ }
107
+
108
+ isAQueryMap.set(queryName, returnValue);
109
+
110
+ return returnValue
111
+ }
112
+ }
113
+
114
+ export default Neo.setupClass(ClassHierarchy);
package/src/menu/List.mjs CHANGED
@@ -182,7 +182,7 @@ class List extends BaseList {
182
182
  let me = this,
183
183
  {iconCls} = record,
184
184
  id = record[me.store.keyProperty],
185
- vdomCn = [{tag: 'span', cls: ['neo-content'], html: record[me.displayField]}];
185
+ vdomCn = [{tag: 'span', cls: ['neo-content'], text: record[me.displayField]}];
186
186
 
187
187
  if (iconCls && iconCls !== '') {
188
188
  vdomCn.unshift({tag: 'i', cls: ['neo-menu-icon', 'neo-icon', iconCls], id: me.getIconId(id)})
@@ -18,10 +18,10 @@ import Plugin from './Base.mjs';
18
18
  * ntype : 'panel',
19
19
  * headers: [{
20
20
  * dock: 'top',
21
- * html: 'HEADER'
21
+ * text: 'HEADER'
22
22
  * }],
23
23
  * items : [{
24
- * html: 'This is a comment about the button'
24
+ * text: 'This is a comment about the button'
25
25
  * }]
26
26
  * }]
27
27
  * }]
@@ -130,7 +130,7 @@ class Component extends Base {
130
130
  tag : 'a',
131
131
  cls : ['neo-action', `neo-level-${record.level}`],
132
132
  id : me.getItemId(record.id),
133
- html: record.name
133
+ text: record.name
134
134
  };
135
135
 
136
136
  if (action && action !== '') {
@@ -177,7 +177,7 @@ class TableBody extends Component {
177
177
 
178
178
  switch (Neo.typeOf(rendererOutput)) {
179
179
  case 'Object': {
180
- if (rendererOutput.html) {
180
+ if (rendererOutput.html || rendererOutput.text) {
181
181
  rendererOutput.cls && cellCls.push(...rendererOutput.cls);
182
182
  } else {
183
183
  rendererOutput = [rendererOutput];
@@ -230,7 +230,11 @@ class TableBody extends Component {
230
230
  }
231
231
 
232
232
  if (Neo.typeOf(rendererOutput) === 'Object') {
233
- cellConfig.html = rendererOutput.html || ''
233
+ if (Object.hasOwn(rendererOutput, 'html')) {
234
+ cellConfig.html = rendererOutput.html || ''
235
+ } else {
236
+ cellConfig.text = rendererOutput.text || ''
237
+ }
234
238
  } else {
235
239
  cellConfig.cn = rendererOutput
236
240
  }
@@ -76,12 +76,7 @@ class Tooltip extends Container {
76
76
  * True prevents the tooltip from hiding while the mouse cursor is above it
77
77
  * @member {Boolean|null} stayOnHover_=true
78
78
  */
79
- stayOnHover_: true,
80
- /**
81
- * Shortcut to add a label item
82
- * @member {String} text_=null
83
- */
84
- text_: null
79
+ stayOnHover_: true
85
80
  }
86
81
 
87
82
  /**
@@ -277,13 +277,13 @@ class AccordionTree extends TreeList {
277
277
  tag : 'span',
278
278
  cls : [itemCls + '-content-header'],
279
279
  id : id + '__item-content-header',
280
- html: item[me.fields.header]
280
+ text: item[me.fields.header]
281
281
  }, {
282
282
  flag: 'content',
283
283
  tag : 'span',
284
284
  cls : [itemCls + '-content-text'],
285
285
  id : id + '__item-content-text',
286
- html: item[me.fields.text]
286
+ text: item[me.fields.text]
287
287
  }]
288
288
  }],
289
289
  style: {
@@ -428,7 +428,7 @@ class AccordionTree extends TreeList {
428
428
  NeoArray.add(cls, clsItems);
429
429
  itemVdom.cls = cls
430
430
  } else {
431
- itemVdom.html = field.value
431
+ itemVdom.text = field.value
432
432
  }
433
433
  }
434
434
  });
@@ -37,23 +37,6 @@ class Helper extends Base {
37
37
  singleton: true
38
38
  }
39
39
 
40
- /**
41
- * @returns {Promise<void>}
42
- */
43
- async initAsync() {
44
- super.initAsync();
45
-
46
- let me = this;
47
-
48
- // Subscribe to global Neo.config changes for dynamic renderer switching.
49
- Neo.currentWorker.on({
50
- neoConfigChange: me.onNeoConfigChange,
51
- scope : me
52
- });
53
-
54
- await me.importUtil()
55
- }
56
-
57
40
  /**
58
41
  * @param {Object} config
59
42
  * @param {Object} config.deltas
@@ -517,6 +500,25 @@ class Helper extends Base {
517
500
  }
518
501
  }
519
502
 
503
+ /**
504
+ * @returns {Promise<void>}
505
+ */
506
+ async initAsync() {
507
+ super.initAsync();
508
+
509
+ let me = this;
510
+
511
+ if (!NeoConfig.unitTestMode) {
512
+ // Subscribe to global Neo.config changes for dynamic renderer switching.
513
+ Neo.currentWorker.on({
514
+ neoConfigChange: me.onNeoConfigChange,
515
+ scope : me
516
+ })
517
+ }
518
+
519
+ await me.importUtil()
520
+ }
521
+
520
522
  /**
521
523
  * @param {Object} config
522
524
  * @param {Object} config.deltas
@@ -629,12 +631,12 @@ class Helper extends Base {
629
631
 
630
632
  /**
631
633
  * Handler for global Neo.config changes.
632
- * If 'useDomApiRenderer' property changes, this method dynamically loads/clears the renderer utilities.
634
+ * If the `Neo.config.useDomApiRenderer` value changes, this method dynamically loads the renderer utilities.
633
635
  * @param {Object} config
634
636
  * @return {Promise<void>}
635
637
  */
636
638
  async onNeoConfigChange(config) {
637
- if(Object.hasOwn(config, 'useDomApiRenderer')) {
639
+ if (Object.hasOwn(config, 'useDomApiRenderer')) {
638
640
  await this.importUtil()
639
641
  }
640
642
  }
@@ -1,8 +1,7 @@
1
1
  import Neo from '../Neo.mjs';
2
2
  import Base from './Base.mjs';
3
- import * as core from '../core/_export.mjs';
4
3
  import Application from '../controller/Application.mjs';
5
- import Instance from '../manager/Instance.mjs';
4
+ import InstanceManager from '../manager/Instance.mjs';
6
5
  import DomEventManager from '../manager/DomEvent.mjs';
7
6
  import HashHistory from '../util/HashHistory.mjs';
8
7
 
@@ -1,7 +1,9 @@
1
- import Base from '../core/Base.mjs';
2
- import Observable from '../core/Observable.mjs';
3
- import Message from './Message.mjs';
4
- import RemoteMethodAccess from './mixin/RemoteMethodAccess.mjs';
1
+ import Base from '../core/Base.mjs';
2
+ import * as core from '../core/_export.mjs';
3
+ import Observable from '../core/Observable.mjs';
4
+ import ClassHierarchyManager from '../manager/ClassHierarchy.mjs';
5
+ import Message from './Message.mjs';
6
+ import RemoteMethodAccess from './mixin/RemoteMethodAccess.mjs';
5
7
 
6
8
  /**
7
9
  * The abstract base class for e.g. the App, Data & VDom worker
@@ -1,6 +1,5 @@
1
- import Neo from '../Neo.mjs';
2
- import Base from './Base.mjs';
3
- import * as core from '../core/_export.mjs';
1
+ import Neo from '../Neo.mjs';
2
+ import Base from './Base.mjs';
4
3
 
5
4
  /**
6
5
  * The Canvas worker is responsible for dynamically manipulating offscreen canvas.
@@ -1,12 +1,10 @@
1
- import Neo from '../Neo.mjs';
2
- import Base from './Base.mjs';
3
- import Compare from '../core/Compare.mjs';
4
- import Fetch from '../Fetch.mjs';
5
- import Util from '../core/Util.mjs';
6
- import Xhr from '../Xhr.mjs';
1
+ import Neo from '../Neo.mjs';
2
+ import Base from './Base.mjs';
3
+ import Fetch from '../Fetch.mjs';
4
+ import Xhr from '../Xhr.mjs';
7
5
 
8
6
  /**
9
- * The Data worker is responsible to handle all of the communication to the backend (e.g. Ajax-calls).
7
+ * The Data worker is responsible to handle all the communication to the backend (e.g. Ajax-calls).
10
8
  * See the tutorials for further infos.
11
9
  * @class Neo.worker.Data
12
10
  * @extends Neo.worker.Base
@@ -1,6 +1,5 @@
1
- import Neo from '../Neo.mjs';
2
- import Base from './Base.mjs';
3
- import * as core from '../core/_export.mjs';
1
+ import Neo from '../Neo.mjs';
2
+ import Base from './Base.mjs';
4
3
 
5
4
  /**
6
5
  * The Task worker can get filled with custom remote methods as needed.
@@ -1,7 +1,6 @@
1
- import Neo from '../Neo.mjs';
2
- import Base from './Base.mjs';
3
- import * as core from '../core/_export.mjs';
4
- import Helper from '../vdom/Helper.mjs';
1
+ import Neo from '../Neo.mjs';
2
+ import Base from './Base.mjs';
3
+ import Helper from '../vdom/Helper.mjs';
5
4
 
6
5
  /**
7
6
  * The Vdom worker converts vdom templates into vnodes, as well as creating delta-updates.
@@ -90,7 +90,10 @@ class RemoteMethodAccess extends Base {
90
90
  throw new Error('Invalid remote method name "' + msg.remoteMethod + '"')
91
91
  }
92
92
 
93
- if (Array.isArray(msg.data)) {
93
+ // Check for interception
94
+ if (!pkg.isReady && pkg.interceptRemotes?.includes(msg.remoteMethod)) {
95
+ out = pkg.onInterceptRemotes(msg);
96
+ } else if (Array.isArray(msg.data)) {
94
97
  out = method.call(pkg, ...msg.data)
95
98
  } else {
96
99
  out = method.call(pkg, msg.data)
@@ -1,15 +0,0 @@
1
- Let's go through the steps of creating a main thread addon.
2
-
3
- Let's say we needed to show a code editor. There are a lot of libraries
4
- for this, such as Ace (<a href="https://ace.c9.io/" target="_blank">ace.c9.io</a>).
5
- From a coding perspective, these editors have a simple API: a setter
6
- to specify the string being edited, a getter to read the string, and
7
- a change event fired as the user types.
8
-
9
- Here's what we need to do:
10
- - Define a main thread addon and its API
11
- - Define a component wrapper
12
-
13
- ### Define the Main Thread Addon
14
-
15
- ### Define the component wrapper
@@ -1,44 +0,0 @@
1
- Neo.mjs is multi-threaded. There are worker threads
2
- that handle data access, application logic,
3
- and keeping track of DOM updates. Practically all your
4
- application logic is run in parallel in these threads.
5
- However, anything that needs to actually reference or update
6
- the DOM (`window.document`), or just use the `window` object, must be done in the main
7
- application thread.
8
-
9
- That's the purpose of main thread addons. These are classes whose
10
- methods can be accessed from other web workers, but are
11
- actually executed in the main thread.
12
-
13
- For example, what if you needed to read the browser's
14
- URL? That information is in `window.location`.
15
- But `window` is a main thread variable! To access that
16
- from a web-worker our code has to say "hey main thread,
17
- please return a specified `window` property." Neo.mjs
18
- lets you do that via `Neo.Main.getByPath()`. For
19
- example, the following statement logs the URL query string.
20
-
21
- ```javascript readonly
22
- const search = await Neo.Main.getByPath({path: 'window.location.search'});
23
- console.log(search); // Logs the search string
24
- ```
25
-
26
- `Neo.Main` & `Neo.main.DomAccess` provide some basic methods for accessing the
27
- main thread, but in case you want to use a third party library which relies on directly
28
- working with the DOM, you'd use a _main thread addon_.
29
-
30
- Google Maps is a good example of this. In Neo.mjs, most
31
- views are responsible for updating their own vdom, but
32
- the responsibility for rendering maps and markers is handled
33
- by Google Maps itself &mdash; we _ask_ Google Maps to do
34
- certain things via the Google Maps API. Therefore, in Neo.mjs,
35
- Google Maps is implemented as a main thread addon which
36
- loads the libraries and exposes whatever methods we'll need
37
- to run from the other Neo.mjs threads. In addition, in a
38
- Neo.mjs application we want to use Google Maps like any other
39
- component, so Neo.mjs also provides a component wrapper. In
40
- summary:
41
- - The main-thread addon contains the code run in the main thread,
42
- and exposes what methods can be run by other web-workers (remote method access)
43
- - The component wrapper lets you use it like any other component,
44
- internally calling the main thread methods as needed.