open-index/open-npm huggingface dataset:
npm package: @ishiduca/routing
Description: The underlying router for implementing your own router.
Author: ishiduca@gmail.com
Latest version: 0.0.2

# @ishiduca/routing

The underlying router for implementing your own router.

- its goal is only to `define` and `match` URLs.
- its does not handle methods, heaeders, controllers, views, etc., in anyway.


```js
const routing = require('@ishiduca/routing')
const router = routing()

const dashboard = {dashboard: true}
router.define('/dashboard(/:x/(:x))', dashboard)

const node = router.match('/dashboard/xyz/abc')
assert.deepEqual(node.values, [{dashboard: true}])
assert.deepEqual(node.params, {x: ['xyz', 'abc']})
```

## api

### const node = router.define(route[, ...args])

```js
const node = router.define('/user(/:user_id/(profile))/(page)', 1, 2, -1)
// {
//   values: [1, 2, -1]
// }
```

- `node` is a package that stored the defined route pattern and optional data.
- `route` is a definition of a route. this type is `string`.
- `...args` are optional datas. stored as an array in `node.values`.


### const matched = router.match(uriStr)

```js
router.define('/user(/:user_id/(profile))/(page)', 'GET', (req, res) => {...})
const matched = router.match('/user/Tony/profile')
// {
//   values: ['GET', (req, res) => {...}],
//   params: {user_id: 'Tony'}
// }

const unMatched = router.match('/product')
// unMatched === null
```

- `matched` if `uriStr` is matched pattern, then return __object__.
            if `uriStr` is not matched, then return __null__.


## an example of building a Router.

```js
const url = require('url')
const bl = require('bl')
const xtend = require('xtend')

function dispatch (req, res) {
  const u = url.parse(req.url, true)
  const match = router.match(u.pathname)
  if (match == null) return notFound(req, res)

  const methods = match.values[0]
  const hander = methods[req.methed]
  if (handler == null) return methodNotAllow(req, res)

  handler(req, res, match.params, u.query)
}

function post (f) {
  return (req, res, params, query) => {
    req.pipe(bl((err, raw) => {
      var str = String(raw)
      var data; try {
        data = JSON.parse(str)
      } catch (e) {
        ...
      }
      f(req, res, params, query, data)
    })
  }
}
```

```js
router.define('/user/:user_id(/:category)', {
  GET: (req, res, params, query) => {
    ...
  },
  POST: post((req, res, params, query, data) => {
    ...
  })
})
```


## license

The Apache License

