@expressive/mvc 1.0.0-beta.27 → 1.0.0-beta.28
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 +232 -230
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +232 -230
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -24,7 +24,7 @@ function issues(register) {
|
|
|
24
24
|
return Library;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const Oops$
|
|
27
|
+
const Oops$8 = issues({
|
|
28
28
|
BadEffectCallback: () => `Callback for effect-callback may only return a function.`
|
|
29
29
|
});
|
|
30
30
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertyDescriptors, getOwnPropertySymbols, keys: keys$1, values } = Object;
|
|
@@ -53,7 +53,7 @@ function createEffect(callback) {
|
|
|
53
53
|
if (unSet instanceof Promise)
|
|
54
54
|
unSet = undefined;
|
|
55
55
|
if (unSet && typeof unSet !== "function")
|
|
56
|
-
throw Oops$
|
|
56
|
+
throw Oops$8.BadEffectCallback();
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function createValueEffect(callback) {
|
|
@@ -69,7 +69,7 @@ function createValueEffect(callback) {
|
|
|
69
69
|
if (typeof out == "function")
|
|
70
70
|
unSet = out;
|
|
71
71
|
else
|
|
72
|
-
throw Oops$
|
|
72
|
+
throw Oops$8.BadEffectCallback();
|
|
73
73
|
};
|
|
74
74
|
}
|
|
75
75
|
function select(source, select) {
|
|
@@ -157,7 +157,7 @@ class Subscriber {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
-
const Oops$
|
|
160
|
+
const Oops$7 = issues({
|
|
161
161
|
ComputeFailed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
162
162
|
ComputedEarly: (property) => `Note: Computed values don't run until accessed, except when subscribed to. '${property}' getter may have run earlier than intended.`
|
|
163
163
|
});
|
|
@@ -183,7 +183,7 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
183
183
|
return setter.call(sub.proxy, sub.proxy);
|
|
184
184
|
}
|
|
185
185
|
catch (err) {
|
|
186
|
-
Oops$
|
|
186
|
+
Oops$7.ComputeFailed(subject, key, !!initial).warn();
|
|
187
187
|
throw err;
|
|
188
188
|
}
|
|
189
189
|
}
|
|
@@ -229,7 +229,7 @@ function prepare(parent, key, source, setter, getter) {
|
|
|
229
229
|
}
|
|
230
230
|
catch (e) {
|
|
231
231
|
if (early)
|
|
232
|
-
Oops$
|
|
232
|
+
Oops$7.ComputedEarly(key).warn();
|
|
233
233
|
throw e;
|
|
234
234
|
}
|
|
235
235
|
finally {
|
|
@@ -510,9 +510,214 @@ function child(source, name) {
|
|
|
510
510
|
}, name || source.name);
|
|
511
511
|
}
|
|
512
512
|
|
|
513
|
-
const Oops$
|
|
514
|
-
|
|
513
|
+
const Oops$6 = issues({
|
|
514
|
+
CantAttachGlobal: (parent, child) => `Singleton '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
515
|
+
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.`
|
|
516
|
+
});
|
|
517
|
+
const PendingContext = new WeakMap();
|
|
518
|
+
const ContextWasUsed = new WeakMap();
|
|
519
|
+
function tap(type, argument) {
|
|
520
|
+
return child(function tap(key) {
|
|
521
|
+
return pendingAccess(this.subject, type, key, argument);
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
function pendingAccess(from, type, key, argument) {
|
|
525
|
+
if ("current" in type)
|
|
526
|
+
return () => type.current;
|
|
527
|
+
if ("current" in from.constructor)
|
|
528
|
+
throw Oops$6.CantAttachGlobal(from, type.name);
|
|
529
|
+
let instance;
|
|
530
|
+
getPending(from).push(context => {
|
|
531
|
+
instance = context.get(type);
|
|
532
|
+
if (typeof argument == "function") {
|
|
533
|
+
if (argument(instance) === false)
|
|
534
|
+
instance = undefined;
|
|
535
|
+
}
|
|
536
|
+
else if (!instance && argument)
|
|
537
|
+
throw Oops$6.AmbientRequired(type.name, from, key);
|
|
538
|
+
});
|
|
539
|
+
return () => instance;
|
|
540
|
+
}
|
|
541
|
+
function usePeerContext(subject) {
|
|
542
|
+
if (ContextWasUsed.has(subject)) {
|
|
543
|
+
if (ContextWasUsed.get(subject))
|
|
544
|
+
useLookup();
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
const pending = PendingContext.get(subject);
|
|
548
|
+
if (pending) {
|
|
549
|
+
const local = useLookup();
|
|
550
|
+
for (const init of pending)
|
|
551
|
+
init(local);
|
|
552
|
+
PendingContext.delete(subject);
|
|
553
|
+
}
|
|
554
|
+
ContextWasUsed.set(subject, !!pending);
|
|
555
|
+
}
|
|
556
|
+
function getPending(subject) {
|
|
557
|
+
let pending = PendingContext.get(subject);
|
|
558
|
+
if (!pending)
|
|
559
|
+
PendingContext.set(subject, pending = []);
|
|
560
|
+
return pending;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
const Oops$5 = issues({
|
|
564
|
+
DuplicateAction: (key) => `Invoked action ${key} but one is already active.`,
|
|
565
|
+
BadComputedSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
566
|
+
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`
|
|
515
567
|
});
|
|
568
|
+
function createRef(key, cb) {
|
|
569
|
+
const refObjectFunction = this.setter(key, cb && createValueEffect(cb));
|
|
570
|
+
defineProperty(refObjectFunction, "current", {
|
|
571
|
+
set: refObjectFunction,
|
|
572
|
+
get: () => this.state[key]
|
|
573
|
+
});
|
|
574
|
+
return refObjectFunction;
|
|
575
|
+
}
|
|
576
|
+
function ref(arg) {
|
|
577
|
+
return apply(function ref(key) {
|
|
578
|
+
let value = {};
|
|
579
|
+
if (typeof arg == "object") {
|
|
580
|
+
const source = manage(arg);
|
|
581
|
+
for (const key in source.state)
|
|
582
|
+
defineLazy(value, key, createRef.bind(source, key));
|
|
583
|
+
}
|
|
584
|
+
else
|
|
585
|
+
value = createRef.call(this, key, arg);
|
|
586
|
+
return { value };
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
function act(task) {
|
|
590
|
+
return apply(function act(key) {
|
|
591
|
+
let pending = false;
|
|
592
|
+
const invoke = (...args) => {
|
|
593
|
+
if (pending)
|
|
594
|
+
return Promise.reject(Oops$5.DuplicateAction(key));
|
|
595
|
+
pending = true;
|
|
596
|
+
this.update(key);
|
|
597
|
+
return new Promise(res => {
|
|
598
|
+
res(task.apply(this.subject, args));
|
|
599
|
+
}).finally(() => {
|
|
600
|
+
pending = false;
|
|
601
|
+
this.update(key);
|
|
602
|
+
});
|
|
603
|
+
};
|
|
604
|
+
setAlias(invoke, `run ${key}`);
|
|
605
|
+
defineProperty(invoke, "active", {
|
|
606
|
+
get: () => pending
|
|
607
|
+
});
|
|
608
|
+
return {
|
|
609
|
+
value: invoke,
|
|
610
|
+
writable: false
|
|
611
|
+
};
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
function from(source, setter, getter) {
|
|
615
|
+
return apply(function from(key) {
|
|
616
|
+
const { subject } = this;
|
|
617
|
+
let getSource;
|
|
618
|
+
// Easy mistake, using a peer, will always be unresolved.
|
|
619
|
+
if (typeof source == "symbol")
|
|
620
|
+
throw Oops$5.PeerNotAllowed(subject, key);
|
|
621
|
+
// replace source controller in-case different
|
|
622
|
+
if (typeof source == "object")
|
|
623
|
+
getSource = () => manage(source);
|
|
624
|
+
// specifically an arrow function (getter factory)
|
|
625
|
+
else if (!source.prototype) {
|
|
626
|
+
setter = source.call(subject, key);
|
|
627
|
+
getSource = () => this;
|
|
628
|
+
}
|
|
629
|
+
// is a peer Model (constructor)
|
|
630
|
+
else if (Model.isTypeof(source))
|
|
631
|
+
getSource = pendingAccess(subject, source, key, true);
|
|
632
|
+
// Regular function is to ambiguous so not allowed.
|
|
633
|
+
else
|
|
634
|
+
throw Oops$5.BadComputedSource(subject, key, source);
|
|
635
|
+
prepare(this, key, getSource, setter, getter);
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
const Oops$4 = issues({
|
|
640
|
+
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
641
|
+
});
|
|
642
|
+
function pending(source, compute) {
|
|
643
|
+
return (source === undefined ?
|
|
644
|
+
suspendForValue() :
|
|
645
|
+
typeof source == "function" && !source.prototype ?
|
|
646
|
+
suspendForAsync(source) :
|
|
647
|
+
suspendForComputed(source, compute));
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Get value, suspend instead if undefined.
|
|
651
|
+
*
|
|
652
|
+
* Throws suspense promise also interpretable as an error.
|
|
653
|
+
* React could handle it but other contexts probably not.
|
|
654
|
+
*/
|
|
655
|
+
function pendingValue(via, key) {
|
|
656
|
+
const value = via.state[key];
|
|
657
|
+
if (value === undefined)
|
|
658
|
+
throw suspend(via, key);
|
|
659
|
+
return value;
|
|
660
|
+
}
|
|
661
|
+
function suspend(source, key) {
|
|
662
|
+
const error = Oops$4.ValueNotReady(source.subject, key);
|
|
663
|
+
const promise = new Promise(resolve => {
|
|
664
|
+
const release = source.addListener(forKey => {
|
|
665
|
+
if (forKey == key)
|
|
666
|
+
return () => {
|
|
667
|
+
if (source.state[key] !== undefined) {
|
|
668
|
+
release();
|
|
669
|
+
resolve();
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
});
|
|
673
|
+
});
|
|
674
|
+
return Object.assign(promise, {
|
|
675
|
+
toString: () => String(error),
|
|
676
|
+
name: "Suspense",
|
|
677
|
+
message: error.message,
|
|
678
|
+
stack: error.stack
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
function suspendForComputed(source, compute) {
|
|
682
|
+
function getter(_value, key) {
|
|
683
|
+
return pendingValue(manage(this), key);
|
|
684
|
+
}
|
|
685
|
+
return from(source, compute, getter);
|
|
686
|
+
}
|
|
687
|
+
function suspendForValue() {
|
|
688
|
+
return apply(function pending(key) {
|
|
689
|
+
this.state[key] = undefined;
|
|
690
|
+
return {
|
|
691
|
+
set: this.setter(key),
|
|
692
|
+
get: () => pendingValue(this, key)
|
|
693
|
+
};
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
function suspendForAsync(source) {
|
|
697
|
+
return apply(function suspense(key) {
|
|
698
|
+
const subject = this.subject;
|
|
699
|
+
let waiting = true;
|
|
700
|
+
let value;
|
|
701
|
+
let error;
|
|
702
|
+
return () => {
|
|
703
|
+
if (error)
|
|
704
|
+
throw error;
|
|
705
|
+
if (!waiting)
|
|
706
|
+
return value;
|
|
707
|
+
const issue = Oops$4.ValueNotReady(subject, key);
|
|
708
|
+
let suspend = source
|
|
709
|
+
.call(subject, key)
|
|
710
|
+
.catch(err => error = err)
|
|
711
|
+
.then(out => value = out)
|
|
712
|
+
.finally(() => waiting = false);
|
|
713
|
+
throw Object.assign(suspend, {
|
|
714
|
+
message: issue.message,
|
|
715
|
+
stack: issue.stack
|
|
716
|
+
});
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
|
|
516
721
|
function use$1(init) {
|
|
517
722
|
const [state, update] = react.useState(() => [
|
|
518
723
|
init(() => update(state.concat()))
|
|
@@ -533,13 +738,14 @@ function useWatcher(target, focus, expected) {
|
|
|
533
738
|
const hook = use$1(refresh => {
|
|
534
739
|
const sub = new Subscriber(target, () => refresh);
|
|
535
740
|
if (focus) {
|
|
536
|
-
const
|
|
741
|
+
const source = sub.proxy;
|
|
537
742
|
const key = keys(sub.parent, focus)[0];
|
|
538
743
|
defineProperty(sub, "proxy", {
|
|
539
744
|
get() {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
745
|
+
const value = source[key];
|
|
746
|
+
if (value === undefined && expected)
|
|
747
|
+
throw suspend(sub.parent, key);
|
|
748
|
+
return value;
|
|
543
749
|
}
|
|
544
750
|
});
|
|
545
751
|
}
|
|
@@ -567,56 +773,6 @@ function useModel(Type, callback) {
|
|
|
567
773
|
return hook.proxy;
|
|
568
774
|
}
|
|
569
775
|
|
|
570
|
-
const Oops$6 = issues({
|
|
571
|
-
CantAttachGlobal: (parent, child) => `Singleton '${parent}' attempted to attach '${child}' but it is not also a singleton.`,
|
|
572
|
-
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.`
|
|
573
|
-
});
|
|
574
|
-
const PendingContext = new WeakMap();
|
|
575
|
-
const ContextWasUsed = new WeakMap();
|
|
576
|
-
function tap(type, argument) {
|
|
577
|
-
return child(function tap(key) {
|
|
578
|
-
return pendingAccess(this.subject, type, key, argument);
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
function pendingAccess(from, type, key, argument) {
|
|
582
|
-
if ("current" in type)
|
|
583
|
-
return () => type.current;
|
|
584
|
-
if ("current" in from.constructor)
|
|
585
|
-
throw Oops$6.CantAttachGlobal(from, type.name);
|
|
586
|
-
let instance;
|
|
587
|
-
getPending(from).push(context => {
|
|
588
|
-
instance = context.get(type);
|
|
589
|
-
if (typeof argument == "function") {
|
|
590
|
-
if (argument(instance) === false)
|
|
591
|
-
instance = undefined;
|
|
592
|
-
}
|
|
593
|
-
else if (!instance && argument)
|
|
594
|
-
throw Oops$6.AmbientRequired(type.name, from, key);
|
|
595
|
-
});
|
|
596
|
-
return () => instance;
|
|
597
|
-
}
|
|
598
|
-
function usePeerContext(subject) {
|
|
599
|
-
if (ContextWasUsed.has(subject)) {
|
|
600
|
-
if (ContextWasUsed.get(subject))
|
|
601
|
-
useLookup();
|
|
602
|
-
return;
|
|
603
|
-
}
|
|
604
|
-
const pending = PendingContext.get(subject);
|
|
605
|
-
if (pending) {
|
|
606
|
-
const local = useLookup();
|
|
607
|
-
for (const init of pending)
|
|
608
|
-
init(local);
|
|
609
|
-
PendingContext.delete(subject);
|
|
610
|
-
}
|
|
611
|
-
ContextWasUsed.set(subject, !!pending);
|
|
612
|
-
}
|
|
613
|
-
function getPending(subject) {
|
|
614
|
-
let pending = PendingContext.get(subject);
|
|
615
|
-
if (!pending)
|
|
616
|
-
PendingContext.set(subject, pending = []);
|
|
617
|
-
return pending;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
776
|
class Lookup {
|
|
621
777
|
constructor() {
|
|
622
778
|
this.table = new Map();
|
|
@@ -672,7 +828,7 @@ class Lookup {
|
|
|
672
828
|
}
|
|
673
829
|
}
|
|
674
830
|
|
|
675
|
-
const Oops$
|
|
831
|
+
const Oops$3 = issues({
|
|
676
832
|
NoProviderType: () => `Provider 'of' prop must be Model, typeof Model or a collection of them.`,
|
|
677
833
|
NothingInContext: (name) => `Couldn't find ${name} in context; did you forget to use a Provider?`,
|
|
678
834
|
BadConsumerProps: () => `Provider expects either a render function, 'get' or 'has' props.`
|
|
@@ -682,7 +838,7 @@ const useLookup = () => react.useContext(LookupContext);
|
|
|
682
838
|
function useFromContext(Type, strict) {
|
|
683
839
|
const instance = useLookup().get(Type);
|
|
684
840
|
if (!instance && strict)
|
|
685
|
-
throw Oops$
|
|
841
|
+
throw Oops$3.NothingInContext(Type.name);
|
|
686
842
|
return instance;
|
|
687
843
|
}
|
|
688
844
|
function Consumer(props) {
|
|
@@ -693,13 +849,13 @@ function Consumer(props) {
|
|
|
693
849
|
if (typeof callback == "function")
|
|
694
850
|
callback(Control.get(!!has));
|
|
695
851
|
else
|
|
696
|
-
throw Oops$
|
|
852
|
+
throw Oops$3.BadConsumerProps();
|
|
697
853
|
return null;
|
|
698
854
|
}
|
|
699
855
|
function useNewContext(from, inject) {
|
|
700
856
|
return react.useMemo(() => {
|
|
701
857
|
if (!inject)
|
|
702
|
-
throw Oops$
|
|
858
|
+
throw Oops$3.NoProviderType();
|
|
703
859
|
const context = from.push(inject);
|
|
704
860
|
for (const instance of context.local)
|
|
705
861
|
for (const apply of getPending(instance))
|
|
@@ -742,7 +898,7 @@ function Provider(props) {
|
|
|
742
898
|
: render);
|
|
743
899
|
}
|
|
744
900
|
|
|
745
|
-
const Oops$
|
|
901
|
+
const Oops$2 = issues({
|
|
746
902
|
StrictUpdate: (expected) => `Strict update() did ${expected ? "not " : ""}find pending updates.`,
|
|
747
903
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
748
904
|
});
|
|
@@ -841,7 +997,7 @@ class Model {
|
|
|
841
997
|
arg = select(this, arg);
|
|
842
998
|
if (typeof arg == "boolean") {
|
|
843
999
|
if (!control.pending === arg)
|
|
844
|
-
return Promise.reject(Oops$
|
|
1000
|
+
return Promise.reject(Oops$2.StrictUpdate(arg));
|
|
845
1001
|
}
|
|
846
1002
|
else if (arg) {
|
|
847
1003
|
control.update(arg);
|
|
@@ -862,7 +1018,7 @@ class Model {
|
|
|
862
1018
|
else
|
|
863
1019
|
callback(false);
|
|
864
1020
|
else
|
|
865
|
-
throw Oops$
|
|
1021
|
+
throw Oops$2.NoChaining();
|
|
866
1022
|
}
|
|
867
1023
|
};
|
|
868
1024
|
}
|
|
@@ -943,7 +1099,7 @@ function defer(on, method) {
|
|
|
943
1099
|
}
|
|
944
1100
|
|
|
945
1101
|
const Parent = new WeakMap();
|
|
946
|
-
const Oops$
|
|
1102
|
+
const Oops$1 = issues({
|
|
947
1103
|
ParentRequired: (expects, child) => `New ${child} created standalone but requires parent of type ${expects}. Did you remember to create via use(${child})?`,
|
|
948
1104
|
UnexpectedParent: (expects, child, got) => `New ${child} created as child of ${got}, but must be instanceof ${expects}.`,
|
|
949
1105
|
UndefinedNotAllowed: (key) => `Child property ${key} may not be undefined.`,
|
|
@@ -968,7 +1124,7 @@ function use(input, argument) {
|
|
|
968
1124
|
let current;
|
|
969
1125
|
const onUpdate = (next, initial) => {
|
|
970
1126
|
if (mode === true && !initial)
|
|
971
|
-
throw Oops$
|
|
1127
|
+
throw Oops$1.IsReadOnly(subject, key);
|
|
972
1128
|
if (next) {
|
|
973
1129
|
current = next instanceof Model
|
|
974
1130
|
? next : bootstrap(next);
|
|
@@ -976,7 +1132,7 @@ function use(input, argument) {
|
|
|
976
1132
|
manage(current);
|
|
977
1133
|
}
|
|
978
1134
|
else if (mode === undefined)
|
|
979
|
-
throw Oops$
|
|
1135
|
+
throw Oops$1.UndefinedNotAllowed(key);
|
|
980
1136
|
else
|
|
981
1137
|
current = undefined;
|
|
982
1138
|
if (typeof argument == "function")
|
|
@@ -988,11 +1144,11 @@ function use(input, argument) {
|
|
|
988
1144
|
input instanceof Model ? input :
|
|
989
1145
|
typeof input === "function" ? input() :
|
|
990
1146
|
typeof input === "object" ? bootstrap(input) :
|
|
991
|
-
Oops$
|
|
1147
|
+
Oops$1.BadArgument(typeof input).throw();
|
|
992
1148
|
if (current)
|
|
993
1149
|
mode = onUpdate(current, true) || mode;
|
|
994
1150
|
else if (mode == true)
|
|
995
|
-
throw Oops$
|
|
1151
|
+
throw Oops$1.MustBeDefined(subject, key);
|
|
996
1152
|
}
|
|
997
1153
|
else
|
|
998
1154
|
mode = false;
|
|
@@ -1007,10 +1163,10 @@ function parent(Expects, required) {
|
|
|
1007
1163
|
const value = Parent.get(this.subject);
|
|
1008
1164
|
if (!value) {
|
|
1009
1165
|
if (required)
|
|
1010
|
-
throw Oops$
|
|
1166
|
+
throw Oops$1.ParentRequired(expected, child);
|
|
1011
1167
|
}
|
|
1012
1168
|
else if (!(value instanceof Expects))
|
|
1013
|
-
throw Oops$
|
|
1169
|
+
throw Oops$1.UnexpectedParent(expected, child, value);
|
|
1014
1170
|
return { value };
|
|
1015
1171
|
});
|
|
1016
1172
|
}
|
|
@@ -1040,160 +1196,6 @@ function lazy(value) {
|
|
|
1040
1196
|
});
|
|
1041
1197
|
}
|
|
1042
1198
|
|
|
1043
|
-
const Oops$2 = issues({
|
|
1044
|
-
DuplicateAction: (key) => `Invoked action ${key} but one is already active.`,
|
|
1045
|
-
BadComputedSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
1046
|
-
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`
|
|
1047
|
-
});
|
|
1048
|
-
function createRef(key, cb) {
|
|
1049
|
-
const refObjectFunction = this.setter(key, cb && createValueEffect(cb));
|
|
1050
|
-
defineProperty(refObjectFunction, "current", {
|
|
1051
|
-
set: refObjectFunction,
|
|
1052
|
-
get: () => this.state[key]
|
|
1053
|
-
});
|
|
1054
|
-
return refObjectFunction;
|
|
1055
|
-
}
|
|
1056
|
-
function ref(arg) {
|
|
1057
|
-
return apply(function ref(key) {
|
|
1058
|
-
let value = {};
|
|
1059
|
-
if (typeof arg == "object") {
|
|
1060
|
-
const source = manage(arg);
|
|
1061
|
-
for (const key in source.state)
|
|
1062
|
-
defineLazy(value, key, createRef.bind(source, key));
|
|
1063
|
-
}
|
|
1064
|
-
else
|
|
1065
|
-
value = createRef.call(this, key, arg);
|
|
1066
|
-
return { value };
|
|
1067
|
-
});
|
|
1068
|
-
}
|
|
1069
|
-
function act(task) {
|
|
1070
|
-
return apply(function act(key) {
|
|
1071
|
-
let pending = false;
|
|
1072
|
-
const invoke = (...args) => {
|
|
1073
|
-
if (pending)
|
|
1074
|
-
return Promise.reject(Oops$2.DuplicateAction(key));
|
|
1075
|
-
pending = true;
|
|
1076
|
-
this.update(key);
|
|
1077
|
-
return new Promise(res => {
|
|
1078
|
-
res(task.apply(this.subject, args));
|
|
1079
|
-
}).finally(() => {
|
|
1080
|
-
pending = false;
|
|
1081
|
-
this.update(key);
|
|
1082
|
-
});
|
|
1083
|
-
};
|
|
1084
|
-
setAlias(invoke, `run ${key}`);
|
|
1085
|
-
defineProperty(invoke, "active", {
|
|
1086
|
-
get: () => pending
|
|
1087
|
-
});
|
|
1088
|
-
return {
|
|
1089
|
-
value: invoke,
|
|
1090
|
-
writable: false
|
|
1091
|
-
};
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
function from(source, setter, getter) {
|
|
1095
|
-
return apply(function from(key) {
|
|
1096
|
-
const { subject } = this;
|
|
1097
|
-
let getSource;
|
|
1098
|
-
// Easy mistake, using a peer, will always be unresolved.
|
|
1099
|
-
if (typeof source == "symbol")
|
|
1100
|
-
throw Oops$2.PeerNotAllowed(subject, key);
|
|
1101
|
-
// replace source controller in-case different
|
|
1102
|
-
if (typeof source == "object")
|
|
1103
|
-
getSource = () => manage(source);
|
|
1104
|
-
// specifically an arrow function (getter factory)
|
|
1105
|
-
else if (!source.prototype) {
|
|
1106
|
-
setter = source.call(subject, key);
|
|
1107
|
-
getSource = () => this;
|
|
1108
|
-
}
|
|
1109
|
-
// is a peer Model (constructor)
|
|
1110
|
-
else if (Model.isTypeof(source))
|
|
1111
|
-
getSource = pendingAccess(subject, source, key, true);
|
|
1112
|
-
// Regular function is to ambiguous so not allowed.
|
|
1113
|
-
else
|
|
1114
|
-
throw Oops$2.BadComputedSource(subject, key, source);
|
|
1115
|
-
prepare(this, key, getSource, setter, getter);
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
const Oops$1 = issues({
|
|
1120
|
-
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`
|
|
1121
|
-
});
|
|
1122
|
-
function pending(source, compute) {
|
|
1123
|
-
return (source === undefined ?
|
|
1124
|
-
suspendForValue() :
|
|
1125
|
-
typeof source == "function" && !source.prototype ?
|
|
1126
|
-
suspendForAsync(source) :
|
|
1127
|
-
suspendForComputed(source, compute));
|
|
1128
|
-
}
|
|
1129
|
-
/**
|
|
1130
|
-
* Get value, suspend instead if undefined.
|
|
1131
|
-
*
|
|
1132
|
-
* Throws suspense promise also interpretable as an error.
|
|
1133
|
-
* React could handle it but other contexts probably not.
|
|
1134
|
-
*/
|
|
1135
|
-
function pendingValue(via, key) {
|
|
1136
|
-
const value = via.state[key];
|
|
1137
|
-
if (value !== undefined)
|
|
1138
|
-
return value;
|
|
1139
|
-
const error = Oops$1.ValueNotReady(via.subject, key);
|
|
1140
|
-
const promise = new Promise(resolve => {
|
|
1141
|
-
const release = via.addListener(forKey => {
|
|
1142
|
-
if (forKey == key)
|
|
1143
|
-
return () => {
|
|
1144
|
-
if (via.state[key] !== undefined) {
|
|
1145
|
-
release();
|
|
1146
|
-
resolve();
|
|
1147
|
-
}
|
|
1148
|
-
};
|
|
1149
|
-
});
|
|
1150
|
-
});
|
|
1151
|
-
throw Object.assign(promise, {
|
|
1152
|
-
toString: () => String(error),
|
|
1153
|
-
message: error.message,
|
|
1154
|
-
stack: error.stack
|
|
1155
|
-
});
|
|
1156
|
-
}
|
|
1157
|
-
function suspendForComputed(source, compute) {
|
|
1158
|
-
function getter(_value, key) {
|
|
1159
|
-
return pendingValue(manage(this), key);
|
|
1160
|
-
}
|
|
1161
|
-
return from(source, compute, getter);
|
|
1162
|
-
}
|
|
1163
|
-
function suspendForValue() {
|
|
1164
|
-
return apply(function pending(key) {
|
|
1165
|
-
this.state[key] = undefined;
|
|
1166
|
-
return {
|
|
1167
|
-
set: this.setter(key),
|
|
1168
|
-
get: () => pendingValue(this, key)
|
|
1169
|
-
};
|
|
1170
|
-
});
|
|
1171
|
-
}
|
|
1172
|
-
function suspendForAsync(source) {
|
|
1173
|
-
return apply(function suspense(key) {
|
|
1174
|
-
const subject = this.subject;
|
|
1175
|
-
let waiting = true;
|
|
1176
|
-
let value;
|
|
1177
|
-
let error;
|
|
1178
|
-
return () => {
|
|
1179
|
-
if (error)
|
|
1180
|
-
throw error;
|
|
1181
|
-
if (!waiting)
|
|
1182
|
-
return value;
|
|
1183
|
-
const issue = Oops$1.ValueNotReady(subject, key);
|
|
1184
|
-
let suspend = source
|
|
1185
|
-
.call(subject, key)
|
|
1186
|
-
.catch(err => error = err)
|
|
1187
|
-
.then(out => value = out)
|
|
1188
|
-
.finally(() => waiting = false);
|
|
1189
|
-
throw Object.assign(suspend, {
|
|
1190
|
-
message: issue.message,
|
|
1191
|
-
stack: issue.stack
|
|
1192
|
-
});
|
|
1193
|
-
};
|
|
1194
|
-
});
|
|
1195
|
-
}
|
|
1196
|
-
|
|
1197
1199
|
const Oops = issues({
|
|
1198
1200
|
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.`,
|
|
1199
1201
|
GlobalExists: (name) => `Shared instance of ${name} already exists! Consider unmounting existing, or use ${name}.reset() to force-delete it.`
|