# pull-stream-model

> A state machine with pull stream interface

Latest version **0.6.3** (published 2023-10-27) · ISC license · 0 weekly downloads

## Install

```sh
npm install pull-stream-model
pnpm add pull-stream-model
yarn add pull-stream-model
bun add pull-stream-model
```

## 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.3 |
| Published | 2023-10-27 |
| First published | 2017-02-11 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 5 |
| Unpacked size | 14.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 5 |
| Author | nichoth |
| Maintainers | nichoth |
| Keywords | pull, stream, pull-stream, model, store |

## Links

- npm: https://www.npmjs.com/package/pull-stream-model
- Repository: https://github.com/nichoth/pull-stream-model
- Homepage: https://github.com/nichoth/pull-stream-model#readme
- Issues: https://github.com/nichoth/pull-stream-model/issues
- npm.io page: https://npm.io/package/pull-stream-model

## Dependencies (5)

- [xtend](https://npm.io/package/xtend.md) ^4.0.1
- [pull-cat](https://npm.io/package/pull-cat.md) ^1.1.11
- [pull-scan](https://npm.io/package/pull-scan.md) ^1.0.0
- [pull-stream](https://npm.io/package/pull-stream.md) ^3.5.0
- [pull-flat-merge](https://npm.io/package/pull-flat-merge.md) ^2.0.3

## Alternatives

- [byte-size](https://npm.io/package/byte-size.md) — 2.1M weekly downloads
- [speed-limiter](https://npm.io/package/speed-limiter.md) — 16.0K weekly downloads
- [@powersync/node](https://npm.io/package/@powersync/node.md) — 10.9K weekly downloads
- [@ledgerhq/coin-cardano](https://npm.io/package/@ledgerhq/coin-cardano.md) — 1.0K weekly downloads
- [@jayesol/jayeson.lib.streamfinder](https://npm.io/package/@jayesol/jayeson.lib.streamfinder.md) — 1.0K weekly downloads

## Recent versions

- 0.6.3 (latest) — 2023-10-27
- 0.6.2 — 2018-09-04
- 0.6.1 — 2017-04-03
- 0.6.0 — 2017-03-31
- 0.5.6 — 2017-03-05
- 0.5.5 — 2017-03-05
- 0.5.4 — 2017-03-03
- 0.5.3 — 2017-03-03
- 0.5.2 — 2017-03-01
- 0.5.1 — 2017-02-27
- 0.5.0 — 2017-02-25
- 0.4.1 — 2017-02-23
- 0.4.0 — 2017-02-23
- 0.3.0 — 2017-02-23
- 0.2.0 — 2017-02-23
- … 1 more at https://npm.io/package/pull-stream-model/versions

## README

# pull stream model

Trying ways to model application state

This creates a state machine from an object where the keys describe event types. An `update` object is used to create a scan function that handles changing the app state in response to events. It looks like this.

```js
var update = {
    bar: function (state, ev) {
        return state + ev
    },
    start: (state, ev) => state + ' resolving',
    resolve: (state, ev) => state.replace(' resolving', '')
}
```

Effects is an object used to filter and map events. Since mapping can be asynchronous, this is where you would put any IO, like network requests. 

```js
var effects = {
    foo: function (state, msg, ev) {
        return msg.bar(ev + '!!!')
    },
    asyncThing: function (state, msg, ev) {
        // async actions still have a return value -- a new pull stream
        // this gets `join`ed into the main event stream
        return cat([
            S.once(msg.start()),
            async(function (cb) {
                setTimeout(function () {
                    cb(null, msg.resolve())
                }, 100)
            })
        ])
    },
    baz: function (state, msg, ev) {
        // you can filter by returning an empty stream
        return S.empty()
    }
}
```

These functions get called with a `msg` argument, which is an object that returns "messages". The messages are just arrays, which means they can be easily serialized. 

The functions in `update` or `effects` can be nested to any depth, too, and it will be called with the corresponding sub-tree of state.

## example

### model

```js
var test = require('tape')
var async = require('pull-async')
var cat = require('pull-cat')
var S = require('pull-stream')
var Component = require('../')
var pushable = require('pull-pushable')

function Model () {
    return ''
}
Model.update = {
    bar: function (state, ev) {
        return state + ev
    },
    start: (state, ev) => state + ' resolving',
    resolve: (state, ev) => state.replace(' resolving', '')
}
Model.effects = {
    foo: function (state, msg, ev) {
        return msg.bar(ev + '!!!')
    },
    asyncThing: function (state, msg, ev) {
        return cat([
            S.once(msg.start()),
            async(function (cb) {
                setTimeout(function () {
                    cb(null, msg.resolve())
                }, 100)
            })
        ])
    }
}


test('model', function (t) {
    t.plan(2)
    var model = Component(Model)
    var p = pushable()
    p.push(model.msg.foo('hello'))
    p.push(model.msg.bar(' hi'))
    p.push(model.msg.asyncThing())
    p.end()

    S(
        p,
        // S.through(console.log.bind(console, 'ev')),
        model.effects(),
        model.store,
        S.collect(function (err, res) {
            t.error(err)
            t.deepEqual(res, [
                '',
                'hello!!!',
                'hello!!! hi',
                'hello!!! hi resolving',
                'hello!!! hi'
            ], 'should do the thing')
        })
    )
})
```

### should update

This is for filtering events when you need to know the current and also the last state. It is used in the same role as react's `shouldComponentUpdate`.

```js
var shouldUpdate = require('pull-stream-model/should-update')

S(
    S.values([1,2,3]),
    // if this is the first event, then `prev` is null
    shouldUpdate(function (prev, next) {
        return prev + next === 3
    }),
    S.collect(function (err, res) {
        t.error(err)
        t.deepEqual(res, [2], 'should filter the stream')
    })
)
```

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