neo.mjs 4.0.1 → 4.0.4

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.
@@ -0,0 +1,38 @@
1
+ import Button from '../../../../src/button/Base.mjs';
2
+ import CesiumJSComponent from '../../../../src/component/wrapper/CesiumJS.mjs';
3
+ import MainContainerController from './MainContainerController.mjs';
4
+ import Toolbar from '../../../../src/container/Toolbar.mjs';
5
+ import Viewport from '../../../../src/container/Viewport.mjs';
6
+
7
+ /**
8
+ * @class Neo.examples.component.wrapper.cesiumJS.MainContainer
9
+ * @extends Neo.container.Viewport
10
+ */
11
+ class MainContainer extends Viewport {
12
+ static getConfig() {return {
13
+ className : 'Neo.examples.component.wrapper.cesiumJS.MainContainer',
14
+ autoMount : true,
15
+ controller: MainContainerController,
16
+ layout : {ntype: 'vbox', align: 'stretch'},
17
+
18
+ items: [{
19
+ module : CesiumJSComponent,
20
+ flex : 1,
21
+ reference: 'cesium-component'
22
+ }, {
23
+ module: Toolbar,
24
+ flex : 'none',
25
+ style : {margin: '20px'},
26
+ items : [{
27
+ module : Button,
28
+ handler: 'onFlyToButtonClick',
29
+ iconCls: 'fa-solid fa-plane',
30
+ text : 'Fly to San Fran'
31
+ }]
32
+ }]
33
+ }}
34
+ }
35
+
36
+ Neo.applyClassConfig(MainContainer);
37
+
38
+ export default MainContainer;
@@ -0,0 +1,30 @@
1
+ import ComponentController from '../../../../src/controller/Component.mjs';
2
+
3
+ /**
4
+ * @class Neo.examples.component.wrapper.cesiumJS.MainContainerController
5
+ * @extends Neo.controller.Component
6
+ */
7
+ class MainContainerController extends ComponentController {
8
+ static getConfig() {return {
9
+ /**
10
+ * @member {String} className='Neo.examples.component.wrapper.cesiumJS.MainContainerController'
11
+ * @protected
12
+ */
13
+ className: 'Neo.examples.component.wrapper.cesiumJS.MainContainerController'
14
+ }}
15
+
16
+ /**
17
+ * @param {Object} data
18
+ */
19
+ onFlyToButtonClick(data) {
20
+ this.getReference('cesium-component').flyTo({
21
+ destination: [-122.4175, 37.655, 400],
22
+ heading : 0.0,
23
+ pitch : -15.0
24
+ });
25
+ }
26
+ }
27
+
28
+ Neo.applyClassConfig(MainContainerController);
29
+
30
+ export default MainContainerController;
@@ -0,0 +1,7 @@
1
+ import MainContainer from './MainContainer.mjs';
2
+
3
+ export const onStart = () => Neo.app({
4
+ mainView: MainContainer,
5
+ name : 'Neo.examples.component.wrapper.cesiumJS'
6
+ });
7
+
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <meta charset="UTF-8">
6
+ <title>Neo CesiumJS Component</title>
7
+ </head>
8
+ <body>
9
+ <script src="../../../../src/MicroLoader.mjs" type="module"></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,8 @@
1
+ {
2
+ "appPath" : "examples/component/wrapper/cesiumJS/app.mjs",
3
+ "basePath" : "../../../../",
4
+ "cesiumJsToken" : "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4NGY3Y2YyNi1hODY3LTQ2YmMtYWIzNS01NzIxOTM5YzQ5MTUiLCJpZCI6MjQ3NDAsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODU2OTUzMjB9._j_owvL1zmT8KMPPWEWknoryJCIdVL8bY_E3vgoN8KI",
5
+ "environment" : "development",
6
+ "mainPath" : "./Main.mjs",
7
+ "mainThreadAddons": ["CesiumJS", "Stylesheet"]
8
+ }
@@ -0,0 +1,55 @@
1
+ import Button from '../../../src/button/Base.mjs';
2
+ import MainContainerController from './MainContainerController.mjs';
3
+ import Toolbar from '../../../src/container/Toolbar.mjs';
4
+ import Viewport from '../../../src/container/Viewport.mjs';
5
+
6
+ /**
7
+ * @class Neo.examples.remotesApi.basic.MainContainer
8
+ * @extends Neo.container.Viewport
9
+ */
10
+ class MainContainer extends Viewport {
11
+ static getConfig() {return {
12
+ className : 'Neo.examples.remotesApi.basic.MainContainer',
13
+ autoMount : true,
14
+ controller: MainContainerController,
15
+ layout : {ntype: 'vbox', align: 'stretch'},
16
+
17
+ items: [{
18
+ module : Toolbar,
19
+ flex : 'none',
20
+ padding : 20,
21
+ reference: 'headerToolbar',
22
+
23
+ style: {
24
+ backgroundColor: '#f2f2f2',
25
+ padding : '10px 5px 10px 10px'
26
+ },
27
+
28
+ items: [{
29
+ module : Button,
30
+ handler: 'onGetAllUsersButtonClick',
31
+ height : 27,
32
+ iconCls: 'fa fa-users',
33
+ text : 'Get all users'
34
+ }, {
35
+ module : Button,
36
+ handler: 'onGetAllFriendsButtonClick',
37
+ height : 27,
38
+ iconCls: 'fab fa-github',
39
+ style : {marginLeft: '5px'},
40
+ text : 'Get all friends'
41
+ }, {
42
+ module : Button,
43
+ handler: 'onGetAllUsersPlusFriendsButtonClick',
44
+ height : 27,
45
+ iconCls: 'fa-regular fa-heart',
46
+ style : {marginLeft: '5px'},
47
+ text : 'Get users & friends'
48
+ }]
49
+ }]
50
+ }}
51
+ }
52
+
53
+ Neo.applyClassConfig(MainContainer);
54
+
55
+ export default MainContainer;
@@ -0,0 +1,45 @@
1
+ import ComponentController from '../../../src/controller/Component.mjs';
2
+
3
+ /**
4
+ * @class Neo.examples.remotesApi.basic.MainContainerController
5
+ * @extends Neo.controller.Component
6
+ */
7
+ class MainContainerController extends ComponentController {
8
+ static getConfig() {return {
9
+ /**
10
+ * @member {String} className='Neo.examples.remotesApi.basic.MainContainerController'
11
+ * @protected
12
+ */
13
+ className: 'Neo.examples.remotesApi.basic.MainContainerController'
14
+ }}
15
+
16
+ /**
17
+ * @param {Object} data
18
+ */
19
+ onGetAllFriendsButtonClick(data) {
20
+ MyApi.UserService.getAll().then(response => console.log(response))
21
+ }
22
+
23
+ /**
24
+ * @param {Object} data
25
+ */
26
+ onGetAllUsersButtonClick(data) {
27
+ MyApi.FriendService.getAll()
28
+ }
29
+
30
+ /**
31
+ * @param {Object} data
32
+ */
33
+ async onGetAllUsersPlusFriendsButtonClick(data) {
34
+ await Promise.all([
35
+ MyApi.UserService.getAll(),
36
+ MyApi.FriendService.getAll()
37
+ ]);
38
+
39
+ console.log('Both calls are done')
40
+ }
41
+ }
42
+
43
+ Neo.applyClassConfig(MainContainerController);
44
+
45
+ export default MainContainerController;
@@ -0,0 +1,6 @@
1
+ import MainContainer from './MainContainer.mjs';
2
+
3
+ export const onStart = () => Neo.app({
4
+ mainView: MainContainer,
5
+ name : 'Neo.examples.remotesApi.basic'
6
+ });
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE HTML>
2
+ <html>
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <meta charset="UTF-8">
6
+ <title>Remotes API Basic</title>
7
+ </head>
8
+ <body>
9
+ <script src="../../../src/MicroLoader.mjs" type="module"></script>
10
+ </body>
11
+ </html>
@@ -0,0 +1,7 @@
1
+ {
2
+ "appPath" : "examples/remotesApi/basic/app.mjs",
3
+ "basePath" : "../../../",
4
+ "environment" : "development",
5
+ "mainPath" : "./Main.mjs",
6
+ "remotesApiUrl": "remotes-api.json"
7
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "namespace": "MyApi",
3
+ "url" : "./",
4
+
5
+ "services": [{
6
+ "name" : "FriendService",
7
+ "methods": [{
8
+ "name": "getAll"
9
+ }]
10
+ }, {
11
+ "name" : "UserService",
12
+ "methods": [{
13
+ "name": "getAll"
14
+ }]
15
+ }]
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.0.1",
3
+ "version": "4.0.4",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -41,7 +41,7 @@
41
41
  "chalk": "^5.0.1",
42
42
  "clean-webpack-plugin": "^4.0.0",
43
43
  "commander": "^9.1.0",
44
- "cssnano": "^5.1.5",
44
+ "cssnano": "^5.1.7",
45
45
  "envinfo": "^7.8.1",
46
46
  "fs-extra": "^10.0.1",
47
47
  "highlightjs-line-numbers.js": "^2.8.0",
@@ -49,10 +49,10 @@
49
49
  "neo-jsdoc": "^1.0.1",
50
50
  "neo-jsdoc-x": "^1.0.4",
51
51
  "postcss": "^8.4.12",
52
- "sass": "^1.49.10",
53
- "webpack": "^5.70.0",
52
+ "sass": "^1.50.0",
53
+ "webpack": "^5.72.0",
54
54
  "webpack-cli": "^4.9.2",
55
- "webpack-dev-server": "4.7.4",
55
+ "webpack-dev-server": "4.8.1",
56
56
  "webpack-hook-plugin": "^1.0.7",
57
57
  "webpack-node-externals": "^3.0.0"
58
58
  },
