@expressive/mvc 0.12.0 → 0.13.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
@@ -9,8 +9,17 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
9
9
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
10
10
 
11
11
  const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
12
- function unique(array) {
13
- return Array.from(new Set(array));
12
+ const UID_CACHE = new WeakMap();
13
+ function assignWeak(into, from) {
14
+ for (const K in from)
15
+ if (K in into)
16
+ into[K] = from[K];
17
+ }
18
+ function uid(object) {
19
+ let uid = UID_CACHE.get(object);
20
+ if (!uid)
21
+ UID_CACHE.set(object, uid = Math.random());
22
+ return uid;
14
23
  }
15
24
 
16
25
  class Issue extends Error {
@@ -169,7 +178,7 @@ const Oops$d = issues({
169
178
  BadCallback: () => `Callback for effect-callback may only return a function.`
170
179
  });
171
180
  function createEffect(model, callback, keys) {
172
- return Control.for(model, control => {
181
+ return control(model, controller => {
173
182
  let unSet;
174
183
  let busy = false;
175
184
  function effect(value) {
@@ -194,7 +203,7 @@ function createEffect(model, callback, keys) {
194
203
  }
195
204
  if (Array.isArray(keys)) {
196
205
  invoke();
197
- return control.addListener(key => {
206
+ return controller.addListener(key => {
198
207
  if (key === null) {
199
208
  if (!keys.length)
200
209
  invoke();
@@ -203,7 +212,7 @@ function createEffect(model, callback, keys) {
203
212
  return invoke;
204
213
  });
205
214
  }
206
- const sub = control.subscribe(() => invoke);
215
+ const sub = controller.subscribe(() => invoke);
207
216
  model = sub.proxy;
208
217
  invoke();
209
218
  return sub.commit();
@@ -235,13 +244,13 @@ const Oops$c = issues({
235
244
  function addEventListener(source, arg1, arg2, arg3) {
236
245
  if (typeof arg1 == "string")
237
246
  arg1 = [arg1];
238
- return Control.for(source, control => {
247
+ return control(source, controller => {
239
248
  for (const key of arg1)
240
249
  try {
241
250
  void source[key];
242
251
  }
243
252
  catch (e) { }
244
- const removeListener = control.addListener(key => {
253
+ const removeListener = controller.addListener(key => {
245
254
  if (!key && !arg1.length)
246
255
  arg2.call(source, []);
247
256
  if (arg1.includes(key)) {
@@ -264,8 +273,8 @@ function awaitUpdate(source, arg1, arg2) {
264
273
  removeListener();
265
274
  reject(Oops$c.Timeout(k, message));
266
275
  };
267
- const removeListener = Control.for(source, control => {
268
- const pending = control.frame;
276
+ const removeListener = control(source, controller => {
277
+ const pending = controller.frame;
269
278
  if (keys === null) {
270
279
  if (pending.size)
271
280
  reject(Oops$c.StrictNoUpdate());
@@ -292,8 +301,8 @@ function awaitUpdate(source, arg1, arg2) {
292
301
  return;
293
302
  }
294
303
  else
295
- control.waiting.add(resolve);
296
- return control.addListener(key => {
304
+ controller.waiting.add(resolve);
305
+ return controller.addListener(key => {
297
306
  if (!key) {
298
307
  if (keys && !keys.length)
299
308
  resolve([]);
@@ -302,7 +311,7 @@ function awaitUpdate(source, arg1, arg2) {
302
311
  }
303
312
  else if (!keys || keys.includes(key)) {
304
313
  removeListener();
305
- return keys => resolve(single ? control.state.get(key) : keys);
314
+ return keys => resolve(single ? controller.state.get(key) : keys);
306
315
  }
307
316
  });
308
317
  });
@@ -319,35 +328,6 @@ class Subscriber {
319
328
  this.active = false;
320
329
  this.dependant = new Set();
321
330
  this.watch = new Map();
322
- this.commit = () => {
323
- const release = this.parent.addListener(this.event);
324
- this.active = true;
325
- this.dependant.forEach(x => x.commit());
326
- return this.release = () => {
327
- this.dependant.forEach(x => x.release());
328
- release();
329
- };
330
- };
331
- this.event = (key) => {
332
- if (!this.active)
333
- return;
334
- const { parent, watch } = this;
335
- const handler = watch.get(key);
336
- let notify;
337
- if (typeof handler == "function") {
338
- const callback = handler();
339
- if (callback === true)
340
- notify = this.onUpdate(key, parent);
341
- }
342
- else if (handler === true)
343
- notify = this.onUpdate(key, parent);
344
- if (!notify)
345
- return;
346
- parent.waiting.add(update => {
347
- this.latest = update.filter(k => watch.has(k));
348
- });
349
- parent.waiting.add(notify);
350
- };
351
331
  const proxy = create(parent.subject);
352
332
  const reset = () => this.latest = undefined;
353
333
  REGISTER$1.set(proxy, this);
@@ -359,28 +339,45 @@ class Subscriber {
359
339
  }
360
340
  });
361
341
  }
362
- static get(from) {
363
- return REGISTER$1.get(from);
364
- }
365
342
  get using() {
366
343
  return Array.from(this.watch.keys());
367
344
  }
368
- assign(apply, keys) {
369
- const { waiting, subject } = this.parent;
370
- this.active = false;
371
- if (typeof keys !== "object")
372
- keys = getOwnPropertyNames(subject);
373
- for (const key of keys)
374
- if (key in apply)
375
- subject[key] = apply[key];
376
- waiting.add(() => this.active = true);
377
- }
378
345
  add(key, value) {
379
346
  if (value !== undefined)
380
347
  this.watch.set(key, value);
381
348
  else if (!this.watch.has(key))
382
349
  this.watch.set(key, true);
383
350
  }
351
+ commit() {
352
+ const release = this.parent.addListener(key => {
353
+ if (this.active)
354
+ this.onEvent(key);
355
+ });
356
+ this.active = true;
357
+ this.dependant.forEach(x => x.commit());
358
+ return this.release = () => {
359
+ this.dependant.forEach(x => x.release());
360
+ release();
361
+ };
362
+ }
363
+ onEvent(key) {
364
+ const { parent, watch } = this;
365
+ let handler = watch.get(key);
366
+ if (typeof handler == "function")
367
+ handler = handler();
368
+ if (handler) {
369
+ const notify = this.onUpdate(key, parent);
370
+ if (notify) {
371
+ parent.waiting.add(update => {
372
+ this.latest = update.filter(k => watch.has(k));
373
+ });
374
+ parent.waiting.add(notify);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ function subscriber(from) {
380
+ return REGISTER$1.get(from);
384
381
  }
385
382
 
386
383
  const Oops$b = issues({
@@ -400,7 +397,7 @@ class Model {
400
397
  return addEventListener(this.is, arg1, arg2, arg3);
401
398
  }
402
399
  get(arg1, arg2) {
403
- const { state } = Control.for(this);
400
+ const { state } = control(this);
404
401
  const extract = typeof arg1 == "string"
405
402
  ? () => state.get(arg1)
406
403
  : () => {
@@ -417,19 +414,20 @@ class Model {
417
414
  return this.on(arg1, timeout).then(extract);
418
415
  }
419
416
  set(arg1, arg2) {
420
- const control = Control.for(this);
417
+ const controller = control(this);
418
+ const { state } = controller;
421
419
  if (typeof arg1 == "object")
422
420
  for (const key in arg1) {
423
- if (arg2 === true || (arg2 ? arg2.includes(key) : control.state.has(key))) {
424
- control.state.set(key, arg1[key]);
425
- control.update(key);
421
+ if (arg2 === true || (arg2 ? arg2.includes(key) : state.has(key))) {
422
+ state.set(key, arg1[key]);
423
+ controller.update(key);
426
424
  }
427
425
  }
428
426
  else if (typeof arg1 == "string") {
429
- control.update(arg1);
427
+ controller.update(arg1);
430
428
  if (1 in arguments) {
431
- if (control.state.has(arg1))
432
- control.state.set(arg1, arg2);
429
+ if (state.has(arg1))
430
+ state.set(arg1, arg2);
433
431
  else if (arg1 in this) {
434
432
  const method = this[arg1];
435
433
  if (typeof method == "function")
@@ -441,7 +439,7 @@ class Model {
441
439
  then: (callback) => {
442
440
  if (!callback)
443
441
  throw Oops$b.NoChaining();
444
- control.waiting.add(callback);
442
+ controller.waiting.add(callback);
445
443
  }
446
444
  };
447
445
  }
@@ -449,7 +447,7 @@ class Model {
449
447
  * Clean up side effects and mark this instance for garbage-collection.
450
448
  */
451
449
  end() {
452
- Control.for(this).clear();
450
+ control(this).clear();
453
451
  }
454
452
  /**
455
453
  * Creates a new instance of this controller.
@@ -460,7 +458,7 @@ class Model {
460
458
  */
461
459
  static new(...args) {
462
460
  const instance = new this(...args);
463
- Control.for(instance);
461
+ control(instance);
464
462
  return instance;
465
463
  }
466
464
  /**
@@ -515,7 +513,7 @@ class Control {
515
513
  enumerable: false,
516
514
  set: this.ref(key),
517
515
  get() {
518
- const sub = Subscriber.get(this);
516
+ const sub = subscriber(this);
519
517
  if (sub)
520
518
  sub.add(key);
521
519
  return state.get(key);
@@ -575,34 +573,34 @@ class Control {
575
573
  this.followers.clear();
576
574
  listeners.forEach(x => x(null, this));
577
575
  }
578
- static get(from) {
579
- if (from && "is" in from)
580
- from = from.is;
581
- return REGISTER.get(from);
582
- }
583
- static for(subject, cb) {
584
- const control = this.get(subject) || new this(subject);
585
- if (!control.state) {
586
- const { waiting } = control;
587
- if (cb) {
588
- let callback;
589
- waiting.add(() => {
590
- callback = cb(control);
591
- });
592
- return () => {
593
- if (callback)
594
- callback();
595
- };
596
- }
597
- control.state = new Map();
598
- for (const key in subject)
599
- control.watch(key);
600
- control.waiting = new Set();
601
- for (const cb of waiting)
602
- cb([]);
576
+ }
577
+ function controller(from) {
578
+ if ("is" in from)
579
+ from = from.is;
580
+ return REGISTER.get(from);
581
+ }
582
+ function control(subject, cb) {
583
+ const control = controller(subject) || new Control(subject);
584
+ if (!control.state) {
585
+ const { waiting } = control;
586
+ if (cb) {
587
+ let callback;
588
+ waiting.add(() => {
589
+ callback = cb(control);
590
+ });
591
+ return () => {
592
+ if (callback)
593
+ callback();
594
+ };
603
595
  }
604
- return cb ? cb(control) : control;
596
+ control.state = new Map();
597
+ for (const key in subject)
598
+ control.watch(key);
599
+ control.waiting = new Set();
600
+ for (const cb of waiting)
601
+ cb([]);
605
602
  }
603
+ return cb ? cb(control) : control;
606
604
  }
607
605
 
608
606
  const Parent = new WeakMap();
@@ -621,8 +619,8 @@ function getRecursive(key, from) {
621
619
  if (reset)
622
620
  reset();
623
621
  const value = state.get(key);
624
- if (Control.get(value)) {
625
- const child = Control.for(value).subscribe(local.onUpdate);
622
+ if (value && controller(value)) {
623
+ const child = control(value).subscribe(local.onUpdate);
626
624
  if (local.active)
627
625
  child.commit();
628
626
  local.dependant.add(child);
@@ -642,24 +640,24 @@ function getRecursive(key, from) {
642
640
  return context.get(local);
643
641
  };
644
642
  }
645
- function setRecursive(control, key, initial) {
646
- const { state, subject } = control;
643
+ function setRecursive(controller, key, initial) {
644
+ const { state, subject } = controller;
647
645
  const Type = initial.constructor;
648
646
  let get;
649
647
  const onUpdate = (next) => {
650
648
  state.set(key, next);
651
649
  if (!(next instanceof Type))
652
650
  throw Oops$a.BadAssignment(`${subject}.${key}`, Type.name, String(next));
653
- get = getRecursive(key, control);
651
+ get = getRecursive(key, controller);
654
652
  Parent.set(next, subject);
655
- Control.for(next);
653
+ control(next);
656
654
  return true;
657
655
  };
658
656
  onUpdate(initial);
659
657
  defineProperty(subject, key, {
660
- set: control.ref(key, onUpdate),
658
+ set: controller.ref(key, onUpdate),
661
659
  get() {
662
- const local = Subscriber.get(this);
660
+ const local = subscriber(this);
663
661
  if (local)
664
662
  local.add(key);
665
663
  return get(local);
@@ -707,7 +705,7 @@ function add(instruction, label) {
707
705
  get() {
708
706
  if (!state.has(key) && shouldSuspend)
709
707
  throw suspend(control, key);
710
- const local = Subscriber.get(this);
708
+ const local = subscriber(this);
711
709
  if (local)
712
710
  local.add(key);
713
711
  return onGet
@@ -838,7 +836,7 @@ function get(arg0, arg1, arg2) {
838
836
  let source = this;
839
837
  let setter;
840
838
  if (typeof arg0 == "function") {
841
- const result = mayRetry(() => arg0.call(subject, key, subject));
839
+ let result = mayRetry(arg0.bind(subject, key, subject));
842
840
  if (typeof result == "function")
843
841
  setter = result;
844
842
  else {
@@ -852,7 +850,7 @@ function get(arg0, arg1, arg2) {
852
850
  }
853
851
  else if (typeof arg1 == "function") {
854
852
  // replace source controller in-case it is different
855
- source = Control.for(arg0);
853
+ source = control(arg0);
856
854
  setter = arg1;
857
855
  }
858
856
  else
@@ -882,7 +880,7 @@ function ref(arg, mapper) {
882
880
  if (typeof arg != "object")
883
881
  value = createRef(this, key, arg);
884
882
  else
885
- Control.for(arg).state.forEach((_val, key) => {
883
+ control(arg).state.forEach((_val, key) => {
886
884
  defineProperty(value, key, mapper ? {
887
885
  configurable: true,
888
886
  get() {
@@ -1093,7 +1091,7 @@ function use$1(input, argument) {
1093
1091
  if (next) {
1094
1092
  get = getRecursive(key, this);
1095
1093
  Parent.set(next, subject);
1096
- Control.for(next);
1094
+ control(next);
1097
1095
  }
1098
1096
  if (typeof argument == "function")
1099
1097
  argument(next);
@@ -1173,9 +1171,6 @@ class Lookup {
1173
1171
  constructor() {
1174
1172
  this.table = new Map();
1175
1173
  }
1176
- get local() {
1177
- return unique(getOwnPropertySymbols(this).map(symbol => this[symbol]));
1178
- }
1179
1174
  key(T) {
1180
1175
  let key = this.table.get(T);
1181
1176
  if (!key) {
@@ -1184,15 +1179,26 @@ class Lookup {
1184
1179
  }
1185
1180
  return key;
1186
1181
  }
1187
- get(T) {
1188
- return this[this.key(T)];
1182
+ get(Type) {
1183
+ return this[this.key(Type)];
1184
+ }
1185
+ has(key, input, callback) {
1186
+ if (MVC.isTypeof(input) && input.global)
1187
+ return input.new();
1188
+ if (this.register.get(key) === input)
1189
+ return typeof input == "object"
1190
+ ? input
1191
+ : this.get(input);
1192
+ const instance = this.add(input);
1193
+ this.register.set(key, input);
1194
+ if (callback)
1195
+ callback(instance);
1196
+ return instance;
1189
1197
  }
1190
1198
  add(input) {
1191
1199
  let writable = true;
1192
1200
  let T;
1193
1201
  let I;
1194
- if (MVC.isTypeof(input) && input.global)
1195
- return input.new();
1196
1202
  if (typeof input == "function") {
1197
1203
  T = input;
1198
1204
  I = new input();
@@ -1204,10 +1210,9 @@ class Lookup {
1204
1210
  }
1205
1211
  do {
1206
1212
  const key = this.key(T);
1207
- const conflict = this.hasOwnProperty(key);
1208
1213
  defineProperty(this, key, {
1209
- value: conflict ? null : I,
1210
1214
  configurable: true,
1215
+ value: this.hasOwnProperty(key) ? null : I,
1211
1216
  writable
1212
1217
  });
1213
1218
  T = getPrototypeOf(T);
@@ -1215,7 +1220,9 @@ class Lookup {
1215
1220
  return I;
1216
1221
  }
1217
1222
  push() {
1218
- return create(this);
1223
+ const next = create(this);
1224
+ next.register = new Map();
1225
+ return next;
1219
1226
  }
1220
1227
  pop() {
1221
1228
  const items = new Set();
@@ -1245,7 +1252,7 @@ const Pending = new WeakMap();
1245
1252
  const Applied = new WeakMap();
1246
1253
  function tap(type, argument) {
1247
1254
  return add(function tap(key) {
1248
- if (type.global)
1255
+ if (MVC.isTypeof(type) && type.global)
1249
1256
  return {
1250
1257
  recursive: true,
1251
1258
  value: type.get()
@@ -1292,20 +1299,13 @@ function getPending(subject) {
1292
1299
  return pending;
1293
1300
  }
1294
1301
 
1295
- function use(init) {
1296
- const [state, update] = React__default["default"].useState(() => [
1297
- init(() => update(state.concat()))
1298
- ]);
1299
- return state[0];
1300
- }
1301
-
1302
1302
  function useNew(source, arg1, arg2) {
1303
1303
  const instance = React__default["default"].useMemo(() => {
1304
1304
  const callback = arg2 || arg1;
1305
1305
  const instance = Model.isTypeof(source)
1306
1306
  ? new source()
1307
1307
  : source();
1308
- Control.for(instance);
1308
+ control(instance);
1309
1309
  if (typeof callback == "function")
1310
1310
  callback(instance);
1311
1311
  return instance;
@@ -1323,9 +1323,22 @@ function useNew(source, arg1, arg2) {
1323
1323
  }, []);
1324
1324
  return instance;
1325
1325
  }
1326
- const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1327
- if (typeof arg1 == "object")
1328
- local.assign(arg1, arg2);
1326
+ const state = React__default["default"].useState(0);
1327
+ const local = React__default["default"].useMemo(() => {
1328
+ const refresh = state[1].bind(null, x => x + 1);
1329
+ return control(instance).subscribe(() => refresh);
1330
+ }, []);
1331
+ if (typeof arg1 == "object") {
1332
+ const { waiting, subject } = local.parent;
1333
+ let keys = arg2;
1334
+ local.active = false;
1335
+ if (!keys)
1336
+ keys = getOwnPropertyNames(subject);
1337
+ for (const key of keys)
1338
+ if (key in arg1)
1339
+ subject[key] = arg1[key];
1340
+ waiting.add(() => local.active = true);
1341
+ }
1329
1342
  React__default["default"].useLayoutEffect(() => {
1330
1343
  local.commit();
1331
1344
  return () => {
@@ -1337,9 +1350,17 @@ function useNew(source, arg1, arg2) {
1337
1350
  return local.proxy;
1338
1351
  }
1339
1352
 
1340
- function useValue(source, compute, suspend) {
1353
+ function use(init, deps) {
1354
+ const state = React__default["default"].useState(0);
1355
+ return React__default["default"].useMemo(() => {
1356
+ return init(state[1].bind(null, x => x + 1));
1357
+ }, deps);
1358
+ }
1359
+
1360
+ function useCompute(source, compute, suspend) {
1361
+ const deps = [uid(source)];
1341
1362
  const local = use(refresh => {
1342
- const sub = Control.for(source).subscribe(() => update);
1363
+ const sub = control(source).subscribe(() => update);
1343
1364
  const spy = sub.proxy;
1344
1365
  let value = compute.call(spy, spy);
1345
1366
  let update;
@@ -1388,30 +1409,30 @@ function useValue(source, compute, suspend) {
1388
1409
  }
1389
1410
  });
1390
1411
  return sub;
1391
- });
1392
- React__default["default"].useLayoutEffect(() => local.release, []);
1412
+ }, deps);
1413
+ React__default["default"].useLayoutEffect(() => local.release, deps);
1393
1414
  return local.proxy;
1394
1415
  }
1395
1416
 
1396
1417
  function useTap(source, arg1, arg2) {
1397
- const instance = React.useMemo(() => {
1398
- if (typeof source == "object")
1399
- return () => source;
1400
- if (Model.isTypeof(source))
1401
- return "get" in source
1402
- ? () => source.get()
1403
- : () => useContext(source);
1404
- return source;
1405
- }, [])();
1406
- if (typeof arg1 == "function")
1407
- return useValue(instance, arg1, arg2);
1408
- const local = use(refresh => (Control.for(instance).subscribe(() => refresh)));
1409
- React__default["default"].useLayoutEffect(local.commit, []);
1410
- if (arg1 === undefined)
1418
+ const instance = typeof source == "object"
1419
+ ? source
1420
+ : "get" in source
1421
+ ? source.get()
1422
+ : useContext(source);
1423
+ return typeof arg1 == "function"
1424
+ ? useCompute(instance, arg1, arg2)
1425
+ : useSubscribe(instance, arg1, arg2);
1426
+ }
1427
+ function useSubscribe(source, path, expect) {
1428
+ const deps = [uid(source)];
1429
+ const local = use(refresh => (control(source).subscribe(() => refresh)), deps);
1430
+ React__default["default"].useLayoutEffect(() => local.commit(), deps);
1431
+ if (path === undefined)
1411
1432
  return local.proxy;
1412
- const value = local.proxy[arg1];
1413
- if (value === undefined && arg2)
1414
- throw suspend(local.parent, arg1);
1433
+ const value = local.proxy[path];
1434
+ if (value === undefined && expect)
1435
+ throw suspend(local.parent, path);
1415
1436
  return value;
1416
1437
  }
1417
1438
 
@@ -1469,14 +1490,19 @@ class MVC extends Model {
1469
1490
  callback(arg2);
1470
1491
  return instance;
1471
1492
  }
1472
- static tap(key, expect) {
1473
- return useTap(this, key, expect);
1493
+ static tap(arg1, arg2) {
1494
+ const instance = this.get();
1495
+ return typeof arg1 == "function"
1496
+ ? useCompute(instance, arg1, arg2)
1497
+ : useSubscribe(instance, arg1, arg2);
1474
1498
  }
1475
1499
  static use(a, b) {
1476
1500
  return useNew(this, a, b);
1477
1501
  }
1478
- static meta(path, expect) {
1479
- return useTap(() => this, path, expect);
1502
+ static meta(arg1, arg2) {
1503
+ return typeof arg1 == "function"
1504
+ ? useCompute(this, arg1, arg2)
1505
+ : useSubscribe(this, arg1, arg2);
1480
1506
  }
1481
1507
  }
1482
1508
 
@@ -1500,47 +1526,39 @@ const Oops = issues({
1500
1526
  });
1501
1527
  function Provider(props) {
1502
1528
  const context = useNewContext(props.for, props.and);
1503
- React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1504
1529
  return (React__default["default"].createElement(LookupContext.Provider, { value: context }, props.fallback === false
1505
1530
  ? props.children
1506
1531
  : (React__default["default"].createElement(React.Suspense, { fallback: props.fallback || null }, props.children))));
1507
1532
  }
1508
1533
  function useNewContext(include, assign) {
1534
+ const init = new Set();
1509
1535
  const ambient = useLookup();
1510
1536
  const context = React__default["default"].useMemo(() => {
1511
1537
  if (!include)
1512
1538
  throw Oops.NoType();
1513
- const next = ambient.push();
1514
- function register(T) {
1515
- const i = next.add(T);
1516
- if (assign)
1517
- assignWeak(i, assign);
1518
- Control.for(i).state.forEach(value => {
1519
- if (Parent.get(value) === i)
1520
- next.add(value);
1521
- });
1522
- }
1523
- if (include instanceof Model || typeof include == "function")
1524
- register(include);
1525
- else
1526
- values(include).forEach(register);
1527
- for (const instance of next.local)
1528
- if (instance)
1529
- for (const apply of getPending(instance))
1530
- apply(next);
1531
- return next;
1539
+ return ambient.push();
1532
1540
  }, []);
1533
- if (assign)
1534
- context.local.forEach(i => {
1535
- if (i && !Parent.has(i))
1536
- assignWeak(i, assign);
1541
+ function register(key, T) {
1542
+ const instance = context.has(key, T, i => init.add(i));
1543
+ if (assign)
1544
+ assignWeak(instance, assign);
1545
+ }
1546
+ if (typeof include == "function" || include instanceof Model)
1547
+ register(0, include);
1548
+ else
1549
+ entries(include).forEach(e => register(...e));
1550
+ for (const instance of init) {
1551
+ control(instance).state.forEach(value => {
1552
+ if (Parent.get(value) === instance) {
1553
+ context.add(value);
1554
+ init.add(value);
1555
+ }
1537
1556
  });
1557
+ for (const apply of getPending(instance))
1558
+ apply(context);
1559
+ }
1560
+ React__default["default"].useLayoutEffect(() => () => context.pop(), []);
1538
1561
  return context;
1539
- }
1540
- function assignWeak(into, from) {
1541
- for (const K in from)
1542
- if (K in into)
1543
- into[K] = from[K];
1544
1562
  }
1545
1563
 
1546
1564
  class Global extends MVC {
@@ -1555,17 +1573,17 @@ const CONTROL = "$debug controller";
1555
1573
  defineProperties(Model.prototype, {
1556
1574
  [CONTROL]: {
1557
1575
  get() {
1558
- return Control.get(this);
1576
+ return controller(this);
1559
1577
  }
1560
1578
  },
1561
1579
  [LOCAL]: {
1562
1580
  get() {
1563
- return Subscriber.get(this);
1581
+ return subscriber(this);
1564
1582
  }
1565
1583
  },
1566
1584
  [STATE]: {
1567
1585
  get() {
1568
- const { state } = Control.get(this);
1586
+ const { state } = controller(this);
1569
1587
  const output = {};
1570
1588
  state.forEach((value, key) => output[key] = value);
1571
1589
  return output;
@@ -1573,8 +1591,7 @@ defineProperties(Model.prototype, {
1573
1591
  },
1574
1592
  [UPDATE]: {
1575
1593
  get() {
1576
- const source = Subscriber.get(this) || Control.get(this);
1577
- return source && source.latest;
1594
+ return (subscriber(this) || controller(this)).latest;
1578
1595
  }
1579
1596
  }
1580
1597
  });