neo.mjs 3.2.4 → 3.2.7
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/apps/ServiceWorker.mjs +36 -0
- package/buildScripts/webpack/buildThreads.mjs +7 -6
- package/buildScripts/webpack/json/build.json +4 -0
- package/examples/ServiceWorker.mjs +36 -0
- package/examples/component/helix/ImageModel.mjs +38 -0
- package/examples/component/helix/ImageStore.mjs +32 -0
- package/examples/component/helix/MainContainer.mjs +2 -0
- package/examples/component/helix/neo-config.json +2 -1
- package/package.json +6 -6
- package/resources/scss/src/component/Helix.scss +7 -1
- package/src/DefaultConfig.mjs +10 -1
- package/src/Main.mjs +16 -12
- package/src/calendar/view/MainContainer.mjs +1 -1
- package/src/calendar/view/month/Component.mjs +8 -21
- package/src/component/Gallery.mjs +3 -7
- package/src/component/Helix.mjs +26 -40
- package/src/main/addon/ServiceWorker.mjs +71 -0
- package/src/worker/App.mjs +14 -18
- package/src/worker/Manager.mjs +10 -1
- package/src/worker/ServiceBase.mjs +298 -0
- package/src/worker/mixin/RemoteMethodAccess.mjs +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Neo from '../src/Neo.mjs';
|
|
2
|
+
import * as core from '../src/core/_export.mjs';
|
|
3
|
+
import ServiceBase from '../src/worker/ServiceBase.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class Neo.ServiceWorker
|
|
7
|
+
* @extends Neo.worker.ServiceBase
|
|
8
|
+
* @singleton
|
|
9
|
+
*/
|
|
10
|
+
class ServiceWorker extends ServiceBase {
|
|
11
|
+
static getConfig() {return {
|
|
12
|
+
/**
|
|
13
|
+
* @member {String} className='Neo.ServiceWorker'
|
|
14
|
+
* @protected
|
|
15
|
+
*/
|
|
16
|
+
className: 'Neo.ServiceWorker',
|
|
17
|
+
/**
|
|
18
|
+
* @member {Boolean} singleton=true
|
|
19
|
+
* @protected
|
|
20
|
+
*/
|
|
21
|
+
singleton: true,
|
|
22
|
+
/**
|
|
23
|
+
* @member {String} workerId='service'
|
|
24
|
+
* @protected
|
|
25
|
+
*/
|
|
26
|
+
workerId: 'service'
|
|
27
|
+
}}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Neo.applyClassConfig(ServiceWorker);
|
|
31
|
+
|
|
32
|
+
let instance = Neo.create(ServiceWorker);
|
|
33
|
+
|
|
34
|
+
Neo.applyToGlobalNs(instance);
|
|
35
|
+
|
|
36
|
+
export default instance;
|
|
@@ -61,7 +61,7 @@ if (programOpts.info) {
|
|
|
61
61
|
type : 'list',
|
|
62
62
|
name : 'threads',
|
|
63
63
|
message: 'Please choose the threads to build:',
|
|
64
|
-
choices: ['all', 'app', 'canvas', 'data', 'main', 'vdom'],
|
|
64
|
+
choices: ['all', 'app', 'canvas', 'data', 'main', 'service', 'vdom'],
|
|
65
65
|
default: 'all'
|
|
66
66
|
});
|
|
67
67
|
}
|
|
@@ -88,11 +88,12 @@ if (programOpts.info) {
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
function parseThreads(tPath) {
|
|
91
|
-
(threads === 'all' || threads === 'main')
|
|
92
|
-
(threads === 'all' || threads === 'app')
|
|
93
|
-
(threads === 'all' || threads === 'canvas')
|
|
94
|
-
(threads === 'all' || threads === 'data')
|
|
95
|
-
(threads === 'all' || threads === '
|
|
91
|
+
(threads === 'all' || threads === 'main') && spawnSync(webpack, ['--config', `${tPath}.main.mjs`], cpOpts);
|
|
92
|
+
(threads === 'all' || threads === 'app') && spawnSync(webpack, ['--config', `${tPath}.appworker.mjs`, `--env insideNeo=${insideNeo}`], cpOpts);
|
|
93
|
+
(threads === 'all' || threads === 'canvas') && spawnSync(webpack, ['--config', `${tPath}.worker.mjs`, `--env insideNeo=${insideNeo} worker=canvas`], cpOpts);
|
|
94
|
+
(threads === 'all' || threads === 'data') && spawnSync(webpack, ['--config', `${tPath}.worker.mjs`, `--env insideNeo=${insideNeo} worker=data`], cpOpts);
|
|
95
|
+
(threads === 'all' || threads === 'service') && spawnSync(webpack, ['--config', `${tPath}.worker.mjs`, `--env insideNeo=${insideNeo} worker=service`], cpOpts);
|
|
96
|
+
(threads === 'all' || threads === 'vdom') && spawnSync(webpack, ['--config', `${tPath}.worker.mjs`, `--env insideNeo=${insideNeo} worker=vdom`], cpOpts);
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
// dist/development
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Neo from '../src/Neo.mjs';
|
|
2
|
+
import * as core from '../src/core/_export.mjs';
|
|
3
|
+
import ServiceBase from '../src/worker/ServiceBase.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class Neo.ServiceWorker
|
|
7
|
+
* @extends Neo.worker.ServiceBase
|
|
8
|
+
* @singleton
|
|
9
|
+
*/
|
|
10
|
+
class ServiceWorker extends ServiceBase {
|
|
11
|
+
static getConfig() {return {
|
|
12
|
+
/**
|
|
13
|
+
* @member {String} className='Neo.ServiceWorker'
|
|
14
|
+
* @protected
|
|
15
|
+
*/
|
|
16
|
+
className: 'Neo.ServiceWorker',
|
|
17
|
+
/**
|
|
18
|
+
* @member {Boolean} singleton=true
|
|
19
|
+
* @protected
|
|
20
|
+
*/
|
|
21
|
+
singleton: true,
|
|
22
|
+
/**
|
|
23
|
+
* @member {String} workerId='service'
|
|
24
|
+
* @protected
|
|
25
|
+
*/
|
|
26
|
+
workerId: 'service'
|
|
27
|
+
}}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Neo.applyClassConfig(ServiceWorker);
|
|
31
|
+
|
|
32
|
+
let instance = Neo.create(ServiceWorker);
|
|
33
|
+
|
|
34
|
+
Neo.applyToGlobalNs(instance);
|
|
35
|
+
|
|
36
|
+
export default instance;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Model from '../../../src/data/Model.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @class Neo.examples.component.helix.ImageModel
|
|
5
|
+
* @extends Neo.data.Model
|
|
6
|
+
*/
|
|
7
|
+
class ImageModel extends Model {
|
|
8
|
+
static getConfig() {return {
|
|
9
|
+
/**
|
|
10
|
+
* @member {String} className='Neo.examples.component.helix.ImageModel'
|
|
11
|
+
* @protected
|
|
12
|
+
*/
|
|
13
|
+
className: 'Neo.examples.component.helix.ImageModel',
|
|
14
|
+
/**
|
|
15
|
+
* @member {Object[]} fields
|
|
16
|
+
*/
|
|
17
|
+
fields: [{
|
|
18
|
+
name: 'firstname',
|
|
19
|
+
type: 'String'
|
|
20
|
+
}, {
|
|
21
|
+
name: 'id',
|
|
22
|
+
type: 'Integer'
|
|
23
|
+
}, {
|
|
24
|
+
name: 'image',
|
|
25
|
+
type: 'String'
|
|
26
|
+
}, {
|
|
27
|
+
name: 'isOnline',
|
|
28
|
+
type: 'Boolean'
|
|
29
|
+
}, {
|
|
30
|
+
name: 'lastname',
|
|
31
|
+
type: 'String'
|
|
32
|
+
}]
|
|
33
|
+
}}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Neo.applyClassConfig(ImageModel);
|
|
37
|
+
|
|
38
|
+
export default ImageModel;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import ImageModel from './ImageModel.mjs';
|
|
2
|
+
import Store from '../../../src/data/Store.mjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @class Neo.examples.component.helix.ImageStore
|
|
6
|
+
* @extends Neo.data.Store
|
|
7
|
+
*/
|
|
8
|
+
class ImageStore extends Store {
|
|
9
|
+
static getConfig() {return {
|
|
10
|
+
/**
|
|
11
|
+
* @member {String} className='Neo.examples.component.helix.ImageModel'
|
|
12
|
+
* @protected
|
|
13
|
+
*/
|
|
14
|
+
className: 'Neo.examples.component.helix.ImageStore',
|
|
15
|
+
/**
|
|
16
|
+
* @member {Boolean} autoLoad=true
|
|
17
|
+
*/
|
|
18
|
+
autoLoad: true,
|
|
19
|
+
/**
|
|
20
|
+
* @member {Neo.data.Model} model=ImageModel
|
|
21
|
+
*/
|
|
22
|
+
model: ImageModel,
|
|
23
|
+
/**
|
|
24
|
+
* @member {String} url='../../resources/examples/data/ai_contacts.json'
|
|
25
|
+
*/
|
|
26
|
+
url: '../../resources/examples/data/ai_contacts.json'
|
|
27
|
+
}}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
Neo.applyClassConfig(ImageStore);
|
|
31
|
+
|
|
32
|
+
export default ImageStore;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import CheckBox from '../../../src/form/field/CheckBox.mjs';
|
|
2
2
|
import Helix from '../../../src/component/Helix.mjs';
|
|
3
|
+
import ImageStore from './ImageStore.mjs';
|
|
3
4
|
import NumberField from '../../../src/form/field/Number.mjs';
|
|
4
5
|
import Panel from '../../../src/container/Panel.mjs';
|
|
5
6
|
import RangeField from '../../../src/form/field/Range.mjs';
|
|
@@ -312,6 +313,7 @@ class MainContainer extends Viewport {
|
|
|
312
313
|
me.helix = Neo.create({
|
|
313
314
|
module: Helix,
|
|
314
315
|
id : 'neo-helix-1',
|
|
316
|
+
store : ImageStore,
|
|
315
317
|
...me.helixConfig
|
|
316
318
|
});
|
|
317
319
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neo.mjs",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.7",
|
|
4
4
|
"description": "The webworkers driven UI framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -41,16 +41,16 @@
|
|
|
41
41
|
"chalk": "^5.0.0",
|
|
42
42
|
"clean-webpack-plugin": "^4.0.0",
|
|
43
43
|
"commander": "^9.0.0",
|
|
44
|
-
"cssnano": "^5.0
|
|
44
|
+
"cssnano": "^5.1.0",
|
|
45
45
|
"envinfo": "^7.8.1",
|
|
46
|
-
"fs-extra": "^10.0.
|
|
46
|
+
"fs-extra": "^10.0.1",
|
|
47
47
|
"highlightjs-line-numbers.js": "^2.8.0",
|
|
48
48
|
"inquirer": "^8.1.5",
|
|
49
49
|
"neo-jsdoc": "^1.0.1",
|
|
50
50
|
"neo-jsdoc-x": "^1.0.4",
|
|
51
|
-
"postcss": "^8.4.
|
|
52
|
-
"sass": "^1.49.
|
|
53
|
-
"webpack": "^5.
|
|
51
|
+
"postcss": "^8.4.7",
|
|
52
|
+
"sass": "^1.49.9",
|
|
53
|
+
"webpack": "^5.70.0",
|
|
54
54
|
"webpack-cli": "^4.9.2",
|
|
55
55
|
"webpack-dev-server": "4.7.4",
|
|
56
56
|
"webpack-hook-plugin": "^1.0.7",
|
|
@@ -16,6 +16,12 @@
|
|
|
16
16
|
outline: 0;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
+
&.neo-follow-selection {
|
|
20
|
+
.neo-helix-item {
|
|
21
|
+
transition: all 0.1s linear;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
19
25
|
&.neo-transition-100 {
|
|
20
26
|
.neo-helix-item {
|
|
21
27
|
transition: all 0.1s ease-in-out !important;
|
|
@@ -87,4 +93,4 @@
|
|
|
87
93
|
right : 0;
|
|
88
94
|
text-shadow : 0 0 10px #61DFE5;
|
|
89
95
|
}
|
|
90
|
-
}
|
|
96
|
+
}
|
package/src/DefaultConfig.mjs
CHANGED
|
@@ -134,7 +134,7 @@ const DefaultConfig = {
|
|
|
134
134
|
* Experimental flag if an offscreen canvas worker should get created.
|
|
135
135
|
* @default false
|
|
136
136
|
* @memberOf! module:Neo
|
|
137
|
-
* @name config.
|
|
137
|
+
* @name config.useCanvasWorker
|
|
138
138
|
* @type Boolean
|
|
139
139
|
*/
|
|
140
140
|
useCanvasWorker: false,
|
|
@@ -163,6 +163,15 @@ const DefaultConfig = {
|
|
|
163
163
|
* @type Boolean
|
|
164
164
|
*/
|
|
165
165
|
useGoogleAnalytics: false,
|
|
166
|
+
/**
|
|
167
|
+
* True will add the ServiceWorker main thread addon to support caching of assets (PWA)
|
|
168
|
+
* See: https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API
|
|
169
|
+
* @default false
|
|
170
|
+
* @memberOf! module:Neo
|
|
171
|
+
* @name config.useServiceWorker
|
|
172
|
+
* @type Boolean
|
|
173
|
+
*/
|
|
174
|
+
useServiceWorker: false,
|
|
166
175
|
/**
|
|
167
176
|
* Creates App, Data & VDom as SharedWorkers.
|
|
168
177
|
* Set this one to true in case you want to connect multiple main threads.
|
package/src/Main.mjs
CHANGED
|
@@ -188,9 +188,11 @@ class Main extends core.Base {
|
|
|
188
188
|
*
|
|
189
189
|
*/
|
|
190
190
|
async onDomContentLoaded() {
|
|
191
|
-
let me
|
|
192
|
-
config
|
|
193
|
-
|
|
191
|
+
let me = this,
|
|
192
|
+
config = Neo.config,
|
|
193
|
+
mainThreadAddons = config.mainThreadAddons,
|
|
194
|
+
imports = [],
|
|
195
|
+
modules;
|
|
194
196
|
|
|
195
197
|
DomAccess.onDomContentLoaded();
|
|
196
198
|
|
|
@@ -203,18 +205,20 @@ class Main extends core.Base {
|
|
|
203
205
|
__webpack_require__.p = config.basePath.substring(6);
|
|
204
206
|
}
|
|
205
207
|
|
|
206
|
-
config.mainThreadAddons.forEach(addon => {
|
|
207
|
-
if (addon !== 'AnalyticsByGoogle') {
|
|
208
|
-
imports.push(import(`./main/addon/${addon}.mjs`));
|
|
209
|
-
}
|
|
210
|
-
});
|
|
211
|
-
|
|
212
208
|
// intended for the online examples where we need an easy way to add GA to every generated app
|
|
213
|
-
if (config.useGoogleAnalytics
|
|
214
|
-
|
|
209
|
+
if (config.useGoogleAnalytics && !mainThreadAddons.includes('AnalyticsByGoogle')) {
|
|
210
|
+
mainThreadAddons.push('AnalyticsByGoogle');
|
|
215
211
|
}
|
|
216
212
|
|
|
217
|
-
|
|
213
|
+
if (config.useServiceWorker && !mainThreadAddons.includes('ServiceWorker')) {
|
|
214
|
+
mainThreadAddons.push('ServiceWorker');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
mainThreadAddons.forEach(addon => {
|
|
218
|
+
imports.push(import(`./main/addon/${addon}.mjs`));
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
modules = await Promise.all(imports);
|
|
218
222
|
|
|
219
223
|
me.addon = {};
|
|
220
224
|
|
|
@@ -500,7 +500,7 @@ class MainContainer extends Container {
|
|
|
500
500
|
return import('./SettingsContainer.mjs').then(module => {
|
|
501
501
|
me.items[1].add({
|
|
502
502
|
module : module.default,
|
|
503
|
-
collapsed
|
|
503
|
+
collapsed,
|
|
504
504
|
removeInactiveCards: me.removeInactiveCards,
|
|
505
505
|
style : {marginRight: !collapsed ? '0' : `-${me.settingsContainerWidth}px`},
|
|
506
506
|
width : me.settingsContainerWidth,
|
|
@@ -554,10 +554,7 @@ class Component extends BaseComponent {
|
|
|
554
554
|
date.setDate(date.getDate() + 1);
|
|
555
555
|
}
|
|
556
556
|
|
|
557
|
-
return {
|
|
558
|
-
header: header,
|
|
559
|
-
row : row
|
|
560
|
-
}
|
|
557
|
+
return {header, row}
|
|
561
558
|
}
|
|
562
559
|
|
|
563
560
|
/**
|
|
@@ -626,16 +623,12 @@ class Component extends BaseComponent {
|
|
|
626
623
|
let oldPath = data.oldPath,
|
|
627
624
|
path = data.path;
|
|
628
625
|
|
|
629
|
-
if (oldPath) {
|
|
630
|
-
|
|
631
|
-
Neo.applyDeltas(this.appName, {id: oldPath[0].id, cls: {remove: ['neo-focus']}});
|
|
632
|
-
}
|
|
626
|
+
if (oldPath?.[0]?.cls.includes('neo-event')) {
|
|
627
|
+
Neo.applyDeltas(this.appName, {id: oldPath[0].id, cls: {remove: ['neo-focus']}});
|
|
633
628
|
}
|
|
634
629
|
|
|
635
|
-
if (path) {
|
|
636
|
-
|
|
637
|
-
Neo.applyDeltas(this.appName, {id: path[0].id, cls: {add: ['neo-focus']}});
|
|
638
|
-
}
|
|
630
|
+
if (path?.[0]?.cls.includes('neo-event')) {
|
|
631
|
+
Neo.applyDeltas(this.appName, {id: path[0].id, cls: {add: ['neo-focus']}});
|
|
639
632
|
}
|
|
640
633
|
}
|
|
641
634
|
|
|
@@ -668,9 +661,7 @@ class Component extends BaseComponent {
|
|
|
668
661
|
|
|
669
662
|
week = me.createWeek(DateUtil.clone(date));
|
|
670
663
|
|
|
671
|
-
|
|
672
|
-
container.cn.push(week.header);
|
|
673
|
-
}
|
|
664
|
+
week.header && container.cn.push(week.header);
|
|
674
665
|
|
|
675
666
|
container.cn.push(week.row);
|
|
676
667
|
}
|
|
@@ -702,9 +693,7 @@ class Component extends BaseComponent {
|
|
|
702
693
|
|
|
703
694
|
container.cn.unshift(week.row);
|
|
704
695
|
|
|
705
|
-
|
|
706
|
-
container.cn.unshift(week.header);
|
|
707
|
-
}
|
|
696
|
+
week.header && container.cn.unshift(week.header);
|
|
708
697
|
}
|
|
709
698
|
|
|
710
699
|
me.promiseVdomUpdate(me.vdom).then(() => {
|
|
@@ -723,9 +712,7 @@ class Component extends BaseComponent {
|
|
|
723
712
|
me.vdom = vdom;
|
|
724
713
|
}
|
|
725
714
|
|
|
726
|
-
|
|
727
|
-
clearTimeout(me.scrollTaskId);
|
|
728
|
-
}
|
|
715
|
+
me.scrollTaskId && clearTimeout(me.scrollTaskId);
|
|
729
716
|
|
|
730
717
|
me.scrollTaskId = setTimeout(me.onWheelEnd.bind(me), 300);
|
|
731
718
|
}
|
|
@@ -576,15 +576,11 @@ class Gallery extends Component {
|
|
|
576
576
|
* @param {Object} data
|
|
577
577
|
*/
|
|
578
578
|
onMouseWheel(data) {
|
|
579
|
-
let me
|
|
580
|
-
deltaX = data.deltaX,
|
|
581
|
-
deltaY = data.deltaY,
|
|
582
|
-
translateX = me.translateX,
|
|
583
|
-
translateZ = me.translateZ;
|
|
579
|
+
let me = this;
|
|
584
580
|
|
|
585
581
|
if (me.mouseWheelEnabled) {
|
|
586
|
-
me._translateX = translateX - (deltaX * me.mouseWheelDeltaX); // silent update
|
|
587
|
-
me._translateZ = translateZ + (deltaY * me.mouseWheelDeltaY); // silent update
|
|
582
|
+
me._translateX = me.translateX - (me.deltaX * me.mouseWheelDeltaX); // silent update
|
|
583
|
+
me._translateZ = me.translateZ + (me.deltaY * me.mouseWheelDeltaY); // silent update
|
|
588
584
|
|
|
589
585
|
me.moveOrigin();
|
|
590
586
|
|
package/src/component/Helix.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import ClassSystemUtil from '../util/ClassSystem.mjs';
|
|
2
|
-
import Collection from '../collection/Base.mjs'
|
|
3
2
|
import Component from './Base.mjs';
|
|
4
3
|
import HelixModel from '../selection/HelixModel.mjs';
|
|
5
4
|
import Matrix from '../util/Matrix.mjs';
|
|
@@ -272,6 +271,19 @@ class Helix extends Component {
|
|
|
272
271
|
me.domListeners = domListeners;
|
|
273
272
|
}
|
|
274
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Triggered after the followSelection config got changed
|
|
276
|
+
* @param {Boolean} value
|
|
277
|
+
* @param {Boolean} oldValue
|
|
278
|
+
* @protected
|
|
279
|
+
*/
|
|
280
|
+
afterSetFollowSelection(value, oldValue) {
|
|
281
|
+
let cls = this.cls;
|
|
282
|
+
|
|
283
|
+
NeoArray[value ? 'add' : 'remove'](cls, 'neo-follow-selection');
|
|
284
|
+
this.cls = cls;
|
|
285
|
+
}
|
|
286
|
+
|
|
275
287
|
/**
|
|
276
288
|
* Triggered after the flipped config got changed
|
|
277
289
|
* @param {Boolean} value
|
|
@@ -436,20 +448,9 @@ class Helix extends Component {
|
|
|
436
448
|
|
|
437
449
|
oldValue?.destroy();
|
|
438
450
|
|
|
439
|
-
|
|
440
|
-
if (value) {
|
|
441
|
-
return ClassSystemUtil.beforeSetInstance(value, Store, {
|
|
442
|
-
listeners : {
|
|
443
|
-
load : me.onStoreLoad,
|
|
444
|
-
sort : me.onSort,
|
|
445
|
-
scope: me
|
|
446
|
-
}
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
return Neo.create(Collection, {
|
|
451
|
-
keyProperty: 'id',
|
|
451
|
+
return ClassSystemUtil.beforeSetInstance(value, Store, {
|
|
452
452
|
listeners : {
|
|
453
|
+
load : me.onStoreLoad,
|
|
453
454
|
sort : me.onSort,
|
|
454
455
|
scope: me
|
|
455
456
|
}
|
|
@@ -746,11 +747,8 @@ class Helix extends Component {
|
|
|
746
747
|
Neo.currentWorker.promiseMessage('main', {
|
|
747
748
|
action : 'readDom',
|
|
748
749
|
appName : me.appName,
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
'offsetHeight',
|
|
752
|
-
'offsetWidth'
|
|
753
|
-
]
|
|
750
|
+
attributes: ['offsetHeight', 'offsetWidth'],
|
|
751
|
+
vnodeId : me.id
|
|
754
752
|
}).then(data => {
|
|
755
753
|
me.offsetHeight = data.attributes.offsetHeight;
|
|
756
754
|
me.offsetWidth = data.attributes.offsetWidth;
|
|
@@ -795,15 +793,7 @@ class Helix extends Component {
|
|
|
795
793
|
*/
|
|
796
794
|
onConstructed() {
|
|
797
795
|
super.onConstructed();
|
|
798
|
-
|
|
799
|
-
let me = this;
|
|
800
|
-
|
|
801
|
-
me.selectionModel?.register(me);
|
|
802
|
-
|
|
803
|
-
// load data for the example collection
|
|
804
|
-
if (!(me.store instanceof Store)) {
|
|
805
|
-
me.loadData();
|
|
806
|
-
}
|
|
796
|
+
this.selectionModel?.register(this);
|
|
807
797
|
}
|
|
808
798
|
|
|
809
799
|
/**
|
|
@@ -825,15 +815,11 @@ class Helix extends Component {
|
|
|
825
815
|
* @param {Object} data
|
|
826
816
|
*/
|
|
827
817
|
onMouseWheel(data) {
|
|
828
|
-
let me
|
|
829
|
-
deltaX = data.deltaX,
|
|
830
|
-
deltaY = data.deltaY,
|
|
831
|
-
rotationAngle = me.rotationAngle,
|
|
832
|
-
translateZ = me.translateZ;
|
|
818
|
+
let me = this;
|
|
833
819
|
|
|
834
820
|
if (me.mouseWheelEnabled && me[lockWheel]) {
|
|
835
|
-
me._rotationAngle = rotationAngle + (deltaX * me.mouseWheelDeltaX); // silent update
|
|
836
|
-
me._translateZ = translateZ + (deltaY * me.mouseWheelDeltaY); // silent update
|
|
821
|
+
me._rotationAngle = me.rotationAngle + (data.deltaX * me.mouseWheelDeltaX); // silent update
|
|
822
|
+
me._translateZ = me.translateZ + (data.deltaY * me.mouseWheelDeltaY); // silent update
|
|
837
823
|
|
|
838
824
|
me.refresh();
|
|
839
825
|
|
|
@@ -849,7 +835,7 @@ class Helix extends Component {
|
|
|
849
835
|
onSelectionChange(value, oldValue) {
|
|
850
836
|
let me = this;
|
|
851
837
|
|
|
852
|
-
if (me.followSelection && value
|
|
838
|
+
if (me.followSelection && value?.[0]) {
|
|
853
839
|
me.applyItemTransitions(me.moveToSelectedItem, 100, value[0]);
|
|
854
840
|
}
|
|
855
841
|
}
|
|
@@ -860,7 +846,7 @@ class Helix extends Component {
|
|
|
860
846
|
onSort() {
|
|
861
847
|
let me = this;
|
|
862
848
|
|
|
863
|
-
if (me[itemsMounted] === true) {
|
|
849
|
+
if (me[itemsMounted] === true) {
|
|
864
850
|
me.applyItemTransitions(me.sortItems, 1000);
|
|
865
851
|
}
|
|
866
852
|
}
|
|
@@ -915,9 +901,9 @@ class Helix extends Component {
|
|
|
915
901
|
s = Math.sin(angle * Math.PI / 180);
|
|
916
902
|
c = Math.cos(angle * Math.PI / 180);
|
|
917
903
|
|
|
918
|
-
x = -300 + radius * s
|
|
919
|
-
y = -400 + angle
|
|
920
|
-
z = 99800 + radius * c
|
|
904
|
+
x = -300 + radius * s + translateX;
|
|
905
|
+
y = -400 + angle * deltaY + translateY;
|
|
906
|
+
z = 99800 + radius * c + translateZ;
|
|
921
907
|
|
|
922
908
|
matrix.items = [
|
|
923
909
|
[c, 0, -s, 0],
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import Base from '../../core/Base.mjs';
|
|
2
|
+
import RemoteMethodAccess from '../../worker/mixin/RemoteMethodAccess.mjs';
|
|
3
|
+
import WorkerManager from '../../worker/Manager.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a ServiceWorker instance, in case Neo.config.useServiceWorker is set to true
|
|
7
|
+
* @class Neo.main.addon.ServiceWorker
|
|
8
|
+
* @extends Neo.core.Base
|
|
9
|
+
* @singleton
|
|
10
|
+
*/
|
|
11
|
+
class ServiceWorker extends Base {
|
|
12
|
+
static getConfig() {return {
|
|
13
|
+
/**
|
|
14
|
+
* @member {String} className='Neo.main.addon.ServiceWorker'
|
|
15
|
+
* @protected
|
|
16
|
+
*/
|
|
17
|
+
className: 'Neo.main.addon.ServiceWorker',
|
|
18
|
+
/**
|
|
19
|
+
* @member {String[]|Neo.core.Base[]|null} mixins=[RemoteMethodAccess]
|
|
20
|
+
*/
|
|
21
|
+
mixins: [RemoteMethodAccess],
|
|
22
|
+
/**
|
|
23
|
+
* @member {ServiceWorkerRegistration|null} registration=null
|
|
24
|
+
* @protected
|
|
25
|
+
*/
|
|
26
|
+
registration: null,
|
|
27
|
+
/**
|
|
28
|
+
* @member {Boolean} singleton=true
|
|
29
|
+
* @protected
|
|
30
|
+
*/
|
|
31
|
+
singleton: true
|
|
32
|
+
}}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param {Object} config
|
|
36
|
+
*/
|
|
37
|
+
construct(config) {
|
|
38
|
+
if ('serviceWorker' in navigator) {
|
|
39
|
+
let me = this,
|
|
40
|
+
config = Neo.config,
|
|
41
|
+
devMode = config.environment === 'development',
|
|
42
|
+
fileName = devMode ? 'ServiceWorker.mjs' : 'serviceworker.js',
|
|
43
|
+
folder = window.location.pathname.includes('/examples/') ? 'examples/' : 'apps/',
|
|
44
|
+
opts = devMode ? {type: 'module'} : {},
|
|
45
|
+
serviceWorker = navigator.serviceWorker;
|
|
46
|
+
|
|
47
|
+
serviceWorker.register(config.basePath + folder + fileName, opts)
|
|
48
|
+
.then(registration => {
|
|
49
|
+
me.registration = registration;
|
|
50
|
+
|
|
51
|
+
serviceWorker.ready.then(() => {
|
|
52
|
+
serviceWorker.onmessage = WorkerManager.onWorkerMessage.bind(WorkerManager);
|
|
53
|
+
|
|
54
|
+
WorkerManager.sendMessage('service', {
|
|
55
|
+
action: 'registerNeoConfig',
|
|
56
|
+
data : config,
|
|
57
|
+
port : registration.active
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
Neo.applyClassConfig(ServiceWorker);
|
|
66
|
+
|
|
67
|
+
let instance = Neo.create(ServiceWorker);
|
|
68
|
+
|
|
69
|
+
Neo.applyToGlobalNs(instance);
|
|
70
|
+
|
|
71
|
+
export default instance;
|
package/src/worker/App.mjs
CHANGED
|
@@ -72,7 +72,7 @@ class App extends Base {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
* @param {
|
|
75
|
+
* @param {Object} data
|
|
76
76
|
*/
|
|
77
77
|
createThemeMap(data) {
|
|
78
78
|
Neo.ns('Neo.cssMap.fileInfo', true);
|
|
@@ -146,21 +146,19 @@ class App extends Base {
|
|
|
146
146
|
|
|
147
147
|
themeFolders = Neo.ns(mapClassName || className, false, cssMap.fileInfo);
|
|
148
148
|
|
|
149
|
-
if (themeFolders) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
ns = Neo.ns(`${lAppName}.${classPath}`, true, cssMap);
|
|
149
|
+
if (themeFolders && !Neo.ns(`${lAppName}.${className}`, false, cssMap)) {
|
|
150
|
+
classPath = className.split('.');
|
|
151
|
+
fileName = classPath.pop();
|
|
152
|
+
classPath = classPath.join('.');
|
|
153
|
+
ns = Neo.ns(`${lAppName}.${classPath}`, true, cssMap);
|
|
155
154
|
|
|
156
|
-
|
|
155
|
+
ns[fileName] = true;
|
|
157
156
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
157
|
+
Neo.main.addon.Stylesheet.addThemeFiles({
|
|
158
|
+
appName,
|
|
159
|
+
className: mapClassName || className,
|
|
160
|
+
folders : themeFolders
|
|
161
|
+
});
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
164
|
}
|
|
@@ -236,9 +234,7 @@ class App extends Base {
|
|
|
236
234
|
.then(response => response.json())
|
|
237
235
|
.then(data => {this.createThemeMap(data)});
|
|
238
236
|
|
|
239
|
-
|
|
240
|
-
import('../vdom/Helper.mjs');
|
|
241
|
-
}
|
|
237
|
+
!config.useVdomWorker && import('../vdom/Helper.mjs');
|
|
242
238
|
}
|
|
243
239
|
|
|
244
240
|
/**
|
|
@@ -269,7 +265,7 @@ class App extends Base {
|
|
|
269
265
|
this.onRegisterApp({ appName });
|
|
270
266
|
|
|
271
267
|
this.sendMessage('main', {
|
|
272
|
-
action:'registerAppName',
|
|
268
|
+
action: 'registerAppName',
|
|
273
269
|
appName
|
|
274
270
|
});
|
|
275
271
|
}
|
package/src/worker/Manager.mjs
CHANGED
|
@@ -218,6 +218,10 @@ class Manager extends Base {
|
|
|
218
218
|
* @returns {Worker}
|
|
219
219
|
*/
|
|
220
220
|
getWorker(name) {
|
|
221
|
+
if (name === 'service') {
|
|
222
|
+
return navigator.serviceWorker?.controller;
|
|
223
|
+
}
|
|
224
|
+
|
|
221
225
|
return name instanceof Worker ? name : this.workers[name].worker;
|
|
222
226
|
}
|
|
223
227
|
|
|
@@ -386,7 +390,12 @@ class Manager extends Base {
|
|
|
386
390
|
message, worker;
|
|
387
391
|
|
|
388
392
|
if (!me.stopCommunication) {
|
|
389
|
-
|
|
393
|
+
if (opts.port) {
|
|
394
|
+
worker = opts.port;
|
|
395
|
+
delete opts.port;
|
|
396
|
+
} else {
|
|
397
|
+
worker = me.getWorker(dest);
|
|
398
|
+
}
|
|
390
399
|
|
|
391
400
|
if (!worker) {
|
|
392
401
|
throw new Error('Called sendMessage for a worker that does not exist: ' + dest);
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
import Base from '../core/Base.mjs';
|
|
2
|
+
import Message from './Message.mjs';
|
|
3
|
+
import RemoteMethodAccess from './mixin/RemoteMethodAccess.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @class Neo.worker.ServiceBase
|
|
7
|
+
* @extends Neo.core.Base
|
|
8
|
+
* @abstract
|
|
9
|
+
*/
|
|
10
|
+
class ServiceBase extends Base {
|
|
11
|
+
/**
|
|
12
|
+
* @member {Object[]|null} channelPorts=null
|
|
13
|
+
* @protected
|
|
14
|
+
*/
|
|
15
|
+
channelPorts = null
|
|
16
|
+
/**
|
|
17
|
+
* @member {Client|null} lastClient=null
|
|
18
|
+
* @protected
|
|
19
|
+
*/
|
|
20
|
+
lastClient = null
|
|
21
|
+
/**
|
|
22
|
+
* @member {Object[]} promises=[]
|
|
23
|
+
* @protected
|
|
24
|
+
*/
|
|
25
|
+
promises = []
|
|
26
|
+
/**
|
|
27
|
+
* @member {String[]} remotes=[]
|
|
28
|
+
* @protected
|
|
29
|
+
*/
|
|
30
|
+
remotes = []
|
|
31
|
+
|
|
32
|
+
static getConfig() {return {
|
|
33
|
+
/**
|
|
34
|
+
* @member {String} className='Neo.worker.ServiceBase'
|
|
35
|
+
* @protected
|
|
36
|
+
*/
|
|
37
|
+
className: 'Neo.worker.ServiceBase',
|
|
38
|
+
/**
|
|
39
|
+
* @member {String} cacheName='neo-runtime'
|
|
40
|
+
*/
|
|
41
|
+
cacheName: 'neo-runtime',
|
|
42
|
+
/**
|
|
43
|
+
* @member {String[]|null} cachePaths
|
|
44
|
+
*/
|
|
45
|
+
cachePaths: [
|
|
46
|
+
'raw.githubusercontent.com/',
|
|
47
|
+
'/dist/production/',
|
|
48
|
+
'/fontawesome',
|
|
49
|
+
'/resources/'
|
|
50
|
+
],
|
|
51
|
+
/**
|
|
52
|
+
* @member {String[]|Neo.core.Base[]|null} mixins=[RemoteMethodAccess]
|
|
53
|
+
*/
|
|
54
|
+
mixins: [RemoteMethodAccess],
|
|
55
|
+
/**
|
|
56
|
+
* Remote method access for other workers
|
|
57
|
+
* @member {Object} remote={app: [//...]}
|
|
58
|
+
* @protected
|
|
59
|
+
*/
|
|
60
|
+
remote: {
|
|
61
|
+
app: [
|
|
62
|
+
'clearCache',
|
|
63
|
+
'clearCaches'
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
/**
|
|
67
|
+
* @member {String|null} workerId=null
|
|
68
|
+
* @protected
|
|
69
|
+
*/
|
|
70
|
+
workerId: null
|
|
71
|
+
}}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @param {Object} config
|
|
75
|
+
*/
|
|
76
|
+
construct(config) {
|
|
77
|
+
super.construct(config);
|
|
78
|
+
|
|
79
|
+
let me = this,
|
|
80
|
+
bind = name => me[name].bind(me);
|
|
81
|
+
|
|
82
|
+
me.channelPorts = [];
|
|
83
|
+
|
|
84
|
+
Object.assign(globalThis, {
|
|
85
|
+
onactivate: bind('onActivate'),
|
|
86
|
+
onfetch : bind('onFetch'),
|
|
87
|
+
oninstall : bind('onInstall'),
|
|
88
|
+
onmessage : bind('onMessage')
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
Neo.currentWorker = me;
|
|
92
|
+
Neo.workerId = me.workerId;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* @param {String} name=this.cacheName
|
|
97
|
+
*/
|
|
98
|
+
clearCache(name=this.cacheName) {
|
|
99
|
+
caches.keys()
|
|
100
|
+
.then(cacheNames => cacheNames.filter(cacheName => cacheName === name))
|
|
101
|
+
.then(cachesToDelete => Promise.all(cachesToDelete.map(cacheToDelete => caches.delete(cacheToDelete))))
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
*
|
|
106
|
+
*/
|
|
107
|
+
clearCaches() {
|
|
108
|
+
caches.keys()
|
|
109
|
+
.then(cachesToDelete => Promise.all(cachesToDelete.map(cacheToDelete => caches.delete(cacheToDelete))))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @param {Client} client
|
|
114
|
+
*/
|
|
115
|
+
createMessageChannel(client) {
|
|
116
|
+
let me = this,
|
|
117
|
+
channel = new MessageChannel(),
|
|
118
|
+
port = channel.port2;
|
|
119
|
+
|
|
120
|
+
channel.port1.onmessage = me.onMessage.bind(me);
|
|
121
|
+
|
|
122
|
+
me.sendMessage('app', {action: 'registerPort', transfer: port}, [port]);
|
|
123
|
+
|
|
124
|
+
me.channelPorts.push({
|
|
125
|
+
clientId : client.id,
|
|
126
|
+
destination: 'app',
|
|
127
|
+
port : channel.port1
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
*
|
|
133
|
+
* @param {String} destination
|
|
134
|
+
* @param {String} clientId=this.lastClient.id
|
|
135
|
+
* @returns {MessagePort|null}
|
|
136
|
+
*/
|
|
137
|
+
getPort(destination, clientId=this.lastClient?.id) {
|
|
138
|
+
for (let port of this.channelPorts) {
|
|
139
|
+
if (clientId === port.clientId && destination === port.destination) {
|
|
140
|
+
return port.port;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Ignore the call in case there is no connected client in place yet
|
|
149
|
+
*/
|
|
150
|
+
initRemote() {
|
|
151
|
+
let me = this,
|
|
152
|
+
lastClientId = me.lastClient?.id;
|
|
153
|
+
|
|
154
|
+
if (lastClientId && !me.remotes.includes(lastClientId)) {
|
|
155
|
+
me.remotes.push(lastClientId);
|
|
156
|
+
super.initRemote();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* @param {ExtendableMessageEvent} event
|
|
162
|
+
*/
|
|
163
|
+
onActivate(event) {
|
|
164
|
+
console.log('onActivate', event);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* @param {Client} source
|
|
169
|
+
*/
|
|
170
|
+
onConnect(source) {
|
|
171
|
+
console.log('onConnect', source);
|
|
172
|
+
|
|
173
|
+
this.createMessageChannel(source);
|
|
174
|
+
this.initRemote();
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @param {ExtendableMessageEvent} event
|
|
179
|
+
*/
|
|
180
|
+
onFetch(event) {
|
|
181
|
+
let hasMatch = false,
|
|
182
|
+
request = event.request,
|
|
183
|
+
key;
|
|
184
|
+
|
|
185
|
+
for (key of this.cachePaths) {
|
|
186
|
+
if (request.url.includes(key)) {
|
|
187
|
+
hasMatch = true;
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
hasMatch && event.respondWith(
|
|
193
|
+
caches.match(request)
|
|
194
|
+
.then(cachedResponse => cachedResponse || caches.open(this.cacheName)
|
|
195
|
+
.then(cache => fetch(request)
|
|
196
|
+
.then(response => cache.put(request, response.clone())
|
|
197
|
+
.then(() => response)
|
|
198
|
+
)))
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* @param {ExtendableMessageEvent} event
|
|
204
|
+
*/
|
|
205
|
+
onInstall(event) {
|
|
206
|
+
console.log('onInstall', event);
|
|
207
|
+
globalThis.skipWaiting();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* For a client based message we receive an ExtendableMessageEvent,
|
|
212
|
+
* for a MessageChannel based message a MessageEvent
|
|
213
|
+
* @param {ExtendableMessageEvent|MessageEvent} event
|
|
214
|
+
*/
|
|
215
|
+
onMessage(event) {
|
|
216
|
+
let me = this,
|
|
217
|
+
data = event.data,
|
|
218
|
+
action = data.action,
|
|
219
|
+
replyId = data.replyId,
|
|
220
|
+
promise;
|
|
221
|
+
|
|
222
|
+
if (event.source) { // ExtendableMessageEvent
|
|
223
|
+
me.lastClient = event.source;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (!action) {
|
|
227
|
+
throw new Error('Message action is missing: ' + data.id);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (action !== 'reply') {
|
|
231
|
+
me['on' + Neo.capitalize(action)](data, event);
|
|
232
|
+
} else if (promise = action === 'reply' && me.promises[replyId]) {
|
|
233
|
+
promise[data.reject ? 'reject' : 'resolve'](data.data);
|
|
234
|
+
delete me.promises[replyId];
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* @param {Object} msg
|
|
240
|
+
* @param {ExtendableMessageEvent} event
|
|
241
|
+
*/
|
|
242
|
+
onPing(msg, event) {
|
|
243
|
+
this.resolve(msg, {originMsg: msg});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* @param {Object} msg
|
|
248
|
+
* @param {ExtendableMessageEvent} event
|
|
249
|
+
*/
|
|
250
|
+
onRegisterNeoConfig(msg, event) {
|
|
251
|
+
Neo.config = Neo.config || {};
|
|
252
|
+
Object.assign(Neo.config, msg.data);
|
|
253
|
+
|
|
254
|
+
this.onConnect(event.source);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @param {String} dest app, data, main or vdom (excluding the current worker)
|
|
259
|
+
* @param {Object} opts configs for Neo.worker.Message
|
|
260
|
+
* @param {Array} [transfer] An optional array of Transferable objects to transfer ownership of.
|
|
261
|
+
* If the ownership of an object is transferred, it becomes unusable (neutered) in the context it was sent from
|
|
262
|
+
* and becomes available only to the worker it was sent to.
|
|
263
|
+
* @returns {Promise<any>}
|
|
264
|
+
*/
|
|
265
|
+
promiseMessage(dest, opts, transfer) {
|
|
266
|
+
let me = this;
|
|
267
|
+
|
|
268
|
+
return new Promise(function(resolve, reject) {
|
|
269
|
+
let message = me.sendMessage(dest, opts, transfer),
|
|
270
|
+
msgId = message.id;
|
|
271
|
+
|
|
272
|
+
me.promises[msgId] = {reject, resolve};
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {String} dest app, data, main or vdom (excluding the current worker)
|
|
278
|
+
* @param {Object} opts configs for Neo.worker.Message
|
|
279
|
+
* @param {Array} [transfer] An optional array of Transferable objects to transfer ownership of.
|
|
280
|
+
* If the ownership of an object is transferred, it becomes unusable (neutered) in the context it was sent from
|
|
281
|
+
* and becomes available only to the worker it was sent to.
|
|
282
|
+
* @returns {Neo.worker.Message}
|
|
283
|
+
* @protected
|
|
284
|
+
*/
|
|
285
|
+
sendMessage(dest, opts, transfer) {
|
|
286
|
+
opts.destination = dest;
|
|
287
|
+
|
|
288
|
+
let message = new Message(opts),
|
|
289
|
+
port = this.getPort(dest) || this.lastClient;
|
|
290
|
+
|
|
291
|
+
port.postMessage(message, transfer);
|
|
292
|
+
return message;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
Neo.applyClassConfig(ServiceBase);
|
|
297
|
+
|
|
298
|
+
export default ServiceBase;
|
|
@@ -56,7 +56,7 @@ class RemoteMethodAccess extends Base {
|
|
|
56
56
|
methods = remote.methods,
|
|
57
57
|
pkg = Neo.ns(className, true);
|
|
58
58
|
|
|
59
|
-
methods.forEach(
|
|
59
|
+
methods.forEach(method => {
|
|
60
60
|
if (remote.origin !== 'main' && pkg[method]) {
|
|
61
61
|
throw new Error('Duplicate remote method definition ' + className + '.' + method);
|
|
62
62
|
}
|