@expressive/mvc 1.0.0-beta.23 → 1.0.0-beta.27

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.js CHANGED
@@ -96,14 +96,34 @@ class Subscriber {
96
96
  constructor(parent, onUpdate) {
97
97
  this.onUpdate = onUpdate;
98
98
  this.active = false;
99
- this.follows = {};
99
+ this.handle = {};
100
100
  this.dependant = new Set();
101
+ this.debug = () => {
102
+ const update = [];
103
+ this.notify = keys => {
104
+ update.splice(0, update.length, ...keys.filter(k => k in this.handle));
105
+ };
106
+ return update;
107
+ };
108
+ this.listen = (key, from) => {
109
+ const handler = this.handle[key];
110
+ if (!handler)
111
+ return;
112
+ if (typeof handler == "function")
113
+ handler();
114
+ const notify = this.onUpdate(key, from);
115
+ if (notify)
116
+ from.waiting.add(notify);
117
+ if (this.notify)
118
+ from.waiting.add(this.notify);
119
+ };
101
120
  if (!(parent instanceof Controller))
102
121
  parent = manage(parent);
103
122
  this.parent = parent;
104
123
  this.source = parent.subject;
105
124
  this.proxy = create(parent.subject);
106
125
  define(this.proxy, LOCAL, this);
126
+ defineLazy(this.proxy, UPDATE, this.debug);
107
127
  for (const key in parent.state)
108
128
  this.spy(key);
109
129
  }
@@ -123,16 +143,15 @@ class Subscriber {
123
143
  enumerable: true
124
144
  });
125
145
  }
126
- follow(key, cb) {
127
- this.follows[key] = cb || this.onUpdate;
146
+ follow(key, callback) {
147
+ this.handle[key] = callback || true;
128
148
  }
129
149
  commit() {
130
- const { dependant, follows, parent } = this;
131
- const onDone = parent.addListener(follows);
150
+ const onDone = this.parent.addListener(this.listen);
132
151
  this.active = true;
133
- dependant.forEach(x => x.commit());
152
+ this.dependant.forEach(x => x.commit());
134
153
  return this.release = () => {
135
- dependant.forEach(x => x.release());
154
+ this.dependant.forEach(x => x.release());
136
155
  onDone();
137
156
  };
138
157
  }
@@ -142,18 +161,23 @@ const Oops$8 = issues({
142
161
  ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
143
162
  ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
144
163
  });
145
- const ComputedInit = new WeakSet();
146
- const ComputedInfo = new WeakMap();
147
- const ComputedUsed = new WeakMap();
148
- const ComputedKeys = new WeakMap();
164
+ const INIT = new WeakSet();
165
+ const INFO = new WeakMap();
166
+ const USED = new WeakMap();
167
+ const KEYS = new WeakMap();
149
168
  function prepare(parent, key, source, setter, getter) {
150
169
  let sub;
151
170
  const { state, subject } = parent;
152
171
  const info = { key, parent, priority: 1 };
172
+ let register = USED.get(parent);
173
+ if (!register) {
174
+ register = new Map();
175
+ USED.set(parent, register);
176
+ }
177
+ register.set(key, info);
153
178
  const current = getter
154
179
  ? () => getter.call(subject, state[key], key)
155
180
  : () => state[key];
156
- const prioritize = register(parent, key, info);
157
181
  function compute(initial) {
158
182
  try {
159
183
  return setter.call(sub.proxy, sub.proxy);
@@ -178,8 +202,19 @@ function prepare(parent, key, source, setter, getter) {
178
202
  }
179
203
  }
180
204
  }
205
+ function defer(_key, from) {
206
+ let pending = KEYS.get(from);
207
+ if (!pending)
208
+ KEYS.set(from, pending = []);
209
+ if (info.parent !== from)
210
+ update();
211
+ else {
212
+ const after = pending.findIndex(peer => (info.priority > INFO.get(peer).priority));
213
+ pending.splice(after + 1, 0, update);
214
+ }
215
+ }
181
216
  function create(early) {
182
- sub = new Subscriber(source(), update);
217
+ sub = new Subscriber(source(), defer);
183
218
  defineProperty(state, key, {
184
219
  value: undefined,
185
220
  writable: true
@@ -199,16 +234,19 @@ function prepare(parent, key, source, setter, getter) {
199
234
  }
200
235
  finally {
201
236
  sub.commit();
202
- for (const key in sub.follows)
203
- prioritize(key);
237
+ for (const key in sub.handle) {
238
+ const peer = register.get(key);
239
+ if (peer && peer.priority >= info.priority)
240
+ info.priority = peer.priority + 1;
241
+ }
204
242
  }
205
243
  return current();
206
244
  }
207
245
  setAlias(update, `try ${key}`);
208
246
  setAlias(create, `new ${key}`);
209
247
  setAlias(setter, `run ${key}`);
210
- ComputedInit.add(create);
211
- ComputedInfo.set(update, info);
248
+ INIT.add(create);
249
+ INFO.set(update, info);
212
250
  for (const on of [state, subject])
213
251
  defineProperty(on, key, {
214
252
  get: create,
@@ -216,53 +254,27 @@ function prepare(parent, key, source, setter, getter) {
216
254
  enumerable: true
217
255
  });
218
256
  }
219
- function register(on, key, info) {
220
- let register = ComputedUsed.get(on);
221
- if (!register)
222
- ComputedUsed.set(on, register = new Map());
223
- register.set(key, info);
224
- return (key) => {
225
- const peer = register.get(key);
226
- if (peer && peer.priority >= info.priority)
227
- info.priority = peer.priority + 1;
228
- };
229
- }
230
257
  function ensure(on, keys) {
231
258
  for (const key of keys) {
232
259
  const desc = getOwnPropertyDescriptor(on.subject, key);
233
260
  const getter = desc && desc.get;
234
- if (ComputedInit.has(getter))
261
+ if (INIT.has(getter))
235
262
  getter(true);
236
263
  }
237
264
  }
238
- function capture(on, request) {
239
- const compute = ComputedInfo.get(request);
240
- const callback = request;
241
- if (!compute)
242
- return;
243
- let pending = ComputedKeys.get(on);
244
- if (!pending)
245
- ComputedKeys.set(on, pending = []);
246
- if (compute.parent !== on)
247
- callback();
248
- else {
249
- const queue = pending.findIndex(peer => compute.priority > ComputedInfo.get(peer).priority);
250
- pending.splice(queue + 1, 0, callback);
251
- }
252
- return true;
253
- }
254
265
  function flush(on) {
255
266
  const handled = on.frame;
256
- let pending = ComputedKeys.get(on);
257
- if (pending) {
258
- while (pending.length) {
259
- const compute = pending.shift();
260
- const { key } = ComputedInfo.get(compute);
261
- if (!handled.has(key))
262
- compute();
263
- }
264
- ComputedKeys.delete(on);
265
- }
267
+ const pending = KEYS.get(on);
268
+ if (!pending)
269
+ return;
270
+ while (pending.length) {
271
+ const why = [...handled];
272
+ const compute = pending.shift();
273
+ const { key } = INFO.get(compute);
274
+ if (!handled.has(key))
275
+ compute(why);
276
+ }
277
+ KEYS.delete(on);
266
278
  }
267
279
 
268
280
  const Lifecycle = {
@@ -313,6 +325,7 @@ function eventsFor(prefix) {
313
325
  }
314
326
 
315
327
  const CONTROL = Symbol("control");
328
+ const UPDATE = Symbol("update");
316
329
  const LOCAL = Symbol("local");
317
330
  const STATE = Symbol("state");
318
331
  function manage(src) {
@@ -341,8 +354,8 @@ class Controller {
341
354
  this.subject = subject;
342
355
  this.state = {};
343
356
  this.frame = new Set();
344
- this.handles = new Set();
345
- this.waiting = [];
357
+ this.waiting = new Set();
358
+ this.followers = new Set();
346
359
  }
347
360
  static setup(onto) {
348
361
  const control = new this(onto);
@@ -408,18 +421,12 @@ class Controller {
408
421
  this.update(key, value);
409
422
  };
410
423
  }
411
- addListener(batch) {
412
- this.handles.add(batch);
424
+ addListener(listener) {
425
+ this.followers.add(listener);
413
426
  return () => {
414
- this.handles.delete(batch);
427
+ this.followers.delete(listener);
415
428
  };
416
429
  }
417
- include(to) {
418
- if (capture(this, to))
419
- return;
420
- else
421
- this.waiting.push(to);
422
- }
423
430
  update(key, value) {
424
431
  if (1 in arguments)
425
432
  this.state[key] = value;
@@ -428,15 +435,22 @@ class Controller {
428
435
  if (!this.frame.size)
429
436
  setTimeout(() => this.emit(), 0);
430
437
  this.frame.add(key);
431
- for (const subscription of this.handles)
432
- if (key in subscription)
433
- this.include(subscription[key]);
438
+ for (const subscription of this.followers) {
439
+ const notify = subscription(key, this);
440
+ if (notify)
441
+ this.waiting.add(notify);
442
+ }
434
443
  }
435
444
  emit() {
436
445
  flush(this);
437
- const keys = Array.from(this.frame);
438
- const handle = new Set(this.waiting.splice(0));
446
+ const keys = Object.freeze([...this.frame]);
447
+ const handle = new Set(this.waiting);
448
+ this.waiting.clear();
439
449
  this.frame.clear();
450
+ defineProperty(this.subject, UPDATE, {
451
+ configurable: true,
452
+ value: keys
453
+ });
440
454
  handle.forEach(callback => {
441
455
  try {
442
456
  callback(keys);
@@ -448,63 +462,66 @@ class Controller {
448
462
  function keys(from, using) {
449
463
  if (typeof using == "string")
450
464
  return [using];
451
- if (typeof using == "object")
452
- return Array.from(using);
465
+ if (typeof using == "object") {
466
+ using = Array.from(using);
467
+ if (using.length === 0)
468
+ using = undefined;
469
+ else
470
+ return using;
471
+ }
453
472
  return from.select(using);
454
473
  }
455
474
 
456
- function child(from, name) {
475
+ function child(source, name) {
457
476
  return apply(function child(key) {
458
- const proxyCache = new WeakMap();
459
- const getCurrent = from.call(this, key);
477
+ const context = new WeakMap();
478
+ const current = source.call(this, key);
460
479
  function subscribe(sub) {
461
480
  let child;
462
481
  function start() {
463
- const instance = getCurrent();
482
+ const instance = current();
464
483
  if (instance) {
465
484
  child = new Subscriber(instance, sub.onUpdate);
466
485
  if (sub.active)
467
486
  child.commit();
468
487
  sub.dependant.add(child);
469
- proxyCache.set(sub, child.proxy);
488
+ context.set(sub, child.proxy);
470
489
  }
471
490
  }
472
- function refresh() {
491
+ function restart() {
473
492
  if (child) {
474
493
  child.release();
475
494
  sub.dependant.delete(child);
476
- proxyCache.set(sub, undefined);
495
+ context.set(sub, undefined);
477
496
  child = undefined;
478
497
  }
479
498
  start();
480
- sub.onUpdate();
481
499
  }
482
500
  start();
483
- sub.follow(key, refresh);
501
+ sub.follow(key, restart);
484
502
  }
485
503
  return (local) => {
486
504
  if (!local)
487
- return getCurrent();
488
- if (!proxyCache.has(local))
505
+ return current();
506
+ if (!context.has(local))
489
507
  subscribe(local);
490
- return proxyCache.get(local);
508
+ return context.get(local);
491
509
  };
492
- }, name || from.name);
510
+ }, name || source.name);
493
511
  }
494
512
 
495
513
  const Oops$7 = issues({
496
514
  HasPropertyUndefined: (control, property) => `${control}.${property} is marked as required for this render.`
497
515
  });
498
- const useElementLifecycle = lifecycle("element");
499
516
  function use$1(init) {
500
517
  const [state, update] = react.useState(() => [
501
518
  init(() => update(state.concat()))
502
519
  ]);
503
520
  return state[0];
504
521
  }
505
- function useLazy(Type, args, callback) {
522
+ function useLazy(Type, callback) {
506
523
  const instance = react.useMemo(() => {
507
- const instance = Type.create(...args || []);
524
+ const instance = Type.create();
508
525
  if (callback)
509
526
  callback(instance);
510
527
  return instance;
@@ -514,7 +531,7 @@ function useLazy(Type, args, callback) {
514
531
  }
515
532
  function useWatcher(target, focus, expected) {
516
533
  const hook = use$1(refresh => {
517
- const sub = new Subscriber(target, refresh);
534
+ const sub = new Subscriber(target, () => refresh);
518
535
  if (focus) {
519
536
  const src = sub.proxy;
520
537
  const key = keys(sub.parent, focus)[0];
@@ -531,21 +548,17 @@ function useWatcher(target, focus, expected) {
531
548
  react.useLayoutEffect(() => hook.commit(), []);
532
549
  return hook.proxy;
533
550
  }
534
- function useSubscriber(target, tag) {
535
- const hook = use$1(refresh => new Subscriber(target, refresh));
536
- useElementLifecycle(hook, tag || 0);
537
- return hook.proxy;
538
- }
539
- function useModel(Type, args, callback) {
551
+ function useModel(Type, callback) {
540
552
  const hook = use$1(refresh => {
541
- const instance = new Type(...args || []);
553
+ const instance = new Type();
542
554
  const control = manage(instance);
543
- const sub = new Subscriber(control, refresh);
544
- const release = control.addListener({
545
- [Lifecycle.WILL_UNMOUNT]() {
546
- instance.destroy();
547
- release();
548
- }
555
+ const sub = new Subscriber(control, () => refresh);
556
+ const release = control.addListener((key) => {
557
+ if (key == Lifecycle.WILL_UNMOUNT)
558
+ return () => {
559
+ instance.destroy();
560
+ release();
561
+ };
549
562
  });
550
563
  if (callback)
551
564
  callback(instance);
@@ -711,7 +724,7 @@ function RenderFunction(props) {
711
724
  const hook = use$1(refresh => {
712
725
  const targets = props.context.local;
713
726
  if (targets.length == 1)
714
- return new Subscriber(targets[0], refresh);
727
+ return new Subscriber(targets[0], () => refresh);
715
728
  return {};
716
729
  });
717
730
  if (hook.commit)
@@ -733,6 +746,7 @@ const Oops$4 = issues({
733
746
  StrictUpdate: (expected) => `Strict update() did ${expected ? "not " : ""}find pending updates.`,
734
747
  NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
735
748
  });
749
+ const useElementLifecycle = lifecycle("element");
736
750
  const useComponentLifecycle = lifecycle("component");
737
751
  class Model {
738
752
  constructor() {
@@ -741,7 +755,7 @@ class Model {
741
755
  define(this, "set", this);
742
756
  defer(control, "on");
743
757
  defer(control, "effect");
744
- control.include(() => {
758
+ control.waiting.add(() => {
745
759
  delete this.on;
746
760
  delete this.effect;
747
761
  });
@@ -752,26 +766,37 @@ class Model {
752
766
  return proxy;
753
767
  }
754
768
  tag(id) {
755
- return useSubscriber(this, id);
769
+ const hook = use$1(refresh => {
770
+ return new Subscriber(this, () => refresh);
771
+ });
772
+ useElementLifecycle(hook, id || 0);
773
+ return hook.proxy;
774
+ }
775
+ use(callback) {
776
+ const hook = use$1(refresh => {
777
+ if (callback)
778
+ callback(this);
779
+ return new Subscriber(this, () => refresh);
780
+ });
781
+ useComponentLifecycle(hook);
782
+ return hook.proxy;
756
783
  }
757
784
  on(subset, handler, squash, once) {
758
785
  const control = manage(this);
759
- const set = keys(control, subset);
760
- const batch = {};
761
- const remove = control.addListener(batch);
786
+ const request = keys(control, subset);
762
787
  const callback = squash
763
788
  ? handler.bind(this)
764
- : (frame) => {
765
- for (const key of frame)
766
- if (set.includes(key))
767
- handler.call(this, control.state[key], key);
768
- };
769
- const handle = once
770
- ? (k) => { remove(); callback(k); }
789
+ : frame => frame
790
+ .filter(k => request.includes(k))
791
+ .forEach(k => handler.call(this, control.state[k], k));
792
+ const trigger = once
793
+ ? frame => { remove(); callback(frame); }
771
794
  : callback;
772
- for (const key of set)
773
- batch[key] = handle;
774
- ensure(control, set);
795
+ ensure(control, request);
796
+ const remove = control.addListener(key => {
797
+ if (request.includes(key))
798
+ return trigger;
799
+ });
775
800
  return remove;
776
801
  }
777
802
  once(select, callback, squash) {
@@ -792,7 +817,7 @@ class Model {
792
817
  return this.on(select, invoke, true);
793
818
  }
794
819
  else {
795
- const sub = new Subscriber(control, invoke);
820
+ const sub = new Subscriber(control, () => invoke);
796
821
  target = sub.proxy;
797
822
  invoke();
798
823
  return sub.commit();
@@ -833,7 +858,7 @@ class Model {
833
858
  then(callback) {
834
859
  if (callback)
835
860
  if (control.pending)
836
- control.include(callback);
861
+ control.waiting.add(callback);
837
862
  else
838
863
  callback(false);
839
864
  else
@@ -852,8 +877,8 @@ class Model {
852
877
  manage(instance);
853
878
  return instance;
854
879
  }
855
- static new(args, callback) {
856
- const instance = useLazy(this, args, callback);
880
+ static new(callback) {
881
+ const instance = useLazy(this, callback);
857
882
  instance.update("willRender", true);
858
883
  return instance;
859
884
  }
@@ -874,19 +899,19 @@ class Model {
874
899
  static tag(id) {
875
900
  return this.find(true).tag(id);
876
901
  }
877
- static use(args, callback) {
878
- const instance = useModel(this, args, callback);
902
+ static use(callback) {
903
+ const instance = useModel(this, callback);
879
904
  useComponentLifecycle(instance[LOCAL]);
880
905
  usePeerContext(instance.get);
881
906
  return instance;
882
907
  }
883
908
  static uses(props, only) {
884
- return this.use([], instance => {
909
+ return this.use(instance => {
885
910
  instance.import(props, only);
886
911
  });
887
912
  }
888
913
  static using(props, only) {
889
- const instance = this.use([]);
914
+ const instance = this.use();
890
915
  instance.import(props, only);
891
916
  return instance;
892
917
  }
@@ -901,6 +926,7 @@ class Model {
901
926
  Model.CONTROL = CONTROL;
902
927
  Model.STATE = STATE;
903
928
  Model.LOCAL = LOCAL;
929
+ Model.WHY = UPDATE;
904
930
  defineLazy(Model, CONTROL, function () {
905
931
  return new Controller(this).start();
906
932
  });
@@ -909,7 +935,7 @@ function defer(on, method) {
909
935
  const real = subject[method];
910
936
  subject[method] = (...args) => {
911
937
  let done;
912
- waiting.push(() => {
938
+ waiting.add(() => {
913
939
  done = real.apply(subject, args);
914
940
  });
915
941
  return () => done();
@@ -921,7 +947,9 @@ const Oops$3 = issues({
921
947
  ParentRequired: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
922
948
  UnexpectedParent: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
923
949
  UndefinedNotAllowed: (key) => `Child property ${key} may not be undefined.`,
924
- BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`
950
+ BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
951
+ IsReadOnly: (owner, key) => `${owner}.${key} is set to read-only, but tried to reassign assign.`,
952
+ MustBeDefined: (owner, key) => `${owner}.${key} must have initial value, as a read-only property.`
925
953
  });
926
954
  function bootstrap(object) {
927
955
  const breakdown = getOwnPropertyDescriptors(object);
@@ -932,34 +960,44 @@ function bootstrap(object) {
932
960
  }
933
961
  function use(input, argument) {
934
962
  return child(function use(key) {
935
- let instance;
936
- const update = (next) => {
937
- instance =
938
- next instanceof Model ? next :
939
- next && bootstrap(next);
940
- if (instance) {
941
- Parent.set(instance, this.subject);
942
- manage(instance);
963
+ const { subject } = this;
964
+ // `true` => readonly
965
+ // `false` => writable, may be undefined
966
+ // `undefined` => writable (default)
967
+ let mode = argument;
968
+ let current;
969
+ const onUpdate = (next, initial) => {
970
+ if (mode === true && !initial)
971
+ throw Oops$3.IsReadOnly(subject, key);
972
+ if (next) {
973
+ current = next instanceof Model
974
+ ? next : bootstrap(next);
975
+ Parent.set(current, subject);
976
+ manage(current);
943
977
  }
944
- if (typeof argument == "function")
945
- argument(instance);
946
- else if (!instance && argument !== false)
978
+ else if (mode === undefined)
947
979
  throw Oops$3.UndefinedNotAllowed(key);
980
+ else
981
+ current = undefined;
982
+ if (typeof argument == "function")
983
+ return argument(current);
948
984
  };
949
985
  if (input) {
950
- instance =
986
+ current =
951
987
  Model.isTypeof(input) ? new input() :
952
988
  input instanceof Model ? input :
953
989
  typeof input === "function" ? input() :
954
990
  typeof input === "object" ? bootstrap(input) :
955
991
  Oops$3.BadArgument(typeof input).throw();
956
- if (instance)
957
- update(instance);
992
+ if (current)
993
+ mode = onUpdate(current, true) || mode;
994
+ else if (mode == true)
995
+ throw Oops$3.MustBeDefined(subject, key);
958
996
  }
959
997
  else
960
- argument = false;
961
- this.manage(key, instance, update);
962
- return () => instance;
998
+ mode = false;
999
+ this.manage(key, current, onUpdate);
1000
+ return () => current;
963
1001
  });
964
1002
  }
965
1003
  function parent(Expects, required) {
@@ -977,6 +1015,31 @@ function parent(Expects, required) {
977
1015
  });
978
1016
  }
979
1017
 
1018
+ function on(initial, cb) {
1019
+ return apply(function on(key) {
1020
+ this.manage(key, initial, cb && createValueEffect(cb));
1021
+ });
1022
+ }
1023
+ function memo(factory, defer) {
1024
+ return apply(function memo(key) {
1025
+ const source = this.subject;
1026
+ const get = () => factory.call(source);
1027
+ if (defer)
1028
+ defineLazy(source, key, get);
1029
+ else
1030
+ define(source, key, get());
1031
+ });
1032
+ }
1033
+ function lazy(value) {
1034
+ return apply(function lazy(key) {
1035
+ const source = this.subject;
1036
+ source[key] = value;
1037
+ defineProperty(this.state, key, {
1038
+ get: () => source[key]
1039
+ });
1040
+ });
1041
+ }
1042
+
980
1043
  const Oops$2 = issues({
981
1044
  DuplicateAction: (key) => `Invoked action ${key} but one is already active.`,
982
1045
  BadComputedSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
@@ -1003,30 +1066,6 @@ function ref(arg) {
1003
1066
  return { value };
1004
1067
  });
1005
1068
  }
1006
- function on(initial, cb) {
1007
- return apply(function on(key) {
1008
- this.manage(key, initial, cb && createValueEffect(cb));
1009
- });
1010
- }
1011
- function memo(factory, defer) {
1012
- return apply(function memo(key) {
1013
- const source = this.subject;
1014
- const get = () => factory.call(source);
1015
- if (defer)
1016
- defineLazy(source, key, get);
1017
- else
1018
- define(source, key, get());
1019
- });
1020
- }
1021
- function lazy(value) {
1022
- return apply(function lazy(key) {
1023
- const source = this.subject;
1024
- source[key] = value;
1025
- defineProperty(this.state, key, {
1026
- get: () => source[key]
1027
- });
1028
- });
1029
- }
1030
1069
  function act(task) {
1031
1070
  return apply(function act(key) {
1032
1071
  let pending = false;
@@ -1099,13 +1138,14 @@ function pendingValue(via, key) {
1099
1138
  return value;
1100
1139
  const error = Oops$1.ValueNotReady(via.subject, key);
1101
1140
  const promise = new Promise(resolve => {
1102
- const release = via.addListener({
1103
- [key](value) {
1104
- if (value !== undefined) {
1105
- release();
1106
- resolve();
1107
- }
1108
- }
1141
+ const release = via.addListener(forKey => {
1142
+ if (forKey == key)
1143
+ return () => {
1144
+ if (via.state[key] !== undefined) {
1145
+ release();
1146
+ resolve();
1147
+ }
1148
+ };
1109
1149
  });
1110
1150
  });
1111
1151
  throw Object.assign(promise, {
@@ -1212,3 +1252,4 @@ exports.pending = pending;
1212
1252
  exports.ref = ref;
1213
1253
  exports.tap = tap;
1214
1254
  exports.use = use;
1255
+ //# sourceMappingURL=index.js.map