@expressive/mvc 1.0.0-beta.30 → 1.0.0-beta.33
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.esm.js +154 -92
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +155 -92
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/types/instructions.d.ts +92 -6
- package/types/model.d.ts +4 -4
package/lib/index.esm.js
CHANGED
|
@@ -20,7 +20,7 @@ function issues(register) {
|
|
|
20
20
|
return Library;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
const Oops$
|
|
23
|
+
const Oops$9 = issues({
|
|
24
24
|
BadEffectCallback: () => `Callback for effect-callback may only return a function.`
|
|
25
25
|
});
|
|
26
26
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertySymbols, keys: keys$1, values } = Object;
|
|
@@ -49,7 +49,7 @@ function createEffect(callback) {
|
|
|
49
49
|
if (unSet instanceof Promise)
|
|
50
50
|
unSet = undefined;
|
|
51
51
|
if (unSet && typeof unSet !== "function")
|
|
52
|
-
throw Oops$
|
|
52
|
+
throw Oops$9.BadEffectCallback();
|
|
53
53
|
};
|
|
54
54
|
}
|
|
55
55
|
function createValueEffect(callback) {
|
|
@@ -65,7 +65,7 @@ function createValueEffect(callback) {
|
|
|
65
65
|
if (typeof out == "function")
|
|
66
66
|
unSet = out;
|
|
67
67
|
else
|
|
68
|
-
throw Oops$
|
|
68
|
+
throw Oops$9.BadEffectCallback();
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
71
|
function select(source, select) {
|
|
@@ -153,7 +153,7 @@ class Subscriber {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
const Oops$
|
|
156
|
+
const Oops$8 = issues({
|
|
157
157
|
ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
158
158
|
ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
159
159
|
});
|
|
@@ -172,14 +172,14 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
172
172
|
}
|
|
173
173
|
register.set(key, info);
|
|
174
174
|
const current = getter
|
|
175
|
-
? () => getter
|
|
175
|
+
? () => getter(parent, key)
|
|
176
176
|
: () => state[key];
|
|
177
177
|
function compute(initial) {
|
|
178
178
|
try {
|
|
179
179
|
return setter.call(sub.proxy, sub.proxy);
|
|
180
180
|
}
|
|
181
181
|
catch (err) {
|
|
182
|
-
Oops$
|
|
182
|
+
Oops$8.ComputeFailed(subject, key, !!initial).warn();
|
|
183
183
|
throw err;
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -225,7 +225,7 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
225
225
|
}
|
|
226
226
|
catch (e) {
|
|
227
227
|
if (early)
|
|
228
|
-
Oops$
|
|
228
|
+
Oops$8.ComputedEarly(key).warn();
|
|
229
229
|
throw e;
|
|
230
230
|
}
|
|
231
231
|
finally {
|
|
@@ -506,6 +506,61 @@ function child(source, name) {
|
|
|
506
506
|
}, name || source.name);
|
|
507
507
|
}
|
|
508
508
|
|
|
509
|
+
const Oops$7 = issues({
|
|
510
|
+
NonOptional: (Parent, key) => `Property ${Parent}.${key} is marked as required.`,
|
|
511
|
+
BadFactory: () => `Set instruction can only accept a factory or undefined.`,
|
|
512
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
513
|
+
});
|
|
514
|
+
function lazy(value) {
|
|
515
|
+
return apply(function lazy(key) {
|
|
516
|
+
const source = this.subject;
|
|
517
|
+
source[key] = value;
|
|
518
|
+
defineProperty(this.state, key, {
|
|
519
|
+
get: () => source[key]
|
|
520
|
+
});
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
function set(factory, argument) {
|
|
524
|
+
return apply(function set(key) {
|
|
525
|
+
let onSet;
|
|
526
|
+
let onGet;
|
|
527
|
+
const required = argument === true || argument === undefined;
|
|
528
|
+
if (factory === undefined)
|
|
529
|
+
onGet = () => pendingValue(this, key);
|
|
530
|
+
else if (typeof factory !== "function")
|
|
531
|
+
throw Oops$7.BadFactory();
|
|
532
|
+
else {
|
|
533
|
+
onGet = pendingFactory(this, key, factory);
|
|
534
|
+
if (required)
|
|
535
|
+
try {
|
|
536
|
+
onGet();
|
|
537
|
+
}
|
|
538
|
+
catch (err) {
|
|
539
|
+
if (err instanceof Promise)
|
|
540
|
+
;
|
|
541
|
+
else {
|
|
542
|
+
Oops$7.FactoryFailed(this.subject, key).warn();
|
|
543
|
+
throw err;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (typeof argument == "function")
|
|
548
|
+
onSet = createValueEffect(argument);
|
|
549
|
+
else if (required)
|
|
550
|
+
onSet = (value) => {
|
|
551
|
+
if (value === undefined)
|
|
552
|
+
throw Oops$7.NonOptional(this.subject, key);
|
|
553
|
+
};
|
|
554
|
+
return {
|
|
555
|
+
set: this.setter(key, onSet),
|
|
556
|
+
get: onGet
|
|
557
|
+
};
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
function on(initial, onUpdate) {
|
|
561
|
+
return set(initial && (() => initial), onUpdate);
|
|
562
|
+
}
|
|
563
|
+
|
|
509
564
|
const Oops$6 = issues({
|
|
510
565
|
CantAttachGlobal: (parent, child) => `Singleton '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
511
566
|
AmbientRequired: (requested, requester, key) => `Attempted to find an instance of ${requested} in context. It is required for [${requester}.${key}], but one could not be found.`
|
|
@@ -608,10 +663,13 @@ function act(task) {
|
|
|
608
663
|
};
|
|
609
664
|
});
|
|
610
665
|
}
|
|
611
|
-
function from(source, setter,
|
|
666
|
+
function from(source, setter, argument) {
|
|
612
667
|
return apply(function from(key) {
|
|
613
668
|
const { subject } = this;
|
|
614
669
|
let getSource;
|
|
670
|
+
let getter = argument === true
|
|
671
|
+
? pendingValue
|
|
672
|
+
: argument || undefined;
|
|
615
673
|
// Easy mistake, using a peer, will always be unresolved.
|
|
616
674
|
if (typeof source == "symbol")
|
|
617
675
|
throw Oops$5.PeerNotAllowed(subject, key);
|
|
@@ -626,7 +684,7 @@ function from(source, setter, getter) {
|
|
|
626
684
|
// is a peer Model (constructor)
|
|
627
685
|
else if (Model.isTypeof(source))
|
|
628
686
|
getSource = pendingAccess(subject, source, key, true);
|
|
629
|
-
// Regular function is
|
|
687
|
+
// Regular function is too ambiguous so not allowed.
|
|
630
688
|
else
|
|
631
689
|
throw Oops$5.BadComputedSource(subject, key, source);
|
|
632
690
|
prepare(this, key, getSource, setter, getter);
|
|
@@ -636,12 +694,14 @@ function from(source, setter, getter) {
|
|
|
636
694
|
const Oops$4 = issues({
|
|
637
695
|
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
638
696
|
});
|
|
697
|
+
/* deprecated - ignore coverage */
|
|
698
|
+
/* istanbul ignore next */
|
|
639
699
|
function pending(source, compute) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
700
|
+
if (source === undefined)
|
|
701
|
+
return set();
|
|
702
|
+
if (typeof source == "function" && !source.prototype)
|
|
703
|
+
return set(source);
|
|
704
|
+
return from(source, compute, true);
|
|
645
705
|
}
|
|
646
706
|
/**
|
|
647
707
|
* Get value, suspend instead if undefined.
|
|
@@ -655,6 +715,40 @@ function pendingValue(via, key) {
|
|
|
655
715
|
throw suspend(via, key);
|
|
656
716
|
return value;
|
|
657
717
|
}
|
|
718
|
+
function pendingFactory(via, key, fn) {
|
|
719
|
+
const { subject, state } = via;
|
|
720
|
+
let waiting;
|
|
721
|
+
let error;
|
|
722
|
+
return () => {
|
|
723
|
+
if (waiting)
|
|
724
|
+
throw waiting;
|
|
725
|
+
if (error)
|
|
726
|
+
throw error;
|
|
727
|
+
if (key in state)
|
|
728
|
+
return state[key];
|
|
729
|
+
let output;
|
|
730
|
+
try {
|
|
731
|
+
output = fn.call(subject, key, subject);
|
|
732
|
+
}
|
|
733
|
+
catch (err) {
|
|
734
|
+
throw error = err;
|
|
735
|
+
}
|
|
736
|
+
if (output instanceof Promise) {
|
|
737
|
+
const issue = Oops$4.ValueNotReady(subject, key);
|
|
738
|
+
output
|
|
739
|
+
.catch(err => error = err)
|
|
740
|
+
.then(out => state[key] = out)
|
|
741
|
+
.finally(() => waiting = undefined);
|
|
742
|
+
throw waiting = Object.assign(output, {
|
|
743
|
+
message: issue.message,
|
|
744
|
+
stack: issue.stack
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
return state[key] = output;
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
}
|
|
658
752
|
function suspend(source, key) {
|
|
659
753
|
const error = Oops$4.ValueNotReady(source.subject, key);
|
|
660
754
|
const promise = new Promise(resolve => {
|
|
@@ -674,45 +768,6 @@ function suspend(source, key) {
|
|
|
674
768
|
message: error.message,
|
|
675
769
|
stack: error.stack
|
|
676
770
|
});
|
|
677
|
-
}
|
|
678
|
-
function suspendForComputed(source, compute) {
|
|
679
|
-
function getter(_value, key) {
|
|
680
|
-
return pendingValue(manage(this), key);
|
|
681
|
-
}
|
|
682
|
-
return from(source, compute, getter);
|
|
683
|
-
}
|
|
684
|
-
function suspendForValue() {
|
|
685
|
-
return apply(function pending(key) {
|
|
686
|
-
this.state[key] = undefined;
|
|
687
|
-
return {
|
|
688
|
-
set: this.setter(key),
|
|
689
|
-
get: () => pendingValue(this, key)
|
|
690
|
-
};
|
|
691
|
-
});
|
|
692
|
-
}
|
|
693
|
-
function suspendForAsync(source) {
|
|
694
|
-
return apply(function suspense(key) {
|
|
695
|
-
const subject = this.subject;
|
|
696
|
-
let waiting = true;
|
|
697
|
-
let value;
|
|
698
|
-
let error;
|
|
699
|
-
return () => {
|
|
700
|
-
if (error)
|
|
701
|
-
throw error;
|
|
702
|
-
if (!waiting)
|
|
703
|
-
return value;
|
|
704
|
-
const issue = Oops$4.ValueNotReady(subject, key);
|
|
705
|
-
let suspend = source
|
|
706
|
-
.call(subject, key)
|
|
707
|
-
.catch(err => error = err)
|
|
708
|
-
.then(out => value = out)
|
|
709
|
-
.finally(() => waiting = false);
|
|
710
|
-
throw Object.assign(suspend, {
|
|
711
|
-
message: issue.message,
|
|
712
|
-
stack: issue.stack
|
|
713
|
-
});
|
|
714
|
-
};
|
|
715
|
-
});
|
|
716
771
|
}
|
|
717
772
|
|
|
718
773
|
function use$1(init) {
|
|
@@ -736,12 +791,11 @@ function useWatcher(target, focus, expected) {
|
|
|
736
791
|
const sub = new Subscriber(target, () => refresh);
|
|
737
792
|
if (focus) {
|
|
738
793
|
const source = sub.proxy;
|
|
739
|
-
const key = keys(sub.parent, focus)[0];
|
|
740
794
|
defineProperty(sub, "proxy", {
|
|
741
795
|
get() {
|
|
742
|
-
const value = source[
|
|
796
|
+
const value = source[focus];
|
|
743
797
|
if (value === undefined && expected)
|
|
744
|
-
throw suspend(sub.parent,
|
|
798
|
+
throw suspend(sub.parent, focus);
|
|
745
799
|
return value;
|
|
746
800
|
}
|
|
747
801
|
});
|
|
@@ -751,6 +805,39 @@ function useWatcher(target, focus, expected) {
|
|
|
751
805
|
useLayoutEffect(() => hook.commit(), []);
|
|
752
806
|
return hook.proxy;
|
|
753
807
|
}
|
|
808
|
+
function useComputed(target, compute, expected) {
|
|
809
|
+
const hook = use$1(refresh => {
|
|
810
|
+
const sub = new Subscriber(target, () => update);
|
|
811
|
+
const { proxy } = sub;
|
|
812
|
+
let value;
|
|
813
|
+
let retry;
|
|
814
|
+
const update = () => {
|
|
815
|
+
const next = compute.call(proxy, proxy);
|
|
816
|
+
if (value == next)
|
|
817
|
+
return;
|
|
818
|
+
value = next;
|
|
819
|
+
if (retry) {
|
|
820
|
+
retry();
|
|
821
|
+
retry = undefined;
|
|
822
|
+
}
|
|
823
|
+
else
|
|
824
|
+
refresh();
|
|
825
|
+
};
|
|
826
|
+
const access = () => {
|
|
827
|
+
if (value === undefined && expected)
|
|
828
|
+
throw new Promise(res => {
|
|
829
|
+
retry = res;
|
|
830
|
+
});
|
|
831
|
+
return value;
|
|
832
|
+
};
|
|
833
|
+
value = compute.call(proxy, proxy);
|
|
834
|
+
sub.commit();
|
|
835
|
+
defineProperty(sub, "proxy", { get: access });
|
|
836
|
+
return sub;
|
|
837
|
+
});
|
|
838
|
+
useLayoutEffect(() => hook.release, []);
|
|
839
|
+
return hook.proxy;
|
|
840
|
+
}
|
|
754
841
|
function useModel(Type, callback) {
|
|
755
842
|
const hook = use$1(refresh => {
|
|
756
843
|
const instance = new Type();
|
|
@@ -914,14 +1001,14 @@ class Model {
|
|
|
914
1001
|
});
|
|
915
1002
|
}
|
|
916
1003
|
tap(path, expect) {
|
|
1004
|
+
if (typeof path == "function")
|
|
1005
|
+
return useComputed(this, path, expect);
|
|
917
1006
|
const proxy = useWatcher(this, path, expect);
|
|
918
1007
|
this.update("willRender", true);
|
|
919
1008
|
return proxy;
|
|
920
1009
|
}
|
|
921
1010
|
tag(id) {
|
|
922
|
-
const hook = use$1(refresh =>
|
|
923
|
-
return new Subscriber(this, () => refresh);
|
|
924
|
-
});
|
|
1011
|
+
const hook = use$1(refresh => (new Subscriber(this, () => refresh)));
|
|
925
1012
|
useElementLifecycle(hook, id || 0);
|
|
926
1013
|
return hook.proxy;
|
|
927
1014
|
}
|
|
@@ -969,12 +1056,10 @@ class Model {
|
|
|
969
1056
|
invoke();
|
|
970
1057
|
return this.on(select, invoke, true);
|
|
971
1058
|
}
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return sub.commit();
|
|
977
|
-
}
|
|
1059
|
+
const sub = new Subscriber(control, () => invoke);
|
|
1060
|
+
target = sub.proxy;
|
|
1061
|
+
invoke();
|
|
1062
|
+
return sub.commit();
|
|
978
1063
|
}
|
|
979
1064
|
import(from, subset) {
|
|
980
1065
|
for (const key of keys(manage(this), subset))
|
|
@@ -1069,7 +1154,9 @@ class Model {
|
|
|
1069
1154
|
return instance;
|
|
1070
1155
|
}
|
|
1071
1156
|
static meta(path) {
|
|
1072
|
-
return
|
|
1157
|
+
return typeof path == "function"
|
|
1158
|
+
? useComputed(this, path)
|
|
1159
|
+
: useWatcher(this, path);
|
|
1073
1160
|
}
|
|
1074
1161
|
static isTypeof(maybe) {
|
|
1075
1162
|
return (typeof maybe == "function" &&
|
|
@@ -1168,31 +1255,6 @@ function parent(Expects, required) {
|
|
|
1168
1255
|
});
|
|
1169
1256
|
}
|
|
1170
1257
|
|
|
1171
|
-
function on(initial, cb) {
|
|
1172
|
-
return apply(function on(key) {
|
|
1173
|
-
this.manage(key, initial, cb && createValueEffect(cb));
|
|
1174
|
-
});
|
|
1175
|
-
}
|
|
1176
|
-
function memo(factory, defer) {
|
|
1177
|
-
return apply(function memo(key) {
|
|
1178
|
-
const source = this.subject;
|
|
1179
|
-
const get = () => factory.call(source);
|
|
1180
|
-
if (defer)
|
|
1181
|
-
defineLazy(source, key, get);
|
|
1182
|
-
else
|
|
1183
|
-
define(source, key, get());
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
function lazy(value) {
|
|
1187
|
-
return apply(function lazy(key) {
|
|
1188
|
-
const source = this.subject;
|
|
1189
|
-
source[key] = value;
|
|
1190
|
-
defineProperty(this.state, key, {
|
|
1191
|
-
get: () => source[key]
|
|
1192
|
-
});
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
1258
|
const Oops = issues({
|
|
1197
1259
|
GlobalDoesNotExist: (name) => `Tried to access singleton ${name}, but none exist! Did you forget to initialize?\nCall ${name}.create() before attempting to access, or consider using ${name}.use() instead.`,
|
|
1198
1260
|
GlobalExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|
|
@@ -1234,5 +1296,5 @@ class Singleton extends Model {
|
|
|
1234
1296
|
}
|
|
1235
1297
|
}
|
|
1236
1298
|
|
|
1237
|
-
export { Consumer, Model, Provider, Singleton, act, apply, child, Model as default, from, lazy, memo, on, parent, pending, ref, tap, use };
|
|
1299
|
+
export { Consumer, Model, Provider, Singleton, act, apply, child, Model as default, from, lazy, set as memo, on, parent, pending, ref, set, tap, use };
|
|
1238
1300
|
//# sourceMappingURL=index.esm.js.map
|