@stamp/fp-constructor
Advanced tools
+58
-8
| var compose = require('@stamp/compose'); | ||
| var FpConstructor = require('..'); | ||
| describe('@stamp/fp-constructor', function() { | ||
| it('adds .constructor should be the stamp itself', function() { | ||
| describe('@stamp/fp-constructor Stamp.of', function() { | ||
| it('should add .of static method referring to the stamp', function() { | ||
| var Stamp = compose(FpConstructor); | ||
| expect(Stamp.constructor).toBe(Stamp); | ||
| expect(Stamp.of).toBe(Stamp); | ||
| }); | ||
| it('.constructor presence regardless of composition chain', function() { | ||
| var Stamp = compose({staticProperties: {constructor: 1}}) | ||
| it('should refer to the correct stamp regardless of other stamps in the composition', function() { | ||
| var Stamp = compose({staticProperties: {of: 1}}) | ||
| .compose( | ||
| {staticProperties: {constructor: 2}}, | ||
| {staticProperties: {of: 2}}, | ||
| FpConstructor, | ||
| {staticProperties: {constructor: 3}} | ||
| ).compose({staticProperties: {constructor: 4}}); | ||
| {staticProperties: {of: 3}} | ||
| ).compose({staticProperties: {of: 4}}); | ||
| expect(Stamp.of).toBe(Stamp); | ||
| }); | ||
| }); | ||
| describe('@stamp/fp-constructor instance.constructor', function() { | ||
| it('should add .constructor method to the stamp', function() { | ||
| var Stamp = compose(FpConstructor); | ||
| var instance = Stamp(); | ||
| expect(instance.constructor).toBe(Stamp); | ||
| }); | ||
| it('should not be an own prop on the instance', function() { | ||
| var Stamp = compose(FpConstructor); | ||
| var instance = Stamp(); | ||
| expect(Object.getPrototypeOf(instance).constructor).toBe(Stamp); | ||
| }); | ||
| it('should refer to the correct stamp regardless of other stamps in the composition', function() { | ||
| var Stamp = compose({methods: {constructor: 1}}) | ||
| .compose( | ||
| {methods: {constructor: 2}}, | ||
| FpConstructor, | ||
| {methods: {constructor: 3}} | ||
| ).compose({methods: {constructor: 4}}); | ||
| var instance = Stamp(); | ||
| expect(instance.constructor).toBe(Stamp); | ||
| }); | ||
| it('should not break other methods', function() { | ||
| var foo = function foo () {}; | ||
| var bar = function bar () {}; | ||
| var Stamp = compose({methods: {foo: foo}}) | ||
| .compose( | ||
| FpConstructor | ||
| ).compose({methods: {bar: bar}}); | ||
| var instance = Stamp(); | ||
| expect(instance.foo).toBe(foo); | ||
| expect(instance.bar).toBe(bar); | ||
| }); | ||
| }); | ||
| describe('@stamp/fp-constructor Stamp.constructor (deprecated)', function() { | ||
| it('should add .constructor static method referring to the stamp', function() { | ||
| var Stamp = compose(FpConstructor); | ||
| expect(Stamp.constructor).toBe(Stamp); | ||
| }); | ||
| }); |
+3
-0
@@ -5,4 +5,7 @@ var compose = require('@stamp/compose'); | ||
| composers: [function (opts) { | ||
| opts.stamp.of = opts.stamp; | ||
| opts.stamp.constructor = opts.stamp; | ||
| opts.stamp.compose.methods = opts.stamp.compose.methods || {}; | ||
| opts.stamp.compose.methods.constructor = opts.stamp; | ||
| }] | ||
| }); |
+1
-1
| { | ||
| "name": "@stamp/fp-constructor", | ||
| "version": "0.1.10", | ||
| "version": "0.2.0", | ||
| "description": "Adds the Stamp.constructor property referencing Stamp itself", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
+41
-4
| # @stamp/fp-constructor | ||
| _Adds the Stamp.constructor property referencing Stamp itself_ | ||
| * _Adds the `Stamp.of` static property referencing Stamp itself_ | ||
| * _Adds the `instance.constructor` property referencing Stamp itself_ | ||
@@ -9,7 +10,38 @@ By composing the `@stamp/fp-constructor` into your stamp | ||
| ``` | ||
| you get the static method `.constructor`: | ||
| you get the static method `.of`: | ||
| ```js | ||
| MyStamp.constructor === MyStamp // true | ||
| MyStamp.of === MyStamp; // true | ||
| ``` | ||
| and the instance method, `.constructor`: | ||
| ```js | ||
| instance = MyStamp(/* ...options */); | ||
| instance.constructor === MyStamp; // true | ||
| ``` | ||
| ## Motivation | ||
| Frequently, it's desirable to instantiate a new instance of a given datatype inside a generic function. However, JavaScript lacks a built-in way to do that which is reliable. Classes throw errors if you leave off `new`, and arrow function factories will throw if you try to instantiate an instance with `new`, and there's no standard way to inject a value into the new datatype. | ||
| The `Stamp.of()` is a standard way to create a new value of a given stamp where the calling conventions are unambiguous: It does not require `new`, and you inject the value by passing the necessary arguments directly into the `.of()` static method. | ||
| Having the `.of()` method only solves half of the problem, though. You still need a way got get a handle on the stamp from an object instance. You can do that with the `instance.constructor()` method. | ||
| Here's an example of what you can do with the combination. The following `empty()` utility will return an empty instance of whatever supporting datatype you pass in, including standard JavaScript arrays: | ||
| ```js | ||
| const empty = ({ constructor } = {}) => constructor.of ? | ||
| constructor.of() : | ||
| undefined | ||
| ; | ||
| const foo = [23]; | ||
| console.log( | ||
| empty(foo) // [] | ||
| ); | ||
| ``` | ||
| All [applicative functors](https://github.com/fantasyland/fantasy-land#applicative) in JavaScript should implement `.of()`. | ||
| ## Usage | ||
@@ -28,2 +60,7 @@ | ||
| #### methods | ||
| `stamp.constructor(...args) -> Object` | ||
| `stamp.of(...args) => Object` | ||
| ### Instance methods | ||
| ### methods | ||
| `instance.constructor(...args) => Object` |
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
4881
190.88%65
182.61%65
132.14%1
Infinity%