asyncjs-rails 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 739f1504ae50b9dae2ef52b3d7ac9d3be18500fc
4
+ data.tar.gz: 6d1381e64ec564b3c533308959f7c7999c4301fd
5
+ SHA512:
6
+ metadata.gz: fc399ec3a50d2a1c5290388ef7fbbdce574e485b6560d4a4c1d24306ee471f5ca6b39a1673212c44858edf57822c431da46b056a6e7e37c83406ca8fd896941d
7
+ data.tar.gz: 0162d8d185e4066418409fb3b7dc99cb00ca746790591580df6af835f972f2b4e9aaa12fefe4b3bfb692b75697ccf76818c9b531aeea8b1924074b9668d3ff0c
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ group :test do
5
+ gem 'mocha'
6
+ gem 'rake'
7
+ gem 'coveralls'
8
+ gem 'rspec'
9
+ end
@@ -0,0 +1,132 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ asyncjs-rails (0.0.2)
5
+ actionpack (>= 3.1)
6
+ execjs
7
+ rails (>= 3.1)
8
+ railties (>= 3.1)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ actionmailer (3.2.13)
14
+ actionpack (= 3.2.13)
15
+ mail (~> 2.5.3)
16
+ actionpack (3.2.13)
17
+ activemodel (= 3.2.13)
18
+ activesupport (= 3.2.13)
19
+ builder (~> 3.0.0)
20
+ erubis (~> 2.7.0)
21
+ journey (~> 1.0.4)
22
+ rack (~> 1.4.5)
23
+ rack-cache (~> 1.2)
24
+ rack-test (~> 0.6.1)
25
+ sprockets (~> 2.2.1)
26
+ activemodel (3.2.13)
27
+ activesupport (= 3.2.13)
28
+ builder (~> 3.0.0)
29
+ activerecord (3.2.13)
30
+ activemodel (= 3.2.13)
31
+ activesupport (= 3.2.13)
32
+ arel (~> 3.0.2)
33
+ tzinfo (~> 0.3.29)
34
+ activeresource (3.2.13)
35
+ activemodel (= 3.2.13)
36
+ activesupport (= 3.2.13)
37
+ activesupport (3.2.13)
38
+ i18n (= 0.6.1)
39
+ multi_json (~> 1.0)
40
+ arel (3.0.2)
41
+ builder (3.0.4)
42
+ colorize (0.5.8)
43
+ coveralls (0.6.7)
44
+ colorize
45
+ multi_json (~> 1.3)
46
+ rest-client
47
+ simplecov (>= 0.7)
48
+ thor
49
+ diff-lcs (1.2.4)
50
+ erubis (2.7.0)
51
+ execjs (1.4.0)
52
+ multi_json (~> 1.0)
53
+ hike (1.2.2)
54
+ i18n (0.6.1)
55
+ journey (1.0.4)
56
+ json (1.7.7)
57
+ libv8 (3.11.8.17)
58
+ mail (2.5.3)
59
+ i18n (>= 0.4.0)
60
+ mime-types (~> 1.16)
61
+ treetop (~> 1.4.8)
62
+ metaclass (0.0.1)
63
+ mime-types (1.23)
64
+ mocha (0.13.3)
65
+ metaclass (~> 0.0.1)
66
+ multi_json (1.7.2)
67
+ polyglot (0.3.3)
68
+ rack (1.4.5)
69
+ rack-cache (1.2)
70
+ rack (>= 0.4)
71
+ rack-ssl (1.3.3)
72
+ rack
73
+ rack-test (0.6.2)
74
+ rack (>= 1.0)
75
+ rails (3.2.13)
76
+ actionmailer (= 3.2.13)
77
+ actionpack (= 3.2.13)
78
+ activerecord (= 3.2.13)
79
+ activeresource (= 3.2.13)
80
+ activesupport (= 3.2.13)
81
+ bundler (~> 1.0)
82
+ railties (= 3.2.13)
83
+ railties (3.2.13)
84
+ actionpack (= 3.2.13)
85
+ activesupport (= 3.2.13)
86
+ rack-ssl (~> 1.3.2)
87
+ rake (>= 0.8.7)
88
+ rdoc (~> 3.4)
89
+ thor (>= 0.14.6, < 2.0)
90
+ rake (10.0.4)
91
+ rdoc (3.12.2)
92
+ json (~> 1.4)
93
+ ref (1.0.4)
94
+ rest-client (1.6.7)
95
+ mime-types (>= 1.16)
96
+ rspec (2.13.0)
97
+ rspec-core (~> 2.13.0)
98
+ rspec-expectations (~> 2.13.0)
99
+ rspec-mocks (~> 2.13.0)
100
+ rspec-core (2.13.1)
101
+ rspec-expectations (2.13.0)
102
+ diff-lcs (>= 1.1.3, < 2.0)
103
+ rspec-mocks (2.13.1)
104
+ simplecov (0.7.1)
105
+ multi_json (~> 1.0)
106
+ simplecov-html (~> 0.7.1)
107
+ simplecov-html (0.7.1)
108
+ sprockets (2.2.2)
109
+ hike (~> 1.2)
110
+ multi_json (~> 1.0)
111
+ rack (~> 1.0)
112
+ tilt (~> 1.1, != 1.3.0)
113
+ therubyracer (0.11.4)
114
+ libv8 (~> 3.11.8.12)
115
+ ref
116
+ thor (0.18.1)
117
+ tilt (1.4.0)
118
+ treetop (1.4.12)
119
+ polyglot
120
+ polyglot (>= 0.3.1)
121
+ tzinfo (0.3.37)
122
+
123
+ PLATFORMS
124
+ ruby
125
+
126
+ DEPENDENCIES
127
+ asyncjs-rails!
128
+ coveralls
129
+ mocha
130
+ rake
131
+ rspec
132
+ therubyracer
@@ -0,0 +1,43 @@
1
+ # Async JS for the Rails 3/4 Asset Pipeline
2
+
3
+ [Async](https://github.com/caolan/async) is a async javascript procession plugin by [Caolan McMahon](https://github.com/caolan).
4
+
5
+
6
+ async-rails is a library that integrates Async for the Rails >= 3.1 Asset Pipeline
7
+
8
+ ## Plugin versions
9
+ * Async 0.2.5 on MASTER branch
10
+ * Async HEAD on CONTINUOUS branch
11
+
12
+ ## Installing Gem
13
+
14
+ ```ruby
15
+ gem "async-rails"
16
+ ```
17
+
18
+ for the latest HEAD builds(updated once a day) use:
19
+
20
+ ```ruby
21
+ gem "async-rails", github: "nirnanaaa/async-rails", branch: "continuous"
22
+ ```
23
+
24
+ ## Using it
25
+
26
+ Require async in your app/assets/application.js file.
27
+
28
+ //= require async
29
+
30
+ ## Thanks
31
+ Thanks to [Caolan McMahon](https://github.com/caolan) for writing the awesome async plugin.
32
+
33
+
34
+ ## LICENSE
35
+ (the MIT license)
36
+
37
+ Copyright (c) 2013 Florian Kasper
38
+
39
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
42
+
43
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,170 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'date'
4
+ require 'rspec/core/rake_task'
5
+
6
+
7
+ #############################################################################
8
+ #
9
+ # Helper functions
10
+ #
11
+ #############################################################################
12
+
13
+ def name
14
+ @name ||= Dir['*.gemspec'].first.split('.').first
15
+ end
16
+
17
+ def version
18
+ line = File.read("lib/#{name}.rb")[/^\s*VERSION\s*=\s*.*/]
19
+ line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
20
+ end
21
+
22
+ # assumes x.y.z all digit version
23
+ def next_version
24
+ # x.y.z
25
+ v = version.split '.'
26
+ # bump z
27
+ v[-1] = v[-1].to_i + 1
28
+ v.join '.'
29
+ end
30
+
31
+ def bump_version
32
+ old_file = File.read("lib/#{name}.rb")
33
+ old_version_line = old_file[/^\s*VERSION\s*=\s*.*/]
34
+ new_version = next_version
35
+ # replace first match of old vesion with new version
36
+ old_file.sub!(old_version_line, " VERSION = '#{new_version}'")
37
+
38
+ File.write("lib/#{name}.rb", old_file)
39
+
40
+ new_version
41
+ end
42
+
43
+ def date
44
+ Date.today.to_s
45
+ end
46
+
47
+ def rubyforge_project
48
+ name
49
+ end
50
+
51
+ def gemspec_file
52
+ "#{name}.gemspec"
53
+ end
54
+
55
+ def gem_file
56
+ "#{name}-#{version}.gem"
57
+ end
58
+
59
+ def replace_header(head, header_name)
60
+ head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
61
+ end
62
+
63
+ #############################################################################
64
+ #
65
+ # Standard tasks
66
+ #
67
+ #############################################################################
68
+
69
+ task :default => :spec_run
70
+
71
+ desc "Run RSpec"
72
+ RSpec::Core::RakeTask.new do |t|
73
+ t.verbose = false
74
+ end
75
+
76
+ desc "Run specs"
77
+ task :spec_run do
78
+ begin
79
+ sh "rake spec"
80
+ rescue RuntimeError => e
81
+ puts e.message
82
+ exit(1)
83
+ end
84
+ end
85
+
86
+
87
+ desc "Open an irb session preloaded with this library"
88
+ task :console do
89
+ sh "irb -rubygems -r ./lib/#{name}.rb"
90
+ end
91
+
92
+ #############################################################################
93
+ #
94
+ # Custom tasks (add your own tasks here)
95
+ #
96
+ #############################################################################
97
+
98
+ desc "Update version number and gemspec"
99
+ task :bump do
100
+ puts "Updated version to #{bump_version}"
101
+ # Execute does not invoke dependenciegem.
102
+ # Manually invoke gemspec then validate.
103
+ Rake::Task[:gemspec].execute
104
+ Rake::Task[:validate].execute
105
+ end
106
+
107
+ #############################################################################
108
+ #
109
+ # Packaging tasks
110
+ #
111
+ #############################################################################
112
+
113
+ desc 'Create a release build'
114
+ task :release => :build do
115
+ unless `git branch` =~ /^\* master$/
116
+ puts "You must be on the master branch to release!"
117
+ exit!
118
+ end
119
+ sh "git commit --allow-empty -a -m 'Release #{version}'"
120
+ sh "git pull"
121
+ sh "git tag v#{version}"
122
+ sh "git push origin master"
123
+ sh "git push origin v#{version}"
124
+ sh "gem push pkg/#{name}-#{version}.gem"
125
+ end
126
+
127
+ desc 'Build gem'
128
+ task :build => :gemspec do
129
+ sh "mkdir -p pkg"
130
+ sh "gem build #{gemspec_file}"
131
+ sh "mv #{gem_file} pkg"
132
+ end
133
+
134
+ desc 'Update gemspec'
135
+ task :gemspec => :validate do
136
+ # read spec file and split out manifest section
137
+ spec = File.read(gemspec_file)
138
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
139
+ # replace name version and date
140
+ replace_header(head, :name)
141
+ replace_header(head, :version)
142
+ replace_header(head, :date)
143
+ #comment this out if your rubyforge_project has a different name
144
+ replace_header(head, :rubyforge_project)
145
+
146
+ # determine file list from git ls-files
147
+ files = `git ls-files`.
148
+ split("\n").
149
+ sort.
150
+ reject { |file| file =~ /^\./ }.
151
+ reject { |file| file =~ /^(doc|pkg|spec|Home\.md|\.gitattributes)/ }.
152
+ map { |file| " #{file}" }.
153
+ join("\n")
154
+
155
+ # piece file back together and write
156
+ manifest = " s.files = %w[\n#{files}\n ]\n"
157
+ spec = [head, manifest, tail].join(" # = MANIFEST =\n")
158
+ File.open(gemspec_file, 'w') { |io| io.write(spec) }
159
+ puts "Updated #{gemspec_file}"
160
+ end
161
+
162
+ desc 'Validate lib files and version file'
163
+ task :validate do
164
+ libfiles = Dir['lib/*'] - ["lib/#{name}.rb", "lib/#{name}", "lib/generators"]
165
+ unless Dir['VERSION*'].empty?
166
+ puts "A `VERSION` file at root level violates Gem best practicegem."
167
+ exit!
168
+ end
169
+ end
170
+
@@ -0,0 +1,41 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "asyncjs-rails"
3
+ s.rubyforge_project = "asyncjs-rails"
4
+
5
+ s.version = '0.0.2'
6
+
7
+ s.summary = "Async JS toolkit for Rails 3/4 Asset Pipeline"
8
+ s.description= "async-rails project integrates Async JS for Rails 3/4 Asset Pipeline"
9
+ s.author = 'Florian Kasper'
10
+ s.email = 'mosny@zyg.li'
11
+ s.homepage = 'http://asyncrails.zyg.li'
12
+ s.license = 'MIT'
13
+ s.platform = Gem::Platform::RUBY
14
+ s.required_ruby_version = '>=1.9.3'
15
+
16
+ # = MANIFEST =
17
+ s.files = %w[
18
+ Gemfile
19
+ Gemfile.lock
20
+ README.md
21
+ Rakefile
22
+ asyncjs-rails.gemspec
23
+ lib/async/rails/bootstrap.rb
24
+ lib/async/rails/engine.rb
25
+ lib/asyncjs-rails.rb
26
+ vendor/assets/javascripts/async.js
27
+ ]
28
+ # = MANIFEST =
29
+
30
+ s.require_paths = %w[lib]
31
+
32
+ s.add_dependency 'railties', '>= 3.1'
33
+ s.add_dependency 'actionpack', '>= 3.1'
34
+
35
+ s.add_runtime_dependency 'rails', '>= 3.1'
36
+ s.add_runtime_dependency 'execjs'
37
+
38
+ s.add_development_dependency 'therubyracer'
39
+ s.add_development_dependency 'rake'
40
+
41
+ end
@@ -0,0 +1 @@
1
+ require "async/rails/engine"
@@ -0,0 +1,16 @@
1
+ require 'rails'
2
+
3
+ module Async
4
+ module Rails
5
+ class Engine < ::Rails::Engine
6
+ initializer 'async-rails.setup', :after => :append_assets_path, :group => :all do |app|
7
+ sprockets = if ::Rails::VERSION::MAJOR == 4
8
+ Sprockets.respond_to?('register_engine') ? Sprockets : app.assets
9
+ else
10
+ app.assets
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,11 @@
1
+ module Async
2
+ module Rails
3
+ require 'async/rails/engine' if defined?(Rails)
4
+
5
+ # Version
6
+ VERSION = '0.0.2'
7
+
8
+ end
9
+ end
10
+
11
+ require 'async/rails/engine' if defined?(Rails)
@@ -0,0 +1,955 @@
1
+ /*global setImmediate: false, setTimeout: false, console: false */
2
+ (function () {
3
+
4
+ var async = {};
5
+
6
+ // global on the server, window in the browser
7
+ var root, previous_async;
8
+
9
+ root = this;
10
+ if (root != null) {
11
+ previous_async = root.async;
12
+ }
13
+
14
+ async.noConflict = function () {
15
+ root.async = previous_async;
16
+ return async;
17
+ };
18
+
19
+ function only_once(fn) {
20
+ var called = false;
21
+ return function() {
22
+ if (called) throw new Error("Callback was already called.");
23
+ called = true;
24
+ fn.apply(root, arguments);
25
+ }
26
+ }
27
+
28
+ //// cross-browser compatiblity functions ////
29
+
30
+ var _each = function (arr, iterator) {
31
+ if (arr.forEach) {
32
+ return arr.forEach(iterator);
33
+ }
34
+ for (var i = 0; i < arr.length; i += 1) {
35
+ iterator(arr[i], i, arr);
36
+ }
37
+ };
38
+
39
+ var _map = function (arr, iterator) {
40
+ if (arr.map) {
41
+ return arr.map(iterator);
42
+ }
43
+ var results = [];
44
+ _each(arr, function (x, i, a) {
45
+ results.push(iterator(x, i, a));
46
+ });
47
+ return results;
48
+ };
49
+
50
+ var _reduce = function (arr, iterator, memo) {
51
+ if (arr.reduce) {
52
+ return arr.reduce(iterator, memo);
53
+ }
54
+ _each(arr, function (x, i, a) {
55
+ memo = iterator(memo, x, i, a);
56
+ });
57
+ return memo;
58
+ };
59
+
60
+ var _keys = function (obj) {
61
+ if (Object.keys) {
62
+ return Object.keys(obj);
63
+ }
64
+ var keys = [];
65
+ for (var k in obj) {
66
+ if (obj.hasOwnProperty(k)) {
67
+ keys.push(k);
68
+ }
69
+ }
70
+ return keys;
71
+ };
72
+
73
+ //// exported async module functions ////
74
+
75
+ //// nextTick implementation with browser-compatible fallback ////
76
+ if (typeof process === 'undefined' || !(process.nextTick)) {
77
+ if (typeof setImmediate === 'function') {
78
+ async.nextTick = function (fn) {
79
+ setImmediate(fn);
80
+ };
81
+ }
82
+ else {
83
+ async.nextTick = function (fn) {
84
+ setTimeout(fn, 0);
85
+ };
86
+ }
87
+ }
88
+ else {
89
+ async.nextTick = process.nextTick;
90
+ }
91
+
92
+ async.each = function (arr, iterator, callback) {
93
+ callback = callback || function () {};
94
+ if (!arr.length) {
95
+ return callback();
96
+ }
97
+ var completed = 0;
98
+ _each(arr, function (x) {
99
+ iterator(x, only_once(function (err) {
100
+ if (err) {
101
+ callback(err);
102
+ callback = function () {};
103
+ }
104
+ else {
105
+ completed += 1;
106
+ if (completed >= arr.length) {
107
+ callback(null);
108
+ }
109
+ }
110
+ }));
111
+ });
112
+ };
113
+ async.forEach = async.each;
114
+
115
+ async.eachSeries = function (arr, iterator, callback) {
116
+ callback = callback || function () {};
117
+ if (!arr.length) {
118
+ return callback();
119
+ }
120
+ var completed = 0;
121
+ var iterate = function () {
122
+ var sync = true;
123
+ iterator(arr[completed], function (err) {
124
+ if (err) {
125
+ callback(err);
126
+ callback = function () {};
127
+ }
128
+ else {
129
+ completed += 1;
130
+ if (completed >= arr.length) {
131
+ callback(null);
132
+ }
133
+ else {
134
+ if (sync) {
135
+ async.nextTick(iterate);
136
+ }
137
+ else {
138
+ iterate();
139
+ }
140
+ }
141
+ }
142
+ });
143
+ sync = false;
144
+ };
145
+ iterate();
146
+ };
147
+ async.forEachSeries = async.eachSeries;
148
+
149
+ async.eachLimit = function (arr, limit, iterator, callback) {
150
+ var fn = _eachLimit(limit);
151
+ fn.apply(null, [arr, iterator, callback]);
152
+ };
153
+ async.forEachLimit = async.eachLimit;
154
+
155
+ var _eachLimit = function (limit) {
156
+
157
+ return function (arr, iterator, callback) {
158
+ callback = callback || function () {};
159
+ if (!arr.length || limit <= 0) {
160
+ return callback();
161
+ }
162
+ var completed = 0;
163
+ var started = 0;
164
+ var running = 0;
165
+
166
+ (function replenish () {
167
+ if (completed >= arr.length) {
168
+ return callback();
169
+ }
170
+
171
+ while (running < limit && started < arr.length) {
172
+ started += 1;
173
+ running += 1;
174
+ iterator(arr[started - 1], function (err) {
175
+ if (err) {
176
+ callback(err);
177
+ callback = function () {};
178
+ }
179
+ else {
180
+ completed += 1;
181
+ running -= 1;
182
+ if (completed >= arr.length) {
183
+ callback();
184
+ }
185
+ else {
186
+ replenish();
187
+ }
188
+ }
189
+ });
190
+ }
191
+ })();
192
+ };
193
+ };
194
+
195
+
196
+ var doParallel = function (fn) {
197
+ return function () {
198
+ var args = Array.prototype.slice.call(arguments);
199
+ return fn.apply(null, [async.each].concat(args));
200
+ };
201
+ };
202
+ var doParallelLimit = function(limit, fn) {
203
+ return function () {
204
+ var args = Array.prototype.slice.call(arguments);
205
+ return fn.apply(null, [_eachLimit(limit)].concat(args));
206
+ };
207
+ };
208
+ var doSeries = function (fn) {
209
+ return function () {
210
+ var args = Array.prototype.slice.call(arguments);
211
+ return fn.apply(null, [async.eachSeries].concat(args));
212
+ };
213
+ };
214
+
215
+
216
+ var _asyncMap = function (eachfn, arr, iterator, callback) {
217
+ var results = [];
218
+ arr = _map(arr, function (x, i) {
219
+ return {index: i, value: x};
220
+ });
221
+ eachfn(arr, function (x, callback) {
222
+ iterator(x.value, function (err, v) {
223
+ results[x.index] = v;
224
+ callback(err);
225
+ });
226
+ }, function (err) {
227
+ callback(err, results);
228
+ });
229
+ };
230
+ async.map = doParallel(_asyncMap);
231
+ async.mapSeries = doSeries(_asyncMap);
232
+ async.mapLimit = function (arr, limit, iterator, callback) {
233
+ return _mapLimit(limit)(arr, iterator, callback);
234
+ };
235
+
236
+ var _mapLimit = function(limit) {
237
+ return doParallelLimit(limit, _asyncMap);
238
+ };
239
+
240
+ // reduce only has a series version, as doing reduce in parallel won't
241
+ // work in many situations.
242
+ async.reduce = function (arr, memo, iterator, callback) {
243
+ async.eachSeries(arr, function (x, callback) {
244
+ iterator(memo, x, function (err, v) {
245
+ memo = v;
246
+ callback(err);
247
+ });
248
+ }, function (err) {
249
+ callback(err, memo);
250
+ });
251
+ };
252
+ // inject alias
253
+ async.inject = async.reduce;
254
+ // foldl alias
255
+ async.foldl = async.reduce;
256
+
257
+ async.reduceRight = function (arr, memo, iterator, callback) {
258
+ var reversed = _map(arr, function (x) {
259
+ return x;
260
+ }).reverse();
261
+ async.reduce(reversed, memo, iterator, callback);
262
+ };
263
+ // foldr alias
264
+ async.foldr = async.reduceRight;
265
+
266
+ var _filter = function (eachfn, arr, iterator, callback) {
267
+ var results = [];
268
+ arr = _map(arr, function (x, i) {
269
+ return {index: i, value: x};
270
+ });
271
+ eachfn(arr, function (x, callback) {
272
+ iterator(x.value, function (v) {
273
+ if (v) {
274
+ results.push(x);
275
+ }
276
+ callback();
277
+ });
278
+ }, function (err) {
279
+ callback(_map(results.sort(function (a, b) {
280
+ return a.index - b.index;
281
+ }), function (x) {
282
+ return x.value;
283
+ }));
284
+ });
285
+ };
286
+ async.filter = doParallel(_filter);
287
+ async.filterSeries = doSeries(_filter);
288
+ // select alias
289
+ async.select = async.filter;
290
+ async.selectSeries = async.filterSeries;
291
+
292
+ var _reject = function (eachfn, arr, iterator, callback) {
293
+ var results = [];
294
+ arr = _map(arr, function (x, i) {
295
+ return {index: i, value: x};
296
+ });
297
+ eachfn(arr, function (x, callback) {
298
+ iterator(x.value, function (v) {
299
+ if (!v) {
300
+ results.push(x);
301
+ }
302
+ callback();
303
+ });
304
+ }, function (err) {
305
+ callback(_map(results.sort(function (a, b) {
306
+ return a.index - b.index;
307
+ }), function (x) {
308
+ return x.value;
309
+ }));
310
+ });
311
+ };
312
+ async.reject = doParallel(_reject);
313
+ async.rejectSeries = doSeries(_reject);
314
+
315
+ var _detect = function (eachfn, arr, iterator, main_callback) {
316
+ eachfn(arr, function (x, callback) {
317
+ iterator(x, function (result) {
318
+ if (result) {
319
+ main_callback(x);
320
+ main_callback = function () {};
321
+ }
322
+ else {
323
+ callback();
324
+ }
325
+ });
326
+ }, function (err) {
327
+ main_callback();
328
+ });
329
+ };
330
+ async.detect = doParallel(_detect);
331
+ async.detectSeries = doSeries(_detect);
332
+
333
+ async.some = function (arr, iterator, main_callback) {
334
+ async.each(arr, function (x, callback) {
335
+ iterator(x, function (v) {
336
+ if (v) {
337
+ main_callback(true);
338
+ main_callback = function () {};
339
+ }
340
+ callback();
341
+ });
342
+ }, function (err) {
343
+ main_callback(false);
344
+ });
345
+ };
346
+ // any alias
347
+ async.any = async.some;
348
+
349
+ async.every = function (arr, iterator, main_callback) {
350
+ async.each(arr, function (x, callback) {
351
+ iterator(x, function (v) {
352
+ if (!v) {
353
+ main_callback(false);
354
+ main_callback = function () {};
355
+ }
356
+ callback();
357
+ });
358
+ }, function (err) {
359
+ main_callback(true);
360
+ });
361
+ };
362
+ // all alias
363
+ async.all = async.every;
364
+
365
+ async.sortBy = function (arr, iterator, callback) {
366
+ async.map(arr, function (x, callback) {
367
+ iterator(x, function (err, criteria) {
368
+ if (err) {
369
+ callback(err);
370
+ }
371
+ else {
372
+ callback(null, {value: x, criteria: criteria});
373
+ }
374
+ });
375
+ }, function (err, results) {
376
+ if (err) {
377
+ return callback(err);
378
+ }
379
+ else {
380
+ var fn = function (left, right) {
381
+ var a = left.criteria, b = right.criteria;
382
+ return a < b ? -1 : a > b ? 1 : 0;
383
+ };
384
+ callback(null, _map(results.sort(fn), function (x) {
385
+ return x.value;
386
+ }));
387
+ }
388
+ });
389
+ };
390
+
391
+ async.auto = function (tasks, callback) {
392
+ callback = callback || function () {};
393
+ var keys = _keys(tasks);
394
+ if (!keys.length) {
395
+ return callback(null);
396
+ }
397
+
398
+ var results = {};
399
+
400
+ var listeners = [];
401
+ var addListener = function (fn) {
402
+ listeners.unshift(fn);
403
+ };
404
+ var removeListener = function (fn) {
405
+ for (var i = 0; i < listeners.length; i += 1) {
406
+ if (listeners[i] === fn) {
407
+ listeners.splice(i, 1);
408
+ return;
409
+ }
410
+ }
411
+ };
412
+ var taskComplete = function () {
413
+ _each(listeners.slice(0), function (fn) {
414
+ fn();
415
+ });
416
+ };
417
+
418
+ addListener(function () {
419
+ if (_keys(results).length === keys.length) {
420
+ callback(null, results);
421
+ callback = function () {};
422
+ }
423
+ });
424
+
425
+ _each(keys, function (k) {
426
+ var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
427
+ var taskCallback = function (err) {
428
+ if (err) {
429
+ callback(err);
430
+ // stop subsequent errors hitting callback multiple times
431
+ callback = function () {};
432
+ }
433
+ else {
434
+ var args = Array.prototype.slice.call(arguments, 1);
435
+ if (args.length <= 1) {
436
+ args = args[0];
437
+ }
438
+ results[k] = args;
439
+ async.nextTick(taskComplete);
440
+ }
441
+ };
442
+ var requires = task.slice(0, Math.abs(task.length - 1)) || [];
443
+ var ready = function () {
444
+ return _reduce(requires, function (a, x) {
445
+ return (a && results.hasOwnProperty(x));
446
+ }, true) && !results.hasOwnProperty(k);
447
+ };
448
+ if (ready()) {
449
+ task[task.length - 1](taskCallback, results);
450
+ }
451
+ else {
452
+ var listener = function () {
453
+ if (ready()) {
454
+ removeListener(listener);
455
+ task[task.length - 1](taskCallback, results);
456
+ }
457
+ };
458
+ addListener(listener);
459
+ }
460
+ });
461
+ };
462
+
463
+ async.waterfall = function (tasks, callback) {
464
+ callback = callback || function () {};
465
+ if (!tasks.length) {
466
+ return callback();
467
+ }
468
+ var wrapIterator = function (iterator) {
469
+ return function (err) {
470
+ if (err) {
471
+ callback.apply(null, arguments);
472
+ callback = function () {};
473
+ }
474
+ else {
475
+ var args = Array.prototype.slice.call(arguments, 1);
476
+ var next = iterator.next();
477
+ if (next) {
478
+ args.push(wrapIterator(next));
479
+ }
480
+ else {
481
+ args.push(callback);
482
+ }
483
+ async.nextTick(function () {
484
+ iterator.apply(null, args);
485
+ });
486
+ }
487
+ };
488
+ };
489
+ wrapIterator(async.iterator(tasks))();
490
+ };
491
+
492
+ var _parallel = function(eachfn, tasks, callback) {
493
+ callback = callback || function () {};
494
+ if (tasks.constructor === Array) {
495
+ eachfn.map(tasks, function (fn, callback) {
496
+ if (fn) {
497
+ fn(function (err) {
498
+ var args = Array.prototype.slice.call(arguments, 1);
499
+ if (args.length <= 1) {
500
+ args = args[0];
501
+ }
502
+ callback.call(null, err, args);
503
+ });
504
+ }
505
+ }, callback);
506
+ }
507
+ else {
508
+ var results = {};
509
+ eachfn.each(_keys(tasks), function (k, callback) {
510
+ tasks[k](function (err) {
511
+ var args = Array.prototype.slice.call(arguments, 1);
512
+ if (args.length <= 1) {
513
+ args = args[0];
514
+ }
515
+ results[k] = args;
516
+ callback(err);
517
+ });
518
+ }, function (err) {
519
+ callback(err, results);
520
+ });
521
+ }
522
+ };
523
+
524
+ async.parallel = function (tasks, callback) {
525
+ _parallel({ map: async.map, each: async.each }, tasks, callback);
526
+ };
527
+
528
+ async.parallelLimit = function(tasks, limit, callback) {
529
+ _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
530
+ };
531
+
532
+ async.series = function (tasks, callback) {
533
+ callback = callback || function () {};
534
+ if (tasks.constructor === Array) {
535
+ async.mapSeries(tasks, function (fn, callback) {
536
+ if (fn) {
537
+ fn(function (err) {
538
+ var args = Array.prototype.slice.call(arguments, 1);
539
+ if (args.length <= 1) {
540
+ args = args[0];
541
+ }
542
+ callback.call(null, err, args);
543
+ });
544
+ }
545
+ }, callback);
546
+ }
547
+ else {
548
+ var results = {};
549
+ async.eachSeries(_keys(tasks), function (k, callback) {
550
+ tasks[k](function (err) {
551
+ var args = Array.prototype.slice.call(arguments, 1);
552
+ if (args.length <= 1) {
553
+ args = args[0];
554
+ }
555
+ results[k] = args;
556
+ callback(err);
557
+ });
558
+ }, function (err) {
559
+ callback(err, results);
560
+ });
561
+ }
562
+ };
563
+
564
+ async.iterator = function (tasks) {
565
+ var makeCallback = function (index) {
566
+ var fn = function () {
567
+ if (tasks.length) {
568
+ tasks[index].apply(null, arguments);
569
+ }
570
+ return fn.next();
571
+ };
572
+ fn.next = function () {
573
+ return (index < tasks.length - 1) ? makeCallback(index + 1): null;
574
+ };
575
+ return fn;
576
+ };
577
+ return makeCallback(0);
578
+ };
579
+
580
+ async.apply = function (fn) {
581
+ var args = Array.prototype.slice.call(arguments, 1);
582
+ return function () {
583
+ return fn.apply(
584
+ null, args.concat(Array.prototype.slice.call(arguments))
585
+ );
586
+ };
587
+ };
588
+
589
+ var _concat = function (eachfn, arr, fn, callback) {
590
+ var r = [];
591
+ eachfn(arr, function (x, cb) {
592
+ fn(x, function (err, y) {
593
+ r = r.concat(y || []);
594
+ cb(err);
595
+ });
596
+ }, function (err) {
597
+ callback(err, r);
598
+ });
599
+ };
600
+ async.concat = doParallel(_concat);
601
+ async.concatSeries = doSeries(_concat);
602
+
603
+ async.whilst = function (test, iterator, callback) {
604
+ if (test()) {
605
+ var sync = true;
606
+ iterator(function (err) {
607
+ if (err) {
608
+ return callback(err);
609
+ }
610
+ if (sync) {
611
+ async.nextTick(function () {
612
+ async.whilst(test, iterator, callback);
613
+ });
614
+ }
615
+ else {
616
+ async.whilst(test, iterator, callback);
617
+ }
618
+ });
619
+ sync = false;
620
+ }
621
+ else {
622
+ callback();
623
+ }
624
+ };
625
+
626
+ async.doWhilst = function (iterator, test, callback) {
627
+ var sync = true;
628
+ iterator(function (err) {
629
+ if (err) {
630
+ return callback(err);
631
+ }
632
+ if (test()) {
633
+ if (sync) {
634
+ async.nextTick(function () {
635
+ async.doWhilst(iterator, test, callback);
636
+ });
637
+ }
638
+ else {
639
+ async.doWhilst(iterator, test, callback);
640
+ }
641
+ }
642
+ else {
643
+ callback();
644
+ }
645
+ });
646
+ sync = false;
647
+ };
648
+
649
+ async.until = function (test, iterator, callback) {
650
+ if (!test()) {
651
+ var sync = true;
652
+ iterator(function (err) {
653
+ if (err) {
654
+ return callback(err);
655
+ }
656
+ if (sync) {
657
+ async.nextTick(function () {
658
+ async.until(test, iterator, callback);
659
+ });
660
+ }
661
+ else {
662
+ async.until(test, iterator, callback);
663
+ }
664
+ });
665
+ sync = false;
666
+ }
667
+ else {
668
+ callback();
669
+ }
670
+ };
671
+
672
+ async.doUntil = function (iterator, test, callback) {
673
+ var sync = true;
674
+ iterator(function (err) {
675
+ if (err) {
676
+ return callback(err);
677
+ }
678
+ if (!test()) {
679
+ if (sync) {
680
+ async.nextTick(function () {
681
+ async.doUntil(iterator, test, callback);
682
+ });
683
+ }
684
+ else {
685
+ async.doUntil(iterator, test, callback);
686
+ }
687
+ }
688
+ else {
689
+ callback();
690
+ }
691
+ });
692
+ sync = false;
693
+ };
694
+
695
+ async.queue = function (worker, concurrency) {
696
+ function _insert(q, data, pos, callback) {
697
+ if(data.constructor !== Array) {
698
+ data = [data];
699
+ }
700
+ _each(data, function(task) {
701
+ var item = {
702
+ data: task,
703
+ callback: typeof callback === 'function' ? callback : null
704
+ };
705
+
706
+ if (pos) {
707
+ q.tasks.unshift(item);
708
+ } else {
709
+ q.tasks.push(item);
710
+ }
711
+
712
+ if (q.saturated && q.tasks.length === concurrency) {
713
+ q.saturated();
714
+ }
715
+ async.nextTick(q.process);
716
+ });
717
+ }
718
+
719
+ var workers = 0;
720
+ var q = {
721
+ tasks: [],
722
+ concurrency: concurrency,
723
+ saturated: null,
724
+ empty: null,
725
+ drain: null,
726
+ push: function (data, callback) {
727
+ _insert(q, data, false, callback);
728
+ },
729
+ unshift: function (data, callback) {
730
+ _insert(q, data, true, callback);
731
+ },
732
+ process: function () {
733
+ if (workers < q.concurrency && q.tasks.length) {
734
+ var task = q.tasks.shift();
735
+ if (q.empty && q.tasks.length === 0) {
736
+ q.empty();
737
+ }
738
+ workers += 1;
739
+ var sync = true;
740
+ var next = function () {
741
+ workers -= 1;
742
+ if (task.callback) {
743
+ task.callback.apply(task, arguments);
744
+ }
745
+ if (q.drain && q.tasks.length + workers === 0) {
746
+ q.drain();
747
+ }
748
+ q.process();
749
+ };
750
+ var cb = only_once(function () {
751
+ var cbArgs = arguments;
752
+
753
+ if (sync) {
754
+ async.nextTick(function () {
755
+ next.apply(null, cbArgs);
756
+ });
757
+ } else {
758
+ next.apply(null, arguments);
759
+ }
760
+ });
761
+ worker(task.data, cb);
762
+ sync = false;
763
+ }
764
+ },
765
+ length: function () {
766
+ return q.tasks.length;
767
+ },
768
+ running: function () {
769
+ return workers;
770
+ }
771
+ };
772
+ return q;
773
+ };
774
+
775
+ async.cargo = function (worker, payload) {
776
+ var working = false,
777
+ tasks = [];
778
+
779
+ var cargo = {
780
+ tasks: tasks,
781
+ payload: payload,
782
+ saturated: null,
783
+ empty: null,
784
+ drain: null,
785
+ push: function (data, callback) {
786
+ if(data.constructor !== Array) {
787
+ data = [data];
788
+ }
789
+ _each(data, function(task) {
790
+ tasks.push({
791
+ data: task,
792
+ callback: typeof callback === 'function' ? callback : null
793
+ });
794
+ if (cargo.saturated && tasks.length === payload) {
795
+ cargo.saturated();
796
+ }
797
+ });
798
+ async.nextTick(cargo.process);
799
+ },
800
+ process: function process() {
801
+ if (working) return;
802
+ if (tasks.length === 0) {
803
+ if(cargo.drain) cargo.drain();
804
+ return;
805
+ }
806
+
807
+ var ts = typeof payload === 'number'
808
+ ? tasks.splice(0, payload)
809
+ : tasks.splice(0);
810
+
811
+ var ds = _map(ts, function (task) {
812
+ return task.data;
813
+ });
814
+
815
+ if(cargo.empty) cargo.empty();
816
+ working = true;
817
+ worker(ds, function () {
818
+ working = false;
819
+
820
+ var args = arguments;
821
+ _each(ts, function (data) {
822
+ if (data.callback) {
823
+ data.callback.apply(null, args);
824
+ }
825
+ });
826
+
827
+ process();
828
+ });
829
+ },
830
+ length: function () {
831
+ return tasks.length;
832
+ },
833
+ running: function () {
834
+ return working;
835
+ }
836
+ };
837
+ return cargo;
838
+ };
839
+
840
+ var _console_fn = function (name) {
841
+ return function (fn) {
842
+ var args = Array.prototype.slice.call(arguments, 1);
843
+ fn.apply(null, args.concat([function (err) {
844
+ var args = Array.prototype.slice.call(arguments, 1);
845
+ if (typeof console !== 'undefined') {
846
+ if (err) {
847
+ if (console.error) {
848
+ console.error(err);
849
+ }
850
+ }
851
+ else if (console[name]) {
852
+ _each(args, function (x) {
853
+ console[name](x);
854
+ });
855
+ }
856
+ }
857
+ }]));
858
+ };
859
+ };
860
+ async.log = _console_fn('log');
861
+ async.dir = _console_fn('dir');
862
+ /*async.info = _console_fn('info');
863
+ async.warn = _console_fn('warn');
864
+ async.error = _console_fn('error');*/
865
+
866
+ async.memoize = function (fn, hasher) {
867
+ var memo = {};
868
+ var queues = {};
869
+ hasher = hasher || function (x) {
870
+ return x;
871
+ };
872
+ var memoized = function () {
873
+ var args = Array.prototype.slice.call(arguments);
874
+ var callback = args.pop();
875
+ var key = hasher.apply(null, args);
876
+ if (key in memo) {
877
+ callback.apply(null, memo[key]);
878
+ }
879
+ else if (key in queues) {
880
+ queues[key].push(callback);
881
+ }
882
+ else {
883
+ queues[key] = [callback];
884
+ fn.apply(null, args.concat([function () {
885
+ memo[key] = arguments;
886
+ var q = queues[key];
887
+ delete queues[key];
888
+ for (var i = 0, l = q.length; i < l; i++) {
889
+ q[i].apply(null, arguments);
890
+ }
891
+ }]));
892
+ }
893
+ };
894
+ memoized.memo = memo;
895
+ memoized.unmemoized = fn;
896
+ return memoized;
897
+ };
898
+
899
+ async.unmemoize = function (fn) {
900
+ return function () {
901
+ return (fn.unmemoized || fn).apply(null, arguments);
902
+ };
903
+ };
904
+
905
+ async.times = function (count, iterator, callback) {
906
+ var counter = [];
907
+ for (var i = 0; i < count; i++) {
908
+ counter.push(i);
909
+ }
910
+ return async.map(counter, iterator, callback);
911
+ };
912
+
913
+ async.timesSeries = function (count, iterator, callback) {
914
+ var counter = [];
915
+ for (var i = 0; i < count; i++) {
916
+ counter.push(i);
917
+ }
918
+ return async.mapSeries(counter, iterator, callback);
919
+ };
920
+
921
+ async.compose = function (/* functions... */) {
922
+ var fns = Array.prototype.reverse.call(arguments);
923
+ return function () {
924
+ var that = this;
925
+ var args = Array.prototype.slice.call(arguments);
926
+ var callback = args.pop();
927
+ async.reduce(fns, args, function (newargs, fn, cb) {
928
+ fn.apply(that, newargs.concat([function () {
929
+ var err = arguments[0];
930
+ var nextargs = Array.prototype.slice.call(arguments, 1);
931
+ cb(err, nextargs);
932
+ }]))
933
+ },
934
+ function (err, results) {
935
+ callback.apply(that, [err].concat(results));
936
+ });
937
+ };
938
+ };
939
+
940
+ // AMD / RequireJS
941
+ if (typeof define !== 'undefined' && define.amd) {
942
+ define([], function () {
943
+ return async;
944
+ });
945
+ }
946
+ // Node.js
947
+ else if (typeof module !== 'undefined' && module.exports) {
948
+ module.exports = async;
949
+ }
950
+ // included directly via <script> tag
951
+ else {
952
+ root.async = async;
953
+ }
954
+
955
+ }());