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