@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 +10 -5
- package/lib/index.esm.js +50 -22
- package/lib/index.js +50 -22
- package/package.json +1 -1
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 |
|
|
246
|
-
on<P extends Model.Event<this>>(keys: P |
|
|
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<
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
653
|
-
if (!
|
|
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 ||
|
|
664
|
-
subject =
|
|
669
|
+
else if (!arg0 || hasParent instanceof arg0)
|
|
670
|
+
subject = hasParent;
|
|
665
671
|
else
|
|
666
|
-
throw Oops$3.Unexpected(arg0, subject,
|
|
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
|
-
|
|
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
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
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
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
657
|
-
if (!
|
|
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 ||
|
|
668
|
-
subject =
|
|
673
|
+
else if (!arg0 || hasParent instanceof arg0)
|
|
674
|
+
subject = hasParent;
|
|
669
675
|
else
|
|
670
|
-
throw Oops$3.Unexpected(arg0, subject,
|
|
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
|
-
|
|
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
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
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
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
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
|
|
1074
|
+
return parent(this);
|
|
1047
1075
|
}
|
|
1048
1076
|
}
|
|
1049
1077
|
});
|
package/package.json
CHANGED