@expressive/mvc 0.7.2 → 0.8.1

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
@@ -26,10 +26,43 @@ function issues(register) {
26
26
  }
27
27
 
28
28
  const Oops$c = issues({
29
+ BadCallback: () => `Callback for effect-callback may only return a function.`
30
+ });
31
+ const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
32
+ function createEffect(callback) {
33
+ let unSet;
34
+ return function (value) {
35
+ if (typeof unSet == "function")
36
+ unSet();
37
+ unSet = callback.call(this, value);
38
+ if (unSet instanceof Promise)
39
+ unSet = undefined;
40
+ if (unSet && typeof unSet !== "function")
41
+ throw Oops$c.BadCallback();
42
+ };
43
+ }
44
+ function createValueEffect(callback) {
45
+ let unSet;
46
+ return function (value) {
47
+ if (typeof unSet == "function")
48
+ unSet(value);
49
+ const out = callback.call(this, value, this);
50
+ if (typeof out == "boolean")
51
+ return out;
52
+ if (!out || out instanceof Promise)
53
+ return;
54
+ if (typeof out == "function")
55
+ unSet = out;
56
+ else
57
+ throw Oops$c.BadCallback();
58
+ };
59
+ }
60
+
61
+ const Oops$b = issues({
29
62
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
30
63
  });
