# koax

> Control flow inspired by koa and redux and in pursuit of free monads.

Latest version **0.6.4** (published 2016-03-05) · MIT license · 0 weekly downloads

## Install

```sh
npm install koax
pnpm add koax
yarn add koax
bun add koax
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.6.4 |
| Published | 2016-03-05 |
| First published | 2016-02-02 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 12 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | koax |

## Links

- npm: https://www.npmjs.com/package/koax
- Repository: https://github.com/koaxjs/koax
- Homepage: https://github.com/koaxjs/koax#readme
- Issues: https://github.com/koaxjs/koax/issues
- npm.io page: https://npm.io/package/koax

## Dependencies (12)

- [@koax/run](https://npm.io/package/@koax/run.md) ^0.3.0
- [@f/compose](https://npm.io/package/@f/compose.md) ^1.0.1
- [@koax/boot](https://npm.io/package/@koax/boot.md) ^1.0.0
- [@koax/fork](https://npm.io/package/@koax/fork.md) ^0.3.1
- [@f/identity](https://npm.io/package/@f/identity.md) ^1.1.1
- [@koax/thunk](https://npm.io/package/@koax/thunk.md) ^1.0.1
- [@f/is-object](https://npm.io/package/@f/is-object.md) ^1.1.4
- [@koax/timing](https://npm.io/package/@koax/timing.md) ^0.1.2
- [@f/middleware](https://npm.io/package/@f/middleware.md) ^1.1.0
- [@koax/compose](https://npm.io/package/@koax/compose.md) ^0.3.1
- [@koax/promise](https://npm.io/package/@koax/promise.md) ^1.0.0
- [@koax/channels](https://npm.io/package/@koax/channels.md) ^0.1.2

## Recent versions

- 0.6.4 (latest) — 2016-03-05
- 0.6.3 — 2016-03-04
- 0.6.2 — 2016-03-04
- 0.6.0 — 2016-03-04
- 0.5.2 — 2016-02-26
- 0.5.1 — 2016-02-26
- 0.5.0 — 2016-02-26
- 0.4.2 — 2016-02-13
- 0.4.1 — 2016-02-13
- 0.4.0 — 2016-02-12
- 0.3.2 — 2016-02-12
- 0.3.1 — 2016-02-06
- 0.3.0 — 2016-02-03
- 0.2.0 — 2016-02-03
- 0.1.2 — 2016-02-02
- … 1 more at https://npm.io/package/koax/versions

## README

# koax

[![Build status][travis-image]][travis-url]
[![Git tag][git-image]][git-url]
[![NPM version][npm-image]][npm-url]
[![Code style][standard-image]][standard-url]

Build apps by decoupling effects from application logic. Inspired by co, koa, redux and cycle.

The basic idea is that your `main` can `yield` effects to your interperter stack.

The basic building block of a koax app is a `koax`. A `koax` is a generator that processes an action and is composed of `koax` middleware.

At the outer most level, koax apps should basically have the same form.

```js
import {run} from 'koax'
import effects from './effects'
import main from './app'

let dispatch = run(effects, main)
```

Effects and main are composed of koax middleware.

```js
import koax from 'koax'
import {fetchEffect} from '@koax/fetch'
import {awsEffect} from '@koax/aws'

let effects = koax()
  .use(fetchEffect())
  .use(awsEffect())
  ...
```

Koax middleware looks like koa middleware, with three params: `action`, `next`, and `ctx`.

```js
function (action, next, ctx) {
  if (action.type === FETCH) {
    return fetch(action.payoad.ur, action.payload.params)
  }
  return next()
}
```

Effects will be added to the interpreter stack, which includes default control flow middlware:

- [promise](//github.com/koaxjs/promise) - promise yielding
- [thunk](//github.com/koaxjs/thunk) - thunk yielding
- [timing](//github.com/koaxjs/timing) - delay
- [fork](//github.com/koaxjs/fork) - async execution

The action creators for these middleware are exposed by koax. They include: `fork`, `delay`, `join`, and `cancel`.

Now we can create our main and process it using the interpreter.

```js
function * main (evt) {
  if (evt.type === REQUEST && evt.method ==== 'get') {
    return yield aws('DynamoDB', 'getItem', {Key: evt.payload, TableName: 'Stuff')
  } else if (evt.type === REQUEST && evt.method ==== 'set') {
    return yield aws('DynamoDB', 'setItem', {Item: evt.payload, TableName: 'Stuff'})
  }
}
```

Putting it all together (again)...

```js

let dispatch = run(effects, main)
dispatch({type: REQUEST, method: 'get'}).then(res => res) // results
```

## Installation

    $ npm install koax

## Router

A router example.

app.js
```js
import koax, {run} from 'koax'
import {route, request} from '@koax/route'
import {fetchEffect} from '@koax/fetch'
import {awsEffect, aws} from '@koax/aws'
import {get} from '@koax/fetch-json'


let effects = koax()
  .use(fetchEffect())
  .use(awsEffect())

let main = koax()
  .use(route('/pets.get', getPets))
  .use(route('/pets.add', addPet))

module.exports = run(effects, main)

function * getPets ({params}) {
  return yield aws('DynamoDB', 'getItem', {Key: {owner: params.owner}, TableName: 'Pets'})
}

function * addPet({param}) {
  yield aws('DynamoDB', 'updateItem', {})
}

```

For an http server, we could do:

server.js
```js
import app from './app'
import koa from 'koa'
import {request} from '@koax/route'

let server = koa()
server.use(function * () {
  this.body = yield app(request(this.request.url, this.request.params, this.request.headers))
})
```

Or a lambda would look like:

index.js
```js
import L from 'apex.js'
import 'babel-polyfill'
import app from './app'

exports.handler = L(e => app(request(e.url, e.params. e.headers)))

```

## API

### koax() (default)

**Returns:** a koax middleware stack

### .use(middleware)

- `middleware` - add middleware to koax app

**Returns:** koax app

### run(effects, main, ctx)

- `effects` - effects processing stack
- `main` - main function or generator, signature: `main(action)`
- `ctx` - ctx to pass to effects and main middleware

**Returns:** a function that interprets data passed to it. data can be an action or a koax app.

## Concepts

### middleware(action, next, ctx)

- `action` - an action that middleware can process (preferably treat as immutable)
- `next` - a function that passes execution to next middleware (can `yield` or `return`)
- `ctx` - global shared context for all middleware

**Returns:** whatever your heart desires or `next()` to defer to the next middleware

```js

function * middleware (action, next, ctx) {
  // return a simple value
  if (action.type === 'FOO') return 'bar'
  // dispatch FETCH and return its result
  if (action.type === 'QUX') return yield {type: 'FETCH', payload: 'google'}
  // pass execution to next middleware
  return next()
}
```

### next()

`next` is simply a function that calls the next middleware with `action` and `next` already bound. Since koax handles generators that are yielded or returned, each middleware can be either a function or generator and they will work as expected.

### yield

`yield` dispatches actions to the interpreter. The interpreter is composed of the default control flow middleware and the effects stack.

## License

MIT

[travis-image]: https://img.shields.io/travis/koaxjs/koax.svg?style=flat-square
[travis-url]: https://travis-ci.org/koaxjs/koax
[git-image]: https://img.shields.io/github/tag/koaxjs/koax.svg
[git-url]: https://github.com/koaxjs/koax
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat
[standard-url]: https://github.com/feross/standard
[npm-image]: https://img.shields.io/npm/v/koax.svg?style=flat-square
[npm-url]: https://npmjs.org/package/koax

---
_Source: https://npm.io/package/koax · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
