Commit 28ed9bebf2904e28107d97a89d40b4e12b753fe3
initial
Dominic Tarr committed on 8/2/2017, 9:06:28 AMFiles changed
LICENSE | added |
README.md | added |
evolve.js | added |
examples/backpressure/state.js | added |
examples/flood/index.js | added |
examples/flood/state.js | added |
examples/fs/index.js | added |
index.js | added |
package.json | added |
LICENSE | ||
---|---|---|
@@ -1,0 +1,22 @@ | ||
1 … | +Copyright (c) 2017 'Dominic Tarr' | |
2 … | + | |
3 … | +Permission is hereby granted, free of charge, | |
4 … | +to any person obtaining a copy of this software and | |
5 … | +associated documentation files (the "Software"), to | |
6 … | +deal in the Software without restriction, including | |
7 … | +without limitation the rights to use, copy, modify, | |
8 … | +merge, publish, distribute, sublicense, and/or sell | |
9 … | +copies of the Software, and to permit persons to whom | |
10 … | +the Software is furnished to do so, | |
11 … | +subject to the following conditions: | |
12 … | + | |
13 … | +The above copyright notice and this permission notice | |
14 … | +shall be included in all copies or substantial portions of the Software. | |
15 … | + | |
16 … | +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
17 … | +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
18 … | +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
19 … | +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR | |
20 … | +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
21 … | +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
22 … | +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
evolve.js | ||
---|---|---|
@@ -1,0 +1,24 @@ | ||
1 … | +function append(ary, ary2) { | |
2 … | + if(!Array.isArray(ary2)) | |
3 … | + ary.push(ary2) | |
4 … | + else | |
5 … | + while(ary2.length) | |
6 … | + ary.push(ary2.shift()) | |
7 … | + return ary | |
8 … | +} | |
9 … | + | |
10 … | +module.exports = function evolve (update, act, state, events) { | |
11 … | + do { | |
12 … | + var next = update(state, events.shift()) | |
13 … | + state = next.state | |
14 … | + if(Array.isArray(next.effects)) { | |
15 … | + while(next.effects.length) | |
16 … | + append(events, act(state, next.effects.shift())||[]) | |
17 … | + } else if(next.effects) | |
18 … | + append(events, act(state, next.effects) || []) | |
19 … | + } | |
20 … | + while(events.length) | |
21 … | + | |
22 … | + return state | |
23 … | +} | |
24 … | + |
examples/backpressure/state.js | ||
---|---|---|
@@ -1,0 +1,24 @@ | ||
1 … | + | |
2 … | +//okay, an infinite stream that stops at 100. | |
3 … | +//like pull.take | |
4 … | + | |
5 … | +function update (state, event) { | |
6 … | + if(state < 100) | |
7 … | + return { | |
8 … | + state: state + 1, | |
9 … | + effects: {type: 'count', value: state+1} | |
10 … | + } | |
11 … | + else | |
12 … | + return { | |
13 … | + state: state, | |
14 … | + effects: {type: 'stdout', value: state} | |
15 … | + } | |
16 … | +} | |
17 … | + | |
18 … | +require('../../')(update, function (state, event) { | |
19 … | + if(event.type === 'stdout') | |
20 … | + console.log(event.value) | |
21 … | + else | |
22 … | + return {type: 'next'} | |
23 … | +}, 0) () | |
24 … | + |
examples/flood/index.js | ||
---|---|---|
@@ -1,0 +1,24 @@ | ||
1 … | +var Universe = require('../../') | |
2 … | + | |
3 … | +//a simple messaging universe | |
4 … | + | |
5 … | +var cause = Universe(require('./state'), function (state, event, cause) { | |
6 … | + //just pipe effects straight back in as events. | |
7 … | + cause(event) | |
8 … | +}, { | |
9 … | + nodes: { | |
10 … | + "alice": {peers:{}, store: {}}, | |
11 … | + "bob": {peers:{}, store: {}}, | |
12 … | + "carol": {peers:{}, store: {}} | |
13 … | + } | |
14 … | +}, []) | |
15 … | + | |
16 … | +cause({type: 'init'}) | |
17 … | +state = cause({type: 'connect', target: 'alice', peer: 'bob'}) | |
18 … | +state = cause({type: 'connect', target: 'carol', peer: 'bob'}) | |
19 … | + | |
20 … | +//send a message to alice | |
21 … | +cause({type: 'data', target: 'alice', value: 'beep'}) | |
22 … | + | |
23 … | +console.log(JSON.stringify(state, null, 2)) | |
24 … | + |
examples/flood/state.js | ||
---|---|---|
@@ -1,0 +1,49 @@ | ||
1 … | + | |
2 … | +function byPeer (update) { | |
3 … | + return function (state, event) { | |
4 … | + if(event.target != null && state.nodes[event.target]) { | |
5 … | + var r = update(state.nodes[event.target], event) | |
6 … | + state.nodes[event.target] = r.state | |
7 … | + r.state = state | |
8 … | + return r | |
9 … | + } | |
10 … | + return {state: state, effects: []} | |
11 … | + } | |
12 … | +} | |
13 … | + | |
14 … | +function peerUpdate (state, event) { | |
15 … | + switch(event.type) { | |
16 … | + case 'connect': | |
17 … | + state.peers = state.peers || {} | |
18 … | + | |
19 … | + if(state.peers[event.peer]) //already connected | |
20 … | + return {state: state} | |
21 … | + | |
22 … | + state.peers[event.peer] = true | |
23 … | + | |
24 … | + return { | |
25 … | + state: state, | |
26 … | + effects: {type: 'connect', target: event.peer, peer: event.target} | |
27 … | + } | |
28 … | + case 'data': | |
29 … | + //if we already have this msg, do nothing | |
30 … | + var hops = event.hops | 0 | |
31 … | + if(state.store[event.value]) | |
32 … | + return {state: state} | |
33 … | + else { //forward to peers | |
34 … | + state.store[event.value] = true | |
35 … | + state.hops = hops | |
36 … | + var effects = [] | |
37 … | + console.log(event, state.peers) | |
38 … | + for(var k in state.peers) | |
39 … | + effects.push({type: 'data', target: k, value:event.value, hops: hops + 1}) | |
40 … | + console.log(effects) | |
41 … | + return {state: state, effects: effects} | |
42 … | + } | |
43 … | + } | |
44 … | + | |
45 … | + return state | |
46 … | +} | |
47 … | + | |
48 … | +module.exports = byPeer(peerUpdate) | |
49 … | + |
examples/fs/index.js | ||
---|---|---|
@@ -1,0 +1,40 @@ | ||
1 … | + | |
2 … | + | |
3 … | +module.exports = function (state, event, cause) { | |
4 … | + | |
5 … | + if(event.type == 'fs.readFile') | |
6 … | + fs.readFile(event.path, function (err, value) { | |
7 … | + cause({ | |
8 … | + type: err ? 'error', | |
9 … | + path: event.path, | |
10 … | + target: event.sender, | |
11 … | + value: value | |
12 … | + }) | |
13 … | + }) | |
14 … | + else if(event.type == 'fs.rename') | |
15 … | + fs.rename(event.path, event.newPath, function (err, value) { | |
16 … | + cause({ | |
17 … | + type: err ? 'error', | |
18 … | + error: err ? err : null, | |
19 … | + path: event.path, | |
20 … | + target: event.sender, | |
21 … | + value: value | |
22 … | + }) | |
23 … | + }) | |
24 … | + else if(event.type == 'fs.unlink') | |
25 … | + fs.unlink(event.path, function (err, value) { | |
26 … | + cause({ | |
27 … | + type: err ? 'error', | |
28 … | + error: err ? err : null, | |
29 … | + path: event.path, | |
30 … | + target: event.sender, | |
31 … | + }) | |
32 … | + }) | |
33 … | +} | |
34 … | + | |
35 … | + | |
36 … | + | |
37 … | + | |
38 … | + | |
39 … | + | |
40 … | + |
index.js | ||
---|---|---|
@@ -1,0 +1,27 @@ | ||
1 … | +var evolve = require('./evolve') | |
2 … | + | |
3 … | +module.exports = function (update, _act, state) { | |
4 … | + var acting = false | |
5 … | + var events = [] | |
6 … | + function cause (ev) { | |
7 … | + events.push(ev) | |
8 … | + if(!acting) run() | |
9 … | + } | |
10 … | + | |
11 … | + function act (state, effect) { | |
12 … | + return _act(state, effect, cause) | |
13 … | + } | |
14 … | + | |
15 … | + function run () { | |
16 … | + acting = true | |
17 … | + state = evolve(update, act, state, events) | |
18 … | + acting = false | |
19 … | + } | |
20 … | + | |
21 … | + return function (ev) { | |
22 … | + cause(ev) | |
23 … | + return state | |
24 … | + } | |
25 … | + | |
26 … | +} | |
27 … | + |
package.json | ||
---|---|---|
@@ -1,0 +1,19 @@ | ||
1 … | +{ | |
2 … | + "name": "fun-actors", | |
3 … | + "description": "", | |
4 … | + "version": "0.0.0", | |
5 … | + "homepage": "https://github.com/dominictarr/fun", | |
6 … | + "repository": { | |
7 … | + "type": "git", | |
8 … | + "url": "git://github.com/dominictarr/fun.git" | |
9 … | + }, | |
10 … | + "dependencies": { | |
11 … | + }, | |
12 … | + "devDependencies": { | |
13 … | + }, | |
14 … | + "scripts": { | |
15 … | + "test": "set -e; for t in test/*.js; do node $t; done" | |
16 … | + }, | |
17 … | + "author": "'Dominic Tarr' <dominic.tarr@gmail.com> (dominictarr.com)", | |
18 … | + "license": "MIT" | |
19 … | +} |
Built with git-ssb-web