thepassle / atom Goto Github PK
View Code? Open in Web Editor NEWA flexible state manager
Home Page: https://klaxon-atom.netlify.app/
A flexible state manager
Home Page: https://klaxon-atom.netlify.app/
It would be nice not to depend on a 'global' map of atoms/selectors.
I think this should be easily refactorable. Instead of having atoms return a {key: 'someAtom'}
, we can just return the Atom
instance. When initializing Selectors, we need to pass the Atom to the Selector anyway, so we can rely on that directly.
This might be a problem for the devtools though, since the global Map is required for getting the initial states of atoms/selectors, but we might be able to work around that.
If you have a Selector that was never registered to an element, that Selectors .active
will be null
and even if other Selectors depend on that Selector, it will not execute, because it never was connected and is still null
so the check to see if selector.active > 0
wont run the get
function, because selector.active
is null
maybe add a flag .hasSelectorDependencies
on the selectors store? and add that to the check? then it will run
if you call getSelector
that means the selector you're get
ting by definition has a dependency
Maybe when the current Selector is trying to get a parent value, it can avoid it when the current Selector self isnt active
Maybe the getSelector
function should always call a parent Selectors get
function? The downside of this is that it could lead to that Selectors get
function to be called multiple times potentially. Maybe this is fine in case of calculations, but less so if a Selector does API calls.
I also dont think the docs about Selectors depending on inactive Selectors
are correct. I think thats only correct if the selector ever WAS active (so its .active
is 0
instead of null
)
Mobx heavily uses "magic" (i.e. hides away most of the reactions/observations by default and 'figures them out').
Not everyone is a fan of this but it has proven to be fairly popular, so i had a go at doing similar with atom.
Here's what i have:
export class MyElement extends AtomLitElement {
render() {
return html`
<button @click="${() => setCount(old => old - 1)}">-</button>
<span>${count.getState()}</span>
<button @click="${() => setCount(old => old + 1)}">+</button>
`;
}
}
import {LitElement, html, PropertyValues} from 'lit-element';
// NOTE: atoms isn't currently exported
import {atom, atoms} from "@klaxon/atom";
const [count, setCount] = atom({
key: 'count',
default: 0
});
// Truly excellent name
class AtomicReactor {
public callback: () => void;
protected _accessed: Set<string> = new Set();
public constructor(callback: () => void) {
this.callback = callback;
}
public track(): () => void {
const originalGet = atoms.get;
// NOTE: overwriting a method like this always feels like hackery
// but the only other way i suppose is to have atom itself have a concept
// of notifying of accesses (e.g. an event fired when one is accessed, but more
// performant than that).
atoms.get = (key: string) => {
this._accessed.add(key);
return originalGet.call(atoms, key);
};
return () => {
atoms.get = originalGet;
for (const [key, atom] of atoms.entries()) {
if (this._accessed.has(key)) {
// NOTE: needs to be removed at some point so we don't fill
// memory with event listeners over time
atom.addEventListener(key, () => {
this.callback();
});
}
}
};
}
}
const reactor = Symbol();
class AtomLitElement extends LitElement {
protected [reactor]?: AtomicReactor;
public connectedCallback(): void {
super.connectedCallback();
this[reactor] = new AtomicReactor(() => {
this.requestUpdate();
});
}
public disconnectedCallback(): void {
super.disconnectedCallback();
// NOTE: probably needs a this[reactor].dispose() which
// removes all those previously mentioned listeners
this[reactor] = undefined;
}
protected update(change: PropertyValues): void {
const reactorInstance = this[reactor];
if (reactorInstance) {
const disposer = reactorInstance.track();
super.update(change);
disposer();
} else {
super.update(change);
}
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.