Skip to content

Commit

Permalink
Require Node.js 12.20 and move to ESM
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Aug 10, 2021
1 parent 1448628 commit dc0b649
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 72 deletions.
3 changes: 1 addition & 2 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* text=auto
*.js text eol=lf
* text=auto eol=lf
8 changes: 2 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,10 @@ jobs:
fail-fast: false
matrix:
node-version:
- 14
- 12
- 10
- 8
- 6
- 16
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
22 changes: 10 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
'use strict';

module.exports = iterable => {
export default function magicIterable(iterable) {
return new Proxy(iterable, {
get(target, property) {
return function (...args) {
const ret = [];
return function (...arguments_) {
const returnValue = [];

let i = 0;
let index = 0;
for (const item of target) {
i++;
index++;

if (typeof item[property] === 'undefined') {
throw new TypeError(`Item ${i} of the iterable is missing the ${property}() method`);
throw new TypeError(`Item ${index} of the iterable is missing the ${property}() method`);
}

ret.push(Reflect.apply(item[property], item, args));
returnValue.push(Reflect.apply(item[property], item, arguments_));
}

return ret;
return returnValue;
};
}
},
});
};
}
2 changes: 1 addition & 1 deletion license
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)

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:

Expand Down
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
"description": "Call a method on all items in an iterable by calling it on the iterable itself",
"license": "MIT",
"repository": "sindresorhus/magic-iterable",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=6"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"scripts": {
"test": "xo && ava"
Expand All @@ -32,7 +35,7 @@
"magic"
],
"devDependencies": {
"ava": "*",
"xo": "*"
"ava": "^3.15.0",
"xo": "^0.44.0"
}
}
21 changes: 6 additions & 15 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@
Uses the [`Proxy` API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy).


## Install

```
$ npm install magic-iterable
```


## Usage

```js
const magicIterable = require('magic-iterable');
import magicIterable from 'magic-iterable';

const x = {
i: 0,
index: 0,
increment(value) {
this.i += value;
return this.i;
this.index += value;
return this.index;
}
};

Expand All @@ -34,20 +32,19 @@ Array.isArray(magicArray);
magicArray.increment(2);
//=> [2, 4, 6, 8];

x.i;
x.index;
//=> 8
```

```js
const magicIterable = require('magic-iterable');
import magicIterable from 'magic-iterable';

// Subscribes to click events for all `<a>` elements
magicIterable(document.querySelectorAll('a')).addEventListener('click', () => {
console.log('Click');
});
```


## API

### magicIterable(iterable)
Expand All @@ -60,14 +57,8 @@ Type: [`Iterable`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer

Iterable where all the items has the method you want to call.


## Related

- [on-change](https://github.com/sindresorhus/on-change) - Watch an object or array for changes (Uses `Proxy` too)
- [negative-array](https://github.com/sindresorhus/negative-array) - Negative array index support (Uses `Proxy` too)
- [known](https://github.com/sindresorhus/known) - Allow only access to known object properties (Uses `Proxy` too)


## License

MIT © [Sindre Sorhus](https://sindresorhus.com)
62 changes: 30 additions & 32 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,83 @@
import test from 'ava';
import m from '.';
import magicIterable from './index.js';

test('main', t => {
let i = 0;

const createFixture = () => {
return {
increment(value) {
i += value;
return i;
}
};
};
let index = 0;

const createFixture = () => ({
increment(value) {
index += value;
return index;
},
});

const array = [
createFixture(),
createFixture(),
createFixture(),
createFixture()
createFixture(),
];

const magicArray = m(array);
const magicArray = magicIterable(array);

t.true(Array.isArray(magicArray));
t.deepEqual(magicArray.increment(2), [2, 4, 6, 8]);
t.is(i, 8);
t.is(index, 8);
});

test('`this` works correctly', t => {
const fixture = {
i: 0,
index: 0,
increment(value) {
this.i += value;
return this.i;
}
this.index += value;
return this.index;
},
};

const array = [fixture, fixture, fixture, fixture];

t.deepEqual(m(array).increment(2), [2, 4, 6, 8]);
t.is(fixture.i, 8);
t.deepEqual(magicIterable(array).increment(2), [2, 4, 6, 8]);
t.is(fixture.index, 8);
});

test('does not work on heterogeneous iterable', t => {
const createFixture = () => {
return {
foo() {}
};
};
const createFixture = () => ({
foo() {},
});

const array = [
createFixture(),
createFixture(),
{},
createFixture()
createFixture(),
];

const magicArray = m(array);
const magicArray = magicIterable(array);

t.throws(() => {
magicArray.foo();
}, /Item 3 of the iterable is missing the foo\(\) method/);
}, {
message: /Item 3 of the iterable is missing the foo\(\) method/,
});
});

test('should work on array of non-objects', t => {
t.deepEqual(m(['a', 'b']).includes('b'), [false, true]);
t.deepEqual(magicIterable(['a', 'b']).includes('b'), [false, true]);
});

test('should only apply to the items of the iterable', t => {
const fixture = {
foo() {
return '🦄';
}
},
};

const array = [fixture, fixture];
array.foo = () => '🤡';

t.deepEqual(m(array).foo(), ['🦄', '🦄']);
t.deepEqual(magicIterable(array).foo(), ['🦄', '🦄']);
});

test.failing('should support properties, not just methods', t => {
t.deepEqual(m(['a', 'ab', 'abc']).length.toString(), ['1', '2', '3']);
t.deepEqual(magicIterable(['a', 'ab', 'abc']).length.toString(), ['1', '2', '3']);
});

0 comments on commit dc0b649

Please sign in to comment.