@expressive/mvc 1.0.0-beta.33 → 1.0.0-beta.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.esm.js CHANGED
@@ -92,58 +92,51 @@ class Subscriber {
92
92
  constructor(parent, onUpdate) {
93
93
  this.onUpdate = onUpdate;
94
94
  this.active = false;
95
- this.handle = {};
95
+ this.using = {};
96
96
  this.dependant = new Set();
97
- this.debug = () => {
98
- const update = [];
99
- this.notify = keys => {
100
- update.splice(0, update.length, ...keys.filter(k => k in this.handle));
101
- };
102
- return update;
103
- };
104
- this.listen = (key, from) => {
105
- const handler = this.handle[key];
106
- if (!handler)
107
- return;
108
- if (typeof handler == "function")
109
- handler();
110
- const notify = this.onUpdate(key, from);
111
- if (notify)
112
- from.waiting.add(notify);
113
- if (this.notify)
114
- from.waiting.add(this.notify);
115
- };
116
97
  if (!(parent instanceof Controller))
117
98
  parent = manage(parent);
118
99
  this.parent = parent;
119
100
  this.source = parent.subject;
120
101
  this.proxy = create(parent.subject);
121
102
  define(this.proxy, LOCAL, this);
122
- defineLazy(this.proxy, UPDATE, this.debug);
103
+ defineLazy(this.proxy, UPDATE, () => {
104
+ const update = [];
105
+ this.notify = keys => {
106
+ update.splice(0, update.length, ...keys.filter(k => k in this.using));
107
+ };
108
+ return update;
109
+ });
123
110
  for (const key in parent.state)
124
111
  this.spy(key);
125
112
  }
126
113
  spy(key) {
127
- const { proxy, source } = this;
128
- const { set } = getOwnPropertyDescriptor(source, key);
129
- const intercept = () => {
130
- this.follow(key);
114
+ const { proxy } = this;
115
+ const existing = getOwnPropertyDescriptor(this.source, key);
116
+ const isUsing = () => {
117
+ this.using[key] = true;
131
118
  delete proxy[key];
132
119
  return proxy[key];
133
120
  };
134
- setAlias(intercept, `tap ${key}`);
121
+ setAlias(isUsing, `tap ${key}`);
135
122
  defineProperty(proxy, key, {
136
- get: intercept,
137
- set,
123
+ set: existing.set,
124
+ get: isUsing,
138
125
  configurable: true,
139
126
  enumerable: true
140
127
  });
141
128
  }
142
- follow(key, callback) {
143
- this.handle[key] = callback || true;
144
- }
145
129
  commit() {
146
- const onDone = this.parent.addListener(this.listen);
130
+ const onDone = this.parent.addListener((key, source) => {
131
+ const handler = this.using[key];
132
+ if (!handler)
133
+ return;
134
+ if (typeof handler == "function")
135
+ handler();
136
+ const notify = this.onUpdate(key, source);
137
+ source.onUpdate(notify);
138
+ source.onUpdate(this.notify);
139
+ });
147
140
  this.active = true;
148
141
  this.dependant.forEach(x => x.commit());
149
142
  return this.release = () => {
@@ -230,7 +223,7 @@ function prepare(parent, key, source, setter, getter) {
230
223
  }
231
224
  finally {
232
225
  sub.commit();
233
- for (const key in sub.handle) {
226
+ for (const key in sub.using) {
234
227
  const peer = register.get(key);
235
228
  if (peer && peer.priority >= info.priority)
236
229
  info.priority = peer.priority + 1;
@@ -367,6 +360,10 @@ class Controller {
367
360
  get pending() {
368
361
  return this.frame.size > 0;
369
362
  }
363
+ onUpdate(cb) {
364
+ if (typeof cb == "function")
365
+ this.waiting.add(cb);
366
+ }
370
367
  start() {
371
368
  const { subject } = this;
372
369
  for (const key in subject) {
@@ -431,11 +428,8 @@ class Controller {
431
428
  if (!this.frame.size)
432
429
  setTimeout(() => this.emit(), 0);
433
430
  this.frame.add(key);
434
- for (const subscription of this.followers) {
435
- const notify = subscription(key, this);
436
- if (notify)
437
- this.waiting.add(notify);
438
- }
431
+ for (const callback of this.followers)
432
+ this.onUpdate(callback(key, this));
439
433
  }
440
434
  emit() {
441
435
  flush(this);
@@ -494,7 +488,7 @@ function child(source, name) {
494
488
  start();
495
489
  }
496
490
  start();
497
- sub.follow(key, restart);
491
+ sub.using[key] = restart;
498
492
  }
499
493
  return (local) => {
500
494
  if (!local)
@@ -665,9 +659,9 @@ function act(task) {
665
659
  }
666
660
  function from(source, setter, argument) {
667
661
  return apply(function from(key) {
668
- const { subject } = this;
669
662
  let getSource;
670
- let getter = argument === true
663
+ const { subject } = this;
664
+ const getter = argument === true
671
665
  ? pendingValue
672
666
  : argument || undefined;
673
667
  // Easy mistake, using a peer, will always be unresolved.
@@ -808,13 +802,11 @@ function useWatcher(target, focus, expected) {
808
802
  function useComputed(target, compute, expected) {
809
803
  const hook = use$1(refresh => {
810
804
  const sub = new Subscriber(target, () => update);
811
- const { proxy } = sub;
812
- let value;
805
+ const spy = sub.proxy;
806
+ let value = compute.call(spy, spy);
807
+ let update;
813
808
  let retry;
814
- const update = () => {
815
- const next = compute.call(proxy, proxy);
816
- if (value == next)
817
- return;
809
+ const set = (next) => {
818
810
  value = next;
819
811
  if (retry) {
820
812
  retry();
@@ -823,16 +815,26 @@ function useComputed(target, compute, expected) {
823
815
  else
824
816
  refresh();
825
817
  };
826
- const access = () => {
827
- if (value === undefined && expected)
828
- throw new Promise(res => {
829
- retry = res;
830
- });
831
- return value;
832
- };
833
- value = compute.call(proxy, proxy);
834
- sub.commit();
835
- defineProperty(sub, "proxy", { get: access });
818
+ if (value instanceof Promise) {
819
+ value.then(set);
820
+ value = undefined;
821
+ }
822
+ else {
823
+ sub.commit();
824
+ update = () => {
825
+ const next = compute.call(spy, spy);
826
+ if (value != next)
827
+ set(next);
828
+ };
829
+ }
830
+ const get = expected
831
+ ? () => {
832
+ if (value === undefined)
833
+ throw new Promise(res => retry = res);
834
+ return value;
835
+ }
836
+ : () => value;
837
+ defineProperty(sub, "proxy", { get });
836
838
  return sub;
837
839
  });
838
840
  useLayoutEffect(() => hook.release, []);
@@ -995,7 +997,7 @@ class Model {
995
997
  define(this, "set", this);
996
998
  defer(control, "on");
997
999
  defer(control, "effect");
998
- control.waiting.add(() => {
1000
+ control.onUpdate(() => {
999
1001
  delete this.on;
1000
1002
  delete this.effect;
1001
1003
  });
@@ -1042,10 +1044,9 @@ class Model {
1042
1044
  once(select, callback, squash) {
1043
1045
  if (callback)
1044
1046
  return this.on(select, callback, squash, true);
1045
- else
1046
- return new Promise(resolve => {
1047
- this.on(select, resolve, true, true);
1048
- });
1047
+ return new Promise(resolve => {
1048
+ this.on(select, resolve, true, true);
1049
+ });
1049
1050
  }
1050
1051
  effect(callback, select) {
1051
1052
  const control = manage(this);