-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit + basic implementation w/ async
- Loading branch information
0 parents
commit 42eb617
Showing
10 changed files
with
2,481 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"presets": [ | ||
[ | ||
"env", | ||
{ | ||
"loose": true, | ||
"target": { | ||
"node": "current" | ||
} | ||
} | ||
] | ||
], | ||
"plugins": [ | ||
"transform-runtime", | ||
"transform-object-rest-spread", | ||
"transform-class-properties" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module.exports = { | ||
env: { | ||
browser: true, | ||
es6: true, | ||
node: true, | ||
}, | ||
extends: ['eslint:recommended'], | ||
parser: 'babel-eslint', | ||
parserOptions: { | ||
sourceType: 'module', | ||
}, | ||
plugins: ['prettier'], | ||
rules: { | ||
'prettier/prettier': [ | ||
'error', | ||
{ | ||
singleQuote: true, | ||
semi: true, | ||
trailingComma: 'all', | ||
bracketSpacing: true, | ||
jsxBracketSameLine: false, | ||
parser: 'babylon', | ||
}, | ||
], | ||
'no-console': 0, | ||
indent: ['error', 2], | ||
'linebreak-style': ['error', 'unix'], | ||
quotes: ['error', 'single', { avoidEscape: true }], | ||
semi: ['error', 'always'], | ||
'require-yield': 0, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
dist | ||
*.log | ||
tmp/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "algebraic-effects-experiments", | ||
"version": "1.0.0", | ||
"main": "dist/index.js", | ||
"repository": "[email protected]:elierotenberg/algebraic-effects-experiments", | ||
"author": "Elie Rotenberg <[email protected]>", | ||
"license": "UNLICENSED", | ||
"scripts": { | ||
"make:lint": "eslint src/**/*.js", | ||
"make:clean": "rimraf dist", | ||
"make:build": "yarn run clean && mkdir dist && cp -r src/* dist && babel src -d dist --source-maps", | ||
"make": "yarn run make:build" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.24.1", | ||
"babel-core": "^6.25.0", | ||
"babel-eslint": "^7.2.3", | ||
"babel-plugin-transform-object-rest-spread": "^6.23.0", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-preset-env": "^1.6.0", | ||
"babel-preset-latest": "^6.24.1", | ||
"babel-register": "^6.24.1", | ||
"babel-runtime": "^6.25.0", | ||
"eslint": "^4.4.0", | ||
"eslint-plugin-prettier": "^2.1.2", | ||
"prettier": "^1.5.3", | ||
"rimraf": "^2.6.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
class CallEffect { | ||
constructor(handlerName, args) { | ||
this.handlerName = handlerName; | ||
this.args = args; | ||
} | ||
} | ||
|
||
export default CallEffect; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import CallEffect from './CallEffect'; | ||
import ForkEffect from './ForkEffect'; | ||
|
||
const noop = () => void 0; | ||
|
||
class Context { | ||
static current = new Context({}, '<root>'); | ||
|
||
static switch(nextContext) { | ||
const prevContext = this.current; | ||
this.current = nextContext; | ||
return () => this.switch(prevContext); | ||
} | ||
|
||
constructor(handlers, name = '<anonymous>') { | ||
this.handlers = handlers; | ||
this.name = name; | ||
} | ||
|
||
perform(genFn) { | ||
return (fn = noop) => this.step(genFn(), null, void 0, fn); | ||
} | ||
|
||
step(gen, err, val, fn) { | ||
const method = err ? 'throw' : 'next'; | ||
const restoreContext = Context.switch(this); | ||
let g; | ||
try { | ||
g = gen[method](err || val); | ||
} catch (err) { | ||
fn(err); | ||
return; | ||
} finally { | ||
restoreContext(); | ||
} | ||
const { value, done } = g; | ||
if (done) { | ||
fn(null, value); | ||
return; | ||
} | ||
if (value instanceof CallEffect) { | ||
const { handlerName, args } = value; | ||
const handler = this.handlers[handlerName]; | ||
const resume = nextVal => this.step(gen, null, nextVal, fn); | ||
const interrupt = nextErr => this.step(gen, nextErr, null, fn); | ||
handler(...args)(resume, interrupt); | ||
return; | ||
} | ||
if (value instanceof ForkEffect) { | ||
const { handlers, name, genFn } = value; | ||
const forkContext = this.fork(handlers, name); | ||
forkContext.perform(genFn)((nextErr, nextVal) => | ||
this.step(gen, nextErr, nextVal, fn), | ||
); | ||
return; | ||
} | ||
fn( | ||
new TypeError( | ||
"Only CallEffects can be yielded (created using 'use(handlerName)')", | ||
), | ||
); | ||
} | ||
|
||
fork(handlers, name) { | ||
return new Context({ ...this.handlers, ...handlers }, name); | ||
} | ||
} | ||
|
||
export default Context; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
class ForkEffect { | ||
constructor(handlers, name, genFn) { | ||
this.handlers = handlers; | ||
this.name = name; | ||
this.genFn = genFn; | ||
} | ||
} | ||
|
||
export default ForkEffect; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { using, use, fork } from './lib'; | ||
|
||
const read = use('read'); | ||
const write = use('write'); | ||
const sleep = use('sleep'); | ||
const print = use('print'); | ||
|
||
function* writeValues() { | ||
yield sleep(1000); | ||
yield write('foo', 'bar'); | ||
yield sleep(1000); | ||
yield write('fizz', 'buzz'); | ||
} | ||
|
||
function* readValues() { | ||
return [yield read('foo'), yield read('fizz')]; | ||
} | ||
|
||
const store = {}; | ||
|
||
using({ | ||
print: (...args) => resume => { | ||
console.log(...args); | ||
resume(...args); | ||
}, | ||
sleep: ms => resume => setTimeout(resume, ms), | ||
}).perform(function*() { | ||
yield print('outer context'); | ||
return yield fork({ | ||
read: key => resume => { | ||
const value = store[key]; | ||
resume(value); | ||
}, | ||
write: (key, value) => resume => { | ||
store[key] = value; | ||
resume(value); | ||
}, | ||
})(function*() { | ||
yield print('inner context'); | ||
yield* writeValues(); | ||
const [foo, bar] = yield* readValues(); | ||
return yield print([foo, bar].join(', ')); | ||
}); | ||
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import CallEffect from './CallEffect'; | ||
import ForkEffect from './ForkEffect'; | ||
import Context from './Context'; | ||
|
||
const use = handlerName => (...args) => new CallEffect(handlerName, args); | ||
|
||
const using = (handlers, name) => Context.current.fork(handlers, name); | ||
|
||
const fork = (handlers, name) => genFn => new ForkEffect(handlers, name, genFn); | ||
|
||
export { use, using, fork }; |
Oops, something went wrong.