SHARE
TWEET

Untitled

a guest Sep 22nd, 2019 78 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const contextMap = new WeakMap();
  2.  
  3. function defaultContext() {
  4.     return window;
  5. }
  6.  
  7. function resolveItemAndContext(ctx, item) {
  8.     if (item === undefined && typeof ctx === 'string') {
  9.         item = ctx;
  10.         ctx = defaultContext();
  11.     }
  12.    
  13.     return { item, ctx };
  14. }
  15. function emptyReference() {
  16.     return {
  17.         value() {
  18.             return undefined;
  19.         },
  20.         validate() { return true; },
  21.         update() {
  22.             return;
  23.         }
  24.     }
  25. }
  26. function referenceFor(ctx, item) {
  27.     if (typeof ctx !== 'object' || ctx === null) {
  28.         return emptyReference();
  29.     }
  30.     if (!contextMap.has(ctx)) {
  31.         contextMap.set(ctx, {});
  32.     }
  33.     const paths = item.split('.');
  34.     if (paths.length > 1) {
  35.         return referenceFor(referenceFor(ctx, paths.shift()).value(), paths.join('.'));
  36.     }
  37.     const existingRefs = contextMap.get(ctx);
  38.     if (!(item in existingRefs)) {
  39.         const ref = {
  40.             ver: 0,
  41.             value() {
  42.                 return ctx[item];
  43.             },
  44.             update(value) {
  45.                 this.ver++;
  46.                 ctx[item] = value;
  47.                 return value;
  48.             }
  49.         };
  50.         existingRefs[item] = ref;
  51.     }
  52.     return existingRefs[item] ;
  53. }
  54.  
  55.  
  56. function get(maybeContxt, maybeItem) {
  57.     const { ctx, item } = resolveItemAndContext(maybeContxt, maybeItem);
  58.     return referenceFor(ctx, item).value();
  59. }
  60. function set(...args) {
  61.     if (args.length <= 1) {
  62.         return undefined;
  63.     }
  64.     if (args.length === 2) {
  65.         const { ctx, item } = resolveItemAndContext(args[0]);
  66.         return referenceFor(ctx, item).update(args[1]);
  67.     } else {
  68.         return referenceFor(args[0], args[1]).update(args[2]);
  69.     }
  70.  
  71. }
  72. function r(maybeContxt, maybeItem) {
  73.     const { ctx, item } = resolveItemAndContext(maybeContxt, maybeItem);
  74.     return referenceFor(ctx, item);
  75. }
  76. r('name').value()
  77. r('name').update(12);
  78. get('name');
  79. set('name', 'foo');
  80.  
  81.  
  82. var handler = {
  83.     get(target, name){
  84.         return get(name);
  85.     },
  86.     set(target, name, value) {
  87.         return set(name, value);
  88.     }
  89. };
  90.  
  91. var globalState = new Proxy({}, handler);
  92.  
  93. const observersMap = new WeakMap();
  94. const observersSet = new Set();
  95.  
  96. function observersFor(originalRef) {
  97.     return observersMap.get(originalRef);
  98. }
  99.  
  100. function registerObserver(originalRef, obs) {
  101.     if (!observersMap.has(originalRef)) {
  102.         observersMap.set(originalRef, []);
  103.     }
  104.     observersSet.add(obs);
  105.     observersMap.get(originalRef).push(obs);
  106. }
  107.  
  108. function observableRef(trackedRef, cb) {
  109.     const ref = {
  110.         validate() {
  111.             return trackedRef.validate();
  112.         },
  113.         sync() {
  114.             trackedRef.update();
  115.             return cb(trackedRef.value());
  116.         }
  117.     };
  118.     registerObserver(trackedRef.ref, ref);
  119.     return ref;
  120. }
  121.  
  122. function trackedRef(ref, maybeCb) {
  123.     return {
  124.         ver: -1,
  125.         computedValue: null,
  126.         ref,
  127.         validate() {
  128.             return this.ver === this.ref.ver;
  129.         },
  130.         value() {
  131.             return this.computedValue;
  132.         },
  133.         update() {
  134.             if (arguments.length === 1) {
  135.                this.ref.update(arguments[0]);
  136.             }
  137.             this.ver = this.ref.ver;
  138.             this.computedValue = this.ref.value();
  139.         }
  140.     }
  141. }
  142.  
  143.  
  144. const observalbleRef = observableRef(trackedRef(r('name')), function(newValue){
  145.     console.log('newValue');
  146. });
  147.  
  148.  
  149. r('name').update('12');
  150. observersFor(r('name')).filter((obs)=>!obs.validate()).forEach((obs)=>obs.sync());
  151.  
  152.  
  153. function subscribe(item, cb) {
  154.     return observableRef(trackedRef(r(item)), cb);
  155. }
  156.  
  157. subscribe('name', (value) => { console.log('valueUpdated', value) ;});
  158.  
  159. function sync() {
  160.     observersSet.forEach((value)=>{
  161.        if (!value.validate()) { value.sync() };
  162.     });
  163. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top