neo.mjs 3.2.5 → 3.2.6
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/neo-config.json +2 -1
- package/package.json +6 -6
- package/src/DefaultConfig.mjs +10 -1
- package/src/Main.mjs +16 -12
- package/src/main/addon/ServiceWorker.mjs +68 -0
- package/src/worker/App.mjs +2 -2
- 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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neo.mjs",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.6",
|
|
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",
|
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
|
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
|
|
46
|
+
navigator.serviceWorker.register(config.basePath + folder + fileName, opts)
|
|
47
|
+
.then(registration => {
|
|
48
|
+
me.registration = registration;
|
|
49
|
+
|
|
50
|
+
navigator.serviceWorker.onmessage = WorkerManager.onWorkerMessage.bind(WorkerManager);
|
|
51
|
+
|
|
52
|
+
WorkerManager.sendMessage('service', {
|
|
53
|
+
action: 'registerNeoConfig',
|
|
54
|
+
data : config,
|
|
55
|
+
port : registration.active
|
|
56
|
+
});
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
Neo.applyClassConfig(ServiceWorker);
|
|
63
|
+
|
|
64
|
+
let instance = Neo.create(ServiceWorker);
|
|
65
|
+
|
|
66
|
+
Neo.applyToGlobalNs(instance);
|
|
67
|
+
|
|
68
|
+
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);
|
|
@@ -265,7 +265,7 @@ class App extends Base {
|
|
|
265
265
|
this.onRegisterApp({ appName });
|
|
266
266
|
|
|
267
267
|
this.sendMessage('main', {
|
|
268
|
-
action:'registerAppName',
|
|
268
|
+
action: 'registerAppName',
|
|
269
269
|
appName
|
|
270
270
|
});
|
|
271
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
|
}
|