neo.mjs 4.0.1 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.2",
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
  },
@@ -96,6 +96,16 @@ const DefaultConfig = {
96
96
  * @type String[]
97
97
  */
98
98
  mainThreadAddons: ['DragDrop', 'Stylesheet'],
99
+ /**
100
+ * Pass the URL of a JSON-file, which contains the services and methods from your backend,
101
+ * which you want to expose to the client.
102
+ * See: https://github.com/neomjs/neo/projects/32
103
+ * @default null
104
+ * @memberOf! module:Neo
105
+ * @name config.remotesApiUrl
106
+ * @type String|null
107
+ */
108
+ remotesApiUrl: null,
99
109
  /**
100
110
  * You can visually show the amount of delta updates per second using this config.
101
111
  * 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;
@@ -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;
@@ -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
 
@@ -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';
@@ -52,6 +53,26 @@ class Data extends Base {
52
53
  onLoad() {
53
54
  console.log('worker.Data onLoad');
54
55
  }
56
+
57
+ /**
58
+ * @param {Object} msg
59
+ */
60
+ async onRpc(msg) {
61
+ console.log('onRpc', msg);
62
+
63
+ let response = await Neo.Fetch.get(msg);
64
+
65
+ this.resolve(msg, response);
66
+ }
67
+
68
+ /**
69
+ * Just for testing
70
+ * @param {Number} ms
71
+ * @returns {Promise<unknown>}
72
+ */
73
+ timeout(ms) {
74
+ return new Promise(resolve => setTimeout(resolve, ms));
75
+ }
55
76
  }
56
77
 
57
78
  Neo.applyClassConfig(Data);
@@ -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
  /**