Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

flume-js

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flume-js - npm Package Compare versions

Comparing version 0.1.1 to 0.1.3

src/bindInputs.js

4

package.json
{
"name": "flume-js",
"version": "0.1.1",
"version": "0.1.3",
"description": "define event-prone applications as a tree of functions",

@@ -33,3 +33,3 @@ "license": "MIT",

"dependencies": {
"flume-core": "~0.1.1"
"flume-core": "~0.1.3"
},

@@ -36,0 +36,0 @@ "devDependencies": {

@@ -7,2 +7,4 @@ # flume-js

**note** flume is more of an experiment at this point, don't use in it production and expect the api to change drastically. The current documentation also leaves much to be desired. If this experiment sees some success, better documentation on what flume is and how it can be used can be expected.
```js

@@ -30,6 +32,2 @@ import {create, input, map, reduce} from 'flume-js';

```
Sorry about the lack of documentation, I know its really not great. Will add this as soon as I can.
```
## install

@@ -52,1 +50,192 @@

```
## overview
### what is flume?
flume is an attempt at a library for defining your applications as a set of inputs and transformations of those inputs.
To some limited degree, it is along the same lines as [Observables](https://github.com/tc39/proposal-observable) and libraries like [rxjs](https://github.com/ReactiveX/rxjs) and [xstream](http://staltz.com/xstream/).
### api overview
Applications can be thought of as pipelines. In the simplest case, we can have a single input at the top, followed by transform functions:
```js
const src = input();
const app = create([
src,
map(v => v * 2),
map(v => v + 1),
map(console.log)
]);
app
.dispatch(src, 2) // 5
.dispatch(src, 3) // 7
```
We can also have multiple inputs at the top:
```js
const src1 = input();
const src2 = input();
const app = create([
[src1, src2],
map(v => v * 2),
map(v => v + 1),
map(console.log)
]);
app
.dispatch(src1, 2) // 5
.dispatch(src2, 3) // 7
```
Applications can also be defined as pipelines of pipelines:
```js
import {create, input, map, reduce} from 'flume-js';
const src1 = input();
const src2 = input();
const app = create([
[[src1, map(v => v * 2)], [src2, map(v => v * 3)]],
reduce(() => 1, (total, v) => total + v),
map(console.log)
])
app
.dispatch(src1, 1) // 3
.dispatch(src2, 2) // 9
.dispatch(src1, 3); // 15
```
**note** The examples above use array literals to define the application. While this helps for demonstration purposes, the indended convention for defining applications is to use [`Array.prototype.concat()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/concat). This allows us to define applications using a chainable api without flume needing to create some wrapper api to achieve the same result. More importantly though, since `Array.prototype.concat` accepts arrays of values, this also gives us a pattern for appending multiple transforms. For example:
```js
const flatMap = fn => []
.concat(flatten())
.concat(map(fn));
const src = input();
const graph = [input]
.concat(flatMap(v => v * 2))
.concat(map(console.log));
create(graph)
.dispatch(src, 2)
// 4
.dispatch(src, [3, 4])
// 6
// 8
```
### value propagation
### error propagation
### main design goals
- constrain applications to statically defined graph of inputs and transforms
- support defining of message types (e.g. values, errors, types of side effects, custom)
- transforms return results instead of pushing them through in an imperitive manner
- support promise-returning functions, but don't mandate promise support for apps that don't need it
## api
### graph creation
#### `create(graphDef)`
Returns a built graph from the given graph definition.
Graphs are defined as arrays. The first element of the array may be an [`input`](#input), a graph definition, or an array of either of these. All following array elements may only be a [transform](#transforms) (see [transform definitions](#transform-definitions) for a lower-level api for defining these).
```js
const src = input();
const app = [src]
.concat(map(console.log));
create(app)
.dispatch(src, 23); // 23
```
#### `graph.dispatch(src, value)`
#### `input()`
#### `except(fn)`
### transforms
#### `map(fn)`
#### `filter([fn])`
#### `strsplit(sep)`
#### `sink(initFn, processFn)`
### lower level api
#### transform definitions
In the simplest case, a transform can be defined as a function. A transform function takes in the transform's current `state`, the `value` to be transformed, and an `opts` object. It should return an object containing with the folling properties:
- `state`: the transform's new state. If omitted, the node's current state is assumed.
- `value` / `values`: the result value to propagated to the next transform in the chain. If specified using the property name `values`, the property is taken as an [array of result values](#propagating-multiple-values) to be propagated sequentially.
```js
const src = input();
const graph = [src]
.concat((state, v) => ({
state: (state || 0) + v,
value: (state || 0) + v + 1
})
.concat(map(console.log));
create(graph)
.dispatch(src, 1) // 2
.dispatch(src, 2); // 4
```
If `value`/`values` are omitted but `state` is given, `state` is used as both the transform's new state _and_ the result value to be propagated.
```js
const src = input();
const graph = [src]
.concat((state, v) => ({state: (state || 0) + v}))
.concat(map(console.log));
create(graph)
.dispatch(src, 2) // 2
.dispatch(src, 3); // 5
```
The given `opts` object contains the following properties:
- `source`: the input from which propagation started
- `parent`: the definition of the transform or input from which `value` propagated
- `dispatch`: a reference to [`graph.dispatch()`](#graph-dispatch-src-value).
### propagating multiple values
### short-circuiting propagation with `nil`
#### `message(type, value)`
#### `trap(transformDef)`
### internal utilities
#### `maybeAsync(fn)`
#### `resolveSeq(values)`
#### `conj(...objects)`
import {nil, resolveSeq} from './core';
import identity from './utils/identity';
import resultValue from './utils/resultValue';

@@ -7,4 +8,7 @@

fn = fn || identity;
return function filterFn(_, v, opts) {
return [null, resolveSeq([fn(v, opts), v]).then(test)];
return resolveSeq([fn(v, opts), v])
.then(test)
.then(resultValue);
};

@@ -11,0 +15,0 @@ }

@@ -7,1 +7,2 @@ export * from './core';

export {default as strsplit} from './strsplit';
export {default as bindInputs} from './bindInputs';

@@ -0,5 +1,10 @@

import {maybeAsync} from './core';
import resultValue from './utils/resultValue';
export default function map(fn) {
fn = maybeAsync(fn);
return function mapFn(_, v, opts) {
return [null, fn(v, opts)];
return fn(v, opts).then(resultValue);
};
}

@@ -0,1 +1,5 @@

import {maybeAsync} from './core';
import resultState from './utils/resultState';
export default function reduce(init, reducer) {

@@ -7,14 +11,11 @@ if (arguments.length < 2) {

reducer = parseReducer(reducer);
reducer = maybeAsync(parseReducer(reducer));
return {
init: init,
process: reduceFn
transform: reduceFn
};
function reduceFn(state, v, opts) {
try{
var res = reducer(state, v, opts);
return [res, res];
} catch(e) { console.log(e); }
return reducer(state, v, opts).then(resultState);
}

@@ -32,3 +33,3 @@ }

function caseSourceOfReducer(pairs) {
var defaultFn = identityProcessor;
var defaultFn = identityReducer;

@@ -61,4 +62,4 @@ if (typeof pairs[pairs.length - 1] == 'function') {

function identityProcessor(state, v) {
function identityReducer(state, v) {
return v;
}

@@ -0,10 +1,16 @@

import {maybeAsync} from './core';
import resultValue from './utils/resultValue';
export default function sink(init, fn) {
fn = maybeAsync(fn);
return {
init: init,
process: sinkFn
transform: sinkFn
};
function sinkFn(state, v, opts) {
return [state, fn(state, v, opts)];
return fn(state, v, opts).then(resultValue);
}
}

@@ -7,5 +7,8 @@ function init() {

function strsplit(sep) {
function process(data, chunk) {
function transform(data, chunk) {
var lines = (data + chunk).split(sep);
return [lines.slice(-1), lines.slice(0, -1)];
return {
state: lines.slice(-1),
values: lines.slice(0, -1)
};
}

@@ -15,3 +18,3 @@

init: init,
process: process
transform: transform
};

@@ -18,0 +21,0 @@ }

import test from 'ava';
import {create, input, filter} from '..';
import {create, input, filter} from '../src';
import {capture, defer} from './utils';

@@ -4,0 +4,0 @@

import test from 'ava';
import {create, input, map} from '..';
import {create, input, map} from '../src';
import {capture} from './utils';

@@ -4,0 +4,0 @@

import test from 'ava';
import {create, input, reduce} from '..';
import {create, input, reduce} from '../src';
import {capture, defer} from './utils';

@@ -4,0 +4,0 @@

import test from 'ava';
import {create, input, sink} from '..';
import {create, input, sink} from '../src';
import {capture, defer} from './utils';

@@ -4,0 +4,0 @@

import test from 'ava';
import {create, input, strsplit} from '..';
import {create, input, strsplit} from '../src';
import {capture} from './utils';

@@ -4,0 +4,0 @@

function capture(arr) {
return (_, v) => arr.push(v);
return (_, v) => {
arr.push(v);
return {value: null};
};
}

@@ -4,0 +7,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc