@expressive/mvc 0.4.7 → 0.5.0

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
@@ -8,31 +8,6 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
8
8
 
9
9
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
10
10
 
11
- /*! *****************************************************************************
12
- Copyright (c) Microsoft Corporation.
13
-
14
- Permission to use, copy, modify, and/or distribute this software for any
15
- purpose with or without fee is hereby granted.
16
-
17
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
18
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
19
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
20
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
21
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
22
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23
- PERFORMANCE OF THIS SOFTWARE.
24
- ***************************************************************************** */
25
-
26
- function __awaiter(thisArg, _arguments, P, generator) {
27
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
28
- return new (P || (P = Promise))(function (resolve, reject) {
29
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
30
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
31
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
32
- step((generator = generator.apply(thisArg, _arguments || [])).next());
33
- });
34
- }
35
-
36
11
  class Issue extends Error {
37
12
  constructor() {
38
13
  super(...arguments);
@@ -95,78 +70,6 @@ function mayRetry(fn) {
95
70
  }
96
71
 
97
72
  const Oops$b = issues({
98
- BadCallback: () => `Callback for effect-callback may only return a function.`
99
- });
100
- const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
101
- function define(target, key, value) {
102
- defineProperty(target, key, { value });
103
- }
104
- function defineLazy(object, property, init) {
105
- defineProperty(object, property, {
106
- configurable: true,
107
- get() {
108
- const value = init.call(this);
109
- defineProperty(this, property, { value });
110
- return value;
111
- }
112
- });
113
- }
114
- function createEffect(callback) {
115
- let unSet;
116
- return function (value) {
117
- if (typeof unSet == "function")
118
- unSet();
119
- unSet = callback.call(this, value);
120
- if (unSet instanceof Promise)
121
- unSet = undefined;
122
- if (unSet && typeof unSet !== "function")
123
- throw Oops$b.BadCallback();
124
- };
125
- }
126
- function createValueEffect(callback) {
127
- let unSet;
128
- return function (value) {
129
- if (typeof unSet == "function")
130
- unSet(value);
131
- const out = callback.call(this, value, this);
132
- if (typeof out == "boolean")
133
- return out;
134
- if (!out || out instanceof Promise)
135
- return;
136
- if (typeof out == "function")
137
- unSet = out;
138
- else
139
- throw Oops$b.BadCallback();
140
- };
141
- }
142
-
143
- function ensure(subject, cb) {
144
- let control = subject[CONTROL];
145
- if (!control) {
146
- control = new Controller(subject);
147
- define(subject, CONTROL, control);
148
- }
149
- if (!control.state) {
150
- const { waiting } = control;
151
- if (cb) {
152
- let done;
153
- waiting.add(() => {
154
- done = cb(control);
155
- });
156
- return () => done && done();
157
- }
158
- control.state = new Map();
159
- for (const key in subject)
160
- control.add(key);
161
- const callback = Array.from(waiting);
162
- waiting.clear();
163
- for (const cb of callback)
164
- cb();
165
- }
166
- return cb ? cb(control) : control;
167
- }
168
-
169
- const Oops$a = issues({
170
73
  BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
171
74
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
172
75
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
@@ -175,7 +78,7 @@ const INFO = new WeakMap();
175
78
  const KEYS = new WeakMap();
176
79
  const ORDER = new WeakMap();
177
80
  function get(source, arg1, arg2) {
178
- return apply(function from(key) {
81
+ return apply(function get(key) {
179
82
  const { subject, state } = this;
180
83
  const required = arg2 === true || arg1 === true;
181
84
  let getSource;
@@ -183,7 +86,7 @@ function get(source, arg1, arg2) {
183
86
  arg1 = undefined;
184
87
  // Easy mistake, using a peer, will always be unresolved.
185
88
  if (typeof source == "symbol")
186
- throw Oops$a.PeerNotAllowed(subject, key);
89
+ throw Oops$b.PeerNotAllowed(subject, key);
187
90
  // replace source controller in-case it is different
188
91
  if (typeof source == "object")
189
92
  getSource = () => ensure(source);
@@ -194,24 +97,23 @@ function get(source, arg1, arg2) {
194
97
  }
195
98
  // Regular function is too ambiguous so not allowed.
196
99
  else
197
- throw Oops$a.BadSource(subject, key, source);
100
+ throw Oops$b.BadSource(subject, key, source);
198
101
  const setter = arg1;
199
102
  const info = { key, parent: this };
200
103
  let sub;
201
104
  let order = ORDER.get(this);
202
105
  if (!order)
203
106
  ORDER.set(this, order = []);
204
- state.set(key, undefined);
205
107
  const compute = (initial) => {
206
108
  try {
207
109
  return setter.call(sub.proxy, sub.proxy);
208
110
  }
209
111
  catch (err) {
210
- Oops$a.Failed(subject, key, initial).warn();
112
+ Oops$b.Failed(subject, key, initial).warn();
211
113
  throw err;
212
114
  }
213
115
  };
214
- const refreshValue = () => {
116
+ const refresh = () => {
215
117
  let value;
216
118
  try {
217
119
  value = compute(false);
@@ -227,19 +129,18 @@ function get(source, arg1, arg2) {
227
129
  }
228
130
  }
229
131
  };
230
- const dependancyDidUpdate = (_key, source) => {
132
+ const update = (_key, source) => {
231
133
  if (source !== this) {
232
- refreshValue();
134
+ refresh();
233
135
  return;
234
136
  }
235
137
  let pending = KEYS.get(this);
236
138
  if (!pending)
237
139
  KEYS.set(this, pending = []);
238
- pending.push(refreshValue);
140
+ pending.push(refresh);
239
141
  };
240
142
  const create = () => {
241
- const control = getSource();
242
- sub = control.subscribe(dependancyDidUpdate);
143
+ sub = getSource().subscribe(update);
243
144
  try {
244
145
  const value = compute(true);
245
146
  state.set(key, value);
@@ -250,10 +151,11 @@ function get(source, arg1, arg2) {
250
151
  }
251
152
  finally {
252
153
  sub.commit();
253
- order.push(refreshValue);
154
+ order.push(refresh);
254
155
  }
255
156
  };
256
- INFO.set(refreshValue, info);
157
+ state.set(key, undefined);
158
+ INFO.set(refresh, info);
257
159
  return () => {
258
160
  const value = sub ? state.get(key) : create();
259
161
  if (value === undefined && required)
@@ -278,6 +180,39 @@ function flush(control) {
278
180
  KEYS.delete(control);
279
181
  }
280
182
 
183
+ const Oops$a = issues({
184
+ BadCallback: () => `Callback for effect-callback may only return a function.`
185
+ });
186
+ const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
187
+ function createEffect(callback) {
188
+ let unSet;
189
+ return function (value) {
190
+ if (typeof unSet == "function")
191
+ unSet();
192
+ unSet = callback.call(this, value);
193
+ if (unSet instanceof Promise)
194
+ unSet = undefined;
195
+ if (unSet && typeof unSet !== "function")
196
+ throw Oops$a.BadCallback();
197
+ };
198
+ }
199
+ function createValueEffect(callback) {
200
+ let unSet;
201
+ return function (value) {
202
+ if (typeof unSet == "function")
203
+ unSet(value);
204
+ const out = callback.call(this, value, this);
205
+ if (typeof out == "boolean")
206
+ return out;
207
+ if (!out || out instanceof Promise)
208
+ return;
209
+ if (typeof out == "function")
210
+ unSet = out;
211
+ else
212
+ throw Oops$a.BadCallback();
213
+ };
214
+ }
215
+
281
216
  class Subscriber {
282
217
  constructor(parent, onUpdate) {
283
218
  this.onUpdate = onUpdate;
@@ -285,7 +220,7 @@ class Subscriber {
285
220
  this.dependant = new Set();
286
221
  const proxy = create(parent.subject);
287
222
  const using = new Map();
288
- define(proxy, LOCAL, this);
223
+ defineProperty(proxy, LOCAL, { value: this });
289
224
  defineProperty(this, "proxy", {
290
225
  configurable: true,
291
226
  get() {
@@ -306,15 +241,13 @@ class Subscriber {
306
241
  }
307
242
  else if (handler === true)
308
243
  notify = this.onUpdate(key, parent);
309
- const getWhy = () => {
310
- const update = getUpdate(parent.subject);
311
- const applicable = update.filter(k => using.has(k));
312
- UPDATE.set(proxy, applicable);
244
+ if (!notify)
245
+ return;
246
+ const notate = () => {
247
+ UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
313
248
  };
314
- if (notify) {
315
- parent.waiting.add(getWhy);
316
- parent.waiting.add(notify);
317
- }
249
+ parent.waiting.add(notate);
250
+ parent.waiting.add(notify);
318
251
  });
319
252
  this.commit = () => {
320
253
  this.active = true;
@@ -334,123 +267,37 @@ class Subscriber {
334
267
  }
335
268
  }
336
269
 
337
- const UPDATE = new WeakMap();
338
- function getUpdate(subject) {
339
- return UPDATE.get(subject);
340
- }
341
- class Controller {
342
- constructor(subject) {
343
- this.subject = subject;
344
- this.frame = new Set();
345
- this.waiting = new Set();
346
- this.followers = new Set();
347
- }
348
- subscribe(callback) {
349
- return new Subscriber(this, callback);
350
- }
351
- add(key) {
352
- const { subject, state } = this;
353
- const { value } = getOwnPropertyDescriptor(subject, key);
354
- if (typeof value == "function")
355
- return;
356
- if (typeof value == "symbol") {
357
- const instruction = PENDING.get(value);
358
- if (instruction)
359
- instruction.call(this, key, this);
360
- return;
361
- }
362
- state.set(key, value);
363
- defineProperty(subject, key, {
364
- enumerable: false,
365
- set: this.ref(key),
366
- get() {
367
- const local = this[LOCAL];
368
- if (local)
369
- local.add(key);
370
- return state.get(key);
371
- }
372
- });
373
- }
374
- addListener(listener) {
375
- this.followers.add(listener);
376
- return () => {
377
- this.followers.delete(listener);
378
- };
379
- }
380
- ref(key, handler) {
381
- const { subject, state } = this;
382
- return (value) => {
383
- if (state.get(key) == value)
384
- return;
385
- if (handler)
386
- switch (handler.call(subject, value)) {
387
- case true:
388
- this.update(key);
389
- case false:
390
- return;
391
- }
392
- state.set(key, value);
393
- this.update(key);
394
- };
395
- }
396
- update(key) {
397
- const { followers, frame, subject, waiting } = this;
398
- if (frame.has(key))
399
- return;
400
- else if (!frame.size)
401
- setTimeout(() => {
402
- flush(this);
403
- UPDATE.set(subject, Array.from(frame));
404
- setTimeout(() => {
405
- UPDATE.delete(subject);
406
- }, 0);
407
- frame.clear();
408
- for (const notify of waiting)
409
- try {
410
- waiting.delete(notify);
411
- notify();
412
- }
413
- catch (err) {
414
- console.error(err);
415
- }
416
- }, 0);
417
- frame.add(key);
418
- for (const callback of followers) {
419
- const event = callback(key, this);
420
- if (typeof event == "function")
421
- waiting.add(event);
422
- }
423
- }
424
- clear() {
425
- const listeners = [...this.followers];
426
- this.followers.clear();
427
- listeners.forEach(x => x(null, this));
428
- }
429
- }
430
-
431
270
  const Oops$9 = issues({
432
271
  Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
433
272
  StrictUpdate: () => `Strict update() did not find pending updates.`,
434
273
  NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
435
274
  });
436
- const CONTROL = Symbol("CONTROL");
437
275
  const WHY = Symbol("UPDATE");
438
276
  const LOCAL = Symbol("LOCAL");
439
277
  const STATE = Symbol("STATE");
440
278
  class Model {
441
279
  constructor() {
442
- define(this, CONTROL, new Controller(this));
443
- define(this, "get", this);
444
- define(this, "is", this);
445
- defineLazy(this, "set", () => {
446
- const controller = ensure(this);
447
- const assign = (key, value) => {
448
- controller.state.set(key, value);
449
- controller.update(key);
450
- };
451
- for (const key of controller.state.keys())
452
- define(assign, key, controller.ref(key));
453
- return assign;
280
+ defineProperty(this, CONTROL, {
281
+ value: new Controller(this)
282
+ });
283
+ defineProperty(this, "is", {
284
+ value: this
285
+ });
286
+ defineProperty(this, "set", {
287
+ configurable: true,
288
+ get: () => {
289
+ const controller = ensure(this);
290
+ const value = (key, value) => {
291
+ controller.state.set(key, value);
292
+ controller.update(key);
293
+ };
294
+ for (const key of controller.state.keys())
295
+ defineProperty(value, key, {
296
+ value: controller.ref(key)
297
+ });
298
+ defineProperty(this, "set", { value });
299
+ return value;
300
+ }
454
301
  });
455
302
  }
456
303
  get [STATE]() {
@@ -636,29 +483,150 @@ class Model {
636
483
  }
637
484
  }
638
485
 
639
- const PENDING = new Map();
640
- function apply(fn, label) {
641
- const name = label || fn.name || "pending";
642
- const placeholder = Symbol(`${name} instruction`);
643
- function setup(key) {
486
+ const UPDATE = new WeakMap();
487
+ const CONTROL = Symbol("CONTROL");
488
+ function getUpdate(subject) {
489
+ return UPDATE.get(subject);
490
+ }
491
+ class Controller {
492
+ constructor(subject) {
493
+ this.subject = subject;
494
+ this.frame = new Set();
495
+ this.waiting = new Set();
496
+ this.followers = new Set();
497
+ }
498
+ subscribe(callback) {
499
+ return new Subscriber(this, callback);
500
+ }
501
+ add(key) {
644
502
  const { subject, state } = this;
645
- const control = this;
646
- PENDING.delete(placeholder);
647
- delete subject[key];
648
- let output = fn.call(this, key, this);
649
- if (typeof output == "function")
650
- output = { get: output };
651
- if (typeof output != "object")
503
+ const { value } = getOwnPropertyDescriptor(subject, key);
504
+ if (typeof value == "function")
652
505
  return;
653
- if ("explicit" in output && output.explicit) {
654
- defineProperty(subject, key, output);
655
- return false;
506
+ if (typeof value == "symbol") {
507
+ const instruction = PENDING.get(value);
508
+ if (instruction)
509
+ instruction.call(this, key, this);
510
+ return;
511
+ }
512
+ state.set(key, value);
513
+ defineProperty(subject, key, {
514
+ enumerable: false,
515
+ set: this.ref(key),
516
+ get() {
517
+ const local = this[LOCAL];
518
+ if (local)
519
+ local.add(key);
520
+ return state.get(key);
521
+ }
522
+ });
523
+ }
524
+ addListener(listener) {
525
+ this.followers.add(listener);
526
+ return () => {
527
+ this.followers.delete(listener);
528
+ };
529
+ }
530
+ ref(key, handler) {
531
+ const { subject, state } = this;
532
+ return (value) => {
533
+ if (state.get(key) == value)
534
+ return;
535
+ if (handler)
536
+ switch (handler.call(subject, value)) {
537
+ case true:
538
+ this.update(key);
539
+ case false:
540
+ return;
541
+ }
542
+ state.set(key, value);
543
+ this.update(key);
544
+ };
545
+ }
546
+ update(key) {
547
+ const { followers, frame, subject, waiting } = this;
548
+ if (frame.has(key))
549
+ return;
550
+ else if (!frame.size)
551
+ setTimeout(() => {
552
+ flush(this);
553
+ UPDATE.set(subject, Array.from(frame));
554
+ setTimeout(() => {
555
+ UPDATE.delete(subject);
556
+ }, 0);
557
+ frame.clear();
558
+ for (const notify of waiting)
559
+ try {
560
+ waiting.delete(notify);
561
+ notify();
562
+ }
563
+ catch (err) {
564
+ console.error(err);
565
+ }
566
+ }, 0);
567
+ frame.add(key);
568
+ for (const callback of followers) {
569
+ const event = callback(key, this);
570
+ if (typeof event == "function")
571
+ waiting.add(event);
572
+ }
573
+ }
574
+ clear() {
575
+ const listeners = [...this.followers];
576
+ this.followers.clear();
577
+ listeners.forEach(x => x(null, this));
578
+ }
579
+ }
580
+ function ensure(subject, cb) {
581
+ let control = subject[CONTROL];
582
+ if (!control)
583
+ defineProperty(subject, CONTROL, {
584
+ value: control =
585
+ new Controller(subject)
586
+ });
587
+ if (!control.state) {
588
+ const { waiting } = control;
589
+ if (cb) {
590
+ let done;
591
+ waiting.add(() => {
592
+ done = cb(control);
593
+ });
594
+ return () => done && done();
656
595
  }
596
+ control.state = new Map();
597
+ for (const key in subject)
598
+ control.add(key);
599
+ const callback = Array.from(waiting);
600
+ waiting.clear();
601
+ for (const cb of callback)
602
+ cb();
603
+ }
604
+ return cb ? cb(control) : control;
605
+ }
606
+
607
+ const PENDING = new Map();
608
+ function apply(fn, label) {
609
+ const name = label || fn.name || "pending";
610
+ const placeholder = Symbol(`${name} instruction`);
611
+ function setup(key) {
612
+ const { subject, state } = this;
613
+ const control = this;
614
+ PENDING.delete(placeholder);
615
+ delete subject[key];
616
+ let output = fn.call(this, key, this);
617
+ if (typeof output == "function")
618
+ output = { get: output };
619
+ if (typeof output != "object")
620
+ return;
621
+ if ("explicit" in output && output.explicit) {
622
+ defineProperty(subject, key, output);
623
+ return false;
624
+ }
625
+ let { get: onGet, set: onSet, suspense } = output;
626
+ if ("value" in output)
627
+ state.set(key, output.value);
657
628
  if ("recursive" in output && output.recursive)
658
- output = Object.assign(Object.assign({}, output), { get: getRecursive(key, this) });
659
- const desc = output;
660
- if ("value" in desc)
661
- state.set(key, desc.value);
629
+ onGet = getRecursive(key, this);
662
630
  if ("destroy" in output) {
663
631
  const { destroy } = output;
664
632
  if (destroy)
@@ -667,57 +635,84 @@ function apply(fn, label) {
667
635
  destroy();
668
636
  });
669
637
  }
670
- const { get: onGet, set: onSet, enumerable, suspense } = desc;
671
- const set = onSet !== false
672
- ? this.ref(key, onSet)
673
- : undefined;
674
- function get() {
675
- if (!state.has(key) && suspense)
676
- throw suspend(control, key);
677
- const local = this[LOCAL];
678
- if (local)
679
- local.add(key);
680
- return onGet
681
- ? onGet(local)
682
- : state.get(key);
683
- }
684
- defineProperty(subject, key, { enumerable, get, set });
638
+ defineProperty(subject, key, {
639
+ enumerable: output.enumerable,
640
+ set: onSet !== false
641
+ ? this.ref(key, onSet)
642
+ : undefined,
643
+ get() {
644
+ if (!state.has(key) && suspense)
645
+ throw suspend(control, key);
646
+ const local = this[LOCAL];
647
+ if (local)
648
+ local.add(key);
649
+ return onGet
650
+ ? onGet(local)
651
+ : state.get(key);
652
+ }
653
+ });
685
654
  }
686
655
  PENDING.set(placeholder, setup);
687
656
  return placeholder;
688
657
  }
689
658
  function getRecursive(key, from) {
690
659
  const context = new WeakMap();
691
- const { state } = from;
692
660
  return (local) => {
693
661
  if (!local)
694
- return state.get(key);
662
+ return from.state.get(key);
695
663
  if (!context.has(local)) {
696
- let child;
664
+ let reset;
697
665
  const init = () => {
698
- if (child) {
699
- child.release();
700
- local.dependant.delete(child);
701
- context.set(local, undefined);
702
- child = undefined;
703
- }
704
- const value = state.get(key);
666
+ if (reset)
667
+ reset();
668
+ const value = from.state.get(key);
705
669
  if (value && CONTROL in value) {
706
- child = ensure(value).subscribe(local.onUpdate);
670
+ const child = ensure(value).subscribe(local.onUpdate);
707
671
  if (local.active)
708
672
  child.commit();
709
673
  local.dependant.add(child);
710
674
  context.set(local, child.proxy);
675
+ reset = () => {
676
+ child.release();
677
+ local.dependant.delete(child);
678
+ context.set(local, undefined);
679
+ reset = undefined;
680
+ };
711
681
  }
712
682
  return true;
713
683
  };
714
- init();
715
684
  local.add(key, init);
685
+ init();
716
686
  }
717
687
  return context.get(local);
718
688
  };
719
689
  }
720
690
 
691
+ /*! *****************************************************************************
692
+ Copyright (c) Microsoft Corporation.
693
+
694
+ Permission to use, copy, modify, and/or distribute this software for any
695
+ purpose with or without fee is hereby granted.
696
+
697
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
698
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
699
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
700
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
701
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
702
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
703
+ PERFORMANCE OF THIS SOFTWARE.
704
+ ***************************************************************************** */
705
+
706
+ function __awaiter(thisArg, _arguments, P, generator) {
707
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
708
+ return new (P || (P = Promise))(function (resolve, reject) {
709
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
710
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
711
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
712
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
713
+ });
714
+ }
715
+
721
716
  const Oops$8 = issues({
722
717
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
723
718
  });
@@ -748,74 +743,6 @@ function act(task) {
748
743
  });
749
744
  }
750
745
 
751
- class Managed extends Array {
752
- constructor(onUpdate) {
753
- super();
754
- this.lastUpdate = [0, 0];
755
- this.update = (from, to) => {
756
- this.lastUpdate = [from, to];
757
- onUpdate();
758
- };
759
- }
760
- push(...items) {
761
- const { length } = this;
762
- const end = super.push(...items);
763
- this.update(length, end);
764
- return end;
765
- }
766
- unshift(...items) {
767
- const end = super.push(...items);
768
- this.update(0, end);
769
- return end;
770
- }
771
- splice(start, deleteCount, ...rest) {
772
- const end = deleteCount !== rest.length ? Infinity : deleteCount;
773
- this.update(start, end);
774
- return super.splice(start, deleteCount, ...rest);
775
- }
776
- }
777
- function array() {
778
- return apply(function array(key) {
779
- const context = new WeakMap();
780
- const array = new Managed(() => this.update(key));
781
- const getLocal = (context) => {
782
- const proxy = Object.create(array);
783
- let rangeA = 0;
784
- let rangeB = 0;
785
- const onUpdate = () => {
786
- const [lastA, lastB] = array.lastUpdate;
787
- if (rangeA <= lastB && rangeB >= lastA)
788
- return true;
789
- };
790
- const listen = (eventA, eventB) => {
791
- if (context.active)
792
- return;
793
- context.add(key, onUpdate);
794
- rangeA = Math.min(rangeA, eventA);
795
- rangeB = Math.max(rangeB, eventB);
796
- };
797
- proxy[Symbol.iterator] = () => {
798
- listen(0, Infinity);
799
- return array[Symbol.iterator]();
800
- };
801
- return proxy;
802
- };
803
- return {
804
- value: array,
805
- set: false,
806
- get: (local) => {
807
- if (!local)
808
- return this.state.get(key);
809
- if (context.has(local))
810
- return context.get(local);
811
- const output = getLocal(local);
812
- context.set(local, output);
813
- return output;
814
- }
815
- };
816
- });
817
- }
818
-
819
746
  function ref(callback) {
820
747
  return apply(function ref(key) {
821
748
  const value = this.ref(key, callback && createValueEffect(callback));
@@ -838,9 +765,8 @@ const Oops$7 = issues({
838
765
  function put(factory, argument) {
839
766
  return apply(function set(key) {
840
767
  const { subject, state } = this;
841
- const required = argument === true || argument === undefined;
842
- let set;
843
- let get;
768
+ const required = argument === true ||
769
+ argument === undefined;
844
770
  let pending;
845
771
  let error;
846
772
  const init = () => {
@@ -863,6 +789,14 @@ function put(factory, argument) {
863
789
  state.set(key, output);
864
790
  return output;
865
791
  };
792
+ if (required)
793
+ try {
794
+ init();
795
+ }
796
+ catch (err) {
797
+ Oops$7.Failed(subject, key).warn();
798
+ throw err;
799
+ }
866
800
  const suspend = () => {
867
801
  if (required === false)
868
802
  return undefined;
@@ -873,30 +807,21 @@ function put(factory, argument) {
873
807
  });
874
808
  throw pending;
875
809
  };
876
- if (required)
877
- try {
878
- init();
879
- }
880
- catch (err) {
881
- Oops$7.Failed(subject, key).warn();
882
- throw err;
883
- }
884
- get = () => {
810
+ const get = () => {
885
811
  if (pending)
886
812
  return suspend();
887
813
  if (error)
888
814
  throw error;
889
815
  if (state.has(key))
890
816
  return state.get(key);
891
- let output = init();
817
+ const output = init();
892
818
  return pending
893
819
  ? suspend()
894
820
  : output;
895
821
  };
896
- if (typeof argument == "function")
897
- set = createValueEffect(argument);
898
- else
899
- set = (value) => {
822
+ const set = typeof argument == "function"
823
+ ? createValueEffect(argument)
824
+ : (value) => {
900
825
  if (value === undefined && required)
901
826
  throw Oops$7.NonOptional(subject, key);
902
827
  };
@@ -924,106 +849,25 @@ function set(value, argument) {
924
849
  });
925
850
  }
926
851
 
927
- const Parent = new WeakMap();
928
- const Oops$6 = issues({
929
- Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
930
- Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
931
- });
932
- function parent(Expects, required) {
933
- return apply(function parent() {
934
- const child = this.subject;
935
- const value = Parent.get(child);
936
- const expected = Expects.name;
937
- if (!value) {
938
- if (required !== false)
939
- throw Oops$6.Required(expected, child);
940
- }
941
- else if (!(value instanceof Expects))
942
- throw Oops$6.Unexpected(expected, child, value);
943
- return { value };
944
- });
945
- }
946
-
947
852
  const ANY = Symbol("any");
948
853
  function keyed(control, property, initial) {
854
+ const init = createProxy(emit, watch);
855
+ const frozen = new Set();
949
856
  const context = new Map();
950
857
  const users = new Map();
951
858
  const watched = new WeakMap();
952
859
  const update = new Set();
953
- const frozen = new Set();
954
- let managed;
955
- manage(initial);
956
- function reset() {
957
- frozen.clear();
958
- }
860
+ let managed = init(initial);
959
861
  function watch(on, key) {
960
862
  const include = watched.get(on);
961
863
  if (include)
962
864
  include.add(key);
963
865
  }
964
866
  function emit(key) {
965
- control.waiting.add(reset);
966
867
  control.update(property);
868
+ control.waiting.add(() => frozen.clear());
967
869
  update.forEach(notify => notify(key));
968
870
  }
969
- function manage(current) {
970
- managed = create(current);
971
- context.clear();
972
- assign(managed, {
973
- delete(key) {
974
- emit(key);
975
- return current.delete(key);
976
- },
977
- clear() {
978
- emit(ANY);
979
- current.clear();
980
- },
981
- has(key) {
982
- watch(this, key);
983
- return current.has(key);
984
- },
985
- keys() {
986
- watch(this, ANY);
987
- return current.keys();
988
- },
989
- values() {
990
- watch(this, ANY);
991
- return current.values();
992
- },
993
- entries() {
994
- watch(this, ANY);
995
- return current.entries();
996
- },
997
- [Symbol.iterator]() {
998
- watch(this, ANY);
999
- return current[Symbol.iterator]();
1000
- },
1001
- }, current instanceof Set
1002
- ? {
1003
- add(key) {
1004
- current.add(key);
1005
- emit(key);
1006
- return this;
1007
- }
1008
- }
1009
- : {
1010
- get(key) {
1011
- watch(this, ANY);
1012
- return current.get(key);
1013
- },
1014
- set(key, value) {
1015
- current.set(key, value);
1016
- emit(key);
1017
- return this;
1018
- }
1019
- });
1020
- defineProperty(managed, "size", {
1021
- get() {
1022
- watch(this, ANY);
1023
- return current.size;
1024
- }
1025
- });
1026
- }
1027
871
  function subscribe(local) {
1028
872
  const proxy = create(managed);
1029
873
  let watch = users.get(local);
@@ -1066,16 +910,90 @@ function keyed(control, property, initial) {
1066
910
  },
1067
911
  set(next) {
1068
912
  control.state.set(property, next);
1069
- manage(next);
913
+ managed = init(next);
914
+ context.clear();
1070
915
  emit(ANY);
1071
916
  },
1072
917
  destroy() {
1073
918
  update.clear();
919
+ context.clear();
1074
920
  }
1075
921
  };
922
+ }
923
+ function createProxy(emit, watch) {
924
+ return (from) => {
925
+ const proxy = create(from);
926
+ assign(proxy, {
927
+ from,
928
+ delete(key) {
929
+ emit(key);
930
+ return from.delete(key);
931
+ },
932
+ clear() {
933
+ emit(ANY);
934
+ from.clear();
935
+ },
936
+ has(key) {
937
+ watch(this, key);
938
+ return from.has(key);
939
+ },
940
+ keys() {
941
+ watch(this, ANY);
942
+ return from.keys();
943
+ },
944
+ values() {
945
+ watch(this, ANY);
946
+ return from.values();
947
+ },
948
+ entries() {
949
+ watch(this, ANY);
950
+ return from.entries();
951
+ },
952
+ forEach(callbackfn, thisArg) {
953
+ const acc = [];
954
+ from.forEach((a, b, c) => {
955
+ const result = callbackfn.call(thisArg, a, b, c);
956
+ if (result !== undefined)
957
+ acc.push(result);
958
+ });
959
+ watch(this, ANY);
960
+ return acc;
961
+ },
962
+ [Symbol.iterator]() {
963
+ watch(this, ANY);
964
+ return from[Symbol.iterator]();
965
+ },
966
+ }, from instanceof Set
967
+ ? {
968
+ add(key) {
969
+ from.add(key);
970
+ emit(key);
971
+ return this;
972
+ }
973
+ }
974
+ : {
975
+ get(key) {
976
+ watch(this, ANY);
977
+ return from.get(key);
978
+ },
979
+ set(key, value) {
980
+ from.set(key, value);
981
+ emit(key);
982
+ return this;
983
+ }
984
+ });
985
+ defineProperty(proxy, "size", {
986
+ get() {
987
+ watch(this, ANY);
988
+ return from.size;
989
+ }
990
+ });
991
+ return proxy;
992
+ };
1076
993
  }
1077
994
 
1078
- const Oops$5 = issues({
995
+ const Parent = new WeakMap();
996
+ const Oops$6 = issues({
1079
997
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
1080
998
  });
1081
999
  function use$1(input, argument) {
@@ -1084,7 +1002,7 @@ function use$1(input, argument) {
1084
1002
  if (typeof input === "function")
1085
1003
  input = "prototype" in input ? new input() : input();
1086
1004
  else if (input && typeof input !== "object")
1087
- throw Oops$5.BadArgument(typeof input);
1005
+ throw Oops$6.BadArgument(typeof input);
1088
1006
  if (input instanceof Map || input instanceof Set)
1089
1007
  return keyed(this, key, input);
1090
1008
  function onUpdate(next) {
@@ -1106,6 +1024,25 @@ function use$1(input, argument) {
1106
1024
  });
1107
1025
  }
1108
1026
 
1027
+ const Oops$5 = issues({
1028
+ Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
1029
+ Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
1030
+ });
1031
+ function has(Expects, required) {
1032
+ return apply(function parent() {
1033
+ const child = this.subject;
1034
+ const value = Parent.get(child);
1035
+ const expected = Expects.name;
1036
+ if (!value) {
1037
+ if (required !== false)
1038
+ throw Oops$5.Required(expected, child);
1039
+ }
1040
+ else if (!(value instanceof Expects))
1041
+ throw Oops$5.Unexpected(expected, child, value);
1042
+ return { value };
1043
+ });
1044
+ }
1045
+
1109
1046
  class Lookup {
1110
1047
  constructor() {
1111
1048
  this.table = new Map();
@@ -1390,12 +1327,12 @@ class MVC extends Model {
1390
1327
  });
1391
1328
  return instance;
1392
1329
  }, []);
1393
- usePeerContext(instance.get);
1330
+ usePeerContext(instance.is);
1394
1331
  return instance;
1395
1332
  }
1396
1333
  static use(a, b) {
1397
1334
  const instance = useModel(this, a, b);
1398
- usePeerContext(instance.get);
1335
+ usePeerContext(instance.is);
1399
1336
  return instance;
1400
1337
  }
1401
1338
  /**
@@ -1539,11 +1476,9 @@ exports.STATE = STATE;
1539
1476
  exports.WHY = WHY;
1540
1477
  exports.act = act;
1541
1478
  exports.apply = apply;
1542
- exports.array = array;
1543
1479
  exports["default"] = MVC;
1544
- exports.from = get;
1545
1480
  exports.get = get;
1546
- exports.parent = parent;
1481
+ exports.has = has;
1547
1482
  exports.put = put;
1548
1483
  exports.ref = ref;
1549
1484
  exports.set = set;