Ninja Parading Musically

    xain

    1.0.5 • Public • Published

    xain

    Using ES2015 proxies to simplify observation and reaction

    Usage

    Simple observation

    'use strict';
     
    const {observable, observe} = require('xian');
     
    const o = observable({
        foo: 1
    });
    let count = 0;
    const unobserve = observe(o, (prop, newValue, oldValue) => count += 1); // returns a funtion that, when called, stops the observation
    // count == 0
    o.foo = 1;
    // count == 0
    o.foo = 2;
    o.foo = 2;
    // count == 1
    o.foo = 1;
    // count == 2
    unobserve(); // stop the observer
    o.foo = 5;
    o.foo = 6;
    o.foo = 7;
    // count == 2

    Batched observation

    (Use when you make several changes and you want to get the diff, if it exists, between the first and last changes on this tick)

    const o = observable({
        foo: 1
    }, true); // notice the `true` parameter indicating it is batched
    let count = 0;
    observe(o, () => count += 1);
    // count == 0
    o.foo = 0;
    // count == 0
    o.foo = 2;
    o.foo = 2;
    // count == 0
    process.nextTick(() => {
        // count == 1, and oldValue will be 1 and newValue will be 2, skipping the 0 in between
    });

    Reactive links

    const x = require('xian');
     
    const o = x.observable({
        x: 3,
        y: 6
    });
    let counter = 0;
    const r = x.reactive({ // note: every reactive object is also `observable`, and thus can be passed to the `observe` function.
        x: x.pipe(o, 'x'), // pipe changes through
        y: x.pipe(o, 'y'),
        z: x.link(o, ({x, y}) => { // link changes of dependencies into a new value
            counter += 1;
            return x + y;
        })
    });
    t.is(r.x, 3);
    t.is(r.y, 6);
    t.is(r.z, 9);
    t.is(counter, 1);
    o.x = 3;
    t.is(r.x, 3);
    t.is(r.y, 6);
    t.is(r.z, 9);
    t.is(counter, 1);
    o.x = 5;
    t.is(r.x, 5);
    t.is(r.y, 6);
    t.is(r.z, 11);
    t.is(counter, 2);

    Note: a link function must always get every single dependency every time it runs. The easiest way is to destructure the observable (the actual argument passed to the link function) into the properties the link depends upon.

    Observable streams

    const x = require('xain');
     
    const o = x.observable({
        x: 3,
        y: 6
    });
    const str = x.stream(o)
                 .filter(key => key === 'x')
                 .map((key, nval, oval) => oval)
                 .reduce((acc, val) => acc + val, 0);
    const expected = [3, 4, 2];
    let actual = [];
    x.observe(str, v => actual.push(v));
    o.x = 1;
    o.x = -2;
    o.x = 5;
    t.is(expected[0], actual[0]);
    t.is(expected[1], actual[1]);
    t.is(expected[2], actual[2]);

    Install

    npm i xain

    DownloadsWeekly Downloads

    1

    Version

    1.0.5

    License

    MIT

    Last publish

    Collaborators

    • oakfang