Copyright &copy; 2018 ishiduca

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
npm package: @ishiduca/snoopy
Description: `@ishiduca/snoopy` is implementation of `inu` using [mississippi](https://github.com/maxogden/mississippi) instead of [pull-stream](https://github.com/pull-stream/pull-stream).
Author: ishiduca@gmail.com
Latest version: 0.0.2

# @ishiduca/snoopy

`@ishiduca/snoopy` is implementation of `inu` using [mississippi](https://github.com/maxogden/mississippi) instead of [pull-stream](https://github.com/pull-stream/pull-stream).

```js
const yo = require('yo-yo')
const {pipe, through} = require('mississippi')
const {start} = require('@ishiduca/snoopy')

const root = document.body.querySelector('.clock')
const app = {
  init () {
    return {
      model: 0,
      effect: 'SCHEDULE_TICK'
    }
  },
  update (model, action) {
    if (action === 'TICK') {
      return {
        model: (model + 1) % 60,
        effect: 'SCHEDULE_TICK'
      }
    }
    return {model}
  },
  view (model, actionsUp) {
    return yo`
      <div class='clock'>
        Seconds Elapsed: ${model}
      </div>
    `
  },
  run (effect, sources) {
    if (effect === 'SCHEDULE_TICK') {
      let actionSource = through.obj()
      setTimeout(() => actionSource.end('TICK'), 1000)
      return actionSource
    }
  }
}

const {views} = start(app)
pipe(
  views(),
  through.obj((view, _, done) => {
    yo.update(div, view)
    done()
  }),
  err => {
    err ? console.error(err) : console.log('Finished app')
  }
)
```


## see also

-[inu](https://github.com/ahdinosaur/inu): `@ishiduca/snoopy` is implementation of `inu` using [mississippi](https://github.com/maxogden/mississippi) instead of [pull-stream](https://github.com/pull-stream/pull-stream).
-[mississippi](https://github.com/maxogden/mississippi)
## license

The Apache License

Copyright &copy; 2018 ishiduca.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
npm package: @ishiduca/snoopy-batch-actions
Description: apply batched actions in app on "@ishiduca/snoopy"
Author: ishidua@gmail.com
Latest version: 0.0.2

# snoopy-batch-actions

apply batch actions in [ '@ishiduca/snoopy' ](https://github.com/ishiduca/snoopy)

## install

```shell
npm i --save @ishiduca/snoopy-batch-actions
```

## usage

### applyBatchActionsApp = batch(app)

### example

```js
const yo = require('yo-yo')
const xtend = require('xtend')
const { start } = require('@ishiduca/snoopy')
const batch = require('@ishiduca/snoopy-batch-actions')
const app = batch({
  init () {
    return {
      model: {
        number: 0,
        string: '0'
      }
    }
  },
  update (_model, action) {
    const model = xtend(_model)
    if (action === 'stringAddOne') {
      model.string = _model.string + '1'
      return { model }
    }
    if (action === 'numberAddOne') {
      model.number = _model.number + 1
      return { model }
    }
    return { model }
  },
  view (model, actionsUp) {
    yo`
      <main>
        <section>
          <a onclick=${e => actionsUp('stringAddOne')}>string add one</a>
          <a onclick=${e => actionsUp('numberAddOne')}>number add one</a>
          <a onclick=${e => actionsUp([ 'stringAddOne', 'numberAddOne' ])}>batch</a>
        </section>
        <section class="result">
          <ol>
            <li>string: ${model.string} </li>
            <li>number: ${model.number} </li>
          </ol>
        </section>
      </main>
    `
  }
})

const root = document.querySelector('main')
const { views } = start(app)
views().pipe(through.obj((el, _, done) => {
  yo.update(root, el)
  done()
}))
```

## authour

ishiduca@gmail.com

## license

The Apache License

Copyright &copy; 2019 ishiduca

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
npm package: @ishiduca/snoopy-bind-rpc
Description: ## example
Author: ishiduca@gmail.com
Latest version: 0.1.2

# snoopy-bind-rpc

## example

config.json
```json
{
  "prefix": "/rpc/v1.0",
  "port": 9876
}
```

schema.json
```json
{
  "sum": {
    "type": "array",
    "items": {
      "type": "number"
    }
  },
  "average": {
    "type": "array",
    "items": {
      "type": "number"
    }
  }
}
```

api-callback.js
```js
function sum (params, cb) {
  cb(null, params.reduce((a, b) => (a + b), 0))
}

function average (params, cb) {
  sum(params, (error, result) => {
    error
      ? cb(error)
      : cb(null, result / params.length)
  })
}

module.exports = { sum, average }
```

sever.js
```js
const http = require('http')
const api = require('./api-callback')
const schemas = require('./schemas')
const { prefix, port } = require('./config')
const bind = require('@ishiduca/snoopy-bind-rpc')
const rpc = bind(prefix, { api, schemas })
const app = http.createServer(rpc((req, res) => {
  ...
}))
app.listen(port)
```

browser.js
```js
const api = require('./api-callback')
const schemas = require('./schemas')
const { prefix } = require('./config')
const bind = require('@ishiduca/snoopy-bind-rpc')
const rpc = bind(prefix, { api, schemas })
const $input = document.querySelector('#inputNumbers')
const $sum = document.querySelector('#resultSum')
const $average = document.querySelector('#resultAverage')

const set = value => {
  var values = value.split(' ').filter(Boolean).map(Number)

  rpc.sum(values)
    .on('data', sum => ($sum.innerHTML = sum))
    .on('error', error => console.error(error))

  rpc.average(values)
    .on('data', ave => ($average.innerHTML = ave))
    .on('error', error => console.error(error))
}

$input.oninput = e => set(e.target.value)
```
npm package: @ishiduca/snoopy-multi
Description: run multiple effects in @ishiduca/snoopy
Author: ishiduca@gmail.com
Latest version: 0.0.3

# snoopy-multi

run multiple effects in [ '@ishiduca/snoopy' ](https://github.com/ishiduca/snoopy)

## install

```shell
npm i --save @ishiduca/snoopy-multi
```

## usage

### applyMultipleEffectsApp = multi(app)

### example

```js
const yo = require('yo-yo')
const { through, pipe } = require('mississippi')
const { start } = require('@ishiduca/snoopy')
const multi = require('@ishiduca/snoopy-multi')
const app = multi({
  init () {
    return {
      model: 0
    }
  },
  update (model, action) {
    if (action === 'add') {
      return { model: model + 1 }
    }
    if (action === 'tick') {
      return {
        model,
        effect: 'TICK'
      }
    }
    if (action === 'tack') {
      return {
        model,
        effect: 'SCHEDULE_TICK'
      }
    }
    if (action === 'tick tack') {
      return {
        model,
        effect: ['SCHEDULE_TICK', 'TICK']
      }
    }
  },
  view (model, actionsUp) {
    return yo`
      <section>
        <nav>
          <a onclick=${e => actionsUp('tick')}>tick</a>
          <a onclick=${e => actionsUp('tack')}>tack</a>
          <a onclick=${e => actionsUp('tick tack')}>tick tack</a>
        </nav>
        <div class="result">${model}</div>
      </section>
    `
  },
  run (effect, sources) {
    if (effect === 'TICK') {
      let s = through.obj()
      process.nextTick(() => s.end('add'))
      return s
    }
    if (effect === 'SCHEDULE_TICK') {
      let s = through.obj()
      setTimeout(() => s.end('add'), 1000)
      return s
    }
  }
})

const root = document.querySelector('main')
const { views } = start(app)

views().pipe(through.obj((el, _, done) => {
  yo.update(el, root)
  done()
}))
```

### inspiration

- [`ashaffer/redux-multi`](https://github.com/ashaffer/redux-multi)
- [`ahdinosaur/inu-multi`](https://github.com/ahdinosaur/inu-multi)

### authour

ishiduca@gmail.com

## license

The Apache License

Copyright &copy; 2019 ishiduca

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.