31
64
  function suspend(source, key) {
32
- const error = Oops$c.NotReady(source.subject, key);
65
+ const error = Oops$b.NotReady(source.subject, key);
33
66
  const promise = new Promise(resolve => {
34
67
  const release = source.addListener(forKey => {
35
68
  if (forKey == key)
@@ -41,7 +74,7 @@ function suspend(source, key) {
41
74
  };
42
75
  });
43
76
  });
44
- return Object.assign(promise, {
77
+ return assign(promise, {
45
78
  toString: () => String(error),
46
79
  name: "Suspense",
47
80
  message: error.message,
@@ -69,7 +102,7 @@ function mayRetry(fn) {
69
102
  return compute();
70
103
  }
71
104
 
72
- const Oops$b = issues({
105
+ const Oops$a = issues({
73
106
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
74
107
  });
75
108
  const INFO = new WeakMap();
@@ -86,7 +119,7 @@ function computeMode(self, source, setter, key, required) {
86
119
  return setter.call(sub.proxy, sub.proxy);
87
120
  }
88
121
  catch (err) {
89
- Oops$b.Failed(subject, key, initial).warn();
122
+ Oops$a.Failed(subject, key, initial).warn();
90
123
  throw err;
91
124
  }
92
125
  };
@@ -155,266 +188,28 @@ function flush(control) {
155
188
  KEYS.delete(control);
156
189
  }
157
190
 
158
- const Oops$a = issues({
159
- BadCallback: () => `Callback for effect-callback may only return a function.`
160
- });
161
- const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
162
- function createEffect(callback) {
163
- let unSet;
164
- return function (value) {
165
- if (typeof unSet == "function")
166
- unSet();
167
- unSet = callback.call(this, value);
168
- if (unSet instanceof Promise)
169
- unSet = undefined;
170
- if (unSet && typeof unSet !== "function")
171
- throw Oops$a.BadCallback();
172
- };
173
- }
174
- function createValueEffect(callback) {
175
- let unSet;
176
- return function (value) {
177
- if (typeof unSet == "function")
178
- unSet(value);
179
- const out = callback.call(this, value, this);
180
- if (typeof out == "boolean")
181
- return out;
182
- if (!out || out instanceof Promise)
183
- return;
184
- if (typeof out == "function")
185
- unSet = out;
186
- else
187
- throw Oops$a.BadCallback();
188
- };
189
- }
190
-
191
- const Oops$9 = issues({
192
- Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
193
- StrictUpdate: () => `Strict update() did not find pending updates.`,
194
- NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
195
- });
196
- const WHY = Symbol("UPDATE");
197
- const LOCAL = Symbol("LOCAL");
198
- const STATE = Symbol("STATE");
199
- class Model {
200
- constructor() {
201
- defineProperty(this, CONTROL, {
202
- value: new Controller(this)
203
- });
204
- defineProperty(this, "is", {
205
- value: this
206
- });
207
- }
208
- get [STATE]() {
209
- return this.export();
210
- }
211
- get [WHY]() {
212
- return UPDATE.get(this);
213
- }
214
- on(select, handler, squash, once) {
215
- return ensure(this, control => {
216
- if (typeof select == "function")
217
- return control.addListener(select);
218
- const keys = typeof select == "string" ? [select] :
219
- select.length ? select : [...control.state.keys()];
220
- for (const key of keys)
221
- try {
222
- void this[key];
223
- }
224
- catch (e) { }
225
- const callback = squash
226
- ? () => {
227
- handler.call(this, getUpdate(this));
228
- }
229
- : () => {
230
- getUpdate(this)
231
- .filter(k => keys.includes(k))
232
- .forEach(k => {
233
- handler.call(this, control.state.get(k), k);
234
- });
235
- };
236
- const onEvent = once
237
- ? () => {
238
- remove();
239
- callback();
240
- }
241
- : callback;
242
- const remove = control.addListener(key => {
243
- if (keys.includes(key))
244
- return onEvent;
245
- });
246
- return remove;
247
- });
248
- }
249
- once(select, argument, squash) {
250
- if (typeof argument == "function")
251
- return this.on(select, argument, squash, true);
252
- if (typeof select == "string")
253
- select = [select];
254
- return new Promise((resolve, reject) => {
255
- const invoke = (key) => {
256
- if (!key) {
257
- clear();
258
- reject(Oops$9.Timeout(select, typeof argument == "number"
259
- ? `${argument}ms`
260
- : `lifetime of ${this}`));
261
- }
262
- else if (select.includes(key)) {
263
- clear();
264
- return resolve;
265
- }
266
- };
267
- const clear = ensure(this, x => {
268
- for (const key of select)
269
- try {
270
- void this[key];
271
- }
272
- catch (e) { }
273
- return x.addListener(invoke);
274
- });
275
- if (typeof argument == "number")
276
- setTimeout(invoke, argument);
277
- });
278
- }
279
- effect(callback, select) {
280
- const effect = createEffect(callback);
281
- return ensure(this, control => {
282
- let busy = false;
283
- let inject = this.is;
284
- const invoke = () => {
285
- if (busy)
286
- return;
287
- const output = mayRetry(() => {
288
- effect.call(inject, inject);
289
- });
290
- if (output instanceof Promise) {
291
- output.finally(() => busy = false);
292
- busy = true;
293
- }
294
- };
295
- if (!select) {
296
- const sub = control.subscribe(() => invoke);
297
- inject = sub.proxy;
298
- invoke();
299
- return sub.commit();
300
- }
301
- invoke();
302
- return control.addListener(key => {
303
- if (key === null) {
304
- if (!select.length)
305
- invoke();
306
- }
307
- else if (select.includes(key))
308
- return invoke;
309
- });
310
- });
311
- }
312
- // TODO: account for exotic properties
313
- import(source, select) {
314
- const { subject } = ensure(this);
315
- if (!select)
316
- select = getOwnPropertyNames(subject);
317
- for (const key of select)
318
- if (key in source)
319
- this[key] = source[key];
320
- }
321
- export(subset) {
322
- const { state } = ensure(this);
323
- const output = {};
324
- const keys = subset || state.keys();
325
- for (const key of keys)
326
- output[key] = state.get(key);
327
- return output;
328
- }
329
- update(arg, tag) {
330
- const target = ensure(this);
331
- const { frame, waiting } = target;
332
- if (typeof arg == "string") {
333
- target.update(arg);
334
- if (1 in arguments && arg in this) {
335
- const method = this[arg];
336
- if (typeof method == "function")
337
- if (typeof tag != "boolean")
338
- method.call(this, tag);
339
- else if (tag)
340
- method.call(this);
341
- }
342
- arg = undefined;
343
- }
344
- if (!frame.size && arg === true)
345
- return Promise.reject(Oops$9.StrictUpdate());
346
- return {
347
- then: (callback) => {
348
- if (!callback)
349
- throw Oops$9.NoChaining();
350
- if (frame.size || arg !== false)
351
- waiting.add(() => {
352
- callback(getUpdate(this));
353
- });
354
- else
355
- callback(false);
356
- }
357
- };
358
- }
359
- /**
360
- * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
361
- */
362
- destroy() {
363
- ensure(this).clear();
364
- }
365
- toString() {
366
- return this.constructor.name;
367
- }
368
- /**
369
- * Creates a new instance of this controller.
370
- *
371
- * Beyond `new this(...)`, method will activate managed-state.
372
- *
373
- * @param args - arguments sent to constructor
374
- */
375
- static create(...args) {
376
- const instance = new this(...args);
377
- ensure(instance);
378
- return instance;
379
- }
380
- /**
381
- * Static equivalent of `x instanceof this`.
382
- *
383
- * Will determine if provided class is a subtype of this one.
384
- */
385
- static isTypeof(maybe) {
386
- return (typeof maybe == "function" &&
387
- maybe.prototype instanceof this);
388
- }
389
- }
390
-
191
+ const REGISTER$1 = new WeakMap();
391
192
  class Subscriber {
392
193
  constructor(parent, onUpdate) {
194
+ this.parent = parent;
393
195
  this.onUpdate = onUpdate;
394
196
  this.active = false;
395
197
  this.dependant = new Set();
396
- const proxy = create(parent.subject);
397
- const using = new Map();
398
- const listen = this.add = (key, value) => {
399
- if (value !== undefined)
400
- using.set(key, value);
401
- else if (!using.has(key))
402
- using.set(key, true);
198
+ this.watch = new Map();
199
+ this.commit = () => {
200
+ const release = this.parent.addListener(this.event);
201
+ this.active = true;
202
+ this.dependant.forEach(x => x.commit());
203
+ return this.release = () => {
204
+ this.dependant.forEach(x => x.release());
205
+ release();
206
+ };
403
207
  };
404
- LISTEN.set(proxy, listen);
405
- defineProperty(proxy, LOCAL, { value: this });
406
- defineProperty(this, "proxy", {
407
- configurable: true,
408
- get() {
409
- if (UPDATE.has(proxy))
410
- setTimeout(() => UPDATE.delete(proxy), 0);
411
- return proxy;
412
- }
413
- });
414
- const release = parent.addListener(key => {
208
+ this.event = (key) => {
415
209
  if (!this.active)
416
210
  return;
417
- const handler = using.get(key);
211
+ const { parent, watch } = this;
212
+ const handler = watch.get(key);
418
213
  let notify;
419
214
  if (typeof handler == "function") {
420
215
  const callback = handler();
@@ -425,41 +220,59 @@ class Subscriber {
425
220
  notify = this.onUpdate(key, parent);
426
221
  if (!notify)
427
222
  return;
428
- const notate = () => {
429
- UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
430
- };
431
- parent.waiting.add(notate);
223
+ parent.waiting.add(() => {
224
+ this.latest = parent.latest.filter(k => watch.has(k));
225
+ });
432
226
  parent.waiting.add(notify);
433
- });
434
- this.commit = () => {
435
- this.active = true;
436
- this.dependant.forEach(x => x.commit());
437
- return this.release;
438
- };
439
- this.release = () => {
440
- this.dependant.forEach(x => x.release());
441
- release();
442
227
  };
228
+ const proxy = create(parent.subject);
229
+ const reset = () => this.latest = undefined;
230
+ REGISTER$1.set(proxy, this);
231
+ defineProperty(this, "proxy", {
232
+ configurable: true,
233
+ get() {
234
+ setTimeout(reset, 0);
235
+ return proxy;
236
+ }
237
+ });
238
+ }
239
+ static get(from) {
240
+ return REGISTER$1.get(from);
241
+ }
242
+ get using() {
243
+ return Array.from(this.watch.keys());
244
+ }
245
+ assign(apply, keys) {
246
+ const { waiting, subject } = this.parent;
247
+ this.active = false;
248
+ if (typeof keys !== "object")
249
+ keys = getOwnPropertyNames(subject);
250
+ for (const key of keys)
251
+ if (key in apply)
252
+ subject[key] = apply[key];
253
+ waiting.add(() => this.active = true);
254
+ }
255
+ add(key, value) {
256
+ if (value !== undefined)
257
+ this.watch.set(key, value);
258
+ else if (!this.watch.has(key))
259
+ this.watch.set(key, true);
443
260
  }
444
261
  }
445
262
 
446
- const UPDATE = new WeakMap();
447
- const LISTEN = new WeakMap();
448
- const CONTROL = Symbol("CONTROL");
449
- function getUpdate(subject) {
450
- return UPDATE.get(subject);
451
- }
452
- class Controller {
263
+ const REGISTER = new WeakMap();
264
+ class Control {
453
265
  constructor(subject) {
454
266
  this.subject = subject;
455
267
  this.frame = new Set();
456
268
  this.waiting = new Set();
457
269
  this.followers = new Set();
270
+ REGISTER.set(subject, this);
458
271
  }
459
272
  subscribe(callback) {
460
273
  return new Subscriber(this, callback);
461
274
  }
462
- add(key) {
275
+ watch(key) {
463
276
  const { subject, state } = this;
464
277
  const { value } = getOwnPropertyDescriptor(subject, key);
465
278
  if (typeof value == "function")
@@ -478,9 +291,9 @@ class Controller {
478
291
  enumerable: false,
479
292
  set: this.ref(key),
480
293
  get() {
481
- const listen = LISTEN.get(this);
482
- if (listen)
483
- listen(key);
294
+ const sub = Subscriber.get(this);
295
+ if (sub)
296
+ sub.add(key);
484
297
  return state.get(key);
485
298
  }
486
299
  });
@@ -508,16 +321,14 @@ class Controller {
508
321
  };
509
322
  }
510
323
  update(key) {
511
- const { followers, frame, subject, waiting } = this;
324
+ const { followers, frame, waiting } = this;
512
325
  if (frame.has(key))
513
326
  return;
514
327
  else if (!frame.size)
515
328
  setTimeout(() => {
516
329
  flush(this);
517
- UPDATE.set(subject, Array.from(frame));
518
- setTimeout(() => {
519
- UPDATE.delete(subject);
520
- }, 0);
330
+ this.latest = Array.from(frame);
331
+ setTimeout(() => this.latest = undefined, 0);
521
332
  frame.clear();
522
333
  for (const notify of waiting)
523
334
  try {
@@ -540,41 +351,44 @@ class Controller {
540
351
  this.followers.clear();
541
352
  listeners.forEach(x => x(null, this));
542
353
  }
543
- }
544
- function ensure(subject, cb) {
545
- let control = subject[CONTROL];
546
- if (!control)
547
- defineProperty(subject, CONTROL, {
548
- value: control =
549
- new Controller(subject)
550
- });
551
- if (!control.state) {
552
- const { waiting } = control;
553
- if (cb) {
554
- let done;
555
- waiting.add(() => {
556
- done = cb(control);
557
- });
558
- return () => done && done();
354
+ static get(from) {
355
+ if (from && "is" in from)
356
+ from = from.is;
357
+ return REGISTER.get(from);
358
+ }
359
+ static for(subject, cb) {
360
+ const control = this.get(subject) || new this(subject);
361
+ if (!control.state) {
362
+ const { waiting } = control;
363
+ if (cb) {
364
+ let done;
365
+ waiting.add(() => {
366
+ done = cb(control);
367
+ });
368
+ return () => done && done();
369
+ }
370
+ control.state = new Map();
371
+ for (const key in subject)
372
+ control.watch(key);
373
+ control.waiting = new Set();
374
+ for (const cb of waiting)
375
+ cb();
559
376
  }
560
- control.state = new Map();
561
- for (const key in subject)
562
- control.add(key);
563
- const callback = Array.from(waiting);
564
- waiting.clear();
565
- for (const cb of callback)
566
- cb();
377
+ return cb ? cb(control) : control;
567
378
  }
568
- return cb ? cb(control) : control;
569
379
  }
570
380
 
571
381
  const PENDING = new Map();
572
- function apply(fn, label) {
573
- const name = label || fn.name || "pending";
382
+ /**
383
+ * Run instruction as controller sets itself up.
384
+ * This will specialize the behavior of a given property.
385
+ */
386
+ function add(instruction, label) {
387
+ const name = label || instruction.name || "pending";
574
388
  const placeholder = Symbol(`${name} instruction`);
575
389
  function setup(key) {
576
390
  const { subject, state } = this;
577
- let output = fn.call(this, key, this);
391
+ let output = instruction.call(this, key, this);
578
392
  if (typeof output == "function")
579
393
  output = { get: output };
580
394
  if (typeof output != "object")
@@ -583,7 +397,7 @@ function apply(fn, label) {
583
397
  defineProperty(subject, key, output);
584
398
  return false;
585
399
  }
586
- let { get: onGet, set: onSet, suspense } = output;
400
+ let { get: onGet, set: onSet, suspend: shouldSuspend } = output;
587
401
  if ("value" in output)
588
402
  state.set(key, output.value);
589
403
  if ("recursive" in output && output.recursive)
@@ -603,12 +417,11 @@ function apply(fn, label) {
603
417
  ? this.ref(key, onSet)
604
418
  : undefined,
605
419
  get() {
606
- if (!state.has(key) && suspense)
420
+ if (!state.has(key) && shouldSuspend)
607
421
  throw suspend(control, key);
608
- const listen = LISTEN.get(this);
609
- const local = this[LOCAL];
610
- if (listen)
611
- listen(key);
422
+ const local = Subscriber.get(this);
423
+ if (local)
424
+ local.add(key);
612
425
  return onGet
613
426
  ? onGet(local)
614
427
  : state.get(key);
@@ -629,8 +442,8 @@ function getRecursive(key, from) {
629
442
  if (reset)
630
443
  reset();
631
444
  const value = from.state.get(key);
632
- if (value && CONTROL in value) {
633
- const child = ensure(value).subscribe(local.onUpdate);
445
+ if (Control.get(value)) {
446
+ const child = Control.for(value).subscribe(local.onUpdate);
634
447
  if (local.active)
635
448
  child.commit();
636
449
  local.dependant.add(child);
@@ -676,15 +489,15 @@ function __awaiter(thisArg, _arguments, P, generator) {
676
489
  });
677
490
  }
678
491
 
679
- const Oops$8 = issues({
492
+ const Oops$9 = issues({
680
493
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
681
494
  });
682
495
  function act(task) {
683
- return apply(function act(key) {
496
+ return add(function act(key) {
684
497
  let pending = false;
685
498
  const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
686
499
  if (pending)
687
- return Promise.reject(Oops$8.DuplicatePending(key));
500
+ return Promise.reject(Oops$9.DuplicatePending(key));
688
501
  pending = true;
689
502
  this.update(key);
690
503
  try {
@@ -727,8 +540,8 @@ function factoryMode(self, output, key, required) {
727
540
  const suspend = () => {
728
541
  if (required === false)
729
542
  return undefined;
730
- const issue = Oops$7.NotReady(subject, key);
731
- Object.assign(pending, {
543
+ const issue = Oops$8.NotReady(subject, key);
544
+ assign(pending, {
732
545
  message: issue.message,
733
546
  stack: issue.stack
734
547
  });
@@ -744,7 +557,7 @@ function factoryMode(self, output, key, required) {
744
557
  };
745
558
  }
746
559
 
747
- const Oops$7 = issues({
560
+ const Oops$8 = issues({
748
561
  // BadSource: (model, property, got) =>
749
562
  // `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
750
563
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
@@ -754,14 +567,14 @@ const Oops$7 = issues({
754
567
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
755
568
  });
756
569
  function get(arg0, arg1, arg2) {
757
- return apply(function get(key) {
570
+ return add(function get(key) {
758
571
  const { subject } = this;
759
572
  const computeRequired = arg1 === true || arg2 === true;
760
573
  const factoryRequired = arg1 !== false && arg2 !== false;
761
574
  let getter;
762
575
  // Easy mistake, using a peer, will always be unresolved.
763
576
  if (typeof arg0 == "symbol")
764
- throw Oops$7.PeerNotAllowed(subject, key);
577
+ throw Oops$8.PeerNotAllowed(subject, key);
765
578
  // if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
766
579
  // throw Oops.BadSource(subject, key, arg0);
767
580
  this.state.set(key, undefined);
@@ -783,7 +596,7 @@ function get(arg0, arg1, arg2) {
783
596
  }
784
597
  else if (typeof arg1 == "function") {
785
598
  // replace source controller in-case it is different
786
- source = ensure(arg0);
599
+ source = Control.for(arg0);
787
600
  setter = arg1;
788
601
  }
789
602
  else
@@ -795,7 +608,7 @@ function get(arg0, arg1, arg2) {
795
608
  init();
796
609
  }
797
610
  catch (err) {
798
- Oops$7.ComputeFailed(subject, key).warn();
611
+ Oops$8.ComputeFailed(subject, key).warn();
799
612
  throw err;
800
613
  }
801
614
  return () => {
@@ -807,12 +620,12 @@ function get(arg0, arg1, arg2) {
807
620
  }
808
621
 
809
622
  function ref(arg, mapper) {
810
- return apply(function ref(key) {
623
+ return add(function ref(key) {
811
624
  let value = {};
812
625
  if (typeof arg != "object")
813
626
  value = createRef(this, key, arg);
814
627
  else
815
- ensure(arg).state.forEach((_val, key) => {
628
+ Control.for(arg).state.forEach((_val, key) => {
816
629
  defineProperty(value, key, mapper ? {
817
630
  configurable: true,
818
631
  get() {
@@ -841,11 +654,11 @@ function set(value, argument) {
841
654
  argument = value;
842
655
  value = undefined;
843
656
  }
844
- return apply(function set(key) {
657
+ return add(function set(key) {
845
658
  if (value !== undefined)
846
659
  this.state.set(key, value);
847
660
  return {
848
- suspense: true,
661
+ suspend: true,
849
662
  set: typeof argument == "function"
850
663
  ? createValueEffect(argument)
851
664
  : undefined
@@ -1000,12 +813,12 @@ function createProxy(emit, watch) {
1000
813
  }
1001
814
 
1002
815
  const Parent = new WeakMap();
1003
- const Oops$6 = issues({
816
+ const Oops$7 = issues({
1004
817
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
1005
818
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
1006
819
  });
1007
820
  function use$1(input, argument) {
1008
- return apply(function use(key) {
821
+ return add(function use(key) {
1009
822
  const { state, subject } = this;
1010
823
  const required = argument !== false;
1011
824
  let pending;
@@ -1017,7 +830,7 @@ function use$1(input, argument) {
1017
830
  input = new input();
1018
831
  }
1019
832
  else if (input && typeof input !== "object")
1020
- throw Oops$6.BadArgument(typeof input);
833
+ throw Oops$7.BadArgument(typeof input);
1021
834
  if (input instanceof Map || input instanceof Set)
1022
835
  return keyed(this, key, input);
1023
836
  const onUpdate = (next) => {
@@ -1025,7 +838,7 @@ function use$1(input, argument) {
1025
838
  if (next) {
1026
839
  get = getRecursive(key, this);
1027
840
  Parent.set(next, subject);
1028
- ensure(next);
841
+ Control.for(next);
1029
842
  }
1030
843
  if (typeof argument == "function")
1031
844
  argument(next);
@@ -1034,8 +847,8 @@ function use$1(input, argument) {
1034
847
  const suspend = () => {
1035
848
  if (required === false)
1036
849
  return;
1037
- const issue = Oops$6.NotReady(subject, key);
1038
- Object.assign(pending, {
850
+ const issue = Oops$7.NotReady(subject, key);
851
+ assign(pending, {
1039
852
  message: issue.message,
1040
853
  stack: issue.stack
1041
854
  });
@@ -1079,25 +892,204 @@ function use$1(input, argument) {
1079
892
  });
1080
893
  }
1081
894
 
1082
- const Oops$5 = issues({
895
+ const Oops$6 = issues({
1083
896
  Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
1084
897
  Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
1085
898
  });
1086
- function has(Expects, required) {
1087
- return apply(function parent() {
899
+ function has(Type, required) {
900
+ return add(function parent() {
1088
901
  const child = this.subject;
1089
902
  const value = Parent.get(child);
1090
- const expected = Expects.name;
903
+ const expected = Type.name;
1091
904
  if (!value) {
1092
905
  if (required !== false)
1093
- throw Oops$5.Required(expected, child);
906
+ throw Oops$6.Required(expected, child);
1094
907
  }
1095
- else if (!(value instanceof Expects))
1096
- throw Oops$5.Unexpected(expected, child, value);
908
+ else if (!(value instanceof Type))
909
+ throw Oops$6.Unexpected(expected, child, value);
1097
910
  return { value };
1098
911
  });
1099
912
  }
1100
913
 
914
+ const Oops$5 = issues({
915
+ Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
916
+ StrictUpdate: () => `Strict update() did not find pending updates.`,
917
+ NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
918
+ });
919
+ class Model {
920
+ constructor() {
921
+ new Control(this);
922
+ defineProperty(this, "is", { value: this });
923
+ }
924
+ on(select, argument, once) {
925
+ if (typeof select == "function")
926
+ return Control.for(this, x => x.addListener(select));
927
+ const single = typeof select == "string";
928
+ let keys = single ? [select] : select;
929
+ if (typeof argument !== "function")
930
+ return new Promise((resolve, reject) => {
931
+ const removeListener = Control.for(this, control => {
932
+ for (const key of keys)
933
+ try {
934
+ void this[key];
935
+ }
936
+ catch (e) { }
937
+ return control.addListener(key => {
938
+ if (!key) {
939
+ removeListener();
940
+ reject(Oops$5.Timeout(select, `lifetime of ${this}`));
941
+ }
942
+ else if (keys.includes(key)) {
943
+ removeListener();
944
+ return () => resolve(single ? control.state.get(key) : control.latest);
945
+ }
946
+ });
947
+ });
948
+ if (typeof argument == "number")
949
+ setTimeout(() => {
950
+ removeListener();
951
+ reject(Oops$5.Timeout(select, `${argument}ms`));
952
+ }, argument);
953
+ });
954
+ return Control.for(this, control => {
955
+ if (!keys.length)
956
+ keys = [...control.state.keys()];
957
+ for (const key of keys)
958
+ try {
959
+ void this[key];
960
+ }
961
+ catch (e) { }
962
+ const callback = single
963
+ ? () => { argument.call(this, control.state.get(select), select); }
964
+ : () => { argument.call(this, control.latest); };
965
+ const onEvent = once
966
+ ? () => {
967
+ removeListener();
968
+ callback();
969
+ }
970
+ : callback;
971
+ const removeListener = control.addListener(key => {
972
+ if (keys.includes(key))
973
+ return onEvent;
974
+ });
975
+ return removeListener;
976
+ });
977
+ }
978
+ effect(callback, select) {
979
+ const effect = createEffect(callback);
980
+ return Control.for(this, control => {
981
+ let busy = false;
982
+ let inject = this.is;
983
+ const invoke = () => {
984
+ if (busy)
985
+ return;
986
+ const output = mayRetry(() => {
987
+ effect.call(inject, inject);
988
+ });
989
+ if (output instanceof Promise) {
990
+ output.finally(() => busy = false);
991
+ busy = true;
992
+ }
993
+ };
994
+ if (!select) {
995
+ const sub = control.subscribe(() => invoke);
996
+ inject = sub.proxy;
997
+ invoke();
998
+ return sub.commit();
999
+ }
1000
+ invoke();
1001
+ return control.addListener(key => {
1002
+ if (key === null) {
1003
+ if (!select.length)
1004
+ invoke();
1005
+ }
1006
+ else if (select.includes(key))
1007
+ return invoke;
1008
+ });
1009
+ });
1010
+ }
1011
+ export(subset) {
1012
+ const { state } = Control.for(this);
1013
+ const output = {};
1014
+ const keys = subset || state.keys();
1015
+ for (const key of keys)
1016
+ output[key] = state.get(key);
1017
+ return output;
1018
+ }
1019
+ update(arg1, arg2) {
1020
+ const control = Control.for(this);
1021
+ const { frame, state, waiting } = control;
1022
+ if (arg1 === true && !frame.size)
1023
+ return Promise.reject(Oops$5.StrictUpdate());
1024
+ if (typeof arg1 == "object") {
1025
+ for (const key in arg1)
1026
+ if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
1027
+ state.set(key, arg1[key]);
1028
+ control.update(key);
1029
+ }
1030
+ }
1031
+ else if (typeof arg1 == "string") {
1032
+ control.update(arg1);
1033
+ if (1 in arguments && arg1 in this) {
1034
+ const method = this[arg1];
1035
+ if (typeof method == "function")
1036
+ if (typeof arg2 != "boolean")
1037
+ method.call(this, arg2);
1038
+ else if (arg2)
1039
+ method.call(this);
1040
+ }
1041
+ arg1 = undefined;
1042
+ }
1043
+ return {
1044
+ then: (callback) => {
1045
+ if (!callback)
1046
+ throw Oops$5.NoChaining();
1047
+ if (frame.size || arg1 !== false)
1048
+ waiting.add(() => {
1049
+ callback(control.latest);
1050
+ });
1051
+ else
1052
+ callback(false);
1053
+ }
1054
+ };
1055
+ }
1056
+ /**
1057
+ * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
1058
+ */
1059
+ kill() {
1060
+ Control.for(this).clear();
1061
+ }
1062
+ /**
1063
+ * Creates a new instance of this controller.
1064
+ *
1065
+ * Beyond `new this(...)`, method will activate managed-state.
1066
+ *
1067
+ * @param args - arguments sent to constructor
1068
+ */
1069
+ static new(...args) {
1070
+ const instance = new this(...args);
1071
+ Control.for(instance);
1072
+ return instance;
1073
+ }
1074
+ /**
1075
+ * Static equivalent of `x instanceof this`.
1076
+ *
1077
+ * Will determine if provided class is a subtype of this one.
1078
+ */
1079
+ static isTypeof(maybe) {
1080
+ return (typeof maybe == "function" &&
1081
+ maybe.prototype instanceof this);
1082
+ }
1083
+ }
1084
+ defineProperty(Model.prototype, "toString", {
1085
+ value() {
1086
+ return this.constructor.name;
1087
+ }
1088
+ });
1089
+
1090
+ const Oops$4 = issues({
1091
+ NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1092
+ });
1101
1093
  class Lookup {
1102
1094
  constructor() {
1103
1095
  this.table = new Map();
@@ -1134,20 +1126,19 @@ class Lookup {
1134
1126
  } while (T !== Model);
1135
1127
  }
1136
1128
  pop() {
1129
+ const items = new Set();
1137
1130
  for (const key of getOwnPropertySymbols(this)) {
1138
1131
  const entry = getOwnPropertyDescriptor(this, key);
1139
1132
  if (entry.writable && entry.value)
1140
- entry.value.destroy();
1133
+ items.add(entry.value);
1141
1134
  }
1135
+ for (const model of items)
1136
+ model.kill();
1142
1137
  }
1143
- }
1144
-
1138
+ }
1145
1139
  const LookupContext = React__default["default"].createContext(new Lookup());
1146
1140
  const useLookup = () => React__default["default"].useContext(LookupContext);
1147
- const Oops$4 = issues({
1148
- NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1149
- });
1150
- function useLocal(Type, arg) {
1141
+ function useContext(Type, arg) {
1151
1142
  const instance = useLookup().get(Type);
1152
1143
  if (!instance && arg !== false)
1153
1144
  throw Oops$4.NotFound(Type.name);
@@ -1155,7 +1146,7 @@ function useLocal(Type, arg) {
1155
1146
  case "string":
1156
1147
  return instance[arg];
1157
1148
  case "function":
1158
- React.useLayoutEffect(() => arg(instance), []);
1149
+ React__default["default"].useLayoutEffect(() => arg(instance), []);
1159
1150
  default:
1160
1151
  return instance;
1161
1152
  }
@@ -1168,7 +1159,7 @@ const Oops$3 = issues({
1168
1159
  const PendingContext = new WeakMap();
1169
1160
  const ContextWasUsed = new WeakMap();
1170
1161
  function tap(type, argument) {
1171
- return apply(function tap(key) {
1162
+ return add(function tap(key) {
1172
1163
  if ("set" in type)
1173
1164
  return {
1174
1165
  recursive: true,
@@ -1190,7 +1181,7 @@ function tap(type, argument) {
1190
1181
  });
1191
1182
  return {
1192
1183
  recursive: true,
1193
- suspense: true
1184
+ suspend: true
1194
1185
  };
1195
1186
  });
1196
1187
  }
@@ -1225,57 +1216,45 @@ function use(init) {
1225
1216
 
1226
1217
  function useModel(source, arg, arg2) {
1227
1218
  const instance = React__default["default"].useMemo(() => {
1228
- const cb = arg2 || arg;
1229
- const instance = typeof source == "function" ?
1230
- source.prototype instanceof Model ?
1231
- new source() :
1232
- source() :
1233
- source;
1234
- ensure(instance);
1235
- if (typeof cb == "function")
1236
- cb(instance);
1219
+ const callback = arg2 || arg;
1220
+ const instance = Model.isTypeof(source) ?
1221
+ source.new() :
1222
+ source();
1223
+ Control.for(instance);
1224
+ if (typeof callback == "function")
1225
+ callback(instance);
1237
1226
  return instance;
1238
1227
  }, []);
1228
+ usePeerContext(instance);
1239
1229
  if (Array.isArray(arg)) {
1240
1230
  const update = React.useState(0)[1];
1241
1231
  React__default["default"].useLayoutEffect(() => {
1242
1232
  if (arg.length && instance instanceof Model)
1243
- instance.on(arg, () => update(x => x + 1), true);
1233
+ instance.on(arg, () => update(x => x + 1));
1244
1234
  return () => {
1245
1235
  if (Model.isTypeof(source))
1246
- instance.destroy();
1236
+ instance.kill();
1247
1237
  };
1248
1238
  }, []);
1249
1239
  return instance;
1250
1240
  }
1251
- else {
1252
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1253
- if (typeof arg == "object") {
1254
- local.active = false;
1255
- if (typeof arg2 !== "object")
1256
- arg2 = getOwnPropertyNames(instance);
1257
- for (const key of arg2)
1258
- if (key in arg)
1259
- instance[key] = arg[key];
1260
- React__default["default"].useLayoutEffect(() => {
1261
- local.active = true;
1262
- });
1263
- }
1264
- React__default["default"].useLayoutEffect(() => {
1265
- local.commit();
1266
- return () => {
1267
- local.release();
1268
- if (Model.isTypeof(source))
1269
- instance.destroy();
1270
- };
1271
- }, []);
1272
- return local.proxy;
1273
- }
1241
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1242
+ if (typeof arg == "object")
1243
+ local.assign(arg, arg2);
1244
+ React__default["default"].useLayoutEffect(() => {
1245
+ local.commit();
1246
+ return () => {
1247
+ local.release();
1248
+ if (Model.isTypeof(source))
1249
+ instance.kill();
1250
+ };
1251
+ }, []);
1252
+ return local.proxy;
1274
1253
  }
1275
1254
 
1276
1255
  function useFrom(target, compute, suspend) {
1277
1256
  const local = use(refresh => {
1278
- const sub = ensure(target).subscribe(() => update);
1257
+ const sub = Control.for(target).subscribe(() => update);
1279
1258
  const spy = sub.proxy;
1280
1259
  let value = compute.call(spy, spy);
1281
1260
  let update;
@@ -1314,84 +1293,80 @@ function useFrom(target, compute, suspend) {
1314
1293
  return local.proxy;
1315
1294
  }
1316
1295
 
1317
- function useTap(source, path, expect) {
1296
+ function useTap(source, arg1, arg2) {
1318
1297
  const instance = React.useMemo(() => {
1319
1298
  if (typeof source == "object")
1320
1299
  return () => source;
1321
- if ("get" in source)
1322
- return () => source.get();
1323
- if ("prototype" in source)
1324
- return () => useLocal(source);
1325
- else
1326
- return source;
1300
+ if (MVC.isTypeof(source))
1301
+ return () => source.get(true);
1302
+ if (Model.isTypeof(source))
1303
+ return () => useContext(source);
1304
+ return source;
1327
1305
  }, [])();
1328
- if (typeof path == "function")
1329
- return useFrom(instance, path, expect);
1330
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1306
+ if (typeof arg1 == "function")
1307
+ return useFrom(instance, arg1, arg2);
1308
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1331
1309
  React__default["default"].useLayoutEffect(local.commit, []);
1332
- if (typeof path !== "undefined") {
1333
- const value = local.proxy[path];
1334
- if (value === undefined && expect)
1335
- throw suspend(ensure(instance), path);
1336
- return value;
1337
- }
1338
- return local.proxy;
1310
+ if (arg1 === undefined)
1311
+ return local.proxy;
1312
+ const value = local.proxy[arg1];
1313
+ if (value === undefined && arg2)
1314
+ throw suspend(local.parent, arg1);
1315
+ return value;
1339
1316
  }
1340
1317
 
1341
- /* istanbul ignore file */
1342
1318
  class MVC extends Model {
1343
- tap(path, expect) {
1344
- return useTap(this, path, expect);
1345
- }
1346
- use(arg, callback) {
1347
- return useModel(this, arg, callback);
1348
- }
1349
1319
  static get(arg) {
1350
- return useLocal(this, arg);
1320
+ return useContext(this, arg);
1351
1321
  }
1352
1322
  static tap(key, expect) {
1353
1323
  return useTap(this, key, expect);
1354
1324
  }
1355
- static new(arg) {
1356
- const instance = React__default["default"].useMemo(() => {
1357
- const instance = new this();
1358
- ensure(instance);
1359
- if (typeof arg == "function")
1360
- arg(instance);
1361
- else if (arg)
1362
- getOwnPropertyNames(instance).forEach(key => {
1363
- if (key in arg)
1364
- instance[key] = arg[key];
1365
- });
1366
- return instance;
1367
- }, []);
1368
- usePeerContext(instance.is);
1369
- return instance;
1370
- }
1371
1325
  static use(a, b) {
1372
- const instance = useModel(this, a, b);
1373
- usePeerContext(instance.is);
1374
- return instance;
1375
- }
1376
- /**
1377
- * @deprecated consider doing this manually - not worth minor efficiency gain over using.
1378
- */
1379
- static uses(apply, keys) {
1380
- return this.use(instance => {
1381
- instance.import(apply, keys);
1382
- });
1383
- }
1384
- /**
1385
- * @deprecated is now replaced by overload of `use` method.
1386
- */
1387
- static using(apply, keys) {
1388
- return this.use(apply, keys);
1326
+ return useModel(this, a, b);
1389
1327
  }
1390
1328
  static meta(path, expect) {
1391
1329
  return useTap(() => this, path, expect);
1392
1330
  }
1393
1331
  }
1394
1332
 
1333
+ const LOCAL = "$debug local";
1334
+ const STATE = "$debug state";
1335
+ const UPDATE = "$debug update";
1336
+ const CONTROL = "$debug controller";
1337
+ Object.defineProperties(Model.prototype, {
1338
+ [CONTROL]: {
1339
+ get() {
1340
+ return Control.get(this);
1341
+ }
1342
+ },
1343
+ [LOCAL]: {
1344
+ get() {
1345
+ return Subscriber.get(this);
1346
+ }
1347
+ },
1348
+ [STATE]: {
1349
+ get() {
1350
+ const { state } = Control.get(this);
1351
+ const output = {};
1352
+ state.forEach((value, key) => output[key] = value);
1353
+ return output;
1354
+ }
1355
+ },
1356
+ [UPDATE]: {
1357
+ get() {
1358
+ const source = Subscriber.get(this) || Control.get(this);
1359
+ return source && source.latest;
1360
+ }
1361
+ }
1362
+ });
1363
+ const Debug = {
1364
+ CONTROL,
1365
+ LOCAL,
1366
+ STATE,
1367
+ UPDATE
1368
+ };
1369
+
1395
1370
  const Oops$2 = issues({
1396
1371
  BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
1397
1372
  });
@@ -1401,66 +1376,66 @@ function Consumer(props) {
1401
1376
  return children(useTap(type));
1402
1377
  const callback = has || get;
1403
1378
  if (typeof callback == "function")
1404
- callback(useLocal(type, !!has));
1379
+ callback(useContext(type, !!has));
1405
1380
  else
1406
1381
  throw Oops$2.BadProps();
1407
1382
  return null;
1408
1383
  }
1409
1384
 
1410
1385
  const Oops$1 = issues({
1411
- NoType: () => "Provider 'of' prop must be Model, typeof Model or a collection of them.",
1412
- PropDeprecated: () => "Provider `of` prop is deprecated, use `for` instead."
1386
+ NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
1413
1387
  });
1414
1388
  function Provider(props) {
1415
- if ("of" in props)
1416
- throw Oops$1.PropDeprecated();
1417
- const from = useLookup();
1418
- const context = React__default["default"].useMemo(() => {
1419
- const I = props.for;
1420
- if (!I)
1389
+ const context = useNewContext(props.for);
1390
+ const render = props.children;
1391
+ useAppliedProps(context, props);
1392
+ React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1393
+ return React__default["default"].createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1394
+ ? React__default["default"].createElement(RenderFunction, { context, render })
1395
+ : render);
1396
+ }
1397
+ function useNewContext(include) {
1398
+ const ambient = useLookup();
1399
+ return React__default["default"].useMemo(() => {
1400
+ if (!include)
1421
1401
  throw Oops$1.NoType();
1422
- const layer = from.push();
1402
+ const layer = ambient.push();
1423
1403
  function register(I) {
1424
1404
  if (I instanceof Model)
1425
1405
  layer.inject(I.constructor, I, false);
1426
1406
  else
1427
- layer.inject(I, I.create(), true);
1407
+ layer.inject(I, I.new(), true);
1428
1408
  }
1429
- if (I instanceof Model || typeof I == "function")
1430
- register(I);
1409
+ if (include instanceof Model || typeof include == "function")
1410
+ register(include);
1431
1411
  else
1432
- values(I).forEach(register);
1412
+ values(include).forEach(register);
1433
1413
  for (const instance of layer.local)
1434
1414
  if (instance)
1435
1415
  for (const apply of getPending(instance))
1436
1416
  apply(layer);
1437
1417
  return layer;
1438
1418
  }, []);
1439
- const render = props.children;
1440
- useAppliedProps(context, props);
1441
- React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1442
- return React__default["default"].createElement(LookupContext.Provider, { value: context }, typeof render == "function"
1443
- ? React__default["default"].createElement(RenderFunction, { context, render })
1444
- : render);
1445
1419
  }
1446
- function useAppliedProps(within, props) {
1447
- const update = React__default["default"].useMemo(() => {
1448
- const targets = within.local;
1449
- return function integrate(props) {
1450
- for (const [key, value] of entries(props))
1451
- if (!["of", "for", "children"].includes(key))
1452
- for (const into of targets)
1453
- if (into && key in into)
1454
- into[key] = value;
1420
+ function useAppliedProps(context, props) {
1421
+ const apply = React__default["default"].useMemo(() => {
1422
+ return (props) => {
1423
+ entries(props).forEach(([key, value]) => {
1424
+ if (key == "for" || key == "children")
1425
+ return;
1426
+ for (const into of context.local)
1427
+ if (into && key in into)
1428
+ into[key] = value;
1429
+ });
1455
1430
  };
1456
1431
  }, []);
1457
- update(props);
1432
+ apply(props);
1458
1433
  }
1459
1434
  function RenderFunction(props) {
1460
1435
  const hook = use(refresh => {
1461
1436
  const targets = props.context.local;
1462
1437
  if (targets.length == 1)
1463
- return ensure(targets[0]).subscribe(() => refresh);
1438
+ return Control.for(targets[0]).subscribe(() => refresh);
1464
1439
  return {};
1465
1440
  });
1466
1441
  if (hook.commit)
@@ -1469,17 +1444,31 @@ function RenderFunction(props) {
1469
1444
  }
1470
1445
 
1471
1446
  const Oops = issues({
1472
- DoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.create() before attempting to access, or consider using ${name}.use() instead.`,
1447
+ DoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.new() before attempting to access, or consider using ${name}.use() instead.`,
1473
1448
  AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
1474
1449
  });
1475
1450
  const Active = new WeakMap();
1476
1451
  class Global extends MVC {
1477
- static create(...args) {
1452
+ constructor() {
1453
+ super();
1454
+ Active.set(this.constructor, this);
1455
+ }
1456
+ kill(force) {
1457
+ const type = this.constructor;
1458
+ if (type.keepAlive && !force)
1459
+ return false;
1460
+ super.kill();
1461
+ Active.delete(type);
1462
+ return true;
1463
+ }
1464
+ static new(...args) {
1478
1465
  if (Active.has(this))
1479
- throw Oops.AlreadyExists(this.name);
1466
+ if (this.keepAlive)
1467
+ return Active.get(this);
1468
+ else
1469
+ throw Oops.AlreadyExists(this.name);
1480
1470
  const instance = new this(...args);
1481
- ensure(instance);
1482
- Active.set(this, instance);
1471
+ Control.for(instance);
1483
1472
  return instance;
1484
1473
  }
1485
1474
  /**
@@ -1487,10 +1476,8 @@ class Global extends MVC {
1487
1476
  * Returns a thenable; resolves after successful update.
1488
1477
  * If instance does not already exist, one will be created.
1489
1478
  */
1490
- static set(updates) {
1491
- const instance = Active.get(this) || this.create();
1492
- instance.import(updates);
1493
- return instance.update(false);
1479
+ static set(values) {
1480
+ return this.get(true).update(values);
1494
1481
  }
1495
1482
  static get(arg) {
1496
1483
  const instance = Active.get(this);
@@ -1504,24 +1491,19 @@ class Global extends MVC {
1504
1491
  static reset() {
1505
1492
  const current = Active.get(this);
1506
1493
  if (current)
1507
- current.destroy();
1494
+ current.kill(true);
1508
1495
  }
1509
- destroy() {
1510
- super.destroy();
1511
- Active.delete(this.constructor);
1512
- }
1513
- }
1496
+ }
1497
+ Global.keepAlive = true;
1514
1498
 
1515
- exports.CONTROL = CONTROL;
1516
1499
  exports.Consumer = Consumer;
1500
+ exports.Debug = Debug;
1517
1501
  exports.Global = Global;
1518
- exports.LOCAL = LOCAL;
1502
+ exports.MVC = MVC;
1519
1503
  exports.Model = MVC;
1520
1504
  exports.Provider = Provider;
1521
- exports.STATE = STATE;
1522
- exports.WHY = WHY;
1523
1505
  exports.act = act;
1524
- exports.apply = apply;
1506
+ exports.add = add;
1525
1507
  exports["default"] = MVC;
1526
1508
  exports.get = get;
1527
1509
  exports.has = has;
@@ -1529,8 +1511,8 @@ exports.ref = ref;
1529
1511
  exports.set = set;
1530
1512
  exports.tap = tap;
1531
1513
  exports.use = use$1;
1514
+ exports.useContext = useContext;
1532
1515
  exports.useFrom = useFrom;
1533
- exports.useLocal = useLocal;
1534
1516
  exports.useModel = useModel;
1535
1517
  exports.useTap = useTap;
1536
1518
  //# sourceMappingURL=index.js.map