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.0.0 to 1.1.0

example/src/services/storage.js

13

CHANGELOG.md
# Changelog
### 1.1.0
- Better seeding. Added `Microcosm::seed` which accepts an
object. For each known key, Microcosm will the associated store's
`getInitialState` function and set the returned value.
- Exposed `Microcosm::getInitialState` to configure the starting value
of the instance. This is useful for those wishing to use the
`immutable` npm package by Facebook.
- Microcosm will not emit changes on dispatch unless the new state
fails a shallow equality check. This can be configured with
`Microcosm::shouldUpdate`
- `Microcosm::send` is now curried.
### 1.0.0

@@ -4,0 +17,0 @@

27

design.md
```
|--> [Store] ---|
[Signal] --------> [Processing] -----> [Multicast] ----+--> [Store] ---+------> [Update Global State]
^ |- Auth |--> [Store] ---| |
| |- Routing v
| [Render]
| |
| |
+------------------------- [Signal] ------------------------------------------+
|
^
|
[Background Services]
|- History API
|- Window Resize
|- Mouse move
|- Server request (for Progression)
|- Firebase sync
|--> [Store] ---|
[app.send] ------> [Action] ------> [Dispatcher] ---+--> [Store] ---+--> [app.shouldUpdate?]
^ |--> [Store] ---| |
| |
| v
[External Services] <--------------------------------------------------------- [YES]
|- User Interface
|- Router
|- Firebase sync
```

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

