Skip to content

Commit

Permalink
listent to array of states
Browse files Browse the repository at this point in the history
  • Loading branch information
windmaomao committed Nov 15, 2021
1 parent c07abd3 commit edcfa21
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 13 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,30 @@ p.inc(9) // count: 10

Notice the `inc` action is defined with a function that takes the current `state` as an input argument.

To listen to a property change, we can use a event listener:
To listen to a state change, we can subscribe to it with an event listener:

```jsx
const p = proxy({
count: 1
})

p.on('count', (v, prev) => {
// v: 2 prev: 1
// v: 2, prev: 1
console.log(v)
})

p.count++
```

The preceding `on` function listens to any change happened to the `count` state. The callback gives you the current value it changes to and the previous value it changes from.
The `on` function listens to any change happened to the `count` state. The callback gives you the current value and the previous value it changes from.

You can also listen to a set of states change instead of a single state:

```jsx
p.on(['count'], (v, prev, prop) => {
// v: 2, prev: 1, prop: 'count'
})
```

## Options

Expand Down
9 changes: 8 additions & 1 deletion dist/proxy-states.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ var listener = () => {
var has = event => !!m[event];

var add = (event, fn) => {
if (Array.isArray(event)) {
event.forEach(e => {
add(e, fn);
});
return;
}

m[event] = m[event] || [];
if (m[event].indexOf(fn) >= 0) return;
m[event].push(fn);
Expand Down Expand Up @@ -59,7 +66,7 @@ var handler = (ops, events) => ({
}

ops.afterSet && ops.afterSet(obj, prop, value, prev);
events.has(prop) && events.invoke(prop, value, prev);
events.has(prop) && events.invoke(prop, value, prev, prop);
return true;
}
});
Expand Down
9 changes: 8 additions & 1 deletion dist/proxy-states.umd.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
var has = event => !!m[event];

var add = (event, fn) => {
if (Array.isArray(event)) {
event.forEach(e => {
add(e, fn);
});
return;
}

m[event] = m[event] || [];
if (m[event].indexOf(fn) >= 0) return;
m[event].push(fn);
Expand Down Expand Up @@ -65,7 +72,7 @@
}

ops.afterSet && ops.afterSet(obj, prop, value, prev);
events.has(prop) && events.invoke(prop, value, prev);
events.has(prop) && events.invoke(prop, value, prev, prop);
return true;
}
});
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "proxy-states",
"description": "A plain proxy implementation to support a state object where you can define properties and actions.",
"version": "0.0.6",
"version": "0.0.7",
"main": "dist/proxy-states.umd.js",
"browser": "dist/proxy-states.umd.js",
"browserExport": "ProxyStates",
Expand Down
10 changes: 7 additions & 3 deletions src/listener.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
const listener = () => {
const m = {

}
const m = {}

const has = (event) => !!m[event]

const add = (event, fn) => {
if (Array.isArray(event)) {
event.forEach(e => {
add(e, fn)
})
return
}
m[event] = m[event] || []
if (m[event].indexOf(fn) >= 0) return

Expand Down
12 changes: 9 additions & 3 deletions src/listener.test.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import listener from './listener'

test('can add an event', () => {
test('can add a listener on a state', () => {
const p = listener()
p.add('m', () => {})
expect(p.has('m')).toBe(true)
})

test('can invoke an event', () => {
test('can invoke a listener upon a state change', () => {
const fn = jest.fn()
const p = listener()
p.add('m', () => { fn() })
Expand All @@ -16,7 +16,7 @@ test('can invoke an event', () => {
expect(fn.mock.calls.length).toBe(1)
})

test('can invoke multiple events', () => {
test('can invoke all listenersupon a state change', () => {
const fn = jest.fn()
const p = listener()
p.add('m', () => { fn() })
Expand All @@ -27,3 +27,9 @@ test('can invoke multiple events', () => {
expect(fn.mock.calls.length).toBe(2)
})

test('can add a listener on a set of states', () => {
const p = listener()
p.add(['m', 'n'], () => { })
expect(p.has('m')).toBe(true)
})

2 changes: 1 addition & 1 deletion src/proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const handler = (ops, events) => ({
obj[prop] = value
}
ops.afterSet && ops.afterSet(obj, prop, value, prev)
events.has(prop) && events.invoke(prop, value, prev)
events.has(prop) && events.invoke(prop, value, prev, prop)

return true
}
Expand Down
11 changes: 11 additions & 0 deletions src/proxy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,15 @@ test('can invoke on event', () => {
expect(fn.mock.calls.length).toBe(1)
expect(fn.mock.calls[0][0]).toBe(2)
expect(fn.mock.calls[0][1]).toBe(1)
})

test('can invoke on event array', () => {
const fn = jest.fn()
const p = proxy({ a: 1 })
p.on(['b', 'a'], (v, prev, prop) => { fn(v, prev, prop) })
p.a++
expect(fn.mock.calls.length).toBe(1)
expect(fn.mock.calls[0][0]).toBe(2)
expect(fn.mock.calls[0][1]).toBe(1)
expect(fn.mock.calls[0][2]).toBe('a')
})

0 comments on commit edcfa21

Please sign in to comment.