@@ -34,6 +34,15 @@ const DefaultConfig = {
34
34
  * @type String
35
35
  */
36
36
  basePath: './',
37
+ /**
38
+ * Pass a token in case you are using the CesiumJS main thread addon
39
+ * See: https://github.com/neomjs/neo/blob/dev/src/main/addon/CesiumJS.mjs
40
+ * @default null
41
+ * @memberOf! module:Neo
42
+ * @name config.cesiumJsToken
43
+ * @type String|null
44
+ */
45
+ cesiumJsToken: null,
37
46
  /**
38
47
  * The current environment. Valid values: 'development', 'dist/development', 'dist/production'
39
48
  * This config will get auto-generated
@@ -44,7 +53,7 @@ const DefaultConfig = {
44
53
  */
45
54
  environment: 'dist/production',
46
55
  /**
47
- * In case you are using the GoogleAnalytics mainThreadAddon or useGoogleAnalytics: true,
56
+ * In case you are using the GoogleAnalytics main thread addon or useGoogleAnalytics: true,
48
57
  * you can change the gtag id here. Required for the online examples (gh pages)
49
58
  * @default 'UA-153734404-1'
50
59
  * @memberOf! module:Neo
@@ -96,6 +105,16 @@ const DefaultConfig = {
96
105
  * @type String[]
97
106
  */
98
107
  mainThreadAddons: ['DragDrop', 'Stylesheet'],
108
+ /**
109
+ * Pass the URL of a JSON-file, which contains the services and methods from your backend,
110
+ * which you want to expose to the client.
111
+ * See: https://github.com/neomjs/neo/projects/32
112
+ * @default null
113
+ * @memberOf! module:Neo
114
+ * @name config.remotesApiUrl
115
+ * @type String|null
116
+ */
117
+ remotesApiUrl: null,
99
118
  /**
100
119
  * You can visually show the amount of delta updates per second using this config.
101
120
  * It expects a dom node with the id "neo-delta-updates" as the rendering target.
package/src/Fetch.mjs ADDED
@@ -0,0 +1,44 @@
1
+ import FetchConnection from './data/connection/Fetch.mjs';
2
+
3
+ /**
4
+ * @class Neo.Fetch
5
+ * @extends Neo.data.connection.Fetch
6
+ * @singleton
7
+ */
8
+ class Fetch extends FetchConnection {
9
+ static getConfig() {return {
10
+ /**
11
+ * @member {String} className='Neo.Fetch'
12
+ * @protected
13
+ */
14
+ className: 'Neo.Fetch',
15
+ /**
16
+ * @member {Object} remote
17
+ * @protected
18
+ */
19
+ remote: {
20
+ app: [
21
+ 'delete',
22
+ 'get',
23
+ 'head',
24
+ 'options',
25
+ 'patch',
26
+ 'post',
27
+ 'put'
28
+ ]
29
+ },
30
+ /**
31
+ * @member {Boolean} singleton=true
32
+ * @protected
33
+ */
34
+ singleton: true
35
+ }}
36
+ }
37
+
38
+ Neo.applyClassConfig(Fetch);
39
+
40
+ let instance = Neo.create(Fetch);
41
+
42
+ Neo.applyToGlobalNs(instance);
43
+
44
+ export default instance;
package/src/Main.mjs CHANGED
@@ -170,7 +170,7 @@ class Main extends core.Base {
170
170
  availWidth : screen.availWidth,
171
171
  colorDepth : screen.colorDepth,
172
172
  height : screen.height,
173
- orientation: {angle: screen.orientation.angle, type: screen.orientation.type},
173
+ orientation: {angle: screen.orientation?.angle, type: screen.orientation?.type},
174
174
  pixelDepth : screen.pixelDepth,
175
175
  width : screen.width
176
176
  },
@@ -0,0 +1,104 @@
1
+ import Component from '../Base.mjs';
2
+
3
+ /**
4
+ * Convenience class to render a CesiumJS component
5
+ * Requires adding the CesiumJS main thread addon
6
+ * @class Neo.component.wrapper.CesiumJS
7
+ * @extends Neo.component.Base
8
+ */
9
+ class CesiumJS extends Component {
10
+ static getConfig() {return {
11
+ /**
12
+ * @member {String} className='Neo.component.wrapper.CesiumJS'
13
+ * @protected
14
+ */
15
+ className: 'Neo.component.wrapper.CesiumJS',
16
+ /**
17
+ * @member {String} ntype='cesiumjs-component'
18
+ * @protected
19
+ */
20
+ ntype: 'cesiumjs-component',
21
+ /**
22
+ * @member {Boolean} createOsmBuildings=true
23
+ */
24
+ createOsmBuildings: true,
25
+ /**
26
+ * @member {Object} _vdom
27
+ */
28
+ _vdom:
29
+ {style: {position: 'relative', height: '100%', width: '100%'}, cn: [
30
+ {style: {position: 'absolute', height: '100%', width: '100%'}, }
31
+ ]}
32
+ }}
33
+
34
+ /**
35
+ * Triggered after the mounted config got changed
36
+ * @param {Boolean} value
37
+ * @param {Boolean} oldValue
38
+ * @protected
39
+ */
40
+ afterSetMounted(value, oldValue) {
41
+ let me = this;
42
+
43
+ if (value === false && oldValue !== undefined) {
44
+ Neo.main.addon.CesiumJS.destroy({
45
+ appName: me.appName,
46
+ id : me.id
47
+ });
48
+ }
49
+
50
+ super.afterSetMounted(value, oldValue);
51
+
52
+ if (value) {
53
+ let opts = {
54
+ appName : me.appName,
55
+ createOsmBuildings: me.createOsmBuildings,
56
+ id : me.id
57
+ };
58
+
59
+ setTimeout(() => {
60
+ Neo.main.addon.CesiumJS.create(opts).then(() => {
61
+ me.onComponentMounted();
62
+ });
63
+ }, 50);
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @param {Object} data
69
+ * @param {Number[]} data.destination
70
+ * @param {Number} data.heading
71
+ * @param {Number} data.pitch
72
+ */
73
+ flyTo(data) {
74
+ Neo.main.addon.CesiumJS.flyTo({
75
+ ...data,
76
+ id: this.id
77
+ });
78
+ }
79
+
80
+ /**
81
+ *
82
+ */
83
+ getVdomRoot() {
84
+ return this.vdom.cn[0];
85
+ }
86
+
87
+ /**
88
+ *
89
+ */
90
+ getVnodeRoot() {
91
+ return this.vnode.childNodes[0];
92
+ }
93
+
94
+ /**
95
+ *
96
+ */
97
+ onComponentMounted() {
98
+ console.log('onComponentMounted', this.id);
99
+ }
100
+ }
101
+
102
+ Neo.applyClassConfig(CesiumJS);
103
+
104
+ export default CesiumJS;
@@ -96,14 +96,12 @@ class MapboxGL extends Component {
96
96
  afterSetChartData(value, oldValue) {
97
97
  let me = this;
98
98
 
99
- if (value) {
100
- Neo.main.addon.MapboxGL.updateData({
101
- appName : me.appName,
102
- data : value,
103
- dataSourceId: me.dataSourceId,
104
- id : me.id
105
- });
106
- }
99
+ value && Neo.main.addon.MapboxGL.updateData({
100
+ appName : me.appName,
101
+ data : value,
102
+ dataSourceId: me.dataSourceId,
103
+ id : me.id
104
+ });
107
105
  }
108
106
 
109
107
  /**
@@ -113,13 +111,11 @@ class MapboxGL extends Component {
113
111
  * @protected
114
112
  */
115
113
  afterSetLayers(value, oldValue) {
116
- if (value) {
117
- Neo.main.addon.MapboxGL.addLayers({
118
- appName: this.appName,
119
- id : this.id,
120
- layers : value
121
- });
122
- }
114
+ value && Neo.main.addon.MapboxGL.addLayers({
115
+ appName: this.appName,
116
+ id : this.id,
117
+ layers : value
118
+ });
123
119
  }
124
120
 
125
121
  /**
@@ -131,14 +127,12 @@ class MapboxGL extends Component {
131
127
  afterSetMapboxStyle(value, oldValue) {
132
128
  let me = this;
133
129
 
134
- if (this.mounted) {
135
- Neo.main.addon.MapboxGL.setStyle({
136
- accessToken: me.accessToken,
137
- appName : me.appName,
138
- id : me.id,
139
- style : value
140
- });
141
- }
130
+ me.mounted && Neo.main.addon.MapboxGL.setStyle({
131
+ accessToken: me.accessToken,
132
+ appName : me.appName,
133
+ id : me.id,
134
+ style : value
135
+ });
142
136
  }
143
137
 
144
138
  /**
@@ -193,13 +187,11 @@ class MapboxGL extends Component {
193
187
  * @protected
194
188
  */
195
189
  afterSetSources(value, oldValue) {
196
- if (value) {
197
- Neo.main.addon.MapboxGL.addSources({
198
- appName: this.appName,
199
- id : this.id,
200
- sources: value
201
- });
202
- }
190
+ value && Neo.main.addon.MapboxGL.addSources({
191
+ appName: this.appName,
192
+ id : this.id,
193
+ sources: value
194
+ });
203
195
  }
204
196
 
205
197
  /**
@@ -211,13 +203,11 @@ class MapboxGL extends Component {
211
203
  afterSetZoom(value, oldValue) {
212
204
  let me = this;
213
205
 
214
- if (me.mounted) {
215
- Neo.main.addon.MapboxGL.zoom({
216
- appName: me.appName,
217
- id : me.id,
218
- zoom : value
219
- });
220
- }
206
+ me.mounted && Neo.main.addon.MapboxGL.zoom({
207
+ appName: me.appName,
208
+ id : me.id,
209
+ zoom : value
210
+ });
221
211
  }
222
212
 
223
213
  /**
@@ -269,7 +259,7 @@ class MapboxGL extends Component {
269
259
  */
270
260
  centerMap(value, animate=false) {
271
261
  Neo.main.addon.MapboxGL.center({
272
- animate: animate,
262
+ animate,
273
263
  appName: this.appName,
274
264
  id : this.id,
275
265
  lat : value.lat,
@@ -317,7 +307,7 @@ class MapboxGL extends Component {
317
307
  * @param {Number} value.lng
318
308
  */
319
309
  flyTo(value) {
320
- const me = this;
310
+ let me = this;
321
311
 
322
312
  value = me.beforeSetCenter(value, null); // long => lng if needed
323
313
 
@@ -0,0 +1,121 @@
1
+ import Base from '../../core/Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.data.connection.Fetch
5
+ * @extends Neo.core.Base
6
+ */
7
+ class Fetch extends Base {
8
+ /**
9
+ * @member {Object} defaultHeaders=null
10
+ */
11
+ defaultHeaders = null
12
+
13
+ static getConfig() {return {
14
+ /**
15
+ * @member {String} className='Neo.data.connection.Fetch'
16
+ * @protected
17
+ */
18
+ className: 'Neo.data.connection.Fetch'
19
+ }}
20
+
21
+ /**
22
+ * @param {Object|String} url
23
+ * @param {Object} config
24
+ * @returns {Promise<any>}
25
+ */
26
+ delete(url, config) {
27
+ return this.request(url, config, 'delete');
28
+ }
29
+
30
+ /**
31
+ * @param {Object|String} url
32
+ * @param {Object} config
33
+ * @returns {Promise<any>}
34
+ */
35
+ get(url, config) {
36
+ return this.request(url, config, 'get');
37
+ }
38
+
39
+ /**
40
+ * @param {Object|String} url
41
+ * @param {Object} config
42
+ * @returns {Promise<any>}
43
+ */
44
+ head(url, config) {
45
+ return this.request(url, config, 'head');
46
+ }
47
+
48
+ /**
49
+ * @param {Object|String} url
50
+ * @param {Object} config
51
+ * @returns {Promise<any>}
52
+ */
53
+ options(url, config) {
54
+ return this.request(url, config, 'options');
55
+ }
56
+
57
+ /**
58
+ * @param {Object|String} url
59
+ * @param {Object} config
60
+ * @param {Object} data
61
+ * @returns {Promise<any>}
62
+ */
63
+ patch(url, config, data) {
64
+ return this.request(url, config, 'patch', data);
65
+ }
66
+
67
+ /**
68
+ * @param {Object|String} url
69
+ * @param {Object} config
70
+ * @param {Object} data
71
+ * @returns {Promise<any>}
72
+ */
73
+ post(url, config, data) {
74
+ return this.request(url, config, 'post', data);
75
+ }
76
+
77
+ /**
78
+ * @param {Object|String} url
79
+ * @param {Object} config
80
+ * @param {Object} data
81
+ * @returns {Promise<any>}
82
+ */
83
+ put(url, config, data) {
84
+ return this.request(url, config, 'put', data);
85
+ }
86
+
87
+ /**
88
+ * @param {Object|String} url
89
+ * @param {Object} config
90
+ * @param {String} method
91
+ * @param {Object} [data]
92
+ * @returns {Promise<any>}
93
+ */
94
+ request(url, config, method, data) {
95
+ if (!Neo.isString(url)) {
96
+ config = url;
97
+ url = config.url;
98
+ }
99
+
100
+ return fetch(url)
101
+ .then(resp => {
102
+ console.log(resp);
103
+
104
+ let response = {
105
+ ok : resp.ok,
106
+ redirected: resp.redirected,
107
+ request : config,
108
+ status : resp.status,
109
+ statusText: resp.statusText,
110
+ type : resp.type,
111
+ url : resp.url
112
+ };
113
+
114
+ return response
115
+ })
116
+ }
117
+ }
118
+
119
+ Neo.applyClassConfig(Fetch);
120
+
121
+ export default Fetch;
@@ -169,7 +169,7 @@ class Xhr extends Base {
169
169
  if (!opts.url) {
170
170
  console.error('Neo.Xhr.request without a given url' + JSON.stringify(opts));
171
171
  } else {
172
- if (!opts.insideNeo && location.href.includes('/node_modules/neo.mjs/') && !location.href.includes('https://neomjs.github.io/')) {
172
+ if (!opts.insideNeo && location.href.includes('/node_modules/neo.mjs/') && !location.href.startsWith('https://neomjs.github.io/')) {
173
173
  if (opts.url.startsWith('./') || opts.url.startsWith('../')) {
174
174
  opts.url = '../../' + opts.url;
175
175
  }
@@ -61,11 +61,12 @@ class Card extends Base {
61
61
  * @protected
62
62
  */
63
63
  async afterSetActiveIndex(value, oldValue) {
64
- let me = this,
65
- containerId = me.containerId,
66
- container = Neo.getComponent(containerId) || Neo.get(containerId), // the instance might not be registered yet
67
- sCfg = me.getStaticConfig(),
68
- needsUpdate = false,
64
+ let me = this,
65
+ containerId = me.containerId,
66
+ container = Neo.getComponent(containerId) || Neo.get(containerId), // the instance might not be registered yet
67
+ sCfg = me.getStaticConfig(),
68
+ needsUpdate = false,
69
+ removeInactiveCards = me.removeInactiveCards,
69
70
  cls, i, isActiveIndex, item, items, len, module, proto, vdom;
70
71
 
71
72
  if (Neo.isNumber(value) && container) {
@@ -119,14 +120,14 @@ class Card extends Base {
119
120
  NeoArray.remove(cls, isActiveIndex ? sCfg.inactiveItemCls : sCfg.activeItemCls);
120
121
  NeoArray.add( cls, isActiveIndex ? sCfg.activeItemCls : sCfg.inactiveItemCls);
121
122
 
122
- if (me.removeInactiveCards || needsUpdate) {
123
+ if (removeInactiveCards || needsUpdate) {
123
124
  item._cls = cls; // silent update
124
125
  item.getVdomRoot().cls = cls;
125
126
 
126
127
  if (isActiveIndex) {
127
128
  delete item.vdom.removeDom;
128
129
  item.activate?.();
129
- } else {
130
+ } else if (removeInactiveCards) {
130
131
  item.mounted = false;
131
132
  item.vdom.removeDom = true;
132
133
  }
@@ -136,7 +137,7 @@ class Card extends Base {
136
137
  }
137
138
  }
138
139
 
139
- if (me.removeInactiveCards || needsUpdate) {
140
+ if (removeInactiveCards || needsUpdate) {
140
141
  container.vdom = vdom;
141
142
  }
142
143
  }
@@ -0,0 +1,126 @@
1
+ import Base from '../../core/Base.mjs';
2
+ import DomAccess from '../DomAccess.mjs';
3
+
4
+ /**
5
+ * See: https://github.com/CesiumGS/cesium
6
+ * @class Neo.main.addon.CesiumJS
7
+ * @extends Neo.core.Base
8
+ * @singleton
9
+ */
10
+ class CesiumJS extends Base {
11
+ /**
12
+ * @member {Object} viewers={}
13
+ * @protected
14
+ */
15
+ viewers = {}
16
+
17
+ static getConfig() {return {
18
+ /**
19
+ * @member {String} className='Neo.main.addon.CesiumJS'
20
+ * @protected
21
+ */
22
+ className: 'Neo.main.addon.CesiumJS',
23
+ /**
24
+ * Remote method access for other workers
25
+ * @member {Object} remote
26
+ * @protected
27
+ */
28
+ remote: {
29
+ app: [
30
+ 'create',
31
+ 'createOsmBuildings',
32
+ 'destroy',
33
+ 'flyTo'
34
+ ]
35
+ },
36
+ /**
37
+ * @member {Boolean} singleton=true
38
+ * @protected
39
+ */
40
+ singleton: true
41
+ }}
42
+
43
+ /**
44
+ * @param {Object} config
45
+ */
46
+ construct(config) {
47
+ super.construct(config);
48
+ this.loadFiles();
49
+ }
50
+
51
+ /**
52
+ * @param {Object} data
53
+ * @param {Boolean} data.createOsmBuildings
54
+ * @param {String} data.id
55
+ */
56
+ create(data) {
57
+ this.viewers[data.id] = new Cesium.Viewer(data.id, {
58
+ terrainProvider: Cesium.createWorldTerrain()
59
+ });
60
+
61
+ data.createOsmBuildings && this.createOsmBuildings({
62
+ id: data.id
63
+ });
64
+ }
65
+
66
+ /**
67
+ * @param {Object} data
68
+ * @param {String} data.id
69
+ */
70
+ createOsmBuildings(data) {
71
+ this.viewers[data.id].scene.primitives.add(Cesium.createOsmBuildings());
72
+ }
73
+
74
+ /**
75
+ * @param {Object} data
76
+ * @param {String} data.id
77
+ */
78
+ destroy(data) {
79
+ // todo
80
+ console.log('main.addon.CesiumJS: destroy()', data);
81
+ }
82
+
83
+ /**
84
+ * @param {Object} data
85
+ * @param {Number[]} data.destination
86
+ * @param {Number} data.heading
87
+ * @param {String} data.id
88
+ * @param {Number} data.pitch
89
+ */
90
+ flyTo(data) {
91
+ this.viewers[data.id].camera.flyTo({
92
+ destination: Cesium.Cartesian3.fromDegrees(...data.destination),
93
+ orientation: {
94
+ heading: Cesium.Math.toRadians(data.heading),
95
+ pitch : Cesium.Math.toRadians(data.pitch),
96
+ }
97
+ });
98
+ }
99
+
100
+ /**
101
+ * @protected
102
+ */
103
+ loadFiles() {
104
+ Promise.all([
105
+ DomAccess.loadScript( 'https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Cesium.js'),
106
+ DomAccess.loadStylesheet('https://cesium.com/downloads/cesiumjs/releases/1.92/Build/Cesium/Widgets/widgets.css')
107
+ ]).then(() => {
108
+ this.onFilesLoaded();
109
+ });
110
+ }
111
+
112
+ /**
113
+ *
114
+ */
115
+ onFilesLoaded() {
116
+ Cesium.Ion.defaultAccessToken = Neo.config.cesiumJsToken;
117
+ }
118
+ }
119
+
120
+ Neo.applyClassConfig(CesiumJS);
121
+
122
+ let instance = Neo.create(CesiumJS);
123
+
124
+ Neo.applyToGlobalNs(instance);
125
+
126
+ export default instance;
@@ -0,0 +1,40 @@
1
+ import Base from './Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.manager.RemotesApi
5
+ * @extends Neo.manager.Base
6
+ * @singleton
7
+ */
8
+ class RemotesApi extends Base {
9
+ static getConfig() {return {
10
+ /**
11
+ * @member {String} className='Neo.manager.RemotesApi'
12
+ * @protected
13
+ */
14
+ className: 'Neo.manager.RemotesApi',
15
+ /**
16
+ * @member {Boolean} singleton=true
17
+ * @protected
18
+ */
19
+ singleton: true
20
+ }}
21
+
22
+ /**
23
+ *
24
+ * @param msg
25
+ * @returns {Promise<any>}
26
+ */
27
+ async onMessage(msg) {
28
+ let response = await Neo.Fetch.get(msg);
29
+
30
+ return response;
31
+ }
32
+ }
33
+
34
+ Neo.applyClassConfig(RemotesApi);
35
+
36
+ let instance = Neo.create(RemotesApi);
37
+
38
+ Neo.applyToGlobalNs(instance);
39
+
40
+ export default instance;
@@ -0,0 +1,78 @@
1
+ import Base from '../core/Base.mjs';
2
+
3
+ /**
4
+ * @class Neo.remotes.Api
5
+ * @extends Neo.core.Base
6
+ * @singleton
7
+ */
8
+ class Api extends Base {
9
+ static getConfig() {return {
10
+ /**
11
+ * @member {String} className='Neo.remotes.Api'
12
+ * @protected
13
+ */
14
+ className: 'Neo.remotes.Api',
15
+ /**
16
+ * @member {Boolean} singleton=true
17
+ * @protected
18
+ */
19
+ singleton: true
20
+ }}
21
+
22
+ /**
23
+ * @param {String} service
24
+ * @param {String} method
25
+ * @returns {function(*=, *=): Promise<any>}
26
+ */
27
+ generateRemote(service, method) {
28
+ return function(...args) {
29
+ return Neo.currentWorker.promiseMessage('data', {
30
+ action: 'rpc',
31
+ method,
32
+ params: [...args],
33
+ service
34
+ })
35
+ }
36
+ }
37
+
38
+ /**
39
+ *
40
+ */
41
+ load() {
42
+ let config = Neo.config,
43
+ path = config.remotesApiUrl;
44
+
45
+ // relative paths need a special treatment
46
+ if (!path.includes('http')) {
47
+ path = config.appPath.split('/');
48
+ path.pop();
49
+ path = `../../${path.join('/')}/${config.remotesApiUrl}`;
50
+ }
51
+
52
+ fetch(path)
53
+ .then(response => response.json())
54
+ .then(data => {this.register(data)})
55
+ }
56
+
57
+ /**
58
+ * @param {Object} data
59
+ */
60
+ register(data) {
61
+ let method, ns, service;
62
+
63
+ for (service of data.services) {
64
+ for (method of service.methods) {
65
+ ns = Neo.ns(`${data.namespace}.${service.name}`, true);
66
+ ns[method.name] = this.generateRemote(service.name, method.name);
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ Neo.applyClassConfig(Api);
73
+
74
+ let instance = Neo.create(Api);
75
+
76
+ Neo.applyToGlobalNs(instance);
77
+
78
+ export default instance;
@@ -185,27 +185,26 @@ class App extends Base {
185
185
  * @param {Object} data
186
186
  */
187
187
  onLoadApplication(data) {
188
- let me = this,
188
+ let me = this,
189
+ config = Neo.config,
189
190
  path;
190
191
 
191
192
  if (data) {
192
193
  me.data = data;
193
- Neo.config.resourcesPath = data.resourcesPath;
194
+ config.resourcesPath = data.resourcesPath;
194
195
  }
195
196
 
196
197
  path = me.data.path;
197
198
 
198
- if (Neo.config.environment !== 'development') {
199
+ if (config.environment !== 'development') {
199
200
  path = path.startsWith('/') ? path.substring(1) : path;
200
201
  }
201
202
 
202
203
  me.importApp(path).then(module => {
203
204
  module.onStart();
204
205
 
205
- if (Neo.config.hash) {
206
- // short delay to ensure Component Controllers are ready
207
- setTimeout(() => HashHistory.push(Neo.config.hash), 5);
208
- }
206
+ // short delay to ensure Component Controllers are ready
207
+ config.hash && setTimeout(() => HashHistory.push(config.hash), 5);
209
208
  });
210
209
  }
211
210
 
@@ -216,7 +215,7 @@ class App extends Base {
216
215
  super.onRegisterNeoConfig(msg);
217
216
 
218
217
  let config = Neo.config,
219
- url = `resources/theme-map${Neo.config.useCssVars ? '' : '-no-vars'}.json`;
218
+ url = `resources/theme-map${config.useCssVars ? '' : '-no-vars'}.json`;
220
219
 
221
220
  if (config.environment === 'development') {
222
221
  url = `../../${url}`;
@@ -234,6 +233,7 @@ class App extends Base {
234
233
  .then(response => response.json())
235
234
  .then(data => {this.createThemeMap(data)});
236
235
 
236
+ config.remotesApiUrl && import('../remotes/Api.mjs').then(module => module.default.load());
237
237
  !config.useVdomWorker && import('../vdom/Helper.mjs');
238
238
  }
239
239
 
@@ -37,15 +37,15 @@ class Canvas extends Base {
37
37
  *
38
38
  */
39
39
  afterConnect() {
40
- let me = this,
41
- channel = new MessageChannel(),
42
- port = channel.port2;
40
+ let me = this,
41
+ channel = new MessageChannel(),
42
+ {port1, port2} = channel;
43
43
 
44
- channel.port1.onmessage = me.onMessage.bind(me);
44
+ port1.onmessage = me.onMessage.bind(me);
45
45
 
46
- me.sendMessage('app', {action: 'registerPort', transfer: port}, [port]);
46
+ me.sendMessage('app', {action: 'registerPort', transfer: port2}, [port2]);
47
47
 
48
- me.channelPorts.app = channel.port1;
48
+ me.channelPorts.app = port1;
49
49
  }
50
50
 
51
51
  /**
@@ -1,6 +1,7 @@
1
1
  import Neo from '../Neo.mjs';
2
2
  import Base from './Base.mjs';
3
3
  import Compare from '../core/Compare.mjs';
4
+ import Fetch from '../Fetch.mjs';
4
5
  import StoreManager from '../manager/Store.mjs';
5
6
  import Util from '../core/Util.mjs';
6
7
  import Xhr from '../Xhr.mjs';
@@ -13,6 +14,12 @@ import Xhr from '../Xhr.mjs';
13
14
  * @singleton
14
15
  */
15
16
  class Data extends Base {
17
+ /**
18
+ * @member {Boolean} remotesManagerLoaded=false
19
+ * @protected
20
+ */
21
+ remotesManagerLoaded = false
22
+
16
23
  static getConfig() {return {
17
24
  /**
18
25
  * @member {String} className='Neo.worker.Data'
@@ -35,15 +42,15 @@ class Data extends Base {
35
42
  *
36
43
  */
37
44
  afterConnect() {
38
- let me = this,
39
- channel = new MessageChannel(),
40
- port = channel.port2;
45
+ let me = this,
46
+ channel = new MessageChannel(),
47
+ {port1, port2} = channel;
41
48
 
42
- channel.port1.onmessage = me.onMessage.bind(me);
49
+ port1.onmessage = me.onMessage.bind(me);
43
50
 
44
- me.sendMessage('app', {action: 'registerPort', transfer: port}, [port]);
51
+ me.sendMessage('app', {action: 'registerPort', transfer: port2}, [port2]);
45
52
 
46
- me.channelPorts.app = channel.port1;
53
+ me.channelPorts.app = port1;
47
54
  }
48
55
 
49
56
  /**
@@ -52,6 +59,38 @@ class Data extends Base {
52
59
  onLoad() {
53
60
  console.log('worker.Data onLoad');
54
61
  }
62
+
63
+ /**
64
+ * @param {Object} msg
65
+ */
66
+ onRegisterNeoConfig(msg) {
67
+ super.onRegisterNeoConfig(msg);
68
+
69
+ Neo.config.remotesApiUrl && import('../manager/RemotesApi.mjs').then(module => {
70
+ this.remotesManagerLoaded = true
71
+ })
72
+ }
73
+
74
+ /**
75
+ * @param {Object} msg
76
+ */
77
+ async onRpc(msg) {
78
+ console.log('onRpc', msg);
79
+
80
+ let me = this,
81
+ response;
82
+
83
+ if (!me.remotesManagerLoaded) {
84
+ // todo: we could store calls which arrive too early and pass them to the manager once it is ready
85
+ console.warn('manager.RemotesApi not loaded yet', msg);
86
+
87
+ me.reject(msg);
88
+ } else {
89
+ response = await Neo.manager.RemotesApi.onMessage(msg);
90
+
91
+ me.resolve(msg, response);
92
+ }
93
+ }
55
94
  }
56
95
 
57
96
  Neo.applyClassConfig(Data);
@@ -160,21 +160,25 @@ class Manager extends Base {
160
160
  * Calls createWorker for each worker inside the this.workers config.
161
161
  */
162
162
  createWorkers() {
163
- let me = this,
164
- hash = location.hash,
163
+ let me = this,
164
+ config = Neo.clone(NeoConfig, true),
165
+ hash = location.hash,
165
166
  key, value;
166
167
 
168
+ // remove configs which are not relevant for the workers scope
169
+ delete config.cesiumJsToken;
170
+
167
171
  // pass the initial hash value as Neo.configs
168
172
  if (hash) {
169
- NeoConfig.hash = {
173
+ config.hash = {
170
174
  hash : DomEvents.parseHash(hash.substr(1)),
171
175
  hashString: hash.substr(1)
172
176
  };
173
177
  }
174
178
 
175
179
  for ([key, value] of Object.entries(me.workers)) {
176
- if (key === 'canvas' && !NeoConfig.useCanvasWorker ||
177
- key === 'vdom' && !NeoConfig.useVdomWorker
180
+ if (key === 'canvas' && !config.useCanvasWorker ||
181
+ key === 'vdom' && !config.useVdomWorker
178
182
  ) {
179
183
  continue;
180
184
  }
@@ -189,7 +193,7 @@ class Manager extends Base {
189
193
 
190
194
  me.sendMessage(key, {
191
195
  action: 'registerNeoConfig',
192
- data : NeoConfig
196
+ data : config
193
197
  });
194
198
  }
195
199
  }
@@ -116,18 +116,18 @@ class ServiceBase extends Base {
116
116
  * @param {Client} client
117
117
  */
118
118
  createMessageChannel(client) {
119
- let me = this,
120
- channel = new MessageChannel(),
121
- port = channel.port2;
119
+ let me = this,
120
+ channel = new MessageChannel(),
121
+ {port1, port2} = channel;
122
122
 
123
- channel.port1.onmessage = me.onMessage.bind(me);
123
+ port1.onmessage = me.onMessage.bind(me);
124
124
 
125
- me.sendMessage('app', {action: 'registerPort', transfer: port}, [port]);
125
+ me.sendMessage('app', {action: 'registerPort', transfer: port2}, [port2]);
126
126
 
127
127
  me.channelPorts.push({
128
128
  clientId : client.id,
129
129
  destination: 'app',
130
- port : channel.port1
130
+ port : port1
131
131
  });
132
132
  }
133
133
 
@@ -35,11 +35,11 @@ class VDom extends Base {
35
35
  afterConnect() {
36
36
  let me = this,
37
37
  channel = new MessageChannel(),
38
- port = channel.port2;
38
+ {port2} = channel;
39
39
 
40
40
  channel.port1.onmessage = me.onMessage.bind(me);
41
41
 
42
- me.sendMessage('app', {action: 'registerPort', transfer: port}, [port]);
42
+ me.sendMessage('app', {action: 'registerPort', transfer: port2}, [port2]);
43
43
  }
44
44
  }
45
45
 
@@ -37,12 +37,12 @@ class RemoteMethodAccess extends Base {
37
37
  };
38
38
 
39
39
  if (me.isSharedWorker) {
40
- opts.appName = opts.appName || data?.appName;
41
- opts.port = opts.port || data?.port;
40
+ opts.appName = data?.appName;
41
+ opts.port = data?.port;
42
42
  }
43
43
 
44
44
  return me.promiseMessage(origin, opts, buffer);
45
- };
45
+ }
46
46
  }
47
47
 
48
48
  /**