1
1
angular . module ( 'FredrikSandell.worker-pool' , [ ] )
2
2
. service ( 'WorkerService' , [ '$q' , function ( $q ) {
3
3
var that = { } ;
4
-
5
- //this should be configured from the app in the future
6
- var urlToAngular = 'http://localhost:9876/base/bower_components/angular/angular.js' ;
4
+ var urlToAngular ;
7
5
var serviceToUrlMap = { } ;
8
-
9
- that . setAngularUrl = function ( urlToAngularJs ) {
6
+ /*jshint laxcomma:true */
7
+ /*jshint quotmark: false */
8
+ var workerTemplate = [ ""
9
+ // Angular needs a global window object \
10
+ , "var window = self;"
11
+ // Skeleton properties to get Angular to load and bootstrap. \
12
+ , "self.history = {};"
13
+ , "var document = {"
14
+ , " readyState: 'complete',"
15
+ , " cookie: '',"
16
+ , " querySelector: function () {},"
17
+ , " createElement: function () {"
18
+ , " return {"
19
+ , " pathname: '',"
20
+ , " setAttribute: function () {}"
21
+ , " };"
22
+ , " }"
23
+ , "};"
24
+ // Load Angular: must be on same domain as this script \
25
+ , "importScripts('<URL_TO_ANGULAR>');"
26
+ , "<CUSTOM_DEP_INCLUDES>"
27
+ // Put angular on global scope \
28
+ , "angular = window.angular;"
29
+ , "var workerApp = angular.module('WorkerApp', [<DEP_MODULES>]);"
30
+ , "workerApp.run(['$q'<STRING_DEP_NAMES>, function ($q<DEP_NAMES>) {"
31
+ , " self.addEventListener('message', function(e) {"
32
+ , " var input = e.data;"
33
+ , " var output = $q.defer();"
34
+ , " var promise = output.promise;"
35
+ , " promise.then(function(success) {"
36
+ , " self.postMessage({event:'success', data : success});"
37
+ , " }, function(reason) {"
38
+ , " self.postMessage({event:'failure', data : reason});"
39
+ , " }, function(update) {"
40
+ , " self.postMessage({event:'update', data : update});"
41
+ , " });"
42
+ , " <WORKER_FUNCTION>;"
43
+ , " });"
44
+ , " self.postMessage({event:'initDone'});"
45
+ , "}]);"
46
+ , "angular.bootstrap(null, ['WorkerApp']);" ] . join ( "\n" ) ;
47
+
48
+
49
+ that . setAngularUrl = function ( urlToAngularJs ) {
10
50
urlToAngular = urlToAngularJs ;
51
+ return that ;
11
52
} ;
12
53
13
- function createAngularWorkerTemplate ( ) {
14
- /*jshint laxcomma:true */
15
- /*jshint quotmark: false */
16
- var workerTemplate = [ ""
17
- , "//try {"
18
- // Angular needs a global window object \
19
- , "var window = self;"
20
- // Skeleton properties to get Angular to load and bootstrap. \
21
- , "self.history = {};"
22
- , "var document = {"
23
- , " readyState: 'complete',"
24
- , " cookie: '',"
25
- , " querySelector: function () {},"
26
- , " createElement: function () {"
27
- , " return {"
28
- , " pathname: '',"
29
- , " setAttribute: function () {}"
30
- , " };"
31
- , " }"
32
- , "};"
33
- // Load Angular: must be on same domain as this script \
34
- , "importScripts('<URL_TO_ANGULAR>');"
35
- , "<CUSTOM_DEP_INCLUDES>"
36
- // Put angular on global scope \
37
- , "angular = window.angular;"
38
- , "var workerApp = angular.module('WorkerApp', [<DEP_MODULES>]);"
39
- , "workerApp.run(['$q'<STRING_DEP_NAMES>, function ($q<DEP_NAMES>) {"
40
- , " self.addEventListener('message', function(e) {"
41
- , " var input = e.data;"
42
- , " var output = $q.defer();"
43
- , " var promise = output.promise;"
44
- , " promise.then(function(success) {"
45
- , " self.postMessage({event:'success', data : success});"
46
- , " }, function(reason) {"
47
- , " self.postMessage({event:'failure', data : reason});"
48
- , " }, function(update) {"
49
- , " self.postMessage({event:'update', data : update});"
50
- , " });"
51
- , " <WORKER_FUNCTION>;"
52
- , " });"
53
- , " self.postMessage({event:'initDone'});"
54
- , "}]);"
55
- , "angular.bootstrap(null, ['WorkerApp']);"
56
- , "//} catch(e) {self.postMessage(JSON.stringify(e));}" ] ;
57
- return workerTemplate . join ( "\n" ) ;
58
- }
59
- var workerTemplate = createAngularWorkerTemplate ( ) ;
60
54
that . addDependency = function ( serviceName , moduleName , url ) {
61
55
serviceToUrlMap [ serviceName ] = {
62
56
url : url ,
@@ -65,6 +59,49 @@ angular.module('FredrikSandell.worker-pool', [])
65
59
return that ;
66
60
} ;
67
61
62
+ that . createAngularWorker = function ( depFuncList ) {
63
+ //validate the input
64
+
65
+ if ( ! Array . isArray ( depFuncList ) ||
66
+ depFuncList . length < 3 ||
67
+ typeof depFuncList [ depFuncList . length - 1 ] !== 'function' ) {
68
+ throw 'Input needs to be: [\'input\',\'output\'\/*optional additional dependencies*\/,\n' +
69
+ ' function(workerInput, deferredOutput \/*optional additional dependencies*\/)\n' +
70
+ ' {\/*worker body*\/}' +
71
+ ']' ;
72
+ }
73
+ if ( typeof urlToAngular !== 'string' ) {
74
+ throw 'The url to angular must be defined before worker creation' ;
75
+ }
76
+ var deferred = $q . defer ( ) ;
77
+
78
+ var dependencyMetaData = createDependencyMetaData ( extractDependencyList ( depFuncList ) ) ;
79
+
80
+ var blobURL = ( window . webkitURL ? webkitURL : URL ) . createObjectURL ( new Blob ( [
81
+ populateWorkerTemplate (
82
+ workerFunctionToString (
83
+ depFuncList [ depFuncList . length - 1 ] ,
84
+ dependencyMetaData . workerFuncParamList ) ,
85
+ dependencyMetaData
86
+ ) ] , { type : 'application/javascript' } ) ) ;
87
+
88
+
89
+ var worker = new Worker ( blobURL ) ;
90
+
91
+ //wait for the worker to load resources
92
+ worker . addEventListener ( 'message' , function ( e ) {
93
+ var eventId = e . data . event ;
94
+ console . log ( e . data ) ;
95
+ if ( eventId === 'initDone' ) {
96
+ deferred . resolve ( buildAngularWorker ( worker ) ) ;
97
+ } else {
98
+ deferred . reject ( e ) ;
99
+ }
100
+ } ) ;
101
+
102
+ return deferred . promise ;
103
+ } ;
104
+
68
105
function createIncludeStatements ( listOfServiceNames ) {
69
106
var includeString = '' ;
70
107
angular . forEach ( listOfServiceNames , function ( serviceName ) {
@@ -142,63 +179,13 @@ angular.module('FredrikSandell.worker-pool', [])
142
179
return that ;
143
180
} ;
144
181
145
- var extractDependencyList = function ( depFuncList ) {
182
+ function extractDependencyList ( depFuncList ) {
146
183
return depFuncList . slice ( 0 , depFuncList . length - 1 ) ;
147
- } ;
184
+ }
148
185
149
- var workerFunctionToString = function ( func , paramList ) {
186
+ function workerFunctionToString ( func , paramList ) {
150
187
return '(' + func . toString ( ) + ')(' + paramList + ')' ;
151
- } ;
152
- /**
153
- * example call:
154
- * WorkerService.createAngularWorker(['input', 'output', '$http', function(input, output, $http)
155
- * {body of function}]);
156
- * Parameters "input" and "output" is required. Not defining them will cause a runtime error.
157
- * Declaring services to be injected, as '$http' is above, requires the web worker to be able to resolve them.
158
- * '$http' service is a part of the standard angular package which means it will resolve without additional information
159
- * since angular source is always loaded in the web worker.
160
- * But if a custom service was to be injected the WorkerService would need be be informed on how to resolve the.
161
- * @param depFuncList
162
- */
163
- that . createAngularWorker = function ( depFuncList ) {
164
- //validate the input
165
-
166
- if ( ! Array . isArray ( depFuncList ) ||
167
- depFuncList . length < 3 ||
168
- typeof depFuncList [ depFuncList . length - 1 ] !== 'function' ) {
169
- throw 'Input needs to be: [\'workerInput\',\'deferredOutput\'\/*optional additional dependencies*\/,\n' +
170
- ' function(workerInput, deferredOutput \/*optional additional dependencies*\/)\n' +
171
- ' {\/*worker body*\/}' +
172
- ']' ;
173
- }
174
- var deferred = $q . defer ( ) ;
175
-
176
- var dependencyMetaData = createDependencyMetaData ( extractDependencyList ( depFuncList ) ) ;
177
-
178
- var blobURL = ( window . webkitURL ? webkitURL : URL ) . createObjectURL ( new Blob ( [
179
- populateWorkerTemplate (
180
- workerFunctionToString (
181
- depFuncList [ depFuncList . length - 1 ] ,
182
- dependencyMetaData . workerFuncParamList ) ,
183
- dependencyMetaData
184
- ) ] , { type : 'application/javascript' } ) ) ;
185
-
186
-
187
- var worker = new Worker ( blobURL ) ;
188
-
189
- //wait for the worker to load resources
190
- worker . addEventListener ( 'message' , function ( e ) {
191
- var eventId = e . data . event ;
192
- console . log ( e . data ) ;
193
- if ( eventId === 'initDone' ) {
194
- deferred . resolve ( buildAngularWorker ( worker ) ) ;
195
- } else {
196
- deferred . reject ( e ) ;
197
- }
198
- } ) ;
199
-
200
- return deferred . promise ;
201
- } ;
188
+ }
202
189
203
190
return that ;
204
191
} ] ) ;
0 commit comments