@expressive/mvc 0.9.2 → 0.9.4
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 +40 -36
- package/lib/index.esm.js +118 -98
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +118 -98
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -27,11 +27,11 @@ function issues(register) {
|
|
|
27
27
|
|
|
28
28
|
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
29
29
|
|
|
30
|
-
const Oops$
|
|
30
|
+
const Oops$e = issues({
|
|
31
31
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
32
32
|
});
|
|
33
33
|
function suspend(source, key) {
|
|
34
|
-
const error = Oops$
|
|
34
|
+
const error = Oops$e.NotReady(source.subject, key);
|
|
35
35
|
const promise = new Promise(resolve => {
|
|
36
36
|
const release = source.addListener(forKey => {
|
|
37
37
|
if (forKey == key)
|
|
@@ -71,7 +71,7 @@ function mayRetry(fn) {
|
|
|
71
71
|
return compute();
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
const Oops$
|
|
74
|
+
const Oops$d = issues({
|
|
75
75
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
76
76
|
});
|
|
77
77
|
const INFO = new WeakMap();
|
|
@@ -91,7 +91,7 @@ function computeMode(self, source, setter, key, required) {
|
|
|
91
91
|
return setter.call(sub.proxy, sub.proxy);
|
|
92
92
|
}
|
|
93
93
|
catch (err) {
|
|
94
|
-
Oops$
|
|
94
|
+
Oops$d.Failed(subject, key, initial).warn();
|
|
95
95
|
throw err;
|
|
96
96
|
}
|
|
97
97
|
};
|
|
@@ -118,6 +118,7 @@ function computeMode(self, source, setter, key, required) {
|
|
|
118
118
|
else
|
|
119
119
|
pending.add(refresh);
|
|
120
120
|
});
|
|
121
|
+
sub.watch.set(key, false);
|
|
121
122
|
try {
|
|
122
123
|
const value = compute(true);
|
|
123
124
|
state.set(key, value);
|
|
@@ -465,7 +466,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
465
466
|
});
|
|
466
467
|
}
|
|
467
468
|
|
|
468
|
-
const Oops$
|
|
469
|
+
const Oops$c = issues({
|
|
469
470
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
470
471
|
});
|
|
471
472
|
function run(task) {
|
|
@@ -473,7 +474,7 @@ function run(task) {
|
|
|
473
474
|
let pending = false;
|
|
474
475
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
475
476
|
if (pending)
|
|
476
|
-
return Promise.reject(Oops$
|
|
477
|
+
return Promise.reject(Oops$c.DuplicatePending(key));
|
|
477
478
|
pending = true;
|
|
478
479
|
this.update(key);
|
|
479
480
|
try {
|
|
@@ -495,7 +496,7 @@ function run(task) {
|
|
|
495
496
|
});
|
|
496
497
|
}
|
|
497
498
|
|
|
498
|
-
const Oops$
|
|
499
|
+
const Oops$b = issues({
|
|
499
500
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
500
501
|
});
|
|
501
502
|
function factoryMode(self, output, key, required) {
|
|
@@ -519,7 +520,7 @@ function factoryMode(self, output, key, required) {
|
|
|
519
520
|
const suspend = () => {
|
|
520
521
|
if (required === false)
|
|
521
522
|
return undefined;
|
|
522
|
-
const issue = Oops$
|
|
523
|
+
const issue = Oops$b.NotReady(subject, key);
|
|
523
524
|
assign(pending, {
|
|
524
525
|
message: issue.message,
|
|
525
526
|
stack: issue.stack
|
|
@@ -536,7 +537,7 @@ function factoryMode(self, output, key, required) {
|
|
|
536
537
|
};
|
|
537
538
|
}
|
|
538
539
|
|
|
539
|
-
const Oops$
|
|
540
|
+
const Oops$a = issues({
|
|
540
541
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
541
542
|
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
542
543
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
@@ -549,7 +550,7 @@ function get(arg0, arg1, arg2) {
|
|
|
549
550
|
let getter;
|
|
550
551
|
// Easy mistake, using a peer, will always be unresolved.
|
|
551
552
|
if (typeof arg0 == "symbol")
|
|
552
|
-
throw Oops$
|
|
553
|
+
throw Oops$a.PeerNotAllowed(subject, key);
|
|
553
554
|
// if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
554
555
|
// throw Oops.BadSource(subject, key, arg0);
|
|
555
556
|
this.state.set(key, undefined);
|
|
@@ -583,7 +584,7 @@ function get(arg0, arg1, arg2) {
|
|
|
583
584
|
init();
|
|
584
585
|
}
|
|
585
586
|
catch (err) {
|
|
586
|
-
Oops$
|
|
587
|
+
Oops$a.ComputeFailed(subject, key).warn();
|
|
587
588
|
throw err;
|
|
588
589
|
}
|
|
589
590
|
return () => {
|
|
@@ -594,7 +595,7 @@ function get(arg0, arg1, arg2) {
|
|
|
594
595
|
});
|
|
595
596
|
}
|
|
596
597
|
|
|
597
|
-
const Oops$
|
|
598
|
+
const Oops$9 = issues({
|
|
598
599
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
599
600
|
});
|
|
600
601
|
function createEffect(model, callback, keys) {
|
|
@@ -608,7 +609,7 @@ function createEffect(model, callback, keys) {
|
|
|
608
609
|
if (unSet instanceof Promise)
|
|
609
610
|
unSet = undefined;
|
|
610
611
|
if (unSet && typeof unSet !== "function")
|
|
611
|
-
throw Oops$
|
|
612
|
+
throw Oops$9.BadCallback();
|
|
612
613
|
}
|
|
613
614
|
function invoke() {
|
|
614
615
|
if (busy)
|
|
@@ -651,7 +652,7 @@ function createValueEffect(callback) {
|
|
|
651
652
|
if (typeof out == "function")
|
|
652
653
|
unSet = out;
|
|
653
654
|
else
|
|
654
|
-
throw Oops$
|
|
655
|
+
throw Oops$9.BadCallback();
|
|
655
656
|
};
|
|
656
657
|
}
|
|
657
658
|
|
|
@@ -849,7 +850,7 @@ function createProxy(emit, watch) {
|
|
|
849
850
|
}
|
|
850
851
|
|
|
851
852
|
const Parent = new WeakMap();
|
|
852
|
-
const Oops$
|
|
853
|
+
const Oops$8 = issues({
|
|
853
854
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
854
855
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
855
856
|
});
|
|
@@ -866,7 +867,7 @@ function use$1(input, argument) {
|
|
|
866
867
|
input = new input();
|
|
867
868
|
}
|
|
868
869
|
else if (input && typeof input !== "object")
|
|
869
|
-
throw Oops$
|
|
870
|
+
throw Oops$8.BadArgument(typeof input);
|
|
870
871
|
if (input instanceof Map || input instanceof Set)
|
|
871
872
|
return keyed(this, key, input);
|
|
872
873
|
const onUpdate = (next) => {
|
|
@@ -883,7 +884,7 @@ function use$1(input, argument) {
|
|
|
883
884
|
const suspend = () => {
|
|
884
885
|
if (required === false)
|
|
885
886
|
return;
|
|
886
|
-
const issue = Oops$
|
|
887
|
+
const issue = Oops$8.NotReady(subject, key);
|
|
887
888
|
assign(pending, {
|
|
888
889
|
message: issue.message,
|
|
889
890
|
stack: issue.stack
|
|
@@ -928,7 +929,7 @@ function use$1(input, argument) {
|
|
|
928
929
|
});
|
|
929
930
|
}
|
|
930
931
|
|
|
931
|
-
const Oops$
|
|
932
|
+
const Oops$7 = issues({
|
|
932
933
|
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
933
934
|
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
934
935
|
});
|
|
@@ -939,19 +940,100 @@ function has(Type, required) {
|
|
|
939
940
|
const expected = Type.name;
|
|
940
941
|
if (!value) {
|
|
941
942
|
if (required !== false)
|
|
942
|
-
throw Oops$
|
|
943
|
+
throw Oops$7.Required(expected, child);
|
|
943
944
|
}
|
|
944
945
|
else if (!(value instanceof Type))
|
|
945
|
-
throw Oops$
|
|
946
|
+
throw Oops$7.Unexpected(expected, child, value);
|
|
946
947
|
return { value };
|
|
947
948
|
});
|
|
948
949
|
}
|
|
949
950
|
|
|
950
|
-
const Oops$
|
|
951
|
+
const Oops$6 = issues({
|
|
951
952
|
Timeout: (keys, timeout) => `No update seen for [${keys}] within ${timeout}.`,
|
|
952
953
|
KeysExpected: (key) => `Key "${key}" was expected in current update.`,
|
|
953
954
|
StrictUpdate: () => `Expected update but none in progress.`,
|
|
954
|
-
StrictNoUpdate: () => `Update is not expected but one is in progress
|
|
955
|
+
StrictNoUpdate: () => `Update is not expected but one is in progress!`
|
|
956
|
+
});
|
|
957
|
+
function addEventListener(source, arg1, arg2, arg3) {
|
|
958
|
+
const single = typeof arg1 == "string";
|
|
959
|
+
const keys = typeof arg1 == "string" ? [arg1] :
|
|
960
|
+
typeof arg1 == "object" ? arg1 :
|
|
961
|
+
undefined;
|
|
962
|
+
if (typeof arg2 == "function" && keys)
|
|
963
|
+
return Control.for(source, control => {
|
|
964
|
+
for (const key of keys)
|
|
965
|
+
try {
|
|
966
|
+
void source[key];
|
|
967
|
+
}
|
|
968
|
+
catch (e) { }
|
|
969
|
+
const invoke = single
|
|
970
|
+
? () => arg2.call(source, control.state.get(arg1), arg1)
|
|
971
|
+
: (frame) => arg2.call(source, frame);
|
|
972
|
+
const removeListener = control.addListener(key => {
|
|
973
|
+
if (!key && !keys.length)
|
|
974
|
+
invoke([]);
|
|
975
|
+
if (keys.includes(key)) {
|
|
976
|
+
if (arg3)
|
|
977
|
+
removeListener();
|
|
978
|
+
return invoke;
|
|
979
|
+
}
|
|
980
|
+
});
|
|
981
|
+
return removeListener;
|
|
982
|
+
});
|
|
983
|
+
return new Promise((resolve, reject) => {
|
|
984
|
+
const timeout = (message) => {
|
|
985
|
+
const k = keys ? keys.join(", ") : "any";
|
|
986
|
+
removeListener();
|
|
987
|
+
reject(Oops$6.Timeout(k, message));
|
|
988
|
+
};
|
|
989
|
+
const removeListener = Control.for(source, control => {
|
|
990
|
+
const pending = control.frame;
|
|
991
|
+
if (keys === null) {
|
|
992
|
+
if (pending.size)
|
|
993
|
+
reject(Oops$6.StrictNoUpdate());
|
|
994
|
+
else
|
|
995
|
+
resolve(null);
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
998
|
+
if (keys) {
|
|
999
|
+
if (keys.length) {
|
|
1000
|
+
if (arg2 === 0 && single && !pending.has(keys[0])) {
|
|
1001
|
+
reject(Oops$6.KeysExpected(keys[0]));
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
else
|
|
1005
|
+
for (const key of keys)
|
|
1006
|
+
try {
|
|
1007
|
+
void source[key];
|
|
1008
|
+
}
|
|
1009
|
+
catch (e) { }
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
else if (!pending.size && arg1 === true || arg2 === 0) {
|
|
1013
|
+
reject(Oops$6.StrictUpdate());
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
else
|
|
1017
|
+
control.waiting.add(resolve);
|
|
1018
|
+
return control.addListener(key => {
|
|
1019
|
+
if (!key) {
|
|
1020
|
+
if (keys && !keys.length)
|
|
1021
|
+
resolve([]);
|
|
1022
|
+
else
|
|
1023
|
+
timeout(`lifetime of ${source}`);
|
|
1024
|
+
}
|
|
1025
|
+
else if (!keys || keys.includes(key)) {
|
|
1026
|
+
removeListener();
|
|
1027
|
+
return keys => resolve(single ? control.state.get(key) : keys);
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
});
|
|
1031
|
+
if (arg2 && typeof arg2 == "number")
|
|
1032
|
+
setTimeout(() => timeout(`${arg2}ms`), arg2);
|
|
1033
|
+
});
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
const Oops$5 = issues({
|
|
955
1037
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
956
1038
|
});
|
|
957
1039
|
class Model {
|
|
@@ -962,82 +1044,7 @@ class Model {
|
|
|
962
1044
|
on(arg1, arg2, arg3) {
|
|
963
1045
|
if (typeof arg1 == "function")
|
|
964
1046
|
return createEffect(this.is, arg1, arg2);
|
|
965
|
-
|
|
966
|
-
const keys = typeof arg1 == "string" ? [arg1] :
|
|
967
|
-
typeof arg1 == "object" ? arg1 :
|
|
968
|
-
undefined;
|
|
969
|
-
if (typeof arg2 == "function" && keys)
|
|
970
|
-
return Control.for(this, control => {
|
|
971
|
-
for (const key of keys)
|
|
972
|
-
try {
|
|
973
|
-
void this[key];
|
|
974
|
-
}
|
|
975
|
-
catch (e) { }
|
|
976
|
-
const invoke = single
|
|
977
|
-
? () => arg2.call(this, control.state.get(arg1), arg1)
|
|
978
|
-
: (frame) => arg2.call(this, frame);
|
|
979
|
-
const removeListener = control.addListener(key => {
|
|
980
|
-
if (!key && !keys.length)
|
|
981
|
-
invoke([]);
|
|
982
|
-
if (keys.includes(key)) {
|
|
983
|
-
if (arg3)
|
|
984
|
-
removeListener();
|
|
985
|
-
return invoke;
|
|
986
|
-
}
|
|
987
|
-
});
|
|
988
|
-
return removeListener;
|
|
989
|
-
});
|
|
990
|
-
return new Promise((resolve, reject) => {
|
|
991
|
-
const timeout = (message) => {
|
|
992
|
-
const k = keys ? keys.join(", ") : "any";
|
|
993
|
-
removeListener();
|
|
994
|
-
reject(Oops$5.Timeout(k, message));
|
|
995
|
-
};
|
|
996
|
-
const removeListener = Control.for(this, control => {
|
|
997
|
-
const pending = control.frame;
|
|
998
|
-
if (keys === null) {
|
|
999
|
-
if (pending.size)
|
|
1000
|
-
reject(Oops$5.StrictNoUpdate());
|
|
1001
|
-
else
|
|
1002
|
-
resolve(null);
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
if (keys) {
|
|
1006
|
-
if (keys.length) {
|
|
1007
|
-
if (arg2 === 0 && single && !pending.has(keys[0])) {
|
|
1008
|
-
reject(Oops$5.KeysExpected(keys[0]));
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
else
|
|
1012
|
-
for (const key of keys)
|
|
1013
|
-
try {
|
|
1014
|
-
void this[key];
|
|
1015
|
-
}
|
|
1016
|
-
catch (e) { }
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
else if (!pending.size && arg1 === true || arg2 === 0) {
|
|
1020
|
-
reject(Oops$5.StrictUpdate());
|
|
1021
|
-
return;
|
|
1022
|
-
}
|
|
1023
|
-
else
|
|
1024
|
-
control.waiting.add(resolve);
|
|
1025
|
-
return control.addListener(key => {
|
|
1026
|
-
if (!key) {
|
|
1027
|
-
if (keys && !keys.length)
|
|
1028
|
-
resolve([]);
|
|
1029
|
-
else
|
|
1030
|
-
timeout(`lifetime of ${this}`);
|
|
1031
|
-
}
|
|
1032
|
-
else if (!keys || keys.includes(key)) {
|
|
1033
|
-
removeListener();
|
|
1034
|
-
return keys => resolve(single ? control.state.get(key) : keys);
|
|
1035
|
-
}
|
|
1036
|
-
});
|
|
1037
|
-
});
|
|
1038
|
-
if (arg2 && typeof arg2 == "number")
|
|
1039
|
-
setTimeout(() => timeout(`${arg2}ms`), arg2);
|
|
1040
|
-
});
|
|
1047
|
+
return addEventListener(this.is, arg1, arg2, arg3);
|
|
1041
1048
|
}
|
|
1042
1049
|
export(subset) {
|
|
1043
1050
|
const { state } = Control.for(this);
|
|
@@ -1290,6 +1297,19 @@ function useValue(source, compute, suspend) {
|
|
|
1290
1297
|
else
|
|
1291
1298
|
refresh();
|
|
1292
1299
|
};
|
|
1300
|
+
if (value === null) {
|
|
1301
|
+
sub.watch.clear();
|
|
1302
|
+
return {
|
|
1303
|
+
proxy: null,
|
|
1304
|
+
release: () => { }
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
if (typeof value == "function") {
|
|
1308
|
+
const get = value;
|
|
1309
|
+
sub.watch.clear();
|
|
1310
|
+
compute = () => get();
|
|
1311
|
+
value = get();
|
|
1312
|
+
}
|
|
1293
1313
|
if (value instanceof Promise) {
|
|
1294
1314
|
value.then(set);
|
|
1295
1315
|
value = undefined;
|