Coder Social home page Coder Social logo

reactive-box's People

Contributors

betula avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

reactive-box's Issues

To make article for beginners

These are three basic elements necessary for creating data flow any difficulty.

The first element is a reactive container for an immutable value. All reactions beginning from container change value reaction.

The second one is the middle element. It uses all reactive containers as a source of values and returns the result of the expression. It's a transformer set of reactive values to a single one. The selector can be used as a reactive container in other selectors and expressions.

It subscribes to change in any of the dependencies. And will recalculate the value if some of the dependency changed.

And the last one is a reaction subscriber. It provides the possibility to subscribe to change any set of reactive containers. It can be run again after the listener was called.

Proposal for flow

Necessary to create breakable flow, who can stop the flow of data spread, and rerun it as many times as necessary.

flow((stop?, resolve?, prev_value?) => {}, empty_value?, compare_fn?);

Example of using:

// Awaiting flow
const b = box(0);
const f = flow((stop, resolve) => {
  const v = b[0]();
  setTimeout(() => resolve(v));
  return stop;
});

expr(() => {
  console.log(b[0](), f[0]());
})[0]();

b[1](1);

// 0, undefined
// 1, undefined
// 1, 0
// 1, 1

Or multiple resolves in one time

const b = box(0);
const f = flow((stop, resolve) => {
  const v = b[0]();
  for (let i = 0; i < v; i++) resolve(i);
  return 0;
});

expr(() => {
  console.log(b[0](), f[0]());
})[0]();

b[1](3);

// 0, 0
// 3, 0
// 3, 1
// 3, 2
// 3, 0

And transaction support:

const b = box(0);
const f = flow((stop, resolve) => {
  const v = b[0]();
  const commit = transaction();
  for (let i = 0; i < v; i++) resolve(i);
  commit();
  return stop;
});

expr(() => {
  console.log(b[0](), f[0]());
})[0]();

b[1](3);

// 0, 0
// 3, 2

Result caching similar selector

const a = box(0);

let i = 0;
const f = flow(() => (i++, a[0]() + 1));
assert(i == 1);

assert(f[0]() == 1);
assert(f[0]() == 1);
assert(i == 1);

a[1](1);
assert(i == 2);
assert(f[0]() == 2);
assert(i == 2);

Should safe correct reactions order for changing depth without modification

  test("should safe correct reactions order for changing depth without modification", () => {
    const spy = jest.fn();
    const a = mut(0);
    const b = mut(0);

    const m0 = comp(() => {
      return !b.val ? a.val : k0.val;
    });
    const k0 = comp(() => {
      return !b.val ? m0.val : a.val;
    });

    const m = comp(() => m0.val);
    const k = comp(() => k0.val);

    let i = 0;
    run(() => (k.val, spy('k', i++)));
    run(() => (m.val, spy('m', i++)));

    expect(spy).toHaveBeenNthCalledWith(1, 'k', 0);
    expect(spy).toHaveBeenNthCalledWith(2, 'm', 1);
    expect(spy).toBeCalledTimes(2);
    spy.mockReset();

    a.val = 1;
    expect(spy).toHaveBeenNthCalledWith(1, 'm', 2);
    expect(spy).toHaveBeenNthCalledWith(2, 'k', 3);
    expect(spy).toBeCalledTimes(2);
    spy.mockReset();

    // switch
    b.val = 1;
    expect(spy).toBeCalledTimes(0);

    // check
    a.val = 2;
    // TODO: check failed (m:4, k:5)
    // expect(spy).toHaveBeenNthCalledWith(1, 'k', 4);
    // expect(spy).toHaveBeenNthCalledWith(2, 'm', 5);
    expect(spy).toBeCalledTimes(2);
    spy.mockReset();
  });

d80be9c#diff-a9b84960a146958d9aecb5cbe3fccdf262c40fe07bddbb659f63d8a7766ed3a5R203-R245

Add free function to box instance

Necessary to add a free function for the box. The source problem is subscriptions in the cycle, the decision of that free box after each iteration.

const [get_a, set_a, free_a] = box(0);

expr(() => {
  console.log(get_a());
})[0]();

set_a(1);
free_a();
set_a(2);

// 0
// 1

Deeply nested selector cache not clearing in write phase immediately

  test("write and read selector in write phase", () => {
    const spy = jest.fn();
    const a = mut(0);
    const b = mut(1);
    const s_1 = comp(() => b.val + 1);
    const s_2 = comp(() => s_1.val + 1);
    const s_3 = comp(() => s_2.val + 1);

    const e = expr(() => {
      if (a.val > 0) {
        b.val = a.val + 1;
        spy(s_3.val);
      }
    });
    e[0]();

    expect(s_3.val).toBe(4);

    a.val = 1;
    expect(spy).toBeCalledTimes(2);

    expect(spy).toHaveBeenNthCalledWith(1, 4); // TODO: that call possible to exclude
    expect(spy).toHaveBeenNthCalledWith(2, 5);
  });

See that test on reactive-box github repo

Future

[] Add transaction

  const [a, b] = [box(0), box[0]];

  const commit = transaction();
  a[1](10); 
  b[1](11);
  commit();

[] Make jsx with box value support

const name = box('');
const App = () => <h1>{name}</h1>

The flow implementation

const [get_a, set_a] = box(-5);

const [get, free] = flow(init_value?, (stop) => {
  // stop is only function, and returns void, no throw anything
  if (get_a() > 0) stop();
  return get_a() + 1;
});

get() // -4
set_a(0);
get() // 1;
set_a(5);
get() // 1;

Update selector invalidation propagate

For performance reason necessary to change invalidation propagate strategy for a selector.
If the selector has holders, I need to recalculate It early, before expanding dependencies after the sync updaters phase.
If the value of the selector is not changed, not need to propagate invalidation to its holders.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.