Skip to content

Instantly share code, notes, and snippets.

@kenotron
Last active November 25, 2019 16:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenotron/8c4b0f70ecacf37d207853b40d0ddbed to your computer and use it in GitHub Desktop.
Save kenotron/8c4b0f70ecacf37d207853b40d0ddbed to your computer and use it in GitHub Desktop.
Mobx Cursor
import {observable} from '../src/api/observable';
import {ObservableValue} from '../src/types/observableValue';
import {IDerivation, IDerivationState, trackDerivedFunction} from '../src/core/derivation';
import {IObservable} from '../src/core/observable';
var store = observable({
foo: {
baz: {
test: "value1"
}
},
bar: {
hello: "kitty"
}
});
// CursorValue.ts
class CursorValue implements IDerivation {
name: string;
observing: IObservable[] = [];
newObserving: IObservable[] = [];
dependenciesState: IDerivationState;
/**
* Id of the current run of a derivation. Each time the derivation is tracked
* this number is increased by one. This number is globally unique
*/
runId: number;
/**
* amount of dependencies used by the derivation in this run, which has not been bound yet.
*/
unboundDepsCount: number;
__mapid: string;
onBecomeStale() {};
recoverFromError() {};
constructor(public selector: () => any) {
trackDerivedFunction(this, this.peek);
this.name = "Cursor@" + this.runId;
}
peek() {
this.selector();
}
get getter() {
let value = <ObservableValue<any>>this.observing[this.observing.length - 1];
return value.get.bind(value);
}
get setter() {
let value = <ObservableValue<any>>this.observing[this.observing.length - 1];
return value.set.bind(value);
}
}
// Select decorator
function select(selector: any) {
return function decorator<T extends Function>(target: T): T {
let _this = this;
let returnValue: any = function() {
let state = {};
Object.keys(selector).forEach(key => {
let cursorValue = new CursorValue(selector[key]);
Object.defineProperty(state, key, {
get: cursorValue.getter,
set: cursorValue.setter
});
});
[].push.call(arguments, state);
return target.apply(_this, arguments);
}
return <T>returnValue;
}
}
// someaction
function someaction(state?) {
state.test = "something else";
state.hello = "world";
}
select({
test: () => store.foo.baz.test,
hello: () => store.bar.hello
})(someaction)();
console.log(store.foo.baz.test);
console.log(store.bar.hello);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment