@expressive/mvc 0.9.3 → 0.9.5
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 +67 -63
- package/lib/index.esm.js +156 -137
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +156 -137
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -8,6 +8,8 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
|
|
|
8
8
|
|
|
9
9
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
10
10
|
|
|
11
|
+
const { assign, create, defineProperties, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
12
|
+
|
|
11
13
|
class Issue extends Error {
|
|
12
14
|
constructor() {
|
|
13
15
|
super(...arguments);
|
|
@@ -25,13 +27,11 @@ function issues(register) {
|
|
|
25
27
|
return Library;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const Oops$d = issues({
|
|
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
|
};
|
|
@@ -466,7 +466,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
466
466
|
});
|
|
467
467
|
}
|
|
468
468
|
|
|
469
|
-
const Oops$
|
|
469
|
+
const Oops$c = issues({
|
|
470
470
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
471
471
|
});
|
|
472
472
|
function run(task) {
|
|
@@ -474,7 +474,7 @@ function run(task) {
|
|
|
474
474
|
let pending = false;
|
|
475
475
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
476
476
|
if (pending)
|
|
477
|
-
return Promise.reject(Oops$
|
|
477
|
+
return Promise.reject(Oops$c.DuplicatePending(key));
|
|
478
478
|
pending = true;
|
|
479
479
|
this.update(key);
|
|
480
480
|
try {
|
|
@@ -496,7 +496,7 @@ function run(task) {
|
|
|
496
496
|
});
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
-
const Oops$
|
|
499
|
+
const Oops$b = issues({
|
|
500
500
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
501
501
|
});
|
|
502
502
|
function factoryMode(self, output, key, required) {
|
|
@@ -520,7 +520,7 @@ function factoryMode(self, output, key, required) {
|
|
|
520
520
|
const suspend = () => {
|
|
521
521
|
if (required === false)
|
|
522
522
|
return undefined;
|
|
523
|
-
const issue = Oops$
|
|
523
|
+
const issue = Oops$b.NotReady(subject, key);
|
|
524
524
|
assign(pending, {
|
|
525
525
|
message: issue.message,
|
|
526
526
|
stack: issue.stack
|
|
@@ -537,7 +537,7 @@ function factoryMode(self, output, key, required) {
|
|
|
537
537
|
};
|
|
538
538
|
}
|
|
539
539
|
|
|
540
|
-
const Oops$
|
|
540
|
+
const Oops$a = issues({
|
|
541
541
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
542
542
|
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
543
543
|
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
@@ -550,7 +550,7 @@ function get(arg0, arg1, arg2) {
|
|
|
550
550
|
let getter;
|
|
551
551
|
// Easy mistake, using a peer, will always be unresolved.
|
|
552
552
|
if (typeof arg0 == "symbol")
|
|
553
|
-
throw Oops$
|
|
553
|
+
throw Oops$a.PeerNotAllowed(subject, key);
|
|
554
554
|
// if(typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
555
555
|
// throw Oops.BadSource(subject, key, arg0);
|
|
556
556
|
this.state.set(key, undefined);
|
|
@@ -584,7 +584,7 @@ function get(arg0, arg1, arg2) {
|
|
|
584
584
|
init();
|
|
585
585
|
}
|
|
586
586
|
catch (err) {
|
|
587
|
-
Oops$
|
|
587
|
+
Oops$a.ComputeFailed(subject, key).warn();
|
|
588
588
|
throw err;
|
|
589
589
|
}
|
|
590
590
|
return () => {
|
|
@@ -595,7 +595,7 @@ function get(arg0, arg1, arg2) {
|
|
|
595
595
|
});
|
|
596
596
|
}
|
|
597
597
|
|
|
598
|
-
const Oops$
|
|
598
|
+
const Oops$9 = issues({
|
|
599
599
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
600
600
|
});
|
|
601
601
|
function createEffect(model, callback, keys) {
|
|
@@ -609,7 +609,7 @@ function createEffect(model, callback, keys) {
|
|
|
609
609
|
if (unSet instanceof Promise)
|
|
610
610
|
unSet = undefined;
|
|
611
611
|
if (unSet && typeof unSet !== "function")
|
|
612
|
-
throw Oops$
|
|
612
|
+
throw Oops$9.BadCallback();
|
|
613
613
|
}
|
|
614
614
|
function invoke() {
|
|
615
615
|
if (busy)
|
|
@@ -652,7 +652,7 @@ function createValueEffect(callback) {
|
|
|
652
652
|
if (typeof out == "function")
|
|
653
653
|
unSet = out;
|
|
654
654
|
else
|
|
655
|
-
throw Oops$
|
|
655
|
+
throw Oops$9.BadCallback();
|
|
656
656
|
};
|
|
657
657
|
}
|
|
658
658
|
|
|
@@ -850,7 +850,7 @@ function createProxy(emit, watch) {
|
|
|
850
850
|
}
|
|
851
851
|
|
|
852
852
|
const Parent = new WeakMap();
|
|
853
|
-
const Oops$
|
|
853
|
+
const Oops$8 = issues({
|
|
854
854
|
BadArgument: (type) => `Instruction \`use\` cannot accept argument type of ${type}.`,
|
|
855
855
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
856
856
|
});
|
|
@@ -867,7 +867,7 @@ function use$1(input, argument) {
|
|
|
867
867
|
input = new input();
|
|
868
868
|
}
|
|
869
869
|
else if (input && typeof input !== "object")
|
|
870
|
-
throw Oops$
|
|
870
|
+
throw Oops$8.BadArgument(typeof input);
|
|
871
871
|
if (input instanceof Map || input instanceof Set)
|
|
872
872
|
return keyed(this, key, input);
|
|
873
873
|
const onUpdate = (next) => {
|
|
@@ -884,7 +884,7 @@ function use$1(input, argument) {
|
|
|
884
884
|
const suspend = () => {
|
|
885
885
|
if (required === false)
|
|
886
886
|
return;
|
|
887
|
-
const issue = Oops$
|
|
887
|
+
const issue = Oops$8.NotReady(subject, key);
|
|
888
888
|
assign(pending, {
|
|
889
889
|
message: issue.message,
|
|
890
890
|
stack: issue.stack
|
|
@@ -929,7 +929,7 @@ function use$1(input, argument) {
|
|
|
929
929
|
});
|
|
930
930
|
}
|
|
931
931
|
|
|
932
|
-
const Oops$
|
|
932
|
+
const Oops$7 = issues({
|
|
933
933
|
Required: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
934
934
|
Unexpected: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
935
935
|
});
|
|
@@ -940,19 +940,100 @@ function has(Type, required) {
|
|
|
940
940
|
const expected = Type.name;
|
|
941
941
|
if (!value) {
|
|
942
942
|
if (required !== false)
|
|
943
|
-
throw Oops$
|
|
943
|
+
throw Oops$7.Required(expected, child);
|
|
944
944
|
}
|
|
945
945
|
else if (!(value instanceof Type))
|
|
946
|
-
throw Oops$
|
|
946
|
+
throw Oops$7.Unexpected(expected, child, value);
|
|
947
947
|
return { value };
|
|
948
948
|
});
|
|
949
949
|
}
|
|
950
950
|
|
|
951
|
-
const Oops$
|
|
951
|
+
const Oops$6 = issues({
|
|
952
952
|
Timeout: (keys, timeout) => `No update seen for [${keys}] within ${timeout}.`,
|
|
953
953
|
KeysExpected: (key) => `Key "${key}" was expected in current update.`,
|
|
954
954
|
StrictUpdate: () => `Expected update but none in progress.`,
|
|
955
|
-
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({
|
|
956
1037
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
957
1038
|
});
|
|
958
1039
|
class Model {
|
|
@@ -963,82 +1044,7 @@ class Model {
|
|
|
963
1044
|
on(arg1, arg2, arg3) {
|
|
964
1045
|
if (typeof arg1 == "function")
|
|
965
1046
|
return createEffect(this.is, arg1, arg2);
|
|
966
|
-
|
|
967
|
-
const keys = typeof arg1 == "string" ? [arg1] :
|
|
968
|
-
typeof arg1 == "object" ? arg1 :
|
|
969
|
-
undefined;
|
|
970
|
-
if (typeof arg2 == "function" && keys)
|
|
971
|
-
return Control.for(this, control => {
|
|
972
|
-
for (const key of keys)
|
|
973
|
-
try {
|
|
974
|
-
void this[key];
|
|
975
|
-
}
|
|
976
|
-
catch (e) { }
|
|
977
|
-
const invoke = single
|
|
978
|
-
? () => arg2.call(this, control.state.get(arg1), arg1)
|
|
979
|
-
: (frame) => arg2.call(this, frame);
|
|
980
|
-
const removeListener = control.addListener(key => {
|
|
981
|
-
if (!key && !keys.length)
|
|
982
|
-
invoke([]);
|
|
983
|
-
if (keys.includes(key)) {
|
|
984
|
-
if (arg3)
|
|
985
|
-
removeListener();
|
|
986
|
-
return invoke;
|
|
987
|
-
}
|
|
988
|
-
});
|
|
989
|
-
return removeListener;
|
|
990
|
-
});
|
|
991
|
-
return new Promise((resolve, reject) => {
|
|
992
|
-
const timeout = (message) => {
|
|
993
|
-
const k = keys ? keys.join(", ") : "any";
|
|
994
|
-
removeListener();
|
|
995
|
-
reject(Oops$5.Timeout(k, message));
|
|
996
|
-
};
|
|
997
|
-
const removeListener = Control.for(this, control => {
|
|
998
|
-
const pending = control.frame;
|
|
999
|
-
if (keys === null) {
|
|
1000
|
-
if (pending.size)
|
|
1001
|
-
reject(Oops$5.StrictNoUpdate());
|
|
1002
|
-
else
|
|
1003
|
-
resolve(null);
|
|
1004
|
-
return;
|
|
1005
|
-
}
|
|
1006
|
-
if (keys) {
|
|
1007
|
-
if (keys.length) {
|
|
1008
|
-
if (arg2 === 0 && single && !pending.has(keys[0])) {
|
|
1009
|
-
reject(Oops$5.KeysExpected(keys[0]));
|
|
1010
|
-
return;
|
|
1011
|
-
}
|
|
1012
|
-
else
|
|
1013
|
-
for (const key of keys)
|
|
1014
|
-
try {
|
|
1015
|
-
void this[key];
|
|
1016
|
-
}
|
|
1017
|
-
catch (e) { }
|
|
1018
|
-
}
|
|
1019
|
-
}
|
|
1020
|
-
else if (!pending.size && arg1 === true || arg2 === 0) {
|
|
1021
|
-
reject(Oops$5.StrictUpdate());
|
|
1022
|
-
return;
|
|
1023
|
-
}
|
|
1024
|
-
else
|
|
1025
|
-
control.waiting.add(resolve);
|
|
1026
|
-
return control.addListener(key => {
|
|
1027
|
-
if (!key) {
|
|
1028
|
-
if (keys && !keys.length)
|
|
1029
|
-
resolve([]);
|
|
1030
|
-
else
|
|
1031
|
-
timeout(`lifetime of ${this}`);
|
|
1032
|
-
}
|
|
1033
|
-
else if (!keys || keys.includes(key)) {
|
|
1034
|
-
removeListener();
|
|
1035
|
-
return keys => resolve(single ? control.state.get(key) : keys);
|
|
1036
|
-
}
|
|
1037
|
-
});
|
|
1038
|
-
});
|
|
1039
|
-
if (arg2 && typeof arg2 == "number")
|
|
1040
|
-
setTimeout(() => timeout(`${arg2}ms`), arg2);
|
|
1041
|
-
});
|
|
1047
|
+
return addEventListener(this.is, arg1, arg2, arg3);
|
|
1042
1048
|
}
|
|
1043
1049
|
export(subset) {
|
|
1044
1050
|
const { state } = Control.for(this);
|
|
@@ -1291,6 +1297,19 @@ function useValue(source, compute, suspend) {
|
|
|
1291
1297
|
else
|
|
1292
1298
|
refresh();
|
|
1293
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
|
+
}
|
|
1294
1313
|
if (value instanceof Promise) {
|
|
1295
1314
|
value.then(set);
|
|
1296
1315
|
value = undefined;
|
|
@@ -1353,43 +1372,6 @@ class MVC extends Model {
|
|
|
1353
1372
|
}
|
|
1354
1373
|
}
|
|
1355
1374
|
|
|
1356
|
-
const LOCAL = "$debug local";
|
|
1357
|
-
const STATE = "$debug state";
|
|
1358
|
-
const UPDATE = "$debug update";
|
|
1359
|
-
const CONTROL = "$debug controller";
|
|
1360
|
-
defineProperties(Model.prototype, {
|
|
1361
|
-
[CONTROL]: {
|
|
1362
|
-
get() {
|
|
1363
|
-
return Control.get(this);
|
|
1364
|
-
}
|
|
1365
|
-
},
|
|
1366
|
-
[LOCAL]: {
|
|
1367
|
-
get() {
|
|
1368
|
-
return Subscriber.get(this);
|
|
1369
|
-
}
|
|
1370
|
-
},
|
|
1371
|
-
[STATE]: {
|
|
1372
|
-
get() {
|
|
1373
|
-
const { state } = Control.get(this);
|
|
1374
|
-
const output = {};
|
|
1375
|
-
state.forEach((value, key) => output[key] = value);
|
|
1376
|
-
return output;
|
|
1377
|
-
}
|
|
1378
|
-
},
|
|
1379
|
-
[UPDATE]: {
|
|
1380
|
-
get() {
|
|
1381
|
-
const source = Subscriber.get(this) || Control.get(this);
|
|
1382
|
-
return source && source.latest;
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
});
|
|
1386
|
-
const Debug = {
|
|
1387
|
-
CONTROL,
|
|
1388
|
-
LOCAL,
|
|
1389
|
-
STATE,
|
|
1390
|
-
UPDATE
|
|
1391
|
-
};
|
|
1392
|
-
|
|
1393
1375
|
const Oops$2 = issues({
|
|
1394
1376
|
BadProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
1395
1377
|
});
|
|
@@ -1519,6 +1501,43 @@ class Global extends MVC {
|
|
|
1519
1501
|
}
|
|
1520
1502
|
Global.keepAlive = true;
|
|
1521
1503
|
|
|
1504
|
+
const LOCAL = "$debug local";
|
|
1505
|
+
const STATE = "$debug state";
|
|
1506
|
+
const UPDATE = "$debug update";
|
|
1507
|
+
const CONTROL = "$debug controller";
|
|
1508
|
+
defineProperties(Model.prototype, {
|
|
1509
|
+
[CONTROL]: {
|
|
1510
|
+
get() {
|
|
1511
|
+
return Control.get(this);
|
|
1512
|
+
}
|
|
1513
|
+
},
|
|
1514
|
+
[LOCAL]: {
|
|
1515
|
+
get() {
|
|
1516
|
+
return Subscriber.get(this);
|
|
1517
|
+
}
|
|
1518
|
+
},
|
|
1519
|
+
[STATE]: {
|
|
1520
|
+
get() {
|
|
1521
|
+
const { state } = Control.get(this);
|
|
1522
|
+
const output = {};
|
|
1523
|
+
state.forEach((value, key) => output[key] = value);
|
|
1524
|
+
return output;
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
[UPDATE]: {
|
|
1528
|
+
get() {
|
|
1529
|
+
const source = Subscriber.get(this) || Control.get(this);
|
|
1530
|
+
return source && source.latest;
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
});
|
|
1534
|
+
const Debug = {
|
|
1535
|
+
CONTROL,
|
|
1536
|
+
LOCAL,
|
|
1537
|
+
STATE,
|
|
1538
|
+
UPDATE
|
|
1539
|
+
};
|
|
1540
|
+
|
|
1522
1541
|
exports.Consumer = Consumer;
|
|
1523
1542
|
exports.Debug = Debug;
|
|
1524
1543
|
exports.Global = Global;
|