@expressive/mvc 0.4.5 → 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.esm.js CHANGED
@@ -1,30 +1,5 @@
1
1
  import React, { useLayoutEffect, useState, useMemo } from 'react';
2
2
 
3
- /*! *****************************************************************************
4
- Copyright (c) Microsoft Corporation.
5
-
6
- Permission to use, copy, modify, and/or distribute this software for any
7
- purpose with or without fee is hereby granted.
8
-
9
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
- PERFORMANCE OF THIS SOFTWARE.
16
- ***************************************************************************** */
17
-
18
- function __awaiter(thisArg, _arguments, P, generator) {
19
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
20
- return new (P || (P = Promise))(function (resolve, reject) {
21
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
22
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
23
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
24
- step((generator = generator.apply(thisArg, _arguments || [])).next());
25
- });
26
- }
27
-
28
3
  class Issue extends Error {
29
4
  constructor() {
30
5
  super(...arguments);
@@ -87,78 +62,6 @@ function mayRetry(fn) {
87
62
  }
88
63
 
89
64
  const Oops$b = issues({
90
- BadCallback: () => `Callback for effect-callback may only return a function.`
91
- });
92
- const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
93
- function define(target, key, value) {
94
- defineProperty(target, key, { value });
95
- }
96
- function defineLazy(object, property, init) {
97
- defineProperty(object, property, {
98
- configurable: true,
99
- get() {
100
- const value = init.call(this);
101
- defineProperty(this, property, { value });
102
- return value;
103
- }
104
- });
105
- }
106
- function createEffect(callback) {
107
- let unSet;
108
- return function (value) {
109
- if (typeof unSet == "function")
110
- unSet();
111
- unSet = callback.call(this, value);
112
- if (unSet instanceof Promise)
113
- unSet = undefined;
114
- if (unSet && typeof unSet !== "function")
115
- throw Oops$b.BadCallback();
116
- };
117
- }
118
- function createValueEffect(callback) {
119
- let unSet;
120
- return function (value) {
121
- if (typeof unSet == "function")
122
- unSet(value);
123
- const out = callback.call(this, value, this);
124
- if (typeof out == "boolean")
125
- return out;
126
- if (!out || out instanceof Promise)
127
- return;
128
- if (typeof out == "function")
129
- unSet = out;
130
- else
131
- throw Oops$b.BadCallback();
132
- };
133
- }
134
-
135
- function ensure(subject, cb) {
136
- let control = subject[CONTROL];
137
- if (!control) {
138
- control = new Controller(subject);
139
- define(subject, CONTROL, control);
140
- }
141
- if (!control.state) {
142
- const { waiting } = control;
143
- if (cb) {
144
- let done;
145
- waiting.add(() => {
146
- done = cb(control);
147
- });
148
- return () => done && done();
149
- }
150
- control.state = new Map();
151
- for (const key in subject)
152
- control.add(key);
153
- const callback = Array.from(waiting);
154
- waiting.clear();
155
- for (const cb of callback)
156
- cb();
157
- }
158
- return cb ? cb(control) : control;
159
- }
160
-
161
- const Oops$a = issues({
162
65
  BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
163
66
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
164
67
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
@@ -166,8 +69,8 @@ const Oops$a = issues({
166
69
  const INFO = new WeakMap();
167
70
  const KEYS = new WeakMap();
168
71
  const ORDER = new WeakMap();
169
- function from(source, arg1, arg2) {
170
- return apply(function from(key) {
72
+ function get(source, arg1, arg2) {
73
+ return apply(function get(key) {
171
74
  const { subject, state } = this;
172
75
  const required = arg2 === true || arg1 === true;
173
76
  let getSource;
@@ -175,7 +78,7 @@ function from(source, arg1, arg2) {
175
78
  arg1 = undefined;
176
79
  // Easy mistake, using a peer, will always be unresolved.
177
80
  if (typeof source == "symbol")
178
- throw Oops$a.PeerNotAllowed(subject, key);
81
+ throw Oops$b.PeerNotAllowed(subject, key);
179
82
  // replace source controller in-case it is different
180
83
  if (typeof source == "object")
181
84
  getSource = () => ensure(source);
@@ -186,24 +89,23 @@ function from(source, arg1, arg2) {
186
89
  }
187
90
  // Regular function is too ambiguous so not allowed.
188
91
  else
189
- throw Oops$a.BadSource(subject, key, source);
92
+ throw Oops$b.BadSource(subject, key, source);
190
93
  const setter = arg1;
191
94
  const info = { key, parent: this };
192
95
  let sub;
193
96
  let order = ORDER.get(this);
194
97
  if (!order)
195
98
  ORDER.set(this, order = []);
196
- state.set(key, undefined);
197
99
  const compute = (initial) => {
198
100
  try {
199
101
  return setter.call(sub.proxy, sub.proxy);
200
102
  }
201
103
  catch (err) {
202
- Oops$a.Failed(subject, key, initial).warn();
104
+ Oops$b.Failed(subject, key, initial).warn();
203
105
  throw err;
204
106
  }
205
107
  };
206
- const refreshValue = () => {
108
+ const refresh = () => {
207
109
  let value;
208
110
  try {
209
111
  value = compute(false);
@@ -219,19 +121,18 @@ function from(source, arg1, arg2) {
219
121
  }
220
122
  }
221
123
  };
222
- const dependancyDidUpdate = (_key, source) => {
124
+ const update = (_key, source) => {
223
125
  if (source !== this) {
224
- refreshValue();
126
+ refresh();
225
127
  return;
226
128
  }
227
129
  let pending = KEYS.get(this);
228
130
  if (!pending)
229
131
  KEYS.set(this, pending = []);
230
- pending.push(refreshValue);
132
+ pending.push(refresh);
231
133
  };
232
134
  const create = () => {
233
- const control = getSource();
234
- sub = control.subscribe(dependancyDidUpdate);
135
+ sub = getSource().subscribe(update);
235
136
  try {
236
137
  const value = compute(true);
237
138
  state.set(key, value);
@@ -242,10 +143,11 @@ function from(source, arg1, arg2) {
242
143
  }
243
144
  finally {
244
145
  sub.commit();
245
- order.push(refreshValue);
146
+ order.push(refresh);
246
147
  }
247
148
  };
248
- INFO.set(refreshValue, info);
149
+ state.set(key, undefined);
150
+ INFO.set(refresh, info);
249
151
  return () => {
250
152
  const value = sub ? state.get(key) : create();
251
153
  if (value === undefined && required)
@@ -270,6 +172,39 @@ function flush(control) {
270
172
  KEYS.delete(control);
271
173
  }
272
174
 
175
+ const Oops$a = issues({
176
+ BadCallback: () => `Callback for effect-callback may only return a function.`
177
+ });
178
+ const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
179
+ function createEffect(callback) {
180
+ let unSet;
181
+ return function (value) {
182
+ if (typeof unSet == "function")
183
+ unSet();
184
+ unSet = callback.call(this, value);
185
+ if (unSet instanceof Promise)
186
+ unSet = undefined;
187
+ if (unSet && typeof unSet !== "function")
188
+ throw Oops$a.BadCallback();
189
+ };
190
+ }
191
+ function createValueEffect(callback) {
192
+ let unSet;
193
+ return function (value) {
194
+ if (typeof unSet == "function")
195
+ unSet(value);
196
+ const out = callback.call(this, value, this);
197
+ if (typeof out == "boolean")
198
+ return out;
199
+ if (!out || out instanceof Promise)
200
+ return;
201
+ if (typeof out == "function")
202
+ unSet = out;
203
+ else
204
+ throw Oops$a.BadCallback();
205
+ };
206
+ }
207
+
273
208
  class Subscriber {
274
209
  constructor(parent, onUpdate) {
275
210
  this.onUpdate = onUpdate;
@@ -277,7 +212,7 @@ class Subscriber {
277
212
  this.dependant = new Set();
278
213
  const proxy = create(parent.subject);
279
214
  const using = new Map();
280
- define(proxy, LOCAL, this);
215
+ defineProperty(proxy, LOCAL, { value: this });
281
216
  defineProperty(this, "proxy", {
282
217
  configurable: true,
283
218
  get() {
@@ -298,15 +233,13 @@ class Subscriber {
298
233
  }
299
234
  else if (handler === true)
300
235
  notify = this.onUpdate(key, parent);
301
- const getWhy = () => {
302
- const update = getUpdate(parent.subject);
303
- const applicable = update.filter(k => using.has(k));
304
- UPDATE.set(proxy, applicable);
236
+ if (!notify)
237
+ return;
238
+ const notate = () => {
239
+ UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
305
240
  };
306
- if (notify) {
307
- parent.waiting.add(getWhy);
308
- parent.waiting.add(notify);
309
- }
241
+ parent.waiting.add(notate);
242
+ parent.waiting.add(notify);
310
243
  });
311
244
  this.commit = () => {
312
245
  this.active = true;
@@ -326,123 +259,37 @@ class Subscriber {
326
259
  }
327
260
  }
328
261
 
329
- const UPDATE = new WeakMap();
330
- function getUpdate(subject) {
331
- return UPDATE.get(subject);
332
- }
333
- class Controller {
334
- constructor(subject) {
335
- this.subject = subject;
336
- this.frame = new Set();
337
- this.waiting = new Set();
338
- this.followers = new Set();
339
- }
340
- subscribe(callback) {
341
- return new Subscriber(this, callback);
342
- }
343
- add(key) {
344
- const { subject, state } = this;
345
- const { value } = getOwnPropertyDescriptor(subject, key);
346
- if (typeof value == "function")
347
- return;
348
- if (typeof value == "symbol") {
349
- const instruction = PENDING.get(value);
350
- if (instruction)
351
- instruction.call(this, key, this);
352
- return;
353
- }
354
- state.set(key, value);
355
- defineProperty(subject, key, {
356
- enumerable: false,
357
- set: this.ref(key),
358
- get() {
359
- const local = this[LOCAL];
360
- if (local)
361
- local.add(key);
362
- return state.get(key);
363
- }
364
- });
365
- }
366
- addListener(listener) {
367
- this.followers.add(listener);
368
- return () => {
369
- this.followers.delete(listener);
370
- };
371
- }
372
- ref(key, handler) {
373
- const { subject, state } = this;
374
- return (value) => {
375
- if (state.get(key) == value)
376
- return;
377
- if (handler)
378
- switch (handler.call(subject, value)) {
379
- case true:
380
- this.update(key);
381
- case false:
382
- return;
383
- }
384
- state.set(key, value);
385
- this.update(key);
386
- };
387
- }
388
- update(key) {
389
- const { followers, frame, subject, waiting } = this;
390
- if (frame.has(key))
391
- return;
392
- else if (!frame.size)
393
- setTimeout(() => {
394
- flush(this);
395
- UPDATE.set(subject, Array.from(frame));
396
- setTimeout(() => {
397
- UPDATE.delete(subject);
398
- }, 0);
399
- frame.clear();
400
- for (const notify of waiting)
401
- try {
402
- waiting.delete(notify);
403
- notify();
404
- }
405
- catch (err) {
406
- console.error(err);
407
- }
408
- }, 0);
409
- frame.add(key);
410
- for (const callback of followers) {
411
- const event = callback(key, this);
412
- if (typeof event == "function")
413
- waiting.add(event);
414
- }
415
- }
416
- clear() {
417
- const listeners = [...this.followers];
418
- this.followers.clear();
419
- listeners.forEach(x => x(null, this));
420
- }
421
- }
422
-
423
262
  const Oops$9 = issues({
424
263
  Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
425
264
  StrictUpdate: () => `Strict update() did not find pending updates.`,
426
265
  NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
427
266
  });
428
- const CONTROL = Symbol("CONTROL");
429
267
  const WHY = Symbol("UPDATE");
430
268
  const LOCAL = Symbol("LOCAL");
431
269
  const STATE = Symbol("STATE");
432
270
  class Model {
433
271
  constructor() {
434
- define(this, CONTROL, new Controller(this));
435
- define(this, "get", this);
436
- define(this, "is", this);
437
- defineLazy(this, "set", () => {
438
- const controller = ensure(this);
439
- const assign = (key, value) => {
440
- controller.state.set(key, value);
441
- controller.update(key);
442
- };
443
- for (const key of controller.state.keys())
444
- define(assign, key, controller.ref(key));
445
- return assign;
272
+ defineProperty(this, CONTROL, {
273
+ value: new Controller(this)
274
+ });
275
+ defineProperty(this, "is", {
276
+ value: this
277
+ });
278
+ defineProperty(this, "set", {
279
+ configurable: true,
280
+ get: () => {
281
+ const controller = ensure(this);
282
+ const value = (key, value) => {
283
+ controller.state.set(key, value);
284
+ controller.update(key);
285
+ };
286
+ for (const key of controller.state.keys())
287
+ defineProperty(value, key, {
288
+ value: controller.ref(key)
289
+ });
290
+ defineProperty(this, "set", { value });
291
+ return value;
292
+ }
446
293
  });
447
294
  }
448
295
  get [STATE]() {
@@ -628,6 +475,127 @@ class Model {
628
475
  }
629
476
  }
630
477
 
478
+ const UPDATE = new WeakMap();
479
+ const CONTROL = Symbol("CONTROL");
480
+ function getUpdate(subject) {
481
+ return UPDATE.get(subject);
482
+ }
483
+ class Controller {
484
+ constructor(subject) {
485
+ this.subject = subject;
486
+ this.frame = new Set();
487
+ this.waiting = new Set();
488
+ this.followers = new Set();
489
+ }
490
+ subscribe(callback) {
491
+ return new Subscriber(this, callback);
492
+ }
493
+ add(key) {
494
+ const { subject, state } = this;
495
+ const { value } = getOwnPropertyDescriptor(subject, key);
496
+ if (typeof value == "function")
497
+ return;
498
+ if (typeof value == "symbol") {
499
+ const instruction = PENDING.get(value);
500
+ if (instruction)
501
+ instruction.call(this, key, this);
502
+ return;
503
+ }
504
+ state.set(key, value);
505
+ defineProperty(subject, key, {
506
+ enumerable: false,
507
+ set: this.ref(key),
508
+ get() {
509
+ const local = this[LOCAL];
510
+ if (local)
511
+ local.add(key);
512
+ return state.get(key);
513
+ }
514
+ });
515
+ }
516
+ addListener(listener) {
517
+ this.followers.add(listener);
518
+ return () => {
519
+ this.followers.delete(listener);
520
+ };
521
+ }
522
+ ref(key, handler) {
523
+ const { subject, state } = this;
524
+ return (value) => {
525
+ if (state.get(key) == value)
526
+ return;
527
+ if (handler)
528
+ switch (handler.call(subject, value)) {
529
+ case true:
530
+ this.update(key);
531
+ case false:
532
+ return;
533
+ }
534
+ state.set(key, value);
535
+ this.update(key);
536
+ };
537
+ }
538
+ update(key) {
539
+ const { followers, frame, subject, waiting } = this;
540
+ if (frame.has(key))
541
+ return;
542
+ else if (!frame.size)
543
+ setTimeout(() => {
544
+ flush(this);
545
+ UPDATE.set(subject, Array.from(frame));
546
+ setTimeout(() => {
547
+ UPDATE.delete(subject);
548
+ }, 0);
549
+ frame.clear();
550
+ for (const notify of waiting)
551
+ try {
552
+ waiting.delete(notify);
553
+ notify();
554
+ }
555
+ catch (err) {
556
+ console.error(err);
557
+ }
558
+ }, 0);
559
+ frame.add(key);
560
+ for (const callback of followers) {
561
+ const event = callback(key, this);
562
+ if (typeof event == "function")
563
+ waiting.add(event);
564
+ }
565
+ }
566
+ clear() {
567
+ const listeners = [...this.followers];
568
+ this.followers.clear();
569
+ listeners.forEach(x => x(null, this));
570
+ }
571
+ }
572
+ function ensure(subject, cb) {
573
+ let control = subject[CONTROL];
574
+ if (!control)
575
+ defineProperty(subject, CONTROL, {
576
+ value: control =
577
+ new Controller(subject)
578
+ });
579
+ if (!control.state) {
580
+ const { waiting } = control;
581
+ if (cb) {
582
+ let done;
583
+ waiting.add(() => {
584
+ done = cb(control);
585
+ });
586
+ return () => done && done();
587
+ }
588
+ control.state = new Map();
589
+ for (const key in subject)
590
+ control.add(key);
591
+ const callback = Array.from(waiting);
592
+ waiting.clear();
593
+ for (const cb of callback)
594
+ cb();
595
+ }
596
+ return cb ? cb(control) : control;
597
+ }
598
+
631
599
  const PENDING = new Map();
632
600
  function apply(fn, label) {
633
601
  const name = label || fn.name || "pending";
@@ -646,11 +614,11 @@ function apply(fn, label) {
646
614
  defineProperty(subject, key, output);
647
615
  return false;
648
616
  }
617
+ let { get: onGet, set: onSet, suspense } = output;
618
+ if ("value" in output)
619
+ state.set(key, output.value);
649
620
  if ("recursive" in output && output.recursive)
650
- output = Object.assign(Object.assign({}, output), { get: getRecursive(key, this) });
651
- const desc = output;
652
- if ("value" in desc)
653
- state.set(key, desc.value);
621
+ onGet = getRecursive(key, this);
654
622
  if ("destroy" in output) {
655
623
  const { destroy } = output;
656
624
  if (destroy)
@@ -659,57 +627,84 @@ function apply(fn, label) {
659
627
  destroy();
660
628
  });
661
629
  }
662
- const { get: onGet, set: onSet, enumerable, suspense } = desc;
663
- const set = onSet !== false
664
- ? this.ref(key, onSet)
665
- : undefined;
666
- function get() {
667
- if (!state.has(key) && suspense)
668
- throw suspend(control, key);
669
- const local = this[LOCAL];
670
- if (local)
671
- local.add(key);
672
- return onGet
673
- ? onGet(local)
674
- : state.get(key);
675
- }
676
- defineProperty(subject, key, { enumerable, get, set });
630
+ defineProperty(subject, key, {
631
+ enumerable: output.enumerable,
632
+ set: onSet !== false
633
+ ? this.ref(key, onSet)
634
+ : undefined,
635
+ get() {
636
+ if (!state.has(key) && suspense)
637
+ throw suspend(control, key);
638
+ const local = this[LOCAL];
639
+ if (local)
640
+ local.add(key);
641
+ return onGet
642
+ ? onGet(local)
643
+ : state.get(key);
644
+ }
645
+ });
677
646
  }
678
647
  PENDING.set(placeholder, setup);
679
648
  return placeholder;
680
649
  }
681
650
  function getRecursive(key, from) {
682
651
  const context = new WeakMap();
683
- const { state } = from;
684
652
  return (local) => {
685
653
  if (!local)
686
- return state.get(key);
654
+ return from.state.get(key);
687
655
  if (!context.has(local)) {
688
- let child;
656
+ let reset;
689
657
  const init = () => {
690
- if (child) {
691
- child.release();
692
- local.dependant.delete(child);
693
- context.set(local, undefined);
694
- child = undefined;
695
- }
696
- const value = state.get(key);
658
+ if (reset)
659
+ reset();
660
+ const value = from.state.get(key);
697
661
  if (value && CONTROL in value) {
698
- child = ensure(value).subscribe(local.onUpdate);
662
+ const child = ensure(value).subscribe(local.onUpdate);
699
663
  if (local.active)
700
664
  child.commit();
701
665
  local.dependant.add(child);
702
666
  context.set(local, child.proxy);
667
+ reset = () => {
668
+ child.release();
669
+ local.dependant.delete(child);
670
+ context.set(local, undefined);
671
+ reset = undefined;
672
+ };
703
673
  }
704
674
  return true;
705
675
  };
706
- init();
707
676
  local.add(key, init);
677
+ init();
708
678
  }
709
679
  return context.get(local);
710
680
  };
711
681
  }
712
682
 
683
+ /*! *****************************************************************************
684
+ Copyright (c) Microsoft Corporation.
685
+
686
+ Permission to use, copy, modify, and/or distribute this software for any
687
+ purpose with or without fee is hereby granted.
688
+
689
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
690
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
691
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
692
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
693
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
694
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
695
+ PERFORMANCE OF THIS SOFTWARE.
696
+ ***************************************************************************** */
697
+
698
+ function __awaiter(thisArg, _arguments, P, generator) {
699
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
700
+ return new (P || (P = Promise))(function (resolve, reject) {
701
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
702
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
703
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
704
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
705
+ });
706
+ }
707
+
713
708
  const Oops$8 = issues({
714
709
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
715
710
  });
@@ -740,74 +735,6 @@ function act(task) {
740
735
  });
741
736
  }
742
737
 
743
- class Managed extends Array {
744
- constructor(onUpdate) {
745
- super();
746
- this.lastUpdate = [0, 0];
747
- this.update = (from, to) => {
748
- this.lastUpdate = [from, to];
749
- onUpdate();
750
- };
751
- }
752
- push(...items) {
753
- const { length } = this;
754
- const end = super.push(...items);
755
- this.update(length, end);
756
- return end;
757
- }
758
- unshift(...items) {
759
- const end = super.push(...items);
760
- this.update(0, end);
761
- return end;
762
- }
763
- splice(start, deleteCount, ...rest) {
764
- const end = deleteCount !== rest.length ? Infinity : deleteCount;
765
- this.update(start, end);
766
- return super.splice(start, deleteCount, ...rest);
767
- }
768
- }
769
- function array() {
770
- return apply(function array(key) {
771
- const context = new WeakMap();
772
- const array = new Managed(() => this.update(key));
773
- const getLocal = (context) => {
774
- const proxy = Object.create(array);
775
- let rangeA = 0;
776
- let rangeB = 0;
777
- const onUpdate = () => {
778
- const [lastA, lastB] = array.lastUpdate;
779
- if (rangeA <= lastB && rangeB >= lastA)
780
- return true;
781
- };
782
- const listen = (eventA, eventB) => {
783
- if (context.active)
784
- return;
785
- context.add(key, onUpdate);
786
- rangeA = Math.min(rangeA, eventA);
787
- rangeB = Math.max(rangeB, eventB);
788
- };
789
- proxy[Symbol.iterator] = () => {
790
- listen(0, Infinity);
791
- return array[Symbol.iterator]();
792
- };
793
- return proxy;
794
- };
795
- return {
796
- value: array,
797
- set: false,
798
- get: (local) => {
799
- if (!local)
800
- return this.state.get(key);
801
- if (context.has(local))
802
- return context.get(local);
803
- const output = getLocal(local);
804
- context.set(local, output);
805
- return output;
806
- }
807
- };
808
- });
809
- }
810
-
811
738
  function ref(callback) {
812
739
  return apply(function ref(key) {
813
740
  const value = this.ref(key, callback && createValueEffect(callback));
@@ -830,9 +757,8 @@ const Oops$7 = issues({
830
757
  function put(factory, argument) {
831
758
  return apply(function set(key) {
832
759
  const { subject, state } = this;
833
- const required = argument === true || argument === undefined;
834
- let set;
835
- let get;
760
+ const required = argument === true ||
761
+ argument === undefined;
836
762
  let pending;
837
763
  let error;
838
764
  const init = () => {
@@ -855,6 +781,14 @@ function put(factory, argument) {
855
781
  state.set(key, output);
856
782
  return output;
857
783
  };
784
+ if (required)
785
+ try {
786
+ init();
787
+ }
788
+ catch (err) {
789
+ Oops$7.Failed(subject, key).warn();
790
+ throw err;
791
+ }
858
792
  const suspend = () => {
859
793
  if (required === false)
860
794
  return undefined;
@@ -865,30 +799,21 @@ function put(factory, argument) {
865
799
  });
866
800
  throw pending;
867
801
  };
868
- if (required)
869
- try {
870
- init();
871
- }
872
- catch (err) {
873
- Oops$7.Failed(subject, key).warn();
874
- throw err;
875
- }
876
- get = () => {
802
+ const get = () => {
877
803
  if (pending)
878
804
  return suspend();
879
805
  if (error)
880
806
  throw error;
881
807
  if (state.has(key))
882
808
  return state.get(key);
883
- let output = init();
809
+ const output = init();
884
810
  return pending
885
811
  ? suspend()
886
812
  : output;
887
813
  };
888
- if (typeof argument == "function")
889
- set = createValueEffect(argument);
890
- else
891
- set = (value) => {
814
+ const set = typeof argument == "function"
815
+ ? createValueEffect(argument)
816
+ : (value) => {
892
817
  if (value === undefined && required)
893
818
  throw Oops$7.NonOptional(subject, key);
894
819
  };
@@ -916,257 +841,162 @@ function set(value, argument) {
916
841
  });
917
842
  }
918
843
 
919
- const Parent = new WeakMap();
920
- const Oops$6 = issues({
921
- Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
922
- Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
923
- });
924
- function parent(Expects, required) {
925
- return apply(function parent() {
926
- const child = this.subject;
927
- const value = Parent.get(child);
928
- const expected = Expects.name;
929
- if (!value) {
930
- if (required !== false)
931
- throw Oops$6.Required(expected, child);
932
- }
933
- else if (!(value instanceof Expects))
934
- throw Oops$6.Unexpected(expected, child, value);
935
- return { value };
936
- });
937
- }
938
-
939
- const ANY$1 = Symbol("any");
940
- function managedMap(control, property, initial) {
941
- const managed = new ManagedMap(initial, emit);
942
- const context = new WeakMap();
943
- const observers = new Set();
844
+ const ANY = Symbol("any");
845
+ function keyed(control, property, initial) {
846
+ const init = createProxy(emit, watch);
944
847
  const frozen = new Set();
945
- function reset() {
946
- frozen.clear();
848
+ const context = new Map();
849
+ const users = new Map();
850
+ const watched = new WeakMap();
851
+ const update = new Set();
852
+ let managed = init(initial);
853
+ function watch(on, key) {
854
+ const include = watched.get(on);
855
+ if (include)
856
+ include.add(key);
947
857
  }
948
858
  function emit(key) {
949
- observers.forEach(notify => notify(key));
950
859
  control.update(property);
951
- control.waiting.add(reset);
860
+ control.waiting.add(() => frozen.clear());
861
+ update.forEach(notify => notify(key));
952
862
  }
953
- function init(local) {
863
+ function subscribe(local) {
954
864
  const proxy = create(managed);
955
- const using = new Set();
956
- observers.add(key => {
957
- if (frozen.has(local))
958
- return;
959
- if (using.has(key) || using.has(ANY$1) || key === ANY$1 && using.size) {
960
- const refresh = local.onUpdate(property, control);
961
- if (refresh) {
962
- frozen.add(local);
963
- refresh();
865
+ let watch = users.get(local);
866
+ if (!watch) {
867
+ const using = watch = new Set();
868
+ users.set(local, using);
869
+ function onEvent(key) {
870
+ if (frozen.has(local))
871
+ return;
872
+ if (key === ANY || using.has(key) || using.has(ANY)) {
873
+ const refresh = local.onUpdate(property, control);
874
+ if (refresh) {
875
+ frozen.add(local);
876
+ refresh();
877
+ }
964
878
  }
965
879
  }
966
- });
967
- local.add(property, false);
880
+ local.add(property, false);
881
+ local.dependant.add({
882
+ commit() {
883
+ if (using.size === 0)
884
+ using.add(ANY);
885
+ update.add(onEvent);
886
+ },
887
+ release() {
888
+ update.delete(onEvent);
889
+ }
890
+ });
891
+ }
892
+ watched.set(proxy, watch);
968
893
  context.set(local, proxy);
969
- proxy.watch = (key) => {
970
- if (!local.active)
971
- using.add(key);
972
- };
973
894
  return proxy;
974
895
  }
975
896
  return {
976
897
  value: initial,
977
898
  get(local) {
978
- if (!local)
979
- return managed;
980
- if (context.has(local))
981
- return context.get(local);
982
- return init(local);
899
+ return local ?
900
+ context.get(local) || subscribe(local) :
901
+ managed;
983
902
  },
984
903
  set(next) {
985
- managed.source = next;
986
904
  control.state.set(property, next);
987
- emit(ANY$1);
905
+ managed = init(next);
906
+ context.clear();
907
+ emit(ANY);
988
908
  },
989
909
  destroy() {
990
- observers.clear();
910
+ update.clear();
911
+ context.clear();
991
912
  }
992
913
  };
993
914
  }
994
- class ManagedMap {
995
- constructor(source, emit) {
996
- this.source = source;
997
- this.emit = emit;
998
- }
999
- watch(_key) { }
1000
- set(key, value) {
1001
- this.source.set(key, value);
1002
- this.emit(key);
1003
- return this;
1004
- }
1005
- ;
1006
- delete(key) {
1007
- this.emit(key);
1008
- return this.source.delete(key);
1009
- }
1010
- ;
1011
- clear() {
1012
- this.emit(ANY$1);
1013
- this.source.clear();
1014
- }
1015
- get(key) {
1016
- this.watch(key);
1017
- return this.source.get(key);
1018
- }
1019
- ;
1020
- has(key) {
1021
- this.watch(key);
1022
- return this.source.has(key);
1023
- }
1024
- ;
1025
- values() {
1026
- this.watch(ANY$1);
1027
- return this.source.values();
1028
- }
1029
- keys() {
1030
- this.watch(ANY$1);
1031
- return this.source.keys();
1032
- }
1033
- entries() {
1034
- this.watch(ANY$1);
1035
- return this.source.entries();
1036
- }
1037
- ;
1038
- [Symbol.iterator]() {
1039
- this.watch(ANY$1);
1040
- return this.source[Symbol.iterator]();
1041
- }
1042
- ;
1043
- get size() {
1044
- this.watch(ANY$1);
1045
- return this.source.size;
1046
- }
1047
- }
1048
-
1049
- const ANY = Symbol("any");
1050
- function managedSet(control, property, initial) {
1051
- const managed = new ManagedSet(initial, emit);
1052
- const context = new WeakMap();
1053
- const observers = new Set();
1054
- const frozen = new Set();
1055
- function reset() {
1056
- frozen.clear();
1057
- }
1058
- function emit(key) {
1059
- observers.forEach(notify => notify(key));
1060
- control.update(property);
1061
- control.waiting.add(reset);
1062
- }
1063
- function init(local) {
1064
- const proxy = create(managed);
1065
- const using = new Set();
1066
- observers.add(key => {
1067
- if (frozen.has(local))
1068
- return;
1069
- if (using.has(key) || using.has(ANY) || key === ANY && using.size) {
1070
- const refresh = local.onUpdate(property, control);
1071
- if (refresh) {
1072
- frozen.add(local);
1073
- refresh();
915
+ function createProxy(emit, watch) {
916
+ return (from) => {
917
+ const proxy = create(from);
918
+ assign(proxy, {
919
+ from,
920
+ delete(key) {
921
+ emit(key);
922
+ return from.delete(key);
923
+ },
924
+ clear() {
925
+ emit(ANY);
926
+ from.clear();
927
+ },
928
+ has(key) {
929
+ watch(this, key);
930
+ return from.has(key);
931
+ },
932
+ keys() {
933
+ watch(this, ANY);
934
+ return from.keys();
935
+ },
936
+ values() {
937
+ watch(this, ANY);
938
+ return from.values();
939
+ },
940
+ entries() {
941
+ watch(this, ANY);
942
+ return from.entries();
943
+ },
944
+ forEach(callbackfn, thisArg) {
945
+ const acc = [];
946
+ from.forEach((a, b, c) => {
947
+ const result = callbackfn.call(thisArg, a, b, c);
948
+ if (result !== undefined)
949
+ acc.push(result);
950
+ });
951
+ watch(this, ANY);
952
+ return acc;
953
+ },
954
+ [Symbol.iterator]() {
955
+ watch(this, ANY);
956
+ return from[Symbol.iterator]();
957
+ },
958
+ }, from instanceof Set
959
+ ? {
960
+ add(key) {
961
+ from.add(key);
962
+ emit(key);
963
+ return this;
964
+ }
965
+ }
966
+ : {
967
+ get(key) {
968
+ watch(this, ANY);
969
+ return from.get(key);
970
+ },
971
+ set(key, value) {
972
+ from.set(key, value);
973
+ emit(key);
974
+ return this;
1074
975
  }
976
+ });
977
+ defineProperty(proxy, "size", {
978
+ get() {
979
+ watch(this, ANY);
980
+ return from.size;
1075
981
  }
1076
982
  });
1077
- local.add(property, false);
1078
- context.set(local, proxy);
1079
- proxy.watch = (key) => {
1080
- if (!local.active)
1081
- using.add(key);
1082
- };
1083
983
  return proxy;
1084
- }
1085
- return {
1086
- value: initial,
1087
- get(local) {
1088
- if (!local)
1089
- return managed;
1090
- if (context.has(local))
1091
- return context.get(local);
1092
- return init(local);
1093
- },
1094
- set(next) {
1095
- managed.source = next;
1096
- control.state.set(property, next);
1097
- emit(ANY);
1098
- },
1099
- destroy() {
1100
- observers.clear();
1101
- }
1102
984
  };
1103
- }
1104
- class ManagedSet {
1105
- constructor(source, emit) {
1106
- this.source = source;
1107
- this.emit = emit;
1108
- }
1109
- watch(_key) { }
1110
- add(key) {
1111
- this.source.add(key);
1112
- this.emit(key);
1113
- return this;
1114
- }
1115
- ;
1116
- delete(key) {
1117
- this.emit(key);
1118
- return this.source.delete(key);
1119
- }
1120
- ;
1121
- clear() {
1122
- this.emit(ANY);
1123
- this.source.clear();
1124
- }
1125
- has(key) {
1126
- this.watch(key);
1127
- return this.source.has(key);
1128
- }
1129
- ;
1130
- values() {
1131
- this.watch(ANY);
1132
- return this.source.values();
1133
- }
1134
- keys() {
1135
- this.watch(ANY);
1136
- return this.source.keys();
1137
- }
1138
- entries() {
1139
- this.watch(ANY);
1140
- return this.source.entries();
1141
- }
1142
- ;
1143
- [Symbol.iterator]() {
1144
- this.watch(ANY);
1145
- return this.source[Symbol.iterator]();
1146
- }
1147
- ;
1148
- get size() {
1149
- this.watch(ANY);
1150
- return this.source.size;
1151
- }
1152
985
  }
1153
986
 
1154
- const Oops$5 = issues({
987
+ const Parent = new WeakMap();
988
+ const Oops$6 = issues({
1155
989
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
1156
990
  });
1157
991
  function use$1(input, argument) {
1158
992
  return apply(function use(key) {
1159
993
  const { state, subject } = this;
1160
994
  if (typeof input === "function")
1161
- input = Model.isTypeof(input)
1162
- ? new input()
1163
- : input();
995
+ input = "prototype" in input ? new input() : input();
1164
996
  else if (input && typeof input !== "object")
1165
- throw Oops$5.BadArgument(typeof input);
1166
- if (input instanceof Map)
1167
- return managedMap(this, key, input);
1168
- if (input instanceof Set)
1169
- return managedSet(this, key, input);
997
+ throw Oops$6.BadArgument(typeof input);
998
+ if (input instanceof Map || input instanceof Set)
999
+ return keyed(this, key, input);
1170
1000
  function onUpdate(next) {
1171
1001
  state.set(key, next);
1172
1002
  if (next) {
@@ -1186,6 +1016,25 @@ function use$1(input, argument) {
1186
1016
  });
1187
1017
  }
1188
1018
 
1019
+ const Oops$5 = issues({
1020
+ Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
1021
+ Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
1022
+ });
1023
+ function has(Expects, required) {
1024
+ return apply(function parent() {
1025
+ const child = this.subject;
1026
+ const value = Parent.get(child);
1027
+ const expected = Expects.name;
1028
+ if (!value) {
1029
+ if (required !== false)
1030
+ throw Oops$5.Required(expected, child);
1031
+ }
1032
+ else if (!(value instanceof Expects))
1033
+ throw Oops$5.Unexpected(expected, child, value);
1034
+ return { value };
1035
+ });
1036
+ }
1037
+
1189
1038
  class Lookup {
1190
1039
  constructor() {
1191
1040
  this.table = new Map();
@@ -1470,12 +1319,12 @@ class MVC extends Model {
1470
1319
  });
1471
1320
  return instance;
1472
1321
  }, []);
1473
- usePeerContext(instance.get);
1322
+ usePeerContext(instance.is);
1474
1323
  return instance;
1475
1324
  }
1476
1325
  static use(a, b) {
1477
1326
  const instance = useModel(this, a, b);
1478
- usePeerContext(instance.get);
1327
+ usePeerContext(instance.is);
1479
1328
  return instance;
1480
1329
  }
1481
1330
  /**
@@ -1609,5 +1458,5 @@ class Global extends MVC {
1609
1458
  }
1610
1459
  }
1611
1460
 
1612
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1461
+ export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, MVC as default, get, has, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1613
1462
  //# sourceMappingURL=index.esm.js.map