module.exports=function(t){function n(r){if(e[r])return e[r].exports;var o=e[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,n),o.loaded=!0,o.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._tick=null,this._callbacks=[]}return t.prototype._pump=function(){for(var t=0;t<this._callbacks.length;t++)this._callbacks[t]()},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(){this._callbacks.length>0&&(cancelAnimationFrame(this._tick),this._tick=requestAnimationFrame(this._pump.bind(this)))},t}();t.exports=e},function(t,n,e){"use strict";var r=function(t){return t&&t.__esModule?t["default"]:t},o=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},i=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=function(t){function n(e){s(this,n),t.call(this),this.stores=[],this._state=this.getInitialState(e)}return i(n,t),n.prototype.getInitialState=function(){var t=void 0===arguments[0]?{}:arguments[0];return o({},t)},n.prototype.set=function(t,n){this._state=o({},this._state,function(){var e={};return e[t]=n,e}())},n.prototype.get=function(t){return this._state[t]||t.getInitialState()},n.prototype.send=function(t,n){var e=this,r=a(t(n));return r.then(function(n){return e.dispatch(t,n)})},n.prototype.dispatch=function(t,n){var e=this;return this._state=this.stores.reduce(function(r,o){return t in o&&(r[o]=o[t](e.get(o),n)),r},o({},this._state)),this.pump(),n},n.prototype.addStore=function(){for(var t=arguments.length,n=Array(t),e=0;t>e;e++)n[e]=arguments[e];this.stores=this.stores.concat(n)},n.prototype.serialize=function(){var t=this;return this.stores.reduce(function(n,e){return n[e]=t.get(e),n},{})},n}(u);t.exports=c},function(t){"use strict";t.exports=function(t){return t instanceof Promise?t:Promise.resolve(t)}},function(t,n,e){"use strict";var r=function(t){return t&&t.__esModule?t["default"]:t};n.__esModule=!0;var o=r(e(5)),i=0,s=function(t){var n=t.bind(null),e="_microcosm-"+i++;return n.toString=function(){return e},n};n.infuse=s,n["default"]=function(t){return o(t,s)}},function(t){"use strict";t.exports=function(t,n){var e=void 0===arguments[0]?{}:arguments[0],r=void 0===arguments[2]?{}:arguments[2],o=Object.keys(e);return o.reduce(function(t,r){return t[r]=n(e[r],r),t},r)}}]);
module.exports=function(t){function n(e){if(r[e])return r[e].exports;var o=r[e]={exports:{},id:e,loaded:!1};return t[e].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){"use strict";n.__esModule=!0;var e=r(3);n.tag=e,n["default"]=r(2)},function(t){"use strict";var n=function(t,n){if(!(t instanceof n))throw new TypeError("Cannot call a class as a function")},r=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]()},t}();t.exports=r},function(t,n,r){"use strict";var e=function(t){return t&&t.__esModule?t["default"]:t},o=Object.assign||function(t){for(var n=1;n<arguments.length;n++){var r=arguments[n];for(var e in r)Object.prototype.hasOwnProperty.call(r,e)&&(t[e]=r[e])}return t},i=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=e(r(1)),a=e(r(5)),c=function(t){function n(){s(this,n),t.call(this),this._stores=[],this._state=this.getInitialState()}return i(n,t),n.prototype.shouldUpdate=function(t,n){return 0==a(t,n)},n.prototype.getInitialState=function(){return{}},n.prototype.seed=function(t){var n=this._stores.filter(function(n){return t[n]});n.forEach(function(n){this.set(n,n.getInitialState(t[n]))},this)},n.prototype.set=function(t,n){this._state=o({},this._state,function(){var r={};return r[t]=n,r}())},n.prototype.has=function(t){return this._stores.indexOf(t)>-1},n.prototype.get=function(t,n){return this._state[t]||t.getInitialState(n)},n.prototype.send=function(t){for(var n=this,r=arguments.length,e=Array(r>1?r-1:0),o=1;r>o;o++)e[o-1]=arguments[o];if(e.length<t.length)return this.send.bind(this,t);var i=t.apply(void 0,e);return i instanceof Promise?i.then(function(r){return n.dispatch(t,r)}):this.dispatch(t,i)},n.prototype.dispatch=function(t,n){var r=this,e=this._stores.reduce(function(e,o){return t in o&&(e[o]=o[t](r.get(o),n)),e},o({},this._state));return this.shouldUpdate(this._state,e)&&(this._state=e,this.pump()),n},n.prototype.addStore=function(){for(var t=arguments.length,n=Array(t),r=0;t>r;r++)n[r]=arguments[r];this._stores=this._stores.concat(n)},n.prototype.toJSON=function(){return this.serialize()},n.prototype.serialize=function(){var t=this;return this._stores.reduce(function(n,r){return n[r]=t.get(r),n},{})},n}(u);t.exports=c},function(t,n,r){"use strict";var e=function(t){return t&&t.__esModule?t["default"]:t};n.__esModule=!0;var o=e(r(4)),i=0,s=function(t){var n=t.bind(null),r="_microcosm-"+i++;return n.toString=function(){return r},n};n.infuse=s,n["default"]=function(t){return o(t,s)}},function(t){"use strict";t.exports=function(t,n){var r=void 0===arguments[0]?{}:arguments[0],e=void 0===arguments[2]?{}:arguments[2],o=Object.keys(r);return o.reduce(function(t,e){return t[e]=n(r[e],e),t},e)}},function(t,n,r){/*!
* is-equal-shallow <https://github.com/jonschlinkert/is-equal-shallow>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
"use strict";var e=r(6);t.exports=function(t,n){if(!t&&!n)return!0;if(!t&&n||t&&!n)return!1;for(var r in n)if(!e(n[r])||!t.hasOwnProperty(r)||t[r]!==n[r])return!1;return!0}},function(t){/*!
* is-primitive <https://github.com/jonschlinkert/is-primitive>
*
* Copyright (c) 2014 Jon Schlinkert, contributors.
* Licensed under the MIT License
*/
"use strict";t.exports=function(t){switch(typeof t){case"string":case"number":case"boolean":case"symbol":return!0}return null==t}}]);
//# sourceMappingURL=Microcosm.js.map

@@ -27,3 +27,3 @@ import Items from 'stores/Items'

componentDidMount() {
this.props.flux.listen(_ => this.setState(this.getState))
this.props.flux.listen(_ => this.setState(this.getState()))
},

@@ -30,0 +30,0 @@

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

import TaskList from 'fragments/TaskList'
import { Link } from 'react-router'

