├── #
└── chain.js
├── .circleci
└── config.yml
├── .editorconfig
├── .github
└── FUNDING.yml
├── .gitignore
├── CHANGELOG.md
├── CHANGES
├── LICENSE
├── README.md
├── appveyor.yml
├── array.js
├── for-of.js
├── get.js
├── index.js
├── is-iterable.js
├── package.json
├── string.js
├── test
├── #
│ └── chain.js
├── .eslintrc.json
├── array.js
├── for-of.js
├── get.js
├── index.js
├── is-iterable.js
├── string.js
└── valid-iterable.js
└── valid-iterable.js
/#/chain.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var setPrototypeOf = require("es5-ext/object/set-prototype-of")
4 | , d = require("d")
5 | , Iterator = require("../")
6 | , validIterable = require("../valid-iterable")
7 |
8 | , push = Array.prototype.push
9 | , defineProperties = Object.defineProperties
10 | , IteratorChain;
11 |
12 | IteratorChain = function (iterators) {
13 | defineProperties(this, {
14 | __iterators__: d("", iterators),
15 | __current__: d("w", iterators.shift())
16 | });
17 | };
18 | if (setPrototypeOf) setPrototypeOf(IteratorChain, Iterator);
19 |
20 | IteratorChain.prototype = Object.create(Iterator.prototype, {
21 | constructor: d(IteratorChain),
22 | next: d(function () {
23 | var result;
24 | if (!this.__current__) return { done: true, value: undefined };
25 | result = this.__current__.next();
26 | while (result.done) {
27 | this.__current__ = this.__iterators__.shift();
28 | if (!this.__current__) return { done: true, value: undefined };
29 | result = this.__current__.next();
30 | }
31 | return result;
32 | })
33 | });
34 |
35 | module.exports = function () {
36 | var iterators = [this];
37 | push.apply(iterators, arguments);
38 | iterators.forEach(validIterable);
39 | return new IteratorChain(iterators);
40 | };
41 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 |
4 | lint:
5 | docker:
6 | - image: circleci/node:8
7 | steps:
8 | - checkout
9 | - restore_cache:
10 | keys:
11 | - dependencies-v8-{{ checksum "package.json" }}
12 | - dependencies-v8
13 | - run: npm install
14 | - save_cache:
15 | paths:
16 | - node_modules
17 | key: dependencies-v8-{{ checksum "package.json" }}
18 | - run: npm run lint
19 |
20 | node8:
21 | docker:
22 | - image: circleci/node:8
23 | steps:
24 | - checkout
25 | - restore_cache:
26 | keys:
27 | - dependencies-v8-{{ checksum "package.json" }}
28 | - dependencies-v8
29 | - run: npm install
30 | - save_cache:
31 | paths:
32 | - node_modules
33 | key: dependencies-v8-{{ checksum "package.json" }}
34 | - run: npm test
35 |
36 | node6:
37 | docker:
38 | - image: circleci/node:6
39 | steps:
40 | - checkout
41 | - restore_cache:
42 | keys:
43 | - dependencies-v6-{{ checksum "package.json" }}
44 | - dependencies-v6
45 | - run: npm install
46 | - save_cache:
47 | paths:
48 | - node_modules
49 | key: dependencies-v6-{{ checksum "package.json" }}
50 | - run: npm test
51 |
52 | node4:
53 | docker:
54 | - image: circleci/node:4
55 | steps:
56 | - checkout
57 | - restore_cache:
58 | keys:
59 | - dependencies-v4-{{ checksum "package.json" }}
60 | - dependencies-v4
61 | - run: npm install
62 | - save_cache:
63 | paths:
64 | - node_modules
65 | key: dependencies-v4-{{ checksum "package.json" }}
66 | - run: npm test
67 |
68 | workflows:
69 | version: 2
70 | test_and_lint:
71 | jobs:
72 | - lint
73 | - node8
74 | - node6
75 | - node4
76 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = tab
11 |
12 | [{*.json,*.yml,*.md}]
13 | indent_style = space
14 | indent_size = 2
15 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: medikoo
2 | tidelift: "npm/es6-iterator"
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | npm-debug.log
3 | /package-lock.json
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [2.0.3](https://github.com/medikoo/es6-iterator/compare/v2.0.2...v2.0.3) (2017-10-17)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * configurability of toStringTag ([b99f692](https://github.com/medikoo/es6-iterator/commit/b99f692))
12 |
13 |
14 |
15 |
16 | ## [2.0.2](https://github.com/medikoo/es6-iterator/compare/v2.0.1...v2.0.2) (2017-10-17)
17 |
18 |
19 | ### Bug Fixes
20 |
21 | * constructor exposure ([dbc0c51](https://github.com/medikoo/es6-iterator/commit/dbc0c51))
22 | * do not allow non constructor calls ([1f2f800](https://github.com/medikoo/es6-iterator/commit/1f2f800))
23 | * toString and toStringTag symbol definitions. ([2d17786](https://github.com/medikoo/es6-iterator/commit/2d17786)), closes [#6](https://github.com/medikoo/es6-iterator/issues/6)
24 |
25 | ## Changelog for previous versions
26 |
27 | See `CHANGES` file
28 |
--------------------------------------------------------------------------------
/CHANGES:
--------------------------------------------------------------------------------
1 | For recent changelog see CHANGELOG.md
2 |
3 | -----
4 |
5 | v2.0.1 -- 2017.03.15
6 | * Update dependencies
7 |
8 | v2.0.0 -- 2015.10.02
9 | * Use es6-symbol at v3
10 |
11 | v1.0.0 -- 2015.06.23
12 | * Implement support for arguments object
13 | * Drop support for v0.8 node ('^' in package.json dependencies)
14 |
15 | v0.1.3 -- 2015.02.02
16 | * Update dependencies
17 | * Fix spelling of LICENSE
18 |
19 | v0.1.2 -- 2014.11.19
20 | * Optimise internal `_next` to not verify internal's list length at all times
21 | (#2 thanks @RReverser)
22 | * Fix documentation examples
23 | * Configure lint scripts
24 |
25 | v0.1.1 -- 2014.04.29
26 | * Fix es6-symbol dependency version
27 |
28 | v0.1.0 -- 2014.04.29
29 | * Assure strictly npm hosted dependencies
30 | * Remove sparse arrays dedicated handling (as per spec)
31 | * Add: isIterable, validIterable and chain (method)
32 | * Remove toArray, it's addressed by Array.from (polyfil can be found in es5-ext/array/from)
33 | * Add break possiblity to 'forOf' via 'doBreak' function argument
34 | * Provide dedicated iterator for array-likes (ArrayIterator) and for strings (StringIterator)
35 | * Provide @@toStringTag symbol
36 | * When available rely on @@iterator symbol
37 | * Remove 32bit integer maximum list length restriction
38 | * Improve Iterator internals
39 | * Update to use latest version of dependencies
40 |
41 | v0.0.0 -- 2013.10.12
42 | Initial (dev version)
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (C) 2013-2017 Mariusz Nowak (www.medikoo.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # es6-iterator
2 | ## ECMAScript 6 Iterator interface
3 |
4 | ### Installation
5 |
6 | $ npm install es6-iterator
7 |
8 | To port it to Browser or any other (non CJS) environment, use your favorite CJS bundler. No favorite yet? Try: [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake) or [Webpack](http://webpack.github.io/)
9 |
10 | ## API
11 |
12 | ### Constructors
13 |
14 | #### Iterator(list) _(es6-iterator)_
15 |
16 | Abstract Iterator interface. Meant for extensions and not to be used on its own.
17 |
18 | Accepts any _list_ object (technically object with numeric _length_ property).
19 |
20 | _Mind it doesn't iterate strings properly, for that use dedicated [StringIterator](#string-iterator)_
21 |
22 | ```javascript
23 | var Iterator = require('es6-iterator')
24 | var iterator = new Iterator([1, 2, 3]);
25 |
26 | iterator.next(); // { value: 1, done: false }
27 | iterator.next(); // { value: 2, done: false }
28 | iterator.next(); // { value: 3, done: false }
29 | iterator.next(); // { value: undefined, done: true }
30 | ```
31 |
32 |
33 | #### ArrayIterator(arrayLike[, kind]) _(es6-iterator/array)_
34 |
35 | Dedicated for arrays and array-likes. Supports three iteration kinds:
36 | * __value__ _(default)_ - Iterates values
37 | * __key__ - Iterates indexes
38 | * __key+value__ - Iterates keys and indexes, each iteration value is in _[key, value]_ form.
39 |
40 |
41 | ```javascript
42 | var ArrayIterator = require('es6-iterator/array')
43 | var iterator = new ArrayIterator([1, 2, 3], 'key+value');
44 |
45 | iterator.next(); // { value: [0, 1], done: false }
46 | iterator.next(); // { value: [1, 2], done: false }
47 | iterator.next(); // { value: [2, 3], done: false }
48 | iterator.next(); // { value: undefined, done: true }
49 | ```
50 |
51 | May also be used for _arguments_ objects:
52 |
53 | ```javascript
54 | (function () {
55 | var iterator = new ArrayIterator(arguments);
56 |
57 | iterator.next(); // { value: 1, done: false }
58 | iterator.next(); // { value: 2, done: false }
59 | iterator.next(); // { value: 3, done: false }
60 | iterator.next(); // { value: undefined, done: true }
61 | }(1, 2, 3));
62 | ```
63 |
64 | #### StringIterator(str) _(es6-iterator/string)_
65 |
66 | Assures proper iteration over unicode symbols.
67 | See: http://mathiasbynens.be/notes/javascript-unicode
68 |
69 | ```javascript
70 | var StringIterator = require('es6-iterator/string');
71 | var iterator = new StringIterator('f🙈o🙉o🙊');
72 |
73 | iterator.next(); // { value: 'f', done: false }
74 | iterator.next(); // { value: '🙈', done: false }
75 | iterator.next(); // { value: 'o', done: false }
76 | iterator.next(); // { value: '🙉', done: false }
77 | iterator.next(); // { value: 'o', done: false }
78 | iterator.next(); // { value: '🙊', done: false }
79 | iterator.next(); // { value: undefined, done: true }
80 | ```
81 |
82 | ### Function utilities
83 |
84 | #### forOf(iterable, callback[, thisArg]) _(es6-iterator/for-of)_
85 |
86 | Polyfill for ECMAScript 6 [`for...of`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of) statement.
87 |
88 | ```
89 | var forOf = require('es6-iterator/for-of');
90 | var result = [];
91 |
92 | forOf('🙈🙉🙊', function (monkey) { result.push(monkey); });
93 | console.log(result); // ['🙈', '🙉', '🙊'];
94 | ```
95 |
96 | Optionally you can break iteration at any point:
97 |
98 | ```javascript
99 | var result = [];
100 |
101 | forOf([1,2,3,4]', function (val, doBreak) {
102 | result.push(monkey);
103 | if (val >= 3) doBreak();
104 | });
105 | console.log(result); // [1, 2, 3];
106 | ```
107 |
108 | #### get(obj) _(es6-iterator/get)_
109 |
110 | Return iterator for any iterable object.
111 |
112 | ```javascript
113 | var getIterator = require('es6-iterator/get');
114 | var iterator = get([1,2,3]);
115 |
116 | iterator.next(); // { value: 1, done: false }
117 | iterator.next(); // { value: 2, done: false }
118 | iterator.next(); // { value: 3, done: false }
119 | iterator.next(); // { value: undefined, done: true }
120 | ```
121 |
122 | #### isIterable(obj) _(es6-iterator/is-iterable)_
123 |
124 | Whether _obj_ is iterable
125 |
126 | ```javascript
127 | var isIterable = require('es6-iterator/is-iterable');
128 |
129 | isIterable(null); // false
130 | isIterable(true); // false
131 | isIterable('str'); // true
132 | isIterable(['a', 'r', 'r']); // true
133 | isIterable(new ArrayIterator([])); // true
134 | ```
135 |
136 | #### validIterable(obj) _(es6-iterator/valid-iterable)_
137 |
138 | If _obj_ is an iterable it is returned. Otherwise _TypeError_ is thrown.
139 |
140 | ### Method extensions
141 |
142 | #### iterator.chain(iterator1[, …iteratorn]) _(es6-iterator/#/chain)_
143 |
144 | Chain multiple iterators into one.
145 |
146 | ### Tests [](https://travis-ci.org/medikoo/es6-iterator)
147 |
148 | $ npm test
149 |
150 | ## Security contact information
151 |
152 | To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
153 |
154 | ---
155 |
156 |
165 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | # Test against the latest version of this Node.js version
2 | environment:
3 | matrix:
4 | # node.js
5 | - nodejs_version: "0.12"
6 | - nodejs_version: "4"
7 | - nodejs_version: "6"
8 | - nodejs_version: "8"
9 |
10 | # Install scripts. (runs after repo cloning)
11 | install:
12 | # Get the latest stable version of Node.js or io.js
13 | - ps: Install-Product node $env:nodejs_version
14 | # install modules
15 | - npm install
16 |
17 | # Post-install test scripts.
18 | test_script:
19 | # Output useful info for debugging.
20 | - node --version
21 | - npm --version
22 | # run tests
23 | - npm test
24 |
25 | # Don't actually build.
26 | build: off
27 |
--------------------------------------------------------------------------------
/array.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var setPrototypeOf = require("es5-ext/object/set-prototype-of")
4 | , contains = require("es5-ext/string/#/contains")
5 | , d = require("d")
6 | , Symbol = require("es6-symbol")
7 | , Iterator = require("./");
8 |
9 | var defineProperty = Object.defineProperty, ArrayIterator;
10 |
11 | ArrayIterator = module.exports = function (arr, kind) {
12 | if (!(this instanceof ArrayIterator)) throw new TypeError("Constructor requires 'new'");
13 | Iterator.call(this, arr);
14 | if (!kind) kind = "value";
15 | else if (contains.call(kind, "key+value")) kind = "key+value";
16 | else if (contains.call(kind, "key")) kind = "key";
17 | else kind = "value";
18 | defineProperty(this, "__kind__", d("", kind));
19 | };
20 | if (setPrototypeOf) setPrototypeOf(ArrayIterator, Iterator);
21 |
22 | // Internal %ArrayIteratorPrototype% doesn't expose its constructor
23 | delete ArrayIterator.prototype.constructor;
24 |
25 | ArrayIterator.prototype = Object.create(Iterator.prototype, {
26 | _resolve: d(function (i) {
27 | if (this.__kind__ === "value") return this.__list__[i];
28 | if (this.__kind__ === "key+value") return [i, this.__list__[i]];
29 | return i;
30 | })
31 | });
32 | defineProperty(ArrayIterator.prototype, Symbol.toStringTag, d("c", "Array Iterator"));
33 |
--------------------------------------------------------------------------------
/for-of.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isArguments = require("es5-ext/function/is-arguments")
4 | , callable = require("es5-ext/object/valid-callable")
5 | , isString = require("es5-ext/string/is-string")
6 | , get = require("./get");
7 |
8 | var isArray = Array.isArray, call = Function.prototype.call, some = Array.prototype.some;
9 |
10 | module.exports = function (iterable, cb /*, thisArg*/) {
11 | var mode, thisArg = arguments[2], result, doBreak, broken, i, length, char, code;
12 | if (isArray(iterable) || isArguments(iterable)) mode = "array";
13 | else if (isString(iterable)) mode = "string";
14 | else iterable = get(iterable);
15 |
16 | callable(cb);
17 | doBreak = function () {
18 | broken = true;
19 | };
20 | if (mode === "array") {
21 | some.call(iterable, function (value) {
22 | call.call(cb, thisArg, value, doBreak);
23 | return broken;
24 | });
25 | return;
26 | }
27 | if (mode === "string") {
28 | length = iterable.length;
29 | for (i = 0; i < length; ++i) {
30 | char = iterable[i];
31 | if (i + 1 < length) {
32 | code = char.charCodeAt(0);
33 | if (code >= 0xd800 && code <= 0xdbff) char += iterable[++i];
34 | }
35 | call.call(cb, thisArg, char, doBreak);
36 | if (broken) break;
37 | }
38 | return;
39 | }
40 | result = iterable.next();
41 |
42 | while (!result.done) {
43 | call.call(cb, thisArg, result.value, doBreak);
44 | if (broken) return;
45 | result = iterable.next();
46 | }
47 | };
48 |
--------------------------------------------------------------------------------
/get.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isArguments = require("es5-ext/function/is-arguments")
4 | , isString = require("es5-ext/string/is-string")
5 | , ArrayIterator = require("./array")
6 | , StringIterator = require("./string")
7 | , iterable = require("./valid-iterable")
8 | , iteratorSymbol = require("es6-symbol").iterator;
9 |
10 | module.exports = function (obj) {
11 | if (typeof iterable(obj)[iteratorSymbol] === "function") return obj[iteratorSymbol]();
12 | if (isArguments(obj)) return new ArrayIterator(obj);
13 | if (isString(obj)) return new StringIterator(obj);
14 | return new ArrayIterator(obj);
15 | };
16 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var clear = require("es5-ext/array/#/clear")
4 | , assign = require("es5-ext/object/assign")
5 | , callable = require("es5-ext/object/valid-callable")
6 | , value = require("es5-ext/object/valid-value")
7 | , d = require("d")
8 | , autoBind = require("d/auto-bind")
9 | , Symbol = require("es6-symbol");
10 |
11 | var defineProperty = Object.defineProperty, defineProperties = Object.defineProperties, Iterator;
12 |
13 | module.exports = Iterator = function (list, context) {
14 | if (!(this instanceof Iterator)) throw new TypeError("Constructor requires 'new'");
15 | defineProperties(this, {
16 | __list__: d("w", value(list)),
17 | __context__: d("w", context),
18 | __nextIndex__: d("w", 0)
19 | });
20 | if (!context) return;
21 | callable(context.on);
22 | context.on("_add", this._onAdd);
23 | context.on("_delete", this._onDelete);
24 | context.on("_clear", this._onClear);
25 | };
26 |
27 | // Internal %IteratorPrototype% doesn't expose its constructor
28 | delete Iterator.prototype.constructor;
29 |
30 | defineProperties(
31 | Iterator.prototype,
32 | assign(
33 | {
34 | _next: d(function () {
35 | var i;
36 | if (!this.__list__) return undefined;
37 | if (this.__redo__) {
38 | i = this.__redo__.shift();
39 | if (i !== undefined) return i;
40 | }
41 | if (this.__nextIndex__ < this.__list__.length) return this.__nextIndex__++;
42 | this._unBind();
43 | return undefined;
44 | }),
45 | next: d(function () {
46 | return this._createResult(this._next());
47 | }),
48 | _createResult: d(function (i) {
49 | if (i === undefined) return { done: true, value: undefined };
50 | return { done: false, value: this._resolve(i) };
51 | }),
52 | _resolve: d(function (i) {
53 | return this.__list__[i];
54 | }),
55 | _unBind: d(function () {
56 | this.__list__ = null;
57 | delete this.__redo__;
58 | if (!this.__context__) return;
59 | this.__context__.off("_add", this._onAdd);
60 | this.__context__.off("_delete", this._onDelete);
61 | this.__context__.off("_clear", this._onClear);
62 | this.__context__ = null;
63 | }),
64 | toString: d(function () {
65 | return "[object " + (this[Symbol.toStringTag] || "Object") + "]";
66 | })
67 | },
68 | autoBind({
69 | _onAdd: d(function (index) {
70 | if (index >= this.__nextIndex__) return;
71 | ++this.__nextIndex__;
72 | if (!this.__redo__) {
73 | defineProperty(this, "__redo__", d("c", [index]));
74 | return;
75 | }
76 | this.__redo__.forEach(function (redo, i) {
77 | if (redo >= index) this.__redo__[i] = ++redo;
78 | }, this);
79 | this.__redo__.push(index);
80 | }),
81 | _onDelete: d(function (index) {
82 | var i;
83 | if (index >= this.__nextIndex__) return;
84 | --this.__nextIndex__;
85 | if (!this.__redo__) return;
86 | i = this.__redo__.indexOf(index);
87 | if (i !== -1) this.__redo__.splice(i, 1);
88 | this.__redo__.forEach(function (redo, j) {
89 | if (redo > index) this.__redo__[j] = --redo;
90 | }, this);
91 | }),
92 | _onClear: d(function () {
93 | if (this.__redo__) clear.call(this.__redo__);
94 | this.__nextIndex__ = 0;
95 | })
96 | })
97 | )
98 | );
99 |
100 | defineProperty(
101 | Iterator.prototype,
102 | Symbol.iterator,
103 | d(function () {
104 | return this;
105 | })
106 | );
107 |
--------------------------------------------------------------------------------
/is-iterable.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isArguments = require("es5-ext/function/is-arguments")
4 | , isValue = require("es5-ext/object/is-value")
5 | , isString = require("es5-ext/string/is-string");
6 |
7 | var iteratorSymbol = require("es6-symbol").iterator
8 | , isArray = Array.isArray;
9 |
10 | module.exports = function (value) {
11 | if (!isValue(value)) return false;
12 | if (isArray(value)) return true;
13 | if (isString(value)) return true;
14 | if (isArguments(value)) return true;
15 | return typeof value[iteratorSymbol] === "function";
16 | };
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es6-iterator",
3 | "version": "2.0.3",
4 | "description": "Iterator abstraction based on ES6 specification",
5 | "author": "Mariusz Nowak (http://www.medikoo.com/)",
6 | "keywords": [
7 | "iterator",
8 | "array",
9 | "list",
10 | "set",
11 | "map",
12 | "generator"
13 | ],
14 | "repository": {
15 | "type": "git",
16 | "url": "git://github.com/medikoo/es6-iterator.git"
17 | },
18 | "dependencies": {
19 | "d": "^1.0.1",
20 | "es5-ext": "^0.10.50",
21 | "es6-symbol": "^3.1.1"
22 | },
23 | "devDependencies": {
24 | "eslint": "^5.16.0",
25 | "eslint-config-medikoo-es5": "^1.7.3",
26 | "event-emitter": "^0.3.5",
27 | "tad": "^0.2.8"
28 | },
29 | "eslintConfig": {
30 | "extends": "medikoo-es5",
31 | "root": true,
32 | "rules": {
33 | "no-extend-native": "off"
34 | }
35 | },
36 | "scripts": {
37 | "lint": "eslint --ignore-path=.gitignore .",
38 | "test": "node ./node_modules/tad/bin/tad"
39 | },
40 | "license": "MIT"
41 | }
42 |
--------------------------------------------------------------------------------
/string.js:
--------------------------------------------------------------------------------
1 | // Thanks @mathiasbynens
2 | // http://mathiasbynens.be/notes/javascript-unicode#iterating-over-symbols
3 |
4 | "use strict";
5 |
6 | var setPrototypeOf = require("es5-ext/object/set-prototype-of")
7 | , d = require("d")
8 | , Symbol = require("es6-symbol")
9 | , Iterator = require("./");
10 |
11 | var defineProperty = Object.defineProperty, StringIterator;
12 |
13 | StringIterator = module.exports = function (str) {
14 | if (!(this instanceof StringIterator)) throw new TypeError("Constructor requires 'new'");
15 | str = String(str);
16 | Iterator.call(this, str);
17 | defineProperty(this, "__length__", d("", str.length));
18 | };
19 | if (setPrototypeOf) setPrototypeOf(StringIterator, Iterator);
20 |
21 | // Internal %ArrayIteratorPrototype% doesn't expose its constructor
22 | delete StringIterator.prototype.constructor;
23 |
24 | StringIterator.prototype = Object.create(Iterator.prototype, {
25 | _next: d(function () {
26 | if (!this.__list__) return undefined;
27 | if (this.__nextIndex__ < this.__length__) return this.__nextIndex__++;
28 | this._unBind();
29 | return undefined;
30 | }),
31 | _resolve: d(function (i) {
32 | var char = this.__list__[i], code;
33 | if (this.__nextIndex__ === this.__length__) return char;
34 | code = char.charCodeAt(0);
35 | if (code >= 0xd800 && code <= 0xdbff) return char + this.__list__[this.__nextIndex__++];
36 | return char;
37 | })
38 | });
39 | defineProperty(StringIterator.prototype, Symbol.toStringTag, d("c", "String Iterator"));
40 |
--------------------------------------------------------------------------------
/test/#/chain.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var Iterator = require("../../");
4 |
5 | module.exports = function (t, a) {
6 | var i1 = new Iterator(["raz", "dwa", "trzy"])
7 | , i2 = new Iterator(["cztery", "pięć", "sześć"])
8 | , i3 = new Iterator(["siedem", "osiem", "dziewięć"])
9 |
10 | , iterator = t.call(i1, i2, i3);
11 |
12 | a.deep(iterator.next(), { done: false, value: "raz" }, "#1");
13 | a.deep(iterator.next(), { done: false, value: "dwa" }, "#2");
14 | a.deep(iterator.next(), { done: false, value: "trzy" }, "#3");
15 | a.deep(iterator.next(), { done: false, value: "cztery" }, "#4");
16 | a.deep(iterator.next(), { done: false, value: "pięć" }, "#5");
17 | a.deep(iterator.next(), { done: false, value: "sześć" }, "#6");
18 | a.deep(iterator.next(), { done: false, value: "siedem" }, "#7");
19 | a.deep(iterator.next(), { done: false, value: "osiem" }, "#8");
20 | a.deep(iterator.next(), { done: false, value: "dziewięć" }, "#9");
21 | a.deep(iterator.next(), { done: true, value: undefined }, "Done #1");
22 | a.deep(iterator.next(), { done: true, value: undefined }, "Done #2");
23 | };
24 |
--------------------------------------------------------------------------------
/test/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "id-length": "off"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/test/array.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var iteratorSymbol = require("es6-symbol").iterator;
4 |
5 | module.exports = function (T) {
6 | return {
7 | "Values": function (a) {
8 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], it;
9 |
10 | it = new T(x);
11 | a(it[iteratorSymbol](), it, "@@iterator");
12 | a.deep(it.next(), { done: false, value: "raz" }, "#1");
13 | a.deep(it.next(), { done: false, value: "dwa" }, "#2");
14 | x.splice(1, 0, "elo");
15 | a.deep(it.next(), { done: false, value: "dwa" }, "Insert");
16 | a.deep(it.next(), { done: false, value: "trzy" }, "#3");
17 | a.deep(it.next(), { done: false, value: "cztery" }, "#4");
18 | x.pop();
19 | a.deep(it.next(), { done: false, value: "pięć" }, "#5");
20 | a.deep(it.next(), { done: true, value: undefined }, "End");
21 | },
22 | "Keys & Values": function (a) {
23 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], it;
24 |
25 | it = new T(x, "key+value");
26 | a(it[iteratorSymbol](), it, "@@iterator");
27 | a.deep(it.next(), { done: false, value: [0, "raz"] }, "#1");
28 | a.deep(it.next(), { done: false, value: [1, "dwa"] }, "#2");
29 | x.splice(1, 0, "elo");
30 | a.deep(it.next(), { done: false, value: [2, "dwa"] }, "Insert");
31 | a.deep(it.next(), { done: false, value: [3, "trzy"] }, "#3");
32 | a.deep(it.next(), { done: false, value: [4, "cztery"] }, "#4");
33 | x.pop();
34 | a.deep(it.next(), { done: false, value: [5, "pięć"] }, "#5");
35 | a.deep(it.next(), { done: true, value: undefined }, "End");
36 | },
37 | "Keys": function (a) {
38 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], it;
39 |
40 | it = new T(x, "key");
41 | a(it[iteratorSymbol](), it, "@@iterator");
42 | a.deep(it.next(), { done: false, value: 0 }, "#1");
43 | a.deep(it.next(), { done: false, value: 1 }, "#2");
44 | x.splice(1, 0, "elo");
45 | a.deep(it.next(), { done: false, value: 2 }, "Insert");
46 | a.deep(it.next(), { done: false, value: 3 }, "#3");
47 | a.deep(it.next(), { done: false, value: 4 }, "#4");
48 | x.pop();
49 | a.deep(it.next(), { done: false, value: 5 }, "#5");
50 | a.deep(it.next(), { done: true, value: undefined }, "End");
51 | },
52 | "Sparse": function (a) {
53 | var x = new Array(6), it;
54 |
55 | x[2] = "raz";
56 | x[4] = "dwa";
57 | it = new T(x);
58 | a.deep(it.next(), { done: false, value: undefined }, "#1");
59 | a.deep(it.next(), { done: false, value: undefined }, "#2");
60 | a.deep(it.next(), { done: false, value: "raz" }, "#3");
61 | a.deep(it.next(), { done: false, value: undefined }, "#4");
62 | a.deep(it.next(), { done: false, value: "dwa" }, "#5");
63 | a.deep(it.next(), { done: false, value: undefined }, "#6");
64 | a.deep(it.next(), { done: true, value: undefined }, "End");
65 | }
66 | };
67 | };
68 |
--------------------------------------------------------------------------------
/test/for-of.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var ArrayIterator = require("../array")
4 |
5 | , slice = Array.prototype.slice;
6 |
7 | module.exports = function (t, a) {
8 | var i = 0, x = ["raz", "dwa", "trzy"], y = {}, called = 0;
9 | t(x, function () {
10 | a.deep(slice.call(arguments, 0, 1), [x[i]], "Array " + i + "#");
11 | a(this, y, "Array: context: " + i++ + "#");
12 | }, y);
13 | i = 0;
14 | t((function () {
15 | return arguments;
16 | }("raz", "dwa", "trzy")), function () {
17 | a.deep(slice.call(arguments, 0, 1), [x[i]], "Arguments" + i + "#");
18 | a(this, y, "Arguments: context: " + i++ + "#");
19 | }, y);
20 | i = 0;
21 | t(x = "foo", function () {
22 | a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#");
23 | a(this, y, "Regular String: context: " + i++ + "#");
24 | }, y);
25 | i = 0;
26 | x = ["r", "💩", "z"];
27 | t("r💩z", function () {
28 | a.deep(slice.call(arguments, 0, 1), [x[i]], "String " + i + "#");
29 | a(this, y, "Unicode String: context: " + i++ + "#");
30 | }, y);
31 | i = 0;
32 | t(new ArrayIterator(x), function () {
33 | a.deep(slice.call(arguments, 0, 1), [x[i]], "Iterator " + i + "#");
34 | a(this, y, "Iterator: context: " + i++ + "#");
35 | }, y);
36 |
37 | t(x = ["raz", "dwa", "trzy"], function (value, doBreak) {
38 | ++called;
39 | return doBreak();
40 | });
41 | a(called, 1, "Break");
42 | };
43 |
--------------------------------------------------------------------------------
/test/get.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var iteratorSymbol = require("es6-symbol").iterator
4 | , Iterator = require("../");
5 |
6 | module.exports = function (t, a) {
7 | var iterator;
8 | a.throws(function () {
9 | t();
10 | }, TypeError, "Null");
11 | a.throws(function () {
12 | t({});
13 | }, TypeError, "Plain object");
14 | a.throws(function () {
15 | t({ length: 0 });
16 | }, TypeError, "Array-like");
17 | iterator = {};
18 | iterator[iteratorSymbol] = function () {
19 | return new Iterator([]);
20 | };
21 | a(t(iterator) instanceof Iterator, true, "Iterator");
22 | a(String(t([])), "[object Array Iterator]", " Array");
23 | a(String(t(function () {
24 | return arguments;
25 | }())), "[object Array Iterator]", " Arguments");
26 | a(String(t("foo")), "[object String Iterator]", "String");
27 | };
28 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var ee = require("event-emitter")
4 | , iteratorSymbol = require("es6-symbol").iterator;
5 |
6 | module.exports = function (T) {
7 | return {
8 | "": function (a) {
9 | var x = ["raz", "dwa", "trzy", "cztery", "pięć"], it, y, z;
10 |
11 | it = new T(x);
12 | a(it[iteratorSymbol](), it, "@@iterator");
13 | y = it.next();
14 | a.deep(y, { done: false, value: "raz" }, "#1");
15 | z = it.next();
16 | a.not(y, z, "Recreate result");
17 | a.deep(z, { done: false, value: "dwa" }, "#2");
18 | a.deep(it.next(), { done: false, value: "trzy" }, "#3");
19 | a.deep(it.next(), { done: false, value: "cztery" }, "#4");
20 | a.deep(it.next(), { done: false, value: "pięć" }, "#5");
21 | a.deep(y = it.next(), { done: true, value: undefined }, "End");
22 | a.not(y, it.next(), "Recreate result on dead");
23 | },
24 | "Emited": function (a) {
25 | var x = ["raz", "dwa", "trzy", "cztery", "pięć"], y, it;
26 |
27 | y = ee();
28 | it = new T(x, y);
29 | a.deep(it.next(), { done: false, value: "raz" }, "#1");
30 | a.deep(it.next(), { done: false, value: "dwa" }, "#2");
31 | y.emit("_add", x.push("sześć") - 1);
32 | a.deep(it.next(), { done: false, value: "trzy" }, "#3");
33 | x.splice(1, 0, "półtora");
34 | y.emit("_add", 1);
35 | a.deep(it.next(), { done: false, value: "półtora" }, "Insert");
36 | x.splice(5, 1);
37 | y.emit("_delete", 5);
38 | a.deep(it.next(), { done: false, value: "cztery" }, "#4");
39 | a.deep(it.next(), { done: false, value: "sześć" }, "#5");
40 | a.deep(it.next(), { done: true, value: undefined }, "End");
41 | },
42 | "Emited #2": function (a) {
43 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], y, it;
44 |
45 | y = ee();
46 | it = new T(x, y);
47 | a.deep(it.next(), { done: false, value: "raz" }, "#1");
48 | a.deep(it.next(), { done: false, value: "dwa" }, "#2");
49 | x.splice(1, 0, "półtora");
50 | y.emit("_add", 1);
51 | x.splice(1, 0, "1.25");
52 | y.emit("_add", 1);
53 | x.splice(0, 1);
54 | y.emit("_delete", 0);
55 | a.deep(it.next(), { done: false, value: "półtora" }, "Insert");
56 | a.deep(it.next(), { done: false, value: "1.25" }, "Insert #2");
57 | a.deep(it.next(), { done: false, value: "trzy" }, "#3");
58 | a.deep(it.next(), { done: false, value: "cztery" }, "#4");
59 | x.splice(5, 1);
60 | y.emit("_delete", 5);
61 | a.deep(it.next(), { done: false, value: "sześć" }, "#5");
62 | a.deep(it.next(), { done: true, value: undefined }, "End");
63 | },
64 | "Emited: Clear #1": function (a) {
65 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], y, it;
66 |
67 | y = ee();
68 | it = new T(x, y);
69 | a.deep(it.next(), { done: false, value: "raz" }, "#1");
70 | a.deep(it.next(), { done: false, value: "dwa" }, "#2");
71 | x.length = 0;
72 | y.emit("_clear");
73 | a.deep(it.next(), { done: true, value: undefined }, "End");
74 | },
75 | "Emited: Clear #2": function (a) {
76 | var x = ["raz", "dwa", "trzy", "cztery", "pięć", "sześć"], y, it;
77 |
78 | y = ee();
79 | it = new T(x, y);
80 | a.deep(it.next(), { done: false, value: "raz" }, "#1");
81 | a.deep(it.next(), { done: false, value: "dwa" }, "#2");
82 | x.length = 0;
83 | y.emit("_clear");
84 | x.push("foo");
85 | x.push("bar");
86 | a.deep(it.next(), { done: false, value: "foo" }, "#3");
87 | a.deep(it.next(), { done: false, value: "bar" }, "#4");
88 | x.splice(1, 0, "półtora");
89 | y.emit("_add", 1);
90 | x.splice(1, 0, "1.25");
91 | y.emit("_add", 1);
92 | x.splice(0, 1);
93 | y.emit("_delete", 0);
94 | a.deep(it.next(), { done: false, value: "półtora" }, "Insert");
95 | a.deep(it.next(), { done: false, value: "1.25" }, "Insert #2");
96 | a.deep(it.next(), { done: true, value: undefined }, "End");
97 | }
98 | };
99 | };
100 |
--------------------------------------------------------------------------------
/test/is-iterable.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var iteratorSymbol = require("es6-symbol").iterator
4 | , Iterator = require("../");
5 |
6 | module.exports = function (t, a) {
7 | var iterator;
8 | a(t(), false, "Undefined");
9 | a(t(123), false, "Number");
10 | a(t({}), false, "Plain object");
11 | a(t({ length: 0 }), false, "Array-like");
12 | iterator = {};
13 | iterator[iteratorSymbol] = function () {
14 | return new Iterator([]);
15 | };
16 | a(t(iterator), true, "Iterator");
17 | a(t([]), true, "Array");
18 | a(t("foo"), true, "String");
19 | a(t(""), true, "Empty string");
20 | a(t(function () {
21 | return arguments;
22 | }()), true, "Arguments");
23 | };
24 |
--------------------------------------------------------------------------------
/test/string.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var iteratorSymbol = require("es6-symbol").iterator;
4 |
5 | module.exports = function (T, a) {
6 | var it = new T("foobar");
7 |
8 | a(it[iteratorSymbol](), it, "@@iterator");
9 | a.deep(it.next(), { done: false, value: "f" }, "#1");
10 | a.deep(it.next(), { done: false, value: "o" }, "#2");
11 | a.deep(it.next(), { done: false, value: "o" }, "#3");
12 | a.deep(it.next(), { done: false, value: "b" }, "#4");
13 | a.deep(it.next(), { done: false, value: "a" }, "#5");
14 | a.deep(it.next(), { done: false, value: "r" }, "#6");
15 | a.deep(it.next(), { done: true, value: undefined }, "End");
16 |
17 | a.h1("Outside of BMP");
18 | it = new T("r💩z");
19 | a.deep(it.next(), { done: false, value: "r" }, "#1");
20 | a.deep(it.next(), { done: false, value: "💩" }, "#2");
21 | a.deep(it.next(), { done: false, value: "z" }, "#3");
22 | a.deep(it.next(), { done: true, value: undefined }, "End");
23 | };
24 |
--------------------------------------------------------------------------------
/test/valid-iterable.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var iteratorSymbol = require("es6-symbol").iterator
4 | , Iterator = require("../");
5 |
6 | module.exports = function (t, a) {
7 | var obj;
8 | a.throws(function () {
9 | t();
10 | }, TypeError, "Undefined");
11 | a.throws(function () {
12 | t({});
13 | }, TypeError, "Plain object");
14 | a.throws(function () {
15 | t({ length: 0 });
16 | }, TypeError, "Array-like");
17 | obj = {};
18 | obj[iteratorSymbol] = function () {
19 | return new Iterator([]);
20 | };
21 | a(t(obj), obj, "Iterator");
22 | obj = [];
23 | a(t(obj), obj, "Array");
24 | obj = (function () {
25 | return arguments;
26 | }());
27 | a(t(obj), obj, "Arguments");
28 | };
29 |
--------------------------------------------------------------------------------
/valid-iterable.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var isIterable = require("./is-iterable");
4 |
5 | module.exports = function (value) {
6 | if (!isIterable(value)) throw new TypeError(value + " is not iterable");
7 | return value;
8 | };
9 |
--------------------------------------------------------------------------------