@@ -15,13 +15,50 @@ FlareTail.app.AbstractWorker = class AbstractWorker {
15
15
constructor ( name ) {
16
16
this . name = name ;
17
17
18
+ self . addEventListener ( 'connect' , event => this . onconnect ( event ) ) ;
19
+
18
20
return ( {
19
21
datasources : { } ,
20
22
collections : { } ,
21
23
models : { } ,
22
24
handlers : { } ,
23
25
} ) ;
24
26
}
27
+
28
+ /**
29
+ * Called whenever a MessagePort connection is opened. Add support for WorkerProxy.
30
+ * @argument {MessageEvent} event - A connect event.
31
+ * @return {undefined }
32
+ */
33
+ onconnect ( event ) {
34
+ let port = event . ports [ 0 ] ;
35
+
36
+ port . addEventListener ( 'message' , event => {
37
+ let { type, id, func_path, args } = event . data ;
38
+
39
+ if ( type === 'WorkerProxyRequest' ) {
40
+ let obj = self ; // WorkerGlobalScope
41
+
42
+ // Extract the target object from func_path like 'BzDeck.collections.bugs.get'
43
+ for ( let name of func_path . split ( '.' ) ) {
44
+ obj = obj [ name ] ;
45
+
46
+ if ( ! obj ) {
47
+ break ; // Object/Function not found
48
+ }
49
+ }
50
+
51
+ // Return the results or error
52
+ if ( typeof obj === 'function' ) {
53
+ obj ( ...args ) . then ( result => port . postMessage ( { type : 'WorkerProxyResponse' , id, result } ) ) ;
54
+ } else {
55
+ port . postMessage ( { type : 'WorkerProxyResponse' , id, error : 'Function Not Found' } ) ;
56
+ }
57
+ }
58
+ } ) ;
59
+
60
+ port . start ( ) ;
61
+ }
25
62
}
26
63
27
64
/**
@@ -107,7 +144,7 @@ FlareTail.app.Model = class Model extends FlareTail.app.Base {
107
144
* @argument {undefined}
108
145
* @return {Proxy } this - Proxified `this` object.
109
146
*/
110
- proxy ( ) {
147
+ get proxy ( ) {
111
148
return new Proxy ( this , {
112
149
get : ( obj , prop ) => prop in this ? this [ prop ] : this . data [ prop ] ,
113
150
set : ( obj , prop , value ) => {
@@ -118,6 +155,17 @@ FlareTail.app.Model = class Model extends FlareTail.app.Base {
118
155
} ) ;
119
156
}
120
157
158
+ /**
159
+ * Get a transferable, clone-safe data object that contains the original data and custom attributes.
160
+ * @argument {undefined}
161
+ * @argument {Object} data
162
+ */
163
+ get copy ( ) {
164
+ let obj = JSON . parse ( JSON . stringify ( this ) ) ; // Remove functions
165
+ delete obj . data ; // Remove data
166
+ return Object . assign ( obj , this . data ) ; // Add data again
167
+ }
168
+
121
169
/**
122
170
* Cache data as a new Proxy, so the object is automatically saved when a property is modifled.
123
171
* @argument {Object} data - Raw data object.
@@ -152,7 +200,7 @@ FlareTail.app.Model = class Model extends FlareTail.app.Base {
152
200
console . info ( 'Data saved:' , this . constructor . name , this . data ) ;
153
201
}
154
202
155
- return Promise . resolve ( this . proxy ( ) ) ;
203
+ return Promise . resolve ( this . proxy ) ;
156
204
} ) ;
157
205
}
158
206
}
@@ -224,12 +272,12 @@ FlareTail.app.Collection = class Collection extends FlareTail.app.Base {
224
272
* Get an item by a specific key.
225
273
* @argument {(Number|String)} key - Key of the item.
226
274
* @argument {Object} [fallback_value] - If an item is not found, create a new model object with this value.
227
- * @return {Promise.<(Proxy|undefined) > } item - Promise to be resolved in a model instance.
275
+ * @return {Promise.<Object > } item - Promise to be resolved in a model instance's transferable copy .
228
276
*/
229
277
get ( key , fallback_value = undefined ) {
230
278
return this . has ( key ) . then ( has => {
231
279
if ( has ) {
232
- return this . map . get ( key ) ;
280
+ return this . map . get ( key ) . copy ;
233
281
}
234
282
235
283
if ( fallback_value ) {
@@ -242,20 +290,22 @@ FlareTail.app.Collection = class Collection extends FlareTail.app.Base {
242
290
243
291
/**
244
292
* Get items by specific keys.
245
- * @argument {(Array|Set).<(String|Number)>} keys - Key list.
246
- * @return {Promise.<Map.<(String|Number), Proxy>> } items - Promise to be resolved in model instances.
293
+ * @argument {(Array|Set|Iterator).<(String|Number)>} keys - Key list.
294
+ * @return {Promise.<Map.<(String|Number), Object>> } items - Promise to be resolved in a Map of model instances'
295
+ * transferable copies.
247
296
*/
248
297
get_some ( keys ) {
249
- return Promise . resolve ( new Map ( [ ...keys ] . map ( key => [ key , this . map . get ( key ) ] ) ) ) ;
298
+ return Promise . resolve ( new Map ( [ ...keys ] . map ( key => [ key , this . map . get ( key ) . copy ] ) ) ) ;
250
299
}
251
300
252
301
/**
253
302
* Get all items locally-stored in IndexedDB.
254
303
* @argument {undefined}
255
- * @return {Promise.<Map.<(String|Number), Proxy>> } items - Promise to be resolved in model instances.
304
+ * @return {Promise.<Map.<(String|Number), Object>> } items - Promise to be resolved in a Map of model instances'
305
+ * transferable copies.
256
306
*/
257
307
get_all ( ) {
258
- return Promise . resolve ( this . map ) ;
308
+ return this . get_some ( this . map . keys ( ) ) ;
259
309
}
260
310
261
311
/**
0 commit comments