Comparing version 0.1.0-alpha to 0.1.0
@@ -1,4 +0,4 @@ | ||
/*! pollock v0.1.0alpha | (C) 2017 Alasdair Mercer, !ninja | MIT License */ | ||
/*! pollock v0.1.0 | (C) 2017 Alasdair Mercer, !ninja | MIT License */ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.pollock=t()}(this,function(){"use strict";function e(e,t){t<0&&(t=e.length+t);var n=e[t=Math.max(t,0)];return"function"==typeof n?n:null}return function(t,n,o){function i(){var i,r=o.typeName||t.name||"<anonymous>",f=o.static?".":"#",u=new Error(r+f+n+" abstract method is not implemented");if(null!=o.callback&&(i=e(arguments,o.callback)))return i(u);if(o.promise&&"undefined"!=typeof Promise)return Promise.reject(u);throw u}o||(o={}),o.static?t[n]=i:t.prototype[n]=i}}); | ||
//# sourceMappingURL=pollock.min.js.map |
{ | ||
"name": "pollock", | ||
"version": "0.1.0alpha", | ||
"description": "TODO", | ||
"version": "0.1.0", | ||
"description": "Simple lightweight library for adding abstract methods to types", | ||
"homepage": "https://github.com/NotNinja/pollock", | ||
@@ -16,3 +16,4 @@ "bugs": { | ||
"keywords": [ | ||
"abstract" | ||
"abstract", | ||
"method" | ||
], | ||
@@ -19,0 +20,0 @@ "repository": { |
224
README.md
@@ -1,14 +0,5 @@ | ||
888 888 888 | ||
888 888 888 | ||
888 888 888 | ||
88888b. .d88b. 888 888 .d88b. .d8888b 888 888 | ||
888 "88b d88""88b 888 888 d88""88b d88P" 888 .88P | ||
888 888 888 888 888 888 888 888 888 888888K | ||
888 d88P Y88..88P 888 888 Y88..88P Y88b. 888 "88b | ||
88888P" "Y88P" 888 888 "Y88P" "Y8888P 888 888 | ||
888 | ||
888 | ||
888 | ||
[![Pollock](https://cdn.rawgit.com/NotNinja/pollock/master/images/pollock.png)](https://github.com/NotNinja/pollock) | ||
[pollock](https://github.com/NotNinja/pollock) TODO | ||
A simple lightweight JavaScript library for adding abstract methods to types which, when called, report a useful error | ||
indicating that they have not been implemented/overridden on the child type. | ||
@@ -39,9 +30,212 @@ [![Build Status](https://img.shields.io/travis/NotNinja/pollock/develop.svg?style=flat-square)](https://travis-ci.org/NotNinja/pollock) | ||
* [Development Version](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.js) (TODO - [Source Map](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.js.map)) | ||
* [Production Version](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.min.js) (TODO - [Source Map](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.min.js.map)) | ||
* [Development Version](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.js) (4.6kb - [Source Map](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.js.map)) | ||
* [Production Version](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.min.js) (722b - [Source Map](https://cdn.rawgit.com/NotNinja/pollock/master/dist/pollock.min.js.map)) | ||
## API | ||
TODO: Document | ||
The API couldn't be simpler and consists of a single function, `pollock`: | ||
``` javascript | ||
pollock(type, methodName[, options]) | ||
``` | ||
The most common use case is to add an abstract instance method to a type (i.e. it's prototype) which, when called, | ||
throws an error: | ||
``` javascript | ||
class GraphicObject { | ||
constructor(x, y) { | ||
this.x = x; | ||
this.y = y; | ||
} | ||
moveTo(newX, newY) { | ||
// ... | ||
} | ||
} | ||
pollock(GraphicObject, 'draw'); | ||
pollock(GraphicObject, 'resize'); | ||
class Circle extends GraphicObject { | ||
draw() { | ||
// ... | ||
} | ||
resize() { | ||
// ... | ||
} | ||
} | ||
class Rectangle extends GraphicObject { | ||
draw() { | ||
// ... | ||
} | ||
} | ||
``` | ||
By declaring the abstract methods `draw` and `resize`, it will make it much easier/quicker to discover cases where | ||
children of that type have not implemented those methods, but it's important to note it's only reported if/when the | ||
method is called. | ||
``` javascript | ||
const circle = new Circle(0, 0); | ||
circle.draw(); | ||
circle.resize(); | ||
const rect = new Rectangle(50, 50); | ||
rect.draw(); | ||
rect.resize(); | ||
//=> Error(GraphicObject#resize abstract method is not implemented) | ||
``` | ||
The examples in this document are all using ECMAScript 2015 classes, which your code may not be. Don't worry though, | ||
pollock works with ECMAScript Version 5 as well. ECMAScript 2015 classes were used mainly because they better | ||
demonstrate the inheritance without the noise of different type extension mechanisms. | ||
### Static Methods | ||
While pollock creates instance methods by default, enabling the `static` option will result in the abstract method being | ||
assigned directly to the type instead, effectively making it static. | ||
``` javascript | ||
class GraphicObject { | ||
// ... | ||
} | ||
pollock(GraphicObject, 'getEdges', { static: true }); | ||
class Circle extends GraphicObject { | ||
static getEdges() { | ||
return 1; | ||
} | ||
// ... | ||
} | ||
class Rectangle extends GraphicObject { | ||
// ... | ||
} | ||
``` | ||
This behaves exactly as you'd expect it to and the only difference is in the error message; the character separating the | ||
type and method names is different. This is to help differentiate such cases while debugging as, in theory, a single | ||
type could have two abstract methods with the same name; one instance and one static. | ||
``` javascript | ||
Circle.getEdges(); | ||
//=> 1 | ||
Rectangle.getEdges(); | ||
//=> Error(GraphicObject.getEdges abstract method is not implemented) | ||
``` | ||
### Asynchronous Methods | ||
In most cases, throwing an error as soon as the abstract method is called is best, regardless of whether the method is | ||
intended to be synchronous or asynchronous in nature. However, pollock is flexible and allows you to easily support two | ||
of the most common asynchronous patterns should you wish: callbacks and promises. | ||
#### Callback | ||
In order to have the abstract method invoke a callback function with the error instead of it being thrown, you just need | ||
to specify the index of the callback argument via the `callback` option. | ||
``` javascript | ||
class UserService { | ||
getUserCount(callback) { | ||
this.getUsers((error, users) => { | ||
if (error) { | ||
callback(error); | ||
} else { | ||
callback(null, users.length); | ||
} | ||
}); | ||
} | ||
} | ||
pollock(UserService, 'getUser', { callback: 1 }); | ||
pollock(UserService, 'getUsers', { callback: 0 }); | ||
class UserServiceImpl extends UserService { | ||
getUsers(callback) { | ||
// ... | ||
} | ||
} | ||
``` | ||
Now the error will be passed to the specified callback function argument when invoked. | ||
``` javascript | ||
const userService = new UserServiceImpl(); | ||
userService.getUser(123, (error) => { | ||
//=> Error(UserService#getUser abstract method is not implemented) | ||
}); | ||
``` | ||
If the value of the `callback` option is negative (i.e. less than zero), then it will be applied to the end of argument | ||
list passed to the abstract method. For example; to always treat the last argument as the callback function argument, | ||
pass `-1`. | ||
If the specified index is invalid or does not match an argument that is a function, then the abstract method will fall | ||
back on throwing the error instead. | ||
#### Promise | ||
For the abstract method to return a ECMAScript 2015 `Promise` that has been rejected with the error instead of it being | ||
thrown, simply enable the `promise` option. | ||
``` javascript | ||
class UserService { | ||
getUserCount() { | ||
return this.getUsers() | ||
.then((users) => users.length); | ||
} | ||
} | ||
pollock(UserService, 'getUser', { promise: true }); | ||
pollock(UserService, 'getUsers', { promise: true }); | ||
class UserServiceImpl extends UserService { | ||
getUser(id) { | ||
// ... | ||
} | ||
} | ||
``` | ||
Done! | ||
``` javascript | ||
const userService = new UserServiceImpl(); | ||
userService.getUsers() | ||
.catch((error) => { | ||
//=> Error(UserService#getUsers abstract method is not implemented) | ||
}); | ||
``` | ||
If the current environment does not support ECMAScript 2015's `Promise`, which is tested by detecting whether it's in | ||
the global scope, then the abstract method will fall back on throwing the error instead. | ||
### Custom Type Name | ||
The type name that is reported in the error message can be controlled using the `typeName` option. The type name | ||
resolution occurs in the following order: | ||
1. `typeName` option, if specified | ||
2. `type.name` property value, if available | ||
3. `"<anonymous>"` otherwise | ||
This can be useful for cases where your code is minified and you don't want errors like "p#lock abstract method is not | ||
implemented" or you're using a library/framework that creates the constructor function for you and results in the | ||
assigned name being lost/distorted. | ||
``` javascript | ||
const GraphicObject = Nevis.extend({ | ||
// ... | ||
}); | ||
pollock(GraphicObject, 'draw', { typeName: 'GraphicObject' }); | ||
pollock(GraphicObject, 'resize', { typeName: 'GraphicObject' }); | ||
``` | ||
## Bugs | ||
@@ -48,0 +242,0 @@ |
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
33331
258
0