@expressive/mvc 0.20.0 → 0.21.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.d.ts CHANGED
@@ -91,7 +91,6 @@ declare class Control<T extends Model = any> {
91
91
  static for: typeof control;
92
92
  static apply: typeof apply;
93
93
  static watch: typeof watch;
94
- parent?: Model;
95
94
  state: {
96
95
  [key: string]: any;
97
96
  };
@@ -242,8 +241,8 @@ declare class Model {
242
241
  get is(): this;
243
242
  on(): Promise<Model.Event<this>[]>;
244
243
  on(timeout?: number): Promise<Model.Event<this>[] | false>;
245
- on<P extends Model.Event<this>>(keys?: P | Iterable<P>, timeout?: number): Promise<P[] | false>;
246
- on<P extends Model.Event<this>>(keys: P | Iterable<P>, listener: Model.OnCallback<this>, once?: boolean): Callback;
244
+ on<P extends Model.Event<this>>(keys?: P | P[], timeout?: number): Promise<P[] | false>;
245
+ on<P extends Model.Event<this>>(keys: P | P[], listener: Model.OnCallback<this>, once?: boolean): Callback;
247
246
  on(effect: Model.Effect<this>): Callback;
248
247
  get(): Model.Export<this>;
249
248
  get<P extends Model.Key<this>>(select: P): this[P];
@@ -251,7 +250,7 @@ declare class Model {
251
250
  get<P extends Model.Key<this>>(select: P, listener: (this: this, value: this[P]) => void): Callback;
252
251
  get<P extends Model.Key<this>>(select: Iterable<P>, listener: (this: this, value: Model.Get<this, P>) => void): Callback;
253
252
  set<T extends Model.Compat<this>>(source: T, select?: (keyof T)[]): Promise<Model.Key<T>[]>;
254
- set<K extends Model.Event<this>>(key: K, value?: Model.ValueOf<this, K>): Promise<readonly Model.Event<this>[]>;
253
+ set<K extends Model.Event<this>>(key: K, value?: Model.ValueOf<this, K>): Promise<Model.Event<this>[] | false>;
255
254
  /** Mark this instance for garbage collection. */
256
255
  null(): void;
257
256
  static get: typeof get$1;
@@ -398,12 +397,18 @@ declare function use<T extends Model>(from: () => Promise<T> | T, callback?: (i:
398
397
  */
399
398
  declare function use<T extends Model>(peer: T, callback?: (i: T) => void): T;
400
399
 
400
+ declare namespace Context {
401
+ type Inputs = {
402
+ [key: string | number]: Model | Model.New;
403
+ };
404
+ }
401
405
  declare class Context {
402
406
  private table;
403
407
  private input;
404
408
  private has;
405
409
  get<T extends Model>(Type: Model.Type<T>): T | undefined;
406
- add<T extends Model>(input: T | Model.New<T>, key?: number | string): T;
410
+ include(inputs: Context.Inputs): Map<Model, boolean>;
411
+ add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
407
412
  push(): this;
408
413
  pop(): void;
409
414
  }
package/lib/index.esm.js CHANGED
@@ -379,7 +379,7 @@ class Model {
379
379
  state[key] = arg1[key];
380
380
  controller.update(key);
381
381
  }
382
- return awaitUpdate(this, undefined, 0);
382
+ return this.on(0);
383
383
  }
384
384
  /** Mark this instance for garbage collection. */
385
385
  null() {
@@ -427,6 +427,7 @@ const Oops$5 = issues({
427
427
  const INSTRUCTION = new Map();
428
428
  const REGISTER = new WeakMap();
429
429
  const OBSERVER = new WeakMap();
430
+ const PARENTS = new WeakMap();
430
431
  class Control {
431
432
  constructor(subject, id = random()) {
432
433
  this.subject = subject;
@@ -573,7 +574,7 @@ function setRecursive(on, key, value) {
573
574
  const set = (next) => {
574
575
  if (next instanceof value.constructor) {
575
576
  on.state[key] = next;
576
- control(next).parent = on.subject;
577
+ parent(next, on.subject);
577
578
  control(next, true);
578
579
  return true;
579
580
  }
@@ -582,6 +583,11 @@ function setRecursive(on, key, value) {
582
583
  on.watch(key, { set });
583
584
  set(value);
584
585
  }
586
+ function parent(child, register) {
587
+ if (!register)
588
+ return PARENTS.get(child);
589
+ PARENTS.set(child, register);
590
+ }
585
591
  function watch(on, cb) {
586
592
  if (!on.hasOwnProperty("is"))
587
593
  on = defineProperty(create(on), "is", { value: on });
@@ -649,8 +655,8 @@ function get(arg0, arg1) {
649
655
  if (arg0 instanceof Model)
650
656
  subject = arg0;
651
657
  else if (Model.isTypeof(arg0)) {
652
- const { parent } = control;
653
- if (!parent) {
658
+ const hasParent = parent(subject);
659
+ if (!hasParent) {
654
660
  if (arg1 === true)
655
661
  throw Oops$3.Required(arg0, subject);
656
662
  source = callback => Control.has(arg0, subject, got => {
@@ -660,10 +666,10 @@ function get(arg0, arg1) {
660
666
  throw Oops$3.AmbientRequired(arg0, subject);
661
667
  });
662
668
  }
663
- else if (!arg0 || parent instanceof arg0)
664
- subject = parent;
669
+ else if (!arg0 || hasParent instanceof arg0)
670
+ subject = hasParent;
665
671
  else
666
- throw Oops$3.Unexpected(arg0, subject, parent);
672
+ throw Oops$3.Unexpected(arg0, subject, hasParent);
667
673
  }
668
674
  else if (typeof arg0 == "function")
669
675
  arg1 = arg0.call(subject, key, subject);
@@ -891,7 +897,7 @@ function use(input, argument) {
891
897
  const onUpdate = (next) => {
892
898
  state[key] = next;
893
899
  if (next) {
894
- control(next).parent = subject;
900
+ parent(next, subject);
895
901
  control(next, true);
896
902
  }
897
903
  if (typeof argument == "function")
@@ -947,7 +953,8 @@ function use(input, argument) {
947
953
  }
948
954
 
949
955
  const Oops = issues({
950
- MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`
956
+ MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`,
957
+ NewValue: (name) => `Provider already has already defined '${name}' but got new value. This is not yet supported.`
951
958
  });
952
959
  class Context {
953
960
  constructor() {
@@ -968,11 +975,32 @@ class Context {
968
975
  throw Oops.MultipleExist(Type);
969
976
  return result;
970
977
  }
971
- add(input, key) {
972
- if (key && this.input.get(key) === input)
973
- return typeof input == "object"
974
- ? input
975
- : this[this.has(input)];
978
+ include(inputs) {
979
+ const init = new Map();
980
+ for (const key in inputs) {
981
+ const input = inputs[key];
982
+ const exists = this.input.get(key);
983
+ if (exists)
984
+ if (exists !== input)
985
+ throw Oops.NewValue(key);
986
+ else
987
+ continue;
988
+ const instance = this.add(input);
989
+ this.input.set(key, input);
990
+ init.set(instance, true);
991
+ }
992
+ for (const [model] of init) {
993
+ const { state } = control(model, true);
994
+ Object.values(state).forEach(value => {
995
+ if (parent(value) === model) {
996
+ this.add(value, true);
997
+ init.set(value, false);
998
+ }
999
+ });
1000
+ }
1001
+ return init;
1002
+ }
1003
+ add(input, implicit) {
976
1004
  let writable = true;
977
1005
  let T;
978
1006
  let I;
@@ -987,15 +1015,15 @@ class Context {
987
1015
  }
988
1016
  do {
989
1017
  const key = this.has(T);
990
- defineProperty(this, key, {
991
- configurable: true,
992
- value: this.hasOwnProperty(key) && I !== this[key] ? null : I,
993
- writable
994
- });
1018
+ const value = this.hasOwnProperty(key) ? null : I;
1019
+ if (value || I !== this[key] && !implicit)
1020
+ defineProperty(this, key, {
1021
+ configurable: true,
1022
+ value,
1023
+ writable
1024
+ });
995
1025
  T = getPrototypeOf(T);
996
1026
  } while (T !== Model);
997
- if (key !== undefined)
998
- this.input.set(key, input);
999
1027
  return I;
1000
1028
  }
1001
1029
  push() {
@@ -1039,7 +1067,7 @@ defineProperties(Model.prototype, {
1039
1067
  },
1040
1068
  [PARENT]: {
1041
1069
  get() {
1042
- return control(this).parent;
1070
+ return parent(this);
1043
1071
  }
1044
1072
  }
1045
1073
  });
package/lib/index.js CHANGED
@@ -383,7 +383,7 @@ class Model {
383
383
  state[key] = arg1[key];
384
384
  controller.update(key);
385
385
  }
386
- return awaitUpdate(this, undefined, 0);
386
+ return this.on(0);
387
387
  }
388
388
  /** Mark this instance for garbage collection. */
389
389
  null() {
@@ -431,6 +431,7 @@ const Oops$5 = issues({
431
431
  const INSTRUCTION = new Map();
432
432
  const REGISTER = new WeakMap();
433
433
  const OBSERVER = new WeakMap();
434
+ const PARENTS = new WeakMap();
434
435
  class Control {
435
436
  constructor(subject, id = random()) {
436
437
  this.subject = subject;
@@ -577,7 +578,7 @@ function setRecursive(on, key, value) {
577
578
  const set = (next) => {
578
579
  if (next instanceof value.constructor) {
579
580
  on.state[key] = next;
580
- control(next).parent = on.subject;
581
+ parent(next, on.subject);
581
582
  control(next, true);
582
583
  return true;
583
584
  }
@@ -586,6 +587,11 @@ function setRecursive(on, key, value) {
586
587
  on.watch(key, { set });
587
588
  set(value);
588
589
  }
590
+ function parent(child, register) {
591
+ if (!register)
592
+ return PARENTS.get(child);
593
+ PARENTS.set(child, register);
594
+ }
589
595
  function watch(on, cb) {
590
596
  if (!on.hasOwnProperty("is"))
591
597
  on = defineProperty(create(on), "is", { value: on });
@@ -653,8 +659,8 @@ function get(arg0, arg1) {
653
659
  if (arg0 instanceof Model)
654
660
  subject = arg0;
655
661
  else if (Model.isTypeof(arg0)) {
656
- const { parent } = control;
657
- if (!parent) {
662
+ const hasParent = parent(subject);
663
+ if (!hasParent) {
658
664
  if (arg1 === true)
659
665
  throw Oops$3.Required(arg0, subject);
660
666
  source = callback => Control.has(arg0, subject, got => {
@@ -664,10 +670,10 @@ function get(arg0, arg1) {
664
670
  throw Oops$3.AmbientRequired(arg0, subject);
665
671
  });
666
672
  }
667
- else if (!arg0 || parent instanceof arg0)
668
- subject = parent;
673
+ else if (!arg0 || hasParent instanceof arg0)
674
+ subject = hasParent;
669
675
  else
670
- throw Oops$3.Unexpected(arg0, subject, parent);
676
+ throw Oops$3.Unexpected(arg0, subject, hasParent);
671
677
  }
672
678
  else if (typeof arg0 == "function")
673
679
  arg1 = arg0.call(subject, key, subject);
@@ -895,7 +901,7 @@ function use(input, argument) {
895
901
  const onUpdate = (next) => {
896
902
  state[key] = next;
897
903
  if (next) {
898
- control(next).parent = subject;
904
+ parent(next, subject);
899
905
  control(next, true);
900
906
  }
901
907
  if (typeof argument == "function")
@@ -951,7 +957,8 @@ function use(input, argument) {
951
957
  }
952
958
 
953
959
  const Oops = issues({
954
- MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`
960
+ MultipleExist: (name) => `Did find ${name} in context, but multiple were defined.`,
961
+ NewValue: (name) => `Provider already has already defined '${name}' but got new value. This is not yet supported.`
955
962
  });
956
963
  class Context {
957
964
  constructor() {
@@ -972,11 +979,32 @@ class Context {
972
979
  throw Oops.MultipleExist(Type);
973
980
  return result;
974
981
  }
975
- add(input, key) {
976
- if (key && this.input.get(key) === input)
977
- return typeof input == "object"
978
- ? input
979
- : this[this.has(input)];
982
+ include(inputs) {
983
+ const init = new Map();
984
+ for (const key in inputs) {
985
+ const input = inputs[key];
986
+ const exists = this.input.get(key);
987
+ if (exists)
988
+ if (exists !== input)
989
+ throw Oops.NewValue(key);
990
+ else
991
+ continue;
992
+ const instance = this.add(input);
993
+ this.input.set(key, input);
994
+ init.set(instance, true);
995
+ }
996
+ for (const [model] of init) {
997
+ const { state } = control(model, true);
998
+ Object.values(state).forEach(value => {
999
+ if (parent(value) === model) {
1000
+ this.add(value, true);
1001
+ init.set(value, false);
1002
+ }
1003
+ });
1004
+ }
1005
+ return init;
1006
+ }
1007
+ add(input, implicit) {
980
1008
  let writable = true;
981
1009
  let T;
982
1010
  let I;
@@ -991,15 +1019,15 @@ class Context {
991
1019
  }
992
1020
  do {
993
1021
  const key = this.has(T);
994
- defineProperty(this, key, {
995
- configurable: true,
996
- value: this.hasOwnProperty(key) && I !== this[key] ? null : I,
997
- writable
998
- });
1022
+ const value = this.hasOwnProperty(key) ? null : I;
1023
+ if (value || I !== this[key] && !implicit)
1024
+ defineProperty(this, key, {
1025
+ configurable: true,
1026
+ value,
1027
+ writable
1028
+ });
999
1029
  T = getPrototypeOf(T);
1000
1030
  } while (T !== Model);
1001
- if (key !== undefined)
1002
- this.input.set(key, input);
1003
1031
  return I;
1004
1032
  }
1005
1033
  push() {
@@ -1043,7 +1071,7 @@ defineProperties(Model.prototype, {
1043
1071
  },
1044
1072
  [PARENT]: {
1045
1073
  get() {
1046
- return control(this).parent;
1074
+ return parent(this);
1047
1075
  }
1048
1076
  }
1049
1077
  });
package/package.json CHANGED
@@ -27,5 +27,5 @@
27
27
  "preversion": "npm run test && npm run build",
28
28
  "postversion": "git push & npm publish"
29
29
  },
30
- "version": "0.20.0"
30
+ "version": "0.21.0"
31
31
  }