@expressive/mvc 0.7.1 → 0.8.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,4 +1,4 @@
1
- import React, { useLayoutEffect, useState, useMemo } from 'react';
1
+ import React, { useState, useMemo } from 'react';
2
2
 
3
3
  class Issue extends Error {
4
4
  constructor() {
@@ -18,10 +18,43 @@ function issues(register) {
18
18
  }
19
19
 
20
20
  const Oops$c = issues({
21
+ BadCallback: () => `Callback for effect-callback may only return a function.`
22
+ });
23
+ const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
24
+ function createEffect(callback) {
25
+ let unSet;
26
+ return function (value) {
27
+ if (typeof unSet == "function")
28
+ unSet();
29
+ unSet = callback.call(this, value);
30
+ if (unSet instanceof Promise)
31
+ unSet = undefined;
32
+ if (unSet && typeof unSet !== "function")
33
+ throw Oops$c.BadCallback();
34
+ };
35
+ }
36
+ function createValueEffect(callback) {
37
+ let unSet;
38
+ return function (value) {
39
+ if (typeof unSet == "function")
40
+ unSet(value);
41
+ const out = callback.call(this, value, this);
42
+ if (typeof out == "boolean")
43
+ return out;
44
+ if (!out || out instanceof Promise)
45
+ return;
46
+ if (typeof out == "function")
47
+ unSet = out;
48
+ else
49
+ throw Oops$c.BadCallback();
50
+ };
51
+ }
52
+
53
+ const Oops$b = issues({
21
54
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
22
55
  });
23
56
  function suspend(source, key) {
24
- const error = Oops$c.NotReady(source.subject, key);
57
+ const error = Oops$b.NotReady(source.subject, key);
25
58
  const promise = new Promise(resolve => {
26
59
  const release = source.addListener(forKey => {
27
60
  if (forKey == key)
@@ -33,7 +66,7 @@ function suspend(source, key) {
33
66
  };
34
67
  });
35
68
  });
36
- return Object.assign(promise, {
69
+ return assign(promise, {
37
70
  toString: () => String(error),
38
71
  name: "Suspense",
39
72
  message: error.message,
@@ -61,7 +94,7 @@ function mayRetry(fn) {
61
94
  return compute();
62
95
  }
63
96
 
64
- const Oops$b = issues({
97
+ const Oops$a = issues({
65
98
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
66
99
  });
67
100
  const INFO = new WeakMap();
@@ -78,7 +111,7 @@ function computeMode(self, source, setter, key, required) {
78
111
  return setter.call(sub.proxy, sub.proxy);
79
112
  }
80
113
  catch (err) {
81
- Oops$b.Failed(subject, key, initial).warn();
114
+ Oops$a.Failed(subject, key, initial).warn();
82
115
  throw err;
83
116
  }
84
117
  };
@@ -147,259 +180,20 @@ function flush(control) {
147
180
  KEYS.delete(control);
148
181
  }
149
182
 
150
- const Oops$a = issues({
151
- BadCallback: () => `Callback for effect-callback may only return a function.`
152
- });
153
- const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
154
- function createEffect(callback) {
155
- let unSet;
156
- return function (value) {
157
- if (typeof unSet == "function")
158
- unSet();
159
- unSet = callback.call(this, value);
160
- if (unSet instanceof Promise)
161
- unSet = undefined;
162
- if (unSet && typeof unSet !== "function")
163
- throw Oops$a.BadCallback();
164
- };
165
- }
166
- function createValueEffect(callback) {
167
- let unSet;
168
- return function (value) {
169
- if (typeof unSet == "function")
170
- unSet(value);
171
- const out = callback.call(this, value, this);
172
- if (typeof out == "boolean")
173
- return out;
174
- if (!out || out instanceof Promise)
175
- return;
176
- if (typeof out == "function")
177
- unSet = out;
178
- else
179
- throw Oops$a.BadCallback();
180
- };
181
- }
182
-
183
- const Oops$9 = issues({
184
- Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
185
- StrictUpdate: () => `Strict update() did not find pending updates.`,
186
- NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
187
- });
188
- const WHY = Symbol("UPDATE");
189
- const LOCAL = Symbol("LOCAL");
190
- const STATE = Symbol("STATE");
191
- class Model {
192
- constructor() {
193
- defineProperty(this, CONTROL, {
194
- value: new Controller(this)
195
- });
196
- defineProperty(this, "is", {
197
- value: this
198
- });
199
- }
200
- get [STATE]() {
201
- return this.export();
202
- }
203
- get [WHY]() {
204
- return UPDATE.get(this);
205
- }
206
- on(select, handler, squash, once) {
207
- return ensure(this, control => {
208
- if (typeof select == "function")
209
- return control.addListener(select);
210
- const keys = typeof select == "string" ? [select] :
211
- select.length ? select : [...control.state.keys()];
212
- for (const key of keys)
213
- try {
214
- void this[key];
215
- }
216
- catch (e) { }
217
- const callback = squash
218
- ? () => {
219
- handler.call(this, getUpdate(this));
220
- }
221
- : () => {
222
- getUpdate(this)
223
- .filter(k => keys.includes(k))
224
- .forEach(k => {
225
- handler.call(this, control.state.get(k), k);
226
- });
227
- };
228
- const onEvent = once
229
- ? () => {
230
- remove();
231
- callback();
232
- }
233
- : callback;
234
- const remove = control.addListener(key => {
235
- if (keys.includes(key))
236
- return onEvent;
237
- });
238
- return remove;
239
- });
240
- }
241
- once(select, argument, squash) {
242
- if (typeof argument == "function")
243
- return this.on(select, argument, squash, true);
244
- if (typeof select == "string")
245
- select = [select];
246
- return new Promise((resolve, reject) => {
247
- const invoke = (key) => {
248
- if (!key) {
249
- clear();
250
- reject(Oops$9.Timeout(select, typeof argument == "number"
251
- ? `${argument}ms`
252
- : `lifetime of ${this}`));
253
- }
254
- else if (select.includes(key)) {
255
- clear();
256
- return resolve;
257
- }
258
- };
259
- const clear = ensure(this, x => {
260
- for (const key of select)
261
- try {
262
- void this[key];
263
- }
264
- catch (e) { }
265
- return x.addListener(invoke);
266
- });
267
- if (typeof argument == "number")
268
- setTimeout(invoke, argument);
269
- });
270
- }
271
- effect(callback, select) {
272
- const effect = createEffect(callback);
273
- return ensure(this, control => {
274
- let busy = false;
275
- let inject = this.is;
276
- const invoke = () => {
277
- if (busy)
278
- return;
279
- const output = mayRetry(() => {
280
- effect.call(inject, inject);
281
- });
282
- if (output instanceof Promise) {
283
- output.finally(() => busy = false);
284
- busy = true;
285
- }
286
- };
287
- if (!select) {
288
- const sub = control.subscribe(() => invoke);
289
- inject = sub.proxy;
290
- invoke();
291
- return sub.commit();
292
- }
293
- invoke();
294
- return control.addListener(key => {
295
- if (key === null) {
296
- if (!select.length)
297
- invoke();
298
- }
299
- else if (select.includes(key))
300
- return invoke;
301
- });
302
- });
303
- }
304
- // TODO: account for exotic properties
305
- import(source, select) {
306
- const { subject } = ensure(this);
307
- if (!select)
308
- select = getOwnPropertyNames(subject);
309
- for (const key of select)
310
- if (key in source)
311
- this[key] = source[key];
312
- }
313
- export(subset) {
314
- const { state } = ensure(this);
315
- const output = {};
316
- const keys = subset || state.keys();
317
- for (const key of keys)
318
- output[key] = state.get(key);
319
- return output;
320
- }
321
- update(arg, tag) {
322
- const target = ensure(this);
323
- const { frame, waiting } = target;
324
- if (typeof arg == "string") {
325
- target.update(arg);
326
- if (1 in arguments && arg in this) {
327
- const method = this[arg];
328
- if (typeof method == "function")
329
- if (typeof tag != "boolean")
330
- method.call(this, tag);
331
- else if (tag)
332
- method.call(this);
333
- }
334
- arg = undefined;
335
- }
336
- if (!frame.size && arg === true)
337
- return Promise.reject(Oops$9.StrictUpdate());
338
- return {
339
- then: (callback) => {
340
- if (!callback)
341
- throw Oops$9.NoChaining();
342
- if (frame.size || arg !== false)
343
- waiting.add(() => {
344
- callback(getUpdate(this));
345
- });
346
- else
347
- callback(false);
348
- }
349
- };
350
- }
351
- /**
352
- * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
353
- */
354
- destroy() {
355
- ensure(this).clear();
356
- }
357
- toString() {
358
- return this.constructor.name;
359
- }
360
- /**
361
- * Creates a new instance of this controller.
362
- *
363
- * Beyond `new this(...)`, method will activate managed-state.
364
- *
365
- * @param args - arguments sent to constructor
366
- */
367
- static create(...args) {
368
- const instance = new this(...args);
369
- ensure(instance);
370
- return instance;
371
- }
372
- /**
373
- * Static equivalent of `x instanceof this`.
374
- *
375
- * Will determine if provided class is a subtype of this one.
376
- */
377
- static isTypeof(maybe) {
378
- return (typeof maybe == "function" &&
379
- maybe.prototype instanceof this);
380
- }
381
- }
382
-
183
+ const REGISTER$1 = new WeakMap();
383
184
  class Subscriber {
384
185
  constructor(parent, onUpdate) {
186
+ this.parent = parent;
385
187
  this.onUpdate = onUpdate;
386
188
  this.active = false;
387
189
  this.dependant = new Set();
388
190
  const proxy = create(parent.subject);
389
191
  const using = new Map();
390
- const listen = this.add = (key, value) => {
391
- if (value !== undefined)
392
- using.set(key, value);
393
- else if (!using.has(key))
394
- using.set(key, true);
395
- };
396
- LISTEN.set(proxy, listen);
397
- defineProperty(proxy, LOCAL, { value: this });
192
+ REGISTER$1.set(proxy, this);
398
193
  defineProperty(this, "proxy", {
399
194
  configurable: true,
400
195
  get() {
401
- if (UPDATE.has(proxy))
402
- setTimeout(() => UPDATE.delete(proxy), 0);
196
+ hasUpdate(proxy);
403
197
  return proxy;
404
198
  }
405
199
  });
@@ -417,12 +211,15 @@ class Subscriber {
417
211
  notify = this.onUpdate(key, parent);
418
212
  if (!notify)
419
213
  return;
420
- const notate = () => {
421
- UPDATE.set(proxy, getUpdate(parent.subject).filter(k => using.has(k)));
422
- };
423
- parent.waiting.add(notate);
214
+ parent.waiting.add(() => addUpdate(proxy, using));
424
215
  parent.waiting.add(notify);
425
216
  });
217
+ this.add = (key, value) => {
218
+ if (value !== undefined)
219
+ using.set(key, value);
220
+ else if (!using.has(key))
221
+ using.set(key, true);
222
+ };
426
223
  this.commit = () => {
427
224
  this.active = true;
428
225
  this.dependant.forEach(x => x.commit());
@@ -433,25 +230,42 @@ class Subscriber {
433
230
  release();
434
231
  };
435
232
  }
233
+ static get(from) {
234
+ return REGISTER$1.get(from);
235
+ }
436
236
  }
437
237
 
438
- const UPDATE = new WeakMap();
439
- const LISTEN = new WeakMap();
440
- const CONTROL = Symbol("CONTROL");
238
+ const REGISTER = new WeakMap();
239
+ const UPDATE$1 = new WeakMap();
441
240
  function getUpdate(subject) {
442
- return UPDATE.get(subject);
241
+ return UPDATE$1.get(subject);
242
+ }
243
+ function setUpdate(subject, keys) {
244
+ UPDATE$1.set(subject, Array.from(keys));
245
+ setTimeout(() => UPDATE$1.delete(subject), 0);
443
246
  }
444
- class Controller {
247
+ /** Ensure a local update is dropped after use. */
248
+ function hasUpdate(proxy) {
249
+ if (UPDATE$1.has(proxy))
250
+ setTimeout(() => UPDATE$1.delete(proxy), 0);
251
+ }
252
+ /** Set local update for a subscribed context. */
253
+ function addUpdate(proxy, using) {
254
+ const parent = UPDATE$1.get(getPrototypeOf(proxy));
255
+ UPDATE$1.set(proxy, parent.filter(k => using.has(k)));
256
+ }
257
+ class Control {
445
258
  constructor(subject) {
446
259
  this.subject = subject;
447
260
  this.frame = new Set();
448
261
  this.waiting = new Set();
449
262
  this.followers = new Set();
263
+ REGISTER.set(subject, this);
450
264
  }
451
265
  subscribe(callback) {
452
266
  return new Subscriber(this, callback);
453
267
  }
454
- add(key) {
268
+ watch(key) {
455
269
  const { subject, state } = this;
456
270
  const { value } = getOwnPropertyDescriptor(subject, key);
457
271
  if (typeof value == "function")
@@ -470,9 +284,9 @@ class Controller {
470
284
  enumerable: false,
471
285
  set: this.ref(key),
472
286
  get() {
473
- const listen = LISTEN.get(this);
474
- if (listen)
475
- listen(key);
287
+ const sub = Subscriber.get(this);
288
+ if (sub)
289
+ sub.add(key);
476
290
  return state.get(key);
477
291
  }
478
292
  });
@@ -500,16 +314,13 @@ class Controller {
500
314
  };
501
315
  }
502
316
  update(key) {
503
- const { followers, frame, subject, waiting } = this;
317
+ const { followers, frame, waiting } = this;
504
318
  if (frame.has(key))
505
319
  return;
506
320
  else if (!frame.size)
507
321
  setTimeout(() => {
508
322
  flush(this);
509
- UPDATE.set(subject, Array.from(frame));
510
- setTimeout(() => {
511
- UPDATE.delete(subject);
512
- }, 0);
323
+ setUpdate(this.subject, frame);
513
324
  frame.clear();
514
325
  for (const notify of waiting)
515
326
  try {
@@ -532,36 +343,35 @@ class Controller {
532
343
  this.followers.clear();
533
344
  listeners.forEach(x => x(null, this));
534
345
  }
535
- }
536
- function ensure(subject, cb) {
537
- let control = subject[CONTROL];
538
- if (!control)
539
- defineProperty(subject, CONTROL, {
540
- value: control =
541
- new Controller(subject)
542
- });
543
- if (!control.state) {
544
- const { waiting } = control;
545
- if (cb) {
546
- let done;
547
- waiting.add(() => {
548
- done = cb(control);
549
- });
550
- return () => done && done();
346
+ static get(from) {
347
+ if (from && "is" in from)
348
+ from = from.is;
349
+ return REGISTER.get(from);
350
+ }
351
+ static for(subject, cb) {
352
+ const control = this.get(subject) || new this(subject);
353
+ if (!control.state) {
354
+ const { waiting } = control;
355
+ if (cb) {
356
+ let done;
357
+ waiting.add(() => {
358
+ done = cb(control);
359
+ });
360
+ return () => done && done();
361
+ }
362
+ control.state = new Map();
363
+ for (const key in subject)
364
+ control.watch(key);
365
+ control.waiting = new Set();
366
+ for (const cb of waiting)
367
+ cb();
551
368
  }
552
- control.state = new Map();
553
- for (const key in subject)
554
- control.add(key);
555
- const callback = Array.from(waiting);
556
- waiting.clear();
557
- for (const cb of callback)
558
- cb();
369
+ return cb ? cb(control) : control;
559
370
  }
560
- return cb ? cb(control) : control;
561
371
  }
562
372
 
563
373
  const PENDING = new Map();
564
- function apply(fn, label) {
374
+ function add(fn, label) {
565
375
  const name = label || fn.name || "pending";
566
376
  const placeholder = Symbol(`${name} instruction`);
567
377
  function setup(key) {
@@ -575,7 +385,7 @@ function apply(fn, label) {
575
385
  defineProperty(subject, key, output);
576
386
  return false;
577
387
  }
578
- let { get: onGet, set: onSet, suspense } = output;
388
+ let { get: onGet, set: onSet, suspend: shouldSuspend } = output;
579
389
  if ("value" in output)
580
390
  state.set(key, output.value);
581
391
  if ("recursive" in output && output.recursive)
@@ -595,12 +405,11 @@ function apply(fn, label) {
595
405
  ? this.ref(key, onSet)
596
406
  : undefined,
597
407
  get() {
598
- if (!state.has(key) && suspense)
408
+ if (!state.has(key) && shouldSuspend)
599
409
  throw suspend(control, key);
600
- const listen = LISTEN.get(this);
601
- const local = this[LOCAL];
602
- if (listen)
603
- listen(key);
410
+ const local = Subscriber.get(this);
411
+ if (local)
412
+ local.add(key);
604
413
  return onGet
605
414
  ? onGet(local)
606
415
  : state.get(key);
@@ -621,8 +430,8 @@ function getRecursive(key, from) {
621
430
  if (reset)
622
431
  reset();
623
432
  const value = from.state.get(key);
624
- if (value && CONTROL in value) {
625
- const child = ensure(value).subscribe(local.onUpdate);
433
+ if (Control.get(value)) {
434
+ const child = Control.for(value).subscribe(local.onUpdate);
626
435
  if (local.active)
627
436
  child.commit();
628
437
  local.dependant.add(child);
@@ -668,15 +477,15 @@ function __awaiter(thisArg, _arguments, P, generator) {
668
477
  });
669
478
  }
670
479
 
671
- const Oops$8 = issues({
480
+ const Oops$9 = issues({
672
481
  DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
673
482
  });
674
483
  function act(task) {
675
- return apply(function act(key) {
484
+ return add(function act(key) {
676
485
  let pending = false;
677
486
  const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
678
487
  if (pending)
679
- return Promise.reject(Oops$8.DuplicatePending(key));
488
+ return Promise.reject(Oops$9.DuplicatePending(key));
680
489
  pending = true;
681
490
  this.update(key);
682
491
  try {
@@ -719,8 +528,8 @@ function factoryMode(self, output, key, required) {
719
528
  const suspend = () => {
720
529
  if (required === false)
721
530
  return undefined;
722
- const issue = Oops$7.NotReady(subject, key);
723
- Object.assign(pending, {
531
+ const issue = Oops$8.NotReady(subject, key);
532
+ assign(pending, {
724
533
  message: issue.message,
725
534
  stack: issue.stack
726
535
  });
@@ -736,7 +545,7 @@ function factoryMode(self, output, key, required) {
736
545
  };
737
546
  }
738
547
 
739
- const Oops$7 = issues({
548
+ const Oops$8 = issues({
740
549
  // BadSource: (model, property, got) =>
741
550
  // `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
742
551
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
@@ -746,14 +555,14 @@ const Oops$7 = issues({
746
555
  Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
747
556
  });
748
557
  function get(arg0, arg1, arg2) {
749
- return apply(function get(key) {
558
+ return add(function get(key) {
750
559
  const { subject } = this;
751
560
  const computeRequired = arg1 === true || arg2 === true;
752
561
  const factoryRequired = arg1 !== false && arg2 !== false;
753
562
  let getter;
754
563
  // Easy mistake, using a peer, will always be unresolved.
755
564
  if (typeof arg0 == "symbol")
756
- throw Oops$7.PeerNotAllowed(subject, key);
565
+ throw Oops$8.PeerNotAllowed(subject, key);
757
566
  // if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
758
567
  // throw Oops.BadSource(subject, key, arg0);
759
568
  this.state.set(key, undefined);
@@ -775,7 +584,7 @@ function get(arg0, arg1, arg2) {
775
584
  }
776
585
  else if (typeof arg1 == "function") {
777
586
  // replace source controller in-case it is different
778
- source = ensure(arg0);
587
+ source = Control.for(arg0);
779
588
  setter = arg1;
780
589
  }
781
590
  else
@@ -787,7 +596,7 @@ function get(arg0, arg1, arg2) {
787
596
  init();
788
597
  }
789
598
  catch (err) {
790
- Oops$7.ComputeFailed(subject, key).warn();
599
+ Oops$8.ComputeFailed(subject, key).warn();
791
600
  throw err;
792
601
  }
793
602
  return () => {
@@ -799,12 +608,12 @@ function get(arg0, arg1, arg2) {
799
608
  }
800
609
 
801
610
  function ref(arg, mapper) {
802
- return apply(function ref(key) {
611
+ return add(function ref(key) {
803
612
  let value = {};
804
613
  if (typeof arg != "object")
805
614
  value = createRef(this, key, arg);
806
615
  else
807
- ensure(arg).state.forEach((_val, key) => {
616
+ Control.for(arg).state.forEach((_val, key) => {
808
617
  defineProperty(value, key, mapper ? {
809
618
  configurable: true,
810
619
  get() {
@@ -833,11 +642,11 @@ function set(value, argument) {
833
642
  argument = value;
834
643
  value = undefined;
835
644
  }
836
- return apply(function set(key) {
645
+ return add(function set(key) {
837
646
  if (value !== undefined)
838
647
  this.state.set(key, value);
839
648
  return {
840
- suspense: true,
649
+ suspend: true,
841
650
  set: typeof argument == "function"
842
651
  ? createValueEffect(argument)
843
652
  : undefined
@@ -922,12 +731,15 @@ function createProxy(emit, watch) {
922
731
  assign(proxy, {
923
732
  from,
924
733
  delete(key) {
734
+ // TODO: this commit's fix needs tests.
735
+ // Was not cause by coverage.
736
+ const out = from.delete(key);
925
737
  emit(key);
926
- return from.delete(key);
738
+ return out;
927
739
  },
928
740
  clear() {
929
- emit(ANY);
930
741
  from.clear();
742
+ emit(ANY);
931
743
  },
932
744
  has(key) {
933
745
  watch(this, key);
@@ -989,12 +801,12 @@ function createProxy(emit, watch) {
989
801
  }
990
802
 
991
803
  const Parent = new WeakMap();
992
- const Oops$6 = issues({
804
+ const Oops$7 = issues({
993
805
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
994
806
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
995
807
  });
996
808
  function use$1(input, argument) {
997
- return apply(function use(key) {
809
+ return add(function use(key) {
998
810
  const { state, subject } = this;
999
811
  const required = argument !== false;
1000
812
  let pending;
@@ -1006,7 +818,7 @@ function use$1(input, argument) {
1006
818
  input = new input();
1007
819
  }
1008
820
  else if (input && typeof input !== "object")
1009
- throw Oops$6.BadArgument(typeof input);
821
+ throw Oops$7.BadArgument(typeof input);
1010
822
  if (input instanceof Map || input instanceof Set)
1011
823
  return keyed(this, key, input);
1012
824
  const onUpdate = (next) => {
@@ -1014,7 +826,7 @@ function use$1(input, argument) {
1014
826
  if (next) {
1015
827
  get = getRecursive(key, this);
1016
828
  Parent.set(next, subject);
1017
- ensure(next);
829
+ Control.for(next);
1018
830
  }
1019
831
  if (typeof argument == "function")
1020
832
  argument(next);
@@ -1023,8 +835,8 @@ function use$1(input, argument) {
1023
835
  const suspend = () => {
1024
836
  if (required === false)
1025
837
  return;
1026
- const issue = Oops$6.NotReady(subject, key);
1027
- Object.assign(pending, {
838
+ const issue = Oops$7.NotReady(subject, key);
839
+ assign(pending, {
1028
840
  message: issue.message,
1029
841
  stack: issue.stack
1030
842
  });
@@ -1068,25 +880,204 @@ function use$1(input, argument) {
1068
880
  });
1069
881
  }
1070
882
 
1071
- const Oops$5 = issues({
883
+ const Oops$6 = issues({
1072
884
  Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
1073
885
  Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
1074
886
  });
1075
- function has(Expects, required) {
1076
- return apply(function parent() {
887
+ function has(Type, required) {
888
+ return add(function parent() {
1077
889
  const child = this.subject;
1078
890
  const value = Parent.get(child);
1079
- const expected = Expects.name;
891
+ const expected = Type.name;
1080
892
  if (!value) {
1081
893
  if (required !== false)
1082
- throw Oops$5.Required(expected, child);
894
+ throw Oops$6.Required(expected, child);
1083
895
  }
1084
- else if (!(value instanceof Expects))
1085
- throw Oops$5.Unexpected(expected, child, value);
896
+ else if (!(value instanceof Type))
897
+ throw Oops$6.Unexpected(expected, child, value);
1086
898
  return { value };
1087
899
  });
1088
900
  }
1089
901
 
902
+ const Oops$5 = issues({
903
+ Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
904
+ StrictUpdate: () => `Strict update() did not find pending updates.`,
905
+ NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
906
+ });
907
+ class Model {
908
+ constructor() {
909
+ new Control(this);
910
+ defineProperty(this, "is", { value: this });
911
+ }
912
+ on(select, argument, once) {
913
+ if (typeof select == "function")
914
+ return Control.for(this, x => x.addListener(select));
915
+ const single = typeof select == "string";
916
+ let keys = single ? [select] : select;
917
+ if (typeof argument !== "function")
918
+ return new Promise((resolve, reject) => {
919
+ const removeListener = Control.for(this, control => {
920
+ for (const key of keys)
921
+ try {
922
+ void this[key];
923
+ }
924
+ catch (e) { }
925
+ return control.addListener(key => {
926
+ if (!key) {
927
+ removeListener();
928
+ reject(Oops$5.Timeout(select, `lifetime of ${this}`));
929
+ }
930
+ else if (keys.includes(key)) {
931
+ removeListener();
932
+ return () => resolve(single ? control.state.get(key) : getUpdate(this));
933
+ }
934
+ });
935
+ });
936
+ if (typeof argument == "number")
937
+ setTimeout(() => {
938
+ removeListener();
939
+ reject(Oops$5.Timeout(select, `${argument}ms`));
940
+ }, argument);
941
+ });
942
+ return Control.for(this, control => {
943
+ if (!keys.length)
944
+ keys = [...control.state.keys()];
945
+ for (const key of keys)
946
+ try {
947
+ void this[key];
948
+ }
949
+ catch (e) { }
950
+ const callback = single
951
+ ? () => { argument.call(this, control.state.get(select), select); }
952
+ : () => { argument.call(this, getUpdate(this)); };
953
+ const onEvent = once
954
+ ? () => {
955
+ removeListener();
956
+ callback();
957
+ }
958
+ : callback;
959
+ const removeListener = control.addListener(key => {
960
+ if (keys.includes(key))
961
+ return onEvent;
962
+ });
963
+ return removeListener;
964
+ });
965
+ }
966
+ effect(callback, select) {
967
+ const effect = createEffect(callback);
968
+ return Control.for(this, control => {
969
+ let busy = false;
970
+ let inject = this.is;
971
+ const invoke = () => {
972
+ if (busy)
973
+ return;
974
+ const output = mayRetry(() => {
975
+ effect.call(inject, inject);
976
+ });
977
+ if (output instanceof Promise) {
978
+ output.finally(() => busy = false);
979
+ busy = true;
980
+ }
981
+ };
982
+ if (!select) {
983
+ const sub = control.subscribe(() => invoke);
984
+ inject = sub.proxy;
985
+ invoke();
986
+ return sub.commit();
987
+ }
988
+ invoke();
989
+ return control.addListener(key => {
990
+ if (key === null) {
991
+ if (!select.length)
992
+ invoke();
993
+ }
994
+ else if (select.includes(key))
995
+ return invoke;
996
+ });
997
+ });
998
+ }
999
+ export(subset) {
1000
+ const { state } = Control.for(this);
1001
+ const output = {};
1002
+ const keys = subset || state.keys();
1003
+ for (const key of keys)
1004
+ output[key] = state.get(key);
1005
+ return output;
1006
+ }
1007
+ update(arg1, arg2) {
1008
+ const control = Control.for(this);
1009
+ const { frame, state, waiting } = control;
1010
+ if (arg1 === true && !frame.size)
1011
+ return Promise.reject(Oops$5.StrictUpdate());
1012
+ if (typeof arg1 == "object") {
1013
+ for (const key in arg1)
1014
+ if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
1015
+ state.set(key, arg1[key]);
1016
+ control.update(key);
1017
+ }
1018
+ }
1019
+ else if (typeof arg1 == "string") {
1020
+ control.update(arg1);
1021
+ if (1 in arguments && arg1 in this) {
1022
+ const method = this[arg1];
1023
+ if (typeof method == "function")
1024
+ if (typeof arg2 != "boolean")
1025
+ method.call(this, arg2);
1026
+ else if (arg2)
1027
+ method.call(this);
1028
+ }
1029
+ arg1 = undefined;
1030
+ }
1031
+ return {
1032
+ then: (callback) => {
1033
+ if (!callback)
1034
+ throw Oops$5.NoChaining();
1035
+ if (frame.size || arg1 !== false)
1036
+ waiting.add(() => {
1037
+ callback(getUpdate(this));
1038
+ });
1039
+ else
1040
+ callback(false);
1041
+ }
1042
+ };
1043
+ }
1044
+ /**
1045
+ * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
1046
+ */
1047
+ kill() {
1048
+ Control.for(this).clear();
1049
+ }
1050
+ /**
1051
+ * Creates a new instance of this controller.
1052
+ *
1053
+ * Beyond `new this(...)`, method will activate managed-state.
1054
+ *
1055
+ * @param args - arguments sent to constructor
1056
+ */
1057
+ static new(...args) {
1058
+ const instance = new this(...args);
1059
+ Control.for(instance);
1060
+ return instance;
1061
+ }
1062
+ /**
1063
+ * Static equivalent of `x instanceof this`.
1064
+ *
1065
+ * Will determine if provided class is a subtype of this one.
1066
+ */
1067
+ static isTypeof(maybe) {
1068
+ return (typeof maybe == "function" &&
1069
+ maybe.prototype instanceof this);
1070
+ }
1071
+ }
1072
+ defineProperty(Model.prototype, "toString", {
1073
+ value() {
1074
+ return this.constructor.name;
1075
+ }
1076
+ });
1077
+
1078
+ const Oops$4 = issues({
1079
+ NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1080
+ });
1090
1081
  class Lookup {
1091
1082
  constructor() {
1092
1083
  this.table = new Map();
@@ -1107,26 +1098,10 @@ class Lookup {
1107
1098
  get(T) {
1108
1099
  return this[this.key(T)];
1109
1100
  }
1110
- push(I) {
1111
- const next = create(this);
1112
- if (I instanceof Model || typeof I == "function")
1113
- next.register(I);
1114
- else
1115
- for (const i of values(I))
1116
- next.register(i);
1117
- return next;
1101
+ push() {
1102
+ return create(this);
1118
1103
  }
1119
- register(I) {
1120
- let writable = true;
1121
- let T;
1122
- if (I instanceof Model) {
1123
- T = I.constructor;
1124
- writable = false;
1125
- }
1126
- else {
1127
- T = I;
1128
- I = I.create();
1129
- }
1104
+ inject(T, I, writable) {
1130
1105
  do {
1131
1106
  const key = this.key(T);
1132
1107
  const conflict = this.hasOwnProperty(key);
@@ -1137,23 +1112,21 @@ class Lookup {
1137
1112
  });
1138
1113
  T = getPrototypeOf(T);
1139
1114
  } while (T !== Model);
1140
- return I;
1141
1115
  }
1142
1116
  pop() {
1117
+ const items = new Set();
1143
1118
  for (const key of getOwnPropertySymbols(this)) {
1144
1119
  const entry = getOwnPropertyDescriptor(this, key);
1145
1120
  if (entry.writable && entry.value)
1146
- entry.value.destroy();
1121
+ items.add(entry.value);
1147
1122
  }
1123
+ for (const model of items)
1124
+ model.kill();
1148
1125
  }
1149
- }
1150
-
1126
+ }
1151
1127
  const LookupContext = React.createContext(new Lookup());
1152
1128
  const useLookup = () => React.useContext(LookupContext);
1153
- const Oops$4 = issues({
1154
- NotFound: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`
1155
- });
1156
- function useLocal(Type, arg) {
1129
+ function useContext(Type, arg) {
1157
1130
  const instance = useLookup().get(Type);
1158
1131
  if (!instance && arg !== false)
1159
1132
  throw Oops$4.NotFound(Type.name);
@@ -1161,7 +1134,7 @@ function useLocal(Type, arg) {
1161
1134
  case "string":
1162
1135
  return instance[arg];
1163
1136
  case "function":
1164
- useLayoutEffect(() => arg(instance), []);
1137
+ React.useLayoutEffect(() => arg(instance), []);
1165
1138
  default:
1166
1139
  return instance;
1167
1140
  }
@@ -1174,7 +1147,7 @@ const Oops$3 = issues({
1174
1147
  const PendingContext = new WeakMap();
1175
1148
  const ContextWasUsed = new WeakMap();
1176
1149
  function tap(type, argument) {
1177
- return apply(function tap(key) {
1150
+ return add(function tap(key) {
1178
1151
  if ("set" in type)
1179
1152
  return {
1180
1153
  recursive: true,
@@ -1196,7 +1169,7 @@ function tap(type, argument) {
1196
1169
  });
1197
1170
  return {
1198
1171
  recursive: true,
1199
- suspense: true
1172
+ suspend: true
1200
1173
  };
1201
1174
  });
1202
1175
  }
@@ -1231,57 +1204,51 @@ function use(init) {
1231
1204
 
1232
1205
  function useModel(source, arg, arg2) {
1233
1206
  const instance = React.useMemo(() => {
1234
- const cb = arg2 || arg;
1235
- const instance = typeof source == "function" ?
1236
- source.prototype instanceof Model ?
1237
- new source() :
1238
- source() :
1239
- source;
1240
- ensure(instance);
1241
- if (typeof cb == "function")
1242
- cb(instance);
1207
+ const callback = arg2 || arg;
1208
+ const instance = Model.isTypeof(source) ?
1209
+ source.new() :
1210
+ source();
1211
+ Control.for(instance);
1212
+ if (typeof callback == "function")
1213
+ callback(instance);
1243
1214
  return instance;
1244
1215
  }, []);
1216
+ usePeerContext(instance);
1245
1217
  if (Array.isArray(arg)) {
1246
1218
  const update = useState(0)[1];
1247
1219
  React.useLayoutEffect(() => {
1248
1220
  if (arg.length && instance instanceof Model)
1249
- instance.on(arg, () => update(x => x + 1), true);
1221
+ instance.on(arg, () => update(x => x + 1));
1250
1222
  return () => {
1251
1223
  if (Model.isTypeof(source))
1252
- instance.destroy();
1224
+ instance.kill();
1253
1225
  };
1254
1226
  }, []);
1255
1227
  return instance;
1256
1228
  }
1257
- else {
1258
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1259
- if (typeof arg == "object") {
1260
- local.active = false;
1261
- if (typeof arg2 !== "object")
1262
- arg2 = getOwnPropertyNames(instance);
1263
- for (const key of arg2)
1264
- if (key in arg)
1265
- instance[key] = arg[key];
1266
- React.useLayoutEffect(() => {
1267
- local.active = true;
1268
- });
1269
- }
1270
- React.useLayoutEffect(() => {
1271
- local.commit();
1272
- return () => {
1273
- local.release();
1274
- if (Model.isTypeof(source))
1275
- instance.destroy();
1276
- };
1277
- }, []);
1278
- return local.proxy;
1229
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1230
+ if (typeof arg == "object") {
1231
+ local.active = false;
1232
+ if (typeof arg2 !== "object")
1233
+ arg2 = getOwnPropertyNames(instance);
1234
+ for (const key of arg2)
1235
+ if (key in arg)
1236
+ instance[key] = arg[key];
1279
1237
  }
1238
+ React.useLayoutEffect(() => {
1239
+ local.commit();
1240
+ return () => {
1241
+ local.release();
1242
+ if (Model.isTypeof(source))
1243
+ instance.kill();
1244
+ };
1245
+ }, []);
1246
+ return local.proxy;
1280
1247
  }
1281
1248
 
1282
1249
  function useFrom(target, compute, suspend) {
1283
1250
  const local = use(refresh => {
1284
- const sub = ensure(target).subscribe(() => update);
1251
+ const sub = Control.for(target).subscribe(() => update);
1285
1252
  const spy = sub.proxy;
1286
1253
  let value = compute.call(spy, spy);
1287
1254
  let update;
@@ -1320,84 +1287,79 @@ function useFrom(target, compute, suspend) {
1320
1287
  return local.proxy;
1321
1288
  }
1322
1289
 
1323
- function useTap(source, path, expect) {
1290
+ function useTap(source, arg1, arg2) {
1324
1291
  const instance = useMemo(() => {
1325
1292
  if (typeof source == "object")
1326
1293
  return () => source;
1327
- if ("get" in source)
1328
- return () => source.get();
1329
- if ("prototype" in source)
1330
- return () => useLocal(source);
1331
- else
1332
- return source;
1294
+ if (MVC.isTypeof(source))
1295
+ return () => source.get(true);
1296
+ if (Model.isTypeof(source))
1297
+ return () => useContext(source);
1298
+ return source;
1333
1299
  }, [])();
1334
- if (typeof path == "function")
1335
- return useFrom(instance, path, expect);
1336
- const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1300
+ if (typeof arg1 == "function")
1301
+ return useFrom(instance, arg1, arg2);
1302
+ const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1337
1303
  React.useLayoutEffect(local.commit, []);
1338
- if (typeof path !== "undefined") {
1339
- const value = local.proxy[path];
1340
- if (value === undefined && expect)
1341
- throw suspend(ensure(instance), path);
1342
- return value;
1343
- }
1344
- return local.proxy;
1304
+ if (arg1 === undefined)
1305
+ return local.proxy;
1306
+ const value = local.proxy[arg1];
1307
+ if (value === undefined && arg2)
1308
+ throw suspend(local.parent, arg1);
1309
+ return value;
1345
1310
  }
1346
1311
 
1347
- /* istanbul ignore file */
1348
1312
  class MVC extends Model {
1349
- tap(path, expect) {
1350
- return useTap(this, path, expect);
1351
- }
1352
- use(arg, callback) {
1353
- return useModel(this, arg, callback);
1354
- }
1355
1313
  static get(arg) {
1356
- return useLocal(this, arg);
1314
+ return useContext(this, arg);
1357
1315
  }
1358
1316
  static tap(key, expect) {
1359
1317
  return useTap(this, key, expect);
1360
1318
  }
1361
- static new(arg) {
1362
- const instance = React.useMemo(() => {
1363
- const instance = new this();
1364
- ensure(instance);
1365
- if (typeof arg == "function")
1366
- arg(instance);
1367
- else if (arg)
1368
- getOwnPropertyNames(instance).forEach(key => {
1369
- if (key in arg)
1370
- instance[key] = arg[key];
1371
- });
1372
- return instance;
1373
- }, []);
1374
- usePeerContext(instance.is);
1375
- return instance;
1376
- }
1377
1319
  static use(a, b) {
1378
- const instance = useModel(this, a, b);
1379
- usePeerContext(instance.is);
1380
- return instance;
1381
- }
1382
- /**
1383
- * @deprecated consider doing this manually - not worth minor efficiency gain over using.
1384
- */
1385
- static uses(apply, keys) {
1386
- return this.use(instance => {
1387
- instance.import(apply, keys);
1388
- });
1389
- }
1390
- /**
1391
- * @deprecated is now replaced by overload of `use` method.
1392
- */
1393
- static using(apply, keys) {
1394
- return this.use(apply, keys);
1320
+ return useModel(this, a, b);
1395
1321
  }
1396
1322
  static meta(path, expect) {
1397
1323
  return useTap(() => this, path, expect);
1398
1324
  }
1399
1325
  }
1400
1326
 
1327
+ const LOCAL = Symbol("LOCAL");
1328
+ const STATE = Symbol("STATE");
1329
+ const UPDATE = Symbol("UPDATE");
1330
+ const CONTROL = Symbol("CONTROL");
1331
+ Object.defineProperties(Model.prototype, {
1332
+ [CONTROL]: {
1333
+ get() {
1334
+ return Control.get(this);
1335
+ }
1336
+ },
1337
+ [LOCAL]: {
1338
+ get() {
1339
+ return Subscriber.get(this);
1340
+ }
1341
+ },
1342
+ [STATE]: {
1343
+ get() {
1344
+ const { state } = Control.get(this);
1345
+ const output = {};
1346
+ state.forEach((value, key) => output[key] = value);
1347
+ return output;
1348
+ }
1349
+ },
1350
+ [UPDATE]: {
1351
+ get() {
1352
+ return getUpdate(this);
1353
+ }
1354
+ }
1355
+ });
1356
+ const Debug = {
1357
+ CONTROL,
1358
+ LOCAL,
1359
+ STATE,
1360
+ UPDATE
1361
+ };
1362
+
1401
1363
  const Oops$2 = issues({
1402
1364
  BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
1403
1365
  });
@@ -1407,19 +1369,16 @@ function Consumer(props) {
1407
1369
  return children(useTap(type));
1408
1370
  const callback = has || get;
1409
1371
  if (typeof callback == "function")
1410
- callback(useLocal(type, !!has));
1372
+ callback(useContext(type, !!has));
1411
1373
  else
1412
1374
  throw Oops$2.BadProps();
1413
1375
  return null;
1414
1376
  }
1415
1377
 
1416
1378
  const Oops$1 = issues({
1417
- NoType: () => "Provider 'of' prop must be Model, typeof Model or a collection of them.",
1418
- PropDeprecated: () => "Provider `of` prop is deprecated, use `for` instead."
1379
+ NoType: () => "Provider 'for' prop must be Model, typeof Model or a collection of them."
1419
1380
  });
1420
1381
  function Provider(props) {
1421
- if ("of" in props)
1422
- throw Oops$1.PropDeprecated();
1423
1382
  const context = useNewContext(props.for);
1424
1383
  const render = props.children;
1425
1384
  useAppliedProps(context, props);
@@ -1428,37 +1387,48 @@ function Provider(props) {
1428
1387
  ? React.createElement(RenderFunction, { context, render })
1429
1388
  : render);
1430
1389
  }
1431
- function useNewContext(inject) {
1432
- const from = useLookup();
1390
+ function useNewContext(include) {
1391
+ const ambient = useLookup();
1433
1392
  return React.useMemo(() => {
1434
- if (!inject)
1393
+ if (!include)
1435
1394
  throw Oops$1.NoType();
1436
- const context = from.push(inject);
1437
- for (const instance of context.local)
1395
+ const layer = ambient.push();
1396
+ function register(I) {
1397
+ if (I instanceof Model)
1398
+ layer.inject(I.constructor, I, false);
1399
+ else
1400
+ layer.inject(I, I.new(), true);
1401
+ }
1402
+ if (include instanceof Model || typeof include == "function")
1403
+ register(include);
1404
+ else
1405
+ values(include).forEach(register);
1406
+ for (const instance of layer.local)
1438
1407
  if (instance)
1439
1408
  for (const apply of getPending(instance))
1440
- apply(context);
1441
- return context;
1409
+ apply(layer);
1410
+ return layer;
1442
1411
  }, []);
1443
1412
  }
1444
- function useAppliedProps(within, props) {
1445
- const update = React.useMemo(() => {
1446
- const targets = within.local;
1447
- return function integrate(props) {
1448
- for (const [key, value] of entries(props))
1449
- if (!["of", "for", "children"].includes(key))
1450
- for (const into of targets)
1451
- if (into && key in into)
1452
- into[key] = value;
1413
+ function useAppliedProps(context, props) {
1414
+ const apply = React.useMemo(() => {
1415
+ return (props) => {
1416
+ entries(props).forEach(([key, value]) => {
1417
+ if (key == "for" || key == "children")
1418
+ return;
1419
+ for (const into of context.local)
1420
+ if (into && key in into)
1421
+ into[key] = value;
1422
+ });
1453
1423
  };
1454
1424
  }, []);
1455
- update(props);
1425
+ apply(props);
1456
1426
  }
1457
1427
  function RenderFunction(props) {
1458
1428
  const hook = use(refresh => {
1459
1429
  const targets = props.context.local;
1460
1430
  if (targets.length == 1)
1461
- return ensure(targets[0]).subscribe(() => refresh);
1431
+ return Control.for(targets[0]).subscribe(() => refresh);
1462
1432
  return {};
1463
1433
  });
1464
1434
  if (hook.commit)
@@ -1467,17 +1437,31 @@ function RenderFunction(props) {
1467
1437
  }
1468
1438
 
1469
1439
  const Oops = issues({
1470
- 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.`,
1440
+ 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.`,
1471
1441
  AlreadyExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
1472
1442
  });
1473
1443
  const Active = new WeakMap();
1474
1444
  class Global extends MVC {
1475
- static create(...args) {
1445
+ constructor() {
1446
+ super();
1447
+ Active.set(this.constructor, this);
1448
+ }
1449
+ kill(force) {
1450
+ const type = this.constructor;
1451
+ if (type.keepAlive && !force)
1452
+ return false;
1453
+ super.kill();
1454
+ Active.delete(type);
1455
+ return true;
1456
+ }
1457
+ static new(...args) {
1476
1458
  if (Active.has(this))
1477
- throw Oops.AlreadyExists(this.name);
1459
+ if (this.keepAlive)
1460
+ return Active.get(this);
1461
+ else
1462
+ throw Oops.AlreadyExists(this.name);
1478
1463
  const instance = new this(...args);
1479
- ensure(instance);
1480
- Active.set(this, instance);
1464
+ Control.for(instance);
1481
1465
  return instance;
1482
1466
  }
1483
1467
  /**
@@ -1485,10 +1469,8 @@ class Global extends MVC {
1485
1469
  * Returns a thenable; resolves after successful update.
1486
1470
  * If instance does not already exist, one will be created.
1487
1471
  */
1488
- static set(updates) {
1489
- const instance = Active.get(this) || this.create();
1490
- instance.import(updates);
1491
- return instance.update(false);
1472
+ static set(values) {
1473
+ return this.get(true).update(values);
1492
1474
  }
1493
1475
  static get(arg) {
1494
1476
  const instance = Active.get(this);
@@ -1502,13 +1484,10 @@ class Global extends MVC {
1502
1484
  static reset() {
1503
1485
  const current = Active.get(this);
1504
1486
  if (current)
1505
- current.destroy();
1487
+ current.kill(true);
1506
1488
  }
1507
- destroy() {
1508
- super.destroy();
1509
- Active.delete(this.constructor);
1510
- }
1511
- }
1489
+ }
1490
+ Global.keepAlive = true;
1512
1491
 
1513
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, MVC as default, get, has, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1492
+ export { Consumer, Debug, Global, MVC, MVC as Model, Provider, act, add, MVC as default, get, has, ref, set, tap, use$1 as use, useContext, useFrom, useModel, useTap };
1514
1493
  //# sourceMappingURL=index.esm.js.map