Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const contextMap = new WeakMap();
- function defaultContext() {
- return window;
- }
- function resolveItemAndContext(ctx, item) {
- if (item === undefined && typeof ctx === 'string') {
- item = ctx;
- ctx = defaultContext();
- }
- return { item, ctx };
- }
- function emptyReference() {
- return {
- value() {
- return undefined;
- },
- validate() { return true; },
- update() {
- return;
- }
- }
- }
- function referenceFor(ctx, item) {
- if (typeof ctx !== 'object' || ctx === null) {
- return emptyReference();
- }
- if (!contextMap.has(ctx)) {
- contextMap.set(ctx, {});
- }
- const paths = item.split('.');
- if (paths.length > 1) {
- return referenceFor(referenceFor(ctx, paths.shift()).value(), paths.join('.'));
- }
- const existingRefs = contextMap.get(ctx);
- if (!(item in existingRefs)) {
- const ref = {
- ver: 0,
- value() {
- return ctx[item];
- },
- update(value) {
- this.ver++;
- ctx[item] = value;
- return value;
- }
- };
- existingRefs[item] = ref;
- }
- return existingRefs[item] ;
- }
- function get(maybeContxt, maybeItem) {
- const { ctx, item } = resolveItemAndContext(maybeContxt, maybeItem);
- return referenceFor(ctx, item).value();
- }
- function set(...args) {
- if (args.length <= 1) {
- return undefined;
- }
- if (args.length === 2) {
- const { ctx, item } = resolveItemAndContext(args[0]);
- return referenceFor(ctx, item).update(args[1]);
- } else {
- return referenceFor(args[0], args[1]).update(args[2]);
- }
- }
- function r(maybeContxt, maybeItem) {
- const { ctx, item } = resolveItemAndContext(maybeContxt, maybeItem);
- return referenceFor(ctx, item);
- }
- r('name').value()
- r('name').update(12);
- get('name');
- set('name', 'foo');
- var handler = {
- get(target, name){
- return get(name);
- },
- set(target, name, value) {
- return set(name, value);
- }
- };
- var globalState = new Proxy({}, handler);
- const observersMap = new WeakMap();
- const observersSet = new Set();
- function observersFor(originalRef) {
- return observersMap.get(originalRef);
- }
- function registerObserver(originalRef, obs) {
- if (!observersMap.has(originalRef)) {
- observersMap.set(originalRef, []);
- }
- observersSet.add(obs);
- observersMap.get(originalRef).push(obs);
- }
- function observableRef(trackedRef, cb) {
- const ref = {
- validate() {
- return trackedRef.validate();
- },
- sync() {
- trackedRef.update();
- return cb(trackedRef.value());
- }
- };
- registerObserver(trackedRef.ref, ref);
- return ref;
- }
- function trackedRef(ref, maybeCb) {
- return {
- ver: -1,
- computedValue: null,
- ref,
- validate() {
- return this.ver === this.ref.ver;
- },
- value() {
- return this.computedValue;
- },
- update() {
- if (arguments.length === 1) {
- this.ref.update(arguments[0]);
- }
- this.ver = this.ref.ver;
- this.computedValue = this.ref.value();
- }
- }
- }
- const observalbleRef = observableRef(trackedRef(r('name')), function(newValue){
- console.log('newValue');
- });
- r('name').update('12');
- observersFor(r('name')).filter((obs)=>!obs.validate()).forEach((obs)=>obs.sync());
- function subscribe(item, cb) {
- return observableRef(trackedRef(r(item)), cb);
- }
- subscribe('name', (value) => { console.log('valueUpdated', value) ;});
- function sync() {
- observersSet.forEach((value)=>{
- if (!value.validate()) { value.sync() };
- });
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement