Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

An observable state tree is a normal object except that listeners can be bound to any subtree of the state tree.

NotificationsYou must be signed in to change notification settings

mfbx9da4/observable-state-tree

Repository files navigation

The below is a programming challenge I set myself on boxing day 2020. Give it a go! 🎄🦌

Problem Statement

Build an observable state tree.

An observable state tree is a normal object except that listeners can be bound to any subtree of the state tree.

Behaviour requirements:

  1. Modifying a subtree will notify all parent listeners.
  2. Modifying a sibling should not notify any siblings.
  3. Modifying a parent only notifies the children listeners, if the children have also changed.

Examples of the above requirements are given below.

Examples and Proposed API

The below code should be viewed as pseudocode to demonstrate the usage of the data structure. You may wish to tweak the API to be more ergonomic or practical as you see fit.

consttree=createTree({a:{b:{c:1,d:1}}})// the tree behaves like a normal object e.gconsole.log(tree)// prints the object 👉 { a: { b: { c : 1, d: 1 }}}// we can setup listenersconstdestroyRoot=listen(tree,(root)=>console.log('root',root))// on initial setup prints the full tree 👉 root { a: { b: { c: 1, d: 1 }}}// the return value is a function which destroys the listenerconstdestroyA=listen(tree.a,(a)=>console.log('a',a))// 👉 a { b: { c: 1 }}constdestroyB=listen(tree.a.b,(b)=>console.log('b',b))// 👉 b { c: 1 }constdestroyC=listen(tree.a.b.c,(c)=>console.log('c',c))// 👉 c 1constdestroyD=listen(tree.a.b.d,(d)=>console.log('d',d))// 👉 d 1// should also support sending the prev valuedestroyRoot()// 👆 calling destroy, removes the listener// 🙋‍♂️// 1. Modifying a subtree will notify all parent listeners.// 2. Modifying a sibling should not notify any siblings.tree.a.b.c=2// 👉 a { b: { c: 2 }}// 👉 b { c: 2 }// 👉 c 2// a, b and c are fired but sibling d is not fired// 🙋‍♂️// 3. Modifying a parent only notifies the children listeners, if the children have also changed.tree.a={ ...tree.a}// 👉 a { b: { c: 2 }}// a is fired but b, c and d are not firedtree.a={e:1}// 👉 a { e: 1 }// 👉 b undefined// 👉 c undefined// 👉 d undefined// b, c and d have been deleted so they should be notified with undefined

Implementation Sketch

Data structure will consist of two trees:

  • State tree
  • Listener tree

The state tree is a standard object which is nothing more than a nested javascript object.The listener tree is the tree of listeners.

Each node in the listener tree has:

  • Children listeners
  • Parent listeners
  • Listener callbacks

Getting a particular path will just return that node of the state tree:

Setting a particular path with a value will:

  • Update state tree
  • Traverse parents and notify with new value
  • Traverse listener children and notify with new value

Use proxies for dot notation.

Real World Applications

Later in react.js, could be used like so

constuseStoreState=(selector)=>{const[state,setState]=useState()useEffect(()=>{constdestroy=listen(selector,setState)returndestroy})returnstate}

Implementation

About

An observable state tree is a normal object except that listeners can be bound to any subtree of the state tree.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp