@expressive/mvc 0.20.0 → 0.21.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.d.ts +11 -22
- package/lib/index.esm.js +51 -23
- package/lib/index.js +50 -23
- package/package.json +1 -1
package/lib/index.d.ts
CHANGED
|
@@ -1,19 +1,3 @@
|
|
|
1
|
-
declare namespace Issue {
|
|
2
|
-
type Variable = {} | string | number | boolean | null | undefined;
|
|
3
|
-
type Variables<T> = T extends (...args: infer T) => any ? T : never;
|
|
4
|
-
type Messages = {
|
|
5
|
-
[named: string]: (...args: Variable[]) => string;
|
|
6
|
-
};
|
|
7
|
-
type Output<M extends Messages> = {
|
|
8
|
-
readonly [P in keyof M]: (...args: Variables<M[P]>) => Issue;
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
declare class Issue extends Error {
|
|
12
|
-
stack: string;
|
|
13
|
-
warn(): void;
|
|
14
|
-
}
|
|
15
|
-
declare function issues<M extends Issue.Messages>(register: M): Issue.Output<M>;
|
|
16
|
-
|
|
17
1
|
type Async<T = any> = (...args: any[]) => Promise<T>;
|
|
18
2
|
/**
|
|
19
3
|
* Sets an exotic method with managed ready-state. Property accepts an async function.
|
|
@@ -91,7 +75,6 @@ declare class Control<T extends Model = any> {
|
|
|
91
75
|
static for: typeof control;
|
|
92
76
|
static apply: typeof apply;
|
|
93
77
|
static watch: typeof watch;
|
|
94
|
-
parent?: Model;
|
|
95
78
|
state: {
|
|
96
79
|
[key: string]: any;
|
|
97
80
|
};
|
|
@@ -242,8 +225,8 @@ declare class Model {
|
|
|
242
225
|
get is(): this;
|
|
243
226
|
on(): Promise<Model.Event<this>[]>;
|
|
244
227
|
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 |
|
|
228
|
+
on<P extends Model.Event<this>>(keys?: P | P[], timeout?: number): Promise<P[] | false>;
|
|
229
|
+
on<P extends Model.Event<this>>(keys: P | P[], listener: Model.OnCallback<this>, once?: boolean): Callback;
|
|
247
230
|
on(effect: Model.Effect<this>): Callback;
|
|
248
231
|
get(): Model.Export<this>;
|
|
249
232
|
get<P extends Model.Key<this>>(select: P): this[P];
|
|
@@ -251,7 +234,7 @@ declare class Model {
|
|
|
251
234
|
get<P extends Model.Key<this>>(select: P, listener: (this: this, value: this[P]) => void): Callback;
|
|
252
235
|
get<P extends Model.Key<this>>(select: Iterable<P>, listener: (this: this, value: Model.Get<this, P>) => void): Callback;
|
|
253
236
|
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<
|
|
237
|
+
set<K extends Model.Event<this>>(key: K, value?: Model.ValueOf<this, K>): Promise<Model.Event<this>[] | false>;
|
|
255
238
|
/** Mark this instance for garbage collection. */
|
|
256
239
|
null(): void;
|
|
257
240
|
static get: typeof get$1;
|
|
@@ -398,14 +381,20 @@ declare function use<T extends Model>(from: () => Promise<T> | T, callback?: (i:
|
|
|
398
381
|
*/
|
|
399
382
|
declare function use<T extends Model>(peer: T, callback?: (i: T) => void): T;
|
|
400
383
|
|
|
384
|
+
declare namespace Context {
|
|
385
|
+
type Inputs = {
|
|
386
|
+
[key: string | number]: Model | Model.New;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
401
389
|
declare class Context {
|
|
402
390
|
private table;
|
|
403
391
|
private input;
|
|
404
392
|
private has;
|
|
405
393
|
get<T extends Model>(Type: Model.Type<T>): T | undefined;
|
|
406
|
-
|
|
394
|
+
include(inputs: Context.Inputs): Map<Model, boolean>;
|
|
395
|
+
add<T extends Model>(input: T | Model.New<T>, implicit?: boolean): T;
|
|
407
396
|
push(): this;
|
|
408
397
|
pop(): void;
|
|
409
398
|
}
|
|
410
399
|
|
|
411
|
-
export { Context, Control, Debug, Model, Model as default, get,
|
|
400
|
+
export { Context, Control, Debug, Model, Model as default, get, ref, run, set, use };
|
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
|
});
|
|
@@ -1050,4 +1078,4 @@ const Debug = {
|
|
|
1050
1078
|
PARENT
|
|
1051
1079
|
};
|
|
1052
1080
|
|
|
1053
|
-
export { Context, Control, Debug, Model, Model as default, get,
|
|
1081
|
+
export { Context, Control, Debug, Model, Model as default, get, ref, run, set, use };
|
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
|
});
|
|
@@ -1060,7 +1088,6 @@ exports.Debug = Debug;
|
|
|
1060
1088
|
exports.Model = Model;
|
|
1061
1089
|
exports["default"] = Model;
|
|
1062
1090
|
exports.get = get;
|
|
1063
|
-
exports.issues = issues;
|
|
1064
1091
|
exports.ref = ref;
|
|
1065
1092
|
exports.run = run;
|
|
1066
1093
|
exports.set = set;
|
package/package.json
CHANGED