@thi.ng/rstream
Advanced tools
Comparing version 0.8.0 to 0.8.1
@@ -6,2 +6,13 @@ # Change Log | ||
<a name="0.8.1"></a> | ||
## [0.8.1](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@0.8.0...@thi.ng/rstream@0.8.1) (2018-01-31) | ||
### Bug Fixes | ||
* **rstream:** subscription unhandled error handling ([54cd526](https://github.com/thi-ng/umbrella/commit/54cd526)) | ||
<a name="0.8.0"></a> | ||
@@ -8,0 +19,0 @@ # [0.8.0](https://github.com/thi-ng/umbrella/compare/@thi.ng/rstream@0.7.6...@thi.ng/rstream@0.8.0) (2018-01-31) |
{ | ||
"name": "@thi.ng/rstream", | ||
"version": "0.8.0", | ||
"version": "0.8.1", | ||
"description": "Reactive multi-tap streams & transformation pipeline constructs", | ||
@@ -5,0 +5,0 @@ "main": "./index.js", |
@@ -93,2 +93,64 @@ # @thi.ng/rstream | ||
### Central app state atom with reactive undo / redo | ||
```typescript | ||
import * as atom from "@thi.ng/atom"; | ||
import * as tx from "@thi.ng/transducers"; | ||
// central app state / single source of truth | ||
const app = new atom.Atom({ui: {theme: "dark", mode: false}, foo: "bar"}); | ||
// define some cursors for different UI params | ||
const theme = new atom.Cursor(app, "ui.theme"); | ||
const mode = new atom.Cursor(app, "ui.mode"); | ||
// create streams of cursor value changes | ||
rs.fromAtom(theme).subscribe(rs.trace("theme:")); | ||
// with transducer | ||
rs.fromAtom(mode).subscribe(rs.trace("mode:"), tx.map(mode => mode ? "advanced" : "basic")); | ||
// another one for an hitherto unknown value in app state | ||
rs.fromAtom(new atom.Cursor(app, "session.user")).subscribe(rs.trace("user:")); | ||
// attach history only to `ui` branch | ||
// undo/redo will not record/change other keys in the atom | ||
const hist = new atom.History(new atom.Cursor(app, "ui")); | ||
hist.record(); // record current snapshot | ||
theme.reset("light"); | ||
// theme: light | ||
hist.record(); | ||
mode.swap(mode => !mode); // toggle mode | ||
// mode: advanced | ||
hist.undo(); // 1st | ||
// mode: basic | ||
// { theme: 'light', mode: false } | ||
hist.undo(); // 2nd | ||
// theme: dark | ||
// { theme: 'dark', mode: false } | ||
hist.redo(); // 1st | ||
// theme: light | ||
// { theme: 'light', mode: false } | ||
// update another part of the app state (SPREAD, DON'T MUTATE!) | ||
app.swap((state) => ({...state, session: {user: "asterix"}})); | ||
// user: asterix | ||
// { ui: { theme: 'light', mode: false }, | ||
// foo: 'bar', | ||
// session: { user: 'asterix' } } | ||
hist.redo(); // redo 2nd time | ||
// mode: advanced | ||
// { theme: 'light', mode: true } | ||
// verify history redo did not destroy other keys | ||
app.deref(); | ||
// { ui: { theme: 'light', mode: true }, | ||
// foo: 'bar', | ||
// session: { user: 'asterix' } } | ||
``` | ||
TODO more to come... see tests for now! | ||
@@ -95,0 +157,0 @@ |
@@ -121,8 +121,12 @@ "use strict"; | ||
this.state = api_1.State.ERROR; | ||
let notified = false; | ||
if (this.subs && this.subs.length) { | ||
for (let s of [...this.subs]) { | ||
s.error && s.error(e); | ||
if (s.error) { | ||
s.error(e); | ||
notified = true; | ||
} | ||
} | ||
} | ||
else { | ||
if (!notified) { | ||
console.log(this.id, "unhandled error:", e); | ||
@@ -129,0 +133,0 @@ if (this.parent) { |
55731
1096
164