Advertisement
Guest User

Untitled

a guest
Sep 22nd, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.17 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement