New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

microcosm

Package Overview
Dependencies
Maintainers
1
Versions
233
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

microcosm - npm Package Compare versions

Comparing version 1.4.0 to 2.0.0

src/assert.js

34

CHANGELOG.md
# Changelog
### 2.0.0
- Replace default `Microcosm::send` currying with partial application
using `Microcosm::prepare`
- Throw an error if a store is added that does not have a unique identifier
- `Microcosm::set` has been replaced with `Microcosm::merge`, so far
`set` has only been used internally to `Microcosm` and `merge` dries
a couple of things up
#### More info on removing currying
Currying has been removed `Microcosm::send`. This was overly clever
and somewhat malicious. If an action has default arguments, JavaScript
has no way (to my knowledge) of communicating it. One (me) could get into a
situation where it is unclear why an action has not fired properly
(insufficient arguments when expecting fallback defaults).
In a language without static typing, this can be particularly hard to debug.
In most cases, partial application is sufficient. In light of this,
actions can be "buffered up" up with `Microcosm::prepare`:
```javascript
// Old
let curried = app.send(Action)
// New
let partial = app.prepare(Action)
```
`Microcosm::prepare` is basically just `fn.bind()` under the
hood. Actions should not use context whatsoever, so this should be a
reasonable caveat.
### 1.4.0

@@ -4,0 +38,0 @@

4

dist/Microcosm.js

@@ -1,2 +0,2 @@

