midstream
A fully reactive middleware library good for forms or data transforms
Installing
npm install midstream@latest
Usage
Import midstream into your application:
V2 API
// Import midstream // Create some middleware that returns the updated value or throws an error // Validation Example, errors populate both the err and errors return valueconst isOdd = { if v % 2 > 0 return v throw 'value is not odd'} // Data modification middleware exampleconst to2Decimals = // Split on space exampleconst split = v // Asynchronous fetch exampleconst multiplyByRandom = async { let res = await let n = await restext return * } // Initialize a midstream object.const ms = // The midstream object is composed of several parts:// - src - the object with all the pre-middleware processed values// - err - the object containing the first error thrown by each middleware array// - dst - a reference to the destination object or function passed inlet src err dst odd setOdd num setNum str: setStr rnd setRnd run wait = ms // Default values are not processed immediately.// use `await run()` to force a complete refresh of dst data from src data// use `await wait()` to wait until any ongoing async updates are completed // There a few ways to set a value:srcodd = 3// Output: odd: 3 // Output: odd: 3 console// Output: 3 // odd is not updated because destructing assignment doesn't copy getters. console// Output: 1 console// Output: 3 console// Output: 3 // Errors in middleware are stored in errsrcodd = 2 console// Output: value is not odd console// Output: 3 console// Output: 3 // Async callbacks can be awaited if using a setterasync { // a setter can be awaited await // Output: rnd: 40 // this form cannot be awaited because js syntax does not support it srcrnd = 20 // wait has to be called await // Output: rnd: 60 // call run to run all middleware even on default values await // Output: // odd: 3 // num: 1.00 // str: ["foo", "boo"] // rnd: 0} whiletrue
An Example React Component
// import midstream // Some middlewareconst isOddv => if v % 2 > 0 return v throw 'value is not odd' // Simple hook for Midstreamconst useMidstream = { let dst = {} let err = {} // standard force rerender hack let tick setTick = let ms _ = return ms dst err } // Your actual component { const ms dst err = // react call this on every update so odd will be up to date const odd setOdd = ms return <div> <p>Last Odd Number: dstodd </p> <input value=odd onChange= /> errodd ? <small>Error: errodd </small> : null </div>}
Legacy API:
Create a source, destination, and some error throwing middleware. Values set to source will populate destination if all
const defaults = a: 1 b: 2 // can take synchronous or asynchronous functionsconst middleware = // multiple middleware in array a: { if x === 1 return x throw 'a not 1' } // singular middleware c: async { if x === 3 return x await { } }const dst = a: 1 b: 2 c: 3 let src err dst = // set values and wait for asynchronous result, even synchronous middleware completes on the next ticksrca = 4// await src.run('a', 4) to for the awaitable async settersrcb = 0srcc = 5 // optionally await src.run('a', 'optional value overwrite'), src.runAll(), or src.runSettle().// src.test is like run but will not set any destination values even without errorlet ret = await src console// {// a: {reason: new Error('a not 1'), status: 'rejected'},// b: {status: 'fulfilled', value: 0},// c: {reason: new Error('c not 3'), status: 'rejected'},// } console// {// a: new Error('a not 1'),// c: new Error('c not 3'),// } console// {// a: 1,// b: 0,// c: 3,// } console// {// a: 4,// b: 0,// c: 5,// }
Note: test
, run
, runAll
, and runSettle
are all functions.
Running tests
npm installnpm run testnpm run test --watchnpm run test:coverage
Dev mode
When developing you can run:
npm run watch
This will regenerate the build files each time a source file is changed and serve on http://127.0.0.1:5000.
Publishing
npm publish