prevwong / reka.js

💎 State management system to build any no-code editor
https://reka.js.org/
MIT License
527 stars 35 forks source link

Vanilla JS example #160

Open ddorstijn opened 3 weeks ago

ddorstijn commented 3 weeks ago

Thanks for the library! It seems useful and lightweight, which I can really appreciate.

I would like to try out the library myself, but I have a hard time implementing the library in another framework (or vanilla js). Could you give a minimal example on how the subscrive pattern (or mobx in general) could be used without a framework? Or some pointers for me to implement it myself? It is way easier to integrate the library anywhere if I have a better understanding of what happens under the hood.

prevwong commented 2 weeks ago

There's a basic example without React here: https://github.com/prevwong/reka.js/tree/main/examples/00-basic

ddorstijn commented 2 weeks ago

I'm sorry I was unclear. In issue https://github.com/prevwong/reka.js/issues/139. You mentioned an implementation with subscribe. There is not a lot of documentation on this function. I thought about implementing a simple editor in vanilla js and took that as a pointer, but I did not come far.

prevwong commented 2 weeks ago

Ah okay. So firstly, as you already know - Mobx is used in Reka as the reactive state management provider - so the State AST and output View data types in Reka in particular are Mobx observables. We create a View anytime we want to evaluate a component that exists in the State.

The core functionality of Reka is to ensure that any resulting View is updated/evaluated correctly based on the State. So let's say you change a prop of a button element in State, then the View corresponding to that button element should be evaluated again.

Reka has some methods like subscribe which allows you to get some values from the State/View, and perform a callback whenever the values you subscribe to have changed:

const frame = reka.createFrame({...});

reka.subscribe(() => { 
  // get the values you need:
  return { 
    tag:  t.assert(frame.view.render[0], t.TagView).tag
  }
}, (collected) => {
  console.log("The tag has changed", collected.tag);
});

So let's say you want to render some HTML elements for every View in a frame, you probably need to subscribe/listen to a frame's view and render/update the HTML elements accordingly. The React example, more or less works like this.