@expressive/mvc 0.6.0 → 0.6.1
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 +37 -39
- package/lib/index.esm.js +113 -108
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +113 -108
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.js
CHANGED
|
@@ -25,11 +25,11 @@ function issues(register) {
|
|
|
25
25
|
return Library;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const Oops$
|
|
28
|
+
const Oops$c = issues({
|
|
29
29
|
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
30
30
|
});
|
|
31
31
|
function suspend(source, key) {
|
|
32
|
-
const error = Oops$
|
|
32
|
+
const error = Oops$c.NotReady(source.subject, key);
|
|
33
33
|
const promise = new Promise(resolve => {
|
|
34
34
|
const release = source.addListener(forKey => {
|
|
35
35
|
if (forKey == key)
|
|
@@ -69,106 +69,12 @@ function mayRetry(fn) {
|
|
|
69
69
|
return compute();
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
const Oops$
|
|
73
|
-
|
|
74
|
-
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
75
|
-
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`,
|
|
76
|
-
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
77
|
-
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
78
|
-
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`
|
|
72
|
+
const Oops$b = issues({
|
|
73
|
+
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
79
74
|
});
|
|
80
75
|
const INFO = new WeakMap();
|
|
81
76
|
const KEYS = new WeakMap();
|
|
82
77
|
const ORDER = new WeakMap();
|
|
83
|
-
function get(arg0, arg1, arg2) {
|
|
84
|
-
return apply(function get(key) {
|
|
85
|
-
const { subject } = this;
|
|
86
|
-
const computeRequired = arg1 === true || arg2 === true;
|
|
87
|
-
const factoryRequired = arg1 !== false && arg2 !== false;
|
|
88
|
-
let getter;
|
|
89
|
-
// Easy mistake, using a peer, will always be unresolved.
|
|
90
|
-
if (typeof arg0 == "symbol")
|
|
91
|
-
throw Oops$a.PeerNotAllowed(subject, key);
|
|
92
|
-
if (typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
93
|
-
throw Oops$a.BadSource(subject, key, arg0);
|
|
94
|
-
this.state.set(key, undefined);
|
|
95
|
-
const init = () => {
|
|
96
|
-
let source = this;
|
|
97
|
-
let setter;
|
|
98
|
-
if (typeof arg0 == "function") {
|
|
99
|
-
const result = mayRetry(() => arg0.call(subject, key, subject));
|
|
100
|
-
if (typeof result == "function")
|
|
101
|
-
setter = result;
|
|
102
|
-
else {
|
|
103
|
-
getter = factoryMode(this, result, key, factoryRequired);
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else if (arg0 instanceof Promise) {
|
|
108
|
-
getter = factoryMode(this, arg0, key, factoryRequired);
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
else if (typeof arg1 == "function") {
|
|
112
|
-
// replace source controller in-case it is different
|
|
113
|
-
source = ensure(arg0);
|
|
114
|
-
setter = arg1;
|
|
115
|
-
}
|
|
116
|
-
else
|
|
117
|
-
throw new Error(`Factory argument cannot be ${arg1}`);
|
|
118
|
-
getter = computeMode(this, source, setter, key, computeRequired);
|
|
119
|
-
};
|
|
120
|
-
if (typeof arg0 == "function" && factoryRequired)
|
|
121
|
-
try {
|
|
122
|
-
init();
|
|
123
|
-
}
|
|
124
|
-
catch (err) {
|
|
125
|
-
Oops$a.ComputeFailed(subject, key).warn();
|
|
126
|
-
throw err;
|
|
127
|
-
}
|
|
128
|
-
return () => {
|
|
129
|
-
if (!getter)
|
|
130
|
-
init();
|
|
131
|
-
return getter();
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
function factoryMode(self, output, key, required) {
|
|
136
|
-
const { subject, state } = self;
|
|
137
|
-
let pending;
|
|
138
|
-
let error;
|
|
139
|
-
if (output instanceof Promise) {
|
|
140
|
-
state.set(key, undefined);
|
|
141
|
-
pending = output
|
|
142
|
-
.catch(err => error = err)
|
|
143
|
-
.then(val => {
|
|
144
|
-
state.set(key, val);
|
|
145
|
-
return val;
|
|
146
|
-
})
|
|
147
|
-
.finally(() => {
|
|
148
|
-
pending = undefined;
|
|
149
|
-
self.update(key);
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
state.set(key, output);
|
|
153
|
-
const suspend = () => {
|
|
154
|
-
if (required === false)
|
|
155
|
-
return undefined;
|
|
156
|
-
const issue = Oops$a.NotReady(subject, key);
|
|
157
|
-
Object.assign(pending, {
|
|
158
|
-
message: issue.message,
|
|
159
|
-
stack: issue.stack
|
|
160
|
-
});
|
|
161
|
-
throw pending;
|
|
162
|
-
};
|
|
163
|
-
return () => {
|
|
164
|
-
if (error)
|
|
165
|
-
throw error;
|
|
166
|
-
if (pending)
|
|
167
|
-
return suspend();
|
|
168
|
-
if (state.has(key))
|
|
169
|
-
return state.get(key);
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
78
|
function computeMode(self, source, setter, key, required) {
|
|
173
79
|
const { subject, state } = self;
|
|
174
80
|
let sub;
|
|
@@ -180,7 +86,7 @@ function computeMode(self, source, setter, key, required) {
|
|
|
180
86
|
return setter.call(sub.proxy, sub.proxy);
|
|
181
87
|
}
|
|
182
88
|
catch (err) {
|
|
183
|
-
Oops$
|
|
89
|
+
Oops$b.Failed(subject, key, initial).warn();
|
|
184
90
|
throw err;
|
|
185
91
|
}
|
|
186
92
|
};
|
|
@@ -249,7 +155,7 @@ function flush(control) {
|
|
|
249
155
|
KEYS.delete(control);
|
|
250
156
|
}
|
|
251
157
|
|
|
252
|
-
const Oops$
|
|
158
|
+
const Oops$a = issues({
|
|
253
159
|
BadCallback: () => `Callback for effect-callback may only return a function.`
|
|
254
160
|
});
|
|
255
161
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
@@ -262,7 +168,7 @@ function createEffect(callback) {
|
|
|
262
168
|
if (unSet instanceof Promise)
|
|
263
169
|
unSet = undefined;
|
|
264
170
|
if (unSet && typeof unSet !== "function")
|
|
265
|
-
throw Oops$
|
|
171
|
+
throw Oops$a.BadCallback();
|
|
266
172
|
};
|
|
267
173
|
}
|
|
268
174
|
function createValueEffect(callback) {
|
|
@@ -278,11 +184,11 @@ function createValueEffect(callback) {
|
|
|
278
184
|
if (typeof out == "function")
|
|
279
185
|
unSet = out;
|
|
280
186
|
else
|
|
281
|
-
throw Oops$
|
|
187
|
+
throw Oops$a.BadCallback();
|
|
282
188
|
};
|
|
283
189
|
}
|
|
284
190
|
|
|
285
|
-
const Oops$
|
|
191
|
+
const Oops$9 = issues({
|
|
286
192
|
Timeout: (keys, timeout) => `No update for [${keys}] within ${timeout}.`,
|
|
287
193
|
StrictUpdate: () => `Strict update() did not find pending updates.`,
|
|
288
194
|
NoChaining: () => `Then called with undefined; update promise will never catch nor supports chaining.`
|
|
@@ -365,7 +271,7 @@ class Model {
|
|
|
365
271
|
const invoke = (key) => {
|
|
366
272
|
if (!key) {
|
|
367
273
|
clear();
|
|
368
|
-
reject(Oops$
|
|
274
|
+
reject(Oops$9.Timeout(select, typeof argument == "number"
|
|
369
275
|
? `${argument}ms`
|
|
370
276
|
: `lifetime of ${this}`));
|
|
371
277
|
}
|
|
@@ -452,11 +358,11 @@ class Model {
|
|
|
452
358
|
arg = undefined;
|
|
453
359
|
}
|
|
454
360
|
if (!frame.size && arg === true)
|
|
455
|
-
return Promise.reject(Oops$
|
|
361
|
+
return Promise.reject(Oops$9.StrictUpdate());
|
|
456
362
|
return {
|
|
457
363
|
then: (callback) => {
|
|
458
364
|
if (!callback)
|
|
459
|
-
throw Oops$
|
|
365
|
+
throw Oops$9.NoChaining();
|
|
460
366
|
if (frame.size || arg !== false)
|
|
461
367
|
waiting.add(() => {
|
|
462
368
|
callback(getUpdate(this));
|
|
@@ -785,7 +691,7 @@ function __awaiter(thisArg, _arguments, P, generator) {
|
|
|
785
691
|
});
|
|
786
692
|
}
|
|
787
693
|
|
|
788
|
-
const Oops$
|
|
694
|
+
const Oops$8 = issues({
|
|
789
695
|
DuplicatePending: (key) => `Invoked action ${key} but one is already active.`
|
|
790
696
|
});
|
|
791
697
|
function act(task) {
|
|
@@ -793,7 +699,7 @@ function act(task) {
|
|
|
793
699
|
let pending = false;
|
|
794
700
|
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
795
701
|
if (pending)
|
|
796
|
-
return Promise.reject(Oops$
|
|
702
|
+
return Promise.reject(Oops$8.DuplicatePending(key));
|
|
797
703
|
pending = true;
|
|
798
704
|
this.update(key);
|
|
799
705
|
try {
|
|
@@ -815,6 +721,105 @@ function act(task) {
|
|
|
815
721
|
});
|
|
816
722
|
}
|
|
817
723
|
|
|
724
|
+
function factoryMode(self, output, key, required) {
|
|
725
|
+
const { subject, state } = self;
|
|
726
|
+
let pending;
|
|
727
|
+
let error;
|
|
728
|
+
if (output instanceof Promise) {
|
|
729
|
+
state.set(key, undefined);
|
|
730
|
+
pending = output
|
|
731
|
+
.catch(err => error = err)
|
|
732
|
+
.then(val => {
|
|
733
|
+
state.set(key, val);
|
|
734
|
+
return val;
|
|
735
|
+
})
|
|
736
|
+
.finally(() => {
|
|
737
|
+
pending = undefined;
|
|
738
|
+
self.update(key);
|
|
739
|
+
});
|
|
740
|
+
}
|
|
741
|
+
state.set(key, output);
|
|
742
|
+
const suspend = () => {
|
|
743
|
+
if (required === false)
|
|
744
|
+
return undefined;
|
|
745
|
+
const issue = Oops$7.NotReady(subject, key);
|
|
746
|
+
Object.assign(pending, {
|
|
747
|
+
message: issue.message,
|
|
748
|
+
stack: issue.stack
|
|
749
|
+
});
|
|
750
|
+
throw pending;
|
|
751
|
+
};
|
|
752
|
+
return () => {
|
|
753
|
+
if (error)
|
|
754
|
+
throw error;
|
|
755
|
+
if (pending)
|
|
756
|
+
return suspend();
|
|
757
|
+
if (state.has(key))
|
|
758
|
+
return state.get(key);
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
const Oops$7 = issues({
|
|
763
|
+
BadSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
764
|
+
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
765
|
+
ComputeFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
766
|
+
NotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
767
|
+
FactoryFailed: (model, key) => `Generating initial value for ${model}.${key} failed.`,
|
|
768
|
+
Failed: (parent, property, initial) => `An exception was thrown while ${initial ? "initializing" : "refreshing"} [${parent}.${property}].`
|
|
769
|
+
});
|
|
770
|
+
function get(arg0, arg1, arg2) {
|
|
771
|
+
return apply(function get(key) {
|
|
772
|
+
const { subject } = this;
|
|
773
|
+
const computeRequired = arg1 === true || arg2 === true;
|
|
774
|
+
const factoryRequired = arg1 !== false && arg2 !== false;
|
|
775
|
+
let getter;
|
|
776
|
+
// Easy mistake, using a peer, will always be unresolved.
|
|
777
|
+
if (typeof arg0 == "symbol")
|
|
778
|
+
throw Oops$7.PeerNotAllowed(subject, key);
|
|
779
|
+
if (typeof arg0 == "function" && /^[A-Z]/.test(arg0.name))
|
|
780
|
+
throw Oops$7.BadSource(subject, key, arg0);
|
|
781
|
+
this.state.set(key, undefined);
|
|
782
|
+
const init = () => {
|
|
783
|
+
let source = this;
|
|
784
|
+
let setter;
|
|
785
|
+
if (typeof arg0 == "function") {
|
|
786
|
+
const result = mayRetry(() => arg0.call(subject, key, subject));
|
|
787
|
+
if (typeof result == "function")
|
|
788
|
+
setter = result;
|
|
789
|
+
else {
|
|
790
|
+
getter = factoryMode(this, result, key, factoryRequired);
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
else if (arg0 instanceof Promise) {
|
|
795
|
+
getter = factoryMode(this, arg0, key, factoryRequired);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
else if (typeof arg1 == "function") {
|
|
799
|
+
// replace source controller in-case it is different
|
|
800
|
+
source = ensure(arg0);
|
|
801
|
+
setter = arg1;
|
|
802
|
+
}
|
|
803
|
+
else
|
|
804
|
+
throw new Error(`Factory argument cannot be ${arg1}`);
|
|
805
|
+
getter = computeMode(this, source, setter, key, computeRequired);
|
|
806
|
+
};
|
|
807
|
+
if (typeof arg0 == "function" && factoryRequired)
|
|
808
|
+
try {
|
|
809
|
+
init();
|
|
810
|
+
}
|
|
811
|
+
catch (err) {
|
|
812
|
+
Oops$7.ComputeFailed(subject, key).warn();
|
|
813
|
+
throw err;
|
|
814
|
+
}
|
|
815
|
+
return () => {
|
|
816
|
+
if (!getter)
|
|
817
|
+
init();
|
|
818
|
+
return getter();
|
|
819
|
+
};
|
|
820
|
+
});
|
|
821
|
+
}
|
|
822
|
+
|
|
818
823
|
function ref(callback) {
|
|
819
824
|
return apply(function ref(key) {
|
|
820
825
|
const value = this.ref(key, callback && createValueEffect(callback));
|