@expressive/mvc 0.0.1 → 0.0.4
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 +93 -60
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +93 -60
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.esm.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import React, { useState, useMemo } from 'react';
|
|
2
2
|
|
|
3
|
+
/*! *****************************************************************************
|
|
4
|
+
Copyright (c) Microsoft Corporation.
|
|
5
|
+
|
|
6
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
7
|
+
purpose with or without fee is hereby granted.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
16
|
+
***************************************************************************** */
|
|
17
|
+
|
|
18
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
19
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
20
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
21
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
22
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
23
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
24
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
3
28
|
class Issue extends Error {
|
|
4
29
|
constructor() {
|
|
5
30
|
super(...arguments);
|
|
@@ -18,6 +43,50 @@ function issues(register) {
|
|
|
18
43
|
}
|
|
19
44
|
|
|
20
45
|
const Oops$c = issues({
|
|
46
|
+
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
47
|
+
});
|
|
48
|
+
function suspend(source, key) {
|
|
49
|
+
const error = Oops$c.ValueNotReady(source.subject, key);
|
|
50
|
+
const promise = new Promise(resolve => {
|
|
51
|
+
const release = source.addListener(forKey => {
|
|
52
|
+
if (forKey == key)
|
|
53
|
+
return () => {
|
|
54
|
+
if (source.state[key] !== undefined) {
|
|
55
|
+
release();
|
|
56
|
+
resolve();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
return Object.assign(promise, {
|
|
62
|
+
toString: () => String(error),
|
|
63
|
+
name: "Suspense",
|
|
64
|
+
message: error.message,
|
|
65
|
+
stack: error.stack
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function mayRetry(fn) {
|
|
69
|
+
const retry = (err) => {
|
|
70
|
+
if (err instanceof Promise)
|
|
71
|
+
return err.then(compute);
|
|
72
|
+
else
|
|
73
|
+
throw err;
|
|
74
|
+
};
|
|
75
|
+
const compute = () => {
|
|
76
|
+
try {
|
|
77
|
+
const output = fn();
|
|
78
|
+
return output instanceof Promise
|
|
79
|
+
? output.catch(retry)
|
|
80
|
+
: output;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
return retry(err);
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return compute();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const Oops$b = issues({
|
|
21
90
|
BadEffectCallback: () => `Callback for effect-callback may only return a function.`
|
|
22
91
|
});
|
|
23
92
|
const { assign, create, defineProperty, entries, getPrototypeOf, getOwnPropertyNames, getOwnPropertyDescriptor, getOwnPropertySymbols, values } = Object;
|
|
@@ -43,7 +112,7 @@ function createEffect(callback) {
|
|
|
43
112
|
if (unSet instanceof Promise)
|
|
44
113
|
unSet = undefined;
|
|
45
114
|
if (unSet && typeof unSet !== "function")
|
|
46
|
-
throw Oops$
|
|
115
|
+
throw Oops$b.BadEffectCallback();
|
|
47
116
|
};
|
|
48
117
|
}
|
|
49
118
|
function createValueEffect(callback) {
|
|
@@ -59,28 +128,8 @@ function createValueEffect(callback) {
|
|
|
59
128
|
if (typeof out == "function")
|
|
60
129
|
unSet = out;
|
|
61
130
|
else
|
|
62
|
-
throw Oops$
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function suspenseBoundary(fn) {
|
|
66
|
-
const retry = (err) => {
|
|
67
|
-
if (err instanceof Promise)
|
|
68
|
-
return err.then(compute);
|
|
69
|
-
else
|
|
70
|
-
throw err;
|
|
131
|
+
throw Oops$b.BadEffectCallback();
|
|
71
132
|
};
|
|
72
|
-
const compute = () => {
|
|
73
|
-
try {
|
|
74
|
-
const output = fn();
|
|
75
|
-
return output instanceof Promise
|
|
76
|
-
? output.catch(retry)
|
|
77
|
-
: output;
|
|
78
|
-
}
|
|
79
|
-
catch (err) {
|
|
80
|
-
return retry(err);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
return compute();
|
|
84
133
|
}
|
|
85
134
|
|
|
86
135
|
const UPDATE = new WeakMap();
|
|
@@ -142,18 +191,25 @@ class Model {
|
|
|
142
191
|
effect(callback, select) {
|
|
143
192
|
const effect = createEffect(callback);
|
|
144
193
|
return control(this, control => {
|
|
194
|
+
let busy = false;
|
|
195
|
+
let inject = this.get;
|
|
196
|
+
const invoke = () => {
|
|
197
|
+
if (busy)
|
|
198
|
+
return;
|
|
199
|
+
const output = mayRetry(() => {
|
|
200
|
+
effect.call(inject, inject);
|
|
201
|
+
});
|
|
202
|
+
if (output instanceof Promise) {
|
|
203
|
+
output.finally(() => busy = false);
|
|
204
|
+
busy = true;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
145
207
|
if (!select) {
|
|
146
208
|
const sub = new Subscriber(control, () => invoke);
|
|
147
|
-
|
|
148
|
-
const x = sub.proxy;
|
|
149
|
-
effect.call(x, x);
|
|
150
|
-
};
|
|
209
|
+
inject = sub.proxy;
|
|
151
210
|
invoke();
|
|
152
211
|
return sub.commit();
|
|
153
212
|
}
|
|
154
|
-
const invoke = () => {
|
|
155
|
-
effect.call(this.get, this.get);
|
|
156
|
-
};
|
|
157
213
|
invoke();
|
|
158
214
|
if (!select.length) {
|
|
159
215
|
control.onDestroy.add(invoke);
|
|
@@ -282,30 +338,6 @@ class Subscriber {
|
|
|
282
338
|
}
|
|
283
339
|
}
|
|
284
340
|
|
|
285
|
-
const Oops$b = issues({
|
|
286
|
-
ValueNotReady: (model, key) => `Value ${model}.${key} value is not yet available.`,
|
|
287
|
-
});
|
|
288
|
-
function suspend(source, key) {
|
|
289
|
-
const error = Oops$b.ValueNotReady(source.subject, key);
|
|
290
|
-
const promise = new Promise(resolve => {
|
|
291
|
-
const release = source.addListener(forKey => {
|
|
292
|
-
if (forKey == key)
|
|
293
|
-
return () => {
|
|
294
|
-
if (source.state[key] !== undefined) {
|
|
295
|
-
release();
|
|
296
|
-
resolve();
|
|
297
|
-
}
|
|
298
|
-
};
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
return Object.assign(promise, {
|
|
302
|
-
toString: () => String(error),
|
|
303
|
-
name: "Suspense",
|
|
304
|
-
message: error.message,
|
|
305
|
-
stack: error.stack
|
|
306
|
-
});
|
|
307
|
-
}
|
|
308
|
-
|
|
309
341
|
const Oops$a = issues({
|
|
310
342
|
BadComputedSource: (model, property, got) => `Bad from-instruction provided to ${model}.${property}. Expects an arrow-function or a Model as source. Got ${got}.`,
|
|
311
343
|
PeerNotAllowed: (model, property) => `Attempted to use an instruction result (probably use or tap) as computed source for ${model}.${property}. This is not possible.`,
|
|
@@ -683,18 +715,19 @@ const Oops$8 = issues({
|
|
|
683
715
|
function act(task) {
|
|
684
716
|
return apply(function act(key) {
|
|
685
717
|
let pending = false;
|
|
686
|
-
const invoke = (...args) => {
|
|
718
|
+
const invoke = (...args) => __awaiter(this, void 0, void 0, function* () {
|
|
687
719
|
if (pending)
|
|
688
720
|
return Promise.reject(Oops$8.DuplicateAction(key));
|
|
689
721
|
pending = true;
|
|
690
722
|
this.update(key);
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
}
|
|
723
|
+
try {
|
|
724
|
+
return yield mayRetry(() => (task.apply(this.subject, args)));
|
|
725
|
+
}
|
|
726
|
+
finally {
|
|
694
727
|
pending = false;
|
|
695
728
|
this.update(key);
|
|
696
|
-
}
|
|
697
|
-
};
|
|
729
|
+
}
|
|
730
|
+
});
|
|
698
731
|
this.state[key] = undefined;
|
|
699
732
|
defineProperty(invoke, "active", {
|
|
700
733
|
get: () => pending
|
|
@@ -824,7 +857,7 @@ function pendingFactory(parent, key, fn, required) {
|
|
|
824
857
|
let pending;
|
|
825
858
|
let error;
|
|
826
859
|
const init = () => {
|
|
827
|
-
const output =
|
|
860
|
+
const output = mayRetry(() => {
|
|
828
861
|
return fn.call(subject, key, subject);
|
|
829
862
|
});
|
|
830
863
|
if (output instanceof Promise) {
|