@@ -25,10 +24,13 @@ let Home = React.createClass({

getList(list) {
let items = this.props.items.filter(i => i.list === list.id)
let { items, flux } = this.props
return (
<ListItem key={ list.id } items={ items } list={ list } onDelete={ this._onDestroy } />
)
return (<ListItem key={ list.id }
items={ items.filter(i => i.list === list.id) }
list={ list }
onDelete={ flux.send(ListActions.remove) } />)
},
render() {
let { flux } = this.props
return (

@@ -56,3 +58,3 @@ <main role="main">

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

@@ -64,10 +66,2 @@ )

this.setState({ openCreate: !this.state.openCreate })
},
_onDestroy(id) {
this.props.flux.send(ListActions.remove, id)
},
_onCreate(props) {
this.props.flux.send(ListActions.add, props)
}

@@ -74,0 +68,0 @@

@@ -46,3 +46,3 @@ import BackIcon from 'icons/arrow-back'

this.props.flux.send(ListActions.remove, this.props.params.id)
.then(() => page('/'))
page('/')
},

@@ -49,0 +49,0 @@

import 'style/app'
import App from './App'
import Router from './services/router'
import Route from './actions/route'
import App from 'App'
import Layout from 'components/Layout'
import React from 'react'
import Router from 'services/router'
import Storage from 'services/storage'
let flux = new App()
let el = document.getElementById('app')
// Each app is a unique instance.
// It will get its own state, useful for having multiple apps on
// the same page or for independence between requests
let app = new App()
// Services
Router.install(flux, Route.set)
// Services are basically just listeners
// that operate on an app instance
requestAnimationFrame(function() {
React.render(<Layout flux={ flux } />, document.getElementById('app'))
})
// On change, this will save to local stoage
Storage.install(app)
// Pushes route actions as they occur
Router.install(app)
React.render(<Layout flux={ app } />, document.getElementById('app'))

@@ -7,2 +7,3 @@ /**

import Route from 'actions/route'
import page from 'page'

@@ -17,6 +18,6 @@

install(flux, action) {
install(flux) {
Object.keys(routes).forEach(route => {
page(route, function({ params }) {
flux.send(action, { handler: routes[route], params })
flux.send(Route.set, { handler: routes[route], params })
})

@@ -23,0 +24,0 @@ })

import Items from 'actions/items'
import Lists from 'actions/lists'
import uid from 'uid'
export default {
getInitialState() {
return []
getInitialState(seed=[]) {
return seed
},
[Items.add](state, { list, name }) {
let record = { id: state.length, list: list.id, name }
let record = {
id : uid(),
list : list.id,
name : name
}

@@ -13,0 +18,0 @@ return state.concat(record)

import Lists from 'actions/lists'
import contrast from 'contrast'
import uid from 'uid'
export default {
getInitialState() {
return []
getInitialState(seed=[]) {
return seed
},
[Lists.add](state, params) {
let record = { color : '#aaaaaa', id : state.length, ...params }
let record = {
id : uid(),
color : '#aaaaaa',
...params
}

@@ -13,0 +18,0 @@ record.contrast = contrast(record.color)

{
"name": "microcosm",
"version": "1.0.0",
"version": "1.1.0",
"description": "An experimental flux implimentation",

@@ -17,3 +17,5 @@ "main": "dist/Microcosm.js",

"license": "MIT",
"dependencies": {},
"dependencies": {
"is-equal-shallow": "^0.1.1"
},
"devDependencies": {

@@ -51,2 +53,3 @@ "autoprefixer-core": "^5.1.7",

"style-loader": "^0.8.2",
"uid": "0.0.2",
"webpack": "^1.7.2",

@@ -53,0 +56,0 @@ "webpack-dev-server": "^1.7.0"

@@ -37,5 +37,4 @@ Important! This is largely an exploratory repo, used to vet some ideas

updated by returning a new value.
3. All Actions return promises when called. This allows error
validation for forms and easy prefetching of information
when rendering on the server.
3. All Actions that return promises will wait to resolve before
dispatching.
4. It should be easily to embed in libraries. Additional features

@@ -42,0 +41,0 @@ should be able to layer on top.

@@ -5,4 +5,4 @@ import Action from './Action'

getInitialState() {
return 'test'
getInitialState(seed='test') {
return seed
},

@@ -9,0 +9,0 @@

@@ -8,12 +8,2 @@ import Heartbeat from '../Heartbeat'

it ('does not flush if there are no callbacks', function() {
let spy = sinon.spy(window, 'requestAnimationFrame')
heart.pump()
spy.should.not.have.been.called
spy.restore()
})
it ('can listen to callbacks', function(done) {

@@ -24,30 +14,13 @@ heart.listen(done)

it ('batches subscriptions', function(done) {
it ('can ignore callbacks', function() {
let stub = sinon.stub()
heart.listen(stub)
heart.ignore(stub)
for (var i = 100; i > 0; i--) {
heart.pump()
}
requestAnimationFrame(() => {
stub.should.have.been.calledOnce
done()
})
})
it ('can ignore callbacks', function(done) {
let stub = sinon.stub()
heart.listen(stub)
heart.ignore(stub)
heart.pump()
requestAnimationFrame(() => {
stub.should.not.have.been.called
done()
})
stub.should.not.have.been.called
})
})

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

m.stores.length.should.equal(1)
m.has(DummyStore).should.equal(true)
})

@@ -28,3 +28,3 @@

m.addStore(DummyStore)
m.serialize().should.have.property('dummy', 'test')
m.toJSON().should.have.property('dummy', 'test')
})

@@ -34,6 +34,8 @@

let seed = { fiz: 'buz' }
let m = new Microcosm({ dummy: seed })
let m = new Microcosm()
m.addStore(DummyStore)
m.seed({ dummy: seed })
m.get(DummyStore).should.equal(seed)

@@ -53,3 +55,3 @@ })

it ('can send messages to the dispatcher', function(done) {
it ('can send sync messages to the dispatcher', function() {
let m = new Microcosm()

@@ -59,4 +61,14 @@

m.send(Action).then(function() {
m.dispatch.should.have.been.calledWith(Action, true)
m.send(Action)
m.dispatch.should.have.been.calledWith(Action, true)
})
it ('can send async messages to the dispatcher', function(done) {
let m = new Microcosm()
let Async = () => Promise.resolve(true)
sinon.spy(m, 'dispatch')
m.send(Async).then(function() {
m.dispatch.should.have.been.calledWith(Async, true)
done()

@@ -73,16 +85,27 @@ })

m.send(Action).then(function() {
spy.should.have.been.called
spy.restore()
done()
})
m.send(Action)
spy.should.have.been.called
spy.restore()
done()
})
it('can handle actions without store responses', function(done) {
it('does not emit a change if no handler responds', function() {
let m = new Microcosm()
m.addStore({ toString:() => 'another-store' })
m.send(Action).then(_ => done())
m.listen(function() {
throw Error("Expected app to not respond but did")
})
m.addStore({ toString: () => 'another-store' })
m.send(Action)
})
it ('can curry the send method', function() {
let m = new Microcosm()
let add = (a, b) => a + b
m.send(add)(2, 3).should.equal(5)
})
})

@@ -7,18 +7,30 @@ /**

import Heartbeat from 'Heartbeat'
import promiseWrap from 'promiseWrap'
import Heartbeat from 'Heartbeat'
import isEqual from 'is-equal-shallow'
export default class Microcosm extends Heartbeat {
constructor(seed) {
constructor() {
super()
this.stores = []
this._state = this.getInitialState(seed)
this._stores = []
this._state = this.getInitialState()
}
getInitialState(seed={}) {
return { ...seed }
shouldUpdate(prev, next) {
return isEqual(prev, next) == false
}
getInitialState() {
return {}
}
seed(data) {
let insert = this._stores.filter(i => data[i])
insert.forEach(function(store) {
this.set(store, store.getInitialState(data[store]))
}, this)
}
set(key, value) {

@@ -28,14 +40,27 @@ this._state = { ...this._state, [key]: value }

get(store) {
return this._state[store] || store.getInitialState()
has(store) {
return this._stores.indexOf(store) > -1
}
send(fn, params) {
let request = promiseWrap(fn(params))
get(store, seed) {
return this._state[store] || store.getInitialState(seed)
}
return request.then(body => this.dispatch(fn, body))
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(...params)
if (request instanceof Promise) {
return request.then(body => this.dispatch(fn, body))
}
return this.dispatch(fn, request)
}
dispatch(type, body) {
this._state = this.stores.reduce((state, store) => {
let next = this._stores.reduce((state, store) => {
if (type in store) {

@@ -47,3 +72,6 @@ state[store] = store[type](this.get(store), body)

this.pump()
if (this.shouldUpdate(this._state, next)) {
this._state = next
this.pump()
}

@@ -54,7 +82,11 @@ return body

addStore(...store) {
this.stores = this.stores.concat(store)
this._stores = this._stores.concat(store)
}
toJSON() {
return this.serialize()
}
serialize() {
return this.stores.reduce((memo, store) => {
return this._stores.reduce((memo, store) => {
memo[store] = this.get(store)

@@ -61,0 +93,0 @@ return memo

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