Skip to content

Commit

Permalink
feat: add state class
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickheng committed Feb 12, 2017
1 parent 66e1891 commit 9e08f59
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 34 deletions.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,10 @@
"require": [
"babel-core/register"
]
},
"dependencies": {
"ava": "^0.18.1",
"lodash.isequal": "^4.5.0",
"quark-signal": "^1.1.0"
}
}
154 changes: 124 additions & 30 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,129 @@
/**
* Simple class
*
* @class
*
* @license {@link https://opensource.org/licenses/MIT|MIT}
*
* @author Patrick Heng <hengpatrick.pro@gmail.com>
* @author Fabien Motte <contact@fabienmotte.com>
*
* @example
* const simple = new Simple()
* simple.test()
*/
class Simple {
/**
* Creates an instance of Simple
*
* @constructor
*/
import Signal from 'quark-signal'
import isEquals from 'lodash.isequal'

class State {

constructor () {
this.message = 'Hello world'
this._containers = {}
}

/**
* Simple method
*
* @returns {string}
*/
test () {
return this.message
get (query) {
const { container, splittedQuery } = this._parseStateQuery(query)

let value = container

if (splittedQuery.length > 1) {
for (let i = 1, l = splittedQuery.length; i < l; i++) {
value = value[splittedQuery[i]]

if (value === undefined || value === null) {
break
}
}
}

return value
}
}

export default Simple
set (query, value, forced = false) {
const { container, containerId, splittedQuery } = this._parseStateQuery(query)

let target = this._containers
for (let i = 0, l = splittedQuery.length; i < l; i++) {
const p = splittedQuery[i]
const oldVal = target[p]

if (typeof target[p] !== 'object') {
target[p] = {}
}

if (i === splittedQuery.length - 1) {
if (typeof oldVal === 'undefined' || typeof value !== 'object' || value === null || forced) {
target[p] = value
} else {
target[p] = {
...target,
...value
}
}
}

target = target[p]

// Dispatch signal on change
let signalId = containerId
for (let j = 0; j < i; j++) {
signalId += `_${splittedQuery[i]}`

console.log(signalId)
if (typeof container.signals[signalId] !== 'undefined') {
if (!isEquals(oldVal, target)) {
container.signals[signalId].dispatch(oldVal, target)
}
}
}
}
}

onChange (query, callback) {
const { container, containerId, splittedQuery } = this._parseStateQuery(query)

let signalId = containerId

for (let i = 1, l = splittedQuery.length; i < l; i++) {
signalId += `_${splittedQuery[i]}`
}

if (typeof container.signals[query] === 'undefined') {
container.signals[signalId] = new Signal()
}

if (typeof callback !== 'function') {
throw new TypeError('Signal.onChange() : Second argument must be a Function')
}

container.signals[signalId].add(callback)
}

removeChangeCallback (query, callback) {
const { container } = this._parseStateQuery(query)

if (typeof callback !== 'function') {
throw new TypeError('Signal.removeChangeCallback() : Second argument must be a Function')
}

if (typeof container.signals[query] !== 'undefined') {
container.signals[query].remove(callback)
}
}

initContainer (containerId, value) {
this._containers[containerId] = value
this._containers[containerId].signals = {}
}

destroyContainer (containerId) {
if (typeof this._containers[containerId] !== 'undefined') {
for (let signalProp in this._containers[containerId].signals) {
this._containers[containerId].signals[signalProp].removeAll()
this._containers[containerId].signals[signalProp] = null
}

this._containers[containerId] = null
delete this._containers[containerId]
}
}

_parseStateQuery (query) {
const splittedQuery = query.split('.')
let objPathSegments = null

return {
container: this._containers[splittedQuery[0]],
containerId: splittedQuery[0],
prop: splittedQuery[1],
splittedQuery
}
}
}
export default new State()
14 changes: 10 additions & 4 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import test from 'ava'

import Simple from '../src/index'
import States from '../src/index'

test.beforeEach(t => {
t.context.simple = new Simple()
// t.context.simple = new Simple()
})

test('simple test', t => {
t.is(t.context.simple.test(), 'Hello world')
test('Set container', t => {
const initObj = {
message: 'hello world'
}

States.initContainer('TEST', initObj)

t.is(States.containers['TEST'], initObj)
})

0 comments on commit 9e08f59

Please sign in to comment.