module.exports=function(t){function n(r){if(e[r])return e[r].exports;var i=e[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){"use strict";n.__esModule=!0;var r=e(4);n.tag=r,n["default"]=e(2)},function(t){"use strict";var n=function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")},e=function(){function t(){n(this,t),this._callbacks=[]}return t.prototype.ignore=function(t){this._callbacks=this._callbacks.filter(function(n){return n!==t})},t.prototype.listen=function(t){this._callbacks=this._callbacks.concat(t)},t.prototype.pump=function(){for(var t=0;t<this._callbacks.length;t++)this._callbacks[t].call(this)},t}();t.exports=e},function(t,n,e){"use strict";var r=function(t){return t&&t.__esModule?t["default"]:t},i=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var e=arguments[n];for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&(t[r]=e[r])}return t},o=function(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Super expression must either be null or a function, not "+typeof n);t.prototype=Object.create(n&&n.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),n&&(t.__proto__=n)},s=function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")},u=r(e(1)),a=r(e(3)),c=r(e(5)),f=function(t){function n(){s(this,n),t.call(this),this._stores=[],this._state=this.getInitialState()}return o(n,t),n.prototype.getInitialState=function(){return{}},n.prototype.shouldUpdate=function(t,n){return 0==c(t,n)},n.prototype.seed=function(t){this.swap(this.deserialize(t))},n.prototype.swap=function(t){this.shouldUpdate(this._state,t)&&(this._state=t,this.pump())},n.prototype.set=function(t,n){this._state=i({},this._state,function(){var e={};return e[t]=n,e}())},n.prototype.get=function(t){return this._state[t]},n.prototype.send=function(t){for(var n=this,e=arguments.length,r=Array(e>1?e-1:0),i=1;e>i;i++)r[i-1]=arguments[i];if(r.length<t.length)return this.send.bind(this,t);var o=t.apply(void 0,r);return o instanceof Promise?o.then(function(e){return n.dispatch(t,e)}):this.dispatch(t,o)},n.prototype.dispatch=function(t,n){var e=this,r=this._stores.filter(function(n){return t in n}),o=r.reduce(function(r,i){return r[i]=i[t](e.get(i),n),r},{});return this.swap(i({},this._state,o)),n},n.prototype.addStore=function(){for(var t=this,n=arguments.length,e=Array(n),r=0;n>r;r++)e[r]=arguments[r];this._stores=e.reduce(function(n,e){var r=i({},a,e);return t.set(r,r.getInitialState()),n.concat(r)},this._stores)},n.prototype.serialize=function(){var t=this;return this._stores.reduce(function(n,e){return n[e]=e.serialize(t.get(e)),n},i({},this._state))},n.prototype.deserialize=function(t){return this._stores.reduce(function(n,e){return n[e]=e.deserialize(t[e]),n},i({},t))},n.prototype.toJSON=function(){return this.serialize()},n}(u);t.exports=f},function(t){"use strict";t.exports={getInitialState:function(){return void 0},serialize:function(t){return t},deserialize:function(){var t=void 0===arguments[0]?this.getInitialState():arguments[0];return t},toString:function(){throw new Error("Stores must implement a toString() method")}}},function(t){"use strict";var n=0,e=function(t){return"function"==typeof t},r=function(t,e){var r=t.bind(null),i="_"+e+"_"+n++;return r.toString=function(){return i},r};t.exports=function(t){var n=Object.keys(t);return n.reduce(function(n,i){var o=t[i];return n[i]=e(o)?r(o,i):o,n},{})}},function(t,n,e){/*!
module.exports=function(t){function r(e){if(n[e])return n[e].exports;var o=n[e]={exports:{},id:e,loaded:!1};return t[e].call(o.exports,o,o.exports,r),o.loaded=!0,o.exports}var n={};return r.m=t,r.c=n,r.p="",r(0)}([function(t,r,n){"use strict";r.__esModule=!0;var e=n(7);r.tag=e,r["default"]=n(2)},function(t){"use strict";var r=function(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")},n=function(){function t(){r(this,t),this._callbacks=[]}return t.prototype.ignore=function(t){this._callbacks=this._callbacks.filter(function(r){return r!==t})},t.prototype.listen=function(t){this._callbacks=this._callbacks.concat(t)},t.prototype.pump=function(){for(var t=0;t<this._callbacks.length;t++)this._callbacks[t].call(this)},t}();t.exports=n},function(t,r,n){"use strict";var e=function(t){return t&&t.__esModule?t["default"]:t},o=function(t,r){if("function"!=typeof r&&null!==r)throw new TypeError("Super expression must either be null or a function, not "+typeof r);t.prototype=Object.create(r&&r.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),r&&(t.__proto__=r)},i=function(t,r){if(!(t instanceof r))throw new TypeError("Cannot call a class as a function")},s=e(n(1)),u=e(n(3)),a=e(n(4)),c=e(n(5)),f=e(n(8)),p=e(n(6)),l=function(t){function r(){i(this,r),t.call(this),this._stores=[],this._state=this.getInitialState()}return o(r,t),r.prototype.getInitialState=function(){return{}},r.prototype.shouldUpdate=function(t,r){return 0==f(t,r)},r.prototype.seed=function(t){this.swap(this.deserialize(t))},r.prototype.has=function(){for(var t=this,r=arguments.length,n=Array(r),e=0;r>e;e++)n[e]=arguments[e];return n.some(function(r){return t._stores.some(function(t){return""+r==""+t})})},r.prototype.get=function(t){return this._state[t]},r.prototype.swap=function(t){this.shouldUpdate(this._state,t)&&(this._state=t,this.pump())},r.prototype.merge=function(t){this.swap(c(this._state,t))},r.prototype.prepare=function(t){for(var r,n=arguments.length,e=Array(n>1?n-1:0),o=1;n>o;o++)e[o-1]=arguments[o];return(r=this.send).bind.apply(r,[this,t].concat(e))},r.prototype.send=function(t){for(var r=this,n=arguments.length,e=Array(n>1?n-1:0),o=1;n>o;o++)e[o-1]=arguments[o];var i=t.apply(this,e);return i instanceof Promise?i.then(function(n){return r.dispatch(t,n)}):this.dispatch(t,i)},r.prototype.dispatch=function(t,r){var n=this,e=this._stores.filter(function(r){return t in r}),o=p(e,function(e){return e[t](n.get(e),r)});return this.merge(o),r},r.prototype.addStore=function(){for(var t=arguments.length,r=Array(t),n=0;t>n;n++)r[n]=arguments[n];var e=r.map(function(t){return c(u,t)});a(!this.has(e),'A toString method within "'+r+'" is not unique'),this._stores=this._stores.concat(e),this.merge(p(e,function(t){return t.getInitialState()}))},r.prototype.serialize=function(){var t=this;return p(this._stores,function(r){return r.serialize(t.get(r))})},r.prototype.deserialize=function(t){return p(this._stores,function(r){return r.deserialize(t[r])})},r.prototype.toJSON=function(){return this.serialize()},r}(s);t.exports=l},function(t){"use strict";t.exports={getInitialState:function(){return void 0},serialize:function(t){return t},deserialize:function(){var t=void 0===arguments[0]?this.getInitialState():arguments[0];return t},toString:function(){throw new Error("Stores must implement a toString() method")}}},function(t){"use strict";function r(t,r){if(!t){var n=new Error(r);throw n.framesToPop=1,n}}t.exports=r},function(t){"use strict";function r(t,r){return n({},t,r)}var n=Object.assign||function(t){for(var r=1;r<arguments.length;r++){var n=arguments[r];for(var e in n)Object.prototype.hasOwnProperty.call(n,e)&&(t[e]=n[e])}return t};t.exports=r},function(t){"use strict";function r(t,r){return t.reduce(function(t,n){return t[n]=r(n),t},{})}t.exports=r},function(t){"use strict";var r=0,n=function(t){return"function"==typeof t},e=function(t,n){var e=t.bind(null),o="_"+n+"_"+r++;return e.toString=function(){return o},e};t.exports=function(t){var r=Object.keys(t);return r.reduce(function(r,o){var i=t[o];return r[o]=n(i)?e(i,o):i,r},{})}},function(t,r,n){/*!
* is-equal-shallow <https://github.com/jonschlinkert/is-equal-shallow>

@@ -7,3 +7,3 @@ *

*/
"use strict";var r=e(6);t.exports=function(t,n){if(!t&&!n)return!0;if(!t&&n||t&&!n)return!1;for(var e in n)if(!r(n[e])||!t.hasOwnProperty(e)||t[e]!==n[e])return!1;return!0}},function(t){/*!
"use strict";var e=n(9);t.exports=function(t,r){if(!t&&!r)return!0;if(!t&&r||t&&!r)return!1;for(var n in r)if(!e(r[n])||!t.hasOwnProperty(n)||t[n]!==r[n])return!1;return!0}},function(t){/*!
* is-primitive <https://github.com/jonschlinkert/is-primitive>

@@ -10,0 +10,0 @@ *

@@ -51,6 +51,6 @@ # Microcosm

}
set(key, value) {
merge(object) {
// How state should be re-assigned. This function is useful to
// override with the particular method of assignment for the data
// structure returned from `getInitialState`
// override with the particular method of assignment for merging
// data for whatever is returned from from `getInitialState`
}

@@ -62,6 +62,9 @@ get(key) {

}
prepare(fn, ...params) {
// Returns a partially applied version of `send`. Useful
// for concise callbacks in React components
}
send(fn, ...params) {
// Responsible for pushing an action through the system.
// `send` allows for currying of the `params` list is shorter than
// the accepted arguments of `fn
// `send`.
//

@@ -68,0 +71,0 @@ // If `fn(...params)` returns a promise, it will wait for this

@@ -28,3 +28,3 @@ import AddIcon from 'icons/add'

list={ list }
onDelete={ flux.send(ListActions.remove) } />)
onDelete={ flux.prepare(ListActions.remove) } />)
},

@@ -57,3 +57,3 @@

onExit={ this._onToggle }
onCreate={ flux.send(ListActions.add) } />
onCreate={ flux.prepare(ListActions.add) } />
</main>

@@ -60,0 +60,0 @@ )

@@ -18,3 +18,3 @@ /**

install(app) {
let action = app.send(Route.set)
let action = app.prepare(Route.set)

@@ -21,0 +21,0 @@ // Create a callback for each route that pushes the event

{
"name": "microcosm",
"version": "1.4.0",
"version": "2.0.0",
"description": "An experimental flux implimentation",

@@ -22,6 +22,6 @@ "main": "dist/Microcosm.js",

"autoprefixer-core": "^5.1.7",
"babel": ">= 4.7.3",
"babel-loader": ">= 4.1.0",
"babel": ">= 4.7.16",
"babel-loader": ">= 4.2.0",
"babel-runtime": "^4.7.16",
"chai": "^2.1.1",
"chai": "^2.1.2",
"coveralls": "^2.11.2",

@@ -31,6 +31,6 @@ "css-loader": "^0.9.0",

"csswring": "^3.0.2",
"istanbul": "^0.3.5",
"istanbul": "^0.3.11",
"istanbul-instrumenter-loader": "^0.1.2",
"json-loader": "^0.5.1",
"karma": "^0.12.31",
"karma": "^0.12.32",
"karma-chrome-launcher": "^0.1.7",

@@ -48,8 +48,9 @@ "karma-cli": "0.0.4",

"raw-loader": "^0.5.1",
"react-hot-loader": "^1.2.3",
"react-tools": ">= 0.12.2",
"react-hot-loader": "^1.2.4",
"react": ">= 0.13.1",
"react-tools": ">= 0.13.1",
"route-recognizer": "^0.1.5",
"sass-loader": "^0.4.1",
"sass-loader": "^1.0.0",
"source-map-loader": "^0.1.3",
"style-loader": "^0.8.2",
"style-loader": "^0.9.0",
"uid": "0.0.2",

@@ -56,0 +57,0 @@ "webpack": "^1.7.2",

@@ -60,3 +60,3 @@ import Action from './fixtures/Action'

it ('can assign new state', function() {
it ('can merge in new state', function() {
let seed = { fiz: 'buz' }

@@ -67,3 +67,3 @@ let m = new Microcosm({ dummy: seed })

m.set(DummyStore, { fiz: 'not-buz'})
m.merge({ [DummyStore] : { fiz: 'not-buz'} })

@@ -109,2 +109,4 @@ m.get(DummyStore).fiz.should.equal('not-buz')

m.addStore({ toString: () => 'another-store' })
m.listen(function() {

@@ -114,14 +116,25 @@ throw Error("Expected app to not respond but did")

m.addStore({ toString: () => 'another-store' })
m.send(Action)
})
it ('can curry the send method', function() {
it ('can partially apply actions', function() {
let m = new Microcosm()
let add = (a, b) => a + b
let add = (a=0, b=0) => a + b
m.send(add)(2, 3).should.equal(5)
m.prepare(add)(2, 3).should.equal(5)
m.prepare(add, 4)(1).should.equal(5)
m.prepare(add)(1).should.equal(1)
})
it ('throws an error of a stores toString is not unique', function(done) {
let m = new Microcosm()
m.addStore({ toString() { return 'fiz' } })
try {
m.addStore({ toString() { return 'fiz' } })
} catch(x) {
done()
}
})
})

@@ -9,3 +9,6 @@ /**

import Store from './Store'
import assert from './assert'
import assign from './assign'
import isEqual from 'is-equal-shallow'
import mapBy from './mapBy'

@@ -47,2 +50,13 @@ export default class Microcosm extends Heartbeat {

has(...stores) {
return stores.some(a => this._stores.some(b => `${a}` === `${b}`))
}
get(key) {
// How state should be retrieved. This function is useful to
// override with the particular method of retrieval for the data
// structure returned from `getInitialState`
return this._state[key]
}
swap(next) {

@@ -56,24 +70,16 @@ // Given a next state, only trigger an event if state actually changed

set(key, value) {
merge(obj) {
// How state should be re-assigned. This function is useful to
// override with the particular method of assignment for the data
// structure returned from `getInitialState`
this._state = { ...this._state, [key]: value }
this.swap(assign(this._state, obj))
}
get(key) {
// How state should be retrieved. This function is useful to
// override with the particular method of retrieval for the data
// structure returned from `getInitialState`
return this._state[key]
prepare(fn, ...buffer) {
return this.send.bind(this, fn, ...buffer)
}
send(fn, ...params) {
// Allow currying of send method for cleaner callbacks
if (params.length < fn.length) {
return this.send.bind(this, fn)
}
let request = fn.apply(this, params)
let request = fn(...params)
// Actions some times return promises. When this happens, wait for

@@ -93,9 +99,6 @@ // them to resolve before moving on

// Next build the change set
let changes = answerable.reduce((state, store) => {
state[store] = store[action](this.get(store), body)
return state
}, {})
let changes = mapBy(answerable, store => store[action](this.get(store), body))
// Produce the next state by folding changes into the current state
this.swap({ ...this._state, ...changes })
// Produce the next state by mapBying changes into the current state
this.merge(changes)

@@ -107,27 +110,23 @@ // Send back the body to the original signaler

addStore(...stores) {
this._stores = stores.reduce((pool, store) => {
// Make sure that the Store implements important life cycle
// methods
let valid = { ...Store, ...store }
// Make sure that the Store implements important life cycle methods
let safe = stores.map(s => assign(Store, s))
// Once verified, setup initial state
this.set(valid, valid.getInitialState())
// Don't reassign stores that are already included fail hard
assert(!this.has(safe), `A toString method within "${stores}" is not unique`)
// Finally, add it to the pool of known stores
return pool.concat(valid)
}, this._stores)
// Add the validated stores to the list of known entities
this._stores = this._stores.concat(safe)
// Once verified, setup initial state.
// This is done last so that any callbacks that need to reduce
// over the current state have the latest list of stores
this.merge(mapBy(safe, store => store.getInitialState()))
}
serialize() {
return this._stores.reduce((memo, store) => {
memo[store] = store.serialize(this.get(store))
return memo
}, { ...this._state })
return mapBy(this._stores, store => store.serialize(this.get(store)))
}
deserialize(data) {
return this._stores.reduce(function(memo, store) {
memo[store] = store.deserialize(data[store])
return memo
}, { ...data })
return mapBy(this._stores, store => store.deserialize(data[store]))
}

@@ -134,0 +133,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc