@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.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}].`
@@ -167,7 +70,7 @@ const INFO = new WeakMap();
167
70
  const KEYS = new WeakMap();
168
71
  const ORDER = new WeakMap();
169
72
  function get(source, arg1, arg2) {
170
- return apply(function from(key) {
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 get(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 get(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 get(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 get(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,29 +475,150 @@ class Model {
628
475
  }
629
476
  }
630
477
 
631
- const PENDING = new Map();
632
- function apply(fn, label) {
633
- const name = label || fn.name || "pending";
634
- const placeholder = Symbol(`${name} instruction`);
635
- function setup(key) {
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) {
636
494
  const { subject, state } = this;
637
- const control = this;
638
- PENDING.delete(placeholder);
639
- delete subject[key];
640
- let output = fn.call(this, key, this);
641
- if (typeof output == "function")
642
- output = { get: output };
643
- if (typeof output != "object")
495
+ const { value } = getOwnPropertyDescriptor(subject, key);
496
+ if (typeof value == "function")
644
497
  return;
645
- if ("explicit" in output && output.explicit) {
646
- defineProperty(subject, key, output);
647
- return false;
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();
648
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
+
599
+ const PENDING = new Map();
600
+ function apply(fn, label) {
601
+ const name = label || fn.name || "pending";
602
+ const placeholder = Symbol(`${name} instruction`);
603
+ function setup(key) {
604
+ const { subject, state } = this;
605
+ const control = this;
606
+ PENDING.delete(placeholder);
607
+ delete subject[key];
608
+ let output = fn.call(this, key, this);
609
+ if (typeof output == "function")
610
+ output = { get: output };
611
+ if (typeof output != "object")
612
+ return;
613
+ if ("explicit" in output && output.explicit) {
614
+ defineProperty(subject, key, output);
615
+ return false;
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,106 +841,25 @@ 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
844
  const ANY = Symbol("any");
940
845
  function keyed(control, property, initial) {
846
+ const init = createProxy(emit, watch);
847
+ const frozen = new Set();
941
848
  const context = new Map();
942
849
  const users = new Map();
943
850
  const watched = new WeakMap();
944
851
  const update = new Set();
945
- const frozen = new Set();
946
- let managed;
947
- manage(initial);
948
- function reset() {
949
- frozen.clear();
950
- }
852
+ let managed = init(initial);
951
853
  function watch(on, key) {
952
854
  const include = watched.get(on);
953
855
  if (include)
954
856
  include.add(key);
955
857
  }
956
858
  function emit(key) {
957
- control.waiting.add(reset);
958
859
  control.update(property);
860
+ control.waiting.add(() => frozen.clear());
959
861
  update.forEach(notify => notify(key));
960
862
  }
961
- function manage(current) {
962
- managed = create(current);
963
- context.clear();
964
- assign(managed, {
965
- delete(key) {
966
- emit(key);
967
- return current.delete(key);
968
- },
969
- clear() {
970
- emit(ANY);
971
- current.clear();
972
- },
973
- has(key) {
974
- watch(this, key);
975
- return current.has(key);
976
- },
977
- keys() {
978
- watch(this, ANY);
979
- return current.keys();
980
- },
981
- values() {
982
- watch(this, ANY);
983
- return current.values();
984
- },
985
- entries() {
986
- watch(this, ANY);
987
- return current.entries();
988
- },
989
- [Symbol.iterator]() {
990
- watch(this, ANY);
991
- return current[Symbol.iterator]();
992
- },
993
- }, current instanceof Set
994
- ? {
995
- add(key) {
996
- current.add(key);
997
- emit(key);
998
- return this;
999
- }
1000
- }
1001
- : {
1002
- get(key) {
1003
- watch(this, ANY);
1004
- return current.get(key);
1005
- },
1006
- set(key, value) {
1007
- current.set(key, value);
1008
- emit(key);
1009
- return this;
1010
- }
1011
- });
1012
- defineProperty(managed, "size", {
1013
- get() {
1014
- watch(this, ANY);
1015
- return current.size;
1016
- }
1017
- });
1018
- }
1019
863
  function subscribe(local) {
1020
864
  const proxy = create(managed);
1021
865
  let watch = users.get(local);
@@ -1058,16 +902,90 @@ function keyed(control, property, initial) {
1058
902
  },
1059
903
  set(next) {
1060
904
  control.state.set(property, next);
1061
- manage(next);
905
+ managed = init(next);
906
+ context.clear();
1062
907
  emit(ANY);
1063
908
  },
1064
909
  destroy() {
1065
910
  update.clear();
911
+ context.clear();
1066
912
  }
1067
913
  };
914
+ }
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;
975
+ }
976
+ });
977
+ defineProperty(proxy, "size", {
978
+ get() {
979
+ watch(this, ANY);
980
+ return from.size;
981
+ }
982
+ });
983
+ return proxy;
984
+ };
1068
985
  }
1069
986
 
1070
- const Oops$5 = issues({
987
+ const Parent = new WeakMap();
988
+ const Oops$6 = issues({
1071
989
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
1072
990
  });
1073
991
  function use$1(input, argument) {
@@ -1076,7 +994,7 @@ function use$1(input, argument) {
1076
994
  if (typeof input === "function")
1077
995
  input = "prototype" in input ? new input() : input();
1078
996
  else if (input && typeof input !== "object")
1079
- throw Oops$5.BadArgument(typeof input);
997
+ throw Oops$6.BadArgument(typeof input);
1080
998
  if (input instanceof Map || input instanceof Set)
1081
999
  return keyed(this, key, input);
1082
1000
  function onUpdate(next) {
@@ -1098,6 +1016,25 @@ function use$1(input, argument) {
1098
1016
  });
1099
1017
  }
1100
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
+
1101
1038
  class Lookup {
1102
1039
  constructor() {
1103
1040
  this.table = new Map();
@@ -1382,12 +1319,12 @@ class MVC extends Model {
1382
1319
  });
1383
1320
  return instance;
1384
1321
  }, []);
1385
- usePeerContext(instance.get);
1322
+ usePeerContext(instance.is);
1386
1323
  return instance;
1387
1324
  }
1388
1325
  static use(a, b) {
1389
1326
  const instance = useModel(this, a, b);
1390
- usePeerContext(instance.get);
1327
+ usePeerContext(instance.is);
1391
1328
  return instance;
1392
1329
  }
1393
1330
  /**
@@ -1521,5 +1458,5 @@ class Global extends MVC {
1521
1458
  }
1522
1459
  }
1523
1460
 
1524
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, get as from, get, 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 };
1525
1462
  //# sourceMappingURL=index.esm.js.map