index.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. 'use strict';
  2. exports.isIterable = isIterable;
  3. exports.isArrayLike = isArrayLike;
  4. exports.isCollection = isCollection;
  5. exports.getIterator = getIterator;
  6. exports.getIteratorMethod = getIteratorMethod;
  7. exports.createIterator = createIterator;
  8. exports.forEach = forEach;
  9. exports.isAsyncIterable = isAsyncIterable;
  10. exports.getAsyncIterator = getAsyncIterator;
  11. exports.getAsyncIteratorMethod = getAsyncIteratorMethod;
  12. exports.createAsyncIterator = createAsyncIterator;
  13. exports.forAwaitEach = forAwaitEach;
  14. var SYMBOL = typeof Symbol === 'function' ? Symbol : void 0;
  15. var SYMBOL_ITERATOR = SYMBOL && SYMBOL.iterator;
  16. var $$iterator = exports.$$iterator = SYMBOL_ITERATOR || '@@iterator';
  17. function isIterable(obj) {
  18. return !!getIteratorMethod(obj);
  19. }
  20. function isArrayLike(obj) {
  21. var length = obj != null && obj.length;
  22. return typeof length === 'number' && length >= 0 && length % 1 === 0;
  23. }
  24. function isCollection(obj) {
  25. return Object(obj) === obj && (isArrayLike(obj) || isIterable(obj));
  26. }
  27. function getIterator(iterable) {
  28. var method = getIteratorMethod(iterable);
  29. if (method) {
  30. return method.call(iterable);
  31. }
  32. }
  33. function getIteratorMethod(iterable) {
  34. if (iterable != null) {
  35. var method = SYMBOL_ITERATOR && iterable[SYMBOL_ITERATOR] || iterable['@@iterator'];
  36. if (typeof method === 'function') {
  37. return method;
  38. }
  39. }
  40. }
  41. function createIterator(collection) {
  42. if (collection != null) {
  43. var iterator = getIterator(collection);
  44. if (iterator) {
  45. return iterator;
  46. }
  47. if (isArrayLike(collection)) {
  48. return new ArrayLikeIterator(collection);
  49. }
  50. }
  51. }
  52. function ArrayLikeIterator(obj) {
  53. this._o = obj;
  54. this._i = 0;
  55. }
  56. ArrayLikeIterator.prototype[$$iterator] = function () {
  57. return this;
  58. };
  59. ArrayLikeIterator.prototype.next = function () {
  60. if (this._o === void 0 || this._i >= this._o.length) {
  61. this._o = void 0;
  62. return { value: void 0, done: true };
  63. }
  64. return { value: this._o[this._i++], done: false };
  65. };
  66. function forEach(collection, callback, thisArg) {
  67. if (collection != null) {
  68. if (typeof collection.forEach === 'function') {
  69. return collection.forEach(callback, thisArg);
  70. }
  71. var i = 0;
  72. var iterator = getIterator(collection);
  73. if (iterator) {
  74. var step;
  75. while (!(step = iterator.next()).done) {
  76. callback.call(thisArg, step.value, i++, collection);
  77. if (i > 9999999) {
  78. throw new TypeError('Near-infinite iteration.');
  79. }
  80. }
  81. } else if (isArrayLike(collection)) {
  82. for (; i < collection.length; i++) {
  83. if (collection.hasOwnProperty(i)) {
  84. callback.call(thisArg, collection[i], i, collection);
  85. }
  86. }
  87. }
  88. }
  89. }
  90. var SYMBOL_ASYNC_ITERATOR = SYMBOL && SYMBOL.asyncIterator;
  91. var $$asyncIterator = exports.$$asyncIterator = SYMBOL_ASYNC_ITERATOR || '@@asyncIterator';
  92. function isAsyncIterable(obj) {
  93. return !!getAsyncIteratorMethod(obj);
  94. }
  95. function getAsyncIterator(asyncIterable) {
  96. var method = getAsyncIteratorMethod(asyncIterable);
  97. if (method) {
  98. return method.call(asyncIterable);
  99. }
  100. }
  101. function getAsyncIteratorMethod(asyncIterable) {
  102. if (asyncIterable != null) {
  103. var method = SYMBOL_ASYNC_ITERATOR && asyncIterable[SYMBOL_ASYNC_ITERATOR] || asyncIterable['@@asyncIterator'];
  104. if (typeof method === 'function') {
  105. return method;
  106. }
  107. }
  108. }
  109. function createAsyncIterator(source) {
  110. if (source != null) {
  111. var asyncIterator = getAsyncIterator(source);
  112. if (asyncIterator) {
  113. return asyncIterator;
  114. }
  115. var iterator = createIterator(source);
  116. if (iterator) {
  117. return new AsyncFromSyncIterator(iterator);
  118. }
  119. }
  120. }
  121. function AsyncFromSyncIterator(iterator) {
  122. this._i = iterator;
  123. }
  124. AsyncFromSyncIterator.prototype[$$asyncIterator] = function () {
  125. return this;
  126. };
  127. AsyncFromSyncIterator.prototype.next = function (value) {
  128. return unwrapAsyncFromSync(this._i, 'next', value);
  129. };
  130. AsyncFromSyncIterator.prototype.return = function (value) {
  131. return this._i.return ? unwrapAsyncFromSync(this._i, 'return', value) : Promise.resolve({ value: value, done: true });
  132. };
  133. AsyncFromSyncIterator.prototype.throw = function (value) {
  134. return this._i.throw ? unwrapAsyncFromSync(this._i, 'throw', value) : Promise.reject(value);
  135. };
  136. function unwrapAsyncFromSync(iterator, fn, value) {
  137. var step;
  138. return new Promise(function (resolve) {
  139. step = iterator[fn](value);
  140. resolve(step.value);
  141. }).then(function (value) {
  142. return { value: value, done: step.done };
  143. });
  144. }
  145. function forAwaitEach(source, callback, thisArg) {
  146. var asyncIterator = createAsyncIterator(source);
  147. if (asyncIterator) {
  148. var i = 0;
  149. return new Promise(function (resolve, reject) {
  150. function next() {
  151. asyncIterator.next().then(function (step) {
  152. if (!step.done) {
  153. Promise.resolve(callback.call(thisArg, step.value, i++, source)).then(next).catch(reject);
  154. } else {
  155. resolve();
  156. }
  157. return null;
  158. }).catch(reject);
  159. return null;
  160. }
  161. next();
  162. });
  163. }
  164. }