@expressive/mvc 0.2.5 → 0.4.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
@@ -51,7 +51,7 @@ function suspend(source, key) {
51
51
  const release = source.addListener(forKey => {
52
52
  if (forKey == key)
53
53
  return () => {
54
- if (source.state[key] !== undefined) {
54
+ if (source.state.get(key) !== undefined) {
55
55
  release();
56
56
  resolve();
57
57
  }
@@ -132,225 +132,37 @@ function createValueEffect(callback) {
132
132
  };
133
133
  }
134
134
 
135
- const UPDATE = new WeakMap();
136
- function applyUpdate(subject, keys) {
137
- UPDATE.set(subject, keys);
138
- return () => {
139
- setTimeout(() => {
140
- UPDATE.delete(subject);
141
- }, 0);
142
- };
143
- }
144
-
145
- const CONTROL = Symbol("CONTROL");
146
- const WHY = Symbol("UPDATE");
147
- const LOCAL = Symbol("LOCAL");
148
- const STATE = Symbol("STATE");
149
- class Model {
150
- constructor() {
151
- define(this, CONTROL, new Controller(this));
152
- define(this, "get", this);
153
- define(this, "is", this);
154
- defineLazy(this, "set", () => {
155
- const controller = control(this);
156
- const assign = (key, value) => {
157
- controller.update(key, value);
158
- };
159
- for (const key of getOwnPropertyNames(controller.proxy))
160
- define(assign, key, controller.ref(key));
161
- return assign;
162
- });
163
- }
164
- get [STATE]() {
165
- return this[CONTROL].state;
166
- }
167
- get [WHY]() {
168
- return UPDATE.get(this);
169
- }
170
- on(select, handler, squash, once) {
171
- return control(this, control => {
172
- if (typeof select == "function")
173
- return control.addListener(select);
174
- const keys = typeof select == "string" ? [select] :
175
- !select.length ? getOwnPropertyNames(control.state) :
176
- select;
177
- ensure(control, keys);
178
- const callback = squash
179
- ? handler.bind(this)
180
- : frame => frame
181
- .filter(k => keys.includes(k))
182
- .forEach(k => handler.call(this, control.state[k], k));
183
- const trigger = once
184
- ? frame => { remove(); callback(frame); }
185
- : callback;
186
- const remove = control.addListener(key => {
187
- if (keys.includes(key))
188
- return trigger;
189
- });
190
- return remove;
191
- });
192
- }
193
- once(select, callback, squash) {
194
- if (callback)
195
- return this.on(select, callback, squash, true);
196
- return new Promise(resolve => {
197
- this.on(select, resolve, true, true);
198
- });
135
+ function ensure(subject, cb) {
136
+ let control = subject[CONTROL];
137
+ if (!control) {
138
+ control = new Controller(subject);
139
+ define(subject, CONTROL, control);
199
140
  }
200
- effect(callback, select) {
201
- const effect = createEffect(callback);
202
- return control(this, control => {
203
- let busy = false;
204
- let inject = this.get;
205
- const invoke = () => {
206
- if (busy)
207
- return;
208
- const output = mayRetry(() => {
209
- effect.call(inject, inject);
210
- });
211
- if (output instanceof Promise) {
212
- output.finally(() => busy = false);
213
- busy = true;
214
- }
215
- };
216
- if (!select) {
217
- const sub = new Subscriber(control, () => invoke);
218
- inject = sub.proxy;
219
- invoke();
220
- return sub.commit();
221
- }
222
- invoke();
223
- if (!select.length) {
224
- control.onDestroy.add(invoke);
225
- return () => {
226
- control.onDestroy.delete(invoke);
227
- };
228
- }
229
- return control.addListener(key => {
230
- if (select.includes(key))
231
- return invoke;
141
+ if (!control.state) {
142
+ const { waiting } = control;
143
+ if (cb) {
144
+ let done;
145
+ waiting.add(() => {
146
+ done = cb(control);
232
147
  });
233
- });
234
- }
235
- // TODO: account for exotic properties
236
- import(source, select) {
237
- const { subject } = control(this);
238
- if (!select)
239
- select = getOwnPropertyNames(subject);
240
- for (const key of select)
241
- if (key in source)
242
- this[key] = source[key];
243
- }
244
- export(subset) {
245
- const { state } = control(this);
246
- const output = {};
247
- if (!subset)
248
- subset = getOwnPropertyNames(state);
249
- for (const key of subset)
250
- output[key] = state[key];
251
- return output;
252
- }
253
- update(arg, tag) {
254
- const target = control(this);
255
- if (typeof arg == "string") {
256
- target.update(arg);
257
- if (1 in arguments && arg in this) {
258
- const method = this[arg];
259
- if (typeof method == "function")
260
- if (typeof tag != "boolean")
261
- method.call(this, tag);
262
- else if (tag)
263
- method.call(this);
264
- }
265
- arg = undefined;
148
+ return () => done && done();
266
149
  }
267
- return target.requestUpdate(arg);
268
- }
269
- /**
270
- * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
271
- */
272
- destroy() {
273
- control(this).stop();
274
- }
275
- toString() {
276
- return this.constructor.name;
277
- }
278
- /**
279
- * Creates a new instance of this controller.
280
- *
281
- * Beyond `new this(...)`, method will activate managed-state.
282
- *
283
- * @param args - arguments sent to constructor
284
- */
285
- static create(...args) {
286
- const instance = new this(...args);
287
- control(instance);
288
- return instance;
289
- }
290
- /**
291
- * Static equivalent of `x instanceof this`.
292
- *
293
- * Will determine if provided class is a subtype of this one.
294
- */
295
- static isTypeof(maybe) {
296
- return (typeof maybe == "function" &&
297
- maybe.prototype instanceof this);
298
- }
299
- }
300
-
301
- class Subscriber {
302
- constructor(target, onUpdate) {
303
- this.onUpdate = onUpdate;
304
- this.active = false;
305
- this.dependant = new Set();
306
- this.watch = {};
307
- const parent = target instanceof Controller
308
- ? target : control(target);
309
- const proxy = create(parent.proxy);
310
- let reset;
311
- define(proxy, LOCAL, this);
312
- defineProperty(this, "proxy", {
313
- configurable: true,
314
- get() {
315
- if (reset)
316
- setTimeout(reset, 0);
317
- return proxy;
318
- }
319
- });
320
- const release = parent.addListener(key => {
321
- const handler = this.watch[key];
322
- if (!handler || !this.active)
323
- return;
324
- if (typeof handler == "function")
325
- handler();
326
- const notify = this.onUpdate(key, parent);
327
- const getWhy = (keys) => {
328
- reset = applyUpdate(proxy, keys.filter(k => k in this.watch));
329
- };
330
- if (notify) {
331
- parent.requestUpdate(getWhy);
332
- parent.requestUpdate(notify);
333
- }
334
- });
335
- this.commit = () => {
336
- this.active = true;
337
- this.dependant.forEach(x => x.commit());
338
- return this.release;
339
- };
340
- this.release = () => {
341
- this.dependant.forEach(x => x.release());
342
- release();
343
- };
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();
344
157
  }
158
+ return cb ? cb(control) : control;
345
159
  }
346
160
 
347
161
  const Oops$a = issues({
348
162
  BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
349
163
  PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
350
- Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
351
- Early: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
164
+ Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
352
165
  });
353
- const INIT = new WeakSet();
354
166
  const INFO = new WeakMap();
355
167
  const USED = new WeakMap();
356
168
  const KEYS = new WeakMap();
@@ -358,8 +170,8 @@ function from(source, arg1, arg2) {
358
170
  return apply(function from(key) {
359
171
  const parent = this;
360
172
  const { subject, state } = this;
173
+ const required = arg2 === true || arg1 === true;
361
174
  let getSource;
362
- let required = arg2 === true || arg1 === true;
363
175
  if (typeof arg1 == "boolean")
364
176
  arg1 = undefined;
365
177
  // Easy mistake, using a peer, will always be unresolved.
@@ -367,7 +179,7 @@ function from(source, arg1, arg2) {
367
179
  throw Oops$a.PeerNotAllowed(subject, key);
368
180
  // replace source controller in-case it is different
369
181
  if (typeof source == "object")
370
- getSource = () => control(source);
182
+ getSource = () => ensure(source);
371
183
  // specifically an arrow function (getter factory)
372
184
  else if (!source.prototype) {
373
185
  arg1 = source.call(subject, key);
@@ -376,21 +188,20 @@ function from(source, arg1, arg2) {
376
188
  // Regular function is too ambiguous so not allowed.
377
189
  else
378
190
  throw Oops$a.BadSource(subject, key, source);
379
- let sub;
380
191
  const setter = arg1;
381
192
  const info = { key, parent, priority: 1 };
193
+ let sub;
382
194
  let register = USED.get(parent);
383
- if (!register) {
384
- register = new Map();
385
- USED.set(parent, register);
386
- }
195
+ if (!register)
196
+ USED.set(parent, register = new Map());
197
+ state.set(key, undefined);
387
198
  register.set(key, info);
388
199
  function compute(initial) {
389
200
  try {
390
201
  return setter.call(sub.proxy, sub.proxy);
391
202
  }
392
203
  catch (err) {
393
- Oops$a.Failed(subject, key, !!initial).warn();
204
+ Oops$a.Failed(subject, key, initial).warn();
394
205
  throw err;
395
206
  }
396
207
  }
@@ -403,8 +214,9 @@ function from(source, arg1, arg2) {
403
214
  console.error(e);
404
215
  }
405
216
  finally {
406
- if (state[key] !== value) {
407
- parent.update(key, value);
217
+ if (state.get(key) !== value) {
218
+ parent.state.set(key, value);
219
+ parent.update(key);
408
220
  return value;
409
221
  }
410
222
  }
@@ -420,218 +232,410 @@ function from(source, arg1, arg2) {
420
232
  pending.splice(after + 1, 0, update);
421
233
  }
422
234
  }
423
- function create(early) {
424
- sub = new Subscriber(getSource(), defer);
425
- defineProperty(state, key, {
426
- value: undefined,
427
- writable: true
428
- });
235
+ function create() {
236
+ const control = getSource();
237
+ sub = control.subscribe(defer);
429
238
  try {
430
- return state[key] = compute(true);
239
+ const value = compute(true);
240
+ state.set(key, value);
241
+ return value;
431
242
  }
432
243
  catch (e) {
433
- if (early)
434
- Oops$a.Early(key).warn();
435
244
  throw e;
436
245
  }
437
246
  finally {
438
247
  sub.commit();
439
- for (const key in sub.watch) {
248
+ for (const key of control.state.keys()) {
440
249
  const peer = register.get(key);
441
250
  if (peer && peer.priority >= info.priority)
442
251
  info.priority = peer.priority + 1;
443
252
  }
444
253
  }
445
254
  }
446
- INIT.add(create);
447
255
  INFO.set(update, info);
448
- defineProperty(state, key, {
449
- get: create,
450
- configurable: true,
451
- enumerable: true
452
- });
453
256
  return () => {
454
- const value = parent.state[key];
257
+ const value = sub ? state.get(key) : create();
455
258
  if (value === undefined && required)
456
259
  throw suspend(this, key);
457
260
  return value;
458
261
  };
459
262
  });
460
263
  }
461
- function ensure(on, keys) {
462
- for (const key of keys) {
463
- const desc = getOwnPropertyDescriptor(on.state, key);
464
- const getter = desc && desc.get;
465
- if (INIT.has(getter))
466
- getter(true);
467
- }
468
- }
469
- function flush(on) {
470
- const handled = on.frame;
471
- const pending = KEYS.get(on);
264
+ function flush(control) {
265
+ const pending = KEYS.get(control);
472
266
  if (!pending)
473
267
  return;
474
268
  while (pending.length) {
475
- const why = [...handled];
476
269
  const compute = pending.shift();
477
270
  const { key } = INFO.get(compute);
478
- if (!handled.has(key))
479
- compute(why);
271
+ if (!control.frame.has(key))
272
+ compute();
480
273
  }
481
- KEYS.delete(on);
274
+ KEYS.delete(control);
482
275
  }
483
276
 
484
- const Oops$9 = issues({
485
- StrictUpdate: () => `Strict update() did not find pending updates.`,
486
- NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
487
- });
488
- const PENDING = new Map();
489
- const READY = new WeakSet();
277
+ class Subscriber {
278
+ constructor(parent, onUpdate) {
279
+ this.onUpdate = onUpdate;
280
+ this.active = false;
281
+ this.dependant = new Set();
282
+ const proxy = create(parent.subject);
283
+ const using = new Map();
284
+ define(proxy, LOCAL, this);
285
+ defineProperty(this, "proxy", {
286
+ configurable: true,
287
+ get() {
288
+ if (UPDATE.has(proxy))
289
+ setTimeout(() => UPDATE.delete(proxy), 0);
290
+ return proxy;
291
+ }
292
+ });
293
+ const release = parent.addListener(key => {
294
+ if (!this.active || !using.has(key))
295
+ return;
296
+ const handler = using.get(key);
297
+ if (typeof handler == "function")
298
+ if (handler() !== true)
299
+ return;
300
+ const 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);
305
+ };
306
+ if (notify) {
307
+ parent.waiting.add(getWhy);
308
+ parent.waiting.add(notify);
309
+ }
310
+ });
311
+ this.commit = () => {
312
+ this.active = true;
313
+ this.dependant.forEach(x => x.commit());
314
+ return this.release;
315
+ };
316
+ this.release = () => {
317
+ this.dependant.forEach(x => x.release());
318
+ release();
319
+ };
320
+ this.add = (key, value) => {
321
+ if (value)
322
+ using.set(key, value);
323
+ else if (!using.has(key))
324
+ using.set(key, true);
325
+ };
326
+ }
327
+ }
328
+
329
+ const UPDATE = new WeakMap();
330
+ function getUpdate(subject) {
331
+ return UPDATE.get(subject);
332
+ }
490
333
  class Controller {
491
334
  constructor(subject) {
492
335
  this.subject = subject;
493
- this.state = {};
494
336
  this.frame = new Set();
495
337
  this.waiting = new Set();
496
- this.onDestroy = new Set();
497
338
  this.followers = new Set();
498
- this.proxy = Object.create(subject);
499
- }
500
- start() {
501
- READY.add(this);
502
- for (const key in this.subject) {
503
- const { value: entry } = getOwnPropertyDescriptor(this.subject, key);
504
- if (typeof entry == "function")
505
- continue;
506
- if (typeof entry == "symbol") {
507
- const instruction = PENDING.get(entry);
508
- if (instruction)
509
- instruction.call(this, key, this);
510
- continue;
511
- }
512
- this.manage(key, entry);
513
- }
514
- this.emit([]);
515
339
  }
516
- stop() {
517
- this.followers.clear();
518
- this.onDestroy.forEach(x => x());
340
+ subscribe(callback) {
341
+ return new Subscriber(this, callback);
519
342
  }
520
- manage(key, value) {
521
- const { proxy, state, subject } = this;
522
- state[key] = value;
523
- const set = this.ref(key);
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);
524
355
  defineProperty(subject, key, {
525
356
  enumerable: false,
526
- get: () => state[key],
527
- set
528
- });
529
- defineProperty(proxy, key, {
530
- enumerable: false,
357
+ set: this.ref(key),
531
358
  get() {
532
359
  const local = this[LOCAL];
533
- if (local && !local.watch[key])
534
- local.watch[key] = true;
535
- return state[key];
536
- },
537
- set
360
+ if (local)
361
+ local.add(key);
362
+ return state.get(key);
363
+ }
538
364
  });
539
365
  }
366
+ addListener(listener) {
367
+ this.followers.add(listener);
368
+ return () => {
369
+ this.followers.delete(listener);
370
+ };
371
+ }
540
372
  ref(key, handler) {
541
- const { state, subject } = this;
373
+ const { subject, state } = this;
542
374
  return (value) => {
543
- if (state[key] == value)
375
+ if (state.get(key) == value)
544
376
  return;
545
377
  if (handler)
546
- switch (handler.call(subject, value, state)) {
378
+ switch (handler.call(subject, value)) {
547
379
  case true:
548
380
  this.update(key);
549
381
  case false:
550
382
  return;
551
383
  }
552
- this.update(key, value);
553
- };
554
- }
555
- addListener(listener) {
556
- this.followers.add(listener);
557
- return () => {
558
- this.followers.delete(listener);
384
+ state.set(key, value);
385
+ this.update(key);
559
386
  };
560
387
  }
561
- emit(keys) {
562
- const waiting = [...this.waiting];
563
- this.waiting.clear();
564
- applyUpdate(this.subject, keys)();
565
- for (const callback of waiting)
566
- try {
567
- callback(keys);
568
- }
569
- catch (err) {
570
- console.error(err);
571
- }
572
- }
573
- update(key, value) {
574
- if (1 in arguments)
575
- this.state[key] = value;
576
- if (this.frame.has(key))
388
+ update(key) {
389
+ const { followers, frame, subject, waiting } = this;
390
+ if (frame.has(key))
577
391
  return;
578
- if (!this.frame.size)
392
+ else if (!frame.size)
579
393
  setTimeout(() => {
580
394
  flush(this);
581
- const keys = Object.freeze([...this.frame]);
582
- this.frame.clear();
583
- this.emit(keys);
395
+ const callback = Array.from(waiting);
396
+ const keys = Array.from(frame);
397
+ frame.clear();
398
+ waiting.clear();
399
+ UPDATE.set(subject, keys);
400
+ setTimeout(() => {
401
+ UPDATE.delete(subject);
402
+ }, 0);
403
+ for (const cb of callback)
404
+ try {
405
+ cb();
406
+ }
407
+ catch (err) {
408
+ console.error(err);
409
+ }
584
410
  }, 0);
585
- this.frame.add(key);
586
- for (const callback of this.followers) {
411
+ frame.add(key);
412
+ for (const callback of followers) {
587
413
  const event = callback(key, this);
588
414
  if (typeof event == "function")
589
- this.waiting.add(event);
415
+ waiting.add(event);
590
416
  }
591
417
  }
592
- requestUpdate(arg) {
593
- if (typeof arg == "function") {
594
- this.waiting.add(arg);
595
- return;
418
+ clear() {
419
+ const listeners = [...this.followers];
420
+ this.followers.clear();
421
+ listeners.forEach(x => x(null, this));
422
+ }
423
+ }
424
+
425
+ const Oops$9 = issues({
426
+ Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
427
+ StrictUpdate: () => `Strict update() did not find pending updates.`,
428
+ NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
429
+ });
430
+ const CONTROL = Symbol("CONTROL");
431
+ const WHY = Symbol("UPDATE");
432
+ const LOCAL = Symbol("LOCAL");
433
+ const STATE = Symbol("STATE");
434
+ class Model {
435
+ constructor() {
436
+ define(this, CONTROL, new Controller(this));
437
+ define(this, "get", this);
438
+ define(this, "is", this);
439
+ defineLazy(this, "set", () => {
440
+ const controller = ensure(this);
441
+ const assign = (key, value) => {
442
+ controller.state.set(key, value);
443
+ controller.update(key);
444
+ };
445
+ for (const key of controller.state.keys())
446
+ define(assign, key, controller.ref(key));
447
+ return assign;
448
+ });
449
+ }
450
+ get [STATE]() {
451
+ return this.export();
452
+ }
453
+ get [WHY]() {
454
+ return UPDATE.get(this);
455
+ }
456
+ on(select, handler, squash, once) {
457
+ return ensure(this, control => {
458
+ if (typeof select == "function")
459
+ return control.addListener(select);
460
+ const keys = typeof select == "string" ? [select] :
461
+ select.length ? select : [...control.state.keys()];
462
+ for (const key of keys)
463
+ try {
464
+ void this[key];
465
+ }
466
+ catch (e) { }
467
+ const callback = squash
468
+ ? () => {
469
+ handler.call(this, getUpdate(this));
470
+ }
471
+ : () => {
472
+ getUpdate(this)
473
+ .filter(k => keys.includes(k))
474
+ .forEach(k => {
475
+ handler.call(this, control.state.get(k), k);
476
+ });
477
+ };
478
+ const onEvent = once
479
+ ? () => {
480
+ remove();
481
+ callback();
482
+ }
483
+ : callback;
484
+ const remove = control.addListener(key => {
485
+ if (keys.includes(key))
486
+ return onEvent;
487
+ });
488
+ return remove;
489
+ });
490
+ }
491
+ once(select, argument, squash) {
492
+ if (typeof argument == "function")
493
+ return this.on(select, argument, squash, true);
494
+ if (typeof select == "string")
495
+ select = [select];
496
+ return new Promise((resolve, reject) => {
497
+ const invoke = (key) => {
498
+ if (!key) {
499
+ clear();
500
+ reject(Oops$9.Timeout(select, typeof argument == "number"
501
+ ? `${argument}ms`
502
+ : `lifetime of ${this}`));
503
+ }
504
+ else if (select.includes(key)) {
505
+ clear();
506
+ return resolve;
507
+ }
508
+ };
509
+ const clear = ensure(this, x => {
510
+ for (const key of select)
511
+ try {
512
+ void this[key];
513
+ }
514
+ catch (e) { }
515
+ return x.addListener(invoke);
516
+ });
517
+ if (typeof argument == "number")
518
+ setTimeout(invoke, argument);
519
+ });
520
+ }
521
+ effect(callback, select) {
522
+ const effect = createEffect(callback);
523
+ return ensure(this, control => {
524
+ let busy = false;
525
+ let inject = this.is;
526
+ const invoke = () => {
527
+ if (busy)
528
+ return;
529
+ const output = mayRetry(() => {
530
+ effect.call(inject, inject);
531
+ });
532
+ if (output instanceof Promise) {
533
+ output.finally(() => busy = false);
534
+ busy = true;
535
+ }
536
+ };
537
+ if (!select) {
538
+ const sub = control.subscribe(() => invoke);
539
+ inject = sub.proxy;
540
+ invoke();
541
+ return sub.commit();
542
+ }
543
+ invoke();
544
+ return control.addListener(key => {
545
+ if (key === null) {
546
+ if (!select.length)
547
+ invoke();
548
+ }
549
+ else if (select.includes(key))
550
+ return invoke;
551
+ });
552
+ });
553
+ }
554
+ // TODO: account for exotic properties
555
+ import(source, select) {
556
+ const { subject } = ensure(this);
557
+ if (!select)
558
+ select = getOwnPropertyNames(subject);
559
+ for (const key of select)
560
+ if (key in source)
561
+ this[key] = source[key];
562
+ }
563
+ export(subset) {
564
+ const { state } = ensure(this);
565
+ const output = {};
566
+ const keys = subset || state.keys();
567
+ for (const key of keys)
568
+ output[key] = state.get(key);
569
+ return output;
570
+ }
571
+ update(arg, tag) {
572
+ const target = ensure(this);
573
+ const { frame, waiting } = target;
574
+ if (typeof arg == "string") {
575
+ target.update(arg);
576
+ if (1 in arguments && arg in this) {
577
+ const method = this[arg];
578
+ if (typeof method == "function")
579
+ if (typeof tag != "boolean")
580
+ method.call(this, tag);
581
+ else if (tag)
582
+ method.call(this);
583
+ }
584
+ arg = undefined;
596
585
  }
597
- if (arg === true && this.frame.size < 1)
586
+ if (!frame.size && arg === true)
598
587
  return Promise.reject(Oops$9.StrictUpdate());
599
588
  return {
600
589
  then: (callback) => {
601
- if (callback)
602
- if (this.frame.size || arg !== false)
603
- this.waiting.add(callback);
604
- else
605
- callback(false);
606
- else
590
+ if (!callback)
607
591
  throw Oops$9.NoChaining();
592
+ if (frame.size || arg !== false)
593
+ waiting.add(() => {
594
+ callback(getUpdate(this));
595
+ });
596
+ else
597
+ callback(false);
608
598
  }
609
599
  };
610
600
  }
611
- }
612
- function control(subject, cb) {
613
- let control = subject[CONTROL];
614
- if (!control) {
615
- control = new Controller(subject);
616
- define(subject, CONTROL, control);
601
+ /**
602
+ * Mark this instance for garbage-collection and send `willDestroy` event to all listeners.
603
+ */
604
+ destroy() {
605
+ ensure(this).clear();
617
606
  }
618
- const ready = READY.has(control);
619
- if (!ready) {
620
- if (cb) {
621
- let done;
622
- control.requestUpdate(() => done = cb(control));
623
- return () => done && done();
624
- }
625
- control.start();
607
+ toString() {
608
+ return this.constructor.name;
609
+ }
610
+ /**
611
+ * Creates a new instance of this controller.
612
+ *
613
+ * Beyond `new this(...)`, method will activate managed-state.
614
+ *
615
+ * @param args - arguments sent to constructor
616
+ */
617
+ static create(...args) {
618
+ const instance = new this(...args);
619
+ ensure(instance);
620
+ return instance;
621
+ }
622
+ /**
623
+ * Static equivalent of `x instanceof this`.
624
+ *
625
+ * Will determine if provided class is a subtype of this one.
626
+ */
627
+ static isTypeof(maybe) {
628
+ return (typeof maybe == "function" &&
629
+ maybe.prototype instanceof this);
626
630
  }
627
- return cb ? cb(control) : control;
628
631
  }
629
632
 
633
+ const PENDING = new Map();
630
634
  function apply(fn, label) {
631
635
  const name = label || fn.name || "pending";
632
636
  const placeholder = Symbol(`${name} instruction`);
633
637
  function setup(key) {
634
- const { proxy, state, subject } = this;
638
+ const { subject, state } = this;
635
639
  const control = this;
636
640
  PENDING.delete(placeholder);
637
641
  delete subject[key];
@@ -645,67 +649,56 @@ function apply(fn, label) {
645
649
  return false;
646
650
  }
647
651
  if ("recursive" in output && output.recursive)
648
- output = Object.assign(Object.assign({}, output), { get: recursive(this, key) });
652
+ output = Object.assign(Object.assign({}, output), { get: getRecursive(key, this) });
649
653
  const desc = output;
650
654
  if ("value" in desc)
651
- state[key] = desc.value;
655
+ state.set(key, desc.value);
652
656
  const { get: onGet, set: onSet, enumerable, suspense } = desc;
653
- let set = onSet === false
654
- ? undefined
655
- : this.ref(key, onSet);
657
+ const set = onSet !== false
658
+ ? this.ref(key, onSet)
659
+ : undefined;
656
660
  function get() {
657
- if (!(key in state) && suspense)
661
+ if (!state.has(key) && suspense)
658
662
  throw suspend(control, key);
659
663
  const local = this[LOCAL];
660
- if (local && !(key in local.watch))
661
- local.watch[key] = true;
662
- const value = state[key];
663
- if (!onGet)
664
- return value;
665
- return local
666
- ? onGet(value, local)
667
- : onGet(value);
664
+ if (local)
665
+ local.add(key);
666
+ return onGet
667
+ ? onGet(local)
668
+ : state.get(key);
668
669
  }
669
- for (const x of [subject, proxy])
670
- defineProperty(x, key, { enumerable, get, set });
670
+ defineProperty(subject, key, { enumerable, get, set });
671
671
  }
672
672
  PENDING.set(placeholder, setup);
673
673
  return placeholder;
674
674
  }
675
- function recursive(source, key) {
676
- return forSubscriber((parent, context) => {
677
- let child;
678
- function init() {
679
- if (child) {
680
- child.release();
681
- parent.dependant.delete(child);
682
- context.set(parent, undefined);
683
- child = undefined;
684
- }
685
- const value = source.state[key];
686
- if (value && CONTROL in value) {
687
- child = new Subscriber(value, parent.onUpdate);
688
- if (parent.active)
689
- child.commit();
690
- parent.dependant.add(child);
691
- context.set(parent, child.proxy);
692
- }
693
- }
694
- init();
695
- parent.watch[key] = init;
696
- });
697
- }
698
- function forSubscriber(fn) {
675
+ function getRecursive(key, from) {
699
676
  const context = new WeakMap();
700
- return (value, local) => {
677
+ const { state } = from;
678
+ return (local) => {
701
679
  if (!local)
702
- return value;
680
+ return state.get(key);
703
681
  if (!context.has(local)) {
704
- const output = fn(local, context);
705
- if (output) {
706
- context.set(local, output);
707
- return output;
708
- }
682
+ let child;
683
+ const init = () => {
684
+ if (child) {
685
+ child.release();
686
+ local.dependant.delete(child);
687
+ context.set(local, undefined);
688
+ child = undefined;
689
+ }
690
+ const value = state.get(key);
691
+ if (value && CONTROL in value) {
692
+ child = ensure(value).subscribe(local.onUpdate);
693
+ if (local.active)
694
+ child.commit();
695
+ local.dependant.add(child);
696
+ context.set(local, child.proxy);
697
+ }
698
+ return true;
699
+ };
700
+ init();
701
+ local.add(key, init);
709
702
  }
710
703
  return context.get(local);
711
704
  };
@@ -730,7 +723,7 @@ function act(task) {
730
723
  this.update(key);
731
724
  }
732
725
  });
733
- this.state[key] = undefined;
726
+ this.state.set(key, undefined);
734
727
  defineProperty(invoke, "active", {
735
728
  get: () => pending
736
729
  });
@@ -751,7 +744,7 @@ class Managed extends Array {
751
744
  };
752
745
  }
753
746
  push(...items) {
754
- const length = this.length;
747
+ const { length } = this;
755
748
  const end = super.push(...items);
756
749
  this.update(length, end);
757
750
  return end;
@@ -762,64 +755,65 @@ class Managed extends Array {
762
755
  return end;
763
756
  }
764
757
  splice(start, deleteCount, ...rest) {
765
- this.update(start, deleteCount !== rest.length ? Infinity : deleteCount);
758
+ const end = deleteCount !== rest.length ? Infinity : deleteCount;
759
+ this.update(start, end);
766
760
  return super.splice(start, deleteCount, ...rest);
767
761
  }
768
762
  }
769
763
  function array() {
770
764
  return apply(function array(key) {
765
+ const context = new WeakMap();
771
766
  const array = new Managed(() => this.update(key));
772
- const access = forSubscriber(context => {
773
- const local = Object.create(array);
774
- const update = context.onUpdate(key, this);
767
+ const getLocal = (context) => {
768
+ const proxy = Object.create(array);
775
769
  let rangeA = 0;
776
770
  let rangeB = 0;
777
- function onUpdate() {
771
+ const onUpdate = () => {
778
772
  const [lastA, lastB] = array.lastUpdate;
779
773
  if (rangeA <= lastB && rangeB >= lastA)
780
- return update;
781
- }
782
- function listen(eventA, eventB) {
774
+ return true;
775
+ };
776
+ const listen = (eventA, eventB) => {
783
777
  if (context.active)
784
778
  return;
785
- context.watch[key] = onUpdate;
779
+ context.add(key, onUpdate);
786
780
  rangeA = Math.min(rangeA, eventA);
787
781
  rangeB = Math.max(rangeB, eventB);
788
- }
789
- local[Symbol.iterator] = () => {
782
+ };
783
+ proxy[Symbol.iterator] = () => {
790
784
  listen(0, Infinity);
791
785
  return array[Symbol.iterator]();
792
786
  };
793
- return local;
794
- });
787
+ return proxy;
788
+ };
795
789
  return {
796
- get: access,
790
+ value: array,
797
791
  set: false,
798
- value: array
792
+ get: (local) => {
793
+ if (!local)
794
+ return this.state.get(key);
795
+ if (context.has(local))
796
+ return context.get(local);
797
+ const output = getLocal(local);
798
+ context.set(local, output);
799
+ return output;
800
+ }
799
801
  };
800
802
  });
801
803
  }
802
804
 
803
- function ref(arg) {
805
+ function ref(callback) {
804
806
  return apply(function ref(key) {
805
- let value = {};
806
- if (typeof arg == "object") {
807
- const source = control(arg);
808
- for (const key in source.state)
809
- defineLazy(value, key, createRef.bind(source, key));
810
- }
811
- else
812
- value = createRef.call(this, key, arg);
813
- return { value, explicit: true };
814
- });
815
- }
816
- function createRef(key, cb) {
817
- const refObjectFunction = this.ref(key, cb && createValueEffect(cb));
818
- defineProperty(refObjectFunction, "current", {
819
- set: refObjectFunction,
820
- get: () => this.state[key]
807
+ const value = this.ref(key, callback && createValueEffect(callback));
808
+ defineProperty(value, "current", {
809
+ set: value,
810
+ get: () => this.state.get(key)
811
+ });
812
+ return {
813
+ value,
814
+ explicit: true
815
+ };
821
816
  });
822
- return refObjectFunction;
823
817
  }
824
818
 
825
819
  const Oops$7 = issues({
@@ -827,65 +821,64 @@ const Oops$7 = issues({
827
821
  NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
828
822
  Failed: (model, key) => `Generating initial value for ${model}.${key} failed.`
829
823
  });
830
- function set(factory, argument) {
824
+ function put(factory, argument) {
831
825
  return apply(function set(key) {
832
826
  const { subject, state } = this;
833
827
  const required = argument === true || argument === undefined;
834
828
  let set;
835
829
  let get;
836
- let suspense;
837
- if (factory === undefined)
838
- suspense = true;
839
- else {
840
- let pending;
841
- let error;
842
- const init = () => {
843
- const output = typeof factory == "function" ?
844
- mayRetry(() => factory.call(subject, key, subject)) :
845
- factory;
846
- if (output instanceof Promise) {
847
- pending = output
848
- .catch(err => error = err)
849
- .then(val => state[key] = val)
850
- .finally(() => {
851
- pending = undefined;
852
- this.update(key);
853
- });
854
- return;
855
- }
856
- return state[key] = output;
857
- };
858
- const suspend = () => {
859
- if (required === false)
860
- return undefined;
861
- const issue = Oops$7.NotReady(subject, key);
862
- Object.assign(pending, {
863
- message: issue.message,
864
- stack: issue.stack
830
+ let pending;
831
+ let error;
832
+ const init = () => {
833
+ const output = typeof factory == "function" ?
834
+ mayRetry(() => factory.call(subject, key, subject)) :
835
+ factory;
836
+ if (output instanceof Promise) {
837
+ pending = output
838
+ .catch(err => error = err)
839
+ .then(val => {
840
+ state.set(key, val);
841
+ return val;
842
+ })
843
+ .finally(() => {
844
+ pending = undefined;
845
+ this.update(key);
865
846
  });
866
- throw pending;
867
- };
868
- if (required)
869
- try {
870
- init();
871
- }
872
- catch (err) {
873
- Oops$7.Failed(subject, key).warn();
874
- throw err;
875
- }
876
- get = () => {
877
- if (pending)
878
- return suspend();
879
- if (error)
880
- throw error;
881
- if (key in state)
882
- return state[key];
883
- let output = init();
884
- return pending
885
- ? suspend()
886
- : output;
887
- };
888
- }
847
+ return;
848
+ }
849
+ state.set(key, output);
850
+ return output;
851
+ };
852
+ const suspend = () => {
853
+ if (required === false)
854
+ return undefined;
855
+ const issue = Oops$7.NotReady(subject, key);
856
+ Object.assign(pending, {
857
+ message: issue.message,
858
+ stack: issue.stack
859
+ });
860
+ throw pending;
861
+ };
862
+ if (required)
863
+ try {
864
+ init();
865
+ }
866
+ catch (err) {
867
+ Oops$7.Failed(subject, key).warn();
868
+ throw err;
869
+ }
870
+ get = () => {
871
+ if (pending)
872
+ return suspend();
873
+ if (error)
874
+ throw error;
875
+ if (state.has(key))
876
+ return state.get(key);
877
+ let output = init();
878
+ return pending
879
+ ? suspend()
880
+ : output;
881
+ };
889
882
  if (typeof argument == "function")
890
883
  set = createValueEffect(argument);
891
884
  else
@@ -895,8 +888,24 @@ function set(factory, argument) {
895
888
  };
896
889
  return {
897
890
  set,
898
- get,
899
- suspense
891
+ get
892
+ };
893
+ });
894
+ }
895
+
896
+ function set(value, argument) {
897
+ if (!(1 in arguments)) {
898
+ argument = value;
899
+ value = undefined;
900
+ }
901
+ return apply(function set(key) {
902
+ if (value !== undefined)
903
+ this.state.set(key, value);
904
+ return {
905
+ suspense: true,
906
+ set: typeof argument == "function"
907
+ ? createValueEffect(argument)
908
+ : undefined
900
909
  };
901
910
  });
902
911
  }
@@ -921,35 +930,212 @@ function parent(Expects, required) {
921
930
  });
922
931
  }
923
932
 
933
+ const ANY$1 = Symbol("any");
934
+ function managedMap(control, property, initial) {
935
+ const context = new WeakMap();
936
+ const lastUpdate = new Set();
937
+ let managed;
938
+ let value;
939
+ function reset() {
940
+ lastUpdate.clear();
941
+ }
942
+ function emit(key) {
943
+ lastUpdate.add(key);
944
+ control.update(property);
945
+ control.waiting.add(reset);
946
+ }
947
+ function setValue(next, initial) {
948
+ value = next;
949
+ managed = create(next);
950
+ control.state.set(property, next);
951
+ if (!initial)
952
+ emit(ANY$1);
953
+ managed.set = (k, v) => {
954
+ emit(k);
955
+ return value.set(k, v);
956
+ };
957
+ managed.delete = (k) => {
958
+ emit(k);
959
+ return value.delete(k);
960
+ };
961
+ managed.clear = () => {
962
+ emit(ANY$1);
963
+ value.clear();
964
+ };
965
+ }
966
+ function getValue(local) {
967
+ if (!local)
968
+ return managed;
969
+ if (context.has(local))
970
+ return context.get(local);
971
+ const proxy = Object.create(managed);
972
+ const using = new Set();
973
+ context.set(local, proxy);
974
+ local.add(property, () => {
975
+ if (using.has(ANY$1) || lastUpdate.has(ANY$1) && using.size)
976
+ return true;
977
+ for (const key of lastUpdate)
978
+ if (using.has(key))
979
+ return true;
980
+ });
981
+ const watch = (key) => {
982
+ if (!local.active)
983
+ using.add(key);
984
+ };
985
+ proxy.get = (key) => {
986
+ watch(key);
987
+ return value.get(key);
988
+ };
989
+ proxy.has = (key) => {
990
+ watch(key);
991
+ return value.has(key);
992
+ };
993
+ proxy.values = () => {
994
+ watch(ANY$1);
995
+ return value.values();
996
+ };
997
+ proxy.keys = () => {
998
+ watch(ANY$1);
999
+ return value.keys();
1000
+ };
1001
+ proxy.entries = () => {
1002
+ watch(ANY$1);
1003
+ return value.entries();
1004
+ };
1005
+ proxy[Symbol.iterator] = () => {
1006
+ watch(ANY$1);
1007
+ return value[Symbol.iterator]();
1008
+ };
1009
+ defineProperty(proxy, "size", {
1010
+ get() {
1011
+ watch(ANY$1);
1012
+ return value.size;
1013
+ }
1014
+ });
1015
+ return proxy;
1016
+ }
1017
+ setValue(initial, true);
1018
+ return {
1019
+ set: setValue,
1020
+ get: getValue
1021
+ };
1022
+ }
1023
+
1024
+ const ANY = Symbol("any");
1025
+ function managedSet(control, property, initial) {
1026
+ const context = new WeakMap();
1027
+ const lastUpdate = new Set();
1028
+ let managed;
1029
+ let value;
1030
+ function reset() {
1031
+ lastUpdate.clear();
1032
+ }
1033
+ function emit(key) {
1034
+ lastUpdate.add(key);
1035
+ control.update(property);
1036
+ control.waiting.add(reset);
1037
+ }
1038
+ function setValue(next, initial) {
1039
+ value = next;
1040
+ managed = create(next);
1041
+ control.state.set(property, next);
1042
+ if (!initial)
1043
+ emit(ANY);
1044
+ managed.add = (k) => {
1045
+ emit(k);
1046
+ return value.add(k);
1047
+ };
1048
+ managed.delete = (k) => {
1049
+ emit(k);
1050
+ return value.delete(k);
1051
+ };
1052
+ managed.clear = () => {
1053
+ emit(ANY);
1054
+ value.clear();
1055
+ };
1056
+ }
1057
+ function getValue(local) {
1058
+ if (!local)
1059
+ return managed;
1060
+ if (context.has(local))
1061
+ return context.get(local);
1062
+ const proxy = Object.create(managed);
1063
+ const using = new Set();
1064
+ context.set(local, proxy);
1065
+ local.add(property, () => {
1066
+ if (using.has(ANY) || lastUpdate.has(ANY) && using.size)
1067
+ return true;
1068
+ for (const key of lastUpdate)
1069
+ if (using.has(key))
1070
+ return true;
1071
+ });
1072
+ const watch = (key) => {
1073
+ if (!local.active)
1074
+ using.add(key);
1075
+ };
1076
+ proxy.has = (key) => {
1077
+ watch(key);
1078
+ return value.has(key);
1079
+ };
1080
+ proxy.values = () => {
1081
+ watch(ANY);
1082
+ return value.values();
1083
+ };
1084
+ proxy.keys = () => {
1085
+ watch(ANY);
1086
+ return value.keys();
1087
+ };
1088
+ proxy.entries = () => {
1089
+ watch(ANY);
1090
+ return value.entries();
1091
+ };
1092
+ proxy[Symbol.iterator] = () => {
1093
+ watch(ANY);
1094
+ return value[Symbol.iterator]();
1095
+ };
1096
+ defineProperty(proxy, "size", {
1097
+ get() {
1098
+ watch(ANY);
1099
+ return value.size;
1100
+ }
1101
+ });
1102
+ return proxy;
1103
+ }
1104
+ setValue(initial, true);
1105
+ return {
1106
+ set: setValue,
1107
+ get: getValue
1108
+ };
1109
+ }
1110
+
924
1111
  const Oops$5 = issues({
925
1112
  BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
926
1113
  });
927
1114
  function use$1(input, argument) {
928
1115
  return apply(function use(key) {
929
- const { subject } = this;
930
- const onUpdate = (next) => {
931
- this.state[key] = next;
1116
+ const { state, subject } = this;
1117
+ if (typeof input === "function")
1118
+ input = Model.isTypeof(input)
1119
+ ? new input()
1120
+ : input();
1121
+ else if (input && typeof input !== "object")
1122
+ throw Oops$5.BadArgument(typeof input);
1123
+ if (input instanceof Map)
1124
+ return managedMap(this, key, input);
1125
+ if (input instanceof Set)
1126
+ return managedSet(this, key, input);
1127
+ function onUpdate(next) {
1128
+ state.set(key, next);
932
1129
  if (next) {
933
1130
  Parent.set(next, subject);
934
- control(next);
1131
+ ensure(next);
935
1132
  }
936
1133
  if (typeof argument == "function")
937
1134
  argument(next);
938
1135
  return true;
939
- };
940
- if (input) {
941
- const value = Model.isTypeof(input)
942
- ? new input() :
943
- typeof input === "object"
944
- ? input :
945
- typeof input === "function"
946
- ? input()
947
- : null;
948
- if (value === null)
949
- throw Oops$5.BadArgument(typeof input);
950
- if (value)
951
- onUpdate(value);
952
1136
  }
1137
+ if (input)
1138
+ onUpdate(input);
953
1139
  return {
954
1140
  set: onUpdate,
955
1141
  recursive: true
@@ -1061,7 +1247,8 @@ function tap(type, argument) {
1061
1247
  }
1062
1248
  else if (!instance && argument)
1063
1249
  throw Oops$3.AmbientRequired(type.name, subject, key);
1064
- this.update(key, instance);
1250
+ this.state.set(key, instance);
1251
+ this.update(key);
1065
1252
  });
1066
1253
  return {
1067
1254
  recursive: true,
@@ -1106,7 +1293,7 @@ function useModel(source, arg, arg2) {
1106
1293
  new source() :
1107
1294
  source() :
1108
1295
  source;
1109
- control(instance);
1296
+ ensure(instance);
1110
1297
  if (typeof cb == "function")
1111
1298
  cb(instance);
1112
1299
  return instance;
@@ -1124,7 +1311,7 @@ function useModel(source, arg, arg2) {
1124
1311
  return instance;
1125
1312
  }
1126
1313
  else {
1127
- const local = use(refresh => (new Subscriber(instance, () => refresh)));
1314
+ const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1128
1315
  if (typeof arg == "object") {
1129
1316
  local.active = false;
1130
1317
  if (typeof arg2 !== "object")
@@ -1150,7 +1337,7 @@ function useModel(source, arg, arg2) {
1150
1337
 
1151
1338
  function useFrom(target, compute, suspend) {
1152
1339
  const local = use(refresh => {
1153
- const sub = new Subscriber(target, () => update);
1340
+ const sub = ensure(target).subscribe(() => update);
1154
1341
  const spy = sub.proxy;
1155
1342
  let value = compute.call(spy, spy);
1156
1343
  let update;
@@ -1202,23 +1389,14 @@ function useTap(source, path, expect) {
1202
1389
  }, [])();
1203
1390
  if (typeof path == "function")
1204
1391
  return useFrom(instance, path, expect);
1205
- const local = use(refresh => {
1206
- const parent = control(instance);
1207
- const sub = new Subscriber(parent, () => refresh);
1208
- if (typeof path == "string") {
1209
- const source = sub.proxy;
1210
- defineProperty(sub, "proxy", {
1211
- get() {
1212
- const value = source[path];
1213
- if (value === undefined && expect)
1214
- throw suspend(parent, path);
1215
- return value;
1216
- }
1217
- });
1218
- }
1219
- return sub;
1220
- });
1392
+ const local = use(refresh => (ensure(instance).subscribe(() => refresh)));
1221
1393
  React.useLayoutEffect(local.commit, []);
1394
+ if (typeof path !== "undefined") {
1395
+ const value = local.proxy[path];
1396
+ if (value === undefined && expect)
1397
+ throw suspend(ensure(instance), path);
1398
+ return value;
1399
+ }
1222
1400
  return local.proxy;
1223
1401
  }
1224
1402
 
@@ -1239,7 +1417,7 @@ class MVC extends Model {
1239
1417
  static new(arg) {
1240
1418
  const instance = React.useMemo(() => {
1241
1419
  const instance = new this();
1242
- control(instance);
1420
+ ensure(instance);
1243
1421
  if (typeof arg == "function")
1244
1422
  arg(instance);
1245
1423
  else if (arg)
@@ -1324,7 +1502,7 @@ function useAppliedProps(within, props) {
1324
1502
  const targets = within.local;
1325
1503
  return function integrate(props) {
1326
1504
  for (const [key, value] of entries(props))
1327
- if (["of", "for", "children"].indexOf(key) < 0)
1505
+ if (!["of", "for", "children"].includes(key))
1328
1506
  for (const into of targets)
1329
1507
  if (into && key in into)
1330
1508
  into[key] = value;
@@ -1336,7 +1514,7 @@ function RenderFunction(props) {
1336
1514
  const hook = use(refresh => {
1337
1515
  const targets = props.context.local;
1338
1516
  if (targets.length == 1)
1339
- return new Subscriber(targets[0], () => refresh);
1517
+ return ensure(targets[0]).subscribe(() => refresh);
1340
1518
  return {};
1341
1519
  });
1342
1520
  if (hook.commit)
@@ -1388,5 +1566,5 @@ class Global extends MVC {
1388
1566
  }
1389
1567
  }
1390
1568
 
1391
- export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1569
+ export { CONTROL, Consumer, Global, LOCAL, MVC as Model, Provider, STATE, WHY, act, apply, array, MVC as default, from, parent, put, ref, set, tap, use$1 as use, useFrom, useLocal, useModel, useTap };
1392
1570
  //# sourceMappingURL=index.esm.js.map